OOP & design: DI / IoC · SOLID · singleton · observer · factory · repository · facade
0 / 5 completed
1 / 5
In software architecture, what is the key characteristic of a monolith?
A monolith (monolithic architecture) is a single deployable unit — all features (auth, payments, notifications, business logic) live in one codebase and are deployed together. Pros: simpler to develop initially, no network latency between components, easier to debug. Cons: as it grows — harder to scale individual parts, long build/deploy cycles, tight coupling. Compare with microservices: each business capability is a separate, independently deployable service. A common career path is "monolith first, then extract services when pain points emerge." Key vocabulary: modular monolith (well-structured monolith with clear module boundaries — a good middle ground), big ball of mud (unstructured, tangled monolith — the anti-pattern to avoid).
2 / 5
What does CQRS stand for, and what problem does it solve?
CQRS (Command Query Responsibility Segregation) is an architectural pattern that separates the way you write data (commands) from the way you read it (queries). Why useful: your read model can be highly optimized for display (denormalized, pre-joined, fast) while your write model validates business rules and ensures consistency. Example: an e-commerce order write model applies complex inventory and payment logic; the read model is a precomputed "order summary" view for fast page loads. Often paired with Event Sourcing (storing every state change as an immutable event, then replaying events to rebuild state). Key vocabulary: command (mutates state — "PlaceOrder"), query (reads state — "GetOrderById"), projection (a read-optimized view rebuilt from events), event store.
3 / 5
What is a circuit breaker in distributed systems?
The circuit breaker pattern (from Michael Nygard's Release It!) protects a system from calling a service that is likely to fail. States: Closed (normal — calls pass through), Open (too many failures detected — calls are blocked and a fallback is returned immediately), Half-Open (after a timeout, one test call is allowed to check if the service has recovered). Why critical in microservices: one slow service can exhaust all threads in caller services, causing cascading failures. Circuit breaker fails fast and returns a fallback (cached data, default value, or error message). Tools: Resilience4j (Java), Polly (.NET), Hystrix (Netflix, now mostly retired). Related: retry with backoff, bulkhead, timeout.
4 / 5
Complete with the correct architecture term: "We need to decouple the email service from the order service so that a slow email provider doesn't block order processing. Let's use an event _____ — the order service publishes an OrderPlaced event, and the email service subscribes to it asynchronously."
An event bus (or message bus) is a communication mechanism that lets services publish events and other services subscribe to them without the publisher knowing who is listening. This is the foundation of event-driven architecture. The order service publishes → the bus holds the event → email service, analytics service, inventory service each consume it independently. Key vocabulary: publisher (produces events), subscriber/consumer (reacts to events), topic (category of event), queue (storage for unprocessed messages), broker (infrastructure — Kafka, RabbitMQ, AWS SNS/SQS). Benefits: loose coupling, independent scaling, resilience. Trade-offs: harder to trace a request end-to-end, eventual consistency instead of immediate.
5 / 5
What is Dependency Injection (DI)?
Dependency Injection (DI) means that a class receives its dependencies (the objects it needs to work) from an external source — typically a DI container or a calling context — rather than instantiating them with new. Why it matters: it makes code more testable (you can inject a mock instead of a real database), more flexible (swap implementations without changing the consumer), and easier to reason about (dependencies are explicit). DI is a specific form of Inversion of Control (IoC) — the class no longer controls how its dependencies are created (control is inverted to the container/caller). Example: a UserService receives an IEmailService interface via its constructor — in production you inject a real SMTP client; in tests you inject a mock. Frameworks: Spring (Java), ASP.NET Core DI, Angular DI, NestJS.