Android Kotlin Multiplatform Interview Questions

Shared code, expect/actual, targets, and interop.

50 questions in this topic · 8 sample questions below

Practice Kotlin Multiplatform in the quiz engine

Sample questions

  1. Which source set holds code that is compiled against every declared target and may use only APIs available on all of them?

    • androidMain, which is shared only with the Android target
    • An intermediateMain source set generated separately per module
    • commonMain, compiled against every declared target — correct
    • sharedMain, a reserved name required by the Kotlin Gradle plugin

    Why: commonMain is compiled for all targets and is restricted to APIs common to them, so it is where truly shared code lives. sharedMain is not a special reserved name, and androidMain is platform-specific rather than shared.

  2. What is the primary role of an expect declaration in common code?

    • To declare an API in common code that each target must supply a matching actual implementation for — correct
    • To provide a runtime interface resolved by dependency injection at startup
    • To mark a function as abstract so unrelated subclasses can override it
    • To defer compilation of a declaration until link time on the JVM only

    Why: expect/actual is resolved at compile time per target, so every target compiling the common source set must provide an actual. It is not a runtime interface picked by DI, nor a JVM-only linking trick.

  3. Since Kotlin 1.7.20 with the new Kotlin/Native memory manager, how do you share a mutable object between threads?

    • You must call freeze() to make it immutable before sharing it
    • Sharing mutable state is impossible; only frozen objects may cross threads
    • You must wrap it in an AtomicReference and freeze the whole object graph
    • You can share it directly; object freezing has been removed and objects are no longer frozen automatically — correct

    Why: The new memory manager removed the freezing requirement, so objects move between threads without being frozen and freeze() is deprecated. The requirement to freeze before sharing was the old model and is the misconception here.

  4. How are Kotlin suspend functions exposed to Swift and Objective-C by default in the generated framework?

    • As blocking synchronous calls that the caller must manually move off the main thread
    • As functions taking a completion handler, callable from Swift with async/await — correct
    • As Combine publishers generated automatically for each suspend function
    • They are not exported; suspend functions are stripped from the Objective-C header

    Why: The Kotlin/Native compiler exposes a suspend function with a completion-handler signature that Swift can call using async/await, so it is neither blocking nor stripped. Automatic Combine publishers are not part of the default export.

  5. What is a known limitation when consuming Kotlin generics from Swift through the Objective-C interop framework?

    • Generic classes are fully preserved, including declaration-site variance and where-constraints
    • Kotlin generics become Swift protocols with associated types automatically
    • Objective-C interop erases much generic information, so Swift often sees them as loosely typed Any or AnyObject — correct
    • Generics cause a compile error and must be rewritten as reified inline functions

    Why: Because export flows through Objective-C, generic type information is largely erased and Swift sees weakly typed APIs. It does not preserve full variance, nor convert every generic into an associated-type protocol, nor fail to compile.

  6. Why might launching a coroutine on Dispatchers.Main work in a shared module on Android but fail at runtime on iOS if misconfigured?

    • Dispatchers.Main on iOS relies on the main run loop and the multiplatform coroutines dependency; without proper setup it throws about a missing main dispatcher — correct
    • iOS has no concept of a main thread, so Dispatchers.Main is simply unavailable there
    • Dispatchers.Main on Native always silently falls back to Dispatchers.Default
    • Coroutines are unsupported on Kotlin/Native and must be replaced with Grand Central Dispatch

    Why: Dispatchers.Main is backed by the platform main queue and needs the multiplatform coroutines artifact plus a running run loop. iOS does have a main thread and coroutines are supported on Native, so the other options are false.

  7. Which of the following is generally NOT shareable in commonMain and must live in platform source sets?

    • kotlinx.serialization annotated model classes
    • Direct use of platform UI toolkit types such as UIView or android.view.View — correct
    • Ktor HTTP client request-building logic
    • SQLDelight-generated query code

    Why: Platform UI types exist only in their platform source sets, so they cannot be referenced from commonMain. Serialization models, Ktor logic, and SQLDelight queries are all explicitly designed to be shared.

  8. What does the default hierarchy template, enabled by default in recent Kotlin versions, provide?

    • It auto-generates actual implementations for every expect declaration you write
    • It merges androidMain and iosMain into a single platform source set
    • It disables commonMain in favor of per-target main source sets
    • It creates intermediate source sets such as iosMain automatically based on the targets you declare — correct

    Why: The default hierarchy template wires up intermediate source sets, for example an iosMain shared by the iOS device and simulator targets, from your target list. It neither generates actuals nor collapses platform main sets together.

Practice all 50 Kotlin Multiplatform questions

These 8 are a sample. The full Kotlin Multiplatform bank is scored, tracks your progress, and explains every answer.

Open the quiz

More Android interview topics