Appel à mettre fin aux défis de code irréalistes
(blackentropy.bearblog.dev)- Certaines épreuves de code irréalistes lors d’entretiens techniques créent des situations de pression sans rapport avec le travail réel et ne mesurent pas correctement les compétences pratiques des développeurs
- Les exercices individuels sous forte pression ne reflètent pas un environnement de travail avec collaboration et soutien, et finissent facilement par consister à déboguer une base de code ancienne sans documentation ni aide de l’équipe
- Même les « exercices de 4 heures » annoncés par les entreprises peuvent atteindre 8 à 10 heures, voire plus une fois ajoutés la recherche sur l’entreprise, l’examen des exigences du poste et la finalisation du livrable
- Les exercices portant sur une stack technique sans rapport avec le rôle sont justifiés au nom de l’évaluation de l’adaptabilité, mais demander à un développeur Ruby de déboguer du PHP peut être déconnecté de l’adéquation réelle au poste
- Le recrutement devrait se concentrer sur les technologies pertinentes, la résolution de problèmes, la collaboration et le potentiel de progression plutôt que sur des exercices arbitraires sous forte pression ; les exercices excessifs peuvent épuiser et faire fuir de bons candidats
Des exercices d’entretien déconnectés du travail réel
- Certains entretiens techniques demandent aux développeurs de réaliser en quelques heures des tâches comme du débogage de PHP legacy ou la création d’une mini-application
- Ces exercices individuels diffèrent de la manière dont le travail se fait réellement
- Au travail, on collabore généralement avec une équipe et l’on peut obtenir le soutien nécessaire
- Se retrouver à déboguer seul et rapidement une vieille base de code, sans documentation ni aide de l’équipe, ne correspond pas à un environnement de développement habituel
- Les entreprises y voient une évaluation de la « capacité à résoudre des problèmes », mais si l’exercice n’est pas lié aux exigences réelles du rôle, il est difficile d’évaluer l’adéquation pratique du candidat
Le coût caché en temps et la charge pour les candidats
- Le temps recommandé pour un exercice de code ne reflète pas suffisamment le temps réellement consacré par les candidats
- Avant l’exercice, il faut se renseigner sur l’entreprise et vérifier les exigences du poste
- Il faut aussi du temps pour peaufiner le projet afin de soumettre un livrable de qualité
- Un exercice de « 4 heures » peut s’étendre à 8 heures, 10 heures ou davantage
- Pour les développeurs qui jonglent avec un emploi et leur vie personnelle, cela peut donner l’impression d’effectuer du travail non rémunéré pour un poste qu’ils n’ont pas encore obtenu
Là où l’évaluation de l’adaptabilité se trompe
- Les exercices sur une stack technique sans rapport avec le poste sont parfois justifiés comme une évaluation de « l’adaptabilité »
- Demander à un développeur Ruby de déboguer du PHP peut, indépendamment de l’importance de l’adaptabilité, être un critère inadapté pour juger de la valeur du candidat
- La capacité à traiter rapidement des exercices flous et sans rapport ne suffit pas à déterminer l’adéquation à un rôle réel
- Certains exercices peuvent donner l’impression de mettre en scène les critères « élitistes » de l’entreprise plutôt que d’évaluer l’adéquation du candidat
- Si chaque recrutement impose une barrière du type « top 1 % », même des candidats expérimentés capables de bien faire le travail peuvent se retirer face à une situation artificielle et sous forte pression
Ce que les exercices de recrutement devraient évaluer
- Le processus de recrutement devrait être conçu autour des compétences concrètes nécessaires au rôle
- Il faut éviter les exercices façon bootcamp de code sans rapport avec les exigences réelles du poste
- Il faut se concentrer sur la résolution de problèmes, la collaboration et le potentiel de progression dans le domaine concerné
- L’adaptabilité devrait être évaluée comme une capacité à apprendre sur le long terme, et non comme la vitesse à traiter un exercice arbitraire
1 commentaires
Avis sur Hacker News
La dernière fois que j’ai dû déboguer une vieille base de code sans documentation ni aide de l’équipe ? Tout le temps. C’était 300 000 à 400 000 lignes de C++, et « legacy » voulait dire aucun test, quasiment aucune documentation ; en tant que seul développeur dans une petite entreprise, je devais continuer à servir des dizaines de milliers d’utilisateurs tout en corrigeant des bugs et en ajoutant des fonctionnalités.
Exemple récent : un correctif pour une fonctionnalité clé, vieux de plus d’un an, dont l’auteur original n’est plus là ; il fallait soit réécrire le code de zéro, soit ressusciter le patch pour l’adapter à
master.La capacité à se plonger dans un projet et à amener les gens vers l’objectif est clairement une compétence nécessaire pour un développeur senior, et je suis d’accord avec l’idée qu’il faut tester la résolution de problèmes. Mais le contenu d’un entretien technique doit dépendre du rôle : inutile de demander à un développeur web junior de faire des algorithmes de graphes au tableau blanc, tandis qu’un développeur senior ou un architecte sur un produit de réseau social doit les comprendre en profondeur.
La semaine dernière, j’ai aussi débogué du code Go de 2020 sans commentaires ni documentation ; c’était également une partie centrale du système, et on aurait dit qu’il avait été écrit par des fous. C’est douloureux.
La volonté de descendre dans les couches inférieures pour résoudre le problème au bon niveau est, selon moi, l’une des grandes soft skills qui distinguent les ingénieurs seniors. Plutôt que de contourner un bug ou une fonctionnalité manquante dans une couche basse par une correction a posteriori dans son propre code, le corriger au bon niveau rend tout le système plus robuste face aux changements dans toute la stack et aux cas d’usage futurs imprévus.
À l’inverse, sans cette approche, la base de code commence à pourrir quand les ingénieurs seniors partent ou sont remplacés par des juniors. Par exemple, si l’on ajoute naïvement une regex de validation devant un parseur effrayant et opaque pour chaque cas limite de parsing d’entrée, au lieu de corriger la grammaire du parseur lui-même, la base de code est en train d’évoluer en boule de boue.
Bien sûr, corriger au bon niveau oblige souvent l’entreprise à maintenir une petite branche de hotfix privée et de longue durée pour un logiciel de l’écosystème utilisé dans sa stack. L’upstream ne considère généralement pas ce problème comme un problème et n’accepte donc pas le patch ; il faut le garder pour soi.
Pour le dire en plaisantant, si l’on certifiait sur les profils GitHub le nombre de fois où quelqu’un a créé ou maintenu ce genre de branche de hotfix privée au long cours, on pourrait mesurer la séniorité d’un ingénieur bien plus simplement qu’avec un test de code.
Faire comme si cela ne servait à rien dans la vraie vie n’aide pas. La réalité est désordonnée, la documentation est souvent absente ou peu fiable, et la personne ou l’équipe qui a écrit le code d’origine peut déjà ne plus être là.
Petite anecdote. Le conjoint d’un ami a quitté son emploi au début de l’année, puis a préparé ses entretiens pour chaque entreprise de la Big Tech pendant 4 à 6 semaines. Il a préparé Meta pendant 4 à 6 semaines, Stripe pendant 4 à 6 semaines, etc., en passant aussi des entretiens au hasard entre-temps pour s’entraîner et acquérir des automatismes, en se renseignant sur les types de problèmes susceptibles de tomber dans chaque entreprise, puis en faisant du LeetCode plusieurs heures par jour.
Au final, tout s’est bien passé et il a accepté une offre L6/staff chez MAANG. Mais quand je lui ai parlé cette semaine, il disait avoir déjà oublié la plupart des détails qu’il avait travaillés, alors qu’il n’a même pas encore commencé son nouveau poste. Il disait que la préparation au system design avait été la plus difficile, faute d’expérience en conception de systèmes, mais il est désormais staff eng chez MAANG. Pour avoir travaillé avec lui sur un petit projet, dans la réalité il est très bon, mais pas un ingénieur exceptionnel.
C’est vraiment étrange, et cela semble expliquer en grande partie les cycles d’euphorie et de creux du recrutement. Quand on regarde des vidéos de préparation aux entretiens de system design, on dirait presque un script. Il suffit d’entrer en entretien et de suivre le script ; le fait d’avoir réellement conçu des systèmes similaires, ou plus complexes, ne semble pas très important. L’objectif de l’entretien de system design semble finalement être : « connaît-il le script ? »
Si l’on regarde ces deux vidéos à la suite en vitesse 2×, il est frappant de voir à quel point l’exécution ressemble à un script : https://www.youtube.com/watch?v=4_qu1F9BXow, https://www.youtube.com/watch?v=_K-eupuDVEc
Mes deux parents travaillaient dans la tech à Santa Cruz dans les années 1980-1990, et à l’époque, comme le vivier de talents n’était pas immense, c’était un outil inclusif pour repérer des personnes qu’on pouvait faire grandir comme développeurs. Le secteur a repris cette pratique aujourd’hui, mais l’a rendue exactement inverse : excluante.
L’une des personnes que j’ai recrutées était physicienne, ne connaissait aucun jargon spécialisé et était terrifiée la première fois qu’elle a vu un problème au tableau blanc. Une fois guidée jusqu’à une zone où elle se sentait à l’aise, elle a commencé à parler des outils qu’elle avait créés pour l’aider dans son travail de physique ; elle a été surprise quand je lui ai dit que ces outils, même conçus sans connaissances en développement, étaient du logiciel. Non seulement c’était bel et bien du logiciel, mais c’était aussi très impressionnant, et le problème au tableau blanc avait servi d’outil pour révéler un potentiel.
Je comprends que les grandes entreprises veuillent des widgets qu’on puisse brancher directement à la place de personnes, mais c’est amusant de les voir utiliser quelque chose qui avait été créé dans un but exactement opposé. Je me dis aussi que j’ai finalement de la chance d’être assez âgé pour ne plus avoir d’espoir d’entrer dans une super entreprise qui impose ce genre de code challenge.
Le raisonnement est le suivant : quelle que soit l’université fréquentée, les cours suivis ou les avantages et désavantages rencontrés, si l’on possède les qualités nécessaires au poste, c’est quelque chose qu’on peut apprendre en quelques mois. La technique est très standardisée, donc le processus devient assez objectivement différenciant.
On ne s’attend pas à ce que ces compétences précises soient utilisées dans le travail réel. En revanche, le candidat montre qu’il peut apprendre ce type de compétences et les exécuter à un haut niveau dans une situation d’entretien très stressante. Selon cette logique, c’est un bon signal qu’il saura apprendre les technologies nécessaires au projet auquel il sera affecté plus tard, et performer sous une forte pression de délais.
Je ne défends pas ce système, mais il y a une logique claire derrière.
Il dit avoir oublié, mais s’il a obtenu ce poste, il a probablement été capable de résoudre des problèmes LeetCode de difficulté moyenne. Il est difficile de croire qu’il a tout oublié, et il est très possible qu’il sache encore résoudre les problèmes faciles que la plupart des gens ne peuvent pas faire sur le vif. Il connaît sans doute encore la complexité des tâches backend essentielles comme la recherche, le tri, les tableaux et recherches par hash, ainsi que les parcours d’arbres et de graphes.
Et le talent d’acteur est peut-être plus répandu dans la population générale que le talent de programmation.
J’ai récemment mené un processus d’entretien pour un poste d’ingénieur relativement senior dans une petite startup. Comme je crois que les formats d’entretien qui conviennent le mieux varient selon les personnes, j’ai proposé un choix à tout le monde
Comme j’avais vu beaucoup de colère contre les tests à faire chez soi, je pensais que les trois options seraient réparties assez équitablement. À ma grande surprise, environ 90 à 95 % des candidats ont choisi le test à faire chez soi. C’était une donnée intéressante, car c’est aussi le format que je préférerais en tant que candidat, et j’ai été très surpris que la plupart le préfèrent également
Dans un entretien en présentiel, l’entreprise supporte aussi un coût important, donc on peut considérer que le risque de perdre mon temps est plus faible. L’asymétrie dans la recherche d’emploi s’accentue déjà, et les exercices à faire chez soi accélèrent encore cette tendance
Un ami non technique me reproche encore de ne pas avoir terminé un exercice autrefois : l’exigence principale était clairement triviale, mais les consignes étaient suffisamment floues pour que je puisse y passer des heures à me demander si c’était assez bon pour être soumis. En plus, ils attendaient un ensemble de technologies étroit ; ce n’était pas difficile, mais je n’avais pas envie de l’apprendre juste pour une éventuelle occasion d’aider une entreprise qui disait « ne pas trouver de talents techniques »
Je pense que je préférerais les options 1 et 2 à la 3. Si l’examinateur comprend le problème que je résous, il peut mieux évaluer mon approche
Si je le fais chez moi et que je le soumets ensuite, l’examinateur peut comparer ma solution à la sienne ou à d’autres solutions, et mieux cerner mon style de code sur la base du même exercice
Si on travaille ensemble en pair programming, il peut voir mon raisonnement, et je peux aussi mieux expliquer pourquoi j’ai choisi tel ou tel idiome
Le code passé n’a presque pas de contexte. C’est juste du code écrit pour un autre projet. C’est utile en amont, avec le CV, pour vérifier que la personne sait réellement écrire du code, mais plus tard dans le processus, ce ne sera impressionnant que si l’on dispose d’une application qui fonctionne et que l’on peut guider l’intervieweur dans le code d’une fonctionnalité précise. Or combien de personnes ont simplement un logiciel fonctionnel sous la main ? Le plus souvent, on a du code qui tient à peu près debout grâce à quelques astuces
Je préfère la 1 à la 2. Cela réduit le risque de faire une erreur. Plutôt que de risquer de me planter sur place pendant 2 heures à cause de la pression et de la loi de Murphy, je préfère évidemment passer 2 heures de plus chez moi et avoir la liberté de chercher ce que je ne sais pas
J’ai aussi été du côté de ceux qui évaluent des tests à faire chez soi, et je sais à quel point il est difficile d’impressionner profondément quelqu’un avec ça
La dernière fois que j’ai passé un vrai entretien de code, je pouvais choisir n’importe quel langage de programmation, et aussi choisir un problème parmi trois. J’ai plutôt apprécié, et j’ai reçu une offre. Dans un entretien avec limite de temps, pouvoir choisir Python au lieu de C++ donnait presque l’impression de tricher
Plus je vois de plaintes en ligne au sujet des entretiens de code, plus je suis convaincu que les entretiens de code sont de loin la meilleure façon de filtrer les candidats à des postes de développement logiciel. Dans tout le secteur, il y a trop de beaux parleurs, d’imposteurs et de gens qui organisent des réunions, et pas assez de personnes prêtes à retrousser leurs manches, à se plonger dans le code et à vraiment terminer le travail
Le problème s’aggrave encore aux niveaux élevés. Vous pouvez vous plaindre autant que vous voulez, mais un poste confortable chez FAANG à 500 000 dollars par an ne vous est pas dû. Si vous n’êtes pas prêt à revoir les bases de la programmation et à écrire quelques boucles for, l’entreprise passera simplement à quelqu’un qui le fera
Si l’entretien testait vraiment la capacité à retrousser ses manches et à se plonger dans le code, je ne comprends pas pourquoi, en tant que nouvel arrivant, je dois expliquer autant de pratiques d’ingénierie logicielle et de débogage à des gens qui sont là depuis longtemps
Si vous avez vraiment travaillé dans une grande entreprise, vous savez que 90 % du vrai travail est fait par moins de 5 % des gens. Si les entretiens fonctionnaient correctement, ce ratio devrait être bien meilleur
Il y a Cracking the Coding Interview, Elements of Programming Interviews in Java/Python/autres langages, LeetCode et ses abonnements premium payants, sans parler des bootcamps d’entretiens blancs. Ce n’est plus vraiment une question de compétence, mais plutôt de savoir jouer avec le système
Ce qui est étonnant, c’est l’absence totale de dissonance cognitive entre le fait que les entretiens de code sont la méthode de recrutement standard et la réalité de résultats aussi mauvais
Si le problème porte sur quelque chose comme la tokenisation des LLM, comment peut-on interdire l’usage d’un LLM dans un problème de « ML-LeetCode » ?
Si un candidat est un expert qui code très efficacement avec Cursor et Claude, résout le problème en 10 minutes avec 3 prompts et 2 corrections d’erreurs faciles à repérer, et possède en plus des articles de niveau NeurIPS et du code open source, ai-je filtré un faux imposteur ou éliminé un candidat de tout premier plan ?
Je ne pense pas que les problèmes de type LeetCode aient du sens pour les personnes qui travaillent sur des sujets liés aux LLM. Qu’on le veuille ou non, une part croissante des postes confortables à 500 000 dollars par an chez FAANG+ sera liée aux LLM
Faire déboguer du PHP à un développeur Ruby pour tester sa flexibilité me semble être un test acceptable. Un bon développeur, surtout un développeur senior, devrait être capable de faire ce genre de chose. Se classer uniquement comme « développeur Ruby » est un piège de carrière
Il arrive qu’on doive déboguer un vieux DSL spécifique à un fournisseur, ou du code dont le framework et les standards sont si anciens qu’il est presque devenu un autre langage
Il faut parfois ajouter la prise en charge de fonctionnalités rétroportées, ou corriger des failles de sécurité pour d’anciens clients et des stacks legacy. Dans une grande entreprise, il nous est aussi arrivé de devoir prendre en charge le code en escrow d’un partenaire beaucoup plus petit
Mettre en place l’environnement pour pouvoir déboguer correctement représente souvent plus de travail que le correctif lui-même. Malgré tout, c’est un bon test pour les profils senior et au-delà
L’intervieweur m’a dit : « inversez ce tableau », et j’ai répondu : « En Python, j’utiliserais array.reverse() ou reversed(array), et il doit y avoir l’un des deux en JS, donc probablement une méthode .reverse ». L’intervieweur a répondu : « Bonne supposition »
Je suis sincèrement sorti de là en ayant trouvé ça amusant et en ayant appris quelques trucs, et eux ont pu voir comment je raisonnais face à un problème nouveau
J’ai débogué plusieurs fois de vieilles codebases sans documentation ni aide de l’équipe. Des systèmes dont les créateurs ne sont plus là et dont la documentation n’existe pas ou est introuvable, ça existe vraiment. Cet exemple n’est donc pas très bon. Savoir déboguer un programme, suivre le flux des requêtes et comprendre ce qui se passe est une bonne compétence
En revanche, là où cet exemple est vraiment mauvais, c’est qu’il enferme les développeurs dans des cases liées à une technologie précise. Si vous avez une application PHP legacy, vous allez écarter des développeurs Java, Python, Ruby ou Go qui ont cette capacité de débogage mais qui ne connaissent pas PHP et seront donc plus lents. Alors qu’après quelques mois à toucher directement à PHP, ils pourraient être de meilleurs développeurs
Je suis d’accord sur le fait qu’un « exercice de 4 heures » peut facilement devenir 8, 10 heures ou plus si l’on veut produire quelque chose de bon. Le temps annoncé peut facilement être contourné, si bien que les personnes qui ont plus de temps peuvent paraître de meilleurs candidats
Quand ai-je débogué une vieille codebase sans documentation ni aide de l’équipe ? Tous les jours cette semaine
Pour la documentation : le code a été mis à jour pour la dernière fois en juin, et la documentation en janvier 2022
Pour l’équipe : la moitié qui n’a pas été licenciée il y a deux ans est partie vers de meilleurs horizons. Bien sûr, il y a une équipe propriétaire du projet, mais elle a aussi trois autres projets, et sa contribution ici au cours de l’année écoulée se résume à une dizaine de lignes, dont 11 étaient des mises à jour de dépendances
Dire « c’est comme demander à un développeur Ruby de déboguer du PHP » ou « si un poste requiert une technologie précise, testez cette technologie » ressemble au discours de quelqu’un qui a échoué à un coding challenge
Plus sérieusement, les entreprises adoptent rarement des pratiques de recrutement juste pour s’amuser. C’est généralement la meilleure méthode à laquelle leur intelligence collective est parvenue. Demander de les supprimer sans chercher à comprendre quel problème elles essaient de résoudre, et sans proposer d’alternative, n’est pas productif
Dans le développement logiciel, je pense qu’on réinvente trop souvent la roue au lieu d’emprunter les pratiques d’autres métiers. Regardons par quel processus de recrutement passent les ingénieurs en génie civil pour toucher la moitié du salaire des développeurs logiciels, et intégrons-le à nos pratiques. Alors nous serons tous de bons petits soldats heureux
Je pense qu’il est très peu probable qu’elles aient vraiment réfléchi à ce qu’elles essaient d’accomplir. Elles ont simplement suivi ce que font les autres, en croyant qu’un processus conçu avec intention avait été créé quelque part par quelqu’un
Le recrutement tech s’est tellement égaré qu’on a l’impression qu’il s’est installé, au mieux, dans ce qui ressemble à un maximum local
J’ai eu une très mauvaise expérience dans une entreprise qui ne faisait aucun test de code. Il n’y avait que 2 ou 3 entretiens
Le problème est apparu quand j’ai commencé à travailler avec l’équipe data engineering. La majeure partie de la stack reposait sur Hadoop, Kubernetes, Ruby, Python et plusieurs autres technologies, et nécessitait une compréhension de base du cloud computing
Mais les expériences professionnelles et les parcours étaient tellement hétérogènes que, au lieu de faire le travail pour lequel j’avais été embauché, je passais beaucoup de temps à combler les lacunes des autres. Certains collègues n’étaient même pas capables de faire des tâches de base comme empaqueter un CLI Python avec Docker ou vérifier des jobs Hadoop, si bien que je faisais beaucoup de travail de colle pour compenser
J’ai fini par partir. Pas parce que je me pensais exceptionnel, mais parce que j’en avais assez de passer 80 % de mon temps à soutenir des personnes embauchées au même niveau que moi, voire à un niveau supérieur. Je reconnais que les pratiques de recrutement de cette entreprise étaient très mauvaises, mais il faut bien une forme ou une autre de test technique de base
Une autre question importante est de savoir s’il fallait leur expliquer les mêmes choses à répétition. Ne pas savoir est acceptable ; ne pas vouloir apprendre l’est beaucoup moins
Ce qui est amusant avec les tests sous forme de devoir à rendre, c’est qu’il y a un aléa moral qui pousse à y consacrer plus de temps, même quand on dit de « n’y passer que X heures ». Et si l’entreprise le demande, cela crée aussi une incitation à mentir sur le temps réellement passé
Il m’est arrivé plusieurs fois de soumettre un devoir en insistant pour rester dans le temps recommandé, tout en résolvant correctement le problème, puis de me faire reprocher lors de l’entretien suivant : « Pourquoi n’avez-vous pas implémenté X ? »
À ce sujet, les tests sous forme de devoir trop ouverts sont de mauvais exercices. Ils avantagent les personnes qui ont plus de temps libre et peuvent peaufiner davantage. Pensée émue aux tests de data science à rendre qui demandent comme livrable final une présentation PowerPoint