FroquizFroquiz
HomeQuizzesSenior ChallengeGet CertifiedBlogAbout
Sign InStart Quiz
Sign InStart Quiz
Froquiz

The most comprehensive quiz platform for software engineers. Test yourself with 10000+ questions and advance your career.

LinkedIn

Platform

  • Start Quizzes
  • Topics
  • Blog
  • My Profile
  • Sign In

About

  • About Us
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

Β© 2026 Froquiz. All rights reserved.Built with passion for technology
Blog & Articles

Node.js Interview Questions and Answers (2025): From Basics to Advanced

Prepare for your Node.js interview with the most asked questions. Covers the event loop, streams, modules, clustering, error handling, and real-world patterns.

Yusuf SeyitoğluMarch 11, 20263 views11 min read

Node.js Interview Questions and Answers (2025): From Basics to Advanced

Node.js powers some of the most high-traffic applications in the world β€” and it remains one of the most in-demand backend skills. Whether you are interviewing for a junior or senior Node.js role, this guide covers the questions you will almost certainly face.

What Is Node.js and Why Is It Different?

Q: What is Node.js?

Node.js is a JavaScript runtime built on Chrome's V8 engine. It lets you run JavaScript on the server side, outside of a browser.

What makes it different from traditional server platforms:

  • Non-blocking I/O β€” operations like file reads, database queries, and HTTP calls do not block the thread while waiting for results
  • Single-threaded event loop β€” handles thousands of concurrent connections without spawning a new thread per request
  • npm ecosystem β€” the largest package registry in the world

Q: What is the difference between Node.js and the browser JavaScript environment?

FeatureBrowserNode.js
Global objectwindowglobal
DOM accessYesNo
File systemNoYes (fs module)
HTTP serverNoYes (http module)
Module systemES ModulesCommonJS + ES Modules
process objectNoYes

The Event Loop

Q: How does the Node.js event loop work?

Node.js uses a single thread with a non-blocking event loop. When an async operation (file read, network call) is initiated, Node.js hands it off to the OS or a thread pool (via libuv), then continues executing other code. When the operation completes, its callback is queued and executed when the call stack is clear.

The event loop processes queues in this order each "tick":

  1. timers β€” setTimeout and setInterval callbacks
  2. pending callbacks β€” I/O callbacks deferred from previous tick
  3. idle/prepare β€” internal use
  4. poll β€” retrieve new I/O events, execute callbacks
  5. check β€” setImmediate callbacks
  6. close callbacks β€” socket close events

Q: What is the difference between setTimeout, setImmediate, and process.nextTick?

javascript
process.nextTick(() => console.log("nextTick")); setImmediate(() => console.log("setImmediate")); setTimeout(() => console.log("setTimeout"), 0); console.log("sync");

Output:

code
sync nextTick setTimeout setImmediate
  • process.nextTick runs before the event loop continues β€” even before I/O callbacks. Runs after current operation, before next event loop tick.
  • setTimeout(..., 0) runs in the timers phase
  • setImmediate runs in the check phase, after I/O

Caution: Recursive process.nextTick calls can starve the event loop. Use setImmediate for recursion in async operations.

Modules

Q: What is the difference between CommonJS and ES Modules?

CommonJS (the original Node.js module system):

javascript
const fs = require("fs"); const { helper } = require("./utils"); module.exports = { myFunction };

ES Modules (modern standard, supported in Node.js 12+):

javascript
import fs from "fs"; import { helper } from "./utils.js"; export function myFunction() {} export default myFunction;

Key differences: ES Modules are static (imports resolved at parse time), support tree-shaking, and are asynchronous. CommonJS is dynamic and synchronous. Use .mjs extension or "type": "module" in package.json for ES Modules.

Q: What is the difference between exports and module.exports?

exports is a reference to module.exports. Reassigning exports breaks the reference:

javascript
-- Works: adding properties to exports exports.add = (a, b) => a + b; -- Works: replacing module.exports entirely module.exports = { add: (a, b) => a + b }; -- Broken: reassigning exports variable exports = { add: (a, b) => a + b }; -- does nothing

Streams

Q: What are streams and why are they important in Node.js?

Streams process data in chunks rather than loading everything into memory at once. Critical for handling large files, network data, or any data larger than available RAM.

Four types of streams:

TypeDescriptionExample
ReadableSource of datafs.createReadStream()
WritableDestinationfs.createWriteStream()
DuplexBoth readable and writableTCP socket
TransformModify data as it passes throughzlib.createGzip()
javascript
const fs = require("fs"); const zlib = require("zlib"); -- Stream a large file, compress it, save β€” without loading it all into memory fs.createReadStream("large-file.txt") .pipe(zlib.createGzip()) .pipe(fs.createWriteStream("large-file.txt.gz")) .on("finish", () => console.log("Done"));

Without streams, reading a 4GB file would require 4GB of RAM. With streams, you process it in small chunks.

Error Handling

Q: What are the ways to handle errors in Node.js?

Synchronous errors β€” try/catch:

javascript
try { const data = JSON.parse(invalidJson); } catch (err) { console.error("Parse error:", err.message); }

Async callbacks β€” error-first convention:

javascript
fs.readFile("file.txt", (err, data) => { if (err) { console.error("Read failed:", err); return; } console.log(data.toString()); });

Promises:

javascript
fetchData() .then(process) .catch(err => console.error(err));

async/await:

javascript
async function load() { try { const data = await fetchData(); return process(data); } catch (err) { console.error("Failed:", err); } }

Unhandled rejections β€” always handle globally:

javascript
process.on("unhandledRejection", (reason, promise) => { console.error("Unhandled rejection:", reason); process.exit(1); }); process.on("uncaughtException", (err) => { console.error("Uncaught exception:", err); process.exit(1); });

Never silently swallow errors. An unhandled rejection can leave your app in an inconsistent state.

Clustering and Worker Threads

Q: Node.js is single-threaded. How do you use multiple CPU cores?

Cluster module β€” spawns multiple Node.js processes (workers), each with its own event loop, sharing the same port:

javascript
const cluster = require("cluster"); const os = require("os"); const http = require("http"); if (cluster.isPrimary) { const numCPUs = os.cpus().length; console.log(`Spawning ${numCPUs} workers`); for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on("exit", (worker) => { console.log(`Worker ${worker.process.pid} died, restarting...`); cluster.fork(); }); } else { http.createServer((req, res) => { res.end("Hello from worker " + process.pid); }).listen(3000); }

Worker Threads β€” run JavaScript in parallel threads, sharing memory via SharedArrayBuffer. Best for CPU-intensive tasks (image processing, crypto, data parsing):

javascript
const { Worker, isMainThread, parentPort } = require("worker_threads"); if (isMainThread) { const worker = new Worker(__filename); worker.on("message", result => console.log("Result:", result)); worker.postMessage({ numbers: [1, 2, 3, 4, 5] }); } else { parentPort.on("message", ({ numbers }) => { const sum = numbers.reduce((a, b) => a + b, 0); parentPort.postMessage(sum); }); }

Q: What is the difference between clustering and worker threads?

  • Cluster β€” multiple processes, each with its own memory. Great for scaling HTTP servers across CPUs.
  • Worker Threads β€” multiple threads in one process, can share memory. Great for CPU-intensive background work without blocking the event loop.

EventEmitter

Q: What is EventEmitter and how does it work?

EventEmitter is the core of event-driven programming in Node.js. Many built-in modules (streams, HTTP, fs) extend it.

javascript
const EventEmitter = require("events"); class OrderService extends EventEmitter { placeOrder(order) { -- process order... this.emit("orderPlaced", order); this.emit("inventoryNeeded", order.items); } } const service = new OrderService(); service.on("orderPlaced", (order) => { console.log("Send confirmation email for order", order.id); }); service.on("orderPlaced", (order) => { console.log("Update analytics for order", order.id); }); service.placeOrder({ id: 123, items: ["laptop"] });

Multiple listeners can subscribe to the same event. Use once() for one-time listeners. Use removeListener() or off() to clean up and avoid memory leaks.

Performance and Best Practices

Q: What are common Node.js performance mistakes?

Blocking the event loop β€” never run synchronous CPU-intensive code on the main thread:

javascript
-- Blocks the entire server for all users app.get("/report", (req, res) => { const result = generateHugeReport(); -- synchronous, CPU-heavy res.json(result); }); -- Correct: offload to worker thread or background job app.get("/report", async (req, res) => { const result = await generateReportInWorker(); res.json(result); });

Not streaming large responses:

javascript
-- Bad: loads entire file into memory app.get("/download", (req, res) => { const file = fs.readFileSync("huge-file.zip"); res.send(file); }); -- Good: streams directly to response app.get("/download", (req, res) => { fs.createReadStream("huge-file.zip").pipe(res); });

Practice Node.js on Froquiz

Node.js interview questions often combine runtime knowledge with JavaScript fundamentals. Test your skills on Froquiz across backend and JavaScript topics at all difficulty levels.

Summary

  • Node.js is single-threaded with a non-blocking event loop β€” I/O operations do not block
  • process.nextTick runs before I/O; setImmediate runs after I/O in the check phase
  • CommonJS uses require/module.exports; ES Modules use import/export
  • Streams process data in chunks β€” essential for large files and network data
  • Always handle errors: try/catch for sync, .catch() or try/catch with async/await for async
  • Cluster for multi-core HTTP scaling; Worker Threads for CPU-intensive tasks
  • Never block the event loop with synchronous CPU-heavy operations

About Author

Yusuf Seyitoğlu

Author β†’

Other Posts

  • GraphQL Schema Design: Types, Resolvers, Mutations and Best PracticesMar 12
  • CSS Advanced Techniques: Custom Properties, Container Queries, Grid Masonry and Modern LayoutsMar 12
  • Java Collections Deep Dive: ArrayList, HashMap, TreeMap, LinkedHashMap and When to Use EachMar 12
All Blogs