skip to content

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 pageshow

explore

questions

113 · 6 sections

A hand-written stream source emits a failure signal and then keeps pushing values — which rule does that break?

level: juniorimportance: must knowfreq 70%
basics
~20 s

The 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.

open as a page

A chat screen builds a message stream but no request is sent — what act starts the work, and what does it return?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Subscribing 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.

open as a page

What has happened when a source declared to carry at most one value completes without emitting a value?

level: juniorimportance: must knowfreq 65%
basics
~20 s

Nothing 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.

open as a page

Three dashboard panels subscribe to one source built around a query, and that query runs three times - why?

level: middleimportance: must knowfreq 70%
basics
~10 s

The 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.

open as a page

Two workers in a hand-written stream source push values to one subscriber concurrently — why does the contract forbid that?

level: middleimportance: must knowfreq 58%
basics
~20 s

Signals 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.

open as a page

A checkout display joins a scan feed and a price feed: why does lockstep pairing emit fewer results than latest-value combination?

level: juniorimportance: must knowfreq 58%
basics
~20 s

Lockstep 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.

open as a page

In a stream pipeline, how do a mapping step, a predicate filter, and a running-total accumulator differ?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A 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.

open as a page

A stream pipeline assembled once at start-up writes a log line immediately, before any run — why?

level: middleimportance: must knowfreq 62%
basics
~20 s

Building 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.

open as a page

In a two-source join, what happens to the output when one source completes early or emits nothing at all?

level: middleimportance: must knowfreq 62%
basics
~20 s

It 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.

open as a page

A moderation queue classifies each arriving item with an external call: what does concatenating those calls sequentially cost against merging them concurrently?

level: middleimportance: must knowfreq 72%
basics
~20 s

Sequential 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.

open as a page

In a log-shipping pipeline whose hold between reader and slow archival writer has no capacity limit, what fails and when?

level: middleimportance: must knowfreq 66%
basics
~20 s

An 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.

open as a page

In a demand-driven stream, a consumer requests 10 values, then 5 more before any arrive — what may the producer send?

level: middleimportance: must knowfreq 68%
basics
~20 s

Up 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.

open as a page

A vehicle-position feed and a settlement-instruction feed both outrun their consumers - why can one discard values and the other not?

level: middleimportance: must knowfreq 58%
basics
~20 s

Classify 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.

open as a page

A bounded buffer in a stream pipeline fills up - what do drop-newest, keep-latest and fail-fast each sacrifice?

level: middleimportance: must knowfreq 66%
basics
~20 s

Bounded 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.

open as a page

A fixed-interval clock source emits a tick whether or not the consumer asked for one — where must flow control live instead?

level: middleimportance: must knowfreq 60%
basics
~20 s

Flow 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.

open as a page

Why does one pipeline stage calling a synchronous routine that waits slow down unrelated requests sharing its worker pool?

level: middleimportance: must knowfreq 64%
basics
~20 s

A parked worker is unavailable to every subscription that shares it. Asynchronous pipelines multiplex many requests over a pool sized to the processor count, so a few simultaneous waits occupy every worker and unrelated routes queue behind them.

open as a page

Why does a tenant id stashed in per-worker ambient storage come back empty after a pipeline stage hops workers?

level: middleimportance: must knowfreq 64%
basics
~20 s

Ambient 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.

open as a page

Why would you deliberately run a pipeline stage on the calling thread, with no execution-context hop at all?

level: middleimportance: must knowfreq 52%
basics
~20 s

A 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.

open as a page

In a reactive media pipeline, how do you choose the execution context for a decode stage versus a stage that waits on remote storage?

level: middleimportance: must knowfreq 64%
basics
~20 s

Match 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.

open as a page

Why does assigning a stream pipeline to a pool of many workers still leave its elements processed one at a time?

level: middleimportance: must knowfreq 58%
basics
~20 s

A 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.

open as a page

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?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Retrying 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.

open as a page

An observe-only hook in a stream logs every failure signal that passes it — what does the hook change about that signal?

level: middleimportance: must knowfreq 58%
basics
~20 s

An 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.

open as a page

In a product-page pipeline, what happens to the formatting stages between a failing price lookup and a recovery step placed last?

level: middleimportance: must knowfreq 62%
basics
~20 s

Nothing 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.

open as a page

Your dispatcher resubscribes on every carrier failure without limit; what must a retry decision take into account before it resubscribes again?

level: middleimportance: must knowfreq 58%
basics
~20 s

A 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.

open as a page

A stream-based import validates ten thousand address rows and row twelve signals a failure — what happens to rows thirteen onward?

level: middleimportance: must knowfreq 72%
basics
~10 s

Nothing 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.

open as a page

In a fulfilment pipeline, picking sends packing an asynchronous message instead of calling it — what does picking wait for?

level: juniorimportance: must knowfreq 60%
basics
~10 s

Only 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.

open as a page

Why does asynchronous data flow buy nothing measurable for an internal admin tool with a dozen concurrent users?

level: middleimportance: must knowfreq 60%
basics
~20 s

Asynchronous 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.

open as a page

In a fulfilment system, what distinguishes a message-driven boundary between packing and shipping from an event-driven one?

level: middleimportance: must knowfreq 72%
basics
~10 s

Addressing. 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.

open as a page

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?

level: seniorimportance: must knowfreq 55%
basics
~20 s

All 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.

open as a page

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?

level: seniorimportance: must knowfreq 62%
basics
~20 s

A 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.

open as a page