A practice prompt we wrote. No company or candidate report names it, so it carries no company tag.
How to answer
“Unbounded” is the word to answer. The stream never ends, so the interviewer is checking what your memory grows with. Say the bound you are aiming for before you write a class: memory grows with the number of active keys, never with the event rate.
- Pin the semantics. Ask whether the five minutes are measured in event time or arrival time, and say your choice: event time, a half-open window ending at the newest timestamp seen so far, the watermark. Say that the watermark is shared by every key, and what that costs. Ask whether averages are read on demand or pushed, and how late events can arrive.
- Pick the storage by its memory cost. A deque of raw events per key is exact, but it grows with the rate. One-second buckets, each a sum and a count, cost min(seconds with events, 300) per key whatever the rate, and the only error is at the trailing edge, where a whole second leaves at once. Keep only the seconds that have events, so a device that reports once a minute doesn’t pay for 300 empty slots. Say that trade out loud and let the interviewer pick.
- Keep a running sum and count. A read costs only the expiry since the last read, which never exceeds the live buckets, and never grows with the event rate. Eviction happens lazily as the watermark moves.
- Handle disorder by where the event lands. A late event still inside the window goes into its bucket. One older than the window cannot change any average you will report, so drop it and count it; a silent drop is the bug the customer finds first.
- Forget idle keys. A key whose window is empty costs as much as a missing one, so delete it.
- Test against a brute-force oracle on random, partly shuffled input, including keys that go quiet for longer than the window.
The trap is evicting by time.time(). Arrival time turns a backlog into a spike, and the same events replayed give different answers.
Follow-ups
What the interviewer may ask next, once your first answer is on the table.
- One device sends an event stamped a year in the future. What happens to every other key’s average, and how do you stop it?
- The customer now wants an average pushed for every key every few seconds, and wants late events to correct values already pushed. What changes?
- Memory is still too high at the customer’s key count. What do you give up next?
- They want the p95 over the same window instead of the mean. Which part of your design survives?
Where answers go wrong
- Keeps every raw event per key and sums the window on each query, so memory and time grow with the event rate, the one number an unbounded stream does not bound.
- Ages events out by the machine’s clock instead of their own timestamps, so a backlog or a replay produces different averages from the same events.
Answer this in two minutes
Write the answer you would say out loud. The clock starts with your first word.
Model answer
“I’ll use event time, a window (watermark - 300, watermark] in whole seconds, and on-demand reads. The watermark is shared, so a key’s average is over the last five minutes of stream time, not its own.