Las entrevistas de Node.js giran alrededor del event loop, patrones asíncronos, Express o NestJS, y las consecuencias de un runtime de un solo hilo. Aquí están las preguntas más comunes con respuestas modelo.
Cada pregunta viene con una respuesta modelo con la que puedes comparar la tuya.
1
Explica el event loop en Node.js. ¿Cuáles son sus fases?
Respuesta
El event loop procesa repetidamente colas de operaciones completadas en fases: timers para setTimeout y setInterval, pending callbacks, poll para I/O entrante, check para setImmediate, y close callbacks. Entre cada fase Node vacía la cola de microtasks — primero process.nextTick, luego los callbacks de promises. Por eso una función síncrona larga bloquea cada request en el servidor: nada más puede correr hasta que retorne.
2
¿Cuál es la diferencia entre process.nextTick() y setImmediate()?
Respuesta
process.nextTick encola un callback para correr antes de que el event loop continúe a la siguiente fase, antes que las microtasks de promises. setImmediate programa el callback para la fase check de la siguiente iteración. Por eso nextTick siempre corre antes, y llamadas recursivas a nextTick pueden matar de hambre al event loop por completo, por eso setImmediate es el default más seguro para diferir trabajo.
3
¿Qué es una Promise? Explica Promise.all versus Promise.allSettled.
Respuesta
Una Promise representa un valor que estará disponible después y está ya sea pending, fulfilled, o rejected. Promise.all resuelve cuando cada input resuelve pero rechaza inmediatamente en el primer rechazo, descartando los otros resultados — justo cuando necesitas todos para continuar. Promise.allSettled siempre resuelve con un status y valor por cada entrada, lo que conviene para operaciones independientes donde una falla no debería cancelar el resto.
4
¿Cómo manejas errores en async/await? ¿Qué pasa en un unhandled rejection?
Respuesta
Envuelves las llamadas awaited en try/catch, o adjuntas .catch a la promise devuelta. En Express, un error lanzado dentro de un handler async no lo captura el framework a menos que lo reenvíes a next(), así que la mayoría de los equipos usa un wrapper o express-async-errors. Un unhandled rejection termina el proceso por defecto en Node moderno, lo cual es intencional — el proceso está en un estado desconocido y debería reiniciarse.
5
¿Qué son los streams y cuándo los usas en vez de leer un archivo completo?
Respuesta
Los streams procesan datos en chunks, así que el uso de memoria se mantiene constante sin importar el tamaño del payload y el primer byte puede enviarse antes de leer el último. Leer un archivo de dos gigabytes en un Buffer agota la memoria y demora la respuesta; hacer pipe lo transmite directo al cliente. Los streams también se componen a través de pipe o pipeline, dejándote encadenar descompresión, transformación, y salida con el backpressure manejado por ti.
6
¿Qué es el middleware en Express? ¿Cómo funciona next()?
Respuesta
El middleware es una función que recibe request, response, y next, ejecutada en orden de registro para formar un pipeline. Llamar a next() pasa el control al siguiente middleware; no llamarlo y no enviar una respuesta deja el request colgado. Pasar un argumento a next() salta directo al middleware de manejo de errores, que se reconoce por tener cuatro parámetros.
7
¿Cómo maneja Node las tareas intensivas en CPU? ¿Qué son los worker threads?
Respuesta
Como JavaScript corre en un solo hilo, un cómputo pesado en CPU bloquea cada request pendiente. Los worker threads corren JavaScript en hilos paralelos dentro del mismo proceso, comunicándose por paso de mensajes y shared array buffers, lo que conviene para hashing, procesamiento de imágenes, o parsing. Las alternativas son delegar a un servicio separado o una cola de trabajos — clustering solo agrega procesos y no hace más rápido un solo request.
8
¿Qué es un JWT? ¿Dónde lo guardas y cuáles son los riesgos?
Respuesta
Un JWT es un token firmado que lleva claims, así que el servidor puede autenticar un request sin una búsqueda de sesión. Guardarlo en localStorage lo expone a XSS; guardarlo en una cookie httpOnly, Secure, SameSite protege contra XSS pero requiere defensa contra CSRF. El trade-off más profundo es la revocación: un token stateless sigue siendo válido hasta que expira, así que los sistemas sensibles usan access tokens de vida corta con refresh tokens y una denylist del lado del servidor.
9
¿Cuál es la diferencia entre require e import? ¿Qué son CommonJS y ESM?
Respuesta
CommonJS require es síncrono, resuelto en runtime, y se puede llamar condicionalmente dentro de una función. ESM import es estático, hoisted, y se analiza antes de la ejecución, lo que habilita tree shaking y top-level await. Un paquete declara su formato con "type": "module" o las extensiones .mjs y .cjs; ESM puede importar CommonJS, pero al revés necesita un import() dinámico porque require no puede cargar un grafo de módulos async.
10
¿Cómo implementas un graceful shutdown?
Respuesta
Con SIGTERM dejas de aceptar nuevas conexiones con server.close(), dejas que terminen los requests en vuelo, luego cierras los pools de base de datos, consumidores de mensajes, y timers antes de salir. Un timeout fuerza la salida si algo se cuelga, así que el contenedor nunca queda atascado. Sin esto, un deploy mata requests a mitad de camino y puede dejar transacciones o mensajes de cola en un estado inconsistente.