Top 30 Advanced Android & Kotlin Concepts Quiz
30 advanced multiple-choice Android & Kotlin concept questions, the corners that separate having used it from understanding it: internals, edge cases, and the reasons behind the design. They come from 30 bites in the Android & Kotlin library, the hardest slice of the 157 Android & Kotlin concept questions in the library. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.
Jetpack Compose, Android Studio, Kotlin, Material You
30 questions. Pick an answer, or open “Show the answer” to read it.
Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.
Question 1 of 30
Which statement accurately describes how Kotlin extension functions fundamentally add functionality to a class?
Show the answer
Answer: a · The compiler transforms calls to them into static utility method invocations, passing the receiver object as an argument.
Kotlin extension functions are syntactic sugar; the compiler rewrites calls to them as static utility method calls, passing the receiver instance as an argument. They do not modify the original class's bytecode, create new classes, or use reflection to add methods dynamically.
Read the full bite: Kotlin Extension Functions: Add Methods Without Inheritance
Question 2 of 30
Which scenario is explicitly identified as the biggest anti-pattern when utilizing Kotlin's scope functions?
Show the answer
Answer: a · Nesting multiple scope functions within each other.
B is correct because the card explicitly states, "The biggest anti-pattern is nesting multiple scope functions. It becomes extremely difficult to reason about which this or it is in scope at any given moment, leading to subtle bugs and unreadable code." Option C, while something to avoid for clarity, is not labeled as the "biggest anti-pattern"; nesting is highlighted due to its complexity and potential for subtle bugs.
Read the full bite: Kotlin Scope Functions: Cleaner Code, Clearer Choices
Question 3 of 30
What is the primary advantage of using a sealed class over a regular abstract class when modeling a finite set of distinct states?
Show the answer
Answer: d · It guarantees that all possible subclasses are explicitly handled by the compiler in 'when' expressions.
The card states that sealed classes enable the compiler to perform an exhaustiveness check in 'when' expressions, ensuring all possible subclasses are handled. Option B is incorrect because sealed classes restrict inheritance to a known set of types, not open it up.
Question 4 of 30
A coroutine launched with GlobalScope.launch inside a Fragment keeps running and eventually crashes the app after the Fragment is destroyed. What is the root cause?
Show the answer
Answer: a · GlobalScope has no lifecycle attachment, so nothing cancels the coroutine when the Fragment is destroyed, letting it keep referencing destroyed views
GlobalScope exists outside Android's lifecycle system entirely, so nothing ties its coroutines to a Fragment or Activity, and they keep running and can touch destroyed views after the screen is gone. Cooperative suspend functions are cancellable when properly scoped, and there is no automatic reparenting from GlobalScope.
Question 5 of 30
An exception occurs inside an `async` block. The `Deferred` result is stored, but `await()` is never called on it. What happens to the exception?
Show the answer
Answer: b · It is caught and held within the `Deferred` object, and program execution continues.
`async` catches its own exceptions and stores them in the `Deferred` result. The exception is only re-thrown when `await()` is called. Option C describes the behavior of `launch`, a common point of confusion.
Read the full bite: Coroutine Exception Handling: launch vs. async
Question 6 of 30
Which scenario is the most appropriate use case for a Kotlin SharedFlow?
Show the answer
Answer: b · Broadcasting real-time user authentication status updates to all active UI components.
SharedFlow is designed for one-to-many event distribution, like broadcasting UI events or real-time updates to multiple parts of an application, as described in option B. Option D describes the use case for StateFlow, which is specialized for a single, observable piece of state.
Read the full bite: SharedFlow: A Hot Flow for Broadcasting Events
Question 7 of 30
What is the primary reason Kotlin's MutableList<E> is invariant, while List<out E> is covariant?
Show the answer
Answer: b · MutableList allows elements of type E to be both added to and retrieved from the list, requiring E to be used in both 'in' and 'out' positions.
The card explains that a generic type must remain invariant if it is used in both 'in' (consumer, like add) and 'out' (producer, like get) positions, which is precisely the case for MutableList. Option A is tempting because mutability is the context, but the direct reason for invariance is the dual usage of the generic type in 'in' and 'out' positions, as per Kotlin's variance rules.
Read the full bite: Kotlin's `in` and `out`: Declaration-Site Variance
Question 8 of 30
What is the fundamental reason Kotlin's reified type parameters are exclusively usable with inline functions?
Show the answer
Answer: c · The compiler uses inline functions to substitute the actual type argument directly into the function's bytecode at the call site.
The card states that when an inline function is called, the compiler copies its body to the call site and replaces the reified generic type with the actual type argument. This compile-time substitution is the core mechanism that inline functions enable for reified types. Option B describes a workaround that reified types aim to eliminate, not how they function with inline.
Read the full bite: Reified Type Parameters: Accessing Generic Types at Runtime
Question 9 of 30
What is the immediate output of a successfully executed Kotlin type-safe builder block?
Show the answer
Answer: a · A hierarchical tree of interconnected Kotlin objects representing the defined structure.
The card explicitly states that a builder block "doesn't generate a string" but rather "instantiate and link HTML, Head, and Title objects into a tree," with the "final result is a root HTML object." While builders are often used to eventually produce strings, their immediate output is an object hierarchy. Option C is a common misconception because builders are frequently used for markup generation.
Read the full bite: Kotlin's Type-Safe Builders: Code as Data
Question 10 of 30
For which scenario would you typically NOT use the Android Gradle Plugin (AGP)?
Show the answer
Answer: d · Developing a pure Kotlin library intended for a backend service
AGP is specifically designed for projects that produce Android artifacts like APKs, AABs, or AARs. For non-Android projects, such as a pure Kotlin backend service, standard Gradle plugins for Kotlin or Java would be used instead of AGP. Building debug versions of Android apps is a core function of AGP.
Read the full bite: Android Gradle Plugin (AGP): The Engine of Your Android Build
Question 11 of 30
What is a significant limitation to consider when using the Android Studio Profiler for performance measurement?
Show the answer
Answer: b · The overhead from its instrumentation means performance metrics may not perfectly reflect a normal user's experience.
The card states that "The instrumentation it adds creates performance overhead, so the numbers you see are not 100% true to a normal user's experience," directly supporting option B. While powerful, the Profiler is explicitly noted as "not a replacement for automated benchmark tests" (option C), which are better for catching regressions over time.
Read the full bite: Android Studio Profiler: Find Your App's Bottlenecks
Question 12 of 30
Which of the following is NOT a capability or primary use case of the Android Layout Inspector?
Show the answer
Answer: c · Debugging application logic issues by stepping through code execution.
The Layout Inspector is designed for UI hierarchy and visual debugging, providing insights into component properties and layout issues. It is explicitly stated that it is not for debugging application logic; that task is handled by the debugger.
Read the full bite: Layout Inspector: Debug Your UI Hierarchy
Question 13 of 30
What are the primary reasons R8 is enabled by default for Android release builds?
Show the answer
Answer: c · To reduce the app's overall size and make its compiled code more difficult to reverse-engineer.
The card states R8's purpose is to "shrink and obfuscate your Android app," which means it reduces APK size and deters reverse-engineering. It explicitly mentions that R8 slows down build times, making options suggesting faster compilation incorrect. Obfuscation makes code harder to understand, but it is not encryption.
Read the full bite: R8: Shrinking and Obfuscating Android Code
Question 14 of 30
What is the immediate and critical action required after starting an Android foreground service to ensure its proper operation?
Show the answer
Answer: d · Invoke startForeground() within a few seconds, providing a unique ID and a persistent notification.
The card states that "within a short time limit (a few seconds), the service must call startForeground(), passing it a unique ID and a Notification object." This action signals to the OS that the user is aware of the ongoing work, preventing termination. Option C is a prerequisite, not an immediate action after starting the service.
Read the full bite: Android Foreground Services: Work the User Can See
Question 15 of 30
For which of the following background tasks is WorkManager the most appropriate solution?
Show the answer
Answer: a · Uploading user-generated content to a server when network connectivity is available, even if the app is closed.
WorkManager is designed for guaranteed, deferrable background work, such as uploading data when network conditions are met, even if the app is no longer active. Option D requires precise timing, which is better handled by AlarmManager, while options A and D are for Foreground Services and immediate foreground tasks, respectively.
Read the full bite: WorkManager: Guaranteed, Deferrable Background Work
Question 16 of 30
Which scenario best highlights Data Binding's unique advantage over View Binding?
Show the answer
Answer: c · Automatically updating UI elements when their associated data models change.
Data Binding excels at linking UI components directly to observable data sources in XML, enabling automatic UI updates when the data changes. While View Binding also provides type-safe access to views and eliminates findViewById calls, it does not offer this automatic data-to-UI synchronization, making it suitable only for simpler view access.
Read the full bite: Data Binding: Link Android UI to Data in XML
Question 17 of 30
Which animation scenario is the most appropriate use case for MotionLayout?
Show the answer
Answer: c · A complex UI element, like a collapsing toolbar, smoothly transitioning between expanded and collapsed states based on scroll.
MotionLayout is designed for complex, multi-element UI choreography and interactive animations, such as a collapsing toolbar transitioning between states based on user scroll. Simple, one-off animations on a single view, like a button press effect or a fade-in, are better handled by simpler APIs like ViewPropertyAnimator or ObjectAnimator.
Read the full bite: MotionLayout: Animate Layouts with States, Not Code
Question 18 of 30
After loading an XML-defined Property Animation, which method is used to specify the target View that will be animated?
Show the answer
Answer: b · Animator.setTarget()
The card explicitly states that after loading the Animator object, you call setTarget() on that object to link it to your target View. View.startAnimation() is used for the older View Animation system, not for Property Animations.
Read the full bite: Android View Animation: A Blueprint for Motion
Question 19 of 30
Which scenario most appropriately utilizes a Compose side-effect API?
Show the answer
Answer: a · Triggering a network request to fetch data when a screen first appears.
Fetching data is a non-UI action that needs to be tied to the composable's lifecycle, preventing unpredictable execution during recomposition, which is the purpose of side-effect APIs. The other options describe UI calculations or derived state that should be handled directly within the composable's body or with derivedStateOf, not with side-effects.
Read the full bite: Compose Side-Effects: Escaping the Pure Function
Question 20 of 30
Which scenario best justifies the use of CompositionLocal in a Jetpack Compose application?
Show the answer
Answer: d · Providing a global analytics client instance to various deeply nested composables without explicit parameter passing.
CompositionLocal is ideal for ambient, semi-static data like a singleton service that needs to be accessed by many composables in a subtree, avoiding 'prop drilling'. Using it for mutable state or primary data dependencies (options A and C) is discouraged as it hides dependencies and complicates testing. Option C describes a side effect, not the primary justification for its use.
Read the full bite: CompositionLocal: Implicitly Pass Data Down the UI Tree
Question 21 of 30
Which of the following scenarios is LEAST suitable for a Compose UI test?
Show the answer
Answer: a · Confirming that a Button composable from the Material library correctly triggers its onClick lambda when tapped.
The card explicitly advises against testing the behavior of standard library composables, as this is trusting the framework's implementation. Other options describe valid scenarios for Compose UI tests, focusing on application-specific UI logic and state changes.
Read the full bite: Compose UI Testing: Find Nodes, Assert State, Perform Actions
Question 22 of 30
Under which circumstance is the implementation of an Android Domain Layer most beneficial?
Show the answer
Answer: d · When business logic, whether complex or simple, needs to be reused across multiple ViewModels or would otherwise bloat a ViewModel.
The Domain Layer is explicitly recommended for centralizing complex business logic or simple rules that need to be reused across multiple ViewModels, preventing ViewModel bloat. Option A describes when not to use it, while options B and D describe responsibilities of the UI Layer (ViewModel) and Data Layer (Repositories), respectively.
Read the full bite: Android's Domain Layer: Your Business Logic's Home
Question 23 of 30
When is it inappropriate to use deep linking with Android's Navigation Component?
Show the answer
Answer: b · To move from one fragment to another within the app's established navigation flow
The card explicitly states, "Do not use deep links for navigating between screens within your app. For internal navigation, always use Navigation Component actions." Options A, B, and D describe valid and intended use cases for deep linking.
Read the full bite: Deep Linking with Android's Navigation Component
Question 24 of 30
Which of the following best describes how Navigation Safe Args prevents runtime crashes when passing data?
Show the answer
Answer: b · It generates type-safe classes that enable compile-time validation of arguments, preventing mismatches before runtime.
Safe Args generates type-safe code, allowing the compiler to validate arguments at build time, thus preventing runtime errors. Distractor C is incorrect because the card explicitly advises against passing large objects with Safe Args due to Bundle size limits, recommending shared ViewModels instead.
Read the full bite: Navigation Safe Args: Type-Safe Navigation in Android
Question 25 of 30
When would Room's relational query feature, mapping related data to nested objects, typically lead to significant performance issues?
Show the answer
Answer: b · When fetching a large collection of parent objects, where each parent also requires its own nested list of related child objects.
The card explicitly states that fetching a large list of items, each with its own nested list of related data, can lead to the 'N+1' query problem and significant performance degradation. This is the scenario described in option B, whereas option D describes the ideal use case for this feature.
Read the full bite: Room: Querying Relational Data Without Manual Joins
Question 26 of 30
Which scenario most strongly indicates that an instrumented test is the appropriate choice for your Room database?
Show the answer
Answer: a · When validating complex DAO queries, intricate relationships, or schema migrations.
Option A aligns with the card's recommendation to use instrumented tests as the "source of truth" for complex DAO logic and migrations due to their accuracy. Option D describes the ideal use case for faster local JVM tests, while Option C contradicts the advice to not test Room's own functionality.
Read the full bite: Testing Room Databases: On-Device vs. Local JVM
Question 27 of 30
Which scenario best exemplifies the primary use case for Android's FileProvider?
Show the answer
Answer: c · Sharing a file from your app's private internal storage with another application.
Option C is correct because FileProvider's core purpose is to securely share files from an app's private storage with other applications, replacing insecure direct path exposure. Option A describes the insecure method (file:/// URIs) that FileProvider was specifically designed to prevent, not its intended use.
Read the full bite: FileProvider: Securely Share Files Between Apps
Question 28 of 30
What is the most significant operational challenge when implementing certificate pinning in a client application?
Show the answer
Answer: c · It can lead to service outages if server certificates are renewed without a corresponding client application update.
The card explicitly states that if a server certificate changes and the client application is not updated with the new pin, all network requests will fail, causing service outages. This brittleness is highlighted as the primary operational risk. Pinning actually reduces reliance on the broad trust of the OS CA store, rather than requiring updates to it.
Read the full bite: Certificate Pinning: Trusting Only Your Own Servers
Question 29 of 30
Which scenario would prevent OkHttp from successfully storing a network response in its disk cache, even if caching is enabled and the server provides appropriate cache-control headers?
Show the answer
Answer: a · The application code retrieves the response but only inspects its headers before closing the response stream without consuming the body.
The card explicitly states that for a response to be written to the cache, its body must be fully read and closed by the application. Failing to consume the body prevents the response from being stored. While a non-exclusive cache directory (Option C) can cause issues, the unconsumed body is a direct, common coding error preventing storage of a specific response.
Read the full bite: OkHttp Caching: Beyond Simple Hits and Misses
Question 30 of 30
What is the primary advantage of using Hilt's testing features in Android?
Show the answer
Answer: d · It simplifies the process of replacing real application dependencies with test-specific fakes.
The core purpose of Hilt testing is to automate the swapping of production dependencies with test doubles, enabling isolated testing without manual setup. While Hilt reduces boilerplate, you still create the fake implementations yourself, making option A incorrect. Hilt testing is specifically for classes managed by Hilt, contradicting option B.
Read the full bite: Testing with Hilt: Swapping Dependencies for Isolation
Could you explain these out loud?
That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.