Top 50 Advance NodeJS Interview Questions

Top 50 Advance NodeJS Interview Questions

Table of Contents

Introduction

Node.js is a popular open-source JavaScript runtime environment that allows developers to build server-side applications using JavaScript. As more companies adopt Node.js for their web development needs, it’s becoming increasingly important for developers to showcase Node.js skills during interviews.

In this article, we have compiled a list of 50 advanced NodeJS interview questions that employers commonly ask. We have provided detailed sample answers to help you prepare for your next Node.js interview and land your dream job!

NodeJS Interview Questions

1. Explain the concept of event loop in Node.js.

The event loop is the secret behind Node.js’s ability to handle high throughput and scalability despite using a single thread. Here’s how it works:

Node.js is built around the concept of events and callbacks. Every API in Node.js adheres to asynchronous event-driven architecture. When Node.js starts, it initializes the event loop which is an infinite loop that receives and processes events and callbacks.

The event loop executes the callbacks/functions when the corresponding events occur. It does not wait for one callback to return in order to execute another one. This allows Node.js to handle high concurrent workloads without getting blocked.

2. What is the difference between Asynchronous and Non-blocking?

Asynchronous means that things can happen independently of the main program flow. Non-blocking means that the execution of the program is not halted while waiting for an I/O event to complete.

In asynchronous operations, when one function starts an I/O request, it registers a callback and immediately returns control. The callback is invoked once the I/O response comes back. So the program is not blocked while waiting for the I/O.

Non-blocking is usually implemented using asynchronous operations. So asynchronous code is non-blocking but non-blocking code is not necessarily asynchronous.

3. Explain Node.js module system. How can you create a module and export members?

Node.js has a simple module system that enables encapsulating related code into reusable modules very easily. To create a module, you just need to create a new .js file and add the code you want to export.

To export members of a module:

// myModule.js
const greeting = 'Hello';

function sayHi(name) {
  console.log(`${greeting} ${name}`); 
}

module.exports = {
  greeting, 
  sayHi
}

And to import and use the module:

const myModule = require('./myModule.js');

myModule.sayHi('John'); // Hello John

4. How can you listen on port 80 with Node.js?

By default, regular Node.js processes won’t have access to ports below 1024 due to their privileged nature. To listen to port 80 in Node, you need elevated privileges. Here are two ways to achieve that:

  1. Use the setcap command to enable the cap_net_bind_service capability on the Node binary:
sudo setcap cap_net_bind_service=+ep /usr/bin/node

2. Launch your Node process with root privileges:

sudo node app.js

But it’s recommended to have a reverse proxy like Nginx listen on port 80 and forward requests to your Node app running on a higher port.

5. What is the purpose of module.exports in Node.js?

The module.exports object is used to export members from a Node.js module so they can be consumed and used by other parts of your application.

Some key points about module.exports:

  • It defines the public API of your module – what members are made available when someone imports your module
  • By default it is an empty object {}
  • You assign members to it to export them, like functions, objects, strings etc.
  • When someone imports your module via requiremodule.exports gets returned

For example:

module.exports.sayHi = function() {
  console.log('Hi!');
}

Allows someone to do:

const myModule = require('./myModule.js');
myModule.sayHi();

6. How can you listen asynchronously for an event in Node.js?

Node provides the EventEmitter class which allows listening and emitting custom events asynchronously. Here is how it can be used:

const EventEmitter = require('events');
const emitter = new EventEmitter();

// Listen for the 'message' event
emitter.on('message', (message) => {
  console.log(`Message received: ${message}`); 
}); 

// Emit a 'message' event 
emitter.emit('message', 'Hello World');

Some key points:

  • emitter.on() registers a listener callback for the event
  • emitter.emit() emits the event which calls the callback
  • EventEmitter provides singleton instance through EventEmitter.defaultMaxListeners
  • Useful for async comm, loose coupling between modules

