Top 50 Kotlin Interview Questions 2026

What changed in 2026 drives
Mass-recruiter offer letters are flatter for 2026 batch - the 4-5 LPA ASE band has barely budged in three years while inflation eats real wages. Premium tracks (Digital, Pro, Elite, Specialist) are still where the differential lives, and they are entirely test-driven. If you are aiming higher than the default offer, the coding round is not optional pageantry - it is the entire interview.
What I'd actually study for this
- 01Two solid coding-round answers (1 medium-hard DSA each, with edge-case discussion) > five half-baked ones
- 02One real project you can defend end-to-end - file paths, design decisions, and what you would change
- 03One DBMS schema you actually built (not a textbook ER diagram), with at least 3 join-heavy queries written from memory
- 04Three behavioural STAR stories: failure recovered, conflict handled, ownership taken
Where most candidates trip up
The single biggest mistake is treating company-specific guides as primary prep and DSA as secondary. It is the opposite. Mass recruiters use the test as a filter, but premium tracks at every IT services company use coding to allocate offer band. Spend 70% of prep time on DSA + system fundamentals, 20% on company-specific patterns, 10% on HR rehearsal. Reverse that ratio and you collect the default offer.
Editorial commentary by Aditya Sharma · written for PapersAdda · not generated, not aggregated.
Last Updated: June 2026 | Level: Freshers to 3 Years Experience | Read Time: ~22 min
Kotlin is the primary language for Android development and is growing in backend use. Candidates report that null safety, coroutines, data classes, and sealed classes are the most consistently tested topics in Android engineering interviews. This guide covers 50 questions from basic syntax to advanced coroutines, with predict-the-output problems and comparison tables. Confirm current requirements on the official careers portal for the company you are targeting.
Pair with Java Interview Questions 2026 and Spring Boot Interview Questions 2026 for complete preparation.
Table of Contents
- Kotlin Basics (Q1-Q12)
- OOP and Functional Features (Q13-Q22)
- Null Safety (Q23-Q30)
- Coroutines and Async (Q31-Q40)
- Collections and Sequences (Q41-Q46)
- Advanced Topics (Q47-Q50)
- Mock Interview: 5 Questions
- FAQ
Kotlin Basics
Q1. What is Kotlin and how does it interoperate with Java? Easy
// Kotlin calling Java
val list = java.util.ArrayList<String>() // Java class, works fine
list.add("hello")
// Java calling Kotlin
// Kotlin top-level functions become static methods on a class named FileName.kt -> FileNameKt
// @JvmStatic annotation for companion object methods
Q2. What is the difference between val and var? Easy
val name = "Aditya" // immutable, like Java's final
// name = "other" // compile error
var count = 0 // mutable
count++ // ok
// val != constant: can be computed at runtime
val timestamp = System.currentTimeMillis()
// const: true compile-time constant
const val MAX = 100
Rule: default to val. Use var only when mutation is genuinely needed.
Q3. What is the Kotlin type system? How does it differ from Java? Easy
| Feature | Kotlin | Java |
|---|---|---|
| Null safety | Nullable (String?) vs non-null (String) | All references nullable |
| Primitives | Unified (Int, Long - no separate int) | int + Integer |
| Type inference | Yes | Limited (since Java 10 var) |
| Smart casts | Yes | Manual cast required |
Q4. What are data classes? Easy
data class User(val name: String, val age: Int)
val u1 = User("Aditya", 25)
val u2 = u1.copy(age = 26) // create modified copy
println(u1 == u2) // false (structural equality)
println(u1.toString()) // User(name=Aditya, age=25)
val (name, age) = u1 // destructuring
Q5. What are sealed classes? When would you use them? Medium
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val message: String) : Result<Nothing>()
object Loading : Result<Nothing>()
}
fun handle(result: Result<User>) = when (result) {
is Result.Success -> println(result.data)
is Result.Error -> println("Error: ${result.message}")
is Result.Loading -> println("Loading...")
// no else needed - compiler knows all cases
}
Q6. What are companion objects? Medium
class Config {
companion object {
const val VERSION = "1.0"
fun create(): Config = Config()
}
}
Config.VERSION // access like static
Config.create() // factory method
Companion objects can have names and implement interfaces.
Q7. What are object declarations and expressions? Medium
// Object declaration: singleton
object DatabasePool {
val connections = mutableListOf<Connection>()
fun acquire() = connections.firstOrNull()
}
// Object expression: anonymous object (like Java anonymous class)
val comparator = object : Comparator<Int> {
override fun compare(a: Int, b: Int) = a - b
}
Q8. What is the when expression? Easy
val x = 5
val result = when (x) {
1 -> "one"
2, 3 -> "two or three"
in 4..10 -> "four to ten"
is Int -> "some int"
else -> "other"
}
println(result) // "four to ten"
// Without argument (replaces if-else chain)
when {
x < 0 -> println("negative")
x == 0 -> println("zero")
else -> println("positive")
}
Q9. What are extension functions? Medium
// Extend String class
fun String.capitalize(): String = this[0].uppercase() + this.substring(1)
// Extend List
fun <T> List<T>.second(): T = this[1]
"hello world".capitalize() // Hello world
listOf(10, 20, 30).second() // 20
Extension functions are resolved statically (at compile time), not polymorphically.
Q10. What is string interpolation in Kotlin? Easy
val name = "Aditya"
val age = 25
println("My name is $name") // simple
println("Next year I will be ${age + 1}") // expression
println("Initials: ${name[0]}") // indexing
// Raw strings
val json = """
{
"name": "$name",
"age": $age
}
""".trimIndent()
Q11. What is lateinit and lazy? Medium
// lateinit: for mutable var, initialized after declaration
class Activity {
lateinit var presenter: Presenter
fun onCreate() {
presenter = Presenter() // initialized here
presenter.start()
}
}
// lazy: for val, computed on first access, thread-safe by default
val heavyConfig: Config by lazy {
println("initializing")
loadConfigFromDisk()
}
// "initializing" prints only on first access
lateinit throws UninitializedPropertyAccessException if accessed before init. lazy is computed once and cached.
Q12. Predict the output: Easy
fun main() {
val nums = listOf(1, 2, 3, 4, 5)
val result = nums
.filter { it % 2 == 0 }
.map { it * it }
.sum()
println(result)
}
Output: 20
Explanation: Filter keeps [2, 4]. Map squares them: [4, 16]. Sum: 20.
OOP and Functional Features
Q13. What is the difference between abstract class and interface in Kotlin? Medium
| Feature | abstract class | interface |
|---|---|---|
| State | Can have fields with state | Properties (no backing field by default) |
| Constructor | Yes | No |
| Inheritance | Single | Multiple |
| Default implementation | Yes | Yes (since Kotlin 1.0) |
| Visibility | Any | Public by default |
interface Printable {
val prefix: String get() = "LOG" // default property
fun print(msg: String) = println("$prefix: $msg") // default impl
}
abstract class Document {
var title = ""
abstract fun render(): String
}
Q14. How does Kotlin handle multiple inheritance conflicts? Medium
interface A { fun hello() = println("A") }
interface B { fun hello() = println("B") }
class C : A, B {
override fun hello() {
super<A>.hello() // explicit disambiguation
super<B>.hello()
}
}
Kotlin requires explicit override when multiple supertypes provide conflicting implementations.
Q15. What are higher-order functions and lambdas? Medium
// Higher-order function
fun operate(a: Int, b: Int, op: (Int, Int) -> Int): Int = op(a, b)
val sum = operate(3, 4) { x, y -> x + y } // 7
val product = operate(3, 4) { x, y -> x * y } // 12
// Function type as variable
val square: (Int) -> Int = { n -> n * n }
val squaredNums = listOf(1, 2, 3).map(square) // [1, 4, 9]
Q16. What is the inline keyword? Advanced
inline fun <T> measureTime(block: () -> T): T {
val start = System.currentTimeMillis()
val result = block()
println("Took ${System.currentTimeMillis() - start}ms")
return result
}
// No lambda object created; code is copied to call site
val result = measureTime { computeHeavy() }
Q17. What are let, run, apply, also, with? Medium
| Function | Receiver | Returns | Key Use |
|---|---|---|---|
let | it | Lambda result | Null check, transform |
run | this | Lambda result | Object config + compute |
apply | this | The object itself | Object initialization |
also | it | The object itself | Side effects (logging) |
with | this | Lambda result | Multiple calls on object |
// apply: builder pattern
val user = User().apply {
name = "Aditya"
age = 25
}
// let: null-safe call
user?.let { println(it.name) }
// also: logging without changing chain
val list = mutableListOf(1, 2, 3)
.also { println("before: $it") }
.map { it * 2 }
Q18. What is typealias? Medium
typealias UserId = String
typealias Callback = (String, Int) -> Unit
fun processUser(id: UserId, callback: Callback) {
callback(id, 200)
}
Type aliases improve readability but do not create new types - they are interchangeable at runtime.
Q19. What are destructuring declarations? Medium
// Data class
data class Point(val x: Int, val y: Int)
val (x, y) = Point(3, 4)
// Map entries
for ((key, value) in mapOf("a" to 1, "b" to 2)) {
println("$key -> $value")
}
// Lambda parameters
val pairs = listOf(Pair("x", 1), Pair("y", 2))
pairs.forEach { (name, value) -> println("$name=$value") }
Q20. What is operator overloading in Kotlin? Medium
data class Vector(val x: Double, val y: Double) {
operator fun plus(other: Vector) = Vector(x + other.x, y + other.y)
operator fun times(scalar: Double) = Vector(x * scalar, y * scalar)
override fun toString() = "($x, $y)"
}
val v1 = Vector(1.0, 2.0)
val v2 = Vector(3.0, 4.0)
println(v1 + v2) // (4.0, 6.0)
println(v1 * 2.0) // (2.0, 4.0)
Q21. Predict the output: Medium
fun main() {
var x = 10
val add = { n: Int -> x += n }
add(5)
add(3)
println(x)
}
Output: 18
Explanation: Kotlin lambdas can capture and mutate var variables from the enclosing scope (unlike Java, which requires effectively-final variables in lambdas).
Q22. What is reified type parameter? Advanced
// Without reified: T is erased at runtime
fun <T> isType(value: Any): Boolean = value is T // compile error
// With reified: T is available at runtime (only in inline functions)
inline fun <reified T> isType(value: Any): Boolean = value is T
println(isType<String>("hello")) // true
println(isType<Int>("hello")) // false
Null Safety
Q23. How does Kotlin's null safety work? Easy
var name: String = "Aditya"
// name = null // compile error
var nullable: String? = null
nullable = "now set"
// Safe call operator
println(nullable?.length) // prints length or null
// Elvis operator: default if null
val len = nullable?.length ?: 0
// Not-null assertion (throws NullPointerException if null)
val len2 = nullable!!.length // risky, avoid when possible
Q24. What is the Elvis operator? Easy
val name: String? = null
val display = name ?: "Anonymous" // "Anonymous"
// Chained
val city = user?.address?.city ?: "Unknown"
// Elvis with throw
val user = findUser(id) ?: throw IllegalArgumentException("User not found: $id")
Q25. What is the ?: vs !! operator? When is each appropriate? Medium
| Operator | Name | Behavior | When to use |
|---|---|---|---|
?. | Safe call | Returns null if receiver is null | Chaining nullable calls |
?: | Elvis | Returns default if left side is null | Providing fallbacks |
!! | Not-null assertion | Throws NPE if null | When you are CERTAIN not null and want to fail fast |
// BAD: !! in production logic
val len = user!!.name!!.length // NPE-prone
// GOOD: safe chain + elvis
val len = user?.name?.length ?: 0
Q26. What is let for null checks? Medium
val maybeUser: User? = findUser(id)
// Without let (verbose)
if (maybeUser != null) {
println(maybeUser.name)
}
// With let (idiomatic)
maybeUser?.let { user ->
println(user.name)
sendEmail(user.email)
}
Q27. What is requireNotNull and checkNotNull? Medium
fun process(name: String?) {
val n = requireNotNull(name) { "name must not be null" }
// n is String (non-nullable) here
println(n.uppercase())
}
// checkNotNull: same but throws IllegalStateException instead of IllegalArgumentException
val config = checkNotNull(loadConfig()) { "Config not loaded" }
Q28. How do platform types work (Java interop)? Medium
// Java method returns String (possibly null)
val result: String = JavaClass.getResult() // risky - might be null
val safe: String? = JavaClass.getResult() // safe - explicitly nullable
Annotating Java with @Nullable/@NotNull (from Jetbrains or Android) gives Kotlin proper type information.
Q29. Predict the output: Medium
fun main() {
val s: String? = "hello"
val len = s?.length ?: -1
println(len)
val n: String? = null
val len2 = n?.length ?: -1
println(len2)
}
Output:
5
-1
Q30. What is filterNotNull? Easy
val mixed: List<String?> = listOf("a", null, "b", null, "c")
val clean: List<String> = mixed.filterNotNull()
println(clean) // [a, b, c]
Coroutines
Q31. What are Kotlin coroutines? How are they different from threads? Medium
| Feature | Coroutines | Threads |
|---|---|---|
| Memory per unit | ~1 KB | ~1 MB |
| Creation overhead | Microseconds | Milliseconds |
| Context switching | Controlled by coroutine dispatcher | OS scheduler |
| Suspend/resume | Non-blocking | Blocking |
| 1 million units | Feasible | Not feasible (RAM) |
Q32. What is suspend? What can call a suspend function? Medium
suspend fun fetchUser(id: Int): User {
delay(100) // non-blocking wait
return httpGet("users/$id")
}
// Can only be called from:
// 1. Another suspend function
// 2. A coroutine builder (launch, async)
fun main() = runBlocking {
val user = fetchUser(42) // OK inside runBlocking
println(user.name)
}
Q33. What is the difference between launch and async? Medium
// launch: fire and forget, returns Job
val job = GlobalScope.launch {
doSomething()
}
job.cancel()
// async: returns Deferred<T>, result via await()
val deferred = GlobalScope.async {
fetchData() // returns String
}
val result: String = deferred.await()
Use launch for side effects. Use async/await when you need the return value.
Q34. What is CoroutineScope and CoroutineContext? Advanced
class MyViewModel : ViewModel() {
// viewModelScope is cancelled when ViewModel is cleared
fun loadData() = viewModelScope.launch {
val data = withContext(Dispatchers.IO) {
fetchFromNetwork() // runs on IO thread pool
}
updateUI(data) // back on Main thread
}
}
Q35. What are coroutine dispatchers? Medium
| Dispatcher | Thread pool | Use case |
|---|---|---|
Dispatchers.Main | Main/UI thread | UI updates |
Dispatchers.IO | Shared pool (64 threads) | Network, DB, file I/O |
Dispatchers.Default | CPU-core count | CPU-intensive work |
Dispatchers.Unconfined | Caller's thread | Testing, simple transforms |
withContext(Dispatchers.IO) { readFile() }
withContext(Dispatchers.Default) { sortLargeList() }
Q36. What is structured concurrency? Advanced
coroutineScope {
val a = async { fetchUserDetails() }
val b = async { fetchUserOrders() }
// If a throws, b is cancelled automatically
println("${a.await()} ${b.await()}")
} // scope exits only when all children complete
Q37. What is Flow in Kotlin? Advanced
fun numberFlow(): Flow<Int> = flow {
for (i in 1..5) {
delay(100)
emit(i)
}
}
// Collect in a coroutine
viewModelScope.launch {
numberFlow()
.filter { it % 2 == 0 }
.map { it * it }
.collect { println(it) } // 4, 16
}
Q38. What is the difference between StateFlow and SharedFlow? Advanced
| Feature | StateFlow | SharedFlow |
|---|---|---|
| Initial value | Required | Not required |
| Replay | 1 (latest) | Configurable |
| Use case | State (current value) | Events (one-time) |
| Behavior | Hot, conflated | Hot, configurable |
// StateFlow: for UI state
val uiState = MutableStateFlow(UiState.Loading)
// SharedFlow: for events
val events = MutableSharedFlow<Event>()
Q39. What is withTimeout? Medium
try {
val result = withTimeout(3000L) { // milliseconds
fetchSlowData()
}
} catch (e: TimeoutCancellationException) {
println("Operation timed out")
}
// withTimeoutOrNull returns null instead of throwing
val result = withTimeoutOrNull(3000L) { fetchSlowData() } ?: "default"
Q40. Predict the output: Advanced
fun main() = runBlocking {
val job = launch {
repeat(5) { i ->
println("job: step $i")
delay(100)
}
}
delay(250)
println("cancelling")
job.cancelAndJoin()
println("done")
}
Output:
job: step 0
job: step 1
job: step 2
cancelling
done
Explanation: After 250ms, steps 0, 1, 2 have completed (each takes 100ms). The job is then cancelled before step 3.
Collections and Sequences
Q41. What is the difference between Sequence and List operations? Advanced
// Eager: creates 3 intermediate lists
listOf(1..1_000_000)
.map { it * 2 }
.filter { it > 10 }
.take(5)
// Lazy: processes elements one at a time, stops after 5
(1..1_000_000).asSequence()
.map { it * 2 }
.filter { it > 10 }
.take(5)
.toList()
Use Sequence for large collections or pipelines where you take only a few results.
Q42. Key collection operations: Easy
val nums = listOf(3, 1, 4, 1, 5, 9, 2, 6)
nums.sorted() // [1, 1, 2, 3, 4, 5, 6, 9]
nums.sortedByDescending { it } // [9, 6, 5, 4, 3, 2, 1, 1]
nums.distinct() // [3, 1, 4, 5, 9, 2, 6]
nums.groupBy { it % 2 == 0 } // {false=[3,1,1,5,9], true=[4,2,6]}
nums.partition { it > 4 } // ([5, 9, 6], [3, 1, 4, 1, 2])
nums.windowed(3) // [[3,1,4],[1,4,1],[4,1,5],...]
nums.chunked(3) // [[3,1,4],[1,5,9],[2,6]]
nums.fold(0) { acc, v -> acc + v } // 31 (sum)
nums.reduce { acc, v -> acc + v } // 31 (sum, no initial value)
Q43. What are mapOf, mutableMapOf, and linkedMapOf? Easy
val map = mapOf("a" to 1, "b" to 2) // immutable, unordered
val mutable = mutableMapOf("x" to 10) // mutable, unordered
val linked = linkedMapOf("first" to 1, "second" to 2) // insertion-ordered
mutable["y"] = 20
mutable.getOrDefault("z", 0) // 0
mutable.getOrPut("z") { 30 } // inserts and returns 30
Q44. What is flatMap? Medium
val nested = listOf(listOf(1, 2), listOf(3, 4), listOf(5))
val flat = nested.flatMap { it }
println(flat) // [1, 2, 3, 4, 5]
// Each word split into characters
val words = listOf("hello", "world")
val chars = words.flatMap { it.toList() }
// [h, e, l, l, o, w, o, r, l, d]
Q45. What is zip and unzip? Medium
val names = listOf("Alice", "Bob", "Charlie")
val scores = listOf(95, 87, 91)
val combined = names.zip(scores) // [(Alice, 95), (Bob, 87), (Charlie, 91)]
val (ns, ss) = combined.unzip() // back to separate lists
Q46. Predict the output: collection chain. Medium
fun main() {
val result = (1..10)
.filter { it % 3 == 0 }
.map { it * 2 }
.sumOf { it }
println(result)
}
Output: 72
Explanation: Numbers divisible by 3 in 1-10: [3, 6, 9]. Doubled: [6, 12, 18]. Sum: 36. Wait - sumOf with the doubled values: 6+12+18 = 36. Actually: filter gives [3,6,9], map gives [6,12,18], sumOf gives 36. Correction: output is 36.
Corrected output: 36
Advanced Topics
Q47. What is delegation in Kotlin (by)? Advanced
// Property delegation
class Prefs(val prefs: SharedPreferences) {
var username by StringPref(prefs, "username", "")
}
// Interface delegation - forward all calls to wrapped object
class LoggingList<T>(private val inner: MutableList<T>) : MutableList<T> by inner {
override fun add(element: T): Boolean {
println("Adding: $element")
return inner.add(element)
}
}
Q48. What is Kotlin Multiplatform (KMP)? Advanced
// commonMain
expect fun getPlatformName(): String
// androidMain
actual fun getPlatformName(): String = "Android"
// iosMain
actual fun getPlatformName(): String = "iOS"
Q49. What are inline classes (value classes)? Advanced
@JvmInline
value class UserId(val value: Long)
@JvmInline
value class Email(val value: String)
// At runtime these wrap a single primitive - no heap allocation
fun sendEmail(id: UserId, email: Email) { ... }
// Type safety without runtime overhead
sendEmail(UserId(42), Email("[email protected]"))
// sendEmail(Email("..."), UserId(42)) // compile error
Q50. What is the difference between == and === in Kotlin? Easy
val a = "hello"
val b = "hello"
val c = String(charArrayOf('h','e','l','l','o'))
println(a == b) // true: structural equality (calls equals())
println(a === b) // true: same reference (string pool in JVM)
println(a == c) // true: structural equality
println(a === c) // false: different objects
== in Kotlin is equivalent to Java's .equals(). === is equivalent to Java's == (reference check).
Mock Interview: 5 Questions
- Implement a thread-safe counter in Kotlin using coroutines (no locks).
- Write a sealed class hierarchy for a network
Resulttype and handle all cases in awhenexpression. - Convert this Java-style null-checking code to idiomatic Kotlin null safety.
- Explain why
StateFlowis better thanLiveDatafor non-Android modules. - Given a
List<User?>, write a single chain to get the uppercase names of non-null users sorted alphabetically.
FAQ
Q: Should I learn Kotlin or Java for Android? A: Kotlin. New Android codebases at product companies are Kotlin-first. Google officially recommends it, and all new Jetpack APIs are Kotlin-first.
Q: Is coroutines knowledge required for freshers? A: Basic awareness yes - know what a suspend function is, launch vs async. Deep coroutines internals are asked at senior level.
Q: Does Kotlin work for competitive programming? A: Yes, but most competitive programmers prefer Java or C++ due to faster I/O. Kotlin is accepted on Codeforces, LeetCode, and HackerRank.
Related reading: Java Interview Questions 2026 | Android Interview Questions | Spring Boot Interview Questions 2026 | React Native Interview Questions 2026
Methodology applied to this articlelast verified 8 Jun 2026
- No fabricated salary numbers or success rates. If we quote a range, it's sourced.
- No noun-substituted templates. This article was not generated by swapping company names in a stock prompt.
- No paid placements, sponsored coaching links, or affiliate-shilled course pushes.
Explore this topic cluster
More resources in Interview Questions
Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.
Paid contributor programme
Sat this this year? Share your story, earn ₹500.
First-person experience reports help future candidates prep smarter. We pay verified contributors ₹500 via UPI per accepted story - with byline.
Submit your story →Ready to practice?
Take a free timed mock test
Put what you learned into practice. Our mock tests match the 2026 pattern with timer, navigator, reveal, and score breakdown. No signup.
Start Free Mock Test →Related Articles
Airbnb Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing Airbnb's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical, behavioural,...
Airtel Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing Airtel's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical, behavioural,...
AMD Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing AMD's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical, behavioural,...
Atlassian Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing Atlassian's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical,...
Barclays Interview Questions 2026
_Last verified by [Aditya Sharma](/author/aditya-sharma/) · cross-checked against PapersAdda Hiring Pulse and...
More from PapersAdda
Top 15 Product Companies Hiring Freshers India 2026: Compensation + Bar + Interview Loop
Accenture Interview Process 2026: Rounds & Prep
Accenture Interview Questions 2026 (with Answers for Freshers)
Adobe Interview Process 2026: Rounds, OA & Aptitude