百度提前批前端一面
- 轮次
- 一面
- 结果
- 挂
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 自我介绍。
- 介绍项目:哪一个是你完全做的?收益有哪些?
- 讲讲事件循环(宏任务与微任务的执行顺序)。
- 给一段代码,说出输出结果。
- 手写 Promise.allSettled。
- 场景题:页面存在表单联动,用户输入之后页面卡顿,如何排查这个问题?
- 一些 React 相关问题。
- 实习中 AI 的使用情况。
- 反问。
《参考解析》
事件循环这道题要答到「谁先谁后、什么时候渲染」。 浏览器的事件循环可以记成:执行一个宏任务 → 清空所有微任务(清空过程中新产生的微任务继续在本轮清完)→ 需要时进入渲染阶段(样式计算、布局、绘制,其间会执行 requestAnimationFrame 回调)→ 取下一个宏任务。宏任务包括 script 整体、setTimeout/setInterval、MessageChannel、用户交互与网络回调;微任务包括 Promise.then/catch/finally、queueMicrotask、MutationObserver。所以 setTimeout(fn, 0) 一定排在 Promise.resolve().then(fn) 后面;async/await 中 await 之前是同步执行,await 之后的代码等价于 then 里的回调,进微任务队列。面试里被追的通常是三个点:微任务如果无限产生新微任务会饿死渲染(长任务与掉帧的根因之一);渲染不是每个宏任务之后都发生,浏览器会按刷新率合并;requestAnimationFrame 在渲染前执行,适合做动画,setTimeout 做不到帧同步。能顺手对比 Node 会更完整:Node 按 timers、pending callbacks、poll、check、close 等阶段轮转,process.nextTick 的优先级高于 Promise 微任务。
「看代码说输出」的通用解法。 这类题考的不是记忆力而是执行模型,答题方法可以固定成三步:先把代码里的同步部分按调用栈顺序推进,把回调按类型分别丢进「微任务」和「宏任务」两个队列;然后按事件循环规则取任务,注意每个宏任务执行完要清空微任务;最后处理变量的绑定方式(var 是函数作用域会共享同一个变量,let 是块作用域每次迭代新建绑定)与 this 的指向(普通调用指向 undefined 或全局、方法调用指向调用者、箭头函数取词法作用域、bind 之后不可变)。常见考点集中在闭包与循环里的 setTimeout、原型链与 this、隐式类型转换([] + {}、== 的转换规则)、深浅拷贝对引用类型的影响、以及异步顺序混合考察。写答案时要边说边标记队列,面试官看的是过程。
手写 Promise.allSettled 的要点。 语义是「等所有 Promise 都敲定(无论成功失败)后返回结果数组」,每项形如 {status: 'fulfilled', value} 或 {status: 'rejected', reason},并且数组顺序必须严格对应输入顺序(不是完成顺序)。实现要点五条:返回一个新的 Promise;用一个计数器统计已敲定数量,等于输入长度时 resolve,输入为空数组要立即 resolve(顺序不能错,先判空否则永远不 resolve);每项用 Promise.resolve(item).then(...) 包一层以兼容非 Promise 值;在 then 的两个分支里分别写入结果对象,绝不能 reject;写入时用索引而不是 push,保证顺序与输入一致。它和 Promise.all 的区别要能一句话说清:all 是「一个失败就整体失败」的短路语义,allSettled 是「全部有结果才返回」,前者适合「任一失败就没意义」的场景,后者适合「批量上报、批量请求,失败项单独处理」的场景;另外还有 Promise.any(第一个成功即成功)与 Promise.race(第一个敲定即敲定),四个 API 的语义要能区分开。
表单联动导致输入卡顿怎么排查(这场面试丢分的那道题)。 排查顺序应该是「先量化、再定位、后优化」。量化用 Chrome DevTools 的 Performance 面板录制一次输入操作,看主线程火焰图:如果出现大段黄色长任务、输入事件到下一帧的间隔超过 50 毫秒、或者每敲一个键就触发一次完整的布局与绘制,问题就确认了。定位的三个常见根因:一是受控组件的状态放在了整个表单的最上层,一个字段变化导致整棵表单树重渲染(用 React DevTools Profiler 的 ranked 视图可以直接看到哪个组件重渲染、渲染耗时多少、以及是不是 props 引用每次都变导致 memo 失效);二是联动逻辑在 render 期间做重计算或同步读取布局属性(offsetHeight 之类的强制同步布局会触发 layout thrashing);三是有长列表或大量输入项同时渲染。优化手段对应着来:把状态下沉到各自字段组件、联动逻辑用 useMemo/useCallback 与不可变更新避免无谓重渲染、对大列表做虚拟化、把非紧急更新放进 startTransition 或用 useDeferredValue 降优先级、高频输入做防抖、非受控组件加 ref 读取、以及把重活移出主线程(Web Worker)。回答时把「录制火焰图 → 找到长任务与重渲染组件 → 用最小改动验证」这条链路讲出来,比直接背优化清单更得分。
项目自我介绍与「AI 使用情况」怎么答。 面试官问「哪一个是你完全做的、收益有哪些」,本质是筛掉把团队成果说成个人成果的人,答案要给出你的职责边界与可验证的收益(接口数量、性能数字、上线后的观测变化),说不清收益的项目会被判定为「参与过」。问实习中 AI 的使用情况,正确的答法是讲用法与验证:用在哪一环(生成脚手架、写单测、读陌生代码)、怎么保证正确(测试覆盖、review diff、边界用例),而不要只说「提效很多」。这场面试整体不流畅、节奏拖沓,次日收到挂——复盘时值得把「事件循环、手写 Promise、性能排查」这三块补成能现场推演的程度,它们几乎每一场前端一面都会出现。