Everything in Backend Dev, page 8
Comparing the three async error-handling styles
Callbacks pass err as first arg; Promises route errors to catch; async/await uses try/catch; an unhandled rejection can crash the Node process.
Handling async errors in Express middleware
Await inside try/catch and call next(err) on failure, or wrap the handler in an async error adapter; never let a rejected Promise go uncaught.
Running independent requests with Promise.all and race
Start all requests then await Promise.all to get all results or fail fast on first rejection; use Promise.race when only the fastest settled result matters.
Output order of sync, microtask, and macrotask
C runs first synchronously, then B drains from the microtask queue, then A from the macrotask queue.
The three states of a JavaScript Promise
Pending, fulfilled, rejected; settle is one-way and final; create with the executor calling resolve or reject, consume with then and catch.
Monorepo workspaces vs private npm packages
Workspaces give atomic cross-service changes and instant local linking but couple release cadence; private packages give versioned isolation but add publish overhead and version drift.
Diamond dependencies and nested node_modules
Npm hoists one version to the top and nests the conflicting version under the dependent package; both coexist on disk.
Circular dependencies in CommonJS modules
When A requires B which requires A, the cache returns A's partial exports; fields defined later are undefined at that moment.
SemVer and the caret vs tilde range operators
MAJOR.MINOR.PATCH signals breaking/feature/fix; caret allows minor and patch updates, tilde allows only patch; use tilde for tighter control.
Layered structure for a scalable Express API
Routes map URLs, controllers handle HTTP, services hold business logic, data layer talks to the DB; keep each layer ignorant of HTTP except controllers.
Choosing between CommonJS and ES Modules
ESM is the standard with static import/export and top-level await; set type to module; CJS uses require and module.exports and is synchronous.
Why package-lock.json must be committed
Lockfile pins exact versions of the whole dependency tree including transitive deps; guarantees identical installs across machines and CI.
Resolving core vs relative module specifiers
'fs' is a built-in core module loaded by name with top priority; './my-file.js' is a relative path resolved from the current file.
dependencies vs devDependencies in package.json
Dependencies ship and run in production; devDependencies are only for development; omitted with npm install --production.
Offloading CPU-bound work with Worker Threads
Synchronous CPU work freezes the loop and all requests; offload to a Worker, communicate via messages or SharedArrayBuffer, use a pool.
nextTick vs setImmediate vs setTimeout(fn, 0)
NextTick is a microtask that drains before the loop continues; setImmediate runs in check; setTimeout(0) in timers.
Order of the Node.js event loop phases
Timers, pending callbacks, poll, check, close phases in order; I/O completion runs in poll.
The WebSocket Protocol
WebSocket (RFC 6455) is a protocol providing full-duplex, persistent communication over a single TCP connection. It begins as an HTTP request that upgrades, then both client and server can send messages anytime, enabling real-time apps without HTTP's…
Diagnosing high Redis eviction and cache misses
Use INFO memory and stats to confirm pressure, check fragmentation ratio, pick LFU over LRU for skewed access, set sane TTLs.
Modeling IoT data with tags and fields
Tags are indexed identifying metadata, fields are unindexed measured values, and tag cardinality drives memory.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles