Interview questions in Node.js & Express
How does Node.js handle thousands of connections on one thread?
This tests non-blocking I/O: Node.js runs one thread for an event loop while the OS handles sockets via epoll or IOCP, resuming callbacks when data arrives. Mention the thread pool for DNS and fs work. A red flag is claiming threads spawn per request.
Order of the Node.js event loop phases
Timers, pending callbacks, poll, check, close phases in order; I/O completion runs in poll.
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.
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.
dependencies vs devDependencies in package.json
Dependencies ship and run in production; devDependencies are only for development; omitted with npm install --production.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Output order of sync, microtask, and macrotask
C runs first synchronously, then B drains from the microtask queue, then A from the macrotask queue.
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.
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.
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.
Bounded concurrency for many async requests
Chunk the array and await Promise.all per chunk, or run a fixed worker pool pulling from a shared index; cap in-flight requests.
Promise.all vs Promise.allSettled
All rejects on the first failure; allSettled always fulfills with a status/value or reason per input. Use allSettled when partial success is acceptable.
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