互联网大厂算法工程师面试题汇总
本文整理了科大讯飞、小米、百度等知名互联网企业的算法工程师面试真题,涵盖自然语言处理、深度学习模型原理、工程实践及经典算法题解。
一、科大讯飞 NLP 方向 AI 算法工程师
1. jieba 分词的原理
jieba 分词是一款高效的中文文本分词工具,其核心基于前缀词典匹配与动态规划。主要实现机制如下:
- 前缀词典与 DAG:利用前缀词典对句子进行扫描,生成所有可能的成词路径构成的有向无环图(DAG)。
- 最大概率路径:采用动态规划算法在 DAG 上查找概率最大的切分组合,通常结合词频统计信息。
- 未登录词处理:对于词典中不存在的词,使用基于汉字成词能力的 HMM(隐马尔可夫模型),并通过 Viterbi 算法解码最优状态序列,从而识别新词。
2. Word2Vec 的原理与训练
Word2Vec 是一种将词语映射为稠密向量的模型,通过预测上下文或目标词来学习语义表示。包含两种主要架构:
- CBOW(连续词袋模型):输入是目标词周围的上下文词向量累加,输出是目标词的概率分布。适合捕捉局部上下文信息。
- Skip-gram:输入是目标词,输出是上下文的词向量。更适合处理长距离依赖和低频词。
训练过程通常使用大规模语料库,通过负采样(Negative Sampling)或层次 Softmax 优化梯度下降效率,更新神经网络参数以最小化预测误差。
3. ChatGPT 的训练流程
ChatGPT 基于 GPT-3.5 架构,训练分为两个关键阶段:
- 预训练(Pre-training):使用海量无标注文本数据(网页、书籍、维基百科等),通过自监督学习(如掩码语言建模或下一词预测)学习语言模式与结构。此阶段模型掌握通用语言能力。
- 微调(Fine-tuning):使用人工编写的对话数据集进行有监督训练。人类标注员扮演用户与模型交互,生成高质量问答对。模型通过对比预期输出调整参数,提升对话的连贯性与准确性。部分版本还会引入 RLHF(基于人类反馈的强化学习)进一步优化对齐效果。
4. BERT 模型简述
BERT(Bidirectional Encoder Representations from Transformers)是基于 Transformer 的双向编码器模型。与传统单向语言模型不同,BERT 同时利用左侧和右侧上下文信息。
- 预训练任务:
- MLM(掩码语言建模):随机掩盖输入中的部分词,要求模型根据上下文预测被掩盖的词。
- NSP(下一句预测):判断两个句子是否连续,增强句子间关系理解。
- 下游应用:在分类、命名实体识别、问答等任务上,通过微调特定层参数即可适配。
5. PyTorch 中的 train 和 eval 模块
PyTorch 中 train() 和 eval() 用于控制模型的运行模式:
- train():启用训练模式。此时 Dropout 层会随机丢弃神经元,BatchNorm 层会使用当前批次的统计量并更新全局均值方差。主要用于计算损失和反向传播更新参数。
- eval():启用评估模式。Dropout 层关闭(保留所有神经元),BatchNorm 层使用训练期间累积的全局统计量。主要用于验证集或测试集的推理,确保结果确定性。
6. Python 字典的结构及实现方式
Python 字典(dict)是键值对的集合,键必须唯一且不可变,值可重复。底层基于哈希表(Hash Table)实现:
- 哈希函数:将键转换为固定大小的整数索引。
- 冲突解决:采用开放寻址法(Open Addressing)处理哈希冲突。
- 性能:平均时间复杂度为 O(1),支持快速查找、插入和删除操作。
d = {'a': 1, 'b': 2}
print(d['a'])
d['c'] = 3
7. 无序数组取前 10 个最大的数
针对无序数组寻找 Top K 大元素,常见方案有两种:
- 全排序:使用快速排序或堆排序,时间复杂度 O(n log n)。适用于数据量较小场景。
- 小顶堆:维护一个大小为 K 的小顶堆,遍历数组时若当前元素大于堆顶则替换并调整堆。时间复杂度 O(n log K),空间更优。
import heapq
def top_k_largest(nums, k):
if not nums or k <= 0:
return []
heap = []
for num in nums:
if len(heap) < k:
heapq.heappush(heap, num)
elif num > heap[0]:
heapq.heapreplace(heap, num)
return sorted(heap, reverse=True)
二、小米 AIGC 大模型岗位
1. Transformer 原理
Transformer 摒弃了循环结构,完全基于注意力机制处理序列数据。核心组件包括:
- 自注意力机制(Self-Attention):计算序列中每个位置与其他位置的相关性权重,捕捉长距离依赖。
- 位置编码(Positional Encoding):由于模型并行处理,需注入位置信息以区分词序。
- 多头注意力(Multi-Head Attention):并行执行多个注意力头,从不同子空间提取特征。
- 前馈神经网络(FFN):在每个注意力层后接全连接网络,增加非线性变换能力。
- 残差连接与层归一化:稳定深层网络训练,防止梯度消失。
2. P-Tuning V2 原理
P-Tuning V2 是对 Prompt Tuning 的改进,旨在减少可学习参数同时提升性能:
- 分层 Prompt:在每一层 Transformer 都加入可学习的 Prompt tokens,而非仅输入层,使深层结构也能直接受控。
- 移除重参数化:简化结构,避免重参数化带来的优化困难。
- 任务自适应长度:针对不同任务搜索最佳提示长度,提升泛化能力。
- 多任务学习:支持跨任务预训练,缓解连续提示的随机惯性问题。
3. BiLSTM-CRF 模型
BiLSTM-CRF 结合了双向长短期记忆网络与条件随机场,常用于序列标注任务(如命名实体识别):
- BiLSTM:提取输入序列的正反向上下文特征,捕捉长期依赖。
- CRF:作为解码层,对标签序列进行全局建模,考虑标签间的转移约束(如禁止非法标签组合),提高标注一致性。
4. 代码题:两数之和
给定整数数组 nums 和目标值 target,找出和为目标值的两个整数下标。
def two_sum(nums, target):
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return None
三、百度算法工程师
1. LoRA 原理
LoRA(Low-Rank Adaptation)是一种高效微调技术,用于大型语言模型:
- 低秩分解:在原始权重矩阵旁增加旁路,分解为两个低秩矩阵 A 和 B(A 为高斯初始化,B 为零初始化)。
- 参数冻结:训练过程中固定原始 PLM 参数,仅训练 A 和 B。
- 叠加输出:推理时将 BA 乘积叠加到原参数上,保持输入输出维度不变,大幅降低显存占用。
2. GBDT 原理
GBDT(Gradient Boosting Decision Tree)是一种集成学习算法:
- 迭代拟合:每轮训练一棵新树,目标是拟合前一棵树的残差(真实值与预测值之差)。
- 加法模型:最终预测值为所有树的预测结果累加,逐步修正错误,提升模型精度。
3. 翻译任务架构
机器翻译主要采用 Seq2Seq 架构,目前主流基于 Transformer:
- Encoder-Decoder:编码器将源语言序列编码为上下文向量,解码器基于该向量生成目标语言序列。
- 自注意力机制:有效捕捉输入序列内部及编码解码之间的关联信息。
4. Encoder-only、Decoder-only、Encoder-decoder 区别
- Encoder-only:仅含编码器,用于特征提取(如 BERT),不适合生成任务。
- Decoder-only:仅含解码器,用于自回归生成(如 GPT),适合文本生成。
- Encoder-decoder:两者结合,用于序列到序列任务(如翻译),兼顾理解与生成。
5. Transformer 结构细节
Transformer 由多层相同的块组成,每块包含:
- 多头自注意力子层:处理序列依赖。
- 前馈网络子层:非线性变换。
- 残差连接与 LayerNorm:位于每个子层之后,保障训练稳定性。
- 交叉注意力:仅在 Decoder 端存在,连接 Encoder 与 Decoder。
6. Flash Attention 原理
Flash Attention 旨在优化 GPU 上的 Attention 计算效率:
- Tiling 技术:将矩阵分块存储在 SRAM 中,减少 HBM 读写次数。
- IO 感知:通过重新组织计算顺序,在不牺牲精度的前提下显著降低内存带宽压力,加速训练与推理。
7. FP32 与 FP16 及混合精度
- FP32:32 位浮点,精度高,占用 4 字节,适合存储梯度和累积值。
- FP16:16 位浮点,占用 2 字节,计算速度快但精度较低。
- 混合精度训练:使用 FP16 进行前向/反向计算以减少显存,同时维护 FP32 的主权重副本以防止精度丢失,平衡效率与稳定性。
8. Beam Search 原理
Beam Search 是序列生成中的搜索策略:
- 候选保留:每一步保留概率最高的 K 个候选序列(Beam Width)。
- 扩展剪枝:基于当前候选扩展下一个词,剪除低概率路径。
- 终止条件:直到生成结束符或达到最大长度,输出得分最高的完整序列。
以上题目涵盖了从基础数据结构到前沿大模型技术的核心知识点,建议结合官方文档与源码深入理解。