字节 AML / 火山方舟 AI Infra 一面:Agent Runtime、OS 与网络(2026 年 8 月)

更新于 2026-08-29

面经与参考答法

字节 AML / 火山方舟 AI Infra 一面:Agent Runtime、OS 与网络(2026 年 8 月)

这轮机器学习平台研发一面约一小时,方向偏机器学习系统与调度。流程从项目深挖进入 Agent Runtime 和沙箱容错,随后连续考察操作系统、TCP 异常断连与算法优化。回答重点不是只背定义,而是说明设计动机、故障边界和验证方式。

(1)自我介绍和项目经历怎样组织?

用“方向匹配—核心项目—个人职责—量化结果”组织。先用一句话说明自己的工程方向,再选与机器学习平台、Agent Runtime 或分布式系统最相关的项目,交代业务问题、系统规模和本人负责的模块。结果应尽量用任务成功率、P95 延迟、资源利用率、故障恢复时间或人工接管率说明,避免只罗列框架名称。

(2)怎样介绍一个项目的技术架构和核心技术点?

先画清数据流和控制流:请求从哪里进入,经过哪些服务、队列、状态存储和执行单元,结果怎样验证与返回。随后说明模块边界、关键数据结构、部署形态和外部依赖,再挑两三个真正影响可靠性或性能的决策讲取舍。最后明确自己设计、实现和排障的部分,以及上线后如何验证效果。

(3)项目最大的技术难点应该怎样回答?

选择一个存在真实约束的问题,而不是把“使用了某项技术”当难点。依次说明现象与影响、根因定位、候选方案、最终取舍、实现细节、验证指标和遗留边界。如果是可靠性问题,还要说明故障如何发现、状态是否可恢复、外部副作用是否可能重复,以及失败后如何降级或人工接管。

(4)Agent Infra 和 Agent Runtime 通常包含哪些模块?

可以把系统分为持久控制面和临时执行面。控制面负责身份与权限、任务编排、状态和检查点、预算、调度、工具注册、策略与审计;执行面负责模型调用、工具执行、沙箱生命周期和结果校验。每次运行都应有稳定的 run ID 和 step ID,状态写入持久存储,日志、指标和 Trace 贯穿模型、工具与沙箱。

Runtime 的核心不是循环调用模型,而是把不确定决策放入可恢复、可观察、受权限和预算约束的执行协议中。

延伸阅读:从零构建 Agent 运行时。

(5)Agent 调用 Sandbox 的链路怎样容错?Sandbox 运行中崩溃怎么办?

控制器先生成稳定的 job ID,持久化任务、镜像摘要、输入引用、权限、资源预算和状态,再把任务交给 Sandbox supervisor。执行状态至少区分 created、running、succeeded、failed、cancelling 和 unknown。

Sandbox 崩溃可以通过进程退出事件、心跳或租约超时、OOM 和资源告警发现。恢复时不要继续信任已损坏环境,而是在新的隔离环境中加载最近一次安全检查点和持久化产物。只有可重试且幂等的步骤才能在总预算内限次重试;参数错误、权限拒绝和确定性失败应直接终止或修正输入。

外部写操作可能已经成功但回执丢失,此时不能直接重做。应使用 operation ID 或幂等键查询真实状态,再决定读取结果、补偿、重试或转人工。临时文件不能充当恢复真相,关键产物应写入外部持久存储。最后还要确认进程组、网络、磁盘和配额已经释放,并用故障注入验证进程崩溃、超时、重复投递和检查点损坏等场景。

延伸阅读:Agent 沙箱、失败分类与恢复、检查点与断点续跑。

(6)为什么操作系统需要区分用户态和内核态?

核心目的是建立保护边界。普通程序不能任意访问其他进程内存、修改页表、控制设备或执行特权指令;这些能力只能由内核在更高特权级执行。应用需要资源时通过受控接口请求内核,内核完成权限检查、参数校验、资源记账和调度。

