Bird
Raised Fist0
Kotlinprogramming~20 mins

Coroutine scope and structured concurrency in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Coroutine Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of nested coroutine scopes
What is the output of this Kotlin code using coroutine scopes and structured concurrency?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(100)
        println("Task 1 done")
    }
    coroutineScope {
        launch {
            delay(50)
            println("Task 2 done")
        }
        println("Inside coroutineScope")
    }
    println("Outside coroutineScope")
}
A
Inside coroutineScope
Task 2 done
Task 1 done
Outside coroutineScope
B
Task 1 done
Task 2 done
Inside coroutineScope
Outside coroutineScope
C
Inside coroutineScope
Task 1 done
Task 2 done
Outside coroutineScope
D
Task 2 done
Inside coroutineScope
Task 1 done
Outside coroutineScope
Attempts:
2 left
💡 Hint
Remember that coroutineScope waits for all its child coroutines to complete before continuing.
❓ Predict Output
intermediate
2:00remaining
Effect of cancelling a parent coroutine scope
What will be printed when this Kotlin code runs?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val parentJob = launch {
        launch {
            delay(100)
            println("Child 1 finished")
        }
        launch {
            delay(200)
            println("Child 2 finished")
        }
    }
    delay(150)
    parentJob.cancel()
    delay(200)
    println("Done")
}
ADone
B
Child 1 finished
Child 2 finished
Done
C
Child 1 finished
Done
D
Child 2 finished
Done
Attempts:
2 left
💡 Hint
Cancelling a parent coroutine cancels all its children immediately.
🔧 Debug
advanced
2:00remaining
Identify the error in coroutine scope usage
This Kotlin code throws an exception. What is the cause?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = GlobalScope.launch {
        delay(100)
        println("Hello from GlobalScope")
    }
    job.join()
    println("Done")
}
ANo error; code runs and prints both lines.
BThe use of GlobalScope.launch breaks structured concurrency and may cause unexpected behavior.
Cjob.join() causes a deadlock in runBlocking.
DMissing coroutineScope block causes compilation error.
Attempts:
2 left
💡 Hint
GlobalScope is not tied to the lifecycle of runBlocking.
📝 Syntax
advanced
2:00remaining
Correct syntax for coroutineScope usage
Which option correctly uses coroutineScope to launch two child coroutines and waits for both to finish?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Fill in the blank
}
A
coroutineScope {
    launch { println("Child 1") }
    launch { println("Child 2") }
}
B
launch {
    coroutineScope {
        launch { println("Child 1") }
        launch { println("Child 2") }
    }
}
C
coroutineScope {
    launch { println("Child 1") }
}
launch { println("Child 2") }
D
runBlocking {
    launch { println("Child 1") }
    launch { println("Child 2") }
}
Attempts:
2 left
💡 Hint
coroutineScope waits for all child coroutines inside it to complete before returning.
🚀 Application
expert
2:00remaining
How many coroutines are active at peak in this code?
Consider this Kotlin code snippet. How many coroutines run concurrently at the peak?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        repeat(3) { i ->
            launch {
                delay(100L * i)
                println("Inner coroutine $i done")
            }
        }
    }
    launch {
        delay(50)
        println("Another coroutine done")
    }
}
A2
B3
C5
D4
Attempts:
2 left
💡 Hint
Count all coroutines launched that overlap in time at the peak.

Practice

(1/5)
1. What is the main purpose of a CoroutineScope in Kotlin?
easy
A. To block the main thread until coroutines finish
B. To create threads manually for parallel execution
C. To group coroutines and manage their lifecycle together
D. To convert coroutines into synchronous functions

Solution

  1. Step 1: Understand CoroutineScope role

    A CoroutineScope groups coroutines so they can be managed as one unit.
  2. Step 2: Compare other options

    The other options describe unrelated or incorrect behaviors for CoroutineScope.
  3. Final Answer:

    To group coroutines and manage their lifecycle together -> Option C
  4. Quick Check:

    CoroutineScope groups coroutines [OK]
Hint: CoroutineScope manages coroutines lifecycle as a group [OK]
Common Mistakes:
  • Thinking CoroutineScope creates threads
  • Confusing CoroutineScope with blocking calls
  • Assuming CoroutineScope converts coroutines to sync
