Java篇
类加载过程
加载:将class文件加载到内存中
链接(验证、准备、解析):将java类的二进制代码合并到JVM的运行状态中
验证:比如字节码验证、文件格式验证、元数据验证和符号引用验证
准备:为类变量分配内存并设置类变量的初始值的阶段
解析:虚拟机将常量池内的符号引用转为直接引用的过程、
初始化:初始化是类加载的最后一步,也是真正执行类中定义的 Java 程序代码(字节码),初始化阶段是执行初始化方法 <clinit> ()方法的过程。
使用:
卸载:该类的Class对象被gc
hashcode和equals什么情况下重写
自定义类需要判断对象在业务逻辑中是否相等,因为Object类中的equals方法是:
public boolean equals(Object obj) {
return (this == obj);
}
和 == 一样\
反射机制
就是在程序运行期间可以获得类的属性和方法名\
String为什么是不可变的和builder、buffer的区别
String内部是final char的数组
StringBuffer线程安全,StringBuilder非线程安全\
sync和lock的区别
1)Lock是一个接口,而synchronized是Java中的关键字;
2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁; synchronized: 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 Lock: 分情况而定,Lock有多个锁获取的方式,大致就是可以尝试获得锁,线程可以不用一直等待(可以通过tryLock判断有没有锁)
3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
5)Lock可以提高多个线程进行读操作的效率。
除了加锁如何保证线程安全
原子类\
final修饰的方法、类名
方法不可重写,类不可继承
==和equals的区别
==对比的是栈中的值,基本数据类型是变量的值,引用类型是堆中内存对象的地址
equals:object中默认也是采用==来比较。通常是要重写的
LinkedList和ArrayList的区别
ArrayList:查找 LinkedList:增删
主要:ArrayList添加元素是要先从末尾将数字拷贝到后边,逐个前移;使用尾插法,并指定初始容量可以极大提升性能,甚至超过LinkedList;
LinkedList遍历必须使用迭代器,使用for循环遍历时,对任何一个元素get(i)都需要重新对链表遍历
如何查看线程死锁
1.使用jstack命令查看,会显示发生了死锁的进程 2.两个线程去操作数据库时,数据库发生死锁,可以查询数据库的情况
泛型中extends和super的区别
- ? extends T 表示包括T在内的任何T的子类\
- ? super T 表示包括T在内的任何父类\
Threadlcoal
每一个threadlocal对象
线程安全
主要是JVM中存在堆在这一被所有线程共享的区域,在多线程中,可能会有多个线程同时访问这一区域的数据操作,导致结果和单线程执行时结果不一样等问题。
双亲委托模型
AppClassloader->ExClassLoader->BootStrapClassLoader
向上委派:实际就是查找缓存,如果加载了该类,就返回,没有就继续向上
向下查找:查找加载路径,有则返回,没有继续
优点:安全性,避免用户字节编写的类动态替换Java的一些核心类 避免类的重复加载,JVM中区分不同的类,不仅仅是根据类名,相同class文件被不同的classloader加载就是不同的两个类