用 Java 徒手写一个抽奖系统,拿去用吧

  • 奖品

  • 奖品池

  • 抽奖算法

  • 奖品限制

  • 奖品发放

2、奖品


奖品包括奖品、奖品概率和限制、奖品记录。

奖品表:

CREATE TABLE points_luck_draw_prize (

id bigint(20) NOT NULL AUTO_INCREMENT,

name varchar(50) DEFAULT NULL COMMENT ‘奖品名称’,

url varchar(50) DEFAULT NULL COMMENT ‘图片地址’,

value varchar(20) DEFAULT NULL,

type tinyint(4) DEFAULT NULL COMMENT ‘类型1:红包2:积分3:体验金4:谢谢惠顾5:自定义’,

status tinyint(4) DEFAULT NULL COMMENT ‘状态’,

is_del bit(1) DEFAULT NULL COMMENT ‘是否删除’,

position int(5) DEFAULT NULL COMMENT ‘位置’,

phase int(10) DEFAULT NULL COMMENT ‘期数’,

create_time datetime DEFAULT NULL,

update_time datetime DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=164 DEFAULT CHARSET=utf8mb4 COMMENT=‘奖品表’;

奖品概率限制表:

CREATE TABLE points_luck_draw_probability (

id bigint(20) NOT NULL AUTO_INCREMENT,

points_prize_id bigint(20) DEFAULT NULL COMMENT ‘奖品ID’,

points_prize_phase int(10) DEFAULT NULL COMMENT ‘奖品期数’,

probability float(4,2) DEFAULT NULL COMMENT ‘概率’,

frozen int(11) DEFAULT NULL COMMENT ‘商品抽中后的冷冻次数’,

prize_day_max_times int(11) DEFAULT NULL COMMENT ‘该商品平台每天最多抽中的次数’,

user_prize_month_max_times int(11) DEFAULT NULL COMMENT ‘每位用户每月最多抽中该商品的次数’,

create_time datetime DEFAULT NULL,

update_time datetime DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COMMENT=‘抽奖概率限制表’;

奖品记录表:

CREATE TABLE points_luck_draw_record (

id bigint(20) NOT NULL AUTO_INCREMENT,

member_id bigint(20) DEFAULT NULL COMMENT ‘用户ID’,

member_mobile varchar(11) DEFAULT NULL COMMENT ‘中奖用户手机号’,

points int(11) DEFAULT NULL COMMENT ‘消耗积分’,

prize_id bigint(20) DEFAULT NULL COMMENT ‘奖品ID’,

result smallint(4) DEFAULT NULL COMMENT ‘1:中奖 2:未中奖’,

month varchar(10) DEFAULT NULL COMMENT ‘中奖月份’,

daily date DEFAULT NULL COMMENT ‘中奖日期(不包括时间)’,

create_time datetime DEFAULT NULL,

update_time datetime DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=3078 DEFAULT CHARSET=utf8mb4 COMMENT=‘抽奖记录表’;

3、奖品池


奖品池是根据奖品的概率和限制组装成的抽奖用的池子。主要包括奖品的总池值和每个奖品所占的池值(分为开始值和结束值)两个维度。

  • 奖品的总池值:所有奖品池值的总和。

  • 每个奖品的池值:算法可以变通,常用的有以下两种方式 :

  • 奖品的概率*10000(保证是整数)

  • 奖品的概率10000奖品的剩余数量

奖品池bean:

public class PrizePool implements Serializable{

/**

  • 总池值

*/

private int total;

/**

  • 池中的奖品

*/

private List poolBeanList;

}

池中的奖品bean:

public class PrizePoolBean implements Serializable{

/**

  • 数据库中真实奖品的ID

*/

private Long id;

/**

  • 奖品的开始池值

*/

private int begin;

/**

  • 奖品的结束池值

*/

private int end;

}

奖品池的组装代码:

/**

  • 获取超级大富翁的奖品池

* @param zillionaireProductMap 超级大富翁奖品map

* @param flag true:有现金 false:无现金

* @return

*/

private PrizePool getZillionairePrizePool(Map<Long, ActivityProduct> zillionaireProductMap, boolean flag) {

//总的奖品池值

int total = 0;

List poolBeanList = new ArrayList<>();

for(Entry<Long, ActivityProduct> entry : zillionaireProductMap.entrySet()){

ActivityProduct product = entry.getValue();

//无现金奖品池,过滤掉类型为现金的奖品

if(!flag && product.getCategoryId() == ActivityPrizeTypeEnums.XJ.getType()){

continue;

}

//组装奖品池奖品

PrizePoolBean prizePoolBean = new PrizePoolBean();

prizePoolBean.setId(product.getProductDescriptionId());

prizePoolBean.setBengin(total);

total = total + product.getEarnings().multiply(new BigDecimal(“10000”)).intValue();

prizePoolBean.setEnd(total);

poolBeanList.add(prizePoolBean);

}

PrizePool prizePool = new PrizePool();

prizePool.setTotal(total);

prizePool.setPoolBeanList(poolBeanList);

return prizePool;

}

4、抽奖算法


整个抽奖算法为:

1. 随机奖品池总池值以内的整数

2. 循环比较奖品池中的所有奖品,随机数落到哪个奖品的池区间即为哪个奖品中奖。

抽奖代码:

public static PrizePoolBean getPrize(PrizePool prizePool){

//获取总的奖品池值

int total = prizePool.getTotal();

//获取随机数

Random rand=new Random();

int random=rand.nextInt(total);

//循环比较奖品池区间

for(PrizePoolBean prizePoolBean : prizePool.getPoolBeanList()){

if(random >= prizePoolBean.getBengin() && random < prizePoolBean.getEnd()){

return prizePoolBean;

}

}

return null;

}

5、奖品限制


实际抽奖中对一些比较大的奖品往往有数量限制,比如:某某奖品一天最多被抽中5次、某某奖品每位用户只能抽中一次。。等等类似的限制,对于这样的限制我们分为两种情况来区别对待:

1. 限制的奖品比较少,通常不多于3个:这种情况我们可以再组装奖品池的时候就把不符合条件的奖品过滤掉,这样抽中的奖品都是符合条件的。例如,在上面的超级大富翁抽奖代码中,我们规定现金奖品一天只能被抽中5次,那么我们可以根据判断条件分别组装出有现金的奖品和没有现金的奖品。

2. 限制的奖品比较多,这样如果要采用第一种方式,就会导致组装奖品非常繁琐,性能低下,我们可以采用抽中奖品后校验抽中的奖品是否符合条件,如果不符合条件则返回一个固定的奖品即可。

6、奖品发放


奖品发放可以采用工厂模式进行发放:不同的奖品类型走不同的奖品发放处理器,示例代码如下:

奖品发放:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

这份面试题几乎包含了他在一年内遇到的所有面试题以及答案,甚至包括面试中的细节对话以及语录,可谓是细节到极致,甚至简历优化和怎么投简历更容易得到面试机会也包括在内!也包括教你怎么去获得一些大厂,比如阿里,腾讯的内推名额!

某位名人说过成功是靠99%的汗水和1%的机遇得到的,而你想获得那1%的机遇你首先就得付出99%的汗水!你只有朝着你的目标一步一步坚持不懈的走下去你才能有机会获得成功!

成功只会留给那些有准备的人!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
alt=“img” style=“zoom: 33%;” />

总结

这份面试题几乎包含了他在一年内遇到的所有面试题以及答案,甚至包括面试中的细节对话以及语录,可谓是细节到极致,甚至简历优化和怎么投简历更容易得到面试机会也包括在内!也包括教你怎么去获得一些大厂,比如阿里,腾讯的内推名额!

某位名人说过成功是靠99%的汗水和1%的机遇得到的,而你想获得那1%的机遇你首先就得付出99%的汗水!你只有朝着你的目标一步一步坚持不懈的走下去你才能有机会获得成功!

成功只会留给那些有准备的人!

[外链图片转存中…(img-ofg3OlfX-1713757892287)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 30
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值