Android · 15 min read

Android mock interview: a full script with a rubric

A complete Android mock interview to run alone or with a partner: timings, eight prompts with follow-ups, a scoring rubric and how to self-score a recording.

An Android mock interview is only useful if it feels like the real one: a clock, a person who pushes, and a score you did not give yourself out of kindness. Most mocks I hear about are friendly conversations where the “interviewer” nods at the first answer and moves on. That is the one thing a real interviewer never does.

This page is a complete script. It has the format and timings, eight prompts across four rounds with the follow-ups an interviewer would ask, a scoring rubric, and a method for scoring yourself from a recording when you have no partner. I built it from the way I run and score Android rounds after more than 500 interviews on the hiring side. None of the prompts is attributed to a company.

Format and timing

This mock runs 90 minutes, split into four rounds with a short break. The timings below are a suggested practice format, not a description of any company’s loop; real loops differ. You can run one round at a time if that is all you have, but run the full thing at least once before a real loop, because stamina is part of what is tested.

Block Time Content
Round 1 20 min Kotlin, coroutines and Flow: prompts 1 and 2
Round 2 20 min Compose and the UI: prompts 3 and 4
Break 5 min Stand up. Do not review answers.
Round 3 30 min System design: prompts 5 and 6
Round 4 15 min Incident and ownership: prompts 7 and 8

Inside each prompt, the time splits roughly into a two-minute first answer, then follow-ups until the time runs out. The interviewer’s job is to spend most of the time on follow-ups, because that is where the score comes from.

How to run it

With a partner. Give your partner this page and ask them to read only the prompt aloud, then the follow-ups in order, whatever you say. They should not help, agree or explain. They take notes in the rubric table: one rating per dimension and one piece of evidence, such as a quote or a timestamp.

Alone. Record video or audio of yourself. Read the prompt, start a timer, answer out loud, then read the first follow-up and answer it, and so on. Do not pause the recording to think; silence is part of the data. Score the recording the next day, not the same evening, because you will remember what you meant instead of hearing what you said.

Either way, pick your level before you start: mid-level or senior. The prompts are the same, but the rubric anchors differ, and scoring a senior answer against a mid-level bar hides the gaps you came to find.

Round 1: Kotlin, coroutines and Flow

Prompt 1. “A ViewModel starts a coroutine to generate a report. The user leaves, but CPU stays high for several seconds. Why?”

Follow-ups, in order:

  1. “It already runs inside withContext(Dispatchers.IO). So why is it still going?”
  2. “Would you call Thread.interrupt()?”
  3. “Show me the fix in code.”

Strong answer: Cancellation is cooperative. The scope requested it, but blocking code, a swallowed CancellationException, or work launched in another scope can ignore it. Moving work to IO makes it main-safe, not interruptible. Interrupting arbitrary library code is only safe when the library documents it; prefer the library’s own cancellation or runInterruptible, bound the work with a timeout, and make late results harmless. The fix puts ensureActive() inside the loop.

Prompt 2. “One StateFlow holds the screen state, a second StateFlow holds navigation. Rotate the device and the app navigates twice. Fix it.”

Follow-ups:

  1. “So SharedFlow(replay = 0) solves it?”
  2. “What if the event is a payment result?”

Strong answer: StateFlow replays its current value to the new collector, so the old navigation command fires again. A SharedFlow without replay avoids that but drops the event if the UI is not collecting at that moment. Losing a toast is fine; losing a payment result is not. For important outcomes, model them as state with an ID and an acknowledgement, so the UI can recover after recreation.

The Kotlin coroutines interview questions guide has the full reasoning for both prompts if you want to check your answers after scoring. Do not read it before the mock; the point is to find out what you produce without it.

Round 2: Compose and the UI

Prompt 3. “Scrolling a search screen triggers recomposition on each event, and typing lags. Where do you start?”

Follow-ups:

  1. “Does derivedStateOf make the calculation run less often?”
  2. “After a refresh the list flashes and the scroll position jumps. Why?”
  3. “A colleague claims every state change recomposes the entire screen. Respond.”

Strong answer: Measure before changing anything: recomposition counts and a frame trace. A frequent cause is a composable near the root reading the raw scroll offset when the UI only cares whether a threshold was crossed; derivedStateOf limits invalidation to when the derived value changes, but it still observes every input change, so it is not a cache for expensive work. Flashing and jumping point to unstable item keys or a refresh that is not transactional. A state write invalidates only the scopes that read it, and stable, unchanged composables can be skipped.

Prompt 4. “Analytics shows the screen-view event fires three times per visit.”

Follow-ups:

  1. “You moved it into LaunchedEffect(Unit). Is it fixed now?”
  2. “What if navigation recreates the destination?”

Strong answer: A call in the composable body runs on every recomposition. Moving it into an effect helps, but LaunchedEffect(Unit) means once per entry into composition, not once per visit as the business defines it. Make the visit identity explicit, key the effect on it, and agree with whoever owns the metric what counts as one view.

Round 3: System design

Prompt 5. “Design a field-service app. Technicians work for hours with no signal. They open jobs, tick off checklists and add photos. Office staff need those changes shortly after the device reconnects.”

Follow-ups:

  1. “Why not call the API directly when the device is online?”
  2. “A photo upload times out at 99 percent. What happens?”
  3. “The technician logs out before sync finishes.”
  4. “Two technicians edit the same checklist item offline.”
  5. “What do you monitor in production?”

