前端八股文面经大全:腾讯前端一面(2026-04-04)·深度解析

前言

大家好,我是木斯佳。

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

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

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

面经原文内容

📍面试公司:腾讯

🕐面试时间:近期

💻面试岗位:前端一面

❓面试问题:

  1. 自我介绍
  2. Monorepo 架构实现(代码位置 + 配置)
  3. AI 模块如何拆分(放在哪里)
  4. 双 token 如何实现 + 自动续期 + 无感刷新
  5. 无感刷新下请求队列问题(分页错乱):双token无感刷新下,如果存储的历史请求队列中的请求再次请求,会有什么问题?比如分页请求数据,原本请求page=1,此时access_token过期,接着再次点击下一页,导致在分页的情况下有两次请求(请求到不同的页下的数据),原本只希望出现一页的数据,此时出现两页的数据,如何解决这个bug问题?
  6. 项目与市面产品差异,优点
  7. AI对话是否与项目有强关联的关系?为什么这样?
  8. AI对话下上下文记忆的实现
  9. 详细介绍SSE,以及为什么不用websocket,他们两个有什么区别?常见的chatgpt等对话模式中为什么要用SSE,解决了什么问题?
  10. 为什么AI智能对话需要使用流式输出?不用其他的
  11. 介绍前端埋点SDK如何实现
  12. 介绍埋点中的web性能指标(FP/FCP/LCP/INP/CLS)的每个的详细含义
  13. 说明以上性能指标中你认为哪一个是最重要的?为什么?
  14. 讲述如何优化spa应用白屏,从哪几个方面可以优化这个问题?
  15. 说说对于你使用过的vue,react,svelte这三个框架,更擅长,喜欢使用哪一个框架,为什么?
  16. 说说为什么在react框架中为什么需要使用单标签?原理是什么?
  17. 详细说说缓存机制
  18. https 建立连接的原理,如何建立连接
  19. 说说http有哪几个版本,以及他们的不同之处(区别)
  20. 使用过哪些 AI 工具或者 AI 辅助开发的编辑器?

来源:牛客网 寻觅流光

💡 木木有话说(刷前先看)

腾讯这场一面,是一份"深度+广度"兼备的高质量面经。现在大厂对前端的要求好像越来越高了。从网络到项目基建到AI,属于什么都问类型的。


📝 腾讯前端一面·深度解析

🎯 面试整体画像

维度 特征
面试风格 工程实战型 + 深度追问型 + 场景设计型
难度评级 ⭐⭐⭐⭐(四星,涉及复杂业务场景和底层原理)
考察重心 工程化(Monorepo/模块拆分)、鉴权(双token/无感刷新)、AI对话(SSE/上下文)、性能(埋点/指标/白屏)、框架原理、网络协议
特殊之处 第5题的分页错乱bug非常真实,考察业务场景下的问题解决能力

🔍 逐题深度解析

二、Monorepo架构实现

回答思路:Monorepo是用一个仓库管理多个项目/包。

常用工具

  • pnpm workspace(推荐):节省磁盘空间,严格依赖管理
  • Nx:智能构建缓存,适合大型项目
  • Turborepo:增量构建,缓存优化
  • Lerna(较老)

目录结构

复制代码
my-monorepo/
├── packages/
│   ├── shared/        # 共享工具库
│   ├── components/    # 公共组件库
│   ├── ai-module/     # AI模块
│   └── web-app/       # 主应用
├── pnpm-workspace.yaml
└── package.json

pnpm-workspace.yaml

yaml 复制代码
packages:
  - 'packages/*'

三、AI模块如何拆分

回答思路 :按职责拆分,放在packages/ai-module

拆分原则

  • 核心层:AI SDK封装(调用API、SSE连接)
  • 业务层:提示词管理、对话上下文
  • UI层:对话组件、消息渲染
  • 工具层:函数调用(Tool Calling)实现
typescript 复制代码
// 目录结构
ai-module/
├── core/
│   ├── client.ts      # API客户端
│   └── stream.ts      # SSE处理
├── prompts/
│   └── templates.ts   # 提示词模板
├── hooks/
│   └── useChat.ts     # React/Vue Hook
├── components/
│   └── ChatBox.tsx    # 对话组件
└── index.ts

四、双token实现 + 自动续期 + 无感刷新

回答思路:access_token(短期)+ refresh_token(长期)。

