面灵AI→

字节跳动 AI Agent 开发面经合集:动态 UI 渲染、MCP 与 Skill 设计

轮次
面试合集
时间
2026-10
来源
牛客网

《面试题目》

面经 01

面试岗位:AI 全栈开发工程师 | 面试时间:2026 年 10 月 13 日

  1. 自我介绍。
  2. 实习:讲一下项目有哪些模块,分别负责什么,怎么交互的?
  3. 你负责哪个模块?
  4. 这个数据转发工作经历了哪些模块?
  5. 讲讲你说的前台和后台分别是承担什么工作?
  6. 前台有哪些主要的页面和业务?
  7. 设计模式是什么?
  8. 技术选型怎么做的?
  9. DDS 是什么?
  10. 为什么用 DDS?
  11. 怎么保证数据的可靠性?
  12. 怎么取舍 DDS 和 HTTP 的数据通信时延?
  13. 现在系统的时延状态是怎样的?
  14. 这个 DDS 是怎么设计的?
  15. 无人机集群规模是怎样的?
  16. 如果两个飞机数据被篡改会发生什么?
  17. 如果飞手抢夺控制软件会怎么处理当前任务?
  18. 无人机哪些数据要同步更新?
  19. 举个例子?
  20. 频率大概是怎样的?
  21. 在这个频率下有没有遇到前端卡顿的问题?
  22. 怎么解决的?
  23. 具体是怎么实现的呢?
  24. 前端:说说 URL 到页面显示经历的过程?
  25. 看一下这段代码(一段 JS 事件循环的代码),说说它的输出是什么?
  26. 说一下为什么是这样的?
  27. Promise 里面持续 resolve 循环生成微任务会发生什么?
  28. 后端:数据库应该用的多吧?
  29. 说说 MySQL 的四种事务隔离级别以及如何实现的?
  30. RC 上的是什么锁?
  31. MySQL 索引用的数据结构是什么?
  32. 为什么用 B+ 树不用红黑树?
  33. 只是结构特性决定的吗?
  34. AIcoding:平时主要用 AI 做什么?
  35. 怎么做的?
  36. 写了什么 skill?
  37. TDD 驱动是怎么进行的?
  38. 手撕:求字符串 s 到其子序列 t 的实现(删除操作)种类数量,提示用动态规划做。

面经 02

