华为ai算法笔试 华为秋招 华为笔试题 1017
笔试时间:2025年10月17日
往年笔试合集:
第一题
【背景信息】在现代运维体系中,大量告警可能指向同一故障根源(如"服务器CPU利用率过高"和"应用响应超时"可能由同一硬件资源不足导致)。若能将语义相似的告警归为一类,不仅可以减少重复信息的干扰,还能帮助运维人员快速定位故障核心,缩短故障修复时间。
行业内普遍采用自然语言处理(NLP)技术对告警文本进行语义理解,采用基于预训练语言模型(如BERT、sBERT等)的语义向量(embedding)转化技术:通过模型处理,每条告警文本被转化为一个高维数值向量,向量的数学特征能够准确反映告警的语义信息,使得两条描述相同故障的告警(即使措辞有差异),其对应的向量在空间中的距离会非常靠近;而语义无关的告警,向量距离则较远。
【任务目标】通过语义向量(embedding)对给定的告警信息进行聚类:每条告警包含唯一的ID和对应的向量embedding,要求将余弦相似度≥0.95的告警归为同一个聚类,并返回数量最大的聚类的告警数量。
【规则要求】聚类判定标准:1)相似度阈值:当两条告警的余弦相似度≥0.95时,判定为语义相似。2)弱传递聚类(连通图聚类)规则:
- 初始状态:每条告警单独构成一个类别。
- 归入规则:若告警A与某类别C中的任意一条告警的余弦相似度≥0.95,则将A归入类别C。
- 合并规则:若告警A同时满足归入多个类别的条件(即与多个类别中的告警均相似),则这些类别需合并为一个新类别,A归入该新类别。
- 传递性保证:聚类过程需确保所有满足相似条件的告警最终被合并到同一类别中。例如:若A与B相似(余弦相似度≥0.95),且B与C相似(余弦相似度≥0.95),则A、B、C必须属于同一类别(即使A与C的相似度可能<0.95)。
输入描述
每一行为一个告警信息,其中第一个字段是告警ID,后面的字段是告警的嵌入向量。告警信息的总行数不会超过1000条。(请注意,测试集中可能包含如样例2所示的那种异常情况)
输出描述
找到包含告警数量最多的聚类,输出该聚类的告警数量。若所有告警均无法聚类(即每个类别仅包含1条告警),则返回1;若输入为空列表(无任何告警),或者输入告警信息的向量维度不一致(即不同告警的embedding长度不同),则返回0。
样例输入
1 1.0 0.0 0.0
2 0.99 0.01 0.0
3 0.0 1.0 0.0
4 0.0 1.0 0.01
5 0.1 0.0 0.0
样例输出
3
样例说明1
根据余弦相似度≥0.95的规则,我们得到以下聚类关系:
- 告警1、2、5构成一个聚类
- 告警3、4构成一个聚类 所有聚类的大小分别为3、2,其中数量最大的为3,因此输出为3。
参考题解
解题思路:
将告警文本的语义向量进行聚类,使用并查集(Union-Find)数据结构高效处理连通关系:
- 异常情况处理:检查输入是否为空,向量维度是否一致
- 使用并查集管理聚类关系,具有传递性
- 计算余弦相似度:cosine_similarity = dot(v1,v2) / (||v1|| * ||v2||)
- 遍历所有告警对,如果相似度≥0.95,合并它们所在的类
- 统计每个连通分量的大小,返回最大值
Python:
import sys import math from collections import Counter p = [] def f(x): if p[x] == x: return x p[x] = f(p[x]) return p[x] def u(a, b): ra = f(a) rb = f(b) if ra != rb: p[rb] = ra def sim(v1, v2): s = 0.0 m1 = 0.0 m2 = 0.0 for i in range(len(v1)): s += v1[i] * v2[i] m1 += v1[i] * v1[i] m2 += v2[i] * v2[i] m1 = math.sqrt(m1) m2 = math.sqrt(m2) if m1 == 0 or m2 == 0: return 0.0 return s / (m1 * m2) def work(): global p data = [] dim = -1 while True: line = sys.stdin.readline() if not line: break line = line.strip() if not line: continue parts = line.split() vec = [float(x) for x in parts[1:]] if not vec: print(0) return if dim == -1: dim = len(vec) elif len(vec) != dim: print(0) return data.append(vec) if not data: print(0) return n = len(data) if n == 1: print(1) return p = list(range(n)) for i in range(n): for j in range(i + 1, n):
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南