流程

  1. 登录成功,服务端返回access_token(如2小时过期)和refresh_token(如7天过期)
  2. 前端存储token(通常access_token在内存,refresh_token在httpOnly cookie)
  3. 请求携带access_token
  4. access_token过期时,接口返回401
  5. 前端调用刷新接口,携带refresh_token换取新access_token
  6. 重试原请求

无感刷新实现

javascript 复制代码
let isRefreshing = false
let pendingRequests = []

axios.interceptors.response.use(
  response => response,
  async error => {
    if (error.response?.status === 401 && !error.config._retry) {
      if (isRefreshing) {
        // 等待刷新完成
        return new Promise(resolve => {
          pendingRequests.push(() => resolve(axios(error.config)))
        })
      }
      
      error.config._retry = true
      isRefreshing = true
      
      try {
        const { access_token } = await refreshToken()
        setAccessToken(access_token)
        // 重试所有等待的请求
        pendingRequests.forEach(cb => cb())
        pendingRequests = []
        return axios(error.config)
      } catch {
        // 刷新失败,跳转登录
        redirectToLogin()
      } finally {
        isRefreshing = false
      }
    }
    return Promise.reject(error)
  }
)

五、无感刷新下的请求队列问题(分页错乱)

问题场景

  • 用户请求第1页数据(page=1),此时access_token过期,请求进入等待队列
  • 用户继续点击下一页(page=2),也进入等待队列
  • token刷新成功后,两个请求同时发出,页面同时显示两页数据(错乱)

解决方案

方案1:请求去重(推荐)

javascript 复制代码
// 为每个请求生成唯一key,相同key的请求只保留最后一个
const requestMap = new Map()

function dedupeRequest(config) {
  const key = `${config.method}_${config.url}_${JSON.stringify(config.params)}`
  
  if (requestMap.has(key)) {
    // 取消上一个相同请求
    requestMap.get(key).cancel()
  }
  
  const cancelToken = new CancelToken(c => {
    requestMap.set(key, { cancel: c })
  })
  
  return { ...config, cancelToken }
}

方案2:请求队列只保留最新

javascript 复制代码
let latestRequest = null

function enqueueRequest(requestFn) {
  latestRequest = requestFn
}

function flushQueue() {
  if (latestRequest) {
    latestRequest()
    latestRequest = null
  }
}

方案3:禁用刷新期间的交互:刷新时显示loading遮罩,禁止用户操作。


六~七(项目差异与AI关联):略


八、AI对话上下文记忆的实现

回答思路:核心是将历史对话作为上下文传递给模型。

实现方式

  1. 前端维护消息数组messages = [{ role: 'user', content: '...' }, { role: 'assistant', content: '...' }]
  2. 每次请求携带历史消息POST /api/chat { messages: [...messages, newUserMessage] }
  3. 限制上下文长度:超出token限制时,截断或压缩早期消息
  4. 摘要压缩:历史过长时,调用模型生成摘要,替代原始消息
javascript 复制代码
const MAX_TOKENS = 4000

function buildContext(messages, newMessage) {
  let context = [...messages, newMessage]
  let tokens = estimateTokens(context)
  
  while (tokens > MAX_TOKENS && context.length > 1) {
    // 移除最早的非系统消息
    const removed = context.shift()
    if (removed.role !== 'system') {
      tokens = estimateTokens(context)
    }
  }
  
  return context
}

九、SSE详解与WebSocket区别

回答思路:参考之前面经。

区别

维度 SSE WebSocket
方向 单向(服务端→客户端) 双向
协议 HTTP WS/WSS
自动重连 内置 手动实现
数据格式 文本(UTF-8) 文本/二进制

为什么ChatGPT用SSE

  • 对话是单向流(模型生成→用户接收),不需要双向
  • 实现简单,基于HTTP
  • 自动重连,网络波动时体验好

十、为什么AI对话需要流式输出

回答思路:用户体验 + 实时反馈。

原因

  1. 减少等待焦虑:逐字输出让用户感知到"模型在工作"
  2. 提前展示结果:用户可以提前阅读,不必等全部生成
  3. 可中断性:用户发现回答不对时可以提前停止
  4. 长文本友好:生成1000字不需要等待10秒才看到内容

十一、前端埋点SDK实现

回答思路:一个完整的埋点SDK需要包含数据采集、上报、配置等模块。

核心功能

javascript 复制代码
class Tracker {
  constructor(options) {
    this.appId = options.appId
    this.reportUrl = options.reportUrl
    this.queue = []
    this.timer = null
  }
  
  // 初始化:监听全局错误、路由变化
  init() {
    this.listenErrors()
    this.listenRoute()
    this.startBatchTimer()
  }
  
  // 手动埋点
  track(eventName, properties = {}) {
    this.queue.push({
      event: eventName,
      properties,
      timestamp: Date.now(),
      url: location.href,
      ua: navigator.userAgent
    })
  }
  
  // 批量上报
  batchReport() {
    if (this.queue.length === 0) return
    const data = [...this.queue]
    this.queue = []
    navigator.sendBeacon(this.reportUrl, JSON.stringify(data))
  }
  
  // 定时批量发送
  startBatchTimer() {
    this.timer = setInterval(() => this.batchReport(), 3000)
  }
  
  // 页面关闭时立即发送
  beforeUnload() {
    this.batchReport()
  }
  
  // 监听性能指标
  reportPerformance() {
    const perf = performance.getEntriesByType('navigation')[0]
    this.track('page_performance', {
      dns: perf.domainLookupEnd - perf.domainLookupStart,
      tcp: perf.connectEnd - perf.connectStart,
      ttfb: perf.responseStart - perf.requestStart,
      domReady: perf.domContentLoadedEventEnd - perf.fetchStart,
      load: perf.loadEventEnd - perf.fetchStart
    })
  }
}

十二、Web性能指标详解

指标 全称 含义 标准
FP First Paint 第一个像素绘制到屏幕 无硬性标准
FCP First Contentful Paint 第一个内容(文本/图片)绘制 ≤1.8s
LCP Largest Contentful Paint 最大内容绘制完成 ≤2.5s
INP Interaction to Next Paint 交互延迟(点击/键盘响应) ≤200ms
CLS Cumulative Layout Shift 累计布局偏移 ≤0.1

获取方式

javascript 复制代码
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(entry.name, entry.startTime)
  }
}).observe({ entryTypes: ['paint', 'largest-contentful-paint', 'layout-shift'] })

十三、最重要的性能指标

回答思路:取决于业务类型,没有标准答案。

示例回答

"对于内容型网站(新闻、博客),我认为LCP最重要 ,因为它直接影响用户看到主要内容的速度。对于交互型应用(后台管理系统),INP最重要,因为用户需要频繁点击、输入,响应延迟会严重影响操作体验。"


十四、优化SPA应用白屏

回答思路:白屏是指从输入URL到看到内容的时间。

