本文共 1296 字,大约阅读时间需要 4 分钟。
面试官:你对HashMap了解吗? 我回答:HashMap是一种基于键值对存储数据的数据结构,支持null键、null值、null键对应null值、null键对应非null值、非null键对应null值以及非null键对应非null值的存储方式。它是一种线程不安全的数据结构,内部使用数组+链表+红黑树的组合结构来存储数据,实现了Map接口。与HashTable相比,HashMap的操作效率更高。
面试官:刚说线程不安全,那如果要线程安全该如何处理? 我回答:要实现线程安全,可以选择使用Collections.synchronizedMap(Map)方法来进行线程安全处理。此外,也可以选择使用ConcurrentHashMap类,该类通过分段锁的方式来实现线程安全,并且其效率比HashTable要高。
面试官:刚说数据结构是数组+链表+红黑树,可以说下HashMap是如何用该结构存数据的吗? 我回答:HashMap在存储数据时,会根据是否是第一次put操作来判断是否需要初始化。初始化时,会调用resize()方法,申请初始数组长度为16,阈值(threshold)为12。通过计算i=(n-1)&hash来定位数组中的下标。如果该下标为空,则通过i=(n-1)&hash计算出新的下标,并将值存入Node数组中。若下标已存在值,则检查链表长度是否超过TREEIFY_THRESHOLD(8)-1,如果超过,则将链表转换为红黑树。
面试官:在下标定位时 我回答:hash值的计算方式中使用^(异或)运算符,是为了避免不同对象的hash值冲突。具体来说,计算hash值时,会将key的hashCode与其高16位进行异或运算,得到最终的hash值。这样可以避免在相同n值下,两个不同的对象hash值相同的问题。
面试官:为什么使用(n-1)& hash 取代了 hash % 16 我回答:使用(n-1)& hash比hash % 16更高效。因为在Java中,&运算符是按位操作,直接处理0和1,而%运算符则会产生更复杂的计算过程,导致效率较低。
面试官:刚才在说put的过程中,有几个数值 我回答:n=16,threshold=12,treeify_threshold=8。这些数值的选择主要基于性能考量。n=16是2的幂次,方便二进制运算;threshold=12是n的75%;treeify_threshold=8则是链表长度的转换门槛。这些数值的选择能够在不同负载下均衡性能,避免过多的扩容或过多的链表转换。
通过以上回答,可以看出我对HashMap的理解较为深入,同时也能结合实际应用场景进行合理的解释和分析。
转载地址:http://hchfk.baihongyu.com/