ARTICLE · 1234283
华为机考AI方向10月23日笔试题与解析
写在前面
本次给大家带来2026年10月23日华为AI方向笔试题的2道题,本套题涉及到的岗位:AI算法工程师,AI应用开发工程师,AI数据科学工程师等以AI为开头的岗位,统一笔试,不区分部门。
需要我整理的AI机考速成攻略&题单可访问文章底部左侧:阅读原文
选择题(15*6分 + 5*12分,共150分)
1、自注意力层的输入序列包含 个 token,每个 token 表示成 维向量(忽略 batch 维与多头)。计算注意力得分矩阵 的复杂度是?
2、卷积神经网络中池化层的主要作用是?
通过激活函数为网络补充非线性表达能力 依靠反向传播学习卷积核,完成局部特征提取 统一各通道数值的均值和方差,起到归一化作用 按窗口聚合、压缩特征图的空间尺寸,从而降低后续计算量与参数量
3、关于主成分分析(PCA)降维,下列说法正确的是?
各主成分按方差贡献从大到小排列,且都是原始特征的线性组合 PCA 是有监督方法,降维过程要用到样本标签 PCA 的优化目标是让不同类别之间的间隔尽可能大 PCA 对量纲不敏感,因此使用前不必做特征标准化
4、评测大模型的数学解题能力时,常用约 5200 道带唯一标准答案的中学数学题组成的数据集。对这类题目,最常用的评测指标是?
困惑度(Perplexity) 准确率(Accuracy) 语义相似度(Cosine Similarity) 单次请求的平均耗时(Latency)
5、对实数域上的向量组,下列哪一条是它线性相关的等价刻画?
组内所有向量的 2-范数彼此相等 向量组中向量的个数一定少于向量的维度 存在一组不全为零的系数,使它们的线性组合等于零向量 组内任意一个向量都不能由其余向量线性表出
6、设随机变量 服从参数 的泊松分布,则 等于?
7、Transformer 解码器自注意力里的因果掩码(Causal Mask)主要用来做什么?
屏蔽补位(padding)token,避免无效位置参与计算 让每个位置只能看到它之前的 token,防止未来信息泄漏 在不同注意力头之间重新分配权重,抑制多头冗余 把位置编码叠加到注意力分数上,补充顺序信息
8、 卷积在通道数 很大时,哪种内存布局更利于向量化、缓存更友好?其中 为 batch 大小,、 为特征图的高和宽。
NHWC NCHW NHCW 每个通道单独存成一个文件
9、循环神经网络展开到时刻 时,隐藏状态 由哪些量决定?
只由当前输入 决定 只由上一时刻的隐藏状态 决定 由当前输入 和上一时刻的隐藏状态 共同决定 由整个序列最后一个输入 决定
10、某二分类模型的精确率为 0.6,召回率为 0.9,该模型的 F1 分数是?
0.75 0.54 0.72 0.68
第2题-大模型推理KV Cache 内存池管理(150分)
大语言模型自回归生成时,历史 token 的 Key 与 Value 会缓存在 KV Cache 里,后面每一步解码直接复用,不必重算。序列越长,KV Cache 占的显存越多,而且是线性增长。
工程上通常先把显存切成一堆等大的块(Block)集中管理,这套机制叫内存池(Memory Pool):Block 一次分配好,每个 Block 装固定条数 token 的 KV 数据。
题目描述
内存池中有 个等大的 Block,每个 Block 能容纳 条 token 的 KV 数据。
现有 个推理请求,第 个请求要处理 条 token(输入长度与生成长度之和),它占用的 Block 数为 。
决策规则
请求按给定顺序逐个到达。 对每个请求可以选择接受或拒绝: 接受:被接受请求占用的 Block 总数最终不能超过 ; 拒绝:该请求不占用任何资源。 允许在后续决策中撤销先前已接受的请求(释放它占用的 Block),以换取更好的整体结果。 请求一旦被拒绝,就不能再次考虑。 请求之间不允许重排,必须按到达顺序逐个决策。
优化目标
在接受的请求占用 Block 总数不超过 的前提下,使被接受的请求数量最多。
样例1
输入
4 8 320 6 11
输出
2
解释:三个请求的 Block 需求依次为 、、。只接第 1 个请求,它独占 3 个 Block,剩下 1 个 Block 哪个请求都放不下,只能接受 1 个;跳过它、改接第 2 与第 3 个请求,占用 个 Block,可以接受 2 个。三个请求全接需要 个 Block,超过上限 ,所以最多接受 2 个。
解题思路
核心思路
题面允许在后续决策中撤销先前已接受的请求,这条规则把“必须按顺序在线决策”的约束消掉了:任何一个最终合法的请求集合,都可以先把这些请求全部接受、再在必要时撤销被拒绝的那些得到;反过来,任何时刻的最终集合也只是原请求的一个子集。所以顺序不影响答案,问题等价于——从 个请求中选出尽可能多的请求,使它们的 Block 占用之和不超过 。
第 个请求的代价是 ,每个请求的价值都是 。价值全都相同、代价都是正数,这种情况下的最优策略就是先装最便宜的:把 从小到大排序,依次尝试加入,只要当前占用加上 不超过 就接受,第一次放不下就停止(它后面只会更大,没有放得下的可能)。
这样贪心为什么最优:假设某个最优解选了 个请求、总占用 。若它选中的某个请求 的代价大于某个未选中的请求 的代价,把 换成 ,数量不变、总占用不增,仍然可行;反复替换后总能得到一个“代价最小的前 项”的可行解。于是前 小的代价之和必然不超过 ,而前 小的代价之和必然超过 (否则能选 个,与最优性矛盾)。贪心取的正是这个最大可行前缀长度。
实现方法
读入 、、,再读入 个 ; 逐个算出 Block 需求 (向上取整,注意不能写成整除); 对 升序排序; 从头累加,若 立即停止,否则 、计数加一; 输出计数。
几个容易踩的点:
需求总数的上界是 量级,累加用的整数必须能存到 , 位整数会溢出; “不超过 ”含等号,恰好填满是可以接受的; 不能按到达顺序遇到能放就放、放不下就跳过——不给撤销时这个策略在样例 1 上就错(先接 3 个 Block 的请求会挡住后面两个小请求); 不要用 的计数背包, 时必然超时。
python代码(C++和JAVA代码见在线OJ网址)
def solve(m, k, lens):# 每个请求的 Block 需求:向上取整 need = [(x + k - 1) // k for x in lens]# 需求量从小到大排序,先放最小的一定不会更差 need.sort() used = 0 ans = 0for b in need:if used + b > m:break used += b ans += 1return ansdef main(): m, k, n = map(int, input().split()) lens = []while len(lens) < n: lens.extend(map(int, input().split()))print(solve(m, k, lens[:n]))main()
第3题-OCR 智能文字纠错(300分)
题目内容
某智能终端内置了一套基于朴素贝叶斯的字符级 OCR 纠错模块。可识别的字符集为 26 个小写英文字母 ,记 。
模块用两组统计量描述模型:
发射计数 :训练语料里,真实字符 被识别成 的次数; 先验计数 :训练语料里,真实字符 出现的次数。
发射概率与先验概率均做加 拉普拉斯平滑( 为正整数):
纠错规则:对待纠错串里的每个字符 单独决策
若多个候选同时取到最大得分,则取字典序最小者()。
自训练流程:除了 条人工标注的「识别串 → 真实串」样本外,系统还保存着 条只有 OCR 输出、没有真实文本的样本,并迭代 轮。每一轮依次做两件事:
用当前模型逐条解码这 条未标注样本,得到伪真实串; 用 条标注样本,再加上这 条「识别串, 伪真实串」,重新统计 与 ,得到本轮的新模型。
每轮重新统计时,伪标注只使用本轮的,不与上一轮的累积;原始的 条标注每轮都参与。
轮结束后,用最终的模型对测试串纠错并输出。
数值稳定性:为避免浮点误差,比较两个候选 、 时应使用整数交叉相乘:
其中 ,。分母 与候选 无关,比较时可以约去。
样例1
输入
1 3 1 2pc okqqqpq
输出
kk
解题思路
核心思路
这题的模型完全由两组计数决定:发射计数 (真实字符 被识别成 的次数)与先验计数 (真实字符 出现的次数)。加 平滑后
分母里 与候选 无关,比较时可以约掉,于是只需要比较
实现方法
一轮内模型是固定的,所以每个识别字符 的最优真实字符也固定:每轮先把 26 个 的答案算成一张大小为 的解码表,之后不管解码多少条串都是查表, 一条。 填表时对每个 扫一遍 26 个候选 ,用整数交叉相乘比较 ,避免浮点误差: 优于 当且仅当 。判断用严格大于,并列时不会替换,于是自然保留字典序最小的字符。 每轮的流程是:按当前训练集( 条标注 + 本轮 条伪标注)重新统计 → 建解码表 → 用这张表把 条未标注串解码成伪标注。注意下一轮的训练集是「原始 条 + 新的 条」,上一轮的伪标注要丢掉,不能累积。 轮结束后再重建一次模型,用它解码测试串。注意 时用的是只在标注样本上统计出的模型。 计数最大约 , 最大约 ,交叉相乘最大约 ,超出 32 位整数范围,、 与乘积都要用 64 位整数。
python代码(C++和JAVA代码见在线OJ网址)
K = 26def count(pairs, alpha):"""统计发射计数与先验计数。""" emit = [[0] * K for _ in range(K)] prior = [0] * Kfor ocr, truth in pairs:for o, t in zip(ocr, truth): emit[ord(t) - 97][ord(o) - 97] += 1 prior[ord(t) - 97] += 1return emit, priordef table_of(emit, prior, alpha):"""模型固定时,26 个识别字符各自的最优真实字符也固定,先算成表。""" den = [0] * K num = [[0] * K for _ in range(K)]for c in range(K): den[c] = sum(emit[c]) + alpha * K row = num[c]for o in range(K): row[o] = (emit[c][o] + alpha) * (prior[c] + alpha) table = [0] * Kfor o in range(K): best = 0# 交叉相乘比较得分,严格大于才换人,保证并列时取字典序最小的字符for c in range(1, K):if num[c][o] * den[best] > num[best][o] * den[c]: best = c table[o] = bestreturn tabledef translate(text, table):return ''.join(chr(97 + table[ord(ch) - 97]) for ch in text)def solve(n, m, t, alpha, pairs, labels, test): train = list(pairs)for _ in range(t): emit, prior = count(train, alpha) table = table_of(emit, prior, alpha)# 伪标注只保留本轮结果,替换掉上一轮的 train = pairs + [(s, translate(s, table)) for s in labels] emit, prior = count(train, alpha)return translate(test, table_of(emit, prior, alpha))def main(): n, m, t, alpha = map(int, input().split()) pairs = [input().split() for _ in range(n)] labels = [input().strip() for _ in range(m)] test = input().strip()print(solve(n, m, t, alpha, pairs, labels, test))main()
PC端刷题:CodeFun2000.com
手机端刷题:塔子哥刷题宝















































































