☰
奇安信秋招前端笔试题解析:安全厂商最看重的基础与漏洞防护
2026/10/31 0:03:52 网站建设 项目流程

2020年奇安信秋招前端方向的试卷2,我是在笔试截止前一个半小时才点开链接的,当时心态比较放松,结果做完之后反而印象很深。怎么说呢,这份试卷不像一般互联网公司那样把八股文背熟就能拿高分,它在基础题之外塞了不少安全厂商才会关心的东西。如果你是准备校招前端岗,尤其是投安全类、政企服务类公司的前端岗位,这套题很值得认真过一遍。里面的知识点放在2026年看也依然不过时,反而因为这几年供应链安全、前端漏洞被重视,这些内容更值钱了。

这篇文章我会把试卷的考点结构、每类题目的答题思路、安全方向的加分答法、以及我当时踩过的坑完整整理出来。内容量比较大,建议先收藏,然后对着目录挑自己薄弱的部分精读。

1. 试卷整体布局与出题风格分析

1.1 一份安全厂商把前端题考出了什么味道

先说结论:奇安信这份前端试卷,整体难度在中上水平,覆盖面很广,但它的重点不在"偏难怪",而在"基础是否扎实+有没有安全敏感度"。

和阿里、字节那种动辄让你手写 Promise.all、实现一个 mini Vue 的试卷不同,奇安信2020年秋招前端方向试卷2更多在考三件事:

  1. 你对前端基础(HTML/CSS/JavaScript/网络)的理解是否成体系;
  2. 你在编码过程中有没有考虑边界条件、异常输入、安全问题;
  3. 你对安全类漏洞(XSS、CSRF、路径遍历、SQL注入等在Web前端的表现)有没有基本概念。

这其实反映出安全类公司的前端岗位特点:你写出的页面可能影响的是政府客户、金融机构、大型企业,一旦出现 XSS 漏洞或越权访问,那就是安全事故。所以他们在笔试题里会有意识地用场景题去试探你是否具备"安全编码"的直觉。

我当时拿到试卷第一反应是:这不就是一份前端八股文加安全科普的混合体吗?但做完之后我意识到,恰恰是这种混合风格,能区分出"背题党"和"真正写过项目并且思考过为什么的人"。

1.2 考点分布与各模块占比参考

根据我做题时的记忆,这份试卷大致可以分成以下几个模块,我结合当年讨论群里同学们的反馈,整理了一个考点占比参考:

模块大致占比典型考点
HTML/CSS 基础15%语义化标签、盒模型、BFC、flex 布局
JavaScript 核心30%事件循环、闭包、原型链、异步编程、手写代码
浏览器与网络15%缓存策略、HTTP 状态码、浏览器渲染流程
安全相关25%XSS、CSRF、路径遍历、输入校验、CSP
框架与工程化10%Vue/React 生命周期、组件通信、构建工具理解
开放题5%项目描述、性能优化思路

注意,安全相关占了四分之一,这个比重在别家互联网公司的前端试卷里很少见。这意味着如果你投的是奇安信这类安全厂商,复习时需要额外准备 Web 安全基础,而不是只刷 LeetCode 和 Vue 源码。

2. 基础技术考点详解:从HTML到JavaScript的核心题

2.1 HTML与CSS考点:别在这种题目上丢分

试卷里 HTML/CSS 的题目不算难,但很考察你有没有真正理解"标准"。我印象比较深的几个考点:

第一个是语义化标签。题目会给出一段结构混乱的 HTML,让你用合适的语义化标签重构,并解释为什么要用<header><nav><main><article><aside><footer>而不是一堆<div>。这种题很多人觉得简单,其实答好不容易。你需要从三个层面答:

  • 可访问性:屏幕阅读器依赖语义化标签理解页面结构;
  • SEO:搜索引擎爬虫对有语义的标签更友好;
  • 代码可维护性:团队其他人看到标签就能猜到内容作用。

