[{"key":"sysdesign:what-is-system-design--functional-vs-nonfunctional","moduleId":"sysdesign","cardId":"what-is-system-design--functional-vs-nonfunctional","front":"What is the difference between functional and non-functional requirements, and why does the distinction decide your entire design?","back":"Functional requirements say what the system does - post a tweet, follow a user, search. Non-functional requirements say how well it must do it - 100 million daily users, 200 ms p99, 99.99% availability, five-year retention. The functional list decides which boxes appear in your diagram; the non-functional numbers decide how many of each box, which database, and whether you need a cache, a queue or a CDN at all. Two systems with identical features and different scale numbers are completely different designs.","keyPoints":["Functional = what it does; non-functional = how well, and the latter drives the architecture.","Always convert vague adjectives into numbers: users, RPS, percentile latency, nines.","Ask read/write ratio early - it decides caching, replication and storage engine.","State the consistency requirement explicitly; it is the fork in the road for database choice."],"href":"/system-design-interview/questions/what-is-system-design","moduleLabel":"System Design"},{"key":"sysdesign:what-is-system-design--core-vocabulary","moduleId":"sysdesign","cardId":"what-is-system-design--core-vocabulary","front":"Define latency, throughput, availability and consistency - and explain how they trade against each other.","back":"Latency is how long one request takes; throughput is how many requests you complete per second. They are not inverses - you can raise throughput with batching while making latency worse. Availability is the fraction of time the system successfully serves requests, and consistency is whether every reader sees the latest write. The central tension is that improving availability usually means adding replicas, and adding replicas makes strong consistency slower and more fragile.","keyPoints":["Latency = per-request time; throughput = requests per second; they trade via batching and queueing.","Quote p95/p99, not averages - tail latency dominates real page loads.","Know the nines table cold: 99.9% ≈ 43 min/month, 99.99% ≈ 4 min/month.","Availability comes from redundancy, and redundancy is what forces the consistency trade-off."],"href":"/system-design-interview/questions/what-is-system-design","moduleLabel":"System Design"},{"key":"sysdesign:what-is-system-design--interview-format","moduleId":"sysdesign","cardId":"what-is-system-design--interview-format","front":"How is a 45-minute system design interview actually structured, and how should you budget the time?","back":"Roughly: 5 minutes clarifying requirements and scale, 5 minutes on API and data model, 10 minutes on a high-level design you draw end to end, 15 minutes going deep on two or three components the interviewer picks, and 5–10 minutes identifying bottlenecks and scaling the design. The failure mode is spending twenty minutes on requirements and never producing a design, or drawing instantly and never justifying anything.","keyPoints":["Have a complete end-to-end design by roughly the 20-minute mark.","Write the requirement numbers down and refer back to them when justifying decisions.","Find your own bottleneck before the interviewer does.","Narrate your agenda and think out loud - silence scores zero."],"href":"/system-design-interview/questions/what-is-system-design","moduleLabel":"System Design"},{"key":"sysdesign:what-is-system-design--building-blocks","moduleId":"sysdesign","cardId":"what-is-system-design--building-blocks","front":"What are the standard building blocks of a large-scale system, and what problem does each one solve?","back":"There are about a dozen reusable components: DNS, CDN, load balancer, API gateway, stateless application servers, cache, relational and NoSQL databases, object storage, message queue or event log, search index, and a background worker pool. Each exists to solve one specific bottleneck. Knowing which problem each solves means you add components because you need them, rather than because they look impressive.","keyPoints":["Each component removes one specific bottleneck; name the bottleneck before adding the box.","Caching and CDNs are usually the cheapest big wins for read-heavy systems.","Queues convert slow synchronous work into fast requests plus background jobs.","Sharding and microservices come last - they cost the most complexity per unit of benefit."],"href":"/system-design-interview/questions/what-is-system-design","moduleLabel":"System Design"},{"key":"sysdesign:back-of-the-envelope-estimation--qps-estimation","moduleId":"sysdesign","cardId":"back-of-the-envelope-estimation--qps-estimation","front":"Walk me through estimating queries per second for a system with 100 million daily active users.","back":"Take DAU, multiply by actions per user per day to get daily requests, divide by 86,400 seconds to get average QPS, then multiply by a peak factor of 2 to 3. For 100 million DAU doing 20 actions a day: 2 billion requests a day, ÷ 86,400 ≈ 23,000 average QPS, so roughly 50,000–70,000 QPS at peak. Then split that by read/write ratio, because 50,000 reads and 500 writes are completely different engineering problems.","keyPoints":["QPS = DAU × actions/day ÷ 86,400, then × 2–3 for peak.","Round 86,400 to 10⁵ for instant mental arithmetic.","Always split into reads and writes - the ratio decides the architecture.","Finish with a decision: what does this number rule in or out?"],"href":"/system-design-interview/questions/back-of-the-envelope-estimation","moduleLabel":"System Design"},{"key":"sysdesign:back-of-the-envelope-estimation--storage-estimation","moduleId":"sysdesign","cardId":"back-of-the-envelope-estimation--storage-estimation","front":"How do you estimate storage and bandwidth requirements for a media-heavy product?","back":"Storage = objects per day × average size × retention, then multiply by a replication factor (usually 3) and add roughly 30% for indexes, metadata and headroom. Bandwidth = QPS × average payload size, computed separately for ingress and egress - egress is usually far larger for media products and is the line item that actually costs money. Always express the result per day and per year, because the yearly figure is what decides your storage tier.","keyPoints":["Multiply by replication factor and add ~30% overhead - raw size is never the real number.","Separate ingress from egress; for media, egress dominates and drives cost.","Express storage per year - that is the figure that picks the storage tier.","Use scientific notation to keep whiteboard arithmetic error-free."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation","moduleLabel":"System Design"},{"key":"sysdesign:back-of-the-envelope-estimation--latency-numbers","moduleId":"sysdesign","cardId":"back-of-the-envelope-estimation--latency-numbers","front":"What are the latency numbers every engineer should know, and how do you use them in a design?","back":"The ladder spans about eight orders of magnitude: L1 cache around 1 ns, main memory around 100 ns, an SSD read around 100 µs, a same-datacentre round trip around 500 µs, a disk seek around 10 ms, and a cross-continent round trip around 150 ms. The practical consequence is that memory is roughly a thousand times faster than SSD and over a million times faster than a cross-ocean hop - so the design question is never 'is this fast?' but 'how many times do I cross which boundary?'.","keyPoints":["Memory ≈ 100 ns, SSD ≈ 100 µs, same-DC RTT ≈ 0.5 ms, cross-continent ≈ 150 ms.","Optimise by removing round trips, not by shaving microseconds.","The speed of light sets a hard floor - that is why CDNs and regional replicas exist.","Parallel fan-out turns rare tail latency into common tail latency."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation","moduleLabel":"System Design"},{"key":"sysdesign:back-of-the-envelope-estimation--servers-needed","moduleId":"sysdesign","cardId":"back-of-the-envelope-estimation--servers-needed","front":"How many servers do you need for 50,000 QPS, and how do you reason about the answer?","back":"Divide target QPS by realistic per-server throughput, then divide again by your target utilisation, then add redundancy. If a server handles 2,000 QPS and you run at 50% utilisation for headroom, 50,000 QPS needs 50 servers, plus enough extra to survive losing an availability zone - so around 75 across three zones. The number matters less than the reasoning: state per-server capacity, utilisation target and failure budget explicitly.","keyPoints":["Servers = QPS ÷ per-server capacity ÷ utilisation target, then × redundancy factor.","Plan for 50–70% utilisation; latency explodes non-linearly as you approach saturation.","Little's Law (L = λW) sizes thread pools and connection pools instantly.","State your per-request cost assumption - that is the number the interviewer will probe."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation","moduleLabel":"System Design"},{"key":"sysdesign:scalability-availability-and-reliability--scalability-vs-availability","moduleId":"sysdesign","cardId":"scalability-availability-and-reliability--scalability-vs-availability","front":"What is the difference between scalability, availability and reliability?","back":"Scalability is the ability to handle growth by adding resources, ideally with cost rising linearly rather than exponentially. Availability is the fraction of time the system responds successfully. Reliability is the probability it behaves correctly over a period - an available system that returns wrong answers is not reliable. A system can be highly available and unreliable (always up, silently corrupting data), or reliable but unavailable (perfectly correct when running, down four hours a week).","keyPoints":["Scalable = handles growth with proportional cost; available = up; reliable = correct.","Scalability is determined by your worst bottleneck, not your average component.","Retries trade reliability for availability unless operations are idempotent.","Amdahl's Law: the serial fraction sets a hard ceiling on parallel speedup."],"href":"/system-design-interview/questions/scalability-availability-and-reliability","moduleLabel":"System Design"},{"key":"sysdesign:scalability-availability-and-reliability--availability-maths","moduleId":"sysdesign","cardId":"scalability-availability-and-reliability--availability-maths","front":"If a request depends on three services each with 99.9% availability, what is the end-to-end availability - and how do you improve it?","back":"Dependencies in series multiply: 0.999³ ≈ 0.997, so about 99.7%, which is roughly 2.2 hours of downtime a month rather than 43 minutes. Each dependency you add makes things worse. You improve it either by adding redundancy within each service - two independent replicas at 99.9% give 99.9999% for that component - or by removing the dependency from the critical path entirely with caching, defaults, or asynchronous processing.","keyPoints":["Series dependencies multiply availability; parallel redundancy multiplies failure probability.","Three 99.9% dependencies in series ≈ 99.7% - microservices tax availability by default.","Redundancy only compounds when failures are genuinely independent.","Removing a dependency from the critical path beats making it more reliable.","SLI measures, SLO targets, SLA contracts; the error budget makes the trade-off explicit."],"href":"/system-design-interview/questions/scalability-availability-and-reliability","moduleLabel":"System Design"},{"key":"sysdesign:scalability-availability-and-reliability--single-point-of-failure","moduleId":"sysdesign","cardId":"scalability-availability-and-reliability--single-point-of-failure","front":"How do you identify and eliminate single points of failure in a design?","back":"Walk the request path and ask of every component: if exactly this one thing dies, does the system stop? Anything that answers yes is a single point of failure. The classic ones are the database primary, the load balancer itself, a single availability zone, the DNS provider, a shared config or secrets service, and the deployment pipeline. You eliminate them with redundancy plus automatic failover - and you verify the failover actually works, because untested failover is not redundancy.","keyPoints":["Walk the request path and ask 'if only this dies, does the system stop?'","Redundancy must cross failure domains - three instances in one zone is one failure domain.","Non-server SPOFs (DNS, certs, config, deploy pipeline) cause many real outages.","Availability = MTBF / (MTBF + MTTR); lowering MTTR is usually the cheaper lever.","Untested failover should be assumed broken."],"href":"/system-design-interview/questions/scalability-availability-and-reliability","moduleLabel":"System Design"},{"key":"sysdesign:how-the-internet-works-dns-tcp-tls-http--what-happens-when-you-type-a-url","moduleId":"sysdesign","cardId":"how-the-internet-works-dns-tcp-tls-http--what-happens-when-you-type-a-url","front":"What happens when you type a URL into a browser and press enter?","back":"The browser checks its caches, resolves the hostname to an IP via DNS, opens a TCP connection with a three-way handshake, negotiates TLS, sends an HTTP request, and receives a response - usually from a CDN edge rather than the origin. The browser then parses the HTML and repeats the process for every referenced asset. The whole sequence is dominated by round trips, which is why caching, connection reuse and edge termination matter more than server speed.","keyPoints":["Cache check → DNS → TCP → TLS → HTTP → render, and every asset repeats the tail of it.","Cold HTTPS to a far origin ≈ 4 RTTs before the first byte.","TLS 1.3 is 1 RTT (0 on resumption); TLS 1.2 is 2.","DNS TTL is a failover control, not just a caching detail."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http","moduleLabel":"System Design"},{"key":"sysdesign:how-the-internet-works-dns-tcp-tls-http--tcp-vs-udp","moduleId":"sysdesign","cardId":"how-the-internet-works-dns-tcp-tls-http--tcp-vs-udp","front":"TCP or UDP - how do you choose, and what does QUIC change?","back":"TCP gives ordered, reliable, congestion-controlled delivery at the cost of handshakes, retransmission delay and head-of-line blocking. UDP gives you a fire-and-forget datagram with none of those guarantees and none of that overhead. Use TCP when correctness and completeness matter - APIs, page loads, file transfer. Use UDP when timeliness beats completeness - live video, voice, gaming, DNS, metrics. QUIC is the interesting middle: it runs reliability and congestion control over UDP in user space, so it gets TCP's guarantees per stream without TCP's cross-stream head-of-line blocking.","keyPoints":["TCP = reliable, ordered, congestion-controlled, with handshake and HoL cost.","UDP = no guarantees, no setup - right whenever a late packet is worthless.","HTTP/2 multiplexes at the app layer but still suffers TCP-level head-of-line blocking.","QUIC gives per-stream ordering, 1-RTT setup and connection migration over UDP."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http","moduleLabel":"System Design"},{"key":"sysdesign:how-the-internet-works-dns-tcp-tls-http--load-balancer-l4-l7","moduleId":"sysdesign","cardId":"how-the-internet-works-dns-tcp-tls-http--load-balancer-l4-l7","front":"What is the difference between an L4 and an L7 load balancer, and when do you use each?","back":"An L4 load balancer routes on IP and port without reading the payload - it is fast, protocol-agnostic and cheap, but it cannot make decisions based on the request. An L7 load balancer terminates the connection and parses HTTP, so it can route by path, host or header, retry idempotent requests, do TLS termination, compression, rate limiting and sticky sessions. Use L4 for raw throughput and non-HTTP protocols; use L7 whenever routing decisions depend on the content of the request, which for a modern web system is almost always.","keyPoints":["L4 routes on IP/port and is fast; L7 parses HTTP and can route on content.","L7 health checks distinguish 'port open' from 'actually able to serve'.","L7 enables path routing, canaries, TLS termination, retries and rate limiting.","Big stacks use L4 in front of L7: throughput first, intelligence second."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http","moduleLabel":"System Design"},{"key":"sysdesign:api-design-rest-grpc-graphql--rest-grpc-graphql","moduleId":"sysdesign","cardId":"api-design-rest-grpc-graphql--rest-grpc-graphql","front":"How do you choose between REST, gRPC and GraphQL?","back":"REST for public APIs and anything cached by HTTP infrastructure - it is universally understood and works with every proxy, CDN and browser. gRPC for internal service-to-service calls where you want a typed contract, binary efficiency, streaming and code generation. GraphQL when many diverse clients need different shapes of the same data and over-fetching is the real problem - typically a mobile app plus a web app against a rich domain. Most large companies use all three: REST at the public edge, gRPC internally, GraphQL as a client-facing aggregation layer.","keyPoints":["REST for public and cacheable; gRPC for internal and latency-sensitive; GraphQL for many client shapes.","gRPC's real wins are the enforced contract and code generation, not just binary size.","GraphQL costs you HTTP caching and invites N+1 and expensive-query attacks.","Large systems combine all three rather than picking one."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql","moduleLabel":"System Design"},{"key":"sysdesign:api-design-rest-grpc-graphql--idempotency","moduleId":"sysdesign","cardId":"api-design-rest-grpc-graphql--idempotency","front":"A client retries a payment request after a timeout. How do you make sure the customer is not charged twice?","back":"Make the operation idempotent with a client-generated idempotency key. The client sends a unique key with the request; the server claims the key in a table with a uniqueness constraint before doing the work, then stores the response against it. A retry with the same key returns the stored response instead of executing again. The critical details are that the key must be recorded in the same transaction as the effect, that concurrent duplicates must be serialised by the unique constraint rather than a read-then-write check, and that in-flight duplicates should get a 409 rather than a second execution.","keyPoints":["Client-generated idempotency key, stored with a uniqueness constraint.","Insert first and catch the unique violation - never read-then-write.","Commit the key and the side effect atomically, or push the key to the external provider.","Return 409 for an in-flight duplicate, and replay the stored response for a completed one.","Hash the body to detect key reuse with different content."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql","moduleLabel":"System Design"},{"key":"sysdesign:api-design-rest-grpc-graphql--pagination-and-versioning","moduleId":"sysdesign","cardId":"api-design-rest-grpc-graphql--pagination-and-versioning","front":"How do you paginate a large collection, and how do you evolve an API without breaking clients?","back":"Use cursor-based pagination, not offset. `OFFSET 100000` makes the database scan and discard 100,000 rows, so page 10,000 is catastrophically slow, and rows inserted while the user pages cause items to be skipped or duplicated. A cursor encodes the last seen sort key and becomes a `WHERE (created_at, id) < (?, ?)` predicate that uses the index directly - constant time regardless of depth, and stable under concurrent inserts. For versioning, prefer additive, backwards-compatible changes; when you must break, version in the URL path for public APIs and run both versions concurrently with a published deprecation window.","keyPoints":["Cursor pagination is O(log n) and stable; offset is O(n) and drifts.","Always add a unique tie-breaker to the sort and the cursor, using a tuple comparison.","Make cursors opaque so the sort key stays an implementation detail.","Additive changes are free; breaking changes need dual running and usage telemetry."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql","moduleLabel":"System Design"},{"key":"sysdesign:realtime-communication-websockets-sse-polling--polling-vs-sse-vs-websockets","moduleId":"sysdesign","cardId":"realtime-communication-websockets-sse-polling--polling-vs-sse-vs-websockets","front":"Compare short polling, long polling, Server-Sent Events and WebSockets. When do you use each?","back":"Short polling asks on a timer - simple, stateless, wasteful, and latency equal to half the interval. Long polling holds the request open until there is news, giving near-real-time delivery over ordinary HTTP but tying up a connection per client. Server-Sent Events is a one-way server-to-client stream over plain HTTP with automatic reconnection and event IDs built in, which covers most notification use cases. WebSockets give a full-duplex persistent connection and are the right answer only when the client also needs to send frequently - chat, collaborative editing, multiplayer. Choose the simplest one that meets the latency requirement, because each step up costs you statefulness.","keyPoints":["Pick the simplest option meeting the latency requirement; each step up adds statefulness.","SSE covers most one-way cases and gives reconnection plus resumption for free.","WebSockets are justified by frequent client→server traffic, not by 'real time'.","Long polling is a legacy fallback, not a default."],"href":"/system-design-interview/questions/realtime-communication-websockets-sse-polling","moduleLabel":"System Design"},{"key":"sysdesign:realtime-communication-websockets-sse-polling--scaling-websockets","moduleId":"sysdesign","cardId":"realtime-communication-websockets-sse-polling--scaling-websockets","front":"How do you scale a WebSocket service to millions of concurrent connections?","back":"Separate the connection tier from the business logic. Stateless gateway nodes hold the sockets and do nothing but authenticate, decode and forward; a registry maps user ID to the gateway currently holding that user's connection; and a pub/sub layer fans messages out to the right gateway. Each node can hold roughly 50,000–200,000 connections given enough file descriptors and memory, so a million connections is 5–20 nodes. The genuinely hard parts are not throughput but reconnect storms, deploys that drop every connection at once, and presence - knowing who is actually online.","keyPoints":["Split dumb connection gateways from stateless business logic.","Registry (user → gateway) plus pub/sub fan-out removes gateway-to-gateway coupling.","Exponential backoff with full jitter is what prevents reconnect storms.","Sequence numbers plus a durable store make reconnects gap-free.","Presence is approximate: heartbeat plus TTL, never a correctness dependency."],"href":"/system-design-interview/questions/realtime-communication-websockets-sse-polling","moduleLabel":"System Design"},{"key":"sysdesign:database-indexes-and-query-performance--how-indexes-work","moduleId":"sysdesign","cardId":"database-indexes-and-query-performance--how-indexes-work","front":"How does a database index actually work, and why does adding one slow down writes?","back":"An index is a separate sorted data structure - usually a B+ tree - mapping column values to row locations. It turns an O(n) table scan into an O(log n) tree descent, typically three or four disk pages instead of millions. Writes slow down because every insert, update or delete must also update every index on that table, each of which is an additional random write plus possible page splits. So indexes trade write throughput and disk space for read speed, and a table with twelve indexes can be several times slower to write than the same table with two.","keyPoints":["B+ tree indexes turn O(n) scans into ~4 page reads regardless of table size.","Every index multiplies write cost; page splits and write amplification make it worse.","Sequential primary keys avoid random page splits - UUIDv4 is a real throughput tax.","Composite indexes obey the leftmost-prefix rule; put equality columns before range columns.","Covering indexes avoid the table entirely; low-selectivity indexes get ignored."],"href":"/system-design-interview/questions/database-indexes-and-query-performance","moduleLabel":"System Design"},{"key":"sysdesign:database-indexes-and-query-performance--btree-vs-lsm","moduleId":"sysdesign","cardId":"database-indexes-and-query-performance--btree-vs-lsm","front":"What is the difference between a B-tree and an LSM-tree storage engine, and how does that choice show up in a system design?","back":"A B-tree updates data in place: writes are random I/O but reads are a single predictable tree descent. An LSM-tree buffers writes in memory, flushes them as sorted immutable files, and merges those files in the background - so writes are sequential and fast, but a read may have to check several files, making reads slower and less predictable. B-trees power Postgres, MySQL InnoDB and most relational systems and suit read-heavy or read-modify-write workloads. LSM-trees power Cassandra, RocksDB, LevelDB, ScyllaDB and HBase and suit write-heavy, append-oriented workloads such as time series, event logs and metrics.","keyPoints":["B-tree: in-place, random writes, predictable single-descent reads.","LSM: sequential writes via memtable and immutable SSTables, reads merge several files.","Bloom filters make LSM reads practical by skipping files that cannot contain the key.","Write-heavy/append → LSM; read-heavy with updates → B-tree.","Compaction causes tail-latency spikes and is the main operational cost of LSM."],"href":"/system-design-interview/questions/database-indexes-and-query-performance","moduleLabel":"System Design"},{"key":"sysdesign:database-indexes-and-query-performance--slow-query-debugging","moduleId":"sysdesign","cardId":"database-indexes-and-query-performance--slow-query-debugging","front":"A query that used to run in 10 ms now takes 8 seconds and nothing was deployed. How do you debug it?","back":"Start with EXPLAIN ANALYZE and compare the planner's estimated rows with the actual rows - a large divergence means stale statistics and a bad plan. Then check the four usual causes: data growth crossing a threshold that flipped the plan from index scan to sequential scan, stale or missing statistics after a bulk load, lock contention or long-running transactions blocking progress, and a change in parameter values causing parameter-sniffing to reuse a plan that suits a different value. Confirm with the plan, not with intuition.","keyPoints":["EXPLAIN ANALYZE first; compare estimated to actual rows.","Plan flips (index → sequential scan) are the classic overnight regression.","Stale statistics after a bulk load cause bad plans with no code change.","Check lock waits and vacuum backlog before blaming the query.","Close with prevention: timeouts, slow-query capture, latency alerting."],"href":"/system-design-interview/questions/database-indexes-and-query-performance","moduleLabel":"System Design"},{"key":"sysdesign:sql-vs-nosql-choosing-a-database--database-families","moduleId":"sysdesign","cardId":"sql-vs-nosql-choosing-a-database--database-families","front":"Walk me through the main database families and what each is genuinely good at.","back":"Relational for structured data with relationships, transactions and ad-hoc queries. Document for self-contained aggregates with a flexible schema and a natural read-whole-object pattern. Key-value for the fastest possible lookup by a single known key - sessions, caches, feature flags. Wide-column for enormous write volumes with predictable query patterns and no joins. Graph when the relationships themselves are the data and you traverse many hops. Time series for append-only measurements queried by time range with automatic downsampling. Most real systems use two or three of these deliberately.","keyPoints":["Pick by access pattern, not by SQL/NoSQL label.","Relational = query flexibility; non-relational = shape the data around known queries.","Postgres is a legitimate default well past the scale most candidates assume.","Justify with a constraint (throughput, access pattern, retention), never with 'it scales'.","One source of truth; derived stores must be rebuildable and fed by CDC or an outbox."],"href":"/system-design-interview/questions/sql-vs-nosql-choosing-a-database","moduleLabel":"System Design"},{"key":"sysdesign:sql-vs-nosql-choosing-a-database--denormalization","moduleId":"sysdesign","cardId":"sql-vs-nosql-choosing-a-database--denormalization","front":"When should you denormalise, and what does it cost you?","back":"Denormalise when a read path is hot enough that the join cost dominates and the duplicated data changes rarely relative to how often it is read. The cost is that every copy must be updated on write, so you trade cheap reads for expensive, error-prone writes and the permanent risk of copies drifting apart. Normalise by default, measure, then denormalise the specific hot path - and make the update path a single owned code path, ideally driven by an event rather than scattered across the codebase.","keyPoints":["Normalise first; denormalise a measured hot path, not speculatively.","Copy the minimum number of fields, not whole entities.","Denormalising immutable or slow-changing data is cheap; fast-changing data is not.","Drive updates from a single event-based path, never scattered writes.","Build a reconciliation job - copies will drift."],"href":"/system-design-interview/questions/sql-vs-nosql-choosing-a-database","moduleLabel":"System Design"},{"key":"sysdesign:acid-transactions-and-isolation-levels--acid-explained","moduleId":"sysdesign","cardId":"acid-transactions-and-isolation-levels--acid-explained","front":"Explain ACID, and which property is hardest to keep in a distributed system.","back":"Atomicity means all-or-nothing. Consistency means the transaction moves the database from one valid state to another, respecting constraints. Isolation means concurrent transactions do not observe each other's partial work. Durability means a committed write survives a crash. In a distributed system, isolation is by far the hardest - atomicity across nodes is solvable with two-phase commit, and durability with replication, but providing serializable isolation across partitions requires global coordination that costs latency on every operation.","keyPoints":["A = all-or-nothing, C = constraints hold, I = no visible partial work, D = survives crashes.","ACID's C is constraint validity; CAP's C is linearizability. Different things.","Isolation is the hardest property to provide across nodes.","Durability is a spectrum: buffer → fsync → quorum replication, each costing latency."],"href":"/system-design-interview/questions/acid-transactions-and-isolation-levels","moduleLabel":"System Design"},{"key":"sysdesign:acid-transactions-and-isolation-levels--isolation-levels","moduleId":"sysdesign","cardId":"acid-transactions-and-isolation-levels--isolation-levels","front":"What are the SQL isolation levels, which anomalies does each prevent, and which one should you use?","back":"Read Uncommitted allows dirty reads and is essentially never useful. Read Committed prevents dirty reads but allows non-repeatable reads and phantoms - it is the Postgres default. Repeatable Read gives a stable snapshot for the transaction's duration, preventing non-repeatable reads and, in Postgres and InnoDB, phantoms too; it is MySQL's default. Serializable behaves as if transactions ran one at a time, preventing everything, at the cost of aborts or lock contention. Default to Read Committed, and use Serializable specifically for transactions that read data and then write based on what they read.","keyPoints":["Read Committed is the common default and permits non-repeatable reads and phantoms.","Write skew survives everything below Serializable - know the on-call doctors example.","Prefer atomic in-database updates over read-modify-write.","Optimistic for low contention, pessimistic for hot rows; never hold a lock across user think-time.","MVCC means readers and writers do not block each other, at the cost of vacuum pressure."],"href":"/system-design-interview/questions/acid-transactions-and-isolation-levels","moduleLabel":"System Design"},{"key":"sysdesign:database-replication-and-sharding--replication-lag","moduleId":"sysdesign","cardId":"database-replication-and-sharding--replication-lag","front":"A user updates their profile and immediately sees the old value. What happened, and how do you fix it?","back":"The write went to the primary and the subsequent read was served by a replica that had not yet applied it - replication lag. The fix is read-your-writes consistency, and there are three standard approaches: route that user's reads to the primary for a short window after they write (or pin their whole session there), have the client pass the log position it wrote at and wait for a replica to catch up, or make the UI optimistic and render the value it just submitted. Sticking a session to one replica does not help - that gives monotonic reads, not read-your-writes. Route-to-primary-after-write is the usual pragmatic choice.","keyPoints":["Stale reads after a write are replication lag, not a bug.","Read-your-writes via a short primary-read window is the common pragmatic fix.","Distinguish read-your-writes, monotonic reads and consistent prefix by name.","Alert on replication lag and fail back to the primary when it exceeds your window.","Semi-synchronous replication is the usual durability/latency compromise."],"href":"/system-design-interview/questions/database-replication-and-sharding","moduleLabel":"System Design"},{"key":"sysdesign:database-replication-and-sharding--sharding-strategies","moduleId":"sysdesign","cardId":"database-replication-and-sharding--sharding-strategies","front":"How do you shard a database, and how do you choose the shard key?","back":"Split data across independent databases by a shard key. Range partitioning keeps ranges together - great for range scans, terrible for hotspots, since recent data all lands on one shard. Hash partitioning distributes evenly but destroys range queries. Directory partitioning uses an explicit lookup table, giving full flexibility at the cost of an extra hop and a component that must not become a bottleneck. Choose a key that is present on almost every query, has high cardinality, and distributes evenly - and accept that queries not containing the key must scatter-gather across every shard.","keyPoints":["Replication scales reads; sharding scales writes and storage.","Shard key must be on most queries, high cardinality, evenly distributed, and colocate related rows.","Hot shards are solved with compound keys, dedicated shards for whales, or caching.","Sharding costs joins, transactions, global uniqueness and operational simplicity.","Logical shards mapped to physical servers make resharding a move, not a rehash."],"href":"/system-design-interview/questions/database-replication-and-sharding","moduleLabel":"System Design"},{"key":"sysdesign:caching-strategies-and-eviction-policies--caching-patterns","moduleId":"sysdesign","cardId":"caching-strategies-and-eviction-policies--caching-patterns","front":"Compare cache-aside, read-through, write-through and write-back. Which do you default to?","back":"Cache-aside puts the application in charge: check the cache, on a miss read the database and populate. Read-through hides that behind the cache client. Write-through writes to cache and database together, keeping them consistent at the cost of write latency and caching data nobody reads. Write-back writes only to the cache and flushes later, which is the fastest and the only one that can lose data. Cache-aside is the default for almost every system because it is simple, resilient to cache outages, and only caches what is actually read.","keyPoints":["Cache-aside is the default: simple, survives cache loss, caches only what is read.","Write to the database first, then delete the cache key - never write the value in.","Cache negative results briefly to stop lookups for nonexistent keys hammering the DB.","Version keys so a schema change is a deploy, not a mass purge.","Each caching layer trades latency against invalidation difficulty."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies","moduleLabel":"System Design"},{"key":"sysdesign:caching-strategies-and-eviction-policies--cache-failure-modes","moduleId":"sysdesign","cardId":"caching-strategies-and-eviction-policies--cache-failure-modes","front":"What are cache stampedes, penetration and avalanche - and how do you prevent each?","back":"A stampede happens when a hot key expires and thousands of concurrent requests all miss and hit the database at once - prevent it with a lock so one request recomputes while the others wait or serve stale. Penetration is repeated requests for keys that do not exist, so the cache never helps - prevent it by caching negative results and using a Bloom filter. Avalanche is many keys expiring simultaneously, usually because they were populated together with identical TTLs - prevent it by adding random jitter to every TTL.","keyPoints":["Stampede: one expiring hot key can take down the database - lock or recompute early.","Penetration: cache negative results and front with a Bloom filter.","Avalanche: always add random jitter to TTLs.","Plan capacity for a zero-hit-rate scenario; a cache outage must not cascade.","Serving stale while revalidating is usually acceptable and removes an entire class of failure."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies","moduleLabel":"System Design"},{"key":"sysdesign:caching-strategies-and-eviction-policies--eviction-policies","moduleId":"sysdesign","cardId":"caching-strategies-and-eviction-policies--eviction-policies","front":"How do LRU, LFU and TTL eviction differ, and how do you size a cache?","back":"LRU evicts what was used least recently - cheap, and it adapts fast to changing access patterns, but a single large scan can wipe the whole working set. LFU evicts what is used least often - it protects genuinely hot keys from scans, but adapts slowly and needs frequency decay or yesterday's popular items never leave. TTL is not really eviction, it is a freshness bound, and you almost always want it alongside a size-based policy. Size the cache by measuring the working set: plot hit rate against memory and find the knee, because past that point additional memory buys almost nothing.","keyPoints":["LRU adapts fast but is scan-vulnerable; LFU resists scans but adapts slowly.","Use TTL for freshness alongside a size-based eviction policy, not instead of one.","Size by the knee of the hit-rate curve - usually ~10% of the dataset.","Track origin load and tail latency, not just hit rate.","Some data should never be cached; write-heavy and low-reuse data are the clearest cases."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies","moduleLabel":"System Design"},{"key":"sysdesign:cdn-and-edge-caching--how-cdn-works","moduleId":"sysdesign","cardId":"cdn-and-edge-caching--how-cdn-works","front":"How does a CDN work, and what should and should not go through it?","back":"A CDN is a network of points of presence worldwide. DNS or anycast routing directs a user to the nearest PoP; if that PoP has a fresh copy it serves it in tens of milliseconds, and if not it fetches from origin, caches it, and serves subsequent requests locally. Put static assets, images, video, downloads and cacheable API responses through it. Keep personalised, authenticated and rapidly changing content on the origin - or use edge compute so the dynamic part is assembled near the user while the static shell still comes from cache.","keyPoints":["Anycast or GeoDNS routes users to the nearest PoP; the edge caches per response headers.","The cache key determines hit rate - strip irrelevant query parameters.","Origin shielding turns N PoP misses into one origin request per region.","Static and media content are the obvious wins; personalised content usually is not.","Pull is the default; push suits predictable, large, hot content."],"href":"/system-design-interview/questions/cdn-and-edge-caching","moduleLabel":"System Design"},{"key":"sysdesign:cdn-and-edge-caching--cache-control-headers","moduleId":"sysdesign","cardId":"cdn-and-edge-caching--cache-control-headers","front":"Which HTTP caching headers control CDN and browser behaviour, and how do you invalidate content?","back":"`Cache-Control` is the primary control: `max-age` for browsers, `s-maxage` for shared caches, `public` versus `private`, `no-store` to forbid caching entirely, and `stale-while-revalidate` to serve stale content while refreshing in the background. `ETag` and `Last-Modified` enable revalidation, letting the server return a 304 with no body. For invalidation, the best strategy is to avoid it: use content-hashed immutable URLs so a new version is a new URL. When you must purge, prefer surrogate keys - tag responses and purge by tag - over purging URLs one at a time.","keyPoints":["`s-maxage` targets shared caches; `max-age` targets browsers - set them differently.","`stale-while-revalidate` removes expiry-driven latency spikes and edge stampedes.","ETag revalidation saves bandwidth but not the round trip.","Content-hashed immutable URLs make invalidation unnecessary.","Surrogate keys are the only invalidation strategy that scales; purge-all is an emergency tool."],"href":"/system-design-interview/questions/cdn-and-edge-caching","moduleLabel":"System Design"},{"key":"sysdesign:horizontal-vs-vertical-scaling--vertical-vs-horizontal","moduleId":"sysdesign","cardId":"horizontal-vs-vertical-scaling--vertical-vs-horizontal","front":"When do you scale vertically and when do you scale horizontally?","back":"Scale vertically first because it requires no code changes and modern machines are enormous - hundreds of cores and terabytes of RAM. Switch to horizontal when you hit the ceiling of a single machine, when the cost curve turns superlinear (the biggest instances cost disproportionately more per unit of capacity), or when you need redundancy, because one machine is a single point of failure regardless of how big it is. In practice, redundancy forces horizontal scaling long before capacity does.","keyPoints":["Scale vertically first; it needs no code change and modern machines are huge.","Redundancy usually forces horizontal scaling before capacity does.","Statelessness is the precondition - move session, files and counters out of the instance.","Autoscale on a leading signal, out fast and in slow, with a floor and a ceiling.","The database is the hard part; the app tier is the easy part."],"href":"/system-design-interview/questions/horizontal-vs-vertical-scaling","moduleLabel":"System Design"},{"key":"sysdesign:load-balancing-algorithms--lb-algorithms","moduleId":"sysdesign","cardId":"load-balancing-algorithms--lb-algorithms","front":"Compare load balancing algorithms. Which would you choose and why?","back":"Round robin is simple and fine when every server and every request is roughly identical. Least connections adapts to uneven request cost and is the usual default for heterogeneous workloads. Weighted variants handle servers of different sizes. Consistent hashing routes the same key to the same server, which matters for cache locality and sticky routing. In practice the best general-purpose choice is power of two choices: sample two backends at random and pick the less loaded one - nearly the quality of least connections with none of its coordination cost or herd behaviour.","keyPoints":["Power of two choices is the best general default: near-optimal, no coordination.","Least connections is dangerous alone - a fast-failing backend attracts all traffic.","Outlier ejection on error rate is what protects you from that.","Separate liveness from readiness; never let a shared dependency mark the whole fleet unready.","Drain connections before terminating, or expect 502s on every deploy."],"href":"/system-design-interview/questions/load-balancing-algorithms","moduleLabel":"System Design"},{"key":"sysdesign:load-balancing-algorithms--retry-amplification","moduleId":"sysdesign","cardId":"load-balancing-algorithms--retry-amplification","front":"A downstream service slows down and your whole system collapses. What happened?","back":"Retry amplification. When a service slows, callers time out and retry, which multiplies the load on an already-struggling service. With three layers each making three attempts, one user request becomes 27 backend requests exactly when the backend can handle fewest. The service gets slower, more retries fire, and the system collapses. Fixes are retry budgets rather than fixed retry counts, exponential backoff with jitter, circuit breakers, load shedding at the server, and retrying at only one layer of the stack.","keyPoints":["Retries multiply across layers: 3 layers × 3 attempts = 27× load.","Retry budgets stop retrying during a broad outage; fixed counts make it worse.","Retry at one layer, back off exponentially, and always add full jitter.","Circuit breakers give a failing dependency room to recover.","Timeouts must shrink with depth - propagate a deadline instead of hard-coding."],"href":"/system-design-interview/questions/load-balancing-algorithms","moduleLabel":"System Design"},{"key":"sysdesign:consistent-hashing-explained--consistent-hashing","moduleId":"sysdesign","cardId":"consistent-hashing-explained--consistent-hashing","front":"What problem does consistent hashing solve, and how does the ring work?","back":"Modulo hashing remaps almost every key when the server count changes, which is catastrophic for caches and expensive for sharded data. Consistent hashing maps both keys and servers onto the same circular hash space; a key belongs to the first server encountered clockwise from its position. Adding or removing a server only affects keys between it and its neighbour, so on average only K/N keys move instead of nearly all of them. Virtual nodes - placing each physical server at many points on the ring - are what make the distribution even in practice.","keyPoints":["Modulo hashing remaps ~N/(N+1) of keys on resize; consistent hashing moves ~1/(N+1).","Key belongs to the first node clockwise; lookup is a binary search over sorted positions.","Virtual nodes (100–200 per server) are required for even distribution and graceful removal.","Replication walks clockwise for distinct physical nodes, skipping shared failure domains.","Hot keys are a separate problem; consider bounded loads or key replication."],"href":"/system-design-interview/questions/consistent-hashing-explained","moduleLabel":"System Design"},{"key":"sysdesign:cap-theorem-and-pacelc--cap-theorem","moduleId":"sysdesign","cardId":"cap-theorem-and-pacelc--cap-theorem","front":"State the CAP theorem precisely and explain why 'pick two' is misleading.","back":"CAP says that during a network partition, a distributed system must choose between consistency - every read returns the most recent write or an error - and availability - every request receives a non-error response, possibly stale. Partition tolerance is not a choice: networks fail, so any real distributed system must tolerate partitions. That makes CAP a conditional statement about behaviour during a partition, not a menu of three items. 'CA' systems do not exist in a distributed setting; a single-node database is CA only because it is not distributed.","keyPoints":["P is not optional; CAP is a conditional about behaviour during a partition.","C means linearizability, not 'the data is valid' - that is ACID's C.","PACELC adds the everyday trade: latency versus consistency with no partition present.","Most databases are tunable per request rather than fixed at CP or AP.","Different features in one product can and should make different choices."],"href":"/system-design-interview/questions/cap-theorem-and-pacelc","moduleLabel":"System Design"},{"key":"sysdesign:consistency-models-and-replication--consistency-models","moduleId":"sysdesign","cardId":"consistency-models-and-replication--consistency-models","front":"Order the main consistency models from strongest to weakest, and say what each guarantees.","back":"Linearizability is strongest: operations appear to occur instantaneously at some point between invocation and response, so the system behaves like a single copy and reads always see the latest completed write. Sequential consistency preserves each client's program order but allows a global order that is not real time. Causal consistency guarantees that causally related operations are seen in order while concurrent ones may differ per observer. Then come the session guarantees - read-your-writes, monotonic reads, consistent prefix - and finally eventual consistency, which promises only that replicas converge if writes stop.","keyPoints":["Linearizable → sequential → causal → session guarantees → eventual, in decreasing strength and cost.","Causal consistency prevents the anomalies users actually notice, cheaply.","R + W > N guarantees overlap, but read repair and anti-entropy are what deliver convergence.","Multi-leader buys write availability and costs you conflict resolution.","LWW silently loses data; CRDTs make conflicts impossible by construction."],"href":"/system-design-interview/questions/consistency-models-and-replication","moduleLabel":"System Design"},{"key":"sysdesign:consensus-and-leader-election--raft-consensus","moduleId":"sysdesign","cardId":"consensus-and-leader-election--raft-consensus","front":"Explain how Raft works and why a majority quorum prevents split brain.","back":"Raft elects a single leader per term. Followers who stop hearing heartbeats become candidates, increment the term and request votes; a node votes at most once per term, so at most one candidate can win a majority. The leader accepts all writes, appends them to its log, replicates to followers, and commits an entry once a majority have stored it. Split brain is impossible because two disjoint majorities of the same set cannot exist - any two majorities of N nodes must share at least one member, and that member's single vote per term prevents a second leader.","keyPoints":["Raft: randomised election timeouts, one vote per node per term, majority to win.","Two majorities of the same set must overlap, which makes split brain impossible.","Always odd cluster sizes; 4 nodes tolerate no more failures than 3.","The minority side becomes unavailable, never inconsistent.","Use consensus for rarely-changing metadata, never on the per-request data path."],"href":"/system-design-interview/questions/consensus-and-leader-election","moduleLabel":"System Design"},{"key":"sysdesign:consensus-and-leader-election--distributed-locks","moduleId":"sysdesign","cardId":"consensus-and-leader-election--distributed-locks","front":"Implement a distributed lock with Redis. Why is the naive version unsafe, and what fixes it?","back":"The naive version is `SET key value NX PX ttl` plus a delete on release, and it is unsafe for two reasons. First, releasing must verify ownership atomically - otherwise a client whose lock expired can delete a lock now held by someone else, which requires a Lua script comparing the token. Second, and more fundamentally, a TTL-based lock cannot guarantee mutual exclusion: a client can be paused by GC or a network delay, its lock expires, another client acquires it, and then the first client wakes up and acts believing it still holds the lock. The only real fix is a monotonically increasing fencing token that the protected resource itself checks and rejects if stale.","keyPoints":["`SET NX PX` to acquire; release must be an atomic compare-and-delete via Lua.","TTL locks cannot guarantee mutual exclusion - pauses are unbounded.","Fencing tokens enforced at the resource are the only real fix.","Distinguish efficiency locks (best-effort is fine) from correctness locks.","Prefer database constraints or partitioned consumers over distributed locks."],"href":"/system-design-interview/questions/consensus-and-leader-election","moduleLabel":"System Design"},{"key":"sysdesign:distributed-transactions-and-idempotency--2pc-vs-saga","moduleId":"sysdesign","cardId":"distributed-transactions-and-idempotency--2pc-vs-saga","front":"An order must reserve inventory, charge payment and create a shipment across three services. How do you keep it consistent?","back":"Two-phase commit gives real atomicity but requires every participant to hold locks until the coordinator decides, and if the coordinator dies mid-decision the participants block indefinitely - unacceptable across services and impossible with an external payment provider. The practical answer is a saga: a sequence of local transactions, each with a compensating action, coordinated either by choreography through events or by an orchestrator. You give up isolation and accept that intermediate states are visible, in exchange for availability and no distributed locks.","keyPoints":["2PC gives atomicity but blocks on coordinator failure and cannot span external APIs.","Sagas trade isolation for availability: local transactions plus compensations.","Orchestration for complex flows, choreography for two or three steps.","Order irreversible steps last; prefer reserve-then-confirm.","Sagas lack isolation - use semantic locks and re-validation."],"href":"/system-design-interview/questions/distributed-transactions-and-idempotency","moduleLabel":"System Design"},{"key":"sysdesign:distributed-transactions-and-idempotency--exactly-once","moduleId":"sysdesign","cardId":"distributed-transactions-and-idempotency--exactly-once","front":"Is exactly-once delivery possible? How do you build an exactly-once pipeline in practice?","back":"Exactly-once delivery is impossible over an unreliable network - the sender can never distinguish a lost message from a lost acknowledgement, so it must either risk losing it or risk sending it twice. What is achievable is exactly-once processing: at-least-once delivery combined with idempotent consumers that deduplicate by message ID, plus atomic commit of the side effect and the dedup record. The transactional outbox pattern extends this to publishing, writing the message into the same database transaction as the state change so you cannot commit one without the other.","keyPoints":["Exactly-once delivery is impossible; exactly-once processing is at-least-once plus dedup.","The transactional outbox removes the dual-write window entirely.","Commit the dedup record and the side effect in one transaction.","Pass idempotency keys to external providers so they deduplicate too.","Dedup windows are bounded - state the retention and the residual risk."],"href":"/system-design-interview/questions/distributed-transactions-and-idempotency","moduleLabel":"System Design"},{"key":"sysdesign:message-queues-and-event-streams--queue-vs-log","moduleId":"sysdesign","cardId":"message-queues-and-event-streams--queue-vs-log","front":"What is the difference between a message queue like SQS or RabbitMQ and a log like Kafka?","back":"A queue holds work: a message is delivered to one consumer, acknowledged, and deleted. It is a job dispatcher, and it scales by adding competing consumers. A log holds an ordered, durable, replayable record: messages are appended and retained for a configured period, and each consumer group tracks its own offset independently. Many groups can read the same data without affecting one another, and a new consumer can replay history from the beginning. Choose a queue for task distribution, and a log when several independent consumers need the same events, or when replay matters.","keyPoints":["Queue = who does this work; log = what happened, replayably, for many consumers.","Queues shift latency and level load; they do not make work faster.","Every mainstream broker is at-least-once - consumers must be idempotent.","Backpressure is unavoidable when λ > μ; scale, shed, throttle or bound.","Alert on oldest-message age, and always configure and watch a DLQ."],"href":"/system-design-interview/questions/message-queues-and-event-streams","moduleLabel":"System Design"},{"key":"sysdesign:kafka-architecture-and-delivery-semantics--kafka-partitions-ordering","moduleId":"sysdesign","cardId":"kafka-architecture-and-delivery-semantics--kafka-partitions-ordering","front":"How does Kafka guarantee ordering, and how do you choose the number of partitions?","back":"Kafka guarantees ordering within a partition only - never across partitions. Messages with the same key always land in the same partition, so per-key ordering is achieved by keying on the entity that needs it, such as user ID or order ID. Partition count is the unit of consumer parallelism: you cannot have more useful consumers in a group than partitions. Size it from target throughput divided by per-consumer throughput, add headroom, and remember you can increase partitions later but never decrease them - and increasing them changes the key-to-partition mapping, breaking ordering for in-flight keys.","keyPoints":["Ordering is per partition; key by entity to get per-key ordering.","Partition count caps consumer parallelism and cannot be reduced.","Adding partitions remaps keys and breaks ordering across the change.","RF=3 with acks=all and min.insync.replicas=2 is the durability sweet spot.","Watch per-partition consumer lag in time units; use cooperative rebalancing."],"href":"/system-design-interview/questions/kafka-architecture-and-delivery-semantics","moduleLabel":"System Design"},{"key":"sysdesign:monolith-vs-microservices--when-to-split","moduleId":"sysdesign","cardId":"monolith-vs-microservices--when-to-split","front":"When should you split a monolith into microservices, and when should you not?","back":"Split when teams block each other: when a deploy requires coordinating several teams, when one component needs a radically different scaling or reliability profile, or when a subsystem genuinely needs a different technology stack. Do not split because the codebase is large, because the architecture diagram would look more modern, or before you know where the boundaries are. Below roughly 20–30 engineers, a modular monolith with enforced internal boundaries gives you most of the benefit and almost none of the cost.","keyPoints":["Microservices solve an organisational problem: independent deployment by independent teams.","Availability multiplies down across critical-path services.","A distributed monolith has all the cost and none of the benefit - test with 'can it deploy alone?'.","Modular monolith first; boundaries are cheap to move before they are network calls.","Migrate with the strangler fig, starting from a leaf capability that owns its data."],"href":"/system-design-interview/questions/monolith-vs-microservices","moduleLabel":"System Design"},{"key":"sysdesign:api-gateway-and-service-communication--gateway-responsibilities","moduleId":"sysdesign","cardId":"api-gateway-and-service-communication--gateway-responsibilities","front":"What belongs in an API gateway, what belongs in a service mesh, and what should stay in the service?","back":"The gateway owns edge concerns for untrusted external traffic: TLS termination, authentication, rate limiting per API key, request validation, routing and response caching. The mesh owns transport concerns between trusted internal services: mTLS, retries, timeouts, circuit breaking, load balancing and telemetry, implemented as a sidecar so it is uniform across languages. Business logic, authorisation decisions that depend on domain state, and data validation belong in the service - the classic failure is a gateway that accumulates business rules until it becomes an undeployable monolith nobody owns.","keyPoints":["Gateway = north-south edge concerns; mesh = east-west transport concerns.","Authenticate at the edge, authorise in the service where the domain state lives.","A BFF is owned by the client team, aggregates calls, and holds no business logic.","A mesh pays off above roughly 10–15 services or with multiple languages.","Never let business rules accumulate in the gateway."],"href":"/system-design-interview/questions/api-gateway-and-service-communication","moduleLabel":"System Design"},{"key":"sysdesign:event-driven-architecture-cqrs-and-event-sourcing--events-vs-commands","moduleId":"sysdesign","cardId":"event-driven-architecture-cqrs-and-event-sourcing--events-vs-commands","front":"What is the difference between an event and a command, and what should an event contain?","back":"A command is an instruction to a specific handler to do something, named imperatively - `ChargePayment` - and it can be rejected. An event is a statement that something already happened, named in the past tense - `PaymentCharged` - and cannot be rejected because it is history. Commands have one intended handler; events have zero or many subscribers. On content, prefer events that carry enough state for common consumers to act without calling back, but include the entity ID and a version so a consumer that needs more can fetch it.","keyPoints":["Commands are imperative, singular and rejectable; events are past tense, broadcast and factual.","Include IDs, timestamp, sequence/version, trace ID and the commonly needed fields.","A version number lets consumers detect out-of-order delivery.","Event schemas are public contracts - additive changes and a registry from day one."],"href":"/system-design-interview/questions/event-driven-architecture-cqrs-and-event-sourcing","moduleLabel":"System Design"},{"key":"sysdesign:event-driven-architecture-cqrs-and-event-sourcing--cqrs-event-sourcing","moduleId":"sysdesign","cardId":"event-driven-architecture-cqrs-and-event-sourcing--cqrs-event-sourcing","front":"Explain CQRS and event sourcing. When is each worth the complexity?","back":"CQRS separates the write model from the read model so each can be optimised independently - normalised and validated for writes, denormalised and query-shaped for reads, kept in sync asynchronously. It is worth it when read and write workloads differ dramatically in shape or volume. Event sourcing goes further: the immutable event log becomes the source of truth and current state is a projection of it, giving a perfect audit trail and the ability to rebuild any view or answer historical questions. It is worth it in genuinely event-shaped domains - finance, ledgers, order lifecycles - and is usually a mistake elsewhere, because you inherit schema versioning, replay cost, snapshotting and the loss of simple ad-hoc queries.","keyPoints":["CQRS separates read and write models; event sourcing makes the event log the source of truth.","Projections are disposable and rebuildable - that is the main practical superpower.","Event sourcing costs schema versioning, replay, snapshots and GDPR complexity.","It fits genuinely event-shaped domains: ledgers, order lifecycles, regulated audit.","For most 'we need history' requirements, an audit-log table gets 80% for 10% of the cost."],"href":"/system-design-interview/questions/event-driven-architecture-cqrs-and-event-sourcing","moduleLabel":"System Design"},{"key":"sysdesign:designing-for-failure--bulkheads-and-degradation","moduleId":"sysdesign","cardId":"designing-for-failure--bulkheads-and-degradation","front":"How do you stop one failing dependency from taking down your whole service?","back":"Isolate resources with bulkheads so one slow dependency cannot consume the whole thread or connection pool, and design explicit graceful degradation so the feature that depends on it disappears rather than the page. The classic failure is a shared thread pool: one dependency slows from 50 ms to 5 s, every thread ends up blocked waiting on it, and requests that never touch that dependency start timing out too. Separate pools per dependency, combined with circuit breakers and a defined degraded mode per feature, contain the blast radius.","keyPoints":["Bulkheads: bounded per-dependency pools so one slow dependency cannot starve the rest.","Define degraded behaviour per feature in advance, including which must fail closed.","Fail-open versus fail-closed is a business risk decision - say so.","Chaos experiments need a hypothesis, business hours and abort criteria.","RTO/RPO drive the DR strategy; an unrestored backup is unverified."],"href":"/system-design-interview/questions/designing-for-failure","moduleLabel":"System Design"},{"key":"sysdesign:rate-limiting-algorithms--rate-limit-algorithms","moduleId":"sysdesign","cardId":"rate-limiting-algorithms--rate-limit-algorithms","front":"Compare rate limiting algorithms. Which would you implement and why?","back":"Token bucket refills tokens at a fixed rate up to a capacity, so it enforces an average rate while allowing bursts up to the bucket size - that flexibility makes it the usual default for APIs. Leaky bucket drains at a constant rate, smoothing traffic completely, which suits downstream systems that cannot absorb bursts at all. Fixed window is the simplest and has a serious flaw: a client can send a full window's quota at the end of one window and again at the start of the next, achieving double the intended rate. Sliding window log is exact but stores a timestamp per request; sliding window counter approximates it cheaply and is the right choice when precision matters more than burst tolerance.","keyPoints":["Token bucket is the default: average rate enforced, bursts permitted up to capacity.","Fixed window allows 2× the limit at boundaries - name this failure explicitly.","Sliding window counter is the accurate-but-cheap compromise.","Distributed: local buckets with periodic sync beat a per-request central counter.","Always return Retry-After and RateLimit headers, and limit on several dimensions."],"href":"/system-design-interview/questions/rate-limiting-algorithms","moduleLabel":"System Design"},{"key":"sysdesign:observability-logging-metrics-tracing--three-pillars","moduleId":"sysdesign","cardId":"observability-logging-metrics-tracing--three-pillars","front":"How do metrics, logs and traces differ, and what do you instrument first?","back":"Metrics are pre-aggregated numeric time series - cheap to store and query, ideal for alerting, but they cannot explain an individual request. Logs are discrete structured events with full context - ideal for investigation, expensive at scale. Traces stitch one request's spans across every service, showing where the latency and the failure actually occurred. Instrument metrics first because they drive alerting: for every service, the RED metrics - request rate, error rate and duration percentiles - get you most of the way.","keyPoints":["Metrics alert, logs explain, traces localise - you need all three.","RED for services, USE for resources; instrument these first.","Never put unbounded identifiers in metric labels - cardinality is multiplicative.","Propagate a trace ID into every log line and return it to the client.","Alert on user-visible symptoms, and make every page actionable."],"href":"/system-design-interview/questions/observability-logging-metrics-tracing","moduleLabel":"System Design"},{"key":"sysdesign:security-in-system-design--sessions-vs-jwt","moduleId":"sysdesign","cardId":"security-in-system-design--sessions-vs-jwt","front":"Sessions or JWTs? Explain the trade-off and how you would handle logout.","back":"Server-side sessions store state in Redis and hand the client an opaque ID: revocation is instant because you delete the record, at the cost of a lookup per request. JWTs are self-contained and signed, so any service can verify them without a lookup - but that same property means you cannot revoke one before it expires. The standard resolution is short-lived access tokens of 5–15 minutes paired with a long-lived refresh token that is stored server-side and therefore revocable. That gives you stateless verification on the hot path and a real logout.","keyPoints":["Sessions revoke instantly but need a lookup; JWTs verify statelessly but cannot be revoked.","Short access tokens plus revocable refresh tokens is the standard resolution.","Rotate refresh tokens and treat reuse as theft.","HttpOnly Secure SameSite cookies, never localStorage.","Zero trust: the network grants no authority; use mTLS and short-lived identities."],"href":"/system-design-interview/questions/security-in-system-design","moduleLabel":"System Design"},{"key":"sysdesign:security-in-system-design--encryption-and-secrets","moduleId":"sysdesign","cardId":"security-in-system-design--encryption-and-secrets","front":"How do you handle encryption and secrets management in a distributed system?","back":"Encrypt in transit with TLS 1.3 everywhere including internal traffic, and at rest with per-tenant or per-field keys managed by a KMS using envelope encryption - a data key encrypts the data, and the KMS master key encrypts the data key, so rotation re-encrypts keys rather than terabytes of data. Secrets belong in a managed secret store with short-lived dynamic credentials wherever possible, never in source control, container images or plain environment variables. For particularly sensitive fields, application-level encryption means a database compromise alone does not reveal the data.","keyPoints":["TLS 1.3 in transit including internal calls; mTLS between services.","Envelope encryption makes key rotation cheap - rotate keys, not terabytes.","Disk and TDE encryption protect against stolen media, not a compromised application.","Secrets in a manager with short-lived dynamic credentials; design for rotation from day one.","Defence in depth: prevent, limit, detect, contain - no single control is enough."],"href":"/system-design-interview/questions/security-in-system-design","moduleLabel":"System Design"},{"key":"sysdesign:design-a-url-shortener--url-id-generation","moduleId":"sysdesign","cardId":"design-a-url-shortener--url-id-generation","front":"How do you generate short codes? Compare hashing, counters and random generation.","back":"Hashing the URL and truncating produces collisions that you must detect and resolve, and it leaks that two users shortened the same link. A global counter encoded in base62 is collision-free and compact but produces sequential, guessable codes and needs a coordination point. The practical answer is a counter with per-host pre-allocated ranges, so each server allocates from memory with no coordination, combined with a bijective scramble of the integer before encoding so the output is not sequentially guessable. For private links, generate random codes and rely on a uniqueness constraint.","keyPoints":["7 base62 characters give 3.5 trillion codes - decades of headroom.","Range-allocated counters remove per-request coordination.","Scramble sequential IDs bijectively so codes are not enumerable.","Random codes plus a uniqueness constraint for private links.","Custom aliases require a conditional insert and a reserved-word list."],"href":"/system-design-interview/questions/design-a-url-shortener","moduleLabel":"System Design"},{"key":"sysdesign:design-a-url-shortener--url-redirect-path","moduleId":"sysdesign","cardId":"design-a-url-shortener--url-redirect-path","front":"Design the redirect path for 350,000 requests per second. 301 or 302?","back":"Layer the reads: CDN at the edge, Redis in the region, then the key-value store. Link popularity follows a power law, so a few gigabytes of cache serves well over 95% of traffic and the database sees only a few thousand QPS. On the status code, 301 is permanent and cacheable by browsers and proxies, which makes redirects nearly free but means you stop seeing repeat clicks and can never change the destination. 302 is temporary and uncached, so every click reaches you - full analytics and editable destinations, at the cost of full traffic. Shorteners that sell analytics either use 302 or send 301 with a short Cache-Control max-age, so repeat clicks keep reaching them.","keyPoints":["CDN + Redis + KV turns 350k QPS into ~3.5k QPS at the database.","301 is cacheable and kills analytics; 302 preserves analytics and costs full traffic.","Cache negative lookups - scanners probe nonexistent codes constantly.","Analytics is fire-and-forget, never on the redirect path.","Guard against open-redirect abuse and redirect loops."],"href":"/system-design-interview/questions/design-a-url-shortener","moduleLabel":"System Design"},{"key":"sysdesign:design-a-news-feed-system--fanout-write-vs-read","moduleId":"sysdesign","cardId":"design-a-news-feed-system--fanout-write-vs-read","front":"Compare fan-out on write and fan-out on read for a news feed. Which do you choose?","back":"Fan-out on write pushes each new post into every follower's precomputed feed, so reads are a single fast lookup - but a celebrity with 100 million followers generates 100 million writes for one post, which is unacceptable. Fan-out on read builds the feed at query time by fetching recent posts from everyone you follow, so writes are cheap but a read touches hundreds of timelines and cannot meet a 200 ms budget. The answer is hybrid: fan-out on write for ordinary users, and fan-out on read for the small number of accounts above a follower threshold, merging both at read time.","keyPoints":["Push for normal users (cheap writes, O(1) reads); pull for celebrities (avoid write amplification).","Merge both at read time - this is what every major platform does.","Fan out only to active users: a 70–90% reduction in work.","Store post IDs, not content, so edits and deletions propagate correctly.","Cap feed length; deeper pagination falls back to a pull query."],"href":"/system-design-interview/questions/design-a-news-feed-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-news-feed-system--feed-ranking-pagination","moduleId":"sysdesign","cardId":"design-a-news-feed-system--feed-ranking-pagination","front":"How do you rank and paginate the feed, and what breaks with offset pagination?","back":"Rank in two stages: cheap candidate generation to get a few hundred posts, then a scoring pass combining recency, affinity with the author, engagement signals and content type. Serve with cursor pagination, never offset - with a constantly changing feed, offset causes users to see duplicates and miss posts, because rows shift between requests. The cursor should encode the ranking position and a snapshot identifier so a scrolling session stays stable even as new posts arrive.","keyPoints":["Two-stage ranking: cheap recall, then expensive precision on a few hundred candidates.","Exponential recency decay plus affinity and predicted engagement.","Add a diversity penalty or the feed fills with one author.","Offset pagination guarantees duplicates on a changing feed - use cursors.","Pin the candidate set per scroll session and surface new posts explicitly."],"href":"/system-design-interview/questions/design-a-news-feed-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-chat-system--chat-message-delivery","moduleId":"sysdesign","cardId":"design-a-chat-system--chat-message-delivery","front":"How do you guarantee a message is delivered exactly once and in the right order?","back":"Assign each message a monotonically increasing sequence number per conversation, allocated server-side - never trust client clocks, because devices are skewed and users change time zones. Persist the message durably before acknowledging to the sender, then deliver at-least-once and let clients deduplicate by a client-generated message ID. On reconnect, the client sends its last-seen sequence number and the server backfills everything newer, so ordering and completeness both come from the sequence rather than from the transport.","keyPoints":["Server-assigned per-conversation sequence numbers, never client clocks.","Client-generated message IDs make retries idempotent.","Persist durably before acknowledging the sender.","Reconnect syncs by last-seen sequence - the same path as offline delivery.","The store is the source of truth; the socket is only transport."],"href":"/system-design-interview/questions/design-a-chat-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-chat-system--chat-group-fanout","moduleId":"sysdesign","cardId":"design-a-chat-system--chat-group-fanout","front":"How do you handle group chat with 100,000 members, and how do you store messages?","back":"Write the message once per conversation and give each member a cursor, rather than copying the message per member - 100,000 copies of every message is untenable in both write volume and storage. Store messages in a wide-column or sharded store partitioned by conversation ID and clustered by descending sequence, so 'the last 50 messages' is a single partition read. For very large groups, stop pushing to every member: deliver in real time only to members with an active connection and currently viewing, and let everyone else pull on open.","keyPoints":["Store one copy per conversation plus a cursor per member - never a copy per member.","Partition by conversation ID, cluster by descending sequence: last-50 is one partition read.","Cursors make unread counts subtraction and mark-as-read a single write.","Above a few thousand members, switch from push to pull-on-open.","Per-message read receipts do not scale - use counts or disable them for big groups."],"href":"/system-design-interview/questions/design-a-chat-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-notification-system--notification-dedup-preferences","moduleId":"sysdesign","cardId":"design-a-notification-system--notification-dedup-preferences","front":"How do you prevent duplicate notifications and respect user preferences?","back":"Route every notification through a single gate that owns both concerns. Deduplicate on a caller-supplied idempotency key stored with a TTL, so retries and duplicate events collapse into one send. Enforce preferences as a layered check: global opt-out, then per-category, then per-channel, then quiet hours in the user's own time zone, then a frequency cap. Critical transactional messages - password resets, security alerts, payment failures - bypass marketing preferences but must still be deduplicated and rate limited.","keyPoints":["A single gate owns preferences, quiet hours, frequency caps and deduplication.","Deduplicate on a caller-supplied idempotency key with a TTL.","Quiet hours use the user's time zone, and defer rather than drop.","Security and transactional messages bypass marketing preferences, not deduplication.","Only the notification service holds provider credentials - no bypass path exists."],"href":"/system-design-interview/questions/design-a-notification-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-notification-system--notification-reliability","moduleId":"sysdesign","cardId":"design-a-notification-system--notification-reliability","front":"Your email provider goes down. How does the system behave, and how do you handle retries?","back":"Each channel needs at least two providers with automatic failover driven by a circuit breaker on error rate, not just on hard failures. Retries must distinguish transient errors - timeouts, 5xx, provider rate limits - which are retried with exponential backoff and jitter, from permanent errors like an invalid address or an unregistered device token, which must not be retried at all and should update the user's contact record. Queue depth grows during an outage, which is exactly what the queue is for, but you need a maximum age after which time-sensitive notifications are dropped rather than delivered uselessly late.","keyPoints":["Two providers per channel with circuit-breaker-driven failover.","Classify errors: transient retries with backoff, permanent never retries.","Hard bounces and complaints go to a permanent suppression list.","Attach a max age; drop stale notifications rather than delivering them late.","Separate queues per channel and per priority."],"href":"/system-design-interview/questions/design-a-notification-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-video-streaming-platform--video-transcoding-pipeline","moduleId":"sysdesign","cardId":"design-a-video-streaming-platform--video-transcoding-pipeline","front":"Design the upload and transcoding pipeline. How do you transcode a two-hour film quickly?","back":"Upload directly to object storage with a pre-signed URL so the bytes never pass through your application servers, using resumable multipart upload for reliability on poor connections. Then split the source into short segments - typically 5 to 30 seconds - and transcode segments in parallel across a worker fleet, which turns a two-hour serial job into a few minutes of wall-clock time. Each segment is encoded into every rendition, then the outputs are stitched into HLS and DASH manifests. The pipeline is a DAG of retryable stages with per-segment idempotency, because at this volume individual task failures are constant.","keyPoints":["Pre-signed direct-to-object-storage upload keeps bytes off your servers.","Split at keyframes and transcode segments in parallel - wall clock becomes fleet-size-bound.","Keyframe alignment across renditions enables seamless bitrate switching.","Every task is idempotent and retryable, so spot instances are viable.","Transcode high renditions lazily based on popularity."],"href":"/system-design-interview/questions/design-a-video-streaming-platform","moduleLabel":"System Design"},{"key":"sysdesign:design-a-video-streaming-platform--video-playback-abr","moduleId":"sysdesign","cardId":"design-a-video-streaming-platform--video-playback-abr","front":"How does adaptive bitrate streaming work, and how do you serve an exabyte of egress per day?","back":"The player fetches a master manifest listing every available rendition, then requests short segments one at a time. It measures throughput and buffer level and switches rendition between segments, so quality adapts to changing network conditions without interrupting playback. On distribution, essentially all bytes must come from CDN edges: pre-position popular content, use origin shielding for the long tail, and for the very largest platforms place caching appliances directly inside ISP networks so traffic never crosses the public internet at all.","keyPoints":["ABR: master manifest, short segments, switch between segments using buffer level.","Keyframe alignment across renditions is what makes switching seamless.","Origin must serve under 1% of bytes; ISP-embedded caches carry the majority.","Cache hit rate is bimodal - the long tail always misses, so shield the origin.","Count views via a stream and rollups, never a per-view database increment."],"href":"/system-design-interview/questions/design-a-video-streaming-platform","moduleLabel":"System Design"},{"key":"sysdesign:design-a-ride-hailing-system--geospatial-indexing","moduleId":"sysdesign","cardId":"design-a-ride-hailing-system--geospatial-indexing","front":"How do you index 5 million moving drivers so 'find nearby drivers' is fast?","back":"Use a grid-based spatial index that turns a two-dimensional proximity query into a one-dimensional key lookup. Geohash or Uber's H3 hexagonal system encodes a location into a cell identifier, so 'nearby' becomes 'in this cell or its neighbours' - a handful of key lookups rather than a scan. Keep live positions in memory in Redis rather than a database, because at 1.25 million writes per second the durability of each individual position is worthless: a position four seconds old is already stale, so losing it costs nothing.","keyPoints":["Grid indexing turns 2D proximity into 1D key lookups.","H3 hexagons give uniform neighbour distances and cleaner radius queries.","Live positions in Redis; durability of an individual position is worthless.","Query the k-ring of cells, then compute exact distance on a small candidate set.","Persist only trip paths, asynchronously, not every location ping."],"href":"/system-design-interview/questions/design-a-ride-hailing-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-ride-hailing-system--ride-matching-concurrency","moduleId":"sysdesign","cardId":"design-a-ride-hailing-system--ride-matching-concurrency","front":"Two riders request a ride simultaneously and the same driver is nearest to both. How do you resolve it?","back":"Make the assignment an atomic compare-and-set on the driver's state: transition from `available` to `offered` only if the current state is `available`, so exactly one rider wins and the other immediately gets the next-best driver. Never do a read-then-write. Model the trip as an explicit state machine with allowed transitions and enforce them in the database, and give every offer a short expiry so a driver who does not respond within a few seconds releases automatically rather than being stuck.","keyPoints":["Atomic compare-and-set on driver status; rows-affected decides the winner.","Explicit trip state machine with database-enforced transitions.","Offers must expire so an unresponsive driver does not stall the trip.","Match on ETA and acceptance likelihood, not straight-line distance.","Batch matching beats greedy assignment on total wait time."],"href":"/system-design-interview/questions/design-a-ride-hailing-system","moduleLabel":"System Design"},{"key":"sysdesign:design-a-web-crawler-and-search--crawler-design","moduleId":"sysdesign","cardId":"design-a-web-crawler-and-search--crawler-design","front":"Design a web crawler for 10 billion pages. How do you stay polite and avoid crawling the same content twice?","back":"The core structure is a URL frontier: a set of per-host queues with a scheduler that guarantees at most one in-flight request per host, so politeness is enforced by the data structure rather than by hoping workers behave. Deduplicate at three levels - exact URL after canonicalisation, exact content by hash, and near-duplicate content by SimHash, since a huge fraction of the web is boilerplate variations of the same page. Store the frontier durably and partition it by host hash so each worker owns a disjoint set of hosts and no cross-worker coordination is needed.","keyPoints":["Per-host queues make politeness structurally impossible to violate.","Partition the frontier by hash(host) so workers need no coordination.","Deduplicate at URL, exact-content and near-duplicate levels.","Bloom filters handle billions of seen URLs in a few gigabytes.","Adaptive recrawl frequency from observed change rate."],"href":"/system-design-interview/questions/design-a-web-crawler-and-search","moduleLabel":"System Design"},{"key":"sysdesign:design-a-web-crawler-and-search--inverted-index-sharding","moduleId":"sysdesign","cardId":"design-a-web-crawler-and-search--inverted-index-sharding","front":"How do you build and shard an inverted index to answer a query in under 200 ms?","back":"An inverted index maps each term to a posting list of the documents containing it, with positions and frequencies. A query intersects the posting lists of its terms and ranks the results. Shard by *document* rather than by term: each shard holds a complete index over a subset of documents, so every query fans out to all shards, each returns its top-k, and a coordinator merges them. Term sharding looks appealing because a query only touches a few shards, but it creates catastrophic hotspots on common terms and makes multi-term intersection require cross-shard traffic.","keyPoints":["Shard by document, not by term - term sharding creates unfixable hotspots.","Query fans out to all shards; each returns local top-k and a coordinator merges.","Two-stage retrieval: cheap BM25 recall, then expensive reranking.","Skip pointers, tiered indexes and compression are what deliver sub-200 ms.","Base index plus incremental index, merged periodically, handles freshness."],"href":"/system-design-interview/questions/design-a-web-crawler-and-search","moduleLabel":"System Design"},{"key":"sysdesign:system-design-interview-framework--the-script","moduleId":"sysdesign","cardId":"system-design-interview-framework--the-script","front":"Give me the exact script - what do you say at each stage of a system design interview?","back":"Open by restating the problem and proposing an agenda. Ask for scale numbers before drawing anything. Estimate out loud and immediately convert the numbers into a design decision. Sketch the API and data model. Draw a complete end-to-end design and trace one write and one read through it. Then go deep wherever the interviewer points, and finish by identifying your own bottleneck and the central trade-off. Narrating the agenda turns the interview from an interrogation into a design review, which is exactly the collaboration being assessed.","keyPoints":["Restate, propose an agenda, and get numbers before drawing.","Convert every estimate into an explicit design decision.","Complete end-to-end design by roughly minute 20.","Name the alternative you rejected and why, for every significant choice.","Find your own bottleneck, and close with the central trade-off."],"href":"/system-design-interview/questions/system-design-interview-framework","moduleLabel":"System Design"},{"key":"sysdesign:system-design-tradeoffs-cheatsheet--tradeoff-reference","moduleId":"sysdesign","cardId":"system-design-tradeoffs-cheatsheet--tradeoff-reference","front":"Walk me through the major trade-offs in system design and how you justify each choice.","back":"Every recurring decision reduces to spending one resource to buy another. Consistency buys correctness with latency and availability. Caching buys latency with staleness and invalidation complexity. Denormalisation buys read speed with write cost and drift risk. Asynchrony buys responsiveness with eventual consistency and ordering complexity. Microservices buy team autonomy with availability, latency and operational cost. The skill is naming both sides and tying the choice to a stated requirement.","keyPoints":["Every decision spends one resource to buy another - name both sides.","Tie the choice to a stated requirement, not to a preference.","Complexity is a finite budget; declining to add something is a real decision.","'It depends' must always be followed by 'and here's how I'd resolve it'.","Pair each choice with its failure mode and how you would detect it."],"href":"/system-design-interview/questions/system-design-tradeoffs-cheatsheet","moduleLabel":"System Design"},{"key":"sysdesign:system-design-interview-levels-and-evaluation--level-expectations","moduleId":"sysdesign","cardId":"system-design-interview-levels-and-evaluation--level-expectations","front":"What distinguishes a mid-level answer from a senior or staff-level answer to the same question?","back":"Mid-level produces a working design using standard components with reasonable reasoning, and needs prompting for scale and failure. Senior gets there faster, justifies every component against a requirement, proactively identifies bottlenecks and failure modes, and quantifies with back-of-envelope arithmetic. Staff does all that and adds: explicit consideration of what not to build, operational and cost reality, migration paths from the current state, and organisational implications such as which team owns which service. The differentiator is not knowing more components - it is depth of justification and breadth of concern.","keyPoints":["Depth of justification and breadth of concern separate the levels, not component knowledge.","Senior: unprompted estimation, failure analysis and named alternatives.","Staff: what not to build, cost, migration path, team ownership.","Most negative feedback is about process, not knowledge.","Close with a three-sentence summary, the central trade-off, and one good question."],"href":"/system-design-interview/questions/system-design-interview-levels-and-evaluation","moduleLabel":"System Design"},{"key":"aiml:linear-algebra-for-machine-learning--dot-product-meaning","moduleId":"aiml","cardId":"linear-algebra-for-machine-learning--dot-product-meaning","front":"What does the dot product actually measure, and why is cosine similarity the default metric for embeddings?","back":"The dot product is the length of one vector times the projection of the other onto it: it grows with both magnitude and alignment. Cosine similarity divides that by both norms, isolating the angle. Embeddings encode meaning in direction, not length, so cosine removes the nuisance magnitude that comes from token frequency or document length.","keyPoints":["Dot product = magnitude × magnitude × alignment.","Embedding meaning lives in direction; norm is often a length/frequency artefact.","After L2 normalisation, cosine / inner product / Euclidean give identical rankings.","Serving metric must match the training objective (cosine-trained → cosine served)."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning","moduleLabel":"AI/ML"},{"key":"aiml:linear-algebra-for-machine-learning--matrix-multiplication-cost","moduleId":"aiml","cardId":"linear-algebra-for-machine-learning--matrix-multiplication-cost","front":"Given a batch of activations X (B×d) and a weight matrix W (d×h), what is the FLOP and memory cost of X @ W - and why does that matter for transformer inference?","back":"X @ W costs roughly 2·B·d·h FLOPs (one multiply and one add per term) and produces a B×h output. In transformers this is why the feed-forward block dominates FLOPs, why attention is O(n²·d) in sequence length, and why decoding is memory-bandwidth-bound rather than compute-bound.","keyPoints":["2·B·d·h FLOPs is the number to quote; the ×2 is multiply + add.","Arithmetic intensity, not FLOP count, decides the bottleneck.","Prefill is compute-bound; decode is bandwidth-bound.","FFN dominates FLOPs until context length exceeds roughly 6× model width."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning","moduleLabel":"AI/ML"},{"key":"aiml:linear-algebra-for-machine-learning--eigen-svd-pca","moduleId":"aiml","cardId":"linear-algebra-for-machine-learning--eigen-svd-pca","front":"Explain eigendecomposition versus SVD, and how PCA relates to both.","back":"Eigendecomposition factors a square matrix into directions that only get scaled, A = QΛQ⁻¹. SVD generalises this to any m×n matrix, A = UΣVᵀ, always exists, and is numerically stable. PCA is the SVD of the mean-centred data matrix: right singular vectors are principal directions, and squared singular values are proportional to explained variance.","keyPoints":["Eigendecomposition needs a square matrix; SVD always exists.","V = eigenvectors of AᵀA, U = eigenvectors of AAᵀ, σ = √λ.","PCA = SVD of centred X; explained variance ∝ σ².","Never build the covariance matrix explicitly - it squares the condition number.","Truncated SVD scales PCA; low-rank factorisation underpins LoRA."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning","moduleLabel":"AI/ML"},{"key":"aiml:linear-algebra-for-machine-learning--matrix-norms-conditioning","moduleId":"aiml","cardId":"linear-algebra-for-machine-learning--matrix-norms-conditioning","front":"What are L1, L2 and Frobenius norms used for in ML, and what does 'ill-conditioned' mean for training?","back":"Norms measure size. L2 penalises large weights smoothly and shrinks them proportionally; L1 has a constant-magnitude gradient that drives weights exactly to zero, giving sparsity. Frobenius is the L2 norm of a flattened matrix. A matrix is ill-conditioned when its largest and smallest singular values differ by orders of magnitude - the loss surface becomes a narrow ravine and plain gradient descent zig-zags.","keyPoints":["L1 gradient is constant-magnitude → exact zeros → sparsity/feature selection.","L2 gradient is proportional → smooth shrinkage, never exact zero.","Frobenius = L2 over a flattened matrix; spectral norm controls Lipschitz constant.","κ = σ_max/σ_min; large κ → ravine-shaped loss → slow, zig-zagging descent.","Standardisation, BatchNorm/LayerNorm and Adam are all conditioning improvements."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning","moduleLabel":"AI/ML"},{"key":"aiml:linear-algebra-for-machine-learning--matrix-calculus-backprop","moduleId":"aiml","cardId":"linear-algebra-for-machine-learning--matrix-calculus-backprop","front":"Derive the gradient of a linear layer. Given loss L, y = xW + b, what are ∂L/∂W, ∂L/∂x and ∂L/∂b?","back":"With upstream gradient g = ∂L/∂y of shape (B×h): ∂L/∂W = xᵀg (d×h), ∂L/∂x = gWᵀ (B×d), and ∂L/∂b = g summed over the batch dimension (h,). The reliable trick is that gradients must match the shape of the thing they differentiate - that determines the transposes uniquely.","keyPoints":["∂L/∂W = xᵀg, ∂L/∂x = gWᵀ, ∂L/∂b = sum of g over batch.","Shape matching uniquely determines the transposes.","Needing x in the backward pass is exactly why activations dominate training memory.","Repeated multiplication by Wᵀ is the mechanism behind vanishing/exploding gradients."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning","moduleLabel":"AI/ML"},{"key":"aiml:probability-for-ml-interviews--bayes-base-rate","moduleId":"aiml","cardId":"probability-for-ml-interviews--bayes-base-rate","front":"A test for a disease is 99% sensitive and 99% specific. The disease affects 1 in 10,000 people. A patient tests positive. What is the probability they have the disease - and what does this mean for ML systems?","back":"About 1%. Even a 99%-accurate test produces ~100 false positives for every true positive when the base rate is 1 in 10,000. This is exactly why a fraud or rare-disease model with 99.9% accuracy can be useless, and why you report precision/recall at a realistic prevalence rather than accuracy.","keyPoints":["P(D|+) ≈ 1% - recite it with natural frequencies, not formulas.","Base rate dominates: rare positives make precision collapse regardless of sensitivity.","Accuracy is meaningless under imbalance; use PR-AUC and cost-based thresholds.","Resampling breaks probability calibration - recalibrate before using scores as probabilities."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews","moduleLabel":"AI/ML"},{"key":"aiml:probability-for-ml-interviews--mle-vs-map","moduleId":"aiml","cardId":"probability-for-ml-interviews--mle-vs-map","front":"Explain MLE versus MAP, and show why cross-entropy loss and MSE both come from maximum likelihood.","back":"MLE picks parameters maximising P(data|θ). MAP maximises P(θ|data) ∝ P(data|θ)P(θ), so it adds a prior. Taking the negative log turns MLE into a loss: a Gaussian noise assumption gives MSE, a Bernoulli/categorical assumption gives cross-entropy. A Gaussian prior on θ under MAP is exactly L2 regularisation; a Laplace prior is L1.","keyPoints":["Loss = negative log-likelihood; the likelihood encodes your noise assumption.","Gaussian noise → MSE; Bernoulli/categorical → cross-entropy; Laplace → MAE.","MAP = MLE + prior; Gaussian prior → L2, Laplace prior → L1.","λ = σ²/τ² makes the ridge/prior correspondence exact.","MAP is still a point estimate; full Bayes gives predictive uncertainty."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews","moduleLabel":"AI/ML"},{"key":"aiml:probability-for-ml-interviews--distributions-in-ml","moduleId":"aiml","cardId":"probability-for-ml-interviews--distributions-in-ml","front":"Which probability distributions should an ML engineer know cold, and where does each appear in practice?","back":"Bernoulli/categorical for classification outputs, Gaussian for continuous noise and initialisation, Poisson for counts, Exponential for waiting times, Beta as the conjugate prior for rates (Thompson sampling), and the long-tailed Zipf/power-law for user and token frequency. Knowing which one your data follows tells you which loss and which sampling strategy to use.","keyPoints":["Every classification head is a categorical distribution; every MSE is a Gaussian assumption.","CLT is about sample means, not raw data.","Poisson forces variance = mean; real count data is usually overdispersed → negative binomial.","Beta–Bernoulli conjugacy makes Thompson sampling a counting exercise.","Latency and revenue are log-normal - model in log space and report percentiles."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews","moduleLabel":"AI/ML"},{"key":"aiml:probability-for-ml-interviews--expectation-variance-estimators","moduleId":"aiml","cardId":"probability-for-ml-interviews--expectation-variance-estimators","front":"What is the bias–variance decomposition of expected prediction error, and how do you derive it?","back":"Expected squared error at a point decomposes into irreducible noise σ², squared bias (how far the average model is from truth), and variance (how much the model moves across training sets). You derive it by adding and subtracting the expected prediction E[f̂(x)] and showing the cross term vanishes.","keyPoints":["Error = σ² + bias² + variance; the expectation is over training-set resamples.","The cross term vanishes because E[f̄ − f̂] = 0.","Bagging attacks variance, boosting attacks bias.","Fix bias before variance - regularisation cannot create signal.","Double descent means the classic U-curve is an approximation, not a law."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews","moduleLabel":"AI/ML"},{"key":"aiml:probability-for-ml-interviews--sampling-monte-carlo","moduleId":"aiml","cardId":"probability-for-ml-interviews--sampling-monte-carlo","front":"What is importance sampling, and where does it appear in modern ML systems?","back":"Importance sampling estimates an expectation under distribution p while only being able to sample from q, by reweighting each sample by p(x)/q(x). It appears in off-policy RL and PPO's ratio term, in off-policy evaluation of recommenders and bandits, in negative sampling for embeddings, and in speculative decoding for LLMs.","keyPoints":["Reweight by p/q to estimate under p while sampling from q; unbiased if q covers p's support.","Variance explodes when q has thinner tails than p - clip weights or fix the proposal.","PPO's clipped ratio is a variance-bounded importance weight.","Off-policy evaluation needs logged propensities from a stochastic policy.","Report ESS = (Σw)²/Σw² to show whether the estimate is trustworthy."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews","moduleLabel":"AI/ML"},{"key":"aiml:statistics-and-ab-testing-for-ml--p-value-meaning","moduleId":"aiml","cardId":"statistics-and-ab-testing-for-ml--p-value-meaning","front":"What exactly is a p-value, and what are the three most common misinterpretations?","back":"A p-value is the probability of observing data at least as extreme as yours, assuming the null hypothesis is true. It is not the probability the null is true, not the probability your result is a fluke, and not a measure of effect size. A p-value of 0.04 with a 0.01% lift is statistically significant and commercially worthless.","keyPoints":["p = P(data this extreme | H₀), not P(H₀ | data).","Significance depends on sample size, so it is not a measure of importance.","Even with correct stats, ~35% of p<0.05 wins are false when only 10% of ideas work.","Report effect size + CI first; p-value second."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml","moduleLabel":"AI/ML"},{"key":"aiml:statistics-and-ab-testing-for-ml--sample-size-power","moduleId":"aiml","cardId":"statistics-and-ab-testing-for-ml--sample-size-power","front":"How do you determine the sample size for an A/B test, and what happens if you peek at the results early?","back":"Sample size comes from four inputs: baseline rate, minimum detectable effect, α and power. For proportions, n ≈ 16·p(1−p)/MDE² per arm for 80% power at α=0.05. Peeking inflates the false-positive rate dramatically - checking daily for two weeks pushes a nominal 5% α above 20% - unless you use sequential testing or always-valid confidence intervals.","keyPoints":["n ≈ 16·p(1−p)/δ² per arm for 80% power at α = 0.05.","Halving the MDE quadruples the required sample.","Naive daily peeking inflates α from 5% to >20%.","Fix with group-sequential boundaries or always-valid confidence sequences.","CUPED and triggered analysis buy power without buying traffic."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml","moduleLabel":"AI/ML"},{"key":"aiml:statistics-and-ab-testing-for-ml--offline-online-gap","moduleId":"aiml","cardId":"statistics-and-ab-testing-for-ml--offline-online-gap","front":"Your new ranking model improves offline AUC by 3% but the A/B test shows no lift. What are the possible causes?","back":"Most likely: the offline metric is a poor proxy for the business metric; the training data was logged under the old policy so the new model is evaluated off-distribution; there is a position/selection bias feedback loop; the gain sits in a segment that gets little traffic; or the test is underpowered for the true effect size. Also check for training/serving skew and latency regressions.","keyPoints":["AUC is a global-ordering metric; users only see top-k. Use NDCG@k/recall@k.","Offline eval is off-policy - logged data came from the old ranker.","Check SRM and A/A first: validate the experiment before debugging the model.","Training/serving skew is detectable by re-scoring logged features and comparing distributions.","'No lift' can mean 'underpowered' - read the confidence interval."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml","moduleLabel":"AI/ML"},{"key":"aiml:statistics-and-ab-testing-for-ml--multiple-testing","moduleId":"aiml","cardId":"statistics-and-ab-testing-for-ml--multiple-testing","front":"You track 20 metrics across 5 segments in one experiment. How do you avoid fooling yourself?","back":"100 comparisons at α = 0.05 yield about 5 false positives even when nothing works. Pre-register one primary metric, treat the rest as guardrails or exploratory, and apply Benjamini–Hochberg FDR control to the exploratory family. Segment findings must be pre-registered or treated as hypothesis-generating and confirmed in a follow-up test.","keyPoints":["100 comparisons at α=0.05 → ~99% chance of at least one false positive.","Bonferroni controls FWER (strict); BH controls FDR (practical for exploration).","Pre-register one primary metric; everything else is guardrail or exploratory.","Segment wins are leads to confirm, not results to ship.","Correlated metrics make Bonferroni over-conservative; bootstrap the joint null if you can."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml","moduleLabel":"AI/ML"},{"key":"aiml:statistics-and-ab-testing-for-ml--confidence-intervals-bootstrap","moduleId":"aiml","cardId":"statistics-and-ab-testing-for-ml--confidence-intervals-bootstrap","front":"What does a 95% confidence interval mean, and how would you compute one for a metric with no closed form - like NDCG@10?","back":"A 95% CI is a procedure that captures the true parameter in 95% of repeated experiments - not a 95% probability that this particular interval contains it. For metrics without an analytic variance, like NDCG@10 or a custom business metric, use the bootstrap: resample your evaluation units with replacement, recompute the metric thousands of times, and take the 2.5th and 97.5th percentiles.","keyPoints":["A CI is a statement about the procedure across repeats, not this interval.","Lead with the CI: it conveys direction, magnitude and uncertainty in one line.","Bootstrap gives intervals for any metric, including NDCG@k and custom business metrics.","Resample at the randomisation unit (user/session), never at the row level.","Pairing removes item difficulty and dramatically reduces variance."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml","moduleLabel":"AI/ML"},{"key":"aiml:machine-learning-fundamentals-interview--supervised-unsupervised-self","moduleId":"aiml","cardId":"machine-learning-fundamentals-interview--supervised-unsupervised-self","front":"Compare supervised, unsupervised, self-supervised and reinforcement learning. Where does modern LLM training sit?","back":"Supervised learns from labelled pairs; unsupervised finds structure with no labels; self-supervised manufactures labels from the data itself (predict the next token, the masked patch); RL learns from a reward signal through interaction. LLMs use all three in sequence: self-supervised pre-training, supervised fine-tuning on instruction pairs, then RL from human feedback.","keyPoints":["Self-supervised = supervised learning where the label is extracted from the input itself.","Labels, not compute or architecture, were the historical bottleneck.","LLMs: self-supervised pre-training → supervised fine-tuning → preference optimisation.","Semi-supervised and weak supervision are the practical middle ground for real teams."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview","moduleLabel":"AI/ML"},{"key":"aiml:machine-learning-fundamentals-interview--overfitting-diagnosis","moduleId":"aiml","cardId":"machine-learning-fundamentals-interview--overfitting-diagnosis","front":"Your model gets 0.98 training accuracy and 0.71 validation accuracy. Walk me through what you do.","back":"That gap is textbook overfitting, but before touching the model I check for leakage or a distribution mismatch between the splits, because both fake this signature. Then, in order of expected value: more or augmented data, stronger regularisation, early stopping, a smaller model, and ensembling. I plot learning curves to decide whether more data will actually help.","keyPoints":["Audit for leakage and split mismatch before assuming overfitting.","Learning curves distinguish 'need more data' from 'need less capacity'.","Order: data → regularisation → early stopping → smaller model → ensemble.","Use CV so you know whether a change beats noise.","The test set is used once, at the end."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview","moduleLabel":"AI/ML"},{"key":"aiml:machine-learning-fundamentals-interview--cross-validation-strategies","moduleId":"aiml","cardId":"machine-learning-fundamentals-interview--cross-validation-strategies","front":"When is k-fold cross-validation wrong, and what do you use instead?","back":"Plain k-fold assumes rows are i.i.d. and exchangeable. It is wrong for time series (it trains on the future), grouped data such as multiple rows per patient or user (the same entity appears in train and val), and heavily imbalanced targets. Use time-based/rolling splits, GroupKFold, and StratifiedKFold respectively - and nest CV when you are also tuning hyperparameters.","keyPoints":["k-fold assumes i.i.d. exchangeable rows; most real data is not.","Time → TimeSeriesSplit with purge/embargo. Groups → GroupKFold. Imbalance → StratifiedKFold.","Grouped leakage can inflate scores by 15+ points and is completely silent.","Nested CV separates hyperparameter selection from performance estimation.","Principle: the validation split must mirror the production split."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview","moduleLabel":"AI/ML"},{"key":"aiml:machine-learning-fundamentals-interview--data-leakage","moduleId":"aiml","cardId":"machine-learning-fundamentals-interview--data-leakage","front":"What is data leakage? Give me the categories and how you would detect each in a real pipeline.","back":"Leakage is any information in training that will not be available at prediction time. The main types are target leakage (a feature computed from the label or after the event), train/test contamination (preprocessing fitted on the full dataset, or duplicate rows), and temporal leakage (using future information). Detect it with suspiciously high scores, feature-importance outliers, a time-based holdout, and a strict point-in-time feature store.","keyPoints":["Leakage = information at training time that will not exist at prediction time.","Categories: target, contamination, temporal, group, ordering.","Detect with single-feature AUC screens, ablations, and adversarial validation.","0.99 AUC on a business problem is a leakage alarm, not a success.","Point-in-time feature stores prevent temporal leakage structurally."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview","moduleLabel":"AI/ML"},{"key":"aiml:machine-learning-fundamentals-interview--generative-vs-discriminative","moduleId":"aiml","cardId":"machine-learning-fundamentals-interview--generative-vs-discriminative","front":"What is the difference between generative and discriminative models, and when would you pick each?","back":"Discriminative models learn P(y|x) - the decision boundary directly. Generative models learn P(x, y) or P(x), so they can sample new data and can be inverted to classify via Bayes. Discriminative usually wins on pure classification accuracy given enough data; generative wins with scarce data, when you need to sample, handle missing features, or detect out-of-distribution inputs.","keyPoints":["Discriminative learns the boundary P(y|x); generative learns the joint/marginal and can sample.","Generative converges faster with little data; discriminative has the better asymptote.","Generative handles missing features and OOD detection natively.","LLMs are generative models routinely used for discriminative tasks."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview","moduleLabel":"AI/ML"},{"key":"aiml:regression-and-regularization-interview--linear-regression-assumptions","moduleId":"aiml","cardId":"regression-and-regularization-interview--linear-regression-assumptions","front":"What are the assumptions of linear regression, how do you check them, and which ones actually matter in practice?","back":"Linearity in the parameters, independent errors, homoscedasticity, normally distributed errors, and no perfect multicollinearity. In practice linearity and independence matter most; normality only matters for small-sample inference (the CLT rescues large samples), and heteroscedasticity biases your standard errors rather than your coefficients - fixable with robust standard errors.","keyPoints":["Five assumptions, but linearity and independence are the ones that break predictions.","Heteroscedasticity breaks standard errors, not coefficients - use HC3.","Normality of errors is largely irrelevant at large n thanks to the CLT.","Multicollinearity destroys interpretability, not accuracy. VIF > 10 is the flag.","Always ask whether the goal is prediction or inference - it changes everything."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview","moduleLabel":"AI/ML"},{"key":"aiml:regression-and-regularization-interview--logistic-regression-mse","moduleId":"aiml","cardId":"regression-and-regularization-interview--logistic-regression-mse","front":"Why can't you train logistic regression with mean squared error? Derive the gradient of cross-entropy through the sigmoid.","back":"MSE combined with a sigmoid is non-convex in the weights, so gradient descent can stall in local minima, and its gradient contains a σ'(z) factor that vanishes exactly when the model is confidently wrong. Cross-entropy is convex for logistic regression and its gradient simplifies beautifully to (p − y)x - the sigmoid derivative cancels, so confident mistakes produce large gradients.","keyPoints":["∂L/∂w = (p − y)x - the sigmoid derivative cancels against cross-entropy's denominator.","MSE keeps a p(1−p) factor that vanishes exactly when the model is confidently wrong.","MSE ∘ sigmoid is non-convex; cross-entropy ∘ sigmoid is convex.","Coefficients are log-odds; e^w is the odds ratio, not a probability change.","Perfect separation sends the MLE to infinity; L2 regularisation is the fix (and sklearn's default)."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview","moduleLabel":"AI/ML"},{"key":"aiml:regression-and-regularization-interview--l1-l2-elastic-net","moduleId":"aiml","cardId":"regression-and-regularization-interview--l1-l2-elastic-net","front":"Compare L1, L2 and elastic net regularisation. When would you choose each, and how do you tune the strength?","back":"L2 (ridge) shrinks all coefficients smoothly, handles correlated features by splitting weight between them, and never zeroes anything. L1 (lasso) produces exact zeros for automatic feature selection but arbitrarily picks one from a correlated group. Elastic net combines both to get sparsity plus stable grouping. Tune λ by cross-validation over a log-spaced grid, always on standardised features.","keyPoints":["Ridge: smooth shrinkage, splits weight across correlated features, closed form.","Lasso: exact zeros, but unstable selection among correlated features, capped at n features when p ≫ n.","Elastic net: sparsity with grouping - the default when features are correlated.","Standardise inside the pipeline; tune λ on a log grid; use the 1-SE rule.","Never penalise the intercept."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview","moduleLabel":"AI/ML"},{"key":"aiml:regression-and-regularization-interview--gradient-descent-variants","moduleId":"aiml","cardId":"regression-and-regularization-interview--gradient-descent-variants","front":"Compare batch, stochastic and mini-batch gradient descent. Why is mini-batch the universal default?","back":"Batch GD uses the whole dataset per step: an exact gradient but one update per epoch and no ability to scale past memory. SGD uses one sample: very noisy but many fast updates. Mini-batch takes 32–1024 samples, which gives a low-variance gradient estimate, saturates GPU parallelism, and keeps enough noise to escape sharp minima. It is the only one of the three that maps well onto hardware.","keyPoints":["Gradient noise falls as 1/√B - diminishing returns explain the 32–1024 sweet spot.","Mini-batch is the only variant that maps well onto GPU parallelism.","Mini-batch noise is an implicit regulariser that favours flat minima.","Scale LR linearly with batch size, and use warmup.","Gradient accumulation requires dividing the loss by the accumulation count."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview","moduleLabel":"AI/ML"},{"key":"aiml:regression-and-regularization-interview--handling-categorical-features","moduleId":"aiml","cardId":"regression-and-regularization-interview--handling-categorical-features","front":"You have a categorical feature with 50,000 distinct values. How do you encode it?","back":"One-hot is out - 50k sparse columns. The realistic options are target/mean encoding with out-of-fold computation and smoothing, hashing to a fixed number of buckets, learned embeddings if you have a neural model, frequency encoding, or grouping the long tail into an 'other' bucket. The choice depends on model family, cardinality of the *useful* signal, and whether new categories appear at serving time.","keyPoints":["One-hot fails past a few thousand categories; pick by model family and serving constraints.","Target encoding must be out-of-fold and smoothed, or it leaks the label.","Hashing gives fixed memory and free handling of unseen categories, at the cost of collisions.","Embedding dim ≈ 1.6 · n^0.56 capped at 600 is a solid starting heuristic.","Check the head/tail distribution first - top-k + 'other' often wins."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview","moduleLabel":"AI/ML"},{"key":"aiml:trees-ensembles-and-boosting-interview--tree-splitting-criteria","moduleId":"aiml","cardId":"trees-ensembles-and-boosting-interview--tree-splitting-criteria","front":"How does a decision tree choose a split? Compare Gini impurity, entropy and MSE.","back":"It greedily evaluates every feature and threshold and picks the split that maximises the reduction in an impurity measure, weighted by child sizes. Classification uses Gini (1 − Σp²) or entropy (−Σp log p); regression uses variance/MSE reduction. Gini and entropy agree on the chosen split about 98% of the time, so Gini is preferred purely because it avoids a logarithm.","keyPoints":["Greedy search over (feature, threshold), maximising weighted impurity decrease.","Gini vs entropy: near-identical results; Gini is cheaper (no log).","Cost is O(n·d) per node - the reason histogram binning exists.","Trees are scale-invariant and model interactions natively but fit linear trends poorly.","Depth and leaf-size constraints matter far more than the impurity criterion."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview","moduleLabel":"AI/ML"},{"key":"aiml:trees-ensembles-and-boosting-interview--bagging-vs-boosting","moduleId":"aiml","cardId":"trees-ensembles-and-boosting-interview--bagging-vs-boosting","front":"Explain bagging versus boosting. Why does adding trees never hurt a random forest but can overfit a boosted model?","back":"Bagging trains many deep, low-bias, high-variance trees on bootstrap samples in parallel and averages them - averaging independent errors reduces variance without adding bias, so more trees only ever converges. Boosting trains shallow, high-bias trees sequentially, each fitting the previous ensemble's residuals - this reduces bias but each tree also fits some noise, so past a point more trees increases variance and test error rises.","keyPoints":["Bagging: parallel, deep trees, reduces variance, monotone in tree count.","Boosting: sequential, shallow trees, reduces bias, overfits past an optimum.","Ensemble variance floor is ρσ² - feature subsampling exists to lower ρ.","Recipe: low learning rate + many estimators + early stopping.","'RFs can't overfit' applies to tree count, not tree depth or noisy small data."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview","moduleLabel":"AI/ML"},{"key":"aiml:trees-ensembles-and-boosting-interview--xgboost-lightgbm-catboost","moduleId":"aiml","cardId":"trees-ensembles-and-boosting-interview--xgboost-lightgbm-catboost","front":"Compare XGBoost, LightGBM and CatBoost. What are the actual algorithmic differences?","back":"XGBoost uses second-order gradients with explicit regularisation and grows trees level-wise. LightGBM grows leaf-wise (best-first), uses histogram binning plus GOSS sampling and exclusive feature bundling, making it much faster on wide/large data but more prone to overfitting on small data. CatBoost uses ordered boosting and ordered target statistics to eliminate the prediction-shift bias from categorical encoding, and is the strongest default when you have many categorical features.","keyPoints":["XGBoost: second-order Taylor expansion, closed-form leaf weights, γ prunes inside the gain.","LightGBM: leaf-wise growth + histograms + GOSS + EFB - fast, but overfits small data.","num_leaves < 2^max_depth, and raise min_data_in_leaf on small datasets.","CatBoost: ordered boosting and ordered target statistics eliminate prediction shift.","Accuracy is comparable when tuned; choose on speed, categoricals and tooling."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview","moduleLabel":"AI/ML"},{"key":"aiml:trees-ensembles-and-boosting-interview--feature-importance-shap","moduleId":"aiml","cardId":"trees-ensembles-and-boosting-interview--feature-importance-shap","front":"Your stakeholder asks which features drive the model. Why is the default feature_importances_ misleading, and what do you use instead?","back":"Default impurity-based importance is biased toward high-cardinality and continuous features, is computed on training data so it rewards overfitting, and splits credit arbitrarily among correlated features. Use permutation importance on a held-out set for a global, model-agnostic view, and SHAP values when you need per-prediction attributions with consistency guarantees.","keyPoints":["Impurity importance is biased toward high-cardinality features and computed on training data.","Permutation importance on a holdout set is the honest, cheap global default.","SHAP uniquely satisfies local accuracy, missingness and consistency.","Correlated features break naive permutation - use grouped permutation.","Importance is not causation; interventions require a causal design."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview","moduleLabel":"AI/ML"},{"key":"aiml:trees-ensembles-and-boosting-interview--hyperparameter-tuning-strategy","moduleId":"aiml","cardId":"trees-ensembles-and-boosting-interview--hyperparameter-tuning-strategy","front":"How do you tune a gradient boosting model efficiently? You have a 12-hour compute budget.","back":"Fix the learning rate low and let early stopping choose the tree count, then tune in order of impact: tree complexity (max_depth/num_leaves, min_child_weight), then sampling (subsample, colsample), then regularisation (lambda, alpha). Use Bayesian optimisation or Optuna's TPE rather than grid search, add a pruner to kill bad trials early, and always tune against the same CV scheme you will report.","keyPoints":["Fix a low learning rate and let early stopping choose n_estimators.","Tune in order: tree complexity → sampling → regularisation → imbalance.","Use TPE/Bayesian search with a pruner; grid search wastes the budget.","Log-scale multiplicative hyperparameters.","The best-of-200 CV score is biased - confirm on an untouched holdout."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview","moduleLabel":"AI/ML"},{"key":"aiml:evaluation-metrics-interview-questions--precision-recall-f1","moduleId":"aiml","cardId":"evaluation-metrics-interview-questions--precision-recall-f1","front":"Explain precision, recall and F1. When would you optimise for each?","back":"Precision is the fraction of positive predictions that are correct - it answers 'when I flag something, am I right?'. Recall is the fraction of actual positives caught - 'of everything I should have found, how much did I?'. F1 is their harmonic mean. Optimise precision when false positives are expensive (spam filters, auto-blocking payments), recall when false negatives are expensive (cancer screening, fraud triage, safety).","keyPoints":["Precision divides by predicted positives; recall divides by actual positives.","Choose based on the relative cost of FP vs FN - ask before answering.","F1's equal weighting is rarely what the business wants; F_β or expected cost is better.","Score and threshold are separate artefacts with separate owners.","Always state macro vs micro vs weighted averaging in multi-class."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:evaluation-metrics-interview-questions--roc-auc-vs-pr-auc","moduleId":"aiml","cardId":"evaluation-metrics-interview-questions--roc-auc-vs-pr-auc","front":"When is ROC-AUC misleading, and why does PR-AUC behave differently under class imbalance?","back":"ROC-AUC uses the false positive rate, whose denominator is the (huge) negative count, so thousands of extra false positives barely move it. PR-AUC's precision has false positives in the denominator against a tiny true-positive count, so it responds sharply. At 1:1000 imbalance a model can show 0.95 ROC-AUC and 0.08 PR-AUC - the second number is the one that describes what a user experiences.","keyPoints":["TN appears in ROC and never in PR - that single asymmetry explains everything.","ROC-AUC is nearly invariant to imbalance; PR-AUC is not.","The PR baseline is the positive rate, so judge PR-AUC as a lift over prevalence.","Use precision@k when review capacity is the real constraint.","Use average_precision_score, not auc(recall, precision)."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:evaluation-metrics-interview-questions--calibration","moduleId":"aiml","cardId":"evaluation-metrics-interview-questions--calibration","front":"What is model calibration, why does it matter, and how do you fix a miscalibrated model?","back":"A calibrated model's predicted probabilities match observed frequencies: among all cases scored 0.7, about 70% should be positive. It matters whenever a score feeds an expected-value calculation - pricing, bidding, ranking by expected revenue, or thresholding on cost. Fix it post-hoc with Platt scaling (sigmoid) or isotonic regression, fitted on a held-out set, and measure with ECE and a reliability diagram.","keyPoints":["Calibration and discrimination are independent; AUC measures only discrimination.","Measure with reliability diagrams, ECE and Brier score.","Platt for small calibration sets, isotonic for large, temperature scaling for deep nets.","Always calibrate on held-out data, and recalibrate after any change.","Resampling for imbalance destroys calibration - recalibrate or apply prior correction."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:evaluation-metrics-interview-questions--regression-metrics","moduleId":"aiml","cardId":"evaluation-metrics-interview-questions--regression-metrics","front":"Compare RMSE, MAE, MAPE and R². Which would you use for demand forecasting?","back":"RMSE penalises large errors quadratically and targets the conditional mean; MAE is robust to outliers and targets the median; MAPE is scale-free but explodes near zero and asymmetrically punishes over-prediction; R² is a relative measure that flatters models on high-variance data. For demand forecasting I would use MAE or weighted MAE for the headline, plus a pinball loss if the downstream decision is inventory, since that needs a quantile rather than a mean.","keyPoints":["RMSE targets the conditional mean, MAE the median - pick the one the decision needs.","MAPE is undefined at zero and biases forecasts downward; use WAPE or MASE.","R² is relative to target variance and is not comparable across datasets.","Inventory decisions need a quantile: τ = c_u / (c_u + c_o), optimised with pinball loss.","Weight the metric by business value and always beat seasonal naive."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:evaluation-metrics-interview-questions--ranking-metrics","moduleId":"aiml","cardId":"evaluation-metrics-interview-questions--ranking-metrics","front":"How do you evaluate a ranking or recommendation system offline?","back":"Use top-k metrics because users only see the top: precision@k and recall@k for binary relevance, MAP for ordering within the relevant set, MRR when only the first hit matters, and NDCG@k when relevance is graded and position matters. Complement these with beyond-accuracy metrics - coverage, diversity, novelty - and validate offline conclusions with interleaving before a full A/B test.","keyPoints":["Users see the top-k, so evaluate at k: precision@k, recall@k, MRR, MAP, NDCG@k.","NDCG's exponential gain rewards putting the best item first; the log discount models click decay.","Position bias and missing-not-at-random labels are the core offline evaluation traps.","Track coverage, diversity and novelty alongside accuracy.","Interleaving bridges offline and A/B testing with far less traffic."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:feature-engineering-and-imbalanced-data--feature-engineering-patterns","moduleId":"aiml","cardId":"feature-engineering-and-imbalanced-data--feature-engineering-patterns","front":"You are predicting customer churn from transaction logs. Walk me through your feature engineering.","back":"Start from the mechanism of churn, then build features across five families: recency/frequency/monetary aggregates over multiple windows, trend and ratio features that compare recent to historical behaviour, engagement-breadth features, support and friction signals, and time-derived features. Every aggregate must be computed with a point-in-time cutoff so nothing after the prediction timestamp leaks in.","keyPoints":["Reason from the mechanism of churn before listing transformations.","Five families: RFM windows, trend/ratio, breadth, friction, lifecycle.","Trend features (recent vs baseline) usually beat level features.","Use a rolling-cutoff design: past-only features, forward-window labels.","Every feature is a production dependency with a freshness SLA."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data","moduleLabel":"AI/ML"},{"key":"aiml:feature-engineering-and-imbalanced-data--missing-values","moduleId":"aiml","cardId":"feature-engineering-and-imbalanced-data--missing-values","front":"How do you handle missing values? When is imputation actively harmful?","back":"First classify the mechanism: MCAR, MAR or MNAR. For MCAR/MAR, simple imputation plus a missingness indicator is usually enough; for MNAR the missingness itself carries signal and must become a feature. Imputation is harmful when it destroys that signal, when it is fitted outside the CV fold, or when serving-time missingness patterns differ from training. Tree ensembles can often handle NaN natively - prefer that over guessing.","keyPoints":["Classify MCAR / MAR / MNAR before choosing a strategy.","MNAR: missingness is signal - always add an indicator.","Fit imputers inside the CV fold; they are model parameters.","Tree ensembles handle NaN natively and often beat imputation.","Monitor serving-time missingness rates; upstream outages change the distribution."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data","moduleLabel":"AI/ML"},{"key":"aiml:feature-engineering-and-imbalanced-data--class-imbalance","moduleId":"aiml","cardId":"feature-engineering-and-imbalanced-data--class-imbalance","front":"How do you handle a 1:1000 class imbalance? Rank your options.","back":"In order: (1) change the metric and threshold rather than the data - this alone fixes most cases; (2) use class weights or scale_pos_weight, which is equivalent to resampling but without discarding or fabricating rows; (3) undersample the majority if training cost is the problem; (4) SMOTE and its variants last, because synthetic points in high dimensions are often unrealistic. Whatever you do, calibrate afterwards and evaluate at the true prevalence.","keyPoints":["Fix the metric and threshold before touching the data distribution.","Class weights ≈ resampling in expectation, with less pipeline damage.","SMOTE frequently hurts in high dimensions - always measure PR-AUC before and after.","All resampling destroys calibration; recalibrate or apply prior correction.","Resample only the training fold, inside the CV loop."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data","moduleLabel":"AI/ML"},{"key":"aiml:feature-engineering-and-imbalanced-data--clustering-evaluation","moduleId":"aiml","cardId":"feature-engineering-and-imbalanced-data--clustering-evaluation","front":"How do you choose k in k-means, and how do you evaluate a clustering with no ground truth?","back":"Use the elbow on inertia as a rough guide, silhouette score for cluster separation, gap statistic for a principled comparison against a null reference, and stability analysis across bootstrap resamples. But the real test is external: do the clusters differ on variables you did not cluster on, and can a domain expert name them? A statistically clean clustering nobody can act on is a failed clustering.","keyPoints":["Combine elbow, silhouette, gap statistic and stability - never rely on one.","Stability across resamples is the strongest practical criterion.","k-means assumes spherical, equal-sized clusters and requires scaling.","Validate on variables not used for clustering (churn, LTV, support).","The real test is whether someone can act differently per segment."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data","moduleLabel":"AI/ML"},{"key":"aiml:feature-engineering-and-imbalanced-data--anomaly-detection","moduleId":"aiml","cardId":"feature-engineering-and-imbalanced-data--anomaly-detection","front":"Design an anomaly detection system when you have almost no labelled anomalies.","back":"Start with robust statistical baselines (per-segment z-scores, seasonal decomposition residuals) because they are interpretable and cheap. Add Isolation Forest for multivariate structure and an autoencoder or density model if the data is high-dimensional. Critically, build a labelling flywheel: every analyst decision on a flagged case becomes a label, and once you have a few thousand you migrate to supervised or semi-supervised learning.","keyPoints":["Alert capacity is the binding constraint - design for precision@k.","Layer cheap interpretable detectors before ML ones.","Use robust statistics (median/MAD), because mean/std are corrupted by the outliers.","Build a labelling flywheel from analyst decisions plus a random unflagged sample.","Keep an unsupervised layer for novel attacks after migrating to supervised."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data","moduleLabel":"AI/ML"},{"key":"aiml:neural-networks-and-backpropagation--backprop-derivation","moduleId":"aiml","cardId":"neural-networks-and-backpropagation--backprop-derivation","front":"Derive backpropagation for a two-layer network with ReLU and softmax + cross-entropy.","back":"Forward: z1 = xW1 + b1, a1 = ReLU(z1), z2 = a1W2 + b2, p = softmax(z2). Backward: dz2 = p − y (the softmax/cross-entropy cancellation), dW2 = a1ᵀ dz2, da1 = dz2 W2ᵀ, dz1 = da1 ⊙ 1[z1 > 0], dW1 = xᵀ dz1. Biases are the batch-sums of the corresponding dz.","keyPoints":["Backprop = chain rule in reverse topological order with cached intermediates.","softmax + cross-entropy ⇒ dz = p − y; the Jacobian collapses.","ReLU backward is a mask: 1 where z > 0, else 0.","dW needs the forward activation - that is why activation memory dominates training.","Verify custom gradients with finite differences."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation","moduleLabel":"AI/ML"},{"key":"aiml:neural-networks-and-backpropagation--activation-functions","moduleId":"aiml","cardId":"neural-networks-and-backpropagation--activation-functions","front":"Compare sigmoid, tanh, ReLU, LeakyReLU, GELU and SwiGLU. Why did ReLU replace sigmoid, and what replaced ReLU?","back":"Sigmoid saturates at both ends, so its derivative peaks at 0.25 and gradients vanish through depth; it is also not zero-centred. ReLU has a derivative of exactly 1 on the positive side, which preserves gradient magnitude and is trivially cheap - but it can die. GELU and SiLU/Swish are smooth, non-monotonic variants that consistently train transformers better, and SwiGLU (a gated variant) is the current default in most large language models.","keyPoints":["Sigmoid's derivative caps at 0.25 → gradients vanish exponentially with depth.","ReLU's derivative is exactly 1 on the positive side, preserving gradient magnitude.","Dead ReLUs come from large LR or bad init; LeakyReLU/GELU/normalisation fix them.","GELU/SiLU are smooth non-monotonic gates that train transformers better.","SwiGLU is the current LLM default; FFN hidden is scaled to 8d/3 to match parameters."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation","moduleLabel":"AI/ML"},{"key":"aiml:neural-networks-and-backpropagation--weight-initialization","moduleId":"aiml","cardId":"neural-networks-and-backpropagation--weight-initialization","front":"Why does weight initialisation matter, and how do you choose between Xavier and He?","back":"Initialisation sets the variance of activations and gradients at layer 1. If the per-layer variance multiplier is not ≈1, signals grow or shrink exponentially with depth. Xavier/Glorot keeps variance stable for symmetric activations like tanh (var = 2/(fan_in+fan_out)); He uses var = 2/fan_in to compensate for ReLU zeroing half the inputs. All-zero init is fatal because every unit in a layer computes the same gradient forever.","keyPoints":["Init sets per-layer variance multipliers; deviations compound exponentially with depth.","Xavier: 2/(fan_in+fan_out) for tanh; He: 2/fan_in for ReLU (compensates the zeroing).","Zero init breaks symmetry breaking - every unit stays identical forever.","Normalisation layers reduce but do not remove init sensitivity.","Modern deep nets scale or zero residual branches so blocks start as identity."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation","moduleLabel":"AI/ML"},{"key":"aiml:neural-networks-and-backpropagation--normalization-layers","moduleId":"aiml","cardId":"neural-networks-and-backpropagation--normalization-layers","front":"Compare BatchNorm, LayerNorm and RMSNorm. Why do transformers use LayerNorm and where exactly is it placed?","back":"BatchNorm normalises each feature across the batch, so it depends on batch statistics and breaks with small batches, variable sequence lengths and autoregressive inference. LayerNorm normalises across features within each token independently, so it is batch-size independent - essential for sequences. RMSNorm drops the mean-centring and the bias, keeping only the scale, which is ~10-15% faster with no measurable quality loss. Modern transformers use pre-norm placement for training stability.","keyPoints":["BatchNorm normalises across the batch per feature; LayerNorm across features per token.","LayerNorm is batch-independent, which sequences and autoregressive decoding require.","RMSNorm drops mean-centring and bias for ~10–15% speedup at equal quality.","Pre-norm keeps a clean residual identity path and removes warmup fragility.","Compute RMSNorm/LayerNorm statistics in fp32 under mixed precision."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation","moduleLabel":"AI/ML"},{"key":"aiml:neural-networks-and-backpropagation--cnn-fundamentals","moduleId":"aiml","cardId":"neural-networks-and-backpropagation--cnn-fundamentals","front":"Explain convolution, receptive field and why ResNet's skip connections made very deep networks trainable.","back":"A convolution slides a small learned kernel across the input, giving translation equivariance and massive parameter sharing versus a dense layer. The receptive field is the input region influencing one output unit; it grows linearly with depth for stride-1 convs and exponentially with dilation. ResNet's skip connections make each block learn a residual F(x) so the layer output is x + F(x) - the identity path lets gradients flow directly to early layers, which is what enabled 50–1000 layer networks.","keyPoints":["Convolution = locality + translation equivariance + parameter sharing.","Receptive field grows linearly with depth, faster with stride, exponentially with dilation.","Two 3×3 convs beat one 5×5: same receptive field, fewer params, extra non-linearity.","Residual connections give ∂y/∂x = I + ∂F/∂x - a gradient path through zero weight matrices.","Deep plain nets fail on *training* error: it is an optimisation, not a capacity, problem."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation","moduleLabel":"AI/ML"},{"key":"aiml:training-optimization-and-regularization--sgd-vs-adam-vs-adamw","moduleId":"aiml","cardId":"training-optimization-and-regularization--sgd-vs-adam-vs-adamw","front":"Compare SGD with momentum, Adam and AdamW. Why does AdamW exist, and when would you still choose SGD?","back":"SGD+momentum uses one global learning rate and an EMA of gradients; it generalises well but needs careful tuning. Adam adds per-parameter adaptive scaling by an EMA of squared gradients, which handles badly-scaled and sparse gradients and converges fast. AdamW exists because adding L2 to the loss under Adam gets divided by the adaptive denominator, so large-gradient parameters get *less* decay - AdamW decouples decay from the adaptive step. SGD still wins for vision CNNs where it often generalises 1-2% better.","keyPoints":["Adam = momentum + per-parameter scaling by an EMA of squared gradients.","L2-in-loss under Adam gets divided by √v, so decay is inversely proportional to gradient size - AdamW decouples it.","Never weight-decay biases, norm parameters or (usually) embeddings.","Adam costs 2× parameter memory in optimiser state - the reason ZeRO shards it first.","SGD+momentum still generalises better on vision CNNs; AdamW dominates transformers."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization","moduleLabel":"AI/ML"},{"key":"aiml:training-optimization-and-regularization--learning-rate-schedules","moduleId":"aiml","cardId":"training-optimization-and-regularization--learning-rate-schedules","front":"Why do we need learning-rate warmup and decay? Describe the schedule you would use for a transformer.","back":"Warmup exists because Adam's second-moment estimate is unreliable in the first few hundred steps - bias correction makes every early update a full-size step built on a handful of noisy gradients, which can push an untrained network somewhere it never recovers from. Decay exists because a large LR is needed to escape bad regions early but prevents settling into a minimum later. The standard transformer recipe is linear warmup over 1–5% of steps to a peak, then cosine decay to about 10% of peak.","keyPoints":["Warmup fixes Adam's unreliable early second-moment estimate, which produces huge first steps.","Decay lets you explore early and settle late.","Standard recipe: linear warmup 1–5% of steps, then cosine decay to ~10% of peak.","Cosine requires knowing total steps; use constant+cooldown when you do not.","Find the peak LR with an LR range test rather than by guessing."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization","moduleLabel":"AI/ML"},{"key":"aiml:training-optimization-and-regularization--training-instability","moduleId":"aiml","cardId":"training-optimization-and-regularization--training-instability","front":"Your loss spikes to NaN at step 12,000 after training fine. Walk me through debugging it.","back":"Check in this order: (1) is it a data problem - a corrupt batch, a huge outlier, or an all-padding sequence causing a division by zero; (2) numerical overflow in fp16, especially in attention scores or normalisation; (3) gradient explosion, visible as a rising gradient norm before the spike; (4) a stale Adam second moment meeting a sudden large gradient. Fixes: clip gradients, lower β₂, switch fp16→bf16, and always keep the last few checkpoints so you can skip the offending batch.","keyPoints":["First determine whether the spike is reproducible at the same step - data vs numerics.","fp16 overflows at 65,504; bf16 has fp32's exponent range and avoids the whole class.","Log global and per-layer gradient norms; spikes are usually preceded by a rising trend.","A stale Adam v meeting a large gradient produces an outsized step on many weights at once; lower β₂ to 0.95.","Operationally: frequent checkpoints, automatic rollback, and batch-skipping."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization","moduleLabel":"AI/ML"},{"key":"aiml:training-optimization-and-regularization--regularization-techniques","moduleId":"aiml","cardId":"training-optimization-and-regularization--regularization-techniques","front":"Rank the regularisation techniques you would apply to an overfitting deep model, and explain the mechanism of each.","back":"Data augmentation first - it adds real information rather than constraining capacity. Then early stopping (free), weight decay, dropout, label smoothing, and finally architectural reductions. For transformers specifically, dropout matters much less than for CNNs and is often set to 0 during large-scale pre-training, where data volume alone provides the regularisation.","keyPoints":["Augmentation and early stopping first - they add information or cost nothing.","Inverted dropout scales at train time so inference is a plain forward pass.","Forgetting model.eval() is a classic production bug.","Label smoothing bounds the optimum and improves calibration, at some cost to representation quality.","Dropout is often 0 in large-scale pre-training; it returns for small-data fine-tuning."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization","moduleLabel":"AI/ML"},{"key":"aiml:training-optimization-and-regularization--mixed-precision-training","moduleId":"aiml","cardId":"training-optimization-and-regularization--mixed-precision-training","front":"Explain mixed-precision training. Why is bf16 preferred over fp16 for large models?","back":"Mixed precision runs matmuls in 16-bit for ~2× tensor-core throughput and half the activation memory, while keeping a master copy of weights and the optimiser state in fp32 for update precision. fp16 has only 5 exponent bits and overflows at 65,504, so it needs dynamic loss scaling. bf16 has 8 exponent bits - the same range as fp32 - so it never overflows and needs no loss scaling, at the cost of less mantissa precision.","keyPoints":["Mixed precision: 16-bit matmuls, fp32 master weights and optimiser state.","fp16 has 5 exponent bits and overflows at 65,504 → dynamic loss scaling required.","bf16 matches fp32's range, so no loss scaling; it trades mantissa precision instead.","Training a 7B model needs ~112 GB - optimiser state dominates, not weights.","Keep softmax, normalisation statistics and the optimiser update in fp32."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization","moduleLabel":"AI/ML"},{"key":"aiml:transformers-and-attention-explained--self-attention-derivation","moduleId":"aiml","cardId":"transformers-and-attention-explained--self-attention-derivation","front":"Derive scaled dot-product attention. Why divide by √d_k specifically?","back":"Attention(Q,K,V) = softmax(QKᵀ/√d_k)V. Each query is compared to every key by dot product to produce relevance scores; softmax turns them into weights; the output is a weighted average of values. The √d_k divisor exists because the dot product of two independent d_k-dimensional unit-variance vectors has variance d_k - without normalisation the logits grow with dimension, softmax saturates, and gradients vanish.","keyPoints":["Attention = soft dictionary lookup: Q asks, K advertises, V delivers.","Var(q·k) = d_k, so unscaled logits grow with dimension and saturate softmax.","Saturated softmax has near-zero gradient - attention stops learning entirely.","Mask before softmax using −inf, never after and never with a large finite negative.","Time O(n²d); naive memory O(n²) per head per layer."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained","moduleLabel":"AI/ML"},{"key":"aiml:transformers-and-attention-explained--multi-head-attention","moduleId":"aiml","cardId":"transformers-and-attention-explained--multi-head-attention","front":"Why multi-head attention instead of one large attention head? And what are GQA and MQA?","back":"One head produces a single averaged attention distribution, so it can only attend one way at a time. Splitting d_model into h heads lets each learn a different relation - syntactic dependency, coreference, positional locality - in parallel, at identical total FLOPs. MQA shares one K/V pair across all query heads and GQA shares one per group; both exist to shrink the KV cache, which is the dominant memory cost in long-context serving.","keyPoints":["Heads split d_model, so multi-head is free relative to one full-width head.","One head produces one attention distribution and cannot serve two relations at once.","KV cache size = 2·L·n·h_kv·d_k·batch·bytes - it can exceed the model weights.","GQA (8 KV heads) is the standard: 8× smaller cache, near-MHA quality.","MQA is 64× smaller but measurably degrades quality; MLA gets both via low-rank latents."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained","moduleLabel":"AI/ML"},{"key":"aiml:transformers-and-attention-explained--positional-encodings","moduleId":"aiml","cardId":"transformers-and-attention-explained--positional-encodings","front":"Why do transformers need positional encodings, and compare sinusoidal, learned, ALiBi and RoPE.","back":"Self-attention is permutation-equivariant - shuffle the input tokens and the outputs shuffle identically, so word order carries no information without positional signal. Sinusoidal encodings are fixed and extrapolate weakly; learned embeddings are flexible but hard-capped at the trained length; ALiBi adds a distance-proportional bias to attention scores and extrapolates well; RoPE rotates Q and K by position-dependent angles so attention naturally depends on relative position, and is the modern default because it extrapolates and can be interpolated to extend context.","keyPoints":["Self-attention is permutation-equivariant, so position must be injected explicitly.","RoPE rotates Q and K so the score depends only on relative offset (m − n).","Learned absolute embeddings cannot exceed the trained length; RoPE and ALiBi can.","Extend RoPE context with PI, NTK-aware scaling or YaRN - usually with a short fine-tune.","Advertised context length ≠ usable context; validate with needle-in-a-haystack across depths."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained","moduleLabel":"AI/ML"},{"key":"aiml:transformers-and-attention-explained--flash-attention","moduleId":"aiml","cardId":"transformers-and-attention-explained--flash-attention","front":"How does FlashAttention make attention faster without changing the mathematics?","back":"Standard attention writes the n×n score matrix to HBM and reads it back several times - it is memory-bandwidth-bound, not compute-bound. FlashAttention tiles Q, K and V into blocks that fit in on-chip SRAM and uses the online-softmax trick to compute the exact result without ever materialising the full matrix. Same maths, O(n) memory instead of O(n²), and 2–4× faster because HBM traffic drops by an order of magnitude.","keyPoints":["Attention is memory-bandwidth-bound; the n² score matrix is the bottleneck.","SRAM is ~10× faster than HBM but only ~20 MB - hence tiling.","Online softmax with a running max and sum lets you normalise incrementally.","Result is exact, not approximate; FLOPs are unchanged, HBM traffic collapses.","Backward recomputes tiles from saved statistics rather than storing the matrix."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained","moduleLabel":"AI/ML"},{"key":"aiml:transformers-and-attention-explained--transformer-block-anatomy","moduleId":"aiml","cardId":"transformers-and-attention-explained--transformer-block-anatomy","front":"Walk me through a full transformer decoder block and account for its parameters and FLOPs.","back":"Each block is: x + Attention(Norm(x)), then x + FFN(Norm(x)). Attention contributes 4d² parameters (Q, K, V, O) and the FFN contributes 8d² with SwiGLU (or 8d² with a 4d ReLU MLP). So ~12d² per layer, giving N ≈ 12·L·d² total plus embeddings. Forward FLOPs are about 2N per token and a full training step is about 6N per token (forward + backward).","keyPoints":["Block = x + Attn(Norm(x)); x + FFN(Norm(x)) - pre-norm, residual stream untouched.","≈12d² parameters per layer; N ≈ 12·L·d² plus embeddings.","Forward ≈ 2N FLOPs/token; training ≈ 6N FLOPs/token; Chinchilla ≈ 20N tokens.","Modern stack: RMSNorm + GQA + SwiGLU + RoPE + weight tying + no biases.","Each choice traces to stability, quality-per-parameter, serving cost or context length."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained","moduleLabel":"AI/ML"},{"key":"aiml:llm-fundamentals-interview-questions--tokenization-bpe","moduleId":"aiml","cardId":"llm-fundamentals-interview-questions--tokenization-bpe","front":"Explain byte-pair encoding. Why not just use words or characters, and what practical problems does tokenisation cause?","back":"Word-level vocabularies explode in size and cannot handle out-of-vocabulary words; character-level sequences are far too long for quadratic attention. BPE starts from bytes and iteratively merges the most frequent adjacent pair, producing subwords that cover any input with a fixed vocabulary. The practical consequences are real: non-English text can cost 3–5× more tokens, numbers tokenise inconsistently which hurts arithmetic, and trailing whitespace changes completions.","keyPoints":["BPE greedily merges the most frequent adjacent pair, starting from bytes.","Fixed vocabulary with zero OOV, and moderate sequence length - the best of both extremes.","Non-English text can cost 3–5× more tokens for the same content.","Digit tokenisation inconsistency degrades arithmetic; digit-splitting helps.","Trailing whitespace changes tokenisation and can degrade completions."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:llm-fundamentals-interview-questions--pretraining-objectives","moduleId":"aiml","cardId":"llm-fundamentals-interview-questions--pretraining-objectives","front":"Compare BERT's masked language modelling with GPT's causal language modelling. When would you use an encoder over a decoder?","back":"MLM masks ~15% of tokens and predicts them using bidirectional context - excellent representations, but it cannot generate and only trains on the masked fraction. CLM predicts the next token with causal masking - it trains on every position, generates naturally, and scales better. Use an encoder for classification, retrieval and NER where you need the best embeddings cheaply; use a decoder for generation and for anything you want to steer with instructions.","keyPoints":["MLM: bidirectional, ~15% supervision, no generation, great embeddings.","CLM: causal, 100% supervision, generative, in-context learning emerges at scale.","Decoders won on training efficiency and interface uniformity, not raw quality per token.","Encoders remain optimal for embeddings, reranking, high-volume classification and low latency.","Distilling LLM labels into a small encoder is the standard cost-optimisation pattern."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:llm-fundamentals-interview-questions--scaling-laws","moduleId":"aiml","cardId":"llm-fundamentals-interview-questions--scaling-laws","front":"Explain scaling laws and the Chinchilla result. Given a fixed compute budget, how do you choose model size versus training tokens?","back":"Loss follows a power law in parameters, data and compute. Kaplan et al. concluded you should scale model size faster than data; Chinchilla corrected this by matching the learning-rate schedule to each run's length and found parameters and tokens should scale roughly equally - about 20 tokens per parameter. Given compute C ≈ 6ND, the optimal split is N ∝ C^0.5 and D ∝ C^0.5. In practice teams now deliberately overtrain small models because inference cost dominates over the model's lifetime.","keyPoints":["L(N,D) = E + A/N^α + B/D^β; you can be parameter-bound or data-bound.","Chinchilla: scale N and D roughly equally, ≈20 tokens per parameter, C ≈ 6ND.","Chinchilla optimises training compute only - inference cost usually dominates lifetime cost.","Modern practice deliberately overtrains small models (Llama-3-8B at ~1900 tokens/param).","MoE FLOP accounting uses active parameters, not total parameters."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:llm-fundamentals-interview-questions--context-window-management","moduleId":"aiml","cardId":"llm-fundamentals-interview-questions--context-window-management","front":"A user's conversation exceeds the context window. How do you handle it?","back":"Options in increasing sophistication: sliding window over recent turns, recursive summarisation of older turns, retrieval over the conversation history so only relevant past turns are injected, and a structured memory store holding extracted facts. In production I would combine them - always keep the system prompt and the last N turns verbatim, retrieve relevant older turns, and maintain a running summary plus a structured fact store.","keyPoints":["Combine pinned system prompt + recent verbatim turns + summary + retrieved history.","Never truncate the system prompt - pin it explicitly.","Lost-in-the-middle means advertised window ≠ usable window; place key content at the edges.","Long prompts cost linearly in prefill and are often less accurate than good retrieval.","Order the prompt so the stable prefix is cacheable."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:llm-fundamentals-interview-questions--embeddings-for-retrieval","moduleId":"aiml","cardId":"llm-fundamentals-interview-questions--embeddings-for-retrieval","front":"How do embedding models differ from LLMs, and how would you choose one for a retrieval system?","back":"An embedding model maps text to a fixed-size vector optimised so semantically similar texts are close, typically trained with a contrastive objective on positive/negative pairs. Choose based on retrieval benchmark performance in your domain, dimension (which drives index cost), max sequence length, multilingual coverage, and whether you can self-host. Always evaluate on your own queries - MTEB rankings frequently do not transfer.","keyPoints":["Embedding models are trained contrastively for a metric space; LLM hidden states are not.","Hard negatives drive quality far more than more data or a bigger model.","Evaluate on a gold set from your own traffic - MTEB rank often does not transfer.","Dimension drives index cost; Matryoshka embeddings let you truncate safely.","Use the model's required query/passage prefixes, and plan for re-indexing on upgrade."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:fine-tuning-lora-and-rlhf--when-to-finetune","moduleId":"aiml","cardId":"fine-tuning-lora-and-rlhf--when-to-finetune","front":"A stakeholder wants to fine-tune an LLM on their company documentation so it 'knows' their product. What do you tell them?","back":"That fine-tuning is the wrong tool for that goal. Fine-tuning adjusts behaviour, format and style; it is an unreliable and expensive way to inject facts, and the facts go stale the moment the docs change. RAG is the correct approach for knowledge. I would propose RAG first, then consider fine-tuning only if the remaining gap is about tone, output format, or a domain-specific task the base model performs poorly.","keyPoints":["Fine-tuning teaches behaviour and style; RAG supplies knowledge.","Fine-tuned facts have no provenance, go stale, and can increase hallucination.","Order: prompt → few-shot → RAG → fine-tune. Each step is cheaper to iterate.","Build the eval set before any intervention or you cannot measure anything.","The best fine-tuning use case is distilling a frontier model into a small one for cost."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf","moduleLabel":"AI/ML"},{"key":"aiml:fine-tuning-lora-and-rlhf--lora-qlora","moduleId":"aiml","cardId":"fine-tuning-lora-and-rlhf--lora-qlora","front":"Explain LoRA mathematically. What does QLoRA add, and what rank would you choose?","back":"LoRA freezes the pre-trained weight W and learns a low-rank update ΔW = BA where B is d×r and A is r×k with r ≪ d. You train ~0.1–1% of the parameters, so optimiser state collapses and adapters are megabytes rather than gigabytes. QLoRA adds 4-bit NF4 quantisation of the frozen base weights plus double quantisation and paged optimisers, letting you fine-tune a 65B model on a single 48GB GPU. Rank 8–16 covers most style/format tasks; 64–128 for genuinely new capabilities.","keyPoints":["ΔW = (α/r)·BA with B initialised to zero, so training starts at the pre-trained model.","0.1–2% trainable parameters collapses optimiser memory; adapters are tens of MB.","QLoRA = NF4 4-bit frozen base + double quantisation + paged optimisers; ~30% slower per step.","Targeting all linear layers matters more than increasing rank.","Keep adapters unmerged for multi-tenant hot-swapping; merge for single-model latency."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf","moduleLabel":"AI/ML"},{"key":"aiml:fine-tuning-lora-and-rlhf--rlhf-vs-dpo","moduleId":"aiml","cardId":"fine-tuning-lora-and-rlhf--rlhf-vs-dpo","front":"Explain RLHF and how DPO differs. Why did DPO become popular?","back":"RLHF has three stages: supervised fine-tuning, training a reward model on human preference pairs, then optimising the policy against that reward with PPO plus a KL penalty to the reference model. DPO proves the optimal RLHF policy has a closed form, which lets you skip the reward model and the RL loop entirely and optimise a simple classification-style loss directly on preference pairs. DPO won on simplicity, stability and cost - it needs two models in memory instead of four.","keyPoints":["RLHF = SFT → reward model (Bradley–Terry) → PPO with a KL penalty to the reference.","The KL term prevents reward hacking; without it the policy exploits the reward model.","DPO uses the closed-form optimal policy so the partition function cancels - no reward model, no RL.","DPO: 2 models, 1 main hyperparameter, stable. PPO: 4 models, ~12 hyperparameters, fragile.","DPO is offline and cannot exceed its preference data; GRPO uses group baselines with verifiable rewards."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf","moduleLabel":"AI/ML"},{"key":"aiml:fine-tuning-lora-and-rlhf--catastrophic-forgetting","moduleId":"aiml","cardId":"fine-tuning-lora-and-rlhf--catastrophic-forgetting","front":"After fine-tuning on your domain data, the model gets worse at general tasks. What is happening and how do you fix it?","back":"Catastrophic forgetting: gradient descent on a narrow distribution moves weights away from the configuration that encoded general capability, and nothing in the loss penalises that. Fixes ranked by effectiveness: mix 5–30% general instruction data into the fine-tuning set, use LoRA so the base weights are frozen, lower the learning rate and train fewer epochs, and always evaluate on a general benchmark alongside your domain metric.","keyPoints":["Forgetting happens because the loss contains no term for preserving general capability.","Mixing 15–30% general instruction data is the single most effective fix.","LoRA bounds the perturbation by freezing the base weights.","Weight interpolation between base and fine-tune recovers capability with zero training.","Always evaluate general benchmarks and safety alongside the domain metric."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf","moduleLabel":"AI/ML"},{"key":"aiml:fine-tuning-lora-and-rlhf--instruction-tuning-data","moduleId":"aiml","cardId":"fine-tuning-lora-and-rlhf--instruction-tuning-data","front":"How would you build a fine-tuning dataset? How much data do you need and what makes an example good?","back":"Quality and diversity beat volume decisively. LIMA showed 1,000 carefully curated examples can outperform 50,000 noisy ones for instruction tuning. Target 1,000–10,000 examples for style and format tasks, 10,000–100,000 for genuinely new capability. Good examples are diverse in phrasing and task type, consistent in output format, contain no contradictions, and - critically - no example should require knowledge the model does not have.","keyPoints":["LIMA: 1,000 curated examples beat 52,000 noisy ones for instruction tuning.","1k–10k for style/format; 10k–100k for new capability.","Audit for duplicates, diversity, format consistency, length outliers and accidental refusals.","Production logs are the best source because they match the real distribution.","Hold out 100–300 hand-curated eval examples that never touch training."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf","moduleLabel":"AI/ML"},{"key":"aiml:llm-inference-decoding-and-serving--decoding-strategies","moduleId":"aiml","cardId":"llm-inference-decoding-and-serving--decoding-strategies","front":"Explain temperature, top-k and top-p sampling. What would you set for a code assistant versus a creative writing tool?","back":"Temperature divides logits before softmax: below 1 sharpens the distribution, above 1 flattens it. Top-k keeps the k highest-probability tokens; top-p (nucleus) keeps the smallest set whose cumulative probability exceeds p, so it adapts to how confident the model is. For code: temperature 0–0.2 with top_p 0.95 for determinism. For creative writing: temperature 0.8–1.0 with top_p 0.9–0.95.","keyPoints":["Temperature rescales logits: <1 sharpens, >1 flattens, 0 is argmax.","Top-k is a fixed cut; top-p adapts to the model's confidence - usually preferred.","Code and extraction: temperature 0–0.2. Creative: 0.8–1.1.","Frequency penalty targets loops; presence penalty targets topic diversity.","Temperature 0 is not bit-deterministic under batched GPU inference."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving","moduleLabel":"AI/ML"},{"key":"aiml:llm-inference-decoding-and-serving--kv-cache-batching","moduleId":"aiml","cardId":"llm-inference-decoding-and-serving--kv-cache-batching","front":"Explain the KV cache and continuous batching. Why does vLLM achieve much higher throughput than a naive server?","back":"The KV cache stores past keys and values so each decode step is O(n) instead of O(n²) - mandatory, but it consumes enormous memory. Static batching wastes GPU time because the whole batch waits for its longest sequence. Continuous batching evicts finished sequences and admits new ones every step. vLLM adds PagedAttention, which stores the cache in fixed-size blocks like OS virtual memory, eliminating the fragmentation that otherwise wastes 60–80% of cache memory.","keyPoints":["KV cache turns decode from O(n²) to O(n); it is mandatory but memory-hungry.","Static batching wastes ~80% of slot-steps because of the long-tail length distribution.","Continuous batching admits and evicts sequences every step.","PagedAttention stores the cache in 16-token blocks, cutting fragmentation from 60–80% to <4%.","Prefix caching shares a long system prompt's blocks across all concurrent requests."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving","moduleLabel":"AI/ML"},{"key":"aiml:llm-inference-decoding-and-serving--quantization-inference","moduleId":"aiml","cardId":"llm-inference-decoding-and-serving--quantization-inference","front":"Compare INT8, INT4, GPTQ and AWQ quantisation. What quality loss should you expect?","back":"Weight-only INT8 is essentially lossless and halves memory. INT4 with a good method (GPTQ, AWQ) typically costs 1–3% on benchmarks while cutting memory ~4×. GPTQ minimises layer-wise reconstruction error using second-order information; AWQ identifies the ~1% of salient channels by activation magnitude and scales them to protect them. Since decode is memory-bandwidth-bound, quantisation usually improves latency proportionally to the memory saving.","keyPoints":["INT8 weight-only is nearly free; 4-bit with GPTQ/AWQ costs 1–3%.","Activation outlier channels are the core problem all methods address.","Group-wise scales (typically 128) are essential - per-tensor 4-bit is unusable.","Weight-only helps memory-bound decode; weight+activation also helps compute-bound prefill.","Quantise the KV cache too when long context is the bottleneck."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving","moduleLabel":"AI/ML"},{"key":"aiml:llm-inference-decoding-and-serving--speculative-decoding","moduleId":"aiml","cardId":"llm-inference-decoding-and-serving--speculative-decoding","front":"Explain speculative decoding. How does it stay mathematically exact?","back":"A small draft model proposes k tokens autoregressively; the large model verifies all k in one forward pass (parallel, so nearly the cost of one token). A modified rejection-sampling rule accepts each draft token with probability min(1, p_target/p_draft) and, on rejection, resamples from the normalised residual distribution. That rule guarantees the output distribution is exactly the target model's, giving 2–3× lower latency with zero quality change.","keyPoints":["Draft k tokens with a small model, verify all k in one large-model forward pass.","Accept with probability min(1, p/q); on rejection resample from norm(max(0, p−q)).","The output distribution is provably identical to the target model's.","Expected tokens per step = (1−α^(k+1))/(1−α); acceptance rate drives everything.","Improves latency at low concurrency; can reduce throughput under saturation."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving","moduleLabel":"AI/ML"},{"key":"aiml:llm-inference-decoding-and-serving--llm-cost-latency-optimization","moduleId":"aiml","cardId":"llm-inference-decoding-and-serving--llm-cost-latency-optimization","front":"Your LLM feature costs $50k/month and p95 latency is 8 seconds. How do you improve both?","back":"Measure first: break cost down by prompt tokens, output tokens and call volume, and split latency into time-to-first-token and inter-token latency. Then attack in order of ROI: semantic and prefix caching, prompt compression, model routing so easy requests hit a cheap model, streaming to fix perceived latency, output-length limits, and batching for anything non-interactive. Most teams find 60–80% savings without changing the model.","keyPoints":["Instrument cost by prompt/output/cached tokens and latency by TTFT vs ITL first.","Prefix caching, semantic caching and model routing typically deliver 60–80% savings.","Retrieved context is usually the largest input-token bucket - rerank to fewer chunks.","Streaming cuts perceived latency ~10× for zero cost; ship it first.","Every cost optimisation needs a quality A/B, not just a spend chart."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving","moduleLabel":"AI/ML"},{"key":"aiml:rag-architecture-interview-questions--rag-pipeline-design","moduleId":"aiml","cardId":"rag-architecture-interview-questions--rag-pipeline-design","front":"Design a RAG system for 500,000 internal company documents. Walk me through the full pipeline.","back":"Ingestion (parse, clean, chunk, enrich with metadata, embed, index), retrieval (hybrid dense + sparse, metadata filtering, rerank), and generation (assemble context, prompt with citation requirements, verify). Critically, add an evaluation layer that measures retrieval recall and generation faithfulness separately, plus access control enforced at query time - not after retrieval.","keyPoints":["Parse quality is the foundation - bad PDF extraction cannot be fixed downstream.","Prepend document title and section heading before embedding; large recall win.","Hybrid dense + sparse with RRF, then a cross-encoder rerank.","Enforce ACLs inside the index filter, never as a post-filter.","5M vectors fits on one node - do not over-engineer the infrastructure."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:rag-architecture-interview-questions--chunking-strategies","moduleId":"aiml","cardId":"rag-architecture-interview-questions--chunking-strategies","front":"How do you choose a chunking strategy? What breaks when chunks are too small or too large?","back":"Chunks too small lose the context needed to be understood or matched; chunks too large dilute the embedding so the relevant sentence is averaged away with irrelevant text, and they waste context budget. 300–600 tokens with 10–20% overlap is a reasonable default, but structure-aware splitting beats fixed windows, and small-to-big retrieval (embed small, return the parent) resolves the trade-off directly.","keyPoints":["Too small: lost referents and split facts. Too large: diluted embeddings and wasted context.","Never split tables or code blocks - keep them atomic even if oversized.","300–600 tokens with 10–20% overlap is a reasonable starting point, not an answer.","Small-to-big (embed sentences, return parents) gives precision plus context.","Sweep chunking parameters against a real gold set; do not copy defaults."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:rag-architecture-interview-questions--vector-databases-ann","moduleId":"aiml","cardId":"rag-architecture-interview-questions--vector-databases-ann","front":"Compare HNSW, IVF and product quantisation. How would you choose an index for 100M vectors?","back":"HNSW is a navigable small-world graph: excellent recall/latency, but memory-heavy and slow to build. IVF partitions into clusters and searches only the nearest few - much cheaper memory, tunable via nprobe, but recall degrades near cluster boundaries. Product quantisation compresses vectors 8–64× by splitting into subvectors and quantising each, trading accuracy for memory. At 100M vectors I would use IVF-PQ or HNSW-PQ, because raw HNSW would need hundreds of gigabytes of RAM.","keyPoints":["HNSW: best recall/latency, ~1.5× vector memory, slow build.","IVF: cheap, tunable via nprobe, recall loss at cell boundaries.","PQ compresses 8–64× by per-subspace quantisation with lookup-table distances.","At 100M×768, flat/HNSW need ~300 GB; IVF-PQ needs ~10 GB.","Two-stage (lossy ANN → exact rescore → cross-encoder) recovers quality cheaply."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:rag-architecture-interview-questions--hybrid-search-reranking","moduleId":"aiml","cardId":"rag-architecture-interview-questions--hybrid-search-reranking","front":"Why does pure vector search fail, and how do hybrid search and reranking fix it?","back":"Dense embeddings capture semantics but are weak on exact tokens - product codes, error numbers, names, rare acronyms - because those get averaged into a general-topic vector. BM25 handles exact terms perfectly but misses paraphrase. Hybrid search fuses both (usually with reciprocal rank fusion). Reranking then applies a cross-encoder that reads query and document jointly, which is far more accurate than any bi-encoder similarity and typically the single biggest quality win in a RAG system.","keyPoints":["Dense embeddings fail on rare exact tokens; BM25 fails on paraphrase.","RRF fuses ranked lists without score normalisation - the robust default.","Cross-encoders read query and document jointly and are far more accurate than bi-encoders.","Hybrid fixes recall; reranking fixes precision at the top. Diagnose recall@50 first.","Apply an absolute relevance threshold - irrelevant context causes hallucination."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:rag-architecture-interview-questions--rag-evaluation","moduleId":"aiml","cardId":"rag-architecture-interview-questions--rag-evaluation","front":"How do you evaluate a RAG system? Your users say it 'sometimes gives wrong answers'.","back":"Evaluate retrieval and generation separately, because they fail differently. For retrieval: recall@k, precision@k and NDCG against a gold set of query→relevant-chunk pairs. For generation: faithfulness (is every claim supported by the retrieved context?), answer relevance, and citation accuracy. Then build a failure taxonomy from real bad answers so you know which stage to fix - most 'wrong answers' turn out to be retrieval misses, not model failures.","keyPoints":["Evaluate retrieval and generation separately - they fail for different reasons.","Classify 50 real failures by stage before building metrics.","Gold set: real queries, expert-labelled chunks, ≥15% unanswerable, plus adversarial cases.","Faithfulness = fraction of atomic claims supported by the retrieved context.","Validate the LLM judge against human labels and pin its version."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions","moduleLabel":"AI/ML"},{"key":"aiml:ai-agents-and-tool-calling--agent-loop-architecture","moduleId":"aiml","cardId":"ai-agents-and-tool-calling--agent-loop-architecture","front":"Describe the core agent loop. What are the main failure modes and how do you bound them?","back":"The loop is: observe state → decide (LLM picks a tool and arguments) → act (execute) → observe result → repeat until a stop condition. Main failure modes are infinite loops, repeated identical tool calls, context overflow from accumulated results, cascading errors from a bad early step, and unbounded cost. Bound them with a step limit, a token/cost budget, loop detection on repeated calls, per-tool timeouts, and a fallback that returns partial results rather than failing.","keyPoints":["Loop: observe → decide → act → observe, with an explicit stop condition.","Return tool errors to the model as observations so it can self-correct.","Bound steps, tokens, wall-clock time and cost - check before each LLM call.","Detect repeated identical tool calls and tell the model explicitly.","If you can draw the flowchart, write the flowchart instead of using an agent."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling","moduleLabel":"AI/ML"},{"key":"aiml:ai-agents-and-tool-calling--tool-design","moduleId":"aiml","cardId":"ai-agents-and-tool-calling--tool-design","front":"How do you design tools for an LLM agent? What makes a tool schema good or bad?","back":"Design tools for the model, not for the machine. Good tools have few parameters, unambiguous names, descriptions that explain when to use them and when not to, enums instead of free strings, and return concise structured results with actionable errors. Bad tools mirror your internal API surface: dozens of overlapping endpoints with generic names and huge unfiltered payloads.","keyPoints":["Tool descriptions are prompts - say what it does, when to use it, when not to.","Keep the tool count low (accuracy degrades past ~20) and the parameters few.","Use enums, patterns and defaults so invalid arguments are impossible.","Shape results aggressively: 1,300 useful tokens beats 18,000 raw ones.","Enforce limits, idempotency and approval in code, never in the prompt."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling","moduleLabel":"AI/ML"},{"key":"aiml:ai-agents-and-tool-calling--agent-memory-planning","moduleId":"aiml","cardId":"ai-agents-and-tool-calling--agent-memory-planning","front":"How do you give an agent memory and planning ability across a long task?","back":"Separate short-term working memory (the current message list, compacted as it grows) from long-term memory (a retrievable store of facts, decisions and past outcomes) and from a task state object (an explicit structured record of the plan and progress). For planning, prefer an explicit plan artefact the agent writes and updates over implicit chain-of-thought, because you can then inspect it, resume from it, and validate it.","keyPoints":["Separate working memory, long-term memory and structured task state.","An explicit plan artefact is compact, inspectable, resumable and verifiable.","Truncate tool outputs at the source; store the full payload behind a handle.","Extract durable facts and discard raw transcripts on compaction.","Plan → execute → re-plan on failure beats both pure planning and pure ReAct."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling","moduleLabel":"AI/ML"},{"key":"aiml:ai-agents-and-tool-calling--prompt-injection-guardrails","moduleId":"aiml","cardId":"ai-agents-and-tool-calling--prompt-injection-guardrails","front":"Your agent reads web pages and emails. How do you defend against prompt injection?","back":"Accept that no prompt-level defence is reliable and design so a successful injection cannot cause harm. That means least-privilege tool access scoped per task, human approval for irreversible or high-value actions, hard limits enforced in code, clear separation and labelling of untrusted content, output filtering to catch exfiltration, and an audit trail. Detection classifiers and delimiter tricks are defence in depth, not the control.","keyPoints":["There is no architectural separation between instructions and data in an LLM.","Design so that a successful injection cannot cause harm - bound the blast radius.","Drop irreversible capabilities once untrusted content enters the context.","Enforce value limits, rate limits and egress rules in code, never in prompts.","Act with the user's permissions, not the agent's service account."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling","moduleLabel":"AI/ML"},{"key":"aiml:ai-agents-and-tool-calling--multi-agent-systems","moduleId":"aiml","cardId":"ai-agents-and-tool-calling--multi-agent-systems","front":"When is a multi-agent system better than a single agent, and what goes wrong?","back":"Multi-agent helps when subtasks are genuinely independent and parallelisable, when they need different tools or permissions, or when you want an adversarial check such as a separate critic. It hurts through context fragmentation, expensive and lossy inter-agent communication, error compounding across handoffs, and dramatically harder debugging. Most 'multi-agent' problems are better solved by one agent with well-designed tools.","keyPoints":["Default to one agent with well-designed tools.","Every handoff is a lossy compression step; context fragmentation is the core problem.","Error rates compound multiplicatively across stages.","Multi-agent typically costs 4–6× a single agent for the same task.","The critic pattern (fresh-context reviewer) is the reliably valuable exception."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling","moduleLabel":"AI/ML"},{"key":"aiml:ml-deployment-and-serving-patterns--serving-patterns","moduleId":"aiml","cardId":"ml-deployment-and-serving-patterns--serving-patterns","front":"Compare batch, online and streaming inference. How do you choose?","back":"Batch precomputes predictions on a schedule and serves them from a key-value store - cheapest and simplest, but predictions are stale and you can only score entities you know about. Online computes on request - fresh and works for unseen inputs, but you must meet a latency SLA and have every feature available at request time. Streaming sits between: predictions update on events. Choose by how quickly the input changes and how tight the latency budget is.","keyPoints":["Choose from the product decision: when is the prediction consumed and how fast does the input change?","Write down the latency budget - feature fetching is often larger than inference.","Most real systems are hybrid: precompute the expensive part, compute the fresh part online.","Batch failures are silent; always serve and monitor a prediction-freshness timestamp."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns","moduleLabel":"AI/ML"},{"key":"aiml:ml-deployment-and-serving-patterns--training-serving-skew","moduleId":"aiml","cardId":"ml-deployment-and-serving-patterns--training-serving-skew","front":"What is training/serving skew and how do you prevent it structurally?","back":"Skew is any difference between how a feature is computed in training and at inference: different code, different data sources, different time windows, or different handling of missing values. The structural fixes are a single shared feature-transformation library used by both paths, a feature store with point-in-time correct training data and identical online serving, and continuous monitoring that re-scores logged serving features offline and compares distributions.","keyPoints":["Skew has six flavours: implementation, temporal, source, freshness, null-handling, distribution.","One shared transformation module used by both paths is the structural fix.","Bake a feature-schema signature into the model artefact and refuse to serve on mismatch.","Log serving features and re-score offline - this one practice catches most skew.","Feature stores productise point-in-time correctness; adopt when scale justifies it."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns","moduleLabel":"AI/ML"},{"key":"aiml:ml-deployment-and-serving-patterns--safe-rollout","moduleId":"aiml","cardId":"ml-deployment-and-serving-patterns--safe-rollout","front":"How do you safely roll out a new model version to production?","back":"Shadow first: run the new model on real traffic without serving its output, and compare score distributions and latency against the incumbent. Then canary a small percentage with automated guardrail monitoring, ramp progressively, and keep the old version warm for instant rollback. Ship the model behind a flag so the rollback is a config change, not a redeploy.","keyPoints":["Shadow → canary → A/B → permanent holdback, in that order.","Shadow catches latency and skew problems offline evaluation cannot.","Automate guardrail kill thresholds so rollback needs no human.","Rollback must be a config flag against a warm artefact, not a redeploy.","Model rollback does not undo downstream writes; gate mutating effects."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns","moduleLabel":"AI/ML"},{"key":"aiml:ml-deployment-and-serving-patterns--ml-testing","moduleId":"aiml","cardId":"ml-deployment-and-serving-patterns--ml-testing","front":"How do you test machine learning code? What is different from testing regular software?","back":"Regular software has deterministic expected outputs; ML code has statistical ones. So you test at four levels: data tests (schema, ranges, null rates, distribution), code tests (deterministic unit tests on transformations, shape and dtype assertions), model tests (behavioural - invariance, directional expectation, minimum functionality - plus performance thresholds on a frozen set), and infrastructure tests (serialisation round-trip, latency, training/serving parity).","keyPoints":["ML tests assert properties, not exact outputs.","Four levels: data contracts, deterministic code tests, behavioural model tests, infrastructure tests.","Behavioural: invariance, directional expectation, minimum functionality.","Test per-segment performance - aggregate gains hide segment regressions.","Data contracts must fail the pipeline, not log a warning."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns","moduleLabel":"AI/ML"},{"key":"aiml:ml-deployment-and-serving-patterns--reproducibility","moduleId":"aiml","cardId":"ml-deployment-and-serving-patterns--reproducibility","front":"A model trained six months ago needs to be retrained. What do you need to reproduce it?","back":"Five things must be versioned together: code (git SHA), data (a snapshot or immutable query with a timestamp), environment (pinned dependencies and a container digest), configuration (all hyperparameters and feature definitions), and random seeds. Experiment tracking should record all five automatically at training time, plus the resulting metrics and artefacts, because nobody reconstructs this retrospectively.","keyPoints":["Version code, data, environment, config and seeds - all five, together.","Data is the hard part; use snapshots or table-format time travel.","Capture provenance automatically in the training entrypoint, never manually.","Refuse to train from a dirty git tree.","Aim for statistical reproducibility; bit-exactness costs throughput."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns","moduleLabel":"AI/ML"},{"key":"aiml:model-monitoring-and-drift-detection--drift-types","moduleId":"aiml","cardId":"model-monitoring-and-drift-detection--drift-types","front":"Distinguish data drift, concept drift and label drift. Which is most dangerous?","back":"Data drift is a change in P(X) - the inputs shift but the input→output relationship holds. Concept drift is a change in P(Y|X) - the same inputs now imply a different outcome. Label drift is a change in P(Y), the base rate. Concept drift is the most dangerous because it is invisible in input monitoring: your features look perfectly normal while the model is systematically wrong.","keyPoints":["Data drift = P(X) changes; concept drift = P(Y|X) changes; label drift = P(Y) changes.","Concept drift is most dangerous because input monitoring stays green.","PSI measures effect size and is the operational alert; KS p-values fire constantly at scale.","Without labels, monitor prediction distribution, confidence collapse and proxy outcomes.","Adversarial domains guarantee concept drift by design."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection","moduleLabel":"AI/ML"},{"key":"aiml:model-monitoring-and-drift-detection--retraining-strategy","moduleId":"aiml","cardId":"model-monitoring-and-drift-detection--retraining-strategy","front":"How do you decide when to retrain a model? Scheduled, triggered, or continuous?","back":"Scheduled retraining is simple and predictable but wastes compute when nothing changed and reacts too slowly when something did. Trigger-based retrains on a signal - drift above threshold, performance below floor, or enough new labels - which is more efficient but needs reliable signals. Continuous/online learning adapts fastest but is hard to validate and easy to poison. Most production systems use scheduled retraining with a trigger override and a mandatory offline gate before any deploy.","keyPoints":["Most systems: scheduled cadence with trigger overrides and a cooldown.","Triggers: model age, PSI, performance floor, sufficient new labels.","Automatic retraining must not imply automatic deployment - keep the gate.","Time-decayed weighting usually beats both sliding and expanding windows.","Keep a random exploration bucket or the training distribution collapses onto the model's own decisions."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection","moduleLabel":"AI/ML"},{"key":"aiml:model-monitoring-and-drift-detection--ml-incident-response","moduleId":"aiml","cardId":"model-monitoring-and-drift-detection--ml-incident-response","front":"Production alerts fire: your model's predictions have shifted dramatically. Walk me through your response.","back":"Mitigate first, diagnose second. Check whether the impact is user-visible and, if so, roll back or fall back to a safe default immediately - do not debug in production while users are affected. Then work up the stack: is it the model, the features, the upstream data, or a genuine world change? The most common cause by far is an upstream data pipeline change, not the model.","keyPoints":["Mitigate before diagnosing: roll back or fall back if users are affected.","Golden-batch re-scoring bisects model-vs-input in one step.","Most ML incidents are upstream data incidents, not model failures.","Look for null spikes, constant values, unit changes and new categories before subtle drift.","The postmortem's output should be a new monitor or data contract."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection","moduleLabel":"AI/ML"},{"key":"aiml:model-monitoring-and-drift-detection--inference-optimization","moduleId":"aiml","cardId":"model-monitoring-and-drift-detection--inference-optimization","front":"Your model meets accuracy targets but p99 latency is 800 ms against a 100 ms budget. How do you fix it?","back":"Profile first to find where the 800 ms goes - it is frequently feature fetching or serialisation rather than the model. Then work through: batching and async I/O, caching, model-level optimisation (quantisation, ONNX/TensorRT export, operator fusion), architectural changes (distillation to a smaller model, a two-stage cascade), and finally hardware. Distillation and cascades usually give the biggest wins.","keyPoints":["Profile every stage first - feature I/O and logging often dominate the model.","Move logging and non-essential work off the request path.","Cascades give large average-latency and cost wins with tunable accuracy loss.","Distillation on unlabelled production data matches the real serving distribution.","Measure p99 under realistic concurrency; the tail is queueing, not compute."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection","moduleLabel":"AI/ML"},{"key":"aiml:model-monitoring-and-drift-detection--ml-cost-management","moduleId":"aiml","cardId":"model-monitoring-and-drift-detection--ml-cost-management","front":"Your ML infrastructure costs $200k/month. How would you reduce it without hurting model quality?","back":"Attribute costs first - training, inference, storage, data processing - because teams are usually wrong about the split. Then: right-size instances and use spot for training, cache aggressively, use cascades and smaller distilled models for inference, autoscale to real traffic instead of peak, delete unused features and stale artefacts, and kill models nobody uses. The last one is usually the single biggest saving and nobody looks for it.","keyPoints":["Attribute costs before optimising - intuitions about the split are usually wrong.","Audit deployed models by call volume; unused endpoints are free savings.","Spot instances with checkpointing cut training cost 60–80%.","GPU utilisation below ~20% means consolidate or move to CPU.","Report cost and quality together, and gate cuts behind the same canary as a model change."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-framework--the-framework","moduleId":"aiml","cardId":"ml-system-design-framework--the-framework","front":"Walk me through your framework for an ML system design interview.","back":"Eight steps: clarify requirements and constraints, define the ML problem and metrics, design the data strategy, do feature engineering, choose a model with a baseline, define training and evaluation, design serving and scale, then close with monitoring and iteration. Spend the first 5–8 minutes on clarification - it is the highest-leverage part and the part most candidates skip.","keyPoints":["Eight steps: clarify → frame → data → features → model → train/eval → serve → monitor.","Spend the first 5–8 minutes clarifying; write the constraints down.","Do the QPS, storage and cost arithmetic out loud - it constrains every later choice.","Always propose a baseline before the sophisticated model.","Manage the clock explicitly and narrate your prioritisation."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-framework--choosing-metrics","moduleId":"aiml","cardId":"ml-system-design-framework--choosing-metrics","front":"How do you pick the right metrics in a system design interview, and how do you connect offline to online?","back":"Define three layers and state how they connect: the business metric (revenue, retention, cost), the online product metric that is a fast proxy for it (CTR, completion rate, resolution rate), and the offline ML metric you can compute without shipping (NDCG@k, PR-AUC, faithfulness). Then name the guardrails that must not regress and say explicitly that offline metrics are proxies to be validated by an A/B test.","keyPoints":["Three layers: business → online product → offline ML, plus guardrails.","State the proxy chain and say you would validate the correlations.","Name the classic proxy traps: clickbait, length bias, engagement-vs-integrity.","Define launch criteria as primary lift AND no guardrail regression.","Propose a long-term holdback to catch feedback-loop damage."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-framework--design-recommendation-system","moduleId":"aiml","cardId":"ml-system-design-framework--design-recommendation-system","front":"Design a recommendation system for a video platform with 100M users and 50M videos.","back":"A multi-stage funnel: candidate generation narrows 50M videos to ~1,000 using a two-tower retrieval model plus complementary sources (trending, subscriptions, collaborative filtering), a ranking model scores those few hundred with rich cross features and multi-task heads, and a re-ranking layer applies diversity, freshness and business rules. Item embeddings are precomputed; the user tower runs online with ANN search.","keyPoints":["Multi-stage funnel: 50M → 1,000 → 800 → 20, spending compute where it changes the outcome.","Two-tower's no-interaction constraint is what enables precomputed item vectors and ANN search.","Use in-batch negatives with the logQ correction or you under-recommend popular items.","Multi-task ranking with a shared trunk; combine heads with product-tuned weights.","Handle cold start, position bias, diversity and freshness explicitly - they will be probed."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-framework--design-fraud-detection","moduleId":"aiml","cardId":"ml-system-design-framework--design-fraud-detection","front":"Design a real-time fraud detection system for a payments company.","back":"A layered system: deterministic rules for known patterns and hard blocks, a real-time ML model scoring every transaction within a ~100 ms budget using streaming velocity features, and a case-management queue for the uncertain band. Because fraud is adversarial and labels arrive 30–90 days late via chargebacks, the design must include an exploration bucket, rapid rule deployment, and monitoring that does not depend on labels.","keyPoints":["Fraud is adversarial, extremely imbalanced, and has delayed censored labels - say this first.","Layer rules + ML + a three-band decision policy + analyst queue + feedback loop.","Streaming velocity and entity fan-out features carry most of the signal.","A challenge/step-up band is what makes the economics work.","Exploration bucket is mandatory or the model goes blind at the boundary."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-framework--design-llm-assistant","moduleId":"aiml","cardId":"ml-system-design-framework--design-llm-assistant","front":"Design a customer support AI assistant for a company with 10M users.","back":"A tiered system: intent classification routes trivial requests to deterministic flows, a RAG pipeline over help-centre and policy content handles informational questions, tool calling handles account actions with strict permission scoping, and confident escalation hands off to humans with full context. Wrap it in caching, guardrails, evaluation and a feedback loop - and design the human handoff first, because it is what determines user trust.","keyPoints":["Design the escalation criteria before the automation.","Route by intent and risk - 30–40% of volume never needs an LLM.","Cache aggressively: support questions are highly repetitive.","Verify before sending: citations, PII, faithfulness - escalate on failure.","Measure containment, CSAT, escalation reasons and 7-day re-contact rate."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-search-and-ranking--design-search-ranking","moduleId":"aiml","cardId":"ml-system-design-search-and-ranking--design-search-ranking","front":"Design the search ranking system for an e-commerce site with 100M products.","back":"Query understanding (spell correction, intent, attribute extraction), retrieval (inverted index for lexical + vector index for semantic, fused), then learning-to-rank over the candidates using query, product, query-product and behavioural features. Optimise NDCG offline but the real objective is conversion, and the key trap is position bias in the click logs used for training.","keyPoints":["Query understanding → hybrid retrieval → LTR → re-rank, with a ~100 ms budget.","E-commerce optimises conversion, not pure relevance; attributes should become filters.","Position bias is the central trap - correct with an examination model or IPW.","Serve with the relevance tower only; position exists solely for training.","Handle head/tail queries, zero-results and sponsored blending explicitly."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-search-and-ranking--design-feed-ranking","moduleId":"aiml","cardId":"ml-system-design-search-and-ranking--design-feed-ranking","front":"Design the ranking system for a social feed. How is it different from search?","back":"There is no query, so intent must be inferred from context and history; recency matters enormously; the objective is multi-dimensional (engagement, satisfaction, creator ecosystem health, integrity); and the feedback loop is severe because the feed shapes the behaviour you learn from. Architecture is still a funnel - candidate sources, a multi-task ranker, then a re-ranking layer applying diversity, integrity and pacing rules.","keyPoints":["No query means intent is inferred; recency and diversity matter far more.","Blend multiple candidate sources with deliberate exploration and fresh-creator quotas.","Multi-task prediction with product-tuned weights; integrity as a hard constraint.","Weight negative signals (hide, report, unfollow) heavily and asymmetrically.","Feedback loops are severe - use exploration, holdbacks and long-horizon metrics."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-search-and-ranking--design-ads-ctr","moduleId":"aiml","cardId":"ml-system-design-search-and-ranking--design-ads-ctr","front":"Design a click-through-rate prediction system for an ad platform.","back":"Predict calibrated P(click) for every eligible ad, then rank by expected value - bid × pCTR (× pConversion for conversion campaigns) - inside a second-price-style auction. The defining constraints are extreme scale (millions of QPS, billions of sparse features), a hard sub-50 ms budget, and an absolute requirement for calibrated probabilities because those probabilities directly determine what advertisers pay.","keyPoints":["pCTR feeds an auction, so calibration is a billing-accuracy requirement.","Rank by expected value (bid × pCTR × quality), price by second-price mechanics.","Handle sparsity with hashing plus learned embeddings and feature crosses.","Monitor calibration per bucket daily - miscalibration concentrates in high-pCTR ads.","Guard revenue with advertiser-ROI and user-experience metrics."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-search-and-ranking--design-content-moderation","moduleId":"aiml","cardId":"ml-system-design-search-and-ranking--design-content-moderation","front":"Design a content moderation system for a platform with 1B posts per day.","back":"A tiered pipeline: hash matching for known violating content (instant, exact), fast multimodal classifiers on everything, escalation of uncertain or high-reach content to stronger models, and human review for the ambiguous and appealable tail. The defining constraints are asymmetric error costs that differ per policy, adversarial evasion, cultural and linguistic context, and a legally required appeals path.","keyPoints":["Tier: hash match → fast classifier → heavy model → human review, with per-policy thresholds.","Error-cost asymmetry differs per policy; one global threshold is wrong.","Weight scrutiny by reach - high-reach content gets a lower review bar.","Human review capacity is the real constraint; a 0.1% shift is thousands of staff.","Adversarial evasion, per-language fairness, appeals and backfill are all design requirements."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking","moduleLabel":"AI/ML"},{"key":"aiml:ml-system-design-search-and-ranking--handling-scale-questions","moduleId":"aiml","cardId":"ml-system-design-search-and-ranking--handling-scale-questions","front":"The interviewer asks 'what if traffic grows 100×?' How do you answer well?","back":"Identify what actually breaks first rather than saying 'add more machines'. Walk through each component and state whether it scales horizontally, vertically or not at all: stateless serving scales trivially, the feature store becomes the bottleneck, the vector index may no longer fit in memory, training data volume forces sampling, and the human-in-the-loop components hit a hard staffing ceiling. Then propose the specific change for the first thing to break.","keyPoints":["Name what breaks first and why, then the fix, then the next constraint.","Stateless serving is almost never the bottleneck.","At extreme scale, training data volume and human-in-the-loop capacity break first.","Do the arithmetic - it turns a hand-wave into a defensible answer.","Be able to answer the reverse question about far less data too."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking","moduleLabel":"AI/ML"},{"key":"aiml:numpy-pandas-ml-coding-interview--vectorization-broadcasting","moduleId":"aiml","cardId":"numpy-pandas-ml-coding-interview--vectorization-broadcasting","front":"Vectorise a nested loop that computes pairwise distances. Explain broadcasting rules.","back":"Use the expansion ‖a−b‖² = ‖a‖² + ‖b‖² − 2a·b so the whole distance matrix is one matmul plus two broadcasts. Broadcasting aligns shapes from the right, and dimensions are compatible if they are equal or one of them is 1; size-1 dimensions are stretched without copying. This turns an O(n·m) Python loop into a single BLAS call - typically 100–1000× faster.","keyPoints":["‖a−b‖² = ‖a‖² + ‖b‖² − 2a·b turns pairwise distance into one matmul.","Broadcasting aligns right; dims must be equal or 1; size-1 dims stretch via stride-0.","Guard sqrt with np.maximum(d2, 0) - fp cancellation produces tiny negatives.","The 3D difference tensor is a memory trap, not a speed trap.","keepdims=True is required whenever you divide by a reduction."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview","moduleLabel":"AI/ML"},{"key":"aiml:numpy-pandas-ml-coding-interview--implement-kmeans","moduleId":"aiml","cardId":"numpy-pandas-ml-coding-interview--implement-kmeans","front":"Implement k-means from scratch, including k-means++ initialisation.","back":"Initialise centroids with k-means++ (pick the first uniformly, then each subsequent one with probability proportional to squared distance from the nearest existing centroid), then alternate assignment (each point to its nearest centroid) and update (each centroid to the mean of its points) until the assignments stop changing or the inertia change falls below a tolerance.","keyPoints":["Alternate assignment and update until assignments stabilise or inertia plateaus.","k-means++ samples each new centroid with probability ∝ D² to the nearest existing one.","Handle empty clusters explicitly or you get NaN centroids.","Use n_init restarts - the objective is non-convex.","O(n·k·d) per iteration; use mini-batch k-means at large n."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview","moduleLabel":"AI/ML"},{"key":"aiml:numpy-pandas-ml-coding-interview--implement-logistic-regression","moduleId":"aiml","cardId":"numpy-pandas-ml-coding-interview--implement-logistic-regression","front":"Implement logistic regression with gradient descent, numerically stable and regularised.","back":"Use a numerically stable sigmoid and a log-loss computed via logaddexp so you never take log(0). The gradient is Xᵀ(p − y)/n plus the regularisation term, with the intercept excluded from the penalty. Add a convergence check on the gradient norm and support mini-batching.","keyPoints":["Branch the sigmoid on the sign of z to avoid exp overflow.","Compute log-loss from logits with logaddexp - never log(p).","Gradient is Xᵀ(p − y)/n; the intercept is never penalised.","Always gradient-check a hand-rolled model with finite differences.","Extensions: softmax multi-class, class weights, IRLS, early stopping."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview","moduleLabel":"AI/ML"},{"key":"aiml:numpy-pandas-ml-coding-interview--pandas-performance","moduleId":"aiml","cardId":"numpy-pandas-ml-coding-interview--pandas-performance","front":"This pandas code takes 20 minutes on 50M rows. How do you speed it up?","back":"Profile first, then apply in order: eliminate `.apply` and `iterrows` in favour of vectorised operations or `groupby.transform`, downcast dtypes and use categoricals (often 5–10× memory reduction), avoid repeated concatenation in loops, use merge on indexed and sorted keys, chunk or move to a columnar engine (Polars, DuckDB) when the data no longer fits comfortably in memory.","keyPoints":["`.apply(axis=1)` and `iterrows` are the usual culprits - vectorise them.","`groupby.transform` beats groupby-then-merge for broadcasting aggregates.","Categorical and downcast dtypes often cut memory 5×, speeding everything up.","Never concat inside a loop - it is quadratic.","Beyond ~100M rows, move to Polars or DuckDB over Parquet."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview","moduleLabel":"AI/ML"},{"key":"aiml:numpy-pandas-ml-coding-interview--implement-attention","moduleId":"aiml","cardId":"numpy-pandas-ml-coding-interview--implement-attention","front":"Implement multi-head self-attention in PyTorch with a KV cache for generation.","back":"Project to Q, K, V, reshape to (batch, heads, seq, head_dim), compute scaled dot-product scores with a causal mask, softmax, multiply by V, then merge heads and apply the output projection. For generation, cache K and V across steps and only compute Q, K, V for the new token - turning each step from O(n²) to O(n).","keyPoints":["Fuse the QKV projection; reshape to (B, H, T, head_dim); scale by √head_dim.","Mask before softmax with −inf, and offset the mask correctly when using a cache.","KV caching turns generation from O(n²) to O(n) - ~13× at 200 tokens.","`.contiguous()` is required after transpose before `.view()`.","Use `F.scaled_dot_product_attention` in production for the fused Flash kernel."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview","moduleLabel":"AI/ML"},{"key":"aiml:pytorch-and-ml-engineering-coding--autograd-mechanics","moduleId":"aiml","cardId":"pytorch-and-ml-engineering-coding--autograd-mechanics","front":"Explain how autograd works. What do requires_grad, detach, no_grad and retain_graph do?","back":"PyTorch builds a dynamic computation graph during the forward pass, recording each operation and its inputs. Calling `.backward()` traverses it in reverse applying the chain rule and accumulating into `.grad`. `requires_grad` marks a tensor as needing gradients; `detach()` returns a tensor sharing storage but cut from the graph; `no_grad()` disables graph construction entirely for a block; `retain_graph=True` keeps the graph alive so you can backward through it twice.","keyPoints":["The graph is built during the forward pass and traversed in reverse by `.backward()`.","Gradients accumulate - hence `zero_grad()` every step.","`detach()` cuts the output from the graph but shares storage; `no_grad()` disables tracking wholesale.","`total_loss += loss` without `.item()` leaks the entire graph each step.","Dynamic graphs are what make Python control flow work inside `forward`."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding","moduleLabel":"AI/ML"},{"key":"aiml:pytorch-and-ml-engineering-coding--training-loop-from-memory","moduleId":"aiml","cardId":"pytorch-and-ml-engineering-coding--training-loop-from-memory","front":"Write a complete, correct PyTorch training loop from memory.","back":"Set the model to train mode, iterate batches, move to device, zero gradients, forward, compute loss, backward, clip gradients, optimiser step, scheduler step. Then a validation pass under `no_grad()` in eval mode, tracking the best checkpoint. The details that separate correct from nearly-correct are `zero_grad(set_to_none=True)`, `.item()` for accumulation, model.train()/eval() toggling, and stepping the scheduler at the right granularity.","keyPoints":["train()/eval() toggling, zero_grad(set_to_none=True), .item() accumulation.","Clip gradients after backward and before optimiser step.","Step per-batch schedulers inside the loop, per-epoch ones outside.","Save optimiser and scheduler state alongside the model to resume correctly.","Overfit a single batch first as a sanity check."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding","moduleLabel":"AI/ML"},{"key":"aiml:pytorch-and-ml-engineering-coding--debug-broken-model","moduleId":"aiml","cardId":"pytorch-and-ml-engineering-coding--debug-broken-model","front":"A model's loss is NaN after 50 steps and another isn't learning at all. Debug both.","back":"For NaN: check for division by zero or log(0) in the loss, exploding gradients (log the gradient norm), fp16 overflow, and bad input data. For not-learning: verify the loss is actually connected to the parameters, that `zero_grad` and `step` are both called, that the learning rate is sane, that labels align with predictions, and that the model can overfit a single batch.","keyPoints":["Check inputs → shapes → initial loss vs ln(k) → gradient norms → overfit one batch.","NaN after N steps means growing gradients; log the norm to find the real start.","Params with `grad is None` indicate a detached or unused branch.","Loss stuck at exactly ln(k) means gradients are not reaching the parameters.","`set_detect_anomaly(True)` pinpoints the op, at ~3× slowdown."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding","moduleLabel":"AI/ML"},{"key":"aiml:pytorch-and-ml-engineering-coding--custom-dataset-dataloader","moduleId":"aiml","cardId":"pytorch-and-ml-engineering-coding--custom-dataset-dataloader","front":"Write a custom Dataset and DataLoader for variable-length text, including a collate function.","back":"Implement `__len__` and `__getitem__` returning a single unbatched example, then write a `collate_fn` that pads sequences to the batch maximum and builds an attention mask. Pad to the longest in the batch rather than a global maximum, and use a length-grouped sampler so batches contain similar lengths - that alone often cuts wasted compute by 30–50%.","keyPoints":["`__getitem__` returns one unbatched example; `collate_fn` assembles the batch.","Pad to the batch maximum, never a global maximum.","Length-grouped sampling can cut padding waste from ~60% to ~10%.","num_workers + pin_memory + persistent_workers keep the GPU fed.","Each worker copies the dataset object - avoid holding large data in memory."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding","moduleLabel":"AI/ML"},{"key":"aiml:pytorch-and-ml-engineering-coding--profiling-optimization","moduleId":"aiml","cardId":"pytorch-and-ml-engineering-coding--profiling-optimization","front":"Your training epoch takes 40 minutes and GPU utilisation is 30%. Find and fix the bottleneck.","back":"30% utilisation almost always means the GPU is starved by the input pipeline, not that the model is slow. Check data loading first (num_workers, pin_memory, expensive per-item transforms, slow storage), then synchronisation points (`.item()`, `.cpu()`, printing inside the loop), then the model itself. Use the PyTorch profiler to see the actual gaps rather than guessing.","keyPoints":["Low GPU utilisation means the input pipeline is the bottleneck, not the model.","Profile with torch.profiler; do not guess.","num_workers, pin_memory and persistent_workers are the first fixes.","`.item()` and prints in the hot loop force CPU-GPU synchronisation.","Then bf16 autocast, torch.compile, channels_last - roughly 7× cumulative in practice."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding","moduleLabel":"AI/ML"},{"key":"aiml:ml-behavioral-and-project-deep-dive--project-deep-dive","moduleId":"aiml","cardId":"ml-behavioral-and-project-deep-dive--project-deep-dive","front":"Tell me about the most impactful ML project you have worked on.","back":"Structure it as: business context and why it mattered, your specific role and what you decided, the two or three hardest technical decisions with the alternatives you rejected, the measured outcome in business terms, and what you would do differently. Two minutes for the narrative, then let their questions steer the depth.","keyPoints":["Lead with the problem and the decisions, not the chronology.","Be precise about your scope and honest about the team's contributions.","Two or three hard decisions, each with the rejected alternative.","Close with business-metric impact and a genuine reflection.","Only tell stories you can defend three follow-ups deep."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive","moduleLabel":"AI/ML"},{"key":"aiml:ml-behavioral-and-project-deep-dive--failure-story","moduleId":"aiml","cardId":"ml-behavioral-and-project-deep-dive--failure-story","front":"Tell me about a time an ML project failed or a model performed badly in production.","back":"Pick a real failure with real consequences that you were genuinely responsible for, explain the root cause honestly, describe what you did to detect and fix it, and - most importantly - what you changed *systemically* so it could not recur. The systemic change is what converts a failure story into evidence of seniority.","keyPoints":["Pick a real failure with real consequences that you owned.","State the root cause honestly, including your part in it.","Be truthful about whether you or someone else caught it.","The systemic fix is the point - fix the class of bug, not the instance.","Prepare two: one technical, one judgement-based."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive","moduleLabel":"AI/ML"},{"key":"aiml:ml-behavioral-and-project-deep-dive--disagreement-story","moduleId":"aiml","cardId":"ml-behavioral-and-project-deep-dive--disagreement-story","front":"Tell me about a time you disagreed with a colleague or your manager on a technical decision.","back":"Pick a substantive disagreement, explain both positions fairly, describe how you tried to resolve it with evidence rather than opinion, and state the outcome honestly - including cases where you were wrong or where you disagreed and committed anyway. The quality of the resolution process matters far more than who turned out to be right.","keyPoints":["Steelman the other position before explaining yours.","Convert the disagreement into the cheapest experiment that resolves it.","Stories where you were wrong or committed after losing are stronger than vindication stories.","Pre-register what would change your mind, then commit fully.","Never disparage the other person."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive","moduleLabel":"AI/ML"},{"key":"aiml:ml-behavioral-and-project-deep-dive--ambiguity-and-prioritisation","moduleId":"aiml","cardId":"ml-behavioral-and-project-deep-dive--ambiguity-and-prioritisation","front":"How do you approach a problem where the requirements are unclear and the stakeholder can't tell you what they want?","back":"Work backwards from the decision the output will drive. Ask what action changes based on the model's answer, who takes it, and what happens today without one. That usually converts a vague request into a concrete prediction problem with a clear metric. Then propose the smallest thing that tests the hypothesis, rather than trying to specify the full system up front.","keyPoints":["Ask what decision changes based on the output - it derives every requirement.","Establish today's baseline: who decides, how fast, how well, at what cost.","Ask the cost of being wrong in each direction to derive metric and threshold.","Propose the smallest time-boxed test rather than a full specification.","Be willing to say ML is the wrong tool."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive","moduleLabel":"AI/ML"},{"key":"aiml:ml-behavioral-and-project-deep-dive--explaining-to-non-technical","moduleId":"aiml","cardId":"ml-behavioral-and-project-deep-dive--explaining-to-non-technical","front":"How do you explain a model's behaviour to a non-technical stakeholder who is unhappy with a prediction?","back":"Start by taking the specific case seriously rather than defending the model. Investigate the individual prediction, explain the drivers in their language using feature attributions, be explicit about what the model can and cannot do, and convert the complaint into either a fix or a monitored metric. Never open with 'the model is 94% accurate' - that answers a question they did not ask.","keyPoints":["Never open with aggregate accuracy - investigate the specific case.","Translate feature attributions into domain language, not SHAP values.","Be explicit and honest about the model's limitations.","Provide an override path and close the feedback loop.","Set expectations and show failure modes before launch, not after."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive","moduleLabel":"AI/ML"},{"key":"aiml:ai-ml-interview-strategy-and-offers--role-types","moduleId":"aiml","cardId":"ai-ml-interview-strategy-and-offers--role-types","front":"What is the difference between ML Engineer, Research Scientist, Applied Scientist and Data Scientist - and how do interviews differ?","back":"ML Engineer is production-focused: system design, MLOps and strong software engineering. Applied Scientist blends modelling depth with shipping and usually requires stronger ML theory plus coding. Research Scientist is publication-oriented and typically requires a PhD with a research track record. Data Scientist varies enormously by company - sometimes analytics and experimentation, sometimes modelling. Read the actual job description rather than the title.","keyPoints":["Titles are unreliable; read responsibilities and ask what the team ships.","Ask the recruiter for the loop breakdown - highest-return question in the process.","MLE = production systems; Applied Scientist = modelling + shipping; RS = publications.","AI Engineer roles test RAG, evals, agents and product judgement over classical theory.","Find out whether level is set before or after the loop."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers","moduleLabel":"AI/ML"},{"key":"aiml:ai-ml-interview-strategy-and-offers--take-home-strategy","moduleId":"aiml","cardId":"ai-ml-interview-strategy-and-offers--take-home-strategy","front":"How do you approach an ML take-home assignment to maximise your chance of passing?","back":"Optimise for what is actually graded: a clear README, a correct and leak-free evaluation, a sensible baseline before anything sophisticated, clean reproducible code, and explicit discussion of trade-offs and limitations. Time-box it, do not chase the last 2% of accuracy, and write down what you would do with more time - that section is often weighted more heavily than the model itself.","keyPoints":["Reviewers grade correctness of evaluation, code quality and write-up over raw accuracy.","Build the evaluation and a baseline before anything sophisticated.","The README is the primary deliverable - including what did not work.","Add a Makefile, pinned deps and a few tests; most submissions have none.","Include an honest Limitations section and time-box the work."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers","moduleLabel":"AI/ML"},{"key":"aiml:ai-ml-interview-strategy-and-offers--questions-to-ask","moduleId":"aiml","cardId":"ai-ml-interview-strategy-and-offers--questions-to-ask","front":"What questions should you ask your interviewers?","back":"Ask questions that reveal how the team actually works and whether ML there is real: what fraction of models reach production, how long from idea to deployment, who owns the pipelines, how success is measured, and what the last project that got cancelled was and why. Avoid questions answered on the careers page, and tailor by interviewer - ask the engineer about tooling and the manager about roadmap and levelling.","keyPoints":["Ask what fraction of started ML projects reach production.","Probe infrastructure maturity, pipeline ownership and shipping timelines.","Ask about the last cancelled project - honesty and failure handling.","Tailor questions to engineer / manager / director.","The questions you ask are part of your evaluation."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers","moduleLabel":"AI/ML"},{"key":"aiml:ai-ml-interview-strategy-and-offers--levelling-and-negotiation","moduleId":"aiml","cardId":"ai-ml-interview-strategy-and-offers--levelling-and-negotiation","front":"How do you negotiate an ML offer, and how does levelling work?","back":"Level is usually decided by the loop's feedback and matters far more than negotiating within a band - a level change is often 30–50% of total compensation. Avoid naming a number first, get the full offer in writing, negotiate on total compensation with a specific justified figure, and use competing offers if you have them. Always negotiate; it is expected, and the downside is essentially zero at a company worth joining.","keyPoints":["Level matters far more than in-band negotiation - 30–50% of total comp.","Do not name a number first; get the full offer in writing.","Make one specific, justified ask with a clear close.","Sign-on and equity usually have more flexibility than base.","Scrutinise private equity: preference stack, share count, exercise window."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers","moduleLabel":"AI/ML"},{"key":"aiml:ai-ml-interview-strategy-and-offers--first-90-days","moduleId":"aiml","cardId":"ai-ml-interview-strategy-and-offers--first-90-days","front":"You have accepted an ML engineering offer. What is your plan for the first 90 days?","back":"Days 1–30: learn the systems, the data and the people; ship something small to exercise the whole deployment path. Days 31–60: own a real piece of work and find one concrete improvement, ideally in evaluation or monitoring where gaps usually exist. Days 61–90: deliver a measurable result and propose the next thing. Throughout, write down what confuses you - that document is your most valuable contribution as a newcomer.","keyPoints":["Trace one model end to end from raw data to serving - the highest-value onboarding exercise.","Ship something small in the first weeks to learn the deployment friction.","Evaluation and monitoring gaps are usually unowned and high-value.","Keep a confusion log; share it constructively around week five.","Ask your manager what success at 90 days looks like, specifically."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers","moduleLabel":"AI/ML"},{"key":"pythonfs:fc-gil","moduleId":"pythonfs","cardId":"fc-gil","front":"Can Python threads run CPU-bound code in parallel?","back":"On a standard build, no - the GIL allows one thread to execute bytecode at a time. But the free-threaded build (PEP 703) removes it: experimental in 3.13, officially supported in 3.14.","keyPoints":["Separate build (python3.14t), not a flag - the default still has the GIL","Removing the GIL does not make your own data structures thread-safe","Single-threaded code is somewhat slower; C extensions must opt in"],"href":"/python-fullstack-interview/questions/Python-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-io-cpu","moduleId":"pythonfs","cardId":"fc-io-cpu","front":"Threads, processes or asyncio - how do you choose?","back":"I/O-bound: asyncio or threads, because the GIL is released while waiting. CPU-bound: processes, or push the work into a native library that releases the GIL.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-mutable-default","moduleId":"pythonfs","cardId":"fc-mutable-default","front":"What is wrong with `def f(items=[])`?","back":"The list is created once at definition time and shared across every call, so it accumulates between calls. Use None as the default and build inside the body.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-is-eq","moduleId":"pythonfs","cardId":"fc-is-eq","front":"When do you use `is` rather than `==`?","back":"Only for singletons - None, True, False, custom sentinels. `is` tests identity; equal values need not be the same object.","keyPoints":["CPython interning small ints makes `is` accidentally work - do not rely on it"],"href":"/python-fullstack-interview/questions/Python-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-shallow","moduleId":"pythonfs","cardId":"fc-shallow","front":"What does `list.copy()` actually copy?","back":"Only the outer list. Nested objects are still shared references, so mutating one shows through both. copy.deepcopy() copies recursively at much greater cost.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-generator","moduleId":"pythonfs","cardId":"fc-generator","front":"Generator vs list comprehension?","back":"A comprehension materialises everything; a generator yields lazily with constant memory. The trade is that a generator is single-use and cannot be indexed.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-legb","moduleId":"pythonfs","cardId":"fc-legb","front":"What does LEGB stand for, and what is the consequence?","back":"Local, Enclosing, Global, Built-in. Assigning to a name anywhere in a function makes it local for the whole function, so reading it earlier raises UnboundLocalError.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-wraps","moduleId":"pythonfs","cardId":"fc-wraps","front":"Why does a decorator need functools.wraps?","back":"Without it the wrapper replaces the original's __name__ and __doc__, breaking introspection, debugging and documentation tooling.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-slots","moduleId":"pythonfs","cardId":"fc-slots","front":"What does __slots__ do and what does it cost?","back":"Replaces the per-instance __dict__ with fixed descriptors, cutting memory substantially. The cost: no ad-hoc attributes, and awkward multiple inheritance.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-classmethod","moduleId":"pythonfs","cardId":"fc-classmethod","front":"@classmethod vs @staticmethod?","back":"classmethod receives cls, so cls(...) builds the right type for subclasses - the alternative-constructor pattern. staticmethod is just a function living in the class namespace.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-bare-except","moduleId":"pythonfs","cardId":"fc-bare-except","front":"Why avoid a bare `except:`?","back":"It catches BaseException, so it swallows SystemExit and KeyboardInterrupt - the process becomes very hard to stop. Use `except Exception:`.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-mro","moduleId":"pythonfs","cardId":"fc-mro","front":"What algorithm determines Python's method resolution order?","back":"C3 linearisation. It guarantees a class precedes its parents and preserves base order; when no consistent order exists Python refuses to create the class.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-new-init","moduleId":"pythonfs","cardId":"fc-new-init","front":"__new__ vs __init__?","back":"__new__ creates and returns the instance; __init__ configures an already-created one and must return None. You need __new__ for immutable types and singletons.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-str-repr","moduleId":"pythonfs","cardId":"fc-str-repr","front":"__str__ vs __repr__ - which do you define first?","back":"__repr__. It should be unambiguous and ideally reconstructable, and str() falls back to it. It is what you see in the REPL, in a list and in tracebacks.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-property","moduleId":"pythonfs","cardId":"fc-property","front":"Why does Python have no culture of writing getters?","back":"@property lets you turn a plain attribute into computed logic later without changing a single call site, so there is no reason to write a getter up front.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-gather","moduleId":"pythonfs","cardId":"fc-gather","front":"What does asyncio.gather buy over sequential awaits?","back":"Sequential awaits serialise the waiting. gather schedules them together, so ten 100ms calls take about 100ms - still one thread, one core.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-lru-hashable","moduleId":"pythonfs","cardId":"fc-lru-hashable","front":"Why does functools.lru_cache fail on some arguments?","back":"The cache is a dict keyed on the arguments, so they must be hashable. Passing a list or dict raises TypeError - convert to a tuple or frozenset at the boundary.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-pep695","moduleId":"pythonfs","cardId":"fc-pep695","front":"How do you write a generic function in Python 3.12+?","back":"`def identity[T](x: T) -> T:` - PEP 695 scopes the type parameter to the function, so there is no separate TypeVar. `type Alias = ...` declares a type alias.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-51-55","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-protocol","moduleId":"pythonfs","cardId":"fc-protocol","front":"Protocol vs ABC?","back":"Protocol is structural - a class matches by shape with no inheritance, checked statically. ABC is nominal - explicit inheritance, enforced at instantiation.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-51-55","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-pickle","moduleId":"pythonfs","cardId":"fc-pickle","front":"Why never unpickle untrusted data?","back":"Pickle is a code-execution format - __reduce__ can run arbitrary code on load. Use JSON, or msgpack if you need binary.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-56-60","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-profile","moduleId":"pythonfs","cardId":"fc-profile","front":"Which tool finds a slow line, and which finds a leak?","back":"cProfile for per-function cost then line_profiler for per-line; tracemalloc for allocations, by diffing two snapshots.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-56-60","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-uv","moduleId":"pythonfs","cardId":"fc-uv","front":"How do you manage dependencies on a new project in 2026?","back":"uv - it handles environments, resolution, a real lockfile and even the interpreter version in one fast tool. poetry is the common incumbent; pipenv is largely legacy.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-ruff","moduleId":"pythonfs","cardId":"fc-ruff","front":"What does Ruff replace, and what does it not?","back":"Replaces flake8, isort, pyupgrade, bandit and black. It does no type inference, so mypy or pyright stays in the stack.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-61-65","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-logger-name","moduleId":"pythonfs","cardId":"fc-logger-name","front":"Why logging.getLogger(__name__)?","back":"It names the logger after the module, and loggers form a dotted hierarchy - so you can silence myapp.db without touching myapp.api.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-61-65","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-patch-where","moduleId":"pythonfs","cardId":"fc-patch-where","front":"Where do you patch when mocking?","back":"Where the name is looked up, not where it is defined. If mymodule does `from requests import get`, patch mymodule.get.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-66-70","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-mp-pickle","moduleId":"pythonfs","cardId":"fc-mp-pickle","front":"Why does multiprocessing raise 'cannot pickle'?","back":"Processes share no memory, so arguments and returns are pickled across the boundary. Lambdas, closures and open sockets cannot be pickled; module-level functions can.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-66-70","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-str-bytes","moduleId":"pythonfs","cardId":"fc-str-bytes","front":"str vs bytes in Python 3?","back":"str is Unicode code points, bytes is raw octets, and conversion needs an explicit encoding. Decode at input, encode at output, keep str in between.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-71-75","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-eval","moduleId":"pythonfs","cardId":"fc-eval","front":"Why is eval() unsafe even with a restricted namespace?","back":"Attackers reach arbitrary objects through introspection like __class__ and __subclasses__. Use ast.literal_eval for data.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-71-75","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-reverse-list","moduleId":"pythonfs","cardId":"fc-reverse-list","front":"Reversing a linked list - why save `next` first?","back":"Setting curr.next = prev destroys the only reference to the rest of the list. Save it, flip the pointer, then advance both.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-76-80","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-lru-structure","moduleId":"pythonfs","cardId":"fc-lru-structure","front":"What two structures make an LRU cache O(1)?","back":"A hash map for O(1) lookup, plus a doubly linked list for O(1) reordering and eviction. The map stores the list node.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-76-80","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-floyd","moduleId":"pythonfs","cardId":"fc-floyd","front":"Why use Floyd's cycle detection over a visited set?","back":"Same O(n) time but O(1) space. Fast gains one position per step on slow, so they must meet; restarting one at the head then finds the loop entry.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-81-85","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-bsearch","moduleId":"pythonfs","cardId":"fc-bsearch","front":"Why `lo + (hi - lo) // 2`?","back":"In fixed-width integer languages lo + hi can overflow. Python ints cannot, but the habit matters - this exact bug sat in the JDK for nine years.","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-81-85","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-queue-stacks","moduleId":"pythonfs","cardId":"fc-queue-stacks","front":"Queue from two stacks - what is the dequeue cost?","back":"O(1) amortised. Each element moves from the in-stack to the out-stack exactly once, so n operations total O(n) even though one can be O(n).","keyPoints":[],"href":"/python-fullstack-interview/questions/Python-86-90","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-pk-unique","moduleId":"pythonfs","cardId":"fc-pk-unique","front":"PRIMARY KEY vs UNIQUE?","back":"Both enforce uniqueness and create an index. A primary key cannot be NULL and there is one per table; UNIQUE allows NULLs and you can have several.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-leftmost","moduleId":"pythonfs","cardId":"fc-leftmost","front":"An index on (a, b) - which queries can seek?","back":"Those filtering on a leftmost prefix: `a = ?` and `a = ? AND b = ?`. Filtering on b alone cannot use it.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-sargable","moduleId":"pythonfs","cardId":"fc-sargable","front":"Why does `WHERE YEAR(created) = 2026` scan?","back":"Wrapping the column in a function means the engine cannot compare against stored index values. Rewrite as a date range, which is sargable.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-covering","moduleId":"pythonfs","cardId":"fc-covering","front":"What makes an index 'covering'?","back":"It contains every column the query references, so the engine never reads the table row. EXPLAIN shows 'Using index'.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-truncate","moduleId":"pythonfs","cardId":"fc-truncate","front":"DELETE vs TRUNCATE?","back":"DELETE is row-by-row DML: logged, triggers fire, WHERE allowed, transactional. TRUNCATE is DDL: all-or-nothing, no triggers, resets AUTO_INCREMENT.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-where-having","moduleId":"pythonfs","cardId":"fc-where-having","front":"WHERE vs HAVING?","back":"WHERE filters rows before grouping; HAVING filters groups after aggregation. You cannot reference an aggregate in WHERE because the groups do not exist yet.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-null","moduleId":"pythonfs","cardId":"fc-null","front":"Why does `WHERE col = NULL` match nothing?","back":"NULL means unknown, so any comparison yields unknown rather than true - including NULL = NULL. Use IS NULL.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-union","moduleId":"pythonfs","cardId":"fc-union","front":"UNION vs UNION ALL?","back":"UNION deduplicates, which needs a sort or hash. UNION ALL just concatenates - meaningfully cheaper when you know the sets are disjoint.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-3nf","moduleId":"pythonfs","cardId":"fc-3nf","front":"State the normal forms in one line.","back":"The key, the whole key, and nothing but the key. 1NF removes repeating groups, 2NF partial dependencies, 3NF transitive ones.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-isolation","moduleId":"pythonfs","cardId":"fc-isolation","front":"Which anomaly does each isolation level prevent?","back":"READ COMMITTED stops dirty reads; REPEATABLE READ also stops non-repeatable reads; SERIALIZABLE also stops phantoms.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-deadlock","moduleId":"pythonfs","cardId":"fc-deadlock","front":"How do you systematically prevent deadlocks?","back":"Acquire locks on multiple resources in a consistent global order, which makes a wait-for cycle impossible. Then keep transactions short and retry.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-31-35","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-innodb","moduleId":"pythonfs","cardId":"fc-innodb","front":"Why InnoDB over MyISAM?","back":"Transactions, row-level locking and foreign keys. MyISAM's table-level locking serialises writers and collapses under concurrency.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-31-35","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-leftjoin-where","moduleId":"pythonfs","cardId":"fc-leftjoin-where","front":"Why does a LEFT JOIN sometimes behave like an INNER JOIN?","back":"A WHERE condition on the right table's column fails for the NULL rows, filtering them out. Put the condition in the ON clause instead.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-view","moduleId":"pythonfs","cardId":"fc-view","front":"What does a standard view store?","back":"Nothing - it stores the query, which runs on every select. It simplifies and can restrict access, but gives no performance benefit by itself.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-repl-lag","moduleId":"pythonfs","cardId":"fc-repl-lag","front":"What breaks because of replication lag?","back":"Read-after-write: a user saves, the read goes to a lagging replica, and the change appears to vanish. Route that read to the primary.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-split-brain","moduleId":"pythonfs","cardId":"fc-split-brain","front":"What is the biggest risk during failover?","back":"Split-brain - two nodes both accepting writes, producing divergent histories. Quorum or fencing prevents it; losing a few transactions is more recoverable.","keyPoints":[],"href":"/python-fullstack-interview/questions/DB-MySQL-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-queryset-lazy","moduleId":"pythonfs","cardId":"fc-queryset-lazy","front":"When does a Django QuerySet hit the database?","back":"Only when evaluated - iterated, len(), list(), bool() or sliced with a step. Chaining filters costs nothing until then.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-select-prefetch","moduleId":"pythonfs","cardId":"fc-select-prefetch","front":"select_related vs prefetch_related?","back":"select_related does a JOIN for single-valued relations (FK, OneToOne). prefetch_related runs a second query for multi-valued ones (M2M, reverse FK) and joins in Python.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-n1","moduleId":"pythonfs","cardId":"fc-n1","front":"How do you stop an N+1 regression reaching production?","back":"assertNumQueries in a test turns the query count into a failing assertion. Code review misses it because the extra query fires at attribute access.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-async-orm","moduleId":"pythonfs","cardId":"fc-async-orm","front":"Is the Django ORM synchronous?","back":"No longer. Since 4.1 there is an async query API - aget, acreate, acount, plus async iteration, with asave from 4.2. But it executes on a thread; these are not native async drivers.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-31-35","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-generatedfield","moduleId":"pythonfs","cardId":"fc-generatedfield","front":"You need a column always equal to qty * price. What do you use?","back":"GeneratedField (Django 5.0) - the database computes it, so it stays correct for bulk operations and raw SQL that bypass save().","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-dbdefault","moduleId":"pythonfs","cardId":"fc-dbdefault","front":"default vs db_default?","back":"default is applied by Python; db_default is applied by the database, so it covers inserts that never touch the ORM and can use functions like Now().","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-middleware-order","moduleId":"pythonfs","cardId":"fc-middleware-order","front":"Why does MIDDLEWARE order matter?","back":"It is an onion - requests pass down, responses come back up. AuthenticationMiddleware must follow SessionMiddleware because it reads the session.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-signals","moduleId":"pythonfs","cardId":"fc-signals","front":"What is the case against signals?","back":"Implicit action-at-a-distance that is hard to trace, and bulk_create / queryset.update() bypass save() so post_save never fires.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-static-media","moduleId":"pythonfs","cardId":"fc-static-media","front":"Static vs media files?","back":"Static ships with the code and can be collected and cached hard at deploy. Media is user-uploaded at runtime and needs writable, backed-up, usually off-server storage.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-related-name","moduleId":"pythonfs","cardId":"fc-related-name","front":"What does related_name control?","back":"The reverse accessor. Without it you get modelname_set; with related_name='articles' you write author.articles.all() - and it avoids clashes with two FKs to one target.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-through","moduleId":"pythonfs","cardId":"fc-through","front":"When do you need a `through` model?","back":"When the relationship itself carries data - a joined-at date, a role. The implicit join table only holds the two foreign keys.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-jwt-revoke","moduleId":"pythonfs","cardId":"fc-jwt-revoke","front":"What is the cost of stateless JWTs?","back":"You cannot revoke one before it expires, because there is no session to delete. Short-lived access tokens plus refresh tokens is the mitigation.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-cursor-pagination","moduleId":"pythonfs","cardId":"fc-cursor-pagination","front":"Why cursor pagination over offset on large tables?","back":"OFFSET scans and discards every preceding row, so deep pages get slow - and rows shift if data changes mid-paging. A cursor seeks directly and is stable.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-nginx-gunicorn","moduleId":"pythonfs","cardId":"fc-nginx-gunicorn","front":"Why put NGINX in front of Gunicorn?","back":"TLS, static files and buffering. Without it a slow client occupies an entire application worker for the whole transfer.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-debug-false","moduleId":"pythonfs","cardId":"fc-debug-false","front":"Single most important production setting?","back":"DEBUG = False with ALLOWED_HOSTS set. DEBUG = True leaks settings, SQL and local variables on every error page.","keyPoints":[],"href":"/python-fullstack-interview/questions/Django-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-asgi","moduleId":"pythonfs","cardId":"fc-asgi","front":"What does ASGI give you that WSGI does not?","back":"Async callables and long-lived connections. WSGI is one synchronous call per request with no concept of a persistent connection, so WebSockets are impossible.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-01-05","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-blocking-loop","moduleId":"pythonfs","cardId":"fc-blocking-loop","front":"What happens if you put a blocking call in `async def`?","back":"It stalls the event loop and every other concurrent request. Use plain `def` - FastAPI runs it in a threadpool - or an async driver.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-01-05","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-route-order","moduleId":"pythonfs","cardId":"fc-route-order","front":"Why must /users/me be declared before /users/{id}?","back":"Routes match in declaration order, so the parameterised route would capture 'me' as the id. Fixed paths first.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-06-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-model-dump","moduleId":"pythonfs","cardId":"fc-model-dump","front":"Pydantic v1 to v2 - name the four renames.","back":".dict() to .model_dump(), .json() to .model_dump_json(), class Config to model_config = ConfigDict(...), orm_mode to from_attributes. And @validator to @field_validator.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-annotated","moduleId":"pythonfs","cardId":"fc-annotated","front":"Why Annotated[Session, Depends(get_db)] rather than a default?","back":"The default form burns the parameter's default slot on framework metadata and confuses type checkers. Annotated keeps the type honest and lets you alias and reuse it.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-yield-dep","moduleId":"pythonfs","cardId":"fc-yield-dep","front":"Why does a session dependency use yield?","back":"Code after yield runs as teardown once the response is finished, so the session closes even if the route raises. It behaves like a context manager.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-streaming","moduleId":"pythonfs","cardId":"fc-streaming","front":"When do you return a StreamingResponse?","back":"When the payload is large or generated incrementally - memory stays flat and the client starts receiving immediately instead of after full buffering.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-cors-credentials","moduleId":"pythonfs","cardId":"fc-cors-credentials","front":"Why can't you use allow_origins=['*'] with credentials?","back":"The CORS spec forbids it - any site could then make authenticated requests. With credentials you must echo back a specific allowed origin.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-bcrypt","moduleId":"pythonfs","cardId":"fc-bcrypt","front":"Why not SHA-256 for passwords?","back":"It is fast by design, so an attacker can try billions per second. Passwords need a deliberately slow, salted hash with a tunable work factor - bcrypt or argon2.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-36-40","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-lifespan","moduleId":"pythonfs","cardId":"fc-lifespan","front":"What replaced @app.on_event('startup')?","back":"A lifespan async context manager - setup before yield, teardown after. It keeps paired resources together and makes shared state explicit.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-sse-ws","moduleId":"pythonfs","cardId":"fc-sse-ws","front":"SSE or WebSockets?","back":"SSE when updates flow server-to-client only - plain HTTP, automatic reconnect, no protocol upgrade. WebSockets when you genuinely need bidirectional.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-sqla2","moduleId":"pythonfs","cardId":"fc-sqla2","front":"What changed in SQLAlchemy 2.0?","back":"declarative_base() became a DeclarativeBase class, columns became Mapped[] / mapped_column(), and queries standardised on select() with scalars().","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-31-35","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-override","moduleId":"pythonfs","cardId":"fc-override","front":"How do you swap the database in tests?","back":"app.dependency_overrides - point get_db at a transactional test session and the whole app runs against it with no application code change.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-ratelimit-shared","moduleId":"pythonfs","cardId":"fc-ratelimit-shared","front":"Why does in-memory rate limiting break at scale?","back":"Each instance enforces its own counter, so four instances turn a 100/min limit into 400/min. State belongs in Redis.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-docker-layers","moduleId":"pythonfs","cardId":"fc-docker-layers","front":"Why copy requirements before application code in a Dockerfile?","back":"Layer caching. Dependencies change rarely, so a code edit rebuilds only the last layer instead of reinstalling everything.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-51-55","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-idempotency","moduleId":"pythonfs","cardId":"fc-idempotency","front":"Why do payment endpoints need an idempotency key?","back":"A timeout never tells the client whether the write happened. The key lets the server recognise a retry and return the original result instead of charging twice.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-56-60","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-presigned","moduleId":"pythonfs","cardId":"fc-presigned","front":"Why use a pre-signed S3 URL for uploads?","back":"The file goes client-to-S3 directly, so your API spends no bandwidth, memory or worker time. Proxying a 500MB upload occupies a worker throughout.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-61-65","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-ws-scale","moduleId":"pythonfs","cardId":"fc-ws-scale","front":"What breaks when WebSockets scale to several instances?","back":"Each instance only holds its own sockets, so an event elsewhere cannot reach them. You need Redis pub/sub or a broker to fan out.","keyPoints":[],"href":"/python-fullstack-interview/questions/FastAPI-61-65","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-microtask","moduleId":"pythonfs","cardId":"fc-microtask","front":"Promise callback or setTimeout(0) - which runs first?","back":"The promise. Microtasks drain completely between every macrotask, so promise callbacks always beat timers.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-tdz","moduleId":"pythonfs","cardId":"fc-tdz","front":"What is the temporal dead zone?","back":"The span between a let/const binding entering scope and being initialised, where access throws ReferenceError. They are hoisted, just not initialised.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-const","moduleId":"pythonfs","cardId":"fc-const","front":"What does const actually guarantee?","back":"Only that the binding cannot be reassigned. The object it points at is still mutable - const arr = []; arr.push(1) is legal.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-arrow-this","moduleId":"pythonfs","cardId":"fc-arrow-this","front":"How does an arrow function treat `this`?","back":"It has none of its own - it closes over `this` lexically. That is why arrows fixed callback binding and why they are wrong as object methods.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-call-bind","moduleId":"pythonfs","cardId":"fc-call-bind","front":"call, apply and bind?","back":"call and apply invoke immediately (args listed vs as an array); bind returns a new function with `this` permanently fixed.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-delegation","moduleId":"pythonfs","cardId":"fc-delegation","front":"What does event delegation solve?","back":"One listener on a parent handles many children via bubbling - fewer listeners, and it works for elements added after the listener was attached.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-debounce","moduleId":"pythonfs","cardId":"fc-debounce","front":"Debounce or throttle - which for scroll?","back":"Throttle. It guarantees a maximum rate so updates keep happening during the scroll. Debounce waits for quiet, which suits 'user finished typing'.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-cors-who","moduleId":"pythonfs","cardId":"fc-cors-who","front":"Who enforces CORS?","back":"The browser. The request often reaches the server and runs; the browser just refuses to hand the response to your script. curl is unaffected.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-26-30","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-cookie-storage","moduleId":"pythonfs","cardId":"fc-cookie-storage","front":"Cookie or localStorage for a token?","back":"An HttpOnly cookie cannot be read by XSS, but needs CSRF protection. localStorage is XSS-readable but immune to CSRF. Name the trade, do not pick blindly.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-31-35","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-promise-all","moduleId":"pythonfs","cardId":"fc-promise-all","front":"Three independent API calls - how do you run them?","back":"Promise.all, so total time is the slowest rather than the sum. Use allSettled when one failure should not discard the others.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-31-35","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-treeshake","moduleId":"pythonfs","cardId":"fc-treeshake","front":"Why does tree-shaking need ES modules?","back":"ESM imports are static and analysable at build time. require() can be dynamic, so a bundler must assume everything might be used.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-41-45","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-spread-shallow","moduleId":"pythonfs","cardId":"fc-spread-shallow","front":"What does { ...obj } copy?","back":"Own enumerable properties, one level deep - nested objects remain shared references. structuredClone() gives a real deep copy.","keyPoints":[],"href":"/python-fullstack-interview/questions/JavaScript-46-50","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-keys","moduleId":"pythonfs","cardId":"fc-keys","front":"Why are index keys a problem?","back":"On reorder or insertion the indexes shift, so React matches the wrong elements and component state follows position rather than item.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-props-state","moduleId":"pythonfs","cardId":"fc-props-state","front":"Props vs state?","back":"Props come from the parent and are read-only to the component; state is owned and mutable by the component. One-way data flow follows from that.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-1-5","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-stale-closure","moduleId":"pythonfs","cardId":"fc-stale-closure","front":"Why is my counter stuck at 0 inside useEffect?","back":"A stale closure - the effect captured the first render's value because the dependency was omitted, so it never re-created.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-6-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-context-cost","moduleId":"pythonfs","cardId":"fc-context-cost","front":"What is the performance pitfall of Context?","back":"Every consumer re-renders when the value changes, and an inline object literal is a new value each render. Memoise it, or split contexts by update frequency.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-memo-break","moduleId":"pythonfs","cardId":"fc-memo-break","front":"Why does React.memo often not prevent re-renders?","back":"An inline arrow or object literal prop is a new reference each render, so the shallow comparison always fails. That is what useCallback is for.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-hydration","moduleId":"pythonfs","cardId":"fc-hydration","front":"What causes a hydration mismatch?","back":"Non-determinism during render - Date.now(), Math.random(), reading localStorage. Move it into useEffect so the first client render matches the server.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-portal","moduleId":"pythonfs","cardId":"fc-portal","front":"What does a portal change - and not change?","back":"It renders into a different DOM node, escaping overflow and z-index. Events still bubble through the React tree, not the DOM tree.","keyPoints":[],"href":"/python-fullstack-interview/questions/React-21-25","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-specificity","moduleId":"pythonfs","cardId":"fc-specificity","front":"Order CSS specificity, lowest first.","back":"Element < class/attribute/pseudo-class < id < inline, with !important above all. Reaching for !important usually signals a specificity problem.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-01-05","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-absolute","moduleId":"pythonfs","cardId":"fc-absolute","front":"position: absolute is relative to what?","back":"The nearest ancestor with a position other than static. Forgetting position: relative on the intended parent is why it escapes to the page corner.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-01-05","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-borderbox","moduleId":"pythonfs","cardId":"fc-borderbox","front":"What does box-sizing: border-box change?","back":"width and height include padding and border, so a 200px element occupies 200px. With content-box, width: 100% plus padding overflows.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-06-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-flex-grid","moduleId":"pythonfs","cardId":"fc-flex-grid","front":"Grid or Flexbox?","back":"Grid for two-dimensional layout where rows and columns align together; Flexbox for one axis at a time. They compose - Grid for the frame, Flex inside cells.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-06-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-stacking","moduleId":"pythonfs","cardId":"fc-stacking","front":"Why might z-index: 9999 not work?","back":"z-index only compares within a stacking context. A parent with transform, filter or opacity below 1 creates one and traps the child.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-rem-em","moduleId":"pythonfs","cardId":"fc-rem-em","front":"rem vs em?","back":"em is relative to the element's own font size and compounds when nested; rem is relative to the root. Both respect the user's font-size setting, unlike px.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-margin-collapse","moduleId":"pythonfs","cardId":"fc-margin-collapse","front":"What is margin collapsing?","back":"Adjacent vertical margins combine into the larger of the two, not the sum. Flex and grid containers do not collapse margins.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-vh-mobile","moduleId":"pythonfs","cardId":"fc-vh-mobile","front":"Why does height: 100vh overflow on mobile?","back":"vh ignored the browser chrome that hides and shows on scroll. The dynamic viewport units - dvh, svh, lvh - exist for exactly this.","keyPoints":[],"href":"/python-fullstack-interview/questions/CSS-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-async-defer","moduleId":"pythonfs","cardId":"fc-async-defer","front":"async vs defer on a script tag?","back":"Both download in parallel. async executes as soon as it lands with no order guarantee; defer waits for parsing and runs in order.","keyPoints":[],"href":"/python-fullstack-interview/questions/HTML-11-15","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-aria-rule","moduleId":"pythonfs","cardId":"fc-aria-rule","front":"What is the first rule of ARIA?","back":"Do not use it if a native element already provides the semantics. A <button> is focusable and keyboard-activatable for free; role='button' gives you neither.","keyPoints":[],"href":"/python-fullstack-interview/questions/HTML-16-20","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-viewport-meta","moduleId":"pythonfs","cardId":"fc-viewport-meta","front":"What does the viewport meta tag do?","back":"Tells mobile browsers to use the device width instead of emulating a ~980px desktop viewport. Without it your media queries never match.","keyPoints":[],"href":"/python-fullstack-interview/questions/HTML-06-10","moduleLabel":"Python Full-Stack"},{"key":"pythonfs:fc-svg-canvas","moduleId":"pythonfs","cardId":"fc-svg-canvas","front":"SVG or Canvas?","back":"SVG for scalable, accessible graphics with few elements - charts, icons. Canvas is a pixel buffer: far faster for thousands of objects, but opaque to the DOM.","keyPoints":[],"href":"/python-fullstack-interview/questions/HTML-06-10","moduleLabel":"Python Full-Stack"},{"key":"rapidreview:qz-programming-and-oop--oop-q1","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q1","front":"In Java, what happens if a method reassigns its object parameter to a new object?","back":"The caller's reference is unchanged - only the local copy was repointed","keyPoints":["Java is pass-by-value always. The value copied for an object parameter is the reference itself, so reassigning the parameter only changes the method's local copy. Mutating the object through the reference, by contrast, is visible to the caller."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q2","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q2","front":"A `static` local variable in C differs from an ordinary local variable in that it has:","back":"The same scope but a lifetime that lasts the whole program","keyPoints":["`static` changes lifetime, not scope. The variable is still only nameable inside its block, but its storage lives in the data segment for the whole run, so it retains its value between calls."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q3","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q3","front":"Which pair of declarations is NOT a valid overload?","back":"`int f(int)` and `double f(int)`","keyPoints":["Overload resolution uses the parameter list only. Two functions differing solely in return type give the compiler nothing to select on at a call site like `f(3);`, so it is an error."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q4","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q4","front":"What is the difference between abstraction and encapsulation?","back":"Abstraction is about what to expose (design); encapsulation is about hiding the rest (implementation)","keyPoints":["Abstraction is a design decision - which concepts and operations the caller sees. Encapsulation is the implementation mechanism that keeps the remaining state and detail inaccessible. An interface expresses abstraction; `private` enforces encapsulation."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q5","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q5","front":"Deleting a derived object through a base-class pointer whose destructor is not virtual:","back":"Is undefined behaviour - the derived destructor never runs","keyPoints":["Without a virtual destructor the call is resolved statically to the base destructor, so the derived part is never destroyed. The standard calls this undefined behaviour; in practice the derived class's resources leak."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q6","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q6","front":"`Square extends Rectangle`, where setting the width of a Square also changes its height, violates which principle?","back":"Liskov Substitution","keyPoints":["Liskov Substitution requires a subtype to be usable anywhere the supertype is, without surprising the caller. Code written against Rectangle reasonably assumes width and height are independent; Square breaks that assumption."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q7","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q7","front":"Does a garbage-collected language make memory leaks impossible?","back":"No - objects that are still reachable are never collected, so a growing cache or listener list still leaks","keyPoints":["GC reclaims unreachable objects. A collection that keeps growing holds live references, so its contents remain reachable and are never freed. Modern collectors handle reference cycles fine; the real leak is logical."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q8","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q8","front":"Java forbids multiple class inheritance primarily to avoid:","back":"The diamond problem - ambiguity when two parents provide the same member","keyPoints":["With two paths to a common ancestor, it is ambiguous which inherited member a class receives. Java sidesteps this by allowing one superclass and many interfaces; when Java 8 default methods reintroduced the clash, it required the programmer to override and disambiguate explicitly."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q9","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q9","front":"Adapter, Decorator and Proxy all wrap another object. What distinguishes them?","back":"Their intent - Adapter changes the interface, Decorator adds behaviour, Proxy controls access","keyPoints":["Structurally they are nearly identical. The catalogue separates them by intent: converting an incompatible interface, adding responsibilities while keeping the interface, and controlling access to the real subject respectively."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-programming-and-oop--oop-q10","moduleId":"rapidreview","cardId":"qz-programming-and-oop--oop-q10","front":"What does a `return` statement inside a `finally` block do to an exception thrown in the `try` block?","back":"Discards it - the exception is silently lost","keyPoints":["Returning from `finally` completes the method normally, which abandons the in-flight exception entirely. The failure disappears without any trace, which is why it is universally flagged by static analysers."],"href":"/rapid-review-cs/programming-and-oop#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q1","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q1","front":"Which statement about Big-O is correct?","back":"Big-O is an upper bound and can be stated for any case - best, average or worst","keyPoints":["Notation and case are independent. Big-O bounds growth from above; you can bound the best case with it just as well as the worst. Big-Theta is the tight bound and is strictly more informative when it is available."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q2","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q2","front":"Building a binary heap from n unsorted elements bottom-up takes:","back":"O(n)","keyPoints":["Sift-down cost depends on node height, and most nodes are near the leaves. Summing n/2^(h+1) · h over all heights converges to O(n). Inserting one at a time really is O(n log n) - the bottom-up build is what gives the linear bound."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q3","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q3","front":"Why does Dijkstra's algorithm fail on graphs with negative edge weights?","back":"It finalises a vertex's distance greedily and never revisits it, so a later shorter path is missed","keyPoints":["The greedy invariant - that a vertex popped from the priority queue has its final distance - depends on all remaining paths being at least as long. A negative edge breaks that, and Dijkstra returns a wrong answer silently rather than failing."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q4","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q4","front":"Inorder traversal of a binary search tree produces:","back":"Keys in ascending sorted order","keyPoints":["Left–Node–Right visits everything smaller before the node and everything larger after it, at every level. This is the basis for validating a BST and for finding the k-th smallest element."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q5","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q5","front":"Which sorting algorithm is stable, guaranteed O(n log n), but needs O(n) extra space?","back":"Mergesort","keyPoints":["Mergesort's merge step requires an auxiliary array, giving O(n) space, but it never degrades from O(n log n) and preserves the relative order of equal keys. Heapsort is in-place but unstable; quicksort is in-place but O(n²) worst case."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q6","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q6","front":"Deleting an entry from an open-addressed hash table by simply clearing the slot causes:","back":"Later keys whose probe sequence passed through that slot to become unreachable","keyPoints":["Search stops at the first empty slot. Clearing a slot in the middle of a probe chain truncates that chain, hiding every key beyond it. The fix is a tombstone marker that search skips over but insertion may reuse."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q7","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q7","front":"Database indexes use B+ trees rather than balanced binary trees mainly because:","back":"A high branching factor makes the tree only a few levels deep, minimising disk block reads","keyPoints":["The cost that matters on disk is block reads, not comparisons. A node sized to one block holds hundreds of keys, so a million records sit three or four levels deep instead of twenty. The linked leaf level also makes range scans sequential."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q8","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q8","front":"Dynamic programming is preferable to plain divide and conquer when:","back":"Subproblems overlap, so the same subproblem would otherwise be recomputed","keyPoints":["Overlap is the deciding property. Mergesort's halves are disjoint so caching buys nothing; Fibonacci recomputes the same subproblems exponentially often, so memoising collapses O(2ⁿ) to O(n). DP also requires optimal substructure."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q9","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q9","front":"BFS finds shortest paths only when:","back":"All edges have equal weight","keyPoints":["BFS explores in order of edge count. That corresponds to distance only if every edge costs the same. With varying weights a path with more edges can be shorter, and you need Dijkstra."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q10","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q10","front":"The 0/1 knapsack DP runs in O(nW). Why is that not a polynomial-time algorithm?","back":"Because W is encoded in log W bits, so O(nW) is exponential in the input length","keyPoints":["Input size is measured in bits. A weight limit W takes about log W bits to write down, so a runtime linear in W is exponential in the size of its encoding. Such algorithms are called pseudo-polynomial, and 0/1 knapsack remains NP-hard."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q11","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q11","front":"Which is true of a binary heap?","back":"It is a complete binary tree, so it needs no child pointers","keyPoints":["Completeness is what allows the array layout, with children of index i at 2i+1 and 2i+2. A heap is not sorted, and it imposes no order between siblings, so arbitrary search is O(n)."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-data-structures-and-algorithms--dsa-q12","moduleId":"rapidreview","cardId":"qz-data-structures-and-algorithms--dsa-q12","front":"The Ω(n log n) lower bound on sorting applies to:","back":"Only comparison-based sorts","keyPoints":["The decision-tree argument counts binary comparison outcomes needed to distinguish n! orderings. Counting sort and radix sort escape it by never comparing elements - they read the structure of the keys instead, which is why they need bounded integer-like keys."],"href":"/rapid-review-cs/data-structures-and-algorithms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q1","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q1","front":"Which of these is logically equivalent to p → q?","back":"¬q → ¬p","keyPoints":["Only the contrapositive ¬q → ¬p is equivalent. The converse q → p and the inverse ¬p → ¬q are equivalent to each other, but neither is equivalent to the original."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q2","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q2","front":"The statement \"if 2 is odd, then 3 is even\" is:","back":"True, because the premise is false (vacuously true)","keyPoints":["An implication is false only when the premise is true and the conclusion false. With a false premise it is vacuously true regardless of the conclusion - a direct reading of p → q ≡ ¬p ∨ q."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q3","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q3","front":"A relation that is reflexive, antisymmetric and transitive is:","back":"A partial order","keyPoints":["Antisymmetry is the marker of a partial order - it allows a hierarchy such as subset inclusion, where some pairs are simply incomparable. Swap antisymmetry for symmetry and you get an equivalence relation instead."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q4","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q4","front":"How many distinct arrangements are there of the letters in BANANA?","back":"60","keyPoints":["Six letters with 3 A's and 2 N's repeated: 6!/(3!·2!·1!) = 720/12 = 60. Divide total arrangements by the factorial of each repetition count."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q5","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q5","front":"In any undirected graph, the number of vertices with odd degree is:","back":"Always even","keyPoints":["By the handshake lemma the degrees sum to 2|E|, which is even. An odd number of odd-degree vertices would make that sum odd, so the count of odd-degree vertices must be even."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q6","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q6","front":"∀x ∃y Loves(x, y) differs from ∃y ∀x Loves(x, y) because:","back":"The first allows a different y for each x; the second requires one y that works for all x","keyPoints":["Mixed quantifiers do not commute. The second is the stronger claim and implies the first, but not conversely - everyone loving someone does not mean there is one universally loved person."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q7","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q7","front":"A set with 5 elements has a power set of size:","back":"32","keyPoints":["The power set has 2ⁿ elements - each element is independently in or out of a subset. For n = 5 that is 2⁵ = 32, counting both the empty set and the full set."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q8","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q8","front":"An Euler circuit exists in a connected graph if and only if:","back":"Every vertex has even degree","keyPoints":["Entering and leaving a vertex uses two edges, so a closed walk covering every edge requires all degrees even. Exactly two odd-degree vertices gives an Euler path (starting and ending at those two) but not a circuit."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q9","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q9","front":"Concluding p from p → q and q is:","back":"Affirming the consequent, and invalid","keyPoints":["Valid modus ponens goes from p → q and p to q. Reasoning backwards from the conclusion is the fallacy of affirming the consequent: q may hold for entirely unrelated reasons."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-discrete-mathematics--dm-q10","moduleId":"rapidreview","cardId":"qz-discrete-mathematics--dm-q10","front":"A modular inverse of a modulo m exists precisely when:","back":"gcd(a, m) = 1","keyPoints":["Coprimality is the exact condition. The extended Euclidean algorithm produces x and y with ax + my = gcd(a, m); when that gcd is 1, x is the inverse of a mod m. This is why RSA requires e coprime to φ(n)."],"href":"/rapid-review-cs/discrete-mathematics#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q1","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q1","front":"Which resource is shared between threads of the same process?","back":"The heap and global data","keyPoints":["Threads share the address space - code, global data, heap and open files. Each thread keeps its own stack, registers and program counter, which is precisely what lets them execute independently."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q2","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q2","front":"Deadlock prevention works by:","back":"Structurally ensuring at least one of the four Coffman conditions can never hold","keyPoints":["All four conditions are necessary simultaneously, so negating one makes deadlock impossible. Checking for safe states is avoidance (banker's algorithm); cycle detection with a victim is detection and recovery."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q3","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q3","front":"Belady's anomaly can occur with:","back":"FIFO","keyPoints":["FIFO can fault more often with more frames. LRU and Optimal are stack algorithms - the pages resident with n frames are always a subset of those resident with n+1 - so the anomaly is impossible for them."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q4","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q4","front":"The main advantage of paging over segmentation is that paging:","back":"Eliminates external fragmentation","keyPoints":["Because pages and frames are the same fixed size, any page fits any free frame, so free memory is never unusable for being the wrong shape. Some internal fragmentation remains in the last page. Matching the logical view is segmentation's advantage."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q5","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q5","front":"The essential difference between a mutex and a binary semaphore is:","back":"A mutex has ownership - only the locking thread may unlock it","keyPoints":["Ownership is the distinction. A mutex protects a critical section and must be released by its acquirer; a semaphore is an ownerless counter that any thread may signal, which makes it suitable for signalling and for resource pools."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q6","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q6","front":"A process whose I/O completes moves to which state?","back":"Ready","keyPoints":["It becomes eligible to run but must still be selected by the scheduler, so it re-enters the ready queue. Only the dispatcher moves a process from Ready to Running."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q7","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q7","front":"Thrashing is best remedied by:","back":"Reducing the degree of multiprogramming","keyPoints":["Thrashing is a shortage of physical frames per process. Suspending some processes gives the rest enough frames for their working sets. More swap space allows a higher degree of multiprogramming, which makes the feedback loop worse."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q8","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q8","front":"Which scheduling algorithm provably minimises average waiting time?","back":"Shortest Job First","keyPoints":["SJF is optimal for average waiting time - running shorter jobs first reduces total accumulated wait. It is not directly usable because the next burst length is unknown, and it starves long jobs."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q9","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q9","front":"With 4 KB pages and a 32-bit logical address, the page offset occupies how many bits?","back":"12","keyPoints":["The offset must address every byte within a page: log₂(4096) = 12 bits. The remaining 20 bits form the page number, giving a single-level page table of about a million entries per process."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q10","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q10","front":"Deleting the original file breaks a symbolic link but not a hard link because:","back":"A hard link references the inode directly, and data persists until the link count reaches zero","keyPoints":["A hard link is another directory entry pointing at the same inode, so removing one entry merely decrements the link count. A symbolic link stores a path string, which becomes dangling once nothing resolves at that path."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q11","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q11","front":"A system call transfers control to the kernel via:","back":"A trap that switches the mode bit and enters at a fixed vector address","keyPoints":["Letting user code jump to an arbitrary kernel address would defeat protection entirely. The trap instruction atomically raises privilege and transfers to a fixed handler; the requested service is selected by a call number in a register."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-operating-systems--os-q12","moduleId":"rapidreview","cardId":"qz-operating-systems--os-q12","front":"C-SCAN is preferred over SCAN mainly because it:","back":"Provides more uniform waiting time across cylinders","keyPoints":["Under SCAN, cylinders just behind the head are served twice in quick succession while the far end waits a full sweep. C-SCAN always sweeps one way and jumps back, so every cylinder sees a similar service interval. Neither algorithm starves requests."],"href":"/rapid-review-cs/operating-systems#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q1","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q1","front":"How many usable host addresses does a /27 subnet provide?","back":"30","keyPoints":["A /27 leaves 5 host bits, so 2⁵ = 32 total addresses. Subtract the network address (all host bits 0) and the broadcast address (all host bits 1) to get 30 usable."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q2","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q2","front":"The TCP three-way handshake requires three messages because:","back":"Sequence numbers must be synchronised and acknowledged in both directions","keyPoints":["Each direction has its own initial sequence number, and each must be acknowledged by the other side. Two messages would confirm only one direction, so three is the minimum."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q3","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q3","front":"Which statement correctly distinguishes flow control from congestion control?","back":"Flow control protects the receiver; congestion control protects the network","keyPoints":["Flow control prevents a fast sender from overwhelming a slow receiver, signalled by the advertised window. Congestion control prevents senders collectively from overwhelming the network, inferred from loss and delay."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q4","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q4","front":"A switch and a router differ in that a router:","back":"Creates a separate broadcast domain per port","keyPoints":["Switches segment collision domains but pass broadcasts to every port, so a switched LAN is one broadcast domain. Routers do not forward broadcasts, so each interface bounds its own broadcast domain."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q5","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q5","front":"DNS primarily uses UDP rather than TCP because:","back":"A query and reply are small and a single fast round trip beats a handshake","keyPoints":["A typical query and response fit in one datagram, so UDP avoids the three-way handshake entirely. DNS falls back to TCP when the response is too large for one datagram (512 bytes classically, commonly 1,232 with EDNS) or for zone transfers."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q6","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q6","front":"In TCP slow start, the congestion window:","back":"Doubles every RTT","keyPoints":["Despite the name, slow start grows the window exponentially - doubling each RTT - until it reaches the slow-start threshold, after which congestion avoidance grows it linearly."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q7","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q7","front":"Which HTTP method is idempotent but not safe?","back":"PUT","keyPoints":["PUT changes server state, so it is not safe, but sending it repeatedly leaves the resource in the same final state, so it is idempotent. POST is neither; GET and HEAD are both."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q8","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q8","front":"ARP is used to:","back":"Resolve an IP address to a MAC address within a broadcast domain","keyPoints":["ARP broadcasts a request for the MAC address that owns a given IP on the local link. Hostname resolution is DNS, automatic address assignment is DHCP, and inter-AS routing is BGP."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q9","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q9","front":"Go-Back-N differs from Selective Repeat in that Go-Back-N:","back":"Retransmits the lost frame and every frame after it","keyPoints":["The Go-Back-N receiver discards anything out of order, so the sender must resend from the lost frame onward. Selective Repeat buffers out-of-order frames and retransmits only what was actually lost, at the cost of a more complex receiver."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q10","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q10","front":"The key difference between HTTP 401 and 403 is:","back":"401 means unauthenticated - credentials may help; 403 means the request is refused regardless of identity","keyPoints":["401 signals that authentication is missing or invalid, so retrying with credentials can succeed. 403 signals that the server has identified the requester and is still refusing, so retrying will not help."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q11","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q11","front":"TLS uses asymmetric cryptography mainly to:","back":"Authenticate the server and agree on a symmetric session key","keyPoints":["Asymmetric operations are far too slow for bulk data. TLS uses them during the handshake to verify the server's certificate and establish a shared secret, then encrypts the actual traffic with a fast symmetric cipher."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-networks--cn-q12","moduleId":"rapidreview","cardId":"qz-computer-networks--cn-q12","front":"Count-to-infinity is a problem in:","back":"Distance-vector routing protocols such as RIP","keyPoints":["Distance-vector routers know only what neighbours report, so after a failure two routers can keep learning a stale route from each other and increment its cost indefinitely. Link-state routers hold the full topology, so they recompute correctly."],"href":"/rapid-review-cs/computer-networks#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q1","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q1","front":"Computers use two's complement rather than sign-magnitude primarily because:","back":"Subtraction becomes addition, so one adder circuit serves both","keyPoints":["In two's complement a − b is computed as a + (−b) with no special case, and there is a single representation of zero. That hardware simplification is why it is universal."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q2","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q2","front":"Pipelining a processor improves:","back":"Instruction throughput, while individual latency is unchanged","keyPoints":["Each instruction still passes through every stage, so its own start-to-finish time is unchanged or slightly worse. What improves is that one instruction completes per cycle once the pipeline is full."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q3","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q3","front":"A load-use hazard requires a stall even with forwarding because:","back":"The loaded value is not available until the end of the MEM stage, after the next instruction needs it in EX","keyPoints":["Forwarding can only move a value backwards in time if it already exists. An ALU result exists after EX and can be forwarded; a loaded value exists only after MEM, one stage too late, so one bubble is unavoidable."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q4","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q4","front":"In IEEE 754 single precision, the leading 1 of a normalised mantissa is:","back":"Implicit and not stored, gaining one extra bit of precision","keyPoints":["Every normalised binary number has the form 1.xxx, so the leading 1 carries no information and is omitted. This gives 24 bits of effective precision from 23 stored bits."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q5","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q5","front":"A cache miss that occurs because two hot blocks map to the same cache line, despite space being free elsewhere, is a:","back":"Conflict miss","keyPoints":["Conflict misses arise from mapping restrictions and are cured by increasing associativity. Compulsory misses are first-ever references; capacity misses occur when the working set simply exceeds the cache."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q6","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q6","front":"A program is 80% parallelisable. With infinitely many processors, the maximum speedup is:","back":"5×","keyPoints":["By Amdahl's law the ceiling is 1/(1−P) = 1/0.2 = 5×. The 20% serial portion sets a hard limit regardless of processor count."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q7","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q7","front":"The von Neumann bottleneck refers to:","back":"Instructions and data sharing one memory path, limiting throughput","keyPoints":["With one shared bus, the CPU cannot fetch an instruction and a data word simultaneously, and memory bandwidth has not kept pace with processor speed. The entire cache hierarchy exists to mitigate it."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q8","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q8","front":"Which addressing mode is used to access an element of an array?","back":"Indexed (base plus displacement)","keyPoints":["Array access computes base address plus an offset, which is exactly indexed addressing. Immediate holds a constant, direct names a fixed address, and register addressing accesses no memory at all."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q9","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q9","front":"DMA reduces CPU load because:","back":"The DMA controller moves data directly between device and memory, interrupting the CPU only on completion","keyPoints":["The CPU issues one command and is free until the transfer finishes. The DMA controller does contend for the memory bus - cycle stealing - but that costs far less than the CPU executing thousands of load and store instructions."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-computer-architecture--ca-q10","moduleId":"rapidreview","cardId":"qz-computer-architecture--ca-q10","front":"Traversing a 2D array in C row by row is faster than column by column because:","back":"C stores arrays row-major, so row traversal has spatial locality and reuses cache lines","keyPoints":["Row-major storage puts consecutive row elements in adjacent memory, so one cache line serves many elements. Striding down a column touches a new line each step, converting one miss per 16 elements into one per element."],"href":"/rapid-review-cs/computer-architecture#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q1","moduleId":"rapidreview","cardId":"qz-dbms--db-q1","front":"A relation is in 2NF but not 3NF. What must be removed to reach 3NF?","back":"Transitive dependencies of one non-key attribute on another","keyPoints":["2NF has already eliminated partial dependencies. 3NF targets transitive dependencies - a non-key attribute determined by another non-key attribute, such as StudentID → Dept → DeptHead."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q2","moduleId":"rapidreview","cardId":"qz-dbms--db-q2","front":"Two-phase locking guarantees:","back":"Conflict serialisability","keyPoints":["The growing/shrinking discipline guarantees a serialisable schedule but says nothing about deadlock - two transactions can still block each other. Strict 2PL additionally prevents cascading rollback, but still not deadlock."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q3","moduleId":"rapidreview","cardId":"qz-dbms--db-q3","front":"Which anomaly is possible at Repeatable Read but not at Serializable?","back":"Phantom read","keyPoints":["Repeatable Read locks the rows it has read, so existing rows cannot change, but new rows matching the same predicate can still be inserted. Only Serializable is required to prevent these phantoms."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q4","moduleId":"rapidreview","cardId":"qz-dbms--db-q4","front":"A table can have at most one clustered index because:","back":"The clustered index determines the physical order of rows, and rows can only be stored in one order","keyPoints":["A clustered index is the table's storage order, with the data rows in its leaves. Only one physical ordering can exist, so all other indexes must be non-clustered and point back to it."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q5","moduleId":"rapidreview","cardId":"qz-dbms--db-q5","front":"In relational algebra, σ (sigma) performs:","back":"Selection of rows matching a predicate","keyPoints":["Sigma is selection - it filters rows, equivalent to SQL's WHERE. Column projection is π (pi). The naming trips people up because 'projection' sounds like it should filter rows."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q6","moduleId":"rapidreview","cardId":"qz-dbms--db-q6","front":"With a composite index on (last_name, first_name), which query CANNOT use it?","back":"WHERE first_name = 'Rina'","keyPoints":["The leftmost prefix rule. The index is sorted by last_name first, so first names are only ordered within a given last name - filtering on first_name alone gives the tree nothing to descend on."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q7","moduleId":"rapidreview","cardId":"qz-dbms--db-q7","front":"The write-ahead logging rule requires that:","back":"Log records reach stable storage before the corresponding data pages","keyPoints":["Logging first guarantees the log always describes at least as much as the data files contain, so recovery can always reconstruct or reverse any change that reached disk."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q8","moduleId":"rapidreview","cardId":"qz-dbms--db-q8","front":"Under the CAP theorem, a distributed database experiencing a network partition must sacrifice:","back":"Either consistency or availability","keyPoints":["Partitions are a fact of networks, not a design option, so partition tolerance is mandatory. The real choice during a partition is between refusing requests to stay consistent (CP) or answering with possibly stale data (AP)."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q9","moduleId":"rapidreview","cardId":"qz-dbms--db-q9","front":"Which is true of TRUNCATE compared to DELETE?","back":"TRUNCATE is DDL, deallocates pages, and is generally much faster","keyPoints":["TRUNCATE deallocates whole data pages rather than logging individual row deletions, so it is far faster but cannot be filtered and does not fire row triggers. DROP is what removes the definition."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q10","moduleId":"rapidreview","cardId":"qz-dbms--db-q10","front":"`WHERE salary = NULL` returns no rows because:","back":"NULL means unknown, so any comparison with it evaluates to unknown rather than true","keyPoints":["SQL uses three-valued logic. Comparing anything to an unknown yields unknown, and WHERE only passes rows evaluating to true. The correct predicate is `IS NULL`."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q11","moduleId":"rapidreview","cardId":"qz-dbms--db-q11","front":"A schedule is conflict serialisable if and only if its precedence graph:","back":"Is acyclic","keyPoints":["Each edge records that one transaction must precede another. A cycle means the required orderings contradict each other, so no equivalent serial order exists. Acyclicity means a topological sort gives that serial order."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-dbms--db-q12","moduleId":"rapidreview","cardId":"qz-dbms--db-q12","front":"In converting an M:N relationship to tables you must:","back":"Create a junction table keyed on both foreign keys","keyPoints":["Neither side can hold a single foreign key without repeating rows, so an M:N relationship always becomes its own table whose primary key is the pair of foreign keys. Placing the key on the N side is the rule for 1:N."],"href":"/rapid-review-cs/dbms#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q1","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q1","front":"Compared to a DFA, an NFA can recognise:","back":"Exactly the same class of languages","keyPoints":["The subset construction converts any n-state NFA into an equivalent DFA with at most 2ⁿ states. Non-determinism buys conciseness of description, never additional recognising power."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q2","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q2","front":"The language {aⁿbⁿ | n ≥ 0} is not regular because:","back":"A finite automaton has bounded memory and cannot count an unbounded n","keyPoints":["Matching the count of a's against b's requires remembering an arbitrarily large number, and a finite automaton's only memory is its finite state set. The pumping lemma formalises this."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q3","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q3","front":"The pumping lemma can be used to prove that a language:","back":"Is not regular","keyPoints":["It states a property all regular languages must have, so exhibiting a string that cannot be pumped proves non-regularity. Satisfying the lemma does not prove regularity - it is necessary, not sufficient."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q4","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q4","front":"Context-free languages are NOT closed under:","back":"Intersection","keyPoints":["{aⁿbⁿcᵐ} and {aⁿbᵐcᵐ} are both context-free, but their intersection {aⁿbⁿcⁿ} is not. CFLs are also not closed under complement, though intersection with a regular language is fine."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q5","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q5","front":"A grammar is ambiguous if:","back":"Some string has more than one parse tree","keyPoints":["Ambiguity means more than one parse tree - equivalently more than one leftmost derivation - for a single string. It is a property of the grammar, and can often be removed by encoding precedence and associativity."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q6","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q6","front":"Which is true of the halting problem?","back":"It is undecidable, but recursively enumerable","keyPoints":["You can recognise halting by simulating and accepting if it stops - so it is recursively enumerable - but there is no way to decide non-halting, so no algorithm always terminates with an answer. Its complement is not even recognisable."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q7","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q7","front":"A problem that is NP-hard but not NP-complete:","back":"Is at least as hard as every NP problem but is not itself in NP","keyPoints":["NP-completeness requires both NP-hardness and membership in NP. The halting problem is NP-hard - everything in NP reduces to it - yet it is undecidable and therefore not in NP."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q8","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q8","front":"Which machine model recognises exactly the context-free languages?","back":"Pushdown automaton","keyPoints":["A PDA is a finite automaton plus a stack, which supplies exactly the nested-structure memory context-free grammars need. Linear bounded automata handle context-sensitive languages; Turing machines handle recursively enumerable ones."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q9","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q9","front":"Rice's theorem states that:","back":"Every non-trivial semantic property of program behaviour is undecidable","keyPoints":["If a property concerns what a program does - rather than how its source is written - and some programs have it while others do not, no algorithm can decide it for all programs. Program equivalence and 'does it ever output 7' are both covered."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-theory-of-computation--toc-q10","moduleId":"rapidreview","cardId":"qz-theory-of-computation--toc-q10","front":"In the Chomsky hierarchy, which containment is correct?","back":"Regular ⊂ context-free ⊂ context-sensitive ⊂ recursively enumerable","keyPoints":["Each class strictly contains the one below it, matching increasing machine memory: finite state, then a stack, then a bounded tape, then an unbounded tape."],"href":"/rapid-review-cs/theory-of-computation#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q1","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q1","front":"`int x = \"hello\";` is rejected during which phase?","back":"Semantic analysis","keyPoints":["The statement matches the grammar for a declaration with an initialiser perfectly, so it passes syntax analysis. Type compatibility is a semantic property that no context-free grammar can express."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q2","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q2","front":"Lexical analysis is implemented with finite automata because:","back":"Tokens are described by regular expressions, which finite automata recognise exactly","keyPoints":["Token patterns are regular languages, and finite automata recognise precisely those. Anything requiring nesting - such as balanced brackets - needs a stack and is therefore the parser's job."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q3","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q3","front":"Left recursion must be eliminated for which parsing technique?","back":"Top-down recursive descent","keyPoints":["A recursive-descent routine for E → E + T calls itself immediately without consuming input, recursing forever. Bottom-up parsers shift tokens before reducing, so left recursion is not a problem for them."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q4","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q4","front":"An LR parser constructs:","back":"A rightmost derivation in reverse, bottom-up","keyPoints":["LR parsers shift tokens and reduce completed right-hand sides, building the tree from the leaves up. Tracing the reductions backwards yields a rightmost derivation."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q5","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q5","front":"A basic block is:","back":"A sequence with one entry at the start and one exit at the end","keyPoints":["No branch enters except at the first instruction and none leaves except from the last, so control flows straight through. That property makes basic blocks the unit of local optimisation and the nodes of the control flow graph."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q6","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q6","front":"\"Undefined reference to printf\" is produced by:","back":"The linker","keyPoints":["The declaration in stdio.h satisfies the compiler, which emits a call to an external symbol. Only the linker, resolving symbols across object files and libraries, discovers that no definition was supplied."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q7","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q7","front":"Register allocation is typically modelled as:","back":"A graph colouring problem on the interference graph","keyPoints":["Variables live at the same time interfere and must occupy different registers, which is exactly a colouring constraint. Since graph colouring is NP-complete, compilers use heuristics and spill to memory when colouring fails."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q8","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q8","front":"Replacing `x * 2` with `x << 1` is an example of:","back":"Strength reduction","keyPoints":["Strength reduction substitutes a cheaper operation for a more expensive one with the same effect. Constant folding evaluates constant expressions; dead code elimination removes unused computation."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q9","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q9","front":"Which parser generator output is used by most real compilers, balancing power against table size?","back":"LALR(1)","keyPoints":["LALR(1) merges LR(1) states with identical cores, giving nearly full LR(1) power with dramatically smaller tables. It is what yacc and bison generate."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-compiler-design--cd-q10","moduleId":"rapidreview","cardId":"qz-compiler-design--cd-q10","front":"The compiler front end is distinguished from the back end in that the front end:","back":"Depends on the source language but not the target machine","keyPoints":["The split is by dependency, not merely order. A source-dependent front end and a machine-dependent back end meeting at a shared IR is what lets one suite support n languages and m targets with n + m components rather than n × m."],"href":"/rapid-review-cs/compiler-design#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q1","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q1","front":"Verification differs from validation in that verification asks:","back":"Are we building the product right?","keyPoints":["Verification checks the product against its specification, largely through reviews and inspections. Validation checks it against the user's actual need. A system can pass verification and still fail validation if the specification was wrong."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q2","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q2","front":"Which combination indicates good modular design?","back":"Low coupling, high cohesion","keyPoints":["Low coupling means modules can be understood and changed independently; high cohesion means each module's contents genuinely belong together. Splitting responsibilities correctly improves both at once."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q3","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q3","front":"What distinguishes the spiral model from other iterative models?","back":"Each loop begins with explicit risk analysis","keyPoints":["Iteration alone is common to many models. Spiral's defining feature is that every cycle starts by identifying and analysing risks, prototyping the highest ones first."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q4","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q4","front":"For an input field accepting values 1 to 100, boundary value analysis suggests testing:","back":"0, 1, 2, 99, 100 and 101","keyPoints":["Defects cluster where comparisons are written, so values just below, at and just above each boundary find the most bugs. Interior values like 50 add almost nothing beyond one equivalence-class representative."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q5","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q5","front":"A module that reads and writes another module's internal variables exhibits:","back":"Content coupling","keyPoints":["Content coupling is the worst form - one module depends on another's internals, so any change to those internals breaks it. Data coupling, passing only simple parameters, is the goal."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q6","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q6","front":"\"The system should be fast\" is a poor requirement mainly because it is:","back":"Not verifiable - no test can determine whether it is met","keyPoints":["Non-functional requirements are legitimate and necessary. The defect is the missing measurable threshold: without one such as '95% of pages load in under 2 seconds', no test can pass or fail it."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q7","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q7","front":"Which testing level is performed by the customer against their actual requirements?","back":"Acceptance testing","keyPoints":["Acceptance testing determines whether the delivered system solves the customer's real problem. System testing verifies the integrated system against its specification, which is a different question."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q8","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q8","front":"Continuous Delivery differs from Continuous Deployment in that Continuous Delivery:","back":"Prepares every passing build for release but leaves the release decision to a human","keyPoints":["Both automate the pipeline through to a release-ready artefact. Continuous Deployment additionally pushes every passing build to production with no manual gate."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q9","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q9","front":"The largest share of maintenance effort typically goes to:","back":"Perfective - new features and improvements","keyPoints":["Roughly half of maintenance is enhancement requested by users, not defect repair. This is why designing for change matters as much as designing for initial correctness."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-software-engineering--se-q10","moduleId":"rapidreview","cardId":"qz-software-engineering--se-q10","front":"Brooks's law states that adding people to a late software project:","back":"Makes it later, because of training time and growing communication overhead","keyPoints":["New members must be trained by existing ones, consuming productive time, and communication paths grow as n(n−1)/2. Beyond a point the coordination cost exceeds the added output."],"href":"/rapid-review-cs/software-engineering#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q1","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q1","front":"To send a confidential message to Alice, you encrypt it with:","back":"Alice's public key","keyPoints":["Only Alice holds the matching private key, so only she can decrypt it. Encrypting with your own private key produces a signature - anyone with your public key can read it, so it provides authenticity rather than secrecy."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q2","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q2","front":"The purpose of a salt in password storage is to:","back":"Ensure identical passwords produce different hashes, defeating precomputed rainbow tables","keyPoints":["A unique per-user salt means an attacker cannot precompute one table that cracks every account, and equal hashes no longer reveal shared passwords. Salting does not make passwords recoverable - hashing is one-way."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q3","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q3","front":"Which mechanism provides non-repudiation?","back":"A digital signature made with a private key","keyPoints":["Only the private key holder can produce a valid signature, so they cannot credibly deny it. An HMAC proves the message came from someone holding the shared secret - but either party could have produced it, so it cannot settle a dispute."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q4","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q4","front":"The only reliable defence against SQL injection is:","back":"Parameterised queries, which fix the query structure before data is supplied","keyPoints":["Parameterised queries send structure and data separately, so input can never be reinterpreted as SQL. Escaping and blocklists are perpetually bypassable; least privilege limits damage but does not prevent the injection."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q5","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q5","front":"SHA-256 is a poor choice for hashing passwords because it is:","back":"Too fast, allowing billions of guesses per second on commodity GPUs","keyPoints":["SHA-256 remains cryptographically sound for integrity. Its speed is the problem: password hashing wants deliberate slowness, which is what bcrypt, scrypt and Argon2 provide through a tunable cost factor."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q6","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q6","front":"Practical systems combine asymmetric and symmetric cryptography because:","back":"Asymmetric solves key distribution but is too slow for bulk data, so it is used to agree a symmetric session key","keyPoints":["Each covers the other's weakness. Asymmetric cryptography lets two strangers establish a shared secret without a prior channel; symmetric encryption then handles the actual traffic at usable speed."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q7","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q7","front":"Forward secrecy means that:","back":"Recorded traffic stays secure even if the server's long-term private key is later stolen","keyPoints":["Session keys are ephemeral and are not derivable from the long-term key, so an attacker who archives ciphertext today and compromises the server years later still cannot decrypt those past sessions."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q8","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q8","front":"CSRF differs from XSS in that CSRF:","back":"Exploits the browser's automatic inclusion of credentials, without needing to read the response","keyPoints":["CSRF causes the victim's browser to send an authenticated request; the attacker never sees the response and does not need to. XSS runs script in the victim's page and is prevented by output encoding - the two need different defences."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q9","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q9","front":"Kerckhoffs's principle states that a cryptosystem should remain secure even if:","back":"Everything about the system except the key is public knowledge","keyPoints":["Security must rest on the secrecy of the key alone. Algorithms get reverse-engineered and leak permanently; keys can be rotated, and public algorithms benefit from open scrutiny."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"rapidreview:qz-security-cryptography--sec-q10","moduleId":"rapidreview","cardId":"qz-security-cryptography--sec-q10","front":"HTTPS does NOT protect:","back":"Which website you connected to","keyPoints":["The DNS lookup, destination IP and SNI field all reveal the host. TLS protects the content and authenticates the server, but the fact of the connection is visible to anyone observing the network."],"href":"/rapid-review-cs/security-cryptography#self-check","moduleLabel":"CS Syllabus"},{"key":"sysdesign:qz-what-is-system-design--f1q1","moduleId":"sysdesign","cardId":"qz-what-is-system-design--f1q1","front":"Which of these is a non-functional requirement?","back":"The p99 read latency must stay under 150 ms","keyPoints":["Latency targets describe how well the system must behave, not what it does. The other three are features - functional requirements."],"href":"/system-design-interview/questions/what-is-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-what-is-system-design--f1q2","moduleId":"sysdesign","cardId":"qz-what-is-system-design--f1q2","front":"99.99% availability allows roughly how much downtime per month?","back":"4.4 minutes","keyPoints":["Four nines ≈ 52.6 minutes per year, which is about 4.4 minutes per month. Three nines is ~43.8 minutes per month; five nines is ~26 seconds."],"href":"/system-design-interview/questions/what-is-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-what-is-system-design--f1q3","moduleId":"sysdesign","cardId":"qz-what-is-system-design--f1q3","front":"Batching 100 writes into one request raises throughput 12.5× but raises per-write latency 8×. What does this demonstrate?","back":"Latency and throughput are independent dimensions that can be traded","keyPoints":["They are distinct dimensions. Batching amortises fixed per-request cost across many items, buying throughput at the cost of the time the first item waits."],"href":"/system-design-interview/questions/what-is-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-what-is-system-design--f1q4","moduleId":"sysdesign","cardId":"qz-what-is-system-design--f1q4","front":"In a 45-minute interview, roughly when should you have a complete end-to-end high-level design on the board?","back":"By minute 20","keyPoints":["Aim for a complete (even naive) design by around minute 20, leaving 15–20 minutes for the deep dive and scaling discussion - the highest-signal part of the interview."],"href":"/system-design-interview/questions/what-is-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-back-of-the-envelope-estimation--f2q1","moduleId":"sysdesign","cardId":"qz-back-of-the-envelope-estimation--f2q1","front":"A service has 50 million DAU, each making 4 requests per day. Roughly what is the peak QPS at a 2× peak factor?","back":"~4,600","keyPoints":["50 M × 4 = 200 M/day. 200 M ÷ 86,400 ≈ 2,300 average QPS. × 2 for peak ≈ 4,600 QPS."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-back-of-the-envelope-estimation--f2q2","moduleId":"sysdesign","cardId":"qz-back-of-the-envelope-estimation--f2q2","front":"Roughly how much slower is an SSD read than a main-memory read?","back":"~1,000×","keyPoints":["Main memory is ~100 ns; an SSD read is ~100 µs. That is a factor of about 1,000 - the gap that makes caching worthwhile."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-back-of-the-envelope-estimation--f2q3","moduleId":"sysdesign","cardId":"qz-back-of-the-envelope-estimation--f2q3","front":"At 20,000 QPS with an average latency of 50 ms, how many requests are in flight at any moment?","back":"1,000","keyPoints":["Little's Law: L = λW = 20,000 × 0.05 = 1,000 concurrent requests. This sizes your thread and connection pools."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-back-of-the-envelope-estimation--f2q4","moduleId":"sysdesign","cardId":"qz-back-of-the-envelope-estimation--f2q4","front":"Why do capacity plans target 60–70% utilisation instead of 95%?","back":"Queueing delay grows non-linearly and explodes near saturation","keyPoints":["Average queue wait scales as ρ/(1−ρ). At 95% utilisation you wait ~19 service times versus ~1.5 at 60%. Headroom buys latency stability."],"href":"/system-design-interview/questions/back-of-the-envelope-estimation#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-scalability-availability-and-reliability--f3q1","moduleId":"sysdesign","cardId":"qz-scalability-availability-and-reliability--f3q1","front":"Four services, each 99.95% available, all on the critical path. Approximate end-to-end availability?","back":"99.80%","keyPoints":["Series dependencies multiply: 0.9995⁴ ≈ 0.9980, i.e. about 99.8% - roughly 87 minutes of downtime per month instead of 22."],"href":"/system-design-interview/questions/scalability-availability-and-reliability#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-scalability-availability-and-reliability--f3q2","moduleId":"sysdesign","cardId":"qz-scalability-availability-and-reliability--f3q2","front":"Two replicas, each 99% available, behind a load balancer. Assuming independent failures, combined availability?","back":"99.99%","keyPoints":["Parallel redundancy: 1 − (0.01 × 0.01) = 0.9999, i.e. 99.99% - but only if the failures really are independent."],"href":"/system-design-interview/questions/scalability-availability-and-reliability#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-scalability-availability-and-reliability--f3q3","moduleId":"sysdesign","cardId":"qz-scalability-availability-and-reliability--f3q3","front":"A system fails once a week but recovers automatically in 15 seconds. Roughly what availability is that?","back":"~99.997%","keyPoints":["15 s per week ≈ 13 minutes per year. Availability = MTBF/(MTBF+MTTR) ≈ 99.997%. Fast recovery beats rare failure."],"href":"/system-design-interview/questions/scalability-availability-and-reliability#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-scalability-availability-and-reliability--f3q4","moduleId":"sysdesign","cardId":"qz-scalability-availability-and-reliability--f3q4","front":"Which of these is NOT typically a single point of failure worth auditing?","back":"A stateless app server behind a load balancer with peers in other zones","keyPoints":["A stateless server with healthy peers across zones is exactly the redundancy you want. The other three are classic non-obvious SPOFs that have caused major real-world outages."],"href":"/system-design-interview/questions/scalability-availability-and-reliability#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-how-the-internet-works-dns-tcp-tls-http--n1q1","moduleId":"sysdesign","cardId":"qz-how-the-internet-works-dns-tcp-tls-http--n1q1","front":"Roughly how many round trips does a cold HTTPS request cost before the HTTP request itself can be sent, using TLS 1.3?","back":"3","keyPoints":["DNS (1, if uncached) + TCP handshake (1) + TLS 1.3 (1) then the request itself. Roughly three round trips before data flows; TLS 1.2 adds one more."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-how-the-internet-works-dns-tcp-tls-http--n1q2","moduleId":"sysdesign","cardId":"qz-how-the-internet-works-dns-tcp-tls-http--n1q2","front":"Why can HTTP/2 be slower than HTTP/1.1 on a lossy network?","back":"A single lost TCP packet stalls all multiplexed streams","keyPoints":["HTTP/2 multiplexes over one TCP connection, and TCP delivers bytes strictly in order - so one lost packet blocks every stream. HTTP/1.1's six separate connections isolate that damage."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-how-the-internet-works-dns-tcp-tls-http--n1q3","moduleId":"sysdesign","cardId":"qz-how-the-internet-works-dns-tcp-tls-http--n1q3","front":"Which is a genuine advantage of an L7 load balancer over L4?","back":"It can route based on URL path and detect application-level unhealthiness","keyPoints":["L7 parses HTTP, so it can route by path/host/header and health-check the application rather than just the TCP port. That parsing is exactly why it costs more CPU than L4."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-how-the-internet-works-dns-tcp-tls-http--n1q4","moduleId":"sysdesign","cardId":"qz-how-the-internet-works-dns-tcp-tls-http--n1q4","front":"Your service streams live audio. A packet is lost. What should happen?","back":"Drop it and continue - a late audio packet is worthless","keyPoints":["For real-time media, timeliness beats completeness. That is the core reason live audio and video ride on UDP-based protocols rather than TCP."],"href":"/system-design-interview/questions/how-the-internet-works-dns-tcp-tls-http#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-design-rest-grpc-graphql--n2q1","moduleId":"sysdesign","cardId":"qz-api-design-rest-grpc-graphql--n2q1","front":"Which HTTP method is NOT inherently idempotent?","back":"POST","keyPoints":["POST creates a new resource on each call, so retries duplicate. PUT and DELETE leave identical state when repeated; GET has no side effects."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-design-rest-grpc-graphql--n2q2","moduleId":"sysdesign","cardId":"qz-api-design-rest-grpc-graphql--n2q2","front":"Why is `LIMIT 20 OFFSET 100000` slow even with an index on the sort column?","back":"The database must walk and discard 100,000 rows before returning any","keyPoints":["The index is used, but the engine still traverses and discards every skipped row. Cost grows linearly with offset depth, which keyset pagination avoids entirely."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-design-rest-grpc-graphql--n2q3","moduleId":"sysdesign","cardId":"qz-api-design-rest-grpc-graphql--n2q3","front":"Two concurrent requests arrive with the same idempotency key. What is the correct behaviour for the second?","back":"Return 409 while the first is in progress, then replay the stored response once it completes","keyPoints":["A duplicate must never execute the side effect twice. Returning 409 while in progress and replaying the recorded response afterwards keeps exactly-once semantics from the caller's perspective."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-design-rest-grpc-graphql--n2q4","moduleId":"sysdesign","cardId":"qz-api-design-rest-grpc-graphql--n2q4","front":"Which API change is safely backwards compatible?","back":"Adding an optional field to the response body","keyPoints":["Additive optional fields are safe for clients that ignore unknown properties. The others change existing behaviour - and the page-size change is the most dangerous because nothing errors."],"href":"/system-design-interview/questions/api-design-rest-grpc-graphql#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-realtime-communication-websockets-sse-polling--n3q1","moduleId":"sysdesign","cardId":"qz-realtime-communication-websockets-sse-polling--n3q1","front":"You need to stream progress updates for a long-running export job to a browser. The client sends nothing. Best choice?","back":"Server-Sent Events","keyPoints":["One-way server→client is exactly SSE's use case, and you get automatic reconnection plus Last-Event-ID resumption without writing any of it."],"href":"/system-design-interview/questions/realtime-communication-websockets-sse-polling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-realtime-communication-websockets-sse-polling--n3q2","moduleId":"sysdesign","cardId":"qz-realtime-communication-websockets-sse-polling--n3q2","front":"A gateway holding 100,000 WebSocket connections crashes. Which client behaviour prevents a cascading failure?","back":"Exponential backoff with random jitter","keyPoints":["Backoff spreads retries over time; jitter desynchronises them. Fixed intervals just move the thundering herd to a predictable schedule."],"href":"/system-design-interview/questions/realtime-communication-websockets-sse-polling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-realtime-communication-websockets-sse-polling--n3q3","moduleId":"sysdesign","cardId":"qz-realtime-communication-websockets-sse-polling--n3q3","front":"Why keep business logic out of the WebSocket gateway tier?","back":"So feature deploys do not disconnect every live connection","keyPoints":["Restarting a gateway drops its sockets. Keeping gateways thin means they restart rarely, so ordinary feature deploys never disturb connected users."],"href":"/system-design-interview/questions/realtime-communication-websockets-sse-polling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-realtime-communication-websockets-sse-polling--n3q4","moduleId":"sysdesign","cardId":"qz-realtime-communication-websockets-sse-polling--n3q4","front":"What makes reconnects gap-free after a network blip?","back":"A per-conversation sequence number plus backfill from a durable store","keyPoints":["The socket is not durable. The client records the last sequence number it saw and the server replays anything newer from persistent storage."],"href":"/system-design-interview/questions/realtime-communication-websockets-sse-polling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-indexes-and-query-performance--d1q1","moduleId":"sysdesign","cardId":"qz-database-indexes-and-query-performance--d1q1","front":"Given `CREATE INDEX idx ON t (a, b, c)`, which query can NOT use the index for seeking?","back":"WHERE b = 2 AND c = 3","keyPoints":["The leftmost-prefix rule: without a predicate on `a`, the index cannot be seeked. The engine would need a full index scan or a table scan."],"href":"/system-design-interview/questions/database-indexes-and-query-performance#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-indexes-and-query-performance--d1q2","moduleId":"sysdesign","cardId":"qz-database-indexes-and-query-performance--d1q2","front":"Why is a random UUIDv4 primary key bad for write throughput?","back":"Inserts scatter across the whole index, causing page splits and cold pages","keyPoints":["Random keys touch random pages, so the working set becomes the entire index and inserts constantly split pages. Sequential keys append to a single hot page."],"href":"/system-design-interview/questions/database-indexes-and-query-performance#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-indexes-and-query-performance--d1q3","moduleId":"sysdesign","cardId":"qz-database-indexes-and-query-performance--d1q3","front":"Which workload is the best fit for an LSM-tree storage engine?","back":"High-volume append-only time-series ingestion","keyPoints":["LSM turns writes into sequential appends, ideal for high-ingest append-mostly data. Update- and delete-heavy workloads fight compaction."],"href":"/system-design-interview/questions/database-indexes-and-query-performance#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-indexes-and-query-performance--d1q4","moduleId":"sysdesign","cardId":"qz-database-indexes-and-query-performance--d1q4","front":"EXPLAIN ANALYZE shows `rows=1` estimated but `rows=1,240,000` actual. What is the most likely cause?","back":"Statistics are stale, so the planner chose a plan for the wrong data size","keyPoints":["A huge estimate/actual divergence means the optimiser was misinformed. Running ANALYZE to refresh statistics is the first fix."],"href":"/system-design-interview/questions/database-indexes-and-query-performance#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-sql-vs-nosql-choosing-a-database--d2q1","moduleId":"sysdesign","cardId":"qz-sql-vs-nosql-choosing-a-database--d2q1","front":"You need 200,000 writes/second of append-only sensor readings, always queried by device and time range, never updated. Best fit?","back":"Wide-column or time-series store","keyPoints":["Append-only, extremely high write volume, predictable access by partition key and time range - the canonical wide-column / time-series workload."],"href":"/system-design-interview/questions/sql-vs-nosql-choosing-a-database#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-sql-vs-nosql-choosing-a-database--d2q2","moduleId":"sysdesign","cardId":"qz-sql-vs-nosql-choosing-a-database--d2q2","front":"What is the fundamental trade in choosing a relational database?","back":"Query flexibility for horizontal write scalability","keyPoints":["Relational stores let you query data any way later; that flexibility is what makes horizontal write scaling hard. Non-relational stores invert both."],"href":"/system-design-interview/questions/sql-vs-nosql-choosing-a-database#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-sql-vs-nosql-choosing-a-database--d2q3","moduleId":"sysdesign","cardId":"qz-sql-vs-nosql-choosing-a-database--d2q3","front":"You keep a search index alongside Postgres. What must be true of the index?","back":"It must be fully rebuildable from Postgres and never the source of truth","keyPoints":["Derived stores must be rebuildable and fed asynchronously (CDC or outbox). If it holds data you cannot regenerate, it has quietly become a second source of truth."],"href":"/system-design-interview/questions/sql-vs-nosql-choosing-a-database#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-sql-vs-nosql-choosing-a-database--d2q4","moduleId":"sysdesign","cardId":"qz-sql-vs-nosql-choosing-a-database--d2q4","front":"Which value is safest to denormalise into another table?","back":"A user's immutable signup date","keyPoints":["Immutable data can never drift. Prices, balances and inventory change frequently and are exactly where duplicated copies cause real bugs."],"href":"/system-design-interview/questions/sql-vs-nosql-choosing-a-database#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-acid-transactions-and-isolation-levels--d3q1","moduleId":"sysdesign","cardId":"qz-acid-transactions-and-isolation-levels--d3q1","front":"Two transactions each read 'at least one doctor is on call' and each sign a different doctor off. Which anomaly is this?","back":"Write skew","keyPoints":["Write skew: each transaction reads an overlapping set, checks an invariant, and writes a different row. Only Serializable isolation prevents it."],"href":"/system-design-interview/questions/acid-transactions-and-isolation-levels#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-acid-transactions-and-isolation-levels--d3q2","moduleId":"sysdesign","cardId":"qz-acid-transactions-and-isolation-levels--d3q2","front":"What is the default isolation level in PostgreSQL?","back":"Read Committed","keyPoints":["Postgres defaults to Read Committed, which prevents dirty reads but still allows non-repeatable reads, phantoms and lost updates."],"href":"/system-design-interview/questions/acid-transactions-and-isolation-levels#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-acid-transactions-and-isolation-levels--d3q3","moduleId":"sysdesign","cardId":"qz-acid-transactions-and-isolation-levels--d3q3","front":"Which is the most robust fix for a counter increment under high concurrency?","back":"UPDATE t SET n = n + 1 WHERE id = ?","keyPoints":["An atomic in-database update eliminates the read-modify-write window entirely - no lock, no retry loop, no lost update."],"href":"/system-design-interview/questions/acid-transactions-and-isolation-levels#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-acid-transactions-and-isolation-levels--d3q4","moduleId":"sysdesign","cardId":"qz-acid-transactions-and-isolation-levels--d3q4","front":"In an MVCC database, what does a long-running idle transaction cause?","back":"Old row versions cannot be vacuumed, causing bloat","keyPoints":["MVCC keeps versions visible to any open snapshot. A long-open transaction pins them, blocking cleanup and bloating tables and indexes."],"href":"/system-design-interview/questions/acid-transactions-and-isolation-levels#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-replication-and-sharding--d4q1","moduleId":"sysdesign","cardId":"qz-database-replication-and-sharding--d4q1","front":"A user updates their name and the next page load shows the old one. Most likely cause?","back":"Read served by a replica that has not applied the change yet","keyPoints":["Classic replication lag with a read routed to a replica. The fix is read-your-writes - typically routing that user's reads to the primary for a short window."],"href":"/system-design-interview/questions/database-replication-and-sharding#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-replication-and-sharding--d4q2","moduleId":"sysdesign","cardId":"qz-database-replication-and-sharding--d4q2","front":"You shard by `hash(user_id) mod 8` and need to add a ninth shard. What happens?","back":"Nearly every key maps to a different shard and must be moved","keyPoints":["Changing the modulus changes almost every mapping. Consistent hashing or a logical-shard indirection layer avoids this."],"href":"/system-design-interview/questions/database-replication-and-sharding#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-replication-and-sharding--d4q3","moduleId":"sysdesign","cardId":"qz-database-replication-and-sharding--d4q3","front":"Which is the strongest reason NOT to shard yet?","back":"A single primary plus replicas and caching still comfortably handles the load","keyPoints":["Sharding costs joins, transactions and operational simplicity. Exhaust replication, caching and vertical scaling first, and be able to state the number where they run out."],"href":"/system-design-interview/questions/database-replication-and-sharding#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-database-replication-and-sharding--d4q4","moduleId":"sysdesign","cardId":"qz-database-replication-and-sharding--d4q4","front":"A celebrity account makes one shard 50× hotter than the others. Which is NOT a valid mitigation?","back":"Switching from hash to range partitioning on the same key","keyPoints":["Range partitioning does not help - the celebrity's rows still share one key value and therefore one shard. Sub-bucketing, isolation or caching do help."],"href":"/system-design-interview/questions/database-replication-and-sharding#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-caching-strategies-and-eviction-policies--c1q1","moduleId":"sysdesign","cardId":"qz-caching-strategies-and-eviction-policies--c1q1","front":"After writing to the database, what should you do to the cache?","back":"Delete the key and let the next read repopulate","keyPoints":["Deleting is idempotent and order-independent. Writing the value in allows two concurrent writers to interleave so the older value lands last and persists until TTL."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-caching-strategies-and-eviction-policies--c1q2","moduleId":"sysdesign","cardId":"qz-caching-strategies-and-eviction-policies--c1q2","front":"100,000 keys are warmed at deploy with identical 1-hour TTLs. What happens an hour later?","back":"An avalanche: all keys expire at once and the database is overwhelmed","keyPoints":["Keys populated together expire together. Adding random jitter to each TTL spreads the expiry - and the resulting database load - over time."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-caching-strategies-and-eviction-policies--c1q3","moduleId":"sysdesign","cardId":"qz-caching-strategies-and-eviction-policies--c1q3","front":"A nightly analytics job scans a million rows and your morning hit rate collapses. Which policy would have prevented it?","back":"LFU","keyPoints":["LFU evicts by access frequency, so single-touch scan keys never accumulate enough frequency to displace genuinely hot entries. LRU is exactly the vulnerable policy here."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-caching-strategies-and-eviction-policies--c1q4","moduleId":"sysdesign","cardId":"qz-caching-strategies-and-eviction-policies--c1q4","front":"Which data is the worst candidate for caching?","back":"A counter written 500×/s and read 5×/s","keyPoints":["Write-heavy, read-light data costs continuous invalidation for almost no read benefit. Cache things read far more often than they change."],"href":"/system-design-interview/questions/caching-strategies-and-eviction-policies#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cdn-and-edge-caching--c2q1","moduleId":"sysdesign","cardId":"qz-cdn-and-edge-caching--c2q1","front":"Which header combination is correct for a JavaScript bundle whose filename contains a content hash?","back":"Cache-Control: public, max-age=31536000, immutable","keyPoints":["A content-hashed filename can never change meaning, so cache it for a year and skip revalidation entirely. A new build produces a new URL."],"href":"/system-design-interview/questions/cdn-and-edge-caching#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cdn-and-edge-caching--c2q2","moduleId":"sysdesign","cardId":"qz-cdn-and-edge-caching--c2q2","front":"What does `stale-while-revalidate=600` do?","back":"Serves the stale response immediately for up to 600 s past expiry while refreshing in the background","keyPoints":["It decouples freshness from latency: users never wait for a revalidation, and the edge refreshes asynchronously. It also prevents expiry stampedes."],"href":"/system-design-interview/questions/cdn-and-edge-caching#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cdn-and-edge-caching--c2q3","moduleId":"sysdesign","cardId":"qz-cdn-and-edge-caching--c2q3","front":"Why does origin shielding matter after a global purge?","back":"It prevents every PoP from independently fetching the same object from origin","keyPoints":["Without a shield, each of hundreds of PoPs misses and fetches independently. Shielding funnels those misses through one PoP per region, cutting origin load by orders of magnitude."],"href":"/system-design-interview/questions/cdn-and-edge-caching#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cdn-and-edge-caching--c2q4","moduleId":"sysdesign","cardId":"qz-cdn-and-edge-caching--c2q4","front":"You must remove a leaked document from all caches immediately. What is the reliable approach?","back":"Enforce an authorisation check at the edge or origin - do not rely on purge timing","keyPoints":["Purges are eventually consistent across PoPs. Anything security-critical needs an access check on every request, not a cache-invalidation race."],"href":"/system-design-interview/questions/cdn-and-edge-caching#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-horizontal-vs-vertical-scaling--s1q1","moduleId":"sysdesign","cardId":"qz-horizontal-vs-vertical-scaling--s1q1","front":"What is the precondition for horizontal scaling of an application tier?","back":"Stateless instances - no request state in local memory or disk","keyPoints":["Interchangeable instances are what make load balancing, autoscaling and instance failure routine. Everything else is optional."],"href":"/system-design-interview/questions/horizontal-vs-vertical-scaling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-horizontal-vs-vertical-scaling--s1q2","moduleId":"sysdesign","cardId":"qz-horizontal-vs-vertical-scaling--s1q2","front":"An I/O-bound API sits at 30% CPU while latency triples. Which autoscaling signal is most appropriate?","back":"In-flight request concurrency or requests per instance","keyPoints":["An I/O-bound service saturates on concurrency and connection limits long before CPU. Little's Law gives you the concurrency figure to scale on."],"href":"/system-design-interview/questions/horizontal-vs-vertical-scaling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-horizontal-vs-vertical-scaling--s1q3","moduleId":"sysdesign","cardId":"qz-horizontal-vs-vertical-scaling--s1q3","front":"Why should scale-in be slower than scale-out?","back":"Over-provisioning briefly costs money; under-provisioning causes an outage","keyPoints":["The costs are asymmetric. Keeping spare capacity a few minutes longer is cheap insurance against a premature scale-in during a dip that immediately reverses."],"href":"/system-design-interview/questions/horizontal-vs-vertical-scaling#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-load-balancing-algorithms--s2q1","moduleId":"sysdesign","cardId":"qz-load-balancing-algorithms--s2q1","front":"A backend fails instantly with 500s, so it has near-zero open connections. Which algorithm sends it MORE traffic?","back":"Least connections","keyPoints":["Least connections interprets zero connections as 'idle and available'. Error-rate-based outlier ejection is what prevents this death spiral."],"href":"/system-design-interview/questions/load-balancing-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-load-balancing-algorithms--s2q2","moduleId":"sysdesign","cardId":"qz-load-balancing-algorithms--s2q2","front":"Three layers each retry twice on failure. How many backend requests can one user request generate?","back":"27","keyPoints":["Amplification is multiplicative: (1+2)³ = 27. This is why retry budgets and single-layer retries matter more than tuning retry counts."],"href":"/system-design-interview/questions/load-balancing-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-load-balancing-algorithms--s2q3","moduleId":"sysdesign","cardId":"qz-load-balancing-algorithms--s2q3","front":"Why must a readiness check avoid failing when a shared cache is down?","back":"Every instance would report unready at once, leaving the load balancer with no backends","keyPoints":["A shared dependency failure would mark the entire fleet unready simultaneously, converting a degraded service into a total outage. Degrade, do not de-register."],"href":"/system-design-interview/questions/load-balancing-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-load-balancing-algorithms--s2q4","moduleId":"sysdesign","cardId":"qz-load-balancing-algorithms--s2q4","front":"Under overload, which server behaviour is best?","back":"Reject immediately with 503 once the queue exceeds a threshold","keyPoints":["Fast rejection frees resources on both sides and lets callers fail over. Deep queueing turns overload into timeouts that consume capacity on the client and the server."],"href":"/system-design-interview/questions/load-balancing-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consistent-hashing-explained--s3q1","moduleId":"sysdesign","cardId":"qz-consistent-hashing-explained--s3q1","front":"You use `hash(key) % 10` across 10 cache servers and add an 11th. Roughly what fraction of keys map elsewhere?","back":"~91%","keyPoints":["Changing the modulus changes almost every mapping - only about 1/11 of keys keep their server. The cache is effectively cold, which is exactly the outage consistent hashing prevents."],"href":"/system-design-interview/questions/consistent-hashing-explained#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consistent-hashing-explained--s3q2","moduleId":"sysdesign","cardId":"qz-consistent-hashing-explained--s3q2","front":"Why are virtual nodes necessary in a consistent hash ring?","back":"To even out arc sizes and spread a removed node's keys across all survivors","keyPoints":["A few random positions produce wildly uneven arcs. Many virtual positions per server average the load out and make node removal graceful rather than dumping everything on one neighbour."],"href":"/system-design-interview/questions/consistent-hashing-explained#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consistent-hashing-explained--s3q3","moduleId":"sysdesign","cardId":"qz-consistent-hashing-explained--s3q3","front":"One key receives 40% of all traffic. Does consistent hashing help?","back":"No - the key still maps to exactly one node; you need key replication or bounded loads","keyPoints":["The ring distributes keys, not request volume. A single hot key lives on one node regardless of ring configuration, so it needs a separate mitigation."],"href":"/system-design-interview/questions/consistent-hashing-explained#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cap-theorem-and-pacelc--ds1q1","moduleId":"sysdesign","cardId":"qz-cap-theorem-and-pacelc--ds1q1","front":"Why is a 'CA' distributed system not a real option?","back":"Because networks partition, so P is a fact rather than a choice","keyPoints":["Partitions happen in any distributed system, so the system must tolerate them. The real choice is what to do during one."],"href":"/system-design-interview/questions/cap-theorem-and-pacelc#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cap-theorem-and-pacelc--ds1q2","moduleId":"sysdesign","cardId":"qz-cap-theorem-and-pacelc--ds1q2","front":"What does the 'ELC' half of PACELC describe?","back":"The trade between latency and consistency when there is no partition","keyPoints":["Else, choose Latency or Consistency. This is the trade you make on every single request in normal operation, which is why it shapes p99 more than CAP does."],"href":"/system-design-interview/questions/cap-theorem-and-pacelc#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-cap-theorem-and-pacelc--ds1q3","moduleId":"sysdesign","cardId":"qz-cap-theorem-and-pacelc--ds1q3","front":"In Cassandra with N=3, which read/write configuration gives strong consistency?","back":"R=2, W=2","keyPoints":["Strong consistency requires R + W > N. With N=3, quorum reads and writes (2 + 2 = 4 > 3) guarantee an overlapping replica that has the latest value."],"href":"/system-design-interview/questions/cap-theorem-and-pacelc#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consistency-models-and-replication--ds2q1","moduleId":"sysdesign","cardId":"qz-consistency-models-and-replication--ds2q1","front":"Which model prevents a reply appearing before the message it replies to?","back":"Causal consistency","keyPoints":["Causal consistency orders causally related operations for every observer. It is much cheaper than linearizability and prevents exactly the anomaly users notice."],"href":"/system-design-interview/questions/consistency-models-and-replication#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consistency-models-and-replication--ds2q2","moduleId":"sysdesign","cardId":"qz-consistency-models-and-replication--ds2q2","front":"With N=5, which configuration tolerates two node failures for both reads and writes?","back":"W=3, R=3","keyPoints":["W=3, R=3 satisfies R+W>N (6>5) and each quorum needs only 3 of 5 nodes, so two failures are survivable on both paths. W=2,R=2 gives 4, which is not >5."],"href":"/system-design-interview/questions/consistency-models-and-replication#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consistency-models-and-replication--ds2q3","moduleId":"sysdesign","cardId":"qz-consistency-models-and-replication--ds2q3","front":"What is the main danger of last-write-wins conflict resolution?","back":"It silently discards one writer's data, and clock skew decides which","keyPoints":["LWW resolves by timestamp, so a clock a few hundred milliseconds ahead can erase a legitimate later write with no error surfaced anywhere."],"href":"/system-design-interview/questions/consistency-models-and-replication#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consensus-and-leader-election--ds3q1","moduleId":"sysdesign","cardId":"qz-consensus-and-leader-election--ds3q1","front":"Why is a 4-node Raft cluster a poor choice?","back":"It tolerates the same single failure as 3 nodes while needing a larger quorum","keyPoints":["Majority of 4 is 3, so only one failure is tolerated - identical to a 3-node cluster - but every commit must now reach three nodes instead of two."],"href":"/system-design-interview/questions/consensus-and-leader-election#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consensus-and-leader-election--ds3q2","moduleId":"sysdesign","cardId":"qz-consensus-and-leader-election--ds3q2","front":"A Raft leader is partitioned from the majority. What can it still do?","back":"Nothing durable - it cannot commit without a majority acknowledging","keyPoints":["Commitment requires majority acknowledgement. The isolated leader may append locally but can never commit, and it truncates those entries when it rejoins."],"href":"/system-design-interview/questions/consensus-and-leader-election#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-consensus-and-leader-election--ds3q3","moduleId":"sysdesign","cardId":"qz-consensus-and-leader-election--ds3q3","front":"What makes a TTL-based distributed lock unsafe for correctness?","back":"A process pause can outlast the TTL, so two clients can believe they hold the lock","keyPoints":["Pauses and network delays are unbounded, so the lock can expire while its holder still believes it is valid. Only a fencing token checked at the resource restores safety."],"href":"/system-design-interview/questions/consensus-and-leader-election#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-distributed-transactions-and-idempotency--ds4q1","moduleId":"sysdesign","cardId":"qz-distributed-transactions-and-idempotency--ds4q1","front":"Why is two-phase commit usually unsuitable across microservices?","back":"Participants hold locks and block indefinitely if the coordinator fails","keyPoints":["2PC's blocking behaviour on coordinator failure is its fatal flaw across service boundaries - and it cannot include third-party APIs at all."],"href":"/system-design-interview/questions/distributed-transactions-and-idempotency#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-distributed-transactions-and-idempotency--ds4q2","moduleId":"sysdesign","cardId":"qz-distributed-transactions-and-idempotency--ds4q2","front":"What does a saga give up compared to a distributed transaction?","back":"Isolation","keyPoints":["Sagas reach eventual atomicity through compensation, but intermediate states are visible to other readers - there is no isolation."],"href":"/system-design-interview/questions/distributed-transactions-and-idempotency#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-distributed-transactions-and-idempotency--ds4q3","moduleId":"sysdesign","cardId":"qz-distributed-transactions-and-idempotency--ds4q3","front":"What problem does the transactional outbox pattern solve?","back":"The dual-write problem: committing a state change and publishing an event atomically","keyPoints":["Writing the event as a row in the same transaction as the state change means both commit or neither does. A relay then publishes at-least-once."],"href":"/system-design-interview/questions/distributed-transactions-and-idempotency#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-distributed-transactions-and-idempotency--ds4q4","moduleId":"sysdesign","cardId":"qz-distributed-transactions-and-idempotency--ds4q4","front":"A consumer applies a side effect, then records the message ID in a second transaction. What is wrong?","back":"A crash between the two leaves the effect applied with no dedup record, so a retry duplicates it","keyPoints":["The dedup record and the side effect must commit atomically. Splitting them recreates exactly the window the pattern exists to close."],"href":"/system-design-interview/questions/distributed-transactions-and-idempotency#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-message-queues-and-event-streams--m1q1","moduleId":"sysdesign","cardId":"qz-message-queues-and-event-streams--m1q1","front":"Three teams each need to react to every OrderPlaced event. Queue or log?","back":"Log - independent consumer groups each read the full stream","keyPoints":["Queue consumers compete, so each message goes to exactly one. A log lets each consumer group track its own offset and read every event independently."],"href":"/system-design-interview/questions/message-queues-and-event-streams#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-message-queues-and-event-streams--m1q2","moduleId":"sysdesign","cardId":"qz-message-queues-and-event-streams--m1q2","front":"Which is the most meaningful alert for an async pipeline?","back":"Oldest unprocessed message older than 2 minutes","keyPoints":["Age maps directly to the user-visible promise. Depth means nothing without knowing throughput - 10,000 messages can be two seconds or two hours of work."],"href":"/system-design-interview/questions/message-queues-and-event-streams#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-message-queues-and-event-streams--m1q3","moduleId":"sysdesign","cardId":"qz-message-queues-and-event-streams--m1q3","front":"Producers publish 5,000/s; consumers process 4,000/s. What happens?","back":"Queue depth and latency grow without bound until something changes","keyPoints":["With λ > μ the queue is unstable. No configuration fixes it - you must scale consumers, shed load, or throttle producers."],"href":"/system-design-interview/questions/message-queues-and-event-streams#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-kafka-architecture-and-delivery-semantics--m2q1","moduleId":"sysdesign","cardId":"qz-kafka-architecture-and-delivery-semantics--m2q1","front":"A topic has 8 partitions. You run a consumer group with 12 consumers. What happens?","back":"8 consumers get one partition each; 4 sit idle","keyPoints":["A partition is assigned to exactly one consumer within a group. Partition count is a hard ceiling on group parallelism."],"href":"/system-design-interview/questions/kafka-architecture-and-delivery-semantics#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-kafka-architecture-and-delivery-semantics--m2q2","moduleId":"sysdesign","cardId":"qz-kafka-architecture-and-delivery-semantics--m2q2","front":"With replication.factor=3, what is the correct min.insync.replicas?","back":"2","keyPoints":["2 tolerates one broker being down while still guaranteeing no acknowledged data is lost. 3 makes a single restart block all writes; 1 makes acks=all meaningless."],"href":"/system-design-interview/questions/kafka-architecture-and-delivery-semantics#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-kafka-architecture-and-delivery-semantics--m2q3","moduleId":"sysdesign","cardId":"qz-kafka-architecture-and-delivery-semantics--m2q3","front":"How do you guarantee all events for one user are processed in order?","back":"Key messages by user ID so they hash to the same partition","keyPoints":["Keying routes all of a user's events to one partition, giving per-user ordering while retaining parallelism across users."],"href":"/system-design-interview/questions/kafka-architecture-and-delivery-semantics#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-kafka-architecture-and-delivery-semantics--m2q4","moduleId":"sysdesign","cardId":"qz-kafka-architecture-and-delivery-semantics--m2q4","front":"Why is increasing a topic's partition count a one-way, disruptive change?","back":"hash(key) % N changes, so existing keys move partitions and lose their ordering guarantee","keyPoints":["The key-to-partition mapping depends on N. Changing it sends a key to a different partition, so ordering is not preserved across the boundary - and partitions can never be removed."],"href":"/system-design-interview/questions/kafka-architecture-and-delivery-semantics#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-monolith-vs-microservices--a1q1","moduleId":"sysdesign","cardId":"qz-monolith-vs-microservices--a1q1","front":"What is the strongest signal that you should split a service out?","back":"Two teams must coordinate every deploy","keyPoints":["Independent deployment by independent teams is the problem microservices genuinely solve. Codebase size is addressed by modularisation, not by network boundaries."],"href":"/system-design-interview/questions/monolith-vs-microservices#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-monolith-vs-microservices--a1q2","moduleId":"sysdesign","cardId":"qz-monolith-vs-microservices--a1q2","front":"Six services, each 99.9% available, all on the critical path. Combined availability?","back":"99.4%","keyPoints":["0.999⁶ ≈ 0.994 - roughly 4.3 hours of downtime per month versus 43 minutes for one service. Critical-path dependencies multiply."],"href":"/system-design-interview/questions/monolith-vs-microservices#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-monolith-vs-microservices--a1q3","moduleId":"sysdesign","cardId":"qz-monolith-vs-microservices--a1q3","front":"Which best identifies a distributed monolith?","back":"Services that cannot be deployed independently","keyPoints":["Independent deployability is the defining property of microservices. Without it you have paid all the distribution costs and gained none of the autonomy."],"href":"/system-design-interview/questions/monolith-vs-microservices#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-gateway-and-service-communication--a2q1","moduleId":"sysdesign","cardId":"qz-api-gateway-and-service-communication--a2q1","front":"Which concern should NOT live in the API gateway?","back":"Deciding whether user 42 may edit document 991","keyPoints":["Record-level authorisation needs domain state. Doing it in the gateway means duplicating business rules or giving the gateway database access."],"href":"/system-design-interview/questions/api-gateway-and-service-communication#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-gateway-and-service-communication--a2q2","moduleId":"sysdesign","cardId":"qz-api-gateway-and-service-communication--a2q2","front":"What is the primary purpose of a BFF?","back":"To let each client type get a tailored, aggregated API owned by its own team","keyPoints":["A BFF removes over-fetching and cross-team negotiation by giving each client an endpoint shaped for it, owned by the team that consumes it."],"href":"/system-design-interview/questions/api-gateway-and-service-communication#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-api-gateway-and-service-communication--a2q3","moduleId":"sysdesign","cardId":"qz-api-gateway-and-service-communication--a2q3","front":"When does a service mesh usually start to pay for itself?","back":"Around 10–15 services, especially with multiple languages or mandatory mTLS","keyPoints":["The value is uniform transport behaviour across many services and languages. Below that scale the sidecar and control-plane overhead outweighs the benefit."],"href":"/system-design-interview/questions/api-gateway-and-service-communication#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-event-driven-architecture-cqrs-and-event-sourcing--a3q1","moduleId":"sysdesign","cardId":"qz-event-driven-architecture-cqrs-and-event-sourcing--a3q1","front":"Which is correctly named as an event?","back":"OrderShipped","keyPoints":["Events are past tense and describe facts. The others are imperative commands with a single intended handler."],"href":"/system-design-interview/questions/event-driven-architecture-cqrs-and-event-sourcing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-event-driven-architecture-cqrs-and-event-sourcing--a3q2","moduleId":"sysdesign","cardId":"qz-event-driven-architecture-cqrs-and-event-sourcing--a3q2","front":"What is the main practical benefit of CQRS?","back":"Read and write models can be optimised and scaled independently","keyPoints":["Writes want normalisation and validation; reads want denormalised, query-shaped data. CQRS lets each be right instead of compromising on one model."],"href":"/system-design-interview/questions/event-driven-architecture-cqrs-and-event-sourcing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-event-driven-architecture-cqrs-and-event-sourcing--a3q3","moduleId":"sysdesign","cardId":"qz-event-driven-architecture-cqrs-and-event-sourcing--a3q3","front":"Which is the strongest case for event sourcing?","back":"A financial ledger with regulatory audit requirements","keyPoints":["Ledgers are genuinely event-shaped and legally require a complete, immutable history. Elsewhere the versioning and replay costs usually outweigh the benefit."],"href":"/system-design-interview/questions/event-driven-architecture-cqrs-and-event-sourcing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-event-driven-architecture-cqrs-and-event-sourcing--a3q4","moduleId":"sysdesign","cardId":"qz-event-driven-architecture-cqrs-and-event-sourcing--a3q4","front":"Why do event-sourced systems need snapshots?","back":"Because replaying a long event history to load an aggregate becomes too slow","keyPoints":["Loading an aggregate means replaying its events. Past a few thousand, a periodic snapshot plus subsequent events is the only way to keep load times acceptable."],"href":"/system-design-interview/questions/event-driven-architecture-cqrs-and-event-sourcing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-designing-for-failure--r1q1","moduleId":"sysdesign","cardId":"qz-designing-for-failure--r1q1","front":"One optional dependency slows to 5 s and your entire service starts timing out. What was missing?","back":"Bulkheads - bounded separate resource pools per dependency","keyPoints":["A shared pool lets one slow dependency consume every thread. Separate bounded pools cap the damage to that one feature."],"href":"/system-design-interview/questions/designing-for-failure#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-designing-for-failure--r1q2","moduleId":"sysdesign","cardId":"qz-designing-for-failure--r1q2","front":"Which feature should fail closed rather than degrade?","back":"Displaying a product's price","keyPoints":["Showing a wrong price has real financial and legal consequences. Cosmetic features degrade; anything where a wrong answer is worse than no answer fails closed."],"href":"/system-design-interview/questions/designing-for-failure#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-designing-for-failure--r1q3","moduleId":"sysdesign","cardId":"qz-designing-for-failure--r1q3","front":"What do RTO and RPO measure?","back":"Time to recover, and the amount of data loss you can tolerate","keyPoints":["Recovery Time Objective is how long until service is restored; Recovery Point Objective is how far back the recovered data may be. Together they pick the DR strategy."],"href":"/system-design-interview/questions/designing-for-failure#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-rate-limiting-algorithms--r2q1","moduleId":"sysdesign","cardId":"qz-rate-limiting-algorithms--r2q1","front":"A limit of 100/minute using a fixed window. A client sends 100 at 10:00:59 and 100 at 10:01:00. What happened?","back":"200 requests arrived in one second - the fixed-window boundary flaw","keyPoints":["Each window individually respected the limit, but the boundary allows up to 2× the intended rate in a short span. Sliding window or token bucket avoids this."],"href":"/system-design-interview/questions/rate-limiting-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-rate-limiting-algorithms--r2q2","moduleId":"sysdesign","cardId":"qz-rate-limiting-algorithms--r2q2","front":"Which algorithm allows bursts while enforcing a long-run average rate?","back":"Token bucket","keyPoints":["Tokens accumulate up to a capacity, so an idle client can burst; the refill rate caps the sustained average. That combination is why it is the API default."],"href":"/system-design-interview/questions/rate-limiting-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-rate-limiting-algorithms--r2q3","moduleId":"sysdesign","cardId":"qz-rate-limiting-algorithms--r2q3","front":"Fifty nodes must enforce one shared limit without adding latency to every request. Best approach?","back":"Local buckets holding a share of the quota, synced periodically with a shared store","keyPoints":["Local enforcement keeps the hot path free of network calls; periodic sync redistributes unused quota and keeps global accuracy close enough for most purposes."],"href":"/system-design-interview/questions/rate-limiting-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-rate-limiting-algorithms--r2q4","moduleId":"sysdesign","cardId":"qz-rate-limiting-algorithms--r2q4","front":"Why must a 429 response include Retry-After?","back":"Without it, clients retry immediately and turn one limited client into a retry storm","keyPoints":["Retry-After tells well-behaved clients when to come back. Omitting it means the limiter itself becomes the target of a tight retry loop."],"href":"/system-design-interview/questions/rate-limiting-algorithms#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-observability-logging-metrics-tracing--r3q1","moduleId":"sysdesign","cardId":"qz-observability-logging-metrics-tracing--r3q1","front":"Which label should never be added to a Prometheus-style metric?","back":"user_id","keyPoints":["User ID is unbounded. Cardinality multiplies across labels, so one unbounded dimension can create billions of series and take down the metrics backend."],"href":"/system-design-interview/questions/observability-logging-metrics-tracing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-observability-logging-metrics-tracing--r3q2","moduleId":"sysdesign","cardId":"qz-observability-logging-metrics-tracing--r3q2","front":"Which is a good alert?","back":"p99 checkout latency above 2 s for 5 minutes","keyPoints":["It describes user-visible impact and is actionable. The others are causes that frequently occur without any user harm."],"href":"/system-design-interview/questions/observability-logging-metrics-tracing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-observability-logging-metrics-tracing--r3q3","moduleId":"sysdesign","cardId":"qz-observability-logging-metrics-tracing--r3q3","front":"Why is tail sampling usually better than head sampling for traces?","back":"It decides after the trace completes, so you can keep 100% of errors and slow requests","keyPoints":["Head sampling discards most error traces because errors are rare. Tail sampling buffers the trace and keeps exactly the ones worth investigating."],"href":"/system-design-interview/questions/observability-logging-metrics-tracing#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-security-in-system-design--r4q1","moduleId":"sysdesign","cardId":"qz-security-in-system-design--r4q1","front":"What is the primary security weakness of a long-lived JWT?","back":"It cannot be revoked before it expires","keyPoints":["Stateless verification is exactly what prevents revocation. Short access tokens plus a revocable refresh token bound the exposure window."],"href":"/system-design-interview/questions/security-in-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-security-in-system-design--r4q2","moduleId":"sysdesign","cardId":"qz-security-in-system-design--r4q2","front":"Why use envelope encryption rather than encrypting data directly with a KMS key?","back":"Bulk encryption happens locally, and rotating the master key only re-encrypts small data keys","keyPoints":["Calling a KMS per record would be a throughput bottleneck, and rotating a key that directly encrypted terabytes would mean re-encrypting all of it."],"href":"/system-design-interview/questions/security-in-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-security-in-system-design--r4q3","moduleId":"sysdesign","cardId":"qz-security-in-system-design--r4q3","front":"An attacker gains your application's database credentials. What still protects sensitive fields?","back":"Application-level field encryption with keys the database never sees","keyPoints":["Disk and TDE decrypt transparently for any authorised connection. Only application-level encryption keeps the plaintext out of reach of a database compromise."],"href":"/system-design-interview/questions/security-in-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-security-in-system-design--r4q4","moduleId":"sysdesign","cardId":"qz-security-in-system-design--r4q4","front":"Where should a browser store an access token?","back":"An HttpOnly, Secure, SameSite cookie","keyPoints":["HttpOnly makes the token unreadable to JavaScript, so an XSS flaw cannot exfiltrate it. localStorage and sessionStorage are both fully readable by any script on the page."],"href":"/system-design-interview/questions/security-in-system-design#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-url-shortener--cs1q1","moduleId":"sysdesign","cardId":"qz-design-a-url-shortener--cs1q1","front":"How many URLs can a 7-character base62 code represent?","back":"~3.5 trillion","keyPoints":["62⁷ ≈ 3.5 × 10¹². At 100 million new URLs per day that is roughly 96 years of capacity."],"href":"/system-design-interview/questions/design-a-url-shortener#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-url-shortener--cs1q2","moduleId":"sysdesign","cardId":"qz-design-a-url-shortener--cs1q2","front":"Why would a URL shortener that sells click analytics return 302 rather than 301?","back":"302 is not cached, so every click reaches them for analytics and editable destinations","keyPoints":["A cached 301 means the browser never contacts you again - no repeat-click analytics and no way to change the destination. That trade is the crux of the question."],"href":"/system-design-interview/questions/design-a-url-shortener#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-url-shortener--cs1q3","moduleId":"sysdesign","cardId":"qz-design-a-url-shortener--cs1q3","front":"What is the main advantage of range-allocated counter IDs?","back":"One coordination call per 10,000 IDs instead of one per request","keyPoints":["Range allocation removes the per-request round trip and the single point of failure while keeping counters collision-free. Guessability is a separate problem, solved by scrambling."],"href":"/system-design-interview/questions/design-a-url-shortener#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-url-shortener--cs1q4","moduleId":"sysdesign","cardId":"qz-design-a-url-shortener--cs1q4","front":"Where should click analytics be written?","back":"To a queue, asynchronously, after the redirect is decided","keyPoints":["Analytics must never add latency to the redirect. Fire-and-forget to a queue trades occasional event loss for a fast, reliable redirect path."],"href":"/system-design-interview/questions/design-a-url-shortener#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-news-feed-system--cs2q1","moduleId":"sysdesign","cardId":"qz-design-a-news-feed-system--cs2q1","front":"Why is pure fan-out on write unworkable for a celebrity account?","back":"One post generates writes proportional to the follower count - up to 100 million","keyPoints":["Write amplification scales with followers. A 100 M-follower account posting ten times a day would generate a billion feed writes daily."],"href":"/system-design-interview/questions/design-a-news-feed-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-news-feed-system--cs2q2","moduleId":"sysdesign","cardId":"qz-design-a-news-feed-system--cs2q2","front":"Why store post IDs rather than post content in each follower's feed list?","back":"It keeps storage small and means edits and deletions are handled correctly at hydration time","keyPoints":["Content duplicated into millions of lists would be enormous and would go stale on every edit or delete. IDs plus hydration keeps one authoritative copy."],"href":"/system-design-interview/questions/design-a-news-feed-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-news-feed-system--cs2q3","moduleId":"sysdesign","cardId":"qz-design-a-news-feed-system--cs2q3","front":"A user scrolls while 12 new posts arrive. What does offset pagination cause?","back":"Duplicated posts, because the offset now points into already-seen content","keyPoints":["New rows shift everything down, so a fixed offset lands inside content already displayed. Cursor pagination over a pinned candidate set avoids it."],"href":"/system-design-interview/questions/design-a-news-feed-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-news-feed-system--cs2q4","moduleId":"sysdesign","cardId":"qz-design-a-news-feed-system--cs2q4","front":"Which optimisation typically reduces fan-out work the most?","back":"Only fanning out to users active in the last 30 days","keyPoints":["Most registered accounts are dormant. Skipping them commonly removes 70–90% of fan-out writes, and returning users get a pull-built feed."],"href":"/system-design-interview/questions/design-a-news-feed-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-chat-system--cs3q1","moduleId":"sysdesign","cardId":"qz-design-a-chat-system--cs3q1","front":"Why must message ordering use a server-assigned sequence rather than client timestamps?","back":"Device clocks are unreliable, so skewed clients would sort incorrectly and permanently","keyPoints":["A device with a fast clock would pin its messages to the top of the conversation forever. Server-assigned sequences give a single authoritative order."],"href":"/system-design-interview/questions/design-a-chat-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-chat-system--cs3q2","moduleId":"sysdesign","cardId":"qz-design-a-chat-system--cs3q2","front":"How should read state be stored for a 100,000-member group?","back":"One cursor (read_seq) per member per conversation","keyPoints":["A cursor turns per-message state into one integer per member. Unread count becomes subtraction, and marking many messages read is a single write."],"href":"/system-design-interview/questions/design-a-chat-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-chat-system--cs3q3","moduleId":"sysdesign","cardId":"qz-design-a-chat-system--cs3q3","front":"What should the messages table be partitioned by?","back":"conversation_id","keyPoints":["The dominant query is 'recent messages in this conversation'. Partitioning by conversation and clustering by descending sequence makes that a single partition read."],"href":"/system-design-interview/questions/design-a-chat-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-chat-system--cs3q4","moduleId":"sysdesign","cardId":"qz-design-a-chat-system--cs3q4","front":"When is a message considered reliably delivered?","back":"When it is durably stored and the recipient's cursor advances past it","keyPoints":["Sockets are lossy transport. Durability plus a cursor advance is the only definition that survives disconnections, crashes and multi-device sync."],"href":"/system-design-interview/questions/design-a-chat-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-notification-system--cs4q1","moduleId":"sysdesign","cardId":"qz-design-a-notification-system--cs4q1","front":"A notification arrives during a user's quiet hours. What is the best behaviour?","back":"Defer it until quiet hours end, or roll it into a digest","keyPoints":["Dropping loses information the user wanted; sending violates their preference. Deferring or digesting respects both."],"href":"/system-design-interview/questions/design-a-notification-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-notification-system--cs4q2","moduleId":"sysdesign","cardId":"qz-design-a-notification-system--cs4q2","front":"An email hard-bounces with 'mailbox does not exist'. What should happen?","back":"Add the address to a permanent suppression list and never retry","keyPoints":["It is a permanent failure. Retrying damages sender reputation and reduces deliverability for every other user."],"href":"/system-design-interview/questions/design-a-notification-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-notification-system--cs4q3","moduleId":"sysdesign","cardId":"qz-design-a-notification-system--cs4q3","front":"Why separate queues per channel?","back":"So a slow or failing provider on one channel cannot delay the others","keyPoints":["Shared queues mean a backed-up SMS provider stalls push notifications too. Separate queues isolate the failure and let each channel scale independently."],"href":"/system-design-interview/questions/design-a-notification-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-video-streaming-platform--cs5q1","moduleId":"sysdesign","cardId":"qz-design-a-video-streaming-platform--cs5q1","front":"Why split video into segments before transcoding?","back":"Segments transcode in parallel, so wall-clock time depends on fleet size rather than video length","keyPoints":["The work is embarrassingly parallel at segment granularity. Total CPU is roughly unchanged; wall-clock time collapses from an hour to minutes."],"href":"/system-design-interview/questions/design-a-video-streaming-platform#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-video-streaming-platform--cs5q2","moduleId":"sysdesign","cardId":"qz-design-a-video-streaming-platform--cs5q2","front":"Why must keyframes be aligned across renditions?","back":"So the player can switch bitrate at a segment boundary without a visible glitch","keyPoints":["A new segment must be independently decodable at the same content position in every rendition. Without alignment, switching produces a jump or a stall."],"href":"/system-design-interview/questions/design-a-video-streaming-platform#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-video-streaming-platform--cs5q3","moduleId":"sysdesign","cardId":"qz-design-a-video-streaming-platform--cs5q3","front":"What fraction of video bytes should be served from your origin?","back":"Under 1%","keyPoints":["At exabyte-per-day scale no origin can serve meaningful volume. The architecture exists to push essentially all bytes to CDN edges and ISP-embedded caches."],"href":"/system-design-interview/questions/design-a-video-streaming-platform#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-video-streaming-platform--cs5q4","moduleId":"sysdesign","cardId":"qz-design-a-video-streaming-platform--cs5q4","front":"How should a billion daily views be counted?","back":"Emit events to a stream, aggregate in windows, write periodic rollups","keyPoints":["Per-view row updates create a write-hot row on every popular video. Stream aggregation with rollups gives an eventually consistent count at a tiny fraction of the cost."],"href":"/system-design-interview/questions/design-a-video-streaming-platform#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-ride-hailing-system--cs6q1","moduleId":"sysdesign","cardId":"qz-design-a-ride-hailing-system--cs6q1","front":"Why does Uber's H3 use hexagons rather than squares?","back":"All six neighbours are equidistant, unlike a square's edge and diagonal neighbours","keyPoints":["Uniform neighbour distance simplifies radius queries and smoothing, and removes a class of boundary bugs that square grids create."],"href":"/system-design-interview/questions/design-a-ride-hailing-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-ride-hailing-system--cs6q2","moduleId":"sysdesign","cardId":"qz-design-a-ride-hailing-system--cs6q2","front":"Which correctly prevents two riders being matched to the same driver?","back":"UPDATE drivers SET status='offered' WHERE id=? AND status='available'","keyPoints":["The guard clause makes it a single atomic operation the database arbitrates. Rows-affected tells the caller whether it won, with no race window."],"href":"/system-design-interview/questions/design-a-ride-hailing-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-ride-hailing-system--cs6q3","moduleId":"sysdesign","cardId":"qz-design-a-ride-hailing-system--cs6q3","front":"Should every driver location update be written to a durable database?","back":"No - positions are ephemeral; keep live state in memory and persist only sampled trip paths","keyPoints":["A four-second-old position is already stale, so durability buys nothing. Persisting 1.25 M writes/s would be enormously expensive for no benefit."],"href":"/system-design-interview/questions/design-a-ride-hailing-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-ride-hailing-system--cs6q4","moduleId":"sysdesign","cardId":"qz-design-a-ride-hailing-system--cs6q4","front":"Why must a ride offer have a short expiry?","back":"So an unresponsive driver releases automatically and the matcher can try the next candidate","keyPoints":["Without expiry, a driver who ignores the offer leaves the trip stuck indefinitely. Automatic release keeps matching progressing."],"href":"/system-design-interview/questions/design-a-ride-hailing-system#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-web-crawler-and-search--cs7q1","moduleId":"sysdesign","cardId":"qz-design-a-web-crawler-and-search--cs7q1","front":"Why shard a search index by document rather than by term?","back":"Term sharding creates hotspots on common terms and requires shipping huge posting lists for intersection","keyPoints":["A common term's posting list contains billions of entries, making that shard a permanent hotspot, and multi-term intersection would require moving those lists across the network."],"href":"/system-design-interview/questions/design-a-web-crawler-and-search#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-web-crawler-and-search--cs7q2","moduleId":"sysdesign","cardId":"qz-design-a-web-crawler-and-search--cs7q2","front":"How should crawler politeness be enforced?","back":"One queue per host, with the scheduler releasing a host only after its delay has elapsed","keyPoints":["Structural enforcement makes it impossible to hit a host concurrently, regardless of worker count. Code-level checks eventually get bypassed."],"href":"/system-design-interview/questions/design-a-web-crawler-and-search#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-web-crawler-and-search--cs7q3","moduleId":"sysdesign","cardId":"qz-design-a-web-crawler-and-search--cs7q3","front":"What catches printer-friendly variants of the same article?","back":"SimHash near-duplicate detection","keyPoints":["The URLs differ and the bytes differ slightly, so URL and exact-hash dedup both miss it. SimHash with a small Hamming distance identifies near-identical content."],"href":"/system-design-interview/questions/design-a-web-crawler-and-search#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-design-a-web-crawler-and-search--cs7q4","moduleId":"sysdesign","cardId":"qz-design-a-web-crawler-and-search--cs7q4","front":"In a fan-out query across 100 shards, what determines total latency?","back":"The slowest shard","keyPoints":["Shards are queried in parallel, so the coordinator waits for the last one. That is why per-shard tail latency, not average, is the metric that matters."],"href":"/system-design-interview/questions/design-a-web-crawler-and-search#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-interview-framework--pb1q1","moduleId":"sysdesign","cardId":"qz-system-design-interview-framework--pb1q1","front":"By roughly what point in a 45-minute interview should the high-level design be complete?","back":"Minute 20","keyPoints":["A complete, even naive, design by minute 20 leaves 15–20 minutes for the deep dive and scaling discussion - the highest-signal part."],"href":"/system-design-interview/questions/system-design-interview-framework#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-interview-framework--pb1q2","moduleId":"sysdesign","cardId":"qz-system-design-interview-framework--pb1q2","front":"You produce an estimate of 35,000 read QPS. What must you do next?","back":"Immediately convert it into a design decision, such as needing a cache layer","keyPoints":["An estimate you never use is wasted time. The point of the number is to rule designs in or out, out loud."],"href":"/system-design-interview/questions/system-design-interview-framework#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-interview-framework--pb1q3","moduleId":"sysdesign","cardId":"qz-system-design-interview-framework--pb1q3","front":"You are genuinely stuck. What is the best move?","back":"Narrate the options you are weighing and the trade-off between them","keyPoints":["Narrating the trade-off is itself scoreable reasoning and invites a nudge. Silence gives the interviewer nothing to assess."],"href":"/system-design-interview/questions/system-design-interview-framework#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-tradeoffs-cheatsheet--pb2q1","moduleId":"sysdesign","cardId":"qz-system-design-tradeoffs-cheatsheet--pb2q1","front":"Which is the strongest way to present a design decision?","back":"“I'd use Kafka. It gives replay and multi-consumer fan-out, at the cost of operational complexity. A simple queue would do if only one consumer needed the events - but we have three teams consuming.”","keyPoints":["It names the gain, the cost, the alternative and the condition that decides between them - and ties it to a stated requirement."],"href":"/system-design-interview/questions/system-design-tradeoffs-cheatsheet#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-tradeoffs-cheatsheet--pb2q2","moduleId":"sysdesign","cardId":"qz-system-design-tradeoffs-cheatsheet--pb2q2","front":"When is choosing NOT to add a component a strong signal?","back":"When you name the complexity it would add and show the simpler path already meets the requirement","keyPoints":["Complexity is a budget. Declining to spend it, with reasoning tied to the requirement, demonstrates judgement - which is what senior levels are assessed on."],"href":"/system-design-interview/questions/system-design-tradeoffs-cheatsheet#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-tradeoffs-cheatsheet--pb2q3","moduleId":"sysdesign","cardId":"qz-system-design-tradeoffs-cheatsheet--pb2q3","front":"Denormalisation buys read speed. What is the primary cost?","back":"Every copy must be updated on write, and copies can drift","keyPoints":["Write amplification and drift are the real costs. Storage is usually the least significant part, and drift is the one that produces bugs nobody can explain six months later."],"href":"/system-design-interview/questions/system-design-tradeoffs-cheatsheet#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-interview-levels-and-evaluation--pb3q1","moduleId":"sysdesign","cardId":"qz-system-design-interview-levels-and-evaluation--pb3q1","front":"Which behaviour most reliably signals staff-level thinking?","back":"Explaining what you deliberately chose NOT to build, and why","keyPoints":["Deliberately declining complexity, with reasoning tied to a requirement, demonstrates the judgement that distinguishes staff from senior."],"href":"/system-design-interview/questions/system-design-interview-levels-and-evaluation#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-interview-levels-and-evaluation--pb3q2","moduleId":"sysdesign","cardId":"qz-system-design-interview-levels-and-evaluation--pb3q2","front":"Levelling is usually calibrated on which dimension?","back":"The weakest dimension","keyPoints":["A gap in failure analysis or trade-off reasoning caps the level regardless of how strong the architecture was - which is why breadth matters as much as depth."],"href":"/system-design-interview/questions/system-design-interview-levels-and-evaluation#quiz","moduleLabel":"System Design","latent":true},{"key":"sysdesign:qz-system-design-interview-levels-and-evaluation--pb3q3","moduleId":"sysdesign","cardId":"qz-system-design-interview-levels-and-evaluation--pb3q3","front":"Which feedback comment is about process rather than knowledge?","back":"“Needed significant prompting to reach a design”","keyPoints":["Needing prompting is a failure to drive the conversation. Most negative system design feedback is of this kind rather than a missing fact."],"href":"/system-design-interview/questions/system-design-interview-levels-and-evaluation#quiz","moduleLabel":"System Design","latent":true},{"key":"aiml:qz-linear-algebra-for-machine-learning--la-q1","moduleId":"aiml","cardId":"qz-linear-algebra-for-machine-learning--la-q1","front":"You L2-normalise every vector before inserting them into your vector index. Which statement is now true?","back":"Cosine, inner product and negative squared-Euclidean all rank identically","keyPoints":["For unit vectors, ‖a−b‖² = 2 − 2(a·b), a strictly decreasing function of the inner product, so all three metrics induce the same ordering. This is why libraries let you swap the metric freely once vectors are normalised."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-linear-algebra-for-machine-learning--la-q2","moduleId":"aiml","cardId":"qz-linear-algebra-for-machine-learning--la-q2","front":"Approximately how many FLOPs does multiplying a 32×1024 activation matrix by a 1024×4096 weight matrix take?","back":"268 million","keyPoints":["2 · B · d · h = 2 · 32 · 1024 · 4096 ≈ 2.68 × 10⁸ FLOPs. The factor of 2 accounts for one multiply plus one add per term."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-linear-algebra-for-machine-learning--la-q3","moduleId":"aiml","cardId":"qz-linear-algebra-for-machine-learning--la-q3","front":"Why does Lasso drive coefficients to exactly zero while Ridge does not?","back":"The L1 subgradient has constant magnitude λ regardless of how small the weight is","keyPoints":["L2's gradient 2λw shrinks toward zero as w shrinks, so it asymptotes. L1's λ·sign(w) never weakens, so once it dominates the data gradient the coefficient is pinned at exactly zero."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-linear-algebra-for-machine-learning--la-q4","moduleId":"aiml","cardId":"qz-linear-algebra-for-machine-learning--la-q4","front":"For y = xW + b with x of shape (B, d) and W of shape (d, h), what is the shape of ∂L/∂W?","back":"(d, h)","keyPoints":["A gradient always has the same shape as the tensor it differentiates. W is (d, h), so ∂L/∂W is (d, h) - obtained as xᵀg."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-linear-algebra-for-machine-learning--la-q5","moduleId":"aiml","cardId":"qz-linear-algebra-for-machine-learning--la-q5","front":"Why is single-token LLM decoding memory-bandwidth-bound?","back":"Because you read the full weight matrices to compute a single skinny matrix-vector product, so arithmetic intensity collapses","keyPoints":["With batch size 1 you move O(d·h) bytes of weights to do only O(d·h) FLOPs - roughly one FLOP per parameter read. The GPU spends its time waiting on HBM, not computing. Batching many requests together restores intensity."],"href":"/ai-ml-engineer-interview/questions/linear-algebra-for-machine-learning#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-probability-for-ml-interviews--pr-q1","moduleId":"aiml","cardId":"qz-probability-for-ml-interviews--pr-q1","front":"A disease affects 1 in 10,000. A 99% sensitive, 99% specific test returns positive. P(disease | positive) is closest to:","back":"1%","keyPoints":["Out of a million people, ~99 true positives and ~9,999 false positives. 99/10,098 ≈ 1%. Base rate dominates test accuracy."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-probability-for-ml-interviews--pr-q2","moduleId":"aiml","cardId":"qz-probability-for-ml-interviews--pr-q2","front":"Minimising MSE is equivalent to maximum likelihood under which noise assumption?","back":"Gaussian noise with constant variance","keyPoints":["The negative log-likelihood of a Gaussian reduces to the squared residual up to constants. Heavy-tailed residuals call for a Laplace likelihood (MAE) or Huber instead."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-probability-for-ml-interviews--pr-q3","moduleId":"aiml","cardId":"qz-probability-for-ml-interviews--pr-q3","front":"A Laplace prior on model weights under MAP estimation corresponds to:","back":"L1 regularisation","keyPoints":["−log of a Laplace density is proportional to ‖θ‖₁, giving Lasso. A Gaussian prior gives ‖θ‖₂² (ridge)."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-probability-for-ml-interviews--pr-q4","moduleId":"aiml","cardId":"qz-probability-for-ml-interviews--pr-q4","front":"In the bias–variance decomposition, 'variance' is the expectation taken over what?","back":"Resampled training sets","keyPoints":["Variance measures how much the fitted prediction at a fixed x moves as you redraw the training data. That is precisely what bagging averages away."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-probability-for-ml-interviews--pr-q5","moduleId":"aiml","cardId":"qz-probability-for-ml-interviews--pr-q5","front":"Your importance-sampling estimator has an effective sample size of 12 out of 10,000 draws. What should you conclude?","back":"The proposal poorly covers the target; the estimate is dominated by a handful of samples and is untrustworthy","keyPoints":["Low ESS means a few enormous weights carry the entire estimate - the classic signature of a proposal with thinner tails than the target. Fix the proposal or widen it; do not just add samples."],"href":"/ai-ml-engineer-interview/questions/probability-for-ml-interviews#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-statistics-and-ab-testing-for-ml--st-q1","moduleId":"aiml","cardId":"qz-statistics-and-ab-testing-for-ml--st-q1","front":"A p-value of 0.03 means:","back":"If the null were true, data this extreme would occur 3% of the time","keyPoints":["The p-value conditions on H₀ being true. It is P(data | H₀), not P(H₀ | data), and it says nothing about magnitude."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-statistics-and-ab-testing-for-ml--st-q2","moduleId":"aiml","cardId":"qz-statistics-and-ab-testing-for-ml--st-q2","front":"Baseline conversion is 5% and you want to detect a 0.5 percentage-point absolute lift at 80% power, α = 0.05. Roughly how many users per arm?","back":"≈30,000","keyPoints":["n ≈ 16·p(1−p)/δ² = 16 × 0.05 × 0.95 / (0.005)² = 0.76 / 0.000025 ≈ 30,400 per arm. Note that if you halved the MDE to 0.25pp, δ² shrinks 4× and you would need ~122,000 per arm - the quadratic penalty in action."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-statistics-and-ab-testing-for-ml--st-q3","moduleId":"aiml","cardId":"qz-statistics-and-ab-testing-for-ml--st-q3","front":"You check an A/B test daily for two weeks and stop as soon as p < 0.05. Your true false-positive rate is approximately:","back":"20%+","keyPoints":["Each look is another chance to cross the threshold. Fourteen looks pushes a nominal 5% α above 20%. Use group-sequential boundaries or always-valid confidence sequences if you need to peek."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-statistics-and-ab-testing-for-ml--st-q4","moduleId":"aiml","cardId":"qz-statistics-and-ab-testing-for-ml--st-q4","front":"Offline AUC improved 3% but the A/B test is flat. Which check should come FIRST?","back":"Validate the experiment itself - sample ratio mismatch, A/A, and online-vs-offline score parity","keyPoints":["Roughly half of these cases are pipeline or experiment problems, not model problems. SRM and training/serving skew checks are cheap and rule out the most common causes before you spend a week retraining."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-statistics-and-ab-testing-for-ml--st-q5","moduleId":"aiml","cardId":"qz-statistics-and-ab-testing-for-ml--st-q5","front":"When bootstrapping a confidence interval for per-user engagement, you should resample:","back":"Users (the randomisation unit)","keyPoints":["Events within a user are correlated. Resampling rows understates variance and produces intervals that are far too narrow. Always bootstrap at the unit of randomisation."],"href":"/ai-ml-engineer-interview/questions/statistics-and-ab-testing-for-ml#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-machine-learning-fundamentals-interview--mlf-q1","moduleId":"aiml","cardId":"qz-machine-learning-fundamentals-interview--mlf-q1","front":"Next-token prediction on raw web text is best described as:","back":"Self-supervised learning","keyPoints":["There is a label - the next token - but no human created it; it is extracted from the data itself. That is precisely self-supervised learning."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-machine-learning-fundamentals-interview--mlf-q2","moduleId":"aiml","cardId":"qz-machine-learning-fundamentals-interview--mlf-q2","front":"Training accuracy 0.98, validation 0.71, and the validation curve is still rising with more data. Best next action?","back":"Get or generate more training data","keyPoints":["A rising validation curve means you are data-limited, not capacity-limited. Regularisation trades bias for variance; more data reduces variance with no bias cost."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-machine-learning-fundamentals-interview--mlf-q3","moduleId":"aiml","cardId":"qz-machine-learning-fundamentals-interview--mlf-q3","front":"You have 5 hospital visits per patient. Using plain KFold on the rows will:","back":"Overestimate performance, because the same patient appears in both train and validation","keyPoints":["Visits from the same patient are near-duplicates. The model memorises the patient rather than learning the condition. GroupKFold on patient id is required."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-machine-learning-fundamentals-interview--mlf-q4","moduleId":"aiml","cardId":"qz-machine-learning-fundamentals-interview--mlf-q4","front":"Adversarial validation returns an AUC of 0.93 between your train and test sets. This means:","back":"Train and test come from measurably different distributions, so your CV estimate will not describe production","keyPoints":["A classifier that can tell train from test has found a feature that separates them - a date, an id, a schema change. Whatever it found will also break your model in production."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-machine-learning-fundamentals-interview--mlf-q5","moduleId":"aiml","cardId":"qz-machine-learning-fundamentals-interview--mlf-q5","front":"With only 50 labelled examples, which is more likely to perform better?","back":"Naive Bayes or another generative model with strong assumptions","keyPoints":["Ng & Jordan showed generative models reach their asymptote much faster. Strong assumptions act as a prior, which is exactly what you want when data cannot pin down the parameters."],"href":"/ai-ml-engineer-interview/questions/machine-learning-fundamentals-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-regression-and-regularization-interview--reg-q1","moduleId":"aiml","cardId":"qz-regression-and-regularization-interview--reg-q1","front":"Heteroscedastic residuals in OLS primarily invalidate:","back":"The standard errors and therefore the p-values","keyPoints":["OLS coefficients stay unbiased under heteroscedasticity; the variance estimate is what breaks. Robust (HC3) standard errors fix inference without changing the fit."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-regression-and-regularization-interview--reg-q2","moduleId":"aiml","cardId":"qz-regression-and-regularization-interview--reg-q2","front":"The gradient of binary cross-entropy with respect to the pre-activation z is:","back":"p − y","keyPoints":["The p(1−p) from the sigmoid derivative cancels against the same factor in ∂L/∂p, leaving the clean error term p − y. That cancellation is why confident mistakes still produce large gradients."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-regression-and-regularization-interview--reg-q3","moduleId":"aiml","cardId":"qz-regression-and-regularization-interview--reg-q3","front":"Two features are correlated at 0.98. Lasso will most likely:","back":"Keep one and zero the other, with the choice unstable across resamples","keyPoints":["L1's corner geometry selects a single representative from a correlated group, and which one it picks is sensitive to resampling. Elastic net's L2 term is what keeps the group together."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-regression-and-regularization-interview--reg-q4","moduleId":"aiml","cardId":"qz-regression-and-regularization-interview--reg-q4","front":"You increase batch size from 128 to 512. According to the linear scaling rule you should:","back":"Increase the learning rate by 4× and add warmup","keyPoints":["A 4× larger batch gives a lower-variance gradient, so a 4× larger step is justified. Warmup is needed because that large LR is destabilising in the first few hundred steps of an untrained network."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-regression-and-regularization-interview--reg-q5","moduleId":"aiml","cardId":"qz-regression-and-regularization-interview--reg-q5","front":"Target encoding computed once on the full training set before cross-validation:","back":"Leaks the label into every fold's validation rows, making the CV score meaningless","keyPoints":["Each validation row contributed its own label to the encoding it is scored against. The encoding must be recomputed out-of-fold inside the CV loop, which is why it belongs in a Pipeline."],"href":"/ai-ml-engineer-interview/questions/regression-and-regularization-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-trees-ensembles-and-boosting-interview--tree-q1","moduleId":"aiml","cardId":"qz-trees-ensembles-and-boosting-interview--tree-q1","front":"Gini impurity versus entropy as a splitting criterion:","back":"They select the same split ~98% of the time; Gini is cheaper because it avoids a log","keyPoints":["The two criteria are near-equivalent in practice. Depth, leaf size and pruning parameters control tree behaviour far more than the impurity measure."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-trees-ensembles-and-boosting-interview--tree-q2","moduleId":"aiml","cardId":"qz-trees-ensembles-and-boosting-interview--tree-q2","front":"Why can adding more trees hurt a gradient boosted model but not a random forest?","back":"Boosting fits each tree to the previous ensemble's residuals, so extra trees eventually fit noise; bagging averages independent trees and converges","keyPoints":["Ensemble variance under averaging decreases monotonically to ρσ². Boosting is additive and stagewise - once the signal is exhausted, further trees model noise and test error rises."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-trees-ensembles-and-boosting-interview--tree-q3","moduleId":"aiml","cardId":"qz-trees-ensembles-and-boosting-interview--tree-q3","front":"In LightGBM, leaving `max_depth = -1` with `num_leaves = 255` on a 5,000-row dataset will most likely:","back":"Overfit badly, because leaf-wise growth builds very deep unbalanced trees","keyPoints":["Leaf-wise growth always splits the highest-gain leaf anywhere in the tree. Without a depth cap and with a small dataset, it isolates tiny groups of rows. Keep num_leaves < 2^max_depth and raise min_data_in_leaf."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-trees-ensembles-and-boosting-interview--tree-q4","moduleId":"aiml","cardId":"qz-trees-ensembles-and-boosting-interview--tree-q4","front":"A random row-id column ranks first in `feature_importances_`. This happens because:","back":"Impurity importance favours high-cardinality features, which offer many candidate split points, and it is computed on training data","keyPoints":["More unique values means more chances to find a split that reduces training impurity by luck. Permutation importance on a holdout set exposes it immediately as worthless."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-trees-ensembles-and-boosting-interview--tree-q5","moduleId":"aiml","cardId":"qz-trees-ensembles-and-boosting-interview--tree-q5","front":"Best practice for tuning `learning_rate` and `n_estimators` in boosting:","back":"Fix a low learning rate, set n_estimators very high, and let early stopping choose the count","keyPoints":["The two trade off almost perfectly, so searching both wastes budget. A low η with early stopping reliably produces the best-generalising ensemble."],"href":"/ai-ml-engineer-interview/questions/trees-ensembles-and-boosting-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-evaluation-metrics-interview-questions--met-q1","moduleId":"aiml","cardId":"qz-evaluation-metrics-interview-questions--met-q1","front":"A model has 0.95 ROC-AUC and 0.08 PR-AUC on a 1:1000 problem. This means:","back":"The model ranks well overall, but acting on its top predictions means most flags are false positives","keyPoints":["ROC-AUC's FPR denominator is dominated by the enormous negative class, so it stays high. PR-AUC exposes what an analyst working the queue will actually see. Both numbers are correct; only PR-AUC is actionable."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-evaluation-metrics-interview-questions--met-q2","moduleId":"aiml","cardId":"qz-evaluation-metrics-interview-questions--met-q2","front":"False negatives cost 100× false positives. Your decision threshold should be:","back":"Well below 0.5, so you catch more positives at the cost of more false alarms","keyPoints":["Cost-optimal thresholds move toward the expensive error. With a 100:1 asymmetry the optimal threshold is often below 0.05. Class weights are complementary but do not replace choosing an operating point."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-evaluation-metrics-interview-questions--met-q3","moduleId":"aiml","cardId":"qz-evaluation-metrics-interview-questions--met-q3","front":"A model outputs 0.9 for a group of cases in which only 60% are actually positive. This is:","back":"Overconfidence - a calibration problem that AUC will not detect","keyPoints":["Ranking can be perfect while the probability scale is wrong. Fix with Platt/isotonic/temperature scaling on held-out data, and monitor ECE - calibration drifts before discrimination does."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-evaluation-metrics-interview-questions--met-q4","moduleId":"aiml","cardId":"qz-evaluation-metrics-interview-questions--met-q4","front":"On right-skewed demand data, optimising MAE instead of RMSE causes the model to predict:","back":"The conditional median, which is substantially lower","keyPoints":["MAE is minimised by the median, RMSE by the mean. On skewed demand these differ a lot, and neither is right for inventory - that needs a quantile via pinball loss."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-evaluation-metrics-interview-questions--met-q5","moduleId":"aiml","cardId":"qz-evaluation-metrics-interview-questions--met-q5","front":"NDCG@10 uses a logarithmic position discount because:","back":"Click-through probability decays roughly logarithmically with rank, so lower positions should count less","keyPoints":["The discount encodes observed user behaviour. Paired with the exponential gain 2^rel − 1, it rewards putting the single best item at the very top - which is what actually drives user satisfaction."],"href":"/ai-ml-engineer-interview/questions/evaluation-metrics-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-feature-engineering-and-imbalanced-data--fe-q1","moduleId":"aiml","cardId":"qz-feature-engineering-and-imbalanced-data--fe-q1","front":"For churn prediction, which feature family typically carries the most signal?","back":"Trend/ratio features comparing recent behaviour to the user's own baseline","keyPoints":["Churn is about change. A heavy user dropping to half their normal activity is a much stronger signal than an absolute level, which mostly encodes what kind of customer they always were."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-feature-engineering-and-imbalanced-data--fe-q2","moduleId":"aiml","cardId":"qz-feature-engineering-and-imbalanced-data--fe-q2","front":"Income is missing 30% of the time, and those rows have a 4× higher default rate. You should:","back":"Keep a missingness indicator - the missingness is MNAR and carries strong signal","keyPoints":["A 4× lift means the fact of missingness is one of your strongest features. Imputing without an indicator throws that away and tells the model these applicants are average."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-feature-engineering-and-imbalanced-data--fe-q3","moduleId":"aiml","cardId":"qz-feature-engineering-and-imbalanced-data--fe-q3","front":"On a 1:1000 imbalance, the FIRST thing you should change is:","back":"The evaluation metric and the decision threshold","keyPoints":["Most 'imbalance problems' are metric-and-threshold problems. Fixing those costs nothing and preserves calibration; resampling damages calibration and often does not improve PR-AUC at all."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-feature-engineering-and-imbalanced-data--fe-q4","moduleId":"aiml","cardId":"qz-feature-engineering-and-imbalanced-data--fe-q4","front":"Silhouette score peaks at k=4 but stability (ARI across resamples) collapses at k=5. You should choose:","back":"k=4, because the structure is both well-separated and reproducible","keyPoints":["Agreement between the two criteria at k=4 with a stability cliff right after is strong evidence of four genuine clusters. The k=5 solution is splitting a real cluster on noise."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-feature-engineering-and-imbalanced-data--fe-q5","moduleId":"aiml","cardId":"qz-feature-engineering-and-imbalanced-data--fe-q5","front":"In an anomaly detection system, reviewing a random sample of UNFLAGGED traffic is necessary because:","back":"Without it you can never estimate recall or discover anomaly types your detector misses","keyPoints":["If you only ever label what you flagged, you learn nothing about your misses. The random unflagged sample is the only source of unbiased recall estimates and of novel anomaly patterns."],"href":"/ai-ml-engineer-interview/questions/feature-engineering-and-imbalanced-data#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-neural-networks-and-backpropagation--dl-q1","moduleId":"aiml","cardId":"qz-neural-networks-and-backpropagation--dl-q1","front":"For softmax + cross-entropy, ∂L/∂z (logits) equals:","back":"p − y","keyPoints":["The softmax Jacobian collapses against the cross-entropy derivative, leaving the pure error term p − y. This cancellation is why frameworks fuse the two operations."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-neural-networks-and-backpropagation--dl-q2","moduleId":"aiml","cardId":"qz-neural-networks-and-backpropagation--dl-q2","front":"Sigmoid causes vanishing gradients in deep networks because:","back":"Its maximum derivative is 0.25, so gradients shrink by at least 4× per layer","keyPoints":["σ'(x) = σ(x)(1−σ(x)) peaks at 0.25. Through 20 layers the gradient is multiplied by at most 0.25²⁰ ≈ 10⁻¹². Not being zero-centred is a real but secondary problem."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-neural-networks-and-backpropagation--dl-q3","moduleId":"aiml","cardId":"qz-neural-networks-and-backpropagation--dl-q3","front":"He initialisation uses variance 2/fan_in rather than 1/fan_in because:","back":"ReLU zeroes roughly half its inputs, halving the propagated variance","keyPoints":["The factor of 2 exactly offsets ReLU discarding the negative half of the distribution, keeping activation variance stable through depth."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-neural-networks-and-backpropagation--dl-q4","moduleId":"aiml","cardId":"qz-neural-networks-and-backpropagation--dl-q4","front":"Transformers use LayerNorm rather than BatchNorm mainly because:","back":"LayerNorm is batch-independent, which variable-length sequences and single-stream autoregressive decoding require","keyPoints":["At decode time each stream produces one token at a time - there is no batch to compute statistics over. LayerNorm normalises within a token, so train and inference behave identically."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-neural-networks-and-backpropagation--dl-q5","moduleId":"aiml","cardId":"qz-neural-networks-and-backpropagation--dl-q5","front":"The original ResNet paper observed that a 56-layer plain network had higher TRAINING error than a 20-layer one. This shows:","back":"An optimisation failure - deeper networks could not even learn the identity mapping","keyPoints":["Higher training error rules out overfitting. Skip connections make the identity the default behaviour (learn F = 0), turning a hard optimisation problem into an easy one."],"href":"/ai-ml-engineer-interview/questions/neural-networks-and-backpropagation#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-training-optimization-and-regularization--opt-q1","moduleId":"aiml","cardId":"qz-training-optimization-and-regularization--opt-q1","front":"AdamW differs from Adam + L2 regularisation because:","back":"It applies weight decay directly to the update instead of the gradient, so decay is not divided by √v","keyPoints":["Under Adam, L2 added to the gradient flows through the adaptive denominator, so parameters with large gradients get the least decay - the opposite of what you want. AdamW decouples them."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-training-optimization-and-regularization--opt-q2","moduleId":"aiml","cardId":"qz-training-optimization-and-regularization--opt-q2","front":"Learning-rate warmup is needed primarily because:","back":"Adam's second-moment estimate is based on very few samples early on, producing huge and damaging updates","keyPoints":["At step 1, v̂ is a single-sample estimate, so m̂/√v̂ = ±1 and every parameter takes a full-size step of η along one noisy gradient. v̂ stays high-variance for hundreds of steps, and a randomly-initialised network may never recover from those early updates."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-training-optimization-and-regularization--opt-q3","moduleId":"aiml","cardId":"qz-training-optimization-and-regularization--opt-q3","front":"Your fp16 training NaNs but the identical run in fp32 is fine. The most likely cause is:","back":"Numerical overflow - fp16's maximum representable value is 65,504","keyPoints":["Attention logits and normalisation sums routinely exceed 65,504 in large models. bf16 has fp32's exponent range and eliminates this failure mode entirely."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-training-optimization-and-regularization--opt-q4","moduleId":"aiml","cardId":"qz-training-optimization-and-regularization--opt-q4","front":"PyTorch's inverted dropout scales activations by 1/(1−p) during TRAINING because:","back":"It keeps the expected activation constant so inference needs no rescaling at all","keyPoints":["Scaling at train time means the inference path is a plain forward pass with zero dropout overhead - important because inference runs far more often than training."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-training-optimization-and-regularization--opt-q5","moduleId":"aiml","cardId":"qz-training-optimization-and-regularization--opt-q5","front":"Training a 7B-parameter model with AdamW in mixed precision requires roughly:","back":"About 112 GB, because fp32 master weights plus Adam's m and v dominate","keyPoints":["bf16 weights (14) + fp32 master (28) + m (28) + v (28) + gradients (14–28) ≈ 112–126 GB. Optimiser state, not the model, is what forces sharding."],"href":"/ai-ml-engineer-interview/questions/training-optimization-and-regularization#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-transformers-and-attention-explained--tr-q1","moduleId":"aiml","cardId":"qz-transformers-and-attention-explained--tr-q1","front":"Attention divides by √d_k because:","back":"Var(q·k) = d_k, so unscaled logits grow with dimension and saturate the softmax, killing gradients","keyPoints":["With unit-variance components, the dot product has variance d_k. At d_k = 512 logits span ±22, softmax becomes a hard argmax, and its gradient p(δ−p) goes to zero."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-transformers-and-attention-explained--tr-q2","moduleId":"aiml","cardId":"qz-transformers-and-attention-explained--tr-q2","front":"Grouped-query attention (GQA) primarily exists to:","back":"Shrink the KV cache - the dominant memory cost in long-context serving","keyPoints":["At batch 32 and 8k context, a 70B model's MHA KV cache is ~687 GB - nearly five times the weights. GQA with 8 KV heads cuts that 8× at near-identical quality."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-transformers-and-attention-explained--tr-q3","moduleId":"aiml","cardId":"qz-transformers-and-attention-explained--tr-q3","front":"RoPE's defining property is that:","back":"The rotated dot product ⟨R_m q, R_n k⟩ depends only on the relative offset m − n","keyPoints":["Rotating Q and K by position-proportional angles makes their inner product a function of m − n alone, giving relative-position awareness without a separate bias term."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-transformers-and-attention-explained--tr-q4","moduleId":"aiml","cardId":"qz-transformers-and-attention-explained--tr-q4","front":"FlashAttention achieves its speedup by:","back":"Tiling into SRAM with online softmax so the n×n matrix never touches HBM - same result, far less memory traffic","keyPoints":["It is exact and does the same FLOPs. Attention was memory-bandwidth-bound, so eliminating the n² HBM round-trips gives 2–4× throughput."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-transformers-and-attention-explained--tr-q5","moduleId":"aiml","cardId":"qz-transformers-and-attention-explained--tr-q5","front":"A rough estimate of the FLOPs to train a model with N parameters on T tokens is:","back":"6NT","keyPoints":["Forward is ~2N per token; backward is about twice that. 6NT is the standard estimate used for compute-budget planning and Chinchilla-style scaling arguments."],"href":"/ai-ml-engineer-interview/questions/transformers-and-attention-explained#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-fundamentals-interview-questions--llm-q1","moduleId":"aiml","cardId":"qz-llm-fundamentals-interview-questions--llm-q1","front":"Compared to English, Hindi text typically costs:","back":"Several times more tokens, because the script is underrepresented in the BPE merge corpus","keyPoints":["BPE merges are learned from a corpus dominated by English. Scripts with little representation fall back to near-byte-level encoding, sometimes ~1 character per token - a real cost and fairness issue."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-fundamentals-interview-questions--llm-q2","moduleId":"aiml","cardId":"qz-llm-fundamentals-interview-questions--llm-q2","front":"The main reason decoder-only models displaced BERT-style encoders is:","back":"CLM produces a training signal at every position and gives one text-in/text-out interface for all tasks","keyPoints":["MLM only supervises ~15% of positions. CLM supervises all of them and unifies every task under generation, which is what enabled in-context learning and a single deployed model."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-fundamentals-interview-questions--llm-q3","moduleId":"aiml","cardId":"qz-llm-fundamentals-interview-questions--llm-q3","front":"The Chinchilla result says that for compute-optimal training you should use roughly:","back":"20 tokens per parameter","keyPoints":["Chinchilla found N and D should scale roughly equally, giving ≈20 tokens per parameter. Production models deliberately exceed this because inference cost dominates lifetime cost."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-fundamentals-interview-questions--llm-q4","moduleId":"aiml","cardId":"qz-llm-fundamentals-interview-questions--llm-q4","front":"'Lost in the middle' means:","back":"Accuracy on information placed mid-context is lower than at the start or end","keyPoints":["Retrieval accuracy is U-shaped in position. Put critical instructions and evidence at the beginning or end, and validate with needle-in-a-haystack tests at multiple depths."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-fundamentals-interview-questions--llm-q5","moduleId":"aiml","cardId":"qz-llm-fundamentals-interview-questions--llm-q5","front":"The highest-impact change when fine-tuning an embedding model is usually:","back":"Mining hard negatives - topically similar but non-relevant documents","keyPoints":["Random negatives are trivially separable and teach little. Hard negatives force the model to learn the fine distinctions that actually determine retrieval quality."],"href":"/ai-ml-engineer-interview/questions/llm-fundamentals-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-fine-tuning-lora-and-rlhf--ft-q1","moduleId":"aiml","cardId":"qz-fine-tuning-lora-and-rlhf--ft-q1","front":"A stakeholder wants to fine-tune so the model 'knows' their documentation. The correct response is:","back":"Explain that fine-tuning teaches behaviour, not facts - RAG is the right tool for knowledge","keyPoints":["Fine-tuned facts have no provenance, go stale, and can increase hallucination. RAG is updatable, citable, and far cheaper to iterate on."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-fine-tuning-lora-and-rlhf--ft-q2","moduleId":"aiml","cardId":"qz-fine-tuning-lora-and-rlhf--ft-q2","front":"In LoRA, matrix B is initialised to zero because:","back":"It makes ΔW = BA equal zero at step 0, so training starts exactly at the pre-trained model","keyPoints":["If both A and B were random, the adapter would immediately perturb a well-trained model. Zero-initialising B guarantees a clean starting point; A must be random so gradients to B are non-zero."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-fine-tuning-lora-and-rlhf--ft-q3","moduleId":"aiml","cardId":"qz-fine-tuning-lora-and-rlhf--ft-q3","front":"DPO eliminates the need for a reward model because:","back":"The closed-form optimal policy lets you express the reward via the policy, and the partition function cancels between chosen and rejected","keyPoints":["Substituting the implicit reward into the Bradley–Terry model cancels Z(x) because it is identical for both responses to the same prompt. What remains is a simple pairwise logistic loss."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-fine-tuning-lora-and-rlhf--ft-q4","moduleId":"aiml","cardId":"qz-fine-tuning-lora-and-rlhf--ft-q4","front":"The most effective single fix for catastrophic forgetting during fine-tuning is:","back":"Mix 15–30% general instruction data into the fine-tuning set","keyPoints":["Forgetting occurs because the loss contains no term for general capability. Mixing general data puts it back in the objective; in practice ~15% costs about one point of domain accuracy and recovers most of the general benchmark."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-fine-tuning-lora-and-rlhf--ft-q5","moduleId":"aiml","cardId":"qz-fine-tuning-lora-and-rlhf--ft-q5","front":"The LIMA paper demonstrated that:","back":"1,000 carefully curated examples can match or beat 52,000 auto-generated ones for instruction tuning","keyPoints":["SFT mostly teaches format and register rather than knowledge, and those are learnable from a small, diverse, consistent set. Curation beats volume."],"href":"/ai-ml-engineer-interview/questions/fine-tuning-lora-and-rlhf#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-inference-decoding-and-serving--inf-q1","moduleId":"aiml","cardId":"qz-llm-inference-decoding-and-serving--inf-q1","front":"Top-p (nucleus) sampling is usually preferred over top-k because:","back":"It adapts the candidate set to the model's confidence, keeping fewer tokens when certain and more when uncertain","keyPoints":["Top-k is a fixed cut. When the model is confident, top-k=50 admits 49 junk tokens; top-p keeps only what is needed to reach the probability mass."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-inference-decoding-and-serving--inf-q2","moduleId":"aiml","cardId":"qz-llm-inference-decoding-and-serving--inf-q2","front":"PagedAttention improves throughput primarily by:","back":"Storing the KV cache in fixed-size blocks, cutting memory fragmentation from 60–80% to under 4%","keyPoints":["Pre-allocating contiguous KV to max_seq_len wastes most of the reservation. Block-based allocation with a page table frees that memory for more concurrent sequences."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-inference-decoding-and-serving--inf-q3","moduleId":"aiml","cardId":"qz-llm-inference-decoding-and-serving--inf-q3","front":"In 4-bit quantisation, per-group scales (e.g. group size 128) are essential because:","back":"A few outlier channels would otherwise dominate a per-tensor scale and destroy precision for all ordinary weights","keyPoints":["Activation and weight outliers are 10–100× typical magnitude. A single tensor-wide scale is set by the outlier, leaving ordinary weights with almost no effective precision."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-inference-decoding-and-serving--inf-q4","moduleId":"aiml","cardId":"qz-llm-inference-decoding-and-serving--inf-q4","front":"Speculative decoding produces output that is:","back":"Exactly the target model's distribution, guaranteed by the modified rejection-sampling rule","keyPoints":["Accepting with probability min(1, p/q) and resampling from norm(max(0, p−q)) on rejection reproduces p exactly. This is provable and verifiable empirically."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-llm-inference-decoding-and-serving--inf-q5","moduleId":"aiml","cardId":"qz-llm-inference-decoding-and-serving--inf-q5","front":"The highest-ROI change for perceived latency in an LLM chat product is usually:","back":"Streaming tokens as they are generated","keyPoints":["Streaming makes nothing faster but drops perceived latency from seconds to a few hundred milliseconds, because the user starts reading immediately. It is cheap and should be shipped before any model change."],"href":"/ai-ml-engineer-interview/questions/llm-inference-decoding-and-serving#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-rag-architecture-interview-questions--rag-q1","moduleId":"aiml","cardId":"qz-rag-architecture-interview-questions--rag-q1","front":"Access control in a RAG system should be enforced:","back":"Inside the index query as a pre-filter, so inaccessible vectors are never searched","keyPoints":["Post-filtering can return zero results for restricted users and risks leaking text into the prompt if the filter has a bug. Every serious vector database supports metadata pre-filtering - use it."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-rag-architecture-interview-questions--rag-q2","moduleId":"aiml","cardId":"qz-rag-architecture-interview-questions--rag-q2","front":"Chunks of 2000 tokens typically hurt retrieval because:","back":"The embedding averages over many topics, diluting the one relevant passage","keyPoints":["A single vector must summarise the whole chunk. A relevant sentence surrounded by 1900 unrelated tokens produces a vector that no longer sits close to the query."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-rag-architecture-interview-questions--rag-q3","moduleId":"aiml","cardId":"qz-rag-architecture-interview-questions--rag-q3","front":"For 100M vectors at 768 dimensions, plain HNSW is usually impractical because:","back":"It would need roughly 330 GB of RAM including graph links","keyPoints":["Raw fp32 vectors alone are ~307 GB, plus HNSW's graph edges. IVF-PQ compresses to ~10 GB at m=96, which is why it is standard at this scale."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-rag-architecture-interview-questions--rag-q4","moduleId":"aiml","cardId":"qz-rag-architecture-interview-questions--rag-q4","front":"Hybrid search improves recall, while reranking improves:","back":"Precision at the top of the list - getting the right chunk to position 1","keyPoints":["They solve different problems. If recall@50 is already high, reranking is the lever; if recall@50 is low, no reranker can help because the answer is not in the candidate set."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-rag-architecture-interview-questions--rag-q5","moduleId":"aiml","cardId":"qz-rag-architecture-interview-questions--rag-q5","front":"A RAG gold evaluation set should include unanswerable questions because:","back":"They are the only way to measure whether the system correctly refuses instead of confabulating","keyPoints":["Confident answers to questions the corpus cannot support are the failure users complain about most. Without unanswerable cases in the eval set, that behaviour is completely unmeasured."],"href":"/ai-ml-engineer-interview/questions/rag-architecture-interview-questions#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-agents-and-tool-calling--ag-q1","moduleId":"aiml","cardId":"qz-ai-agents-and-tool-calling--ag-q1","front":"When a tool call fails inside an agent loop, you should:","back":"Return the error to the model as an observation so it can self-correct","keyPoints":["A well-worded error ('expected YYYY-MM-DD') lets the agent fix its arguments on the next step. Exceptions end runs that could have recovered."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-agents-and-tool-calling--ag-q2","moduleId":"aiml","cardId":"qz-ai-agents-and-tool-calling--ag-q2","front":"A good tool description should include:","back":"What it does, when to use it, when NOT to use it, and what it returns","keyPoints":["The description is how the model chooses. Explicit negative guidance ('do NOT use this for refunds') is what prevents confusion between overlapping tools."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-agents-and-tool-calling--ag-q3","moduleId":"aiml","cardId":"qz-ai-agents-and-tool-calling--ag-q3","front":"For a long-running agent task, an explicit structured plan object beats implicit chain-of-thought because it is:","back":"Compact, inspectable, resumable after a crash, and verifiable","keyPoints":["Chain-of-thought lives in an unbounded transcript that gets truncated arbitrarily. A plan artefact survives compaction, can be reviewed mid-run, and lets you resume."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-agents-and-tool-calling--ag-q4","moduleId":"aiml","cardId":"qz-ai-agents-and-tool-calling--ag-q4","front":"The most effective defence against prompt injection is:","back":"Least privilege - ensuring the harmful capability is not reachable in that context","keyPoints":["Prompt-level defences are bypassable because instructions and data share one token stream. Assume the injection succeeds and bound what it can do."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-agents-and-tool-calling--ag-q5","moduleId":"aiml","cardId":"qz-ai-agents-and-tool-calling--ag-q5","front":"If each agent in a 4-stage pipeline is 90% reliable, end-to-end reliability is roughly:","back":"66%","keyPoints":["0.9⁴ ≈ 0.656. Error rates compound multiplicatively, which is why adding agents without per-stage validation makes systems less reliable, not more."],"href":"/ai-ml-engineer-interview/questions/ai-agents-and-tool-calling#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-deployment-and-serving-patterns--mlo-q1","moduleId":"aiml","cardId":"qz-ml-deployment-and-serving-patterns--mlo-q1","front":"With a 200 ms p99 latency budget, feature fetching takes 40 ms and other overhead 55 ms. Your model has:","back":"About 105 ms","keyPoints":["200 − 40 − 55 = 105 ms. Feature I/O is frequently larger than inference itself, which is why optimising the model first is often the wrong move."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-deployment-and-serving-patterns--mlo-q2","moduleId":"aiml","cardId":"qz-ml-deployment-and-serving-patterns--mlo-q2","front":"The single most effective practice for detecting training/serving skew is:","back":"Logging the exact features used at serving time and re-scoring them offline","keyPoints":["Re-scoring logged serving features with the training pipeline catches implementation, freshness and source skew simultaneously, and pinpoints the offending feature."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-deployment-and-serving-patterns--mlo-q3","moduleId":"aiml","cardId":"qz-ml-deployment-and-serving-patterns--mlo-q3","front":"Shadow deployment is valuable primarily because it:","back":"Reveals latency, error and skew problems on real traffic at zero user risk","keyPoints":["Shadow answers 'does it break?' - including latency regressions offline evaluation cannot see. Only a powered A/B answers 'is it better?'."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-deployment-and-serving-patterns--mlo-q4","moduleId":"aiml","cardId":"qz-ml-deployment-and-serving-patterns--mlo-q4","front":"A directional expectation test asserts that:","back":"Changing a feature in a known way moves the prediction in the expected direction","keyPoints":["You cannot assert exact outputs for a model, so you assert properties. 'More failed payments must increase churn risk' catches regressions an aggregate AUC threshold hides."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-deployment-and-serving-patterns--mlo-q5","moduleId":"aiml","cardId":"qz-ml-deployment-and-serving-patterns--mlo-q5","front":"The hardest artefact to version for reproducibility is usually:","back":"The training data, because tables change under you via late arrivals, corrections and deletions","keyPoints":["Git handles code and lockfiles handle environments. Data requires immutable snapshots or a table format with AS OF time travel - otherwise the same query returns different rows every day."],"href":"/ai-ml-engineer-interview/questions/ml-deployment-and-serving-patterns#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-model-monitoring-and-drift-detection--mon-q1","moduleId":"aiml","cardId":"qz-model-monitoring-and-drift-detection--mon-q1","front":"Concept drift is the most dangerous form because:","back":"Input distributions look completely normal, so feature-drift monitoring stays green while the model is systematically wrong","keyPoints":["P(Y|X) changes while P(X) stays put. Every drift dashboard is green. Adversarial domains guarantee this because attackers actively invalidate the learned relationship."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-model-monitoring-and-drift-detection--mon-q2","moduleId":"aiml","cardId":"qz-model-monitoring-and-drift-detection--mon-q2","front":"At 10 million rows/day, alerting on KS-test p-values is a bad idea because:","back":"Statistical significance is trivially achieved, so nearly every feature alerts every day","keyPoints":["Huge samples make tiny differences significant. PSI measures effect size and is the operational alert; p-values are a supporting signal at most."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-model-monitoring-and-drift-detection--mon-q3","moduleId":"aiml","cardId":"qz-model-monitoring-and-drift-detection--mon-q3","front":"An automated retraining pipeline should:","back":"Retrain automatically but gate promotion behind the same offline evaluation, behavioural tests and canary as a manual deploy","keyPoints":["Automated training plus automated deployment will happily ship a model trained on a corrupted batch. Automate the work; keep the promotion gated."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-model-monitoring-and-drift-detection--mon-q4","moduleId":"aiml","cardId":"qz-model-monitoring-and-drift-detection--mon-q4","front":"Predictions shifted sharply at 03:00. Your FIRST diagnostic step should be:","back":"Re-score a frozen golden batch to determine whether the model or the inputs changed","keyPoints":["Golden-batch re-scoring bisects the problem in seconds. Matching scores means the model is fine and something upstream changed - which is the majority of ML incidents."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-model-monitoring-and-drift-detection--mon-q5","moduleId":"aiml","cardId":"qz-model-monitoring-and-drift-detection--mon-q5","front":"In a cascade with an 88% early-exit rate, a 2 ms fast model and a 180 ms slow model, average latency is roughly:","back":"23 ms","keyPoints":["2 + 0.12 × 180 ≈ 23 ms. Cascades give large average-latency and cost reductions while leaving accuracy on the escalated tail unchanged."],"href":"/ai-ml-engineer-interview/questions/model-monitoring-and-drift-detection#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-framework--sd-q1","moduleId":"aiml","cardId":"qz-ml-system-design-framework--sd-q1","front":"In an ML system design interview, the first 5–8 minutes should be spent:","back":"Clarifying requirements, scale, latency budget and available data","keyPoints":["Every later decision depends on scale, latency and data availability. Candidates who skip clarification design for the wrong problem and cannot recover in 45 minutes."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-framework--sd-q2","moduleId":"aiml","cardId":"qz-ml-system-design-framework--sd-q2","front":"Why does a recommender use a multi-stage funnel instead of one model?","back":"You cannot score 50M items per request, so a cheap model narrows the field and an expensive one ranks the survivors","keyPoints":["The funnel exists to spend compute where it changes the outcome. Two-tower retrieval trades away user×item interactions in exchange for precomputed embeddings and 8 ms ANN search."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-framework--sd-q3","moduleId":"aiml","cardId":"qz-ml-system-design-framework--sd-q3","front":"In fraud detection, a random exploration bucket is necessary because:","back":"You never observe outcomes for blocked transactions, so without exploration the training data collapses onto the model's own decisions","keyPoints":["Blocked transactions are censored. Without a small value-capped sample of approvals in the block region, the model becomes progressively blind at its own decision boundary."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-framework--sd-q4","moduleId":"aiml","cardId":"qz-ml-system-design-framework--sd-q4","front":"For a support assistant, the most important design decision is usually:","back":"When the assistant escalates to a human","keyPoints":["A confidently wrong policy answer creates a ticket and destroys trust simultaneously. Defining escalation criteria first bounds the damage and makes everything else a tuning problem."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-framework--sd-q5","moduleId":"aiml","cardId":"qz-ml-system-design-framework--sd-q5","front":"Optimising CTR alone in a recommender typically causes:","back":"Clickbait promotion and degraded long-term satisfaction","keyPoints":["CTR rewards the click, not the outcome. Multi-task ranking with watch-fraction and negative-feedback heads, plus diversity and integrity guardrails, is the standard correction."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-framework#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-search-and-ranking--sd2-q1","moduleId":"aiml","cardId":"qz-ml-system-design-search-and-ranking--sd2-q1","front":"In search ranking, including position as a feature and serving it causes:","back":"The model to reproduce the existing ranker instead of learning true relevance","keyPoints":["Clicks correlate with position regardless of relevance. Use an examination model where position feeds only the propensity term and is dropped at serving, or apply inverse propensity weighting."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-search-and-ranking--sd2-q2","moduleId":"aiml","cardId":"qz-ml-system-design-search-and-ranking--sd2-q2","front":"In a feed value model, why are negative signals like 'hide' and 'report' weighted so heavily?","back":"One explicit dissatisfaction signal indicates far more user harm than several weak positive signals indicate benefit","keyPoints":["The asymmetry is deliberate: engagement optimisation without heavily weighted negative signals drifts toward content people engage with but dislike, which erodes retention."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-search-and-ranking--sd2-q3","moduleId":"aiml","cardId":"qz-ml-system-design-search-and-ranking--sd2-q3","front":"Calibration matters more in ads CTR prediction than in most ranking problems because:","back":"The predicted probability directly determines auction pricing, so miscalibration means advertisers are systematically mischarged","keyPoints":["eCPM = bid × pCTR. A 20% over-prediction is a 20% pricing error. It is a billing-accuracy issue, not a modelling nicety."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-search-and-ranking--sd2-q4","moduleId":"aiml","cardId":"qz-ml-system-design-search-and-ranking--sd2-q4","front":"In content moderation, why should CSAM use a much lower auto-action threshold than hate speech?","back":"The cost of a false negative is orders of magnitude higher, while false positives are absorbed by human review","keyPoints":["Error costs differ enormously by policy. Maximise recall where a miss is catastrophic; protect precision where over-removal harms legitimate speech."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-system-design-search-and-ranking--sd2-q5","moduleId":"aiml","cardId":"qz-ml-system-design-search-and-ranking--sd2-q5","front":"At 100× scale, the component that most often breaks first is:","back":"Training data volume and human-in-the-loop capacity","keyPoints":["Stateless serving scales with replicas. 90 billion training rows and thousands of required reviewers do not - those need sampling, prioritisation and automation changes, not more machines."],"href":"/ai-ml-engineer-interview/questions/ml-system-design-search-and-ranking#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-numpy-pandas-ml-coding-interview--cd-q1","moduleId":"aiml","cardId":"qz-numpy-pandas-ml-coding-interview--cd-q1","front":"Why compute pairwise distances with ‖a‖² + ‖b‖² − 2a·b rather than broadcasting the difference?","back":"Broadcasting allocates an (n, m, d) intermediate that explodes in memory; the identity needs only one matmul","keyPoints":["At n=m=10,000 and d=128, the difference tensor is ~100 GB. The matmul form allocates only (n, m). Remember to clamp with np.maximum(d2, 0) before sqrt."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-numpy-pandas-ml-coding-interview--cd-q2","moduleId":"aiml","cardId":"qz-numpy-pandas-ml-coding-interview--cd-q2","front":"The most common bug in a from-scratch k-means implementation is:","back":"Not handling empty clusters, which produces NaN centroids","keyPoints":["If a cluster loses all its points, the mean of an empty set is NaN and it poisons everything downstream. Reseed the empty centroid at the point furthest from its current centroid."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-numpy-pandas-ml-coding-interview--cd-q3","moduleId":"aiml","cardId":"qz-numpy-pandas-ml-coding-interview--cd-q3","front":"Computing log-loss as `-y*log(p) - (1-y)*log(1-p)` is risky because:","back":"p can underflow to exactly 0 or 1, giving log(0) = -inf","keyPoints":["Work from logits instead: logaddexp(0, z) − y·z is mathematically identical and never evaluates log(0). Pair it with a sign-branched sigmoid to avoid exp overflow."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-numpy-pandas-ml-coding-interview--cd-q4","moduleId":"aiml","cardId":"qz-numpy-pandas-ml-coding-interview--cd-q4","front":"Replacing `df.apply(fn, axis=1)` with a vectorised `np.where` typically gives:","back":"A 100–500× speedup","keyPoints":["`apply(axis=1)` makes one Python function call per row. Vectorised operations run in C over the whole array. This is usually the single largest pandas optimisation available."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-numpy-pandas-ml-coding-interview--cd-q5","moduleId":"aiml","cardId":"qz-numpy-pandas-ml-coding-interview--cd-q5","front":"With a KV cache during generation, the causal mask needs care because:","back":"The query length is 1 while the key length is the full history, so a naive tril masks almost everything","keyPoints":["With T_q = 1 and T_k = 501, the mask must allow all cached positions. Use `diagonal=Tk-Tq` or skip masking entirely when the query length is 1."],"href":"/ai-ml-engineer-interview/questions/numpy-pandas-ml-coding-interview#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-pytorch-and-ml-engineering-coding--pt-q1","moduleId":"aiml","cardId":"qz-pytorch-and-ml-engineering-coding--pt-q1","front":"`total_loss += loss` inside a training loop causes:","back":"A memory leak - every step's computation graph stays alive","keyPoints":["`loss` still references its graph. Accumulating the tensor keeps every graph alive until OOM. Use `loss.item()` or `loss.detach()`."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-pytorch-and-ml-engineering-coding--pt-q2","moduleId":"aiml","cardId":"qz-pytorch-and-ml-engineering-coding--pt-q2","front":"For a balanced 10-class classification problem, the initial cross-entropy loss of an untrained model should be approximately:","back":"2.30","keyPoints":["ln(10) ≈ 2.30, because an untrained model outputs roughly uniform probabilities. A very different initial loss immediately signals a label, loss or initialisation bug."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-pytorch-and-ml-engineering-coding--pt-q3","moduleId":"aiml","cardId":"qz-pytorch-and-ml-engineering-coding--pt-q3","front":"In a variable-length text pipeline, you should pad each batch to:","back":"The longest sequence in that batch, ideally with length-grouped sampling","keyPoints":["Padding to a global max wastes enormous compute. Batch-max padding plus length-grouped sampling typically cuts padding from ~60% of tokens to ~10%."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-pytorch-and-ml-engineering-coding--pt-q4","moduleId":"aiml","cardId":"qz-pytorch-and-ml-engineering-coding--pt-q4","front":"GPU utilisation is 30% during training. The most likely cause is:","back":"The input pipeline is starving the GPU","keyPoints":["Low utilisation means the GPU is waiting. Fix num_workers, pin_memory, expensive transforms and storage before touching the model."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-pytorch-and-ml-engineering-coding--pt-q5","moduleId":"aiml","cardId":"qz-pytorch-and-ml-engineering-coding--pt-q5","front":"The difference between `.detach()` and `torch.no_grad()` is:","back":"`detach()` cuts one tensor from the graph and shares storage; `no_grad()` disables graph construction for an entire block","keyPoints":["`detach()` returns a view sharing storage - mutating it mutates the original. `no_grad()` is a context manager that stops tracking any operation inside it."],"href":"/ai-ml-engineer-interview/questions/pytorch-and-ml-engineering-coding#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-behavioral-and-project-deep-dive--bh-q1","moduleId":"aiml","cardId":"qz-ml-behavioral-and-project-deep-dive--bh-q1","front":"The strongest structure for a project deep-dive opens with:","back":"The business problem, what it cost, and the hardest decision you faced","keyPoints":["Leading with problem and decisions invites substantive follow-ups you are prepared for. A chronological tools narrative signals task execution rather than ownership."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-behavioral-and-project-deep-dive--bh-q2","moduleId":"aiml","cardId":"qz-ml-behavioral-and-project-deep-dive--bh-q2","front":"The most important part of a failure story is:","back":"The systemic change you made so that class of failure cannot recur","keyPoints":["Interviewers are testing candour, root-cause thinking and whether you fix the class of bug rather than the instance. The systemic change is the evidence of seniority."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-behavioral-and-project-deep-dive--bh-q3","moduleId":"aiml","cardId":"qz-ml-behavioral-and-project-deep-dive--bh-q3","front":"In a disagreement story, the strongest move is usually:","back":"Proposing the cheapest experiment that resolves the disagreement with data","keyPoints":["Converting an opinion conflict into a days-long experiment is what strong engineers do. Stories where you were wrong, or disagreed and committed, are more revealing than vindication stories."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-behavioral-and-project-deep-dive--bh-q4","moduleId":"aiml","cardId":"qz-ml-behavioral-and-project-deep-dive--bh-q4","front":"The single most useful question when requirements are unclear is:","back":"What will you do differently based on the model's answer?","keyPoints":["Naming the downstream decision derives the output format, latency, precision/recall trade-off and metric all at once - and if no decision changes, the project has no value."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ml-behavioral-and-project-deep-dive--bh-q5","moduleId":"aiml","cardId":"qz-ml-behavioral-and-project-deep-dive--bh-q5","front":"A stakeholder is upset about one wrong prediction. Your first response should be:","back":"Pull up that specific prediction and investigate what drove it","keyPoints":["Aggregate accuracy answers a question they did not ask and reads as dismissive. Investigating the case turns an adversarial conversation collaborative - and often surfaces a real systematic issue."],"href":"/ai-ml-engineer-interview/questions/ml-behavioral-and-project-deep-dive#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-ml-interview-strategy-and-offers--st2-q1","moduleId":"aiml","cardId":"qz-ai-ml-interview-strategy-and-offers--st2-q1","front":"The highest-return question to ask a recruiter before your loop is:","back":"What is the loop breakdown - how many rounds and what does each cover?","keyPoints":["Recruiters almost always share the loop structure, and it tells you exactly what to prepare. Preparing LeetCode for an 'implement k-means' round is a common and avoidable failure."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-ml-interview-strategy-and-offers--st2-q2","moduleId":"aiml","cardId":"qz-ai-ml-interview-strategy-and-offers--st2-q2","front":"In an ML take-home, reviewers weight most heavily:","back":"Correct evaluation methodology, code quality and the write-up","keyPoints":["Submissions cluster within a few points on accuracy. A trustworthy evaluation, clean reproducible code and an honest write-up with limitations are where candidates actually differentiate."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-ml-interview-strategy-and-offers--st2-q3","moduleId":"aiml","cardId":"qz-ai-ml-interview-strategy-and-offers--st2-q3","front":"The single most revealing question to ask your interviewers is:","back":"What fraction of ML projects started in the last year are in production today?","keyPoints":["It measures infrastructure maturity and organisational support for ML. A low number - or visible discomfort - predicts that your models will not ship, which is how ML careers stall."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-ml-interview-strategy-and-offers--st2-q4","moduleId":"aiml","cardId":"qz-ai-ml-interview-strategy-and-offers--st2-q4","front":"In offer negotiation, the lever with the largest long-term impact is usually:","back":"The level you are placed at","keyPoints":["A level difference is often 30–50% of total compensation and compounds through every future raise, refresh and job change. In-band negotiation is a much smaller lever."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers#quiz","moduleLabel":"AI/ML","latent":true},{"key":"aiml:qz-ai-ml-interview-strategy-and-offers--st2-q5","moduleId":"aiml","cardId":"qz-ai-ml-interview-strategy-and-offers--st2-q5","front":"In your first 90 days, the highest-value early contribution is usually:","back":"Fixing an evaluation or monitoring gap that nobody owns","keyPoints":["Evaluation and monitoring gaps are common, unowned, and immediately valuable - and fixing one teaches you the system while building credibility. Rewrites proposed before you have context reliably fail."],"href":"/ai-ml-engineer-interview/questions/ai-ml-interview-strategy-and-offers#quiz","moduleLabel":"AI/ML","latent":true},{"key":"pythonfs:qz-Python-1-5--py1-mutable","moduleId":"pythonfs","cardId":"qz-Python-1-5--py1-mutable","front":"b = a where a is a list, then b.append(4). What does a contain, and why?","back":"a also has 4 appended - both names refer to the same list object","keyPoints":["Assignment binds a name to an object; it never copies. Both a and b reference the same list, so mutating through either name is visible through the other. Use a.copy() or list(a) for a shallow copy."],"href":"/python-fullstack-interview/questions/Python-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-1-5--py1-immutable","moduleId":"pythonfs","cardId":"qz-Python-1-5--py1-immutable","front":"Which of these is immutable in Python?","back":"tuple","keyPoints":["Tuples are immutable. Note the trap: a tuple can *contain* mutable objects, so ([1,2], 3) can still change through its first element - immutability is about the tuple's own bindings, not the objects it points at."],"href":"/python-fullstack-interview/questions/Python-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-1-5--py1-intern","moduleId":"pythonfs","cardId":"qz-Python-1-5--py1-intern","front":"Why can `a is b` be True for small integers but False for large ones?","back":"CPython caches small integers (-5 to 256), so those names point at the same cached object","keyPoints":["CPython interns small integers as an optimisation, so identity happens to match. This is an implementation detail, not a language guarantee - which is exactly why you compare values with == and reserve `is` for None and sentinels."],"href":"/python-fullstack-interview/questions/Python-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-6-10--py6-shallow","moduleId":"pythonfs","cardId":"qz-Python-6-10--py6-shallow","front":"a = [[1, 2], [3, 4]]; b = a.copy(); b[0].append(99). What is a[0]?","back":"[1, 2, 99] - copy() is shallow, so the inner lists are shared","keyPoints":["copy() duplicates the outer list only; the inner lists are the same objects. Use copy.deepcopy() when the nesting matters - and remember it is far more expensive."],"href":"/python-fullstack-interview/questions/Python-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-6-10--py6-generator","moduleId":"pythonfs","cardId":"qz-Python-6-10--py6-generator","front":"What is the main advantage of a generator over a list comprehension?","back":"Generators produce values lazily, so memory stays constant regardless of length","keyPoints":["A list comprehension materialises everything up front. A generator yields one item at a time, which is what lets you stream a multi-gigabyte file. The trade is that it can only be consumed once and cannot be indexed."],"href":"/python-fullstack-interview/questions/Python-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-6-10--py6-legb","moduleId":"pythonfs","cardId":"qz-Python-6-10--py6-legb","front":"In what order does Python resolve a name?","back":"Local, Enclosing, Global, Built-in","keyPoints":["LEGB. Assigning to a name anywhere in a function makes it local for the whole function, which is why reading it before assignment raises UnboundLocalError rather than falling through to the global."],"href":"/python-fullstack-interview/questions/Python-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-16-20--py16-slots","moduleId":"pythonfs","cardId":"qz-Python-16-20--py16-slots","front":"What does __slots__ actually do?","back":"Replaces the per-instance __dict__ with a fixed set of descriptors, cutting memory","keyPoints":["Without __dict__ each instance is markedly smaller, which matters when you create millions. The cost is that you cannot add attributes not listed, and multiple inheritance with slots gets awkward."],"href":"/python-fullstack-interview/questions/Python-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-16-20--py16-classmethod","moduleId":"pythonfs","cardId":"qz-Python-16-20--py16-classmethod","front":"When would you use @classmethod rather than @staticmethod?","back":"When the method needs the class - typically an alternative constructor that must work for subclasses","keyPoints":["A classmethod receives cls, so cls(...) constructs the right type even when called on a subclass. A staticmethod is just a function living in the class namespace."],"href":"/python-fullstack-interview/questions/Python-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-16-20--py16-exception","moduleId":"pythonfs","cardId":"qz-Python-16-20--py16-exception","front":"Why is `except Exception:` preferred over a bare `except:`?","back":"A bare except also catches SystemExit and KeyboardInterrupt, so Ctrl-C and clean shutdown stop working","keyPoints":["Bare except catches BaseException. Swallowing SystemExit and KeyboardInterrupt makes a process very hard to stop - a classic production incident."],"href":"/python-fullstack-interview/questions/Python-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-21-25--py21-is-eq","moduleId":"pythonfs","cardId":"qz-Python-21-25--py21-is-eq","front":"When is `is` the correct operator to use?","back":"For comparing against None and other singletons","keyPoints":["`is` tests identity. Only sentinels - None, True, False, custom singletons - have guaranteed identity. Everything else should use ==, because equal values need not be the same object."],"href":"/python-fullstack-interview/questions/Python-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-21-25--py21-with","moduleId":"pythonfs","cardId":"qz-Python-21-25--py21-with","front":"What guarantees does the `with` statement give you?","back":"__exit__ runs even if the block raises, so cleanup is not skipped","keyPoints":["It is try/finally with a nicer face. __exit__ can suppress an exception by returning True, but by default it just guarantees cleanup and lets the exception propagate."],"href":"/python-fullstack-interview/questions/Python-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-21-25--py21-import","moduleId":"pythonfs","cardId":"qz-Python-21-25--py21-import","front":"What is a circular import, and what usually fixes it?","back":"Two modules importing each other; fixed by moving the shared piece into a third module or importing inside the function","keyPoints":["The partially-initialised module is the giveaway - you get an ImportError or a half-built object. Extracting the shared dependency is the clean fix; a function-local import is the pragmatic one."],"href":"/python-fullstack-interview/questions/Python-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-31-35--py31-dataclass-mutable","moduleId":"pythonfs","cardId":"qz-Python-31-35--py31-dataclass-mutable","front":"Why does @dataclass reject `items: list = []` as a default?","back":"It would be shared across every instance, so it must use field(default_factory=list)","keyPoints":["This is the mutable-default-argument bug, and dataclasses raise at class-creation time rather than letting it bite you later. default_factory constructs a fresh list per instance."],"href":"/python-fullstack-interview/questions/Python-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-31-35--py31-pydantic-vs-dataclass","moduleId":"pythonfs","cardId":"qz-Python-31-35--py31-pydantic-vs-dataclass","front":"What does Pydantic give you that a plain dataclass does not?","back":"Runtime validation and coercion of incoming data","keyPoints":["Dataclass type hints are not enforced at runtime - passing a str where an int was annotated just works. Pydantic validates and coerces, which is why it sits at API boundaries."],"href":"/python-fullstack-interview/questions/Python-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-31-35--py31-abc","moduleId":"pythonfs","cardId":"qz-Python-31-35--py31-abc","front":"What does inheriting from abc.ABC with an @abstractmethod enforce?","back":"The subclass must implement the method before it can be instantiated","keyPoints":["Instantiating a subclass that has not implemented every abstract method raises TypeError. That is the difference from a Protocol, which is checked statically and requires no inheritance."],"href":"/python-fullstack-interview/questions/Python-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-36-40--py36-mro","moduleId":"pythonfs","cardId":"qz-Python-36-40--py36-mro","front":"What does Python use to compute the method resolution order?","back":"C3 linearisation","keyPoints":["C3 guarantees that a class precedes its parents and that the order of bases is preserved. If no consistent order exists Python refuses to create the class - the 'cannot create a consistent MRO' error."],"href":"/python-fullstack-interview/questions/Python-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-36-40--py36-new-init","moduleId":"pythonfs","cardId":"qz-Python-36-40--py36-new-init","front":"What is the difference between __new__ and __init__?","back":"__new__ creates and returns the instance; __init__ configures the already-created instance","keyPoints":["__new__ is the actual constructor and must return an instance; __init__ is the initialiser and must return None. You need __new__ for immutable types and singletons."],"href":"/python-fullstack-interview/questions/Python-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-36-40--py36-str-repr","moduleId":"pythonfs","cardId":"qz-Python-36-40--py36-str-repr","front":"What is the intended difference between __str__ and __repr__?","back":"__repr__ should be unambiguous and ideally reconstructable; __str__ is the readable form","keyPoints":["If you define only one, define __repr__ - str() falls back to it, and it is what you see in the REPL, in a list, and in debugging output."],"href":"/python-fullstack-interview/questions/Python-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-41-45--py41-property","moduleId":"pythonfs","cardId":"qz-Python-41-45--py41-property","front":"Why use @property rather than a get_x() method?","back":"It lets you add computation or validation later without changing the public attribute access API","keyPoints":["You start with a plain attribute, and if it later needs logic you convert it to a property with no change at any call site. That is why Python has no culture of writing getters up front."],"href":"/python-fullstack-interview/questions/Python-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-41-45--py41-weakref","moduleId":"pythonfs","cardId":"qz-Python-41-45--py41-weakref","front":"What problem does weakref solve?","back":"Holding a reference that does not prevent the object from being garbage collected - useful for caches and back-references","keyPoints":["A cache holding strong references keeps everything alive forever. A weak reference lets the object die and the entry disappear. It also breaks parent/child reference cycles."],"href":"/python-fullstack-interview/questions/Python-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-41-45--py41-gather","moduleId":"pythonfs","cardId":"qz-Python-41-45--py41-gather","front":"What does asyncio.gather do that a sequence of awaits does not?","back":"Schedules them concurrently so their waiting overlaps, rather than one after another","keyPoints":["Awaiting in sequence serialises the waiting. gather schedules them all on the loop, so ten 100ms calls take about 100ms rather than a second. It is still one thread, one core."],"href":"/python-fullstack-interview/questions/Python-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-46-50--py46-awaitable","moduleId":"pythonfs","cardId":"qz-Python-46-50--py46-awaitable","front":"What makes an object awaitable?","back":"It implements __await__","keyPoints":["Coroutines, Tasks and Futures are all awaitable because they implement __await__. That is the protocol, which is why you can make your own awaitable types."],"href":"/python-fullstack-interview/questions/Python-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-46-50--py46-memoryview","moduleId":"pythonfs","cardId":"qz-Python-46-50--py46-memoryview","front":"What does memoryview give you?","back":"Zero-copy slicing of a bytes-like object, avoiding duplication of large data","keyPoints":["Slicing bytes copies; slicing a memoryview does not. For a large buffer processed in chunks that turns O(n²) copying into none at all."],"href":"/python-fullstack-interview/questions/Python-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-46-50--py46-lrucache","moduleId":"pythonfs","cardId":"qz-Python-46-50--py46-lrucache","front":"What is required of a function's arguments for functools.lru_cache to work?","back":"They must be hashable","keyPoints":["The cache is a dict keyed on the arguments, so passing a list or dict raises TypeError: unhashable type. Convert to a tuple or frozenset at the boundary."],"href":"/python-fullstack-interview/questions/Python-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-56-60--py56-profile","moduleId":"pythonfs","cardId":"qz-Python-56-60--py56-profile","front":"You need to find which line of a slow function is the problem. Which tool?","back":"cProfile for per-function cost, then line_profiler for per-line","keyPoints":["cProfile tells you which function; line_profiler tells you which line inside it. timeit is for microbenchmarks and tracemalloc is for memory, not time."],"href":"/python-fullstack-interview/questions/Python-56-60#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-56-60--py56-tracemalloc","moduleId":"pythonfs","cardId":"qz-Python-56-60--py56-tracemalloc","front":"What is tracemalloc for?","back":"Tracking memory allocations so you can find what is growing and where it was allocated","keyPoints":["It snapshots allocations and lets you diff two snapshots, which is how you find a leak - the traceback tells you the line that allocated the growing objects."],"href":"/python-fullstack-interview/questions/Python-56-60#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-56-60--py56-pickle","moduleId":"pythonfs","cardId":"qz-Python-56-60--py56-pickle","front":"Why should you never unpickle data from an untrusted source?","back":"Unpickling can execute arbitrary code via __reduce__","keyPoints":["Pickle is a code-execution format, not a data format. For untrusted input use JSON, or msgpack if you need binary - both are data-only."],"href":"/python-fullstack-interview/questions/Python-56-60#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-61-65--py61-logging","moduleId":"pythonfs","cardId":"qz-Python-61-65--py61-logging","front":"Why use logging rather than print() in an application?","back":"Logging gives levels, structured output, and per-module configuration you can change without editing code","keyPoints":["The decisive part is that a library logs and the application decides what to do with it. print() hard-codes the destination and the verbosity at the call site."],"href":"/python-fullstack-interview/questions/Python-61-65#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-61-65--py61-logger-name","moduleId":"pythonfs","cardId":"qz-Python-61-65--py61-logger-name","front":"Why is logging.getLogger(__name__) the recommended pattern?","back":"It creates a logger named after the module, so configuration can target packages hierarchically","keyPoints":["Loggers form a dotted hierarchy, so you can silence myapp.db without touching myapp.api. Using the root logger throughout throws that away."],"href":"/python-fullstack-interview/questions/Python-61-65#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-61-65--py61-secrets","moduleId":"pythonfs","cardId":"qz-Python-61-65--py61-secrets","front":"Which is the correct way to handle a production API key?","back":"Load it from an environment variable or a secrets manager, never from source","keyPoints":["Encoding is not encryption, and a private repo is one fork or one leaked laptop from public. Anything committed to git is in the history permanently, even after deletion."],"href":"/python-fullstack-interview/questions/Python-61-65#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-66-70--py66-fixture","moduleId":"pythonfs","cardId":"qz-Python-66-70--py66-fixture","front":"What does a pytest fixture give you over setUp()?","back":"Explicit dependency injection, composability, and scopes (function/module/session)","keyPoints":["A test declares what it needs as a parameter, so there is no hidden shared state on self, and expensive setup can be scoped to the session rather than repeated per test."],"href":"/python-fullstack-interview/questions/Python-66-70#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-66-70--py66-mock-where","moduleId":"pythonfs","cardId":"qz-Python-66-70--py66-mock-where","front":"Where should you patch when mocking?","back":"Where the object is looked up - the module under test","keyPoints":["'Patch where it is used, not where it is defined.' If mymodule does `from requests import get`, you patch mymodule.get - patching requests.get is too late, the name is already bound."],"href":"/python-fullstack-interview/questions/Python-66-70#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-66-70--py66-mp-pickle","moduleId":"pythonfs","cardId":"qz-Python-66-70--py66-mp-pickle","front":"Why can multiprocessing fail with 'cannot pickle' errors?","back":"Arguments and return values are pickled to cross the process boundary, and lambdas, closures and open sockets cannot be pickled","keyPoints":["Separate processes share no memory, so everything is serialised. Module-level functions pickle fine; lambdas and local functions do not."],"href":"/python-fullstack-interview/questions/Python-66-70#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-71-75--py71-eval","moduleId":"pythonfs","cardId":"qz-Python-71-75--py71-eval","front":"Why is eval() on user input dangerous even with a restricted namespace?","back":"Attackers can reach arbitrary objects through introspection like __class__ and __subclasses__","keyPoints":["Sandboxing eval in Python is famously unreliable - the object graph is reachable from almost anything. Use ast.literal_eval for data, or a real parser for expressions."],"href":"/python-fullstack-interview/questions/Python-71-75#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-71-75--py71-unicode","moduleId":"pythonfs","cardId":"qz-Python-71-75--py71-unicode","front":"What is the practical difference between a str and bytes in Python 3?","back":"str is a sequence of Unicode code points; bytes is raw octets, and converting needs an explicit encoding","keyPoints":["Python 3 refuses to guess an encoding, which is why implicit conversion raises rather than silently mangling. Decode at input, encode at output, keep str in between."],"href":"/python-fullstack-interview/questions/Python-71-75#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-71-75--py71-yield-send","moduleId":"pythonfs","cardId":"qz-Python-71-75--py71-yield-send","front":"What does generator.send(value) do?","back":"Resumes the generator, making the paused `yield` expression evaluate to that value","keyPoints":["This turns a generator into a two-way channel and is the mechanism coroutines were built on before async/await got dedicated syntax."],"href":"/python-fullstack-interview/questions/Python-71-75#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-11-15--py11-gil-2026","moduleId":"pythonfs","cardId":"qz-Python-11-15--py11-gil-2026","front":"An interviewer asks: 'Can Python threads run CPU-bound code in parallel?' What is the strongest 2026 answer?","back":"On a standard build, no. But the free-threaded build (PEP 703), experimental in 3.13 and officially supported in 3.14, removes the GIL","keyPoints":["A flat 'no' is now incomplete. Free-threaded CPython is a separate, officially supported build as of 3.14 (distributed as python3.14t). The default download still has the GIL, so the practical advice is unchanged - but knowing the distinction is what shows currency."],"href":"/python-fullstack-interview/questions/Python-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-11-15--py11-freethread-safety","moduleId":"pythonfs","cardId":"qz-Python-11-15--py11-freethread-safety","front":"What does removing the GIL NOT give you?","back":"Automatic thread safety for your own shared data structures","keyPoints":["This is the follow-up that catches people. The GIL was an interpreter-wide lock, not a correctness guarantee for your code. Anything that quietly relied on it for atomicity now needs an explicit lock."],"href":"/python-fullstack-interview/questions/Python-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-11-15--py11-decorator","moduleId":"pythonfs","cardId":"qz-Python-11-15--py11-decorator","front":"What does functools.wraps do in a decorator?","back":"Copies __name__, __doc__ and other metadata from the wrapped function onto the wrapper","keyPoints":["Without it, the decorated function reports the wrapper's name and loses its docstring, which breaks introspection, debugging and documentation tools."],"href":"/python-fullstack-interview/questions/Python-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-11-15--py11-io-cpu","moduleId":"pythonfs","cardId":"qz-Python-11-15--py11-io-cpu","front":"Your service spends most of its time waiting on HTTP calls. Best choice?","back":"asyncio or threads - the GIL is released while waiting on I/O","keyPoints":["I/O-bound work releases the GIL while blocked, so threads and asyncio both scale well. Processes would add memory and IPC overhead for no benefit."],"href":"/python-fullstack-interview/questions/Python-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-26-30--py26-uv","moduleId":"pythonfs","cardId":"qz-Python-26-30--py26-uv","front":"Asked how you manage dependencies on a new Python project in 2026, which answer sounds most current?","back":"uv - it handles environments, resolution and a real lockfile in one fast tool; poetry is common in existing codebases","keyPoints":["uv (from Astral) consolidates pip, pip-tools, virtualenv, pyenv and twine into one Rust binary and has become the default in a large share of projects. Mentioning poetry as the incumbent shows you know the landscape rather than just the newest tool."],"href":"/python-fullstack-interview/questions/Python-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-26-30--py26-ruff","moduleId":"pythonfs","cardId":"qz-Python-26-30--py26-ruff","front":"Which task does Ruff NOT replace?","back":"mypy type checking","keyPoints":["Ruff lints and formats; it does no type inference. Type checking stays with mypy or pyright. Knowing where the boundary is matters more than listing the tools."],"href":"/python-fullstack-interview/questions/Python-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-26-30--py26-venv","moduleId":"pythonfs","cardId":"qz-Python-26-30--py26-venv","front":"What problem does a virtual environment actually solve?","back":"It isolates one project's dependency versions from another's","keyPoints":["Two projects needing different versions of the same library cannot share one global site-packages. A venv gives each its own."],"href":"/python-fullstack-interview/questions/Python-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-51-55--py51-pep695","moduleId":"pythonfs","cardId":"qz-Python-51-55--py51-pep695","front":"Which is the Python 3.12+ syntax for a generic function?","back":"def identity[T](x: T) -> T: ...","keyPoints":["PEP 695 gave generics dedicated syntax. The type parameter is scoped to the function, so there is no separate TypeVar declaration. The old form still works and you will see it everywhere."],"href":"/python-fullstack-interview/questions/Python-51-55#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-51-55--py51-protocol","moduleId":"pythonfs","cardId":"qz-Python-51-55--py51-protocol","front":"What does typing.Protocol give you that an ABC does not?","back":"Structural typing - a class matches by having the right methods, without inheriting anything","keyPoints":["Protocols are static duck typing. An ABC requires explicit inheritance (nominal typing); a Protocol matches any class with a compatible shape, which is why it fits Python's existing idioms better."],"href":"/python-fullstack-interview/questions/Python-51-55#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-76-80--py76-reverse","moduleId":"pythonfs","cardId":"qz-Python-76-80--py76-reverse","front":"In an iterative linked-list reversal, why must you save `next` before setting `curr.next = prev`?","back":"Because that assignment destroys the only reference to the rest of the list","keyPoints":["Once curr.next points backwards, nothing references the remaining nodes. Swap those two lines and you lose the tail. Step through it in the linked-list reversal visualizer."],"href":"/python-fullstack-interview/questions/Python-76-80#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-76-80--py76-lru","moduleId":"pythonfs","cardId":"qz-Python-76-80--py76-lru","front":"Why does an LRU cache need a doubly linked list rather than a singly linked one?","back":"Unlinking a node in O(1) requires its predecessor, which only a prev pointer provides","keyPoints":["Every get moves a node from the middle to the front. Without prev you would scan to find the predecessor, making the operation O(n) and defeating the whole design."],"href":"/python-fullstack-interview/questions/Python-76-80#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-76-80--py76-palindrome","moduleId":"pythonfs","cardId":"qz-Python-76-80--py76-palindrome","front":"What is the space complexity of the two-pointer palindrome check?","back":"O(1)","keyPoints":["Two indices walking inward use constant space. Reversing the string and comparing is also O(n) time but allocates a second copy - the two-pointer version is what interviewers are after."],"href":"/python-fullstack-interview/questions/Python-76-80#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-81-85--py81-floyd-space","moduleId":"pythonfs","cardId":"qz-Python-81-85--py81-floyd-space","front":"Why is Floyd's cycle detection preferred over a set of visited nodes?","back":"It uses O(1) memory rather than O(n)","keyPoints":["A visited-set solution is O(n) time and O(n) space. Floyd's is O(n) time and O(1) space, which is the point of the question when the interviewer adds 'now in constant space'."],"href":"/python-fullstack-interview/questions/Python-81-85#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-81-85--py81-bsearch-mid","moduleId":"pythonfs","cardId":"qz-Python-81-85--py81-bsearch-mid","front":"Why write mid = lo + (hi - lo) // 2 instead of (lo + hi) // 2?","back":"In fixed-width integer languages lo + hi can overflow; the subtraction form cannot","keyPoints":["Python ints are arbitrary precision so it cannot overflow here, but the habit matters - this exact bug sat in the JDK's binary search for nine years, and interviewers ask about it."],"href":"/python-fullstack-interview/questions/Python-81-85#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-81-85--py81-fib","moduleId":"pythonfs","cardId":"qz-Python-81-85--py81-fib","front":"Naive recursive fib(n) is O(2ⁿ). What makes memoisation collapse it to O(n)?","back":"Each distinct n is computed once and reused, eliminating the repeated subtrees","keyPoints":["The exponential cost comes entirely from recomputing the same subproblems. Caching turns the call tree into a line - the recursion visualizer has a toggle that shows this happening."],"href":"/python-fullstack-interview/questions/Python-81-85#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-86-90--py86-counter","moduleId":"pythonfs","cardId":"qz-Python-86-90--py86-counter","front":"What is the idiomatic way to count character frequency in Python?","back":"collections.Counter(s)","keyPoints":["Counter is a dict subclass built for exactly this, and gives you most_common() for free. The manual dict works but the interviewer is checking whether you know the standard library."],"href":"/python-fullstack-interview/questions/Python-86-90#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-86-90--py86-queue-stacks","moduleId":"pythonfs","cardId":"qz-Python-86-90--py86-queue-stacks","front":"Implementing a queue with two stacks: what is the amortised dequeue cost?","back":"O(1) amortised","keyPoints":["Elements move from the in-stack to the out-stack only once each. A single dequeue can be O(n), but across n operations the total is O(n) - the same amortised argument as a dynamic array."],"href":"/python-fullstack-interview/questions/Python-86-90#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Python-86-90--py86-cpython","moduleId":"pythonfs","cardId":"qz-Python-86-90--py86-cpython","front":"What is the main difference between CPython and PyPy?","back":"PyPy uses a tracing JIT, so long-running numeric code is often much faster; CPython interprets bytecode","keyPoints":["PyPy's JIT shines on long-running pure-Python hot loops. The trade is slower startup and weaker C-extension compatibility, which is why CPython remains the default."],"href":"/python-fullstack-interview/questions/Python-86-90#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-1-5--db1-pk-unique","moduleId":"pythonfs","cardId":"qz-DB-MySQL-1-5--db1-pk-unique","front":"What is the difference between a PRIMARY KEY and a UNIQUE constraint?","back":"A primary key cannot be NULL and there is only one per table; UNIQUE allows NULLs and you can have several","keyPoints":["Both enforce uniqueness and both create an index. The differences are nullability and multiplicity - and in InnoDB the primary key also determines physical row order."],"href":"/python-fullstack-interview/questions/DB-MySQL-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-1-5--db1-fk","moduleId":"pythonfs","cardId":"qz-DB-MySQL-1-5--db1-fk","front":"What does a FOREIGN KEY actually enforce?","back":"Referential integrity - you cannot reference a row that does not exist, nor orphan rows by deleting the parent","keyPoints":["It pushes a correctness rule into the database so no application bug can violate it. ON DELETE CASCADE / SET NULL decide what happens to children when the parent goes."],"href":"/python-fullstack-interview/questions/DB-MySQL-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-1-5--db1-nosql","moduleId":"pythonfs","cardId":"qz-DB-MySQL-1-5--db1-nosql","front":"When is a document store a better fit than a relational database?","back":"When the schema varies per record and access is mostly by a single key, with few cross-entity joins","keyPoints":["The honest answer names the trade: you gain schema flexibility and horizontal scaling, and you give up joins and (historically) some transactional guarantees. 'It is faster' is not a reason."],"href":"/python-fullstack-interview/questions/DB-MySQL-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-11-15--db11-leftmost","moduleId":"pythonfs","cardId":"qz-DB-MySQL-11-15--db11-leftmost","front":"You have an index on (last_name, first_name). Which query can use it for a seek?","back":"WHERE last_name = 'Lovelace'","keyPoints":["The leftmost-prefix rule: a composite index can be used for a prefix of its columns. Filtering on first_name alone skips the leading column, so the index cannot seek."],"href":"/python-fullstack-interview/questions/DB-MySQL-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-11-15--db11-covering","moduleId":"pythonfs","cardId":"qz-DB-MySQL-11-15--db11-covering","front":"What makes an index 'covering' for a query?","back":"It contains every column the query needs, so the engine never touches the table itself","keyPoints":["The lookup back to the table row is often the expensive part. If the index already holds every referenced column, that step disappears - EXPLAIN shows 'Using index'."],"href":"/python-fullstack-interview/questions/DB-MySQL-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-11-15--db11-function","moduleId":"pythonfs","cardId":"qz-DB-MySQL-11-15--db11-function","front":"Why does WHERE YEAR(created_at) = 2026 usually prevent an index seek?","back":"Wrapping the column in a function means the engine cannot compare against the stored index values, so it scans","keyPoints":["Rewrite as a range: created_at >= '2026-01-01' AND created_at < '2027-01-01'. That is sargable and can seek. Same issue with LIKE '%foo'."],"href":"/python-fullstack-interview/questions/DB-MySQL-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-16-20--db16-truncate","moduleId":"pythonfs","cardId":"qz-DB-MySQL-16-20--db16-truncate","front":"What distinguishes TRUNCATE from DELETE?","back":"TRUNCATE drops and recreates the table, is not row-by-row, cannot have a WHERE clause, and resets AUTO_INCREMENT","keyPoints":["DELETE logs each row and fires triggers, which is why it is slow but selective and transactional. TRUNCATE is a DDL operation - fast, all-or-nothing, and it resets the counter."],"href":"/python-fullstack-interview/questions/DB-MySQL-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-16-20--db16-having","moduleId":"pythonfs","cardId":"qz-DB-MySQL-16-20--db16-having","front":"What is the difference between WHERE and HAVING?","back":"WHERE filters rows before grouping; HAVING filters groups after aggregation","keyPoints":["You cannot reference an aggregate in WHERE because the groups do not exist yet. Filter as much as possible in WHERE - it reduces the rows that need grouping."],"href":"/python-fullstack-interview/questions/DB-MySQL-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-16-20--db16-nth","moduleId":"pythonfs","cardId":"qz-DB-MySQL-16-20--db16-nth","front":"What is the cleanest modern way to find the Nth highest salary?","back":"A window function: DENSE_RANK() OVER (ORDER BY salary DESC)","keyPoints":["Window functions handle ties correctly and read clearly. The correlated-subquery version works but is O(n²) in the worst case and awkward to explain."],"href":"/python-fullstack-interview/questions/DB-MySQL-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-21-25--db21-null","moduleId":"pythonfs","cardId":"qz-DB-MySQL-21-25--db21-null","front":"Why does WHERE column = NULL never match anything?","back":"NULL means unknown, so any comparison with it yields unknown - you need IS NULL","keyPoints":["Three-valued logic. NULL = NULL is also unknown, not true, which is why IS NULL / IS NOT NULL exist and why NOT IN with a NULL in the list returns no rows."],"href":"/python-fullstack-interview/questions/DB-MySQL-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-21-25--db21-union","moduleId":"pythonfs","cardId":"qz-DB-MySQL-21-25--db21-union","front":"What is the difference between UNION and UNION ALL?","back":"UNION removes duplicates, which requires a sort or hash and costs more; UNION ALL just concatenates","keyPoints":["If you know the sets are disjoint, UNION ALL is meaningfully cheaper because it skips the deduplication pass entirely."],"href":"/python-fullstack-interview/questions/DB-MySQL-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-21-25--db21-3nf","moduleId":"pythonfs","cardId":"qz-DB-MySQL-21-25--db21-3nf","front":"What does third normal form require?","back":"No transitive dependency - non-key columns must depend on the key, the whole key, and nothing but the key","keyPoints":["1NF removes repeating groups, 2NF removes partial dependencies, 3NF removes transitive ones. Denormalising afterwards is a deliberate read-performance trade, not a failure."],"href":"/python-fullstack-interview/questions/DB-MySQL-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-31-35--db31-deadlock","moduleId":"pythonfs","cardId":"qz-DB-MySQL-31-35--db31-deadlock","front":"What is the most reliable way to prevent deadlocks?","back":"Always acquire locks on multiple resources in a consistent order","keyPoints":["Deadlocks need a cycle in the wait-for graph. A globally consistent lock ordering makes a cycle impossible. Beyond that, keep transactions short and be ready to retry."],"href":"/python-fullstack-interview/questions/DB-MySQL-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-31-35--db31-innodb","moduleId":"pythonfs","cardId":"qz-DB-MySQL-31-35--db31-innodb","front":"Why is InnoDB the default rather than MyISAM?","back":"It supports transactions, row-level locking and foreign keys; MyISAM has table-level locking and no transactions","keyPoints":["Table-level locking serialises writers, which collapses under concurrency. MyISAM can still win on read-only workloads, but the safety trade is rarely worth it."],"href":"/python-fullstack-interview/questions/DB-MySQL-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-31-35--db31-bufferpool","moduleId":"pythonfs","cardId":"qz-DB-MySQL-31-35--db31-bufferpool","front":"What does the InnoDB buffer pool hold?","back":"Cached data and index pages in memory, so hot data is served without touching disk","keyPoints":["It is the single most important tuning knob - sized correctly, the working set stays in RAM. The query cache is a different thing, and was removed in MySQL 8 because its invalidation cost outweighed the benefit."],"href":"/python-fullstack-interview/questions/DB-MySQL-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-36-40--db36-leftjoin","moduleId":"pythonfs","cardId":"qz-DB-MySQL-36-40--db36-leftjoin","front":"A LEFT JOIN with a WHERE condition on the right table's column - what happens?","back":"It silently behaves like an INNER JOIN, because NULL rows fail the WHERE test","keyPoints":["The unmatched rows have NULL on the right, and NULL fails any comparison. Put the condition in the ON clause instead if you want to keep them."],"href":"/python-fullstack-interview/questions/DB-MySQL-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-36-40--db36-correlated","moduleId":"pythonfs","cardId":"qz-DB-MySQL-36-40--db36-correlated","front":"What makes a subquery 'correlated'?","back":"It references a column from the outer query, so it is conceptually re-evaluated per outer row","keyPoints":["That per-row dependency is why they can be slow. Modern optimisers often rewrite them as joins, but a JOIN or window function is usually clearer and more predictable."],"href":"/python-fullstack-interview/questions/DB-MySQL-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-36-40--db36-selfjoin","moduleId":"pythonfs","cardId":"qz-DB-MySQL-36-40--db36-selfjoin","front":"What is a self-join typically used for?","back":"Relating rows within one table, such as an employee to their manager","keyPoints":["The table is aliased twice so the same rows can be compared against each other - hierarchies, adjacent rows, and finding pairs."],"href":"/python-fullstack-interview/questions/DB-MySQL-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-41-45--db41-view","moduleId":"pythonfs","cardId":"qz-DB-MySQL-41-45--db41-view","front":"What does a standard (non-materialised) view store?","back":"Nothing - it stores the query, which runs each time the view is selected from","keyPoints":["A view is a named query. It simplifies and can restrict access, but gives no performance benefit by itself. A materialised view stores results and needs a refresh strategy."],"href":"/python-fullstack-interview/questions/DB-MySQL-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-41-45--db41-proc-func","moduleId":"pythonfs","cardId":"qz-DB-MySQL-41-45--db41-proc-func","front":"What is the key difference between a stored procedure and a function?","back":"A function returns a value and can be used inside a query; a procedure is invoked with CALL and may return multiple result sets","keyPoints":["Because a function is callable from within a SELECT it must be deterministic-ish and side-effect free; a procedure is a script and can do more."],"href":"/python-fullstack-interview/questions/DB-MySQL-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-41-45--db41-trigger","moduleId":"pythonfs","cardId":"qz-DB-MySQL-41-45--db41-trigger","front":"What is the main risk of business logic in triggers?","back":"They run invisibly, so behaviour is hard to trace, test and reason about from the application side","keyPoints":["A trigger firing another trigger is a genuinely hard debugging session. They are excellent for audit trails and integrity, and a poor place for business rules."],"href":"/python-fullstack-interview/questions/DB-MySQL-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-46-50--db46-lag","moduleId":"pythonfs","cardId":"qz-DB-MySQL-46-50--db46-lag","front":"What is replication lag and why does it matter?","back":"The delay before a write on the primary is visible on a replica - so a read-after-write can return stale data","keyPoints":["This is the classic bug: user saves a profile, the read goes to a lagging replica, and the change appears to vanish. Route read-after-write to the primary, or pin the session."],"href":"/python-fullstack-interview/questions/DB-MySQL-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-46-50--db46-split","moduleId":"pythonfs","cardId":"qz-DB-MySQL-46-50--db46-split","front":"What problem does read-write splitting solve, and what does it not?","back":"It scales reads by spreading them across replicas; writes still all go to one primary","keyPoints":["Replication scales reads, not writes. Once the primary is write-saturated the next step is sharding, which is a much larger change."],"href":"/python-fullstack-interview/questions/DB-MySQL-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-46-50--db46-failover","moduleId":"pythonfs","cardId":"qz-DB-MySQL-46-50--db46-failover","front":"What is the biggest risk during an automated failover?","back":"Split-brain - two nodes both believing they are primary and accepting conflicting writes","keyPoints":["This is why failover systems use quorum or fencing. Losing a few unreplicated transactions is recoverable; two divergent write histories often are not."],"href":"/python-fullstack-interview/questions/DB-MySQL-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-6-10--db6-index-cost","moduleId":"pythonfs","cardId":"qz-DB-MySQL-6-10--db6-index-cost","front":"What is the main cost of adding an index?","back":"Writes become slower and the index consumes storage","keyPoints":["Every INSERT, UPDATE and DELETE must also maintain the index. That is the trade: faster reads, slower writes, more disk. It is why you index for the queries you actually run, not for every column."],"href":"/python-fullstack-interview/questions/DB-MySQL-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-6-10--db6-clustered","moduleId":"pythonfs","cardId":"qz-DB-MySQL-6-10--db6-clustered","front":"How many clustered indexes can a table have, and why?","back":"Exactly one - it determines the physical row order on disk","keyPoints":["A clustered index defines how rows are physically stored, and rows can only be laid out one way. In InnoDB the primary key is the clustered index."],"href":"/python-fullstack-interview/questions/DB-MySQL-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-26-30--db26-acid-i","moduleId":"pythonfs","cardId":"qz-DB-MySQL-26-30--db26-acid-i","front":"Which anomaly does READ COMMITTED still permit?","back":"Non-repeatable reads","keyPoints":["READ COMMITTED prevents dirty reads but not non-repeatable reads: the same row can change between two reads in one transaction. REPEATABLE READ fixes that, and SERIALIZABLE additionally prevents phantoms."],"href":"/python-fullstack-interview/questions/DB-MySQL-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-DB-MySQL-26-30--db26-shard-key","moduleId":"pythonfs","cardId":"qz-DB-MySQL-26-30--db26-shard-key","front":"What is the most common cause of a hot shard?","back":"A shard key with skewed access - one value receives disproportionate traffic","keyPoints":["Sharding by a key with a celebrity value (a single tenant, a viral user) concentrates load on one shard. Choosing a high-cardinality, evenly-accessed key is the whole game."],"href":"/python-fullstack-interview/questions/DB-MySQL-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-1-5--dj1-mvt","moduleId":"pythonfs","cardId":"qz-Django-1-5--dj1-mvt","front":"In Django's MVT, what plays the role that a 'controller' does elsewhere?","back":"The View - and the framework itself handles URL dispatch","keyPoints":["Django's View is the controller by another name; the Template is the presentation layer. Django calls the pattern MVT because the framework, not your code, does the routing."],"href":"/python-fullstack-interview/questions/Django-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-1-5--dj1-vs-flask","moduleId":"pythonfs","cardId":"qz-Django-1-5--dj1-vs-flask","front":"What is the honest trade between Django and Flask?","back":"Django is batteries-included (ORM, admin, auth, migrations) with more convention; Flask is minimal and you assemble the stack yourself","keyPoints":["The right answer names what you gain and what you give up. Django's opinions save enormous time when they match your problem, and get in the way when they do not."],"href":"/python-fullstack-interview/questions/Django-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-1-5--dj1-lazy","moduleId":"pythonfs","cardId":"qz-Django-1-5--dj1-lazy","front":"When does a Django QuerySet actually hit the database?","back":"When it is evaluated - iterated, sliced with a step, len(), list(), bool() and so on","keyPoints":["Laziness lets you chain filters without extra queries. It also means a queryset defined in one place and evaluated in another can surprise you - and it is why the N+1 problem hides so well."],"href":"/python-fullstack-interview/questions/Django-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-11-15--dj11-middleware-order","moduleId":"pythonfs","cardId":"qz-Django-11-15--dj11-middleware-order","front":"Why does the order of MIDDLEWARE matter?","back":"Requests pass down the list and responses come back up, so a middleware depending on another must sit after it","keyPoints":["It is an onion. AuthenticationMiddleware must come after SessionMiddleware because it reads the session - swap them and request.user is never populated."],"href":"/python-fullstack-interview/questions/Django-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-11-15--dj11-signals","moduleId":"pythonfs","cardId":"qz-Django-11-15--dj11-signals","front":"What is the main drawback of Django signals?","back":"They create implicit, action-at-a-distance coupling that is hard to trace and easy to miss in bulk operations","keyPoints":["Also worth knowing: bulk_create and queryset.update() bypass save(), so post_save never fires. An explicit service function is usually clearer than a signal."],"href":"/python-fullstack-interview/questions/Django-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-11-15--dj11-cbv","moduleId":"pythonfs","cardId":"qz-Django-11-15--dj11-cbv","front":"What is the strongest argument for class-based views?","back":"Shared behaviour composes through mixins and generic views, removing repetitive CRUD boilerplate","keyPoints":["The counter-argument is real too: the MRO can make it hard to see what actually runs. Function-based views stay easier to read for genuinely one-off logic."],"href":"/python-fullstack-interview/questions/Django-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-16-20--dj16-static-media","moduleId":"pythonfs","cardId":"qz-Django-16-20--dj16-static-media","front":"What is the difference between static files and media files?","back":"Static files ship with the code (CSS, JS, images you wrote); media files are uploaded by users at runtime","keyPoints":["The consequence matters: static files can be collected and cached aggressively at deploy time, while media needs writable, backed-up, often off-server storage like S3."],"href":"/python-fullstack-interview/questions/Django-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-16-20--dj16-collectstatic","moduleId":"pythonfs","cardId":"qz-Django-16-20--dj16-collectstatic","front":"What does collectstatic actually do?","back":"Copies static files from every app and STATICFILES_DIRS into one STATIC_ROOT directory for the web server to serve","keyPoints":["In development Django serves static files itself; in production it should not. collectstatic produces the single directory NGINX or a CDN points at."],"href":"/python-fullstack-interview/questions/Django-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-16-20--dj16-cache-invalidation","moduleId":"pythonfs","cardId":"qz-Django-16-20--dj16-cache-invalidation","front":"What is the hardest part of adding caching?","back":"Invalidation - knowing when cached data has become wrong","keyPoints":["Setting a cache is easy. Deciding what to evict when the underlying data changes, without either serving stale results or evicting everything, is the real design work."],"href":"/python-fullstack-interview/questions/Django-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-26-30--dj26-related-name","moduleId":"pythonfs","cardId":"qz-Django-26-30--dj26-related-name","front":"What does related_name on a ForeignKey control?","back":"The attribute used for the reverse lookup from the related model","keyPoints":["Without it you get the default modelname_set. Setting related_name='articles' lets you write author.articles.all(), which reads far better and avoids clashes when a model has two FKs to the same target."],"href":"/python-fullstack-interview/questions/Django-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-26-30--dj26-m2m-through","moduleId":"pythonfs","cardId":"qz-Django-26-30--dj26-m2m-through","front":"When do you need an explicit `through` model on a ManyToManyField?","back":"When the relationship itself carries data, such as a joined-at date or a role","keyPoints":["The implicit join table has only the two foreign keys. The moment the relationship has attributes of its own, you need a through model - and adding it later is a painful migration."],"href":"/python-fullstack-interview/questions/Django-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-26-30--dj26-channels","moduleId":"pythonfs","cardId":"qz-Django-26-30--dj26-channels","front":"What does Django Channels add?","back":"ASGI support for long-lived protocols like WebSockets, plus a channel layer for cross-process messaging","keyPoints":["Plain WSGI has no notion of a persistent connection. The channel layer, usually Redis-backed, is what lets one process push a message to a socket held by another."],"href":"/python-fullstack-interview/questions/Django-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-36-40--dj36-jwt-tradeoff","moduleId":"pythonfs","cardId":"qz-Django-36-40--dj36-jwt-tradeoff","front":"What is the main drawback of stateless JWTs?","back":"You cannot easily revoke one before it expires, because the server holds no session state","keyPoints":["That is the whole trade: no session lookup, but no instant logout either. The usual mitigations are short-lived access tokens with refresh tokens, plus a denylist for the exceptional case."],"href":"/python-fullstack-interview/questions/Django-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-36-40--dj36-throttle","moduleId":"pythonfs","cardId":"qz-Django-36-40--dj36-throttle","front":"What is DRF throttling actually protecting against?","back":"Abuse and resource exhaustion - one client consuming capacity that belongs to everyone","keyPoints":["It is a fairness and availability control, not a security boundary. Scoped throttles let you rate-limit an expensive endpoint separately from cheap ones."],"href":"/python-fullstack-interview/questions/Django-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-36-40--dj36-pagination","moduleId":"pythonfs","cardId":"qz-Django-36-40--dj36-pagination","front":"Why is cursor pagination preferred over offset pagination on large tables?","back":"OFFSET must scan and discard all preceding rows, so deep pages get slow - and rows shift if data changes mid-paging","keyPoints":["LIMIT 20 OFFSET 100000 reads 100,020 rows to return 20. A cursor keyed on an indexed ordering column seeks directly, and is stable under concurrent inserts."],"href":"/python-fullstack-interview/questions/Django-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-41-45--dj41-gunicorn","moduleId":"pythonfs","cardId":"qz-Django-41-45--dj41-gunicorn","front":"Why put NGINX in front of Gunicorn rather than exposing Gunicorn directly?","back":"NGINX handles TLS, static files, buffering and slow clients efficiently, freeing app workers for application work","keyPoints":["The buffering point is the one people miss: without a reverse proxy, a slow client ties up a whole application worker for the duration of the transfer."],"href":"/python-fullstack-interview/questions/Django-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-41-45--dj41-workers","moduleId":"pythonfs","cardId":"qz-Django-41-45--dj41-workers","front":"What determines a sensible Gunicorn worker count?","back":"Roughly (2 × CPU cores) + 1 for sync workers, adjusted for memory and workload type","keyPoints":["Each sync worker is a process with its own memory, and each holds a database connection. Async workers change the calculation entirely, which is why the workload type matters."],"href":"/python-fullstack-interview/questions/Django-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-41-45--dj41-only-defer","moduleId":"pythonfs","cardId":"qz-Django-41-45--dj41-only-defer","front":"When is .only() or .defer() worth using?","back":"When a table has large columns you do not need for this query, such as a TextField body","keyPoints":["Careful though: accessing a deferred field afterwards triggers an extra query per object, which turns one saving into an N+1. Measure rather than sprinkle."],"href":"/python-fullstack-interview/questions/Django-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-46-50--dj46-s3","moduleId":"pythonfs","cardId":"qz-Django-46-50--dj46-s3","front":"Why serve user uploads from S3 rather than the application server's disk?","back":"App servers should be stateless and replaceable; local disk does not survive a redeploy and is not shared between instances","keyPoints":["The moment you run two instances behind a load balancer, a file uploaded to one is invisible to the other. Statelessness is the reason, not raw speed."],"href":"/python-fullstack-interview/questions/Django-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-46-50--dj46-debug","moduleId":"pythonfs","cardId":"qz-Django-46-50--dj46-debug","front":"What is the single most important production setting to get right?","back":"DEBUG = False, with ALLOWED_HOSTS set","keyPoints":["DEBUG = True in production leaks settings, SQL and local variables on every error page. Django refuses to serve requests without ALLOWED_HOSTS when DEBUG is off, which is a deliberate guard."],"href":"/python-fullstack-interview/questions/Django-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-46-50--dj46-n1-detect","moduleId":"pythonfs","cardId":"qz-Django-46-50--dj46-n1-detect","front":"How do you catch an N+1 regression before it reaches production?","back":"Assert the query count in a test with assertNumQueries, and watch Debug Toolbar in development","keyPoints":["assertNumQueries turns a performance property into a failing test. Code review misses N+1 reliably, because the extra query is triggered by attribute access far from the queryset."],"href":"/python-fullstack-interview/questions/Django-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-6-10--dj6-generated","moduleId":"pythonfs","cardId":"qz-Django-6-10--dj6-generated","front":"You need a column that is always quantity * unit_price and can never drift. Best option in Django 5?","back":"GeneratedField - the database computes it","keyPoints":["GeneratedField (Django 5.0) makes the database compute the value, so it stays correct for rows created outside the ORM too. save() overrides and signals are both bypassed by bulk operations and raw SQL."],"href":"/python-fullstack-interview/questions/Django-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-6-10--dj6-dbdefault","moduleId":"pythonfs","cardId":"qz-Django-6-10--dj6-dbdefault","front":"How does db_default differ from default?","back":"default is applied by Python; db_default is applied by the database, so it also covers inserts that bypass the ORM","keyPoints":["A Python-side default never reaches rows created by raw SQL or another service writing to the same table. db_default (Django 5.0) pushes it into the schema, and lets you use database functions like Now()."],"href":"/python-fullstack-interview/questions/Django-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-21-25--dj21-selectrelated","moduleId":"pythonfs","cardId":"qz-Django-21-25--dj21-selectrelated","front":"When do you use prefetch_related rather than select_related?","back":"When the relation is ManyToMany or a reverse ForeignKey","keyPoints":["select_related does a SQL JOIN, which only works for single-valued forward relations. prefetch_related issues a second query and joins in Python, which is what multi-valued relations need."],"href":"/python-fullstack-interview/questions/Django-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-21-25--dj21-n1","moduleId":"pythonfs","cardId":"qz-Django-21-25--dj21-n1","front":"What is the signature of an N+1 query problem?","back":"One query for the list, then one additional query per row when a related field is accessed","keyPoints":["The count scales with the number of rows, which is why it looks fine in development and falls over in production. Django Debug Toolbar or a query-count assertion in tests will catch it."],"href":"/python-fullstack-interview/questions/Django-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-31-35--dj31-async-orm","moduleId":"pythonfs","cardId":"qz-Django-31-35--dj31-async-orm","front":"Inside an async Django view, how do you fetch one object?","back":"await Product.objects.aget(pk=1)","keyPoints":["Django 4.1 added the a-prefixed async query API: aget, acreate, acount, afirst, plus async iteration - and 4.2 added asave. sync_to_async is still needed for operations with no async variant, but it is no longer the default answer."],"href":"/python-fullstack-interview/questions/Django-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-Django-31-35--dj31-async-nuance","moduleId":"pythonfs","cardId":"qz-Django-31-35--dj31-async-nuance","front":"What is true about Django's async ORM methods?","back":"They provide an async-safe interface but still execute the query on a thread underneath","keyPoints":["They give you correctness and clean syntax inside an event loop, not true async I/O to the database. Fully async backends are still in progress - saying this is what separates a real answer from a memorised one."],"href":"/python-fullstack-interview/questions/Django-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-01-05--fa01-asgi","moduleId":"pythonfs","cardId":"qz-FastAPI-01-05--fa01-asgi","front":"What does ASGI provide that WSGI does not?","back":"Support for long-lived connections and async callables - WebSockets, SSE, background lifespan","keyPoints":["WSGI is one synchronous call per request with no notion of a persistent connection. ASGI's event-based interface is what makes WebSockets and concurrent I/O possible in the first place."],"href":"/python-fullstack-interview/questions/FastAPI-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-01-05--fa01-typehints","moduleId":"pythonfs","cardId":"qz-FastAPI-01-05--fa01-typehints","front":"How does FastAPI use your type hints?","back":"For request parsing, validation, serialisation and the OpenAPI schema - all from the same annotations","keyPoints":["That single-source-of-truth design is the framework's core idea: the annotation you write for the type checker is the same one that validates input and generates the docs."],"href":"/python-fullstack-interview/questions/FastAPI-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-01-05--fa01-blocking","moduleId":"pythonfs","cardId":"qz-FastAPI-01-05--fa01-blocking","front":"You put a blocking DB call inside `async def` without awaiting anything. What happens?","back":"It blocks the event loop, stalling every other concurrent request","keyPoints":["This is the most common FastAPI performance bug. Use `def` (FastAPI runs it in a threadpool) or an async driver. `async def` with blocking code is the worst of both worlds."],"href":"/python-fullstack-interview/questions/FastAPI-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-06-10--fa06-path-query","moduleId":"pythonfs","cardId":"qz-FastAPI-06-10--fa06-path-query","front":"How does FastAPI decide whether a parameter is a path or query parameter?","back":"If the name appears in the route path it is a path parameter; otherwise it is a query parameter","keyPoints":["Scalar types not named in the path become query parameters; Pydantic models become the request body. That convention is why most routes need no explicit Path()/Query()."],"href":"/python-fullstack-interview/questions/FastAPI-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-06-10--fa06-docs","moduleId":"pythonfs","cardId":"qz-FastAPI-06-10--fa06-docs","front":"Where do the /docs and /redoc pages come from?","back":"Both render the OpenAPI schema FastAPI generates from your type hints and Pydantic models","keyPoints":["One schema, two renderers. Because it is derived from the code, the docs cannot drift from the implementation - which is the main reason people adopt the framework."],"href":"/python-fullstack-interview/questions/FastAPI-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-06-10--fa06-order","moduleId":"pythonfs","cardId":"qz-FastAPI-06-10--fa06-order","front":"You declare /users/me after /users/{user_id}. What happens when you request /users/me?","back":"It matches /users/{user_id} with user_id='me', because routes are matched in declaration order","keyPoints":["First match wins, so fixed paths must be declared before their parameterised siblings. A classic hard-to-spot bug."],"href":"/python-fullstack-interview/questions/FastAPI-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-21-25--fa21-streaming","moduleId":"pythonfs","cardId":"qz-FastAPI-21-25--fa21-streaming","front":"When should you return a StreamingResponse?","back":"When the payload is large or generated incrementally, so you avoid buffering it all in memory","keyPoints":["A normal response builds the whole body first. Streaming yields chunks, keeping memory flat for a large export and letting the client start receiving immediately."],"href":"/python-fullstack-interview/questions/FastAPI-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-21-25--fa21-middleware-cost","moduleId":"pythonfs","cardId":"qz-FastAPI-21-25--fa21-middleware-cost","front":"What is the risk of reading the request body inside custom middleware?","back":"The body is a stream and can only be consumed once - reading it without restoring it leaves the route handler with nothing","keyPoints":["You must buffer and re-attach the body, which also removes the memory benefit of streaming. Prefer a dependency for anything that needs the parsed body."],"href":"/python-fullstack-interview/questions/FastAPI-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-21-25--fa21-upload","moduleId":"pythonfs","cardId":"qz-FastAPI-21-25--fa21-upload","front":"Why prefer UploadFile over bytes for file uploads?","back":"UploadFile spools to disk beyond a threshold, so a large upload does not sit entirely in memory","keyPoints":["Declaring the parameter as bytes loads the whole file into RAM. UploadFile gives you a file-like object with an async interface and spooling built in."],"href":"/python-fullstack-interview/questions/FastAPI-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-26-30--fa26-cors-wildcard","moduleId":"pythonfs","cardId":"qz-FastAPI-26-30--fa26-cors-wildcard","front":"Why can you not combine allow_origins=['*'] with allow_credentials=True?","back":"The CORS spec forbids it - a wildcard origin with credentials would let any site make authenticated requests","keyPoints":["Browsers reject the combination outright. With credentials you must echo back a specific allowed origin, which means maintaining a real allowlist."],"href":"/python-fullstack-interview/questions/FastAPI-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-26-30--fa26-exception-handler","moduleId":"pythonfs","cardId":"qz-FastAPI-26-30--fa26-exception-handler","front":"What does a custom exception handler give you over try/except in each route?","back":"One place to map a domain exception to an HTTP response, so routes raise meaningfully and stay clean","keyPoints":["Routes raise UserNotFound; the handler turns it into a 404 with a consistent body. Without it, every route repeats the same translation logic."],"href":"/python-fullstack-interview/questions/FastAPI-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-26-30--fa26-oauth-flow","moduleId":"pythonfs","cardId":"qz-FastAPI-26-30--fa26-oauth-flow","front":"In the OAuth2 password flow, what does the /token endpoint return?","back":"An access token the client sends back in the Authorization header on subsequent requests","keyPoints":["Credentials are exchanged once for a token. Note the detail that trips people up: the endpoint expects form data, not JSON - hence OAuth2PasswordRequestForm."],"href":"/python-fullstack-interview/questions/FastAPI-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-36-40--fa36-bcrypt","moduleId":"pythonfs","cardId":"qz-FastAPI-36-40--fa36-bcrypt","front":"Why use bcrypt or argon2 rather than SHA-256 for passwords?","back":"They are deliberately slow and salted, making brute-force and rainbow-table attacks impractical","keyPoints":["SHA-256 is fast by design, which is exactly wrong for passwords - an attacker can try billions per second. Password hashes need a tunable work factor."],"href":"/python-fullstack-interview/questions/FastAPI-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-36-40--fa36-scopes","moduleId":"pythonfs","cardId":"qz-FastAPI-36-40--fa36-scopes","front":"What do OAuth2 security scopes give you beyond authentication?","back":"Fine-grained authorisation - a token can be limited to a subset of permissions","keyPoints":["Authentication is who you are; scopes are what this particular token may do. FastAPI surfaces required scopes in the OpenAPI schema too."],"href":"/python-fullstack-interview/questions/FastAPI-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-36-40--fa36-rbac-where","moduleId":"pythonfs","cardId":"qz-FastAPI-36-40--fa36-rbac-where","front":"Where does an RBAC check belong in a FastAPI app?","back":"In a dependency, so it is declarative, reusable and visible in the route signature","keyPoints":["A dependency composes with the rest of the injection system and can be applied per-route or per-router. Middleware runs before routing, so it does not know which permission applies."],"href":"/python-fullstack-interview/questions/FastAPI-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-41-45--fa41-lifespan","moduleId":"pythonfs","cardId":"qz-FastAPI-41-45--fa41-lifespan","front":"Why did lifespan replace @app.on_event('startup')?","back":"A single lifespan context manager keeps startup and shutdown together and makes shared resources explicit; on_event is deprecated","keyPoints":["Setup before yield, teardown after - the same shape as any context manager. It also lets you attach state to the app cleanly rather than through globals."],"href":"/python-fullstack-interview/questions/FastAPI-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-41-45--fa41-sse-ws","moduleId":"pythonfs","cardId":"qz-FastAPI-41-45--fa41-sse-ws","front":"When is SSE a better choice than WebSockets?","back":"When updates flow server-to-client only - SSE is plain HTTP, reconnects automatically, and needs no protocol upgrade","keyPoints":["Notifications, progress bars and live feeds are one-directional. Reaching for WebSockets there adds protocol upgrade, proxy configuration and reconnect logic you did not need."],"href":"/python-fullstack-interview/questions/FastAPI-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-41-45--fa41-openapi","moduleId":"pythonfs","cardId":"qz-FastAPI-41-45--fa41-openapi","front":"Why customise response_model and status_code on a route?","back":"It controls exactly what is serialised out and documents the real contract - response_model also strips fields not declared","keyPoints":["The filtering behaviour is a security feature: returning an ORM object with a password_hash is harmless if the response_model does not declare that field."],"href":"/python-fullstack-interview/questions/FastAPI-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-46-50--fa46-override","moduleId":"pythonfs","cardId":"qz-FastAPI-46-50--fa46-override","front":"What does app.dependency_overrides give you in tests?","back":"A way to swap a real dependency (database, auth) for a fake without touching application code","keyPoints":["This is the practical payoff of dependency injection. Point get_db at a transactional test session and the whole app runs against it unchanged."],"href":"/python-fullstack-interview/questions/FastAPI-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-46-50--fa46-ratelimit-where","moduleId":"pythonfs","cardId":"qz-FastAPI-46-50--fa46-ratelimit-where","front":"Where should rate limiting state live for a multi-instance deployment?","back":"In shared storage such as Redis, or the limit is per-instance and effectively N times higher","keyPoints":["An in-memory counter behind a load balancer means each instance enforces its own limit independently. With four instances a '100/min' limit becomes 400/min."],"href":"/python-fullstack-interview/questions/FastAPI-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-46-50--fa46-testclient","moduleId":"pythonfs","cardId":"qz-FastAPI-46-50--fa46-testclient","front":"What does TestClient actually do?","back":"Drives the ASGI app in-process, so tests are fast and need no network","keyPoints":["No socket, no port conflicts, no startup wait. That is what makes route tests fast enough to run on every save."],"href":"/python-fullstack-interview/questions/FastAPI-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-51-55--fa51-uvicorn-gunicorn","moduleId":"pythonfs","cardId":"qz-FastAPI-51-55--fa51-uvicorn-gunicorn","front":"What is the usual relationship between Uvicorn and Gunicorn?","back":"Gunicorn manages a pool of Uvicorn worker processes, adding supervision and graceful restarts","keyPoints":["Uvicorn is the ASGI server; Gunicorn contributes process management. Uvicorn can also manage its own workers, which is often enough in a container orchestrator."],"href":"/python-fullstack-interview/questions/FastAPI-51-55#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-51-55--fa51-docker-layer","moduleId":"pythonfs","cardId":"qz-FastAPI-51-55--fa51-docker-layer","front":"Why copy requirements and install dependencies before copying application code in a Dockerfile?","back":"Docker caches layers - dependencies change rarely, so a code change then rebuilds only the last layer","keyPoints":["Copy everything first and every one-line code change reinstalls the entire dependency tree. Ordering layers by rate of change is the core Dockerfile skill."],"href":"/python-fullstack-interview/questions/FastAPI-51-55#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-51-55--fa51-structured-logs","moduleId":"pythonfs","cardId":"qz-FastAPI-51-55--fa51-structured-logs","front":"What is the main benefit of structured (JSON) logging in production?","back":"Logs become queryable - you can filter and aggregate by field rather than grepping free text","keyPoints":["Adding a request id to every line is what lets you reconstruct one request's path across services. Free-text logs make that a text-search exercise."],"href":"/python-fullstack-interview/questions/FastAPI-51-55#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-56-60--fa56-session-scope","moduleId":"pythonfs","cardId":"qz-FastAPI-56-60--fa56-session-scope","front":"Why should a database session be scoped per request rather than shared globally?","back":"A shared session mixes transactions between concurrent requests and is not safe under concurrency","keyPoints":["One request's rollback would discard another's pending work. The yield-dependency pattern gives each request its own session and guarantees cleanup."],"href":"/python-fullstack-interview/questions/FastAPI-56-60#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-56-60--fa56-pool","moduleId":"pythonfs","cardId":"qz-FastAPI-56-60--fa56-pool","front":"What happens when the connection pool is exhausted under load?","back":"Requests block waiting for a free connection, and eventually time out","keyPoints":["It surfaces as latency, not errors, which makes it confusing. Total connections = workers × pool_size, and that has to stay under the database's own limit."],"href":"/python-fullstack-interview/questions/FastAPI-56-60#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-56-60--fa56-idempotency","moduleId":"pythonfs","cardId":"qz-FastAPI-56-60--fa56-idempotency","front":"Why do payment and order-creation endpoints need an idempotency key?","back":"So a client retry after a timeout does not create a second charge - the server recognises the repeat and returns the original result","keyPoints":["A timeout does not tell the client whether the write happened. Without idempotency the safe choices are 'retry and risk duplicates' or 'do not retry and risk losing it'."],"href":"/python-fullstack-interview/questions/FastAPI-56-60#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-61-65--fa61-presigned","moduleId":"pythonfs","cardId":"qz-FastAPI-61-65--fa61-presigned","front":"Why use a pre-signed S3 URL rather than proxying uploads through your API?","back":"The file goes straight from client to S3, so your app does not spend bandwidth, memory or worker time on the transfer","keyPoints":["A 500MB upload through your API occupies a worker for its whole duration. The pre-signed URL keeps your service on the control path only."],"href":"/python-fullstack-interview/questions/FastAPI-61-65#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-61-65--fa61-router","moduleId":"pythonfs","cardId":"qz-FastAPI-61-65--fa61-router","front":"What does APIRouter give a growing project?","back":"Modularity - routes grouped by domain, with shared prefixes, tags and dependencies applied per group","keyPoints":["Router-level dependencies are the practical win: apply an auth dependency to an entire admin router rather than repeating it on twenty routes."],"href":"/python-fullstack-interview/questions/FastAPI-61-65#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-61-65--fa61-ws-scale","moduleId":"pythonfs","cardId":"qz-FastAPI-61-65--fa61-ws-scale","front":"What breaks when you scale a WebSocket notification service to several instances?","back":"Connections are held by one instance, so an event on another instance cannot reach them without a shared pub/sub layer","keyPoints":["Each instance only knows its own sockets. Redis pub/sub or a message broker is what lets any instance broadcast to every connected client."],"href":"/python-fullstack-interview/questions/FastAPI-61-65#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-11-15--fa11-modeldump","moduleId":"pythonfs","cardId":"qz-FastAPI-11-15--fa11-modeldump","front":"In Pydantic v2, how do you convert a model to a dict?","back":".model_dump()","keyPoints":["v2 renamed most of the public API: .dict() became .model_dump(), .json() became .model_dump_json(), and parse_obj() became model_validate(). Using the v1 names is the clearest sign someone has not touched the framework recently."],"href":"/python-fullstack-interview/questions/FastAPI-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-11-15--fa11-fromattributes","moduleId":"pythonfs","cardId":"qz-FastAPI-11-15--fa11-fromattributes","front":"Which config lets a Pydantic v2 model read from a SQLAlchemy object?","back":"model_config = ConfigDict(from_attributes=True)","keyPoints":["v2 replaced the inner `class Config` with a `model_config` attribute, and renamed orm_mode to from_attributes. Both halves changed, which is why the v1 snippet fails in two ways at once."],"href":"/python-fullstack-interview/questions/FastAPI-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-11-15--fa11-validator","moduleId":"pythonfs","cardId":"qz-FastAPI-11-15--fa11-validator","front":"Which decorator validates a single field in Pydantic v2?","back":"@field_validator","keyPoints":["@validator became @field_validator, and @root_validator became @model_validator. @field_validator is usually stacked on @classmethod; a mode='after' @model_validator takes self instead."],"href":"/python-fullstack-interview/questions/FastAPI-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-16-20--fa16-annotated","moduleId":"pythonfs","cardId":"qz-FastAPI-16-20--fa16-annotated","front":"Why is Annotated[Session, Depends(get_db)] preferred over a default value?","back":"It keeps the type honest for checkers and frees the parameter's default slot","keyPoints":["The old form burns the default slot on framework metadata, so the parameter cannot have a real default and type checkers see a Depends object rather than a Session. Annotated also lets you alias the whole thing and reuse it across routes."],"href":"/python-fullstack-interview/questions/FastAPI-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-16-20--fa16-yield","moduleId":"pythonfs","cardId":"qz-FastAPI-16-20--fa16-yield","front":"Why does a database-session dependency use yield rather than return?","back":"Code after yield runs as teardown once the response is finished, so the session is reliably closed","keyPoints":["A yield dependency behaves like a context manager: setup before, teardown after. That is what guarantees the session closes even if the path operation raises."],"href":"/python-fullstack-interview/questions/FastAPI-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-31-35--fa31-sqla2","moduleId":"pythonfs","cardId":"qz-FastAPI-31-35--fa31-sqla2","front":"Which is SQLAlchemy 2.0 style?","back":"class Base(DeclarativeBase): pass; id: Mapped[int] = mapped_column(primary_key=True)","keyPoints":["2.0 replaced the declarative_base() factory with a real base class and introduced Mapped[]/mapped_column(), so models carry static types a checker can actually use."],"href":"/python-fullstack-interview/questions/FastAPI-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-FastAPI-31-35--fa31-select","moduleId":"pythonfs","cardId":"qz-FastAPI-31-35--fa31-select","front":"What is the 2.0-style way to run a query?","back":"session.scalars(select(User)).all()","keyPoints":["2.0 standardised on select() with scalars()/execute(). The old Query API still works - it is legacy, not deprecated - and mixing the two is a common source of confusion in older codebases."],"href":"/python-fullstack-interview/questions/FastAPI-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-01-05--html1-semantic","moduleId":"pythonfs","cardId":"qz-HTML-01-05--html1-semantic","front":"What is the practical benefit of semantic HTML over div soup?","back":"Screen readers, search engines and browser reader modes can understand the structure - and it needs less CSS","keyPoints":["A <nav> tells assistive technology this is navigation; a <div class='nav'> tells it nothing. Accessibility is the concrete, testable benefit."],"href":"/python-fullstack-interview/questions/HTML-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-01-05--html1-block-inline","moduleId":"pythonfs","cardId":"qz-HTML-01-05--html1-block-inline","front":"What is the core difference between block and inline elements?","back":"Block elements start a new line and take full available width; inline elements flow in text and ignore width/height","keyPoints":["The consequence that catches people: setting width or vertical margin on a pure inline element does nothing. inline-block gives you both behaviours."],"href":"/python-fullstack-interview/questions/HTML-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-01-05--html1-validation","moduleId":"pythonfs","cardId":"qz-HTML-01-05--html1-validation","front":"Why can you never rely on HTML5 form validation alone?","back":"It is a client-side convenience and trivially bypassed - the server must validate independently","keyPoints":["Anyone can disable it in devtools or post directly to the endpoint. Client validation is for user experience; server validation is for correctness and security."],"href":"/python-fullstack-interview/questions/HTML-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-06-10--html6-svg-canvas","moduleId":"pythonfs","cardId":"qz-HTML-06-10--html6-svg-canvas","front":"When should you choose SVG over Canvas?","back":"For scalable, accessible graphics with few elements you want in the DOM - charts, icons, diagrams","keyPoints":["SVG elements are real DOM nodes: styleable, clickable, screen-reader accessible, resolution independent. Canvas is a pixel buffer - far faster for many objects, but the content is opaque."],"href":"/python-fullstack-interview/questions/HTML-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-06-10--html6-viewport","moduleId":"pythonfs","cardId":"qz-HTML-06-10--html6-viewport","front":"What does the viewport meta tag actually do?","back":"Tells mobile browsers to use the device width rather than emulating a ~980px desktop viewport","keyPoints":["Without it a mobile browser renders as a wide desktop and scales down, so your media queries never match and everything looks tiny."],"href":"/python-fullstack-interview/questions/HTML-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-06-10--html6-void","moduleId":"pythonfs","cardId":"qz-HTML-06-10--html6-void","front":"What is a void element?","back":"An element that cannot have children and has no closing tag, such as <img>, <br> and <input>","keyPoints":["The self-closing slash is optional in HTML5 and required in JSX/XHTML - which is why React insists on <br /> while plain HTML accepts <br>."],"href":"/python-fullstack-interview/questions/HTML-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-11-15--html11-async-defer","moduleId":"pythonfs","cardId":"qz-HTML-11-15--html11-async-defer","front":"What is the difference between async and defer on a script tag?","back":"Both download in parallel; async executes as soon as it lands (order not guaranteed), defer waits for parsing and runs in order","keyPoints":["Use defer for application code that depends on the DOM or on script order. Use async for independent third-party tags like analytics."],"href":"/python-fullstack-interview/questions/HTML-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-11-15--html11-storage","moduleId":"pythonfs","cardId":"qz-HTML-11-15--html11-storage","front":"What is the key difference between localStorage and sessionStorage?","back":"sessionStorage is cleared when the tab closes and is not shared between tabs; localStorage persists and is shared per origin","keyPoints":["Neither is sent to the server - that is the difference from cookies. And neither is secure storage: never put a token you cannot afford to have XSS-stolen in either."],"href":"/python-fullstack-interview/questions/HTML-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-11-15--html11-doctype","moduleId":"pythonfs","cardId":"qz-HTML-11-15--html11-doctype","front":"What does <!DOCTYPE html> do?","back":"Triggers standards mode - without it browsers fall back to quirks mode with legacy box-model behaviour","keyPoints":["Quirks mode is the real consequence: the box model and several layout rules change, so a page can look subtly wrong everywhere."],"href":"/python-fullstack-interview/questions/HTML-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-16-20--html16-aria-first","moduleId":"pythonfs","cardId":"qz-HTML-16-20--html16-aria-first","front":"What is the first rule of ARIA?","back":"Do not use ARIA if a native HTML element already provides the semantics and behaviour","keyPoints":["A <button> is focusable, keyboard-activatable and announced correctly for free. A <div role='button'> gives you the announcement and none of the behaviour - you have to rebuild it all."],"href":"/python-fullstack-interview/questions/HTML-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-16-20--html16-id-class","moduleId":"pythonfs","cardId":"qz-HTML-16-20--html16-id-class","front":"When should you use an id rather than a class?","back":"For a single unique element that needs to be targeted - fragment links, label/for, aria-labelledby","keyPoints":["Styling by id works but its high specificity makes overrides painful. Use ids for identity and relationships, classes for styling."],"href":"/python-fullstack-interview/questions/HTML-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-HTML-16-20--html16-dataset","moduleId":"pythonfs","cardId":"qz-HTML-16-20--html16-dataset","front":"What are data-* attributes for?","back":"Attaching custom metadata to an element, readable via element.dataset, without inventing non-standard attributes","keyPoints":["They keep markup valid and are readable from both JS and CSS attribute selectors. They are visible to anyone, so nothing sensitive belongs there."],"href":"/python-fullstack-interview/questions/HTML-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-01-05--css1-specificity","moduleId":"pythonfs","cardId":"qz-CSS-01-05--css1-specificity","front":"Order these by specificity, lowest first: class, inline style, element, id.","back":"element < class < id < inline","keyPoints":["Element (0,0,1) < class/attribute/pseudo-class (0,1,0) < id (1,0,0) < inline. !important overrides all of it, which is why reaching for it usually signals a specificity problem rather than solving one."],"href":"/python-fullstack-interview/questions/CSS-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-01-05--css1-absolute","moduleId":"pythonfs","cardId":"qz-CSS-01-05--css1-absolute","front":"What is position: absolute positioned relative to?","back":"The nearest ancestor with a position other than static, falling back to the initial containing block","keyPoints":["Forgetting position: relative on the intended parent is why an absolutely positioned element so often escapes to the page corner."],"href":"/python-fullstack-interview/questions/CSS-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-01-05--css1-pseudo","moduleId":"pythonfs","cardId":"qz-CSS-01-05--css1-pseudo","front":"What distinguishes a pseudo-class from a pseudo-element?","back":"A pseudo-class targets a state of an existing element (:hover); a pseudo-element creates a sub-element that is not in the DOM (::before)","keyPoints":["The double colon signals 'this is not a real element'. ::before and ::after need a content property, even an empty string, before they render."],"href":"/python-fullstack-interview/questions/CSS-01-05#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-06-10--css6-boxsizing","moduleId":"pythonfs","cardId":"qz-CSS-06-10--css6-boxsizing","front":"What does box-sizing: border-box change?","back":"width and height include padding and border, so an element declared 200px wide actually occupies 200px","keyPoints":["With the default content-box, padding and border are added on top, so width: 100% plus padding overflows its container. Nearly every reset sets border-box globally."],"href":"/python-fullstack-interview/questions/CSS-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-06-10--css6-flex-grid","moduleId":"pythonfs","cardId":"qz-CSS-06-10--css6-flex-grid","front":"When is Grid the better tool than Flexbox?","back":"For two-dimensional layout where rows and columns must align together; Flexbox handles one axis at a time","keyPoints":["Page-level layout is usually Grid; a row of buttons or a nav bar is Flexbox. They compose well - Grid for the frame, Flex inside the cells."],"href":"/python-fullstack-interview/questions/CSS-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-06-10--css6-mobile-first","moduleId":"pythonfs","cardId":"qz-CSS-06-10--css6-mobile-first","front":"Why are min-width media queries preferred over max-width?","back":"Mobile-first: the base styles serve the smallest, cheapest device and enhancements are added upward","keyPoints":["It also produces simpler CSS - you add capability as space allows rather than repeatedly undoing desktop styles for small screens."],"href":"/python-fullstack-interview/questions/CSS-06-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-11-15--css11-rem-em","moduleId":"pythonfs","cardId":"qz-CSS-11-15--css11-rem-em","front":"What is the difference between rem and em?","back":"em is relative to the element's own font size and compounds when nested; rem is relative to the root, so it does not","keyPoints":["Nested ems multiply, which is how you end up with unexpectedly tiny or huge text three levels deep. rem is predictable and still respects the user's browser font-size setting - unlike px."],"href":"/python-fullstack-interview/questions/CSS-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-11-15--css11-stacking","moduleId":"pythonfs","cardId":"qz-CSS-11-15--css11-stacking","front":"Why might z-index: 9999 still not put an element on top?","back":"z-index only compares within a stacking context - a parent with transform, opacity or filter creates one and traps the child","keyPoints":["This is the single most confusing part of CSS layering. An opacity of 0.99 on an ancestor is enough to create a context the child can never escape."],"href":"/python-fullstack-interview/questions/CSS-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-11-15--css11-display-visibility","moduleId":"pythonfs","cardId":"qz-CSS-11-15--css11-display-visibility","front":"How do display: none and visibility: hidden differ?","back":"display: none removes the element from layout entirely; visibility: hidden keeps its space reserved","keyPoints":["There is also an accessibility consequence: both hide content from screen readers, whereas clipping techniques like .sr-only keep it announced while visually hidden."],"href":"/python-fullstack-interview/questions/CSS-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-16-20--css16-shadow-dom","moduleId":"pythonfs","cardId":"qz-CSS-16-20--css16-shadow-dom","front":"What does the Shadow DOM provide?","back":"Encapsulation - styles inside do not leak out and outside styles do not leak in","keyPoints":["That isolation is what makes web components safe to drop into any page. It is also why styling one from outside needs explicit hooks like ::part or CSS custom properties."],"href":"/python-fullstack-interview/questions/CSS-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-16-20--css16-margin-padding","moduleId":"pythonfs","cardId":"qz-CSS-16-20--css16-margin-padding","front":"Which behaviour is unique to margin, not padding?","back":"It can be negative, and adjacent vertical margins collapse into one","keyPoints":["Margin collapsing surprises everyone at least once: two stacked 20px margins give 20px of gap, not 40px. Flex and grid containers do not collapse margins, which is one reason gap is easier."],"href":"/python-fullstack-interview/questions/CSS-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-CSS-16-20--css16-vh-mobile","moduleId":"pythonfs","cardId":"qz-CSS-16-20--css16-vh-mobile","front":"Why does height: 100vh often overflow on mobile?","back":"vh historically ignored the dynamic browser chrome, so the element is taller than the visible area - dvh addresses this","keyPoints":["The address bar hides and shows as you scroll, changing the visible height. The dynamic viewport units - dvh, svh, lvh - exist precisely for this."],"href":"/python-fullstack-interview/questions/CSS-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-1-5--js1-eqeq","moduleId":"pythonfs","cardId":"qz-JavaScript-1-5--js1-eqeq","front":"Why prefer === over ==?","back":"== coerces types first, producing surprises like '' == 0 and null == undefined being true","keyPoints":["The one common exception: `x == null` is a deliberate idiom for 'null or undefined'. Otherwise the coercion table is not worth memorising - just use ===."],"href":"/python-fullstack-interview/questions/JavaScript-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-1-5--js1-tdz","moduleId":"pythonfs","cardId":"qz-JavaScript-1-5--js1-tdz","front":"What is the temporal dead zone?","back":"The span between a let/const binding entering scope and being initialised, where accessing it throws ReferenceError","keyPoints":["let and const are hoisted, but unlike var they are not initialised to undefined. The TDZ is what turns a silent undefined bug into a loud error."],"href":"/python-fullstack-interview/questions/JavaScript-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-1-5--js1-const","moduleId":"pythonfs","cardId":"qz-JavaScript-1-5--js1-const","front":"What does const actually guarantee?","back":"The binding cannot be reassigned - the object it points at can still be mutated","keyPoints":["const arr = []; arr.push(1) is perfectly legal. Object.freeze() is what makes the contents immutable, and even that is shallow."],"href":"/python-fullstack-interview/questions/JavaScript-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-6-10--js6-this","moduleId":"pythonfs","cardId":"qz-JavaScript-6-10--js6-this","front":"How does an arrow function differ in its handling of `this`?","back":"It has no own this - it closes over this from the enclosing lexical scope","keyPoints":["That is why arrows fixed the old `const self = this` pattern in callbacks - and why they are wrong as object methods or constructors, where you want dynamic this."],"href":"/python-fullstack-interview/questions/JavaScript-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-6-10--js6-closure","moduleId":"pythonfs","cardId":"qz-JavaScript-6-10--js6-closure","front":"What is a closure?","back":"A function together with the lexical environment it captured, keeping those variables alive after the outer call returns","keyPoints":["It is the mechanism behind private state, memoisation and the classic 'var in a loop' bug - where all callbacks close over the same binding."],"href":"/python-fullstack-interview/questions/JavaScript-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-6-10--js6-hoist-fn","moduleId":"pythonfs","cardId":"qz-JavaScript-6-10--js6-hoist-fn","front":"Which can you call before its definition in the source?","back":"A function declaration","keyPoints":["Function declarations are hoisted with their body. Expressions - including arrows - are only bound when the assignment runs, so calling early hits the TDZ or undefined."],"href":"/python-fullstack-interview/questions/JavaScript-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-11-15--js11-proto","moduleId":"pythonfs","cardId":"qz-JavaScript-11-15--js11-proto","front":"What does JavaScript use instead of classical inheritance?","back":"A prototype chain - lookups that miss on an object continue up through its prototype","keyPoints":["ES6 class syntax is sugar over the same prototype mechanism. Understanding the chain is what makes instanceof, Object.create and the odd `__proto__` bug comprehensible."],"href":"/python-fullstack-interview/questions/JavaScript-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-11-15--js11-bind","moduleId":"pythonfs","cardId":"qz-JavaScript-11-15--js11-bind","front":"How do call, apply and bind differ?","back":"call and apply invoke immediately (arguments listed vs as an array); bind returns a new function with this fixed","keyPoints":["bind is what you reach for when passing a method as a callback - it produces a permanently bound copy rather than calling anything."],"href":"/python-fullstack-interview/questions/JavaScript-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-11-15--js11-generator","moduleId":"pythonfs","cardId":"qz-JavaScript-11-15--js11-generator","front":"What does a JavaScript generator function return when called?","back":"An iterator object - nothing in the body runs until you call next()","keyPoints":["Lazy by construction, and two-way: next(value) makes the paused yield expression evaluate to that value, which is how async libraries were built before async/await."],"href":"/python-fullstack-interview/questions/JavaScript-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-21-25--js21-bubbling","moduleId":"pythonfs","cardId":"qz-JavaScript-21-25--js21-bubbling","front":"What is the order of event propagation?","back":"Capturing from the root down to the target, then bubbling from the target back up","keyPoints":["Listeners bubble by default; pass { capture: true } to catch the downward phase. stopPropagation halts the rest of the journey, which is why it can silently break delegated handlers elsewhere."],"href":"/python-fullstack-interview/questions/JavaScript-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-21-25--js21-vdom","moduleId":"pythonfs","cardId":"qz-JavaScript-21-25--js21-vdom","front":"What is the virtual DOM actually for?","back":"It lets you write declarative UI while the library batches and minimises the real DOM mutations","keyPoints":["Hand-written imperative DOM updates can beat it. The value is that you describe the target state and never manage transitions yourself - correctness and maintainability, not raw speed."],"href":"/python-fullstack-interview/questions/JavaScript-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-21-25--js21-settimeout-0","moduleId":"pythonfs","cardId":"qz-JavaScript-21-25--js21-settimeout-0","front":"What does setTimeout(fn, 0) actually do?","back":"Queues fn as a macrotask, so it runs after the current synchronous code and after pending microtasks","keyPoints":["The 0 is a minimum delay, not a promise of immediacy. It is the classic way to yield to the browser so it can paint before continuing."],"href":"/python-fullstack-interview/questions/JavaScript-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-26-30--js26-delegation","moduleId":"pythonfs","cardId":"qz-JavaScript-26-30--js26-delegation","front":"What problem does event delegation solve?","back":"One listener on a parent handles events from many children, including ones added later - fewer listeners, works with dynamic content","keyPoints":["Attaching a handler to a thousand rows costs memory and misses rows added afterwards. One listener on the container plus event.target.closest() handles both."],"href":"/python-fullstack-interview/questions/JavaScript-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-26-30--js26-debounce-throttle","moduleId":"pythonfs","cardId":"qz-JavaScript-26-30--js26-debounce-throttle","front":"When would you throttle rather than debounce?","back":"For a scroll or resize handler, where you want regular updates during the event rather than only at the end","keyPoints":["Debounce waits for quiet - right for 'user finished typing'. Throttle guarantees a maximum rate - right for 'keep updating while scrolling but not 200 times a second'."],"href":"/python-fullstack-interview/questions/JavaScript-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-26-30--js26-cors-who","moduleId":"pythonfs","cardId":"qz-JavaScript-26-30--js26-cors-who","front":"Who enforces CORS?","back":"The browser - it blocks the response from being read by script based on the server's headers","keyPoints":["This is why curl and a backend HTTP client are unaffected. The request often reaches the server and runs; the browser just refuses to hand the response to your JavaScript."],"href":"/python-fullstack-interview/questions/JavaScript-26-30#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-31-35--js31-cookie-storage","moduleId":"pythonfs","cardId":"qz-JavaScript-31-35--js31-cookie-storage","front":"What does a cookie do that localStorage does not?","back":"It is sent automatically with matching HTTP requests, and can be HttpOnly so JavaScript cannot read it","keyPoints":["HttpOnly is the security point: a token in localStorage is readable by any XSS on the page, while an HttpOnly cookie is not. Cookies then need CSRF protection in exchange."],"href":"/python-fullstack-interview/questions/JavaScript-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-31-35--js31-parallel","moduleId":"pythonfs","cardId":"qz-JavaScript-31-35--js31-parallel","front":"You need three independent API calls. What is the right approach?","back":"Promise.all - they run concurrently and total time is the slowest, not the sum","keyPoints":["Sequential awaits are the most common avoidable latency bug. Use Promise.allSettled when one failure should not discard the other results."],"href":"/python-fullstack-interview/questions/JavaScript-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-31-35--js31-json-limits","moduleId":"pythonfs","cardId":"qz-JavaScript-31-35--js31-json-limits","front":"What does JSON.stringify silently do to a Date and to undefined?","back":"Converts the Date to an ISO string and drops undefined object properties entirely","keyPoints":["So a round trip does not give you back what you put in - the Date comes back as a string. undefined in an array becomes null, but as an object value the key vanishes."],"href":"/python-fullstack-interview/questions/JavaScript-31-35#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-36-40--js36-undefined-debug","moduleId":"pythonfs","cardId":"qz-JavaScript-36-40--js36-undefined-debug","front":"You get 'cannot read properties of undefined'. What is the systematic fix?","back":"Find which access returned undefined - then guard with optional chaining or fix the upstream data","keyPoints":["Optional chaining silences the symptom. It is the right tool when absence is genuinely valid, and the wrong one when the data should have been there - that is a bug further upstream."],"href":"/python-fullstack-interview/questions/JavaScript-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-36-40--js36-lib-framework","moduleId":"pythonfs","cardId":"qz-JavaScript-36-40--js36-lib-framework","front":"What distinguishes a library from a framework?","back":"Inversion of control - you call a library; a framework calls your code","keyPoints":["That is the whole distinction. It also explains the trade: a framework gives more structure and takes more of your architectural choices away."],"href":"/python-fullstack-interview/questions/JavaScript-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-36-40--js36-perf","moduleId":"pythonfs","cardId":"qz-JavaScript-36-40--js36-perf","front":"What is usually the biggest front-end performance win?","back":"Shipping less JavaScript - code splitting, lazy loading and removing unused dependencies","keyPoints":["Bytes must be downloaded, parsed and executed before anything is interactive. Bundle size dominates almost every micro-optimisation."],"href":"/python-fullstack-interview/questions/JavaScript-36-40#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-41-45--js41-treeshake","moduleId":"pythonfs","cardId":"qz-JavaScript-41-45--js41-treeshake","front":"Why does tree-shaking need ES modules rather than CommonJS?","back":"ESM imports are static and analysable at build time; CommonJS require() is dynamic, so unused exports cannot be proven unreachable","keyPoints":["require() can be called conditionally with a computed path, so a bundler must assume everything might be used. Side effects in modules also block shaking, which is what sideEffects: false declares."],"href":"/python-fullstack-interview/questions/JavaScript-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-41-45--js41-microtask-order","moduleId":"pythonfs","cardId":"qz-JavaScript-41-45--js41-microtask-order","front":"Which queue drains first after the current synchronous code?","back":"The microtask queue (promises, queueMicrotask) - fully, before any macrotask","keyPoints":["Microtasks drain completely between every macrotask. A microtask that keeps scheduling more microtasks can starve the loop entirely and freeze the page."],"href":"/python-fullstack-interview/questions/JavaScript-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-41-45--js41-immutable","moduleId":"pythonfs","cardId":"qz-JavaScript-41-45--js41-immutable","front":"Why does React rely on immutable updates?","back":"Change detection compares references - mutating in place leaves the reference identical, so nothing re-renders","keyPoints":["state.items.push(x) then setState(state.items) is the classic no-op: same array reference, so React concludes nothing changed."],"href":"/python-fullstack-interview/questions/JavaScript-41-45#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-46-50--js46-spread-rest","moduleId":"pythonfs","cardId":"qz-JavaScript-46-50--js46-spread-rest","front":"What is the difference between spread and rest?","back":"Same ... syntax, opposite directions: spread expands a collection, rest gathers remaining values into one","keyPoints":["Position tells you which: on the right of an assignment or in a call it spreads; in a parameter list or destructuring target it gathers."],"href":"/python-fullstack-interview/questions/JavaScript-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-46-50--js46-spread-shallow","moduleId":"pythonfs","cardId":"qz-JavaScript-46-50--js46-spread-shallow","front":"What does { ...obj } copy?","back":"Own enumerable properties, one level deep - nested objects are still shared references","keyPoints":["The same shallow-copy trap as Python's copy(). structuredClone() gives a real deep copy in modern environments, without the JSON round-trip's loss of Dates and undefined."],"href":"/python-fullstack-interview/questions/JavaScript-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-46-50--js46-template","moduleId":"pythonfs","cardId":"qz-JavaScript-46-50--js46-template","front":"What can tagged template literals do that ordinary ones cannot?","back":"Pass the string parts and interpolated values to a function, which can escape or transform them - the basis of safe SQL and styled-components","keyPoints":["The tag function receives the static strings and the values separately, so it can treat interpolated values as data rather than code - which is exactly how injection is prevented."],"href":"/python-fullstack-interview/questions/JavaScript-46-50#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-1-5--re1-keys","moduleId":"pythonfs","cardId":"qz-React-1-5--re1-keys","front":"Why is using an array index as a key problematic?","back":"When the list reorders or items are inserted, indexes shift - so React matches the wrong elements and component state follows the wrong item","keyPoints":["The visible symptom is state attaching to the wrong row - a checked checkbox jumping after a deletion. Index keys are fine only for static lists that never reorder."],"href":"/python-fullstack-interview/questions/React-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-1-5--re1-props-state","moduleId":"pythonfs","cardId":"qz-React-1-5--re1-props-state","front":"What is the essential difference between props and state?","back":"Props come from the parent and are read-only to the component; state is owned and mutable by the component itself","keyPoints":["One-way data flow follows from this: to change a prop you ask the owner to change its state, usually via a callback passed down."],"href":"/python-fullstack-interview/questions/React-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-1-5--re1-jsx","moduleId":"pythonfs","cardId":"qz-React-1-5--re1-jsx","front":"What does JSX compile to?","back":"Function calls that create element descriptor objects - React.createElement or the automatic jsx runtime","keyPoints":["This is why JSX expressions are just values you can store and pass around, and why className is used instead of class - the attributes are JavaScript object keys."],"href":"/python-fullstack-interview/questions/React-1-5#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-11-15--re11-context-cost","moduleId":"pythonfs","cardId":"qz-React-11-15--re11-context-cost","front":"What is the main performance pitfall of Context?","back":"Every consumer re-renders when the value changes - and an inline object literal creates a new value on every parent render","keyPoints":["value={{ user, setUser }} is a fresh object each render, so every consumer re-renders regardless. Memoise the value, or split into separate contexts by update frequency."],"href":"/python-fullstack-interview/questions/React-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-11-15--re11-controlled","moduleId":"pythonfs","cardId":"qz-React-11-15--re11-controlled","front":"What makes an input 'controlled'?","back":"Its value comes from state and changes flow through onChange - React is the single source of truth","keyPoints":["Uncontrolled inputs keep their value in the DOM and you read it with a ref. Controlled is the default advice because validation and conditional logic need the value during render."],"href":"/python-fullstack-interview/questions/React-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-11-15--re11-lifting","moduleId":"pythonfs","cardId":"qz-React-11-15--re11-lifting","front":"When do you lift state up?","back":"When two or more components need to share or stay in sync with the same value - move it to their closest common ancestor","keyPoints":["Lifting further than necessary causes wide re-renders and prop drilling. The closest common ancestor is the rule, not the top of the tree."],"href":"/python-fullstack-interview/questions/React-11-15#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-16-20--re16-usememo-when","moduleId":"pythonfs","cardId":"qz-React-16-20--re16-usememo-when","front":"When is useMemo actually worth adding?","back":"For genuinely expensive computation, or to keep a reference stable for a memoised child or a dependency array","keyPoints":["It is not free - there is a comparison and retained memory on every render. Wrapping a cheap calculation usually costs more than it saves."],"href":"/python-fullstack-interview/questions/React-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-16-20--re16-memo-break","moduleId":"pythonfs","cardId":"qz-React-16-20--re16-memo-break","front":"Why might React.memo on a child not prevent re-renders?","back":"A prop is a new reference each render - an inline arrow or object literal defeats the shallow comparison","keyPoints":["onClick={() => ...} creates a new function every render, so the shallow prop check always fails. That is what useCallback is for - and why memo and useCallback usually arrive together."],"href":"/python-fullstack-interview/questions/React-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-16-20--re16-virtualization","moduleId":"pythonfs","cardId":"qz-React-16-20--re16-virtualization","front":"What problem does list virtualisation solve?","back":"Rendering only the visible rows, so a 10,000-row list creates a few dozen DOM nodes instead of 10,000","keyPoints":["DOM node count is the bottleneck for long lists. Virtualisation trades a little scroll complexity for a constant-size DOM."],"href":"/python-fullstack-interview/questions/React-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-21-25--re21-ssr-csr","moduleId":"pythonfs","cardId":"qz-React-21-25--re21-ssr-csr","front":"What is the main benefit of server-side rendering?","back":"Meaningful HTML arrives in the first response - better first paint on slow devices, and crawlable content","keyPoints":["CSR ships an empty div and a bundle; nothing is visible until it downloads, parses and runs. SSR moves that cost to the server, at the price of server load and hydration."],"href":"/python-fullstack-interview/questions/React-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-21-25--re21-hydration","moduleId":"pythonfs","cardId":"qz-React-21-25--re21-hydration","front":"What causes a hydration mismatch?","back":"The server-rendered HTML differing from the first client render - typically Date.now(), Math.random() or reading localStorage during render","keyPoints":["Anything non-deterministic or browser-only must move into useEffect, so the first client render matches the server exactly and the difference is applied afterwards."],"href":"/python-fullstack-interview/questions/React-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-21-25--re21-portal","moduleId":"pythonfs","cardId":"qz-React-21-25--re21-portal","front":"What does a portal change, and what does it not?","back":"It renders into a different DOM node, but events still bubble through the React tree, not the DOM tree","keyPoints":["That distinction is what makes portals work for modals: escape a parent's overflow or z-index while a click inside still reaches handlers on the logical React parent."],"href":"/python-fullstack-interview/questions/React-21-25#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-16-20--js16-microtask","moduleId":"pythonfs","cardId":"qz-JavaScript-16-20--js16-microtask","front":"console.log(1); setTimeout(()=>console.log(2)); Promise.resolve().then(()=>console.log(3)); console.log(4). Output order?","back":"1 4 3 2","keyPoints":["Synchronous code first (1, 4). Then the microtask queue drains before any macrotask, so the promise callback (3) runs before the timer (2). Microtasks always beat macrotasks."],"href":"/python-fullstack-interview/questions/JavaScript-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-JavaScript-16-20--js16-await","moduleId":"pythonfs","cardId":"qz-JavaScript-16-20--js16-await","front":"What does `await` actually do to the surrounding function?","back":"Suspends the async function and returns control to the event loop, resuming in a microtask","keyPoints":["Nothing is blocked. The function's continuation is scheduled as a microtask when the promise settles, which is why other work can run in between."],"href":"/python-fullstack-interview/questions/JavaScript-16-20#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-6-10--re6-deps","moduleId":"pythonfs","cardId":"qz-React-6-10--re6-deps","front":"A useEffect with an empty dependency array runs when?","back":"Once after the initial mount (and cleanup on unmount)","keyPoints":["An empty array means no dependencies to re-check, so the effect runs once after mount. In StrictMode during development React deliberately mounts, unmounts and remounts to surface missing cleanup."],"href":"/python-fullstack-interview/questions/React-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true},{"key":"pythonfs:qz-React-6-10--re6-stale","moduleId":"pythonfs","cardId":"qz-React-6-10--re6-stale","front":"What causes a stale closure in a useEffect?","back":"Omitting a value the effect reads from the dependency array, so it captures the first render's value","keyPoints":["The effect closes over the render in which it was created. If a value it reads is not in the deps, the effect never re-creates and keeps seeing the old value - the classic 'why is my counter stuck at 0'."],"href":"/python-fullstack-interview/questions/React-6-10#quiz","moduleLabel":"Python Full-Stack","latent":true}]