Skip to main content

Mobile engineer role-specific interview questions

30 questions on role-specific for mobile engineer candidates. Expect prompts such as “Walk through the iOS app lifecycle states” and “Explain the Android Activity back stack and task affinity”, each with a worked answer outline and the follow-ups interviewers push on.

Questions

Showing 1 to 25 of 30 role-specific questions (page 1 of 2).

As asked

Can you walk me through the five UIApplicationDelegate lifecycle states in iOS, what triggers each transition, and where you'd place expensive setup or teardown work in a typical production app?

Sample answer outline

A strong answer names Not Running, Inactive, Active, Background, and Suspended, explains the delegate callbacks (willFinishLaunching, didBecomeActive, willResignActive, didEnterBackground, willTerminate), and notes that background time is limited. Candidate should mention moving heavy init out of didFinishLaunching to avoid slow launch, and doing state-save in didEnterBackground before the 5-second window closes.

Expect these follow-ups

  • How does SceneDelegate change this picture on iOS 13 and later?
  • What happens if your app is suspended and a push arrives while the device has Low Power Mode on?
iosapp-lifecycleuiapplicationdelegatebackground-execution

As asked

Explain how Android's Activity back stack works, what task affinity does, and describe a real scenario where misunderstanding task affinity caused a navigation bug in an app you might build.

Sample answer outline

A strong answer covers the task and back stack model, explains how launch modes (standard, singleTop, singleTask, singleInstance) interact with the back stack, and describes taskAffinity to group activities across packages. The scenario should mention something like a deep-link opening an activity in a new task, causing the back button to exit instead of returning to the parent screen.

Expect these follow-ups

  • How does Fragment back stack differ from Activity back stack?
  • With Jetpack Navigation, how do you replicate singleTop behavior?
androidactivityback-stacknavigationjetpack-navigation

As asked

How does Automatic Reference Counting work in Swift, and what are the three most common patterns that produce retain cycles in iOS apps? How do you detect and fix them?

Sample answer outline

Candidate should explain that ARC deallocates objects when retainCount hits zero, then name delegate cycles (strong delegate property), closure captures of self, and parent-child object graphs. Detection via Xcode Memory Graph Debugger and Instruments Leaks template. Fix with weak/unowned references in closures and delegate declarations, with a note on when unowned is safe versus when it causes a crash.

Expect these follow-ups

  • When would you choose unowned over weak, and what crash does a wrong choice cause?
  • How do Combine subscribers interact with ARC?
swiftarcmemory-managementretain-cycleinstruments

As asked

Describe how structured concurrency works in Kotlin coroutines. What guarantees does it provide, and how does a CoroutineScope tied to an Android ViewModel prevent memory leaks that you would have seen with raw threads or AsyncTask?

Sample answer outline

Strong answer explains that a parent coroutine's scope outlives all children, cancellation propagates down, and exceptions propagate up through SupervisorJob versus Job. For ViewModel: viewModelScope is cancelled in onCleared(), so in-flight network calls are cancelled when the user leaves the screen, avoiding stale callbacks writing to a dead UI.

Expect these follow-ups

  • What is the difference between launch and async in terms of exception handling?
  • How would you test a suspend function that calls a network layer?
kotlincoroutinesstructured-concurrencyviewmodelandroid

As asked

Trace a push notification end-to-end from your backend, through APNs or FCM, to the device, including what can go wrong at each step and how you would debug a report that 'notifications are not being received by some users.'

Sample answer outline

Candidate should name the token registration flow, the backend sending to APNs/FCM with the device token, APNs/FCM delivering to the OS, and the OS waking the app. Common failure points: expired or rotated tokens, invalid certificates or auth keys (APNs HTTP/2 JWT versus p12), user revoked permission, app in foreground requiring UNUserNotificationCenterDelegate, and notification payload exceeding 4KB for APNs. Debugging steps: check APNs HTTP/2 provider API responses for error reason codes (BadDeviceToken, Unregistered with a 410 status) and use those responses to prune stale tokens from the backend. Note that the legacy APNs feedback service was deprecated in 2020 and should not be relied on. On the FCM side, check delivery stats in the Firebase console and handle the NotRegistered error to remove stale tokens.

Expect these follow-ups

  • How does a notification differ from a silent/data-only push, and what background execution time does each get?
  • What happens to queued notifications if a device is offline for 28 days?
push-notificationsapnsfcmiosandroid

As asked

Explain why RecyclerView uses the ViewHolder pattern instead of inflating new views for each item, describe how the RecycledViewPool works in a nested RecyclerView scenario, and name two common performance mistakes you see in RecyclerView adapters.

Sample answer outline

