题目重点:分开菜单版本、点单、厨房任务与结算,处理改菜和重复发送。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 披萨order模拟只给题名,尺寸/饼底/toppings和价格规则未披露;按MenuItem变体和OrderLine定制选项归同订单OOD,确切计价留待核。
- 只有餐馆OOD名称,未给堂食/外卖或库存。练习选择堂食点单、厨房制作、账单支付;预约、配送和原料库存为扩展。
- 菜单价格和可售状态会变;订单保存点单时的item版本/价格快照,不能历史订单回查当前菜单重新计价。
解题路线
- 披萨定制训练可将size/crust/toppings作为订单行选项和值对象,校验兼容约束并由PricePolicy报价;选项去重、双份topping及变更退款规则需合同,不把“每项统一加价”当已给定。
- 实体MenuItem/Order/OrderLine/KitchenTicket/Payment职责分离。订单行有独立lineId、数量、定制选项和状态;同菜两种做法不能仅用itemId合并。
- 提交订单事务写订单与厨房outbox,厨房消费以ticketId幂等;网络重试不重复制作。厨房接单、制作和交付状态反馈影响哪些改单还能执行。
- 未开始制作的行可按策略改/取消,已经完成的行进入退款/人工处置而非直接从订单数组删掉;所有状态变更保留事件和版本。
- 账单来自权威订单行和折扣规则快照,支付异步与关单分开。拆单支付要控制已付总额和剩余金额,避免两人同时付全单。
手动走一遍
两份burger,一份不要洋葱:保存两行或可区分的modifier组。厨房ticket重发只生成一次任务;菜单从10涨到12后,已经确认10价格的订单不自动变12。
规模与取舍
订单更新按主键/行索引;单订单L行生成厨房任务O(L),存储O(历史订单行)。多个餐馆可分区,单厨房队列有容量和制作并行度限制,不能靠更多消费者自动缩短烹饪时间。
易错点与追问
容易失分的边界
- 把MenuItem直接当OrderLine,价格变更修改旧账单。
- 重复提交重复做菜。
- 没有区分订单支付完成与厨房履约完成。
继续深挖
- 合桌、分账时哪些行可以迁移,如何防重复付款?
- 厨房暂停某菜供应时如何处置已确认但未制作的订单?
