面试题:维持10%/10%/80%比例的优惠券分发方案实现问询
优惠券按比例分发的可行实现方案
问题核心
需要给每位结账用户分发三种优惠券中的一种,长期维持**10%免运费、10%买一送一、80%直减10%**的比例,且每个用户即时获得一张券,不能出现比例偏差累积。
方案一:预分配池+动态补充(绝对精准)
这是最能保证比例精准的方案,适合对统计精度要求极高的场景:
- 初始化一个固定大小的“券池”,比如包含10张免运费券、10张买一送一券、80张直减券,将池内券的顺序随机打乱
- 用户结账时,从券池的头部取出一张券发放给用户
- 当券池剩余数量低于阈值(比如10张)时,立即生成一个新的、同样比例的打乱后的券池,追加到当前券池的末尾
- 长期来看,每100个用户的分发完全符合目标比例,不会出现任何统计偏差
方案二:加权随机算法(带偏差校准)
如果不想维护券池,可采用加权随机,配合校准机制平衡短期偏差:
- 给三种券设置对应权重:免运费(10)、买一送一(10)、直减(80),总权重为100
- 每次生成一个0-99的随机整数:
- 随机数在0-9范围内:发放免运费券
- 随机数在10-19范围内:发放买一送一券
- 随机数在20-99范围内:发放直减券
- 若要进一步消除短期偏差,可添加偏差校准计数器:
- 实时统计每种券已发放的数量,计算实际占比与目标比例的差值
- 当某类券的实际占比低于目标时,临时调高其权重;高于目标时则调低,总权重保持100不变,直到比例回归正常范围
方案三:分步优先级随机(逻辑简洁)
你提到的优先级随机思路可以调整为分步计算概率,从而符合目标比例:
- 第一步:以10%的概率给用户发放免运费券,剩余90%的用户进入下一步
- 第二步:在剩余用户中,以**1/9(约11.11%)**的概率发放买一送一券,剩下的用户发放直减券
- 最终比例计算:免运费10%,买一送一=90%×1/9=10%,直减=90%×8/9=80%,完全符合要求
方案对比
- 预分配池:实现简单,比例绝对精准,适合用户量稳定的场景
- 加权随机:无需维护池,适合用户量波动大的场景,短期可能有微小偏差,长期回归精准
- 分步优先级随机:逻辑清晰,计算量小,适合后端快速迭代开发
内容的提问来源于stack exchange,提问作者Jinja2Django
相关产品推荐
相关产品推荐