Inflation is expensive; ViewHolder caches findViewById lookups so only bind is called on recycle. RecycledViewPool lets multiple RecyclerViews share a scrap pool, critical for a horizontal list inside a vertical list. Common mistakes: calling notifyDataSetChanged instead of DiffUtil, doing heavy work (image decode, network fetch) in onBindViewHolder on the main thread, or nesting scrollable views that disable recycling.

Expect these follow-ups

  • How does DiffUtil decide which items changed, and what is the O complexity of its diff algorithm?
  • When would you use ConcatAdapter?
androidrecyclerviewviewholderperformancediffutil

As asked

Your company is starting a new mobile app and asks whether to use React Native, Flutter, or two native codebases. Walk me through the decision.

Sample answer outline

Drivers: team composition (web-heavy team favours RN, fresh team can pick either), platform-specific features (heavy use of camera, AR, Bluetooth, background work all push toward native), performance ceiling (graphics-heavy games or 120fps interactions need native), and long-term maintenance (one codebase is cheaper to evolve, two codebases give better platform fidelity). Real answer: most consumer apps ship fine on RN or Flutter; native is right when the app IS the device experience (audio editor, camera app, AAA game). The cost of cross-platform is a lower platform-fidelity ceiling, not raw performance.

Expect these follow-ups

  • What is the migration story from RN to native if you outgrow RN?
  • When does Flutter beat React Native?
  • What is the team size where one native codebase per platform is cheaper than RN?
react-nativeflutterplatform-choice

As asked

Your app must work fully offline and sync data when connectivity returns. Walk me through the sync strategy you would choose, how you handle conflict resolution when the server and local device both have changes, and what data layer you would use on-device.

Sample answer outline

A strong answer picks a concrete local store (SQLite via Room on Android, Core Data or SQLite directly on iOS), describes a queue of pending mutations with idempotency tokens, and explains conflict resolution options (last-write-wins with timestamps, server wins, CRDTs, or vector clocks). Candidate should mention tombstones for deletes, retry with exponential backoff, and surfacing sync status to the UI.

Expect these follow-ups

  • How do you handle a conflict where the server deleted a record the user edited offline?
  • How would you test the sync logic in isolation without a real network?
offline-firstsyncconflict-resolutionroomcore-data

As asked

List the background execution modes available on iOS, explain the time limit for each, and describe which one you would use to keep a fitness tracking app recording location while the user has locked their screen.

Sample answer outline

Answer should cover: background fetch (limited time, system-scheduled), background URLSession (network completion), background processing tasks (BGProcessingTask, up to minutes when plugged in), silent push, and the continuous background modes (location, audio, VoIP, Bluetooth, external accessory). For fitness location: declare the 'location' background mode, use CLLocationManager with allowsBackgroundLocationUpdates = true and pausesLocationUpdatesAutomatically = false, with significant-change as fallback to save battery.

Expect these follow-ups

  • What does the system do if your BGProcessingTask takes longer than its allotted time?
  • How do you test background fetch locally without waiting for the system to decide when to call it?
iosbackground-executioncore-locationbgtaskrequestbattery

As asked

When would you use WorkManager and when would you use a ForegroundService on Android? Give me a concrete example for each, and explain what changes with Doze mode and App Standby buckets.

Sample answer outline

WorkManager is for deferrable, guaranteed work that does not need to run immediately (photo upload, log sync) and survives process death and reboots via JobScheduler/AlarmManager under the hood. ForegroundService is for user-visible work that must run now and continuously (music playback, navigation, live workout). Doze restricts network and wakelocks in maintenance windows; ForegroundServices are exempt. App Standby places apps in buckets (Active, Working Set, Frequent, Rare, Restricted) that throttle WorkManager jobs.

Expect these follow-ups

  • How do you set WorkManager constraints like 'only on Wi-Fi and charging'?
  • What changed in Android 14 regarding ForegroundService types?
androidworkmanagerforeground-servicedozebackground

As asked

Explain Core Data's concurrency model. What is the difference between the main queue context and a private queue context, and how do you safely pass objects between them to avoid crashes?

Sample answer outline

NSManagedObjectContext is not thread-safe. The main context runs on the main queue and drives the UI. Private contexts are spawned for background operations. Objects are bound to their context, so passing an NSManagedObject across contexts causes crashes. Safe patterns: pass NSManagedObjectID across threads and re-fetch in the target context, or use performAndWait/perform on the correct context. Also explain parent-child context pattern for draft editing.

Expect these follow-ups

  • How does NSFetchedResultsController work with context merging from a background import?
  • When would you choose SQLite directly over Core Data?
ioscore-dataconcurrencynsmanagedobjectcontextswift

As asked

Describe how Room database migrations work. What happens if you increment the version number without providing a Migration object, and how do you handle a migration from version 3 to version 5 when the user may have skipped version 4?

