L’entretien de code commence quand la solution passe les tests
Après une solution correcte, prolongez l’entretien de code par un exercice de maintenance concret : une modification, des tests de non-régression et une note de transmission.
Ernest Bursa
Une fois la solution validée par les tests, demandez au candidat d’effectuer une modification précise, de tester le nouveau comportement et le contrat existant, puis d’expliquer comment transmettre le travail. Les questions posées à ce stade révèlent sa manière de travailler sur une implémentation existante. Choisissez la modification en fonction des responsabilités du poste et évaluez chacun à partir des mêmes éléments.
La discussion sur Hacker News autour de Competitive Programmer’s Handbook remet l’entraînement aux algorithmes à l’ordre du jour. Le livre d’Antti Laaksonen est une version provisoire datée du 3 juillet 2018. Son introduction présente la programmation compétitive comme un travail de conception et d’implémentation d’algorithmes, dont les solutions sont testées pour vérifier leur correction. Elle précise aussi que les programmes de concours sont courts et n’exigent aucune maintenance ultérieure.
Cette dernière distinction fournit une bonne question d’entretien. Si vous recrutez pour maintenir un produit, que se passe-t-il lorsqu’une solution correcte doit évoluer ? Gardez le raisonnement algorithmique parmi les critères lorsque le poste l’exige. Puis observez le travail qui commence quand un autre ingénieur doit pouvoir compter sur ce code.
Que vous apprend une solution qui passe les tests ?
Une solution qui passe les tests montre que l’implémentation satisfait les cas vérifiés. Elle peut aussi servir de point de départ pour discuter de sa correction et de sa complexité. Ce sont des observations utiles, mais elles ne répondent pas à toutes les questions de maintenance.
Vous n’avez pas encore vu comment le candidat comprend un contrat qu’il n’a pas défini. Vous ignorez peut-être s’il sait distinguer une nouvelle exigence d’un changement involontaire de comportement. Une solution terminée vous apprend également peu de choses sur la note qu’il laisserait au prochain ingénieur.
Le manuel décrit clairement son propre cadre. Une épreuve de concours récompense une implémentation correcte qui respecte les contraintes données. Votre exercice de recrutement doit refléter les responsabilités que vous souhaitez confier. Ces deux objectifs peuvent coexister.
Pour un ingénieur travaillant sur un service de réservation, préserver la sémantique d’une API existante peut justifier un critère d’évaluation à part entière. Pour un poste consacré au développement d’algorithmes, la conception et l’analyse d’un algorithme peuvent rester centrales. Définissez ces objectifs avant de choisir l’exercice.
Cet article utilise un exemple fictif de réservation. Il propose un dossier d’exercice concret, sans prétendre fournir un outil d’évaluation validé. Rien ici ne démontre que cet exercice prédit la productivité, élimine les biais ou améliore les recrutements.
Pour une discussion plus générale des formats d’évaluation, consultez notre guide des entretiens de code à l’ère de l’IA. Ici, le périmètre est plus restreint : une fonction existante, une modification demandée, un test et une note de transmission.
Choisissez le travail de maintenance exigé par le poste
Partez d’une responsabilité que le nouvel ingénieur devra assumer dès son arrivée. Traduisez-la en une petite tâche observable, puis retirez de l’exercice les étapes de préparation sans rapport avec cette tâche.
Les recommandations sur l’analyse des postes de l’Office of Personnel Management américain (OPM) relient les tâches d’un poste aux compétences nécessaires pour les accomplir. En appliquant ce principe au logiciel, vous pourriez choisir la préservation d’un contrat d’API, l’évolution d’un modèle de données ou la documentation des conséquences d’un correctif. Ces exemples logiciels sont notre application de ces recommandations.
Pour ce dossier, l’objectif est de modifier un comportement tout en préservant un contrat documenté. Vous voulez vérifier si le candidat sait identifier les éléments concernés, réaliser la modification et protéger le comportement existant par des tests. Vous attendez aussi une explication lisible de ce qui a changé.
Cet objectif n’impose ni de configurer votre environnement de production ni de découvrir une règle métier non documentée. Fournissez une commande de test fonctionnelle, un petit dépôt et les règles pertinentes. Si l’installation échoue, résolvez le problème avant d’évaluer le correctif.
Les recommandations de l’OPM sur les échantillons de travail décrivent des tâches proches du travail réalisé dans le poste. Elles déconseillent également d’évaluer des compétences que vous comptez enseigner après le recrutement. Si le poste prévoit l’apprentissage de votre framework après l’arrivée, n’en faites pas implicitement le critère décisif.
Rendez le périmètre explicite pour le candidat. Indiquez les fichiers concernés, les livrables attendus et les modalités d’évaluation. Précisez si la documentation, la recherche et l’assistance par IA sont autorisées. Notre guide de conception des échantillons de travail aborde ces choix de format plus généraux.
Donnez à chaque candidat la même implémentation fonctionnelle
Fournissez l’implémentation et ses tests à tous les candidats. La tâche de maintenance doit partir d’une base commune : son évaluation ne doit pas dépendre de la résolution préalable d’un problème d’algorithmique.
Le dossier fictif porte sur un service de réservation qui stocke des intervalles de temps sous forme de nombres entiers. La fonction indique si toutes les réservations peuvent occuper la même salle sans se chevaucher. La version de départ ci-dessous utilise uniquement la bibliothèque standard de Python ; le langage sert d’exemple et ne constitue pas une exigence de l’évaluation.
Contrat existant
Placez ces règles dans le README, à côté de la fonction :
- Chaque élément possède des valeurs
startetend, avecstart < end. - Les intervalles sont semi-ouverts : une réservation qui se termine à
20peut partager la salle avec une réservation qui commence à20. - Les éléments peuvent arriver dans n’importe quel ordre.
- La fonction renvoie un booléen et conserve l’ordre initial de la liste d’entrée.
- Les intervalles invalides sortent du cadre de cet exercice. Vous pouvez supposer que la précondition fournie est respectée.
Ces règles évitent au candidat de devoir deviner les réponses. En particulier, les réservations contiguës sont autorisées et le tri ne doit pas modifier la liste de l’appelant.
Solution fournie et tests de départ
# bookings.py
def can_share_room(bookings):
ordered = sorted(bookings, key=lambda booking: booking["start"])
return all(
previous["end"] <= current["start"]
for previous, current in zip(ordered, ordered[1:])
)
# test_bookings.py
import unittest
from bookings import can_share_room
class BookingTests(unittest.TestCase):
def test_empty_and_single_booking(self):
self.assertTrue(can_share_room([]))
self.assertTrue(can_share_room([{"start": 10, "end": 20}]))
def test_adjacent_bookings_can_share(self):
self.assertTrue(can_share_room([
{"start": 10, "end": 20},
{"start": 20, "end": 30},
]))
def test_overlapping_bookings_cannot_share(self):
self.assertFalse(can_share_room([
{"start": 10, "end": 20},
{"start": 15, "end": 25},
]))
def test_unsorted_input_keeps_its_order(self):
bookings = [
{"start": 20, "end": 30},
{"start": 10, "end": 20},
]
original = [booking.copy() for booking in bookings]
self.assertTrue(can_share_room(bookings))
self.assertEqual(original, bookings)
if __name__ == "__main__":
unittest.main()
Le README fournit une seule commande : python -m unittest. Exécutez-la vous-même avant de transmettre le dépôt. Le candidat doit trouver une version de départ dont les tests passent, sans téléchargement de dépendances ni identifiants cachés.
Demandez-lui pourquoi le tri permet de vérifier les chevauchements entre paires voisines. Si un intervalle ultérieur chevauche un intervalle antérieur, il existe nécessairement un chevauchement entre deux voisins dans la séquence triée. Vous pouvez aussi discuter du coût du tri et de l’allocation d’une liste supplémentaire si ces notions comptent pour le poste.
Consignez cette discussion algorithmique séparément des observations sur la maintenance. Un candidat peut expliquer clairement l’algorithme et manquer une question de compatibilité. Un autre peut préserver soigneusement le contrat tout en ayant besoin d’aide pour expliquer la complexité. Des critères distincts rendent l’évaluation plus précise.
Demandez une modification et les tests qui la protègent
Formulez une demande précise : les réservations annulées doivent cesser d’occuper la salle, tandis que les anciens éléments conservent leur signification. Demandez un correctif ciblé et des tests qui distinguent le comportement modifié de celui qui doit rester intact.
Utilisez cette demande telle quelle dans le README fictif :
Les éléments peuvent désormais contenir un champ booléen
cancelled. Un élément aveccancelled: Truen’occupe pas la salle. Un champ absent ou la valeurcancelled: Falsesignifie que la réservation l’occupe toujours. Préservez les règles existantes sur les intervalles et l’ordre des éléments en entrée. Supposez que les valeurs d’annulation fournies sont des booléens. Ajoutez des tests et une courte note de transmission.
Cela limite la tâche à un seul changement de comportement. Le candidat n’a pas à inventer des droits d’annulation, une analyse de dates, un mécanisme de stockage ou un nouveau format de réponse. S’il relève ces questions, la note de transmission permet de les mentionner.
Une implémentation ciblée
Un correctif acceptable consiste à filtrer avant de trier :
def can_share_room(bookings):
active = [
booking for booking in bookings
if not booking.get("cancelled", False)
]
ordered = sorted(active, key=lambda booking: booking["start"])
return all(
previous["end"] <= current["start"]
for previous, current in zip(ordered, ordered[1:])
)
La valeur par défaut en l’absence du champ préserve les anciens éléments. Le filtrage ne modifie pas la liste de l’appelant. La vérification des chevauchements garde sa signification initiale puisqu’elle ne reçoit désormais que les éléments qui occupent la salle.
Cette réponse sert d’exemple pour préparer l’exercice. Ne l’incluez pas dans le dossier remis au candidat. Acceptez les autres implémentations qui respectent le contrat ; vos préférences de nommage ou de mise en forme ne doivent pas devenir des exigences implicites.
Des tests qui démontrent la modification
Ajoutez ces méthodes à la classe de test fournie :
def test_cancelled_overlap_does_not_block_room(self):
self.assertTrue(can_share_room([
{"start": 10, "end": 20},
{"start": 15, "end": 25, "cancelled": True},
]))
def test_explicit_false_still_blocks_room(self):
self.assertFalse(can_share_room([
{"start": 10, "end": 20},
{"start": 15, "end": 25, "cancelled": False},
]))
def test_all_cancelled_bookings_leave_room_available(self):
self.assertTrue(can_share_room([
{"start": 10, "end": 20, "cancelled": True},
{"start": 15, "end": 25, "cancelled": True},
]))
Le premier nouveau test échoue avec l’implémentation fournie. C’est une preuve utile : le test vérifie bien la modification demandée. Le deuxième protège les éléments explicitement actifs, tandis que le test initial de chevauchement protège ceux qui ne possèdent pas de champ d’annulation.
Les tests initiaux sur les intervalles contigus et l’ordre des éléments restent nécessaires. Ils couvrent des parties du contrat que la demande n’a pas modifiées. Demandez au candidat de montrer quelles assertions établissent la nouvelle règle et lesquelles préservent les règles existantes.
Vous pouvez discuter de l’ajout d’un test confirmant que les éléments annulés restent eux aussi dans la liste de l’appelant. Il rendrait explicite la règle de préservation des entrées pour cette nouvelle forme de données. Consignez l’absence éventuelle de ce test comme une lacune précise de couverture, puis vérifiez si l’implémentation enfreint réellement la règle.
Ne récompensez pas le nombre de tests à lui seul. Plusieurs tests répétant le même scénario peuvent masquer un cas limite manquant. Examinez le lien entre chaque assertion et le contrat annoncé.
Évaluez la transmission avec des questions communes
Demandez à chaque candidat d’expliquer la modification à partir des mêmes questions principales. Les évaluateurs doivent consigner les éléments tirés du code et des tests avant de discuter de la décision globale.
Les recommandations de l’OPM sur les entretiens structurés décrivent des questions prédéfinies, posées dans un ordre commun, ainsi que des critères de notation partagés. Appliquer ces principes à une discussion sur le code est une recommandation pratique. Cela ne fait pas de cet exercice une évaluation certifiée par l’OPM et ne démontre pas sa validité prédictive.
Une note de transmission utile
Une note pourrait prendre cette forme :
Les réservations annulées sont exclues avant le tri. En l’absence du champ d’annulation, les réservations restent actives : les anciens éléments conservent donc leur comportement. Les tests existants sur les intervalles contigus et l’ordre d’entrée passent toujours. Le nouveau test de chevauchement avec annulation échoue sur la fonction initiale. Les valeurs d’annulation en entrée sont supposées être des booléens ; la validation des données importées reste hors du périmètre de ce correctif.
Cette note indique au prochain ingénieur ce qui a changé, ce qui reste stable et où s’arrête l’hypothèse. Elle n’exige ni une longue dissertation ni le récit de chaque modification.
Posez les trois mêmes questions principales :
- Quel comportement existant avez-vous protégé, et quels éléments le démontrent ?
- Quel test échouerait sans votre modification ?
- Que doit savoir le prochain ingénieur avant de modifier à nouveau cette fonction ?
Un évaluateur peut demander des précisions sur le travail remis. Consignez aussi ces questions, surtout lorsqu’elles ont apporté une information qu’un autre candidat avait reçue dans l’énoncé initial. Améliorez le dossier lorsque des questions récurrentes révèlent une ambiguïté.
Une grille d’évaluation commune
Utilisez une grille dont les éléments de preuve attendus ont été définis avant le début des entretiens :
| Critère | Éléments à consigner | Point à examiner |
|---|---|---|
| Compréhension du contrat | Identifie comme actifs les éléments dont le champ d’annulation est absent ou vaut false | Écarte les anciens éléments ou modifie les règles sur les intervalles contigus |
| Correction de la modification | Les éléments annulés n’affectent pas la disponibilité | Laisse les chevauchements annulés dans la comparaison |
| Protection contre les régressions | Relie les assertions aux comportements nouveaux et existants | Présente des tests qui passent sans expliquer ce qu’ils couvrent |
| Transmission | Précise la modification, le comportement préservé et l’hypothèse sur les entrées | Laisse le prochain responsable de la maintenance deviner le contrat |
Ce sont des repères proposés pour cet exercice. Adaptez-les aux responsabilités identifiées et décidez de leur poids dans la décision de recrutement avant de voir les travaux remis. Ne les présentez pas comme des seuils de notation validés par la recherche.
Testez le dossier avec des collègues qui connaissent le poste. Demandez-leur où ils ont eu besoin de précisions et si le travail demandé correspond à une compétence exigée dès l’arrivée. L’OPM souligne que les échantillons de travail demandent des efforts de conception et d’administration ; prévoyez du temps pour cette préparation et cette évaluation.
Pour un poste senior dont la tâche centrale est d’évaluer une proposition de conception, choisissez un autre exercice. Notre guide des entretiens de revue de conception pour ingénieurs seniors aborde cette responsabilité. Ce petit correctif ne peut pas représenter toutes les formes de jugement en ingénierie.
Organisez l’exercice dans Kit
Préparez vous-même l’exercice et les critères d’évaluation, puis utilisez Kit pour organiser l’exercice de code dans le pipeline de recrutement. GitHub héberge l’implémentation, les tests et la revue de code ; les évaluateurs humains interprètent les éléments recueillis.
Les exercices de code de Kit utilisent des dépôts privés créés à partir d’un dépôt modèle de l’employeur. Les candidats connectent GitHub pour réaliser l’exercice. Après la remise du travail, les évaluateurs ayant connecté leur compte GitHub peuvent recevoir une invitation au dépôt et y examiner le code et son historique.
Placez le README, les tests de départ et les livrables attendus dans votre modèle. Si vous souhaitez une pull request, demandez-la dans ces instructions. Kit n’en crée pas automatiquement et ne note pas l’implémentation. Définissez en parallèle les critères que l’équipe utilisera pour l’évaluation.
Fixez une date limite de remise adaptée au processus et expliquez séparément l’effort attendu. Une échéance n’est pas un chronomètre mesurant les heures réellement consacrées au code. Ne considérez pas son expiration comme une preuve que le dépôt est figé. Notre guide de configuration des exercices de code décrit le processus plus général, notamment les échéances et l’évaluation.
Une solution correcte est un bon point de départ. Pour un poste de maintenance, prolongez-la par une modification claire, des tests qui protègent le contrat et une note de transmission utilisable par un autre ingénieur. Commencez par tester ce dossier sur une responsabilité réelle de votre équipe, puis révisez les instructions avant de le donner aux candidats.
Articles similaires
Essayez Kit pendant 30 jours.
Le recrutement, les rapports de sécurité et la formation dans un seul compte, pour les équipes où rien de tout cela n'est un poste à plein temps. 30 jours d'essai gratuit, carte bancaire demandée. Résiliez avant la fin et vous ne payez rien.
Essayez gratuitement