Title: System Design — LearnCoachAssist

Q: What is horizontal scaling?
A: Horizontal scaling (or scaling out) means adding more machines to your resource pool to handle increased load. For example, going from 1 server to 10 servers behind a load balancer.
Advantages:
- Near-infinite scalability
- Better fault tolerance — one server failing doesn't take down the system
- Can use commodity hardware
Disadvantage: Adds complexity in data consistency and distributed coordination.

Q: What is vertical scaling?
A: Vertical scaling (or scaling up) means adding more power (CPU, RAM, disk) to an existing machine.
Advantages:
- Simpler architecture — no distributed coordination needed
- No code changes required
Disadvantages:
- Hardware limits — there's a ceiling to how much you can upgrade
- Single point of failure
- Downtime during upgrades

Q: What is a load balancer?
A: A load balancer distributes incoming network traffic across multiple backend servers to ensure no single server is overwhelmed.
It sits between clients and servers, improving:
- Availability — routes around failed servers
- Throughput — parallel processing across servers
- Latency — directs to least-loaded server
Common examples: NGINX, HAProxy, AWS ALB/NLB.

Q: What are common load balancing algorithms?
A: Common algorithms:
- Round Robin — requests are distributed sequentially across servers
- Weighted Round Robin — servers with higher capacity get more requests
- Least Connections — routes to the server with fewest active connections
- IP Hash — routes based on client IP, ensuring session stickiness
- Random — randomly selects a server
- Least Response Time — routes to the fastest-responding server

Q: What are Layer 4 vs Layer 7 load balancers?
A: Layer 4 (Transport) load balancers route based on IP address and TCP/UDP port without inspecting packet contents. They are faster but less flexible.
Layer 7 (Application) load balancers inspect HTTP headers, cookies, and URLs to make smarter routing decisions. They can do content-based routing, SSL termination, and request modification.
Example: HAProxy supports both; AWS NLB is L4, ALB is L7.

Q: How do load balancer health checks work?
A: Health checks are periodic probes sent by the load balancer to backend servers to verify they are operational.
Types:
- Active — LB sends HTTP/TCP requests at intervals (e.g., GET /health every 10s)
- Passive — LB monitors real traffic for errors or timeouts
Configuration: Typically includes interval, timeout, unhealthy threshold (failures before removal), and healthy threshold (successes before re-adding).

Q: What is Redis?
A: Redis (Remote Dictionary Server) is an open-source, in-memory key-value data store used as a cache, message broker, and database.
Key features:
- Sub-millisecond latency
- Rich data structures: strings, hashes, lists, sets, sorted sets, streams
- Persistence options: RDB snapshots and AOF (Append Only File)
- Built-in replication, Lua scripting, pub/sub
- Cluster mode for horizontal scaling

Q: What is Memcached and how does it differ from Redis?
A: Memcached is a distributed in-memory caching system designed for simplicity and speed.
Differences from Redis:
- Memcached: only simple key-value strings; Redis: rich data structures
- Memcached: no persistence; Redis: optional persistence
- Memcached: multi-threaded; Redis: single-threaded (with I/O threads in v6+)
- Memcached: no replication; Redis: built-in replication
- Memcached: better for simple caching; Redis: better for complex use cases

Q: What is CDN caching?
A: A CDN (Content Delivery Network) caches static and dynamic content at edge servers geographically distributed around the world.
How it works:
- User requests content → routed to nearest edge server
- If cached (cache hit), served directly with low latency
- If not cached (cache miss), fetched from origin, cached, then served
Benefits: reduced latency, lower origin server load, DDoS protection.
Examples: CloudFlare, AWS CloudFront, Akamai.

Q: What are cache invalidation strategies?
A: Cache invalidation ensures stale data is removed or updated. Main strategies:
- TTL (Time-To-Live) — cache entries expire after a set duration
- Event-based — invalidate on write/update events
- Write-through — data is written to cache and DB simultaneously
- Write-behind — data is written to cache first, DB updated asynchronously
- Manual purge — explicitly delete specific cache keys
"There are only two hard things in CS: cache invalidation and naming things."

Q: What is the cache-aside pattern?
A: In the cache-aside (lazy-loading) pattern, the application manages the cache directly:
Read path:
1. Check cache for data
2. On cache miss, read from database
3. Store result in cache, return to caller
Write path:
1. Write to database
2. Invalidate (delete) the cache entry
Pros: Only requested data is cached; resilient to cache failures.
Cons: Cache miss penalty (extra DB call); possible stale data between write and invalidation.

Q: What is write-through caching?
A: In write-through caching, every write goes to both the cache and the database synchronously.
App → write to Cache → write to DB
Pros:
- Cache is always consistent with DB
- No stale reads
Cons:
- Higher write latency (two writes per operation)
- Cache may hold data that is never read
Often combined with TTL to evict unused entries.

Q: What is database sharding?
A: Sharding is a horizontal partitioning strategy where data is split across multiple database instances (shards), each holding a subset of the total data.
Shard key determines which shard stores a given record (e.g., user_id % num_shards).
Pros: horizontal scalability, better performance
Cons:
- Cross-shard queries are expensive
- Rebalancing shards is complex
- Joins across shards are difficult

Q: What is database replication?
A: Database replication copies data from one database server (primary/master) to one or more replicas (secondaries/slaves).
Types:
- Synchronous — primary waits for replica acknowledgment (strong consistency)
- Asynchronous — primary doesn't wait (better performance, eventual consistency)
- Semi-synchronous — waits for at least one replica
Benefits: read scalability, high availability, disaster recovery.

Q: What is database partitioning?
A: Database partitioning divides a large table into smaller, more manageable pieces.
Types:
- Horizontal — rows are split across partitions (e.g., orders by date range)
- Vertical — columns are split (e.g., frequently-accessed vs rarely-accessed columns)
Strategies:
- Range — partition by value ranges
- Hash — partition by hash of a key
- List — partition by explicit value lists
Improves query performance and maintenance operations.

Q: How does database indexing work?
A: A database index is a data structure (typically a B-tree or B+ tree) that speeds up data retrieval at the cost of additional storage and slower writes.
CREATE INDEX idx_email ON users(email);
Types:
- Primary index — on the primary key
- Secondary index — on non-primary columns
- Composite index — on multiple columns
- Covering index — contains all columns needed by a query
Trade-off: Faster reads, slower writes, more storage.

Q: What are the key differences between SQL and NoSQL databases?
A: SQL databases:
- Relational, table-based with fixed schema
- ACID compliant
- Vertically scalable
- Examples: PostgreSQL, MySQL
NoSQL databases:
- Non-relational: document, key-value, column-family, graph
- Flexible/dynamic schema
- Horizontally scalable
- Eventually consistent (typically)
- Examples: MongoDB, Cassandra, DynamoDB
Choose SQL for complex queries/transactions; NoSQL for scale/flexibility.

Q: What are microservices and how do they differ from monoliths?
A: A monolith is a single deployable unit containing all application functionality. Microservices decompose the application into small, independently deployable services.
Monolith:
- Simpler to develop and deploy initially
- Harder to scale individual components
- Single codebase, single deployment
Microservices:
- Independent scaling, deployment, and technology choices
- Better fault isolation
- Increased operational complexity (networking, observability, data consistency)

Q: What is service discovery?
A: Service discovery is the mechanism by which microservices locate and communicate with each other in a dynamic environment where instances come and go.
Two patterns:
- Client-side discovery — client queries a service registry and selects an instance (e.g., Netflix Eureka)
- Server-side discovery — client sends request to a load balancer/router which queries the registry (e.g., AWS ALB, Kubernetes kube-proxy)
Common registries: Consul, etcd, ZooKeeper.

Q: What is Apache Kafka?
A: Apache Kafka is a distributed event streaming platform used for building real-time data pipelines and streaming applications.
Core concepts:
- Topics — named feeds of messages
- Partitions — topics are split for parallelism
- Producers — publish messages to topics
- Consumers — read messages from topics via consumer groups
- Brokers — Kafka servers in a cluster
Key features: high throughput, durability (messages persisted to disk), exactly-once semantics, replay capability.

Q: What is RabbitMQ?
A: RabbitMQ is an open-source message broker implementing the AMQP protocol.
Core concepts:
- Producer → sends messages to an Exchange
- Exchange → routes messages to Queues based on bindings/routing keys
- Consumer → reads from queues
Exchange types: direct, fanout, topic, headers.
Kafka vs RabbitMQ: Kafka is best for high-throughput event streaming and log aggregation; RabbitMQ excels at complex routing and task queues with delivery guarantees.