第二个是盒模型计算。题目大概长这样:一个宽度为 300px 的元素,设置了padding: 20px; border: 5px solid; box-sizing: content-box;问实际占位宽度是多少。答案很简单:300 + 20×2 + 5×2 = 350px。关键是你要解释清楚 content-box 和 border-box 的区别,以及什么时候用哪种更合适。我当时在回答里补了一句"全局设置 border-box 可以降低布局心智负担,但要注意第三方组件样式可能会被影响",这属于加分细节。

第三个是 BFC(块级格式化上下文)。它会问你如何触发 BFC,以及 BFC 有哪些作用。触发方式包括overflow: hidden、float: left/right、position: absolute/fixed、display: inline-block/flex/grid等。作用有三个核心:清除浮动、防止 margin 塌陷、阻止元素被浮动元素覆盖。刷过面经的同学基本都能答出来,但要拿高分得补充"现代布局中 flex/grid 已经取代了大量 BFC hack 的需求,但理解 BFC 能帮你排查老旧项目中的样式 bug"。

CSS 部分还有个 flex 布局题,通常是让你用 flex 实现一个经典布局:左侧固定 200px,右侧自适应。核心代码是父容器display: flex,左侧width: 200px; flex-shrink: 0,右侧flex: 1。注意flex-shrink: 0这一点很容易漏,不加的话宽度不够时左侧会被压缩。

2.2 JavaScript核心题:事件循环、闭包与原型链

JavaScript 部分是整张试卷的重头戏,题型以选择、简答和手写代码为主。我挑几个典型题目展开说。

事件循环是必考的。它通常会给你一段代码,让你写出输出顺序,类似:

console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');

正确答案是:script start、script end、promise1、promise2、setTimeout。答题时要画清楚宏任务和微任务的执行顺序:同步代码先执行,微任务在每一个宏任务结束后清空,promise.then 属于微任务,setTimeout 属于宏任务。这里有个细节值得补充:Promise.resolve().then的回调是微任务,而new Promise(executor)里的 executor 是同步执行的,这两者经常被混淆。

闭包的考点也很经典。题目通常会问:什么是闭包?闭包有什么作用?有什么缺点?然后让你写出一个用闭包实现私有变量的例子。

function createCounter() { let count = 0; return { increment() { count++; return count; }, decrement() { count--; return count; }, getCount() { return count; } }; } const counter = createCounter(); console.log(counter.increment()); // 1 console.log(counter.increment()); // 2 console.log(counter.getCount()); // 2

我建议把闭包的作用答全:数据私有化、柯里化、函数工厂、在循环中保存变量快照。缺点也要提:可能导致内存常驻,如果闭包引用了较大的对象且没有被释放,会造成内存泄漏。

原型链的题目通常是给一个对象,问obj.__proto__、Constructor.prototype、Object.getPrototypeOf()之间的关系。还会考 instanceof 的原理:遍历右侧构造函数的 prototype 对象,看是否存在于左侧对象的原型链上。

这类题目没有捷径,只能把原型链的图盯熟。我自己的记忆方法是一句话:实例的__proto__指向构造函数的prototype,构造函数的prototype的__proto__指向Object.prototype,Object.prototype的__proto__是null。

2.3 手写代码题:边界条件是分水岭

手写题是前端笔试拉开差距的地方。奇安信这份试卷里有几个手写题,难度中等,但边界条件很坑。

第一个是手写防抖和节流。基础的写法很多同学都能写出来,但要注意细节。

function debounce(fn, delay) { let timer = null; return function(...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args); }, delay); }; }

这里有个容易忽略的点:fn.apply(this, args)里的this必须保留,否则在对象方法上使用防抖时this会丢失。

第二个是手写深拷贝。注意它不只是让你用JSON.parse(JSON.stringify(obj)),因为这么考就没意思了。出题人期望你写出一个能处理基本类型、数组、普通对象、Date、RegExp,并且能解决循环引用的版本。我当时的实现思路是用 WeakMap 存储已拷贝的对象,遇到循环引用时直接返回缓存。

function deepClone(obj, map = new WeakMap()) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags); if (map.has(obj)) return map.get(obj); const clone = Array.isArray(obj) ? [] : {}; map.set(obj, clone); for (const key of Object.keys(obj)) { clone[key] = deepClone(obj[key], map); } return clone; }

