随机数在系统开发中几乎是不可避免的一个需求,在大多数面试宝典一定会告诉你所谓的随机数其实是“伪”随机数,除此之外也就没有什么别的了。实际上这条知识本身已经是非常落后了,更不用说当它还是正确的时候,用处也并不是很大。本篇要提到的正确使用随机数的要点,是一个比较常见的错误,甚至某不只是世界500强公司也曾经在其产品中出现过这种问题,还改了 2 次才解决问题。
从根本上说,一个非常容易犯的错误出在对随机数种子的认识上,指定随机数种子一种用途是重复产生相同的随机数序列,另外更常用的是希望随机数序列可以更随机一点,避免产生相近的随机数。实际上现在常用的伪随机数序列是用线性同余算法生成的,给定一个种子连续计算产生的伪随机数是均匀分布的,如果不断指定新的随机数种子,会影响到序列的分布。从随机数生成算法和种子作用,很容易推导出几个常犯的错误:
- 不断指定随机数种子导致随机数序列质量不高
- 并发编程中并发指定与时间相关的随机数种子导致多个随机数发生器产生相同的随机数序列
- 不指定随机数种子依赖随机数发生器缺省初始化的随机数种子,又频繁创建随机数发生器,导致随机数序列质量不高
- 不指定随机数种子依赖随机数发生器缺省初始化的随机数种子,缺省初始化的随机数种子又与时间相关,又频繁或者并发创建随机数发生器,导致产生重复的随机数序列
- 并发使用非线程安全的随机数发生器导致多次获取到同一个随机数
要正确使用随机数,需要注意以下几点:
- 随机数发生器一旦初始化后应长期重复使用,避免临时创建随机数发生器
- 如果有并发使用的场景,注意检查随机数发生器是否是线程安全的,如果不是则要避免并发或者额外加锁
- 如果希望将来通过相同的随机数种子重放随机数序列,从而实现重放业务的目的,要考虑避免并发使用随机数发生器以免无法完全重复业务处理过程