前言
大家好,我是木斯佳。
相信很多人都感受到了,在AI浪潮的席卷之下,前端领域的门槛在变高,纯粹的"增删改查"岗位正在肉眼可见地减少。曾经热闹非凡的面经分享,如今也沉寂了许多。但我们都知道,市场的潮水退去,留下的才是真正在踏实准备、努力沉淀的人。学习的需求,从未消失,只是变得更加务实和深入。
这个专栏的初衷很简单:拒绝过时的、流水线式的PDF引流贴,专注于收集和整理当下最新、最真实的前端面试资料。我会在每一份面经和八股文的基础上,尝试从面试官的角度去拆解问题背后的逻辑,而不仅仅是提供一份静态的背诵答案。无论你是校招还是社招,目标是中大厂还是新兴团队,只要是真实发生、有价值的面试经历,我都会在这个专栏里为你沉淀下来。专栏快速地址

温馨提示:市面上的面经鱼龙混杂,甄别真伪、把握时效,是我们对抗内卷最有效的武器。
面经原文内容
📍面试公司:TME QQ音乐
🕐面试时间:4月24日下午6点55,时长23分钟
💻面试岗位:前端暑期电话三面
📝面试体验:二面觉得太烂了居然过了,可能是运气好或排序
❓面试问题:
- 介绍一下项目里你觉得最有难度的点是什么(依旧虚拟列表)
- 你平常学习前端开发主要是自学,还是参加培训
- 你有做过自己的开源项目或者参与过开源项目研发吗
- 讲一下你后台管理系统里大文件分片上传的完整流程
- 计算文件 hash 本身是强 IO 操作,可能会导致卡顿,你会怎么优化
- 如果想在 Web 里嵌入 C++ 的逻辑,一般会用什么方式
- 你了解 WebAssembly 吗
- 你接触过 C++ 或端侧 App 开发吗
- 如果让你实现一个快速排序,你会怎么做
- Web 端常见的持久化机制有哪些
- TCP 和 UDP 有什么区别
- HTTP/1.1 和 HTTP/2 的区别是什么
- HTTP/2 和 HTTP/3 的区别是什么
- Web 上实现动画一般有哪几种方式
- 你了解 Canvas 吗
- 你对 Web 性能指标了解多少
- 如果要评价一个页面快不快、用户体验好不好,你会看哪些指标
- 如果发现页面性能有问题,你一般会从哪些方向分析
- 你实际项目里有遇到过性能问题吗,怎么解决的
来源:牛客网 前端死了咩
💡 木木有话说(刷前先看)
三面还在问一些计算机原理,遇到的比较少,一般三面技术侧的问题比例就变少了,收录做个补充吧
📝 TME QQ音乐前端三面·深度解析
🎯 面试整体画像
| 维度 | 特征 |
|---|---|
| 面试风格 | 广度考察型 + 底层追问型 + 实战导向型 |
| 难度评级 | ⭐⭐⭐⭐(四星,WebAssembly、HTTP/3、性能指标全覆盖) |
| 考察重心 | 项目难点、性能优化、底层技术(WASM/C++)、网络协议、动画、性能指标 |
| 特殊之处 | 电话面试,23分钟快速覆盖20+知识点,考察知识广度 |
🔍 逐题深度解析
四、大文件分片上传的完整流程
回答思路:参考之前面经,从分片、hash、上传、合并、秒传完整链路说明。
完整流程:
- 文件分片 :
Blob.prototype.slice将文件切成N个分片(如5MB) - 计算Hash:使用Web Worker计算完整文件MD5(用于秒传)和分片MD5(用于断点续传)
- 上传前检查:请求服务端,获取已上传的分片列表
- 并发上传:控制并发数(如3-5个),上传缺失分片,携带分片索引和MD5
- 断点续传:上传中断时,下次只传缺失分片
- 合并通知:所有分片上传完成后,通知服务端合并
- 秒传:完整文件MD5已存在时,直接跳过上传
javascript
// 核心流程代码
async function uploadFile(file) {
const chunkSize = 5 * 1024 * 1024
const chunks = Math.ceil(file.size / chunkSize)
const fileHash = await computeMD5InWorker(file)
// 秒传检查
const { exists, uploadedChunks } = await checkFile(fileHash)
if (exists) return alert('秒传成功')
for (let i = 0; i < chunks; i++) {
if (uploadedChunks.includes(i)) continue
const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize)
const chunkHash = await computeMD5(chunk)
await uploadChunk({ index: i, chunk, chunkHash })
}
await mergeChunks(fileHash, chunks)
}
五、计算文件Hash是强IO操作,会导致卡顿,怎么优化
优化方案(从之前面经提炼):
| 优化方向 | 具体方法 | 效果 |
|---|---|---|
| Web Worker | 在Worker线程计算,不阻塞主线程 | UI保持响应 |
| 增量计算 | 分块读取,边读边更新hash | 减少内存占用 |
| 采样计算 | 只计算开头/中间/结尾部分数据 | 快速秒传,牺牲准确性 |
| 降低优先级 | 使用requestIdleCallback在空闲时计算 |
不影响交互 |
| 分片复用 | 用分片MD5推导完整文件MD5 | 避免重复计算 |
javascript
// 空闲时计算
function computeHashIdle(file) {
requestIdleCallback(async () => {
const hash = await computeMD5(file)
localStorage.setItem('fileHash', hash)
})
}
六、如果想在Web里嵌入C++的逻辑,一般会用什么方式
回答思路:主要有三种方式。
方案:
- WebAssembly :将C++编译成
.wasm,通过JavaScript调用,性能接近原生 - Web Worker + 本地服务:通过WebSocket与本地C++服务通信(复杂)
- NPAPI/PPAPI:老旧浏览器插件技术,已淘汰
推荐:WebAssembly,现代浏览器标准。
七、你了解WebAssembly吗
回答思路:WebAssembly是一种二进制指令格式,可在浏览器中高效运行。
特点:
- 高性能:接近原生的执行速度
- 多语言:C/C++/Rust/Go等可编译成WASM
- 安全:沙箱隔离,遵循同源策略
- 体积小:二进制格式,比JS小
适用场景:视频/音频编解码、图像处理、游戏引擎、加密计算。
javascript
// 加载WASM模块
const response = await fetch('module.wasm')
const buffer = await response.arrayBuffer()
const module = await WebAssembly.instantiate(buffer)
module.exports.add(1, 2) // 调用C++函数
九、如果让你实现一个快速排序,你会怎么做
快速排序:分治算法,选取基准,分区递归。
javascript
function quickSort(arr) {
if (arr.length <= 1) return arr
const pivot = arr[0]
const left = []
const right = []
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) left.push(arr[i])
else right.push(arr[i])
}
return [...quickSort(left), pivot, ...quickSort(right)]
}
// 原地排序版本(节省内存)
function quickSortInPlace(arr, left = 0, right = arr.length - 1) {
if (left >= right) return
const pivotIndex = partition(arr, left, right)
quickSortInPlace(arr, left, pivotIndex - 1)
quickSortInPlace(arr, pivotIndex + 1, right)
}
function partition(arr, left, right) {
const pivot = arr[right]
let i = left - 1
for (let j = left; j < right; j++) {
if (arr[j] <= pivot) {
i++
[arr[i], arr[j]] = [arr[j], arr[i]]
}
}
[arr[i + 1], arr[right]] = [arr[right], arr[i + 1]]
return i + 1
}
时间复杂度 :平均O(n log n),最坏O(n²)
空间复杂度:O(log n)(递归栈)
十、Web端常见的持久化机制有哪些
| 机制 | 容量 | 特点 |
|---|---|---|
| localStorage | 5-10MB | 同步,永久存储 |
| sessionStorage | 5-10MB | 同步,标签页关闭清除 |
| IndexedDB | 大(>250MB) | 异步,支持索引/事务 |
| CacheStorage | 取决于配额 | Service Worker缓存 |
| Cookies | 4KB | 自动携带,有过期时间 |
| File System Access API | 大 | 读写本地文件 |
十一、TCP和UDP的区别
| 维度 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 可靠(确认+重传) | 不可靠 |
| 顺序 | 保证 | 不保证 |
| 拥塞控制 | 有 | 无 |
| 速度 | 慢 | 快 |
| 适用场景 | HTTP、文件传输 | 实时音视频、DNS、游戏 |
十二、HTTP/1.1和HTTP/2的区别
| 特性 | HTTP/1.1 | HTTP/2 |
|---|---|---|
| 连接模型 | 串行(需多个TCP连接并发) | 多路复用(单连接并发) |
| 头部压缩 | 无 | HPACK压缩 |
| 服务器推送 | 无 | 支持 |
| 二进制分帧 | 文本协议 | 二进制协议 |
| 优先级 | 无 | 支持请求优先级 |
十三、HTTP/2和HTTP/3的区别
| 特性 | HTTP/2 | HTTP/3 |
|---|---|---|
| 传输层 | TCP | UDP(QUIC协议) |
| 队头阻塞 | TCP层仍存在 | 解决(独立流) |
| 连接建立 | TCP+TLS(2-3 RTT) | 0-RTT / 1-RTT |
| 连接迁移 | 不支持(IP变化需重连) | 支持(Connection ID) |
十四、Web上实现动画一般有哪几种方式
方式:
- CSS动画 :
transition、animation+@keyframes - JS动画 :
requestAnimationFrame+ 手动更新样式 - Web Animations API :
element.animate() - Canvas/SVG动画:逐帧绘制
- GSAP等库:更强大的控制能力
性能建议 :优先用CSS动画(GPU加速),复杂用requestAnimationFrame,避免setTimeout/setInterval。
十五、你了解Canvas吗
Canvas:通过JS绘制2D图形的HTML元素。
特点:
- 像素级控制,适合复杂图形、游戏、图表
- 高性能,直接操作像素
- 无事件系统,需配合坐标计算
javascript
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect(10, 10, 100, 50)
十六~十七:Web性能指标与页面评价
核心指标(Web Vitals):
- FCP(First Contentful Paint):首次内容绘制 ≤1.8s
- LCP(Largest Contentful Paint):最大内容绘制 ≤2.5s
- INP(Interaction to Next Paint):交互延迟 ≤200ms
- CLS(Cumulative Layout Shift):累积布局偏移 ≤0.1
- TTFB(Time To First Byte):首字节时间 ≤800ms
评价页面体验:
- 加载速度:LCP、TTFB
- 交互性:INP、FID
- 视觉稳定性:CLS
- 资源利用:CPU占用、内存占用
十八:发现页面性能问题,从哪些方向分析
分析维度:
- 网络:Chrome DevTools Network面板,查看请求耗时、资源大小、是否阻塞
- 渲染:Performance面板,录制分析长任务、重排重绘
- 运行时:Memory面板,检查内存泄漏、DOM节点数
- 代码层面:React DevTools Profiler,查看组件渲染次数
- 日志监控:查看错误上报、性能指标(LCP/INP)
十九:实际项目里遇到的性能问题及解决
回答思路:结合具体项目说明。
示例 :
"在后台管理系统的长列表页面,滚动时卡顿严重。通过Performance面板发现,每次滚动都会触发大量重排。解决方案:实现虚拟滚动,只渲染可视区域的DOM节点,滚动帧率从20fps提升到60fps。"
📚 知识点速查表
| 知识点 | 核心要点 |
|---|---|
| 大文件上传 | 分片+MD5+断点续传+秒传+合并 |
| Hash优化 | Web Worker、增量计算、采样、空闲计算 |
| WebAssembly | C++编译成wasm,高性能,浏览器运行 |
| 快速排序 | 选基准、分区、递归,O(n log n) |
| 持久化 | localStorage/IndexedDB/CacheStorage |
| TCP vs UDP | 可靠/不可靠、连接/无连接、顺序/不保证 |
| HTTP/2 | 多路复用、头部压缩、服务器推送 |
| HTTP/3 | QUIC、解决TCP队头阻塞、0-RTT |
| 动画方式 | CSS/JS/requestAnimationFrame/Canvas |
| 性能指标 | FCP/LCP/INP/CLS/TTFB |
| 性能分析 | Network/Performance/Memory面板 |
📌 最后一句:
TME QQ音乐这场三面,是一场"知识广度"的快速检阅。从大文件上传优化、WebAssembly嵌入C++,到快速排序实现、HTTP版本演进、性能指标分析,面试官在23分钟内快速扫描了你的技术雷达。用户自述"对这些知识点不怎么熟",但能走到三面,说明决心和基础被认可。技术面试有时不是要你全对,而是看你是否具备解决问题的潜力和学习能力。