36 practice questions with answers for MERN Stack interviews in Delhi.
MERN Stack jobs in Delhi
Delhi NCR has one of India's biggest pools of IT, consulting, banking and start-up jobs. Delhi itself hosts many corporate, government-tech and consulting offices, and most candidates also apply across Noida and Gurgaon, so interviews here mix service-company and product-company styles.
Below are 36 questions that match the mix of service, product and domain employers hiring mern stack developers in Delhi.
Solved for DelhiStart 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.
Debounce delays a call until a quiet period has passed. Each new call clears the previous timer.
function debounce(fn, delay = 300) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const onSearch = debounce((q) => fetchResults(q), 400);
It relies on a closure over timer and keeps this and arguments intact.
02
Write an asyncHandler wrapper for Express 4 route handlers.
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.
03
How do you implement code splitting in a React app?
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.
04
What is the aggregation pipeline and what are its common stages?
The aggregation pipeline processes documents through a sequence of stages, each transforming the stream. Common stages are $match to filter, $group to aggregate with operators like $sum and $avg, $project or $addFields to shape fields, $sort, $limit, $skip, $lookup to join another collection, $unwind to flatten arrays and $facet for multiple outputs. Put $match and $sort early so they can use indexes and reduce the data volume.
05
What are the common ways to render content conditionally in React?
Use an early return for whole-component cases like loading, an if statement outside JSX, the ternary operator for either-or markup, and logical && for show-or-hide. Be careful with && on numbers: count && <Badge /> renders 0 when count is zero, so use count > 0 && <Badge />. For many states, map a status value to components with an object lookup.
06
What are the core principles of a RESTful API, and which HTTP methods are idempotent?
REST models data as resources identified by URLs, uses standard HTTP methods, is stateless, and returns representations like JSON with proper status codes. Use nouns, for example GET /orders and POST /orders. GET, PUT, DELETE, HEAD and OPTIONS are idempotent: repeating them gives the same server state. POST is not idempotent, and PATCH usually is not, which matters when clients retry requests.
07
What are Mongoose middleware hooks and give a common use case.
Mongoose middleware are functions that run before or after operations such as save, validate, deleteOne, findOneAndUpdate and aggregate. A classic pre-save hook hashes a password only if it was modified: if (!this.isModified('password')) return; this.password = await bcrypt.hash(this.password, 12). Post hooks are used for logging or syncing. Note that query middleware like findOneAndUpdate does not trigger save hooks.
08
A search box fires an API request on every keystroke and overloads the backend. How would you solve it?
Debounce the input so the request goes out only after the user stops typing for around 300 ms. Also skip very short queries, cancel the previous request with AbortController so stale responses cannot overwrite newer ones, and cache recent results. On the server side, add rate limiting and an index on the searched field. Throttling is the alternative when you need periodic updates, like scroll tracking.
09
Write a reusable validation middleware for Express using zod.
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.
11
Fast typing in a search box sometimes shows results for an older query. What causes this and how do you fix it?
It is a race condition: responses arrive out of order, so a slow earlier request overwrites results of a newer one. In the effect, use an AbortController and abort the previous request in the cleanup, or keep an ignore flag set to true during cleanup and skip setState when it is set. Debouncing reduces requests, and TanStack Query handles this automatically by keying results to the query.
12
How should a component display data loaded from an API in a user-friendly way?
Handle every state explicitly: show a skeleton or spinner while loading, an error message with a retry button if the request fails, an empty state with guidance when there is no data, and the content otherwise. Keep these in state variables or use a library like TanStack Query that provides isPending, isError and data. Never leave a blank screen or crash on undefined data.
13
Typing in a filter box over a list of 10,000 rows feels laggy. How do you fix it?
First profile to confirm what re-renders. Then virtualise the list with a library like TanStack Virtual or react-window so only visible rows render. Memoise row components and keep the filtered list in useMemo. Use useDeferredValue or startTransition so the input stays responsive while the list update is treated as low priority. For very large data, filter on the server with pagination and an index.
14
Create a compound index for a user's order history query and verify it is used.
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 }).
15
What is a custom hook and what rules must hooks follow?
A custom hook is a function whose name starts with use and that calls other hooks to package reusable stateful logic, such as useFetch, useDebounce or useAuth. Each component using it gets its own state. Hooks must be called at the top level of a component or another hook, never inside conditions, loops or nested functions, so React can match state by call order. The eslint-plugin-react-hooks rules enforce this.
16
Tell me about a time you improved the performance of a slow database-driven feature.
Situation: our admin orders page took 8 seconds to load. Task: I was asked to fix it within a sprint. Action: I profiled the API, found a populate on every row plus an unindexed sort, added a compound index, replaced populate with a single $lookup projecting only needed fields, and used lean. Result: load time dropped below 600 ms and I shared an indexing checklist with the team.
A JSON Web Token is a compact, URL-safe token made of three Base64URL-encoded parts separated by dots: the header with algorithm and type, the payload with claims like sub, role and exp, and the signature created from the header and payload using a secret or private key. The signature proves the token was not altered, but the payload is readable by anyone, so never put passwords or sensitive data in it.
18
What is PM2 and why is it used to run Node.js in production?
PM2 is a process manager for Node.js. It keeps the app alive by restarting it after crashes, runs multiple instances in cluster mode to use all CPU cores, supports zero-downtime reloads with pm2 reload, manages logs and starts apps on server boot. Configuration lives in an ecosystem.config.js file. On container platforms like Kubernetes, the orchestrator often replaces PM2's restart and scaling role.
19
Write a register endpoint that hashes the password with bcrypt.
Functional components with hooks need less code, avoid confusion around this binding, and let you reuse stateful logic through custom hooks instead of higher-order components or render props. All new React features, such as Server Components and hooks like useActionState, target functions. Class components still work and appear in older codebases, and error boundaries still require a class or a library wrapper.
21
Why do applications use both access tokens and refresh tokens?
The access token is short-lived, for example 15 minutes, and is sent with every API request, so if stolen it is useful only briefly. The refresh token is long-lived, stored more securely in an httpOnly cookie, and is used only at a refresh endpoint to get new access tokens. Refresh tokens should be stored server-side or hashed so they can be revoked, and rotated on every use to detect theft.
22
Two sibling components need to share data. How do you handle it?
Lift the shared state to their nearest common parent and pass the value to one sibling and an updater to the other. If the data is needed by many components deep in the tree, use Context or a state library like Zustand or Redux Toolkit. If the data comes from the server, a data-fetching library like TanStack Query can share the cached result across components.
Authentication verifies who the user is, for example by checking email and password, an OTP or a Google login, and results in a session or token. Authorization decides what that authenticated user may do, such as whether a normal user can delete products or only an admin can. Failed authentication should return 401 Unauthorized, while an authenticated user lacking permission should get 403 Forbidden.
25
How should errors be handled in a Node.js application?
Separate operational errors, like a failed DB connection or invalid input, which you handle and respond to, from programmer errors, like undefined property access, which signal bugs. Use try/catch with async/await, always handle Promise rejections and stream error events. Listen to uncaughtException and unhandledRejection only to log and exit cleanly, then let a process manager restart the app, because state may be corrupted.
26
Design a secure forgot-password flow for a MERN application.
The user submits an email; always respond with the same message whether or not it exists. Generate a random token with crypto.randomBytes, store only its hash with an expiry of around 15 minutes, and email a link with the raw token. On submission, hash the token, find a matching unexpired record, set the new hashed password, delete the token and invalidate existing sessions. Rate limit the endpoint.
27
What practical steps do you take to sanitise and validate input in an Express and MongoDB API?
Validate every request body, params and query against a schema with zod or Joi, rejecting unknown fields and wrong types. Apply body size limits with express.json({ limit: '100kb' }). Strip MongoDB operator keys from input with a small sanitising middleware or library, and keep Mongoose strict mode on. Escape or sanitise HTML with DOMPurify before storing rich text, and validate ObjectIds before querying.
A fragment, written <>...</> or <Fragment key={id}>, groups children without adding an extra DOM element, which keeps tables and flex layouts valid. A portal, created with createPortal(child, domNode), renders children into a different DOM node such as document.body while keeping them in the same React tree, so context and event bubbling still work. Portals are used for modals, tooltips and toasts that must escape overflow hidden containers.
29
Your Node.js API runs on an 8-core server but CPU monitoring shows only one core busy. What do you do?
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.
30
How would you structure the folders of a production Express API?
A layered structure keeps responsibilities clear: src/routes for route definitions, src/controllers for request and response handling, src/services for business logic, src/models for Mongoose schemas, src/middlewares for auth, validation and errors, src/config for environment and database setup, src/utils for helpers, and tests alongside or in a tests folder. Keep app.js, which builds the app, separate from server.js, which listens, so tests can import the app.
31
What is libuv and which operations use the Node.js thread pool?
libuv is the C library that provides Node's event loop and asynchronous I/O. Network I/O uses non-blocking OS mechanisms like epoll or IOCP, so it does not use the pool. The thread pool, four threads by default, handles file system calls, DNS lookup, zlib compression and crypto functions like pbkdf2 and scrypt. Heavy bcrypt or crypto load can saturate it; UV_THREADPOOL_SIZE can increase it.
32
A component calls setState inside useEffect and the app goes into an infinite render loop. Why?
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.
33
How do you debug a JavaScript bug that a user reports but you cannot reproduce locally?
Situation: a user reported a checkout button doing nothing, but it worked for me. Task: find the cause quickly. Action: I asked for browser, device and steps, checked our error-tracking logs, and found a TypeError only on an older Safari version due to an unsupported method. I reproduced it on a cloud device, added a polyfill and a test. Result: the fix shipped the same day and I added browser targets to our build.
34
Write Express middleware that logs method, URL, status code and response time.
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.
35
Your API has 40 routes and each returns errors in a different format. How would you standardise this?
Create a custom AppError class with statusCode and code fields, throw it from services and controllers, and handle every error in one central error middleware that returns a consistent shape such as { success: false, error: { code, message, details } }. Map validation, Mongoose cast and duplicate key errors to proper status codes there. Document the format in OpenAPI so the React team handles errors uniformly.
36
Tell me about a deployment that went wrong and what you learned.
Situation: a release broke login for all users because a new environment variable was missing in production. Task: restore service fast. Action: I rolled back to the previous version within ten minutes, added the variable, and redeployed after testing on staging. Afterwards I added startup config validation and a post-deploy smoke test for login in our pipeline. Result: no config-related outage has happened since.
Frequently asked questions
Which companies hire MERN Stack professionals in Delhi?
Companies with large offices in Delhi include many IT services and product firms. Use their company pages below to practise employer-specific sets.
Are MERN Stack interviews in Delhi different from other cities?
The questions depend more on the company than the city. Delhi's mix of employers decides the style: Delhi itself hosts many corporate, government-tech and consulting offices, and most candidates also apply across Noida and Gurgaon, so interviews here mix service-company and product-company styles
How do I find MERN Stack jobs in Delhi?
Shortlist companies with Delhi offices, keep your CV focused on MERN Stack projects, apply on company career pages and job portals with the Delhi filter, and practise the questions on this page before each interview.