BE
Backend Interview Preparation
What you need for a Backend (BE) tech interview:
Core Skills
- Strong understanding of at least one backend language (Node.js, Python, Java,
Go, etc.)
- Knowledge of RESTful API design and/or GraphQL
- Database fundamentals (SQL and/or NoSQL)
- Authentication, authorization, and security best practices
- Understanding of networking, HTTP, and web protocols
- Familiarity with cloud platforms or deployment (AWS, GCP, Azure, Docker, etc.)
Coding & Problem Solving
- Ability to solve algorithm and data structure problems
- Comfort with live coding and whiteboard exercises
- Debugging and performance optimization skills
- Experience with version control (Git)
- Familiarity with testing frameworks (unit, integration, E2E)
- CI/CD basics and deployment pipelines
Soft Skills
- Clear communication and ability to explain technical concepts
- Code review and collaboration experience
Interview Preparation
- Practice common BE interview questions (see the Q&A section)
- Build and review small projects or coding challenges
- Be ready to discuss trade-offs, best practices, and recent trends in backend
development
1 - Node.js Interview
Most Probable Node.js Interview Questions (2025)
Most Probable Node.js Interview Questions (2025) — with thorough answers
Curated and ordered by likelihood based on common interview patterns for React
engineers in 2024–2025. Answers are practical, detailed, and include pitfalls,
examples, and “when to use” guidance.
1) Explain Node.js’s event-driven, non-blocking I/O architecture
Node.js uses an event-driven, non-blocking I/O model. This means operations like
reading files, network requests, or database queries do not block the main
thread. Instead, Node.js delegates these tasks to the system and continues
executing other code. When the operation completes, a callback is triggered.
Benefits:
- Handles many concurrent connections efficiently
- Ideal for I/O-heavy applications (APIs, real-time apps)
Pitfall:
- Not suitable for CPU-bound tasks (see Q5)
Example:
fs.readFile('file.txt', (err, data) => {
if (err) throw err;
console.log(data);
});
// Code below runs immediately, not after file is read
2) What is the Node.js event loop and how does it work?
The event loop is the core mechanism that allows Node.js to perform non-blocking
I/O. It continuously checks for pending events (timers, I/O, callbacks) and
processes them in phases. When your code schedules async work (e.g., setTimeout,
fs.readFile), the event loop ensures callbacks run when the work is done.
Phases:
- Timers (setTimeout, setInterval)
- I/O callbacks
- Idle/prepare
- Poll (new I/O events)
- Check (setImmediate)
- Close callbacks
Example:
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
console.log('sync');
// Output order: sync, timeout OR immediate (order not guaranteed)
3) What is the difference between asynchronous and synchronous programming?
- Synchronous: Code executes line by line; each operation waits for the
previous one to finish. Blocking.
- Asynchronous: Operations can start and finish independently; code
continues running while waiting for results. Non-blocking.
Example:
// Synchronous
const data = fs.readFileSync('file.txt');
console.log(data);
// Asynchronous
fs.readFile('file.txt', (err, data) => {
console.log(data);
});
console.log('This runs before file is read');
4) How does Node.js handle multiple requests if it’s single-threaded?
Node.js runs JavaScript in a single thread, but uses background threads (via
libuv) for I/O. When a request comes in, Node.js delegates I/O work to the
system, freeing the main thread to handle more requests. Callbacks are queued
and processed by the event loop.
Key point:
- Node.js is single-threaded for JS, but multi-threaded for I/O under the hood.
5) What happens if you run CPU-heavy code in Node.js?
CPU-heavy code (e.g., image processing, large calculations) blocks the event
loop, preventing Node.js from handling other requests. This leads to poor
performance and unresponsive servers.
Solution:
- Offload CPU work to child processes, worker threads, or external services.
Example:
// Bad: blocks event loop
while (true) {
/* infinite loop */
}
// Good: use worker_threads
const { Worker } = require('worker_threads');
new Worker('./heavy-task.js');
6) What is the EventEmitter class?
EventEmitter is a core Node.js class that enables objects to emit and listen for
named events. It’s the foundation for many Node.js APIs (e.g., streams, HTTP
server).
Example:
const EventEmitter = require('events');
const emitter = new EventEmitter();
emitter.on('greet', (name) => console.log(`Hello, ${name}`));
emitter.emit('greet', 'Alice');
7) Explain middleware in Express.js
Middleware are functions that run during the request-response cycle in Express.
They can modify the request/response, end the request, or pass control to the
next middleware.
Types:
- Application-level, router-level, error-handling, built-in, third-party
Example:
app.use((req, res, next) => {
console.log('Request received');
next();
});
8) How do you scale Node.js applications?
- Use the cluster module to spawn multiple processes (one per CPU core)
- Use load balancers (e.g., Nginx, PM2)
- Use stateless design and externalize session/state
- Use microservices for large systems
Example:
const cluster = require('cluster');
if (cluster.isMaster) {
for (let i = 0; i < require('os').cpus().length; i++) {
cluster.fork();
}
} else {
// Worker process
require('./server');
}
9) What is the V8 engine?
V8 is Google’s open-source JavaScript engine, written in C++. It compiles
JavaScript to machine code for fast execution. Node.js uses V8 to run JavaScript
on the server.
Key features:
- Just-In-Time (JIT) compilation
- Used by Chrome and Node.js
10) What are callbacks and what is callback hell?
- Callback: A function passed as an argument to be executed later (e.g.,
after async work).
- Callback hell: Code becomes deeply nested and hard to read/maintain due to
many callbacks.
Solution:
- Use Promises or async/await for cleaner async code.
Example:
// Callback hell
fs.readFile('a.txt', (err, a) => {
fs.readFile('b.txt', (err, b) => {
fs.readFile('c.txt', (err, c) => {
// ...
});
});
});
// Promises
fs.promises
.readFile('a.txt')
.then((a) => fs.promises.readFile('b.txt'))
.then((b) => fs.promises.readFile('c.txt'));
11) What are Streams in Node.js?
Streams are objects for reading or writing data piece by piece (chunks), rather
than all at once. Useful for large files, network sockets, etc.
Types:
- Readable, Writable, Duplex, Transform
Example:
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
readStream.on('data', (chunk) => console.log(chunk));
process.nextTick() queues a callback to run after the current operation,
before the event loop continues.setImmediate() queues a callback to run on the next event loop iteration,
after I/O events.
Example:
process.nextTick(() => console.log('nextTick'));
setImmediate(() => console.log('immediate'));
console.log('sync');
// Output: sync, nextTick, immediate
13) What are global objects in Node.js?
Global objects are available in all Node.js modules without requiring imports.
Examples: global, process, __dirname, __filename, Buffer,
setTimeout, etc.
Pitfall:
- Avoid polluting the global namespace; prefer module scope.
14) What is the cluster module and how does it enable multi-threading?
The cluster module allows Node.js to create child processes (workers) that share
the same server port. Each worker runs in its own process, enabling multi-core
CPU usage. Communication is via IPC (inter-process communication).
Example:
const cluster = require('cluster');
if (cluster.isMaster) {
cluster.fork();
} else {
// Worker code
}
15) How do you prevent memory leaks in Node.js?
- Remove event listeners when no longer needed
- Avoid global variables for large objects
- Monitor memory usage (process.memoryUsage())
- Use tools like heapdump, clinic.js, or Chrome DevTools
Example:
emitter.removeAllListeners();
global.bigObject = null;
16) What are the security best practices for Node.js applications?
- Validate and sanitize user input
- Use HTTPS
- Avoid eval and insecure deserialization
- Use environment variables for secrets
- Keep dependencies up to date
- Use security linters (npm audit, snyk)
17) How do you debug Node.js applications?
- Use
console.log for simple debugging - Use the built-in Node.js debugger (
node inspect) - Use Chrome DevTools (
node --inspect) - Use logging libraries (winston, pino)
- Add breakpoints and step through code
Example:
// Start with inspect
node --inspect-brk app.js
// Open chrome://inspect in Chrome