# Node Interview - Basic

1. **<mark>What is Node.js? Explain its main features and advantages/benefits.</mark>**  
    **Node.js** is an open-source, cross-platform runtime environment that allows you to run JavaScript code on the server side. It is built on **Chrome's V8 JavaScript engine** and enables developers to use JavaScript to write server-side applications, rather than being limited to client-side scripting.  
    ***i) Main Features of Node.js***  
    ***a) Asynchronous and Event-Driven***  
    Node.js uses a **non-blocking I/O** model, meaning operations like reading from a database or file don’t block the execution of other code.  
    It uses an **event loop** to handle multiple requests simultaneously, making it highly scalable.  
    ***b) Single-Threaded but Highly Scalable***  
    It uses a single-threaded event loop architecture, which is more efficient than traditional multi-threaded models for I/O-heavy operations.  
    ***c) Fast Execution***  
    Built on the **V8 engine**, Node.js compiles JavaScript into machine code, making execution very fast.  
    ***d) NPM (Node Package Manager)***  
    Comes with a vast library of open-source packages and tools, making development faster and easier.  
    ***e) Cross-Platform***  
    Runs on multiple platforms including Windows, Linux, and macOS.  
    ***f) Real-Time Capabilities***  
    Perfect for building real-time applications like chat apps or collaborative tools due to WebSocket support.  
    ***g) No Buffering***  
    Streams data rather than buffering it, which is particularly useful for real-time audio/video streaming applications.  
    ***2) Advantages / Benefits of Node.js***  
    ***a) High Performance***  
    Thanks to V8 and asynchronous handling, Node.js delivers great speed and performance.  
    ***b) Efficient for I/O-heavy Applications***  
    Especially suitable for applications that involve lots of disk or network access (e.g., APIs, file servers).  
    ***c) Single Language for Frontend and Backend***  
    Developers can write both client-side and server-side code in JavaScript, improving productivity and code sharing.  
    ***d) Large and Active Community***  
    A rich ecosystem of modules and a supportive developer community help solve problems and accelerate development.  
    ***e) Microservices-Friendly***  
    Lightweight and modular, making it suitable for microservices architectures and serverless applications.  
    ***f) Easy to Learn for JavaScript Developers***  
    Front-end developers can transition to backend development without learning a new language.  
    ***3) Common Use Cases of Node.js***  
    a) RESTful APIs and backend services
    
    b) Real-time chat applications
    
    c) Streaming services
    
    d) Serverless and microservices architecture
    
    e) IoT (Internet of Things) applications
    
2. **<mark>Explain how does Node.js work?</mark>**  
    Node.js works on a **single-threaded, event-driven architecture** that is particularly well-suited for building **non-blocking, I/O-intensive applications** like web servers, APIs, and real-time services.  
    Node.js uses a **non-blocking, event-driven model** to handle thousands of concurrent connections efficiently.
    
    It uses **asynchronous callbacks** and the **event loop** to avoid blocking the main thread. This makes it **fast and memory-efficient**, especially for I/O-bound operations.  
    ***i) Single Thread + Event Loop***  
    Unlike traditional web servers (e.g., Apache), which spawn multiple threads for each connection, **Node.js uses a single main thread**.  
    It handles **concurrent connections** using an **event loop**, which listens for events (like HTTP requests, file read/write, etc.) and delegates the heavy work to the **background (worker) threads** via **libuv**, a C++ library Node.js uses under the hood.  
    ***ii) Event Loop Explained***  
    **a)** **Incoming Request :** Client makes a request (e.g., read a file or call an API).
    
    **b) Event Loop Receives Request :** Puts the request in the **event queue**.
    
    **c) Delegation to Worker Thread (if needed) :** For I/O tasks like file reading or DB queries, the task is handed to a thread in the **libuv thread pool**.
    
    **d) Continue Processing :** While waiting for I/O, Node.js continues handling other events.
    
    **e) Callback Triggered** **:** Once the I/O operation finishes, the callback is added to the event loop.
    
    **f) Response Sent :** Callback is executed, and the result is sent back to the client.  
    ***iii) Architecture Components***  
    ***a) V8 Engine :*** Compiles and executes JavaScript code.  
    ***b) libuv :*** Handles thread pooling, async I/O, and abstracting OS functionalities.  
    ***c) Event Loop :*** Core component that processes all callbacks and non-blocking tasks.  
    ***d) Worker Threads :*** Handle long-running tasks like file I/O or DNS lookups.  
    ***e) NPM :*** Provides access to third-party packages and modules.
    