Sample answer outline

Without a Migration, Room throws IllegalStateException at runtime if fallbackToDestructiveMigration is not set, or silently drops and recreates the database (losing data) if it is. A Migration(3,5) can be added directly; Room chains migrations so a user on version 2 would run 2-to-3 then 3-to-5. Candidate should mention migration testing with MigrationTestHelper from the Room testing library.

Expect these follow-ups

  • How do you verify that your migration SQL is correct before shipping?
  • What is autoMigrations and when would it not be sufficient?
androidroomsqlitemigrationsdatabase

As asked

Explain how UIKit's rendering pipeline works from a layout pass to pixels on screen. What operations on the main thread cause dropped frames, and how would you find them in Instruments?

Sample answer outline

Pipeline: setNeedsLayout triggers layoutIfNeeded/layoutSubviews, then drawRect for custom drawing, then Core Animation composites layers and commits to the render server, which rastersizes on the GPU. Main thread blocks that drop frames include synchronous network calls, heavy JSON parsing, blocking file I/O, and expensive drawRect implementations. Detection: Instruments Time Profiler to find main thread hangs, Core Animation instrument to see commit duration and offscreen rendering, and the Xcode frame rate graph.

Expect these follow-ups

  • What is offscreen rendering and which UIView properties trigger it?
  • How does SwiftUI's rendering model differ from UIKit's?
iosuikitrenderingperformanceinstruments

As asked

How does Jetpack Compose decide when to recompose a composable? What makes a type 'stable' in Compose's compiler, and what are the consequences of passing an unstable type as a parameter to a composable that should be skippable?

Sample answer outline

Compose tracks State reads at the snapshot level; when a snapshot state object changes, composables that read it are invalidated. A type is stable if it is immutable or implements Stable/Immutable. Passing an unstable type (such as a mutable List or a non-data class) prevents Compose from skipping recomposition even when parameters haven't changed, causing unnecessary work. Fix with @Stable annotation, ImmutableList, or wrapping in a stable wrapper.

Expect these follow-ups

  • How do you use the Compose compiler metrics to see which composables are skippable?
  • What is the difference between remember and rememberSaveable?
androidjetpack-composerecompositionperformancekotlin

As asked

Walk me through the difference between @State, @ObservableObject with @Published, and the new @Observable macro introduced in iOS 17. When would you pick each, and what problem does @Observable solve that ObservableObject did not?

Sample answer outline

State is for local, value-type view state owned by the view. ObservableObject with @Published triggers whole-view redraws when any published property changes. @Observable (Observation framework) tracks per-property access, so only views that actually read a changed property are re-rendered, reducing needless redraws. Candidate should mention @StateObject vs @ObservedObject ownership semantics.

Expect these follow-ups

  • How do you share an @Observable object between two sibling views?
  • What is the @Environment property wrapper used for in SwiftUI?
iosswiftuistate-managementobservableswift

As asked

Our app has grown to 120 MB and marketing is unhappy because users on limited data plans are not downloading it. What concrete techniques would you apply on both iOS and Android to reduce the download size?

Sample answer outline

iOS: enable App Thinning (slicing, bitcode deprecated in Xcode 14, on-demand resources), audit and remove unused assets with tools like LSUnusedResources, switch PNG assets to HEIC or use SF Symbols where possible, enable link-time optimization and dead code stripping, modularize with dynamic frameworks only if sharing. Android: enable R8/ProGuard full mode, split APKs or use App Bundle for ABI and density splits, use vector drawables instead of multiple PNGs, audit third-party SDK sizes with the Android Size Analyzer.

Expect these follow-ups

  • What is the difference between download size and install size on Android, and which metric matters more for user acquisition?
  • How do on-demand resources on iOS work for a level-based game?
app-sizeiosandroidoptimizationapp-bundle

As asked

Your app is listed in users' battery stats as a top consumer even when not actively used. Walk me through a systematic approach to diagnosing the drain and the changes you would make.

Sample answer outline

Diagnosis: Android Battery Historian or iOS Energy Gauge in Instruments to find CPU wakeups, excessive location polling, wake locks, and background network bursts. Common causes: polling timer set too aggressively, holding a GPS lock in background when approximate location would suffice, frequent wake-up from push or background fetch without Doze awareness, blocking main thread causing extra rendering passes. Fixes: batch network requests, use significant-location-change instead of best accuracy, release wake locks promptly, use JobScheduler/WorkManager constraints to run only on charger.

Expect these follow-ups

  • How do you measure battery impact in a CI pipeline before shipping?
  • What is the difference between foreground and background location permission on iOS 14 and later?
batteryperformanceiosandroidbackground-execution

As asked

Describe your workflow for using Xcode Instruments Time Profiler to isolate a performance regression that only appears when scrolling through a large list of images. What specific things do you look for in the call tree?

Sample answer outline

Profile on a real device, not simulator. Record with Time Profiler, focus the call tree to 'Hide System Libraries' first to isolate app code. Look for high self-time functions called repeatedly on the main thread. For image lists, common culprits are synchronous disk reads in cellForRowAtIndexPath, large image decoding on the main thread, and lack of downsampling. Enable the Thread track to confirm main thread work, and cross-reference with the Core Animation instrument to see if commit duration is high.

Expect these follow-ups

  • How would you use the Allocations instrument to check if images are being released correctly?
  • What is the difference between sample-based profiling and system call tracing with os_signpost?
iosinstrumentsperformanceprofilinguikit

As asked

What causes an Application Not Responding error on Android, how does the system determine when to show the dialog, and walk me through reading an ANR traces file to find the root cause?

Sample answer outline

ANR triggers when the main thread does not process an input event within 5 seconds, or a BroadcastReceiver does not finish within 10 seconds, or a Service does not respond within 20 seconds. The system dumps a traces.txt with thread stacks. In the trace, find the main thread stack, look for it waiting on a monitor (lock contention from background thread), blocked on a file or network I/O, or in a long loop. Common fixes: move the work to a coroutine/thread, use StrictMode in debug to catch violations early.

Expect these follow-ups

  • How does StrictMode help catch potential ANR sources during development?
  • What is the difference between an ANR and a crash from the Play Console perspective?
androidanrperformancedebuggingmain-thread

As asked

Describe the layers of automated tests you would put in a CI pipeline for a mobile app, from unit tests through UI tests. What trade-offs do you make about how many UI tests to write, and what tools would you use on each platform?

Sample answer outline

Unit tests: business logic, ViewModels, use cases, repository fakes (XCTest/JUnit). Integration tests: Room/Core Data with real database, network layer with a local mock server (OHHTTPStubs, MockWebServer). UI tests: critical user journeys only because they are slow and flaky (XCUITest, Espresso). Trade-off: UI tests are expensive, so keep them to the top 5 to 10 flows. Screenshot testing (Paparazzi, swift-snapshot-testing) for visual regression without a device. Devices: simulators for unit/integration, real devices or Firebase Test Lab for UI.

Expect these follow-ups

  • How do you handle flaky UI tests in CI without just disabling them?
  • What is a robot pattern in Espresso testing?
testingci-cdiosandroidxcuitestespresso

As asked

Compare MVVM and MVI as architecture patterns for Android or iOS. What problem does MVI's unidirectional data flow solve that MVVM with two-way binding does not, and what overhead does MVI add?

Sample answer outline

MVVM with LiveData/StateFlow is simpler but allows two-way bindings that create event cycles and shared mutable state that is hard to reason about. MVI makes state a single immutable snapshot driven by intents, so every state transition is an explicit function (oldState + event = newState), making it easy to replay and test. Overhead: more boilerplate for intent/state/effect classes, and developers unfamiliar with the pattern find the learning curve steep.

Expect these follow-ups

  • How do you handle one-off side effects like navigation events or toast messages in MVI?
  • Does Jetpack Compose push you toward one pattern over the other?
architecturemvvmmviandroidios

As asked

How would you design a networking layer in Swift that supports request cancellation, automatic retry with exponential backoff, and centralized authentication token refresh without firing multiple refresh calls simultaneously?

Sample answer outline

Use async/await with URLSession; cancellation is via Task.cancel(). For retry, wrap the request in a loop with an attempt counter and await Task.sleep with exponential jitter. For token refresh, use an actor or a serial dispatch queue with a flag so that concurrent requests wait on the single refresh Task using async let or a continuation. Candidate should mention propagating AuthenticationError to the UI and the refresh token expiry edge case.

Expect these follow-ups

  • How do you unit test a retry policy without actually sleeping?
  • What does URLSession's delegate queue do, and is it the main queue by default?
iosnetworkingswiftasync-awaitauthentication

As asked

What does Swift's actor isolation guarantee, and why does the compiler require you to await properties on an actor from outside its context? How does @MainActor interact with UIKit's threading rules?

Sample answer outline

Actors serialize access to their mutable state; any property or method on an actor can only be accessed from within the actor's executor without await, preventing data races. From outside, you must await to hop to the actor's executor. @MainActor is a global actor that guarantees execution on the main queue, replacing DispatchQueue.main.async. UIKit types are annotated @MainActor, so accessing UILabel.text off the main actor is a compiler error in strict concurrency checking mode.

Expect these follow-ups

  • What is nonisolated and when would you annotate a function with it?
  • How do you bridge old completion-handler APIs into the Swift concurrency model safely?
swiftconcurrencyactormain-actorios