MEAN Stack Developer Certification — Questions and Answers
Question 1: How do you set the HTTP status code of a response in Express.js?
- res.setStatus(404)
- response.status = 404
- res.code(404)
- res.status(404).send('Not Found') (Correct answer)
Correct answer: res.status(404).send('Not Found')
res.status() sets the HTTP status code and returns the response object for chaining with send(), json(), or end().
Question 2: What MongoDB aggregation stage is used to filter documents, similar to a WHERE clause in SQL?
- $filter
- $project
- $match (Correct answer)
- $group
Correct answer: $match
$match filters documents to pass only those that meet the specified conditions to the next stage.
Question 3: How do you access query string parameters in Express.js (e.g., /search?q=mean)?
- req.params.q
- req.query.q (Correct answer)
- req.body.q
- req.search.q
Correct answer: req.query.q
Express automatically parses query string parameters from the URL and makes them available as properties of the req.query object.
Question 4: You want two sibling router-outlets — a primary outlet and a named outlet called `sidebar` — to be active simultaneously. Which route configuration correctly keeps `SidebarComponent` in the `sidebar` outlet while navigating the primary outlet?
- { path: '**', component: SidebarComponent, outlet: 'sidebar' } as a catch-all for the sidebar outlet
- { path: 'dashboard', component: DashboardComponent, outlet: 'primary' } and { path: 'sidebar', component: SidebarComponent, outlet: 'sidebar' }, navigated via routerLink with an outlets object (Correct answer)
- Named outlets are mutually exclusive with the primary outlet — only one outlet can be active per navigation event
- { path: 'dashboard', component: DashboardComponent, children: [{ path: 'sidebar', component: SidebarComponent }] } with a nested router-outlet inside DashboardComponent
Correct answer: { path: 'dashboard', component: DashboardComponent, outlet: 'primary' } and { path: 'sidebar', component: SidebarComponent, outlet: 'sidebar' }, navigated via routerLink with an outlets object
Named outlets are navigated independently using the outlets object in the router link: `[routerLink]="[{ outlets: { primary: ['dashboard'], sidebar: ['sidebar'] } }]"`. Each outlet maps to its own route configuration where `outlet: 'sidebar'` is specified. Both outlets remain active simultaneously and each can be updated independently. The named outlet route is a sibling in the route config, not a child.
Question 5: You're configuring Content Security Policy (CSP) headers for a MEAN stack app that uses Angular on the frontend. Angular's template compilation in JIT mode requires `'unsafe-eval'` in the CSP `script-src` directive. Which deployment change ELIMINATES the need for `'unsafe-eval'` without breaking Angular's functionality?
- Add a nonce to all inline scripts and include the nonce in the CSP header, which overrides the need for `'unsafe-eval'`
- Host Angular as a Chrome Extension where CSP restrictions on `eval()` do not apply to the extension's content scripts
- Switch from JIT (Just-in-Time) to AOT (Ahead-of-Time) compilation in the Angular build, which pre-compiles templates and removes the runtime `eval()` requirement (Correct answer)
- Use `'strict-dynamic'` in the CSP header, which implicitly permits trusted scripts to call `eval()` without requiring `'unsafe-eval'`
Correct answer: Switch from JIT (Just-in-Time) to AOT (Ahead-of-Time) compilation in the Angular build, which pre-compiles templates and removes the runtime `eval()` requirement
Angular JIT mode compiles templates in the browser at runtime using `eval()`-like mechanisms, requiring `'unsafe-eval'` in CSP. AOT compilation moves all template compilation to build time — the browser receives pre-compiled JavaScript with no need for runtime eval. This is the standard production build mode (`ng build --configuration production`) and is the correct architectural fix. Nonces authorize specific scripts but don't remove the eval requirement. `'strict-dynamic'` propagates trust to dynamically added scripts but does not grant eval permission. The Chrome Extension scenario is irrelevant to MEAN stack web deployment.
Question 6: What is NoSQL injection and how can it occur in a MongoDB/Express application?
- Flooding MongoDB with concurrent write operations
- Sending malicious operators like $where or $gt in request bodies to manipulate MongoDB queries (Correct answer)
- Overwriting MongoDB documents with XSS payloads
- Injecting SQL commands into MongoDB's aggregation pipeline
Correct answer: Sending malicious operators like $where or $gt in request bodies to manipulate MongoDB queries
NoSQL injection occurs when unvalidated user input is passed directly to MongoDB queries, allowing attackers to inject operators like $where or $regex to bypass authentication.
Question 7: An Angular SPA communicates with an Express REST API. The API uses JWT access tokens (15-min expiry) and refresh tokens (7-day expiry) stored in HttpOnly cookies. An attacker exploits a CSRF vulnerability to silently refresh the access token. Which defense specifically addresses refresh-token CSRF without breaking the HttpOnly cookie approach?
- Adding a CSRF token in the Authorization header for refresh requests
- Setting SameSite=Strict on the refresh token cookie (Correct answer)
- Storing the refresh token in localStorage instead of a cookie
- Reducing the refresh token expiry to 1 hour
Correct answer: Setting SameSite=Strict on the refresh token cookie
Setting `SameSite=Strict` on the refresh token cookie prevents it from being sent on any cross-site request, including CSRF-triggered refresh calls, because the browser will not attach the cookie when the request originates from a different site. Storing refresh tokens in localStorage eliminates the HttpOnly protection and exposes them to XSS. Adding a CSRF token in the Authorization header is valid but more complex to implement correctly. Reducing expiry limits damage but doesn't prevent the attack.
Question 8: You have two routers mounted on the same path: js app.use('/data', routerA); app.use('/data', routerB); `routerA` has a handler for `GET /item` that calls `next()` without sending a response. `routerB` has a handler for `GET /item` that sends a 200. A `GET /data/item` request arrives. What is the final HTTP response status?
- 500 — mounting two routers on the same path causes an internal conflict
- 200 — but only `routerA`'s handler runs; `routerB` is shadowed by the first mount
- 200 — after `routerA`'s handler calls `next()`, Express continues to `routerB`'s matching handler (Correct answer)
- 404 — once `routerA` is mounted on `/data` and its handler calls `next()`, Express exits the `/data` mount entirely
Correct answer: 200 — after `routerA`'s handler calls `next()`, Express continues to `routerB`'s matching handler
Express processes middleware and routers in the order they are registered. When `routerA`'s handler calls `next()` without sending a response, Express continues down the middleware stack and reaches `routerB`, which also matches `/data`. `routerB`'s `GET /item` handler then runs and sends the 200 response. Multiple routers mounted on the same path form a chain, not a conflict — the first one to send a response wins.
Question 9: You define a component with `ViewEncapsulation.ShadowDom`. A global stylesheet in `styles.scss` sets `button { color: red; }`. What will happen to a `<button>` rendered inside this component?
- The button inherits the red color because Shadow DOM does not block inherited CSS properties (Correct answer)
- The button inherits red color only if the global rule uses `!important`
- The button is completely unaffected because ShadowDom encapsulation creates a true shadow root that blocks all external styles including inherited ones
- Angular emulates Shadow DOM and still applies the global style with an attribute selector override
Correct answer: The button inherits the red color because Shadow DOM does not block inherited CSS properties
CSS custom properties and *inheritable* CSS properties (like `color`, `font-family`, `line-height`) pierce the Shadow DOM boundary by design. The `color: red` rule on `button` sets an inheritable property, so child elements inside the shadow root inherit it. Non-inherited properties (like `border`, `background`) would be blocked. This is a nuanced distinction — `ShadowDom` blocks non-inherited styles but not the cascade of inheritable properties.
Question 10: What is Angular Universal and when would you use it in a MEAN stack?
- A universal testing framework for all Angular versions
- Server-Side Rendering for Angular apps, used to improve SEO and initial load performance (Correct answer)
- A shared component library for Angular apps
- A deployment tool for Angular apps to multiple cloud providers
Correct answer: Server-Side Rendering for Angular apps, used to improve SEO and initial load performance
Angular Universal enables server-side rendering of Angular apps using Node.js, delivering fully rendered HTML to the browser for better SEO and faster perceived load times.
Question 11: Which of the following correctly describes the behavior of Express route parameter middleware defined with `router.param('id', callback)`?
- The callback fires after every route handler that uses `:id` completes, allowing post-processing
- The callback fires once per request for each route that contains the `:id` parameter, before that route's handler executes (Correct answer)
- The callback fires only on the first request that matches `:id` and is cached for subsequent requests
- The callback replaces the route handler entirely; returning from it sends the response
Correct answer: The callback fires once per request for each route that contains the `:id` parameter, before that route's handler executes
`router.param()` registers a callback that is triggered automatically whenever a route on that router contains the named parameter. It fires before the route handler, allowing you to load a resource, validate, or transform `req.params.id`. It runs once per request (not once per parameter occurrence across multiple routes), and you must call `next()` to proceed.
Question 12: In MongoDB, what is a capped collection?
- A collection with a maximum document size limit
- A collection limited to 100 documents
- A collection with read-only access
- A fixed-size collection that overwrites oldest documents when full (Correct answer)
Correct answer: A fixed-size collection that overwrites oldest documents when full
Capped collections have a fixed size and automatically overwrite the oldest entries in insertion order when the size limit is reached.
Question 13: Which Angular feature allows you to conditionally apply CSS classes to an element based on component state?
- [ngClass] directive (Correct answer)
- {{class}} interpolation
- @HostListener decorator
- [style] binding only
Correct answer: [ngClass] directive
[ngClass] accepts an object, array, or string and dynamically adds or removes CSS classes based on truthy/falsy expressions.
Question 14: What is the purpose of environment variables in a Node.js MEAN application?
- Pass data between Node.js processes and threads
- Configure the Node.js runtime version and memory limits
- Define available npm scripts for the project
- Store configuration and secrets outside the codebase, accessed via process.env (Correct answer)
Correct answer: Store configuration and secrets outside the codebase, accessed via process.env
Environment variables keep sensitive data like database URLs, API keys, and JWT secrets out of source code, with different values per environment (dev/staging/prod).
Question 15: In Express.js, what is the difference between `app.get()` and `app.use()` for the same path?
- Both are identical in behavior
- app.use() requires an exact path match; app.get() matches sub-paths
- app.get() matches all methods; app.use() only matches GET
- app.get() only matches exact GET requests; app.use() matches all methods and also sub-paths (Correct answer)
Correct answer: app.get() only matches exact GET requests; app.use() matches all methods and also sub-paths
app.get() strictly matches GET requests at the exact path, while app.use() matches any HTTP method and any path that starts with the given prefix.
Question 16: What does the MongoDB $project aggregation stage do?
- Creates new collections from query results
- Filters documents by field existence
- Projects indexes onto query results
- Shapes output documents by including, excluding, or renaming fields (Correct answer)
Correct answer: Shapes output documents by including, excluding, or renaming fields
$project allows you to specify which fields to include (1) or exclude (0), add computed fields, and reshape documents in the aggregation pipeline.
Question 17: Consider the following async function: async function fetchAll(ids) { const results = []; for (const id of ids) { results.push(await fetch(id)); } return results; } For an array of 100 IDs, what is the primary performance problem with this implementation compared to Promise.all()?
- Requests are serialized — each fetch waits for the previous one to complete, giving a total time of sum(all latencies) instead of max(all latencies) (Correct answer)
- async/await cannot be used inside for...of loops without causing unhandled promise rejections
- fetch() inside async functions always runs synchronously, blocking the event loop
- The results array will contain rejected promises instead of resolved values when any fetch fails
Correct answer: Requests are serialized — each fetch waits for the previous one to complete, giving a total time of sum(all latencies) instead of max(all latencies)
The await inside the for...of loop makes each fetch execute sequentially — the next request only starts after the previous one resolves. For 100 requests each taking 100ms, this is ~10 seconds total. Promise.all() fires all requests concurrently, completing in ~100ms (the time of the slowest request). This is a common async antipattern called 'sequential await in a loop'.
Question 18: A partial index is created on a 'products' collection: db.products.createIndex({ price: 1 }, { partialFilterExpression: { inStock: true } }). Which query will MongoDB guarantee uses this index?
- db.products.find({ price: { $gt: 50 }, inStock: { $exists: true } })
- db.products.find({ inStock: true })
- db.products.find({ price: { $gt: 50 } })
- db.products.find({ price: { $gt: 50 }, inStock: true }) (Correct answer)
Correct answer: db.products.find({ price: { $gt: 50 }, inStock: true })
A partial index only indexes documents that match the partialFilterExpression. For MongoDB to use this index, the query filter must include a condition that is at least as restrictive as the partialFilterExpression — in this case, { inStock: true } must appear explicitly. A query on price alone could match out-of-stock documents that are not in the index, so MongoDB cannot safely use the partial index for it. The $exists check is not equivalent to the boolean true filter.
Question 19: What is the correct Angular template syntax for two-way data binding on an input element?
- (input)='name=$event.target.value'
- [(ngModel)]='name' (Correct answer)
- [value]='name'
- {{name}}
Correct answer: [(ngModel)]='name'
[(ngModel)] is the 'banana in a box' syntax that combines property binding and event binding for two-way data binding.
Question 20: What is the Node.js Event Loop and why is it important for MEAN stack applications?
- A loop that processes DOM events in the browser
- A queue that manages database transactions sequentially
- A single-threaded mechanism that processes async callbacks without blocking, enabling high concurrency (Correct answer)
- A multi-threaded scheduler for parallel task execution
Correct answer: A single-threaded mechanism that processes async callbacks without blocking, enabling high concurrency
Node.js's event loop processes I/O callbacks, timers, and promises on a single thread without blocking, making it efficient for high-concurrency API servers.
Question 21: In Angular, you configure a route with `canActivateChild: [AuthGuard]`. Which of the following accurately describes how this guard differs in behavior from `canActivate: [AuthGuard]` on the same route?
- canActivateChild prevents lazy-loaded child modules from being downloaded, while canActivate only blocks navigation
- canActivateChild and canActivate behave identically — both block the parent and all children
- canActivateChild runs before the parent component is instantiated, while canActivate runs after
- canActivateChild runs for every child route activation, while canActivate runs only once when the parent route is first activated (Correct answer)
Correct answer: canActivateChild runs for every child route activation, while canActivate runs only once when the parent route is first activated
canActivate guards the parent route itself and fires once when navigating to that route. canActivateChild fires every time a child route within that parent is activated — even if the parent is already loaded and the user is navigating between siblings. This makes canActivateChild the right choice when you want per-child-navigation access checks without re-evaluating the parent.
Question 22: A component decorated with `@Component({ changeDetection: ChangeDetectionStrategy.OnPush })` receives an input `@Input() items: string[]`. A parent component pushes a new string onto the existing array reference. Why does the child component's view NOT update?
- OnPush only runs change detection when the input reference changes, not when the object's contents mutate (Correct answer)
- OnPush disables all change detection including zone.js events
- Arrays are not valid inputs for OnPush components
- The parent must call `markForCheck()` before mutating any child input
Correct answer: OnPush only runs change detection when the input reference changes, not when the object's contents mutate
ChangeDetectionStrategy.OnPush instructs Angular to skip change detection for the component unless one of its input references changes, an async pipe receives a new value, or change detection is manually triggered. Mutating the existing array (push) does not create a new reference, so Angular's comparison sees no difference and skips re-rendering the child.
Question 23: What does the MongoDB `upsert` option do in an update operation?
- Updates all matching documents
- Validates the document before updating
- Deletes and re-inserts the document
- Inserts a new document if no matching document exists (Correct answer)
Correct answer: Inserts a new document if no matching document exists
When upsert: true is set, MongoDB inserts a new document if no document matches the filter criteria, otherwise it updates the existing one.
Question 24: What is the purpose of the MongoDB $bucket aggregation stage?
- Groups documents by a hashed value of a field
- Creates histogram indexes on numeric fields
- Distributes documents across shards
- Categorizes documents into user-defined ranges (buckets) based on a field value (Correct answer)
Correct answer: Categorizes documents into user-defined ranges (buckets) based on a field value
$bucket groups incoming documents into contiguous, user-specified ranges and counts (or computes) values within each range.
Question 25: In a Node.js Worker Threads setup, a main thread passes a large `Float64Array` to a worker using `postMessage(buffer, [buffer.transferList])`. After the transfer, the main thread attempts to read `buffer[0]`. What is the result, and why?
- It throws a TypeError, because the ArrayBuffer backing the Float64Array has been detached (Correct answer)
- It returns the original value, because transferable objects are copied not moved when sent to workers
- It returns undefined, because the Float64Array reference is garbage collected after transfer
- It returns 0, because transferring zero-fills the original buffer as a safety measure
Correct answer: It throws a TypeError, because the ArrayBuffer backing the Float64Array has been detached
The Transferable Objects protocol in the Web Workers / Node.js Worker Threads API performs a *zero-copy move*, not a copy. The underlying `ArrayBuffer` is detached from the originating context and ownership is transferred to the worker. Any subsequent access to the original TypedArray (or its buffer) throws a `TypeError: Cannot perform %TypedArray%.prototype.get on a detached ArrayBuffer`. This is the key trade-off of transfer vs. structured clone: transfer is O(1) but destructive; clone is safe but O(n).
Question 26: You mount a third-party middleware with `app.use(thirdPartyMiddleware)` and later discover it never calls `next()` for certain requests, silently hanging them. Without modifying the third-party package, what is the most architecturally correct Express-native way to enforce a timeout and forward a `503` for those hung requests?
- Register an `uncaughtException` handler in Node.js that intercepts the hanging promise and sends a 503
- Use `app.use(express.timeout(5000))` built into Express to automatically abort hung middleware
- Set `req.socket.setTimeout(5000)` in a preceding middleware; Express will automatically forward to the error handler when the socket times out
- Wrap thirdPartyMiddleware with a custom middleware that sets a `setTimeout` before calling it, and in the timeout callback calls `next(new Error('timeout'))` and sets a flag so subsequent next() calls from the third-party code are ignored (Correct answer)
Correct answer: Wrap thirdPartyMiddleware with a custom middleware that sets a `setTimeout` before calling it, and in the timeout callback calls `next(new Error('timeout'))` and sets a flag so subsequent next() calls from the third-party code are ignored
Express has no built-in timeout middleware (`express.timeout` does not exist in modern Express 4/5). The correct approach is to wrap the problematic middleware: set a `setTimeout`, and inside it call `next(new Error('upstream timeout'))` with a guard flag (`timedOut = true`) so that if the third-party code eventually calls `next()`, the flag prevents double-advancing the middleware chain. `req.socket.setTimeout` fires a socket-level event but does not automatically propagate to Express's error handler. The `uncaughtException` approach is dangerous and unrelated to per-request handling.
Question 27: What is Angular's Change Detection strategy `OnPush` used for?
- Improves performance by only checking a component when its inputs change or events fire (Correct answer)
- Forces immediate UI updates on every data change
- Disables change detection for a component entirely
- Pushes data changes to a remote server
Correct answer: Improves performance by only checking a component when its inputs change or events fire
ChangeDetectionStrategy.OnPush tells Angular to skip change detection for a component unless its @Input references change, an event occurs, or an Observable emits.
Question 28: In MongoDB, which design pattern should you prefer when related data is always accessed together and the 'many' side has a bounded, small number of items?
- Always using references with separate collections
- Using a junction collection like a relational join table
- Embedding the related documents inside the parent document (Correct answer)
- Storing the relationship as a comma-separated string field
Correct answer: Embedding the related documents inside the parent document
Embedding is preferred when data is always read together and the nested array won't grow unboundedly (e.g., a blog post's comments when there are fewer than a few hundred). It avoids extra queries and keeps related data in one atomic document.
Question 29: What Angular pipe is used to format a date in a template?
- date (Correct answer)
- dateFormat
- formatDate
- moment
Correct answer: date
Angular's built-in `date` pipe formats a date value according to locale rules, e.g., {{ today | date:'short' }}.
Question 30: In Angular, what is the purpose of the `ChangeDetectionStrategy.OnPush` setting?
- Limits change detection to when input references change or events are emitted (Correct answer)
- Forces change detection on every browser event
- Disables change detection entirely for the component
- Runs change detection only on component initialization
Correct answer: Limits change detection to when input references change or events are emitted
OnPush strategy tells Angular to run change detection only when input properties change by reference or an observable emits, improving performance.
MEAN Stack Developer Certification
This certification exam validates proficiency in the MEAN stack — MongoDB, Express.js, Angular, and Node.js — covering full-stack JavaScript development including database management, server-side routing, frontend frameworks, and deployment practices.
Exam Rules
- You can skip questions and return to them later
- Flag questions for review before submitting
- No feedback shown until you submit the entire exam
- Unanswered questions count as wrong — answer everything
- 10 pretest questions are mixed in and don't affect your score
- Timer auto-submits when time runs out
- Your progress is auto-saved every 30 seconds