Android için Kotlin 2.3: İsim Tabanlı Yapı Bozma, KMP ve 2026 Mülakat Soruları

İsim tabanlı yapı bozma, Kotlin Multiplatform, context parametreleri, coroutines ve Flow konularını kapsayan Kotlin 2.3 mülakat soruları. 2026'da gerçek dünya kod örnekleriyle Android geliştirici mülakatlarına hazırlanın.

Yapı bozma ve KMP kavramlarıyla Kotlin 2.3 Android mülakat soruları

Kotlin 2.3 mülakat soruları, 2026'da Android geliştirici pozisyonları için en çok aranan konular arasında yer alıyor. İsim tabanlı yapı bozma bildirimleri, stabilize edilen context parametreleri ve olgunlaşmış Kotlin Multiplatform ekosistemi sayesinde mülakatçılar adaylardan bu özelliklerde akıcılık bekliyor.

Kotlin 2.3'te neler değişti

Mart 2026'da yayınlanan Kotlin 2.3.20, isim tabanlı yapı bozma bildirimleri, context parametreleri için aşırı yükleme çözümleme değişiklikleri ve C ile TypeScript için iyileştirilmiş KMP birlikte çalışabilirliği sunuyor. Bu özellikler kıdemli Android mülakatlarında sıkça karşımıza çıkıyor.

İsim Tabanlı Yapı Bozma: En Yaygın Kotlin 2.3 Mülakat Sorusu

Kotlin 2.3'ten önce yapı bozma bildirimleri konum tabanlı componentN() fonksiyonlarına dayanıyordu. Bu, iyi bilinen bir tuzak yaratıyordu: bir data class'ta özellik sırasını değiştirmek, mevcut yapı bozma kullanım yerlerini sessizce bozuyordu.

Klasik mülakat sorusu şu senaryoyu sunar:

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 bu sorunu isim tabanlı yapı bozma ile çözüyor. Üç derleyici modu davranışı kontrol eder:

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")
    }
}

complete modunda parantezler isim tabanlı eşleştirme kullanırken, köşeli parantezler konum tabanlı davranışı korur:

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)
}

Mülakatta güçlü bir yanıt üç modu da açıklar ve her birinin ne zaman uygulanacağını belirtir: kademeli geçiş için only-syntax, mevcut koddaki hataları yakalamak için name-mismatch ve yeni projeler için complete.

Android Geliştiriciler için Kotlin Multiplatform Mülakat Soruları

KMP deneysel aşamayı geride bıraktı. Google, Android ve iOS arasında iş mantığını paylaşmak için resmi olarak destekliyor ve yeni çoklu platform projelerinin çoğu varsayılan olarak paylaşılan çekirdek mimarisini benimsiyor.

Tipik bir mülakat sorusu şudur: "Paylaşılan ağ iletişimi için bir KMP modülünü nasıl yapılandırırdınız?"

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)
        }
    }
}

Mülakatçılar adayın expect/actual mekanizmasını, platforma özgü bağımlılıkları ve paylaşılan kod ile platform kodu arasındaki sınırı anlayıp anlamadığını değerlendirir.

Diğer sık sorulan bir konu da 2026'da önemli ölçüde gelişen Swift Export konusudur. Kotlin suspend fonksiyonları artık doğrudan Swift async/await'e, sealed sınıflar ise ilişkili değerlere sahip Swift enum'lara eşleniyor.

Context Parametreleri ve Aşırı Yükleme Çözümleme Değişiklikleri

Context parametreleri, kullanımdan kaldırılan context receivers API'sinin yerini alır. Kotlin 2.3.20, aşırı yükleme çözümlemesinde önemli bir değişiklik getirdi: context parametreli bildirimler artık context parametresi olmayanlardan daha spesifik olarak değerlendirilmiyor.

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
}

Mülakatçılar bu konuyu, kırıcı değişiklikler ve geçiş stratejileri konusundaki farkındalığı ölçmek için kullanır. Anahtar çıkarım: context parametresi olmayan aşırı yüklemeleri gölgelemek için örtük context parametresi çözümlemesine güvenmek artık işe yaramıyor.

Coroutines ve Flow: Hâlâ En Önemli Android Mülakat Konusu

Kotlin 2.3'ün yeni özellikler getirmesine rağmen, coroutines ve Flow en çok test edilen alan olmaya devam ediyor. Mülakat soruları genellikle soğuk ve sıcak flow'lar arasındaki farkı, yapılandırılmış eşzamanlılığı ve iptal mekanizmasını araştırır.

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")
    }
}

Devam sorusu genellikle Android'de flow'ların güvenli şekilde toplanması hakkındadır:

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")
            }
        }
    }
}

