Node.js Backend Developer Guide
Node.js Backend Developer Guide
-
Hello and welcome! I'm Parikh Jain, and I'm excited to share with you the
ultimate guide to become a MERN stack full stack developer. This kit is a labor
of love, drawn from my extensive journey as an SDE at Amazon, a founding
member at Coding Ninjas, and the founder of ProPeers. I’ve distilled my real-
world experience into a comprehensive resource that covers every topic you
need to excel.
5. Database Integration
9. Real-Time Communication
Target Audience
Aspiring [Link] Developers: Beginners who want to learn [Link]
fundamentals and build a strong foundation in backend development.
Hands-On Practice: Implement the provided code snippets and modify them
to suit your project requirements. Use the challenges as a starting point to
build more complex systems.
Reference Material: Use the Additional Resources section for further reading,
exploring useful [Link] packages, and staying updated with the latest trends.
Important Concepts
What is [Link]?
Event-Driven Architecture:
[Link] uses a non-blocking, event-driven architecture that makes it
lightweight and efficient—ideal for data-intensive real-time applications.
Full-Stack Integration:
[Link] seamlessly integrates with various frontend frameworks (like React,
Angular, or Vue) and databases (like MongoDB) to build modern full-stack
applications.
Expected Answer: [Link] is widely used for building REST APIs, real-time
applications (e.g., chat apps, live dashboards), microservices, single-page
applications (SPAs), and data streaming applications.
This introductory section sets the stage for the rest of the guide. It provides an
overview of what [Link] is, its key advantages, and how it fits into modern
backend development. The interview questions help assess your foundational
knowledge and understanding of the [Link] ecosystem.
Important Concepts
[Link] Runtime:
[Link] is a JavaScript runtime built on Chrome's V8 engine that allows
JavaScript to be executed on the server side.
npm is used to install, manage, and update [Link] packages and libraries.
Visit the [Link] official website and download the LTS version.
2. Verify Installation:
bash
Copy
node -v
npm -v
Important Concepts
Project Metadata:
npm Initialization:
Use npm init (or npm init -y for default settings) to generate the [Link] file.
bash
Copy
npm init -y
Sample [Link]
json
Copy
{
"name": "node-backend-project",
"version": "1.0.0",
"description": "A sample [Link] backend project",
"main": "[Link]",
"scripts": {
"start": "node [Link]",
"dev": "nodemon [Link]",
"test": "jest"
},
"author": "Your Name",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^2.0.20",
Important Concepts
Installing Dependencies:
npm Scripts:
Scripts defined in [Link] automate tasks like starting the server or running
tests.
Code Snippets
1. Install Express:
bash
Copy
npm install express
json
Copy
"scripts": {
"start": "node [Link]",
"dev": "nodemon [Link]",
"test": "jest"
}
bash
Copy
npm start # Starts the server
npm run dev # Starts the server with hot-reloading (nodemon)
npm test # Runs tests with Jest
Important Concepts
Integrated Development Environments (IDEs):
Tools like Visual Studio Code (VS Code) and WebStorm provide rich features
(debugging, extensions, Git integration) for [Link] development.
Version Control:
Use Git to manage source code. Create a .gitignore file to exclude files such as
node_modules/ .
Code Snippets
1. VS Code Settings ( .vscode/[Link] ):
json
Copy
{
"[Link]": true,
"[Link]": true,
2. Git Setup:
bash
Copy
git init
gitignore
Copy
node_modules/
.env
bash
Copy
git add .
git commit -m "Initial commit"
git push origin main
Answer:
bash
Copy
node -v
npm -v
Expected Output: Version numbers for both [Link] and npm confirm proper
installation.
Interview Question 2
Q: How do you initialize a new [Link] project and create a [Link] file?
Answer:
Explanation: Run the command npm init -y in your project directory to create a
default [Link] file.
Code Example:
bash
Copy
npm init -y
Interview Question 3
Q: How do you install a dependency (e.g., Express) and ensure it is saved in your
project?
Answer:
Code Example:
bash
Copy
npm install express
Interview Question 4
Q: How can npm scripts help streamline development workflows, and how do you
run them?
Answer:
Explanation: npm scripts automate common tasks like starting the server,
running tests, or launching development tools. They are defined in the scripts
section of [Link] and can be run using npm start or npm run <script-name> .
json
Copy
"scripts": {
"start": "node [Link]",
"dev": "nodemon [Link]",
"test": "jest"
}
Run Script:
bash
Copy
Interview Question 5
Q: How do you set up version control for a [Link] project using Git?
Answer:
Explanation: Initialize a Git repository with git init , create a .gitignore file to
exclude node_modules and other sensitive files, and use Git commands to
manage changes.
Code Example:
bash
Copy
git init
gitignore
Copy
node_modules/
.env
bash
Copy
git add .
git commit -m "Initial commit"
git push origin main
Install [Link] and npm: Verify installations with simple terminal commands.
Use Essential Tools: Configure your IDE with helpful extensions and set up Git
for version control.
The interview questions and code challenges provided are designed to reinforce
your understanding of the environment setup and tooling—a critical foundation for
[Link] backend development.
Express Instance:
Middleware:
javascript
Copy
// [Link]
const express = require('express');
const app = express();
const PORT = [Link] || 3000;
Routing:
Define endpoints to respond to different HTTP methods (GET, POST, etc.).
Middleware Functions:
Functions that intercept and process requests before passing them on to the
next handler.
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
[Link] = router;
javascript
Copy
// [Link] (continued)
const greetingRoute = require('./routes/greeting');
[Link]('/api', greetingRoute);
javascript
Copy
// middleware/[Link]
function logger(req, res, next) {
[Link](`[${new Date().toISOString()}] ${[Link]} ${[Link]}`);
next();
}
Usage in [Link]:
javascript
Copy
const logger = require('./middleware/logger');
[Link](logger);
Request Logging:
Use libraries like Morgan to log HTTP requests automatically.
javascript
Copy
// middleware/[Link]
function errorHandler(err, req, res, next) {
[Link]('Error:', [Link]);
[Link](500).json({ error: 'Something went wrong!' });
}
[Link] = errorHandler;
javascript
Copy
const morgan = require('morgan');
// Log requests in development mode
[Link](morgan('dev'));
Interview Question 1
Q: How do you set up a basic Express server and start it?
Answer:
You create an Express instance, use middleware to parse JSON (if needed),
define your routes, and finally start the server using [Link]() .
Code Example:
Interview Question 2
Q: What is middleware in Express, and how do you implement it?
Answer:
Code Example:
(See the logger middleware snippet above.)
Interview Question 3
Q: How do you handle errors in an Express application?
Answer:
By creating error handling middleware that takes four parameters (err, req, res,
next) and adding it after your routes.
Code Example:
(See the errorHandler middleware snippet above.)
Interview Question 4
Q: What is the difference between [Link]() and [Link]() in Express?
Answer:
[Link]() applies middleware only to the routes defined within that router.
Code Example:
javascript
Copy
// Global middleware using [Link]()
[Link]((req, res, next) => {
[Link]('Global middleware');
next();
});
// Router-specific middleware
const router = [Link]();
[Link]((req, res, next) => {
Interview Question 5
Q: How do you log HTTP requests in an Express application?
Answer:
You can use logging middleware like Morgan to automatically log details of
incoming HTTP requests.
Code Example:
(See the Morgan snippet above.)
Interview Question 6
Q: How can you modularize routes in an Express application?
Answer:
You can create separate router modules and use [Link]() to mount them on
specific paths.
Code Example:
javascript
Copy
// In routes/[Link]
const express = require('express');
const router = [Link]();
// In [Link]
const usersRouter = require('./routes/users');
[Link]('/api/users', usersRouter);
Summary
In this section, you learned to:
Define routes using both the main application and modular routers.
The interview questions and code challenges provided here reinforce your
understanding of Express fundamentals and prepare you to discuss and
implement these concepts in real-world scenarios.
HTTP Methods:
Status Codes:
Use proper HTTP status codes (e.g., 200, 201, 400, 404, 500) to communicate
the outcome of API requests.
Data Validation:
Validate incoming data to ensure correctness using libraries like express-
validator or custom middleware.
API Versioning:
Organize endpoints into versions (e.g., /api/v1/ ) to handle changes over time.
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
[Link] = router;
javascript
Copy
// [Link]
const express = require('express');
const app = express();
const PORT = [Link] || 3000;
// Global error handler (optional, see next section for more on error handling)
[Link]((err, req, res, next) => {
[Link]('Error:', [Link]);
[Link](500).json({ error: 'Internal Server Error' });
});
Interview Question 1
Q: What is REST, and what are its main principles?
Answer:
Interview Question 2
Q: How do you implement a basic GET endpoint in Express?
Answer:
Code Example:
javascript
Copy
// GET /api/hello
[Link]('/api/hello', (req, res) => {
[Link](200).json({ message: 'Hello World' });
});
Interview Question 3
Code Example: (Refer to the POST handler in the users router above.)
javascript
Copy
[Link]('/', (req, res) => {
const { name, email } = [Link];
const newUser = { id: [Link] + 1, name, email };
[Link](newUser);
[Link](201).json(newUser);
});
Interview Question 4
Q: How do you handle URL parameters in Express routes?
Answer:
Code Example:
javascript
Copy
// GET /api/users/:id
[Link]('/:id', (req, res) => {
const userId = [Link];
// Find user by userId...
});
Interview Question 5
Q: How do you validate request data in Express?
Code Example:
javascript
Copy
const { body, validationResult } = require('express-validator');
[Link]('/',
body('name').notEmpty().withMessage('Name is required'),
body('email').isEmail().withMessage('Valid email is required'),
(req, res) => {
const errors = validationResult(req);
if (![Link]()) {
return [Link](400).json({ errors: [Link]() });
}
// Proceed to create user...
}
);
Interview Question 6
Q: What HTTP status code would you use for a successful resource creation, and
why?
Answer:
Explanation: HTTP 201 (Created) indicates that the request has been fulfilled
and has resulted in a new resource being created.
Interview Question 7
Q: How do you implement a PUT endpoint to update a resource?
Code Example:
javascript
Copy
[Link]('/:id', (req, res) => {
const user = [Link](u => [Link] === parseInt([Link]));
if (!user) return [Link](404).json({ error: 'User not found' });
const { name, email } = [Link];
[Link] = name || [Link];
[Link] = email || [Link];
[Link](200).json(user);
});
Interview Question 8
Q: How do you delete a resource using Express?
Answer:
Code Example:
javascript
Copy
[Link]('/:id', (req, res) => {
const index = [Link](u => [Link] === parseInt([Link]));
if (index === -1) return [Link](404).json({ error: 'User not found' });
const deletedUser = [Link](index, 1);
[Link](200).json(deletedUser);
});
Interview Question 9
Q: How do you implement API versioning in your REST API?
Code Example:
javascript
Copy
// Mount versioned router
const v1Router = require('./routes/v1/users');
[Link]('/api/v1/users', v1Router);
Interview Question 10
Q: How do you implement pagination in a REST API?
Answer:
Code Example:
javascript
Copy
[Link]('/', (req, res) => {
const page = parseInt([Link]) || 1;
const limit = parseInt([Link]) || 10;
const startIndex = (page - 1) * limit;
const paginatedUsers = [Link](startIndex, startIndex + limit);
[Link](200).json(paginatedUsers);
});
Interview Question 11
Code Example:
javascript
Copy
[Link]('/:id', (req, res, next) => {
try {
const user = [Link](u => [Link] === parseInt([Link]));
if (!user) return [Link](404).json({ error: 'User not found' });
[Link](200).json(user);
} catch (err) {
next(err);
}
});
// And a global error handler:
[Link]((err, req, res, next) => {
[Link](err);
[Link](500).json({ error: 'Internal Server Error' });
});
Interview Question 12
Q: What are the differences between HTTP methods GET, POST, PUT, and
DELETE?
Answer:
Explanation:
Interview Question 13
Q: How do you secure your REST API endpoints in Express?
Answer:
Code Example:
javascript
Copy
const { authenticateToken } = require('./middleware/auth');
[Link]('/protected', authenticateToken, (req, res) => {
[Link](200).json({ message: 'Protected data' });
});
Interview Question 14
Q: How do you document your REST API so that frontend developers can easily
understand and use it?
Answer:
Interview Question 15
Answer:
Code Example:
javascript
Copy
// Directory structure:
// - controllers/
// [Link]
// - routes/
// [Link]
//
// In controllers/[Link]:
[Link] = (req, res) => {
[Link](200).json(users);
};
// In routes/[Link]:
const express = require('express');
const router = [Link]();
const userController = require('../controllers/userController');
[Link]('/', [Link]);
[Link] = router;
Summary of Section 4
In this section, you learned how to design and implement RESTful APIs with
Express by:
Implementing data validation, proper HTTP status codes, and error handling.
The 15+ interview questions provided are designed to reinforce these concepts
with practical code examples, ensuring you can both implement and explain your
API design choices during technical interviews.
5. Database Integration
Modern [Link] backend applications often use NoSQL databases like MongoDB
for flexibility and scalability. Mongoose is a popular ODM (Object Data Modeling)
library that simplifies working with MongoDB in [Link].
MongoDB:
A NoSQL database that stores data in JSON-like documents.
Mongoose:
An ODM that provides a straightforward schema-based solution to model
application data.
javascript
Copy
// [Link]
const mongoose = require('mongoose');
[Link] = connectDB;
javascript
Copy
// [Link] (at the top)
const connectDB = require('./db');
connectDB();
Schema Definition:
Define the structure of your documents using Mongoose schemas.
Models:
Create models based on schemas to interact with the corresponding
MongoDB collections.
javascript
Copy
// models/[Link]
const mongoose = require('mongoose');
Express Integration:
Use Mongoose within Express routes to handle database operations.
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
const User = require('../models/User');
// Get user by ID
[Link]('/:id', async (req, res, next) => {
try {
const user = await [Link]([Link]);
if (!user) return [Link](404).json({ error: 'User not found' });
[Link](200).json(user);
} catch (err) {
next(err);
}
});
// Update user by ID
[Link]('/:id', async (req, res, next) => {
try {
const updatedUser = await [Link](
[Link],
// Delete user by ID
[Link]('/:id', async (req, res, next) => {
try {
const deletedUser = await [Link]([Link]);
if (!deletedUser) return [Link](404).json({ error: 'User not found' });
[Link](200).json(deletedUser);
} catch (err) {
next(err);
}
});
[Link] = router;
javascript
Copy
const userRoutes = require('./routes/users');
[Link]('/api/users', userRoutes);
javascript
Copy
// routes/[Link] (add this endpoint)
[Link]('/paginated', async (req, res, next) => {
try {
const page = parseInt([Link]) || 1;
const limit = parseInt([Link]) || 10;
const skip = (page - 1) * limit;
const users = await [Link]().skip(skip).limit(limit).sort({ username: 1 });
[Link](200).json(users);
} catch (err) {
next(err);
}
});
Relationships:
Embedding vs. referencing documents.
Middleware (Hooks):
Pre/post hooks in Mongoose to perform actions before or after operations.
In the User model, you can reference posts (if needed) or simply populate posts in
your queries:
javascript
Copy
// Query with population example:
[Link](userId).populate('posts').exec((err, user) => {
// [Link] will contain the related posts
});
Interview Question 1
Q: What is Mongoose, and why would you use it with MongoDB?
Answer:
Interview Question 2
Q: How do you define a schema and create a model in Mongoose?
Answer:
Code Example:
javascript
Copy
const mongoose = require('mongoose');
Interview Question 3
Q: How do you connect to MongoDB using Mongoose?
Answer:
Code Example:
(Refer to the connection snippet in Part 5.1.1)
javascript
Copy
[Link]('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => [Link]('MongoDB Connected'))
.catch(err => [Link](err));
Interview Question 4
Q: How do you perform a create operation (insert a document) using Mongoose?
Answer:
Code Example:
javascript
Copy
// Creating and saving a user document
const newUser = new User({ username: 'charlie', email: 'charlie@example.
com' });
[Link]()
.then(user => [Link]('User created:', user))
.catch(err => [Link](err));
Interview Question 5
Q: How do you read (retrieve) documents from MongoDB using Mongoose?
Answer:
Code Example:
javascript
Copy
// Find a user by ID
[Link]('userIdHere')
.then(user => [Link]('User:', user))
.catch(err => [Link](err));
Interview Question 6
Q: How do you update a document using Mongoose?
Answer:
Code Example:
javascript
Copy
[Link](
'userIdHere',
{ email: 'newemail@[Link]' },
{ new: true, runValidators: true }
)
.then(updatedUser => [Link]('Updated User:', updatedUser))
.catch(err => [Link](err));
Interview Question 7
Q: How do you delete a document using Mongoose?
Answer:
Code Example:
Interview Question 8
Q: How do you implement pagination in a Mongoose query?
Answer:
Code Example:
(Refer to the pagination endpoint snippet in Part 5.1.4)
javascript
Copy
const page = parseInt([Link]) || 1;
const limit = parseInt([Link]) || 10;
const skip = (page - 1) * limit;
[Link]().skip(skip).limit(limit)
.then(users => [Link](users))
.catch(err => next(err));
Interview Question 9
Q: How do you use Mongoose middleware (hooks) to perform actions before
saving a document?
Answer:
Code Example:
Interview Question 10
Q: How do you define a relationship between two collections in Mongoose?
Answer:
Code Example:
javascript
Copy
// In [Link]
const PostSchema = new [Link]({
title: String,
content: String,
user: { type: [Link], ref: 'User' }
});
Interview Question 11
Q: How do you populate referenced documents in Mongoose?
Answer:
javascript
Copy
[Link]().populate('user')
.then(posts => [Link]('Posts with user details:', posts))
.catch(err => [Link](err));
Interview Question 12
Q: How do you implement data validation in a Mongoose schema?
Answer:
Code Example:
javascript
Copy
const UserSchema = new [Link]({
username: { type: String, required: [true, 'Username is required'], unique:
true },
email: { type: String, required: [true, 'Email is required'], unique: true }
});
Interview Question 13
Q: How can you implement indexing in MongoDB using Mongoose?
Answer:
Code Example:
javascript
Copy
Interview Question 14
Q: How do you handle errors during database operations in Mongoose?
Answer:
Code Example:
javascript
Copy
async function getUser(id) {
try {
const user = await [Link](id);
return user;
} catch (err) {
[Link]('Database error:', err);
throw err;
}
}
Interview Question 15
Q: How do you implement transactions in Mongoose?
Answer:
Code Example:
Interview Question 16
Q: How do you optimize queries in Mongoose for better performance?
Answer:
Code Example:
javascript
Copy
Interview Question 17
Q: How do you seed initial data into a MongoDB collection using Mongoose?
Answer:
Explanation: Create a seed script that imports your models and inserts
documents.
Code Example:
javascript
Copy
// [Link]
const mongoose = require('mongoose');
const User = require('./models/User');
const connectDB = require('./db');
seed();
Connecting to MongoDB.
The 15+ interview questions with sample code snippets reinforce these concepts
and prepare you to explain your database integration strategies during technical
interviews.
jsonwebtoken Library:
A popular [Link] library for generating and verifying JWTs.
[Link] = router;
javascript
Copy
// middleware/[Link]
const jwt = require('jsonwebtoken');
const secret = [Link].JWT_SECRET || 'your_jwt_secret';
[Link] = authenticateToken;
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
const authenticateToken = require('../middleware/authenticate');
[Link] = router;
bcrypt:
A widely used library for hashing and comparing passwords securely.
javascript
Copy
// utils/[Link]
const bcrypt = require('bcrypt');
// Example usage:
hashPassword('myPlainPassword')
.then(hashed => [Link]('Hashed password:', hashed))
.catch(err => [Link](err));
[Link] = hashPassword;
javascript
Copy
// utils/[Link]
const bcrypt = require('bcrypt');
// Example usage:
const plain = 'myPlainPassword';
const hashed = '$2b$10$D4G5f18o7aMMfwasBlh6Lu...'; // Example hash
verifyPassword(plain, hashed)
.then(match => [Link]('Password match:', match))
.catch(err => [Link](err));
[Link] = verifyPassword;
javascript
Copy
// routes/[Link]
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const router = [Link]();
const secret = [Link].JWT_SECRET || 'your_jwt_secret';
// User Registration
[Link]('/register', async (req, res) => {
const { username, password, email } = [Link];
const hashedPassword = await [Link](password, 10);
const newUser = { id: [Link] + 1, username, email, password: hashedP
assword };
[Link](newUser);
[Link](201).json({ message: 'User registered successfully' });
});
// User Login
[Link]('/login', async (req, res) => {
const { username, password } = [Link];
const user = [Link](u => [Link] === username);
if (!user) return [Link](400).json({ error: 'User not found' });
[Link] = router;
Interview Question 1
Q: What is JWT and why is it used in authentication?
Answer:
Interview Question 2
Q: How do you generate a JWT token in [Link]?
Answer:
Code Example:
javascript
Copy
const jwt = require('jsonwebtoken');
const secret = [Link].JWT_SECRET || 'your_jwt_secret';
Interview Question 3
Q: How do you verify a JWT token in Express middleware?
Answer:
Code Example:
(See the authenticateToken middleware snippet in Part 6.1.1.)
Interview Question 4
Q: How do you protect a route so that only authenticated users can access it?
Answer:
Code Example:
javascript
Copy
const authenticateToken = require('./middleware/authenticate');
Interview Question 5
Code Example:
(See the hashPassword function in Part 6.1.2.)
Interview Question 6
Q: How do you compare a plain text password with a hashed password?
Answer:
Code Example:
(See the verifyPassword function in Part 6.1.2.)
Interview Question 7
Q: What are the benefits of using JWT for authentication over traditional sessions?
Answer:
Explanation: JWTs are stateless, reducing server load, and they allow easy
scaling across multiple servers. They also enable decoupled authentication
between services.
Interview Question 8
Q: How do you handle token expiration in your [Link] application?
Answer:
Code Example:
javascript
Copy
// In authenticateToken middleware:
[Link](token, secret, (err, user) => {
if (err) return [Link](403); // Token invalid or expired
[Link] = user;
next();
});
Interview Question 9
Q: How do you implement role-based access control (RBAC) in [Link]?
Answer:
Code Example:
javascript
Copy
// Middleware: [Link]
function checkRole(requiredRole) {
return (req, res, next) => {
if ([Link] !== requiredRole) {
return [Link](403).json({ error: 'Access denied' });
}
next();
};
}
[Link] = checkRole;
Interview Question 10
Q: What is the difference between authentication and authorization?
Answer:
Interview Question 11
Q: How do you store sensitive information like JWT secret keys?
Answer:
Code Example:
javascript
Copy
// Using environment variable
const secret = [Link].JWT_SECRET;
Interview Question 12
Q: How do you implement a refresh token mechanism in [Link]?
Explanation: A refresh token is issued alongside the access token and has a
longer expiration. When the access token expires, the client can request a new
access token by presenting the refresh token.
javascript
Copy
// On login:
const accessToken = [Link]({ id: [Link], username: [Link] }, se
cret, { expiresIn: '15m' });
const refreshToken = [Link]({ id: [Link], username: [Link] }, se
cret, { expiresIn: '7d' });
[Link]({ accessToken, refreshToken });
// Refresh endpoint:
[Link]('/token', (req, res) => {
const { token } = [Link];
if (!token) return [Link](401);
[Link](token, secret, (err, user) => {
if (err) return [Link](403);
const newAccessToken = [Link]({ id: [Link], username: [Link]
e }, secret, { expiresIn: '15m' });
[Link]({ accessToken: newAccessToken });
});
});
Interview Question 13
Q: How do you mitigate common vulnerabilities in authentication (e.g., brute-
force, token theft)?
Answer:
No detailed code snippet is required, but you can mention using packages like
express-rate-limit and setting secure cookie flags.
Interview Question 14
Q: How do you integrate password reset functionality securely?
Answer:
Interview Question 15
Q: How do you log authentication-related events for security auditing?
Answer:
Explanation: Use logging libraries (like Winston) to log critical events (failed
logins, token refreshes, etc.) with proper log rotation and secure storage.
Code Example:
javascript
Copy
const winston = require('winston');
const logger = [Link]({
level: 'info',
transports: [
new [Link](),
new [Link]({ filename: '[Link]' })
]
});
Summary of Section 6
In this section, you learned how to implement robust authentication and
authorization in a [Link] backend application by:
The 15+ interview questions and code challenges provided help reinforce these
concepts, ensuring you can both implement secure authentication and articulate
your solutions during technical interviews.
Unit Tests:
Verify the functionality of individual units (functions, modules) in isolation.
javascript
Copy
// utils/[Link]
function add(a, b) {
return a + b;
}
[Link] = { add };
javascript
Copy
// tests/[Link]
const { add } = require('../utils/math');
bash
Copy
npm test
Supertest:
A library for testing HTTP endpoints in [Link] by simulating requests.
javascript
Copy
// [Link]
const express = require('express');
const app = express();
const PORT = [Link] || 3000;
[Link]([Link]());
[Link] = app;
javascript
Copy
// tests/[Link]
const request = require('supertest');
const app = require('../server');
TDD:
Write tests before writing the actual code. This ensures that your code meets
the specified requirements.
Cycle:
Red (fail) → Green (pass) → Refactor.
javascript
Copy
// tests/[Link]
const { increment } = require('../utils/counter');
test('increment should add 1 to the number', () => {
expect(increment(1)).toBe(2);
});
javascript
Copy
CI Pipelines:
Automate tests on every push/commit using tools like GitHub Actions or
Jenkins.
yaml
Copy
# .github/workflows/[Link]
name: [Link] CI
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
steps:
- uses: actions/checkout@v2
- name: Use [Link] ${{ [Link]-version }}
uses: actions/setup-node@v2
with:
Interview Question 1
Q: What is the difference between unit tests and integration tests?
A:
Answer:
Interview Question 2
Q: How do you set up Jest for a [Link] project?
A:
Answer:
Install Jest as a dev dependency and add a test script in [Link] .
Code Example:
bash
Copy
npm install --save-dev jest
Interview Question 3
Q: How do you write a unit test for a function that adds two numbers?
A:
Code Example:
(See the add function and its test in the Unit Testing with Jest example above.)
Interview Question 4
Q: How do you test an Express API endpoint using Supertest?
A:
Code Example:
javascript
Copy
const request = require('supertest');
const app = require('../server');
Answer:
TDD is a process where you write tests before implementing functionality. This
ensures that code meets requirements and improves code quality.
Interview Question 6
Q: How do you mock external dependencies in Jest?
A:
Answer:
Use Jest’s built-in mocking functions to simulate external modules.
Code Example:
javascript
Copy
// Suppose we have a module that fetches data from an API
const axios = require('axios');
[Link]('axios');
Interview Question 7
Code Example:
javascript
Copy
test('async function returns data', async () => {
const data = await someAsyncFunction();
expect(data).toBeDefined();
});
Interview Question 8
Q: What is the purpose of the .lean() method in Mongoose queries during testing?
A:
Answer:
The .lean() method returns plain JavaScript objects instead of Mongoose
documents, which can speed up tests by reducing overhead.
Interview Question 9
Q: How do you integrate continuous testing in a CI pipeline for [Link]?
A:
Answer:
Use a CI tool (e.g., GitHub Actions) to automatically run tests on every push or
pull request.
Code Example:
(Refer to the GitHub Actions workflow snippet above.)
Code Example:
javascript
Copy
// In your test file
afterAll(async () => {
await [Link]();
});
Interview Question 11
Q: How do you simulate HTTP errors in your integration tests using Supertest?
A:
Code Example:
javascript
Copy
test('GET /api/unknown should return 404', async () => {
const res = await request(app).get('/api/unknown');
expect([Link]).toBe(404);
});
Interview Question 12
Q: How do you test middleware functions independently in Express?
A:
Code Example:
javascript
Copy
const logger = require('../middleware/logger');
Interview Question 13
Q: How do you handle timeouts and slow responses in your tests?
A:
Answer:
Use Jest’s timeout configuration ( [Link]() ) or set individual test timeouts.
Code Example:
javascript
Copy
[Link](10000); // Sets timeout to 10 seconds for all tests
Code Example:
javascript
Copy
test('errorHandler middleware sends 500 status', () => {
const err = new Error('Test error');
const req = {};
const res = { status: [Link]().mockReturnThis(), json: [Link]() };
const next = [Link]();
expect([Link]).toHaveBeenCalledWith(500);
expect([Link]).toHaveBeenCalledWith({ error: 'Something went wrong!'
});
});
Interview Question 15
Q: How do you simulate and test token expiration in a JWT authentication
workflow?
A:
Answer:
Generate a token with a short expiration, wait for it to expire, and then assert
that the authentication middleware rejects it.
Code Example:
Summary of Section 7
In this section, you have learned how to:
The 15+ interview questions provided cover both conceptual and practical aspects
of testing and quality assurance, preparing you to both write tests and discuss
your testing strategy in technical interviews.
Caching:
Storing frequently accessed data in memory to reduce latency and improve
throughput.
Redis:
bash
Copy
npm install redis
javascript
Copy
// [Link]
const redis = require('redis');
const client = [Link]({ host: '[Link]', port: 6379 });
[Link]('connect', () => {
[Link]('Connected to Redis');
});
[Link] = client;
javascript
Copy
// routes/[Link]
const express = require('express');
[Link] = router;
Lean Queries:
In MongoDB/Mongoose, using .lean() returns plain JavaScript objects instead
of Mongoose documents, reducing overhead.
Code Profiling:
Use tools like [Link] built-in profiler or external tools (e.g., [Link]) to
identify bottlenecks.
javascript
Copy
// Example usage in a route
[Link]('/users/lean', async (req, res, next) => {
try {
const users = await [Link]().lean(); // Returns plain objects
[Link](200).json(users);
} catch (err) {
next(err);
}
});
Rate Limiting:
Prevents abuse and ensures fair usage by limiting the number of requests per
client within a specified time window.
express-rate-limit:
A middleware to apply rate limiting on Express routes.
1. Installation:
bash
Copy
npm install express-rate-limit
[Link] = limiter;
javascript
Copy
// [Link] (or within specific routes)
const rateLimiter = require('./middleware/rateLimiter');
[Link]('/api/', rateLimiter);
Interview Question 1
Q: What is caching, and why is it important in backend development?
Answer:
Interview Question 2
Q: How do you integrate Redis into a [Link] application?
Answer:
Code Example:
(See the [Link] snippet above.)
Interview Question 3
Q: How can you cache API responses using Redis in an Express application?
Answer:
Code Example:
(Refer to the /data endpoint in the routes/[Link] snippet above.)
Interview Question 4
Q: What is the purpose of using the .lean() method in Mongoose queries?
Answer:
Interview Question 5
Q: How do you implement rate limiting in an Express application?
Answer:
Code Example:
(See the [Link] snippet and its usage in [Link] above.)
Interview Question 7
Q: How would you test if your Redis caching layer is working correctly?
Answer:
Code Example:
javascript
Copy
// Test route to verify caching
[Link]('/test-cache', (req, res, next) => {
const key = 'test:key';
[Link](key, (err, data) => {
if (data) {
return [Link]({ cached: true, data: [Link](data) });
}
const freshData = { value: 'fresh data' };
[Link](key, 3600, [Link](freshData));
[Link]({ cached: false, data: freshData });
});
});
Interview Question 8
Explanation: By tuning the rate limit thresholds (windowMs and max) based
on expected traffic, and providing clear error messages or fallback options.
Interview Question 9
Q: How do you configure multiple Redis instances for scaling caching?
Answer:
Interview Question 10
Q: How would you handle cache invalidation when underlying data changes?
Answer:
Interview Question 11
Q: How can you monitor the performance of your [Link] application?
Answer:
Answer: Use profiling tools like [Link], [Link] built-in profiler, and logging
libraries to monitor memory usage, response times, and CPU usage.
Code Example:
javascript
Copy
// Example using environment variables
const windowMs = [Link].RATE_LIMIT_WINDOW || 15 * 60 * 1000;
const maxRequests = [Link].RATE_LIMIT_MAX || 100;
Interview Question 13
Q: How do you simulate heavy load in your tests to ensure your caching and rate
limiting strategies work?
Answer:
Interview Question 14
Q: How do you implement graceful degradation if the cache server becomes
unavailable?
Explanation: In your code, catch caching errors and fallback to fetching data
from the primary data source. Use try-catch or error-first callbacks.
Code Example:
javascript
Copy
[Link]('/data', (req, res, next) => {
const key = 'api:data';
[Link](key, (err, cachedData) => {
if (err) {
[Link]('Redis error:', err);
// Fallback: fetch from database or default value
return [Link](200).json({ message: 'Fallback data' });
}
if (cachedData) {
return [Link](200).json([Link](cachedData));
}
// Simulate database fetch
const data = { message: 'Fresh data from DB' };
[Link](key, 3600, [Link](data));
[Link](200).json(data);
});
});
Interview Question 15
Q: What are some best practices for using Redis in a production environment?
Answer:
Answer:
Interview Question 16
Q: How do you adjust rate limiting thresholds for different routes or users?
Answer:
Explanation: You can define multiple rate limiters with different settings and
apply them selectively using route-specific middleware.
Code Example:
javascript
Copy
const generalLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
});
[Link]('/api/', generalLimiter);
[Link]('/api/sensitive', sensitiveLimiter);
Summary of Section 8
In this section, you learned how to:
Optimize performance using techniques like lean queries and proper indexing.
Configure and fine-tune caching and rate limiting with environment variables.
Discuss best practices and error handling when the cache is unavailable.
The 15+ interview questions and code challenges provided are designed to
reinforce these concepts, ensuring you can implement and articulate strategies to
improve performance and reliability in your [Link] backend.
9. Real-Time Communication
Part 9.1: Concepts & Code Snippets
Key Concepts
Real-Time Communication:
Enables bi-directional, persistent communication between clients and the
server.
WebSockets:
A protocol that provides full-duplex communication channels over a single
TCP connection.
[Link]:
Handling Connections:
javascript
Copy
// [Link]
const express = require('express');
const http = require('http');
const socketIo = require('[Link]');
// Handle disconnection
[Link]('disconnect', () => {
[Link]('Client disconnected:', [Link]);
});
});
html
Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>[Link] Client</title>
<script src="/[Link]/[Link]"></script>
<script>
[Link]('DOMContentLoaded', () => {
const socket = io();
[Link]('connect', () => {
[Link]('Connected to server via [Link]');
});
javascript
Copy
// In [Link] (within the [Link]('connection') block)
[Link]('connection', (socket) => {
[Link]('New client connected:', [Link]);
[Link]('disconnect', () => {
[Link]('Client disconnected:', [Link]);
});
Interview Question 2
Q: How do you set up a basic [Link] server in [Link]?
A:
Interview Question 3
Q: How do you broadcast a message to all connected clients using [Link]?
A:
Code Example:
javascript
Copy
[Link]('message', (data) => {
[Link]('message', data); // Broadcasts to all clients
});
Interview Question 5
Q: How do you handle client disconnections in [Link]?
A:
Code Example:
javascript
Copy
[Link]('disconnect', () => {
[Link]('Client disconnected:', [Link]);
});
Interview Question 6
Q: How do you implement private messaging between clients using [Link]?
A:
Code Example:
javascript
Copy
// Send a private message to a specific client
[Link]('privateMessage', ({ recipientId, message }) => {
[Link](recipientId).emit('message', message);
Interview Question 7
Q: How do you integrate [Link] with an existing Express application?
A:
Interview Question 8
Q: How do you use namespaces in [Link], and why might you use them?
A:
Code Example:
javascript
Copy
const adminNamespace = [Link]('/admin');
[Link]('connection', (socket) => {
[Link]('Admin client connected:', [Link]);
});
Interview Question 9
Q: How do you test real-time events in your [Link] application?
A:
Code Example:
javascript
Copy
const ioClient = require('[Link]-client');
const socket = [Link]('[Link] { 'force new conn
ection': true });
[Link]('connect', () => {
[Link]('Test client connected');
[Link]('message', 'Test Message');
});
Interview Question 10
Q: How do you implement a heartbeat mechanism to detect inactive clients?
A:
Interview Question 11
Q: How do you handle errors in real-time communication using [Link]?
A:
javascript
Copy
[Link]('error', (error) => {
[Link]('Socket encountered error:', error);
});
Interview Question 12
Q: How do you implement reconnection logic with [Link] on the client side?
A:
Code Example:
javascript
Copy
const socket = io({
reconnectionAttempts: 5,
reconnectionDelay: 1000
});
Interview Question 13
Q: How do you secure [Link] connections with authentication?
A:
Code Example:
Interview Question 14
Q: How do you implement a notification system using [Link]?
A:
Code Example:
javascript
Copy
// When a new notification is generated:
[Link]('notification', { title: 'New Notification', message: 'You have a new
message' });
Interview Question 15
Q: How do you integrate [Link] with a front-end framework for real-time
updates?
A:
No additional code snippet is required; refer to the client code example above.
Summary of Section 9
In this section, you learned how to implement real-time communication in your
[Link] backend using [Link]. You covered:
Docker:
Containerization allows you to package your application and its dependencies
into a single image that runs consistently in any environment.
dockerfile
Copy
# Use an official [Link] runtime as a base image
FROM node:16-alpine
# Install dependencies
RUN npm install
yaml
Copy
# [Link]
version: '3.8'
services:
app:
build: .
ports:
CI/CD:
Continuous Integration and Continuous Deployment automate testing, building,
and deploying your application on code changes.
yaml
Copy
# .github/workflows/[Link]
name: [Link] CI/CD
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
steps:
groovy
Copy
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build') {
steps {
sh 'npm run build'
Winston:
A popular logging library for [Link], allowing configurable log levels and
transports (e.g., console, file).
PM2:
A process manager that helps you run, monitor, and manage [Link]
applications in production.
javascript
Copy
// utils/[Link]
const { createLogger, format, transports } = require('winston');
[Link] = logger;
javascript
Copy
// [Link]
[Link] = {
apps: [{
name: 'node-app',
script: '[Link]',
instances: 2,
autorestart: true,
watch: false,
max_memory_restart: '500M',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
bash
Copy
pm2 start [Link] --env production
Interview Question 1
Q: What is Docker and why is containerization important for [Link] applications?
Answer:
Explanation: Docker allows you to package your application along with its
dependencies into a container, ensuring consistent behavior across
environments and simplifying deployment.
Interview Question 2
Q: How do you create a Dockerfile for a [Link] application?
Answer:
Code Example:
(Refer to the Dockerfile snippet above.)
Interview Question 3
Code Example:
(Refer to the [Link] snippet above.)
Interview Question 4
Q: How do you set up a CI/CD pipeline for a [Link] application using GitHub
Actions?
Answer:
Code Example:
(Refer to the GitHub Actions workflow snippet above.)
Interview Question 5
Q: How can you use Jenkins to automate testing and deployment of your [Link]
app?
Answer:
Code Example:
(Refer to the Jenkinsfile snippet above.)
Interview Question 6
Q: What is PM2 and how does it help manage [Link] applications in production?
Answer:
Code Example:
(Refer to the [Link] snippet above.)
Code Example:
(Refer to the Winston logger snippet above.)
Interview Question 8
Q: How do you ensure environment-specific configuration for your [Link]
application during deployment?
Answer:
Code Example:
javascript
Copy
// Accessing environment variable in [Link]
const port = [Link] || 3000;
Interview Question 9
Q: How do you monitor the performance and health of a [Link] application in
production?
Answer:
Interview Question 10
Interview Question 11
Q: How do you manage secrets and sensitive configuration data in a [Link]
deployment?
Answer:
Code Example:
javascript
Copy
// Using dotenv package
require('dotenv').config();
const secretKey = [Link].SECRET_KEY;
Interview Question 12
Q: How can you automate testing for your [Link] application in your CI/CD
pipeline?
Answer:
Explanation: Configure your CI/CD tool to run unit tests, integration tests, and
code coverage reports on every push or pull request.
Answer:
Explanation: Use structured logging with appropriate log levels (error, warn,
info, debug), implement log rotation, and avoid logging sensitive information.
Interview Question 14
Q: How do you use Docker and CI/CD to ensure consistent deployments across
environments?
Answer:
Interview Question 15
Q: How do you set up health checks for your [Link] application in a
containerized environment?
Answer:
Code Example:
javascript
Copy
// In [Link]
[Link]('/health', (req, res) => {
[Link](200).json({ status: 'UP' });
Summary of Section 10
In this section, you learned how to deploy and manage your [Link] backend
using modern DevOps practices:
CI/CD Pipelines: Automating build, test, and deployment using GitHub Actions
or Jenkins.
Logging & Monitoring: Implementing robust logging with Winston and process
management with PM2.
The 15+ interview questions and code challenges provided reinforce these
concepts, preparing you to discuss and implement these strategies in real-world
production environments.
Implement an API to set, get, and delete key-value pairs stored in memory.
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
const store = {};
[Link] = router;
javascript
Copy
// [Link]
class LRUCache {
constructor(capacity) {
[Link] = capacity;
[Link] = new Map();
}
get(key) {
if () return -1;
const value = [Link](key);
[Link](key);
[Link](key, value);
return value;
}
put(key, value) {
if ([Link](key)) {
[Link](key);
} else if ([Link] >= [Link]) {
const firstKey = [Link]().next().value;
[Link](firstKey);
}
[Link](key, value);
}
}
javascript
Copy
// routes/[Link]
const express = require('express');
const crypto = require('crypto');
const router = [Link]();
const baseUrl = '[Link]
const urlMap = {};
function generateKey(url) {
return [Link]('md5').update(url).digest('hex').substring(0, 6);
}
[Link] = router;
Solution:
javascript
Copy
// routes/[Link]
const express = require('express');
const multer = require('multer');
const router = [Link]();
const storage = [Link]();
const upload = multer({ storage });
[Link] = router;
Solution:
javascript
Copy
// [Link]
class TaskScheduler {
constructor() {
[Link] = new Map();
}
cancelTask(id) {
if ([Link](id)) {
clearTimeout([Link](id));
[Link](id);
}
}
}
Solution:
javascript
Copy
// utils/[Link]
const { createLogger, format, transports } = require('winston');
[Link] = logger;
Solution:
javascript
Copy
// [Link]
const Queue = require('bull');
const jobQueue = new Queue('jobQueue');
function addJob(jobData) {
[Link](jobData);
}
[Link] = jobQueue;
javascript
Copy
[Link] = router;
Solution:
javascript
Copy
// [Link]
const WebSocket = require('ws');
const wss = new [Link]({ port: 8081 });
Solution:
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
[Link] = router;
Build a custom Express middleware that limits the number of requests per IP.
Solution:
javascript
Copy
// middleware/[Link]
const rateLimit = {};
if (!rateLimit[ip]) {
rateLimit[ip] = [];
}
rateLimit[ip] = rateLimit[ip].filter(ts => currentTime - ts < windowTime);
if (rateLimit[ip].length >= maxRequests) {
return [Link](429).json({ error: 'Too many requests, please try again lat
er.' });
}
rateLimit[ip].push(currentTime);
next();
}
javascript
Copy
// routes/[Link]
const express = require('express');
const router = [Link]();
const User = require('../models/User');
// Create User
[Link]('/', async (req, res, next) => {
try {
const newUser = new User([Link]);
const savedUser = await [Link]();
[Link](201).json(savedUser);
} catch (error) {
next(error);
}
});
// Read Users
[Link]('/', async (req, res, next) => {
try {
const users = await [Link]().lean();
[Link](200).json(users);
} catch (error) {
// Update User
[Link]('/:id', async (req, res, next) => {
try {
const updatedUser = await [Link]([Link], [Link]
y, { new: true, runValidators: true });
if (!updatedUser) return [Link](404).json({ error: 'User not found' });
[Link](200).json(updatedUser);
} catch (error) {
next(error);
}
});
// Delete User
[Link]('/:id', async (req, res, next) => {
try {
const deletedUser = await [Link]([Link]);
if (!deletedUser) return [Link](404).json({ error: 'User not found' });
[Link](200).json(deletedUser);
} catch (error) {
next(error);
}
});
[Link] = router;
Develop a simple chat server that allows multiple clients to send and receive
messages in real time.
javascript
Copy
// [Link]
const express = require('express');
const http = require('http');
const socketIo = require('[Link]');
const app = express();
const server = [Link](app);
const io = socketIo(server);
javascript
Copy
// [Link]
// Example usage:
(async () => {
const lock = new SimpleLock();
await [Link]();
[Link]('Lock acquired');
[Link]();
[Link]('Lock released');
})();
javascript
Copy
function mergeSortedArrays(arr1, arr2) {
Solution:
javascript
Copy
const fs = require('fs');
const zlib = require('zlib');
compressFile('[Link]', '[Link]');
javascript
Copy
class TrieNode {
constructor() {
[Link] = {};
[Link] = false;
}
}
class Trie {
constructor() {
[Link] = new TrieNode();
}
insert(word) {
let node = [Link];
for (let char of word) {
if (![Link][char]) {
[Link][char] = new TrieNode();
}
node = [Link][char];
}
[Link] = true;
}
search(prefix) {
let node = [Link];
for (let char of prefix) {
if (![Link][char]) return [];
_findAllWords(node, prefix) {
let results = [];
if ([Link]) [Link](prefix);
for (let char in [Link]) {
results = [Link](this._findAllWords([Link][char], prefix + ch
ar));
}
return results;
}
}
Implement a basic web crawler that fetches URLs from a starting point
(simulation).
Solution:
javascript
Copy
const axios = require('axios');
crawl('[Link] 2);
Solution:
javascript
Copy
class InMemoryCache {
constructor() {
[Link] = new Map();
}
get(key) {
return [Link](key);
}
}
javascript
Copy
class MessageBroker {
constructor() {
[Link] = {};
}
subscribe(topic, listener) {
if (![Link][topic]) [Link][topic] = [];
[Link][topic].push(listener);
}
publish(topic, message) {
Solution:
javascript
Copy
async function processTasks(tasks) {
const promises = [Link](task => new Promise(resolve => {
setTimeout(() => resolve(`Processed ${task}`), 1000);
}));
return await [Link](promises);
}
javascript
Copy
// middleware/[Link]
const throttleMap = new Map();
[Link](now);
next();
}
[Link] = throttle;
javascript
Copy
// [Link]
const { Worker } = require('worker_threads');
function runWorker(workerData) {
return new Promise((resolve, reject) => {
const worker = new Worker('./[Link]', { workerData });
[Link]('message', resolve);
[Link]('error', reject);
});
}
// Usage:
runWorker('task data').then(result => [Link](result));
Solution:
javascript
Copy
class TTLCache {
constructor() {
[Link] = new Map();
get(key) {
return [Link](key);
}
}
Solution:
javascript
Copy
const fs = require('fs');
const path = require('path');
Set up a job queue to send emails asynchronously using nodemailer and Bull.
Solution:
javascript
Copy
// [Link]
const Queue = require('bull');
const nodemailer = require('nodemailer');
const emailQueue = new Queue('emailQueue');
Summary
These 26 machine coding challenges cover a wide range of backend
functionalities in [Link]—from in-memory storage and caching to real-time
communication, job queues, and distributed processing. Each challenge includes
a sample solution that you can build upon, optimize, and adapt to your projects.
Practicing these challenges will strengthen your problem-solving skills and
prepare you for technical interviews.