ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

奇安信前端笔试真题解析:从基础到安全的全面备考指南

2026/8/29 22:20:05 拓冰建站 浏览量
奇安信前端笔试真题解析:从基础到安全的全面备考指南 2019年那时候奇安信还没有从360体系里完全独立出来多久春招笔试的题目风格其实已经很有辨识度了。我印象里那套前端开发试题整体难度中等偏上不算变态但覆盖面很广基础不扎实的人很容易在及格线附近徘徊。今天把这套题掰开揉碎讲一讲不只是给答案更重要的是讲清楚每一类题目背后的考察逻辑和备考思路。不管你是准备应届生校招还是社招想跳槽去安全行业的技术团队这套题里的知识点都值得过一遍。1. 试题整体印象怎么看懂一套前端笔试题的“出题人意图”拿到任何一套笔试题先别急着埋头做题。我习惯先花五分钟把整张卷子扫一遍标出题目类型和分值分布这时候出题人的“口味”基本就暴露了。1.1 奇安信2019春招前端卷的题型构成从整体来看这套题大致分为四个板块基础理论题、代码输出题、手写实现题和开放设计题。基础理论题覆盖HTML、CSS、JavaScript、浏览器原理和网络基础代码输出题主要考察JavaScript的语言特性比如作用域、闭包、异步顺序手写实现题则集中在数组去重、深拷贝、防抖节流这类经典场景开放设计题会给你一个业务场景让你描述技术方案。这种结构说明什么说明奇安信的前端团队在招人时非常看重候选人的语言基本功和工程思维而不是看你背了多少框架API。那一年Vue和React已经非常流行了但这套题里框架相关的考点占比并不高反而基础能力占了大头。这和当时很多大厂的出题风格是反着来的——当时不少公司一上来就问Vue生命周期、React diff算法的细节。后来我复盘了一下这个思路其实和奇安信的业务属性高度相关。安全公司做的前端产品比如管理后台、态势感知大屏、终端管控界面绝大多数时候不是面向海量C端用户的而是面向企业客户和安全运维人员的。这类产品对稳定性、数据准确性、安全性要求极高花里胡哨的交互反而是次要的。所以面试官更在意你能不能写出靠谱的代码而不是能不能背出某个框架的源码细节。1.2 这套题的备考价值在哪儿哪怕你不是去奇安信面试这套题的参考价值也很大。原因很简单它考察的知识点全部是前端领域“保值率”最高的那部分。反而是那些当年很热门的框架题放到今天可能早就过时了。ES6语法、事件循环、原型链、HTTP缓存、跨域方案这些内容今天依然是前端面试的绝对主力。所以如果你现在正在准备前端面试与其漫无目的地刷题不如拿这套题当一次自测。能把这套题做到80分以上至少说明你的JS基础是过关的面对大多数公司的笔试环节都不会太虚。2. HTML与CSS考点安全公司会在布局题里埋什么坑很多人对HTML和CSS题不以为然觉得就是背背标签、记记属性。但实际上奇安信这类公司的前端笔试里CSS题的陷阱往往藏得很深。2.1 盒模型与BFC不只是概念题盒模型是CSS的第一课但能把content-box和border-box的区别讲透的人并不多。标准盒模型content-box的width只包含内容区而IE盒模型border-box的width包含内容、内边距和边框。实际开发里我们普遍通过box-sizing: border-box来统一全局盒模型因为这样更符合人脑直觉——你设置多大的宽度元素就占多大的宽度。BFC块级格式化上下文同样是高频考点。BFC可以理解为一个独立的渲染区域内部元素的布局不会影响外部。触发BFC的方式有float非none、position为absolute或fixed、overflow非visible、display为inline-block或flex等。常见的应用场景有两个一是清除浮动当子元素全部浮动导致父容器高度塌陷时给父容器设置overflow: hidden触发BFC父容器就会重新包裹子元素二是防止 margin 折叠两个兄弟元素的上下margin在垂直方向会取较大值合并但把它们各自放进独立的BFC里就可以避免折叠。这里有个实操经验真正做后台管理系统的时候overflow: hidden触发BFC来清除浮动这个方案在新老浏览器上表现都不错但也有副作用——如果子元素需要溢出显示下拉菜单会被父容器裁掉。所以现代项目里我一般优先用display: flow-root或者直接改用flex布局这两种方式干净利落。2.2 经典布局题圣杯布局与双飞翼布局圣杯布局和双飞翼布局是CSS笔试的常青树它们要解决的核心问题是一样的左右两栏固定宽度中间主内容栏自适应宽度且中间栏在DOM结构上优先渲染这对首屏加载和SEO友好。圣杯布局的思路是三栏都用float: left中间栏宽度设为100%然后利用padding为左右栏腾出位置。左右两栏通过负margin移动到对应位置——左栏margin-left: -100%让它上移到中间栏的左侧起点右栏margin-left: -自身宽度让它上移到最右侧。最后给三栏的父容器设置左右padding宽度等于左右栏的宽度。双飞翼布局则换了个思路中间栏内部再套一层div左右两栏的定位方式和圣杯一样但为中间栏内容腾位置时不用父容器的padding而是给中间栏内部那层div设置左右margin。这样父容器宽度就是100%左右栏直接贴在两侧省去了相对定位的步骤。实际笔试里这种题不一定要求你手写完整代码更多是让你说清楚实现思路和区别。但我的建议是哪怕不写完整代码也要把这个过程推导清楚同时提一句“现在都用flex或grid实现了”这样面试官会觉得你既懂老方案也跟得上新趋势。2.3 垂直水平居中的N种姿势垂直水平居中几乎每次笔试都会出现而且出题人常常会补一句“元素高度未知”。这个限制条件很关键它排除了line-height和绝对定位配合负margin的方案。我一般会给面试官按场景分类元素定宽高绝对定位 四角为0 margin: auto这个方案兼容性最好不定宽高绝对定位 transform: translate(-50%, -50%)用CSS3解决唯一注意父容器要相对定位flex方案父元素display: flex; align-items: center; justify-content: center;这是当前项目里的首选代码量最少grid方案父元素display: grid; place-items: center;更简洁。实话说现在项目里我从来不给弹窗用transform居中而是直接用flex。因为transform会创建新的层叠上下文有时候会连带出z-index和定位问题。笔试写方案的时候可以提一句“flex最稳transform有层叠上下文副作用”这种细节会让你跟其他候选人明显拉开差距。3. JavaScript核心考点输出题背后藏着多少语言特性JS部分永远是前端笔试的主导奇安信也不例外。这套题里代码输出题占比不低而且专门挑那些“看似简单一写就错”的语法糖来考。3.1 作用域、闭包和立即执行函数经典题目var在for循环中配合setTimeout打印的问题。连续输出10个10原因在于var声明是函数作用域循环体里的i是同一个变量等到定时器回调执行时循环早已结束i已经变成了10。解决办法有两个用let声明让每一次循环都绑定一个新的i或者用立即执行函数IIFE传递当前值。闭包在奇安信这类基础题里几乎是必考的。比如问你以下代码输出什么function foo() { let count 0; return function () { count; console.log(count); }; } const f foo(); f(); f();答案是1, 2。核心考点是内部函数引用了外部函数的变量外部函数执行结束后变量没有被垃圾回收而是被内部函数继续持有。这也解释了为什么闭包可能造成内存泄漏——如果你在DOM事件里用了闭包又忘了移除事件绑定整个作用域链都会残留。3.2 this的指向问题别背口诀画调用栈this指向是JS笔试的重灾区也是很多工作两三年的前端说不清的地方。出题人很爱把this和对象调用、普通函数调用、箭头函数混在一起出题比如const obj { name: qihoo, getName: function () { return this.name; }, getNameArrow: () { return this.name; }, }; console.log(obj.getName()); console.log(obj.getNameArrow());第一行输出qihoo没问题this指向调用者obj。第二行就有意思了箭头函数没有自己的this它的this是在定义时从外部作用域捕获的所以这里的this指向全局对象this.name是undefined。我不建议死记“谁调用指向谁”这种口诀因为遇到箭头函数这口诀立刻就失效了。更好的分析方式是先把函数调用方式画出来看它是普通调用、对象方法调用、call/apply调用还是new调用然后逐层确定this如果函数是箭头函数直接往上找最近的外层普通函数的this。这套逻辑可以应对所有this考题。3.3 事件循环与异步顺序输出题里最能拉开差距的就是事件循环。比如考这样的代码console.log(a); setTimeout(() { console.log(b); }, 0); Promise.resolve().then(() { console.log(c); }); console.log(d);输出顺序是a d c b。这里考察的微任务和宏任务执行顺序同步代码先执行然后本轮事件循环中的微任务Promise的then回调优先于宏任务setTimeout回调执行。即使setTimeout的延迟是0它也会被放进宏任务队列要等下一轮事件循环才轮到。2019年的考题还很少问到async/await和微任务嵌套的复杂情况但现在这里已经成了必考深水区。我的建议是把事件循环的机制彻底搞清楚执行栈清空后微任务队列会一次性清空然后再取一个宏任务执行宏任务执行过程中又会产生新的微任务这些微任务会排在下一次宏任务之前执行。把这条链路理解透不管题目怎么嵌套你都不会懵。3.4 对象与数组方法map、filter、reduce的熟用程度数组方法题在笔试题里也经常出现。比如[1, 2, 3].map(parseInt)的输出是什么答案是[1, NaN, NaN]。原因是parseInt接收两个参数map回调会把当前值和索引传进去所以第二次调用是parseInt(2, 1)第三次是parseInt(3, 2)都是无效进制返回NaN。这类题考察的不是你会不会用map而是你清不清楚map回调的完整参数列表当前值、索引、原数组以及parseInt的完整参数签名字符串、进制基数。所以平时写代码多留意标准API的完整签名少依赖记忆中的“常用方式”这种坑踩一次就能记住。4. 框架与工程化考点安全公司也躲不开的范畴虽然前面说这套题基础占比大但框架和工程化的内容也没有缺席。尤其是在开放题和应用题里Vue/React的使用经验是加分项。4.1 Vue与React从“会写页面”到“说清原理”笔试中常见的框架问题有Vue的双向绑定原理、虚拟DOM的作用、key的作用、组件通讯方式、生命周期钩子对比。React的常见考点则是state与props的区别、setState的异步性、受控组件与非受控组件、 useState/useEffect的依赖数组、Fiber架构解决了什么问题。奇安信前台产品偏管理类和展示类Vue的普及率在我印象里比React高一些所以Vue出题概率更大。重点准备这几个问题computed和watch的区别computed是声明式地根据依赖数据计算出新值有缓存watch是监听数据变化执行副作用操作用于异步或开销较大的操作。v-if和v-show的区别v-if是条件渲染不满足条件直接不渲染DOM切换有渲染销毁成本v-show是css的display切换只是视觉隐藏适合频繁切换的场景。key的作用key帮助diff算法识别节点复用当列表顺序变化时正确的key可以最小化DOM操作。不建议用数组索引当key因为增删元素后索引会变可能导致状态错乱。4.2 前端性能优化笔试爱问实际项目更要会安全产品的前端页面往往数据量大、图表多、刷新频繁性能优化是实际问题。笔试里的性能优化题通常不要求你写代码但要求你按场景列出方案。我通常会按浏览器工作流程来组织答案网络层面做资源压缩合并、HTTP缓存、CDN分发渲染层面减少DOM操作次数避免强制同步回流用文档碎片或虚拟列表处理长列表代码层面做按需加载和懒加载拆分首屏代码优化图片格式和尺寸。这里有一个很多人的误区一说性能优化就在扣JS执行时间但实际上首屏性能的大头通常在资源加载和网络请求。2019年我优化一个数据中心管理后台时把十几个第三方依赖全部改为按需引入首屏体积从2.4M降到800K加载时间从5秒变成2秒左右这个收益远大于优化几个函数执行耗时。所以面试时一定要先说网络和加载层面的优化再说渲染和运行时的优化这更符合真实场景的优先级。4.3 工程化工具链webpack问题怎么答不露怯工程化题偶尔会考webpack的构建流程、loader和plugin的区别、如何做代码分割。这类题其实有个答题模板先说整个构建过程是入口解析、依赖收集、模块编译、代码生成这几个阶段loader负责对模块源代码进行转换是在编译单个模块时执行plugin则在整个构建流程里都可以介入通过钩子机制完成更广泛的任务。只要把base流程说清楚然后举一两个常用的loader和plugin例子比如babel-loader处理ES6、eslint-loader做代码检查、HtmlWebpackPlugin生成HTML、TerserPlugin做代码压缩基本就能过关。5. 安全公司面试的隐藏彩蛋前端安全题才是重头戏奇安信做的是安全业务前端笔试题里几乎一定会出现安全相关的考点。这既是奇安信面试的特色也是非安全公司面试容易忽略的盲区。把这块准备好你能给面试官留下极其深刻的印象。5.1 XSS攻击与防御别只知道alert弹窗XSS跨站脚本攻击是前端安全里最经典的考点。基本原理是攻击者把恶意脚本注入到页面中当其他用户访问这个页面时脚本在用户浏览器中执行从而盗取Cookie、篡改页面内容或者发起请求。防御手段有三个层次。第一层是输入过滤用户输入的内容一律当作数据而非代码处理前端要对特殊字符做转义比如替换为lt;替换为gt;第二层是输出编码在不同上下文HTML标签内、属性内、JavaScript内要用不同的编码方式第三层是设置安全响应头比如Content-Security-PolicyCSP可以限制页面能加载的资源和脚本来源就算脚本被注入也执行不了。5.2 CSRF与CORS跨域问题的安全视角CSRF跨站请求伪造的经典场景是用户登录了银行网站又去访问了恶意网站恶意网站利用浏览器自动携带Cookie的特性构造一个跨站请求让用户在不知情的情况下完成转账或修改操作。防御CSRF的思路主要有校验请求头中的Origin或Referer用token机制——后端生成一个随机token存到表单或请求头里服务器验证token是否有效设置Cookie的SameSite属性限制跨站请求是否携带Cookie用自定义请求头因为跨站请求无法自动构造自定义头。CORS跨域资源共享和CSRF容易混淆但考点完全不同。CORS是浏览器对外部请求的一种协议规范当页面请求了其他域的接口浏览器会先发起预检请求OPTIONS服务器通过响应头里的Access-Control-Allow-Origin来声明是否允许跨域。前端开发中常见的跨域方案除了CORS外还有JSONP、代理服务器等。有一道题让我印象很深题目问的是“前端做了CORS配置能彻底解决跨域安全问题吗”。正确答案当然是不能。CORS只是浏览器层面的访问控制接口本身是否安全还需要后端做鉴权验证。你能在理解CORS的同时指出这个边界面试官会明显高看你一眼。5.3 路径遍历与文件上传场景热词里提到了“奇安信 输入验证路径遍历”这个知识点同样会出现在笔试题甚至实际产品中。路径遍历是指攻击者通过构造../这样的特殊路径访问服务器上本不该被访问的文件。前端在接收文件上传、下载参数时一定要对路径参数做白名单校验不能直接拼接用户输入到文件路径里。比如下载文件的接口如果后端拿到的文件名参数是../../etc/passwd拼接路径后就可能读取到系统敏感文件。前端的责任是上传文件时校验文件类型限制文件大小对文件名做合法性校验下载文件时不要把用户输入直接作为路径参数传递而是建议后端用映射ID来定位文件。6. 手写实现题这些代码现在就可以背下来手写题是笔试里最能直接反映编码能力的一环。说实话这部分题是有套路的核心题型不多练熟了就是送分题。但如果没练过现场写很容易翻车。6.1 数组去重至少给出三种思路数组去重是最经典的手写题也是我当年笔试的第一道手写题。现在回想起来这道题的关键不是写出来而是写得全面、有层次。最朴素的方案是双重循环或使用indexOf做去重时间复杂度较高。用Set是最简洁的方案一行代码搞定[...new Set(arr)]。但面试官往往不希望你就此打住还会追问如果数组里有对象Set去重还靠谱吗这时候要答到Array.from(new Set(arr.map(item JSON.stringify(item))))来对对象序列化后去重或者用reduce配合Map来做按属性去重。我写题时的习惯是先说清楚各种方案的优缺点再选一种代码量适中的方案写上。除非题目明确要求性能最优否则不要一上来就写奇技淫巧。6.2 深拷贝考你会不会考虑边界情况深拷贝题的高频程度不用多说。手写一个递归深拷贝看起来简单但能拿满分的人不多。基础版本是判断值类型和引用类型值类型直接返回引用类型创建新对象后递归复制属性。但要注意几个边界数组和对象要分别处理要防止循环引用否则会栈溢出函数的特殊处理不算重点但要说清楚。比较稳妥的写法是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); for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { result[key] deepClone(obj[key], map); } } return result; }这里用WeakMap来处理循环引用是关键点。很多人写深拷贝不考虑循环引用一遇到a.self a这种结构就爆栈。能主动想到用WeakMap处理这个问题这道题基本稳了。6.3 防抖和节流应用场景比代码本身更重要防抖debounce和节流throttle也是手写题里的常客。防抖的核心是“延迟执行”在事件触发后的一段时间内如果再次触发就重新计时适用于输入框搜索联想、窗口resize后的计算节流的核心是“限制执行频率”一段时间内只执行一次适用于滚动加载、按钮连点、拖拽等场景。一个比较完整的防抖实现是function debounce(fn, delay, immediate false) { let timer null; return function (...args) { if (immediate !timer) fn.apply(this, args); if (timer) clearTimeout(timer); timer setTimeout(() { fn.apply(this, args); timer null; }, delay); }; }注意这里用apply绑定this并且...args接收参数这两个细节很多培训班出来的候选人都会漏。如果面试官让你说应用场景别只说搜索输入可以补充一个“请求取消”的场景用户快速点击多个筛选条件时只保留最后一个请求结果既能防止重复请求也能避免旧请求覆盖新请求。6.4 其他高频手写题清单除了上面几道下面是2019年前后前端笔试中出现频率很高的手写题建议每道题都能做到10分钟内独立写出可运行版本实现一个new操作符实现Function.prototype.call/apply/bind实现一个Promise.all实现一个简单的发布订阅EventEmitter实现instanceof的底层逻辑实现一个简单的Object.create洗牌算法Fisher-Yates手写一个简单的MVVM响应式系统这些题目虽然看着多但其实是相互关联的。比如Promise.all的核心是理解Promise的执行和状态流转EventEmitter的核心是维护一个事件回调数组。把底层逻辑想明白代码写出来就是水到渠成的事。7. 时间分配与答题策略笔试比的不只是会多少一套笔试题做下来很多人挂掉的原因不是不会而是来不及做。笔试的时间分配直接决定你的得分上限。7.1 拿到卷子先做这三件事第一快速浏览全卷把所有题目分成“秒杀题”“思考题”“硬骨头”三类。第二先把秒杀题做完并检查一遍保证拿满基础分。第三再去做思考题最后进攻硬骨头。不要把时间耗在某一题上比如深拷贝写了一半卡住就先跳到下一题最后再回来补。我见过不少人在一道手写题上死磕了30分钟结果后面10道基础选择题全没做。这种策略性失误完全可以通过考前模拟来避免。建议考前自己卡着时间做两套完整的真题或高质量模拟题别只看题不解题。7.2 代码题的“过程分”怎么拿手写题即使写不出来完整答案也要把自己的思路分步骤写下来。比如深拷贝写不出来你写了“先判断类型然后递归复制注意循环引用”三行字也能拿一部分过程分。更聪明的做法是在注释里写清楚思路然后写出一个不完美但思路正确的版本——笔试批卷人更看重你解决问题的思维路径而不是最后的代码是否一字不差。另外手写题的代码格式一定要干净。变量命名合理、缩进统一、函数抽取清晰这些细节都能加分。别小看这些印象分在水平接近的候选人里代码风格好的往往优先进面试。7.3 安全公司的笔试复习重点既然目标公司是安全行业除了常规前端知识一定要多花时间看安全和业务结合的部分。我的建议是准备一个“安全场景下的前端项目经验”故事比如你曾经处理过登录表单的输入校验、给文件上传接口做过类型和尺寸校验、用CSP增强过页面的安全性或者改过接口的鉴权逻辑防止越权访问。把这些真实经历整理成一小段有背景、有举措、有结果的描述比背十个面试题模板都管用。8. 那些年我踩过的笔试坑和回头看的心得现在回头看看2019年的前端笔试再对照这些年带团队的面试经历有些心得值得和还在准备笔试的你说一说。8.1 笔试挂掉最常见的三个原因第一基础题不仔细读题。很多题目不是不会是题眼没看到。比如题目要求用ES5实现防抖你上来就用let、箭头函数直接扣分。第二手写题只看逻辑不看边界。代码在正常输入下没问题但一遇到空数组、空对象、循环引用就崩了这种代码在工程化标准里是过不了评审的。第三框架经验写得太满基础一塌糊涂。笔试就是一面照妖镜你平时靠框架和工具掩盖的知识盲区在基础题面前全都会现原形。8.2 从面试官视角看什么样的候选人能过我后来也参与过校招笔试的出题和阅卷站在面试官的角度我会优先看三样东西一是代码的完整性边界条件和异常处理有没有考虑二是思路的清晰度即使题目没完全做出来注释和流程描述也能看出思考过程三是对安全相关的意识哪怕笔试没有专门的安全题候选人在回答性能优化、跨域问题时能否主动提到安全风险这会让我觉得这个候选人很契合公司业务。8.3 给正在准备前端笔试的你的实操建议如果你现在是准备阶段我建议你做两件事。第一件把本文提到的所有手写题全部写一遍写到不需要思考就能默写的程度。笔试现场是有时间压力的如果这些基础题你在脑子清醒时都不能秒写现场环境会更糟。第二件找一个有经验的前端帮你做一次模拟面试让他用这套题的类型抽考你重点看你能不能边说思路边写代码而不是默默写完。很多笔试挂掉的人不是不会写是不敢在时间压力下写这个问题只能靠模拟场景来克服。这组题放在今天依然不过时因为它考的从来不是某个特定版本的框架API而是你对前端底层的理解深度。这份理解力一旦建立不管面哪家公司笔试环节都不会对你构成真正的阻碍。