华为ai算法笔试 华为秋招 华为笔试题 1017

笔试时间:2025年10月17日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

【背景信息】在现代运维体系中,大量告警可能指向同一故障根源(如"服务器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)数据结构高效处理连通关系:

  1. 异常情况处理:检查输入是否为空,向量维度是否一致
  2. 使用并查集管理聚类关系,具有传递性
  3. 计算余弦相似度:cosine_similarity = dot(v1,v2) / (||v1|| * ||v2||)
  4. 遍历所有告警对,如果相似度≥0.95,合并它们所在的类
  5. 统计每个连通分量的大小,返回最大值

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 春招笔试合集 文章被收录于专栏

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

全部评论

相关推荐

水瓶子010209:我去,这倒提醒我了,我记得我做得也不赖,我得回去看看,明个要去现眼了
点赞 评论 收藏
分享
野猪不是猪🐗:还是太卑微了,什么叫放弃本次面试应该说经过评估,贵公司与自己不匹配,决定不再推进后续流程
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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