Reactive Programming
Programming with streams that push values over time, operators that transform them, and demand that stops a fast producer drowning a slow consumer. Interviewers raise it for event-driven services.
on this pageshowhide
explore
- Observable Streams18 questions
- Signal Contract4 questions
- Cold and Hot Sources5 questions
- Subscription Lifecycle5 questions
- Value Cardinality4 questions
- Operators23 questions
- Element Transformation4 questions
- Flattening Strategies5 questions
- Combining Sources5 questions
- Time and Windowing5 questions
- Assembly and Execution4 questions
- Backpressure18 questions
- Demand Signalling4 questions
- Overflow Strategies5 questions
- Unbounded Buffer Collapse5 questions
- Producers That Cannot Slow4 questions
- Schedulers & Threading23 questions
- Subscribe and Observe Sides5 questions
- Execution Contexts5 questions
- Blocking a Pipeline4 questions
- Contextual Data Across Hops4 questions
- Parallel Execution5 questions
- Error Handling17 questions
- Terminal Failure Semantics4 questions
- Recovery and Fallback4 questions
- Retry by Resubscription4 questions
- Failure Visibility5 questions
- Reactive Systems14 questions
- Manifesto Properties5 questions
- Message-Driven Boundaries5 questions
- Cost and Fit4 questions
questions
113 · 6 sectionsA hand-written stream source emits a failure signal and then keeps pushing values — which rule does that break?
basics
~20 sThe signal grammar: a run carries any number of value signals and then at most one terminal signal, completion or failure, never both. A failure is that ending, not another value, so the source must go silent after it.
A chat screen builds a message stream but no request is sent — what act starts the work, and what does it return?
basics
~20 sSubscribing starts the work; building a stream only describes it. A subscription call attaches a subscriber to the source, triggers whatever the source does to produce values, and hands back a handle the caller uses to cancel that run.
What has happened when a source declared to carry at most one value completes without emitting a value?
basics
~20 sNothing was found and nothing failed: empty completion is a third outcome beside a value and a failure. The caller must decide what absence means here - a default, a fallback source, or an error it raises itself.
Three dashboard panels subscribe to one source built around a query, and that query runs three times - why?
basics
~10 sThe source is cold: it describes work instead of sharing a sequence that is already running, so every subscriber starts a fresh, independent run. Three panels subscribed, so the query executed three times.
Two workers in a hand-written stream source push values to one subscriber concurrently — why does the contract forbid that?
basics
~20 sSignals must be delivered one at a time, with each one seeing what the previous one wrote. Every stage downstream is written on that promise and keeps its accumulated state unsynchronised, so overlapping deliveries corrupt it.
A checkout display joins a scan feed and a price feed: why does lockstep pairing emit fewer results than latest-value combination?
basics
~20 sLockstep pairing consumes one value from each source per result, so its rate is the slowest source's rate. Latest-value combination keeps each source's most recent value and emits on every arrival, so its rate is the sum of all rates.
In a stream pipeline, how do a mapping step, a predicate filter, and a running-total accumulator differ?
basics
~20 sA mapping step returns exactly one output element per input; a predicate filter returns zero or one, dropping the rest; a running accumulator emits a value derived from every element seen so far, so it carries state between elements.
A stream pipeline assembled once at start-up writes a log line immediately, before any run — why?
basics
~20 sBuilding the chain runs ordinary code. The expressions handed to each step are evaluated as the chain is described, so a log line or a computed value written there fires once at assembly, not on each later run of the pipeline.
In a two-source join, what happens to the output when one source completes early or emits nothing at all?
basics
~20 sIt depends on the joining rule. Lockstep pairing ends as soon as a completed source's queue is empty, discarding whatever is buffered elsewhere. Latest-value combination keeps going on the completed source's last value until all sources complete. A source that emits nothing leaves the output empty.
A moderation queue classifies each arriving item with an external call: what does concatenating those calls sequentially cost against merging them concurrently?
basics
~20 sSequential concatenation keeps one call in flight: results arrive in queue order, throughput is capped at one call per call-latency. Bounded merging runs several at once, trading that ordering for throughput and putting the bound's worth of load on the dependency.
In a log-shipping pipeline whose hold between reader and slow archival writer has no capacity limit, what fails and when?
basics
~20 sAn unbounded hold converts a sustained rate mismatch into memory exhaustion. Every line the writer cannot take is retained, so the pipeline behaves normally for as long as the spare memory lasts, then the process dies all at once.
In a demand-driven stream, a consumer requests 10 values, then 5 more before any arrive — what may the producer send?
basics
~20 sUp to 15 values, and not one more. Requests accumulate additively into a single outstanding count, each delivered value spends one unit, and the producer is barred from sending a sixteenth value until the consumer asks again.
A vehicle-position feed and a settlement-instruction feed both outrun their consumers - why can one discard values and the other not?
basics
~20 sClassify the item first. A position is a snapshot that the next one supersedes, so discarding intermediates costs the consumer nothing. A settlement instruction has an effect of its own that no later item re-derives, so discarding it is a lost transfer.
A bounded buffer in a stream pipeline fills up - what do drop-newest, keep-latest and fail-fast each sacrifice?
basics
~20 sBounded buffering spends memory and adds latency and only postpones the decision; dropping the newest arrival sacrifices freshness; keeping only the latest sacrifices every superseded value; failing fast sacrifices availability but is the only one that reports the loss.
A fixed-interval clock source emits a tick whether or not the consumer asked for one — where must flow control live instead?
basics
~20 sFlow control moves into the adapter wrapping the source. A clock cannot wait for demand, so the adapter decides each tick's fate: discard it, overwrite a stored latest value, or hold it in a bounded buffer.
Why does a tenant id stashed in per-worker ambient storage come back empty after a pipeline stage hops workers?
basics
~20 sAmbient storage is attached to the worker, not to the request: a read resolves against whatever worker is executing right now. Once a stage runs on a different worker, nothing ever wrote that worker's slot.
Why would you deliberately run a pipeline stage on the calling thread, with no execution-context hop at all?
basics
~20 sA hop is not free: it enqueues the value, wakes another worker and adds latency for every element. For a short non-blocking stage, running inline on whichever worker delivered the value costs less than moving the work somewhere else.
In a reactive media pipeline, how do you choose the execution context for a decode stage versus a stage that waits on remote storage?
basics
~20 sMatch the worker to where a stage spends its time. Compute-bound decoding belongs on a small fixed pool sized near the processor count; a stage that spends its wall-clock time waiting on remote storage belongs on an elastic pool that can grow.
Why does assigning a stream pipeline to a pool of many workers still leave its elements processed one at a time?
basics
~20 sA reactive sequence is serial by contract: values reach each stage one at a time, in order, however many workers the execution context owns. That choice decides which worker runs a stage, never how many elements run at once.
When a notification pipeline that loads a recipient, records an attempt and calls a carrier is retried after the carrier fails, which steps run again?
basics
~20 sRetrying resubscribes to the source, so every stage above the retry point runs again from the start: the recipient is loaded a second time, a second attempt record is written, and the carrier is called again.
An observe-only hook in a stream logs every failure signal that passes it — what does the hook change about that signal?
basics
~20 sAn observe-only hook changes nothing about the signal. It is a tap: it sees the failure, records it, and lets the same failure continue downstream, so the sequence still ends and every later stage still sees it.
In a product-page pipeline, what happens to the formatting stages between a failing price lookup and a recovery step placed last?
basics
~20 sNothing runs in them. A failure signal travels past every stage that only handles values, so the formatting stages are skipped and the substituted value enters the sequence below them — it must therefore already be in the shape the subscriber expects.
Your dispatcher resubscribes on every carrier failure without limit; what must a retry decision take into account before it resubscribes again?
basics
~20 sA retry decision needs three inputs: the kind of failure, since some can never clear; a bound on attempts, as a count or a deadline; and some space between attempts. When the bound is reached, the failure must reach the subscriber.
A stream-based import validates ten thousand address rows and row twelve signals a failure — what happens to rows thirteen onward?
basics
~10 sNothing processes them. A failure signal is terminal: it ends the sequence at row twelve and releases the subscription, so the source is never asked for rows thirteen onward and nothing downstream sees them.
In a fulfilment pipeline, picking sends packing an asynchronous message instead of calling it — what does picking wait for?
basics
~10 sOnly for the message to be accepted for delivery, not for packing to run. Picking holds no thread and no result, and hears about the outcome only if a later message tells it.
Why does asynchronous data flow buy nothing measurable for an internal admin tool with a dozen concurrent users?
basics
~20 sAsynchronous data flow buys capacity, not speed: it stops workers being parked while waiting on input and output. A tool with a dozen users never runs out of workers, so there is no parked capacity to reclaim.
In a fulfilment system, what distinguishes a message-driven boundary between packing and shipping from an event-driven one?
basics
~10 sAddressing. A message is directed at a named recipient and expresses intent toward it; an event is a broadcast fact about what already happened, addressed to nobody, which zero or many observers may consume.
Which of the four reactive system properties does a service fail to deliver if it uses asynchronous streams internally but calls every dependency with a blocking request?
basics
~20 sAll four remain unclaimed, because the four properties are claims about the boundary between components and that boundary is still synchronous. Internal streams buy more concurrent conversations per worker, which is a capacity gain, not one of the properties.
A ticket site's on-sale dashboard shows a healthy mean response time while buyers report waits - what measurement would actually prove the system is responsive?
basics
~20 sA high percentile of one named request, measured over every outcome including timeouts and refusals, at a stated arrival rate, across the spike window. Responsiveness is a bounded tail under load, not a healthy average.