华为笔试 华为笔试题 20260304

笔试时间:2026年03月04日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

华为笔试题解

笔试时间:2026年3月4日

第一题:网络流量分析

难度:中等

涉及知识点: KMeans聚类算法实现、欧式距离计算、聚类中心更新、数值精度处理

题目描述

网络流量分析是网络安全和性能优化的关键任务。假设你有一个包含网络流量数据的数据,每条数据包包含以下特征:

  • packet_size(数据包大小,单位:字节)
  • inter_arrival_time(数据包到达间隔时间,单位:毫秒)
  • protocol_type(协议类型,如TCP、UDP、ICMP等,已转换为数值编码)

你的任务是使用KMeans聚类算法对网络流量进行分类,分类后的中心点再经过一个分类头,能识别出可能的流量类型(如正常流量、异常流量、DDoS攻击流量等)。KMeans算法原理为:先将数据划分为K组,随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个聚类中心之间的距离,将每个对象分配给距离它最近的聚类中心,聚类中心以及分配给它们的对象就代表一个聚类。(为保证结果固定,本题初始的聚类中心已给出,不需要随机)

输入描述

  1. 初始聚类点个数 K
  2. 初始聚类中心点集合(往下 K 行,一行一个中心点)
  3. 迭代次数
  4. 样本个数 M
  5. 样本数据,每个样本有三个特征(往下 M 行,各种特征数据已归一化处理,各维度权重占比一致)

输出描述

按给定次数迭代后新的聚类中心集合,结果保留两位小数,注意四舍五入。

样例1

输入:

3
50 25 30
60 15 60
25 75 90
3
9
50 25 30
30 50 30
60 15 60
25 75 90
100 5 60
26 15 30
32 67.5 90
80 7.5 60
20 100 90

输出:

35.33 30.00 30.00
80.00 9.17 60.00
25.67 80.83 90.00

说明: 采用欧式距离计算不同数据之间的距离:计算每个特征距离中心点的距离,选择距离最近的点作为当前特征归属的类别;按照划分的类别,重新计算每个类别的中心点,完成一轮迭代(中心点为对应类型所有样本的平均值)。重复上述流程指定次数得到结果。

样例2

输入:

3
50 20 30
60 10 60
180 180 180
3
8
50 20 30
30 50 30
60 10 60
25 75 90
100 5 60
30 60 90
80 10 60
180 180 180

输出:

40.00 35.00 30.00
59.00 32.00 72.00
180.00 180.00 180.00

提示

  • 初始聚类中心点个数:≤1000,类型为 int
  • 初始聚类中心点集合:每个特征的取值范围为 0~1000,类型为 float
  • 迭代次数:≤1000,类型为 int
  • 初始特征个数:≤1000,类型为 int
  • 初始特征集合:每个特征的取值范围为 0~1000,类型为 int

参考题解

解题思路:

这是一个KMeans聚类算法的模拟实现问题。给定初始聚类中心、样本点和迭代次数,需要模拟KMeans算法的迭代过程,输出迭代后的聚类中心。

  1. 距离计算: 使用欧几里得距离(欧式距离)计算样本点与聚类中心的距离。优化技巧:计算距离的平方,避免开方运算,因为比较距离大小时,平方距离和实际距离的排序是一致的。
  2. 分配阶段: 对于每个样本点,计算它与所有聚类中心的距离,找到距离最近的聚类中心,将该样本点分配到对应的聚类中。
  3. 更新阶段: 对于每个聚类,如果聚类中有样本点,计算所有样本点在三个维度上的平均值作为新的聚类中心;如果聚类中没有样本点,保持原来的聚类中心不变。
  4. 迭代过程: 重复执行分配阶段和更新阶段,直到达到指定的迭代次数。

算法复杂度: 每次迭代 O(N×K),总复杂度 O(T×N×K),由于 T、N、K 都≤1000,最坏情况下约 10^9 次运算。

Python:

import sys
from decimal import Decimal, ROUND_HALF_UP

def round_half_up(val):
    val_str = f"{val:.10f}"
    dec = Decimal(val_str).quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    return f"{dec:.2f}"

