Project Architecture interview revision notes
Software and project architectures. Written for developers preparing for an interview who want to refresh their Project Architecture fast. Free, no sign-up.
8 topics in these notes
Layered (n-tier) architecture
Simple real-life example (Understand first — very important for understanding)
- Like a building: ground floor (UI), middle floor (business logic), basement (data). Each layer talks to the one below; you don’t skip floors.
- Presentation → Business → Data. Clear separation so you can change one layer without rewriting the others.
Real-world idea: layers separate concerns. UI handles display and input; business layer has rules and workflows; data layer handles persistence. Dependencies point downward.
Technical definition
- Presentation: UI, API controllers; validates input, calls business layer.
- Business (domain): core logic, use cases; no UI or DB details.
- Data: persistence, external APIs; repositories, DB access.
- Rule: upper layers depend on lower; lower layers don’t depend on upper (dependency rule).
Code example
// Controller (presentation) → Service (business) → Repository (data)
app.post('/orders', async (req, res) => {
const order = await orderService.create(req.body);
res.status(201).json(order);
});
// orderService uses orderRepository to saveWhy it matters
Layered architecture is the baseline for most apps. Interviewers expect you to name layers and explain dependency direction.
Interview tip
Say: "We use presentation, business, and data layers. Dependencies go down; business layer has no knowledge of HTTP or DB. This keeps logic testable and swappable."
MVC & MVVM
Simple real-life example (Understand first — very important for understanding)
- MVC: Model (data + rules), View (what user sees), Controller (handles input and updates model/view). User action → Controller → Model → View.
- MVVM: Model, View, ViewModel (state and logic for the view). View binds to ViewModel; ViewModel doesn’t know the View. Great for reactive UIs.
Real-world idea: MVC separates data, display, and input handling. MVVM goes further by binding view to a view model so the UI updates automatically when data changes.
Technical definition
- MVC: Model = domain + state; View = UI; Controller = input, coordinates Model and View. Common in server-rendered and desktop apps.
- MVVM: ViewModel exposes state and commands; View binds to it (data binding). Model stays separate. Reduces boilerplate in UIs (e.g. React state, Vue, Angular).
Why it matters
MVC/MVVM are standard UI architecture patterns. You should be able to compare them and say where each fits.
Interview tip
Explain Model/View/Controller and Model/View/ViewModel. Say MVVM’s binding and separation make it a good fit for reactive front-ends.
Clean / Hexagonal (Ports & Adapters) architecture
Simple real-life example (Understand first — very important for understanding)
- Core (domain) is in the middle; everything else is an adapter. UI, DB, and external APIs are pluggable; the core doesn’t depend on them.
- Ports = interfaces the core defines; adapters = implementations (REST, DB, message queue).
Real-world idea: business logic lives in the center and depends only on abstractions (ports). Adapters implement those abstractions so you can swap DB or UI without touching the core.
Technical definition
- Hexagonal: core domain + application (use cases); incoming adapters (HTTP, CLI); outgoing adapters (DB, external API).
- Ports: interfaces (e.g. IUserRepository, IEmailService). Adapters implement ports.
- Dependency rule: core has no framework or DB imports; dependencies point inward.
Code example
// Port (interface)
class IUserRepository {
save(user) {}
findById(id) {}
}
// Adapter
class MongoUserRepository extends IUserRepository {
save(user) { /* MongoDB */ }
}
// Core use case uses IUserRepository, not MongoWhy it matters
Clean/Hexagonal architecture is a common interview topic for testability and maintainability. You should know ports, adapters, and dependency direction.
Interview tip
Say: "We keep the domain in the center and depend on abstractions (ports). Adapters implement those for HTTP, DB, etc. The core stays testable and independent of frameworks."
Monolith vs modular monolith vs microservices
Simple real-life example (Understand first — very important for understanding)
- Monolith: one big codebase and deploy; simple but can become a tangle.
- Modular monolith: same one deploy, but code split into clear modules (bounded contexts) with strict boundaries—easier to later extract to services.
- Microservices: separate deploys per service; more flexibility and ops complexity.
Real-world idea: choose by team size, scale, and release needs. Modular monolith is often the best next step after a monolith before going full microservices.
Technical definition
- Monolith: single codebase and deployment; shared DB common; simple ops; risk of coupling.
- Modular monolith: one deploy; modules with clear boundaries, minimal cross-module coupling; can use events or in-process interfaces.
- Microservices: multiple services and deploys; database per service; independent scaling and teams; need discovery, resilience, distributed data.
Why it matters
Interviewers often ask how you structure a growing app and when you’d move from monolith to microservices.
Interview tip
Compare the three. Say you’d prefer a modular monolith until boundaries and scaling needs justify microservices, and that modular monolith makes extraction easier.
Event-driven architecture
Simple real-life example (Understand first — very important for understanding)
- Instead of A calling B and C directly, A publishes "something happened"; B and C subscribe and react. A doesn’t know who’s listening.
- Loose coupling: producers and consumers can be added or changed without changing the publisher.
Real-world idea: components communicate via events. One service emits events; others subscribe. Good for decoupling and scaling consumers independently.
Technical definition
- Event: something that happened (e.g. OrderPlaced, UserRegistered). Immutable; often with timestamp and payload.
- Producer publishes to a broker (Kafka, RabbitMQ, SNS); consumers subscribe. Can be pub/sub or event log (Kafka).
- Benefits: decoupling, async processing, multiple consumers; challenges: ordering, exactly-once, schema evolution.
Code example
// Producer
await eventBus.publish('order.placed', { orderId, userId, total });
// Consumer
eventBus.subscribe('order.placed', async (event) => {
await inventoryService.reserve(event.items);
await notificationService.sendOrderConfirmation(event.userId);
});Why it matters
Event-driven design is central to scalable and decoupled systems. Interviewers ask when to use events vs direct calls.
Interview tip
Say: "We use events when multiple consumers need to react to the same occurrence, or when we want to decouple producers from consumers and process asynchronously."
CQRS (Command Query Responsibility Segregation)
Simple real-life example (Understand first — very important for understanding)
- Writing (commands) and reading (queries) can use different models and stores. Write path: validate, change state, publish events. Read path: optimized for queries (e.g. denormalized views, different DB).
- Like having separate "order desk" and "inquiry desk" with different workflows and data shapes.
Real-world idea: commands change state; queries return data. Splitting them lets you optimize read and write independently (e.g. fast reads from a cache or read replica).
Technical definition
- Command: intent to change state; returns minimal or nothing. Query: returns data; no state change.
- CQRS: separate models (and often stores) for write and read. Write side may publish events; read side builds projections (views).
- Use when read and write patterns differ (e.g. many reads, complex queries, or different consistency needs).
Why it matters
CQRS is a common interview topic for high-scale or complex domains. You should know when it helps and that it adds complexity.
Interview tip
Explain command vs query and that CQRS separates write and read models. Say you’d use it when read/write loads or shapes differ a lot, and mention eventual consistency on the read side.
SOLID & separation of concerns
Simple real-life example (Understand first — very important for understanding)
- Single responsibility: one component, one reason to change. Open/closed: extend with new code, not by changing existing. Liskov: subtypes must be substitutable. Interface segregation: small, focused interfaces. Dependency inversion: depend on abstractions, not concrete classes.
- Separation of concerns: each part of the system has a clear job; don’t mix UI, business rules, and DB in one place.
Real-world idea: SOLID and separation of concerns keep code maintainable and testable. You use them in layers, modules, and when defining service boundaries.
Technical definition
- SRP: one class/module, one responsibility. OCP: open for extension (new code), closed for modification. LSP: subclasses don’t break contracts. ISP: many specific interfaces better than one huge one. DIP: depend on interfaces/abstractions.
- SoC: separate UI, business logic, data access, infrastructure; avoid mixing concerns in one layer.
Why it matters
SOLID and SoC are foundational in architecture discussions. Interviewers use them to assess how you structure code and services.
Interview tip
Give a one-line per SOLID principle and say you apply them in layering and when defining ports/adapters. Mention separation of concerns across the stack.
Scalability & availability (horizontal vs vertical)
Simple real-life example (Understand first — very important for understanding)
- Vertical: bigger machine (more CPU/RAM)—simpler but has a ceiling and single point of failure.
- Horizontal: more machines—add capacity by adding nodes; need load balancing and stateless or shared state.
Real-world idea: scale vertically for quick gains; scale horizontally for long-term growth and availability. Design for horizontal scaling (stateless app, shared-nothing or shared storage).
Technical definition
- Vertical scaling: scale up (bigger instance). Limit on size and cost; single point of failure.
- Horizontal scaling: scale out (more instances). Load balancer in front; app should be stateless or use external session/store. Enables high availability (multiple replicas).
- Availability: redundancy, health checks, failover; target 99.9% etc. with SLAs.
Why it matters
System design interviews always touch scaling and availability. You should know vertical vs horizontal and how to make an app stateless.
Interview tip
Say: "We prefer horizontal scaling for growth and availability. We keep app servers stateless and put session/cache in shared stores so we can add instances behind a load balancer."
Practise the questions
Read the top 50 Project Architecture interview questions and answers to test yourself after revising.
More Design & Architecture notes
OOP · Data Structures · Microservices · System Design · All developer notes