写完之后我特意在试卷旁边注释了:Object.keys不会遍历继承属性,Symbol 类型的 key 用Object.getOwnPropertySymbols单独处理。虽然可能超纲,但能让阅卷人看到你的知识深度。

第三个是数组去重。常规答法是[...new Set(arr)],但如果题目补充了一句"要求兼容对象数组",那就要小心了。对象数组按引用去重通常没意义,需要按某个唯一字段去重。这部分我会在后面的"常见问题"里专门展开。

3. 安全方向考点:奇安信笔试中最特别的25%

3.1 XSS与CSRF:前端安全必考双雄

安全类公司笔试前端方向,XSS 和 CSRF 如果不出,那基本是不可能的。奇安信更是一道题都没落下,而且考查方式不是简单的名词解释,而是给你一段代码,让你找出漏洞并说明修复方案。

先看 XSS。题目一般会给出这样的代码:

const userInput = getUrlParam('name'); document.getElementById('welcome').innerHTML = '欢迎你,' + userInput;

漏洞点一目了然:用户输入未经任何处理直接拼进 innerHTML,攻击者可以通过?name=<script>alert(document.cookie)</script>执行任意脚本。

修复方案要分层来答:

  • 第一层:对输入进行编码,把<、>、&、"、'转义为 HTML 实体;
  • 第二层:优先使用textContent替代innerHTML,从源头避免 HTML 注入;
  • 第三层:设置 CSP(内容安全策略),限制脚本来源,即使被注入也无法加载外部恶意脚本。

如果你只是答"过滤一下"或者"用正则替换",那基本只能拿一半分。出题人想看的是你有没有完整的纵深防御意识。

再来看 CSRF。题目会问:什么是 CSRF?它和 XSS 有什么区别?如何防御?

CSRF 的核心是利用浏览器自动携带 Cookie 的特性。攻击者构造一个恶意页面,诱导用户点击,浏览器会自动带上用户的登录态,向目标站点发送请求。因为请求来自受信任的浏览器,服务器无法区分这是用户主动操作还是攻击者伪造的。

防御方案有三个主流方向:

  1. 校验 Referer/Origin 头,拒绝来自非白名单域名的请求;
  2. 使用 CSRF Token,在请求中加入随机的 token,服务器端校验;
  3. 关键操作使用自定义请求头,比如X-Requested-With: XMLHttpRequest,因为跨域请求无法自定义头部。

这里有个容易混淆的点:XSS 是"我信任了用户的输入",CSRF 是"我信任了用户的浏览器"。前者攻击代码注入到页面里执行,后者是伪造用户身份发起请求。把这两个概念区分清楚,面试官印象分会高不少。

3.2 路径遍历和输入验证:安全厂商的特色考题

很多前端同学做奇安信的题会死在这一块,因为普通互联网公司真的不考路径遍历。但是对安全厂商来说,Web 攻击面里路径遍历(Path Traversal)太常见了,所以它出现在前端试卷里也不奇怪。

题目大概是这样的:你写了一个文件预览功能,把用户传入的文件相对路径拼到静态资源服务器地址上,比如:

const path = req.query.filePath; const fullPath = '/var/www/files/' + path;

如果用户传入../../../../etc/passwd,然后 Node.js 后端直接拼接路径读取文件,那就能读到系统敏感文件。作为前端,虽然你只是拼接 URL,但你要能识别出这种风险。

答题要点包括:

  • 路径遍历的本质是对输入校验不严,导致攻击者可以通过../跳出预期目录;
  • 前端需要在入口处拦截包含..的路径,以及%2e%2e(URL 编码后的点号)、%252e(双重编码)等变体;
  • 更可靠的做法是服务器端规范化路径后再做前缀检查,不能只依赖前端过滤;
  • 可以提到使用path.normalize()和path.resolve()把路径转换成绝对路径,然后判断是否以允许的根目录开头。

当时这道题我还答了一个思路:用白名单校验而不是黑名单过滤。因为黑名单很难覆盖所有编码变体,而白名单直接把允许的路径模式写死,不匹配的直接拒绝,更安全。

