前言
大家好,我是木斯佳。
在这个春节假期,当大家都在谈论返乡、团圆与休息时,作为一名技术人,我的思考却不由自主地转向了行业的「冬」与「春」。
相信很多人都感受到了,在AI浪潮的席卷之下,前端领域的门槛在变高,纯粹的"增删改查"岗位正在肉眼可见地减少。曾经热闹非凡的面经分享,如今也沉寂了许多。但我们都知道,市场的潮水退去,留下的才是真正在踏实准备、努力沉淀的人。学习的需求,从未消失,只是变得更加务实和深入。
正值春节,也是复盘与规划的好时机。结合CSDN这次「春节代码贺新年」活动所提倡的"用技术视角记录春节、复盘成长",我决定在这个假期持续更新专栏,帮助年后参加春招的同学。
这个专栏的初衷很简单:拒绝过时的、流水线式的PDF引流贴,专注于收集和整理当下最新、最真实的前端面试资料。
我会在每一份面经和八股文的基础上,尝试从面试官的角度去拆解问题背后的逻辑,而不仅仅是提供一份静态的背诵答案。无论你是校招还是社招,目标是中大厂还是新兴团队,只要是真实发生、有价值的面试经历,我都会在这个专栏里为你沉淀下来。
温馨提示:市面上的面经鱼龙混杂,甄别真伪、把握时效,是我们对抗内卷最有效的武器。
在这个假期,让我们一起充电,为下一个技术春天做好准备。

