秋招前端笔试这一关刷人从来不在“难”而在“广”和“细”。2023年掌阅科技秋招前端岗的笔试我是在一个周六下午做的全程线上双机位限时60分钟。这套题给我的整体感觉是不偏不怪但每一道题都卡在“你平时以为自己会、实际一写就露馅”的位置上。尤其是那些手写代码题考的全是日常开发里高频使用、却很少系统梳理过的能力——数组去重、防抖节流、Promise并发控制、简易版Vue响应式。如果你正打算投阅读/内容类互联网公司的前端岗这套题的复习方向很有参考价值。这篇就按笔试题型逐块拆解把核心考点、答题思路和踩坑点一次讲透。1. 笔试整体印象题量、时长与考察范围1.1 试卷结构与时间分配先说这套卷子的基本面。2023年掌阅科技秋招前端岗笔试采用的是牛客网在线笔试系统总共四大块单选、多选、两道手写编程题、一道简答题。总时长60分钟题量在35道左右。乍一看题量不大但实际做起来时间非常紧张原因是选择题里有一大半都带“坑”需要反复斟酌编程题又要求你写得完整、能跑、边界条件考虑周全。从内容分布来看JavaScript基础占了约40%CSS和浏览器相关约25%Vue框架和工程化约20%网络与安全约10%剩下5%是开放性的场景题。这个比例和大多数中小型互联网公司前端笔试的画像高度重合。你要注意掌阅科技是做阅读类App和Web端产品的技术栈以Vue为主所以框架题里Vue的权重明显高于React但也不是完全不考React——多选题里就出现了一道React Hooks闭包陷阱的辨析。时间分配上我的策略是选择题控制在35分钟以内编程题每题10到12分钟最后留5分钟检查边界情况。实测下来这个节奏刚好够用如果你在选择题上恋战后面编程题必然写不完。1.2 从题目反推的产品与技术选型直觉做这套笔试有一个很明显的体感出题人不是从题库里随机抽题而是结合了掌阅自身业务场景来选的。比如选择题里有一道关于“大文件分片上传”的考点还有一个关于“H5页面在弱网环境下的优化手段”的多选——这两个方向做阅读类产品的前端几乎天天都要碰。再比如简答题让你设计一个“阅读进度同步方案”要求考虑多端App、Web、小程序之间的进度一致性。这种题纯粹靠背八股文是答不好的你得有真实的项目经验来支撑方案的取舍逻辑。所以我的判断是掌阅笔试并不是想要招“刷题机器”而是想要招“上来就能干活、知道业务里有哪些真实坑”的前端工程师。这也给你提了个醒准备笔试不能只看知识点本身还要把知识点往业务场景上靠。比如学了HTTP缓存就想想“为什么阅读App的书籍封面图要设很长的Cache-Control”学了懒加载就想想“长篇小说目录几百个章节DOM怎么渲染才不卡”。这种思维方式才是做这套题的正确打开姿势。2. 核心考点逐题拆解八股文里面的“暗坑”2.1 JavaScript闭包、事件循环与异步编程JavaScript部分的选择题几乎把前端面试里最经典的几个“送命题”都包圆了。闭包、事件循环、原型链、this指向、变量提升这些是基础中的基础但出题人会在题干里埋各种视觉陷阱。有一道题我印象特别深给你一段代码for (var i 0; i 5; i) { setTimeout(() { console.log(i); }, 100); }问你输出什么。如果只背过“var是函数作用域”这个结论你可能会说输出0到4但正确答案是5个5。原因在于var声明的i是函数作用域循环结束后i的值已经是5而setTimeout的回调是在循环结束后才执行的此时访问到的i是同一个变量所以打印的全是5。如果你把var换成let每次循环都会创建一个新的块级绑定输出才会是0、1、2、3、4。这道题的变体还有用闭包包一层马上执行函数来固定每次循环的值本质都是考察对“变量作用域异步执行时机”的理解。事件循环的题也考得很细。我记得有一道多选给了setTimeout、Promise.resolve().then()、async/await、requestAnimationFrame四种异步任务问你它们在事件循环里的执行顺序。正确的理解是Promise的回调和async函数里await后面的代码都属于微任务microtask会在当前宏任务执行完后、下一个宏任务之前全部清空setTimeout和requestAnimationFrame属于宏任务macrotask每次事件循环只取一个执行。所以如果同一轮里有微任务又有宏任务微任务永远先跑完。这个知识点如果你只是背结论不自己写代码验证几遍一到考场上就会在选项之间犹豫。2.2 CSS与布局从盒模型考到BFCCSS题量不大但每一道都踩在“常用但容易忽略”的细节上。盒模型是必考的box-sizing: border-box和content-box的区别你光会背不够还得知道在什么场景下切换——比如做移动端适配时全局设置border-box能让宽度计算更直觉避免因为加上padding或border导致元素溢出父容器。笔试里这道题给了一个width: 200px; padding: 20px; border: 5px solid;的盒子问你content-box下实际占位宽度是多少答案是250px还是200px要看题干怎么问如果问渲染出来的总宽度是200 20*2 5*2 250px如果问内容区域宽度就是200px。这种表述上的细微差异就是选择题的“坑”所在读题时必须逐字看。BFCBlock Formatting Context也考了一道题目大概是“下列哪些方式可以触发BFC”。overflow: hidden、display: inline-block、position: absolute/fixed、display: flex都可以触发但display: block不行position: static/relative也不行除非配合z-index。考BFC的本质是考你对“文档流、浮动塌陷、外边距折叠”这三个常见布局问题的理解。比如子元素全部float导致父容器高度塌陷给父容器加overflow: hidden触发BFC就能包住浮动元素再比如上下两个子元素的margin发生了重叠用BFC隔离其中一个就能避免。这些细节笔试不会让你写代码但你得能在选项里把“哪段代码能解决哪个问题”精准匹配上。还有一个高频考点是垂直居中。笔试里给了至少三种方案来判断对错flex加align-items: center和justify-content: center、position: absolute加top: 50%配合transform: translateY(-50%)、display: grid加place-items: center。这三种都能实现居中但要注意absolute方案里父元素必须有position: relative而且translate百分比是相对自身尺寸计算的所以就算不知道子元素宽高也能居中。多选题里还有一种错误选项是用text-align: center配合vertical-align: middle这个对块级元素无效是常见混淆项。2.3 框架与工程化Vue问题为主React也有涉及Vue部分的选择题明显是结合了实际项目开发经验来出的不是单纯背生命周期钩子就能全对。生命周期那道题问你“在Vue 2中mounted钩子里能访问到this.$el吗”答案是可以因为mounted阶段DOM已经挂载完成你在created里访问this.$el会是undefined这俩太容易被新手搞混了。Vue 3的组合式API里对应的是onMounted同样保证在组件挂载后执行。数据响应式也是必考。Vue 2用的是Object.definePropertyVue 3用的是Proxy两者的核心区别你要说得清楚Object.defineProperty只能劫持单个属性的读取和赋值所以新增属性和删除属性都不会触发更新才需要Vue.set和Vue.delete来补救而Proxy是代理整个对象新增、删除、读取、赋值都能拦截这就是Vue 3响应式更完整的原因。笔试里给了一个场景“给Vue 2的data对象动态新增一个属性页面会不会更新”正确答案是不会必须用Vue.set(obj, key, value)或者把整个对象重新赋值。这个考点太经典了我建议你复习时一定要写个小demo验证一遍。React那道多选也很有代表性考的是useEffect的依赖数组。题目给了一段代码const [count, setCount] useState(0); useEffect(() { console.log(count); }, []);问点击按钮把count从0变成1后控制台会打印什么答案是“什么也不会打印”因为依赖数组是空的useEffect只在组件挂载时执行一次后续count变化不会触发它重新执行。这道题考的就是Hooks闭包陷阱的变体——如果你在useEffect里访问了外部变量但没把它列入依赖就会拿到闭包捕获的旧值。这类题目在2023年的笔试里已经非常高频因为很多前端开发从Vue转React或者两个框架混用容易把Vue的“自动追踪依赖”直觉带到React里。工程化的考点集中在Webpack和模块化上。有一道题问import和require的区别正确答案要包含import是ES6语法静态分析编译时执行支持tree-shakingrequire是CommonJS规范动态加载运行时执行。还有一个选项说“import可以在条件语句里使用”这是错的import必须位于模块顶层require才能放在if块里。这些点如果你没用过Webpack仔细看过打包产物很容易选错。2.4 浏览器网络与安全HTTP缓存、XSS与CSRF网络与安全的题目数量不多但分值密度高因为这类题往往带实际场景。HTTP缓存那道题问的是“强缓存和协商缓存分别由哪些HTTP头控制”。强缓存是Cache-Control和Expires其中Cache-Control的max-age单位是秒优先级高于Expires协商缓存是Last-Modified/If-Modified-Since和ETag/If-None-Match。这里有一个很容易踩的坑Cache-Control: no-cache不是“不缓存”而是“每次都要向服务器验证缓存是否新鲜”也就是走协商缓存的逻辑真正不让缓存的是no-store。笔试里就故意把这个选项的注释写成了“完全不使用缓存”很多考生一看no-cache字面意思就直接选了结果丢了分。XSS和CSRF也考了一道多选。对于XSS题目问“下列哪些方式可以防御XSS”对用户输入做HTML转义、使用CSP内容安全策略、对富文本内容做白名单过滤、使用HttpOnly的Cookie。前三个都对第四个是干扰项——HttpOnly确实能防止脚本通过document.cookie读取Cookie但它防的是XSS攻击后的“窃取会话”环节并不能阻止XSS本身的发生。这个概念区分对做题很重要。CSRF的防御则主要是SameSite属性、校验Referer/Origin、增加CSRF Token、双重Cookie验证等“在Cookie上设置Secure属性”是防止传输中被窃听和CSRF防御没有直接关系属于选项里的混淆项。3. 编程题实战从读题到AC的全过程3.1 编程题一实现防抖函数和节流函数笔试第一道编程题就是手写防抖和节流这也是前端笔试最高频的手写题之一没有悬念。题目要求实现一个debounce函数和throttle函数要求支持leading首次是否立即执行参数并且要能返回一个取消执行的方法。我的实现思路是这样的。防抖的核心逻辑是“每次触发都重置计时器”所以函数内部用一个timer变量保存setTimeout的句柄function debounce(fn, wait 300, leading false) { let timer null; let isInvoked false; // 记录leading模式下是否已经执行过 const debounced function (...args) { // leading模式第一次触发时立即执行 if (leading !isInvoked) { fn.apply(this, args); isInvoked true; } if (timer) { clearTimeout(timer); } timer setTimeout(() { fn.apply(this, args); isInvoked false; // 重置让下一次连续触发能重新走leading }, wait); }; debounced.cancel function () { if (timer) { clearTimeout(timer); timer null; } isInvoked false; }; return debounced; }这道题里必须注意两个细节。第一fn.apply(this, args)里的this一定要透传否则在对象方法上使用防抖时this会指向window第二是leading为true时要保证“第一次触发立即执行后续连续触发不执行等到停止触发且wait时间结束后下一次触发才再次立即执行”所以我在setTimeout回调里把isInvoked重置为false。笔试时我见过很多人只写了leading的立即执行却忘了重置导致第二次连续触发时不会立即执行这个细节就扣了不少分。节流的核心逻辑是“固定时间间隔内最多执行一次”。我用的实现是时间戳版本立即执行型function throttle(fn, wait 300, leading true) { let previous 0; const throttled function (...args) { const now Date.now(); if (leading) { // 首次触发时 previous 为0now - previous wait 必然成立会立即执行 if (now - previous wait) { fn.apply(this, args); previous now; } } else { // 非leading模式用previous记录最后一次执行的时间 // 这里简化为每次都要等wait实际项目中可根据需求混合两种模式 if (!previous) previous now; if (now - previous wait) { fn.apply(this, args); previous now; } } }; return throttled; }时间戳版适合“滚动监听、点击事件”这类需要跟手场景setTimeout版适合“拖拽结束、输入结束”这类需要延迟的场景。笔试时我建议你把两种版本都写清楚并且在注释里说明各自的适用场景这样阅卷人能看出你不仅仅会背代码还理解背后的取舍。3.2 编程题二数组扁平化去重排序第二道编程题是一道“全家桶”题写一个函数输入一个多维数组输出一个扁平化、去重、按升序排序的一维数组。题型经典但要注意它同时考察了你是否会写reduce、Set和排序时的比较函数。我的写法如下function flattenAndSort(arr) { // 使用reduce递归扁平化layers参数控制展开深度 const flatten (list, depth Infinity) { return list.reduce((acc, item) { if (Array.isArray(item) depth 0) { return acc.concat(flatten(item, depth - 1)); } return acc.concat(item); }, []); }; const flatArr flatten(arr); // 去重使用Set然后转回数组 const uniqueArr [...new Set(flatArr)]; // 排序必须传比较函数否则默认按字符串排序 uniqueArr.sort((a, b) a - b); return uniqueArr; }这里有两个点非常容易出错。第一sort不传比较函数时数组元素会被转成字符串再按字典序排序比如[1, 20, 3]会排成[1, 20, 3]而不是[1, 3, 20]所以(a, b) a - b必须写。第二题目如果要求“只扁平化一层”你的递归就必须限制深度如果默认完全扁平化可以用Infinity。我建议你在函数签名里加一个可选的depth参数这样不管题目怎么变都能覆盖。还有一种更简洁的替代方案是用Array.prototype.flat(Infinity)做扁平化const flatArr arr.flat(Infinity);但笔试时我不太建议你直接用flat因为flat是ES2019的API某些低版本浏览器和旧的Node环境不支持更重要的是面试官想看的是你“会用递归和reduce实现”而不是“知道有个API”。你就当这个题考的是底层实现能力老老实实手写递归。3.3 编程题三Promise并发数限制第三道编程题是整套卷子里含金量最高的一道——实现一个控制并发请求的函数limitConcurrency(promises, limit)要求同时最多只有limit个Promise在执行所有任务完成后返回结果数组。这类题在2023年秋招笔试里出现频率极高因为它考察了异步编程中真正的难点并发控制。我的实现思路是用“队列空闲槽位”的方式。function limitConcurrency(tasks, limit) { return new Promise((resolve, reject) { const results []; let running 0; let index 0; let completed 0; function run() { // 所有任务已完成处理边界情况 if (completed tasks.length) { resolve(results); return; } // 空闲槽位且还有任务未启动时启动任务 while (running limit index tasks.length) { const currentIndex index; const currentTask tasks[index]; index; running; Promise.resolve(currentTask()) .then((res) { results[currentIndex] res; running--; completed; run(); // 当前任务完成后尝试启动新的任务 }) .catch((err) { reject(err); // 有一个失败就整体失败 }); } } run(); }); }这个实现的核心是run()函数内部的两个判断completed tasks.length判断是否全部完成一旦全部完成就resolvewhile循环里的running limit index tasks.length判断是否还有空余并发槽位。注意我用了一个currentIndex来记录每次启动任务时的索引这样异步结果才能按顺序放回results数组里而不是按完成先后顺序放——顺序正确对很多场景很关键。如果题目要求“失败后继续执行而不是整体reject”你可以在catch里把错误也存进results而不是直接reject.catch((err) { results[currentIndex] err; running--; completed; run(); });笔试时你可以先写整体reject的版本再在注释里补充“如果需要策略自选可改为容错模式”。这样能展示你考虑到异常路径是个加分项。3.4 简化版Vue响应式考察底层原理的动手能力这题是整张卷子里我最意外的一道也是一道综合的简答手写题。题目给你一个小型对象要你用Object.defineProperty实现一个简单的响应式系统当属性变化时自动执行副作用函数。我现场写的版本如下function observe(obj, onUpdate) { Object.keys(obj).forEach((key) { let value obj[key]; Object.defineProperty(obj, key, { get() { return value; }, set(newValue) { if (newValue value) return; value newValue; onUpdate(key, newValue); }, }); }); } const user { name: zhangyue, age: 3 }; observe(user, (key, newValue) { console.log(属性 ${key} 更新为 ${newValue}); }); user.age 4; // 控制台输出属性 age 更新为 4这道题的核心考点是你要理解Object.defineProperty的get/set机制知道闭包value变量在多次属性访问之间被共享并且能区分“值相等就不触发更新”和“值变了才触发更新”的边界。我还在代码里加了一个if (newValue value) return;的判断这个判断本身是优化点能避免无意义的重复渲染在Vue源码里也有类似的逻辑。如果你遇到这类题我建议你把Vue.set/Vue.delete的局限性也说明一下因为Object.defineProperty定义属性时只能对已存在的属性生效所以动态新增属性不会触发set这就是为什么Vue 2需要Vue.set。能讲清这一点基本就给阅卷人留下“他真的研究过Vue源码”的印象。3.5 简答题阅读进度同步方案与前端工程化实践最后一道简答题是开放性的“你负责的阅读类产品需要实现多端阅读进度同步进度数据存在服务端请设计一套前端方案。”要求给出具体实现思路并说明理由。这类题没有标准答案但你要展现出完整的思考链路。我的回答分了五层第一层是数据层面同步的核心字段是“书籍ID章节位置滚动偏移量时间戳”一次上报可以批量携带多本书的进度减少请求次数。第二层是时机层面不能每次滚动都上报那是灾难。我选择用“节流离开页面时强制上报进入下一章时上报”的组合策略阅读类产品还要特别注意App切后台、Web切Tab隐藏、小程序onHide这些生命周期时机都要兜底上报。第三层是网络层面弱网环境这是移动阅读的典型场景要支持失败重试、本地暂存、下次启动补交。可以用localStorage/IndexedDB暂存未上报的进度恢复在线后再同步。第四层是冲突处理多端同时阅读同一本书时进度以“时间戳最新”为准不能简单用“谁后报谁覆盖”。如果业务要更精细可加入版本号/递增序号机制。第五层是性能层面进度同步接口要防抖默认每10秒或每滚动2000px才上报一次同时要注意页面卸载时的sendBeacon或fetch keepalive避免请求被浏览器取消。我当时把这个方案拆成“定时节流兜底”三段式来讲阅卷人应该能看出我有真实项目经验不是单纯背方案。因为只有真实做过阅读类或内容型产品才会主动去考虑“用户在地铁里信号差”“用户切到后台再回来”“多端同时看同一本书”这些具体场景。4. 实操复盘做题顺序、时间管理与草稿纸用法4.1 60分钟试卷我是怎么分配时间的现在重点说下实战操作层面的东西。整套题60分钟我的分配是选择题35分钟编程题20分钟简答题5分钟。但这只是理想模型实际上选择题里个别题目犹豫太久编程题又因为调试占用了不少时间最后简答题我几乎是边想边打字。一个更稳妥的时间分配建议是先花1分钟通读整张试卷把每道大题的难度在心里排个序。我的做法是“先编程题、后简答题、最后啃选择题”。因为编程题分值高、容错率低必须保证有整块时间写选择题里有些绕圈的题放到最后如果时间不够可以快速蒙一个影响相对小。但要注意牛客网的在线考试一般允许你在各题之间跳转所以“跳题”的决策成本很低遇到卡壳的选择题果断标记后跳过千万别在单选题上耗超过3分钟。4.2 先拿稳分再冲难题的做题策略具体到做题策略上我总结了一个“三七法则”选择填空题里先做你有把握的题把能稳拿的分全部拿到手再回头处理模棱两可的选项编程题里先写能直接AC的暴力或简单实现把边界条件处理好再去优化时间/空间复杂度。这套策略的核心逻辑是秋招笔试不是竞赛你的目标不是拿满分而是“在有限时间内拿到尽可能多的通过率”。编程题尤其要警惕“想一把梭写出最优解”的心态。有一道题我一开始想用O(n)的滑动窗口但写着写着发现边界条件很复杂于是果断退回暴力解法——虽然时间复杂度高一些但正确性有保证笔试环境里“能跑对”永远比“跑得快”重要。暴力解拿到基本分后如果还有剩余时间再回去优化也不迟。4.3 在线笔试平台的常见操作坑最后提醒几个在线笔试平台特有的坑这些在平时刷题时很难遇到但考场上碰到了真的很伤。第一是代码编辑器默认没有自动补全。牛客网的编辑器有基础的高亮但不会像IDE那样帮你自动补括号、提示方法名。如果你平时重度依赖IDE考前一定要在牛客网自己的在线编辑器里练几道题提前适应手打代码的感觉。我就是因为平时都用VS Code写代码上考场后连写十几个document.querySelector的手感都变了白白浪费了几分钟。第二是代码运行环境不一定支持ES6的全部特性。牛客的JavaScript运行环境一般是Node.js的某个固定版本支持ES6语法但不一定支持最新的ES2022/ES2023特性比如Array.prototype.at、Object.hasOwn这类API。保险起见手写代码时尽量只用ES6ES2016/2017的常见功能不要用太新的API否则本地写得好好的线上跑出来全是undefined。第三是编程题默认只要求你补充函数体不要自己写readline读入输出。我见过不少考生习惯力扣式的“输入输出自己处理”结果把题目给的函数签名改了导致编译失败。在线笔试系统一般会给出一个函数签名模板你只要在里面完成逻辑即可千万别画蛇添足。5. 常见问题与避坑心得速查表5.1 笔试中最容易翻车的6个场景编号场景错误原因正确做法1sort不传比较函数以为默认就是升序排序必须写(a, b) a - b2var和let在循环中的区别只知道有区别说不清原因理解作用域和闭包捕获变量本质3Cache-Control: no-cache的含义字面理解成“不缓存”它的含义是“每次使用前必须向服务器验证”4useEffect依赖数组为空以为组件更新后会重新执行只在挂载时执行一次后续不触发5手写防抖时忘了透传this和args写多了容易忽略上下文绑定用fn.apply(this, args)6在线编程题修改了给定的函数签名误以为需要自己写完整输入输出直接按题目模板补全函数体即可这张表里每一条都是我亲眼见过别人踩过的坑或者自己栽过跟头后复盘总结的。第1条和第5条是典型的“背到了但没写对”第3条是“想当然”式的错误第6条更是考场操作层面的致命伤。你准备笔试时可以专门用一张类似的表格做考前速查把每个知识点对应的“最容易错的点”列出来考前看一遍比临时翻书有用得多。5.2 复盘之后我发现的备考重心笔试结束后的复盘比笔试本身的价值大得多。我发现自己丢分最严重的不是不会的知识点而是“会但不熟”的知识点——比如事件循环的详细执行顺序我大概知道但在多选场景下一碰到混淆选项就开始发虚再比如BFC的触发条件平时布局时用overflow: hidden顺手就写了真要我说出“还能用display: flow-root触发”时我卡住了。针对这种情况我建议你备考时不要把时间花在“背更多八股文”上而是把功夫下在“把已会知识点之间的关联打通”上。怎么打通一个很有效的方法是“给每个知识点找一道能落地的实践场景”比如学习事件循环就写一个通过“微任务宏任务DOM渲染”实现页面分帧更新的小Demo学习BFC就整理一份“清除浮动、防止外边距折叠、阻止元素被浮动元素覆盖”的代码片段集。当知识被你要解决的问题串起来时考场上遇到变体题你也能靠逻辑推而不是靠记忆猜。从热词趋势来看2026年的前端面试题比2023年更加注重工程化、组件库、AI辅助开发工具比如anything-llm这类前端应用、cursor、codebuddy等的实际使用经验但基础核心——JavaScript异步、响应式原理、浏览器运行机制——依然是笔试里占比最重、最关键的部分。掌阅这套卷子虽然出在2023年但它的命题思路和2026年的面试方向是一脉相承的基础题考原理开放题考业务落地能力。只要把这两个方向抓稳以不变应万变是最稳的备考策略。5.3 给准备前端笔试的同学的一个核心建议如果只让我说一条备考建议那就是不要只刷选择题一定要动手写题。笔试题里那些手写代码题你光看答案是永远看不出易错点的只有自己写一遍才能真正理解“为什么debounce的timer要存在闭包里”“为什么Promise并发控制要维护running和index两个变量”。我的实操方法是每学完一个知识点就在牛客网的在线编辑器或者自己的本地上把它实现一遍然后故意改一些边界条件比如空数组、极限并发数、重复触发观察程序的输出变化直到自己能用两三句话解释清楚每段代码的每个关键行为为止。另一个建议是建立“高频手写题清单”包括防抖节流、数组去重/扁平化、深拷贝、发布订阅、并发控制、简易响应式、大数相加/字符串相加、Promise.all/race实现等每道题都要求自己能够5~8分钟内无参考地写出来。这张清单里的题目我在掌阅笔试里碰到了至少两道防抖节流和并发控制在其他公司的笔试题里也都出现过。它们就是前端笔试的“基本盘”反复练到形成肌肉记忆考场上才能腾出脑力去处理更复杂的业务设计题。最后再分享一个小技巧笔试开始前先在草稿纸上写下一些容易忘记的关键点比如debounce和throttle的核心区别、sort比较函数的写法、BFC的触发条件列表。考场上的紧张情绪会让人脑子一片空白但有了这张“记忆外置”的草稿纸你能快速恢复正常状态。这套方法我自己用下来非常有效推荐你也试试。