NODEJS INTERVIEW QUESTIONS

What is event loop in nodejs?

  1. An event loop is an endless loop, which waits for tasks, executes them, and then sleeps until it receives more tasks. The event loop executes tasks from the event queue only when the call stack is empty
  2. The Event Loop has one simple job — to monitor the Call Stack and the Callback Queue. 
  3. If the Call Stack is empty, the Event Loop will take the first event from the queue and will push it to the Call Stack, which effectively runs it. Such an iteration is called a tick in the Event Loop
  4. The event loop is a fundamental concept in Node.js that allows it to handle asynchronous operations efficiently and enable non-blocking I/O
  5. An event loop is an endless loop, which waits for tasks, executes them, and then sleeps until it receives more tasks

===========================================================================

What are the two types of API functions in Node.js?

The two types of API functions in Node.js are: 
a) Asynchronous, non-blocking functions b) Synchronous, blocking functions

===========================================================================

what is node.js? 

node is framework and build on google chrome's javascript engine (v8 engine)

node js primary used  to create server-side web applications

node js is single threaded programming language means which means that your code can only do one task at a time.

Node js is a single threaded application but it support concurrency via concept of event and callbacks - event loop

Node.js are asynchronous by default and in order to achieve this asynchronus behavior, nodejs utilizes the event loop.

The V8 engine is written in C++ and used in Chrome and Nodejs

==========================================================================

CallBack Hell?

  1. in Node.js, where nested callbacks are complex and hard-to-read code structures 
  2. This occurs when multiple asynchronous operations are dependent on each other.
asyncOperation1((err, result1) => {
if (err) {
console.error(err);
} else {
asyncOperation2(result1, (err, result2) => {
if (err) {
console.error(err);
} else {
asyncOperation3(result2, (err, result3) => {
if (err) {
console.error(err);
} else {
// More nested callbacks...
}
});
}
});
}
});

DrawBack of Callback Hell:
  1. Readability - it  is very hard to understand the flow due to nested structure
  2. Debugging - idenfiying the errors will be challenging.
  3. Maintainability - Making changes or adding new functionality becomes risky.
  4. Error Handling: Error handling becomes complex.

By using the promises and async/await we can avoid nesting and callback hell.

Promises: Promises provide a more structured way to handle asynchronous operations and avoid nesting. They allow chaining and better error handling

Async/Await: This modern syntax builds upon promises and provides a cleaner and more synchronous-like way to write asynchronous code.

In modern Node.js programming, using Promises or async/await is recommended to avoid falling into callback hell and to write more maintainable and readable asynchronous code

===========================================================================

Control flow functions in Node.js?

Control flow functions are patterns or mechanisms.

Control flow functions are used to manage the execution order of asynchronous operations, ensuring that certain tasks are performed in a specific sequence or based on specific conditions. 

These functions help prevent callback hell 
and make it easier to perform or handle the  asynchronous code by providing a structured way to control the flow of execution


async function callbackHell() {
try {
const result1 = await asyncOperation1();
const result2 = await asyncOperation2(result1);
const result3 = await asyncOperation3(result2);
console.log(result3);
} catch (error) {
console.error("An error occurred:", error);
}
}
callbackHell();

===========================================================================

What are Event Listeners in nodejs? 

In Node.js, event listeners are a core part of the event-driven architecture and are used to handle and respond to events that occur within an application

Node.js has built in event's and built in event listeners. Node.js also provides functionality to create Custom events and Custom Event listeners.

const EventEmitter = require('events');

// Create an instance of EventEmitter
const myEmitter = new EventEmitter();

// Register a listener for the 'greet' event
myEmitter.on('greet', (name) => {
console.log(`Hello, ${name}!`);
});

// Emit the 'greet' event
myEmitter.emit('greet', 'Alice'); // Output: Hello, Alice!

===========================================================================

Could we run an external process with Node.js?

Yes, you can run an external process from within a Node.js application. Node.js provides the child_process module that allows you to spawn and interact with external processes.

Here are a few ways to run an external process using the child_process module:

exec(): This function runs a shell command and buffers the output.

spawn(): This function starts a new process and provides streams for stdin, stdout, and stderr.

fork(): This function is used to create child processes that run Node.js modules.

This is very useful for long running process
==========================================================================

What are the core modules of Node JS?

  1. fs - file system This module provides methods for interacting with the file system, including reading, writing, and manipulating files
  2. http  and https -  these modules are used for creating HTTP and HTTPS servers and making HTTP requests
  3. path -   module provides utilities for working with file and directory paths
  4. os - The os module provides information about the operating system and allows you to perform operations related
  5. events -  allows you to create and emit custom events and handle them with event listeners
  6. stream - . It includes readable and writable streams that are useful for dealing with large amounts of data efficiently.
  7. crypto - for encrypt and decrypt usecase
==========================================================================

The Singleton pattern is commonly used when you want to ensure that there is only one instance of a certain class and that this instance is shared across multiple parts of your codebase.

class Singleton {
constructor() {
// Initialize properties here
}
static getInstance() {
if (!this.instance) {
this.instance = new Singleton();
}
return this.instance;
}
// Other methods and properties
}
// Usage
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // Outputs: true

The Singleton design pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance

===========================================================================

Clustering in Node.js refers to a technique that allows you to create multiple processes (workers) to handle incoming connections within a single Node.js application

it utilize multiple CPU cores and distribute the workload more efficiently

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
// Fork workers for each CPU core
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
// Worker process handles server logic
http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello, World!');
}).listen(8000);
}

its is basically for long running processes.

==========================================================================

Both process.nextTick() and setImmediate() are used in Node.js for scheduling asynchronous code execution, but they have different behaviors and use cases.

1. process.nextTick():

process.nextTick() is a method provided by the Node.js process object. it will execute before the event loop continues. 

This means that functions scheduled with process.nextTick() have a higher priority than other asynchronous operations.

setImmediate() is another method used for scheduling asynchronous code execution.

it will  run in the next iteration of the event loop.

console.log('Start');

setImmediate(() => {
console.log('Set Immediate');
});

process.nextTick(() => {
console.log('Next Tick');
});

console.log('End');

// Start
// End
// Next Tick
// Set Immediate


==========================================================================
Discuss the differences between require() and ES6 import statements in Node.js?

Both the require() and ES6 import statements are used in Node.js to include modules and files

require() is a function that takes the module path as an argument and returns the exported module object. and require() is dynamically evaluated - This means that the module is loaded and executed when require() is called

ES6 import is a keyword that is used with a specific syntax to import bindings from modules.

ES6 import is statically evaluated. - The imports are resolved and evaluated during the module loading phase, before the code is executed.

===========================================================================

In Node.js, the __dirname and __filename variables are special global variables that provide information about the directory and file paths of the currently executing module.

They are not part of the JavaScript language itself but are specific to the Node.js runtime environment.

console.log(__dirname); // Outputs: '/path/to/your/current/directory'

console.log(__filename); // Outputs: '/path/to/your/current/file.js'

===========================================================================

Securing sensitive information, such as API keys we have to use

Use Environment Variables
Use the dotenv package to load environment variables from a .env file

Never hardcode sensitive information directly in your code. Hardcoded values are easily visible in your source code 

If you must store sensitive information in a database, encrypt the data before storing it. 

===========================================================================
Garbage collection is the process of automatically identifying and reclaiming memory that is no longer in use by the program. In Node.js, garbage collection is particularly important due to its asynchronous and event-driven nature. The V8 JavaScript engine, which is the engine used in Node.js, plays a central role in managing memory and performing garbage collection.

Overall, the V8 engine's garbage collection process in Node.js helps manage memory efficiently and automatically without requiring explicit memory deallocation by the programmer


=========================================================================

Basic Node.js Interview Questions

  1. What is Node.js?

    • Answer: Node.js is an open-source, cross-platform runtime environment built on Chrome's V8 JavaScript engine that allows you to run JavaScript on the server side.
  2. How does Node.js handle asynchronous operations?

    • Answer: Node.js uses an event-driven, non-blocking I/O model with the help of the event loop and callback functions to handle asynchronous operations.
  3. What is the difference between setImmediate() and process.nextTick()?

    • Answer: process.nextTick() schedules a callback function to be invoked in the current phase of the event loop, before the next I/O cycle. setImmediate() schedules a callback to be executed in the next iteration of the event loop, after the current poll phase.
  4. Explain the purpose of npm.

    • Answer: npm (Node Package Manager) is a package manager for JavaScript. It helps manage project dependencies, install libraries, share code with others, and maintain package versions.
  5. What is a callback function in Node.js?

    • Answer: A callback is a function passed as an argument to another function, which is then executed once the other function completes its operation, often asynchronously.

