SWE · System Design / 设计追问

每周优惠服务:活跃分页、个性排序与一次领取

多pipeline导入优惠,按浏览历史排名并允许每用户领取一次。

题目重点:多pipeline导入优惠,按浏览历史排名并允许每用户领取一次。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 优惠有start/end,半开活跃区间;默认每页20个,可按条件筛选。
  • 一次领取是每user/deal唯一;是否有库存、领取后是否兑换未给,训练假设库存可选并单独设计。

解题路线

  1. 导入先规范化sourceDealId、内容版本、时间与可用范围,幂等upsert,状态发布采用outbox驱动搜索/推荐索引更新。
  2. 列表先过滤活跃和权限,再ranking。游标包含排序版本/快照及最后score/dealId,减少同分翻页漏重;动态个性排序需要session快照或容忍明确的更新语义。
  3. POST claim以(userId,dealId)唯一键防重复,事务中校验服务端时间与可选库存;索引上显示active不代表此刻还能领取,claim必须权威复核。
  4. 浏览日志异步更新兴趣profile,迟到事件按eventTime去重;召回/排序分离,故障可降级到合法热门优惠。过滤权限不能在推荐之后随便截断造成大量空页。

手动走一遍

优惠end=12:00,列表11:59显示;12:00点击领取返回已结束。重复点击同idempotencyKey返回同一领取结果而非二次扣库存。每周导入10万条是容量假设,活跃查询缓存不能跨user个性rank;可缓存公共候选并在请求端精排。

规模与取舍

读侧QPS×候选评分数决定服务成本,写侧导入峰值与索引延迟决定新鲜度。领取唯一键索引常见O(logN),跨region严格唯一需一致性设计。

易错点与追问

容易失分的边界

  • 页码offset遇排名变化可能漏重,不能保证稳定分页。
  • 先查“未领”再insert有竞态,必须数据库唯一约束或等价原子操作。

继续深挖

  • 同deal从两pipeline导入,如何判定业务同一优惠并合并版本?
  • 库存耗尽与多区域并发领取时选择强一致还是分区预算?
✓已复制微信号!