PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates the ability to implement a stateful, concurrent alert execution engine, focusing on skills such as periodic task scheduling, concurrency control, external API interaction, and state-transition detection for threshold-based notifications.

  • medium
  • Palo
  • Coding & Algorithms
  • Software Engineer

Implement an Alert Execution Engine

Company: Palo

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

You are given an alert client API that provides alert configurations, metric query execution, and notification methods. Implement an alert execution engine. ### Alert configuration Each alert has: - `name`: unique alert name - `query`: metric query string to execute - `criticalThreshold`: numeric threshold - `intervalSeconds`: how often this alert should be evaluated - `thresholdMessage`: message to include when the alert fires Alert configurations are loaded once at startup by calling `GetAlerts`. You may assume alert configurations never change while the engine is running. ### Alert evaluation cycle For each alert, the engine must periodically execute one evaluation cycle according to that alert's interval: 1. Call `ExecuteQuery(query)` to get the current metric value. 2. Compare the returned value with the alert's critical threshold. 3. Determine the alert state: - `PASS` if `value <= criticalThreshold` - `CRITICAL` if `value > criticalThreshold` 4. If the alert is in `CRITICAL` state, call `Notify(alertName, thresholdMessage)`. 5. If the alert transitions from `CRITICAL` to `PASS`, call `Resolve(alertName)`. ### Requirements - Multiple alerts must be evaluated independently. - Each alert must run on its own configured interval. - The engine must remember each alert's previous state so it can detect transitions back to `PASS`. - Alerts are loaded only once at engine startup. - You may use the provided fake client for testing. The fake query API may return values in round-robin order for each query. Implement the alert execution engine and demonstrate that it correctly sends notifications and resolves alerts as metric values cross the threshold.

Quick Answer: This question evaluates the ability to implement a stateful, concurrent alert execution engine, focusing on skills such as periodic task scheduling, concurrency control, external API interaction, and state-transition detection for threshold-based notifications.

Implement a deterministic simulation of an alert execution engine. At startup, the engine receives alert configurations. Alert i is defined by names[i], queries[i], critical_thresholds[i], interval_seconds[i], and threshold_messages[i]. Each alert must be evaluated immediately at time 0, then again every interval_seconds[i] seconds until total_seconds, inclusive. For each evaluation cycle, simulate ExecuteQuery(query) by reading the next metric value from query_values[query]. Values are returned in round-robin order per query string, so alerts sharing the same query consume from the same cursor. Compare the returned value with the alert threshold: PASS if value <= critical_threshold, CRITICAL if value > critical_threshold. If an alert is CRITICAL, simulate Notify(alertName, thresholdMessage) by appending an event string formatted as 'time:NOTIFY:alertName:thresholdMessage'. Notify is called on every CRITICAL evaluation, even if the alert was already CRITICAL. If an alert transitions from CRITICAL to PASS, simulate Resolve(alertName) by appending 'time:RESOLVE:alertName'. Do not resolve an alert that starts in PASS. When multiple alerts are due at the same time, evaluate them in increasing input index order.

Constraints

  • 0 <= n <= 10^4
  • names, queries, critical_thresholds, interval_seconds, and threshold_messages all have length n
  • Alert names are unique
  • 1 <= interval_seconds[i] <= 10^9
  • -10^9 <= critical_thresholds[i] <= 10^9
  • 0 <= total_seconds <= 10^9
  • Every query used by an alert appears in query_values and maps to a non-empty list
  • All metric values are integers between -10^9 and 10^9
  • The total number of alert evaluations is at most 200000
  • Alert names and threshold messages do not contain ':'

Examples

Input: (['cpu_high'], ['cpu'], [80], [10], ['CPU high'], {'cpu': [50, 85, 90, 70, 95]}, 40)

Expected Output: ['10:NOTIFY:cpu_high:CPU high', '20:NOTIFY:cpu_high:CPU high', '30:RESOLVE:cpu_high', '40:NOTIFY:cpu_high:CPU high']

Explanation: The alert is evaluated at 0, 10, 20, 30, and 40 seconds. Values 85, 90, and 95 are above 80, so notifications are sent. At time 30 the value drops to 70 after being critical, so the alert resolves.

Input: (['errors', 'latency'], ['err', 'lat'], [5, 200], [15, 10], ['Too many errors', 'Latency high'], {'err': [1, 7, 3], 'lat': [250, 180, 220, 210]}, 30)

Expected Output: ['0:NOTIFY:latency:Latency high', '10:RESOLVE:latency', '15:NOTIFY:errors:Too many errors', '20:NOTIFY:latency:Latency high', '30:RESOLVE:errors', '30:NOTIFY:latency:Latency high']

Explanation: The two alerts run on different intervals. At time 30 both are due, so errors is evaluated first because it has the smaller input index.

Input: ([], [], [], [], [], {}, 100)

Expected Output: []

Explanation: There are no alerts to schedule or evaluate.

Input: (['disk'], ['disk_used'], [10], [5], ['Disk above 10'], {'disk_used': [10, 11, 10]}, 10)

Expected Output: ['5:NOTIFY:disk:Disk above 10', '10:RESOLVE:disk']

Explanation: A value equal to the threshold is PASS. The alert fires at time 5 when the value is 11, then resolves at time 10 when the value returns to 10.

Input: (['a', 'b'], ['shared', 'shared'], [5, 5], [10, 10], ['A high', 'B high'], {'shared': [6, 4, 7, 3]}, 10)

Expected Output: ['0:NOTIFY:a:A high', '10:NOTIFY:a:A high']

Explanation: Both alerts use the same query, so they share one round-robin cursor. Alert a consumes 6 and 7, both critical; alert b consumes 4 and 3, both passing.

Hints

  1. Treat each alert as an independent scheduled task. A priority queue keyed by next evaluation time can avoid scanning every second.
  2. Keep two kinds of state: the previous PASS/CRITICAL state per alert, and the round-robin cursor per query string.
Last updated: Jun 19, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Find Maximum Rectangle in Bar Chart - Palo (medium)
  • Find minimum tanks to cover all houses - Palo (medium)
  • Implement three whiteboard coding tasks - Palo (easy)