7. Explain the purpose of Buffer class in Node.js

The Buffer class in Node.js allows storing and manipulating streams of binary data.

Some important uses of Buffer are:

  • Used to represent sequences of octets efficiently
  • Can convert between data types like UTF-8 strings ↔ binary data
  • Interact with TCP streams and file system operations
  • Used in streams API for moving chunks of data around

For example, you can convert a UTF-8 string into a buffer, manipulate the data, and convert back:

const buf = Buffer.from('Hello World', 'utf8');

buf[0] = 0x45; // Change H to E

console.log(buf.toString('utf8')); // Eello World

Buffers provide a critical bridge between JavaScript strings and raw binary data.

8. How can you promisify the callback based APIs in Node.js?

We can promisify callback style APIs in Node.js using the util.promisify method:

const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);

async function run() {
  const data = await readFile('./file.txt', 'utf8');
  console.log(data);
}

run();

The key steps are:

  1. Import util module
  2. Call util.promisify passing the original callback-style function
  3. It returns a function that returns a promise when called
  4. Await the promise instead of passing a callback

This allows combining callback APIs with async/await for synchronous looking code.

9. How can you use HTTPS with Node.js?

Node.js provides the https module to create HTTPS servers in a very similar way as http. To create a HTTPS server:

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) => {
  // handle request
}).listen(8000);

The key steps are:

  1. Import https and fs modules
  2. Define options with location of key and cert files
  3. Pass options to https.createServer()
  4. Process requests like a normal HTTP server
  5. Call server.listen()

HTTPS provides transport layer security for secure communication.

10. How do you handle file uploads in Express.js?

Express provides the multer middleware to handle file uploads in Node.js. To add upload capabilities to an Express app:

  1. Install multer:
npm install multer
  1. Import and configure multer:
const multer = require('multer');

const upload = multer({
  storage: multer.diskStorage(...)
});
  1. Define upload route and parser:
app.post('/upload', upload.single('image'), (req, res) => {
  // req.file contains the uploaded file 
});

Some key points:

  • Set storage engine to determine where to store files
  • upload.single() parses a single file
  • upload.array() for multiple files
  • File info is available in req.file in route handler

This provides a handy API for handling multipart form data.

11. How can you implement authentication in an Express.js app?

Here are a few common ways to implement authentication in Express:

  • HTTP Basic Auth – Use express basic-auth middleware. Simple but unsecure.
  • Sessions – Store user data in server-side session. Popular packages like express-session.
  • JWT Tokens – Stateless token based authentication. Encode user info in signed JWT.
  • OAuth – Delegate authentication to 3rd party providers like Facebook, Twitter etc.
  • Passport.js – Flexible middleware that supports multiple strategies including Local, OAuth, JWT. Extremely popular.

For example, Passport can be used as:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

app.use(passport.initialize());
app.use(passport.session());

passport.use(new LocalStrategy(
  function(username, password, done) {
    // ...
  }
));

This implements username/password auth using sessions and Passport!

12. How can you use WebSockets in a Node.js app?

The ws module in Node.js allows implementing real-time communication using WebSockets:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', ws => {

  ws.on('message', message => {
    // a message was received
  });

  ws.send('Hello!');

});

Some key aspects:

  • WebSocket.Server creates the WebSocket server
  • The server listens for ‘connection’ events
  • The callback provides the connected ws socket
  • Send messages with ws.send()
  • Receive messages with ws.on('message')

WebSockets enable real-time, bidirectional communication which is great for apps like chat, live updates, notifications etc.

13. How can you make an HTTP request in Node.js?

Node.js provides the HTTP core module to create both HTTP servers as well as clients. To make HTTP requests:

const https = require('https');

const options = {
  hostname: 'example.com',
  port: 443,
  path: '/data',
  method: 'GET' 
};

const req = https.request(options, res => {  
  console.log(`statusCode: ${res.statusCode}`);

  res.on('data', d => {
    // process data
  });
});

