面试问题
📍面试公司:字节跳动
🕐面试时间:近期
💻面试岗位:前端一面
⏱️面试时长:未提及
📝面试体验:难度 Plus Ultra 版,苦战,加粗的是没答上来的
❓面试问题:
- Reconciler 如何遍历 fiber 树(先序遍历)
- 为什么要这么设计
- DOM 树和 fiber 树的区别
- diff 算法是怎么比较新旧两个树的
- 浏览器从拿到渲染树以后都经过了哪些阶段(布局→分层→分块→光栅化→直接显示(其实是合成))
- 为什么光栅化要由 GPU 去做
- 为什么会这样呢
- Webpack 和 Vite 有什么区别
- Vite 打包用的什么
- ESM 和 CJS 区别(提到同步导入和异步导入)
- 微任务队列和宏任务队列都是什么
- 任务循环在浏览器和 Node 有什么区别
- Message channel 是什么
- 为什么 React 用了 Message channel 调度没用 setTimeout
- 听说过 React 时间分片吗
- 说一下 JavaScript 是不是单线程的语言
- 用过哪些设计模式
- 手撕:同时允许 2 个任务执行的异步调度器
- 手撕:两个有序数组合并成一个有序数组
字节跳动前端一面深度解析
面试整体画像
| 维度 | 特征 |
|---|---|
| 面试风格 | 源码级深挖型 + 底层原理型 + 追根究底型 |
| 难度评级 | ⭐⭐⭐⭐(四星半,React 原理 + 浏览器底层 + 工程化深度) |
| 考察重心 | React fiber 架构、浏览器渲染流水线、构建工具原理、事件循环机制、设计模式 |
| 特殊之处 | 问题层层递进,连续追问'为什么这样设计',考察真正的理解深度而非背诵 |
逐题深度解析
一、Reconciler 如何遍历 fiber 树(先序遍历)
回答思路:这是 React fiber 架构的核心。Reconciler(协调器)负责找出组件树的变化,它采用深度优先遍历(DFS),具体是先序遍历(pre-order)。
遍历过程:
- 从根 fiber 开始,先处理当前节点
- 如果有 child,进入 child
- child 处理完后,如果有 sibling,进入 sibling
- 重复直到完成所有节点
// 伪代码示意
function workLoop(unitOfWork) {
while (unitOfWork !== null) {
// 处理当前节点(beginWork)
unitOfWork = beginWork(unitOfWork);
// 如果有 child,继续向下
(unitOfWork !== && unitOfWork. !== ) {
unitOfWork = unitOfWork.;
} {
(unitOfWork !== ) {
(unitOfWork);
(unitOfWork. !== ) {
unitOfWork = unitOfWork.;
;
}
unitOfWork = unitOfWork.;
}
}
}
}

