面试笔记-java篇

165 阅读3分钟

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的区别

  1. ? extends T 表示包括T在内的任何T的子类\
  2. ? super T 表示包括T在内的任何父类\

Threadlcoal

每一个threadlocal对象

线程安全

主要是JVM中存在堆在这一被所有线程共享的区域,在多线程中,可能会有多个线程同时访问这一区域的数据操作,导致结果和单线程执行时结果不一样等问题。

双亲委托模型

AppClassloader->ExClassLoader->BootStrapClassLoader

向上委派:实际就是查找缓存,如果加载了该类,就返回,没有就继续向上

向下查找:查找加载路径,有则返回,没有继续

优点:安全性,避免用户字节编写的类动态替换Java的一些核心类 避免类的重复加载,JVM中区分不同的类,不仅仅是根据类名,相同class文件被不同的classloader加载就是不同的两个类