●init()
在一个Servlet的生命周期中,init方法只会被执行一次。
●service()
当一个客户请求改Servlet时,实际的处理工作全部有service方法来完成,service方法用来处理客户端的请求,并生成格式化数据返回给客户端。
●destory();
该方法在整个生命周期中,也是只会被调用一次
序列化是为了解决在对对象流进行读写操作时所引发的问题。把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化(将对象转换成二进制)。
ObjectOutputStream.writeObject() 实现序列化
ObjectInputStream.readObject() 实现反序列化
1个字节=8位
byte 1字节
short 2字节
int 4字节
long 8字节
float 4字节
double 8字节
char 2字节
boolean 1字节
①、在运行时判断任意一个对象所属的类
②、在运行时构造任意一个类的对象
③、在运行时判断任意一个类所具有的成员变量和方法(通过反射设置可以调用 private)
④、在运行时调用任意一个对象的方法
AOP/注解/分布式服务的服务端
反射创建对象是几倍时间,获取成员变量和调用方法就是太多倍了。
原因是在调用方法时,源码中遍历查找最为消耗时间。
1. m.setAccessible(true);
由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
2.用缓存,比如redis, 这个方法提高效率是显而易见的。
将反射得到元数据保存起来,使用时,只需从内存中调用即可
3.利用一些高性能的反射库,如ReflectASM
String:String的值是不可变的,这就导致每次对String的操作都会生成新的String对象。
StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
Stringbuffer:可变字符串、效率低、线程安全;
StringBuilder:可变字符序列、效率高、线程不安全;
Statement:
每次都会执行SQL语句,相关数据库都要执行SQL语句的编译。
Statement为一条Sql语句生成执行计划,
PreparedStatement:
Statement为一条Sql语句生成执行计划,
但是PreparedStatement的预编译结果会被缓存,下次执行相同的预编译语句时,就不需要编译,只要将参数直接传入编译过的语句执行代码 中就会得到执行,所以,对于批量处理可以大大提高效率。
作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。
1、PreparedStatement尽最大可能提高性能。
2、极大的提高了安全性
Runtime 类代表着Java程序的运行时环境,每个Java程序都有一个Runtime实例,该实例是单例的,该类会被自动创建,我们可以通过Runtime.getRuntime() 方法来获取当前程序的Runtime实例。
用途:
1、使用java代开本地可执行文件,例如调用shell。
2、打开一个程序,并用改程序打开一个支持的文件。
例如:打开记事本,用记事本打开java文件。
打开暴风播放器,用播放器打开一个本地视频。
etag/last-modifyed/expires/cache-control
https://www.cnblogs.com/duiniweixiao/p/8884274.html
●session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象
●一个在客户端一个在服务端。因Cookie在客户端所以可以编辑伪造,不是十分安全。
●Session过多时会消耗服务器资源,大型网站会有专门Session服务器,Cookie存在客户端没问题。
●域的支持范围不一样,比方说a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解决这个问题的办法是JSONP或者跨域资源共享。
①查询ip地址
②建立tcp连接,接入服务器
③浏览器发起http请求
④服务器后台操作并做出http响应
⑤网页的解析与渲染
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
●toString()
●equals()
●hashCode()
●notify()
●notifyAll()
●wait()
indexOf() 是查某个指定的字符串在字符串首次出现的位置(索引值) (也就是从前往后查)
lastIndexOf() 方法有以下四种形式:
public int lastIndexOf(int ch): 返回指定字符在此字符串中最后一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
public int lastIndexOf(int ch, int fromIndex): 返返回指定字符在此字符串中最后一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
public int lastIndexOf(String str): 返回指定字符在此字符串中最后一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
public int lastIndexOf(String str, int fromIndex): 返回指定字符在此字符串中最后一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
int x = 3;
switch (x){
case 2:
x++;
case 3:
x++;
case 4:
x++;
default:
x++;
}
System.out.println(x); x=6
float a = 15/2;
Sys.out.print(a); a = 7.0
String类型转boolean类型的一个方法。
当String的值为“true”时返回ture。
当为其他字符串时返回false。是boolean 类型。
for(int k=0;k<100;k++){
}
System.out.println(k); k=100
1、子类异常和父类异常同时存在,子类异常要放到父类异常之前,这样直接走子类异常,不会走父类异常。如果父类异常当到前面,子类异常放到后面,编译不会通过。
int i=10,j=0;
try{
j+=i/j;
System.out.println(j);
}catch (ArithmeticException e){
System.out.println("AException");
}catch (Exception e){
System.out.println("Exception");
}finally {
System.out.println(j);
}
1.字节:byte:用来计量存储容量的一种计量单位;位:bit
2.一个字节等于8位 1byte = 8bit
char占用的是2个字节 16位,所以一个char类型的可以存储一个汉字。
整型:
byte:1个字节 8位 -128~127
short :2个字节 16位
int :4个字节 32位
long:8个字节 64位
浮点型:
float:4个字节 32 位
double :8个字节 64位
注:默认的是double类型,如3.14是double类型的,加后缀F(3.14F)则为float类型的。
char类型:
char:2个字节。
Boolean 类型
boolean: (true or false)(并未指明是多少字节 1字节 1位 4字节)
补充:BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。
/**
* 基础表示
*/
public void baseData(){
//十进制默认
int i_10 = 5;
//八进制0开头
int i_8 = 05;
//十六进制0x开头
int i_16 = 0x5;
//二级制0b/0B开头
int i_2 = 0b1;
//<< : 左移运算符,num << 1,相当于num乘以2
//>> : 右移运算符,num >> 1,相当于num除以2
//>>> : 无符号右移,忽略符号位,空位都以0补齐
}
/**
* short到字节数组的转换
* short占2个字节,转换为字节数组长度为2
* 字节数组的第1个元素为short的低位,第2个为short的高位(大于255才有高位,即0xffff)
* @param number
* @return
*/
public static byte[] shortToByte(short number){
int temp = number;
byte[] b = new byte[2];
for(int i=0;i> 8;// 向右移8位(取高8位)
}
return b;
}
/**
* short到字节数组的转换
* short占2个字节,转换为字节数组长度为2
* 字节数组的第1个元素为short的低位,第2个为short的高位(大于255才有高位,即0xffff)
* @param number
* @return
*/
public static byte[] shortToByte(short number){
int temp = number;
byte[] b = new byte[2];
for(int i=0;i> 8;// 二进制向右移8位(取高8位)
}
return b;
}
/**
* int到byte[]的转换
* @return
*/
public static byte[] intTpByte(int number){
int temp = number;
byte[] b = new byte[4];
for (int i = 0; i < b.length; i++) {
b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位
temp = temp >> 8;// 向右移8位
}
return b;
}
注释是绑定到程序源代码元素的元数据,对它们运行的代码的操作没有影响。
返回类型必须是基本类型,String,Class,Enum或以前类型之一的数组。否则,编译器将抛出错误。
@ Target注释可用于此目的。
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE })
是否适用于其他注释的注释。
所有未标记为@Target的注释,或者使用它标记但包含ANNOTATION_TYPE常量的注释也都是元注释:
您可以使用Reflection API或注释处理器来检索注释。
该@Retention注解和其的RetentionPolicy参数会影响您检索它们。RetentionPolicy枚举中有三个常量:
RetentionPolicy.SOURCE - 使注释被编译器丢弃,但注释处理器可以读取它们
RetentionPolicy.CLASS - 表示注释已添加到类文件中,但无法通过反射访问
RetentionPolicy.RUNTIME -Annotations由编译器记录在类文件中,并由JVM在运行时保留,以便可以反射性地读取它们
下面的代码会编译吗?
@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.FIELD })
public @interface TestAnnotation {
int[] value() default {};
}
如果在@Target注释中多次出现相同的枚举常量,那么这是一个编译时错误。
注释。注释总是扩展java.lang.annotation.Annotation,如Java语言规范中所述。
如果我们尝试在注释声明中使用extends子句,我们将得到一个编译错误:
LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”,LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉,比如我们缓存10000条数据,当数据小于10000时可以随意添加,当超过10000时就需要把新的数据添加进来,同时要把过期数据删除,以确保我们最大缓存10000条,那怎么确定删除哪条过期数据呢,采用LRU算法实现的话就是将最老的数据删掉,废话不多说,下面来说下Java版的LRU缓存实现
Java里面实现LRU缓存通常有两种选择,一种是使用LinkedHashMap,一种是自己设计数据结构,使用链表+HashMap
为了实现缓存回收,我们需要很容易做到:
1、查询出最近最晚使用的项
2、给最近使用的项做一个标记
链表可以实现这两个操作。检测最近最少使用的项只需要返回链表的尾部。标记一项为最近使用的项只需要从当前位置移除,然后将该项放置到头部。比较困难的事情是怎么快速的在链表中找到该项。
LinkedHashMap自身已经实现了顺序存储,默认情况下是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据放在最后面,然后它还有一个判断是否删除最老数据的方法,默认是返回false,即不删除数据,我们使用LinkedHashMap实现LRU缓存的方法就是对LinkedHashMap实现简单的扩展,扩展方式有两种,一种是inheritance(继承),一种是delegation(代理),具体使用什么方式看个人喜好:
//LinkedHashMap的一个构造函数,当参数accessOrder为true时,即会按照访问顺序排序,最近访问的放在最前,最早访问的放在后面
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
//LinkedHashMap自带的判断是否删除最老的元素方法,默认返回false,即不删除老数据
//我们要做的就是重写这个方法,当满足一定条件时删除老数据
protected boolean removeEldestEntry(Map.Entry eldest) {
return false;
}
google guava中有cache包,此包提供内存缓存功能。
内存缓存需要考虑很多问题,包括:
●并发问题
●缓存失效机制
●内存不够用时缓存释放
●缓存的命中率
●缓存的移除
guava中使用缓存需要先声明一个CacheBuilder对象,并设置缓存的相关参数,然后调用其build方法获得一个Cache接口的实例。