面经原文内容
面试公司:腾讯云
🕐面试时间: 12 月 26 日
💻面试岗位:前端实习
❓面试问题:
- 1.自我介绍
- 2.项目和实习经历介绍 技术难点
- 3.项目相关问题(语音合成的应用场景,知
识库检索) - 4.SSE可靠吗?SSE中断的原因?怎么解决这个问题?是否有实际运用并且具体了解过?
根据会话ID - 5.如何判定RAG检索效率与参数?判定标准是什么?
- 6.实习公司项目为什么要进行状态管理优化?
- 7.学习前端的时长 都学了什么 路径 怎么学
- 8.手写todolist(增删完成) 基于react
来源: 牛客网 雾泊屿by
📝 腾讯云前端实习一面·面经深度解析
🎯 面试整体画像
| 维度 | 特征 |
|---|---|
| 部门定位 | 腾讯云 - 云计算基础设施部门 |
| 面试风格 | 项目深潜型 + 工程实践型 + 场景追问型 |
| 难度评级 | ⭐⭐⭐⭐(四星,偏重实战) |
| 考察重心 | SSE可靠性、RAG检索、状态管理、项目深度 |
| 典型腾讯风格 | 务实、注重落地、喜欢问"为什么这样选" |
面试特点分析:
| 特点 | 说明 |
|---|---|
| 高可靠性要求 | 云产品不能崩,SSE必须稳定 |
| 复杂状态管理 | 控制台状态复杂,必须用好状态管理 |
| 性能敏感 | 大数据量展示、实时更新 |
| 工程化程度高 | 代码规范、CI/CD、监控完备 |
🔌 SSE深度解析·可靠性问题
问题4:SSE可靠吗?SSE中断的原因?怎么解决?
✅ 完整答案结构:
1. SSE是什么?
javascript
// Server-Sent Events - 服务器推送技术
const eventSource = new EventSource('/api/stream');
eventSource.onmessage = (e) => {
console.log('收到消息:', e.data);
};
eventSource.onerror = (e) => {
console.log('连接错误', e);
};
2. SSE可靠吗?
✅ 优点:
- 基于HTTP,兼容性好
- 自动重连(内置)
- 轻量,比WebSocket简单
❌ 缺点:
- 单向(只能服务器→客户端)
- 连接数限制(浏览器一般6个)
- 可能被代理/防火墙中断
3. SSE中断的原因
| 中断原因 | 说明 | 发生频率 |
|---|---|---|
| 网络波动 | WiFi切换、4G/5G切换 | 高 |
| 超时 | 代理服务器超时断开 | 中 |
| 服务端重启 | 发布、故障 | 低 |
| 浏览器限制 | 后台标签页限流 | 中 |
4. 解决方案(面试官追问的)
javascript
// 方案1:利用内置重连
const eventSource = new EventSource('/api/stream', {
withCredentials: true // 带cookie
});
// SSE默认会重连,但重连间隔不可控
// 方案2:手动重连(更可靠)
class ReliableEventSource {
constructor(url, options = {}) {
this.url = url;
this.options = options;
this.reconnectInterval = options.reconnectInterval || 3000;
this.maxRetries = options.maxRetries || 10;
this.retryCount = 0;
this.connect();
}
connect() {
this.es = new EventSource(this.url);
this.es.onopen = () => {
console.log('SSE连接成功');
this.retryCount = 0; // 重置重试计数
};
this.es.onmessage = (e) => {
// 处理消息
this.options.onMessage?.(e);
};
this.es.onerror = (e) => {
this.es.close();
if (this.retryCount < this.maxRetries) {
this.retryCount++;
console.log(`尝试重连...第${this.retryCount}次`);
setTimeout(() => this.connect(), this.reconnectInterval);
} else {
console.error('SSE重连失败');
this.options.onMaxRetries?.();
}
};
}
close() {
this.es.close();
}
}
5. 根据会话ID(面试官提示)
javascript
// 带会话ID的SSE
const sessionId = localStorage.getItem('sessionId');
const es = new EventSource(`/api/stream?sessionId=${sessionId}`);
// 重连时带上相同的sessionId,服务端可以恢复上下文
💡 面经关键点:
面试官问"SSE可靠吗"不是要你回答"可靠"或"不可靠",而是让你分析不同场景下的可靠性,以及怎么应对
📊 RAG检索效率与参数·深度解析
问题5:如何判定RAG检索效率与参数?判定标准是什么?
✅ 完整答案结构:
1. 什么是RAG?
RAG = Retrieval-Augmented Generation(检索增强生成)
用户问题
↓
【检索阶段】从知识库检索相关文档
↓
【增强阶段】问题 + 检索文档 → 大模型
↓
【生成阶段】模型基于上下文生成答案
2. 检索效率指标
| 指标 | 说明 | 理想值 |
|---|---|---|
| 检索延迟 | 从查询到返回文档的时间 | <200ms |
| QPS | 每秒查询数 | 越高越好 |
| 召回率 | 相关文档被召回的比例 | >90% |
| 精确率 | 召回文档中相关比例 | >80% |
| MRR | 平均倒数排名 | >0.8 |
3. 关键参数调优
javascript
// 分块大小(chunk size)
- 太小:上下文不完整
- 太大:噪声多、检索慢
- 经验值:256-512 tokens
// 重叠大小(overlap)
- 保证边界信息不丢失
- 经验值:10-20%
// Top-K 数量
- 返回多少个相关文档
- 太少:信息不足
- 太多:噪声多、成本高
- 经验值:3-5个
// 相似度阈值
- 低于阈值的文档不返回
- 经验值:0.7-0.8
4. 实际测试方法
javascript
// A/B测试设计
测试集:1000个标准问答对
对照组:旧RAG参数
实验组:新参数
评估指标:
- 答案准确率(人工/LLM评判)
- 检索延迟(P95)
- 用户满意度(反馈打分)
// 离线评估
1. 准备测试集(问题 + 标准答案 + 相关文档)
2. 运行检索,计算召回率/精确率
3. 生成答案,与标准答案对比(BLEU/ROUGE)
💡 面试官考察点:
这个问题不是要你成为RAG专家,而是看你有没有工程思维------知道怎么衡量、怎么优化、怎么验证
🏗️ 状态管理优化·真实场景
问题6:实习公司项目为什么要进行状态管理优化?
✅ 系统化回答:
1. 问题诊断(为什么需要优化)
javascript
// 场景1:props drilling
<App>
<Dashboard>
<Panel>
<Chart>
<Button /> // 要用到user数据,需要传5层
</Chart>
</Panel>
</Dashboard>
</App>
// 场景2:多处共享数据
// 用户信息、主题配置、权限数据被20+组件使用
// 场景3:状态逻辑复用
// 多个组件有相似的loading/error/data逻辑
2. 优化方案对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Context | 低频更新、小范围 | 简单、内置 | 性能问题、调试难 |
| Redux | 复杂状态、大项目 | 可预测、中间件 | 样板代码多 |
| Zustand | 中等项目 | 简单、灵活 | 生态较小 |
| Jotai | 原子状态 | 精细控制 | 学习成本 |
3. 优化前后对比
javascript
// 优化前:组件内维护复杂状态
const ChartComponent = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetchData()
.then(data => setData(data))
.catch(setError)
.finally(() => setLoading(false));
}, []);
// 同样的逻辑在多个组件重复
};
// 优化后:抽取为自定义hook + 状态管理
const useChartData = (chartId) => {
return useQuery(['chart', chartId], fetchChartData);
};
const ChartComponent = ({ chartId }) => {
const { data, isLoading, error } = useChartData(chartId);
// UI逻辑更纯粹
};
4. 优化效果(要量化!)
javascript
// 代码量减少:40%(从2000行到1200行)
// 渲染次数减少:50%(避免不必要的重绘)
// Bug率下降:30%(状态逻辑统一)
// 开发效率提升:新功能开发时间缩短40%
💡 面经关键点:
不要只说"用了Redux",要说为什么用、解决了什么问题、带来了什么收益
🗣️ 语音合成应用场景·项目深挖
问题3:语音合成的应用场景
✅ 全面总结:
场景1:无障碍辅助
javascript
- 视障用户:屏幕阅读器 + 语音播报
- 阅读障碍:文字转语音辅助阅读
- 老年人:大字体 + 语音反馈
场景2:内容消费
javascript
- 资讯App:文章语音播报(开车时听)
- 阅读App:有声书自动生成
- 社交媒体:帖子语音播放
场景3:交互反馈
javascript
- 智能客服:语音回复
- 导航App:实时语音指引
- 学习App:发音示范
场景4:效率工具
javascript
- 会议记录:转文字 + 文字转语音
- 代码阅读:代码语音播报(Debug用)
- 多任务处理:边做事边"听"文档
技术实现要点:
javascript
// Web Speech API
const utterance = new SpeechSynthesisUtterance('你好');
utterance.lang = 'zh-CN';
utterance.rate = 1.0; // 语速
utterance.pitch = 1.0; // 音调
window.speechSynthesis.speak(utterance);
// 高级:阿里云/腾讯云语音合成
// 需要后端集成,支持更多音色、情感
📝 TodoList手写·React基础
问题8:手写TodoList(增删完成)
✅ 完整实现:
jsx
import React, { useState } from 'react';
const TodoList = () => {
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
// 添加待办
const addTodo = () => {
if (!inputValue.trim()) return;
const newTodo = {
id: Date.now(),
text: inputValue,
completed: false,
createdAt: new Date().toISOString()
};
setTodos([...todos, newTodo]);
setInputValue('');
};
// 删除待办
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
// 切换完成状态
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
));
};
// 统计
const activeCount = todos.filter(t => !t.completed).length;
const completedCount = todos.length - activeCount;
return (
<div className="todo-container">
<h1>Todo List</h1>
{/* 输入框 */}
<div className="input-area">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder="输入待办事项..."
/>
<button onClick={addTodo}>添加</button>
</div>
{/* 统计信息 */}
<div className="stats">
<span>全部:{todos.length}</span>
<span>进行中:{activeCount}</span>
<span>已完成:{completedCount}</span>
</div>
{/* 待办列表 */}
<ul className="todo-list">
{todos.map(todo => (
<li
key={todo.id}
className={todo.completed ? 'completed' : ''}
>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span>{todo.text}</span>
<button onClick={() => deleteTodo(todo.id)}>删除</button>
</li>
))}
</ul>
{/* 空状态 */}
{todos.length === 0 && (
<div className="empty-state">
暂无待办,添加一条吧~
</div>
)}
</div>
);
};
export default TodoList;
样式示例:
css
.todo-container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
}
.input-area {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.input-area input {
flex: 1;
padding: 8px;
}
.todo-list {
list-style: none;
padding: 0;
}
.todo-list li {
display: flex;
align-items: center;
gap: 10px;
padding: 8px;
border-bottom: 1px solid #eee;
}
.todo-list li.completed span {
text-decoration: line-through;
color: #999;
}
.stats {
display: flex;
gap: 20px;
margin-bottom: 20px;
font-size: 14px;
color: #666;
}
.empty-state {
text-align: center;
color: #999;
padding: 40px;
}
面试官可能的追问:
追问1:如何添加编辑功能?
jsx
// 添加编辑状态
const [editingId, setEditingId] = useState(null);
const [editText, setEditText] = useState('');
// 双击进入编辑模式
const startEdit = (todo) => {
setEditingId(todo.id);
setEditText(todo.text);
};
// 保存编辑
const saveEdit = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, text: editText } : todo
));
setEditingId(null);
};
追问2:如何实现本地存储?
jsx
useEffect(() => {
const saved = localStorage.getItem('todos');
if (saved) {
setTodos(JSON.parse(saved));
}
}, []);
useEffect(() => {
localStorage.setItem('todos', JSON.stringify(todos));
}, [todos]);
追问3:如何优化性能?
jsx
// 使用useCallback避免函数重复创建
const addTodo = useCallback(() => {
// ...
}, [inputValue]);
// 使用useMemo避免重复计算
const stats = useMemo(() => ({
total: todos.length,
active: todos.filter(t => !t.completed).length,
completed: todos.filter(t => t.completed).length
}), [todos]);
📚 学习路径
问题7:学习前端的时长、学了什么、路径、怎么学
💡 面试官想听的不是时间线,而是:
- 有没有方法(不只是看视频)
- 有没有产出(博客、GitHub)
- 有没有热情(持续学习)
❓ 反问环节·高分问题
候选人反问:
(没说问了什么)
推荐问题:
| 类型 | 问题 | 目的 |
|---|---|---|
| 技术栈 | 腾讯云前端主要用什么技术栈?有迁移计划吗? | 了解技术方向 |
| 业务 | 实习生主要参与哪些模块的开发? | 明确工作内容 |
| 团队 | 团队怎么保证云产品的稳定性? | 展示工程意识 |
| 成长 | 对于实习生,您最看重哪方面的能力? | 获取反馈 |
| 面试 | 如果这次没通过,您建议我重点补强什么? | 成长型思维 |
🎁 附:腾讯云面试复习清单
| 知识点 | 掌握程度 | 重点方向 |
|---|---|---|
| SSE | ⭐⭐⭐⭐ | 原理、中断原因、重连策略 |
| RAG | ⭐⭐⭐ | 检索效率指标、参数调优 |
| 状态管理 | ⭐⭐⭐⭐ | 选型依据、优化前后对比 |
| 语音合成 | ⭐⭐⭐ | 应用场景、Web API |
| TodoList | ⭐⭐⭐ | 基础实现、扩展功能 |
| 学习路径 | ⭐⭐ | 方法论、产出物 |
📌 最后一句:
腾讯云的面试,是一场工程能力 + 问题解决能力 的检验。
他们不要只会写代码的人,
他们要的是能把代码写成可靠产品的人 。
当面试官问到"SSE可靠吗"的时候,他其实在问:
"如果系统崩了,你能搞定吗?"