又到一年校招季,前端岗位的笔试总是让不少同学头疼。京东作为大厂里比较早开始校招笔试的一批公司,它的前端笔试题一直被当作练手风向标,尤其是2019年那一套题,到现在还在牛客网和各类面试题汇总里被反复翻出来。我当初准备校招时也做过这一套,后来带团队面试时也参考过类似题目,文章不会把题目逐字贴出来(网上已经有很多回忆版),而是想跟你聊聊这套题背后的东西:京东前端笔试到底在考什么、为什么这么考、以及你该怎么准备才能稳稳通过。
如果你是正在准备校招的应届生,或是想系统梳理前端基础的开发者,这篇文章值得花二十分钟读完。我会把京东2019校招前端笔试题的考点分布、答题思路和备考方法拆开讲清楚,也会把我在实际面试别人时看到的常见问题一并放进来。看完之后,你再去做网上流传的真题,思路会清晰很多。
1. 笔试到底考什么:京东前端校招的题型全貌
1.1 先从一道“送分题”说起:别在基础题上翻车
很多同学拿到京东前端笔试题的第一反应是“怎么还有这种题”?比如给你一段代码,问typeof null的输出是什么,或者问==和===的区别。这类题目看起来简单,但正确率往往没有想象中高,因为很多人在准备时只盯着框架和算法,把最基础的语法细节忽略了。
2019年这批题目里,基础题占比非常重。选择题部分大量考察了JavaScript的数据类型、作用域、闭包、原型链、事件循环、this指向这些内容,CSS部分则聚焦在盒模型、定位、flex布局、BFC这些高频考点上。HTML5的语义化标签、canvas与svg的区别也考了不少。
为什么大厂会出这些“简单题”?原因很简单:校招候选人没有实际项目经验可以深挖,笔试的首要目的是筛掉基础不扎实的人。前端这个岗位,框架可以入职后再学,但JavaScript和CSS的底层逻辑必须在入职前就过关。所以你在准备时,千万别觉得这些基础题“太Low”,恰恰是它们决定了你能不能进下一轮面试。
1.2 整卷结构:选择题、编程题、问答题的比例与应对思路
从题型结构来看,京东2019校招前端笔试题大致分为三个部分:客观题(单选多选)、简答题、编程题。客观题覆盖面广,考察的是知识面的广度,很多题你即使不会也能靠排除法蒙一蒙,所以关键是把确定会做的题做对,不留粗心失误。
简答题考察的是表达能力,比如“描述一下从输入URL到页面渲染的完整过程”“说说你对BFC的理解”“列举几种常见的跨域方案”。这类题没有标准答案,但踩分点很明确,你必须把关键术语写出来,步骤写完整。我批过不少这种卷子,最怕看到的是那种“一两句话就写完”的答案,哪怕核心点说对了,也拿不到高分。
编程题一般有两到三道,常见的是手写防抖节流、深拷贝、数组去重、Promise相关实现,偶尔还会有一道算法题。这里有个很关键的经验:编程题不要只写核心逻辑,要写完整函数声明,要考虑边界条件,最好把注释也写上。因为这不仅是考你会不会写,更是考你的编码习惯。
2. 核心考点逐个击破:这些知识点几乎年年必考
2.1 JavaScript:作用域、闭包、原型链与事件循环
JavaScript是前端笔试的绝对核心,京东的题里有一半以上都在围着它转。先说作用域,这块爱考的是var、let、const的区别,变量提升的机制,以及块级作用域的表现。很多同学能背出“let有暂存性死区”这句话,但一做题就错,原因是没有真正理解执行上下文和词法环境的关系。
闭包是另一个重头戏,常见的考法是给一段循环代码,问每个按钮点击后输出的值是多少。经典题目是for (var i = 0; i < 5; i++)里面创建五个定时器,问最终输出。正确解法用let或者立即执行函数包裹,原理是让每个闭包捕获独立的变量副本。这种题我建议大家不要死记答案,而是画一下作用域链的示意图,搞清楚每个函数引用的到底是哪个i。
原型链考的则是构造函数、实例、原型对象之间的关系,比如instanceof的原理、Object.create(null)和{}的区别、Function.__proto__和Function.prototype是不是同一个对象。这块知识点比较绕,建议找一张完整的原型链图,把Object、Function、Array这几个构造函数的__proto__和prototype关系理清楚。
事件循环考的则是宏任务和微任务的执行顺序,经典题目是综合了setTimeout、Promise、async/await的一道输出题。解题思路只有一个:先执行同步代码,遇到微任务(Promise.then、MutationObserver、queueMicrotask)放进微任务队列,遇到宏任务(setTimeout、setInterval、I/O)放进宏任务队列,微任务队列清空后再取一个宏任务执行,如此循环。
2.2 浏览器与网络:从输入URL到页面渲染的全过程
浏览器和网络这块,京东笔试很喜欢出一道“从输入URL到页面渲染”的简答题,看似简单,想拿满分却不容易。完整的回答应该是:DNS解析、建立TCP连接(三次握手)、发送HTTP请求、服务器响应并返回HTML、浏览器解析HTML构建DOM树、解析CSS构建CSSOM树、脚本执行、布局(Layout)、绘制(Paint)、合成(Composite)。
这道题的关键在于,你要把每个环节里的细节都说出来。比如DNS解析是逐级查询还是递归查询,浏览器有哪几层缓存(强缓存和协商缓存),TCP为什么要三次握手而不是两次,CSS是否会阻塞渲染,script标签的defer和async有什么区别。把这些问题串起来,答案才算完整。
跨域是一个必考点,因为它在项目中太常见了。常见的方案有JSONP、CORS、postMessage、document.domain、window.name、代理转发这几种。笔试和面试中让你“手写一个JSONP”,主要考动态创建script标签、回调函数挂在window上、服务端返回一段JS调用这个回调。CORS方案里要答出简单请求和预检请求的区别,以及Access-Control-Allow-Origin等响应头的含义。
2.3 框架与工程化:Vue和React的原理
2019年那会儿Vue和React已经非常流行了,京东的笔试题里框架部分占了不少分数。Vue的考点集中在响应式原理、虚拟DOM、diff算法、生命周期和组件通信这几个方面。你至少要知道Object.defineProperty的getter和setter是如何实现依赖收集和派发更新的,也要知道Vue3里为什么改用Proxy,它能代理数组和动态添加属性的特性解决了Vue2的哪些痛点。
React的考点则围绕JSX语法、组件生命周期、setState的同步异步问题、虚拟DOM和Fiber架构展开。学校招笔试阶段对Fiber不会挖得太深,但你要知道React16之后为什么引入Fiber,以及它如何通过时间切片实现可中断渲染。
还有一类很实际的题,是给一段Vue模板问它最终渲染成什么DOM,或者给一个父子组件传值的场景让你找出问题。这类题必须多写多练才能提高,光看文档是学不会的。工程化方面,Webpack的loader和plugin的区别、打包流程、Tree Shaking的原理、Babel的作用,这些也最好掌握。不用太深,但至少能说出“loader是对模块源码进行转换,而plugin是在打包生命周期里做更广泛的事情”。
3. 手写代码题实战:高频题目与答题套路
3.1 数组去重、防抖节流、深拷贝:看似简单但有坑
手写代码题里,数组去重、防抖节流、深拷贝这三件套出镜率极高,京东的笔试里也考了。先说数组去重,普通人第一时间想到Set,一行代码解决,但这只能算七十分。你要是能在答案里补充“NaN和对象怎么处理”“===和Object.is的区别”,那才能拿高分。比较好的写法是先判断数组里每个元素唯一的场景,再考虑性能,比如用Map做哈希表,这样时间复杂度是O(n)。
防抖和节流看起来是背代码,实际考的是对执行时机的理解。防抖是“停止触发后delay毫秒执行”,节流是“固定时间间隔内最多执行一次”。准备这类题时,我建议你不仅要知道怎么用,还要理解this的绑定问题和event对象的透传问题。网上很多版本的实现都忽略了event透传,在真实项目中会导致bug,你可以在代码里用apply把参数传进去,然后主动提一句“这里需要注意this和event”。
深拷贝是真正的区分题,能写对的人不多。初级写法是用JSON.parse(JSON.stringify(obj)),能应付大多数面试,但考笔试题时你要能说出它的缺陷:函数、undefined、Symbol值会被丢失,循环引用会报错,Date对象和RegExp对象会被转成普通字符串和空对象。进阶解法是用递归判断类型,遇到对象和数组就遍历复制,遇到函数/Date/RegExp/Map/Set要做对应的处理,同时用WeakMap解决循环引用。这段代码建议你手写至少三遍,直到不查资料也能完整默写出来。
3.2 手写Promise与发布订阅模式:进阶题的常客
很多同学看到“手写Promise”就头皮发麻,觉得这是大佬才需要掌握的东西。但实际上,京东2019年的笔试题里已经出现了和Promise相关的题目,而且难度其实没那么离谱。它一般不是让你实现完整的Promise/A+规范,而是考某个局部点,比如 “写一个简版的Promise,包含resolve、reject、then方法”,或者 “把一段回调嵌套改成Promise链式调用的写法”。
如果你只能背下来一段完整Promise的实现,那就很好。但更推荐你理解整体架构:构造函数存的state、value、callbacks三个状态,resolve和reject修改状态并触发回调,then返回一个新的Promise实现链式调用。理解了这三个核心点,不管题目怎么变形,你都能随机应变。
发布订阅模式在笔试里也经常出现,它会让你实现一个EventEmitter,包含on、emit、off、once四个方法。核心是内部维护一个事件名到回调数组的映射,on往里push回调,emit把回调数组取出来逐个执行,off把对应回调过滤掉,once是执行一次后就自动取消订阅。建议你准备面试前,把这段代码跟着写一遍,因为它本身就是很多框架内部机制的雏形。
3.3 算法题:从冒泡排序到动态规划
前端笔试的算法题通常不会像后端考得那么深,但基本的排序、查找、字符串处理和简单的递归/动态规划还是会出现的。京东这种量级的公司,笔试算法题一般处于LeetCode简单到中等难度之间,考的是你把算法思想应用到实际问题的能力。
排序是最基本的要求,至少快排、归并、冒泡、选择这几种要能随手写出来,还要知道它们的时间复杂度和稳定性。字符串相关的题也常考,比如判断回文串、反转字符串、找出最长不重复子串。这类题目说难不难,但容易出现边界条件错误,比如空字符串、全相同字符、长度为1的数组等。每次写完代码,建议你主动在心里跑一遍边界用例。
动态规划如果基础薄弱,可以先不深究,但至少要知道经典题目的套路,比如爬楼梯、斐波那契、背包问题。动态规划的通用解题步骤是:定义状态 -> 找状态转移方程 -> 确定初始值 -> 编码。看懂答案和自己能写出来是两回事,所以不管多简单的DP题,都建议你亲手在编辑器里跑一遍。
4. 真题思路还原:经典场景题怎么一步步推演
4.1 场景题一:页面卡顿排查与性能优化
京东笔试里有些题不是纯粹考知识点,而是给你一个具体场景让你分析。比如“页面加载很慢,怎么定位和优化”,这种题没有固定答案,但考察思路是否完整。我的建议是采用“分层排查法”,把自己想象成一个医生,从外到内逐层诊断。
第一层是网络层面,要想到用DevTools的Network面板看加载耗时的瓶颈在哪里。重点排查有没有体积过大的图片、有没有未压缩的JS/CSS文件、有没有太多请求需要串行加载,还要看有没有开启HTTP缓存。第二层是渲染层面,要关注是否有多余的重排和重绘,有没有在循环里频繁操作DOM,是否可以使用DocumentFragment批量更新DOM。第三层是JS执行层面,可以想到用Performance面板录制一段脚本,看主线程上哪个函数耗时最长。
答题的时候,建议按“发现问题 -> 定位原因 -> 给出优化方案”的结构来写。你给出的优化方案要有可落地性,不能说“优化性能”这种废话,要说具体手段:http缓存、CDN加速、图片懒加载、代码分割、Tree Shaking、requestAnimationFrame替代setInterval、虚拟滚动等。每写一个方案,最好跟一句“这样做能解决什么问题”,这样能体现你不是在背答案,而是真的理解性能优化的原理。
4.2 场景题二:跨域问题的完整解决方案
跨域在本地开发环境里几乎人人都会遇到,京东笔试里拿它出场景题一点也不意外。考法通常是“项目里前端跑在localhost:8080,后端跑在localhost:3000,请求被拦截了,怎么办”,或者 “你们项目中如何处理跨域”。
回答这种题,我会建议先解释清楚“什么是跨域、为什么会有这个限制”,这能体现你对浏览器的同源策略有基本认知。然后列举方案时,按“开发环境”和“生产环境”两个维度来组织答案。开发环境下最常用的是 Webpack DevServer 的 proxy 配置,vue-cli和create-react-app里都有现成的方案,生产环境则通常使用Nginx反向代理。
CORS方案要讲清楚前端的改动和后台的改动分别是什么。前端一般在axios里配置withCredentials: true,后台需要设置Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers这几个响应头。如果涉及带cookie的请求,还要特别说明Access-Control-Allow-Origin不能是*,必须指定具体域名。
4.3 场景题三:设计一个组件库的Button组件
有一部分笔试题非常贴近实际工作,比如让设计一个Button组件,要考虑哪些属性和事件。别小看这道题,它考的是你的组件设计能力和工程思维,而不是单纯的API记忆。
我会从需求分析开始写答案。Button组件的属性至少包括:type(默认/主要/成功/警告/危险)、size(大中小)、disabled、loading、icon、block(块级按钮)、circle(圆形按钮)。事件要支持click,但要注意disabled和loading状态下不能触发。然后是样式上要考虑的问题:按钮的视觉反馈、hover/active/disabled状态样式、不同type之间的颜色变量应该如何管理。再进一步,还要考虑主题定制、全局默认配置、按需引入这些工程化能力。
如果笔试时间充裕,你还可以补充一段组件代码示例,用Vue或React实现一个包含主要属性的Button。要点是:用$attrs或者...restProps把原生属性透传给button元素,这样使用者可以设置id、name、type等原生属性。能写出这个细节,说明你真的设计过组件库,而不仅仅是会写页面。
5. 备考路线与时间规划:从基础薄弱到笔试通过
5.1 三轮复习法:基础、进阶、冲刺
准备笔试最忌讳的是没有章法,今天刷几道题,明天看几篇面经,最后哪一块都没吃透。我自己的经验是三轮复习法,每一轮有明确的目标,时间分配大概是4:3:3。
第一轮是打基础,目标是把你见过的所有前端知识点串成一张网。建议时间两周左右,重点过JavaScript核心概念(数据类型、作用域、闭包、原型链、异步编程)、CSS布局(flex、grid、定位、BFC)和浏览器基础(渲染机制、缓存、跨域)。这轮不用刷很多题,每学一个知识点,就在笔记里用自己话写一遍,能写出来就算理解了。
第二轮是刷题,目标是熟悉笔试题型,掌握常见题目的答题套路。建议用一到两周,每天刷一套笔试题或50道选择题。遇到不会的题,不要直接看答案,先在脑子里思考可能的解法,再对照答案找自己的思维盲区。这轮你会发现自己有很多“以为自己会但一做就错”的知识点,正好补漏。
第三轮是冲刺,目标是模拟真实笔试环境,训练时间分配能力。建议考前一周,每天在限定时间内完成一套完整试卷,注意编程题必须在编辑器里亲手敲一遍,不能只写个大概。到了考场上你会发现,时间管理比知识储备更重要,很多人不是不会做,而是没时间做完。
5.2 刷题工具与资源推荐
工具选择上,我推荐LeetCode用于算法题,牛客网用于刷大厂历年笔试题,还有一个容易被忽视的工具是CodePen或本地编辑器——手写代码题一定要在真实环境里敲,很多人纸上写得好,一打开编辑器就各种报错。
教材方面,JavaScript部分我推荐《JavaScript高级程序设计(第4版)》,重点看第3、4、5、7、10、11章,这几章覆盖了笔试的大部分考点。CSS部分看《CSS世界》就够用了,这本书里的例子很贴近实际,不是堆砌语法。框架部分,Vue和React的官方文档就是最好的资料,但要学会自己总结常考点的笔记,不然看了就忘。
还有一个很实用的资源是各互联网大厂的历年笔试题汇总,网上的回忆版虽然不一定全,但考点分布很稳定,多刷几套你会发现出题人的偏好。刷题不要只刷一遍,我会把做错的题整理成一个错题本,每周复习一次,把反复错的题标记出来,集中攻克。
5.3 时间规划表实战参考
下面给一个可执行的四周复习时间规划表,按每周7天、每天3到4小时计算。这个表是我自己备考时用的,也推荐给过不少学弟学妹,实践下来效率很高。
| 周次 | 复习重点 | 具体安排 | 产出目标 |
|---|---|---|---|
| 第一周 | JavaScript核心 | 每天2小时看书+笔记,1小时做数据类型/作用域/闭包选择填空题 | 整理出JS核心知识笔记30条以上 |
| 第二周 | CSS布局与浏览器 | 每天1小时CSS实战布局,1小时浏览器原理,1小时刷题 | 能默写flex的九大属性和BFC的触发条件 |
| 第三周 | 框架与手写题 | 每天手写2道代码题,1小时Vue/React原理复习,1小时刷题 | 手写防抖/节流/深拷贝/EventEmitter各三遍以上 |
| 第四周 | 综合模拟 | 每天一套完整笔试题,错题整理+回顾 | 连续三套题达到70%以上正确率 |
这个规划的核心思路是:前两周把知识点吃透,第三周开始输出,第四周全真模拟。如果你的基础很好,可以跳过第一周的一部分,但至少要保持每天刷题的手感。笔试是个细水长流的活,突击一两天效果很差。
6. 考场上的实战技巧与常见坑点
6.1 阅卷人的视角:踩分点在哪里
作为带过新人的前端工程师,我看过不少笔试答卷,可以告诉你阅卷时的真实感受。选择题是机器判分,没什么技巧,但简答题和编程题是人工看的,这时候你的答题方式直接影响得分。
简答题的踩分点就是关键术语。比如“描述一下flex布局”,你回答“容器上设置display:flex,项目沿着主轴排列,可以通过justify-content控制主轴方向的对齐方式,align-items控制交叉轴对齐方式”,比写一大段文字但没提主轴交叉轴得分高得多。我的建议是,简答题先写一句话的直接答案,再补充细节。阅卷人每天看几百份卷子,不会逐字读你的长篇大论,你要让他在十秒内看到踩分点。
编程题也有踩分点,而且比简答题更具体。函数名是否规范、是否有参数校验、是否考虑边界条件、是否写了注释、代码风格是否整洁,这些都是潜在得分项。有些同学核心逻辑写对了,但函数整体缺个return,导致整个答案功亏一篑。每次写完代码,养成习惯问自己三个问题:函数有没有返回值?空值怎么处理?异常情况怎么兜底?
6.2 常见错误:读题不仔细、边界条件遗漏
我在审阅笔试答案时发现,很多同学丢分不是因为不会,而是因为粗心。最典型的错误是不看题目要求,比如题目明说“不能使用ES6语法”,你偏偏用了箭头函数和const;题目要求“用递归实现”,你写了个循环。这不是技术问题,是态度问题,非常可惜。
边界条件遗漏是编程题丢分的第二大头。一个经典的例子是手写深拷贝时没处理循环引用,导致递归栈溢出;数组去重时没考虑NaN;实现addEvent时没考虑节点不存在的情况。准备笔试时,我会要求自己在写完每一段代码后,立刻在脑子里列出至少三个测试用例:正常输入、空输入、边界输入。这招在真实考场上非常管用,能帮你多拿不少分。
还有一个很容易被忽略的问题是,题目要求“用 ```javascript 代码块”还是“直接写在答题区”,不同的要求决定了你的代码排版方式。如果题目明确要求关键注释,那你一定要写注释,而且写中文注释就行,不用刻意写英文。代码可读性在人工阅卷中真的能影响分数。
6.3 心态与时间分配:笔试不只是考知识
最后聊聊考场上和时间赛跑这件事。京东校招笔试题量大,很多同学拿到卷子就开始从头做题,结果最后一道高分编程题没时间写,只能眼睁睁看着。我的策略是:先花一到两分钟把整张卷子浏览一遍,看清楚题量和难度分布,然后按“先易后难、先高性价比后低性价比”的顺序答题。
一般的选择题部分控制在20到30分钟内完成,简答题每题控制在8到10分钟,编程题留足40分钟以上。如果某道题超过五分钟没有思路,果断跳过,不要在一道题上死磕。笔试的时间分配本质上是个项目管理问题,目标不是每道题都完美,而是总分最大化。
心态上建议大家放平。笔试和面试不同,它没有“面试官现场给反馈”的过程,你只能通过卷面展现能力。遇到完全没见过的题,不要慌,先写一点和题目相关的知识,再试着推导。实在不会的题,宁可留白也不要乱答,因为乱答会给阅卷人留下“基础不牢”的印象,而留白顶多是“这道题不会”。
就我个人经验来说,校招笔试是一个可以通过系统准备大幅提高分数的环节。我不建议把时间花在押题上,因为大厂出题官永远比你想象中灵活。真正值得做的,是把基础打扎实、把手写代码练到条件反射、把答题节奏练出肌肉记忆。做到这三点,不管面对哪一年的京东笔试题,你都会从容很多。