字节前端高频面试题试析
@jarringslee
文章目录
- 字节前端高频面试题试析
-
- 部分一面题目试析
-
- 八股部分(基础概念题)
-
- [**1. JS 中有哪几种数据类型?**](#1. JS 中有哪几种数据类型?)
- [**2. 数组的方法有哪些?**](#2. 数组的方法有哪些?)
- [**3. slice 和 splice 的区别**](#3. slice 和 splice 的区别)
- [**4. 讲一讲事件循环(Event Loop)**](#4. 讲一讲事件循环(Event Loop))
- [**5. React 有哪几种钩子?**](#5. React 有哪几种钩子?)
- [**6. 自定义 Hook 是什么?**](#6. 自定义 Hook 是什么?)
- [**7. React 中如何进行组件通信?**](#7. React 中如何进行组件通信?)
- [**8. useContext 会出现什么问题?**](#8. useContext 会出现什么问题?)
- [**9. React 中如何进行性能优化?**](#9. React 中如何进行性能优化?)
- [**10. 讲一讲图片懒加载,怎么实现?**](#10. 讲一讲图片懒加载,怎么实现?)
- 代码题
-
- [**1. React 闭包陷阱**](#1. React 闭包陷阱)
- [**2. URL 解析 ? 后的内容**](#2. URL 解析 ? 后的内容)
- 部分二面题题目试析
-
-
- [1 Vue2 vs Vue3 核心差异](#1 Vue2 vs Vue3 核心差异)
- [2 Vue 生命周期(含父子组件调用顺序 & 常见实践)](#2 Vue 生命周期(含父子组件调用顺序 & 常见实践))
- [3 Vue3 为什么改用 Proxy?Vue2 defineProperty 局限](#3 Vue3 为什么改用 Proxy?Vue2 defineProperty 局限)
- [4 Vue Router 的两种模式(hash / history)实现原理与优缺点](#4 Vue Router 的两种模式(hash / history)实现原理与优缺点)
- [5 从输入 URL 到页面渲染完整链路(分阶段与可观测点)](#5 从输入 URL 到页面渲染完整链路(分阶段与可观测点))
- [6 浏览器渲染流水线:DOM/CSSOM、回流与重绘触发与优化](#6 浏览器渲染流水线:DOM/CSSOM、回流与重绘触发与优化)
- [7 构建工具对比与选型:Vite / Webpack / Rollup](#7 构建工具对比与选型:Vite / Webpack / Rollup)
-
- 前端一二面总体策略
-
- [1. 如果无法答满,就把重点放在条理上](#1. 如果无法答满,就把重点放在条理上)
- [**2. 面试过程中的通用表达框架**](#2. 面试过程中的通用表达框架)
-
- **如何应对基础八股(JS、浏览器、性能)**
- [**浏览器机制(Event Loop、渲染流水线)**](#浏览器机制(Event Loop、渲染流水线))
- [**4. 框架类问题(Vue、React)回答技巧**](#4. 框架类问题(Vue、React)回答技巧)
- [**7. 如何主动拿分(提出场景 + 实战经验)**](#7. 如何主动拿分(提出场景 + 实战经验))
- [**8. 如何面对项目拷打环节**](#8. 如何面对项目拷打环节)
- [**9. 遇到复杂八股问题(如 HTTP/SSL/TCP)怎么稳住?**](#9. 遇到复杂八股问题(如 HTTP/SSL/TCP)怎么稳住?)
经过一段时间的积累,我们已经具备了构建一个基础 Web 项目的能力:能够使用 HTML / CSS 完成页面结构与样式,通过 JavaScript 与 TypeScript 处理前端逻辑,掌握基于 AJAX 与 Node.js 的异步通信与后端交互,并能够借助 Vue 框架 构建更复杂的前端应用。
这里,我初步整理了字节跳动前端招聘的一些高频试题(基本为考察学过的知识的题目),并就我目前所学进行解答。
部分一面题目试析
一面题的题目较为简短,基本都是考察基础知识储备。
八股部分(基础概念题)
1. JS 中有哪几种数据类型?
-
string
-
number
-
boolean
-
null
-
undefined
-
symbol
-
bigint
还有一种引用类型object(含 array、function、Date、RegExp...)
补充
typeof null === "object"是历史遗留 bug- 判断数组:Array.isArray()
2. 数组的方法有哪些?
- 可变/不可变方法,遍历方法,查找方法
- 熟悉 ES6+
可以按功能分类回答(最优答案结构)。
增删改(会修改原数组)
- push / pop
- shift / unshift
- splice
- sort(注意不稳定)
- reverse
返回新数组(不修改原数组)
- slice
- concat
- map
- filter
- flat / flatMap
- toSorted / toReversed(ES2023,不改变原数组)
查找
- indexOf / lastIndexOf
- find / findIndex / findLast
- includes
判断
- Array.isArray()
遍历
- forEach
- some / every
- reduce
| 操作 | 方法 | 是否改变原数组 | 备注 |
|---|---|---|---|
| 增 | push(...items) |
✅ | 末尾追加,返回新长度 |
unshift(...items) |
✅ | 头部追加 | |
splice(index,0,...items) |
✅ | 任意位置插入 | |
| 删 | pop() |
✅ | 删末尾,返回被删元素 |
shift() |
✅ | 删头部 | |
splice(index,n) |
✅ | 删任意连续 n 个 | |
slice(start,end) |
❌ | 返回切片,左闭右开 | |
| 改 | fill(value,start,end) |
✅ | 批量改值 |
| 查 | indexOf/lastIndexOf |
❌ | 找不到返回 -1 |
includes(value) |
❌ | 布尔版查找 | |
| 排序 | sort((a,b)=>a-b) |
✅ | 默认字典序,需传比较器 |
| 反转 | reverse() |
✅ | 直接倒序 |
| 最值 | Math.max(...arr) / Math.min(...arr) |
❌ | 需配合展开运算符 |
3. slice 和 splice 的区别
考点:是否改变原数组 + 用途区别
| 方法 | 是否修改原数组 | 返回什么 | 常用场景 |
|---|---|---|---|
| slice(start, end) | 不修改 | 新数组 | 复制、截取 |
| splice(start, deleteCount, ...items) | 修改 | 被删除的项 | 删除/插入/替换 |
slice 用于"复制",splice 用于"增删改"。
4. 讲一讲事件循环(Event Loop)
- 宏任务 / 微任务
- 执行顺序
- 浏览器 vs Node 差异(一般一面不深问)
最优结构:JS 是单线程,通过事件循环(Event Loop)调度任务:
任务队列类型:
- 同步任务 ------ 主线程执行
- 微任务(microtask)
- Promise.then
- queueMicrotask
- MutationObserver
- 宏任务(macrotask)
- setTimeout
- setInterval
- DOM 事件
- Ajax 回调
执行顺序规则:
- 执行同步代码
- 清空所有微任务
- 执行一个宏任务
- 再清空所有微任务
- 继续下一轮宏任务...
5. React 有哪几种钩子?
后面学到react的时候可以细看。
常用 Hooks
- useState:状态
- useEffect:副作用
- useMemo:缓存计算
- useCallback:缓存函数
- useRef:存值 / DOM 引用
- useContext:全局共享数据
- useReducer:复杂状态逻辑
- useLayoutEffect:同步执行副作用
6. 自定义 Hook 是什么?
考点
- 本质:复用逻辑
- 自定义 Hook 必须以 use 开头
答案:
自定义 Hook 是将"可复用的状态逻辑"抽取出来的函数,例如封装:
- 请求数据 useRequest
- 防抖 useDebounce
- 监听窗口大小 useWindowSize
本质:把多个 hooks 串起来→形成一个高阶逻辑。
7. React 中如何进行组件通信?
常见方式:
- 父 → 子:props
- 子 → 父:回调函数 props
- 跨层级:Context
- 非父子:Redux / Zustand / Jotai / 全局事件
- URL 参数、localStorage 也算间接通信方式
8. useContext 会出现什么问题?
核心考点:Context 引发"广播式刷新"
- 只要 context value 变化 → 所有使用 useContext 的组件都重新渲染
- 无法局部更新
- 性能差
- 很容易造成"不可控刷新"
解决:使用 useMemo、拆分 context、用 Zustand 等状态库。
9. React 中如何进行性能优化?
从渲染、计算、资源三方面:
渲染优化
- React.memo(组件缓存)
- useMemo、useCallback(缓存计算和函数)
- 列表 key
- 避免无用 re-render(拆组件)
虚拟列表(长列表优化)
- react-window
- react-virtualized
资源加载优化
- 懒加载 React.lazy
- 按需组件拆分
10. 讲一讲图片懒加载,怎么实现?
两种常见实现方式:
方式 1:原生 IntersectionObserver(推荐)
js
const io = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src;
io.unobserve(entry.target);
}
});
});
方式 2:scroll + getBoundingClientRect
- 计算图片位置是否进入 viewport
代码题
1. React 闭包陷阱
常见题:
ts
function App() {
const [count, setCount] = useState(0);
function log() {
console.log(count); // 闭包陷阱:永远是旧值
}
useEffect(() => {
setInterval(log, 1000);
}, []);
return <button onClick={() => setCount(count + 1)}>+</button>;
}
解决方案:
- 用 useRef 保存最新值
- 或将 log 写在 useEffect 内部
2. URL 解析 ? 后的内容
关键点:要考虑多值、decode
手写:
js
function parseQuery(url) {
const query = url.split('?')[1];
if (!query) return {};
const obj = {};
query.split('&').forEach(pair => {
const [key, val] = pair.split('=');
obj[decodeURIComponent(key)] = decodeURIComponent(val);
});
return obj;
}
部分二面题题目试析
二面题考察点多为高级语言框架、操作系统和更复杂的逻辑操作和问题处理,考察点也更加综合。
1 Vue2 vs Vue3 核心差异
考点:响应式实现、API 设计演化(Options → Composition)、性能优化与编译器改进、打包/Tree-shaking 能力与生态迁移成本。面试官想看你对原理的理解、优缺点比较与工程化取舍。
结论要点(面试回答):
- 响应式 :Vue2 用
Object.defineProperty给每个属性劫持 getter/setter;Vue3 用Proxy,能监听对对象本身的增删、对数组索引的变化、支持深度拦截且无需递归替换。 - API 设计 :Vue2 主打 Options API(data/methods/computed/watch),组织大型组件时状态/逻辑难以复用;Vue3 推 Composition API(
setup、ref、reactive、computed等),逻辑更易组合和复用。 - 性能与编译器:Vue3 的编译器做了更多编译时优化(静态节点提升、VNode 静态标记、优化 patch 算法),运行时更轻量;Tree-shaking 更友好(模块化重写),Bundle 一般更小,初始化性能和更新性能都有提升。
- 其它:更好的 TypeScript 支持(从设计层面),更细粒度的源码模块化。
展开细节(面试喜欢追问的点)
- Proxy 相比 defineProperty 的优势 :
- 可以监听属性的 新增/删除 (
set/deleteProperty),而 defineProperty 无法拦截obj.newProp = x这种操作。 - 无需对每个嵌套对象递归
defineProperty(在 Vue2 中要递归遍历对象并对每一个属性做劫持,增加初始化成本且对深度变化处理复杂);Proxy 在访问时拦截(惰性代理/按需代理)更灵活。 - 支持对数组索引操作的精确拦截(push/pop/直接设置索引)。
- 缺点:Proxy 在老旧环境(IE11)不支持,需要 polyfill(但 polyfill 不能完全模拟 Proxy),且 Proxy 的某些调试堆栈会不同。
- 可以监听属性的 新增/删除 (
- Composition API 的优势 :
- 把相关逻辑放在一起(而不是散落在
data/methods/computed不同选项),便于复用(可抽成useXxx)。 - TypeScript 支持更自然(类型向导、infer)。
- 也要能说到缺点:对初学者学习曲线稍陡、可能使组件内部过度抽象(需要良好约定)。
- 把相关逻辑放在一起(而不是散落在
- 编译器优化举例 :
- 静态节点提升(把不变的 DOM 提到渲染函数之外,避免每次 patch),减少运行时 vnode 创建。
- Patch 时更少的内存分配、更多的静态分析(比如
v-once、v-if优化)。
- 面试可能问的延伸:如何从 Vue2 迁移到 Vue3(逐步迁移策略、Vue 兼容构建)、Composition API 实际使用场景举例(表单逻辑复用、图表事件复用等)。
2 Vue 生命周期(含父子组件调用顺序 & 常见实践)
考点:生命周期钩子顺序、绑定事件/发请求/DOM 操作/销毁清理各放在哪个钩子、父子先后顺序(面试会让你列出顺序并说明为什么在某钩子放哪类代码)。
关键钩子(Vue2 / Vue3 对应)
beforeCreate:实例刚创建,响应式/事件尚未初始化 ------ 不要访问this的数据。created:数据已观测(reactive 已设置),但 DOM 未生成 ------ 适合做数据初始化、非 DOM 的逻辑、注册全局事件,不适合 DOM 操作。beforeMount:渲染函数首次执行前(还没挂载到真实 DOM)。mounted:组件 DOM 已插入页面 ------ 适合 DOM 操作(measure、第三方库 init)、发起首屏请求(也可在 created)。beforeUpdate:数据更新导致重新渲染前(可读旧 DOM 状态)。updated:更新后 DOM 已重新渲染 ------ 适合依赖最新 DOM 的操作(注意避免在此再改数据导致无限循环)。activated/deactivated(keep-alive):组件被激活/停用时的钩子。beforeDestroy/beforeUnmount:销毁前清理(取消订阅/定时器/移除事件监听)。destroyed/unmounted:销毁完成,实例解绑。
父子组件生命周期顺序(重点)
假设父组件 A 包含子组件 B,创建挂载阶段顺序:
- A.beforeCreate
- A.created
- A.beforeMount
- B.beforeCreate
- B.created
- B.beforeMount
- B.mounted
- A.mounted
也就是说:父组件进入挂载流程后,子组件会被创建并完成 mounted,然后父组件才完成自己的 mounted。(销毁时顺序反过来:子先 destroyed,再父 destroyed。)
常见实践放在哪些钩子:
- 注册订阅(EventBus/全局事件) :
created/mounted(若需要 DOM 相关就mounted)。 - 发请求 :
created(可更早发请求)或mounted(如果依赖 DOM 或 SSR 有其他考量);要能说明选择理由(SSR 情况下 server-side render 只能在created/server code 中处理)。 - 第三方 UI/图表初始化 :
mounted(DOM 必须存在)。 - 测量尺寸(offsetWidth/高度) :
mounted或updated(在数据变化后需要重新测量)。 - 清理(定时器/订阅) :
beforeDestroy/unmounted。 - 性能面试追问:如果大量组件发请求如何优化(去重/请求合并、父级集中请求、缓存/pagination、useSuspense/async setup 等)。
3 Vue3 为什么改用 Proxy?Vue2 defineProperty 局限
(前面已有部分覆盖,这里集中列举局限性与 Proxy 优势,便于面试回答)
defineProperty 的局限(Vue2):
- 不能监听对对象新增或删除属性(需用
Vue.set(obj, key, val)作为补救)。 - 必须递归地对每个可枚举属性做劫持(初始化成本高、对深层对象处理复杂)。
- 无法直接拦截数组的索引赋值或
length变化(对数组需特殊处理,重写数组原型方法)。 - 无法拦截对对象本身(如
Object.setPrototypeOf/delete)的操作。 - 较难与 Proxy 一些高级行为(如
ownKeys、has拦截)对应。
Proxy 带来的好处(Vue3):
- 能拦截
get、set、deleteProperty、has、ownKeys等操作,功能更全。 - 不需要在初始化时递归代理全部属性(可以做懒代理策略),且代码更简洁。
- 更自然地支持集合类型(Map/Set)和数组操作。
- 更友好地与现代 JS 特性(Reflect、Proxy trap)配合实现高级特性。
4 Vue Router 的两种模式(hash / history)实现原理与优缺点
面试官可能会让说明两种的实现(浏览器特性)、SEO/兼容性、服务器配置等。
hash 模式(#)
- 实现原理 :URL 中
#后面的部分(hash)不会被浏览器发送到服务器,变化不会触发页面重载;通过监听window.onhashchange或读取location.hash来决定路由。 - 优点:兼容性好(包括老浏览器)、服务端无需额外配置(所有请求都可返回同一 HTML),实现简单。
- 缺点 :URL 不够"干净"(有
#),不利于 SEO(搜索引擎对 JS 渲染有差异),且某些场景下对历史记录控制有限。
history 模式(HTML5 History API)
- 实现原理 :使用
history.pushState/history.replaceState改变地址栏、监听popstate事件来响应路由变化。URL 看起来是正常路径(无#)。 - 优点:URL 干净、SEO 更友好(需要配合服务端渲染或预渲染),用户和后端更容易协同。
- 缺点:需要服务端做路由回退(所有前端路由对应的路径都需要返回同一 index.html,否则直接刷新会 404),实现稍复杂,老浏览器需做 fallback。
面试常见追问
- "刷新时 history 模式为什么会 404?" → 服务器看到完整路径如果没有对应资源就会 404;解决:所有未匹配的路径都返回前端入口(或做 301/重写)。
- "哪种适合移动端 App 的 H5 页面?" → 通常 hash 更方便,但若追求 SEO 或更友好的后端协同,选择 history 并做好服务器配置。
5 从输入 URL 到页面渲染完整链路(分阶段与可观测点)
考点:面试官想看你能把浏览器端整个请求/渲染流程拆解到可观测点,并提出定位手段(DevTools、network、performance、RUM、后端日志等)。
分阶段(高层)
- 地址解析与 DNS 解析 (域名 → IP)
- 可观测点:浏览器 Network 面板中的 DNS 时间;后端/客户端 DNS logs;
dig/nslookup。 - 优化:DNS 预解析(
<link rel="dns-prefetch">)、使用可靠 DNS 服务、CDN 的地理就近解析。
- 可观测点:浏览器 Network 面板中的 DNS 时间;后端/客户端 DNS logs;
- 建立 TCP 连接 / TLS 握手 (TCP 三次握手 + TLS)
- 可观测点:Network timing(Stalled/Connect/SSL)。
- 优化:启用 keep-alive、使用 TLS 加速(session resumption)、使用 HTTP/2 或 HTTP/3 减少延迟。
- 发送 HTTP 请求并等待响应(TTFB)
- 可观测点:TTFB(Time to First Byte)指标、后端日志分析、APM。
- 优化:后端性能、缓存策略(CDN/边缘缓存)、减少阻塞中间件。
- 接收 HTML 并解析(构建 DOM)
- 可观测点:Chrome 的
DOMContentLoaded时间、解析时间片段、Lighthouse 报告。 - 优化:服务器端渲染(SSR)、减小首屏 HTML、大文件分块传输。
- 可观测点:Chrome 的
- 资源加载(CSS/JS/图片/字体)并构建 CSSOM / 执行 JS
- 可观测点:Network 面板、waterfall、资源优先级(preload/prefetch)、Lighthouse。
- 优化:资源合并/分割、HTTP/2 多路复用、preload critical assets、异步加载非关键 JS (
defer/async)。
- 构建 render tree、布局(reflow)、绘制(paint)、合成(composite)
- 可观测点:Performance 面板(帧时间、Long Tasks、渲染统计)、FPS、Paint events。
- 优化:减少复杂布局、避免同步布局读取(避免强制回流)、把动画移动到合成层(transform/opacity)。
- 交互就绪(First Input Delay / INP / TTI)
- 可观测点:Core Web Vitals:FCP、LCP、FID/INP、CLS。
- 优化:减少主线程任务、拆分长任务(web worker)、代码拆分、按需加载。
面试常会追问的监控/定位方法
- 如何定位慢首屏?(查看 waterfall、Lighthouse、RUM 对比网络/地域)
- 如果 LCP 很差,可能在网络层(图片太大/未使用 CDN)或渲染层(大量阻塞脚本/未 preconnect)?要给出定位步骤。
6 浏览器渲染流水线:DOM/CSSOM、回流与重绘触发与优化
考点:能区分构建 DOM/CSSOM 的流程、何为回流(reflow)/重绘(repaint)、哪些操作会触发、如何优化(合并操作、离屏、transform/opacity)。
渲染流水简要
- 解析 HTML → DOM Tree
- 解析 CSS → CSSOM
- Render Tree(渲染树)构建(结合 DOM + CSSOM,忽略 display:none 等节点)
- 布局(reflow):计算元素大小与位置(涉及几何信息)。
- 绘制(paint):把元素转换为像素(颜色/文本/阴影等)。
- 合成(composite):分层并送入 GPU,最终合成到屏幕。
触发回流/重绘的常见操作
- 回流(高代价) :改变几何信息(width/height/margin/padding/position/DOM 增删/文本内容改变等),也包括读取会强制回流的属性(
offsetWidth,scrollTop,getComputedStyle)。 - 重绘(相对低):视觉但不影响布局(color/background等)。
- 浏览器优化建议 :
- 批量 DOM 修改(document fragment、一次性 innerHTML 替换)。
- 减少同步读取布局信息后马上写入(避免"读写"交错)。
- 把动画属性限定为可合成的(
transform和opacity),使用will-change谨慎提示合成层。 - 使用虚拟列表(虚拟化)避免大量节点渲染。
- 使用
requestAnimationFrame在合适时间窗执行动画样式变更。
7 构建工具对比与选型:Vite / Webpack / Rollup
考点:知道每个工具的本质、场景适配、优缺点与工程化考量(plugin 生态、HMR 性能、生产构建能力)。
本质与设计目标
- Webpack:模块打包器,功能全面、插件/loader 丰富,适合大型复杂应用(复杂 asset 管理、legacy 兼容)。但 dev 构建慢(尤其冷启动),需要配置。
- Rollup:侧重打包库(library),输出更干净的 ES modules,Tree-shaking 效果好,适合打包小巧库或工具。
- Vite:开发期间基于原生 ES 模块(esbuild 用于依赖预构建),极快的冷启动与 HMR;生产构建实际调用 Rollup。目标是极速开发体验,推荐用于现代前端应用(Vue/React 等)开发。
何时选哪种
- 开发用体验优先(快速迭代):Vite(更快 HMR、instant server start)。
- 打包库(需要精细输出格式、对 tree-shaking 要求高):Rollup。
- 大型单体工程、需要丰富 loader/plugin、兼容 legacy 工具链:Webpack(仍然是工程里复杂场景首选)。
- 面试追问点:了解 esbuild 的角色(极快的 JS/TS 转换但并非完整替代 bundler),Vite 在生产构建上用的是 Rollup,Webpack 的 scope hoisting、code splitting、dynamic import 等能力也要会讲。
下面我将结合你给出的前端基础 + 框架(Vue/React)+ 性能优化 + 手写题 的方向,为你整理一套最实用的面试技巧与应对策略。这套策略适用于字节、美团、腾讯、快手等大厂一面/二面。
前端一二面总体策略
1. 如果无法答满,就把重点放在条理上
面试官最看重的不是你是否答到100%正确,而是:
- 能不能抓住核心点
- 能不能结构化表达
- 能不能举例说明你是真的懂
- 不会的题能否体面处理
例如:
混帐回答:
event loop 就是宏任务微任务......
优秀回答框架:
Event Loop 可以分三个层面解释:
- 调度模型(宏任务、微任务)
- 浏览器与 Node 的不同 task queue
- 常见触发点(Promise、setTimeout、DOM事件)
如果你需要,我可以逐层讲。
面试官听到这里,会觉得你体系非常清晰。
2. 面试过程中的通用表达框架
大多数题目都可以用「三步表达法」答:
(1)先用一句话抓核心
例如:
Vue3 改用 Proxy,因为 defineProperty 无法监听对象新增/删除属性,也无法深层递归劫持。
(2)进一步解释机制
Proxy 是一层代理,不需要递归每个子属性,可监听 13 种操作,因此性能更好、覆盖更全。
(3)结合实际场景
我在项目中遇到过修改 obj.xxx = xxx 视图不更新的问题,就是 Vue2 的局限。
回答任何综合类问题都可以带入一定的场景。
如何应对基础八股(JS、浏览器、性能)
数据结构、API 类问题
如:
- slice/splice
- 数组方法
- JS数据类型
答题策略:
不要硬背,要"分类回答"
例如:
数组方法我分三类讲:
- 不修改原数组:map、filter、reduce、slice...
- 修改原数组:push、pop、splice、sort...
- 遍历类:forEach、every、some...
毫无条理的输出会给面试官感觉像在死记硬背,所以需要我们把答案"结构化"。
浏览器机制(Event Loop、渲染流水线)
常被问:
- Event Loop
- 重绘/回流
- 从 URL 到渲染
答题技巧:分阶段讲
例如:
从输入 URL 到渲染可以分成 5 阶段:
- DNS
- TCP + TLS
- HTTP 请求资源
- 浏览器构建 DOM/CSSOM → Layout → Paint → Composite
- JS 执行、重绘/回流触发点
面试官会觉得你非常稳。
4. 框架类问题(Vue、React)回答技巧
Vue 技巧
Vue 有个特点:八股点固定。
常问:
- Vue2/3 响应式机制
- 生命周期
- 父子组件顺序
- diff 算法
- computed 与 watch 区别
答题要有"对比性":
Vue3 更强的点有三个:
- 响应式从 defineProperty 变为 Proxy
- API 设计从 Options 变为 Composition
- 编译器更智能(tree-shaking + 静态提升)
面试技巧:有对比就有深度。
React 技巧
我目前还没学,学到了再说吧...
但是如果真的遇到了毫无头绪的或者自己没学到的范畴,可以大方的承认自己还没学过,也可以讲讲本题同类型的自己学过的东西,千万不要0基础胡然。
7. 如何主动拿分(提出场景 + 实战经验)
面试官问:
图片为什么会在移动端模糊?
我们先:
我从三个角度回答: DPR、图片格式、布局方式。
然后:
我实际项目中因为 DPR=3 导致 icon 模糊,通过 3 倍图 + object-fit 解决过。
面试官会觉得你经验很丰富。
8. 如何面对项目拷打环节
你要提前准备:
1. 背出项目的结构化介绍模板
这个项目主要解决什么问题(一句话)
技术栈是什么
核心模块有哪些
性能与稳定性怎么做
遇到什么难点 & 怎么解决
2. 一定要准备一个"技术亮点"
例如:
- 图片懒加载 + 节流
- 封装请求库 + Token 刷新
- 本地存储限流
- 虚拟列表
- 无限滚动
9. 遇到复杂八股问题(如 HTTP/SSL/TCP)怎么稳住?
你不会全部答,但可以用"层级策略":
HTTP 的演进我从两个维度讲:
- 功能增强
- 阻塞解决
0.9:纯文本1.0:短连接
1.1:Keep-Alive + pipelining(但仍有队头阻塞)
2:多路复用解决队头阻塞
3:基于 QUIC,避免 TCP 慢启动
即使答不细,结构清晰就很稳。