skip to content

Software design & architecture

26 roadmaps2,129 questionsupdated

Everything about giving software a deliberate shape lives here, from naming a single function well to deciding whether a system is one deployable or fifty. Interviews lean on this area because it is where they find out whether you can justify a structure rather than just copy one.

on this pageshow

guide

overview

~2 min

Software design and architecture is where an interview stops asking whether your code works and starts asking whether its shape can be defended. Most questions here have no single right answer, so the interviewer listens to the reasoning instead: which forces you named, which option you rejected and why, what the structure will cost to change later, and which decisions you deliberately left open. Reciting a pattern's definition earns less than saying when that pattern would be the wrong choice, and at senior levels the conversation is mostly about trade-offs. The subject runs from the scale of a single function to the scale of an organization's whole estate. At the small end sit [design principles](/topics/found-design-principles), [clean code and refactoring](/topics/found-clean-code) and [design patterns](/topics/found-design-patterns): the vocabulary for judging whether a class or module will stay changeable. In the middle are [software architecture](/topics/found-software-architecture) as a discipline (making, recording and evaluating decisions that are expensive to reverse), the catalogue of [architectural styles](/topics/found-architectural-styles), [domain-driven design](/topics/found-ddd) for drawing boundaries around the business, and [codebase and dependency organization](/topics/found-codebase-organization) for how all of it is laid out and versioned. Once a system spans machines, [distributed and scalable systems](/topics/found-distributed-systems) supplies the theory, and three applied sections build on it: [microservices](/topics/found-microservices), [event-driven architecture and messaging](/topics/found-eda), and [resilience and cloud-native patterns](/topics/found-cloud-design-patterns). At the top, [enterprise and solution architecture](/topics/found-enterprise-architecture) covers work above a single system: turning requirements into a governed solution and aligning many systems with a business strategy. Start with the principles, because every later section argues in their terms: coupling, cohesion, dependency direction. Patterns and clean code come next, then architecture fundamentals and styles, and only then the distributed sections, which assume you already know what a boundary costs while it is still an in-process call. Questions range from a junior defining a term to a principal defending a decomposition against a quality attribute and planning how it will evolve. The distributed-systems section is the largest and the one senior rounds lean on hardest, so expect to return to it as your level rises.

primer

### Design is about the cost of change Code that works today is the easy part; the question every design review asks is what the next change will cost. Coupling measures how far a change ripples, and cohesion measures whether related things sit together so a change lands in one place. SOLID, GRASP, DRY and the package principles are heuristics for the same goal, each aimed at a different kind of ripple. When an interviewer asks why a design feels wrong, the strongest answer names the change that would hurt and traces where it would spread. ### Dependencies point somewhere, and that is a choice Every dependency exposes one part to another's changes, so the direction matters as much as the count. The recurring rule is that volatile details (storage, frameworks, transport, other teams' services) should depend on stable policy, not the reverse. Layering, dependency inversion, ports and adapters, and the clean and hexagonal architectures restate that rule at different scales. Cycles are the failure case: two parts that depend on each other become hard to understand, test or release separately. ### Boundaries are the unit of architecture A boundary (a module, a package, a bounded context, a service) decides what can change independently of what. The kind of boundary decides what crossing it costs: an in-process call is cheap and can share a transaction; a network call adds latency, partial failure and a separate lifecycle; a message adds time between cause and effect. Many architecture questions reduce to two sub-questions: where should this line sit, and what kind of line should it be. [Domain-driven design](/topics/found-ddd) answers the first from the business side; the styles and distributed sections answer the second. ### Architecture is judged against quality attributes Architecture is the subset of decisions that are expensive to reverse, and a decision is only good relative to what the system must achieve: latency, availability, scalability, modifiability, security, cost. A strong answer names the attribute that dominates, states it as a measurable scenario rather than an adjective, and shows which alternative it rules out. Writing the decision down, with its context and the rejected options, is part of the discipline; it is how the next engineer tells a deliberate trade-off from an accident. ### A named pattern or style is compressed trade-offs Pattern and style names (Decorator, Repository, layered, event-driven, microservices, circuit breaker) let two engineers describe a design in a word. The word is only useful if you know the forces behind it: the problem it solves, what it costs, and how it degrades when applied where that problem is absent. Interviewers probe the edge of a pattern more than its definition, typically by asking when you would not use it or what it looks like overused. ### Crossing the network changes the rules Inside one process, a call either returns or throws, and a single transaction can cover the work. Across machines, a request can succeed while its response is lost, clocks disagree, and a component can be slow rather than down, which the caller cannot easily tell apart. Much of the distributed and service-level material follows from that: retries force idempotency, replication forces a choice of consistency model, slow dependencies force timeouts and circuit breakers, and the lack of a shared transaction forces sagas and compensation. Designs built on single-process intuition tend to work only while nothing fails. ### Consistency is decided per boundary Strong consistency is comparatively cheap inside one aggregate or one database and expensive across services. Designs therefore choose where the transactional boundary sits and accept eventual consistency outside it, with explicit handling for the window in which views disagree. Being able to say which data must be correct immediately, which can lag, and what a user sees during the lag is what separates a structured answer from a hopeful one.

