Node Interview
Node Interview
Beginner Node.js
interview questions
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 3/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
For example
server.listen(3000, () => {
console.log('Server is running
});
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 4/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
require()
const fs = require('fs');
import :
For example
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 5/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
const fs = require('fs');
fs.readFile('example.txt', 'utf8
if (err) {
console.error(err);
return;
}
console.log(data);
});
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 6/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
math.js
function add(a, b) {
return a + b;
}
module.exports = add;
In app.js :
const fs = require('fs');
const readableStream = fs.create
readableStream.on('data', (chunk
console.log('Chunk received:',
});
readableStream.on('end', () => {
console.log('File reading comp
});
Intermediate Node.js
interview questions
In this example:
Using Callbacks
fs.readFile('file.txt', 'utf8',
if (err) {
console.error('Error reading
return;
}
console.log(data);
});
Using Promises
fs.promises.readFile('file.txt',
.then((data) => console.log(da
.catch((err) => console.error(
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 9/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
// Define routes
app.get('/', (req, res) => {
res.send('Welcome to the homep
});
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 10/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
How it works:
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 11/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
DB_HOST=localhost
DB_USER=root
DB_PASS=securepassword
require('dotenv').config();
It depends:
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 12/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
Advanced Node.js
interview questions
This section covers more complex topics, focusing
on optimization, scalability, and advanced concepts
in Node.js.
Here’s an example:
if (cluster.isMaster) {
const numCPUs = os.cpus().leng
for (let i = 0; i < numCPUs; i
cluster.fork(); // Create a
}
} else {
http.createServer((req, res) =
res.writeHead(200);
res.end('Hello, World!');
}).listen(3000);
}
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 13/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
In this setup:
if (isMainThread) {
const worker = new Worker('./w
worker.on('message', (msg) =>
} else {
parentPort.postMessage('Hello
}
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 14/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
while (true) {
// This loop blocks the event
}
For example:
https://zerotomastery.io/blog/node-js-interview-questions/#Advanced-Node-js-interview-questions 15/20
28/05/2025, 15:05 Node.js Interview Prep: Questions + Answers (With Code Examples) | Zero To Mastery
console.log('This runs before bo
Output:
. How does the event loop work in Node.js, and how is it different from the browser?
1
Explanation:
The Node.js event loop allows Node.js to perform non-blocking I/O operations despite
JavaScript being single-threaded. It does this by offloading operations to the system kernel or a
thread pool and running callbacks asynchronously in different phases.
Phases of the Node.js event loop:
setTimeout()and
1. Timers:Executes callbacks scheduled by setInterval() .
2. P
ending Callbacks:Executes some system-level callbacks deferred to the next loop
iteration.
setImmediate()
5. Check:Executes callbacks scheduled by .
socket.on('close')
6. Close Callbacks:Handles close events like .
● Browsers have extra phases related to UI rendering and user events.
● Node.js uses libuv under the hood for its event loop and asynchronous I/O handling.
xample:
E
console.log('start');
console.log('end');
utput:
O
start
end
nextTick
setTimeout
setImmediate
2. Explain the difference between process.nextTick, setImmediate, and setTimeout.
● process.nextTick()
○ R
uns callbacks immediately after the current operation completes, before the
event loop continues.
● setImmediate()
○ Runs callbacks in the “check” phase of the event loop, after the poll phase.
○ S
chedules callback to run in the timers phase, with a minimum delay (usually
around 1-2 ms).
Summary:
process.nextTi A
fter current operation, before event efore event loop
B Highest
ck
loop continues continues
setImmediate
After poll phase Check phase ediu
M
m
● U
seful for CPU-intensive tasks that would block the event loop (e.g., data processing,
image manipulation).
worker_threadsmodule.
● You create a worker thread with the
● Communication between main thread and workers is via message passing.
Example usage:
worker.postMessage('start');
4. How does Node.js handle asynchronous operations under the hood?
● Node.js relies onlibuv, a C library that providesa thread pool and handles async I/O.
● I/O operations like file reading, network calls are offloaded to the thread pool or system
kernel.
● When I/O completes, the callback is queued to the event loop for execution.
● N
ode.js uses the V8 JavaScript engine, which implementsgenerational garbage
collection.
● Major GC: cleans old generation less frequently (more expensive).
6. How do streams work in Node.js, and when would you use them?
● U
se streams when working with large files, network data, or any data that shouldn't be
buffered fully in memory.
Example:
onst fs = require('fs');
c
const readStream = fs.createReadStream('largefile.txt');
const writeStream = fs.createWriteStream('copy.txt');
readStream.pipe(writeStream);
7. What is the purpose of the cluster module, and how does it handle scaling?
● T
he cluster module allows creating multiple Node.js processes (workers) sharing the
same server port.
● Each worker runs in its own process and can handle a subset of requests.
● The master process manages workers and can restart them if they crash.
Example:
if (cluster.isMaster) {
for (let i=0; i<numCPUs; i++) {
cluster.fork();
}
} else {
http.createServer((req, res) => {
res.end('Hello world');
}).listen(8000);
}
If you’re good so far, I can proceed withPerformance and Optimizationsection next.
Let me know!
Section 2: Performance and Optimization
Common causes:
How to detect:
process.memoryUsage()
● Monitor process memory with .
How to fix:
Example:
emitter.on('event', () => {
console.log(hugeArray.length);
});
}
setInterval(leak, 1000);
Best practices:
● Leverage caching:Cache frequent data using Redisor in-memory cache with TTL.
● A
void blocking the event loop:Offload CPU-intensivetasks to worker threads or
external services.
● Efficient database queries:Use indexes, limit query results, and optimize joins.
● Profiling:Use tools like Clinic.js or Node.js built-in profiler to find bottlenecks.
. What are the trade-offs between child processes, worker threads, and
3
clustering?
ommunicatio
C IPC via messaging hared memory,
S IPC messaging
n message passing
winston
● Logging:Use structured logging (e.g., pino
, ) for tracing.
● APM tools:New Relic, Datadog, AppDynamics offer deep profiling and monitoring.
5. What are some ways to prevent blocking the event loop?
● Avoid heavy synchronous operations (e.g., large loops, sync file I/O).
setImmediateor
● Break large computations into smaller chunks and schedule with
process.nextTick
.
● Limit concurrency for tasks that can overload event loop.
rototype pollutionis an attack that modifies the prototype of built-in objects, leading to
P
unexpected behavior or security vulnerabilities.
ow it happens:
H
{"__proto__":
If user input is merged into objects without validation, malicious input like
{"isAdmin": true}}can pollute prototypes.
Prevention:
● alidate and sanitize user input before merging objects.
V
● lodashwith safe merge functions).
Use safe libraries (like
● Avoid merging user data directly into objects without checks.
● fast-safe-setor
Use packages like deepmergethat protect against prototype
pollution.
Upgrade dependencies regularly to patch vulnerabilities.
●
eval()pose in a Node.jsapp?
2. What security risks does
Risks:
R
● emote code execution if user input is passed unchecked.
● Difficult to audit or secure.
● Can lead to injection attacks.
Best Practice:
eval()altogether.
● Avoid
● Use safer alternatives like JSON parsing or dedicated expression evaluators.
3. How do you handle JWT authentication securely in a Node.js backend?
Best practices:
● Use strong secret keys or RSA key pairs for signing tokens.
● Avoid storing sensitive info in JWT payload (only non-sensitive claims).
Protection mechanisms:
U
● se CSRF tokens (random tokens in forms/requests).
● Validate origin or referer headers.
● Use SameSite cookies to restrict cross-site usage.
● T
ypically, REST APIs used with tokens (like JWT in Authorization headers) are not
vulnerable to CSRF, since tokens aren’t automatically sent by browsers.
● Use environment variables or secure vaults (HashiCorp Vault, AWS Secrets Manager).
Would you like me to continue with theCode Challenges/ Hands-on Exercisessection now?
just give for Code Challenges / Hands-on
Exercises
Here are detailed solutions for the Code Challenges / Hands-on Exercises section, each with a
clear explanation and code example.
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.handlers = [];
const resolve = (value) => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value;
this.handlers.forEach(h => h.onFulfilled(value));
};
const reject = (reason) => {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.value = reason;
this.handlers.forEach(h => h.onRejected(reason));
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
const handler = {
onFulfilled: value => {
if (!onFulfilled) return resolve(value);
try {
resolve(onFulfilled(value));
} catch (err) {
reject(err);
}
},
onRejected: reason => {
if (!onRejected) return reject(reason);
try {
resolve(onRejected(reason));
} catch (err) {
reject(err);
}
}
};
if (this.state === 'fulfilled') handler.onFulfilled(this.value);
else if (this.state === 'rejected') handler.onRejected(this.value);
else this.handlers.push(handler);
});
}
}
// Usage:
const tasks = Array.from({length: 10}, (_, i) => () =>
new Promise(res => setTimeout(() => { console.log(i); res(); }, 1000))
);
runWithConcurrencyLimit(tasks, 3); // Only 3 tasks run at once
3. Build a Simple Rate Limiter Middleware in Express
Explanation:
A rate limiter restricts the number of requests a client can make in a given time window.
Example:
class LRUCache {
constructor(limit) {
this.limit = limit;
this.cache = new Map();
}
get(key) {
if (!this.cache.has(key)) return -1;
const value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value); // Move to end (most recently used)
return value;
}
put(key, value) {
if (this.cache.has(key)) this.cache.delete(key);
else if (this.cache.size === this.limit) {
this.cache.delete(this.cache.keys().next().value); // Remove LRU
}
this.cache.set(key, value);
}
}
// Usage
const lru = new LRUCache(2);
lru.put('a', 1);
lru.put('b', 2);
lru.get('a'); // 1
lru.put('c', 3); // 'b' is evicted
lru.get('b'); // -1
5. Create an Async Queue That Processes Tasks with a Given Concurrency Limit
Explanation:
An async queue processes tasks, but only up to concurrency at a time.
Example:
class AsyncQueue {
constructor(concurrency) {
this.concurrency = concurrency;
this.running = 0;
this.queue = [];
}
push(task) {
this.queue.push(task);
this.next();
}
next() {
if (this.running >= this.concurrency || !this.queue.length) return;
const task = this.queue.shift();
this.running++;
task().then(() => {
this.running--;
this.next();
});
this.next();
}
}
// Usage
const queue = new AsyncQueue(2);
for (let i = 0; i < 5; i++) {
queue.push(() => new Promise(res => setTimeout(() => {
console.log('Task', i);
res();
}, 1000)));
}
These challenges are fundamental for Node.js interviews and backend engineering roles,
demonstrating deep understanding of asynchronous programming, middleware, and efficient
data structures [1] [2] [3] .
⁂
1. https://www.softlogicsys.in/node-js-coding-challenges-with-solutions-for-beginners/
2. https://dev.to/snyk/essential-nodejs-backend-examples-for-developers-in-2024-2j00
3. https://zerotomastery.io/blog/node-js-interview-questions/