# Kotlin 2.3 voor Android: Naamgebaseerde Destructurering, KMP en Sollicitatievragen 2026 > Kotlin 2.3 sollicitatievragen over naamgebaseerde destructurering, Kotlin Multiplatform, contextparameters, coroutines en Flow. Voorbereiding op Android-ontwikkelaarsgesprekken in 2026 met praktische codevoorbeelden. - Published: 2026-05-06 - Updated: 2026-05-06 - Author: SharpSkill - Tags: kotlin, android, interview, kmp, kotlin-multiplatform, coroutines - Reading time: 5 min --- Kotlin 2.3 sollicitatievragen behoren in 2026 tot de meest gezochte onderwerpen voor Android-ontwikkelaarsposities. Met naamgebaseerde destructureringsdeclaraties, gestabiliseerde contextparameters en een volwassen Kotlin Multiplatform-ecosysteem verwachten interviewers dat kandidaten deze functionaliteiten beheersen. > **Wat verandert in Kotlin 2.3** > > Kotlin 2.3.20, uitgebracht in maart 2026, introduceert naamgebaseerde destructureringsdeclaraties, wijzigingen in de overload-resolutie voor contextparameters en verbeterde KMP-interoperabiliteit met C en TypeScript. Deze features komen regelmatig terug in senior Android-sollicitatiegesprekken. ## Naamgebaseerde destructurering: de meestgestelde Kotlin 2.3 sollicitatievraag Voor Kotlin 2.3 waren destructureringsdeclaraties gebaseerd op positiegebonden `componentN()`-functies. Dit veroorzaakte een bekend probleem: het wijzigen van de volgorde van properties in een data class brak bestaande destructureringspunten zonder waarschuwing. De klassieke sollicitatievraag presenteert precies dit 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 lost dit op met naamgebaseerde destructurering. Drie compilermodi bepalen het gedrag: ```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") } } ``` In de `complete`-modus gebruiken ronde haakjes naamgebaseerde matching, terwijl vierkante haakjes het positiegebaseerde gedrag behouden: ```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) } ``` Een sterk antwoord in een sollicitatiegesprek legt alle drie de modi uit en identificeert wanneer elke modus van toepassing is: `only-syntax` voor geleidelijke migratie, `name-mismatch` voor het opsporen van bugs in bestaande code en `complete` voor nieuwe projecten. ## Kotlin Multiplatform sollicitatievragen voor Android-ontwikkelaars KMP heeft de experimentele fase achter zich gelaten. Google ondersteunt het officieel voor het delen van bedrijfslogica tussen Android en iOS, en de meeste nieuwe cross-platform projecten hanteren standaard een shared-core-architectuur. Een typische sollicitatievraag luidt: "Hoe zou je een KMP-module structureren voor gedeelde 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 beoordelen of de kandidaat het expect/actual-mechanisme, platformspecifieke afhankelijkheden en de grens tussen gedeelde en platformspecifieke code begrijpt. Een andere veelgestelde vraag gaat over [Swift Export](https://kotlinlang.org/docs/whatsnew2320.html), dat in 2026 aanzienlijk is doorontwikkeld. Kotlin suspend-functies worden nu rechtstreeks gemapt op Swift async/await, en sealed classes komen overeen met Swift enums met bijbehorende waarden. ## Contextparameters en wijzigingen in de overload-resolutie Contextparameters vervangen de verouderde context receivers API. Kotlin 2.3.20 introduceerde een breaking change in de overload-resolutie: declaraties met contextparameters worden niet langer behandeld als specifieker dan declaraties zonder. ```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 gebruiken dit onderwerp om het bewustzijn van breaking changes en migratiestrategieën te toetsen. De kernboodschap: vertrouwen op impliciete contextparameterresolutie om niet-contextuele overloads te overschaduwen, werkt niet meer. ## Coroutines en Flow: nog steeds het belangrijkste Android-sollicitatieonderwerp Ondanks de nieuwe functies in Kotlin 2.3 blijven coroutines en Flow het meest geteste gebied. Sollicitatievragen onderzoeken doorgaans het verschil tussen cold en hot flows, structured concurrency en 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") } } ``` Een vervolgvraag gaat vaak over het veilig verzamelen van flows 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") } } } } ``` De `WhileSubscribed(5000)`-strategie houdt de upstream 5 seconden actief nadat de laatste subscriber is verdwenen, waardoor onnodige herstarts tijdens configuratiewijzigingen zoals schermrotatie worden voorkomen. ## Sealed classes en exhaustive when: pattern matching in sollicitatiegesprekken Sealed classes verschijnen in vrijwel elk Android-sollicitatiegesprek. De vraag verzoekt kandidaten doorgaans om een UI-state te modelleren: ```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 zijn `when`-expressies over sealed types exhaustief tijdens compilatie. Het toevoegen van een nieuw subtype dwingt af dat het overal wordt afgehandeld, waardoor een hele categorie runtime-bugs wordt geëlimineerd. Interviewers controleren specifiek of de kandidaat `sealed interface` (niet `sealed class`) gebruikt voor dit patroon, omdat interfaces flexibelere hiërarchieën mogelijk maken. ## Kotlin/Wasm en cross-platform compilatiedoelen Kotlin/Wasm heeft de Beta-status bereikt en biedt bijna-native prestaties in browsers. Hoewel het voor Android-ontwikkelaars nog geen dagelijks onderwerp is, wordt het wel gevraagd bij bedrijven met web- en mobiele producten. Belangrijke feiten voor het sollicitatiegesprek: - Kotlin 2.3.20 leverde 4,6x snellere string-interpolatie in Wasm via JS String builtins - Binaire grootten zijn met ongeveer 5% afgenomen - Clean builds draaien 65% sneller, incrementele builds 21% sneller - De `@nativeInvoke`-annotatie stelt Kotlin-objecten in staat om als JavaScript-functies te fungeren Kotlin/JS kreeg bovendien de mogelijkheid om Kotlin-interfaces vanuit TypeScript te implementeren, waarmee een eerdere beperking werd opgeheven. In combinatie met SWC-ondersteuning voor transpilatie dekt Kotlin nu Android, iOS (via KMP), Web (via Wasm/JS) en server-side doelen vanuit één enkele codebase. ## Scope functions: een misleidend eenvoudig sollicitatiefilter Scope functions (`let`, `run`, `with`, `apply`, `also`) lijken eenvoudig maar onderscheiden ervaren Kotlin-ontwikkelaars. De sollicitatievraag luidt doorgaans: "Wanneer gebruik je `let` in plaats van `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) } } ``` Het besliskader: `apply` voor objectconfiguratie (retourneert de receiver), `let` voor null-veilige transformaties (retourneert het lambda-resultaat), `also` voor neveneffecten (retourneert de receiver), `run` voor het berekenen van een resultaat met receivercontext. ## Null safety en het gevaar van de double-bang-operator Null safety blijft een fundamenteel sollicitatieonderwerp. De vraag "Waarom is `!!` gevaarlijk?" test of een kandidaat het typesysteem van Kotlin werkelijk begrijpt. ```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" } ``` Een volledig antwoord vermeldt dat `!!` alleen in testcode of op platforminterop-grenzen mag voorkomen, waar null daadwerkelijk onmogelijk is. ## Conclusie - Naamgebaseerde destructurering in Kotlin 2.3.20 elimineert positieafhankelijke bugs. Alle drie de compilermodi moeten bekend zijn: `only-syntax`, `name-mismatch`, `complete` - KMP is productiestabiel in 2026. Vragen over expect/actual, gedeelde module-architectuur en Swift Export-interoperabiliteit zijn te verwachten - Contextparameters hebben context receivers vervangen. De wijziging in de overload-resolutie in 2.3.20 is een veelgebruikte strikvraag - Coroutines en Flow domineren Android-sollicitatiegesprekken. Beheersing van `StateFlow` vs `SharedFlow`, `WhileSubscribed` en structured concurrency is vereist - Sealed interfaces modelleren UI-state met compile-time exhaustiviteit. Gebruik `sealed interface` boven `sealed class` - Scope functions vereisen een duidelijk besliskader: receiver vs argument, retourwaarde vs receiver - Null safety is niet onderhandelbaar. Kunnen uitleggen waarom `!!` het typesysteem ondermijnt en alternatieven kunnen demonstreren --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/nl/blog/android/kotlin-2-3-interview-questions