Lottery项目学习

1.斐波那契数列

ThreadLocal源码分析-黄金分割数的使用 - 腾讯云开发者社区-腾讯云

https://www.cnblogs.com/xiaozhongfeixiang/archive/2019/09/23/11571902.html

keyIndex = ((i + 1) * HASH_INCREMENT) & (length - 1)
// length 取2^n 比较好

// i+1的目的是 避免了每次0都在位置0上,如果length不同,0不一定每次都在0这个索引上 我猜测是这样

2.为什么大小设置为2^n-1比较好: 

位运算比除法快

假设有两个数,A和B(A>0,B>0)。B为2^n,期中n>=0,A>=0。则:(原来B得为2^n)

要求A * B的话,则可使用<<操作符,A << n。

要求A / B的话,则可使用>>操作符,A >> n。

要求A % B的话,则可使用&操作符,A&(B-1)。

3.状态模式

设计模式之什么是状态模式 - 知乎

秒懂设计模式之状态模式(State Pattern) - 知乎

4.策略模式

重学 Java 设计模式:实战策略模式「模拟多种营销类型优惠券,折扣金额计算策略场景」

5.雪花算法

雪花算法SnowFlake—利用hutool生成分布式订单唯一流水号和ID - 零一开源—技术|科技|资源分享

// 0 ~ 31 位,可以采用配置的方式使用
        long workerId;
        try {
            workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
        } catch (Exception e) {
            workerId = NetUtil.getLocalhostStr().hashCode();
        }

// 只保留后5位
        workerId = workerId >> 16 & 31;

        long dataCenterId = 1L;
        snowflake = IdUtil.createSnowflake(workerId, dataCenterId);
// 生成雪花ID
        snowflake.nextId();


// UUID
//生成的UUID是带-的字符串,类似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
String uuid = IdUtil.randomUUID();

//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42
String simpleUUID = IdUtil.simpleUUID();

//ObjectId
//生成类似:5b9e306a4df4f8c54a39fb0c
String id = ObjectId.next();

//方法2:从Hutool-4.1.14开始提供
String id2 = IdUtil.objectId();

//Snowflake
//参数1为终端ID
//参数2为数据中心ID
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
long id = snowflake.nextId();

6.扰动函数

HashMap扰动函数解读_supercmd的博客-CSDN博客

7.BeansUtil的使用

BeanUtils介绍及使用

8.正则表达式的使用

Java Matcher replaceAll(String)用法及代码示例 - 纯净天空

9.业务逻辑

1>抽奖逻辑设计

把活动和网购进行类比,中间加一层类似于订单信息的东西,也就是该项目中的user_take_active表抽奖单

提供一层领取活动,可以生成抽奖单。如果一次抽奖执行失败,这个抽奖单也可以发起重试。

类似于你在商城下单到支付发货,这个是活动下单,执行抽奖,奖品发货。

因为设计一个用户同一个活动可以抽奖多次,所以单独设计一个类似于订单表的概念比较好,并且可以在这加上状态位

这里分了用户参与活动记录表和用户策略计算结果表,这样做的原因是由于用户活动参与次数表和最终的抽奖结果做一个幂等性,也可以不加这个表,按照下面的顺序来:

1.不加用户参与活动记录表

则需要在最终的抽奖结果表中记录当前是用户第几次抽奖

判断该活动是否还有名额->查询用户是否还有参与次数->抽奖->扣用户剩余参与次数->生成最终抽奖订单

最后两个步骤保证幂等性

2.加用户参与活动记录表

扣用户剩余参与次数->生成最终抽奖订单(前两个步骤需要幂等性)->抽奖(如果抽奖放在上面两个步骤的事务中会降低效率,不太行)->在订单中记录最终抽奖结果

最终结果表可能经常被访问,所以可以单独把用户第几次抽奖单独抽出一个表,也就是用户参与活动记录表,这样不用每次都访问最终抽奖结果表,这样还可以在活动记录表里面加状态位

2>防止刷新浏览器持续请求,或者羊毛同时1s多次请求

在抽奖单里,加个state状态位,每次先看是否有没有进行抽奖的抽奖单,如果有的话就取出来进行抽奖,这样就算一个人同时好多次请求进来,也会取到同一个抽奖单,抽奖单和最后抽奖结果分离的好处

3.id的生成选择

  • 订单号:唯一、大量、订单创建时使用、分库分表
  • 活动号:唯一、少量、活动创建时使用、单库单表
  • 策略号:唯一、少量、活动创建时使用、单库单表
雪花算法,长码,大量
日期算法,短码,少量,全局唯一需要自己保证
随机算法,短码,大量,全局唯一需要自己保证
1.雪花算法,用于生成单号
2. 日期算法,用于生成活动编号类,特性是生成数字串较短,但指定时间内不能生成太多
   Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);

        // 打乱排序:2020年为准 + 小时 + 周期 + 日 + 三位随机数
        StringBuilder idStr = new StringBuilder();
        idStr.append(year - 2020);
        idStr.append(hour);
        idStr.append(String.format("%02d", week));
        idStr.append(day);
        idStr.append(String.format("%03d", new Random().nextInt(1000)));

        return Long.parseLong(idStr.toString());
3. 随机算法,用于生成策略ID  阿帕奇工具包 RandomStringUtils

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值