220103
1. Java中有哪些容器(集合类)?
答:集合类主要由Collection(有Set、Queue、Tree三个子接口)和Map接口派生。有超多的实现类。
Set:无序、元素不可重复
List:有序、元素可以重复
Queue:(FIFO)队列
Map:有映射关系的集合
2. 容器线程安全和线程不安全的分别有哪些?
答:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZGSzQhDr-1641219420921)(D:\Java\图\线程安全与否.png)]
如需使用线程安全的集合类,可以用Collections工具类提供的synchronizedXxx()方法,将其包装为线程安全的集合类。
3. Map接口的实现类
答:HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap。
HashMap基于hash表,继承自AbstractMap,实现接口Map。它是线程不安全的,但他是性能最好的Map实现(相比HashTable,它在put采取加锁机制,而非同步)。它允许null key与null value,元素无序。对于多线程环境应采用ConcurrentHashMap。HashMap使用链表实现entry的存储,叫做bucket/bin。默认空间为16,权值为2。
4. 描述Map put的过程
答:以HashMap为例。先判断数组是否为空,若为空进行第一次扩容;依据hash算法计算键值对索引;若当前位置为空,则直接插入;若不为空,且key存在,直接覆盖value,若key不存在,将数据链到尾端;若长度到8,则将其转为红黑树,将数据插入数中;若元素个数超过threshold,则再次进行扩容。
5. 如何得到一个线程安全的Map
答:使用ConcurrentHashMap;用工具类包装非线程安全的map
6. HashMap的特点
答:非线程安全、允许null key null value的存在
7. JDK7和JDK8中的HashMap有什么区别?
答:以前的HashMap采用数组+链表存储,一旦链表过长,效率会很低O(N)。而JDK8加入了红黑树来优化存储,它的时间复杂度降低为O(logN)
8. HashMap底层实现原理
答:基于Hash算法,通过put、get存储获取对象。
存储:调用k的hashCode得到bucket位置,进行存储
获取:调用k的hashCode得到bucket位置,使用equals确定
发生碰撞时,将使用链表/红黑树组织数据。
9. 介绍HashMapd的扩容机制
答:数组初始容量为16,是否扩充是由负载因子判断,默认0.75。
10. HashMap中的循环链表如何产生
答:循环链表如何产生可以看这篇。
11. HashMap为什么用红黑树而不用B树?
答:B/B+树多用于外存,而在数据量不高的情况下,数据都会挤到一个节点里,这时候遍历效率就退化为链表。
12. HashMap为什么线程不安全?
答:在并发执行put时,可能形成循环链表,从而引起死循环。
13. HashMap如何实现线程安全?
答:直接使用ConcurrentHashMap;使用HashTable类;用方法包装HashMap。
14. HashMap是如何解决哈希冲突的?
答:数组元素为单向链表类型。当链表长度达到一个阈值时,链表会被转为红黑树存储提高性能,反之缩小到一个阈值,红黑树会被转为单向链表。
15. 说一说HashMap和HashTable的区别
答:HashMap线程不安全,允许null key、value
HashTable线程安全,不允许null作为key和value
|