面试岗位:AI Agent开发岗 | 面试时间:2026 年 10 月 13 日

  1. 学校课程多不多?
  2. 能实习多久?
  3. 你课程上的怎么样?
  4. 那个操作系统、算法什么这些都上了吗?
  5. 讲一下你在最近的这段实习做了什么。
  6. 你说一下这个,比如说在你的这个工作台里,我输入一句 prompt,然后一直到它能够实现、生成这些东西,这个整条链路是怎么转起来的?
  7. 这块有了解吗?
  8. 你刚刚描述的这一段的整个链路其实是一个比较顺的链路,对吧?
  9. 那整个 Agent 在读用户的 prompt 以及你的 skill 的过程当中,它一轮就能完成这个订单整个的生成吗?
  10. 还是说它这个 Agent 会有多轮的这种思考或者自动添加的过程,这些是谁来做的?或者怎么做的?
  11. Agent 的这种循环,或者 Agent 这个 loop 的一些架构有了解过吗?
  12. 你刚才说的整个路径当中其实有一个关键的点,就是前端后续的一些操作都是基于后端给你的返回的 JSON 去做的,对吧?
  13. 这个 JSON 的生成成功率是怎么样的?
  14. 就是你怎么约束说一定能进到你后续的这个链路里?
  15. 你拿到这个 JSON 然后去渲染这个 widget,有没有自己做过比如说技术方案的一些调研,看过 ChatGPT 或者 Claude Code 他们在做类似的 UI 动态渲染的时候用的都是什么方案?
  16. 然后你们用的是什么方案?
  17. 就是比如看一下其他的产品,国内的比如说豆包、Kimi,或者国外的 ChatGPT、Claude Code,他们在做这种动态 UI 的渲染的时候,用的是什么样的方案?
  18. 然后你们为什么是说采用你们现在这套方案?这个有做过对比吗?
  19. 那你刚才说到,你们这个 widget 或者是这个东西,它是有交互的是吧?可以去点确定或者编辑、删除这些。那这个过程当中再和后端通信的时候,这块是怎么做的?
  20. 你修改了之后,这个用户的行为,包括他定的这些东西,你得存到后端的数据库里面不是吗?
  21. 就是跟后端服务的通信有没有吗?还是说就是纯前端的一个改动?
  22. 这个组件是动态生成的对吧?
  23. 那你动态生成的时候,你怎么绑定某一个按钮,可以怎么请求后端的哪个接口?
  24. 我是想了解这个事情,你这个方案是怎么设计的?
  25. 那你的这个渲染的 UI 的页面,又可以在用户侧、端侧去做一些交互,对吧?你交互完了之后又要去和后端的服务去做一个通信,是吧?UI 怎么和后端的服务去做一个映射或者是捆绑呢?
  26. 那不同的按钮或者不同的操作行为,它肯定最后是有不同的这个请求的,对吧?都对应一个后端接口,对吧?只不过是改一些入参什么的?
  27. 有听说过 Dynamic UI 或者是 A2UI 的这种方案吗?
  28. 你们这个是流式渲染是怎么做的?就是 Markdown 渲染是吧?
  29. 结构化的那个 JSON,就是你们整个的相当于一个小卡片,渲染出来是流式出来的,还是说所有的东西都准备好了之后一下出来?
  30. 增量流式输出会出现哪些问题?
  31. 你刚才说那个你们那个工具调用有一些 MCP 是吧?然后前面还有一些 skills,你这个对 MCP、skills 这些工具的了解大概是什么程度?
  32. 有了解过吗?
  33. 有自己去实现过一些 MCP Server,或者是自己写过 Skills 吗?
  34. 那你说一下一个 Skill 有哪些组成部分?
  35. 如果让你写一个 Skill,你会怎么写?
  36. 你说的这所有的内容是写在一个文件里的是吧?
  37. 你觉得一个项目里面的话最多能加载多少个 skill 呢?
  38. 你在做这个前端开发的时候,最后你们的这个项目部署上线,我面向用户去用,假如说我作为一个用户去访问你们的这个站点的话,你们这个站点给我一个 URL,一直到我在浏览器里面把这个 URL 打开,这个过程当中经历了哪些环节?
  39. 其实这是个比较常规的一个链路对吧?
  40. 就是从 DNS 的解析到整个的页面去渲染出来,那现在比如说,从你刚才说的这个所有的节点里面,DNS 解析、TCP 连接、HTTP 请求、包括服务端的返回静态资源、然后拼接这个页面,每一个环节想去让你去做一下优化,你会想哪些方案去做这个链路上的优化?
  41. 就现在比如说这个站点性能有问题,想让你在你刚才所描述的所有的环节里,每一个节点都找一个优化方案,你会怎么去测?
  42. 你听说过闭包这个概念吗?
  43. 我现在想让你写一个闭包函数,这个函数就叫做 A,然后这个 A 每次执行的时候可以做一个计数器的效果,比如说我 A 调用一次就返回一,第二次返回二,第三次返回三(P1)。
  44. 你平时在做这个前端开发的时候,会请求后端的接口对吧?不需要写测试用例,你直接说一下思路。

面经 03

面试岗位:AI 全栈开发工程师 | 面试时间:2026 年 10 月 12 日

  1. 有在大型公司、正规企业实习过吗?

