在真实的业务中生成唯一数是常见的功能,也是面试必考题。今天说说在面试过程中面试官在问这个问题时最想得到怎样的答案。
大部分编程语言都提供了唯一数生成函数,可惜大部分并不好用,原因是使用条件不符合使用场景。比如你需要生成唯一的数字并且是按顺序增长的,但系统函数只能生成字符串,最后只能另辟蹊径。所以面试官会问通常都有哪些生成唯一数的方法?
一. 散列+时间+随机值
md5(time() . mt_rand(1,1000000));
如上 `time()` 函数获取当前时间戳,`mt_rand(1,1000000)` 函数获取一个1到1000000的随机值,看着好像生成的数是唯一的,但这行代码问题非常多。
在操作系统中时间是很不靠谱的参数,因为CPU计算太快,没有对应的时间单位。如果CPU 1秒内处理了2个请求,那么`time()`字段毫无意义。
在编程语言中随机数也并不随机,常见的随机数都需要有随机种子,而为了保证种子不被猜到,编程语言默认会使用当前系统时间作为种子。又变成了依赖时间的一个参数,所以这种方案不可取。
二. 微秒+进程编号
uniqid();
`uniqid()`函数可以得到一个基于微秒和进程编号的唯一ID。对于php-fpm来说,每个请求都独占一个进程,一个进程会串行的处理多个请求。所以通过进程编号+微秒看上去能生成唯一ID。但深究之后发现并不靠谱。
1秒等于100万微秒,现在问题会变成一个进程能在百万分之一秒内处理多个请求吗?答案是可以的,用当前最普通的CPU来说,单核心1秒就可以计算20亿次,1微秒可以计算2千次。