Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/面试/面经

8腾讯-前端-全部

13 分钟阅读 · Note

目录树 578 篇

          • 0 面试技巧&HR面⬇️
          • 1磐松资产-前端实习-一面
          • 2字节跳动-豆包前端实习-全部
          • 3百度-前端实习面试-一面
          • 5光庭-前端实习-一面
          • 6懂车帝-前端实习-一面
          • 7字节-抖音团购-全部
          • 8腾讯-前端-全部
          • 9字节&美团-笔试
          • 10 美团-一面
          • 11 B站-一面
          • 12 腾讯-一面-企业微信团队
          • 13 腾讯-一面-腾讯金融科技
          • 14 腾讯-二面-腾讯金融科技
          • 15 美团-一面-核心本地商业
          • 16 斑马智行-全部
          • 17 字节-一面-飞书
          • 18 美团-二面-核心本地商业
          • 19 心影随形-全部
          • 20 thunderbit-全部
          • 21 converge ai-全部
          • 22 字节-国际化广告创意与品牌
        • 可投递企业
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗0 面试技巧&HR面⬇️同一路径↗10 美团-一面同一路径↗11 B站-一面同一路径↗12 腾讯-一面-企业微信团队同一路径↗13 腾讯-一面-腾讯金融科技同一路径↗14 腾讯-二面-腾讯金融科技同一路径
  • 8腾讯-前端-全部

8腾讯-前端-全部

> Last Format Time:6/12/2026 21:03:57

AI面

提问:

  • webpack的热更新机制的作用与原理
  • 一个应用在H5与小程序是怎么开发的
  • 301与302的网络协议代表了什么,他们在seo优化的过程中起到了什么作用
  • 浏览器的内存优化技巧,爆了内存如何排查

靠,这些问题我都不太会啊,倒霉了孩子们

这四个问题覆盖了工程化、跨端开发、网络协议和性能优化,确实是前端面试的高频考点。下面我会逐个拆解,力求让你不仅知道"是什么",更理解"为什么"和"怎么做"。


webpack 的热更新机制(HMR)的作用与原理

作用

HMR(Hot Module Replacement)让你在修改代码后,无需刷新整个页面,就能把新模块替换掉运行时的旧模块,同时保留应用当前状态。

如果没有 HMR,每次改代码保存后页面都会全量刷新,你填的表单、对话框状态、当前路由等全都会丢失,开发调试效率极低。

核心原理(简化链路)

整个 HMR 过程涉及四个角色:

  • webpack 编译器 + watcher:监听文件变更,编译出更新文件
  • webpack-dev-server / webpack-dev-middleware:作为服务端,通过 WebSocket 与浏览器连接
  • HMR Runtime(浏览器端注入的代码):接收更新通知,请求更新模块并交给模块热替换逻辑
  • 模块系统(module.hot):各模块可以自行决定如何接受和替换自己

整体流程:

  1. 启动阶段
    webpack-dev-server 启动时,会通过 webpack-dev-middleware 在内存中编译打包,同时注入 HMR 客户端代码到打包产物。然后开启一个 WebSocket 长连接(路径通常是 /ws)。

  2. 文件监听
    webpack 开启文件系统 watcher。当文件保存修改后,webpack 重新编译只变更的模块,生成两个增量文件:

    • [hash].hot-update.json(描述哪些 chunk 和模块更新了)
    • [hash].hot-update.js(模块的新代码)
  3. 推送 hash 给浏览器
    编译完成后,webpack 通过 WebSocket 向浏览器发送一个 hash 消息,告知本次编译的最新 hash 值。

  4. 浏览器请求热更新文件
    HMR Runtime 收到 hash 后,发起 AJAX 请求 [hash].hot-update.json,获取需要更新的 chunk 和模块 ID 列表。然后通过动态<script>标签加载对应的 [hash].hot-update.js 获取新模块代码。

  5. 热替换检查(关键)
    得到新模块后,Runtime 从入口模块开始,沿着模块依赖树向上冒泡询问:"你是否接受这个模块的更新?"。每个模块可以通过 module.hot.accept() 声明自己能处理某个依赖的更新:

    if (module.hot) {
      module.hot.accept('./someModule', () => {
        // 执行一些重新渲染逻辑,保留状态
      })
    }
    

    如果一直冒泡到根模块还没有被 accept,就会降级为全量刷新(window.location.reload)。如果某一级模块 accept 了,它会执行注册的回调,重新获取该模块的导出,更新相关变量,从而在不刷新页面的情况下完成局部替换。

  6. 状态保持
    React、Vue 等框架的 loader 已内置 HMR 处理逻辑。例如 vue-loader 会为组件注入 hot.accept,保存组件的 render 和 data,替换后重用原有实例状态,实现"无感"更新。

