大专前端暑期实习面经:脚手架、HTTP缓存与XSS防御全复盘 📅 发布时间:2026/9/1 1:30:03 👁 浏览次数: 面完这轮前端实习面试我在地铁上就把问题一条条记下来了。作为大专大二的学生这个暑假能不能拿到一份前端实习基本决定了秋招简历上有没有东西可写。整场面试聊了一个多小时面试官一半时间在追问项目里脚手架的搭建过程另一半在问 HTTP 和 XSS 相关的八股中间还穿插了两道手写题和几个开发场景排查。回来后我做了完整复盘把问到的每个点重新推导了一遍包括脚手架从零怎么搭、强缓存和协商缓存的完整字段、DOM 型 XSS 的攻击链路和防御方案。这篇内容就是这次面经的实录不仅记录面试官问了什么更会讲清楚每个问题背后的原理、我的回答思路以及当时没答好的地方。希望给同样在准备前端暑期实习的同学一些参考尤其是学历不占优势、靠自学走到现在的朋友。1. 面试前的准备大专生怎么规划暑期实习1.1 为什么大二就得出来面试坦白讲投这份实习之前我纠结了很久。大二上学期结束、下学期刚开始身边很多同学都觉得实习还早但我自己算了一笔时间账大三一开学就要卷秋招而秋招简历上最值钱的板块就是实习经历。如果等到大三再去投暑期实习面试大概率会撞上秋招提前批压力会大很多。所以我的规划是大二下学期就开始投目标锁定暑期实习公司大小无所谓外包、远程、创业团队都行先上车积累一段真实业务经验再说。事实证明这个决定是对的面试官对我的学历没有太多偏见反而更关注我有没有实际做过东西、基础概念能不能讲清楚。这次面试能约上我觉得和我的准备方向也有关。我没有海投而是挑了十几家规模不大但技术栈匹配的团队根据岗位要求微调简历把我做过的项目和脚手架搭建经历写在最显眼的位置。比起一份“精通 Vue 全家桶”的空话简历面试官明显更愿意看一个能讲清楚自己写了什么的人。1.2 我把复习重心放在了哪三块确定目标后我列了一份复习清单主要分三块基础八股、项目细节、手写题。八股里优先级最高的是 HTTP、XSS、浏览器原理、Vue 响应式原理这几个方向因为这些几乎每家都会问。项目细节我会把脚手架的搭建过程、请求封装、权限拦截一条条写成文档确保被追问时能说出具体实现而不是含糊带过。手写题我每天刷 3 到 5 个重点不是背答案而是理解函数内部发生了什么。实际面试时面试官看到你写对了还不一定满意会追问几个边界情况比如“防抖的 this 指向怎么保存”“reduce 不传初始值会怎样”这种题没有真理解是答不出来的。另外我还准备了一个“自我介绍模板”控制在两分钟内核心逻辑是我是谁、我做过什么、我擅长什么、我为什么想加入这里。因为是大专学历我会重点强调自己的动手能力和复盘习惯比如写过博客、参与过开源项目。这些内容在这次面试里发挥了很大作用后面会详细说。1.3 简历不花哨但每一条都能被追问我的简历只有一页项目经历写了两个一个是后台管理系统一个是这个面经里重点聊的脚手架工具。管理系统重点是权限控制和数据可视化脚手架工具则体现了我的工程化能力。每一段描述我都会提前想好至少三个会被追问的点比如“你这个脚手架怎么实现的”“下载模板失败了怎么办”“Vite 比 webpack 快在哪里”。这里有个经验简历上写的任何东西面试官都有可能在现场让你展开讲写上去之前先问自己一句“如果被问到最深的细节我能答上来吗”。答不上来的东西宁可不写写了就要做好准备。我身边很多同学简历写得花团锦簇一问项目细节就支支吾吾反而扣分更严重。这次面试开场面试官就顺着简历问了一句“你简历上说你搭过脚手架这个脚手架解决了什么问题”我一下就明白项目细节才是这轮面试的主线。2. 脚手架搭建的高频题从使用到实现2.1 面试官为什么揪着脚手架不放面试官问脚手架表面上是问工具实际上是在摸底三段能力第一你有没有工程化意识知不知道一个项目从零到一需要哪些步骤第二你有没有研究过常用工具背后的原理还是只会机械地敲命令第三你有没有动手扩展过工具链比如改过打包配置、写过脚本。这三段能力对应的是“熟练工”“工程师”“能独当一面”三个层次。很多同学回答脚手架只会说“我用 Vue CLI 和 Vite 创建过项目”这个答案太浅了。面试官想听的是脚手架到底替你做了哪些事初始化目录结构、统一依赖版本、生成公共配置、启动开发服务器、提供构建命令、集成代码规范和测试工具。如果你能把这些环节拆开讲就已经超过了大多数候选人。我这次准备的思路是先讲清楚“脚手架的本质是自动化工程初始化”再讲我实际怎么从零写了一个迷你脚手架把 bin 配置、交互式问答、模板下载、动态渲染这几个核心步骤用自己的话说一遍。面试官听完明显有兴趣继续追问后面好几个问题都是顺着这条路展开的。2.2 Vue CLI 和 Vite 的区别要这样答面试官问我的第一道技术题是“你平时用哪个脚手架Vite 和 Vue CLI 有什么区别”。我先说了结论Vue CLI 基于 webpackVite 基于原生 ESModule。然后我展开解释了两者的本质差异——webpack 在启动开发服务器时需要把所有模块打包成一个 bundle项目越大启动越慢Vite 则利用了浏览器原生支持 import 的特性开发时不需要整体打包而是按需把请求到的模块返回给浏览器所以冷启动速度非常快。依赖处理也是一个关键点。Vite 会用 esbuild 做依赖预构建把 node_modules 里的依赖提前转成 ESModule 并统一版本减少浏览器请求次数Vue CLI 则走 webpack 的完整构建流程配置多、编译步骤多但生态更成熟遇到问题时社区方案也更多。生产构建上两者也有区别Vue CLI 用 webpack 打包Vite 使用 Rollup。我特意补了一个细节自己在写脚手架时会同时支持“拉取 Vite 模板”和“拉取 Vue CLI 模板”两种选择因为不同团队维护的老项目可能还在用 Vue CLI新项目则更推荐 Vite。面试官听完就说了一句“你能从使用场景出发考虑方案这个思路是对的”。我当时心里松了一口气感觉这一题拿到了加分。2.3 手写一个迷你脚手架的核心流程这道题是我准备最充分的因为简历上写了。面试官问我具体怎么实现我直接把设计思路和核心代码讲了一遍代码不用完整背但流程必须清楚。第一步在 package.json 里配置 bin 字段指定命令入口文件{ name: my-cli, version: 1.0.0, bin: { my-cli: ./bin/index.js } }第二步在入口文件头部加上#!/usr/bin/env node告诉系统用 Node.js 执行这个文件。第三步用 commander 或者单纯解析 process.argv 处理命令。我写了一个create命令用法是my-cli create my-project#!/usr/bin/env node import { program } from commander program .command(create projectName) .description(create a new project) .action((projectName) { console.log(creating project: ${projectName}) }) program.parse(process.argv)第四步用 inquirer 做交互式问答让用户选择框架模板比如 React 还是 VueTypeScript 还是 JavaScript是否需要 ESLint。这个环节对应的是 create-vite 和 vue-cli 初始化时那一堆交互选项。第五步根据用户选择从 GitHub 或 Gitee 拉取对应的模板仓库这一步用 download-git-repo 库实现支持direct:前缀直接下载 zip 包。下载完成后需要用 handlebars 或 ejs 对模板里的变量做替换把 package.json 的 name、version、author 替换成用户输入的内容。最后提示用户进入目录并执行 npm install、npm run dev。这个流程听起来不长但每一步都有坑。比如 download-git-repo 对 GitHub 的域名解析偶尔会超时需要切换到国内镜像模板渲染时会遇到{{ }}冲突需要在模板里转义bin 文件名和 package.json 里的命令名不一致会导致安装后命令找不到。这些坑我都实际踩过所以能说得比较具体面试官也能感觉到我真的实现过而不是背了一段网上的教程。2.4 脚手架题的加分回答模板如果只讲步骤这道题也就是及格分。我后续补充了两个加分项一是讲清楚自己为什么做这个脚手架而不是直接用 create-vite。我的理由是团队里老项目技术栈不统一有人用 JS有人用 TS有人用 Vue2有人用 Vue3创建一个新项目时每次都要手动改一堆配置。我写脚手架的目标就是让新人一条命令拉起符合规范的项目省去重复劳动。二是讲了“脚手架如何做模板版本管理”。我一开始是从固定分支拉模板后来发现模板更新后老项目想升级很麻烦于是改成打 tag脚手架支持指定版本号比如my-cli create app --template vue3-ts1.2.0。这个设计灵感来自 create-vite 的模板命名方式也让面试官觉得我考虑了工程化中的版本演进问题。最后我补了一句如果只是做一个给个人用的脚手架直接复制 create-vite 改一改就好了没必要重复造轮子自己做是因为想完全掌控模板内容和初始化流程也为了学习原理。这句话表达了一种务实的技术判断面试官一般比较认可。3. HTTP 相关八股真实面试题与答题思路3.1 从「输入 URL 到页面展示」开头HTTP 这一块面试官是从一道综合性问题开始的“你在地址栏输入一个网址到页面展示出来中间发生了什么”。这道题范围很广实际上是给考生一块自由发挥的画布面试官会在你停顿的地方继续深挖。我按照这个顺序回答先做 DNS 解析把域名解析成 IP然后通过 TCP 三次握手建立连接如果是 HTTPS还要多做一次 TLS 握手协商加密套件和证书验证接着浏览器构造 HTTP 请求报文发送到服务器服务器处理请求后返回 HTTP 响应状态码、响应头、响应体浏览器拿到 HTML 后解析遇到 CSS、JS 等静态资源会再次发请求最后构建 DOM 树和 CSSOM 树执行 JavaScript完成渲染。我说到“TCP 三次握手”时面试官打断了问“为什么是三次而不是两次”。这个问题很多人会背“防止重复连接”之类的结论但我换了个角度解释三次握手实际上是双方互相确认彼此的收发能力。第一次客户端告诉服务端“我要连你”第二次服务端告诉客户端“我收到你的请求我也能发”第三次客户端告诉服务端“我收到你的应答准备开始传输数据”。只有完成这三步双方才能确认自己的发送和接收都正常。这样答面试官能看出你不是死记硬背。3.2 HTTPS 比 HTTP 安全在哪接下来面试官直接问“HTTP 和 HTTPS 的区别”。我先说基本点HTTP 明文传输HTTPS 在 HTTP 和 TCP 之间加了一层 TLS/SSL 加密协议。然后我展开讲了加密原理——HTTP 本身没有加密能力HTTPS 通过混合加密方案解决安全问题。具体是这么个逻辑直接用对称加密密钥一旦被中间人截获所有通信内容都能被解密直接用非对称加密性能开销太大。所以 TLS 握手阶段使用非对称加密协商一个对称密钥之后用这个对称密钥加密实际传输的数据。非对称加密解决了密钥分发问题对称加密解决了性能问题。证书的作用是验证服务器身份防止中间人冒充服务器浏览器会校验证书是否由可信 CA 签发、域名是否匹配、是否过期。面试官追问“如果证书过期了浏览器会怎么做”我回答浏览器会给出不安全的警告用户可以选择继续访问但正常情况下应该停止访问因为服务器身份已经无法验证。他没有继续深挖证书链我已经准备好要讲根证书、中间证书和证书链校验了这题就算过了。3.3 HTTP 状态码高频考点速查表状态码是 HTTP 八股里的送分题但也是细节最多的一类。面试官这次没有让我背全部状态码而是问了几个实际场景“你平时开发中见过哪些状态码分别代表什么问题”。我把常见状态码按照几个大类和实际排查经验过了一遍这里也整理成表格方便大家直接背状态码含义常见触发场景200请求成功正常返回页面或接口数据201创建成功POST 创建资源成功204无内容删除操作成功无返回体301永久重定向网站换域名旧地址跳转新地址302临时重定向未登录跳转到登录页304未修改协商缓存命中服务器判定资源没变400请求参数错误必填字段缺失、JSON 格式不对401未认证未携带 token 或 token 失效403无权限已登录但无权访问该资源或跨域被拦截404资源不存在接口路径写错、路由未匹配500服务器内部错误后端代码异常、数据库未启动502网关错误网关拿不到上游服务响应服务挂了或没启动503服务不可用服务器过载、停机维护504网关超时上游服务处理太久网关等不下去了我特意强调了一个容易混淆的点401 和 403 的区别。401 表示“你是谁我不知道”需要先认证403 表示“我知道你是谁但你没有权限做这件事”。如果登录后发现请求返回 403比较多的情况是跨域配置没放开或者角色权限不够。这种细节如果不理解排查接口问题时很容易走弯路。3.4 强缓存与协商缓存别只背概念缓存机制是 HTTP 面试题里的重头戏每家几乎都会问。面试官这次问的是“强缓存和协商缓存的区别”我按照字段、优先级、触发流程三个方面回答。强缓存核心字段是Cache-Control: max-age3600和Expires。浏览器在有效期内不会发请求直接使用本地副本状态码显示 200但来源是 memory cache 或 disk cache。Cache-Control中的max-age是相对时间Expires是绝对时间两者同时存在时Cache-Control优先级更高因为Expires依赖客户端本地时间本地时间不准就会出问题。协商缓存核心是Last-Modified和ETag。浏览器带着If-Modified-Since或If-None-Match去请求服务器判断资源没变返回 304浏览器继续用本地副本。ETag比Last-Modified更精确因为Last-Modified只能精确到秒同一秒内修改多次就判断不出来而且有些服务器返回的修改时间不准确。我的回答里还加了一个实战场景在脚手架的模板下载里我也用到了缓存思路对下载过的模板做本地缓存二次创建时直接复用减少网络请求。这样面试官会觉得你是真的把知识用起来了而不只是会背字段。3.5 HTTP 版本对比1.1、2.0、3.0这个问题是我主动提的因为前面聊到 TCP我觉得可以顺带把 HTTP 版本演进讲掉。幸好我提前准备过不然很容易翻车。HTTP/1.1 的问题主要有两个一是队头阻塞同一个连接上多个请求必须按顺序排队前一个响应没返回后面的只能等着二是头部冗长每次请求都重复携带大量头信息。虽然 1.1 有了 keep-alive 连接复用但还是必须严格遵守“先进先出”的响应顺序。HTTP/2 为了解决这些问题引入了二进制分帧层多个请求可以同时在同一个连接上交错传输这叫多路复用。它还用 HPACK 算法对头部做压缩大大减少了重复头部开销。另外 2.0 支持服务端推送服务器可以主动推送 CSS、JS 等资源。但 2.0 并没有彻底解决队头阻塞因为 TCP 层的丢包重传机制还是会阻塞整个连接。HTTP/3 换了个思路直接放弃 TCP改用基于 UDP 的 QUIC 协议。QUIC 实现了可靠传输和快速握手还支持 0-RTT 连接建立避免了 TCP 慢启动带来的延迟也解决了 TCP 层队头阻塞。面试官听完点了点头这个知识点虽然不一定每家都问但答出来绝对是加分项。4. XSS 漏洞详解三种类型、payload 与防御4.1 反射型、存储型、DOM 型的区别XSS 是前端安全里最高频的面试题也是这次面试的压轴环节。面试官先让我讲三种 XSS 的区别我把分类标准和攻击链路都讲了一遍。反射型 XSS也叫非持久性 XSS恶意脚本藏在 URL 参数里服务端把参数内容原样拼到 HTML 返回浏览器解析时就执行了。特点是攻击链路短需要诱导用户点击恶意链接。存储型 XSS也叫持久性 XSS恶意脚本被保存在服务器数据库里比如一个评论功能没做过滤用户发了一条包含脚本的评论所有访问这个页面的用户都会中招危害最大。DOM 型 XSS 不走服务端恶意脚本通过 URL、localStorage 等输入源进入页面被前端 JavaScript 用 innerHTML、document.write 等方式插入 DOM 后执行纯前端侧就完成了攻击。三种类型的对比我整理了一个表格类型脚本是否入库攻击入口执行位置典型场景反射型否URL 参数服务端渲染后搜索页报错信息回显存储型是表单、评论服务端渲染后评论区、用户昵称DOM 型否URL hash、query前端 DOM 操作前端路由参数渲染我强调了一个点DOM 型 XSS 不依赖服务端拼接所以很多后端开发者觉得“我做了转义就安全了”其实并不够前端如果用了 innerHTML 和v-html这类危险 API依然会中招。4.2 DOM 型 XSS 的完整攻击流程面试官听到我说 DOM 型后追问了一个很细的问题“DOM 型 XSS 的攻击流程是怎样的你手写给我看”。我现场写了这样一个链路第一步攻击者构造恶意链接把 payload 放进 URL 参数https://example.com/item?idimg srcx onerroralert(document.cookie)第二步受害者点击链接页面 JavaScript 读取 URL 参数并直接插入 DOMconst params new URLSearchParams(location.search) const id params.get(id) document.getElementById(item).innerHTML 商品编号 id第三步img标签被插入后浏览器尝试加载srcx这个不存在的资源触发onerror事件执行其中的 JavaScript恶意代码就这么跑起来了。我补了一个细节现代很多单页应用会把参数放在 hash 路由里比如https://example.com/#/item?idxxx这种情况下参数不会随着 HTTP 请求发送给服务端但会留在浏览器端被 JavaScript 读取所以更容易被开发者忽略。面试官听到这个点又追问了一句“那怎么确认漏洞是否存在”我说通常会用一个无害的弹窗测试 payload 是否执行然后进一步验证能否窃取 cookie、能否读取页面数据。但这些测试只应该在自有环境或授权范围内进行这一点我在回答时也明确表达了。4.3 一个 XSS payload 的逐段含义面试官问了一道让我印象深刻的题“如果面试项目里出现了 XSS 攻击你能不能把 payload 拆开讲清楚每一段在干什么”。我现场写了一个经典 payload逐段解释img srcx onerroralert(document.cookie)img是 HTML 图像标签浏览器会自动尝试加载 src 指向的资源。这里的关键是浏览器加载图片失败后不会停止解析而是会触发 onerror 事件。srcx是一个不存在的资源地址作用就是故意触发错误。onerroralert(document.cookie)是事件处理属性一旦错误事件触发浏览器就会执行这段 JavaScript。document.cookie读取的是当前站点的 cookie攻击者拿到后可以冒充用户身份发起请求。我继续补了一个更隐蔽的变体a hrefjavascript:alert(document.cookie)点击领取福利/a这种 payload 不需要任何事件触发只要用户点击链接就会执行。还有基于 SVG 的svg/onloadalert(1)SVG 标签加载完成时自动触发 onload不需要用户交互。拆解 payload 的每个部分其实就是理解 HTML 解析器、事件循环、JavaScript 执行上下文三者如何配合。这段回答让面试官比较满意因为我不只停留在“会背 payload”而是真正理解了执行链路。4.4 防御手段转义、CSP、HttpOnly讲完攻击面试官自然要问怎么防御。我把防御体系从“前端、后端、浏览器”三个层面展开。前端第一层永远不要用 innerHTML 插入不可信数据改用 textContent。textContent 会把内容当作文本处理script标签就不会被执行。第二层Vue 默认的插值语法{{ }}和 React 的{ }都会自动转义进入 DOM 前变成了纯文本所以平时写代码只要不碰v-html和dangerouslySetInnerHTML框架本身能挡住大部分 XSS。第三层如果业务确实需要渲染富文本就引入 DOMPurify 这类白名单过滤库把script、iframe这些危险标签和onerror、javascript:这类危险属性统统过滤掉。后端层面所有用户输入进入数据库前必须做校验和过滤输出时也要转义。不能依赖前端过滤因为攻击者完全可以绕过前端直接用 postman 发包。浏览器层面这里有两个关键机制。第一个是 CSPContent-Security-Policy。通过响应头限制脚本资源来源比如Content-Security-Policy: default-src self; script-src self https://cdn.example.com这样即使页面被植入了恶意脚本浏览器也会拒绝执行非白名单来源的脚本。第二个是 HttpOnlyCookie 设置了 HttpOnly 属性后JavaScript 的document.cookie读不到这个 Cookie即使 XSS 执行了也无法直接窃取登录凭证。但同时要认识到HttpOnly 只能防 cookie 被读取不能防恶意脚本发请求、改页面。4.5 面试官追问怎么修复线上 XSS面试官最后出了一个场景题“你的项目上线后收到安全报告说搜索页存在反射型 XSS你会怎么排查和修复”。我按自己的实操经验回答先定位搜索关键词是怎么渲染到页面上的找到对应的服务端模板或者前端渲染代码。如果搜索关键词被直接拼进了 HTML就在输出时做 HTML 实体编码把转成lt;把转成gt;转成amp;这样浏览器会把它显示成普通文本而不是解析成标签。如果页面是 Vue 或 React 写的就看是不是用了v-html或dangerouslySetInnerHTML如果是改成普通插值。业务必须保留富文本时加上 DOMPurify 清洗。同时通知后端增加输出转义部署 CSP 响应头复查其他类似接口有没有同样问题。修复完成后我会跑一遍自动扫描和手工测试确认 payload 不再执行再发布上线。这一套流程涵盖了“复现、定位、修复、部署、验证”五个环节面试官听完后问了一句“这些都是你自己做过的吗”我说是的之前自己写功能时真的遇到过类似问题所以印象很深。这种真实经历带来的细节比背一百道面试题都管用。5. 面试现场实录意外问题与翻车复盘5.1 npm run dev 背后发生了什么面试官在聊到脚手架时突然换了个角度“你执行 npm run dev 的时候你的开发服务器究竟做了哪些事情”。这个问题表面问命令实际上是在考对前端工具链底层流程的掌握程度。我按顺序回答npm run dev 会在 node_modules/.bin 里查找对应的可执行文件这个可执行文件是通过 package.json 的 bin 字段注册的。Vite 项目执行的就是 vite 命令Vue CLI 项目执行的是 vue-cli-service serve。接下来开发服务器会读取配置文件Vite 会解析 vite.config.js启动一个基于 Node 的 HTTP 服务器然后对浏览器请求做中间件处理。Vite 把当前项目依赖用 esbuild 预构建把 node_modules 里的第三方库转成 ESModule缓存到 node_modules/.vite 目录。浏览器访问页面时Vite 拦截请求找到对应的 .vue 文件或 .ts 文件实时编译后返回给浏览器。开发服务器和浏览器之间还会建立一条 WebSocket 连接用来做热更新当代码变化时Vite 通过这条连接通知浏览器替换对应模块而不是整页刷新。我特意说了一下 Vue 单文件组件在浏览器里是什么形式一个 .vue 文件会被拆分成 template、script、style 三个部分分别编译成 JS 函数、渲染函数和 CSS浏览器拿到的实际上是一个包含了 render 函数的 JS 模块。这些细节如果不了解只能在面试时说“它帮我开了个服务器然后页面就能热更新了”一下就露馅了。5.2 开发中的 403、404、502 怎么排查这个问题是面试官临时加的估计是想看我的实际排错能力而不是只背书。他说“你平时开发中遇到接口返回 403、404、502分别会怎么处理”。我先回答了 404。遇到 404 第一步先确认接口地址拼得对不对重点检查 baseURL 和实际请求 URL 是否拼接正确第二步看代理配置Vite 的 proxy 有没有把 /api 前缀转发到正确的 target第三步问后端排查路由是否注册、服务是否部署到对应环境。很多时候前端的 404 其实是代理没配好后端根本没收到请求。403 我强调先分清楚是认证问题还是权限问题。如果请求带了 token 还是返回 403优先考虑 CORS 跨域配置因为浏览器拦截跨域请求时控制台经常报 403 或 CORS 相关错误其次确认后端是否校验了角色权限。我自己遇到过的一种情况是cookie 没设置 SameSite 属性跨域携带 cookie 被浏览器拦截接口直接返回 403。502 我讲了两种典型场景。本地的 502 一般是后端服务没启动或者代理 target 配错了 IP线上的 502 大多是网关后面的服务挂了、超时或者正在发布重启。排查思路是先确认是偶发还是持续然后看后端日志、网关日志确认上游服务状态。我不建议前端一遇到 502 就疯狂刷新更稳妥的做法是先判断服务是否还在运行。这个回答思路清晰面试官没有再追问。5.3 手写题复盘防抖、节流、reduce最后面试官出了两道手写题第一道是防抖第二道是 reduce。防抖我写得比较顺利重点是把 this 和参数正确传递回去function debounce(fn, delay) { let timer null return function (...args) { if (timer) clearTimeout(timer) timer setTimeout(() { fn.apply(this, args) timer null }, delay) } }面试官问了一个细节“这里的 fn.apply(this, args) 为什么要传 this”。我说因为事件处理函数里的 this 指向原 DOM 元素如果直接调用 fn()this 就会丢失导致内部依赖 this 的逻辑出错。这题没问题。reduce 那题我翻车了。面试官让我实现一个 Array.prototype.reduce我一开始写的时候没有处理“不传初始值时从第二项开始遍历”的边界情况。面试官及时提示了一句“如果不传 initialValue 会发生什么”我才补上了对空数组的判断和首项作为累加器的逻辑。这个坑很典型建议大家在复习时把 reduce、map、filter、call、apply、bind 全部手写一遍只背用法是不够的。这次翻车给我的教训是手写题面试的时候即使第一遍写错了只要能在提示下修正并讲清楚原因面试官依然会给分。最怕的是写错了还硬着头皮不承认那样反而暴露了基础不牢。6. 大专生暑期实习的投递策略与心态6.1 投递时间线什么时候投命中率更高不少同学问我“暑期实习到底什么时候开始投”我的经验是提前半年到三个月。大二上学期九十月份就可以开始刷招聘信息提前了解目标公司的招聘时间线大二下学期二月到四月是投递高峰五六月才投很多坑位已经被占了。我这次赶的是二月底投递、三月中旬面试节奏刚刚好。投递渠道方面我用得最多的是招聘软件直投其次是公司官网的校招入口然后是牛客、V2EX 这类社区里的内推贴。内推的最大好处是简历可以直接到用人部门减少被 HR 条件筛选卡掉的风险。投递量上我建议不要只投三五家觉得“够得上”的也不要盲目海投几百家。我的策略是分三批第一批投最想去的第二批投比较合适的中型团队第三批是保底的本地公司或外包岗。每批投完后根据反馈调整简历比一次性全投出去有效得多。6.2 学历短板怎么补作品、博客、开源大专学历在简历筛选阶段确实会有劣势但屏幕对面真正干活的人更在意你能不能上手。所以我的思路是用可以被直接验证的东西补齐学历差距。作品集中在两个方面一个是线上可访问的项目另一个是开源代码仓库。面试官看到你的简历时如果附带了可以直接访问的线上地址他会优先打开看看而不是只看学校栏。我在简历上放了两个线上链接一个是后台管理系统的演示地址一个是脚手架的 GitHub 仓库都在面试前一整周做了完整打磨。博客的作用不是用来炫耀流量而是展示你的学习方式和复盘习惯。我写了大概十几篇技术笔记其中有几篇是踩坑记录比如“npm run dev 启动失败端口被占用怎么排查”“脚手架下载模板超时怎么解决”。面试官其实会看这些文章因为内容质量直接反映了一个人的表达能力和总结能力。这些都是大专生弥补学历背景比较靠谱的路径。6.3 如果没拿到 offer 怎么办这个问题我在面试前想过很多次也会在面试最后主动问面试官“您觉得我目前还需要提升哪些方面”。这轮面试的结果还没出但我做好了万一没过的准备。如果暑期实习失败了我的备选路线是先找小公司的日常实习或者远程外包项目把真实业务经验攒起来同时继续维护开源项目和博客。秋招投递时就算没有大厂暑期实习我也能拿出“一个自己从零搭脚手架的工程化项目 半年线上业务经验”来谈比一张空白简历强太多。这里给同样是大专的同学一个建议不要把暑期实习当成“一锤子买卖”它只是秋招前的一次热身。面试官看的是长期成长曲线你只要每次面试后都认真复盘、补齐短板两三个月后水平会有明显差距。我自己就是在这次面试复盘时把 HTTP 缓存和 DOM 型 XSS 重新过了一遍很多细节在第一次学习时根本没注意到。复盘完整场面试我最大的感受是大专生面试前端实习岗位面试官真的不会要求你把框架源码讲得多深但非常在意两件事——基础扎不扎实项目里的事情是不是真做过。脚手架、HTTP、XSS 这些题能成为高频八股恰恰是因为它们就是日常开发每天都在碰的东西背答案没有用只有自己搭过脚手架、修过 502 报错、排查过 XSS 漏洞才能在临场答出让人信服的细节。最后再分享一个小技巧每次面试结束后趁记忆还热着把面试官问过的所有问题全部记下来标注哪些答得好、哪些翻车了再用几天时间把翻车的题目重新整理成文档。这份复盘文档会越攒越厚到秋招前它就是你自己最靠谱的面试题库。祝大家暑期都能拿到满意的实习哪怕第一封感谢信是拒信也别停下手里的代码。