2026/10/10 10:51:34

半吊子前端工程师的面试避坑指南:从原理到实践

半吊子前端工程师的面试避坑指南:从原理到实践 1. 这场面试让我崩溃的点在哪实话说我做了七八年前端也面过几百号人自认为心理素质还算可以。但今天这位候选人真的让我在面完后面试官复盘时忍不住揉太阳穴。不是因为他态度差也不是因为答不上来而是那种“什么都学了一点、什么都敢写简历、但细问下去全是糊的”状态让我一时不知道从哪里开始吐槽。候选人自称有三年经验技术栈写的是“熟悉 Vue、React掌握 TypeScript了解 Node.js会 Webpack 配置写过移动端、PC 端、小程序做过性能优化”。简历一眼看去几乎把前端能碰的方向都列了一遍。我心想这挺好的就问了个最简单的开场题“说说你最近一个项目里从输入 URL 到页面渲染中间经历了什么”对方沉默了三秒然后说“浏览器发请求给服务器服务器返回 HTML然后浏览器解析。”我点头鼓励他继续。他说“然后……就渲染出来了。”我追问“HTML 里面有 JS 和 CSS浏览器怎么处理它们的DOM 树和 CSSOM 怎么构建有没有阻塞一说”他想了半天最后挤出一句“应该是一边下载一边解析的吧反正最终页面能出来。”这一瞬间我就知道后面可能要花不少时间在“拆解水分”上。但本着负责任的态度我还是把流程走完了结果后面更精彩问他 Flex 布局和 Grid 布局的适用场景他说“Flex 是一维的Grid 是二维的平时我用 Flex 多一些”再问“那你 Grid 实际用过吗”他说“写过 demo但项目里没真用上”。问他闭包是什么他背了段定义让他写一个简单的防抖函数他憋了五分钟写出来的代码里定时器还没清理。最让我无语的是最后反问环节。他问我“你们这边技术栈是 Vue 还是 React我两个都熟都可以。”“都熟”这个词在我这里基本就是“都只懂皮毛”的委婉说法。果然我接着问他对 Vue 3 的响应式原理理解到什么程度他说“用的 Proxy比 Vue 2 的 defineProperty 性能好”。我问“好在哪里”他卡住了。面完那一刻我的情绪其实不是生气更多的是一种无力感。三年时间如果踏实学真的能把前端基础打得很牢。但“什么都想会、什么都只学了一半”的学习方式恰恰是很多人三年后依然在原地打转的核心原因。这篇文章我就想把这个事情拆开讲讲。一来给面试官和团队 leader 做个参考半吊子候选人有哪些典型特征、怎么问能快速筛出来二来也想跟正在学前端的读者掏心窝子说几句哪些坑是你现在正在踩、但可能还没意识到的。2. 半吊子前端人的典型画像与危险信号“半吊子”这个词听起来有点损但它其实描述的不是智商问题而是学习路径和思维模式的问题。很多半吊子候选人并不是不努力相反他们往往很焦虑什么都想补只是没有形成体系。下面我结合今天的面试把这类人的典型特征拆成四个维度来讲。2.1 简历很丰满追问很骨感今天的候选人简历里有这么几条负责公司主站前端架构升级引入 TypeScript重构了核心模块开发过基于 WebSocket 的实时数据看板做过前端性能优化首屏时间从 3 秒降到 1.2 秒封装过团队公共组件库组件数量 30熟练使用 Docker负责前端项目容器化部署每一条拎出来都值得细问。我挑了两个问。第一个“你说首屏从 3 秒降到 1.2 秒具体做了哪些优化”他说“加了懒加载还把一些大图片换成 WebP 格式了。”“还有呢”“还有……用了 CDN。”“那你有没有做过数据上的分析比如现在首屏请求数是多少、哪个资源耗时最长”他说没细看反正最后测出来变快了。这就是典型的“结果导向式简历写法”——只写结论不给过程和数据。真正做过性能优化的人哪怕只做过一次也一定聊得出细节改前是什么样、改后是什么样、用了什么工具做分析、Lighthouse 分数多少、最大的性能瓶颈在哪个资源。讲不出这些的人大概率只是在文档里看到过“性能优化”这个词。第二个问题问组件库“你的 30 个组件里哪个最难封装”他想了想说“表格组件吧要处理列宽、排序、筛选”。“那你是怎么设计的比如列配置是声明式还是通过 API 传入”他有点犹豫说“我们用的时候都是别人封好的我自己封装的部分是一些简单的按钮、弹窗之类的。”你看又是典型的“简历与现实不符”。不是说人不能成长而是你既然敢把组件库重构写进简历至少要知道表格类组件封装里有哪些经典问题虚拟滚动、列固定、单元格渲染自定义、嵌套表头。一点没想过就说明这条经历根本不是你的核心产出。2.2 框架就像背课文只记住了“结论”现在前端面试基本绕不开框架题。问 Vue 的 reactivity、问 React 的 fiber、问 diff 算法其实不是要求每个候选人都能背源码而是想通过这些问题判断你有没有深入理解过“框架是怎么工作的”。今天的候选人问他 Vue 3 和 Vue 2 的区别他能说出“Composition API、Proxy、更快”这几个词但你继续问Proxy 相比 defineProperty 具体解决了哪些问题数组和对象属性的新增是怎么被代理到的Composition API 的 setup 执行时机是什么和 beforeCreate 谁先谁后为什么 Vue 3 的 diff 比 Vue 2 快静态标记是怎么回事他就卡住了。这说明他看过的不是源码分析而是“面试题总结”之类的八股集合。背结论在真正懂行的人面前反而比直接说“不太清楚”还要减分因为你明显在表演。同样的逻辑也适用于 React。我常问的一道题是“setState 是同步还是异步”。很多人张口就答“异步的”。但你问他“为什么在 React 18 里Promise 回调中的 setState 还能拿到最新的值React 是怎么实现批处理的”他基本就懵了。这道题没有标准答案但考察的完全是“有没有实际追踪过内部调度过程”的感觉。在这里我想给候选人一个非常实用的提醒如果你真的没深入研究过框架源码面试时完全可以大方说“这一层我没有细看但我知道 .... 大概是怎么工作的”。至少这是诚实的面试官还能评估你能不能补上。硬背结论反而会让你的信任度直接崩盘后面就算你答对了其他题目对方也会多留一个心眼。2.3 项目经验“跑得通但说不清”缺少一层抽象半吊子的另一个典型表现是代码能跑项目能上线但你让他讲设计他只有“业务实现”这一个层面。我通常喜欢问这么一类问题“如果现在让你重新做这个项目你会在架构上做哪些调整”候选人听完往往一脸茫然反问我“能跑就行为什么还要重新做”这就是思维方式的分水岭。一个合格的前端不应该只停留在“把功能做出来”这个层面而应该对代码结构、组件拆分、状态管理、错误处理、可维护性有持续反思。业务代码写完是起点不是终点。举个我今天实际问的例子。他说自己做过一个后台管理系统里面有很多表单。我问他“你这些表单是怎么处理的每个表单都自己写一个 state还是有统一封装”他说“都是手写的用组件的 data 或 ref 存着。”我又问“你有没有遇到过一个页面里表单特别多、校验逻辑重复的情况当时怎么处理的”他说“复制粘贴。”从这个回答可以看出他的工作模式基本是“给到需求就实现从来不会停下来想一层”。真正常见的做法是当表单足够多、校验足够重复时你会自然产生封装一个 Schema 驱动表单的想法或者至少抽象一个 useForm 之类的逻辑。这种“被业务推着走、而不是主动抽象”的状态是很多前端工作两三年后依然只能写业务页面的根本原因。面试中遇到这种候选人倒也不用直接淘汰但如果他表达里全是功能罗列没有一句“我当时选择了某种设计是因为...”那基本说明他的成长节奏已经落后于他的工作年限了。2.4 对基础知识没有敬畏心总想着“会用就行”最后一类特征严格来说不是能力问题而是心态问题。今天的候选人有个细节让我印象很深。当我问到他一些基础概念比如“事件冒泡和事件捕获有什么区别”他说“这个平时开发用不到一般都用框架帮我们处理了所以没太关注”。我听到这话真的愣了一下。事件委托、冒泡、捕获这些东西可能在小团队里确实不经常直接操作但它们是理解整个前端运行机制的地基。框架可以帮你绑定事件但框架解决不了所有问题。而且真正日常开发中事件冒泡带来的 bug 并不罕见。比如弹窗点击外部关闭、表格里点按钮不小心触发行点击、页面里某个浮层莫名出现又消失——追根溯源全是事件传播的问题。“用不到所以不学”这个逻辑本身就把程序员这份职业看低了。很多知识的关键性不用你判断它就在那里。你只是还没遇到那个让你头疼的场景。一旦遇到了临时去查和早有体系地理解效率差距是十倍不止。我总结了一下半吊子的画像做一个对照表方便你自查或者面试时评估候选人维度半吊子表现靠谱工程师表现简历描述什么都写什么都是“熟悉/掌握”写得克制突出 1-2 个深度方向项目细节只能讲做了什么功能能讲为什么这么设计、有什么取舍框架理解背结论、背生命周期能谈原理、能对比不同方案的差异问题排查说的最多的是“百度”会定位、会复现、会二分排查学习习惯追新技术、追框架版本追底层、追运行机制、追规范你对照一下如果自己踩中了 ≥3 条那“半吊子”这个标签可能离你不远。3. 面试官视角前端面试应该怎么问怎么筛吐槽完候选人该说说我们自己了。其实一场面试里遇到半吊子候选人面试官也不是完全没责任。很多团队面试流程本身就太“随缘”了想问什么问什么想怎么评怎么评最后靠感觉拍板。如果你不想每次都被“已经写进简历的假经历”浪费时间面试问题的设计就得有章法。下面是我这些年试下来比较有效的一套做法。3.1 把面试拆成“三层问法”由浅入深看真实水平我把前端面试的提问分成三层第一层语言基础。HTML、CSS、JavaScript 本身的运行机制。这是硬门槛靠背题过不了。第二层工程实践。组件拆分、状态管理、模块化、构建工具、代码规范、错误监控。考察的是你真实干活时的组织能力。第三层方案设计。给你一个不完整的需求让你现场设计技术方案。考察的是你在信息不充分的时候怎么思考。今天的面世候选人第一层就漏得差不多了第二层勉强能用“经验不足”来解释第三层更是直接垮掉。如果你在面人的时候发现第一层就有大问题其实后面两层基本不用再花太多时间了。我在第一层往往会固定准备这些母题每个都能往外延伸解释一下事件循环微任务和宏任务的区别写一个深拷贝并说明你的方案有什么缺陷说说浏览器缓存机制强缓存和协商缓存怎么选择什么是闭包它的内存问题怎么解决原型链是什么Class 和构造函数的关系是什么异步编程有哪些方案Promise、async/await 本质区别是什么每个问题后面我都会埋伏追问。比如深拷贝我会接着问“你拷贝一个带循环引用的对象怎么办”“Date、RegExp 怎么处理”“函数需要深拷贝吗”。这些追问只要你真正写过就不存在答不上来的可能。如果一个人连这些问题都答不透那他说自己“三年经验”大概率是打折的。3.2 用“真实的项目追问”筛掉简历水分除了基础题项目经验是水分重灾区。我会针对简历里的每一条项目描述问出下面几个固定问题这个项目你承担的角色是什么是完全自己写还是基于别人的代码改项目里最复杂的一个问题是啥你是怎么发现、分析、解决的项目上线后出了问题你是怎么排查的这三个问题问完基本能判断一个人是不是项目的核心参与者。第一种完全自己写的能说出“我遇到一个性能问题排查发现是某个组件重复渲染导致我用 React.memo useMemo 解决同时把数据请求从组件内提到状态管理里”这个就是有实战经验的。第二种基于别人的代码改的他说不出“为什么这里要这样设计”的取舍但能说清楚“我改动的是哪个模块、新增了什么逻辑”这也是可以接受的。第三种纯“挂名”的哪怕只是负责少数页面也一问就露馅。因为这种候选人说不清代码之间的关系也说不出任何一次有深度的调试经历。我还特别推荐一个方法让他“写代码”。不需要现场写很多5 分钟的小题就够了。最简单的就是“手写一个防抖函数”“手写一个数组去重”“实现一个简单的 EventBus”。这些题不求效率多高但能看出三件事变量命名习惯、边界情况意识、代码组织思路。今天的候选人写防抖时我眼睁睁看他写完一个 setTimeout 就忘了 clearTimeout然后还自信地把代码交给我。那一刻我真的冒出一个念头他不是不会写是真的不知道这种细节才是防抖的灵魂。你说他做过的项目里没遇到过一个输入框不停触发搜索的情况吗大概率遇到过的只是当时可能从网上下载了一个别人封装好的根本没过脑子。3.3 判断候选人的“学习能力”比判断“存量知识”更重要面试的终极目标是预测“这个人未来能不能成长”。所以除了问他会什么我通常还会问一个开放性问题“如果你现在要在一个月内把一个完全没接触过的技术栈投入到生产环境使用你会怎么学”这个问题没有标准答案。但不同的回答能暴露不同的思维方式上来就说“看官方文档直接写”的人偏向实操但可能缺乏体系说“先了解框架设计哲学、再写 demo、再看社区踩坑、最后做个小项目验证”的人更加稳妥回答“我从来不学简历之外的东西遇到再说”的人说实话可以直接排除我面过的人里还有一种特别有意思就是“遇到不会的先复制再说”型。这种其实不算坏因为至少解决问题了但如果他复制完了不去研究“它为什么这么写”那下次遇到同样的问题还是会复制。久而久之就成了半吊子。我自己的判断标准是候选人回答问题时有没有出现“因为”“所以”“我对比过”“我发现”这类因果表达。如果他的回答里全是名词没有推理那真别指望他以后能解决复杂问题。4. 半吊子是怎么养成的以及怎么避免成为半吊子这一章本来是写给正在学前端或工作一到三年的读者看的。面试官看完前面已经知道怎么筛人了但你如果是个“被筛的人”可能更想知道的是我已经是半吊子了还有救吗先说结论有救而且只要方法对半年就能有明显变化。4.1 学习方式上的两个致命误区半吊子的学习路径通常有两大问题。第一只追技术名词不追底层原理。今天候选人的简历里写了“了解 Node.js”我问他 Node.js 的事件循环和浏览器事件循环有什么不同他答不上来。这就叫“只记名词”。名词很好背但名词不会体现在你的代码水平里。你要真的理解 Node.js至少得知道 libuv、事件循环的 phase、setImmediate 和 nextTick 的区别。这些内容一开始接触会有点绕但绕过去了你就很难再退回到半吊子状态。第二把“会用”当成“已精通”。最典型的例子就是“会用 webpack”和“能配置 webpack”之间的鸿沟。很多人项目脚手架都是别人搭好的他只需在已有配置里加几个规则就能说自己会 webpack。但真正的会用说的是你能从零搭起来一个项目能处理多环境配置、代码分割、缓存策略、插件开发遇到构建问题能定位到是 loader 顺序问题还是 plugin 冲突问题。我用一个类比来解释这件事会用遥控器的人不叫“会修空调”会打开手机银行的人不叫“懂金融”。工具的使用门槛和知识体系的深度从来是两回事。4.2 打破半吊子状态的四个实操建议建议一把一个方向彻底挖透再谈广度。现在前端生态确实卷Vue、React、小程序、RN、Taro、SSR、微前端、可视化每一样都有人喊“必学”。但我的建议是工作前三年只选一个核心方向把它挖到你能讲清楚“它为什么这么设计”的程度。比如你选 Vue就把响应式原理、虚拟 DOM、diff、nextTick、keep-alive、组件通信完整过一遍。不是背面试题是真的去写代码验证。等这个方向通了你学 React 的速度会快得惊人因为很多设计思路是相通的。建议二遇到报错不要立刻百度。我见过太多人遇到样式不生效、接口 500、组件报错第一反应就是复制报错信息去搜索引擎搜。不是说不能搜但你至少要先自己分析一轮报错发生在哪个模块这个变量是什么值函数调用栈最外层是谁自己写一个最小可复现的 demo 试试很多人没有意识到“调试能力”是区分初级和高级工程师的核心指标之一。高级工程师解决一个 bug 的路径通常是这样复现问题 - 定位引入点 - 缩小代码范围 - 构造最小 demo - 修复并写测试。这个流程看起来复杂但其实做多了会变成肌肉记忆。建议三主动复盘“设计决策”而不只是“功能实现”。每次做完一个功能停下来问自己三个问题如果这个需求改一种实现方式会有什么不同当前代码里有哪些地方让我感觉“这样写不舒服”为什么如果别人接手他能看懂我的代码吗这些问题看起来简单但坚持半年你的代码质量和表达能力都会上一个台阶。因为你会开始从“我能实现”走向“我有自己的技术判断”。建议四输出内容无论多小。这里的输出不是指写技术博客或者开源项目哪怕只是在团队内部做一个分享、把一个新的知识点写成笔记发到群里、跟同事讲清楚你是怎么排查一个 bug 的都算。关键在于“你讲得明白的东西才是你真懂的东西”。很多人看着文档觉得懂了一开口讲才发现逻辑全是断的。这就是半吊子到靠谱之间的“最后一公里”。4.3 如果面试被挂怎么正确复盘如果你看了上面这些发现自己目前正处在“危险画像”里也不用太焦虑。面试被刷不可怕可怕的是你复盘的方向搞错了。正确复盘方式不是“哎这道题我没背过”而是拿着面试官提到的知识点往回追一层他问我的时候为什么我不懂我是从哪一环开始跟不上的我需要补的是这个知识点的原理还是它的工程实践比如今天这位候选人面试结束后我最想建议他做的事不是去背几十道 Vue 面试题而是把“浏览器渲染原理”这一整个话题啃下来。啃完这个他会自然理解 DOM 树、CSSOM、JavaScript 执行、事件循环、回流与重绘、异步加载脚本等一串知识点。这一串啃完他在性能优化、兼容性处理、调试排障上的判断力都会显著提升。“学一题通一串”是打破半吊子状态最有效的方法。贪多嚼不烂不如把一个系统的核心链路彻底想明白。5. 面试官防崩溃实用清单最后这部分送给同为面试官、团队负责人或者将来可能需要面人的朋友。面试碰到半吊子候选人要说完全不生气是假的但我们可以通过优化流程尽量在短时间内做出准确的判断不浪费彼此时间也不用搭上自己的情绪。5.1 面试前用简历做“预判题”而不是“默读题”我见过不少面试官面试前半小时才开始看简历到场后一边翻一边想问题。这种效率很低。我的习惯是提前一天把简历里的每一条项目经验、每个技能点、每个关键数字都过一遍然后在旁边批注出至少两个“必问点”。比如对方写了“首屏优化 3 秒降到 1.2 秒”下面直接写怎么测的工具是什么优化前后的请求量和资源大小分别是什么最大的优化点是哪个线上效果如何持续监控到面试时这些批注就是你的“追问地图”。你会发现靠谱的人跟你聊这些细节时是兴奋的、流畅的而半吊子会含糊、转移话题或者直接说“没细看”。5.2 面试中把“我说你听”变成“你写我看”有些技术面更像是一场“背题考试”面试官念题候选人背答。这种情况下半吊子反而可能比靠谱的人表现更好因为八股文可以突击但实际动手能力却装不出来。所以我的建议是一次技术面试里至少留 15 分钟给现场编程题。题目不需要难甚至越基础越能暴露问题越好。举个例子我常让人写“实现一个 once 函数”也就是不管调用多少次只执行一次的函数。这道题两三行就能写完但它能折射出很多信息是能立刻想到闭包还是懵了写出来的代码有没有处理返回值有没有考虑并发调用时只执行一次的边界还有一道更基础的手写一个debounce要求实现首调用立即执行、尾调用延迟触发。这道题能筛掉很多简历里写着“熟练使用 lodash”的人因为很少人真正思考过 lodash 里的 debounce 为什么参数那么多。我强烈建议把这道题作为前端面试的“通用入场券”。你要是连防抖都思考过“为什么这样写”后面再聊什么框架原理我都愿意多给你一些时间要是一上来就写一个只在 setTimeout 里 console.log 的“伪防抖”那我可以很负责任地说这位候选人对“闭包 定时器 参数传递”的组合理解是不到位的。5.3 面试后用“三个记录”做决策而不是“一个感觉”面完以后我建议你立刻做三件事记录候选人答对的问题和答错的问题记录候选人自己主动提过哪些追问记录你对他的整体判断依据是什么第一个记录好理解第二个其实很有意思因为靠谱的候选人会在回答完之后主动追问“你问我这个问题是在考察什么我的解法里你比较关心哪一块”说明他在互动、在思考。半吊子通常是“你问我答、答完结束”全程没有任何求知欲。第三个记录是为了防止你的情绪影响决策。如果面试中遇到很无语的候选人气场很尴尬你可能会放大他的缺点或者因为简历本来不错就心软。写清楚判断依据至少能让决策更客观。提示如果面试现场不方便写笔记可以在手机备忘录里快速记几个关键词面试结束后半小时内补全。笔记一定要趁热写过了半天你的记忆会严重衰减那时候补的像是“合理化后的版本”而不是真实记录。5.4 顺带说说遇到“半吊子”候选人到底要不要发 offer这个问题没有标准答案取决于团队的培养能力和业务节奏。如果团队非常缺人业务又急接受一个基础薄弱的候选人也不是不行但要有明确的心理预期和管理成本。你需要给他配一个导师制定基础补课计划三个月后再做一次同样的技术评定。如果你没有这个培养精力直接 pass 反而是对双方都负责的决定。还有一种情况是候选人的基础其实还行只是简历写得太膨大。这种其实可以“降级录用”比如按初级工程师的标准给他发 offer试用期观察大半年。很多人不是没能力而是被焦虑和简历文化带偏了。如果他能接受现实定位踏实干半年往往会给你惊喜。但今天的这位候选人我个人的结论是连“降级录用”都不太建议因为他对基础的敏感度太低主动性也不够。我在反问环节问过他“你最近在读什么书或者在看哪方面的源码”他说“最近在刷短视频里的前端技巧”那一刻我就知道他对“成长”这件事的理解和我们需要的人不在一个频道上。写在最后的一点个人体会面试官这个角色做得久了真的会忍不住反思到底是我们太苛责还是整个行业的培训路径出了问题我的看法是不能把责任全推给候选人。前端这个行业的特点是“入门易、精通难”加上到处都是“三天学会 React”“七天拿下大厂面试”的内容新人很容易在错误的方向上狂奔。你让他说 Vue 的生命周期他背得比谁都熟但你让他解释自己的项目为什么选 Vue 而不是 React他完全答不上来。这就是典型的“知识半衰期”学得快忘得更快因为从来就没有形成理解链路。我给被筛掉的候选人一个不算客气但很真诚的建议别再去刷那些“面经合集”了。面经治标不治本它只会让你下一次面试的时候从“一个看起来什么都会的人”变成“一个看起来更熟练但依然什么都说不透的人”。真正能让你翻身的事不外乎三件把基础原理的链路想通把项目的设计取舍想透把手里的代码写到无可挑剔。这三件事半年足够看到变化一年足够拉开差距。到那时候你不用在简历上写“熟练使用”四个字面试官光听你说话就能感觉到你是干过活儿的人。最后说个小技巧。往后面试官的时候如果候选人能主动说出“你问的这个点我确实没深入过但我之前在某次排查 bug 时有过类似的经历是这么处理的”我其实大概率会给他加分。因为人非全能知道自己哪里不行、且能主动关联经验这种思维习惯比记住一万个知识点都值钱。今天的候选人如果哪天能看到这篇文章希望你不要只看到“面试官崩溃”这几个字。我更想让你看到的是一个人在职业路上最怕的从来不是“不会”而是“已经知道了自己不会却还在用背题的方式假装会”。这个坎迈过去前面就通了大半。