Agent(50%-70%)

  1. Agent 是用的框架吗?
  2. 除了步数耗尽以外,还有什么方法防止 Agent Loop 死循环?
  3. ReAct、Workflow、Replan 他们分别在什么场景下适用?
  4. MCP 和 function call 有什么区别?
  5. Agent 的 state、context、memory、MCP,分别是干什么的?
  6. Codex 他的上下文压缩机制,有什么优势?
  7. 已经有了一个 session,怎么跨会话?或者说怎么在新的会话当中使用之前那个会话的信息?
  8. Skill、MCP、CLI、plugin 分别适用在哪些场景下?
  9. 如果有 100 个 skill 和 100 个 MCP,应该如何去处理?
  10. 怎么让 Agent 知道精确地匹配到你写的 MCP?
  11. SKILL 由哪些组成部分?
  12. 从 URL 到用户浏览器,是一个怎么样的过程?
  13. 这些过程哪些地方你可以去优化?
  14. DNS 优化有哪些?

《参考解析》

JSON 驱动的动态 UI 渲染与交互回传

这套方案的本质是「模型产出受约束的结构,前端按结构渲染组件」。链路:模型返回带类型标识和参数的 JSON(组件名 + 属性 + 数据 + 动作声明),前端有一份组件注册表,按类型映射到真实组件;JSON 用 schema 或结构化输出约束,解析失败要有降级(提示重试、回退成纯文本),并把解析成功率、失败样本记进日志。交互回传是这套方案的难点:按钮的「动作」不能由模型自由编一个 URL,而应声明成后端预定义的动作标识,前端用映射表把动作 id 换成真实接口与参数,入参再按 schema 校验;用户编辑后的状态先落本地,再按动作提交到后端并落库,同时把用户改过的值回灌进会话上下文,保证模型下一轮看到的是最新状态。要能对比业界路线:OpenAI 的交互式组件依赖客户端预置组件与结构化输出,A2UI 这类方案把「组件描述 + 动作绑定」标准化,好处是前端不必为每个新组件发版、安全边界收敛在注册表内,代价是表达能力受注册表限制。面试官追问「UI 怎么和后端映射」,正确的回答是映射表与动作 id 由后端契约决定,模型只负责选择,不负责拼接口。

流式渲染与增量输出的坑

流式输出把「一次完整结果」拆成「边生成边渲染」,体验好但引入四类问题:结构不完整(JSON 流到一半不是合法 JSON,不能直接 JSON.parse,要用增量解析器或先按 Markdown 增量渲染再在结束帧替换成组件)、渲染抖动(卡片高度反复变化、闪烁,要靠占位骨架与最小高度约束)、顺序与依赖(后到的字段依赖前面的字段,要按声明顺序渲染并处理字段缺失)、以及错误可恢复性(流中断时要有明确的失败态与重试入口,而不是留下半张卡片)。工程上把「文本通道」和「结构通道」分开:Markdown 走增量渲染,结构化卡片走「先收完整帧再挂载」,并给每个可交互组件一个稳定 key,避免流式重渲染时把用户已经输入的内容冲掉。指标上要监控首字延迟、结构帧到达率、解析失败率与中断率,否则只看「流式很流畅」是自欺。

MCP、Skill、CLI、plugin 的边界与加载策略

四者解决的是不同问题:MCP 是工具与资源的接入协议,适合需要独立进程、统一鉴权、跨应用复用的能力(数据库查询、第三方 API);Skill 是写给模型的说明文档与资源包,适合承载业务规则、流程步骤和多文件参考资料,本质上靠上下文生效;CLI 是最原始的形态,能力确定、可组合、可被脚本与人共用,适合本地确定性操作(构建、部署、代码生成);plugin 是宿主应用的扩展点,由宿主加载并定义生命周期,适合与宿主深度耦合的能力(编辑器、IDE、浏览器扩展)。选型判据:能力是否需要跨应用复用、是否有凭据与权限边界、是否需要确定性执行。Skill 的组成一般包含元数据(名称与「何时使用」的描述)、正文指令(步骤、约束、输出格式)、可选脚本与参考资料,写法上把触发条件写在最前面、步骤可执行、边界写清。加载数量是硬约束:每个 Skill 的描述都进系统提示,几十个描述的 token 开销与选择噪声就很大,正确做法是分级——常驻少量高层索引,按需展开正文,用检索或显式路由选出候选;100 个 MCP 同理,靠命名空间、按会话授权和懒加载,只把当前任务相关的工具暴露给模型。「怎么让 Agent 精确匹配到 MCP」的答案是描述与命名要写清适用与不适用场景,并把工具选择纳入评测,而不是靠模型自己猜。

