Bird
Raised Fist0
Kotlinprogramming~20 mins

Coroutine context and dispatchers in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Coroutine Context Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this coroutine dispatcher code?
Consider the following Kotlin coroutine code snippet. What will be printed to the console?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch(Dispatchers.Default) {
        println("Running on: ${Thread.currentThread().name}")
    }.join()
}
ARunning on: IO-1
BRunning on: DefaultDispatcher-worker-1
CRunning on: main
DRunning on: CommonPool-worker-1
Attempts:
2 left
💡 Hint
Think about which thread the Default dispatcher uses in Kotlin coroutines.
❓ Predict Output
intermediate
2:00remaining
What is the value of 'result' after this coroutine context merge?
Given the following Kotlin code, what will be the value of 'result' printed?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val context1 = Dispatchers.Default + CoroutineName("First")
    val context2 = Dispatchers.IO + CoroutineName("Second")
    val mergedContext = context1 + context2
    println("CoroutineName: ${mergedContext[CoroutineName]?.name}")
}
ACoroutineName: Default
BCoroutineName: First
CCoroutineName: null
DCoroutineName: Second
Attempts:
2 left
💡 Hint
When merging contexts, the last CoroutineName overrides the previous one.
🔧 Debug
advanced
2:00remaining
Identify the error in this coroutine dispatcher usage
What error will this Kotlin coroutine code produce when run?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch(Dispatchers.Main) {
        println("Hello from Main")
    }.join()
}
Ajava.lang.IllegalStateException: Module with the Main dispatcher is missing.
BNo error, prints 'Hello from Main'
Cjava.lang.NullPointerException
Djava.lang.IllegalArgumentException: Dispatcher not found
Attempts:
2 left
💡 Hint
Dispatchers.Main requires a special setup in JVM environments.
🧠 Conceptual
advanced
1:30remaining
Which dispatcher is best for CPU-intensive tasks?
In Kotlin coroutines, which dispatcher is designed to efficiently handle CPU-intensive work?
ADispatchers.Unconfined
BDispatchers.IO
CDispatchers.Default
DDispatchers.Main
Attempts:
2 left
💡 Hint
Think about which dispatcher uses a shared pool of threads optimized for CPU work.
❓ Predict Output
expert
3:00remaining
What is the output of this nested coroutine context example?
Analyze the following Kotlin code and determine what will be printed to the console.
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val outerContext = Dispatchers.Default + CoroutineName("Outer")
    val job = launch(outerContext) {
        println("Outer context: ${coroutineContext[CoroutineName]?.name}")
        withContext(Dispatchers.IO + CoroutineName("Inner")) {
            println("Inner context: ${coroutineContext[CoroutineName]?.name}")
            println("Inner dispatcher: ${coroutineContext[CoroutineDispatcher]}")
        }
        println("Back to outer context: ${coroutineContext[CoroutineName]?.name}")
    }
    job.join()
}
A
Outer context: Outer
Inner context: Inner
Inner dispatcher: Dispatchers.IO
Back to outer context: Outer
B
Outer context: Outer
Inner context: Outer
Inner dispatcher: Dispatchers.Default
Back to outer context: Outer
C
Outer context: Outer
Inner context: Inner
Inner dispatcher: Dispatchers.Default
Back to outer context: Inner
D
Outer context: Outer
Inner context: Inner
Inner dispatcher: Dispatchers.IO
Back to outer context: Inner
Attempts:
2 left
💡 Hint
withContext changes both dispatcher and CoroutineName temporarily inside the block.

Practice

(1/5)
1. Which dispatcher should you use in Kotlin coroutines to perform heavy CPU-intensive tasks?
easy
A. Dispatchers.Default
B. Dispatchers.IO
C. Dispatchers.Main
D. Dispatchers.Unconfined

Solution

  1. Step 1: Understand dispatcher roles

    Dispatchers.Default is designed for CPU-intensive work like calculations.
  2. Step 2: Match task type to dispatcher

    Heavy CPU tasks should use Dispatchers.Default to avoid blocking UI or IO threads.
  3. Final Answer:

    Dispatchers.Default -> Option A
  4. Quick Check:

    CPU work = Dispatchers.Default [OK]
Hint: Use Default for CPU tasks, IO for disk/network, Main for UI [OK]
Common Mistakes:
  • Using Dispatchers.IO for CPU tasks
  • Using Dispatchers.Main for background work
  • Confusing Dispatchers.Unconfined with Default