req.on('error', error => {
  console.error(error);
});

req.end();

Key steps:

  • Import http(s) module
  • Create options object with URL, method etc.
  • Call http.request() with options
  • Add data and error handlers
  • Call req.end() to initiate request

This allows making any HTTP request very easily.

14. How does routing work in Express.js?

Express provides a Router class which allows handling routes and their handlers separately from the main app.

Some key aspects of Express routing:

  • Create router instance with express.Router()
  • Define routes using router middleware methods like router.getrouter.post etc.
  • Specify path and route handler callback
  • Use app.use() to mount router at path
  • Multiple routers can be created and mounted

For example:

const router = express.Router();

router.get('/', (req, res) => {
  // handle GET /
});

app.use('/data', router);

This approach allows breaking an app into reusable and modular route handlers.

15. How can you implement authentication using Passport.js?

Passport.js provides various strategies to implement authentication in Express apps. Here is an example using the local strategy:

const passport = require('passport'); 
const LocalStrategy = require('passport-local').Strategy;

// passport config
passport.use(new LocalStrategy(
  (username, password, done) => {
    // auth logic
  } 
));

// passport middleware
app.use(passport.initialize()); 
app.use(passport.session());

// POST login route
app.post('/login', passport.authenticate('local'), (req, res) => {
  res.redirect('/home');
});

Key steps:

  • Configure passport to use LocalStrategy
  • Add passport middleware
  • Use passport.authenticate() in routes
  • On success call done(), on failure call done(err)

This implements username/password authentication using sessions. Many other strategies like OAuth are available.

16. Explain the concept of middleware in Express.js

Middleware functions are functions that have access to the request and response objects. Express has built-in middleware and allows adding custom middleware.

  • Executed during request/response lifecycle
  • Have access to req, res objects
  • Next function allows passing control to the next middleware
  • Common built-in middleware: express.json(), express.urlencoded() etc
  • Third party middleware: Morgan, helmet, cors etc
  • Custom middleware:
app.use((req, res, next) => {
  // perform action
  next(); 
});

Middleware allows implementing common functionality like logging, authentication, headers etc in a modular manner. Multiple middleware can be combined to create a request processing pipeline.

17. How does Node.js handle child threads?

Node.js is single threaded and uses an event loop to handle async operations. However, it provides the child_process module to create child threads for CPU intensive work.

Some ways to use child threads:

  • child_process.spawn() – Spawns a new process and runs command
  • child_process.fork() – Spawns new Node.js process and communication via IPC
  • child_process.exec() – Executes command in a shell

For example:

const { spawn } = require('child_process');
const child = spawn('node', ['script.js']);

child.stdout.on('data', (data) => {
  // ... 
});

child.on('close', (code) => {
  // ...
});

Some key benefits are parallelism, isolation and communication via IPC. The main Node process remains single threaded.

18. When should you npm and when yarn?

Both Yarn and npm can be used for managing Node.js packages. Some key differences:

npm

  • Default package manager for Node.js
  • Largest ecosystem and community
  • Slower installs compared to Yarn
  • Better support for SEMVER based ranges

Yarn

  • Alternative package manager for Node.js
  • Performs installs faster than npm
  • Default package manager for Facebook projects
  • Strict file locking, caches dependencies locally
  • More emojis!

General guidelines:

  • New projects: Use yarn
  • Existing projects already using npm: Stick to npm
  • Cutting edge features: npm
  • Stable projects: yarn

Evaluate both and choose based on specific needs.

19. How does Node.js support multi-core platforms?

Node.js is inherently single threaded. However, it can leverage multiple cores in these ways:

  • Cluster Module – Spawns multiple Node.js worker processes to share port. Achieves parallelism by load balancing between workers.
  • Worker Threads – Moves heavy CPU tasks to background threads while keeping main thread responsive. Parallelism within a single process.
  • Child Processes – Spawns processes for parallelism. Inter-process communication via messaging.
  • Promises – Encourages async programming which allows concurrent request handling even on single thread.