Coupling
The degree to which one part must know about, or change along with, another. Lower coupling lets parts be changed, tested and released with less ripple.
Cohesion
How strongly the responsibilities inside one module relate to each other. A cohesive module changes for one kind of reason and is easy to name.
Dependency inversion
Having high-level policy and low-level detail both depend on an abstraction owned by the policy side, so the detail can be replaced without touching the policy.
Encapsulation
Hiding a component's internal state behind operations that enforce its rules, so outside code cannot put it into an invalid state.
Code smell
A surface symptom suggesting a structural problem, such as duplication or an overlong method; a prompt to look closer, not proof of a defect.
Refactoring
Restructuring code in small steps that leave its observable behavior unchanged, normally protected by tests run after each step.
Technical debt
The future cost of a design or code shortcut: extra effort on every change until it is paid down, plus the work of paying it down.
Quality attribute
A measurable property a system must exhibit beyond its features, such as availability, latency, scalability or modifiability; the yardstick architectural decisions are judged by.
Architecture decision record
A short document capturing one significant decision: its context, the options considered, the choice and its consequences, kept alongside the system it shaped.
Architectural style
A named macro-structure for a whole system, such as layered, pipes and filters, event-driven or microservices, with a known set of strengths and costs.
Modular monolith
A single deployable unit whose internals are split into modules with enforced boundaries; the usual alternative to services when independent deployment is not yet needed.
Bounded context
The explicit boundary within which one domain model and its vocabulary keep a single consistent meaning; the main tool for splitting a large domain.
Aggregate
A cluster of domain objects treated as one unit for changes, with a single root that guards its invariants and marks the transaction boundary.
Partial failure
A condition in a distributed system where some components or messages fail while others succeed, leaving the caller unsure what actually happened.
Idempotency
The property that performing an operation more than once has the same effect as performing it once, which makes retries safe.
Eventual consistency
A guarantee that replicas or services converge to the same state once updates stop, while allowing them to disagree in the meantime.
At-least-once delivery
A messaging guarantee that no message is lost but some may arrive more than once, so consumers must tolerate duplicates.
Saga
A long-running business transaction split into local steps across services, each paired with a compensating action that undoes it if a later step fails.
Circuit breaker
A guard around calls to a dependency that stops sending requests after repeated failures, fails fast for a period, then probes whether the dependency has recovered.
Semantic versioning
A major.minor.patch numbering scheme in which each part signals whether a release breaks, extends or only fixes the public contract.
Conway's law
The observation that a system's structure tends to mirror the communication structure of the organization that builds it.

The sections form a ladder of scale, and the same three questions come back on every rung: where does the boundary sit, which way do dependencies point, and what does crossing the boundary cost. ### Inside one codebase [Design principles](/topics/found-design-principles) are the judging criteria. [Clean code](/topics/found-clean-code) applies them at the level of names, functions and error handling, and its smell catalogue is largely a list of principle violations, each paired with a refactoring. [Design patterns](/topics/found-design-patterns) are the recurring object designs those principles produce, so a pattern question is often a principle question in disguise. The [package and component principles](/topics/found-design-principles-package) lift cohesion and coupling from classes to modules, which is where [project structure](/topics/found-project-structure) and the tactical half of domain-driven design take over: how the domain layer is shaped, and how the [enterprise application patterns](/topics/found-enterprise-patterns) connect it to storage and presentation. ### From one system's shape to many systems [Software architecture](/topics/found-software-architecture) supplies the method: identify quality attributes, make and record decisions, evaluate them, evolve them. [Architectural styles](/topics/found-architectural-styles) are the catalogue of answers that method chooses among, and the pivotal choice between a modular monolith and services depends on boundaries that [strategic design](/topics/found-ddd-strategic-design) draws from the business. Once those boundaries become network boundaries, [distributed systems](/topics/found-distributed-systems) theory applies. [Microservices](/topics/found-microservices) inherits its problems of data ownership and coordination, [event-driven architecture](/topics/found-eda) offers asynchronous integration as one answer to them, and the [resilience and cloud-native patterns](/topics/found-cloud-design-patterns) are named responses to its failure modes. ### Around the edges [Solution architecture](/topics/found-solution-architecture) turns a project's requirements, especially the non-functional ones, into those choices, and [enterprise architecture](/topics/found-enterprise-architecture-ea) governs them across a whole portfolio. [Codebase organization](/topics/found-codebase-organization) is where architecture meets daily work: repository layout tends to mirror the system's boundaries, and dependency versioning is coupling stretched across release cycles, with semantic versioning as the contract that keeps it manageable.

  1. Core Design Principles →

    Coupling, cohesion, encapsulation and DRY are the terms every later section argues in; learn to apply them before anything built on them.

  2. SOLID Principles →

    The principles interviewers cite most often, and the bridge from class design to dependency direction at architectural scale.

  3. Design Patterns →

    Principles resolved into recurring designs; knowing each pattern's intent and misuse gives you shorthand for every later design discussion.

  4. Architecture Fundamentals →

    What makes a decision architectural and how quality attributes judge it: the method every style and system design answer relies on.

  5. Architectural Styles →

    The catalogue of whole-system shapes and their costs, including the monolith-versus-services choice that frames the later sections.

  6. Core Distributed Theory →

    Partial failure, replication, consistency and time: the theory that microservices, messaging and resilience patterns all assume you already have.

  • Answering "it depends" and stopping there; name what it depends on and which way each plausible value would tip the decision.

  • Proposing microservices by default for a small team or an unclear domain, taking on network, data and operations costs with no independent-deployment need to justify them.

  • Adding a pattern because its name fits rather than because its problem is present; an interface or factory with one implementation adds indirection and no flexibility.

  • Merging code because it looks alike rather than because it encodes the same rule; code that changes for different reasons becomes coupled once merged.

  • Calling a class encapsulated because its fields are private while each one has a public setter; its invariants are still unprotected.

  • Claiming exactly-once processing end to end without saying how duplicates are made harmless; expect the follow-up about what happens on a retry.

  • Splitting a system into services that still share one database, which keeps the coupling and adds the network on top.

  • Drawing only the happy path; a design answer should say what happens when a dependency is slow, down, or returns a partial result.

  • Designing for scale with no numbers: no estimate of request rate, data size or availability target to show why each component is needed.

  • Mixing a refactoring with a behavior change in one step, so a failing test no longer tells you which of the two broke things.

  • Presenting a decision without the rejected alternatives or the conditions under which you would revisit it; senior rounds weigh the reasoning over the choice.

Most questions in this hub come down to a handful of recurring choices. Naming the one you are making, and the condition that would flip it, is often most of the answer. - **Flexibility now versus simplicity now.** An abstraction added before a second use case exists costs indirection today for a change that may never come. Adding it later, when the variation is real, is usually cheaper than guessing its shape early. - **In-process versus across the network.** A module boundary is cheap to cross and easy to move; a service boundary buys independent deployment and scaling at the price of latency, partial failure and a harder consistency story. - **Consistency versus availability and latency.** Keeping every view in step needs coordination, and coordination costs time and stalls when parts cannot reach each other. What decides it is which data the business needs correct immediately and which can lag. - **Synchronous versus asynchronous integration.** A direct call is simple to reason about but ties the caller's availability to the callee's. A message decouples them in time at the cost of harder debugging, ordering questions and duplicate handling. - **Reuse versus independence.** A shared library or shared schema removes duplication but couples every consumer's release to it. Across service boundaries, some duplication is often the cheaper option. - **Central control versus local autonomy.** Orchestration, platform standards and enterprise governance make the whole easier to see and steer; choreography and team autonomy make each part quicker to change on its own. - **Reproducibility versus upkeep.** Every install should resolve to the same versions, yet dependencies still have to move forward for fixes. Recording the exact resolved versions handles the first; how the manifest states its ranges decides how much manual work the second takes.

The same few moves recur at every scale of this hub under different names. Spotting the shared shape is how you place an unfamiliar question. - **Put a translator at the boundary.** Adapter, anti-corruption layer, ports and adapters, and an API gateway all stop one side's model or protocol from leaking into the other. - **Depend on an abstraction the stable side owns.** Dependency inversion in a class, the dependency rule in layered and hexagonal designs, and published contracts between services are the same move at three sizes. - **Separate reads from writes.** Query-shaped read models, read replicas, materialized views and cache-aside each let the read path take a different form from the write path, and each accepts some staleness to do it. - **Make repetition harmless.** Idempotency keys, deduplication on the consumer and the transactional outbox let at-least-once delivery and client retries coexist with correct results. - **Contain failure and fail fast.** Timeouts, circuit breakers, bulkheads and backpressure stop one slow dependency from exhausting the caller's resources. - **Record what happened, not only where things stand.** Event sourcing, append-only logs and audit trails keep the history from which current state and new views can be rebuilt. - **Coordinate centrally or let each part respond on its own.** Orchestration and choreography appear in sagas, in workflow design and, in miniature, in the observer pattern; the choice trades visibility for independence. - **Change in place, gradually.** Strangler-fig migration, branch by abstraction and incremental refactoring replace a part behind a stable interface instead of stopping everything for a rewrite.

explore

→ has its own guide

report an issue with this guide →

questions

2,129 · 12 sections

In software design, what do the terms "cohesion" and "coupling" mean, and what is the standard rule of thumb about them?

level: juniorimportance: must knowfreq 88%
basics
~10 s

Cohesion is how strongly the things inside one module belong together. Coupling is how much one module depends on another. The rule: aim for high cohesion inside modules and low coupling between them.

open as a page

What does the design guideline "favor composition over inheritance" actually mean, and what is the difference between the two techniques?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Inheritance reuses code by making a new type a subtype of an existing one ("is-a"). Composition reuses code by holding another object as a field and calling it ("has-a"). Prefer composition: it couples types less and can change at runtime.

open as a page

In software design, what is the difference between abstraction and indirection, and why is it said that every abstraction introduces indirection but not every indirection is an abstraction?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Abstraction hides detail behind a simpler idea you can reason about, like 'send a payment'. Indirection just means going through something in between instead of calling the thing directly. Abstractions use indirection, but a pass-through wrapper that hides nothing is only indirection.

open as a page

What is Command-Query Separation (CQS), and how do you classify a method as a command or a query?

level: juniorimportance: must knowfreq 58%
basics
~10 s

CQS says every method should either change state (a command, returning nothing) or return information (a query, changing nothing) — never both. Put differently: asking a question must not change the answer.

open as a page

What does the "fail fast" design principle mean, and why is stopping at the moment invalid state is detected usually better than letting execution continue?

level: juniorimportance: must knowfreq 65%
basics
~20 s

Fail fast means checking for invalid input or state right where it appears and stopping immediately with a clear error, instead of continuing with bad data that causes a confusing failure much later somewhere else.

open as a page

In Robert Martin's Clean Code terminology, what is the difference between an "object" and a "data structure"?

level: juniorimportance: must knowfreq 62%
basics
~20 s

An object hides its data and exposes behaviour - you tell it to do something. A data structure exposes its data and has almost no behaviour - other code reads its fields and does the work.

open as a page

In software engineering, what is the "Boy Scout Rule" (also called the campsite rule), and what does following it look like in an ordinary day-to-day code change?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Always leave code a little better than you found it. Whenever you touch a file, make one small safe improvement — a clearer name, a deleted unused line, an extracted helper — so quality slowly rises instead of decaying.

open as a page

What is the difference between cyclomatic complexity and cognitive complexity as code metrics, and why was cognitive complexity introduced?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Cyclomatic complexity counts the independent execution paths through code, which estimates how many tests you need. Cognitive complexity estimates how hard code is for a human to read: it penalises nesting and ignores structures people find easy.

open as a page

How do guard clauses and early returns reduce the cognitive load of a function, and when is the 'single exit point' rule still justified?

level: juniorimportance: must knowfreq 68%
basics
~20 s

A guard clause handles an invalid or special case immediately and returns, instead of wrapping the real work in an if. That flattens nesting, so the reader stops carrying conditions in their head and the main path stays at the left margin.

open as a page

In code review, why is a comment that explains WHY the code does something usually more valuable than a comment that restates WHAT the code does?

level: juniorimportance: must knowfreq 72%
basics
~20 s

The code already shows what it does; a reader can see that. It cannot show the reason, constraint, or bug that forced this approach. "Why" comments add information; "what" comments repeat it and can go stale.

open as a page

What problem does the Abstract Factory design pattern solve, and what does it mean that it creates a "family" of objects?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Abstract Factory gives you one interface with several creation methods that together produce a set of related objects. Client code asks the interface for parts and never names concrete classes, so swapping one factory swaps the whole matching set.

open as a page

What problem does the Adapter design pattern (Gang of Four, structural category) solve, and what are its participants?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Adapter converts one type's interface into the interface a caller already expects, so two otherwise incompatible pieces of code can work together. The adapter wraps the existing type and translates each call, without changing either side.

open as a page

What is the "god object" anti-pattern in software design, and why is it considered harmful?

level: juniorimportance: must knowfreq 62%
basics
~20 s

A god object is one class that knows and does almost everything: data, rules, coordination, I/O. Because everything depends on it and every feature edits it, it is hard to understand, hard to test, and a constant source of conflicts and bugs.

open as a page

In the Gang of Four design pattern classification, what problem space do behavioral patterns address, and how do they differ from creational and structural patterns?

level: juniorimportance: must knowfreq 72%
basics
~10 s

Behavioral patterns describe how objects talk to each other and who is responsible for what. Creational patterns are about how objects get made; structural patterns are about how objects are composed into bigger shapes.

open as a page

What problem does the Bridge design pattern solve, and how does its structure solve it?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Bridge splits a design into two separate hierarchies — an abstraction (what the thing is) and an implementation (how it does its work) — connected by a reference instead of inheritance, so each side can grow independently.

open as a page

What is an architectural boundary in a software system, and what is the difference between a module's interface and its implementation?

level: juniorimportance: must knowfreq 72%
basics
~20 s

A boundary is a line separating parts of a system that change for different reasons. The interface is the small set of operations other parts may call; the implementation is the hidden internals (data structures, algorithms, storage) they must not touch.

open as a page

What are the three component cohesion principles (REP, CCP, CRP) described by Robert C. Martin, and what does each one say about which code belongs together in a releasable component?

level: juniorimportance: must knowfreq 72%
basics
~20 s

REP: things released together should be usable together. CCP: put classes that change for the same reason in the same component. CRP: don't force users to depend on code they never use. Together they decide component contents.

open as a page

What is the Dependency Inversion Principle (DIP), and how does introducing an interface change which way a dependency points between a high-level policy and a low-level detail?

level: juniorimportance: must knowfreq 82%
basics
~20 s

DIP says high-level policy should not depend on low-level details; both should depend on an abstraction. You define an interface next to the policy, the policy calls it, and the detail implements it — so the arrow now points from the detail to the policy.

open as a page

In software design, what do the terms "coupling" and "cohesion" mean, and why is the standard goal low coupling with high cohesion?

level: juniorimportance: must knowfreq 82%
basics
~20 s

Coupling is how much one module depends on another; cohesion is how well the things inside one module belong together. Low coupling means changing one module rarely forces changes elsewhere; high cohesion means each module does one clear job.

open as a page

In a layered software architecture with presentation, domain (business logic), and infrastructure/persistence layers, what is each layer responsible for and in which direction may dependencies point?

level: juniorimportance: must knowfreq 85%
basics
~20 s

Presentation handles input and output (UI, HTTP endpoints). Domain holds business rules and decisions. Infrastructure talks to databases, files, and other systems. Dependencies point one way — upper layers know about lower ones, never the reverse.

open as a page

In Clean Architecture, the 'Dependency Rule' says source code dependencies can only point inward. If a UseCase class needs to save data to a PostgreSQL database, why shouldn't that UseCase class directly import a JDBC or ORM library?

level: juniorimportance: must knowfreq 75%
basics
~10 s

Inner circles (business rules) must never depend on outer circles (frameworks/DB). The use case defines an interface it needs; a database-specific class outside implements it. This keeps business logic free of database code.

open as a page

In Hexagonal Architecture (Ports & Adapters), what is a 'port', and what distinguishes a driving (primary) port from a driven (secondary) port?

level: juniorimportance: must knowfreq 75%
basics
~20 s

A port is an interface the core app defines. Driving ports are ways the outside world calls INTO the app (like an API). Driven ports are ways the app calls OUT to things it needs (like a database).

open as a page

In a microkernel (plug-in) architecture, what is the difference between the 'core system' and a 'plug-in', and what does each side own?

level: juniorimportance: must knowfreq 55%
basics
~10 s

The core is a small always-on engine that only knows how to load and talk to plug-ins. Plug-ins are separate, swappable pieces of code that add actual features, each following rules the core sets.

open as a page

In the classic MVC (Model-View-Controller) pattern, what job does each of the Model, View, and Controller play, and why does splitting responsibilities this way help maintainability?

level: juniorimportance: must knowfreq 85%
basics
~10 s

Model holds data and business rules, View shows it on screen, Controller takes user input and decides what happens next. Splitting them means you can change how something looks without touching how it works.

open as a page

In Onion Architecture, why is the domain model placed at the center of the design instead of the database or UI?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Onion Architecture puts the business rules in the middle of the app, like the core of an onion, and everything else (database, web framework, UI) sits in layers wrapped around it. The middle never needs to know about the outer layers.

open as a page

In plain terms, what does the CAP theorem say a distributed database must sacrifice when a network partition occurs, and why can't a system just have all three of consistency, availability, and partition tolerance?

level: juniorimportance: must knowfreq 80%
basics
~20 s

When two halves of a system can't talk to each other, you must pick: either every request works but might return old/wrong data (available), or requests wait/fail until the data is provably correct (consistent). You can't have perfect answers and instant answers at once during that outage.

open as a page

Two servers in different data centers each timestamp an event using their local system clock (wall-clock/time-of-day). Why can't you safely assume that whichever timestamp is numerically smaller happened first in real time?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Computer clocks aren't perfectly synced - they drift apart between corrections and can even jump backward during a correction, so timestamps from two different machines can't be trusted to show which event really happened first.

open as a page

In a Raft or Paxos cluster of N nodes, a write is considered committed once it has been acknowledged by a quorum. Why does that quorum have to be a strict majority (more than N/2) rather than some fixed count like 2 nodes, regardless of cluster size?

level: juniorimportance: must knowfreq 70%
basics
~10 s

A majority is needed so any two quorums always share at least one node - that overlap is what stops two different decisions from being made at once.

open as a page

A distributed transaction coordinator needs to make sure a payment write to Database A and an inventory write to Database B either both happen or neither happens. Walk through how the two-phase commit (2PC) protocol achieves this, phase by phase.

level: juniorimportance: must knowfreq 75%
basics
~10 s

2PC asks everyone 'can you commit?' first (prepare phase). Only if all say yes does it tell them to actually commit (commit phase). If anyone says no, everyone rolls back.

open as a page

A cluster node pings its peers every second and marks a peer 'dead' if it misses 5 heartbeats in a row (5 seconds of silence). What is the basic trade-off this fixed-timeout heartbeat approach faces when choosing the timeout value, and why can't a single value be 'correct' for all conditions?

level: juniorimportance: must knowfreq 65%
basics
~10 s

A short timeout catches crashes fast but often wrongly declares a slow-but-alive node dead. A long timeout avoids false alarms but takes longer to notice a real crash.

open as a page

Your team's new 'Orders' microservice needs to read data from a 20-year-old legacy inventory system that uses cryptic status codes like 'S3' and denormalized flat records. Instead of letting the Orders service call the legacy API directly and pass those codes around internally, the team builds a small module that sits between them and converts everything into the Orders service's own clean model before anything else touches it. What is this module called, and what problem does it solve?

level: juniorimportance: must knowfreq 65%
basics
~20 s

It's an anti-corruption layer - a translator sitting at the boundary that converts a foreign or messy system's data/language into your own clean model, so ugliness on the other side never leaks into your code.

open as a page

What is an API Gateway in a microservices architecture, and what problem does it solve for client applications that need data from multiple backend services?

level: juniorimportance: must knowfreq 85%
basics
~20 s

It's a single door that all client requests pass through before reaching the actual services behind it. Instead of a client knowing about and calling ten different services, it talks to one address, and the gateway figures out where to send each request.

open as a page

What problem does the Backend for Frontend (BFF) pattern solve, and how does it typically sit between a client app and the backend services?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A BFF is a small backend built just for one type of app (like a mobile app or a website) so that app gets exactly the data it needs in one call, instead of talking to lots of different services itself and stitching the results together.

open as a page

In a microservices system, what's the basic difference between a synchronous call between services (like REST over HTTP) and an asynchronous message (like publishing to a queue), and when would you pick each?

level: juniorimportance: must knowfreq 85%
basics
~20 s

A synchronous call waits for an immediate answer before moving on, like a phone call. An asynchronous message is sent off while the sender keeps working, like leaving a voicemail; the other side handles it and replies whenever it's ready.

open as a page

Why should application configuration (like database URLs, timeouts, or feature flags) be kept outside the compiled application artifact instead of hardcoded, especially when the same service runs in dev, staging, and production?

level: juniorimportance: must knowfreq 75%
basics
~20 s

Because the same built package has to run in different places (laptop, test, live servers) that need different settings. If settings are baked into the code, you'd have to rebuild the whole app just to change a URL, and test settings could leak into production.

open as a page

In a system that separates commands from events, what is the key difference between a command like `PlaceOrder` and an event like `OrderPlaced`, and why does that naming difference matter for how each one is handled?

level: juniorimportance: must knowfreq 75%
basics
~20 s

A command asks the system to do something and can be refused, like a request. An event says something already happened and is a fact - you can't refuse a fact, only react to it.

open as a page

In a CQRS (Command Query Responsibility Segregation) system, commands update a write model and queries read from a separate read model that is synchronized afterward. Why does a user sometimes not see their own change immediately after saving it, and what do engineers call the time window during which this can happen?