输入验证的题目也和这个相关。它会问:如何设计一个安全的登录表单前端?涉及的考点包括:

  • 前端不能只做非空校验,还要对邮箱格式、密码强度做预校验;
  • 密码不能在前端做加密后传给后端,因为前端加密不是真正的加密,只是混淆,必须依赖 HTTPS;
  • 对用户输入的长度做限制,防止超大 payload 打垮后端;
  • 登录接口要加验证码或频率限制,防止暴力破解;
  • 前端不要拼 SQL、拼 shell 命令,统一使用参数化查询。

这些内容单独看是安全知识的科普,但结合奇安信的业务背景,它们恰恰是入职后写内部后台系统时天天会遇到的问题。

3.3 安全厂商前端笔试的加分答法

我总结一下,安全厂商的前端笔试里,代码题只要沾边安全的,都有一种"加分答法"。

比如题目只是让你实现一个图片上传组件。普通答法是讲 FormData、进度条、缩略图预览、大文件断点续传。但是安全向的加分答法会额外提到:

  • 上传前要做文件类型校验,除了看后缀名,还要读取文件头魔数(Magic Number)判断真实类型,防止绕过后缀检查;
  • 上传接口要限制文件大小和并发数量;
  • 预览时使用URL.createObjectURL而不是FileReader,性能更好而且对内存更友好;
  • 如果服务端预览是直接拼接文件名拼接 URL,需要考虑路径穿越问题。

再比如让你实现一个富文本编辑器,普通人只聊 contenteditable 和 document.execCommand;加分答法会提到 XSS 的富文本绕过问题:粘贴进来的内容不能直接渲染,需要做白名单标签过滤,保存时要对 HTML 进行清洗(sanitize),展示时要执行 CSP。

这种答题思路的核心是:把安全思维嵌入到每一个功能设计里,而不是把安全当作一个独立模块。这个习惯,也确实帮我后来在工作里少踩了不少坑。

4. 框架与工程化考点:Vue、React和性能优化怎么答

4.1 Vue/React相关题目:生命周期与组件通信

2020年秋招时,Vue 2 还是主流,React 16.8 也已经普及了 Hooks。奇安信的试卷在框架方面考得不算深,主要停留在"是否真的用过"这个层面。

Vue 的题目通常是让你简述 Vue 2 的生命周期,以及created和mounted的区别。这题的关键是答出每个生命周期适合做什么:

生命周期钩子适合做的事不适合做的事
beforeCreate初始化非响应式数据拿不到 this.data
created请求接口、初始化数据操作 DOM,因为 DOM 还没挂载
mounted操作 DOM、初始化图表库长时间同步逻辑,会阻塞首屏渲染
beforeDestroy清理定时器、解绑事件访问响应式数据

created和mounted的区别要讲清楚:created时模板还没渲染成 DOM,this.$el拿不到;mounted时组件已经挂载到页面上,this.$el可以拿到。所以如果需要初始化 echarts 这类依赖 DOM 的库,必须在 mounted 里做。

组件通信的题也比较常规,问你父子组件、兄弟组件、跨层级组件怎么通信。答案是分层的:父传子用 props,子传父用$emit,兄弟组件用事件总线或者状态管理,跨层级用 provide/inject 或 Vuex。如果面试官要求手写代码,一般写一个$emit触发父组件事件的例子就够了。

React 的题目大概率会围绕 Hooks 展开,比如useEffect依赖数组的作用,以及useCallback和useMemo的区别。核心考点是:useEffect的依赖数组为空时,回调只在挂载后执行一次;依赖数组变更是浅比较,引用类型要特别注意。useCallback缓存函数引用,useMemo缓存计算结果,别把两者搞混。

我当时在这类题目上花的时间不多,因为框架题只要用过基本都能答。真正拉开差距的是下一节提到的性能和浏览器原理题。

4.2 浏览器渲染与性能优化:一道题能答出三个层次

