ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

2018秋招前端面经:JavaScript、Vue与工程化核心考点全解析

2018秋招前端面经:JavaScript、Vue与工程化核心考点全解析 2018年秋招那会儿前端岗位的竞争已经白热化。我记得九月初开始投简历身边不少人都是“海投笔试面试”三线并行一天跑两三场宣讲会也不稀奇。当时前端面试的主流套路已经非常清晰基础知识、框架原理、手写代码、项目深挖四块内容基本能覆盖90%的面试时间。这篇面经我整理了那段时间的面试题目、回答思路、踩过的坑和一些复盘心得给后来者做个参考尤其是那些打算走前端方向的同学可以对着目录自查一下自己哪块还薄弱。1. 2018年秋招的整体节奏与考察倾向1.1 校招时间线从提前批到补录2018年的校招节奏比往年更早。互联网大厂通常七月底八月初就开放提前批九月初开始正式批笔试九月中下旬到十月是面试高峰期十一月中旬进入补录阶段。提前批一般免笔试或者笔试难度较低主要看简历筛选所以简历投得越早越好千万别等到九月才动手。我当时实际走下来的感受是提前批的面试官普遍更看重基础和项目深度正式批则因为筛选量大笔试环节刷人特别狠。笔试一般是单选、多选、填空题加两道编程题编程题大多不会超出LeetCode中等难度范围但多选题考得非常细会涉及JS引擎执行机制、CSS层叠规则、HTTP报文格式这类细节没有系统复习过的话很容易错。补录阶段是很多人忽略的机会。十一月下旬不少公司会放出剩余名额这个时候竞争比高峰期小很多而且因为补录通常直接约面试没有笔试环节对于笔试不占优势的同学来说反而是一条更顺的路。我有一个同学就是在补录阶段拿到了一家上海中厂的前端offer薪资比正式批还高了点。1.2 面试官角度他们到底想考察什么在秋招面试中前端岗位的考察点其实可以归纳成四层语言基础、框架原理、工程化认知、综合素质。语言基础指的是HTML/CSS/JavaScript重点是JS。面试官一般会用两三道题快速试探你的水平你说得越深入他追问的也就越深。比如说防抖节流初级回答是“防抖就是短时间内多次触发只执行最后一次”深入一点要能说出时间戳版和定时器版的区别、两者适用场景、能不能结合requestAnimationFrame改进等等。框架原理在2018年几乎必问Vue或React。当年Vue 2.x还是绝对主流面试官最爱问的包括数据响应式原理Object.defineProperty的getter/setter、虚拟DOM和diff算法、computed依赖收集、nextTick机制。如果简历里写了React那setState同步异步、fiber架构的动机、diff算法复杂度优化也会被追问。工程化认知是区分“会用工具”和“理解工程”的分水岭。webpack的loader和plugin区别、babel的编译流程、如何做代码分割、HTTP缓存策略这类问题在2018年秋招中几乎成了必考项。面试官不是真想考你哪个API怎么配而是要判断你有没有从“页面开发者”往“工程开发者”迈进的意识。综合素质包括沟通表达、遇到不会问题时的反应、对业务的理解深度。这一块没有标准答案但面试官会在你回答问题的过程中默默打分。我曾经有一轮面试挂在了一个开放题上——“如果让你设计一个弹窗组件你会怎么设计”我回答得太浅只说了样式和展示逻辑没有考虑可访问性、挂载位置、关闭策略、动画性能这些点面试官就没继续问了。1.3 前端岗位认知的变化2018年被很多人称为“前端工程化元年”这个说法有一定道理。前一年webpack 4发布babel 7也在2018年推出PWA、WebAssembly被频繁提及GraphQL在社区里讨论度很高小程序开发也刚开始带火一套全新的前端开发方式。这些背景知识不一定直接考但面试聊到行业趋势时能说出一些见解会显得你是一个有行业敏感度的候选人而不只是会刷题的应试者。我自己在面试中就被问到过“你怎么看待前端未来的方向”。这类问题没有标准答案但有几个角度可以切入前端从页面展示走向业务闭环、Node.js带来的全栈化趋势、小程序生态对前端开发模式的影响、前端工程化与自动化测试的成熟度。说完角度之后再结合自己的学习方向收尾比如“所以我最近在关注WebAssembly相关的应用场景”效果会好于干巴巴地背结论。2. 前端知识体系的考察重心拆解2.1 HTML/CSS看似简单坑却不少很多同学在复习时容易忽略HTML/CSS觉得太基础、没有区分度。但2018年秋招恰恰喜欢在这上面做文章因为基础题大家都会区分度反而在于细节掌握得是否准确。CSS方面被问频率最高的是这几个盒模型标准模型和IE模型的区别、BFC块级格式化上下文什么情况下会触发能解决什么问题、flex布局的常用属性特别是flex-grow、flex-shrink、flex-basis的配合关系、水平垂直居中的全部方案、CSS选择器优先级计算。这些每个都不能停留在“会写”层面面试官追问时至少要说出“为什么”。举一个例子flex布局中flex: 1到底代表什么标准答案是flex: 1 1 0%即flex-grow: 1; flex-shrink: 1; flex-basis: 0%但很多人会用却说不清楚。如果面试官继续追问“flex-basis为0%和auto的区别”能答出来的人就更少了。0%意味着初始主轴尺寸为0完全由剩余空间分配撑开auto则取决于内容尺寸。这个细节在实际布局中非常关键建议所有准备秋招的同学把flex的三大属性彻底吃透。HTML方面重点有语义化标签header、nav、main、article、section、footer的适用场景、表单元素的原生校验什么时候用required、pattern怎么配合正则、Canvas与SVG的对比。另外页面的可访问性a11y在2018年的一些企业面试中开始出现比如alt属性的作用、aria-label的使用场景我当时准备不足被问到过一次回答得不太好。2.2 JavaScript基础原型、闭包、this、作用域JavaScript是前端面试的绝对核心没有之一。2018年秋招的JS问题翻来覆去就是这几个方向原型与原型链、闭包与作用域、this指向与call/apply/bind、事件循环event loop、Promise与异步编程、ES6新特性。原型链这个问题面试官通常会用“new一个对象发生了什么”来切入。标准回答是创建一个空对象、对象链接到构造函数的prototype上、构造函数内部的this指向这个新对象、如果构造函数没有显式返回对象则返回this。但深入一点面试官会追问“instanceof的原理”要答出沿着__proto__向上查找和prototype做比较的过程再深入一点会问“Function.prototype和Object.prototype之间的关系”这一层能答上来的人就不多了。闭包这个话题常见的面试题是“for循环中使用var声明变量点击事件输出索引为什么都是最后一个怎么解决”。但更值得准备的是闭包在开发中的实际应用比如节流防抖、模块化封装、柯里化等。面试官听到这类应用场景时会明显对你的评价高一层因为说明你理解闭包不是为了解题而是在写代码时真的有使用意识。this指向问题在2018年被反复考。面试官最常用的套路是给一段代码让你说出输出的this是什么然后追问原因。核心就几条默认绑定严格模式下是undefined、隐式绑定谁调用指向谁、显式绑定call/apply/bind、new绑定优先级最高。箭头函数没有自己的this继承外层作用域的this。这些规则不只靠背最好自己能动手画一下代码执行过程。事件循环在秋招中出现频率极高。V8引擎的单线程模型、宏任务和微任务的分类、执行顺序的规则一道题就能考出一大截差距。经典输出题比如先执行script代码、遇到setTimeout放到宏任务队列、遇到Promise.then放到微任务队列、当前宏任务执行完清空微任务队列、再取下一个宏任务。准备这道题时建议自己写十个类似的变体跑一遍然后对比答案基本就能通关。2.3 浏览器与网络缓存、渲染、安全2018年的前端面试已经越来越重视浏览器底层原理因为面试官想确认你不是只会调接口而是对页面整体生命周期有理解力。HTTP缓存是这一块的最重要考点。强缓存Cache-Control、Expires和协商缓存Last-Modified、ETag的区别、各自的优先级、请求流程一定要能画出来或者用语言说清楚。面试官还会追问一个页面刚加载时资源是怎么被判定走缓存还是重新请求的修改了文件名后缀例如加了hash为什么能强制刷新缓存。如果这些问题都答上来基本就是满分了。浏览器渲染流程也经常考从输入URL到页面展示的完整过程包括DNS解析、TCP连接、HTTP请求、HTML解析构建DOM树、CSS解析构建CSSOM、合并渲染树、布局、绘制、合成。面试官喜欢在“CSS会阻塞DOM解析吗”“script标签放在body末尾的原因是什么”“defer和async的区别”这些点上深挖每个都值得仔细准备。前端安全方面XSS和CSRF是必考题。XSS要说出分类存储型、反射型、DOM型、危害、防御方式转义、CSP、HttpOnlyCSRF要说出攻击原理、和XSS的区别、防御方式SameSite、Token校验、Referer校验。最好配合一个实际案例来记忆比如“用户登录了银行网站又访问了钓鱼网站钓鱼网站通过表单自动提交请求转账”这个场景解释CSRF特别直观。3. 框架与工程化的深度准备3.1 Vue 2.x响应式原理面试必考点如果简历上写了“熟练使用Vue”那数据响应式原理几乎是必问的。2018年面试官最常用的追问路径是这样的Vue是怎么实现数据响应式的用Object.defineProperty的getter和setter对data中的每个属性做劫持getter中收集依赖setter中触发更新。追问依赖收集具体怎么做每个属性在初始化时会被new一个Depgetter中调用dep.depend()收集当前Watchersetter中调用dep.notify()通知Watcher更新。再追问为什么Vue 2不能检测到数组下标的变化因为Object.defineProperty无法拦截通过索引新增的属性。那怎么解决使用hack方式重写了数组的七个方法包括push、pop、shift、unshift、splice、sort、reverse。我建议每个准备Vue面试的同学都自己手写一个最简版的响应式系统几百行代码就能让你对依赖收集的理解产生质变。那时候我在准备时把Vue的响应式源码看了三遍然后把核心流程用白纸画出来能默写之后再去看第二遍效果完全不同。3.2 虚拟DOM与diff算法虚拟DOM和diff算法在2018年秋招中也是高频考点。要理解这个问题的本质得先回答“为什么需要虚拟DOM”直接操作DOM性能开销大频繁操作会导致页面重排重绘虚拟DOM用JS对象描述DOM结构通过对比新旧虚拟DOM的差异最小化真实DOM操作次数。diff算法的核心可以归纳为几点只做同层比较不跨层移动节点对比顺序是从根节点开始逐层递归当节点的类型不同时直接替换整个节点当类型相同时对比属性并更新变化部分对于列表节点通过key值来复用移动节点。面试官通常会追问“key的作用是什么”如果回答“为了提升性能”是很片面的准确说法是“key让Vue在diff时能识别哪些节点是同一逻辑单元的从而进行复用和移动不写key的情况下列表重排时可能会造成状态错乱”。为了加深记忆可以自己写一个小demo实现一个最简单的diff算法对比两个对象数组的变化然后在控制台输出操作步骤。做一遍之后再看Vue源码能理解得更透彻。3.3 webpack工程化从基础配置到优化策略2018年校招对webpack的要求已经不只是“会配置”了。基础问题是loader和plugin的区别loader是文件加载器用于处理各种类型模块的转换plugin是插件能介入webpack构建生命周期做更广泛的事情比如打包优化、资源管理、环境变量注入。loader执行顺序是从右向左plugin则通过tapable钩子注册事件。优化策略方面比较常考的点有HappyPack多线程构建当年还是主流方案、DllPlugin预编译第三方库、按需加载与代码分割dynamic import实现路由懒加载、Tree Shaking去除未引用的代码、提取公共代码splitChunks。面试官还会问生产环境构建和开发环境构建的配置差异比如开发环境需要SourceMap方便调试、需要热更新生产环境需要压缩代码、加hash指纹、配置CDN路径等。我当时准备webpack时把官网文档完整过了一遍然后用一个简单的Vue项目从头配置了一遍dev和prod环境手动实践了loader和plugin的编写。亲手写一个loader比如给文件内容加一个注释头和一个plugin在打包完成后输出文件大小列表这比背十篇面经都有用。4. 手写代码题与算法题的实战复盘4.1 高频手写题分类与解题思路手写代码是2018年校招中刷人最狠的环节往往安排在面试前二十分钟或者笔试的压轴题。我遇到的题型可以分四类工具函数类、继承类、设计模式类、浏览器API实现类。工具函数类最典型的是防抖、节流、深拷贝、数组扁平化、去重、柯里化。防抖和节流要能写出两种实现时间戳版和定时器版能说清楚各自的应用场景——防抖适合搜索框输入、窗口resize等高频触发且需要等待稳定后再执行的场景节流适合滚动监听、鼠标移动等需要保持一定频率执行的场景。深拷贝是2018年的一个重要考点重点在于考虑数组和普通对象的区分、处理循环引用使用WeakMap或者Map做缓存、处理Date和RegExp等特殊对象、可选地处理Symbol和函数。只答JSON.parse(JSON.stringify())的话基本就挂了因为面试官立刻会追问“循环引用怎么办”“函数和Symbol呢”“Date对象会变成什么”每个都是送命题。继承类需要掌握至少三种继承方式及各自的优缺点原型链继承、构造函数继承、组合继承、寄生组合继承。还要能实现ES6 class的extends转成ES5的实现方式这个在Babel时代算半个必考题。设计模式类在2018年也开始出现最常见的是观察者模式和发布订阅模式的手写实现。观察者模式和发布订阅模式的本质区别是前者目标和观察者相互依赖后者通过事件中心解耦。能把这个区别讲清楚再手写一个简单的EventEmitter包含on、emit、off、once方法面试官基本就满意了。浏览器API实现类最经典的是手写一个简易版的new、bind、call/apply、instanceof、Promise。手写new的关键是创建一个新对象、把新对象的原型指向构造函数的prototype、执行构造函数并让this指向新对象返回。手写bind要注意的点是支持函数柯里化传递预设参数、当bind返回的函数被new调用时this要被忽略指向新创建的对象。4.2 算法题LeetCode中等题为主的实战策略2018年的前端校招算法要求比普遍印象中要高一些。一线大厂基本会出2道LeetCode算法题难度在中等偏上偶尔有一道困难题。中小厂的编程题大多偏应用比如字符串处理、数组去重、简单排序。我的实战策略是首先把LeetCode的Top 100高频题刷熟特别是数组、字符串、链表、二叉树这四个类型。链表反转、两数之和、无重复字符的最长子串、三数之和、二叉树的层序遍历、爬楼梯这些题目几乎是重复出现的高频题。其次要准备排序算法的完整实现包括冒泡、选择、插入、快排、归并不仅要能写出来还要能分析时间复杂度和空间复杂度知道什么时候该用哪个。面试时最怕的不是题目难而是写了一半卡壳或者思路对但编码细节出错。我自己的经验是看完题目先和面试官确认输入输出和边界条件然后用中文说一遍思路再动手写代码。这样做的好处是即使最后代码没写完整面试官也能看到你的思考过程至少不会得零分。4.3 手写Promise一个能体现综合能力的题目手写Promise在2018年秋招中频繁出现因为它能同时考察你对异步编程、状态管理、this绑定、错误处理的理解。我当时准备时把Promise的完整实现从头写了一遍大概两百行代码写完后再去看那些面试题感觉一下子豁然开朗。手写Promise的核心要点Promise有三个状态pending、fulfilled、rejected状态一旦改变就不能再变构造函数接收一个executor函数立即执行并传入resolve和reject两个函数then方法返回一个新的Promise实现链式调用then中的回调是异步执行的需要用微任务模拟用queueMicrotask或者Promise.resolve()来包一层错误处理通过catch方法或者是then的第二个参数实现。面试时即使要求只实现基础版也要主动展示你对细节的理解。比如在then中处理返回值时如果返回值是一个Promise需要递归调用then来衔接如果执行过程中抛出异常需要走reject分支。这些细节写出来面试官会明显觉得你是有深度的。5. 简历、项目与面试过程的实操经验5.1 简历怎么写才不会被刷2018年秋招的简历筛选规则其实很简单粗暴学校背景是一道门槛但这个门槛往下有一定的突破空间关键是“有没有可量化的产出和明确的技能栈”。简历上写“了解Vue”和写“用Vue搭建过什么项目解决了什么问题带来了什么提升”在筛选者眼里是两种完全不同的信息密度。我整理简历时踩过几个坑写出来提醒大家技能列表别写太满写“熟悉”就行不会的话面试官一戳就穿项目经历不要只写功能要写清楚“哪部分是自己独立完成的”“技术难点是什么”“如何解决的”实习经历如果有要写清楚业务规模和负责模块而不是只有一句“参与xxx项目开发”。简历整体最好控制在一页A4纸排版干净清晰别用花哨的模板和花边。5.2 项目深挖如何做好自我介绍与项目陈述项目深挖是2018年面试中最容易翻车也最容易拉开差距的环节。面试官会在你介绍完项目后顺着你的话追问“你这个项目的难点是什么”“这里为什么这么做”“如果不这么做会有什么问题”“这个方案在极端情况下会怎么表现”。这一连串问题本质上是在验证两件事项目是不是你真正参与过的你做完之后有没有自己总结过。我在准备项目时会提前写好一个“项目介绍模板”包含项目背景解决什么问题、技术选型为什么选这些技术、我的职责具体做了哪些模块、难点与解决方案至少写两个、项目成果带来了什么可量化的收益。然后对着镜子练习两遍保证面试时用一分钟左右的时间能清楚讲完。面试时被打断很常见不用慌。面试官打断你有可能是对某个细节更感兴趣你只需要顺着他的问题回答就行。如果被问到“这个功能是怎么实现的”这类开放问题一定要边说边画思路把自己的逻辑分条目讲清楚不要一股脑把所有细节倒出来。5.3 面试中的沟通技巧与心态管理面试沟通技巧经常被低估但它实实在在影响了面试官对你的印象分。2018年我总结出的几个实用原则回答问题先说结论再展开细节不确定的情况不要瞎编可以说“这个我不太确定但我猜是xxx理由是xxx”遇到不会的题目先用自己的理解复述一遍问题再思考有没有相关的部分可以回答。心态管理方面最重要的是不要把一次面试的成败看得太重。秋招是一场长跑我见过一些同学因为前面几家公司挂了就一蹶不振后面发挥越来越差。正确的心态是每面完一场当天晚上复盘半小时记下被问到但回答不好的题目然后立即去查资料补齐这样下一场面试才会明显进步。我自己就是靠这个方法在面到第三家公司时明显感觉状态好了很多。6. 常见问题与避坑细节整理6.1 高频送命题的排查与应对这一节整理了我在秋招过程中遇到或者听身边同学遇到过的典型问题按难度和出现频率做了一张速查表。题目类型高频问题正确应对思路CSS什么是BFC如何触发触发条件float、overflow不为visible、position为absolute/fixed等作用防止外边距重叠、清除浮动、阻断margin穿透JS闭包是什么实际用途函数嵌套、内层访问外层作用域变量应用柯里化、防抖节流、模块封装JS手写深拷贝区分数组/对象、处理循环引用WeakMap、处理Date/RegExp、不要只会JSON法浏览器从输入URL到页面展示过程按DNS、TCP、HTTP、解析DOM/CSSOM、渲染树、布局、绘制、合成完整流程回答不要漏掉关键节点Vuecomputed和watch的区别computed有缓存、依赖响应式数据、同步返回结果watch适用于异步或复杂逻辑无缓存框架key的作用是什么让diff算法能识别节点复用和移动影响性能和组件状态正确性网络localStorage和sessionStorage的区别localStorage存储生命周期持久sessionStorage仅在当前会话有效都要注意存储大小限制工程化webpack的构建流程初始化参数→编译模块→构建模块依赖图→输出chunk→生成文件能说出loader和plugin介入的时机算法快排的时间复杂度平均O(nlogn)最坏O(n^2)何时退化为最坏每次基准值是最大/最小值开放题如何设计一个前端组件考虑props设计、事件交互、可扩展性、可访问性、性能、使用文档按层次展开6.2 笔试中容易丢分的细节笔试是很多人忽略的丢分点。2018年校招笔试通常是选择题两道编程题全卷时间一小时。选择题考得特别细丢分最多的往往是这几类正则表达式匹配规则、Promise输出的执行顺序、ES6中Set和Map的API细节、CSS选择器优先级计算、HTTP状态码语义。编程题是笔试的重头戏很多时候决定你是否能进入面试环节。我强烈建议在笔试前把编辑器环境熟悉一遍特别是输入输出格式。很多牛客网风格的笔试不需要你自己处理输入输出函数题但有些公司会出ACM风格题需要手动读取标准输入。两种模式都要练几道题不然正式笔试时容易在环境上浪费时间。笔试的另外一个技巧是时间分配选择题控制在二十分钟内编程题每道至少留二十分钟。遇到不会的选择题不要纠结直接标记跳过。编程题即使做不完也把思路写在注释里部分判卷会看代码注释给分。6.3 一些准备建议与个人体会秋招准备切忌突击。2018年我见过最成功的准备方式基本都是在五六月份就开始系统复习七月份刷完一轮基础题八月份集中做项目复盘和手写题九月份开始投递。如果等到九月份才开始从零准备时间压力确实非常大心态也很容易崩。另外一定要重视模拟面试。找同学或者学长学姐互面不但能帮你提前适应面试节奏还能暴露出你自己发现不了的问题比如说话停顿多、逻辑混乱、回答问题发散等。我当时和三个同学组了一个互相模拟的小组每周两场坚持了一个多月效果非常好。后来正式面试时心态稳定了很多。最后再说一点面经只是参考不能代替自己的系统学习。面试题是流动的2018年的重点可能和2019年、2026年的重点完全不同但底层能力是一样的。把基础原理弄懂把项目经历吃透把代码练熟无论面试题怎么变你都能从容应对。
返回列表