1. Explain the concept of the CommonJS module system in Node.js:

    CommonJS is a module system used in Node.js for organizing and structuring code. It allows you to define modules using module.exports and include them in other files using the require function. For example:

    // math.js
    const add = (a, b) => a + b;
    module.exports = { add };
    
    // app.js
    const math = require('./math');
    console.log(math.add(2, 3)); // Outputs: 5
    
  2. Differentiate between 'require' and 'import' in Node.js:

    In Node.js, require is used for CommonJS modules, while import is part of ECMAScript modules (ESM) introduced in newer versions of Node.js. The syntax is different:

    // Using require (CommonJS)
    const math = require('./math');
    
    // Using import (ESM)
    import { add } from './math';
    
  3. Explain the role of the 'fs' module in handling file operations in Node.js:

    The fs (file system) module in Node.js is used for file operations like reading, writing, and manipulating files. For example:

    const fs = require('fs');
    
    // Reading a file
    fs.readFile('example.txt', 'utf8', (err, data) => {
      if (err) throw err;
      console.log(data);
    });
    
    // Writing to a file
    fs.writeFile('newFile.txt', 'Hello, Node.js!', (err) => {
      if (err) throw err;
      console.log('File written successfully.');
    });
    
  4. How does garbage collection work in Node.js:

    Node.js uses automatic garbage collection to manage memory. The V8 engine, which powers Node.js, employs a garbage collector that identifies and releases memory that is no longer in use. Developers don't need to explicitly manage memory deallocation; the garbage collector automatically handles it.

  5. Describe the purpose of the 'zlib' module in Node.js:

    The zlib module in Node.js provides compression and decompression functionalities using the zlib library. It's commonly used to compress data streams. For example:

    const zlib = require('zlib');
    const fs = require('fs');
    
    const readStream = fs.createReadStream('input.txt');
    const writeStream = fs.createWriteStream('input.txt.gz');
    
    readStream.pipe(zlib.createGzip()).pipe(writeStream);
    
  6. What is the 'os' module, and how can it be utilized in Node.js applications:

    The os module in Node.js provides operating system-related utility methods. It can be used to retrieve information about the system, such as CPU architecture, free memory, and network interfaces. For example:

    const os = require('os');
    
    console.log('CPU Architecture:', os.arch());
    console.log('Free Memory:', os.freemem());
    console.log('Network Interfaces:', os.networkInterfaces());
    
  7. Explain the concept of middleware in the context of Express.js:

    Middleware in Express.js are functions that have access to the request, response, and the next middleware function in the application’s request-response cycle. They can modify the request and response objects, end the request-response cycle, or call the next middleware function in the stack. For example:

    const express = require('express');
    const app = express();
    
    // Middleware function
    app.use((req, res, next) => {
      console.log('Middleware executed!');
      next();
    });
    
    app.get('/', (req, res) => {
      res.send('Hello, Express!');
    });
    
    app.listen(3000, () => {
      console.log('Server is running on port 3000');
    });
    
  8. How does Node.js support the use of Promises in asynchronous operations:

    Node.js has a built-in Promise object that is used to handle asynchronous operations. Many functions in Node.js return promises, and you can also create your own promise-based functions. For example:

    const fs = require('fs').promises;
    
    fs.readFile('example.txt', 'utf8')
      .then(data => console.log(data))
      .catch(error => console.error(error));
    
  9. What is the 'child_process' module used for in Node.js:

    The child_process module in Node.js is used to spawn child processes. It allows you to run other executables or shell commands from your Node.js application. For example:

    const { spawn } = require('child_process');
    
    const childProcess = spawn('ls', ['-l']);
    
    childProcess.stdout.on('data', (data) => {
      console.log(`stdout: ${data}`);
    });
    
    childProcess.on('close', (code) => {
      console.log(`Child process exited with code ${code}`);
    });
    
  10. How can you secure a Node.js application:

    To secure a Node.js application, you can:

  • Use HTTPS to encrypt data in transit.
  • Implement input validation and sanitize user input.
  • Use authentication mechanisms like JSON Web Tokens (JWT).
  • Regularly update dependencies to patch security vulnerabilities.
  • Employ security headers to prevent common web vulnerabilities.
  • Implement proper error handling to avoid exposing sensitive information.
  • Secure database connections and use parameterized queries to prevent SQL injection.
  1. Describe the use of the 'http' and 'https' modules in Node.js:

    The http and https modules in Node.js are used to create HTTP and HTTPS servers, respectively. For example:

const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello, HTTP!');
});

server.listen(3000, () => {
  console.log('HTTP server is running on port 3000');
});

For HTTPS:

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('public-cert.pem')
};

const server = https.createServer(options, (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello, HTTPS!');
});

server.listen(3000, () => {
  console.log('HTTPS server is running on port 3000');
});
  1. What is the role of the 'crypto' module in Node.js:

    The crypto module in Node.js provides cryptographic functionality. It can be used for various tasks such as creating hashes, generating HMAC (Hash-based Message Authentication Code), and performing encryption/decryption operations. For example:

const crypto = require('crypto');

const hash = crypto.createHash

('sha256');
hash.update('Hello, Crypto!');
const hashedData = hash.digest('hex');

console.log('Hashed Data:', hashedData);
  1. How can you deploy a Node.js application to production:

    Deployment of a Node.js application to production typically involves:

  • Setting up a production-ready web server (e.g., Nginx or Apache).
  • Using process managers like PM2 to manage your Node.js processes.
  • Configuring environment variables for sensitive information.
  • Setting up HTTPS for secure communication.
  • Regularly monitoring and logging application performance.
  • Ensuring proper error handling and fallback mechanisms.
  • Performing routine backups and updates.
  1. Explain the purpose of the 'stream' module in Node.js:

    The stream module in Node.js provides a way to handle streaming data, allowing you to read or write data in chunks rather than loading the entire dataset into memory. Streams can be readable, writable, or both. This is particularly useful for large datasets, network communication, and file processing. For example:

const fs = require('fs');

// Using readable stream
const readableStream = fs.createReadStream('largeFile.txt');
readableStream.on('data', (chunk) => {
  console.log(`Received ${chunk.length} bytes of data.`);
});

// Using writable stream
const writableStream = fs.createWriteStream('output.txt');
writableStream.write('Writing data to the file.');
  1. What are the benefits of using GraphQL over REST in a Node.js environment:

    GraphQL offers several advantages over REST in a Node.js environment:

  • Reduced Over-fetching and Under-fetching: Clients can request exactly the data they need, reducing the amount of unnecessary data transferred over the network.

  • Single Request: Clients can retrieve multiple types of data in a single request, reducing the number of network requests compared to REST.

  • Strong Typing: GraphQL schemas provide a strong typing system, making it easier to understand and work with the API.

  • Real-time Updates: GraphQL subscriptions allow clients to receive real-time updates when data changes, eliminating the need for constant polling.

  • Introspection: Clients can introspect the schema to discover available types and operations, making it self-documenting.

  • Versioning: GraphQL eliminates the need for versioning endpoints, as clients can request the specific fields they need.

Example GraphQL query:

query {
  getUser(id: 123) {
    name
    email
  }
}

Example REST API equivalent:

GET /users/123?fields=name,email