一句话总结:WebSocket 推送编译 hash -> 拉取增量更新文件 -> 模块冒泡接受热替换 -> 框架自行实现状态保留。


一个应用在 H5 与小程序是怎么开发的

这个问题考察的是你对跨端开发方案的理解以及原生开发模式的认知。

方案一:同一套代码,跨端输出(主流)

现在大部分团队使用跨端框架来同时适配 H5 和小程序,主要有:

  • Taro(京东):React/Vue 语法,编译到微信、支付宝、H5 等多个端
  • uni-app(DCloud):Vue 语法,一套代码编 10+ 端,包括 H5、各种小程序和原生 App
  • Remax:基于 React,直接使用小程序原生 API,运行时方案

开发模式: 你使用框架提供的 DSL(类 React/Vue 组件),框架通过编译器或运行时适配,将代码转为各平台底层原生调用。

  • 编译时:将视图层的 <View>、<Text> 编译成小程序的 wxml 模板或 H5 的 dom 标签,逻辑代码打包到对应平台生命周期(如小程序的 Page/Component 或 H5 的 Vue 实例)。
  • 运行时:框架在小程序环境模拟 DOM/BOM 操作,让 React/Vue 能跑起来;H5 端则直接使用标准 DOM。

优劣势:一套代码维护成本低,但复杂场景下可能出现平台兼容问题,需要编写条件编译代码。

方案二:H5 与小程序独立开发

  • H5 开发:通常是一个单页应用(SPA),用 Vue/React + 路由 + axios 调接口,运行在浏览器和手机浏览器内。需要注意移动端适配(rem/vw)、手势、性能优化。
  • 小程序开发:使用各平台自家的开发工具(如微信开发者工具),编写 WXML + WXSS + JS。有自己的生命周期(onLoad, onShow, onHide),网络请求用 wx.request,组件体系、数据绑定模式(setData 更新)都与 H5 完全不同。

如果各自独立开发,需要维护两套代码和业务逻辑,仅共享 API 接口和部分通用工具库。优点是原生性能最好、功能无封装限制,缺点是人力成本高。

实际开发流程(以 Taro 为例)

  1. 初始化 Taro 项目,选择模版(React/Vue)
  2. 编写页面和组件,使用 Taro 提供的跨平台组件(View, Text, Image等)
  3. 调用 Taro 统一 API(如 Taro.request, Taro.navigateTo),它会自动抹平各端差异
  4. 配置 app.config.js,页面路由和窗口表现
  5. 运行 npm run dev:h5 开发调试 H5,npm run dev:weapp 预览小程序
  6. 构建发布:npm run build:h5 输出静态资源部署到服务器,npm run build:weapp 输出小程序代码包上传

核心差异开发者需要注意:

  • 渲染层:小程序是双线程架构,渲染层 WXML 和逻辑层 JS 隔离,操作 DOM 能力受限
  • 包大小限制:小程序有主包、分包体积限制,需要优化分包策略
  • 能力限制:小程序无 Cookie,使用自己的登录体系和缓存 API

301 与 302 网络协议含义及在 SEO 优化中的作用

协议含义

两者都是 HTTP 状态码,表示重定向。

  • 301 Moved Permanently(永久重定向):请求的资源已被永久移动到新 URI,搜索引擎和浏览器应该用新 URI 替代旧 URI 进行索引和访问。后续请求直接请求新地址。
  • 302 Found(临时重定向,旧称 Moved Temporarily):资源只是暂时性的转移,以后可能还会变回去,客户端应继续使用原有 URI 进行请求。

在 SEO 优化中的重要作用

搜索引擎传递权重(link juice)的方式不同

  • 301:会将原页面的大部分权重(PageRank)传递到目标新页面。搜索引擎会删除旧 URL 并索引新 URL。大多数情况下,权重传递效率能达到 90% 以上。
  • 302:权重通常不传递或传递极少。搜索引擎认为这只是临时跳转,所以继续索引旧 URL,不会将排名信号赋予新 URL。

常见 SEO 场景

场景应使用原因
网站域名变更301将旧域名的权重和收录平滑迁移到新域名
HTTP 升级到 HTTPS301将带 www/不带 www 统一到一个规范域名;将 HTTP 权重集中到 HTTPS
页面永久删除,替代页有效301旧页面重定向到内容最相关的现有页面,保留流量和排名
季节性促销页或临时活动302促销结束会恢复原页面,索引仍留在原 URL
网址重构、合并301旧路径永久映射到新路径,帮助搜索引擎更新索引

使用错误的严重后果

  • 如果网站迁移时错误使用 302,搜索引擎可能继续索引旧域名,新域名无法获得排名,导致流量归零。
  • 曾经有个经典案例:某大站全站 302 跳转到新域名,搜索引擎把 302 当成"短期的",没有转移任何权重,造成新域名长期无索引无排名,最终改为 301 才恢复。

技术实现注意 服务器端配置:

# Nginx 301 永久重定向
server {
  listen 80;
  server_name old-site.com;
  return 301 http://new-site.com$request_uri;
}

# Nginx 302 临时重定向
server {
  ...
  return 302 /special-offer.html /spring-sale.html;
}

浏览器的内存优化技巧,爆了内存如何排查

浏览器内存优化技巧

a) 减少内存占用

  • 及时解除引用:对于不再使用的对象、定时器、监听器,设置为 null。特别是全局变量和闭包引用要倍加小心。
  • 使用 WeakMap / WeakSet:当 key 是对象且希望该对象被垃圾回收时不受此集合影响,避免内存泄漏。
  • DOM 清理:移除 DOM 节点时,也要解绑相关事件监听,避免游离 DOM 引用导致无法 GC。现代浏览器有一定处理,但手动清理更可靠。
  • 虚拟滚动(windowing):长列表只渲染可视区域,回收屏幕外 DOM 节点和其状态,极大降低 DOM 节点数量和内存。
  • 图片和媒体优化:图片懒加载、使用合适尺寸和格式(WebP),用 URL.revokeObjectURL() 释放 blob 内存。
  • 变量局部化:避免挂载大数据到大对象或全局作用域,函数内用完即释放。
  • 组件销毁清理:Vue/React 生命周期中清除定时器、取消网络请求、销毁第三方库实例。

b) 防止内存泄漏的编码习惯

  • 移除事件监听:element.removeEventListener 或在框架销毁钩子中解绑。
  • 清理定时器:clearInterval / clearTimeout。
  • 避免循环引用:特别留意 DOM 和 JS 对象互相引用,现代浏览器不会因循环引用泄漏,但旧 IE 会。
  • 处理闭包:小心在闭包中持有大对象或 DOM 引用。

c) 利用工具减轻压力

  • Web Worker:将复杂计算移到 Worker,避免主线程阻塞和内存压力堆积在一起。
  • 分片处理:大数组分批次处理,使用 requestAnimationFrame 或 requestIdleCallback 让出主线程,让 GC 有机会运行。

内存暴涨如何排查

https://www.bilibili.com/video/BV1GQ4y1G7so/?spm_id_from=333.337.search-card.all.click&vd_source=47c9acd507be61251cd2bb730416395c

在性能面板中勾选内存进行录制,然后进行一些操作,看到折线图回落即为回收了 ![Pasted image 20260603215026](../../../_assets/f5deb89-Pasted image 20260603215026.png)

1. 确认现象与场景

  • 页面卡顿甚至崩溃,JS heap size 逐渐增大或突然飙升,标签页内存占用持续增长。
  • 重现步骤:反复打开/关闭页面或执行某些操作后内存不下降。

2. 使用 Chrome DevTools 定位

  • Performance 面板:记录页面运行过程,勾选 Memory 选项,观察内存曲线是否呈阶梯式上升并且 GC 后不下降,即存在内存泄漏。
  • Memory 面板(堆快照,Heap Snapshot)
    • 发生泄漏操作前拍一个快照,操作后(如打开弹窗再关闭)再拍一个,查看"Comparison"(对比)视图。
    • 按 # Delta(对象数量差异)排序,找出新增且未释放的对象。
    • 通过 Retainers(引用追溯)查看是谁让这些对象无法被回收,通常会发现闭包、事件监听器、全局变量等持有引用。
  • Performance Monitor 面板:实时观察 JS heap size、Documents、Nodes、Listeners 等指标,操作时看哪些数值只增不减。

