---
title: "Kotlin: Modern JVM Language Fundamentals"
description: "Test your knowledge of Kotlin covering null safety and smart casts, data classes, coroutines and structured concurrency, extension functions, scope functions, sealed classes, and Java interoperability."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/quizzes/post/kotlin-fundamentals-quiz
---

# Kotlin: Modern JVM Language Fundamentals

Kotlin reads like a friendlier Java for about a week, and then you meet the parts that are genuinely different: nullability living in the type system, coroutines with a scope that owns its children, and extension functions that look like methods but do not dispatch like them.

This quiz targets those. Most questions are about a distinction that compiles either way, which is what makes them worth knowing: the wrong choice does not fail, it quietly does something else.

_Null safety and structured concurrency, side by side_

Several questions are really about production behaviour rather than syntax, and one in particular is worth seeing laid out, because it is where the coroutine model meets a blocking JDBC driver.

_A Kotlin service on AWS, and the dispatcher trap_

Read the explanations even on the ones you get right. Most name the specific failure mode rather than restating the answer, and the failure mode is the reason the distinction exists at all.

## Questions

### 1. Why does `s.length` fail to compile when `s` is declared as `String?`

- `String?` is a different type from `String`, and the compiler will not allow member access until null is handled
- Kotlin inserts a runtime null check and it fails there
- `length` is not defined on `String?`, so you need an extension function
- You must annotate the variable with `@Nullable` first

**Hint:** Think about whether nullability is checked at runtime or expressed in the type.

### 2. What does `!!` actually do?

- Asserts the value is non-null, throwing a KotlinNullPointerException if it is not
- Converts null into the type default, such as an empty string
- Suppresses the compiler warning without any runtime effect
- Marks the variable as non-null for the rest of the scope

**Hint:** It is not a way of telling the compiler to relax.

### 3. What is a platform type, written `String!` in IDE hints?

- A type from Java with unknown nullability, which Kotlin neither enforces nor rejects
- A type that changes depending on the target platform, JVM or Native
- An alias for `String?`
- A primitive type mapped to `java.lang.String`

**Hint:** It arises at a boundary where Kotlin has no nullability information.

### 4. Which members does `data class User(val id: String, val name: String)` generate?

- equals, hashCode, toString, copy, and componentN, from the constructor properties only
- The same five, from every property including those in the class body
- Only equals and hashCode; toString and copy must be written by hand
- Getters and setters, nothing more

**Hint:** Five things, and one common assumption about what is included is wrong.

### 5. What is the difference between `val` and `const val`?

- `const val` is a compile-time constant inlined at use sites; `val` is assigned at runtime
- They are identical; `const` is only documentation
- `val` is immutable and `const val` is mutable
- `const val` can only be used inside a class body

**Hint:** One is resolved by the compiler, the other at runtime.

### 6. What does `coroutineScope { }` guarantee that plain `launch` on a global scope does not?

- It waits for all children, and cancels the siblings if one fails
- It runs the children on a dedicated thread pool
- It makes the children run sequentially
- It retries any child that throws

**Hint:** Two guarantees, both about the relationship between parent and children.

### 7. How do `launch` and `async` differ in how an exception surfaces?

- `launch` propagates immediately; `async` holds the exception until `await()` is called
- Both propagate immediately to the parent scope
- Both swallow exceptions unless a CoroutineExceptionHandler is installed
- `async` propagates immediately; `launch` requires joining the Job

**Hint:** One tells you immediately, the other waits to be asked.

### 8. Does marking a function `suspend` make a blocking JDBC call non-blocking?

- No. Wrap it in withContext(Dispatchers.IO), or use a non-blocking driver
- Yes, the compiler rewrites blocking calls into non-blocking ones
- Yes, as long as the function is called from a coroutine
- Only if the function also returns a Deferred

**Hint:** Think about what suspend actually changes, and what it cannot change.

### 9. What is the difference between `apply` and `let`?

- `apply` returns the receiver; `let` returns the lambda result
- `apply` works on nullables and `let` does not
- They are interchangeable; the difference is only the parameter name
- `apply` is inline and `let` is not

**Hint:** Consider what each returns.

### 10. What does a `sealed` class give you that an abstract class does not?

- A closed set of subclasses, so `when` can be checked for exhaustiveness without an else
- Automatic equals and hashCode for all subclasses
- It prevents instantiation
- It makes all subclasses singletons

**Hint:** It is about what the compiler can prove at the `when`.

### 11. How is an extension function dispatched?

- Statically, by the declared type; it is compiled to a static method and cannot be overridden
- Dynamically, like a normal member function override
- The class is reopened and the function added to it
- At runtime via reflection

**Hint:** Think about whether the receiver object has any say in it.

### 12. What is `lateinit var` for, and what is its main limitation?

- Deferring initialisation of a non-null property; it cannot be used with primitives and throws if read too early
- Making a property thread-safe on first access
- Allowing a `val` to be reassigned once
- Giving a nullable property a non-null default

**Hint:** Consider which types it can be applied to.

### 13. Why does an `object` declaration differ from a class with a companion object?

- An `object` is a standalone singleton; a companion object is a singleton belonging to a class
- A companion object is static in the JVM sense and an object is not
- Objects cannot implement interfaces
- A companion object is created per instance of the class

**Hint:** One is the instance itself.

### 14. What does `@JvmStatic` change when Kotlin code is called from Java?

- It emits a real static method, so Java can call it without going through `Companion`
- It makes the method final and non-overridable
- It moves the method onto the companion object
- It allows the method to be called before class initialisation

**Hint:** Think about what the Java caller has to type without it.
