ID 生成器

记录一下昨天面试时被问到的 ID 生成器的场景题,当时的回答面试官不是很满意。

介绍

设计一个ID生成器,要求生成的ID在一个范围(0-10000000),且是无序的,并需要保证性能,碰撞概率低或不碰撞。

当时给出的答案和提问

使用随机数算法获取范围内的一个 ID,使用 BitMap 数据结构进行碰撞检测,避免生成重复的 ID。

  • 缺点:性能随ID消耗而急剧下降,重试次数增多
  • BitMap 内存占用:100000000 bit ≈ 12.5 MB
  • 如何优化内存占用(当时没算出来 BitMap 的内存占用):使用布隆过滤器

更好的答案

预生成随机列表

提前把这个范围内的所有数字生成好,彻底打乱顺序,然后每次需要ID时,从这个乱序列表里取一个即可。

  • 洗牌:使用 Fisher-Yates Shuffle 高效的洗牌算法
  • 存储:使用 Redis 的 LIST 数据结构,取用时调用 LPOPRPOP
  • 内存占用:使用 32 位整数存储一个 ID,总共需要 32 * 100000000 bit ≈ 400MB,是完全可以接受的

可逆混淆算法

通过数学/密码学方法,将一个有序的、递增的序列(如0, 1, 2, ...)动态地转换为一个无序的、乱序的ID。需要设计一个函数 F(i),满足一一映射和看似无序的特性,Feistel网络是一种构建这种可逆混淆函数的经典密码学结构。这种方法无需额外存储,不需要存储整个ID池,节省了大量内存。但缺点是混淆函数的设计比较复杂,需要一定的数学和密码学知识。

posted @ 2025-06-17 18:27  zmsbruce  阅读(53)  评论(0)    收藏  举报