5-Day Intensive Android Interview Prep Plan for Google Senior Software
Engineer
Overview
This is an aggressive, comprehensive plan to prepare for Google's Android Senior Software Engineer interview
in 5 days. The plan assumes 16-18 hours of focused study per day (with breaks for sleep/rest).
Interview Rounds You're Preparing For:
1. DSA (You're managing separately)
2. Android Technical Interview
3. Hands-on Android Project Round
DAY 1: Kotlin Fundamentals + Core Android Components (18 hours)
Morning Session (6 hours): Kotlin Deep Dive
Part 1: Kotlin Basics (2 hours)
Variables & Types: val vs var, const val, lateinit, lazy
Functions: Higher-order functions, extension functions, infix functions
Null Safety: Nullable types, safe calls (?.), elvis operator (?:), !! operator
Data Classes: Auto-generated methods, copy(), destructuring
Sealed Classes & Objects: When to use, companion objects
Lambda Expressions: Syntax, trailing lambdas, with/apply/let/run/also
Practice Exercise:
kotlin
// Create a data class for User with validation
data class User(val name: String, val email: String) {
init {
require([Link]("@")) { "Invalid email" }
}
}
// Extension function example
fun [Link]() = contains("@") && contains(".")
// Higher-order function
fun processUser(user: User, action: (User) -> Unit) {
action(user)
}
Part 2: Kotlin Coroutines (4 hours) CRITICAL
Must-Know Concepts:
Structured Concurrency
Coroutine Scopes: GlobalScope, lifecycleScope, viewModelScope, coroutineScope
Dispatchers: Main, IO, Default, Unconfined
Launch vs Async/Await
suspend functions
Job, Deferred
Exception Handling in Coroutines
Coroutine Context
Key Interview Questions:
1. Difference between launch and async?
2. What happens if exception is thrown in async but await() is never called?
3. How to run coroutines in parallel vs sequential?
4. Explain structured concurrency
5. What is SupervisorJob?
Hands-on Exercise:
kotlin
// Sequential execution
suspend fun fetchUserData() {
val user = fetchUser() // Waits
val posts = fetchPosts() // Waits after user
}
// Parallel execution
suspend fun fetchUserDataParallel() = coroutineScope {
val userDeferred = async { fetchUser() }
val postsDeferred = async { fetchPosts() }
Pair([Link](), [Link]())
}
// Exception handling
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught: $exception")
}
Afternoon Session (6 hours): Core Android Components
Android Application Components (3 hours)
Activities:
Activity Lifecycle (onCreate → onStart → onResume → onPause → onStop → onDestroy)
onSaveInstanceState & onRestoreInstanceState
Launch Modes: standard, singleTop, singleTask, singleInstance
Task & Back Stack management
Configuration changes handling
Fragments:
Fragment Lifecycle vs Activity Lifecycle
Fragment Transactions & BackStack
Fragment communication (ViewModel, Interfaces)
FragmentContainerView
Why use fragments?
Services:
Foreground Service vs Background Service
Started Service vs Bound Service
IntentService (deprecated, use WorkManager)
Service lifecycle
Broadcast Receivers:
Static vs Dynamic registration
LocalBroadcastManager
Ordered broadcasts
Content Providers:
CRUD operations
ContentResolver
URI matching
When to use?
Key Interview Questions:
1. Activity lifecycle when opening another activity
2. Difference between onPause and onStop
3. When is onDestroy() not called?
4. How to handle process death?
5. Fragment vs Activity - when to use which?
6. Launch modes practical scenarios
7. Service vs IntentService vs WorkManager
Intents & Navigation (1.5 hours)
Explicit vs Implicit Intents
Intent Filters
PendingIntent
Deep Links & App Links
Navigation Component (Jetpack)
Android Manifest (0.5 hours)
Essential tags and attributes
Permissions (runtime vs install-time)
Application class
Evening Session (6 hours): First Practice Project
Project 1: News Reader App (6 hours) Build a news app using:
Kotlin + Coroutines
MVVM Architecture (prepare for Day 2)
RecyclerView with DiffUtil
Multiple Activities/Fragments
Proper lifecycle handling
Requirements:
List of news articles
Detail screen
Handle rotation properly
Loading states
Error handling
DAY 2: Architecture Patterns + Jetpack Components (18 hours)
Morning Session (6 hours): MVVM Architecture GOOGLE FAVORITE
MVVM Deep Dive (4 hours)
Components:
1. Model: Data layer (Repository, Data Sources, API, Database)
2. View: UI Layer (Activity/Fragment/Compose)
3. ViewModel: Business logic, state management
Key Concepts:
ViewModel lifecycle awareness
ViewModelFactory
LiveData vs StateFlow vs SharedFlow
Repository Pattern
Single Source of Truth
Unidirectional Data Flow
LiveData vs Flow vs StateFlow:
kotlin
// LiveData - lifecycle aware, always has value
val userData: LiveData<User> = MutableLiveData()
// StateFlow - always has value, Kotlin Flow + State
val userData: StateFlow<User> = MutableStateFlow(User())
// SharedFlow - can be hot, no initial value needed
val events: SharedFlow<Event> = MutableSharedFlow()
// Flow - cold stream, reactive
fun getUsers(): Flow<List<User>> = flow {
emit([Link]())
}
Must Practice:
Converting callbacks to Flow/LiveData
Combining multiple data sources
Error handling in ViewModels
Testing ViewModels
Clean Architecture (2 hours)
Layers:
1. Presentation Layer: UI + ViewModel
2. Domain Layer: Use Cases, Business Logic, Domain Models
3. Data Layer: Repository, Data Sources, DTOs
Benefits:
Testability
Separation of concerns
Independence from frameworks
Scalability
Key Interview Questions:
1. Why MVVM over MVP/MVC?
2. How to communicate between ViewModel and View?
3. ViewModel vs AndroidViewModel
4. How to share ViewModel between fragments?
5. Explain Single Source of Truth
6. When to use LiveData vs Flow?
7. How to handle configuration changes in MVVM?
Afternoon Session (6 hours): Jetpack Components
Room Database (2 hours) CRITICAL
Components:
Entity (Table)
DAO (Data Access Object)
Database (Singleton)
Must Know:
Relationships (@Relation, @Embedded)
Migrations
Type Converters
Transactions
Flow + Room for reactive queries
[Link]
kotlin
@Entity(tableName = "users")
data class UserEntity(
@PrimaryKey val id: Int,
@ColumnInfo(name = "user_name") val name: String
)
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAllUsers(): Flow<List<UserEntity>>
@Insert(onConflict = [Link])
suspend fun insert(user: UserEntity)
@Transaction
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUserWithPosts(userId: Int): UserWithPosts
}
@Database(entities = [UserEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
@Volatile private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
}
}
}
Retrofit + Networking (1.5 hours)
REST API calls
Converters (Gson, Moshi, Kotlinx Serialization)
Interceptors (OkHttp)
Error handling
Suspend functions with Retrofit
Combining with Coroutines/Flow
kotlin
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") id: Int): Response<User>
@POST("users")
suspend fun createUser(@Body user: User): Response<User>
}
// Repository
class UserRepository(private val api: ApiService) {
suspend fun getUser(id: Int): Result<User> {
return try {
val response = [Link](id)
if ([Link]) {
[Link]([Link]()!!)
} else {
[Link](Exception([Link]()))
}
} catch (e: Exception) {
[Link](e)
}
}
}
WorkManager (1 hour)
For deferrable background work
Constraints (network, charging, etc.)
OneTimeWorkRequest vs PeriodicWorkRequest
Chaining work
WorkManager vs JobScheduler vs AlarmManager
Paging 3 Library (1 hour)
PagingSource
Paging with Room
RemoteMediator
Load states
Navigation Component (0.5 hours)
NavGraph, NavHost, NavController
Safe Args
Deep linking
Evening Session (6 hours): Project 2 - Advanced Architecture
Project 2: Task Manager App (6 hours) Build with:
MVVM + Clean Architecture
Room Database
Retrofit API (use JSONPlaceholder)
Repository Pattern
Flow/StateFlow
Coroutines
WorkManager for sync
Features:
CRUD operations
Offline-first approach
Pull to refresh
Search functionality
Proper error handling
DAY 3: Jetpack Compose + Modern UI (18 hours)
Morning Session (6 hours): Jetpack Compose Fundamentals MUST KNOW
Compose Basics (3 hours)
Core Concepts:
Declarative UI vs Imperative UI
Composable functions (@Composable)
Composition vs Recomposition
State & State Hoisting
remember, rememberSaveable
Modifier system
Layouts: Column, Row, Box, LazyColumn, LazyRow
State Management:
kotlin
@Composable
fun Counter() {
// State that survives recomposition
var count by remember { mutableStateOf(0) }
// State that survives process death
var count2 by rememberSaveable { mutableStateOf(0) }
Column {
Text("Count: $count")
Button(onClick = { count++ }) {
Text("Increment")
}
}
}
// State hoisting
@Composable
fun StatelessCounter(
count: Int,
onIncrement: () -> Unit
){
Button(onClick = onIncrement) {
Text("Count: $count")
}
}
Side Effects in Compose (2 hours) CRITICAL FOR INTERVIEWS
Must Master:
1. LaunchedEffect: For suspend functions
2. DisposableEffect: Setup/cleanup (like useEffect in React)
3. SideEffect: Publish state to non-compose code
4. derivedStateOf: Computed state
5. rememberCoroutineScope: Manual coroutine launch
6. rememberUpdatedState: Capture latest value in callback
kotlin
// LaunchedEffect - runs when key changes
LaunchedEffect(userId) {
val user = [Link](userId)
// Update state
}
// DisposableEffect - cleanup needed
DisposableEffect(Unit) {
val listener = LocationListener()
[Link](listener)
onDispose {
[Link](listener)
}
}
// rememberCoroutineScope - for event handlers
val scope = rememberCoroutineScope()
Button(onClick = {
[Link] {
[Link]("Message")
}
}) {
Text("Show Snackbar")
}
// derivedStateOf - expensive computation
val filteredList by remember {
derivedStateOf {
[Link] { [Link] }
}
}
Compose Performance (1 hour)
Avoiding unnecessary recompositions
Key parameter in lists
Stability in Compose
Immutable collections
@Stable and @Immutable annotations
Afternoon Session (6 hours): Advanced Compose
Compose + ViewModel (2 hours)
kotlin
@Composable
fun UserScreen(viewModel: UserViewModel = viewModel()) {
val uiState by [Link]()
when (uiState) {
is Loading -> LoadingScreen()
is Success -> UserList([Link])
is Error -> ErrorScreen([Link])
}
}
// ViewModel
class UserViewModel : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
init {
loadUsers()
}
private fun loadUsers() {
[Link] {
try {
val users = [Link]()
_uiState.value = Success(users)
} catch (e: Exception) {
_uiState.value = Error([Link])
}
}
}
}
Material Design 3 in Compose (1 hour)
Material Theme
Colors, Typography, Shapes
Material Components
Dark theme support
Lists & Performance (2 hours)
LazyColumn vs Column
LazyVerticalGrid
Sticky headers
Item animations
Keys in lists
Navigation in Compose (1 hour)
NavHost, NavController
Passing arguments
Bottom navigation
Nested navigation
Evening Session (6 hours): Project 3 - Compose App
Project 3: E-commerce Product Catalog (6 hours) Build with:
100% Jetpack Compose
MVVM Architecture
StateFlow/Flow
Navigation Compose
Material Design 3
LazyColumn with pagination
Search & Filter
Detail screen with animations
DAY 4: System Design + Advanced Topics (18 hours)
Morning Session (6 hours): Android System Design CRITICAL FOR GOOGLE
System Design Approach (1 hour)
Steps:
1. Clarify requirements (5 min)
2. High-level design (10 min)
3. Component design (15 min)
4. Deep dive into critical components (15 min)
5. Trade-offs & Optimizations (10 min)
Common Questions:
1. Design WhatsApp
2. Design Instagram
3. Design News Reader App
4. Design File Download Manager
5. Design Stopwatch (Google asked this!)
6. Design Image Loading Library
7. Design Analytics Library
System Design Practice (5 hours)
Problem 1: Design WhatsApp (2 hours)
Requirements:
Send/receive text messages
Online/offline status
Message delivery status (sent, delivered, read)
Offline support
Real-time updates
Solution Outline:
Architecture: MVVM + Clean Architecture
Layers:
├── Presentation (Compose/XML + ViewModel)
├── Domain (UseCases)
└── Data
├── Repository
├── Local (Room Database)
└── Remote (WebSocket + REST API)
Key Components:
1. Data Layer:
- WebSocket for real-time messaging
- REST API for historical messages
- Room DB for offline storage
- Repository as single source of truth
2. Message Sync:
- WorkManager for background sync
- Exponential backoff for retries
- Conflict resolution strategy
3. Message States:
- Pending (storing locally)
- Sent (delivered to server)
- Delivered (user received)
- Read (user opened)
4. Online/Offline:
- ConnectivityManager + NetworkCallback
- Ping/pong mechanism via WebSocket
- Update UI based on connection state
5. Performance:
- Pagination for message history
- Message batching
- DB indexing
- Message pooling
Database Schema:
@Entity
data class Message(
@PrimaryKey val id: String,
val senderId: String,
val receiverId: String,
val content: String,
val timestamp: Long,
val status: MessageStatus, // PENDING, SENT, DELIVERED, READ
val type: MessageType // TEXT, IMAGE, VIDEO
)
WebSocket Events:
- onMessageReceived
- onMessageStatusUpdate
- onUserOnlineStatus
- onTypingIndicator
Problem 2: Design Instagram Feed (1.5 hours)
Requirements:
Infinite scroll feed
Images/videos
Like, comment, share
Offline support
Preload next page
Key Points:
Paging 3 with RemoteMediator
Image caching (Glide/Coil)
Video playback optimization
Feed ranking algorithm
Database normalization
Problem 3: Design Stopwatch (Google Question!) (1.5 hours)
Requirements:
Start, pause, stop, lap
Millisecond precision
Persist across config changes
No system libraries
Solution:
kotlin
class StopwatchUseCase {
private var startTime = 0L
private var pausedTime = 0L
private var isRunning = false
private val laps = mutableListOf<Long>()
private val _timeFlow = MutableStateFlow(0L)
val timeFlow: StateFlow<Long> = _timeFlow
private var job: Job? = null
fun start() {
if (!isRunning) {
startTime = [Link]() - pausedTime
isRunning = true
job = CoroutineScope([Link]).launch {
while (isRunning) {
_timeFlow.value = [Link]() - startTime
delay(10) // 10ms precision
}
}
}
}
fun pause() {
if (isRunning) {
pausedTime = [Link]() - startTime
isRunning = false
job?.cancel()
}
}
fun stop() {
isRunning = false
pausedTime = 0L
startTime = 0L
_timeFlow.value = 0L
[Link]()
job?.cancel()
}
fun lap() {
[Link](_timeFlow.value)
}
}
// ViewModel
class StopwatchViewModel : ViewModel() {
private val stopwatchUseCase = StopwatchUseCase()
val time = [Link]
.stateIn(
viewModelScope,
[Link](5000),
0L
)
fun start() = [Link]()
fun pause() = [Link]()
fun stop() = [Link]()
}
// In Compose
@Composable
fun StopwatchScreen(viewModel: StopwatchViewModel = viewModel()) {
val time by [Link]()
Column {
Text(formatTime(time))
Row {
Button(onClick = viewModel::start) { Text("Start") }
Button(onClick = viewModel::pause) { Text("Pause") }
Button(onClick = viewModel::stop) { Text("Stop") }
}
}
}
fun formatTime(millis: Long): String {
val seconds = (millis / 1000) % 60
val minutes = (millis / (1000 * 60)) % 60
val hours = millis / (1000 * 60 * 60)
val ms = (millis % 1000) / 10
return "%02d:%02d:%02d.%02d".format(hours, minutes, seconds, ms)
}
Afternoon Session (6 hours): Performance & Optimization
Memory Management (2 hours)
Topics:
Memory Leaks (Handler, Context, static references)
Leak Detection (LeakCanary)
Memory Profiler
Bitmap handling
WeakReference, SoftReference
Memory thrashing
GC types
Common Leaks:
kotlin
// BAD - Memory Leak
class MyActivity : AppCompatActivity() {
companion object {
private var context: Context? = null // LEAK!
}
}
// GOOD - Use Application Context
class MyActivity : AppCompatActivity() {
companion object {
private var context: Context? = null
fun init(app: Application) {
context = [Link]
}
}
}
// BAD - Handler Leak
private val handler = Handler() { // LEAK!
// Handle message
true
}
// GOOD - WeakReference
private class MyHandler(activity: MainActivity) : Handler() {
private val weakActivity = WeakReference(activity)
override fun handleMessage(msg: Message) {
[Link]()?.let {
// Use activity
}
}
}
App Performance (2 hours)
Metrics:
App startup time (cold, warm, hot)
Frame rate (60fps, 120fps)
ANR (Application Not Responding)
Jank/Frame drops
Optimization Techniques:
ViewStub for lazy inflation
RecyclerView optimizations (ViewHolder pattern, DiffUtil, RecycledViewPool)
Avoid overdraw
Use ConstraintLayout over nested layouts
Profile-guided optimization
R8/ProGuard
App Bundle
StrictMode:
kotlin
if ([Link]) {
[Link](
[Link]()
.detectAll()
.penaltyLog()
.build()
)
[Link](
[Link]()
.detectAll()
.penaltyLog()
.build()
)
}
Dependency Injection - Hilt/Dagger (2 hours) IMPORTANT
Hilt Setup:
kotlin
@HiltAndroidApp
class MyApplication : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity()
@AndroidEntryPoint
class UserFragment : Fragment()
// Module
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideDatabase(@ApplicationContext context: Context): AppDatabase {
return [Link](
context,
AppDatabase::[Link],
"app_database"
).build()
}
@Provides
fun provideUserDao(database: AppDatabase): UserDao {
return [Link]()
}
}
// ViewModel with Hilt
@HiltViewModel
class UserViewModel @Inject constructor(
private val repository: UserRepository
) : ViewModel() {
// Implementation
}
Evening Session (6 hours): Testing
Unit Testing (2 hours)
JUnit 4/5
Mockito, MockK
Testing ViewModels
Testing Repositories
Coroutine testing (TestCoroutineDispatcher)
kotlin
class UserViewModelTest {
@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()
@get:Rule
val mainDispatcherRule = MainDispatcherRule()
private lateinit var repository: UserRepository
private lateinit var viewModel: UserViewModel
@Before
fun setup() {
repository = mockk()
viewModel = UserViewModel(repository)
}
@Test
fun `loadUsers should update state to Success`() = runTest {
// Given
val users = listOf(User(1, "Test"))
coEvery { [Link]() } returns [Link](users)
// When
[Link]()
// Then
assert([Link] is Success)
assertEquals(users, ([Link] as Success).data)
}
}
UI Testing (2 hours)
Espresso
Compose Testing
UI Automator
Screenshot testing
kotlin
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun counterIncrements() {
[Link] {
Counter()
}
[Link]("0").assertExists()
[Link]("Increment").performClick()
[Link]("1").assertExists()
}
Integration Testing (1 hour)
Testing with real database
Testing API calls
End-to-end testing
Project 4: Implement Tests (1 hour)
Add tests to one of your previous projects.
DAY 5: Advanced Topics + Mock Interviews (18 hours)
Morning Session (6 hours): Advanced Android Topics
Custom Views (2 hours)
kotlin
class CircularProgressBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = [Link]
strokeWidth = 20f
}
var progress = 0f
set(value) {
field = [Link](0f, 100f)
invalidate() // Redraw
}
override fun onDraw(canvas: Canvas) {
[Link](canvas)
val centerX = width / 2f
val centerY = height / 2f
val radius = minOf(centerX, centerY) - [Link]
// Draw background circle
[Link] = [Link]
[Link](centerX, centerY, radius, paint)
// Draw progress arc
[Link] = [Link]
val sweepAngle = (progress / 100f) * 360f
[Link](
centerX - radius,
centerY - radius,
centerX + radius,
centerY + radius,
-90f,
sweepAngle,
false,
paint
)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val size = minOf(
[Link](widthMeasureSpec),
[Link](heightMeasureSpec)
)
setMeasuredDimension(size, size)
}
}
Animations (1 hour)
View animations (Alpha, Scale, Translate, Rotate)
Property animations (ValueAnimator, ObjectAnimator)
Transition framework
MotionLayout
Compose animations
Multi-threading (1 hour)
Threads vs Coroutines
Handler, Looper, HandlerThread
AsyncTask (deprecated)
Executor framework
Thread safety
Security (1 hour)
EncryptedSharedPreferences
Keystore system
Network security config
Certificate pinning
ProGuard/R8 obfuscation
SafetyNet API
Firebase Integration (1 hour)
Cloud Firestore
Firebase Auth
Cloud Messaging (FCM)
Crashlytics
Remote Config
Analytics
Afternoon Session (6 hours): Practice Common Questions
Top 50 Must-Know Interview Questions
Kotlin:
1. val vs var vs const val
2. lateinit vs lazy
3. Higher-order functions
4. Extension functions
5. Sealed classes vs Enum
6. Companion object
7. Data classes
8. inline, noinline, crossinline
9. Scope functions (let, run, with, apply, also)
10. Coroutines fundamentals
Android Components: 11. Activity lifecycle 12. Fragment lifecycle 13. Launch modes 14. Service types 15.
BroadcastReceiver 16. Content Provider 17. Intent types 18. PendingIntent 19. Task affinity 20. Process and
Application
Architecture: 21. MVVM vs MVP vs MVC 22. Repository pattern 23. Clean Architecture 24. Single Source of
Truth 25. Unidirectional data flow 26. ViewModel vs AndroidViewModel 27. LiveData vs Flow vs StateFlow
Jetpack: 28. Room - Entities, DAO, Database 29. Room migrations 30. Room relationships 31. WorkManager
constraints 32. Navigation Component 33. Paging 3 34. DataStore vs SharedPreferences
Compose: 35. Recomposition 36. State hoisting 37. remember vs rememberSaveable 38. LaunchedEffect vs
DisposableEffect 39. derivedStateOf 40. Side effects in Compose
Networking & Data: 41. Retrofit suspend functions 42. OkHttp interceptors 43. Caching strategies 44. Error
handling 45. JSON parsing (Gson, Moshi, Kotlinx)
Performance: 46. Memory leaks 47. ANR causes and prevention 48. RecyclerView optimization 49. Bitmap
handling 50. App startup optimization
Practice: Write detailed answers for each. Use STAR method for behavioral questions.
Evening Session (6 hours): Final Project + Mock Interview
Project 5: Twitter Clone (4 hours) COMPLETE APP
Build a mini Twitter with:
Login/Register (mock API or Firebase)
Feed (LazyColumn)
Post tweet
Like/retweet
Profile screen
MVVM + Clean Architecture
Room for caching
Retrofit for API
Jetpack Compose
Pull to refresh
Proper error handling
Loading states
Dark theme support
Focus on:
System design decisions
Code organization
Handling edge cases
Performance
Testing
Mock Interview (2 hours)
Practice answering:
1. "Design a file download manager"
2. "How would you implement pull-to-refresh?"
3. "Explain your architecture choices in the Twitter app"
4. "How do you handle configuration changes?"
5. "What would you do if users report app crashes?"
Essential Resources
Documentation
Android Developers
Kotlin Docs
Jetpack Compose
GitHub Repositories to Study
amitshekhariitbhu/android-interview-questions
anandwana001/android-interview
Android Architecture Samples
Now in Android
YouTube Channels
Philipp Lackner
Coding in Flow
Android Developers (official)
Google-Specific Tips (Based on Real Experiences)
What Google Actually Asks:
1. System Design is CRITICAL - 2-3 rounds may be system design
2. Stopwatch problem - Design without libraries
3. Thread safety questions
4. Coroutines deep dive
5. Architecture justification
6. Performance optimization scenarios
Interview Tips:
1. Think out loud - Explain your reasoning
2. Ask clarifying questions - Don't jump to coding
3. Discuss trade-offs - No perfect solution
4. Start with high-level design - Then deep dive
5. Be ready to defend choices - "Why MVVM?" "Why Flow over LiveData?"
6. Code quality matters - Clean, readable, maintainable
7. Handle edge cases - Null safety, errors, loading states
8. Know the Android framework deeply - Not just libraries
Red Flags to Avoid:
Not asking questions
Jumping to code immediately
Ignoring error handling
Poor code organization
Not explaining trade-offs
Saying "I don't know" without attempting
Being inflexible about solutions
Green Flags:
Structured approach
Clear communication
Considering scale
Security awareness
Performance consciousness
Testing mindset
Modern Android practices
Quick Reference Cheat Sheet
Coroutines Cheat Sheet
kotlin
// Sequential
val a = async { fetchA() }
val b = async { fetchB() }
[Link]() + [Link]()
// Parallel
coroutineScope {
val a = async { fetchA() }
val b = async { fetchB() }
[Link]() + [Link]()
}
// Dispatchers
[Link] // UI operations
[Link] // Network, DB
[Link] // CPU-intensive
[Link] // Don't use
// Exception handling
supervisorScope {
// Children failures don't cancel parent
}
Room Cheat Sheet
kotlin
// Entity
@Entity(tableName = "users")
data class User(@PrimaryKey val id: Int, val name: String)
// DAO
@Dao interface UserDao {
@Query("SELECT * FROM users") fun getAll(): Flow<List<User>>
@Insert suspend fun insert(user: User)
@Delete suspend fun delete(user: User)
}
// Database
@Database(entities = [User::class], version = 1)
abstract class AppDb : RoomDatabase() {
abstract fun userDao(): UserDao
}
Compose Cheat Sheet
kotlin
// State
var text by remember { mutableStateOf("") }
var text by rememberSaveable { mutableStateOf("") }
// Side effects
LaunchedEffect(key) { /* suspend */ }
DisposableEffect(key) { onDispose { } }
val scope = rememberCoroutineScope()
// Layouts
Column(modifier = Modifier) { }
Row(modifier = Modifier) { }
Box(modifier = Modifier) { }
LazyColumn { items(list) { } }
Final Day Checklist
Before Interview:
Review all 5 projects
Practice explaining system design on whiteboard/paper
Prepare questions for interviewer
Test your setup (if remote)
Get good sleep
During Interview:
Listen carefully
Ask clarifying questions
Think out loud
Start with high-level design
Consider edge cases
Discuss trade-offs
Keep code clean
Handle feedback gracefully
Topics You MUST Be Confident In:
1. Kotlin Coroutines (launch, async, Flow, StateFlow)
2. MVVM Architecture (ViewModel, LiveData, Repository)
3. Jetpack Compose (State, Side effects, Recomposition)
4. Room Database (Entities, DAO, Migrations)
5. System Design (WhatsApp, Instagram, News App)
6. Performance Optimization (Memory, ANR, Rendering)
7. Testing (Unit, UI, Integration)
8. Dependency Injection (Hilt)
Final Words
Remember:
Google values system thinking over memorization
Communication is as important as coding
Trade-offs show maturity
Ask questions - shows you think about requirements
Be honest - if you don't know something, say so but show how you'd learn
You have 5 days. Make them count!
Coming from TypeScript background is actually an advantage:
You understand async patterns (Promises ≈ Coroutines)
You know reactive programming
Modern tooling experience
Strong CS fundamentals transfer
You can do this! Good luck!