MEAN Stack Developer Certification — Questions and Answers
Question 1: A Node.js HTTP server under heavy load is exhibiting high latency despite low CPU usage. Heap snapshots show no memory leak. The event loop lag metric (measured via `perf_hooks`) spikes to ~800ms. Which of the following is the MOST likely root cause?
- Synchronous I/O or a CPU-bound operation blocking the event loop between iterations (Correct answer)
- Excessive use of `process.nextTick()` starving I/O callbacks
- The V8 garbage collector running full GC cycles too frequently
- A misconfigured `keep-alive` timeout causing sockets to queue indefinitely
Correct answer: Synchronous I/O or a CPU-bound operation blocking the event loop between iterations
High event loop lag with low CPU and no memory leak strongly points to synchronous blocking code (e.g., `fs.readFileSync`, a large JSON.parse, or a tight computation loop) that prevents the event loop from processing I/O callbacks. `process.nextTick()` starvation (option B) would appear as microtask queue flooding. Keep-alive issues (option C) affect connection pooling, not loop lag. GC pressure (option D) would surface in heap metrics and higher CPU.
Question 2: What service should you inject to access URL route parameters inside an Angular component?
- Router
- RouterLink
- ActivatedRoute (Correct answer)
- RouteConfig
Correct answer: ActivatedRoute
ActivatedRoute provides observables for the current route's parameters (params), query parameters (queryParams), and static route data.
Question 3: In Express.js, when a middleware function calls `next('route')` instead of `next()`, what is the exact behavior?
- It skips only the immediately following middleware function in the stack
- It terminates the request-response cycle and sends a 404 response
- It behaves identically to next() but also logs a deprecation warning
- It skips all remaining middleware in the current router and passes control to the next matching route handler (Correct answer)
Correct answer: It skips all remaining middleware in the current router and passes control to the next matching route handler
`next('route')` is a special form that skips all remaining handlers/middleware registered on the current route and jumps to the next route definition that matches the same path. This only works inside middleware or handlers mounted with `app.METHOD()` or `router.METHOD()`, not inside middleware mounted with `app.use()`.
Question 4: Which MongoDB CRUD method should you use to insert multiple documents in a single network round-trip?
- save() with an array argument
- insertMany() (Correct answer)
- bulkWrite() with insert operations only
- insertOne() called in a loop
Correct answer: insertMany()
insertMany() accepts an array of documents and inserts them all in one operation, drastically reducing network overhead compared to calling insertOne() repeatedly. bulkWrite() also works but is more complex and designed for mixed operation types.
Question 5: Node.js's `cluster` module forks worker processes to utilize multiple CPU cores. Which statement accurately describes how incoming TCP connections are distributed among workers in Node.js v16+ on Linux?
- The master process uses a least-connections algorithm to forward file descriptors to the least-busy worker
- The master process accepts connections and distributes them to workers via a round-robin algorithm by default, except when `cluster.schedulingPolicy` is set to `SCHED_NONE` (Correct answer)
- Each worker binds independently to the port using `SO_REUSEPORT`, and the OS kernel distributes connections using its own load balancing
- Workers poll a shared queue in the master process using `process.send()` IPC to pull connections on demand
Correct answer: The master process accepts connections and distributes them to workers via a round-robin algorithm by default, except when `cluster.schedulingPolicy` is set to `SCHED_NONE`
On all platforms except Windows, Node.js cluster defaults to `SCHED_RR` (round-robin), where the master process is the sole listener and distributes accepted connection handles to workers via IPC. Setting `cluster.schedulingPolicy = cluster.SCHED_NONE` hands off balancing to the OS. The `SO_REUSEPORT` behavior describes the Windows model, not the Linux default.
Question 6: What is the difference between MongoDB's `deleteOne()` and `findOneAndDelete()` methods?
- There is no functional difference; they are aliases
- deleteOne() returns a result with deletedCount; findOneAndDelete() returns the deleted document itself (Correct answer)
- deleteOne() removes all matching documents; findOneAndDelete() removes only the first
- findOneAndDelete() is faster because it skips index lookups
Correct answer: deleteOne() returns a result with deletedCount; findOneAndDelete() returns the deleted document itself
deleteOne() returns an acknowledgment object (e.g., { acknowledged: true, deletedCount: 1 }) but not the document. findOneAndDelete() atomically finds, returns, and deletes the document — useful when you need the document's content after removing it.
Question 7: Your Angular app uses lazy-loaded modules served via a CDN with long-lived `Cache-Control: max-age=31536000, immutable` headers. After a security patch, you push a new build with content-hashed chunk filenames. Old sessions still running in browsers load the patched `main.hash1.js` but cached lazy chunks from the previous build (`feature.oldhash.js`). Which deployment strategy SPECIFICALLY prevents mixed old/new chunk execution in active sessions?
- Implement a build version check via a polling endpoint; force reload when the app version changes (Correct answer)
- Use `Cache-Control: no-store` on all JavaScript chunks
- Invalidate the CDN cache for all files after every deploy
- Configure the Angular service worker to clear the cache on activation
Correct answer: Implement a build version check via a polling endpoint; force reload when the app version changes
Content-hashed filenames with `immutable` caching are correct for long-term caching of static assets — you should NOT break this with `no-store`. CDN invalidation updates what new page loads fetch but does nothing for already-running SPAs that have loaded `main.hash1.js` and still hold references to old lazy chunk URLs. A version polling endpoint (e.g., checking `/version.json` every few minutes) detects when a new build is live and can trigger `window.location.reload()` to force the browser to fetch all new hashed chunks atomically. The Angular service worker approach helps but has activation timing edge cases in active sessions.
Question 8: How do you set the HTTP status code of a response in Express.js?
- res.setStatus(404)
- res.code(404)
- response.status = 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 9: What does the MongoDB `upsert` option do in an update operation?
- Inserts a new document if no matching document exists (Correct answer)
- Deletes and re-inserts the document
- Updates all matching documents
- Validates the document before updating
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 10: What does connection pooling do for MongoDB in a Node.js application?
- Reuses a set of pre-established database connections rather than creating a new one for each query (Correct answer)
- Caches query results to reduce database load
- Limits the number of concurrent MongoDB operations
- Distributes queries across multiple MongoDB servers
Correct answer: Reuses a set of pre-established database connections rather than creating a new one for each query
Connection pooling maintains a pool of open connections that queries can reuse, avoiding the overhead of establishing a new TCP connection and MongoDB handshake for every operation.
Question 11: A Node.js/Express API experiences a memory leak under sustained load. Heap snapshots show that Request objects are being retained. The application uses a custom middleware that attaches a logger to each request. What is the most likely root cause?
- Express's req object holds a reference to the TCP socket, preventing GC until the connection is closed
- The middleware stores req references in a module-level Map or array for metrics tracking without ever deleting entries on response finish (Correct answer)
- Using res.locals to pass data between middleware creates circular references that the V8 garbage collector cannot collect
- Async middleware functions that call next() without await cause unresolved promise chains to retain the request scope
Correct answer: The middleware stores req references in a module-level Map or array for metrics tracking without ever deleting entries on response finish
The most common cause of request object retention in Express is module-level collections (Map, Set, or array) used for metrics, rate limiting, or logging that store req or res references without cleaning them up on the 'finish' or 'close' event of the response. Since these collections live at module scope (outside the request lifecycle), the GC cannot collect them. The fix is attaching cleanup via res.on('finish', () => map.delete(reqId)). The other options describe technically real concerns but are either handled by Node.js/V8 automatically or are not the typical pattern described.
Question 12: Which Node.js method limits the concurrency of multiple async operations?
- There is no built-in method; use a semaphore pattern (Correct answer)
- Promise.race()
- Promise.allSettled()
- Promise.all()
Correct answer: There is no built-in method; use a semaphore pattern
Node.js has no built-in concurrency limiter; developers implement semaphore/queue patterns or use libraries like `p-limit` to cap parallel operations.
Question 13: What is the difference between `@Input()` and `@Output()` decorators in Angular?
- @Input() is for template binding; @Output() is for service calls
- @Input() receives data from parent; @Output() emits events to the parent with EventEmitter (Correct answer)
- @Input() sends data to the server; @Output() receives server responses
- @Input() handles form inputs; @Output() submits form data
Correct answer: @Input() receives data from parent; @Output() emits events to the parent with EventEmitter
@Input() allows a parent component to pass data down to a child, while @Output() with EventEmitter lets a child emit events that the parent can listen to.
Question 14: In Express.js, what does `res.json()` do differently from `res.send()`?
- It compresses the response
- It enables CORS headers
- It automatically sets Content-Type to application/json (Correct answer)
- It sets the status code to 201
Correct answer: It automatically sets Content-Type to application/json
res.json() automatically sets the Content-Type header to application/json and JSON-stringifies the object.
Question 15: What is the purpose of the MongoDB `explain()` method?
- Adds a description field to documents
- Generates schema documentation
- Returns execution plan and performance statistics for a query (Correct answer)
- Lists all indexes on a collection
Correct answer: Returns execution plan and performance statistics for a query
explain() provides details about query execution, including the winning plan, index usage, and statistics like documents examined.
Question 16: A MEAN stack app uses JWT for auth. The access token is stored in memory (JS variable) and the refresh token is in an HttpOnly cookie. An attacker performs a successful CSRF attack on the /auth/refresh endpoint. What is the practical impact, and which additional mitigation closes this gap?
- The attacker triggers a token refresh server-side but cannot read the new access token from the response due to CORS; mitigate with a CSRF token on the refresh endpoint (Correct answer)
- No impact — HttpOnly cookies are immune to CSRF; no additional mitigation needed
- The attacker can refresh the session and obtain a new access token in their own JS context; mitigate with SameSite=Strict on the refresh cookie
- The attacker can steal the HttpOnly cookie via the CSRF request; mitigate with Content-Security-Policy headers
Correct answer: The attacker triggers a token refresh server-side but cannot read the new access token from the response due to CORS; mitigate with a CSRF token on the refresh endpoint
CSRF can force the victim's browser to send the HttpOnly refresh cookie to the server, causing a valid token refresh. However, because the attacker's origin is cross-site, CORS policy prevents the attacker's JavaScript from reading the response body (the new access token). Despite this, the server-side state is affected (token rotation logs, rate limits, audit trails). The correct mitigation is adding a CSRF token (double-submit cookie pattern or synchronizer token) to the refresh endpoint. SameSite=Strict is also valid but breaks cross-origin SSO flows; a CSRF token is more targeted. HttpOnly does NOT prevent CSRF — it only prevents JS from reading the cookie.
Question 17: What is the recommended way to store sensitive configuration values (e.g., JWT secrets, DB passwords) in a MEAN stack production deployment?
- Use environment variables loaded at runtime, never committed to source control (Correct answer)
- Store them in a .env file committed to the Git repository
- Hard-code them in the server.js file for reliability
- Encrypt them with MD5 and store them in the MongoDB config collection
Correct answer: Use environment variables loaded at runtime, never committed to source control
Sensitive values should be stored as environment variables (e.g., via dotenv locally, secrets managers in production) and never committed to version control.
Question 18: What does OWASP Top 10 mean in the context of securing a MEAN stack application?
- A list of the ten best Node.js security packages recommended by OWASP
- The ten Angular security directives required for enterprise applications
- MongoDB's top ten performance optimization recommendations
- The ten most critical web application security risks published by OWASP that developers should protect against (Correct answer)
Correct answer: The ten most critical web application security risks published by OWASP that developers should protect against
The OWASP Top 10 lists the most dangerous web vulnerabilities (injection, broken auth, XSS, etc.) that MEAN stack developers must mitigate when building production applications.
Question 19: In Mongoose, what method is used to find a single document by its _id field?
- findById() (Correct answer)
- getById()
- findOne()
- findByPk()
Correct answer: findById()
Mongoose's findById() is a shorthand for findOne({ _id: id }) and is the idiomatic way to fetch by ID.
Question 20: You are deploying a MEAN stack application behind an Nginx reverse proxy. After enabling trust proxy in Express with `app.set('trust proxy', 1)`, your rate limiter based on `req.ip` stops working correctly in production — some users are rate-limited immediately while others bypass it entirely. What is the most likely root cause?
- The rate limiter is keying on IPv6 addresses returned by `req.ip` while the CDN forwards IPv4 addresses in `X-Forwarded-For`, creating duplicate keys per user
- The `trust proxy` setting of `1` trusts only one hop, but your infrastructure has multiple proxy layers (e.g., CDN → load balancer → Nginx), so `req.ip` resolves to an intermediate proxy IP rather than the real client IP (Correct answer)
- Nginx is not forwarding the `X-Forwarded-For` header, so `req.ip` falls back to the loopback address for all requests
- Express's `trust proxy` setting conflicts with Nginx's `proxy_pass` directive when both are on the same server, causing `req.ip` to return `undefined`
Correct answer: The `trust proxy` setting of `1` trusts only one hop, but your infrastructure has multiple proxy layers (e.g., CDN → load balancer → Nginx), so `req.ip` resolves to an intermediate proxy IP rather than the real client IP
When `trust proxy` is set to `1`, Express trusts one hop of the `X-Forwarded-For` chain. In multi-layer infrastructure (CDN → load balancer → Nginx → Node), the header may contain multiple IPs. With `trust proxy: 1`, Express picks the rightmost IP it trusts, which could be an internal load balancer IP — shared across all clients — causing some users to instantly hit the rate limit (shared IP) while others bypass it if the header isn't populated correctly. The fix is to set `trust proxy` to the correct number of proxy hops or to a specific trusted IP/subnet range.
Question 21: Which Angular decorator is used to inject a service into a component?
- @Inject
- @Injectable
- Constructor parameter typing (Correct answer)
- @Component with providers
Correct answer: Constructor parameter typing
Angular's dependency injection reads TypeScript constructor parameter types to inject services automatically.
Question 22: What is `util.promisify()` used for in Node.js?
- Creates utility Promises for common async patterns
- Converts callback-style functions following the error-first pattern into Promise-returning functions (Correct answer)
- Validates that a function returns a Promise
- Adds timeout capability to existing Promises
Correct answer: Converts callback-style functions following the error-first pattern into Promise-returning functions
util.promisify() wraps legacy Node.js callback-based functions (like fs.readFile) into functions that return Promises, enabling async/await usage.
Question 23: In MongoDB, what does a 'covered query' mean?
- A query with all fields projected
- A query running inside a transaction
- A query satisfied entirely by an index without accessing documents (Correct answer)
- A query that uses the $match stage
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 24: What happens when you provide a service at the component level using the 'providers' array in @Component?
- A new service instance is created for each instance of that component (Correct answer)
- The service becomes a singleton shared across the entire app
- The service is only available in the root module
- The service cannot be injected into child components
Correct answer: A new service instance is created for each instance of that component
Component-level providers create a new service instance for each component instance, isolating state between components.
Question 25: You are using MongoDB Change Streams to watch a collection for inserts and updates. You notice that after a primary failover during a replica set election, your change stream stops receiving events even after the new primary is elected. What is the correct way to make your change stream resilient to replica set elections?
- Set readPreference to 'primaryPreferred' on the change stream
- Store and resume from the resumeToken when the stream errors or closes (Correct answer)
- Use a tailable cursor instead of a change stream on the oplog
- Increase the oplog size so events are retained during the election window
Correct answer: Store and resume from the resumeToken when the stream errors or closes
Change streams return a resumeToken with each event. When a failover occurs and the stream closes with an error, you should catch the error, retrieve the last stored resumeToken, and re-open the change stream using the 'resumeAfter' or 'startAfter' option. MongoDB guarantees that events are recoverable as long as the oplog has not rolled over. This is the idiomatic pattern for fault-tolerant change stream consumers.
Question 26: What CSS class does Angular add to a form control that fails validation?
- ng-error
- ng-invalid (Correct answer)
- ng-dirty
- ng-invalid-touched
Correct answer: ng-invalid
Angular adds the ng-invalid class to any form control that fails validation, regardless of whether the user has interacted with it.
Question 27: A Node.js HTTP server experiences 'memory leak' symptoms under sustained load. Heap snapshots show a growing number of `EventEmitter` instances. Which of the following is the most likely root cause?
- The `http` module allocates a new V8 heap per incoming connection
- Node.js garbage collector cannot reclaim EventEmitter objects when there are more than 10 listeners
- Using `emitter.on()` instead of `emitter.once()` prevents GC for the lifetime of the process
- Listeners are being added to a shared emitter per request without ever being removed (Correct answer)
Correct answer: Listeners are being added to a shared emitter per request without ever being removed
EventEmitter instances are retained in memory as long as something holds a reference to them — most commonly when listeners are attached but never removed. If each HTTP request attaches a listener to a shared emitter (e.g., for 'data' or 'error' events) without calling `emitter.removeListener()` or `emitter.off()`, those closures accumulate and prevent GC of the captured scope. Node.js does emit a MaxListenersExceededWarning at 11 listeners, but does not garbage-collect them. The fix is to use `emitter.once()` for one-time handlers, or explicitly remove listeners in cleanup logic.
Question 28: What happens if an Express middleware function does not call `next()` and does not send a response?
- The request hangs indefinitely (Correct answer)
- The connection is closed after a default timeout
- Express automatically sends a 500 error
- Express skips to the next registered route
Correct answer: The request hangs indefinitely
If a middleware neither calls `next()` nor ends the response, the request remains open and the client waits until a network or server timeout occurs.
Question 29: What is the purpose of MongoDB's `writeConcern` option in write operations?
- It determines the order in which bulk write operations are executed
- It specifies the level of acknowledgment required from MongoDB before a write is considered successful (Correct answer)
- It controls which fields are written to disk during an update
- It sets the maximum document size for write operations
Correct answer: It specifies the level of acknowledgment required from MongoDB before a write is considered successful
writeConcern specifies the level of acknowledgment MongoDB must receive before returning success, balancing between performance (w:0) and durability (w:'majority').
Question 30: What is a potential security risk of setting `express.static` to serve the project root directory?
- It may expose sensitive files like `package.json` or `.env` to public access (Correct answer)
- It disables gzip compression
- It increases memory usage
- It prevents dynamic routes from working
Correct answer: It may expose sensitive files like `package.json` or `.env` to public access
Serving from the project root means all files — including source code, environment files, and configs — become publicly downloadable.
Question 31: In Angular template-driven forms, what attribute is required on a form control for Angular to track it as part of the form model?
- [(model)]
- formControlName
- formControl
- ngModel (Correct answer)
Correct answer: ngModel
The ngModel directive registers the element with the parent NgForm, making it part of the template-driven form model and enabling two-way data binding.
Question 32: What is the purpose of the 'canActivate' route guard interface in Angular?
- To prevent navigation away from a route
- To control whether a user can navigate to a route (Correct answer)
- To resolve data before a route is activated
- To lazy-load a module when its route is first accessed
Correct answer: To control whether a user can navigate to a route
canActivate is a guard interface that runs a check before a route is activated, returning true to allow navigation or false to block it.
Question 33: What does the MongoDB $facet aggregation stage allow you to do?
- Run multiple aggregation pipelines within a single stage on the same input (Correct answer)
- Join two collections using a common field
- Split documents into multiple output collections
- Create faceted search indexes
Correct answer: Run multiple aggregation pipelines within a single stage on the same input
$facet enables multi-faceted aggregations by processing multiple sub-pipelines on the same set of input documents in one pass.
Question 34: What is the purpose of calling `next()` in Express middleware?
- Passes control to the next matching middleware or route handler (Correct answer)
- Moves to the next HTTP request
- Sends the response to the client
- Skips remaining middleware in the chain
Correct answer: Passes control to the next matching middleware or route handler
Calling next() without arguments passes control to the next middleware function in the stack; calling next(err) skips to error-handling middleware.
Question 35: Which MongoDB update operator increments a numeric field by a specified amount without reading the document first?
- $inc (Correct answer)
- $add
- $push
- $set
Correct answer: $inc
$inc atomically increments (or decrements with a negative value) a numeric field by the specified amount. For example, { $inc: { views: 1 } } adds 1 to the views field. $set replaces a field's value entirely.
Question 36: In NgRx, what is the correct way for a component to trigger a state change?
- Call the Reducer function directly with a new state
- Directly modify the state object returned by a Selector
- Inject the Store and call store.dispatch(myAction()) (Correct answer)
- Import the state object and mutate it via an Effect
Correct answer: Inject the Store and call store.dispatch(myAction())
In NgRx, state is read-only from the component's perspective. To change state, a component must inject the Store and dispatch an Action: this.store.dispatch(loadUsers()). The Store routes the action to the relevant Reducer, which computes and returns the new state.
Question 37: What is the purpose of `process.nextTick()` versus `setImmediate()` in Node.js?
- `process.nextTick()` is for synchronous code; `setImmediate()` is for async code
- Both execute at identical priority in the event loop
- `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()` fires after I/O callbacks; `setImmediate()` fires before the current operation completes
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 38: You have a MongoDB collection with a compound index on `{ status: 1, createdAt: -1 }`. Which query will NOT benefit from an index scan (i.e., will require a COLLSCAN or inefficient use of the index)?
- db.orders.find({ status: 'active', createdAt: { $gt: ISODate('2025-01-01') } })
- db.orders.find({ status: { $in: ['active', 'pending'] } }).sort({ createdAt: -1 })
- db.orders.find({ status: 'active' }).sort({ createdAt: -1 })
- db.orders.find({}).sort({ createdAt: -1 }) (Correct answer)
Correct answer: db.orders.find({}).sort({ createdAt: -1 })
A query that sorts by `createdAt` without filtering on `status` (the leading index field) cannot efficiently use the compound index `{ status: 1, createdAt: -1 }`. MongoDB requires the leftmost prefix of a compound index to be used — skipping the leading field means the index cannot be traversed in sorted order for `createdAt` alone. The other three queries all reference `status` as an equality or range filter, allowing the index to be used.
Question 39: In Express.js, a middleware function calls `next('route')` instead of `next()`. What is the exact behavior?
- It terminates the request-response cycle immediately without sending a response
- It behaves identically to `next()` — the string argument is ignored
- It skips all remaining middleware in the current router and passes control to the next matching route handler (Correct answer)
- It passes an error object with the string 'route' to the next error-handling middleware
Correct answer: It skips all remaining middleware in the current router and passes control to the next matching route handler
`next('route')` is a special invocation that skips the remaining handlers for the current route and jumps to the next route that matches the request path. It only works inside middleware or handlers loaded with `app.METHOD()` or `router.METHOD()`, not inside `app.use()` middleware.
Question 40: Which of the following correctly defines a parameterized route in Express that captures an integer-like segment named `id`?
- app.get('/users/{id}', handler)
- app.get('/users/[id]', handler)
- app.get('/users/?id', handler)
- app.get('/users/:id(\\d+)', handler) (Correct answer)
Correct answer: app.get('/users/:id(\\d+)', handler)
Express supports optional regex constraints on route parameters using the syntax `:param(regex)`, so `/:id(\d+)` restricts `id` to digits.
Question 41: What does the `express.static()` middleware do?
- Validates static file MIME types
- Caches dynamic responses as static files
- Serves static files like HTML, CSS, and images from a directory (Correct answer)
- Generates static HTML from templates
Correct answer: Serves static files like HTML, CSS, and images from a directory
express.static() is built-in middleware that serves files from a specified directory, handling file streaming, ETags, and cache headers automatically.
Question 42: What does `res.locals` provide in Express.js?
- An object for passing data from middleware to route handlers within a single request (Correct answer)
- Template variables for server-side rendering
- Local configuration settings for the response
- A cache for frequently accessed response data
Correct answer: An object for passing data from middleware to route handlers within a single request
res.locals is a request-scoped object where middleware can store data (like an authenticated user) that later middleware and route handlers can access.
Question 43: What is Docker and how does it benefit MEAN stack application deployment?
- A CI/CD pipeline tool for deploying MEAN stack applications
- Containerizes each application component (Node, MongoDB, Angular) for consistent, portable deployments (Correct answer)
- A reverse proxy for routing traffic to Node.js servers
- A database management system for containerized MongoDB instances
Correct answer: Containerizes each application component (Node, MongoDB, Angular) for consistent, portable deployments
Docker packages applications with their dependencies into containers that run consistently across development, staging, and production environments, eliminating 'works on my machine' issues.
Question 44: You have a Node.js stream pipeline where a Readable stream produces data faster than a Writable stream can consume it. Which behavior correctly describes what happens when backpressure is NOT properly handled?
- Node.js automatically throttles the Readable stream by pausing it at the OS level
- The Readable stream's internal buffer grows unboundedly, potentially causing out-of-memory errors (Correct answer)
- The Writable stream drops excess chunks silently to maintain throughput
- The event loop blocks until the Writable stream catches up
Correct answer: The Readable stream's internal buffer grows unboundedly, potentially causing out-of-memory errors
Without backpressure handling (i.e., not checking the return value of writable.write() or not using pipe()/pipeline()), the Readable stream keeps pushing data into memory regardless of consumer speed. This causes the internal buffer to grow unchecked, leading to excessive memory consumption. Node.js does not automatically throttle the source — that is the developer's responsibility via the backpressure mechanism.
Question 45: What is the purpose of MongoDB transactions introduced in version 4.0?
- Enable cross-database replication
- Enforce document schema validation
- Provide ACID guarantees across multiple documents and collections (Correct answer)
- Improve single-document write speed
Correct answer: Provide ACID guarantees across multiple documents and collections
MongoDB multi-document transactions allow multiple reads and writes across documents, collections, and databases to execute with ACID properties.
Question 46: What does the `trackBy` function do when used with `*ngFor`?
- Sorts items in the list by a property
- Groups items in the list for display
- Filters items in the list by a condition
- Tells Angular how to track items uniquely to minimize DOM re-rendering when the list changes (Correct answer)
Correct answer: Tells Angular how to track items uniquely to minimize DOM re-rendering when the list changes
trackBy provides a unique identifier for each list item so Angular can reuse existing DOM nodes instead of destroying and recreating them when data changes.
Question 47: In MongoDB, you have a collection where documents embed an array field `tags`. You run the query: `db.items.find({ tags: { $elemMatch: { $eq: 'node' } } })` versus `db.items.find({ tags: 'node' })`. Both return the same results. When does using `$elemMatch` become NECESSARY instead of the simpler dot-notation query?
- When matching array elements that must satisfy MULTIPLE conditions simultaneously on the same element (e.g., `{ $elemMatch: { score: { $gt: 80 }, grade: 'A' } }`). (Correct answer)
- When querying nested arrays (arrays of arrays), because `$elemMatch` flattens them automatically.
- When the index on `tags` is a multikey index, because simple equality queries don't use multikey indexes.
- When the array contains more than 1,000 elements, because MongoDB's simple array query degrades beyond that threshold.
Correct answer: When matching array elements that must satisfy MULTIPLE conditions simultaneously on the same element (e.g., `{ $elemMatch: { score: { $gt: 80 }, grade: 'A' } }`).
`$elemMatch` is essential when you need a SINGLE array element to satisfy multiple conditions at once. Without it, `{ score: { $gt: 80 }, grade: 'A' }` on an array field would match documents where ANY element has `score > 80` AND ANY (possibly different) element has `grade: 'A'` — the conditions are evaluated across the array collectively, not per-element. `$elemMatch` enforces that both conditions must match the SAME element. For single-condition queries like `{ tags: 'node' }`, the simpler form is equivalent and preferred. Options B, C, and D are all false: there's no 1,000-element threshold; multikey indexes work with simple equality; and `$elemMatch` does not flatten nested arrays.
Question 48: In a Node.js/Express API, you use `Promise.all([queryA(), queryB(), queryC()])` to run three independent MongoDB queries concurrently. One of the promises rejects. Which statement best describes the outcome?
- `Promise.all` rejects immediately with the first rejection reason, but the other two promises continue executing to completion (Correct answer)
- `Promise.all` waits for all three promises to settle before rejecting, collecting all errors into an array
- The rejection is silently ignored and `Promise.all` resolves with the results of the two successful queries
- `Promise.all` rejects immediately and automatically cancels the other two in-flight MongoDB operations
Correct answer: `Promise.all` rejects immediately with the first rejection reason, but the other two promises continue executing to completion
`Promise.all` rejects as soon as any one of the input promises rejects, forwarding that rejection reason — this is called 'fail-fast' behavior. Crucially, the other promises are NOT cancelled; they continue running to completion (or rejection) on their own, but their results are discarded. MongoDB operations are not automatically aborted because JavaScript promises have no built-in cancellation mechanism. To collect all results including failures, `Promise.allSettled` is the correct tool.
Question 49: Which Express method is used to redirect a client to a different URL?
- res.location()
- res.forward()
- res.redirect() (Correct answer)
- res.navigate()
Correct answer: res.redirect()
res.redirect() sends a response with a 3xx status code (default 302) and a Location header pointing to the target URL.
Question 50: 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()?
- 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
- 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)
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'.
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