Architecture patterns, engineering trade-offs, and production-grade techniques every Android engineer should have in their toolkit.
The foundation of every scalable Android app. Clean Architecture with MVVM or MVI ensures strict separation of concerns, independent testability of each layer, and maintainability as the codebase grows.
Interview Tip: When asked "how do you structure a large Android app?", name the three layers explicitly and emphasize that the Domain layer has NO Android imports — this single detail signals deep architectural understanding. Also mention that UseCases encapsulate one business operation each, making them trivially testable.
Users expect apps to function without internet. Single Source of Truth (SSOT) with Room as the local DB and Retrofit for remote data is the industry gold standard. The key insight: UI observes Room, network just populates it.
Interview Tip: The critical insight: Room returns a Flow — so any Room update automatically re-emits to all collectors. This means you never need to manually refresh the UI. The network layer just "writes to Room" and the UI updates itself. This is the reactive SSOT pattern.
At scale, a monolithic app becomes a liability: slow builds, merge conflicts, inability to parallelise development. Feature modules enable team scalability, faster incremental builds, and Play Feature Delivery for smaller APK size.
Interview Tip: Mention the build time impact: in a 50-engineer team, modularisation reduces Gradle compile time from 10+ minutes to under 2 minutes because only changed modules recompile. Also mention convention plugins (build-logic module) to avoid duplicating Gradle config across 20+ modules — interviewers at large companies love this detail.
Predictable, unidirectional state is the foundation of bug-free UIs. Understanding the distinction between screen state (StateFlow), one-time effects (SharedFlow/Channel), and Compose state hoisting is essential for senior engineers.
rememberSaveable for state that must survive process death (form inputs, scroll position).collectAsStateWithLifecycle() — avoids background collection that wastes battery.Interview Tip: The most common interview mistake: using StateFlow for navigation events. On screen rotation, a new collector subscribes and immediately receives the last emitted navigation event — causing double navigation. Always use Channel or SharedFlow(replay=0) for one-time effects. This gotcha shows you have real production experience.
Robust networking handles unreliable mobile connections gracefully. Key concerns: layered interceptors for cross-cutting concerns, retry with exponential backoff, token refresh race conditions, and choosing REST vs GraphQL for your data shape.
Interview Tip: The token refresh race condition is a classic senior interview question. When 5 requests fail with 401 simultaneously, naive implementations refresh the token 5 times. The Mutex solution ensures only one refresh happens and all others wait for the result — this shows you understand concurrency in production networking.
Android aggressively kills background processes to preserve battery. WorkManager is the modern standard for guaranteed deferrable work. Understanding which tool to use — WorkManager, Coroutines, or Foreground Services — is a key decision point.
Interview Tip: When asked "WorkManager vs JobScheduler?": WorkManager wraps JobScheduler (API 23+) and adds guaranteed execution across process death, chainable work, unique work (prevent duplicate jobs), observability via Flow/LiveData, and Hilt injection. You should never use JobScheduler directly in new code.
Memory leaks and frame drops are silent killers in production. Understanding the rendering pipeline, common leak patterns, Baseline Profiles, and measurement tooling is what separates senior engineers from mid-level ones.
Interview Tip: Mention Android Vitals metrics: cold start < 5s, ANR rate < 0.47%, crash rate < 1.09% to stay in Play Store good standing. Baseline Profiles are compiled by the Play Store before first launch — this is how Google's own apps achieve sub-1s cold starts. Bring up Macrobenchmark for measuring in CI.
Defence in depth for mobile: secure the network layer, encrypt local storage, obfuscate code, and add runtime protections. Non-negotiable for fintech, healthcare, and any app handling user credentials or PII.
Interview Tip: For fintech/healthcare interviews, describe the full threat model: network (SSL pinning + HSTS), storage (Keystore + EncryptedSharedPrefs), runtime (root detection + Play Integrity API), code (R8/ProGuard obfuscation + string encryption). Mentioning backup pins to avoid outages on certificate rotation is a detail that stands out.
Choosing the right real-time strategy has profound implications for battery life, server infrastructure costs, and user experience. Each protocol has a different latency, battery, and complexity trade-off.
Interview Tip: On FCM: explain the critical difference between notification messages (system-handled, shown automatically) vs data messages (your app handles, full control over UI). For chat apps, always use data messages so your app can decrypt, format, and show the notification — notification messages expose plaintext to the system.
A robust test strategy catches regressions before users do. Follow the testing pyramid: many fast unit tests, fewer integration tests, minimal but high-value E2E tests. Clean Architecture makes each layer trivially testable in isolation.
Interview Tip: Show you understand the test double hierarchy: use fakes (real in-memory implementations) for repositories to avoid fragile mock setups, mocks (MockK) only when you need to verify interactions were called, and stubs for simple return values. Over-mocking leads to tests that pass when the code is broken.
System design is a conversation about trade-offs, not a quiz with right answers. Practice explaining why you choose each pattern, not just what it is. Every decision has context — show that you understand when and why to apply each approach.