3. 具体泄漏模式排查

  • 游离 DOM 节点(Detached DOM):从 JS 栈还可以访问到已从页面上移除的 DOM 元素。快照中搜索 "Detached",判断是否有变量仍引用它们。
  • 闭包泄漏:在 Retainers 中寻找 context 或 closure,看看是否捕获了大对象。
  • 定时器未清:检查 setInterval 是否回调持有组件引用且未被清除。
  • 事件监听器持续增加:检查 Memory 面板中 Event Listeners 是否每次操作都新增。

4. 复现与修复

  • 定位到具体变量和代码位置后,在合适时机(如组件卸载)清空引用、移除监听、销毁定时器等。
  • 修复后重新跑快照对比验证。

例子:React 组件内存泄漏

// 错误:定时器引用组件实例,组件卸载后定时器依然运行
useEffect(() => {
  const id = setInterval(() => {
    setCount(c => c + 1);
  }, 1000);
  // 缺少清理
}, []);

// 正确
useEffect(() => {
  const id = setInterval(() => {
    setCount(c => c + 1);
  }, 1000);
  return () => clearInterval(id); // 清理
}, []);

优化技巧延伸(V8 垃圾回收机制简知)

V8 采用分代回收:新生代(存活时间短)用 Scavenge 算法,快速回收;老生代用标记-清除 & 标记-整理。了解这一点能帮助你写出更利于 GC 的代码,如避免频繁触发分配,减少"内存碎片"。


如果你需要,我可以把其中一个主题深入到底层源码级,或者提供具体的模拟面试追问和回答。


一面

完蛋了,都不会啊,这个肯定是凉了。。。

提问

  • 树状导出,虚拟滚动的过程是怎么做的,展开后高度发生了变化你是怎么做的,如果一开始有个固定的高度,你点开后的高度变化了,你又是怎么做的,为什么不去做分页,如果做分页应该怎么搞,通过样式计算出来的节点的与真实的结点可能是不同的,这里你又该如何处理呢?

  • 高危bug,这个由于有提前的准备,所以不虚。如果你的同事在搞这个问题的时候,除了代码逻辑与后端的校验,你又应该怎么去约束呢?(面试官的回答是,TS)

  • 滑动流畅丝滑是怎么做的,你的事件处理机制是什么搞得,滑动和点击出现冲突会怎么样,你的视频没有去做卸载,你的内存泄漏怎么去做呢,怎么定位呢?怎么去更新视频呢?

这是简历中写的,需要关注的点在于导出,定位报错问题,高危bug。所以说,简历不要给AI乱搞啊!混蛋!

  • 负责火山账号管理模块体验优化,使用 React Hooks 与 TypeScript 重构列表筛选、搜索组件,设计并实现权限预览面板;累计修复多个样式与交互缺陷,优化后模块相关缺陷反馈显著下降。就是列变中去搜索的功能,筛选就是加个默认值

  • 负责 Quota 配额管理核心模块线上稳定性保障,定位并修复数据渲染不一致、导出失败、审批流状态异常等 4 个高优 Bug;引入前端分页导出方案,解决大数据量下浏览器卡顿问题,保障财务结算准确率。

  • 参与前端稳定性治理,为审批、配额申请等关键路径接入监控埋点,实现可用性监控能力提升;配合搭建的AI Skill与MCP工具分析线上错误日志,精准定位并闭环修复高频 JS 错误,相关页面错误率明显下降。

  • 参与项目日常维护,统计常用与不常用组件,在vibe coding的环境下精简冗余代码,在 Monorepo 架构下完成全流程开发,严格遵循团队 Git-Flow 与 MR 规范;累计提交 17 个已合并 MR。

编程

  • 乱序数组的最长有序子序列(动态规划)
  • 最长不重复子串(双指针)

反问

  • 项目组目前在与vibe coding做什么
  • 在这个AI至上的环境,没有经验的程序员该何去何从 硬着头皮上,在不急着去交付的需求,可以自己去写

反思

这次的面试告诉我们一个道理,前端不是不考算法的,越是老牌的大厂,就越是会考察。而且你一旦实习过,就会问你有关实习的东西,不会特别的去考察你的基础了,一般都是实习中的问题。也不是啊,他们都是随便考的,才不会管你呢


二面