==用于比较两个内存的地址
equals用于比较两个对象的值
hashCode用于在Hash集合中快速定位对象
针对某一对象的编码被称为hashCode。典型作用:在hashMap中进行对象的快速定位。
hashMap会在内存中开辟一系列的小存储空间,这个小存储空间被称为slot槽。
hashCode和slot如何对应呢?最简单的做法就是将hashMap按slot的总量取模%,得到的结果就是slot的号。
hashMap中查询数据步骤:首先针对key计算出hashCode,接着对hashCode按slot总量取模%,得到slot号位,再使用equals方法来按key进行比对,最终提取出数据。
基础篇中记过
计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。
jvm主要工作就是在操作系统之上构建出一个独立运行的体系。封闭生态,和外界沟通非常少。
jvm核心组成:类加载子系统、运行时数据区、执行引擎(用于计算,和CPU交互)、本地方法接口(很少用到,也不推荐)。
GC负责3项任务:分配内存、确保引用、回收内存。
GC回收的依据:某个对象没有任何引用,则可以被回收。
最主要一个对象GC Roots集合。
可作为GC Roots:方法的入参、局部变量;方法执行过程中的引用对象;静态变量引用的对象;常量引用的对象;JNI本地方法引用的对象;
静态集合类:通过static描述的list、map等数据结构。
各种连接/IO未释放
不合理的变量作用域
缓存未设置过期时效与淘汰算法
出现交叉引用(死锁)
单例模式使用集合
基础篇记过
IOC控制反转,设计理念,由第三方来管理与控制对象(运行时中)。
DI依赖注入,具体实现,由对象容器在运行时动态注入对象(反射方式,工厂模式方式)。
web应用环境,比如SpringMVC:可以使用扩展接口WebApplicationContext,扩展了web应用能力。
IOC容器-工厂方法模式
Bean对象-单例模式
AOP-代理模式
(面向切面编程的含义就是:在调用者和服务提供者之间,增加一个代理类,利用代理类为原有的系统功能提供扩展。同时让调用者和真正的服务提供者之间增加代理进行解耦工作)
(代理模式在Spring中又分成两种情况:目标类如果有接口则使用JDK动态代理来实现;目标类如果没有接口则需要使用Cglib进行扩展实现。这是AOP代理模式的底层实现。)
AOP-适配器模式
对象监听-观察者模式
JdbcTemplate-模板方法(提供给用户统一接口)
把查询结果保存在内存中
一级缓存默认开启,缓存范围SqlSession会话
二级缓存手动开启,缓存范围更大,属于Mapper Namespace级别
二级开启后默认所有查询操作均使用缓存
写操作commit提交时对该namespace缓存强制清空(一张表频繁写入的话,不建议开启二级缓存)
配置useCache=false可以不用缓存(SQL语句标签中)
配置flushCache=true代表强制清空缓存(SQL语句标签中)
FIFO-先进先出
LRU-最近最少使用(推荐)
SOFT-软引用(基于GC)
WEAK-弱引用(基于GC)
useGeneratedKeys会执行 select last_insert_id()获取最新主键。
last_insert_id()与连接绑定,每个线程一个连接,不会出现线程安全问题。
Oracle不支持自增主键的做法:
public class I18NFactory {
public static Language getI18NObject(String area) {
if(area.equals("china")) {
return new Chinese();
} else if(area.equals("spain")) {
return new Spanish();
} else if(area.equals("italy")) {
return new Italian();
} else {
return null;
}
}
}
与之对应的,工厂模式中的产品它有一个顶层接口Language,Language提供了对应的方法。
public interface Language {
public String getTitle();
}
每个具体产品都要实现接口,来完成里面的逻辑。再由简单工厂来完成对这个对象的创建工作。
public class Chinese implements Language {
@Override
public String getTitle() {
return "人事管理系统";
}
}
可直接通过 I8NFactory.getI18NObject() 得到对应的语言对象。
//把工厂也抽象出接口的使用形式,就称为工厂方法。
public interface I18NFactory {
public Language getI18NObject();
}
工厂方法解决了扩展性问题。xx语言对象 Spainish、xx语言工厂 SpainishFactory。
可直接通过 new SpainishFactory().getI18NObject() 得到对应的语言对象。
利用工厂模式隐藏类创建细节,修改类的细节不会影响其他人对类的使用。
把相应的判断条件和字符串保存在配置文件中,再通过反射的形式,动态的进行对象实例化。这样即便使用简单工厂配合反射机制,未来新增新的业务或分支,只需要在配置文件中修改就可以。也可以达到不用修改简单工厂源代码的前提。Spring IOC容器的核心原理(工厂模式+配置文件)。
代理模式:
通过生成代理对象对原始对象实现无侵入的功能扩展。
静态代理需要Java工程师手动的创建代理类。而动态代理则使用Java的反射机制或Cglib这种技术来动态的生成代理类。
这里有个非常巧妙的设计,因为所有的代理类和实现类都实现了UserService接口,所以在静态代理类实例化的时候,传入的userService对象,既可以是目标对象,也可以是其他的代理类。基于这种特性,我们就可以在当前的系统中增加多级代理,来分门别类的提供前置或者后置的功能。
静态代理的使用
Java引入反射机制以后,同样提供了自动生成代理类的机制。
动态代理典型特点:根据目标的接口来自动的利用反射技术生成代理类,然后通过InvocationHandler中的invoke方法来对目标方法进行代理和扩展。
好处:只要某一个类有相应的接口,自动就可以利用动态代理完成这个任务的扩展。
package com.imooc.spring.aop.service;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* InvocationHandler是JDK提供的反射类,用于在JDK动态代理中对目标方法进行增强
* InvocationHandler实现类与切面类的环绕通知类似
*/
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;//目标对象
private ProxyInvocationHandler(Object target){
this.target = target;
}
/**
* 在invoke()方法对目标方法进行增强
* @param proxy 代理类对象
* @param method 目标方法对象
* @param args 目标方法实参
* @return 目标方法运行后返回值
* @throws Throwable 目标方法抛出的异常
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("=====" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()) +"=========");
Object ret = method.invoke(target, args);//调用目标方法,ProceedingJoinPoint.proceed()
return ret;
}
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler(userService);
//动态创建代理类
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
invocationHandler);
userServiceProxy.createUser();
//动态代理,必须实现接口才可以运行
EmployeeService employeeService = new EmployeeServiceImpl();
EmployeeService employeeServiceProxy = (EmployeeService)Proxy.newProxyInstance(employeeService.getClass().getClassLoader(),
employeeService.getClass().getInterfaces(),
new ProxyInvocationHandler(employeeService));
employeeServiceProxy.createEmployee();
}
}
CGLib是运行时字节码增强技术
SpringAOP扩展无接口类使用CGLib
AOP会使用在运行时生成 目标继承类 字节码的方式进行行为扩展
//适配器典型特征
//实现与目标类相同的接口
public class JsonAdapter implements DataSource {
//通过构造方法内部持有目标对象
private DataSource dataSource;
public JsonAdapter(DataSource dataSource) {
this.dataSource = dataSource;
}
//重写接口方法,完成接口转换的业务逻辑
@Override
public String searchUser() {
String xml = dataSource.searchUser();
//XML转换为JSON的代码省略
String json = "......"
return json;
}
}
二进制分帧
首部压缩
流量控制
多路复用
请求优先级
服务器推送