穿越15年的前端笔试卷:2011年的题目暴露了哪些永恒考点
如果今天突然让你去考一套“人人网2011前端工程师笔试卷”你第一反应大概率是“这有什么可考的”甚至会觉得题目透着一种考古气息。但真正有意思的是这套卷子上那些看起来“过时”的题目恰好是前端行业从“会写页面的人”走向“软件工程师”这条路上的一个关键横截面。我当时看到这份卷子的第一感受不是怀旧而是“原来2011年的时候面试官就已经在这么考察前端了”。这份卷子能回答几个很有意思的问题为什么2011年的前端笔试要考CSS hack为什么没有一点框架题如果把你现在的前端能力“穿越”回2011年你哪些题能妥妥答对哪些题会当场翻车这些问题拆开来看其实比单纯刷一遍“2026最新面试题”要有价值得多。因为技术会被淘汰但技术背后的设计思路和问题意识不会。我尽量把这份卷子背后的行业环境、每类题目的考察意图和当年的标准答案都还原出来也会顺手聊聊哪些知识点放到今天依然是硬通货。1. 那份卷子的时代底色2011年前端到底在干什么要读懂一份笔试卷先得知道出题人活在什么样的技术环境里。2011年的前端是一个很微妙的节点。一方面jQuery已经统治了绝大多数网站的交互层写动画、发Ajax、绑定事件都可以用几行简单的链式调用搞定另一方面整个行业还没有“工程化”这个概念没有webpack、没有npm装依赖的习惯很多项目直接在服务器上改文件前端代码的模块化基本靠“命名空间约定”和“注释分隔线”。1.1 一个前端岗位的日常工作流当时的真实工作流大概是这样的设计师用Photoshop切好图前端拿到PSD后开始写HTML和CSS然后手动把页面切成一个个静态模板再把模板交给后端去嵌数据。交互部分靠jQuery搞定遇到浏览器不兼容就加条件注释或者写hack。人人网这种量级的SNS页面上有大量的动态内容、消息提醒、好友动态、评论回复这些交互说白了都是靠JS在浏览器里硬撑出来的所以前端岗位的实际压力非常大。在这个背景下笔试题目不可能脱离实际去考抽象理论。面试官关心的是你能不能在一个充满兼容性陷阱和性能压力的真实环境里把页面又快又稳地做出来。1.2 笔试出题人真正想筛选的能力我在前公司带团队时也出过笔试题深知出题人的心态。2011年这份卷子的出题人想筛掉的不是“不会React的”而是“连JavaScript语言本身的坑都搞不明白的人”。因为那个年代没有构建工具帮你包一层兼容没有框架帮你屏蔽浏览器差异写出来的代码会直接跑在用户的IE8里出了问题就是线上事故。出题人真正想筛选的能力可以概括成三类独立还原页面的能力HTML语义、CSS布局、盒模型、浮动清理这是前端的地基。写出不坑队友的JavaScript的能力变量作用域、闭包、this指向、事件处理这些决定了你写的代码会不会在三个月后变成没人敢动的屎山。让页面真正跑得快的能力对HTTP请求、缓存、DOM操作成本有没有概念决定了你上线后服务器扛不扛得住、用户等不等得起。这三类能力基本对应了卷面上那几大块题目的来源。所以这份卷子绝不是一个孤立存在的考题列表它是2011年前端岗位在真实业务中的镜像——考什么就说明这个岗位最需要什么。2. 笔试卷全景拆解从题型分布看2011年的技能权重说明一下我手里没有当年原始试卷的完整扫描件下面这份题型结构是综合当年参加考试的同行回忆和同时期大厂前端笔试题库做的合理重建。虽然具体题目可能有出入但考察的模块分布和命题逻辑基本是能对上号的。考察模块典型题型占比重建值命题意图JavaScript基础读代码写输出、手写函数约35%语言底层掌握程度HTML/CSS盒模型、浮动、定位、语义化约25%页面还原能力浏览器兼容问答、写出hack写法约15%真实项目踩坑经验性能优化简答、方案设计约10%上线前后的链路意识正则/算法基础手写正则、数组去重、排序约10%逻辑基本功开放性/经验题介绍项目经历、讲踩过的坑约5%真实水平与学习能力2.1 JavaScript占比一枝独秀为什么JS几乎占了半壁江山因为2011年的HTML/CSS虽然有兼容性坑但基本是“写出来就知道长什么样”的东西而JavaScript是唯一一个会让页面行为产生不确定性的变量。人人网这种交互密集型产品新消息提醒、好友动态的异步加载、评论区的展开收起全部依赖JS。面试官特别怕招进来一个只会用jQuery写特效、但一遇到作用域和闭包就懵的人。所以卷面上出现大量的“读代码写输出”题本质上是在模拟线上代码出bug时的排查场景给一段看起来人畜无害的代码问你输出什么答错了就说明你根本没理解变量是怎么存储和查找的。这种题直到今天依然是前端面试的主流只是代码例子从var换成了let和const。2.2 为什么没有框架题和构建题如果你穿越到2011年问面试官“你们考不考React生命周期”对方大概率会反问你React是什么。那个年代前端框架的形态还很原始Backbone.js刚流行起来AngularJS还在1.x早期更不用说Vue和React了。没有统一的框架生态意味着笔试不能考某个具体框架的API一旦考了就变成比谁背得多而不是比谁基本功扎实。同样构建工具也谈不上。当时压缩JS用的还是YUI Compiler或者Google Closure Compiler很少有人把它当成笔试考点。这也是为什么现在很多人看老卷子会觉得“这考的也太底层了”——因为那个年代的开发者确实没有框架和构建工具可以依赖所有问题都必须回到浏览器和语言本身去解决。2.3 开放性题目的隐藏价值卷子最后通常还有一些开放性题目比如“描述一下你做过的最复杂的JS交互”“如果一个页面滚动很卡你会怎么排查”。这类题没有标准答案反而最能拉开差距。我当年参加面试时遇到过一个类似的问题我当时说的是项目中遇到的一个同步请求导致页面卡死的问题以及我后来怎么改成异步并加loading态的。面试官听完就点头因为他要的不是答案本身而是你有没有真实解决问题的经历和排查思路。这一点放到今天依然成立。在候选人技术栈趋同的情况下开放性题目的回答质量往往决定了最终是否能拿到offer。3. 逐题拆解那些经典题目的考察意图与今天的答案这部分是全文的干货核心。我会挑几类出现频率最高、最有代表性的题目还原当年的考察角度并给出放到现在依然正确的解题思路。你会发现很多题的内部逻辑十几年来几乎没变变的只是表面上的API和语法。3.1 变量提升与闭包一道题串起JS最难的两块当年必考的一道题长这样var a []; for (var i 0; i 5; i) { a[i] function() { console.log(i); }; } a[3]();问你输出什么。答案是5不是3。为什么因为var没有块级作用域整个循环里的i是同一个变量五个匿名函数构成了闭包它们捕获的是变量i所在的那个环境记录而不是创建函数那一刻i的“快照”。循环结束后i已经变成了5所以不管调用a[0]还是a[3]打印出来的都是5。当年标准的修复方式是立即执行函数IIFE把每次循环的i作为参数传进一个新的函数作用域里for (var i 0; i 5; i) { a[i] (function(n) { return function() { console.log(n); }; })(i); } a[3](); // 3放到今天这个问题的修复会简单很多直接把var换成let就可以了因为let会为每一轮循环创建独立的块级绑定。但理解了“闭包捕获的是引用而不是值”这个底层机制你才能明白let到底做了什么而不只是“反正换了let就好了”。这道题还常会配一个变量提升的送分题console.log(typeof a); // ? var a 1;输出undefined而不是报错或抛出ReferenceError。原因是var声明会被提升到作用域顶部赋值留在原地。所以代码实际执行顺序相当于先声明a值为undefined再打印再赋值。这就是“声明提升赋值不提升”。这类题为什么经典因为它考察的是你对JavaScript执行上下文的理解。一个连变量提升都搞不清楚的人写出来的代码很可能出现“我以为a已经有值了”的bug。今天面试前端闭包和作用域依然是必考内容而且考察方式更刁钻了比如让你结合事件循环、微任务、Promise分析一段异步代码的输出顺序本质上考的还是同一套执行模型。3.2 this指向的四条规则别背结论去推演调用点this指向问题也是2011年前端笔试的钉子户。当年最经典的题目就是“读代码写输出”var name window; var obj { name: obj, show: function() { console.log(this.name); } }; var fn obj.show; obj.show(); // ? fn(); // ? setTimeout(obj.show, 100); // ?运行结果分别是obj、window、window。解释起来就是this的指向完全由“调用点”决定而不是由“定义位置”决定。obj.show()的调用点是obj对象所以this指向objfn()是裸调用调用点是全局所以this指向全局对象setTimeout(obj.show, 100)本质上是把obj.show这个函数当作回调整体调用调用点是定时器不是obj所以this依然指向window。关于this指向我一直觉得背结论不如建立一套推导框架。总结下来就四条规则默认绑定裸函数调用this指向全局对象严格模式下指向undefined。隐式绑定obj.fn()这种形式this指向点号前面的对象。显式绑定call、apply、bind可以强制指定this。new绑定new一个函数时this指向被构造出来的新对象。四条规则的优先级从低到高是默认绑定 隐式绑定 显式绑定 new绑定。当年很多答题者能背下每条规则但一遇到组合场景就懵。比如“new一个已经被bind过的函数this指向什么”——答案是new绑定优先this指向新对象而不是被bind绑定的对象。这种组合考察直到今天都很有杀伤力。3.3 事件冒泡与事件委托从“绑定太多”到“只绑一个”事件相关题目在2011年卷子里几乎必考因为那个时候页面交互非常重事件处理写得好不好直接影响性能和代码可维护性。核心概念是事件冒泡一个元素触发事件后事件会从目标元素开始逐级向上传播到document。利用这个机制可以把本来要绑定在多个子元素上的事件统一绑定到父元素上通过事件对象里的target来判断真正触发的是哪个子元素这就是事件委托。当年的经典题是“页面上有一个ul里面有100个li点击li要弹出对应的序号你怎么实现”。新手写法是循环给每个li绑定click每个函数再捕获一个循环变量稍微不注意就会踩到上一节说的闭包陷阱。正解是用事件委托document.getElementById(list).addEventListener(click, function(e) { var target e.target || window.event.srcElement; if (target.tagName LI) { alert(target.textContent); } });这道题在2011年有两个加分答法。第一个是讲清楚为什么要用事件委托一方面100个li挂100个事件监听器内存开销大另一方面如果是动态插入的li每次插入后还得重新绑定事件事件委托天然规避了这个问题。第二个加分答法是提到IE的差异标准浏览器用addEventListenerIE8及以下用attachEvent而且attachEvent有四个坑——事件名要加“on”前缀、this指向window而不是当前元素、事件对象不能直接在回调参数里拿而是要访问window.event、绑定多个事件的执行顺序是反的。放到今天事件委托依然好用尤其在长列表、表格、虚拟滚动的场景里React 18的合成事件系统底层就是基于事件委托实现的核心思路没变。理解了2011年的这道题你会更容易看懂React合成事件为什么要挂在根容器上。3.4 盒模型与浮动清除CSS笔试永恒的主角CSS部分的题目不会太花哨但每一道都在考你“页面为什么长成这样”。2011年最喜欢考的是盒模型差异标准盒模型里width只包含contentIE的怪异盒模型里width包含content、padding和border。这道题今天看起来像是历史考古但碰上如果你写CSS没有统一设置box-sizing照样会量出偏差。当年最常用的解决方法是靠doctype声明把浏览器拉回标准模式然后针对IE6/7的情况写hack。但如果你在2026年做前端直接统一设置* { box-sizing: border-box; }反而能省掉一堆padding撑开宽度的算术题。这个思维转变本身就是“从浏览器差异里走出来用规范消灭差异”的过程。浮动清除是另一道必考。为什么要清除浮动因为float元素脱离了文档流父容器计算高度时会把它们当作不存在导致父容器高度塌陷。当年最标准的通用方案是clearfix代码大概是这个样子.clearfix:after { content: ; display: block; height: 0; clear: both; visibility: hidden; } .clearfix { zoom: 1; /* IE6/7触发hasLayout */ }这段代码为什么这么写原理是在浮动元素的父容器末尾用::after生成一个不可见的块级元素并给它设置clear: both强制让父容器的高度把浮动元素包裹进来。zoom: 1则是当年给IE6/7触发hasLayout的hack因为IE6/7对::after支持不完整。今天我们用flex和grid布局已经不怎么需要清除浮动了。但如果你去维护老项目或者看一些还在运行的旧系统这套clearfix依然是救命稻草。更重要的是理解“文档流、定位、浮动”这三个概念之间的相互关系对理解现代布局里的BFC块格式化上下文非常有帮助而BFC直到今天依然是面试高频概念。3.5 正则表达式看起来很唬人的“送分题”正则题在2011年的前端笔试里常以“请写出一个匹配手机号码的正则”或者“请把字符串首尾空格去掉”的形式出现。今天看来简单当时也是大量人在这上面栽跟头。手机号的典型写法是var phone /^1[3458]\d{9}$/;这个正则在当时没问题因为11位手机号以13、15、18开头为主流后面跟着9位数字。但今天号段已经扩展到17、19等更稳妥的写法是var phone /^1[3-9]\d{9}$/;这算是一个小细节却能看出一个人是不是停留在“背题”层面。真正的工程师会意识到号段是动态变化的外部约束正则写成“当前已知号段”还是“尽可能匹配未来合理号段”体现的是设计思维。去掉字符串首尾空格当年标准答案要兼容IE8及以下因为ES5里的trim()在IE8及以下不支持var str hello world ; str str.replace(/^\s|\s$/g, );如果要顺手展示一下对正则的理解可以提到贪婪匹配和懒惰匹配的区别\s默认是贪婪的会尽可能多地匹配空白字符如果要换成懒惰匹配可以写成\s?。对于这道题用贪婪匹配即可反而更高效。正则题在当年之所以被归为“送分题”是因为它们不考算法只考你有没有见过真实需求。但现在前端面试里正则考得少了因为很多字符串处理都可以靠split、filter、map等数组方法组合搞定。不过正则本身依然是前端处理用户输入、校验表单、格式化文本的核心工具无论什么时候都值得认真学一遍。4. 浏览器兼容2011年笔试的灵魂考题如果说JS和CSS题目是笔试的地基那浏览器兼容就是这套卷子的灵魂。2011年这个时间点很特殊IE6还在苟延残喘IE7/8是主流IE9刚刚发布Chrome开始快速抢占市场Firefox还有一席之地。人人都知道标准是对的但现实里用户就是用IE8打开你的页面你能怎么办笔试里的兼容性题目就是在考察你“面对混乱现实时能不能给出可落地的方案”。4.1 IE6/7/8的经典坑现在看就是一部血泪史IE6/7/8的坑多到能写一本书笔试通常只会挑最有代表性的几个来考。我按出现频率整理了一个表格这些都是当年前端人的“肌肉记忆”问题表现原因双倍margin浮动元素设置了margin-left后实际距离变成两倍IE6在浮动元素上重复计算margin3px文本偏移浮动元素旁边有文本时文本与元素之间多出3px缝隙IE6/7的文本布局计算缺陷不支持min-height给容器设置min-height后IE6里会当成height使用IE6把height设计成min-height的效果opacity不生效使用CSS opacity没有任何效果IE6/7不支持标准opacity必须用filter滤镜PNG半透明无法显示背景PNG图片的边缘变成黑色/灰色块IE6不支持24位PNG的alpha通道position: fixed失效fixed定位元素会跟着页面滚动IE6不支持fixed只能靠absolute定时器模拟双倍margin这道题当年特别典型解法也很有代表性只要给浮动元素加上display: inlineIE6就会把它当inline元素处理从而不再重复计算margin。这个解法看起来毫无道理但它的原理是“IE6的hasLayout机制下inline元素不会触发双倍margin”。后来我们在H5跨端开发时遇到各种奇奇怪怪的bug很多也只能靠经验性的workaround本质上和当年的hack一样——先在真实环境里复现再去查它对应的布局机制。4.2 CSS hack背后的原理浏览器把不认识的东西当什么处理浏览器兼容题里最让新手头皮发麻的是写CSS hack。当年有一道非常经典的题“请分别写出针对IE6、IE7、标准浏览器的任意CSS hack”。参考答案可以这样组织.box { color: red; /* 标准浏览器 */ *color: blue; /* IE7 */ _color: green; /* IE6 */ }为什么这个写法能生效因为CSS引擎遇到不认识的属性名会直接跳过而不是报错。标准浏览器不认识*color和_color于是跳过IE7解析器对星号前缀比较宽容会当作有效属性使用IE6则连下划线前缀也认识。于是同一行CSS里不同浏览器各取所需实现了差异化显示。现在的浏览器已经完全不需要这些hack了但“优雅降级”和“渐进增强”这两个设计思想其实都是从这些hack里沉淀出来的。今天做跨端适配时我们写supports (display: grid)来判断浏览器是否支持grid布局本质上也还是“识别能力边界针对不同环境给不同方案”的思路。4.3 条件注释唯一不那么难看的上古方案除了CSS hack2011年还有一个看起来很优雅的兼容方案叫条件注释。它的写法是这样的!--[if IE 6] link relstylesheet hrefie6.css ![endif]--这段HTML在IE6里会被当成指令加载ie6.css在标准浏览器和其他IE版本里则被当作普通的HTML注释直接忽略。这样可以在不污染主样式表的前提下单独为IE6写一套兜底样式。条件注释后来在IE10里被彻底移除了但它当时的意义在于体现了一种可维护的兼容思路把“差异”从代码逻辑中隔离出来而不是把hack散落在各个地方。今天我们在工程化项目里用postcss、autoprefixer自动添加浏览器前缀本质上是用构建工具来处理这种差异思路完全一致。所以从这份卷子看下来2011年的兼容性题在表面上已经过时但它背后的“面向现实环境编程”的思维方式是永远不过时的。5. 性能优化题的答案逻辑从雅虎军规到“能省就省”性能优化在2011年笔试卷里占比不算特别高但一旦出现往往就是大分值的主观题。当年最典型的问法是“一个页面加载很慢你会从哪些方面入手优化”这个问题没有标准答案考察的是你有没有一套完整的优化链路意识。我后来带团队时也喜欢问类似的问题因为能答出层次感的人通常对线上环境是真的有感觉的。5.1 减少HTTP请求雪碧图的兴与衰当时面试官最想听到的第一条一定是“减少HTTP请求”因为HTTP/1.1时代浏览器对同一域名的并发连接数非常有限基本上是6个左右每个请求还要经历DNS解析、TCP建连、发送请求、响应下载等完整流程。页面上的小图标如果是一个个图片文件光握手的时间就把性能拖垮了。所以当年的标准方案是CSS雪碧图CSS Sprite把所有小图标合并成一张大图通过background-position定位来显示对应区域。做一个雪碧图并不只是把图拼起来那么简单你得保证每个图标之间留足够的间距避免定位时把旁边图标露出来还得生成一张精确的坐标表。到了HTTP/2时代多路复用允许一个连接同时传输多个请求雪碧图的收益变小了反而暴露出“改一个图标要重新下载整张大图”的尴尬。现在前端更倾向于用SVG图标、图标字体或者让构建工具自动把散碎的小图转成base64内联到CSS里。但“减少HTTP请求”这个底层指标到今天依然是性能优化的第一考虑项只是实现方式变了。5.2 缓存与压缩让浏览器少干活第二个高频答法是“利用缓存”。当时的标准操作是静态资源加长Cache-Control过期时间文件名里带版本号这样内容变了就换文件名避免浏览器使用旧缓存。同时开启gzip压缩让HTML、CSS、JS在传输前被压缩能省掉70%左右的体积。还有一个加分项是讲CDN把静态资源分发到离用户近的节点减少网络延迟。今天做性能优化很多人一上来就讲React.lazy、图片懒加载、Web Worker、PWA反而忽略了HTTP缓存和压缩这两个基础。其实对一个真实页面来说缓存策略正确是可以直接让二次加载速度提升一个数量级的。这也是为什么老卷子上这些看似基础的内容放到今天依然是面试官考察候选人“有没有性能意识”的试金石。5.3 操作DOM为什么贵一次重排背后的几何计算2011年的卷子里还有一类题考察“为什么不能在循环里频繁操作DOM”。知识点是浏览器渲染机制DOM树和样式合并后要计算布局reflow也叫重排然后才绘制repaint。每一次对DOM结构、尺寸、位置的改变都可能触发一次整棵子树甚至整个页面的重排这是非常昂贵的操作。当年标准答案有两个层次。第一个层次是“合并操作”用DocumentFragment在内存里先构建节点再一次插入真实DOM把多次重排变成一次。代码长这样var frag document.createDocumentFragment(); for (var i 0; i 1000; i) { var li document.createElement(li); li.textContent i; frag.appendChild(li); } document.getElementById(list).appendChild(frag);第二个层次是“虚拟DOM”的雏形思想先在内存里算出最终结果再去操作真实DOM。2011年还没有React但这道题里隐含的思路和后来React引入虚拟DOM、Diff算法要解决的问题是同构的。所以当我后来看React源码时会格外亲切因为虚拟DOM的核心价值之一就是减少真实DOM的布局和绘制开销。6. 把2011年的卷子放到2026年哪些题还配得上“必考”看完整套卷子的内容你可能会有一个感觉很多题目如果原封不动拿到2026年的前端面试里确实显得过时了但如果你把每一道题背后的原理拆出来会发现它们穿越了十几年依然有效。这让我忍不住想做一场思想实验如果把不同时代的题目互换会怎样6.1 岗位定位之变从切图工到软件工程师2011年前端岗位在很多人眼里还属于“会写页面的人”是设计师的延伸、后端的附庸。笔试中大量考察CSS hack、浏览器兼容是因为当时前端要花大量精力去伺候各种不听话的浏览器环境。到了2026年前端已经是一个完整的软件工程领域模块化、组件化、构建工具链、测试体系、CI/CD、Node.js服务端渲染、桌面与移动跨端开发……面试题也随之转向工程化、性能分析、架构设计、TypeScript类型系统、Node/Bun运行时等话题。前端不再是“写页面”而是“在浏览器和类浏览器环境里构建复杂应用”。但注意这个变化并没有让底层知识失效而是把它们封装进了更深的技术栈里。你用flex替代了清除浮动但盒模型没有消失你用Vue/React组件替代了大量手写事件绑定但事件机制依然是框架的底层依赖你用Set一行代码去重但知道哈希冲突原理永远是一项底层优势。6.2 底层能力没有变那些穿越十年依然有效的知识点我列举几个我认为“放之四海而皆准”的底层能力这些是我在工作多年后回头看发现老卷子真正值钱的地方对JavaScript执行模型的理解。作用域链、闭包、this、事件循环、微任务——这些东西十几年没有变而且未来大概率也不会变。对浏览器渲染流程的敏感。无论是2011年的DocumentFragment还是2026年的requestAnimationFrame 虚拟滚动你都得知道哪些操作会导致重排、哪些会触发重绘。对网络协议与资源的敬畏。HTTP缓存、压缩、并发连接数限制、CDN、资源加载顺序——这些决定了一个页面在真实网络里的表现而不是本地开发环境的表现。排查问题的方法论。先复现、再定位、然后最小化验证、最后修复回归。这个流程在老卷子里通过兼容性题和开放性题来考察今天则体现在对线上报错、性能瓶颈的排查里。6.3 一场思想实验把今天的面试题丢回2011年如果现在把一套2026年的前端面试题丢回2011年的人人网会出现什么场面面试官看到“请手写Promise.all”第一反应是“Promise是什么”——2015年ES6正式发布之前Promise还是一个社区概念2011年绝大多数前端根本没用过。你给2011年的面试官解释React.useEffect他可能会追问“你用函数组件里的闭包存状态那每次渲染都是独立的闭包状态到底是存在哪里的”这个追问本身其实很有价值因为它会逼你把“组件状态”和“闭包作用域”的关系讲清楚。反过来如果把2011年的卷子拿到今天CSS hack和条件注释大概率会被面试官视为“陈旧知识”但那双倍margin的底层布局逻辑、opacity的兼容替代方案、事件委托在动态列表里的应用放到如今的组件框架、跨端H5适配场景里依然能聊出很多真东西。所以我一直觉得别急着嘲笑老题目。技术确实在变但很多时候变的只是API壳子内核还是那一套。6.4 我个人在实际操作中的体会最后说一点我自己的真实工作感受。这几年我面试前端候选人时习惯拿一套混合题来考察既有“new Set去重”这种现代便捷工具题也会追问“如果不允许用Set你会怎么实现”甚至会直接给人一段很像2011年风格的代码问输出结果。为什么会这么做因为我发现能准确解释闭包和this指向的候选人和背熟各种框架API的候选人在进入实际项目后往往走向完全不同——前者遇到没见过的问题会自己推导后者遇到框架解决不了的问题就卡住。如果你现在想拿这份2011年的老卷子当作复习资料我的建议是不要只背答案而是把每一道题对应到“它为什么会被考”这个问题上。比如看到CSS hack就去查一下IE6的解析机制看到DocumentFragment就去了解一下浏览器渲染管线。把这些底层机制搞明白之后你会发现不需要再背任何题库——因为不管题目包装成什么样你都能一眼看穿它真正想考的那个点是什么。这大概就是老卷子留给我们最大的财富它不是考纲而是一张“前端底层知识地图”。