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.

Kotlin 2.3 Android sollicitatievragen met destructurering en KMP-concepten

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:

User.ktkotlin
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:

build.gradle.ktskotlin
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:

NameBasedDestructuring.ktkotlin
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?"

shared/src/commonMain/kotlin/com/app/network/ApiClient.ktkotlin
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())
    }
}
shared/src/androidMain/kotlin/com/app/network/HttpClient.android.ktkotlin
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, 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.

ContextParameters.ktkotlin
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.

FlowComparison.ktkotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

// Cold Flow: emits only when collected
fun userUpdates(): Flow<String> = 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<String> = _state.asStateFlow()

    // SharedFlow broadcasts to multiple collectors
    private val _events = MutableSharedFlow<String>()
    val events: SharedFlow<String> = _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:

UserViewModel.ktkotlin
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<String> = 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.

Klaar om je Android gesprekken te halen?

Oefen met onze interactieve simulatoren, flashcards en technische tests.

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:

UiState.ktkotlin
sealed interface UiState<out T> {
    data object Loading : UiState<Nothing>
    data class Success<T>(val data: T) : UiState<T>
    data class Error(val message: String, val retry: (() -> Unit)? = null) : UiState<Nothing>
}

// Usage in ViewModel
fun loadUsers(): Flow<UiState<List<UserProfile>>> = 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?"

ScopeFunctions.ktkotlin
data class Request(
    var url: String = "",
    var method: String = "GET",
    var headers: MutableMap<String, String> = 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.

NullSafety.ktkotlin
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.

Begin met oefenen!

Test je kennis met onze gespreksimulatoren en technische tests.

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

Begin met oefenen!

Test je kennis met onze gespreksimulatoren en technische tests.

Tags

#kotlin
#android
#interview
#kmp
#kotlin-multiplatform
#coroutines

Delen

Gerelateerde artikelen