Q: What is the publish/subscribe messaging pattern?
A: Pub/Sub is a messaging pattern where publishers send messages to a topic without knowing who will receive them, and subscribers receive messages from topics they're interested in.
Key properties:
- Loose coupling between producers and consumers
- One-to-many communication
- Subscribers can be added without changing publishers
Implementations: Kafka topics, Redis Pub/Sub, AWS SNS, Google Pub/Sub.

Q: What is the CAP theorem?
A: The CAP theorem states that a distributed system can guarantee at most two out of three properties simultaneously:
- Consistency — every read receives the most recent write
- Availability — every request receives a response (success or failure)
- Partition Tolerance — system operates despite network partitions
Since network partitions are inevitable, the real choice is between CP (e.g., HBase, MongoDB) and AP (e.g., Cassandra, DynamoDB).

Q: What are the ACID properties?
A: ACID guarantees for database transactions:
- Atomicity — a transaction is all-or-nothing; if any part fails, the entire transaction is rolled back
- Consistency — a transaction brings the database from one valid state to another, respecting all constraints
- Isolation — concurrent transactions don't interfere with each other
- Durability — once committed, changes survive system crashes (persisted to disk)
ACID is fundamental to relational databases like PostgreSQL and MySQL.

Q: What is BASE in distributed systems?
A: BASE is an alternative to ACID, commonly used in NoSQL and distributed systems:
- Basically Available — the system guarantees availability (per CAP)
- Soft state — the system's state may change over time even without input (due to eventual consistency)
- Eventually consistent — the system will become consistent over time once it stops receiving updates
BASE trades strong consistency for availability and partition tolerance. Examples: Cassandra, DynamoDB, CouchDB.

Q: What is consistent hashing?
A: Consistent hashing is a technique for distributing data across nodes where adding or removing a node only requires remapping K/N keys (K = total keys, N = nodes), instead of rehashing everything.
How it works:
- Nodes and keys are mapped onto a hash ring
- Each key is assigned to the first node clockwise from its position
- Virtual nodes improve balance by mapping each physical node to multiple ring positions
Used in: DynamoDB, Cassandra, Memcached.

Q: What is an API gateway?
A: An API gateway is a server that acts as a single entry point for all client requests to backend microservices.
Responsibilities:
- Request routing to appropriate services
- Authentication and authorization
- Rate limiting and throttling
- Request/response transformation
- SSL termination
- Caching, logging, monitoring
Examples: Kong, AWS API Gateway, NGINX, Apigee.
It simplifies client interactions and centralizes cross-cutting concerns.

Q: What is a reverse proxy?
A: A reverse proxy sits in front of backend servers and forwards client requests to them. The client communicates only with the proxy.
Benefits:
- Security — hides backend server IPs
- SSL termination — handles encryption/decryption
- Load balancing — distributes requests
- Caching — serves cached responses
- Compression — reduces response sizes
Forward proxy acts on behalf of clients; reverse proxy acts on behalf of servers.
Examples: NGINX, HAProxy, Traefik.

Q: What is rate limiting?
A: Rate limiting controls the number of requests a client can make to a service within a given time window, protecting against abuse and ensuring fair resource usage.
Common responses: HTTP 429 Too Many Requests with a Retry-After header.
Implementation levels:
- Per-user / per-API-key
- Per-IP address
- Global (entire service)
Can be implemented at the API gateway, load balancer, or application layer.

Q: How does the token bucket algorithm work?
A: The token bucket algorithm is a rate limiting strategy:
- A bucket holds up to B tokens (burst capacity)
- Tokens are added at a fixed rate of R tokens/second
- Each request consumes one token
- If the bucket is empty, the request is rejected or queued
Advantages:
- Allows short bursts of traffic up to bucket size
- Simple to implement
- Smooths out traffic over time
Used by AWS, Stripe, and many API providers.

Q: How does the sliding window rate limiting algorithm work?
A: The sliding window algorithm tracks requests in a continuously moving time window:
Sliding Window Log:
- Store timestamps of all requests
- On each request, remove timestamps older than the window
- Count remaining; reject if over limit
Sliding Window Counter (hybrid):
- Combine current and previous fixed window counts
- Weight by overlap: count = prev * (1 - elapsed/window) + current
More accurate than fixed windows, avoids the boundary burst problem.

Q: What are WebSockets?
A: WebSockets provide a full-duplex, persistent communication channel over a single TCP connection between client and server.
How it works:
- Starts with an HTTP upgrade handshake
- Once established, both sides can send messages at any time
- Connection stays open until explicitly closed
Use cases: real-time chat, live dashboards, multiplayer games, collaborative editing.
const ws = new WebSocket('wss://example.com/socket');
Protocol: ws:// or wss:// (encrypted).

Q: What is long polling?
A: Long polling is a technique where the client sends a request and the server holds it open until new data is available or a timeout occurs.
Flow:
1. Client sends HTTP request
2. Server holds the connection open
3. When data is available, server responds
4. Client immediately sends a new request
Pros: Works everywhere HTTP works, no special protocol.
Cons: Higher latency than WebSockets, server holds many open connections, HTTP overhead per response.

Q: What are Server-Sent Events (SSE)?
A: SSE is a standard allowing servers to push updates to clients over a single, long-lived HTTP connection.
Characteristics:
- Unidirectional — server to client only
- Uses standard HTTP (port 80/443)
- Auto-reconnection built into the browser API
- Text-based (not binary)
Content-Type: text/event-stream
SSE vs WebSockets: Use SSE for server-push scenarios (live feeds, notifications). Use WebSockets when bidirectional communication is needed.

Q: What is event-driven architecture?
A: Event-driven architecture (EDA) is a design pattern where components communicate by producing and consuming events — records of state changes.
Components:
- Event producers — emit events (e.g., OrderPlaced)
- Event broker — routes events (e.g., Kafka, RabbitMQ)
- Event consumers — react to events
Benefits: loose coupling, scalability, real-time processing, auditability.
Challenges: eventual consistency, event ordering, debugging complexity.

Q: What is CQRS?
A: CQRS (Command Query Responsibility Segregation) separates read and write operations into different models.
Command side: handles writes/updates with a model optimized for validation and business logic.
Query side: handles reads with a model optimized for fast queries and projections.
Benefits:
- Independent scaling of reads and writes
- Optimized data models for each operation
- Better performance for read-heavy systems
Often paired with Event Sourcing, where state changes are stored as a sequence of events.

Q: How does DNS work?
A: DNS (Domain Name System) translates human-readable domain names into IP addresses.
Resolution flow:
1. Browser checks local cache
2. Queries recursive resolver (usually ISP)
3. Resolver queries root nameserver → TLD nameserver (.com) → authoritative nameserver
4. IP address returned and cached with a TTL
Record types: A (IPv4), AAAA (IPv6), CNAME (alias), MX (mail), NS (nameserver), TXT.

Q: What is a CDN and why is it used?
A: A CDN (Content Delivery Network) is a geographically distributed network of servers that delivers content to users from the nearest edge location.
Benefits:
- Reduced latency — content served from nearby servers
- Lower origin load — edge servers handle most requests
- DDoS protection — distributed infrastructure absorbs attacks
- High availability — redundant edge servers
Use cases: static assets (images, CSS, JS), video streaming, API acceleration.
Examples: CloudFlare, Akamai, AWS CloudFront.

Q: What is the circuit breaker pattern?
A: The circuit breaker pattern prevents cascading failures in distributed systems by stopping calls to a failing service.
Three states:
- Closed — requests flow normally; failures are counted
- Open — after failure threshold is reached, all requests are immediately rejected (fail fast)
- Half-Open — after a timeout, a limited number of test requests are allowed through
If test requests succeed → Closed. If they fail → back to Open.
Implemented in libraries like Resilience4j, Hystrix, Polly.

Q: What is eventual consistency?
A: Eventual consistency is a consistency model where, given enough time without new updates, all replicas will converge to the same value.
Key properties:
- Reads may return stale data temporarily
- System prioritizes availability over immediate consistency
- Conflicts are resolved via timestamps, vector clocks, or application logic
Examples: DNS propagation, DynamoDB, Cassandra.
Contrast with strong consistency: every read returns the latest write (e.g., single-leader replication with synchronous writes).

Q: What is strong consistency vs eventual consistency?
A: Strong consistency: After a write completes, all subsequent reads return the updated value. Every node sees the same data at the same time.
Eventual consistency: After a write, reads may return stale data, but all nodes will eventually converge.
Trade-offs:
- Strong: higher latency, lower availability (per CAP)
- Eventual: lower latency, higher availability, but stale reads possible
Strong: Spanner, CockroachDB
Eventual: DynamoDB, Cassandra

