华为OD机试真题 Java 实现【告警抑制】【2023 B卷 100分】,附详细解题思路
发布人:shili8
发布时间:2025-02-22 13:39
阅读次数:0
**华为OD机试真题 Java 实现【告警抑制】【2023 B卷100分】**
**一、题目描述**
在一个监控系统中,存在多个设备,每个设备都有自己的告警阈值。当某个设备的数据超过其阈值时,就会产生告警。为了避免过度告警,我们需要设计一个抑制机制,使得当某个设备连续多次产生告警时,只在第一次告警后一定时间内不再产生告警。
**二、题目要求**
1. 设计一个告警抑制系统,能够记录每个设备的告警历史,并根据阈值和历史数据决定是否产生新的告警。
2. 系统需要支持多个设备,每个设备都有自己的阈值和历史数据。
3. 当某个设备连续多次产生告警时,只在第一次告警后一定时间内不再产生告警。
**三、解题思路**
1. 设计一个`Device`类,代表每个设备。该类包含以下属性:
* `id`:设备ID* `threshold`:阈值* `alarmHistory`:告警历史列表2. 设计一个`AlarmSuppressor`类,负责管理所有设备的告警抑制逻辑。
3. 在`AlarmSuppressor`类中,维护一个`deviceMap`,用于存储每个设备的当前状态(是否正在抑制告警)。
4. 当某个设备产生新告警时,首先检查其历史数据是否超过一定时间内连续多次告警。如果是,则进入抑制模式。
5. 在抑制模式下,不再产生新的告警,但仍然记录历史数据。
**四、Java代码实现**
javaimport java.util.*;
// 设备类class Device {
private int id;
private double threshold; // 阈值 private List alarmHistory; // 告警历史列表 public Device(int id, double threshold) {
this.id = id;
this.threshold = threshold;
this.alarmHistory = new ArrayList<>();
}
public int getId() {
return id;
}
public double getThreshold() {
return threshold;
}
public List getAlarmHistory() {
return alarmHistory;
}
}
// 告警类class Alarm {
private long timestamp; // 告警时间戳 public Alarm(long timestamp) {
this.timestamp = timestamp;
}
public long getTimestamp() {
return timestamp;
}
}
// 告警抑制器类public class AlarmSuppressor {
private Map deviceMap; // 设备映射表 private int suppressDuration; // 抑制时间 public AlarmSuppressor(int suppressDuration) {
this.suppressDuration = suppressDuration;
this.deviceMap = new HashMap<>();
}
public void addDevice(Device device) {
deviceMap.put(device.getId(), device);
}
public void produceAlarm(Device device, long timestamp) {
// 检查设备是否正在抑制告警 if (isSuppressing(device)) {
System.out.println("设备 " + device.getId() + " 正在抑制告警,忽略新告警");
return;
}
//产生新告警 Alarm alarm = new Alarm(timestamp);
device.getAlarmHistory().add(alarm);
// 检查历史数据是否超过一定时间内连续多次告警 if (isContinuousAlarm(device, suppressDuration)) {
System.out.println("设备 " + device.getId() + " 连续多次产生告警,进入抑制模式");
setSuppressing(device);
}
}
private boolean isSuppressing(Device device) {
return deviceMap.get(device.getId()).getSuppressing();
}
private void setSuppressing(Device device) {
device.setSuppressing(true);
}
private boolean isContinuousAlarm(Device device, int suppressDuration) {
List alarmHistory = device.getAlarmHistory();
long currentTime = System.currentTimeMillis();
// 检查历史数据是否超过一定时间内连续多次告警 for (Alarm alarm : alarmHistory) {
if (currentTime - alarm.getTimestamp() > suppressDuration *1000) {
return false;
}
}
return true;
}
}
**五、测试代码**
javapublic class Main {
public static void main(String[] args) {
AlarmSuppressor suppressor = new AlarmSuppressor(10); // 抑制时间为10 秒 Device device1 = new Device(1,100);
Device device2 = new Device(2,200);
suppressor.addDevice(device1);
suppressor.addDevice(device2);
//产生新告警 suppressor.produceAlarm(device1, System.currentTimeMillis());
suppressor.produceAlarm(device1, System.currentTimeMillis() +10000); //10 秒后再次产生新告警 // 检查设备是否正在抑制告警 System.out.println("设备 " + device1.getId() + " 是否正在抑制告警:" + suppressor.isSuppressing(device1));
}
}
**六、总结**
本题目要求设计一个告警抑制系统,能够记录每个设备的告警历史,并根据阈值和历史数据决定是否产生新的告警。我们通过设计一个`Device`类和一个`AlarmSuppressor`类来实现这个需求。在`AlarmSuppressor`类中,我们维护一个`deviceMap`,用于存储每个设备的当前状态(是否正在抑制告警)。当某个设备产生新告警时,我们首先检查其历史数据是否超过一定时间内连续多次告警。如果是,则进入抑制模式。在抑制模式下,不再产生新的告警,但仍然记录历史数据。

