# Kotlin 2.3 for Android: Name-Based Destructuring, KMP and Interview Questions 2026 > Kotlin 2.3 interview questions covering name-based destructuring, Kotlin Multiplatform, context parameters, coroutines and Flow. Prepare for Android developer interviews in 2026 with real-world code examples. - Published: 2026-05-06 - Updated: 2026-05-06 - Author: SharpSkill - Tags: kotlin, android, interview, kmp, kotlin-multiplatform, coroutines - Reading time: 9 min --- Kotlin 2.3 interview questions now rank among the most searched topics for Android developer roles in 2026. With name-based destructuring declarations, stabilized context parameters, and a mature Kotlin Multiplatform ecosystem, interviewers expect candidates to demonstrate fluency in these features. > **What changed in Kotlin 2.3** > > Kotlin 2.3.20, released March 2026, introduces name-based destructuring declarations, overload resolution changes for context parameters, and improved KMP interop with C and TypeScript. These features appear frequently in senior Android interviews. ## Name-Based Destructuring: The Most Common Kotlin 2.3 Interview Question Before Kotlin 2.3, destructuring declarations relied on position-based `componentN()` functions. This created a well-known pitfall: swapping property order in a data class silently broke existing destructuring sites. The classic interview question presents this scenario: ```kotlin // User.kt data class User(val username: String, val email: String) fun main() { val user = User("alice", "alice@example.com") // Position-based: order matters, not names val (email, username) = user println(email) // Prints "alice" -- wrong! println(username) // Prints "alice@example.com" -- wrong! } ``` Kotlin 2.3.20 solves this with name-based destructuring. Three compiler modes control the behavior: ```kotlin // build.gradle.kts kotlin { compilerOptions { // Mode 1: Explicit syntax only freeCompilerArgs.add("-Xname-based-destructuring=only-syntax") // Mode 2: Warns on name mismatch // freeCompilerArgs.add("-Xname-based-destructuring=name-mismatch") // Mode 3: Full name-based by default // freeCompilerArgs.add("-Xname-based-destructuring=complete") } } ``` With `complete` mode, parentheses use name-based matching, and square brackets preserve position-based behavior: ```kotlin // NameBasedDestructuring.kt data class User(val username: String, val email: String) fun main() { val user = User("alice", "alice@example.com") // Name-based: matches by property name val (email, username) = user println(email) // "alice@example.com" -- correct println(username) // "alice" -- correct // Position-based: square brackets preserve old behavior val [first, second] = user println(first) // "alice" (component1) println(second) // "alice@example.com" (component2) } ``` A strong answer in an interview explains all three modes and identifies when each applies: `only-syntax` for gradual migration, `name-mismatch` for catching bugs in existing code, and `complete` for new projects. ## Kotlin Multiplatform Interview Questions for Android Developers KMP has moved past the experimental phase. Google officially supports it for sharing business logic between Android and iOS, and most new multi-platform projects adopt a shared-core architecture by default. A typical interview question asks: "How would you structure a KMP module for shared networking?" ```kotlin // shared/src/commonMain/kotlin/com/app/network/ApiClient.kt import io.ktor.client.* import io.ktor.client.request.* import io.ktor.client.statement.* import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json @Serializable data class UserProfile( val id: String, val displayName: String, val avatarUrl: String? ) // Expect/actual pattern for platform-specific HTTP engine expect fun createHttpClient(): HttpClient class ApiClient { private val client = createHttpClient() private val json = Json { ignoreUnknownKeys = true } // Suspend function shared across Android and iOS suspend fun fetchProfile(userId: String): UserProfile { val response = client.get("https://api.example.com/users/$userId") return json.decodeFromString(response.bodyAsText()) } } ``` ```kotlin // shared/src/androidMain/kotlin/com/app/network/HttpClient.android.kt import io.ktor.client.* import io.ktor.client.engine.okhttp.* // Android uses OkHttp engine actual fun createHttpClient(): HttpClient = HttpClient(OkHttp) { engine { config { retryOnConnectionFailure(true) } } } ``` Interviewers evaluate whether the candidate understands the expect/actual mechanism, platform-specific dependencies, and the boundary between shared and platform code. Another frequent question covers [Swift Export](https://kotlinlang.org/docs/whatsnew2320.html), which has evolved significantly in 2026. Kotlin suspend functions now map directly to Swift async/await, and sealed classes map to Swift enums with associated values. ## Context Parameters and Overload Resolution Changes Context parameters replace the deprecated context receivers API. Kotlin 2.3.20 introduced a breaking change in overload resolution: declarations with context parameters are no longer treated as more specific than those without. ```kotlin // ContextParameters.kt class Logger { fun info(msg: String) = println("INFO: $msg") } class TransactionScope { fun execute(block: () -> Unit) = block() } // Function with context parameter context(logger: Logger) fun saveUser(id: Int) { logger.info("Saving user $id") } // Overload without context -- now ambiguous in 2.3.20 fun saveUser(id: Int) { println("Saving user $id (no logger)") } fun main() { val logger = Logger() // This now produces an ambiguity error in Kotlin 2.3.20 // context(logger) { saveUser(1) } // Fix: rename or qualify the context-aware variant } ``` Interviewers use this topic to assess awareness of breaking changes and migration strategies. The key takeaway: relying on implicit context parameter resolution to shadow non-contextual overloads no longer works. ## Coroutines and Flow: Still the Top Android Interview Topic Despite Kotlin 2.3 introducing new features, coroutines and Flow remain the most tested area. Interview questions typically probe the difference between cold and hot flows, structured concurrency, and cancellation. ```kotlin // FlowComparison.kt import kotlinx.coroutines.* import kotlinx.coroutines.flow.* // Cold Flow: emits only when collected fun userUpdates(): Flow = flow { println("Flow started") // Runs per collector emit("User logged in") delay(1000) emit("User updated profile") } // Hot Flow: emits independently of collectors class UserRepository { // StateFlow holds the latest value private val _state = MutableStateFlow("idle") val state: StateFlow = _state.asStateFlow() // SharedFlow broadcasts to multiple collectors private val _events = MutableSharedFlow() val events: SharedFlow = _events.asSharedFlow() suspend fun login() { _state.value = "loading" delay(500) _state.value = "authenticated" _events.emit("login_success") } } ``` A follow-up question often asks about collecting flows safely in Android: ```kotlin // UserViewModel.kt import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch class UserViewModel(private val repo: UserRepository) : ViewModel() { // Expose state to Compose UI val uiState: StateFlow = repo.state .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5000), initialValue = "idle" ) init { // Collect events safely within ViewModel scope viewModelScope.launch { repo.events.collect { event -> // Handle one-time events println("Event received: $event") } } } } ``` The `WhileSubscribed(5000)` strategy keeps the upstream active for 5 seconds after the last subscriber disappears, preventing unnecessary restarts during configuration changes like screen rotation. ## Sealed Classes and Exhaustive When: Pattern Matching in Interviews Sealed classes appear in nearly every Android interview. The question typically asks candidates to model a UI state: ```kotlin // UiState.kt sealed interface UiState { data object Loading : UiState data class Success(val data: T) : UiState data class Error(val message: String, val retry: (() -> Unit)? = null) : UiState } // Usage in ViewModel fun loadUsers(): Flow>> = flow { emit(UiState.Loading) try { val users = apiClient.fetchUsers() emit(UiState.Success(users)) } catch (e: Exception) { emit(UiState.Error( message = e.localizedMessage ?: "Unknown error", retry = { /* trigger reload */ } )) } } ``` In Kotlin, `when` expressions over sealed types are exhaustive at compile time. Adding a new subtype forces handling it everywhere, which eliminates an entire category of runtime bugs. Interviewers specifically check that the candidate uses `sealed interface` (not `sealed class`) for this pattern, since interfaces allow more flexible hierarchies. ## Kotlin/Wasm and Cross-Platform Compilation Targets Kotlin/Wasm reached Beta status and brings near-native performance in browsers. While not yet a daily concern for Android developers, interviewers at companies with web+mobile products ask about it. Key facts for the interview: - Kotlin 2.3.20 delivered 4.6x faster string interpolation in Wasm through JS String builtins - Binary sizes dropped approximately 5% - Clean builds run 65% faster, incremental builds 21% faster - The `@nativeInvoke` annotation allows Kotlin objects to act as JavaScript functions Kotlin/JS also gained the ability to implement Kotlin interfaces from TypeScript, removing a previous limitation. Combined with SWC support for transpilation, Kotlin now covers Android, iOS (via KMP), Web (via Wasm/JS), and server-side targets from a single codebase. ## Scope Functions: A Deceptively Simple Interview Filter Scope functions (`let`, `run`, `with`, `apply`, `also`) appear simple but differentiate experienced Kotlin developers. The interview question usually asks: "When do you use `let` versus `apply`?" ```kotlin // ScopeFunctions.kt data class Request( var url: String = "", var method: String = "GET", var headers: MutableMap = mutableMapOf(), var body: String? = null ) fun buildRequest(): Request { // apply: configure an object, returns the object return Request().apply { url = "https://api.example.com/users" method = "POST" headers["Content-Type"] = "application/json" body = "{\"name\": \"Alice\"}" } } fun processNullable(input: String?) { // let: transform nullable, returns lambda result val length = input?.let { value -> println("Processing: $value") value.trim().length } ?: 0 // also: side effects, returns the original object input?.also { println("Logging input: $it") } // run: execute a block with receiver, returns lambda result val result = input?.run { // 'this' is the string uppercase().take(10) } } ``` The decision framework: `apply` for object configuration (returns receiver), `let` for null-safe transformations (returns lambda result), `also` for side effects (returns receiver), `run` for computing a result with receiver context. ## Null Safety and the Danger of Double-Bang Null safety remains a fundamental interview topic. The question "Why is `!!` dangerous?" tests whether a candidate truly understands Kotlin's type system. ```kotlin // NullSafety.kt fun findUser(id: String): User? { // Returns null if user not found return database.queryUser(id) } // Bad: !! defeats the purpose of null safety fun riskyApproach(id: String) { val user = findUser(id)!! // NullPointerException if null println(user.username) } // Good: handle null explicitly fun safeApproach(id: String) { val user = findUser(id) ?: run { println("User not found") return } println(user.username) } // Good: provide default with Elvis operator fun displayName(id: String): String { return findUser(id)?.username ?: "Anonymous" } ``` A complete answer mentions that `!!` should only appear in test code or platform interop boundaries where null is genuinely impossible. ## Conclusion - Name-based destructuring in Kotlin 2.3.20 eliminates position-dependent bugs. Know all three compiler modes: `only-syntax`, `name-mismatch`, `complete` - KMP is production-stable in 2026. Expect questions on expect/actual, shared module architecture, and Swift Export interop - Context parameters replaced context receivers. The overload resolution change in 2.3.20 is a common trick question - Coroutines and Flow dominate Android interviews. Master `StateFlow` vs `SharedFlow`, `WhileSubscribed`, and structured concurrency - Sealed interfaces model UI state with compile-time exhaustiveness. Prefer `sealed interface` over `sealed class` - Scope functions require a clear decision framework: receiver vs argument, return value vs receiver - Null safety is non-negotiable. Articulate why `!!` undermines the type system and demonstrate alternatives --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/en/blog/android/kotlin-2-3-interview-questions