Node.js
Node.js is a runtime that embeds the V8 engine and the libuv library so JavaScript can run on the server: files, networking, processes. The model is the same as in the browser — a single-threaded event loop — but on the server that single-threadedness turns from a background detail into the central constraint the whole architecture is built around.
Node shines for I/O-bound work: while it waits on the network or disk, the event loop serves thousands of other connections without blocking. And it is weak for CPU-bound work: one long synchronous function occupies the single thread and stalls all other requests until it finishes. From this grow four advanced topics: how the loop's phases work, how to step beyond one thread via worker_threads and child_process, how streams keep memory flat via backpressure, and how to shut a process down cleanly without dropping live requests. Each mechanism is broken down in the layers below.
Topic map
- The Node runtime — V8 plus
libuv, the single-threaded event loop, and why Node is good for I/O and poor for CPU. - Event loop phases — the ordered
libuvphases, microtasks, and wheresetImmediatesits versusprocess.nextTick. - Multi-core concurrency —
worker_threadsversuschild_process, and the cluster module for spreading across cores. - Streams and backpressure — the four stream types, chunked processing, and backpressure via
pipe. - Lifecycle and graceful shutdown — clean termination on
SIGTERMwith request draining and a timeout.
Common traps
| Mistake | Consequence |
|---|---|
| Running CPU-heavy synchronous work on the main thread | Blocks the event loop; all pending requests stall |
| Thinking Node is multi-threaded for application code | Expecting parallelism where there is none without workers or cluster |
Treating setImmediate as identical to setTimeout(0) | Different phases; at the top level the order is not guaranteed |
Thinking promise microtasks run before process.nextTick | process.nextTick drains first — a wrong model of ordering |
| Reading a large file wholly into memory | Memory grows with file size instead of staying flat via a stream |
| Ignoring backpressure | A fast source overruns a slow sink |
Exiting on SIGTERM immediately | Live requests are dropped, connections leak on redeploys |
Interview relevance
Node.js is the core of the backend section, and here it is the execution model — not API knowledge — that gets tested. A candidate who explains "the single thread serves I/O without blocking, but one CPU task stops it" immediately shows they grasp the essence rather than memorizing "Node is asynchronous".
Typical checks:
- Why Node is good for I/O and poor for CPU, and how not to block the event loop.
- The event loop phases and the order of
setImmediate/setTimeout(0)/process.nextTick. - The difference between
worker_threadsandchild_processand when to reach for each. - What streams and backpressure solve; what graceful shutdown is and why the timeout.
Common wrong answer: "Node is multi-threaded, heavy computation runs in parallel by itself". In fact application JavaScript runs on one thread; parallelism comes only from an explicit worker_threads, child_process, or cluster, and synchronous CPU work on the main thread freezes the whole server.