Intermediate Node.js Interview Questions

  1. What are streams in Node.js?

    • Answer: Streams are objects that allow reading or writing data continuously. They are used to handle large amounts of data in Node.js efficiently, especially for I/O operations like reading files, network communication, or HTTP requests.

      Example 1: Readable Stream - Reading a File

      const fs = require('fs');

      // Create a readable stream from a file
      const readableStream = fs.createReadStream('example.txt', {
      encoding: 'utf8',
      highWaterMark: 16 * 1024, // 16 KB chunks
      });

      readableStream.on('data', (chunk) => {
      console.log('Received chunk:', chunk);
      });

      readableStream.on('end', () => {
      console.log('Reading finished.');
      });

      readableStream.on('error', (err) => {
      console.error('Error reading the file:', err);
      });


      Example 2: Writable Stream - Writing to a File

      const fs = require('fs');

      // Create a writable stream to a file
      const writableStream = fs.createWriteStream('output.txt');

      writableStream.write('Hello, ');
      writableStream.write('world!\n');
      writableStream.end('This is the end of the stream.');

      writableStream.on('finish', () => {
      console.log('All data has been written to the file.');
      });

      writableStream.on('error', (err) => {
      console.error('Error writing to the file:', err);
      });


      Example 3: Duplex Stream - Transform Stream (Compressing a File)

      This example uses a duplex stream, specifically a transform stream, to compress a file using zlib.
      const fs = require('fs');
      const zlib = require('zlib');

      // Create a readable stream for the input file
      const readableStream = fs.createReadStream('example.txt');

      // Create a writable stream for the output file
      const writableStream = fs.createWriteStream('example.txt.gz');

      // Create a gzip transform stream
      const gzip = zlib.createGzip();

      // Pipe the readable stream into the gzip stream, then into the writable stream
      readableStream
      .pipe(gzip) // Compress the data
      .pipe(writableStream) // Write the compressed data
      .on('finish', () => {
      console.log('File has been compressed successfully.');
      })
      .on('error', (err) => {
      console.error('Error compressing the file:', err);
      });




  2. Explain the different types of streams in Node.js.

    • Answer: The four types of streams in Node.js are:
      • Readable: For reading data (e.g., fs.createReadStream()).
      • Writable: For writing data (e.g., fs.createWriteStream()).
      • Duplex: For both reading and writing data (e.g., TCP sockets).
      • Transform: A type of duplex stream that can modify or transform the data as it is written and read (e.g., zlib.createGzip()).
  3. What is the event loop in Node.js?

    • Answer: The event loop is the mechanism that allows Node.js to perform non-blocking I/O operations by offloading tasks to the system kernel whenever possible. It continually checks the call stack, processes callbacks, and handles asynchronous operations.
  4. Explain how Node.js handles file system operations.

    • Answer: Node.js provides the fs module to handle file system operations. This module includes both synchronous and asynchronous methods for reading, writing, updating, and deleting files.
  5. What is the difference between require and import in Node.js?

    • Answer: require is used to load CommonJS modules, whereas import is used for ES6 modules. ES6 modules are the standard JavaScript modules, offering static imports and better support for tools like tree shaking.

Advanced Node.js Interview Questions

  1. What is clustering in Node.js, and why is it used?

    • Answer: Clustering in Node.js is used to create multiple instances of the Node.js application, each running on a separate core of the CPU. This allows for load balancing and improved application performance on multi-core systems.
  2. How do you handle errors in asynchronous code in Node.js?

    • Answer: Errors in asynchronous code can be handled using try-catch blocks with async-await, callbacks (with error-first patterns), or by using .catch() with Promises.
  3. What are some common security best practices in Node.js?

    • Answer:
      • Validate and sanitize user input to prevent SQL injections.
      • Use environment variables for sensitive information.
      • Implement rate limiting to prevent DOS Attacks denial-of-service attacks.
      • Use HTTPS to encrypt data.
      • Regularly update dependencies and monitor for vulnerabilities.
  4. What is middleware in Node.js?

    • Answer: Middleware are functions that have access to the request and response objects in an application. They are used in the processing pipeline to modify requests, end requests, or call the next middleware function.
  5. Explain how to handle real-time communication in Node.js.

    • Answer: Real-time communication in Node.js can be handled using WebSockets with libraries like Socket.io or the native ws package. These enable bi-directional communication between the client and server.
  6. What are some methods to optimize performance in a Node.js application?

    • Answer:
      • Use asynchronous APIs and avoid blocking the event loop.
      • Optimize the usage of memory and garbage collection.
      • Implement caching strategies.
      • Use compression middleware to reduce response sizes.
      • Load balancing with clustering or reverse proxy (e.g., Nginx).
  7. What is the purpose of buffer in Node.js?

    • Answer: A buffer is a temporary storage for raw binary data, primarily used when working with streams in Node.js. It allows manipulation of binary data directly in the server-side JavaScript environment.
  8. How would you handle large payloads in Node.js applications?

    • Answer: For large payloads, use streaming, pagination, or chunking methods to handle data efficiently without blocking the event loop or consuming excessive memory.
  9. Explain how to use environment variables in Node.js.

    • Answer: Environment variables in Node.js are accessed via process.env. They are used to store configuration details, such as API keys, database credentials, and other sensitive information, to keep them separate from the codebase.
  10. Describe how you would implement authentication in a Node.js application.

    • Answer: Authentication in Node.js can be implemented using strategies such as:
      • JWT (JSON Web Tokens): For stateless, token-based authentication.
      • Passport.js: For various authentication strategies including local, OAuth, JWT, etc.
      • OAuth 2.0: For authorizing users via third-party services (e.g., Google, Facebook).


Post a Comment

Previous Post Next Post