Module Quiz
Complete this quiz after finishing all concept and practice pages.
Current Module Questions
Question 1: Sinkhole Anti-Pattern
In a layered architecture, what is the architecture sinkhole anti-pattern and what is the 80/20 rule of thumb used to detect it?
Answer: The sinkhole anti-pattern occurs when most requests pass through a layer without that layer doing meaningful work -- typically the business layer simply forwards calls to persistence. The 80/20 rule of thumb (Richards & Ford): if more than 20% of requests are pass-throughs, you have a sinkhole and the layer is paying its cost without delivering its isolation benefit.
Question 2: Pipeline vs Layered Fit
Name one system where pipeline architecture is a clearly better fit than layered, and explain in one sentence why.
Answer: An ETL or log-enrichment job where the system's core purpose is transforming data through sequential independent stages -- pipeline is a better fit because layered forces transformation logic into a degenerate single "business layer" that loses the composability and per-stage isolation of filters.
Question 3: Modular Monolith Definition
What three properties distinguish a true modular monolith from "a monolith with folders"?
Answer: (1) Each module has an explicit public API surface and internal implementation; (2) Module boundaries are enforced by a tool in CI (ArchUnit, Packwerk, import-linter, etc.), not just by convention; (3) Each module owns its persistence (schema or table prefix), so cross-module data access goes through the module API rather than through shared tables.
Question 4: Cohesion and Coupling
Given a package with Ca = 0, Ce = 8, what does this tell you? Is this a problem?
Answer: The package depends on 8 other packages but nothing depends on it. Instability I = Ce/(Ca+Ce) = 1.0 -- maximally unstable. This is not inherently a problem if the package is a leaf concrete component (e.g., a main entry point or a top-level composition root). It is a problem if the package is supposed to be reused (Ca = 0 means no one is using it) or contains important abstractions (which should be stable, not unstable).
Question 5: Enforcing Boundaries
Why is a boundary rule that only lives in code review unreliable, and what is the minimum enforcement level for a modular monolith?
Answer: Code reviewers do not hold the dependency graph in their head across multi-file diffs; most violations look locally fine and only become visible in aggregate. The minimum enforcement is a fitness function in CI: an automated rule (ArchUnit, Packwerk, import-linter, or language-level access control) that fails the build on violation. Without automation, boundaries erode predictably.
Question 6: Service-Based vs Microservices
State three concrete differences between service-based architecture and microservices.
Answer: (1) Granularity: service-based uses 4-12 coarse services (roughly subsystem-sized); microservices uses 10-100+ fine services (roughly bounded-context-sized). (2) Data: service-based shares a database (often with per-service schemas); microservices isolate data per service. (3) Operations: service-based is tolerable with a small platform investment and a shared deployment story; microservices require a dedicated platform team, distributed tracing, service mesh or gateway, and per-service CI/CD.
Question 7: Event-Driven Topologies
What is the fundamental difference between broker and mediator topology in event-driven architecture, and one tradeoff each makes?
Answer: Broker topology is choreographed: each service knows its own topics and subscribers; there is no central coordinator. It trades low coupling for low visibility -- workflow state is distributed across services. Mediator topology is orchestrated: a central component (Temporal, Step Functions, Camunda) sequences the workflow. It trades centralized single-point-of-failure for explicit, debuggable workflow visibility.
Question 8: The Microservices Tax
Enumerate the six taxes microservices impose, and for each, name one concrete cost.
Answer: (1) Network tax -- every in-process call becomes a networked call requiring timeouts, retries, and circuit breakers. (2) Debugging tax -- distributed tracing, centralized logs, correlation IDs are required to diagnose incidents. (3) Deploy tax -- N CI pipelines, N runbooks, N release notes; coordination for dependent changes. (4) Data tax -- no cross-service joins; materialized read models, sagas, event sourcing, or CDC needed. (5) Consistency tax -- eventual consistency across services; compensating actions and idempotency required. (6) People tax -- platform team headcount; longer onboarding; per-service ownership; cross-team negotiation for cross-cutting changes.
Question 9: Style from Characteristics -- Scenario
A team is building a real-time bidding system: 80k requests/sec, p99 latency <100ms, the dataset (ad inventory and bid state) is ~15GB and fits in memory, traffic is spikey. Which style do you recommend as the core of the system, and what alternative would you reject first?
Answer: Space-based architecture. The characteristics (very high performance, very high elasticity, scalable writes to a hot in-memory dataset) are the canonical fit for SBA. First alternative to reject: microservices -- the network tax (latency + RTT across services) alone blows the 100ms p99 budget, and the operational complexity buys nothing for a read/write-hot-path workload. A modular monolith would be rejected next (cannot scale the hot path elastically).
Question 10: Style from Characteristics -- Scenario
A 5-engineer startup is building a SaaS tool: CRUD on ~15 entities, ~100 customers, heavy emphasis on shipping features fast, unclear requirements. Which style do you recommend, and what would you reject?
Answer: Modular monolith (or even plain layered if the domain is truly simple). Characteristics are simplicity, evolutionary, testability. Reject microservices outright: the team is too small (disqualifier 1), the product is early stage (disqualifier 2), and the domain is unstable -- premature service boundaries will lock in wrong decompositions. Service-based is also premature; there is no independent-deploy pain yet.
Question 11: Style from Characteristics -- Scenario
A 10-engineer data team ingests 800GB/day from multiple customers, runs validation, enrichment, aggregation, and loads results into per-customer warehouses nightly. Which style do you recommend and why?
Answer: Pipeline (pipe-and-filter) architecture. The defining characteristic is transformation with sequential independent stages; filters (parse, validate, enrich, aggregate, load) connect through pipes (files, queues, topics). This gives composability (add an enrichment stage without touching earlier stages), stage-level observability, and easy replay of individual stages after failures.
Question 12: Distributed Fallacies
A team proposes moving from modular monolith to microservices. Name three of the eight fallacies of distributed computing and the concrete production failure each predicts if ignored.
Answer: (1) "The network is reliable" -- calls without timeouts hang and cascade back to callers; without circuit breakers, one slow service takes down the mesh. (2) "Latency is zero" -- p99 across a 6-service call chain is much larger than the sum of means because p99s compound; requests that met SLO in monolith miss SLO as microservices. (3) "Transport cost is zero" -- cloud egress and cross-AZ data-transfer fees become a monthly cost line that was invisible in the monolith (common failure: $20-40k/month surprise bills from chatty meshes).
Question 13: Distributed Monolith
What is a "distributed monolith," and what is the most reliable way to tell if you have one?
Answer: A distributed monolith is a system that looks like microservices (multiple services, multiple processes, multiple databases) but is coupled so tightly that they cannot be deployed independently. The most reliable diagnostic: pick a service and try to deploy a change to it without coordinating with any other team. If the answer is "you cannot, because service Y depends on the new field" or "you have to release service X and Y together," you have a distributed monolith -- you have paid the microservices tax without getting the benefit.
Question 14: Strangler Fig
Describe the strangler fig pattern and when to use it instead of a big-bang rewrite.
Answer: The strangler fig pattern (Fowler) extracts functionality from a legacy system one capability at a time by routing traffic for that capability to a new service via a facade or proxy, while the monolith continues to handle everything else. The legacy system shrinks in place as capabilities are extracted, until it is gone or comfortably small. Use this instead of a big-bang rewrite whenever the legacy system captures years of edge-case behavior (nearly always), or when the team cannot freeze feature work for the duration of a full rewrite (also nearly always). Big-bang rewrites fail at high rates because they must rediscover edge cases in production; strangler preserves them automatically.
Question 15: Hybrid Architectures
Explain why most mature production systems are hybrids rather than pure examples of a single style.
Answer: Different parts of a system have genuinely different quality-attribute requirements. Transactional cores need consistency and testability (layered or modular monolith); data platforms need transformation throughput (pipeline); integration layers need async fan-out (event-driven); hot paths need elasticity (extracted microservice or space-based). Forcing a single style across all of these is worse than admitting the differences: you either over-engineer the quiet parts (microservices for admin tools) or under-serve the hot parts (layered monolith for a real-time bidding system). A hybrid is an honest acknowledgment that one style does not fit all.
Interleaved Review Questions
Prior Module Question 1 (M01: Architecture Fundamentals)
What is an architectural characteristic, and what distinguishes it from a functional requirement?
Answer: An architectural characteristic (quality attribute, non-functional requirement) is a measurable property of the system as a whole -- performance, scalability, availability, security, evolvability -- that shapes structural decisions. Functional requirements describe what the system does; architectural characteristics describe how well it must do it. Styles are chosen primarily from the latter.
Prior Module Question 2 (M01: Quality Attribute Scenarios)
What is a quality attribute scenario and why is it required (rather than just naming "fast" or "scalable")?
Answer: A quality attribute scenario is a concrete, measurable description of a quality requirement: source, stimulus, environment, artifact, response, response measure. "Fast" is unmeasurable; "under 500 concurrent users, 95% of search requests return in <200ms on p99" is measurable and testable. Without measurable scenarios you cannot design for or against the attribute.
Prior Module Question 3 (S06: Distributed Systems)
State the CAP theorem in one sentence and give one example of when a system deliberately sacrifices consistency for availability.
Answer: In the presence of a network partition, a distributed system can guarantee either strong consistency or availability, but not both. Example: an e-commerce shopping cart service under partition may deliberately accept writes on both sides and reconcile later, because unavailability (user cannot add items) is worse than brief inconsistency that is resolved on next checkout.
Prior Module Question 4 (S04: Databases)
Why is it harder to perform an ACID transaction across two microservices than across two tables in the same database?
Answer: ACID transactions rely on a single coordinator (the database's transaction manager) that can lock, commit, or rollback all touched rows atomically. Across two microservices, there is no shared coordinator; distributed transactions (2PC) are expensive and fragile. The alternative is a saga: a sequence of local transactions with explicit compensating actions for failures. Sagas are eventually consistent, require idempotency and careful failure-mode design, and are one of the tax items in microservices.
Prior Module Question 5 (S05: APIs and Contracts -- forward to M04)
A microservices system exposes services to each other via REST. What is the most important property those inter-service APIs must have to preserve independent deployability?
Answer: Backward compatibility of every change to the contract. If a consumer breaks when a provider releases a "compatible" change, independent deployment has failed. This is why contract tests, schema versioning, additive-only evolution rules, and deprecation policies (all from M04) are preconditions for genuine microservices, not optional extras.
Self-Assessment and Remediation
Mastery Level (90-100% correct):
- Ready to advance to M03 (Domain-Driven Design & Bounded Contexts).
Proficient Level (75-89% correct):
- Review missed concept pages. Redo the Architecture Pattern Katas (Practice 4) with the concepts for your missed questions open.
Developing Level (60-74% correct):
- Rework the practice pages, especially the Style Selection Lab and Microservices Decomposition Clinic. Re-attempt the quiz after 48 hours.
Insufficient Level (<60% correct):
- Return to the concept pages for Clusters 4 and 5. Style selection and microservices judgment are the weight-bearing concepts of this module. Do not advance until these are stable.