RMRM Full Stack & AI Engineer · All questions · Roadmaps
Backend · interview questions

Node.js Interview Questions

Node.js is a server-side JavaScript runtime built on Chrome's V8 engine, known for its non-blocking, event-driven architecture. These questions cover core concepts, async patterns, streams, performance, security, and real-world usage commonly tested in backend and full-stack engineering interviews.

1. What is Node.js and how does it differ from browser JavaScript?

beginner

Node.js is a runtime that executes JavaScript outside the browser using Chrome's V8 engine. It provides server-side APIs (fs, http, path, etc.) instead of browser APIs (DOM, window), and it can handle file systems, networking, and processes directly.

2. What is the Event Loop in Node.js?

beginner

The Event Loop is the mechanism that allows Node.js to perform non-blocking I/O by offloading operations to the OS and processing callbacks when those operations complete. It cycles through phases: timers, pending callbacks, idle/prepare, poll, check, and close callbacks.

3. What is the difference between require() and import in Node.js?

beginner

require() is the CommonJS (CJS) module system, synchronous and available by default in Node.js. import is ES Module (ESM) syntax, which is asynchronous, statically analyzable, and supported in Node.js v12+ via .mjs files or "type":"module" in package.json.

4. What are the differences between process.nextTick(), setImmediate(), and setTimeout()?

intermediate

process.nextTick() fires before the next Event Loop iteration, after the current operation completes. setImmediate() fires in the check phase of the current Event Loop iteration. setTimeout(fn, 0) fires in the timers phase, which can be after setImmediate() depending on context.

5. What is the Node.js cluster module and why would you use it?

intermediate

The cluster module allows you to fork multiple child processes that share the same server port, enabling Node.js to take advantage of multi-core CPUs. Since Node.js is single-threaded, clustering is a common way to scale CPU-bound workloads and improve throughput.

6. Explain the difference between readable streams and writable streams in Node.js.

intermediate

A Readable stream is a source you consume data from (e.g., fs.createReadStream), while a Writable stream is a destination you write data to (e.g., fs.createWriteStream). They can be connected via pipe(), and Transform streams implement both interfaces simultaneously.

7. What is backpressure in Node.js streams?

advanced

Backpressure occurs when a writable stream cannot process data as fast as a readable stream produces it, causing memory build-up. Node.js streams handle this by returning false from write() when the internal buffer is full and emitting a 'drain' event when it's safe to write again.

8. What is the difference between synchronous and asynchronous error handling in Node.js?

beginner

Synchronous errors are caught with try/catch. Asynchronous errors in callbacks follow the error-first convention (cb(err, data)), while Promise-based and async/await code uses .catch() or try/catch. Unhandled rejections should be caught with process.on('unhandledRejection').

9. How does Node.js handle child processes, and what are the main methods?

intermediate

Node.js provides the child_process module with four main methods: spawn() for streaming I/O, exec() for buffered shell commands, execFile() for executing a file directly, and fork() for spawning Node.js processes with an IPC channel. Use spawn() for large outputs to avoid buffer overflow.

10. What are Worker Threads in Node.js and when should you use them?

advanced

Worker Threads (worker_threads module, stable since Node 12) run JavaScript in parallel OS threads, sharing memory via SharedArrayBuffer. They are ideal for CPU-intensive tasks (image processing, cryptography) where the Event Loop would otherwise block, unlike child processes which have separate memory spaces.

11. What is middleware in the context of Express.js?

beginner

Middleware are functions with the signature (req, res, next) that execute sequentially in a request-response cycle. They can read/modify the request or response, end the cycle, or pass control to the next middleware by calling next(). Common uses include logging, authentication, and parsing.

12. How would you prevent callback hell in Node.js?

beginner

Callback hell can be avoided by using named functions instead of anonymous nesting, adopting Promises with .then()/.catch() chaining, or using async/await for flat, readable asynchronous code. Modularizing code into smaller functions also reduces nesting depth.

13. Explain the module caching behavior in Node.js.

intermediate

When a module is first required, Node.js loads and executes it, then caches the exported object in require.cache. Subsequent require() calls for the same module return the cached instance without re-executing the file, making module singletons the default behavior.

14. What are some common Node.js security best practices?

intermediate

Key practices include: validating and sanitizing all user input, using helmet for HTTP security headers, avoiding eval() and child_process with user input, keeping dependencies updated (npm audit), using environment variables for secrets, and rate-limiting APIs to prevent DoS attacks.

15. What is the difference between app.use() and app.get() in Express?

beginner

app.use() mounts middleware or a router for all HTTP methods and optionally a path prefix (default '/'), matching any request whose path starts with it. app.get() registers a route handler only for HTTP GET requests on an exact path match.

16. How does Node.js manage memory, and what causes memory leaks?

advanced

Node.js uses V8's garbage collector with generational collection (new/old space). Common causes of memory leaks include global variables that grow indefinitely, uncleaned event listeners, closures holding large references, and unresolved Promises. Tools like --inspect, heapdump, and Clinic.js help diagnose them.

17. What is the purpose of the package-lock.json file?

beginner

package-lock.json records the exact resolved versions and dependency tree of all installed packages, ensuring deterministic installs across environments. It should be committed to version control; npm ci uses it exclusively to guarantee reproducible builds.

18. How would you implement rate limiting in a Node.js API?

intermediate

Rate limiting can be implemented using middleware libraries like express-rate-limit, which tracks requests per IP using an in-memory store or Redis for distributed systems. Redis-backed solutions (e.g., rate-limiter-flexible) are preferred in multi-instance deployments to share counters across nodes.

19. Explain how async_hooks can be used in Node.js.

advanced

The async_hooks module provides an API to track the lifecycle of asynchronous resources (init, before, after, destroy callbacks). It is used to implement context propagation (e.g., request-scoped logging, distributed tracing with AsyncLocalStorage) across async boundaries without modifying function signatures.

20. What is the difference between a hot and cold Observable, and how does this relate to Node.js streams?

advanced

Cold observables/streams produce data per subscriber (each consumer gets its own source), while hot ones share a single source among all consumers. Node.js Readable streams are cold by default—each pipe or read call gets its own read cycle—but can be made hot by using PassThrough or broadcasting via EventEmitter patterns.

Practice these out loud with an AI interviewer that grills you and grades your answers.
Open the app — free to start

© RM Full Stack & AI Engineer · All interview questions · Roadmaps · Open the app