Node.js-Interviewfragen für Senior Backend Entwickler

Milad Bonakdar
Autor
Bereiten Sie sich mit 30 praxisnahen Fragen zu Event Loop, Streams, API-Sicherheit, Systemdesign, Skalierung, Performance, Testing und Produktionsverantwortung auf Senior-Node.js-Backend-Interviews vor.
Node.js-Interviewfragen für Senior Backend Entwickler
In Senior-Node.js-Interviews geht es selten nur um Syntax. Rechnen Sie mit Fragen dazu, wie Sie Event-Loop-Verhalten, Backpressure, API-Grenzen, verteilte Systeme, Observability, Sicherheit und Produktions-Tradeoffs erklären. Starke Antworten verbinden Node.js-Interna mit Entscheidungen aus echten Services.
Nutzen Sie diese 30 Fragen, um präzise Antworten auf Senior-Niveau zu üben. Bereiten Sie zu jedem Thema ein Beispiel aus Ihrer Arbeit vor: eine Skalierungsentscheidung, ein Performance-Problem, einen Zuverlässigkeitsvorfall oder einen Architektur-Tradeoff, den Sie klar erklären können.
Fortgeschrittene Node.js-Konzepte (10 Fragen)
1. Erklären Sie die Node.js Event Loop im Detail. Welche verschiedenen Phasen gibt es?
Antwort: Die Event Loop ermöglicht Node.js nicht-blockierende I/O, während JavaScript standardmäßig auf einem Hauptthread läuft. Wartende oder teure Arbeit wird vom Betriebssystem oder von libuv übernommen; danach werden Callbacks für JavaScript eingeplant.
- Timers: Führt Callbacks von
setTimeout()undsetInterval()aus. In modernen Node.js-Versionen kann Arbeit in der Poll-Phase das Timing beeinflussen. - Pending Callbacks: Führt bestimmte systemnahe I/O-Callbacks aus, die auf die nächste Iteration verschoben wurden.
- Idle, Prepare: Interne libuv-Phasen.
- Poll: Holt neue I/O-Ereignisse ab und führt I/O-Callbacks aus. Ist die Queue leer, wartet Node.js auf I/O oder wechselt weiter, wenn
setImmediate()-Callbacks anstehen. - Check: Führt
setImmediate()-Callbacks aus. - Close Callbacks: Führt Close-Handler wie
socket.on('close', ...)aus.
Eine Senior-Antwort erwähnt außerdem Microtask-Queues: process.nextTick() läuft vor Promise-Microtasks, und beide laufen bevor die Event Loop fortgesetzt wird. Zu viel davon kann I/O ausbremsen.
Seltenheit: Sehr häufig Schwierigkeit: Schwer
2. Was ist der Unterschied zwischen process.nextTick() und setImmediate()?
Antwort:
process.nextTick(): Es ist kein Teil der Event Loop. Es wird sofort nach Abschluss der aktuellen Operation ausgelöst, aber bevor die Event Loop fortfährt. Es hat eine höhere Priorität alssetImmediate(). Übermäßiger Gebrauch kann die Event Loop blockieren (Starvation).setImmediate(): Es ist Teil der Check-Phase der Event Loop. Es wird nach der Poll-Phase ausgeführt.
Seltenheit: Häufig Schwierigkeit: Mittel
3. Wie handhabt Node.js Concurrency, wenn es Single-Threaded ist?
Antwort: Node.js verwendet ein ereignisgesteuertes, nicht-blockierendes I/O-Modell.
- Main Thread: Führt JavaScript-Code aus (V8-Engine).
- Libuv: Eine C-Bibliothek, die die Event Loop und einen Thread-Pool bereitstellt (standardmäßig 4 Threads).
- Mechanismus: Wenn eine asynchrone Operation (wie Datei-I/O oder Netzwerkanfrage) initiiert wird, lagert Node.js diese an Libuv aus. Libuv verwendet seinen Thread-Pool (für Datei-I/O, DNS) oder asynchrone Mechanismen des Systemkerns (für Netzwerk). Wenn die Operation abgeschlossen ist, wird der Callback in die Event-Loop-Warteschlange verschoben, um vom Main Thread ausgeführt zu werden.
Seltenheit: Häufig Schwierigkeit: Mittel
4. Erklären Sie Streams in Node.js und ihre Typen.
Antwort: Streams sind Objekte, mit denen Sie Daten aus einer Quelle lesen oder Daten in kontinuierlichen Blöcken in ein Ziel schreiben können. Sie sind speichereffizient, da Sie nicht die gesamten Daten in den Speicher laden müssen.
- Typen:
- Readable: Zum Lesen von Daten (z. B.
fs.createReadStream). - Writable: Zum Schreiben von Daten (z. B.
fs.createWriteStream). - Duplex: Sowohl lesbar als auch schreibbar (z. B. TCP-Sockets).
- Transform: Duplex-Streams, bei denen die Ausgabe basierend auf der Eingabe berechnet wird (z. B.
zlib.createGzip).
- Readable: Zum Lesen von Daten (z. B.
Seltenheit: Häufig Schwierigkeit: Mittel
5. Was ist Backpressure in Streams und wie handhaben Sie sie?
Antwort: Backpressure entsteht, wenn ein Readable-Stream schneller Daten produziert, als die Writable-Seite sie verarbeiten kann. Wer das ignoriert, lässt Puffer wachsen, belastet die Garbage Collection und riskiert Speicherprobleme.
stream.pipeline()oderpipelineausnode:stream/promisesnutzen: Damit werden Streams verbunden, Fehler weitergegeben und Ressourcen sauber aufgeräumt..write()respektieren: Gibt esfalsezurück, warten Sie aufdrain, bevor Sie weiter schreiben.- Vorsichtig tunen:
highWaterMarkkann helfen, sollte aber nur mit Messung erhöht werden. - Bei Uploads: Direkt in Object Storage oder eine Verarbeitungspipeline streamen, statt ganze Dateien im Speicher zu puffern.
Seltenheit: Mittel Schwierigkeit: Schwer
6. Wie funktioniert das cluster-Modul?
Antwort:
Da Node.js Single-Threaded ist, läuft es auf einem einzelnen CPU-Kern. Mit dem cluster-Modul können Sie Child-Prozesse (Worker) erstellen, die sich denselben Server-Port teilen.
- Master-Prozess: Verwaltet die Worker.
- Worker-Prozesse: Jeder führt eine Instanz Ihrer Anwendung aus.
- Vorteil: Ermöglicht Ihnen die Nutzung aller verfügbaren CPU-Kerne, wodurch der Durchsatz erhöht wird.
Seltenheit: Häufig Schwierigkeit: Mittel
7. Worker Threads vs. Cluster-Modul: Wann sollte man was verwenden?
Antwort:
- Cluster: Erstellt separate Prozesse. Jeder hat seinen eigenen Speicherbereich und seine eigene V8-Instanz. Am besten geeignet für die Skalierung von HTTP-Servern (I/O-gebunden).
- Worker Threads: Erstellt Threads innerhalb eines einzelnen Prozesses. Sie teilen sich den Speicher (über
SharedArrayBuffer). Am besten geeignet für CPU-intensive Aufgaben (z. B. Bildverarbeitung, Kryptografie), um die Main Event Loop nicht zu blockieren.
Seltenheit: Mittel Schwierigkeit: Schwer
8. Wie behandeln Sie Uncaught Exceptions und Unhandled Promise Rejections?
Antwort:
- Uncaught Exception: Lauschen Sie auf
process.on('uncaughtException', cb). Es ist normalerweise am besten, den Fehler zu protokollieren und den Prozess neu zu starten (mit einem Prozessmanager wie PM2), da der Anwendungsstatus beschädigt sein könnte. - Unhandled Rejection: Lauschen Sie auf
process.on('unhandledRejection', cb). - Best Practice: Verwenden Sie immer
try/catch-Blöcke und.catch()bei Promises.
Seltenheit: Häufig Schwierigkeit: Einfach
9. Welche Rolle spielt package-lock.json?
Antwort: Es beschreibt den exakten Baum, der generiert wurde, sodass nachfolgende Installationen identische Bäume generieren können, unabhängig von zwischenzeitlichen Abhängigkeitsaktualisierungen. Es stellt sicher, dass Ihr Projekt auf jedem Rechner (CI/CD, andere Entwickler) genau gleich funktioniert.
Seltenheit: Häufig Schwierigkeit: Einfach
10. Erklären Sie das Konzept der Middleware in Express.js.
Antwort:
Middleware-Funktionen sind Funktionen, die Zugriff auf das Request-Objekt (req), das Response-Objekt (res) und die nächste Middleware-Funktion im Request-Response-Zyklus der Anwendung (next) haben.
- Aufgaben: Code ausführen, req/res-Objekte ändern, den Request-Response-Zyklus beenden, die nächste Middleware aufrufen.
- Reihenfolge: Sie werden sequenziell in der Reihenfolge ausgeführt, in der sie definiert sind.
Seltenheit: Häufig Schwierigkeit: Einfach
Systemdesign & Architektur (10 Fragen)
11. Wie würden Sie eine Echtzeit-Chat-Anwendung entwerfen?
Antwort:
- Protokoll: WebSockets (mit
socket.iooderws) für Vollduplex-Kommunikation. - Backend: Node.js ist ideal, da es ereignisgesteuert ist und viele gleichzeitige Verbindungen verarbeiten kann.
- Skalierung:
- Redis Pub/Sub: Wenn Sie mehrere Serverinstanzen haben, muss ein Benutzer, der mit Server A verbunden ist, eine Nachricht an einen Benutzer auf Server B senden. Redis Pub/Sub fungiert als Message Broker, um Nachrichten über Server hinweg zu übertragen.
- Datenbank:
- Nachrichten: NoSQL (MongoDB/Cassandra) für hohen Schreibdurchsatz.
- Benutzer: Relational (PostgreSQL) oder NoSQL.
Seltenheit: Sehr häufig Schwierigkeit: Schwer
12. Microservices in Node.js: Kommunikationsmuster.
Antwort:
- Synchron: HTTP/REST oder gRPC. Gut für einfache Request/Response.
- Asynchron: Message Queues (RabbitMQ, Kafka, SQS). Gut für die Entkopplung von Diensten und die Handhabung von Lastspitzen.
- Event-Driven: Dienste senden Ereignisse aus, andere hören zu.
Seltenheit: Häufig Schwierigkeit: Mittel
13. Wie behandeln Sie verteilte Transaktionen (Saga-Muster)?
Antwort: In Microservices kann sich eine Transaktion über mehrere Dienste erstrecken. ACID ist schwer zu garantieren.
- Saga-Muster: Eine Sequenz lokaler Transaktionen. Jede lokale Transaktion aktualisiert die Datenbank und veröffentlicht ein Ereignis oder eine Nachricht, um die nächste lokale Transaktion in der Saga auszulösen.
- Kompensation: Wenn eine lokale Transaktion fehlschlägt, führt die Saga eine Reihe von kompensierenden Transaktionen aus, die die Änderungen rückgängig machen, die von den vorhergehenden lokalen Transaktionen vorgenommen wurden.
Seltenheit: Mittel Schwierigkeit: Schwer
14. Erklären Sie das Circuit Breaker-Muster.
Antwort: Es verhindert, dass eine Anwendung wiederholt versucht, eine Operation auszuführen, die wahrscheinlich fehlschlagen wird (z. B. Aufrufen eines ausgefallenen Microservice).
- Zustände:
- Geschlossen: Anfragen werden durchgelassen.
- Offen: Anfragen schlagen sofort fehl (Fast Fail), ohne den Dienst aufzurufen.
- Halb-Offen: Erlaubt eine begrenzte Anzahl von Anfragen, um zu überprüfen, ob sich der Dienst erholt hat.
Seltenheit: Mittel Schwierigkeit: Mittel
15. Wie sichern Sie eine Node.js-API?
Antwort: Eine starke Antwort beginnt mit Threat Modeling, nicht nur mit einer Paketliste. Für eine Node.js-API sollten Sie abdecken:
- Authentifizierung und Autorisierung: Identität prüfen, objektbezogene Rechte erzwingen und keine User- oder Tenant-IDs aus dem Client blind vertrauen.
- Input-Validierung: Typ, Format, Wertebereich, Content-Type und Request-Größe an der Grenze validieren, etwa mit Zod oder Joi.
- Transport und Header: HTTPS, sichere Cookies, CORS-Allowlists und Header über Helmet oder Plattformregeln verwenden.
- Missbrauchsschutz: Rate Limits, Timeouts, Body-Size-Limits und Reverse-Proxy-Schutz gegen langsame oder sehr viele Clients.
- Dependencies und Secrets: Abhängigkeiten locken, verwundbare Pakete überwachen, Secrets nicht in den Code legen und kompromittierte Zugangsdaten rotieren.
- Observability: Sicherheitsrelevante Fehler loggen, ohne sensible Daten preiszugeben.
Seltenheit: Häufig Schwierigkeit: Mittel
16. Was ist Serverless und wie passt es zu Node.js?
Antwort: Serverless (z. B. AWS Lambda) ermöglicht es Ihnen, Code auszuführen, ohne Server bereitzustellen oder zu verwalten.
- Node.js-Fit: Node.js eignet sich hervorragend für Serverless, da es eine schnelle Startzeit (Cold Start) und eine schlanke Natur hat.
- Anwendungsfälle: API-Endpunkte, Ereignisverarbeitung (S3-Uploads), geplante Aufgaben.
Seltenheit: Mittel Schwierigkeit: Mittel
17. Erklären Sie GraphQL vs. REST. Wann sollte man GraphQL verwenden?
Antwort:
- REST: Mehrere Endpunkte, Über- oder Unterabruf von Daten.
- GraphQL: Einzelner Endpunkt, Client fragt genau das an, was er benötigt.
- Verwenden Sie GraphQL: Wenn Sie komplexe Datenanforderungen haben, mehrere Clients (Web, Mobile) unterschiedliche Datenformen benötigen oder um Netzwerk-Roundtrips zu reduzieren.
Seltenheit: Häufig Schwierigkeit: Mittel
18. Wie implementieren Sie Caching in Node.js?
Antwort:
- In-Memory:
node-cache(gut für Single-Instanz, aber Daten gehen beim Neustart verloren und werden nicht geteilt). - Verteilt: Redis (Industriestandard).
- Strategien: Cache-Aside, Write-Through.
- HTTP-Caching: Verwenden Sie ETag-, Cache-Control-Header.
Seltenheit: Häufig Schwierigkeit: Mittel
19. Datenbank-Connection-Pooling.
Antwort: Das Öffnen einer neuen Datenbankverbindung für jede Anfrage ist teuer.
- Pooling: Verwaltet einen Cache von Datenbankverbindungen, die wiederverwendet werden können.
- Node.js: Bibliotheken wie
pg(PostgreSQL) odermongooseverwalten das Pooling automatisch. Sie müssen die Poolgröße basierend auf Ihrer Workload und den DB-Limits konfigurieren.
Seltenheit: Mittel Schwierigkeit: Mittel
20. Wie behandeln Sie Datei-Uploads in Node.js?
Antwort:
- Multipart/form-data: Die Standardcodierung für Datei-Uploads.
- Bibliotheken:
multer(Middleware für Express),formidable,busboy. - Speicher: Speichern Sie keine Dateien im Server-Dateisystem (Statelessness). Laden Sie sie in Cloud-Speicher wie AWS S3 hoch. Streamen Sie die Datei direkt zu S3, um zu vermeiden, dass sie in den Speicher geladen wird.
Seltenheit: Häufig Schwierigkeit: Mittel
Leistung & Tests (10 Fragen)
21. Wie debuggen Sie ein Memory Leak in Node.js?
Antwort:
- Symptome: Zunehmende Speichernutzung im Laufe der Zeit (RSS), eventueller Absturz.
- Tools:
- Node.js Inspector:
--inspect-Flag, verbinden Sie sich mit Chrome DevTools. - Heap Snapshots: Erstellen Sie Snapshots und vergleichen Sie sie, um Objekte zu finden, die nicht per Garbage Collection entfernt werden.
process.memoryUsage(): Überwachen Sie programmgesteuert.
- Node.js Inspector:
Seltenheit: Häufig Schwierigkeit: Schwer
22. Profiling von Node.js-Anwendungen.
Antwort: Profiling hilft, CPU-Engpässe zu identifizieren.
- Integrierter Profiler:
node --prof app.js. Generiert eine Protokolldatei. Verarbeiten Sie sie mitnode --prof-process isolate-0x...log. - Clinic.js: Eine Suite von Tools (
clinic doctor,clinic flame,clinic bubbleprof) zur Diagnose von Leistungsproblemen.
Seltenheit: Mittel Schwierigkeit: Schwer
23. Erklären Sie die Regel "Blockieren Sie die Event Loop nicht".
Antwort: Da es nur einen Thread gibt, stoppt die Event Loop, wenn Sie eine lang andauernde synchrone Operation ausführen (z. B. schwere Berechnung, synchrones Dateilesen, komplexer Regex). Es können keine anderen Anfragen verarbeitet werden.
- Lösung: Partitionieren Sie die Berechnung (setImmediate), verwenden Sie Worker Threads oder lagern Sie sie an einen Microservice aus.
Seltenheit: Sehr häufig Schwierigkeit: Einfach
24. Unit Testing vs. Integration Testing in Node.js.
Antwort:
- Unit Testing: Testen einzelner Funktionen/Module in Isolation. Mock-Abhängigkeiten. (Tools: Jest, Mocha, Chai).
- Integration Testing: Testen, wie Module zusammenarbeiten (z. B. API-Endpunkt + Datenbank). (Tools: Supertest).
Seltenheit: Häufig Schwierigkeit: Einfach
25. Was ist TDD (Test Driven Development)?
Antwort: Ein Entwicklungsprozess, bei dem Sie den Test vor dem Code schreiben.
- Schreiben Sie einen fehlschlagenden Test (Rot).
- Schreiben Sie den minimalen Code, um den Test zu bestehen (Grün).
- Refaktorieren Sie den Code (Refactor).
Seltenheit: Mittel Schwierigkeit: Mittel
26. Wie handhaben Sie die Protokollierung in einer Node.js-Produktionsanwendung?
Antwort: Produktions-Logging sollte strukturiert, durchsuchbar und sicher an Observability-Tools übergebbar sein.
- Logger verwenden: Pino, Winston oder einen Plattform-Logger statt verstreuter
console.log-Aufrufe. - Struktur: JSON mit Request-ID, sicheren User- oder Tenant-Hinweisen, Route, Status, Latenz und Fehlerdetails ausgeben.
- Levels: Error, Warn, Info und Debug konsistent nutzen.
- Redaktion: Keine Tokens, Passwörter, vollständigen Zahlungsdaten oder privaten Nutzerinhalte loggen.
- Korrelation: Logs mit Metriken und Traces verbinden, um Produktionsvorfälle über Services hinweg zu debuggen.
Seltenheit: Häufig Schwierigkeit: Einfach
27. Erklären Sie Semantic Versioning (SemVer).
Antwort:
Format: MAJOR.MINOR.PATCH (z. B. 1.2.3).
- MAJOR: Inkompatible API-Änderungen.
- MINOR: Abwärtskompatible Funktionalität.
- PATCH: Abwärtskompatible Fehlerbehebungen.
^vs.~:^1.2.3aktualisiert auf<2.0.0.~1.2.3aktualisiert auf<1.3.0.
Seltenheit: Häufig Schwierigkeit: Einfach
28. Was sind Umgebungsvariablen und wie verwalten Sie sie?
Antwort:
- Zweck: Konfiguration, die zwischen Umgebungen variiert (Dev, Staging, Prod) wie DB-URLs, API-Schlüssel.
- Verwendung:
process.env.VARIABLE_NAME. - Verwaltung:
.env-Dateien (mit demdotenv-Paket) für die lokale Entwicklung. In der Produktion legen Sie sie im Betriebssystem oder in den Container-/Plattformeinstellungen fest.
Seltenheit: Häufig Schwierigkeit: Einfach
29. Wie stellen Sie eine Node.js-Anwendung bereit?
Antwort:
- Prozessmanager: PM2 (hält die App am Leben, behandelt Neustarts, protokolliert).
- Reverse Proxy: Nginx (behandelt SSL, statische Dateien, Load Balancing) -> Node.js App.
- Containerisierung: Docker (Standard).
- Orchestrierung: Kubernetes.
- CI/CD: GitHub Actions, Jenkins.
Seltenheit: Häufig Schwierigkeit: Mittel
30. Was ist ein Event Emitter?
Antwort:
Das events-Modul ist der Kern der ereignisgesteuerten Architektur von Node.js.
- Verwendung:
- Viele Kernmodule erweitern es:
fs.ReadStream,net.Server,http.Server.
Seltenheit: Häufig Schwierigkeit: Einfach