So in summary, Node.js supports concurrency using single threaded event loop but can utilize multiple cores for heavyweight operations using processes/threads.

20. What are the key differences between SQL and NoSQL databases?

SQLNoSQL
Relational databaseNon-relational database
Table based structureFlexible schemas
Predefined schemaDynamic schema
ACID compliance (strong consistency)Eventual consistency
Vertically scalableHorizontally scalable
Good for complex queriesSimpler queries over large data
Examples: MySQL, Oracle, SQL ServerExamples: MongoDB, Cassandra, Redis

To summarize, SQL databases are better for highly structured relational data while NoSQL databases provide flexibility and scalability for semi-structured data. The choice depends on the data and use cases.

21. How can you handle exceptions in Async/Await?

Async/await makes asynchronous code look synchronous but exceptions are handled a bit differently. Some key points:

  • Wrap await in try/catch to handle errors
  • Uncaught exceptions bubble up to the next try/catch block
  • Use .catch() on promises if try/catch is not used
  • Exceptions can be caught at the global level using process.on('uncaughtException')

22. What are the differences between Node.js and Ajax?

Node.js

  • JavaScript runtime environment for executing JS code on the server
  • Asynchronous and event-driven
  • Single threaded, highly scalable
  • Uses Chrome’s V8 JavaScript engine
  • Includes libuv for asynchronous I/O

AJAX

  • Async communication technique for client-side JavaScript
  • Allows requests to be made after page load
  • Uses XMLHttpRequest API for requesting data
  • Displays data without full page refresh
  • Used with modern frontend frameworks like React, Vue, Angular etc.

So in summary:

  • Node.js is a server-side runtime and AJAX is a client-side async communication technique.
  • Node.js allows JS execution on the server while AJAX facilitates communication between client and server.

23. How does Node.js handle multi-processor platforms?

Although Node.js uses a single thread with an event loop, it can take advantage of multiple processors cores using the Worker Threads module.

The key concepts are:

  • Main thread runs the server and event loop
  • Compute intensive tasks are offloaded to worker threads
  • Workers allow parallel execution on multiple CPUs
  • Main thread communicates via message passing
  • Promises and async/await used for sync code

For example:

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

const worker = new Worker('./script.js'); 

worker.postMessage(data); // send data to worker

worker.on('message', result => {
  // worker sent result 
});

So in summary, worker threads enable parallelism within a Node process while keeping the event loop single threaded.

24. How can you debug a Node.js application in production?

Here are some ways to debug Node.js apps in production:

  • Use console.log() statements to log debug info
  • Enable debug logs in your application or frameworks
  • Use external tracing systems like Datadog or New Relic
  • Attach debugger in code during startup
  • Enable debugging flags and increase verbosity
  • Use debuggers like node inspect and Chrome DevTools
  • Add more metrics and monitors for visibility
  • Write output to log files for analysis
  • Test and reproduce issues locally or on staging

The key is having enough visibility into the runtime without impacting performance. Logging and tracing solutions are designed to help debug production systems.

25. What is in-memory caching and how can you implement it in Node.js?

In-memory caching refers to temporarily storing data in memory for low latency access. Some ways to implement in-memory caching in Node.js:

  • Simple key-value cache using Map data structure
  • Use 3rd party cache like Redis for advanced capabilities
  • Use utility libraries like Node Cache Manager
  • Configure cache size, eviction policy, TTL, etc
  • Cache request results, database queries, API responses etc
  • Use cache first pattern – cache hit returns cached data
  • Rebuild cache lazily after cache expiry

For example:

const NodeCache = require("node-cache");
const cache = new NodeCache();

function getUser(id) {
  if (cache.has(id)) {
    return cache.get(id); 
  }

  // cache miss - fetch user from DB
}

