100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 年会现场抽奖代码到底该怎么写?过来人告诉你答案

年会现场抽奖代码到底该怎么写?过来人告诉你答案

时间:2020-06-26 21:47:09

相关推荐

年会现场抽奖代码到底该怎么写?过来人告诉你答案

前沿

说件严肃到事情,真到快要结束了。各家公司一定在紧锣密鼓到准备年会当中了吧。年会肯定离不开抽奖吧?现场几百上千人抽奖可千万别出bug。如果真出bug老板得要杀你祭天了。现场好多人看着呢。

抽奖代码

/*** 抽奖** @author 托尼老师* @create -12-27 11:11**/public class LotteryTest {/*** 抽奖** @param originalRates 原始的概率列表* @return 物品的索引*/public static int lottery(List<Double> originalRates) {if (originalRates == null || originalRates.isEmpty()) {return -1;}int size = originalRates.size();double sumRate = 0d;for (double rate : originalRates) {sumRate += rate;}List<Double> sortOrignalRates = new ArrayList<>(size);Double tempSumRate = 0d;for (double rate : originalRates) {tempSumRate += rate;sortOrignalRates.add(tempSumRate / sumRate);}// 根据区块值来获取抽取到的物品索引double nextDouble = Math.random();sortOrignalRates.add(nextDouble);Collections.sort(sortOrignalRates);return sortOrignalRates.indexOf(nextDouble);}@Testpublic void testLottery() {List<Reward> lotteryList = new ArrayList<>();Reward r = new Reward();r.setRate(0.03d);r.setRewardName("双色球彩票一张");lotteryList.add(r);r = new Reward();r.setRate(0.001d);r.setRewardName("mac book");lotteryList.add(r);r = new Reward();r.setRate(0.06d);r.setRewardName("没抽中");lotteryList.add(r);r = new Reward();r.setRate(0.001d);r.setRewardName("迪拜七日双人豪华游");lotteryList.add(r);List<Double> originalRates = new ArrayList<>();for (Reward e : lotteryList) {originalRates.add(e.getRate());}for (int i = 0; i < 20; i++) {System.out.println("恭喜抽中========>"+ lotteryList.get(lottery(originalRates)).getRewardName());}}class Reward {//奖品名称private String rewardName;//概率private Double rate;public String getRewardName() {return rewardName;}public void setRewardName(String rewardName) {this.rewardName = rewardName;}public Double getRate() {return rate;}public void setRate(Double rate) {this.rate = rate;}}}

运行结果如下

分析结果

老板让做个抽奖的功能,抽奖到底该怎么做?

前端分析

大家都知道前端显示的数据,都是可以修改的,数据都不正确。有些抽奖逻辑代码写在前端文件中,这种只是针对不懂技术的人员,稍微懂些技术的肯定忽悠不住。

概率

公平性,公平性怎么做?上面的代码就是根据概率来实现,大奖概率低小奖概率低。这个就是随机的,全凭运气这个词。不公平,这种的话就靠逻辑来实现来。比如,某个时间段提高中奖概率。还有一种情况直接代码里面判断某个用户直接中xx奖。这种就是所谓的内在用户,白名单用户。

库存

奖品千万要设置库存,千万要设置,千万要设置。好了,重要的事情已经说了三遍了 。

讲讲并发的场景

以前Reids没出场的时候,做起来真的麻烦。现在好了,很大并发我们可以交给Redis来扛了。Redis 官方数据官方表示Redis读的速度是110000次/s,写的速度是81000次/s 。

Redis单机支持万级别的别分可以是很轻松,一般小公司足够用了。 不会出现你们所说的超卖现象。顺便说一句如果要10万+的需求可以使用

Reids replication模式。

每个人只能抽奖一次

这种场景可以看看Redis Incr 命令,Redis key再加上用户的ID代表用户的唯一键,根据自增和原子性能保证唯一还能抗大并发。

Redis Incr 命令将 key 中储存的数字值增一。

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。

如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

本操作的值限制在 64 位(bit)有符号数字表示之内。

我们线上很多场景都用到过Incr命令。

1个小时只能抽奖一次

这种时候用Reis 的Expire 命令,Redis Expire 命令用于设置 key 的过期时间,key 过期后将不再可用。单位以秒计。顺便说个题外话,实现原理和Redis 的Set 命令差不多,

只有当然取这个key的时候,它才会判断当前key有没有失效。也就是Expire命令过期策略是你Get用到这个可key的时候才判断当前的key有没有失效。

Nginx

其实Nginx也有对应的模块抗并发做拦截,根据Ip来做黑名单的拦截。当有人来刷接口,大量的黑产IP过来抽奖,这个时候就要根据你们的场景来增加抽奖门槛。比如你在我们公司注册过,或者你10天前预约过抽奖活动,这些都是例子,可以根据场景来调整。

这个就是道高一尺魔高一丈,怎么说呢?和黄牛斗其乐无穷。我们以前就遇到过很多IP来刷接口,黄牛来搞事情的场景。Nginx做一层防护,Redis再做一层防护,这样经过层层的筛选

打到数据库的流量就很少了许多。

总结

其实这个只是抽奖环节中比较简单的场景,可能会遇到的问题。线上乱七八糟什么情况都会出现了, 但是遇到bug了一定不要慌张。要坦然去面对,线上数据库我们曾经遇到过一条sql引发惨案。

具体什么情况呢?有个员工执行sql 语句的时候 where 参数没生效。最终每个人的账户都增加了相同都一笔钱。最终系统账面总资金增加了一个多亿。对的,你们没看错一个多亿。幸亏夜里发布,然后那天夜里我们就忙了一宿,具体那晚的情况下次我再发个博文好好说说。

🙏好了,你们看到这里。相信对抽奖代码怎么写,大概有了思路。

如果你觉得有用的话,就点个赞👍,分享也是一种美德。祝福你在公司的年会中大奖,迪拜双人豪华游。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。