douyin LSY_HELLOWORLD,已成功入职互联网大厂,请关注我,了解非科班的程序员的工作生活把
哈希表
首先说说什么是哈希表。
哈希表就是通过一个哈希函数,计算出变量的哈希值然后映射到一个桶bucket上。
通常有两种方式:
取模法:hash&m
与运算:hash&(m-1)
为了保证与运算的结果不会有空值,m取值应当为2的n次幂。
哈希冲突
当计算的哈希值映射到同一个桶上,就说发生了哈希冲突,解决办法如下:
开放地址法:把第二个值放在冲突的桶下一个桶
拉链法:在冲突桶后面链接一个新桶
扩容
用了/总数=装载因子 0.65
超过装载因子,就需要扩容
扩容的时候一次性分配足够多的新桶
将旧桶里的数据移入到新桶内,但一次性转移可能会消耗大量时间造成阻塞,因此会分多次逐渐转移。
在哈希表里记录一个旧桶的地址和一个转移的进度。
在每次哈希表操作时,如果检测到在扩容阶段,转移一部分,直到全部转移完成才算一次扩容结束。
map
哈希值的低八位用来选择桶,高八位选择在桶里的位置。
map的底层实现就是一个哈希表
bmap的结构
为了排列更紧凑,k放在一起,v放在一起,在末尾的指针指向一个溢出桶,从而减少扩容。
hmap里的noverflow记录使用的溢出桶数量
扩容规则
1 使用桶的数量超过了负载因子旧翻倍扩容
2 常规桶没有超,但是溢出桶超了就触发等量扩容,将桶内的数据整合一边压缩一下,因为肯定出现了太多键值对删除的情况。
常规桶数量没有超过2^15,溢出桶数目超过常规桶就触发;
常规桶数量超过了215,溢出桶数目超过2^15就触发。