Intermediate everything in Mobile Dev, page 16
Flutter Performance Overlay
Flutter's Performance Overlay is a real-time EKG for frame budgets. Two graphs reveal whether Dart UI work or GPU rasterization is causing jank during animations. The footgun is rewriting widget logic when the raster thread is actually the bottleneck.
Tree Shaking Removes Unused Flutter Code
Tree shaking is the compiler deleting code your app never calls, so importing a massive package only costs the pieces you use. It runs automatically in release builds. Relying on dynamic dispatch or dart:mirrors silently disables it and brings back the bloat.
Legacy Integration Testing with flutter_driver
flutter_driver remotely pilots your app from a host via Dart VM service, common in legacy codebases with host-side scripts. Do not treat it as an in-process widget test because it runs outside the app; you cannot inspect state or use flutter_test matchers.
Repository Pattern: Hide Your Data Sources
A repository is a contract that hides where your data lives. Your Flutter app should not care if a user profile comes from Firebase, SQLite, or a mock. Engineers often leak HTTP clients or database models into UI instead of returning domain models.
Flutter Network Errors: Fail Gracefully
Treat every network call as a promise that might break. In Flutter, catch exceptions at the HTTP boundary and map them to UI states like retry widgets. The footgun is letting Dio or http exceptions bubble up, crashing the app instead of degrading gracefully.
Describe staged rollout on Google Play Console, benefits, and metrics to monitor
Tests release engineering and risk mitigation. Covers: set percentage and countries, manually ramp, halt on bad signals; benefits are blast-radius reduction and real-world validation. Flag: auto-ramping claims or ignoring halted users keep the bad build.

Google Play App Signing: upload key versus app signing key
Tests Android signing infrastructure and key escrow knowledge. A strong answer states Google holds the app signing key while you retain an upload key, protecting critical signing material. Red flag: claiming both keys sign the final install artifact.

Release build ClassNotFoundException not in debug: cause and file?
Tests R8 shrinking awareness: release-only obfuscation removes classes loaded by reflection. Check proguard-rules.pro first and add a -keep rule. Red flag: blaming multidex or disabling minification rather than writing a targeted keep rule.

What is certificate pinning and what are its trade-offs?
Pinning hardcodes a server key to block rogue CA MITM; trade-offs are breakage on cert rotation and forced updates.

Explain cold, warm, and hot app startups and three cold-start optimizations
Cold means no process; warm means process lives but activity recreates; hot means activity resumes. Three fixes: lazy-load deps, trim Application.onCreate, defer blocking I/O.

Diagnose Android UI jank using Android Studio's Profiler
Start with CPU Profiler for traces over 16ms and main thread blocking; check Memory Profiler for GC.

How do you test a Compose click and verify state change?
This tests Compose semantics and interaction-to-assertion flow. Mention ComposeTestRule, onNodeWithTag, performClick, and assert on the changed node with assertIsDisplayed or assertTextEquals.

Mock vs Fake test doubles: when to use a Fake Repository?
Tests if you know a Fake is a working lightweight implementation while a Mock verifies interactions. Good answers define Fake as in-memory with real logic, Mock as expectation-based, and choose a Repository Fake when many tests need reusable state.

Explain integration tests and isolate Room DAO tests
Tests integration vs unit testing and Room isolation. Outline: verify real DAO-to-DB interaction with Room.inMemoryDatabaseBuilder; reset state by closing and recreating the DB in @After. Red flag: mocking the DAO or using an on-disk database.

Unit test a ViewModel exposing StateFlow in a local JVM test
Tests coroutine hygiene and flow collection strategy. A strong answer covers injecting a TestDispatcher, using runTest, collecting emissions in a background scope, and asserting states.

Explain Structured Concurrency in Kotlin Coroutines
Structured concurrency binds coroutines to a scope; parent cancellation propagates to all children, preventing leaks.

How would you access a Hilt dependency in a non-injectable ContentProvider?
Tests Hilt's escape hatch for framework classes. Strong answer: define an EntryPoint in SingletonComponent, expose the dependency, and retrieve it with EntryPointAccessors.fromApplication. Red flag: field injection or manual static singletons.

How do you inject two different OkHttpClient instances with Hilt?
Tests Hilt qualifiers for same-type bindings. Answer: define a custom @Qualifier (or @Named), annotate two @Provides methods and the injection site. Red flag: manual client creation or subclassing OkHttpClient instead of qualifying the binding.

Explain Hilt scoping: @Singleton vs @ActivityRetainedScoped
Tests Hilt component lifecycles. Answer: @Singleton lives for the app process; @ActivityRetainedScoped survives config changes via ActivityRetainedComponent but dies when the activity finishes.

How do you upload a file with text data in Retrofit?
Tests multipart uploads versus JSON bodies. Strong answer: @Multipart, @POST, @Part; file as MultipartBody.Part and text as RequestBody; avoid @Field. Red flag: suggesting @Body with a data class.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles