知

模块五 · AI 协作与表达

第 18 / 18 节17 分钟阅读型

面试表达:把 React 讲成工程判断

面试不是背 API,而是展示判断。这一节给出"结论—机制—取舍—验证"的表达骨架、五个高频题的答法,以及项目案例与追问应对。

读完这一节,你能做到

  1. 用四步结构回答原理题,而不是背结论。
  2. 把 Hooks、渲染、Fiber、性能、状态五个高频题讲到点上。
  3. 用项目案例讲清一次技术决策与代价。
  4. 应对"为什么不用 Vue/如果重来"这类追问。

一、四步表达骨架

结论(一句话判断)
→ 机制(底层怎么实现)
→ 取舍(为什么这样设计,代价是什么)
→ 验证(怎么证明有效)

示例:问"为什么 Hooks 不能条件调用"。

  • 结论:因为 Hooks 靠调用顺序定位状态。
  • 机制:每个 Fiber 上有一条 Hooks 链表,第 n 次调用对应第 n 个节点。
  • 取舍:规则限制写法,换来更简单的状态复用与更小的运行时开销。
  • 验证:条件调用会让后续 Hook 错位,报 "Rendered fewer hooks than expected"。

二、五个高频题

1. setState 是同步还是异步

"调用是同步的,渲染是异步批量的。setState 只是把更新入队并调度,当前闭包里读到的仍是旧值;需要基于旧值更新时用函数式写法。"

2. useEffect 与 useLayoutEffect

"都是同步外部系统。useLayoutEffect 在 DOM 更新后、绘制前同步执行,适合读取布局;useEffect 在绘制后执行,适合请求与订阅。用错会导致闪烁或阻塞。"

3. 为什么 React 需要 key

"key 是节点身份。没有 key 时按位置复用,插入/删除会导致状态错位;用稳定 id 才能让 React 正确复用或重建。"

4. Fiber 解决了什么

"把递归渲染拆成可中断的工作单元,配合双缓冲与 Lane 优先级,让高优先级更新先执行,输入不卡。"

5. 怎么做性能优化

"先测量,再按'减少渲染范围 → 减少单次工作量 → 减少 DOM 数量'的顺序优化。常用手段是状态下放、children 组合、memo、虚拟列表;每项都要有前后对比。"

三、项目案例模板

背景:业务、规模、你的角色
问题:具体指标(首屏 4s、列表 2,000 行卡顿)
动作:为什么选这个方案,排除了哪些
结果:指标变化 + 代价
反思:如果重做会怎么改

不要只说"用了虚拟列表",要说"2,000 行列表滚动 18fps,虚拟滚动后 55fps,代价是不定高需要测量"。

四、追问应对

追问回答骨架
为什么不用 Vue?团队栈、生态、开发效率,讲取舍不拉踩
memo 为什么没生效?props 是否每次新建、比较是否浅、children 是否稳定
如果数据量再大 10 倍?分页/虚拟滚动/服务端聚合,先算瓶颈
这个优化真的有效吗?基线、单变量、前后对比
看过源码吗?讲一个具体模块(如 Fiber 的 beginWork),不要泛泛而谈

五、常见坑

  1. 只背结论,讲不出机制。
  2. 把"setState 是异步的"说成"React 有个定时器"。
  3. 案例只有动作,没有指标与代价。
  4. 遇到不会的硬编,不如说"这块我没深挖,我的理解是……"。
  5. 贬低其他框架来抬高自己。

六、动手任务:自写 → AI 写 → 对比 → 取舍

这一步的"AI 写"是写答案,不是写代码:让 AI 用同一套骨架答一遍,你负责挑出它哪里在背结论。

① 自己写

选一个你做过的页面,用四步结构讲清一次性能优化,要求:

  • 至少两个指标的前后对比。
  • 至少一个"代价"或"没做好的地方"。
  • 结尾给出"如果重做会怎么改"。

② 让 AI 写同一题

把同一道题交给 AI:用一个真实项目回答"你怎么做 React 性能优化",要求结论、机制、取舍、验证四段,并给出具体数字。

③ 对比

维度我的版本AI 版本差异说明
有没有具体指标
机制讲到哪一层
有没有代价与失败
追问一层会不会断

④ 说取舍

  1. AI 的答案里,哪句是正确的空话,一追问就塌?
  2. 它缺的那部分,是不是恰好是你的项目经验值钱的地方?
  3. 如果只能保留三段,你留哪三段?

七、自测

  1. 四步表达骨架是什么?
  2. setState 的"异步"具体指什么?
  3. key 的作用是什么?
  4. Fiber 的两个关键能力是什么?
  5. 性能优化的三步顺序是什么?

参考答案要点:结论/机制/取舍/验证;渲染批量调度;节点身份;可中断与优先级;缩小范围→减少工作量→减少 DOM。

附:五个追问的完整答法

问:setState 一定是异步的吗? 答:调用是同步的,渲染是批量的。React 18 起,事件、Promise、定时器里的更新都会批处理;需要同步读 DOM 时用 flushSync,但会牺牲批处理。

问:useMemo 能替代 useCallback 吗? 答:不能。useMemo 缓存值,useCallback 缓存函数;缓存函数也可以用 useMemo 返回函数,但语义不如 useCallback 清晰。

问:为什么 props 变了子组件不一定重渲染? 答:如果子组件被 memo 包裹且 props 浅比较相等,就会跳过。反过来,props 没变也可能重渲染——父组件渲染时,未 memo 的子组件都会跟着渲染。

问:Fiber 一定比栈调和快吗? 答:不一定。Fiber 的收益是可中断与优先级,不是单次渲染速度;它反而带来额外的链表操作开销。

问:你项目里最难的问题是什么? 答:讲现象、排查、假设、验证、结果、代价。不要讲“用了什么框架”。

附:如何讲源码而不翻车

  • 只讲你读过的模块,比如 beginWork、completeWork、dispatchSetState。
  • 先讲设计意图,再讲实现,最后讲边界。
  • 不确定就说“这块我没读到”,比编造更加分。

附:面试准备清单

  • 三个案例:性能、架构、失败
  • 每个案例都能说出指标与代价
  • 能手写一个 20 行的 useState
  • 能解释一次 setState 到 DOM 的完整链路
  • 准备两个反问问题

附:面试节奏

原理题控制在 2-3 分钟:先结论,再机制,再一句取舍。项目题 3-5 分钟:背景一句、问题一句、动作三句、结果一句、反思一句。被打断就顺着追问走,不要念稿。

如果对方连续追问细节,说明他在验证你是否真做过;这时给具体数字与代价,比背概念有效。

附:三个不要

不要背术语、不要把所有成绩归因于自己、不要讲没有数据的“大幅提升”。讲清判断与代价,比数字更重要。准备好两个失败案例,比十个成功案例更能证明水平。

附:反问的两个问题

  1. 团队目前最大的技术痛点是什么?
  2. 这个岗位前三个月最重要的目标是什么?

不要问“加不加班”“用什么框架”这类可以提前查到的信息。先把结论说清楚,机制讲一层就够。一句结论胜过长篇背景。

配套题目

★ 越多越该先背;点题目可看完整答案与深入版。

提示:读完可以顺手做几道对应题目,检验是否真的理解