目录
二、HashMap、ThreadLocal、数据库路由都是用了什么散列算法?
为什么ThreadLocalMap要使用线性探测法解决冲突?(哈希冲突不使用链表可以更好地利用CPU缓存,局部性原理)
三、ThreadLocal使用了一个基于斐波那契数列的散列算法来计算每个ThreadLocal变量的索引?
一、散列算法有哪些种?
- 基于数学运算的散列算法:
- 除留余数法:最常用的方法之一,通过取模运算将键映射到有限的连续区间上。
- 平方取中法:先求键的平方,然后取中间的几位作为散列地址。
- 折叠法:将键分割成位数相同的几部分,然后取这几部分的叠加和(舍去进位)作为散列地址。
- 基数转换法:将键看作一个数,采用不同的基数进行计算,然后按需要取其中的几位作为散列地址。
- 旋转法:将键的字符进行旋转或者颠倒。
- 乘法散列:通过乘以一个常数并取模的方式来计算散列值。
- 基于密码学的散列算法:
- 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潜在的弱点。
- 基于复杂性的散列算法:
- Whirlpool:一种基于AES设计的加密哈希函数,产生512位的散列值。
- Blake2:一种高性能的散列函数,提供了多种输出长度,包括256位和512位。
- 基于字符串的散列算法:
- BKDRHash、RSHash、APHash、DJBHash等:这些算法通常用于字符串的快速散列,具有较低的碰撞率和较好的分布特性。
- 局部敏感散列(LSH, Locality-Sensitive Hashing):
- 这是一种特殊类型的散列算法,用于在哈希表中快速查找相似项。它通过降低不同数据点之间的哈希冲突概率来实现,适用于大规模数据集的相似性搜索。
- 一致性散列(Consistent Hashing):
- 不是传统意义上的散列算法,但它通过哈希环的方式将数据和缓存节点进行映射,以实现负载均衡和容错。
需要注意的是,不同的散列算法具有不同的特点和用途,选择哪种算法取决于具体的应用场景和需求。例如,在需要高安全性的场合,通常会选择基于密码学的散列算法;而在需要快速计算和较低碰撞率的场合,则可能会选择基于数学运算或字符串的散列算法。
二、HashMap、ThreadLocal、数据库路由都是用了什么散列算法?
析:
HashMap
HashMap在Java中是一种常用的基于散列表的Map接口实现。它主要使用了以下散列算法和策略:
-
散列函数:HashMap的散列函数结合了多种方法,如折叠法和除留余数法。具体来说,它会对key的hashCode()进行一定的扰动处理(如右位移、异或等操作),以增加散列的随机性和均匀性。
-
解决冲突:HashMap通过链表法(JDK 1.8之前)或链表+红黑树(JDK 1.8及之后,当链表长度超过一定阈值时)来解决散列冲突。即,所有散列值相同的元素会被放在同一个链表或红黑树中。
-
扩容机制:当HashMap中的元素数量超过其容量(capacity)的负载因子(load factor,默认为0.75)时,HashMap会进行扩容,即创建一个新的、容量更大的数组,并重新计算所有元素的散列值和新位置。
ThreadLocal
ThreadLocal在Java中提供了一种线程局部变量,每个使用该变量的线程都会有一个独立的变量副本。ThreadLocal的散列算法和存储策略如下:
-
散列函数:ThreadLocal使用了一个基于斐波那契数列的散列算法来计算每个ThreadLocal变量的索引。具体来说,它会为每个ThreadLocal变量生成一个唯一的hashCode,并通过这个hashCode与数组长度进行取模运算来得到索引。
-
解决冲突:ThreadLocal通过开放寻址法来解决冲突。
-
扩容机制:ThreadLocal的扩容机制与HashMap类似,当数组中的元素数量超过一定阈值时(通常是数组长度的2/3),会进行扩容并重新计算所有元素的索引。
数据库路由
数据库路由通常用于分布式数据库系统中,根据一定的规则将请求路由到不同的数据库实例上。虽然数据库路由的具体实现可能因系统而异,但常见的散列算法包括:
-
取模法:直接对某个键值(如用户ID)进行哈希计算,然后对数据库实例的数量取模,得到的结果即为目标数据库实例的索引。
-
范围划分:根据键值的范围将不同的键值分配到不同的数据库实例上。这种方法不是严格意义上的散列算法,但也是一种常见的路由策略。
-
一致性哈希:在分布式系统中,一致性哈希是一种用于数据分布和负载均衡的算法。它通过构建一个哈希环,将数据和节点映射到环上,并根据顺时针方向找到离数据最近的节点作为目标节点。虽然一致性哈希不是直接用于计算散列值的算法,但它通过哈希环的方式实现了数据的分布式存储和路由。
综上所述,HashMap、ThreadLocal和数据库路由在散列算法的应用上各有特色,它们分别采用了不同的散列函数、冲突解决策略和扩容机制来适应不同的应用场景和需求。