k = int(sys.stdin.readline().strip())
centers = []
for _ in range(k):
    parts = sys.stdin.readline().strip().split()
    centers.append([float(parts[0]), float(parts[1]), float(parts[2])])

iterations = int(sys.stdin.readline().strip())
m = int(sys.stdin.readline().strip())
points = []
for _ in range(m):
    parts = sys.stdin.readline().strip().split()
    points.append([float(parts[0]), float(parts[1]), float(parts[2])])

for _ in range(iterations):
    clusters = [[] for _ in range(k)]
    for p in points:
        best_c = -1
        best_dist = float('inf')
        for i, c in enumerate(centers):
            dist_sq = sum((p[j] - c[j]) ** 2 for j in range(3))
            if dist_sq < best_dist:
                best_dist = dist_sq
                best_c = i
        clusters[best_c].append(p)
    new_centers = []
    for i in range(k):
        if clusters[i]:
            new_c = [sum(x[j] for x in clusters[i]) / len(clusters[i]) for j in range(3)]
            new_centers.append(new_c)
        else:
            new_centers.append(centers[i])
    centers = new_centers

for c in centers:
    print(" ".join(round_half_up(x) for x in c))

C++:

#include <iostream>
#include <vector>
#include <cmath>
#include <climits>
#include <iomanip>
#include <cstdio>
using namespace std;

// 标准四舍五入保留两位小数
string roundHalfUp(double val) {
    // 加上一个极小量避免浮点误差导致的截断问题
    double rounded = floor(val * 100.0 + 0.5 + 1e-9) / 100.0;
    char buf[32];
    sprintf(buf, "%.2f", rounded);
    return string(buf);
}

int main() {
    int k;
    cin >> k;
    
    vector<vector<double>> centers(k, vector<double>(3));
    for (int i = 0; i < k; i++) {
        cin >> centers[i][0] >> centers[i][1] >> centers[i][2];
    }
    
    int iterations;
    cin >> iterations;
    
    int m;
    cin >> m;
    
    vector<vector<double>> points(m, vector<double>(3));
    for (int i = 0; i < m; i++) {
        cin >> points[i][0] >> points[i][1] >> points[i][2];
    }
    
    for (int iter = 0; iter < iterations; iter++) {
        vector<vector<vector<double>>> clusters(k);
        
        for (int p = 0; p < m; p++) {
            int bestC = -1;
            double bestDist = 1e18;
            for (int i = 0; i < k; i++) {
                double distSq = 0;
                for (int j = 0; j < 3; j++) {
                    double diff = points[p][j] - centers[i][j];
                    distSq += diff * diff;
                }
                if (distSq < bestDist) {
                    bestDist = distSq;
                    bestC = i;
                }
            }
            clusters[bestC].push_back(points[p]);
        }
        
        vector<vector<double>> newCenters(k, vector<double>(3, 0.0));
        for (int i = 0; i < k; i++) {
            if (!clusters[i].empty()) {
                for (int j = 0; j < 3; j++) {
                    double sum = 0;
                    for (auto& pt : clusters[i]) {
                        sum += pt[j];
                    }
                    newCenters[i][j] = sum / clusters[i].size();
                }
            } else {
                newCenters[i] = centers[i];
            }
        }
        centers = newCenters;
    }
    
    for (int i = 0; i < k; i++) {
        for (int j = 0; j < 3; j++) {
            if (j > 0) cout << " ";
            cout << roundHalfUp(centers[i][j]);
        }
        cout << endl;
    }
    
    return 0;
}

Java:

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

