Q1: 知道Redis的字典吧,问你个问题,字典的底层数据结构知道怎么实现的吗?Java的HashMap不是采用的是数组加链表加红黑树,为什么这里的哈希表解决键冲突的时候用的是拉链法,而没有用到红黑树呢? A: 字典的底层数据结构就是哈希表,而且使用的是两个哈希表,第一个哈希表用于存放数据,第二个哈希表用户扩容(Rehash),字典的结构是`type`、`ht`、`rehashIndex` 、`privatedata` 而关于HashMap中的键冲突问题,首先是采用拉链法,在java 1.8中,如果链表的长度超过了8,那么链表将转换为红黑树。(桶的数量必须大于64,小于64的时候只会扩容)发生hash碰撞时,java 1.7 会在链表的头部插入,而java 1.8会在链表的尾部插入。而且可以看到转换红黑树的时机是超过一定大小才会去转换,因为红黑树是一种自平衡二叉搜索树,它可以保证在**最坏情况**下,查找、插入和删除操作的时间复杂度为O(log n)。也就是说在规模不断增加的情况下,红黑树是比较不错的选择,但是如果规模比较小的话,就没必要采取红黑树了。 另外,Redis的哈希表会让键值对处于一个合理的区间(执行BGSAVE指令时,哈希表的负载因子大于等于1,未执行BGSAVE时,负载因子大于等于5执行扩展;哈希表的负载因子小于0.1自动执行收缩===》**执行BGSAVE命令时,Redis需要创建当前进程的子进程(写时复制优化子进程的使用效率),因此提高扩展所需要的负载因子,尽可能避免执行扩展,最大限度节约内存**),因此会自动进行Rehash去扩展与收缩,**查询性能消耗并不大,因此采取红黑树反而增加了性能耗费**。因此,并没有采用红黑树来实现哈希表的冲突扩展。
点赞 评论

相关推荐

牛客网
牛客企业服务