题目重点:从包裹与柜格分离建模,选择最小可容纳空柜,用条件更新与取件授权防止重复分配和误开门。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版 S/M/L 有固定兼容关系,选择最小可容纳且空闲的格子;最优指当前最小合适格,非未来到达包裹的全局最优。
- Package、Compartment、DeliveryAssignment 分开,取件授权是 assignment 的能力令牌,不仅是可猜测的柜号。
- 单站点先支持多线程并发,多站点调度、硬件开门失败和超时为追问;柜格尺寸之外的重量/温度要求另行澄清。
解题路线
- 先给主流程 allocate(package)、deposit(assignment)、pickup(token)、release/expire。定义柜格 FREE→RESERVED→OCCUPIED→RELEASING→FREE 与故障隔离,包裹状态不与柜格枚举混用。
- Allocator 查询兼容尺寸由小到大找空格,通过原子 FREE→RESERVED 获取所有权。单机用锁保护选择与移除;数据库用条件更新或行锁。不能在查询空格后无保护地异步分配。
- assignment 保存 package_id、compartment_id、版本、到期时间和请求幂等键。重复 allocate 同请求返回原分配;包裹已分配时拒绝第二个独立请求,避免一件占两格。
- deposit 需要确认物理放入和关门。若硬件命令超时,状态未知时隔离并核验,不能直接FREE给下一件。pickup先校验授权、状态和版本,再发送带命令id的开门请求;物理取出确认后释放。
- 取件令牌只存安全摘要并限制尝试,不写进公开日志。超时预约释放 RESERVED可行,但 OCCUPIED包裹不能因软件TTL自动视为空格;转入逾期处理/人工流程。
- 返回 no-compatible-free-slot 与 unsupported-package 区分,有利用户改投其他站点。指标看占用、分配失败、卡门和孤儿assignment,而非只看 API成功率。
手动走一遍
训练例 S格空、M格空、L格占用。M包裹只能选M;随后S包裹选S。两个线程同时投M时只能一方完成条件更新,另一方重新查或报满。取件命令发出后设备断线,柜格保持未知/隔离,不因接口超时给第三个包裹。
规模与取舍
固定尺寸档位查找 O(1),可用每档空格集合;任意连续尺寸需有序索引 O(log C)。持久状态更新受事务/锁竞争约束;算法复杂度不能代替硬件流程延迟。
易错点与追问
容易失分的边界
- 直接遍历列表找空格后写状态,出现并发重复分配。
- 最小尺寸贪心宣称对所有未来包裹全局最优。
- 取件码公开或用柜号直接授权。
- OCCUPIED到期直接释放,柜里仍有包裹。
- 硬件超时等同失败,重复开门或错误复用柜格。
继续深挖
- 任意长宽高包裹允许旋转,兼容判断怎么改?
- 软件状态与门传感器矛盾怎么修复?
- 优先级包裹是否预留大柜,怎样衡量损失?
- 多站点找柜与单站点分配如何分层?
