System Design Expectations (Senior Level)
📖 Concept
System design at Google's senior level is one of the most critical rounds. For Android roles, this focuses on mobile-first system design — not just backend architecture.
What Google evaluates:
- Requirements Gathering — Do you ask the right clarifying questions?
- High-Level Architecture — Can you diagram the major components and their interactions?
- API Design — RESTful contracts, data models, request/response schemas
- Data Layer — Local storage, caching strategies, sync mechanisms
- Scalability — How does the system handle millions of users?
- Offline Support — A uniquely mobile concern that backend-focused candidates miss
- Trade-offs — Every decision has pros and cons. Can you articulate them?
- Failure Handling — Network errors, partial sync, conflict resolution
Common mobile system design questions at Google:
- Design Google Photos for Android
- Design Gmail's offline mode
- Design a real-time chat application
- Design a news feed with infinite scroll
- Design Google Maps navigation for Android
- Design an offline-first document editor
The framework for mobile system design:
1. Requirements & Constraints (5 min)
- Functional: What does the app DO?
- Non-functional: Scale, latency, offline, battery
- Out of scope: What to exclude
2. High-Level Architecture (10 min)
- UI Layer → ViewModel → Repository → Data Sources
- Network layer, local database, sync engine
- Diagram the data flow
3. Deep Dive (20 min)
- Pick 2-3 critical components to design in detail
- Data models, API contracts, sync strategies
- Caching, pagination, error handling
4. Trade-offs & Scalability (10 min)
- Alternative approaches considered
- How to handle 10x growth
- Failure scenarios and recovery
Senior-level signal: You should be able to discuss how the mobile client interacts with the backend, even if you're designing the Android side. Understanding the full stack — not just the Android layer — is what separates L5 from L4.
💻 Code Example
1// System Design: Offline-First Sync Architecture (High-Level Code)2// This is the kind of architectural code Google expects you to sketch34// 1. Data Model with sync metadata5data class Note(6 val id: String = UUID.randomUUID().toString(),7 val title: String,8 val content: String,9 val updatedAt: Long = System.currentTimeMillis(),10 val syncStatus: SyncStatus = SyncStatus.PENDING,11 val version: Int = 112)1314enum class SyncStatus { SYNCED, PENDING, CONFLICT }1516// 2. Repository Pattern — Single source of truth17class NoteRepository(18 private val localDb: NoteDao,19 private val remoteApi: NoteApi,20 private val syncEngine: SyncEngine21) {22 // Local-first: always read from local DB23 fun getNotes(): Flow<List<Note>> = localDb.getAllNotes()2425 // Write locally first, then sync26 suspend fun saveNote(note: Note) {27 val updated = note.copy(28 syncStatus = SyncStatus.PENDING,29 updatedAt = System.currentTimeMillis(),30 version = note.version + 131 )32 localDb.upsert(updated)33 syncEngine.schedulePush(updated.id)34 }3536 // Sync engine handles push/pull37 suspend fun sync() {38 syncEngine.pushPendingChanges(localDb, remoteApi)39 syncEngine.pullRemoteChanges(localDb, remoteApi)40 }41}4243// 3. Sync Engine — Conflict resolution strategy44class SyncEngine {45 suspend fun pushPendingChanges(local: NoteDao, remote: NoteApi) {46 val pending = local.getNotesByStatus(SyncStatus.PENDING)47 for (note in pending) {48 try {49 val serverNote = remote.pushNote(note)50 local.upsert(note.copy(51 syncStatus = SyncStatus.SYNCED,52 version = serverNote.version53 ))54 } catch (e: ConflictException) {55 // Last-write-wins or manual conflict resolution56 local.upsert(note.copy(syncStatus = SyncStatus.CONFLICT))57 }58 }59 }6061 suspend fun pullRemoteChanges(local: NoteDao, remote: NoteApi) {62 val lastSync = local.getLastSyncTimestamp()63 val remoteChanges = remote.getChangesSince(lastSync)64 for (change in remoteChanges) {65 val localNote = local.getById(change.id)66 if (localNote == null || localNote.syncStatus == SyncStatus.SYNCED) {67 local.upsert(change.copy(syncStatus = SyncStatus.SYNCED))68 }69 // If local has pending changes, mark as conflict70 }71 }7273 fun schedulePush(noteId: String) {74 // Use WorkManager for reliable background sync75 // Exponential backoff, network constraint76 }77}
🏋️ Practice Exercise
System Design Practice:
- Design Google Photos for Android — focus on image loading, caching, and sync
- Design an offline-capable email client — consider draft saving, send queue, search
- Design a real-time collaborative document editor (like Google Docs)
- Design a ride-sharing app's driver tracking system
- Design Instagram's feed — infinite scroll, caching, prefetching
- Design a notification system for a social media app
- For each design, create:
- Component diagram showing data flow
- API contract for 3 key endpoints
- Local database schema (Room entities)
- Sync strategy with conflict resolution
- Failure handling for 3 common failure modes
- Practice whiteboarding each design in 35 minutes
- Prepare to answer: "How would this change if we needed to support 100M users?"
- Prepare to answer: "What would you change if the user has poor/intermittent connectivity?"
⚠️ Common Mistakes
Designing only the backend and ignoring the Android client architecture — for Android roles, the mobile side is the focus
Not discussing offline support — this is the #1 differentiator for mobile system design
Jumping into low-level details without establishing high-level architecture first
Ignoring data consistency — what happens when the user edits offline and syncs later?
Not quantifying scale — 'a lot of users' is not a number. State assumptions: '10M DAU, 50 req/sec per user'
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for System Design Expectations (Senior Level). Login to unlock this feature.