Senior engineering, architecture, and leadership interview questions
Status: Complete for Wave 4. Last reviewed 2026-08-28.
This canonical bank covers senior design, architecture, operations, leadership, and system-design decisions. Example answers model credible 60–120 second spoken responses, not grading rubrics or uniquely correct scripts.
Software design
Section titled “Software design”Diagnose coupling and cohesion in a change
Section titled “Diagnose coupling and cohesion in a change”A pricing change repeatedly touches controllers, jobs, models, and listeners, while each class appears small and well separated. How would you diagnose the real coupling and reshape the design without performing a broad rewrite?
Example answer
Solid response: I would trace one real pricing change and list every policy assumption it moves: validation, calculation, persistence, and emitted effects. Small classes do not imply low coupling if they share call order, DTO shape, or transaction timing. I would inspect change history, traces, and defects, then put the pricing rules and inputs behind one cohesive application-owned operation while leaving transport and delivery at the edges.
Senior extension: I would characterize current outputs, queries, side effects, and failure behavior before moving one path at a time. Tests should assert prices and transaction boundaries, not the old class graph. I would stop if the consolidation creates an oversized owner or unrelated rules stop changing together. Reduced files per pricing change, fewer ordering defects, and clearer traces are evidence; aesthetics alone are not.
Apply SOLID behaviorally
Section titled “Apply SOLID behaviorally”A checkout implementation has been split into many one-method interfaces and services in the name of SOLID, yet routine changes are slower and failures cross several layers. How would you assess and improve it?
Example answer
Solid response: I would evaluate SOLID as behavior, not count interfaces. The question is whether responsibilities change for one reason, clients can rely on substitutions, capabilities match their needs, and high-level checkout policy avoids volatile details. One-method layers that merely delegate add navigation and failure hops without changing coupling. I would inline pass-through types and group rules that change together, retaining interfaces only at meaningful persistence, provider, clock, or independently varying policy boundaries.
Senior extension: First I would record the current contract, latency, exception mapping, retries, and transaction scope because ceremony may conceal behavior. I would simplify incrementally and compare tests, traces, review time, and files touched per change. A trigger to reintroduce a seam would be a demonstrated second implementation, separate ownership, or repeated volatile change, not a hypothetical future need.
Separate dependency inversion, injection, and containers
Section titled “Separate dependency inversion, injection, and containers”A domain service resolves a vendor client from Laravel’s container and catches vendor exceptions directly. Explain which design concepts are being conflated and propose a boundary that preserves useful failure information.
Example answer
Solid response: Container lookup is service location, not dependency inversion. Injection makes a requirement explicit; inversion requires application policy to own the semantics of the boundary. I would define a narrow capability such as CreditDecision assess(...), inject it into the application service, and implement it with an outer vendor adapter wired at the composition root. The adapter translates vendor DTOs and distinguishes refusal, timeout, throttling, and unknown outcome rather than collapsing everything into one exception.
Senior extension: I assume provider replacement or failure policy is consequential; otherwise a concrete injected collaborator may be enough. Contract tests would exercise mapping against realistic provider responses, while policy tests use controlled outcomes. Traces should expose provider latency and classifications. If callers repeatedly need vendor-specific capabilities, I would revisit the port rather than keep expanding a fictional universal abstraction.
Select a pattern from production forces
Section titled “Select a pattern from production forces”A team proposes events, commands, strategies, factories, and decorators for a new fulfilment workflow. How would you select only the patterns justified by its change and failure modes?
Example answer
Solid response: I would begin with forces: which fulfilment steps are mandatory, which policies vary, which reactions are independent, and where failures must be visible to the caller. A strategy fits a recurring selectable policy; an adapter translates an external contract; a command can represent a durable requested action; events fit facts with independently owned reactions. Decorators suit orthogonal behavior only when ordering is explicit. A direct application call is the baseline.
Senior extension: I would trace timeout, retry, transaction, and partial-success paths before approving any chain. Events must define delivery and ordering; decorators can accidentally nest retries or transactions; factories can become service locators. I would add a pattern when a second case or production failure proves the force, and remove it when every change crosses both abstraction and implementation. Trace depth and change history provide evidence.
Remove an abstraction whose cost exceeds its value
Section titled “Remove an abstraction whose cost exceeds its value”Describe an abstraction you would remove because its navigation, wiring, and change cost now exceed its value. What evidence would support removal, and how would you preserve any hidden behavior?
Example answer
Solid response: I would remove a generic service layer whose methods mirror one Eloquent model and whose callers still depend on Eloquent builders and exceptions. Change history showing every feature editing controller, interface, implementation, and binding would demonstrate cost; one implementation and frequent bypasses would show the promised boundary is absent. I would first characterize returned shapes, query counts, authorization, exceptions, transactions, and side effects, then inline callers in small, reviewable steps.
Senior extension: I would compare production-like tests and telemetry before deleting registrations and dead mocks. A pass-through layer may hide eager loading, retry, or after-commit behavior, so those guarantees need an explicit new owner. I would pause if independent ownership or a stable domain capability emerges. Success means fewer concepts and touched files with unchanged outcomes, latency, and failure classification, not merely a smaller class count.
Decide whether a repository adds value over Eloquent
Section titled “Decide whether a repository adds value over Eloquent”When does a repository add value over direct Eloquent use, and when is it ceremony? Decide for a reservation workflow with locking rules and several reporting queries.
Example answer
Solid response: For reservations, a repository can earn its cost by exposing a capability such as claimAvailable, returning application values, and owning locking, transaction, and not-found/conflict semantics. Direct Eloquent remains clearer for ordinary CRUD. Reporting queries have different shapes, so I would use named query objects or projections rather than force reads through a generic find/save/delete contract that returns models and leaks builders.
Senior extension: I would state that the production database still owns constraints; a fake repository cannot prove lock or query behavior. Integration tests must force contention and verify SQL semantics. Evidence for extraction includes repeated query guarantees, unstable persistence detail leaking into policy, or a credible ownership boundary. If every feature edits the repository and its Eloquent implementation together, or callers need arbitrary criteria, I would remove it rather than advertise database interchangeability we do not have.
Architecture and domain-driven design
Section titled “Architecture and domain-driven design”Build an architecture and DDD mental model
Section titled “Build an architecture and DDD mental model”A growing Laravel product is considering “clean architecture and DDD everywhere.” How would you decide where strategic or tactical DDD earns its cost and where conventional application code should remain?
Example answer
Solid response: I would use strategic DDD where language conflicts, policy is subtle, change is frequent, and ownership matters. I would map capabilities, core versus supporting domains, decision owners, and model conflicts before choosing folders. Tactical entities, values, aggregates, and domain events are useful only where they protect real invariants. Straightforward administration can remain conventional Laravel application code; ports are justified at volatile external boundaries, not around every class.
Senior extension: My assumption is that one deployment remains operationally adequate. I would pilot the approach in one high-change core area and measure defect concentration, files touched, onboarding friction, and delivery time. Excess mappings, pass-through services, and terms nobody in the business uses are failure evidence. Repeated cross-boundary changes or ownership conflict triggers a context review; low domain complexity triggers simplification rather than broader ceremony.
Find and integrate bounded contexts
Section titled “Find and integrate bounded contexts”Billing and fulfilment disagree about the meaning and lifecycle of a customer. How would you find the bounded contexts, assign data ownership, and integrate them without creating one shared canonical model?
Example answer
Solid response: I would interview both domains around decisions and language. Billing may own an account, credit status, and invoice address; fulfilment may own a recipient and delivery preferences. Each context gets its own model and authoritative writes. Integration crosses a published application API or versioned fact, with an anti-corruption layer translating terms. Shared reads can use projections, but neither context updates the other’s tables.
Senior extension: I would create a context map naming upstream/downstream expectations, latency, unavailable behavior, and schema owner. Existing joins and foreign keys reveal coupling but do not define the right boundary. I would monitor cross-context imports, writes, and coordinated releases. If translation defects and synchronized policy changes remain frequent, the split may be wrong; if independent language and cadence strengthen, I would enforce it with architecture tests and ownership rules.
Model entities, values, and aggregate invariants
Section titled “Model entities, values, and aggregate invariants”Model an order whose payment, inventory reservation, and shipment evolve independently. Where would you place entity identity, value objects, aggregate boundaries, and concurrency enforcement?
Example answer
Solid response: The order is an entity by order identity; money and addresses are immutable value objects with construction invariants. I would keep only rules requiring immediate consistency inside the order aggregate, such as line totals and valid order-state transitions. Payment, inventory, and shipment are separate aggregates or contexts referenced by identity and coordinated through explicit workflow state, not one ORM object graph.
Senior extension: Concurrency must complete the model. I would use database constraints, conditional version updates, or short locks for each owner’s invariant and make workflow commands idempotent. Provider timeout becomes unknown and reconciled rather than failed. Evidence of an oversized aggregate includes loading thousands of children, lock contention, and cross-team changes. A rule proven to require atomic cross-owner consistency may move a boundary; tolerable delay favors events and reconciliation instead.
Place services, events, ports, and adapters
Section titled “Place services, events, ports, and adapters”For a credit-reservation use case involving HTTP input, domain rules, a database, and an external provider, place application services, domain services, events, ports, and adapters, and explain their failure boundaries.
Example answer
Solid response: An inbound HTTP adapter authenticates and translates input into an application command. The application service authorizes, loads state, controls the transaction, invokes domain behavior, persists it, and records required outgoing work. A domain service holds only credit-allocation policy that fits no entity. Application-owned ports describe loading reservations and assessing credit; database and provider adapters implement them. A domain event records the accepted reservation, while an outbox bridges a committed integration event.
Senior extension: I would not imply events are asynchronous or reliable by name. The transaction cannot include the provider, so timeout and unknown outcomes need explicit states, idempotency, retries, and reconciliation. Adapter tests verify mappings; domain tests verify policy; production evidence tracks outbox age and provider classifications. If a port merely mirrors a vendor API, I would redesign or remove it.
Enforce boundaries in a modular monolith
Section titled “Enforce boundaries in a modular monolith”How would you find and enforce a module boundary inside a growing Laravel monolith when teams currently import each other’s models and write each other’s tables?
Example answer
Solid response: I would trace business capabilities, language, change history, data writes, and team ownership to find a candidate boundary, rather than split by controllers or tables. Each module should own its policy, migrations, and writes and publish a narrow application entry point. I would first stop new cross-module writes, then replace existing model imports with calls or owned projections one flow at a time.
Senior extension: Namespaces and folders are insufficient, so I would add static dependency rules, architecture tests, code ownership, and telemetry for prohibited queries. Shared-database transactions remain possible only for named cross-module invariants and accepted coordinated evolution. Evidence of success is fewer cross-owner changes and imports, plus independent internal evolution. If every request requires chatty calls or duplicate models with no language distinction, I would reconsider the boundary rather than enforce a diagram.
Decide and migrate a service extraction
Section titled “Decide and migrate a service extraction”When would you extract a service from that monolith? Choose a concrete trigger and describe a migration that transfers data ownership without split-brain writes.
Example answer
Solid response: I would extract only for concrete pressure such as measured independent scaling, security isolation, damaging failure containment, or an autonomous team’s blocked release cadence. First I would enforce commands, queries, invariants, and ownership inside the monolith and instrument traffic. For data, I would backfill with checkpoints, replicate changes through a replayable log or outbox, compare domain invariants, shadow reads, and gradually route traffic.
Senior extension: One writer remains authoritative at every stage. At cutover I fence old writers, drain or version in-flight work, and retain a tested rollback that cannot create divergent owners. Dual application writes are a failure risk, not a migration strategy. Lag, mismatches, latency, and error rate gate progression. If the internal boundary cannot hold or measured pressure disappears, I stop; a network would add timeouts, on-call, contracts, and reconciliation without solving ownership.
Deployment and release engineering
Section titled “Deployment and release engineering”Model a compatible multi-part release
Section titled “Model a compatible multi-part release”Describe a safe migration from an older PHP or Laravel baseline when web instances, queue workers, schema, configuration, and cached assets cannot switch atomically.
Example answer
Solid response: I treat the upgrade as a compatibility transition. I inventory PHP extensions, Composer constraints, framework behavior changes, schema, serialized jobs, configuration, and assets, then build one immutable artifact per stage. I first deploy representations both baselines tolerate, make jobs and schema additive, and ensure new code can read old data. I upgrade a small web and worker cohort, compare errors, latency, business outcomes, and queue age, then expand before contracting old paths later.
Senior extension: Long-lived workers, cached config, queued payloads, and cached HTML extend the coexistence window. I preserve old artifacts and define whether reversal remains data-compatible. A failing canary, unsupported dependency, serialization mismatch, or migration lock pauses promotion. Once new-only data or external effects exist, I prefer disabling the path or rolling forward rather than claiming an old artifact can undo them.
Choose a rollout strategy
Section titled “Choose a rollout strategy”A high-volume checkout release has uncertain performance impact, long-lived sessions, and limited spare capacity. Choose among recreate, rolling, blue-green, canary, and feature flags, and define promotion evidence.
Example answer
Solid response: I would use a capacity-aware rolling canary if sessions can be assigned stably and checkout versions are contract-compatible. A small representative cohort limits blast radius while avoiding the duplicate fleet cost of blue-green. I would reserve surge capacity, warm instances, and compare candidate versus control on checkout success, p95/p99, database and provider saturation, and business conversion. A feature flag may separately control the risky capability with a safe default.
Senior extension: One percent must include large tenants, regions, workers, and asynchronous producers; otherwise it is false confidence. Missing telemetry fails the gate, and noisy data pauses rather than promotes. Blue-green becomes preferable if full-environment validation and rapid traffic reversal justify capacity. Recreate is acceptable only with an agreed outage. Thresholds, evaluation windows, authority, and rollback compatibility are decided before exposure.
Evolve schema, events, configuration, and assets
Section titled “Evolve schema, events, configuration, and assets”A release adds a required field, changes an event enum, rotates a secret, and publishes a new asset bundle. Sequence the change so old and new producers and consumers can coexist safely.
Example answer
Solid response: I would expand first: add a nullable field, teach readers both forms, make consumers tolerate additive event fields and retained old enum values, install both old and new secrets, and publish content-addressed assets while retaining prior bundles. Then deploy transition-capable producers, backfill in resumable throttled batches, observe convergence, switch authority, and only later enforce the field, remove enum support, revoke the old secret, and delete old assets.
Senior extension: I name each producer, consumer, and coexistence window, including delayed jobs and third-party clients. Application dual writes require an authority and reconciliation. I test exact DDL locking and replica impact. Unknown enum rejection, asset 404s, decryption failures, backfill drift, or old-consumer traffic pause contraction. Rollback is credible only while the previous version accepts every currently emitted representation.
Design a container artifact and lifecycle
Section titled “Design a container artifact and lifecycle”Design the build, startup, health checks, and termination lifecycle for an immutable web-and-worker container release. Which guarantees remain outside the image?
Example answer
Solid response: I build once from locked dependencies and an immutable base identity, attach revision and provenance, scan by policy, and promote the same artifact. Environment configuration and secrets arrive at deployment and are validated at startup. A startup probe covers bounded initialization, readiness controls traffic admission, and liveness detects only states restart can repair. On termination, the process becomes unready, stops claiming work, finishes or checkpoints within the grace period, and exits.
Senior extension: The image does not guarantee reproducibility, vulnerability absence, correct config, durable state, or safe retries. Durable data stays external; local state is disposable. I test hard kills because grace is not guaranteed. Probe failures, restart rates, startup duration, in-flight work, and duplicate effects provide evidence. If dependency checks in readiness amplify an outage, I narrow them to the process’s ability to serve safely.
Decide between rollback and roll-forward
Section titled “Decide between rollback and roll-forward”Ten minutes into a release, errors rise after new data has been written and external notifications sent. How would you choose mitigation, rollback, or roll-forward, and what evidence changes the decision?
Example answer
Solid response: I first reduce harm: pause promotion, disable the path or producer, shed traffic, or restore configuration. Then I determine whether the old artifact can read current schema, messages, and data. Notifications already sent and facts already written are not rolled back by code reversal. If compatibility holds and diagnosis is uncertain, automated rollback may be fastest; if state changed irreversibly or the defect is understood and small, I roll forward and reconcile effects.
Senior extension: I compare candidate/control errors, affected cohorts, deploy markers, data invariants, and dependency outcomes rather than blame the nearest change. Pre-agreed thresholds and authority avoid debate during harm. Failed compensation, unknown provider outcomes, or old-reader rejection are rollback stop signals. After recovery I verify queues, customer effects, and data, because normal HTTP graphs alone do not prove correctness.
Turn RTO and RPO into a recovery design
Section titled “Turn RTO and RPO into a recovery design”A business declares a four-hour RTO and fifteen-minute RPO for order processing. Turn those objectives into a recovery design and an exercise that proves more than backup completion.
Example answer
Solid response: RPO fifteen minutes means restored order state may be at most fifteen minutes behind the incident point; RTO four hours covers restoring a usable capability, not merely starting a database. I map databases, object stores, queues, identity, configuration, DNS, and encryption keys, then choose protected backup and replication intervals that can meet those objectives without treating replicas as corruption protection.
Senior extension: I rehearse in isolation: declare a failure time, recover credentials and infrastructure, restore to a selected point, start the application, switch test traffic, and verify order totals, state transitions, missing/duplicate work, and external reconciliation. I record achieved recovery point and elapsed time by stage. If key access, data volume, or integrity checks breach either target, that evidence triggers design or objective renegotiation, not a successful-backup report.
Observability and incident response
Section titled “Observability and incident response”Design evidence for a queue-backed service
Section titled “Design evidence for a queue-backed service”Design telemetry for an import API that acknowledges quickly but may process for hours. How would you show user outcomes, locate delay, correlate work, and control telemetry cost and failure?
Example answer
Solid response: I instrument stable import states: accepted, queued, started, checkpointed, completed, rejected, cancelled, and reconciled. Metrics cover valid outcomes, completion latency, queue age, throughput, retries, and saturation; structured logs hold safe import and tenant context; traces connect receipt, storage, and sampled processing; audit events record operator and release changes. A stable import ID crosses asynchronous boundaries without placing personal data in labels.
Senior extension: HTTP acceptance is not import success, so the user-facing view and SLI follow the terminal state and deadline. I bound metric dimensions, sample detailed traces with a stated bias, redact before export, and use non-blocking bounded buffers with drop accounting. Missing terminal events, correlation gaps, cardinality growth, collector backpressure, and disagreement with business records trigger instrumentation repair or reconciliation.
Define SLIs, SLOs, and an error-budget policy
Section titled “Define SLIs, SLOs, and an error-budget policy”Define SLIs and SLOs for that import capability, then propose an error-budget policy that informs release and reliability decisions without becoming a mechanical punishment.
Example answer
Solid response: I define valid events as accepted imports eligible under the product contract. One SLI is the proportion reaching a correct terminal state within, say, the agreed deadline; another may measure result availability. The SLO target and window come from user need, dependency reality, and cost, while the SLA remains a separate external agreement. Exclusions such as customer cancellation are explicit and observable.
Senior extension: Error-budget policy changes decisions: high sustained consumption can slow risky releases, prioritize backlog or correctness work, and require safer rollout, while healthy budget permits bounded experiments. It is not an automatic team penalty. I validate the SLI against user reports and domain records; missing telemetry is not good service. Changed import sizes, dependency reliability, product promises, or consistent overachievement at low cost trigger target and policy review.
Build actionable burn-rate alerts
Section titled “Build actionable burn-rate alerts”Build paging and ticket alerts for the import SLO using burn rates. How would you handle low traffic, missing telemetry, noisy recovery, ownership, and validation?
Example answer
Solid response: I page on user-impacting budget burn that needs timely judgment, using paired short and long windows: a high short-window burn catches severe failure, while a lower sustained burn catches a slow leak. The page names capability, affected scope, owner, dashboard, and first mitigation. Capacity trends and individual malformed imports become tickets unless they threaten the objective.
Senior extension: Low traffic needs minimum-event handling or synthetic evidence so one failure does not create unstable ratios. Missing data is a separate failure state, never success. I add evaluation and recovery windows to avoid flapping and segment by release and cohort. Historical incident replay, controlled queue delay, telemetry loss, and recovery exercises validate thresholds. If responders repeatedly cannot act, pages are ignored, or incidents evade detection, I revise the SLI, routing, or runbook.
Diagnose a latency incident from competing signals
Section titled “Diagnose a latency incident from competing signals”Checkout p99 and queue age are rising, application CPU is low, one dependency is slower, and a release occurred nearby. Give an evidence-led diagnosis and mitigation sequence.
Example answer
Solid response: I start with impact: which checkout paths, regions, tenants, and releases are slow, and since when. I compare healthy and affected populations and construct a timeline of deploy, traffic, configuration, and dependency changes. Low CPU does not clear the application; rising queue age may indicate database connection wait, locks, downstream latency, quota, or admission pressure. Traces locate time for examples, metrics establish breadth, and logs classify explicit failures.
Senior extension: I query the smallest evidence that separates hypotheses, such as connection-pool wait versus provider span time. The nearby release is correlation, not cause. During harm I may stop the producer, shed optional work, cap concurrency, or revert only the affected compatible cohort, annotating each change. User outcomes, queue drain, resource recovery, and business reconciliation verify recovery; ambiguous evidence keeps the incident open.
Lead and communicate an incident
Section titled “Lead and communicate an incident”Describe an incident response from detection through verified recovery. How would you establish command, preserve uncertainty, choose mitigation, and communicate with users and stakeholders?
Example answer
Solid response: I declare when coordinated response is cheaper than fragmented debugging, name an incident commander, operations lead, and communications owner, and open a chronological decision record. We state impact, scope, hypotheses, owners, hazards, and the next check-in. Mitigation outranks perfect cause: prefer a reversible traffic shift, feature disablement, or producer stop while preserving evidence. Public updates describe user impact, known scope, mitigation, and next update time without unsupported cause or restoration promises.
Senior extension: I predefine escalation for security, privacy, legal, and cross-team risk. Observations remain distinct from conclusions, and one major variable changes at a time when harm permits. Recovery requires business checks: queued work drained, records reconciled, and recurrence monitored. Afterwards, a blameless review still assigns accountable owners and verification to system changes; repeated detection or command delays become measurable improvement triggers.
Turn review and recovery exercises into risk reduction
Section titled “Turn review and recovery exercises into risk reduction”An outage review produces “add monitoring,” “be more careful,” and “test backups.” Replace those with owned actions and a recovery exercise whose evidence demonstrates reduced risk.
Example answer
Solid response: I replace “add monitoring” with an owned checkout-completion SLI and tested page for a named failure; “be careful” with an enforced compatibility gate or smaller blast radius; and “test backups” with a scheduled isolated restore owned by the service and platform teams. Each action has expected risk reduction, priority, due or review point, and evidence that determines completion.
Senior extension: The exercise removes normal access, declares a corruption time, restores data plus keys and configuration, switches test traffic, and checks business invariants, missing/duplicate work, achieved RPO, and elapsed RTO. I record where the runbook, permissions, capacity, or communication failed. Actions that do not reduce detection, mitigation, recurrence, or recovery risk are revised or consciously dropped. Repeated exercise misses trigger architecture investment or honest objective renegotiation.
Technical leadership
Section titled “Technical leadership”Lead a decision without authority
Section titled “Lead a decision without authority”Two teams must choose a shared integration approach, but you own neither team. How would you create a timely, challengeable decision without manufacturing consensus or authority?
Example answer
Solid response: I would make the decision legible: shared outcome, accountable owner, deadline, hard constraints, unknowns, and what evidence could change the choice. I would consult the operators, security owners, maintainers, and consumers, then compare a small set of credible options against the same criteria and recommend one with failure modes. Consultation is not consensus; the named owner decides and dissent is recorded.
Senior extension: I separate facts, forecasts, and preferences so seniority cannot disguise uncertainty. For reversible choices I propose a bounded trial with success and stop conditions; irreversible commitments get deeper validation. If teams deadlock past the deadline or consequences exceed local authority, I escalate the decision, evidence, urgency, and requested owner, not personalities. Once decided, we commit unless new evidence activates a recorded revision trigger.
Calibrate code-review feedback
Section titled “Calibrate code-review feedback”How do you distinguish blocking review feedback from a preference? Apply your approach to a risky migration mixed with naming and service-layer disagreements.
Example answer
Solid response: I block on a plausible correctness, security, data-loss, compatibility, operability, or agreed-requirement failure. I explain the violated invariant and evidence needed, not just prescribe my preferred code. The migration’s unbounded lock or unsafe rollback is blocking; unclear behavior is a question; a clearer service boundary may be non-blocking follow-up; naming is a preference unless an enforced convention applies.
Senior extension: Review rigor follows blast radius and reversibility. I ask for representative migration timing, compatibility stages, recovery behavior, and operational ownership, while automation handles style. If service-layer disagreement affects transaction or failure semantics, it can become blocking; otherwise the author chooses and we avoid delaying risk reduction. I escalate only unresolved cross-owner risk, and I track follow-ups so “non-blocking” does not mean forgotten.
Forecast uncertain work
Section titled “Forecast uncertain work”Leadership requests a delivery date for a provider migration before its data quality, rate limits, and contract gaps are understood. How would you forecast, reduce uncertainty, and communicate change?
Example answer
Solid response: I would give a range or scenarios conditioned on scope, staffing, provider cooperation, and interruption rate, explicitly separating a requested target from my forecast. The largest uncertainties are data cleanup, quota behavior, and undocumented contract differences. I include integration, migration, reconciliation, rollout, and operational readiness, not just implementation, and state the next reforecast point.
Senior extension: I would time-box discovery: profile production data, test the provider’s difficult paths and limits, and agree unresolved semantics with its owner. Each spike answers a named question. Reference work and observed team throughput inform the range, but correlated risks prevent simple summation. If evidence moves the forecast, I communicate early with options to reduce scope, sequence value, or fund compatibility, rather than silently consume contingency to protect a date.
Prioritize technical debt
Section titled “Prioritize technical debt”A team has a long debt backlog containing old code, recurring incidents, slow delivery paths, and disliked abstractions. How would you prioritize investment and verify that repayment worked?
Example answer
Solid response: I would describe each debt item economically: principal to change it, recurring interest in incidents, lead time, compute, cognitive load, or blocked outcomes, affected paths, and confidence. Old or disliked code is not automatically debt. I prioritize by expected impact, timing, and strategic work: recurring outages and a migration bottleneck may outrank a cleaner abstraction with no observed cost.
Senior extension: Deferral gets an owner and trigger such as another incident, support expiry, measured saturation, or an upcoming feature touching the area. Repayment may be deletion, containment, characterization tests, or incremental replacement, not always a rewrite. Before work I define evidence such as incident rate, change lead time, support volume, or resource cost; afterwards I compare it. If predicted interest does not fall, I revisit the diagnosis rather than declare success from code completion.
Record and reverse an architecture decision
Section titled “Record and reverse an architecture decision”Record a decision to adopt a vendor-specific workflow that may be difficult to reverse. What belongs in the ADR, and how would reversibility change your validation and migration plan?
Example answer
Solid response: The ADR records context, owner, date, decision, alternatives, constraints, assumptions, consequences, and status. For a vendor workflow I include data location, API and identity coupling, reliability and support expectations, cost model, portability, and the capabilities deliberately accepted as proprietary. Review triggers include pricing, SLA misses, compliance change, volume, and loss of export capability; later decisions supersede rather than rewrite history.
Senior extension: Reversibility is concrete. If customer data, public contracts, or operations adopt vendor semantics, an adapter alone does not make exit cheap. I would prove difficult paths, export and restore data, retain stable internal identifiers, stage migration, and define the last safe reversal point plus compensation afterward. Low-cost reversible choices get capped analysis; durable commitments require security review, failure exercises, and an owned exit rehearsal.
Resolve disagreement and lead an incident
Section titled “Resolve disagreement and lead an incident”Resolve a persistent disagreement over a service/repository layer in code review, then explain how your decision process changes if the dispute occurs during a live incident.
Example answer
Solid response: In review I restate the shared outcome and ask whether the layer protects a real invariant, owner, or volatile boundary. Each side names its strongest failure mode and revision trigger. Change history, a small prototype, and a trace of transactions and exceptions can settle factual claims. If consequences are equivalent, it is preference; the accountable author or owner decides, dissent is recorded, and relitigation requires new evidence.
Senior extension: During an incident the outcome changes to limiting harm. The incident commander owns decision cadence, not the most forceful reviewer. I choose the safest reversible mitigation with available evidence, assign execution and communication, and defer architecture cleanup. Security or data-loss boundaries still escalate immediately. After recovery we revisit the service/repository decision with preserved evidence and without turning incident pressure into permanent design authority.
System design
Section titled “System design”Frame an ambiguous system-design problem
Section titled “Frame an ambiguous system-design problem”You are asked to design a global scheduling platform with few initial requirements. Show how you would turn ambiguity into assumptions, invariants, estimates, and a deliberately simple first architecture.
Example answer
Solid response: I would identify actors and two critical journeys, then clarify booking horizon, recurrence, cancellation, geography, and external calendar scope. I state assumptions for active tenants, peak requests, event size, retention, latency, availability, recovery, privacy, and team timeline. The strongest invariants might be tenant isolation and no double booking for resources we authoritatively schedule. Averages are insufficient, so I include burst and hot-resource contention.
Senior extension: I start with a modular application, relational source of truth, object storage if needed, and a queue for deferred integrations. I estimate only enough to test database, queue, and provider feasibility, then trace a write and failure. Measured contention, residency needs, provider limits, or independent ownership are triggers for partitioning or extraction; they are not day-one decoration.
Trace data, transactions, and failure
Section titled “Trace data, transactions, and failure”Trace one critical write and read in a queue-backed order system, including ownership, transaction boundaries, duplicate delivery, timeout after commit, stale reads, and reconciliation.
Example answer
Solid response: The API authenticates tenant scope, accepts a stable operation ID, validates intent, and commits the order plus outbox row in one database transaction. A timeout after commit is safe because retry returns that operation. The relay may publish twice, so the worker claims idempotently, records provider outcomes, and advances explicit states. The response read uses the primary for read-your-write or exposes documented projection lag.
Senior extension: I insert failure before and after every commit, publish, provider call, and acknowledgement. Unknown external outcomes enter reconciliation, not blind retry; dead letters have an owner and age objective. Constraints protect hard invariants, while traces and causation IDs connect asynchronous work. Queue age, duplicate suppression, outbox age, and invariant discrepancies are evidence. Growing reconciliation gaps or unacceptable freshness trigger a boundary or workflow redesign.
Design concurrent booking
Section titled “Design concurrent booking”Design booking for a limited resource where two users can contend for the same slot and payment can time out. Protect the invariant and define expiry, retries, and recovery.
Example answer
Solid response: I make “one active booking per resource and overlapping interval” a database-owned invariant using an engine-appropriate exclusion constraint, conditional claim, or short locked allocation transaction. A stable booking operation ID makes retries return the same result. I create a held state with expiry, commit before calling payment, and move through paid, failed, expired, or unknown states idempotently.
Senior extension: Payment timeout is ambiguous, so I query or reconcile with the provider before charging again. Expiry workers claim safely and compensation releases exactly once. I test two contenders, crash after commit, delayed payment, duplicate messages, and clock behavior against the production engine. Lock wait, conflict rate, abandoned holds, and reconciliation age reveal pressure. If contention becomes concentrated, I revisit allocation or admission before adding distributed locks.
Design a webhook and import pipeline
Section titled “Design a webhook and import pipeline”Design a platform that receives signed provider webhooks and large customer imports. Address acknowledgement, durable processing, idempotency, bounded resources, progress, cancellation, and deployment compatibility.
Example answer
Solid response: For webhooks I verify the exact signed bytes, timestamp and provider event ID, durably deduplicate, acknowledge quickly, and process asynchronously. For imports I store the file durably, persist schema version and operation ID, stream bounded chunks, checkpoint progress, and define row-level versus whole-file atomicity. Both flows use bounded worker concurrency, classified retries, dead-letter ownership, cancellation semantics, and terminal status visible to users.
Senior extension: Acknowledged means durably accepted, not applied. Consumers tolerate retained old payloads during rolling deploys; producer changes are additive before contraction. I test replay, crash points, malformed input, archive bombs, provider timeout, worker termination, and cancellation during a chunk. Queue age, memory, per-tenant share, duplicate count, and reconciliation gaps gate capacity changes. Sustained backlog triggers throttling or capacity, not unlimited queueing.
Design multi-tenant SaaS
Section titled “Design multi-tenant SaaS”Design a multi-tenant SaaS data and execution model for tenants ranging from ten to ten million records, including isolation, noisy-neighbor control, restore, residency, and evolution triggers.
Example answer
Solid response: I make tenant identity explicit in authorization, rows, unique constraints, indexes, cache keys, files, jobs, quotas, and telemetry. I would begin with shared tables keyed by tenant if isolation and residency permit, using scoped access paths and database constraints. Per-tenant concurrency and storage quotas prevent noisy neighbors; privileged cross-tenant operations are separately authorized and audited.
Senior extension: Restore is part of isolation: I define whether one tenant can be restored without overwriting others and test export, deletion, and residency movement. Realistic skew tests include the ten-million-row tenant, not only averages. I would introduce placement groups, partitions, schemas, or databases when measured size, contention, legal isolation, blast radius, or restore requirements justify their operational cost. Cross-tenant leaks, hot tenants, and recovery misses are explicit triggers.
Design a notification platform
Section titled “Design a notification platform”Design a multi-channel notification platform with preferences, provider quotas, retries, fallback, and delivery evidence. State what accepted, sent, and delivered mean and how the design evolves.
Example answer
Solid response: I separate notification intent, recipient preferences, channel rendering, provider attempt, and delivery evidence. A stable intent and recipient/channel key deduplicate fan-out. Workers enforce per-provider and per-tenant concurrency and quotas, classify permanent, transient, throttled, and unknown outcomes, and retry with bounded jitter. Fallback is an explicit product policy so a delayed email does not unexpectedly become an SMS.
Senior extension: Accepted means durably recorded, sent means the provider accepted an attempt, and delivered means provider evidence under its stated limitations; none proves the user read it. Outbox publication, idempotent consumers, dead-letter ownership, and reconciliation cover crash gaps. I monitor queue age, provider outcomes, preference violations, cost, and delivery latency. Sustained quota pressure, reliability differences, or cost triggers another adapter or traffic strategy, not premature provider abstraction.