# Kotlin 2.3 per Android: Destrutturazione Basata sui Nomi, KMP e Domande da Colloquio 2026 > Domande da colloquio su Kotlin 2.3 riguardanti la destrutturazione basata sui nomi, Kotlin Multiplatform, parametri di contesto, coroutine e Flow. Preparazione ai colloqui per sviluppatori Android nel 2026 con esempi di codice reali. - Published: 2026-05-06 - Updated: 2026-05-06 - Author: SharpSkill - Tags: kotlin, android, interview, kmp, kotlin-multiplatform, coroutines - Reading time: 5 min --- Le domande da colloquio su Kotlin 2.3 si posizionano tra gli argomenti più ricercati per le posizioni di sviluppatore Android nel 2026. Con le dichiarazioni di destrutturazione basate sui nomi, i parametri di contesto stabilizzati e un ecosistema Kotlin Multiplatform maturo, gli intervistatori si aspettano che i candidati dimostrino padronanza di queste funzionalità. > **Cosa cambia in Kotlin 2.3** > > Kotlin 2.3.20, rilasciato a marzo 2026, introduce le dichiarazioni di destrutturazione basate sui nomi, modifiche alla risoluzione degli overload per i parametri di contesto e una migliore interoperabilità KMP con C e TypeScript. Queste funzionalità compaiono frequentemente nei colloqui per posizioni Android senior. ## Destrutturazione basata sui nomi: la domanda più frequente su Kotlin 2.3 Prima di Kotlin 2.3, le dichiarazioni di destrutturazione si basavano sulle funzioni `componentN()` posizionali. Questo creava un problema ben noto: modificare l'ordine delle proprietà in una data class rompeva silenziosamente i punti di destrutturazione esistenti. La domanda classica da colloquio presenta esattamente questo 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 risolve il problema con la destrutturazione basata sui nomi. Tre modalità del compilatore controllano il comportamento: ```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") } } ``` Con la modalità `complete`, le parentesi tonde utilizzano il matching basato sui nomi, mentre le parentesi quadre preservano il comportamento posizionale: ```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) } ``` Una risposta convincente durante un colloquio spiega tutte e tre le modalità e identifica quando ciascuna è appropriata: `only-syntax` per la migrazione graduale, `name-mismatch` per individuare bug nel codice esistente e `complete` per i nuovi progetti. ## Domande su Kotlin Multiplatform per sviluppatori Android KMP ha superato la fase sperimentale. Google lo supporta ufficialmente per la condivisione della logica di business tra Android e iOS, e la maggior parte dei nuovi progetti multipiattaforma adotta un'architettura shared-core per impostazione predefinita. Una domanda tipica da colloquio chiede: "Come struttureresti un modulo KMP per il networking condiviso?" ```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) } } } ``` Gli intervistatori valutano se il candidato comprende il meccanismo expect/actual, le dipendenze specifiche della piattaforma e il confine tra codice condiviso e codice di piattaforma. Un'altra domanda frequente riguarda [Swift Export](https://kotlinlang.org/docs/whatsnew2320.html), che si è evoluto significativamente nel 2026. Le funzioni suspend di Kotlin ora si mappano direttamente su Swift async/await, e le sealed class corrispondono agli enum Swift con valori associati. ## Parametri di contesto e modifiche alla risoluzione degli overload I parametri di contesto sostituiscono la deprecata API dei context receivers. Kotlin 2.3.20 ha introdotto una breaking change nella risoluzione degli overload: le dichiarazioni con parametri di contesto non vengono più trattate come più specifiche rispetto a quelle senza. ```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 } ``` Gli intervistatori utilizzano questo argomento per valutare la consapevolezza dei candidati riguardo alle breaking change e alle strategie di migrazione. Il punto chiave: affidarsi alla risoluzione implicita dei parametri di contesto per sovrascrivere gli overload non contestuali non funziona più. ## Coroutine e Flow: ancora il tema principale nei colloqui Android Nonostante le novità introdotte da Kotlin 2.3, le coroutine e Flow rimangono l'area più testata. Le domande da colloquio esplorano tipicamente la differenza tra cold e hot flow, la structured concurrency e la 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") } } ``` Una domanda di follow-up chiede spesso come raccogliere i flow in modo sicuro 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") } } } } ``` La strategia `WhileSubscribed(5000)` mantiene l'upstream attivo per 5 secondi dopo la scomparsa dell'ultimo subscriber, evitando riavvii non necessari durante i cambiamenti di configurazione come la rotazione dello schermo. ## Sealed class e when esaustivo: il pattern matching nei colloqui Le sealed class compaiono in quasi tutti i colloqui Android. La domanda chiede tipicamente ai candidati di modellare uno stato dell'interfaccia utente: ```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, le espressioni `when` sui sealed type sono esaustive a tempo di compilazione. L'aggiunta di un nuovo sottotipo obbliga a gestirlo ovunque, eliminando un'intera categoria di bug a runtime. Gli intervistatori verificano specificamente che il candidato utilizzi `sealed interface` (non `sealed class`) per questo pattern, poiché le interfacce consentono gerarchie più flessibili. ## Kotlin/Wasm e target di compilazione cross-platform Kotlin/Wasm ha raggiunto lo stato Beta e offre prestazioni quasi native nei browser. Sebbene non sia ancora un tema quotidiano per gli sviluppatori Android, viene richiesto nelle aziende con prodotti web e mobile. Fatti chiave per il colloquio: - Kotlin 2.3.20 ha portato un'interpolazione di stringhe 4,6 volte più veloce in Wasm tramite JS String builtins - Le dimensioni dei binari sono diminuite di circa il 5% - I clean build sono il 65% più veloci, i build incrementali il 21% più veloci - L'annotazione `@nativeInvoke` permette agli oggetti Kotlin di funzionare come funzioni JavaScript Kotlin/JS ha inoltre acquisito la capacità di implementare interfacce Kotlin da TypeScript, rimuovendo una precedente limitazione. Combinato con il supporto SWC per la transpilazione, Kotlin copre ora Android, iOS (tramite KMP), Web (tramite Wasm/JS) e target server-side da un'unica base di codice. ## Scope function: un filtro insidiosamente semplice nei colloqui Le scope function (`let`, `run`, `with`, `apply`, `also`) sembrano semplici ma distinguono gli sviluppatori Kotlin esperti. La domanda da colloquio di solito chiede: "Quando si usa `let` rispetto ad `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) } } ``` Lo schema decisionale: `apply` per la configurazione degli oggetti (restituisce il receiver), `let` per le trasformazioni null-safe (restituisce il risultato della lambda), `also` per gli effetti collaterali (restituisce il receiver), `run` per calcolare un risultato con il contesto del receiver. ## Null safety e il pericolo del double-bang La null safety resta un argomento fondamentale nei colloqui. La domanda "Perché `!!` è pericoloso?" verifica se un candidato comprende davvero il sistema di tipi di Kotlin. ```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" } ``` Una risposta completa menziona che `!!` dovrebbe comparire solo nel codice di test o ai confini dell'interoperabilità con la piattaforma, dove il null è genuinamente impossibile. ## Conclusione - La destrutturazione basata sui nomi in Kotlin 2.3.20 elimina i bug dipendenti dalla posizione. Tutte e tre le modalità del compilatore devono essere conosciute: `only-syntax`, `name-mismatch`, `complete` - KMP è stabile in produzione nel 2026. Aspettarsi domande su expect/actual, architettura dei moduli condivisi e interoperabilità Swift Export - I parametri di contesto hanno sostituito i context receivers. La modifica alla risoluzione degli overload nella 2.3.20 è una classica domanda trabocchetto - Coroutine e Flow dominano i colloqui Android. Padroneggiare `StateFlow` vs `SharedFlow`, `WhileSubscribed` e structured concurrency - Le sealed interface modellano lo stato UI con esaustività a tempo di compilazione. Preferire `sealed interface` rispetto a `sealed class` - Le scope function richiedono uno schema decisionale chiaro: receiver vs argomento, valore di ritorno vs receiver - La null safety non è negoziabile. Saper articolare perché `!!` mina il sistema di tipi e dimostrare le alternative --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/it/blog/android/kotlin-2-3-interview-questions