sendRedirect()方法和 forward() 方法的区别sendRedirect() 方法原理
客户端发送请求, Servlet1 做出处理.
Servlet1 调用 sendReadirect() 方法, 将客户端的请求重新定位到 Servlet2.
客户端浏览器访问 Servlet2.
Servlet2 对客户端浏览器做出响应.
forward() 方法原理
客户端发送请求, Servlet1 做出处理.
Servlet1 调用 forward() 方法, 将请求转发给 Servlet2 来处理请求, 为客户端服务.
Servlet2 对客户端浏览器做出响应.
区别
定位与转发
sendRedirect(): 重新定位到另外一个资源来处理请求, URL 会重新定位, 让客户端重新访问另外一个资源.
forward(): 转发到另外一个资源来处理请求. URL 不会变化. 隐藏了处理对象的变化.
处理请求的资源的范围sendReadirect(): 可以跨 WEB 应用程序和服务器重新定位资源来处理请求.forward(): 只能在应用程序内部转发.
enco ...
代码优化, 一个很重要的课题. 可能有些人觉得没用, 一些细小的地方有什么好修改的, 改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的, 就像大海里面的鲸鱼一样, 它吃一条小虾米有用吗?没用, 但是, 吃的小虾米一多之后, 鲸鱼就被喂饱了.代码优化也是一样, 如果项目着眼于尽快无 BUG 上线, 那么此时可以抓大放小, 代码的细节可以不精打细磨.如果有足够的时间开发、维护代码, 这时候就必须考虑每个可以优化的细节了, 一个一个细小的优化点累积起来, 对于代码的运行效率绝对是有提升的.
代码优化的目标是
减小代码的体积
提高代码运行的效率
代码优化细节:1. 尽量指定类、方法的 final 修饰符带有 final 修饰符的类是不可派生的. 在 Java 核心 API 中, 有许多应用 final 的例子, 例如 java.lang.String, 整个类都是 final 的.为类指定 final 修饰符可以让类不可以被继承, 为方法指定 final 修饰符可以让方法不可以被重写. 如果指定了一个类为 final, 则该类所有的方法都是final 的.Java 编译器会 ...
新时代码农
未读
持久代持久代中包含了虚拟机中所有可通过反射获取到的数据, 比如 Class 和 Method 对象. 不同的 Java 虚拟机之间可能会进行类共享, 因此持久代又分为只读区和读写区.
JVM 用于描述应用程序中用到的类和方法的元数据也存储在持久代中. JVM 运行时会用到多少持久代的空间取决于应用程序用到了多少类. 除此之外, Java SE库中的类和方法也都存储在这里.
如果 JVM 发现有的类已经不再需要了, 它会去回收(卸载)这些类, 将它们的空间释放出来给其它类使用. Full GC 会进行持久代的回收.
JVM 中类的元数据在 Java 堆中的存储区域.
Java 类对应的 HotSpot 虚拟机中的内部表示也存储在这里.
类的层级信息, 字段, 名字.
方法的编译信息及字节码.
变量
常量池和符号解析
持久代的大小
它的上限是 MaxPermSize, 默认是 64M
Java 堆中的连续区域 : 如果存储在非连续的堆空间中的话, 要定位出持久代到新对象的引用非常复杂并且耗时. 卡表(card table), 是一种记忆集(RememberedSet), 它用来记录 ...
为什么使用 Junit我们以前测试一个类的步骤:
新建一个 test 类
创建 main() 方法
在 main 类 new 一个我们要测试的类的实例
然后调用这个类的方法, 输出一个结果
当测试的类有多个方法时, 我们必须调用所有的方法, 为了不让上一次的方法调用对下一次的调用产生影响, 我们会在 new 一个实例出来, 或者将上一次的代码注释掉.则将造成整个测试代码的混乱.这个时候我们希望如果可以有多个 mian()方法, 每个 main() 方法内只调用一个需要测试的类的方法,这样显得调理清晰. 但是这是不可能的, 一个程序只能有一个入口
这个时候, Junit 站了出来, 它大声的说它可以做到.
怎么使用 Junit主要步骤:
新建一个 java 项目
在 src 下新建一个 util 包, 编写一个普通的类
12345678910111213141516171819202122232425262728/** * 对名称, 地址等字符串格式的内容进行格式检查 * 或者格式化的工具类 * @author CodeA */public class WordDeanUti ...
Hibernate 的理解
面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系, 调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样, 本质上都是要得到一个结果, 程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化.
为了在关机和内存空间不够的状况下, 保持程序的运行状态, 需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息. 从 Java 程序的运行功能上来讲, 保存对象状态的功能相比系统运行的其他功能来说, 应该是一个很不起眼的附属功能,java 采用 jdbc 来实现这个功能, 这个不起眼的功能却要编写大量的代码, 而做的事情仅仅是保存对象和恢复对象, 并且那些大量的 jdbc 代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写, 是一种苦活和重复性的工作.
通过数据库保存 java 程序运行时产生的对象和恢复对象, 其实就是实现了 java 对象与关系数据库记录的映射关系, 称为 ORM(即 Objec ...
新时代码农
未读
获取环境变量12System.getenv("PATH");System.getenv("JAVA_HOME");
获取系统属性12345System.getProperty("pencil color"); // 得到属性值java -Dpencil color=greenSystem.getProperty("java.specification.version"); // 得到 Java 版本号Properties p = System.getProperties(); // 得到所有属性值p.list(System.out);
String Tokenizer12345678// 能够同时识别, 和 |StringTokenizer st = new StringTokenizer("Hello, World|of|Java", ", |");while (st.hasMoreElements()) { st.nextToken( ...
新时代码农
未读
equals 的写法12345678public boolean equals(Object o){ if(this == o) return true; if(o == null) return false; if(!o instanceof strudent) return false; student s = (student)o; if(s.name.equals(this.name) && s.age == this.age) return true; else return false;}
说说 & 和 && 的区别.& 和 && 都可以用作逻辑与的运算符, 表示逻辑与(and), 当运算符两边的表达式的结果都为 true 时, 整个运算结果才为 true, 否则, 只要有一方为 false,则结果为 false.&& 还具有短路的功能, 即如果第一个表达式为 false, 则不再计算第二个表达式, 例如, 对于 if(str ! ...
Java 集合
Collection
List
LinkedList
ArrayList
CopyOnWriteArrayList
Vetor
Stack
Set
HashSet
LinkedHashSet
TreeSet
CopyOnWriteArraySet
Map
ConcurrentHashMap
ConcurrentShipListMap
EnumMap
HashMap
HashTable
LinkedHashMap
Properties
TreeMap
WeakHashMap
单线程集合ListArrayList
底层基于泛型数组
它允许所有元素,包括 null
ArrayList 实际上是通过一个数组去保存数据的。当我们构造 ArrayList 时;若使用默认构造函数,则 ArrayList 的默认容量大小是 10。
当 ArrayList 容量不足以容纳全部元素时,ArrayList 会重新设置容量:新的容量 =“(原始容量 x3)/2 + 1”。
ArrayList 的克隆函数,即是将全部元素克隆到一个数组中。
ArrayL ...
新时代码农
未读serializable 的意义
比如说你的内存不够用了, 那计算机就要将内存里面的一部分对象暂时的保存到硬盘中, 等到要用的时候再读入到内存中, 硬盘的那部分存储空间就是所谓的虚拟内存.在比如过你要将某个特定的对象保存到文件中, 我隔几天在把它拿出来用, 那么这时候就要实现 Serializable 接口;
在进行 java 的 Socket 编程的时候, 你有时候可能要传输某一类的对象, 那么也就要实现 Serializable 接口;最常见的你传输一个字符串, 它是 JDK里面的类, 也实现了 Serializable 接口, 所以可以在网络上传输.
如果要通过远程的方法调用(RMI)去调用一个远程对象的方法, 如在计算机 A 中调用另一台计算机 B 的对象的方法, 那么你需要通过 JNDI 服务获取计算机B 目标对象的引用, 将对象从 B 传送到 A, 就需要实现序列化接口.
例如:
在 web 开发中, 如果对象被保存在了 Session 中, tomcat 在重启时要把 Session 对象序列化到硬盘, 这个对象就必须实现 Serializable 接口.
如果对象要经 ...
.gitignore 规则写法.gitignore 文件用于指定哪些类型的文件应被 Git 忽略。以下是一些常用的忽略规则:
在已忽略文件夹中不忽略特定的子文件夹:
12/node_modules/*!/node_modules/layer/
在已忽略文件夹中不忽略特定的文件:
12/node_modules/*!/node_modules/layer/layer.js
注意:要使这些规则生效,被忽略的文件或目录需要以 /* 结尾。此外,请参考以下规则写法:
以斜杠 / 开头表示目录;
星号 * 可匹配多个字符;
问号 ? 匹配单个字符;
方括号 [] 内包含单个字符的匹配列表;
大叹号 ! 表示不忽略(跟踪)匹配到的文件或目录;
取消跟踪已版本控制的文件你可以使用 git update-index --assume-unchanged <file> 命令来取消对一个文件的跟踪。这适用于你希望暂时停止 Git 监控特定文件变动的情况。
1git update-index --assume-unchanged your_file_path
从版本库中删除文件 ...
新时代码农
未读新建代码库在开始任何项目前,我们通常需要创建一个新的代码库。这可以通过以下方式完成:
123456# 在当前目录创建新的git仓库$ git init# 初始化一个新目录作为Git代码库(如果这个目录已存在)$ git init [project-name]# 克隆远程代码库至本地$ git clone [url]
注意事项:
请确保选择合适的位置和项目名称,避免与现有文件或目录冲突。
如果要克隆一个项目,请确认你有访问权限以及所选 URL 是正确的。
配置配置 Git 有助于确保你在提交时信息准确且一致:
1234567# 查看当前Git的全局配置$ git config --list# 编辑本地或全球的gitconfig文件$ git config -e [--global]# 设置提交代码时的基本用户信息(推荐使用--global)$ git config [--global] user.name "[name]"$ git config [--global] user.email "[email address]"
注意事项:
使用 ...
在 Ubuntu 系统的使用过程中,熟练掌握图形界面与命令行模式的切换,以及配置 SSH 服务是非常有用的技能。下面我将分享一些基本的操作步骤,帮助 Ubuntu 初学者们更好地管理自己的系统。
图形界面与命令行模式切换在 Ubuntu 系统中,你可以通过以下快捷键在图形界面和命令行模式之间进行切换:
切换到命令行模式:使用 Ctrl + Alt + F2 到 F6。每个组合键会打开一个新的命令行界面。
切换回图形界面:使用 Ctrl + Alt + F7。
安装 openssh-server为了能够远程登录到你的 Ubuntu 系统,你需要安装 openssh-server。
首先,更新你的系统包列表:1sudo apt-get update
接着,安装 openssh-server:1sudo apt-get install openssh-server
查看和开启 SSH 服务安装完成后,你可以检查 SSH 服务是否已经开启。
查看当前运行的进程,确认 SSH 服务是否在运行:1sudo ps -e | grep ssh
如果 SSH 服务没有运行,你可以通过以下命令启 ...
深入理解泛型什么是泛型泛型就是变量类型的参数化。在使用泛型前,存入集合中的元素可以是任何类型的,当从集合中取出时,所有的元素都是 Object 类型,需要进行向下的强制类型转换,转换到特定的类型。而强制类型转换容易引起运行时错误。泛型类型参数只能被类或接口类型赋值,不能被原生数据类型赋值,原生数据类型需要使用对应的包装类。
不适用泛型
123456789101112131415161718192021222324252627282930class Test { private Object ob; // 定义一个通用类型成员 public Test(Object ob) { this.ob = ob; } public Object getOb() { return ob; } public void setOb(Object ob) { this.ob = ob; } public void showTyep() { ...
新时代码农
未读Git 是一种分布式版本控制系统,它广泛用于软件开发和项目管理领域,提供了一个简单高效的工具来跟踪文件的修改记录,并允许多个开发者协作。本文档将从基础知识开始介绍,逐步深入到高级用法。
1. 安装 GitLinux:在大多数 Linux 发行版中可以直接通过包管理器安装 Git。
1sudo apt-get update && sudo apt-get install git #对于Debian/Ubuntu用户
或者
1sudo yum install git #对于CentOS/RHEL用户
Windows 和 macOS:建议从官网下载 Git 最新版本的安装程序进行安装:https://git-scm.com/downloads
2. 配置 Git在第一次使用前,需要配置你的用户名和邮箱。这是重要的识别信息。
12git config --global user.name "Your Name"git config --global user.email you@example.com
可以查看已有的配置:
1git config -- ...