WhileSubscribed(5000) stratejisi, son abone kaybolduktan sonra upstream'i 5 saniye boyunca aktif tutar ve ekran döndürme gibi yapılandırma değişiklikleri sırasında gereksiz yeniden başlatmaları önler.

Android mülakatlarında başarılı olmaya hazır mısın?

İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.

Sealed Class ve Exhaustive When: Mülakatlarda Pattern Matching

Sealed sınıflar neredeyse her Android mülakatında karşımıza çıkar. Soru genellikle adaylardan bir UI durumunu modellemelerini ister:

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 */ }
        ))
    }
}

Kotlin'de sealed tipler üzerindeki when ifadeleri derleme zamanında exhaustive'dir. Yeni bir alt tip eklemek, onu her yerde işlemeye zorlar ve bu da bir bütün çalışma zamanı hata kategorisini ortadan kaldırır. Mülakatçılar özellikle adayın bu kalıp için sealed class yerine sealed interface kullandığını kontrol eder, çünkü arayüzler daha esnek hiyerarşilere izin verir.

Kotlin/Wasm ve Çapraz Platform Derleme Hedefleri

Kotlin/Wasm Beta statüsüne ulaştı ve tarayıcılarda neredeyse yerel performans sunuyor. Henüz Android geliştiricileri için günlük bir endişe olmasa da, web ve mobil ürünleri olan şirketlerdeki mülakatçılar bunu sorar.

Mülakat için kilit gerçekler:

  • Kotlin 2.3.20, JS String builtin'leri sayesinde Wasm'da string interpolasyonunu 4,6 kat hızlandırdı
  • İkili dosya boyutları yaklaşık %5 düştü
  • Temiz derlemeler %65 daha hızlı, artımlı derlemeler %21 daha hızlı çalışıyor
  • @nativeInvoke anotasyonu, Kotlin nesnelerinin JavaScript fonksiyonları gibi davranmasına olanak tanır

Kotlin/JS de TypeScript'ten Kotlin arayüzlerini uygulama yeteneği kazandı ve önceki bir kısıtlamayı ortadan kaldırdı. Transpilasyon için SWC desteğiyle birlikte Kotlin artık tek bir kod tabanından Android, iOS (KMP aracılığıyla), Web (Wasm/JS aracılığıyla) ve sunucu tarafı hedefleri kapsıyor.

Scope Fonksiyonları: Yanıltıcı Şekilde Basit Bir Mülakat Filtresi

Scope fonksiyonları (let, run, with, apply, also) basit görünür ama deneyimli Kotlin geliştiricilerini ayırt eder. Mülakat sorusu genellikle şudur: "let ile apply'ı ne zaman kullanırsınız?"

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)
    }
}

Karar çerçevesi: nesne yapılandırması için apply (alıcıyı döner), null güvenli dönüşümler için let (lambda sonucunu döner), yan etkiler için also (alıcıyı döner), alıcı bağlamıyla bir sonuç hesaplamak için run.

Null Güvenliği ve Çift Ünlem İşaretinin Tehlikesi

Null güvenliği temel bir mülakat konusu olmaya devam ediyor. "!! neden tehlikelidir?" sorusu, adayın Kotlin'in tip sistemini gerçekten anlayıp anlamadığını test eder.

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"
}

Eksiksiz bir cevap, !!'in yalnızca test kodunda veya null'un gerçekten imkânsız olduğu platform interop sınırlarında görünmesi gerektiğini belirtir.

Pratik yapmaya başla!

Mülakat simülatörleri ve teknik testlerle bilgini test et.

Sonuç

  • Kotlin 2.3.20'deki isim tabanlı yapı bozma, konuma bağımlı hataları ortadan kaldırır. Üç derleyici modunu bilmek gerekir: only-syntax, name-mismatch, complete
  • KMP 2026'da üretim açısından stabil. expect/actual, paylaşılan modül mimarisi ve Swift Export birlikte çalışabilirliği üzerine sorular bekleyin
  • Context parametreleri, context receivers'ın yerini aldı. 2.3.20'deki aşırı yükleme çözümleme değişikliği yaygın bir tuzak sorusudur
  • Coroutines ve Flow Android mülakatlarına hakimdir. StateFlow vs SharedFlow, WhileSubscribed ve yapılandırılmış eşzamanlılığı ustaca kullanın
  • Sealed interface'ler UI durumunu derleme zamanı exhaustive'liği ile modeller. sealed class yerine sealed interface tercih edin
  • Scope fonksiyonları net bir karar çerçevesi gerektirir: alıcı vs argüman, dönüş değeri vs alıcı
  • Null güvenliği pazarlık konusu değildir. !!'in tip sistemini neden zayıflattığını anlatın ve alternatifleri gösterin

Pratik yapmaya başla!

Mülakat simülatörleri ve teknik testlerle bilgini test et.

Etiketler

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

Paylaş

İlgili makaleler