public class Main {
    static String roundHalfUp(double val) {
        BigDecimal bd = new BigDecimal(String.format("%.10f", val));
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        return bd.toPlainString();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int k = Integer.parseInt(sc.nextLine().trim());

        double[][] centers = new double[k][3];
        for (int i = 0; i < k; i++) {
            String[] parts = sc.nextLine().trim().split("\\s+");
            centers[i][0] = Double.parseDouble(parts[0]);
            centers[i][1] = Double.parseDouble(parts[1]);
            centers[i][2] = Double.parseDouble(parts[2]);
        }

        int iterations = Integer.parseInt(sc.nextLine().trim());
        int m = Integer.parseInt(sc.nextLine().trim());

        double[][] points = new double[m][3];
        for (int i = 0; i < m; i++) {
            String[] parts = sc.nextLine().trim().split("\\s+");
            points[i][0] = Double.parseDouble(parts[0]);
            points[i][1] = Double.parseDouble(parts[1]);
            points[i][2] = Double.parseDouble(parts[2]);
        }

        for (int iter = 0; iter < iterations; iter++) {
            List<List<double[]>> clusters = new ArrayList<>();
            for (int i = 0; i < k; i++) {
                clusters.add(new ArrayList<>());
            }

            for (int p = 0; p < m; p++) {
                int bestC = -1;
                double bestDist = Double.MAX_VALUE;
                for (int i = 0; i < k; i++) {
                    double distSq = 0;
                    for (int j = 0; j < 3; j++) {
                        double diff = points[p][j] - centers[i][j];
                        distSq += diff * diff;
                    }
                    if (distSq < bestDist) {
                        bestDist = distSq;
                        bestC = i;
                    }
                }
                clusters.get(bestC).add(points[p]);
            }

            double[][] newCenters = new double[k][3];
            for (int i = 0; i < k; i++) {
                if (!clusters.get(i).isEmpty()) {
                    for (int j = 0; j < 3; j++) {
                        double sum = 0;
                        for (double[] pt : clusters.get(i)) {
                            sum += pt[j];
                        }
                        newCenters[i][j] = sum / clusters.get(i).size();
                    }
                } else {
                    newCenters[i] = centers[i].clone();
                }
            }
            centers = newCenters;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < k; i++) {
            sb.append(roundHalfUp(centers[i][0]));
            sb.append(" ");
            sb.append(roundHalfUp(centers[i][1]));
            sb.append(" ");
            sb.append(roundHalfUp(centers[i][2]));
            sb.append("\n");
        }
        System.out.print(sb);
    }
}

第二题:动态区间的多项式岭回归

难度:较高

涉及知识点: 时间序列分析、岭回归建模、动态区间确定、矩阵运算、二阶多项式拟合

题目描述

某大型互联网公司的网管中心,记录了其核心服务在连续 N 天内的出口总流量(单位 GB,取值范围通常在 100 到 500.00 之间),

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

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

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

全部评论

相关推荐

哎,这两周面试一共才面了6+1场吧,多是中小厂,目前有一个offer但是不想去,因为问了问业务和要干的活,感觉是私人外包服务对接嵌入式前端的。感觉这几天对我的面试能力和八股能力大有提升,但是眼看时间一点点流逝,我还没有个能有个能学到真正的技术和工程化开发流程的实习,就很焦虑,看了看牛客,黑盒,xhs,感觉自己水的同时还非常菜,面对27真正找实习的人来说,感觉实力还是不足的,但是这周没有面试了,也没有地方去实习,一点点浪费时间。所以请牛油们,大佬们,帮我看看怎么样具体细化,还有什么优化空间。现在也很绝望的一件事就是如果没有找到实习,暑假不说了,秋招该怎么办,拉长战线我感觉我会死,充斥焦虑和无所事事的忙碌中,我的一种心理常常作祟:要不考研,要不就此摆烂。总之这两种悲观的声音时常是想让我放弃,一面是安逸的只需要学习就好的稳定,一面是敢于突破自我的历练,但是突破自我往往需要打破过往的舒适区,我现在的倾向肯定是找实习找工作,但是如果秋招前还是颗粒无收,我将何去何从,更何况AI发展如此迅速,谁知道半年之后的就业市场是风平浪静还是翻天覆地。对于考研我觉得半斤八两,考408非92出来照样跟现在情形无变,反而会错过机会,到时候就业人数肯定更多,市场肯定趋于饱和。
点赞 评论 收藏
分享
今天 17:01
门头沟学院 Java
程序员大奋:不好意思,打扰大家🙏我是一个拼多多骑手,小电驴的最大电量为C😭😭😭需要从x=0处走到x=L处,途中有n个充电站,🙏🙏每个充电站的距离和电价分别为di和pi,初始电量是满的😭😭😭请告诉我到达终点最少要花多少钱😭😭😭求求大家把这些钱转给我
拼多多集团-PDD笔试
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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