Introduction to Node.js
Node.js is a JavaScript runtime built on Chrome’s V8 engine, designed for building scalable, high-performance applications. Unlike traditional server-side languages, Node.js uses an event-driven, non-blocking I/O model, making it lightweight and efficient for real-time apps, APIs, and microservices.
This guide’ll break down Node.js’s core architecture, answer critical interview questions, and provide practical examples to solidify your understanding.
1. Node.js Architecture: The Pillars
1.1 Event-Driven Architecture
Node.js operates on an event loop that handles asynchronous operations. Instead of blocking threads, it delegates tasks like file I/O or network requests to the system kernel and processes callbacks once functions complete.
Key Components:
- Event Loop: Manages asynchronous callbacks (phases: timers, I/O, idle/prepare, poll, check, close).
- Worker Pool: Handles heavy tasks via
libuv
(e.g., file system operations). - Single-Threaded Model: Executes JavaScript code in a single main thread but leverages worker threads for I/O.
Real-World Analogy:
Imagine a coffee shop with one cashier (main thread). The cashier takes orders (requests), delegates them to baristas (worker threads), and serves coffee (responses) as each order is ready—without waiting in line.
1.2 Non-Blocking I/O
Node.js avoids waiting for operations like reading files or fetching APIs. Instead, it continues processing other tasks and returns to completed operations via callbacks.
Example:
javascript
const fs = require('fs'); // Non-blocking file read fs.readFile('file.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); }); console.log('This runs first!');
Output:
This runs first! [File content]
2. Critical Node.js Concepts
2.1 The Event Loop Explained
Interview Q: “Can you explain the event loop phases?”
Answer:
The event loop has six phases:
- Timers: Executes
setTimeout
andsetInterval
callbacks. - Pending Callbacks: Runs I/O-related callbacks (e.g., TCP errors).
- Idle/Prepare: Internal use only.
- Poll: Retrieves new I/O events; executes their callbacks.
- Check: Processes
setImmediate
callbacks. - Close: Handles cleanup (e.g.,
socket.on('close')
).
Priority Order:process.nextTick()
> Promises (microtasks) > setImmediate()
.
2.2 Modules and require()
Interview Q: “How does Node.js resolve module dependencies?”
Answer:
Node.js uses CommonJS modules (though ES6 modules are supported with .mjs
files). When you require('module')
, Node.js:
- Checks
node_modules
folders. - Looks for
package.json
(formain
field). - Falls back to
index.js
.
Example:
javascript
// math.js exports.add = (a, b) => a + b; // app.js const math = require('./math'); console.log(math.add(2, 3)); // 5
2.3 Asynchronous Patterns
Interview Q: “Compare callbacks, promises, and async/await.”
Answer:
- Callbacks: Basic but prone to “callback hell”
fs.readFile('file.txt', (err, data) => { /* ... */ });
- Promises: Chainable with
.then()
and.catch()
.
fetchData()
.then(data => process(data))
.catch(err => handleError(err));
- Async/Await: Syntactic sugar for promises.
async function loadData() {
try {
const data = await fetchData();
} catch (err) {
handleError(err);
}
}
3. Node.js Interview Questions & Answers
Core Concepts
Q1: Why is Node.js single-threaded?
A: The single-threaded model simplifies code execution and avoids context-switching overhead. I/O operations are handled asynchronously via the event loop.
Q2: What is the Global Object in Node.js?
A: global
(similar to the browser’s window
). Example: global.setTimeout()
.
Q3: What is __dirname
?
A: Returns the directory path of the current module.
Advanced Topics
Q4: How does the Cluster Module improve performance?
A: It forks multiple worker processes (one per CPU core) to utilize multi-core systems.
Example:
const cluster = require('cluster'); if (cluster.isPrimary) { cluster.fork(); // Create workers } else { // Worker code const server = require('http').createServer(); server.listen(3000); }
Q5: What are Streams? Name the types.
A: Streams process data in chunks. Types:
- Readable (e.g.,
fs.createReadStream
). - Writable (e.g., HTTP response).
- Duplex (e.g., TCP sockets).
- Transform (e.g., zlib compression).
4. Common Node.js Pitfalls & Fixes
4.1 Blocking the Event Loop
Issue: Running CPU-heavy tasks (e.g., loops) synchronously.
Fix: Offload tasks to worker threads or split into smaller chunks.
4.2 Memory Leaks
Causes:
- Unclosed event listeners.
- Global variables.
Debugging: Usenode --inspect
With Chrome DevTools.
5. Node.js Best Practices
- Use Async Code: Avoid synchronous functions like
fs.readFileSync
. - Handle Errors: Always include
.catch()
for promises. - Environment Variables: Store configs in
.env
(usedotenv
). - Logging: Use libraries like
winston
ormorgan
.
FAQs (Semantic SEO)
Q: Is Node.js multithreaded?
A: JavaScript runs single-threaded, but Node.js uses worker threads for I/O.
Q: What is REPL?
A: Read-Eval-Print Loop—a CLI to test Node.js code snippets.
Q: How to debug a Node.js app?
A: Use console.log
, debugger
, or node --inspect
.
Q: What is NPM?
A: Node Package Manager—installs third-party libraries (e.g., npm install express
).
Conclusion
Mastering Node.js requires understanding its event-driven architecture, asynchronous patterns, and module system. Whether you’re prepping for an interview or building a blog, this guide equips you with actionable knowledge and real-world examples.