拓展阅读
chat
详细介绍一下哈希
哈希(Hash),又叫散列,是计算机中一种将任意长度的数据映射为固定长度的数据的技术,广泛应用于查找、去重、加密、负载均衡等场景。
🧠 核心概念
1. 哈希函数(Hash Function)
- 将任意长度的输入“压缩”成固定长度的输出。
- 相同输入,输出必定相同;不同输入,尽量输出不同。
- 输出结果一般称为哈希值(Hash Value)或哈希码(Hash Code)。
比如:
输入: "apple" → 哈希值: 97af...
输入: "banana" → 哈希值: b1c4...
🧮 哈希的主要用途
1. 哈希表(Hash Table)
最典型的应用,键值对形式存储数据,具有接近 O(1) 的查找效率。
Map<String, Integer> map = new HashMap<>();
map.put("apple", 5);
System.out.println(map.get("apple")); // 输出 5
-
背后原理:
- key 通过哈希函数映射到数组中的一个索引位置。
- 如果多个 key 映射到了同一位置(哈希冲突),就通过链表、红黑树等方式解决。
2. 哈希去重
- 将元素的哈希值存入集合中判断是否重复。
Set<String> set = new HashSet<>();
3. 密码加密(如 MD5, SHA-256)
- 将原始密码经过哈希函数后存储,防止明文泄露。
-
特点:
- 不可逆(从哈希值推不出原始值)
- 雪崩效应:输入变化一点点,输出变化很大。
4. 数据校验(如文件传输)
- 比如用 MD5 校验码检查文件是否被篡改。
5. 负载均衡 / 分布式系统
- 一致性哈希:把 key 均匀地映射到多个节点上。
⚠️ 哈希冲突
不同的输入得到相同的哈希值,叫哈希冲突(Collision)。
解决方法主要有两种:
1. 开放地址法
- 冲突后,向后查找空位插入。
2. 链地址法(Java HashMap 用的)
- 冲突的元素用链表或红黑树连接在一起。
🧪 哈希函数的好坏标准
一个“好的”哈希函数应该具备:
- 计算快(不能拖后腿)
- 分布均匀(避免集中在少数桶里)
- 抗碰撞性强(避免冲突太多)
- 确定性(输入一样输出一定一样)
🧰 常见哈希函数
名称 | 应用场景 |
---|---|
Object.hashCode() |
Java 的哈希表 |
MD5 |
密码、文件校验 |
SHA-256 |
密码、更安全的加密 |
CRC32 |
文件完整性检查 |
MurmurHash |
大数据、分布式高性能哈希 |
🔍 例子:哈希表查找效率
假设你用一个数组存储 100 万个数字,查找一个值平均是 O(logN) 或 O(N)。
但如果用哈希表(数组 + 哈希函数):
Map<Integer, String> map = new HashMap<>();
map.put(1000000, "value");
System.out.println(map.get(1000000)); // O(1) 查找
几乎是常数时间,这是哈希表强大的原因。
总结 🧾
项目 | 说明 |
---|---|
哈希是什么 | 把数据映射为固定长度的值 |
主要作用 | 查找、去重、加密、校验、分布式 |
关键结构 | 哈希函数 + 哈希表(数组 + 链) |
核心优势 | 高效查找、快速匹配 |
风险点 | 冲突处理,哈希函数选择 |
哈希的应用场景可以在拓展一些吗?比如 bloom-filter 之类的
当然可以!哈希的应用场景其实非常广泛,除了常规的哈希表、去重、加密等之外,还有很多“隐藏高手”也离不开哈希,比如 布隆过滤器、LRU缓存、一致性哈希、区块链、图像/音频指纹识别 等等。
✅ 哈希的更多应用场景拓展
1. 布隆过滤器(Bloom Filter)
是一种用空间换时间的概率型数据结构,核心依赖哈希。
- 用途:判断某个元素是否存在于集合中。
-
特点:
- 占用内存极小
- 有误判率(可能会说有,其实没有),但绝不会漏判。
-
应用:
- 爬虫系统去重 URL
- 缓存穿透防护(比如 Redis + Bloom Filter)
- 大规模黑名单检测
原理简述:
- 把元素通过多个哈希函数映射到一个位数组的多个位置。
- 查询时检查对应位置是否全为 1,如果是就认为可能存在。
2. 一致性哈希(Consistent Hashing)
分布式系统中的负载均衡利器。
- 用途:将请求分布到多个服务器节点,避免因新增/删除节点导致大规模重映射。
-
应用:
- 分布式缓存(如 Redis Cluster)
- CDN、数据库分片
-
原理:
- 将节点和 key 都哈希到一个环上,顺时针找到最近的节点处理该 key。
3. LRU Cache(最近最少使用缓存)
常见于操作系统、数据库、浏览器等缓存策略。
-
LRU 的核心结构通常是:
- 哈希表(用于 O(1) 查找)
- 双向链表(用于维护使用顺序)
哈希表用于高效定位缓存项,链表用于记录访问顺序。
4. 区块链(BlockChain)
哈希几乎是区块链的“骨架”。
- 每个区块都包含前一个区块的哈希值(称为“区块头”)
- 一旦区块中的数据被篡改,其哈希值就会改变,链条就断裂,从而保证数据不可篡改性
- 使用大量哈希函数如 SHA-256、Merkle Tree 等
5. Merkle Tree(默克尔树)
一种基于哈希构造的树结构,常用于数据校验和对比。
-
应用:
- 区块链(如比特币、以太坊)
- 分布式系统中的数据一致性校验
-
每个叶子节点是数据的哈希值,上层节点是下层两个节点哈希拼接后的哈希。
6. 图像/音频指纹识别
哈希用于生成“特征指纹”。
- 如 Perceptual Hash(感知哈希):将图片压缩为低分辨率图像后计算哈希值,能识别“相似图像”。
-
应用:
- 图像去重、版权保护
- 音频识别(如 Shazam)
7. 哈希索引(数据库)
一种基于哈希表实现的数据库索引机制。
- 应用:MySQL Memory 引擎默认使用哈希索引
- 特点:查找非常快,但不适合范围查询(因为哈希是无序的)
8. 负载均衡(Load Balancing)
哈希算法用于决定用户请求发送到哪个服务器。
-
常见方案:
userId % 服务器数
hash(IP)
-> 映射到服务器池
-
避免某个服务器被频繁切换,提高粘性和效率。
9. 分布式系统中的幂等处理
防止消息重复处理,常用哈希存储“处理过的标识”。
-
应用:
- 消息队列(如 Kafka)
- API 接口幂等性判断
10. 验证码识别/防刷机制
通过哈希生成验证码标识、或者限制同一 IP 重复访问行为。
📌 总结:哈希的高级应用场景地图
应用领域 | 场景/技术 | 用途说明 |
---|---|---|
数据结构 | 哈希表、布隆过滤器 | 高效查找、去重 |
分布式系统 | 一致性哈希、哈希分片 | 节点路由、负载均衡 |
缓存机制 | LRU 缓存、布隆过滤器+Redis | 查询加速、减少 DB 压力 |
安全领域 | 加密哈希(SHA, MD5) | 密码存储、签名、防篡改 |
区块链 | 区块哈希、Merkle Tree | 数据完整性、追溯、抗篡改 |
多媒体处理 | 图像哈希、音频指纹 | 版权识别、去重 |
数据库系统 | 哈希索引、分布式幂等判断 | 加速查询、避免重复写入 |
网络安全 | DoS 攻击防御、验证码限制 | 限流、行为识别 |