3. **<mark>Explain the Node.js application architecture?</mark>**  
    Node.js follows a **modular, layered architecture** designed to handle asynchronous I/O operations efficiently. The architecture is event-driven and non-blocking, making it ideal for building fast, scalable network applications like APIs, microservices, real-time apps, and more.  
    ***Main Components of Node.js Application Architecture***  
    ***i) Request-Response Model***
    
    Node.js uses a **single-threaded event loop** to process incoming requests and send back responses. Each incoming request is processed asynchronously.  
    ***ii) Core Layers in Node.js Architecture***  
    ***a) Request Handling Layer***  
    Uses the `http` module or frameworks like **Express.js** to receive HTTP requests.  
    Handles headers, body parsing, and passes the request to the router.  
    ***b) Routing Layer***  
    Determines which controller to invoke based on the URL and HTTP method (GET, POST, etc.).  
    Typically uses routing middleware like `app.get()`, [`app.post`](http://app.post)`()` in Express.  
    ***c) Controller Layer***  
    Handles the main application logic for each endpoint.  
    Validates input, calls services, handles errors, etc.  
    ***d) Service Layer (Business Logic Layer)***  
    Contains the logic for interacting with the data layer, performing computations, etc.  
    Separates concerns to make code reusable and testable.  
    ***e) Data Access Layer***  
    Handles communication with the **database** (e.g., MongoDB, PostgreSQL).  
    Uses libraries like `mongoose`, `Sequelize`, `TypeORM`, etc.  
    ***f) Response Layer***  
    Prepares the response (e.g., JSON) and sends it back to the client.  
    Also handles setting HTTP status codes, headers, and error messages.
    
4. **<mark>Why Node.js is single-threaded, and how does it handle concurrency and non-blocking I/O operations?</mark>**  
    Node.js is **single-threaded by design** to simplify programming and improve performance for **I/O-bound** (input/output-heavy) tasks.  
    ***1) Reasons for Being Single-Threaded***  
    **i) Simplicity**: Writing multi-threaded code in JavaScript (especially with shared memory and locking) would be complex and error-prone.
    
    **ii)** **JavaScript Origins**: JavaScript was originally created for browsers, where it runs in a single thread (the main thread), and Node.js extended this model to the server.  
    **iii) Asynchronous Nature**: Node.js doesn’t need multiple threads for concurrency—it achieves it with **non-blocking asynchronous I/O** and an **event-driven architecture**.  
    ***2) How Node.js Handles Concurrency and Non-blocking I/O***  
    Even though Node.js is single-threaded, it **can handle thousands of concurrent connections** efficiently using,  
    ***i) Event Loop***
    
    The **event loop** is the core of Node.js's concurrency model.
    
    It continuously checks for new events (like HTTP requests, completed file reads, etc.) and executes their associated callbacks.  
    ***ii) Non-blocking I/O***
    
    Node.js uses **non-blocking APIs** (e.g., `fs.readFile`, `http.get`) so the main thread doesn’t wait for operations to complete.
    
    While I/O tasks run, Node.js continues executing other code.  
    ***iii) libuv and Thread Pool***
    
    Node.js uses **libuv**, a C/C++ library, to abstract OS-level operations.
    
    For CPU-bound or blocking operations (e.g., file system access, DNS, compression), libuv delegates them to a **worker thread pool**.
    
    By default, the pool has 4 threads (configurable), allowing these heavy tasks to run **in parallel**.  
    ***3) High-Level Flow of Concurrency***  
    i) A request comes in (e.g., read a file).
    
    ii) Node.js passes the task to **libuv**, which assigns it to a worker thread.
    
    iii) The **event loop** continues running and handles other incoming requests.
    
    iv) When the file read is complete, the result is passed back to the event loop.
    
    v) The callback for that request is executed, and the response is sent.
    
