Interview conceptSoftware Engineering Fundamentals

Low-Level Design, Code Review And Secrets

Asked of: Software Engineer

Last updated

Editorial architecture infographic showing a secure reservation service, its Movie–Show–Seat–Reservation domain model, concurrency controls, idempotent payments, secrets management, and code-review gates.

What's being tested

These prompts test whether you can turn ambiguous requirements into low-level designs with explicit entities, invariants, lifecycle transitions, and failure behavior. You must reason about concurrency, transactional boundaries, optimistic locking, API contracts, and maintainable class responsibilities—not merely draw classes or list technologies. Salesforce cares because production services are multi-tenant, highly concurrent, and security-sensitive; a design that works only on the happy path can cause data leakage, double allocation, downtime, or credential exposure.

Core knowledge

  • Domain modeling separates stable configuration from runtime state: a Movie has Show instances, while a reusable Seat layout is distinct from per-show SeatReservation state. Keep ownership and invariants explicit rather than putting all behavior in a god class.

  • State machines make lifecycle rules executable. For a reservation, valid transitions might be AVAILABLE → HELD → BOOKED or HELD → AVAILABLE; reject BOOKED → AVAILABLE unless a defined cancellation workflow exists. Store state transitions with timestamps and actor IDs for auditability.

  • Concurrency control prevents double booking. Use a database transaction with a conditional update such as UPDATE seats SET status = 'HELD' WHERE show_id = ? AND seat_id = ? AND status = 'AVAILABLE'; require the affected-row count to equal the requested count.

  • Optimistic locking adds a version predicate: UPDATE resource SET state = ?, version = version + 1 WHERE id = ? AND version = ?. A zero-row update means a conflicting write occurred; return a retryable conflict rather than silently overwriting another tenant’s decision.

  • Pessimistic locking such as SELECT ... FOR UPDATE can simplify correctness for short, bounded transactions, but reduces concurrency and risks lock contention. Never hold a database lock while calling a payment provider; use a short reservation hold plus an explicit payment workflow.

  • Idempotency makes retries safe. Require an idempotency key for payment confirmation, allocation requests, and credential-rotation operations; persist the key, request fingerprint, final result, and expiry. Reusing a key with different parameters must fail, not create a second operation.

  • Code review should proceed in layers: behavior and invariants first, then authorization and tenant isolation, transaction boundaries, error handling, data modeling, performance, observability, and maintainability. A review that checks formatting while missing an unscoped UPDATE is not thorough.

  • Multi-tenancy requires tenant identity to be enforced at every data-access boundary, not merely accepted from a request body. Prefer repository methods requiring tenant_id, database row-level security where appropriate, and tests proving that IDs from another tenant cannot be read or mutated.

  • Secrets management means database passwords belong in a dedicated secret manager such as AWS Secrets Manager, HashiCorp Vault, or a cloud-native equivalent—not source control, container images, logs, or ordinary configuration files. Applications should receive short-lived or tightly scoped credentials where practical.

  • Zero-downtime rotation requires overlap: create a new credential, publish it, let clients reload or reconnect, validate connectivity, then revoke the old credential after a grace period. Connection pools must refresh safely; caching a secret forever defeats rotation.

  • Reliability and observability are part of the design. Define timeouts, bounded retries with exponential backoff and jitter, dead-letter or reconciliation handling where needed, structured audit events, and metrics such as hold-expiry rate, conflict rate, allocation latency, and secret-refresh failures.

Worked example — Design a Movie-Ticket Booking System's Classes and Prevent Double Booking

In the first 30 seconds, I would clarify whether users select individual seats, how long a payment hold lasts, whether payment is synchronous, and whether a booking may span multiple shows or only one. I would declare that seat-layout metadata is immutable per auditorium version, while availability is modeled per show and seat. I would organize the answer around four pillars: domain classes and state transitions, transactional booking behavior, payment/idempotency integration, and expiry/reconciliation. The central invariant is that one (show_id, seat_id) can have at most one active booking or hold. To enforce it, I would use a conditional database update or a unique constraint over an active reservation representation, then verify the affected-row count inside a transaction. I would keep payment calls outside the seat lock, using HELD with an expiry timestamp and a confirmation endpoint carrying an idempotency key. The explicit tradeoff is between SELECT ... FOR UPDATE, which is straightforward but can reduce throughput, and optimistic conditional updates, which scale better but require conflict handling and retries. I would close by saying that, with more time, I would specify cancellation races, clock handling for expiry, payment webhooks, load-test assumptions, and a reconciliation job for ambiguous payment outcomes.

A second angle — Store, Deliver and Rotate an API Server's Database Credentials

The same discipline applies to database credentials, but the primary invariant changes from unique seat ownership to “only authorized workloads can obtain a usable credential, and rotation never causes avoidable downtime.” I would separate the secret manager, workload identity, credential-delivery mechanism, connection-pool refresh logic, and rotation controller. The key lifecycle is CURRENT → OVERLAPPING → REVOKED, with validation and a grace period between publication and revocation. The main tradeoff is short-lived dynamic credentials, which reduce exposure but add dependency and renewal complexity, versus longer-lived rotated credentials, which are simpler but riskier if leaked. I would also review logs, crash dumps, tracing, environment-variable exposure, and failure behavior when the secret manager is temporarily unavailable.

Common pitfalls

Pitfall: Treating an in-memory seat map or application-level mutex as the concurrency guarantee. Multiple API instances bypass that lock; the database transaction and uniqueness or conditional-write invariant must be authoritative.

A common analytical mistake is saying “use a transaction” without defining what the transaction protects or what happens when payment fails, a request retries, or a hold expires. State the invariant, transition conditions, idempotency behavior, and recovery path explicitly.

A communication mistake is presenting a long class diagram before confirming assumptions. Start with scope, scale, consistency requirements, and failure semantics, then explain only the classes and interfaces that support those decisions.

A depth mistake is recommending a secret vault while ignoring delivery and rotation mechanics. Explain workload authentication, caching, connection-pool refresh, overlapping validity, revocation, and the behavior of a failed refresh.

Connections

An interviewer may pivot to distributed transactions, the outbox pattern, and webhook idempotency when discussing payment or allocation workflows. Other natural pivots are row-level security, RBAC, connection-pool behavior, structured audit logging, and contract or property-based testing.

Further reading

Practice questions

Related concepts