level: juniorimportance: must knowfreq 80%
basics
~20 s

The read copy of the data updates a little after the write copy, through a background sync step. Until that catches up, queries can show old data. That gap in time is called the lag window (or replication lag).

open as a page

CQRS separates the model used to handle commands (writes) from the model used to handle queries (reads). Is Event Sourcing a required part of implementing CQRS, or is it a separate, optional choice? Explain how the two typically fit together when a team does use both.

level: juniorimportance: must knowfreq 70%
basics
~20 s

CQRS just means writes and reads use different models. Event Sourcing means you store every change as an event instead of overwriting data. You can do CQRS without Event Sourcing, but when a team does use Event Sourcing, the event log naturally becomes the write side and the read side is built from those events.

open as a page

In a CQRS system, what is a 'projection', and why do teams build one instead of just querying the write-side data directly?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A projection is a read-only copy of your data, shaped for easy querying, that's kept updated by watching events from the part of the system that handles writes. Teams build it because the write data is often shaped for correctness, not for fast, flexible reading.

open as a page

In a CQRS system, what is a 'read model' (also called a query model) and why is it usually shaped differently from the domain/write model?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A read model is a copy of your data shaped exactly for what a screen or report needs to show, separate from the data structure used to save changes. It exists so reading is fast and simple, and writing stays focused on correctness.

open as a page

In Domain-Driven Design, what is an aggregate root, and why should code outside the aggregate hold a reference to it by ID rather than by object pointer?

level: juniorimportance: must knowfreq 80%
basics
~20 s

An aggregate root is the single object outside code may touch inside a related cluster. Everything else is reached through it. Other code keeps just its ID, not a direct pointer, so it can't reach in and break the rules.

open as a page

In a layered application built with Domain-Driven Design, what is the basic difference between an 'application service' and a 'domain service'?

level: juniorimportance: must knowfreq 70%
basics
~20 s

An application service coordinates a use case — starts transactions, checks permissions, calls objects, converts data — without deciding business rules. A domain service holds business rules that don't fit one entity, like a rule spanning two accounts.

open as a page

In Domain-Driven Design, what is a bounded context, and why might the word 'Order' mean something different inside a company's Sales system than inside its Shipping system?

level: juniorimportance: must knowfreq 75%
basics
~10 s

A bounded context is a boundary around a part of a system where a specific model and its terms have one exact meaning. Outside that boundary, the same word can mean something completely different.

open as a page

In Domain-Driven Design, what is a context map, and what three things does it typically show about a system made up of multiple bounded contexts?

level: juniorimportance: must knowfreq 70%
basics
~10 s

A context map is a diagram showing all the bounded contexts in a system, how they connect, which one leads (upstream) vs follows (downstream), and which teams own each one.

open as a page

In Domain-Driven Design, what is an Anti-Corruption Layer (ACL), and why would a team put one between their bounded context and an external or legacy system?

level: juniorimportance: must knowfreq 70%
basics
~10 s

An Anti-Corruption Layer is a translation wall between your code and someone else's system, so their messy or different data model doesn't leak into and pollute your own model.

open as a page

When a new service needs to integrate with a legacy system that has messy, inconsistent naming and data structures, what problem does putting an Anti-Corruption Layer between them solve?

level: juniorimportance: must knowfreq 70%
basics
~10 s

An Anti-Corruption Layer is a translator between two systems. It converts the old system's weird data and terms into clean data your new system understands, so the mess doesn't spread into your new code.

open as a page

A client calls a REST endpoint that kicks off a report that takes 2 minutes to generate. Instead of holding the connection open, the server responds immediately with HTTP 202 Accepted and a URL the client can check later. What is this approach called, and why use it instead of just blocking the connection until the report is ready?

level: juniorimportance: must knowfreq 70%
basics
~20 s

The server says 'got it, working on it' right away instead of making the client wait. It hands back a link the client can check later to see if the work is done. This keeps the connection short and frees the client to do other things while it waits.

open as a page

What is the bulkhead pattern in software resilience, and why would a service give each downstream dependency its own pool of threads or connections instead of sharing one pool across all dependencies?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Bulkhead means giving each external service its own separate pool of workers/connections, like separate lifeboats on a ship. If one dependency gets slow or breaks, it only uses up its own pool — it can't eat all the workers other dependencies need.

open as a page

In the cache-aside (lazy-loading) caching pattern, walk through step by step what happens when application code requests a key that is not currently in the cache.

level: juniorimportance: must knowfreq 85%
basics
~20 s

The app checks the cache first. If the value isn't there (a miss), the app reads it from the real database, saves a copy in the cache, then returns it to the caller. Next time it's a fast cache hit.

