大厂真题 / 华为

华为 4.8 笔试真题 - AI岗

本场考试概述

考试时间:2026年4月8日 考试岗位:AI岗 难度评级:中等

考点分析

  1. 选择题(20道):数学(概率统计/线代/数值计算)、深度学习(优化器/归一化/损失/CNN/Transformer)、大模型(推理优化/注意力/生成策略/端侧/训练范式)
  2. 第一题:批量梯度下降(BGD)+ 特征归一化 + 权重还原(难度中等)
  3. 第二题:K-Means 聚类 + 配送路径规划(难度中等)

建议策略

  1. 选择题分值高,大模型前沿题是难点,注意力机制优化和量化策略要细心区分
  2. 两道编程题都是 ML 经典算法实现,NumPy 向量化是关键
  3. 第一题注意权重还原步骤,第二题注意 K > N 的边界和配送排序不等于聚类顺序

选择题精选

第1题

相关系数 r = -1 说明 X 和 Y:

A. 相互独立 B. 存在线性函数关系 C. 完全负线性相关 D. 完全不相关

答案:C

r = -1 表示两变量满足严格的负线性函数关系 y = ax + b(a < 0),即完全负线性相关。

第2题

对任意实矩阵 A,若 SVD 为 UΣV^T,则 A 的秩等于:

A. Σ的迹 B. Σ对角线上非零奇异值的个数 C. U的行数 D. V的列数

答案:B

矩阵的秩等于其非零奇异值的个数,这是 SVD 的基本性质。

第4题

混合精度训练中 loss scaling 主要解决:

A. 梯度爆炸 B. 梯度下溢 C. 激活饱和 D. 权重过大

答案:B

FP16 能表示的最小正数约为 6×10^-8,反向传播中小梯度容易下溢为 0。Loss scaling 通过放大 loss 避免梯度下溢。

第6题

关于 Layer Normalization 说法错误的是:

A. 可分 Pre-LN 和 Post-LN B. 与 RMSNorm 相比,LN 去掉了减均值部分 C. LN 先算均值和方差再归一化 D. LN 可避免梯度消失/爆炸

答案:B

是 RMSNorm 去掉了减均值的部分(只按 RMS 缩放),而不是 LN。B 说反了。

第10题

关于注意力机制优化,正确的是:

A. SWA 无法捕获超窗口长距离依赖 B. SWA 层总显存与全注意力相同 C. Flash Attention 是低秩近似 D. 线性注意力推理时可转化为 RNN 递推

答案:D

线性注意力在推理时可转化为 RNN 递推形式,生成每个新 token 的计算量与上下文长度无关。A 错(多层堆叠扩大感受野),B 错(SWA 的 KV Cache 更小),C 错(Flash Attention 是 IO 优化,复杂度仍为 O(n^2))。

第12题

关于 Huber 损失函数,正确的是:

A. 平衡了 MSE 对异常值的敏感性和 MAE 在零点的不可导性 B. 存在不可导点 C. 误差小时为线性,大时为二次 D. 与 MSE 完全相同

答案:A

Huber 在误差小时用平方(光滑),在误差大时用线性(对异常值不敏感),同时保持处处可导。


第一题:路由器资源用量预测

题目描述

路由器资源利用率与三个特征强相关:协议连接数、转发数据包速率、内存占用率。实现批量梯度下降法(BGD)训练线性回归模型。

模型:y = w0 + w1x1 + w2x2 + w3*x3。损失函数为 MSE。训练时对特征做 min-max 归一化,训练完成后还原权重。

样例

输入

3
100
0.10
100 200 150 6000
200 800 600 7500
300 70 60 6500

输出

4394.59 6.82 1.20 1.55

思路分析

第一步:为什么要归一化

三个特征的数量级差几十到上百倍。min-max 归一化把每一维都映射到 [0,1],三维尺度统一后学习率好选、收敛也快。

第二步:批量梯度下降

从全零权重开始,每一步用全部样本算梯度,沿”让 MSE 变小最快的方向”更新权重。把 m 个样本堆成矩阵 X(前面拼一列全 1 对应偏置),预测和梯度各只需一次矩阵乘。

第三步:权重还原

归一化把 x 轴压缩了 range 倍,还原时斜率要除以 range;偏置部分由 min 值吸收常数平移。

题解代码

import sys
import numpy as np

