前端八股文面经大全:腾讯前端暑期提前批一、二、三面面经(上)(2026-03-04)·面经深度解析

前言

大家好,我是木斯佳。

相信很多人都感受到了,在AI浪潮的席卷之下,前端领域的门槛在变高,纯粹的"增删改查"岗位正在肉眼可见地减少。曾经热闹非凡的面经分享,如今也沉寂了许多。但我们都知道,市场的潮水退去,留下的才是真正在踏实准备、努力沉淀的人。学习的需求,从未消失,只是变得更加务实和深入。

这个专栏的初衷很简单:拒绝过时的、流水线式的PDF引流贴,专注于收集和整理当下最新、最真实的前端面试资料。我会在每一份面经和八股文的基础上,尝试从面试官的角度去拆解问题背后的逻辑,而不仅仅是提供一份静态的背诵答案。无论你是校招还是社招,目标是中大厂还是新兴团队,只要是真实发生、有价值的面试经历,我都会在这个专栏里为你沉淀下来。

温馨提示:市面上的面经鱼龙混杂,甄别真伪、把握时效,是我们对抗内卷最有效的武器。

面经原文内容(一面)

📍面试公司:腾讯

🕐面试时间:2月10日

💻面试岗位:前端暑期提前批(一面)

⏱️预计时长:60分钟,实际51分钟

❓面试问题:

开场

  1. 对于部门的背景和这次面试有什么想问的吗

项目与跨端

  1. 我看到你现在是在百度实习,可以讲讲这个业务吗

  2. 跨端做的是IOS还是安卓

  3. 你对整个架构有什么理解吗,比如离线包这一块,比如离线包解决什么样的问题,离线包是怎么下发和更新的

  4. 如果说不用离线包,在app上打开一个http地址,这个页面会有什么问题

  5. 离线包除了快还有什么优势

React原理

  1. React18新特性有了解吗

  2. 在没有这些特性之前,react是怎么调度的,有了之后是怎么调度的

  3. fiber本身是为了解决什么样的问题

  4. 如果没有fiber,diff的时候会怎么样,会不会有一些性能瓶颈

TypeScript

  1. 平时ts用的多吗

  2. 讲讲泛型,如果现在要通过泛型传入一个string进去,希望推导出来的结果也是string,怎么做

React Hooks

  1. 平时用vue还是react多一点

  2. 讲一下react中常用的hooks

  3. useLayoutEffect和useEffect有什么区别

  4. useEffect中可以返回一个函数,这个函数什么时候会执行

性能优化

  1. 平时有没有对项目做一些性能优化

  2. 除了资源相关的优化,还能在哪些方面做优化

  3. 在浏览器中从输入URL到页面加载完毕的过程是什么(引出可优化的内容)

网络

  1. 有了解过http2.0吗,可以讲一下他的一些特性吗

  2. 二进制帧如果丢失,重传机制是怎么样的

  3. TCP和UDP的区别

  4. TCP是怎么去实现可靠传输的

手撕

  • 深拷贝(后续又延伸问了处理除了对象和数组类型之外的数据的思路)

反问

  1. 反问及建议

来源:牛客网 喜喜玺玺

📝 腾讯前端暑期提前批一面·深度解析

🎯 面试整体画像

维度 特征
公司定位 腾讯 - 互联网巨头
面试风格 深度原理型 + 项目延伸型 + 网络基础型
难度评级 ⭐⭐⭐⭐(四星半,从项目到原理层层深入)
考察重心 跨端架构、React原理、TS泛型、性能优化、网络协议、手写能力

木木有话说:这场面试比较有价值,我分成了上下两篇去讲,今天的热帖前10只有一个是前端的。虽然环境不行,但是坚持总有回报,感谢原UP的分享,也恭喜他成功获得offer。

🔍 逐题深度解析

一、跨端架构与离线包

问题:你对整个架构有什么理解吗,比如离线包这一块?
javascript 复制代码
// 1. 离线包是什么?
// 离线包是将H5页面资源(HTML/CSS/JS/图片)打包下载到本地,下次打开时直接从本地加载

// 2. 离线包解决的问题
// - 网络依赖:弱网/无网环境下可访问
// - 加载速度:本地加载,跳过网络请求
// - 用户体验:秒开率提升,白屏时间减少

// 3. 离线包下发和更新流程
// 3.1 下发
// - 发布系统生成离线包(zip包)
// - 上传到CDN
// - App启动时检查更新

// 3.2 更新机制
// - 增量更新:只下载变更的文件
// - 全量更新:版本差异大时全量下载
// - 灰度发布:逐步放量,监控异常

// 3.3 离线包结构
offline-package/
  ├── manifest.json    // 版本信息、文件列表
  ├── index.html       // 入口文件
  ├── static/
  │   ├── css/
  │   ├── js/
  │   └── images/
问题:不用离线包,在app上打开http地址会有什么问题?
javascript 复制代码
// 1. 网络问题
// - 弱网环境加载慢或失败
// - 首次打开需要下载所有资源

// 2. 性能问题
// - DNS解析耗时
// - TCP连接耗时
// - TLS握手耗时
// - 资源串行下载

// 3. 用户体验问题
// - 白屏时间长
// - 加载进度不可控
// - 断网时完全不可用

// 4. 数据统计
// 对比数据:
// - 离线包:平均加载时间 200ms
// - HTTP在线:平均加载时间 1.2s
// - 离线包首屏加载速度提升 83%
问题:离线包除了快还有什么优势?
javascript 复制代码
// 1. 离线可用
// 地铁、电梯等弱网场景仍可正常使用

// 2. 节省流量
// - 只下载一次,后续使用本地资源
// - 增量更新只下载变更部分

// 3. 版本控制
// - 统一版本管理,避免缓存混乱
// - 灰度发布,逐步放量

// 4. 安全可控
// - 离线包可签名验证
// - 避免中间人攻击

// 5. 性能优化空间
// - 可预加载下一个页面
// - 可预渲染页面

// 6. 数据监控
// - 可统计离线包使用率
// - 可监控加载成功率

二、React18新特性与调度

问题:React18新特性有了解吗?
javascript 复制代码
// 1. 并发渲染(Concurrent Rendering)
// - 渲染可中断,根据优先级调度
// - 高优先级任务优先执行

// 2. 自动批处理(Automatic Batching)
// - 在Promise、setTimeout中也能批量更新
setTimeout(() => {
  setCount(c => c + 1)
  setFlag(f => !f) // React18中会合并,只触发一次渲染
}, 0)

// 3. 新Hooks
// - useTransition:标记非紧急更新
const [isPending, startTransition] = useTransition()
startTransition(() => {
  setState(newState) // 低优先级更新
})

// - useDeferredValue:延迟更新
const deferredValue = useDeferredValue(value)

// - useId:生成唯一ID
const id = useId()

// 4. Suspense改进
// - 支持服务端渲染
// - 支持数据获取

// 5. 新Root API
// React 18
const root = createRoot(container)
root.render(<App />)

// React 18之前
ReactDOM.render(<App />, container)
问题:在没有这些特性之前,react是怎么调度的,有了之后是怎么调度的?
javascript 复制代码
// React 18之前:同步不可中断渲染
// - 递归遍历虚拟DOM,一旦开始无法中断
// - 如果组件树很大,会阻塞主线程
// - 用户输入、动画会出现卡顿

// React 18之后:并发可中断渲染
// 1. 时间切片
// 将渲染工作拆分成小单元(5ms),空闲时执行
requestIdleCallback(workLoop)

// 2. 优先级调度
const priorities = {
  Immediate: 1,  // 用户输入
  UserBlocking: 2, // 点击、滚动
  Normal: 3,       // 网络请求
  Low: 4,          // 数据预加载
  Idle: 5          // 日志上报
}

// 3. 双缓冲
// current树(当前显示) + workInProgress树(内存构建)
// 构建完成后一次性切换

// 4. 调度流程
function scheduleUpdate(priority) {
  if (priority === Immediate) {
    // 立即执行
    performSyncWork()
  } else {
    // 放入任务队列,等待调度
    taskQueue.push({ update, priority })
    requestIdleCallback(processTaskQueue)
  }
}
问题:fiber本身是为了解决什么样的问题?
javascript 复制代码
// 1. React 15的问题
// - 递归更新:一旦开始无法中断
// - 主线程长时间占用:页面卡顿
// - 无法优先级调度:高优先级任务被阻塞

// 2. Fiber的解决方案
// 2.1 可中断
// Fiber将更新拆分成小单元,每执行一个单元检查是否有更高优先级任务

// 2.2 优先级调度
// 不同更新分配不同优先级
// 高优先级任务可打断低优先级

// 2.3 任务复用
// 更新过程中可以复用已完成的工作

// 2.4 错误边界
// 可以捕获子组件树的错误

// 3. Fiber节点结构
{
  tag: 1,                    // 组件类型
  type: 'div',               // 元素类型
  key: null,                 // 唯一标识
  stateNode: DOM节点,        // 真实DOM
  return: Fiber父节点,       // 父节点
  child: Fiber子节点,        // 第一个子节点
  sibling: Fiber兄弟节点,    // 下一个兄弟节点
  pendingProps: {},          // 新props
  memoizedProps: {},         // 当前props
  memoizedState: {},         // 当前state
  effectTag: 'UPDATE',       // 操作类型
  lanes: 1,                  // 优先级
  alternate: null            // 指向workInProgress树
}
问题:如果没有fiber,diff的时候会怎么样?
javascript 复制代码
// 没有Fiber的情况下:
// 1. 递归diff,无法中断
function diff(oldNode, newNode) {
  // 比较节点
  if (oldNode.type !== newNode.type) {
    replaceNode(oldNode, newNode)
    return
  }
  
  // 递归子节点
  for (let i = 0; i < oldNode.children.length; i++) {
    diff(oldNode.children[i], newNode.children[i])
  }
}

// 2. 性能瓶颈
// - 如果组件树有1000个节点,一次更新需要执行1000次diff
// - 中间无法让给用户输入,页面卡顿
// - 帧率可能掉到10fps以下

// 3. 具体问题
// - 长列表更新:全部重新计算
// - 动画卡顿:渲染任务抢占主线程
// - 输入延迟:用户输入得不到响应

// 4. 有Fiber后的改善
// - 增量渲染:分片执行,每片约5ms
// - 优先级调度:用户输入优先处理
// - 帧率提升:稳定在60fps

三、TypeScript泛型

问题:讲讲泛型,如果现在要通过泛型传入一个string进去,希望推导出来的结果也是string,怎么做?
typescript 复制代码
// 1. 基础泛型
function identity<T>(arg: T): T {
  return arg
}

const result = identity<string>('hello') // result类型是string

// 2. 类型推导
const result2 = identity('hello') // 自动推导为string

// 3. 约束泛型
function loggingIdentity<T extends { length: number }>(arg: T): T {
  console.log(arg.length) // 可以访问length属性
  return arg
}

// 4. 多个泛型参数
function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 }
}

// 5. 泛型工具类型
// 传入string返回string的类型工具
type Identity<T> = T extends string ? string : T

type Result = Identity<string> // string
type Result2 = Identity<number> // number

// 6. 泛型约束实现传入string返回string
type SameType<T> = T extends string ? string : T

function sameType<T>(arg: T): SameType<T> {
  return arg as any
}

const a = sameType('hello') // string
const b = sameType(123)     // number

// 7. 更精确的写法
type EnsureString<T> = T extends string ? T : never

function ensureString<T>(arg: T & EnsureString<T>): T {
  return arg
}

const c = ensureString('hello') // 只能传string
// ensureString(123) // 报错

四、React Hooks深入

问题:讲一下react中常用的hooks
javascript 复制代码
// 1. useState - 状态管理
const [count, setCount] = useState(0)

// 2. useEffect - 副作用
useEffect(() => {
  document.title = `点击了${count}次`
  return () => { /* 清理 */ }
}, [count])

// 3. useContext - 上下文
const theme = useContext(ThemeContext)

// 4. useReducer - 复杂状态
const [state, dispatch] = useReducer(reducer, initialState)

// 5. useCallback - 缓存函数
const handleClick = useCallback(() => {
  doSomething(count)
}, [count])

// 6. useMemo - 缓存计算结果
const expensiveValue = useMemo(() => {
  return computeExpensive(count)
}, [count])

// 7. useRef - 引用
const inputRef = useRef(null)

// 8. useLayoutEffect - 同步执行
useLayoutEffect(() => {
  // DOM更新后同步执行
}, [])

// 9. useImperativeHandle - 暴露子组件方法
useImperativeHandle(ref, () => ({
  focus: () => inputRef.current.focus()
}))

// 10. useDebugValue - 调试
useDebugValue(value)
问题:useLayoutEffect和useEffect有什么区别?
javascript 复制代码
// 1. 执行时机
// useEffect:异步执行,在浏览器绘制之后
// useLayoutEffect:同步执行,在DOM更新后、浏览器绘制前

// 2. 执行顺序
function Component() {
  useEffect(() => {
    console.log('useEffect')
  }, [])
  
  useLayoutEffect(() => {
    console.log('useLayoutEffect')
  }, [])
  
  return <div>Component</div>
}
// 输出顺序:useLayoutEffect → useEffect

// 3. 适用场景
// useLayoutEffect:需要同步测量DOM
useLayoutEffect(() => {
  const height = ref.current.offsetHeight // 立即测量
  setHeight(height)
}, [])

// useEffect:大多数副作用场景
useEffect(() => {
  fetchData() // 异步请求
}, [])

// 4. 性能考虑
// useLayoutEffect会阻塞浏览器绘制,尽量少用
// useEffect不会阻塞绘制,性能更好
问题:useEffect中可以返回一个函数,这个函数什么时候会执行?
javascript 复制代码
// 1. 组件卸载时
useEffect(() => {
  console.log('组件挂载')
  
  return () => {
    console.log('组件卸载') // 组件销毁时执行
  }
}, [])

// 2. 依赖更新前(清理上一次的副作用)
useEffect(() => {
  console.log('count变化:', count)
  
  return () => {
    console.log('清理上一次的count副作用') // 每次count更新前执行
  }
}, [count])

// 3. 每次重新渲染后
useEffect(() => {
  console.log('每次渲染后执行')
  
  return () => {
    console.log('下次渲染前执行') // 每次重新渲染前都会执行
  }
}) // 无依赖数组

// 4. 典型应用:清除定时器
useEffect(() => {
  const timer = setInterval(() => {
    console.log('tick')
  }, 1000)
  
  return () => {
    clearInterval(timer) // 组件卸载时清除定时器
  }
}, [])

// 5. 取消订阅
useEffect(() => {
  const subscription = eventEmitter.subscribe(handleEvent)
  
  return () => {
    subscription.unsubscribe() // 组件卸载时取消订阅
  }
}, [])

五、性能优化

问题:除了资源相关的优化,还能在哪些方面做优化?
javascript 复制代码
// 1. 渲染优化
// 1.1 React.memo
const MemoizedComponent = React.memo(Component)

// 1.2 useMemo避免重复计算
const expensiveValue = useMemo(() => compute(a, b), [a, b])

// 1.3 useCallback避免函数重新创建
const handleClick = useCallback(() => doSomething(), [deps])

// 1.4 虚拟列表
import { FixedSizeList } from 'react-window'
<List
  height={500}
  itemCount={10000}
  itemSize={35}
>
  {({ index, style }) => <div style={style}>Row {index}</div>}
</List>

// 2. 代码优化
// 2.1 避免内联函数
// ❌ 不好
<button onClick={() => handleClick(id)} />

// ✅ 好
const handleClick = useCallback(() => doSomething(id), [id])
<button onClick={handleClick} />

// 2.2 避免重复计算
// ❌ 不好
const visibleList = list.filter(item => item.visible) // 每次渲染都计算

// ✅ 好
const visibleList = useMemo(() => 
  list.filter(item => item.visible), [list]
)

// 3. 网络优化
// 3.1 请求合并
// 将多个请求合并成一个

