SWE / Senior SWE · VO System Design

Airbnb Booking System:可用性、并发确认与稳定分页

多篇 Onsite SD 反复出现 Booking System; 特别追问 pagination 与关系数据库索引,用事务边界解释防双订。

题目重点:多篇 Onsite SD 反复出现 Booking System; 特别追问 pagination 与关系数据库索引,用事务边界解释防双订。

题意与假设

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

  • 一套 listing 在同一入住夜晚最多一个 CONFIRMED reservation;将日期标准化为 listing 本地日历夜晚,查询输入可换成半开 [checkIn,checkOut)。
  • 支付是外部依赖,系统只能承诺内部状态与幂等,不假设支付超时等于失败。
  • 搜索/列表页可用性结果为候选快照,最终预订确认必须在受控写入边界重新校验。

解题路线

  1. 先画 Listing、CalendarNight/Inventory、Reservation、PriceQuote、PaymentIntent 与状态变迁,确定查询、暂锁、支付、确认和取消链路。
  2. 可用性查询按地理/日期/人数等过滤,读缓存或索引返回候选;最终确认对 (listingId,date) 逐夜做唯一约束/条件占用并在同事务中写 reservation,防并发双订。
  3. 价格 quote 带版本和过期时间,确认时核快照/币种/税费;支付用 idempotency key,未知状态查询/对账,库存 hold 到期后才释放。
  4. 列表分页按稳定 (rankScore,listingId) 或 (createdAt,reservationId) keyset cursor;持续变化的 rank 必须带快照版本,否则明确可能重复/漏项。配合索引选择合适排序前缀,避免深 offset。
  5. 监控冲突率、hold 过期、支付 UNKNOWN、确认延迟、日历与订单不一致、分页重复率。

手动走一遍

训练例:两人同时请求同一 listing 的同一晚,缓存都显示可住;最终写入唯一 (listingId,date) 约束使只一单占用成功。失败者得到重新搜索提示。若成功者支付响应丢失,用原 paymentIntentId 查询状态,不创建第二单。

规模与取舍

可用性搜索取索引/候选数与日期窗长度,确认写至少与预订夜晚数线性;分页用 keyset 索引约 O(log N+P) 返回 P 项。题目无负载,不能给固定容量。

易错点与追问

容易失分的边界

  • 以缓存可用性结果直接确认预订。
  • 先支付再无条件创建订单。
  • 把支付超时当失败重试新请求。
  • offset 深分页或 rank 变动未设稳定 tie-break。
  • 跨时区日期造成退房日/入住夜晚重叠误判。

继续深挖

  • Hold 时间与支付延迟如何取舍?
  • 跨 Listing 组合预订如何原子化?
  • 搜索排序不断变化如何分页?
  • 取消后多久恢复可订?
✓已复制微信号!