Problem
A stream of transaction events arrives for many homes, possibly out of order and with retries. Each Event has (eventId, homeId, ts, status). Build a Processor whose process(List<Event>) does three things: ignore duplicate eventIds (first occurrence wins), apply each home's events in TIMESTAMP order regardless of input order, and skip events whose status is not a known transaction status — recording those skipped ones. Then finalByHome() returns each home's status from its latest valid event by ts, duplicatesIgnored() returns how many duplicate-eventId events were dropped, and invalid() returns the recorded invalid events. Valid statuses: LISTED, OFFER_MADE, UNDER_CONTRACT, CLOSED, CANCELLED.
Restate the problem in one sentence and list the edge cases — before writing any code.
Then keep talking — restate the problem + the edge cases in your own words.
“Let me make sure I understand the problem, then I'll walk through my approach.”
checking microphone…
Self-check
Hints / what this doesn't test
An Opendoor-flavored ingestion problem: a noisy event stream (out-of-order arrival,
retried/duplicated events, garbage statuses) has to collapse into one clean answer
per home. Restate the three jobs before you code — "So I dedup by eventId
first-wins, then per home I take the status from the event with the largest ts,
and anything with an unknown status I skip but keep in a list?"
Why the naive starter is wrong (name the bugs out loud): it writes homeId -> status in input order, so (1) the last-seen event wins instead of the latest-by-ts
event, (2) a retried eventId overwrites and is never counted, and (3) a garbage
status like TELEPORTED is treated as a real terminal state. All three are the
classic ingestion failures: no idempotency, no event-time ordering, no input
validation.
What this problem does not test (say so): late-arriving events after a "final"
read (watermarks), tie-breaking when two valid events share the exact same ts,
state-transition legality (is LISTED -> CLOSED even allowed?), and durable/streaming
processing. A senior names that the batch group-and-sort here becomes a per-home
last-write-wins on an event-time watermark once this is a real stream rather than a
list you hold in memory.
Tests
- ○out_of_order_resolved_by_ts
- ○duplicate_eventId_ignored
- ○final_status_per_home
- ○invalid_recorded