常见面试问题及回答——集合
- 谈谈对JAVA集合的了解
- 线程安全的集合
- HashMap的底层原理
- <font color=#900>红黑树<font>
- hashmap和hashtable的区别
- concurrenthashmap
- Arraylist
谈谈对JAVA集合的了解
1、java集合主要分为两大类collection和map(具有映射关系的集合)
2、collection主要list(有序的可重复的),set(无序的不可重复的),queue(先进先出队列)
3、常见的list有arraylist,linkedlist
4、常见的set有hashset,treeset
5、常见的queue有PriorityQueue,可以用来实现大小顶堆
6、常见的map有hashmap和treemap
线程安全的集合
1、HashTable,Vector古老的API虽然线程安全,但是性能差
2、JUC下面提供了concurrentHashMap/copyonwritearraylist支持线程安全,并保持了较好的性能
HashMap的底层原理
1、1.7之间hashmap采用链表和数组的方式构建,就是拉链法解决hash冲突
2、1.8之后hashmap采用链表/红黑树和数组的方式构建,初始的时候结构是链表和数组,如果当数组的大小>64,链表的大小大于8,链表转换成红黑树,如果数组没有到达64,只会进行扩容
3、hashmap的数组扩容机制,初始数组长度为16,默认负载因子为0.75,如果现在插入第12个数,就会进行扩容,每次扩容为原本长度的两倍
4、1.7中采用头插法并发下的扩容造成死循环,1.8中采用尾插法避免这个问题
红黑树
后续补充
hashmap和hashtable的区别
1、都是map接口的实现
2、hashtable线程安全,效率低,hashmap线程不安全,效率高
3、hashmapkey和value可以为null,只能有一个key为null,可以有多个value为 null,hashtable不允许存入null
4、hashtable虽然线程安全,但是不建议使用,建议使用concurrenthashmap
concurrenthashmap
1、JUC下提供的线程安全的集合
2、早期采用分段锁的形式,
3、后面采用数组+链表+红黑树,采用锁定头节点的方式降低锁的粒度,以较低的代价实现了线程安全
实现机制
1、初始化数组或头节点时,不加锁,采用CAS的方式进行原子替换
2、插入数据时会进行加锁处理,锁定的是头节点,锁的粒度小,并发性能好
3、扩容时会进行加锁处理,锁定的仍然是头节点
4、查找数据的时候不会加锁
5、扩容时支持查找操作,可以从旧数据中获取,扩容时如果另外一个线程进行插入操作,另外线程会加入扩容工作,等扩容完成后再插入数据
Arraylist
1、可扩容数组
2、初始化大小问10,每次扩容1.5倍
3、线程不安全