前端面试文档
目录
HTML/CSS 基础
1. HTML5 新特性
问题: 请列举 HTML5 的主要新特性。
答案要点:
- 语义化标签:
header、nav、article、section、aside、footer - 多媒体支持:
audio、video、canvas - 表单增强:
date、time、email、url、number等输入类型 - 本地存储:
localStorage、sessionStorage - 离线应用:Application Cache / Service Worker
- Web Workers、WebSocket、Geolocation API
2. CSS 选择器优先级
问题: CSS 选择器的优先级是如何计算的?
答案要点: 优先级计算:内联样式 > ID 选择器 > 类/属性/伪类选择器 > 元素/伪元素选择器
具体权重值(0,0,0,0):
- 内联样式:1000
- ID 选择器:100
- 类/属性/伪类:10
- 元素/伪元素:1
!important 具有最高优先级,但不建议使用。
3. 盒模型
问题: 标准盒模型和怪异盒模型有什么区别?
答案要点:
- 标准盒模型(
box-sizing: content-box):width/height 只包含 content - 怪异盒模型(
box-sizing: border-box):width/height 包含 content + padding + border - 推荐使用
border-box,便于布局计算
4. Flexbox 布局
问题: 请解释 Flexbox 布局的主要属性。
答案要点: 容器属性:
display: flex- 开启 flex 布局flex-direction- 主轴方向(row/column)justify-content- 主轴对齐方式align-items- 交叉轴对齐方式flex-wrap- 是否换行
项目属性:
flex: 1- shorthand for flex-grow, flex-shrink, flex-basisalign-self- 单个项目的对齐方式order- 排列顺序
5. Grid 布局
问题: CSS Grid 布局相比 Flexbox 有什么优势?
答案要点:
- Grid 是二维布局系统,Flexbox 是一维布局系统
- Grid 可以同时处理行和列
- 更适合复杂的页面布局
- 支持
grid-template-areas进行可视化布局定义
6. 响应式设计
问题: 如何实现响应式网页设计?
答案要点:
- 使用 viewport meta 标签
- 媒体查询(Media Queries)
- 相对单位(rem, em, %, vw, vh)
- 弹性布局(Flexbox/Grid)
- 图片响应式:
max-width: 100% - 移动优先(Mobile First)策略
7. BFC(块级格式化上下文)
问题: 什么是 BFC?如何创建?有什么作用?
答案要点: BFC 是独立的渲染区域,内部元素布局不影响外部。
创建方式:
float不为 noneposition为 absolute 或 fixeddisplay为 inline-block、table-cell、flex、grid 等overflow不为 visible
作用:
- 清除浮动
- 防止 margin 重叠
- 阻止元素被浮动元素覆盖
JavaScript 核心
1. 数据类型
问题: JavaScript 有哪些数据类型?
答案要点: 基本类型(7种):
string、number、boolean、null、undefined、symbol、bigint
引用类型:
Object(包括 Array、Function、Date、RegExp 等)
判断方法:
typeof:判断基本类型(null 返回 object)instanceof:判断原型链Object.prototype.toString.call():最准确的方法
2. 原型与原型链
问题: 请解释 JavaScript 的原型与原型链。
答案要点:
- 每个对象都有
__proto__属性,指向其构造函数的原型对象 - 每个函数都有
prototype属性,指向原型对象 - 原型链:对象查找属性时,沿着
__proto__向上查找,直到 null constructor指向构造函数
// 示例
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, ' + this.name);
};
const person = new Person('Tom');
person.__proto__ === Person.prototype; // true
Person.prototype.constructor === Person; // true
3. 闭包
问题: 什么是闭包?有什么应用场景?
答案要点: 闭包:函数能够记住并访问其词法作用域,即使函数在当前作用域外执行。
应用场景:
- 数据私有化(模块化)
- 函数柯里化
- 防抖节流
- 循环中的异步操作
// 闭包示例 - 计数器
function createCounter() {
let count = 0;
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
4. this 指向
问题: JavaScript 中 this 的指向规则是什么?
答案要点:
- 默认绑定:全局环境指向 window(严格模式 undefined)
- 隐式绑定:方法调用时指向调用对象
obj.method() - 显式绑定:call/apply/bind 指定 this
- new 绑定:指向新创建的实例对象
- 箭头函数:继承外层作用域的 this,不可改变
const obj = {
name: 'Tom',
sayHi: function() {
console.log(this.name);
},
sayHiArrow: () => {
console.log(this.name); // undefined,指向外层 this
}
};
5. 事件循环
问题: 请解释 JavaScript 的事件循环机制。
答案要点:
- JavaScript 是单线程语言,使用事件循环处理异步操作
- 调用栈(Call Stack):同步代码执行
- 任务队列(Task Queue):
- 宏任务(MacroTask):setTimeout、setInterval、I/O、UI rendering
- 微任务(MicroTask):Promise.then、MutationObserver、queueMicrotask
- 执行顺序:同步代码 → 微任务 → 宏任务
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 输出:1 4 3 2
6. Promise
问题: Promise 是什么?如何处理多个 Promise?
答案要点: Promise 是异步编程的解决方案,代表一个尚未完成但预期将来会完成的操作。
状态:pending → fulfilled/rejected
方法:
Promise.all():所有成功才成功,一个失败就失败Promise.race():返回最快完成的Promise.allSettled():等待所有完成,无论成功失败Promise.any():返回第一个成功的
// async/await 语法糖
async function fetchData() {
try {
const result = await Promise.all([
fetch('/api/user'),
fetch('/api/posts')
]);
return result;
} catch (error) {
console.error(error);
}
}
7. 深浅拷贝
问题: 如何实现对象的深拷贝?
答案要点: 浅拷贝:只复制一层,引用类型共享内存
Object.assign()、{...obj}、Array.prototype.slice()
深拷贝:完全独立的新对象
JSON.parse(JSON.stringify(obj))- 有局限性(函数、undefined、循环引用)- 递归实现
structuredClone()- 现代浏览器支持- Lodash 的
cloneDeep
// 简单深拷贝实现
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);
const clone = Array.isArray(obj) ? [] : {};
map.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], map);
}
}
return clone;
}
8. 防抖与节流
问题: 防抖和节流有什么区别?如何实现?
答案要点:
- 防抖(Debounce):事件停止触发后延迟执行,期间再次触发重新计时
- 节流(Throttle):固定时间间隔执行,期间多次触发只执行一次
// 防抖
function debounce(fn, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流
function throttle(fn, limit) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
9. ES6+ 新特性
问题: 请列举 ES6 及之后版本的重要新特性。
答案要点: ES6 (2015):
let、const、块级作用域- 箭头函数
- 模板字符串
- 解构赋值
- 扩展运算符
... - 类(Class)
- 模块化(import/export)
- Promise
- Map、Set
ES7+:
async/await(ES2017)- 可选链
?.(ES2020) - 空值合并
??(ES2020) - 私有字段
#(ES2022)
框架与库
1. Vue 3
问题: Vue 3 相比 Vue 2 有哪些重大变化?
答案要点:
- Composition API:更灵活的代码组织方式
- 性能提升:Proxy 替代 Object.defineProperty,更快更小
- TypeScript 支持:更好的 TS 集成
- Teleport:组件渲染到 DOM 其他位置
- Fragments:支持多根节点组件
- Suspense:异步组件加载状态管理
- Tree-shaking:更好的打包优化
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
</script>
2. React
问题: React 的虚拟 DOM 工作原理是什么?
答案要点:
- 虚拟 DOM 是真实 DOM 的 JavaScript 对象表示
- 数据变化时生成新的虚拟 DOM
- Diff 算法比较新旧虚拟 DOM,找出最小变更
- 批量更新真实 DOM
React Hooks 常用:
useState:状态管理useEffect:副作用处理useContext:上下文useCallback/useMemo:性能优化useRef:引用 DOM 或持久化数据
3. 状态管理
问题: 如何选择状态管理方案?
答案要点:
- 小型应用:组件内部状态(useState/ref)
- 中型应用:Context API / Provide/Inject
- 大型应用:Pinia / Vuex / Redux / Zustand
Pinia 优势:
- 完整的 TypeScript 支持
- 更简洁的 API
- 支持组合式 API
- 更好的开发体验(Devtools)
4. 组件通信
问题: Vue/React 中有哪些组件通信方式?
Vue 通信方式:
- Props / $emit(父子)
- children / $refs(直接访问)
- Provide / Inject(跨层级)
- EventBus / Mitt(全局事件)
- Pinia / Vuex(全局状态)
- listeners(属性透传)
React 通信方式:
- Props / Callback(父子)
- Context(跨层级)
- Redux / Zustand(全局状态)
- 自定义事件(EventEmitter)
工程化与工具
1. 构建工具
问题: Webpack、Vite、Rollup 有什么区别?
答案要点:
| 特性 | Webpack | Vite | Rollup |
|---|---|---|---|
| 开发启动 | 慢(需打包) | 快(原生 ESM) | - |
| 生产构建 | 成熟优化 | 使用 Rollup | 优秀的 Tree-shaking |
| 配置复杂度 | 高 | 低 | 中 |
| 适用场景 | 大型应用 | 现代前端开发 | 库开发 |
| HMR | 支持 | 极快 | - |
2. 包管理器
问题: npm、yarn、pnpm 有什么区别?
答案要点:
- npm:Node.js 自带,v5+ 有 lock 文件
- yarn:并行安装,确定性安装,workspace 支持
- pnpm:硬链接节省磁盘空间,严格的依赖管理,更快的安装速度
3. Git 工作流
问题: 常用的 Git 工作流有哪些?
答案要点:
- Git Flow:feature → develop → release → master
- GitHub Flow:简单,master + feature branch
- GitLab Flow:结合 issue 和 PR
- Trunk-based:主干开发,频繁集成
常用命令:
git checkout -b feature/new-feature
git add .
git commit -m "feat: add new feature"
git push origin feature/new-feature
# 创建 PR/MR 进行代码审查
git checkout main
git pull origin main
4. 代码规范
问题: 如何统一团队代码风格?
答案要点:
- ESLint:JavaScript/TypeScript 代码检查
- Prettier:代码格式化
- Stylelint:CSS/SCSS 代码检查
- Husky:Git hooks,提交前检查
- lint-staged:只检查暂存区文件
- Commitlint:提交信息规范(Conventional Commits)
性能优化
1. 加载优化
问题: 如何优化网页加载速度?
答案要点:
- 代码分割:路由懒加载、动态 import
- 资源压缩:Gzip/Brotli、代码压缩、图片压缩
- 缓存策略:强缓存、协商缓存、Service Worker
- CDN:静态资源分发
- 预加载:
<link rel="preload/prefetch"> - 骨架屏:提升感知性能
2. 渲染优化
问题: 如何优化页面渲染性能?
答案要点:
- 减少重排重绘:批量修改样式、使用 transform/opacity
- 虚拟列表:长列表优化(react-window、vue-virtual-scroller)
- 节流防抖:高频事件优化
- Web Worker:耗时操作移出主线程
- requestAnimationFrame:动画优化
- will-change:提示浏览器优化
3. 内存优化
问题: 如何避免内存泄漏?
答案要点:
- 及时清理事件监听器
- 避免循环引用
- 清理定时器
- 组件销毁时清理订阅
- 避免全局变量
- 使用 Chrome DevTools Memory 面板分析
4. Core Web Vitals
问题: 什么是 Core Web Vitals?
答案要点: Google 提出的三个核心指标:
- LCP(Largest Contentful Paint):最大内容绘制,< 2.5s
- FID(First Input Delay):首次输入延迟,< 100ms
- CLS(Cumulative Layout Shift):累积布局偏移,< 0.1
浏览器原理
1. 渲染过程
问题: 浏览器如何渲染页面?
答案要点:
- 解析 HTML → DOM 树
- 解析 CSS → CSSOM 树
- 合并 → Render Tree(渲染树)
- 布局(Layout) → 计算几何信息
- 绘制(Paint) → 绘制像素
- 合成(Composite) → 图层合并显示
2. 重排与重绘
问题: 重排(Reflow)和重绘(Repaint)有什么区别?
答案要点:
- 重排:几何属性变化,重新计算布局(width、height、position)
- 重绘:外观变化,不影响布局(color、background-color)
- 重排必定引起重绘,重绘不一定会引起重排
- 优化:使用 CSS 动画、transform、opacity
3. 事件机制
问题: 事件冒泡和事件捕获是什么?
答案要点:
- 事件捕获:从 window 向下到目标元素(capture 阶段)
- 事件目标:到达目标元素(target 阶段)
- 事件冒泡:从目标元素向上到 window(bubble 阶段)
addEventListener第三个参数:true捕获,false冒泡(默认)event.stopPropagation()阻止传播event.preventDefault()阻止默认行为
4. 存储方案
问题: 浏览器有哪些存储方案?
答案要点:
| 特性 | Cookie | localStorage | sessionStorage | IndexedDB |
|---|---|---|---|---|
| 容量 | 4KB | 5-10MB | 5-10MB | 较大 |
| 生命周期 | 可设置 | 永久 | 会话级 | 永久 |
| 服务端读取 | 是 | 否 | 否 | 否 |
| 适用场景 | 身份认证 | 持久化数据 | 临时数据 | 大量结构化数据 |
网络与安全
1. HTTP 协议
问题: HTTP/1.1、HTTP/2、HTTP/3 有什么区别?
答案要点: HTTP/1.1:
- 持久连接(Keep-Alive)
- 管道化(Pipelining)
- 队头阻塞问题
HTTP/2:
- 二进制分帧
- 多路复用(解决队头阻塞)
- 头部压缩(HPACK)
- 服务器推送
HTTP/3:
- 基于 QUIC(UDP)
- 更快的连接建立
- 更好的移动网络支持
2. HTTPS
问题: HTTPS 是如何保证安全的?
答案要点:
- 对称加密:传输数据加密
- 非对称加密:交换对称密钥
- 数字证书:验证服务器身份(CA 机构签发)
- TLS/SSL 握手:建立安全连接
握手过程:
- Client Hello(支持的加密算法)
- Server Hello(选择的算法 + 证书)
- 客户端验证证书
- 密钥交换
- 加密通信
3. 跨域
问题: 如何解决跨域问题?
答案要点:
- CORS(跨域资源共享):服务器设置响应头
Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers
- JSONP:利用
<script>标签(仅 GET) - 代理服务器:开发环境使用 devServer.proxy
- Nginx 反向代理:生产环境
- postMessage:窗口间通信
4. Web 安全
问题: 常见的 Web 安全威胁有哪些?如何防范?
答案要点:
| 威胁 | 说明 | 防范措施 |
|---|---|---|
| XSS | 跨站脚本攻击 | 转义输入、CSP、HttpOnly Cookie |
| CSRF | 跨站请求伪造 | Token 验证、SameSite Cookie、Referer 检查 |
| SQL 注入 | 恶意 SQL 语句 | 参数化查询、ORM |
| 点击劫持 | 透明 iframe 覆盖 | X-Frame-Options、CSP |
| MITM | 中间人攻击 | HTTPS、HSTS |
算法与数据结构
1. 常用数据结构
问题: 前端常用的数据结构有哪些?
答案要点:
- 数组/链表:基础线性结构
- 栈/队列:LIFO/FIFO
- 哈希表:快速查找(Map/Set)
- 树:DOM 树、二叉搜索树
- 图:复杂关系(邻接表/矩阵)
- 堆:优先队列
2. 常用算法
问题: 前端面试常考的算法有哪些?
答案要点:
- 排序:快排、归并、冒泡
- 查找:二分查找、深度/广度优先搜索
- 双指针:数组去重、滑动窗口
- 动态规划:最长子序列、背包问题
- 递归/回溯:全排列、组合
- 贪心算法:区间调度
// 快排示例
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
const left = arr.filter(x => x < pivot);
const middle = arr.filter(x => x === pivot);
const right = arr.filter(x => x > pivot);
return [...quickSort(left), ...middle, ...quickSort(right)];
}
3. 时间复杂度
问题: 常见操作的时间复杂度是多少?
答案要点:
| 操作 | 数组 | 链表 | 哈希表 | 二叉搜索树 |
|---|---|---|---|---|
| 访问 | O(1) | O(n) | - | O(log n) |
| 查找 | O(n) | O(n) | O(1) | O(log n) |
| 插入 | O(n) | O(1) | O(1) | O(log n) |
| 删除 | O(n) | O(1) | O(1) | O(log n) |
项目经验
1. 项目介绍
问题: 请介绍你最满意的一个项目。
回答框架:
- 项目背景:业务场景、目标用户
- 技术栈:前端框架、状态管理、构建工具
- 个人职责:负责模块、团队协作
- 技术难点:遇到的问题和解决方案
- 项目成果:性能提升、用户增长等数据
2. 技术难点
问题: 项目中遇到过什么技术难点?如何解决的?
常见场景:
- 性能优化(首屏加载、大数据量渲染)
- 复杂状态管理
- 跨端适配(PC/移动端/小程序)
- 第三方库集成问题
- 浏览器兼容性问题
回答结构:
- 问题描述
- 原因分析
- 解决方案
- 最终效果
3. 团队协作
问题: 如何与后端、产品、设计协作?
答案要点:
- 与后端:接口文档(Swagger/YApi)、Mock 数据、联调流程
- 与产品:需求评审、功能优先级、技术可行性评估
- 与设计:设计稿标注、组件化思维、设计系统
- 代码协作:Code Review、Git Flow、文档沉淀
软技能
1. 自我介绍
建议结构(1-2分钟):
- 基本信息(姓名、工作年限)
- 技术栈(主技术栈 + 熟悉程度)
- 项目经验(最有价值的 1-2 个项目)
- 个人优势(技术深度、业务理解、团队协作)
- 求职意向
2. 职业规划
问题: 你的职业规划是什么?
答案要点:
- 短期(1-2年):技术深耕,成为领域专家
- 中期(3-5年):技术广度,架构设计能力
- 长期(5年+):技术管理或技术专家路线
3. 常见问题
问题: 你最大的缺点是什么?
建议回答:
- 选择一个真实的但不致命的缺点
- 说明正在如何改进
- 避免说"完美主义"等套话
示例:
"我有时候会过于关注技术细节,导致对项目整体进度把控不够。现在我会在开发前先做技术方案评估,设定里程碑,定期同步进度。"
问题: 为什么离开上一家公司?
建议回答:
- 避免抱怨前公司
- 聚焦职业发展
- 表达对新机会的期待
示例:
"我在上一家公司学到了很多,但现在希望能在更大的平台接触更复杂的业务场景,提升架构设计能力。"
面试准备清单
技术准备
- 复习 JavaScript 核心概念(闭包、原型、this、事件循环)
- 熟悉框架原理(Vue/React 响应式、虚拟 DOM、Diff 算法)
- 准备 2-3 个项目的详细介绍
- 刷算法题(LeetCode 简单/中等)
- 了解目标公司的技术栈和业务
材料准备
- 简历(PDF 格式,1-2 页)
- 作品集/项目链接
- GitHub 主页(保持活跃)
- 技术博客(加分项)
面试技巧
- 提前了解公司产品和业务
- 准备 3-5 个反问问题
- 保持自信和真诚
- 不懂的问题诚实回答,不要编造
- 注意沟通表达,技术点讲清楚原理
附录:常用资源
学习资源
算法练习
面试经验
祝你面试顺利!