Caching improves performance by avoiding expensive regeneration of data.

26. How can you secure passwords in a Node.js app?

Some best practices for securing passwords in Node.js:

  • Use bcrypt or scrypt for password hashing instead of plain text passwords.
  • Use salting and multiple rounds of computation for stronger hashes.
  • Ensure passwords are always hashed on the server, never on the client.
  • Use environment variables or a secure key management system for secret keys.
  • Enforce a minimum password length and complexity requirement.
  • Use parameterized queries or ORM to prevent SQL injection.
  • Ensure user registration, login and password management APIs are over HTTPS.
  • Implement rate limiting on authentication routes to prevent brute force attacks.
  • Follow OWASP password security guidelines.

Proper password hashing, salting and storing only hashed values are critical for application security.

27. What are some Server-Sent Events (SSE) best practices?

Some Server-Sent Event best practices include:

  • Use unique event names for each event type.
  • Send keep-alive events periodically to prevent timeouts.
  • Check EventSource readyState before sending data.
  • Handle connection loss gracefully and attempt reconnection.
  • Set retry timeout to balance reconnect frequency.
  • Send small events, don’t exceed memory limits.
  • Avoid sending plain text credentials. Use tokens instead.
  • Prefer SSE over websockets for one-way server to client comms.
  • Follow general security practices of encryption, auth, CORS etc.
  • Batch messages for reduced overhead if appropriate.
  • Implement reconnect timeouts to prevent stale connections.

SSE enables efficient real-time communication from server to client over HTTP. Following these practices ensures a smooth experience.

28. How does the Node.js event emitter work?

The event emitter module in Node.js allows publishing and subscribing to named events. Some key characteristics:

  • EventEmitter class provides interface to deal with events
  • .on() registers listener callback for an event
  • .emit() emits an event which calls all callbacks
  • Listeners registered first are called first
  • error and newListener are reserved events
  • Events allow loose coupling between modules
  • Useful for async communication/coordination

For example:

const EventEmitter = require('events');
const emitter = new EventEmitter();

emitter.on('message', (msg) => {
  console.log('Received: ' + msg);
});

emitter.emit('message', 'Hello World');

The event emitter enables pub-sub style communication between components/modules.

29. How can you create custom events in Node.js?

The events module in Node.js provides the EventEmitter class to create custom events:

  • Create event emitter instance
  • Call emitter.on() to add a listener for the event
  • Call emitter.emit() to trigger the event
  • Listener callbacks are invoked with any data passed

For example:

const EventEmitter = require('events');

class Logger extends EventEmitter {
  log(msg) {
    this.emit('message', `Logged: ${msg}`);
  }
}

const logger = new Logger();

logger.on('message', (msg) => {
  console.log(msg);  
});

logger.log('Hello World');

So in summary, extend the EventEmitter class, register listeners, and emit custom events as needed.

30. How can you improve web server performance in Node.js?

Some ways to improve web server performance in Node.js:

  • Use worker threads for CPU intensive tasks
  • Enable cluster mode to utilize multiple cores
  • Load balance requests across cluster workers
  • Use Node.js profiling tools to identify bottlenecks
  • Cache request results and database queries
  • Use memory wisely, limit memory leaks
  • Compress responses to reduce bandwidth
  • Defer non-critical work with queues
  • Limit unnecessary middleware use
  • Ensure DB queries are optimized
  • Use tools like Nginx for static content

Performance analysis, caching, parallelism, and optimization at multiple levels can significantly improve a Node.js server’s capabilities.

31. What are the key benefits of using Node.js?

Some of the key benefits of using Node.js include:

  • Asynchronous event-driven architecture
  • Single threaded, highly scalable
  • Great for real-time applications
  • Active and vibrant ecosystem
  • Large collection of open source packages
  • Uses JavaScript for fullstack development
  • High performance compared to other platforms
  • Suits microservices, fast and scalable services
  • Improves developer productivity and satisfaction

