1.JDK、JRE、JVM之间的关系。
答:jdk包含jre,jre包含了jvm。jdk包含标准开发包,提供编译运行java程序所需的各种工具和资源。jre用于运行字节码文件。jvm用于执行java字节码文件,所以凡是某个代码编译后是java字节码,那就都能在jvm上运行。
2.hashCode()与equals()之间的关系。
答:首先,如果两个对象的hashCode值不相同,则一定是两个不同的对象,但是如果两个对象的hashCode值相同,不代表这两个对象一定是同一个对象,如果两个对象是同一个对象,那么hashcode值一定相同。
在java的一些集合类中,在比较两个对象是否相等时,会更具上面的原则,先调用对象的hashCode()方法,计算hash值,如果hash值不同则直接认为两个对象不同,如果hashcode相同,那么进一步调用equals()方法进行比较。
3.String,StringBuffer,StringBuilder的区别。
答:String是不可变的,如果修改,则会生成一个新的字符串对象,然后修改变量的指向。
StringBuffer是可变的,线程安全的,StringBuilder可变的,是线程不安全的,如果是单线程StringBuilder效率更高。
4.==和equals方法的区别
答:==如果是基本数据类型,比较的是值,如果是应用类型,比较的是引用地址。
equals的比较要看各个类重写equals方法之后的逻辑,比如String,虽然是引用类型,但是重写了equals方法,方法内部是比较各个字符是否相等。
5.List和Set的区别。
答:List:有序,按对象插入的顺序保存对象,可重复,允许多个null元素对象,可以使用iterator取出所有元素后逐一遍历。
set:无需,不可重复,最多只允许有一个null元素,使用iterator取出所有元素后逐一遍历。
6.ArrayList和LinkedList区别。
答:首先他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的。由于数据结构不同,所以应用场景也不同,ArrayList适合随机查找,LinkedList适合添加和删除。另外ArrayList和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以当作队列。
7.ConcurrentHashMap的扩容机制。
答:1.7版本:1.7版本的ConcurrentHashMap是基于Segment分段实现的,每个Segment相对于一个小型的hashMap,每个segment内部会进行扩容,和hashmap的扩容逻辑类似,先生成新的数组,然后将旧数组的元素转移到新数组中,扩容的判断是每个segment单独判断,判断是否超过阈值。
1.8版本:1.8版本的ConcurrentHashMap不在基于segment实现,每个线程进行put时,如果发现ConcurrentHashMap正在扩容,那么该线程也加入一起进行扩容,如果某个线程put时没有在扩容,则将key-value添加到ConcurrentHashMap中,判断是否超过阈值,超过则进行扩容,ConcurrentHashMap支持多线程扩容,扩容前先生成一个新数组,转移元素时,将新数组分组,将每个分组交给不同的线程对元素进行转移,每个线程负责一个或多个分组。
8.jdk1.7到jdk1.8hashMap发生了什么变化?
答:1.7底层是基于链表+数组,1.8是基于链表+数组+红黑树,加入红黑树的目的是提供hashMap插入和查询整体效率。1.7采用的是头插法,1.8采用的是尾插法,1.8需要判断链表元素的个数,所以需要遍历链表统计个数,正好使用尾插法。1.7中哈希算法比较复杂,存在各种右移和异或运算,1.8进行了简化,因为复杂的哈希算法的目标是提高散列性,来提供hashmap的整体效率,1.8中增加了红黑树,所以可以适当的简化哈希算法,节省cpu资源。
9.Spring中的IOC。
答:IOC(控制反转)。就是将对象的创建和对象内属性的赋值交给Spring容器,并且配置对象之间的关系。这样开发者可以更加关注业务逻辑的实现,以及模块化和松耦合的方式构建应用进程。
10.AQS的理解,AQS如何实现可重入锁。
答:AQS是一个java线程同步框架,是jdk中很多锁工具的和兴实现框架。
在AQS中维护了一个信号量State和一个线程组成的双向链表队列,其中,这个线程队列,就是用来给线程排队的,state用来控制线程排队或者放行,在不同场景下,有不同的意义。在可重入锁的场景下,state用来表示加锁次数,0表示无锁,每加一次锁,state加一,释放锁,state-1。
11.Sychronized和ReentrantLock的区别。
- Sychronized是一个关键字,ReentrantLock是一个类
- Sychronized自动加锁和释放锁,ReentrantLock需要手动加锁和释放锁
- Sychronized是jvm层面的锁,ReentrantLock是api层面的锁
- Sychronized是非公平锁,ReentrantLock可以选择公平锁和非公平锁
- Sychronized锁的是对象,锁的信息保存在对象中,ReentrantLock通过state表示锁的状态
- Sychronized底层有一个锁升级的过程。
12.为什么不建议使用Executors来创建线程池?
13.线程池的5中状态。
Running,shutdown,stop,tidying,termined.
14.线程的创建方式。5种
继承Thread类
实现Runable接口
实现Callable接口
线程池
匿名内部类