ANDROID INTERVIEW PREPARATION
Aiming for an Android role at a leading product company? Build the depth to explain your code, defend your design decisions, and work through unfamiliar problems.
474 questions with answers · Kotlin to system design · Progress saved as you learn
PRACTISE WITH PURPOSE
Find a question, explain your approach, then explore the answer.
474 of 474 questions
Choose lifetime from the operation: screen work may be cancellable, while a confirmed publish may need durable scheduling.
Scope rendering to the Fragment view lifecycle and collect while STARTED; the Fragment can outlive its view.
Separate in-memory screen state, small restoration keys, and durable cart data. A ViewModel alone cannot survive process death.
Use durable operation IDs and server-side idempotency. Unique WorkManager scheduling alone does not guarantee exactly-once server effects.
Treat the confirmed purchase as recoverable state, not only a transient navigation emission. Reconcile the authoritative outcome on return.
A long-lived object must not retain a shorter-lived Activity or its callbacks. Align dependency lifetime with ownership.
Check query-scoped cache membership and remote keys, plus transactional refresh writes and invalidation.
Represent available content separately from refresh status so a network error does not discard useful cached data.
Define a migration for existing installations, export schemas, and test that real stored progress survives each supported upgrade path.
Expose the meaning of the drawing through semantics, including its label and progress, then test the accessibility tree.
Inspect effect keys: work that belongs to a lesson should restart when that lesson ID changes.
Give lazy-list items stable, unique keys so remembered row state follows item identity rather than position.
Compose must observe the mutation. Replace an immutable list held in state or use a snapshot-aware state collection.
Find where rapidly changing state is read, then move reads to the smallest relevant scope or an appropriate later rendering phase.
Stopping the UI collector and stopping the upstream producer are separate events. Inspect sharing policy, scope, and other subscribers.
CPU-bound loops must check cancellation. Use a suitable dispatcher and deliberate cancellation checkpoints between bounded units of work.
delay suspends cooperatively; Thread.sleep blocks a thread. Neither is a reliable way to synchronize a test or wait for a request.
Handle expected failures locally, preserve cancellation, and reason about parent-child propagation; async failure is not postponed until await.
Use sequential calls for dependencies and structured async children for independent results. Concurrency does not guarantee parallel threads.
StateFlow models a current value; SharedFlow broadcasts emissions with configurable replay and buffering. Neither is a durable event queue.
Suspension can pause a coroutine without occupying its thread. The suspend modifier alone neither moves work off Main nor makes blocking code non-blocking.
Cancelling a scope cancels its Job and children cooperatively. Cancel an operation's Job when you intend to reuse the owner scope.
supervisorScope isolates direct child failures, still waits for children, and still propagates cancellation from its caller.
Suspended coroutines can share threads, but each still retains state and resources. Lightweight does not mean unlimited concurrency.
Inspect the main thread and its dependencies: parsing, lock contention, synchronous IPC, and initialization can still block responsiveness.
Measure repeatable startup journeys on a release-like build with controlled compilation, device conditions, and meaningful readiness metrics.
StateFlow conflates updates. Decide whether you are testing the current state or a required observable intermediate state.
Control coroutine time with a shared test scheduler, start collection explicitly, and assert requests before and after the debounce boundary.