Skip to content

MERN Stack Interview Questions in Chennai

36 practice questions with answers for MERN Stack interviews in Chennai.

MERN Stack jobs in Chennai

Chennai is a long-standing IT-services and SaaS hub along OMR, with strong demand for testing, data and support-engineering roles. Many companies here hire freshers in large batches and train them on the job.

Below are 36 questions that match the mix of service, product and domain employers hiring mern stack developers in Chennai.

Solved for ChennaiStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What are streams in Node.js and what types exist?

Save to ▾
Show answer
Streams process data in chunks instead of loading it all into memory. The four types are Readable (file read, HTTP request), Writable (file write, HTTP response), Duplex (TCP socket) and Transform (gzip, encryption), which modifies data as it passes. Streams handle backpressure, pausing the source when the destination is slow. pipeline() from node:stream/promises connects them safely and handles errors and cleanup.
02

Your Node.js API runs on an 8-core server but CPU monitoring shows only one core busy. What do you do?

Save to ▾
Show answer
A Node process runs JavaScript on a single thread, so one instance uses about one core. Run multiple instances: PM2 in cluster mode with -i max, the cluster module, or several containers behind a load balancer such as Nginx. Because instances do not share memory, move sessions, caches and rate-limit counters to Redis, and make sure the app is stateless so any instance can serve any request.
03

How do class component lifecycle methods map to hooks?

Save to ▾
Show answer
componentDidMount maps to useEffect with an empty dependency array. componentDidUpdate maps to useEffect with specific dependencies. componentWillUnmount maps to the cleanup function returned from useEffect. shouldComponentUpdate is roughly React.memo, and getDerivedStateFromProps is usually replaced by computing values during render. The mindset shifts from lifecycle moments to synchronising with external systems whenever certain values change.
04

What is the difference between controlled and uncontrolled components?

Save to ▾
Show answer
In a controlled component, form input values live in React state and change through onChange, so React is the single source of truth, which makes validation and conditional UI easy. In an uncontrolled component, the DOM holds the value and you read it with a ref or FormData when needed. Uncontrolled inputs mean fewer re-renders and suit simple forms and file inputs; libraries like React Hook Form use this approach.
05

Write a register endpoint that hashes the password with bcrypt.

Save to ▾
Show answer
Validate, check duplicates and hash before saving. import bcrypt from 'bcrypt'; router.post('/register', async (req, res) => { const { name, email, password } = req.body; if (!email || !password || password.length < 8) { return res.status(400).json({ message: 'Invalid input' }); } const exists = await User.findOne({ email: email.toLowerCase() }); if (exists) return res.status(409).json({ message: 'Email already registered' }); const hash = await bcrypt.hash(password, 12); const user = await User.create({ name, email, password: hash }); res.status(201).json({ id: user._id, name: user.name }); }); A unique index on email still guards against races.
06

Walk me through a MERN project you built, end to end.

Save to ▾
Show answer
Situation: I built a job portal as my major project. Task: let recruiters post jobs and students apply with resumes. Action: I designed MongoDB collections for users, jobs and applications with indexes, built an Express REST API with JWT auth and role checks, a React frontend with React Router and TanStack Query, uploaded resumes to cloud storage, wrote API tests and deployed with Docker. Result: 60 classmates used it during placement season.
07

Every time a user types in an input inside a list item, the input loses focus. What could be the cause?

Save to ▾
Show answer
The component is likely being remounted on each render. Common causes are generating keys randomly, such as key={Math.random()}, defining a component inside another component's body so it gets a new identity every render, or using index keys while the list reorders. Use stable ids as keys and move inner component definitions to the module level so React preserves their DOM and state.
08

When should you use useReducer instead of useState?

Save to ▾
Show answer
Use useReducer when state has multiple related fields, when the next state depends on complex logic, or when many event handlers update state in different ways. A reducer is a pure function (state, action) => newState that centralises transitions and is easy to unit test, for example a cart with add, remove, change quantity and clear actions. For simple independent values, useState is clearer.
09

What is the difference between server state and client state, and why use a library like TanStack Query?

Save to ▾
Show answer
Client state is UI data owned by the browser, like modal open or selected tab. Server state lives in the database, can be changed by others, and is only a cached copy in the browser. TanStack Query manages server state with caching, deduplication, background refetching, retries, pagination and mutations with cache invalidation. This removes much hand-written useEffect fetching and stops global stores from holding stale API data.
10