优化方向

  1. 减少首屏资源大小

    • 路由懒加载:React.lazy()
    • 代码分割:按页面拆分chunk
    • Tree shaking:移除未使用代码
  2. 优化加载顺序

    • 关键CSS内联
    • 非关键脚本异步加载(async/defer
    • 预加载关键资源(<link rel="preload">
  3. 骨架屏:在内容加载前展示占位图,减少用户感知等待

  4. 服务端渲染(SSR):直出HTML,无需等待JS执行

  5. 使用缓存:强缓存、Service Worker缓存静态资源

  6. CDN加速:静态资源走CDN


十五、Vue、React、Svelte框架对比(主观)

回答思路:根据实际使用情况回答,展现思考。

对比

  • React:生态最丰富,适合大型应用;需要手动优化(memo/useMemo)
  • Vue:上手简单,响应式自动依赖收集;官方生态完善
  • Svelte:编译时框架,无虚拟DOM,打包体积小;适合中小型项目

十六、React中为什么需要单标签(Fragment)

回答思路:React组件必须返回单个根元素。

原因:React的虚拟DOM diff算法基于树结构,每个组件返回的JSX必须是一个节点,否则无法进行diff比较。

解决方案

  • 使用<div>包裹(会多一层DOM)
  • 使用<React.Fragment><> </>(不产生额外DOM节点)
jsx 复制代码
// 错误:相邻JSX元素
return (
  <h1>Title</h1>
  <p>Content</p>
)

// 正确:用Fragment包裹
return (
  <>
    <h1>Title</h1>
    <p>Content</p>
  </>
)

十七、缓存机制

回答思路:从浏览器缓存、HTTP缓存、服务端缓存多维度说明。

浏览器缓存

  • localStorage/sessionStorage:键值对存储
  • IndexedDB:大量结构化数据

HTTP缓存

  • 强缓存Cache-Control: max-age=3600,缓存期间不发请求
  • 协商缓存ETag/If-None-MatchLast-Modified/If-Modified-Since,返回304

CDN缓存:边缘节点缓存静态资源

Service Worker缓存:拦截请求,返回缓存,支持离线


十八、HTTPS建立连接原理

回答思路:HTTPS = HTTP + TLS/SSL。

TLS握手流程

  1. Client Hello:客户端发送支持的加密套件、随机数
  2. Server Hello:服务端选择套件、发送服务端随机数 + 证书
  3. 验证证书:客户端验证证书有效性
  4. 密钥交换:客户端生成Pre-Master Secret,用公钥加密发送
  5. 生成会话密钥:双方用随机数 + Pre-Master生成对称密钥
  6. 加密通信:后续数据用会话密钥加密传输

关键点:非对称加密用于交换密钥,对称加密用于实际数据传输。


十九、HTTP版本区别

版本 特点 问题
HTTP/1.0 短连接,每次请求建立TCP 效率低
HTTP/1.1 长连接(Keep-Alive)、管道化 队头阻塞
HTTP/2 多路复用、头部压缩、服务器推送 仍受TCP队头阻塞影响
HTTP/3 基于UDP(QUIC协议),0-RTT连接 较新,兼容性待完善

多路复用:一个TCP连接上可以并发多个请求和响应。


二十、AI工具使用

回答思路:诚实回答使用过的工具。

常见工具

  • Copilot/Cursor:代码补全、生成
  • ChatGPT/Claude:调试问题、学习、代码审查
  • 通义灵码:国内替代
  • V0/bolt.new:UI生成

使用方式:生成重复性代码、调试错误、优化建议、学习新技术。


📚 知识点速查表

知识点 核心要点
Monorepo pnpm workspace/Nx/Turborepo,按功能拆分packages
双token access_token短期 + refresh_token长期,401自动刷新
分页错乱 刷新期间多个请求堆积导致数据错乱,解决方案:请求去重、禁用交互
上下文记忆 维护messages数组,超长时截断或摘要压缩
SSE vs WS 单向/双向、HTTP/WS协议、自动重连、AI场景选SSE
流式输出 减少焦虑、提前展示、可中断
埋点SDK 数据采集、批量上报、sendBeacon、性能监听
性能指标 FP/FCP/LCP/INP/CLS,LCP内容型最重要、INP交互型最重要
SPA白屏优化 懒加载、内联CSS、骨架屏、SSR、缓存、CDN
Fragment React需单根节点,Fragment不产生额外DOM
缓存机制 本地存储、HTTP缓存(强缓存/协商缓存)、CDN、Service Worker
HTTPS握手 非对称交换密钥,对称加密传输
HTTP版本 1.1长连接、2多路复用、3基于UDP

📌 最后一句:

腾讯这场一面,是一场"实战派"面试。从双token无感刷新的分页错乱bug,到AI对话的上下文记忆,从埋点SDK设计到HTTP版本演进,每一题都在考察你是否具备解决真实业务问题的能力。面试官不是在考八股,而是在看你的工程化思维和系统设计能力。能扛住这样的追问,说明你离"生产级"前端工程师又近了一步。

相关推荐
code_Bo2 小时前
kiro生成小程序商业案例
前端·微信小程序·小程序·云开发
yellowbuff2 小时前
为什么你的 0.01 秒倒计时看起来一卡一卡的?
前端
onebyte8bits2 小时前
NestJS 系列教程(十八):文件上传与对象存储架构(Multer + S3/OSS + 访问控制)
前端·架构·node.js·状态模式·nestjs
Ruihong2 小时前
放弃 Vue3 传统 <script>!我的 VuReact 编译器做了一次清醒取舍
前端·vue.js
weixin_456164832 小时前
vue3 父组件向子组件传参
前端
Beginner x_u2 小时前
前端八股整理|CSS|高频小题 01
前端·css·八股
UltraLAB-F2 小时前
GPU显存不足时的分配策略:渲染与仿真的显存争夺战解决方案
图像处理·算法·3d·ai·硬件架构
蜡台2 小时前
IDEA LiveTemplates Vue ElementUI
前端·vue.js·elementui·idea·livetemplates
E-cology2 小时前
【泛微低代码开发平台e-builder】使用HTML组件实现页面中部分区域自定义开发
前端·低代码·泛微·e-builder