浏览器相关的题目,一般是:从输入 URL 到页面显示,中间发生了什么?这道题能考出一个人对前端理解的深度,也很能反映日常写代码时有没有全局观。

第一层答法是八股文标准版:DNS 解析、建立 TCP 连接、发送 HTTP 请求、服务器返回 HTML、浏览器解析 HTML 生成 DOM 树、解析 CSS 生成 CSSOM 树、合并生成渲染树、布局、绘制。这一层能拿基础分。

第二层要补充细节,比如:

  • DNS 查询有本地缓存和递归查询,现在还用上了 DoH(DNS over HTTPS);
  • TCP 连接在 HTTPS 下要先做 TLS 握手;
  • HTML 解析过程中遇到<script>标签会阻塞渲染,所以脚本要加defer或async;
  • CSS 默认不会阻塞 DOM 解析,但会阻塞渲染,因为渲染树需要 CSSOM;
  • 现代浏览器有预加载扫描器(preload scanner),会提前发现资源并下载。

第三层要结合实际业务场景,说明页面性能瓶颈在哪里、怎么优化。我当时用了一个对比示例:一个首屏必须显示图片的页面,<img>标签上没加loading="lazy",也没配宽高,结果图片加载导致布局偏移(CLS)严重,页面在弱网下白屏时间很长。优化方案是:图片用 CDN 并开启 WebP 格式,按屏幕尺寸做多分辨率适配,核心图片预加载,非核心图片懒加载。

还有一道性能优化题让我印象很深,题目是:一个页面加载了 20 个第三方 SDK,导致首屏时间从 1.2 秒变成 3.8 秒,如何排查和优化?

我的答题思路分四步:

  1. 优先用 Performance 面板看网络瀑布图,找出哪些 SDK 是渲染阻塞的;
  2. 确认哪些 SDK 是首屏必需的,非必需的异步加载;
  3. 用浏览器原生能力替代部分第三方 SDK,比如用 IntersectionObserver 替代 lazy-load 库;
  4. 聚合多次请求:多个 SDK 如果功能相似,只保留一个,或者用服务端拼包的方式减少请求数。

效果是首屏时间可以压回 1.5 秒以内。这道题说白了就是在考你有没有真实做过性能优化,而不是只会背"减少 HTTP 请求、启用压缩、使用 CDN"这三板斧。

4.3 构建工具与组件库:工程化基础题

工程化方面,奇安信的试卷没有考 Webpack 源码级配置,更多是问概念和常用的优化手段。比如问你:Webpack 打包速度慢,你会从哪些方向优化?

常规答法是先分层次:

  • 优化 loader 范围,用include限定 src 目录,排除 node_modules;
  • 使用cache-loader或持久化缓存,二次打包提速明显;
  • 开启thread-loader或parallel-webpack并行构建;
  • 使用DllPlugin预编译不常变动的依赖包,但要注意它现在已经不是最推荐的方案了;
  • 开发环境用devServer的hot: true,减少全量编译。

要注意的是,如果试卷时间已经到了2022年之后,最好补充 Vite 的思路:开发阶段用原生 ESM 按需编译,避免 Webpack 冷启动和热更新慢的问题。2020年的时候 Vite 还算新东西,提一句"我关注到 Vite 可以解决 Webpack 开发服务器的瓶颈"就已经很出彩了。

组件库的问题,热词里有"前端组件库"。它一般会问:你们项目里是怎么封装组件库的?或者让你设计一个可复用的弹窗组件(Modal),需要考虑哪些问题?

设计弹窗组件的答案框架可以这样搭:

  • Props 设计:visible、title、width、footer、closeOnClickModal、confirmLoading;
  • 事件设计:confirm、cancel、open 后的事件;
  • 插槽设计:允许自定义内容、底部按钮区、标题;
  • 功能细节:点击遮罩是否关闭、是否支持 Esc 关闭、弹窗出现后 body 滚动是否锁定、弹窗的层级管理、多弹窗共存时的 z-index 处理;
  • 无障碍:焦点陷阱(focus trap),关闭后焦点是否回归到触发元素。