2. Which of the following is the correct way to launch a coroutine within a CoroutineScope?
easy
A. scope.launch { /* coroutine code */ }
B. launch.scope { /* coroutine code */ }
C. CoroutineScope.launch { /* coroutine code */ }
D. scope.run { /* coroutine code */ }

Solution

  1. Step 1: Recall coroutine launch syntax

    Within a CoroutineScope, you call launch as a function on the scope instance.
  2. Step 2: Check options for syntax correctness

    scope.launch { /* coroutine code */ } uses scope.launch {} which is correct. Others misuse syntax or functions.
  3. Final Answer:

    scope.launch { /* coroutine code */ } -> Option A
  4. Quick Check:

    launch is called on CoroutineScope instance [OK]
Hint: Use scope.launch { } to start coroutine inside scope [OK]
Common Mistakes:
  • Swapping order like launch.scope
  • Using run instead of launch
  • Calling launch as a static method
3. What will be the output of this Kotlin code snippet?
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        delay(100)
        println("Task done")
    }
    println("Waiting")
    job.join()
    println("Finished")
}
medium
A. Task done\nWaiting\nFinished
B. Waiting\nTask done\nFinished
C. Waiting\nFinished\nTask done
D. Finished\nWaiting\nTask done

Solution

  1. Step 1: Analyze coroutine launch and delay

    The coroutine launched delays 100ms before printing "Task done". Meanwhile, "Waiting" prints immediately.
  2. Step 2: Understand job.join() effect

    The main coroutine waits for the launched job to finish before printing "Finished".
  3. Final Answer:

    Waiting\nTask done\nFinished -> Option B
  4. Quick Check:

    Output order respects delay and join [OK]
Hint: join() waits for coroutine to finish before continuing [OK]
Common Mistakes:
  • Assuming launched coroutine runs instantly
  • Ignoring delay effect
  • Printing Finished before job completes
4. Identify the problem in this Kotlin coroutine code and choose the correct fix:
fun main() = runBlocking {
    val job = GlobalScope.launch {
        delay(1000)
        println("Done")
    }
    println("Waiting")
}
medium
A. Replace delay(1000) with Thread.sleep(1000)
B. Use CoroutineScope().launch {} instead of GlobalScope.launch
C. Remove runBlocking and use GlobalScope.launch only
D. Add job.join() after println("Waiting")

Solution

  1. Step 1: Identify lifecycle issue with GlobalScope

    Using GlobalScope.launch starts coroutine that may outlive runBlocking, so "Done" may never print.
  2. Step 2: Fix by waiting for job completion

    Calling job.join() ensures main coroutine waits for launched coroutine to finish before exiting.
  3. Final Answer:

    Add job.join() after println("Waiting") -> Option D
  4. Quick Check:

    join() waits for coroutine to complete [OK]
Hint: Always join launched jobs to wait for completion [OK]
Common Mistakes:
  • Ignoring job.join() causing premature exit
  • Replacing delay with blocking sleep
  • Removing runBlocking causing main to exit early
5. Given this Kotlin code using structured concurrency, what will be printed?
import kotlinx.coroutines.*

fun main() = runBlocking {
    try {
        coroutineScope {
            launch {
                delay(100)
                println("Child 1 done")
            }
            launch {
                delay(50)
                throw RuntimeException("Error in Child 2")
            }
        }
    } catch (e: Exception) {
        println("Caught: " + e.message)
    }
    println("End of main")
}
hard
A. Caught: Error in Child 2\nEnd of main
B. Child 1 done\nCaught: Error in Child 2\nEnd of main
C. Caught: Error in Child 2
D. Child 1 done\nEnd of main

Solution

  1. Step 1: Understand coroutineScope behavior on exceptions

    If any child coroutine throws an exception, coroutineScope cancels all children and throws the exception.
  2. Step 2: Analyze timing and cancellation

    Child 2 throws after 50ms, cancelling Child 1 before it prints. The exception is caught and message printed.
  3. Final Answer:

    Caught: Error in Child 2\nEnd of main -> Option A
  4. Quick Check:

    Exception cancels siblings, caught prints message [OK]
Hint: Exception cancels sibling coroutines in coroutineScope [OK]
Common Mistakes:
  • Assuming Child 1 prints despite cancellation
  • Missing try-catch around coroutineScope
  • Thinking exceptions are ignored in coroutineScope
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