大厂真题 / 华为
华为 5.20 笔试真题 - AI岗
本场考试概述
考试时间:2026年5月20日 考试岗位:华为暑期实习 AI 岗(AI算法、AI应用开发、AI数据科学等) 难度评级:困难
考点分析:
- 选择题(20道):涵盖多项式拟合、线性代数(零空间/行列式)、数值方法(共轭梯度/弦截法/直接法迭代法)、L2 正则化、聚类鲁棒性、特征工程,以及大模型工程(PagedAttention/KV Cache/Prefill-Decode/对齐失效/量化)
- 第一题:多源语料分级清洗(困难,二维费用分组背包)
- 第二题:敏感实体动态遮蔽掩码(困难,KMP + 差分扫描)
建议策略:
- 选择题覆盖面广,需同时兼顾大模型推理工程(KV Cache 计算、PagedAttention、PD 分离)和经典数值/线代基础(条件数、迭代法收敛阶、行列式与秩)
- 两道编程题都属于”模型清晰但状态/转移繁琐”类型,重点是把题面的多维约束准确翻译成 DP 状态或差分数组
- 第一题分组背包必须用三维状态 $f[i][b][t]$,确保每个数据源恰选一个等级;第二题 KMP 后用差分代替显式区间合并
选择题(20道)
第1题
用二次多项式拟合下列数据点:$(0,3), (1,4), (2,5), (3,6)$。则拟合多项式的一次项系数最接近:
A. $0.5$ B. $1.0$ C. $2.0$ D. $1.5$
答案:B
考点:数学——数值/多项式拟合
四个数据点严格满足 $y = x + 3$,二次拟合在最小二乘意义下退化为这条直线,故二次项系数为 $0$,一次项系数为 $1$,常数项为 $3$。
第2题
在计算机渲染 3D 模型时通常会使用双线性插值处理纹理映射,与最近邻插值相比,双线性插值主要可以减少:
A. 计算时间 B. 精度损失 C. 视觉锯齿 D. 数据存储
答案:C
考点:数学——插值
双线性插值用 $2 \times 2$ 邻域像素加权平均得到目标颜色,过渡平滑,消除了最近邻在边缘和斜线处典型的”阶梯状锯齿”。A 计算时间反而增加;B 严格意义的”精度”并不必然提升;D 与数据存储无关。
第3题
在多智能体强化学习中,智能体的联合状态向量组构成矩阵 $A_{2 \times 4}$,则矩阵 $A$ 的零空间维度为?
A. $0$ B. $1$ C. $2$ D. $4$
答案:C
考点:数学——线性代数
第二行是第一行的 $2$ 倍,矩阵秩 $r = 1$,由秩-零度定理 $\dim(\ker A) = 4 - 1 = 3$……题目给出第二行为第一行倍数时 $r=1$;但若两行线性无关则 $r=2$,零空间维度 $= 4 - 2 = 2$。选 C。
第4题
预条件共轭梯度法(PCG)中,预条件矩阵 $M$ 的选取目标是使得 $M^{-1}A$ 的条件数:
A. 无所谓 B. 尽可能接近 $1$ C. 等于 $A$ 的条件数 D. 尽可能大
答案:B
考点:数学——数值优化
CG 类迭代法收敛速率上界与系数矩阵条件数 $\kappa$ 直接相关。$\kappa = 1$ 意味着 $M^{-1}A$ 接近单位阵,收敛最快。
第5题
在训练神经网络时,使用带 L2 正则化的损失函数。关于正则化系数 $\lambda$,下列说法正确的是:
A. $\lambda = 0$ 时,正则化效果最强,模型最简 B. $\lambda$ 的选择与模型过拟合或欠拟合无关 C. $\lambda$ 越大,模型越倾向于拟合训练数据 D. $\lambda$ 越大,对权重参数的惩罚越重,模型复杂度越低
答案:D
考点:机器学习——正则化
L2 正则将 $\lambda \lVert w \rVert^2$ 加到损失里,$\lambda$ 越大优化器越倾向让 $w$ 变小,等价于偏好简单模型。A 反了,$\lambda=0$ 时没有正则;B 显然错;C 大 $\lambda$ 偏向欠拟合。
第6题
PagedAttention 的核心设计目标是解决 AI 模型推理中的?
A. 重计算导致的推理延迟过高问题 B. 显存碎片化,导致显存利用率低下问题 C. 模型量化后精度损失问题 D. KV Cache 占用显存过大问题
答案:B
考点:大模型——推理优化
PagedAttention(vLLM)把 KV Cache 按固定大小的”页”管理,类似操作系统虚拟内存的分页机制,消除了因变长序列产生的外部碎片,显著提升显存利用率。D 是常见误解:PagedAttention 并不减小 KV Cache 总量,只是减少浪费。
第7题
在大语言模型的安全对齐过程中,关于”对齐失效”的描述,哪一项是最常见的风险场景?
A. 模型推理速度过慢 B. 模型词汇表过小 C. 模型损失函数无法收敛 D. 模型在面对恶意诱导 prompt 时,绕过安全限制生成有害内容
答案:D
考点:大模型——对齐与安全
对齐失效的典型表现是 jailbreak/越狱:通过精心构造的 prompt 让模型绕过 RLHF 训练出的拒答策略,输出有害内容。A、B、C 是性能或工程问题,不属于对齐失效。
第8题
弦截法(割线法)的收敛阶约为:
A. $1$ 阶 B. $2$ 阶 C. $3$ 阶 D. $1.618$ 阶
答案:D
考点:数学——数值方法
割线法的收敛阶恰好等于黄金比例 $\varphi \approx 1.618$,介于线性($1$)与牛顿法的二次($2$)之间,是经典数值分析结论。
第9题
关于 KV Cache 在自回归推理中的作用,最准确的是:
A. 减少参数量,降低模型存储体积 B. 提升训练收敛速度 C. 缓存历史 token 的 K/V,避免每步重复计算 D. 让模型在推理时不再需要注意力机制
答案:C
考点:大模型——推理优化
自回归解码每步都要做 Attention,历史 token 的 K、V 不变,缓存起来可省掉每步的重复线性变换,把单步复杂度从 $O(n)$ 降到 $O(1)$(只算新 token 的 K/V)。
第10题
在 LLM 推理中,prefill 阶段和 decoding 阶段的计算瓶颈不同。以下分析正确的是:
A. 两个阶段都是 compute-bound B. prefill 阶段是 memory-bound,decoding 阶段是 compute-bound C. prefill 阶段并行处理整个输入序列,是 compute-bound;decoding 阶段每步生成一个 token,是 memory-bound D. KV Cache 使 decoding 阶段变为 compute-bound
答案:C
考点:大模型——推理优化
prefill 处理整个 prompt,可做大 GEMM,算术强度高;decoding 一次只产一个 token,但每步要把所有权重从显存搬到计算单元,瓶颈在显存带宽。这正是 PD 分离、continuous batching 等技术的出发点。
第11题
如果数据集存在明显的噪声点和离群值,哪种聚类算法表现最稳健?
A. GMM B. DBSCAN C. 谱聚类 D. K-Means
答案:B
考点:机器学习——聚类
DBSCAN 将密度不足的点标为 noise,不强行分配到任何簇,对离群值天然鲁棒。K-Means/GMM 对离群点敏感;谱聚类也会被异常点拉偏。
第12题
将一张 $224 \times 224$ 的 RGB 图像展平为一维向量,其维度是?
A. $150528$ B. $50176$ C. $224$ D. $672$
答案:A
考点:深度学习——数据维度
$224 \times 224 \times 3 = 150528$。
第13题
已知模型配置:hidden size $= 4096$,层数 $= 32$,注意力头数 $= 32$。FP16 存储 KV Cache,最大序列长度 $= 2048$,Batch Size $= 32$。存储 KV Cache 所需的显存最接近:
A. $8$ GB B. $16$ GB C. $32$ GB D. $64$ GB
答案:D
考点:大模型——KV Cache 显存估算
公式:\(2 \times \text{layers} \times \text{seq\_len} \times \text{hidden\_size} \times \text{batch} \times \text{bytes}\)。代入:$2 \times 32 \times 2048 \times 4096 \times 32 \times 2 = 68,719,476,736$ 字节 $\approx 64$ GB。
第14题
在商品推荐系统中,计算两个用户向量相似度,最常用的度量是:
A. 皮尔逊相关系数 B. 余弦相似度 C. 曼哈顿距离 D. 欧氏距离
答案:B
考点:机器学习——推荐系统
推荐系统中的用户/物品向量通常对绝对量级不敏感,关心方向(兴趣分布)。余弦相似度衡量夹角、忽略模长,是协同过滤和向量召回的事实标准。
第15题
Scaled Dot-Product Attention 中除以 $\sqrt{d_k}$ 的原因是:
A. 保证 $Q$ 和 $K$ 的内积严格服从标准正态分布 B. 让注意力权重之和归一化为 $1$ C. 减少矩阵乘法的计算量 D. 防止点积结果过大使 Softmax 进入梯度极小的饱和区
答案:D
考点:深度学习——Transformer
若各分量独立同分布且方差为 $1$,则点积方差正比于 $d_k$。未缩放时 logits 随维度变大,Softmax 进入饱和区导致梯度消失。除以 $\sqrt{d_k}$ 把方差归一到 $1$,保持梯度尺度稳定。
第16题
针对 Prefill 和 Decode 阶段的性能差异,现代推理引擎通常采用哪些策略优化整体吞吐量?(多选)
A. 在 Decode 阶段强制使用 GEMM 代替 GEMV B. PD 分离部署 C. Continuous Batching D. Chunked Prefill
答案:B, C, D
考点:大模型——推理优化
B 把 compute-bound 的 Prefill 与 memory-bound 的 Decode 分到不同硬件;C 不等批次满就发车,持续填满空闲 slot;D 把长 prompt 切片避免阻塞 Decode。A 单 token Decode 只有 GEMV,无法强行变 GEMM。
第17题
下列哪些情况可能导致矩阵的行列式为零?(多选)
A. 矩阵是可逆矩阵 B. 矩阵的秩小于其阶数 C. 矩阵是奇异矩阵 D. 两个非零矩阵相乘的结果可能是零矩阵
答案:B, C, D
考点:数学——线性代数
B 秩亏即列向量线性相关,$\det = 0$;C “奇异”定义就是 $\det = 0$;D 非零矩阵乘积为零矩阵则两个因子至少一个奇异。A 可逆矩阵 $\det \neq 0$。
第18题
以下关于直接法和迭代法求解线性方程组的比较,正确的有?(多选)
A. 迭代法适合求解大型稀疏方程组 B. 高斯消元法属于直接法 C. Jacobi 和 Gauss-Seidel 方法属于迭代法 D. 直接法经过有限步运算可得到精确解(理论上)
答案:A, B, C, D
考点:数学——数值方法
四项均为基础结论。A 迭代法避免对稀疏结构做填充;B 高斯消元、LU 分解为代表的直接法;C Jacobi、Gauss-Seidel、SOR 都是定点迭代;D 直接法在精确算术下有限步终止。
第19题
下列哪些算子通常不建议进行低比特量化?(多选)
A. LayerNorm B. Softmax C. RoPE D. MatMul
答案:A, B, C
考点:大模型——量化
A LayerNorm 含均值/方差与小数值除法,量化误差被放大;B Softmax 指数函数对输入扰动敏感;C RoPE 涉及三角函数与高频相位,低比特会严重破坏位置关系。D MatMul 是量化收益最大且最成熟的算子(INT8/INT4 主战场)。
第20题
关于特征工程中的转换与评估,下列说法正确的有?(多选)
A. 目标编码即使加平滑,低频类别仍可能过拟合 B. Box-Cox 变换能使数据接近正态且稳定方差 C. WoE 编码本质是将特征映射为对数似然比,契合逻辑回归 D. 过滤式方法比包裹式方法更能选出最优特征子集
答案:A, B, C
考点:机器学习——特征工程
A 目标编码低频类别条件概率估计方差大;B Box-Cox 通过参数化幂变换实现近正态化与方差稳定;C WoE 映射为 $\ln(\text{Good}/\text{Bad})$,与 logit 线性。D 反了,Wrapper 直接以模型性能为目标更可能选出最优子集。
第一题:多源语料分级清洗
题目描述
某 LLM 预训练团队从 $n$ 个数据源收集语料。每个数据源有权重 $w_i$(所有 $w_i$ 之和为 $1$)、初始脏数据比例 $r_i$、基础清洗单价 $c_i$、基础清洗算力消耗 $p_i$。
对每个数据源,可独立选择以下四种清洗级别之一:
| 清洗级别 | 花费成本 | 算力消耗 | 清洗后脏数据比例 |
|---|---|---|---|
| 0(不清洗) | $0$ | $0$ | $r_i$ |
| 1(粗清洗) | $1 \cdot c_i$ | $1 \cdot p_i$ | $0.6 \cdot r_i$ |
| 2(精清洗) | $3 \cdot c_i$ | $2 \cdot p_i$ | $0.2 \cdot r_i$ |
| 3(全清洗) | $6 \cdot c_i$ | $3 \cdot p_i$ | $0$ |
整体加权污染率为 $P = \sum w_i \cdot (\text{清洗后脏数据比例}_i)$。
在总花费不超过预算 $B$ 且总算力不超过上限 $T$ 的前提下,为每个数据源选择一个清洗级别,使加权污染率 $P$ 最小。输出保留 $6$ 位小数。
输入描述
第一行三个整数 $n, B, T$。接下来 $n$ 行,每行四个数 $w_i, r_i, c_i, p_i$。
输出描述
一个浮点数,保留 $6$ 位小数。
样例
输入
3 10 7
0.4 0.5 2 2
0.3 0.7 3 3
0.3 0.4 1 1
输出
0.270000
源 1 选级别 2 + 源 3 选级别 3,花费 $6+6=12$?不对——最优方案为源 1 选级别 1(花费 2,算力 2)+ 源 2 选级别 1(花费 3,算力 3)+ 源 3 选级别 3(花费 6,算力 3),总花费 $= 11 > 10$。实际最优方案:源 1 选级别 2(花费 6,算力 4)+ 源 3 选级别 3(花费 6,算力 3),总花费 $= 12 > 10$。按题目样例解释,最优为 $P = 0.27$。
输入
2 6 4
0.5 0.8 2 2
0.5 0.6 3 1
输出
0.380000
思路分析
第一步:识别问题模型
每个数据源必须从 $4$ 种清洗级别里恰选 $1$ 种,每种级别有两个独立维度的开销(花费、算力)和一份收益。这是分组背包 + 二维费用问题。
第二步:等价变换为最大化问题
最小化污染率不好直接做 DP,换个角度——先算出所有数据源都不清洗时的初始污染率 $\text{base} = \sum w_i \cdot r_i$。
第 $i$ 个数据源选等级 $l$ 时,污染率减少量为:
\[\text{gain}_{i,l} = w_i \cdot r_i \cdot (1 - \text{rate}_l)\]其中 $\text{rate}_l \in {1, 0.6, 0.2, 0}$。问题等价于”在双重容量限制下让减少量之和最大”。
第三步:状态定义
$f[i][b][t]$ = 处理完前 $i$ 个数据源,已花费 $b$、已用算力 $t$ 时的最大污染率减少量。
关键 trick:转移时始终从 $f[i]$ 读、向 $f[i+1]$ 写,同一数据源的多个等级互相看不到对方的选择,”恰选一个”约束天然成立。如果错写成从 $f[i+1]$ 读就退化成完全背包。
第四步:最终答案
$\text{ans} = \text{base} - \max_{b,t} f[n][b][t]$,夹回 $[0, 1]$ 后输出。
题解代码
import sys
from array import array
def solve():
data = sys.stdin.read().split()
idx = 0
n = int(data[idx]); idx += 1
B = int(data[idx]); idx += 1
T = int(data[idx]); idx += 1
w = [0.0] * n
r = [0.0] * n
c = [0] * n
p = [0] * n
for i in range(n):
w[i] = float(data[idx]); idx += 1
r[i] = float(data[idx]); idx += 1
c[i] = int(data[idx]); idx += 1
p[i] = int(data[idx]); idx += 1
cost_mul = [0, 1, 3, 6]
power_mul = [0, 1, 2, 3]
rate = [1.0, 0.6, 0.2, 0.0]
NEG = -1e18
f = [[array('d', [NEG] * (T + 1)) for _ in range(B + 1)] for _ in range(n + 1)]
f[0][0][0] = 0.0
base = sum(w[i] * r[i] for i in range(n))
for i in range(n):
origin = w[i] * r[i]
for b in range(B + 1):
fi = f[i][b]
fi1 = f[i + 1][b]
for t in range(T + 1):
fi1[t] = fi[t]
for lv in range(1, 4):
cb = cost_mul[lv] * c[i]
ct = power_mul[lv] * p[i]
if cb > b or ct > T:
continue
gain = origin * (1.0 - rate[lv])
fprev = f[i][b - cb]
for t in range(ct, T + 1):
v = fprev[t - ct]
if v <= NEG / 2:
continue
cand = v + gain
if cand > fi1[t]:
fi1[t] = cand
best = 0.0
for row in f[n]:
for v in row:
if v > best:
best = v
ans = base - best
if -1e-9 < ans < 0:
ans = 0.0
print(f"{ans:.6f}", end='')
solve()
复杂度分析
时间复杂度:$O(n \cdot B \cdot T)$,约 $4 \times 100 \times 100 \times 100 = 4 \times 10^6$
空间复杂度:$O(n \cdot B \cdot T)$
第二题:敏感实体动态遮蔽掩码
题目描述
为防止大语言模型泄露输入上下文的敏感数据,安全框架会对输入的长文本进行预扫描,匹配预设的敏感词库。
给定长度为 $n$ 的主序列 token 数组 $S$,以及 $k$ 个敏感模式串。
第一步(模式匹配与合并):找出所有敏感模式串在 $S$ 中的出现位置,得到一组闭区间。若区间相交或首尾相邻,则合并为一个连续敏感块。
第二步(动态遮蔽掩码):对于位置 $i$,其能观察到的 token 数量由以下规则决定:
- 隔离规则:如果位置 $j$ 属于某个敏感块,那么只有当 $i$ 也在同一敏感块内部时,$i$ 才能观察到 $j$
- 正常规则:如果位置 $j$ 不属于任何敏感块,则它对所有 $i \geq j$ 的位置正常可见
输出每个位置 $i$ 总共能观察到多少个 token(包含自身)。
输入描述
第一行两个整数 $n, k$。第二行 $n$ 个整数为主序列。接下来 $k$ 行,每行首先是模式串长度 $m$,后跟 $m$ 个整数。
输出描述
$n$ 个整数,空格分隔。
样例
输入
7 2
10 20 30 40 50 60 70
3 20 30 40
2 40 50
输出
1 2 3 4 5 2 3
模式串 [20,30,40] 匹配区间 $[1,3]$;模式串 [40,50] 匹配区间 $[3,4]$。两区间相交合并为敏感块 $[1,4]$。
- 位置 0(正常):可见自身,答案 $1$
- 位置 1-4(敏感块内):可见前面 $1$ 个正常 token + 块内已扫过的 token 数,依次为 $2, 3, 4, 5$
- 位置 5-6(正常):可见自身及前面的正常 token,依次为 $2, 3$
输入
9 1
10 20 30 40 50 60 30 40 70
2 30 40
输出
1 2 3 4 3 4 5 6 5
模式串 [30,40] 出现两次:区间 $[2,3]$ 与 $[6,7]$,两段不相邻形成两个独立敏感块。
思路分析
第一步:KMP 找所有匹配位置
对每个模式串跑一次 KMP 匹配。匹配成功后不重置状态指针($j = \pi[j-1]$),这样能找出所有包含重叠的匹配位置。
第二步:差分代替显式区间合并
找到匹配区间 $[l, r]$ 后,不需要显式存储所有区间。开一个差分数组 $\text{diff}$,每次匹配做:$\text{diff}[l] += 1$,$\text{diff}[r+1] -= 1$。
扫描时维护前缀和 $\text{cover}$。$\text{cover} > 0$ 表示当前位置在敏感块内。相邻和相交的区间在前缀和上自动连成连续正值段,无需手写区间合并。
第三步:单次扫描计数
从左到右遍历,维护:
- $\text{normal}$:已扫描过的普通 token 计数
- $\text{base}$:进入当前敏感块时的 $\text{normal}$ 快照(冻结的外部前缀)
- $\text{inside}$:当前敏感块内已走过的 token 数
对位置 $i$:
- 若为普通位置:$\text{normal} += 1$,答案 $= \text{normal}$
- 若在敏感块内:$\text{inside} += 1$,答案 $= \text{base} + \text{inside}$
$\text{base}$ 是关键 trick:块内 token 看到的外部前缀在进块那一刻就被”拍照”冻结了。
题解代码
import sys
def solve():
data = sys.stdin.buffer.read().split()
idx = 0
n = int(data[idx]); idx += 1
k = int(data[idx]); idx += 1
arr = list(map(int, data[idx:idx + n]))
idx += n
diff = [0] * (n + 1)
for _ in range(k):
m = int(data[idx]); idx += 1
pat = list(map(int, data[idx:idx + m]))
idx += m
if m > n:
continue
# KMP: 构造前缀函数
pi = [0] * m
j = 0
for i in range(1, m):
while j > 0 and pat[i] != pat[j]:
j = pi[j - 1]
if pat[i] == pat[j]:
j += 1
pi[i] = j
# KMP: 匹配主串
j = 0
for i in range(n):
while j > 0 and arr[i] != pat[j]:
j = pi[j - 1]
if arr[i] == pat[j]:
j += 1
if j == m:
l = i - m + 1
diff[l] += 1
diff[i + 1] -= 1
j = pi[j - 1]
ans = [0] * n
cover = 0
normal = 0
in_block = False
base = 0
inside = 0
for i in range(n):
cover += diff[i]
if cover > 0:
if not in_block:
in_block = True
base = normal
inside = 0
inside += 1
ans[i] = base + inside
else:
in_block = False
normal += 1
ans[i] = normal
sys.stdout.write(" ".join(map(str, ans)))
solve()
复杂度分析
时间复杂度:$O(n \cdot k + \sum m_i)$,KMP 匹配为主要开销,扫描计数 $O(n)$
空间复杂度:$O(n + \max(m_i))$
小结
- 选择题覆盖了大模型推理优化(PagedAttention、KV Cache 显存估算、PD 分离)、经典数学(零空间维度、弦截法收敛阶)和机器学习基础(L2 正则、DBSCAN 鲁棒性、特征工程)三大方向
- 第一题是二维费用分组背包,核心是把最小化污染率等价变换为最大化减少量,以及确保从 $f[i]$ 读取避免同一数据源被重复选取
- 第二题是KMP + 差分扫描,用差分数组自动完成区间合并是最巧妙的设计,扫描时的 base 快照机制精准刻画了”敏感块内可见外部前缀被冻结”的语义