2019 年春天那会儿,我刚结束春招的大规模海投,拿到了几家公司的暑期实习 Offer。从 3 月初开始密集笔试,到 4 月底基本收尾,前前后后面了 15 场左右。现在回头看,那段经历最值钱的不是最后那张 Offer,而是通过一轮轮面试倒逼自己把前端知识体系从“会写页面”推到了“能讲清楚原理”的层次。
这篇面经主要面向两类人:一是正在准备前端暑期实习的大三/研二学生,二是刚转行前端、想系统梳理知识点的朋友。我会把 2019 春季招聘的面试题型、考察重点、准备方法、实战复盘完整还原出来。虽然每年考点会有微调,但底层逻辑和复习框架是通用的,照着这个思路去准备,至少能少走一半弯路。
1. 面试考察逻辑与整体准备思路
1.1 前端实习面试到底在考什么
先泼一盆冷水:前端实习面试,尤其是大厂的暑期实习面试,绝不是考你会不会写页面。因为能过简历筛选的同学,基本都具备“会写页面”的能力,这个维度拉不开差距。面试官真正想判断的是三件事:基础扎不扎实、思维清不清晰、潜力大不大。
基础指的是 JavaScript 语言本身的掌握程度,包括原型链、闭包、事件循环、作用域、this 指向、异步编程这些核心概念。思维指的是面对一个开放性问题时,能不能结构化地分析问题、拆分问题、给出解决方案。潜力指的是学习能力和沟通能力,面试官抛出你没见过的问题时,你的反应是“这我没学过”还是“这个我没接触过,但根据我的理解,它可能是什么什么原理”。
我后来跟一位参与过校招的资深前端工程师聊过,他的原话是:“实习生进来之后,至少有一到两个月是净投入期,我们要的是能快速学习和出活的人。基础好的人遇到问题会自己查文档解决,基础差的人连问题都描述不清楚。”所以面试本质上是在筛选能否在团队里活下来并创造价值的人。
1.2 准备周期、资料清单与知识图谱
我自己的准备周期大概两个月。1 月中旬开始系统复习,2 月集中刷题和整理项目,3 月进入笔试面试实战阶段。如果你准备时间更短,建议至少保证一个月以上,因为前端面试的知识面太散,不系统过一遍很容易漏。
资料方面,我当时的清单是这样的:
- JavaScript 核心:《JavaScript 高级程序设计(第 3 版)》重点章节 + 网上大量的前端面试题汇总。
- ES6+:阮一峰的《ES6 标准入门》电子版,重点看 Promise、async/await、解构赋值、模块化、Class 语法。
- 浏览器与网络:MDN 文档为主,配合一些经典的性能优化文章。
- Vue/React 框架:官方文档 + 源码分析文章。我主攻 Vue,所以把 Vue 的响应式原理、虚拟 DOM、diff 算法、nextTick 实现都过了一遍。
- 算法与数据结构:LeetCode 简单+中等难度题,重点是数组、字符串、链表、二叉树、动态规划入门。
复习时我画了一张知识图谱,按模块梳理:JavaScript 基础、浏览器机制、网络协议、前端工程化、框架原理、手写代码、项目经历。每个模块下再细化知识点,比如浏览器机制下面分渲染原理、缓存机制、事件循环、垃圾回收。这张图谱的作用是查漏补缺,哪个模块不熟就重点补哪个。
1.3 笔试与面试的侧重点差异
笔试和面试的考察方式完全不一样。笔试重点是算法题、编程题、选择题,考察的是编程基本功。面试则分电话面和技术面,电话面通常 30 分钟左右,考察基础知识和项目经历;现场面通常 2-3 轮,每轮 45-60 分钟,考察深度和广度。
笔试有个很重要的策略:先做会的题,再做不会的题。因为很多公司的笔试系统是计时的,而且题目难度不按顺序排列,第一题往往不是最简单的。我遇到过好几次,先花大量时间死磕一道难题,结果简单题没时间做,这种教训很惨痛。
面试的话,自我介绍一定要准备好,时间控制在 1-2 分钟,说清楚学校、方向、擅长的技术栈、项目经历中最亮点的部分。不要背简历,而是挑一两个能体现能力的点展开说,引导面试官问你准备好的内容。这是我的核心策略:面试不是被动答题,而是主动引导。
2. 核心考点深度解析与高频面试题
2.1 JavaScript 基础考点:闭包、原型链、作用域与 this
JavaScript 基础是每一场面试的必考内容,而且往往在前两轮出现。高频考点里,闭包、原型链、作用域与 this 几乎场场必考。这些知识点看似独立,实际上是一条线串起来的:JavaScript 是一门基于原型继承的动态语言,词法作用域决定了变量的可访问性,而 this 的指向则是在函数调用时动态决定的。
闭包的高频问法是“什么事闭包?有什么作用?有什么缺点?”。标准回答是:闭包是一个函数及其所在词法作用域的引用组合。作用有两个,一是隐藏变量实现封装,二是让函数可以记住创建时的上下文环境。缺点是变量不会自动销毁,容易造成内存泄漏,所以使用闭包时要注意引用关系的处理。
原型链的考点更隐蔽。面试官很少直接问“什么是原型链”,而是用一段代码让你判断输出结果,考察你对prototype、\__proto__、constructor的理解。比如:
function Person(name) { this.name = name; } Person.prototype.getName = function() { return this.name; }; const p = new Person('Tom'); console.log(p.getName()); console.log(p.__proto__ === Person.prototype); console.log(Person.prototype.constructor === Person);这段代码的输出是'Tom'、true、true,但很多人会在第二行卡住。原因是没有想清楚new创建对象时,p.__proto__会被指向构造函数的prototype。这个问题能深度考察,比如“如果给Person.prototype重新赋值一个对象,原来创建的实例还能访问到新方法吗?”答案是访问不到,因为实例的__proto__仍然指向旧的 prototype 对象。
this 的考察也很刁钻。经典的考法是给一段代码,问输出什么,比如:
var name = 'window'; var obj = { name: 'obj', getName: function() { return function() { return this.name; }; } }; console.log(obj.getName()());答案是'window',因为返回的匿名函数是在全局作用域下执行的。要回答这类问题,需要记住 this 的绑定规则:默认绑定、隐式绑定、显式绑定、new 绑定,以及箭头函数的特殊性——它没有自己的 this,而是继承外层词法作用域的 this。
2.2 浏览器机制:事件循环、渲染原理与垃圾回收
浏览器机制的考点范围很广,但是考察频率很高。事件循环(Event Loop)几乎是必考,而且通常是编程题的形式。面试官会给一段包含setTimeout、Promise、async/await的代码,让你写出输出顺序。高频的一个例子是:
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve() .then(function() { console.log('promise1'); }) .then(function() { console.log('promise2'); }); console.log('script end');输出顺序是:script start、script end、promise1、promise2、setTimeout。这背后是宏任务和微任务的执行顺序:每次执行一个宏任务后,会把当前微任务队列全部清空,再执行下一个宏任务。Promise.then属于微任务,setTimeout属于宏任务,所以微任务先执行。
这块内容要多花时间理解,因为后续的虚拟 DOM、React Fiber 调度、Vue 的 nextTick 实现都和事件循环相关。
渲染原理的考点集中在浏览器从输入 URL 到页面展示的完整过程。需要讲清楚 DNS 解析、TCP 连接、HTTP 请求、服务端响应、HTML 解析、CSS 渲染树构建、JavaScript 执行、重排重绘这几个环节。面试官还会追问“JavaScript 放在 body 底部的原因是什么”以及“async和defer的区别是什么”。答案是:脚本放在底部可以避免阻塞 DOM 解析;defer是异步加载,但会在 DOM 解析完成后执行;async也是异步加载,但下载完成后立即执行,可能会在 DOM 解析完成前执行。
垃圾回收一般问得比较浅,主要是问 V8 引擎的 GC 机制。核心是新生代用 Scavenge 算法进行复制回收,老生代用 Mark-Sweep 和 Mark-Compact 算法。面试官更关心的是你知不知道内存泄漏的常见场景:意外全局变量、闭包引用、未清除的定时器与事件监听器、分离的 DOM 节点。
2.3 网络协议考点:HTTP 缓存、HTTPS 握手与跨域方案
前端虽然不直接写网络层代码,但 HTTP 相关的问题是面试官非常爱问的。因为前端性能优化的核心就是合理利用缓存和减少请求,而跨域问题则无时无刻不伴随着前后端分离的开发模式。
HTTP 缓存是高频考点。需要说清楚强缓存和协商缓存的关系与区别。强缓存基于Expires和Cache-Control响应头,命中后直接从浏览器本地读取,不发请求给服务器。协商缓存基于Last-Modified和ETag,需要向服务器发请求,由服务器判断缓存是否有效。Cache-Control的优先级高于Expires,ETag的优先级高于Last-Modified。
HTTPS 握手也是常客。面试官通常会问“HTTPS 和 HTTP 的区别是什么”以及“HTTPS 的加密流程”,核心是握手的四次交换过程。简化版可以这样答:客户端向服务器发送支持的加密协议版本和加密套件列表,服务器从中选择一项并返回证书,客户端验证证书合法性后生成对称加密密钥,用服务器公钥加密传输给服务器,之后双方用对称密钥通信。这里的技术点涉及 TLS 握手、非对称加密、数字证书与数字签名,回答时注意讲清楚为什么需要对称加密和非对称加密混合使用——因为非对称加密慢,而对称加密需要安全的密钥分发。
跨域问题是很多同学容易翻车的点。面试官会问“什么情况下会产生跨域”“有哪些解决方案”。产生跨域的条件是协议、域名、端口任一不同。解决方案:JSONP、CORS、proxy 代理、postMessage、WebSocket。重点说的是 CORS,因为现在主流方案是 CORS 和后端 proxy。CORS 的细节包括简单请求和预检请求(preflight)的区别。满足以下条件的属于简单请求:方法为 GET/HEAD/POST,且请求头仅包含安全字段。其他请求会先发一个 OPTIONS 请求做预检,通过后才会发起真正的请求。
2.4 框架原理:响应式系统、虚拟 DOM 与生命周期
框架原理是区分度高的一类考点,面试官会从“会不会用框架”到“懂不懂框架原理”两个层次来考察。对于 Vue,我被问到最多的是响应式原理、虚拟 DOM、diff 算法和生命周期。
Vue 2 的响应式系统基于Object.defineProperty。核心思路是遍历数据对象的每个属性,用getter收集依赖,用setter触发更新。每个组件实例对应一个Watcher,当数据变化时,setter会通知依赖的Watcher进行更新。注意 Vue 2 的响应式有缺陷:无法检测对象属性的添加和删除,也无法直接检测数组索引和长度的变化。解决方案是使用Vue.set、Vue.delete以及数组的原型方法重写。
虚拟 DOM 与 diff 算法也是必问。Vue 的 diff 是双端比较,通过对比新旧虚拟节点的差异,最小化真实 DOM 操作。核心逻辑是只在同层进行对比,不跨层比较。算法过程:通过isSameVNode判断是否为同一节点,如果是则调用patchVNode递归更新子节点,否则替换整个节点。key 的作用是在列表 diff 时识别节点的复用,key 要稳定且唯一。
生命周期这块,面试官会问各阶段做了什么,以及父子组件生命周期执行顺序。Vue 的完整生命周期:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。父子组件的执行顺序是:父组件beforeCreate→ 父组件created→ 父组件beforeMount→ 子组件beforeCreate→ 子组件created→ 子组件beforeMount→ 子组件mounted→ 父组件mounted。销毁顺序是父组件beforeDestroy→ 子组件beforeDestroy→ 子组件destroyed→ 父组件destroyed。
如果面试官问 React,会考察 Hooks、Fiber 架构、渲染调度等。我第一次被问到“为什么 Hooks 不能写在条件语句里”,当时的回答是 Hooks 依赖调用顺序来关联状态,条件语句会导致顺序错乱,从而引发 bug。这个答案基本正确,但后来我还了解到这与 React 内部用链表存储 Hooks 状态有关,每次渲染需要保持同样的调用顺序才能正确取出对应 Hook 的状态。
3. 面试全过程还原与项目实战复盘
3.1 电话面 + 笔试实战记录
大部分公司的第一轮是简历初筛和电话面。电话面通常由 HR 或技术负责人发起,时长在 20-40 分钟。考察内容不算深,但覆盖面很广,主要是快速验证简历上的信息是否属实,以及技术基础是否达到及格线。
我记得有一场电话面,面试官没有问任何具体技术题,只让我“介绍一下你的项目中最有挑战的一部分”。我当时做的是一个基于 Vue 2 的后台管理系统,里面有一个复杂的权限控制模块,涉及菜单权限、按钮权限、数据权限。我把从需求分析到技术选型的完整链路讲了一遍,面试官听完后说“好,大概了解了”,然后就直接告诉我过了。
这个经验说明了一个关键点:项目经历表达比技术题回答更影响面试官判断。如果项目讲述能做到逻辑清晰、技术选型有依据、遇到的坑能讲明白,面试官会认为你具备独立思考能力,而这比背一百道题有用。
笔试环节,大厂的笔试题通常包含选择题、编程题和简答题。选择题覆盖 JavaScript、CSS、HTTP 等基础知识,编程题是 2-3 道 LeetCode 风格题目和一道手写前端代码题。手写题比较常考的有:手写防抖节流、手写深拷贝、手写发布订阅、手写 Promise、手写原生bind。这些题目在面试现场也会出现,所以属于必须准备的内容。
手写bind是一个经典考题。核心实现逻辑是:
Function.prototype.myBind = function(context, ...args) { const fn = this; return function(...innerArgs) { return fn.apply(context, [...args, ...innerArgs]); }; };但完整的实现需要考虑特殊情况:如果bind返回的函数被new调用,this指向要被忽略,而是指向新创建的对象。这种边角问题最能体现对 JS 的掌握深度,所以我建议复习时把bind、call、apply、new的原理全部过一遍。
3.2 现场面三轮全流程复盘
我印象最深的是某大型互联网公司的现场面。三轮技术面加一轮 HR 面,每一轮的侧重点都不同,特别能体现大厂的分层考察逻辑。
第一轮是基础面,时长大约 60 分钟。面试官是个年轻工程师,由浅入深,从“说一下 JavaScript 的数据类型”开始,逐步深入。先是null和undefined的区别,然后typeof null为什么是'object',然后是判断数组的方法与原理,等到我放松警惕后,他抛出了一个陷阱题:“typeof function(){}返回什么?为什么?”这道题要说明函数也是对象,但 JavaScript 底层将函数特殊标记为'function',不是'object'。
第一轮后半段考了算法题:“给定一个数组,找出其中连续子数组的最大和”。这是 LeetCode 53 题,用动态规划解法,状态转移方程是dp[i] = Math.max(nums[i], dp[i-1] + nums[i]),时间复杂度 O(n),空间复杂度可以优化到 O(1)。面试官要求我手写并解释思路,我写完后他追问了一个变种:“如果数组可以循环呢?”这个对应环形数组的最大子数组和,要分两种情况讨论。
第二轮是项目面,面试官直接打开我的简历,指着一个项目问细节。我的项目是一个可视化数据报表平台,技术栈是 Vue 2 + ECharts + Element UI。面试官追问了三个高难度问题:ECharts 图表在大数据量下的性能怎么优化;大量数据展示时页面卡顿,怎么排查和解决;如果让你重新设计这个项目的架构,你会怎么改。
这时候“说人话”特别重要。我如实说明了当时的做法:数据量几千条时直接渲染,但超过万条后图表明显卡顿,所以做了三个优化。第一,后端做数据聚合,前端展示聚合结果而不是原始数据;第二,用lodash.throttle对窗口 resize 事件做节流;第三,用v-if控制不可见图表的渲染,减少 DOM 节点数。面试官又追问“为什么这些能解决问题”,我解释到瓶颈在 DOM 节点过多和 ECharts 内部计算的复杂度,减少 DOM 节点数和数据量能直接降低渲染耗时。
第三轮是总监面,时长 30 分钟,没有具体技术题,更偏向综合素质考察。我记得面试官问过:“你怎么看前端的发展趋势?”“遇到一个从未见过的技术问题,你会怎么解决?”“你有没有主动做一些非课程要求的技术项目?”这些问题没有标准答案,核心是考察你的自驱力和学习能力。我谈到自己维护了一个技术博客,把学习过的知识点沉淀成文章;还参与了一个开源的组件库项目,给一个表单校验组件提了 PR。这些都让面试官觉得我具备持续学习的习惯。
3.3 从基础、项目到分层的考察策略
三家不同规模公司的面试流程和考察侧重点差异很大,这个分层现象值得细说。
大型互联网公司(TMD、头部独角兽等)的面试通常有 2-3 轮技术面,第一轮基础面,第二轮项目面,第三轮综合面。基础面重点考察 JavaScript、CSS、HTTP、算法,难度中等偏上;项目面重点考察技术深度和项目复杂度,会追着细节一直问;综合面重点考察学习能力、沟通能力、团队协作能力,技术问题不多但很开放。
中型公司(B 轮以后、规模几百人)的面试通常有 2 轮技术面,考察点更偏实战。面试官会直接问你用过什么技术栈,做过什么业务项目,遇到的具体问题怎么解决的。对算法考察不太多,但对业务理解有要求。比如做电商的会问你“商品列表页怎么做性能优化”,做内容平台的会问“图片懒加载怎么实现”。
创业公司和外包公司的面试相对更随意,可能是创始人和 team leader 直接面。考察重点是你能不能马上干活,技术深度要求不高,但要求你掌握的量比较广。会问到 CSS 兼容性、移动端适配、微信小程序开发这些更实操的内容。
所以准备面试前,最好先了解目标公司处于什么阶段,再针对性准备。如果目标是头部大厂,那算法和基础必须过硬,建议至少刷 100 道 LeetCode 简单中等题;如果目标是中型公司,项目经历和技术广度更重要;如果目标是初创公司,多准备一些跨技术栈的实战经验更有优势。
3.4 手写代码题的常见题型与答题技巧
手写代码题是前端面试的保留项目,也是最能拉开差距的环节。常见的题型大致分三类:工具函数类、异步控制类、框架原理类。
工具函数类包括防抖、节流、深拷贝、数组去重、数组扁平化、函数柯里化、发布订阅等。拿防抖举例,核心实现是:
function debounce(fn, wait) { let timer = null; return function() { const context = this; const args = arguments; if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(context, args); timer = null; }, wait); }; }写完之后面试官通常会追问“防抖和节流的区别”和“分别适用于什么场景”。防抖是等待事件停止触发后执行一次,适合搜索框输入场景;节流是事件在指定时间内只能触发一次,适合滚动加载和窗口 resize 场景。
异步控制类通常是手写Promise.all、Promise.race、实现一个串行请求函数、控制并发请求数。这些题的难点在于处理错误、处理空数组、处理顺序保证。实现Promise.all要注意用索引法而不是 push 法来保证结果顺序,还要考虑参数不是数组的情况。
框架原理类一般是手写一个简易的响应式系统、手写一个useState、手写一个nextTick。这类题难度较高,但考察深度最直接。比如手写简易响应式系统时,需要同时实现依赖收集和依赖触发,可以参考 Vue 2 的实现思路:用Dep管理依赖,用Watcher建立数据与视图的映射关系,用defineReactive拦截数据访问和修改。
手写题的回答技巧是:先讲思路,问清楚边界条件,再动手写。写完后主动跑一遍测试用例,不要等面试官提问。哪怕代码写得不是最优雅,思考和验证的过程本身就能加分。
4. 踩坑复盘与实习选择建议
4.1 我踩过的那些坑
面了十几场,踩过的坑不少,有几个特别典型,写出来给后来的同学提个醒。
第一个坑是项目经历准备得不够深。我一开始只准备了项目做了什么、用了什么技术,但没准备好“为什么这么设计”。第一次面试时面试官问“表单校验为什么选择动态规则而非静态规则”,我当场愣住了。后来我把项目里所有技术选型的“为什么”都列出来逐个准备,从 HTTP 缓存策略到组件拆分粒度再到状态管理方案,每个点都重新过了一遍。准备充分之后,面试节奏完全不一样。
第二个坑是算法基础不扎实导致翻车。有一场笔试,我卡在了一道中等难度的动态规划题上,浪费了太多的精力和时间,导致后面的简单题没写完。笔试整个心态崩了。这个教训很深刻:复习时要按知识点分类刷题,而不是随机刷题。每种算法类型都至少做 5 道题,总结出通用的解题模板。
第三个坑是忽略软技能。有一次面试,面试官让我“举一个你和别人产生分歧的例子”,我憋了半天没举出来。后来我想明白了,团队里沟通协作的价值甚至超过技术本身。面试官问这类问题,不是想听我说技术多牛逼,而是想确认未来一起工作时沟通不会出问题。准备阶段应当认真总结两个能够体现沟通能力和冲突处理能力的真实案例。
第四个坑是忽略了 HR 面的重要性。很多人以为拿到技术面通过就万事大吉,实际上 HR 面有一票否决权。我听说过一个案例,一个技术非常优秀的候选人因为跟 HR 谈薪资时态度太傲慢,最终被放弃。HR 面考察的是你的稳定性、求职动机、文化匹配度。回答“你为什么选择我们公司”这类问题时,要提前做功课,了解公司的业务方向和技术氛围,不要用“离家近”“钱多”这种答案应付。
4.2 如何评估和选择暑期实习 Offer
拿到多个 Offer 后,选择哪个公司也是个需要认真思考的问题,不要只盯着薪资和公司名气,更要关注以下几个维度。
第一是团队技术氛围。暑期实习的核心目标应该是技术成长,而不是赚钱。面试时可以反向问面试官:“团队现在主要用什么技术栈?有没有技术分享机制?迭代节奏是什么样的?”如果面试官答不上来,或者支支吾吾,说明团队可能没有沉淀,建议慎重考虑。
第二是业务的方向和发展前景。虽然实习生大部分时间是在比较基础的业务上开发,但业务方向会决定你能接触到什么类型的问题。做数据可视化和做管理后台,技术挑战的深度完全不同。如果在面试时能看出部门业务正处于快速上升期,代码结构在频繁迭代,说明你参与的项目有足够的复杂度,这种环境对实习生的成长更有利。
第三是 mentor 的质量。有一句话说“第一份工作的 mentor 决定了你的职业起点”,虽然有点绝对,但很有道理。一个负责任的 mentor 会认真 review 你的代码,带着你解决问题,甚至帮你规划成长路径。但这个信息很难在面试时获取,可以尝试联系在该公司实习过的学长学姐,或者向面试官询问具体的工作安排和团队协作模式。
第四是转正率。暑期实习很重要的目标之一是拿到转正 Offer,避开秋招的激烈竞争。面试时可以委婉地问 HR 或者面试官:“上一届实习生的转正情况大概是怎样的?”如果对方回答模糊,可能转正率不高。
4.3 入职前的技术准备与心态调整
拿到 Offer 之后的空窗期不要完全放松,建议提前做三件事:第一,了解公司的技术栈和团队使用的框架版本,尽量提前熟悉;第二,补足工程化知识,包括 Git 工作流、代码规范、CI/CD 流程;第三,读一到两本经典的技术书,比如《深入浅出 Vue.js》或者《JavaScript 忍者秘籍》,把理论基础再夯实一下。
心态上也要调整。很多实习生入职后会有挫败感,觉得学校学的东西跟公司用的东西完全脱节,代码写得慢,或者被 review 打回很多次。这些都是正常的。实习生的定位是学习和成长,不是产出第一生产力。保持空杯心态,多问、多听、多记录,遇到问题先自己尝试解决,超过一定时间再向同事或者 mentor 求助。这样既展示了主动学习能力,又不会浪费团队时间。
我进入公司实习后,第一个月基本就是熟悉项目、读代码、提交一些小 bug 修复。第二个月开始接需求,然后因为一个功能模块的边界情况没考虑清楚而被 mentor 打回重写。那次经历教给我的东西比任何面试题都深刻:写业务代码时,边界情况的考虑比主流程的实现更重要。这个教训,在后续所有工作中都很有帮助。
5. 常见问题速查与实战技巧
5.1 高频送命题速查表
以下这个问题清单覆盖了 2019 春季招聘中出现频率较高的考点,每个问题都值得整理出自己的一套标准回答。不要背答案,而是理解背后的原理,用自己的语言讲出来。
| 考点分类 | 高频问题 | 答题要点 |
|---|---|---|
| JavaScript 基础 | 闭包是什么?有什么用途和陷阱? | 函数 + 词法作用域引用;隐藏变量、记忆环境;内存泄漏风险 |
| JavaScript 基础 | 原型链继承的优缺点 | 基于原型链的属性查找机制;属性遮蔽现象 |
| 异步编程 | 宏任务和微任务的区别 | 执行顺序规则:先微后宏;常见宏任务与微任务类型 |
| 浏览器机制 | 浏览器从输入 URL 到页面展示经过哪些步骤 | DNS、TCP、HTTP、解析、渲染、JS 执行 |
| 浏览器机制 | 事件的冒泡与捕获流程 | capture 阶段从上到下,bubble 阶段从下到上;addEventListener 第三个参数 |
| 网络协议 | HTTP 1.1 与 HTTP 2.0 的区别 | 队头阻塞、多路复用、二进制分帧、头部压缩 |
| 网络安全 | XSS 攻击原理与防护 | 不要信任用户输入;转义、CSP、httponly |
| CSS | 盒模型与 BFC | content-box vs border-box;BFC 的触发条件与作用 |
| 框架 | Vue 中 computed 和 watch 区别 | computed 有缓存并依赖于响应式数据;watch 用于执行异步或开销较大的操作 |
| 工程化 | 前端构建流程中 Webpack 做了哪些事情 | 入口、loader、plugin、chunk、打包优化 |
5.2 五步答题法:遇到不会的问题怎么救场
面试中一定会遇到不会的问题,不要慌,更不要直接说“不会”。我总结了一个五步救场法,可以帮你把不会的问题转化成展示思维过程的机会。
第一步,复述问题。用自己的话把面试官的问题再描述一遍,确认自己理解正确。如果理解有偏差,面试官会帮你纠正。第二步,定位知识边界。说清楚这个问题涉及的领域你是知道的,但具体细节不完全清楚。比如“关于浏览器渲染原理我了解一些,但 CSS 的样式计算这块我没有深入看过”。第三步,展示推理过程。基于已有的知识做合理推测。比如“如果让我推测,我觉得子元素的相对定位应该会影响 BFC 的生成,因为定位元素会触发新的格式化上下文”。第四步,反问面试官。你在给出推测后,可以主动问面试官“这个方向对吗?”这样能把单方面答题变成讨论,面试官通常会愿意提示。第五步,表明学习态度,可以说“这个问题我确实没研究透,面试后我会去查一下,如果允许的话我可以加您的微信回头讨教吗?”——当然,最后这句要看面试氛围是否允许,有些正式场景不一定合适。
这个救场法不是技巧层面的投机取巧,而是把“不会”这个被动局面转化为“展示学习能力”的主动机会。面试官见过太多简历写得天花乱坠的人,他们更看重你面对未知时的应对姿态。
5.3 从面经到技术体系的沉淀方法
面经最大的价值不是看别人面了什么,而是通过面经反推自己的知识盲区。每次面试结束后,我会花 20 分钟做一个复盘,把面试中被问到的问题、当时的回答、面试后的思考全部记录下来。然后按知识点分类归纳,总结出高频考点的共性。
举个例子,我面了 5 家公司后发现,只要简历上写了“熟悉 HTTP”,面试官一定会问缓存。只要写了“熟悉 Vue”,一定会问响应式原理。这说明这两个点是标配,必须准备到位。再比如,如果多家公司都问了同一个你不会的问题,说明这不是冷门考点,而是行业共识,必须补齐。
复盘时要注意把知识点串成体系,而不是孤立的题目。比如从“浏览器缓存”这个点可以延伸出:强缓存和协商缓存的工作流程、HTTP 头字段的优先级关系、缓存失效时怎么更新前端的静态资源、后端设置缓存策略时的考虑维度。这样一个知识点能带动一整片知识网络,复习效率会高很多。
另外一个误区是只刷题不写。手写代码和框架原理必须自己实现一遍,只看别人的代码是看不懂的。我复习 Promise 时,是先看了一遍实现思路,然后合上书自己手写,写不出来再回头看,这样反复三次,直到完全掌握。这种方式虽然慢,但记忆效果非常牢固。
6. 总体复盘
2019 春季那次找暑期实习的经历,对我个人成长的影响比预期大得多。倒不是因为拿到了多好的 Offer,而是通过整整两个月的密集准备,我第一次意识到:前端不是一个“写写页面”的岗位,它需要扎实的编程基础、清晰的逻辑思维、结构化的表达能力和持续学习的习惯。
回头看,我觉得最值得推荐的做法有三个:第一,把面试准备当成一次系统学习的机会,而不是临时抱佛脚;第二,项目经历一定要深挖“为什么”,而不仅是“怎么做”;第三,每次面试后认真复盘,建立自己的知识题库,比看任何人的面经都有效。
最后分享一个面试技巧:面试结束后,记得主动向面试官表达感谢,并询问后续流程的预计时间。这不仅是礼貌,也能给你留下一个积极沟通的好印象。如果面试中某些问题没有回答好,可以当场表示“这个问题我会去补充学习”,并真诚地在面试后整理一份答案发给联系你的 HR 或面试官。我亲测过,这个动作会让面试官对你的印象分大幅提升。
祝正在准备暑期实习的朋友们都能拿到心仪的 Offer。