Advanced everything in Android & Kotlin, page 4

Coroutine Exception Handling: launch vs. async
Coroutine builders handle exceptions differently. launch propagates them immediately, crashing if unhandled. async silently catches them, waiting for you to call await. Use a CoroutineExceptionHandler on root scopes for global logging.

How do you diagnose and fix excessive recomposition in Jetpack Compose?
This tests your understanding of Compose's stability system for performance. Use the Layout Inspector and Compiler Metrics to find unstable composables, then fix them with immutable data types and stable lambdas.

remember vs. rememberSaveable: When and Why to Use Each
Tests understanding of Compose state survival. remember is for recomposition scope. rememberSaveable survives activity recreation and process death via a Bundle, requiring custom Savers for complex types. Red flag: saying remember survives rotation.
How does Android manage a ContentProvider's lifecycle during a query?
This tests your understanding of Android IPC and component lifecycles. Explain how ContentResolver uses a URI to have the system instantiate the provider in its own process.

Bound Service Lifecycle: Config Changes and Multiple Clients
Tests deep knowledge of bound service lifecycles. A config change causes an unbind/rebind cycle, recreating the service. With multiple clients, the service isn't destroyed until the last one unbinds. Red flag: assuming the service survives the config change.

Handle Android Process Death vs. Configuration Changes
Tests your grasp of Android's lifecycle for state restoration. A good answer explains that onCreate(savedInstanceState) is called in both cases, but process death recreates everything. Use ViewModel with SavedStateHandle.
How would you manage API keys in Gradle without version control?
Tests secure credential handling in Android builds. A good answer proposes the Secrets Gradle Plugin, which reads from an untracked properties file and exposes keys via BuildConfig, while also noting this doesn't protect against APK decompilation.

How do you diagnose a memory leak with Android Studio Profiler?
This tests your systematic process for debugging memory issues. A good answer outlines using the Memory Profiler, forcing GC, capturing heap dumps, and analyzing object references. A red flag is just naming the tool without explaining the 'how'.

Gradle Build Types vs. Product Flavors
This tests your understanding of Gradle's build matrix for creating different app versions. A great answer defines build types (how it's built) vs. flavors (what is built) and explains that variants are the cross-product. A red flag is confusing their roles.

Implement a type-safe DSL in Kotlin for a UI component
Tests understanding of Kotlin's type-safe builders via lambdas with receivers. A great answer defines model classes, creates a top-level builder function taking a Receiver.() -> Unit lambda, and defines nested builder methods.

Explain Kotlin's `reified` type parameters and their use case
Tests your grasp of JVM type erasure and Kotlin's solution. A great answer defines reified as making a generic type's Class accessible at runtime, explains this requires an inline function to substitute the type at the call site, and shows an example.

How does coroutine cancellation work internally?
This tests your grasp of cooperative cancellation. Explain that cancel() sets a flag, causing a CancellationException at the next suspension point. A non-suspending loop must explicitly check isActive to stop.

Explain backpressure in Kotlin Flows and its management operators
This tests your understanding of Flow's sequential nature and strategies for decoupling producers and consumers. Explain default suspension, then detail buffer(), conflate(), and collectLatest(). A red flag is confusing conflate() with collectLatest().

What problem does `inline` solve, and how does `reified` relate?
This tests your grasp of Kotlin compiler optimizations and JVM type erasure. Explain that inline eliminates the runtime overhead of lambda objects. Then, describe how reified leverages inlining to make generic types accessible at runtime.

Compare and contrast `apply` and `let` scope functions
Tests Kotlin scope function knowledge: context (this/it) & return value. apply uses this, returns the object (for config). let uses it, returns lambda result (for null-checks/transforms). Red flag: mixing up return values or use cases.

When to use a sealed class instead of an enum?
Tests your grasp of Kotlin's type hierarchies. Use sealed class for states with associated data (e.g., Success(data)), as subclasses can have unique properties. Use enum for simple, constant states. A red flag is treating them as interchangeable.

Play Asset Delivery: Beyond the APK Size Limit
Think of Play Asset Delivery as Google Play managing a CDN for your game's large assets, letting you bypass the initial download size limit. It delivers textures and levels at install, right after, or on-demand. The footgun is assuming delivery succeeds.

Perfetto: See Your Whole System on One Timeline
Perfetto is a flight recorder for your system, capturing kernel and app events on a single timeline. Use it to diagnose complex issues like jank by correlating app behavior with system activity.

Android Baseline Profiles: Pre-compiling for Speed
A Baseline Profile is a cheat sheet for the Android runtime, telling it which code to pre-compile for faster performance. This speeds up app startup and reduces UI jank in critical flows.

UI Automator: Black-Box UI Testing for Android
Think of UI Automator as a robot that tests your app by looking at the screen, not your code. It's for end-to-end tests that cross app boundaries, like interacting with the system Settings. The footgun: tests are powerful but can be slow and brittle.
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