1. String、StringBuffer和StringBuilder区别
String: 通过new String();创建出来的字符串,存放在JVM内存的堆上,通过String s = “asdf”;创建的字符串是存放在JVM的字符串常量池中。而且String创建出来后都是不可变的【地址】。
StringBuffer: 可动态改变字符串内容,而且地址是不变的,方法上都加的有synchronize关键字,是线程安全的。
StringBuilder: 也是可以动态改变字符串内容,且指向地址不变,但是是线程不安全的,不存在并发的情况下推荐使用。
2. ArrayList和LinkedList区别
ArrayList:实现了List接口;底层是数组结构,大多数情况下查询的效率会高,但是增、删效率相对低一点;更适合查询多的场景
LinkedList:实现了List和Deque【链表、双向队列】接口,底层是链表,大多数情况下增、删块,查询慢一点;更适合增删多的场景。
3. CopyOnWriteList
线程安全的,添加元素的时候,先把原始数组复制出来一份,在新的数组上执行添加操作,写的时候会加锁,然后将地址指向新的数组上。
4.HashMap扩容机制
HashMap:
1.7:数组+链表
- 先生成新数组,大小默认为原来的2倍
- 遍历老数组每个位置上的链表的每个元素
- 取每个元素的key,并基于新数组长度和hashcode,计算出每个元素在新数组的下标
- 将新元素添加到新数组中去
- 所有元素转移完成之后,将新数组赋值给HashMap对象的table属性
1.8:数组+链表+红黑树
- 先生成新数据,大小同样是原来的两倍
- 遍历老数组中每个位置上的链表或者红黑树
- 如果是链表,则直接将链表中的每个元素重新计算下标,添加到新数组中区
- 如果是红黑树,则先遍历红黑树,先计算出红黑树中每个元素对应在新数组中的下标位置
1.统计每个下标位置的元素个数
2.如果该位置下的元素个数超过了8,则生成一个新的红黑树,并将根节点的添加到新数组的对应位置
3.如果该位置下的元素个数没有超过8,那么则生成一个链表,并将链表的头结点添加到新数组的对应位置 - 所有元素转移完成后,将新数组赋值给HashMap对象的table属性
5. ConcurrentHashMap
1.7之前:
- 基于Segment分段实现
- 每个segment相对于一个小型的HashMap
- 每个Segment内部会进行扩容,和HashMap的扩容逻辑类似
- 先生成新的数组,然后转移元素到新的数组中
- 扩容的判断也是每个Segment内部单独判断的,判断是否超过阈值
1.8版本:
- 不再基于Segment实现
- 当某个线程进行put时,如果发现ConcurrentHashMap正在进行扩容,那么改线程一起进行扩容
- 如果某个线程put时,发现没有正在进行扩容,则将key-value添加到ConcurrentHashMap中,然后判断是否超过阈值,超过了则进行扩容
- ConcurrentHashMap是支持多个线程同时扩容的,扩容前也是先生成一个新的数组
- 在转移元素时,先将原数组分组,将每组分给不同的线程来进行元素的转移,每个线程负责一组或者多组的元素转移工作
6. JDK1.8新特性
- lambda表达式:函数式编程,简化编程Collection.sort/stream/filter/map/match…
- 接口里面的方法可以有默认实现,为了支持lambda表达式
- 时间类…Date Time API
- 支持多重注解
7. 接口和抽象类区别
语法上的区别:
抽象类里面可以有抽象方法和具体方法,接口里面的方法都是抽象的等等…
语义区别,也就是什么情况用抽象类,什么时候用接口:
- 抽象类更重于描述抽象的概念,有具体概念的,比如动物、植物。是一种什么类型的概念
- 接口描述一些具有的共性特征
8. HaspMap和HashTable区别
- HashTable是线程同步【线程安全】,HashMap非线程同步。因为HashTable方法上都加的有关键字synchronized
- HashTable的key和value都不能为空,HashMap允许key和value有空值
- HashTable使用Enumeration,HashMap使用iterator【不重要】
- HashTable中hash数组默认大小是11,扩容的方式是old*2+1,HashMap数据默认大小是16,扩容是2的倍数
- HashTable和HashMap都实现了Map接口,但父类不同
9. HashMap有哪些线程安全的方式
- 通过Collection.synchronizedMap()返回一个新的Map,返回的是Map的一个实现
- 使用ConcurrentHashMap构造HashMap