OctogleHire
← Interview questions library

25 Kotlin interview questions

Structure a Kotlin interview loop around evidence, not syntax recall. Start with a 30-minute screen on recent Kotlin work, production debugging, and comfort with JDK 21, Gradle, and common frameworks such as Spring Boot 3.x, Ktor 3.x, or Android where relevant. Follow with a focused coding exercise that tests null-safety, collections, coroutines, tests, and readable design. Add a debugging/refactoring round using real Kotlin code with flaky tests, blocking calls, or poor boundaries. For mid and senior candidates, include a system design discussion on API shape, persistence, observability, deployment, and failure modes. Finish with a behavioral/ownership interview covering code review, incident response, trade-offs, and collaboration in remote teams.

Junior Kotlin questions

Fundamentals, learning speed and how they debug.

  1. 01You are reviewing Kotlin code that uses several `!!` operators around request fields and database results. How would you decide what to change first?

    Listen for: A strong answer treats nullability as a domain and boundary problem, not just a compiler issue. Listen for validating input at the edge, modeling required versus optional fields, using safe calls or `requireNotNull` with useful errors, and adding tests for missing data. They should avoid blindly replacing `!!` with `?.`.

    Red flag: They say `!!` is fine because it fails fast without discussing where the failure occurs or how it is reported.

  2. 02A teammate wrote a long chain of `map`, `filter`, and `flatMap` over a list, and it is hard to debug. What would you do?

    Listen for: Look for judgment about readability versus clever functional style. A good junior can explain intermediate names, small helper functions, sequence use only when useful, and tests around edge cases. They should know collection operations are eager by default and be able to use the debugger or logging without rewriting everything unnecessarily.

    Red flag: They insist all loops are bad or all functional chains are automatically better.

  3. 03How would you test a Kotlin service method that calls a repository and returns a sealed result type?

    Listen for: They should discuss testing behavior rather than implementation details: success, not found, validation error, and repository failure paths. Listen for clear fixtures, assertions on specific sealed subclasses, avoiding brittle mock setup, and using JUnit 5 plus MockK or fakes. Bonus if they mention testing public API boundaries and meaningful names.

    Red flag: They only test the happy path or assert that a mock method was called without checking the result.

  4. 04You see `runBlocking` inside application code in a Spring Boot or Ktor service. What questions would you ask before changing it?

    Listen for: A good answer recognizes `runBlocking` can be valid at top-level entry points or tests but suspicious inside request handling. They should ask whether the caller is already suspending, whether blocking IO is involved, what dispatcher is used, and whether the framework supports suspending handlers. They should propose small, tested changes.

    Red flag: They remove `runBlocking` everywhere without understanding call sites or threading.

  5. 05A Gradle Kotlin DSL build is slow and hard to understand. What would you inspect first as a junior engineer?

    Listen for: Listen for practical steps: run with build scans or `--profile`, check dependency resolution, kapt versus KSP usage, unnecessary plugins, test task configuration, and version catalogs. They do not need to be a build expert, but should know to measure before changing and to keep build logic simple and reviewed.

    Red flag: They start deleting dependencies or changing plugin versions without reproducing the problem.

  6. 06When would you choose a `data class`, a regular class, or a value class in Kotlin?

    Listen for: A strong junior answer connects language features to intent. `data class` is for immutable-ish value carriers with generated equality and copy; regular classes fit behavior, identity, lifecycle, or controlled equality; value classes wrap primitives for type safety with constraints. They should mention not exposing mutable collections accidentally.

    Red flag: They choose `data class` for every model because it is shorter.

Mid-level Kotlin questions

Independent delivery, trade-offs and code quality.

  1. 07A Kotlin API endpoint sometimes times out under load. It uses coroutines, a JDBC repository, and calls an external HTTP service. How would you debug it?

    Listen for: Look for a structured approach: check metrics, traces, thread dumps, connection pools, dispatcher saturation, HTTP client timeouts, and database query times. A strong answer distinguishes suspending from non-blocking, knows JDBC blocks threads, and may isolate blocking work on an appropriate dispatcher while fixing pool sizing and deadlines.

    Red flag: They assume coroutines automatically make blocking database and HTTP work scalable.

  2. 08How do you design error handling for a Kotlin service without turning every function into `try/catch` or throwing unchecked exceptions everywhere?

    Listen for: Strong candidates separate expected domain outcomes from unexpected failures. Listen for sealed result types or Arrow-style `Either` where useful, exceptions at infrastructure boundaries, consistent HTTP mapping, logging once at the edge, and preserving causes. They should avoid over-engineering while keeping call sites readable and failures observable.

    Red flag: They either catch all exceptions and return null or throw generic `RuntimeException` for all domain cases.

  3. 09You need to migrate a Java module to Kotlin incrementally. What problems do you expect and how would you manage them?

    Listen for: Expect discussion of platform types, nullability annotations, Java interop, Lombok, checked exceptions, static utilities, Gradle configuration, and mixed test coverage. A good answer proposes small slices, preserving public contracts, using ktlint or detekt gradually, and reviewing generated bytecode or API signatures when libraries are consumed by Java.

    Red flag: They suggest converting the whole module at once because Kotlin and Java interoperate perfectly.

  4. 10How would you decide between Spring Boot with Kotlin and Ktor for a new backend service?

    Listen for: A strong answer weighs team familiarity, ecosystem needs, startup/runtime constraints, dependency injection style, operational conventions, coroutine support, validation, security, observability, and integration with existing services. They should avoid framework tribalism and consider the cost of hiring, maintenance, deployment templates, and long-term support.

    Red flag: They pick one because it is more modern without tying it to requirements.

  5. 11A codebase uses many extension functions. Some make code elegant; others hide important behavior. How do you draw the line?

    Listen for: Listen for concrete heuristics: extensions are good for local readability, pure transformations, adapters, and domain vocabulary, but risky when they hide IO, transactions, security checks, or surprising side effects. Strong candidates mention discoverability, package placement, naming, testability, and whether a real type or collaborator would be clearer.

    Red flag: They treat extension functions as a way to monkey-patch any behavior onto any type.

  6. 12What would you look for when reviewing coroutine code that uses `launch`, `async`, and `Flow`?

    Listen for: A mid-level candidate should mention structured concurrency, cancellation propagation, exception handling, supervisor scopes only when justified, dispatcher choice, backpressure or buffering for `Flow`, and avoiding global scope. They should ask whether concurrent work is actually needed and whether tests use `kotlinx-coroutines-test` virtual time where appropriate.

    Red flag: They use `GlobalScope.launch` for request work or ignore cancellation because the operation usually finishes quickly.

  7. 13How would you introduce static analysis and formatting to an existing Kotlin repository without slowing the team down?

    Listen for: Good answers start with low-friction formatting using ktlint or Spotless, baseline detekt findings, CI gates for new or changed code, and documented rules. Listen for avoiding noisy custom rules at first, aligning IDE settings, fixing high-risk issues first, and making build output actionable for developers.

    Red flag: They enable every rule in CI immediately and expect the team to fix the entire backlog before merging features.

Senior Kotlin questions

Judgement, architecture and raising the team's bar.

  1. 14A Kotlin service has accumulated nullable fields, ambiguous DTOs, and business rules scattered across controllers, services, and repositories. How would you lead a redesign?

    Listen for: Listen for incremental domain modeling: identify bounded contexts, separate API DTOs from domain types, encode invariants with constructors or factories, use sealed types for state, and add characterization tests before refactoring. A senior answer includes migration strategy, compatibility, team buy-in, and avoiding a large rewrite with unclear payoff.

    Red flag: They propose a full rewrite into a pure architecture without explaining migration risk or business value.

  2. 15How do you reason about transactions in Kotlin code that mixes coroutines, Spring, and database access?

    Listen for: Strong candidates know transaction context, thread-local behavior, proxy boundaries, suspending functions, and blocking JDBC can interact badly. Listen for verifying framework support, keeping transactional work small, avoiding long external calls inside transactions, integration testing rollback behavior, and being explicit about dispatcher changes that may break assumptions.

    Red flag: They assume `@Transactional` works the same in every coroutine and dispatcher scenario without testing.

  3. 16You are asked to improve p95 latency in a Kotlin backend. What changes would you consider before rewriting hot paths?

    Listen for: Look for measurement-first thinking: traces, allocation profiling, database plans, client timeouts, serialization cost, connection pools, GC behavior on JDK 21, and lock contention. Strong answers consider algorithmic fixes, caching with invalidation, batching, payload trimming, and coroutine/thread tuning only after identifying bottlenecks.

    Red flag: They immediately suggest switching frameworks, adding coroutines, or rewriting in another language.

  4. 17How would you set standards for Kotlin code style and architecture across several teams?

    Listen for: A senior answer balances consistency and autonomy. Listen for shared Gradle convention plugins, version catalogs, ktlint/detekt baselines, examples of good module boundaries, code review guidelines, and decision records. They should involve teams, document exceptions, and keep standards tied to reliability and maintainability rather than personal preference.

    Red flag: They rely on authority or personal taste instead of lightweight standards and feedback loops.

  5. 18A team wants to adopt Kotlin Multiplatform to share domain logic between backend and mobile. How would you evaluate it?

    Listen for: Strong candidates assess whether shared code is truly platform-independent, library maturity, build complexity, testing on each target, serialization, time/date handling, networking abstractions, ownership, and release cadence. They should propose a thin pilot around stable domain logic, not wholesale sharing of UI or infrastructure concerns.

    Red flag: They treat Kotlin Multiplatform as an automatic way to cut development effort without discussing build and ownership costs.

  6. 19How would you handle a production incident caused by a coroutine leak or runaway background job?

    Listen for: Listen for immediate containment, disabling the job if possible, checking thread dumps, coroutine debug probes where enabled, logs, metrics, and deployment history. A senior answer includes root cause analysis around scope lifecycle, cancellation, retries, and backoff, then adds tests, ownership boundaries, dashboards, and runbooks to prevent recurrence.

    Red flag: They only restart the service and add more instances without investigating lifecycle or cancellation.

  7. 20What trade-offs do you consider when exposing Kotlin library APIs used by both Kotlin and Java consumers?

    Listen for: Good answers cover binary compatibility, nullability annotations, default parameters and `@JvmOverloads`, top-level functions, companion objects, checked exception expectations, collections mutability, value classes, and sealed types. They should discuss API evolution, semantic versioning, and testing usage from Java rather than assuming Kotlin idioms translate cleanly.

    Red flag: They design only for Kotlin callers and say Java interop can be fixed later.

System design Kotlin questions

Designing real systems end to end.

  1. 21Design a Kotlin service that ingests webhook events, validates them, deduplicates them, and updates customer state. Assume at-least-once delivery and occasional provider outages.

    Listen for: Look for idempotency keys, signature verification at the edge, durable event storage, transactional state changes, retry policy with backoff, dead-letter handling, and observability. Strong Kotlin-specific answers model event types with sealed interfaces, parse with kotlinx.serialization or Jackson Kotlin module carefully, and avoid blocking request threads unnecessarily.

    Red flag: They process the webhook entirely in memory and rely on the provider not sending duplicates.

  2. 22Design a coroutine-based Kotlin worker that calls several third-party APIs, combines results, and writes to Postgres. How do you control concurrency and failure behavior?

    Listen for: A strong design uses structured concurrency, bounded parallelism, explicit timeouts, cancellation, rate-limit handling, and isolation between providers. Listen for connection pool sizing, dispatcher choice for blocking clients, partial failure semantics, retries with jitter, idempotent database writes, and tests with fake clients plus `kotlinx-coroutines-test`.

    Red flag: They launch one coroutine per item with no bounds, deadlines, or cancellation strategy.

  3. 23Design the module structure for a Kotlin monolith that is growing into multiple business domains but is not ready for microservices.

    Listen for: Listen for a modular monolith: Gradle subprojects or clearly enforced packages, domain-owned APIs, dependency direction rules, separate persistence adapters, shared libraries kept small, and integration tests around module contracts. Strong answers avoid premature distribution while creating seams for future extraction if operationally justified.

    Red flag: They split into microservices mainly to make the codebase feel cleaner.

  4. 24Design an API layer in Kotlin that must support REST clients today and GraphQL clients next year without duplicating business logic.

    Listen for: Strong answers separate transport DTOs from application use cases, keep validation and authorization consistent, and map transport-specific errors cleanly. Listen for schema evolution, pagination, batching to avoid N+1 queries, serialization choices, and Kotlin models that do not leak framework annotations into core domain logic.

    Red flag: They put all business logic in controllers or resolvers and plan to copy it for the second API.

  5. 25Design observability for a Kotlin Spring Boot or Ktor service using coroutines and message processing.

    Listen for: Look for structured logs with correlation IDs, OpenTelemetry traces across suspending boundaries, metrics for queue lag, retries, external calls, database pools, and coroutine/thread saturation. Strong candidates include error budgets or SLO-style signals, dashboards, alert routing, and care not to log sensitive payloads.

    Red flag: They rely only on application logs and manual debugging after users report failures.

Practical task · 2–3 hours

Kotlin Order Status Aggregator

Build a small Kotlin service or command-line application that reads order IDs, fetches order details from a provided fake HTTP client, applies business rules, and returns a summary grouped by status and risk level. Include retries for transient failures, clear handling for missing orders, and unit tests. Use Kotlin 2.x, JDK 21, Gradle Kotlin DSL, and either coroutines or straightforward synchronous code with a short explanation of the choice. Candidates may use Spring Boot 3.x, Ktor 3.x, or no framework. The exercise should be completable in 2–3 hours and easy to run locally.

How to evaluate it

  • Clear domain modeling with null-safety and meaningful result/error types.
  • Readable, idiomatic Kotlin without cleverness that hides behavior.
  • Correct handling of retries, timeouts, missing data, and edge cases.
  • Focused tests that cover success, failure, and boundary scenarios.
  • Simple build/run instructions and reasonable dependency choices.

Rather skip the interview loop?

Every Octogle Kotlin engineer has already passed a technical assessment, system design and a live interview with an engineer who has shipped Kotlin. Send a brief and get 3–5 scored profiles in 48 hours.