Agent Loop 防死循环与 ReAct、Workflow、Replan 的适用场景

防死循环不能只靠步数上限,要多层兜底:①重复检测,对「工具名 + 关键参数」做哈希,连续 N 次相同调用就中断;②无进展检测,比对每轮的状态或产物是否变化,长时间无变化即停止;③预算约束,同时卡步数、token 与墙钟时间;④错误熔断,同一个工具连续失败就换路或直接上报;⑤状态校验,要求每轮必须产生可验证的进展(新增信息、状态迁移),否则回退;⑥人工介入点,在关键写操作前暂停等确认。选型上:ReAct 适合信息获取路径不确定、需要根据反馈调整的开放任务,代价是轮次多、延迟与成本不可控;Workflow 适合步骤可枚举、要求可复现与可审计的流程;Replan 适合计划容易失效的场景(外部状态变化、长任务中途环境改变),代价是额外一次规划调用与上下文膨胀。回答时把判据说清楚(路径能否穷举、失败代价、实时反馈需求),比背定义更有说服力。

从 URL 到页面的全链路与逐节点优化

链路按顺序:DNS 解析 → TCP 握手(HTTPS 再加 TLS)→ 发 HTTP 请求 → 服务端处理并返回 HTML → 浏览器解析 HTML、构建 DOM 与 CSSOM → 遇到资源发起请求(JS 阻塞、CSS 阻塞)→ 执行 JS → 布局与绘制 → 合成上屏。逐节点优化:DNS 用 DNS 预解析、减少域名数、加长 TTL 与就近解析;连接层用 CDN 边缘节点、HTTP/2 多路复用、TLS 1.3 与会话复用、连接预热;请求层做资源合并与按需加载、缓存(强缓存与协商缓存、ETag)、压缩(gzip/brotli)、接口合并与并行;服务端做静态资源直出、SSR 或流式渲染、结果缓存;渲染层把阻塞脚本改成 defer/async、关键 CSS 内联、图片懒加载与预加载、避免布局抖动、用骨架屏提升体感。怎么测是这题的加分项:用 Lighthouse 与 WebPageTest 拿 Lab 数据、用 RUM 与 PerformanceObserver 拿真实用户的 LCP、INP、CLS,把优化前后按同一环境对比;再对照 Nginx 日志与服务端耗时把「网络慢」和「后端慢」分开,避免拍脑袋优化。批量图片请求的场景则答:合并成雪碧图或按需懒加载、用同一域名的 HTTP/2 连接复用减少建连、加缓存与 CDN 命中率、用响应式图片按屏幕尺寸取合适分辨率、通过预加载可视区图片拉齐首屏。

手撕:闭包计数器与子序列计数

闭包计数器用一个外层函数持有私有变量,内层函数每次调用自增并返回:function A() { let n = 0; return function () { return ++n; } }(题干是「A 每调用一次返回一、二、三」,等价写法是 const A = (() => { let n = 0; return () => ++n; })())。要点是讲清闭包为什么能保住状态(内层函数持有对外层作用域变量的引用,外层执行完栈帧销毁但变量被引用而保留)、var 与 let 在循环里的差异、以及内存角度(闭包会让变量常驻,不再需要时置空引用避免泄漏)。「字符串 s 到子序列 t 的删除方案数」是标准的二维 DP:dp[i][j] 表示 s 的前 i 个字符中凑出 t 的前 j 个字符的方案数,边界 dp[i][0] = 1;当 s[i-1] == t[j-1] 时 dp[i][j] = dp[i-1][j-1] + dp[i-1][j](用这个字符或不用),否则 dp[i][j] = dp[i-1][j]。先讲清状态定义与转移含义再写代码,并主动提边界(t 为空、s 比 t 短则结果为 0)与空间优化(只保留上一行),数据量大时注意取模。