如果是在安全厂商面试,可以额外补充:弹窗中的富文本内容需要清洗,防止 XSS;按钮的 loading 状态要防止用户重复提交。

5. 笔试实战经验:时间分配与常见坑

5.1 时间分配与答题顺序策略

奇安信这套试卷,正常水平做完大概需要 90 到 120 分钟。我当时花了 110 分钟左右,其中选择题 20 分钟,简答题 40 分钟,手写代码题 30 分钟,开放题 20 分钟。

一个很实用的策略是:先做选择题,尤其是那些一眼就能确认答案的题,用最短的时间拿下基础分。然后做简答题,优先答你熟悉的知识点,把能拿的分先拿到。手写代码题放在中间偏后,因为它最耗时间,而且一旦卡住很容易影响心态。最后留充足时间给开放题,因为开放题往往是最能体现工程经验的,值得多写几句。

我强烈建议不要在一道选择题上纠结超过 3 分钟。2020年我有个同学就栽在了一道关于 HTTP 状态码的题上,他反复怀疑自己是记错了 304 还是 301,结果花了 10 分钟,后面手写题时间不够,最后把debounce都写错了。这种损失非常不值得。

判断题里还有一种常见坑:题目问let和var的区别,选项里有一项说"let 可以在声明之前使用"。这是错的,let 存在暂时性死区(TDZ),声明之前访问会报 ReferenceError。而var声明之前访问到的是 undefined。这类题就是用来筛掉基础不牢的人。

5.2 常见问题与排查技巧实录

我在做这套题和复盘其他人的反馈时,收集了一些容易出错的地方,整理成速查表:

题目/考点容易踩的坑参考答案要点
事件循环题忘记await后面是微任务但需要额外宏任务切换async function体内await会暂停,await Promise.resolve 后面的代码属于微任务
深拷贝只处理普通对象,没考虑 Date/RegExp/循环引用用 WeakMap 缓存引用,特殊类型单独处理
路径遍历只知道过滤..,没考虑 URL 编码变体服务端规范化后用白名单前缀校验
防抖节流丢失this指向用fn.apply(this, args)保留
HTTP 缓存混淆强制缓存和协商缓存Cache-Control: max-age是强制缓存,ETag/Last-Modified是协商缓存
Promise忘记 executor 同步执行new Promise((resolve) => console.log(1))会立即打印 1
flex 布局固定栏没加flex-shrink: 0防止被压缩,右侧自适应区域用flex: 1
Vue 生命周期在 created 里操作 DOM 拿不到元素created 适合初始化数据,DOM 操作放 mounted
XSS 修复只做输入过滤,没做输出编码和 CSP纵深防御:输入编码 + 优先 textContent + CSP
数组去重对象用Set直接去重对象数组无效按唯一字段手动去重,或先序列化再 Set

除了这张表,还有一个值得单独说的:数组去重,看起来是最简单的题,但碰到对象数组就翻车了。

比如你有这样一个数组:

const arr = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 1, name: 'Alice' } ];

直接[...new Set(arr)]是没用的,因为 Set 比较的是引用,两个对象即使内容相同也认为是不同的。正确做法是按 id 字段去重:

const map = new Map(); arr.forEach(item => map.set(item.id, item)); const uniqueArr = [...map.values()];

这里有个陷阱:Map的 key 如果传对象,那还是按引用比较,必须传基本类型字段。我当时看到一个同学写的是map.set(item, item),那和不去重没区别。这种细节就是在考你"是不是真的写过代码"。

5.3 安全向附加题:CSP配置与上报思路

热词列表里反复出现"奇安信代码卫士""路径遍历",说明现在的安全团队对前端代码质量检查已经非常关注了。如果这套试卷放到今天来出,很可能会增加 CSP 配置和异常上报的题目。

CSP(Content Security Policy)是防御 XSS 的最后一层防线。它的配置方式是在 HTTP 响应头里加一个字段,或者用<meta>标签指定。简单的配置长这样:

Content-Security-Policy: default-src 'self'; script-src 'self' cdn.example.com; style-src 'self' 'unsafe-inline'