def solve():
    data = sys.stdin.read().split()
    m = int(data[0])
    N = int(data[1])
    alpha = float(data[2])
    arr = np.array(data[3:3 + 4 * m], dtype=float).reshape(m, 4)
    X = arr[:, :3]
    y = arr[:, 3]

    # min-max 归一化
    mins = X.min(axis=0)
    maxs = X.max(axis=0)
    ranges = maxs - mins
    safe = np.where(ranges == 0, 1.0, ranges)
    Xn = (X - mins) / safe
    Xn[:, ranges == 0] = 0

    # 增广矩阵(首列全 1 对应偏置)
    Xa = np.hstack([np.ones((m, 1)), Xn])
    w = np.zeros(Xa.shape[1])

    # BGD 迭代
    for _ in range(N):
        err = Xa @ w - y
        grad = (Xa.T @ err) / m
        w = w - alpha * grad

    # 还原权重到原始特征空间
    w_real = np.zeros(4)
    w_real[1:] = np.where(ranges == 0, 0.0, w[1:] / safe)
    w_real[0] = w[0] - (w_real[1:] * mins).sum()

    print(f"{w_real[0]:.2f} {w_real[1]:.2f} {w_real[2]:.2f} {w_real[3]:.2f}")

solve()

复杂度分析

时间复杂度:O(N * m * d),每轮两次矩阵-向量乘均为 O(md)。 空间复杂度:O(m * d),存放增广特征矩阵。


第二题:快递员极速配送挑战

题目描述

N 个快递包裹需要派送,每个包裹对应坐标 (x, y)。使用 K-Means 将包裹划分为 K 个簇(社区)。快递员从原点出发,按社区中心到原点距离由近到远依次配送,最后返回原点。求总时间(秒,向下取整)。

K-Means 规则:种子点按到起点距离升序选前 K 个点初始化;迭代优化直到中心移动距离和 < 10^-4 或达到 50 次。

样例

输入

3 10 30
1.2 1.5
1.8 1.2
5.0 5.2
5.5 4.8
4.9 5.5
-2.0 3.0
-2.5 3.5
-1.8 2.8
1.5 1.8
5.2 5.0

输出

2502

思路分析

第一步:K-Means 聚类

先按到原点距离升序选前 K 个点作为初始中心。每轮让每个点投奔最近的中心,然后每个中心挪到其组员的重心位置。反复迭代直到中心几乎不动。

第二步:配送路径计算

聚类收敛后,配送顺序按”中心到原点距离”由近到远排序(注意不等于聚类编号顺序)。起点→最近中心→次近中心→…→最远中心→起点,相邻点欧氏距离求和得到总公里数,再转换为秒数。

第三步:边界处理

当 K > N 时每个点自成一簇,有效簇数取 min(K, N)。

题解代码

import sys
import numpy as np

def kmeans(points, K):
    N = points.shape[0]
    dist_to_origin = (points ** 2).sum(axis=1)
    order = np.argsort(dist_to_origin, kind='stable')
    Ke = min(K, N)
    centers = points[order[:Ke]].astype(float)

    for _ in range(50):
        diff = points[:, None, :] - centers[None, :, :]
        d2 = (diff ** 2).sum(axis=2)
        labels = d2.argmin(axis=1)

        sum_xy = np.zeros_like(centers)
        np.add.at(sum_xy, labels, points)
        cnt = np.bincount(labels, minlength=Ke)

        new_centers = centers.copy()
        mask = cnt > 0
        new_centers[mask] = sum_xy[mask] / cnt[mask, None]

        move = np.linalg.norm(new_centers - centers, axis=1).sum()
        centers = new_centers
        if move < 1e-4:
            break
    return centers

def solve():
    data = sys.stdin.read().split()
    K = int(data[0])
    N = int(data[1])
    speed = int(data[2])
    pts = np.array(data[3:3 + 2 * N], dtype=float).reshape(N, 2)

    centers = kmeans(pts, K)

    # 按到原点距离排序配送
    order = np.argsort((centers ** 2).sum(axis=1), kind='stable')
    path = np.vstack([[0.0, 0.0], centers[order], [0.0, 0.0]])
    segs = np.linalg.norm(np.diff(path, axis=0), axis=1)
    total = segs.sum()
    print(int(3600.0 * total / speed))

solve()

复杂度分析

时间复杂度:O(iter * N * K),每轮广播距离表为 O(NK)。 空间复杂度:O(N * K),主要来自广播距离表。


小结

  • 选择题涵盖概率统计、线代、深度学习和大模型前沿,重点关注 RMSNorm vs LN、Flash Attention 原理、线性注意力 RNN 化、KV Cache 量化策略
  • 第一题 BGD 线性回归,核心是 min-max 归一化训练后还原权重,NumPy 向量化实现高效
  • 第二题 K-Means 聚类,注意种子点初始化规则和配送顺序不等于聚类顺序