MEAN Stack Interview Questions for 5 Years Experience
40 questions with answers for candidates with 5 years of experience — 29 medium, 11 hard.
What interviewers expect: 5 years experience
At five years, interviews focus on architecture and leadership. You may design a large Angular application structure with lazy features, plan migrations to standalone components, signals or zoneless mode, add SSR, and design scalable Node.js APIs with caching and MongoDB scaling. Behavioural rounds cover mentoring, estimation, handling client escalations and balancing quality with delivery deadlines.
This set is weighted towards Angular Forms and HTTP Client (7), Node.js and Express APIs (7), MongoDB Data Modelling and Queries (6), Security, Testing and Deployment (6).
Frontend architecture Framework migrations Scalable APIs Mentoring and estimation
Solved at this levelStart 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
Your app must call different API base URLs for development, staging and production. How do you configure this in Angular?
Use environment files such as environment.ts and environment.prod.ts with fileReplacements in angular.json build configurations, or load a config.json at startup with provideAppInitializer so one build works in every environment. Expose the URL through an InjectionToken and inject it in services or an interceptor. Never put secrets in these files, because everything in the Angular bundle is public.
02
What are generics in TypeScript? Give an Angular-related example.
Generics let you write reusable code that works with many types while keeping type safety, using type parameters like T. For example, an ApiResponse<T> interface can wrap any payload, and a service method get<T>(url: string): Observable<T> returns correctly typed data. Angular's HttpClient.get<User[]>() uses generics so the component knows it receives an array of users, without casting.
03
Write a custom attribute directive that highlights an element on hover.
First limit the impact: roll back to the previous version or disable the feature with a flag, and communicate status to support. Then reproduce the bug, fix it with a test that covers the case, and redeploy through the normal pipeline. Afterwards, run a blameless post-mortem to find gaps, such as missing tests, review or monitoring, and add the actions to the backlog.
06
Write a generic TypeScript function that groups an array of items by a key.
Situation: our team was hesitant to change working RxJS patterns. Task: I wanted to reduce subscription bugs and prepare for zoneless mode. Action: I built a proof of concept converting one complex component, measured fewer lines and change detection cycles, and proposed a gradual plan: signals for component state, RxJS kept for streams, toSignal at boundaries. Result: the team agreed to use signals in all new features.
08
Tell me about a time you improved test coverage or quality in a project.
Situation: our MEAN project had almost no tests and every release broke something. Task: I volunteered to improve this. Action: I set up Supertest with an in-memory MongoDB for critical APIs, added component tests for checkout, wrote a short testing guide and made tests required in CI. I started with the five most bug-prone areas. Result: production bugs per release dropped sharply within three months.
09
Use httpResource to load a product whenever the selected id signal changes.
Add a global error interceptor that maps network and 5xx errors to a friendly toast or banner, with retry for transient failures. In each data component, handle loading, error and empty states explicitly, using httpResource status signals or catchError with fallback values. Show a retry button, keep cached data visible if available, and log errors to monitoring. A health check banner helps during outages.
$lookup performs a left outer join with another collection in the same database. The basic form matches localField to foreignField and writes matching documents into an array field. The pipeline form lets you add conditions, filtering and projections on the joined collection using let variables. Often you follow it with $unwind to flatten the array. Index the foreign field so the join stays efficient.
12
What are HTTP interceptors and what are common use cases?
Interceptors sit between HttpClient and the server and can modify every request and response. Modern Angular uses functional interceptors of type HttpInterceptorFn registered through withInterceptors. Common uses are attaching an Authorization header, adding a base URL, showing a global loading indicator, logging, retrying failed requests, refreshing expired tokens and mapping errors to user-friendly messages. Interceptors run in the order they are listed.
13
Serve the built Angular app and the API from one Express server.
A monolith is one deployable API containing all modules, which is simpler to build, test and deploy, and is right for most early-stage products. Microservices split domains like orders, payments and notifications into separate services communicating over HTTP or message queues, allowing independent scaling and deployments, but adding network failures, distributed data and operational complexity. Many teams start with a modular monolith and split later.
15
Write a type-ahead search using a reactive FormControl and RxJS operators.
Build Angular with ng build, which outputs static files to dist/project/browser. In Express, register API routes under /api first, then serve the static files with express.static, and finally add a catch-all GET route that returns index.html so Angular routing works on refresh. In larger deployments, Nginx or a CDN usually serves the Angular files while Express handles only the API.
Angular server-side rendering renders pages to HTML on a Node.js server, so users and search engines see content immediately. The browser then hydrates the page, attaching Angular to the existing DOM; incremental hydration can hydrate parts only when needed using @defer triggers. Route-level render modes allow some pages to be prerendered at build time and others rendered per request. It improves SEO and first load for public pages.
18
Write an exhaustive switch over a union type using never.
The never check makes the compiler flag unhandled cases.
type Shape = { kind: 'circle'; r: number } | { kind: 'square'; side: number };
function area(s: Shape): number {
switch (s.kind) {
case 'circle':
return Math.PI * s.r ** 2;
case 'square':
return s.side ** 2;
default: {
const unreachable: never = s;
throw new Error(`Unknown shape ${unreachable}`);
}
}
}
Adding a triangle variant now causes a compile error until it is handled.
19
Write a BullMQ queue and worker to send emails in the background.
Situation: I built a loan application form with five steps and over sixty fields. Task: make it reliable and user friendly. Action: I used typed reactive forms split into step groups, cross-field validators for income rules, a FormArray for co-applicants, auto-saved drafts every thirty seconds and mapped server validation errors back to fields. Result: drop-offs reduced noticeably and QA found very few form bugs.
22
Write a multi-stage Dockerfile that builds Angular and serves it with Nginx.
Build in Node, ship only static files.
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx ng build --configuration production
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/shop/browser /usr/share/nginx/html
EXPOSE 80
The final image contains no Node.js or source code. nginx.conf should include try_files $uri /index.html for Angular routes.
23
Define a typed Mongoose model in TypeScript with an instance method.
Find the root cause from logs and fix missing await or catch blocks. Use Express 5, which forwards async errors to error middleware, or an async wrapper in Express 4. Add a central error handler, log unhandledRejection and uncaughtException and then exit cleanly. Run under PM2 or a container orchestrator with multiple instances and health checks so a crash restarts one instance while others keep serving.
25
Build a dynamic FormArray for adding and removing phone numbers.
Use a FormArray of FormGroups, each with product, quantity and price controls and validators like min(1). Provide addItem and removeItem methods that push or removeAt on the array, and render rows with @for over items.controls. Calculate the total from valueChanges or a computed signal. On submit, send getRawValue() typed as the order DTO, and disable the submit button while invalid or pending.
27
What are Mongoose virtuals, instance methods and statics?
Virtuals are computed properties not stored in MongoDB, such as fullName from firstName and lastName, or a virtual populate that links related documents. Instance methods are functions available on each document, like user.comparePassword(). Statics are functions on the model itself, like User.findByEmail(email). Virtuals are excluded from JSON output unless you enable toJSON: { virtuals: true } in schema options.
28
Describe how you handled a situation where requirements changed late in a sprint.
Situation: two days before release, the client asked to add role-based access to a reporting page. Task: deliver without breaking the release. Action: I clarified the minimum needed with the product owner, implemented a canMatch guard and hid admin actions, and coordinated with the backend developer for API checks, while moving extra filters to the next sprint. Result: we released on time and the client approved the change.
29
How do real-time features work in a MEAN application?
Use WebSockets, commonly through Socket.IO on the Express server and its client library in an Angular service that exposes events as Observables or signals. The server emits events, such as new chat messages or order status changes, to rooms of interested users. For scaling across instances, add a Redis adapter. Server-sent events are a simpler option for one-way updates like notifications or live dashboards.
30
Every API request needs a JWT header, and expired tokens should trigger a refresh without logging the user out. How do you implement this?
Write an auth interceptor that clones each request with the Authorization header from the auth service. In the response path, catch 401 errors, call the refresh endpoint once, store the new access token, and retry the original request. Use a shared refresh Observable with shareReplay or a flag so parallel failed requests wait for one refresh. If refresh fails, clear the session and redirect to login.
31
A penetration test report says your API returns other users' invoices when the invoice id is changed. How do you fix it?
This is broken object-level authorization, the top API risk in the OWASP list. Fix every query to scope by the authenticated user, for example Invoice.findOne({ _id: id, userId: req.user.id }), and return 404 when not found. Centralise ownership checks in services or middleware, add tests that try cross-user access, and review similar endpoints. Avoid relying on unguessable ids as protection.
32
Load three APIs in parallel with forkJoin and handle a failure in one of them.
An InjectionToken is a unique key for providing values that are not classes, such as configuration objects, API base URLs or feature flags. You create it with new InjectionToken<AppConfig>('APP_CONFIG'), provide it with { provide: APP_CONFIG, useValue: config }, and read it with inject(APP_CONFIG). Other provider types include useClass to swap implementations, useFactory for computed values and useExisting for aliases.
34
An npm audit shows several high-severity vulnerabilities in the Express project. How do you handle it?
Read each advisory to see whether the vulnerable code path is actually used in production or only in dev tooling. Run npm audit fix for safe updates, upgrade direct dependencies that pull vulnerable transitive packages, and use overrides in package.json if a fix is not yet released upstream. Test thoroughly after upgrading, enable Dependabot or Renovate for continuous updates and track any accepted risks.
35
What are change streams in MongoDB and how can a MEAN app use them?
Change streams let an application subscribe to real-time inserts, updates and deletes on a collection, database or deployment, using the oplog of a replica set. A Node.js service can watch the orders collection and push status changes to Angular clients over Socket.IO, or sync data to search indexes and caches. Streams are resumable using a resume token after a restart.
Since Angular 14, reactive forms are strongly typed. A FormControl<string> knows its value type, so form.value and getRawValue return typed objects and the compiler catches wrong field names. Controls are nullable by default because reset sets them to null; using nonNullable: true or NonNullableFormBuilder resets to the initial value instead. Typed forms make it safe to map form values directly to API request interfaces.
37
Frontend and backend models keep drifting apart, causing runtime bugs. How would you keep them in sync in a MEAN project?
Share types from a single source. In a monorepo, for example with Nx, put DTO interfaces in a shared library used by both the Express API and Angular. Alternatively generate an OpenAPI spec from the backend and generate Angular client types from it, or define schemas once with zod and infer types. Add contract tests in CI so a breaking change fails the build.
38
Write a functional auth guard that redirects unauthenticated users to the login page.
Check how many queries populate triggers and how much data each returns. Select only needed fields in populate, use lean(), and add indexes on the referenced fields. If the list always needs a customer name, store it with the extended reference pattern to avoid the join entirely. For complex filtering on related data, switch to one aggregation with $lookup and $project, and paginate.
40
What are @defer blocks and how do they help performance?
@defer lets you lazy load part of a template and its dependencies only when a trigger occurs, such as on viewport, on interaction, on hover, on idle, on timer or a custom condition with when. Angular automatically splits that code into a separate chunk. You can show @placeholder, @loading and @error blocks. It is ideal for heavy below-the-fold widgets like charts, comments and maps.
Frequently asked questions
What is asked in MEAN Stack interviews for 5 years of experience?
At five years, interviews focus on architecture and leadership. You may design a large Angular application structure with lazy features, plan migrations to standalone components, signals or zoneless mode, add SSR, and design scalable Node.js APIs with caching and MongoDB scaling. Behavioural rounds cover mentoring, estimation, handling client escalations and balancing quality with delivery deadlines.
How many questions should I practise before a MEAN Stack interview?
Work through all 40 questions here, then the company-wise sets for the employers you are targeting. Quality matters more than count: be able to explain why each answer is right.
Which topics matter most for 5 years of experience?
Focus first on Frontend architecture, Framework migrations, Scalable APIs, Mentoring and estimation.