Node.js offers a powerful runtime that excels in building highly scalable network applications using JavaScript.

32. What is the Node.js Global Object?

The Node.js global object is a JavaScript object which is available everywhere. Some of its key attributes are:

  • Stores Node.js native modules like fs, http, path etc.
  • Stores global values like process, console, Buffer
  • Stores timer functions like setTimeout, clearTimeout
  • Contains helper methods like setImmediate and queueMicrotask
  • Stores global objects like the event emitter
  • Has Node.js environment details like __dirname
  • Allows requiring modules e.g. require(‘fs’)

In the Node REPL, you can inspect it using:

> global
{
  global: [Circular],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout]
  // ...
}

So in summary, the global object provides easy access to built-in modules, functions and values.

33. Explain the concept of Event Loop in Node.js

The event loop is the secret behind Node.js’ asynchronous, non-blocking behavior. Here are some key aspects:

  • Executes JavaScript code asynchronously
  • Uses an event queue for requests and responses
  • Node APIs register handler callbacks on event loop
  • Any I/O request gets added to queue instead of blocking
  • Single thread keeps pulling events from queue and executing callbacks
  • If queue is empty, it waits for callbacks to complete

So in essence, the event loop handles all async callbacks and operations while allowing synchronous code to run uninterrupted on the main thread. This makes Node.js highly performant and scalable.

34. How does Node.js handle errors?

Node.js has an asynchronous error handling paradigm. Some key aspects of error handling:

  • Errors in callbacks need to be handled or they will crash
  • Unhandled exceptions bubble up to outer try/catch block
  • Uncaught exceptions generated at top level terminate process
  • Best practice is to listen for uncaught exceptions on process
  • Can use domains for isolation and error handling
  • Lots of third party error handling modules available

For example:

process.on('uncaughtException', (err) => {
  console.log('Caught exception: ' + err);
});

Robust error handling prevents crashes and better notifies developers of issues.

35. How does Node.js support multi-processor platforms?

Although Node.js uses a single thread with event loop, it can leverage multiple cores in these ways:

  • Cluster module to spawn Node worker processes
  • Worker threads move heavyweight work out of main thread
  • Child processes can be spawned for parallelism
  • Node processes can communicate via messaging
  • Async patterns like promises allow concurrent requests
  • The single threaded event loop delegates work

So in essence, Node enables parallelism via processes, threads and asynchronous operations while keeping the main thread lightweight.

36. What are some key Node.js design patterns?

Some popular design patterns used in Node.js:

  • Event emitter – used to implement pub/sub for custom events
  • Streams – allows processing data as chunks in pipelines
  • Singleton – restrict instantiation of a class to one object
  • Factory – creates object instances based on input
  • Observer – allows subscription to events/changes
  • Async wrapper – wrap async code to look synchronous
  • Dependency injection – supply dependencies to classes
  • Namespaces – logical grouping of functionality

Understanding these patterns allows writing reusable and modular Node.js code.

37. What are some Node.js best practices?

Here are some recommended Node.js coding best practices:

  • Use async code and callbacks instead of blocking code
  • Handle errors properly for clean crashes
  • Avoid deep nested callbacks aka “callback hell”
  • Modularize code into reusable modules/files
  • Name functions and variables properly
  • Use promises for async code instead of callbacks
  • Use async/await for synchronous looking async code
  • Add debugging logs and metrics for observability
  • Follow security best practices for authentication, data validation etc
  • Lint code and run tests locally before committing
  • Match style to guidelines like Airbnb or Google style

Following these Node.js specific best practices results in cleaner and more robust code.

38. What is the Node.js Event Loop?

