ID 生成器
记录一下昨天面试时被问到的 ID 生成器的场景题,当时的回答面试官不是很满意。
介绍
设计一个ID生成器,要求生成的ID在一个范围(0-10000000),且是无序的,并需要保证性能,碰撞概率低或不碰撞。
当时给出的答案和提问
使用随机数算法获取范围内的一个 ID,使用 BitMap 数据结构进行碰撞检测,避免生成重复的 ID。
- 缺点:性能随ID消耗而急剧下降,重试次数增多
- BitMap 内存占用:100000000 bit ≈ 12.5 MB
- 如何优化内存占用(当时没算出来 BitMap 的内存占用):使用布隆过滤器
更好的答案
预生成随机列表
提前把这个范围内的所有数字生成好,彻底打乱顺序,然后每次需要ID时,从这个乱序列表里取一个即可。
- 洗牌:使用 Fisher-Yates Shuffle 高效的洗牌算法
- 存储:使用 Redis 的
LIST数据结构,取用时调用LPOP或RPOP - 内存占用:使用 32 位整数存储一个 ID,总共需要 32 * 100000000 bit ≈ 400MB,是完全可以接受的
可逆混淆算法
通过数学/密码学方法,将一个有序的、递增的序列(如0, 1, 2, ...)动态地转换为一个无序的、乱序的ID。需要设计一个函数 F(i),满足一一映射和看似无序的特性,Feistel网络是一种构建这种可逆混淆函数的经典密码学结构。这种方法无需额外存储,不需要存储整个ID池,节省了大量内存。但缺点是混淆函数的设计比较复杂,需要一定的数学和密码学知识。

浙公网安备 33010602011771号