[{"data":1,"prerenderedAt":488},["ShallowReactive",2],{"all-questions-node":3},{"beginner":4,"intermediate":139,"advanced":339},[5,16,23,32,40,48,56,65,73,81,88,94,101,109,116,124,131],{"id":6,"category":7,"question":8,"answer":9,"level":10,"tags":11},1,"Basics","What is Node.js and how does it differ from traditional web servers like Apache or Nginx?","**Concept Explanation:**\nNode.js is a JavaScript runtime built on Chrome's V8 engine that allows executing JavaScript on the server-side. Unlike traditional multi-threaded web servers (Apache, Nginx), Node.js uses a single-threaded event-driven architecture with non-blocking I\u002FO.\n\n**Execution Flow:**\n1. Client sends request to Node.js server\n2. Request enters event loop\n3. If operation is I\u002FO (file, network, DB), Node.js delegates to libuv's thread pool\n4. Main thread continues processing next request\n5. When I\u002FO completes, callback is placed in event queue\n6. Event loop executes callbacks on main thread\n\n**Event Loop Explanation:**\nNode.js event loop runs in six phases: timers, pending callbacks, idle\u002Fprepare, poll, check, close. For beginners: think of it as a forever loop that checks if there are any async tasks completed, then runs their callbacks while the main thread never blocks.\n\n**Memory Behavior:**\n- Each JavaScript object allocated in heap memory\n- V8 manages garbage collection (Mark-Compact)\n- No per-request thread overhead → memory efficient\n- Native modules may have separate memory pools\n\n**Lifecycle Explanation:**\n1. Node.js process starts, initializes V8 and libuv\n2. Runs module code (require\u002Fimport)\n3. Processes event loop until no more work to do\n4. Exits automatically when nothing left in event loop\n\n**Syntax Explanation:**\nBasic server creation:\n```js\nimport http from 'node:http';\n\nconst server = http.createServer((req, res) => {\n  res.writeHead(200, { 'Content-Type': 'text\u002Fplain' });\n  res.end('Hello World');\n});\n\nserver.listen(3000, () => console.log('Server running'));\n```\n\n**Practical Example:**\nFile server that handles concurrent reads without blocking:\n```js\nimport { readFile } from 'node:fs\u002Fpromises';\nimport http from 'node:http';\n\nhttp.createServer(async (req, res) => {\n  if (req.url === '\u002Fdata') {\n    const data = await readFile('.\u002Fdata.json', 'utf8');\n    res.end(data);\n  }\n}).listen(8080);\n```\n\n**Common Mistakes:**\n- Blocking the event loop with synchronous methods (fs.readFileSync)\n- Assuming multiple requests spawn separate threads\n- Forgetting to handle errors in async operations\n- Not setting `NODE_ENV=production` for performance\n\n**Interview Follow-ups:**\n- Q: How many requests can Node.js handle concurrently? A: Thousands due to async I\u002FO, but CPU-heavy tasks can block\n- Q: What happens when an uncaught exception occurs? A: Process exits; use `process.on('uncaughtException')` but should restart\n\n**Best Practices:**\n- Always use async versions of fs\u002Fnetwork methods\n- Use `node:http` or Express for production\n- Set appropriate timeout values\n- Use process managers like PM2 for multi-core\n\n**Performance Considerations:**\n- Single-threaded means one CPU core fully utilized\n- I\u002FO operations are extremely efficient (non-blocking)\n- CPU-intensive tasks (image processing, crypto) require worker threads\n- Keep event loop tick time under ~10ms for responsiveness\n\n**Production Recommendations:**\n- Deploy behind Nginx for static assets and SSL termination\n- Use clustering (cluster module) or PM2 to utilize all CPU cores\n- Implement health check endpoints\n- Monitor event loop lag using `process.hrtime()`\n\n**Browser Behavior:**\nNot directly applicable; Node.js is server-side. However, browser JavaScript also uses event loop but with Web APIs instead of libuv.\n\n**Node.js Runtime Behavior:**\n- Global objects: `global` (vs browser's `window`)\n- No DOM, but has `Buffer`, `process`, `__dirname`\n- Uses CommonJS by default, but supports ES modules with .mjs or `\"type\": \"module\"`\n\n**Latest Node.js Patterns:**\n- Use native ES modules (import\u002Fexport)\n- Top-level await in modules\n- `node:` protocol for core modules (`import fs from 'node:fs'`)\n\n**TypeScript Example:**\n```ts\nimport http, { IncomingMessage, ServerResponse } from 'node:http';\n\nconst server = http.createServer((req: IncomingMessage, res: ServerResponse) => {\n  res.writeHead(200, { 'Content-Type': 'application\u002Fjson' });\n  res.end(JSON.stringify({ message: 'Hello TypeScript' }));\n});\nserver.listen(3000);\n```\n\n**Interview Tip:**\nExplain that Node.js is not a framework or language, it's a runtime environment. Emphasize \"event-driven\" and \"non-blocking I\u002FO\" as key differentiators.\n\n**Common Follow-up:**\n\"Can Node.js handle CPU-intensive tasks well?\" Answer: Not on main thread; use worker_threads or offload to microservices.\n\n**Real-world Example:**\nNetflix uses Node.js for its server-side UI rendering and API layer because it handles many concurrent connections with low memory overhead.\n\n**Advanced Notes:**\nUnder the hood, Node.js uses libuv for cross-platform async I\u002FO. Epoll (Linux), kqueue (BSD), IOCP (Windows).","beginner",[12,13,14,15],"basics","architecture","event-loop","non-blocking",{"id":17,"category":7,"question":18,"answer":19,"level":10,"tags":20},2,"Explain the Event-Driven Architecture in Node.js. How does it work?","**Concept Explanation:**\nEvent-Driven Architecture (EDA) is a programming paradigm where the flow of execution is determined by events such as user actions, I\u002FO completions, or timers. Node.js implements EDA via the EventEmitter class and the event loop.\n\n**Execution Flow:**\n1. An event is emitted (e.g., `emitter.emit('data', payload)`)\n2. All registered listeners for that event are invoked synchronously\n3. If no listeners, event is ignored (unless error event)\n4. Async events go through event loop phases\n\n**Event Loop Explanation:**\nThe event loop continuously checks for pending events and executes callbacks in phases: timers → I\u002FO callbacks → idle → poll → check → close. EventEmitters directly trigger callbacks synchronously, but I\u002FO events rely on the loop.\n\n**Memory Behavior:**\n- Each EventEmitter maintains a Map of event names to arrays of listener functions\n- Memory leak can occur if listeners aren't removed (use `emitter.setMaxListeners()`)\n- Listeners hold references to outer scope; can prevent garbage collection\n\n**Lifecycle Explanation:**\n1. Create EventEmitter instance\n2. Register listeners with `.on()` or `.once()`\n3. Emit events with `.emit()`\n4. Listeners execute in registration order\n5. Remove listeners with `.off()` or `.removeListener()`\n\n**Syntax Explanation:**\n```js\nimport EventEmitter from 'node:events';\n\nclass MyEmitter extends EventEmitter {}\nconst emitter = new MyEmitter();\n\n\u002F\u002F Register listener\nemitter.on('greet', (name) => {\n  console.log(`Hello ${name}`);\n});\n\n\u002F\u002F Emit event\nemitter.emit('greet', 'Alice'); \u002F\u002F Output: Hello Alice\n```\n\n**Practical Example:**\nReal-time order processing system:\n```js\nimport EventEmitter from 'node:events';\n\nclass OrderProcessor extends EventEmitter {\n  processOrder(order) {\n    this.emit('orderReceived', order);\n    \u002F\u002F Validate\n    this.emit('orderValidated', order);\n    \u002F\u002F Charge payment\n    this.emit('paymentProcessed', order);\n    \u002F\u002F Ship\n    this.emit('orderShipped', order);\n  }\n}\n\nconst processor = new OrderProcessor();\nprocessor.on('orderReceived', (order) => console.log(`Received: ${order.id}`));\nprocessor.on('orderShipped', (order) => console.log(`Shipped: ${order.id}`));\n```\n\n**Common Mistakes:**\n- Not handling `error` events → crashes process\n- Forgetting to remove listeners causing memory leaks\n- Synchronous listeners blocking event loop\n- Using async operations in listeners without proper handling\n\n**Interview Follow-ups:**\n- Q: Are event listeners synchronous or asynchronous? A: By default, they run synchronously in the order attached\n- Q: How to make them async? A: Use `setImmediate()` or `process.nextTick()` inside listener\n\n**Best Practices:**\n- Always attach `error` listener\n- Use `.once()` for one-time events\n- Limit max listeners with `setMaxListeners(20)` for high-volume events\n- Prefer `EventEmitter` over callbacks for multiple subscribers\n\n**Performance Considerations:**\n- Emitting events with many listeners (1000+) has linear cost\n- Each listener is a function call overhead\n- Avoid emitting same event thousands per second; consider batching\n- Use `emitter.emit()` with spread arguments carefully\n\n**Production Recommendations:**\n- Use EventEmitter for decoupled architecture\n- For high-throughput event processing, consider message queue (RabbitMQ, Kafka)\n- Monitor listener count via `emitter.listenerCount(eventName)`\n- Use WeakRefs if listeners shouldn't prevent garbage collection\n\n**Browser Behavior:**\nBrowser has similar but not identical event system (DOM Events). Node.js EventEmitter is not available; use custom event target or libraries.\n\n**Node.js Runtime Behavior:**\n- EventEmitter core module uses hybrid C++\u002FJavaScript\n- `new EventEmitter()` is lightweight\n- Built-in streams, HTTP requests inherit EventEmitter\n\n**Latest Node.js Patterns:**\n- Use `EventTarget` (web-compatible) as alternative in Node.js 15+\n- `once(emitter, eventName)` from `node:events\u002Fpromises`\n- `emitter[Symbol.for('nodejs.rejection')]` for async error handling\n\n**TypeScript Example:**\n```ts\nimport EventEmitter from 'node:events';\n\ninterface Order {\n  id: string;\n  amount: number;\n}\n\nclass TypedEmitter extends EventEmitter {\n  emit(event: 'process', order: Order): boolean;\n  emit(event: string | symbol, ...args: any[]): boolean {\n    return super.emit(event, ...args);\n  }\n  on(event: 'process', listener: (order: Order) => void): this;\n  on(event: string | symbol, listener: (...args: any[]) => void): this {\n    return super.on(event, listener);\n  }\n}\n```\n\n**Interview Tip:**\nCompare Event-Driven vs. traditional request-response: EDA enables loose coupling, better scalability for real-time apps, but harder to debug.\n\n**Common Follow-up:**\n\"How does Node.js handle thousands of concurrent connections with single thread?\" Answer: Event loop and non-blocking I\u002FO; connections are just event sources, not threads.\n\n**Real-world Example:**\nSocket.io uses EventEmitter to handle real-time messages; each room and socket is an EventEmitter instance.\n\n**Advanced Notes:**\nEventEmitter uses `Reflect.apply` for listener calls. For max performance, consider `emit` with pre-bound listeners. Async hooks can track event propagation.",[21,22,13],"event-driven","eventemitter",{"id":24,"category":25,"question":26,"answer":27,"level":10,"tags":28},3,"Modules","What's the difference between CommonJS and ES Modules in Node.js? How do you use each?","**Concept Explanation:**\nCommonJS (CJS) is the original module system for Node.js using `require()` and `module.exports`. ES Modules (ESM) is the official ECMAScript standard using `import`\u002F`export` statements, natively supported in Node.js 12+.\n\n**Execution Flow:**\n- CJS: `require()` is synchronous, loads module at runtime, caches after first load\n- ESM: `import` is asynchronous (hoisted), parsed at compile time, supports top-level await\n\n**Event Loop Explanation:**\nESM imports are resolved before execution, which can affect startup timing. CJS `require()` may block event loop during large synchronous module loads.\n\n**Memory Behavior:**\nBoth cache modules after first load. CJS caches in `require.cache`. ESM caches based on URL. Unused ESM exports can be tree-shaken (though not automatic in Node.js).\n\n**Lifecycle Explanation:**\nCJS: module wrapped in function, executed when required. ESM: module is parsed, imports resolved, then executed asynchronously.\n\n**Syntax Explanation:**\n```js\n\u002F\u002F CommonJS - file.cjs\nconst fs = require('node:fs');\nmodule.exports = { read: fs.readFile };\n\n\u002F\u002F ES Modules - file.mjs or package.json \"type\": \"module\"\nimport fs from 'node:fs';\nexport const read = fs.readFile;\n```\n\n**Practical Example:**\nDynamic imports in ESM:\n```js\n\u002F\u002F ESM with dynamic import\nif (condition) {\n  const module = await import('.\u002Fsome-module.js');\n  module.doSomething();\n}\n\n\u002F\u002F CJS equivalent\nlet module;\nif (condition) {\n  module = require('.\u002Fsome-module.js');\n}\n```\n\n**Common Mistakes:**\n- Mixing `import` and `require()` without proper flags\n- Forgetting `.js` extension in ESM (required)\n- Using `__dirname` in ESM (use `import.meta.url` instead)\n- Expecting synchronous `import` (it's async)\n\n**Interview Follow-ups:**\n- Q: Can you use both in same project? A: Yes, with .cjs\u002F.mjs extensions or `\"type\": \"module\"` with `.cjs` for CJS\n- Q: Which is faster? A: CJS slightly faster for startup, ESM better for static analysis\n\n**Best Practices:**\n- Prefer ESM for new projects (future-proof)\n- Use `node:` protocol for core modules: `import fs from 'node:fs'`\n- For libraries, publish both CJS and ESM (dual package)\n- Use `.cjs` for scripts that need `require()`\n\n**Performance Considerations:**\n- ESM static imports are resolved at startup, no runtime cost\n- Dynamic `import()` has overhead per call\n- CJS `require()` has small caching overhead but synchronous\n- ESM enables better tree-shaking for frontend bundlers\n\n**Production Recommendations:**\n- Use `\"type\": \"module\"` in package.json for consistency\n- Configure TypeScript with `\"module\": \"ESNext\"` and `\"moduleResolution\": \"node\"`\n- Use `--experimental-specifier-resolution=node` legacy; better to use full file paths\n\n**Browser Behavior:**\nBrowsers support ESM natively with `\u003Cscript type=\"module\">`. CJS is not supported; must bundle.\n\n**Node.js Runtime Behavior:**\n- ESM modules loaded via `--loader` flags historically, now stable since Node.js 16\n- `import.meta.url` gives file URL, convert to path with `fileURLToPath`\n- CJS has `require.resolve()` for resolution, ESM has `import.meta.resolve()` (experimental)\n\n**Latest Node.js Patterns:**\n- `--experimental-default-type` flag to change default module system\n- `import.meta.dirname` and `import.meta.filename` (Node.js 20.11+)\n- `module.register()` for custom loaders\n\n**TypeScript Example:**\n```ts\n\u002F\u002F Using ESM in TS (tsconfig.json: \"module\": \"NodeNext\")\nimport { readFile } from 'node:fs\u002Fpromises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport async function loadConfig() {\n  const configPath = path.join(__dirname, 'config.json');\n  return JSON.parse(await readFile(configPath, 'utf-8'));\n}\n```\n\n**Interview Tip:**\nShow knowledge of the historical context (CJS born before JS had modules) and how Node.js unified them.\n\n**Common Follow-up:**\n\"What's the `node:` prefix?\" Answer: Explicit import of built-in modules, ensures no user-land module shadowing.\n\n**Real-world Example:**\nExpress 5 dropped CJS-only support; frameworks now dual-publish. Next.js uses ESM internally but supports both.\n\n**Advanced Notes:**\nESM import specifiers are URLs, enabling loading from HTTP (experimental `--experimental-network-imports`). Custom loaders can intercept imports for advanced patterns (e.g., importing GraphQL files).",[29,30,31],"commonjs","esmodules","modules",{"id":33,"category":7,"question":34,"answer":35,"level":10,"tags":36},4,"How does non-blocking I\u002FO work in Node.js? Give a concrete example with file system operations.","**Concept Explanation:**\nNon-blocking I\u002FO means that operations (file reads, network requests, database queries) don't block the main thread while waiting for completion. Node.js delegates these operations to libuv's thread pool (for file system) or OS async facilities (for network), then notifies via callbacks.\n\n**Execution Flow:**\n1. Main thread calls `fs.readFile()` - non-blocking version\n2. Operation passed to thread pool (libuv default 4 threads)\n3. Main thread continues executing subsequent code\n4. Thread pool thread reads file from disk\n5. On completion, callback is queued in event loop's poll phase\n6. Event loop executes callback on main thread\n\n**Event Loop Explanation:**\nFile I\u002FO callbacks are processed in the `poll` phase. While waiting, the loop can process other phases (timers, pending callbacks). This allows concurrency without multithreading complexity.\n\n**Memory Behavior:**\n- Each async operation allocates a small control structure in C++ heap\n- File contents read into Buffer (managed by V8 or external memory)\n- Callback closure captures outer variables; release after execution\n\n**Lifecycle Explanation:**\n```js\nimport { readFile } from 'node:fs\u002Fpromises';\n\nasync function nonBlockingExample() {\n  console.log('Start reading');\n  const dataPromise = readFile('file.txt', 'utf8'); \u002F\u002F Non-blocking\n  console.log('Reading started, doing other work');\n  const data = await dataPromise; \u002F\u002F Suspends but doesn't block\n  console.log('File content:', data);\n}\n```\n\n**Syntax Explanation:**\nCompare blocking vs non-blocking:\n```js\nimport fs from 'node:fs';\n\n\u002F\u002F BLOCKING - do NOT use in production\nconst data = fs.readFileSync('.\u002Fbigfile.txt', 'utf8');\nconsole.log('Done'); \u002F\u002F Waits for file\n\n\u002F\u002F NON-BLOCKING - correct\nfs.readFile('.\u002Fbigfile.txt', 'utf8', (err, data) => {\n  console.log('File loaded');\n});\nconsole.log('This runs immediately');\n```\n\n**Practical Example:**\nServer that reads multiple files concurrently:\n```js\nimport { readFile } from 'node:fs\u002Fpromises';\nimport http from 'node:http';\n\nhttp.createServer(async (req, res) => {\n  if (req.url === '\u002Fdashboard') {\n    \u002F\u002F All three reads happen concurrently (non-blocking)\n    const [user, settings, stats] = await Promise.all([\n      readFile('.\u002Fuser.json', 'utf8'),\n      readFile('.\u002Fsettings.json', 'utf8'),\n      readFile('.\u002Fstats.json', 'utf8')\n    ]);\n    res.end(`User: ${user}, Settings: ${settings}, Stats: ${stats}`);\n  }\n}).listen(3000);\n```\n\n**Common Mistakes:**\n- Using sync versions in web servers (`readFileSync`)\n- Assuming callbacks execute immediately\n- Forgetting error handling in callbacks\n- Blocking the thread pool with synchronous crypto operations\n\n**Interview Follow-ups:**\n- Q: What determines which operations are non-blocking? A: Node.js uses libuv's thread pool for file system, DNS, some crypto; network sockets use OS native async (epoll\u002Fkqueue\u002FIOCP)\n- Q: How many threads in pool? A: Default 4, set via `UV_THREADPOOL_SIZE`\n\n**Best Practices:**\n- Always use async versions of I\u002FO methods\n- Use `fs.promises` API with async\u002Fawait\n- For many concurrent file operations, consider `worker_threads` or batching\n- Set timeouts on I\u002FO operations\n\n**Performance Considerations:**\n- Non-blocking I\u002FO allows handling thousands of concurrent connections\n- Thread pool size limits concurrent file operations; increase for heavy file workloads\n- Each async operation has small overhead (~200-300 bytes)\n- Avoid `fs.stat` on every request; cache results\n\n**Production Recommendations:**\n- Use `fs.open` and streams for large files\n- Configure thread pool size: `UV_THREADPOOL_SIZE=8 node app.js`\n- Monitor pending async operations with `process._getActiveRequests()`\n- Use cluster mode to avoid thread pool bottlenecks\n\n**Browser Behavior:**\nBrowser JavaScript uses Web APIs for non-blocking (fetch, IndexedDB). Node.js extends to file system, child processes.\n\n**Node.js Runtime Behavior:**\n- Libuv thread pool uses POSIX threads (pthread) on Unix\n- Network sockets are non-blocking at OS level (O_NONBLOCK)\n- `process.binding('uv')` exposes libuv internals\n\n**Latest Node.js Patterns:**\n- `fs.createReadStream` with `await` using `for await...of`\n- `fs.promises` with `AbortController` for cancellation\n- `stream\u002Fpromises` pipeline functions\n\n**TypeScript Example:**\n```ts\nimport { readFile, writeFile } from 'node:fs\u002Fpromises';\nimport { createServer, IncomingMessage, ServerResponse } from 'node:http';\n\ninterface Data {\n  id: string;\n  value: number;\n}\n\ncreateServer(async (req: IncomingMessage, res: ServerResponse) => {\n  try {\n    const data = await readFile('.\u002Fdata.json', 'utf-8');\n    const json: Data = JSON.parse(data);\n    res.writeHead(200, { 'Content-Type': 'application\u002Fjson' });\n    res.end(JSON.stringify(json));\n  } catch (err) {\n    res.writeHead(500);\n    res.end('Internal Error');\n  }\n}).listen(8080);\n```\n\n**Interview Tip:**\nDraw the diagram: Main thread -> libuv thread pool -> callback queue -> event loop -> main thread. Emphasize that JavaScript code is never parallel, only I\u002FO is parallel.\n\n**Common Follow-up:**\n\"What happens if all thread pool threads are busy?\" Answer: New file operations queue up; event loop may starve. Increase pool size or use worker_threads.\n\n**Real-world Example:**\nA logging service writing to disk while handling HTTP requests - non-blocking ensures logs don't block incoming requests.\n\n**Advanced Notes:**\nNative `fs` module uses `uv_fs_*` functions that delegate to thread pool. Network sockets use `uv_poll_t` with OS events. Custom C++ addons can use `napi_create_async_work` to implement non-blocking operations.",[37,38,39],"nonblocking-io","async","filesystem",{"id":41,"category":7,"question":42,"answer":43,"level":10,"tags":44},5,"What is the V8 engine and how does Node.js use it?","**Concept Explanation:**\nV8 is Google's open-source JavaScript engine written in C++. It compiles JavaScript directly to native machine code (JIT - Just In Time compilation) instead of interpreting bytecode. Node.js embeds V8 to provide JavaScript execution environment on the server.\n\n**Execution Flow:**\n1. JavaScript source code parsed into AST (Abstract Syntax Tree)\n2. Ignition interpreter generates bytecode\n3. Profiler monitors hot functions\n4. TurboFan compiler optimizes hot code to machine code\n5. Deoptimization occurs if assumptions invalidated\n\n**Event Loop Explanation:**\nV8 doesn't include event loop; Node.js provides it via libuv. V8 executes JavaScript callbacks when event loop invokes them, but V8 itself knows nothing about timers or I\u002FO.\n\n**Memory Behavior:**\n- V8 manages heap (where objects live)\n- Garbage collection: Minor GC (Scavenger) for young generation, Major GC (Mark-Compact) for old generation\n- Memory limit default: ~1.4GB on 64-bit (can increase via --max-old-space-size)\n\n**Lifecycle Explanation:**\n1. Node.js startup: initializes V8, creates Isolate (V8 instance)\n2. JavaScript code loaded and compiled\n3. V8 executes code, manages allocations\n4. When idle, V8 GC runs\n5. Process exit: V8 shutdown, heap teardown\n\n**Syntax Explanation:**\nV8 is internal; no direct JS API, but you can access V8 flags:\n```bash\nnode --v8-options | grep \"flag\"\nnode --max-old-space-size=4096 app.js\n```\n\n**Practical Example:**\nOptimizing for V8's hidden classes:\n```js\n\u002F\u002F Bad - changes shape after creation\nconst obj = {};\nobj.name = 'Alice';  \u002F\u002F Creates hidden class C0\nobj.age = 30;        \u002F\u002F Transitions to C1\n\n\u002F\u002F Good - define all properties at once\nconst obj = { name: 'Alice', age: 30 }; \u002F\u002F Single hidden class\n\n\u002F\u002F Also bad - polymorphic operations\nfunction add(a, b) { return a + b; }\nadd(1, 2);     \u002F\u002F monomorphic\nadd('x', 'y'); \u002F\u002F polymorphic - deoptimization\n```\n\n**Common Mistakes:**\n- Creating objects with dynamic properties (slow)\n- Deleting properties (forces hidden class transition)\n- Using `try\u002Fcatch` in performance-critical loops\n- Allocating large arrays with holes\n\n**Interview Follow-ups:**\n- Q: How does JIT compilation differ from AOT? A: JIT compiles at runtime based on profiling, enabling optimization for actual usage patterns\n- Q: What's an inline cache? A: V8 optimizes property access by caching object shapes (maps)\n\n**Best Practices:**\n- Initialize object properties in constructor consistently\n- Avoid changing object shapes after creation\n- Use arrays with single type if possible (e.g., all numbers)\n- Keep functions monomorphic (called with same argument types)\n\n**Performance Considerations:**\n- JIT warmup: code may be slower initially, then fast\n- Deoptimizations hurt performance severely\n- Large heap leads to longer GC pauses (stop-the-world)\n- Use `--trace-opt` and `--trace-deopt` to debug optimization issues\n\n**Production Recommendations:**\n- Monitor memory usage; set heap limits\n- Use `--max-semi-space-size` for young generation size\n- Consider `--expose-gc` and manually call `global.gc()` only in tests\n- Run with `--optimize-for-size` for low-memory environments\n\n**Browser Behavior:**\nSame V8 engine in Chrome; but browser adds DOM APIs, Web APIs. Node.js removes those, adds `fs`, `http`, etc.\n\n**Node.js Runtime Behavior:**\n- Node.js creates one V8 Isolate per process (except worker threads each have their own)\n- `vm` module can create additional Isolates\n- V8 serialization used in `postMessage` for worker threads\n\n**Latest Node.js Patterns:**\n- V8 version updates with each Node.js major release\n- `structuredClone()` uses V8's structured cloning algorithm\n- `--heap-snapshot` flag to generate heap snapshots\n\n**TypeScript Example:**\nTypeScript compiles to JavaScript, then V8 runs it. Type annotations have no runtime V8 effect.\n```ts\n\u002F\u002F This TypeScript\nclass User {\n  constructor(public name: string, public age: number) {}\n}\n\u002F\u002F Compiles to JS with consistent hidden class shape\n```\n\n**Interview Tip:**\nExplain that V8 is what makes Node.js fast for CPU tasks, but the event loop makes it scalable for I\u002FO.\n\n**Common Follow-up:**\n\"Can you run multiple V8 instances in one process?\" Yes, using `worker_threads` (each worker has its own Isolate) or `vm` module (multiple contexts in same Isolate).\n\n**Real-world Example:**\nNode.js 12+ uses V8 7.4+ with improved startup performance (bytecode caching). Companies like PayPal saw 40% faster startup after optimizing hidden classes.\n\n**Advanced Notes:**\nV8 has two compilers: Ignition (interpreter) and TurboFan (optimizing compiler). Bytecode is architecture-agnostic. V8 also includes Torque language for builtins. `d8` shell is V8's standalone REPL.",[45,46,47],"v8","javascript-engine","performance",{"id":49,"category":25,"question":50,"answer":51,"level":10,"tags":52},6,"How do you manage dependencies with NPM? Explain package.json, node_modules, and lock files.","**Concept Explanation:**\nNPM (Node Package Manager) is the default package manager for Node.js. `package.json` declares project metadata and dependencies. `node_modules` stores installed packages. Lock files (`package-lock.json`) pin exact versions for reproducible installs.\n\n**Execution Flow:**\n1. `npm init` creates package.json\n2. `npm install \u003Cpkg>` downloads package and its dependencies into node_modules\n3. Dependency tree is flattened as much as possible\n4. package-lock.json records exact versions and integrity hashes\n5. Subsequent installs use lock file to reproduce same tree\n\n**Event Loop Explanation:**\nNot directly related, but `npm install` is a CLI tool that runs separately before Node.js execution. The install process uses its own event loop for network and file operations.\n\n**Memory Behavior:**\nEach `require()` or `import` caches module in `require.cache`. Modules are stored in memory once per process. Large `node_modules` doesn't affect runtime memory except loaded modules.\n\n**Lifecycle Explanation:**\n- `preinstall` \u002F `postinstall` scripts run during install\n- `prepare` runs before pack and publish\n- Lifecycle hooks allow building native addons or downloading binaries\n\n**Syntax Explanation:**\npackage.json example:\n```json\n{\n  \"name\": \"my-app\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node server.js\",\n    \"test\": \"node --test\"\n  },\n  \"dependencies\": {\n    \"express\": \"^4.18.0\"\n  },\n  \"devDependencies\": {\n    \"nodemon\": \"^3.0.0\"\n  }\n}\n```\n\n**Practical Example:**\nManaging versions with npm:\n```bash\n# Install exact version\nnpm install express@4.18.2 --save-exact\n\n# Install dev dependency\nnpm install --save-dev jest\n\n# Update all minor\u002Fpatch versions\nnpm update\n\n# Install from lock file only\nnpm ci  # Faster for CI environments\n```\n\n**Common Mistakes:**\n- Committing `node_modules` to git (should be .gitignore)\n- Not committing `package-lock.json` (leads to inconsistent installs)\n- Using `^` (caret) in production without lock file\n- Forgetting `--save` (now default) - old npm versions\n\n**Interview Follow-ups:**\n- Q: What's difference between `dependencies` and `devDependencies`? A: `devDependencies` are for tools (testing, building), not needed in production; use `npm install --production` to skip them\n- Q: How does npm resolve conflicting versions? A: Nested `node_modules` (nested in the dependent's folder) or hoisting when possible\n\n**Best Practices:**\n- Always commit `package-lock.json` to version control\n- Use `npm ci` in CI\u002FCD for fast, reliable installs\n- Specify engines in package.json for Node.js version requirements\n- Use `npm audit` to check for vulnerabilities\n\n**Performance Considerations:**\n- `node_modules` size can be large (hundreds of MB)\n- `npm install` time increases with dependency count\n- Use `--no-audit` and `--no-fund` in CI for speed\n- Consider `pnpm` or `yarn` for monorepos or disk space\n\n**Production Recommendations:**\n- Run `npm ci --production` in production Docker images\n- Use `.npmrc` to configure registry or authentication\n- Set `NODE_ENV=production` to skip devDependencies automatically\n- Use `npm dedupe` to clean up duplicate packages\n\n**Browser Behavior:**\nNPM is not for browsers directly; bundlers (Webpack, Vite) resolve `import` from `node_modules` for frontend.\n\n**Node.js Runtime Behavior:**\n- Node.js resolves modules by walking up directories looking for `node_modules`\n- `require.resolve()` shows resolution path\n- `--preserve-symlinks` flag changes symlink resolution\n\n**Latest Node.js Patterns:**\n- `--experimental-vm-modules` for isolated module loading\n- `node --import` to preload ESM modules\n- `COREPACK` for managing package manager versions\n\n**TypeScript Example:**\npackage.json with TypeScript:\n```json\n{\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"node dist\u002Findex.js\",\n    \"dev\": \"tsx watch src\u002Findex.ts\"\n  },\n  \"devDependencies\": {\n    \"@types\u002Fnode\": \"^20.0.0\",\n    \"tsx\": \"^4.0.0\",\n    \"typescript\": \"^5.0.0\"\n  }\n}\n```\n\n**Interview Tip:**\nExplain that `package-lock.json` ensures deterministic builds, crucial for security and consistency across environments.\n\n**Common Follow-up:**\n\"What's the difference between `^1.2.3` and `~1.2.3`?\" Carat allows minor and patch updates (~1.2.3 allows patch updates only).\n\n**Real-world Example:**\nWhen Uber migrated from Node.js 8 to 12, they used `package-lock.json` to ensure all services got exact same dependencies, preventing subtle bugs.\n\n**Advanced Notes:**\n`npm` version 7+ automatically installs peer dependencies. `npm` uses `@npmcli\u002Farborist` for tree calculation. `npx` runs packages without installing globally. `npm link` symlinks local packages for development.",[53,54,55],"npm","dependencies","package-json",{"id":57,"category":58,"question":59,"answer":60,"level":10,"tags":61},7,"HTTP","How do you create a basic HTTP server in Node.js using the core http module?","**Concept Explanation:**\nThe `node:http` module provides functionality to create an HTTP server that listens for connections and responds to requests. It's built on Node.js's event-driven architecture and handles each connection as a stream.\n\n**Execution Flow:**\n1. `http.createServer()` returns a server instance\n2. Server listens on a port via `server.listen()`\n3. When request arrives, server emits 'request' event\n4. Callback receives `req` (IncomingMessage) and `res` (ServerResponse)\n5. Developer writes headers and response body\n6. `res.end()` sends response and closes connection (or keeps alive)\n\n**Event Loop Explanation:**\nThe HTTP server uses the event loop's poll phase to accept new connections. Each request is processed asynchronously; long-running operations won't block other requests.\n\n**Memory Behavior:**\n- Each request creates `req` and `res` objects (garbage collected after response)\n- Request body is streamed; buffering all data may cause memory issues\n- Keep-alive connections maintain socket objects in memory\n\n**Lifecycle Explanation:**\n```js\nimport http from 'node:http';\n\nconst server = http.createServer((req, res) => {\n  res.writeHead(200, { 'Content-Type': 'text\u002Fplain' });\n  res.end('Hello World');\n});\n\nserver.on('error', (err) => console.error(err));\n\nserver.listen(3000, () => {\n  console.log('Server listening on port 3000');\n});\n```\n\n**Syntax Explanation:**\n- `createServer(requestListener)` - returns Server object\n- `server.listen(port, hostname, backlog, callback)` - start accepting connections\n- `req` (IncomingMessage): url, method, headers, httpVersion\n- `res` (ServerResponse): writeHead(), write(), end(), setHeader()\n\n**Practical Example:**\nREST API with route handling:\n```js\nimport http from 'node:http';\n\nconst users = [{ id: 1, name: 'Alice' }];\n\nconst server = http.createServer(async (req, res) => {\n  const { method, url } = req;\n  \n  \u002F\u002F Set CORS headers for browser clients\n  res.setHeader('Access-Control-Allow-Origin', '*');\n  res.setHeader('Content-Type', 'application\u002Fjson');\n  \n  if (url === '\u002Fusers' && method === 'GET') {\n    res.end(JSON.stringify(users));\n  } else if (url === '\u002Fusers' && method === 'POST') {\n    let body = '';\n    req.on('data', chunk => body += chunk);\n    req.on('end', () => {\n      const newUser = JSON.parse(body);\n      users.push(newUser);\n      res.statusCode = 201;\n      res.end(JSON.stringify(newUser));\n    });\n  } else {\n    res.statusCode = 404;\n    res.end(JSON.stringify({ error: 'Not found' }));\n  }\n});\n\nserver.listen(8080);\n```\n\n**Common Mistakes:**\n- Forgetting to call `res.end()` - client hangs\n- Not handling `error` events on server or requests\n- Using synchronous operations that block event loop\n- Not parsing request body correctly (concatenating chunks with strings)\n\n**Interview Follow-ups:**\n- Q: How do you handle large request bodies? A: Use streams, not `data` events concatenation\n- Q: What's the difference between `res.end()` and `res.write()`? A: `write()` sends partial data, `end()` finishes response\n\n**Best Practices:**\n- Always call `res.end()` exactly once\n- Set status code before headers or use `res.writeHead()`\n- Use `res.setTimeout()` to prevent slowloris attacks\n- For production, use Express or Fastify instead of raw `http`\n\n**Performance Considerations:**\n- `http.createServer` is fast (handles ~20k+ req\u002Fs on modern hardware)\n- Each request adds small overhead (event emission)\n- Keep-alive reduces TCP handshake overhead\n- Use `server.maxHeadersCount` to limit memory\n\n**Production Recommendations:**\n- Put behind Nginx or HAProxy for SSL, static files, load balancing\n- Enable `server.keepAliveTimeout` appropriately\n- Use `'request'` event or requestListener; `'upgrade'` event for WebSockets\n- Monitor `server.getConnections()` for connection count\n\n**Browser Behavior:**\nBrowser sends requests, receives responses. CORS headers are needed for cross-origin browser requests. Browser expects proper status codes and headers.\n\n**Node.js Runtime Behavior:**\n- `http` module uses `net` module under the hood\n- Supports HTTP\u002F1.1 only (HTTP\u002F2 in `node:http2`)\n- Automatic `Expect: 100-continue` handling\n- `req.socket` provides underlying TCP socket\n\n**Latest Node.js Patterns:**\n- `req.protocol` not in core; check `req.socket.encrypted` for HTTPS\n- `res.req` reference to original request\n- `server.closeAllConnections()` (Node.js 18+)\n\n**TypeScript Example:**\n```ts\nimport http, { IncomingMessage, ServerResponse } from 'node:http';\n\ninterface User {\n  id: number;\n  name: string;\n}\n\nconst server = http.createServer((req: IncomingMessage, res: ServerResponse) => {\n  const { method, url } = req;\n  \n  res.setHeader('Content-Type', 'application\u002Fjson');\n  \n  if (method === 'GET' && url === '\u002Fusers') {\n    const users: User[] = [{ id: 1, name: 'Alice' }];\n    res.end(JSON.stringify(users));\n  } else {\n    res.statusCode = 404;\n    res.end(JSON.stringify({ error: 'Not found' }));\n  }\n});\n\nserver.listen(3000);\n```\n\n**Interview Tip:**\nMention that Node.js HTTP server is production-ready but you'd likely use a framework for routing, middleware, and body parsing.\n\n**Common Follow-up:**\n\"How does Node.js handle 10,000 concurrent HTTP connections?\" Event loop: each connection is just an open socket with callbacks; no threads per connection.\n\n**Real-world Example:**\nThe `http` module powers Express, NestJS, Fastify. Companies like PayPal use custom `http` server implementations for low-latency needs.\n\n**Advanced Notes:**\n`http.globalAgent` manages connection pooling. `keepAlive` sockets can be reused across requests. `agent.maxSockets` default 256. For high concurrency, disable Nagle's algorithm with `socket.setNoDelay()`.",[62,63,64],"http","server","api",{"id":66,"category":7,"question":67,"answer":68,"level":10,"tags":69},8,"What are environment variables in Node.js and how do you use them?","**Concept Explanation:**\nEnvironment variables are key-value pairs set outside the application, accessible via `process.env`. They're used for configuration (database URLs, API keys, NODE_ENV) without hardcoding values in source code.\n\n**Execution Flow:**\n1. When Node.js starts, it copies environment variables from the parent process (shell)\n2. Access via `process.env.VAR_NAME`\n3. Changes to `process.env` affect current process and child processes\n4. Child processes inherit parent's environment by default\n\n**Event Loop Explanation:**\nReading `process.env` is synchronous and doesn't involve event loop. It's a direct property access on the `process` object.\n\n**Memory Behavior:**\nEnvironment variables are stored in the process's memory as strings. Modifying `process.env` adds new key-value pairs to the Node.js representation but doesn't affect the actual system environment.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Set before running\n\u002F\u002F NODE_ENV=production node app.js\n\nconsole.log(process.env.NODE_ENV); \u002F\u002F 'production'\n\n\u002F\u002F Or load from .env file (requires dotenv)\nimport 'dotenv\u002Fconfig';\nconsole.log(process.env.DB_PASSWORD);\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Read\nconst dbUrl = process.env.DATABASE_URL;\n\n\u002F\u002F Set (in-process only)\nprocess.env.MY_VAR = 'value';\n\n\u002F\u002F Check existence\nif (process.env.DEBUG === 'true') {\n  console.log('Debug mode');\n}\n\n\u002F\u002F Default values\nconst port = process.env.PORT || 3000;\n```\n\n**Practical Example:**\nConfiguration management with environment variables:\n```js\n\u002F\u002F config.js\nexport const config = {\n  env: process.env.NODE_ENV || 'development',\n  port: parseInt(process.env.PORT) || 3000,\n  db: {\n    host: process.env.DB_HOST,\n    user: process.env.DB_USER,\n    password: process.env.DB_PASSWORD,\n    database: process.env.DB_NAME\n  },\n  redisUrl: process.env.REDIS_URL,\n  jwtSecret: process.env.JWT_SECRET,\n  isProduction: process.env.NODE_ENV === 'production',\n  isTest: process.env.NODE_ENV === 'test'\n};\n\n\u002F\u002F Validate required variables\nconst required = ['DB_HOST', 'DB_USER', 'JWT_SECRET'];\nfor (const varName of required) {\n  if (!process.env[varName]) {\n    throw new Error(`Missing required env variable: ${varName}`);\n  }\n}\n```\n\n**Common Mistakes:**\n- Committing `.env` file to version control\n- Forgetting to restart application after changing env vars\n- Treating `process.env` as object with inheritance (it's not a plain object)\n- Using env vars for secrets in client-side code\n\n**Interview Follow-ups:**\n- Q: How do you load environment variables from a file? A: Use `dotenv` package or Node.js `--env-file` flag (Node.js 20.6+)\n- Q: What's the difference between `process.env` and `process.argv`? A: `process.argv` contains command-line arguments; env vars are for environment configuration\n\n**Best Practices:**\n- Use `dotenv` for development, never in production\n- Prefix custom variables (e.g., `MYAPP_`)\n- Validate required variables at startup\n- Use `NODE_ENV=production` to enable optimizations\n- Never hardcode secrets; always use env vars or secret managers\n\n**Performance Considerations:**\n- Accessing `process.env` is very fast (property lookup)\n- Modifying `process.env` is slower (creates new copy)\n- Setting many variables at startup is fine\n\n**Production Recommendations:**\n- Use platform's secret management (AWS Secrets Manager, Kubernetes secrets, Vault)\n- Run `node --env-file=.env` instead of `dotenv` package\n- For Docker, use `-e` flags or environment files\n- Log startup without logging secrets\n\n**Browser Behavior:**\nNo `process.env` in browser. Build tools like Webpack replace `process.env.NODE_ENV` at compile time. For runtime config, fetch from server endpoint.\n\n**Node.js Runtime Behavior:**\n- `process.env` returns an object with getters for each environment variable\n- Modifying doesn't change parent shell\n- `process.env` is case-sensitive on Unix, case-insensitive on Windows\n- Special variables: `NODE_OPTIONS`, `NODE_NO_WARNINGS`\n\n**Latest Node.js Patterns:**\n- `--env-file` flag (Node.js 20.6+ stable) to load .env files\n- `process.getBuiltinModule()` not related but useful\n- `process.loadEnvFile()` (Node.js 21.7+) programmatic .env loading\n\n**TypeScript Example:**\n```ts\n\u002F\u002F types\u002Fenv.d.ts\ndeclare global {\n  namespace NodeJS {\n    interface ProcessEnv {\n      NODE_ENV: 'development' | 'production' | 'test';\n      PORT: string;\n      DATABASE_URL: string;\n      JWT_SECRET: string;\n    }\n  }\n}\n\n\u002F\u002F usage\nexport const config = {\n  port: parseInt(process.env.PORT),\n  dbUrl: process.env.DATABASE_URL\n};\n```\n\n**Interview Tip:**\nEmphasize the twelve-factor app principle: store configuration in environment. Explain that it's critical for security (no secrets in code) and dev\u002Fprod parity.\n\n**Common Follow-up:**\n\"How do you handle different environment configs (dev, staging, prod)?\" Use separate .env files (`.env.development`, `.env.production`) or same variables with different values on each platform.\n\n**Real-world Example:**\nStripe uses `process.env.STRIPE_SECRET_KEY` with test keys in development and live keys in production, switching automatically based on NODE_ENV.\n\n**Advanced Notes:**\n`process.env` is backed by `uv_os_getenv` from libuv. On Unix, modifying `process.env` changes the actual process environment via `setenv`. Some internal Node.js modules check env vars at load time, requiring restart to pick up changes.",[70,71,72],"environment-variables","configuration","process",{"id":74,"category":75,"question":76,"answer":77,"level":10,"tags":78},9,"Streams","What are streams in Node.js and why are they important for handling large data?","**Concept Explanation:**\nStreams are objects that let you read data from a source or write data to a destination continuously, piece by piece, instead of loading everything into memory at once. Four types: Readable, Writable, Duplex, Transform.\n\n**Execution Flow:**\n1. Create a readable stream from a file or network\n2. Data flows in chunks (buffer objects)\n3. 'data' events emit each chunk\n4. Pipe to a writable stream\n5. Backpressure automatically manages flow when writable can't keep up\n\n**Event Loop Explanation:**\nStreams use the event loop for asynchronous I\u002FO. 'data' events are emitted from the poll phase when new data is available. Backpressure causes the readable to pause, preventing memory overload.\n\n**Memory Behavior:**\n- Streams process data in small chunks (default 64KB for files)\n- Memory usage is O(chunk size), not O(total data)\n- Internal buffers store pending data when paused\n- HighWaterMark controls buffer size before backpressure\n\n**Lifecycle Explanation:**\n```js\nimport { createReadStream } from 'node:fs';\n\nconst stream = createReadStream('.\u002Flargefile.bin', { highWaterMark: 64 * 1024 });\n\nstream.on('data', (chunk) => {\n  console.log(`Received ${chunk.length} bytes`);\n  \u002F\u002F Process chunk\n});\n\nstream.on('end', () => console.log('File complete'));\nstream.on('error', (err) => console.error(err));\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Readable stream\nconst readable = fs.createReadStream('file.txt');\nreadable.pipe(process.stdout);\n\n\u002F\u002F Writable stream\nconst writable = fs.createWriteStream('output.txt');\nreadable.pipe(writable);\n\n\u002F\u002F Transform stream (modify data)\nimport { Transform } from 'node:stream';\nconst upper = new Transform({\n  transform(chunk, encoding, callback) {\n    callback(null, chunk.toString().toUpperCase());\n  }\n});\nreadable.pipe(upper).pipe(process.stdout);\n```\n\n**Practical Example:**\nProcessing a large CSV file without loading into memory:\n```js\nimport { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\n\nconst rl = createInterface({\n  input: createReadStream('large-data.csv'),\n  crlfDelay: Infinity\n});\n\nrl.on('line', (line) => {\n  \u002F\u002F Process each line individually\n  const [id, name, email] = line.split(',');\n  \u002F\u002F Insert into database, send to API, etc.\n  \u002F\u002F No memory issues even for 10GB file\n});\n```\n\n**Common Mistakes:**\n- Not handling backpressure (piping handles it automatically)\n- Using `readable.on('data')` without `readable.pause()` when processing is slow\n- Forgetting error handlers on streams\n- Not calling `callback()` in custom transform\n\n**Interview Follow-ups:**\n- Q: What is backpressure? A: When writable can't write as fast as readable reads, readable is paused until writable drains\n- Q: Difference between `pipe` and `pipeline`? A: `pipeline` forwards errors and cleans up, `pipe` does not\n\n**Best Practices:**\n- Prefer `stream\u002Fpromises` pipeline for async\u002Fawait\n- Always handle errors with `.on('error')` or try\u002Fcatch\n- Use `finished` utility to detect stream completion\n- Set appropriate `highWaterMark` based on use case\n\n**Performance Considerations:**\n- Streams reduce memory by 90%+ for large files\n- Chunk size affects performance: too small = many syscalls; too large = memory\n- Object mode streams have overhead per object\n- Piping is more efficient than manual 'data' event handling\n\n**Production Recommendations:**\n- Use `pipeline` from `stream\u002Fpromises` for production\n- For HTTP, stream request\u002Fresponse bodies\n- Implement custom streams with `Readable.from()` for simple cases\n- Monitor `readable.readableLength` to detect backpressure\n\n**Browser Behavior:**\nBrowser has Web Streams API (ReadableStream, WritableStream, TransformStream) similar but not identical. Node.js streams are based on EventEmitter.\n\n**Node.js Runtime Behavior:**\n- Internally uses `UV_TTY` for TTY streams\n- File streams use libuv file descriptors\n- Socket streams are net.Socket (Duplex)\n\n**Latest Node.js Patterns:**\n- `stream.compose` to combine streams\n- `Readable.toWeb()` and `Readable.fromWeb()` for Web Streams interop\n- `stream\u002Fpromises` for pipeline with promise support\n\n**TypeScript Example:**\n```ts\nimport { Transform, pipeline } from 'node:stream';\nimport { promisify } from 'node:util';\nimport { createReadStream, createWriteStream } from 'node:fs';\n\nconst pipelineAsync = promisify(pipeline);\n\nconst upperCase = new Transform({\n  transform(chunk: Buffer, encoding: string, callback: (error?: Error | null, data?: Buffer) => void) {\n    callback(null, chunk.toString().toUpperCase());\n  }\n});\n\nasync function processFile() {\n  const source = createReadStream('input.txt');\n  const destination = createWriteStream('output.txt');\n  await pipelineAsync(source, upperCase, destination);\n  console.log('Done');\n}\n```\n\n**Interview Tip:**\nExplain that streams are Node.js's superpower for handling large data (logs, videos, database exports) without OOM errors. Compare to loading entire file with `readFile`.\n\n**Common Follow-up:**\n\"What's the difference between flow mode and paused mode?\" In flow mode, 'data' events auto-emit; in paused mode, you call `read()` manually.\n\n**Real-world Example:**\nNetflix uses Node.js streams to serve video content; the video file is streamed in chunks, allowing seeking and adaptive bitrate without loading entire file on server.\n\n**Advanced Notes:**\nStreams internally use `BufferList` for queuing. `pipe` calls `readable.pipe` which attaches listeners and manages backpressure. `pipeline` uses `AbortController` for cancellation. Custom streams can implement `_read`, `_write`, `_transform`.",[79,47,80],"streams","memory",{"id":82,"category":7,"question":83,"answer":84,"level":10,"tags":85},10,"What is the process object in Node.js? What are its common uses?","**Concept Explanation:**\nThe `process` object is a global that provides information about, and control over, the current Node.js process. It's available everywhere without `require()`. It gives access to environment, arguments, exit codes, and I\u002FO streams.\n\n**Execution Flow:**\n1. `process` object created when Node.js starts\n2. Provides access to `stdin`, `stdout`, `stderr`\n3. Events like 'exit', 'uncaughtException', 'beforeExit' are emitted during process lifecycle\n4. Methods like `exit()` terminate the process\n\n**Event Loop Explanation:**\nThe process object doesn't directly interact with event loop, but events like `exit` are emitted when loop finishes. `process.nextTick()` queues callbacks before the next event loop tick (microtask queue).\n\n**Memory Behavior:**\n`process.memoryUsage()` returns heap stats: rss, heapTotal, heapUsed, external. `process.resourceUsage()` returns more detailed metrics. Process memory includes V8 heap, C++ objects, and libuv resources.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Process events\nprocess.on('exit', (code) => {\n  console.log(`Exiting with code ${code}`);\n  \u002F\u002F Only synchronous operations allowed\n});\n\nprocess.on('uncaughtException', (err) => {\n  console.error('Uncaught exception:', err);\n  \u002F\u002F Clean up, then exit\n  process.exit(1);\n});\n\nprocess.on('SIGINT', () => {\n  console.log('Received SIGINT. Cleaning up...');\n  process.exit();\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Command line arguments\nprocess.argv \u002F\u002F ['node', 'app.js', 'arg1', 'arg2']\n\n\u002F\u002F Exit with code\nprocess.exit(0) \u002F\u002F Success\nprocess.exit(1) \u002F\u002F Failure\n\n\u002F\u002F Working directory\nprocess.cwd()\n\n\u002F\u002F Process ID\nprocess.pid\n\n\u002F\u002F Platform\nprocess.platform \u002F\u002F 'linux', 'darwin', 'win32'\n\n\u002F\u002F Next tick (before event loop)\nprocess.nextTick(() => console.log('Runs next'))\n```\n\n**Practical Example:**\nCLI tool using process:\n```js\n#!\u002Fusr\u002Fbin\u002Fenv node\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nif (command === 'greet') {\n  const name = args[1] || 'World';\n  console.log(`Hello ${name}!`);\n  process.exit(0);\n} else if (command === 'uppercase') {\n  let input = '';\n  process.stdin.on('data', chunk => input += chunk);\n  process.stdin.on('end', () => {\n    console.log(input.toUpperCase());\n  });\n} else {\n  console.error(`Unknown command: ${command}`);\n  process.exit(1);\n}\n```\n\n**Common Mistakes:**\n- Using `process.exit()` without cleaning up (closing DB connections, etc.)\n- Assuming `process.argv` includes everything (first two args are node and script)\n- Not handling `uncaughtException` causing silent crashes\n- Using `process.nextTick` recursively causing event loop starvation\n\n**Interview Follow-ups:**\n- Q: What's difference between `process.nextTick()` and `setImmediate()`? A: `nextTick` fires before event loop continues; `setImmediate` fires in check phase\n- Q: How to get CPU usage? A: `process.cpuUsage()` returns user and system CPU time\n\n**Best Practices:**\n- Use `process.exitCode` instead of `process.exit()` to allow cleanup\n- Always handle `uncaughtException` and `unhandledRejection`\n- Use `process.on('SIGTERM')` for graceful shutdown in containers\n- Prefer `process.env.NODE_ENV` for environment detection\n\n**Performance Considerations:**\n- `process.nextTick` is faster than `Promise.resolve().then()`\n- `process.hrtime.bigint()` for high-resolution timing\n- `process.memoryUsage()` is cheap but not free\n- `process.cpuUsage()` measures cumulative CPU time\n\n**Production Recommendations:**\n- Use `process.exitCode = 1` instead of `process.exit()` in error handlers\n- Implement graceful shutdown: close servers, wait for pending requests, then exit\n- Monitor `process.memoryUsage().heapUsed` for memory leaks\n- Use `--inspect` flag with `process.debugPort` for debugging\n\n**Browser Behavior:**\nBrowser has no `process` global. Polyfills exist for process.env, but not core Node.js behavior.\n\n**Node.js Runtime Behavior:**\n- `process.stdin` is a Duplex stream\n- `process.stdout` and `process.stderr` are Writable streams\n- `process.execPath` returns path to Node.js executable\n- `process.version` returns Node.js version string\n\n**Latest Node.js Patterns:**\n- `process.loadEnvFile()` (Node.js 21.7+) to load .env files\n- `process.getBuiltinModule()` to get built-in module without require\n- `process.report` for diagnostic reporting\n- `process.getActiveResourcesInfo()` for debugging\n\n**TypeScript Example:**\n```ts\n\u002F\u002F Extend ProcessEnv type for custom variables\ndeclare global {\n  namespace NodeJS {\n    interface ProcessEnv {\n      MY_CUSTOM_VAR: string;\n    }\n  }\n}\n\nfunction safeExit(code: number): never {\n  console.log(`Exiting with code ${code}`);\n  process.exit(code);\n}\n\nprocess.on('SIGTERM', () => {\n  console.log('Received SIGTERM, cleaning up...');\n  \u002F\u002F Close database connections, etc.\n  safeExit(0);\n});\n\nconsole.log(`Node.js version: ${process.version}`);\nconsole.log(`Platform: ${process.platform}`);\nconsole.log(`Memory usage: ${JSON.stringify(process.memoryUsage())}`);\n```\n\n**Interview Tip:**\nMention that `process` is the bridge between Node.js JavaScript and the underlying operating system. It's essential for CLI tools, graceful shutdowns, and monitoring.\n\n**Common Follow-up:**\n\"How do you handle unhandled promise rejections globally?\" Use `process.on('unhandledRejection', (reason, promise) => {})`\n\n**Real-world Example:**\nExpress.js uses `process.env.PORT` to determine listen port. PM2 uses `process.send()` for inter-process communication. Docker uses `process.on('SIGTERM')` for graceful container shutdown.\n\n**Advanced Notes:**\n`process.nextTick` uses a queue that can starve I\u002FO if overused. Event loop phases: nextTick callbacks run after each phase. `process._getActiveHandles()` returns active handles (sockets, timers). `process._kill(pid, signal)` sends signals.",[72,86,87],"global-object","cli",{"id":89,"category":7,"question":90,"answer":91,"level":10,"tags":92},11,"What is the Path module in Node.js and how do you use it to work with file paths?","**Concept Explanation:**\nThe `node:path` module provides utilities for working with file and directory paths. It handles path parsing, joining, normalization, and extraction of components (directory, base name, extension) in a platform-agnostic way (Windows vs POSIX).\n\n**Execution Flow:**\n1. Import path module: `import path from 'node:path'`\n2. Use methods like `join()`, `resolve()`, `basename()`, `dirname()`, `extname()`\n3. Path operations are synchronous and pure (no I\u002FO)\n4. Platform-specific behavior: Windows uses backslashes and drive letters; POSIX uses forward slashes\n\n**Event Loop Explanation:**\nPath operations are synchronous and do not involve the event loop. They run immediately on the main thread.\n\n**Memory Behavior:**\nMethods return new strings; no mutation of original paths. Memory allocation per operation is small (path string length).\n\n**Lifecycle Explanation:**\nUsed throughout application lifecycle whenever constructing file paths (reading config, serving static files, requiring modules).\n\n**Syntax Explanation:**\n```js\nimport path from 'node:path';\n\n\u002F\u002F Join segments\nconst fullPath = path.join('\u002Fusers', 'john', 'documents', 'file.txt');\n\u002F\u002F Linux: '\u002Fusers\u002Fjohn\u002Fdocuments\u002Ffile.txt'\n\u002F\u002F Windows: '\\users\\john\\documents\\file.txt'\n\n\u002F\u002F Resolve absolute path\nconst absolute = path.resolve('src', 'index.js');\n\u002F\u002F Returns absolute path from current working directory\n\n\u002F\u002F Parse components\nconst parsed = path.parse('\u002Fhome\u002Fuser\u002Fapp\u002Fconfig.json');\n\u002F\u002F { root: '\u002F', dir: '\u002Fhome\u002Fuser\u002Fapp', base: 'config.json', ext: '.json', name: 'config' }\n\n\u002F\u002F Get basename (file name with extension)\nconst base = path.basename('\u002Fa\u002Fb\u002Fc.txt'); \u002F\u002F 'c.txt'\nconst baseNoExt = path.basename('\u002Fa\u002Fb\u002Fc.txt', '.txt'); \u002F\u002F 'c'\n\n\u002F\u002F Get directory name\nconst dir = path.dirname('\u002Fa\u002Fb\u002Fc\u002Fd.txt'); \u002F\u002F '\u002Fa\u002Fb\u002Fc'\n\n\u002F\u002F Get extension\nconst ext = path.extname('image.jpeg'); \u002F\u002F '.jpeg'\n\n\u002F\u002F Normalize path (remove . and ..)\nconst normalized = path.normalize('\u002Fa\u002Fb\u002F..\u002Fc\u002F.\u002Fd'); \u002F\u002F '\u002Fa\u002Fc\u002Fd'\n```\n\n**Practical Example:**\nDynamic file serving based on request URL:\n```js\nimport http from 'node:http';\nimport path from 'node:path';\nimport fs from 'node:fs\u002Fpromises';\n\nconst server = http.createServer(async (req, res) => {\n  \u002F\u002F Sanitize URL to prevent directory traversal\n  let filePath = path.join(process.cwd(), 'public', req.url);\n  \n  \u002F\u002F Resolve and check if still within public directory\n  const resolvedPath = path.resolve(filePath);\n  const publicDir = path.resolve(process.cwd(), 'public');\n  \n  if (!resolvedPath.startsWith(publicDir)) {\n    res.statusCode = 403;\n    return res.end('Forbidden');\n  }\n  \n  try {\n    const ext = path.extname(filePath);\n    const mimeTypes = { '.html': 'text\u002Fhtml', '.js': 'application\u002Fjavascript', '.css': 'text\u002Fcss' };\n    res.setHeader('Content-Type', mimeTypes[ext] || 'application\u002Foctet-stream');\n    const data = await fs.readFile(filePath);\n    res.end(data);\n  } catch (err) {\n    res.statusCode = 404;\n    res.end('Not Found');\n  }\n});\nserver.listen(3000);\n```\n\n**Common Mistakes:**\n- Using string concatenation (`__dirname + '\u002Ffile.txt'`) instead of `path.join()`\n- Not normalizing user input, leading to directory traversal vulnerabilities\n- Assuming `path.resolve()` always returns a path within current directory\n- Forgetting that `path.extname()` returns the extension including the dot\n\n**Interview Follow-ups:**\n- Q: What's the difference between `path.join()` and `path.resolve()`? A: `join()` concatenates and normalizes; `resolve()` produces absolute path by resolving from current working directory\n- Q: How to get the current file's directory in ES modules? A: Use `import.meta.url` with `fileURLToPath` and `path.dirname()`\n\n**Best Practices:**\n- Always use `path.join()` or `path.resolve()` instead of manual concatenation\n- Validate user-provided paths by resolving and checking prefix\n- Use `path.parse()` when you need all components\n- For cross-platform code, use `path.sep` (path separator) instead of hardcoding '\u002F' or '\\'\n\n**Performance Considerations:**\n- Path operations are cheap (O(n) on path length)\n- Avoid parsing same path repeatedly; cache results if needed\n- `path.resolve()` does filesystem-like resolution without touching disk\n\n**Production Recommendations:**\n- Use `path.normalize()` on user input before security checks\n- For static file servers, combine `path.resolve()` with prefix check\n- Use `path.relative()` to compute relative paths for logging or display\n\n**Browser Behavior:**\nBrowser has no `path` module. Use `URL` API or libraries like `path-browserify`.\n\n**Node.js Runtime Behavior:**\n- `path.win32` and `path.posix` provide platform-specific versions\n- Default `path` uses platform-specific behavior (Windows vs POSIX)\n- `path.toNamespacedPath()` for Windows long path support\n\n**Latest Node.js Patterns:**\n- `import.meta.dirname` and `import.meta.filename` (Node.js 20.11+) as alternatives to `__dirname` in ESM\n- Using `URL` with `file:` protocol for cross-platform paths\n\n**TypeScript Example:**\n```ts\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n\u002F\u002F ESM-compatible __dirname\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nfunction safeJoin(baseDir: string, userPath: string): string {\n  const resolved = path.resolve(baseDir, userPath);\n  if (!resolved.startsWith(baseDir)) {\n    throw new Error('Path traversal detected');\n  }\n  return resolved;\n}\n```\n\n**Interview Tip:**\nMention directory traversal attacks and how `path` module helps prevent them. Show that `path.join()` removes ambiguity.\n\n**Common Follow-up:**\n\"How do you get the file extension without the dot?\" Use `path.extname(filename).slice(1)`.\n\n**Real-world Example:**\nExpress.js static middleware uses `path.resolve()` and `path.normalize()` to serve files safely from a public directory.\n\n**Advanced Notes:**\n`path.resolve()` treats the first argument specially: if it starts with `\u002F` on POSIX or drive letter on Windows, it becomes root. `path.parse()` returns an object that can be used with `path.format()` to reconstruct.",[93,39],"path",{"id":95,"category":7,"question":96,"answer":97,"level":10,"tags":98},12,"What information can you retrieve with the OS module in Node.js? Give examples.","**Concept Explanation:**\nThe `node:os` module provides operating system-related utility methods and system information. It gives access to CPU details, memory stats, network interfaces, system uptime, user info, and platform constants.\n\n**Execution Flow:**\n1. Import `os` module\n2. Call methods synchronously to retrieve system information\n3. Methods query kernel\u002Fsystem APIs (libuv\u002FOS syscalls)\n4. Returns plain JavaScript objects\u002Fnumbers\u002Fstrings\n\n**Event Loop Explanation:**\nAll `os` methods are synchronous and do not involve the event loop. They directly return OS-level information.\n\n**Memory Behavior:**\nReturn values are typically small (strings, numbers, small arrays). Network interfaces may return larger objects but still manageable.\n\n**Lifecycle Explanation:**\nUseful at startup for configuration (adjust thread pool size based on CPU cores), during operation for monitoring (memory usage), or for logging system context.\n\n**Syntax Explanation:**\n```js\nimport os from 'node:os';\n\n\u002F\u002F Platform\nconsole.log(os.platform()); \u002F\u002F 'linux', 'darwin', 'win32'\nconsole.log(os.type()); \u002F\u002F 'Linux', 'Darwin', 'Windows_NT'\nconsole.log(os.release()); \u002F\u002F kernel version\n\n\u002F\u002F CPU information\nconsole.log(os.cpus()); \u002F\u002F Array of CPU cores with speed and times\nconsole.log(os.availableParallelism()); \u002F\u002F Node.js 19+ returns logical cores\n\n\u002F\u002F Memory\nconsole.log(os.totalmem()); \u002F\u002F Total RAM in bytes\nconsole.log(os.freemem()); \u002F\u002F Free RAM in bytes\nconsole.log(os.freemem() \u002F 1024 \u002F 1024, 'MB'); \u002F\u002F In MB\n\n\u002F\u002F System\nconsole.log(os.uptime()); \u002F\u002F System uptime in seconds\nconsole.log(os.loadavg()); \u002F\u002F 1, 5, 15 minute load averages (Unix only)\nconsole.log(os.hostname()); \u002F\u002F System hostname\nconsole.log(os.homedir()); \u002F\u002F Current user's home directory\nconsole.log(os.tmpdir()); \u002F\u002F Temporary directory path\n\n\u002F\u002F Network\nconsole.log(os.networkInterfaces()); \u002F\u002F All network interfaces\nconsole.log(os.userInfo()); \u002F\u002F Current user (username, uid, gid, homedir, shell)\n\n\u002F\u002F Endianness\nconsole.log(os.endianness()); \u002F\u002F 'BE' or 'LE'\n\n\u002F\u002F Constants\nconsole.log(os.constants.signals.SIGINT); \u002F\u002F Signal constants\nconsole.log(os.constants.errno.EADDRINUSE); \u002F\u002F Error code constants\n```\n\n**Practical Example:**\nDynamic configuration based on system resources:\n```js\nimport os from 'node:os';\nimport cluster from 'node:cluster';\nimport http from 'node:http';\n\nconst numCPUs = os.availableParallelism() || os.cpus().length;\nconsole.log(`Detected ${numCPUs} CPU cores`);\n\n\u002F\u002F Set thread pool size for libuv based on CPUs\nprocess.env.UV_THREADPOOL_SIZE = Math.min(16, numCPUs * 2);\n\n\u002F\u002F Cluster workers\nif (cluster.isPrimary) {\n  for (let i = 0; i \u003C numCPUs; i++) {\n    cluster.fork();\n  }\n} else {\n  http.createServer((req, res) => res.end('Hello')).listen(3000);\n}\n\n\u002F\u002F Memory-based cache limit\nconst totalMemGB = os.totalmem() \u002F 1024 \u002F 1024 \u002F 1024;\nconst maxCacheSizeMB = Math.floor(totalMemGB * 0.1); \u002F\u002F Use 10% of RAM for cache\nconsole.log(`Cache size limited to ${maxCacheSizeMB}MB`);\n```\n\n**Common Mistakes:**\n- Assuming `os.cpus()` always returns an array (always does, but could be empty in containers)\n- Using `os.loadavg()` on Windows (returns 0 values as placeholder)\n- Not handling network interfaces with internal IPv6 addresses\n- Using `os.userInfo()` on Windows where some fields may be undefined\n\n**Interview Follow-ups:**\n- Q: What's the difference between `os.totalmem()` and `process.memoryUsage().rss`? A: `totalmem` is system RAM; RSS is memory used by this Node.js process\n- Q: How to check if running in a container? A: No direct method, but check `os.cpus().length` vs `os.availableParallelism()` difference or container-specific env vars\n\n**Best Practices:**\n- Cache values that don't change (e.g., `os.cpus()`) at startup\n- Use `os.availableParallelism()` over `os.cpus().length` for worker count (respects CPU affinity)\n- For cross-platform code, check `os.platform()` before using Unix-specific calls\n- Use `os.freemem()` for health checks but don't rely on it for precise scheduling\n\n**Performance Considerations:**\n- `os.cpus()` can be slow on some systems (reads \u002Fproc\u002Fcpuinfo); call once at startup\n- `os.networkInterfaces()` can be expensive; avoid frequent calls\n- `os.freemem()` is fast (syscall) but still synchronous\n- Memory values are in bytes; convert to MB\u002FGB for readability\n\n**Production Recommendations:**\n- Use `os.freemem()` in health endpoints to detect memory pressure\n- Adjust `UV_THREADPOOL_SIZE` based on `os.cpus()` for CPU-heavy I\u002FO\n- Log `os.hostname()` in distributed systems to identify node\n- Use `os.uptime()` to detect system restarts (alert if uptime resets unexpectedly)\n\n**Browser Behavior:**\nNot available in browsers. Polyfills may provide limited info.\n\n**Node.js Runtime Behavior:**\n- On Windows, `os.cpus()` returns correct values but times are less detailed\n- `os.endianness()` is always 'LE' on x64\u002FARM64 (modern systems)\n- `os.constants` includes error codes, signals, and priority levels\n\n**Latest Node.js Patterns:**\n- `os.availableParallelism()` (Node.js 19+ stable in 20+)\n- `os.machine()` (Node.js 18+ for CPU architecture: x86_64, arm64)\n- `os.version()` (Node.js 13+) for OS version string\n\n**TypeScript Example:**\n```ts\nimport os from 'node:os';\n\ninterface SystemMetrics {\n  platform: NodeJS.Platform;\n  totalMemoryGB: number;\n  freeMemoryGB: number;\n  cpuCount: number;\n  loadAvg: number[];\n  uptimeHours: number;\n}\n\nfunction getSystemMetrics(): SystemMetrics {\n  return {\n    platform: os.platform(),\n    totalMemoryGB: os.totalmem() \u002F (1024 ** 3),\n    freeMemoryGB: os.freemem() \u002F (1024 ** 3),\n    cpuCount: os.availableParallelism(),\n    loadAvg: os.loadavg(),\n    uptimeHours: os.uptime() \u002F 3600\n  };\n}\n\n\u002F\u002F Get network interfaces without internal IPs\nconst interfaces = Object.values(os.networkInterfaces()).flat().filter(iface => !iface.internal);\n```\n\n**Interview Tip:**\nUse `os` module to demonstrate understanding of environment-aware programming. Show how to scale workers based on CPU count.\n\n**Common Follow-up:**\n\"How do you get the number of logical vs physical CPU cores?\" Use `os.cpus().length` for logical; physical requires native module or parsing `\u002Fproc\u002Fcpuinfo`.\n\n**Real-world Example:**\nPM2 uses `os.cpus().length` to determine default number of cluster processes. Logging libraries use `os.hostname()` to add host identifier to logs.\n\n**Advanced Notes:**\n`os.freemem()` returns available memory, but some may be cached\u002Fbuffered; `os.totalmem()` - `os.freemem()` gives used memory including caches. `os.networkInterfaces()` returns IPv4 and IPv6; filter for `family: 'IPv4'` for external IPs.",[99,100],"os","system-info",{"id":102,"category":103,"question":104,"answer":105,"level":10,"tags":106},13,"Buffers","What are Buffers in Node.js? How do they differ from arrays and strings?","**Concept Explanation:**\n`Buffer` is a global class in Node.js for handling binary data (raw bytes). Unlike strings (UTF-8 encoded text) and arrays (JavaScript objects with overhead), buffers are fixed-size chunks of memory allocated outside the V8 heap. They are essential for dealing with TCP streams, file I\u002FO, cryptography, and binary protocols.\n\n**Execution Flow:**\n1. Create a buffer of specific size or from data (string, array, another buffer)\n2. Buffer memory allocated in C++ (managed by Node.js\u002FUV)\n3. Data can be read\u002Fwritten using numeric indices or methods\n4. When buffer is no longer referenced, memory is freed (but not garbage collected in JS sense)\n\n**Event Loop Explanation:**\nBuffer creation and manipulation are synchronous and CPU-bound. They don't involve the event loop but can block if large allocations happen frequently.\n\n**Memory Behavior:**\n- Buffer memory lives in a separate external memory region (not V8 heap)\n- `Buffer.alloc()` initializes memory (zero-filled, safer)\n- `Buffer.allocUnsafe()` avoids zero-fill but may contain old data (performance)\n- Memory freed when no references exist (using `malloc`\u002F`free`)\n- `Buffer.poolSize` controls internal pool (default 8KB)\n\n**Lifecycle Explanation:**\nCreated when reading binary data (file chunks, network packets), manipulated (slice, copy, concatenate), then eventually garbage collected when out of scope.\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Creation\nconst buf1 = Buffer.alloc(10); \u002F\u002F 10 bytes filled with zeros\nconst buf2 = Buffer.from('Hello'); \u002F\u002F UTF-8 string to buffer\nconst buf3 = Buffer.from([72, 101, 108, 108, 111]); \u002F\u002F From byte array\nconst buf4 = Buffer.allocUnsafe(100); \u002F\u002F Fast but unsafe (uninitialized)\n\n\u002F\u002F Read\u002Fwrite\nbuf2[0] = 104; \u002F\u002F Modify first byte (lowercase 'h')\nconsole.log(buf2[0]); \u002F\u002F 104 (numeric byte value)\nconsole.log(buf2.toString()); \u002F\u002F 'hello'\nconsole.log(buf2.toString('hex')); \u002F\u002F '68656c6c6f'\n\n\u002F\u002F Slicing (shallow, shares memory)\nconst slice = buf2.subarray(1, 3); \u002F\u002F 'el' (bytes 1-2)\nslice[0] = 100; \u002F\u002F modifies original!\n\n\u002F\u002F Copy\nconst copy = Buffer.allocUnsafe(5);\nbuf2.copy(copy);\n\n\u002F\u002F Concatenation\nconst total = Buffer.concat([buf2, Buffer.from(' World')]);\n```\n\n**Practical Example:**\nParsing a binary file header:\n```js\nimport { readFile } from 'node:fs\u002Fpromises';\n\nasync function parseImageHeader(filePath) {\n  const buffer = await readFile(filePath);\n  \n  \u002F\u002F Check PNG signature\n  const pngSignature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);\n  if (!buffer.subarray(0, 8).equals(pngSignature)) {\n    throw new Error('Not a PNG file');\n  }\n  \n  \u002F\u002F Read IHDR chunk (bytes 16-24)\n  const width = buffer.readUInt32BE(16);\n  const height = buffer.readUInt32BE(20);\n  const bitDepth = buffer[24];\n  const colorType = buffer[25];\n  \n  return { width, height, bitDepth, colorType };\n}\n```\n\n**Common Mistakes:**\n- Using `Buffer.from(string)` without encoding parameter (defaults to 'utf8')\n- Assuming `buf.slice()` creates a copy (it doesn't; use `copy()`)\n- Forgetting that indices access bytes (0-255), not characters\n- Using `new Buffer()` (deprecated, unsafe) instead of `Buffer.from()` or `Buffer.alloc()`\n\n**Interview Follow-ups:**\n- Q: Why is `Buffer.allocUnsafe()` faster? A: Skips zero-fill, reuses uninitialized memory; but may leak sensitive data if not fully overwritten\n- Q: How does Buffer differ from Uint8Array? A: Buffer extends Uint8Array (Node.js 4+), but adds Node-specific methods like `write()`, `read()`\n\n**Best Practices:**\n- Always prefer `Buffer.alloc()` over `Buffer.allocUnsafe()` unless performance critical\n- Use `buf.equals()` for comparison, not `==` or `===`\n- For large buffers, reuse them from a pool to reduce allocations\n- Use `buf.toString('hex')` for debugging binary data\n\n**Performance Considerations:**\n- `Buffer.allocUnsafe()` is ~2x faster than `Buffer.alloc()`\n- `buffer.slice()` is O(1) (just creates a view)\n- `buffer.copy()` is O(n) (copies bytes)\n- Avoid creating many small buffers; use pooling or `Buffer.concat()`\n\n**Production Recommendations:**\n- For HTTP request bodies, use streams with buffers, not `Buffer.concat()` of all chunks\n- Use `Buffer.allocUnsafe()` in hot paths after confirming memory is overwritten\n- Monitor external memory usage via `process.memoryUsage().external`\n- Use `Buffer.poolSize` to tune allocation pool for high-throughput apps\n\n**Browser Behavior:**\nNo `Buffer` in browsers. Use `Uint8Array` and `TextEncoder`\u002F`TextDecoder` for string\u002Fbinary conversion. Node.js Buffer extends Uint8Array but has extra methods.\n\n**Node.js Runtime Behavior:**\n- Buffers are instances of Uint8Array (subclass)\n- Internal memory management uses `malloc`\u002F`free`\n- `Buffer.poolSize` controls small buffer pooling\n- `--zero-fill-buffers` flag forces zero-fill (security, but slower)\n\n**Latest Node.js Patterns:**\n- `Buffer.from(arrayBuffer, byteOffset, length)` to wrap existing ArrayBuffer\n- `Buffer.isBuffer(obj)` to check if object is buffer\n- Using `buf.swap16()`, `swap32()`, `swap64()` for endianness conversion\n\n**TypeScript Example:**\n```ts\nimport { Buffer } from 'node:buffer';\n\ninterface Frame {\n  type: number;\n  length: number;\n  payload: Buffer;\n}\n\nfunction parseFrame(data: Buffer): Frame {\n  const type = data.readUInt8(0);\n  const length = data.readUInt16BE(1);\n  const payload = data.subarray(3, 3 + length);\n  return { type, length, payload };\n}\n\nfunction serializeFrame(frame: Frame): Buffer {\n  const buffer = Buffer.allocUnsafe(3 + frame.length);\n  buffer.writeUInt8(frame.type, 0);\n  buffer.writeUInt16BE(frame.length, 1);\n  frame.payload.copy(buffer, 3);\n  return buffer;\n}\n```\n\n**Interview Tip:**\nExplain that buffers bridge the gap between Node.js JavaScript and C++\u002FOS-level binary data. Mention that every stream chunk is a buffer.\n\n**Common Follow-up:**\n\"What's the maximum buffer size?\" Depends on system: `buffer.constants.MAX_LENGTH` (typically ~2GB on 64-bit).\n\n**Real-world Example:**\nDatabase drivers (PostgreSQL, MySQL) use buffers to parse binary protocol messages. Redis client uses buffers for RESP protocol.\n\n**Advanced Notes:**\nBuffer memory is tracked by V8's `ArrayBuffer` backing store. `Buffer.allocUnsafe()` may reuse freed memory containing sensitive data (crypto keys, passwords) – always overwrite. `Buffer.poolSize` affects allocation strategy: buffers \u003C poolSize use pooled memory.",[107,108],"buffers","binary-data",{"id":110,"category":7,"question":111,"answer":112,"level":10,"tags":113},14,"How do you use native fetch in Node.js? How is it different from browser fetch?","**Concept Explanation:**\nThe `fetch()` function is a native Web API for making HTTP requests, available in Node.js 18+ as an experimental feature and stable from Node.js 21+. It implements the WHATWG Fetch standard, providing a promise-based interface for network requests without requiring external libraries like `axios` or `node-fetch`.\n\n**Execution Flow:**\n1. Call `fetch(url, options)` – returns a Promise\n2. Node.js performs DNS resolution, TCP connection, TLS handshake (if HTTPS), sends request\n3. Response headers arrive; `fetch()` resolves with a `Response` object\n4. Body streams as chunks; can consume with `res.text()`, `res.json()`, `res.arrayBuffer()`, `res.blob()`\n5. Response body must be consumed (or canceled) to avoid memory leaks\n\n**Event Loop Explanation:**\n`fetch()` uses the event loop for non-blocking network I\u002FO. DNS resolution may use libuv thread pool. The promise resolves in a future event loop tick.\n\n**Memory Behavior:**\n- Response body is streamed, but `res.json()`\u002F`res.text()` buffer entire response in memory\n- For large responses, use `res.body` (ReadableStream) with chunks\n- Each `fetch()` creates a `AbortController` if timeout needed\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Basic GET\nconst response = await fetch('https:\u002F\u002Fapi.example.com\u002Fusers');\nconst data = await response.json();\n\n\u002F\u002F POST with JSON\nconst res = await fetch('https:\u002F\u002Fapi.example.com\u002Fusers', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application\u002Fjson' },\n  body: JSON.stringify({ name: 'Alice' })\n});\n\nif (!res.ok) throw new Error(`HTTP ${res.status}`);\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Standard fetch\nimport fetch from 'node:fetch'; \u002F\u002F Not needed; global in Node.js 18+\n\n\u002F\u002F Options\nconst options = {\n  method: 'GET', \u002F\u002F or 'POST', 'PUT', 'DELETE', 'PATCH'\n  headers: {\n    'Authorization': `Bearer ${token}`,\n    'Content-Type': 'application\u002Fjson'\n  },\n  body: JSON.stringify(data),\n  signal: AbortSignal.timeout(5000), \u002F\u002F Auto-abort after 5 seconds\n  \u002F\u002F Node.js-specific: (not standard)\n  \u002F\u002F agent: new http.Agent({ keepAlive: true }),\n};\n\nconst res = await fetch(url, options);\n\n\u002F\u002F Response methods\nres.status \u002F\u002F 200\nres.statusText \u002F\u002F 'OK'\nres.ok \u002F\u002F true if 2xx\nres.headers \u002F\u002F Headers object\nconst json = await res.json()\nconst text = await res.text()\nconst buffer = Buffer.from(await res.arrayBuffer())\n```\n\n**Practical Example:**\nAPI client with retry and timeout:\n```js\nasync function fetchWithRetry(url, options = {}, maxRetries = 3) {\n  for (let i = 0; i \u003C maxRetries; i++) {\n    try {\n      const controller = new AbortController();\n      const timeoutId = setTimeout(() => controller.abort(), options.timeout || 10000);\n      \n      const response = await fetch(url, {\n        ...options,\n        signal: controller.signal\n      });\n      \n      clearTimeout(timeoutId);\n      \n      if (!response.ok && i \u003C maxRetries - 1 && response.status >= 500) {\n        await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));\n        continue;\n      }\n      \n      return response;\n    } catch (err) {\n      if (i === maxRetries - 1) throw err;\n      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));\n    }\n  }\n}\n\n\u002F\u002F Usage\nconst res = await fetchWithRetry('https:\u002F\u002Fapi.github.com\u002Fusers\u002Foctocat');\nconst user = await res.json();\n```\n\n**Common Mistakes:**\n- Not checking `res.ok` – fetch only rejects on network errors, not HTTP errors (404, 500)\n- Forgetting to await `res.json()` or `res.text()`\n- Not handling `AbortError` from timeouts\n- Assuming `fetch` is available in older Node.js versions (\u003C18) without flag\n\n**Interview Follow-ups:**\n- Q: How does Node.js fetch differ from browser fetch? A: Node.js version adds `agent` option for custom HTTP agent (keep-alive, proxy), but otherwise API identical\n- Q: What about HTTP\u002F2 support? A: fetch uses HTTP\u002F1.1 by default; HTTP\u002F2 requires custom agent or third-party library\n\n**Best Practices:**\n- Always set a timeout using `AbortSignal.timeout(ms)`\n- Check `res.ok` and handle non-2xx responses\n- Use `res.clone()` if you need to consume body multiple times\n- For streaming responses, use `res.body.getReader()` for large data\n- Reuse `AbortController` for cancelling multiple requests (e.g., SPA navigation)\n\n**Performance Considerations:**\n- Each `fetch` creates a new connection by default (no keep-alive in Node.js standard fetch)\n- For high-throughput, use custom `Agent` with `keepAlive: true` (via `undici` options)\n- `res.json()` parses full body; consider streaming parser for huge JSON\n- Parallel requests with `Promise.all` are efficient\n\n**Production Recommendations:**\n- Set default timeout globally using `AbortSignal.timeout` or custom wrapper\n- Implement retry logic with exponential backoff for transient failures\n- Use connection pooling via custom Agent: `new http.Agent({ keepAlive: true, maxSockets: 50 })`\n- Monitor fetch latency and error rates; `fetch` is built on `undici` – use its diagnostics\n\n**Browser Behavior:**\nBrowser fetch has same API but with browser-specific limitations (CORS, no custom agents). Node.js fetch doesn't have CORS restrictions.\n\n**Node.js Runtime Behavior:**\n- Implemented via `undici` HTTP\u002F1.1 client\n- Requires Node.js 18+ (experimental), stable in 21+\n- Can be disabled with `--no-experimental-fetch`\n- `fetch` is global, no `require('node:fetch')` needed\n\n**Latest Node.js Patterns:**\n- `AbortSignal.timeout(ms)` for easy timeouts\n- `fetch` with `Blob` and `FormData` support (full WHATWG compatibility)\n- `Response.json()` static method for creating responses\n\n**TypeScript Example:**\n```ts\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nasync function fetchUser(id: number): Promise\u003CUser> {\n  const response = await fetch(`https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fusers\u002F${id}`);\n  \n  if (!response.ok) {\n    throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n  }\n  \n  const user = await response.json() as User;\n  return user;\n}\n\n\u002F\u002F With timeout and type guard\nasync function safeFetch\u003CT>(url: string): Promise\u003CT | null> {\n  try {\n    const res = await fetch(url, { signal: AbortSignal.timeout(5000) });\n    if (!res.ok) return null;\n    return await res.json() as T;\n  } catch (err) {\n    console.error('Fetch failed:', err);\n    return null;\n  }\n}\n```\n\n**Interview Tip:**\nCompare fetch with other HTTP clients: built-in (no install, standard), less feature-rich than axios (interceptors, request cancellation, progress events), but sufficient for most needs.\n\n**Common Follow-up:**\n\"How do you upload a file using fetch?\" Use `FormData` or `Blob` in body, set `Content-Type: multipart\u002Fform-data` automatically when using FormData.\n\n**Real-world Example:**\nStripe SDK uses fetch internally in Node.js 18+; they removed `node-fetch` dependency, reducing bundle size.\n\n**Advanced Notes:**\nNode.js fetch uses `undici` which supports `Dispatcher` interface for custom connection management. `fetch` doesn't support HTTP\u002F2 multiplexing; for that use `http2.connect` or `http2.fetch` in the future.",[114,115,64],"fetch","http-client",{"id":117,"category":118,"question":119,"answer":120,"level":10,"tags":121},15,"Express.js","What is Express.js and how do you build a basic REST API with it?","**Concept Explanation:**\nExpress.js is a minimal and flexible Node.js web application framework that provides a thin layer of fundamental web application features, without obscuring Node.js features. It simplifies routing, middleware integration, request\u002Fresponse handling, and template engine integration.\n\n**Execution Flow:**\n1. Create Express app: `const app = express()`\n2. Define routes: `app.get()`, `app.post()`, etc.\n3. Add middleware: `app.use(express.json())` for body parsing\n4. Start server: `app.listen(port)`\n5. Each request goes through middleware chain → route handler → response\n\n**Event Loop Explanation:**\nExpress doesn't change Node.js event loop; it's a collection of functions that respond to requests. Each request triggers callbacks (route handlers) that run asynchronously on the event loop.\n\n**Memory Behavior:**\n- Each middleware function is stored in an array\n- Route handlers are stored in a routing table (trie structure)\n- `req` and `res` objects are augmented with Express methods\n- Session data (if used) stored in memory by default (not for production)\n\n**Lifecycle Explanation:**\n```js\nimport express from 'express';\n\nconst app = express();\n\n\u002F\u002F Middleware (runs for every request)\napp.use(express.json());\napp.use((req, res, next) => {\n  console.log(`${req.method} ${req.url}`);\n  next(); \u002F\u002F Pass control to next middleware\u002Froute\n});\n\n\u002F\u002F Routes\napp.get('\u002F', (req, res) => {\n  res.send('Hello World');\n});\n\napp.get('\u002Fusers\u002F:id', (req, res) => {\n  const userId = req.params.id;\n  res.json({ id: userId, name: 'Alice' });\n});\n\napp.post('\u002Fusers', (req, res) => {\n  const newUser = req.body;\n  res.status(201).json(newUser);\n});\n\napp.listen(3000, () => console.log('Server started'));\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F CRUD routes\napp.get('\u002Fitems', getItems);        \u002F\u002F Read all\napp.get('\u002Fitems\u002F:id', getItemById); \u002F\u002F Read one\napp.post('\u002Fitems', createItem);     \u002F\u002F Create\napp.put('\u002Fitems\u002F:id', updateItem);  \u002F\u002F Update (full)\napp.patch('\u002Fitems\u002F:id', patchItem); \u002F\u002F Update (partial)\napp.delete('\u002Fitems\u002F:id', deleteItem); \u002F\u002F Delete\n\n\u002F\u002F Route parameters\n\u002F\u002F URL: \u002Fusers\u002F42\u002Fposts\u002F7\napp.get('\u002Fusers\u002F:userId\u002Fposts\u002F:postId', (req, res) => {\n  req.params.userId; \u002F\u002F '42'\n  req.params.postId; \u002F\u002F '7'\n});\n\n\u002F\u002F Query string: \u002Fsearch?q=express&page=2\napp.get('\u002Fsearch', (req, res) => {\n  req.query.q; \u002F\u002F 'express'\n  req.query.page; \u002F\u002F '2'\n});\n```\n\n**Practical Example:**\nComplete REST API for task management:\n```js\nimport express from 'express';\n\nconst app = express();\nconst port = process.env.PORT || 3000;\n\napp.use(express.json());\n\nlet tasks = [];\nlet nextId = 1;\n\n\u002F\u002F GET \u002Ftasks\napp.get('\u002Ftasks', (req, res) => {\n  res.json(tasks);\n});\n\n\u002F\u002F GET \u002Ftasks\u002F:id\napp.get('\u002Ftasks\u002F:id', (req, res) => {\n  const task = tasks.find(t => t.id === parseInt(req.params.id));\n  if (!task) return res.status(404).json({ error: 'Task not found' });\n  res.json(task);\n});\n\n\u002F\u002F POST \u002Ftasks\napp.post('\u002Ftasks', (req, res) => {\n  const { title, completed = false } = req.body;\n  if (!title) return res.status(400).json({ error: 'Title required' });\n  const task = { id: nextId++, title, completed };\n  tasks.push(task);\n  res.status(201).json(task);\n});\n\n\u002F\u002F PUT \u002Ftasks\u002F:id\napp.put('\u002Ftasks\u002F:id', (req, res) => {\n  const id = parseInt(req.params.id);\n  const index = tasks.findIndex(t => t.id === id);\n  if (index === -1) return res.status(404).json({ error: 'Not found' });\n  const { title, completed } = req.body;\n  tasks[index] = { ...tasks[index], title, completed };\n  res.json(tasks[index]);\n});\n\n\u002F\u002F DELETE \u002Ftasks\u002F:id\napp.delete('\u002Ftasks\u002F:id', (req, res) => {\n  const id = parseInt(req.params.id);\n  const index = tasks.findIndex(t => t.id === id);\n  if (index === -1) return res.status(404).json({ error: 'Not found' });\n  tasks.splice(index, 1);\n  res.status(204).send();\n});\n\napp.listen(port);\n```\n\n**Common Mistakes:**\n- Forgetting `express.json()` middleware – `req.body` will be undefined\n- Using `res.send()` after `res.json()` (can't send twice)\n- Not handling async errors (Express 4 needs `next(err)` or try\u002Fcatch)\n- Putting logic before `next()` that might throw – wrap in try\u002Fcatch\n\n**Interview Follow-ups:**\n- Q: What's the difference between `app.use()` and `app.METHOD()`? A: `app.use()` matches all HTTP methods and path prefixes; `app.get()` only GET and exact path match\n- Q: How does Express handle errors? A: Middleware with 4 parameters `(err, req, res, next)` catches errors from `next(err)`\n\n**Best Practices:**\n- Organize routes with `express.Router()` for modularity\n- Use environment variables for configuration\n- Add helmet.js for security headers\n- Compress responses with compression middleware\n- Validate request data using libraries like Joi or Zod\n- Use async wrappers to avoid unhandled rejections\n\n**Performance Considerations:**\n- Express is lightweight (~2x overhead over raw http)\n- Each middleware adds function call overhead\n- Avoid synchronous functions that block event loop\n- Use `res.json()` instead of `res.send(JSON.stringify(obj))` (optimized)\n\n**Production Recommendations:**\n- Use `express-rate-limit` to prevent brute force\n- Deploy behind Nginx; enable gzip\n- Use PM2 or cluster module for multi-core scaling\n- Set `NODE_ENV=production` (disables view caching and error stack traces)\n- Use `express-async-errors` or Express 5 (beta) for async error handling\n\n**Browser Behavior:**\nExpress runs on server; browsers make HTTP requests to its endpoints. CORS headers needed for browser clients from different origins.\n\n**Node.js Runtime Behavior:**\nExpress extends Node.js `http` module's `req` and `res` objects, adding methods like `res.json()`, `res.send()`, `req.params`, `req.query`.\n\n**Latest Node.js Patterns:**\n- Express 5 (beta) supports promises and async handlers natively\n- Using ES modules with Express (set `\"type\": \"module\"` in package.json)\n- `app.set('trust proxy', true)` when behind reverse proxy\n\n**TypeScript Example:**\n```ts\nimport express, { Request, Response, NextFunction } from 'express';\n\ninterface Task {\n  id: number;\n  title: string;\n  completed: boolean;\n}\n\nconst app = express();\napp.use(express.json());\n\nconst tasks: Task[] = [];\n\napp.get('\u002Ftasks', (req: Request, res: Response) => {\n  res.json(tasks);\n});\n\napp.post('\u002Ftasks', (req: Request\u003C{}, {}, { title: string }>, res: Response) => {\n  const { title } = req.body;\n  if (!title) {\n    return res.status(400).json({ error: 'Title required' });\n  }\n  const task: Task = { id: tasks.length + 1, title, completed: false };\n  tasks.push(task);\n  res.status(201).json(task);\n});\n\n\u002F\u002F Async error handler wrapper\nconst asyncHandler = (fn: Function) => (req: Request, res: Response, next: NextFunction) => {\n  Promise.resolve(fn(req, res, next)).catch(next);\n};\n\napp.listen(3000);\n```\n\n**Interview Tip:**\nCompare Express to alternatives: Fastify (faster, schema validation), Koa (modern, no callback hell), NestJS (opinionated, TypeScript-first). Express remains most popular due to ecosystem.\n\n**Common Follow-up:**\n\"How do you serve static files with Express?\" `app.use(express.static('public'))` – serves files from `public` directory.\n\n**Real-world Example:**\nUber's API gateway was built with Express; they contributed middleware back to the community. PayPal migrated from Java to Node.js\u002FExpress, reducing development time by 33%.\n\n**Advanced Notes:**\nExpress 5 will drop support for Node.js \u003C 18 and include `router.route()` improvements. The `express.json()` limit can be configured: `express.json({ limit: '10mb' })`. `app.param()` for parameter validation middleware.",[122,64,123],"express","rest",{"id":125,"category":7,"question":126,"answer":127,"level":10,"tags":128},16,"How do you handle JSON in Node.js? Parse, stringify, and work with JSON files.","**Concept Explanation:**\nJSON (JavaScript Object Notation) is the primary data interchange format for Node.js APIs. Node.js provides global `JSON` object with `parse()` (string → object) and `stringify()` (object → string) methods. For file operations, combine with `fs` module.\n\n**Execution Flow:**\n1. Receive JSON string (from request body, file, API)\n2. `JSON.parse()` validates and converts to JavaScript object\n3. Work with the object (modify, validate)\n4. `JSON.stringify()` converts back to string\n5. Send or store the string\n\n**Event Loop Explanation:**\nJSON parsing is synchronous and CPU-bound. Large JSON parsing blocks event loop. For huge JSON, use streaming parsers (JSONStream, oboe.js).\n\n**Memory Behavior:**\n- `JSON.parse()` creates full object tree in memory\n- `JSON.stringify()` creates a single string (can be huge)\n- Circular references cause `JSON.stringify()` to throw\n- Large JSON can exhaust memory (e.g., 500MB file)\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Parse JSON string\nconst jsonString = '{\"name\":\"Alice\",\"age\":30}';\nconst obj = JSON.parse(jsonString);\nconsole.log(obj.name); \u002F\u002F 'Alice'\n\n\u002F\u002F Stringify object\nconst obj2 = { name: 'Bob', age: 25 };\nconst string = JSON.stringify(obj2);\nconsole.log(string); \u002F\u002F '{\"name\":\"Bob\",\"age\":25}'\n\n\u002F\u002F Pretty print\nconst pretty = JSON.stringify(obj2, null, 2);\n\u002F\u002F {\n\u002F\u002F   \"name\": \"Bob\",\n\u002F\u002F   \"age\": 25\n\u002F\u002F }\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F parse with reviver (transform values)\nconst data = JSON.parse('{\"date\":\"2024-01-01\"}', (key, value) => {\n  if (key === 'date') return new Date(value);\n  return value;\n});\n\n\u002F\u002F stringify with replacer (filter\u002Ftransform)\nconst filtered = JSON.stringify(obj, ['name', 'age']); \u002F\u002F only these keys\nconst transformed = JSON.stringify(obj, (key, value) => {\n  if (typeof value === 'string') return value.toUpperCase();\n  return value;\n});\n\n\u002F\u002F Handle BigInt (not JSON-serializable by default)\nconst withBigInt = { id: 12345678901234567890n };\nconst serialized = JSON.stringify(withBigInt, (key, value) =>\n  typeof value === 'bigint' ? value.toString() : value\n);\n```\n\n**Practical Example:**\nReading and writing config.json:\n```js\nimport { readFile, writeFile } from 'node:fs\u002Fpromises';\n\nasync function loadConfig() {\n  try {\n    const data = await readFile('.\u002Fconfig.json', 'utf8');\n    return JSON.parse(data);\n  } catch (err) {\n    if (err.code === 'ENOENT') {\n      \u002F\u002F Default config if file doesn't exist\n      return { port: 3000, env: 'development' };\n    }\n    throw err;\n  }\n}\n\nasync function saveConfig(config) {\n  const data = JSON.stringify(config, null, 2);\n  await writeFile('.\u002Fconfig.json', data, 'utf8');\n}\n\n\u002F\u002F Usage\nconst config = await loadConfig();\nconfig.port = 8080;\nawait saveConfig(config);\n```\n\n**Common Mistakes:**\n- Not catching `JSON.parse()` errors (malformed JSON throws)\n- Using `JSON.stringify()` on objects with circular references\n- Assuming `JSON.parse()` handles Dates, BigInts, undefined, functions (it doesn't)\n- Forgetting `await` when reading files, parsing empty or invalid JSON\n\n**Interview Follow-ups:**\n- Q: What are the limitations of JSON? A: No comments, no Date\u002FRegExp\u002FFunction\u002Fundefined\u002FBigInt, no circular references, verbose\n- Q: How to parse large JSON files? A: Use streaming parsers like `JSONStream` or process line-delimited JSON\n\n**Best Practices:**\n- Always wrap `JSON.parse()` in try\u002Fcatch\n- Use `JSON.stringify(obj, null, 2)` for human-readable configs\n- For logs, use single-line JSON (no spaces)\n- Validate JSON schema using libraries like `ajv` or `zod`\n- Never use `eval()` or `new Function()` to parse JSON (security risk)\n\n**Performance Considerations:**\n- `JSON.parse` is highly optimized (native code)\n- `JSON.stringify` on large objects produces temporary string\n- For repeated serialization, consider `fast-json-stringify` (schema-based)\n- Avoid parsing large JSON in main thread; use `worker_threads`\n\n**Production Recommendations:**\n- Set body size limits in Express: `express.json({ limit: '10mb' })`\n- Use `JSON.parse()` with `reviver` for custom type reconstruction\n- For API responses, compress JSON with gzip\n- Use `JSON.parse(JSON.stringify(obj))` for shallow cloning (but loses non-JSON types)\n\n**Browser Behavior:**\nSame `JSON` global in browsers. Slightly different error messages, but identical API.\n\n**Node.js Runtime Behavior:**\n- `JSON.parse()` uses V8's native JSON parser\n- `JSON.stringify()` handles `toJSON()` method on objects\n- `JSON.parse()` accepts trailing commas? No (throws in strict mode)\n\n**Latest Node.js Patterns:**\n- `structuredClone(obj)` – similar to JSON parse\u002Fstringify but supports more types (Map, Set, Date, RegExp)\n- `JSON.parse` with `BigInt` support via reviver\n- `--json` flag in Node.js test runner for JSON output\n\n**TypeScript Example:**\n```ts\ninterface Config {\n  port: number;\n  env: 'development' | 'production';\n  database: {\n    url: string;\n    poolSize: number;\n  };\n}\n\nfunction parseConfig(data: unknown): Config {\n  if (typeof data !== 'string') {\n    throw new Error('Config must be a string');\n  }\n  \n  const parsed = JSON.parse(data);\n  \n  \u002F\u002F Basic validation\n  if (typeof parsed.port !== 'number' || !['development', 'production'].includes(parsed.env)) {\n    throw new Error('Invalid config shape');\n  }\n  \n  return parsed as Config;\n}\n\n\u002F\u002F With Zod validation\nimport { z } from 'zod';\nconst ConfigSchema = z.object({\n  port: z.number().positive(),\n  env: z.enum(['development', 'production']),\n  database: z.object({\n    url: z.string().url(),\n    poolSize: z.number().min(1).max(100)\n  })\n});\n\ntype Config = z.infer\u003Ctypeof ConfigSchema>;\nconst config = ConfigSchema.parse(JSON.parse(fileContent));\n```\n\n**Interview Tip:**\nExplain that `JSON.parse()` is strict: property names must be double-quoted, no single quotes. Mention `JSON.stringify()` performance for large objects.\n\n**Common Follow-up:**\n\"How do you handle JSON with comments?\" JSON doesn't support comments. Use JSON5, YAML, or strip comments with a preprocessor.\n\n**Real-world Example:**\nnpm uses `package.json` (JSON) for configuration. Many CLI tools (ESLint, Prettier) use `.json` or `.jsonc` (JSON with comments).\n\n**Advanced Notes:**\n`JSON.stringify()` has third parameter `space` for indentation. Negative space removes newlines (compact). `toJSON()` method: if object defines it, `stringify` calls it. Example: `Date.prototype.toJSON()` returns ISO string.",[129,130,39],"json","parsing",{"id":132,"category":7,"question":133,"answer":134,"level":10,"tags":135},17,"What is async\u002Fawait in Node.js? How does it differ from promises and callbacks?","**Concept Explanation:**\nAsync\u002Fawait is syntactic sugar built on top of Promises, making asynchronous code look and behave more like synchronous code. `async` functions always return a Promise. `await` pauses the function execution until the Promise settles, without blocking the event loop.\n\n**Execution Flow:**\n1. Call an `async` function – returns a Promise immediately\n2. Inside the function, `await` a Promise\n3. Function execution suspends at `await`, control returns to caller\n4. When awaited Promise resolves, function resumes with the resolved value\n5. If rejected, exception is thrown (can be caught with try\u002Fcatch)\n\n**Event Loop Explanation:**\n`await` yields control back to the event loop, allowing other pending tasks to run. The resumed function continuation is scheduled as a microtask (higher priority than timers).\n\n**Memory Behavior:**\n- Each async function creates a Promise object\n- Local variables are kept in closure until function completes\n- Await chains create microtask queue entries (small overhead)\n- Unhandled rejections cause memory leaks; always handle errors\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Callback style (old)\nfs.readFile('file.txt', (err, data) => {\n  if (err) throw err;\n  console.log(data);\n});\n\n\u002F\u002F Promise style\nfetch('\u002Fapi')\n  .then(res => res.json())\n  .then(data => console.log(data))\n  .catch(err => console.error(err));\n\n\u002F\u002F Async\u002Fawait (modern)\nasync function getData() {\n  try {\n    const res = await fetch('\u002Fapi');\n    const data = await res.json();\n    console.log(data);\n  } catch (err) {\n    console.error(err);\n  }\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Basic async function\nasync function fetchUser(id) {\n  const response = await fetch(`\u002Fusers\u002F${id}`);\n  const user = await response.json();\n  return user; \u002F\u002F wrapped in Promise\n}\n\n\u002F\u002F Arrow function\nconst fetchUser = async (id) => {\n  \u002F\u002F ...\n};\n\n\u002F\u002F Immediately invoked async function\n(async () => {\n  const data = await fetchSomething();\n  console.log(data);\n})();\n\n\u002F\u002F Top-level await (ES modules only)\nconst data = await fetchData();\n```\n\n**Practical Example:**\nSequential vs parallel execution:\n```js\n\u002F\u002F Sequential (bad for independent ops)\nasync function sequential() {\n  const user = await fetchUser(1);   \u002F\u002F Wait 100ms\n  const posts = await fetchPosts(1); \u002F\u002F Wait 200ms (total 300ms)\n  return { user, posts };\n}\n\n\u002F\u002F Parallel (good)\nasync function parallel() {\n  const [user, posts] = await Promise.all([\n    fetchUser(1),\n    fetchPosts(1)\n  ]);\n  return { user, posts }; \u002F\u002F Total ~200ms (max of both)\n}\n\n\u002F\u002F Real-world: database operations\nasync function createOrder(orderData) {\n  const connection = await db.getConnection();\n  try {\n    await connection.beginTransaction();\n    const order = await connection.query('INSERT INTO orders SET ?', orderData);\n    await connection.query('INSERT INTO order_items ...', items);\n    await connection.commit();\n    return order;\n  } catch (err) {\n    await connection.rollback();\n    throw err;\n  } finally {\n    connection.release();\n  }\n}\n```\n\n**Common Mistakes:**\n- Forgetting `await` – function returns Promise, not value\n- Using `await` outside `async` function (except top-level in modules)\n- Not handling rejections (no try\u002Fcatch or `.catch()`)\n- Sequential `await` when parallel would be faster\n- Mixing callbacks and async\u002Fawait incorrectly\n\n**Interview Follow-ups:**\n- Q: What's the difference between `return await` and `return` in async function? A: `return await` adds extra microtask but better stack trace; `return` returns Promise directly\n- Q: Can you use `await` in loops? A: Yes, but beware of performance; use `Promise.all` for independent iterations\n\n**Best Practices:**\n- Always use try\u002Fcatch for error handling in async functions\n- Use `Promise.all` for independent concurrent operations\n- Use `Promise.allSettled` when you need all results even if some fail\n- Name async functions clearly (e.g., `fetchUserAsync`)\n- Avoid `async` functions that don't use `await` (unnecessary overhead)\n\n**Performance Considerations:**\n- Async\u002Fawait has similar performance to Promises (very small overhead)\n- Each `await` creates a microtask (faster than `setTimeout`)\n- Deep `await` chains can cause microtask queue buildup\n- For CPU-intensive work, offload to `worker_threads`\n\n**Production Recommendations:**\n- Use `async` handlers in Express (with error wrapper)\n- Set `unhandledRejection` listener at process level\n- For retries, implement with async\u002Fawait + exponential backoff\n- Use `p-queue` or `p-limit` for concurrency control\n\n**Browser Behavior:**\nAsync\u002Fawait works in all modern browsers. Same semantics as Node.js. Top-level await available in modern browsers for modules.\n\n**Node.js Runtime Behavior:**\n- Top-level await available in ES modules (`.mjs` or `\"type\": \"module\"`)\n- Async functions return `Promise` objects\n- `await` uses `PromiseResolve` and microtask queue\n\n**Latest Node.js Patterns:**\n- Async iterators: `for await (const chunk of stream)`\n- `await using` (Node.js 20+ with explicit resource management)\n- Top-level await without IIFE in ES modules\n\n**TypeScript Example:**\n```ts\ninterface User {\n  id: number;\n  name: string;\n}\n\nasync function fetchUser(id: number): Promise\u003CUser> {\n  const response = await fetch(`https:\u002F\u002Fapi.example.com\u002Fusers\u002F${id}`);\n  if (!response.ok) {\n    throw new Error(`HTTP ${response.status}`);\n  }\n  return response.json();\n}\n\nasync function getAllUsers(ids: number[]): Promise\u003CUser[]> {\n  \u002F\u002F Parallel with error handling\n  const results = await Promise.allSettled(ids.map(id => fetchUser(id)));\n  return results\n    .filter((r): r is PromiseFulfilledResult\u003CUser> => r.status === 'fulfilled')\n    .map(r => r.value);\n}\n\n\u002F\u002F With custom timeout\nasync function withTimeout\u003CT>(promise: Promise\u003CT>, ms: number): Promise\u003CT> {\n  const timeout = new Promise\u003Cnever>((_, reject) =>\n    setTimeout(() => reject(new Error('Timeout')), ms)\n  );\n  return Promise.race([promise, timeout]);\n}\n```\n\n**Interview Tip:**\nExplain that async\u002Fawait doesn't make code asynchronous – it's just a different syntax for Promises. The asynchronicity still comes from the underlying async operation.\n\n**Common Follow-up:**\n\"What happens if you await a non-Promise?\" It's wrapped in `Promise.resolve()`, so it's fine; the `await` will resolve immediately with the value.\n\n**Real-world Example:**\nMongoose (ODM) uses async\u002Fawait for database operations. Discord.js uses async\u002Fawait extensively for API calls and event handling.\n\n**Advanced Notes:**\nAsync functions generate a state machine internally. Each `await` is a transition. The `async` function's body is wrapped in a `Promise` executor. `return` is transformed to `resolve`, `throw` to `reject`.",[136,137,138],"async-await","promises","asynchronous",[140,149,156,162,169,174,181,190,198,207,216,223,231,239,246,253,263,271,278,286,295,301,308,316,324,332],{"id":141,"category":142,"question":143,"answer":144,"level":145,"tags":146},18,"Event Loop","Explain the six phases of the Node.js event loop in detail. How do timers, I\u002FO callbacks, and the poll phase interact?","**Concept Explanation:**\nThe Node.js event loop is a C++ program (libuv) that orchestrates asynchronous operations. It runs in six distinct phases, each with a FIFO queue of callbacks. The phases run in order, and the loop can exit when no more work is pending.\n\n**Execution Flow:**\nPhase order: `timers` → `pending callbacks` → `idle, prepare` → `poll` → `check` → `close callbacks`. After each phase, the loop processes `process.nextTick()` and microtasks (Promise callbacks).\n\n**Event Loop Explanation:**\n- **Timers phase:** Executes callbacks scheduled by `setTimeout()` and `setInterval()`. Uses a min-heap to fire timers in order.\n- **Pending callbacks:** Executes I\u002FO callbacks deferred from previous loop (e.g., TCP errors, `ECONNREFUSED`).\n- **Idle, prepare:** Internal use only (not exposed to JavaScript).\n- **Poll phase:** Most important. Retrieves new I\u002FO events, executes I\u002FO callbacks (except timers, check, close). If no timers pending, it can block here waiting for events.\n- **Check phase:** Executes `setImmediate()` callbacks.\n- **Close callbacks:** Executes `socket.on('close', ...)` and similar cleanup.\n\n**Memory Behavior:**\nEach callback queue stores function references. Unhandled callbacks remain in memory. The poll phase's blocking behavior is efficient for idle connections.\n\n**Lifecycle Explanation:**\n```js\nconst fs = require('node:fs');\n\n\u002F\u002F Timer (timers phase)\nsetTimeout(() => console.log('timer'), 0);\n\n\u002F\u002F I\u002FO (poll phase)\nfs.readFile(__filename, () => {\n  console.log('I\u002FO callback');\n  \n  \u002F\u002F Nested timer (timers phase next iteration)\n  setTimeout(() => console.log('timer in I\u002FO'), 0);\n  \n  \u002F\u002F setImmediate (check phase - same iteration)\n  setImmediate(() => console.log('immediate in I\u002FO'));\n});\n\nsetImmediate(() => console.log('top-level immediate'));\n\n\u002F\u002F Output order: top-level immediate, I\u002FO callback, immediate in I\u002FO, timer, timer in I\u002FO\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Phase inspection (advanced)\nconst events = require('node:events');\nconst loop = require('node:internal\u002Fevent_loop'); \u002F\u002F Not public API\n\n\u002F\u002F Simulate phases with timers\nsetTimeout(() => console.log('1: timers'), 0);\nsetImmediate(() => console.log('5: check'));\nrequire('fs').readFile(__filename, () => console.log('3: poll'));\nprocess.nextTick(() => console.log('0: nextTick (before phases)'));\nPromise.resolve().then(() => console.log('0.1: microtask'));\n\n\u002F\u002F Output order: nextTick, microtask, timers, I\u002FO, check or immediate\n```\n\n**Practical Example:**\nImplementing a delay function that doesn't block the loop:\n```js\nfunction delay(ms) {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nasync function rateLimitedTask(items) {\n  for (const item of items) {\n    await processItem(item);\n    await delay(100); \u002F\u002F Yield to event loop every 100ms\n    \u002F\u002F Allows other connections to be processed\n  }\n}\n```\n\n**Common Mistakes:**\n- Assuming `setTimeout(fn, 0)` executes immediately (it queues in timers phase, after I\u002FO)\n- Using `setImmediate()` and `setTimeout(..., 0)` interchangeably (order depends on loop phase when called)\n- Blocking the poll phase with synchronous CPU work (e.g., `while(1)`)\n- Overusing `process.nextTick()` causing event loop starvation\n\n**Interview Follow-ups:**\n- Q: What's the difference between `process.nextTick()` and `setImmediate()`? A: `nextTick` executes after current phase before next phase; `setImmediate` executes in check phase (between poll and close)\n- Q: How does `Promise.resolve().then()` compare? A: Microtasks run after each callback, before `nextTick`? Actually `nextTick` runs before microtasks? Wait: `nextTick` queue processes after each phase, microtasks after each callback. Order within same event loop tick: `nextTick` then microtasks? No: In Node.js, `process.nextTick` queue empties before promise microtasks. Correct order: after each operation, all `nextTick` callbacks, then all promise microtasks.\n\n**Best Practices:**\n- Avoid `process.nextTick()` recursion that blocks I\u002FO\n- Use `setImmediate()` for breaking up long-running synchronous tasks\n- Prefer `Promise.resolve().then()` for microtask scheduling (more standard)\n- Monitor event loop lag using `process.hrtime()` in health checks\n\n**Performance Considerations:**\n- Each phase's queue can accumulate many callbacks; long queues increase latency\n- Poll phase blocking is tunable via `uv_run` timeout (internal)\n- `nextTick` recursion depth > 1000 can cause event loop to never reach I\u002FO\n\n**Production Recommendations:**\n- Use `node:inspector` to profile event loop utilization\n- Set `--trace-event-categories node.environment` to trace phases\n- For high concurrency, keep per-callback work under 5ms\n- Use `worker_threads` for CPU-heavy tasks to avoid blocking\n\n**Browser Behavior:**\nBrowser event loop has similar concepts (task\u002Fmicrotask queues) but phases are different. No `process.nextTick()` or `setImmediate()`; use `setTimeout(fn, 0)` and `Promise`.\n\n**Node.js Runtime Behavior:**\n- `libuv` implements the loop; `uv_run()` is called at Node.js startup\n- Loop exits when no active handles (timers, sockets) and no pending callbacks\n- `process._getActiveHandles()` shows open handles preventing exit\n\n**Latest Node.js Patterns:**\n- `queueMicrotask()` for standard microtask scheduling (available in Node.js 11+)\n- `--inspect` with Chrome DevTools to visualize event loop phases\n- `perf_hooks` with `monitorEventLoopDelay` for high-resolution lag measurement\n\n**TypeScript Example:**\n```ts\nimport { monitorEventLoopDelay } from 'node:perf_hooks';\n\n\u002F\u002F Create histogram for loop delay\nconst histogram = monitorEventLoopDelay({ resolution: 20 });\nhistogram.enable();\n\nsetInterval(() => {\n  const lag = histogram.min;\n  if (lag > 50) console.warn(`Event loop lag detected: ${lag}ms`);\n}, 5000);\n\nasync function yieldToLoop(): Promise\u003Cvoid> {\n  return new Promise(resolve => setImmediate(resolve));\n}\n\nasync function longTask() {\n  for (let i = 0; i \u003C 1000; i++) {\n    \u002F\u002F Do work\n    if (i % 100 === 0) await yieldToLoop();\n  }\n}\n```\n\n**Interview Tip:**\nDraw the phases on a whiteboard. Emphasize that the poll phase is where most I\u002FO occurs and can block, making it the heart of Node.js concurrency.\n\n**Common Follow-up:**\n\"How does `process.nextTick()` cause event loop starvation?\" Recursively calling `nextTick()` without giving control back to the loop will prevent poll phase from ever running, starving I\u002FO.\n\n**Real-world Example:**\nExpress.js uses `nextTick` internally to defer middleware execution. `socket.io` uses `setImmediate` to batch writes.\n\n**Advanced Notes:**\nThe poll phase uses `epoll` (Linux), `kqueue` (BSD), or `IOCP` (Windows). `uv_run` can be called in different modes: `UV_RUN_DEFAULT`, `UV_RUN_ONCE`, `UV_RUN_NOWAIT`. The event loop's heartbeat is 1ms (timer resolution).","intermediate",[14,147,148],"libuv","phases",{"id":150,"category":142,"question":151,"answer":152,"level":145,"tags":153},19,"What are microtasks, macrotasks, and process.nextTick? Explain their execution order with examples.","**Concept Explanation:**\nIn Node.js, asynchronous callbacks are scheduled into different queues: macrotasks (timers, I\u002FO, setImmediate), microtasks (Promise callbacks), and the special `process.nextTick` queue. Understanding order is critical for debugging unexpected execution sequences.\n\n**Execution Flow:**\n1. After each phase of the event loop, Node.js runs all `process.nextTick` callbacks.\n2. Then it runs all microtasks (Promise callbacks).\n3. Then proceeds to the next event loop phase.\n4. Within a phase, after each individual callback, `nextTick` and microtasks are **not** interleaved; they run after the entire phase's callbacks have executed? Actually: After each callback in a phase, Node.js checks for `nextTick` and microtasks? No — the rule: `nextTick` queue is processed after each operation (phase callback) in the event loop, and microtasks are processed after `nextTick` queue empties. But this is complex. Better: For each event loop turn, after the current phase's queue is emptied, `nextTick` and then microtasks run completely before moving to next phase.\n\n**Event Loop Explanation:**\nSimplified order within one event loop iteration:\n1. Execute all callbacks in timers phase.\n2. Execute all `process.nextTick()` callbacks queued during timers.\n3. Execute all microtasks (Promise callbacks) queued during timers\u002FnextTick.\n4. Move to pending callbacks phase, repeat steps 2-3 after each phase.\n\n**Memory Behavior:**\nEach queue holds references. Deep recursion in `nextTick` can cause memory blow if not resolved.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Order demonstration\nPromise.resolve().then(() => console.log('promise1'));\nprocess.nextTick(() => console.log('nextTick1'));\nsetImmediate(() => console.log('setImmediate'));\nsetTimeout(() => console.log('setTimeout'), 0);\nPromise.resolve().then(() => console.log('promise2'));\nprocess.nextTick(() => console.log('nextTick2'));\n\n\u002F\u002F Output:\n\u002F\u002F nextTick1\n\u002F\u002F nextTick2\n\u002F\u002F promise1\n\u002F\u002F promise2\n\u002F\u002F setTimeout\n\u002F\u002F setImmediate (order between setTimeout and setImmediate can vary)\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F nextTick vs Promise vs setImmediate\nfunction testOrder() {\n  process.nextTick(() => console.log('A'));\n  Promise.resolve().then(() => console.log('B'));\n  setImmediate(() => console.log('C'));\n  console.log('D');\n}\ntestOrder();\n\u002F\u002F Output: D, A, B, C\n\n\u002F\u002F Nesting to see interleaving\nprocess.nextTick(() => {\n  console.log('1');\n  process.nextTick(() => console.log('1.1'));\n  Promise.resolve().then(() => console.log('1.promise'));\n});\nPromise.resolve().then(() => console.log('2'));\n\u002F\u002F Output: 1, 2, 1.1, 1.promise (all nextTick before microtasks after each phase)\n```\n\n**Practical Example:**\nImplementing `async\u002Fawait` polyfill behavior:\n```js\n\u002F\u002F Queue microtask manually\nfunction scheduleMicrotask(fn) {\n  Promise.resolve().then(fn);\n}\n\n\u002F\u002F queueMicrotask is standard\nqueueMicrotask(() => console.log('microtask'));\n\n\u002F\u002F Avoiding recursion explosion\nlet depth = 0;\nfunction recursiveNextTick() {\n  if (depth++ > 1000) return;\n  process.nextTick(recursiveNextTick); \u002F\u002F THIS WILL STARVE EVENT LOOP\n}\n\n\u002F\u002F Better: use setImmediate which yields I\u002FO\nfunction recursiveImmediate() {\n  if (depth++ > 1000) return;\n  setImmediate(recursiveImmediate);\n}\n```\n\n**Common Mistakes:**\n- Assuming `Promise.then` runs before `process.nextTick` (incorrect; nextTick runs first)\n- Using `process.nextTick` for recursive asynchronous loops (starves I\u002FO)\n- Not understanding that microtasks can be created from within microtasks, delaying macrotasks indefinitely\n\n**Interview Follow-ups:**\n- Q: How do you make `setImmediate` run before `setTimeout(fn,0)`? A: Wrap setTimeout in I\u002FO callback, or rely on order depending on loop phase when scheduled.\n- Q: What happens if you have an infinite loop of `process.nextTick` callbacks? A: Event loop never proceeds to I\u002FO, process may appear hung.\n\n**Best Practices:**\n- Use `setImmediate` or `setTimeout` instead of recursive `nextTick`\n- Use `queueMicrotask` for standard microtask scheduling (better than Promise hack)\n- Avoid heavy work in `process.nextTick`; keep callbacks fast\n- For deferring operations without blocking, prefer `setImmediate`\n\n**Performance Considerations:**\n- `process.nextTick` is faster than `setImmediate` (no timer overhead)\n- Microtasks have higher priority than macrotasks, can starve timers\n- Too many microtasks can cause high CPU and event loop lag\n\n**Production Recommendations:**\n- Limit `nextTick` recursion depth\n- Use `node:inspector` to profile task queue sizes\n- In serverless functions, be mindful of pending microtasks before invocation end\n\n**Browser Behavior:**\nBrowser has no `process.nextTick`. Microtasks are scheduled via `queueMicrotask` or `Promise`. Browser event loop processes microtasks after each macrotask, similar but not identical.\n\n**Node.js Runtime Behavior:**\n- `process.nextTick` uses a simple queue (`nextTickQueue`)\n- Microtasks (Promise) use V8's `MicrotaskQueue`\n- `nextTickQueue` is processed before `MicrotaskQueue` in Node.js\n\n**Latest Node.js Patterns:**\n- `queueMicrotask` available since Node.js 11\n- `Promise.resolve().then(fn)` still works but `queueMicrotask` is more intent-revealing\n\n**TypeScript Example:**\n```ts\n\u002F\u002F Queue type safety\ntype Task = () => void;\n\nclass TaskQueue {\n  private nextTickTasks: Task[] = [];\n  \n  deferNextTick(fn: Task) {\n    this.nextTickTasks.push(fn);\n    process.nextTick(() => {\n      const task = this.nextTickTasks.shift();\n      task?.();\n    });\n  }\n  \n  deferMicrotask(fn: Task) {\n    queueMicrotask(fn);\n  }\n}\n```\n\n**Interview Tip:**\nMemorize this order: Synchronous code → process.nextTick → Promise callbacks → timers\u002FsetImmediate (depending on phase).\n\n**Common Follow-up:**\n\"Why does `setImmediate` sometimes run before `setTimeout(fn,0)`?\" At top-level (outside I\u002FO), order depends on event loop state; inside I\u002FO callbacks, `setImmediate` always runs first.\n\n**Real-world Example:**\nDatabase connection pool libraries use `nextTick` to invoke callbacks after successful connection, ensuring user code runs before any I\u002FO.\n\n**Advanced Notes:**\n`process.nextTick` callbacks can be nested. Node.js has a `process.maxTickDepth` (not configurable). `process._getActiveRequests()` and `_getActiveHandles()` show pending operations that keep loop alive.",[14,154,155],"microtasks","nexttick",{"id":157,"category":75,"question":158,"answer":159,"level":145,"tags":160},20,"Explain backpressure in Node.js streams. How do you handle it correctly, and what are common pitfalls?","**Concept Explanation:**\nBackpressure occurs when a writable stream cannot process data as fast as a readable stream produces it. Without handling, data accumulates in memory causing high usage or crashes. Node.js streams automatically handle backpressure when using `pipe()`, but manual implementations must respect `write()` return value and `drain` events.\n\n**Execution Flow:**\n1. Readable stream emits `data` events or you call `read()`\n2. You write to a writable stream via `write(chunk)`\n3. If `write()` returns `false`, the internal buffer is full (highWaterMark exceeded)\n4. You must pause the readable stream and wait for `drain` event on writable\n5. On `drain`, resume reading\n\n**Event Loop Explanation:**\nThe `drain` event is emitted in the check phase (setImmediate) after the write buffer empties. Backpressure doesn't block the loop but pauses data flow, allowing other events to process.\n\n**Memory Behavior:**\nEach stream has an internal buffer (default 16KB for readable, 16KB for writable). When backpressure engages, readable continues reading? Actually, readable will stop reading if you don't consume data, but if you keep calling `read()` without checking `write()` return, buffers fill and memory grows.\n\n**Lifecycle Explanation:**\n```js\nimport { Readable, Writable } from 'node:stream';\n\nconst readable = Readable.from(['a', 'b', 'c', 'd']);\nconst writable = new Writable({\n  highWaterMark: 1, \u002F\u002F Small buffer to force backpressure\n  write(chunk, encoding, callback) {\n    console.log(`Writing: ${chunk}`);\n    \u002F\u002F Simulate slow write\n    setTimeout(() => callback(null), 100);\n  }\n});\n\n\u002F\u002F Manual backpressure handling\nasync function pump() {\n  for await (const chunk of readable) {\n    const canWrite = writable.write(chunk);\n    if (!canWrite) {\n      await new Promise(resolve => writable.once('drain', resolve));\n    }\n  }\n  writable.end();\n}\npump();\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Using pipe (automatic backpressure)\nreadable.pipe(writable);\n\n\u002F\u002F Manual handling with events\nreadable.on('data', (chunk) => {\n  const canWrite = writable.write(chunk);\n  if (!canWrite) {\n    readable.pause();\n    writable.once('drain', () => readable.resume());\n  }\n});\n\n\u002F\u002F Using pipeline (recommended)\nimport { pipeline } from 'node:stream\u002Fpromises';\nawait pipeline(readable, writable);\n```\n\n**Practical Example:**\nCompressing a large file with backpressure awareness:\n```js\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { createGzip } from 'node:zlib';\nimport { pipeline } from 'node:stream\u002Fpromises';\n\nasync function compressFile(input, output) {\n  const source = createReadStream(input);\n  const gzip = createGzip();\n  const dest = createWriteStream(output);\n  \n  \u002F\u002F pipeline handles backpressure and cleanup\n  await pipeline(source, gzip, dest);\n  console.log('Compression complete');\n}\n```\n\n**Common Mistakes:**\n- Ignoring `write()` return value (causes memory bloat)\n- Calling `readable.resume()` before `drain` (writes fail again)\n- Forgetting to handle `error` events (streams may crash)\n- Using `pipe` on streams that emit non-buffer data (object mode)\n\n**Interview Follow-ups:**\n- Q: How does `pipe()` implement backpressure? A: It listens to `data` on readable and `drain` on writable, automatically pausing\u002Fresuming.\n- Q: What is `highWaterMark`? A: Internal buffer size threshold (in bytes for buffers, object count for object mode) that triggers backpressure.\n\n**Best Practices:**\n- Always use `pipeline` instead of `pipe` for proper error forwarding\n- Set appropriate `highWaterMark` based on expected chunk size\n- For object mode, set objectMode:true and highWaterMark as object count\n- Never ignore backpressure; memory leaks are common\n\n**Performance Considerations:**\n- Larger `highWaterMark` reduces backpressure events but uses more memory\n- Too small buffer causes frequent `drain` events, reducing throughput\n- `pipe` is optimized for performance; manual handling is slower\n- Backpressure propagates through multiple streams (e.g., file → gzip → network)\n\n**Production Recommendations:**\n- Monitor stream buffer sizes with `readable.readableLength` \u002F `writable.writableLength`\n- Use `stream\u002Fpromises` pipeline for async\u002Fawait style\n- Implement custom backpressure handling for non-standard flows (e.g., rate limiting)\n- Test with slow consumers (e.g., network throttling simulation)\n\n**Browser Behavior:**\nWeb Streams API has backpressure via `writer.ready` and `reader.read()`. `pipeTo` handles automatically.\n\n**Node.js Runtime Behavior:**\n- `write()` returns false when buffer length > highWaterMark\n- `drain` emitted when buffer length drops below highWaterMark\n- `cork()` \u002F `uncork()` batch writes to reduce `drain` events\n\n**Latest Node.js Patterns:**\n- `stream.compose` to combine streams with backpressure propagation\n- `Readable.from(async function*())` with yield backpressure? Generator yield doesn't automatically handle backpressure; need manual checks.\n- `Writable` constructor `autoDestroy` option (default true) cleans up on error\u002Fend\n\n**TypeScript Example:**\n```ts\nimport { Writable, Readable } from 'node:stream';\n\nclass RateLimitWritable extends Writable {\n  private bytesPerSecond: number;\n  private bytesWritten = 0;\n  private timer: NodeJS.Timeout | null = null;\n  \n  constructor(bytesPerSecond: number) {\n    super({ highWaterMark: bytesPerSecond });\n    this.bytesPerSecond = bytesPerSecond;\n  }\n  \n  _write(chunk: Buffer, encoding: string, callback: (error?: Error | null) => void) {\n    this.bytesWritten += chunk.length;\n    if (this.bytesWritten >= this.bytesPerSecond) {\n      this.timer = setTimeout(() => {\n        this.bytesWritten = 0;\n        callback(null);\n      }, 1000);\n    } else {\n      callback(null);\n    }\n  }\n  \n  _destroy() {\n    if (this.timer) clearTimeout(this.timer);\n  }\n}\n```\n\n**Interview Tip:**\nExplain that backpressure is a signal flow control mechanism, not an error. Good backpressure handling is what makes Node.js streams memory-efficient for large data.\n\n**Common Follow-up:**\n\"What is the difference between `drain` and `finish` events?\" `drain` indicates buffer cleared for more writes; `finish` emitted when `end()` called and all writes complete.\n\n**Real-world Example:**\nA log shipping service reading from file and sending to Elasticsearch. Without backpressure, fast file reads could overwhelm HTTP client, causing connection hangs or OOM.\n\n**Advanced Notes:**\nInternally, streams use `WriteWrap` C++ objects. `writeOrBuffer` checks highWaterMark. `doWrite` calls native layer. Backpressure can propagate across multiple streams via `readable.pipe()` chaining.",[79,161,80],"backpressure",{"id":163,"category":75,"question":164,"answer":165,"level":145,"tags":166},21,"What are transform streams and how do you create custom transform streams? Give an example of encryption or compression.","**Concept Explanation:**\nTransform streams are duplex streams where the output is computed from the input (through a transformation). They sit between readable and writable streams, modifying data as it passes through. Examples: `zlib.createGzip`, `crypto.createCipher`, `through2`.\n\n**Execution Flow:**\n1. Data written to transform stream's writable side\n2. Internal `_transform()` method processes each chunk\n3. Call `push()` to output transformed data or `callback()` to indicate done\n4. Data is emitted on readable side\n5. When input ends, `_flush()` is called to output any remaining data\n\n**Event Loop Explanation:**\nTransform streams are synchronous by default (transform method called immediately for each chunk). For async transforms, use callback or promise to not block event loop.\n\n**Memory Behavior:**\n- Each chunk is stored in internal buffer until transformed and pushed\n- `transform()` should not accumulate chunks indefinitely\n- Use `highWaterMark` to control buffer size\n\n**Lifecycle Explanation:**\n```js\nimport { Transform } from 'node:stream';\n\n\u002F\u002F Simple uppercase transform\nconst upperCaseTransform = new Transform({\n  transform(chunk, encoding, callback) {\n    const output = chunk.toString().toUpperCase();\n    this.push(output);\n    callback();\n  }\n});\n\nprocess.stdin.pipe(upperCaseTransform).pipe(process.stdout);\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Class-based transform\nclass MyTransform extends Transform {\n  _transform(chunk, encoding, callback) {\n    \u002F\u002F Transform chunk\n    const transformed = this.process(chunk);\n    this.push(transformed);\n    callback();\n  }\n  \n  _flush(callback) {\n    \u002F\u002F Called before stream ends, push any remaining data\n    if (this.remaining) this.push(this.remaining);\n    callback();\n  }\n}\n\n\u002F\u002F Using constructor with options\nconst transform = new Transform({\n  transform(chunk, enc, cb) { cb(null, chunk.toString().toUpperCase()); },\n  flush(cb) { cb(); },\n  objectMode: false,\n  highWaterMark: 16384\n});\n```\n\n**Practical Example:**\nCustom line-by-line JSON formatter:\n```js\nimport { Transform } from 'node:stream';\n\nclass JSONFormatter extends Transform {\n  constructor() {\n    super({ objectMode: true }); \u002F\u002F Accept objects, output strings\n  }\n  \n  _transform(obj, encoding, callback) {\n    const line = JSON.stringify(obj) + '\\n';\n    this.push(line);\n    callback();\n  }\n}\n\n\u002F\u002F Use with readable object stream\nimport { Readable } from 'node:stream';\nconst objects = Readable.from([{a:1}, {b:2}, {c:3}]);\nobjects.pipe(new JSONFormatter()).pipe(process.stdout);\n```\n\n**Common Mistakes:**\n- Not calling `callback()` (stream hangs)\n- Calling `push()` after `callback()` (error)\n- Forgetting to handle errors in transform (emit 'error' event)\n- Using `this.push(data)` without checking if writable side is still flowing\n\n**Interview Follow-ups:**\n- Q: What's the difference between `_transform` and `_flush`? A: `_transform` called per chunk; `_flush` called once at end for final output\n- Q: Can transform streams be asynchronous? A: Yes, call `callback()` asynchronously or use async\u002Fawait with promise wrapper\n\n**Best Practices:**\n- Always call `callback()` exactly once per `_transform`\n- Use `objectMode: true` for object streams (e.g., database rows)\n- For async transforms, use `callback` or await; don't return promise unless using `Transform.from`\n- Handle errors by emitting 'error' and calling `callback(err)`\n\n**Performance Considerations:**\n- Transform overhead is minimal (function call per chunk)\n- Large chunk sizes reduce number of transform calls\n- Avoid buffering all data in `_transform`; push as you go\n- For CPU-heavy transforms (encryption), consider `worker_threads`\n\n**Production Recommendations:**\n- Use built-in transforms (zlib, crypto) when possible\n- For simple transforms, use `Transform.from` (Node.js 15+)\n- Monitor `transform._writableState.length` for backpressure\n- Pipeline transforms together with `stream\u002Fpromises`\n\n**Browser Behavior:**\nWeb Streams API has `TransformStream` class with `transform()` method similar to Node.js.\n\n**Node.js Runtime Behavior:**\n- Transform extends Duplex, so it has both readable and writable sides\n- If `objectMode` is false, chunks are Buffers or strings\n- `transform()` can push multiple times or not push (filtering)\n\n**Latest Node.js Patterns:**\n- `Transform.from(async function* (source) { ... })` (experimental)\n- `Readable.toWeb()` \u002F `Transform.fromWeb()` for interop with Web Streams\n- `stream.compose(transform1, transform2)` to chain transforms\n\n**TypeScript Example:**\n```ts\nimport { Transform, TransformCallback } from 'node:stream';\n\ninterface EncryptedChunk {\n  iv: Buffer;\n  data: Buffer;\n}\n\nclass EncryptTransform extends Transform {\n  private algorithm: string;\n  private key: Buffer;\n  \n  constructor(key: Buffer, algorithm = 'aes-256-gcm') {\n    super();\n    this.key = key;\n    this.algorithm = algorithm;\n  }\n  \n  _transform(chunk: Buffer, encoding: string, callback: TransformCallback): void {\n    const iv = crypto.randomBytes(16);\n    const cipher = crypto.createCipheriv(this.algorithm, this.key, iv);\n    const encrypted = Buffer.concat([cipher.update(chunk), cipher.final()]);\n    const authTag = cipher.getAuthTag();\n    const output = Buffer.concat([iv, authTag, encrypted]);\n    this.push(output);\n    callback();\n  }\n}\n```\n\n**Interview Tip:**\nHighlight that transform streams enable streaming processing (e.g., gzip on the fly) without buffering entire file. This is crucial for large files.\n\n**Common Follow-up:**\n\"How do you create a transform stream that operates on lines instead of arbitrary chunks?\" Use `readline` module or split on newline in transform, buffering partial lines.\n\n**Real-world Example:**\nLog processing pipeline: read log file → transform (parse timestamp, filter errors) → write to database. Transform stream does field extraction without needing full file in memory.\n\n**Advanced Notes:**\n`_transform` can receive `null` chunk when encoding is 'buffer'? No, only non-null. `_flush` can be used to output trailers (e.g., closing JSON array bracket). `Transform` can be used as both readable and writable in pipelines.",[79,167,168],"transform","encryption",{"id":170,"category":103,"question":171,"answer":172,"level":145,"tags":173},22,"How does Buffer memory allocation work? Explain the internal pooling mechanism and Buffer.allocUnsafe().","**Concept Explanation:**\nBuffers in Node.js allocate memory outside the V8 heap using `malloc`\u002F`free`. For efficiency, small buffers (\u003C poolSize, default 8KB) are allocated from a shared pool to reduce system calls and fragmentation.\n\n**Execution Flow:**\n1. `Buffer.alloc(size)` or `Buffer.allocUnsafe(size)` called\n2. If size \u003C poolSize, try to allocate from current pool\n3. Pool is a 8KB Buffer instance (slowBuffer)\n4. If pool has enough free space, slice it and return\n5. Otherwise, allocate new pool or use `malloc` directly for large buffers\n\n**Event Loop Explanation:**\nAllocation is synchronous and may block event loop briefly. Large allocations (GBs) can cause noticeable pauses.\n\n**Memory Behavior:**\n- Pool size: 8KB (`Buffer.poolSize`, can be changed globally)\n- `allocUnsafe` returns uninitialized memory (may contain sensitive leftover data)\n- `alloc` zero-fills, safer but slower\n- Memory is freed when Buffer is garbage collected (via `ArrayBuffer` backing store finalizer)\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Internal pool mechanism (simplified)\nlet pool = null;\nlet poolOffset = 0;\nconst POOL_SIZE = 8192;\n\nfunction allocateFromPool(size) {\n  if (!pool || poolOffset + size > POOL_SIZE) {\n    pool = Buffer.allocUnsafe(POOL_SIZE);\n    poolOffset = 0;\n  }\n  const chunk = pool.subarray(poolOffset, poolOffset + size);\n  poolOffset += size;\n  return chunk;\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Buffer creation methods\nconst buf1 = Buffer.alloc(1024); \u002F\u002F Zero-filled, safe\nconst buf2 = Buffer.allocUnsafe(1024); \u002F\u002F Fast but unsafe\nconst buf3 = Buffer.allocUnsafeSlow(1024); \u002F\u002F Always outside pool\nconst buf4 = Buffer.from('hello'); \u002F\u002F From string\n\n\u002F\u002F Check pool usage\nconsole.log(buf1.poolSize); \u002F\u002F 8192\nconsole.log(buf2.buffer !== buf3.buffer); \u002F\u002F Different backing stores\n\n\u002F\u002F Zero-fill behavior\nprocess.env.NODE_NO_DEPRECATION = '1';\nconst buf = Buffer.allocUnsafe(10);\nconsole.log(buf); \u002F\u002F May contain previous memory contents\n```\n\n**Practical Example:**\nPerformance comparison and safe usage:\n```js\nimport { performance } from 'node:perf_hooks';\n\nconst size = 1024 * 1024; \u002F\u002F 1MB\n\n\u002F\u002F Measure alloc\nlet start = performance.now();\nfor (let i = 0; i \u003C 1000; i++) {\n  Buffer.alloc(size);\n}\nconsole.log(`alloc: ${performance.now() - start}ms`);\n\nstart = performance.now();\nfor (let i = 0; i \u003C 1000; i++) {\n  Buffer.allocUnsafe(size);\n}\nconsole.log(`allocUnsafe: ${performance.now() - start}ms`);\n\n\u002F\u002F Security: always overwrite unsafe buffers before use\nconst secretBuffer = Buffer.allocUnsafe(64);\nsecretBuffer.fill(0); \u002F\u002F Zero out to avoid data leak\n\u002F\u002F Now safe to use\n```\n\n**Common Mistakes:**\n- Using `allocUnsafe` without zero-filling for sensitive data\n- Assuming `subarray` creates a copy (it's a view, shares memory)\n- Holding references to small buffers preventing pool reuse\n- Modifying pool buffer after slicing (affects all slices)\n\n**Interview Follow-ups:**\n- Q: Why is `Buffer.allocUnsafe()` faster? A: Skips zero-filling, but may return memory with old data\n- Q: When does Node.js bypass the pool? A: When size >= poolSize\u002F2 (4KB) or `allocUnsafeSlow` is used\n\n**Best Practices:**\n- Default to `Buffer.alloc()` for safety\n- Use `allocUnsafe` only in performance-critical sections and immediately fill\n- Never pass `allocUnsafe` buffers to external APIs without overwriting\n- For large buffers (> 8KB), pool isn't used; direct malloc\n\n**Performance Considerations:**\n- Pool reduces malloc calls from thousands to ~1 per 8KB of small allocations\n- `allocUnsafe` is ~2-3x faster than `alloc`\n- Very small allocations (\u003C 100 bytes) benefit most from pooling\n- Creating many large pools wastes memory\n\n**Production Recommendations:**\n- Set `Buffer.poolSize` at startup for custom pool size (e.g., 16KB for network chunks)\n- Use `--zero-fill-buffers` flag to force zero-fill globally (security over performance)\n- For high-throughput, reuse buffers via pool pattern\n- Monitor heap snapshots for external memory via `process.memoryUsage().external`\n\n**Browser Behavior:**\nNo Buffer; use `Uint8Array` which always zero-fills? Not exactly; `new Uint8Array(size)` is zero-filled. `new ArrayBuffer(size)` is zero-filled.\n\n**Node.js Runtime Behavior:**\n- Buffer inherits from Uint8Array but adds pool\n- `Buffer.poolSize` can be changed before any allocations\n- SlowBuffer is deprecated; use `Buffer.allocUnsafeSlow`\n\n**Latest Node.js Patterns:**\n- `Buffer.allocUnsafe` now accepts `size` up to `buffer.constants.MAX_LENGTH` (~2GB)\n- `Buffer.isBuffer()` for type checking\n- `blob` and `file` APIs may replace some Buffer use cases\n\n**TypeScript Example:**\n```ts\nclass BufferPool {\n  private pool: Buffer;\n  private offset = 0;\n  private readonly size: number;\n  \n  constructor(size = 8192) {\n    this.size = size;\n    this.pool = Buffer.allocUnsafe(size);\n  }\n  \n  allocate(size: number): Buffer {\n    if (size > this.size) {\n      return Buffer.allocUnsafe(size); \u002F\u002F Large buffer, bypass pool\n    }\n    if (this.offset + size > this.size) {\n      this.pool = Buffer.allocUnsafe(this.size);\n      this.offset = 0;\n    }\n    const chunk = this.pool.subarray(this.offset, this.offset + size);\n    this.offset += size;\n    return chunk;\n  }\n  \n  reset(): void {\n    this.offset = 0;\n    \u002F\u002F Optionally zero-fill for security\n    this.pool.fill(0);\n  }\n}\n```\n\n**Interview Tip:**\nExplain pooling as a classic trade-off: memory usage vs. allocation speed. This shows systems thinking.\n\n**Common Follow-up:**\n\"How does `Buffer.from(array)` differ from `Buffer.alloc()`?\" `Buffer.from(array)` copies existing data; `Buffer.alloc` zero-fills new memory.\n\n**Real-world Example:**\nHTTP\u002F2 implementation in Node.js uses buffer pooling for frame construction. A custom pool reduces GC pressure under high load.\n\n**Advanced Notes:**\nThe pool is a C++ `BackingStore` referenced by a Buffer. When all slices are garbage collected, the pool can be freed. `Buffer.allocUnsafe` may reuse memory from freed buffers, including potential sensitive data from other processes? No, within same Node.js process only. But across workers? Workers have separate memory spaces.",[107,80,47],{"id":175,"category":25,"question":176,"answer":177,"level":145,"tags":178},23,"How does module caching work in Node.js? How can you clear or manipulate the cache?","**Concept Explanation:**\nNode.js caches modules after the first `require()` or `import` to improve performance. The cache is stored in `require.cache` (object). Subsequent loads return the cached module, preventing re-execution and maintaining state.\n\n**Execution Flow:**\n1. First `require('.\u002Fmodule.js')`: Node.js resolves path, reads file, wraps code, executes, stores exports in cache\n2. Second `require('.\u002Fmodule.js')`: Returns cached exports without re-executing\n3. Circular dependencies: partially cached module, cycles handled by caching\n\n**Event Loop Explanation:**\nModule resolution and loading are synchronous and happen during startup or first import. Caching doesn't involve event loop.\n\n**Memory Behavior:**\nCache holds reference to module.exports object. Memory grows with each unique module. Unloading modules requires deleting cache entry and cleaning references.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F module.js\nexports.count = 0;\nconsole.log('Module executed');\n\n\u002F\u002F main.js\nrequire('.\u002Fmodule'); \u002F\u002F 'Module executed' logged\nconst mod = require('.\u002Fmodule'); \u002F\u002F No log, returns cached\nconsole.log(mod.count); \u002F\u002F 0\nmod.count++;\n\nconst mod2 = require('.\u002Fmodule'); \u002F\u002F Same object\nconsole.log(mod2.count); \u002F\u002F 1\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Inspect cache\nconsole.log(require.cache);\n\n\u002F\u002F Clear a specific module\ndelete require.cache[require.resolve('.\u002Fmodule.js')];\n\n\u002F\u002F Re-require after clearing\nconst fresh = require('.\u002Fmodule.js'); \u002F\u002F Re-executes\n\n\u002F\u002F Clear all cache (not recommended in production)\nObject.keys(require.cache).forEach(key => {\n  delete require.cache[key];\n});\n\n\u002F\u002F For ES modules (import), cache is not directly accessible\n\u002F\u002F Use --eval to inspect, but no delete\n```\n\n**Practical Example:**\nHot reloading during development:\n```js\nimport fs from 'node:fs';\n\nfunction hotReload(modulePath) {\n  \u002F\u002F Clear from cache\n  const resolved = require.resolve(modulePath);\n  delete require.cache[resolved];\n  \n  \u002F\u002F Re-require\n  try {\n    const fresh = require(modulePath);\n    console.log('Module reloaded');\n    return fresh;\n  } catch (err) {\n    console.error('Reload failed', err);\n    return null;\n  }\n}\n\n\u002F\u002F Watch file changes\nfs.watch('.\u002Fconfig.js', () => {\n  const newConfig = hotReload('.\u002Fconfig.js');\n  if (newConfig) global.config = newConfig;\n});\n```\n\n**Common Mistakes:**\n- Expecting cache clear to free memory immediately (module may still be referenced elsewhere)\n- Modifying cached modules leading to unexpected shared state\n- Clearing cache in production causes memory leaks and inconsistent state\n- Assuming ES modules (import) have same cache API (they don't, cache is internal)\n\n**Interview Follow-ups:**\n- Q: How does circular dependency resolution work with caching? A: Node.js returns a partially populated module (empty exports) to break cycle, then continues\n- Q: Can you disable caching? A: No, but you can clear or use `require.cache` to manipulate\n\n**Best Practices:**\n- Never clear cache in production except for specific tooling (test runners, dev servers)\n- Use dependency injection instead of relying on module singletons for config\n- For hot reloading, use dedicated tools (nodemon, webpack HMR)\n- Keep modules stateless where possible to avoid cache-related bugs\n\n**Performance Considerations:**\n- Cache reduces startup time significantly for repeated requires\n- Cache lookup is O(1) based on resolved filename\n- Large cache (thousands of modules) uses memory but not CPU\n\n**Production Recommendations:**\n- Avoid conditional requires that bypass cache (e.g., `require(condition ? 'a' : 'b')` still caches each)\n- Use `module.require` for relative requires from module context\n- For dynamic configuration, use environment variables or config service, not cache manipulation\n\n**Browser Behavior:**\nBrowser ES modules have cache per `import` based on URL. No API to clear.\n\n**Node.js Runtime Behavior:**\n- `require.cache` key is the fully resolved filename\n- Each module has `module.children` array of required modules\n- `module.parent` deprecated; use `require.main` to check if directly executed\n- `require.resolve.paths` shows resolution paths\n\n**Latest Node.js Patterns:**\n- ES modules have `import.meta.resolve` but no exposed cache\n- `module.register()` for custom loaders (affects caching)\n- `node:vm` module for isolated contexts with separate caches\n\n**TypeScript Example:**\n```ts\ninterface ModuleCache {\n  [key: string]: NodeModule;\n}\n\nclass ModuleCacheManager {\n  static clearByPattern(pattern: RegExp): void {\n    const cache = require.cache as ModuleCache;\n    for (const key of Object.keys(cache)) {\n      if (pattern.test(key)) {\n        delete cache[key];\n      }\n    }\n  }\n  \n  static reloadModule\u003CT>(modulePath: string): T {\n    const resolved = require.resolve(modulePath);\n    delete require.cache[resolved];\n    return require(modulePath);\n  }\n}\n```\n\n**Interview Tip:**\nExplain that module caching makes singletons work in Node.js. It's a feature, not a bug. Use with care.\n\n**Common Follow-up:**\n\"How does ES module caching differ from CommonJS?\" ES modules are cached by URL, but cache is not exposed; also top-level `await` affects execution order.\n\n**Real-world Example:**\nJest test runner clears module cache between tests to isolate test cases. Webpack dev server uses module cache invalidation for HMR.\n\n**Advanced Notes:**\n`require.cache` entries are `Module` objects with `exports`, `filename`, `loaded`, `children`. Deleting an entry doesn't automatically delete children references; memory leaks possible. `module.require` uses same cache as global require.",[31,179,180],"caching","require",{"id":182,"category":183,"question":184,"answer":185,"level":145,"tags":186},24,"Authentication","How do you implement JWT authentication in Node.js? What are security best practices?","**Concept Explanation:**\nJWT (JSON Web Token) is a compact, URL-safe token format for securely transmitting claims between parties. In Node.js auth, JWTs are used for stateless authentication: server issues a signed token; client includes it in requests; server verifies signature without session storage.\n\n**Execution Flow:**\n1. User logs in with credentials; server validates\n2. Server generates JWT with payload (userId, roles, expiry) signed with secret\n3. Client stores token (localStorage, cookie)\n4. Client sends token in Authorization: Bearer \u003Ctoken> header\n5. Server verifies signature, checks expiry, extracts user ID\n6. Server processes request based on claims\n\n**Event Loop Explanation:**\nJWT verification (signature check) is synchronous and CPU-bound. For high throughput, use `fast-jwt` or worker threads. Asynchronous verify options exist but still block event loop.\n\n**Memory Behavior:**\n- JWT parsing creates object; token strings are small (\u003C 1KB typically)\n- No server-side storage, reducing memory footprint\n- Malformed tokens error quickly\n\n**Lifecycle Explanation:**\n```js\nimport jwt from 'jsonwebtoken';\n\n\u002F\u002F Login endpoint\napp.post('\u002Flogin', async (req, res) => {\n  const { username, password } = req.body;\n  const user = await authenticate(username, password);\n  \n  const token = jwt.sign(\n    { userId: user.id, role: user.role },\n    process.env.JWT_SECRET,\n    { expiresIn: '1h' }\n  );\n  \n  res.json({ token });\n});\n\n\u002F\u002F Middleware to verify token\nfunction authenticateToken(req, res, next) {\n  const authHeader = req.headers['authorization'];\n  const token = authHeader && authHeader.split(' ')[1];\n  \n  if (!token) return res.sendStatus(401);\n  \n  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {\n    if (err) return res.sendStatus(403);\n    req.user = user;\n    next();\n  });\n}\n\n\u002F\u002F Protected route\napp.get('\u002Fprofile', authenticateToken, (req, res) => {\n  res.json(req.user);\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Signing\nconst token = jwt.sign(payload, secret, { expiresIn: '1h', issuer: 'myapp' });\n\n\u002F\u002F Verification (synchronous)\ntry {\n  const decoded = jwt.verify(token, secret, { algorithms: ['HS256'] });\n} catch (err) {\n  \u002F\u002F invalid signature or expired\n}\n\n\u002F\u002F Decoding without verification (unsafe!)\nconst decoded = jwt.decode(token); \u002F\u002F DO NOT USE FOR AUTH\n```\n\n**Practical Example:**\nRefresh token flow:\n```js\nimport jwt from 'jsonwebtoken';\n\nconst ACCESS_SECRET = process.env.ACCESS_SECRET;\nconst REFRESH_SECRET = process.env.REFRESH_SECRET;\n\nfunction generateTokens(userId) {\n  const accessToken = jwt.sign({ userId }, ACCESS_SECRET, { expiresIn: '15m' });\n  const refreshToken = jwt.sign({ userId }, REFRESH_SECRET, { expiresIn: '7d' });\n  \u002F\u002F Store refresh token hash in database for revocation\n  return { accessToken, refreshToken };\n}\n\napp.post('\u002Frefresh', async (req, res) => {\n  const { refreshToken } = req.body;\n  try {\n    const { userId } = jwt.verify(refreshToken, REFRESH_SECRET);\n    const isValid = await db.checkRefreshToken(userId, refreshToken);\n    if (!isValid) throw new Error('Invalid');\n    const newAccessToken = jwt.sign({ userId }, ACCESS_SECRET, { expiresIn: '15m' });\n    res.json({ accessToken: newAccessToken });\n  } catch {\n    res.status(403).json({ error: 'Invalid refresh token' });\n  }\n});\n```\n\n**Common Mistakes:**\n- Storing sensitive data (passwords) in JWT (payload is base64 encoded, not encrypted)\n- Not setting expiration (tokens valid forever)\n- Using weak secrets or default `none` algorithm\n- Verifying token without checking `alg` (algorithm confusion attack)\n- Storing JWT in localStorage (XSS risk) vs httpOnly cookie (CSRF risk)\n\n**Interview Follow-ups:**\n- Q: What's the difference between JWT and session-based auth? A: JWT stateless (no server storage), sessions stored server-side (memory\u002Fdb)\n- Q: How do you revoke a JWT before expiry? A: Maintain a blacklist or use short-lived access tokens + refresh tokens\n\n**Best Practices:**\n- Use strong secret (>=32 bytes, random) and rotate periodically\n- Set reasonable expiry (15 min for access, days for refresh)\n- Use `httpOnly`, `Secure`, `SameSite=Strict` cookies for web apps\n- Validate algorithm: `jwt.verify(token, secret, { algorithms: ['HS256'] })`\n- Never use `none` algorithm in production\n\n**Performance Considerations:**\n- RSA\u002FECDSA verification slower than HMAC; prefer HS256 for internal services\n- Synchronous `verify` blocks event loop; use async version or `setImmediate` for many tokens\n- Cache public keys for JWKS (if using OIDC)\n\n**Production Recommendations:**\n- Store secrets in environment variables or Vault\n- Implement token versioning to force re-login after secret rotation\n- Use `express-jwt` middleware for easier integration\n- Monitor failed verifications (potential brute force or invalid tokens)\n\n**Browser Behavior:**\nJWT not specific to browser; client stores token. For XSS protection, prefer httpOnly cookies; but then CSRF protection needed. Modern: use `SameSite=Strict` + `__Host-` prefix.\n\n**Node.js Runtime Behavior:**\n`jsonwebtoken` library is most common, but `jose` and `njwt` are alternatives. Native `crypto` can verify JWTs but no built-in parser.\n\n**Latest Node.js Patterns:**\n- `jsonwebtoken` 9.x supports async sign\u002Fverify with `crypto.generateKeyPair`\n- `jose` library for JWT with Web Cryptography API\n- Edge runtime support (Cloudflare Workers, Vercel Edge) with WebCrypto\n\n**TypeScript Example:**\n```ts\nimport jwt from 'jsonwebtoken';\n\ninterface JwtPayload {\n  userId: number;\n  role: 'admin' | 'user';\n}\n\nclass JwtService {\n  private readonly secret: string;\n  \n  constructor(secret: string) {\n    this.secret = secret;\n  }\n  \n  sign(payload: JwtPayload): string {\n    return jwt.sign(payload, this.secret, { expiresIn: '1h' });\n  }\n  \n  verify(token: string): JwtPayload | null {\n    try {\n      return jwt.verify(token, this.secret, { algorithms: ['HS256'] }) as JwtPayload;\n    } catch {\n      return null;\n    }\n  }\n}\n```\n\n**Interview Tip:**\nEmphasize that JWT is for authentication, not session management. Revocation is the main downside; recommend refresh token pattern.\n\n**Common Follow-up:**\n\"How do you handle token renewal when access token expires?\" Use refresh token grant; client calls refresh endpoint, server issues new access token.\n\n**Real-world Example:**\nStripe uses JWT for Connect platform authentication. Auth0 issues JWTs as access tokens for API authorization.\n\n**Advanced Notes:**\nJWT claims can be encrypted (JWE) for sensitive data. Use `jsonwebtoken` with `jose` for encryption. Audience (`aud`) and issuer (`iss`) validation prevents token misuse across services.",[187,188,189],"jwt","authentication","security",{"id":191,"category":192,"question":193,"answer":194,"level":145,"tags":195},25,"Architecture","What are Worker Threads in Node.js? When should you use them instead of clusters or child processes?","**Concept Explanation:**\nWorker threads (`worker_threads` module) allow parallel execution of JavaScript code within the same Node.js process. Each worker runs in its own V8 isolate and event loop, but can share memory via `SharedArrayBuffer`. Unlike clusters (separate processes), workers share the same address space and can transfer data more efficiently.\n\n**Execution Flow:**\n1. Main thread creates a worker: `new Worker(filename)`\n2. Worker loads and executes script in separate thread\n3. Communication via `postMessage` and `parentPort`\n4. Data transfer: either cloned (structuredClone) or transferred (ArrayBuffer ownership)\n5. Worker exits or terminates\n\n**Event Loop Explanation:**\nEach worker has its own event loop, independent of the main thread. Blocking I\u002FO or CPU work in one worker does not block others or the main thread.\n\n**Memory Behavior:**\n- Each worker has separate V8 heap (~2-4 MB overhead + memory usage)\n- Shared memory via `SharedArrayBuffer` (synchronized via `Atomics`)\n- `postMessage` with transfer moves memory ownership (zero-copy)\n\n**Lifecycle Explanation:**\n```js\nimport { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';\n\nif (isMainThread) {\n  \u002F\u002F Main thread\n  const worker = new Worker(__filename, {\n    workerData: { start: 1, end: 1e8 }\n  });\n  \n  worker.on('message', (result) => console.log('Sum:', result));\n  worker.on('error', console.error);\n  worker.on('exit', (code) => console.log(`Worker exited with ${code}`));\n} else {\n  \u002F\u002F Worker thread\n  const { start, end } = workerData;\n  let sum = 0;\n  for (let i = start; i \u003C= end; i++) sum += i; \u002F\u002F CPU-intensive\n  parentPort.postMessage(sum);\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Transferring ArrayBuffer (zero-copy)\nconst buffer = new SharedArrayBuffer(1024);\nconst worker = new Worker('.\u002Fworker.js');\nworker.postMessage(buffer, [buffer]); \u002F\u002F Transfers ownership\n\n\u002F\u002F Using Atomics for synchronization\nconst shared = new Int32Array(new SharedArrayBuffer(4));\nAtomics.store(shared, 0, 1);\nAtomics.wait(shared, 0, 1); \u002F\u002F Blocks until notified\n\n\u002F\u002F Worker pools\nimport { Worker } from 'node:worker_threads';\nconst pool = [];\nfor (let i = 0; i \u003C os.cpus().length; i++) {\n  pool.push(new Worker('.\u002Fcpu-worker.js'));\n}\n```\n\n**Practical Example:**\nParallel image processing:\n```js\nimport { Worker } from 'node:worker_threads';\nimport os from 'node:os';\n\nfunction processImageParallel(imageBuffer, operations) {\n  const numWorkers = os.cpus().length;\n  const chunkSize = Math.ceil(imageBuffer.length \u002F numWorkers);\n  const workers = [];\n  \n  for (let i = 0; i \u003C numWorkers; i++) {\n    const start = i * chunkSize;\n    const end = Math.min(start + chunkSize, imageBuffer.length);\n    const chunk = imageBuffer.subarray(start, end);\n    \n    const worker = new Worker('.\u002Fimage-worker.js', {\n      workerData: { chunk, operations }\n    });\n    workers.push(worker);\n  }\n  \n  return Promise.all(workers.map(worker => \n    new Promise(resolve => worker.on('message', resolve))\n  )).then(results => Buffer.concat(results));\n}\n```\n\n**Common Mistakes:**\n- Using workers for I\u002FO-bound tasks (clusters or just async I\u002FO better)\n- Creating too many workers (overhead, memory)\n- Not handling worker exit\u002Ferror (silent failures)\n- Sharing state without synchronization (race conditions)\n- Using `workerData` for large data (serialized, inefficient; use transfer)\n\n**Interview Follow-ups:**\n- Q: Difference between worker threads and child_process? A: Workers share memory, faster IPC; child processes separate memory, more stable isolation\n- Q: When to use cluster vs worker threads? A: Cluster for load balancing HTTP requests (multiple ports), workers for CPU-intensive tasks within one app\n\n**Best Practices:**\n- Use worker pools (pre-create workers, reuse) instead of creating per task\n- Use `Atomics` or message passing for synchronization, not shared state\n- Terminate workers when idle: `worker.terminate()`\n- Keep worker scripts small and independent\n\n**Performance Considerations:**\n- Worker creation overhead ~5-10ms, reuse for many tasks\n- Each worker adds ~2-4MB RSS overhead\n- Transferring ArrayBuffer is O(1) (pointer handoff)\n- CPU-bound tasks scale linearly up to number of cores\n\n**Production Recommendations:**\n- Use `worker_threads` for CPU-intensive work (crypto, image processing, data compression)\n- Use `piscina` (npm) for robust worker pool management\n- Set `resourceLimits` to prevent memory blow\n- Monitor `worker.performance.resourceUsage` for CPU time\n\n**Browser Behavior:**\nWeb Workers are similar but use `postMessage` and `SharedArrayBuffer`. Node.js workers are based on Web Workers API but not identical.\n\n**Node.js Runtime Behavior:**\n- Workers require `--experimental-worker` in Node.js 10; stable since 12\n- `worker.parentPort` is a MessagePort\n- `worker.threadId` unique identifier\n- `worker.getHeapSnapshot()` for debugging\n\n**Latest Node.js Patterns:**\n- `new Worker` with `eval` option for inline code\n- `worker.moveMessagePortToContext` for advanced use\n- `MessageChannel` for two-way communication\n- `worker.unref()` to allow process exit\n\n**TypeScript Example:**\n```ts\nimport { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';\n\ninterface Task {\n  id: number;\n  data: Uint8Array;\n}\n\nif (isMainThread) {\n  class WorkerPool {\n    private workers: Worker[] = [];\n    private queue: Task[] = [];\n    \n    constructor(size: number, filename: string) {\n      for (let i = 0; i \u003C size; i++) {\n        const worker = new Worker(filename);\n        worker.on('message', this.handleResult.bind(this));\n        this.workers.push(worker);\n      }\n    }\n    \n    run(task: Task): Promise\u003Cany> {\n      const worker = this.workers.pop();\n      if (worker) {\n        worker.postMessage(task);\n        return new Promise(resolve => {\n          worker.once('message', (result) => {\n            this.workers.push(worker);\n            resolve(result);\n          });\n        });\n      } else {\n        this.queue.push(task);\n        return Promise.resolve();\n      }\n    }\n    \n    private handleResult() { \u002F* ... *\u002F }\n  }\n}\n```\n\n**Interview Tip:**\nHighlight that worker threads don't make Node.js 'multi-threaded' in the traditional shared-memory sense; they are isolated execution contexts with message passing.\n\n**Common Follow-up:**\n\"Can workers share database connections?\" No, each worker creates its own connection. Use a connection pool per worker or centralize in main thread.\n\n**Real-world Example:**\nSharp (image processing library) uses worker threads to parallelize image resizing. Prisma uses workers for query engine.\n\n**Advanced Notes:**\nWorkers use V8 isolates, each with its own heap. `SharedArrayBuffer` uses actual shared memory; synchronization via `Atomics` (wait\u002Fnotify) can block threads. `worker.moveMessagePortToContext` allows passing ports across contexts.",[196,197,47],"worker-threads","concurrency",{"id":199,"category":192,"question":200,"answer":201,"level":145,"tags":202},26,"How do you create and manage child processes in Node.js? Compare spawn, exec, execFile, and fork.","**Concept Explanation:**\nThe `node:child_process` module enables creating subprocesses to execute system commands, scripts, or other Node.js apps. Four main methods: `spawn` (streams), `exec` (buffers), `execFile` (executable file), and `fork` (Node.js module). Each has different use cases, performance characteristics, and output handling.\n\n**Execution Flow:**\n1. Parent process calls `spawn`, `exec`, `execFile`, or `fork`\n2. OS creates new process (fork+exec on Unix, CreateProcess on Windows)\n3. Communication via stdio streams (stdin\u002Fstdout\u002Fstderr) or IPC channel\n4. Parent can send signals, kill process, receive exit code\n\n**Event Loop Explanation:**\nChild processes run independently of the parent's event loop. The parent receives events (`'exit'`, `'message'`, `'close'`) via the event loop. `exec` buffers output in memory and returns it all at once, which can block if output is huge.\n\n**Memory Behavior:**\n- `spawn` streams output → constant memory usage\n- `exec` \u002F `execFile` buffer output → O(output size) memory\n- `fork` creates IPC channel, moderate overhead (~10-20MB per child)\n\n**Lifecycle Explanation:**\n```js\nimport { spawn, exec, execFile, fork } from 'node:child_process';\n\n\u002F\u002F spawn (streams, large output)\nconst ls = spawn('ls', ['-la']);\nls.stdout.on('data', (data) => console.log(data.toString()));\nls.stderr.on('data', (data) => console.error(data.toString()));\nls.on('close', (code) => console.log(`Exit: ${code}`));\n\n\u002F\u002F exec (buffers, simple commands)\nexec('cat *.js | wc -l', (error, stdout, stderr) => {\n  if (error) console.error(error);\n  console.log(stdout);\n});\n\n\u002F\u002F execFile (direct executable, no shell)\nexecFile('node', ['--version'], (err, stdout) => console.log(stdout));\n\n\u002F\u002F fork (Node.js module with IPC)\nconst child = fork('.\u002Fchild.js');\nchild.on('message', (msg) => console.log('From child:', msg));\nchild.send({ hello: 'parent' });\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F spawn options\nconst proc = spawn('command', ['arg1', 'arg2'], {\n  cwd: '\u002Fsome\u002Fpath',      \u002F\u002F working directory\n  env: { ...process.env, MY_VAR: 'value' }, \u002F\u002F environment\n  detached: true,          \u002F\u002F run independently\n  stdio: 'pipe'            \u002F\u002F 'pipe', 'ignore', 'inherit', or array\n});\n\n\u002F\u002F exec options\n exec('command', {\n  maxBuffer: 1024 * 1024, \u002F\u002F 1MB buffer limit (default 1MB)\n  timeout: 5000,          \u002F\u002F kill after 5 seconds\n  killSignal: 'SIGTERM'\n});\n```\n\n**Practical Example:**\nRunning a Python script from Node.js with streaming output:\n```js\nimport { spawn } from 'node:child_process';\nimport { createWriteStream } from 'node:fs';\n\nfunction runPythonScript(scriptPath, args, outputFile) {\n  const python = spawn('python3', [scriptPath, ...args]);\n  const logStream = createWriteStream(outputFile, { flags: 'a' });\n  \n  python.stdout.pipe(process.stdout); \u002F\u002F Live output to console\n  python.stdout.pipe(logStream);      \u002F\u002F Also log to file\n  \n  python.stderr.on('data', (data) => {\n    console.error(`Python error: ${data}`);\n  });\n  \n  return new Promise((resolve, reject) => {\n    python.on('close', (code) => {\n      if (code === 0) resolve();\n      else reject(new Error(`Process exited with ${code}`));\n    });\n  });\n}\n```\n\n**Common Mistakes:**\n- Using `exec` for large outputs (causes buffer overflow error)\n- Forgetting to handle `error` event (process can crash silently)\n- Not killing child processes on parent exit (zombie processes)\n- Using `shell: true` unnecessarily (security risk)\n\n**Interview Follow-ups:**\n- Q: When to use `fork` vs `spawn`? A: `fork` for Node.js modules with IPC; `spawn` for any other command\n- Q: How do you detect child process crash? A: Listen for `'exit'` with non-zero code or `'error'` event\n\n**Best Practices:**\n- Default to `spawn` for most use cases (streaming, no buffer limits)\n- Use `exec` only for short, small-output commands\n- Always set timeout for `exec` to avoid hanging\n- Use `util.promisify` with `exec` for async\u002Fawait: `import { exec } from 'node:child_process'; import { promisify } from 'node:util'; const execAsync = promisify(exec);`\n\n**Performance Considerations:**\n- `spawn` has lowest overhead (no extra shell, streaming)\n- `exec` creates a shell (extra process)\n- `fork` is optimized for Node.js modules, shares V8 memory? No, each fork creates new isolate\n\n**Production Recommendations:**\n- Use `detached: true` with `child.unref()` for daemon processes\n- Monitor child process resource usage via `process.resourceUsage()`\n- Set `maxBuffer` appropriately to avoid memory DoS\n- For many child processes, use `worker_threads` instead if CPU-bound\n\n**Browser Behavior:**\nNot applicable (no child processes in browser).\n\n**Node.js Runtime Behavior:**\n- `fork` automatically sets up IPC channel, default stdio ['pipe', 'pipe', 'pipe', 'ipc']\n- `exec` uses `\u002Fbin\u002Fsh` on Unix, `cmd.exe` on Windows\n- `detached` processes on Windows can be tricky; use `child_process.spawn` with `detached` and `stdio: 'ignore'`\n\n**Latest Node.js Patterns:**\n- `subprocess.kill('SIGTERM')` vs `subprocess.kill()` (SIGTERM default)\n- `subprocess.ref()` and `subprocess.unref()` for event loop reference\n- `--inspect` for debugging child processes\n\n**TypeScript Example:**\n```ts\nimport { spawn, SpawnOptions } from 'node:child_process';\n\ninterface RunResult {\n  stdout: string;\n  stderr: string;\n  code: number | null;\n}\n\nfunction runCommand(cmd: string, args: string[], options?: SpawnOptions): Promise\u003CRunResult> {\n  return new Promise((resolve, reject) => {\n    const proc = spawn(cmd, args, options);\n    let stdout = '';\n    let stderr = '';\n    \n    proc.stdout.on('data', (data) => stdout += data);\n    proc.stderr.on('data', (data) => stderr += data);\n    proc.on('close', (code) => resolve({ stdout, stderr, code }));\n    proc.on('error', reject);\n  });\n}\n```\n\n**Interview Tip:**\nMention that `fork` is a specialized `spawn` for Node.js scripts with built-in IPC, making it ideal for breaking work into separate processes.\n\n**Common Follow-up:**\n\"How do you pass an environment variable to a child process?\" Use `env` option in `spawn`\u002F`exec`, merging `process.env` with custom values.\n\n**Real-world Example:**\nnpm scripts use `child_process.spawn` to run other commands. Build tools (Webpack, Vite) spawn compilers (TypeScript, Babel) as child processes.\n\n**Advanced Notes:**\n`spawn` returns a `ChildProcess` object with `pid`, `connected`, `kill()`, `send()`. IPC messages use JSON serialization, can send handles (sockets, servers) via `send(message, handle)`.",[203,204,205,206],"child-process","spawn","exec","fork",{"id":208,"category":209,"question":210,"answer":211,"level":145,"tags":212},27,"Scaling","What is the cluster module and how does it help with scaling Node.js applications?","**Concept Explanation:**\nThe `node:cluster` module allows creating multiple Node.js processes (workers) that share the same server port. It enables horizontal scaling on multi-core systems by distributing incoming connections across child processes, maximizing CPU utilization.\n\n**Execution Flow:**\n1. Master process calls `cluster.fork()` to create workers\n2. Each worker runs the same application code\n3. Master listens on a port and distributes incoming connections to workers\n4. Distribution can be round-robin (default on Linux) or OS-based (master socket handle passing)\n5. Workers handle requests independently; if one crashes, master restarts it\n\n**Event Loop Explanation:**\nEach worker has its own event loop, isolated from others. The master process has its own event loop (lightweight, only for management).\n\n**Memory Behavior:**\n- Each worker has separate memory space (~20-50MB overhead each)\n- No shared memory between workers (unlike worker_threads)\n- Master process minimal memory usage\n- Total memory = sum of workers + master\n\n**Lifecycle Explanation:**\n```js\nimport cluster from 'node:cluster';\nimport os from 'node:os';\nimport http from 'node:http';\n\nif (cluster.isPrimary) {\n  console.log(`Master ${process.pid} running`);\n  \n  \u002F\u002F Fork workers for each CPU core\n  const numCPUs = os.availableParallelism();\n  for (let i = 0; i \u003C numCPUs; i++) {\n    cluster.fork();\n  }\n  \n  \u002F\u002F Restart worker on crash\n  cluster.on('exit', (worker, code, signal) => {\n    console.log(`Worker ${worker.process.pid} died. Restarting...`);\n    cluster.fork();\n  });\n} else {\n  \u002F\u002F Workers share same port\n  http.createServer((req, res) => {\n    res.writeHead(200);\n    res.end(`Handled by worker ${process.pid}`);\n  }).listen(3000);\n  \n  console.log(`Worker ${process.pid} started`);\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Communication between master and workers\nif (cluster.isPrimary) {\n  const worker = cluster.fork();\n  worker.send({ hello: 'worker' });\n  worker.on('message', (msg) => console.log('From worker:', msg));\n} else {\n  process.on('message', (msg) => {\n    console.log('Worker received:', msg);\n    process.send({ pong: 'ok' });\n  });\n}\n\n\u002F\u002F Sticky sessions (if needed)\n\u002F\u002F Use external store (Redis) because workers are separate\n```\n\n**Practical Example:**\nZero-downtime restart using cluster:\n```js\nimport cluster from 'node:cluster';\nimport http from 'node:http';\n\nif (cluster.isPrimary) {\n  let workers = [];\n  \n  function restart() {\n    for (let i = 0; i \u003C workers.length; i++) {\n      const worker = workers[i];\n      worker.disconnect(); \u002F\u002F Stop accepting new connections\n      \n      worker.once('disconnect', () => {\n        console.log(`Worker ${worker.id} disconnected`);\n        const newWorker = cluster.fork();\n        workers[i] = newWorker;\n      });\n    }\n  }\n  \n  for (let i = 0; i \u003C os.cpus().length; i++) {\n    workers.push(cluster.fork());\n  }\n  \n  process.on('SIGUSR2', restart); \u002F\u002F Send signal to restart\n} else {\n  \u002F\u002F App code\n  const server = http.createServer((req, res) => {\n    res.end('Hello');\n  }).listen(3000);\n  \n  \u002F\u002F Graceful shutdown on disconnect\n  process.on('disconnect', () => {\n    server.close(() => process.exit(0));\n  });\n}\n```\n\n**Common Mistakes:**\n- Not handling worker crashes (cluster stays with fewer workers)\n- Assuming workers share memory (need Redis\u002FDB for shared state)\n- Creating too many workers (more than CPU cores causes overhead)\n- Using cluster for non-HTTP workloads (better to use worker_threads)\n\n**Interview Follow-ups:**\n- Q: How does cluster differ from worker_threads? A: Clusters are separate processes (better isolation, more memory); worker threads share memory (efficient for CPU tasks)\n- Q: What is the default load balancing algorithm? A: Round-robin on Linux, OS-scheduled on Windows (can set `cluster.schedulingPolicy = cluster.SCHED_RR` for consistency)\n\n**Best Practices:**\n- Fork one worker per CPU core (or `os.availableParallelism()`)\n- Use `cluster.on('exit')` to restart failed workers\n- For zero-downtime, use `worker.disconnect()` before killing\n- Share no in-memory state; use distributed cache\n\n**Performance Considerations:**\n- Cluster adds ~5-10% overhead for IPC (negligible)\n- Round-robin balancing may cause out-of-order requests for long-polling\n- Each worker has full event loop, handles many concurrent connections\n- Master process should be lightweight (no heavy work)\n\n**Production Recommendations:**\n- Use PM2 for process management (easier, more features)\n- Combine cluster with reverse proxy (Nginx) for static assets\n- Set `cluster.schedulingPolicy = cluster.SCHED_RR` for consistent balancing\n- Monitor worker memory; restart if exceeds limit\n\n**Browser Behavior:**\nNot applicable.\n\n**Node.js Runtime Behavior:**\n- On Linux, master creates a server socket, passes handle to workers via `send`\n- On Windows, uses named pipes for handle passing\n- `cluster.worker.id` and `cluster.worker.process.pid` for identification\n\n**Latest Node.js Patterns:**\n- `cluster.setupPrimary()` to configure default settings\n- `cluster.worker.kill()` vs `cluster.worker.disconnect()`\n- Worker `'listening'` event to know when ready\n\n**TypeScript Example:**\n```ts\nimport cluster from 'node:cluster';\nimport http from 'node:http';\nimport os from 'node:os';\n\nif (cluster.isPrimary) {\n  const numWorkers = os.availableParallelism();\n  console.log(`Master starting ${numWorkers} workers`);\n  \n  for (let i = 0; i \u003C numWorkers; i++) {\n    cluster.fork();\n  }\n  \n  cluster.on('exit', (worker, code, signal) => {\n    console.log(`Worker ${worker.process.pid} died. Forking new one.`);\n    cluster.fork();\n  });\n} else {\n  const server = http.createServer((req, res) => {\n    res.writeHead(200, { 'Content-Type': 'text\u002Fplain' });\n    res.end(`Worker ${process.pid} handled request\\n`);\n  });\n  \n  server.listen(3000, () => {\n    console.log(`Worker ${process.pid} listening`);\n  });\n}\n```\n\n**Interview Tip:**\nExplain that cluster solves the single-threaded limitation for I\u002FO-bound servers, but for CPU-bound tasks, worker_threads are better.\n\n**Common Follow-up:**\n\"How do you handle WebSockets with cluster?\" Use sticky sessions (same worker for same client) or external adapter (Redis adapter for socket.io).\n\n**Real-world Example:**\nExpress.js apps commonly run behind cluster to utilize all CPU cores. PM2 cluster mode is widely used in production.\n\n**Advanced Notes:**\n`cluster` uses `child_process.fork` under the hood. The master process shares the file descriptor using `send('server', handle)`. Round-robin scheduling ensures even distribution, but may cause increased latency for keep-alive connections if not configured.",[213,214,215],"cluster","scaling","load-balancing",{"id":217,"category":118,"question":218,"answer":219,"level":145,"tags":220},28,"What is middleware in Express.js? Explain different types and how to write custom middleware.","**Concept Explanation:**\nMiddleware functions in Express have access to request (`req`), response (`res`), and the next middleware (`next`). They can execute code, modify req\u002Fres, end the request-response cycle, or call `next()` to pass control. Middleware executes in the order they are mounted.\n\n**Execution Flow:**\n1. Request enters Express app\n2. Matches first middleware (by path\u002Fmethod)\n3. Middleware runs synchronously or asynchronously, calls `next()` when done\n4. Next middleware in chain executes\n5. If no middleware ends the cycle, Express sends 404\n\n**Event Loop Explanation:**\nMiddleware functions can be async; if they don't call `next()` or send response, request hangs. Use `next(error)` to jump to error handlers.\n\n**Memory Behavior:**\nMiddleware functions are stored in an array per route. Each request creates a `next` closure but middleware stack is shared.\n\n**Lifecycle Explanation:**\n```js\nimport express from 'express';\nconst app = express();\n\n\u002F\u002F Application-level middleware (runs for all requests)\napp.use((req, res, next) => {\n  console.log(`${req.method} ${req.url}`);\n  next(); \u002F\u002F Pass to next middleware\n});\n\n\u002F\u002F Router-level middleware (applies to specific router)\nconst router = express.Router();\nrouter.use('\u002Fadmin', (req, res, next) => {\n  if (!req.user.isAdmin) return res.status(403).send('Forbidden');\n  next();\n});\n\n\u002F\u002F Error-handling middleware (4 arguments)\napp.use((err, req, res, next) => {\n  console.error(err.stack);\n  res.status(500).send('Something broke!');\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Built-in middleware\napp.use(express.json());           \u002F\u002F Parse JSON bodies\napp.use(express.urlencoded({ extended: true })); \u002F\u002F Parse form data\napp.use(express.static('public')); \u002F\u002F Serve static files\n\n\u002F\u002F Third-party middleware\nimport morgan from 'morgan';\napp.use(morgan('combined'));\n\n\u002F\u002F Custom middleware (synchronous)\napp.use((req, res, next) => {\n  req.requestTime = Date.now();\n  next();\n});\n\n\u002F\u002F Custom middleware (async with error handling)\napp.use(async (req, res, next) => {\n  try {\n    await someAsyncOperation();\n    next();\n  } catch (err) {\n    next(err); \u002F\u002F Forward to error handler\n  }\n});\n```\n\n**Practical Example:**\nAuthentication middleware with JWT:\n```js\nfunction authenticate(req, res, next) {\n  const token = req.headers.authorization?.split(' ')[1];\n  if (!token) return res.status(401).json({ error: 'No token' });\n  \n  try {\n    const decoded = jwt.verify(token, process.env.JWT_SECRET);\n    req.user = decoded; \u002F\u002F Attach user to request\n    next();\n  } catch (err) {\n    res.status(403).json({ error: 'Invalid token' });\n  }\n}\n\n\u002F\u002F Apply to specific routes\napp.get('\u002Fprofile', authenticate, (req, res) => {\n  res.json(req.user);\n});\n\n\u002F\u002F Apply to all routes except some\napp.use('\u002Fapi', authenticate);\napp.use('\u002Fapi\u002Fpublic', (req, res, next) => next()); \u002F\u002F Skip auth for public routes\n```\n\n**Common Mistakes:**\n- Forgetting to call `next()` (request hangs)\n- Calling `next()` after sending response (causes errors)\n- Not handling async errors (unhandled promise rejections)\n- Ordering middleware incorrectly (e.g., static before logging missing files)\n- Returning `next(err)` without `return` (still executes after next? Actually `next(err)` throws? No, it just calls, but you should `return next(err)` to avoid executing further code)\n\n**Interview Follow-ups:**\n- Q: How does `next()` work? A: It calls the next middleware in the stack; if called with an argument, jumps to error handlers\n- Q: Can middleware modify `req` and `res`? A: Yes, common pattern: attach properties to `req` (e.g., `req.user`)\n\n**Best Practices:**\n- Keep middleware focused (one responsibility)\n- Use `next(err)` for error propagation\n- Place error-handling middleware last\n- Use `app.use()` order carefully (top-to-bottom)\n- For conditional skipping, check condition early and call `next()`\n\n**Performance Considerations:**\n- Each middleware adds function call overhead; keep number reasonable (~10-20)\n- Expensive middleware (e.g., parsing large bodies) should be placed after auth\n- Use `express.json()` with `verify` option for custom parsing\n\n**Production Recommendations:**\n- Use `helmet` (security headers), `cors`, `compression` as middleware\n- Logging middleware like `morgan` with `combined` format\n- Rate limiting middleware (`express-rate-limit`) before expensive operations\n- Compress responses with `compression` middleware\n\n**Browser Behavior:**\nNot applicable (server-side).\n\n**Node.js Runtime Behavior:**\nMiddleware stack is an array; `next` recursively calls next matching middleware. Error-handling middleware have 4 parameters; Express identifies them by arity.\n\n**Latest Node.js Patterns:**\n- Express 5 supports async middleware without try\u002Fcatch (handles rejections automatically)\n- `app.param()` for parameter middleware (pre-processing route params)\n\n**TypeScript Example:**\n```ts\nimport { Request, Response, NextFunction, RequestHandler } from 'express';\n\n\u002F\u002F Typed custom middleware\ninterface AuthRequest extends Request {\n  user?: { id: number; role: string };\n}\n\nconst authenticate = (req: AuthRequest, res: Response, next: NextFunction): void => {\n  const token = req.headers.authorization?.split(' ')[1];\n  if (!token) {\n    res.status(401).json({ error: 'Unauthorized' });\n    return;\n  }\n  try {\n    const decoded = jwt.verify(token, process.env.JWT_SECRET!);\n    req.user = decoded as { id: number; role: string };\n    next();\n  } catch (err) {\n    res.status(403).json({ error: 'Invalid token' });\n  }\n};\n\n\u002F\u002F Higher-order middleware factory\nfunction requireRole(role: string): RequestHandler {\n  return (req: AuthRequest, res: Response, next: NextFunction) => {\n    if (req.user?.role !== role) {\n      res.status(403).json({ error: 'Insufficient permissions' });\n      return;\n    }\n    next();\n  };\n}\n\napp.get('\u002Fadmin', authenticate, requireRole('admin'), (req, res) => {\n  res.json({ message: 'Welcome admin' });\n});\n```\n\n**Interview Tip:**\nExplain that middleware is essentially the chain of responsibility pattern, and Express's implementation is what makes it so flexible.\n\n**Common Follow-up:**\n\"What's the difference between `app.use()` and `app.METHOD()`?\" `app.use()` matches any HTTP method and path prefix; `app.get()` only GET and exact path.\n\n**Real-world Example:**\nMorgan (logging), Helmet (security), Compression, and Cors are almost universal middleware in production Express apps.\n\n**Advanced Notes:**\nMiddleware can be mounted on a path: `app.use('\u002Fapi', middleware)`. It will run only for requests starting with `\u002Fapi`. Error-handling middleware must be defined after all other `app.use()` routes. Express 5 will automatically pass async rejects to `next()`, eliminating the need for wrappers.",[122,221,222],"middleware","auth",{"id":224,"category":225,"question":226,"answer":227,"level":145,"tags":228},29,"APIs","What are best practices for designing REST APIs in Node.js? How do you handle versioning?","**Concept Explanation:**\nREST API design best practices include resource naming, HTTP method usage, status codes, versioning strategies, filtering\u002Fsorting\u002Fpagination, idempotency, HATEOAS, and documentation. Versioning prevents breaking changes for clients.\n\n**Execution Flow:**\n1. Client sends HTTP request with version indicator (URL, header, or content negotiation)\n2. Express route handler determines version from req\n3. Appropriate controller logic executes\n4. Response includes version info and appropriate status code\n\n**Event Loop Explanation:**\nAPI handling doesn't affect event loop; focus is on design patterns, not performance.\n\n**Memory Behavior:**\nStateless APIs reduce server memory; no session storage needed.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Resource naming: plural nouns, lower case, kebab-case\nGET    \u002Fusers           \u002F\u002F List users\nGET    \u002Fusers\u002F123       \u002F\u002F Get user 123\nPOST   \u002Fusers           \u002F\u002F Create user\nPUT    \u002Fusers\u002F123       \u002F\u002F Replace user 123\nPATCH  \u002Fusers\u002F123       \u002F\u002F Partial update\nDELETE \u002Fusers\u002F123       \u002F\u002F Delete user 123\n\n\u002F\u002F Nested resources\nGET    \u002Fusers\u002F123\u002Fposts         \u002F\u002F Posts by user 123\nGET    \u002Fusers\u002F123\u002Fposts\u002F456     \u002F\u002F Post 456 by user 123\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Versioning strategies\n\n\u002F\u002F 1. URL path versioning (most common)\napp.get('\u002Fv1\u002Fusers', getUsersV1);\napp.get('\u002Fv2\u002Fusers', getUsersV2);\n\n\u002F\u002F 2. Custom header versioning\napp.get('\u002Fusers', (req, res) => {\n  const version = req.headers['api-version'] || '1.0';\n  if (version === '2.0') return getUsersV2(req, res);\n  getUsersV1(req, res);\n});\n\n\u002F\u002F 3. Content negotiation (Accept header)\napp.get('\u002Fusers', (req, res) => {\n  if (req.accepts('application\u002Fvnd.myapp.v2+json')) {\n    return getUsersV2(req, res);\n  }\n  getUsersV1(req, res);\n});\n```\n\n**Practical Example:**\nComplete versioned API structure:\n```js\nimport express from 'express';\nconst app = express();\n\n\u002F\u002F Version routing\nconst v1Router = express.Router();\nconst v2Router = express.Router();\n\nv1Router.get('\u002Fusers', (req, res) => {\n  res.json({ version: '1.0', users: [{ id: 1, name: 'Alice' }] });\n});\n\nv2Router.get('\u002Fusers', (req, res) => {\n  res.json({ version: '2.0', data: { users: [{ id: 1, fullName: 'Alice Smith', email: 'alice@example.com' }] } });\n});\n\napp.use('\u002Fv1', v1Router);\napp.use('\u002Fv2', v2Router);\n\n\u002F\u002F Query parameters for filtering, sorting, pagination\napp.get('\u002Fproducts', (req, res) => {\n  const { page = 1, limit = 20, sort = 'name', filter } = req.query;\n  const offset = (page - 1) * limit;\n  \n  \u002F\u002F Build query\n  let query = Product.find(filter);\n  query = query.sort(sort).skip(offset).limit(limit);\n  \n  \u002F\u002F Return pagination metadata\n  res.json({\n    data: results,\n    pagination: { page, limit, total, pages: Math.ceil(total \u002F limit) }\n  });\n});\n\n\u002F\u002F Proper status codes\napp.post('\u002Forders', async (req, res) => {\n  try {\n    const order = await createOrder(req.body);\n    res.status(201).location(`\u002Forders\u002F${order.id}`).json(order);\n  } catch (err) {\n    if (err.code === 'VALIDATION_ERROR') return res.status(422).json({ errors: err.details });\n    if (err.code === 'INSUFFICIENT_STOCK') return res.status(409).json({ error: 'Conflict' });\n    res.status(500).json({ error: 'Internal Server Error' });\n  }\n});\n```\n\n**Common Mistakes:**\n- Using verbs in URLs (`\u002FgetUser` instead of `GET \u002Fusers\u002F1`)\n- Returning 200 for errors (should use 4xx\u002F5xx)\n- Not versioning APIs (breaks existing clients)\n- Ignoring idempotency for PUT\u002FDELETE\n- Not providing pagination for list endpoints\n\n**Interview Follow-ups:**\n- Q: What is idempotency? Which methods should be idempotent? A: Idempotent means multiple identical requests have same effect. GET, PUT, DELETE should be idempotent; POST is not.\n- Q: What's the difference between PUT and PATCH? A: PUT replaces entire resource; PATCH applies partial update.\n\n**Best Practices:**\n- Use semantic HTTP status codes (200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 Unprocessable Entity, 429 Too Many Requests, 500 Internal Error)\n- Use `ETag` and `If-Match` for optimistic concurrency control\n- Return `Location` header on creation (201 Created)\n- Use `Content-Range` header for partial responses\n- Document API with OpenAPI\u002FSwagger\n\n**Performance Considerations:**\n- Versioning via URL has best CDN caching\n- Header versioning avoids duplicate code paths but may be less cacheable\n- Use `express-rate-limit` per endpoint\n- Implement conditional requests (If-None-Match, If-Modified-Since) to reduce bandwidth\n\n**Production Recommendations:**\n- Deprecate old versions gradually: return `Deprecation` header, `Sunset` header\n- Keep old versions alive for at least 6-12 months\n- Use API gateway to route versions\n- Validate input with Zod or Joi, return 422 with details\n\n**Browser Behavior:**\nBrowsers respect status codes and headers. CORS headers needed for cross-origin API calls.\n\n**Node.js Runtime Behavior:**\nExpress apps can implement versioning via middleware that parses version from header\u002FURL.\n\n**Latest Node.js Patterns:**\n- OpenAPI 3.0 code generation (express-openapi-validator)\n- GraphQL as alternative to versioned REST\n- Versioning via content negotiation (Accept: application\u002Fvnd.api+json;version=2)\n\n**TypeScript Example:**\n```ts\nenum ApiVersion {\n  V1 = '1.0',\n  V2 = '2.0'\n}\n\nfunction versionMiddleware(allowedVersions: ApiVersion[]) {\n  return (req: Request, res: Response, next: NextFunction) => {\n    const version = (req.headers['api-version'] as ApiVersion) || ApiVersion.V1;\n    if (!allowedVersions.includes(version)) {\n      res.status(400).json({ error: `Unsupported version. Allowed: ${allowedVersions.join(', ')}` });\n      return;\n    }\n    req.apiVersion = version;\n    next();\n  };\n}\n\napp.get('\u002Fusers', versionMiddleware([ApiVersion.V1, ApiVersion.V2]), (req, res) => {\n  if (req.apiVersion === ApiVersion.V2) {\n    \u002F\u002F v2 logic\n  } else {\n    \u002F\u002F v1 logic\n  }\n});\n```\n\n**Interview Tip:**\nEmphasize that REST APIs should be stateless, cacheable, and have a uniform interface. Versioning is crucial for long-lived APIs.\n\n**Common Follow-up:**\n\"How do you handle breaking changes without versioning?\" Use evolvable designs: add optional fields, never remove, use new endpoints for new resources, deprecation headers.\n\n**Real-world Example:**\nStripe API uses URL versioning (v1, v2). GitHub API uses custom header versioning (Accept: application\u002Fvnd.github.v3+json).\n\n**Advanced Notes:**\nHATEOAS (Hypermedia as Engine of Application State) includes links in responses. `Content-Type` negotiation can specify version via vendor MIME type. API Gateway (Kong, Zuul) can transparently route versions.",[123,229,230],"api-design","versioning",{"id":232,"category":225,"question":233,"answer":234,"level":145,"tags":235},30,"How do you implement request validation in Node.js? Compare Joi, Zod, and JSON Schema.","**Concept Explanation:**\nRequest validation ensures incoming data (body, query, params) meets expected shape, types, and constraints before processing. Libraries like Joi (schema object validation), Zod (TypeScript-first), and JSON Schema (standard) provide declarative validation with error messages.\n\n**Execution Flow:**\n1. Middleware extracts request data (body, query, params)\n2. Validates against schema\n3. If invalid, returns 400 with details\n4. If valid, attaches validated data to `req` and calls `next()`\n\n**Event Loop Explanation:**\nValidation is synchronous CPU work; for large payloads, consider async validation (e.g., database checks) but keep light.\n\n**Memory Behavior:**\nValidation creates temporary objects; schemas are compiled once.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Joi example\nimport Joi from 'joi';\n\nconst userSchema = Joi.object({\n  name: Joi.string().min(2).max(50).required(),\n  email: Joi.string().email().required(),\n  age: Joi.number().integer().min(0).max(150),\n  role: Joi.string().valid('admin', 'user').default('user')\n});\n\nfunction validateUser(req, res, next) {\n  const { error, value } = userSchema.validate(req.body, { abortEarly: false });\n  if (error) {\n    return res.status(400).json({ errors: error.details.map(d => d.message) });\n  }\n  req.validatedBody = value;\n  next();\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Zod example (TypeScript native)\nimport { z } from 'zod';\n\nconst UserSchema = z.object({\n  name: z.string().min(2).max(50),\n  email: z.string().email(),\n  age: z.number().int().min(0).max(150).optional(),\n  role: z.enum(['admin', 'user']).default('user')\n});\n\ntype User = z.infer\u003Ctypeof UserSchema>;\n\nfunction validate(req, res, next) {\n  try {\n    req.validated = UserSchema.parse(req.body);\n    next();\n  } catch (err) {\n    if (err instanceof z.ZodError) {\n      return res.status(400).json({ errors: err.errors });\n    }\n    next(err);\n  }\n}\n```\n\n**Practical Example:**\nExpress middleware with Zod and custom refinements:\n```js\nimport { z } from 'zod';\n\nconst createPostSchema = z.object({\n  title: z.string().min(5).max(100),\n  content: z.string().min(10).max(10000),\n  tags: z.array(z.string()).max(5).optional(),\n  publishDate: z.string().datetime().optional().refine(\n    (date) => !date || new Date(date) > new Date(),\n    { message: 'Publish date must be in the future' }\n  )\n});\n\nexport const validate = (schema) => (req, res, next) => {\n  const toValidate = { body: req.body, query: req.query, params: req.params };\n  const results = {};\n  try {\n    for (const [key, value] of Object.entries(toValidate)) {\n      if (schema[key]) {\n        results[key] = schema[key].parse(value);\n      }\n    }\n    req.validated = results;\n    next();\n  } catch (err) {\n    if (err instanceof z.ZodError) {\n      return res.status(400).json({ \n        error: 'Validation failed', \n        details: err.errors.map(e => ({ path: e.path.join('.'), message: e.message }))\n      });\n    }\n    next(err);\n  }\n};\n\n\u002F\u002F Usage\napp.post('\u002Fposts', \n  validate({ body: createPostSchema }), \n  (req, res) => {\n    \u002F\u002F req.validated.body is safe\n    createPost(req.validated.body);\n    res.status(201).end();\n  }\n);\n```\n\n**Common Mistakes:**\n- Aborting validation on first error (use `abortEarly: false` in Joi)\n- Not handling coercion (e.g., strings to numbers)\n- Validating only body but not query\u002Fparams\n- Exposing internal error details to client\n\n**Interview Follow-ups:**\n- Q: Why use a validation library instead of manual checks? A: Declarative, reusable, better error messages, TypeScript inference, performance\n- Q: How to validate query parameters like pagination? A: Same schema with `z.coerce.number()` for type coercion\n\n**Best Practices:**\n- Validate on all input sources (body, query, params, headers)\n- Use strict mode to reject unknown fields\n- Return structured error responses (e.g., JSON:API spec)\n- Cache compiled schemas (Zod does, Joi validates per call)\n\n**Performance Considerations:**\n- Joi can be slow for complex schemas; consider `joi-speed` or Zod\n- Zod performance is good for moderate schemas\n- JSON Schema with `ajv` is fastest (compiled to code)\n- Validate only what you need; skip validation for trusted internal calls\n\n**Production Recommendations:**\n- For TypeScript projects, Zod provides best type inference\n- For standard compliance, use JSON Schema + Ajv\n- For dynamic schemas, Joi has rich API\n- Always return 422 Unprocessable Entity for validation failures\n\n**Browser Behavior:**\nValidation can be mirrored on frontend (Zod works in browser, Joi doesn't).\n\n**Node.js Runtime Behavior:**\nAll libraries work synchronously. For async validation (e.g., check email uniqueness), integrate after sync validation.\n\n**Latest Node.js Patterns:**\n- `zod` 3.x with `superRefine` for complex rules\n- `typebox` for JSON Schema with TypeScript\n- `valibot` (new, modular)\n- Express 5 may include validation helpers\n\n**TypeScript Example:**\n```ts\nimport { z } from 'zod';\nimport { RequestHandler } from 'express';\n\nconst userIdParamSchema = z.object({\n  id: z.string().regex(\u002F^\\d+$\u002F).transform(Number)\n});\n\nconst paginationQuerySchema = z.object({\n  page: z.coerce.number().int().positive().default(1),\n  limit: z.coerce.number().int().min(1).max(100).default(20)\n});\n\nexport const validateParams = \u003CT extends z.ZodSchema>(schema: T): RequestHandler =>\n  (req, res, next) => {\n    try {\n      req.params = schema.parse(req.params);\n      next();\n    } catch (err) {\n      res.status(400).json({ error: err.errors });\n    }\n  };\n\n\u002F\u002F Usage with transformation\napp.get('\u002Fusers\u002F:id', validateParams(userIdParamSchema), (req, res) => {\n  \u002F\u002F req.params.id is now number, not string\n  getUserById(req.params.id);\n});\n```\n\n**Interview Tip:**\nRecommend Zod for TypeScript projects because of seamless type inference, reducing duplication between validation and types.\n\n**Common Follow-up:**\n\"How do you validate file uploads?\" Use multer for multipart, then validate file size, mime type, and use existing library for metadata.\n\n**Real-world Example:**\nDiscord API uses JSON Schema for validation. tRPC uses Zod for end-to-end type safety.\n\n**Advanced Notes:**\nJoi allows custom validation with `Joi.extend`. Zod has `.refine()` for custom logic. Ajv can compile schemas to functions for extreme performance (millions of validations\u002Fsec).",[236,237,238,64],"validation","joi","zod",{"id":240,"category":142,"question":241,"answer":242,"level":145,"tags":243},31,"Explain the timers and poll phases of the event loop in detail. How do setTimeout and setImmediate behave differently?","**Concept Explanation:**\nThe timers phase executes callbacks scheduled by `setTimeout()` and `setInterval()`. The poll phase is where the event loop retrieves new I\u002FO events and executes I\u002FO callbacks (except timers, check, close). Understanding their interaction explains ordering of async operations.\n\n**Execution Flow:**\n1. Timers phase: checks min-heap of timers, executes callbacks for expired timers\n2. Poll phase: if there are pending timers, loop calculates how long to block (next timer expiry)\n3. Poll phase blocks waiting for I\u002FO events up to that timeout\n4. After I\u002FO callbacks execute, check phase runs setImmediate callbacks\n\n**Event Loop Explanation:**\n- If timers are pending, poll phase does not block (zero timeout)\n- If no timers, poll phase blocks until first I\u002FO event\n- After poll phase completes, `setImmediate` callbacks run (check phase)\n- `setTimeout(fn,0)` vs `setImmediate()`: order depends on loop state when scheduled\n\n**Memory Behavior:**\nTimers use a min-heap; each timer has callback and timeout value.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Understanding timer+immediate order\nsetTimeout(() => console.log('timeout'), 0);\nsetImmediate(() => console.log('immediate'));\n\u002F\u002F Output order varies: sometimes immediate first, sometimes timeout first\n\u002F\u002F Reason: loop may already be in poll phase when scheduled\n\n\u002F\u002F To guarantee order: wrap in I\u002FO\nrequire('fs').readFile(__filename, () => {\n  setTimeout(() => console.log('timeout'), 0);\n  setImmediate(() => console.log('immediate'));\n  \u002F\u002F Always: immediate then timeout (because poll phase I\u002FO callbacks run before timers)\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Timer phases with blocking\nconst start = Date.now();\nsetTimeout(() => {\n  console.log(`Timer fired after ${Date.now() - start}ms`);\n}, 100);\n\n\u002F\u002F Poll phase blocking example\nconst fs = require('fs');\nfs.readFile('large-file.txt', () => {\n  \u002F\u002F This callback runs in poll phase\n  \u002F\u002F Loop will block here if no timers\n  let sum = 0;\n  for (let i = 0; i \u003C 1e9; i++) sum += i; \u002F\u002F Blocks poll phase\n  console.log('Done');\n});\n```\n\n**Practical Example:**\nMeasuring event loop lag (timer phase delay):\n```js\nlet last = Date.now();\nsetInterval(() => {\n  const now = Date.now();\n  const lag = now - last - 1000; \u002F\u002F Expected 1000ms interval\n  if (lag > 50) console.warn(`Event loop lag: ${lag}ms`);\n  last = now;\n}, 1000);\n```\n\n**Common Mistakes:**\n- Assuming `setTimeout(fn, 0)` runs immediately (it waits for timers phase)\n- Blocking poll phase with synchronous CPU work (delays all timers)\n- Setting too many timers (CPU overhead from heap management)\n\n**Interview Follow-ups:**\n- Q: How does `setTimeout(fn, 0)` differ from `setImmediate()`? A: setTimeout queues in timers phase, setImmediate in check phase; order depends on loop phase when called\n- Q: What happens if a timer callback itself schedules a timer? A: New timer is evaluated in next loop iteration\n\n**Best Practices:**\n- Use `setImmediate` for deferring work without minimum delay\n- Avoid setting many timers; use `setInterval` sparingly\n- For high-resolution timers, use `timers\u002Fpromises` or `setTimeout` with promise\n\n**Performance Considerations:**\n- Timer resolution is 1ms (due to system clock limitations)\n- Many active timers cause heap operations O(log n)\n- Use `timeout.unref()` to allow process exit if timer is only pending handle\n\n**Production Recommendations:**\n- Monitor event loop lag using `perf_hooks.monitorEventLoopDelay`\n- For real-time systems, keep timer callbacks under 10ms\n- Use `setTimeout` with `setInterval` via `setTimeout` recursion for dynamic intervals\n\n**Browser Behavior:**\nBrowser timers have minimum nesting delay (4ms after 5+ nestings). Node.js does not have this restriction.\n\n**Node.js Runtime Behavior:**\nTimer heap is managed by libuv. `timeout.ref()` and `unref()` control event loop lifetime.\n\n**Latest Node.js Patterns:**\n- `setTimeout` promises: `const { setTimeout } = require('timers\u002Fpromises'); await setTimeout(1000);`\n- `setImmediate` with `queueMicrotask` for microtask scheduling\n\n**TypeScript Example:**\n```ts\nimport { monitorEventLoopDelay } from 'node:perf_hooks';\n\nconst histogram = monitorEventLoopDelay({ resolution: 20 });\nhistogram.enable();\n\nsetInterval(() => {\n  const lag = histogram.percentile(99);\n  if (lag > 50) {\n    console.warn(`High event loop lag at 99th percentile: ${lag}ms`);\n  }\n}, 10000);\n```\n\n**Interview Tip:**\nDraw the loop phases on whiteboard showing timers → poll → check. Emphasize that poll phase blocking is what makes Node.js efficient for I\u002FO but can starve timers if misused.\n\n**Common Follow-up:**\n\"Can the poll phase block forever?\" No, it has a timeout computed from nearest timer expiry. If no timers, it blocks indefinitely until I\u002FO.\n\n**Real-world Example:**\nExpress.js servers rely on poll phase to handle incoming requests; if CPU-heavy work blocks poll phase, new requests are queued but not processed until phase completes.\n\n**Advanced Notes:**\nTimer heap is implemented in libuv as a binary min-heap. `uv__next_timeout` calculates poll timeout. `uv__run_timers` executes expired timers. Each timer callback runs on the main thread.",[14,244,245],"timers","poll-phase",{"id":247,"category":192,"question":248,"answer":249,"level":145,"tags":250},32,"What is dependency injection in Node.js? How does it help with testing and modularity?","**Concept Explanation:**\nDependency Injection (DI) is a design pattern where dependencies are provided to a module\u002Ffunction from the outside rather than created internally. This decouples component creation from usage, making code more testable, flexible, and maintainable.\n\n**Execution Flow:**\n1. Instead of `require` inside a module, dependencies are passed as parameters or via constructors\n2. In production, container or factory injects real dependencies (DB, services)\n3. In tests, mock\u002Fstub dependencies are injected\n4. Module uses the provided dependency without knowing its concrete implementation\n\n**Event Loop Explanation:**\nDI doesn't affect event loop directly but enables better structuring of async operations.\n\n**Memory Behavior:**\nDependencies are typically singletons (shared) or request-scoped. DI containers manage lifecycle.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Without DI (tight coupling)\nclass UserService {\n  constructor() {\n    this.db = require('.\u002Fdatabase'); \u002F\u002F Hard dependency\n  }\n  async getUser(id) {\n    return this.db.query('SELECT * FROM users WHERE id = ?', [id]);\n  }\n}\n\n\u002F\u002F With DI (decoupled)\nclass UserService {\n  constructor(db) {\n    this.db = db; \u002F\u002F Injected dependency\n  }\n  async getUser(id) {\n    return this.db.query('SELECT * FROM users WHERE id = ?', [id]);\n  }\n}\n\n\u002F\u002F Manual injection\nconst db = require('.\u002Fdatabase');\nconst userService = new UserService(db);\n\n\u002F\u002F Test injection\nconst mockDb = { query: async () => ({ id: 1, name: 'Test' }) };\nconst testService = new UserService(mockDb);\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Factory pattern for DI\nconst createUserService = (dependencies) => {\n  const { db, logger, cache } = dependencies;\n  return {\n    async getUser(id) {\n      logger.info(`Fetching user ${id}`);\n      const cached = await cache.get(`user:${id}`);\n      if (cached) return cached;\n      const user = await db.query('SELECT * FROM users WHERE id = ?', [id]);\n      await cache.set(`user:${id}`, user);\n      return user;\n    }\n  };\n};\n\n\u002F\u002F Usage\nconst userService = createUserService({\n  db: realDb,\n  logger: console,\n  cache: redisClient\n});\n\n\u002F\u002F DI container (simple)\nclass Container {\n  constructor() {\n    this.services = {};\n  }\n  register(name, definition) {\n    this.services[name] = definition;\n  }\n  get(name) {\n    const service = this.services[name];\n    if (typeof service === 'function') {\n      return service(this); \u002F\u002F Pass container for recursive resolution\n    }\n    return service;\n  }\n}\n\nconst container = new Container();\ncontainer.register('db', () => require('.\u002Fdatabase'));\ncontainer.register('userService', (c) => new UserService(c.get('db')));\n```\n\n**Practical Example:**\nExpress middleware with DI:\n```js\n\u002F\u002F app.js\nimport { createUserRouter } from '.\u002Fuser-router.js';\nimport { UserService } from '.\u002Fuser-service.js';\nimport { Database } from '.\u002Fdb.js';\n\nconst db = new Database(process.env.DB_URL);\nconst userService = new UserService({ db, logger: console });\nconst userRouter = createUserRouter({ userService });\n\napp.use('\u002Fusers', userRouter);\n\n\u002F\u002F user-router.js\nexport const createUserRouter = ({ userService }) => {\n  const router = express.Router();\n  router.get('\u002F:id', async (req, res) => {\n    const user = await userService.getUser(req.params.id);\n    res.json(user);\n  });\n  return router;\n};\n\n\u002F\u002F test.js\nconst mockUserService = { getUser: async () => ({ id: 1, name: 'Mock' }) };\nconst router = createUserRouter({ userService: mockUserService });\n\u002F\u002F test router with supertest\n```\n\n**Common Mistakes:**\n- Over-engineering DI for simple apps (unnecessary complexity)\n- Using DI containers that hide dependency graph (magic resolution)\n- Circular dependencies in DI graph\n- Mixing constructor injection with internal `require` (partial DI)\n\n**Interview Follow-ups:**\n- Q: What are advantages of DI over global `require`? A: Testability, explicit dependencies, easier refactoring, control over scope\n- Q: How does DI help with mocking? A: Inject mock implementations without modifying production code\n\n**Best Practices:**\n- Prefer constructor injection for required dependencies\n- Use factory functions for complex creation logic\n- Keep DI container simple; avoid service locator anti-pattern\n- Use `async` factories for dependencies that need async initialization\n\n**Performance Considerations:**\n- DI adds minimal overhead (function call to resolve)\n- Inline `require` is cached, so performance difference negligible\n- DI containers may add reflection overhead; use simple factories for performance-critical paths\n\n**Production Recommendations:**\n- Use DI for services with external dependencies (DB, APIs, caches)\n- Avoid DI for utility functions (pure functions)\n- Consider Awilix (Node DI library) for complex apps\n- For small\u002Fmedium apps, manual injection is sufficient\n\n**Browser Behavior:**\nDI patterns apply similarly in frontend frameworks (Angular DI, React context).\n\n**Node.js Runtime Behavior:**\nModule caching means `require` is effectively a singleton; DI provides alternative scoping.\n\n**Latest Node.js Patterns:**\n- Using ES modules with dynamic `import()` for lazy DI\n- `AsyncLocalStorage` for request-scoped DI in web frameworks\n- TypeScript decorators for DI (experimental)\n\n**TypeScript Example:**\n```ts\ninterface Logger {\n  info(msg: string): void;\n  error(msg: string): void;\n}\n\ninterface Database {\n  query(sql: string, params: any[]): Promise\u003Cany[]>;\n}\n\nclass UserService {\n  constructor(\n    private db: Database,\n    private logger: Logger\n  ) {}\n  \n  async getUser(id: number) {\n    this.logger.info(`Fetching user ${id}`);\n    const rows = await this.db.query('SELECT * FROM users WHERE id = ?', [id]);\n    return rows[0];\n  }\n}\n\n\u002F\u002F DI container with typed tokens\nclass TypedContainer {\n  private services = new Map();\n  \n  register\u003CT>(token: string, factory: (c: TypedContainer) => T): void {\n    this.services.set(token, factory);\n  }\n  \n  resolve\u003CT>(token: string): T {\n    const factory = this.services.get(token);\n    if (!factory) throw new Error(`No registration for ${token}`);\n    return factory(this);\n  }\n}\n\nconst container = new TypedContainer();\ncontainer.register('db', () => new RealDatabase());\ncontainer.register('logger', () => console);\ncontainer.register('userService', (c) => new UserService(c.resolve('db'), c.resolve('logger')));\n\nconst userService = container.resolve\u003CUserService>('userService');\n```\n\n**Interview Tip:**\nExplain that DI is about inverting control: instead of a module deciding its dependencies, the caller provides them. This aligns with SOLID principles.\n\n**Common Follow-up:**\n\"What's the difference between DI and service locator?\" DI passes dependencies explicitly; service locator hides them behind a global registry, making dependencies implicit.\n\n**Real-world Example:**\nNestJS uses a full-featured DI container with decorators. Express apps often use manual DI in route factories for testability.\n\n**Advanced Notes:**\n`Awilix` provides resolution modes (singleton, scoped, transient). DI can be combined with `proxy` for lazy initialization. Inversion of Control containers can automatically resolve constructor parameter types using reflection (`Reflect.getMetadata`).",[251,252,13],"dependency-injection","testing",{"id":254,"category":255,"question":256,"answer":257,"level":145,"tags":258},33,"Observability","How do you implement structured logging in Node.js? Compare Winston and Pino.","**Concept Explanation:**\nStructured logging outputs logs as machine-readable JSON (or key-value pairs) instead of plain text. This enables searching, filtering, and alerting on log aggregation systems (ELK, Datadog, Loki). Winston (flexible, feature-rich) and Pino (fast, low overhead) are popular Node.js logging libraries.\n\n**Execution Flow:**\n1. Application calls logger.info('message', { context })\n2. Logger formats message as JSON with timestamp, level, and additional fields\n3. Output goes to stdout\u002Fstderr, files, or network\n4. Log aggregator ingests, indexes, and makes searchable\n\n**Event Loop Explanation:**\nLogging is typically non-blocking (asynchronous) to avoid slowing down the app. Pino is designed for minimal overhead; Winston can be synchronous or async.\n\n**Memory Behavior:**\nLogging large objects can generate large strings and memory pressure. Use `child` loggers to avoid re-serializing common fields.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Pino (fast, minimal)\nimport pino from 'pino';\n\nconst logger = pino({\n  level: process.env.LOG_LEVEL || 'info',\n  formatters: {\n    level: (label) => ({ level: label }),\n  },\n  timestamp: pino.stdTimeFunctions.isoTime,\n});\n\nlogger.info({ userId: 123 }, 'User logged in');\nlogger.error({ err }, 'Database connection failed');\n\n\u002F\u002F Winston (flexible)\nimport winston from 'winston';\n\nconst logger = winston.createLogger({\n  level: 'info',\n  format: winston.format.json(),\n  transports: [\n    new winston.transports.Console(),\n    new winston.transports.File({ filename: 'error.log', level: 'error' }),\n  ],\n});\n\nlogger.info('User logged in', { userId: 123 });\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Pino child loggers (adds fixed fields)\nconst child = logger.child({ service: 'auth' });\nchild.info('Auth attempt'); \u002F\u002F includes { service: 'auth' }\n\n\u002F\u002F Winston with custom format\nconst logger = winston.createLogger({\n  format: winston.format.combine(\n    winston.format.timestamp(),\n    winston.format.errors({ stack: true }),\n    winston.format.json()\n  ),\n  transports: [new winston.transports.Console()]\n});\n\n\u002F\u002F Redaction (Pino)\nconst logger = pino({\n  redact: ['password', '*.token', 'user.email']\n});\nlogger.info({ user: { email: 'test@example.com', password: 'secret' } });\n\u002F\u002F password and email redacted\n```\n\n**Practical Example:**\nExpress middleware with request ID logging:\n```js\nimport pino from 'pino';\nimport { randomUUID } from 'node:crypto';\n\nconst logger = pino();\n\napp.use((req, res, next) => {\n  req.id = randomUUID();\n  req.logger = logger.child({ requestId: req.id, method: req.method, url: req.url });\n  req.logger.info('Request started');\n  \n  const start = Date.now();\n  res.on('finish', () => {\n    req.logger.info({ status: res.statusCode, duration: Date.now() - start }, 'Request completed');\n  });\n  next();\n});\n\napp.get('\u002Fusers', async (req, res) => {\n  req.logger.info({ userId: req.query.id }, 'Fetching user');\n  \u002F\u002F ...\n});\n```\n\n**Common Mistakes:**\n- Logging sensitive data (passwords, tokens) without redaction\n- Using synchronous logging in high-throughput apps (blocks event loop)\n- Logging large objects (e.g., entire request body) causing memory issues\n- Not setting appropriate log level in production (debug level fills disk)\n\n**Interview Follow-ups:**\n- Q: Why is JSON logging better than plain text? A: Structured querying, automatic indexing, machine-readable for alerting\n- Q: When to use Pino vs Winston? A: Pino for performance-critical; Winston for complex transports (multiple destinations, file rotation)\n\n**Best Practices:**\n- Log at appropriate levels: error, warn, info, debug, trace\n- Include request ID for tracing across microservices\n- Log in JSON format; never log multi-line strings\n- Use `logger.child()` for request-scoped fields\n- Always log errors with stack trace\n\n**Performance Considerations:**\n- Pino benchmarks ~5x faster than Winston (due to extreme JSON serialization optimization)\n- Pino uses `sonic-boy` for fast output, Winston uses `readable-stream`\n- Async logging reduces overhead; use `pino.destination()` for file logging\n\n**Production Recommendations:**\n- Use Pino for high-throughput APIs (thousands of req\u002Fs)\n- Use Winston for complex logging pipelines (multiple transports, rotating files)\n- Send logs to stdout\u002Fstderr; let container\u002Fprocess manager handle aggregation\n- Set `NODE_ENV=production` to disable pretty printing\n\n**Browser Behavior:**\nNot applicable; use browser DevTools or `console`.\n\n**Node.js Runtime Behavior:**\nBoth libraries handle async logging. `pino.destination` uses file descriptors; sync=false by default.\n\n**Latest Node.js Patterns:**\n- `pino-pretty` for development human-readable output\n- Winston 3.x with `winston.transport` custom transports\n- OpenTelemetry integration for distributed tracing correlation\n\n**TypeScript Example:**\n```ts\nimport pino from 'pino';\n\ninterface LogContext {\n  requestId?: string;\n  userId?: number;\n  [key: string]: unknown;\n}\n\nclass AppLogger {\n  private logger: pino.Logger;\n  \n  constructor(serviceName: string) {\n    this.logger = pino({\n      name: serviceName,\n      level: process.env.LOG_LEVEL || 'info',\n      base: { env: process.env.NODE_ENV }\n    });\n  }\n  \n  child(context: LogContext) {\n    return new AppLogger(this.logger.child(context));\n  }\n  \n  info(msg: string, context?: LogContext) {\n    if (context) this.logger.info(context, msg);\n    else this.logger.info(msg);\n  }\n  \n  error(err: Error, msg?: string) {\n    this.logger.error({ err }, msg || err.message);\n  }\n}\n```\n\n**Interview Tip:**\nMention that structured logging is essential for microservices observability; correlate logs with request IDs and trace IDs from OpenTelemetry.\n\n**Common Follow-up:**\n\"How do you rotate log files in production?\" Use built-in `pino-roll` or Winston file rotation; better to let Docker\u002Fcontainer logs handle rotation and use aggregators.\n\n**Real-world Example:**\nUber uses Pino for Node.js services because of low overhead and JSON output. Express Gateway uses Winston for its configurable transports.\n\n**Advanced Notes:**\nPino uses `sonic-boy` for asynchronous output writing; it serializes objects incrementally. Winston supports `stream` for custom transports (e.g., to Elasticsearch). Both support redaction of sensitive fields.",[259,260,261,262],"logging","observability","pino","winston",{"id":264,"category":265,"question":266,"answer":267,"level":145,"tags":268},34,"Security","How do you implement rate limiting in Node.js? What are different strategies (in-memory, Redis, sliding window)?","**Concept Explanation:**\nRate limiting restricts the number of requests a client can make within a time window to prevent abuse, brute force attacks, and resource exhaustion. Strategies include in-memory (simple, not scalable), Redis (distributed, production-ready), and sliding window (more accurate).\n\n**Execution Flow:**\n1. Middleware extracts client identifier (IP, API key, user ID)\n2. Checks current request count from store\n3. If limit exceeded, returns 429 Too Many Requests\n4. Otherwise increments counter, sets expiry, passes request\n\n**Event Loop Explanation:**\nRate limiting adds storage I\u002FO; Redis operations are async, non-blocking.\n\n**Memory Behavior:**\nIn-memory stores keep counters in process memory; not suitable for multi-process\u002Fcluster. Redis stores outside Node.js.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F In-memory (single process, not for production cluster)\nimport rateLimit from 'express-rate-limit';\n\nconst limiter = rateLimit({\n  windowMs: 60 * 1000, \u002F\u002F 1 minute\n  max: 100, \u002F\u002F limit each IP to 100 requests per window\n  message: 'Too many requests, please try again later.',\n  standardHeaders: true, \u002F\u002F Return rate limit info in `RateLimit-*` headers\n  legacyHeaders: false,\n});\n\napp.use('\u002Fapi', limiter);\n\n\u002F\u002F Redis-based (distributed)\nimport RedisStore from 'rate-limit-redis';\nimport Redis from 'ioredis';\n\nconst redisClient = new Redis(process.env.REDIS_URL);\n\nconst distributedLimiter = rateLimit({\n  store: new RedisStore({\n    sendCommand: (...args) => redisClient.call(...args),\n  }),\n  windowMs: 60 * 1000,\n  max: 100,\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Custom sliding window algorithm (pseudo)\nasync function slidingWindowLimit(key, limit, windowSec) {\n  const now = Date.now();\n  const windowStart = now - (windowSec * 1000);\n  \n  \u002F\u002F Remove old entries\n  await redis.zremrangebyscore(key, 0, windowStart);\n  const count = await redis.zcard(key);\n  \n  if (count >= limit) return false;\n  \n  await redis.zadd(key, now, `${now}:${Math.random()}`);\n  await redis.expire(key, windowSec);\n  return true;\n}\n\n\u002F\u002F Per-endpoint limiters\nconst strictLimiter = rateLimit({ windowMs: 60 * 1000, max: 10 });\nconst looseLimiter = rateLimit({ windowMs: 60 * 1000, max: 1000 });\n\napp.post('\u002Flogin', strictLimiter, handleLogin); \u002F\u002F Brute force protection\napp.get('\u002Fpublic', looseLimiter, handlePublic);\n```\n\n**Practical Example:**\nCustom rate limiter with key by user ID + IP:\n```js\nimport rateLimit from 'express-rate-limit';\nimport RedisStore from 'rate-limit-redis';\n\nconst keyGenerator = (req) => {\n  const userId = req.user?.id || 'anonymous';\n  const ip = req.ip;\n  return `${userId}:${ip}`;\n};\n\nconst limiter = rateLimit({\n  store: new RedisStore({ client: redisClient }),\n  windowMs: 15 * 60 * 1000, \u002F\u002F 15 minutes\n  max: 100,\n  keyGenerator,\n  skip: (req) => req.user?.role === 'admin', \u002F\u002F Skip for admins\n  handler: (req, res) => {\n    res.status(429).json({ error: 'Rate limit exceeded. Retry after ' + req.rateLimit.resetTime });\n  }\n});\n\napp.use('\u002Fapi', limiter);\n```\n\n**Common Mistakes:**\n- Using in-memory store when running multiple Node.js processes (counts per process, not global)\n- Not handling Redis connection failures (fail open vs fail closed)\n- Rate limiting by IP only (IPv6, proxies, NAT issues → use combined keys)\n- Too low limit causing false positives; too high limit ineffective\n\n**Interview Follow-ups:**\n- Q: Difference between fixed window and sliding window? A: Fixed window resets at interval boundaries (bursts allowed at edges). Sliding window smooths by considering rolling time window.\n- Q: How to handle rate limiting behind a reverse proxy? A: Trust proxy IP via `app.set('trust proxy', 1)` and use `req.ip` correctly.\n\n**Best Practices:**\n- Set different limits for different endpoints (login stricter than search)\n- Return standard `RateLimit-*` headers for client backoff\n- Use Redis for distributed systems (cluster, multiple servers)\n- Exempt health check endpoints from rate limiting\n\n**Performance Considerations:**\n- In-memory fastest, not scalable\n- Redis adds network round-trip (1-2ms), acceptable for most APIs\n- Batch operations (Lua scripts) reduce round trips for sliding window\n\n**Production Recommendations:**\n- Use `express-rate-limit` with RedisStore for production\n- Implement global rate limiting at API gateway or load balancer (Nginx, CloudFlare)\n- Monitor rate limit hits to detect abuse patterns\n- Consider using `rate-limit-flexible` for advanced strategies\n\n**Browser Behavior:**\nBrowsers respect `Retry-After` header and will automatically delay retries.\n\n**Node.js Runtime Behavior:**\n`express-rate-limit` uses `setTimeout` to reset windows; memory store uses `Map`. Redis store uses `INCR` + `EXPIRE`.\n\n**Latest Node.js Patterns:**\n- `rate-limit-redis` v3+ with ioredis support\n- `@upstash\u002Fratelimit` for serverless (Edge, Vercel)\n- Token bucket algorithm via `bottleneck` library\n\n**TypeScript Example:**\n```ts\nimport rateLimit, { Options } from 'express-rate-limit';\nimport RedisStore from 'rate-limit-redis';\nimport Redis from 'ioredis';\n\nconst redis = new Redis(process.env.REDIS_URL!);\n\nconst createRateLimiter = (max: number, windowMs: number): rateLimit.RateLimitRequestHandler => {\n  return rateLimit({\n    store: new RedisStore({\n      client: redis,\n      prefix: 'rl:',\n    }),\n    windowMs,\n    max,\n    standardHeaders: true,\n    legacyHeaders: false,\n    skipSuccessfulRequests: false, \u002F\u002F Count successful requests too\n    keyGenerator: (req) => {\n      return req.user?.id || req.ip || 'unknown';\n    }\n  } as Options);\n};\n\napp.use('\u002Fapi', createRateLimiter(100, 60 * 1000));\n```\n\n**Interview Tip:**\nExplain that rate limiting is a critical part of API security; you must consider distributed deployments. Redis is the standard solution.\n\n**Common Follow-up:**\n\"How do you handle rate limiting for authenticated vs unauthenticated users?\" Different limits: authenticated users higher (e.g., 1000\u002Fhour), unauthenticated lower (100\u002Fhour).\n\n**Real-world Example:**\nGitHub API uses rate limiting with token-based quotas (5000 req\u002Fh for authenticated, 60 for unauthenticated). Twitter API uses per-endpoint sliding windows.\n\n**Advanced Notes:**\nToken bucket algorithm allows bursts while maintaining average rate. Sliding window logs (storing timestamps) more accurate but heavier. Redis Lua scripts implement sliding window atomically.",[269,189,270],"rate-limiting","redis",{"id":272,"category":265,"question":273,"answer":274,"level":145,"tags":275},35,"How do you handle file uploads securely in Node.js? What are common pitfalls?","**Concept Explanation:**\nFile uploads require handling multipart\u002Fform-data, validating file types, limiting size, sanitizing filenames, and storing securely. Common libraries: `multer` (Express middleware), `busboy` (raw), `formidable`. Pitfalls include path traversal, denial-of-service, and malicious file execution.\n\n**Execution Flow:**\n1. Client sends multipart request with file(s)\n2. Express middleware parses stream, writes to disk or memory\n3. Validate file size, mime type, extension\n4. Sanitize filename (remove `..\u002F`, replace spaces, generate random name)\n5. Store file outside public webroot or with random name\n6. Return file identifier\u002Flocation to client\n\n**Event Loop Explanation:**\nFile parsing and writing use non-blocking I\u002FO. Large files stream to disk without blocking event loop.\n\n**Memory Behavior:**\nMemory storage (`multer.memoryStorage()`) keeps file in RAM; disk storage streams to disk. Set size limits to prevent OOM.\n\n**Lifecycle Explanation:**\n```js\nimport multer from 'multer';\nimport path from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\n\u002F\u002F Configure storage\nconst storage = multer.diskStorage({\n  destination: (req, file, cb) => {\n    cb(null, 'uploads\u002F');\n  },\n  filename: (req, file, cb) => {\n    const ext = path.extname(file.originalname);\n    const randomName = randomBytes(16).toString('hex') + ext;\n    cb(null, randomName);\n  }\n});\n\nconst upload = multer({\n  storage,\n  limits: { fileSize: 5 * 1024 * 1024 }, \u002F\u002F 5MB\n  fileFilter: (req, file, cb) => {\n    const allowedMimes = ['image\u002Fjpeg', 'image\u002Fpng', 'image\u002Fwebp'];\n    if (allowedMimes.includes(file.mimetype)) {\n      cb(null, true);\n    } else {\n      cb(new Error('Invalid file type'));\n    }\n  }\n});\n\napp.post('\u002Fupload', upload.single('avatar'), (req, res) => {\n  res.json({ file: req.file });\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Multiple files\napp.post('\u002Fuploads', upload.array('photos', 10), (req, res) => {\n  \u002F\u002F req.files is array of uploaded files\n});\n\n\u002F\u002F Mixed fields\napp.post('\u002Fprofile', \n  upload.fields([\n    { name: 'avatar', maxCount: 1 },\n    { name: 'gallery', maxCount: 8 }\n  ]),\n  (req, res) => {\n    \u002F\u002F req.files.avatar, req.files.gallery\n  }\n);\n\n\u002F\u002F Memory storage (for processing before saving)\nconst memoryUpload = multer({ \n  storage: multer.memoryStorage(),\n  limits: { fileSize: 10 * 1024 * 1024 }\n});\n\napp.post('\u002Fprocess', memoryUpload.single('file'), async (req, res) => {\n  const buffer = req.file.buffer;\n  const processed = await sharp(buffer).resize(300).toBuffer();\n  await fs.writeFile('output.jpg', processed);\n  res.end();\n});\n```\n\n**Practical Example:**\nSecure image upload with validation and virus scanning:\n```js\nimport multer from 'multer';\nimport { lookup } from 'mime-types';\nimport fileType from 'file-type';\n\nconst upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 5e6 } });\n\napp.post('\u002Fupload', upload.single('image'), async (req, res) => {\n  try {\n    \u002F\u002F 1. Validate magic bytes (file-type)\n    const type = await fileType.fromBuffer(req.file.buffer);\n    if (!type || !type.mime.startsWith('image\u002F')) {\n      return res.status(400).json({ error: 'Invalid file content' });\n    }\n    \n    \u002F\u002F 2. Verify extension matches content\n    const ext = path.extname(req.file.originalname).slice(1);\n    if (lookup(ext) !== type.mime) {\n      return res.status(400).json({ error: 'Extension mismatch' });\n    }\n    \n    \u002F\u002F 3. Sanitize filename (no path traversal)\n    const safeName = randomBytes(16).toString('hex') + '.' + type.ext;\n    \n    \u002F\u002F 4. Scan with ClamAV (optional)\n    \u002F\u002F const isClean = await clamav.scanBuffer(req.file.buffer);\n    \u002F\u002F if (!isClean) throw new Error('Virus detected');\n    \n    \u002F\u002F 5. Save and serve via separate endpoint (not directly from \u002Fuploads)\n    await fs.writeFile(`.\u002Fstorage\u002F${safeName}`, req.file.buffer);\n    \n    \u002F\u002F 6. Return tokenized URL (not actual path)\n    res.json({ fileId: safeName, url: `\u002Ffiles\u002F${safeName}` });\n  } catch (err) {\n    res.status(500).json({ error: err.message });\n  }\n});\n```\n\n**Common Mistakes:**\n- Using client-provided filename directly (path traversal: `..\u002F..\u002F..\u002Fetc\u002Fpasswd`)\n- Storing files in public webroot with original names (overwrite risk)\n- Not limiting file count (DoS via many small files)\n- Accepting `multipart\u002Fform-data` without CSRF protection\n- Not scanning uploaded files for malware\u002Fviruses\n\n**Interview Follow-ups:**\n- Q: How do you prevent directory traversal attacks? A: Sanitize filename: remove `..\u002F`, `.\u002F`, `..\\`, use `path.basename`, generate random names\n- Q: What is `multer`'s memory vs disk storage trade-off? A: Memory faster for small files, risk of OOM; disk suitable for large files, slower\n\n**Best Practices:**\n- Generate random filenames; never trust user input\n- Store files outside static webroot; serve via authenticated endpoint\n- Validate both extension AND magic bytes (mime type can be spoofed)\n- Set reasonable limits: file size, total files, field size\n- Use streaming to disk for >1MB files to avoid memory pressure\n\n**Performance Considerations:**\n- `multer` with disk storage streams to disk efficiently\n- Memory storage blocks event loop while parsing large files? No, but buffers in RAM\n- For high concurrency, use `busboy` directly for lower overhead\n- Use CDN for file delivery, not Node.js\n\n**Production Recommendations:**\n- Use `multer` with disk storage and async error handling\n- Integrate virus scanning (ClamAV) for user-generated content\n- Implement upload rate limiting per IP\n- Use `express-rate-limit` on upload endpoints\n- Store file metadata in database; files on S3 or cloud storage\n\n**Browser Behavior:**\nBrowser sends `multipart\u002Fform-data`; JavaScript can upload via `FormData` and `fetch`.\n\n**Node.js Runtime Behavior:**\n`multer` uses `busboy` under the hood. File parsing is streaming, efficient for large files.\n\n**Latest Node.js Patterns:**\n- `multer` with `sharp` for on-the-fly image processing\n- `express-rate-limit` on upload endpoints\n- Cloud storage SDKs (AWS S3, Google Cloud Storage) for direct uploads\n\n**TypeScript Example:**\n```ts\nimport multer, { FileFilterCallback } from 'multer';\nimport { Request } from 'express';\n\ntype DestinationCallback = (error: Error | null, destination: string) => void;\ntype FileNameCallback = (error: Error | null, filename: string) => void;\n\nconst storage = multer.diskStorage({\n  destination: (req: Request, file: Express.Multer.File, cb: DestinationCallback) => {\n    cb(null, process.env.UPLOAD_DIR || '.\u002Fuploads');\n  },\n  filename: (req: Request, file: Express.Multer.File, cb: FileNameCallback) => {\n    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);\n    cb(null, uniqueSuffix + path.extname(file.originalname));\n  }\n});\n\nconst fileFilter = (req: Request, file: Express.Multer.File, cb: FileFilterCallback) => {\n  const allowed = ['image\u002Fjpeg', 'image\u002Fpng'];\n  if (allowed.includes(file.mimetype)) {\n    cb(null, true);\n  } else {\n    cb(new Error('Invalid file type'));\n  }\n};\n\nexport const upload = multer({ storage, fileFilter, limits: { fileSize: 5 * 1024 * 1024 } });\n```\n\n**Interview Tip:**\nEmphasize defense in depth: validate extension, validate magic bytes, sanitize filename, store outside webroot, serve via controlled endpoint.\n\n**Common Follow-up:**\n\"How do you handle very large file uploads (GBs)?\" Use streaming to disk with `multer` (diskStorage), or direct-to-cloud signed URLs to avoid server buffering.\n\n**Real-world Example:**\nCloudinary uses similar approach: client uploads directly to S3, Node.js validates metadata after upload. Slack uses `busboy` for file uploads with virus scanning.\n\n**Advanced Notes:**\n`multer` errors: `LIMIT_FILE_SIZE`, `LIMIT_FILE_COUNT`, `LIMIT_UNEXPECTED_FILE`. Use `app.use((err, req, res, next) => { if (err instanceof multer.MulterError) {...} })`. For progress tracking, use `busboy` directly with `on('field')`, `on('file')` events.",[276,277,189],"file-uploads","multer",{"id":279,"category":225,"question":280,"answer":281,"level":145,"tags":282},36,"How do you implement WebSockets in Node.js? Compare Socket.io vs ws library.","**Concept Explanation:**\nWebSockets provide full-duplex, persistent connections between client and server for real-time communication. `ws` is a minimal WebSocket implementation (RFC 6455). Socket.io adds reliability features (fallbacks, auto-reconnection, rooms, namespaces) but requires its client library.\n\n**Execution Flow:**\n1. HTTP server upgrades connection to WebSocket via `Upgrade` header\n2. Handshake completes; persistent TCP connection open\n3. Both sides can send messages (text\u002Fbinary) asynchronously\n4. Connection stays open until closed by either side\n\n**Event Loop Explanation:**\nWebSocket messages are emitted as events (`message`). The event loop handles I\u002FO; each message callback runs on the main thread.\n\n**Memory Behavior:**\nEach connection maintains a socket object and message buffers. Backpressure applies if consumer slower than sender.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F ws library (simple)\nimport { WebSocketServer } from 'ws';\nimport http from 'http';\n\nconst server = http.createServer();\nconst wss = new WebSocketServer({ server });\n\nwss.on('connection', (ws) => {\n  console.log('Client connected');\n  \n  ws.on('message', (data) => {\n    console.log('Received:', data.toString());\n    ws.send(`Echo: ${data}`);\n  });\n  \n  ws.on('close', () => console.log('Client disconnected'));\n});\n\nserver.listen(8080);\n\n\u002F\u002F Client-side (browser)\nconst ws = new WebSocket('ws:\u002F\u002Flocalhost:8080');\nws.onopen = () => ws.send('Hello');\nws.onmessage = (e) => console.log(e.data);\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Socket.io (higher-level)\nimport { Server } from 'socket.io';\nimport http from 'http';\n\nconst server = http.createServer();\nconst io = new Server(server, { cors: { origin: '*' } });\n\nio.on('connection', (socket) => {\n  console.log('User connected:', socket.id);\n  \n  \u002F\u002F Rooms\n  socket.join('room1');\n  io.to('room1').emit('message', 'Hello room');\n  \n  \u002F\u002F Custom events\n  socket.on('chat message', (msg) => {\n    io.emit('chat message', msg); \u002F\u002F Broadcast to all\n  });\n  \n  \u002F\u002F Acknowledgements\n  socket.on('ping', (cb) => {\n    if (typeof cb === 'function') cb('pong');\n  });\n});\n\nserver.listen(3000);\n```\n\n**Practical Example:**\nReal-time chat with rooms using ws:\n```js\n\u002F\u002F ws with rooms implementation\nimport { WebSocketServer } from 'ws';\n\nconst wss = new WebSocketServer({ port: 8080 });\nconst rooms = new Map(); \u002F\u002F roomName -> Set of ws\n\nwss.on('connection', (ws) => {\n  let currentRoom = null;\n  \n  ws.on('message', (data) => {\n    const { type, payload } = JSON.parse(data);\n    \n    if (type === 'join') {\n      if (currentRoom) rooms.get(currentRoom)?.delete(ws);\n      currentRoom = payload.room;\n      if (!rooms.has(currentRoom)) rooms.set(currentRoom, new Set());\n      rooms.get(currentRoom).add(ws);\n    } else if (type === 'message') {\n      if (currentRoom) {\n        const roomClients = rooms.get(currentRoom);\n        roomClients?.forEach(client => {\n          if (client !== ws && client.readyState === WebSocket.OPEN) {\n            client.send(JSON.stringify({ user: payload.user, text: payload.text }));\n          }\n        });\n      }\n    }\n  });\n  \n  ws.on('close', () => {\n    if (currentRoom) rooms.get(currentRoom)?.delete(ws);\n  });\n});\n```\n\n**Common Mistakes:**\n- Not handling `close` and `error` events (memory leaks, crashes)\n- Using `ws` without scaling (single-process, not sticky sessions)\n- Broadcasting to all clients causing O(n) message processing\n- Not validating incoming messages (security)\n\n**Interview Follow-ups:**\n- Q: When to use Socket.io vs ws? A: `ws` for minimal overhead, custom control; Socket.io for production apps needing fallbacks, rooms, auto-reconnect\n- Q: How to scale WebSockets horizontally? A: Use sticky sessions (same server for same client) or pub\u002Fsub (Redis) to broadcast across servers\n\n**Best Practices:**\n- Implement heartbeat (ping\u002Fpong) to detect dead connections\n- Validate and sanitize incoming messages\n- Use binary formats (MessagePack, protobuf) for efficiency\n- Limit message size and rate per connection\n- Close idle connections after timeout\n\n**Performance Considerations:**\n- `ws` handles ~10x more connections than Socket.io (lower overhead)\n- Each WebSocket consumes ~5-10KB memory idle\n- Broadcasting to many rooms: O(number of clients); use pub\u002Fsub for large rooms\n- Use `WebSocketServer({ perMessageDeflate: false })` to disable compression if not needed\n\n**Production Recommendations:**\n- Use `ws` for high-performance low-level needs (gaming, trading)\n- Use Socket.io for ease of use, automatic reconnection\n- Deploy behind reverse proxy (Nginx) with `proxy_set_header Upgrade`\n- Use Redis adapter for Socket.io multi-server: `io.adapter(redisAdapter)`\n\n**Browser Behavior:**\nNative WebSocket API available in all modern browsers. Socket.io client provides fallbacks to long-polling.\n\n**Node.js Runtime Behavior:**\n`ws` uses `stream` module; `Socket.io` depends on `engine.io` for transport.\n\n**Latest Node.js Patterns:**\n- `uWebSockets.js` (ultra-fast) alternative\n- `ws` with WebStreams API\n- `socket.io` v4 with namespace rooms\n\n**TypeScript Example:**\n```ts\nimport { WebSocket, WebSocketServer } from 'ws';\nimport { IncomingMessage } from 'http';\n\ninterface WebSocketWithId extends WebSocket {\n  id: string;\n}\n\nconst wss = new WebSocketServer({ port: 8080 });\n\nwss.on('connection', (ws: WebSocketWithId, req: IncomingMessage) => {\n  ws.id = Math.random().toString(36).slice(2);\n  \n  ws.on('message', (data: Buffer) => {\n    try {\n      const parsed = JSON.parse(data.toString());\n      \u002F\u002F Handle message\n    } catch (err) {\n      ws.send(JSON.stringify({ error: 'Invalid JSON' }));\n    }\n  });\n  \n  ws.on('error', (err) => console.error(`WebSocket error: ${err}`));\n});\n```\n\n**Interview Tip:**\nExplain that WebSockets are not HTTP, but start as HTTP upgrade. Socket.io adds reliability, but for high-scale, `ws` with custom pub\u002Fsub is better.\n\n**Common Follow-up:**\n\"How do you test WebSockets in Node.js?\" Use `ws` library to create test clients; `socket.io-client` for Socket.io testing.\n\n**Real-world Example:**\nSlack uses WebSockets for real-time messaging. Trading platforms (Binance, Coinbase) use `ws` for market data feeds.\n\n**Advanced Notes:**\nWebSocket frame format: FIN, opcode, mask, payload length, masking key, payload. `ws` implements permessage-deflate compression. Socket.io protocol includes heartbeat, handshake, and binary encoding.",[283,284,285],"websockets","socketio","realtime",{"id":287,"category":288,"question":289,"answer":290,"level":145,"tags":291},37,"Databases","How do you integrate databases in Node.js? Compare connection pooling, ORMs, and query builders.","**Concept Explanation:**\nDatabase integration involves connecting, executing queries, and managing connections. Connection pooling reuses connections to reduce overhead. ORMs (Object Relational Mappers) map database tables to JavaScript objects. Query builders provide programmatic SQL construction without full ORM overhead.\n\n**Execution Flow:**\n1. App initializes pool with max connections\n2. On request, acquires connection from pool\n3. Executes query (prepared statement)\n4. Releases connection back to pool\n5. Pool handles connection lifecycle (keep-alive, reconnection)\n\n**Event Loop Explanation:**\nDatabase drivers use non-blocking I\u002FO (network). Pool management adds async operations.\n\n**Memory Behavior:**\nEach pooled connection holds socket and driver state. Limit pool size to avoid memory exhaustion.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Raw driver with pool (pg for PostgreSQL)\nimport pkg from 'pg';\nconst { Pool } = pkg;\n\nconst pool = new Pool({\n  host: 'localhost',\n  port: 5432,\n  user: 'app',\n  password: 'secret',\n  database: 'mydb',\n  max: 20,          \u002F\u002F max connections in pool\n  idleTimeoutMillis: 30000,\n  connectionTimeoutMillis: 2000,\n});\n\nasync function getUsers() {\n  const client = await pool.connect();\n  try {\n    const res = await client.query('SELECT * FROM users WHERE active = $1', [true]);\n    return res.rows;\n  } finally {\n    client.release(); \u002F\u002F return to pool\n  }\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Knex (query builder)\nimport knex from 'knex';\n\nconst db = knex({\n  client: 'pg',\n  connection: process.env.DATABASE_URL,\n  pool: { min: 2, max: 10 }\n});\n\nconst users = await db('users')\n  .select('id', 'name')\n  .where('active', true)\n  .orderBy('created_at', 'desc')\n  .limit(10);\n\n\u002F\u002F Prisma (ORM)\nimport { PrismaClient } from '@prisma\u002Fclient';\n\nconst prisma = new PrismaClient();\n\nconst users = await prisma.user.findMany({\n  where: { active: true },\n  select: { id: true, name: true },\n  orderBy: { createdAt: 'desc' },\n  take: 10,\n});\n\n\u002F\u002F TypeORM (ORM)\nimport { DataSource } from 'typeorm';\n\nconst AppDataSource = new DataSource({ type: 'postgres', \u002F* ... *\u002F });\nawait AppDataSource.initialize();\n\nconst userRepo = AppDataSource.getRepository(User);\nconst users = await userRepo.find({ where: { active: true }, take: 10 });\n```\n\n**Practical Example:**\nTransaction with connection pool and retries:\n```js\nasync function transferMoney(fromId, toId, amount) {\n  const client = await pool.connect();\n  try {\n    await client.query('BEGIN');\n    const from = await client.query('SELECT balance FROM accounts WHERE id = $1 FOR UPDATE', [fromId]);\n    if (from.rows[0].balance \u003C amount) throw new Error('Insufficient funds');\n    await client.query('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [amount, fromId]);\n    await client.query('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, toId]);\n    await client.query('COMMIT');\n  } catch (err) {\n    await client.query('ROLLBACK');\n    throw err;\n  } finally {\n    client.release();\n  }\n}\n```\n\n**Common Mistakes:**\n- Not releasing connections back to pool (pool exhaustion, hangs)\n- Using ORM for complex queries causing N+1 queries\n- Not setting pool limits (too many connections overwhelm DB)\n- Storing credentials in code instead of env vars\n\n**Interview Follow-ups:**\n- Q: When to use ORM vs raw queries? A: ORM for CRUD, rapid dev; raw for complex reports, bulk operations\n- Q: How to avoid N+1 queries in ORM? A: Use `include` (Prisma), `eager loading` (TypeORM), or `join` in query builder\n\n**Best Practices:**\n- Always use connection pooling (never create new connection per request)\n- Set pool limits based on DB max_connections (leave room for migrations, admin)\n- Use prepared statements to prevent SQL injection\n- Implement retry logic for transient failures (network, deadlock)\n- Monitor pool metrics (waiting clients, connection usage)\n\n**Performance Considerations:**\n- Raw drivers fastest, least abstraction overhead\n- Query builders (Knex) minimal overhead\n- ORMs add 2-5x overhead; acceptable for most apps\n- Connection pool reduces TCP handshake overhead\n\n**Production Recommendations:**\n- Start with Prisma for type safety, migrations, DX\n- Use Knex for complex dynamic queries\n- Use `pg` pool with `async\u002Fawait` for performance-critical paths\n- Implement connection pool health checks (`pool.on('error')`)\n- Use read replicas for queries: separate pool for reads\n\n**Browser Behavior:**\nNot applicable (databases are server-side).\n\n**Node.js Runtime Behavior:**\nDatabase drivers use libuv for socket I\u002FO. Some drivers have native bindings (pg-native, mysql2 native).\n\n**Latest Node.js Patterns:**\n- Prisma 5 with Accelerate (global cache)\n- Drizzle ORM (lightweight, type-safe)\n- `node:sqlite` built-in (Node.js 22+)\n- Connection pooling with `pg-pool` (built into `pg`)\n\n**TypeScript Example:**\n```ts\nimport { Pool, PoolClient, QueryResult } from 'pg';\n\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nclass UserRepository {\n  private pool: Pool;\n  \n  constructor(pool: Pool) {\n    this.pool = pool;\n  }\n  \n  async findById(id: number): Promise\u003CUser | null> {\n    const res = await this.pool.query('SELECT * FROM users WHERE id = $1', [id]);\n    return res.rows[0] || null;\n  }\n  \n  async create(user: Omit\u003CUser, 'id'>): Promise\u003CUser> {\n    const res = await this.pool.query(\n      'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',\n      [user.name, user.email]\n    );\n    return res.rows[0];\n  }\n}\n```\n\n**Interview Tip:**\nEmphasize that connection pooling is essential for production; ORMs are convenient but understand the SQL they generate.\n\n**Common Follow-up:**\n\"How do you handle database migrations in Node.js?\" Use ORM migrations (Prisma migrate, TypeORM migrations) or separate tools (goose, node-pg-migrate).\n\n**Real-world Example:**\nDiscord uses ScyllaDB with Node.js driver and custom pooling. Airbnb uses TypeORM for internal tools. Prisma is used by many startups for type safety.\n\n**Advanced Notes:**\nConnection pool algorithms: simple `acquire\u002Frelease`, `min\u002Fmax`, `idle timeout`. Some pools support `lifo` (last-in-first-out) for better performance. Transaction propagation across multiple queries uses same connection (via `client` object).",[292,293,294],"databases","orm","connection-pooling",{"id":296,"category":297,"question":298,"answer":299,"level":145,"tags":300},38,"Caching","What are caching strategies in Node.js? How do you use Redis for caching?","**Concept Explanation:**\nCaching stores frequently accessed data in fast storage to reduce latency and database load. Strategies include cache-aside (lazy loading), write-through, write-behind, and TTL-based expiration. Redis is an in-memory data store ideal for distributed caching.\n\n**Execution Flow:**\n1. Request arrives, check cache for key\n2. If hit (cache hit), return cached data\n3. If miss (cache miss), fetch from DB, store in cache, return data\n4. On write, invalidate or update cache\n\n**Event Loop Explanation:**\nRedis operations are asynchronous (network I\u002FO). Use connection pool (`ioredis`) for concurrent requests.\n\n**Memory Behavior:**\nRedis stores data in RAM; set maxmemory and eviction policy (LRU, LFU, TTL). Cache keys should have TTL to avoid stale data.\n\n**Lifecycle Explanation:**\n```js\nimport Redis from 'ioredis';\n\nconst redis = new Redis({\n  host: process.env.REDIS_HOST,\n  port: 6379,\n  maxRetriesPerRequest: 3,\n});\n\n\u002F\u002F Cache-aside pattern\nasync function getUser(id) {\n  const cacheKey = `user:${id}`;\n  \u002F\u002F 1. Try cache\n  const cached = await redis.get(cacheKey);\n  if (cached) return JSON.parse(cached);\n  \n  \u002F\u002F 2. Cache miss, fetch from DB\n  const user = await db.query('SELECT * FROM users WHERE id = $1', [id]);\n  \n  \u002F\u002F 3. Store in cache with TTL (expiration)\n  await redis.setex(cacheKey, 3600, JSON.stringify(user));\n  \n  return user;\n}\n\n\u002F\u002F Write-through: update cache on write\nasync function updateUser(id, data) {\n  await db.query('UPDATE users SET name = $1 WHERE id = $2', [data.name, id]);\n  \u002F\u002F Update cache\n  const cacheKey = `user:${id}`;\n  await redis.setex(cacheKey, 3600, JSON.stringify(data));\n  \u002F\u002F Or invalidate: await redis.del(cacheKey);\n}\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Redis data types\nawait redis.set('key', 'value');\nawait redis.get('key');\nawait redis.del('key');\nawait redis.expire('key', 60); \u002F\u002F TTL\n\n\u002F\u002F Hash (for objects)\nawait redis.hset('user:1', 'name', 'Alice', 'age', 30);\nconst name = await redis.hget('user:1', 'name');\n\n\u002F\u002F Set (for tags)\nawait redis.sadd('tags:post:1', 'nodejs', 'caching');\nconst tags = await redis.smembers('tags:post:1');\n\n\u002F\u002F Sorted set (for leaderboards)\nawait redis.zadd('leaderboard', 100, 'player1');\nconst top = await redis.zrevrange('leaderboard', 0, 9, 'WITHSCORES');\n```\n\n**Practical Example:**\nAPI response caching with Express middleware:\n```js\nimport Redis from 'ioredis';\nimport crypto from 'node:crypto';\n\nconst redis = new Redis();\n\nfunction cacheMiddleware(ttlSeconds = 60) {\n  return async (req, res, next) => {\n    \u002F\u002F Generate cache key from URL + user context\n    const key = `cache:${req.user?.id || 'anon'}:${req.originalUrl}`;\n    \n    const cached = await redis.get(key);\n    if (cached) {\n      return res.json(JSON.parse(cached));\n    }\n    \n    \u002F\u002F Override res.json to cache the response\n    const originalJson = res.json;\n    res.json = function(data) {\n      redis.setex(key, ttlSeconds, JSON.stringify(data)).catch(console.error);\n      originalJson.call(this, data);\n    };\n    next();\n  };\n}\n\napp.get('\u002Fapi\u002Fproducts', cacheMiddleware(300), async (req, res) => {\n  const products = await db.getProducts();\n  res.json(products);\n});\n```\n\n**Common Mistakes:**\n- Cache stampede (multiple requests simultaneously recompute same cache on miss) → use locking or `setnx`\n- Not setting TTL (cache grows indefinitely, returns stale data)\n- Caching user-specific data without including user ID in key (cross-user cache leak)\n- Using Redis as primary database (data loss on restart without persistence)\n\n**Interview Follow-ups:**\n- Q: What is cache invalidation? Why is it hard? A: Keeping cache consistent with source of truth. Strategies: TTL, write-through, event-based invalidation\n- Q: How to prevent cache stampede? A: Use `setnx` (set if not exists) for exclusive recomputation, or probabilistic early expiration\n\n**Best Practices:**\n- Always set TTL; avoid unbounded caches\n- Use cache-aside with fallback to DB\n- Implement circuit breaker for Redis failures (fail open or fail closed based on use case)\n- Monitor cache hit ratio; adjust TTL and size\n\n**Performance Considerations:**\n- Redis network round-trip ~0.5ms local, ~2ms remote\n- Batch operations using pipelines: `redis.pipeline().get('a').get('b').exec()`\n- Use `redis.mget()` for multiple keys in one call\n\n**Production Recommendations:**\n- Use `ioredis` with cluster support for distributed Redis\n- Enable Redis persistence (RDB + AOF) for caches that can't be lost\n- Set `maxmemory-policy allkeys-lru` for cache-only use\n- Use connection pool: `ioredis` handles automatically\n\n**Browser Behavior:**\nBrowser caching uses HTTP cache headers (Cache-Control, ETag). Redis is server-side only.\n\n**Node.js Runtime Behavior:**\n`ioredis` uses async\u002Fawait and supports Redis Cluster, Sentinel. `redis` package (v4) also supports modern patterns.\n\n**Latest Node.js Patterns:**\n- `upstash-redis` for serverless (HTTP-based)\n- `cache-manager` with Redis store for higher abstraction\n- `bull` queue using Redis for job queuing\n\n**TypeScript Example:**\n```ts\nimport Redis from 'ioredis';\n\ninterface CacheOptions {\n  ttl: number;\n  prefix?: string;\n}\n\nclass CacheService {\n  private client: Redis;\n  private defaultTTL: number;\n  \n  constructor(redisUrl: string, defaultTTL = 3600) {\n    this.client = new Redis(redisUrl);\n    this.defaultTTL = defaultTTL;\n  }\n  \n  async get\u003CT>(key: string): Promise\u003CT | null> {\n    const data = await this.client.get(key);\n    return data ? JSON.parse(data) : null;\n  }\n  \n  async set\u003CT>(key: string, value: T, ttl = this.defaultTTL): Promise\u003Cvoid> {\n    await this.client.setex(key, ttl, JSON.stringify(value));\n  }\n  \n  async remember\u003CT>(key: string, fn: () => Promise\u003CT>, ttl?: number): Promise\u003CT> {\n    const cached = await this.get\u003CT>(key);\n    if (cached !== null) return cached;\n    const fresh = await fn();\n    await this.set(key, fresh, ttl);\n    return fresh;\n  }\n}\n```\n\n**Interview Tip:**\nExplain that caching is about trade-offs: consistency vs performance. Choose strategy based on read\u002Fwrite ratio and tolerance for staleness.\n\n**Common Follow-up:**\n\"How do you handle cache warming on application startup?\" Preload popular keys after app starts using a background job.\n\n**Real-world Example:**\nGitHub uses Redis for caching API responses. Twitter uses Redis for timeline caching.\n\n**Advanced Notes:**\nRedis supports Lua scripting for atomic operations. Redlock algorithm for distributed locks. `ioredis` supports `redis.resume()` after connection loss. Sentinel provides high availability.",[179,270,47],{"id":302,"category":265,"question":303,"answer":304,"level":145,"tags":305},39,"What are common security vulnerabilities in Node.js applications and how do you prevent them?","**Concept Explanation:**\nNode.js applications face OWASP Top 10 vulnerabilities: injection (SQL, NoSQL, command), XSS, CSRF, insecure deserialization, path traversal, authentication weaknesses, rate limiting, dependency vulnerabilities, and information disclosure.\n\n**Execution Flow:**\nAttack vectors target input validation, authentication, session management, and dependency chains. Prevention includes input sanitization, parameterized queries, CSP headers, secure cookies, and regular `npm audit`.\n\n**Event Loop Explanation:**\nSecurity vulnerabilities don't directly affect event loop but DoS attacks (regex, CPU-intensive input) can block the loop.\n\n**Memory Behavior:**\nUnchecked input size can cause OOM; memory leaks from improper closure references.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F 1. SQL Injection - DO NOT DO THIS\napp.get('\u002Fuser', (req, res) => {\n  const id = req.query.id;\n  \u002F\u002F VULNERABLE: string concatenation\n  db.query(`SELECT * FROM users WHERE id = ${id}`, (err, rows) => {});\n});\n\n\u002F\u002F FIX: Parameterized queries\napp.get('\u002Fuser', (req, res) => {\n  const id = req.query.id;\n  db.query('SELECT * FROM users WHERE id = $1', [id], (err, rows) => {});\n});\n\n\u002F\u002F 2. Command Injection\n\u002F\u002F VULNERABLE\nconst exec = require('child_process').exec;\nexec(`ls ${req.query.dir}`, (err, out) => {});\n\u002F\u002F FIX: Use execFile with arguments array, or validate input\n\n\u002F\u002F 3. Path Traversal\n\u002F\u002F VULNERABLE: req.query.file = '..\u002F..\u002F..\u002Fetc\u002Fpasswd'\nfs.readFile(`.\u002Fpublic\u002F${req.query.file}`, ...);\n\u002F\u002F FIX: Resolve and check prefix\nconst safePath = path.resolve('.\u002Fpublic', req.query.file);\nif (!safePath.startsWith(path.resolve('.\u002Fpublic'))) throw new Error('Forbidden');\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Security middleware\nimport helmet from 'helmet';\nimport cors from 'cors';\nimport rateLimit from 'express-rate-limit';\n\napp.use(helmet()); \u002F\u002F Sets various HTTP headers (X-XSS-Protection, etc.)\napp.use(cors({ origin: process.env.ALLOWED_ORIGIN?.split(',') }));\n\nconst limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 });\napp.use('\u002Fapi', limiter);\n\n\u002F\u002F Prevent XSS via output escaping\nimport escape from 'escape-html';\napp.post('\u002Fcomment', (req, res) => {\n  const safeComment = escape(req.body.comment);\n  \u002F\u002F store safeComment\n});\n\n\u002F\u002F Cookie security\napp.use(require('cookie-parser')());\nres.cookie('token', token, {\n  httpOnly: true,   \u002F\u002F Not accessible via JavaScript\n  secure: true,     \u002F\u002F HTTPS only\n  sameSite: 'strict', \u002F\u002F CSRF protection\n  maxAge: 3600000\n});\n```\n\n**Practical Example:**\nComplete security middleware setup:\n```js\nimport express from 'express';\nimport helmet from 'helmet';\nimport cors from 'cors';\nimport rateLimit from 'express-rate-limit';\nimport mongoSanitize from 'express-mongo-sanitize';\nimport xss from 'xss-clean';\n\nconst app = express();\n\n\u002F\u002F Set security headers\napp.use(helmet({\n  contentSecurityPolicy: {\n    directives: {\n      defaultSrc: [\"'self'\"],\n      scriptSrc: [\"'self'\", 'trusted-cdn.com'],\n      objectSrc: [\"'none'\"],\n      upgradeInsecureRequests: [],\n    },\n  },\n}));\n\n\u002F\u002F Limit payload size\napp.use(express.json({ limit: '10kb' }));\n\n\u002F\u002F Prevent parameter pollution\napp.use(mongoSanitize()); \u002F\u002F Removes $ and . operators\napp.use(xss()); \u002F\u002F Sanitizes user input\n\n\u002F\u002F Rate limiting\nconst strictLimiter = rateLimit({\n  windowMs: 15 * 60 * 1000,\n  max: 100,\n  standardHeaders: true,\n});\napp.use('\u002Fapi\u002F', strictLimiter);\n\n\u002F\u002F Authentication middleware\napp.use('\u002Fapi\u002Fprotected', authenticate);\n```\n\n**Common Mistakes:**\n- Using `eval()` or `new Function()` on user input (remote code execution)\n- Storing secrets in code (environment variables instead)\n- Disabling CSRF protection for REST APIs (use token or sameSite cookies)\n- Not updating dependencies (`npm audit fix`)\n- Trusting `req.headers['x-forwarded-for']` without proxy trust\n\n**Interview Follow-ups:**\n- Q: What is NoSQL injection? A: Malicious operators in query objects (e.g., `{ $gt: '' }`). Prevent by validating input types, using schema validation.\n- Q: How to protect against brute force login? A: Rate limiting, CAPTCHA after attempts, exponential backoff\n\n**Best Practices:**\n- Input validation (allowlist, not blocklist)\n- Parameterized queries for SQL\u002FNoSQL\n- Use `helmet` and `cors` properly\n- Encrypt sensitive data at rest (bcrypt for passwords)\n- Regular security audits: `npm audit`, Snyk, OWASP dependency check\n\n**Performance Considerations:**\n- Helmet adds minimal overhead (setting headers)\n- Rate limiting with Redis adds network latency\n- Input validation (xss-clean) has small CPU cost\n\n**Production Recommendations:**\n- Run Node.js as non-root user\n- Use `--inspect` only in development; disable in production\n- Set `NODE_ENV=production` to disable debug info\n- Implement CSP (Content Security Policy) headers\n- Use API gateway for WAF (Web Application Firewall)\n\n**Browser Behavior:**\nCORS prevents unauthorized cross-origin requests. CSP prevents XSS. Cookies with `HttpOnly` and `Secure` flags.\n\n**Node.js Runtime Behavior:**\n- `child_process` should avoid shell=true with user input\n- `vm` module can be dangerous; use `safe-eval` alternatives\n\n**Latest Node.js Patterns:**\n- `--policy` flag for policy-based security\n- `node:sea` for single executable applications (code protection)\n- `crypto` module for secure random tokens\n\n**TypeScript Example:**\n```ts\nimport helmet from 'helmet';\nimport rateLimit from 'express-rate-limit';\nimport { z } from 'zod';\n\n\u002F\u002F Input validation with Zod (prevents injection)\nconst userIdSchema = z.string().regex(\u002F^[a-f0-9]{24}$\u002F);\n\napp.get('\u002Fuser\u002F:id', (req, res) => {\n  const result = userIdSchema.safeParse(req.params.id);\n  if (!result.success) {\n    return res.status(400).json({ error: 'Invalid user ID format' });\n  }\n  \u002F\u002F Safe to use result.data\n});\n\n\u002F\u002F Secure random token generation\nimport { randomBytes } from 'node:crypto';\nconst token = randomBytes(32).toString('hex');\n```\n\n**Interview Tip:**\nStructure answer by OWASP Top 10 categories, then Node.js specific mitigations. Emphasize defense in depth.\n\n**Common Follow-up:**\n\"How do you handle dependency vulnerabilities?\" Use `npm audit`, `npm outdated`, Snyk, Dependabot, and regular updates with CI checks.\n\n**Real-world Example:**\nEquifax breach (2017) was due to unpatched Apache Struts; similar risks exist for Node.js dependencies. eslint-scope incident (2018) compromised npm package.\n\n**Advanced Notes:**\nSecrets management: use vault (HashiCorp Vault) or cloud secret managers. JWT secrets rotation. CSP nonces for inline scripts. SQL injection via `raw` queries in ORMs still possible. Use `pg` with parameterized queries, not string interpolation.",[189,306,307],"owasp","prevention",{"id":309,"category":310,"question":311,"answer":312,"level":145,"tags":313},40,"Testing","How do you test Node.js applications using the built-in test runner (node:test) and mocking?","**Concept Explanation:**\nNode.js includes a native test runner (`node:test`) since version 18, with assertion library (`node:assert`), mocking (`node:test` mocking), and coverage support. It's designed to be simple, fast, and dependency-free.\n\n**Execution Flow:**\n1. Test files describe tests using `test()` or `describe()`\u002F`it()`\n2. Node.js test runner executes tests concurrently (by default)\n3. Assertions validate expectations\n4. Mock functions replace dependencies\n5. Results output to console (TAP or JSON)\n\n**Event Loop Explanation:**\nTests run asynchronously; `node:test` respects event loop, supports async tests, and handles promises.\n\n**Memory Behavior:**\nEach test isolate (with `concurrency: true`) runs in separate context; mocks reset per test.\n\n**Lifecycle Explanation:**\n```js\nimport { test, describe, it, before, after, beforeEach, afterEach } from 'node:test';\nimport assert from 'node:assert';\n\n\u002F\u002F Simple test\ntest('adds 1 + 2 equals 3', () => {\n  assert.strictEqual(1 + 2, 3);\n});\n\n\u002F\u002F Async test\ntest('async operation', async () => {\n  const result = await fetchData();\n  assert.ok(result);\n});\n\n\u002F\u002F With hooks\ndescribe('database tests', () => {\n  before(async () => {\n    await db.connect();\n  });\n  \n  after(async () => {\n    await db.close();\n  });\n  \n  it('should query users', async () => {\n    const users = await db.query('SELECT * FROM users');\n    assert.equal(users.length, 0);\n  });\n});\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Using test with options\ntest('skipped test', { skip: true }, () => {});\ntest('only this test', { only: true }, () => {});\ntest('timeout test', { timeout: 1000 }, async () => {});\n\n\u002F\u002F Subtesting\ntest('parent', async (t) => {\n  await t.test('child 1', () => {});\n  await t.test('child 2', () => {});\n});\n\n\u002F\u002F Assertions\nimport assert from 'node:assert';\nassert.strictEqual(actual, expected);\nassert.deepStrictEqual(obj1, obj2);\nassert.throws(() => { throw new Error('boom'); }, \u002Fboom\u002F);\nassert.rejects(async () => { throw new Error('async fail'); }, \u002Ffail\u002F);\nassert.match('hello world', \u002Fworld\u002F);\n```\n\n**Practical Example:**\nTesting a service with mocking:\n```js\nimport { test, mock } from 'node:test';\nimport assert from 'node:assert';\nimport { UserService } from '.\u002Fuser-service.js';\n\ntest('UserService.getUser returns user from API', async () => {\n  \u002F\u002F Mock fetch globally\n  const fetchMock = mock.fn();\n  global.fetch = fetchMock;\n  \n  fetchMock.mockResolvedValueOnce({\n    ok: true,\n    json: async () => ({ id: 1, name: 'Alice' }),\n  });\n  \n  const service = new UserService();\n  const user = await service.getUser(1);\n  \n  assert.strictEqual(user.name, 'Alice');\n  assert.strictEqual(fetchMock.mock.calls.length, 1);\n  assert.strictEqual(fetchMock.mock.calls[0].arguments[0], 'https:\u002F\u002Fapi.example.com\u002Fusers\u002F1');\n  \n  \u002F\u002F Cleanup\n  mock.reset();\n});\n```\n\n**Common Mistakes:**\n- Forgetting to `await` async tests (test passes silently)\n- Not resetting mocks between tests (state leaks)\n- Using `only` in CI (accidentally skipping tests)\n- Not handling `before`\u002F`after` errors (test suite hangs)\n\n**Interview Follow-ups:**\n- Q: How does `node:test` differ from Jest\u002FMocha? A: Built-in, no dependencies, uses TAP output, supports mock, simpler configuration\n- Q: How to get code coverage with `node:test`? A: Use `--experimental-test-coverage` flag (Node.js 20+)\n\n**Best Practices:**\n- Name tests descriptively: `'should return user when id exists'`\n- Test both success and error paths\n- Use `describe` for grouping related tests\n- Run tests with `--watch` for development\n- Use `--test-concurrency` to control parallel execution\n\n**Performance Considerations:**\n- Concurrency (default) runs tests in parallel, faster execution\n- Use `--test-timeout` to avoid hanging tests\n- Coverage flag adds overhead; use in CI only\n\n**Production Recommendations:**\n- Use `node --test` in CI pipelines\n- Combine with `c8` for coverage if needed (more features)\n- Use `--test-reporter=spec` for readable output, `--test-reporter=json` for automation\n- Run tests with `NODE_ENV=test` to use test configuration\n\n**Browser Behavior:**\nNot applicable.\n\n**Node.js Runtime Behavior:**\n- `node:test` uses `worker_threads` for isolation when `--test-concurrency` > 1\n- Mocking uses `MockTracker`; `mock.method(object, methodName, implementation)`\n\n**Latest Node.js Patterns:**\n- `--experimental-test-coverage` (Node 20, stable in 21+)\n- `--test-reporter` with `--test-reporter-destination` (multiple reporters)\n- `test.describe` and `test.it` aliases\n\n**TypeScript Example:**\n```ts\nimport { test, describe, mock } from 'node:test';\nimport assert from 'node:assert';\nimport { PrismaClient } from '@prisma\u002Fclient';\n\ndescribe('UserRepository', () => {\n  let repo: UserRepository;\n  let prismaMock: any;\n  \n  test.beforeEach(() => {\n    prismaMock = {\n      user: {\n        findUnique: mock.fn(),\n        create: mock.fn(),\n      }\n    };\n    repo = new UserRepository(prismaMock as PrismaClient);\n  });\n  \n  test('findById returns user', async () => {\n    const expectedUser = { id: 1, email: 'test@example.com' };\n    prismaMock.user.findUnique.mockResolvedValue(expectedUser);\n    \n    const result = await repo.findById(1);\n    \n    assert.deepStrictEqual(result, expectedUser);\n    assert.strictEqual(prismaMock.user.findUnique.mock.calls.length, 1);\n  });\n  \n  test('findById returns null for missing user', async () => {\n    prismaMock.user.findUnique.mockResolvedValue(null);\n    const result = await repo.findById(999);\n    assert.strictEqual(result, null);\n  });\n});\n```\n\n**Interview Tip:**\nHighlight that `node:test` is production-ready in Node.js 20+ and eliminates need for Jest\u002FMocha in many projects, reducing dependencies.\n\n**Common Follow-up:**\n\"How do you mock a module in `node:test`?\" Use `mock.method` on imported module, or use `Module.register` for ESM interception (more complex). For CommonJS, `mock.method(require('module'), 'function')` works.\n\n**Real-world Example:**\nNode.js core team uses `node:test` for Node.js itself. Many open-source projects are migrating from Jest to `node:test` for faster CI.\n\n**Advanced Notes:**\n`node:test` supports `--test-shard` for splitting tests across CI runners. `test.beforeEach` and `afterEach` are per test, not per file. `test.describe.skip` and `test.describe.only` available. Coverage requires `--experimental-test-coverage` and outputs to `coverage\u002F` directory.",[252,314,315],"node-test","mocking",{"id":317,"category":318,"question":319,"answer":320,"level":145,"tags":321},41,"Performance Optimization","How do you profile and optimize performance in Node.js applications? What tools and techniques do you use?","**Concept Explanation:**\nPerformance optimization in Node.js involves identifying bottlenecks (CPU, memory, I\u002FO) using profiling tools, then applying optimizations like algorithm improvements, caching, stream processing, clustering, and native addons. The goal is to reduce latency and increase throughput without sacrificing code clarity.\n\n**Execution Flow:**\n1. Establish baseline metrics (requests per second, latency percentiles)\n2. Profile CPU using inspector\u002Fflamegraphs\n3. Profile memory for leaks or excess usage\n4. Identify hot paths (frequently executed code)\n5. Optimize: caching, batching, concurrency, algorithm changes\n6. Measure again to validate improvement\n\n**Event Loop Explanation:**\nPerformance issues often arise from blocking the event loop (sync CPU work, large JSON parsing, regex on long strings). Use `perf_hooks` to measure loop lag.\n\n**Memory Behavior:**\nMemory leaks cause performance degradation over time. Use heap snapshots to identify retained objects.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Using built-in profiler\n\u002F\u002F node --inspect --cpu-prof app.js\n\u002F\u002F Then open chrome:\u002F\u002Finspect, take CPU profile\n\n\u002F\u002F Programmatic profiling with perf_hooks\nimport { performance, PerformanceObserver } from 'node:perf_hooks';\n\nconst obs = new PerformanceObserver((items) => {\n  console.log(items.getEntries()[0]);\n  performance.clearMarks();\n});\nobs.observe({ entryTypes: ['function'] });\n\nfunction measureAsync(fn, name) {\n  return async function(...args) {\n    performance.mark(`${name}-start`);\n    const result = await fn(...args);\n    performance.mark(`${name}-end`);\n    performance.measure(name, `${name}-start`, `${name}-end`);\n    return result;\n  };\n}\n```\n\n**Syntax Explanation:**\n```bash\n# CLI profiling tools\nnode --cpu-prof --cpu-prof-dir .\u002Fprofiles app.js\nnode --heap-prof --heap-prof-dir .\u002Fprofiles app.js\n\n# Generate flamegraph using 0x\nnpx 0x app.js\n\n# Using clinic.js suite\nnpx clinic doctor -- node app.js\nnpx clinic flame -- node app.js\nnpx clinic bubbleprof -- node app.js\n```\n\n**Practical Example:**\nIdentifying and fixing event loop blocking:\n```js\nimport { monitorEventLoopDelay } from 'node:perf_hooks';\n\nconst histogram = monitorEventLoopDelay({ resolution: 20 });\nhistogram.enable();\n\nsetInterval(() => {\n  const lag = histogram.percentile(99);\n  if (lag > 50) {\n    console.warn(`Event loop blocked for ${lag}ms at 99th percentile`);\n  }\n}, 5000);\n\n\u002F\u002F Bad: blocking operation\nfunction badHashPasswords(users) {\n  \u002F\u002F CPU-heavy, blocking\n  return users.map(u => ({\n    ...u,\n    hash: crypto.createHash('sha256').update(u.password).digest('hex')\n  }));\n}\n\n\u002F\u002F Good: offload to worker thread\nimport { Worker } from 'node:worker_threads';\nasync function goodHashPasswords(users) {\n  const worker = new Worker('.\u002Fhash-worker.js', { workerData: users });\n  return new Promise((resolve, reject) => {\n    worker.on('message', resolve);\n    worker.on('error', reject);\n  });\n}\n```\n\n**Common Mistakes:**\n- Optimizing prematurely without profiling\n- Micro-optimizing I\u002FO (usually network-bound, not CPU)\n- Using synchronous crypto\u002Ffs methods in hot paths\n- Creating too many garbage collection artifacts (objects, closures)\n\n**Interview Follow-ups:**\n- Q: What is a flamegraph and how do you interpret it? A: Visualization of CPU usage; x-axis time, y-axis stack depth; wide bars are hot functions\n- Q: How do you optimize a slow database query? A: Indexes, query optimization, caching, read replicas, query batching\n\n**Best Practices:**\n- Always measure before and after optimization\n- Optimize the critical path (most frequent\u002Flatency-sensitive operations)\n- Use streaming for large data instead of buffering\n- Implement caching for expensive computations\n- Use connection pooling for databases\n\n**Performance Considerations:**\n- V8 optimization: monomorphic functions, hidden classes, avoid try\u002Fcatch in loops\n- Use `--max-old-space-size` to increase heap if needed\n- `Buffer.allocUnsafe` faster than `alloc` but unsafe\n- `fast-json-stringify` for JSON serialization of known schemas\n\n**Production Recommendations:**\n- Set up continuous profiling in production (Pyroscope, Datadog, Dynatrace)\n- Use APM tools (New Relic, AppDynamics) for transaction tracing\n- Run load tests (k6, artillery) before deployment\n- Monitor event loop lag via health checks\n\n**Browser Behavior:**\nNot directly applicable; browser profiling uses DevTools.\n\n**Node.js Runtime Behavior:**\n`--cpu-prof` generates `.cpuprofile` files importable to Chrome DevTools. `--heap-prof` for heap snapshots. `clinic` uses `bubbleprof` for async resource tracking.\n\n**Latest Node.js Patterns:**\n- `perf_hooks.monitorEventLoopDelay` (stable)\n- `--cpu-prof-interval` for sampling rate\n- `diagnostics_channel` for tracing\n- `node:test` includes coverage (performance of test suite)\n\n**TypeScript Example:**\n```ts\nimport { performance } from 'node:perf_hooks';\n\nexport function withTiming\u003CT extends (...args: any[]) => any>(fn: T, name: string): T {\n  return (async (...args: any[]) => {\n    const start = performance.now();\n    const result = await fn(...args);\n    const duration = performance.now() - start;\n    console.log(`${name} took ${duration.toFixed(2)}ms`);\n    return result;\n  }) as T;\n}\n\n\u002F\u002F Usage\nconst slowFunction = async (input: string) => { \u002F* ... *\u002F };\nconst timedSlow = withTiming(slowFunction, 'slowFunction');\n```\n\n**Interview Tip:**\nSay: \"Profile first, then optimize. The most common Node.js performance issue is blocking the event loop with CPU work. Move that to worker threads or break it into smaller chunks using `setImmediate` or `nextTick`.\"\n\n**Common Follow-up:**\n\"How do you optimize a high-traffic API endpoint?\" Caching (Redis, CDN), pagination, compression (gzip), database indexing, connection pooling, horizontal scaling with cluster\u002Fload balancer.\n\n**Real-world Example:**\nNetflix reduced startup time by optimizing V8 hidden classes. PayPal saw 2x throughput after moving blocking crypto to worker threads.\n\n**Advanced Notes:**\nV8 compiles hot functions with TurboFan. Deoptimizations occur when assumptions break (e.g., function called with different argument types). Use `--trace-opt` and `--trace-deopt` to detect. `autocannon` for HTTP benchmarking.",[47,322,323],"profiling","optimization",{"id":325,"category":326,"question":327,"answer":328,"level":145,"tags":329},42,"Memory Management","How do you detect and fix memory leaks in Node.js applications? What tools and patterns help?","**Concept Explanation:**\nMemory leaks occur when objects are no longer needed but still referenced, preventing garbage collection. Common causes: global variables, event listeners not removed, closures retaining large objects, timers, and caches without eviction policies.\n\n**Execution Flow:**\n1. Memory usage grows over time (trend, not spike)\n2. Heap snapshots show retained objects\n3. Leak detector (node-memwatch) identifies suspect references\n4. Fix by removing references, using weak maps, or proper cleanup\n\n**Event Loop Explanation:**\nLeaks don't directly affect event loop but cause increased GC frequency, leading to pause times and latency spikes.\n\n**Memory Behavior:**\nV8 uses generational GC: Scavenger (young), Mark-Compact (old). Leaked objects move to old space and never freed.\n\n**Lifecycle Explanation:**\n```js\n\u002F\u002F Common leak: global variables\n\u002F\u002F LEAK: global cache grows unbounded\nconst cache = {};\nfunction addToCache(key, value) {\n  cache[key] = value; \u002F\u002F never deleted\n}\n\n\u002F\u002F FIX: Use TTL or LRU cache\nimport LRU from 'lru-cache';\nconst cache = new LRU({ max: 500, ttl: 1000 * 60 * 5 });\n\n\u002F\u002F Leak: event listeners not removed\nfunction setupListener() {\n  const onData = (data) => { console.log(data); };\n  emitter.on('data', onData);\n  \u002F\u002F Missing: emitter.off('data', onData) when done\n}\n\n\u002F\u002F FIX: Use once, or cleanup with symbol\nfunction setupListenerCleanup() {\n  const onData = (data) => { console.log(data); };\n  emitter.on('data', onData);\n  return () => emitter.off('data', onData);\n}\nconst cleanup = setupListenerCleanup();\n\u002F\u002F later: cleanup();\n```\n\n**Syntax Explanation:**\n```bash\n# Detect leaks with node flags\nnode --inspect --expose-gc app.js\n# Then take heap snapshots in Chrome DevTools\n\n# Using node-memwatch (third-party)\nnpm install memwatch-next\n\n# Using clinic heap profiler\nnpx clinic heap -- node app.js\n\n# Process memory usage monitor\nsetInterval(() => {\n  const used = process.memoryUsage();\n  console.log(`Heap: ${(used.heapUsed \u002F 1024 \u002F 1024).toFixed(2)} MB`);\n  if (used.heapUsed > 500 * 1024 * 1024) {\n    console.warn('Potential memory leak');\n  }\n}, 30000);\n```\n\n**Practical Example:**\nDetecting leak with heap snapshots:\n```js\nimport v8 from 'node:v8';\nimport fs from 'node:fs';\n\n\u002F\u002F Take heap snapshot on demand\napp.get('\u002Fheapdump', (req, res) => {\n  const snapshot = v8.getHeapSnapshot();\n  const filename = `heap-${Date.now()}.heapsnapshot`;\n  const writeStream = fs.createWriteStream(filename);\n  snapshot.pipe(writeStream);\n  snapshot.on('end', () => res.json({ file: filename }));\n});\n\n\u002F\u002F Leaky class example\nclass RequestTracker {\n  constructor() {\n    this.requests = []; \u002F\u002F grows forever\n  }\n  track(req) {\n    this.requests.push({\n      url: req.url,\n      timestamp: Date.now(),\n      \u002F\u002F Keeps entire request object alive\n      fullRequest: req\n    });\n  }\n  \u002F\u002F Missing: cleanup old requests\n}\n\n\u002F\u002F Fixed: remove old entries and use weak refs\nclass FixedTracker {\n  constructor(maxSize = 1000) {\n    this.requests = [];\n    this.maxSize = maxSize;\n  }\n  track(req) {\n    this.requests.push({\n      url: req.url,\n      timestamp: Date.now(),\n      \u002F\u002F Store only needed fields, not full request\n    });\n    if (this.requests.length > this.maxSize) {\n      this.requests.shift();\n    }\n  }\n}\n```\n\n**Common Mistakes:**\n- Assuming garbage collection is immediate (it's not; objects stay until next GC cycle)\n- Not calling `.destroy()` on streams or `close()` on servers\n- Using `setInterval` without cleanup (keeps process alive and accumulates callbacks)\n- Closures capturing large objects in loops\n\n**Interview Follow-ups:**\n- Q: What is the difference between shallow size and retained size in heap snapshots? A: Shallow size is memory for object itself; retained size includes objects it references exclusively.\n- Q: How do you debug a leak in production? A: Take heap snapshots via inspector, compare two snapshots (baseline and after growth) to see what's retained.\n\n**Best Practices:**\n- Use `WeakMap` and `WeakSet` for caches that shouldn't prevent GC\n- Always remove event listeners in `on('remove')` or using `once` when possible\n- Use `setInterval` with `.unref()` to not keep event loop alive\n- Limit cache sizes with LRU or TTL\n- Use `finalizationRegistry` for cleanup callbacks (advanced)\n\n**Performance Considerations:**\n- Heap snapshots are large (hundreds MB) and pause the process\n- `--expose-gc` and manual `global.gc()` can force GC for testing\n- Leaks increase GC frequency, reducing throughput by 30-50%\n\n**Production Recommendations:**\n- Set memory limit: `--max-old-space-size=512` (MB) to force restart on OOM\n- Use process managers (PM2) with `max_memory_restart`\n- Monitor `process.memoryUsage().heapUsed` in metrics\n- Use `@sentry\u002Fnode` or `newrelic` for leak detection alerts\n\n**Browser Behavior:**\nSimilar concepts (DevTools memory tab). `WeakMap` supported.\n\n**Node.js Runtime Behavior:**\n`v8.getHeapSnapshot()` returns a readable stream of JSON. `process.memoryUsage()` gives current heap stats. `--inspect` connects Chrome DevTools.\n\n**Latest Node.js Patterns:**\n- `node:diagnostics_channel` for tracing allocations\n- `--heap-snapshot-near-heap-limit` to auto-take snapshot before OOM\n- `WeakRef` and `FinalizationRegistry` for advanced memory management\n\n**TypeScript Example:**\n```ts\nclass LeakDetector {\n  private snapshots: Buffer[] = [];\n  private interval: NodeJS.Timeout;\n  \n  start(intervalMs = 60000) {\n    this.interval = setInterval(() => {\n      const used = process.memoryUsage().heapUsed \u002F 1024 \u002F 1024;\n      console.log(`Heap used: ${used.toFixed(2)} MB`);\n      if (this.snapshots.length > 0) {\n        \u002F\u002F Compare growth\n      }\n    }, intervalMs);\n    this.interval.unref();\n  }\n  \n  stop() {\n    clearInterval(this.interval);\n  }\n}\n```\n\n**Interview Tip:**\nExplain that memory leaks in Node.js often come from missing cleanup in async operations. Use `WeakRef` sparingly; prefer explicit cleanup.\n\n**Common Follow-up:**\n\"What tools do you use to find leaks?\" Chrome DevTools (heap snapshots, allocation timeline), `clinic heap`, `node-memwatch`, `@datadog\u002Fnode` profiler.\n\n**Real-world Example:**\nMongoose (MongoDB ODM) had a leak with unclosed connections; fix was proper `connection.close()` in tests. Express.js middleware that attaches `req.user` can leak if not removed after response.\n\n**Advanced Notes:**\n`FinalizationRegistry` allows registering callbacks when objects are garbage collected (for cleanup). `WeakRef` holds weak reference to object; use `deref()` to access. Not recommended for critical logic but useful for caches. Node.js uses `libuv` memory allocation; external memory (buffers) tracked separately.",[330,331,45],"memory-leaks","debugging",{"id":333,"category":334,"question":335,"answer":336,"level":145,"tags":337},43,"Debugging","How do you debug Node.js applications effectively? What tools and techniques do you use?","**Concept Explanation:**\nDebugging Node.js involves inspecting runtime state, setting breakpoints, stepping through code, and analyzing crashes. Tools include built-in inspector (Chrome DevTools), `--inspect` flag, `ndb`, `node --inspect-brk`, logging with `debug` module, and post-mortem debugging with core dumps.\n\n**Execution Flow:**\n1. Start app with `node --inspect` or `--inspect-brk`\n2. Open `chrome:\u002F\u002Finspect` in Chrome\n3. Set breakpoints, watch variables, step through code\n4. Inspect call stack and asynchronously scheduled tasks\n5. For production: use logging, APM, and core dumps\n\n**Event Loop Explanation:**\nDebugger can pause event loop, allowing inspection of asynchronous callbacks. Breakpoints halt execution, but you can resume.\n\n**Memory Behavior:**\nDebugger adds overhead; avoid in production. Breakpoints cause V8 to generate additional metadata.\n\n**Lifecycle Explanation:**\n```bash\n# Basic debugging\nnode --inspect app.js\n# Then open chrome:\u002F\u002Finspect and click \"Open dedicated DevTools\"\n\n# Break on first line\nnode --inspect-brk app.js\n\n# Enable debugging for all workers in cluster\nnode --inspect=9229 --inspect-publish-uid=http app.js\n\n# Debugging tests\nnode --inspect --test\n```\n\n**Syntax Explanation:**\n```js\n\u002F\u002F Manual breakpoints (in code)\ndebugger; \u002F\u002F Execution pauses if inspector attached\n\n\u002F\u002F Conditional breakpoint simulation\nif (someCondition) {\n  debugger; \u002F\u002F Only break when condition true\n}\n\n\u002F\u002F Logging with debug module (namespaced logging)\nimport debug from 'debug';\nconst log = debug('app:server');\nconst error = debug('app:error');\n\nlog('Server started on port %d', port);\nerror('Database connection failed', err);\n\n\u002F\u002F Run with DEBUG=app:* node app.js\n```\n\n**Practical Example:**\nDebugging async call stack:\n```js\n\u002F\u002F Problem: hard to trace async errors\nasync function fetchUser(id) {\n  const res = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n  \u002F\u002F Error might occur here\n  return res.json();\n}\n\nasync function displayUser(id) {\n  const user = await fetchUser(id);\n  console.log(user.name.toUpperCase()); \u002F\u002F Error if user undefined\n}\n\n\u002F\u002F Debug: use long stack traces\nnode --stack-trace-limit=50 --trace-warnings app.js\n\n\u002F\u002F Or use async_hooks for correlation\nimport async_hooks from 'node:async_hooks';\nconst contexts = new Map();\nasync_hooks.createHook({\n  init(asyncId, type, triggerAsyncId) {\n    contexts.set(asyncId, { type, trigger: triggerAsyncId });\n  },\n  destroy(asyncId) {\n    contexts.delete(asyncId);\n  }\n}).enable();\n```\n\n**Common Mistakes:**\n- Debugging in production (performance impact, security risk)\n- Using `console.log` for production logging (use structured logging instead)\n- Not using source maps with TypeScript (breakpoints in .ts files)\n- Forgetting to handle unhandled rejections (process exits silently)\n\n**Interview Follow-ups:**\n- Q: How do you debug a memory leak? A: Heap snapshots, compare before\u002Fafter, identify retained objects\n- Q: How to debug a production crash with no logs? A: Use core dumps (`--abort-on-uncaught-exception`), `node-report` module, or `--heap-snapshot-near-heap-limit`\n\n**Best Practices:**\n- Use `ndb` (improved Node.js debugging by Google) for better UX\n- For complex async flows, use `async_hooks` or `cls-hooked` to track context\n- Use `debug` module with namespaces instead of `console.log`\n- Set `NODE_DEBUG=http` to debug HTTP requests\n- Use `--trace-sync-io` to detect accidental sync operations\n\n**Performance Considerations:**\n- Inspector adds 10-30% overhead; don't leave enabled in production\n- Logging too much (verbose) can slow down app and fill disk\n- `async_hooks` has significant overhead; use only in dev\n\n**Production Recommendations:**\n- Use APM (Datadog, New Relic) for production debugging\n- Set up remote debugging with SSH tunnel (temporary, secure)\n- Log request IDs to correlate logs across services\n- Implement `\u002Fdebug\u002Fpprof` endpoints (like Go) for on-demand profiling\n\n**Browser Behavior:**\nChrome DevTools for frontend works similarly but has DOM\u002Fconsole integration.\n\n**Node.js Runtime Behavior:**\nInspector protocol allows attaching at runtime: `node --inspect=9229` then `process._debugProcess(pid)` to attach to running process.\n\n**Latest Node.js Patterns:**\n- `node --inspect` with `--inspect-publish-uid=http` for Docker\n- `node --watch --inspect` for auto-restart with debugger\n- `import 'node:inspector'` to programmatically start\u002Fstop inspector\n\n**TypeScript Example:**\n```ts\n\u002F\u002F tsconfig.json must have sourceMap: true\n\u002F\u002F Then debug with:\n\u002F\u002F node --inspect -r ts-node\u002Fregister app.ts\n\nimport { inspect } from 'node:util';\n\n\u002F\u002F Better object inspection\nconst obj = { deep: { nested: { data: 'value' } } };\nconsole.log(inspect(obj, { showHidden: false, depth: null, colors: true }));\n\n\u002F\u002F Custom inspection\nclass MyClass {\n  [inspect.custom]() {\n    return 'MyClass(42)';\n  }\n}\n```\n\n**Interview Tip:**\nDemonstrate knowledge of both development (Chrome DevTools) and production (logging, APM, core dumps) debugging techniques. Mention that debugging async code requires understanding event loop.\n\n**Common Follow-up:**\n\"How do you debug an infinite loop?\" Attach inspector, pause execution (pause button), check call stack, find loop in source. Or use `--trace-uncaught` to get stack trace.\n\n**Real-world Example:**\nUber uses `async_hooks` for distributed tracing. Stripe uses `ndb` for development debugging. Vercel uses `node --inspect` in preview deployments.\n\n**Advanced Notes:**\nPost-mortem debugging using `llnode` (LLDB plugin for V8) allows inspecting core dumps offline. `node-report` generates human-readable diagnostic reports. `--diagnostic-dir` controls where reports go. Use `process.report.getReport()` programmatically.",[331,338,259],"inspector",[340,349,354,360,367,373,384,393,403,411,418,425,433,440,447,458,467,478],{"id":341,"category":342,"question":343,"answer":344,"level":345,"tags":346},49,"Node.js Internals","Explain libuv and its role in Node.js architecture.","**Concept Explanation:**\nlibuv is a cross-platform C library that provides asynchronous I\u002FO operations, an event loop, thread pool, and other core utilities. It abstracts platform differences (epoll on Linux, kqueue on macOS, IOCP on Windows) and powers Node.js's non-blocking behavior.\n\n**Internal Working:**\nlibuv implements the event loop that Node.js uses. It handles:\n- File system operations (using thread pool)\n- TCP\u002FUDP networking\n- DNS resolution\n- Child processes\n- Signal handling\n- Timers (`setTimeout`, `setInterval`)\n- `setImmediate`\n\n**Architecture:**\n```\nNode.js JavaScript → Node.js Bindings (C++) → libuv → Kernel\n                         ↑\n                    (thread pool for fs, crypto)\n```\n\n**Event Loop Implementation (libuv):**\nlibuv's event loop is written in C and exposes a C API. Node.js wraps this API and adds JavaScript callbacks. The loop phases are implemented in `uv_run()`.\n\n**Thread Pool (libuv):**\nDefault size 4, controlled by `UV_THREADPOOL_SIZE`. Used for operations that lack native async support (e.g., `fs.readFile`, `crypto.pbkdf2`, `dns.lookup`).\n\n**Request Lifecycle (File I\u002FO):**\n1. JavaScript calls `fs.readFile()`.\n2. Node.js bindings create a `uv_fs_t` request.\n3. libuv submits the request to its thread pool.\n4. Thread performs blocking `read()` syscall.\n5. After completion, thread notifies event loop via async handle.\n6. Event loop calls callback on next iteration (poll phase).\n\n**Code Example (libuv internals – not directly accessible):**\n```javascript\n\u002F\u002F User code triggers libuv\nconst fs = require('fs');\nfs.readFile('file.txt', (err, data) => {\n  console.log(data);\n});\n\u002F\u002F libuv: uv_fs_read(loop, &req, fd, ...)\n```\n\n**Viewing libuv handles (C++ addon or debug):**\n```javascript\n\u002F\u002F Not directly, but you can see active handles\nconsole.log(process._getActiveHandles());\n\u002F\u002F Output: list of TCP, Timer, etc. (wraps libuv handles)\n```\n\n**Common Mistakes:**\n- Assuming all async operations use thread pool (network I\u002FO uses OS async APIs, not thread pool).\n- Not knowing that `UV_THREADPOOL_SIZE` affects all thread pool operations.\n- Overloading thread pool with many synchronous file reads.\n\n**Edge Cases:**\n- Setting `UV_THREADPOOL_SIZE` after libuv is initialized has no effect (set before process start).\n- Some libuv operations (like `getaddrinfo`) also use thread pool.\n- `process.env.UV_THREADPOOL_SIZE` is read at startup.\n\n**Interview Follow-ups:**\n- *\"Which operations use the thread pool and which use native async?\"*\n- *\"How does libuv handle socket I\u002FO differently from file I\u002FO?\"*\n\n**Best Practices:**\n- For heavy file I\u002FO, increase thread pool size.\n- Offload CPU-intensive work to worker threads, not the libuv thread pool.\n- Use `setImmediate` to break up long-running synchronous code.\n\n**Security Considerations:**\n- Thread pool exhaustion can cause DoS (all threads blocked).\n- Monitor `UV_THREADPOOL_SIZE` based on expected concurrency.\n\n**Performance Considerations:**\n- Default 4 threads may be insufficient for file-heavy apps; increase to 8-16.\n- Too many threads cause contention and overhead.\n- Network I\u002FO (sockets) does not use thread pool; it's evented.\n\n**Scalability Considerations:**\n- Each Node.js process has its own libuv instance and thread pool.\n- In clustered apps, total threads = processes × UV_THREADPOOL_SIZE.\n\n**Production Recommendations:**\n- Set `UV_THREADPOOL_SIZE` via environment variable in Docker\u002FK8s.\n- Monitor thread pool usage with `process._getActiveHandles()`.\n- Use `worker_threads` for CPU work to avoid blocking thread pool.\n\n**Latest Node.js Patterns:**\n- `libuv` 1.x has `uv_threadpool` improvements for better scaling.\n- Node.js 16+ exposes `uv_available_parallelism()` for optimal thread count.\n\n**Debugging Tips:**\n- `node --trace-sync-io` warns when sync I\u002FO blocks event loop.\n- Use `clinic doctor` to detect thread pool saturation.\n- `console.log(process._getActiveRequests())` shows pending libuv requests.\n\n**Interview Tip:**\nExplain that libuv is the reason Node.js works across platforms; it's the \"glue\" between V8 and the OS.\n\n**Common Follow-up:**\n*\"What is the difference between libuv's thread pool and worker threads?\"* – libuv thread pool handles internal async operations; worker threads are user-land threads for CPU-intensive JavaScript.\n\n**Real-world Example:**\nA file processing service increased `UV_THREADPOOL_SIZE` from 4 to 16, reducing file read latency by 70% under high concurrency.\n\n**Tags:** [\"libuv\", \"internals\", \"thread-pool\", \"event-loop\"]","advanced",[147,347,348,14],"internals","thread-pool",{"id":350,"category":342,"question":351,"answer":352,"level":345,"tags":353},50,"Deep dive: How does the Node.js event loop work internally with libuv phases?","**Concept Explanation:**\nThe event loop in Node.js is implemented by libuv. It consists of multiple phases, each handling different types of callbacks. Understanding the internal C implementation helps debug performance issues and order-of-execution quirks.\n\n**Internal Working (libuv's `uv_run` loop):**\nPseudo-code of libuv's event loop:\n```c\nint uv_run(uv_loop_t* loop, uv_run_mode mode) {\n  while (uv__loop_alive(loop)) {\n    uv__update_time(loop);\n    uv__run_timers(loop);      \u002F\u002F timers phase\n    uv__run_pending(loop);     \u002F\u002F pending callbacks\n    uv__run_idle(loop);\n    uv__run_prepare(loop);\n    uv__run_check(loop);\n    uv__run_closing_handles(loop);\n    \n    \u002F\u002F Poll for I\u002FO with timeout = next timer expiration\n    if (uv__io_poll(loop, timeout));\n  }\n}\n```\n\n**Detailed Phases:**\n1. **uv__update_time:** Updates loop's cached current time (performance optimization).\n2. **uv__run_timers:** Executes timers that have expired (uses a min-heap of timer nodes).\n3. **uv__run_pending:** Executes I\u002FO callbacks that were deferred from previous poll.\n4. **uv__run_idle \u002F uv__run_prepare:** Internal use (idle handles, prepare handles).\n5. **uv__io_poll:** Polls for I\u002FO events (epoll\u002Fkqueue\u002FIOCP) with a timeout based on next timer.\n6. **uv__run_check:** Executes `setImmediate` callbacks (check handles).\n7. **uv__run_closing_handles:** Executes close callbacks (`socket.on('close')`).\n\n**Between phases (microtask queue):** After each phase, Node.js's JavaScript wrapper drains microtasks (promises, nextTick). This is not in libuv; it's in Node.js's `InternalCallbackScope`.\n\n**Architecture Diagram:**\n```\nlibuv loop ──┬── timers (uv__run_timers)\n             ├── pending\n             ├── idle\u002Fprepare (internal)\n             ├── poll (uv__io_poll) ← waits for I\u002FO\n             ├── check (uv__run_check) ← setImmediate\n             └── close (uv__run_closing_handles)\n                 │\n                 └── each phase: after C callback → JS microtasks\n```\n\n**Code Example (C-level – not directly callable from JS):**\n```javascript\n\u002F\u002F To see event loop phases, use Node.js's internal `_tickCallback`\n\u002F\u002F But better: use `perf_hooks` to measure phase durations\nconst { performance, PerformanceObserver } = require('perf_hooks');\nconst obs = new PerformanceObserver((items) => {\n  console.log(items.getEntries());\n});\nobs.observe({ entryTypes: ['function'] });\n```\n\n**Practical Example – Blocking Poll Phase:**\n```javascript\n\u002F\u002F If there's no pending I\u002FO, poll blocks until next timer or new I\u002FO.\n\u002F\u002F A long-running synchronous operation during poll blocks everything.\nconst start = Date.now();\nfs.readFile('file.txt', () => {\n  \u002F\u002F This callback executes in poll phase\n  while (Date.now() - start \u003C 5000) { \u002F* block for 5 seconds *\u002F }\n  \u002F\u002F This blocks all other phases (timers, setImmediate) during the loop iteration\n});\n```\n\n**Timeout Calculation in Poll:**\nlibuv computes timeout for `uv__io_poll` as:\n- If timers are pending, timeout = next timer expiration - now.\n- If there are `setImmediate` callbacks, timeout = 0.\n- Otherwise, timeout = infinite (wait for I\u002FO).\n\n**Common Mistakes:**\n- Assuming `process.nextTick` is part of libuv (it's in Node.js layer).\n- Not realizing that the poll phase can block for long if no timers.\n- Thinking `setImmediate` always runs before `setTimeout(fn,0)` (depends on loop state).\n\n**Edge Cases:**\n- If the loop is idle (no handles), `uv_run` exits.\n- `uv__io_poll` may return early on signals.\n- Node.js adds an extra microtask checkpoint after each phase.\n\n**Interview Follow-ups:**\n- *\"How does libuv implement cross-platform async I\u002FO?\"*\n- *\"What happens when you have many timers with the same expiration?\"*\n\n**Best Practices:**\n- Keep poll phase callbacks short to avoid delaying other phases.\n- Use `setImmediate` to defer work after I\u002FO.\n- Avoid synchronous work in any callback.\n\n**Security Considerations:**\n- A malicious module could block the event loop by performing heavy work in any phase.\n\n**Performance Considerations:**\n- The event loop is single-threaded; one slow callback blocks all.\n- Use asynchronous I\u002FO whenever possible.\n\n**Scalability Considerations:**\n- Each Node.js process has its own event loop.\n- For multi-core, use cluster or worker threads.\n\n**Production Recommendations:**\n- Monitor event loop lag with `perf_hooks` or `loopbench`.\n- Set `NODE_OPTIONS=\"--trace-event-loop\"` for debugging.\n\n**Latest Node.js Patterns:**\n- `--enable-source-maps` for better async stack traces.\n- Node.js 19+ exposes event loop utilization via `performance.eventLoopUtilization()`.\n\n**Debugging Tips:**\n```javascript\nsetInterval(() => {\n  const start = process.hrtime.bigint();\n  setImmediate(() => {\n    const lag = process.hrtime.bigint() - start;\n    console.log(`Event loop lag: ${Number(lag) \u002F 1e6}ms`);\n  });\n}, 1000);\n```\n\n**Interview Tip:**\nExplain that libuv is the heart of the event loop; Node.js adds JavaScript callbacks on top.\n\n**Common Follow-up:**\n*\"How does libuv handle file system operations?\"* – Uses thread pool because filesystem APIs are blocking.\n\n**Real-world Example:**\nA high-frequency trading app uses `setImmediate` to process trades immediately after I\u002FO, ensuring low latency.\n\n**Tags:** [\"event-loop\", \"libuv\", \"phases\", \"internals\"]",[14,147,148,347],{"id":355,"category":356,"question":357,"answer":358,"level":345,"tags":359},51,"Concurrency","Worker Threads vs Clustering vs Child Processes: When to use each?","**Concept Explanation:**\nNode.js provides three mechanisms for parallel execution: worker threads (shared memory, for CPU-intensive tasks), clustering (multiple processes sharing ports, for scaling), and child processes (isolated processes with IPC). Each has different use cases, memory models, and communication overhead.\n\n**Comparison Table:**\n| Feature | Worker Threads | Cluster | Child Process |\n|---------|---------------|---------|---------------|\n| Memory sharing | Yes (SharedArrayBuffer) | No | No |\n| Communication | Message passing (faster) | IPC | IPC |\n| Use case | CPU-intensive tasks | Horizontal scaling | Isolated tasks |\n| Startup cost | Medium | High (new process) | High |\n| Debugging | Harder (multiple threads) | Separate processes | Separate processes |\n| Event loop | Each thread has its own | Each process has its own | Each process has its own |\n\n**Worker Threads (for CPU-bound work):**\n```javascript\nconst { Worker, isMainThread, parentPort, workerData } = require('worker_threads');\n\nif (isMainThread) {\n  const worker = new Worker(__filename, {\n    workerData: { iterations: 1e7 }\n  });\n  worker.on('message', (result) => console.log(result));\n  worker.on('error', console.error);\n  worker.on('exit', (code) => console.log(`Worker stopped with code ${code}`));\n} else {\n  \u002F\u002F CPU-intensive task\n  const { iterations } = workerData;\n  let sum = 0;\n  for (let i = 0; i \u003C iterations; i++) sum += i;\n  parentPort.postMessage(sum);\n}\n```\n\n**Shared Memory with Worker Threads:**\n```javascript\nconst { Worker, isMainThread, SharedArrayBuffer, Atomics } = require('worker_threads');\n\nif (isMainThread) {\n  const buffer = new SharedArrayBuffer(4);\n  const view = new Int32Array(buffer);\n  new Worker(__filename, { workerData: buffer });\n  setTimeout(() => {\n    console.log('Main sees:', Atomics.load(view, 0));\n  }, 100);\n} else {\n  const view = new Int32Array(workerData);\n  Atomics.add(view, 0, 42);\n}\n```\n\n**Clustering (for scaling HTTP servers):**\n```javascript\nconst cluster = require('cluster');\nconst http = require('http');\nconst os = require('os');\n\nif (cluster.isMaster) {\n  const numCPUs = os.cpus().length;\n  console.log(`Master ${process.pid} forking ${numCPUs} workers`);\n  for (let i = 0; i \u003C numCPUs; i++) cluster.fork();\n  \n  cluster.on('exit', (worker, code, signal) => {\n    console.log(`Worker ${worker.process.pid} died, restarting`);\n    cluster.fork();\n  });\n} else {\n  http.createServer((req, res) => {\n    res.writeHead(200);\n    res.end(`Hello from worker ${process.pid}`);\n  }).listen(3000);\n}\n```\n\n**Child Processes (for running external commands or isolated scripts):**\n```javascript\nconst { spawn, exec, fork } = require('child_process');\n\n\u002F\u002F Spawn (streaming I\u002FO)\nconst ls = spawn('ls', ['-la']);\nls.stdout.on('data', (data) => console.log(data.toString()));\n\n\u002F\u002F Exec (buffer output)\nexec('npm run build', (err, stdout, stderr) => {\n  if (err) console.error(err);\n  console.log(stdout);\n});\n\n\u002F\u002F Fork (Node.js module in separate process)\nconst child = fork('.\u002Fworker.js');\nchild.send({ hello: 'world' });\nchild.on('message', (msg) => console.log(msg));\n```\n\n**Practical Example – Hybrid Approach:**\n```javascript\n\u002F\u002F Master process clusters workers, each worker uses worker threads for CPU tasks\nconst cluster = require('cluster');\nconst { Worker } = require('worker_threads');\nconst express = require('express');\n\nif (cluster.isMaster) {\n  for (let i = 0; i \u003C os.cpus().length; i++) cluster.fork();\n} else {\n  const app = express();\n  app.get('\u002Fheavy', (req, res) => {\n    const worker = new Worker('.\u002Ffibonacci.js', { workerData: { n: 40 } });\n    worker.on('message', result => res.json({ result }));\n    worker.on('error', err => res.status(500).json({ error: err.message }));\n  });\n  app.listen(3000);\n}\n```\n\n**Common Mistakes:**\n- Using worker threads for I\u002FO (not beneficial, use main thread).\n- Creating many cluster workers (more than CPU cores) causing contention.\n- Not handling worker\u002Fchild exits, leading to resource leaks.\n- Using `fork()` for heavy CPU tasks without pooling.\n\n**Edge Cases:**\n- `SharedArrayBuffer` requires cross-origin isolation in browsers, but works in Node.js.\n- Worker threads share the same libuv thread pool? Each worker has its own pool.\n- Cluster workers listen on same port; OS load balances.\n\n**Interview Follow-ups:**\n- *\"How does cluster module achieve port sharing?\"* – Master creates socket, sends handle to workers.\n- *\"Can worker threads share database connections?\"* – No, each thread has its own event loop; use connection pool per thread.\n\n**Best Practices:**\n- Use cluster for scalability (HTTP servers).\n- Use worker threads for CPU-bound tasks (image processing, crypto).\n- Use child processes for running external commands or scripts.\n- Implement worker pools to avoid spawning new threads per request.\n\n**Security Considerations:**\n- Child processes inherit environment variables; sanitize.\n- Worker threads share memory; use Atomics for synchronization.\n- Cluster IPC can be intercepted; use trusted communication.\n\n**Performance Considerations:**\n- Worker threads have lower overhead than child processes (no new V8 instance).\n- Clustering uses separate memory, more overhead but better fault isolation.\n- For CPU work, worker threads ≈ child processes in speed, but memory sharing reduces duplication.\n\n**Scalability Considerations:**\n- Cluster scales horizontally across processes and machines.\n- Worker threads scale within a process (best for shared memory tasks).\n- Use both: cluster for cores, worker threads for concurrency within each.\n\n**Production Recommendations:**\n- Use PM2 cluster mode (built-in load balancing).\n- Use `worker_threads` pool (e.g., `piscina` module).\n- For child processes, use `execa` or `@sindresorhus\u002Fchild-process`.\n\n**Latest Node.js Patterns:**\n- `worker_threads` `move` transfer objects to avoid copy.\n- `cluster` module has `cluster.schedulingPolicy` for round-robin.\n\n**Debugging Tips:**\n- Attach debugger to worker threads: `$ NODE_OPTIONS='--inspect' node app.js` then connect to different ports.\n- Use `ps aux | grep node` to see cluster processes.\n\n**Interview Tip:**\nExplain that clustering is for scaling, worker threads for parallelism, child processes for isolation.\n\n**Common Follow-up:**\n*\"How do you handle uncaught exceptions in worker threads?\"* – Listen to `error` event; worker will exit; restart from pool.\n\n**Real-world Example:**\nA video transcoding service uses: cluster for HTTP load balancing, each worker uses a pool of worker threads to transcode multiple videos concurrently.\n\n**Tags:** [\"worker-threads\", \"cluster\", \"child-process\", \"concurrency\", \"scaling\"]",[196,213,203,197,214],{"id":361,"category":326,"question":362,"answer":363,"level":345,"tags":364},52,"Memory leaks in Node.js: causes, detection, and prevention.","**Concept Explanation:**\nA memory leak occurs when memory that is no longer needed is not released, causing the application's memory usage to grow over time, eventually leading to out-of-memory errors and process termination.\n\n**Common Causes:**\n1. **Global variables:** Accidentally creating global variables that persist.\n2. **Event listeners not removed:** Listeners attached to `EventEmitter` or DOM (in browser) not detached.\n3. **Closures holding references:** Functions retaining references to large objects.\n4. **Caches without eviction:** Unlimited cache growth.\n5. **Timers not cleared:** `setInterval` that never gets cleared.\n6. **Promises with unresolved references.**\n7. **Large buffers not garbage collected.**\n\n**Internal Working (V8 GC):**\nV8 uses generational garbage collection: young generation (scavenge) and old generation (mark-sweep, mark-compact). Leaks typically occur when objects are mistakenly kept alive by references in the old generation.\n\n**Detecting Leaks:**\n- Monitor `process.memoryUsage().heapUsed` over time.\n- Use `--inspect` and Chrome DevTools heap snapshots.\n- Use `clinic heap` tool.\n- Use `node-memwatch` or `@airbnb\u002Fnode-memwatch`.\n\n**Code Examples – Leaking Scenarios:**\n```javascript\n\u002F\u002F 1. Global variable leak\nlet cache = [];\nfunction leakMemory() {\n  cache.push(new Array(1000000)); \u002F\u002F grows indefinitely\n}\n\n\u002F\u002F 2. Event listener leak\nconst EventEmitter = require('events');\nclass MyEmitter extends EventEmitter {}\nconst emitter = new MyEmitter();\nfunction addListener() {\n  emitter.on('data', () => {\n    console.log('listener');\n  });\n}\nsetInterval(addListener, 100); \u002F\u002F listeners accumulate\n\n\u002F\u002F 3. Timer leak\nconst largeObject = new Array(1000000);\nsetInterval(() => {\n  \u002F\u002F largeObject is referenced in closure\n  console.log('timer');\n}, 1000); \u002F\u002F timer holds reference\n\n\u002F\u002F 4. Unbounded cache\nconst cacheMap = new Map();\napp.get('\u002Fcache\u002F:key', (req, res) => {\n  cacheMap.set(req.params.key, new Array(100000));\n  res.send('cached');\n});\n```\n\n**Detecting with Heap Snapshots:**\n```javascript\n\u002F\u002F Run with --inspect\n\u002F\u002F Then take heap snapshots before and after operation, compare.\nconst v8 = require('v8');\nconsole.log(v8.getHeapStatistics());\n\n\u002F\u002F Force GC (requires --expose-gc)\nif (global.gc) {\n  global.gc();\n  console.log('GC forced');\n}\n```\n\n**Prevention Patterns:**\n```javascript\n\u002F\u002F 1. Use weak maps for caches\nconst weakCache = new WeakMap(); \u002F\u002F keys must be objects\n\n\u002F\u002F 2. LRU cache with size limit\nconst LRU = require('lru-cache');\nconst cache = new LRU({ max: 100, maxAge: 1000 * 60 });\n\n\u002F\u002F 3. Remove event listeners\nfunction handler() { \u002F* ... *\u002F }\nemitter.on('event', handler);\nemitter.off('event', handler); \u002F\u002F or removeListener\n\n\u002F\u002F 4. Clear timers\nconst interval = setInterval(() => {}, 1000);\nclearInterval(interval);\n\n\u002F\u002F 5. Use `once` for single-use events\nemitter.once('data', handler);\n\n\u002F\u002F 6. Avoid large closures in loops\nfor (let i = 0; i \u003C 1000000; i++) {\n  \u002F\u002F Bad: function inside loop captures outer scope\n  setTimeout(() => console.log(i), 1000);\n}\n\u002F\u002F Good: use let or pass as parameter\n```\n\n**Practical Example – Leak Detection with Clinic:**\n```bash\nnpm install -g clinic\nclinic heap -- node app.js\n# Then run load test, open generated HTML report\n```\n\n**Common Mistakes:**\n- Assuming `delete` frees memory (it removes property, but object may persist).\n- Not nullifying references after use.\n- Forgetting that `Array` and `Map` hold strong references.\n\n**Edge Cases:**\n- Memory may not be freed immediately; GC runs heuristically.\n- Node.js has memory limits (default ~1.4GB); beyond that crashes.\n- Native addon leaks are invisible to V8 GC.\n\n**Interview Follow-ups:**\n- *\"How does the garbage collector work in Node.js?\"*\n- *\"What tools do you use to find memory leaks?\"*\n\n**Best Practices:**\n- Use `const` and `let` to avoid accidental globals.\n- Implement cache expiration or size limits.\n- Remove event listeners in `close` or `destroy` methods.\n- Use `WeakMap` and `WeakSet` for caches that shouldn't prevent GC.\n- Regularly run load tests to detect leaks.\n\n**Security Considerations:**\n- Memory leaks can lead to DoS (process restarts, but downtime).\n- Leaks may expose sensitive data if memory is not cleared.\n\n**Performance Considerations:**\n- Frequent GC pauses affect throughput (use `--trace-gc` to monitor).\n- Larger heap means longer GC pauses.\n\n**Scalability Considerations:**\n- In clustered apps, a leak in one worker may cause it to restart, affecting capacity.\n- Use process managers to restart workers at memory thresholds.\n\n**Production Recommendations:**\n- Set `--max-old-space-size` to limit heap.\n- Use `--trace-gc` to log garbage collection.\n- Monitor `memoryUsage()` and alert on growth.\n- Restart processes periodically (e.g., daily) to mitigate leaks.\n\n**Latest Node.js Patterns:**\n- `FinalizationRegistry` for cleanup callbacks when objects are GC'd.\n- `WeakRef` for weak references.\n\n**Debugging Tips:**\n```javascript\nconst memwatch = require('@airbnb\u002Fnode-memwatch');\nmemwatch.on('leak', (info) => {\n  console.log('Leak detected:', info);\n});\n```\n\n**Interview Tip:**\nExplain that memory leaks are often caused by accidental references; use heap snapshots to find \"retainers\".\n\n**Common Follow-up:**\n*\"How do you inspect what objects are in memory?\"* – Use Chrome DevTools `--inspect`, take heap snapshot, analyze retained size.\n\n**Real-world Example:**\nA long-running WebSocket server leaked listeners per connection because `socket.on('data', handler)` was never removed. Adding `socket.on('close', () => socket.removeAllListeners())` fixed the leak.\n\n**Tags:** [\"memory-leaks\", \"garbage-collection\", \"heap\", \"debugging\"]",[330,365,366,331],"garbage-collection","heap",{"id":368,"category":369,"question":370,"answer":371,"level":345,"tags":372},53,"Performance","Performance optimization techniques for Node.js applications.","**Concept Explanation:**\nNode.js performance optimization involves reducing latency, increasing throughput, minimizing memory usage, and keeping the event loop responsive. Optimization should be data-driven: measure, identify bottlenecks, optimize, measure again.\n\n**Key Areas:**\n- Event loop responsiveness\n- CPU profiling\n- Memory optimization\n- I\u002FO optimization\n- Caching strategies\n- Database query optimization\n- Compression and serialization\n- Load balancing and scaling\n\n**Event Loop Optimization:**\n```javascript\n\u002F\u002F Avoid blocking the event loop\n\u002F\u002F Bad: synchronous file read\nconst data = fs.readFileSync('large.json');\n\n\u002F\u002F Good: async\nfs.promises.readFile('large.json').then(data => ...);\n\n\u002F\u002F Break up CPU-intensive work\nfunction processChunks(array, processFn, callback) {\n  let index = 0;\n  function next() {\n    if (index >= array.length) return callback();\n    const chunk = array.slice(index, index + 100);\n    processFn(chunk);\n    index += 100;\n    setImmediate(next); \u002F\u002F yield to event loop\n  }\n  next();\n}\n```\n\n**Profiling with Clinic.js:**\n```bash\n# Doctor: detect event loop issues\nclinic doctor -- node app.js\n\n# Flame: CPU profiling\nclinic flame -- node app.js\n\n# Bubbleprof: async operation analysis\nclinic bubbleprof -- node app.js\n```\n\n**Caching Strategies:**\n```javascript\n\u002F\u002F In-memory cache with expiration\nconst NodeCache = require('node-cache');\nconst myCache = new NodeCache({ stdTTL: 600, checkperiod: 120 });\n\napp.get('\u002Fexpensive', (req, res) => {\n  let data = myCache.get('expensiveData');\n  if (!data) {\n    data = computeExpensiveData();\n    myCache.set('expensiveData', data);\n  }\n  res.json(data);\n});\n\n\u002F\u002F Redis cache\nconst redis = require('redis');\nconst client = redis.createClient();\nasync function getCached(key) {\n  const cached = await client.get(key);\n  if (cached) return JSON.parse(cached);\n  const data = await db.query();\n  await client.setEx(key, 3600, JSON.stringify(data));\n  return data;\n}\n```\n\n**Database Optimization:**\n- Use connection pooling (default in mongoose, pg).\n- Index frequently queried fields.\n- Use `SELECT` only needed fields, not `*`.\n- Batch multiple queries with `Promise.all`.\n\n**JSON Optimization:**\n```javascript\n\u002F\u002F Use fast-json-stringify for known schemas\nconst fastJson = require('fast-json-stringify');\nconst stringify = fastJson({\n  title: 'User',\n  type: 'object',\n  properties: { id: { type: 'number' }, name: { type: 'string' } }\n});\nres.send(stringify(user)); \u002F\u002F 2-3x faster than JSON.stringify\n```\n\n**Compression:**\n```javascript\nconst compression = require('compression');\napp.use(compression({ level: 6, threshold: 1024 })); \u002F\u002F compress >1KB\n```\n\n**Load Testing and Benchmarking:**\n```javascript\n\u002F\u002F Use autocannon for load testing\n\u002F\u002F npm install -g autocannon\n\u002F\u002F autocannon -c 100 -d 10 http:\u002F\u002Flocalhost:3000\n\n\u002F\u002F Benchmark a function\nconst { performance } = require('perf_hooks');\nconst start = performance.now();\n\u002F\u002F operation\nconst end = performance.now();\nconsole.log(`Time: ${end - start}ms`);\n```\n\n**Practical Example – Optimized Express Server:**\n```javascript\nconst express = require('express');\nconst compression = require('compression');\nconst helmet = require('helmet');\nconst rateLimit = require('express-rate-limit');\nconst app = express();\n\n\u002F\u002F Middleware order matters\napp.use(helmet());\napp.use(compression());\napp.use(express.json({ limit: '1mb' }));\napp.use(rateLimit({ windowMs: 60 * 1000, max: 100 }));\n\n\u002F\u002F Static files with caching\napp.use('\u002Fstatic', express.static('public', { maxAge: '1d' }));\n\n\u002F\u002F Use clustering\nconst cluster = require('cluster');\nif (cluster.isMaster) {\n  for (let i = 0; i \u003C os.cpus().length; i++) cluster.fork();\n} else {\n  app.listen(3000);\n}\n```\n\n**Common Mistakes:**\n- Premature optimization without profiling.\n- Caching everything (memory blow-up).\n- Using synchronous methods in production.\n- Not using connection pooling.\n\n**Edge Cases:**\n- High memory usage due to large JSON payloads – use streaming.\n- Event loop blocking by `console.log` in loops.\n\n**Interview Follow-ups:**\n- *\"How do you profile a Node.js app in production?\"*\n- *\"What is the difference between micro-optimizations and algorithmic optimization?\"*\n\n**Best Practices:**\n- Measure first, optimize second.\n- Use async\u002Fawait for better performance than raw promises? (negligible difference).\n- Use `--max-old-space-size` to set memory limit.\n- Enable `NODE_ENV=production` (caches module, faster).\n\n**Security Considerations:**\n- Rate limiting to prevent DoS.\n- Compression attacks (CRIME\u002FBREACH) – disable for sensitive data.\n\n**Performance Considerations:**\n- Each middleware adds overhead; remove unused.\n- Use `fast-json-stringify` for high-traffic JSON APIs.\n- Use `pino` for logging (fastest).\n\n**Scalability Considerations:**\n- Horizontal scaling (clusters, container orchestration).\n- Vertical scaling (more CPU\u002Fmemory).\n\n**Production Recommendations:**\n- Set up monitoring (Prometheus + Grafana).\n- Use APM tools (Datadog, New Relic).\n- Run regular load tests.\n\n**Latest Node.js Patterns:**\n- `perf_hooks` `performance` API.\n- `node:diagnostics_channel` for performance instrumentation.\n\n**Debugging Tips:**\n- `node --prof` then `node --prof-process` for CPU profile.\n- `node --trace-opt` to see V8 optimizations.\n\n**Interview Tip:**\nAlways start with profiling before optimizing. Don't guess.\n\n**Common Follow-up:**\n*\"How do you optimize database queries in Node.js?\"* – Use indexes, projection, connection pooling, and avoid N+1 queries.\n\n**Real-world Example:**\nA real-time dashboard reduced latency from 200ms to 15ms by adding a Redis cache, enabling compression, and using `Promise.all` for parallel API calls.\n\n**Tags:** [\"performance\", \"optimization\", \"profiling\", \"caching\", \"scaling\"]",[47,323,322,179,214],{"id":374,"category":375,"question":376,"answer":377,"level":345,"tags":378},54,"Microservices","Building microservices with Node.js: communication patterns (REST, gRPC, message queues).","**Concept Explanation:**\nMicroservices architecture decomposes an application into small, independent services. In Node.js, services can communicate via synchronous protocols (HTTP\u002FREST, gRPC) or asynchronous message brokers (RabbitMQ, Kafka). Each has trade-offs in latency, coupling, and complexity.\n\n**Communication Patterns:**\n1. **REST\u002FHTTP:** Simple, widely adopted, but high latency and tight coupling (services need to know each other's URLs).\n2. **gRPC:** High-performance, binary protocol, supports streaming, but requires protobuf definitions.\n3. **Message Queues:** Asynchronous, decoupled, durable, but adds complexity.\n\n**REST Example (Express):**\n```javascript\n\u002F\u002F order-service (caller)\nconst axios = require('axios');\nasync function getUser(userId) {\n  const response = await axios.get(`http:\u002F\u002Fuser-service\u002Fusers\u002F${userId}`);\n  return response.data;\n}\n```\n\n**gRPC Implementation:**\n```protobuf\n\u002F\u002F user.proto\nservice UserService {\n  rpc GetUser (GetUserRequest) returns (User) {}\n}\nmessage GetUserRequest { int32 id = 1; }\nmessage User { int32 id = 1; string name = 2; }\n```\n```javascript\n\u002F\u002F server.js\nconst grpc = require('@grpc\u002Fgrpc-js');\nconst protoLoader = require('@grpc\u002Fproto-loader');\nconst packageDefinition = protoLoader.loadSync('user.proto');\nconst userProto = grpc.loadPackageDefinition(packageDefinition).UserService;\n\nconst server = new grpc.Server();\nserver.addService(userProto.service, {\n  getUser: (call, callback) => {\n    callback(null, { id: call.request.id, name: 'John' });\n  }\n});\nserver.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {\n  server.start();\n});\n```\n\n**Message Queue (RabbitMQ with amqplib):**\n```javascript\n\u002F\u002F producer (order service)\nconst amqp = require('amqplib');\nasync function publishOrder(order) {\n  const connection = await amqp.connect('amqp:\u002F\u002Flocalhost');\n  const channel = await connection.createChannel();\n  await channel.assertQueue('orders');\n  channel.sendToQueue('orders', Buffer.from(JSON.stringify(order)));\n  await channel.close();\n  await connection.close();\n}\n\n\u002F\u002F consumer (payment service)\nasync function consumeOrders() {\n  const connection = await amqp.connect('amqp:\u002F\u002Flocalhost');\n  const channel = await connection.createChannel();\n  await channel.assertQueue('orders');\n  channel.consume('orders', (msg) => {\n    const order = JSON.parse(msg.content.toString());\n    processPayment(order);\n    channel.ack(msg);\n  });\n}\n```\n\n**Practical Example – Hybrid Microservice (Node.js):**\n```javascript\n\u002F\u002F API Gateway (Express) forwards to services\nconst express = require('express');\nconst amqp = require('amqplib');\nconst app = express();\n\nlet channel;\n(async () => {\n  const conn = await amqp.connect('amqp:\u002F\u002Flocalhost');\n  channel = await conn.createChannel();\n})();\n\napp.post('\u002Forders', async (req, res) => {\n  const order = req.body;\n  \u002F\u002F Publish to queue (async)\n  channel.sendToQueue('order.created', Buffer.from(JSON.stringify(order)));\n  res.status(202).json({ message: 'Order accepted' });\n});\n\napp.get('\u002Forders\u002F:id', async (req, res) => {\n  \u002F\u002F Sync call to order-service via gRPC\n  const order = await grpcClient.getOrder({ id: req.params.id });\n  res.json(order);\n});\n```\n\n**Service Discovery (Consul, etcd):**\n```javascript\n\u002F\u002F Using consul for service discovery\nconst consul = require('consul')();\nconsul.agent.service.register({\n  name: 'user-service',\n  address: 'localhost',\n  port: 3001,\n  check: { http: 'http:\u002F\u002Flocalhost:3001\u002Fhealth', interval: '10s' }\n});\n\n\u002F\u002F Discover service\nconst services = await consul.catalog.service.nodes('user-service');\nconst url = `http:\u002F\u002F${services[0].ServiceAddress}:${services[0].ServicePort}`;\n```\n\n**Common Mistakes:**\n- Synchronous communication leading to cascading failures.\n- Not implementing circuit breakers (e.g., `opossum`).\n- Shared database between services (coupling).\n- Ignoring idempotency with message queues.\n\n**Edge Cases:**\n- Network partitions: use retries with exponential backoff.\n- Message duplication: design idempotent consumers.\n- Service versioning: use API versioning or proto versioning.\n\n**Interview Follow-ups:**\n- *\"When would you choose message queue over HTTP?\"*\n- *\"How do you handle distributed transactions?\"* (Saga pattern)\n\n**Best Practices:**\n- Use API gateway for cross-cutting concerns (auth, logging).\n- Implement health checks and readiness probes.\n- Use distributed tracing (OpenTelemetry, Jaeger).\n- Prefer async messaging for operations that don't need immediate response.\n\n**Security Considerations:**\n- Mutual TLS for gRPC.\n- Authentication at API gateway.\n- Encrypt message queues (TLS).\n\n**Performance Considerations:**\n- gRPC is faster than REST (binary, multiplexed).\n- Message queues add latency but decouple.\n- Use connection pooling for database and gRPC.\n\n**Scalability Considerations:**\n- Each service scales independently.\n- Message queues allow burst handling.\n- Service mesh (Istio) adds observability and control.\n\n**Production Recommendations:**\n- Use Kubernetes for orchestration.\n- Use NATS or RabbitMQ for lightweight messaging.\n- Use Kafka for event sourcing and high throughput.\n\n**Latest Node.js Patterns:**\n- `@grpc\u002Fgrpc-js` for pure JS gRPC.\n- `nestjs\u002Fmicroservices` for built-in patterns.\n\n**Debugging Tips:**\n- Use `k6` for load testing.\n- `jaeger` for distributed tracing.\n- `docker-compose` for local development.\n\n**Interview Tip:**\nExplain that microservices introduce network latency and complexity; use them only when necessary.\n\n**Common Follow-up:**\n*\"How do you handle configuration in microservices?\"* – Centralized config server (e.g., Consul, etcd, environment variables).\n\n**Real-world Example:**\nUber moved from monolithic API to microservices with gRPC for low-latency communication, and Kafka for event streaming (ride updates).\n\n**Tags:** [\"microservices\", \"grpc\", \"rabbitmq\", \"kafka\", \"distributed-systems\"]",[379,380,381,382,383],"microservices","grpc","rabbitmq","kafka","distributed-systems",{"id":385,"category":265,"question":386,"answer":387,"level":345,"tags":388},55,"Advanced security best practices: Helmet, rate limiting, CSRF, XSS, SQL\u002FNoSQL injection.","**Concept Explanation:**\nNode.js applications are vulnerable to common web attacks. Implementing security headers, input validation, rate limiting, and proper authentication prevents many attack vectors.\n\n**Helmet (Security Headers):**\n```javascript\nconst helmet = require('helmet');\napp.use(helmet()); \u002F\u002F sets 12 security headers\n\n\u002F\u002F Custom configuration\napp.use(helmet({\n  contentSecurityPolicy: {\n    directives: {\n      defaultSrc: [\"'self'\"],\n      styleSrc: [\"'self'\", 'https:\u002F\u002Ffonts.googleapis.com'],\n      scriptSrc: [\"'self'\", \"'unsafe-inline'\"]\n    }\n  },\n  hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }\n}));\n```\n\n**Rate Limiting (Prevent DDoS\u002FBrute Force):**\n```javascript\nconst rateLimit = require('express-rate-limit');\nconst slowDown = require('express-slow-down');\n\n\u002F\u002F General rate limit\nconst limiter = rateLimit({\n  windowMs: 15 * 60 * 1000, \u002F\u002F 15 minutes\n  max: 100, \u002F\u002F limit each IP to 100 requests\n  message: 'Too many requests',\n  standardHeaders: true,\n  legacyHeaders: false\n});\napp.use('\u002Fapi', limiter);\n\n\u002F\u002F Stricter for auth endpoints\nconst authLimiter = rateLimit({\n  windowMs: 15 * 60 * 1000,\n  max: 5,\n  skipSuccessfulRequests: true \u002F\u002F only count failures\n});\napp.post('\u002Flogin', authLimiter);\n\n\u002F\u002F Slow down after limits\nconst speedLimiter = slowDown({\n  windowMs: 15 * 60 * 1000,\n  delayAfter: 50,\n  delayMs: 500\n});\n```\n\n**CSRF Protection (Cross-Site Request Forgery):**\n```javascript\nconst csrf = require('csurf');\nconst cookieParser = require('cookie-parser');\n\napp.use(cookieParser());\nconst csrfProtection = csrf({ cookie: true });\n\napp.get('\u002Fform', csrfProtection, (req, res) => {\n  res.send(`\u003Cform action=\"\u002Fsubmit\" method=\"POST\">\n    \u003Cinput type=\"hidden\" name=\"_csrf\" value=\"${req.csrfToken()}\">\n    \u003Cbutton type=\"submit\">Submit\u003C\u002Fbutton>\n  \u003C\u002Fform>`);\n});\n\napp.post('\u002Fsubmit', csrfProtection, (req, res) => {\n  res.send('Data processed');\n});\n\n\u002F\u002F For API with JWT, CSRF is less relevant (use SameSite cookies)\n```\n\n**XSS Prevention (Cross-Site Scripting):**\n```javascript\n\u002F\u002F 1. Escape output (using library like `escape-html`)\nconst escapeHtml = require('escape-html');\napp.get('\u002Fuser\u002F:name', (req, res) => {\n  const safeName = escapeHtml(req.params.name);\n  res.send(`\u003Ch1>Hello ${safeName}\u003C\u002Fh1>`);\n});\n\n\u002F\u002F 2. Set Content Security Policy (helmet does this)\n\n\u002F\u002F 3. Sanitize user input (DOMPurify on client, or sanitize-html on server)\nconst sanitizeHtml = require('sanitize-html');\napp.post('\u002Fcomment', (req, res) => {\n  const clean = sanitizeHtml(req.body.comment, {\n    allowedTags: ['b', 'i', 'em', 'strong'],\n    allowedAttributes: {}\n  });\n  \u002F\u002F store clean\n});\n\n\u002F\u002F 4. Use templating engines that auto-escape (EJS, Pug, Handlebars)\n```\n\n**SQL Injection Prevention:**\n```javascript\n\u002F\u002F BAD: string concatenation\nconst query = `SELECT * FROM users WHERE email = '${req.body.email}'`;\n\n\u002F\u002F GOOD: parameterized queries (using mysql2, pg, etc.)\nconst mysql = require('mysql2');\nconst pool = mysql.createPool({ ... });\nconst [rows] = await pool.query('SELECT * FROM users WHERE email = ?', [req.body.email]);\n\n\u002F\u002F Using Knex.js query builder\nconst users = await knex('users').where('email', req.body.email);\n\n\u002F\u002F Using ORM (Sequelize, TypeORM, Prisma) – automatically parameterized\nconst user = await User.findOne({ where: { email: req.body.email } });\n```\n\n**NoSQL Injection Prevention (MongoDB):**\n```javascript\n\u002F\u002F BAD: using $where with user input\nUser.find({ $where: `this.name === '${req.body.name}'` });\n\n\u002F\u002F GOOD: use Mongoose schema and sanitized input\nconst user = await User.findOne({ name: req.body.name });\n\n\u002F\u002F Prevent operator injection: don't pass entire query object from body\n\u002F\u002F BAD: User.create(req.body) – attacker can send { $ne: null }\n\n\u002F\u002F GOOD: whitelist fields\nconst { name, email } = req.body;\nUser.create({ name, email });\n```\n\n**Practical Example – Secure Express App:**\n```javascript\nconst express = require('express');\nconst helmet = require('helmet');\nconst rateLimit = require('express-rate-limit');\nconst csrf = require('csurf');\nconst mongoSanitize = require('express-mongo-sanitize');\nconst xss = require('xss-clean');\nconst hpp = require('hpp');\n\nconst app = express();\n\n\u002F\u002F Security middleware\napp.use(helmet());\napp.use(mongoSanitize()); \u002F\u002F prevents $ injection\napp.use(xss()); \u002F\u002F sanitizes user input\napp.use(hpp()); \u002F\u002F prevents HTTP parameter pollution\n\n\u002F\u002F Rate limiting\nconst limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 });\napp.use('\u002Fapi', limiter);\n\n\u002F\u002F Body parsers with size limit\napp.use(express.json({ limit: '10kb' }));\n\n\u002F\u002F Cookie parser with CSRF\nconst cookieParser = require('cookie-parser');\napp.use(cookieParser());\napp.use(csrf({ cookie: true }));\n\n\u002F\u002F Secure headers\napp.use((req, res, next) => {\n  res.setHeader('X-Content-Type-Options', 'nosniff');\n  res.setHeader('X-Frame-Options', 'DENY');\n  res.setHeader('X-XSS-Protection', '1; mode=block');\n  next();\n});\n```\n\n**Common Mistakes:**\n- Relying solely on helmet (needs proper configuration).\n- Not validating input type (e.g., expecting number but getting object).\n- Storing sensitive data in JWT payload (it's base64 encoded, not encrypted).\n- Disabling CSRF protection for API endpoints that use cookies.\n\n**Edge Cases:**\n- GraphQL endpoints need custom rate limiting (per field).\n- File uploads need separate validation (file type, size).\n- CORS misconfiguration can expose APIs.\n\n**Interview Follow-ups:**\n- *\"What is the difference between XSS and CSRF?\"*\n- *\"How does parameterized query prevent SQL injection?\"*\n\n**Best Practices:**\n- Use `helmet` with strict CSP.\n- Validate all input (Joi, Zod) – both type and content.\n- Use prepared statements for SQL; sanitize for NoSQL.\n- Implement rate limiting per endpoint.\n- Use `cookie-parser` with `httpOnly`, `secure`, `sameSite` flags.\n\n**Security Considerations:**\n- Enable `trust proxy` if behind reverse proxy for correct IP rate limiting.\n- Rotate secrets and API keys.\n- Use `npm audit` and `snyk` to find vulnerable dependencies.\n\n**Performance Considerations:**\n- Rate limiting adds small overhead; use in-memory store for development, Redis for production.\n- Helmet has negligible overhead.\n\n**Scalability Considerations:**\n- Use Redis for shared rate limiting across multiple instances.\n- CSRF tokens stored in cookies are stateless; no scalability issue.\n\n**Production Recommendations:**\n- Use API gateway for centralized security (rate limiting, WAF).\n- Enable HTTPS with HSTS.\n- Run security scanners (OWASP ZAP).\n\n**Latest Node.js Patterns:**\n- `express-rate-limit` with Redis store.\n- `helmet` v7 with default CSP.\n\n**Debugging Tips:**\n- Test with `curl` to see security headers.\n- Use browser DevTools to check CSP violations.\n- Log rate limit hits.\n\n**Interview Tip:**\nShow that you understand defense in depth: not relying on a single security measure.\n\n**Common Follow-up:**\n*\"How do you protect against brute force login attacks?\"* – Rate limiting + CAPTCHA + account lockout after failures.\n\n**Real-world Example:**\nGitHub uses CSRF tokens for state-changing requests, rate limiting for API, and CSP to prevent XSS.\n\n**Tags:** [\"security\", \"helmet\", \"csrf\", \"xss\", \"sql-injection\", \"rate-limiting\"]",[189,389,390,391,392,269],"helmet","csrf","xss","sql-injection",{"id":394,"category":395,"question":396,"answer":397,"level":345,"tags":398},56,"V8 Internals","Explain V8 internals: Ignition interpreter, TurboFan compiler, hidden classes, and inline caching.","**Concept Explanation:**\nV8 is Google's JavaScript engine used by Node.js. It compiles JavaScript to machine code using a multi-tier approach: Ignition (interpreter) generates bytecode, and TurboFan (optimizing compiler) generates highly optimized machine code for hot functions. Hidden classes and inline caching optimize property access.\n\n**Internal Working - Compilation Pipeline:**\n1. **Parsing:** Source code → AST (Abstract Syntax Tree).\n2. **Ignition:** AST → Bytecode (executed initially).\n3. **TurboFan:** Identifies hot functions (called many times) and compiles them to optimized machine code.\n4. **Deoptimization:** If assumptions made by TurboFan are invalidated (e.g., variable type changes), code falls back to Ignition bytecode.\n\n**Hidden Classes (Maps):**\nV8 attaches a hidden class to each object, describing its layout. Objects with the same property order and type share the same hidden class, enabling fast property access via offsets.\n```javascript\nfunction Point(x, y) {\n  this.x = x; \u002F\u002F hidden class transition\n  this.y = y; \u002F\u002F another transition\n}\nconst p1 = new Point(1, 2);\nconst p2 = new Point(3, 4); \u002F\u002F same hidden class as p1\n\u002F\u002F Fast: property access uses known offset\nconsole.log(p1.x);\n```\n\n**Inline Caching (IC):**\nV8 caches the result of property lookups at call sites. If the same hidden class is seen repeatedly, the cache hits, avoiding expensive lookups.\n\n**Code Example - Optimizing for V8:**\n```javascript\n\u002F\u002F Good: consistent property initialization\nclass User {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n}\n\n\u002F\u002F Bad: adding properties after creation (changes hidden class)\nconst user = { name: 'Alice' };\nuser.age = 30; \u002F\u002F hidden class transition, slower\nuser.email = 'alice@example.com'; \u002F\u002F another transition\n\n\u002F\u002F Good: monomorphic function calls (same type arguments)\nfunction add(a, b) { return a + b; }\nadd(1, 2); \u002F\u002F numbers\nadd(3, 4); \u002F\u002F numbers - monomorphic (fast)\n\n\u002F\u002F Bad: polymorphic (different types)\nadd(1, 2); \u002F\u002F numbers\nadd('a', 'b'); \u002F\u002F strings - polymorphic (slower)\n```\n\n**Deoptimization Example:**\n```javascript\nfunction sum(arr) {\n  let total = 0;\n  for (let i = 0; i \u003C arr.length; i++) {\n    total += arr[i];\n  }\n  return total;\n}\n\u002F\u002F V8 optimizes assuming arr[i] is always number\nsum([1, 2, 3]); \u002F\u002F optimized\nsum([1, '2', 3]); \u002F\u002F deoptimizes because string encountered\n```\n\n**Practical Example - Measuring Performance:**\n```bash\nnode --trace-opt --trace-deopt script.js\n```\n\n**Common Mistakes:**\n- Changing object shape after creation (add\u002Fdelete properties).\n- Using `delete` (forces slow dictionary mode).\n- Mixing many types in function arguments (polymorphism).\n- Creating objects in loops with different property order.\n\n**Edge Cases:**\n- Large objects with many properties (> 1000) may use dictionary mode regardless.\n- `eval()` and `with()` disable most optimizations.\n\n**Interview Follow-ups:**\n- *\"How does V8 handle array optimizations?\"*\n- *\"What is the difference between monomorphic, polymorphic, and megamorphic calls?\"*\n\n**Best Practices:**\n- Initialize all object properties in constructor.\n- Keep function signatures consistent (same types).\n- Avoid `delete`; set property to `undefined` instead.\n- Use `class` syntax for consistent hidden classes.\n\n**Security Considerations:**\n- Deoptimization can be triggered by malicious input to degrade performance (DoS).\n\n**Performance Considerations:**\n- Monomorphic calls are fastest; megamorphic calls slow down significantly.\n- Avoid large try-catch blocks inside hot functions.\n\n**Scalability Considerations:**\n- Each Node.js process has its own V8 instance; memory overhead per process.\n\n**Production Recommendations:**\n- Use `--trace-opt-verbose` to see optimized functions.\n- Profile with `--prof` and `--prof-process`.\n\n**Latest Node.js Patterns:**\n- V8 11+ has Sparkplug (mid-tier compiler) for faster startup.\n- Maglev compiler (still experimental) for mid-tier optimization.\n\n**Debugging Tips:**\n```javascript\n\u002F\u002F V8 debug flags (run with --allow-natives-syntax)\n%OptimizeFunctionOnNextCall(sum);\nsum([1,2,3]);\n%DebugPrint(sum);\n```\n\n**Interview Tip:**\nExplain that V8's optimizations make JavaScript fast, but understanding hidden classes helps write efficient code.\n\n**Common Follow-up:**\n*\"How does V8 handle array of mixed types?\"* – May transition to dictionary mode or use slow path.\n\n**Real-world Example:**\nA high-frequency trading app ensured all order objects had identical property order (timestamp, symbol, price, quantity) to maintain hidden classes and achieve 2x throughput.\n\n**Tags:** [\"v8\", \"hidden-classes\", \"inline-caching\", \"turbo-fan\", \"ignition\"]",[45,399,400,401,402],"hidden-classes","inline-caching","turbo-fan","ignition",{"id":404,"category":75,"question":405,"answer":406,"level":345,"tags":407},57,"Deep dive: Streams internals, backpressure handling, and custom implementation.","**Concept Explanation:**\nNode.js streams are implemented in the `stream` module, which provides an abstract API for handling streaming data. Internally, streams use buffers, highWaterMark thresholds, and the `pipe` method to manage backpressure. Custom streams require implementing `_read`, `_write`, or `_transform` methods.\n\n**Internal Working - Readable Stream State:**\n- `readableState.buffer`: Buffer of chunks not yet consumed.\n- `readableState.length`: Total size of buffered data (bytes or objects).\n- `readableState.highWaterMark`: Threshold that triggers `pause`.\n- `readableState.flowing`: null (not started), false (paused), true (flowing).\n\n**Backpressure Algorithm (Readable → Writable):**\n1. `readable.pipe(writable)` attaches data listener.\n2. On `data` event, writable.write(chunk) returns `false` if internal buffer > highWaterMark.\n3. Readable pauses (emits `pause` event).\n4. Writable drains (buffer \u003C highWaterMark), emits `drain` event.\n5. Readable resumes (emits `resume` event).\n\n**Custom Readable Implementation:**\n```javascript\nconst { Readable } = require('stream');\n\nclass RandomNumberStream extends Readable {\n  constructor(options) {\n    super(options);\n    this.max = 10;\n    this.count = 0;\n  }\n  _read(size) {\n    if (this.count >= this.max) {\n      this.push(null); \u002F\u002F end\n      return;\n    }\n    \u002F\u002F Simulate async data source\n    setTimeout(() => {\n      const chunk = Math.floor(Math.random() * 100);\n      this.push(`${chunk}\\n`);\n      this.count++;\n    }, 100);\n  }\n}\n\nconst rs = new RandomNumberStream();\nrs.pipe(process.stdout);\n```\n\n**Custom Writable with Backpressure:**\n```javascript\nconst { Writable } = require('stream');\n\nclass SlowWritable extends Writable {\n  _write(chunk, encoding, callback) {\n    \u002F\u002F Simulate slow destination (e.g., network)\n    setTimeout(() => {\n      console.log(`Wrote: ${chunk.toString().trim()}`);\n      callback();\n    }, 500);\n  }\n}\n\nconst ws = new SlowWritable({ highWaterMark: 1 });\nws.write('A'); \u002F\u002F returns false (backpressure)\nws.on('drain', () => console.log('Drained, can write more'));\n```\n\n**Custom Transform Stream (with async):**\n```javascript\nconst { Transform } = require('stream');\n\nclass UpperCaseTransform extends Transform {\n  _transform(chunk, encoding, callback) {\n    \u002F\u002F Async processing\n    const result = chunk.toString().toUpperCase();\n    this.push(result);\n    callback();\n  }\n  _flush(callback) {\n    \u002F\u002F Called before stream ends\n    this.push('\\n---END---\\n');\n    callback();\n  }\n}\n\nconst upper = new UpperCaseTransform();\nprocess.stdin.pipe(upper).pipe(process.stdout);\n```\n\n**Backpressure Simulation:**\n```javascript\nconst fs = require('fs');\nconst rs = fs.createReadStream('large.txt', { highWaterMark: 64 * 1024 });\nconst ws = fs.createWriteStream('out.txt', { highWaterMark: 16 * 1024 });\n\nrs.on('data', (chunk) => {\n  const canWrite = ws.write(chunk);\n  if (!canWrite) {\n    console.log('Backpressure, pausing read stream');\n    rs.pause();\n    ws.once('drain', () => {\n      console.log('Drained, resuming');\n      rs.resume();\n    });\n  }\n});\n```\n\n**Practical Example - Stream Pipeline with Error Handling:**\n```javascript\nconst { pipeline } = require('stream\u002Fpromises');\nconst fs = require('fs');\nconst zlib = require('zlib');\n\nasync function compressFile(input, output) {\n  try {\n    await pipeline(\n      fs.createReadStream(input),\n      zlib.createGzip(),\n      fs.createWriteStream(output)\n    );\n    console.log('Compression successful');\n  } catch (err) {\n    console.error('Pipeline failed:', err);\n  }\n}\n```\n\n**Common Mistakes:**\n- Not calling `callback()` in `_write` or `_transform` (hangs).\n- Pushing more data than highWaterMark without checking return value.\n- Not handling errors in pipeline (use `pipeline` instead of `pipe`).\n- Forgetting to call `this.push(null)` to end readable stream.\n\n**Edge Cases:**\n- Object mode streams: `highWaterMark` counts objects, not bytes.\n- `pipe` returns the destination stream, enabling chaining.\n- `unpipe` removes destination.\n\n**Interview Follow-ups:**\n- *\"How does `pipe` handle errors?\"* (It doesn't; use `pipeline`).\n- *\"What is the default highWaterMark for different stream types?\"* (16KB for non-object, 16 for object).\n\n**Best Practices:**\n- Always use `pipeline` for error handling and cleanup.\n- Implement `_destroy` to release resources.\n- Use `stream.compose` to combine multiple transforms.\n- Set `objectMode: true` for streams that deal with objects.\n\n**Security Considerations:**\n- Backpressure prevents memory exhaustion from fast producers.\n- Piped streams can lead to DoS if destination is slow and `highWaterMark` is high.\n\n**Performance Considerations:**\n- Larger `highWaterMark` reduces overhead but increases memory.\n- `_transform` should be efficient; defer heavy work to setImmediate.\n- Use `cork()` and `uncork()` to batch writes.\n\n**Scalability Considerations:**\n- Streams are per-process; for high throughput, use cluster or worker threads.\n- File streams are limited by disk I\u002FO; network streams by bandwidth.\n\n**Production Recommendations:**\n- Monitor `readableLength` and `writableLength` in metrics.\n- Use `stream.finished` to detect stream completion.\n- For large data, prefer streams over `fs.readFile`\u002F`writeFile`.\n\n**Latest Node.js Patterns:**\n- `stream\u002Fpromises` API (Node.js 15+).\n- `Readable.from(asyncIterable)` (Node.js 12+).\n- `stream.addAbortSignal` for cancellation.\n\n**Debugging Tips:**\n- Listen to `pipe`, `unpipe`, `pause`, `resume` events.\n- Log `stream.readableLength` in intervals.\n- Use `node --trace-streams` (experimental).\n\n**Interview Tip:**\nImplementing a custom stream is a great way to demonstrate understanding of backpressure and internal buffering.\n\n**Common Follow-up:**\n*\"How do you create a passthrough stream?\"* – Extend Transform and call `this.push(chunk)` in `_transform` without modification.\n\n**Real-world Example:**\nIn a log processing pipeline, a Transform stream parses log lines, filters errors, and pipes to a writable that sends to Elasticsearch. Backpressure ensures the system doesn't overload the network or Elasticsearch cluster.\n\n**Tags:** [\"streams\", \"backpressure\", \"pipe\", \"pipeline\", \"custom-streams\"]",[79,161,408,409,410],"pipe","pipeline","custom-streams",{"id":412,"category":413,"question":414,"answer":415,"level":345,"tags":416},58,"Garbage Collection","Garbage collection in Node.js: generations, memory limits, tuning, and monitoring.","**Concept Explanation:**\nV8's garbage collector (GC) manages memory automatically. It uses a generational approach: young generation (new space) for short-lived objects, old generation (old space) for long-lived objects. Understanding GC helps optimize performance and prevent memory leaks.\n\n**Generations:**\n- **Young Generation (New Space):** Divided into two semi-spaces: from-space and to-space. Scavenge algorithm copies survivors to to-space. Fast but frequent.\n- **Old Generation (Old Space):** Contains objects that survive multiple scavenges. Uses Mark-Sweep and Mark-Compact algorithms.\n\n**GC Algorithms:**\n1. **Scavenge (minor GC):** Collects young generation. Fast (\u003C1ms).\n2. **Mark-Sweep (major GC):** Marks live objects in old generation, sweeps dead ones. Pauses longer (10-100ms).\n3. **Mark-Compact (major GC):** Same as mark-sweep but compacts memory to reduce fragmentation.\n4. **Incremental GC:** Splits mark-sweep into smaller steps to reduce pause times.\n5. **Concurrent GC:** Performs some work on background threads (Node.js 12+).\n\n**Memory Limits:**\n- Default old generation limit: ~1.4GB on 64-bit, ~700MB on 32-bit.\n- New space limit: ~16MB (can be increased).\n- Can increase with `--max-old-space-size` and `--max-semi-space-size`.\n\n**Monitoring GC:**\n```javascript\n\u002F\u002F Enable GC logging\n\u002F\u002F node --trace-gc app.js\n\n\u002F\u002F Programmatic monitoring\nconst v8 = require('v8');\nconsole.log(v8.getHeapStatistics());\n\u002F*\n{\n  total_heap_size: 10000000,\n  used_heap_size: 8000000,\n  heap_size_limit: 1500000000,\n  ...\n}\n*\u002F\n\nconst { performance } = require('perf_hooks');\nconst obs = new PerformanceObserver((list) => {\n  console.log(list.getEntries());\n});\nobs.observe({ entryTypes: ['gc'] });\n```\n\n**Forcing Garbage Collection:**\n```bash\n# Run with --expose-gc flag\nnode --expose-gc app.js\n```\n```javascript\nif (global.gc) {\n  global.gc(); \u002F\u002F forces full GC\n  console.log('GC forced');\n}\n```\n\n**Tuning GC:**\n```bash\n# Increase old space to 4GB\nnode --max-old-space-size=4096 app.js\n\n# Increase new space to 32MB\nnode --max-semi-space-size=32 app.js\n\n# Reduce GC pause times (incremental marking)\nnode --max-old-space-size=2048 --incremental-marking app.js\n```\n\n**Practical Example - Monitoring Memory:**\n```javascript\nsetInterval(() => {\n  const mem = process.memoryUsage();\n  console.log({\n    rss: `${Math.round(mem.rss \u002F 1024 \u002F 1024)} MB`,\n    heapTotal: `${Math.round(mem.heapTotal \u002F 1024 \u002F 1024)} MB`,\n    heapUsed: `${Math.round(mem.heapUsed \u002F 1024 \u002F 1024)} MB`,\n    external: `${Math.round(mem.external \u002F 1024 \u002F 1024)} MB`\n  });\n}, 5000);\n```\n\n**Common Mistakes:**\n- Setting `--max-old-space-size` too high can cause container OOM.\n- Forcing GC frequently (reduces performance).\n- Ignoring external memory (Buffers, strings) which is not in V8 heap.\n\n**Edge Cases:**\n- Large Buffers allocated outside V8 heap (not tracked by GC automatically).\n- `--expose-gc` should not be used in production (performance hit).\n- Memory fragmentation can cause `heap limit exceeded` even when used memory is below limit.\n\n**Interview Follow-ups:**\n- *\"What is the difference between mark-sweep and mark-compact?\"*\n- *\"How do you reduce GC pause times in Node.js?\"*\n\n**Best Practices:**\n- Keep objects short-lived (young generation).\n- Nullify references to large objects when done.\n- Pool objects instead of allocating frequently.\n- Use streaming instead of loading entire files.\n\n**Security Considerations:**\n- Memory limits prevent DoS via excessive allocations.\n- GC can leak sensitive data if memory is not zeroed (unlikely in JS).\n\n**Performance Considerations:**\n- Frequent GC reduces throughput; increase heap size to reduce frequency.\n- Too large heap increases pause times; find balance.\n- Use `--trace-gc` to analyze GC frequency and duration.\n\n**Scalability Considerations:**\n- Each Node.js process has its own heap and GC.\n- For memory-heavy workloads, consider smaller heap per process and more processes.\n\n**Production Recommendations:**\n- Set `--max-old-space-size` to 75% of container memory.\n- Monitor GC with `--trace-gc` and log to file.\n- Use `gc-stats` npm module for real-time GC metrics.\n\n**Latest Node.js Patterns:**\n- Node.js 14+ has improved concurrent GC.\n- `--heapsnapshot-near-heap-limit` to auto-take snapshots.\n\n**Debugging Tips:**\n```bash\n# Take heap snapshot without stopping\nnode --heapsnapshot-signal=SIGUSR2 app.js\nkill -USR2 \u003Cpid>\n```\n\n**Interview Tip:**\nExplain that V8's GC is non-deterministic; optimize for low allocation rates, not precise timing.\n\n**Common Follow-up:**\n*\"How do you detect memory leaks using GC logs?\"* – Look for growing heap size after each full GC; if used memory never shrinks, likely leak.\n\n**Real-world Example:**\nA long-running WebSocket server was crashing with OOM. GC logs showed old space growing slowly. Heap snapshot revealed event listeners accumulating per connection; fixing the leak reduced memory by 90%.\n\n**Tags:** [\"garbage-collection\", \"v8\", \"memory\", \"heap\", \"gc\"]",[365,45,80,366,417],"gc",{"id":419,"category":209,"question":420,"answer":421,"level":345,"tags":422},59,"Horizontal scaling of Node.js applications: strategies, load balancing, and state management.","**Concept Explanation:**\nHorizontal scaling means running multiple instances of a Node.js app across multiple CPU cores or machines to handle increased load. This requires stateless design, shared session storage (if needed), and a load balancer to distribute requests.\n\n**Strategies:**\n1. **Cluster module:** Multi-process on single machine.\n2. **Process managers (PM2):** Handle clustering, restart, zero-downtime.\n3. **Container orchestration (Docker Swarm, Kubernetes):** Scale across machines.\n4. **Serverless (AWS Lambda):** Auto-scaling per request.\n\n**Cluster Module Deep Dive:**\n```javascript\nconst cluster = require('cluster');\nconst http = require('http');\nconst os = require('os');\n\nif (cluster.isMaster) {\n  const numCPUs = os.cpus().length;\n  console.log(`Master ${process.pid} setting up ${numCPUs} workers`);\n  \n  \u002F\u002F Fork workers\n  for (let i = 0; i \u003C numCPUs; i++) cluster.fork();\n  \n  \u002F\u002F Restart dead workers\n  cluster.on('exit', (worker, code, signal) => {\n    console.log(`Worker ${worker.process.pid} died`);\n    cluster.fork();\n  });\n  \n  \u002F\u002F Graceful shutdown\n  process.on('SIGTERM', () => {\n    for (const id in cluster.workers) {\n      cluster.workers[id].kill();\n    }\n    setTimeout(() => process.exit(0), 5000);\n  });\n} else {\n  \u002F\u002F Worker process\n  const app = require('.\u002Fapp');\n  const server = http.createServer(app);\n  server.listen(3000);\n  console.log(`Worker ${process.pid} started`);\n}\n```\n\n**Load Balancing Algorithms:**\n- **Round-robin (default in Node.js cluster):** Distributes evenly.\n- **Least connections:** Sends to worker with fewest active connections.\n- **IP hash:** Sticky sessions (useful for stateful apps).\n\n**PM2 Clustering (Simpler):**\n```bash\n# Start in cluster mode with max CPUs\npm2 start app.js -i max\n\n# Zero-downtime reload\npm2 reload app.js\n\n# Scale up\u002Fdown\npm2 scale app 8\n```\n\n**State Management for Scaling:**\n```javascript\n\u002F\u002F BAD: in-memory session (not shared across instances)\nconst sessions = new Map();\napp.post('\u002Flogin', (req, res) => {\n  sessions.set(req.body.userId, { loggedIn: true });\n});\n\n\u002F\u002F GOOD: shared session store (Redis)\nconst Redis = require('ioredis');\nconst redis = new Redis();\napp.post('\u002Flogin', async (req, res) => {\n  await redis.set(`session:${req.body.userId}`, JSON.stringify({ loggedIn: true }));\n});\n\n\u002F\u002F Using express-session with Redis\nconst session = require('express-session');\nconst RedisStore = require('connect-redis')(session);\napp.use(session({\n  store: new RedisStore({ client: redis }),\n  secret: 'secret',\n  resave: false,\n  saveUninitialized: false\n}));\n```\n\n**Reverse Proxy (Nginx) Configuration:**\n```nginx\nupstream node_cluster {\n  least_conn;\n  server 127.0.0.1:3000;\n  server 127.0.0.1:3001;\n  server 127.0.0.1:3002;\n  server 127.0.0.1:3003;\n}\n\nserver {\n  listen 80;\n  location \u002F {\n    proxy_pass http:\u002F\u002Fnode_cluster;\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n  }\n}\n```\n\n**Practical Example - Docker + Kubernetes:**\n```yaml\n# deployment.yaml\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: node-app\nspec:\n  replicas: 10\n  selector:\n    matchLabels:\n      app: node-app\n  template:\n    metadata:\n      labels:\n        app: node-app\n    spec:\n      containers:\n      - name: node-app\n        image: myapp:latest\n        ports:\n        - containerPort: 3000\n        env:\n        - name: REDIS_HOST\n          value: redis-service\n        resources:\n          requests:\n            memory: \"256Mi\"\n            cpu: \"250m\"\n          limits:\n            memory: \"512Mi\"\n            cpu: \"500m\"\n```\n\n**Common Mistakes:**\n- Storing session in memory (session affinity\u002Fsticky sessions needed).\n- Using file system for uploads (shared volume required).\n- Not setting proper timeouts for load balancer.\n- Over-scaling (too many processes cause contention).\n\n**Edge Cases:**\n- WebSocket scaling: need sticky sessions or use pub\u002Fsub (Redis) to broadcast.\n- Background jobs: avoid duplication by using distributed locks (Redlock) or separate queue.\n\n**Interview Follow-ups:**\n- *\"How do you handle WebSocket connections across multiple Node.js instances?\"*\n- *\"What is the difference between horizontal and vertical scaling?\"*\n\n**Best Practices:**\n- Design stateless services (store state in databases\u002Fcaches).\n- Use health checks for load balancer to remove unhealthy instances.\n- Implement graceful shutdown to drain connections.\n- Use connection pooling for databases.\n\n**Security Considerations:**\n- Load balancer should handle SSL termination.\n- Ensure shared caches (Redis) are secured with authentication.\n\n**Performance Considerations:**\n- Too many processes can increase context switching overhead.\n- Use `os.cpus().length` as a starting point; benchmark to find optimum.\n- Cluster module uses IPC; overhead is minimal.\n\n**Scalability Considerations:**\n- Horizontal scaling is the primary method for Node.js.\n- Use autoscaling based on CPU\u002Fmemory metrics.\n- For extreme scale, use event-driven architecture with message queues.\n\n**Production Recommendations:**\n- Use PM2 for simple deployments, Kubernetes for complex ones.\n- Deploy behind a reverse proxy (Nginx, HAProxy).\n- Use Redis for session store and caching.\n- Set up monitoring for each instance (Prometheus, Grafana).\n\n**Latest Node.js Patterns:**\n- `cluster` module with `round-robin` scheduling (default on Linux).\n- Docker swarm for simpler orchestration than K8s.\n\n**Debugging Tips:**\n- Log instance ID (process.pid) in requests to see distribution.\n- Use `pm2 logs` to see all worker logs.\n- `kubectl exec` into pod to inspect.\n\n**Interview Tip:**\nExplain that scaling stateful vs stateless services requires different strategies; Node.js is best for stateless.\n\n**Common Follow-up:**\n*\"How do you handle file uploads in a horizontally scaled app?\"* – Upload to S3\u002FGCS directly or use shared NFS.\n\n**Real-world Example:**\nA SaaS product used PM2 cluster on a single VM, then migrated to Kubernetes with 20+ replicas, using Redis for session sharing and S3 for file storage, handling 100k concurrent users.\n\n**Tags:** [\"scaling\", \"cluster\", \"load-balancing\", \"kubernetes\", \"pm2\"]",[214,213,215,423,424],"kubernetes","pm2",{"id":426,"category":427,"question":428,"answer":429,"level":345,"tags":430},60,"Message Queues","Implementing reliable message queues with RabbitMQ and Kafka in Node.js.","**Concept Explanation:**\nMessage queues enable asynchronous, decoupled communication between services. RabbitMQ (AMQP) is good for task distribution and complex routing. Kafka is optimized for high-throughput event streaming and replayability.\n\n**RabbitMQ Core Concepts:**\n- **Producer:** Sends messages to exchange.\n- **Exchange:** Routes messages to queues (direct, topic, fanout, headers).\n- **Queue:** Stores messages until consumed.\n- **Consumer:** Receives and processes messages.\n- **Acknowledgment:** Consumer confirms processing; message removed.\n\n**RabbitMQ Implementation (amqplib):**\n```javascript\nconst amqp = require('amqplib');\n\nasync function setupRabbitMQ() {\n  const connection = await amqp.connect('amqp:\u002F\u002Flocalhost');\n  const channel = await connection.createChannel();\n  \n  \u002F\u002F Durable queue (survives broker restart)\n  const queue = 'task_queue';\n  await channel.assertQueue(queue, { durable: true });\n  \n  \u002F\u002F Producer\n  async function sendTask(task) {\n    const message = JSON.stringify(task);\n    channel.sendToQueue(queue, Buffer.from(message), { persistent: true });\n    console.log('Sent:', task);\n  }\n  \n  \u002F\u002F Consumer with manual ack\n  channel.prefetch(1); \u002F\u002F process one message at a time\n  channel.consume(queue, async (msg) => {\n    if (msg) {\n      try {\n        const task = JSON.parse(msg.content.toString());\n        await processTask(task);\n        channel.ack(msg); \u002F\u002F acknowledge success\n      } catch (err) {\n        \u002F\u002F Negative ack: requeue or send to dead letter\n        channel.nack(msg, false, false); \u002F\u002F false = don't requeue\n      }\n    }\n  });\n}\n\n\u002F\u002F Fanout exchange (broadcast)\nasync function publishEvent(event) {\n  const exchange = 'events';\n  await channel.assertExchange(exchange, 'fanout', { durable: false });\n  channel.publish(exchange, '', Buffer.from(JSON.stringify(event)));\n}\n```\n\n**Kafka Core Concepts:**\n- **Topic:** Category of messages.\n- **Partition:** Ordered, immutable sequence of messages (scales horizontally).\n- **Producer:** Writes to topic partitions.\n- **Consumer:** Reads from partitions (consumer groups manage offset).\n- **Offset:** Position in partition.\n\n**Kafka with Node.js (kafkajs):**\n```javascript\nconst { Kafka } = require('kafkajs');\n\nconst kafka = new Kafka({\n  clientId: 'my-app',\n  brokers: ['localhost:9092']\n});\n\n\u002F\u002F Producer\nconst producer = kafka.producer();\nawait producer.connect();\nawait producer.send({\n  topic: 'order-events',\n  messages: [\n    { key: 'order-123', value: JSON.stringify({ id: 123, status: 'created' }) }\n  ]\n});\n\n\u002F\u002F Consumer\nconst consumer = kafka.consumer({ groupId: 'order-processor' });\nawait consumer.connect();\nawait consumer.subscribe({ topic: 'order-events', fromBeginning: false });\n\nawait consumer.run({\n  eachMessage: async ({ topic, partition, message }) => {\n    const order = JSON.parse(message.value.toString());\n    console.log(`Processing order ${order.id}`);\n    \u002F\u002F process\n    \u002F\u002F Commit offset automatically (default)\n  }\n});\n```\n\n**Practical Example – Dead Letter Queue (RabbitMQ):**\n```javascript\nasync function setupDLQ() {\n  const channel = await connection.createChannel();\n  \n  \u002F\u002F Main queue with DLQ\n  const mainQueue = 'orders';\n  const dlq = 'orders.dlq';\n  \n  await channel.assertQueue(dlq, { durable: true });\n  await channel.assertQueue(mainQueue, {\n    durable: true,\n    deadLetterExchange: '',\n    deadLetterRoutingKey: dlq\n  });\n  \n  \u002F\u002F Consumer with retries\n  channel.consume(mainQueue, async (msg) => {\n    try {\n      const order = JSON.parse(msg.content.toString());\n      await processOrder(order);\n      channel.ack(msg);\n    } catch (err) {\n      const retryCount = (msg.properties.headers?.retryCount || 0) + 1;\n      if (retryCount \u003C 3) {\n        \u002F\u002F Requeue with retry count\n        channel.publish('', mainQueue, msg.content, {\n          headers: { retryCount },\n          expiration: 60000 \u002F\u002F delay 60s\n        });\n        channel.ack(msg);\n      } else {\n        \u002F\u002F Move to DLQ automatically\n        channel.nack(msg, false, false);\n      }\n    }\n  });\n}\n```\n\n**Common Mistakes:**\n- Not acknowledging messages (memory leak in RabbitMQ).\n- Using auto-ack (lose messages on crash).\n- Not setting message timeouts for stuck consumers.\n- Kafka consumer not handling rebalances.\n\n**Edge Cases:**\n- Idempotent processing required for duplicate messages.\n- Partition rebalancing in Kafka can cause processing delays.\n- RabbitMQ can deadlock if consumers die without ack.\n\n**Interview Follow-ups:**\n- *\"When would you choose Kafka over RabbitMQ?\"*\n- *\"How do you guarantee exactly-once delivery?\"*\n\n**Best Practices:**\n- Always use persistent messages (durable queues, persistent flag).\n- Implement dead letter queues for failed messages.\n- Use idempotent consumers (deduplication keys).\n- Monitor queue lengths and consumer lag.\n\n**Security Considerations:**\n- Enable TLS for RabbitMQ\u002FKafka.\n- Use authentication and authorization (virtual hosts, ACLs).\n- Validate message schema to prevent injection.\n\n**Performance Considerations:**\n- Batch messages for Kafka producers (higher throughput).\n- Use prefetch (QoS) for RabbitMQ to avoid overloading consumers.\n- Partition count affects Kafka parallelism; choose wisely.\n\n**Scalability Considerations:**\n- Kafka scales by adding partitions and consumers.\n- RabbitMQ clustering can be complex; use mirrored queues for HA.\n- Both support horizontal scaling of consumers.\n\n**Production Recommendations:**\n- Use RabbitMQ for RPC-like task distribution, Kafka for event streams.\n- Set up monitoring (Prometheus + Grafana).\n- Implement circuit breakers for broker unavailability.\n\n**Latest Node.js Patterns:**\n- `amqplib` with promises.\n- `kafkajs` (pure JS Kafka client).\n- `@nestjs\u002Fmicroservices` for both.\n\n**Debugging Tips:**\n- Enable RabbitMQ management plugin for UI.\n- Use Kafka tools: `kafkacat`, `kcat`.\n- Log message IDs for tracing.\n\n**Interview Tip:**\nExplain the trade-off: RabbitMQ is great for complex routing and tasks; Kafka for high-volume event sourcing.\n\n**Common Follow-up:**\n*\"How do you handle message ordering in Kafka?\"* – Use same partition key (e.g., orderId) so all messages for that entity go to same partition.\n\n**Real-world Example:**\nUber uses Kafka for real-time trip events, RabbitMQ for background job distribution. Node.js services consume both.\n\n**Tags:** [\"rabbitmq\", \"kafka\", \"message-queue\", \"amqp\", \"event-driven\"]",[381,382,431,432,21],"message-queue","amqp",{"id":434,"category":310,"question":435,"answer":436,"level":345,"tags":437},61,"Advanced testing strategies: mocking, integration testing, and performance debugging with Jest.","**Concept Explanation:**\nTesting in Node.js should cover unit tests (isolated), integration tests (API, database), and performance tests. Jest is a popular framework that provides mocking, snapshot testing, and coverage. Advanced strategies include dependency injection for testability, mocking external services, and performance regression testing.\n\n**Unit Test with Jest and Mocking:**\n```javascript\n\u002F\u002F userService.js\nclass UserService {\n  constructor(userRepository) {\n    this.userRepository = userRepository;\n  }\n  async getUser(id) {\n    const user = await this.userRepository.findById(id);\n    if (!user) throw new Error('User not found');\n    return { ...user, fullName: `${user.firstName} ${user.lastName}` };\n  }\n}\n\n\u002F\u002F userService.test.js\nconst { UserService } = require('.\u002FuserService');\n\ndescribe('UserService', () => {\n  let userService;\n  let mockRepository;\n\n  beforeEach(() => {\n    mockRepository = {\n      findById: jest.fn()\n    };\n    userService = new UserService(mockRepository);\n  });\n\n  test('getUser returns user with fullName', async () => {\n    mockRepository.findById.mockResolvedValue({\n      id: 1,\n      firstName: 'John',\n      lastName: 'Doe'\n    });\n    const result = await userService.getUser(1);\n    expect(result).toEqual({ id: 1, firstName: 'John', lastName: 'Doe', fullName: 'John Doe' });\n    expect(mockRepository.findById).toHaveBeenCalledWith(1);\n  });\n\n  test('getUser throws if not found', async () => {\n    mockRepository.findById.mockResolvedValue(null);\n    await expect(userService.getUser(999)).rejects.toThrow('User not found');\n  });\n});\n```\n\n**Mocking External APIs (nock):**\n```javascript\nconst nock = require('nock');\n\n\u002F\u002F API client\nasync function fetchWeather(city) {\n  const response = await fetch(`https:\u002F\u002Fapi.weather.com\u002F${city}`);\n  return response.json();\n}\n\n\u002F\u002F Test\ntest('fetchWeather returns data', async () => {\n  const mockWeather = { temp: 25, condition: 'Sunny' };\n  nock('https:\u002F\u002Fapi.weather.com')\n    .get('\u002FLondon')\n    .reply(200, mockWeather);\n  \n  const result = await fetchWeather('London');\n  expect(result).toEqual(mockWeather);\n});\n```\n\n**Integration Testing with Supertest (Express API):**\n```javascript\nconst request = require('supertest');\nconst app = require('..\u002Fapp');\nconst mongoose = require('mongoose');\n\ndescribe('User API', () => {\n  beforeAll(async () => {\n    await mongoose.connect(process.env.TEST_DB_URL);\n  });\n  \n  afterAll(async () => {\n    await mongoose.connection.dropDatabase();\n    await mongoose.connection.close();\n  });\n  \n  test('POST \u002Fusers creates user', async () => {\n    const res = await request(app)\n      .post('\u002Fusers')\n      .send({ name: 'Alice', email: 'alice@example.com' })\n      .expect(201);\n    expect(res.body).toHaveProperty('id');\n    expect(res.body.name).toBe('Alice');\n  });\n  \n  test('GET \u002Fusers\u002F:id returns user', async () => {\n    const createRes = await request(app)\n      .post('\u002Fusers')\n      .send({ name: 'Bob', email: 'bob@example.com' });\n    const id = createRes.body.id;\n    const getRes = await request(app)\n      .get(`\u002Fusers\u002F${id}`)\n      .expect(200);\n    expect(getRes.body.name).toBe('Bob');\n  });\n});\n```\n\n**Mocking Time\u002FDates:**\n```javascript\ntest('time-based logic', () => {\n  jest.useFakeTimers();\n  jest.setSystemTime(new Date('2024-01-01'));\n  const result = getExpirationDate();\n  expect(result).toEqual(new Date('2024-02-01'));\n  jest.useRealTimers();\n});\n```\n\n**Performance Regression Testing (Benchmarking):**\n```javascript\n\u002F\u002F benchmark.js\nconst { performance } = require('perf_hooks');\n\nfunction measure(fn, iterations = 10000) {\n  const start = performance.now();\n  for (let i = 0; i \u003C iterations; i++) fn();\n  const end = performance.now();\n  return (end - start) \u002F iterations;\n}\n\ntest('should be fast', () => {\n  const avgTime = measure(() => myFunction());\n  expect(avgTime).toBeLessThan(0.5); \u002F\u002F less than 0.5ms\n});\n```\n\n**Common Mistakes:**\n- Not resetting mocks between tests (test pollution).\n- Using real databases in unit tests (use in-memory or mock).\n- Not handling async errors (use `rejects` or `try\u002Fcatch`).\n- Flaky tests due to timing (use fake timers).\n\n**Edge Cases:**\n- Testing error paths where external service times out.\n- Simulating network failures (nock can simulate errors).\n- Testing race conditions (hard; use deterministic timers).\n\n**Interview Follow-ups:**\n- *\"How do you test code that uses setTimeout?\"*\n- *\"What is the difference between mocking and stubbing?\"*\n\n**Best Practices:**\n- Use dependency injection for testability.\n- Run unit tests in CI with `--coverage` flag.\n- Use `beforeEach` to reset mocks and state.\n- Isolate tests (no shared state).\n- Write integration tests for critical paths.\n\n**Security Considerations:**\n- Never use test credentials in production.\n- Mock security modules to avoid actual authentication in tests.\n\n**Performance Considerations:**\n- Run performance tests on dedicated CI runners.\n- Use `--runInBand` to avoid parallel test interference.\n\n**Scalability Considerations:**\n- Split tests into unit vs integration to run in parallel.\n- Use test sharding (`jest --shard`).\n\n**Production Recommendations:**\n- Run unit tests on every commit, integration tests on PR.\n- Use test coverage thresholds (e.g., 80%).\n- Set up performance benchmarks in CI (fail if regression).\n\n**Latest Node.js Patterns:**\n- `jest` with ESM support (`--experimental-vm-modules`).\n- `@jest\u002Fglobals` for explicit imports.\n- `jest.preview` for debugging tests.\n\n**Debugging Tips:**\n- Use `--verbose` and `--debug` flags.\n- Run single test: `jest -t \"test name\"`.\n- Use `console.log` in tests (but use `--silent` in CI).\n\n**Interview Tip:**\nMention that testing ensures confidence in refactoring and deployment.\n\n**Common Follow-up:**\n*\"How do you test a function that makes an HTTP request?\"* – Mock the HTTP client using `nock` or `jest.mock('axios')`.\n\n**Real-world Example:**\nA payment gateway integration test mocks the bank API using nock, simulating success, failure, and timeout scenarios, ensuring the fallback logic works.\n\n**Tags:** [\"testing\", \"jest\", \"mocking\", \"integration-tests\", \"performance\"]",[252,438,315,439,47],"jest","integration-tests",{"id":441,"category":183,"question":442,"answer":443,"level":345,"tags":444},62,"Implement OAuth 2.0 and refresh token rotation in Node.js.","**Concept Explanation:**\nOAuth 2.0 is an authorization framework that allows third-party applications to access user data without sharing credentials. Refresh token rotation is a security best practice where each access token refresh returns a new refresh token, invalidating the old one. This prevents stolen refresh tokens from being used indefinitely.\n\n**Internal Working:**\n1. User authorizes application, server issues access token (short-lived) and refresh token (long-lived).\n2. Client uses access token for API calls.\n3. When access token expires, client sends refresh token to `\u002Ftoken` endpoint.\n4. Server validates refresh token, issues new access token AND new refresh token (rotation).\n5. Old refresh token is invalidated (stored in database or Redis).\n\n**Implementation with JWT and Redis:**\n```javascript\nconst jwt = require('jsonwebtoken');\nconst crypto = require('crypto');\nconst Redis = require('ioredis');\nconst redis = new Redis();\n\n\u002F\u002F Store refresh tokens with family tracking\nclass TokenService {\n  static async generateTokens(userId, familyId = crypto.randomUUID()) {\n    const accessToken = jwt.sign({ userId }, process.env.JWT_SECRET, { expiresIn: '15m' });\n    const refreshToken = jwt.sign({ userId, familyId }, process.env.REFRESH_SECRET, { expiresIn: '7d' });\n    \n    \u002F\u002F Store refresh token with family\n    await redis.setex(`refresh:${familyId}`, 7 * 24 * 3600, refreshToken);\n    await redis.setex(`user:${userId}:current_family`, 7 * 24 * 3600, familyId);\n    \n    return { accessToken, refreshToken };\n  }\n  \n  static async rotateRefreshToken(oldRefreshToken) {\n    try {\n      const decoded = jwt.verify(oldRefreshToken, process.env.REFRESH_SECRET);\n      const { userId, familyId } = decoded;\n      \n      \u002F\u002F Verify stored token matches\n      const storedToken = await redis.get(`refresh:${familyId}`);\n      if (!storedToken || storedToken !== oldRefreshToken) {\n        \u002F\u002F Possible theft - invalidate entire family\n        await this.invalidateFamily(familyId);\n        throw new Error('Token reuse detected');\n      }\n      \n      \u002F\u002F Generate new tokens (new family ID for rotation)\n      const newFamilyId = crypto.randomUUID();\n      const newTokens = await this.generateTokens(userId, newFamilyId);\n      \n      \u002F\u002F Delete old family\n      await redis.del(`refresh:${familyId}`);\n      \n      return newTokens;\n    } catch (err) {\n      throw new Error('Invalid refresh token');\n    }\n  }\n  \n  static async invalidateFamily(familyId) {\n    await redis.del(`refresh:${familyId}`);\n  }\n  \n  static async logout(userId) {\n    const currentFamily = await redis.get(`user:${userId}:current_family`);\n    if (currentFamily) await this.invalidateFamily(currentFamily);\n    await redis.del(`user:${userId}:current_family`);\n  }\n}\n\n\u002F\u002F OAuth 2.0 endpoints with Express\nconst express = require('express');\nconst app = express();\n\n\u002F\u002F Login (password grant)\napp.post('\u002Foauth\u002Ftoken', async (req, res) => {\n  const { grant_type, username, password, refresh_token } = req.body;\n  \n  if (grant_type === 'password') {\n    const user = await authenticateUser(username, password);\n    if (!user) return res.status(401).json({ error: 'Invalid credentials' });\n    const tokens = await TokenService.generateTokens(user.id);\n    res.json({ access_token: tokens.accessToken, refresh_token: tokens.refreshToken, expires_in: 900 });\n  } \n  else if (grant_type === 'refresh_token') {\n    try {\n      const tokens = await TokenService.rotateRefreshToken(refresh_token);\n      res.json({ access_token: tokens.accessToken, refresh_token: tokens.refreshToken, expires_in: 900 });\n    } catch (err) {\n      res.status(401).json({ error: 'Invalid refresh token' });\n    }\n  }\n});\n\n\u002F\u002F Protected endpoint\napp.get('\u002Fapi\u002Fuser', authenticateAccessToken, (req, res) => {\n  res.json({ userId: req.user.userId });\n});\n\n\u002F\u002F Logout\napp.post('\u002Foauth\u002Frevoke', authenticateAccessToken, async (req, res) => {\n  await TokenService.logout(req.user.userId);\n  res.status(204).send();\n});\n```\n\n**OAuth 2.0 with Google (external provider):**\n```javascript\nconst { OAuth2Client } = require('google-auth-library');\nconst client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID);\n\napp.post('\u002Fauth\u002Fgoogle', async (req, res) => {\n  const { token } = req.body;\n  const ticket = await client.verifyIdToken({\n    idToken: token,\n    audience: process.env.GOOGLE_CLIENT_ID\n  });\n  const payload = ticket.getPayload();\n  const user = await findOrCreateUser({ email: payload.email, name: payload.name });\n  const tokens = await TokenService.generateTokens(user.id);\n  res.json(tokens);\n});\n```\n\n**Common Mistakes:**\n- Storing refresh tokens in localStorage (vulnerable to XSS).\n- Not invalidating old refresh tokens after rotation.\n- Using infinite refresh token lifetime.\n- Not detecting token replay attacks.\n\n**Edge Cases:**\n- Concurrent refresh requests: use locking (Redis) to avoid race conditions.\n- Token theft detection: when old token is used after rotation, invalidate family.\n- Refresh token expiration: client must re-authenticate.\n\n**Interview Follow-ups:**\n- *\"What is the difference between OAuth 2.0 and OpenID Connect?\"*\n- *\"How do you handle refresh token theft detection?\"*\n\n**Best Practices:**\n- Use refresh token rotation with family tracking.\n- Store refresh tokens in HTTP-only, Secure, SameSite cookies.\n- Implement rate limiting on `\u002Ftoken` endpoint.\n- Use short-lived access tokens (15 min).\n\n**Security Considerations:**\n- Revoke all tokens on password change.\n- Implement device fingerprinting for token binding.\n- Use PKCE for public clients (mobile\u002FSPA).\n\n**Performance Considerations:**\n- Redis lookups are fast (\u003C1ms).\n- Token rotation adds minor overhead.\n\n**Scalability Considerations:**\n- Redis cluster for shared token storage.\n- Token families per user, not per device.\n\n**Production Recommendations:**\n- Use OAuth2 libraries like `oauth2-server` or `passport`.\n- Monitor for token replay attacks (security events).\n- Set up token cleanup jobs.\n\n**Latest Node.js Patterns:**\n- `@node-oauth\u002Foauth2-server` for full OAuth2 implementation.\n- `jose` for JWT with better algorithms.\n\n**Debugging Tips:**\n- Log familyId and userId in token operations.\n- Use `jwt.io` to decode tokens.\n- Redis CLI: `KEYS refresh:*` to see active families.\n\n**Interview Tip:**\nExplain that refresh token rotation mitigates stolen token risks because the attacker's token becomes invalid after first refresh.\n\n**Common Follow-up:**\n*\"How do you handle logout with JWT?\"* – JWT is stateless, so you must maintain a blacklist (Redis) or rely on short expiration and client-side token deletion.\n\n**Real-world Example:**\nAuth0 uses refresh token rotation by default. Each refresh returns a new token, and the previous token is revoked, preventing token replay attacks.\n\n**Tags:** [\"oauth2\", \"refresh-token\", \"jwt\", \"authentication\", \"security\"]",[445,446,187,188,189],"oauth2","refresh-token",{"id":448,"category":449,"question":450,"answer":451,"level":345,"tags":452},63,"Resilience","Resilience patterns: Circuit Breaker, Retry with exponential backoff in Node.js.","**Concept Explanation:**\nResilience patterns prevent cascading failures in distributed systems. Circuit breaker stops requests to failing services, allowing recovery. Retry with exponential backoff retries failed operations with increasing delays to avoid overwhelming the failing service.\n\n**Circuit Breaker States:**\n- **Closed:** Requests pass through. If failures exceed threshold, circuit opens.\n- **Open:** Requests fail immediately (without calling service). After timeout, circuit goes to half-open.\n- **Half-Open:** Limited requests allowed. If successful, circuit closes; if failure, re-opens.\n\n**Implementation with `opossum`:**\n```javascript\nconst CircuitBreaker = require('opossum');\n\nasync function callExternalAPI() {\n  const response = await fetch('https:\u002F\u002Fapi.example.com\u002Fdata');\n  if (!response.ok) throw new Error('API error');\n  return response.json();\n}\n\nconst options = {\n  timeout: 3000,              \u002F\u002F fail if >3s\n  errorThresholdPercentage: 50, \u002F\u002F open at 50% failure rate\n  resetTimeout: 30000,        \u002F\u002F try again after 30s\n  rollingCountTimeout: 60000, \u002F\u002F statistics window\n  rollingCountBuckets: 10,\n  name: 'external-api'\n};\n\nconst breaker = new CircuitBreaker(callExternalAPI, options);\n\n\u002F\u002F Events\nbreaker.on('open', () => console.log('Circuit opened'));\nbreaker.on('halfOpen', () => console.log('Circuit half-open'));\nbreaker.on('close', () => console.log('Circuit closed'));\n\n\u002F\u002F Using with fallback\napp.get('\u002Fdata', async (req, res) => {\n  try {\n    const result = await breaker.fire();\n    res.json(result);\n  } catch (err) {\n    \u002F\u002F Fallback response when circuit open or error\n    res.status(503).json({ error: 'Service unavailable', fallback: true });\n  }\n});\n```\n\n**Custom Circuit Breaker Implementation:**\n```javascript\nclass CircuitBreaker {\n  constructor(service, options = {}) {\n    this.service = service;\n    this.failureThreshold = options.failureThreshold || 5;\n    this.resetTimeout = options.resetTimeout || 60000;\n    this.failureCount = 0;\n    this.state = 'CLOSED';\n    this.nextAttempt = null;\n  }\n\n  async call(...args) {\n    if (this.state === 'OPEN') {\n      if (Date.now() >= this.nextAttempt) {\n        this.state = 'HALF_OPEN';\n      } else {\n        throw new Error('Circuit breaker is OPEN');\n      }\n    }\n\n    try {\n      const result = await this.service(...args);\n      this.onSuccess();\n      return result;\n    } catch (err) {\n      this.onFailure();\n      throw err;\n    }\n  }\n\n  onSuccess() {\n    if (this.state === 'HALF_OPEN') {\n      this.state = 'CLOSED';\n      this.failureCount = 0;\n    }\n  }\n\n  onFailure() {\n    this.failureCount++;\n    if (this.failureCount >= this.failureThreshold) {\n      this.state = 'OPEN';\n      this.nextAttempt = Date.now() + this.resetTimeout;\n    }\n  }\n}\n```\n\n**Retry with Exponential Backoff:**\n```javascript\nconst sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));\n\nasync function retryWithBackoff(fn, options = {}) {\n  const maxRetries = options.maxRetries || 5;\n  const baseDelay = options.baseDelay || 1000;\n  const maxDelay = options.maxDelay || 30000;\n  \n  for (let attempt = 1; attempt \u003C= maxRetries; attempt++) {\n    try {\n      return await fn();\n    } catch (err) {\n      if (attempt === maxRetries) throw err;\n      \n      \u002F\u002F Exponential backoff with jitter\n      const delay = Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);\n      const jitter = delay * 0.2 * Math.random();\n      const waitTime = delay + jitter;\n      \n      console.log(`Attempt ${attempt} failed. Retrying in ${Math.round(waitTime)}ms`);\n      await sleep(waitTime);\n    }\n  }\n}\n\n\u002F\u002F Usage\nconst result = await retryWithBackoff(\n  () => fetch('https:\u002F\u002Fapi.unreliable.com\u002Fdata'),\n  { maxRetries: 3, baseDelay: 500 }\n);\n```\n\n**Combined Pattern: Circuit Breaker + Retry:**\n```javascript\nconst { CircuitBreaker } = require('opossum');\n\nasync function callWithResilience(serviceCall) {\n  \u002F\u002F Retry with backoff before circuit breaker\n  const callWithRetry = async () => {\n    return retryWithBackoff(serviceCall, { maxRetries: 2, baseDelay: 200 });\n  };\n  \n  const breaker = new CircuitBreaker(callWithRetry, {\n    errorThresholdPercentage: 50,\n    resetTimeout: 30000\n  });\n  \n  return breaker.fire();\n}\n\n\u002F\u002F Use in Express with timeout\napp.get('\u002Fresilient', async (req, res) => {\n  try {\n    const data = await callWithResilience(() => fetchExternal());\n    res.json(data);\n  } catch (err) {\n    if (err.name === 'OpenBreakerError') {\n      res.status(503).json({ error: 'Circuit open - service degraded' });\n    } else {\n      res.status(500).json({ error: 'All retries failed' });\n    }\n  }\n});\n```\n\n**Common Mistakes:**\n- Retrying non-idempotent operations (e.g., payment) without idempotency key.\n- Using retry without backoff (can overwhelm service).\n- Circuit breaker with too low threshold (false positive).\n- Not logging circuit state changes.\n\n**Edge Cases:**\n- Idempotent vs non-idempotent operations: only retry idempotent.\n- Partial success (e.g., timeouts but data processed) – need careful handling.\n- Circuit breaker in clustered apps – use shared state (Redis) to coordinate.\n\n**Interview Follow-ups:**\n- *\"What is the difference between retry and circuit breaker?\"*\n- *\"How do you implement exponential backoff with jitter?\"*\n\n**Best Practices:**\n- Retry only idempotent operations (GET, PUT, DELETE; POST with idempotency key).\n- Use jitter to avoid thundering herd on retry.\n- Set max retry attempts and max delay.\n- Monitor circuit breaker state changes.\n\n**Security Considerations:**\n- Retry can amplify DDoS if not rate-limited.\n- Circuit breaker prevents cascading failures and gives time for recovery.\n\n**Performance Considerations:**\n- Retry adds latency; acceptable for background jobs, less so for user-facing.\n- Circuit breaker fast-fails, reducing latency during outages.\n\n**Scalability Considerations:**\n- Shared circuit breaker state across instances (Redis) prevents each instance from independently opening.\n- Use distributed circuit breaker (e.g., Hystrix).\n\n**Production Recommendations:**\n- Use `opossum` for circuit breaker, `async-retry` for retries.\n- Implement health checks to reset circuit.\n- Set timeouts at each layer (request, connection, read).\n\n**Latest Node.js Patterns:**\n- `@microsoft\u002Fsignalr` for real-time retry strategies.\n- `cockatiel` library (TypeScript-first resilience).\n\n**Debugging Tips:**\n- Log retry attempts with attempt number and delay.\n- Emit metrics (Prometheus) for circuit state.\n- Simulate failures in test environment.\n\n**Interview Tip:**\nExplain that circuit breaker prevents repeated failed requests from consuming resources, allowing the system to degrade gracefully.\n\n**Common Follow-up:**\n*\"How do you handle partial failures in a batch operation?\"* – Use retry with exponential backoff per item, with dead-letter queue for permanent failures.\n\n**Real-world Example:**\nNetflix uses Hystrix (circuit breaker) to handle dependency failures. When a database circuit opens, it serves cached responses, preventing cascading failures across microservices.\n\n**Tags:** [\"circuit-breaker\", \"retry\", \"resilience\", \"backoff\", \"opossum\"]",[453,454,455,456,457],"circuit-breaker","retry","resilience","backoff","opossum",{"id":459,"category":255,"question":460,"answer":461,"level":345,"tags":462},64,"Production monitoring and observability: OpenTelemetry, metrics, logs, and traces in Node.js.","**Concept Explanation:**\nObservability is the ability to understand system internals using three pillars: logs (structured events), metrics (aggregated measurements), and traces (request flow across services). OpenTelemetry provides vendor-agnostic APIs for telemetry generation.\n\n**Key Components:**\n- **Metrics:** Counters, gauges, histograms (e.g., request rate, latency percentiles).\n- **Traces:** Spans representing operations, with parent-child relationships.\n- **Logs:** Structured (JSON) with trace\u002Fspan IDs for correlation.\n\n**OpenTelemetry Setup with Node.js:**\n```bash\nnpm install @opentelemetry\u002Fsdk-node @opentelemetry\u002Finstrumentation-http @opentelemetry\u002Finstrumentation-express @opentelemetry\u002Fexporter-jaeger\n```\n\n```javascript\n\u002F\u002F tracing.js\nconst { NodeSDK } = require('@opentelemetry\u002Fsdk-node');\nconst { JaegerExporter } = require('@opentelemetry\u002Fexporter-jaeger');\nconst { ExpressInstrumentation } = require('@opentelemetry\u002Finstrumentation-express');\nconst { HttpInstrumentation } = require('@opentelemetry\u002Finstrumentation-http');\n\nconst sdk = new NodeSDK({\n  traceExporter: new JaegerExporter({ endpoint: 'http:\u002F\u002Flocalhost:14268\u002Fapi\u002Ftraces' }),\n  instrumentations: [\n    new HttpInstrumentation(),\n    new ExpressInstrumentation()\n  ],\n  serviceName: 'my-node-service'\n});\n\nsdk.start();\n```\n\n**Custom Span Creation:**\n```javascript\nconst { trace } = require('@opentelemetry\u002Fapi');\nconst tracer = trace.getTracer('my-service');\n\napp.get('\u002Fusers\u002F:id', async (req, res) => {\n  const span = tracer.startSpan('get-user');\n  span.setAttribute('user.id', req.params.id);\n  \n  try {\n    const user = await db.findUser(req.params.id);\n    span.setAttribute('db.query', 'findUser');\n    span.end();\n    res.json(user);\n  } catch (err) {\n    span.recordException(err);\n    span.setStatus({ code: 2, message: err.message });\n    span.end();\n    throw err;\n  }\n});\n```\n\n**Metrics with Prometheus:**\n```javascript\nconst client = require('prom-client');\nconst express = require('express');\nconst app = express();\n\n\u002F\u002F Create metrics\nconst httpRequestDuration = new client.Histogram({\n  name: 'http_request_duration_seconds',\n  help: 'Duration of HTTP requests in seconds',\n  labelNames: ['method', 'route', 'status_code']\n});\n\nconst activeRequests = new client.Gauge({\n  name: 'active_requests',\n  help: 'Number of active requests'\n});\n\nconst requestCounter = new client.Counter({\n  name: 'http_requests_total',\n  help: 'Total HTTP requests',\n  labelNames: ['method', 'route', 'status']\n});\n\n\u002F\u002F Middleware to record metrics\napp.use((req, res, next) => {\n  const end = httpRequestDuration.startTimer();\n  activeRequests.inc();\n  res.on('finish', () => {\n    activeRequests.dec();\n    requestCounter.inc({ method: req.method, route: req.route?.path || req.url, status: res.statusCode });\n    end({ method: req.method, route: req.route?.path || req.url, status_code: res.statusCode });\n  });\n  next();\n});\n\n\u002F\u002F Expose metrics endpoint\napp.get('\u002Fmetrics', async (req, res) => {\n  res.set('Content-Type', client.register.contentType);\n  res.end(await client.register.metrics());\n});\n```\n\n**Structured Logging with Correlation:**\n```javascript\nconst pino = require('pino');\nconst { trace } = require('@opentelemetry\u002Fapi');\n\nconst logger = pino({\n  level: 'info',\n  formatters: {\n    bindings: (bindings) => {\n      return { pid: bindings.pid, host: bindings.hostname };\n    },\n    log: (log) => {\n      const span = trace.getActiveSpan();\n      const spanContext = span?.spanContext();\n      return {\n        ...log,\n        trace_id: spanContext?.traceId,\n        span_id: spanContext?.spanId\n      };\n    }\n  }\n});\n\n\u002F\u002F Usage\nlogger.info({ userId: 123 }, 'User logged in');\nlogger.error({ error: err.message }, 'Database connection failed');\n```\n\n**Practical Example – Complete Observability Setup:**\n```javascript\nconst express = require('express');\nconst pino = require('pino-http');\nconst client = require('prom-client');\nconst { trace } = require('@opentelemetry\u002Fapi');\n\nconst app = express();\n\n\u002F\u002F HTTP logging (pino)\napp.use(pino({\n  level: 'info',\n  serializers: { req: (req) => ({ method: req.method, url: req.url }) },\n  redact: ['req.headers.authorization']\n}));\n\n\u002F\u002F Metrics middleware\nconst httpRequestDuration = new client.Histogram({ name: 'http_request_duration_ms', help: '...' });\napp.use((req, res, next) => {\n  const start = Date.now();\n  res.on('finish', () => {\n    const duration = Date.now() - start;\n    httpRequestDuration.observe({ method: req.method, status: res.statusCode }, duration);\n  });\n  next();\n});\n\n\u002F\u002F Health check\napp.get('\u002Fhealth', (req, res) => res.status(200).send('OK'));\n\n\u002F\u002F Ready check (depends on DB, cache)\napp.get('\u002Fready', async (req, res) => {\n  const dbOk = await checkDatabase();\n  res.status(dbOk ? 200 : 503).send(dbOk ? 'Ready' : 'Not ready');\n});\n\n\u002F\u002F Business endpoint\napp.get('\u002Fapi\u002Fdata', async (req, res) => {\n  const span = trace.getActiveSpan();\n  span?.addEvent('fetching-data');\n  \n  const data = await db.query('SELECT * FROM data');\n  \n  span?.setAttribute('row_count', data.length);\n  res.json(data);\n});\n\n\u002F\u002F Metrics endpoint\napp.get('\u002Fmetrics', async (req, res) => {\n  res.set('Content-Type', client.register.contentType);\n  res.end(await client.register.metrics());\n});\n\napp.listen(3000);\n```\n\n**Common Mistakes:**\n- Overhead of too many spans\u002Fmetrics.\n- Not sampling traces in production (use sampler with 1-5%).\n- Logging sensitive data (PII, passwords).\n- Not correlating logs with traces (missing trace ID).\n\n**Edge Cases:**\n- High cardinality labels (e.g., user ID) cause metric explosion.\n- Distributed tracing requires propagating trace headers (W3C `traceparent`).\n- Sampling decision consistency across services.\n\n**Interview Follow-ups:**\n- *\"What is the difference between metrics and tracing?\"*\n- *\"How do you propagate trace context across HTTP calls?\"*\n\n**Best Practices:**\n- Use consistent trace IDs across services (W3C Trace Context).\n- Sample traces based on criteria (errors, slow requests).\n- Keep metrics cardinality low (use buckets, not unique IDs).\n- Log in JSON format for ingestion by log aggregators.\n\n**Security Considerations:**\n- Redact sensitive fields from logs.\n- Secure metrics endpoint (internal access or basic auth).\n- Trace IDs should not be user-controlled.\n\n**Performance Considerations:**\n- Sampling reduces overhead in high-volume systems.\n- Async exporters prevent blocking request processing.\n- Batch span exports (default 5 sec or 512 spans).\n\n**Scalability Considerations:**\n- Use OpenTelemetry Collector to buffer and process telemetry.\n- Metrics aggregations at collector reduce load on Prometheus.\n- Log shippers (Fluentd) decouple logging from application.\n\n**Production Recommendations:**\n- Use Jaeger or Tempo for traces, Prometheus + Grafana for metrics, Loki\u002FELK for logs.\n- Set up alerts on error rate, latency (p99), and circuit breaker events.\n- Use `pino` or `winston` for structured logs.\n\n**Latest Node.js Patterns:**\n- OpenTelemetry JS SDK 1.0+ stable.\n- `@opentelemetry\u002Fauto-instrumentations-node` for auto-instrumentation.\n- `opentelemetry-lambda` for serverless.\n\n**Debugging Tips:**\n- Use `DEBUG=opentelemetry*` to see SDK logs.\n- Jaeger UI to trace individual requests.\n- Prometheus `rate()` and `histogram_quantile` for latency analysis.\n\n**Interview Tip:**\nExplain the difference: metrics tell you *what* happened (e.g., error rate increased), logs give *details* (which user), traces show *where* (which service).\n\n**Common Follow-up:**\n*\"How do you implement distributed tracing in a microservices architecture?\"* – Use OpenTelemetry instrumentation, propagate traceparent headers, and a collector (Jaeger\u002FTempo).\n\n**Real-world Example:**\nAt Lyft, distributed tracing with Jaeger helped debug latency issues by showing that a slow database query in a downstream service caused cascading delays.\n\n**Tags:** [\"observability\", \"opentelemetry\", \"prometheus\", \"jaeger\", \"metrics\"]",[260,463,464,465,466],"opentelemetry","prometheus","jaeger","metrics",{"id":468,"category":469,"question":470,"answer":471,"level":345,"tags":472},65,"GraphQL","Building GraphQL APIs with Apollo Server in Node.js.","**Concept Explanation:**\nGraphQL is a query language for APIs that allows clients to request exactly the data they need. Apollo Server is a popular Node.js library for building GraphQL servers. It provides schema definition, resolvers, and features like caching, batching, and subscriptions.\n\n**Core Concepts:**\n- **Schema:** Defines types, queries, mutations, and subscriptions.\n- **Resolvers:** Functions that fetch data for each field.\n- **Query:** Read operations.\n- **Mutation:** Write operations.\n- **Subscription:** Real-time events.\n\n**Setup with Apollo Server Express:**\n```bash\nnpm install @apollo\u002Fserver express graphql\n```\n\n```javascript\nconst { ApolloServer } = require('@apollo\u002Fserver');\nconst { expressMiddleware } = require('@apollo\u002Fserver\u002Fexpress4');\nconst express = require('express');\nconst { json } = require('body-parser');\n\nconst typeDefs = `\n  type User {\n    id: ID!\n    name: String!\n    email: String!\n    posts: [Post!]!\n  }\n  \n  type Post {\n    id: ID!\n    title: String!\n    content: String!\n    author: User!\n  }\n  \n  type Query {\n    user(id: ID!): User\n    allUsers: [User!]!\n    post(id: ID!): Post\n  }\n  \n  type Mutation {\n    createUser(name: String!, email: String!): User!\n    createPost(title: String!, content: String!, authorId: ID!): Post!\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    user: async (_, { id }) => db.users.findById(id),\n    allUsers: async () => db.users.findAll(),\n    post: async (_, { id }) => db.posts.findById(id)\n  },\n  Mutation: {\n    createUser: async (_, { name, email }) => db.users.create({ name, email }),\n    createPost: async (_, { title, content, authorId }) => db.posts.create({ title, content, authorId })\n  },\n  User: {\n    posts: async (user) => db.posts.findByAuthor(user.id)\n  },\n  Post: {\n    author: async (post) => db.users.findById(post.authorId)\n  }\n};\n\nconst server = new ApolloServer({ typeDefs, resolvers });\nawait server.start();\n\nconst app = express();\napp.use('\u002Fgraphql', json(), expressMiddleware(server, {\n  context: async ({ req }) => ({ user: await authenticate(req.headers.authorization) })\n}));\napp.listen(4000, () => console.log('GraphQL server on http:\u002F\u002Flocalhost:4000\u002Fgraphql'));\n```\n\n**Resolvers with DataLoader (batching):**\n```javascript\nconst DataLoader = require('dataloader');\n\n\u002F\u002F Batch function to load multiple users at once\nconst userLoader = new DataLoader(async (userIds) => {\n  const users = await db.users.findByIds(userIds);\n  \u002F\u002F Return in same order as userIds\n  return userIds.map(id => users.find(u => u.id === id));\n});\n\nconst resolvers = {\n  Post: {\n    author: async (post) => userLoader.load(post.authorId)\n  }\n};\n```\n\n**Error Handling & Custom Errors:**\n```javascript\nconst { GraphQLError } = require('graphql');\n\nconst resolvers = {\n  Mutation: {\n    createUser: async (_, args, context) => {\n      if (!context.user) {\n        throw new GraphQLError('Not authenticated', {\n          extensions: { code: 'UNAUTHENTICATED' }\n        });\n      }\n      const existing = await db.users.findByEmail(args.email);\n      if (existing) {\n        throw new GraphQLError('Email already exists', {\n          extensions: { code: 'BAD_USER_INPUT' }\n        });\n      }\n      return db.users.create(args);\n    }\n  }\n};\n```\n\n**Subscriptions (Real-time):**\n```javascript\nconst { ApolloServer } = require('@apollo\u002Fserver');\nconst { WebSocketServer } = require('ws');\nconst { useServer } = require('graphql-ws\u002Flib\u002Fuse\u002Fws');\n\nconst typeDefs = `\n  type Subscription {\n    postCreated: Post!\n  }\n`;\n\nconst resolvers = {\n  Subscription: {\n    postCreated: {\n      subscribe: (_, __, context) => context.pubsub.asyncIterator(['POST_CREATED'])\n    }\n  },\n  Mutation: {\n    createPost: async (_, args, context) => {\n      const post = await db.posts.create(args);\n      context.pubsub.publish('POST_CREATED', { postCreated: post });\n      return post;\n    }\n  }\n};\n\nconst pubsub = new PubSub();\nconst server = new ApolloServer({ typeDefs, resolvers });\n\u002F\u002F WebSocket setup for subscriptions\n```\n\n**Query Complexity Analysis (Prevent DoS):**\n```javascript\nconst { createComplexityRule, simpleEstimator } = require('graphql-query-complexity');\n\nconst server = new ApolloServer({\n  typeDefs,\n  resolvers,\n  validationRules: [\n    createComplexityRule({\n      estimators: [simpleEstimator({ defaultComplexity: 1 })],\n      maximumComplexity: 1000,\n      onComplete: (complexity) => console.log(`Query complexity: ${complexity}`)\n    })\n  ]\n});\n```\n\n**Common Mistakes:**\n- N+1 queries (resolver for each field calls database separately).\n- Not limiting query depth or complexity (DoS vulnerability).\n- Exposing internal errors to clients.\n- Over-fetching resolved by GraphQL but still possible.\n\n**Edge Cases:**\n- Fragments, aliases, and directives increase complexity.\n- Circular references in schema (e.g., User -> Post -> User).\n- Introspection in production (disable if not needed).\n\n**Interview Follow-ups:**\n- *\"What is the N+1 problem in GraphQL and how do you solve it?\"*\n- *\"How does GraphQL differ from REST?\"*\n\n**Best Practices:**\n- Use DataLoader for batching and caching.\n- Implement query complexity limits.\n- Disable introspection in production unless needed.\n- Use persisted queries for mobile apps.\n- Versioning via schema evolution (add fields, never remove).\n\n**Security Considerations:**\n- Rate limiting on GraphQL endpoint.\n- Authentication at context level, not per resolver.\n- Depth limiting to prevent recursive queries.\n- Timeout for resolvers (Apollo Server `plugins`).\n\n**Performance Considerations:**\n- DataLoader reduces round trips.\n- Use `@defer` and `@stream` for large responses (Apollo federation).\n- Cache expensive resolvers (Apollo Server caching).\n\n**Scalability Considerations:**\n- GraphQL services are stateless; scale horizontally.\n- Use persisted queries to reduce request payload size.\n- Schema registry for client-schema compatibility.\n\n**Production Recommendations:**\n- Use Apollo Studio for schema management and metrics.\n- Set up persisted query storage (for mobile apps).\n- Use GraphQL mesh for federated schemas.\n\n**Latest Node.js Patterns:**\n- Apollo Server 4 with `@apollo\u002Fserver`.\n- GraphQL Yoga (alternative, with built-in plugins).\n- `graphql-request` for client-side.\n\n**Debugging Tips:**\n- Apollo Studio Explorer for query testing.\n- `graphql-playground` (deprecated but useful).\n- Log resolver timings.\n\n**Interview Tip:**\nExplain that GraphQL solves over-fetching and under-fetching but introduces complexity in caching and N+1 queries.\n\n**Common Follow-up:**\n*\"How do you handle authentication in GraphQL?\"* – Extract token from request headers in context, attach user to context, check in resolvers.\n\n**Real-world Example:**\nGitHub's GraphQL API allows clients to fetch exactly the data they need, reducing bandwidth for mobile clients that previously received large REST payloads.\n\n**Tags:** [\"graphql\", \"apollo\", \"resolvers\", \"dataloader\", \"subscriptions\"]",[473,474,475,476,477],"graphql","apollo","resolvers","dataloader","subscriptions",{"id":479,"category":480,"question":481,"answer":482,"level":345,"tags":483},66,"Serverless","Serverless Node.js: AWS Lambda, API Gateway, and best practices.","**Concept Explanation:**\nServerless allows running Node.js functions without managing servers. AWS Lambda executes code on demand, scales automatically, and charges per invocation. API Gateway exposes Lambda functions as HTTP endpoints.\n\n**Key Concepts:**\n- **Lambda:** Function that runs in response to events.\n- **Cold start:** First invocation after idle (adds latency).\n- **Warm start:** Reused execution environment.\n- **Event sources:** API Gateway, S3, SQS, DynamoDB Streams.\n\n**Basic Lambda Handler:**\n```javascript\n\u002F\u002F handler.js\nexports.handler = async (event, context) => {\n  console.log('Event:', JSON.stringify(event, null, 2));\n  console.log('Context:', context);\n  \n  const response = {\n    statusCode: 200,\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      'Access-Control-Allow-Origin': '*'\n    },\n    body: JSON.stringify({ message: 'Hello from Lambda!', timestamp: Date.now() })\n  };\n  return response;\n};\n```\n\n**API Gateway Integration:**\n```javascript\nexports.handler = async (event) => {\n  \u002F\u002F API Gateway event structure\n  const { httpMethod, path, queryStringParameters, body, headers } = event;\n  \n  if (httpMethod === 'GET' && path === '\u002Fusers') {\n    const users = await db.scan();\n    return { statusCode: 200, body: JSON.stringify(users) };\n  }\n  \n  if (httpMethod === 'POST' && path === '\u002Fusers') {\n    const user = JSON.parse(body);\n    const created = await db.put(user);\n    return { statusCode: 201, body: JSON.stringify(created) };\n  }\n  \n  return { statusCode: 404, body: 'Not Found' };\n};\n```\n\n**Using Express with Serverless (serverless-http):**\n```javascript\nconst express = require('express');\nconst serverless = require('serverless-http');\n\nconst app = express();\napp.use(express.json());\n\napp.get('\u002Fusers\u002F:id', async (req, res) => {\n  const user = await db.get(req.params.id);\n  res.json(user);\n});\n\napp.post('\u002Fusers', async (req, res) => {\n  const user = await db.create(req.body);\n  res.status(201).json(user);\n});\n\nexports.handler = serverless(app);\n```\n\n**Cold Start Optimization:**\n```javascript\n\u002F\u002F Move initialization outside handler (reused across warm starts)\nconst AWS = require('aws-sdk');\nconst dynamo = new AWS.DynamoDB.DocumentClient();\n\n\u002F\u002F Cache initialization\nlet cachedData = null;\nconst getData = async () => {\n  if (!cachedData) {\n    cachedData = await loadExpensiveData();\n  }\n  return cachedData;\n};\n\nexports.handler = async (event) => {\n  const data = await getData(); \u002F\u002F cached after first invocation\n  \u002F\u002F ...\n};\n```\n\n**Environment Variables and Secrets:**\n```javascript\n\u002F\u002F Lambda environment variables (set in console or serverless.yml)\nconst { DB_TABLE, STAGE } = process.env;\n\n\u002F\u002F For secrets, use AWS Secrets Manager\nconst { SecretsManager } = require('aws-sdk');\nconst secrets = new SecretsManager();\n\nlet cachedSecrets = null;\nasync function getSecret(secretName) {\n  if (!cachedSecrets) {\n    const data = await secrets.getSecretValue({ SecretId: secretName }).promise();\n    cachedSecrets = JSON.parse(data.SecretString);\n  }\n  return cachedSecrets;\n}\n```\n\n**Connecting to Database (RDS Proxy for connection pooling):**\n```javascript\n\u002F\u002F Without connection pooling (BAD – each Lambda creates new connection)\nconst mysql = require('mysql2\u002Fpromise');\n\n\u002F\u002F With RDS Proxy – connection pooling across Lambdas\nlet connection;\nexports.handler = async (event) => {\n  if (!connection) {\n    connection = await mysql.createConnection({\n      host: process.env.DB_HOST,\n      user: process.env.DB_USER,\n      password: process.env.DB_PASSWORD,\n      database: process.env.DB_NAME\n    });\n  }\n  const [rows] = await connection.query('SELECT * FROM users');\n  return rows;\n};\n```\n\n**Practical Example – Serverless Framework Configuration:**\n```yaml\n# serverless.yml\nservice: my-node-api\n\nprovider:\n  name: aws\n  runtime: nodejs18.x\n  region: us-east-1\n  memorySize: 512\n  timeout: 10\n  environment:\n    DB_TABLE: ${env:DB_TABLE}\n  iamRoleStatements:\n    - Effect: Allow\n      Action:\n        - dynamodb:GetItem\n        - dynamodb:PutItem\n      Resource: arn:aws:dynamodb:${aws:region}:*:table\u002F${env:DB_TABLE}\n\nfunctions:\n  api:\n    handler: handler.api\n    events:\n      - httpApi: '*' # catch-all route\n  \n  cronJob:\n    handler: cron.handler\n    events:\n      - schedule: rate(10 minutes)\n  \n  sqsConsumer:\n    handler: consumer.handler\n    events:\n      - sqs:\n          arn: arn:aws:sqs:us-east-1:123456789012:my-queue\n          batchSize: 10\n```\n\n**Common Mistakes:**\n- Storing state in Lambda (reused across invocations but not guaranteed).\n- Large deployment packages (>50MB slows cold start).\n- Not handling Lambda timeouts (default 6 seconds).\n- Using synchronous operations (blocking event loop).\n\n**Edge Cases:**\n- Provisioned concurrency to eliminate cold starts.\n- Dead letter queues for failed async invocations.\n- Reserved concurrency to prevent runaway functions.\n\n**Interview Follow-ups:**\n- *\"How do you handle database connections in Lambda?\"*\n- *\"What is the difference between cold start and warm start?\"*\n\n**Best Practices:**\n- Keep functions small and focused (single responsibility).\n- Use environment variables for configuration.\n- Minimize deployment package size (use layers for node_modules).\n- Set appropriate memory (CPU scales with memory).\n- Use async handlers and await promises.\n\n**Security Considerations:**\n- Use IAM roles with least privilege.\n- Encrypt environment variables with KMS.\n- Validate input; Lambda is not a WAF.\n- Use VPC only if needed (adds cold start latency).\n\n**Performance Considerations:**\n- Cold start adds 200ms – 1s; use keep-alive or provisioned concurrency.\n- Larger memory = more CPU (cost vs performance).\n- Zip package with minified code.\n\n**Scalability Considerations:**\n- Lambda scales automatically (1000 concurrent executions default).\n- Use SQS for decoupling and burst smoothing.\n- DynamoDB on-demand mode for serverless database.\n\n**Production Recommendations:**\n- Use AWS X-Ray for tracing.\n- Set up CloudWatch alarms for errors and throttles.\n- Use AWS SAM or CDK over Serverless Framework.\n- Implement idempotency for event sources (SQS, SNS).\n\n**Latest Node.js Patterns:**\n- Node.js 18.x in Lambda (ES modules support).\n- Lambda Web Adapter (run Express\u002FFastify natively).\n- Lambda Powertools for structured logging and tracing.\n\n**Debugging Tips:**\n- CloudWatch Logs for each invocation.\n- `console.log` statements appear in logs.\n- Use `context.getRemainingTimeInMillis()` to avoid timeout.\n- `aws-lambda-powertools` for better logging.\n\n**Interview Tip:**\nExplain that serverless is great for variable workloads, but not for long-running processes (max 15 min timeout).\n\n**Common Follow-up:**\n*\"How do you manage Lambda cold starts?\"* – Provisioned concurrency, optimized code (smaller bundle), keep connections alive, use Node.js 18+.\n\n**Real-world Example:**\nNetflix uses AWS Lambda for encoding and media processing – each job is one invocation, scaling to thousands concurrently.\n\n**Tags:** [\"serverless\", \"aws-lambda\", \"apigateway\", \"cold-start\"]",[484,485,486,487],"serverless","aws-lambda","apigateway","cold-start",1779734543422]