面灵AI→

字节跳动 AI全栈开发 一面

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 请做一下自我介绍。

实习项目

  1. 讲一下项目有哪些模块,分别负责什么,怎么交互的?
  2. 你负责哪个模块?
  3. 这个数据转发工作经历了哪些模块?
  4. 你说的前台和后台分别是承担什么工作?前台有哪些主要的页面和业务?
  5. 设计模式是什么?
  6. 技术选型怎么做的?
  7. DDS 是什么?为什么用 DDS?
  8. 怎么保证数据的可靠性?
  9. 怎么取舍 DDS 和 HTTP 的数据通信时延?
  10. 现在系统的时延状态是怎样的?
  11. 这个 DDS 是怎么设计的?
  12. 无人机集群规模是怎样的?
  13. 如果两个飞机的数据被篡改会发生什么?
  14. 如果飞手抢夺控制软件会怎么处理当前任务?
  15. 无人机哪些数据要同步更新?举个例子,频率大概是怎样的?
  16. 在这个频率下有没有遇到前端卡顿的问题?怎么解决的?具体是怎么实现的?

八股·前端

  1. 说说 URL 到页面显示经历的过程?
  2. 看一下这段代码(一段 JS 事件循环的代码),说说它的输出是什么?为什么是这样?
  3. Promise 里面持续 resolve 循环生成微任务会发生什么?

八股·后端

  1. 数据库用得挺多的吧?说说 MySQL 的四种事务隔离级别以及它们是如何实现的?
  2. RC(读已提交)上的是什么锁?
  3. MySQL 索引用的数据结构是什么?为什么用 B+ 树不用红黑树?只是结构特性决定的吗?

AI Coding

  1. 平时主要用 AI 做什么?怎么做的?写了什么 skill?
  2. TDD 驱动是怎么进行的?

手撕

  1. 手撕:求字符串 s 到其子序列 t 的实现(删除操作)种类数量,提示用动态规划。
  2. 你有什么想问我的?

《参考解析》

项目深挖的应对方式是「一张数据流图 + 每层都说清取舍」:面试官从模块划分一路问到集群规模、篡改、抢控制权,考察的是你对数据链路和上下游业务的理解,而不是某段代码。准备时画一张图:数据在哪些组件间流动、每个组件的职责、同步还是异步、频率量级、失败怎么处理。前台通常指面向操作人员的界面(实时状态展示、任务下发、告警、历史回放),后台负责接入、聚合、存储与转发;前后台之间常常是控制面走 HTTP(登录、配置、任务管理),数据面走发布订阅(高频状态)。被问「设计模式」时,别背 23 种,就讲这个项目真实用到的:生产者—消费者、观察者/发布订阅、分层与依赖注入、状态机(任务生命周期)、适配器(屏蔽不同机型协议)。被问技术选型时给三个维度:数据频率与实时性要求、可靠性与一致性要求、团队维护成本。这样即使细节记不清,逻辑也是自洽的。

DDS 是这道项目的技术核心,要能说清它解决什么问题、QoS 怎么用:DDS(Data Distribution Service)是 OMG 定义的以数据为中心的发布订阅中间件,常用于机器人、无人机、车载与工业场景:节点按 Topic 发布数据,订阅方按 Topic 接收,通过 QoS 策略约定可靠性(BEST_EFFORT / RELIABLE)、历史深度(KEEP_LAST / KEEP_ALL)、deadline、liveliness、资源限制与分区。它相比 HTTP 的优势是去中心化(无需请求—响应往返、无 broker 单点)、支持多对多与自动发现、延迟低且可预测,适合高频状态量(姿态、位置、电量等几十到几百赫兹的数据);相比自研 UDP 协议的优势是有标准的发现机制与 QoS 语义。可靠性要落到具体机制:RELIABLE 走心跳与 ACK/NACK 重传、序列号去重与乱序重组、持久化 publisher 保证晚加入的订阅者也能拿到最新值;再叠一层应用级校验(CRC、时间戳、序号)。至于 DDS 与 HTTP 的取舍,标准答法是按数据类型分级:控制指令与配置用 HTTP/请求响应(可靠、易调试、可鉴权),高频状态与控制流用 DDS(低延迟、可丢可覆盖),并说明你量的指标是端到端 P99 时延、丢包率与 CPU 占用,而不是只看平均延迟。

「数据被篡改」「飞手抢控制权」这类场景题在考安全与仲裁设计:数据篡改的后果链条要讲完整:错误数据进入融合与显示 → 操作员基于错误态势决策 → 触发错误指令,所以防护要放在入口和链路两处:来源侧做身份认证与消息签名(每帧带 HMAC/序号,防伪造与重放),链路侧做完整性校验与合理性检查(数值范围、变化率、与惯导/其他传感器交叉验证),发现异常时降级为「标记不可信 + 提示操作员 + 回退到安全策略」而不是静默丢弃。控制权抢夺的实质是「同一目标被多个控制源同时下发指令」,需要一套仲裁机制:先定义权限模型(谁在什么状态下有控制权、优先级、超时释放、显式接管流程),再用版本号或租约(lease)保证同一时刻只有一个有效控制源,冲突时按优先级裁决并把接管事件广播给其他操作端;同时要保证「失去控制权」的飞手能看到明确的状态提示,避免两边都以为自己在控。答题时补一句「所有接管与拒绝都要留审计日志」,这类系统的可追责性往往比功能本身更重要。

