华为笔试 华为春招实习 华为第一场实习笔试真题解析 0408

笔试时间:2026年4月8日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:路由器资源用量预测(150分)

题目

路由器的某资源利用率与多个运行特征强相关:协议连接数(单位:个)、转发数据包速率(单位:Mpps)、内存占用率(单位:%)。

为了精准预测不同负载下的路由器资源利用率,保障网络稳定运行,请实现批量梯度下降法(BGD)来训练资源预测线性回归模型的参数。

资源预测模型:

y = w0 + w1·x1 + w2·x2 + w3·x3

(w0 为偏置项,x1、x2、x3 分别为特征,w1、w2、w3 为特征权重)

损失函数: 均方误差(MSE)

L = (1 / (2m)) · Σ (y_hat_i - y_i)²     (m 为样本数)

梯度更新规则:

wj = wj - α · (1/m) · Σ (y_hat_i - y_i) · x_ij

(偏置项 w0 对应 x_i0 = 1,α 为学习率)

迭代规则: 初始权重(含偏置)全为 0,迭代固定 N 次后停止,无需判断收敛。

为了提高收敛速度,采用特征归一化进行训练,并在训练完成后进行权重还原:

  1. 特征归一化: 对每个特征维度 j(j = 1, 2, 3):其中 x_min_j 为该特征在所有样本中的最小值,x_max_j 为该特征在所有样本中的最大值。若 x_max_j = x_min_j(即特征无波动),则归一化后的值为 0。
  2. 特征权重还原:w_j 为迭代后的权重。若 x_max_j = x_min_j,则 w_j' 取 0。
  3. 偏置项权重还原:w_0 为迭代后偏置项的权重。

输入描述

  • 第一行:整数 m(样本数量)
  • 第二行:整数 N(迭代次数)
  • 第三行:浮点数 α(学习率,保留 2 位小数)
  • 后续 m 行:每行 4 个整数,依次为 x1(协议连接数)、x2(转发数据包速率)、x3(内存占用率)、y(资源用量)

输出描述

一行,4 个浮点数,依次为还原后的 w_0'、w_1'、w_2'、w_3',结果保留 2 位小数,银行家舍入,以一个空格分隔,前后无冗余空格。

样例输入 1

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

样例输出 1

4394.59 6.82 1.20 1.55

样例输入 2

2
50
0.05
0 0 0 0
1000 10000 100 100000

样例输出 2

11419.33 28.26 2.83 282.62

参考题解

解题思路:

本题考察监督学习中线性回归的实现,核心步骤为:

  1. 特征归一化:对每个特征维度,按照 Min-Max 归一化将数据缩放到 [0, 1] 区间,加快梯度下降的收敛速度。对无波动特征(max == min)直接置 0 避免除零。
  2. 批量梯度下降(BGD):每一轮用全部样本计算梯度的累加和,再除以 m 求平均,最后按学习率 α 同步更新偏置和三个特征权重。固定迭代 N 次不做收敛判断。
  3. 权重还原:由于训练时使用的是归一化后的特征,输出时要把权重换回原始尺度——各特征权重除以原始区间 (x_max - x_min);偏置项减去 Σ w_j' · x_min_j 以抵消归一化时的平移量。
  4. 银行家舍入:即"四舍六入五成双",对 .5 的情况取偶数。Python 的内置 round() 默认就是银行家舍入;Java 可用 BigDecimal.ROUND_HALF_EVEN;C++ 需要手工实现。

C++:

#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <sstream>
#include <algorithm>
using namespace std;

// 银行家舍入(四舍六入五成双)保留 decimals 位小数
double bankerRound(double value, int decimals) {
    double factor = pow(10.0, decimals);
    double scaled = value * factor;
    double floorVal = floor(scaled);
    double diff = scaled - floorVal;
    double rounded;
    const double EPS = 1e-9;
    if (diff < 0.5 - EPS) {
        rounded = floorVal;
    } else if (diff > 0.5 + EPS) {
        rounded = floorVal + 1.0;
    } else {
        // 恰好 0.5,向偶数舍入
        long long fi = (long long) floorVal;
        if (fi % 2 == 0) rounded = floorVal;
        else rounded = floorVal + 1.0;
    }
    return rounded / factor;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int m, N;
    double alpha;
    cin >> m >> N >> alpha;

    vector<vector<double>> X(m, vector<double>(3));
    vector<double> Y(m);
    for (int i = 0; i < m; i++) {
        cin >> X[i][0] >> X[i][1] >> X[i][2] >> Y[i];
    }

    // 1. 特征归一化
    vector<double> X_min(3), X_max(3);
    for (int j = 0; j < 3; j++) {
        X_min[j] = X_max[j] = X[0][j];
        for (int i = 1; i < m; i++) {
            X_min[j] = min(X_min[j], X[i][j]);
            X_max[j] = max(X_max[j], X[i][j]);
        }
    }
    vector<vector<double>> X_norm(m, vector<double>(3, 0.0));
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < 3; j++) {
            if (X_max[j] == X_min[j]) X_norm[i][j] = 0.0;
            else X_norm[i][j] = (X[i][j] - X_min[j]) / (X_max[j] - X_min[j]);
        }
    }

    // 2. 批量梯度下降
    vector<double> w(4, 0.0);
    for (int it = 0; it < N; it++) {
        vector<double> grad(4, 0.0);
        for (int i = 0; i < m; i++) {
            double y_hat = w[0]
                         + w[1] * X_norm[i][0]
                         + w[2] * X_norm[i][1]
                         + w[3] * X_norm[i][2];
            double diff = y_hat - Y[i];
            grad[0] += diff;
            grad[1] += diff * X_norm[i][0];
            grad[2] += diff * X_norm[i][1];
            grad[3] += diff * X_norm[i][2];
        }
        for (int j = 0; j < 4; j++) {
            w[j] -= alpha * (grad[j] / m);
        }
    }

    // 3. 特征权重及偏置项还原
    vector<double> wp(4, 0.0);
    for (int j = 1; j < 4; j++) {
        if (X_max[j-1] == X_min[j-1]) wp[j] = 0.0;
        else wp[j] = w[j] / (X_max[j-1] - X_min[j-1]);
    }
    wp[0] = w[0] - (wp[1] * X_min[0] + wp[2] * X_min[1] + wp[3] * X_min[2]);

    // 4. 输出(银行家舍入保留 2 位小数)
    for (int i = 0; i < 4; i++) {
        if (i) cout << " ";
        cout << fixed << setprecision(2) << bankerRound(wp[i], 2);
    }
    cout << "\n";
    return 0;
}

