Top Node.js Interview Questions and Answers
Question: What is the difference between process.nextTick()
and setImmediate()
in Node.js?
Answer:
Both process.nextTick()
and setImmediate()
are used to schedule callbacks to be executed asynchronously in Node.js, but they differ in when and how they are executed within the event loop. Here’s a breakdown of the differences:
1. Execution Timing:
-
process.nextTick()
:- The callback function passed to
process.nextTick()
is executed immediately after the current operation completes and before any I/O events or timers in the event loop. - This means that
process.nextTick()
runs before the I/O events (like timers or I/O callbacks) in the event loop, and before any other queued microtasks or callbacks. This makes it a high priority compared to other asynchronous callbacks. - It is typically used when you need to ensure that certain code runs as soon as possible, but after the current operation, but before I/O or timers.
- The callback function passed to
-
setImmediate()
:- The callback passed to
setImmediate()
is executed on the next iteration of the event loop, specifically after I/O events (like timers and file system operations) have been processed but beforesetTimeout
orsetInterval
callbacks are triggered. - It is designed to be used for tasks that should be executed after the current event loop cycle has finished, but not as urgently as
process.nextTick()
.
- The callback passed to
2. Priority in the Event Loop:
-
process.nextTick()
:- Higher priority: Executes before any other I/O, timers, or
setImmediate()
callbacks. If there are multipleprocess.nextTick()
calls, they are executed in the order they are queued before the event loop continues with its other tasks. - If too many
process.nextTick()
callbacks are scheduled, it can block the event loop, leading to potential performance issues (as it prevents the event loop from progressing).
- Higher priority: Executes before any other I/O, timers, or
-
setImmediate()
:- Lower priority: Executes after the current event loop phase (I/O callbacks), but before timers (
setTimeout
,setInterval
). The callback will be placed in the “check” phase of the event loop.
- Lower priority: Executes after the current event loop phase (I/O callbacks), but before timers (
3. Use Cases:
-
process.nextTick()
:- Use
process.nextTick()
when you need to run code immediately after the current operation and ensure that no other I/O or asynchronous operations interrupt it. - Common use cases include:
- Ensuring that code runs before any I/O events.
- Handling errors in synchronous code that should be caught right after the current task.
- Use
-
setImmediate()
:- Use
setImmediate()
when you want to run code as soon as the event loop has completed the current phase of execution. - It’s commonly used for tasks that should be deferred until after the current operation has finished, such as handling an event or completing a process that doesn’t need to be handled immediately.
- You could use it when you’re processing a task asynchronously and need to yield back to the event loop for I/O processing.
- Use
4. Example:
// Using process.nextTick()
process.nextTick(() => {
console.log('nextTick callback');
});
// Using setImmediate()
setImmediate(() => {
console.log('Immediate callback');
});
// Output:
// nextTick callback
// Immediate callback
In this example, process.nextTick()
will execute first, even though setImmediate()
appears later. This is because process.nextTick()
has a higher priority and executes before I/O operations, timers, and setImmediate()
.
5. Behavioral Example:
console.log("Start");
process.nextTick(() => {
console.log("nextTick 1");
});
setImmediate(() => {
console.log("Immediate 1");
});
process.nextTick(() => {
console.log("nextTick 2");
});
setImmediate(() => {
console.log("Immediate 2");
});
console.log("End");
Output:
Start
End
nextTick 1
nextTick 2
Immediate 1
Immediate 2
Here’s why this happens:
- The “Start” and “End” log statements are executed synchronously.
process.nextTick()
callbacks are executed before thesetImmediate()
callbacks, and they also have a higher priority, sonextTick 1
andnextTick 2
are logged first.- After the current operation completes,
setImmediate()
callbacks are executed in the next event loop cycle, which results in the logging of Immediate 1 and Immediate 2.
6. Key Differences in Summary:
Feature | process.nextTick() | setImmediate() |
---|---|---|
Execution Timing | Executes after the current operation, before I/O and timers | Executes on the next iteration of the event loop, after I/O events |
Priority | Higher priority (before I/O callbacks) | Lower priority (after I/O callbacks) |
Use Case | Use for operations that need to execute immediately after the current operation | Use for tasks that should run after the current operation completes but are less urgent |
Blocking Potential | Can block the event loop if overused | Less likely to block the event loop, since it’s queued later |
Event Loop Phase | Runs before I/O, timers, or setImmediate() callbacks | Runs after I/O callbacks, before timers (setTimeout , setInterval ) |
Conclusion:
process.nextTick()
is ideal for executing code immediately after the current operation, but it has a higher priority and can block the event loop if overused.setImmediate()
is used for deferring execution of a callback until the next iteration of the event loop, allowing I/O and other tasks to be processed first.
Understanding the timing and priority differences between these two functions is essential for writing efficient and non-blocking Node.js applications.
Question: What are the key modules in Node.js?
Answer:
Node.js provides a rich set of built-in modules that are essential for various common tasks like file system operations, networking, cryptography, data streaming, and more. These modules are included by default, meaning you do not need to install them manually. Here are some of the key modules in Node.js:
1. HTTP (http)
- The
http
module is one of the core modules in Node.js that allows you to create web servers and handle HTTP requests and responses. - Use case: Building web servers, APIs, or handling HTTP requests.
- Example:
const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello, Node.js!'); }); server.listen(3000, () => { console.log('Server running at http://localhost:3000'); });
2. File System (fs)
- The
fs
module allows you to interact with the file system by reading from and writing to files, creating directories, and more. - Use case: Reading files, writing files, file manipulation.
- Example:
const fs = require('fs'); // Reading a file asynchronously fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); }); // Writing to a file fs.writeFile('output.txt', 'Hello, world!', (err) => { if (err) throw err; console.log('File has been written!'); });
3. Path (path)
- The
path
module provides utilities for working with file and directory paths in a platform-independent manner. - Use case: Manipulating file and directory paths.
- Example:
const path = require('path'); const filePath = '/usr/local/bin'; const baseName = path.basename(filePath); // 'bin' const dirName = path.dirname(filePath); // '/usr/local' const extName = path.extname('file.txt'); // '.txt' console.log(baseName, dirName, extName);
4. Events (events)
- The
events
module provides an event-driven architecture and allows you to handle events and listeners. This is particularly useful for handling asynchronous operations. - Use case: Creating custom event-driven systems.
- Example:
const EventEmitter = require('events'); const emitter = new EventEmitter(); // Registering an event listener emitter.on('greet', () => { console.log('Hello, EventEmitter!'); }); // Emitting the event emitter.emit('greet');
5. Stream (stream)
- The
stream
module provides APIs for dealing with streaming data. This is important for handling large files or data that comes in chunks, such as network requests. - Use case: Reading and writing large files, handling real-time data.
- Example:
const fs = require('fs'); const readableStream = fs.createReadStream('input.txt'); const writableStream = fs.createWriteStream('output.txt'); readableStream.pipe(writableStream);
6. OS (os)
- The
os
module provides information about the operating system, such as memory usage, platform, CPU architecture, etc. - Use case: Getting system-level information.
- Example:
const os = require('os'); console.log('OS Platform:', os.platform()); // 'darwin', 'win32', 'linux' console.log('Total Memory:', os.totalmem()); console.log('CPU Info:', os.cpus());
7. URL (url)
- The
url
module provides utilities for URL resolution and parsing. It helps in working with URLs, extracting their components, and resolving relative URLs. - Use case: Parsing URLs, constructing URLs from components.
- Example:
const url = require('url'); const parsedUrl = url.parse('https://www.example.com/path?name=value'); console.log(parsedUrl.hostname); // 'www.example.com' console.log(parsedUrl.pathname); // '/path'
8. Crypto (crypto)
- The
crypto
module provides cryptographic functionality, including hashing, encryption, and decryption. - Use case: Performing cryptographic operations like hashing passwords, generating tokens.
- Example:
const crypto = require('crypto'); // Hashing a string using SHA-256 const hash = crypto.createHash('sha256'); hash.update('Hello, Node.js'); console.log(hash.digest('hex'));
9. Cluster (cluster)
- The
cluster
module allows you to create child processes (workers) that can share server ports. This is useful for scaling Node.js applications and making use of multi-core systems. - Use case: Scaling Node.js applications to handle more traffic.
- Example:
const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} died`); }); } else { // Workers share the same server port http.createServer((req, res) => { res.writeHead(200); res.end('Hello from worker ' + process.pid); }).listen(8000); }
10. Child Process (child_process)
- The
child_process
module allows you to spawn new processes, run shell commands, and interact with them. - Use case: Running shell commands or spawning new processes.
- Example:
const { exec } = require('child_process'); exec('ls', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); });
11. Timer (timers)
- The
timers
module is used for setting and managing timers in Node.js, such assetTimeout()
,setInterval()
, andclearTimeout()
. - Use case: Deferring execution of code after a specified time or interval.
- Example:
setTimeout(() => { console.log('Executed after 2 seconds'); }, 2000);
12. DNS (dns)
- The
dns
module provides functions to perform DNS lookup and resolve hostnames. - Use case: Resolving domain names or working with DNS servers.
- Example:
const dns = require('dns'); dns.lookup('www.example.com', (err, address, family) => { if (err) throw err; console.log('Address: ' + address); console.log('Family: ' + family); });
13. Process (process)
- The
process
module provides information about the current Node.js process, including environment variables, exit codes, and command-line arguments. - Use case: Managing the Node.js process and interacting with system environment variables.
- Example:
console.log('Node.js Version:', process.version); console.log('Process ID:', process.pid);
Conclusion:
Node.js includes a wide range of built-in modules that are essential for creating scalable, performant, and feature-rich applications. Some of the key modules you will frequently use are http
, fs
, path
, events
, and stream
, among others. These modules cover a wide variety of functionality, from handling HTTP requests to interacting with the file system, performing cryptographic operations, and working with child processes. Understanding and using these core modules efficiently is crucial for building robust Node.js applications.
Read More
If you can’t get enough from this article, Aihirely has plenty more related information, such as Node.js interview questions, Node.js interview experiences, and details about various Node.js job positions. Click here to check it out.
Tags
- Node.js
- JavaScript
- Backend Development
- Asynchronous Programming
- Event Driven Architecture
- Event Loop
- Callbacks
- Promises
- Async/Await
- Streams
- Require
- Modules
- Middleware
- Express.js
- Error Handling
- Cluster Module
- Process.nextTick
- SetImmediate
- Concurrency
- Non Blocking I/O
- HTTP Module
- File System (fs) Module
- Node.js Interview Questions
- Node.js Advantages
- Node.js Performance
- Node.js Errors
- Callback Hell
- Server Side JavaScript
- Scalable Web Servers
- Node.js Architecture
- Node.js Event Emitters