HashMap
面试官:HashMap扩容规则是什么?
临界值=负载因子*容量.(此时的临界值为12,默认的负载因子为0.75,hashmap的容量为16)
当到达设定的临界值时,就会产生扩容,当前的容量*2
面试官:处理hash冲突的几种方式:
1.开放定址法:(细分为三种)
1.线性探测法
2.线性补偿探测法
3.伪随机探测再散列
2.再哈希法:
重新计算hash值
缺点:增加了计算时间
3.建立公共溢出区:
新建一张表存冲突的元素
4.链地址法(拉链法):
将近义词记录在一张表中,把冲突的位置构成链表.
优点:
处理简单,无堆积,查找长度较短,它的空间结点还是动态申请,适合造表前无法确定表长的情况,在散列中,删除结点实现简单.
缺点:
指针需要额外的空间.
面试官:负载因子为什么使用0.75?
假设:负载因子为 1 的情况下,提高了空间利用率,冲突的机会就越大.
假设:负载因子为 0.5 的情况下,可以减少查询时间的成本,空间利用率会降低.
最后、常见问题
HashMap中的“死锁”是怎么回事HashMap是非线程安全,死锁一般都是产生于并发情况下。
我们假设有二个进程T1、T2,HashMap容量为2,T1线程放入KeyA、B、C、D、E。
在T1线程中A、B、C Hash值相同,于是形成一个链接,假设为A->C->B,而D、E Hash值不同,于是容量不足,需要新建一个更大尺寸的hash表。
然后把数据从老的Hash表中 迁移到新的Hash表中(refresh)。这时T2进程闯进来了,T1暂时挂起,T2进程也准备放入新的key,这时也 发现容量不足,也refresh一把。
refresh之后原来的链表结构假设为C->A,之后T1进程继续执行,链接结构 为A->C,这时就形成A.next=B,B.next=A的环形链表。一旦取值进入这个环形链表就会陷入死循环,