Write a docker-compose file to run a MERN app locally.

Save to ▾
Show answer
Three services on one network: services: mongo: image: mongo:8 volumes: - mongo-data:/data/db api: build: ./server environment: MONGO_URI: mongodb://mongo:27017/shop JWT_SECRET: dev-secret ports: - "5000:5000" depends_on: - mongo web: build: ./client ports: - "8080:80" depends_on: - api volumes: mongo-data: The API reaches the database through the service name mongo.
11

Tell me about a time you led a technical migration in a frontend codebase.

Save to ▾
Show answer
Situation: our React app still used Create React App and class components, and builds took several minutes. Task: as the senior developer I proposed moving to Vite and hooks. Action: I wrote a migration plan, moved the build tool first behind a feature branch, fixed environment variable names, then converted components gradually with tests. Result: dev server start went from 40 seconds to 2, builds became much faster, and the team adopted hooks patterns.
12

What does lean() do in Mongoose and when should you use it?

Save to ▾
Show answer
By default Mongoose queries return full documents with change tracking, getters, virtuals and methods like save. Calling .lean() returns plain JavaScript objects, which uses much less memory and is noticeably faster. Use it for read-only endpoints such as lists and API responses. Skip it when you need to modify and save the document, or depend on virtuals and getters unless you add a lean plugin.
13

Tell me about a time you had to deliver a frontend feature under a tight deadline.

Save to ▾
Show answer
Situation: a client demo was moved two days earlier and our filters page was half done. Task: deliver a working version in time. Action: I agreed a reduced scope with the lead, reused existing components, built the three most-used filters first and wrote quick tests for them, and kept the team updated each evening. Result: the demo went well and the remaining filters shipped in the next sprint.
14

How do you implement code splitting in a React app?

Save to ▾
Show answer
Use dynamic import with React.lazy, for example const Admin = lazy(() => import('./Admin')), and wrap it in a Suspense boundary with a fallback. Bundlers like Vite then create a separate chunk that loads only when needed. Split by route first, then by heavy components like charts, editors and maps. Preload likely next routes on hover, and check results with a bundle analyser such as rollup-plugin-visualizer.
15

How do you implement graceful shutdown for a Node.js API during deployments?

Save to ▾
Show answer
Listen for SIGTERM and SIGINT. When received, stop accepting new connections with server.close(), let in-flight requests finish, close database connections with mongoose.connection.close() and other resources, then exit with code 0. Set a timeout, for example 10 seconds, after which you force exit. In Kubernetes or behind a load balancer, also fail the readiness check first so traffic stops reaching the instance.
16

What is Express.js and what is middleware?

Save to ▾
Show answer
Express is a minimal web framework for Node.js that adds routing, middleware and helpers on top of the http module. Middleware is a function with the signature (req, res, next) that runs during the request cycle. It can read or modify the request, end the response, or call next() to pass control on. Body parsing, logging, authentication, CORS and error handling are all built as middleware.
17

A setInterval inside useEffect always logs the initial count value instead of the updated one. Why, and how do you fix it?

Save to ▾
Show answer
This is a stale closure: the effect ran once with an empty dependency array, so its callback captured count from the first render forever. Fixes include using the functional updater setCount((c) => c + 1) so you do not need to read count, adding count to the dependencies with proper cleanup, or storing the latest value in a ref that the interval reads.
18

Write Express middleware that logs method, URL, status code and response time.

