Android
433 bites tagged Android — interview questions with model answers, and 60-second explainers.
How do you upload a file with text data in Retrofit?
Tests multipart uploads versus JSON bodies. Strong answer: @Multipart, @POST, @Part; file as MultipartBody.Part and text as RequestBody; avoid @Field. Red flag: suggesting @Body with a data class.
How do you differentiate network and server errors in suspend functions?
Catch IOException for connectivity and HttpException for HTTP errors; wrap in a sealed Result. Structured error handling in coroutines and mapping exceptions to recovery. Catching Exception or exposing raw errors to UI.
How do you configure Moshi or Kotlinx.serialization for JSON key mismatches?
This tests library-specific field-mapping annotations. For Kotlinx.serialization use @SerialName with the JSON key; for Moshi use @Json with the name parameter. A red flag is confusing the two or using manual mapping instead of the built-in decorator.
How would you implement a robust offline-first repository?
Tests single-source-of-truth discipline and network-local sync. Outline a Room repository with Flow, background refresh, disk persistence, immediate local emission, and conflict resolution with retry.
Preferences vs Proto DataStore: when is Proto significantly better?
This tests type safety and schema trade-offs. A strong answer contrasts Preferences key-value pairs with Proto typed protobuf schemas, then names nested settings or migration needs as the Proto win. A red flag is recommending Proto for a single boolean.
Model a Room one-to-many Playlist-to-Song relationship
Tests Room relational modeling. Strong answer: Song foreign key, `@Embedded` Playlist with `@Relation` to `List<Song>`, DAO wrapped in `@Transaction`. Red flag: embedding songs in Playlist or skipping `@Transaction`, which causes N+1 queries.
How do you add a non-null column with a default in Room?
Bump version; run ALTER TABLE ADD COLUMN with NOT NULL DEFAULT in a Migration; register via addMigrations. SQLite ALTER TABLE semantics and Room Migration wiring. Dropping tables or omitting DEFAULT on existing rows.
How do you define a Room table for a Kotlin data class?
Tests your grasp of the minimum Room entity contract. A strong answer cites Entity and PrimaryKey, notes Kotlin defaults work out of the box, and mentions ColumnInfo for renaming.
Why choose DataStore over SharedPreferences for a toggle?
This tests your grasp of modern Android storage safety beyond syntax. A strong answer names DataStore's async coroutines API, type safety, transactions, and migration support. A red flag is claiming SharedPreferences is simpler while ignoring ANR risk.
What are Room's three main components and their functions?
Tests whether you know Room's architectural layers. Name the three: Database holds config and is the access point; Entity represents a table schema; DAO defines SQL operations. Red flag: confusing DAOs with Repositories or claiming Room is a full ORM.
How would you architect state-driven UI with ViewModel and Compose?
Tests unidirectional data flow and state hoisting. Model screen state as an immutable data class, expose StateFlow from ViewModel, and collect it in Compose so events flow up and state down. Red flag: exposing mutable state or putting logic in Composables.
How do you navigate between feature modules without direct dependencies?
This tests architectural decoupling in multi-module Android apps. A great answer describes a shared navigation contract or deep-link router that lets features stay independent. Recommending direct Gradle dependencies between features is a major red flag.
How would you architect two source Flows from ViewModel to data layer?
This tests merging parallel async streams into one reactive state. A strong answer uses combine on two cold repository Flows, exposes one UI state Flow from the ViewModel, and maps failures to error states. Red flag: using two coroutines mutating shared state.
Explain the purpose of a UseCase and how it fits into MVVM
UseCases encapsulate single business rules between ViewModel and Repository, keeping ViewModels lean and Repositories focused on data. Separation of concerns beyond basic MVVM.
How do you share a ViewModel across multiple Fragments?
Tests ViewModel scoping and Fragment communication. A strong answer names activityViewModels or navGraphViewModels, warns about Activity memory retention and hidden coupling, and suggests a parent Fragment or data flow alternative.
How would you use a nested navigation graph for a login flow?
Tests modular navigation scoping. Strong answers group the three screens under a nested graph with its own start destination, noting encapsulation and reusability.
Why is LiveData<Boolean> problematic for one-time ViewModel events?
State is not events; suggest an Event wrapper with a consumed flag, or SharedFlow or Channel with no replay. LiveData replays one-time events after rotation. Praising SingleLiveEvent or onCleared resets as fix.
How do you pass data between Fragments with Jetpack Navigation?
Define args in nav graph XML, navigate with generated Directions, read with navArgs() in target Fragment. Type-safe argument flow in Navigation. Direct Fragment constructors, manual Bundles, or Activity Intent extras.
Explain the roles of ViewModel, Repository, and data source in MVVM
Tests your grasp of unidirectional data flow and separation of concerns in Android MVVM. A strong answer maps ViewModel to UI state, Repository to data coordination, and Room or Retrofit to I/O.
What is a ViewModel and what lifecycle problem does it solve?
Tests config-change survival: ViewModel outlives Activity recreation so state survives rotation. Strong answer notes it holds non-serializable data and separates concerns, but does not survive process death.
Diagnose Compose recomposition issues and explain lambda stability
Tests Compose skipping and stability. Strong answers name recomposition counts, compiler metrics, and immutable state, then explain unremembered lambdas create new instances and prevent skipping.
Difference between remember and rememberSaveable
Remember survives recompositions only; rememberSaveable uses Bundle state for config changes and process death; use for UI state after recreation. Compose state vs saved state. Claiming it uses ViewModel or disk.
How do you display a large list efficiently in Jetpack Compose?
This tests understanding of Compose lazy versus eager layout. A strong answer names LazyColumn or LazyRow, notes visible-only composition, and contrasts Column which lays out everything upfront.
Which side-effect handler for a one-time coroutine on composition entry?
Tests Compose side-effect API boundaries. Answer: LaunchedEffect(Unit); it runs once and auto-cancels on exit. Contrast with rememberCoroutineScope for user-triggered callbacks. Red flag: picking SideEffect or rememberCoroutineScope and missing cancellation.
Get Android bites daily.
Five a day, five minutes, offline. With quizzes so it sticks.
Open testing — you’ll join as an early tester.