Q: What is the saga pattern for distributed transactions?
A: The saga pattern manages distributed transactions as a sequence of local transactions, each with a compensating action for rollback.
Two approaches:
- Choreography — each service publishes events that trigger the next step
- Orchestration — a central orchestrator coordinates the saga steps
Example: Order saga: Create Order → Reserve Inventory → Process Payment. If payment fails → Release Inventory → Cancel Order.
Used when you need transactions across microservices without distributed locks.

Q: What is two-phase commit (2PC)?
A: Two-phase commit is a distributed protocol ensuring all participants in a transaction either commit or abort together.
Phase 1 — Prepare:
- Coordinator asks all participants: "Can you commit?"
- Each participant votes Yes or No
Phase 2 — Commit/Abort:
- If all vote Yes → coordinator sends Commit
- If any vote No → coordinator sends Abort
Drawbacks: blocking protocol (participants lock resources), coordinator is a single point of failure.

Q: What is data replication and what are its types?
A: Data replication copies data across multiple nodes for fault tolerance and read scalability.
Types:
- Single-leader — one primary handles writes; replicas serve reads
- Multi-leader — multiple nodes accept writes (e.g., cross-datacenter). Requires conflict resolution
- Leaderless — any node accepts reads/writes; uses quorum (W + R > N) for consistency
Leaderless examples: Cassandra, DynamoDB.
Conflict strategies: last-write-wins, vector clocks, CRDTs.

Q: What is read-through vs write-through caching?
A: Read-through: The cache sits between the app and DB. On a cache miss, the cache itself loads data from the DB, stores it, and returns it to the app.
Write-through: Every write goes through the cache to the DB synchronously. The cache always has up-to-date data.
Comparison:
- Read-through simplifies app code for reads
- Write-through ensures cache consistency on writes
- Both can be combined for strong read/write consistency
Both add latency compared to cache-aside but reduce stale data risk.

Q: What is write-behind (write-back) caching?
A: In write-behind caching, the application writes to the cache, which asynchronously writes to the database after a delay or in batches.
App → Cache (immediate) → DB (async, batched)
Advantages:
- Very low write latency for the application
- Batch writes reduce DB load
- Absorbs write spikes
Risks:
- Data loss if cache fails before flushing to DB
- Complexity in ensuring eventual persistence
Used in: Ehcache, database page caches.

Q: What is database connection pooling?
A: Connection pooling maintains a pool of reusable database connections, avoiding the overhead of creating a new connection for each request.
How it works:
- Pool initialized with min connections at startup
- App borrows a connection, uses it, returns it to the pool
- Pool grows up to max connections under load
Benefits: reduced latency, controlled resource usage, prevents DB overload.
Tools: HikariCP (Java), pgBouncer (PostgreSQL), SQLAlchemy pool (Python).

Q: What is an event store in event sourcing?
A: An event store is a database optimized for storing an immutable, append-only sequence of domain events.
Event sourcing principles:
- State is derived by replaying events, not stored directly
- Events are immutable facts (e.g., OrderPlaced, ItemAdded)
- Current state = fold(initialState, allEvents)
Benefits: complete audit trail, temporal queries, easy debugging.
Challenges: event versioning, storage growth, rebuild time.
Examples: EventStoreDB, Kafka as event store.

Q: What is idempotency and why is it important in distributed systems?
A: An operation is idempotent if performing it multiple times produces the same result as performing it once.
Why it matters:
- Network retries may duplicate requests
- Message queues may deliver messages more than once
- Ensures safety of automatic retries
Implementation:
- Use idempotency keys — unique IDs sent with each request
- Server checks if the key was already processed
- HTTP examples: GET, PUT, DELETE are idempotent; POST is not

Q: What is back-pressure in distributed systems?
A: Back-pressure is a mechanism where a downstream component signals upstream components to slow down when it cannot keep up with incoming data.
Strategies:
- Buffering — queue messages temporarily (bounded buffer)
- Dropping — discard excess messages (acceptable for metrics/logs)
- Blocking — producer blocks until consumer catches up
- Rate limiting — explicitly limit producer throughput
Without back-pressure: memory exhaustion, cascading failures, dropped messages.
Frameworks: Reactive Streams, Kafka consumer lag.