乐于分享
好东西不私藏

AI 之后,我越来越不敢只问前端面试的标准答案了

AI 之后,我越来越不敢只问前端面试的标准答案了

最近一段时间作为面试官面前端,我有个感受越来越强:
很多问题,已经不能再按以前的方式问了。

不是说候选人都不行,也不是说 AI 把面试彻底毁了。
更准确一点说,是以前那套靠标准答案筛人的方法,现在越来越不管用了。

前段时间面了一个三年经验的,简历上写着熟悉 React。

我问他:

useEffect 的清理函数什么时候执行?

对面答得很顺:

组件卸载时会执行,下一次 effect 执行前也会执行,通常用来清理副作用,避免内存泄漏。

这个答案没问题,甚至挺标准,所以我再接着问:

如果在 useEffect 里发了一个请求,组件很快卸载了,这个请求会怎么样?

他回答:

请求会被取消。

我继续追问

fetch 会自动取消吗?

他停了一下,说:

哦对,我的意思是用 AbortController 的话可以取消。

但我其实没问 AbortController。
我问的是那个请求本身会怎样。

如果你真写过这种场景,第一反应通常不是“请求会取消”,而是:

请求还在跑,只是响应回来以后,这个组件可能已经没了。
如果你还 setState,就可能有问题。
如果要取消,需要自己处理,比如 AbortController,或者用请求序号避免旧结果覆盖新结果。

这不是什么特别高级的知识点。
但区别就在这里。

一个人背过答案,和一个人真的在项目里被这个坑烦过,说出来的东西是不一样的。


很多回答不是错,是太干净了

我现在面试时最怕听到的,不是答错。
答错反而好处理,知道哪里不行就完了。

比较麻烦的是那种特别完整、特别顺、特别“正确”的答案。

比如问性能优化。

有些候选人会从代码分割讲到懒加载,从 CDN 讲到缓存,从防抖节流讲到虚拟列表,再讲到 Tree Shaking、SSR、Web Worker。

你不能说他说错。
基本都对。

但听多了以后,会觉得这个答案很像一份整理好的笔记。
里面没有画面感,没有踩过的坑,也没有"我当时为啥这么干"。

真正做过的人,有时候反而讲得没那么完整。

他可能会说:

我们之前有个后台页面,列表一次返回很多数据,客户那边机器又比较老,滚动特别卡。一开始我们以为是接口慢,后来用 Performance 看了一下,主要时间耗在渲染上。最后没搞太复杂,先分页,再把几个计算字段缓存掉,效果就已经明显了。

这种回答不一定高级,但我会觉得可信。
因为它不像是在背“前端性能优化有哪些方法”,而是在讲一个具体问题怎么被定位、怎么被解决。

而且真实项目里很少有人上来就把所有优化手段都铺开。
大多数时候都是先看痛点的地方在哪里,然后用一个够用的办法把它压下去。


我现在会更在意追问

以前我也问八股。

闭包是什么?
事件循环怎么走?
React diff 大概怎么做?
Vue2 和 Vue3 的响应式有什么区别?

这些问题不是完全没价值。
如果一个人完全答不上来,当然也说明问题。

但现在的问题是,这些题太适合被准备,也太适合被 AI 回答了。

远程面试的时候,对面到底有没有开着 AI,我其实不知道。
就算是现场,也很难百分百防住。
现在手机录音、语音转文字、AI 总结,都太方便了。

所以我后来不太纠结“他是不是用了 AI”。
我更关心另一件事:

这个答案往下追,还能不能站得住。

比如候选人说:

我们做过首屏优化。

我不会停在这里。
我会继续问:

优化前首屏大概多慢?
你们怎么量的?
是 Lighthouse,还是自己打点?
最后主要问题在 JS 体积、接口、渲染,还是资源加载?
你说做了代码分割,具体拆了哪些?
拆完以后有没有请求数变多的问题?

这些问题单独看都不难。
但连在一起,就会变成一个真实经历的链条。

如果确实是亲手做的,他可能有些数字记不清,但大体能讲出过程。
如果只是背过"首屏优化方案",很快就会开始说套话:

一般来说,首屏优化可以从资源加载、缓存策略、代码拆分几个方面入手……

一听到"一般来说",我就觉得悬了。
不是说这句话一定有问题,而是很多空话都是从这里开始的。


真经历里通常有麻烦

我现在越来越喜欢问一些“不漂亮”的问题。

比如:

你做过最失败的一次组件封装是什么?

这个问题比“你怎么理解组件封装”有意思得多。

因为“组件封装”这个词太好回答了。
职责单一、可复用、可维护、避免过度设计。
这些话谁都会说。

但如果问失败经历,情况就不一样了。

真做过的人可能会说:

我之前封过一个表格组件,一开始想做得通用一点,列配置、搜索项、按钮、权限、分页、批量操作都塞进去。刚开始挺爽,几个页面很快就接上了。后来业务差异越来越多,props 越加越多,最后谁都不敢改。现在回头看,当时不应该把业务逻辑也塞进去,最多抽视觉结构和一些稳定交互。

