题目重点:Uber Phone Screen 面经要求为底层数据库查询和高层 CPU Metric 任务排程。用 DAG 拓扑排序,并区分同表底层查询合并与同级高层任务串行。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 每个任务有唯一 ID、类型(底层数据库查询或高层 metric)、依赖 ID;底层查询标明 table。依赖有向边 prereq→task,所有前置任务完成后任务才可开始。
- 本文训练约定:同一时刻已就绪且读取同表的底层查询,只有在查询语义允许合并时才作为一个批次执行;不同表查询可以并行。所有高层任务即使同层也串行执行。
- 题目只说可合并同表查询,未规定如何合并 SQL、锁或副作用;若查询结果语义不同,批次仍需分别产出每个任务的结果。
解题路线
- 建依赖图和入度表;先验证不存在未知任务 ID、自依赖和环。把入度为 0 的任务放入 ready 集合。
- 每轮从 ready 中提取可执行底层任务,按 table 分组;安全合并的组给出一个物理查询批次,但逻辑上仍要给组内每个 task 单独标记成功。高层 ready 任务按稳定 ID 顺序逐个放入串行批次。
- 一批成功后对该批逻辑任务的每条出边减入度,新的 0 入度任务进入 ready;直到全部任务完成。若 ready 空但仍有未完成任务,即存在环或失败依赖。
手动走一遍
Query A(table=trips)、Query B(table=trips)、Query C(table=drivers) 都无依赖;Metric M 依赖 A/B,Metric N 依赖 C。首轮可把 A/B 合成一组、C 独立执行;M/N 随后均就绪,但按题目高层串行要求需先执行一个,再执行另一个。
规模与取舍
建图与拓扑释放 O(V+E),同批按 table 哈希分组期望 O(V),空间 O(V+E)。若按任务 ID 排序保证确定顺序,最坏额外 O(V log V);真实完工时间还取决于各物理查询/高层任务的执行时长与资源配额。
易错点与追问
容易失分的边界
- 拓扑‘同层’只说明依赖上可并行,不能忽略题目对高层任务串行的额外资源约束。
- 把同表查询合并成一条 SQL 可能改变过滤/聚合语义;合并是优化选项,不是仅凭 table 相等就能保证正确。
- 只输出一套拓扑任务 ID 顺序,不说明物理合并与高层串行,无法满足题目中的 schedule 要求。
继续深挖
- 若查询可能失败,任务需要 pending/running/succeeded/failed 状态,依赖方只在前置成功后释放;重试使用幂等任务实例键。
- 若不同表查询也受连接池上限约束,可加入每类资源的并发令牌;调度目标可能从任意合法顺序变为最短完工时间,需另行定义优化标准。
