AceMobileInterview

Interview guides / mobile

Mobile System Design Interview Questions

Mobile system design interview questions for iOS and Android clients: caching, offline sync, realtime, modularization, and tradeoffs.

Mobile system design is client-first. Interviewers want component diagrams, networking choices, storage, offline behavior, performance, and explicit tradeoffs.

Use AceMobileInterview system design prompts for deeper diagram-level answers on both platforms.

  1. 1.What sections should every mobile system design answer cover?

    Overview, architecture diagram, networking, storage/caching, offline mode, performance, and tradeoffs with when you would pick A vs B. Stay on the client unless asked for backend detail.

  2. 2.How do you talk about offline in a design interview?

    Define source of truth, what remains usable offline, how writes queue, how conflicts resolve, and how UI shows pending/stale/failed. Avoid pretending everything works magically offline.

  3. 3.Design a photo-sharing iOS client: home feed, upload, likes, comments, profile, and push. Give a thorough client design with architecture, diagram-level components, networking, caching, offline, performance, and explicit tradeoffs.

    ## Overview Treat this as a modular iOS client with a local cache, optimistic engagement, resumable uploads, and clear offline degradation—not a backend-only whiteboard. Interviewers want to hear how MVVM boundaries, repositories, and sync interact under real device constraints (memory, battery, flaky networks). ## Architecture diagram ```mermaid flowchart TB subgraph UI["UI layer"] FeedView["FeedView<br/>SwiftUI/UIKit"] UploadView["Upload Composer"] ProfileView["ProfileView"] end subgraph VM["Presentation"] FeedVM["FeedViewModel"] UploadVM["UploadViewModel"] ProfileVM["ProfileViewModel"] end subgraph Domain["Domain / Data"] FeedRepo["FeedRepository"] EngageRepo["EngagementRepository"] UploadMgr["UploadManager actor"] Outbox["Outbox queue"] LocalDB[(SwiftData / Core Data)] ImageCache["Image cache<br/>NSCache + disk"] end subgraph Remote["Remote"] API["REST API"] CDN["Media CDN"] APNs["APNs"] end FeedView --> FeedVM --> FeedRepo UploadView --> UploadVM --> UploadMgr ProfileView --> ProfileVM --> FeedRepo FeedRepo --> LocalDB FeedRepo --> API FeedRepo --> ImageCache ImageCache --> CDN EngageRepo --> Outbox --> API UploadMgr --> API UploadMgr --> LocalDB APNs -.-> FeedVM ``` ## Architecture Use MVVM with feature modules (Feed, Upload, Profile, Notifications). Views stay dumb: they render state and forward intents. ViewModels own UI state (loading/paging/errors/optimistic likes) and call repositories—never URLSession directly. Introduce a Coordinator/Router for profile deep links so features do not import each other. Shared AuthSession + APIClient are injected. UploadManager should be an actor (or serial operation queue) so concurrent composers cannot corrupt the job list. Keep analytics/haptics as side-effect services invoked from ViewModels after state transitions. ## Networking Cursor-paginated feed GET; ETag/If-None-Match on refresh; idempotent like/unlike POST with client-generated keys; comments paginated separately. Media uses server-signed upload URLs (PUT) then a finalize call. APIClient: auth interceptor, single-flight token refresh, decode DTOs → domain models off the main actor. Prefetch next page when the user is ~5 items from the end. Background URLSession for large uploads that must survive app backgrounding. Cancel in-flight detail fetches when leaving a screen. Push (APNs) invalidates feed/inbox and triggers a lightweight sync—not a full refetch storm. ## Storage & caching Local DB is the cache/SoT for recently seen posts, profiles, and draft uploads. Image pipeline: memory NSCache + disk LRU with max bytes; decode at display size via ImageIO. Persist outbox rows for likes/comments. Evict old feed pages aggressively; pin “saved” posts longer. Never store access tokens in UserDefaults—Keychain only. Draft media stays on disk until server ACK, then delete or keep based on product policy. ## Offline mode Show last cached feed with an explicit stale banner and last-updated time. Likes/comments enqueue to outbox and show pending/failed affordances; flush on reconnect (NWPathMonitor). Uploads created offline remain drafts until network returns. Disable network-only surfaces (Explore/Discover) rather than faking freshness. On conflict (like count mismatch), server wins after reconciliation—roll back optimistic UI calmly. ## Performance Stable cell identities; downsample images before assign; prefetch URLs for upcoming cells; avoid main-thread image decode. Prefer diffable data sources / LazyVStack with explicit ids. Compress HEIC/JPEG before upload. Instruments: Time Profiler, Allocations, Hitches, Network. Bound concurrent decodes. Paginate comments; don’t load full comment trees into the feed cell model. ## Tradeoffs ### Optimistic likes vs server-confirmed likes **Option A — Optimistic UI:** Flip heart immediately, enqueue mutation, rollback on failure. Feels instant; requires conflict/rollback UX and careful idempotency. **Option B — Pessimistic UI:** Wait for 200 before updating. Simpler consistency; feels laggy on poor networks and trains users to tap repeatedly. **Pick A when:** Engagement is high-frequency and failures are rare/recoverable. **Pick B when:** Compliance/audit flows or when double-charges/side effects make rollback unsafe. ### Local DB as cache vs view-memory only **Option A — Persisted feed cache:** Survives process death; enables offline reading; more migration/complexity. **Option B — In-memory only:** Simple and fresh, but blank states after kills and no offline story. **Pick A when:** Offline/read-later matters and cold start UX matters. **Pick B when:** MVP throwaway prototype or highly personalized feed that is meaningless when stale. ### Background uploads vs foreground-only **Option A — Background URLSession:** Uploads continue when backgrounded; more setup (delegates, rejoin sessions) and edge cases. **Option B — Foreground only:** Easier reasoning; large uploads fail if user leaves. **Pick A when:** Media is core and uploads are multi-MB. **Pick B when:** Small images and sessions are short.

  4. 4.Design a feature-flag / remote-config system for a large iOS app: staged rollouts, kill switches, experimentation, and safe startup.

    ## Overview Flags must be cached-first, typed, and non-blocking at launch, with kill switches that can disable broken features without an App Store release. ## Architecture diagram ```mermaid flowchart TB App[App launch] --> Cache[Disk flag snapshot] Cache --> Snapshot[In-memory snapshot] Snapshot --> VM[Feature ViewModels] App --> Fetch[Remote Config fetch] Fetch -->|update| Snapshot Fetch -->|persist| Cache Push[Silent push] --> Fetch Defaults[Compiled defaults] --> Snapshot ``` ## Architecture FeatureFlagProvider protocol with typed keys. ViewModels depend on the provider—not NotificationCenter blasts. Experiment assignment sits beside flags. Bootstrap defaults ship in-binary for first install. ## Networking Non-blocking fetch on launch + periodic refresh + optional silent push. Short timeout; CDN JSON/protobuf; schema version field. Analytics exposures batched. ## Storage & caching Last-known-good on disk; schema migrations; unknown keys ignored; defaults always defined. ## Offline mode Offline uses cache/defaults forever; never crash on missing key; queue exposures. ## Performance O(1) dictionary reads; parse off main; atomic snapshot swap on MainActor if UI observes. ## Tradeoffs ### Cached-first vs network-first launch **Option A — Cached-first:** Instant startup using last snapshot; may be briefly stale. **Option B — Network-first:** Freshest flags; slows/blocks launch and fails offline. **Pick A when:** Consumer apps where launch time matters. **Pick B when:** Rare safety-critical configs that must be fresh (still prefer timeout+cache fallback). ### Client percentage rollout vs server targeting **Option A — Client hash of userId:** Works offline; simple; weaker abuse control. **Option B — Server decides:** Central control and richer targeting; requires network. **Pick A when:** Sticky offline experiments. **Pick B when:** Regulated targeting or rapid kill that must be server authoritative. ### Many fine-grained flags vs coarse modules **Option A — Fine-grained:** Precise control; operational sprawl and interactions. **Option B — Coarse modules:** Fewer combinations; less flexibility. **Pick A when:** Mature platform with flag hygiene. **Pick B when:** Early product—prefer fewer flags.

  5. 5.Design a robust iOS networking layer: auth, refresh, retries, errors, caching, testability.

    ## Overview A single APIClient with interceptor pipeline and protocol boundaries keeps features testable and consistent. ## Architecture diagram ```mermaid flowchart TB VM --> Repo --> APIClient APIClient --> Auth[Auth Interceptor] APIClient --> Retry[Retry Policy] APIClient --> Session[URLSession] Auth --> Keychain Repo --> DTO[DTO mapper] ``` ## Architecture Features depend on repositories/protocols. APIClient handles auth header, redacted logs, refresh single-flight (actor). Map transport errors to domain errors for ViewModels. ## Networking One session config; refresh-on-401 once; retry idempotent GETs only by default; timeouts; optional pinning for high risk. ## Storage & caching Tokens Keychain; URLCache where safe; DTO≠domain; per-endpoint TTL policies. ## Offline mode NWPathMonitor fail-fast OfflineError; writes use feature outboxes—not generic HTTP magic. ## Performance Cancel on disappear; coalesce duplicate GETs; measure p95; HTTP/2. ## Tradeoffs ### Refresh strategy **Option A — Refresh on 401:** Lazy; can stampede without single-flight. **Option B — Proactive refresh:** Fewer mid-flight failures; more refresh traffic. **Pick A when:** With single-flight lock. **Pick B when:** Short-lived tokens with predictable expiry. ### Library vs URLSession **Option A — URLSession:** First-party, enough for most. **Option B — Alamofire/etc:** Faster extras; dependency cost. **Pick A when:** Default modern apps. **Pick B when:** Team already standardized on a lib.

  6. 6.Design a scalable iOS news reader: personalized feed, offline reading, breaking-news push, and image-heavy articles.

    ## Overview Separate “online personalized feed” from “offline readable saved articles,” with Room-like local SoT and careful image pipelines. ## Architecture diagram ```mermaid flowchart TB FeedUI --> FeedVM --> Repo[ArticleRepository] Repo --> DB[(Local DB)] Repo --> API DetailUI --> DetailVM --> Repo Repo --> Images[Image pipeline] Images --> CDN APNs --> FeedVM ``` ## Architecture MVVM; FeedViewModel pages summaries; DetailViewModel loads body. Repository merges API + DB. ContentRenderer isolates HTML/Markdown. Router handles article deep links from push. ## Networking Cursor pagination; conditional GET; CDN images; background download for saved issues; cancel on pop; batch analytics. ## Storage & caching DB for articles/read/saved; image memory+disk cache; TTL for feed; saved articles pinned. ## Offline mode Saved/read offline; feed shows last snapshot + stale label; queue bookmarks; don’t fake personalization refresh offline. ## Performance Prefetch pages; downsample images; stable IDs; hitch profiling; avoid loading full HTML in list cells. ## Tradeoffs ### Server-driven UI vs native cells **Option A — Native cells:** Best performance/control; slower product iteration. **Option B — Server-driven components:** Flexible; riskier perf and app-review complexity. **Pick A when:** Feed FPS is a KPI. **Pick B when:** Editorial needs rapid layout experiments. ### Sync strategy **Option A — Cache-then-network:** Fast paint then refresh. **Option B — Network-only:** Always fresh; slower/blank offline. **Pick A when:** Most news apps. **Pick B when:** Strict live trading-style data (not news).

  7. 7.Design the rider Android app: maps, realtime location, trip state machine, payments, offline resilience. Thorough client design with diagram-level components and explicit tradeoffs.

    ## Overview Mirror a server-authoritative trip state machine on device, stream location separately from command APIs, and degrade honestly offline. ## Architecture diagram ```mermaid flowchart TB UI[Map + Trip Compose UI] --> VM[TripViewModel] VM --> Domain[TripSession use case] Domain --> Repo[TripRepository] Repo --> REST[Trip REST] Repo --> RT[Location Flow/WebSocket] Repo --> Room[(Room)] Pay[Payments] --> VM ``` ## Architecture UDF/MVVM: TripViewModel exposes immutable UI state; TripSession domain owns transitions. Maps SDK behind an interface. Hilt injection. Foreground service only while trip requires it and policy allows. ## Networking REST commands with idempotency; realtime socket for locations/events; OkHttp authenticator; reconnect backoff; polling fallback. ## Storage & caching Room history; DataStore activeTripId; last location cache; no sensitive payment storage. ## Offline mode Show last state offline; queue cancel; block new requests; reconcile version on reconnect. ## Performance Throttle map invalidations; fused location intervals by phase; sample UI collect at 1–2 Hz; battery budgets; Baseline profiles. ## Tradeoffs ### Trip authority **Option A — Server authoritative:** Correct dispatch/money; client may lag. **Option B — Client authoritative:** Feels instant; desync risk. **Pick A when:** Always. **Pick B when:** Never for dispatch. ### Realtime transport **Option A — WebSocket:** Low latency; connection ops. **Option B — Polling:** Simple; laggy. **Pick A when:** Live tracking core. **Pick B when:** Early MVP. ### Foreground service **Option A — In-trip FS:** Reliable updates; UX/notification cost. **Option B — No FS:** Less reliable background. **Pick A when:** Active ongoing trip. **Pick B when:** Browsing only.

  8. 8.Design a robust Android networking layer: auth, refresh, retries, errors, caching, testability.

    ## Overview A single APIClient with interceptor pipeline and protocol boundaries keeps features testable and consistent. ## Architecture diagram ```mermaid flowchart TB VM --> Repo --> APIClient APIClient --> Auth[Auth Interceptor] APIClient --> Retry[Retry Policy] APIClient --> Session[OkHttp/Retrofit] Auth --> EncryptedStorage/DataStore Repo --> DTO[DTO mapper] ``` ## Architecture Features depend on repositories/protocols. APIClient handles auth header, redacted logs, refresh single-flight (actor). Map transport errors to domain errors for ViewModels. ## Networking One session config; refresh-on-401 once; retry idempotent GETs only by default; timeouts; optional pinning for high risk. ## Storage & caching Tokens EncryptedStorage/DataStore; URLCache where safe; DTO≠domain; per-endpoint TTL policies. ## Offline mode ConnectivityManager fail-fast OfflineError; writes use feature outboxes—not generic HTTP magic. ## Performance Cancel on disappear; coalesce duplicate GETs; measure p95; HTTP/2. ## Tradeoffs ### Refresh strategy **Option A — Refresh on 401:** Lazy; can stampede without single-flight. **Option B — Proactive refresh:** Fewer mid-flight failures; more refresh traffic. **Pick A when:** With single-flight lock. **Pick B when:** Short-lived tokens with predictable expiry. ### Library vs OkHttp/Retrofit **Option A — OkHttp/Retrofit:** First-party, enough for most. **Option B — Alamofire/etc:** Faster extras; dependency cost. **Pick A when:** Default modern apps. **Pick B when:** Team already standardized on a lib.

  9. 9.How would you modularize a large Android codebase for build speed, ownership, and clean architecture? Include module diagram thinking and tradeoffs.

    ## Overview Gradle modules encode architecture: app → features → cores, with API/impl splits to prevent cycles. ## Architecture diagram ```mermaid flowchart TB app[:app] --> featureFeed[:feature:feed] app --> featureAuth[:feature:auth] featureFeed --> coreNet[:core:network] featureAuth --> coreNet featureFeed --> coreUI[:core:ui] featureFeed --> coreDB[:core:database] ``` ## Architecture MVVM/UDF inside features. :core:network/:ui/:database/:domain. Features expose entry points only. Navigation abstractions prevent feature↔feature cycles. Hilt aggregation at app. ## Networking Shared OkHttp/Retrofit in core; feature API interfaces; optional dynamic features. ## Storage & caching Document Room ownership; single DB vs multi-DB; migrations owned by schema owners. ## Offline mode core:sync primitives; features plug payload codecs. ## Performance Config cache; parallel builds; Baseline Profile in app; R8 consumer rules; watch AGP costs of too many modules. ## Tradeoffs ### Granularity **Option A — Many modules:** Ownership/build parallel; overhead. **Option B — Few modules:** Simpler; merge conflicts. **Pick A when:** Multi-team. **Pick B when:** Small team. ### Dynamic features **Option A — On-demand modules:** Smaller base; install friction. **Option B — All in base:** Simpler UX; larger download. **Pick A when:** Large optional features. **Pick B when:** Most users need everything.

  10. 10.Design a scalable Android news reader: personalized feed, offline reading, breaking-news push, and image-heavy articles.

    ## Overview Separate “online personalized feed” from “offline readable saved articles,” with Room-like local SoT and careful image pipelines. ## Architecture diagram ```mermaid flowchart TB FeedUI --> FeedVM --> Repo[ArticleRepository] Repo --> DB[(Local DB)] Repo --> API DetailUI --> DetailVM --> Repo Repo --> Images[Image pipeline] Images --> CDN FCM --> FeedVM ``` ## Architecture MVVM / UDF; FeedViewModel pages summaries; DetailViewModel loads body. Repository merges API + DB. ContentRenderer isolates HTML/Markdown. Router handles article deep links from push. ## Networking Cursor pagination; conditional GET; CDN images; background download for saved issues; cancel on pop; batch analytics. ## Storage & caching DB for articles/read/saved; image memory+disk cache; TTL for feed; saved articles pinned. ## Offline mode Saved/read offline; feed shows last snapshot + stale label; queue bookmarks; don’t fake personalization refresh offline. ## Performance Prefetch pages; downsample images; stable IDs; hitch profiling; avoid loading full HTML in list cells. ## Tradeoffs ### Server-driven UI vs native cells **Option A — Native cells:** Best performance/control; slower product iteration. **Option B — Server-driven components:** Flexible; riskier perf and app-review complexity. **Pick A when:** Feed FPS is a KPI. **Pick B when:** Editorial needs rapid layout experiments. ### Sync strategy **Option A — Cache-then-network:** Fast paint then refresh. **Option B — Network-only:** Always fresh; slower/blank offline. **Pick A when:** Most news apps. **Pick B when:** Strict live trading-style data (not news).

Keep going with AceMobileInterview

Reading helps. Timed practice locks it in. Jump into the interactive track for algorithms with LeetCode links, studio projects, debugging zips, and mobile system design.

iOS trackAndroid trackMore guides