Skip to content
tezvyn:

Top 30 Android & Kotlin Concepts Quiz

30 multiple-choice questions on the Android & Kotlin fundamentals, drawn from 30 bites in the Android & Kotlin 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.

  1. Question 1 of 30

    A developer needs to store a user's current score in a game, which will change throughout gameplay. Which Kotlin keyword should be used?

    Show the answer

    Answer: c · var

    The card states that 'var' should be used for values that need to be reassigned, such as a user's score, while 'val' is for values that remain constant after initial assignment. Choosing 'val' here would lead to a compilation error when trying to update the score.

    Read the full bite: Kotlin Variables: `val` for Constants, `var` for Variables

  2. Question 2 of 30

    What is the main consequence of using the not-null assertion operator (!!) in Kotlin?

    Show the answer

    Answer: b · It tells the compiler to trust that a value is not null, potentially leading to a runtime NullPointerException if it is.

    The not-null assertion operator (!!) bypasses Kotlin's compile-time null safety, forcing the compiler to assume a value is non-null. If the value turns out to be null at runtime, it will result in a NullPointerException, defeating the purpose of Kotlin's null safety. Option A is incorrect because it introduces risk, and options C and D describe the Elvis operator (?:) and safe call operator (?.), respectively.

    Read the full bite: Kotlin Null Safety: Catch Nulls at Compile Time

  3. Question 3 of 30

    What is a mandatory requirement when using an `if` expression to assign a value to a variable in Kotlin?

    Show the answer

    Answer: b · An `else` branch must always be present to cover all possible outcomes.

    When `if` is used as an expression, it must always return a value. To guarantee this, the compiler requires an `else` branch to cover all possible cases. The last line of a branch implicitly becomes its return value, without needing an explicit `return` keyword.

    Read the full bite: Kotlin's Control Flow Expressions: `if` and `when`

  4. Question 4 of 30

    What is the main purpose of using functions in Kotlin?

    Show the answer

    Answer: d · To package reusable logic, preventing code duplication and enhancing structure.

    The card states functions exist "to solve the problem of code repetition and disorganization" by packaging logic into "a single, named block that can be called from anywhere." Option C is incorrect because while good code structure can aid optimization, functions' primary role isn't automatic speed enhancement.

    Read the full bite: Kotlin Functions: Named, Reusable Code Blocks

  5. Question 5 of 30

    What is the primary reason Kotlin classes are final by default?

    Show the answer

    Answer: a · To encourage explicit design for inheritance and promote composition over inheritance.

    The card states that Kotlin's design makes inheritance an intentional act to encourage more robust code and promotes composition over inheritance. Option A directly captures these core reasons. Option C is incorrect as 'final by default' relates to inheritance, not the mutability of properties, which is controlled by 'val' and 'var'.

    Read the full bite: Kotlin Inheritance: Open for Extension, Closed by Default

  6. Question 6 of 30

    Which statement accurately describes the behavior of the copy() method generated for a Kotlin data class?

    Show the answer

    Answer: d · It performs a shallow copy, meaning references to mutable objects within the data class are shared between the original and the new instance.

    The card explicitly states that the copy() function creates a shallow copy. This means if a data class contains a mutable object, both the original and the copied instance will refer to the same mutable object. Option A is a common misconception, as many expect a copy function to perform a deep copy for safety.

    Read the full bite: Kotlin Data Classes: Automatic Boilerplate for Data Holders

  7. Question 7 of 30

    Under which circumstance is it generally recommended to reconsider using a chain of standard Kotlin collection operations (like filter followed by map) and opt for an alternative?

    Show the answer

    Answer: b · When the collection is extremely large, and creating intermediate lists would be inefficient.

    Standard chained collection operations create new intermediate lists for each step, which can be very inefficient for large collections. In such cases, using 'asSequence()' or a traditional loop is preferred to avoid this overhead. Option C is incorrect because aggregation can also be achieved using functional operations like 'reduce' or 'fold'.

    Read the full bite: Kotlin Collections: Think Transformations, Not Loops

  8. Question 8 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

  9. Question 9 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

  10. Question 10 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.

    Read the full bite: Kotlin Sealed Classes: Enums for Types

  11. Question 11 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.

    Read the full bite: Kotlin Coroutines on Android

  12. Question 12 of 30

    Which statement best describes why Dispatchers.Unconfined is generally discouraged for common use cases?

    Show the answer

    Answer: d · Its behavior after a suspending function can lead to unpredictable thread execution.

    Dispatchers.Unconfined is discouraged because it starts on the current thread but can resume on any thread used by a suspending function, leading to unpredictable execution. This is distinct from creating new threads (which is more relevant to newSingleThreadContext) or always running on the main thread.

    Read the full bite: Coroutine Dispatchers: Telling Your Coroutines Which Thread to Use

  13. Question 13 of 30

    What is the primary effect of cancelling a CoroutineScope?

    Show the answer

    Answer: b · All coroutines that were launched within that scope are automatically cancelled.

    The core function of a CoroutineScope is to manage the lifecycle of its child coroutines; thus, cancelling the scope automatically cancels all coroutines launched within it. Option C is incorrect because existing coroutines are also cancelled, not continued, and new launches would fail rather than just being prevented.

    Read the full bite: CoroutineScope: The Parent of Your Coroutines

  14. Question 14 of 30

    What happens if a Kotlin Flow is created but no terminal operator like .collect() is invoked?

    Show the answer

    Answer: b · The Flow's producer code will not execute, and no values will be emitted.

    Flows are 'cold,' meaning their producer code only executes when a terminal operator like .collect() is called. Without a collector, the flow builder block never runs, so no values are emitted. Option C is incorrect because nothing is emitted to be discarded.

    Read the full bite: Kotlin Flow: Asynchronous Data Streams

  15. Question 15 of 30

    Which problem does Kotlin's Structured Concurrency primarily aim to solve?

    Show the answer

    Answer: d · Preventing resource leaks from uncancelled background tasks.

    Structured concurrency's main purpose is to enforce lifetime management for concurrent work, preventing resource leaks and unnecessary work by ensuring background tasks are cancelled when no longer needed. While other options are valid concurrency concerns, they are not the primary problem addressed by structured concurrency itself.

    Read the full bite: Structured Concurrency in Kotlin

  16. Question 16 of 30

    What is the key distinction in how a child coroutine's termination impacts its parent Job?

    Show the answer

    Answer: a · An unhandled exception from a child cancels the parent, while a child's normal cancellation does not.

    The card states that if a child Job fails with an exception (other than CancellationException), it cancels its parent. However, if a child is cancelled normally via cancel() (which uses CancellationException), it does not affect the parent.

    Read the full bite: Kotlin's Job: A Handle to a Background Task

  17. Question 17 of 30

    For which scenario is Kotlin's async/await pattern the most appropriate choice?

    Show the answer

    Answer: c · Fetching a user's profile and their friends list concurrently from different API endpoints.

    The card states that async/await is for running multiple independent, long-running tasks concurrently and combining their results, as exemplified by fetching data from different API endpoints. Option B describes an anti-pattern, as async/await is not for sequential, dependent operations.

    Read the full bite: Kotlin Coroutines: async/await for Parallel Results

  18. Question 18 of 30

    What is the primary reason StateFlow is generally not recommended for handling one-time UI events like showing a Snackbar?

    Show the answer

    Answer: a · Its state-holding nature can cause the event to be re-emitted upon UI re-collection (e.g., config change).

    StateFlow is a state-holder that always provides the current value. If used for one-shot events, its state-holding nature means that a UI re-collection (e.g., after a configuration change) would re-receive the last "event" state, causing the event to trigger again. Options A, B, and D describe incorrect characteristics of StateFlow.

    Read the full bite: StateFlow: A Hot Flow for UI State

  19. Question 19 of 30

    What is the fundamental purpose of Kotlin's delegated properties?

    Show the answer

    Answer: b · To allow custom logic for getting and setting a property's value to be encapsulated and reused.

    The card states that delegated properties "let you outsource a property's getter/setter logic" and offer a "reusable, language-level solution to these common behaviors." This directly aligns with encapsulating and reusing custom logic. While lazy initialization (option A) is a key use case, it's one specific application of delegation, not the fundamental purpose of the delegation mechanism itself.

    Read the full bite: Kotlin Delegated Properties: Reusing Getter/Setter Logic

  20. Question 20 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

  21. Question 21 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

  22. Question 22 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

  23. Question 23 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

  24. Question 24 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

  25. Question 25 of 30

    What is the main benefit of Android Studio's design for Android app development?

    Show the answer

    Answer: c · It integrates all essential tools like code editing, building, and testing into one platform.

    The card highlights Android Studio as an "all-in-one workshop" and a "single, official, and tightly integrated environment" that combines code editing, building, and testing. The option about a lightweight environment is incorrect as the card explicitly mentions underestimating its resource needs as a "footgun."

    Read the full bite: Android Studio: The Official Workshop for Android Apps

  26. Question 26 of 30

    To properly include a new image asset (like a user avatar) in an Android application, where should it be placed?

    Show the answer

    Answer: c · Within a designated subfolder, such as drawable, inside the res directory.

    The 'res' folder is specifically designed for non-code resources like images, with 'drawable' being the correct subfolder for image assets. Placing it in the 'java' or 'kotlin' folder is incorrect because those are reserved for source code, keeping resources and logic separate.

    Read the full bite: Android Project Structure: Your App's Filing Cabinet

  27. Question 27 of 30

    What is the most likely outcome if a new Activity class is implemented but not declared in AndroidManifest.xml?

    Show the answer

    Answer: d · The app will crash with an ActivityNotFoundException when attempting to launch the Activity.

    The card states that forgetting an Activity declaration will cause the app to crash with an ActivityNotFoundException when launched, as the OS doesn't recognize it. The app will compile successfully without the declaration, making compilation failure (Option B) incorrect.

    Read the full bite: AndroidManifest.xml: The Blueprint for Your App

  28. Question 28 of 30

    What is the main benefit of developing an Android app using Kotlin or Java with the official SDK?

    Show the answer

    Answer: b · It provides the most direct and complete access to all native Android system APIs.

    The card states that using the official stack (Kotlin, Java, C++) "provides the most direct access to the full range of Android APIs." Option A is incorrect because Kotlin and Java are JVM languages and their code runs within the JVM environment, not without it.

    Read the full bite: Android App Development: Core Languages and Tools

  29. Question 29 of 30

    Which of the following scenarios is an appropriate use for Android's Logcat tool?

    Show the answer

    Answer: a · Debugging an app crash by viewing its stack trace in real-time.

    The card explicitly states that Logcat is used 'to see stack traces when your app crashes' and is your 'primary debugging partner.' It also warns against using Logcat for 'production analytics,' 'to store persistent data,' or to log 'sensitive user information' due to security risks and buffer limitations.

    Read the full bite: Logcat: The `tail -f` for Android Apps

  30. Question 30 of 30

    What is the core function of Gradle when managing build dependencies in an Android project?

    Show the answer

    Answer: c · To ensure that all external libraries and pre-built code are correctly integrated and available for the app.

    The card states that Gradle's role is to "manage these 'build dependencies' to ensure they are correctly included and built into the final application" and is responsible for "finding them, integrating them, and assembling the final product." While Gradle orchestrates the compilation (Option D), its core function regarding dependencies is their integration.

    Read the full bite: Adding Build Dependencies with Gradle in Android

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.

Get it on Google PlayiPhone app coming soon