The event loop is the secret behind Node’s asynchronous, non-blocking behavior. Here are some key aspects:

  • Executes JavaScript code asynchronously
  • Uses an event queue for requests and responses
  • Node APIs register handler callbacks on event loop
  • Any I/O request gets added to queue instead of blocking
  • Single thread keeps pulling events from queue and executing callbacks
  • If queue is empty, it waits for callbacks to complete

So in essence, the event loop handles all async callbacks/ops allowing synchronous code to run on main thread. This makes Node.js highly performant and scalable.

39. What is ‘Callback Hell’ in Node.js and how can you avoid it?

Callback hell refers to heavily nested callbacks that make code difficult to read and maintain. Some ways to avoid it:

  • Modularize code into reusable functions
  • Use promises chains instead of callbacks
  • Use async/await to write async code that looks synchronous
  • Handle errors properly to avoid nested try/catch
  • Use libraries like async that abstract control flow
  • Leverage middleware and modules to flatten code
  • Write small functions that do just one thing

For example:

async function getUser() {
  try { 
    const user = await User.findOne({ id: 1 });
    return user;
  } catch (err) {
    handleError(err);
  }
}

is cleaner than nested callbacks. Avoiding callback hell results in code that is easier to reason about.

40. How can you implement a queue in Node.js?

Some ways to implement a queue in Node.js:

  • Use a simple array, with push and shift methods
  • Linked list data structure
  • 3rd party library like Bull queue
  • Redis provides List datatype that can be used as queue
  • Expose methods like enqueuedequeue and getLength
  • Use queue to defer non-urgent work

For example:

class Queue {
  constructor() {
    this.elements = [];
  }

  enqueue(item) {
    this.elements.push(item);
  }
  
  dequeue() {
    return this.elements.shift(); 
  }

  get length() {
    return this.elements.length;
  }
}

Queues provide reliable asynchronous processing and work distribution capabilities.

41. Explain Node.js Buffer class

The Buffer class in Node.js allows efficient manipulation of binary data:

  • Used to deal with TCP streams, file system operations
  • Allows representing sequences of bytes
  • Converts strings ↔ buffers, buffers ↔ JSON
  • Methods like buf.slice(), buf.toString(), buf.write() etc

For example:

const buf = Buffer.from('Hello'); 

console.log(buf[0]); // 72

buf[0] = 0x45; // E

console.log(buf.toString()); // Ello

Buffers provide a critical bridge between JavaScript strings and raw binary data.

42. How does Node.js support multi-core platforms?

Although Node uses a single thread event loop, it can leverage multiple cores in these ways:

  • Cluster module to spawn multiple Node worker processes
  • Worker threads move heavyweight work out of main thread
  • Child processes can be spawned for parallelism
  • Node processes communicate via messaging
  • Async patterns like promises allow concurrent requests
  • Event loop delegates work to cores but remains single threaded

So in summary, Node enables parallelism via processes, threads and async ops while keeping main thread lightweight.

43. What are some key benefits of Node.js?

Some key benefits of Node.js include:

  • Asynchronous event-driven architecture
  • Highly scalable and performant
  • Great for real-time web applications
  • Active and vibrant ecosystem
  • Simplified fullstack development using JavaScript
  • High throughput compared to other technologies
  • Easy to get started and build fast, scalable services
  • Improves developer productivity and satisfaction

Node.js offers a powerful runtime that excels in building highly scalable network applications using JavaScript.

44. How does Node.js handle child threads?

Although Node.js is single threaded, it can handle child threads using the child_process module:

  • child_process.spawn() method spawns a new process
  • child_process.fork() spawns a Node.js child process
  • child_process.exec() runs a command in a shell
  • The main and child processes can communicate via IPC
  • Promises and async/await provide synchronous feeling code

For example:

const { fork } = require('child_process');

const child = fork('script.js');

child.on('message', (msg) => {
  console.log('Message from child', msg); 
});

So in summary, child processes enable parallelism and isolation while the main thread remains single threaded.

45. How does Node.js handle errors?