这比“组件要保持职责单一”有信息量多了。

因为它讲到了后果。
技术判断很多时候不在“知不知道最佳实践”,而在“知道这个最佳实践什么时候会有问题,会引起复杂性问题”。

类似的问题还有:

你印象最深的一次线上事故是什么?
你有没有做过一个后来自己都不想维护的设计?
哪个技术选型你现在回头看觉得选错了?
哪次优化最后证明没什么效果?

这些问题没那么体面。
但工作本来就不是一直体面的。

如果一个人所有项目都顺风顺水,所有方案都合理,所有优化都有明显收益,所有事故都跟他无关,那我反而不知道该怎么判断。


代码 review 比背概念好用

我现在会准备一些小代码,让候选人看。

比如这种:



1
2
3
4
5
6
7
8
9
10
11

function UserList({ keyword }) {
  const [list, setList] = useState([]);

  useEffect(() => {
    fetch('/api/users?keyword=' + keyword)
      .then(res => res.json())
      .then(data => setList(data));
  }, []);

  return list.map(item =><div key={item.id}>{item.name}</div>);
}


这段代码不复杂,但可以聊很多东西。

最基础的,依赖数组少了 keyword
再往下,keyword 要不要 encodeURIComponent
请求有没有竞态问题。
组件卸载以后怎么办。
有没有 loading 和 error。
空状态怎么展示。
接口慢的时候用户看到什么。
连续输入的时候旧请求会不会覆盖新结果。
key 靠不靠谱。
如果数据量大怎么办。

这些点 AI 当然也能列出来。
所以我不会只看他能列出多少问题。

我会看他怎么展开。

有人会像念 checklist 一样,把所有可能问题都说一遍。
也有人会先抓最关键的:

这个组件最大的问题是 keyword 变了不会重新请求。修完以后第二个问题是竞态,比如用户先搜 a 再搜 ab,a 的请求后回来,可能把 ab 的结果覆盖掉。这个场景在搜索框里挺常见,所以我会先处理这两个。

后者更像真实写代码的人。
因为他知道问题有优先级。

工程里很少是“把所有最佳实践都加上”。
更多时候是先判断哪个问题现在最可能发生,哪个问题发生了后果最严重。


我不太相信“最佳实践”这四个字了

不是说最佳实践没用。
而是面试里只讲最佳实践,信息量太低。

比如问状态管理。

以前我可能会问:

Redux 和 Zustand 有什么区别?

现在我更愿意问:

一个中后台系统,页面很多,筛选条件很多,权限也比较复杂。你会把哪些状态放 URL,哪些放全局 store,哪些留在组件里?

这个问题没有标准答案。
但能听出一个人干活的路子。

我比较期待的回答大概是:

筛选条件、分页、tab 这种需要分享、刷新、前进后退保留的状态,可以考虑放 URL。
用户信息、权限、全局配置,适合放全局 store。
弹窗开关、局部 hover、局部表单过程状态,没必要全局化。
服务端数据也不一定要塞进 store,可以交给 React Query 这类工具。
表单状态如果全局化,要小心同步问题,尤其是复杂表单。

他不一定要跟我选一样的方案。
但他得讲得出为什么。

我现在更想听到的是:

我这么选,是因为这个状态需要被谁消费,需要不会随刷新丢失,要不要支持分享,未来改起来会不会麻烦。

而不是:

Zustand 更轻量,Redux 生态更成熟。

这些对,但太像简介。


AI 不是唯一的问题

说实话,把锅全甩给 AI 也不公平。

以前没有 AI 的时候,也有人靠背题过面试。
背闭包、背原型链、背 React 生命周期、背 webpack 优化。

那时候的问题其实已经存在了:
很多面试考的是“你有没有准备过面试”,不是“你能不能把活干好”。

AI 只是把这件事放大了。

以前背题还需要自己整理,现在让 AI 生成一份“前端面试高频题答案”,几分钟就够了。
以前候选人临场编不出来,现在 AI 可以帮他把话说得很顺。

但从另一个角度看,这也逼面试官改问题。

如果一个问题 AI 五秒钟能答得比候选人还完整,那这个问题可能本来就不该作为核心判断依据。

比如:

Vue2 和 Vue3 有什么区别?

如果只听到 Proxy、Composition API、Fragment、Tree-shaking,这就很难判断水平。

我更愿意换成:

如果你手上有一个 Vue2 老项目,现在要迁 Vue3,你会先看哪些风险?
哪些代码最容易出问题?
你会一次迁完,还是渐进迁?为什么?

这个问题就没那么容易背。
因为它涉及项目规模、依赖、团队节奏、上线风险、兼容策略。

同样,“说说微前端”也很容易变成背概念。
不如问:

你们当时为什么需要微前端?
如果只是几个团队协作,有没有更轻的方案?
微前端引入之后,最烦的问题是什么?

真做过的人大概率不会只讲好处。
他会讲样式隔离、运行时隔离、路由、权限、部署、子应用通信,甚至会讲组织结构的问题。

有些人还会说:

后来发现我们的问题不一定要靠微前端解决,主要还是团队边界和发布流程没理清。

这种回答我反而更信。


远程面试防不住,也没必要装作防得住

远程面试能不能防 AI?
我觉得很难。

你可以要求共享屏幕,可以要求开摄像头,可以限制切屏。
但这些都只能提高成本,不能真正解决问题。

而且我也不太喜欢把面试搞得像监考。
大家都累。

所以我的做法比较简单:
不试图证明他有没有用 AI,而是让答案必须和他的经历绑定。

比如他简历写:

负责前端工程化建设。

那我不会问:

前端工程化包括哪些内容?

这个问题太容易答了。

我会问:

你们当时为什么要做这件事?
是构建慢,还是规范乱,还是发布容易出问题?
ESLint 规则是谁定的?
有没有规则推不下去?
有没有哪个包升级以后出过问题?
构建速度优化前后大概多少?
如果团队有人不愿意改,你们怎么处理?

这些不是为了为难人。
而是"自己干的"和"听别人说的",区别就在这些地方。

自己干过的人会讲麻烦。
听说过的人只会讲方向。


我现在更喜欢现场推演

有时候我会给一个很普通的需求:

做一个搜索框,用户输入关键词后请求接口。要求防抖,避免旧请求覆盖新结果,有 loading,有错误提示。

这题不难,但挺能看出习惯。

有人会直接写一个 debounce。
有人会想到竞态。
有人会想到 AbortController。
有人会说 loading 不能简单粗暴地设 true/false,因为并发请求时可能乱。
有人会区分主动取消和真实报错。
有人会问结果要不要缓存,搜索条件要不要进 URL,用户清空输入时要不要立即清空结果。

这些都没有唯一答案。
但聊天过程里能看出他有没有处理过类似交互。

我还会临时改需求:

如果现在产品说,返回结果要缓存一分钟呢?
如果用户点返回,希望搜索词还在呢?
如果接口偶尔很慢,loading 要不要延迟出现?
如果这个搜索框在多个页面都要用,你会抽成什么?

这比单独问"防抖和节流有啥区别"有用多了。

因为工作里的需求就是这样变的。
不是一道题答完就结束,而是你刚写完,旁边又来一个条件。


pair programming 其实最省事

如果条件允许,我觉得最有效的方式还是一起写点代码。

不用搞很难。
二三十分钟,修一个小 bug,或者实现一个小交互就够了。

让他打开编辑器、浏览器、DevTools。
看看他怎么读陌生代码,怎么定位问题,遇到报错怎么查,改完以后会不会验证。

很多东西在聊天里很难判断,但写代码时很明显。

比如:

他是不是一上来就大改。
会不会先复现问题。
会不会看控制台。
会不会加日志。
改完以后会不会考虑边界。
不知道的时候会不会承认不知道。
能不能把问题拆小。

这东西比背答案真实多了。

当然,这种方式对面试官要求也更高。
你得准备合适的题,不能拿一个脱离业务、毫无意义的玩具题糊弄人。
你还得愿意花时间看过程,而不是只看最后结果。

但如果真的想判断一个人能不能干活,这可能是最直接的办法。


我现在不太急着下判断

面多了以后,我反而没以前那么爱贴标签了。

候选人回答像 AI,不一定说明他作弊。
有些人就是准备得很充分,说话也比较模板化。
有些人紧张的时候,就开始背课文了。
还有些人嘴皮子利索,答案天然就很完整。

反过来,回答不流畅,也不一定说明不会。
有的人做得多,但不擅长总结。
有的人需要看到代码才能进入状态。

所以我现在更愿意多换几种方式看:

聊经历。
抠细节。
看代码。
做推演。
问取舍。
实在不行就一起写一小段。

如果这些环节都能对上,我就比较放心。
如果每个问题一开始都答得很好,但一追到项目细节就开始说套话,那我就会打个问号。


最后

AI 确实让面试变麻烦了。

但我现在觉得,它也只是把一个老问题暴露得更明显了:
我们以前太爱问那些有标准答案的问题了。

标准答案当然方便。
面试官省事,候选人也知道怎么准备。
但工作不是这么回事。

工作里更多的是:

这个需求到底要不要做?
这个 bug 先怀疑哪一层?
这个抽象现在该不该抽?
这个状态放哪里以后最不容易出事?
这个方案看起来很优雅,但团队维护得住吗?

这些问题没有标准答案。
也正因为没有标准答案,才更接近真实工作。

所以现在面试时,我不太期待听到一个完美回答。
我更想看到的是:当标准答案说完以后,这个人还能不能继续往下走。

能不能讲出自己踩过的坑。
能不能承认不确定。
能不能根据场景做取舍。
能不能在一段乱糟糟的代码里找到问题。
能不能把一个看似简单的需求,处理得稳一点。

至于他有没有用 AI,我当然在意。
但我更在意的是,离开 AI 给出的最佳实践,他还剩下多少自己的判断。