华为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 ListalarmHistory; // 告警历史列表 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`,用于存储每个设备的当前状态(是否正在抑制告警)。当某个设备产生新告警时,我们首先检查其历史数据是否超过一定时间内连续多次告警。如果是,则进入抑制模式。在抑制模式下,不再产生新的告警,但仍然记录历史数据。