字节跳动 AI全栈开发 一面
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 请做一下自我介绍。
实习项目
- 讲一下项目有哪些模块,分别负责什么,怎么交互的?
- 你负责哪个模块?
- 这个数据转发工作经历了哪些模块?
- 你说的前台和后台分别是承担什么工作?前台有哪些主要的页面和业务?
- 设计模式是什么?
- 技术选型怎么做的?
- DDS 是什么?为什么用 DDS?
- 怎么保证数据的可靠性?
- 怎么取舍 DDS 和 HTTP 的数据通信时延?
- 现在系统的时延状态是怎样的?
- 这个 DDS 是怎么设计的?
- 无人机集群规模是怎样的?
- 如果两个飞机的数据被篡改会发生什么?
- 如果飞手抢夺控制软件会怎么处理当前任务?
- 无人机哪些数据要同步更新?举个例子,频率大概是怎样的?
- 在这个频率下有没有遇到前端卡顿的问题?怎么解决的?具体是怎么实现的?
八股·前端
- 说说 URL 到页面显示经历的过程?
- 看一下这段代码(一段 JS 事件循环的代码),说说它的输出是什么?为什么是这样?
- Promise 里面持续 resolve 循环生成微任务会发生什么?
八股·后端
- 数据库用得挺多的吧?说说 MySQL 的四种事务隔离级别以及它们是如何实现的?
- RC(读已提交)上的是什么锁?
- MySQL 索引用的数据结构是什么?为什么用 B+ 树不用红黑树?只是结构特性决定的吗?
AI Coding
- 平时主要用 AI 做什么?怎么做的?写了什么 skill?
- TDD 驱动是怎么进行的?
手撕
- 手撕:求字符串 s 到其子序列 t 的实现(删除操作)种类数量,提示用动态规划。
- 你有什么想问我的?
《参考解析》
项目深挖的应对方式是「一张数据流图 + 每层都说清取舍」:面试官从模块划分一路问到集群规模、篡改、抢控制权,考察的是你对数据链路和上下游业务的理解,而不是某段代码。准备时画一张图:数据在哪些组件间流动、每个组件的职责、同步还是异步、频率量级、失败怎么处理。前台通常指面向操作人员的界面(实时状态展示、任务下发、告警、历史回放),后台负责接入、聚合、存储与转发;前后台之间常常是控制面走 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 设计,现场先重述一遍题意再动笔。