这段配置的意思是:所有资源默认只能从本站加载,脚本可以加载本站和 CDN 域名,样式允许本站和内联样式。如果页面里有人插入了一个https://evil.com/x.js,浏览器会直接拦截并报错。

如果你在做这套题的时候能主动提到 CSP 的线上配置技巧,比如"开发环境要用unsafe-inline,生产环境必须收紧",那显然比只答"用 CSP 防止 XSS"高一个段位。

另一个安全厂商比较喜欢问的附加方向是前端错误上报。因为安全事件通常是从异常行为开始的。怎么做前端错误监控,答案可以包括:

  • 用window.onerror捕获未处理的 JS 错误,拿到 message、source、lineno、colno、error 对象;
  • 用unhandledrejection捕获 Promise 异常;
  • 对错误对象做序列化,因为 Error 的属性默认不可枚举,需要手动提取 name、message、stack;
  • 上报时带上用户操作上下文:路由、组件名、HTTP 请求参数(脱敏后)、浏览器信息;
  • 采样率控制:错误上报不能全部上报,否则高并发场景下上报接口会被打爆,一般取 10% 并做 hash 去重。

当时我看到试卷里有一道开放题:"假设你负责的前端项目在客户现场经常白屏,你如何排查?"这道题我答了六个步骤:先分环境(客户环境 vs 内网环境)、看浏览器版本兼容性、看控制台报错、看接口请求是否被拦截(客户网络策略可能导致接口不可达)、看资源是否加载失败(尤其本地部署的项目,静态资源路径可能不对)、最后用远程日志定位。这套思路其实就是前端异常排查的标准流程,放在安全厂商语境下,还要额外关注是否有安全策略拦截了某些请求。

6. 给准备校招前端岗的同学:刷题之外的建议

聊完具体的考题,再聊一点更重要的东西。奇安信这份试卷,包括其他安全厂商的前端笔试题,本质上都在传递一个信号:他们缺的不是会写页面的人,而是写代码时自带安全敏感度的前端。

那这种安全敏感度怎么培养?我给你两条实际可操作的建议。

第一条,把你的个人项目加一些安全改造。比如你写了一个博客系统,把其中的评论功能做一个 XSS 过滤和输出编码;把文件上传功能加上类型校验和大小限制;用 CSP 头保护一下页面。做完这些,简历上就可以写"实现前端安全加固"这几个字,面试时也能拿出真实案例来讲,比你背十遍"什么是 XSS"有用得多。

第二条,刷前端面试题时,把"边界条件"当成一等公民。很多笔试手写题,能写出来是基本分,能处理边界条件是加分项,能解释为什么这么处理边界条件是高分项。比如写一个深拷贝,同步说出循环引用问题;写一个防抖,主动说明 this 绑定的坑;写一个上传组件,主动提到超时重试和大文件分片。这些细节加在一起,阅卷人对你的评价就是一个层次。

关于复习资料,我建议不要只看面经,面经只能帮你查漏,不能建立知识体系。你还是要花两周时间把《JavaScript高级程序设计》里的原型、闭包、异步、事件循环这几章重新过一遍,再用一周时间补一下 Web 安全基础,推荐的入门路线是:OWASP Top 10 的每个漏洞都看一下漏洞描述和修复方案,配合 ctf-wiki 上的 Web 入门题做两三道。

当然,2020年这套试卷已经有点年头了,现在的笔试难度和考点肯定有变化。但有一点始终不变:基础扎实、代码规范、有工程意识的人,不管面试哪家公司,拿到 offer 的概率都比只会背题的人高很多。

最后再分享一个我自己实际踩过的坑。笔试的时候我有一道手写题写得很顺手,防抖节流、深拷贝、数组去重全都写得很流畅,但我栽在一个我没当回事的简单考点上:HTTP 状态码 301 和 302 的区别。我当时想当然地写"301 是临时重定向,302 是永久重定向",正好搞反了。这直接导致笔试排名降了一截。所以我想跟各位说的是:刷题的时候别只刷难题,基础概念反而要多默写几遍,因为你最容易在心里写"我知道",可一旦要落到笔头上,模糊的记忆就是致命的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询