TL;DR
- J'ai passé le process NVIDIA pour un poste d'ingénieur logiciel orienté systèmes, sans une ligne de CUDA sur mon CV, et j'ai eu l'offre après environ sept semaines.
- Ce qui distingue NVIDIA d'une boucle FAANG classique, c'est la co-conception matériel-logiciel : une réponse en O(n) correcte est le point de départ de la question, pas son point d'arrivée, car la relance porte sur le comportement du code en mémoire.
- J'ai failli échouer au round GPU en décrivant un kernel au lieu des accès mémoire, sauvé par trois notions : coalescence, occupancy, intensité arithmétique.
- Si vous venez du back-end, mettez l'essentiel de votre préparation sur la sémantique mémoire C/C++ et l'architecture GPU, pas sur davantage de LeetCode.
Introduction
Je n'avais pas prévu de passer un entretien chez NVIDIA. Six ans de back-end derrière moi — du Go, un peu de Java, beaucoup de Kafka, et de temps en temps un fichier C++ que je touchais prudemment avant de m'en éloigner. Les GPU, c'était ce dont l'équipe inference se plaignait sur Slack. Puis une offre est passée en mars, du type « C++ orienté performance » et « connaissance du calcul parallèle appréciée », et j'ai postulé un mardi soir avec un CV où le mot CUDA n'apparaissait nulle part.
Sept semaines plus tard, j'avais une offre. Voici la version honnête de ce qui s'est passé entre les deux, y compris le round où je suis resté onze secondes en silence face à une question que j'aurais dû voir venir.
Pourquoi j'ai tenté, et pourquoi c'est un pari particulier depuis la France
Deux raisons, une avouable et une moins.
L'avouable : j'avais passé deux ans à regarder mes propres services se faire brider par des choses que je ne savais pas expliquer. Un serveur de modèles à 30 % d'utilisation sans que personne ne sache pourquoi. Un batch où doubler la machine achetait 15 % de débit. Je savais profiler un service Go et lire un flame graph, mais dès que le problème descendait sous le runtime, je devinais. La moins avouable : NVIDIA compte environ 36 000 ingénieurs et tout le monde autour de moi voulait y entrer. Mauvaise raison, mais elle m'a porté pendant six semaines de révisions ingrates.
Le pari, depuis la France, tient au volume. Les postes vraiment bas niveau ouverts dans l'Hexagone sont rares, et la compétence française en semi-conducteurs, embarqué et calcul est concentrée sur quelques bassins : la région parisienne et l'axe Grenoble–Toulouse–Sophia. Filtrez la page carrières par pays, et acceptez l'idée de viser peut-être un poste remote ou une mobilité européenne.
Décrocher l'entretien : la seule chose qui a vraiment compté sur mon CV
Pas de cooptation. J'ai postulé à froid sur le site carrières, rien pendant onze jours. Puis j'ai fait la seule chose qui a probablement changé quelque chose : réécrire le premier tiers de mon CV pour que le travail de performance soit le titre, et non une puce enterrée sous « microservices ».
Avant : « Conception et maintenance de pipelines d'événements à haut débit. »
Après : « Réduction de la latence p99 d'un pipeline d'ingestion à 40 000 événements/s de 180 ms à 34 ms, par restructuration des buffers et suppression des allocations par message. »
Même poste, même travail, mais la seconde version raconte une histoire consciente du matériel. La recruteuse m'a dit plus tard que l'expression qui avait déclenché la lecture était « suppression des allocations par message ». L'appel RH est arrivé une semaine après la mise à jour.
Une remarque propre au marché français : rédigez ce CV en anglais, sans photo, sans état civil et sans rubrique « centres d'intérêt ». Le tri se fait sur les deux premières lignes techniques, et une partie des lecteurs ne sont pas basés en France.
Étape 1 — l'appel RH (30 minutes)
Rien d'exotique. La recruteuse a parcouru mon parcours, ce que je voulais faire, où j'étais basé, et — je ne m'y attendais pas — à quel point j'étais à l'aise en C++ sur une échelle de un à dix.
J'ai dit six. C'était honnête et je crois que ça a aidé. Elle m'a répondu que l'équipe cherchait des gens capables d'atteindre huit, pas des gens déjà à dix, et que la boucle sonderait le raisonnement mémoire bas niveau. C'est l'information la plus utile de tout le process : elle m'a dit exactement quoi réviser pendant un mois.
Deux points typiquement français sont tombés là. Mes prétentions salariales, dès ce premier appel — c'est la norme ici : préparez une fourchette en euros bruts annuels et une phrase pour l'accompagner, pas un silence gêné. Et mon préavis : trois mois, statut cadre, en précisant que je tenterais une dispense partielle. Le dire tôt évite la conversation désagréable six semaines plus tard, quand une équipe a déjà calé une date de démarrage.
Elle a aussi décrit la forme de la boucle : un entretien technique téléphonique, puis un onsite virtuel, sans s'engager sur un nombre de rounds avant confirmation de l'équipe. Le mien a fait cinq rounds sur environ cinq heures ; j'ai entendu parler depuis de boucles à quatre et à six.
Étape 2 — l'entretien technique, et la question derrière la question
Soixante minutes, éditeur partagé, un interlocuteur qui écrivait manifestement du code dans une autre fenêtre pendant les quatre premières minutes. En anglais de bout en bout.
Le problème portait sur un flux de valeurs — l'archétype est « maintenir efficacement un agrégat glissant sur un très grand flux ». J'ai fait ce que six ans de conditionnement m'avaient appris : clarifier les contraintes, dérouler la version naïve en O(n·k), trouver la version en O(n) en une passe avec une structure auxiliaire, écrire proprement, passer les cas limites. Terminé avec quatorze minutes d'avance, et je me sentais bien.
Puis il a dit : « D'accord. Maintenant, supposons cent millions d'éléments et mille cœurs. Comment paralléliseriez-vous ? »
Je me suis figé, parce que j'avais classé le problème dans la case résolu. Je m'en suis sorti avec quelque chose de raisonnable — découper en blocs, calculer des partiels, recombiner — et il a poussé plus loin. Quel est le coût de la combinaison ? L'opération est-elle associative ? Que se passe-t-il aux frontières des blocs pour une fenêtre glissante ?
C'est là que j'ai compris la boucle. Ailleurs, « rendez ça plus rapide » veut dire trouver un meilleur algorithme. Ici, la réponse en O(n) était le ticket d'entrée : l'entretien commençait après, et tout le reste portait sur la façon dont le travail se projette sur du matériel qui fait beaucoup de choses en même temps.
Je suis passé, mais de justesse selon ma propre estimation. Le retour, transmis par la recruteuse, tenait en une phrase : bases algorithmiques solides, souhaite voir plus d'aisance sur la décomposition parallèle. Autrement dit : il vous manque une dimension.
Les quatre semaines d'écart
Vingt-six jours avant l'onsite, dans l'ordre approximatif du rendement.
La hiérarchie mémoire d'abord, le GPU ensuite. La première semaine entièrement sur le cache CPU : lignes de cache, localité spatiale et temporelle, pourquoi parcourir un tableau 2D en row-major est spectaculairement plus rapide qu'en column-major, faux partage entre threads. La semaine la plus rentable, parce que chaque concept GPU appris ensuite n'était qu'une variation de « où vivent les données et quelle distance doivent-elles parcourir ».
La sémantique C++, délibérément. Pointeurs bruts contre références. Ce qu'est réellement un pointeur pendant au niveau de la mémoire. Durée de vie des objets et RAII. Cas où une copie se produit silencieusement. std::unique_ptr contre shared_ptr et le coût du compteur atomique du second. J'ai appris ça en écrivant de petits programmes et en les cassant exprès : plus long que lire, quatre fois plus durable.
Les fondamentaux d'architecture GPU. Les warps, et pourquoi une branche divergente coûte cher. L'occupancy, et pourquoi plus de threads n'est pas automatiquement mieux. Mémoire globale contre mémoire partagée. La coalescence des accès — le concept le plus important du lot. Le transfert hôte-device traité comme un coût de premier ordre. L'intensité arithmétique, et le réflexe de se demander si un kernel est limité par le calcul ou par la bande passante avant d'optimiser quoi que ce soit.
Les simulations, et ce qu'elles ont corrigé. J'ai fait quatre entretiens blancs sur PhantomCodeAI en deux semaines, et le même défaut est remonté à chaque fois : je traitais bien la moitié algorithmique, puis je devenais muet quand la relance basculait sur le matériel. Pas faux — muet. Je raisonnais en silence et ne parlais qu'une fois arrivé à une conclusion, ce qui se lit comme « ne sait pas ». Le voir dans trois transcriptions consécutives a été plus convaincant que n'importe quel conseil d'ami.
Ce que je n'ai pas fait : plus de LeetCode. Une dizaine de problèmes en quatre semaines, pour rester chaud. Si vous sortez d'un cycle de préparation classique, votre algorithmique suffit déjà et votre goulot d'étranglement est ailleurs ; une banque de questions comme notre section entretiens entretient la forme.
L'onsite — cinq rounds, environ cinq heures
Cinq rounds virtuels enchaînés, deux courtes pauses. L'ordre et la composition varient selon l'équipe : lisez ceci comme ma boucle, pas comme la boucle.
Round 1 — algorithmique, niveau soutenu. Un problème de graphe et de parcours avec une contrainte mémoire désagréable. La bascule arrive en seconde moitié : sachant que le graphe ne tient pas en cache, comment le disposeriez-vous en mémoire pour réduire les défauts ? Quinze minutes sur listes d'adjacence contre représentation plate façon CSR — un mois plus tôt, je n'aurais rien eu à dire.
Round 2 — C++ et mémoire. Le round le plus direct de la boucle et, curieusement, celui que j'ai le plus apprécié. Archétypes : voici une petite classe, dites-moi tous les endroits où elle peut fuir ou provoquer un double free. Que vaut cette arithmétique de pointeurs et pourquoi. Où vit cet objet et quand meurt-il. Aucune astuce : un contrôle de compétence frontal, entièrement révisable.
Round 3 — celui qui a failli tout arrêter. GPU et parallélisme. L'énoncé portait sur une transformation de données massive : comment la porter sur GPU et la rendre rapide.
J'ai commencé à décrire un kernel. Indexation des threads, dimensions des blocs, la mécanique. L'interlocuteur m'a laissé parler environ quatre-vingt-dix secondes, puis a dit, gentiment : « Vous me dites comment l'écrire. Je veux savoir comment la mémoire se comporte. »
C'est là que je suis resté silencieux pendant ce que mon enregistrement a confirmé être onze secondes.
Ce qui m'a sauvé, c'est un des concepts que j'avais rabâchés : la coalescence. J'ai redémarré depuis les données. J'ai dit, lentement, que la vraie question était de savoir si des threads voisins lisent des adresses voisines : si oui, le matériel sert les chargements d'un warp en un petit nombre de transactions ; si non, le même travail logique devient plusieurs fois plus de trafic mémoire. Puis que le motif d'accès de la version naïve était à pas constant, donc que je restructurerais les données — d'un tableau de structures vers une structure de tableaux — avant même de toucher au kernel. Puis j'ai demandé si la charge était limitée par la bande passante, parce que dans ce cas aucun réglage de kernel ne sert tant que les transferts ne le sont pas.
Il s'est visiblement détendu. Le reste du round a porté sur le tiling en mémoire partagée et sur la question de savoir si la copie hôte-device mangerait tout le gain pour une seule passe sur les données — la réponse étant oui, d'où la règle : soit vous gardez les données résidentes, soit vous ne le faites pas du tout.
Je pense avoir perdu des points là, et je pense aussi que redémarrer à un autre niveau d'abstraction, à voix haute, l'a rattrapé. Les interlocuteurs observent comment vous vous rattrapez : « laissez-moi reprendre par le côté mémoire » vaut bien mieux que continuer à parler d'indices de threads.
Round 4 — conception. Pas un system design web classique, plutôt de l'architecture de pipeline : comment les données circulent dans un système hétérogène, où l'on tamponne, où l'on batche, comment garder un accélérateur alimenté plutôt qu'inactif, quel composant fixe le plafond de débit. Si votre préparation se limite aux load balancers et au sharding, élargissez.
Round 5 — hiring manager. Comportemental, plus doux que prévu, avec une question tranchante : parlez-moi d'un problème de performance que vous n'avez pas résolu. J'ai dit la vérité sur le serveur de modèles à 30 % d'utilisation, y compris la partie où j'avais supposé un problème réseau et où j'avais tort. Il a semblé plus intéressé par cette réponse que par mes réussites. Détail culturel utile : la modestie française mal calibrée passe mal dans ce format. Racontez l'échec avec un diagnostic précis, pas avec des excuses.
Le débrief, l'offre et la négociation
Neuf jours de silence, passés convaincu que le round 3 m'avait coulé. Puis un appel : boucle globalement positive, un round signalé comme mitigé. La recruteuse n'a pas dit lequel. Je sais lequel.
La conversation d'offre a été simple et sans surprise. J'ai négocié — demandé poliment s'il y avait de la marge, et posé plus de questions sur le niveau et le périmètre de l'équipe que sur le chiffre affiché, faute d'offre concurrente. Certaines choses ont bougé, d'autres non ; personne n'a mal réagi.
Je ne publierai pas de chiffres, mais trois repères français méritent d'être posés. Les packages européens sont sensiblement en dessous des niveaux américains à poste équivalent : ne convertissez jamais un chiffre vu sur un forum américain. Les actions avec un cycle d'acquisition régulier sont rares hors filiales de groupes américains ; si on vous en propose, la question n'est pas le montant initial mais la cadence des refresh. Enfin, regardez la structure complète : statut cadre, forfait jours et RTT, participation et intéressement, mutuelle, période d'essai de quatre mois renouvelable une fois. Sur un CDI, ces lignes valent parfois plus que quelques points sur le fixe.
Ce que je réviserais encore, dans cet ordre
Je referais ces quatre semaines presque à l'identique, avec un changement : commencer les simulations en semaine un plutôt qu'en semaine trois, parce qu'elles m'ont dit ce qui n'allait pas dans ma façon de répondre alors que j'avais encore le temps de le corriger.
- Hiérarchie mémoire et cache. Lignes de cache, localité, faux partage, pourquoi l'ordre des boucles change le temps d'exécution d'un ordre de grandeur. Tout le reste s'appuie là-dessus.
- Coalescence des accès mémoire. Si vous n'apprenez qu'un concept GPU, apprenez celui-là. « Des threads voisins touchent-ils des adresses voisines ? » répond à une part surprenante des relances.
- Pointeurs et durées de vie en C/C++. Pointeurs pendants, propriété, RAII, déplacement contre copie, coût réel d'un
shared_ptr. Questions frontales, pas incidentes. - Modèle d'exécution GPU. Warps, divergence, occupancy, mémoire partagée, coût des transferts hôte-device. Assez pour raisonner, pas assez pour livrer.
- Limité par le calcul contre limité par la bande passante. Entraînez-vous à dire lequel des deux caractérise une charge, et pourquoi, avant toute optimisation.
- Répondre correctement à « rendez ça plus rapide ». Ici, cela veut généralement dire la machine, pas une meilleure structure de données. Si vous ne savez pas trancher, demandez : « voulez-vous que j'attaque l'algorithme ou le motif d'accès ? » est une clarification légitime, et elle passe bien.
L'habitude qui a le plus compté a été de narrer le raisonnement matériel au lieu de le faire en silence. Je ne l'ai appris sur moi-même qu'en revoyant quelques boucles d'entraînement enregistrées sur PhantomCodeAI avant l'onsite, et en me regardant devenir muet au même moment trois fois de suite.
Ce à quoi je pense encore
Je n'étais pas le candidat le plus fort en algorithmique de cette boucle. Ce que j'avais, c'était quatre semaines sur un seul axe — comment le code se comporte sur du vrai matériel — et la volonté de dire « je ne sais pas, laissez-moi raisonner par la mémoire » plutôt que de bluffer. Si vous regardez une annonce NVIDIA en vous disant que vous ne pouvez pas postuler faute d'avoir écrit un kernel : l'écart est plus petit qu'il n'en a l'air, et c'est un écart de lecture, pas d'expérience. Six mois de GPU m'auraient aidé ; quatre semaines de hiérarchie mémoire, de sémantique C++ et d'un concept très bien compris qu'on appelle la coalescence ont suffi.
Questions fréquentes
Faut-il avoir fait du CUDA pour réussir un entretien d'ingénieur logiciel chez NVIDIA ?Pour le poste orienté systèmes que j'ai passé, non — mais il faut savoir raisonner à voix haute sur du matériel parallèle. Personne ne m'a demandé d'écrire un kernel de production de mémoire. On m'a demandé ce qui arrive au trafic mémoire quand des threads voisins lisent des adresses non contiguës, et si mon problème était limité par le calcul ou par la bande passante. Ça s'apprend en quelques semaines ; dix ans d'expérience GPU, non.
En quoi le process NVIDIA diffère-t-il d'une boucle FAANG classique ?Les rounds d'algorithmique et de structures de données ressemblent à ceux de n'importe quelle grande boîte tech. La différence est dans la seconde moitié de chaque question. Chez Meta ou Google, « comment rendre ça plus rapide » signifie généralement une meilleure structure de données. Chez NVIDIA, cela veut souvent dire la machine : lignes de cache, hiérarchie mémoire, faux partage, divergence de warp, débit contre latence. Même question, axe d'amélioration différent.
Les entretiens se déroulent-ils en français si l'on postule depuis la France ?Dans mon cas, l'échange RH a commencé en français puis est passé à l'anglais dès la partie technique, et tous les rounds techniques se sont tenus en anglais avec des interlocuteurs basés dans plusieurs pays. C'est la norme sur les postes bas niveau dans les filiales françaises de groupes américains. Entraînez-vous à expliquer une hiérarchie mémoire en anglais à voix haute : c'est un exercice différent de le comprendre en français.
Que réviser quand on vient du back-end ou du développement applicatif ?Trois choses, dans cet ordre. La sémantique C/C++ : pointeurs, durées de vie, propriété, RAII, copie contre déplacement. Le comportement de la hiérarchie mémoire : lignes de cache, localité, coalescence, et pourquoi la même boucle est dix fois plus lente si l'on inverse les indices. Enfin les bases du modèle d'exécution GPU : warps, occupancy, mémoire partagée, coût des transferts hôte-device. C'est quelques semaines de lecture ciblée, pas une reconversion.
Combien de temps a duré le process, et quel préavis prévoir en France ?Sept semaines environ dans mon cas, de l'appel RH à l'offre verbale, avec deux semaines creuses au milieu pour des raisons de calendrier. À cela s'ajoute le préavis : trois mois pour un statut cadre en France, sauf négociation d'une dispense. Comptez donc quatre à cinq mois entre la candidature et la prise de poste réelle, et annoncez ce préavis dès le premier appel plutôt qu'à la fin.
Faut-il négocier une offre chez NVIDIA en France ?La conversation a été normale et professionnelle, et poser la question n'a créé aucune tension. Je n'avais pas d'offre concurrente, donc j'ai porté la discussion sur le niveau et le périmètre de l'équipe plutôt que sur le chiffre affiché, et j'ai demandé la cadence des refresh d'actions — un élément que très peu d'employeurs français proposent et qu'il faut donc évaluer sérieusement. Ce qui bouge dépend du niveau, de la localisation et du poste ouvert ; je ne généraliserais pas à partir d'un cas.