5. **<mark>What is the package.json file in Node js?</mark>**  
    The `package.json` file is a **central configuration file** used in **Node.js** projects. It defines the **metadata**, **dependencies**, **scripts**, and other configurations for your application or module. It’s essentially the **manifest file** of your Node.js project.  
    To automatically generate a `package.json` file, you can use,
    
    ```bash
    npm init
    # or for a quicker setup
    npm init -y
    ```
    
    ***1) Key Purposes of package.json***  
    ***i) Manages Project Metadata***  
    Name, version, description, author, license, etc.
    
    ***ii) Lists Dependencies***
    
    Third-party libraries your project needs (e.g., `express`, `mongoose`).
    
    Dev dependencies used only during development/testing.
    
    ***iii) Defines Scripts***
    
    Custom commands (e.g., `npm start`, `npm test`, `npm run build`).
    
    ***iv) Tracks Versions***
    
    Keeps version control of the application and its dependencies.
    
    ***v) Used by npm and yarn***
    
    `npm install` reads this file to install the right packages.
    
    ```json
    {
      "name": "my-app", // Name of the project/module
      "version": "1.0.0", // Current version of the app
      "description": "A simple Node.js app", // Brief description of the app
      "main": "index.js", // Entry point file (default is index.js)
      "scripts": { // Custom commands (npm run <script-name>)
        "start": "node index.js",
        "test": "echo \"No tests yet\" && exit 0"
      },
      "author": "Your Name", // Your name or organization
      "license": "MIT", // Open-source license type
      "dependencies": { // Runtime libraries needed for your app
        "express": "^4.18.2"
      },
      "devDependencies": { // Tools needed only during development/testing
        "nodemon": "^3.0.1"
      }
    }
    ```
    
    ***2) Benefits of package.json***
    
    ***i) Automates setup :*** Others can install all needed packages with `npm install`.
    
    ***ii) Makes deployment easier*** *:* You can script build, test, and deploy steps.
    
    ***iii) Supports versioning :*** Helps manage and lock specific versions of packages.
    
    ***iv) Enables sharing :*** Required if you're publishing your package to npm.
    
6. **<mark>Explain REPL in the context of Node.js</mark>**  
    **REPL** stands for: **R**ead – **E**val – **P**rint – **L**oop
    
    In the context of **Node.js**, REPL is an **interactive shell** or environment that allows you to **write and execute JavaScript code one line at a time** directly from the terminal.
    
    It's built into Node.js and is great for **testing, debugging, or exploring** JavaScript and Node features quickly.  
    ***1) How REPL Works***
    
    **Read**: Takes input from the user.
    
    **Eval**: Evaluates the input.
    
    **Print**: Prints the result of the evaluation.
    
    **Loop**: Repeats the process until the user exits.  
    ***2) How to Start REPL***
    
    ```javascript
    // To start the Node.js REPL
    node
    // You’ll see a prompt like
    >
    ```
    
    ***3) REPL Features***  
    i) JavaScript Execution - Run any valid JavaScript expression or code  
    ii) Multiline Support - Write multi-line code using loops, functions, etc.  
    iii) Special Commands - `.help`, `.exit`, `.load`, `.save`, etc.  
    iv) Context Access - Access predefined Node.js modules and global objects  
    v) Underscore (`_`) - Stores the result of the last evaluated expression
    
7. **<mark>What is npm? How is it used in Node.js development?</mark>**  
    **npm** stands for **Node Package Manager**. It is the **default package manager for Node.js** and serves two main roles,
    
    **A command-line tool** to install, update, manage, and run Node.js packages.
    
    **An online registry** ([https://www.npmjs.com](https://www.npmjs.com)) containing thousands of open-source JavaScript libraries and tools.  
    ***1)*** ***How npm Is Used in Node.js Development***  
    ***i) Installing Packages***
    
    ```javascript
    npm install <package-name>
    ```
    
    Adds the package to the `node_modules` folder.
    
    Updates `package.json` and `package-lock.json`.  
    ***ii) Installing Packages as Dev Dependencies***
    
    ```javascript
    npm install --save-dev nodemon
    ```
    
    Used only during development (not required in production).  
    ***iii) Global Package Installation***
    
    ```javascript
    npm install -g <package-name>
    ```
    
    Installs a package globally, making it available from anywhere on your system (e.g., `npm`, `nodemon`, `eslint`).  
    ***iv) Running Scripts***
    
    You can define and run scripts from package.json
    
    ```javascript
    "scripts": {
      "start": "node app.js",
      "dev": "nodemon app.js"
    }
    ```
    
    ```javascript
    npm run dev
    npm start
    ```
    
    ***v) Managing Project Metadata***  
    The `npm init` command sets up a new Node.js project and creates a `package.json` file with:
    
    Project name, Version, Author, License, Dependencies, Scripts
    
    ```javascript
    npm init
    // or for quick setup
    npm init -y
    ```
    
    ***vi) Version Management***
    
    npm supports semantic versioning using:
    
    `^` (caret): Install compatible newer versions
    
    `~` (tilde): Install patch updates
    
    No symbol: Lock to exact version
    
    ```javascript
    "dependencies": {
      "express": "^4.18.2"
    }
    ```
    
8. **<mark>Describe the role of modules in Node.js. How are they created and used?</mark>**
    
    **Modules** are reusable pieces of code in Node.js. They help you organize your application into separate files and functions, improving **code structure, reusability, and maintainability**.
    
    In Node.js, **every file is treated as a separate module**.  
    ***1) Why Use Modules?***  
    **i) Encapsulation**: Avoid polluting the global scope.
    
    **ii) Separation of concerns**: Divide logic by function (e.g., routes, database, utilities).
    
    **iii) Code reuse**: Share modules across files or even projects.  
    ***2) Types of Modules in Node.js***
    
    **i) Core Modules** **(built into Node.js)**
    
    e.g., `fs`, `http`, `path`, `os`, `url` - No installation needed
    
    **ii) Local/User-Defined Modules**
    
    Files you create in your own project (e.g., `math.js`)
    
    **iii) Third-Party Modules**:
    
    Installed via npm (e.g., `express`, `lodash`)
    
9. **<mark>Describe the role of the require function in Node.js.</mark>**  
    The `require()` function is a **built-in Node.js function** used to **import modules**, JSON files, or local files into a Node.js script. It’s a part of the **CommonJS module system**, which Node.js uses by default.  
    ***1) Role of*** `require()` ***in Node.js***  
    The `require()` function allows developers to:
    
    Load **core Node.js modules** (like `fs`, `http`, `path`)
    
    Load **third-party modules** installed via npm (like `express`, `lodash`)
    
    Load **custom (local) modules** created by the developer
    
    Load **JSON files** directly
    
    ```javascript
    // Loading a Core Module
    const fs = require('fs');
    fs.readFile('file.txt', 'utf8', (err, data) => {
      console.log(data);
    });
    ```
    
    ```javascript
    // Loading a Local Module
    // math.js
    module.exports = {
      add: (a, b) => a + b
    };
    
    // app.js
    const math = require('./math');
    console.log(math.add(2, 3)); // Output: 5
    ```
    
10. **<mark>What are the differences between require() and import in Node.js?</mark>**
    
    Both `require()` and `import` are used to **include modules** in Node.js, but they come from **different module systems** and have **different syntax, behaviors, and capabilities**.
    
    ```javascript
    // require
    // math.js
    module.exports = {
      add: (a, b) => a + b
    };
    
    // app.js
    const math = require('./math');
    console.log(math.add(2, 3)); // 5
    ```
    
    ```javascript
    // import
    // math.mjs
    export const add = (a, b) => a + b;
    
    // app.mjs
    import { add } from './math.mjs';
    console.log(add(2, 3)); // 5
    ```
    
    ***When Should You Use Each?***  
    ***i) Use*** `require()` ***for***
    
    Older projects
    
    Simpler setups
    
    Full compatibility with all npm packages
    
    ***ii) Use*** `import` ***for***
    
    Modern, modular codebases
    
    Frontend-backend code sharing
    
    Using top-level `await` or async module loading
    
