1. How does Node.js schedule tasks internally?

Node.js schedules tasks using the event loop, microtask queues, and libuv.

Scheduling priority:

  1. process.nextTick() queue (highest)
  2. Microtasks (Promises)
  3. Event loop phases (timers, I/O, check, etc.)

Flow:

  • Synchronous code runs first
  • Then microtasks
  • Then event loop handles async callbacks

Example:

setTimeout(() => console.log("timeout"), 0);

Promise.resolve().then(() => console.log("promise"));

process.nextTick(() => console.log("nextTick"));

Output:

nextTick
promise
timeout

2. How does Node.js manage memory?

Node.js uses the V8 engine to manage memory automatically.

Memory areas:

  • Stack → stores primitive values and function calls
  • Heap → stores objects and complex data

Key points:

  • Automatic allocation and deallocation
  • Uses garbage collection
  • Limited heap size (can be configured)

3. How does garbage collection work in Node.js?

Garbage collection (GC) in Node.js is handled by the V8 engine.

Mechanism:

  • Uses Mark-and-Sweep algorithm

Steps:

  1. Identify reachable objects
  2. Mark them as active
  3. Remove unreferenced objects

Generations:

  • Young generation (short-lived objects)
  • Old generation (long-lived objects)

4. How does garbage collection impact performance?

GC can pause execution, affecting performance.

Effects:

  • CPU overhead
  • Latency spikes
  • Event loop delays

Example scenario:

  • Large memory allocation → frequent GC → slower response time

Optimization:

  • Reduce object creation
  • Avoid memory leaks
  • Use efficient data structures

5. How do you detect memory leaks?

Techniques:

  1. Monitor memory usage
console.log(process.memoryUsage());
  1. Heap snapshots
  • Chrome DevTools
  • node --inspect
  1. Tools
  • heapdump
  • clinic.js

Signs:

  • Increasing memory over time
  • Slow performance

6. Difference between heap and stack memory

StackHeap
Stores primitivesStores objects
Fast accessSlower access
Fixed sizeDynamic size
Managed automaticallyManaged by GC

7. How do you tune Node.js memory limits?

Node.js has a default memory limit (~1.5–2GB).

Increase memory:

node --max-old-space-size=4096 app.js

Meaning:

  • 4096 MB heap size

When needed:

  • Large applications
  • Data-heavy processing

8. What is WASI and why was it introduced?

WASI (WebAssembly System Interface) is a standard that allows WebAssembly to interact with the system outside the browser.

Purpose:

  • Run WebAssembly on servers (like Node.js)
  • Provide system-level access (files, network)

Benefit:

  • Secure sandboxed execution
  • Cross-platform compatibility

9. What is Punycode in Node.js?

Punycode is a method to encode Unicode domain names into ASCII.

Example:

  • Domain: müller.com
  • Punycode: xn--mller-kva.com

Use case:

  • Internationalized domain names (IDN)

Node.js provides a punycode module (now deprecated but still relevant conceptually).


10. How do you optimize a high-traffic Node.js API?

Key strategies:

1. Use clustering

  • Utilize multiple CPU cores

2. Caching

  • Redis or in-memory cache

3. Load balancing

  • Distribute traffic

4. Optimize database queries

  • Indexing
  • Query optimization

5. Use async operations

  • Avoid blocking code

6. Compression

const compression = require('compression');
app.use(compression());

7. Rate limiting

  • Prevent abuse

8. Monitor performance

  • Logs, metrics

11. How do you handle CPU-intensive tasks?

CPU-intensive tasks can block the event loop, so they must be offloaded.

Approaches:

  1. Worker Threads
  2. Child Processes
  3. External services (microservices)

Example (Worker Thread):

const { Worker } = require('worker_threads');

new Worker(`
let sum = 0;
for (let i = 0; i < 1e9; i++) sum += i;
console.log(sum);
`, { eval: true });

Key idea:

Keep the main thread free for handling requests.


12. How do you measure async operation performance?

Methods:

  1. performance API
const { performance } = require('perf_hooks');

const start = performance.now();

setTimeout(() => {
console.log(performance.now() - start);
}, 100);
  1. process.hrtime()
const start = process.hrtime();
// operation
const diff = process.hrtime(start);
console.log(diff);
  1. Logging and monitoring tools

13. Which metrics should be monitored in production?

Key metrics:

  • CPU usage
  • Memory usage
  • Event loop lag
  • Response time
  • Throughput (requests/sec)
  • Error rate
  • Database latency

Example:

console.log(process.memoryUsage());

14. How do you profile a Node.js application?

Tools:

  1. Built-in profiler
node --inspect app.js
  1. Chrome DevTools
  • CPU profiling
  • Heap snapshots
  1. Clinic.js
  • Flame graphs
  • Bottleneck detection

15. What is load shedding?

Load shedding is a technique where the system intentionally rejects some requests to maintain stability under heavy load.

Example:

  • Returning HTTP 503 when overloaded

Purpose:

  • Prevent system crash
  • Maintain performance for critical users

16. How do you handle traffic spikes?

Strategies:

  1. Load balancing
  2. Auto-scaling
  3. Caching (Redis)
  4. Rate limiting
  5. Queueing systems (RabbitMQ)

17. How does Redis improve Node.js performance?

Redis is an in-memory database used for caching.

Benefits:

  • Faster data access
  • Reduces database load
  • Improves response time

Example:

const redis = require('redis');
const client = redis.createClient();

client.get("key", (err, data) => {
if (data) return console.log(data);

// fetch from DB and cache it
});

18. How would you architect a scalable Node.js application?

Key components:

  1. Load balancer
  2. Multiple Node.js instances (clustering)
  3. Microservices architecture
  4. Database scaling (replication/sharding)
  5. Caching layer (Redis)
  6. Queue system for background jobs

High-level flow:

Client → Load Balancer → Node servers → Cache/DB → Response


19. What design patterns are commonly used in Node.js?

Common patterns:

  1. Singleton → single instance
  2. Factory → object creation
  3. Observer → event-based (EventEmitter)
  4. Middleware pattern → request processing
  5. Module pattern → encapsulation

20. What is the Reactor Pattern?

The Reactor Pattern is the design pattern used by Node.js to handle I/O operations.

Concept:

  • Single thread listens for events
  • Delegates tasks
  • Executes callbacks when ready

Steps:

  1. Event arrives
  2. Event loop detects it
  3. Handler (callback) is executed

Example concept:

setTimeout(() => {
console.log("Handled asynchronously");
}, 1000);

Key idea:

  • Efficient handling of multiple I/O operations without blocking 

21. What is CQRS?

CQRS (Command Query Responsibility Segregation) is a design pattern that separates read and write operations.

Concept:

  • Command → modifies data (create, update, delete)
  • Query → reads data

Why use it:

  • Improves scalability
  • Optimizes read/write performance separately
  • Simplifies complex systems

Example:

// Command
app.post('/user', createUser);

// Query
app.get('/user/:id', getUser);

22. What is the Circuit Breaker pattern?

The Circuit Breaker pattern prevents repeated calls to a failing service.

States:

  • Closed → normal operation
  • Open → calls blocked
  • Half-open → testing recovery

Purpose:

  • Prevent system overload
  • Improve fault tolerance

Example (concept):

if (serviceDown) {
return "Fallback response";
}

23. How do you design idempotent APIs?

An API is idempotent if multiple identical requests produce the same result.

Techniques:

  • Use unique request IDs
  • Avoid duplicate operations
  • Use PUT instead of POST when possible

Example:

app.put('/user/1', updateUser);

Calling it multiple times gives the same result.


24. How do you implement API versioning?

Methods:

  1. URL versioning
/api/v1/users
/api/v2/users
  1. Header versioning
Accept: application/vnd.myapi.v1+json
  1. Query parameter
/users?version=1

Best practice:

Use URL versioning for simplicity.


25. What are microservices?

Microservices architecture breaks an application into small, independent services.

Characteristics:

  • Each service handles a specific function
  • Independently deployable
  • Communicate via APIs

26. Why is Node.js suitable for microservices?

Node.js is suitable because:

  • Lightweight and fast
  • Non-blocking I/O
  • Easy to build APIs
  • Works well with JSON
  • Large ecosystem

27. How do services communicate in microservices?

Methods:

  1. HTTP/REST APIs
  2. Message queues (async)
  3. gRPC

Example:

axios.get('http://user-service/users');

28. What is eventual consistency?

Eventual consistency means that data will become consistent over time, not immediately.

Used in:

  • Distributed systems
  • Microservices

Example:

  • Order placed → inventory updates later

29. How do you implement message queues?

Message queues allow asynchronous communication between services.

Tools:

  • RabbitMQ
  • Kafka

Example (RabbitMQ concept):

channel.sendToQueue('task_queue', Buffer.from('message'));

Flow:

Producer → Queue → Consumer


