
简介面向大前端求职者与前端工程师的高频面试题库覆盖互联网大厂常考知识点既适合面试前集中复习也可作为面试官出题和团队培训的参考。压缩包内共1个pdf文件大小约8.37MB全文1000多页下载后可在电脑或平板上随时查阅。目录按计算机基础、HTML5与CSS3、JavaScript、TypeScript、Vue、React、Node.js、生态工具、图形图像3D、WebRTC与WebSocket、数据结构与算法、微前端等模块展开收录3000道高频题并附答案解析。每道题不只给结论还讲清原理与实现思路如进程与线程、死锁条件、虚拟内存、TCP与UDP、OSI七层模型、GET与POST、事务ACID、二分查找与冒泡排序优化并延伸至WebRTC的RTP/RTCP、WebSocket压缩扩展、Web Audio API调度等进阶主题。已有347人学习适合按章节查漏补缺系统建立大前端知识框架。1. 3000 道题的价值不在数量在于它把大前端切成了可核对的知识格面试前一周翻出「3000 道高频面试题」的人通常栽在同一个地方题看得完答不出来。原因不是记性差是这些题按 JS、CSS、框架、工程化、网络、浏览器混排在一起没有权重、没有验证、也没有和你简历里的项目对上号。真正有效的用法是把它当成一张清单用先用目标岗位的 JD 反推每个知识域该占多少题再把每道题拆成「一句话结论 一段能跑的代码 一个我踩过的坑」最后用限时口述做校验答不顺的题回炉。这套流程对正在准备大厂前端面试的初中级工程师最直接对带人的技术负责人也一样有用——团队内部的题库就是这么攒出来的。下面按知识域划分、单题吃透、模拟实战、题库维护四步往下走每一步都给出可复现的脚本和配置而不是让你对着 1000 多页 PDF 漫无目的地刷。2. 把 3000 道大前端高频面试题切成可复习的模块2.1 大前端的六个主干域与题量权重大前端这个词在不同公司指向不同但落到面试题上逃不出六个域JS 语言与运行时、CSS 与布局、浏览器与网络、框架原理、工程化与构建、跨端与可视化。3000 道题按这六个域切完你会发现分布极不均匀框架原理和 JS 加起来能占一半跨端可能只有一两百道。权重不是题量决定的是目标岗位决定的。校招和初级岗位更看重语言基础和手写能力高级岗位更看重工程化决策和性能治理。我一般用下面这张表做初筛再按 JD 微调知识域典型高频题初级/校招占比高级/资深占比JS 语言与运行时闭包、原型链、事件循环、this 绑定25%15%CSS 与布局BFC、flex/grid、层叠上下文、移动端适配15%8%浏览器与网络缓存策略、跨域、HTTP/2、渲染流水线18%18%框架原理Vue3 响应式、diff 算法、hooks 闭包陷阱22%22%工程化与构建Vite/Webpack、Tree Shaking、Monorepo、CI12%22%跨端与可视化小程序、大屏自适应、Canvas/WebGL8%15%注意跨端与可视化这一栏很多人直接跳过。但凡简历里写过「数据大屏」或者「多端复用」面试官一定会追问自适应方案和渲染性能这一块的投入产出比其实很高。2.2 别按题号刷按「考点指纹」合并同类题3000 道题里有大量重复。「Vue3 中 ref 和 reactive 的区别」和「reactive 与 ref 在使用上有什么不同」是同一道题只是换了个说法。先做去重能把有效题量压到一半以下复习时间立刻省出来。做法是把题干归一化成一个粗指纹去掉「请说一下」「谈谈」「是什么」这类提问套话再剥掉标点取前若干字符做 key。下面这段脚本读一个 JSON 题目清单输出重复度最高的若干组import json, re from collections import defaultdict # 提问套话 高频修饰词归一化时先剔除 NOISE re.compile(r(请|简单|详细|说一下|谈谈|是什么|有哪些|区别|原理|面试题|高频)) def fingerprint(title: str) - str: s NOISE.sub(, title) s re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , s) # 只保留中英文数字 return s[:12] # 粗指纹宁可多分组 questions json.load(open(questions.json, encodingutf-8)) buckets defaultdict(list) for item in questions: buckets[fingerprint(item[title])].append(item) for fp, group in sorted(buckets.items(), keylambda x: -len(x[1]))[:10]: print(len(group), fp, [g[title] for g in group][:3])NOISE决定了归一粒度去掉得越多分组越粗[:12]是经验值太短会把不相干的题并到一起太长又会漏掉真正的重复。questions.json每项至少要有title和domain两个字段domain 来自上一节的六域划分。输出结果里len(group) 1的组人工挑一版留下其余标记为dup_of后续统计题量时不再计入。提示指纹只用来找候选重复最终合并一定要人工过一遍。见过把「Vue3 的 diff」和「React 的 diff」并成一组的情况原理完全不同。2.3 权重表怎么落地从 JD 反推复习顺序知道每个域有多少题之后还要知道该给哪个域多分时间。我的做法是把三到五份目标岗位的 JD 存成纯文本直接统计关键词命中次数用得越多说明这个域越核心# jd/ 目录下放目标岗位的 JD 文本统计各能力关键词出现次数 for kw in 性能优化 微前端 大屏 SSR Node 工程化 可视化 Canvas; do printf %-8s %s\n $kw $(grep -ro $kw jd/ | wc -l) donegrep -ro的-o保证按出现次数计数而不是按行数-r递归整个目录。跑出来的数字直接对应复习优先级命中高的域先做命中为 0 的域可以放到最后。再给每个域做一次 1 到 5 分的自评掌握度复习顺序就是「权重 ÷ 掌握度」从高到低排。这个排序每周重算一次比固定计划表灵活得多。真正拉开差距的往往不是最难的题而是权重高、你又恰好答不利索的那几个域。3. 单题吃透大前端面试题答案的三层写法与可验证的代码3.1 一道题的答案应该有三层第一层是一句话结论面试官问完你先给判断第二层是机制解释说清运行时或框架层面发生了什么第三层是边界条件和你踩过的坑。只背第一层的人一被追问就露馅只讲第二层的人面试官会怀疑你没写过业务代码三层都有才算把这道题收进自己的知识格。拿「闭包」举例结论是「函数持有对外部作用域的引用使外部变量在函数返回后仍不被回收」机制是词法作用域在函数创建时确定V8 里通过 Context 对象保存被引用的变量边界是循环里用var注册事件会全部输出同一个值、以及长生命周期闭包导致的内存驻留。多数人只答前两层第三层才是区分度所在。3.2 用可运行代码验证 JS 与浏览器类题目事件循环这类题背结论没用因为不同运行环境的细节不一样。把下面这段代码在浏览器和 Node 里各跑一遍顺序差异本身就是面试素材// 事件循环顺序验证同步 - 微任务 - 宏任务 console.log(1 script start) setTimeout(() console.log(2 setTimeout), 0) Promise.resolve().then(() console.log(3 promise then)) queueMicrotask(() console.log(4 queueMicrotask)) console.log(5 script end) // 输出顺序1 5 3 4 2Promise.then和queueMicrotask都进微任务队列按入队顺序执行setTimeout属于宏任务要等当前轮微任务队列清空才轮到它所以即使延时写 0 也排在最后。浏览器和 Node 在这里基本一致差异出现在setImmediate与setTimeout(fn, 0)的主模块执行顺序上——Node 里两者顺序并不确定取决于当次循环启动耗时。面试时能主动说出「主模块内不确定、在 I/O 回调里 setImmediate 稳定优先」比复述一遍宏微任务定义有力得多。3.3 布局题怎么验证Vue3 Element Plus 大屏自适应自适应大屏是简历上的高频项目也是高频追问点。方案无非两类rem/vw 的流式缩放和按设计稿整体transform: scale()的等比缩放。固定设计稿、元素位置不能重排的大屏用后者更稳// useScreenScale.js —— 按 1920x1080 设计稿等比缩放 import { ref, onMounted, onUnmounted } from vue export function useScreenScale(design { width: 1920, height: 1080 }) { const scale ref(1) const style ref({}) function resize() { const { innerWidth: w, innerHeight: h } window // 取宽高比中较小的那个保证设计稿完整可见、不裁切 const s Math.min(w / design.width, h / design.height) scale.value s style.value { width: ${design.width}px, height: ${design.height}px, transform: scale(${s}), transformOrigin: left top, // 必须写否则以中心缩放导致定位全错 position: absolute, left: ${(w - design.width * s) / 2}px, // 水平居中留白 top: ${(h - design.height * s) / 2}px } } onMounted(() { resize() window.addEventListener(resize, resize) }) onUnmounted(() window.removeEventListener(resize, resize)) return { scale, style } }Math.min而不是分别算宽高比例是为了避免非等比例拉伸把圆形压成椭圆。transformOrigin必须设成left top否则缩放中心在元素正中配合绝对定位的偏移量会全部算错——这是最常见的一个坑。再往下的加分点是 Element Plus 的下拉框、日期选择器在缩放容器里会飘transform会让元素创建新的包含块Popper 计算偏移时拿到的是缩放后的getBoundingClientRect()视觉位置就对不上。解法是把弹层通过teleport挂到 body 外层或者给弹层容器单独写一个反缩放系数。能把这句说出来说明方案是真跑过的。3.4 框架原理题背诵式答法和加分答法的差距同一个问题答法的层次差别很大题目背诵式答法加分答法ref 和 reactive 区别ref 用 .valuereactive 不用ref 用 RefImpl 包装为了在 Proxy 无法代理基本类型时仍能追踪解构 reactive 对象会丢失响应性key 的作用帮助 diff 识别节点列表就地复用时key 决定了节点能否复用用 index 做 key 在插入排序场景下会引发状态错位Vue3 diff双端比较无 key 用 patch 长度差有 key 先做首尾预处理再对剩余部分求最长递增子序列减少 DOM 移动v-if 与 v-show一个销毁一个隐藏结合v-if的编译期提升和v-show的初始渲染成本说明频繁切换场景该选哪个把这张表填满框架原理这一域基本就稳了。填的过程本身就是复习写不出加分答法的地方就是需要回去读源码或写 demo 的地方。4. 模拟实战手写题、场景题和 Agent 方向新题怎么串成一场4.1 手写题的三个模板覆盖八成手写题看着多其实模板就那么几个。防抖节流和深拷贝练熟剩下的多半是它们的变体// 1) 防抖wait 毫秒内重复触发只执行最后一次 function debounce(fn, wait 300, immediate false) { let timer null return function (...args) { if (timer) clearTimeout(timer) if (immediate !timer) fn.apply(this, args) // 首次立即执行 timer setTimeout(() { timer null if (!immediate) fn.apply(this, args) }, wait) } } // 2) 节流每 wait 毫秒最多执行一次trailing 保证最后一次不丢 function throttle(fn, wait 300, trailing true) { let last 0, timer null return function (...args) { const now Date.now() if (now - last wait) { last now fn.apply(this, args) } else if (trailing !timer) { timer setTimeout(() { last Date.now(); timer null fn.apply(this, args) }, wait - (now - last)) } } }面试官最容易追问的两点一是this和参数透传——所以两处都用了fn.apply(this, args)而不是直接fn()二是取消能力防抖要补一个cancel方法挂到返回函数上节流要处理trailing为 true 时最后一次触发的时机。写的时候主动说出来比等他问再补要强。深拷贝同理能自己说出循环引用用WeakMap缓存、Date/RegExp/Map/Set要单独分支、函数不拷贝只能引用传递这题就算过了。别背一个二十行的万能函数说清取舍更值钱。4.2 场景题性能优化要按指标说话回答性能优化最忌讳罗列手段。正确的骨架是「指标 → 定位 → 手段 → 验证」先说盯的是 LCP、INP 还是 CLS再说怎么测出来的最后才讲改了什么手段主要影响指标代价路由级懒加载 分包LCP首屏多一次请求弱网下可能更慢图片懒加载 现代格式LCP、CLS必须写死宽高否则布局抖动长任务切分时间切片INP代码复杂度上升状态管理变麻烦骨架屏 预渲染LCP、CLS构建流程变长需维护两套结构后台管理系统类的项目比如基于 JeecgBoot 的 Vue3 前端性能瓶颈通常不在首屏而在交互表格上千行、字典项反复请求、弹窗里嵌套大表单。这类项目讲优化的抓手是虚拟滚动、字典缓存和按需渲染比讲打包体积更贴合面试官的实际经验。4.3 前端转 Agent 开发新题怎么接现在不少岗位会在最后加一轮和 AI 应用相关的问题不要求你会训模型但要求你能把流式响应和工具调用接进界面。最常见的追问是「流式输出怎么实现」标准答案是 SSE用fetch加ReadableStream手写解析比EventSource灵活因为后者不支持 POST 和自定义请求头// 用 fetch ReadableStream 解析 SSE 流 async function* sseStream(url, payload) { const res await fetch(url, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(payload) }) const reader res.body.getReader() const decoder new TextDecoder() let buf while (true) { const { done, value } await reader.read() if (done) break buf decoder.decode(value, { stream: true }) const parts buf.split(\n\n) // SSE 事件之间用空行分隔 buf parts.pop() // 最后一段可能被截断留到下一轮 for (const p of parts) { const line p.split(\n).find(l l.startsWith(data:)) if (line) yield JSON.parse(line.slice(5).trim()) } } }decoder.decode(value, { stream: true })不能省多字节字符可能被切在两个 chunk 之间parts.pop()保留下来的残片是必须的否则会丢掉半截 JSON 导致JSON.parse抛错。再往深一层的问题是渲染每个 token 都触发一次全量 Markdown 重渲染长回答会直接卡死主线程。常见做法是按帧合并更新、代码块单独组件化、用AbortController支持中断生成。这些点能讲明白转 Agent 开发方向这一轮基本不会被卡住。4.4 排错类问题白屏、401 和样式错乱怎么答这类题考的是排查路径不是答案本身。白屏先看控制台有没有 JS 报错再看 Network 里主包是否 200、是否被 CDN 缓存了旧版本、路由守卫有没有死循环重定向401 先确认 token 是否存在、时钟偏移是否导致 JWT 校验失败、刷新 token 的并发请求有没有去重样式错乱先看是不是微前端子应用的样式没加作用域、全局 CSS 变量被覆盖。答的时候按「先定位层级再收敛范围」讲是构建产物问题、运行时错误、还是网络层问题三类的排查入口完全不同。能说出用 VSCode 的 JavaScript Debugger 直接 attach 到 Chrome、配好webRoot打断点比只会开 DevTools 更让面试官放心。5. 让题库活下来一题一文件、每天抽题口述5.1 一题一文件交给编辑器全局搜索1000 多页合集最大的问题是没法检索和更新。我的做法是拆成一题一个 Markdown 文件目录按知识域分层文件名用短横线连接的考点名例如framework/vue3-ref-vs-reactive.md。这样在 VSCode 里CtrlShiftF全局搜索「响应式」跨文件命中一次全出来比翻 PDF 快一个量级。文件内部固定四段结论、机制、代码、踩坑。写不出代码段的题说明还没吃透直接标#todo下次优先补。5.2 每天抽十题做口述训练看得懂不等于讲得出。用一个脚本每天随机抽十题看到标题就开口讲 60 秒讲不顺的记下来# 从题库目录随机抽 10 个文件打印文件路径和首行标题 find ~/interview-bank -name *.md \ | sort -R | head -n 10 \ | while read f; do printf %s\n %s\n $f $(head -n 1 $f) doneGNU 环境用sort -R做随机排序macOS 上默认的 BSD sort 不支持-R装 coreutils 后换成gsort -R或者用awk BEGIN{srand()} {print rand(), $0} | sort -n | cut -d -f2-替代。head -n 1取的是文件第一行标题所以约定每个文件第一行必须是# 题目别放注释。每周把讲不顺的题重新标一遍两周还没讲顺的基本就是知识盲区而不是紧张问题值得回去补源码。5.3 用调试器核对「页面代码到底是怎么组成的」面试里被问「你怎么确认这段代码在生产环境真的执行了」能现场演示比嘴上说强。在.vscode/launch.json里配一个 Chrome attach 配置{ version: 0.2.0, configurations: [ { type: chrome, request: launch, name: 调试本地页面, url: http://localhost:5173, webRoot: ${workspaceFolder}/src, sourceMaps: true } ] }webRoot必须指向源码根目录指错了断点会变灰不可用sourceMaps依赖构建工具打开 sourcemapVite 开发模式默认就有生产构建要显式开build.sourcemap。打断点之后配合 DevTools 的 Coverage 面板看哪些代码没被执行到就能回答「这段逻辑是不是死代码」这类追问。真正把 3000 道题变成资产的动作只有一个每道题的踩坑那段必须是你自己写的哪怕只有一行。别人整理的答案只解决「知道」自己踩过的坑才解决「讲得出来」。本文还有配套的精品资源点击获取