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

温馨提示:市面上的面经鱼龙混杂,甄别真伪、把握时效,是我们对抗内卷最有效的武器。
面经原文内容
📍面试公司:腾讯PCG
🕐面试时间:近期
💻面试岗位:暑期前端一面
📝面试体验:一次问得更比两次多
❓面试问题:
- 自我介绍、优势
- 平常怎么接触 AI 编程(说了一下我在项目中的单人异步工作流,以及对 AI 参与到该工作流的思考,由于和 LLM 交流的产出要说起来太长被打断了)
- 手撕:O(log N) 乘法运算符(完全没思路,在一步步引导之下做了一个把乘法拆解成位运算和加法的逻辑)终于是撕出来了
- AI 手撕:初始化一个项目,做一个 iPod 转盘组件,转动一定角度就切换菜单高亮项(跑通以后问 AI 怎么实现的,然后我跑了一个 /doc 加注释,那 AI 都有注释了还问你干啥了)
- 怎么计算转盘转了多少角度(两个坐标求向量夹角、余弦定理);被引导之下说了极坐标(不是还问高中数学?)
- 了解哪些 CSS 布局方式(标准、浮动、定位、flex、grid)
- 说一下盒子模型(四个部分、box-sizing 属性)
- flex 有了解吗(三个属性)
- 闭包
- 让你手写编程语言,你会如何实现闭包(说了一下 C++ 的捕获列表)
- C 怎么处理函数栈(调用函数入栈+函数调用结束弹栈)(气氛逐渐诡异)
- 学校学过汇编语言吗(没,教过 riscv)
- 纯手写 HTTP 服务器怎么写(要求从 TCP 握手开始讲,降到一次请求-响应的链路,还说了请求/响应包体结构)
- 说一下 HTTPS 怎么实现的
- HTTPS 用到了对称加密还是非对称加密(都用了,非对称加密加密的是对称密钥)
- TypeScript 怎么实现枚举的(说了一下枚举值)
- 枚举类本质上是什么(不知道,我说我猜是对象,说猜对了)
- 怎么查枚举类有没有提供一个值(我说应该有原型方法,他说你可以查一下)
- 说一下实习公司干什么的(LLM 生成网页,然后说了本人工作)
- 介绍项目:公式编辑器
- 具体介绍测量和布局做了什么工作
- 一些字母的基线的特性
- 简单介绍日志记录器
- 反问(主要工作、实习生任务、对优秀人才的期望(聊起来愉快)、出结果时间)
来源:牛客网 期望去月球上班
💡 木木有话说(刷前先看)
这篇是期望去月球上班的面试,其实我觉得难度相对还好啊, 其实之前最早校招面试是比较喜欢问计算机基础、设计模式与算法的,这个面试官应该是有一定岁数了。
📝 腾讯PCG暑期前端一面·深度解析
🎯 面试整体画像
| 维度 | 特征 |
|---|---|
| 面试风格 | 广度覆盖型 + 底层追问型 + 实战引导型 |
| 难度评级 | ⭐⭐⭐(三星半-四星,跨学科+底层+算法+组件) |
| 考察重心 | 算法思维、计算机网络、编译原理基础、CSS/JS核心、项目深度 |
| 特殊之处 | 从高中数学(极坐标)问到汇编(riscv),再到HTTP协议细节,跨度极大 |
🔍 逐题深度解析
一、自我介绍与优势
回答思路:突出与岗位匹配的优势,控制在2分钟内。
结构建议:
- 我是谁(学校/年级/实习经历)
- 我的技术栈(擅长什么,深度如何)
- 我的亮点(项目/竞赛/开源/博客)
- 为什么适合这个岗位(结合PCG业务,如内容生态、社区)
二、平常怎么接触AI编程
回答思路:面试官打断了,说明要简洁。可以这样说:
"我在项目中形成了单人异步工作流:用Cursor/Copilot生成代码骨架,自己负责架构设计和核心逻辑审查。AI帮我处理重复性工作(表单、CRUD、单元测试),我专注难点攻关。同时我会让AI review我的代码,提出优化建议。"
三、手撕:O(log N) 乘法运算符
题目 :实现乘法运算,时间复杂度O(log N),不能用*运算符。
思路 :利用快速幂思想,把乘法拆解成加法。
javascript
function multiply(a, b) {
// 处理符号
const sign = (a < 0) ^ (b < 0) ? -1 : 1
let x = Math.abs(a)
let y = Math.abs(b)
let result = 0
while (y > 0) {
if (y & 1) { // 如果当前位是1
result += x
}
x <<= 1 // x左移一位(乘以2)
y >>= 1 // y右移一位(除以2)
}
return sign * result
}
原理 :把b拆成二进制,例如b = 13 = 1101₂,则a * 13 = a * 8 + a * 4 + a * 1。
四、AI手撕:iPod转盘组件
题目:实现一个iPod转盘,转动一定角度切换菜单高亮项。
核心难点:计算旋转角度、判断顺时针/逆时针、角度到菜单项的映射。
javascript
// 角度计算(利用atan2)
function getAngle(centerX, centerY, startX, startY, endX, endY) {
const startAngle = Math.atan2(startY - centerY, startX - centerX)
const endAngle = Math.atan2(endY - centerY, endX - centerX)
let delta = endAngle - startAngle
// 处理跨越-π到π边界
if (delta > Math.PI) delta -= 2 * Math.PI
if (delta < -Math.PI) delta += 2 * Math.PI
return delta // 弧度
}
映射逻辑:总角度变化 > 阈值(如30°)→ 切换高亮项;顺时针下一个,逆时针上一个。
五、怎么计算转盘转了多少角度
回答思路:用户回答"余弦定理"、"极坐标",基本正确。
方法:
- 记录鼠标/触摸起始点坐标
(x1, y1) - 记录当前点坐标
(x2, y2) - 以转盘中心
(cx, cy)为原点,计算两个向量的夹角- 向量1:
(x1-cx, y1-cy) - 向量2:
(x2-cx, y2-cy)
- 向量1:
- 夹角公式:
cosθ = (v1·v2) / (|v1|*|v2|),用Math.acos得弧度 - 用叉积 判断方向:
v1 × v2 > 0为逆时针
六、CSS布局方式
回答思路:列举主流布局模式。
- 标准流:块级元素垂直排列,行内元素水平排列
- 浮动布局 :
float: left/right,需清除浮动 - 定位布局 :
relative/absolute/fixed/sticky - Flex布局:一维布局,主轴/交叉轴
- Grid布局:二维布局,网格系统
七、盒子模型
回答思路:标准盒子 vs IE盒子。
- 组成部分 :
content+padding+border+margin - 标准盒子 :
width= content宽度 - IE盒子 (
box-sizing: border-box):width= content + padding + border
八、Flex属性
回答思路:至少说出三个核心属性。
- 容器属性 :
flex-direction(主轴方向)、justify-content(主轴对齐)、align-items(交叉轴对齐)、flex-wrap(换行) - 项目属性 :
flex-grow(放大比例)、flex-shrink(缩小比例)、flex-basis(基准尺寸)
九、闭包
回答思路:参考之前面经的闭包解析。
定义:函数可以访问其外部作用域的变量,即使外部函数已执行完毕。
用途:封装私有变量、函数工厂、回调保存状态。
危害:内存泄漏(DOM引用未释放)。
十、如何实现闭包(手写编程语言角度)
回答思路:用户回答"C++捕获列表",方向正确。
实现原理:
- 编译器检测到闭包(Lambda),创建一个匿名结构体/类
- 结构体包含:
- 函数指针(指向实际代码)
- 捕获的变量(值捕获或引用捕获)
- 调用时,通过结构体实例访问捕获的变量
cpp
// C++ Lambda底层示意
struct Closure {
int captured;
void operator()(int param) const {
// 函数体,可访问captured和param
}
};
十一、C怎么处理函数栈
回答思路 :调用函数时,CPU将返回地址、参数、局部变量压入调用栈。
流程:
- 调用前:调用方将参数压栈
- 调用时:压入返回地址,跳转到函数
- 函数内:分配局部变量空间,执行
- 返回时:恢复栈指针,弹出返回地址,跳转回去
十二、汇编语言
回答思路:用户学过RISC-V,可以简单说明。
汇编是机器码的文本表示,一条指令对应一个CPU操作。RISC-V是精简指令集,指令固定32位,有32个通用寄存器。
十三、纯手写HTTP服务器(从TCP握手开始)
回答思路:考察网络协议栈理解深度。
完整链路:
- TCP三次握手:客户端发SYN → 服务端回SYN+ACK → 客户端发ACK
- 建立连接:进入ESTABLISHED状态
- 客户端发送HTTP请求 :
GET /index.html HTTP/1.1\r\nHost: ...\r\n\r\n - 服务端解析请求:读取请求行、请求头、空行、body
- 服务端构造响应 :
HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html>... - 服务端发送响应:通过socket send
- 四次挥手关闭连接
HTTP包体结构:
- 请求行/状态行
- 头部(key: value)
- 空行(
\r\n\r\n) - 消息体(可选)
十四、HTTPS怎么实现的
回答思路:HTTPS = HTTP + TLS/SSL,在TCP之上、HTTP之下加一层安全协议。
握手流程:
- 客户端发送
Client Hello(支持的加密套件、随机数) - 服务端回复
Server Hello(选择套件、服务端随机数)+ 证书 - 客户端验证证书,生成
Pre-Master Secret,用公钥加密发送 - 双方用随机数 + Pre-Master生成会话密钥(对称密钥)
- 后续通信使用对称加密
十五、HTTPS用了对称还是非对称加密
回答思路 :都用。
- 非对称加密:加密Pre-Master Secret,交换对称密钥
- 对称加密:加密实际传输的HTTP数据,效率高
十六、TypeScript怎么实现枚举
回答思路 :TS枚举编译成JS后,是对象(双向映射)。
typescript
enum Color { Red, Green, Blue }
编译成:
javascript
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
结果对象:
javascript
{ 0: 'Red', 1: 'Green', 2: 'Blue', Red: 0, Green: 1, Blue: 2 }
十七、枚举类本质上是什么
回答思路 :用户猜"对象",正确。枚举本质上是一个普通对象,同时支持正向和反向映射。
十八、怎么查枚举类有没有提供一个值
回答思路 :可以用in操作符或hasOwnProperty。
typescript
enum Color { Red, Green, Blue }
// 检查值是否存在
const value = 1
if (value in Color) { // true,因为Color[1] = 'Green'
console.log(Color[value])
}
// 检查键是否存在
const key = 'Red'
if (Color.hasOwnProperty(key)) { // true
console.log(Color[key])
}
十九、实习公司:LLM生成网页
回答思路:简要说明工作内容,突出你的贡献。
二十、项目:公式编辑器
回答思路:这是复杂前端项目,重点讲技术难点。
核心能力:
- 公式解析(LaTeX → AST)
- 渲染(Canvas或HTML+CSS)
- 光标定位、选区管理
- 键盘输入映射
二十一、测量和布局的具体工作
回答思路:公式编辑器中,每个字符/符号有不同尺寸和基线。
测量 :Canvas的measureText()获取文本宽度;对于复杂符号,需预先定义尺寸元数据。
布局:根据公式结构(分式、根号、上下标)递归计算每个子元素的位置。
二十二、字母基线的特性
回答思路:不同字母(如'a'和'g')的基线对齐方式不同。
基线类型:
alphabetic baseline:字母底部('a', 'x')hanging baseline:上部('f', 'ö')ideographic baseline:中日韩字符底部
公式编辑器需精确处理基线,保证公式视觉对齐。
二十三、日志记录器
回答思路:简单说明设计。
功能:分级日志(debug/info/warn/error)、可配置输出(控制台/文件)、性能开销小。
javascript
class Logger {
constructor(level = 'info') { ... }
debug(...args) { if (this.shouldLog('debug')) console.debug(...args) }
// ...
}
二十四、反问环节
回答思路:用户问了三个高质量问题。
- 主要工作:了解团队业务,判断是否感兴趣
- 实习生任务:了解成长空间、导师制、能否接触核心
- 对优秀人才的期望:了解团队价值观,判断匹配度
加分反问:
- "您觉得刚才的面试中,我在哪些方面还需要加强?"
- "团队目前面临的最大技术挑战是什么?"
📚 知识点速查表
| 知识点 | 核心要点 |
|---|---|
| O(log N)乘法 | 二进制拆解、快速幂思想、位运算+加法 |
| 角度计算 | atan2、向量夹角、叉积判方向 |
| CSS布局 | 标准/浮动/定位/flex/grid |
| 盒子模型 | content+padding+border+margin,box-sizing |
| Flex | direction/justify/align/wrap,grow/shrink/basis |
| 闭包实现 | 匿名结构体+捕获列表,存储函数指针+变量 |
| C函数栈 | 压参→压返回地址→分配局部变量→弹栈 |
| HTTP服务器 | TCP握手→请求解析→响应构造→挥手 |
| HTTPS | TLS握手→非对称交换密钥→对称加密数据 |
| TS枚举 | 编译成对象,双向映射,用in/hasOwnProperty查 |
| 公式编辑器 | 解析→测量→布局→渲染,基线对齐 |
| 日志记录器 | 分级、可配置、低开销 |
📌 最后一句:
腾讯PCG这场一面,是一次对计算机基础的"大阅兵"。从O(log N)乘法到HTTP协议细节,从闭包底层实现到TS枚举本质,面试官层层深入,考察的不是你会不会用框架,而是你对计算机体系的理解有多深 。用户虽然被问得"气氛逐渐诡异",但能走到反问环节,说明硬核基础仍是通关的关键。框架半年一换,但算法、网络、编译原理,永远是程序员的内功。