The questions that come up most often, each with a sample answer you can adapt into your own words. Read them out loud until the explanation feels natural.
How does Kotlin handle null safety?
FundamentalsNullability is part of the type system: a non-null type like String cannot hold null, and you must use the nullable type String? to allow it, which the compiler then forces you to handle. The safe-call operator ?. returns null instead of throwing if the receiver is null, the Elvis operator ?: supplies a default, and !! asserts non-null and throws if wrong. This eliminates most NullPointerExceptions at compile time.
What is the difference between val and var?
Fundamentalsval declares a read-only (immutable) reference that cannot be reassigned after initialisation, while var declares a mutable one. val is preferred by default for safety and clarity. Note that val makes the reference immutable, not the object it points to; a val list reference can still have its contents mutated unless the collection itself is immutable.
What is a coroutine and how does it differ from a thread?
IntermediateA coroutine is a lightweight unit of asynchronous work that can suspend and resume without blocking the underlying thread, so thousands can run on a small thread pool. A thread is a heavier OS-level resource. A suspending function pauses at suspension points and frees its thread for other work, which is why coroutines keep the Android main thread responsive and scale better than thread-per-task on the backend.
What is the difference between launch and async?
Advancedlaunch starts a coroutine that does not return a result (fire-and-forget), returning a Job you can cancel or join. async starts a coroutine that computes a value and returns a Deferred, whose result you obtain with await. Use launch for side-effecting work and async when you need a result, especially to run several computations concurrently and await them together.
What is a data class?
IntermediateA data class is a class declared with the data keyword for which the compiler auto-generates equals(), hashCode(), toString(), and copy() based on the properties in the primary constructor, plus componentN() functions for destructuring. It is ideal for value/DTO types and removes the boilerplate Java requires. copy() makes it easy to produce a modified duplicate while keeping immutability.
What is a sealed class and why use one?
AdvancedA sealed class restricts its subclasses to a known set declared in the same module, so the compiler knows every possible subtype. This makes a when expression over it exhaustive without an else branch, and the compiler flags you if you add a subtype and forget to handle it. It is the idiomatic way to model a closed set of states, like a UI state of Loading, Success, or Error.
What is an extension function?
IntermediateAn extension function lets you add a method to an existing type without modifying or inheriting from it, by declaring fun Type.newMethod(). It is resolved statically (it does not actually modify the class) and is widely used to add readable helpers to standard or third-party types. The Kotlin standard library is built largely from extension functions on collections and strings.
What is a platform type and why is it a risk?
AdvancedWhen Kotlin calls Java code, the Java type's nullability is usually unknown, so Kotlin treats it as a platform type (written String!), trusting you to know whether it can be null. The risk is that you can use it as non-null without a compiler check, so a Java method returning null can still cause an NPE at runtime. The mitigation is to annotate Java with @Nullable/@NonNull or defensively treat interop values as nullable.