2026 Yilinda En Cok Sorulan 20 Jetpack Compose Mulakat Sorusu
En sik sorulan 20 Jetpack Compose mulakat sorusu: recomposition, state yonetimi, navigasyon, performans ve mimari desenler.

Jetpack Compose, Android gelistirme alaninda standart UI araclari haline geldi. Teknik mulakatlarda Compose yetkinligi artik duzenli olarak test ediliyor — recomposition mekanizmalarindan state yonetimine ve performans optimizasyonuna kadar. Asagida, ayrintili yanitlar ve kod ornekleriyle birlikte en sik sorulan 20 soru yer aliyor.
Her soru yapilandirilmis bir yanit ve kod ornegi icerir. Sorular artan zorluk sirasina gore duzenlenmistir: temel, orta ve ileri seviye.
Jetpack Compose Temelleri
1. Compose ile XML gorunum sistemi arasindaki fark nedir?
Compose deklaratif bir paradigma kullanir: UI, state'in bir fonksiyonu olarak tanimlanir ve framework guncellemeleri otomatik olarak yonetir. Geleneksel XML sistemi ise imperatiftir — gorunumler findViewById veya View Binding ile manuel olarak manipule edilmelidir.
// Compose: UI updates automatically when count changes
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) } // Reactive state
Button(onClick = { count++ }) { // UI declaration
Text("Clicks: $count") // Recomposed automatically
}
}Compose ile bir TextView referansi bulup manuel olarak guncellemek gerekmez — recomposition her seyi otomatik olarak yonetir.
2. Recomposition nedir?
Recomposition, state degistiginde Compose'un @Composable fonksiyonlari yeniden cagirma surrecidir. Yalnizca parametreleri degismis fonksiyonlar yeniden calistirilir ve bu durum performansi optimize eder.
@Composable
fun UserCard(name: String, age: Int) {
Column {
Text("Name: $name") // Recomposed only if name changes
Text("Age: $age") // Recomposed only if age changes
StaticBadge() // Not recomposed if its inputs remain the same
}
}
@Composable
fun StaticBadge() {
Text("Static badge") // Compose knows this function is stable
}Mulakat icin kritik bilgi: recomposition iyimserdir (Compose iptal edilebilecegini varsayar) ve sirali degildir (composable'larin calisma sirasi garanti edilmez).
3. remember ne yapar?
remember, recomposition'lar arasinda bir degeri korur. remember olmadan her recomposition, degiskeni baslangic degerine sifirlar.
@Composable
fun InputField() {
// ✅ Value survives recompositions
var text by remember { mutableStateOf("") }
// ❌ Without remember, text resets to "" on every recomposition
// var text by mutableStateOf("")
TextField(
value = text,
onValueChange = { text = it }, // Triggers recomposition
label = { Text("Enter text") }
)
}4. remember ile rememberSaveable arasindaki fark nedir?
remember, recomposition'lar arasinda degerleri korur ancak yapilandirma degisikliklerinde (ekran dondurme) kaybeder. rememberSaveable ise SavedInstanceState mekanizmasini kullanarak degerleri yapilandirma degisiklikleri boyunca saklar.
@Composable
fun SearchBar() {
// Lost after screen rotation
var query by remember { mutableStateOf("") }
// Preserved after screen rotation
var savedQuery by rememberSaveable { mutableStateOf("") }
TextField(
value = savedQuery,
onValueChange = { savedQuery = it },
placeholder = { Text("Search...") }
)
}Compose'da State Yonetimi
5. State hoisting nedir?
State hoisting, state'i bir composable'dan ust bilesenine tasimak anlamina gelir. Alt bilesen stateless hale gelir: state'i parametre olarak alir ve degisiklikleri callback'ler araciligiyla bildirir.
// ✅ Stateless composable — easy to test and reuse
@Composable
fun EmailInput(
email: String, // State provided by parent
onEmailChange: (String) -> Unit, // Callback to parent
modifier: Modifier = Modifier
) {
TextField(
value = email,
onValueChange = onEmailChange,
label = { Text("Email") },
modifier = modifier
)
}
// Parent manages the state
@Composable
fun LoginForm() {
var email by remember { mutableStateOf("") }
EmailInput(
email = email,
onEmailChange = { email = it } // Parent controls state
)
}Bu desen Compose'da temeldir ve mulakatlarda siklikla karsimiza cikar.
6. derivedStateOf nasil calisir?
derivedStateOf, yalnizca hesaplama sonucu degistiginde recomposition tetikleyen turetilmis bir state olusturur — kaynagin her degisikliginde degil.
@Composable
fun FilteredList(items: List<String>) {
var searchQuery by remember { mutableStateOf("") }
// Recalculated only when the filtered result actually changes
val filteredItems by remember(items) {
derivedStateOf {
items.filter { it.contains(searchQuery, ignoreCase = true) }
}
}
Column {
TextField(value = searchQuery, onValueChange = { searchQuery = it })
LazyColumn {
items(filteredItems) { item -> Text(item) }
}
}
}Bu mekanizma, bir state sik degistiginde ancak turetilmis sonuc nadiren degistiginde faydalidir (ornegin filtrelenmis liste, form dogrulamasina bagli olarak etkin/devre disi buton).
7. StateFlow ile Compose State<T> arasindaki fark nedir?
StateFlow (Kotlin coroutines), ViewModel'den gelen reaktif bir akistir. State<T>, Compose'un recomposition tetiklemek icin kullandigi yerel mekanizmadir. Pratikte StateFlow, bir composable icinde collectAsStateWithLifecycle() ile toplanir.
class UserViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UserUiState())
val uiState: StateFlow<UserUiState> = _uiState.asStateFlow()
}
@Composable
fun UserScreen(viewModel: UserViewModel = viewModel()) {
// Converts StateFlow to State<T> for Compose
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
Text("Hello, ${uiState.userName}")
}collectAsStateWithLifecycle() kullanilmasi onerilir (collectAsState() yerine), cunku yasam dongusune uyar ve ekran artik gorunur olmadiginda toplama islemini durdurur.
Side Effect'ler ve Yasam Dongusu
8. Compose'daki temel side effect'ler nelerdir?
Side effect'ler, composable olmayan kodu (ag cagirilari, loglama, navigasyon) kontrollü bir sekilde calistirmaya olanak tanir. Uc temel side effect sunlardir:
@Composable
fun AnalyticsScreen(screenName: String) {
// LaunchedEffect: runs once when screenName changes
LaunchedEffect(screenName) {
analyticsTracker.logScreenView(screenName) // Suspended call
}
// DisposableEffect: with cleanup (like useEffect with cleanup)
DisposableEffect(Unit) {
val listener = onScrollListener()
scrollView.addListener(listener)
onDispose {
scrollView.removeListener(listener) // Cleanup guaranteed
}
}
// SideEffect: runs after every successful recomposition
SideEffect {
logger.log("Screen recomposed") // Non-suspended code
}
}9. LaunchedEffect ile rememberCoroutineScope ne zaman kullanilir?
LaunchedEffect, composition'a baglidir: composable composition'dan ayrildiginda veya anahtar degistiginde coroutine iptal edilir. rememberCoroutineScope, kullanici tarafindan kontrol edilen bir kapsam saglar ve kullanici tetiklemeli islemler (buton tiklama) icin kullanislidir.
@Composable
fun DataScreen(userId: String) {
// ✅ LaunchedEffect: automatic loading tied to lifecycle
LaunchedEffect(userId) {
loadUserData(userId) // Re-launched if userId changes
}
// ✅ rememberCoroutineScope: one-off user action
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch { refreshData() } // Triggered manually
}) {
Text("Refresh")
}
}Android mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Layout'lar ve Ileri Seviye Bilesenler
10. LazyColumn nasil calisir ve RecyclerView'dan farki nedir?
LazyColumn, Compose'un RecyclerView karsiligdir. Yalnizca ekranda gorunen ogeleri compose eder ve gorunur alanin disina cikan composable'lari geri donusturur.
@Composable
fun UserList(users: List<User>) {
LazyColumn(
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp) // Spacing between items
) {
items(
items = users,
key = { it.id } // Stable key to optimize recompositions
) { user ->
UserCard(user)
}
}
}Onemli nokta: siralama veya eleman kaldirilmasi sirasinda gereksiz recomposition'lari onlemek icin her zaman stabil bir key parametresi saglanmalidir.
11. Ozel layout nasil olusturulur?
Compose, Layout fonksiyonu araciligiyla ozel layout'lar olusturmaya olanak tanir. Bu, gorunum sistemindeki ozel ViewGroup implementasyonlarinin yerini alir.
@Composable
fun OverlappingRow(
overlapOffset: Dp = (-16).dp, // Negative offset for overlap
content: @Composable () -> Unit
) {
Layout(content = content) { measurables, constraints ->
val placeables = measurables.map { it.measure(constraints) }
val width = placeables.sumOf { it.width } + (overlapOffset.roundToPx() * (placeables.size - 1))
val height = placeables.maxOf { it.height }
layout(width, height) {
var xOffset = 0
placeables.forEach { placeable ->
placeable.placeRelative(xOffset, 0)
xOffset += placeable.width + overlapOffset.roundToPx()
}
}
}
}12. MaterialTheme ile ozel tema nasil uygulanir?
Compose'da temalama CompositionLocal uzerine kuruludur. MaterialTheme, composable agacinin tamaminda erisilebilen renk, tipografi ve sekil degerleri saglar.
// Custom color definitions
private val DarkColorScheme = darkColorScheme(
primary = Color(0xFF6200EE),
secondary = Color(0xFF03DAC6),
background = Color(0xFF121212)
)
@Composable
fun AppTheme(content: @Composable () -> Unit) {
MaterialTheme(
colorScheme = DarkColorScheme,
typography = AppTypography, // Custom typography
content = content
)
}
// Usage in a composable
@Composable
fun ThemedCard() {
Card(colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface // Theme access
)) {
Text(
text = "Content",
style = MaterialTheme.typography.bodyLarge // Theme typography
)
}
}Compose'da Navigasyon
13. Compose Navigation nasil calisir?
Compose Navigation, string olarak tanimlanan rotalarla (veya Navigation 2.8+ ile serializasyon destekli tiplerle) bir NavHost kullanir.
@Composable
fun AppNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") {
HomeScreen(onNavigateToDetail = { id ->
navController.navigate("detail/$id") // Navigation with argument
})
}
composable(
route = "detail/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.StringType })
) { backStackEntry ->
val userId = backStackEntry.arguments?.getString("userId") ?: ""
DetailScreen(userId = userId)
}
}
}14. Ekranlar arasi veri nasil aktarilir?
Basit argumanlar (String, Int) dogrudan rota uzerinden iletilir. Karmasik nesneler icin guncel oneri, paylasilan bir ViewModel kullanmak veya yalnizca bir tanimlayici iletip verileri hedef ekranda yuklemektir.
// Type-safe navigation with Kotlin Serialization (Navigation 2.8+)
@Serializable
data class ProfileRoute(val userId: String, val tab: String = "info")
// Declaration
composable<ProfileRoute> { backStackEntry ->
val route = backStackEntry.toRoute<ProfileRoute>()
ProfileScreen(userId = route.userId, tab = route.tab)
}
// Navigation
navController.navigate(ProfileRoute(userId = "123", tab = "stats"))Rotada karmasik serializasyon nesneleri asla iletilmemelidir. Bir ID iletilmeli ve hedef ekranin verileri ViewModel uzerinden yuklemesine izin verilmelidir.
Performans ve Optimizasyon
15. Gereksiz recomposition'lar nasil onlenir?
Gereksiz recomposition'lari en aza indirmek icin uc temel strateji vardir:
// 1. Use stable classes (data class with immutable properties)
@Stable // Tells Compose this class is stable
data class UserState(
val name: String,
val avatar: String
)
// 2. Extract lambdas with remember
@Composable
fun OptimizedList(onItemClick: (String) -> Unit) {
val stableCallback = remember(onItemClick) { onItemClick }
LazyColumn {
items(100) { index ->
ItemRow(onClick = { stableCallback("item_$index") })
}
}
}
// 3. Use key() to help Compose identify elements
@Composable
fun UserTabs(users: List<User>) {
Column {
users.forEach { user ->
key(user.id) { // Stable identity
UserRow(user)
}
}
}
}16. Compose uygulamasinin performansi nasil profillenir?
Android Studio'daki Layout Inspector, her composable icin recomposition sayaclarini gosterir. debugInspectorInfo bayragi ve CompositionTracer tani koyma isleminde yardimci olur.
// Enable recomposition counters in debug
@Composable
fun DebugRecomposition(tag: String, content: @Composable () -> Unit) {
val recompositionCount = remember { mutableIntStateOf(0) }
SideEffect {
recompositionCount.intValue++ // Incremented on every recomposition
Log.d("Recomposition", "$tag: ${recompositionCount.intValue} times")
}
content()
}
// Usage
DebugRecomposition("UserCard") {
UserCard(user)
}Ayrica Compose Compiler Metrics, atlanabilir ve yeniden baslatilabilir fonksiyonlarin yani sira stabil ve stabil olmayan siniflarin ayrintili raporunu olusturur.
17. Modifier nedir ve neden onemlidir?
Modifier, bir composable'in gorunumunu ve davranisini degistiren sirali bir talimat zinciridir. Modifier'larin sirasi render sonucunu dogrudan etkiler.
@Composable
fun ModifierOrderDemo() {
// ❌ Padding THEN background = padding not colored
Text(
text = "Hello",
modifier = Modifier
.padding(16.dp)
.background(Color.Red)
)
// ✅ Background THEN padding = padding is colored
Text(
text = "Hello",
modifier = Modifier
.background(Color.Red)
.padding(16.dp)
)
}En iyi uygulama: yeniden kullanilabilir composable'larda ust bilesen tarafindan ozellestirmeye izin vermek icin her zaman modifier: Modifier = Modifier parametresi kabul edilmelidir.
Mimari ve Ileri Seviye Desenler
18. ViewModel ile bir Compose ekrani nasil yapilandirilir?
Onerilen desen, UI state'ini bir data class icinde, olaylari bir sealed interface icinde ayirir ve ViewModel is mantigi yonetir.
// UI State
data class ProfileUiState(
val user: User? = null,
val isLoading: Boolean = false,
val error: String? = null
)
// User events
sealed interface ProfileEvent {
data object Refresh : ProfileEvent
data class UpdateName(val name: String) : ProfileEvent
}
// ViewModel
class ProfileViewModel(private val repo: UserRepository) : ViewModel() {
private val _uiState = MutableStateFlow(ProfileUiState(isLoading = true))
val uiState = _uiState.asStateFlow()
fun onEvent(event: ProfileEvent) {
when (event) {
is ProfileEvent.Refresh -> loadProfile()
is ProfileEvent.UpdateName -> updateName(event.name)
}
}
}
// Compose screen
@Composable
fun ProfileScreen(viewModel: ProfileViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
ProfileContent(
uiState = uiState,
onEvent = viewModel::onEvent // Event delegation
)
}19. Composable'lar nasil test edilir?
Compose, UI testleri ve semantik dogrulamalar icin ComposeTestRule ile bir test kutuphanesi saglar.
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun counter_incrementsOnClick() {
composeTestRule.setContent {
Counter() // The composable under test
}
// Verify initial state
composeTestRule.onNodeWithText("Clicks: 0").assertIsDisplayed()
// Simulate a click
composeTestRule.onNodeWithText("Clicks: 0").performClick()
// Verify new state
composeTestRule.onNodeWithText("Clicks: 1").assertIsDisplayed()
}Stateless composable'larin testi icin, standart JUnit/Turbine testleriyle ViewModel'i ayri ayri test etmek genellikle daha verimlidir.
20. Compose, mevcut XML tabanli bir uygulamaya nasil entegre edilir?
Birlikte calisabilirlik cift yonludur: ComposeView Compose'u XML icine yerlestirir, AndroidView ise klasik gorunumleri Compose icinde kullanir.
// Compose in XML (in a Fragment or Activity)
class ProfileFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
)
setContent {
AppTheme { ProfileScreen() }
}
}
}
}
// XML View in Compose
@Composable
fun LegacyMapView() {
AndroidView(
factory = { context -> MapView(context).apply { onCreate(null) } },
update = { mapView -> mapView.getMapAsync { /* config */ } }
)
}Migrasyon ekran ekran yapilmalidir, en basit ekranlardan baslanarak. Her yeni ekran tamamen Compose ile olusturulmali, mevcut ekranlar ise kademeli olarak gecis yapmalidir.
Android mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Sonuc
Bu 20 soru, her Android gelistiricinin Jetpack Compose mulakati oncesinde hakim olmasi gereken temel konulari kapsamaktadir. Kontrol listesi:
- ✅ Recomposition ve iyimser davranisini anlamak
- ✅
remember,rememberSaveablevederivedStateOfkonularina hakim olmak - ✅ State hoisting'i sistematik olarak uygulamak
- ✅ Side effect'leri bilmek (
LaunchedEffect,DisposableEffect,SideEffect) - ✅ Performansi optimize etmek (stabil siniflar, anahtarlar, lambda'lar)
- ✅ Ekranlari ViewModel + UiState + Events ile yapilandirmak
- ✅ Composable'lari
ComposeTestRuleile test etmek - ✅ Compose/Views birlikte calisabilirligini yonetmek
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Etiketler
Paylaş
İlgili makaleler

Android'de MVVM vs MVI: 2026'da Hangi Mimariyi Seçmeli?
Android'de MVVM ve MVI karşılaştırması: avantajlar, kısıtlamalar, kullanım senaryoları ve 2026'da doğru mimariyi seçmek için pratik rehber.

Kotlin Coroutines Rehberi: Android için 2026 Kılavuzu
Android geliştirmede Kotlin coroutines konusunda uzmanlaşın: suspend fonksiyonlar, scope yapıları, dispatcher'lar ve ileri düzey kalıplar.

2026'da En Sık Sorulan 25 Veri Bilimi Mülakat Sorusu
2026 yılında veri bilimi mülakatlarında öne çıkan 25 kritik soru: istatistik, makine öğrenmesi, özellik mühendisliği ve MLOps konularında kapsamlı rehber.