其他
面试官:为什么 HashMap 的加载因子是0.75?
来源 | 8rr.co/8V9Q
上一篇:SpringBoot 2.3 新特性之优雅停机,这波操作太秀了!
为什么HashMap需要加载因子? 解决冲突有什么方法? 为什么加载因子一定是0.75?而不是0.8,0.6?
为什么HashMap需要加载因子?
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// AbstractMap
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
加载因子 = 填入表中的元素个数 / 散列表的长度
散列函数是否可以将哈希表中的数据均匀地散列? 怎么处理冲突? 哈希表的加载因子怎么选择?
解决冲突有什么方法?
1. 开放定址法
1.1 线性探查法(Linear Probing):di = 1,2,3,…,m-1
1.2 平方探测法(Quadratic Probing):di = ±12, ±22,±32,…,±k2(k≤m/2)
1.3 伪随机探测法:di = 伪随机数序列
这种方法建立起来的哈希表,当冲突多的时候数据容易堆集在一起,这时候对查找不友好; 删除结点的时候不能简单将结点的空间置空,否则将截断在它填入散列表之后的同义词结点查找路径。因此如果要删除结点,只能在被删结点上添加删除标记,而不能真正删除结点; 如果哈希表的空间已经满了,还需要建立一个溢出表,来存入多出来的元素。
2. 再哈希法
3. 建立一个公共溢出区
4. 链地址法(拉链法)
处理冲突的方式简单,且无堆集现象,非同义词绝不会发生冲突,因此平均查找长度较短; 由于拉链法中各链表上的结点空间是动态申请的,所以它更适合造表前无法确定表长的情况; 删除结点操作易于实现,只要简单地删除链表上的相应的结点即可。
为什么HashMap加载因子一定是0.75?而不是0.8,0.6?
临界值 = DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR
* nodes in bins follows a Poisson distribution
* (http://en.wikipedia.org/wiki/Poisson_distribution) with a
* parameter of about 0.5 on average for the default resizing
* threshold of 0.75, although with a large variance because of
* resizing granularity. Ignoring variance, the expected
* occurrences of list size k are (exp(-0.5) * pow(0.5, k) /
* factorial(k)). The first values are:
* 0: 0.60653066
* 1: 0.30326533
* 2: 0.07581633
* 3: 0.01263606
* 4: 0.00157952
* 5: 0.00015795
* 6: 0.00001316
* 7: 0.00000094
* 8: 0.00000006
* more: less than 1 in ten million
1: 0.30326533
2: 0.07581633
3: 0.01263606
4: 0.00157952
5: 0.00015795
6: 0.00001316
7: 0.00000094
8: 0.00000006
那么为什么不可以是0.8或者0.6呢?
对于开放定址法,加载因子是特别重要因素,应严格限制在0.7-0.8以下。超过0.8,查表时的CPU缓存不命中(cache missing)按照指数曲线上升。因此,一些采用开放定址法的hash库,如Java的系统库限制了加载因子为0.75,超过此值将resize散列表。
参考资料
泊松分布和指数分布:10分钟教程: ruanyifeng.com/blog/2015/06/poisson-distribution.html
-END-
架构师交流群
「顶级架构师」建立了读者架构师交流群,大家可以添加小编微信进行加群
扫描添加好友邀你进架构师群,加我时注明【姓名+公司+职位】
版权申明:内容来源网络,版权归原作者所有。如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。
猜你还想看
对 Java 意义重大的 7 个性能指标
面试必需要明白的 Redis 分布式锁实现原理!
SQL查找是否"存在",别再count了,很耗费时间的
支付宝架构到底有多牛逼?看完这篇你就明白了!
长按识别图片二维码关注,订阅更多精彩
顶级架构师,企业架构、系统架构、网站架构、大规模分布式架构、高可用架构等架构讨论,以及结合互联网技术的架构调整。欢迎有想法、乐于分享的架构师交流学习。