- Mieux utiliser Django pour supprimer du code antédiluvien
- Fichiers gargantuesques et duplications de tests
Ces derniers temps, je suis très impliqué dans le recrutement de l’un de mes futurs collègues.
Ce faisant, j’ai été amené à beaucoup réfléchir à la question, en essayant notamment de tirer parti de ma propre expérience et de mes diverses lectures, mais aussi de l’expertise de mon épouse qui est psychologue du travail.
En constatant à quel point mes propres idées et pratiques sont différentes de ce que l’on voit habituellement, il m’est venu l’idée de rédiger ce billet, afin de coucher sur le papier un tableau d’ensemble de mon point de vue, en décrivant notamment ce qui ne va pas, selon moi, dans ce domaine, et comment j’essaye d’y remédier.
- Avez-vous déjà vu... un mouton à cinq pattes ?
- Avez-vous déjà vu... un candidat fondre en larmes ?
- Avez-vous déjà vu... une recrue se sauver dès le premier jour ?
Avez-vous déjà vu... un mouton à cinq pattes ?
Moi, non, mais ça n’empêche pas les recruteurs de s’obstiner à le chercher.
Si vous êtes vous-même dans le développement, je suis sûr que vous hochez déjà la tête en pensant par exemple au créateur de FastAPI
, qui s’est fait recaler par un recruteur parce qu’il n’avait pas assez d’années d’expérience sur sa propre techno… Oui, certes, c’est arrivé pour de vrai, c’est totalement ridicule et signe que certains recruteurs sont complètement à côté de la plaque, mais vous, si vous deviez rédiger une fiche de poste pour recruter quelqu’un dans votre équipe, là, tout de suite, comment vous en sortiriez-vous ?
Avez-vous la certitude que vous ne lanceriez pas vous-même une meute de chasseurs de têtes sur la piste du mouton à cinq pattes ?
Est-ce que vous vous assureriez vraiment que le profil que vous recherchez correspond :
- à ce dont votre équipe a réellement besoin ?
- à un être humain qui vit actuellement sur notre planète ?
- … et qui a un quelconque intérêt à venir travailler avec vous ?
Vous êtes toujours en train de hocher la tête… n’est-ce pas ? Et pourtant, vous aussi, vous galérez à trouver "de bons profils" en recrutement, je me trompe ?
Alors, mettons-nous en situation. Imaginons que nous soyons une équipe qui travaille sur un projet, disons un ETL en Python, et que nous désirions grandir en recrutant une cinquième personne. N’auriez-vous pas le réflexe de chercher quelqu’un :
- Qui ait déjà N années d’expérience en Python sur des projets d’ETL,
- Qui connaisse déjà votre secteur d’activité,
- (BONUS) Qui connaisse déjà un peu le framework sur lequel vous êtes en train de migrer ?
Ça semble couler de source, a priori…
Maintenant, imaginez quelqu’un qui correspond pile à ce profil. C’est-à-dire une personne qui occupe déjà le même poste que celui pour lequel vous recrutez, mais dans une autre société du même secteur (où les salaires sont donc grosso-modo les mêmes). Quelles sont les chances, d’après vous, qu’elle ait envie de quitter son entreprise actuelle pour venir faire exactement la même chose chez vous ?
Et si c’est le cas, pourquoi veut-elle changer de boîte ? Est-ce que c’est vraiment bon signe ?
« On ne recrute pas un profil, on recrute un potentiel »
Elle est très belle, cette phrase, vous ne trouvez pas ? À l’image de l’inspecteur Columbo, je la tiens de ma femme, et je ne manque jamais une occasion de la citer…
Voyons un peu l’éclairage qu’elle apporte à notre exemple. Une personne qui travaille déjà sur le poste pour lequel vous recrutez représente un potentiel nul ou presque :
- Puisqu’elle fait déjà la même chose que vous depuis des années, il y a fort à parier qu’elle n’aura pas grand chose de frais à injecter dans votre équipe.
- Si cette personne est compétente, alors elle a sûrement déjà fait le tour de son poste et cherchera plutôt un challenge, une opportunité de grandir que vous ne pouvez pas lui offrir.
- Si malgré cela elle veut bien s’en aller pour postuler chez vous, alors c’est parce que ça ne se passe pas comme elle le voudrait dans sa structure actuelle, et donc vous feriez bien de hausser un sourcil et creuser la question.
Demandez-vous ce que vous cherchiez, vous, lorsque l’on vous a recruté dans cette équipe… Sûrement un meilleur salaire, mais probablement aussi des choses que vous désiriez acquérir (compétences ou expérience) pour les rajouter dans votre CV, non ?
Peut-être devrions-nous revoir notre profil recherché, en essayant cette fois de capitaliser sur l’avenir :
- En laissant tomber la "connaissance du secteur d’activité", vous ouvrez votre recherche à des profils qui viennent d’autres horizons que vous, mais qui sont intéressées par votre secteur, avec peut-être une culture ou des pratiques distinctes des vôtres, que vous avez peut-être intérêt à découvrir pour vous les approprier ?
- En laissant tomber les "N années d’expérience en Python sur des ETL", ne croyez surtout pas que vous allez seulement ouvrir les vannes à une masse de gens inexpérimentés : vous allez les ouvrir, certes, mais surtout à des gens qui ont des années d’XP sur des ETL en Java et qui s’intéressent à Python, ou à des gens qui ont des années de Web en Python et qui désirent voir autre chose, et qui ont non seulement quelque chose à apprendre chez vous, mais surtout, là encore, certainement des choses à vous transmettre de par leur expérience distincte de la vôtre.
- Vous ouvririez également les vannes sur des profils plus "juniors", qui sont traditionnellement hyper motivés avec un regard frais, qui pourraient certainement monter en compétences en un rien de temps (depuis quand c’est devenu difficile d’apprendre Python pour un dev motivé ?), et vous aideraient ce faisant à questionner vos pratiques, ce qui est le premier pas pour les améliorer…
Desserrer le robinet, c’est simplement vous demander ce qui peut être acquis "sur le tas" par quelqu’un de motivé, et le rendre optionnel. Autrement dit :
Si vous avez vraiment besoin d’un mouton à cinq pattes :
- Cherchez ceux qui en ont au moins trois,
- Choisissez-en un qui en a quatre,
- Puis aidez-le à faire pousser la cinquième.
Certes, ne nous leurrons pas, cela va aussi vous demander plus d’efforts pour filtrer les bons profils, et de vous montrer particulièrement sélectifs sur les CV et lettres de motivation. Mais c’est le prix à payer : pour avoir plus de bon grain, il faut se préparer à écarter plus d’ivraie. Il n’y a pas de formule magique.
Cette approche vous ouvrira à d'excellents collaborateurs potentiels, tous plus intéressants et enrichissants pour votre équipe les uns que les autres, en leur donnant la possibilité trouver chez vous quelque chose dont ils ont envie, pas seulement une occasion de fuir leur poste actuel.
Avez-vous déjà vu... un candidat fondre en larmes ?
Moi, oui, et ce souvenir me hante depuis des années.
« Tu connais la suite de Fibonacci ? Tu pourrais écrire une fonction qui retourne son N-ième terme ? »
Nous étions deux, mon manager et moi, assis à la grande table de la salle de réunion. En face de nous, un jeune candidat fraîchement diplômé se tenait debout devant le tableau blanc. Je l’avais eu la veille au téléphone, il avait déjà construit des projets intéressants en Python, était même capable de m’expliquer le fonctionnement du GIL, connaissait Linux et le shell comme sa poche, il m’avait montré une belle motivation, s’exprimait de façon fine et claire… toutes les étoiles étaient alignées. Je m’attendais à ce que ça passe crème à l’entretien technique.
Il acquiesce timidement, se retourne et écrit au marqueur bleu :
def fib(n):
a, b = 0, 1
for i in range(
Une petite ampoule verte s’allume dans ma tête : c’est bon, il le résout en O(N). Je commence à chercher ce que je vais lui donner à faire ensuite… Ah oui, tiens, le problème de graphes qu’on m’avait filé chez RandomScaleUp, il est pas mal celui-là…
Mais le marqueur s’arrête.
Je le vois compter sur ses doigts. Je me dis qu’il est juste en train d’anticiper un off-by-one. Mais c’est tout son corps qui se fige. Il ne prononce plus un mot, ne se retourne même pas pour nous demander de l’aide : il est en panique.
Au bout de quelques minutes, je décide de l’aider à remonter en selle avec un exercice très facile : « Hé, c’est pas grave, tout va bien. Détends-toi, on va essayer autre chose. Tu pourrais nous faire un FizzBuzz ? »
Il efface les trois lignes mais n’écrit rien. Je remarque au mouvement de ses épaules qu’il est en train de sangloter…
Nous nous sommes regardés d’un air incrédule avec mon manager, nous avions mal pour lui, alors nous avons mis fin à son calvaire. Il ne nous a même pas jeté un regard ni prononcé une parole. Il est parti tête baissée, honteux et en larmes, presque en courant.
J’étais sonné. Qu’est-ce qui venait de se passer ? Il avait un profil génial, pile ce que je recherchais, je savais exactement ce que je pourrais lui apprendre. Cet exo était un jeu d’enfant pour lui, il avait la bonne réponse… Il avait la bonne réponse, bon sang !
En y repensant aujourd’hui, je me frappe encore le front.
Mais qu’est-ce qui m’avait pris de le soumettre à un exercice aussi irrémédiablement débile, aussi déconnecté de la réalité, aussi profondément stressant et humiliant que d’écrire du code au tableau, sous les yeux de deux inconnus qui sont en train de scanner ses moindres faits et gestes ? On est où, là ? Au travail ou dans un lycée de prépa ? Qu’est-ce que j’espérais, au juste ?
Oui, les développeurs compétents peuvent avoir du mal avec les interactions directes, particulièrement en début de carrière, devant des inconnus, dans un contexte où ils ont la pression, surtout quand on leur en ajoute gratuitement. Et dans ce cas c’est affreux parce qu’ils sont pourtant compétents pour le poste, et tout à fait capables de réfléchir à plusieurs à voix haute en réunion, pour peu qu’on leur laisse prendre leurs marques à leur rythme.
Et moi, est-ce que j’avais vraiment besoin de recruter quelqu’un qui sache calculer le N-ième terme de la suite de Fibonacci avec une complexité algorithmique acceptable, et surtout qui sache écrire du code manuellement, au tableau, sans ses outils habituels ? À quoi ça allait lui servir, une fois embauché ? Qu’est-ce que ça m’apprendrait d’utile sur lui ?
Rien, évidemment, mais je faisais comme les autres : la danse de la pluie autour d’un totem à l’effigie du mouton à cinq pattes.
Que faire à la place ?
Cette mésaventure a été pour moi un déclic. Depuis, je me suis juré de tester uniquement ce que j’ai besoin de savoir, en m’affranchissant des innombrables biais dûs au format des entretiens d’embauche, et sans mettre inutilement les candidats dans une situation de stress injustifiée. Et je dois avouer que le COVID-19, ainsi que la popularisation du télétravail, m’y ont plutôt aidé.
Aujourd’hui, sans prétendre être arrivé à la solution idéale, je sais au moins ce que je fais et pourquoi je le fais comme ça.
Pour ce faire, j’ai adopté un processus qui peut certes sembler lourd, mais qui me permet de savoir si oui ou non j’ai envie de travailler avec eux, tout en ayant une idée précise de ce à quoi m’attendre.
D’abord, j’effectue un premier call, préférablement en visio, avec la personne. Cet entretien prend la forme d’une discussion très informelle d’environ 30 minutes, où je demande simplement à la personne de me parler de ses expériences, avant de rebondir de façon opportuniste sur ce qu’elle me dit, pour me faire une idée de la façon dont elle fonctionne. Parfois, on entre dans les détails techniques. D’autres fois, on parle de fonctionnement des équipes, de communication… À la fin de ces 30 minutes, j’ai une bonne idée de là où la personne se situe dans sa carrière, de sa culture technique et professionnelle, et de ses ambitions.
Ensuite, je lui donne un challenge à faire tranquillement chez elle en prenant son temps. Ce challenge revêt la forme d’une fonctionnalité élémentaire qui existe déjà dans mon projet. L’énoncé de ce challenge :
- Est précis et minimaliste (il n’y a aucun code redondant à écrire) ;
- Représente un programme complet prêt à déployer : en l’occurrence, dans mon cas aujourd’hui, une image de conteneur ;
- Ne mentionne pas certaines problématiques comme la configuration ou la sécurité… mais évidemment, je regarde à la fin si la personne y a pensé (et c’est un bonus) ;
- Impose la même stack technique (pour mon poste actuel, Go et gRPC) que celle qu’on utilise au boulot, comme ça le candidat sait de quoi il retourne, et a l’occasion de s’y frotter au plus tôt ;
- Comporte un ou deux détails piégeux à déjouer ;
- Recommande de ne pas y passer plus de 4 heures, 6 grand max (le temps qu’il me faut pour le résoudre correctement), et que ce n’est pas grave si le projet n’est pas fini, car il est surtout censé servir de base à une discussion.
Il y a d’autres éléments à préciser sur ce challenge. En particulier, j’explique aux candidats que pendant toute la durée du challenge, nous sommes dans la même équipe. Je leur donne notamment mon contact sur Discord, en leur expliquant qu’ils peuvent à tout moment venir me parler, me poser des questions, discuter de la meilleure façon de faire, ou même solliciter une session de pair programming pour le démarrer correctement… Mais je reviendrai sur ce point plus bas.
Une fois que la personne a fini son challenge, elle me l’envoie, j’en fais une revue de code, et je fixe systématiquement un dernier call de 30 minutes avec la personne, pour lui faire mon feedback et avoir l’occasion de discuter plus technique, de savoir ce qu’elle ferait ensuite…
Je promets systématiquement ce feedback à tous les candidats dès le départ. Même si je détermine à la lecture du code que ça ne le fera pas, ou si sa candidature n’est finalement pas retenue par mes patrons après moi, je m’engage à ce que le candidat, qui vient de me donner plusieurs heures de son temps, reparte au minimum avec un échange constructif qui ait pour unique but de l’aider à progresser en tant que professionnel. Et surtout je m’y tiens !
C’est primordial à mes yeux. Et pourtant, l’écrasante majorité des boîtes que je connais ne prennent même pas la peine de vous recontacter après un test pour vous dire que c’est "non", et encore moins de vous expliquer pourquoi. C’est un manque de courage, de considération et de savoir-vivre aussi généralisé qu’impardonnable.
Mais passons…
Juger sur pièce, surtout !
Ce que ce challenge me permet de savoir, c’est comment ça se passerait pour de vrai si on devait travailler ensemble avec ce candidat. Et je n’utilise pas pour cela des "proxies" ou des tests dont j’estime la représentativité au doigt mouillé : déterminer le plus court chemin dans un graphe, ça nous apprend effectivement des choses sur la capacité du candidat à résoudre un problème, mais pour savoir si une personne saura déjouer un bug ou détecter une data race dans la vraie vie, c’est quand même beaucoup plus représentatif de la confronter… à une situation qui engendre facilement des bugs et des data races.
J’utilise donc des vraies tâches réalistes, quotidiennes, que le candidat sera amené à réaliser à l’identique dans mon équipe. Et je ne le lâche surtout pas en pleine nature avec un couteau et deux silex : je lui offre mon aide. Si je veux savoir à quel point il est indépendant, je n’ai qu’à voir à quelle fréquence il aura eu besoin de moi : ça sera pareil dans la vraie vie. Si je veux jauger sa capacité à apprendre et comprendre de nouvelles choses, je n’ai qu’à observer à quel point mes explications lui suffisent pour avancer : ça sera pareil dans la vraie vie. Et s’il ne sollicite ni mon aide, ni mes explications ? Eh bien, je n’ai qu’à voir le résultat de son projet pour déterminer à quel point il a eu tort ou raison de s’en passer !
En tout cas, jusqu’à présent, personne ne m’a jamais dit qu’ils auraient préféré des exos au tableau.
Avez-vous déjà vu... une recrue se sauver dès le premier jour ?
Moi, oui. Ma femme aussi. Et j’ai même failli le faire une fois1. Quand cela arrive, c’est toujours une manifestation du même problème, et les recruteurs n’ont que ce qu’ils méritent !
Ce qui se passe, c’est que la recrue se confronte à un décalage entre :
- Ce qui lui a été présenté, montré, laissé à penser, voire vendu ou même carrément bullshité pendant le processus de recrutement,
- … Et la réalité pure et simple de l’entreprise, de l’équipe, et du travail.
Plus ce décalage est grand, plus intense est le choc, et plus grand aussi est le risque que votre recrue vous file entre les doigts. C’est un risque particulièrement élevé en informatique, où le développeur moyen n’a réellement qu’à se baisser pour trouver un nouveau poste et se sauver… et 4 à 7 mois de période d’essai !
Alors… comment faire ?
Ce n’est pas évident ? Il faut être transparent, honnête et réaliste dès le départ.
- Votre offre d’emploi ne doit pas être rédigée par un auteur de fiction : faites-la rédiger par un membre de l’équipe,
- Mais surtout, le processus de recrutement doit permettre au candidat de se faire une représentation concrète du travail qu’il fera avec vous.
C’est à cause de cela que j’ai failli fuir le premier jour, une fois. On m’avait vendu un poste avec des grosses exigences en Python, une bonne collaboration dans l’équipe, un projet green field un peu gros mais tip-top alors que le premier jour, j’ai découvert du code copié-collé de la codebase de Django, un collaborateur qui était charmant pendant le recrutement mais tatillon, voire hautain en review, une journée par semaine de pur ops à monitorer et maintenir un vieux pipeline Jenkins dont on ne m’avait jamais parlé, une ambiance réellement tendue entre cette équipe et les core engineers qui lui étaient ouvertement hostiles… bref, on m’avait bullshité sur la réalité du travail.
Je suis resté pour le salaire en me disant que ce n’était que ma première impression, pour mieux repartir en constatant que cette impression était non seulement fondée, mais avait en plus empiré avec le temps.
Et c’est pour cela que j’en reviens à mon processus maison : vous remarquerez qu’il me permet de savoir à moi comment ça sera en bossant avec le candidat, mais également à lui de se rendre compte que je peux être chiant sur certains détails, coulant sur certains autres, exigeant sur la qualité du code et l’expressivité des tests, cash dans ma façon de communiquer… Je tiens absolument à ce que les gens sachent à quoi va ressembler leur quotidien s’ils signent, et le meilleur moyen pour cela, c’est encore de se montrer parfaitement naturel en entretien, et de proposer un challenge technique qui leur permet de se mettre en situation concrète.
Un process d’embauche où je sens que le candidat me teste moi, tout autant que je le teste lui, est un excellent signe à mes yeux. Cela veut dire qu’il est en train de se projeter à bosser avec moi.
Alors bien sûr, tout ça ne signifie qu’une chose : si vous voulez rendre vos offres d’emploi et vos processes de recrutement plus attractifs, il faut que la réalité du travail dans votre équipe le soit tout autant. Mais si d’aventure il vous prenait de ne faire que des ajustements de surface, et, pire, de laisser croire aux candidats que le poste et la boîte sont merveilleux sans fondement réel, vous pouvez avoir au moins une certitude : la plupart d’entre eux ne finiront pas leur période d’essai et se sauveront à la première occasion, et votre recrutement du mouton à cinq pattes vous coûtera alors beaucoup, beaucoup plus d’argent.
- Je n’ai pas suivi ma première impulsion, ce jour-là, parce que rien que mettre les pieds chez eux représentait une augmentation de salaire substantielle. Au lieu de cela j’ai même validé ma période d’essai, et démissionné encore quelques mois après, afin d’échapper à une situation de harcèlement moral… La prochaine fois, je n’hésiterai pas.↩
Et vous alors. Quel est votre secret pour recruter le mouton à cinq pattes ?