Deep dive into launch vs async, CoroutineScope lifecycle, StateFlow vs SharedFlow, flowOn(), and structured concurrency.
0 / 5 completed
1 / 5
What is the difference between launch and async in Kotlin coroutines?
launch vs async: use launch when you do not need a return value (logging, updates). Use async when you need to run two computations in parallel and combine their results: val a = async { fetchA() }; val b = async { fetchB() }; a.await() + b.await().
2 / 5
What does CoroutineScope define?
CoroutineScope: every coroutine is launched in a scope. In Android, viewModelScope is cancelled when the ViewModel is cleared, automatically stopping any in-flight network calls or computations, preventing memory leaks and crashes from completed-but-still-running coroutines.
3 / 5
What is StateFlow and how does it differ from SharedFlow?
StateFlow vs SharedFlow: StateFlow is ideal for UI state — a new collector immediately gets the current state. SharedFlow is more general: MutableSharedFlow(replay = 0) delivers events without replay, suitable for one-shot events like navigation commands where you do not want late collectors to trigger an old event.
4 / 5
What does the flowOn(dispatcher) operator do?
flowOn:flow { emit(readFromDisk()) }.flowOn(Dispatchers.IO).map { parse(it) }.collect { ... }. The disk read runs on the IO dispatcher; the map and collect run on whatever scope launches the collection. Only upstream context is affected.
5 / 5
What is structured concurrency in Kotlin coroutines?
Structured concurrency: prevents "fire-and-forget" leaks. If a coroutine scope is cancelled (e.g. due to an exception), all children are cancelled. If a child throws, the exception propagates to the parent. This creates a predictable coroutine hierarchy where no background work outlives its owner.