做了个功能,让商品已售数量涨起来

字数 1039阅读 38

产品经理说,现在商品详情页上显示已售数是实际数量,咱要让这个已售数加点水分进去,营造一点热销的氛围。我去,这也能想出来,好在哥这几年修养好了很多,很少怂产品经理了。看需求吧:

1,每个商品一天最多加100个已售数量,每个小时随机加1~10个。

2,不同商品加已售数量的时间要是随机的。

乍一看,还是有点蒙的。我们就分开来看:

第一个需求:其实就是微信红包的算法

第一条需求,把信息抽象出来可以理解为,分成24份(一天是24小时),每份随机值1~10,24份的总和是个固定值100。一开始的想法是,这可能要用迭代来做,进行反复尝试。然后就上网搜了下,关键字“总和固定 随机分”,居然搜到了很多关于微信红包算法讨论。

看一下微信红包要解决的问题,红包金额是固定,要分个人数要是固定的,每个人分到数是随机的。嘿嘿,确实和我的第一个需求是一样的。


红包算法(摘自网络)

这是我改造后的代码。有些不同的地方,已售数量只会是整形,所以不用考虑浮点精度按小数点后两位对齐的问题;另一个不同地方是,在我们的需求里max值有个固定的上限值10。

class AmountQueueInfo {

int remainSize;

    int remainAmount;

}

public static int getRandomAmount(AmountQueueInfo _queueInfo) {

// remainSize  剩余的次数

// remainMoney 剩余的待增量

    if (_queueInfo.remainSize ==1) {

_queueInfo.remainSize--;

        return _queueInfo.remainAmount;

    }

int min  =1; //

    int dynamicMax = _queueInfo.remainAmount *2 / _queueInfo.remainSize;

    int fixedMax  =10;

    int max = fixedMax

    int amount = CalculationUtil.randomIntBetween(min,max);

    amount = amount <= min ? min: amount;

    _queueInfo.remainSize--;

    _queueInfo.remainAmount -= amount;

    return amount;

}

算法搞定了,还有个需要抉择的地方,要不要一次性预计算后把随机值保存起来。我现在的做法是,每次计算,可以省下些保存空间。这样我只要在缓存中保存一个商品 remain_size和remain_amount量个值。

第二个需求:不同商品增加已售数量的时间要是随机的

对于一个商品的自增信息,在缓存中再增加一条信息 minute_in_hour,标识其这次是在这个点的xx分钟触发自增。

对于这个系统来说,在每个整点的时候,比方说 16:00、17:00点的时候针对每个商品随机生成1~60之间的一个整形数,记录在minute_in_hour中。这是一个整点执行的定时任务。

然后再启动一个每分钟都会执行的定时任务,检查整个缓存中所有商品列表自增任务,如果当前分钟点和该任务中的minute_in_hour是一致的,那么就进行随机自增值的计算(调用 getRandomAmount),然后更新缓存任务中的remain_size和remain_amount,以及数据库中该商品的已售数量。

隐形需求

商品下架后,就不需要运行自增任务;新建商品后,新增任务;24小时一个轮回走完后,重新赋予初始值。

虽然说需求中说是,一天加100个,每次步长1~10,为避免以后要改,这里把这两个值修改为可以配置的值。

这次设计特点

1,不需要增加数据表,毕竟也不是关键业务。

2,小概率事件,最后一次的步长可能会大于10,因为不影响。

总结

这两年大大减少了否产品的需求,换来的是,经常能在技术上有突破,尝试下其实是很有趣的事。

终身程序员小松哥

推荐阅读更多精彩内容