美文网首页
微信红包的随机算法是怎样实现的?

微信红包的随机算法是怎样实现的?

作者: babybus_hentai | 来源:发表于2016-06-08 10:34 被阅读986次

先上代码:

public static double getRandomMoney(LeftMoneyPackage _leftMoneyPackage){
    // remainSize 剩余的红包数量
    // remainMoney 剩余的钱
    if (_leftMoneyPackage.remainSize == 1) {
        _leftMoneyPackage.remainSize--;
        return (double) Math.round(_leftMoneyPackage.remainMoney * 100) / 100;
    }
    Random r = new Random();
    double min = 0.01;
    double max = _leftMoneyPackage.remainMoney / _leftMoneyPackage.remainSize * 2;
    double money = r.nextDouble() * max;
    money = money <= min ? 0.01 : money;
    money = Math.floor(money * 100)/100;
    _leftMoneyPackage.remainSize--;
    _leftMoneyPackage.remainMoney -= money;
    return money;
}

以上代码仅供参考,涉及商业计算要用java.math.BigDecimal.

再说结论:

  • 先抢后抢拿到红包的大小的期望是大致相等的,所以还是先下手抢吧
  • 后抢的人方差大(依赖前面人抢的多少),波动较大,有较大几率拿到“手气最佳

测试数据:
测试结果测试随机红包
以上面的初始化数据(30人抢500块),执行了两次,结果如下:

// 第一次
15.69    21.18    24.11    30.85    0.74    20.85    2.96    13.43    11.12    24.87    1.86    19.62    5.97    29.33    3.05    26.94    18.69    34.47    9.4    29.83    5.17    24.67    17.09    29.96    6.77    5.79    0.34    23.89    40.44    0.92

// 第二次
10.44    18.01    17.01    21.07    11.87    4.78    30.14    32.05    16.68    20.34    12.94    27.98    9.31    17.97    12.93    28.75    12.1    12.77    7.54    10.87    4.16    25.36    26.89    5.73    11.59    23.91    17.77    15.85    23.42    9.77

对应图表如下:
第一次


第二次:


多次均值
200次


2000次

可以看到,这个算法可以让大家抢到的红包面额在概率上是大致均匀的。

微信红包的架构设计简介
概况:2014年微信红包使用数据库硬抗整个流量,2015年使用cache抗流量。

  • 微信的金额什么时候算?
    答:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储。
    采取实时计算金额的考虑:预算需要占存储,实时效率很高,预算才效率低

  • 实时性:为什么明明抢到红包,点开后发现没有?
    答:2014年的红包一点开就知道金额,分两次操作,先抢到金额,然后再转账。
    2015年的红包的拆和抢是分离的,需要点两次,因此会出现抢到红包了,但点开后告知红包已经被领完的状况。进入到第一个页面不代表抢到,只表示当时红包还有

  • 分配:红包里的金额怎么算?为什么出现各个红包金额相差很大?
    答:随机,额度在0.01和(剩余平均值2)之间。
    例如:发100块钱,总共10个红包,那么平均值是10块钱一个,那么发出来的红包的额度在0.01元~20元之间波动。
    当前面3个红包总共被领了40块钱时,剩下60块钱,总共7个红包,那么这7个红包的额度在:0.01~(60/7
    2)=17.14之间。
    注意:这里的算法是每被抢一个后,剩下的会再次执行上面的这样的算法(Tim老师也觉得上述算法太复杂,不知基于什么样的考虑)。

  • 红包的设计
    答:微信从财付通拉取金额数据过来,生成个数/红包类型/金额放到redis集群里,app端将红包ID的请求放入请求队列中,如果发现超过红包的个数,直接返回。根据红包的逻辑处理成功得到令牌请求,则由财付通进行一致性调用,通过像比特币一样,两边保存交易记录,交易后交给第三方服务审计,如果交易过程中出现不一致就强制回归。

  • 发性处理:红包如何计算被抢完?
    答:cache会抵抗无效请求,将无效的请求过滤掉,实际进入到后台的量不大。cache记录红包个数,原子操作进行个数递减,到0表示被抢光。财付通按照20万
    笔每秒入账准备,但实际还不到8万每秒。

  • 通如何保持8w每秒的写入?
    答:多主sharding,水平扩展机器。

  • 据容量多少?
    答:一个红包只占一条记录,有效期只有几天,因此不需要太多空间。

  • 询红包分配,压力大不?
    答:抢到红包的人数和红包都在一条cache记录上,没有太大的查询压力。

  • 一个红包一个队列?
    答:没有队列,一个红包一条数据,数据上有一个计数器字段。

  • 有没有从数据上证明每个红包的概率是不是均等?
    答:不是绝对均等,就是一个简单的拍脑袋算法。

  • 拍脑袋算法,会不会出现两个最佳?
    答:会出现金额一样的,但是手气最佳只有一个,先抢到的那个最佳。

  • 每领一个红包就更新数据么?
    答:每抢到一个红包,就cas更新剩余金额和红包个数。

  • 红包如何入库入账?
    数据库会累加已经领取的个数与金额,插入一条领取记录。入账则是后台异步操作。

  • 入帐出错怎么办?比如红包个数没了,但余额还有?
    答:最后会有一个take all操作。另外还有一个对账来保障。

本文参考自知乎陈鹏 回答

相关文章

  • 微信红包随机算法初探

    本文简书备份地址:微信红包随机算法初探 最近看了一篇文章,讲微信红包随机算法的。感觉很不错,所以自己实现了下,并进...

  • 微信红包的随机算法是怎样实现的?

    先上代码: 以上代码仅供参考,涉及商业计算要用java.math.BigDecimal. 再说结论: 先抢后抢拿到...

  • 正态分布

    最近公司产品上线一个类似于微信抢红包功能,需要实现红包金额的随机分配算法。 基本约束: 发放红包时,每个人所能得到...

  • [code snippet]微信随机红包算法实现

    为了保证不会出现领取的红包比0还小的情况,也就是说要保证每个人都能至少领到min_amount大小的红包,所以只对...

  • 基于微信随机红包算法

    微信随机红包算法, 前提为知道红包的数量, 红包总金额, (红包最小金额, 0.01)为防止浮点数计算出现问题,此...

  • c++代码模拟微信抢红包算法,没人抢得过你!

    算法说明: 微信抢红包基本功能为:提示输入红包总金额和红包份数,保证每个红包的金额随机且不为0,每个红包的金额差距...

  • 微信红包算法 - OC

    知乎-微信红包算法 一个简单的分配算法:随机分配n次把每次分配的部分减去,在进行随机分配分配过程中,考虑好,分配为...

  • 红包随机算法Java实现

    需求:红包总金额随机后每份金额:最大值200, 最小值0.01;最大份数100;工具:idea参考:微信红包算法以...

  • PHP 仿微信红包金额随机

    博主寒冰最近闲来无事。就想研究一下微信红包的金额随机算法。早在微信红包刚出来的时候就研究过。始终不得要领。后来,通...

  • 我也来谈谈类似微信红包算法实现

    最近在做一个类似微信红包的 拼手气红包的算法实现。 需求: 客户抛出一个想法 :他想在他的APP中加入类似微信红包...

网友评论

      本文标题:微信红包的随机算法是怎样实现的?

      本文链接:https://www.haomeiwen.com/subject/ruljdttx.html