尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

欢聚时代2017校招Web前端A卷考点全解析与备考策略

欢聚时代2017校招Web前端A卷考点全解析与备考策略 拿到欢聚时代2017校招web前端A卷的时候大多数人的第一反应是题量不小覆盖面很广而且不是简单的背概念就能答的卷子。我当时把这份卷子完整复盘了一遍发现它其实代表了一种很典型的校招命题思路——企业不指望你什么都会但需要从卷面上判断出你有没有前端的完整知识框架、有没有工程意识、有没有快速上手业务的能力。这篇文章不讨论标准答案我按自己的理解拆解这套卷子背后的考点逻辑和备考方法帮准备校招的朋友看清楚web前端校招笔试到底在考什么以及你该往哪个方向使力。1. 打开这套A卷之前先搞懂校招前端笔试在筛什么1.1 2017年前端岗位的行业背景与技术栈2017年是个很有意思的时间点。jQuery还在大量线上项目里跑着Vue 2.0发布刚一年多React 16也刚刚出现Angular还在从1.x往2.x痛苦迁移。ES6早就定稿了但还有不少老项目用着ES5的写法。前端工程化概念已经普遍被接受Webpack、Babel成了新项目的标配但又远没有今天这么成熟。欢聚时代做直播和游戏相关业务这种公司的前端岗位有个特点对实时交互、高并发更新、页面性能的要求非常明确。直播弹幕要流畅渲染礼物特效不能卡顿聊天室消息要即时推送这些都直接反映在笔试题的倾向里——异步编程、事件机制、DOM操作性能、网络请求优化这些考点占比会明显高于纯做展示类页面的公司。了解这个背景再去看卷子很多出题意图就能猜到了。比如考事件循环不是为了让你背微任务宏任务的定义而是因为直播业务里大量异步回调写错了顺序界面就会乱。考重排重绘是因为弹幕每秒钟要更新几十上百条DOM性能优化不是加分项是刚需。1.2 笔试与面试、项目考察的分工逻辑很多同学在校招季容易陷入一个误区把笔试当成面试的前菜觉得答得差不多就行。实际上笔试、面试、项目考察各有各的分工企业是拿三份材料拼出一个完整评价的。面试主要看沟通能力、临场反应、思维深度面试官可以顺着你的回答往下追问看看你的知识边界到底在哪。项目考察看的是你做事的完整度能不能把一个东西从零做到上线遇到问题怎么解决。而笔试承担的任务非常明确在标准化的题目下用最低成本筛选出基础是否扎实知识体系是否完整代码能力是否达标。它不看你多聪明看的是你平时积累是否到位。所以笔试题的出题风格通常偏向宽而深——覆盖面要广但核心知识点又会往深里挖一层。卷面上不会问你闭包是什么而是给你一段代码让你判断输出结果再让你写一个闭包的应用场景。这就是笔试和面试的区别面试你可以聊思路笔试只能靠手底下的真功夫。1.3 命题比例画像哪些分值是送分哪些是拉差距从我当时对这类卷子的观察看前端笔试的命题结构大致有个稳定比例。JavaScript核心占35%到40%是绝对的大头。浏览器与网络占20%左右HTML/CSS占15%手写代码与算法占15%框架和工程化工具占剩余的10%上下。但这不意味着HTML/CSS可以放弃。恰恰相反很多同学挂在笔试上不是因为难题不会而是基础题丢分太多。选择填空里的语义化标签、CSS选择器优先级、盒模型计算这些题考察的是能不能直接上手写页面的基本功属于送分题。送分题做错会直接拉低整体印象分——阅卷人看卷的时候不会只看你难题答得怎么样他会想这个人连基础都不稳难题是不是蒙的所以备考的重心分配应该是先保证送分题不丢分再花力气主攻JS核心和手写代码这两块才是真正拉开差距的地方。2. JavaScript核心考点的出题方式与破题思路2.1 this指向、闭包、作用域判断题背后的三条规则JS这块每年的出题套路其实很固定但每年都有大批人栽在同一类题上——this指向判断。我记得很清楚有一类经典题目长这样var name global; var obj { name: object, getName: function() { return function() { return this.name; } } }; console.log(obj.getName()());很多人一看getName在obj对象里那么this肯定指向obj于是兴冲冲写下object。但答案是global非严格模式下。原因在于函数调用的this指向看的是调用方式而不是定义位置。obj.getName()执行完了返回的是一个独立函数这个返回函数再单独调用时它的调用者是全局对象所以this指向window。这种题考察的本质是this绑定的三条基本规则默认绑定、隐式绑定、显式绑定。默认绑定就是普通函数调用this指向全局隐式绑定是作为对象方法调用this指向该对象显式绑定是call/apply/bind强制指定this。所有this判断题核心就是看清楚这个函数到底是怎么被调用的而不是去想它定义在哪儿。闭包题也同理。笔试里闭包最常见的出法是结合for循环for (var i 0; i 5; i) { setTimeout(function() { console.log(i); }, 100); }输出的是5个5不是0到4。原因也不复杂setTimeout里的回调函数等到100毫秒后才执行那时候循环已经跑完了i变成了5。闭包捕获的是变量本身不是变量当时的快照。用let声明i就可以解决因为let每次循环都会创建新的绑定。如果你想展示自己对闭包的理解写成IIFE或者包一层函数也完全没问题。2.2 原型链与继承一张查找路径图的价值原型链是前端笔试里最能区分背过书和真懂的知识点。它表面上考的是继承机制实际上考察读代码时能不能沿着一层层原型链准确追踪属性来源。有一类题是这样的function Parent() {} Parent.prototype.say function() { console.log(parent); }; function Child() {} Child.prototype new Parent(); var child new Child(); console.log(child.say()); // parent这个不算难难点在变体。比如在Child.prototype上重新赋值同名属性或者改写了constructor题目就会绕好几层。应对这类题最靠谱的方法不是一遍遍猜而是心里画一张查找图实例访问属性时先找自身属性找不到就沿着__proto__往上找直到原型链顶端的Object.prototype再找不到就返回undefined。很多同学栽在原型链题上是因为死记了太多结论却没有真正理解prototype和__proto__这两个概念的区别。prototype是函数对象才有的属性指向一个对象__proto__是每个对象都有的属性指向构造它的函数的prototype。两者的关系用一句话概括fn.prototype是实例的原型instance.__proto__指向这个原型。把这条主线理清楚了原型链题就有了解题坐标。另外ES6的class在笔试里也常出现但出题人往往不会直接问class怎么用而是让你把class写法转成ES5的构造函数写法或者反过来。这其实就是在考你对原型继承本质的理解——class只是语法糖底层还是原型链。2.3 事件循环与异步编程宏任务微任务的先后博弈这类题在前端笔试里几乎是必考的因为业务里躲不开异步。有一段很经典的代码console.log(script start); setTimeout(function() { console.log(setTimeout); }, 0); Promise.resolve().then(function() { console.log(promise); }); console.log(script end);正确输出是script start、script end、promise、setTimeout。如果之前没研究过事件循环很多人会想当然觉得setTimeout先于Promise执行因为setTimeout写在前面延时还是0。但事件循环的规则是执行完一段同步代码后先清空微任务队列再取出一个宏任务执行。Promise的then回调属于微任务setTimeout的回调属于宏任务。同步代码全部执行完微任务优先宏任务在后。这个知识点在直播类业务里尤其重要。弹幕消息通过WebSocket推过来前端要更新DOM消息里附带礼物动画又得同步触发渲染用户自己发一条弹幕又得先本地更新再等服务器确认。这里面的时序处理用到了大量微任务和宏任务的配合。笔试考事件循环表面上是考概念实际上是在看你有没有能力处理这种复杂的异步时序。2.4 类型转换与数组易错点笔试里的陷阱题清单还有一类题非常讨人厌但确实能考出基本功——隐式类型转换。[] false为什么是truenull undefined为什么是true但null undefined为什么是false1 2是12但2 - 1是1这些题看着像脑筋急转弯实际上是JS设计里的隐式转换规则。笔试里遇到这种题我的建议是别靠猜直接把规则记牢宽松相等比较时如果两边类型不同会先把它们转成原始值再比较对象转原始值会走toString和valueOf数组转字符串时先转成元素以逗号连接的字符串。数组的易错点也值得单独梳理一下。forEach不能break但可以抛出异常达到类似效果map返回新数组forEach返回undefinedfilter是按条件筛选find是找第一个符合条件的元素slice不改变原数组splice会改变。这些区别笔试里可以直接考也可以在编程题里挖坑。我见过不少同学在写数组去重时用splice删元素结果索引对不上最后结果错得离谱。3. 浏览器与网络考点从写页面到懂页面如何工作3.1 输入URL到页面渲染一条主线串起所有细节这类题几乎是前端笔试的保留节目。完整的链路是DNS解析拿到IP建立TCP连接如果是HTTPS还要加TLS握手发送HTTP请求服务器返回响应浏览器拿到HTML开始解析构建DOM树同时解析CSS构建CSSOM树两者合成渲染树然后布局、绘制、合成最后呈现在屏幕上。笔试里不会让你把整条链路背下来而是挑中间某个环节深入考。比如DNS解析过程中浏览器会先查本地缓存然后逐级往上找而不是每次都从根服务器重新查。再比如TCP的三次握手为什么是三次而不是两次——因为要确认双方的收发能力都正常。这个细节在直播场景里非常关键连麦、拉流、弹幕长连接全都建立在TCP连接的基础上连接建立得够不够快直接影响用户体验。3.2 渲染阻塞与重排重绘为什么script要放底部渲染性能是前端笔试的另一个高频考点。这里最典型的问题是CSS会阻塞渲染但不会阻塞DOM解析普通script会阻塞DOM解析而加了defer或async的script不会。为什么script要放在body底部因为script在执行时会阻塞DOM解析如果放在head里浏览器得先下载并执行完脚本才能继续解析后续的HTML页面上出现大片白屏。而CSS放head里是因为CSSOM构建完成后才能渲染如果CSS放太靠后页面会先以无样式的状态渲染出来等CSS到位了再重新渲染——也就是常说的FOUC无样式内容闪烁。重排和重绘的区别是另一个常见考点。重排会改变元素的几何属性比如宽度、高度、位置浏览器得重新计算布局重绘只是改变外观属性比如颜色、背景不会影响布局。实际操作中读offsetWidth、offsetHeight这类属性会强制浏览器同步计算布局这就是为什么循环里反复读这些值性能会急剧下降。笔试答题时把尽量批量修改DOM、用class切换代替直接改style、避免频繁读取布局属性这几个优化点写上去基本就踩中得分点了。3.3 HTTP、缓存与状态码前端必须拿下的网络题网络这块前端笔试不太会考TCP拥塞控制这类偏底层的内容但HTTP协议和缓存策略是跑不掉的。状态码是送分题200正常、301永久重定向、302临时重定向、304走协商缓存、403无权限、404找不到、500服务器内部错误、502网关错误、503服务不可用。前端开发天天打交道的就这几个没理由记不住。缓存机制是容易出简答题的知识点而且容易答不完整。完整的回答应该分两条线强缓存和协商缓存。强缓存的实现方式有两个一个是老牌的Expires一个是HTTP/1.1推出的Cache-Control两者同时存在时Cache-Control优先。协商缓存也有两组headerLast-Modified和If-Modified-Since是一对ETag和If-None-Match是一对。关键点是协商缓存需要发请求问服务器资源有没有变而强缓存不用发请求就能直接用本地副本。我把这两者的差别列个表方便记忆缓存类型关键Header是否需要发请求判定依据强缓存Cache-Control / Expires否判断过期时间协商缓存ETag / If-None-Match是比较资源标识协商缓存Last-Modified / If-Modified-Since是比较最后修改时间笔试如果看到304相关选项答案基本都要落到协商缓存。服务器返回304时浏览器会用本地缓存的资源这是一种节省流量的优化方式。4. 手写代码题的得分逻辑阅卷人眼里什么样的答案值高分4.1 高频手写题清单与标准解法要点手写代码题是笔试里拉开差距最明显的部分也是最有提升性价比的部分——因为高频题目就那十几种练熟了就是送分。我梳理一下当年反复出现的清单防抖、节流、深拷贝、数组去重、数组扁平化、手写Promise、手写call/apply/bind、手写new、手写instanceof、柯里化、快速排序、二分查找。以防抖为例标准解法要先解释场景输入框搜索用户在连续输入时不断触发请求需要等用户停止输入一段时间后才真正发起请求。代码实现的核心是闭包加定时器function debounce(fn, delay) { let timer null; return function(...args) { clearTimeout(timer); timer setTimeout(() { fn.apply(this, args); }, delay); } }这里有个细节值得注意内部函数用了普通函数而不是箭头函数是因为需要继承外层的this。如果写成箭头函数this就得从外层查找逻辑就容易出错。很多同学手写的时候只关注功能忽略了this的正确传递阅卷人一眼就能看出你的JS功底是会用还是真懂。4.2 深拷贝、防抖节流等经典题的边界处理手写题能不能拿高分关键不在主体逻辑是否写对而在边界情况有没有考虑到位。比如深拷贝最简单的实现是JSON.parse(JSON.stringify(obj))但笔试题明确要求手写一个函数时你只写这一行往往拿不满分——因为这种写法丢失了函数、undefined、Symbol遇到循环引用会直接报错。一个更好的实现需要做到三点判断是否数组、递归拷贝、处理循环引用。function deepClone(obj, map new WeakMap()) { if (obj null || typeof obj ! object) return obj; if (map.has(obj)) return map.get(obj); const result Array.isArray(obj) ? [] : {}; map.set(obj, result); Object.keys(obj).forEach(key { result[key] deepClone(obj[key], map); }); return result; }用WeakMap存已经拷贝过的对象循环引用就不会无限递归了。这个处理方式体现了对WeakMap的理解——弱引用不影响垃圾回收这也是面试里可以延展讲的点。数组去重同样有完整答法和及格答法之分。及格答法用Set一行搞定完整答法要能说清楚Array.from(new Set(arr))的时间复杂度是O(n)比双层for循环的O(n²)好很多如果要求保留对象类型的去重就要用Map做深度判断。写代码的时候顺手把时间和空间复杂度写上去是很加分的习惯。4.3 笔试中的算法题难度定位与答题策略前端笔试的算法题难度通常集中在LeetCode简单到中等之间。和算法岗的笔试不一样前端算法题很少考特别偏的数据结构最常见的是字符串处理、数组遍历、简单的动态规划偶尔会出现二叉树的基础操作。答题策略上我的建议是先暴力、后优化、再边界。时间有限的时候先保证暴力解法写对把该拿的分数拿到。暴力解法虽然效率低但正确性没问题阅卷人不会直接给你零分。等暴力解法写完再尝试优化比如用空间换时间、用双指针替代双层循环。最后一定要检查边界数组长度是0怎么办只有一个元素怎么办输入是null怎么办这些细节往往决定了最终分数。以二分查找为例很多人主逻辑写对了但漏了边界条件left right或者数组长度为零时没有提前判断。笔试不是竞赛不要求最优解但要求完整、严谨、可运行。4.4 时间分配与做题顺序150分钟怎么用我自己做笔试复盘时总结过一个时间分配思路。拿到卷子先花1分钟把全卷扫一遍看看每类题的分值和数量然后按选择填空 → 简答题 → 手写编程题 → 算法题的顺序做。选择填空和简答题属于基础分先快速拿下确保不丢。手写编程题放在中间做因为这类题需要状态好、思路清晰放到最后容易因为时间紧张而慌乱出错。算法题放最后能做多少做多少至少把暴力的解法写上去。很多同学喜欢从最难的题开始做觉得难题分多。但笔试题通常不是阶梯式分布难题往往在中后段出现。从难到易的做题顺序一旦在某道题上卡了20分钟后面所有题的节奏就全乱了。先做简单的建立信心再慢慢啃难的这是比较稳妥的做法。5. 从这套题反推校招复习路线知识点优先级与两个月冲刺方案5.1 知识点分级表哪些必须滚瓜烂熟哪些了解即可结合这套卷子的命题风格我整理了一份复习优先级清单。按必须滚瓜烂熟需要熟练运用了解即可三个等级划分优先级知识点复习方式必须滚瓜烂熟this指向、闭包、原型链、事件循环刷题默写原理达到能给别人讲明白的程度必须滚瓜烂熟数组常用方法、ES6新特性每天手写一遍常用API的用法必须滚瓜烂熟HTTP缓存、状态码结合抓包工具看真实请求加深记忆必须滚瓜烂熟防抖节流、深拷贝、手写bind/new每个至少手写5遍直到不卡壳需要熟练运用浏览器渲染过程、重排重绘能结合具体页面案例说明优化点需要熟练运用简单算法排序、去重、二分LeetCode刷简单题每天2到3道需要熟练运用Vue/React生命周期与核心原理至少掌握一个框架能说清楚数据驱动视图的机制了解即可Webpack配置细节能说出loader和plugin的区别不必手写配置了解即可TypeScript、Node.js知道基本概念即可校招不太会深挖这个表的核心思想是笔试的得分重点非常集中别把时间浪费在冷门知识点上。2017年那会儿很多同学花大量时间研究Webpack的复杂配置结果笔试考的全是JS核心这种方向性的错误一定要避开。5.2 两个月复习节奏按周拆解的任务安排我把两个月备考拆成三个阶段。第一阶段是前两周任务是建立知识框架。主攻JS核心和HTML/CSS基础过一遍闭包、原型链、this、事件循环、异步编程每学一个知识点就做对应类型的题目。这时候不急着刷题先把概念吃透。可以配合一些在线练习平台每天留出专门时间做10道基础选择填空。第二阶段是第三到第四周任务是专攻浏览器和网络同时开始手写代码的专项训练。浏览器部分把从输入URL到渲染的完整链路过一遍网络部分把HTTP协议、缓存、状态码搞熟。手写代码从简单题材开始数组去重、深拷贝、防抖节流每题写完都要主动思考这里有边界情况吗这里可以用更优的数据结构吗。理解原理比题数重要。第三阶段是最后两周任务是模拟刷题加查漏补缺。每天做一套完整的前端笔试试卷严格按照考试时间限时。做完之后认真复盘哪些题是因为知识盲区丢分哪些是因为粗心丢分哪些是时间不够丢分。把错题整理成文档最后几天只看错题不再做新题。5.3 笔试结束才是开始同一考点在面试中的追问形式很多人以为笔试结束就解放了但笔试里考过的点面试里经常换个形式继续考而且面试的追问会更深。比如笔试让你手写bind面试就可能追问bind和call、apply的区别是什么bind返回的函数作为构造函数使用时this指向哪里new绑定和bind同时存在谁优先这其实是同一个知识点在往深挖。再比如笔试问HTTP缓存面试可能让你说实际项目中缓存导致的问题比如代码更新了但用户浏览器还显示旧版本你怎么排查、怎么解决这就是笔试考概念的延伸——从知道到会用。所以备考笔试的过程中多问自己一层为什么很关键这不仅仅是应试技巧也是正式入职后解决实际问题的能力基础。还有一点我想特别提醒笔试里的手写题在面试里通常会变成边写边讲思路的形式。面试官想看的不是正确答案而是你的思维路径。平时练习时可以自言自语地讲出每一步的意图比如这里用WeakMap是为了解决循环引用这里用apply是因为需要传递this和参数数组。这个习惯养成后笔试和面试都会受益。最后谈一点个人体会把欢聚时代这套A卷从头到尾梳理完我最大的感受是前端笔试不像很多人想象的那样注重偏题怪题恰恰相反越是基础的知识点越容易反复出现。它考的不是你学过多少新技术而是你对web前端这门学科的理解是否形成了体系。闭包、this、事件循环、浏览器渲染这些概念散落在不同章节里但本质上都是同一套世界观——JS的运行机制、浏览器的渲染逻辑、网络请求的流程这是做一个靠谱前端必须掌握的底层框架。备考时与其四处搜罗最新最全知识点不如把这些核心内容反复吃透。把这套卷子的考点逻辑弄明白了再去面对其他公司的校招笔试心里会踏实很多。web前端这条路基础扎实的人永远走得比追逐热词的人更远。
返回列表