31. Difference between Kafka and RabbitMQ (Node.js perspective)

Apache Kafka vs RabbitMQ

FeatureKafkaRabbitMQ
TypeStreaming platformMessage broker
Use caseHigh-throughput data streamingTask queues
PersistenceStrongOptional
OrderingPartition-basedQueue-based
PerformanceVery highModerate
ComplexityHigherEasier

Summary:

  • Kafka → large-scale streaming systems
  • RabbitMQ → simple message queuing

32. How do you handle retries and dead-letter queues?

Retries and dead-letter queues (DLQ) are used to handle failed message processing.

Retry strategy:

  • Retry failed messages with delay
  • Use exponential backoff

Dead-letter queue:

  • Messages that fail repeatedly are moved to DLQ
  • Allows debugging without blocking the system

Example (concept):

if (retryCount < 3) {
retryMessage();
} else {
moveToDLQ(message);
}

33. How do you handle distributed transactions?

In distributed systems, traditional transactions are difficult.

Solutions:

  1. Saga pattern
    • Sequence of local transactions
    • Rollback using compensating actions
  2. Event-driven approach

Example:

  • Order service → Payment service → Inventory
  • If payment fails → cancel order

34. How do you secure a Node.js application end-to-end?

Key practices:

  • Use HTTPS (TLS)
  • Validate inputs
  • Use Helmet for headers
  • Implement authentication & authorization
  • Use environment variables
  • Prevent XSS, CSRF
  • Use rate limiting

35. How do you implement authentication and authorization?

Authentication:

  • Verify identity (JWT, sessions)

Authorization:

  • Check permissions (roles)

Example:

function auth(req, res, next) {
if (!req.user) return res.status(401).send("Unauthorized");
next();
}

function authorize(role) {
return (req, res, next) => {
if (req.user.role !== role) return res.status(403).send("Forbidden");
next();
};
}

36. How do you handle TLS/SSL in Node.js?

Use HTTPS module with certificates.

Example:

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

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

https.createServer(options, (req, res) => {
res.end("Secure server");
}).listen(443);

37. What is the crypto module used for?

The crypto module is used for:

  • Hashing
  • Encryption/decryption
  • Digital signatures
  • Secure random data

Example:

const crypto = require('crypto');

const hash = crypto.createHash('sha256')
.update('data')
.digest('hex');

console.log(hash);

38. How do you prevent resource starvation?

Resource starvation occurs when some tasks never get executed.

Prevention:

  • Avoid blocking code
  • Limit process.nextTick usage
  • Use queues and scheduling
  • Prioritize tasks properly

39. What is structured logging?

Structured logging means logging data in a consistent, machine-readable format (like JSON).

Benefits:

  • Easier parsing
  • Better monitoring
  • Integration with tools

Example:

console.log(JSON.stringify({
level: "info",
message: "User logged in",
userId: 1
}));

40. What is distributed tracing?

Distributed tracing tracks a request across multiple services.

Purpose:

  • Debug microservices
  • Measure latency

Example:

  • Request → API → Service → DB
  • Trace each step

41. What is OpenTelemetry?

OpenTelemetry is an open-source framework for collecting:

  • Metrics
  • Logs
  • Traces

Benefit:

  • Standardized observability
  • Works with multiple tools

42. How do you debug production issues?

Methods:

  1. Logs (structured logging)
  2. Monitoring tools
  3. Tracing (OpenTelemetry)
  4. Heap/CPU profiling
  5. Reproduce issue locally

43. How do you handle graceful shutdowns?

Graceful shutdown ensures ongoing requests finish before exit.

Example:

process.on('SIGTERM', () => {
server.close(() => {
console.log("Server closed");
});
});

44. How do you set up CI/CD for Node.js?

Steps:

  1. Code push → Git
  2. Run tests
  3. Build app
  4. Deploy automatically

Tools:

  • GitHub Actions
  • Jenkins
  • GitLab CI

45. How do you deploy a Node.js application?

Options:

  • Cloud (AWS, Azure)
  • Containers (Docker)
  • PaaS (Heroku)

Basic steps:

  1. Build app
  2. Install dependencies
  3. Start server

46. How do you handle zero-downtime deployments?

Techniques:

  • Rolling updates
  • Blue-green deployment
  • Load balancer switching

Benefit:

  • No service interruption

47. How do you monitor Node.js applications?

Tools and methods:

  • Metrics (CPU, memory)
  • Logs
  • Alerts
  • APM tools (New Relic, Datadog)

Example:

console.log(process.memoryUsage());