Chapter 6
Software Architecture and Technology Decisions
Bachelors Program in Full Stack Development
Software Engineering Principles
•
Bachelor
Software Architecture and Technology Decisions
Introduction
Software architecture is the set of significant structures and decisions that shape a software system. It describes the system’s major components, their responsibilities, their interactions, deployment environment, data ownership, and the principles governing change. Architecture is not merely a collection of diagrams. It is a reasoned response to business goals, technical constraints, quality requirements, risks, and costs.
For full-stack developers, architectural understanding is essential because decisions made at the system level affect user experience, API design, database selection, testing, deployment, security, and long-term maintainability. A poorly chosen architecture can make a small feature expensive to implement; a well-chosen architecture can allow a system to evolve safely as users, data, and organizational needs grow.
Architecture is also a decision-making discipline. There is no universally best architecture. A monolithic application may be more appropriate than microservices for a small product. A synchronous request may be preferable to an event-driven workflow when immediate confirmation is required. A managed cloud service may reduce operational effort but increase vendor dependence. Sound engineering therefore requires explicit analysis of trade-offs rather than adoption of fashionable technologies.
Learning Objectives
By the end of this chapter, students should be able to:
Explain the purpose and main elements of software architecture.
Design and compare layered, client–server, service-oriented, microservices, event-driven, and cloud-native architectures.
Relate architectural decisions to performance, scalability, availability, interoperability, security, maintainability, and cost.
Use architectural viewpoints and decision records to communicate and govern design choices.
Evaluate technology alternatives using explicit criteria and evidence.
Identify risks associated with distributed systems, cloud platforms, data ownership, and vendor dependence.
1. Architecture as a Set of Decisions
A system’s architecture usually includes the following elements:
Components: deployable or logically distinguishable units such as web applications, APIs, services, databases, queues, and identity providers.
Connectors: mechanisms through which components communicate, including HTTP, remote procedure calls, message brokers, event streams, and database connections.
Interfaces: contracts describing operations, data formats, protocols, errors, authentication, and compatibility rules.
Deployment structures: the mapping of software components to processes, containers, virtual machines, regions, networks, and devices.
Data responsibilities: ownership, persistence, consistency, retention, and access patterns.
Constraints and principles: rules such as “all external traffic uses TLS,” “services own their data,” or “production changes must be reversible.”
Architecture operates at several levels. Enterprise architecture considers organizational capabilities and systems. Solution architecture concerns a particular product or business problem. Application architecture addresses the internal structure of an application. Deployment architecture describes infrastructure and runtime placement. These levels influence one another.
A useful distinction is between functional requirements and quality attributes. Functional requirements describe what the system does, such as registering a user or processing a payment. Quality attributes describe how well it does so, such as response time, availability, security, portability, and maintainability. Architectural decisions primarily determine whether quality attributes can be achieved consistently.
Quality attributes often conflict. Replicating data may improve availability and response time but introduce consistency problems. Splitting an application into many services may improve independent deployment but increase network failure modes and operational cost. Encryption improves confidentiality but can add processing overhead and complicate key management. Architecture is therefore an exercise in managed trade-offs.
2. Architectural Views and Documentation
One diagram cannot communicate every architectural concern. A practical documentation approach uses multiple complementary views:
A diagram should have a clear purpose, legend, scope, and level of abstraction. It should label protocols and trust boundaries where these affect design. For example, an arrow labelled “HTTPS/JSON” communicates more than an unlabeled arrow labelled “uses.” Documentation should be version-controlled and updated with the code or decision that it describes.
Layered cloud application architecture showing client, API, services, data and external systems
Figure: Layered cloud application architecture showing client, API, services, data and external systems
Figure: A logical layered architecture. Real systems may add caches, message brokers, security controls, and observability components across these layers.
3. Common Architectural Styles
3.1 Layered Architecture
Layered architecture organizes responsibilities into levels. A common web application has presentation, application, domain, and infrastructure or data layers. A layer normally uses the layer below it, although controlled exceptions may be justified.
The principal benefits are separation of concerns, testability, comprehensibility, and replaceability. Domain logic can be tested independently of a web framework, while infrastructure adapters can be changed without rewriting business rules. The principal risks are excessive indirection, performance overhead from unnecessary translation, and the creation of an “anemic” domain layer containing little real behavior.
A strict layered system restricts communication to adjacent layers. A relaxed layered system permits selected shortcuts. Strictness improves governance but may make simple operations cumbersome. The appropriate choice depends on the system’s complexity and the team’s ability to maintain boundaries.
3.2 Client–Server Architecture
In client–server architecture, clients request resources or operations from servers. A browser may request HTML, JavaScript, images, and API data from a server. The server commonly owns central business logic and persistent data.
This style supports centralized security, consistent data management, and thin clients. It can also create server bottlenecks, dependence on network connectivity, and a large operational concentration in the server tier. Horizontal scaling, caching, load balancing, and stateless request handling are common responses.
A stateless server does not depend on local memory from a previous request to process the next request. State may instead be kept in a database, distributed cache, or client-held token. Statelessness generally makes horizontal scaling easier, but it does not eliminate state; it changes where state is managed.
3.3 Monolithic Architecture
A monolith is a system deployed as one principal application unit. “Monolith” does not necessarily mean poorly designed. A modular monolith can contain strong internal boundaries while retaining a single deployment unit.
Monoliths usually offer simple local development, straightforward transactions, low network overhead, and relatively easy testing. Their disadvantages may include coordinated releases, limited independent scaling, and the risk that internal boundaries deteriorate over time. For a small or early-stage product, these advantages often outweigh the disadvantages.
3.4 Service-Oriented Architecture
Service-oriented architecture, or SOA, structures capabilities as services that communicate through explicit contracts. Services may be relatively coarse-grained and are often designed for reuse across multiple applications. Enterprise service buses, centralized integration, and formal governance have historically been associated with SOA, although these are not mandatory characteristics.
SOA is useful when heterogeneous enterprise systems must interoperate. Its risks include complex governance, central integration bottlenecks, and overly general services that satisfy no consumer particularly well.
3.5 Microservices Architecture
Microservices divide an application into small, independently deployable services, usually organized around business capabilities. Each service should have a clear responsibility, an explicit interface, and a team capable of owning it through development, testing, deployment, and operation.
Potential benefits include independent deployment, selective scaling, fault isolation, and alignment between team boundaries and business capabilities. Costs include distributed debugging, network latency, duplicated infrastructure, data consistency challenges, more complex testing, and a substantial need for automation and observability.
Microservices are not simply “many small programs.” A credible microservice architecture requires service ownership, automated delivery, health monitoring, secure communication, compatibility management, and an approach to distributed data. If these capabilities are absent, a modular monolith may produce better outcomes.
3.6 Event-Driven Architecture
An event is a record that something happened, such as OrderPlaced or PaymentAuthorized. In an event-driven architecture, producers publish events and consumers react to them, often through a broker or event stream. Producers need not know all consumers, which reduces direct coupling.
Event-driven systems support asynchronous processing, integration, workload smoothing, and independent consumer evolution. They introduce eventual consistency, duplicate delivery, ordering concerns, schema evolution, replay management, and more difficult user-facing error handling.
Important patterns include:
Publish–subscribe: multiple consumers receive an event.
Queue-based work distribution: one consumer in a group processes each task.
Event notification: an event signals that data changed; consumers retrieve details.
Event-carried state transfer: the event contains the information needed by consumers.
Transactional outbox: a service writes a business change and an outgoing event to the same local transaction, after which a publisher delivers the event.
Idempotent consumer: repeated delivery produces the same intended business result as one delivery.
Exactly-once processing is difficult to guarantee across independent systems. A robust design usually assumes at-least-once delivery and makes consumers idempotent. If an event identifier has already been processed, the consumer can record that fact and avoid repeating the business effect.
3.7 Cloud-Native Architecture
Cloud-native architecture uses capabilities such as elastic infrastructure, managed services, containers, automated delivery, declarative configuration, observability, and failure-aware design. Cloud-native does not mean merely “hosted in the cloud.” It means that the system is designed to exploit cloud operating characteristics while controlling their risks.
Common principles include stateless compute where practical, immutable deployment artifacts, infrastructure as code, automated scaling, centralized logs and metrics, health checks, isolated environments, and explicit resilience mechanisms. Cloud-native systems may use serverless functions, containers, managed databases, queues, and regional deployment, but these are implementation options rather than definitions.
Cloud services can reduce capital expenditure and administrative work, but costs may become variable and difficult to predict. Data transfer charges, managed-service pricing, idle resources, observability volume, and duplicated environments must be included in economic analysis.
4. Quality Attributes and Trade-Off Analysis
Performance and Scalability
Performance concerns the time and resources required to complete work. Scalability concerns how capacity changes as demand changes. A system may be fast for one user yet scale poorly under concurrent load.
For a capacity estimate, a simple utilization relationship is:
ρ = λ / μ
Here, ρ is utilization, λ is the arrival rate in requests per second, and μ is the service rate in requests per second for one server or processing unit. The relationship assumes a simplified steady-state model and is not a complete queueing analysis. As utilization approaches 1, waiting time can increase sharply, so operating at 100% theoretical capacity is unsafe.
A practical capacity plan includes peak demand, concurrency, request cost, database limits, network bandwidth, and failure conditions. Caching can reduce repeated computation and database load, but introduces invalidation and staleness problems. Asynchronous queues can absorb bursts, but they may increase completion time and complicate status reporting.
Availability and Reliability
Availability is the proportion of time a service is usable according to an agreed definition. For a period of observation:
A = MTBF / (MTBF + MTTR)
A is availability, MTBF is mean time between failures, and MTTR is mean time to repair or restore. The formula assumes a repairable system and a stable operational regime. It does not capture all forms of partial failure or planned maintenance unless those are included in the measurement definition.
If two components are arranged sequentially so that both must work, and failures are independent, system availability is approximately:
Asystem = A1 × A2
If either of two independent redundant components can serve the request, availability is approximately:
Asystem = 1 − (1 − A1)(1 − A2)
These equations are simplified. Shared networks, common databases, correlated failures, configuration errors, and human actions can invalidate the independence assumption. Redundancy without removal of common failure points may provide little real benefit.
Reliability engineering also uses time objectives. Recovery time objective (RTO) is the maximum acceptable time to restore service. Recovery point objective (RPO) is the maximum acceptable age of recoverable data after a disruption. Backups, replication, failover, and disaster recovery tests should be designed from these objectives rather than from technology preference.
Consistency and Interoperability
Consistency describes what users observe about data across replicas or services. Strong consistency makes recent writes visible according to a strict ordering model, but may reduce availability or increase latency during network partitions. Eventual consistency allows replicas to converge later and can improve responsiveness and availability, but requires conflict handling and user-interface designs that tolerate temporary differences.
Interoperability depends on stable contracts. Good interfaces define data types, error semantics, authentication, versioning, limits, and compatibility expectations. JSON over HTTPS is common for public APIs, while binary protocols or messaging systems may be more efficient for internal communication. The correct choice depends on consumers, performance, governance, and operational capabilities.
Maintainability and Changeability
Maintainability is influenced by cohesion, coupling, clarity, automated tests, documentation, deployment safety, and observability. A component with high cohesion performs closely related responsibilities. Low coupling minimizes the number and strength of dependencies between components.
Architecture should make likely changes localized. If pricing rules change frequently, pricing policy should not be scattered through controllers, database triggers, and user-interface code. If a technology is likely to be replaced, an adapter boundary can prevent it from becoming embedded throughout the domain model.
Security and Privacy
Security is an architectural property as well as an implementation task. Designs should identify assets, trust boundaries, identities, privileges, threats, and failure consequences. Least privilege, defense in depth, secure defaults, encryption in transit and at rest, secret rotation, audit logging, and dependency management should be considered early.
Privacy requires data minimization, purpose limitation, retention controls, access transparency, and appropriate handling of deletion or correction requests. Regulations differ by jurisdiction, but architecture should support accountability and lawful data handling. Sensitive data should not be copied into logs, events, analytics systems, or development environments without a justified control process.
Cost
Total cost includes development, infrastructure, licenses, support, operations, training, migration, security, and the cost of failures. A rough monthly infrastructure estimate can be expressed as:
Each term represents the monthly cost of the indicated category. This is a planning identity, not a pricing law; real providers may apply tiers, reservations, taxes, discounts, and minimum charges. Cost estimates should state assumptions such as requests per month, storage volume, retention period, environments, and data egress.
5. A Method for Technology Decisions
Technology selection should begin with the problem rather than a preferred tool. A disciplined process is:
Clarify the business capability and constraints. Identify users, workflows, regulatory requirements, deadlines, existing systems, and team expertise.
State quality-attribute scenarios. For example: “During the seasonal peak, 95% of product searches should complete within 300 ms at 2,000 requests per second.” A scenario should identify stimulus, environment, response, and measurable target.
Identify architectural forces. List performance, availability, interoperability, security, cost, portability, and likely change.
Generate plausible alternatives. Include a modular monolith, managed platform, event-driven design, or service decomposition where appropriate.
Eliminate infeasible options. Reject alternatives that violate mandatory constraints.
Evaluate trade-offs with evidence. Use prototypes, load tests, failure tests, cost models, vendor documentation, and team capability assessments.
Record the decision. State the context, decision, alternatives, consequences, assumptions, and review conditions.
Validate after deployment. Compare actual metrics with the original scenarios and revise when evidence changes.
A lightweight weighted model can help structure discussion. Let si be the score of option i for criterion j, and wj be the weight of criterion j, where weights sum to 1. A simple score is:
Si = ∑(wj × sij)
The score is useful for transparency, not for pretending that architectural value is perfectly numerical. Scores should be accompanied by assumptions and sensitivity analysis. If a small change in weights reverses the ranking, the decision is sensitive and deserves further investigation.
6. Architecture Decision Records
An Architecture Decision Record (ADR) preserves the reasoning behind an important choice. A practical ADR contains:
Title and status: proposed, accepted, superseded, or rejected.
Context: the problem, constraints, and quality goals.
Decision: the selected approach, stated clearly.
Alternatives considered: including reasons for rejection.
Consequences: benefits, costs, risks, and operational implications.
Assumptions and evidence: tests, measurements, or external constraints.
Review trigger: conditions under which the decision should be revisited.
For example, an ADR might choose a modular monolith for an initial commerce platform because the team is small, transaction boundaries are closely related, and deployment simplicity is valuable. It may explicitly state that extraction into a service will be reconsidered when independent scaling or team ownership becomes a demonstrated need. This is more valuable than a vague statement that the system will “become microservices later.”
7. Applied Case: University Course Registration Platform
The following is an illustrative case.
Background
A university plans a course registration platform used by students, faculty, finance staff, and external identity services. Registration demand is highly concentrated during a short enrollment period. The platform must protect student records, prevent over-enrollment, integrate with payment and learning systems, and remain usable when demand is high.
Problem
A first proposal places all functionality in a single web application with direct synchronous calls to payment, notification, and learning systems. During the previous enrollment period, slow external services caused request timeouts, duplicate registration attempts, and inconsistent notification status.
Analysis
The principal quality scenarios are:
Course searches should remain responsive during peak demand.
A course seat must not be allocated twice.
Payment confirmation must be auditable.
A temporary notification failure must not cancel a valid registration.
The system must meet institutional privacy and retention requirements.
Operations staff need traceable failures and recoverable workflows.
A complete microservices migration would create substantial operational work. A modular monolith with explicit modules for catalog, registration, payment coordination, and notification is therefore selected initially. A relational database provides transactional seat allocation. A queue and transactional outbox publish registration events after the local transaction succeeds. Notification workers consume events and retry safely. Search uses a read-optimized index that can be rebuilt from authoritative catalog data.
Approach and Solution
The request path validates the student, checks prerequisites, and performs seat allocation in one database transaction. The transaction records a registration and an outgoing event in an outbox table. A publisher later sends the event to the messaging system. If the publisher retries, the event identifier remains stable, allowing consumers to deduplicate.
Payment is modeled as a stateful workflow rather than an assumption that one synchronous call always succeeds. The platform records states such as Pending, Authorized, Failed, and Reconciled. A scheduled reconciliation process compares local records with the payment provider. Notification is asynchronous because it is important but not part of the seat-allocation transaction.
The deployment uses multiple application instances behind a load balancer, centralized logs, metrics for registration latency and queue age, alerts for payment reconciliation failures, encrypted backups, and tested recovery procedures. The architecture remains a modular monolith, but its interfaces and event boundaries preserve future extraction options.
Outcome
The design reduces the amount of synchronous work during registration, isolates notification failures, and provides an auditable payment process. It does not eliminate complexity: queue monitoring, duplicate events, reconciliation, and peak-load testing are now required. The solution is appropriate because it addresses the actual bottlenecks without introducing the full cost of many independently deployed services.
Learning Points
A modular monolith can provide strong boundaries without distributed-system overhead.
Transactions should protect tightly coupled invariants such as seat allocation.
Asynchronous processing is valuable when work can complete later.
External systems require explicit state machines, retries, timeouts, and reconciliation.
Architecture should evolve from measured constraints rather than anticipated fashion.
8. Challenges, Governance, and Contemporary Practice
Distributed-System Failure
Networks fail, messages are delayed, clocks differ, services restart, and dependencies return partial responses. Timeouts prevent indefinite waiting, but they do not prove that an operation failed; the remote system may have completed it. Retries can amplify load unless bounded by backoff and jitter. Circuit breakers can stop repeated calls to an unhealthy dependency, while bulkheads limit the impact of one workload on another.
Observability
Observability combines logs, metrics, traces, and contextual information to support diagnosis. Correlation identifiers should follow a request across services and asynchronous messages. Metrics should represent user and business outcomes as well as infrastructure, such as successful registrations, payment reconciliation age, and queue delay.
Deployment and Evolution
Continuous delivery requires automated tests, security checks, repeatable builds, environment configuration, and rollback or forward-fix strategies. Backward-compatible API and event changes are essential when producers and consumers are deployed independently. Database migration should support transitional states; changing an application and database schema in one irreversible step creates avoidable deployment risk.
AI-Assisted Development
AI coding assistants can generate adapters, tests, documentation, and infrastructure templates. They can also introduce insecure dependencies, incorrect error handling, licensing concerns, or fabricated claims about APIs. Human review, automated testing, secret protection, dependency scanning, and clear ownership remain necessary. AI may accelerate implementation, but it does not replace architectural accountability or evidence-based decision-making.
Governance and Ethics
Architecture governance should be enabling rather than bureaucratic. Teams need shared principles for identity, logging, data classification, API compatibility, accessibility, incident response, and dependency risk. Governance must also address concentration risk in cloud providers, resilience of critical public services, accessibility for users with disabilities, algorithmic discrimination where automated decisions are involved, and the environmental cost of unnecessary computation and storage.
Best Practices
Begin with business capabilities and measurable quality scenarios.
Prefer the simplest architecture that satisfies current, demonstrated needs.
Preserve modular boundaries even in a monolith.
Keep data ownership explicit and avoid uncontrolled shared databases.
Treat external calls as fallible; use timeouts, bounded retries, and reconciliation.
Design asynchronous consumers for duplicate delivery.
Automate testing, deployment, security checks, and infrastructure configuration.
Measure actual performance, availability, and cost rather than relying on claims.
Document significant decisions and their consequences in ADRs.
Build observability and recovery testing into the architecture.
Review decisions when assumptions, scale, regulation, or organizational structure changes.
Chapter Summary
Software architecture is a set of significant structures, interfaces, deployment arrangements, and decisions that determine how a system satisfies functional and quality requirements. Layered and client–server styles provide clear foundations for many full-stack systems. Monoliths can be simple and effective, while SOA and microservices support integration or independent ownership when their additional operational costs are justified. Event-driven architecture enables asynchronous processing and loose coupling but requires careful treatment of delivery, ordering, duplication, consistency, and schema evolution. Cloud-native architecture combines automation, elastic infrastructure, managed services, observability, and failure-aware design; it is not synonymous with merely hosting software in a cloud.
Architectural evaluation must consider performance, scalability, availability, reliability, interoperability, maintainability, security, privacy, and total cost. Quantitative models can support reasoning, but their assumptions must be made explicit. Architecture decision records preserve context and consequences, while quality-attribute scenarios, prototypes, load tests, cost estimates, and operational evidence improve decision quality. The central professional principle is to choose the simplest design that meets validated needs and to evolve it deliberately as evidence changes.
Key Terms
Architecture: The significant structures, relationships, constraints, and decisions shaping a software system.
Quality attribute: A measurable or assessable property such as performance, availability, security, or maintainability.
Layered architecture: An arrangement that separates responsibilities into levels with controlled dependencies.
Client–server architecture: A style in which clients request resources or operations from servers.
Monolith: An application deployed as one principal unit.
Modular monolith: A monolith with explicit internal modules and boundaries.
Service-oriented architecture: An architecture that organizes capabilities as contract-based services, often for enterprise integration.
Microservices: Independently deployable services organized around business capabilities.
Event: A record that a significant occurrence has happened.
Event-driven architecture: An architecture in which components communicate by publishing and consuming events.
Cloud-native: Designed to exploit cloud elasticity, automation, managed services, and distributed operation.
Scalability: The ability to handle increased demand by adding or adjusting resources.
Availability: The proportion of time a service is usable according to a defined measure.
MTTR: Mean time to repair or restore service.
RTO: Recovery time objective; the maximum acceptable restoration time.
RPO: Recovery point objective; the maximum acceptable age of recoverable data.
Idempotence: The property that repeating an operation produces the same intended business effect as performing it once.
Observability: The ability to understand internal system behavior from outputs such as logs, metrics, and traces.
Architecture Decision Record: A concise record of an architectural context, decision, alternatives, and consequences.
Technical debt: The future cost created by expedient or inadequate technical choices.
Review Questions
Short Answer Questions
What is the difference between a functional requirement and a quality attribute?
Why can a modular monolith be preferable to microservices for a small team?
What problem does the transactional outbox pattern address?
Define RTO and RPO.
Why must architecture diagrams identify their scope and purpose?
Long Answer Questions
Compare layered, client–server, and microservices architectures in terms of coupling, deployment, scalability, and operational complexity.
Explain the benefits and risks of event-driven architecture, including duplicate delivery and eventual consistency.
Describe a systematic process for selecting a technology or architectural style.
Explain how performance, availability, security, and cost can conflict in architectural decisions.
Discuss the contents and professional value of an Architecture Decision Record.
Analytical / Application Questions
A small team is building an appointment system with one relational database, a modest user base, and strict booking invariants. Recommend an initial architecture and justify it using quality attributes and operational constraints.
An online retailer experiences traffic spikes and delayed email notifications, but inventory must remain accurate. Design a hybrid synchronous and event-driven solution, identifying transactions, events, retries, and failure handling.
Two cloud designs have similar functional features: Design A uses one managed application and database; Design B uses eight services, multiple queues, and independent databases. Construct an evaluation using performance, availability, interoperability, team capability, and total cost. State what evidence would change your recommendation.
Multiple Choice Questions with Answers
Question 1
Which statement best describes a quality attribute?
A. A business operation such as creating an account
B. A property such as availability or maintainability
C. A database table containing user records
D. A programming language used to implement a service
Correct Answer: B. A property such as availability or maintainability
Question 2
What is a major benefit of a modular monolith?
A. It removes the need for automated testing
B. It guarantees unlimited horizontal scalability
C. It provides internal boundaries without requiring distributed deployment
D. It ensures every component has a separate database
Correct Answer: C. It provides internal boundaries without requiring distributed deployment
Question 3
Why are idempotent consumers valuable in event-driven systems?
A. They prevent all network failures
B. They allow repeated delivery to produce one intended business effect
C. They guarantee globally ordered events
D. They eliminate the need for event schemas
Correct Answer: B. They allow repeated delivery to produce one intended business effect
Question 4
Which objective specifies the maximum acceptable time to restore service?
A. RPO
B. MTBF
C. RTO
D. SLA latency
Correct Answer: C. RTO
Question 5
In the simplified availability formula A = MTBF ÷ (MTBF + MTTR), what does MTTR represent?
A. Mean time to replicate
B. Mean time to repair or restore
C. Maximum throughput transfer rate
D. Measured transaction response
Correct Answer: B. Mean time to repair or restore
Question 6
Which situation most strongly supports asynchronous event processing?
A. A response must contain an immediate authorization result
B. A tightly coupled invariant must be checked in one transaction
C. An email can be delivered after registration without blocking registration
D. A caller cannot tolerate eventual consistency
Correct Answer: C. An email can be delivered after registration without blocking registration
Question 7
What is the primary purpose of an Architecture Decision Record?
A. To replace all source-code documentation
B. To record the context, choice, alternatives, and consequences of a significant decision
C. To measure CPU utilization automatically
D. To define a programming language grammar
Correct Answer: B. To record the context, choice, alternatives, and consequences of a significant decision
Question 8
Which is a common risk of microservices?
A. They make network communication unnecessary
B. They prevent independent deployment
C. They introduce distributed debugging and data-consistency challenges
D. They require every application to use a single shared database
Correct Answer: C. They introduce distributed debugging and data-consistency challenges
Question 9
If two independent redundant components each have availability 0.9 and either can serve the request, what is the approximate system availability?
A. 0.09
B. 0.81
C. 0.90
D. 0.99
Correct Answer: D. 0.99
Question 10
Which practice best supports interoperability?
A. Relying on undocumented internal object formats
B. Defining explicit interface contracts, errors, authentication, and versioning
C. Allowing every consumer to modify another service’s database
D. Avoiding all compatibility testing
Correct Answer: B. Defining explicit interface contracts, errors, authentication, and versioning