如果所有程序都拥有内核权限,一个越界指针或恶意程序就可能破坏整台机器。用户态与内核态配合虚拟地址空间,把应用故障限制在进程边界内,也让操作系统能够统一管理 CPU、内存和设备。

(7)什么情况下会发生用户态与内核态切换?

常见入口有三类:

  1. 系统调用,例如文件、网络、进程和内存管理请求;
  2. 异常或故障,例如缺页、非法指令、除零;
  3. 硬件中断,例如时钟、网卡和磁盘完成通知。

CPU 会保存必要现场、切换到内核入口和内核栈,并在处理完成后返回用户态。普通函数调用和访问已经映射的用户内存不会切换特权级。线程被抢占时,时钟中断先进入内核,调度器再决定是否进行上下文切换。

延伸阅读:操作系统的用户态、内核态与切换。

(8)操作系统怎样管理内存?为什么需要虚拟内存?

每个进程看到独立的虚拟地址空间,MMU 根据页表把虚拟页映射到物理页,TLB 缓存近期翻译。内核还负责物理页分配、页表权限、按需调页、缺页处理、共享映射、文件映射、回收和换出。

虚拟内存提供隔离与保护,让程序看到连续地址而不要求物理内存连续,也支持共享库、写时复制、按需加载和内存映射文件。它不等于“把磁盘当内存”;交换只是虚拟内存体系中的一种策略。虚拟地址和物理地址分离后,进程布局、物理页位置和资源回收可以独立变化。

延伸阅读:内存、虚拟内存与分页。

(9)已建立的 TCP 连接中,一端突然掉电,另一端状态会怎样变化?

如果对端没有机会发送 FIN 或 RST,本端不会立刻知道故障,连接通常仍保持 ESTABLISHED。TCP 没有凭空感知远端主机状态的能力。

本端继续发送数据时,会按重传策略尝试,超过实现规定的重传上限后才向应用报告错误并释放连接;启用 TCP Keepalive 时,探测连续失败也可发现失联。若连接长期无流量、没有 Keepalive 或应用层超时,它可能长时间保留。对端重启后已丢失旧连接状态,收到旧连接报文时可能回复 RST。

因此生产服务还需要应用层心跳、读写超时、连接租约和重连策略。必须区分主机掉电、进程退出、网络分区和优雅关闭,因为它们在线上的报文与状态变化不同。

延伸阅读:TCP 建连、断开与连接状态。

(10)两数之和怎样从排序双指针优化到一次遍历?

排序后使用左右指针,时间复杂度是 O(n log n),扫描为 O(n)。额外空间取决于排序实现;如果需要返回原始下标,通常还要把数值与下标绑定,不能简单声称空间为 O(1)。原地排序也会修改输入。

更优的常见方案是一次遍历哈希表:

function twoSum(nums, target) {
  const indexByValue = new Map();

  for (let i = 0; i < nums.length; i += 1) {
    const need = target - nums[i];
    if (indexByValue.has(need)) {
      return [indexByValue.get(need), i];
    }
    indexByValue.set(nums[i], i);
  }

  return null;
}

先查询补数、再写入当前元素,可以保证同一位置不会被使用两次;[3, 3]、目标值为 6 时也能正确返回两个不同下标。平均时间复杂度为 O(n),空间复杂度为 O(n)。测试应覆盖重复数字、负数、无解、单元素和存在多组答案的情况,并提前澄清返回一组下标还是所有组合。

延伸阅读:哈希表、缓存与去重。

反问与复盘

可以继续确认平台主要承载哪些训练或推理工作负载、调度目标如何在等待时间和资源利用率之间取舍、哪些模块自研或借鉴开源方案,以及岗位更偏控制面、调度器还是稳定性工程。反问重点是了解真实问题和成功标准,不是证明自己知道多少组件名称。

面经是候选人自述,解析为 Agent Journey 整理。更多大厂 AI / Agent 岗面经 · 按目标公司模拟面试