Java:

import java.io.*;
import java.util.*;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int m = Integer.parseInt(br.readLine().trim());
        int N = Integer.parseInt(br.readLine().trim());
        double alpha = Double.parseDouble(br.readLine().trim());

        double[][] X = new double[m][3];
        double[] Y = new double[m];
        for (int i = 0; i < m; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            X[i][0] = Double.parseDouble(st.nextToken());
            X[i][1] = Double.parseDouble(st.nextToken());
            X[i][2] = Double.parseDouble(st.nextToken());
            Y[i]    = Double.parseDouble(st.nextToken());
        }

        // 1. 特征归一化
        double[] X_min = new double[3];
        double[] X_max = new double[3];
        for (int j = 0; j < 3; j++) {
            X_min[j] = X[0][j]; X_max[j] = X[0][j];
            for (int i = 1; i < m; i++) {
                X_min[j] = Math.min(X_min[j], X[i][j]);
                X_max[j] = Math.max(X_max[j], X[i][j]);
            }
        }
        double[][] Xn = new double[m][3];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < 3; j++) {
                if (X_max[j] == X_min[j]) Xn[i][j] = 0.0;
                else Xn[i][j] = (X[i][j] - X_min[j]) / (X_max[j] - X_min[j]);
            }
        }

        // 2. 批量梯度下降
        double[] w = new double[4];
        for (int it = 0; it < N; it++) {
            double[] grad = new double[4];
            for (int i = 0; i < m; i++) {
                double y_hat = w[0] + w[1]*Xn[i][0] + w[2]*Xn[i][1] + w[3]*Xn[i][2];
                double diff = y_hat - Y[i];
                grad[0] += diff;
                grad[1] += diff * Xn[i][0];
                grad[2] += diff * Xn[i][1];
                grad[3] += diff * Xn[i][2];
            }
            for (int j = 0; j < 4; j++) {
                w[j] -= alpha * (grad[j] / m);
            }
        }

        // 3. 特征权重及偏置项还原
        double[] wp = new double[4];
        for (int j = 1; j < 4; j++) {
            if (X_max[j-1] == X_min[j-1]) wp[j] = 0.0;
            else wp[j] = w[j] / (X_max[j-1] - X_min[j-1]);
        }
        wp[0] = w[0] - (wp[1]*X_min[0] + wp[2]*X_min[1] + wp[3]*X_min[2]);

        // 4. 银行家舍入输出(HALF_EVEN)
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            BigDecimal bd = new BigDecimal(Double.toString(wp[i]))
                    .setScale(2, RoundingMode.HALF_EVEN);
            if (i > 0) sb.append(' ');
            sb.append(bd.toPlainString());
        }
        System.out.println(sb);
    }
}

Python:

import sys

def solve():
    m = int(sys.stdin.readline().strip())
    N = int(sys.stdin.readline().strip())
    alpha = float(sys.stdin.readline().strip())

    X = []
    Y = []
    # 循环读取 m 行样本数据
    for _ in range(m):
        parts = sys.stdin.readline().strip().split()
        if parts:
            X.append([float(parts[0]), float(parts[1]), float(parts[2])])
            Y.append(float(parts[3]))

    # 1. 特征归一化
    X_min = [min(X[i][j] for i in range(m)) for j in range(3)]
    X_max = [max(X[i][j] for i in range(m)) for j in range(3)]
    X_norm = [[0.0] * 3 for _ in range(m)]
    for i in range(m):
        for j in range(3):
            if X_max[j] == X_min[j]:
                X_norm[i][j] = 0.0
            else:
                X_norm[i][j] = (X[i][j] - X_min[j]) / (X_max[j] - X_min[j])

    # 2. 批量梯度下降�代
    w = [0.0, 0.0, 0.0, 0.0]   # w0, w1, w2

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

牛客93169152...:可以发邮件,我停了三天没收到链接,发邮件问了一下,十分钟后就有了
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务