SWE · System / Product Design

Meta 刷题平台设计:判题沙箱、竞赛排名与已解题榜

设计代码提交、隔离判题、竞赛榜和累计已解题数榜,并分析存储、热点与结果一致性。

题目重点:设计代码提交、隔离判题、竞赛榜和累计已解题数榜,并分析存储、热点与结果一致性。

题意与假设

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

  • 先确认普通刷题、限时竞赛、累计solved榜是否全部要求;竞赛score与solved count不是同一个指标。训练支持三者但分别建模型。
  • 任意用户提交的代码视为不可信。判题需要语言、编译器、题目与测试集版本;时限、内存、网络权限和输出上限由题目配置。
  • 示例假设10万次提交/日、平均2秒CPU,平均约1.16提交/秒,平均CPU需求约2.3核;竞赛10倍峰值且编译/多测试需单独计入。

解题路线

  1. API createSubmission包含idempotencyKey、problemVersion、languageVersion、codeHash。持久化QUEUED状态与outbox后返回submissionId,调度器把任务给worker;客户端轮询或SSE读取状态,重复提交不会重复创建同一请求。
  2. worker启动受限隔离环境,挂只读测试与输入,限制CPU/RAM/进程数/磁盘/输出/网络与wall timeout。记录编译错误、运行错误、超限、答案错误等可解释结果;一次租约仅一个当前attempt有权提交终态。
  3. 代码与完整执行日志放对象存储,提交metadata/状态放数据库。测试集不直接返回客户端;评估结果绑定版本,重判产生新resultRevision而非悄悄覆盖历史。
  4. 已解题榜用(userId,problemId)首次AC唯一事实,重复AC不得重复加1;竞赛榜则按每题得分、罚时、最后有效提交与结束边界决定。事件驱动榜单需要幂等dedup和重放对账。
  5. 竞赛期间同题热点测试与镜像可预热,动态扩worker但保持安全配额;队列年龄与拒绝率是比平均QPS更实用的容量指标。用户公平队列限制单人刷提交,故障重试不会让其绕过限额。

手动走一遍

同一用户同题连续AC五次,solvedCount只增加1;但竞赛若每题允许更优解更新分数,需要保留最佳合规结果。worker超时后旧attempt迟到返回AC,应先核对leaseEpoch,避免覆盖新attempt结果。

规模与取舍

任务量为提交数×实际测试CPU成本,不是只有HTTPQPS;单题测试k个输入不能盲目每次启动k个大容器。榜单更新O(log N)有序索引,提交metadata与code/log存储按保留期和平均大小估算。

易错点与追问

容易失分的边界

  • 普通线程运行用户代码无法承担沙箱边界;隔离和资源控制必须独立设计。
  • 排行榜消费至少一次事件时没有唯一首次AC键,会因重放虚增。
  • 结束时提交、结束后判题的分数是否有效必须按提交时间合同,不按consumer处理时间随意决定。

继续深挖

  • 若测试集发现错误,如何重判并撤销旧AC?保留可重算事实与resultRevision,通过差量或整批重建榜单。
  • 累积榜要求精确即时rank还是几秒延迟?选择单索引、分片计数或周期快照,解释读写预算。
✓已复制微信号!