11. **<mark>How do you create a simple HTTP server in Node.js?</mark>**  
    Node.js includes a built-in `http` module that lets you create a **basic HTTP server** without installing any external packages.
    
    ```javascript
    // Load the http module
    const http = require('http'); // Loads the built-in Node.js HTTP module.
    
    // Create the server
    const server = http.createServer((req, res) => {
      // Set the response header
      res.writeHead(200, { 'Content-Type': 'text/plain' });
    
      // Send response
      res.end('Hello, world!\n');
    });
    
    // Define the port
    const PORT = 3000;
    
    // Start the server
    server.listen(PORT, () => {
      console.log(`Server running at http://localhost:${PORT}/`);
    });
    ```
    
    ***How It Works***
    
    i) `require('http')`  
    Loads the built-in Node.js HTTP module.  
    ii) `http.createServer()`  
    Creates the server and provides a callback function that handles incoming requests (`req`) and sends responses (`res`).  
    iii) `res.writeHead()`  
    Sets the HTTP status and headers.  
    iv) `res.end()`  
    Ends the response and sends data back to the client.  
    v) `server.listen(PORT)`  
    Binds the server to a specific port (e.g., `3000`) so it can receive requests.
    
12. **<mark>How do you create a simple HTTP server in Node.js using Express?</mark>**  
    ***i) Install Express***
    
    ```plaintext
    npm install express
    ```
    
    ***ii) Create the server file***
    
    Create a file named `server.js` (or `index.js`) with the following content
    
    ```javascript
    const express = require('express');
    const app = express();
    const port = 3000;
    
    // Define a simple route
    app.get('/', (req, res) => {
      res.send('Hello, world!');
    });
    
    // Start the server
    app.listen(port, () => {
      console.log(`Server is running at http://localhost:${port}`);
    });
    ```
    
    iii) Run the server
    
    ```javascript
    node server.js
    ```
    
    Open a browser and navigate to `http://localhost:3000`.
    
13. **<mark>What is the role of the process object in Node.js? Give examples of its usage.</mark>**  
    The `process` object in Node.js is a global object that provides information and control over the current Node.js process. It’s an instance of the `EventEmitter` class and is always available without requiring an import.  
    The `process` object is essential for,
    
    Reading input, Handling configuration, Managing the runtime environment
    
    It plays a vital role in writing command-line tools, scripting automation, and managing app behavior dynamically.  
    ***i) Key Roles of the*** `process` ***Object***  
    a) Accessing command-line arguments
    
    b) Interacting with the environment
    
    c) Controlling the process lifecycle (exit, signals)
    
    d) Handling events (e.g., `uncaughtException`, `exit`)
    
    e) Standard input/output (stdin, stdout, stderr)  
    ***ii) Common Examples  
    ***a) Accessing Command-Line Arguments
    
    ```javascript
    // Run: node app.js arg1 arg2
    console.log(process.argv);
    // OUTPUT
    [ 'node', '/path/to/app.js', 'arg1', 'arg2' ]
    ```
    
    b) Accessing Environment Variables
    
    ```javascript
    // Set variable: MY_ENV=production node app.js
    console.log(process.env.MY_ENV); // "production"
    ```
    
    c) Exiting the Process
    
    ```javascript
    if (!process.env.MY_ENV) {
      console.error('Missing environment variable');
      process.exit(1); // Exit with error code
    }
    ```
    
    d) Listening for Exit Events
    
    ```javascript
    process.on('exit', (code) => {
      console.log(`About to exit with code: ${code}`);
    });
    ```
    
    e) Standard Output and Error
    
    ```javascript
    process.stdout.write('This is standard output\n');
    process.stderr.write('This is an error message\n');
    ```
    
    f) Getting Current Working Directory
    
    ```javascript
    console.log(process.cwd());
    ```
    
    g) Changing Working Directory
    
    ```javascript
    process.chdir('/tmp');
    console.log('Changed directory to:', process.cwd());
    ```
    
