Kotlin 2.x, KSP & Collections Interview Questions

KOTLIN › Modern Kotlin

You migrate a module from kapt to KSP and a previously working annotation processor library now fails to generate code. Walk me through what's likely going on and how KSP's programming model actually differs from kapt's under the hood.

What a strong answer covers: KSP works directly against a symbol/resolver API over the source structure instead of kapt's approach of generating Java stub classes and running the processor through javac, so a processor built against kapt's APT-based assumptions doesn't automatically work on KSP, it needs a dedicated KSP-native rewrite from the library author. The practical answer is to check whether the library ships a KSP artifact rather than assuming it's a drop-in swap, and to know that some processors lag behind on KSP support entirely.

A teammate returns a List<String> from a repository function, then a caller casts it to MutableList<String> and mutates it in place at the call site. What's actually going on here, and why does the compiler allow it?

What a strong answer covers: Kotlin's List is a read-only interface view, not a guarantee of immutability; the underlying runtime object is very likely still an ArrayList, which also implements MutableList, so the unchecked cast succeeds and the mutation works, silently breaking whatever contract the read-only return type implied. A strong answer flags this as a real bug source in shared state and mentions defensive copying or a genuinely immutable collection type when the guarantee actually matters.

How would you decide whether your team should adopt context parameters today versus sticking with extension-function or constructor-based dependency passing?

What a strong answer covers: Context parameters are still an evolving, relatively recent feature (renamed from context receivers), so a senior engineer weighs source and binary compatibility risk, IDE/tooling maturity, and whether the API surface is public (library) versus internal app code where churn is cheaper to absorb. The win is real for implicit cross-cutting dependencies like a Logger or a scope, but adopting it in a public library API today is a different risk calculus than using it inside an app module you fully control.

Back to Kotlin 2.x, KSP & Collections