散列算法、斐波那契散列

目录

一、散列算法有哪些种?

二、HashMap、ThreadLocal、数据库路由都是用了什么散列算法?

HashMap

ThreadLocal

数据库路由

为什么ThreadLocalMap要使用线性探测法解决冲突?(哈希冲突不使用链表可以更好地利用CPU缓存,局部性原理)

三、ThreadLocal使用了一个基于斐波那契数列的散列算法来计算每个ThreadLocal变量的索引?

四、ThreadLocal的哈希码是怎么得到的?

哈希码生成机制

增量值HASH_INCREMENT的来源

总结

五、乘法散列为什么要用2的幂值作为每次的扩容条件?

1. 效率高

2. 均匀分布

3. 内存利用率

4. 简化实现

5. 平衡空间和时间成本

六、你有了解过 0x61c88647 是怎么计算的吗?

七、斐波那契散列的使用场景是什么?

斐波那契数列在散列算法中的潜在应用

注意事项

结论


一、散列算法有哪些种?

  1. 基于数学运算的散列算法
    • 除留余数法:最常用的方法之一,通过取模运算将键映射到有限的连续区间上。
    • 平方取中法:先求键的平方,然后取中间的几位作为散列地址。
    • 折叠法:将键分割成位数相同的几部分,然后取这几部分的叠加和(舍去进位)作为散列地址。
    • 基数转换法:将键看作一个数,采用不同的基数进行计算,然后按需要取其中的几位作为散列地址。
    • 旋转法:将键的字符进行旋转或者颠倒。
    • 乘法散列:通过乘以一个常数并取模的方式来计算散列值。
  2. 基于密码学的散列算法
    • MD5:一种广泛使用的散列函数,可以产生一个128位(16字节)的散列值,但因其安全性问题已逐渐被弃用。
    • SHA-1:另一种广泛使用的散列函数,产生一个160位的散列值,但也存在被破解的风险。
    • SHA-2:SHA-1的后继者,包括SHA-256、SHA-384和SHA-512等变体,提供了更高的安全性。
    • SHA-3:在SHA-2之后,NIST选择了Keccak算法作为SHA-3的标准,以解决SHA-2潜在的弱点。
  3. 基于复杂性的散列算法
    • Whirlpool:一种基于AES设计的加密哈希函数,产生512位的散列值。
    • Blake2:一种高性能的散列函数,提供了多种输出长度,包括256位和512位。
  4. 基于字符串的散列算法
    • BKDRHashRSHashAPHashDJBHash等:这些算法通常用于字符串的快速散列,具有较低的碰撞率和较好的分布特性。
  5. 局部敏感散列(LSH, Locality-Sensitive Hashing):
    • 这是一种特殊类型的散列算法,用于在哈希表中快速查找相似项。它通过降低不同数据点之间的哈希冲突概率来实现,适用于大规模数据集的相似性搜索。
  6. 一致性散列(Consistent Hashing):
    • 不是传统意义上的散列算法,但它通过哈希环的方式将数据和缓存节点进行映射,以实现负载均衡和容错。

需要注意的是,不同的散列算法具有不同的特点和用途,选择哪种算法取决于具体的应用场景和需求。例如,在需要高安全性的场合,通常会选择基于密码学的散列算法;而在需要快速计算和较低碰撞率的场合,则可能会选择基于数学运算或字符串的散列算法。

二、HashMap、ThreadLocal、数据库路由都是用了什么散列算法?

析:

HashMap

HashMap在Java中是一种常用的基于散列表的Map接口实现。它主要使用了以下散列算法和策略:

  1. 散列函数:HashMap的散列函数结合了多种方法,如折叠法和除留余数法。具体来说,它会对key的hashCode()进行一定的扰动处理(如右位移、异或等操作),以增加散列的随机性和均匀性。

  2. 解决冲突:HashMap通过链表法(JDK 1.8之前)或链表+红黑树(JDK 1.8及之后,当链表长度超过一定阈值时)来解决散列冲突。即,所有散列值相同的元素会被放在同一个链表或红黑树中。

  3. 扩容机制:当HashMap中的元素数量超过其容量(capacity)的负载因子(load factor,默认为0.75)时,HashMap会进行扩容,即创建一个新的、容量更大的数组,并重新计算所有元素的散列值和新位置。

ThreadLocal

ThreadLocal在Java中提供了一种线程局部变量,每个使用该变量的线程都会有一个独立的变量副本。ThreadLocal的散列算法和存储策略如下:

  1. 散列函数:ThreadLocal使用了一个基于斐波那契数列的散列算法来计算每个ThreadLocal变量的索引。具体来说,它会为每个ThreadLocal变量生成一个唯一的hashCode,并通过这个hashCode与数组长度进行取模运算来得到索引。

  2. 解决冲突:ThreadLocal通过开放寻址法来解决冲突。

  3. 扩容机制:ThreadLocal的扩容机制与HashMap类似,当数组中的元素数量超过一定阈值时(通常是数组长度的2/3),会进行扩容并重新计算所有元素的索引。

数据库路由

数据库路由通常用于分布式数据库系统中,根据一定的规则将请求路由到不同的数据库实例上。虽然数据库路由的具体实现可能因系统而异,但常见的散列算法包括:

  1. 取模法:直接对某个键值(如用户ID)进行哈希计算,然后对数据库实例的数量取模,得到的结果即为目标数据库实例的索引。

  2. 范围划分:根据键值的范围将不同的键值分配到不同的数据库实例上。这种方法不是严格意义上的散列算法,但也是一种常见的路由策略。

  3. 一致性哈希:在分布式系统中,一致性哈希是一种用于数据分布和负载均衡的算法。它通过构建一个哈希环,将数据和节点映射到环上,并根据顺时针方向找到离数据最近的节点作为目标节点。虽然一致性哈希不是直接用于计算散列值的算法,但它通过哈希环的方式实现了数据的分布式存储和路由。

综上所述,HashMap、ThreadLocal和数据库路由在散列算法的应用上各有特色,它们分别采用了不同的散列函数、冲突解决策略和扩容机制来适应不同的应用场景和需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值