尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

翻出2011年阿里前端笔试题:哪些基础至今仍是面试核心

翻出2011年阿里前端笔试题:哪些基础至今仍是面试核心 1. 先聊两句为什么一份十多年前的卷子还值得翻出来最近整理旧电脑硬盘翻出一份2011年前后的阿里巴巴前端工程师笔试卷。说实话刚看到的时候自己也愣了一下当年为了准备这份卷子熬了好几个晚上现在再看很多题甚至有点“古董”的味道了——里面大量题目在问IE6怎么处理、jQuery的链式调用原理、怎么封装一个兼容多浏览器的事件绑定函数。但仔细读了一圈之后我反而觉得这份卷子值得所有现在做前端的人认真看一遍尤其是准备面试的初中级工程师。原因很简单它像一张技术快照把2011年前端这个岗位的核心能力模型拍得清清楚楚。你要知道那一年jQuery如日中天Backbone算是“新潮”框架ES5才刚刚普及ES6还在草案里躺著Chrome的V8引擎刚让前端性能这件事进入大众视野。能在那种环境下考察的内容几乎全都是前端领域最本质、最不容易过时的部分JavaScript语言功底、DOM操作与浏览器兼容、网络与性能优化思维、前端工程化意识的萌芽。说白了2011年的试题没有现在那么多花哨的场景题真正意义上的“三数之和”变体都很少它考的是「你到底懂不懂这门语言」以及「你能不能在一个混乱的浏览器环境里写出靠谱的代码」。这篇文章我打算做三件事先把当年的笔试题按类型拆开逐类讲清楚每一题的考察意图和当时的主流解法然后我会把同一类问题和2026年今天前端面试做对比让你看清技术演进背后的逻辑最后聊一点我对“经典基础题”的个人看法。目标是让正在准备面试的人能从历史题里挖出真正有用的东西而不是把它当成考古学。2. 2011年前端笔试题的类型拆解与考察意图2.1 2011年的前端生态到底长什么样先说背景。2011年的前端圈和现在完全是两个物种浏览器层面IE6虽然已经步入晚年但市场份额仍然高得吓人IE7、IE8是标配IE9刚出来不久Firefox和Chrome正在攻城略地“标准兼容”这四个字是每个前端头顶上的紧箍咒框架层面jQuery是绝对统治者Prototype、MooTools还有一定用户基础YUI在阿里内部也有不少应用Backbone算是“高端玩家”的选择Angular还在地底下酝酿React更是三年后才出生。构建工具Grunt都还没火起来webpack连影子都没有大部分项目还是直接在HTML里通过script标签引库。模块化靠的是namespace加IIFE手工模拟CSS预处理器的代表是Sass和LESS但普及程度远不如今天。性能优化是“雅虎军规”的天下大家会讨论合并几个脚本、雪碧图怎么画、CSS放头部JS放底部但还没有系统的性能监控体系。在这个背景下阿里的笔试考察逻辑就很清晰了我不要你简历上写了多少花哨项目我要看你是否真的理解浏览器、理解JavaScript、理解网络。所以整套卷子的题型比重大概是这样的考察方向典型题目类型2011年必考理由JavaScript语言基础this指向、闭包、作用域、原型链、变量提升语言功底是最难伪装的DOM/BOM操作事件绑定、冒泡捕获、offsetParent、定时器日常开发80%的工作在这里浏览器兼容性IE6/7 bug处理、事件对象差异、样式兼容当年的日常躲不开Ajax与网络缓存原理、HTTP状态码、跨域后端交互的基本功性能优化资源合并压缩、加载顺序、重排重绘Yahoo军规影响深远代码设计与模式继承、封装、模块化还没“框架”可抄只能手写基础算法/逻辑数组去重、字符串处理筛掉完全没写过代码的人2.2 一道经典的JavaScript基础题this指向这类题在当年的卷子里几乎占据半壁江山。给你一段代码让你写出输出结果然后解释为什么。我印象比较深的有这么一道var name window; var obj { name: obj, getName: function() { return this.name; } }; var fn obj.getName; console.log(fn()); // 输出什么 console.log(obj.getName()); // 输出什么本质考的是JavaScript函数调用时this绑定的几条基本规则直接调用fn()时调用者是全局对象非严格模式下所以输出window作为对象方法调用obj.getName()时this绑定到obj所以输出obj。很多基础不牢的考生第一题就会栽不是不知道规则而是容易被var fn obj.getName这一步绕晕。我自己当年做这类题时也经历过一段“背答案”的阶段后来被一道变体彻底教育了var length 10; function fn() { console.log(this.length); } var obj { length: 5, method: function(fn) { fn(); arguments[0](); } }; obj.method(fn);这道题第一问输出10因为fn()是普通调用第二问输出2因为arguments[0]()等价于让arguments对象充当调用者而arguments的length属性正好是2。如果搞不清楚“调用点决定this”这个原则这种题基本没法做。这也是现在前端面试里常考的内容——你以为面试官在问this其实他是在问你到底有没有认真读过执行上下文相关的规范知识。2.3 原型链与继承手写一个靠谱的继承2011年的笔试几乎必考原型链和继承而且不满足于让你说说prototype是什么通常会要求“请用JavaScript实现一个继承机制”有的还会加限制不用ES6的class不考虑浏览器兼容之外还要保证instanceof正确、父类构造函数的参数能正确传递。当年比较标准的答案是组合继承function Animal(name) { this.name name || animal; } Animal.prototype.say function() { console.log(I am this.name); }; function Dog(name) { Animal.call(this, name); } Dog.prototype new Animal(); Dog.prototype.constructor Dog; var dog new Dog(wangcai); dog.say(); console.log(dog instanceof Animal); // true console.log(dog instanceof Dog); // true这个方案的优点是既能继承实例属性通过call又共享原型方法。缺点是父构造函数被调用了两次一次new Animal()建立原型链一次Animal.call(this)设置实例属性导致子类原型上会存在一份冗余的父类实例属性。后来大家写寄生组合继承来解决这个问题利用一个中间构造函数来避免重复调用function inherit(Child, Parent) { var proto Object.create(Parent.prototype); proto.constructor Child; Child.prototype proto; }这种写法现在看是基本功但在2011年能把这个思路写明白的人说明对原型链的理解已经超过大多数竞争者了。今天面试如果不再直接考这种题不是因为它不重要而是因为ES6的class语法把这个复杂度封装了但懂得底层原理的人调试原型链相关bug时会快得多。2.4 DOM事件兼容IE的bind函数到底怎么封装事件处理是2011年前端每天都要写的代码。当时jQuery的.on()/.bind()之所以受欢迎很大程度是因为它帮你抹平了浏览器差异。笔试自然会考到“请手写一个跨浏览器的事件绑定函数支持冒泡阶段并且能移除监听。”当年我的答案长这样function bindEvent(elem, type, handler) { if (elem.addEventListener) { elem.addEventListener(type, handler, false); } else if (elem.attachEvent) { elem.attachEvent(on type, function(e) { e window.event; handler.call(elem, e); }); } else { elem[on type] handler; } }这里面有几个坑第一IE的attachEvent回调里this指向window而不是绑定元素所以要用handler.call(elem)修正第二IE使用window.event而不是事件参数传入第三如果直接传入handler给attachEvent后续detachEvent时也必须用同一个函数引用否则移除不干净。因此要拿到真正传给detachEvent的那个包装函数还得用额外变量保存。这种题放到2026年直接问“事件委托怎么写”的场景更多但背后的思路其实一脉相承。事件委托本身还是靠event.target做判断在React里合成事件做了统一封装但你去排查生产环境问题、或者手写一个小型公共组件库时原生事件的基础依然绕不开。2.5 闭包与内存泄漏经典循环绑定问题2011年的考题特别喜欢拿循环里绑定事件来考闭包。比如给你一个ul里有5个li让你实现点击第i个li弹出它的序号。这题当年能筛选掉一批人因为很多人直接写var lis document.getElementsByTagName(li); for (var i 0; i lis.length; i) { lis[i].onclick function() { alert(i); }; }结果弹出来的永远是5。原理大家都清楚var i是函数级作用域循环结束后i的值已经变成5所有闭包共享同一个变量引用。解法有几种用let当年没有用IIFE传值for (var i 0; i lis.length; i) { (function(index) { lis[index].onclick function() { alert(index); }; })(i); }或者用事件委托、或者把索引挂到DOM属性上。这类题目在2026年的面试里依然存在只是场景从li变成了useEffect里的依赖数组、或者定时器里的捕获变量。闭包本身就是JavaScript的核心特性不管框架怎么变它永远会出现。2.6 Ajax与跨域从XHR到JSONPAjax在当时是前后端分离的雏形。笔试卷里常考的知识点包括XMLHttpRequest的readyState取值含义、status状态码的判断、GET和POST的区别、怎么处理缓存以及JSONP的原理。有个我非常喜欢考的题目是“为什么JSONP只能发GET请求”答案是因为JSONP的原理是动态创建script src标签让服务器返回一段可执行的JavaScript而script标签加载资源本质上就是一次GET请求不存在POST或其他方法。这个知识点放在今天的面试里也许不会直接考JSONP了毕竟CORS已经普及但如果你理解script的加载机制就更容易理解现代前端里的各种预加载、动态注入脚本策略。当年还特别爱考缓存问题。比如GET请求怎样才能避免被浏览器缓存常见的办法是在URL后面拼随机数或时间戳var url /api/list?t new Date().getTime();或者设置请求头Cache-Control: no-cache。这个问题放到现在的价值在于帮助你理解浏览器HTTP缓存的整体框架——强缓存与协商缓存、ETag/Last-Modified的配合、以及为什么静态资源要指纹化命名。你在面试时说一句“我的静态资源都带hash所以可以放心长缓存”面试官就知道你是真懂缓存实践的。3. 从几道“古董题”看前端工程化的起点3.1 当年怎么处理“全局变量污染”的问题现在写Vue或React模块化已经内化到日常开发里了import/export是顺手的事。但2011年没有ES Module也没有CommonJSNode已经存在但前端浏览器端还没有广泛应用打包器所有代码都在同一全局作用域下。所以笔试卷里会考如何避免全局变量污染如何设计命名空间标准答案是全局命名空间加模块模式var App App || {}; App.utils (function() { var privateVar secret; function helper() { return privateVar; } return { getHelper: helper }; })();这套思路里面其实是经典的IIFE 闭包 单例组合。放到今天虽然ES Module帮你解决了顶层作用域问题但闭包和工厂模式在写工具函数库时依旧常用。很多面试八股文里特别爱考的“模块化发展历史IIFE → AMD → CommonJS → ES Module”起点就在这。我当时刷题时一开始是死记这些代码后来想明白一个事所有模块化方案要解决的问题其实就两个——隔离作用域和定义依赖关系。你在React里写export default function本质上和当年App.utils.getHelper的模式有共同的底层诉求。想通了这条线看任何框架的源码都不太会晕。3.2 原型继承与面向对象当年为什么大家都在折腾这个2011年前端圈有一件特别有意思的事大家都在用JavaScript的对象和原型但思维模型很多时候是照着Java/C的“类”去套的。所以面试题才会那么多关于“如何实现类式继承”的套路本质上是因为大家希望像写后端一样组织前端业务代码。这其实带来一个很深刻的问题语言本身的表达能力和开发者脑中的心智模型不匹配。ES6的class语法出现之后这种焦虑缓解了不少但class本质仍然是原型链的语法糖。如果你只学会了class extends不理解super到底调的是什么那遇到“为什么这个子类实例的原型链上多了一层”这种问题照样懵。所以我的建议是2026年准备前端面试仍然要抽时间把原型链那套东西的底层逻辑捋一遍。不一定要会手写寄生组合继承但要能画得出“实例.__proto__ 构造函数.prototype”这条链路能回答“Function.prototype和Object.prototype谁更上层”这类问题。3.3 性能优化题目雅虎军规的遗产2011年的笔试性能题大多围绕一个中心减少请求数、减少体积、减少阻塞。例如为什么把link放head里把script放/body前CSS雪碧图的意义是什么图片懒加载怎么实现合并CSS/JS文件、压缩代码为什么能提升性能使用CDN能解决什么问题这些问题的答案在今天依然成立只是形式和粒度变了。比如“把script放底部”演变成现代构建工具里的defer/async策略和modulepreload“CSS雪碧图”基本被iconfont、SVG Sprite和WebFont替代CDN来了又走但边缘计算和边缘渲染的思路一直在延续。对于准备面试的同学我建议把性能优化题当作一条贯穿线来准备输入URL到页面渲染完成发生了什么——这是前端性能优化的总纲。从DNS解析、TCP连接、TLS握手、HTTP请求、服务端响应、HTML解析、CSSOM构建、脚本执行、渲染管线、资源加载每一个环节都有对应的优化手段。面试官问任何一道性能题你都能把它挂到这条链路上回答的深度和广度就会拉开差距。4. 2011年真题与2026年面试的对照变与不变4.1 题型整体对照表为了直观我整理了一份2011与2026的区别但也加一列“底层共通点”避免大家只看到变化而忽略本质2011年典型题2026年常见面试题底层共通点手写事件绑定兼容函数React合成事件原理、事件委托实现浏览器事件模型与冒泡捕获机制手写AJAX请求封装fetch实现、axios拦截器原理网络请求的生命周期和状态管理手写数组去重手写深拷贝、手写Promise.all、防抖节流基础算法/工具的代码实现能力用闭包解决循环绑定useEffect依赖导致的闭包陷阱作用域与闭包对异步逻辑的影响手写继承实现一个EventEmitter、观察者模式面向对象设计能力与代码组织方式页面加载性能优化首屏性能优化、Core Web Vitals、资源加载策略网络加载与渲染链路理解JSONP跨域CORS配置、反向代理、iframe通信浏览器同源策略含义从表里能看出来技术方案一直在换但考察的内核没怎么变。很多现在被包装成“高级题”的东西比如React的合成事件其事件模型的底层依然是你十年前就该懂的冒泡和捕获再比如防抖节流看起来是功能函数但考的还是你对定时器、闭包、调用频率控制的理解。4.2 “八股文”为什么还是面试主角现在网上一搜“前端面试八股文”出来一大堆“背完进大厂”的清单。有人批判有人拥护。我个人观点是大多数“八股文”知识点本身是有价值的问题只在于你是“背下来”还是“真正理解”。比如“浏览器从输入URL到页面呈现发生了什么”这道题如果你只是在脑海里背了一遍每步的名字没有任何一个步骤能展开讲透那面试官问两三个追问你就会露馅但如果你真的逐层理解过DNS、TCP、TLS、HTTP缓存、渲染管线那你不仅能回答主干问题还能对性能优化题、网络异常排查题、跨域问题都游刃有余。2011年的试卷其实也一样——它里面哪些题是“八股”呢readyState的几个状态值、HTTP状态码含义、事件流的三个阶段……这些都可以算八股。但一个合格的前端不能只知道名字你得在真实项目里遇到过断网重试、遇到过缓存失效、遇到过点击事件不触发的原因排查才会对这些“八股”有体感。所以备考的关键不是背题而是拿真实案例去激活这些知识点。4.3 框架时代基础题为何还重要我在看现在市面上一些前端培训课程时发现一个挺普遍的现象学员学React/Vue学得很熟能写各种组件、能配各种脚手架但一旦问“这个组件的useEffect为什么执行了两次”或者“父组件重新渲染时子组件为何跟着渲染React.memo到底比较的是什么”大部分人会卡壳。这些问题的答案全都在JavaScript基础里依赖比较、闭包、引用相等、副作用与渲染周期的关系。当年没有React但试卷里关于闭包、this、原型链的题本质上是在确认一件事你到底能不能用JavaScript这门语言好好思考。2026年的面试题堆了很多壳但壳下面依然是同一个核。所以我的建议非常朴素如果你的简历里写着“精通JavaScript”那就先把原型链、闭包、作用域、事件循环、异步流程控制这几块啃明白再去看框架源码。不然栈底不稳栈顶修修补补永远觉得虚。5. 我自己刷这份卷子的实操心得5.1 我是怎么用一份老卷子做查漏补缺的如果你手上也有一份老题集不限平台我建议不要只把它当成“做一遍就完事”的东西。我自己的做法是第一遍限时模拟。把每道题当正式考试给自己定好时间不翻资料。做完对答案把所有错题和有疑惑的题标红。第二遍主题归类。把标红的题按“闭包”“this”“事件”“网络”“兼容”等维度归类你会发现自己的薄弱环节非常集中。比如我当年就集中在“this指向”和“异步流程”这两块。第三遍讲给别人听。这个很关键。找朋友或者自己录语音把你对一道题的理解讲清楚。讲不明白的地方就是还没理解透的地方。这个方法不只适用于老题也适用于现在任何一套面试题集。题目的年份不重要重要的是它覆盖了哪些核心领域。5.2 关于手写题从“背答案”到“真理解”2011年的笔试题需要大量手写代码现在的前端机试和手写题同样很多。很多人有个误区手写题 默写。就比如说手写一个节流函数如果你不看注释能直接写出来但说不出“为什么用timestamp比较而不是单纯用一个标记变量”那面试官问一个边界情况你就会慌。这里我分享一个训练方法——“三问法”这个函数/方案的输入是什么可能有哪些边界情况每一步操作对应解决了什么问题不做这一步会怎样如果换一个场景这个函数/方案还能不能直接用需要改哪里拿节流函数举例function throttle(fn, delay) { let last 0; return function(...args) { const now Date.now(); if (now - last delay) { last now; fn.apply(this, args); } }; }三问之后你会意识到必须记录上一次执行的时间必须用apply把this传下去不然用户对象上的方法内部拿不到正确thisDate.now()加上首次调用判断可以控制是否立即执行。到了这一步你写出来的东西才算真正属于你。5.3 学习路线建议从历史题里找到今天的重点基于这份2011年试卷如果你是一个2026年刚开始准备前端面试的同学我会建议这样安排学习路线第一优先级JavaScript语言核心变量/类型/作用域/闭包/原型链/this/异步/事件循环无论框架怎么换这里永远是根基第二优先级浏览器工作原理渲染过程、JavaScript执行、事件机制、存储、缓存、跨域、网络基础HTTP/HTTPS、TCP、DNS、缓存策略第三优先级至少一个主流框架的深度理解不是只会用API而是理解其响应式原理、渲染机制、组件通信、生命周期/副作用管理第四优先级工程化与协作能力模块化、打包工具、代码规范、测试、部署CI/CD、微前端、性能监控。很多培训机构的路线图也差不多是这个顺序但容易忽略的是每个阶段都要配足够的真实练习。只看不写永远记不牢。5.4 一点个人看法老题不是用来背的是用来理解行业演变的最后聊一点我复盘这份卷子时最深的感受。2011年的前端本质上是一个“在混乱中造轮子”的时代浏览器不统一标准不完善能用的工程手段少每个团队都在摸索自己的最佳实践。所以笔试题目偏基础、偏原理、偏“手写一切”。2026年的前端工程化程度已经非常高了框架帮你解决了大部分重复工作但这也带来一种风险很多新人只会在框架的范式里写代码一旦遇到框架覆盖不到的场景就寸步难行。因此我特别建议各位在准备面试或日常提升时刻意安排一些“去框架化”练习比如用原生JavaScript写一个小型列表页、手写一个类似事件总线的通信模块、自己实现一个简易的数据响应式系统类似Vue3的reactive/effect。这些练习不会直接出现在笔试卷上但能极大提升你对语言本身的掌控感而这些掌控感会在你分析复杂问题、阅读框架源码、定位生产bug时成倍地回报你。如果你手头也有一份老题集不妨静下心来按上面的方法过一遍。真正有价值的不在于那几道题的答案而在于你在梳理答案的过程中把散落的知识点串成了完整的知识网。这张网才是面试和工作中真正可靠的东西。
返回列表