前端八股这三题是连在一起的,核心是浏览器渲染流水线与事件循环调度:「URL 到页面显示」按顺序说:URL 解析与 DNS 查询(浏览器缓存 → 系统缓存 → 递归解析)→ 建立 TCP 连接(有 HTTPS 还要 TLS 握手,TLS 1.3 可减少往返)→ 发送 HTTP 请求并经过代理/CDN → 服务端返回 HTML → 浏览器解析 HTML 构建 DOM、解析 CSS 构建 CSSOM,两者合成渲染树 → 布局(layout/reflow)→ 分层与绘制(paint)→ 合成(composite)上屏;遇到 <script> 会阻塞解析(加 defer/async 可改善),CSS 会阻塞渲染。优化手段对应每个阶段:DNS 预解析、连接复用与预连接、CDN、缓存与压缩、关键 CSS 内联、资源懒加载。事件循环部分要能现场推输出顺序:先执行同步代码(含 async 函数中 await 之前的部分),清空微任务队列(Promise 回调、queueMicrotask、MutationObserver),再取一个宏任务(setTimeout、I/O、事件回调),如此往复。Promise 里持续 resolve 生成新微任务会导致微任务队列永远清不空——宏任务与渲染被饿死,页面直接卡死,所以轮询、批量任务要让出控制权(setTimeout(…, 0) 或 requestIdleCallback)。原帖作者的复盘也印证了这一点:追问会一直往下,准备时不能只背结论,要能解释「为什么会这样」。

后端两题(隔离级别与锁、B+ 树)要答到实现机制,而不是背四条定义:MySQL 的四种隔离级别是读未提交(RU)、读已提交(RC)、可重复读(RR,InnoDB 默认)、串行化(Serializable),分别对应脏读、不可重复读、幻读三类异常。实现靠两套东西:MVCC 与锁。MVCC 通过隐藏列(trx_id、roll_pointer)、undo log 版本链和 ReadView 实现一致性读——RC 下每次快照读都生成新的 ReadView,所以能看到别人已提交的新数据;RR 下只在事务第一次快照读时生成一次,所以整个事务看到的是同一个视图。当前读(select ... for update、update、delete)则要加锁:RR 用 next-key lock(记录锁 + 间隙锁)锁住范围,抑制幻读;RC 只加记录锁,不加间隙锁,所以需要 binlog 的 row 格式来保证主从一致。被追问「RC 上的是什么锁」就答记录锁(行锁),没有间隙锁。B+ 树那题的关键是「不只是结构特性」:B+ 树的高度低(三到四层就能索引千万级数据)、非叶节点只存键所以扇出大、叶子节点用链表相连所以范围查询与排序只需顺序扫描,且所有数据都在叶子同层、查询路径长度稳定。红黑树是二叉结构,高度是对数但常数大,磁盘每访问一层就是一次随机 IO,千万级数据要二十多层,完全不适用;它更适合内存里的有序结构(如 Java 的 TreeMap)。再补一句工程因素:InnoDB 的页大小(16KB)与预读、聚簇索引把主键与行数据放在一起(所以二级索引要回表),这些都是「选 B+ 树」的一部分原因。

AI Coding 与手撕环节,考的是工程习惯而不是工具熟练度:「平时用 AI 做什么」推荐按「场景 + 流程 + 产出 + 边界」讲:用它做代码阅读与理解(陌生仓库先让它梳理调用链)、写单测与边界用例、生成重复性代码与脚手架、排查报错时给出假设再自己验证、写文档与提交信息。写了什么 skill 就具体说规则(比如「生成单测」的 skill 规定了必须覆盖空输入、边界值、异常路径,并强制跑通才算完成)。TDD 的流程要说得清:先写一个会失败的测试明确接口与预期(red),再写最小实现让它通过(green),最后重构去重(refactor);关键是测试先行逼你把需求拆成可验证的小步,并且每次改动都有回归保护,AI 时代它的价值更高,因为生成代码很快、验证反而成为瓶颈。手撕题是力扣 115「不同的子序列」的变体:设 dp[i][j] 表示 s 的前 i 个字符中能构成 t 的前 j 个字符的方案数,边界是 dp[i][0] = 1(构成空串只有一种方案),转移为 dp[i][j] = dp[i-1][j] + (s[i-1] == t[j-1] ? dp[i-1][j-1] : 0),答案在 dp[n][m],时间 O(n·m)、空间可用两行滚动压到 O(m),注意方案数可能溢出(题目要求时取模)。这场的教训很直接:不要用「印象里做过的题」代替读题——求方案数与求操作数是两种不同的 DP 设计,现场先重述一遍题意再动笔。