程序设计面试题

抽奖算法

随机数法

根据奖品的概率的精度来设置随机数范围,如精确到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的计数器,跟原库存比较

 

 

线程安全处理:

使用分布式锁保障

posted @ 2023-02-02 09:55  星光闪闪  阅读(39)  评论(0)    收藏  举报