Node.js
Event loop, streams, modules, worker threads, and Node.js runtime internals asked in backend interviews.
Fundamentals
What is Node.js
Node.js is a JavaScript runtime built on V8 with libuv for non-blocking I/O — letting us run JS outside the browser, mainly on servers.
Event Loop Deep Dive
The 6 phases of Node's event loop, microtasks (process.nextTick, Promises), and how it all schedules our async work.
Non-blocking I/O
How libuv's thread pool + OS async APIs let single-threaded Node handle thousands of concurrent operations.
REPL & Node CLI
The interactive Node shell and the flags we actually use day-to-day — --inspect, --watch, -e, -p, --env-file.
Modules & Package Management
CommonJS vs ES Modules
require/module.exports vs import/export, the .cjs/.mjs extensions, dual packages, and the gotchas that bite us in production.
require Resolution Algorithm
How Node finds a module when we call require('x') — core modules, relative paths, node_modules tree walk, and file extension resolution.
package.json Fields
The fields that actually matter — main, module, exports, type, scripts, the three dependency buckets, and engines.
npm vs yarn vs pnpm
Three package managers, three install algorithms. Why pnpm is fastest, what lockfiles do, and how hoisting causes real bugs.
Core APIs
Buffer
Fixed-size binary data outside the V8 heap — what Node uses for files, sockets, crypto. Encodings, allocation, and common operations.
Streams & Backpressure
Readable, Writable, Duplex, Transform — how Node handles data that's too big for memory, and why backpressure matters.
File System
Reading, writing, and watching files with Node's fs module — sync, async, and promises.
Path & URL
Cross-platform path handling and URL parsing — including the ESM __dirname workaround.
Process & Env Vars
The process global — argv, env, exit codes, signals, and the dotenv pattern.
Async Patterns
Callbacks, Promises & async/await in Node
How async evolved in Node — from error-first callbacks to promisification to top-level await.
util.promisify
Converting error-first callback APIs into promise-returning functions.
EventEmitter
Node's pub/sub primitive — the base class behind streams, HTTP, and most of core.
HTTP & Networking
http module
Node's built-in HTTP server and client — the raw layer beneath Express.
HTTPS & TLS
Serving over TLS, mutual TLS, and the pitfalls of certificates in Node.
net & TCP
Raw TCP servers and clients with the net module — the layer below HTTP.
Concurrency & Scaling
Worker Threads
True parallelism in Node for CPU-bound work — when (and when not) to reach for them.
Cluster Module
Fork one Node process per CPU core to actually use all your cores. They share a port and the OS load-balances connections.
Child Process
Run external commands or scripts from Node — spawn for streams, exec for buffered output, fork for talking to another Node process.
Debugging & Performance
Debugging with --inspect
Node ships a real debugger built into the runtime. Attach Chrome DevTools or VS Code, set breakpoints, step through code, inspect variables.
Profiling & Heap Snapshots
Find which functions burn CPU and where memory is going. --prof for CPU, heap snapshots for memory, clinic.js for the easy mode.
Memory Leaks
Memory that should be freed but isn't. Caused by closures over big data, EventEmitter listener leaks, unbounded caches — and how to find them.
Production
Error Handling Patterns
try/catch around async, never swallow errors, listen for unhandledRejection and uncaughtException, and know when to crash vs recover.
Logging
console.log doesn't scale in production. Use a real logger that emits structured JSON with levels and contextual fields.
Process Managers (PM2)
Keep Node processes alive: restart on crash, restart on file change, run a cluster, manage logs. PM2 vs systemd vs Docker.
Graceful Shutdown
When the orchestrator says 'stop,' finish in-flight requests, close DB connections, then exit. Drop nothing on the floor.