Save to ▾
Show answer
Hook into the response finish event to know the final status. function requestLogger(req, res, next) { const start = process.hrtime.bigint(); res.on('finish', () => { const ms = Number(process.hrtime.bigint() - start) / 1e6; console.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${ms.toFixed(1)}ms`); }); next(); } app.use(requestLogger); In production, use a structured logger like pino instead of console.log.
19

What is CORS and how do you configure it in an Express API?

Save to ▾
Show answer
CORS is a browser security mechanism that blocks a page from reading responses from a different origin unless the server allows it through headers like Access-Control-Allow-Origin. For non-simple requests the browser sends a preflight OPTIONS request first. In Express, use the cors package with an explicit allowlist, for example cors({ origin: ['https://app.example.com'], credentials: true }), instead of allowing every origin with credentials.
20

Write a unit test for a function that calculates a cart total.

Save to ▾
Show answer
Vitest and Jest share the same syntax. // cart.js export const cartTotal = (items) => items.reduce((sum, i) => sum + i.price * i.qty, 0); // cart.test.js import { describe, it, expect } from 'vitest'; import { cartTotal } from './cart.js'; describe('cartTotal', () => { it('returns 0 for an empty cart', () => { expect(cartTotal([])).toBe(0); }); it('multiplies price by quantity', () => { expect(cartTotal([{ price: 100, qty: 2 }, { price: 50, qty: 1 }])).toBe(250); }); });
21

Write an asyncHandler wrapper for Express 4 route handlers.

Save to ▾
Show answer
It catches rejected Promises and forwards them to error middleware. const asyncHandler = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next); router.get('/:id', asyncHandler(async (req, res) => { const user = await User.findById(req.params.id); if (!user) return res.status(404).json({ message: 'Not found' }); res.json(user); })); Express 5 does this automatically, but many existing codebases still use this pattern.
22

How do you protect a public Express API from abuse and brute-force traffic?

Save to ▾
Show answer
Add rate limiting with express-rate-limit, using a Redis store when running multiple instances, and apply stricter limits to login and OTP routes. Set request body size limits, validate all input, require authentication on non-public routes, add helmet headers and timeouts. At the edge, a CDN or web application firewall can block bots and DDoS traffic before it reaches Node. Return 429 with a Retry-After header.
23

What is the difference between unit, integration and end-to-end tests in a MERN app?

Save to ▾
Show answer
Unit tests check a single function or component in isolation, such as a price calculator or a button, and are fast. Integration tests check pieces working together, such as an Express route with a real test database using Supertest. End-to-end tests drive the full app in a real browser with Playwright or Cypress, for example signup to checkout. Keep many unit tests, fewer integration tests and a small set of critical E2E flows.
24

A developer accidentally pushed the .env file with the MongoDB password and JWT secret to a public repository. What do you do?

Save to ▾
Show answer
Treat the secrets as compromised immediately. Rotate the MongoDB user password, the JWT secret and any API keys; rotating the JWT secret logs everyone out, which is acceptable. Check database and cloud logs for suspicious access. Remove the file, add .env to .gitignore, and purge it from history with a tool like git filter-repo, though rotation matters more. Enable secret scanning and pre-commit hooks to prevent repeats.
25

What are the important changes in Express 5 compared to Express 4?

Save to ▾
Show answer
Express 5 requires a modern Node version and forwards rejected Promises from async handlers to error middleware. Route path syntax moved to a newer path-to-regexp, so wildcards must be named, like /*splat, and regex-style characters in strings are no longer supported. Deprecated methods like res.send(status, body) were removed, req.query is read-only, and req.body is undefined unless a body parser runs.
26

What is the difference between a shallow copy and a deep copy?

Save to ▾
Show answer
A shallow copy duplicates only the top level, so nested objects are still shared references. Spread syntax and Object.assign make shallow copies. A deep copy duplicates every nested level. structuredClone(obj) is the built-in way in modern browsers and Node.js and supports Dates, Maps and Sets, while JSON.parse(JSON.stringify(obj)) loses functions, undefined and Dates. In React state updates, shallow copies of each changed level are usually enough.
27

Create a compound index for a user's order history query and verify it is used.

Save to ▾
Show answer
Query: orders of one user, newest first. db.orders.createIndex({ userId: 1, createdAt: -1 }) db.orders.find({ userId: ObjectId('...') }) .sort({ createdAt: -1 }) .limit(20) .explain('executionStats') Check that the winning plan shows IXSCAN, not COLLSCAN, and that totalDocsExamined is close to nReturned. In Mongoose, declare it with orderSchema.index({ userId: 1, createdAt: -1 }).
28

A MongoDB query on an orders collection takes 3 seconds. How do you diagnose and fix it?

Save to ▾
Show answer
Run the query with .explain('executionStats') and check whether the winning plan is COLLSCAN and how totalDocsExamined compares to nReturned. Create an index matching the filter and sort, following ESR, and confirm it becomes IXSCAN. Also project only needed fields, add limits, use lean in Mongoose, and check the profiler or Atlas Performance Advisor for other slow queries. Re-test with production-like data volume.
29

What does a CI/CD pipeline for a MERN application usually include?

Save to ▾
Show answer
On every pull request, continuous integration installs dependencies with npm ci, runs lint, type checks, unit and integration tests, and builds the frontend. On merge to main, continuous delivery builds Docker images or artifacts, tags them with the commit, pushes to a registry, deploys to staging, runs smoke tests and then promotes to production, often with manual approval. GitHub Actions, GitLab CI and Jenkins are common tools.
30

Duplicate user accounts with the same email are being created even though the code checks for an existing email first. Why, and how do you fix it?

Save to ▾
Show answer
Check-then-insert is a race condition: two concurrent requests both see no user and both insert. The real fix is a unique index on email, normalised to lowercase, so the database rejects the second insert with error code 11000. Catch that error and return 409 Conflict. Clean up existing duplicates before building the index, otherwise index creation fails.
31

Compress a large file with gzip using streams in Node.js.

Save to ▾
Show answer
pipeline connects streams and handles errors and cleanup. import { createReadStream, createWriteStream } from 'node:fs'; import { createGzip } from 'node:zlib'; import { pipeline } from 'node:stream/promises'; await pipeline( createReadStream('access.log'), createGzip(), createWriteStream('access.log.gz') ); Memory stays low regardless of file size, and backpressure is managed automatically.
32

Tell me about a time you found and fixed a security issue in an application.

Save to ▾
Show answer
Situation: while testing an order history feature, I noticed changing the order id in the URL showed another user's order. Task: fix this insecure direct object reference before release. Action: I added an ownership check in the service layer so queries always filter by the logged-in user's id, wrote tests for cross-user access, and reviewed similar endpoints. Result: we fixed four endpoints and added ownership checks to our review checklist.
33

What is the difference between process.nextTick, setImmediate and setTimeout(fn, 0)?

Save to ▾
Show answer
process.nextTick queues a callback to run right after the current operation, before Promise microtasks and before the event loop continues. setImmediate runs in the check phase after poll. setTimeout with 0 runs in the timers phase once at least about 1 ms has passed. Overusing nextTick recursively can starve I/O, so setImmediate is the safer way to defer heavy work.
34

How do you protect certain routes in React so that only logged-in users can access them?

Save to ▾
Show answer
Create a ProtectedRoute or layout component that reads auth state from context. If the user is not authenticated, return <Navigate to='/login' replace state={{ from: location }} />, otherwise render the Outlet or children. Show a loader while the session check is pending to avoid flicker. Remember that this is only for user experience; real protection must happen on the Express API by verifying tokens on every request.
35

Compare offset-based and cursor-based pagination for an API.

Save to ▾
Show answer
Offset pagination uses page and limit, translating to skip and limit in MongoDB. It is simple and allows jumping to page 10, but gets slower on large collections and can skip or repeat items when data changes. Cursor pagination returns items after a stable sorted value, such as the last _id or createdAt, using an indexed range query. It stays fast and consistent, ideal for infinite scroll feeds.
36

A component calls setState inside useEffect and the app goes into an infinite render loop. Why?

Save to ▾
Show answer
The effect updates state, which re-renders, which runs the effect again. This happens when the dependency array is missing, or when a dependency is a new object or array created every render, or when the effect sets the same state it depends on. Add correct dependencies, move object creation inside the effect or memoize it, and ask whether the value can be calculated during render instead.

Companies with offices in Chennai (9)

Frequently asked questions

Which companies hire MERN Stack professionals in Chennai?

Companies with large offices in Chennai include TCS, Infosys, Wipro, Cognizant, Capgemini, HCLTech, Tech Mahindra, LTIMindtree, EPAM Systems. Use their company pages below to practise employer-specific sets.

Are MERN Stack interviews in Chennai different from other cities?

The questions depend more on the company than the city. Chennai's mix of employers decides the style: Many companies here hire freshers in large batches and train them on the job

How do I find MERN Stack jobs in Chennai?

Shortlist companies with Chennai offices, keep your CV focused on MERN Stack projects, apply on company career pages and job portals with the Chennai filter, and practise the questions on this page before each interview.