Flow & Operators Interview Questions
KOTLIN › Concurrency
For a search-as-you-type feature, you could use debounce, or you could use conflate plus manual dispatch. What's the actual behavioral difference, and why does debounce usually win for this use case?
What a strong answer covers: conflate drops intermediate values only when the collector is slower than the producer, keeping the latest value whenever the collector is ready, but it doesn't wait for any quiet period, so it can still fire a network call on every fast keystroke if the collector keeps pace. debounce actively waits for a pause of N milliseconds since the last emission before emitting anything downstream, which is the actual 'wait until the user stops typing' behavior a search box needs.
You have upstream.map { }.flowOn(Dispatchers.IO).filter { }.flowOn(Dispatchers.Default).collect { }. Walk me through which stage runs on which dispatcher and why stacking flowOn like this is a common source of confusion.
What a strong answer covers: Each flowOn only changes the context of the operators strictly upstream of it up to the previous flowOn boundary, so map runs on IO, filter runs on Default, and collect runs on whatever context the calling coroutine was already on, none of them run where you'd naively guess by just reading top to bottom. The confusion comes from assuming flowOn is like a global 'run everything below this on X' switch, when it actually only affects its own upstream segment, which is exactly why each flowOn call needs to be reasoned about independently.
You need to combine three independent data sources into one UI state and update as soon as any single source emits, without waiting for the others. Which operator fits, and what's the gotcha if one of those three sources is slow to produce its first value?
What a strong answer covers: combine is the right fit since it emits on any upstream update using the latest cached value from the others, but it won't emit anything at all until every upstream has emitted at least once, so a slow or silent source stalls the entire combined flow with no output. The fix is to seed each source with an initial value, for example via onStart { emit(default) } or by backing each source with a StateFlow that already has one, so combine can fire immediately instead of hanging.