Node.js has an asynchronous error handling paradigm:

  • Unhandled exceptions in callbacks will crash Node
  • Use try/catch to handle errors in callbacks
  • Uncaught exceptions bubble up to outer try/catch blocks
  • Uncaught exceptions at top level terminate process
  • Listen for ‘uncaughtException’ on process
  • Use domains for isolation and handling errors

46. What are some key differences between Node.js and PHP?

Node.js

  • Async and event-driven architecture
  • Single threaded, highly scalable
  • Uses JavaScript for fullstack development
  • Great for real-time applications
  • module ecosystem (npm)
  • Non-blocking I/O allows high throughput
  • Well suited for microservices

PHP

  • Scripting language designed for web dev
  • Traditionally used on server with Apache
  • Blocking I/O causes performance issues at scale
  • Not ideal for highly concurrent workloads
  • Strong support for web features like sessions and cookies
  • Familiar syntax for front-end devs switching to backend

In summary, Node.js is well-suited for I/O bound, scalable applications while PHP caters more towards traditional LAMP stack web development.

47. What are some key benefits of the Node.js event loop?

Some benefits of the Node.js event loop include:

  • Asynchronous non-blocking behavior
  • High throughput and scalability
  • Single threaded yet highly performant
  • Great for I/O bound applications
  • Promotes asynchronous coding style
  • Simplified concurrency handling with callbacks
  • Facilitates loose coupling between modules
  • Enables real-time communication between client and server

The event loop makes Node.js efficient, concurrent and well suited for real-time web applications.

48. What is the purpose of the Node.js util module?

The util module provides various utility functions and helpers:

  • util.promisify() converts callback style APIs to promises
  • util.inherits() implements inheritance in JavaScript
  • util.inspect() returns object representation as string
  • util.types() returns internal object types
  • util.format() formats strings like printf in C
  • util.debuglog() creates a debug logger
  • util.deprecate() marks a function as deprecated

For example:

const util = require('util');

const name = 'John';

console.log(util.format('%s is %d years old', name, 30));  
// John is 30 years old

The util module provides useful utility functions to simplify development.

49. How can you improve security of Node.js apps?

Some tips for improving security of Node.js applications:

  • Use security focused frameworks like Helmet
  • Implement encryption, authentication, authorization properly
  • Validate, sanitize and encode user inputs
  • Avoid SQL/NoSQL injection vulnerabilities
  • Use parameterized queries or ORM libraries
  • Enable CORS selectively rather than globally
  • Set HTTP headers for security (Content Security Policy etc.)
  • Keep dependencies up to date
  • Use tools like npm audit to detect vulnerabilities
  • Limit concurrent requests using a middleware if needed
  • Follow all OWASP security best practices

A combination of secure coding practices, tools, and constant vigilance helps keep Node.js apps secure.

50. What are some key Node.js deployment best practices?

Some key deployment practices for Node.js apps:

  • Set NODE_ENV to control enabling debug logs
  • Enable cluster mode with load balancing for production
  • Run processes using PM2 for uptime and restarting crashes
  • Separate app into dev, test and prod dependencies
  • Create staging deployments identical to production
  • Use continuous integration tools like TravisCI
  • Monitor app and infra health with metrics collection
  • Enable security features like firewalls and SSH
  • Set up log aggregation/tracking
  • Automate deployments and use blue/green technique
  • Plan redundancy for infra and services
  • Have a rollback strategy in case of issues

Following standardized deployment patterns and automation helps minimize production issues and improve reliability.

Conclusion

Node.js is a powerful and flexible runtime that offers key advantages like asynchronous programming, high scalability, and fullstack JavaScript capabilities. Mastering advanced Node.js concepts like its event loop, streams, worker threads, security practices etc. allows developers to build fast and robust applications. Hopefully these Node.js interview questions provide a useful jumping-off point for understanding its capabilities!

Leave a Reply

Your email address will not be published. Required fields are marked *