SWE / Intern / New Grad · Technical / Team Screen

Stripe Payment Match Invoice:ID 优先、金额匹配与宽容区间

把多阶段匹配写成确定的优先级,避免同金额多张发票、日期并列与宽容范围的歧义。

题目重点:把多阶段匹配写成确定的优先级,避免同金额多张发票、日期并列与宽容范围的歧义。

题意与假设

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

  • 训练版一次匹配一笔 payment,invoice 的 ID 唯一;金额统一币种且使用整数最小单位。
  • 先有 ID 命中即返回,即使金额不一致也按第 1 段规则返回;若实际题面要求 ID+金额同时满足,应替换该判定。
  • 无 ID 命中时,同金额候选选日期最早;再无候选时,满足 |invoice.amount−payment.amount|≤forgiveness 的候选选日期最早;同日用原始输入顺序稳定破平局。

解题路线

  1. 先明确三个优先层级和每层的比较器,写成能独立测试的 matchById、matchExactAmount、matchWithinTolerance。上一层有结果立即返回,不能让日期更早的低优先级候选盖掉 ID。
  2. 在单笔情况下,ID 可用哈希索引 O(n) 预建;金额候选若列表未排序,线性扫描并维护最优 (date,index),无需先全量排序。
  3. 金额边界用整数和绝对差,forgiveness<0 视为无效参数;币种不同先禁止比较,除非题面提供明确 FX 规则。
  4. 批量支付若同一 invoice 只能用一次,需要额外 used 集与原子占用;若多笔可共享则不需。此约束题目未公开,不能擅自套到账务对账。

手动走一遍

训练例:payment id=missing、amount=1000,候选 A(1000, 2025-01-03)、B(1000, 2025-01-01)、C(995, 2024-12-01)。即使 forgiveness=10,也选 B,因为 exact amount 层优先;若 payment 指向 ID=A,则选 A。这个例子检验优先级而非宣称题目样例。

规模与取舍

单笔、n 张发票最多三次线性扫描 O(n) 时间、O(1) 额外空间;多笔可建 ID/金额索引减少常见查询,但维护最早日期与重复占用状态要更复杂。

易错点与追问

容易失分的边界

  • 把全部候选按日期排序后取首张,破坏 ID 和 exact amount 的优先级。
  • 货币转 float 后做等值或宽容判断。
  • 没有约定同日期平局、ID 重复、不同币种和单发票复用。
  • 把第三段转述当作有完整官方规格。

继续深挖

  • ID 命中但金额不同,应返回、报错还是落到下一层?
  • 批量 payment 与 invoice 一对一全局匹配时,局部最早日期还最优吗?
  • 发票日期有时区与精度差异,稳定排序键如何定义?
✓已复制微信号!