
1. 2017年欢聚时代这张B卷的定位一张试卷背后的行业切片1.1 为什么标题里藏着年份、公司、卷号三个关键信息“欢聚时代2017校招笔试题目web前端类B卷”这个标题看起来只是一个普通的历史笔试题但我建议别把它当成单纯的刷题素材。标题里那三个信息点每个都值得先拆开看。第一是“2017”。2017年的前端生态和现在差别非常大。Vue 2.0才发布不到一年React 16刚刚上线webpack 3还在大量使用TypeScript虽然在开源项目里名声不小但在多数业务团队里的普及率远不及今天。很多中小团队的核心页面还在用jQuery前端工程化刚走完“脚手架”阶段正处于向“体系化”过渡的时期。这个背景直接决定了试卷的题型和难度——它不是在考框架API而是在考语言基础、浏览器机制、手写代码能力因为这才是那个年代前端能力的硬通货。第二是“欢聚时代”。欢聚时代的核心产品是YY语音、多玩游戏网直播和社区是它的基本盘。这类业务的前端有一个很鲜明的特点实时交互密集、活动运营页高频、移动端H5场景多。反映到笔试上它自然会比较关注异步处理、事件机制、浏览器渲染、手写能力因为这些能力直接决定了直播页面的弹幕流畅度、活动页的加载速度、H5在不同机型上的兼容表现。业务类型决定岗位岗位决定了笔试题的偏向这条逻辑链条在2017年比今天还要直接。第三是“B卷”。校招笔试分A、B卷是当年的常规防作弊操作相邻座位用不同卷子题目顺序打乱、数字参数替换、选项重排。B卷并不是“更难的卷”它只是平行卷。我亲眼见过不少同学拿到B卷发现题目顺序和网上的A卷回忆版对不上就开始怀疑自己复习方向错掉了其实完全没必要你只需要关注考点本身而不是纠结自己拿到的是哪一份。1.2 2017年的线下笔试是怎么组织的2017年那会儿校招笔试和现在多数公司线上笔试的模式差别挺大。头部互联网公司主流做法是线下租教室统一笔试有的用手写纸质试卷有的在简陋的答题系统里做选择题编程题还是要落到纸上。就欢聚时代2017年这场前端校招笔试而言从当时参加过的同学反馈和公开信息来看形态基本可以确定为线下闭卷时长大约90到120分钟题型包含单选题、多选题和手写编程题。如果你今天把这份卷子翻出来第一感受很可能是“题目不算难但要写得快”。这恰恰是校招笔试的真实定位它不是要选出满分选手而是要筛选出“基础扎实、能在有限时间内交付有效代码”的人。90分钟要完成二十多道选择题加上两三道手写编程题时间非常紧张。每次有同学来问“编程题写一半时间就到了怎么办”我的回答都是时间分配本身就是考察内容之一。线下手写还有一个被低估的维度它考的是临场呈现能力而不只是知识储备。手写代码没有编译器帮你纠错没有IDE的补全没有浏览器控制台可以现场验证写出来的东西必须一步到位。这和现在的线上编程不一样反而更接近面试白板题的压力状态。所以这份旧卷子练的不只是知识还练心理素质和思维清晰度。1.3 这份B卷想筛出的能力模型从出题逻辑倒推2017年前端校招笔试的能力模型其实高度一致用大白话概括就是三件事语言基础牢不牢、浏览器和网络机制是真理解还是死记硬背、复杂逻辑能不能用手写代码表达。这三件事放在今天仍然是前端面试考察的主轴只是现在的面试形式上更花哨、深度上更卷了。笔试筛掉的通常不是不会做难题的人而是那些“知识点背得很熟一上手就露怯”的人。所以这张B卷的真正价值不在于你今天刷完能得多少分而在于帮你还原一个能力检验的场景。在投简历之前先通过它知道自己的web前端基础水平站在哪个位置后面的复习才更有针对性。2. 卷面考点分布2017年web前端笔试的几大板块与权重2.1 JavaScript基础考试中的重头戏业务里的基本功根据我当时观察到的多数校招前端卷JavaScript基础一块的题量通常占整张卷子的35%到45%在欢聚时代2017年B卷的语境里这个比例只会更高。原因很简单直播业务的前端——聊天、弹幕、礼物动画、排行榜刷新——全部在JavaScript上实时运行一个候选人要是连作用域、闭包、this指向都说不清楚很难想象他能直接参与这类业务开发。这块出题的角度我按出现频率排个序变量提升与作用域。考var、let、const的差异考函数声明与函数表达式的差别。这在读代码输出题里出现频率极高而且错的人极多。原因不是大家不会背概念而是面对嵌套代码脑内运行结果和真实运行结果时常对不上。this的四种指向。普通函数调用、对象方法调用、构造函数调用、箭头函数四类场景说它是2017年笔试题的万金油毫不夸张。闭包的机制与典型场景。最常见的就是循环中绑定事件循环结束后再点击输出i是多少。原型链与继承。原型链查找规则Object.create与new的区别instanceof原理。异步与事件循环。setTimeout、Promise混在一起要求写出正确的输出顺序。说一个当年很有代表性的现象很多同学把Promise语法背得很熟async/await也在框架项目里用过但一遇到“微任务和宏任务执行顺序”这种题输出结果照样错。问题出在他队事件循环的理解停留在“异步就是回调”的层面从来没有在脑子里跑过一遍任务队列的排队顺序。笔试最吃亏的就是这种“你以为你会”的题因为交卷时很笃定改卷时很惨烈。2.2 浏览器、DOM与网络进业务第二天就要用到的知识第二大盘是浏览器与网络算是前端综合基础。在2017年的卷子里它约占20%到30%。校招笔试为什么要考这些因为前端最终跑在浏览器里。不懂渲染机制的人做直播页可能搞不清为什么低端安卓机上弹幕滚动卡顿不懂HTTP缓存的人发布活动页时可能让用户一个月都看不到更新。这些属于“进业务第二天就要用”的知识。常见的考察点我列一下DOM事件流捕获、目标、冒泡三个阶段addEventListener第三个参数的作用常配合“事件委托”一起考。渲染机制重排和重绘的区别什么操作会引起重排批量更新DOM为什么能减少重排。HTTP缓存强缓存和协商缓存的区别Cache-Control、Expires、ETag、Last-Modified各管什么。同源政策与跨域JSONP、CORS原理各自适用场景。状态码304、404、500这些高频状态码加上XMLHttpRequest的readyState变化。你看这些点没有一个是偏题怪题全是实际开发中一天到晚都会遇到的东西。笔试考它们本质上是想确认你有没有做过真实页面而不只是在本地跑过hello world。我记得有一个流传很广的段子面试官问“你的项目有没有遇到过跨域问题”候选人回答“没有我用的是Chrome插件”。这类考生在笔试里通常也藏不住选择题一考JSONP的原理基本就露底了。2.3 HTML/CSS与算法逻辑被低估的两个板块第三个要提醒的是HTML/CSS和算法逻辑。很多同学的备考重心全在JavaScript上把这两块当成“到时候再说”这是很吃亏的。HTML/CSS考察相对轻量大概占10%到15%。常见的考法有盒模型差异、水平垂直居中方案、position的几种取值、margin塌陷、移动端适配的rem原理。这些题不难但是杂而且特容易考细节。比如问“块级格式化上下文BFC是什么有哪些触发方式”不系统复习的话回答很难全面。算法与逻辑占10%到20%。2017年前端校招笔试里的算法题难度上限谈不上高不会出现动态规划或者复杂图论更常见的是数组去重、字符串反转、简单排序、数组扁平化这类问题。但“简单”不等于“送分”因为要求手写代码考察的是能不能写出边界完备、可读性好的代码。比如数组去重至少要能写两三种方案并且说清每个方案的局限indexOf方案处理不了NaNSet方案对对象元素是引用比较双重循环方案性能不理想。这些细节才是拉开分数的地方。我把考点分布整理成一个表方便备考时对照自检考点板块估计占比典型考察方式失分重灾区JavaScript基础35%~45%选择题、读代码输出题作用域、this指向、任务队列浏览器与网络20%~30%选择题、简答题事件流、缓存字段HTML/CSS10%~15%选择题、改错题盒模型、布局方案算法与逻辑10%~20%手写编程题边界处理、代码风格3. 高频典型题复盘这些题目在当年的卷子里反复出现写这一节之前先把话说在前面我手上并没有欢聚时代2017年这份B卷的逐字原卷所以下面这些题目不是“原卷扫描版”而是对2017年前后多家公司web前端校招笔试高频题型的代表性重建考点和答题思路与当年卷子高度接近。这一点希望大家心里有数别拿去当“题库原题”使用要当“考点清单”使用。3.1 变量提升与闭包的组合拳一道读代码题的满分思路先看一道非常经典的输出题var x 10; function test() { console.log(x); var x 20; console.log(x); } test();只要在2017年前后参加过前端校招笔试的人对这道题的变体不会陌生。答案是第一次打印 undefined第二次打印 20。原因是函数作用域内的var声明存在提升var x被提升到test函数作用域顶部但var x 20中的赋值并不会提升。所以执行第一个console.log(x)时x在函数作用域内已经“存在”了只是还没有值于是输出undefined。它不会去访问全局的x10因为最近的作用域已经罩住了它。这是闭包、作用域链和提升三个知识点的一次合体考察。答题思路见到读代码题先在草稿纸上把“变量提升后的代码形态”重写一遍再逐步求解。特别是题目里出现function关键字时要区分函数声明和函数表达式这一个点区分度极高。我记得当年有同学在所有输出题上都按“函数声明会被提升”的规律去套结果在函数表达式题上接二连三栽跟头。3.2 事件循环输出顺序题微任务与宏任务怎么排队再来看异步顺序问题。当年笔试里的异步题最常见的一个模板是这样的console.log(1); setTimeout(function () { console.log(2); }, 0); Promise.resolve().then(function () { console.log(3); }); console.log(4);正确的输出顺序是1、4、3、2。这套逻辑到今天依然成立同步代码先执行当前宏任务这个script本身就是一个宏任务执行完之后清理所有已排队的微任务微任务清空后再取下一个宏任务。setTimeout的回调是下一个宏任务Promise.then的回调是微任务所以3先于2。很多人在这道题上翻车不是不知道微任务优先级高而是忘了同步代码最先按顺序执行这个前提导致把4放到了最后。还有一个常见的错误是把setTimeout的0毫秒理解成“立即执行”忘记了它只是把任务推进宏任务队列要等当前任务和微任务清空之后才轮到它。如果当年卷子里出现多个Promise嵌套或者Promise里再套setTimeout出错率会更高。答题时我建议在草稿上画两列一列是宏任务队列一列是微任务队列模拟浏览器执行一遍输出结果自然会浮现出来。手写答案的时候也要注意顺序一旦写错整个题就没分了所以草稿上先模拟确认后再誊写。3.3 原型链与this指向前端基础里的“劝退题”原型链相关题目当年的出场率很高样式通常是给出构造函数和继承关系让考生写出输出或判断instance的关系。有一个高频变体function Parent() {} function Child() {} Child.prototype new Parent(); var child new Child(); console.log(child instanceof Parent); console.log(child instanceof Child);两个输出都是true。原因在于instanceof查的是对象的原型链里能不能找到目标函数的prototype对象。Child.prototype被重新赋值为new Parent()这个new Parent()的原型链里既有Parent.prototype也保持了child到Child.prototype的链路所以child在两个方向上都能匹配。这道题的高价值突破点在于它侧面考察了constructor属性是否会因为原型替换而丢失。如果卷子加一道追问“child.constructor指向谁”答案大概率是Parent而不是Child因为Child.prototype被赋值成新对象后它自带的constructor被覆盖了。很多候选人在这一步失分。处理方案很简单替换原型之后手动补constructorChild.prototype.constructor Child;这个补充在当年笔试里是能体现源码细节掌握度的得分点。答题时如果只写instanceof的结果不算错但少了一个展示深度的机会。能在答案旁边简单说明constructor的变化改卷人一眼就能看出你理解到哪个层次。3.4 数组去重2017年web前端手写题里的钉子户不夸张地说数组去重是2017年web前端笔试手写题里的常客。低端考法是写一种方案中等考法是写多种方案并说明差异高端考法是写出一个能处理不同类型元素、性能可控的方案。第一种是兼容性最好的indexOf方案function unique(arr) { var result []; for (var i 0; i arr.length; i) { if (result.indexOf(arr[i]) -1) { result.push(arr[i]); } } return result; }这个方案能处理常规场景但有两个明显缺陷NaN无法被去重indexOf对NaN执行时内部处理会让NaN匹配不到所以NaN会被重复加入对象和类对象元素按引用比较不会认为是同一个。当年笔试能写出这个方案只能算及格。如果追加写出ES6方案分数会明显高一个档次function unique(arr) { return Array.from(new Set(arr)); }Set的去重基于SameValueZero算法对NaN的处理比indexOf正确但对对象来说仍然是引用比较。要是面试官想深挖还可能追问“原始值去重和对象去重场景分别怎么处理”那就需要延伸到使用WeakMap或者序列化方案。这道题几乎每一年都有人觉得“太简单”但它恰恰最能暴露出一个候选人手写代码的边界意识。笔试里遇到这种题别急着两行写完交差把边界情况、复杂度分析、备选方案写清楚比多写一道题更容易拿分。4. 纸笔考试时代的时间分配与手写代码技巧4.1 拿到卷子头三分钟别急着动笔线下笔试和线上笔试有个明显的差别拿到纸质卷子之后你有一个很短但完全由你自己支配的时间窗口这时候最忌讳的就是从第一题开始埋头猛做。稳一点的做法是花两三分钟把整张卷子翻一遍搞清楚四件事总题量是多少、选择题多少道、编程题是什么类型、最后一道压轴题难到什么程度。这个“翻卷”的动作本质上是在给大脑建立地图。做完之后你就清楚哪些题是送分题哪些题要先跳过编程题大概需要预留多少分钟。很多同学在考场上觉得时间不够不是题量真的太大而是对试卷结构没有整体感知在个别难题上耗到失去节奏。一个简单的