两年前端经验去面中大厂,说实话是个有点尴尬的节点。说你是校招生吧,已经独立负责过模块了;说你是资深前端吧,又还没到能独当一面做架构的份上。面试官最怕遇到的就是“写了两年业务代码,一问原理就含糊,一让设计就沉默”的候选人。这篇“下篇”我主要想聊聊比基础八股更重要的东西——项目深挖怎么讲、手写题怎么答、场景设计题怎么拆、二面三面到底在看什么。如果你已经差不多把框架原理、浏览器原理这些基础刷过一遍,那这篇文章会更适合你。内容全部来自我自己的真实面试经历和复盘,希望能帮你少走点弯路。
1. 两年经验这个节点,面试官到底在筛什么?
先拆一个现实问题:两年经验去面大厂,你的期望职级通常是P6或者同级别,这个层级不再只看你会不会写代码,而是看你能不能独立负责一块业务或者一个系统。面试官手里的评估清单,跟我一开始想的不太一样。
1.1 五个核心考察维度
我后来复盘了整个面试流程,发现所有问题最后都指向五个维度:
- 基础扎实度:JS、浏览器、网络、框架原理,这些是入场券。两年经验的人如果还要靠背答案才能过基础题,面试官会直接把你定位成“初级”。
- 工程化能力:脚手架、构建工具、代码规范、CI/CD、依赖管理、组件库建设。很多两年经验的人只会在项目里“用”,不知道怎么“搭”。
- 业务和技术深度:你负责的业务有没有技术难点?性能优化做到什么程度?有没有做过数据驱动的决策?项目里有没有你独立设计的技术方案?
- 系统设计思维:给你一个复杂需求,你怎么拆解、怎么设计、怎么取舍。这是区分“写代码的人”和“做方案的人”的关键。
- 软素质和成长性:表达是否清晰、遇到问题怎么排查、能不能主动推进、抗压能力如何、未来有没有成长潜力。
1.2 为什么“只会用不深究”是硬伤
我在前面几轮面试里吃过最大的亏,就是被问到“为什么这样设计”时答不上来。比如用Redux,只答得出来“全局状态管理”,但说不清为什么需要单一数据源、为什么reducer必须是纯函数、和MobX/Zustand的取舍是什么。这种问题一追深,就容易露馅。
后来我的策略是,把用过的每一个库、每一个框架都补到“能说出设计动机”的深度。不要求你源码全看懂,但要知道它解决什么问题、核心思想是什么、缺点是什么。面试官想看到的不是什么都懂,而是你有“探究本质”的习惯。
2. 项目经历深挖:给面试官讲一个“可信”的故事
项目深挖是两年经验面试的重头戏,也是很多候选人最容易翻车的地方。原因很简单:自己做的项目自己最熟,但熟不代表会讲。很多人讲了十分钟,面试官听完不知道你具体做了什么、难点在哪、你扮演什么角色。
2.1 用“STAR+矛盾”框架组织项目陈述
我后来把每个重点项目都用“故事框架”重新梳理了一遍,核心结构是这样的:
- 背景(Situation):项目是什么业务、什么规模、你在什么团队。
- 任务(Task):你具体负责哪块,目标是什么,比如“把首屏时间从3s优化到1.5s”。
- 行动(Action):你做了什么,这个一定要有技术细节,比如“做了路由懒加载+图片压缩+服务端预取数据,而不是笼统地说我做了性能优化”。
- 结果(Result):量化数据,比如“首屏时间平均下降40%”。
- 矛盾(Conflict):这个最关键。项目里有没有资源冲突、技术选型争议、性能与开发效率的平衡、历史包袱限制?把矛盾点讲出来,才能体现你的思考。
比如我第一次讲组件库项目时,只会说“我封装了一些公共组件”,面试官完全无感。后来改成这样讲:背景是团队里有多个后台项目,重复代码严重;任务是搭建一套统一的组件库;行动是我先做了技术选型对比,最终基于业务场景自研了低侵入、可渐进迁移的方案,而不是直接引入第三方UI库;结果是四个后台项目接入,复用率超过60%;矛盾点在于自研组件库初期成本比直接用现成的高,我通过先做最痛的五到八个组件、再逐步扩展的方式降低风险。
2.2 深挖追问的常见套路
面试官听你讲完项目后,通常会顺着几个方向追问:
- “为什么不用现成库?”——考察你选型的能力。不要只说“现成的不好用”,要说清楚业务诉求和现有方案的差异。
- “当时有对比数据吗?”——考察你是否用事实说话。没有数据就补一次快速验证,哪怕是个小Demo也得有结论。
- “这个方案有什么缺点?你后来怎么知道?”——考察自我反思能力。任何方案都有取舍,大方承认缺点比嘴硬要好得多。
- “如果现在重做,你会在哪些地方做不同决策?”——考察复盘和成长能力。这个问题一定要提前准备,结合你后来踩的坑来讲。
2.3 简历上每个项目都要能“滑向”下一个话题
好的项目讲述是有伏笔的。你讲到一个技术点时,面试官很可能顺着往下挖,你要提前想好“钩子”。
比如你提到“用Web Worker处理大文件上传”,面试官下一句很可能就是“Worker通信怎么处理的?分片断点怎么实现?服务端合并方案是什么?”所以准备项目时,最好把项目里的技术点都列成树状结构,每个叶子节点都准备两三个深入问题。我习惯用Markdown把所有可能的追问写一遍,然后对着镜子讲两遍,直到流畅为止。
3. 手写题与算法题:我踩过的那些坑
两年经验面试手写题基本不会太简单,但也不会直接上Hard级别。重点考察的是“你平时写代码的习惯”和“基本功是否扎实”。不夸张地说,我面过的公司里,三轮技术面至少会有一轮出现手写题。
3.1 高频手写题清单和套路
我统计了一下被考过的题,出现频率最高的是这些:
- 防抖节流(几乎必考,但经常被要求实现带取消功能和立即执行版本)
- 深拷贝(要考虑循环引用、Map/Set/Date/RegExp的特殊处理)
- 手写Promise(至少实现基本状态流转和then链式调用)
- 手写apply/call/bind(原理很简单,但考得很细)
- 数组扁平化、去重、乱序(多解法+复杂度分析)
- 事件总线EventEmitter(on/off/emit/once)
- 手写instanceof、new、reduce
- 对象发布订阅、带并发限制的调度器
- 手写一次性函数、函数组合 compose
拿防抖举例,基础版人人会写,但面试官会追问“要不要支持immediate参数”“怎么取消”“this怎么绑定”。我建议直接背一个生产级版本:
function debounce(fn, wait = 300, immediate = false) { let timer = null; let result; const debounced = function (...args) { if (timer) clearTimeout(timer); if (immediate && !timer) { result = fn.apply(this, args); } timer = setTimeout(() => { if (!immediate) { result = fn.apply(this, args); } timer = null; }, wait); return result; }; debounced.cancel = function () { if (timer) clearTimeout(timer); timer = null; }; return debounced; }答这种题的关键不是默写代码,而是把this做对,把边界条件讲清楚。面试官考察的是你平时是不是严谨写代码的人。
3.2 算法题复习优先级
两年经验面试算法题,一般不会超纲到竞赛级别。我按出现频次排个优先级供参考:
| 优先级 | 题型 | 典型题目 |
|---|---|---|
| 第一梯队 | 链表、二叉树、字符串 | 链表反转、环形链表、二叉树层序遍历、最长无重复子串 |
| 第二梯队 | 双指针、哈希表、栈队列 | 三数之和、合并区间、有效括号、滑动窗口 |
| 第三梯队 | 排序、二分、堆 | 快速排序、二分查找变种、前K个高频元素 |
| 第四梯队 | 动态规划、回溯 | 爬楼梯、最长递增子序列、全排列、子集 |
复习策略很简单:优先做面试前背诵成本低、但出现频率高的题。链表和二叉树相关的题套路很固定,练熟性价比最高。动态规划短期提分慢,但爬楼梯、打家劫舍、背包问题这类经典题必须掌握。
3.3 解题节奏比写对更重要
我一开始有个坏习惯:拿到题就开始疯狂敲代码,结果写了一半发现思路错了,反而更慌乱。后来我总结了一套稳定的节奏:
- 先重复题意:用自己的话说一遍,确认没有理解偏差。
- 举一个简单例子:手动推演一遍,顺便验证自己的理解。
- 说思路:哪怕你想的是暴力解法,也要先说出来,面试官会引导你优化;闷头写题是面试大忌。
- 写代码:写的时候注释关键逻辑,边写边讲。
- 自查边界:空输入、只有一个元素、全是重复值、整数溢出等。
- 提优化方案:就算你已经写出最优解,也可以主动补一句“如果数据量再大,还可以用XXX方案”。
这套节奏能让面试官感受到你的工程思维,哪怕题没完全写出来,印象分也不会低。
4. 场景设计题:如何从“会做”到“会说”
到了二面或三面,场景设计题出现的概率会非常高。这种题没有标准答案,考察的是你面对模糊需求时能不能结构化思考、能不能做出合理取舍。我第一次面到这种题直接懵了,后来琢磨出了自己的答题框架,基本能应对90%的场景题。
4.1 场景设计题的五步拆解法
我会把一道场景题拆成五个环节来作答:
- 澄清需求(1-2分钟):先不急着给方案,问清楚业务背景、用户规模、性能预算、团队现状。比如面试官问“设计一个上传组件”,你要反问:上传的文件类型和大小限制?目标浏览器是什么?是否需要断点续传?是否需要并发控制?服务端是否支持分片合并?这些问题本身就展示了你的经验。
- 抽象核心问题:把需求拆成几个核心模块,比如上传组件可以拆成:文件选择与校验、分片与队列、任务调度与并发控制、进度上报、异常恢复、UI展示。
- 给出技术选型:每个模块给出选型方案,说明为什么选它而不是另一个,比较利弊。比如分片用
File.slice,并发控制自己写一个调度器而不是用现成库,因为方便定制重试策略。 - 画清楚交互流程:可以口头描述时序流程,比如文件选择后先校验,再读取元信息,然后生成分片列表,逐个上传,所有分片完成后调合并接口。这种流程叙述也能体现工程思维。
- 补充边界和扩展:主动说这个方案的瓶颈在哪,怎么优化,比如大文件场景下主线程卡顿怎么办,能不能把分片和校验逻辑放进Web Worker。
4.2 一个完整示例:大文件上传组件设计
我面试时被问到过“设计一个大文件上传组件”,恰好我项目里做过类似的功能,所以答得比较顺。这里给你还原一下我的答题思路。
需求澄清阶段我会先确认:文件类型、大小上限、是否需要断点续传、并发数、是否需要秒传。假设答案都是“是”且并发放宽到3个。
核心设计:
- 文件校验:用
type和size做前端预检,但服务端也要做二次校验。 - 分片:用
File.slice按固定大小切分,比如2MB一片。为什么选2MB?太小请求数量多,占用连接资源;太大失败重试成本高。2MB是我在项目里实测比较均衡的值。 - 秒传:先读文件内容算出唯一标识(通常是
hash),可以抽查部分字节做快速hash,也可以全量算。把标识发给服务端,服务端判断之前是否传过,传过就直接返回合并成功。 - 并发调度:自己写一个简单的并发调度器来控制同时上传的分片数,防止把网络打满。
- 断点续传:每传一个分片,成功后记录状态;刷新或失败后,重新查询哪些分片已上传,剩下的继续传。
- 进度计算:进度=已成功上传分片数/总分片数,而不是用网络传输的字节数,这样更稳定。
- Worker优化:如果文件非常大,计算hash确实会卡住主线程,可以把hash计算、甚至校验逻辑放进Web Worker,通过
postMessage通信。我在项目里这么做过,体验提升非常明显。
在扩展部分我会讲:这个方案对超大文件(比如1GB+)依然可用,但服务端要注意磁盘分片管理;如果想进一步优化,可以走“文件元信息+分片级秒传”的路线,先只传文件元信息,再按需传缺失分片。
4.3 另一个常考题型:设计一个组件库
组件库设计也很常考,而且和“组件库建设”项目经常混在一起问。答题框架类似:先从业务现状出发说明为什么不自研而是选型;然后给出分层设计——基础组件层、业务组件层、页面模板层;再说明规范的统一方案,包括命名规范、props规范、文档和示例、按需加载、主题定制、单元测试。面试官更关心你有没有“复用思维”和“规范意识”,而不是真的让你当场设计一套完整的库。
5. 二面三面的“隐形考点”:设计、排错与软技能
到了二面三面,考察的东西会越来越抽象。可能不再问你“响应式原理是什么”这种有固定答案的问题,而是给出一个模糊场景,看你怎么应对。我一开始觉得二面三面很玄学,后来发现还是有规律可循的。
5.1 二面:技术专家或团队负责人,看重系统设计
二面的面试官通常是团队里的技术专家或者直属领导,问题会偏向“你负责的系统整体架构是怎样的”“性能问题怎么定位”“流量翻十倍你会怎么设计”。他更关心你能不能跳出单个组件去思考整体。
比如问“首屏性能怎么优化”,你不能只回答“懒加载、压缩图片”这种零散方案,而要按“资源加载—渲染过程—用户感知”的链路来讲。我的回答模板是:
- 网络层:HTTP缓存策略、CDN加速、服务端开启HTTP/2或HTTP/3。
- 资源层:JS/CSS/图片体积控制、路由懒加载、按需加载、格式升级(WebP/AVIF)。
- 渲染层:减少重排和重绘、优化关键渲染路径、骨架屏/SSR/SSG。
- 数据层:接口合并、数据预取、缓存到本地(localStorage/IndexedDB)。
- 度量层:搭建性能监控,用FP/FCP/LCP/TTI等指标驱动优化闭环。
这套完整性会明显拉开和普通候选人的差距。
5.2 三面:跨部门或总监,看重认知和软素质
三面经常出现一些“没有固定答案”的问题,比如“你怎么看待微前端”“你怎么看待前端AI辅助开发工具”“未来两年你的规划是什么”。不要答成纯粹的技术优劣分析,要往团队协作、业务价值、技术趋势上靠。
比如微前端,面试官真正想听的是:用在什么场景下、解决了什么问题、引入后产生了什么新问题(隔离、通信、依赖共享)、最后怎么权衡取舍。我个人经验是:如果团队不大、业务不复杂,微前端引入的成本可能远大于收益。这种清醒的认知,比一股脑吹某个技术更能打动面试官。
5.3 排错题:把“背答案”变成“讲排查链路”
二面三面还有一个高频题型是排错题,比如“页面白屏怎么排查”“线上接口突然变慢怎么定位”。这种题想拿高分,不能只说一个可能原因,而要展示完整的排查链路。
我一般会这样回答:
- 先复现,再看影响范围:是单用户还是全量?是固定操作还是偶发?能不能用最小化步骤复现?
- 命中监控,看报错信息:有没有JS报错、接口状态码是什么、有没有资源加载失败。
- 按链路逐层排查:前端网络请求(看Network面板)→ 后端服务状态(看接口响应时间)→ 数据链路(看数据库或缓存)。
- 给出临时降级与根因修复方案:白屏时可以先用错误边界兜底,再修根因;接口变慢可以先做缓存或限流,再追查服务端瓶颈。
这种“从现象到影响,再到可能原因,再到排查动作”的结构化思维,是面试官真正想看到的。
6. 我复盘出来的几个“后悔没早点知道”的教训
最后这部分,我不打算做那种“按内容回顾”的总结了,就想以个人身份说几句踩过坑之后才懂的事,希望你能直接拿去用。
第一,项目深挖准备不是写PPT,而是造一棵“追问树”。每个项目里的技术决策,都往下多问两三个“为什么”。你不仅要准备“我做了什么”,还要准备“我为什么这么做”“这么做有什么代价”“如果重来有没有更好方案”。没有这几个层次,面试官随便一深挖你就会露怯。
第二,手写题一定要“带注释地写”。我面试时习惯在代码里写一两行注释,比如在debounced.cancel下面写“用于取消定时器,防止内存泄漏”。这个细节会让面试官觉得你写代码是有意识的,而不是背模板。我亲测很有用。
第三,场景设计题不要急着给答案。哪怕脑子里已经有完整方案了,也要先假装思考一下,然后从“需求澄清”开始答。这个顺序不是表演,而是展示结构化思维的绝佳机会。我见过太多候选人直接开讲方案,结果讲了一会儿发现偏离面试官想问的方向,反而尴尬。
第四,准备一个“个人技术栈之外的兴趣点”。二面三面经常有“你平时关注什么新技术”这种问题。我的经验是提前准备一个和前端相关但不算特别大众的方向,比如前端性能监控、低代码平台、WebAssembly、AI辅助编程效率提升等。选一个你真正研究过的小方向聊,比泛泛地说“我都关注”强得多。我当时准备的是Web Worker结合上传场景的实践,聊得还挺深。
第五,面完之后立刻复盘。我每面完一轮,会在手机上记下被问到的问题,尤其是没答好的题。当天晚上就把这些题按“基础、项目、场景、系统设计、软素质”分类整理,能查的资料立刻查掉。这个方法帮我后面几轮面试越打越顺畅,因为很多题是重复的。
两年经验这个阶段,拼的不是谁聪明,而是谁准备得更充分。基础题大家都会刷,拉开差距的往往是项目讲得清不清楚、设计题有没有章法、被追问时能不能扛住。希望这份面经能让你在下一轮面试里多一分底气。