cswork / libraryOpen practice workspace

Articles

Monzo Mobile Engineer Interview: Codebase Tasks and UI-to-System Design

Prepare for Monzo mobile interviews with an original notification-settings exercise, codebase triage, UI state mapping, and evidence-aware design discussion.

A mobile interview can become difficult before you write much code. You inherit a screen, notice several problems, and must decide which behavior matters first. In a design discussion, a simple toggle can expose questions about local state, server state, permissions, and failure recovery. Preparing only architecture diagrams leaves those decisions unexplained.

This guide uses Monzo’s dated official mobile interview guidance as a starting point, then develops an original notification-settings exercise. The aim is to make your reasoning observable: establish the intended behavior, implement a bounded change, and show what happens when an assumption fails. This is preparation material, not a reconstruction of a Monzo task.

For a complementary codebase exercise, try Implement A Mobile Chat Interface In An Existing Codebase. Focus on understanding the existing state and update paths before adding features.

What is verified about Monzo’s mobile interviews?

Official, dated guidance: Monzo’s January 2025 mobile interview article described an initial technical discussion, an existing-project coding exercise with take-home and pairing alternatives, and a mobile systems design discussion starting from a UI and requirements. The take-home description specified a four-hour limit and a subsequent review; the pairing alternative and design discussion were described as hour-long sessions. The article explicitly describes the process at publication, so these are historical details, not a guarantee about your invitation.

Individual candidate report: One mobile applicant in a Reddit discussion described uncertainty about the desired depth of a UI-led design conversation. That is useful evidence that expectations can feel ambiguous. It does not establish a standard exercise, timing, or evaluation rubric. We did not establish two independent reports from the same hiring cycle, so this guide avoids presenting a fixed current interview sequence.

Preparation inference: Practice connecting visible behavior to implementation decisions. Use your recruiter’s current instructions to establish the exercise format, permitted tools, setup requirements, and time limit. None of the practice below depends on receiving a particular screen or repository.

Start an unfamiliar codebase by tracing one user action

In an original practice project, imagine a notification-settings screen with a toggle that enables delivery updates. A product note says: “People should know whether their preference was saved and whether their device can receive notifications.” The starter implementation changes the toggle immediately, calls a gateway, and ignores failures.

Before modifying it, run the existing app and the relevant tests. Trace one tap from the view through its state holder to the gateway and back to the displayed result. Identify which layer owns the persisted preference, which layer owns temporary editing state, and where platform permissions are queried. This gives you a concrete map of the change rather than a catalog of every module.

Write down the behavior you cannot yet determine. Does the toggle represent a saved account preference or effective delivery on this device? Can a request remain in flight while the user leaves the screen? Does the gateway distinguish an explicit rejection from an unknown result after a timeout? These questions directly affect implementation and tests.

A useful opening explanation is: “I will first check how the screen loads and saves its preference. Then I will fix the misleading success state and add a focused failure test.” That statement names a user problem, an investigation path, and a bounded deliverable. It is more informative than announcing a general cleanup.

Triage defects by the behavior they break

Here is an original triage sheet for this exercise. The ordering assumes the screen remains otherwise accessible; an accessibility defect that prevents interaction would move ahead of cosmetic work.

ObservationWhy it mattersFirst change
Failed save leaves the switch onThe UI claims a preference that was not savedRestore the saved value and show an error
Permission is denied but the page implies delivery worksTwo independent states are being conflatedExplain that device delivery is blocked
Rapid taps start overlapping savesResponses can overwrite newer intentChoose and test a concurrency policy
Spacing differs from the designVisual quality is inconsistentFix after the core behavior is reliable

Do not quietly convert a small repair into a new application architecture. Follow the project’s existing conventions unless they prevent the required behavior. A focused change with a clear limitation is easier to review than a broad rewrite whose correctness depends on several unrelated migrations.

During pairing, keep the investigation visible. Explain a hypothesis before changing code, then say what the test or runtime observation established. If you discover that a presumed network failure is actually a missing state subscription, update your explanation. The value lies in narrowing the problem accurately, not defending your first guess.

Separate saved preference, displayed intent, and permission

For the practice screen, define three concepts explicitly:

  • Saved preference: the account-level value last confirmed by the gateway.
  • Displayed intent: the value currently shown while a save may be pending.
  • Device permission: whether this installation is allowed to deliver notifications.

These definitions are an editorial design choice for the exercise. They are not a claim about Monzo’s implementation or a complete model of either mobile operating system.

Suppose the saved preference is off. The user enables it, so the display becomes on and the screen says “Saving…”. On confirmed success, the saved value becomes on. On a definitive rejection, the display returns to off and an error explains that the save failed. If device permission is denied, a successful account save still does not mean notifications can arrive on that device.

That distinction supports an honest message: “Preference saved; device notifications blocked.” It also avoids erasing account intent merely because a device setting changed. Another product could choose to prevent enabling the preference until permission is available. The interview task is to identify that choice and its consequences, rather than hide it in a Boolean expression.

A small state model makes the trade-off testable

We executed five checks against a local Python state model for this article. It models the transitions above and allows only one write in flight. It is not a native app test: no Android or iOS UI, permission dialog, real network, or server was exercised.

The essential transition logic is small enough to explain without introducing a framework:

def begin_save(state, desired):
    if state.pending:
        return
    state.shown = desired
    state.pending = True
    state.error = None

def finish_save(state, confirmed_success):
    if confirmed_success:
        state.saved = state.shown
    else:
        state.shown = state.saved
        state.error = "Could not save. Try again."
    state.pending = False

The model’s five checks passed: a rejected save restored the old display; a retry cleared the error and confirmed the new value; denied permission preserved the saved account preference; a second tap during a pending write started no additional request; and disabling the account preference remained valid when device permission was denied.

Those checks establish the behavior of this model, not every edge case in the proposed application. In particular, the rejection branch assumes a known failed write. A timeout may leave the result unknown: the server could have committed the change before the response was lost. A real implementation needs a reconciliation rule, such as reading the authoritative preference again before announcing its final state.

Explain the concurrency policy instead of silently choosing one

Single-flight saving is a reasonable first policy for a bounded exercise. Disable the control while saving, make the pending state visible, and ignore duplicate events defensively in the state layer. The executed model verified that second part; it did not verify that a real UI announces or renders the disabled state correctly.

The trade-off is responsiveness. A person who changes their mind must wait for the first save to finish. An alternative is to accept new intent and serialize updates, or cancel and replace an operation when the system can guarantee appropriate semantics. Both alternatives add questions about ordering, cancellation, and failures. “Latest response wins” is unsafe when the latest response belongs to an older user action.

If the interviewer asks for rapid repeated changes, revise the design deliberately. Track desired state separately from confirmed state, identify requests, and define what happens after each completion. Then add a test where the earlier request completes later. Explain why the new requirement justifies the extra machinery; do not add it automatically to every settings screen.

Turn a UI into an implementation blueprint

Begin a design discussion with the observable contract: what the user sees on initial load, after a tap, during saving, and after failure. Next, draw the smallest set of responsibilities needed to support it. For this exercise, that could be a screen, a state holder, a preference gateway, and a device-permission adapter.

Use hypothetical interface names rather than pretending to know a company’s API. A gateway might expose loadPreference() and savePreference(desired). The permission adapter supplies a separate device status. The state holder combines these into a view state without making the gateway responsible for platform UI.

Now test the boundaries with questions. If the app returns from device settings, when does permission refresh? If the screen disappears during a save, who owns completion? If loading the preference fails, is the toggle disabled or displaying cached information? If another device updates the account preference, when will this screen learn about it?

You do not need to solve every extension at once. State the initial scope, choose one follow-up, and revise the relevant boundary. For example, adding cached display introduces a freshness indicator and a reconciliation rule. It does not automatically require an offline write queue. This keeps the discussion tied to requirements rather than to the number of components on the diagram.

Make the review easy to follow

A concise handoff should explain the defect, the changed behavior, and the evidence. For the exercise, say that rejected saves now restore the confirmed value, pending saves block duplicate writes, and permission is shown separately. Then name the tests that demonstrate those behaviors and the limitations they leave open.

Show one failure path during the demonstration. A successful toggle is easy to understand; a failed save reveals whether the interface tells the truth. Afterward, show the smallest relevant diff. Separate a necessary behavior change from optional improvements you deliberately deferred.

For AI tools, distinguish preparation from assessment rules. Monzo’s July 2024 AI interview guidance supports preparation uses while rejecting fabricated examples and AI-generated live interview answers. Follow the instructions for your specific exercise rather than treating general tool access as permission for every use. You should be able to explain and defend all submitted work yourself.

Five practice questions to connect the skills

Use a different review goal for each one.

Practice questionReview goal
Implement A Mobile Chat Interface In An Existing CodebaseTrace existing state before extending behavior
Propose and Validate a Mobile App ImprovementTie a change to a user problem and evidence
Discuss Transferable Experience for a New Mobile Product TeamExplain your contribution and its limits
Design Radius-Based Notifications from Mobile LocationsSeparate product rules from device constraints
Compare front-end state management approachesDefend state ownership and update behavior

Start with the existing-codebase mobile exercise, then review your solution aloud. Can another engineer identify the user-visible contract, the first failure you handled, the evidence for correctness, and the next limitation to address? Those are concrete preparation targets even when the exact interview format changes.

Sources and Further Reading