MEAN Stack Developer Certification ā Questions and Answers
Question 1: In MongoDB, what is a capped collection?
- A collection with read-only access
- A fixed-size collection that overwrites oldest documents when full (Correct answer)
- A collection limited to 100 documents
- A collection with a maximum document size limit
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 2: How do you enable the built-in 'required' validator on an input field in a template-driven Angular form?
- required (Correct answer)
- validate="required"
- ngRequired
- [required]="true"
Correct answer: required
Adding the standard HTML5 'required' attribute to an input that also has ngModel activates Angular's built-in required validator.
Question 3: What does the RxJS `switchMap` operator do when a new value arrives while a previous inner Observable is still active?
- It throws an error if a previous Observable is still running
- It queues the new value until the previous Observable completes
- It cancels the previous inner Observable and subscribes to the new one (Correct answer)
- It merges both Observables and emits from both concurrently
Correct answer: It cancels the previous inner Observable and subscribes to the new one
switchMap cancels (unsubscribes from) any in-flight inner Observable when a new source value arrives, then subscribes to the new inner Observable. This makes it ideal for HTTP search requests where only the latest result matters.
Question 4: What is the purpose of a reverse proxy like Nginx in front of a Node.js/Express application?
- It compiles TypeScript files before forwarding requests to Node.js
- It handles SSL termination, load balancing, and serves static files efficiently (Correct answer)
- It replaces the need for MongoDB by caching query results in memory
- It enforces JWT authentication before requests reach Express
Correct answer: It handles SSL termination, load balancing, and serves static files efficiently
Nginx acts as a reverse proxy to handle SSL/TLS termination, distribute traffic across Node.js instances, and efficiently serve static assets without burdening Node.
Question 5: Consider this Express router code: js router.get('/items/:id(\\d+)', handler); router.get('/items/:id', fallback); A request arrives for `GET /items/abc`. Which handler executes?
- `fallback`, because `abc` does not match the `\d+` regex constraint on the first route (Correct answer)
- Both handlers execute in sequence because the path `/items/:id` appears in both routes
- `handler`, because Express matches routes greedily and the first route wins regardless of the regex
- Neither; Express returns a 400 Bad Request because the parameter fails regex validation
Correct answer: `fallback`, because `abc` does not match the `\d+` regex constraint on the first route
Express supports inline regex constraints on route parameters using the syntax `:param(regex)`. The first route only matches when `:id` consists entirely of digits (`\d+`). Since `abc` contains non-digit characters, the first route does not match, and Express continues to the second route `/items/:id`, which has no constraint and matches any string ā so `fallback` executes.
Question 6: What is rate limiting in Express and which package is commonly used?
- Capping WebSocket connections using socket.io
- Throttling database queries using mongoose middleware
- Limiting requests per time window using express-rate-limit to prevent abuse (Correct answer)
- Limiting response payload size using body-parser limits
Correct answer: Limiting requests per time window using express-rate-limit to prevent abuse
Rate limiting restricts the number of requests a client can make in a time window; express-rate-limit is the most popular package for this in Express.
Question 7: In MongoDB, what does a 'covered query' mean?
- A query that uses the $match stage
- A query satisfied entirely by an index without accessing documents (Correct answer)
- A query running inside a transaction
- A query with all fields projected
Correct answer: A query satisfied entirely by an index without accessing documents
A covered query is one where all fields in the query and projection are part of the index, so MongoDB never needs to read the actual documents.
Question 8: Consider the following code: js async function fetchAll(ids) { const results = []; for (const id of ids) { results.push(await fetch(id)); } return results; } Which statement best describes its performance characteristic when `ids` has 100 elements?
- Promises are batched automatically by the V8 engine into groups of 10
- Each fetch is awaited sequentially, so total time ā sum of all individual fetch durations (Correct answer)
- The for-of loop runs each fetch concurrently because async functions use worker threads
- Performance is identical to Promise.all(ids.map(fetch)) since both use the microtask queue
Correct answer: Each fetch is awaited sequentially, so total time ā sum of all individual fetch durations
Using `await` inside a `for...of` loop serializes each async operation ā the next iteration doesn't begin until the current `await` resolves. With 100 fetches that each take 200ms, total time is ~20 seconds. The correct approach for concurrent execution is `Promise.all(ids.map(fetch))`, which fires all 100 fetches simultaneously and waits for all to settle, reducing total time to roughly the duration of the slowest single fetch. V8 does no automatic batching, and async functions run entirely on the main thread, not worker threads.
Question 9: What is the maximum number of characters that can be entered in the name field of a Node.js package?
- 128
- 256
- 214 (Correct answer)
- 64
Correct answer: 214
In the package.json file of a Node.js project, the name field is limited to a maximum of 214 characters. This includes both letters and any additional characters used in the name. If the name field exceeds this limit, you may encounter errors or issues when working with Node.js tools and packages.
Question 10: What is the purpose of Node.js streams in a MEAN stack application?
- Chain Express middleware functions together
- Stream real-time updates to Angular clients via WebSockets
- Pipe data between MongoDB aggregation stages
- Process data in chunks for memory efficiency, ideal for large file uploads or database exports (Correct answer)
Correct answer: Process data in chunks for memory efficiency, ideal for large file uploads or database exports
Streams process data incrementally in chunks rather than loading it all into memory, making them essential for handling large files, CSV exports, or proxying requests.
Question 11: You run an aggregation pipeline with $lookup that joins a 10M-document collection. The pipeline uses allowDiskUse: true but still times out. Which index strategy will most directly resolve this without changing the pipeline logic?
- Add a single-field index on the local collection's localField
- Add a hashed index on the join field to distribute lookup load evenly across shards
- Add a compound index on the foreign collection's join field plus any fields used in a subsequent $match stage inside the $lookup pipeline (Correct answer)
- Add a text index on the foreign collection to allow full-text matching during the join
Correct answer: Add a compound index on the foreign collection's join field plus any fields used in a subsequent $match stage inside the $lookup pipeline
When $lookup uses a sub-pipeline (the newer syntax), MongoDB can use an index on the foreign collection that covers both the join field and any fields filtered inside that sub-pipeline. A compound index combining the join key with the filtered fields allows MongoDB to avoid a full collection scan on the foreign side for each document, dramatically reducing I/O. A single localField index only speeds up the outer scan, not the join itself. A text index is unrelated to equality joins, and a hashed index helps sharding distribution but not single-node lookup performance.
Question 12: What does the TypeScript `readonly` modifier do when applied to a class property?
- It causes TypeScript to serialize the property to JSON automatically
- It makes the property private so external code cannot access it
- It marks the property as optional in the constructor signature
- It prevents the property from being reassigned after the constructor runs (Correct answer)
Correct answer: It prevents the property from being reassigned after the constructor runs
readonly means the property can only be assigned during declaration or in the constructor. Any attempt to reassign it afterwards is a TypeScript compile-time error. It does not affect visibility (that is controlled by private/public/protected).
Question 13: What is CORS and how is it commonly handled in an Express API?
- Cross-Origin Resource Sharing, handled with the cors npm middleware package (Correct answer)
- Client-Origin Request System, handled with helmet middleware
- Content Origin Restriction Scheme, handled in package.json
- Cross-Origin Route Sharing, handled in app.all()
Correct answer: Cross-Origin Resource Sharing, handled with the cors npm middleware package
CORS allows or restricts web applications from making requests to a different domain; the cors npm package adds the required HTTP headers automatically.
Question 14: A Node.js/Express API uses Mongoose. A request handler performs two independent database reads and then one dependent write. Which pattern minimizes total latency without risking a race condition on the write?
- Promise.race([read1(), read2()]).then(first => write(first));
- const [r1, r2] = await Promise.all([read1(), read2()]); await write(r1, r2); (Correct answer)
- await read1(); await read2(); await write(result1, result2);
- read1().then(r1 => read2().then(r2 => write(r1, r2)));
Correct answer: const [r1, r2] = await Promise.all([read1(), read2()]); await write(r1, r2);
Promise.all fires both independent reads concurrently and resolves when both complete, then the write proceeds with both results. This eliminates the serial latency of awaiting each read sequentially. Promise.race would only give you the first result, discarding the other, making it unsuitable for a write that depends on both reads.
Question 15: Which class represents a single form input control in Angular reactive forms?
- FormInput
- FormControl (Correct answer)
- ReactiveControl
- NgControl
Correct answer: FormControl
FormControl is the most basic building block of reactive forms; it tracks the value, validation status, and interaction state of a single form input.
Question 16: You are designing a MongoDB aggregation pipeline that must compute a running total (cumulative sum) of `amount` ordered by `date` across millions of documents. Which approach produces correct results with the best performance in MongoDB 5.0+?
- Use `$group` with `$push` to accumulate all documents into an array, then `$reduce` in a `$project` stage to compute the running total
- Use `$setWindowFields` with a `$sum` window function over a `documents` window from `unbounded` to `current`, partitioned and sorted appropriately (Correct answer)
- Use `$lookup` with a self-join on date range to sum all prior documents for each record
- Use `$sort` followed by multiple `$group` stages with `$first`/`$last` to progressively accumulate totals
Correct answer: Use `$setWindowFields` with a `$sum` window function over a `documents` window from `unbounded` to `current`, partitioned and sorted appropriately
`$setWindowFields`, introduced in MongoDB 5.0, is specifically designed for window function operations like running totals, moving averages, and rank calculations. Using `{ documents: ['unbounded', 'current'] }` as the window bounds with `$sum` computes a cumulative sum efficiently without loading all documents into memory (as `$push`+`$reduce` would). The self-join approach via `$lookup` is O(n²) and catastrophically slow on large datasets. The `$group` chaining approach cannot correctly maintain per-document running totals. `$setWindowFields` is the purpose-built, performant solution.
Question 17: What is the key behavioral difference between `router.use('/admin', adminRouter)` and `router.use('/admin/', adminRouter)` in Express.js?
- The trailing slash version only matches the exact path '/admin/' and no sub-paths
- Both versions behave identically because router.use does prefix matching in all cases (Correct answer)
- There is no difference; Express normalizes trailing slashes before matching
- The version without a trailing slash also matches paths like '/administrator' because the prefix is evaluated as a starts-with pattern
Correct answer: Both versions behave identically because router.use does prefix matching in all cases
For `router.use()`, Express strips the matched prefix before passing the request to the sub-router regardless of whether a trailing slash is present. Both `/admin` and `/admin/` mount the adminRouter on paths beginning with that segment ā they behave identically. Express does NOT match '/administrator' for '/admin' mounts because path segment boundaries are respected in router mounting. The trailing slash distinction that matters is on individual route definitions (router.get), not on router.use.
Question 18: You are building an Angular service that caches an HTTP response using `shareReplay(1)`. A second subscriber joins after the first request completes. Which statement correctly describes the behavior?
- The second subscriber causes a `ReplaySubject` overflow error since the buffer size is 1
- The second subscriber triggers a new HTTP request since the original Observable has completed
- The second subscriber receives nothing because `shareReplay` only works for multicasting during active subscriptions
- The second subscriber immediately receives the last emitted value from the replay buffer without making a new HTTP request (Correct answer)
Correct answer: The second subscriber immediately receives the last emitted value from the replay buffer without making a new HTTP request
`shareReplay(1)` creates a replay buffer of size 1 that persists even after the source Observable completes. Any late subscriber will synchronously receive the last cached emission without re-executing the source (the HTTP request). This is the primary use case for `shareReplay` in Angular caching patterns. There is no overflow error ā a buffer of size 1 simply keeps only the most recent value.
Question 19: What does the range of font-weight values, from 100 to 700, mean?
- Heading level H6 to H1
- Normal to bold (Correct answer)
- Bold to normal
- Heading level H1 to H6
Correct answer: Normal to bold
In CSS, the font-weight property is used to specify the weight or thickness of a font. The values range from 100 to 900, with each value representing a specific weight.
Question 20: What is the purpose of `process.nextTick()` versus `setImmediate()` in Node.js?
- `process.nextTick()` fires before I/O callbacks in the current iteration; `setImmediate()` fires in the check phase of the next iteration (Correct answer)
- `process.nextTick()` is for synchronous code; `setImmediate()` is for async code
- `process.nextTick()` fires after I/O callbacks; `setImmediate()` fires before the current operation completes
- Both execute at identical priority in the event loop
Correct answer: `process.nextTick()` fires before I/O callbacks in the current iteration; `setImmediate()` fires in the check phase of the next iteration
`process.nextTick()` callbacks run at the end of the current phase before moving to the next event loop phase, while `setImmediate()` runs in the check phase of the following iteration.
Question 21: In Angular's dependency injection system, what is the key behavioral difference between providing a service with { providedIn: 'root' } versus listing it in a lazy-loaded module's providers array?
- A root-provided service is tree-shaken if unused; a module-provided service is always bundled into the lazy chunk
- A root-provided service is eagerly loaded; a module-provided service is instantiated only when first injected
- A root-provided service creates one singleton across the app; a module-provided service creates a new instance scoped to that lazy module and its children (Correct answer)
- There is no behavioral difference ā both result in a single application-wide singleton
Correct answer: A root-provided service creates one singleton across the app; a module-provided service creates a new instance scoped to that lazy module and its children
{ providedIn: 'root' } registers the service in the root injector, creating a single application-wide singleton shared by all modules. When a service is listed in a lazy-loaded module's providers array, Angular creates a child injector for that module, instantiating a separate instance of the service scoped to that module and its children. This can cause subtle bugs if the service holds state that should be shared globally.
Question 22: In a MongoDB sharded cluster, what is a 'jumbo chunk'?
- A chunk that exceeds the configured chunk size and cannot be split because all documents share the same shard key value (Correct answer)
- The first chunk assigned to a new shard
- A chunk that spans multiple config server nodes
- A chunk replicated to all shards
Correct answer: A chunk that exceeds the configured chunk size and cannot be split because all documents share the same shard key value
Jumbo chunks occur when a range of shard key values contains too many documents that cannot be further divided, often causing hotspots.
Question 23: 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?
- Setting SameSite=Strict on the refresh token cookie (Correct answer)
- Reducing the refresh token expiry to 1 hour
- Storing the refresh token in localStorage instead of a cookie
- Adding a CSRF token in the Authorization header for refresh requests
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 24: What is the default port MongoDB listens on?
- 5432
- 27017 (Correct answer)
- 28017
- 3306
Correct answer: 27017
MongoDB's default port is 27017, while port 28017 was used by the deprecated HTTP monitoring interface in older versions.
Question 25: What does `express.json()` middleware do in an Express application?
- Serializes response objects to JSON automatically
- Parses incoming requests with JSON payloads and populates req.body (Correct answer)
- Compresses JSON responses
- Validates JSON schema of request bodies
Correct answer: Parses incoming requests with JSON payloads and populates req.body
express.json() is built-in middleware that parses the request body as JSON when Content-Type is application/json, making it available as req.body.
Question 26: What is Angular Universal and when would you use it in a MEAN stack?
- A shared component library for Angular apps
- 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 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 27: In a RESTful API, what should the response body contain when returning HTTP 204 No Content?
- An empty body ā no content should be sent (Correct answer)
- An error message explaining why there is no content
- A JSON object confirming the operation succeeded
- The deleted resource's data for client-side cache invalidation
Correct answer: An empty body ā no content should be sent
204 No Content explicitly means the server successfully processed the request but has no content to return. Sending a body with a 204 response violates the HTTP spec and may be ignored or cause errors in some clients. It is commonly used for successful DELETE operations.
Question 28: Your MEAN stack app uses JWT authentication. A security audit reveals that your token refresh logic is vulnerable to a race condition where an attacker who steals a refresh token can use it simultaneously with the legitimate user, obtaining two new valid access token pairs before either is invalidated. Which token rotation strategy eliminates this vulnerability?
- Reduce the refresh token TTL to 5 minutes so the attack window is minimized
- Implement refresh token rotation with a reuse-detection mechanism: store a token family, and if a previously used refresh token is presented, immediately invalidate the entire family (Correct answer)
- Store refresh tokens in an HttpOnly cookie and access tokens in memory to prevent XSS-based theft of both tokens simultaneously
- Sign refresh tokens with a per-user secret derived from the user's password hash so stolen tokens become invalid after a password change
Correct answer: Implement refresh token rotation with a reuse-detection mechanism: store a token family, and if a previously used refresh token is presented, immediately invalidate the entire family
Token family rotation with reuse detection is the correct mitigation for refresh token race conditions. Each refresh generates a new token and invalidates the old one, but crucially, if an old (already-rotated) token is presented, it signals a theft scenario and the entire token family is revoked ā logging out both the attacker and the legitimate user. Reducing TTL shrinks the window but doesn't close it. Per-user secrets help post-compromise but don't prevent the concurrent race. HttpOnly cookies are a good XSS defense but don't address the race condition in token reuse.
Question 29: What is the Node.js `--inspect` flag used for?
- Enables the V8 Inspector protocol for debugging Node.js with Chrome DevTools or VS Code (Correct answer)
- Validates the syntax of a JavaScript file without running it
- Displays detailed error stack traces in production
- Inspects npm package dependencies for vulnerabilities
Correct answer: Enables the V8 Inspector protocol for debugging Node.js with Chrome DevTools or VS Code
The --inspect flag starts Node.js with the V8 Inspector enabled, allowing you to connect Chrome DevTools or an IDE for breakpoint debugging and memory profiling.
Question 30: What does `npm ci` do differently compared to `npm install`?
- Updates all packages to their latest versions
- Checks for security vulnerabilities before installing
- Installs from package-lock.json exactly, deleting node_modules first (Correct answer)
- Installs only production dependencies
Correct answer: Installs from package-lock.json exactly, deleting node_modules first
npm ci removes node_modules and installs dependencies exactly as specified in package-lock.json, ensuring reproducible builds.
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