华为笔试 华为笔试题 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等多种语言做法集合指南

全部评论

相关推荐

虽然&nbsp;0&nbsp;面试,没有&nbsp;offer&nbsp;消息,没有&nbsp;HR&nbsp;来电,甚至打开招聘软件依旧是一片安静,但我依然想认认真真地夸夸今天的自己。不是只有拿到面试、收到&nbsp;offer&nbsp;才叫努力,不是只有一路顺风、步步上岸才值得被肯定。在这个人人都晒进度、晒&nbsp;offer、晒上岸喜讯的春招里,愿意安静坚持、不放弃、不摆烂、认真过好每一天的你,已经超级棒了。今天的我,值得被夸,因为我按时起床了。没有赖床到中午,没有在焦虑里昏昏沉沉一整天,哪怕心里空空的、慌慌的,还是掀开被子,认真洗漱,给自己一个清醒的开始。对很多人来说,起床只是一件小事,可对正在求职、天天等待、反复内耗的我们来说,能从床上起来,就已经是战胜了情绪。今天的我,值得被夸,因为我认真投出了每一份简历。没有海投乱投敷衍自己,没有随便点一下投递就草草了事。我仔细看了岗位&nbsp;JD,确认了工作内容,核对了投递要求,哪怕只是一份普通的实习、一个基础的岗位,我也拿出了最真诚的态度。我知道,简历可能石沉大海,可能已读不回,可能连初筛都过不去,但我依然认认真真地完成了每一步。这种不敷衍、不放弃的坚持,比一时的结果更珍贵。今天的我,值得被夸,因为我静下心改完了简历。也许只是微调一句话,也许只是补充一段经历,也许只是把格式排得更整齐一点,但我没有拖延,没有逃避。我知道,一份好简历,是我们敲开机会的第一扇门。我一点点打磨,一点点完善,不着急、不焦躁,把能做的小事做到极致。如果你也和我一样,对着简历反复修改却总觉得不够好,不知道怎么匹配岗位、怎么突出亮点、怎么让&nbsp;HR&nbsp;一眼看到你的优势,真的可以试试泡泡小程序&nbsp;AiCV&nbsp;简历王。它不用你花大量时间研究技巧,就能帮你精准匹配&nbsp;JD、优化经历、梳理亮点,把普通的经历写出价值,把杂乱的排版变得专业。在我们连情绪都快撑不住的时候,有一个靠谱的工具帮我们减负,真的会轻松很多。我们已经够努力了,不必再在简历上独自死磕。今天的我,值得被夸,因为我没有内耗到崩溃。看到别人晒面试、晒&nbsp;offer,我也会羡慕,也会偷偷难过,也会忍不住问:为什么别人那么顺利,我却连一个面试都没有?是不是我不够好?是不是我再努力也没用?但我没有让情绪把自己吞没。我允许自己难过几分钟、叹几口气,然后告诉自己:不是我不够好,只是时机还没到,只是匹配的机会还在路上。我没有刷一晚上焦虑帖,没有整夜失眠自我否定,没有把自己困在&nbsp;“我不行”&nbsp;的怪圈里。能和情绪和平相处,能在低谷里拉住自己,你真的很强大。今天的我,值得被夸,因为我认真吃好了一日三餐。没有因为焦虑不吃早饭,没有因为等待随便啃面包,没有在低落里饿肚子。我好好吃饭,好好喝水,好好照顾自己的身体。求职这条路很难,可身体是我们最踏实的底气。哪怕全世界暂时还没看到我,我也要好好照顾自己。好好吃饭,好好生活,本身就是一种了不起的韧性。今天的我,值得被夸,因为我没有摆烂,没有躺平。我没有关掉招聘软件,没有删除求职群,没有对未来说&nbsp;“算了吧”。哪怕今天&nbsp;0&nbsp;面试、0&nbsp;进展、0&nbsp;消息,我依然保持着节奏,该学习学习,该复盘复盘,该准备面试准备面试。我知道,机会不是突然砸下来的,而是在无数个&nbsp;“没结果”&nbsp;的日子里,一点点攒出来的。别人看得见的是&nbsp;offer,看不见的是你无数个默默坚持的日常。今天的我,值得被夸,因为我依然对明天抱有期待。就算今天一无所获,就算眼前一片静悄悄,我也没有彻底失望。我相信,春招很长,机会很多,不是只有跑得快的人才能赢,能坚持到最后的人,同样会发光。我相信,我投出的每一份简历、改的每一个字、熬过的每一次情绪,都在悄悄铺路。也许明天,也许后天,也许下周,那个属于我的面试,就来了。我想把这些话,也送给正在看这篇文章的你。如果你今天&nbsp;0&nbsp;面试,没有消息,没有回应,甚至有点失落、有点迷茫,请一定停下来,好好夸夸自己。你值得被夸,因为你没有放弃。你值得被夸,因为你在默默努力。你值得被夸,因为你在情绪里依然保持清醒。你值得被夸,因为你认真生活,认真对待自己。我们总以为,只有成功才值得庆祝,只有上岸才值得骄傲。可人生不是只有高光时刻才&nbsp;meaningful,那些低谷里的坚持、迷茫里的不妥协、疲惫里的不垮掉,才是最珍贵的部分。春招不是短跑,是长跑。有人跑得快,有人跑得稳,有人跑得慢,但只要不停下来,就一定会到达终点。今天的你,也许没有面试,没有喜讯,没有惊喜。但你早起了,你投简历了,你改简历了,你好好吃饭了,你稳住情绪了,你没有放弃自己了。就凭这些,你已经很棒了。允许自己暂时没有结果,允许自己慢慢来,允许自己在安静里积蓄力量。你做的每一件小事,都在让你离梦想更近一点。最后,再认真地夸一次今天的自己:我真的很不错,我一直在努力,我值得更好的机会,我一定会上岸。也愿每一个正在春招里默默坚持的人:简历被认真看见,努力被温柔回应,期待终会落地,所有漫长的等待,都换来值得的结果。你已经很棒了,再坚持一下,好运正在赶来。
虽然0面试,但今天___...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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