// 3.2 数据缓存
const cache = new Map()
async function fetchData(key) {
  if (cache.has(key)) return cache.get(key)
  const data = await api.get(key)
  cache.set(key, data)
  return data
}

// 4. 用户体验优化
// 4.1 骨架屏
<div className="skeleton" />

// 4.2 渐进式加载
// 先显示低质量内容,再替换为高质量

// 4.3 预加载
<link rel="preload" href="next-page.js" as="script">
问题:从输入URL到页面加载完毕的过程,有哪些可优化的点?
javascript 复制代码
// 1. DNS解析优化
// - DNS预解析
<link rel="dns-prefetch" href="//api.example.com">

// 2. TCP连接优化
// - 预连接
<link rel="preconnect" href="https://api.example.com">

// 3. 请求发送优化
// - 减少请求数量(合并、雪碧图)
// - 减少请求体积(压缩、Gzip)
// - CDN加速

// 4. 服务器响应优化
// - 缓存策略
// - 数据压缩
// - CDN缓存

// 5. 浏览器解析优化
// - 关键CSS内联
// - 异步加载JS
// - 懒加载

// 6. 渲染优化
// - 避免重排重绘
// - 骨架屏
// - 虚拟列表

六、网络协议

问题:有了解过http2.0吗,可以讲一下他的一些特性吗?
javascript 复制代码
// HTTP/2.0核心特性

// 1. 二进制分帧
// 将消息分割为更小的帧,二进制传输
// 请求1: [frame1][frame2]
// 请求2:   [frame1][frame2][frame3]

// 2. 多路复用
// 一个TCP连接同时发送多个请求
// 避免HTTP/1.1的队头阻塞

// 3. 头部压缩
// 使用HPACK压缩头部,减少体积
// 第一次请求:{ method: 'GET', path: '/', user-agent: 'Chrome' }
// 第二次请求:只发送差异部分

// 4. 服务器推送
// 服务器主动推送资源
push('/', {
  'style.css': styles,
  'script.js': script
})

// 5. 请求优先级
// 可以设置请求优先级,关键资源优先

// 6. 性能提升对比
// HTTP/1.1: 6个连接,串行请求
// HTTP/2.0: 1个连接,并行请求
// 加载时间减少30-50%
问题:二进制帧如果丢失,重传机制是怎么样的?
javascript 复制代码
// 1. HTTP/2.0基于TCP,重传机制由TCP保证

// 2. TCP重传机制
// 2.1 超时重传
// 发送数据后启动定时器,超时未收到ACK则重传

// 2.2 快速重传
// 收到3个重复ACK,立即重传

// 2.3 选择性确认(SACK)
// 告知发送方哪些数据已收到,只重传丢失部分

// 3. HTTP/2.0层面的处理
// 3.1 流控
// 每个流有独立的流量控制

// 3.2 优先级
// 丢失的帧如果是高优先级,会优先重传

// 3.3 错误处理
// 如果某个流持续丢包,可能关闭该流
问题:TCP和UDP的区别?
维度 TCP UDP
连接 面向连接(三次握手) 无连接
可靠性 可靠传输(确认重传) 不可靠,可能丢包
顺序 保证数据顺序 不保证顺序
流量控制 有(滑动窗口)
拥塞控制
头部大小 20字节 8字节
速度
适用场景 HTTP、FTP、邮件 直播、DNS、游戏
问题:TCP是怎么去实现可靠传输的?
javascript 复制代码
// 1. 确认应答(ACK)
// 发送方发送数据后,等待接收方确认
// 未收到确认则重传

// 2. 超时重传
// 发送数据时启动定时器,超时未收到ACK则重传

// 3. 序列号
// 每个字节都有序列号,接收方按序组装

// 4. 校验和
// 检测数据是否损坏

// 5. 流量控制(滑动窗口)
// 接收方告知发送方自己的接收能力
// 发送方根据窗口大小调整发送速度

// 6. 拥塞控制
// - 慢启动
// - 拥塞避免
// - 快速重传
// - 快速恢复

七、手撕:深拷贝