Strong answer: Starts with questions about conflicts, photo sizes and what must never be lost. The local database is the source of truth; each action writes the change and an outbox entry in one transaction; WorkManager drains the outbox with stable operation IDs so the server can deduplicate. Calling the API first creates two code paths and an ambiguous state when the process dies after the server commits. Uploads are resumable with an upload ID and acknowledged offsets. Pending work is partitioned by account, and logout follows an explicit product policy instead of silently deleting unsynced work. Conflicts use server versions, not device clocks. Monitoring covers outbox age, retries, conflict rate and how long users see stale data.

Prompt 6. “Design the data layer for a news feed with pagination, pull to refresh and offline reading.”

Follow-ups:

  1. “Users see duplicates after a refresh. Why?”
  2. “How fresh does the feed need to be, and who decides?”

Strong answer: Paging 3 with a RemoteMediator, Room as the source of truth, and remote keys stored with the items. Refresh replaces items and keys in one transaction. Duplicates usually mean the refresh and the append were not transactional, or keys were derived from positions. Freshness is a product decision with a battery cost, so the answer names a policy and who owns it.

For deeper design practice, the Android system design interview guide works through a full design with the follow-ups. Design rounds are the ones where a mock pays off most, because candidates who read designs rarely practise saying the constraints out loud first.

Round 4: Incident and ownership

Prompt 7. “Since this morning, Android vitals puts your ANR rate over the bad-behaviour threshold. Walk me through your first two hours.”

Follow-ups:

  1. “You only have three Android engineers.”
  2. “The traces lead to a coroutine blocking the main thread. What do you change first?”
  3. “Your manager wants the root cause in thirty minutes.”

Strong answer: Scope the impact before hunting the cause: versions, rollout percentage, devices, screens. If the new release correlates and halting is safe, halt. Roles, not teams: one person on mitigation and communication, two on separate hypotheses. For the trace, classify the blocking work first, because a lock held by background work survives a dispatcher change. To the manager: confirmed facts, the leading hypothesis labelled as a hypothesis, the mitigation status, and the time of the next update.

Prompt 8. “After the fix, who is responsible, and what changes?”

Follow-ups:

  1. “Tell me about a mistake you made during this incident.”

Strong answer: Takes responsibility for reducing the class of failure without naming an individual as the cause. Asks why review, tests, StrictMode and the staged rollout all missed it. Ends with follow-ups that have owners and dates. The mistake story is specific and real, and shows what changed afterwards, not a strength in disguise.

The scoring rubric

Score each prompt on the four dimensions below, from 1 to 4. Write one piece of evidence for every rating: a quote, a timestamp, or a specific omission. A rating without evidence does not count.

Score Correctness Ownership and lifetime Failure handling Communication
4, hire signal Mechanism correct, limits stated without prompting Names who owns the work or state and when it ends Covers the failure the follow-up introduces, before or when asked Clear first sentence, corrects own overclaims
3, acceptable Correct, one guarantee overstated Ownership right, one lifetime missed Handles most failures, one left vague Easy to follow, some wandering
2, mid-level Names the right APIs without their contracts “The lifecycle handles it” Happy path only Answer found only after hints
1, weak A false guarantee, defended when pushed No owner named Retries or ignores failure blindly Hard to follow, no conclusion

Fluency never repairs a false guarantee. If an answer is fluent but claims something the platform does not promise, it scores 1 on correctness regardless of how confident it sounded. That is the rule I apply in real debriefs, and it is the one candidates are most surprised by.

How to self-score a recording

Scoring yourself is harder than being scored, because you fill gaps with what you meant. These steps take that out of the process:

  1. Wait a day. Score the recording at least a night later.
  2. Transcribe the first sentence of every answer. If there is no clear first sentence within ten seconds, note it.
  3. Mark every absolute. Each “always”, “never” or “guarantees” gets a check: did you name the contract behind it?
  4. Score each follow-up separately. The first answer and the follow-up are different data points. Most scores drop at the follow-up.
  5. Count hints. With a partner, note every time they helped. Help is context and does not count as failure. It is also not independent evidence.
  6. Pick one primary gap. Choose the gap with the largest consequence in the round you are about to face, plus at most two secondary ones. Write each as something you can do, such as “explain a timeout without treating it as a failure”, not “study coroutines”.

When a partner scores you too, compare evidence rather than averaging numbers. A disagreement usually means the answer was ambiguous, and an ambiguous answer is itself a finding.

Running it again

The second time, change one constraint yourself before each prompt, and do not look up a new pattern first:

  • the process dies right after the server commits;
  • nobody is collecting when the event fires;
  • two accounts share the device;
  • the app must run on a device with 2 GB of memory;
  • there is no way to roll the release back.

Return to the same questions each time: who owns it, how long it lives, what fails, who enforces it, and how you would know. If your answers change sensibly with the constraint, your preparation is working. If they stay the same, you have memorised answers rather than learned the model, and that is what a real loop will find.

What changed in 2024 to 2026

  • Kotlin 2.0.0, released 21 May 2024, made the K2 compiler the default and Stable on JVM, Native, Wasm and JS (What’s new in Kotlin 2.0.0).
  • In the same release the Jetpack Compose compiler plugin moved into the Kotlin repository and gained its own Gradle plugin.
  • Answers about build speed or compiler plugins that describe the old compiler describe a toolchain most projects have left.

Sources

What to do next

Run the mock once this week, score it honestly, and fix the one gap that costs the most. Then run it again with a changed constraint. Two scored mocks with a fix in between will tell you more about your readiness than any amount of reading.

Free guide: the Phoenix Method