TL;DR
- Hice el proceso de NVIDIA para un puesto de software cercano a sistemas sin haber escrito nunca un kernel de CUDA, y me hicieron oferta unas siete semanas después.
- Lo que distingue este proceso de un proceso FAANG normal es el co-diseño hardware-software: una solución O(n) correcta es el punto de partida, no el final, porque la siguiente pregunta siempre es cómo se comporta tu código sobre memoria real y hardware paralelo real.
- Casi suspendo la ronda de GPU por describir un kernel en lugar de describir el acceso a memoria, y me salvé por saber explicar coalescencia, ocupación e intensidad aritmética en voz alta.
- Si vienes de backend o de aplicación, dedica la mayor parte de la preparación a semánticas de memoria en C/C++ y a fundamentos de arquitectura de GPU, no a más LeetCode.
Introducción
No tenía ningún plan de presentarme a NVIDIA. Llevaba seis años escribiendo servicios de backend en Madrid: sobre todo Go, algo de Java, mucho Kafka y algún fichero de C++ que tocaba con cuidado y abandonaba rápido. Las GPU eran eso de lo que se quejaba el equipo de inferencia en Slack. Entonces en marzo se me cruzó una oferta de un puesto de software cercano a sistemas, de esas que dicen «C++ crítico en rendimiento» y «se valorará familiaridad con computación paralela», y la mandé un martes por la noche con un currículum en el que no aparecía la palabra CUDA por ningún lado.
Siete semanas después tenía una oferta. Esta es la versión honesta de lo que pasó por el medio, incluida la ronda en la que me quedé callado once segundos porque no sabía responder a una pregunta que debería haber visto venir.
Por qué lo intenté
Dos motivos, uno decente y otro no.
El decente: llevaba dos años viendo cómo mis propios servicios se atascaban por cosas que no sabía explicar. Un servidor de modelos que corría al 30 % de utilización y nadie sabía por qué. Sabía perfilar un servicio en Go y leer un flame graph, pero en cuanto el problema bajaba por debajo del runtime, adivinaba. Quería dejar de adivinar.
El no tan decente: NVIDIA tiene del orden de 36.000 personas en ingeniería y todo el mundo que conozco quería entrar. No es una buena razón, pero me sostuvo seis semanas estudiando cosas que al principio no me divertían, así que no voy a fingir que no contó.
Una nota sobre el mercado español
Antes de seguir, algo que me habría gustado que alguien me dijera. En España hay poquísimas vacantes de este perfil comparadas con backend o datos, y buena parte de lo que ves en portales para grandes fabricantes de hardware son roles comerciales o de arquitectura de soluciones, no de ingeniería de producto. Lee la descripción entera antes de invertir un mes de preparación.
En mi caso el equipo no estaba en España y todo el proceso fue en remoto y en inglés, rondas técnicas incluidas. Si llevas años trabajando en castellano no es un detalle menor: explicar coalescencia de memoria en tu idioma es una cosa y hacerlo en inglés, bajo presión y compartiendo editor, es otra.
Cómo conseguí la entrevista
Sin referral. Me inscribí en frío por el portal de empleo y no supe nada durante once días. Luego hice la única cosa que probablemente importó: reescribí el tercio superior del currículum para que el trabajo de rendimiento fuera el titular, y no una viñeta enterrada bajo «microservicios».
Antes: «Construcción y mantenimiento de pipelines de eventos de alto rendimiento.»
Después: «Reducción de la latencia p99 de un pipeline de ingesta de 40.000 eventos/s de 180 ms a 34 ms reestructurando los buffers de lote y eliminando la reserva de memoria por mensaje.»
Mismo trabajo, misma experiencia, pero la segunda versión cuenta una historia consciente del hardware. Una semana después tenía una llamada con recruiting.
Ronda 1 — la llamada con recruiting (30 minutos)
Nada exótico. Mi reclutadora repasó mi trayectoria, me preguntó en qué quería trabajar y con qué disponibilidad, y —esto no me lo esperaba— me pidió que puntuara mi nivel de C++ del uno al diez.
Dije seis. Fue honesto y creo que ayudó. Me contestó que el equipo buscaba gente que pudiera llegar a ocho, no gente que ya estuviera en diez, y que el proceso iba a indagar en razonamiento de memoria a bajo nivel. Esa frase fue la información más útil de todo el proceso, porque me dijo exactamente qué estudiar el mes siguiente.
También me describió la forma del proceso: una entrevista técnica telefónica y después un onsite virtual. No quiso comprometerse con el número de rondas hasta que el equipo confirmara. El mío acabó en cinco rondas repartidas en unas cinco horas, y desde entonces he oído casos de cuatro y de seis.
Ronda 2 — la técnica telefónica y la pregunta detrás de la pregunta
Sesenta minutos, editor compartido, un entrevistador que claramente estaba escribiendo código en otra ventana los primeros minutos.
El problema era de arrays y flujos; el arquetipo es «dado un flujo grande de valores, mantén cierto agregado móvil de forma eficiente». Hice lo que seis años de condicionamiento me habían enseñado. Aclarar restricciones, explicar la versión ingenua O(n·k), encontrar la versión de una pasada en O(n) con una estructura auxiliar, escribirla limpia, repasar los casos límite. Terminé con catorce minutos de sobra y me sentí bien.
Entonces dijo: «Vale. Ahora imagina que el array tiene cien millones de elementos y que dispones de mil núcleos. ¿Cómo lo paralelizas?»
Me quedé bloqueado un instante porque mentalmente había archivado el problema como resuelto. Me recuperé con algo razonable —partir en bloques, calcular parciales por bloque, combinar— y él siguió empujando. ¿Cuánto cuesta el paso de combinación? ¿La operación es asociativa? ¿Qué pasa en las fronteras entre bloques con una ventana móvil? ¿Qué fracción real del tiempo de ejecución es la combinación?
Ahí entendí el proceso. En la mayoría de empresas, «hazlo más rápido» significa encontrar un algoritmo mejor. Aquí, la respuesta O(n) era la entrada: la entrevista empezaba después, y todo lo que vino trataba de cómo se reparte el trabajo sobre hardware que hace muchas cosas a la vez.
Pasé, pero por poco según mi propia estimación. Pedí feedback y me llegó una sola frase por la reclutadora: fundamentos algorítmicos sólidos, quieren ver más soltura en descomposición paralela. Una forma educada de decir: te falta una dimensión.
Las cuatro semanas intermedias
Tenía veintiséis días antes del onsite. Esto es lo que hice de verdad, ordenado por lo que más me rentó.
Primero la jerarquía de memoria, la GPU después. Dediqué la primera semana entera al comportamiento de la caché de CPU: líneas de caché, localidad espacial y temporal, por qué recorrer una matriz 2D por filas es dramáticamente más rápido que por columnas, falso compartido entre hilos. Fue la semana más rentable de toda la preparación, porque cada concepto de GPU que aprendí después resultó ser una variación de «dónde vive el dato y cuánto tiene que viajar».
Semánticas de C++, a propósito. Punteros crudos frente a referencias. Qué es exactamente un puntero colgante a nivel de memoria. Tiempo de vida de los objetos y RAII. Semántica de movimiento y cuándo se produce una copia silenciosa. std::unique_ptr frente a shared_ptr y el coste del contador atómico del segundo. Esto lo hice escribiendo programas pequeños y rompiéndolos a posta, que lleva más tiempo que leer y se fija unas cuatro veces mejor.
Fundamentos de arquitectura de GPU. Warps y por qué una rama que diverge dentro de un warp te cuesta caro. Ocupación y por qué más hilos no es automáticamente mejor. Memoria global frente a compartida. Coalescencia, el concepto más importante de todo el bloque. La transferencia host-dispositivo como coste de primera clase. Y preguntarse siempre si un kernel está limitado por cómputo o por ancho de banda antes de optimizar nada.
Simulacros, y lo concreto que me arreglaron. Hice cuatro entrevistas simuladas en PhantomCodeAI a lo largo de dos semanas, y el patrón que salió todas y cada una de las veces fue el mismo: resolvía bien la mitad algorítmica y me quedaba en silencio cuando la pregunta giraba hacia el hardware. No equivocado: callado. Estaba razonando en silencio y solo hablaba al llegar a una conclusión, lo cual en una entrevista se lee como «no lo sabe». Verlo en tres transcripciones seguidas me convenció más que cualquier consejo de un amigo.
Lo que no hice: más LeetCode. Resolví unos diez problemas en cuatro semanas, básicamente para no oxidarme. Si vienes de un ciclo normal de preparación para grandes tecnológicas, tu nivel de algoritmos probablemente ya es suficiente y tu cuello de botella está en otro sitio.
El onsite — cinco rondas, unas cinco horas
El mío fueron cinco rondas virtuales seguidas con dos pausas cortas. El orden y la composición varían por equipo, así que léelo como mi proceso y no como el proceso.
Ronda 1 — algoritmos, tirando a difícil. Un problema de grafos y recorrido con una restricción incómoda de memoria. De forma, estándar. El giro estaba otra vez en la segunda mitad: dado que el grafo no cabe en caché, ¿cómo lo dispondrías en memoria para reducir fallos? Quince minutos comparando listas de adyacencia con disposiciones planas al estilo CSR. Un mes antes no habría tenido nada que decir.
Ronda 2 — C++ y memoria. La ronda más directa del proceso y, curiosamente, la que más disfruté. Arquetipos: aquí tienes una clase pequeña, dime todos los sitios por los que puede haber fuga o doble liberación. Qué evalúa esta aritmética de punteros y por qué. Qué diferencia hay entre pasar por valor, por referencia y por puntero. Dónde vive este objeto y cuándo muere. No había ninguna astucia en toda la ronda: era una comprobación de competencia pura y dura, y es completamente aprendible.
Ronda 3 — la que casi me deja fuera. GPU y paralelismo. El enunciado era una carga de transformación de datos y la pregunta era cómo la llevaría a una GPU y cómo la haría rápida.
Empecé describiendo un kernel. Indexado de hilos, dimensiones de bloque, la mecánica. El entrevistador me dejó ir unos noventa segundos y luego dijo, con amabilidad: «Me estás contando cómo se escribe. Yo quiero saber cómo se comporta la memoria.»
Ahí me quedé en silencio lo que mi grabación confirmó después que fueron once segundos.
Lo que me salvó fue uno de los conceptos que había machacado: la coalescencia. Reinicié desde el dato. Dije, en voz alta y despacio, que la pregunta importante era si hilos adyacentes leen direcciones adyacentes, porque si lo hacen el hardware sirve las lecturas de un warp en pocas transacciones, y si no, el mismo trabajo lógico se convierte en varias veces el tráfico de memoria. Después dije que el patrón de acceso de la versión ingenua es con salto, así que reestructuraría los datos —de array de estructuras a estructura de arrays— antes de tocar el kernel. Y luego pregunté si la carga estaba limitada por ancho de banda, porque si lo estaba, ningún ajuste del kernel serviría hasta arreglar las transferencias.
Se le notó el alivio. El resto de la ronda lo dedicamos a tiling en memoria compartida y a si la copia host-dispositivo se comería toda la ganancia para una única pasada sobre los datos. La respuesta era que sí, que es exactamente la razón por la que o mantienes los datos residentes o no merece la pena.
Sigo pensando que perdí puntos ahí. También creo que reiniciar desde otro nivel de abstracción, en voz alta, la rescató. Los entrevistadores miran cómo te recuperas, y «déjame atacarlo desde el lado de la memoria» es mucho mejor que seguir hablando de índices de hilo.
Ronda 4 — diseño. No una ronda clásica de diseño de sistemas web. Se parecía más a arquitectura de pipeline: cómo se mueven los datos por un sistema heterogéneo, dónde amortiguas, dónde agrupas, cómo mantienes alimentado un acelerador en lugar de ocioso, y qué componente fija tu techo de rendimiento. Si tu preparación de diseño es toda balanceadores y particionado, ensánchala; los fundamentos del banco de preguntas de diseño de sistemas siguen aplicando, pero la presión estará en el movimiento de datos y no en la topología de servicios.
Ronda 5 — hiring manager. Comportamental, más blanda de lo que esperaba, pero con una pregunta afilada: cuéntame un problema de rendimiento que no resolviste. Le conté la verdad sobre el servidor de modelos al 30 %, incluida la parte en la que asumí que era la red y me equivoqué. Pareció más interesado en esa respuesta que en cualquiera de mis historias de éxito.
El debrief y la oferta
Nueve días de silencio, convencido de que la ronda 3 me había hundido. Después una llamada: el proceso salía positivo en conjunto, con una ronda marcada como mixta. Mi reclutadora no dijo cuál. Yo sé cuál.
La conversación de oferta fue directa y poco memorable, en el mejor sentido. Sí negocié: pregunté educadamente si había margen, y pregunté más sobre nivel y alcance del equipo que sobre la cifra de portada, porque no tenía ninguna oferta competidora ni forma honesta de fingir que la tenía. Algunas cosas se movieron y otras no. Nadie se puso raro por que preguntara.
No voy a publicar números, pero sí dos cosas que en España confunden a mucha gente. Las multinacionales de este tipo suelen pagar en doce pagas, no en catorce, así que si vienes de una empresa española tienes que normalizar antes de comparar nada. Y si aparece un componente en acciones, dedica tiempo real a entender el calendario de consolidación y la política de refresco: fuera de las grandes tecnológicas es raro en el mercado local y es fácil valorarlo mal en las dos direcciones.
Lo que volvería a estudiar, en orden
Si tuviera que repetir esas cuatro semanas, las gastaría casi igual, con un cambio: empezaría los simulacros en la semana uno y no en la tres, porque lo que me dijeron fue qué fallaba en mi forma de responder cuando todavía tenía tiempo de arreglarlo.
- Jerarquía de memoria y comportamiento de caché. Líneas de caché, localidad, falso compartido, por qué el orden del bucle cambia el tiempo de ejecución en un orden de magnitud. Todo lo demás se apoya en esto.
- Coalescencia de memoria. Si vas a aprender un solo concepto específico de GPU, que sea este. «¿Acceden hilos contiguos a direcciones contiguas?» responde a una fracción sorprendente de las repreguntas de este proceso.
- Punteros y tiempos de vida en C/C++. Punteros colgantes, propiedad, RAII, mover frente a copiar, el coste real de un
shared_ptr. Espera preguntas directas, no incidentales. - Modelo de ejecución de la GPU. Warps, divergencia, ocupación, memoria compartida, coste de transferencia host-dispositivo. Lo suficiente para razonar, no para publicar.
- Limitado por cómputo frente a limitado por ancho de banda. Practica decir cuál de los dos es una carga, y por qué, antes de proponer cualquier optimización.
- Responder bien a «hazlo más rápido». En casi todas partes eso significa una estructura de datos mejor; aquí suele significar la máquina. Si no distingues cuál te piden, pregunta: «¿quieres que ataque el algoritmo o el patrón de acceso?» es una aclaración legítima y cae bien.
Añadiría un séptimo punto que no es técnico: si el proceso va a ser en inglés, ensaya en inglés desde el primer día. Yo hice las últimas tres sesiones de práctica en PhantomCodeAI directamente en inglés y grabadas, y descubrí que mi vocabulario técnico en inglés era correcto pero mi narración se volvía telegráfica bajo presión, que es justo lo que un entrevistador interpreta como inseguridad.
Lo que sigo pensando
No era el candidato más fuerte en algoritmos de aquel proceso. Lo que tenía eran cuatro semanas de aprender deliberadamente un solo eje —cómo se comporta el código sobre hardware real— y la disposición a decir «no lo sé, déjame razonarlo desde la memoria» en lugar de farolear.
Si eres un ingeniero competente de backend mirando una oferta de este tipo y te dices que no puedes presentarte porque nunca has escrito un kernel: la distancia es menor de lo que parece, y es de lectura, no de experiencia. Cuatro semanas de jerarquía de memoria, semánticas de C++ y un concepto muy bien entendido llamado coalescencia fueron, en mi caso, suficientes.
Preguntas frecuentes
¿Hace falta experiencia con CUDA para pasar la entrevista de software de NVIDIA?En el puesto que hice yo, cercano a sistemas, no hizo falta, pero sí hay que saber razonar en voz alta sobre hardware paralelo. Nadie me pidió escribir un kernel de producción de memoria. Me preguntaron qué le pasa al tráfico de memoria cuando hilos contiguos leen direcciones no contiguas, y si mi problema estaba limitado por cómputo o por ancho de banda. Eso se aprende en semanas; diez años de experiencia enviando código GPU a producción, no.
¿En qué se diferencia el proceso de NVIDIA de un proceso FAANG estándar?Las rondas de estructuras de datos y algoritmos se parecen bastante a las de cualquier gran tecnológica. La diferencia está en la segunda mitad de cada pregunta. En la mayoría de empresas, hazlo más rápido significa buscar una estructura de datos mejor. Aquí suele significar la máquina: líneas de caché, jerarquía de memoria, falso compartido, divergencia de hilos, throughput frente a latencia. Misma pregunta, eje de mejora distinto.
¿Se puede hacer este proceso desde España?Yo lo hice íntegramente en remoto desde España y todas las rondas fueron en inglés. Lo que sí conviene mirar con lupa es dónde reside realmente el equipo, porque en mi caso el equipo no estaba en España y eso condiciona horario, viajes y expectativa de presencialidad. Pregúntalo en la primera llamada con recruiting, no en la última.
¿Qué estudio si vengo de backend o de desarrollo de aplicación?Tres cosas y en este orden. Punteros, tiempos de vida y propiedad en C/C++, porque te lo van a preguntar de forma directa. Comportamiento de la jerarquía de memoria: líneas de caché, localidad, coalescencia y por qué el mismo bucle es diez veces más lento si intercambias los índices. Y el modelo de ejecución de una GPU: warps, ocupación, memoria compartida y el coste de mover datos entre host y dispositivo. Son unas semanas de lectura enfocada, no un cambio de carrera.
¿Cómo funciona la parte salarial en un proceso así desde España?No voy a publicar cifras concretas porque un paquete individual es un pésimo indicador para otra persona con otro nivel, otra ubicación y otra vacante. Sí diré lo que sorprende a mucha gente en España: las multinacionales tecnológicas suelen pagar en doce pagas y no en catorce, así que comparar el bruto anual con una oferta local de catorce pagas exige normalizar antes. Y si hay acciones, pregunta por el calendario de consolidación y por la política de refresco, que en el mercado español no es un componente habitual y mucha gente lo valora mal.