14. **<mark>What is the role of environment variables in Node.js development and how to manage it?</mark>**  
    Environment variables play a **critical role in Node.js development** by providing a way to configure application behavior **without hardcoding values** in your source code. They’re especially useful for managing different settings across environments like **development**, **staging**, and **production**.  
    ***i) Why Use Environment Variables?***
    
    a) Security - Keep secrets (API keys, DB passwords) out of code.
    
    b) Flexibility - Configure behavior (ports, debug modes) without editing code.
    
    c) Portability - Make code easier to deploy in different environments.  
    ***ii) How to Use Environment Variables in Node.js***  
    a) Accessing an Environment Variable
    
    ```javascript
    const port = process.env.PORT || 3000;
    console.log(`Server will run on port ${port}`);
    ```
    
    b) Setting Environment Variables
    
    ```javascript
    // Linux/macOS
    PORT=5000 node app.js
    
    // Windows (CMD)
    set PORT=5000 && node app.js
    ```
    
    c) Managing with `.env` Files and `dotenv`
    
    For easier management, especially in development, use the [`dotenv`](https://www.npmjs.com/package/dotenv) package.
    
    ```javascript
    // Install dotenv
    npm install dotenv
    
    // Create a .env file
    PORT=4000
    DB_USER=myuser
    DB_PASS=secret
    
    // Load variables in your app
    require('dotenv').config();
    
    const port = process.env.PORT || 3000;
    console.log(`Server is running on port ${port}`);
    ```
    
    ***iii) Best Practices***  
    **Never commit** `.env` to version control. Use `.gitignore` to exclude it.
    
    Use **environment-specific** `.env` files: `.env.development`, `.env.production`, etc.
    
    Load them conditionally if needed,
    
    ```javascript
    require('dotenv').config({
      path: `.env.${process.env.NODE_ENV || 'development'}`
    });
    ```
    
    Environment variables help:
    
    a) Keep configs secure and flexible
    
    b) Separate code from configuration
    
    c) Simplify deployment and scaling
    
15. **<mark>How does error handling differ in synchronous and asynchronous code in Node.js?</mark>**  
    Error handling in Node.js differs significantly between **synchronous** and **asynchronous** code due to the nature of JavaScript's event-driven and non-blocking architecture.
    
    ***i) Synchronous Error Handling***
    
    Synchronous code executes sequentially, so you can use `try...catch` blocks directly
    
    ```javascript
    try {
      const data = JSON.parse('invalid JSON');
    } catch (err) {
      console.error('Caught an error:', err.message);
    }
    ```
    
    If an error is thrown during execution, it's caught immediately.
    
    Simple and predictable.  
    ***ii) Asynchronous Error Handling***  
    Asynchronous code doesn’t throw errors in the same call stack, so `try...catch` won't work directly unless you’re using `async/await`.  
    ***a) Callbacks***
    
    With callbacks, you follow the **Node.js error-first callback pattern**
    
    ```javascript
    const fs = require('fs');
    
    fs.readFile('file.txt', 'utf8', (err, data) => {
      if (err) {
        console.error('Error reading file:', err.message);
        return;
      }
      console.log('File data:', data);
    });
    ```
    
    First argument to the callback is always an error (if any).
    
    You must manually check and handle `err`.
    
    **b) Promises**
    
    You handle errors using `.catch()`
    
    ```javascript
    const fs = require('fs').promises;
    
    fs.readFile('file.txt', 'utf8')
      .then(data => console.log('File data:', data))
      .catch(err => console.error('Error reading file:', err.message));
    ```
    
    **c) Async/Await**
    
    `try...catch` works with `async` functions
    
    ```javascript
    const fs = require('fs').promises;
    
    async function readFile() {
      try {
        const data = await fs.readFile('file.txt', 'utf8');
        console.log('File data:', data);
      } catch (err) {
        console.error('Error reading file:', err.message);
      }
    }
    
    readFile();
    ```
    
16. **<mark>What is an error-first callback in Node.js?</mark>**  
    An **error-first callback** is a **convention in Node.js** for handling errors in asynchronous functions, especially those that use the callback pattern (common before Promises and `async/await`).  
    ***i) Definition***
    
    An **error-first callback** is a function where:
    
    The **first argument** is reserved for an **error object** (if any).
    
    The **subsequent arguments** are used for **successful result data**.
    
    ***ii) Function Signature***
    
    ```javascript
    function callback(err, result) {
      if (err) {
        // handle the error
      } else {
        // use the result
      }
    }
    ```
    
    ***iii) Reading a File with fs***
    
    ```javascript
    const fs = require('fs');
    
    fs.readFile('example.txt', 'utf8', (err, data) => {
      if (err) {
        console.error('Error reading file:', err.message);
        return;
      }
      console.log('File content:', data);
    });
    ```
    
    If reading fails (e.g. file not found), `err` contains an error and `data` is `undefined`.
    
    If successful, `err` is `null`, and `data` contains the file content.
    
    ***iv) Creating Your Own Error-First Callback Function***
    
    ```javascript
    function divide(a, b, callback) {
      if (b === 0) {
        return callback(new Error("Division by zero"));
      }
      const result = a / b;
      callback(null, result);
    }
    
    // Usage:
    divide(10, 2, (err, result) => {
      if (err) {
        console.error(err.message);
      } else {
        console.log('Result:', result);
      }
    });
    ```
    