问题:深拷贝(处理对象、数组及其他类型)
javascript 复制代码
// 1. 基础版(只处理对象和数组)
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj
  
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item))
  }
  
  const cloned = {}
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloned[key] = deepClone(obj[key])
    }
  }
  return cloned
}

// 2. 完整版(处理循环引用、各种类型)
function deepClone(obj, hash = new WeakMap()) {
  // 处理null和基本类型
  if (obj === null || typeof obj !== 'object') return obj
  
  // 处理循环引用
  if (hash.has(obj)) return hash.get(obj)
  
  // 处理Date
  if (obj instanceof Date) {
    return new Date(obj)
  }
  
  // 处理RegExp
  if (obj instanceof RegExp) {
    return new RegExp(obj)
  }
  
  // 处理Map
  if (obj instanceof Map) {
    const map = new Map()
    hash.set(obj, map)
    obj.forEach((value, key) => {
      map.set(key, deepClone(value, hash))
    })
    return map
  }
  
  // 处理Set
  if (obj instanceof Set) {
    const set = new Set()
    hash.set(obj, set)
    obj.forEach(value => {
      set.add(deepClone(value, hash))
    })
    return set
  }
  
  // 处理Array
  if (Array.isArray(obj)) {
    const arr = []
    hash.set(obj, arr)
    obj.forEach((item, index) => {
      arr[index] = deepClone(item, hash)
    })
    return arr
  }
  
  // 处理Object
  const cloned = Object.create(Object.getPrototypeOf(obj))
  hash.set(obj, cloned)
  
  // 处理Symbol属性
  const symbols = Object.getOwnPropertySymbols(obj)
  symbols.forEach(sym => {
    cloned[sym] = deepClone(obj[sym], hash)
  })
  
  // 处理普通属性
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloned[key] = deepClone(obj[key], hash)
    }
  }
  
  return cloned
}

// 3. JSON方法(有局限)
const clone = JSON.parse(JSON.stringify(obj))
// 局限:不能处理函数、undefined、Symbol、循环引用

// 4. 处理其他类型
function cloneOtherTypes(obj) {
  switch (Object.prototype.toString.call(obj)) {
    case '[object Date]':
      return new Date(obj)
    case '[object RegExp]':
      return new RegExp(obj)
    case '[object Map]':
      return new Map(obj)
    case '[object Set]':
      return new Set(obj)
    default:
      return null
  }
}

📚 知识点速查表

知识点 核心要点
离线包 本地资源、快、离线可用、增量更新
React18 并发渲染、自动批处理、新Hooks
Fiber 可中断、优先级调度、双缓冲
TS泛型 类型参数、约束、工具类型
Hooks 常用Hooks、执行时机、清理函数
性能优化 渲染优化、代码优化、网络优化
HTTP/2 二进制分帧、多路复用、头部压缩
TCP可靠 ACK、重传、序列号、滑动窗口
深拷贝 循环引用、各种类型、WeakMap

📌 最后一句:

腾讯这场一面,从跨端架构到React原理,从TS泛型到网络协议,再到手写深拷贝,覆盖了一个前端工程师需要的核心能力。面试官问的每个问题都在考察原理深度和工程实践的结合。能答好这些,说明你已经有了冲击大厂的实力。

相关推荐
嘉琪0012 小时前
Day4 完整学习包(this 指向)——2026 0313
前端·javascript·学习
前端小菜鸟也有人起2 小时前
Vue3父子组件通信方法总结
前端·javascript·vue.js
peachSoda72 小时前
小程序图片加载优化方案
前端·微信小程序·小程序
Maimai108082 小时前
React Server Components 是什么?一文讲清 CSR、Server Components 与 Next.js 中的客户端/服务端组件
前端·javascript·css·react.js·前端框架·html·web3
肉肉不吃 肉2 小时前
事件循环,宏任务,微任务
前端·javascript
z止于至善2 小时前
Vue ECharts:Vue 生态下的 ECharts 可视化最佳实践
前端·vue.js·echarts·vue echarts
℘团子এ2 小时前
什么是Docker
前端·docker·容器