Kotlin Interview Questions & Answers (100+)¶
What's on this page
- Core content for this topic in the Inkorporated enterprise OS.
- Practical guidance, roles, or standards as applicable.
What this enables
- Consistent enterprise operations and decision-making.
- Shared language for humans and cyborg AI agents.
This guide contains 100+ Kotlin interview questions, ranging from basic syntax to advanced concurrency and coroutines. Each question includes a model answer, code examples, and potential follow-up paths based on the candidate's response.
Part 1: Basic Kotlin Concepts (1-20)¶
1. What is the difference between val and var?¶
val: Immutable reference. Once assigned, it cannot be reassigned. (Similar tofinalin Java).var: Mutable reference. Can be reassigned.
Candidate Response Paths:
-
Path A: Candidate mentions 'Immutable'.
- Follow-up: "Does
valmean the object itself is immutable?" - Answer: No,
valonly guarantees the reference is immutable. If the object is aMutableList, you can still add items to it.
- Follow-up: "Does
-
Path B: Candidate compares to Java.
- Follow-up: "When would you prefer
valovervar?" - Answer: Always prefer
valfor thread safety and predictability, unless mutation is strictly required.
- Follow-up: "When would you prefer
2. How does Kotlin handle Null Safety?¶
Kotlin's type system distinguishes between references that can hold null (nullable references) and those that cannot (non-null references).
| Syntax | Name | Description |
|---|---|---|
String |
Non-nullable | Cannot hold null. Compiler error if assigned null. |
String? |
Nullable | Can hold null. |
Key Operators:
* ?. (Safe Call)
* !! (Not-null Assertion)
* ?: (Elvis Operator)
Candidate Response Paths:
- Path A: Candidate mentions
!!.- Follow-up: "When is it acceptable to use
!!?" - Answer: Rarely. Only when you are 100% sure the value is not null and the compiler can't deduce it, or in quick prototypes/tests. It throws a
NullPointerExceptionif null.
- Follow-up: "When is it acceptable to use
3. What is the Elvis Operator ?:?¶
It returns the expression on its left if it is not null, otherwise it returns the expression on its right.
Candidate Response Paths:
- Path A: Control flow.
- Follow-up: "Can you use
returnorthrowon the right side of?:?" - Answer: Yes, because
returnandthroware expressions in Kotlin.
- Follow-up: "Can you use
4. What is Type Inference?¶
The compiler can automatically identify the data type of a variable from the context or the assigned value.
Candidate Response Paths:
- Path A: Limitations.
- Follow-up: "When must you explicitly specify the type?"
- Answer: When declaring a variable without initializing it immediately, or when the inferred type is not the desired one (e.g.,
LongvsInt).
5. What is the difference between const val and val?¶
val: Read-only variable, determined at runtime.const val: Compile-time constant. Must be a top-level property or a member of anobject(orcompanion object). Only primitives and String.
6. What are String Templates?¶
Strings that contain expressions beginning with $.
7. Explain lateinit vs lazy.¶
| Feature | lateinit |
lazy |
|---|---|---|
| Mutability | var (Mutable) |
val (Read-only) |
| Type | Non-primitive types only | Any type |
| Initialization | Later in code | On first access |
| Thread Safety | Not thread-safe by default | Thread-safe (synchronized) by default |
Candidate Response Paths:
- Path A: Use cases.
- Follow-up: "Why use
lateinitin Android?" - Answer: For dependency injection or View initialization in
onCreatewhere you can't initialize at declaration but know it won't be null when used.
- Follow-up: "Why use
8. What are Data Classes?¶
Classes whose main purpose is to hold data. The compiler automatically derives the following members:
* equals() / hashCode()
* toString()
* componentN() functions (for destructuring)
* copy()
Candidate Response Paths:
- Path A: Inheritance.
- Follow-up: "Can a Data Class be
openorabstract?" - Answer: No, data classes are final by default and cannot be open or abstract.
- Follow-up: "Can a Data Class be
9. What is the difference between == and ===?¶
==: Structural equality. Checks if contents are equal (callsequals()).===: Referential equality. Checks if variables point to the same object in memory.
10. How does the when expression work?¶
It replaces the switch operator of C-like languages but is more powerful. It can be used as a statement or an expression.
val result = when (x) {
1 -> "One"
in 2..10 -> "Between 2 and 10"
is String -> "It's a string"
else -> "Unknown"
}
11. How do loops work in Kotlin?¶
- For: Iterates over anything that provides an iterator.
- While / Do-While: Standard conditional loops.
12. What are Range Expressions?¶
Tools to define a range of values.
val r1 = 1..10 // 1 to 10 inclusive
val r2 = 1 until 10 // 1 to 9
val r3 = 10 downTo 1 // 10 to 1
val r4 = 1..10 step 2 // 1, 3, 5, 7, 9
13. How do you define a function?¶
fun sum(a: Int, b: Int): Int {
return a + b
}
// Single-expression syntax
fun sum(a: Int, b: Int) = a + b
Candidate Response Paths:
- Path A: Default Arguments.
- Follow-up: "How do default arguments help compared to Java?"
- Answer: They reduce the need for method overloading.
14. What are Extension Functions?¶
They allow you to add new functionality to a class without inheriting from it or using design patterns like Decorator.
Candidate Response Paths:
- Path A: Under the hood.
- Follow-up: "Does it actually modify the class?"
- Answer: No, it resolves statically. It's syntactic sugar for a static method that takes the instance as the first parameter.
15. What are Infix Functions?¶
Functions marked with infix keyword can be called using infix notation (omitting the dot and the parentheses).
* Must be member functions or extension functions.
* Must have a single parameter.
16. Explain Classes and Objects in Kotlin.¶
Classes are declared using class. Objects can be:
* Object Declaration: Singleton.
* Object Expression: Anonymous class.
17. What are the Visibility Modifiers?¶
public(Default): Visible everywhere.private: Visible inside file (top-level) or class.protected: Visible in class and subclasses.internal: Visible within the same module.
Candidate Response Paths:
- Path A: Internal.
- Follow-up: "What constitutes a 'module'?"
- Answer: A Maven/Gradle module, or an IntelliJ IDEA module.
18. Primary vs Secondary Constructors.¶
- Primary: Part of the class header.
- Secondary: Prefixed with
constructor. Must delegate to the primary constructor (directly or indirectly) usingthis().
19. How does Inheritance work?¶
All classes inherit from Any. Classes are final by default. To allow inheritance, mark the class with open.
20. How are Interfaces different in Kotlin compared to Java 7?¶
Kotlin interfaces can contain properties and functions with default implementations. They cannot store state.
Part 2: OOP & Functional Programming (21-40)¶
21. What is the difference between an Abstract Class and an Interface?¶
| Feature | Abstract Class | Interface |
|---|---|---|
| State | Can hold state (fields). | Cannot hold state (only properties without backing fields). |
| Constructor | Can have constructors. | Cannot have constructors. |
| Inheritance | Single inheritance. | Multiple implementation. |
| Use Case | Is-A relationship, sharing state. | Can-Do relationship, behavior contract. |
22. What are Sealed Classes?¶
sealed classes represent restricted class hierarchies. All direct subclasses must be known at compile time and declared in the same package (and same module).
Use Case:
Perfect for when expressions, ensuring all cases are covered without an else branch.
sealed class Result
data class Success(val data: String) : Result()
data class Error(val exception: Exception) : Result()
object Loading : Result()
23. What is an Object Declaration?¶
It is Kotlin's way of defining a Singleton.
The initialization is thread-safe and lazy (on first access).24. What is a Companion Object?¶
An object declared inside a class using the companion keyword.
* It is tied to the class, not instances.
* Similar to static members in Java.
* Can implement interfaces.
Candidate Response Paths:
- Path A: Access.
- Follow-up: "How do you access members of a companion object?"
- Answer: Simply by using the class name:
MyClass.create().
25. What are the requirements for a Data Class?¶
- Primary constructor must have at least one parameter.
- All primary constructor parameters must be marked as
valorvar. - Cannot be abstract, open, sealed, or inner.
26. Explain Class Delegation (by keyword).¶
Kotlin supports the "composition over inheritance" pattern natively. A class can implement an interface by delegating all of its public members to a specified object.
interface Base { fun print() }
class BaseImpl(val x: Int) : Base {
override fun print() = print(x)
}
class Derived(b: Base) : Base by b
27. What are Higher-Order Functions?¶
A function that takes another function as a parameter and/or returns a function.
28. What is a Lambda Expression?¶
An anonymous function that can be treated as a value.
Syntax: { variable(s) -> body }
Candidate Response Paths:
- Path A: 'it' keyword.
- Follow-up: "When can you use
it?" - Answer: When a lambda has exactly one parameter, you can omit the parameter declaration and refer to it as
it.
- Follow-up: "When can you use
29. What are Inline Functions?¶
Using higher-order functions imposes runtime penalties (object allocation for lambdas). The inline modifier tells the compiler to copy the function's code (and the lambda) directly into the call site.
Pros: Performance boost for loop-heavy high-order functions. Cons: Code size increases.
30. What is noinline and crossinline?¶
noinline: Used in an inline function to prevent a specific lambda parameter from being inlined.crossinline: Used when a lambda is passed to an inline function but executed in a different context (e.g., inside a nested object or local function), disallowing non-local returns.
31. What are Reified Type Parameters?¶
In Java, generics are erased at runtime (Type Erasure). In Kotlin, you can use inline functions with reified type parameters to access the type at runtime.
32. Explain Scope Functions (let, run, with, apply, also).¶
They execute a block of code within the context of an object.
| Function | Object Reference | Return Value | Use Case |
|---|---|---|---|
let |
it |
Lambda result | Null checks, temporary scope. |
run |
this |
Lambda result | Object configuration + computation. |
with |
this |
Lambda result | Grouping calls on an object. |
apply |
this |
Object itself | Object configuration (builder). |
also |
it |
Object itself | Side effects (logging, validation). |
graph TD
A[Start] --> B{Returns Object?}
B -- Yes --> C{Ref is 'this'?}
B -- No --> D{Ref is 'this'?}
C -- Yes --> E[apply]
C -- No --> F[also]
D -- Yes --> G[run / with]
D -- No --> H[let]
33. What are Destructuring Declarations?¶
A way to unpack a single composite value into multiple variables.
34. What is Operator Overloading?¶
Kotlin allows providing custom implementations for a predefined set of operators (+, -, *, ++, etc.) on user-defined types. You must use the operator modifier.
35. What are Type Aliases?¶
Provide alternative names for existing types. Useful for shortening long generic types.
36. Nested vs Inner Classes.¶
- Nested Class: By default, a class inside another class does not have access to the members of the outer class. (Static nested in Java).
- Inner Class: Marked with
inner. Has reference to the outer class object. Can access members.
37. What are Anonymous Inner Classes?¶
Created using object expressions.
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { ... }
})
38. What is SAM Conversion?¶
Single Abstract Method.
Kotlin allows passing a lambda for a Java interface that has only one abstract method.
Example: Runnable, Callable, OnClickListener.
39. What is a Tail Recursive Function?¶
A recursive function where the recursive call is the last operation performed.
Marked with tailrec.
The compiler optimizes this into a loop, preventing StackOverflowError.
40. What is a Functional Interface?¶
An interface with exactly one abstract method. Marked with fun interface.
fun interface IntPredicate {
fun accept(i: Int): Boolean
}
val isEven = IntPredicate { it % 2 == 0 }
Part 3: Coroutines & Concurrency (41-60)¶
41. What are Coroutines?¶
Coroutines are light-weight threads. They allow writing asynchronous code in a sequential manner. They are suspendable computations: they can suspend their execution without blocking the underlying thread.
42. Difference between launch and async.¶
| Feature | launch |
async |
|---|---|---|
| Return | Returns a Job. |
Returns a Deferred<T>. |
| Result | Fire and forget. No result. | Promise of a result later. |
| Exception | Crashes application if unhandled. | Stored inside Deferred, thrown on .await(). |
43. What is runBlocking?¶
It runs a new coroutine and blocks the current thread interruptibly until its completion.
Use Case: Mainly for main functions and tests. Avoid in production UI code.
44. What is a Suspend Function?¶
A function marked with suspend modifier. It can suspend the execution of a coroutine without blocking the thread.
* Can only be called from a coroutine or another suspend function.
45. CoroutineScope vs CoroutineContext.¶
- CoroutineScope: Defines the scope for new coroutines. It manages the lifecycle (cancellation) of coroutines.
- CoroutineContext: A set of elements that define the behavior of a coroutine (Job, Dispatcher, Name, ExceptionHandler).
46. Explain Dispatchers.¶
They determine which thread(s) the coroutine runs on.
Dispatchers.Main: UI thread (Android).Dispatchers.IO: Optimized for disk/network IO (Thread pool).Dispatchers.Default: Optimized for CPU-intensive work (Thread pool size = CPU cores).Dispatchers.Unconfined: Starts in current thread, resumes in whatever thread called resume.
47. What is Job vs Deferred?¶
Job: A handle to a background task with a lifecycle (Active, Cancelled, Completed).Deferred: A generic subclass ofJobthat holds a result. It addsawait()to retrieve the value.
48. What is Structured Concurrency?¶
A paradigm where new coroutines can only be launched in a specific CoroutineScope. This ensures:
1. Children inherit context from parents.
2. Parent waits for all children to complete.
3. If parent is cancelled, all children are cancelled.
4. If a child fails, the parent (and other children) are cancelled.
49. How do you handle exceptions in Coroutines?¶
- try-catch: Inside the coroutine body.
- CoroutineExceptionHandler: Context element to handle uncaught exceptions (only works on root coroutines launched with
launch). - SupervisorJob / supervisorScope: Prevents failure propagation to the parent.
50. supervisorScope vs coroutineScope.¶
coroutineScope: If one child fails, the scope fails and cancels all other children.supervisorScope: If one child fails, it does not affect other children or the scope itself.
Diagram: Failure Propagation
graph TD
A[Parent] --> B[Child 1 (Fails)]
A --> C[Child 2]
B -- "With coroutineScope" --> A
A -- "Cancels" --> C
B -- "With supervisorScope" --> X[Handled locally]
A -. "Unaffected" .- C
51. What are Channels?¶
Primitives for communication between coroutines. They provide a way to transfer a stream of values.
* Logically similar to BlockingQueue.
* Support send (suspend) and receive (suspend).
52. Explain Flow (Cold Stream) vs Channel (Hot Stream).¶
- Flow: Cold. Code inside
flow { ... }does not run untilcollect()is called. Each collector gets its own execution. - Channel: Hot. Values are produced even if no one is listening.
53. StateFlow vs SharedFlow.¶
- StateFlow: A hot flow that holds state. Always has an initial value. Only emits the last known value to new collectors. (Replacement for LiveData).
- SharedFlow: Highly configurable hot flow. Can emit events without state (no initial value). Can replay
nvalues to new collectors.
54. What are buffer, conflate, and collectLatest?¶
buffer(): Buffers emissions if collector is slow.conflate(): Skips intermediate values if collector is slow, only processing the latest.collectLatest(): Cancels the current block if a new value arrives.
55. How to handle Backpressure in Flows?¶
Flows support backpressure by default because they use suspending functions. If the collector is slow, the emitter suspends.
56. Thread vs Coroutine?¶
- Thread: OS-managed resource. Expensive (~1MB stack). Context switching is costly.
- Coroutine: User-space managed. Cheap (Objects). Thousands can run on one thread.
57. What is a Mutex?¶
Mutual Exclusion. A locking primitive for coroutines.
Unlike synchronized (which blocks the thread), Mutex.withLock suspends the coroutine.
58. What is an Actor?¶
An entity made up of a coroutine, the state that is confined and encapsulated into this coroutine, and a channel to communicate with other coroutines.
Note: The actor builder is currently obsolete in Kotlin Coroutines API favor of complex channels or other primitives, but the concept remains.
59. What is the select expression?¶
It waits for the result of multiple suspending functions simultaneously and selects the first one that becomes available.
60. How do you test Coroutines?¶
Using kotlinx-coroutines-test library.
* runTest: Replaces runBlocking for tests. Skips delays (virtual time).
* StandardTestDispatcher: default for runTest.
* UnconfinedTestDispatcher.
Part 4: Standard Library & Collections (61-80)¶
61. List vs MutableList.¶
List<T>: Read-only interface. Noadd,remove,set.MutableList<T>: Modifiable interface. ExtendsList.
62. map, filter, and reduce.¶
map: Transforms each element.filter: Returns elements matching a predicate.reduce: Accumulates value starting with the first element.
63. What is flatMap?¶
Transforms each element into an Iterable and then flattens these iterables into a single list.
64. What does zip do?¶
Combines two collections into a list of pairs.
65. Difference between fold and reduce.¶
reduce: Uses the first element as the initial accumulator value. Throws exception on empty collection.fold: Takes an explicit initial value. Works on empty collections.
66. Sequence vs Iterable (List).¶
- Iterable (List): Eager evaluation. Each step (
map,filter) creates a new intermediate list. - Sequence: Lazy evaluation. Operations are vertical (element by element) rather than horizontal (step by step). No intermediate collections. Better for huge data sets.
67. How does groupBy work?¶
Returns a Map where keys are the grouping criteria and values are lists of original elements.
val words = listOf("a", "abc", "ab", "def", "abcd")
val byLength = words.groupBy { it.length }
// {1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
68. What is partition?¶
Splits the collection into a pair of lists based on a predicate. * First list: Elements that match. * Second list: Elements that don't match.
69. any, all, and none.¶
any: True if at least one matches.all: True if all match.none: True if no elements match.
70. What is associateBy?¶
Creates a Map using elements as values and a key derived from the element. Risk: If keys are duplicates, the last one wins.
71. distinct vs toSet.¶
Both return unique elements.
* toSet(): Converts to a Set.
* distinct(): Returns a List containing only distinct elements.
72. Arrays: IntArray vs Array<Int>.¶
IntArray: Primitiveint[]in JVM. Unboxed. Efficient.Array<Int>: ObjectInteger[]in JVM. Boxed. More memory overhead.
73. String Manipulation.¶
Strings are immutable.
* trimMargin(): Removes whitespace.
* split(): Returns List.
* replace(): Returns new String.
74. Comparable vs Comparator.¶
Comparable: Interface implemented by the class itself (compareTo). Defines natural order.Comparator: External object that defines specific ordering (compare).
75. Why use the copy method in Data Classes?¶
To create a new instance with some properties modified, while keeping others the same. Essential for immutability patterns.
76. Range iterators: until vs downTo.¶
until: Excludes the end value.1 until 10(1..9).downTo: Descending order.10 downTo 1.
77. What is coerceIn?¶
Ensures a value is within a specific range.
78. How to measure execution time?¶
measureTimeMillis { ... } or measureTime { ... } (requires kotlin.time).
79. How to generate Random numbers?¶
Since Kotlin 1.3: Random.nextInt(from, until).
Avoid java.util.Random in pure Kotlin code for multiplatform support.
80. Regular Expressions in Kotlin.¶
Create using Regex("pattern").
* matchEntire()
* find()
* replace()
Part 5: Advanced, Android & Multiplatform (81-100)¶
81. Explain JvmStatic, JvmOverloads, JvmField.¶
Interoperability annotations.
* @JvmStatic: Generates a real static method in the bytecode.
* @JvmOverloads: Generates overloads for functions with default arguments.
* @JvmField: Exposes a property as a public field (no getters/setters).
82. What is Kotlin Multiplatform (KMP)?¶
A way to share code between platforms (Android, iOS, Web, Desktop). * Common code: Business logic. * Platform code: UI, Hardware access.
83. What is expect / actual mechanism?¶
Used in KMP.
* expect: Defined in common module. Declares "I need this functionality".
* actual: Defined in platform modules (Android, iOS). Provides implementation.
84. Reflection in Kotlin.¶
Inspects classes, properties, and functions at runtime.
Requires kotlin-reflect.jar.
Syntax: MyClass::class, ::myFunction.
85. KAPT vs KSP.¶
- KAPT: Kotlin Annotation Processing Tool. Runs Java annotation processors. Slow (generates Java stubs).
- KSP: Kotlin Symbol Processing. Native to Kotlin. Faster.
86. Dependency Injection (Concept).¶
- Koin: Service Locator pattern (DSL). Pure Kotlin. No code generation. Runtime check.
- Dagger/Hilt: Dependency Injection pattern. Compile-time generation. Strict.
87. What is ViewBinding?¶
Generates a binding class for each XML layout file. Replaces findViewById. Null-safe and Type-safe.
88. What is Jetpack Compose?¶
Modern toolkit for building native UI in Android using Kotlin.
* Declarative: You describe the UI state, framework updates the view.
* Functions: UI components are functions annotated with @Composable.
89. Memory Management (JVM).¶
Kotlin on JVM uses the JVM Garbage Collector. * Heap: Objects. * Stack: Primitives, references.
90. What is a value class (Inline Class)?¶
Wraps a single value. At runtime, instances are represented by the underlying value (unboxed) where possible, avoiding object allocation.
91. What is Type Erasure?¶
Generics are checked at compile time but removed (erased) at runtime. List<String> becomes just List (or raw List).
Solution: Reified type parameters (inline functions).
92. Covariance and Contravariance (in vs out).¶
out T(Covariant): Producer. Can only read T. Equivalent to? extends Tin Java.List<out Number>can holdList<Int>.in T(Contravariant): Consumer. Can only write T. Equivalent to? super Tin Java.Comparable<in Number>can acceptDouble.
93. What is Star Projection *?¶
Generic type with unknown argument.
* MutableList<*>: Safe to read as Any?, but unsafe to write (except Nothing).
94. What is the Nothing type?¶
A type that has no values. Represents "a value that never exists". * Used as return type for functions that always throw exceptions. * Subtype of all types.
95. What is the Unit type?¶
Corresponds to void in Java. It is a real object (singleton).
96. What are Contracts?¶
Let you describe the relationship between function parameters and return values/effects to the compiler.
* Example: require(x != null) tells the compiler x is non-null afterwards.
97. What are Context Receivers?¶
(Experimental) Allows a function to have multiple receivers.
98. Kotlin Scripting (.kts).¶
Kotlin code that can run as a script without compilation to a .jar. Used in Gradle Kotlin DSL.
99. Gradle Kotlin DSL.¶
Writing build.gradle.kts using Kotlin instead of Groovy.
* Pros: Autocomplete, Refactoring, Type safety.
* Cons: Slower initial build (compilation).
100. What is the K2 Compiler?¶
The new Kotlin compiler frontend. * Faster compilation. * Better type inference. * Foundation for future language features.
End of Interview Questions
Study Guide¶
To deepen your understanding of these concepts, check out the following resources:
- Official Documentation: Kotlin Docs
- Internal Style Guide: Kotlin Style Guide