open as a page

In the circuit breaker pattern used to protect a caller from a failing downstream dependency, what are the three states a breaker cycles through, and what makes it flip from closed to open?

level: juniorimportance: must knowfreq 82%
basics
~20 s

A circuit breaker watches calls to another service. Normally it's 'closed' and lets calls through. If too many fail, it 'opens' and stops calling that service for a while, failing fast instead. After a timeout it lets a few test calls through ('half-open') to check if the service recovered.

open as a page

What is application portfolio management (APM), and why does an organization need a maintained inventory of its applications rather than relying on architecture diagrams alone?

level: juniorimportance: must knowfreq 55%
basics
~20 s

APM is keeping a living list of every application a company runs — what it does, who owns it, what it costs, and how risky it is — so leaders can decide what to keep, fix, or retire.

open as a page

ArchiMate models are organized into three core layers: business, application, and technology. In plain terms, what does each layer represent, and how do they typically connect to each other in a single architecture model?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Business layer = what the company does for customers (processes, services). Application layer = the software that supports those processes. Technology layer = the infrastructure (servers, networks) that runs the software. Higher layers use services from the layer below.

open as a page

A company wants to figure out which of its IT systems actually help it win against competitors, versus which ones just keep the lights on. What technique from business strategy does an enterprise architect typically borrow to make that distinction, and how does it work?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Enterprise architects use Porter's value chain to map out every business activity, from making the product to selling it, and check which IT systems support the activities that make money versus the ones that just keep things running.

open as a page

In enterprise architecture, what is a business capability, and how does it differ from a business process?

level: juniorimportance: must knowfreq 65%
basics
~10 s

A capability is 'what' a business can do (e.g., 'Manage Customer Orders') - stable and abstract. A process is 'how' it's done, step by step, and changes more often.

open as a page

In enterprise architecture, what does the acronym BDAT stand for, and what does each of the four layers describe?

level: juniorimportance: must knowfreq 75%
basics
~20 s

BDAT = Business, Data, Application, Technology. Business is how the company works (processes, org). Data is what information exists and what it means. Application is the software that manages it. Technology is the hardware/infrastructure it all runs on.

open as a page

Imagine your application directly depends on library A and library B. Library A internally requires a shared library C at version 1.0, while library B internally requires that same library C at version 2.0. Only one version of C typically ends up available at runtime. What is this situation called, and why can't both versions simply be used side by side?

level: juniorimportance: must knowfreq 70%
basics
~20 s

It's called a 'diamond dependency conflict.' Two things your app needs each secretly need a different version of the same third thing, but most systems can only load one version of a library at once, so something has to give.

open as a page

In a Node.js project using npm, package.json lists dependency versions as semver ranges like ^18.2.0. What extra file does npm generate, and what specific problem does it solve that the ranges alone can't?

level: juniorimportance: must knowfreq 85%
basics
~20 s

A lockfile records the exact version of every package (including indirect ones) that got installed, so everyone who installs later gets the identical set of files instead of whatever the version ranges happen to resolve to that day.

open as a page

In Semantic Versioning (SemVer), a library bumps its published version from 2.3.5 to 2.4.0, and later from 2.4.0 to 3.0.0. What does each of those two jumps tell a consumer about what changed, and why does that difference matter when deciding whether to upgrade?

level: juniorimportance: must knowfreq 80%
basics
~10 s

SemVer is MAJOR.MINOR.PATCH. 2.3.5→2.4.0 (MINOR) means new features were added, safe to upgrade. 2.4.0→3.0.0 (MAJOR) means something incompatible changed - your code might break, so check the changelog first.

open as a page

A company publishes an internal package called `acme-auth-utils` on a private registry, but a developer's laptop still has the default public registry configured. One day a build silently pulls in a different `acme-auth-utils` package that was never written by anyone at the company. What attack is this, and how does the resolution logic actually let it happen?

level: juniorimportance: must knowfreq 60%
basics
~20 s

An attacker publishes a public package with the exact same name as a company's private internal package. If a build tool checks the public registry and grabs whichever version looks newest/highest, it installs the attacker's fake package instead of the real internal one — no phishing or malware download needed, just a naming collision.

open as a page

In a build tool's dependency manifest (like package.json, pom.xml, or build.gradle), what is the difference between a 'direct' dependency and a 'transitive' dependency, and where do transitive dependencies come from?

level: juniorimportance: must knowfreq 75%
basics
~10 s

A direct dependency is a library you add yourself. A transitive dependency is a library that gets pulled in automatically because one of your direct dependencies needs it to work.

open as a page