100 Questions in nodejs

interview questions · Node.js — Server-side JavaScript

1. Core Architecture & The Event Loop Q1: What is Node.js? Is it a language or a framework?   Node.js is neither a language nor a framework. It is an open-source, cross-platform JavaScript runtime environment built on Google Chrome's V8 JavaScript engine. It allows developers to execute JavaScript code server-side, outside of a web browser. Q2: Why is Node.js single-threaded? Node.js was designed to handle high-concurrency, I/O-intensive applications efficiently. By using a single execution thread for JavaScript, it avoids the massive memory overhead and complex CPU context-switching associated with traditional multi-threaded servers (like Apache) that spawn a new thread for every incoming connection. Q3: If Node.js is single-threaded, how does it handle highly concurrent, asynchronous operations?   Node.js delegates asynchronous operations (like file system tasks, network requests, or database queries) to the underlying operating system kernel or the Libuv C++ thread pool. While these background operations are processing, the main JavaScript thread remains completely free to handle other incoming requests. When a background operation finishes, its callback is queued to execute on the main thread. Q4: What is Libuv and how does Node.js use it?   Libuv is a multi-platform C library that provides support for asynchronous I/O based on event loops. It is the backbone of Node.js architecture. Libuv manages: The Event Loop. A default thread pool of 4 threads (expandable up to 1024) used to handle blocking tasks that the OS kernel cannot handle natively (such as file I/O and DNS lookups). Q5: Explain the phases of the Node.js Event Loop. The Event Loop executes callbacks sequentially through six main phases in a continuous loop: Timers : Executes callbacks scheduled by setTimeout() and setInterval(). Pending Callbacks : Executes I/O callbacks deferred from the previous loop iteration (e.g., specific types of TCP errors). Idle, Prepare : Used only internally by Node.js for system optimization. Poll : Retrieves new I/O events. Node will execute I/O related callbacks here. If no timers are ready, it may block here to wait for connections. Check : Executes callbacks scheduled by setImmediate(). Close Callbacks : Executes callbacks for closed connections, such as socket.on('close', ...). Q6: What is the difference between process.nextTick() and setImmediate()? process.nextTick() fires immediately after the current operation finishes , completely bypassing the event loop phases. If called recursively, it can starve the event loop by preventing it from reaching the next phase. setImmediate() queues a callback to run during the Check phase of the event loop, meaning it yields control back to the event loop before running. Q7: What are Microtasks and Macrotasks in Node.js? Microtasks : Include process.nextTick() callbacks and Promise reactions (.then, .catch, async/await). They execute immediately after the current operation finishes and before the event loop moves to its next phase. Macrotasks : Include callbacks from setTimeout(), setInterval(), and setImmediate(). They are executed within their designated event loop phases. Q8: How can you change the default size of the Libuv thread pool?   You can increase the size of the thread pool by setting the environment variable UV_THREADPOOL_SIZE before launching your Node.js application: Bash # On Linux/macOS UV_THREADPOOL_SIZE=8 node app.js # On Windows (CMD) set UV_THREADPOOL_SIZE=8 && node app.js The maximum limit is 1024. Q9: What happens when the main JavaScript thread blocks? When the main thread blocks (due to an infinite loop, massive CPU computations, or synchronous file reads), the entire Event Loop halts. Node.js cannot process any new incoming requests, fire any timers, or execute I/O callbacks until the blocking execution finishes, rendering the server completely unresponsive. Q10: What is the difference between operational errors and programmer errors? Operational Errors : Runtime errors that occur during normal application operation, which are expected and must be handled. Examples include database connection failures, file-not-found errors, or network timeouts. Programmer Errors : Bugs or unexpected code states caused by poor logic. Examples include TypeError: Cannot read property 'foo' of undefined, syntax errors, or passing incorrect parameters to a function. 2. Modules & Module Systems Q11: What is the difference between CommonJS (CJS) and ECMAScript Modules (ESM)? CommonJS (CJS) : The legacy default module system in Node.js. Uses require() to load modules and module.exports to export them. It loads modules synchronously at runtime. ECMAScript Modules (ESM) : The official standard JavaScript module system. Uses import and export statements. It is evaluated asynchronously at compile-time/parse-time. Q12: How do module.exports and exports differ in CommonJS?   module.exports is the actual object returned by a require() call. exports is merely a convenient shortcut variable pointing to module.exports. JavaScript // This works perfectly exports .sayHello = () => "Hello" ; // This breaks the reference link and will NOT export your function exports = () => "Hello" ; // To export a single function/class directly, always reassign module.exports module .exports = () => "Hello" ; Q13: Can you use require() in an ES Module, or import in a CommonJS module? In an ES Module, require() is not defined by default. To use it, you must instantiate it manually using createRequire(import.meta.url). In a CommonJS module, you cannot use the static import statement. Instead, you must load ES modules asynchronously using dynamic import: import('module-name'). Q14: How does Node.js resolve module paths when using require('module_name')? It looks for core modules (like fs, path, http) matching that name. If not found, it enters the current directory and checks the local node_modules/ folder. If not found there, it moves up to the parent directory's node_modules/, repeating this traversal up to the root directory. If still not found, it checks global environments paths (like NODE_PATH). Q15: What is caching in Node.js modules? When a module is imported via require() or import for the first time, Node.js executes its code and caches the resulting exported object in memory (require.cache). Subsequent imports of that same module throughout the lifecycle of the application return the exact same cached object without re-executing the file. Q16: How do you force a module to reload by bypassing the cache?   In CommonJS, you can delete the target module's entry from the cache object explicitly before requiring it again: JavaScript delete require .cache[ require .resolve( './my-module' )]; const freshModule = require ( './my-module' ); Q17: What is a Core Module? Name five common examples . Core modules are binaries compiled directly into the Node.js source code that can be imported without downloading external packages. Examples: fs: File system interaction. path: File and directory path manipulation. http: Creating HTTP servers and clients. crypto: Encryption, hashing, and security utilities. os: Fetching operating system metrics and details. Q18: What is the purpose of the package.json file?   The package.json file acts as the manifest for a Node.js project. It manages metadata (name, version, author), scripts (start, test), third-party dependencies (dependencies and devDependencies), and defines the module engine type ("type": "module" vs "type": "commonjs"). Q19: What is the difference between dependencies and devDependencies? dependencies : Packages required for the application to run successfully in a production environment (e.g., express, mongoose). devDependencies : Packages required purely for local development, compiling, testing, and debugging (e.g., jest, eslint, nodemon). They are omitted during production builds (npm install --production). Q20: What is the purpose of package-lock.json? package-lock.json locks down the exact version numbers of every nested dependency installed in your node_modules tree. This ensures that any team member or deployment server running npm install builds a completely identical environment, preventing bugs caused by semantic version drift. 3. Buffers, Streams, & File System Q21: What is a Buffer in Node.js? A Buffer is a global class in Node.js designed to handle raw binary data. It allocates a raw, fixed-size chunk of memory outside the V8 JavaScript engine's heap. Buffers represent arrays of integers where each element corresponds to a byte (0-255). Q22: What are Streams and why are they critical for performance?   Streams are Unix-like data pipelines that allow you to read data from a source or write data to a destination piece-by-piece (chunks) without loading the entire asset into RAM. They are essential for handling massive data sources (like large files or video streams) because they keep memory usage low and constant regardless of file size. Q23: What are the four primary types of Streams? Readable : Streams from which data can be read (e.g., fs.createReadStream()). Writable : Streams to which data can be written (e.g., fs.createWriteStream()). Duplex : Streams that are both Readable and Writable simultaneously (e.g., a TCP socket). Transform : A specialized Duplex stream that modifies or transforms data while reading and writing (e.g., zlib.createGzip()). Q24: What is "Backpressure" in Streams?   Backpressure occurs when a Readable stream reads data from a source far faster than the destination Writable stream can consume and write it. To prevent the data buffer from overflowing and consuming excessive RAM, the Writable stream sends a signal to pause the Readable stream until it catches up. Q25: How do you safely join two streams together while automatically handling backpressure?  \ You use the .pipe() method, or the safer, modern utility pipeline from the stream module which automatically handles error cleanup: JavaScript const { pipeline } = require('stream'); const fs = require('fs'); const zlib = require('zlib'); pipeline( fs.createReadStream('input.txt'), zlib.createGzip(), fs.createWriteStream('input.txt.gz'), (err) => { if (err) console.error('Pipeline failed:', err); else console.log('Pipeline succeeded.'); } ); Q26: What is the difference between fs.readFile() and fs.createReadStream()? fs.readFile(): Reads the entire file into memory asynchronously before passing the complete contents to a callback. It will fail or crash your application if the file size exceeds your available RAM or the maximum V8 buffer limit. fs.createReadStream(): Reads the file in tiny, sequential chunks (defaulting to 64KB), emitting events as data arrives. This ensures memory usage remains minimal. Q27: How does fs.stat() help developers?   fs.stat() retrieves metadata about a specific file or directory pathway. It returns an instance of fs.Stats which contains details like file size, creation dates, permissions, and helper methods like stats.isFile() and stats.isDirectory(). Q28: Why should you avoid using synchronous methods like fs.readFileSync() in a production web server?   Synchronous methods completely block the single thread execution loop while the disk spin reads data. No other requests can be parsed during this period. These methods should only be used in one-off initialization scripts or CLI tools where concurrency is not required. Q29: How do you check if a file exists in Node.js without using deprecated functions? You use fs.promises.access() with the constant flag fs.constants.F_OK. Avoid using fs.existsSync() in highly concurrent code loops as it blocks the thread. JavaScript const fs = require('fs').promises; async function checkFile(path) { try { await fs.access(path, fs.constants.F_OK); return true; } catch { return false; } } Q30: What is the difference between standard buffers and the crypto module's Secure Buffers?   Standard buffers allocate memory dynamically on the system. When garbage collected, the raw data can linger in unallocated RAM spaces. The crypto module uses specialized safe internal allocations to wipe values explicitly when finished, preventing memory inspection leaks of secrets. 4. Asynchronous Patterns & Control Flow Q31: What is "Callback Hell" and how do you resolve it? Callback Hell describes deeply nested, unreadable callback chains that make code hard to maintain and debug. It can be resolved by: Breaking code into modular, named functions. Using Promises . Implementing async/await structures. Q32: What is an "Error-First Callback"?   The standard convention for asynchronous callbacks in Node.js. The first argument passed to the callback function is always reserved for an error object. If the operation succeeds, the first argument is passed as null or undefined, and the remaining arguments contain the operation data. JavaScript fs.readFile('file.txt', (err, data) => { if (err) { // Handle error return; } console.log(data); }); Q33: How do you transform a traditional error-first callback function into a Promise?   You wrap the target function inside a Promise, or use Node's built-in utility utility util.promisify(): JavaScript const util = require('util'); const fs = require('fs'); const readFilePromise = util.promisify(fs.readFile); readFilePromise('file.txt') .then(data => console.log(data)) .catch(err => console.error(err)); Q34: What happens if a Promise rejects and there is no .catch() block attached? It triggers an unhandled rejection event. In modern versions of Node.js, an unhandled promise rejection will immediately log a stack trace to stdout and terminate the process with a non-zero exit code to prevent state corruption. Q35: What is the purpose of Promise.all() versus Promise.allSettled()? Promise.all(): Rejects immediately if any single promise fails in the input array. It is an "all-or-nothing" execution mechanism. Promise.allSettled(): Waits until every single promise resolves or rejects . It returns an array of objects detailing the individual outcome status (fulfilled or rejected) for every promise. Q36: How does Promise.race() operate?   Promise.race() returns a promise that resolves or rejects as soon as one of the promises in the iterable array resolves or rejects, with that first promise's value or error. Q37: What is the purpose of Promise.any()? Promise.any() takes an iterable of promises and returns a single promise that resolves as soon as any single promise in the group resolves successfully . If every promise rejects, it throws an AggregateError containing all rejection errors. Q38: Does async/await completely block the event loop? No. async/await is syntactic sugar built on top of native JavaScript promises. When execution hits an await statement, it pauses the execution of that specific function and yields control of the main thread back to the event loop, allowing other operations to continue. Q39: Can you use an await statement outside of an async function?   Yes, but only if you are working within an ES Module (ESM) file where Top-Level Await is natively supported. In standard CommonJS files, await can only be invoked within a function declared with the async keyword. Q40: What is the event emitter pattern?   The EventEmitter is a core class (events module) that enables communication between objects in Node.js. An object can emit a named event using .emit(), causing any functions listening to that event via .on() to execute asynchronously. 5. Web Servers & Network Layer Q41: How do you build a minimal native HTTP server in Node.js without frameworks? JavaScript const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); }); server.listen(3000, () => { console.log('Server running at http://localhost:3000/'); }); Q42: What is Express.js middleware? Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. They can execute code, modify elements of req/res, and end the cycle or pass control forward using next(). Q43: What is the significance of calling next() inside middleware?   If a middleware function does not send a response back to the client using methods like res.send() or res.end(), it must call next(). Failing to call next() leaves the request hanging indefinitely, and the server will eventually time out. Q44: How can you catch errors globally within an Express.js application?   You define an error-handling middleware function at the very bottom of your Express routing configuration. It must explicitly accept four arguments : JavaScript app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: 'Something went wrong!' }); }); Q45: What is CORS and how do you resolve it in Node.js?   Cross-Origin Resource Sharing (CORS) is a security mechanism enforced by browsers to prevent scripts on one domain from accessing resources on another domain. In Node.js, you handle this by setting the appropriate headers (Access-Control-Allow-Origin) or by using the cors middleware package in Express. Q46: What is the difference between res.send() and res.json() in Express? res.json() explicitly converts the passed object or array into a JSON string format using JSON.stringify() and forces the response header Content-Type to application/json. res.send() accepts strings, buffers, or objects. If passed an object, it mimics res.json(), but it can dynamically assign content types based on input data structures. Q47: How do you extract routing parameters and query string variables in Express? Route Parameters : Accessed via req.params (e.g., matching /user/:id with /user/42 yields req.params.id = '42'). Query Parameters : Accessed via req.query (e.g., matching /search?term=node yields req.query.term = 'node'). Q48: What is the purpose of the helmet package? helmet is a security middleware package for Express. It secures applications by setting various HTTP response headers to defend against common vulnerabilities like Cross-Site Scripting (XSS), clickjacking, and packet sniffing. Q49: Explain the concept of long-polling vs WebSockets in Node.js. Before modern WebSockets existed, Long-Polling was designed as an optimization over standard short-polling (where a client blindly hammers a server with continuous GET requests every few seconds).        How it Works: The Request : The client opens a standard HTTP request to the Node.js server asking for updates. The Hold : Instead of answering immediately, if the server has no new data, it intentionally keeps the request open (holds the connection hanging). The Push & Close : The moment a new event occurs (e.g., a new database write), the Node.js server responds to the open request with the data payload and immediately closes the HTTP connection. The Loop : The client receives the data, processes it, and immediately opens a brand-new HTTP request to start the process over again. WebSockets : Establishes a single, persistent, bi-directional TCP connection between the server and client (using libraries like socket.io), allowing real-time data to flow back and forth with minimal overhead. Q50: How do you handle file uploads in an Express server?   You use middleware designed to parse multipart form data, such as multer. Standard body-parsers cannot read raw files sent via forms. 6. Process Management & Scaling Q51: What is the process object in Node.js?   The process object is a global instance that provides information about, and control over, the current Node.js application process. It allows you to access environment variables, read standard input/output streams, exit the process, and handle global lifecycle events. Q52: How do you extract environment variables inside an application?   You access variables via the process.env object (e.g., process.env.PORT or process.env.DATABASE_URL). These variables are typically injected from a .env file using the dotenv package during local development. Q53: What is the Cluster module and how does it help scale Node.js applications?   The Cluster module allows you to easily create a network of child processes (workers) that all share the same server port. The master process acts as a load balancer, distributing incoming connections to worker processes using a round-robin approach. This allows you to scale across multiple CPU cores on a single machine. Q54: What is the difference between the Cluster module and Worker Threads? Cluster Module : Spawns entirely new system processes with separate memory heaps and instances of the V8 engine. Communication is done via IPC. It is used to scale I/O bound systems horizontally . Worker Threads : Runs multiple threads within the same process , sharing memory spaces. It is designed to handle CPU-heavy computational tasks without blocking the primary event loop. Q55: What are the four methods inside the child_process module? exec(): Spawns a shell and runs a command, buffering the entire output in memory before returning a callback. execFile(): Similar to exec(), but invokes an executable file directly without spawning a full system shell. spawn(): Spawns a process and streams its output chunk-by-chunk via stdout/stderr streams (best for large data jobs). fork(): A specialized variation of spawn() that launches a new Node.js process with an open IPC channel for message passing. Q56: What is a "Zombie Process" or "Orphan Process" in Node.js child processes? An Orphan Process is a child process whose parent process has exited or terminated, leaving the child running alone under the management of the root system process. A Zombie Process is a child process that has completed execution but remains in the system process table because its parent has not yet read its exit status. Q57: What is PM2 and why is it used?   PM2 is a production process manager for Node.js applications. It includes features to: Keep applications running continuously by automatically restarting them if they crash. Manage cluster-mode configurations out of the box. Monitor resource utilization (CPU/RAM). Hot-reload applications with zero downtime. Q58: What is the difference between graceful shutdown and immediate shutdown? Immediate Shutdown (process.exit(0)) : Forcefully terminates the process immediately, killing active client connections and leaving database transactions incomplete. Graceful Shutdown : The process stops accepting new network connections, finishes processing all active requests, closes open database pools, and then exits cleanly. Q59: How do you catch unhandled exceptions globally at the process level?   You listen to the uncaughtException event on the process object: JavaScript process.on('uncaughtException', (err) => { console.error('There was an uncaught error', err); // Perform cleanup operations here process.exit(1); // Always exit to prevent corrupted application state }); Q60: How do you handle unhandled Promise rejections at the process level?   You listen to the unhandledRejection event: JavaScript process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); // Log to external monitoring tool }); 7. Security, Best Practices, & Performance Optimization Q61: What is a Memory Leak in Node.js and what can cause it?   A memory leak occurs when an application allocates memory on the V8 heap but fails to release it back to the system when it is no longer needed. Common causes include: Global variables that persist indefinitely. Forgotten setInterval or setTimeout timers holding closures. Uncleared event listeners attached to long-lived objects. Excessive caching without item limits. Q62: How do you debug a memory leak in Node.js? Use the built-in node inspection flag (node --inspect app.js). Connect Chrome DevTools to take heap snapshots at different points in time. Compare the snapshots to see which objects are growing continuously without being garbage collected. Q63: Why should you avoid using the crypto.sync methods in production handlers? Synchronous cryptographic operations (like crypto.pbkdf2Sync() or crypto.createHash()) block the main JavaScript thread due to their high CPU demands. Always use their asynchronous counterparts or wrap them in Worker Threads. Q64: What is a ReDoS (Regular Expression Denial of Service) attack? A ReDoS attack occurs when an application uses an inefficient regular expression that takes exponential evaluation time on specific input strings (known as "evil regexes"). Attackers exploit this by sending malicious strings that freeze the main thread, causing a Denial of Service. Q65: How do you securely hash passwords in Node.js? Do not use basic algorithms like MD5 or SHA-256, as they are too fast and vulnerable to brute-force attacks. Instead, use specialized, adaptive hashing libraries like bcrypt or argon2, which introduce salts and artificial CPU delays. Q66: What is SQL Injection and how do you prevent it? SQL Injection occurs when an attacker inputs malicious SQL statements into an application's input fields, tricking the database into executing unauthorized commands. It can be prevented by using parameterized queries , prepared statements, or an Object-Relational Mapper (ORM) like Sequelize or Prisma. Q67: What is the purpose of the npm audit command? npm audit checks your project's dependency tree for known security vulnerabilities documented in the public GitHub Advisory Database. It provides a detailed report of insecure packages along with commands to remediate them (npm audit fix). Q68: How can you protect your server from brute-force authentication attacks? Use rate-limiting middleware (such as express-rate-limit) to limit the number of requests an IP address can make within a given window. Implement account lockout or CAPTCHA verification mechanisms after a certain number of failed login attempts. Q69: Why should you avoid using eval() in Node.js?   eval() executes string inputs as arbitrary JavaScript code. This introduces critical security risks (such as Remote Code Execution if user input is passed directly) and hurts performance because it prevents the V8 engine from optimizing the code. Q70: What are JWTs (JSON Web Tokens) and how are they structured? JWTs are a compact, URL-safe means of representing claims to be transferred between two parties. They consist of three parts separated by dots: Header : Contains the token type and the hashing algorithm used. Payload : Contains the statements or user claims (e.g., userId, roles). Signature : Created by signing the encoded header and payload with a secret key to ensure the integrity of the token. 8. Databases & Data Layer Q71: What is the difference between an ORM/ODM and a raw database driver? Raw Drivers (e.g., pg, mysql2): Provide a low-level interface to execute raw SQL queries directly against the database. ORM/ODM (e.g., Sequelize, Mongoose, Prisma): Provide an abstraction layer that maps database rows or documents to JavaScript objects, simplifying validation, relationships, and queries. Q72: What is the default pooling behavior of database clients in Node.js? Most database clients use connection pooling by default. Instead of opening and closing a new TCP connection for every single query, the driver maintains a reusable pool of active connections, improving response times and reducing database overhead. Q73: How do you handle database connection drops in Node.js? You listen for error events on the database client or pool instance and implement reconnection logic: JavaScript pool.on('error', (err, client) => { console.error('Unexpected error on idle database client', err); // Re-establish connection or log error }); Q74: What is Mongoose "Population" and how does it compare to a SQL JOIN? In MongoDB/Mongoose, population replaces a reference path in a document with the actual document(s) from another collection. Unlike a SQL JOIN which happens on the database server in a single query, Mongoose population performs a separate query behind the scenes to fetch the related data. Q75: How do transactions work in Node.js database drivers?   T ransactions ensure that a series of database operations either all succeed or all fail together ( atomicity ). You begin a transaction block, execute your queries using a single shared connection client, and then call COMMIT to persist the changes or ROLLBACK if an error occurs. 9. Testing & Debugging Q76: What is Unit Testing vs Integration Testing? Unit Testing : Tests individual components or functions in isolation, mocking any external dependencies like databases or APIs. Integration Testing : Tests how multiple modules or systems interact together (e.g., testing an Express route, database write, and response delivery). Q77: Name three popular testing frameworks used in the Node.js ecosystem. Jest : A feature-rich testing framework by Meta with built-in mocking and assertions. Mocha : A flexible testing framework often paired with assertion libraries like Chai. Node.js Native Test Runner : A built-in, lightweight test runner available natively in modern Node.js versions via the node:test module. Q78: What is mocking in testing? Mocking replaces real dependencies (such as an external payment gateway or a database) with simulated implementations during testing. This ensures tests are fast, predictable, and do not make accidental side effects (like charging real credit cards). Q79: What is Code Coverage? Code coverage is a metric that measures the percentage of your source code executed during automated testing. It tracks line coverage, branch coverage, and function coverage to help identify untested code paths. Q80: How can you debug a Node.js script using the command line? You can start your script with the inspect flag: Bash node inspect app.js This pauses execution at the first line and opens a command-line debugger where you can set breakpoints, step through code, and inspect variables. 10. Advanced Concepts & System Integration Q81: What is the V8 Garbage Collector and how does it manage memory?   The V8 garbage collector automatically reclaims memory used by objects that are no longer reachable from the application's root execution context. It uses a generational strategy: splitting memory into New Space (short-lived objects evaluated via Scavenge algorithms) and Old Space (long-lived objects evaluated via Mark-Sweep-Compact algorithms). Q82: What is the difference between Heap and Stack memory? Stack : A fast, sequential memory structure used to store temporary function execution frames, primitive variables, and references to objects. Heap : A large, unstructured memory region used to store complex objects, closures, arrays, and buffers. Q83: What is the maximum heap memory limit in Node.js by default, and how can you increase it?   By default, V8 limits the heap size to around 1.4GB to 4GB depending on system architecture and version. You can increase this limit using the --max-old-space-size flag: Bash # Set maximum heap size to 8GB node --max-old-space-size=8192 app.js Q84: What is an Event Loop block and how can you monitor it?   An event loop block occurs when a synchronous task runs for too long, delaying the event loop from moving to its next phase. You can monitor this using the native perf_hooks module or third-party tools like blocked-at to detect long delays. Q85: What are Node.js Addons?   Node.js Addons are dynamically-linked shared objects written in C or C++ that can be loaded into Node.js using require() just like a standard JavaScript module. They are used to bridge high-performance C/C++ libraries with JavaScript execution. Q86: What is N-API (Node-API)? Node-API is an API for building native addons. It is independent of the underlying JavaScript engine (V8), ensuring that native addons compiled for one version of Node.js can run on newer versions without recompilation. Q87: What is the purpose of the dns module in Node.js? The dns module provides name resolution capabilities, allowing you to perform lookups (e.g., resolving a domain name to an IP address) using your operating system's configuration or network DNS queries. Q88: How does Node.js handle clustering when a worker process dies?   The master process can listen for the exit event emitted by the cluster module. When a worker dies due to an unhandled crash, the master can log the failure and immediately spawn a new worker instance to maintain capacity: JavaScript cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} died. Spawning replacement...`); cluster.fork(); }); Q89: What is IPC (Inter-Process Communication) in Node.js? IPC is a built-in channel that allows parent and child processes to send messages back and forth when spawned via fork(). Messages are automatically serialized and deserialized as JSON objects. Q90: What is Semantic Versioning (SemVer)? SemVer is a versioning specification consisting of three numbers: MAJOR.MINOR.PATCH. PATCH : Increment for backwards-compatible bug fixes. MINOR : Increment for backwards-compatible new features. MAJOR : Increment for incompatible, breaking API changes. Q91: What do the caret (^) and tilde (~) symbols mean in package.json? ^1.2.3: Installs minor updates and bug fixes (e.g., allows versions < 2.0.0). ~1.2.3: Installs only patch updates (e.g., allows versions < 1.3.0). Q92: What is the purpose of npm link?   npm link is a development tool that creates a symlink in the global folder pointing to a local module project. This allows you to test an npm package locally across projects without publishing it to the registry. Q93: What is a Monorepo and what tools support it in Node.js?   A monorepo is a architectural strategy where multiple distinct projects or packages reside within a single source repository. Popular management tools include npm workspaces, Yarn workspaces, Lerna, and Turbo. Q94: What is the difference between authorization and authentication? Authentication : Verifying who a user is (e.g., logging in with a username and password). Authorization : Verifying what resources or actions an authenticated user has permission to access (e.g., checking if a user is an admin). Q95: What are Webhooks? Webhooks are user-defined HTTP callbacks triggered by specific events in a source system. When an event occurs (like a successful payment in Stripe), the source system sends an HTTP POST request containing event payload data to a pre-configured URL on your Node.js server. Q96: How do you read options and flags from the command line without third-party tools? You can access command-line arguments using the process.argv array. The first element is the path to the node executable, the second is the script path, and subsequent elements contain the flags and arguments passed. Alternatively, modern Node versions provide the util.parseArgs() utility. Q97: What is the role of the tty module?   The tty module provides text terminal capabilities. It checks whether Node.js is running within a terminal context (process.stdout.isTTY), allowing you to dynamically adjust logging formats or terminal colors. Q98: How do you implement a simple delay function using Promises? JavaScript const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // Usage await sleep(2000); // Pauses execution for 2 seconds Q99: What are standard streams?   Standard streams are pre-connected communication channels between a computer program and its environment: process.stdin: Standard input stream. process.stdout: Standard output stream. process.stderr: Standard error stream. Q100: Why is it important to run Node apps as non-root users in containers? Running a Node.js application as the system root user introduces critical security risks. If an attacker exploits a Remote Code Execution vulnerability within your application, they gain full administrative control over the container filesystem and can potentially compromise the host system. Always declare a non-root execution user in your setup scripts.

Back to Node.js — Server-side JavaScript

Browse all study material on Careeroza