程序设计面试题
抽奖算法
随机数法
根据奖品的概率的精度来设置随机数范围,如精确到0.001范围为1000,根据奖品概率设置不同的数据区间,如0-100为奖品1等,然后采用随机数的方法使用Random类的nexInt方法来获取范围内的随机数抽中奖品,如果奖品库存没有了,从总数中减去该奖品占的比例数值。
算法复杂度
数据准备阶段,为每个奖品确定编号与奖品信息的关系集合需要O(n);
产生随机数阶段O(1);
从集合中查找,不同的数据结构实现不同,最差需要O(n);
Math.random方法说明:
实现:就是调用了Random类的nextDouble()方法;
返回一个0-1的double类型的随机数
线程安全的
random.nextXxxx方法说明:
Random类中的nextXxxx系列方法生成0-n的随机数;
随机数概率法
不需要对应
离散法
(高中数学里几何概形的思想)
将奖品集合的概率划分区段放入数组中。概率区段通过该概率累计相加确定。利用随机数产生随机概率,加入数组并排序,该数据的下标,就是对应奖品集合中奖品的索引。例如,奖品的集合有X1,X2,X3,X4,对应概率为P1=0.2,P2=0.2,P3=0.3,P4=0.3。
那么,产生的概率区段数组为[0.2,0.4,0.7,1.0]。
0.2以下代表X1,0.2~0.4代表X2,0.4~0.7代表X3,0.7~1代表X4。
这样,如果产生一个随机概率为0.5,加入数组排序后,0.4~0.7之间,是X3相加所在的概率区间,返回index=2。
由于区间分布的确定是按照X集合顺序的,所以该索引也正是X3在原集合中的索引。

特点
利用几何概形,概率数组分布在0到1之间,不再需要扩大倍数和取整操作,基本可以保证概率平均分布,避免大量重复的情况
概率分配的排序过程,可以使用java默认的排序工具类,也可以自己实现。保证时间复杂度最小。
复杂度 :
准备阶段,O(m)。m远小于n,因为概率只有几个,不会大量膨胀。
产生随机数,O(1)
排序取下标,根据排序算法,O(logn)即可实现
取值,根据下标,O(1);
设计一个抽奖方法
公司年会抽奖,高并发的条件下,从数据库和程序的角度提出优化方法
抽奖可以根据每个商品的中奖人数和总人数设置概率区间,用户抽到的数在概率区间内就获取奖品,每个用户抽完,概率区间就会发生变化,可以保证所有商品都会被抽完。
系统设计:
后台配置活动规则,奖品信息,奖品概率,奖品库存等
前台展示活动入口
抽奖算法:
采用随机数法
高并发处理:
频繁使用的数据放入缓存:如奖品数据,奖品概率和库存数据,活动数据,用户数据
用户中奖信息保存采用消息队列的方式异步保存
库存的计算可以使用redis的计数器,跟原库存比较
线程安全处理:
使用分布式锁保障

浙公网安备 33010602011771号