17. **<mark>What are the global objects of Node.js?</mark>**  
    In Node.js, **global objects** are built-in objects that are **accessible from anywhere in your code** without importing or requiring them. These differ from browser globals and are specific to the Node.js environment.  
    ***i) global***  
    The global namespace object.
    
    Similar to `window` in browsers.
    
    ```javascript
    global.foo = 'bar';
    console.log(foo); // bar
    ```
    
    ***ii) process***  
    Provides information and control over the current Node.js process.  
    Common uses:
    
    `process.env` for environment variables
    
    `process.argv` for command-line arguments
    
    `process.exit()`, `process.on('exit', ...)`  
    ***iii) \_\_dirname***  
    The directory name of the current module file.
    
    ```javascript
    console.log(__dirname); // e.g., /Users/you/project
    ```
    
    ***iv) \_\_filename***  
    The full path of the current module file.
    
    ```javascript
    console.log(__filename); // e.g., /Users/you/project/index.js
    ```
    
    ***v) require***  
    Function to import modules (CommonJS style).
    
    ```javascript
    const fs = require('fs');
    ```
    
    ***vi) module***  
    Represents the current module.
    
    Contains information about the module (e.g., `module.exports`).  
    ***vii) exports***  
    A shorthand for `module.exports`
    
    ```javascript
    exports.sayHello = () => console.log('Hello');
    ```
    
    ***viii) Buffer***  
    Used to handle binary data.
    
    ```javascript
    const buf = Buffer.from('Hello');
    console.log(buf); // <Buffer 48 65 6c 6c 6f>
    ```
    
    ***ix) setImmediate()***  
    Executes a function after the current event loop cycle.
    
    ```javascript
    setImmediate(() => console.log('Runs after I/O events'));
    ```
    
    ***x)*** `setTimeout()`***,*** `clearTimeout()`***,*** `setInterval()`***,*** `clearInterval()`  
    Timers, same as in the browser.
    
18. **<mark>How would you use a URL module in Node.js?</mark>**  
    In Node.js, the `url` module is used to parse, format, and resolve URLs. It’s built into Node.js, so no installation is required.  
    ***i) Importing the*** `url` ***Module***
    
    ```javascript
    // In CommonJS (default for Node.js)
    const url = require('url');
    
    // In ES Modules (if using "type": "module" in package.json)
    import { URL } from 'url';
    ```
    
    ***ii) Parsing a URL***  
    Using `url.parse()` (Legacy)
    
    ```javascript
    const url = require('url');
    
    const parsedUrl = url.parse('https://example.com:8080/path/name?query=123#hash');
    console.log(parsedUrl.hostname);  // 'example.com'
    console.log(parsedUrl.port);      // '8080'
    console.log(parsedUrl.query);     // 'query=123'
    ```
    
    Using the modern `URL` class
    
    ```javascript
    const { URL } = require('url');
    
    const myUrl = new URL('https://example.com:8080/path/name?query=123#hash');
    console.log(myUrl.hostname);  // 'example.com'
    console.log(myUrl.port);      // '8080'
    console.log(myUrl.pathname);  // '/path/name'
    console.log(myUrl.search);    // '?query=123'
    console.log(myUrl.hash);      // '#hash'
    ```
    
    ***iii) Creating/Modifying a URL***
    
    ```javascript
    const { URL } = require('url');
    
    const myUrl = new URL('https://example.com');
    myUrl.pathname = '/api';
    myUrl.searchParams.set('id', '42');
    
    console.log(myUrl.toString()); // 'https://example.com/api?id=42'
    ```
    
    ***iv) Working with Query Parameters***
    
    ```javascript
    console.log(myUrl.searchParams.get('id')); // '42'
    
    myUrl.searchParams.append('sort', 'asc');
    console.log(myUrl.toString()); // 'https://example.com/api?id=42&sort=asc'
    ```
