题目重点:把定长命令行解析与金额、状态转移和拒绝条件分离,明确回忆稿未公开的审批/取消语义。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版每条命令统一按五列解析,空字符串占位保留而不挤掉字段;金额为非负整数最小货币单位。
- CREATE 初始化 requested amount;APPROVE 设置 approved amount,要求 0≤approved≤requested;每次 CAPTURE 的正金额使累计 captured≤approved。完整捕获到 SUCCEEDED,部分到 PARTIALLY_CAPTURED。
- CANCEL 仅允许尚未 APPROVE 的 CREATED,转到 CANCELED;题目说‘把所有还没 approve 的都取消掉’,是单条 id 取消还是批量取消并不明确,训练版按单 id 命令解释。
解题路线
- 先写 parse_command,将空位置保留并检查 token 个数与命令类型;CREATE 的 payer/payee 必填,其余命令的占位须按具体格式校验。业务方法只接收解析后的强类型对象。
- 为每个 payment ID 保存 state、payer、payee、requested、approved、captured。每条命令先验证 ID 存在/不存在、当前状态、金额范围,再一次性提交状态与金额;失败不修改任何字段。
- APPROVE 时确定可捕获上限;CAPTURE 在 APPROVED 或 PARTIALLY_CAPTURED 中累加,部分/完成由累计与 approved 比较。重复 CAPTURE 必须有命令 ID/幂等规则才能无害重试;题目命令未显示这样的 ID,所以训练版默认重复会再次扣减,应明确此风险。
- CANCEL 的范围按训练合同限定,若题面允许 APPROVED 但未 CAPTURE 的撤销,需要另设 VOID/CANCELED 转移和资金预留释放规则。
- 以转移表测 CREATE→APPROVE→PARTIAL→SUCCEEDED、超过 approved、零金额、重复 CREATE、未知 ID、提前 CAPTURE、CANCEL 前后再命令、固定空占位与输入含空格。
手动走一遍
训练例 CREATE p1 100,APPROVE p1 80,CAPTURE p1 30 后状态 PARTIALLY_CAPTURED、captured=30;再次 CAPTURE 50 后 SUCCEEDED、captured=80;再捕获 1 应拒绝且状态不变。另一个仅 CREATED 的 p2 可 CANCEL,之后 APPROVE 被拒。具体 APPROVE 80 是否应小于 CREATE 100 是训练合同。
规模与取舍
C 条命令,用哈希表按 ID 查状态,期望 O(C) 时间、O(P) 空间(P 个 payment)。真实支付还需持久事务、审计与幂等协议,不能把内存 map 当生产账本。
易错点与追问
容易失分的边界
- 按空白 split 导致空占位丢失,金额列错位。
- 只按状态字符串转移,不维护 approved/captured 金额不变量。
- 先加 captured 后发现超限才报错,失败仍污染状态。
- 把作者不确定的 CANCEL 语义写成唯一原题。
- 把重复 CAPTURE 误当安全重试,造成二次扣款。
继续深挖
- 如果 CAPTURE 命令带唯一操作 ID,如何实现幂等响应重放?
- 同一 payment 并发 CAPTURE 时如何保证总额不超过 approved?
- 部分捕获后能否撤销剩余授权,状态需要怎样扩展?