2. Which of the following is the correct syntax to launch a coroutine on the IO dispatcher in Kotlin?
easy
A. launch(Dispatchers.Background) { /* code */ }
B. launch(Dispatchers.Default) { /* code */ }
C. launch(Dispatchers.Main) { /* code */ }
D. launch(Dispatchers.IO) { /* code */ }

Solution

  1. Step 1: Identify correct dispatcher name

    Dispatchers.IO is the correct dispatcher for IO tasks.
  2. Step 2: Check syntax correctness

    launch(Dispatchers.IO) { /* code */ } is valid Kotlin coroutine syntax.
  3. Final Answer:

    launch(Dispatchers.IO) { /* code */ } -> Option D
  4. Quick Check:

    IO dispatcher syntax = launch(Dispatchers.IO) { /* code */ } [OK]
Hint: Use Dispatchers.IO exactly as shown to launch IO coroutines [OK]
Common Mistakes:
  • Using non-existent Dispatchers.Background
  • Mixing up Dispatchers.Default and Dispatchers.IO
  • Forgetting braces or parentheses
3. What will be the output of this Kotlin coroutine code snippet?
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch(Dispatchers.Default) {
        println("Running on: " + Thread.currentThread().name)
    }.join()
}
medium
A. Running on: DefaultDispatcher-worker-1
B. Running on: main
C. Running on: IO-thread-1
D. Running on: Unconfined

Solution

  1. Step 1: Identify dispatcher thread naming

    Dispatchers.Default uses a shared pool named like DefaultDispatcher-worker-n.
  2. Step 2: Check printed thread name

    The coroutine runs on a background thread named DefaultDispatcher-worker-1 or similar.
  3. Final Answer:

    Running on: DefaultDispatcher-worker-1 -> Option A
  4. Quick Check:

    Default dispatcher thread name = Running on: DefaultDispatcher-worker-1 [OK]
Hint: Default dispatcher runs on worker threads, not main [OK]
Common Mistakes:
  • Assuming it runs on main thread
  • Confusing IO dispatcher thread names
  • Expecting Unconfined dispatcher output
4. Identify the error in this Kotlin coroutine code snippet:
fun main() = runBlocking {
    launch(Dispatchers.Main) {
        println("Hello from Main")
    }
}
medium
A. println is not allowed inside coroutines
B. Dispatchers.Main cannot be used in runBlocking without a UI environment
C. launch must be called with Dispatchers.Default
D. Missing join() call on launched coroutine

Solution

  1. Step 1: Understand Dispatchers.Main requirements

    Dispatchers.Main requires a UI thread environment (like Android or JavaFX).
  2. Step 2: Check runBlocking context

    runBlocking runs on the main thread but usually outside UI context, so Dispatchers.Main is invalid here.
  3. Final Answer:

    Dispatchers.Main cannot be used in runBlocking without a UI environment -> Option B
  4. Quick Check:

    Main dispatcher needs UI thread = Dispatchers.Main cannot be used in runBlocking without a UI environment [OK]
Hint: Use Dispatchers.Main only in UI apps with proper environment [OK]
Common Mistakes:
  • Assuming Dispatchers.Main works everywhere
  • Forgetting to join coroutine before main ends
  • Thinking println is disallowed in coroutines
5. You want to perform a network request in a Kotlin coroutine and then update the UI with the result. Which dispatcher combination should you use to ensure correct threading?
hard
A. launch(Dispatchers.Default) { val data = fetchData(); updateUI(data) }
B. launch(Dispatchers.Main) { val data = fetchData(); updateUI(data) }
C. launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } }
D. launch(Dispatchers.IO) { val data = fetchData(); updateUI(data) }

Solution

  1. Step 1: Identify correct dispatcher for network request

    Network requests should run on Dispatchers.IO to avoid blocking the main thread.
  2. Step 2: Switch to Main dispatcher for UI update

    UI updates must happen on Dispatchers.Main to safely update UI components.
  3. Step 3: Analyze code structure

    launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } correctly uses Dispatchers.IO for fetching and withContext(Dispatchers.Main) for UI update.
  4. Final Answer:

    launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } -> Option C
  5. Quick Check:

    IO for network + Main for UI = launch(Dispatchers.IO) { val data = fetchData(); withContext(Dispatchers.Main) { updateUI(data) } } [OK]
Hint: Use IO for background, switch to Main for UI updates [OK]
Common Mistakes:
  • Updating UI on IO or Default dispatcher
  • Running network request on Main dispatcher
  • Not switching context before UI update
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard