Ce qu'un développeur Kotlin back-end doit savoir des coroutines et de JPA

Un développeur Kotlin back-end écrit des services sur la JVM, le plus souvent avec Spring Boot, parfois avec Ktor. Le langage tourne sur la même machine que Java, mais la null-safety, les coroutines et les classes scellées changent la façon d'écrire le code et de le tester.

Recevoir la fiche complète

Mis à jour le Par l'équipe Delectus5 min de lecture

La fiche Développeur Kotlin back-end : technologies, chaîne du poste, une question et la grille d'évaluation

Les offres Kotlin back-end portent rarement ce titre. Le langage apparaît le plus souvent dans une annonce de développeur Java, à côté de Spring Boot, et la personne recrutée travaille sur un code qui mélange les deux langages. Elle écrit des API REST, consomme des messages Kafka, accède à PostgreSQL avec Spring Data ou Exposed et utilise les coroutines pour les appels concurrents. Ktor se rencontre sur des services plus légers.

Un développeur Java qui a lu la documentation Kotlin écrit souvent du Java avec une autre syntaxe : des !! partout, des lateinit pour contourner l'initialisation, un runBlocking dans un contrôleur. L'expérience réelle se voit ailleurs. La personne sait où passent les types venus de Java, pourquoi une entité JPA ne doit pas être une data class, ce que fait l'annulation d'une coroutine et comment tester du code suspendu sans attendre de vrais délais.

Regardez aussi les versions. Spring Boot 4 demande au minimum Kotlin 2.2 et annote ses API avec JSpecify, ce qui supprime une bonne partie des types incertains côté Spring. Un profil qui a migré un projet vers le compilateur K2 ou vers Spring Boot 4 a des problèmes précis à raconter. Le PDF compte 30 questions sur six axes, un cas de 20 minutes et une grille.

Le langage et les outils d'un poste Kotlin côté serveur

Kotlin et la null-safety

Le langage lui-même. Le compilateur distingue un type qui peut être nul (String?) d'un type qui ne peut pas l'être, ce qui élimine une grande partie des NullPointerException. Les valeurs qui viennent du code Java échappent à cette vérification tant qu'elles ne sont pas annotées. Depuis Kotlin 2.0, le compilateur K2 est utilisé par défaut.

Data classes, classes scellées et extensions

Les data classes servent aux objets de transfert. Les classes et interfaces scellées décrivent un ensemble fermé de cas, par exemple une réponse réussie ou une erreur typée. Les fonctions d'extension ajoutent des méthodes à un type existant. Bien utilisées, elles remplacent beaucoup d'héritage et de code défensif.

Coroutines et Flow

La bibliothèque de concurrence de Kotlin (kotlinx.coroutines). Une fonction suspend libère le thread pendant qu'elle attend une réponse réseau, et un scope regroupe les tâches lancées pour pouvoir les annuler ensemble. Flow transporte une suite de valeurs produites au fil du temps. C'est le sujet qui sépare le plus nettement les profils.

Spring Boot en Kotlin

Le framework le plus courant pour un back-end Kotlin. Spring accepte les fonctions suspend dans les contrôleurs et propose des DSL Kotlin pour les routes, les beans et la sécurité. Spring Boot 4 et Spring Framework 7 exigent Kotlin 2.2 et exposent des API annotées avec JSpecify, que Kotlin lit comme nullables ou non.

Ktor

Le framework web de JetBrains, écrit en Kotlin et construit sur les coroutines. Plus léger que Spring, il laisse choisir chaque brique : sérialisation, authentification, injection de dépendances (Koin ou à la main). On le trouve sur des microservices et des API où l'équipe veut garder la main sur le démarrage.

Persistance : JPA, Spring Data JDBC, Exposed

Les entités JPA demandent des précautions en Kotlin, car Hibernate attend des classes ouvertes avec un constructeur sans argument, d'où les plugins de compilation all-open et no-arg. Spring Data JDBC et Exposed, la bibliothèque SQL de JetBrains, s'accordent mieux avec des classes immuables. Demandez lequel la personne a utilisé et pourquoi.

Gradle Kotlin DSL

Le build est presque toujours en Gradle avec des scripts .kts, plus rarement en Maven. Le plugin Kotlin, les plugins de compilation pour Spring et JPA et le catalogue de versions (libs.versions.toml) se configurent là. Un profil confirmé sait lire une erreur de build causée par un plugin mal déclaré.

Tests : JUnit 5, Kotest, MockK

JUnit 5 reste courant, Kotest propose des styles de tests plus proches du langage. MockK remplace Mockito, qui gère mal les classes finales et les fonctions suspend. kotlinx-coroutines-test fournit runTest et un temps virtuel pour tester sans vrais délais.

Le poste dépend surtout de l'état du code. Sur un projet démarré en Kotlin, la personne pose les conventions : modèle d'erreurs, usage des coroutines, choix entre JPA et une bibliothèque plus légère. Sur un projet Java qui passe progressivement à Kotlin, elle écrit les nouveaux modules en Kotlin à côté de classes Java qui ne seront pas réécrites, et l'interopérabilité devient le sujet principal. Les deux situations demandent la même base JVM, avec Spring, la base de données, Kafka et les conteneurs. Une relecture commentée d'un fichier Kotlin existant montre vite si la personne écrit du Kotlin ou du Java déguisé.

Les points techniques à vérifier chez un développeur Kotlin

  • Null-safety et modélisation des types
  • Coroutines, annulation et Flow
  • Spring Boot et Ktor en Kotlin
  • Interopérabilité Java et persistance
  • Tests du code suspendu
  • Build Gradle et production JVM

Questions techniques pour un développeur Kotlin back-end

Chaque question vient avec ce qu'une bonne réponse contient et le signal qui doit vous alerter. Pas besoin d'être technique pour les poser : écoutez si le candidat raconte du vécu.

  1. Question 1 · confirmé

    Une méthode Java renvoie un String que vous utilisez dans du code Kotlin. Que garantit le compilateur, et comment évitez-vous un NullPointerException ?

    Une bonne réponseRien. C'est un type de plateforme (String!), que Kotlin laisse utiliser comme nullable ou non. La personne le déclare explicitement en String? à la frontière et traite le cas nul, ou s'appuie sur des annotations de nullabilité côté Java (JSpecify, JetBrains, Jakarta) que le compilateur lit. Elle cite les API de Spring Framework 7, annotées avec JSpecify, qui réduisent beaucoup ce problème.

    Signal d'alerte« Kotlin empêche les NullPointerException », sans exception. Ou un !! ajouté pour faire compiler.

  2. Question 2 · confirmé

    Un endpoint appelle trois services externes l'un après l'autre et répond en 900 ms. Comment le réécrivez-vous avec des coroutines, et que se passe-t-il si l'un des appels échoue ?

    Une bonne réponseTrois async dans un coroutineScope, puis awaitAll. Le temps de réponse tombe à celui de l'appel le plus lent. Avec la concurrence structurée, un échec annule les deux autres appels et l'exception remonte au scope. Si un appel est facultatif, un supervisorScope ou un try/catch autour de son await, avec une valeur par défaut. La personne ajoute un withTimeout et vérifie que le client HTTP est non bloquant, sinon elle passe l'appel sur Dispatchers.IO.

    Signal d'alerteGlobalScope.launch pour paralléliser, ou runBlocking dans le contrôleur. Aucune idée de ce que deviennent les autres appels quand l'un échoue.

  3. Question 3 · confirmé

    Vous écrivez une entité JPA en Kotlin. Pourquoi une data class pose-t-elle problème, et comment déclarez-vous l'entité ?

    Une bonne réponseHibernate a besoin d'une classe ouverte pour créer ses proxys de chargement paresseux et d'un constructeur sans argument, ce que font les plugins kotlin-spring (all-open) et kotlin-jpa (no-arg). Une data class génère equals, hashCode et toString sur toutes les propriétés, ce qui déclenche le chargement des relations paresseuses et casse l'égalité quand l'identifiant est généré à l'insertion. D'où une classe simple, avec equals et hashCode sur l'identifiant ou une clé métier, et des var limitées à ce qui change.

    Signal d'alerteUne data class avec des val partout « parce que c'est plus idiomatique », sans savoir pourquoi Hibernate ne peut pas créer de proxy.

  4. Question 4 · junior à confirmé

    Comment modélisez-vous le résultat d'un paiement qui peut réussir, être refusé ou rester en attente ?

    Une bonne réponseUne sealed interface avec un sous-type par cas (data class ou data object), chacun portant ses propres données. Côté appelant, un when exhaustif sans branche else, pour que le compilateur signale le cas oublié le jour où un quatrième état apparaît. La personne explique la différence avec un enum, qui ne porte pas de données différentes selon le cas.

    Signal d'alerteUne exception par motif de refus, ou un statut en String comparé à la main.

  5. Question 5 · confirmé

    Comment testez-vous une fonction suspend qui réessaie un appel trois fois, avec 2 secondes d'attente entre chaque tentative ?

    Une bonne réponseAvec runTest de kotlinx-coroutines-test. Le temps y est virtuel, les delay sont sautés et le test dure quelques millisecondes. Le client est simulé avec MockK (coEvery, coVerify) pour échouer deux fois puis réussir, et le test vérifie le nombre d'appels et le temps virtuel écoulé. Les dispatchers sont injectés pour pouvoir les remplacer dans le test.

    Signal d'alerteUn Thread.sleep ou un vrai délai dans le test, ou Mockito utilisé tel quel sur une fonction suspend.

Recevez la fiche d'entretien complète en PDF

La fiche pour mener l'entretien de bout en bout, prête à imprimer ou à partager avec le manager.

  • 30 questions sur 6 axes, avec la bonne réponse, le signal d'alerte et la relance
  • Le niveau visé pour chaque question
  • Une mise en situation de 20 minutes et ce qu'on attend du candidat
  • La grille d'évaluation de 1 à 4, axe par axe

Recruter en Kotlin back-end, les questions courantes

Un développeur Java peut-il tenir un poste Kotlin back-end ?

Oui, s'il a déjà écrit du Kotlin en production ou si l'équipe peut l'accompagner quelques semaines. Spring, la JVM, la base de données et Kafka restent les mêmes. Ce qui change, ce sont la null-safety, les coroutines et une modélisation avec des classes scellées et immuables. En entretien, faites-lui relire un fichier Kotlin écrit comme du Java, avec des !!, des lateinit et un runBlocking. Un profil prêt repère seul ce qui ne va pas.

Faut-il exiger les coroutines pour un développeur Kotlin back-end ?

Sur un service qui fait beaucoup d'appels réseau, ou qui tourne sur WebFlux ou Ktor, oui. Sur un service Spring MVC classique avec JPA, les coroutines servent moins, et les virtual threads de Java 21 couvrent une partie du même besoin. Demandez dans tous les cas la différence entre launch et async et ce que devient une coroutine annulée. Un profil confirmé doit savoir répondre même s'il les utilise peu.

Quel exercice proposer en test technique Kotlin ?

Un service court à relire et à corriger fonctionne mieux qu'un algorithme. Donnez une classe qui enchaîne trois appels bloquants, avec des !!, un GlobalScope et une entité JPA en data class, et demandez ce qui posera problème en production. En 30 minutes, vous voyez la maîtrise du langage, des coroutines et de la persistance. Faites commenter à voix haute pour suivre le raisonnement.

Comment comparer plusieurs candidats Kotlin entre eux ?

Posez les mêmes questions et notez avec une grille commune par axe : langage, coroutines, frameworks, interopérabilité et persistance, tests, build et production. Chaque axe se note de 1 à 4, avec des niveaux décrits à l'avance pour que deux recruteurs notent de la même façon. La grille Delectus AI du PDF suit ce découpage et ajoute un cas de 20 minutes sur un service de réservation à moderniser.

Pour structurer vos autres entretiens, consultez aussi nos pages sur les questions d'entretien de recrutement, la méthode de l'entretien structuré et la grille d'évaluation d'entretien.

Les fiches voisines

Toutes les fiches →

Voyez Delectus sur vos propres offres.

Commencez gratuitement. Passez à l'échelle quand vous êtes prêt.

Demander une démo

Votre ATS, connecté à Delectus

  • Workable
  • Teamtailor
  • iCIMS
  • Lever
  • SmartRecruiters
  • Jobvite
  • Greenhouse
  • Pinpoint