致站在起跑线前的你,
「金三银四」战鼓已经擂响,屏幕前的你,是否正对着海量的面试题感到焦虑?是否在“经验不足”的自我怀疑中反复挣扎?
别怕。当年的我也和你一样,所以我懂你。
毕业前夕的迷茫,校招笔试面试的挫败,Offer选择的纠结…每一个坎当年我都亲身经历过。所以我们为你做了一件事:把这两年高频出现的面试题、最易踩的坑、面试官最在意的逻辑,整理成这份超过2万字的「2026前端面试题库(详解版)」。
这份题库不是最全的(由于篇幅有限),但是共十二个模块,体系完整,每一道题带追问、详解,还有评分思路,知己知彼百战百胜,你知道面试官是怎么想的,你就更能从容应对了。
对应届生来说,看的从来不是你“已经多厉害”,而是你“能成长多快”。而证明这一点的最好方式,就是展现你清晰的逻辑、扎实的基础、和解决问题的潜力——这也正是我们想帮你通过这份题库呈现的。
“金三银四”不仅是时间窗口,更是心理窗口。当你用系统的准备,换来自信从容的表达,那个在面试中闪闪发光的你,自然会脱颖而出。
现在,深呼吸,然后一道道题,一步步地把焦虑变成具体,把未知变成掌控。我的嘴也很毒,相信我,你的 2026 年的第一个Offer,已经在路上了。 💪Just do it.
FRONTEND INTERVIEW GUIDE |
前端面试
完全参考指南
适用人群:实习生 / 应届生 / 1-3 年经验
共收录 58 道精选题目·12 大知识模块
技术栈:React · Vue · TypeScript · 工程化 · 浏览器 · AI
58+ 精选题目 | 12 知识模块 | 4 档 评分标准 |
● 简单基础必知 | ◆ 中等融会贯通 | ▲ 偏难深度原理 |
整理日期:2026版本:v2.0用途:面试官参考手册
目录
🎨一、HTML & CSS 基础(6 题)
⚡二、JavaScript 核心(8 题)
🔷三、TypeScript(5 题)
⚛️四、React 深度(8 题)
💚五、Vue 核心(3 题)
🔧六、工程化与构建(5 题)
🌐七、浏览器与网络(5 题)
🏗️八、项目与架构(5 题)
💻九、编码与算法(5 题)
🤖十、AI 与前沿技术(3 题)
📱十一、移动端与跨平台(2 题)
🎯十二、综合潜力评估(3 题)
🎨一、HTML & CSS 基础 |
Q1介绍一下 CSS 盒模型,标准盒模型和 IE 盒模型有什么区别? [简单] #CSS#基础
▌ 考察点
CSS 基础理解,是否清楚 box-sizing 的作用
▌ 参考答案
标准盒模型(content-box)中,width/height 只包含内容区域,padding 和 border 会额外增加元素尺寸。
IE 盒模型(border-box)中,width/height 包含 content + padding + border,更符合直觉。
可以通过 box-sizing: border-box 切换到 IE 盒模型,现代项目通常全局设置 border-box。
▌ 追问方向
→如何用一行 CSS 全局统一盒模型?
→height: 100% 有时候不生效,是什么原因?
→margin 折叠发生在什么场景?如何避免?
▌ 评分参考(1-4 分)
1.1分:只知道标准盒模型
2.2分:能区分两种盒模型
3.3分:知道 box-sizing 切换
4.4分:能结合实际场景说清楚 margin 折叠等问题
Q2BFC 是什么?它有哪些触发条件,有哪些实际应用场景? [中等] #CSS#布局
▌ 考察点
CSS 格式化上下文原理,是否能结合实际场景
▌ 参考答案
BFC(块级格式化上下文)是一个独立的渲染区域,内部元素布局不影响外部。
触发条件:overflow 不为 visible、float 不为 none、position 为 absolute/fixed、display 为 inline-block/flex/grid 等。
实际应用:①清除浮动(overflow:hidden)②防止 margin 折叠 ③自适应两列布局(BFC 不与浮动元素重叠)。
▌ 追问方向
→IFC、GFC、FFC 分别是什么?
→为什么 overflow:hidden 能清除浮动?
→使用 clearfix 和 BFC 清浮动有什么区别?
▌ 评分参考(1-4 分)
5.1分:说出 BFC 是格式化上下文
6.2分:能说出几个触发条件
7.3分:能结合清除浮动等场景
8.4分:理解原理,能横向对比 IFC/FFC
Q3Flex 布局中 flex: 1 是什么的简写,各个值代表什么含义? [简单] #CSS#Flex
▌ 考察点
Flex 属性理解深度
▌ 参考答案
flex: 1 是 flex-grow: 1; flex-shrink: 1; flex-basis: 0% 的简写。
flex-grow 控制放大比例,flex-shrink 控制缩小比例,flex-basis 设置初始主轴尺寸。
flex: 1 的意思是:在空间充足时等比放大,空间不足时等比缩小,初始尺寸为 0。
注意 flex: auto 等价于 1 1 auto,与 flex: 1 行为有差异。
▌ 追问方向
→flex-basis 设置为 0 和 auto 有什么区别?
→flex 容器中 align-items 和 align-content 有什么区别?
→如何用 flex 实现圣杯/双飞翼布局?
▌ 评分参考(1-4 分)
9.1分:知道是简写
10.2分:能说出三个属性
11.3分:理解 flex:1 和 flex:auto 的区别
12.4分:能在复杂布局中灵活运用
Q4CSS 选择器优先级如何计算?!important 的副作用是什么? [简单] #CSS#基础
▌ 考察点
CSS 优先级体系,工程实践意识
▌ 参考答案
优先级按权重计算:内联样式(1000) > ID选择器(100) > 类/伪类/属性选择器(10) > 元素/伪元素(1) > 通配符(0)。
多个选择器组合时权重相加。
!important 会覆盖所有,但副作用明显:破坏正常级联顺序,难以调试,被滥用后只能用更多 !important 覆盖,形成恶性循环。
▌ 追问方向
→伪类和伪元素有什么区别?
→CSS 中 :is() 和 :where() 有什么区别?
→如何避免样式污染?CSS Modules 解决了什么问题?
▌ 评分参考(1-4 分)
13.1分:知道优先级概念
14.2分:能说出权重数值
15.3分:能说出 !important 的副作用
16.4分:能结合工程实践谈样式隔离
Q5说说 position 各个取值的区别,sticky 定位的原理和常见问题? [中等] #CSS#布局
▌ 考察点
定位机制理解,实际开发经验
▌ 参考答案
static(默认流)、relative(相对自身偏移,占位不变)、absolute(脱离文档流,相对最近非 static 祖先)
fixed(相对视口)、sticky(粘性定位,相对最近可滚动祖先,需设置 top/bottom 值)。
sticky 常见问题:①父元素 overflow 不为 visible 会导致失效 ②需要明确 top/left 等阈值 ③父元素高度不足时不会粘住。
▌ 追问方向
→z-index 在什么情况下会失效?
→absolute 元素如何水平垂直居中?
→如何实现表格头部吸顶固定?
▌ 评分参考(1-4 分)
17.1分:能区分 absolute 和 fixed
18.2分:能说清楚所有取值
19.3分:理解 sticky 的前置条件
20.4分:能说出 sticky 的 overflow 陷阱并给出方案
Q6CSS 动画 transition 和 animation 有什么区别?如何实现高性能动画? [中等] #CSS#性能#动画
▌ 考察点
动画原理,性能优化意识
▌ 参考答案
transition 是过渡,用于状态切换,需要触发器(如 hover),只有开始和结束两帧。
animation 是帧动画,可以定义关键帧、循环、自动播放。
高性能动画关键:①使用 transform 和 opacity(触发 GPU 合成层,避免 reflow/repaint)
②避免使用 left/top/width 等触发布局的属性 ③使用 will-change: transform 提示浏览器创建合成层(谨慎使用,内存消耗)
④使用 requestAnimationFrame 替代 setTimeout 做 JS 动画。
▌ 追问方向
→浏览器渲染流水线是什么?reflow 和 repaint 的区别?
→will-change 滥用会导致什么问题?
→如何用 CSS 实现一个骨架屏的闪光动画?
▌ 评分参考(1-4 分)
21.1分:知道两者用途区别
22.2分:能说出触发条件差异
23.3分:知道 transform/opacity 不触发重排
24.4分:理解合成层原理,有性能优化实践
⚡二、JavaScript 核心 |
Q7说说 JavaScript 的原型链,instanceof 的实现原理是什么? [中等] #JS#原型
▌ 考察点
原型链理解深度,底层机制
▌ 参考答案
每个对象都有 __proto__ 指向其构造函数的 prototype。当访问属性时,JS 引擎沿原型链向上查找直到 null。 |
instanceof 原理:沿左操作数的原型链查找,是否等于右操作数的 prototype。 |
function myInstanceof(obj, ctor) { |
letproto = Object.getPrototypeOf(obj); |
while(proto){ |
if(proto=== ctor.prototype) return true; |
proto= Object.getPrototypeOf(proto); |
} |
returnfalse; |
} |
▌ 追问方向
→Object.create(null) 创建的对象有什么特点?
→如何判断一个属性是自身属性还是原型链属性?
→class 语法和构造函数+prototype 有什么本质区别?
▌ 评分参考(1-4 分)
25.1分:知道原型链查找机制
26.2分:能说清楚 __proto__ 和 prototype
27.3分:能手写 instanceof
28.4分:理解 class 语法糖本质,能谈到继承链
Q8解释事件循环机制,宏任务和微任务的执行顺序? [偏难] #JS#异步#事件循环
▌ 考察点
异步机制理解,是否能分析复杂执行顺序
▌ 参考答案
事件循环:调用栈清空后,先清空微任务队列(Promise.then、MutationObserver、queueMicrotask),
再执行一个宏任务(setTimeout、setInterval、I/O、MessageChannel),如此循环。
async/await 是 Promise 的语法糖,await 后的代码相当于 .then() 回调,是微任务。
执行顺序:同步代码 → 微任务 → 宏任务 → 微任务 → 宏任务...
▌ 追问方向
→请分析包含 Promise+setTimeout 混合代码的输出顺序
→Node.js 的事件循环和浏览器有什么不同?
→requestAnimationFrame 在事件循环中处于什么位置?
▌ 评分参考(1-4 分)
29.1分:知道宏任务/微任务概念
30.2分:能说清楚执行顺序规则
31.3分:能分析包含 Promise+setTimeout 的复杂题
32.4分:了解 Node.js 差异和 rAF 时机
Q9闭包是什么?有哪些应用场景?可能导致什么问题? [中等] #JS#闭包
▌ 考察点
闭包本质理解,工程应用,内存问题意识
▌ 参考答案
闭包是函数及其引用的词法作用域的组合。当内部函数访问外部函数的变量时,即使外部函数已执行完,该变量仍被保留。
应用场景:①函数柯里化 ②模块模式(私有变量)③防抖节流函数 ④once(只执行一次)⑤缓存(memoize)。
内存问题:闭包持有外部变量引用,如果闭包长期存活(如事件监听),外部变量无法被 GC,可能导致内存泄漏。
▌ 追问方向
→手写一个防抖函数(支持立即执行版本)
→手写一个 memoize 函数
→经典循环+var+setTimeout 闭包陷阱如何解决?
▌ 评分参考(1-4 分)
33.1分:能解释闭包概念
34.2分:能举出实际使用场景
35.3分:能手写防抖/节流
36.4分:能分析内存泄漏原因,能手写 memoize
Q10this 的指向规则有哪些?call/apply/bind 的区别?箭头函数中的 this 是什么? [中等] #JS#this
▌ 考察点
this 绑定规则,是否理解箭头函数的本质
▌ 参考答案
this 指向规则(优先级递减):new 绑定 > 显式绑定(call/apply/bind) > 隐式绑定(obj.fn()) > 默认绑定。
call/apply 立即调用(参数形式不同),bind 返回新函数。
箭头函数没有自己的 this,继承定义时外层作用域的 this,不能用 call/apply/bind 改变。
▌ 追问方向
→如何实现 Function.prototype.call?
→箭头函数有哪些场景不适合使用?(如对象方法、prototype 方法)
→React 类组件中事件处理函数为什么需要绑定 this?
▌ 评分参考(1-4 分)
37.1分:知道默认绑定和隐式绑定
38.2分:能说出四条规则和优先级
39.3分:手写 call/apply 实现
40.4分:结合 React 类组件等实际场景分析
Q11ES6+ 有哪些你常用的新特性?Symbol 和 WeakMap 分别解决了什么问题? [中等] #JS#ES6+
▌ 考察点
ES6+ 掌握广度,对语言设计意图的理解
▌ 参考答案
常用:解构赋值、模板字符串、默认参数、rest/spread、箭头函数、class、模块化、Promise、async/await、Optional chaining(?.)、Nullish coalescing(??)。
Symbol:创建唯一不可变标识符,用于定义私有属性、自定义迭代器(Symbol.iterator)、避免属性名冲突。
WeakMap:键必须是对象,弱引用不阻止 GC,适合存储对象的私有数据或缓存,键对象销毁时自动清理,避免内存泄漏。
▌ 追问方向
→可选链 ?. 和逻辑赋值运算符 ??= 有什么区别?
→如何用 Symbol.iterator 实现一个自定义可迭代对象?
→WeakRef 和 FinalizationRegistry 是什么,有什么用途?
▌ 评分参考(1-4 分)
41.1分:能列出常用 ES6 特性
42.2分:能解释 Symbol 的唯一性
43.3分:理解 WeakMap 弱引用和 GC 关系
44.4分:了解新提案,能谈语言设计意图
Q12手写题:实现一个深拷贝函数,需要处理循环引用、特殊类型(Date、RegExp、Map、Set) [偏难] #JS#手写#编码
▌ 考察点
编码能力,边界意识,数据结构理解
▌ 参考答案
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); |
if(map.has(obj)) return map.get(obj); // 循环引用 |
if(obj instanceof Map) { |
constclone = new Map(); |
map.set(obj,clone); |
obj.forEach((v,k) => clone.set(deepClone(k, map), deepClone(v, map))); |
returnclone; |
} |
if(obj instanceof Set) { |
constclone = new Set(); |
map.set(obj,clone); |
obj.forEach(v=> clone.add(deepClone(v, map))); |
returnclone; |
} |
constclone = Array.isArray(obj) ? [] : {}; |
map.set(obj,clone); |
for(const key of Reflect.ownKeys(obj)) { |
clone[key]= deepClone(obj[key], map); |
} |
returnclone; |
} |
▌ 追问方向
→为什么用 WeakMap 而不是 Map 存储已克隆对象?
→JSON.parse(JSON.stringify()) 深拷贝有哪些缺陷?
→如果需要支持 Symbol 键的属性,需要怎么改造?
▌ 评分参考(1-4 分)
45.1分:能处理基本类型和普通对象
46.2分:能处理数组和 Date
47.3分:能处理循环引用
48.4分:能处理 Map/Set/Symbol 键,使用 WeakMap
Q13说说垃圾回收机制,哪些情况会导致内存泄漏?如何排查? [偏难] #JS#内存#性能
▌ 考察点
底层原理意识,性能排查能力
▌ 参考答案
V8 使用分代 GC:新生代(Scavenge 算法,复制存活对象)和老生代(标记清除+标记整理)。
内存泄漏常见场景:①全局变量意外赋值 ②闭包持有大对象引用 ③DOM 事件监听未移除 ④游离 DOM 引用 ⑤定时器未清除 ⑥缓存无限增长。
排查方法:Chrome DevTools Memory 面板 → Take Heap Snapshot 对比前后内存 → Allocation Timeline 录制分配 → Detached DOM 查找游离节点。
▌ 追问方向
→WeakMap/WeakSet/WeakRef 如何配合 GC?
→如何在 React 中避免内存泄漏?(useEffect 清理函数)
→Detached DOM Tree 是什么,如何用 DevTools 找到它?
▌ 评分参考(1-4 分)
49.1分:知道 GC 基本概念
50.2分:能列出内存泄漏场景
51.3分:了解分代 GC 机制
52.4分:有实际排查经验,能操作 DevTools
Q14Promise 有哪些静态方法?手写 Promise.all 和 Promise.allSettled [中等] #JS#Promise#手写
▌ 考察点
异步 API 掌握,手写能力
▌ 参考答案
Promise.all = (promises) => new Promise((resolve, reject) => { |
constresults = []; let count = 0; |
promises.forEach((p,i) => { |
Promise.resolve(p).then(val=> { |
results[i]= val; |
if(++count === promises.length) resolve(results); |
}).catch(reject); |
}); |
if(!promises.length) resolve([]); |
}); |
Promise.allSettled = (promises) => Promise.all( |
promises.map(p=> Promise.resolve(p) |
.then(value=> ({ status: 'fulfilled', value })) |
.catch(reason=> ({ status: 'rejected', reason }))) |
); |
▌ 追问方向
→如何实现一个并发限制的异步调度器?
→Promise 链式调用中如何捕获错误?.catch 和 try/catch 的区别?
→async 函数的返回值是什么?如果 return 一个 Promise 会怎样?
▌ 评分参考(1-4 分)
53.1分:知道 all 和 race
54.2分:能区分 all 和 allSettled
55.3分:能手写 Promise.all
56.4分:能实现并发调度器
🔷三、TypeScript |
Q15TypeScript 中 type 和 interface 有什么区别?各自的适用场景? [简单] #TS#基础
▌ 考察点
TypeScript 类型系统理解
▌ 参考答案
主要区别:①interface 可声明合并(declaration merging),type 不能
②type 可以用联合类型、交叉类型、条件类型,interface 更受限
③interface 只能描述对象结构,type 可以是任意类型别名(包括基本类型、联合、元组)。
适用场景:对象/类的形状描述优先用 interface(可扩展),复杂类型操作用 type,公开库的 API 类型用 interface(方便使用者扩展)。
▌ 追问方向
→什么是声明合并(declaration merging),有什么实际应用?
→extends 在 interface 和 type 中分别代表什么?
→interface 可以 implements,type 可以吗?
▌ 评分参考(1-4 分)
57.1分:知道基本语法区别
58.2分:能说出合并声明特性
59.3分:能给出适用场景建议
60.4分:理解设计意图,有工程化的类型定义实践
Q16解释 TypeScript 中的泛型,说说你在实际项目中如何使用泛型? [中等] #TS#泛型
▌ 考察点
泛型理解和应用深度
▌ 参考答案
泛型允许创建可重用的组件,延迟指定类型。基本语法:function identity |
实际应用:①通用的请求函数 fetch |
②通用的列表组件 props ③工具类型(Partial、Readonly、ReturnType 底层都是泛型) |
④泛型约束 |
▌ 追问方向
→泛型约束 extends 的作用是什么?
→infer 关键字有什么用?能举一个例子?
→实现一个 DeepReadonly
▌ 评分参考(1-4 分)
61.1分:知道泛型基本语法
62.2分:能在函数中使用泛型
63.3分:在 API 调用、组件 props 中实际应用
64.4分:能使用 infer、条件类型,手写工具类型
Q17TypeScript 的 unknown、any、never 分别是什么,有什么区别? [中等] #TS#类型系统
▌ 考察点
类型系统安全性理解
▌ 参考答案
any:关闭类型检查,可赋值给任何类型,绕过类型系统(不安全)。
unknown:类型安全的 any,不能直接操作,必须先做类型收窄(类型守卫)。
never:表示永不发生的类型,如抛出异常的函数返回值、死循环,在联合类型中会被消除(T | never = T)。
使用原则:用 unknown 代替 any,强制调用方做类型检查;利用 never 做穷尽性检查。
▌ 追问方向
→如何用 never 实现穷尽性检查(exhaustive check)?
→is 关键字是什么?类型守卫有哪些写法?
→as const 和类型断言有什么区别?
▌ 评分参考(1-4 分)
65.1分:知道 any 是什么
66.2分:能区分 unknown 和 any
67.3分:理解 never 在类型操作中的作用
68.4分:能用 never 做穷尽检查,理解类型安全设计
Q18说说 TypeScript 的工具类型:Partial、Required、Readonly、Pick、Omit、Record,能手写其中几个吗? [偏难] #TS#工具类型#手写
▌ 考察点
工具类型掌握程度,映射类型理解
▌ 参考答案
Partial |
Required |
Readonly |
Pick:type Pick= { [P in K]: T[P] } |
Omit:type Omit= Pick> |
Record:type Record |
▌ 追问方向
→Exclude和 Extract的实现原理?
→如何实现 DeepPartial
→ReturnType 和 Parameters 的底层实现用到了什么?
▌ 评分参考(1-4 分)
69.1分:知道这些工具类型的用途
70.2分:能手写 Partial/Readonly
71.3分:能手写 Pick/Omit,理解映射类型
72.4分:能手写 DeepPartial、条件类型工具
Q19TypeScript 中装饰器(Decorator)的原理是什么?在什么场景下会用到? [偏难] #TS#装饰器
▌ 考察点
对元编程的理解,工程化实践(如 NestJS)
▌ 参考答案
装饰器是一种特殊声明,可以附加到类、方法、属性或参数上,本质是一个函数,接收目标对象作为参数。
执行时机是类定义时(非实例化时)。
应用场景:①依赖注入(NestJS @Injectable)②ORM(@Column、@Entity)③日志/监控 AOP ④权限控制 @Auth ⑤参数验证 @IsEmail。
需要在 tsconfig 开启 experimentalDecorators。
▌ 追问方向
→类装饰器和方法装饰器的参数分别是什么?
→Reflect Metadata 是什么?装饰器依赖它做什么?
→装饰器执行顺序是怎样的(多个装饰器叠加时)?
▌ 评分参考(1-4 分)
73.1分:知道装饰器的语法
74.2分:能说出几个应用场景
75.3分:理解执行时机和参数
76.4分:了解 Reflect.metadata,能实现自定义装饰器
⚛️四、React 深度 |
Q20React 的 Fiber 架构是什么?为什么要从 Stack Reconciler 改成 Fiber? [偏难] #React#Fiber#架构
▌ 考察点
对 React 底层原理的掌握程度
▌ 参考答案
旧 Stack Reconciler 是递归遍历,JS 单线程情况下一旦开始无法中断,长列表会阻塞主线程导致卡顿(掉帧)。
Fiber 架构将渲染工作拆分为小单元(Fiber Node),每个 Fiber 对应一个组件,通过链表结构(return/child/sibling)连接。
利用 requestIdleCallback 思想(实际是 MessageChannel 模拟),在浏览器空闲时间分批执行,可中断/恢复/丢弃。
这使得 Concurrent Mode(时间切片、优先级调度、Suspense)成为可能。
▌ 追问方向
→Fiber 双缓存机制是什么?current 树和 workInProgress 树的作用?
→什么是 React 的优先级模型?Lane 模型是什么?
→useTransition 和 useDeferredValue 解决了什么问题?
▌ 评分参考(1-4 分)
77.1分:知道 Fiber 是新架构
78.2分:能说出可中断渲染的意义
79.3分:理解 Fiber 链表结构和双缓存
80.4分:了解 Lane 优先级,能联系 Concurrent 特性
Q21React Hooks 的设计原则是什么?为什么 Hooks 不能在条件语句中调用? [中等] #React#Hooks
▌ 考察点
Hooks 底层原理理解
▌ 参考答案
Hooks 依赖调用顺序来关联 fiber 节点上存储的状态链表(memoizedState 单向链表)。
每次渲染时,React 按照 Hooks 调用顺序依次读取链表节点。
如果在条件语句中调用,某次渲染可能跳过某个 Hook,导致后续 Hook 读取错误的状态节点,状态错位。
设计原则:①只在最顶层调用 ②只在 React 函数中调用 ③命名以 use 开头。
▌ 追问方向
→useEffect 的依赖数组为空数组和不传有什么区别?
→如何用 Hooks 实现 componentDidUpdate 的行为(跳过首次执行)?
→useLayoutEffect 和 useEffect 的执行时机有什么区别?
▌ 评分参考(1-4 分)
81.1分:知道不能在条件中调用
82.2分:能说出是因为调用顺序
83.3分:能描述链表数据结构
84.4分:能结合源码或自实现解释
Q22解释 React 的渲染优化:React.memo、useMemo、useCallback 分别什么时候用? [中等] #React#性能#优化
▌ 考察点
性能优化思路,对浅比较的理解
▌ 参考答案
React.memo:对组件 props 做浅比较,props 未变时跳过重渲染。
适合:纯展示组件、父组件频繁更新但子组件 props 很少变化。
useMemo:缓存计算结果(依赖不变时返回缓存值)。
适合:昂贵计算(排序/过滤大列表),以及需要保持引用稳定的对象/数组(传给 memo 子组件)。
useCallback:缓存函数引用。
适合:作为 props 传给 memo 子组件的回调函数,避免每次父渲染创建新函数导致子组件无效重渲染。
不要过度使用——本身有开销,小组件优化收益为负。
▌ 追问方向
→浅比较是什么?为什么对象字面量的 prop 会绕过 memo?
→React.memo 的第二个参数有什么用?
→如何用 DevTools Profiler 定位不必要的重渲染?
▌ 评分参考(1-4 分)
85.1分:能区分三者用途
86.2分:理解浅比较的局限
87.3分:能说出误用场景
88.4分:有 Profiler 实战经验,能量化优化效果
Q23useState 的 setState 是同步还是异步的?React 18 的自动批处理有什么变化? [中等] #React#状态#React18
▌ 考察点
React 调度机制理解,版本演进认知
▌ 参考答案
React 17 之前:React 合成事件内的 setState 是批处理(异步执行),setTimeout/Promise 中的 setState 是同步执行(每次触发渲染)。
React 18 之后:Auto Batching,所有 setState 默认批处理,包括 setTimeout、Promise、原生事件。
原理:通过 createRoot 启动 Concurrent 模式,用调度器统一管理。
如果需要强制同步更新可用 flushSync。
▌ 追问方向
→flushSync 的使用场景是什么?
→React 18 的 createRoot 和 ReactDOM.render 有什么区别?
→useReducer 对比 useState 有什么优势?适合什么场景?
▌ 评分参考(1-4 分)
89.1分:知道 React 事件中是批处理
90.2分:能说出 React 17 vs 18 的区别
91.3分:理解 Auto Batching 的原理
92.4分:了解 flushSync,能联系 Concurrent Mode
Q24React 中如何管理状态?Context、Redux、Zustand、Jotai 各有什么适用场景? [中等] #React#状态管理
▌ 考察点
架构设计能力,技术选型意识
▌ 参考答案
Context:React 内置,适合低频更新的全局数据(主题、语言、用户信息)。问题:value 变化导致所有消费者重渲染。
Redux:集中式状态,单向数据流,适合大型复杂应用,DevTools 强大。
Zustand:轻量,基于 hooks,支持选择性订阅,无 Provider 包裹,适合中小型项目。
Jotai/Recoil:原子化状态,细粒度更新,适合状态依赖关系复杂的场景(如电子表格)。
▌ 追问方向
→Context 的性能问题如何优化?(context split、memo、useMemo value)
→Redux Toolkit 解决了 Redux 哪些痛点?
→如何决定哪些状态放全局、哪些放本地?
▌ 评分参考(1-4 分)
93.1分:知道 Context 和 Redux
94.2分:能说出各自适用场景
95.3分:了解 Zustand/Jotai 等新方案
96.4分:能给出状态划分原则,有实际项目选型经验
Q25React 的 key 属性有什么作用?为什么不能用 index 作为 key? [简单] #React#Diff#基础
▌ 考察点
Diff 算法理解,基础但容易说不透
▌ 参考答案
key 用于 React Diff 算法识别列表中的元素,帮助 React 在更新时复用 DOM 节点。
当 key 不变时,React 认为是同一个元素,直接更新 props;key 变化时,会销毁旧节点、创建新节点。
用 index 作 key 的问题:列表增删/排序时 index 会变化,React 会重新映射错误的元素,
可能导致输入状态错乱(如 input 的 value)、无效的动画效果,以及性能下降(无法复用 DOM)。
正确做法:用数据的唯一稳定 id。
▌ 追问方向
→React Diff 算法的三个假设(启发式)是什么?
→同层比较是什么意思?React 会进行跨层比较吗?
→key 可以用在哪些场景强制重置组件状态?
▌ 评分参考(1-4 分)
97.1分:知道 key 用于 Diff
98.2分:能说出 index 问题的表现
99.3分:能说出三个 Diff 假设
100.4分:了解 key 强制重置的技巧应用
Q26如何设计一个高扩展性的 React 自定义 Hook?举一个你写过的复杂 Hook 的例子。 [偏难] #React#Hooks#设计
▌ 考察点
工程化设计能力,抽象能力,实际项目经验
▌ 参考答案
设计原则:①单一职责 ②良好的输入输出类型(TypeScript)③合适的初始值和重置机制 ④清理副作用(返回 cleanup)⑤避免过度封装。
示例 useRequest Hook:封装 loading、data、error 状态,支持 manual 模式(手动触发)、轮询、防抖、
取消(AbortController)、依赖变化自动重新请求。
另一个例子:useIntersectionObserver 实现懒加载/无限滚动,封装 IntersectionObserver 的创建销毁,提供 inView 状态。
▌ 追问方向
→如何测试一个自定义 Hook?(@testing-library/react-hooks)
→如果 Hook 需要支持 SSR,有什么需要注意的?
→ahooks 和 react-use 中有哪些 Hook 给了你设计启发?
▌ 评分参考(1-4 分)
101.1分:能写出简单的状态 Hook
102.2分:能设计带副作用清理的 Hook
103.3分:能举出实际项目中的复杂 Hook
104.4分:考虑到 SSR、TypeScript、测试等工程化要素
Q27React Server Components(RSC)是什么?和传统 SSR 有什么区别? [偏难] #React#RSC#Next.js
▌ 考察点
前沿技术掌握,架构理解
▌ 参考答案
RSC 是在服务器上渲染且不参与客户端 bundle 的组件,不能使用 useState、useEffect、浏览器 API。
和 SSR 的区别:SSR 是在服务器生成 HTML 字符串,所有代码仍会发送到客户端(hydration)。
RSC 的组件代码完全不发送到客户端(零 bundle),能直接访问数据库/文件系统,流式传输,
与 Client Components 混合使用。
适用:数据获取层、静态展示组件、减小客户端 bundle 体积。
▌ 追问方向
→'use client' 和 'use server' 指令的作用是什么?
→如何在 RSC 和 Client Component 之间传递数据?
→Next.js 的 App Router 和 Pages Router 有什么核心区别?
▌ 评分参考(1-4 分)
105.1分:知道 RSC 是服务端组件
106.2分:能区分 RSC 和 SSR
107.3分:理解 bundle 体积和数据获取优势
108.4分:了解 use client/server 边界和 App Router 设计
💚五、Vue 核心 |
Q28Vue 2 和 Vue 3 的响应式系统有什么区别?Proxy 相比 Object.defineProperty 的优势? [中等] #Vue#响应式#原理
▌ 考察点
响应式原理理解,Vue2 vs Vue3 对比
▌ 参考答案
Vue 2 用 Object.defineProperty 劫持属性的 getter/setter,缺陷:①无法监测属性新增/删除(需 Vue.set)
②数组变更需特殊处理(重写数组方法)③初始化时需要递归遍历所有属性(性能)。
Vue 3 用 Proxy 代理整个对象,优势:①可拦截属性新增/删除 ②原生支持数组索引赋值
③懒加载(访问时才劫持子对象)④支持 Map/Set 等数据结构。
▌ 追问方向
→Vue 3 的 reactive 和 ref 有什么区别?什么时候用哪个?
→watchEffect 和 watch 有什么区别?
→Vue 3 Composition API vs Options API 的优缺点?
▌ 评分参考(1-4 分)
109.1分:知道 Vue3 改用 Proxy
110.2分:能说出 defineProperty 的缺陷
111.3分:能详细对比 Proxy 的优势
112.4分:理解懒代理机制,能结合 ref/reactive 实践
Q29Vue 3 的 Composition API 相比 Options API 有哪些优势?setup 的执行时机? [中等] #Vue#Composition API
▌ 考察点
Vue 3 新特性掌握,代码组织能力
▌ 参考答案
Composition API 优势:①逻辑复用(自定义 composables 代替 mixin,无命名冲突,类型更好)
②逻辑聚合(相关逻辑放在一起,不再分散在 data/methods/computed/watch 中)
③更好的 TypeScript 支持 ④更小的 bundle(tree-shaking 友好)。
setup 执行时机:beforeCreate 之前,此时组件实例未创建,不能访问 this,data/computed 未初始化。
▌ 追问方向
→自定义 composable 和 Vue 2 的 mixin 有什么根本区别?
→如何在 Composition API 中使用生命周期钩子?
→defineProps 和 withDefaults 怎么用?
▌ 评分参考(1-4 分)
113.1分:知道 Composition API 是新写法
114.2分:能说出逻辑复用的优势
115.3分:能对比 mixin 和 composable
116.4分:了解 setup 时机,有实际 composable 封装经验
Q30Vue 3 中 v-model 的语法糖展开是什么?多个 v-model 如何实现? [中等] #Vue#v-model#组件通信
▌ 考察点
组件通信原理理解
▌ 参考答案
Vue 3 v-model 语法糖:
多个 v-model:
子组件用 defineProps(['title','content']) 和 defineEmits(['update:title','update:content'])。
▌ 追问方向
→如何实现自定义的 v-model 修饰符?
→v-model 和 .sync(Vue 2)的区别?
→defineModel 宏(Vue 3.4+)简化了什么?
▌ 评分参考(1-4 分)
117.1分:知道 v-model 是语法糖
118.2分:能说出展开形式
119.3分:能实现多个 v-model
120.4分:了解自定义修饰符或 defineModel 新语法
🔧六、工程化与构建 |
Q31Webpack 的构建流程是什么?Loader 和 Plugin 的区别和工作时机? [中等] #Webpack#工程化
▌ 考察点
工程化基础,构建工具原理
▌ 参考答案
Webpack 构建流程:①初始化参数(合并配置)②开始编译(compiler.run)③确定入口(entry)
④编译模块(调用 loader 链转换)⑤完成模块编译(建立依赖关系图)⑥输出资源(chunk → bundle)⑦写入文件系统。
Loader:转换文件,从右到左执行,是一个函数。
Plugin:扩展功能,基于 Tapable 事件钩子,在构建生命周期的特定节点注入逻辑。
▌ 追问方向
→如何写一个简单的 Loader?
→HMR(热模块替换)的工作原理是什么?
→Webpack 的 Tree Shaking 如何生效?为什么需要 ES Module?
▌ 评分参考(1-4 分)
121.1分:知道 Loader 转换文件
122.2分:能说出构建流程步骤
123.3分:理解 Plugin 的 Tapable 机制
124.4分:能手写简单 Loader,理解 Tree Shaking 原理
Q32Vite 的原理是什么?为什么开发环境比 Webpack 快很多? [中等] #Vite#构建工具#ESM
▌ 考察点
新构建工具理解,底层原理
▌ 参考答案
Vite 开发环境快的原因:①基于原生 ES Module(浏览器直接 import,不打包)
②按需编译(访问哪个文件才编译哪个,而 Webpack 需要全量构建)
③预构建(用 esbuild 将 node_modules 预打包成单文件,速度比 babel 快 10-100x)
④HMR 精准(模块级别更新,不像 Webpack 重新编译整个 bundle)。
生产环境用 Rollup 打包(更好的 tree-shaking、chunk 分割)。
▌ 追问方向
→Vite 的依赖预构建解决了什么问题?
→如何在 Vite 中配置路径别名、环境变量?
→Turbopack 是什么?和 Vite 相比有什么优势?
▌ 评分参考(1-4 分)
125.1分:知道 Vite 用 ESM
126.2分:能说出按需编译和 esbuild
127.3分:能解释预构建的作用
128.4分:了解 Rollup 生产构建,了解 Turbopack 等趋势
Q33如何做前端性能优化?从构建、网络、运行时三个维度说说你的实践。 [偏难] #性能优化#工程化
▌ 考察点
性能优化知识体系,实战经验
▌ 参考答案
构建:Code Splitting(路由/组件级别懒加载)、Tree Shaking、压缩(Terser/CSS Nano)、图片优化(WebP/AVIF)、资源 Hash 缓存。
网络:HTTP/2 多路复用、CDN、强缓存/协商缓存(Cache-Control/ETag)、预加载(preload/prefetch/preconnect)、Gzip/Brotli 压缩。
运行时:虚拟列表(大列表渲染)、防抖节流、RAF 替代 setTimeout、减少重排重绘、Web Worker(CPU 密集任务离线)、骨架屏提升感知性能。
▌ 追问方向
→说说你在项目中做过的最有效的一次性能优化,数据是什么?
→Core Web Vitals(LCP、FID/INP、CLS)分别是什么?如何优化 LCP?
→如何衡量性能优化的效果?有哪些工具?
▌ 评分参考(1-4 分)
129.1分:能列出几个常见优化手段
130.2分:能分维度系统讲
131.3分:有实际项目数据
132.4分:了解 CWV 指标,能用 Lighthouse/DevTools 量化
Q34ESModule 和 CommonJS 的区别?为什么 Tree Shaking 只能用于 ESM? [中等] #模块化#工程化#ESM
▌ 考察点
模块化原理,Tree Shaking 前置知识
▌ 参考答案
CJS:运行时加载,require() 是函数调用,导出是值的拷贝,支持条件导入(if 内 require)。
ESM:编译时静态分析,import/export 是声明式语法,导出是活引用(live binding),不支持条件导入。
Tree Shaking 依赖静态分析:工具在编译时扫描 import/export,找出未被引用的 export 并删除。
CJS 的 require 是动态的(路径可以是变量、可以在条件中),无法在编译时确定哪些会被用到。
▌ 追问方向
→如何让一个 npm 包支持 Tree Shaking?(package.json 的 exports 和 sideEffects)
→import() 动态导入和静态导入有什么区别?
→如何检查项目中哪些包没有被 Tree Shaking 掉?(webpack-bundle-analyzer)
▌ 评分参考(1-4 分)
133.1分:能区分 CJS 和 ESM
134.2分:能说出静态分析的原因
135.3分:理解活引用(live binding)
136.4分:了解 sideEffects 配置,能用 bundle 分析工具
Q35前端监控体系如何设计?如何捕获 JS 错误、性能指标和用户行为? [偏难] #监控#工程化#稳定性
▌ 考察点
系统设计能力,稳定性工程意识
▌ 参考答案
监控体系三层:①错误监控:window.onerror(JS 错误)、unhandledrejection(Promise 未捕获)
window.addEventListener('error', ..., true)(资源加载失败)、React ErrorBoundary(组件错误)
②性能监控:PerformanceObserver 采集 LCP/FID/CLS/TTFB,Navigation Timing API,Resource Timing
③用户行为:自定义埋点(PV/UV/点击)、行为录制(rrweb)。
上报策略:sendBeacon(页面卸载时不丢数据)、采样率、批量上报、错误聚合去重。
▌ 追问方向
→sourcemap 在生产环境如何使用?如何保护 sourcemap 不泄露到用户?
→如何在不影响性能的情况下采集用户行为?
→你们项目有监控吗?报警策略是怎么设计的?
▌ 评分参考(1-4 分)
137.1分:知道 window.onerror
138.2分:能分三类讲监控体系
139.3分:了解上报策略和 sendBeacon
140.4分:有实际监控建设经验,了解 sourcemap 安全
🌐七、浏览器与网络 |
Q36从输入 URL 到页面显示,详细说说发生了什么? [中等] #浏览器#网络#经典题
▌ 考察点
知识体系完整性,是否能深入展开
▌ 参考答案
①DNS 解析(本地缓存→递归查询→根域名→顶级域→权威域名)
②TCP 三次握手 ③TLS 握手(HTTPS)④发起 HTTP 请求 ⑤服务器处理返回响应
⑥浏览器解析 HTML(构建 DOM 树,遇到 CSS 构建 CSSOM,JS 阻塞解析)
⑦合并 DOM+CSSOM = Render Tree ⑧Layout(计算位置和尺寸)
⑨Paint(绘制到图层)⑩Composite(合成图层显示)⑪TCP 四次挥手。
▌ 追问方向
→HTTP/2 和 HTTP/1.1 的主要区别?HTTP/3 用的是什么协议?
→浏览器为什么要限制同域名并发请求数?
→preload 和 prefetch 分别在页面加载的哪个阶段生效?
▌ 评分参考(1-4 分)
141.1分:能说出几个主要步骤
142.2分:能覆盖 DNS/TCP/HTTP/渲染全流程
143.3分:能展开渲染管线细节
144.4分:能结合 HTTP/2、性能优化深入讨论
Q37浏览器的同源策略是什么?跨域请求有哪些解决方案?各有什么优缺点? [中等] #浏览器#安全#跨域
▌ 考察点
Web 安全基础,实际开发经验
▌ 参考答案
同源:协议+域名+端口均相同。
跨域方案:①CORS(服务器设置 Access-Control-Allow-Origin,主流推荐)
②代理(开发时 Webpack/Vite devServer proxy,生产 Nginx 反向代理)
③JSONP(只支持 GET,利用 script 标签无跨域限制,老方案)
④postMessage(iframe 跨域通信)⑤document.domain(同主域不同子域,已不推荐)。
CORS 分简单请求和预检请求(OPTIONS),需要注意 Cookie 跨域需要 credentials。
▌ 追问方向
→CORS 预检请求什么时候触发?如何减少预检请求?
→为什么跨域请求不带 Cookie?如何配置才能带?
→CSP(内容安全策略)是什么?能防止什么类型的攻击?
▌ 评分参考(1-4 分)
145.1分:知道同源定义
146.2分:能列出几种跨域方案
147.3分:理解 CORS 预检,知道 credentials
148.4分:了解安全含义,能结合 CSP/CSRF 讨论
Q38XSS 和 CSRF 攻击的原理是什么?如何防御? [中等] #安全#浏览器
▌ 考察点
Web 安全意识,实战防御经验
▌ 参考答案
XSS(跨站脚本):注入恶意脚本到页面执行。分反射型(URL参数)、存储型(数据库)、DOM型。
防御:①输出转义(HTML实体编码)②CSP(禁止内联脚本)③HttpOnly Cookie(防JS读取)④DOMPurify 清理富文本。
CSRF(跨站请求伪造):诱导用户在已登录状态下发送伪造请求。
防御:①CSRF Token(服务器验证随机token)②SameSite Cookie(Strict/Lax)③Referer/Origin 验证。
▌ 追问方向
→React/Vue 如何自动防御 XSS?(dangerouslySetInnerHTML 的风险)
→SameSite Cookie 的三个值有什么区别?
→JWT 存在 localStorage 和 Cookie 中各有什么安全风险?
▌ 评分参考(1-4 分)
149.1分:能说出 XSS/CSRF 概念
150.2分:能说出具体攻击过程
151.3分:能说出对应防御措施
152.4分:了解框架的自动转义,能评估 JWT 存储方案安全性
Q39HTTP 缓存机制详解:强缓存和协商缓存的字段、优先级和工作流程? [中等] #HTTP#缓存#网络
▌ 考察点
缓存机制理解,性能优化实践
▌ 参考答案
强缓存(不请求服务器):Cache-Control: max-age=N(优先级高)、Expires(绝对时间,已淘汰)。
协商缓存(请求服务器验证):Last-Modified/If-Modified-Since(精度到秒)、ETag/If-None-Match(文件哈希,精确)。
流程:先查强缓存→命中直接返回200(from cache)→未命中→发请求带条件头→服务器判断→未改变返回304→已改变返回200+新资源。
最佳实践:HTML 设置 no-cache(每次验证),JS/CSS/图片设置长缓存 + 文件名 Hash。
▌ 追问方向
→no-cache 和 no-store 有什么区别?
→为什么 HTML 文件不适合设置长期强缓存?
→Service Worker 缓存和 HTTP 缓存有什么区别?
▌ 评分参考(1-4 分)
153.1分:知道强缓存和协商缓存
154.2分:能说出相关 HTTP 字段
155.3分:能说出完整工作流程
156.4分:能设计合理的缓存策略,了解 SW 缓存
Q40WebSocket 和 HTTP 长轮询、SSE 的区别?各自适用场景? [中等] #网络#实时通信
▌ 考察点
实时通信技术选型
▌ 参考答案
HTTP 长轮询:客户端发请求,服务器 hold 住不响应,有消息再返回,客户端收到后立即再发新请求。
SSE(Server-Sent Events):HTTP 单向推送,服务器可以持续发事件,客户端 EventSource API,自动重连,仅服务器到客户端。
WebSocket:全双工,独立协议(ws://),握手后升级,适合聊天、游戏、协同编辑等高频双向通信。
选型:只需服务器推送(新闻推送、通知)→ SSE;双向实时(聊天、白板)→ WebSocket。
▌ 追问方向
→WebSocket 如何保持连接(心跳机制)?
→如何在 React 中封装一个 useWebSocket Hook?
→WebTransport 是什么?和 WebSocket 相比有什么优势?
▌ 评分参考(1-4 分)
157.1分:知道 WebSocket 是双向的
158.2分:能区分三种方案
159.3分:能给出选型建议
160.4分:了解心跳机制,有实际使用经验
🏗️八、项目与架构 |
Q41你在项目中遇到过最复杂/最难解决的技术问题是什么?是如何解决的? [中等] #项目#沟通
▌ 考察点
实际问题解决能力,沟通表达,成长意识
▌ 参考答案
(开放题,考察点):用 STAR 法则(情境-任务-行动-结果)评估:
①问题是否真实有挑战性 ②分析过程是否有条理 ③解决方案是否合理有创意
④是否有量化结果 ⑤是否有反思和总结。
好的回答会包含:技术背景→尝试过哪些方案→为什么选择这个方案→实施细节→结果数据→复盘。
▌ 追问方向
→如果重来,你会怎么做?
→这个问题让你学到了什么?
→你是如何向团队分享这个解决方案的?
▌ 评分参考(1-4 分)
161.1分:能描述一个具体问题
162.2分:有清晰的解决思路
163.3分:有量化结果和反思
164.4分:STAR 结构完整,展示成长性
Q42如何设计一个前端低代码平台?核心难点是什么? [偏难] #架构#低代码#设计
▌ 考察点
系统设计能力,架构思维
▌ 参考答案
核心模块:①组件 Schema 设计(JSON 描述组件树)②拖拽引擎(交互区域、放置区域、碰撞检测)
③属性编辑面板(动态表单渲染)④数据绑定(变量系统、表达式引擎)⑤事件系统(动作流程)⑥预览/发布。
核心难点:①Schema 设计(扩展性 vs 复杂度)②组件库隔离(沙箱)
③撤销/重做(命令模式、操作历史)④性能(大量组件渲染)⑤表达式引擎安全沙箱。
▌ 追问方向
→如何实现撤销/重做功能?(命令模式/不可变数据)
→组件物料市场如何实现按需加载?
→如何设计让业务方可以自定义扩展组件的机制?
▌ 评分参考(1-4 分)
165.1分:能说出几个核心模块
166.2分:能识别主要难点
167.3分:能展开某一个难点的技术方案
168.4分:有实际低代码项目经验,能深入讨论 Schema 设计
Q43微前端是什么?有哪些实现方案?qiankun 的沙箱机制是如何实现的? [偏难] #微前端#架构
▌ 考察点
微前端架构理解,工程架构能力
▌ 参考答案
微前端:将大型前端应用拆分为独立可部署的小应用,解决巨石应用维护难、技术栈升级难问题。
方案:①qiankun/single-spa(JS Entry,运行时集成)②iframe(最简单,隔离最强,通信难)
③Web Components(标准化,Shadow DOM 隔离)④Module Federation(Webpack5,共享模块)。
qiankun 沙箱:SnapshotSandbox(diff window 快照)、ProxySandbox(Proxy 拦截 window 读写,多实例支持),CSS 沙箱(Shadow DOM 或 scoped 选择器)。
▌ 追问方向
→微前端的主要缺点是什么?什么场景下不建议用?
→Module Federation 和 qiankun 有什么本质区别?
→如何在微前端中共享全局状态和公共依赖?
▌ 评分参考(1-4 分)
169.1分:知道微前端解决什么问题
170.2分:能列出几种方案
171.3分:能解释 qiankun 沙箱原理
172.4分:能对比方案优缺点,有实际微前端经验
Q44设计一个前端通用请求库(类似 Axios),需要支持哪些功能?如何实现拦截器? [偏难] #架构#设计#手写
▌ 考察点
工程化设计能力,拦截器模式理解
▌ 参考答案
功能:请求/响应拦截、超时控制(AbortController)、重试机制、取消请求、baseURL/默认headers、请求去重、进度监控。
拦截器实现:维护两个队列(请求拦截器和响应拦截器),用 Promise 链串联。
核心:将拦截器和请求函数组成一个执行链,请求拦截器从队尾向队头(后加先执行),响应拦截器从队头向队尾。
▌ 追问方向
→如何实现请求去重(相同请求只发一次,共享结果)?
→如何设计一个通用的错误重试机制(支持指数退避)?
→如何基于 Axios 封装一个符合业务场景的请求库?
▌ 评分参考(1-4 分)
173.1分:能列出功能点
174.2分:理解拦截器的执行顺序
175.3分:能描述 Promise 链实现
176.4分:能手写简易版,考虑到请求去重、取消等
Q45说说你对前端架构演进的理解:MVC、MVP、MVVM、Flux/Redux 各解决了什么问题? [偏难] #架构#设计模式
▌ 考察点
架构历史理解,设计模式运用
▌ 参考答案
MVC:Model-View-Controller,但前端 MVC 中 View 和 Model 往往双向依赖,复杂后难以追踪数据流。
MVP:Presenter 取代 Controller,View 完全被动(只显示数据),Presenter 处理逻辑,双向通信但通过接口解耦。
MVVM:ViewModel 通过数据绑定双向同步 View,View 的变化自动反映到 Model(Vue/Angular)。
Flux/Redux:单向数据流,Action→Reducer→Store→View,彻底解决数据流向混乱问题,但引入了更多模板代码。
▌ 追问方向
→Redux 的三大原则是什么?为什么 Reducer 必须是纯函数?
→React + Redux 的单向数据流在大规模项目中还有什么缺点?
→Signal(Solid.js/Vue3 最细粒度响应式)和 MVVM 相比有什么进化?
▌ 评分参考(1-4 分)
177.1分:知道 MVVM 是什么
178.2分:能区分各架构特点
179.3分:能说清楚 Flux 解决的核心问题
180.4分:了解现代 Signal 方向,有架构选型实践
💻九、编码与算法 |
Q46手写题:实现 Promise.all、Promise.race、Promise.allSettled [中等] #手写#Promise#异步
▌ 考察点
Promise API 理解,编码能力
▌ 参考答案
Promise.all = (promises) => new Promise((resolve, reject) => { |
constresults = []; let count = 0; |
promises.forEach((p,i) => { |
Promise.resolve(p).then(val=> { |
results[i]= val; |
if(++count === promises.length) resolve(results); |
}).catch(reject); |
}); |
if(!promises.length) resolve([]); |
}); |
Promise.allSettled = (promises) => Promise.all( |
promises.map(p=> Promise.resolve(p) |
.then(value=> ({ status: 'fulfilled', value })) |
.catch(reason=> ({ status: 'rejected', reason }))) |
); |
Promise.race = (promises) => new Promise((resolve, reject) => { |
promises.forEach(p=> Promise.resolve(p).then(resolve).catch(reject)); |
}); |
▌ 追问方向
→如何实现一个有最大并发数限制的 Promise 调度器?
→Promise.any 的语义是什么?和 race 有什么区别?
→如果 promises 数组为空,各方法的行为分别是什么?
▌ 评分参考(1-4 分)
181.1分:能写出 all 的基本逻辑
182.2分:处理了空数组边界
183.3分:三个都能正确实现
184.4分:能实现并发调度器
Q47手写题:实现 EventEmitter(发布订阅),支持 on/off/emit/once [中等] #手写#设计模式
▌ 考察点
设计模式理解,编码基础
▌ 参考答案
class EventEmitter { |
constructor(){ this._events = {}; } |
on(event,fn) { |
(this._events[event]= this._events[event] || []).push(fn); |
returnthis; |
} |
off(event,fn) { |
if(!fn) { this._events[event] = []; return this; } |
this._events[event]= (this._events[event] || []).filter(f => f !== fn && f._original !== fn); |
returnthis; |
} |
emit(event,...args) { |
(this._events[event]|| []).slice().forEach(fn => fn(...args)); |
returnthis; |
} |
once(event,fn) { |
constwrapper = (...args) => { fn(...args); this.off(event, wrapper); }; |
wrapper._original= fn; |
returnthis.on(event, wrapper); |
} |
} |
▌ 追问方向
→Node.js 的 EventEmitter 有 maxListeners 限制,为什么?如何实现?
→如何防止内存泄漏(监听器未移除)?
→发布订阅和观察者模式有什么区别?
▌ 评分参考(1-4 分)
185.1分:能实现 on/emit
186.2分:能实现 off
187.3分:once 实现正确(off 能取消 once)
188.4分:考虑了边界和内存泄漏
Q48手写题:实现 LRU Cache,要求 get 和 put 都是 O(1) [偏难] #手写#数据结构#算法
▌ 考察点
数据结构设计,算法能力
▌ 参考答案
class LRUCache { |
constructor(capacity){ |
this.capacity= capacity; |
this.map= new Map(); // 保持插入顺序 |
} |
get(key){ |
if(!this.map.has(key)) return -1; |
constval = this.map.get(key); |
this.map.delete(key); |
this.map.set(key,val); // 移到末尾(最近使用) |
returnval; |
} |
put(key,value) { |
if(this.map.has(key)) this.map.delete(key); |
elseif (this.map.size >= this.capacity) { |
this.map.delete(this.map.keys().next().value);// 删除最久未用 |
} |
this.map.set(key,value); |
} |
} |
▌ 追问方向
→JS Map 是有序的吗?为什么可以用来模拟双向链表?
→如果不用 Map,如何用双向链表 + HashMap 实现?
→LRU 在前端有哪些应用场景?(如虚拟列表缓存池)
▌ 评分参考(1-4 分)
189.1分:知道 LRU 原理
190.2分:能用 Map 实现
191.3分:get/put 都是 O(1) 且正确
192.4分:能手写链表版本,联系实际场景
Q49手写题:实现一个 compose/pipe 函数(函数组合) [中等] #手写#函数式#TS
▌ 考察点
函数式编程理解,TypeScript 高级类型
▌ 参考答案
// JS 实现 |
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x); |
const pipe= (...fns) => x => fns.reduce((v, f) => f(v), x); |
// 区别:compose 从右到左执行,pipe 从左到右执行 |
// 示例: |
const add1 = x => x + 1; |
const double = x => x * 2; |
const transform = pipe(add1, double); // 先 add1 再 double |
transform(3); // (3+1)*2 = 8 |
▌ 追问方向
→Redux 的 compose 和这个有什么区别?
→函数式编程中柯里化(curry)的作用是什么?
→Ramda 和 Lodash/fp 有什么区别?你用过吗?
▌ 评分参考(1-4 分)
193.1分:能实现 JS 版本
194.2分:能说出 compose 和 pipe 的区别
195.3分:能写出 TypeScript 版本
196.4分:理解函数式编程,能联系 Redux middleware
Q50手写题:用 requestAnimationFrame 实现一个流畅的数字滚动动画 [中等] #手写#动画#性能
▌ 考察点
动画编码能力,RAF 使用,缓动函数
▌ 参考答案
function animateCount(el, start, end, duration = 1000) { |
conststartTime = performance.now(); |
constrange = end - start; |
functioneaseOutCubic(t) { return 1 - Math.pow(1 - t, 3); } |
functionupdate(currentTime) { |
constelapsed = currentTime - startTime; |
constprogress = Math.min(elapsed / duration, 1); |
consteasedProgress = easeOutCubic(progress); |
el.textContent= Math.round(start + range * easedProgress).toLocaleString(); |
if(progress < 1) requestAnimationFrame(update); |
} |
requestAnimationFrame(update); |
} |
▌ 追问方向
→为什么用 performance.now() 而不是 Date.now()?
→如何让动画在 visibility:hidden 时暂停?(Page Visibility API)
→CSS animation 和 JS + RAF 动画如何选择?
▌ 评分参考(1-4 分)
197.1分:能用 RAF 循环更新
198.2分:用 progress 计算当前值
199.3分:加入缓动函数
200.4分:用 performance.now 计算时间,考虑了动画取消
🤖十、AI 与前沿技术 |
Q51你在项目中如何使用 AI 辅助开发?有哪些实际提效的场景? [简单] #AI#效率
▌ 考察点
对 AI 工具的实际应用,学习能力
▌ 参考答案
(考察候选人对 AI 工具的实际掌握程度和主动性)
好的回答应覆盖:代码生成(GitHub Copilot/Cursor)、代码 Review 和重构、单元测试生成、文档生成、
Bug 排查(让 AI 分析错误日志)、技术方案探讨、正则/SQL 生成。
加分项:有用 AI API 开发功能的经验、了解 prompt engineering、了解 RAG/Agent 等概念。
▌ 追问方向
→你觉得 AI 辅助编程有哪些局限性?什么场景下 AI 会产生误导?
→如果要开发一个 AI 功能(如智能搜索),你会怎么设计前端交互?
→了解 function calling/tool use 吗?前端如何与 AI 流式接口对接?
▌ 评分参考(1-4 分)
201.1分:使用过 AI 编码工具
202.2分:有具体提效场景
203.3分:了解 AI API 开发
204.4分:了解流式输出、RAG、Agent 等,有实际 AI 功能开发经验
Q52如何在前端实现 AI 对话界面?流式输出(Streaming)的实现原理是什么? [中等] #AI#流式#SSE
▌ 考察点
前沿 AI 接入能力,SSE/ReadableStream 理解
▌ 参考答案
AI 流式输出实现:服务端返回 text/event-stream(SSE)或 ReadableStream。
前端两种方式:①EventSource API(仅 GET,自动重连)②fetch + ReadableStream(更灵活,支持 POST)。
实现步骤:fetch 后获取 response.body(ReadableStream),用 getReader() 读取,TextDecoder 解码,
解析 data: 行,逐字追加到 UI。
需要处理:取消(AbortController)、错误重连、Markdown 实时渲染、代码块流式高亮。
▌ 追问方向
→如何实现流式输出时的 Markdown 渲染而不闪烁?
→用户发送新消息时如何取消当前流?
→如何处理 AI 响应中的 function calling / tool use?
▌ 评分参考(1-4 分)
205.1分:知道用 SSE 实现流式
206.2分:能用 fetch + ReadableStream 实现
207.3分:处理了取消和错误
208.4分:解决了 Markdown 流式渲染问题,有完整 AI 对话组件经验
Q53WebAssembly(WASM)是什么?前端有哪些实际应用场景? [偏难] #WASM#前沿
▌ 考察点
前沿技术了解,技术视野
▌ 参考答案
WASM 是一种低级字节码格式,可以在浏览器中以接近原生速度运行,支持 C/C++/Rust/Go 等编译到 WASM。
前端应用:①图像/视频处理(FFmpeg.wasm)②加密运算(高性能 crypto)③游戏引擎(Unity WebGL)
④代码编辑器语言服务(VSCode web 版)⑤AI 推理(TensorFlow.js WASM backend)⑥CAD/3D 应用。
限制:无直接 DOM 操作,需要通过 JS 桥接,加载体积较大,调试困难。
▌ 追问方向
→如何在 React 项目中使用 WASM 模块?
→WASM 和 asm.js 有什么关系?
→WASI 是什么?和 WASM 有什么区别?
▌ 评分参考(1-4 分)
209.1分:知道 WASM 是什么
210.2分:能举出实际应用场景
211.3分:理解 JS 桥接机制和限制
212.4分:有实际使用经验,了解 WASI 等新方向
📱十一、移动端与跨平台 |
Q54移动端 1px 问题是什么?有哪些解决方案? [中等] #移动端#CSS
▌ 考察点
移动端开发经验
▌ 参考答案
问题根源:devicePixelRatio(物理像素/CSS像素)在高清屏(retina)为 2 或 3,
导致 CSS 1px 实际显示为 2-3 物理像素,视觉上比设计稿粗。
解决方案:①伪元素 + transform: scaleY(0.5)(推荐)
②viewport meta 设置 initial-scale=0.5 + rem(影响全局)
③border-image(图片边框)④box-shadow(半像素)⑤SVG 背景。
推荐方案:伪元素 + transform,配合 device-pixel-ratio 媒体查询。
▌ 追问方向
→什么是 CSS 像素、设备像素、设备独立像素?
→如何实现移动端自适应布局?rem、vw、Flexible 方案各有什么优缺点?
→iOS Safari 的安全区域如何处理(env(safe-area-inset-*))?
▌ 评分参考(1-4 分)
213.1分:知道 1px 问题存在
214.2分:能说出原因(DPR)
215.3分:能说出伪元素方案
216.4分:了解多种方案优缺点,有实际处理经验
Q55React Native 和 Flutter 各自的渲染原理是什么?各有什么优缺点? [偏难] #跨平台#RN#Flutter
▌ 考察点
跨平台技术理解,技术选型能力
▌ 参考答案
React Native:JS Bridge(旧架构)/ JSI(新架构)与原生通信,组件映射到原生控件(View → UIView)。
优点:复用 React 生态、热更新、可调用原生。
缺点:Bridge 通信有性能损耗,JSI 改善但仍有 JS 线程瓶颈。
Flutter:自带渲染引擎(Skia/Impeller),不依赖原生控件,直接绘制 UI。
优点:性能高(60/120fps)、跨平台一致性好、没有 Bridge。
缺点:包体积大、Dart 语言、与原生交互成本高、WebView 生态弱。
▌ 追问方向
→Flutter 的 Widget、Element、RenderObject 三棵树是什么?
→React Native 的新架构(Fabric + JSI)改变了什么?
→Taro、uni-app 等多端框架是如何同时支持 H5、小程序、App 的?
▌ 评分参考(1-4 分)
217.1分:知道两者基本区别
218.2分:能说出渲染原理差异
219.3分:能比较 RN 新旧架构
220.4分:了解 Flutter 三树架构,有实际跨平台项目经验
🎯十二、综合潜力评估 |
Q56你最近在学什么新技术?为什么感兴趣?实际使用后有什么心得? [简单] #潜力#学习能力
▌ 考察点
主动学习意识,技术热情,学习方法
▌ 参考答案
(开放题)评估维度:
①是否有持续学习习惯 ②学习选题是否有前瞻性(不只是跟风)
③能否说清楚为什么感兴趣(解决了什么问题)④学习深度(不只是看了 README)
⑤是否有实践和总结。
优秀候选人会谈:对某技术的深入探索、实际项目中的应用、踩坑经验、和已有知识的横向联系。
▌ 追问方向
→你通常通过什么渠道学习新技术?(博客/源码/官方文档/视频)
→你有没有给开源项目提过 PR 或 Issue?
→如果让你给团队做一次技术分享,你会选什么主题?
▌ 评分参考(1-4 分)
221.1分:有明确的学习内容
222.2分:能说出学习动机
223.3分:有实践和心得
224.4分:展现出系统化学习能力和知识构建意识
Q57如果让你从零开始主导一个中台系统的前端架构设计,你会如何规划? [偏难] #架构#设计#潜力
▌ 考察点
架构设计能力,全局思维,技术决策能力
▌ 参考答案
规划维度:①技术选型(框架/构建工具/状态管理/UI 组件库)—结合团队情况
②目录结构(按功能还是按层次)③代码规范(ESLint/Prettier/Commitlint/Husky)
④设计系统(Design Token/组件规范)⑤公共能力沉淀(请求库/工具库/Hooks 库)
⑥权限体系(RBAC)⑦国际化 ⑧监控告警 ⑨CI/CD 流程 ⑩文档体系(Storybook/VitePress)。
强调:先了解业务场景和团队现状,不过度设计。
▌ 追问方向
→Monorepo 和多仓库的选择标准是什么?
→如何推动团队采用新的技术规范?遇到阻力怎么办?
→如何评估一个技术方案的 ROI?
▌ 评分参考(1-4 分)
225.1分:能说出几个技术点
226.2分:有系统的模块划分
227.3分:考虑了团队和业务背景
228.4分:有架构全局观,考虑了规范、质量、效率多个维度
Q58说说你对前端未来发展方向的看法?你觉得前端工程师的核心竞争力是什么? [简单] #潜力#视野
▌ 考察点
技术视野,职业规划,思考深度
▌ 参考答案
(开放题)优质视角:
①AI 赋能前端(Copilot 提效、AI 功能开发)
②全栈趋势(BFF、Edge Function、RSC)
③跨平台(小程序、桌面端、WASM)
④Web 标准演进(View Transitions、Container Query、CSS Houdini)
⑤开发者体验(DX)提升。
核心竞争力讨论点:扎实的 CS 基础、对用户体验的感知、全链路意识、持续学习能力、软技能(沟通/协作)。
▌ 追问方向
→你认为 AI 会取代前端工程师吗?
→你对自己 3 年后的职业发展有什么规划?
→你觉得好的前端代码应该是什么样的?
▌ 评分参考(1-4 分)
229.1分:有基本观点
230.2分:能谈出几个具体方向
231.3分:有独立思考,不只是重复流行观点
232.4分:展现出视野广度和职业成熟度
关注我,获取更多技术干货
面试题解析 · 项目实战 · 技术分享 · 职业成长
微信公众号 扫码关注,更新不错过 |
微信视频号 视频教程,手把手带你学 |
如果这份资料对你有帮助,欢迎转发分享给更多人
© 2026 程序员AI破局指南All Rights Reserved