← Stripe Interview Insights

Stripe·Software Engineer·Technical Phone Screen·Intermediate

Intermediate
Jun 2026

Summary

Stripe SWE interview with a multi-part OOP/design question that kept building on itself. Each part felt manageable until the LRU piece showed up and I had to think pretty carefully about data structures under time pressure.

Questions Asked (3)

Q1

Design an AccountScheduler class that tracks which accounts are locked until a given timestamp. Implement an is_available(account_id, t) method that returns whether the account can be used at time t.

Algorithms & Data StructuresSystem Design
Author's notes

Straightforward to start.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: what operations are needed (lock, unlock, is_available), expected scale, and concurrency needs. Then propose a design using a hash map from account_id to a min-heap of lock expiration timestamps, allowing efficient lazy deletion of expired locks. For is_available, check if the account has any active lock at time t by peeking the heap and removing expired locks.

Pro tip: Mention that you would use a min-heap per account to store lock expiration times, enabling O(log n) lock insertion and O(1) availability check after lazy cleanup. Also discuss how to handle concurrent access with fine-grained locking or lock-free structures if needed.

1. Clarify requirements and constraints

Ask about expected number of accounts, lock/unlock frequency, concurrency requirements, and whether locks can be extended or removed early.

2. Choose data structures

Propose a hash map from account_id to a min-heap of lock expiration timestamps. Explain why a heap is efficient for tracking the earliest expiration.

3. Implement core operations

Define lock(account_id, t) to push t onto the heap, and is_available(account_id, t) to lazily remove expired locks (those <= t) and then check if any lock remains.

4. Analyze complexity and optimize

State time complexities: O(log n) for lock, amortized O(log n) for is_available due to lazy deletion. Discuss potential optimizations like using a balanced BST or a sorted list if locks are few.

5. Address concurrency and edge cases

Discuss thread-safety using locks or concurrent data structures. Handle edge cases: no locks, multiple locks, locks in the past, and time precision.

Key Points to Mention

  • Use a hash map to map account_id to a min-heap of lock expiration timestamps.
  • Lazy deletion: only remove expired locks when is_available is called, to avoid unnecessary work.
  • Time complexity: O(log n) for adding a lock, amortized O(log n) for checking availability.
  • Concurrency: use per-account locks or a concurrent hash map to allow parallel access.
  • Edge cases: account with no locks, multiple overlapping locks, locks that expire exactly at time t.
  • Alternative: if locks are infrequent, a simple list with linear scan might suffice, but heap scales better.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Extend the class with an acquire(account_id, t, duration) method that locks an account for a duration starting at t, using the formula: locked_until[account_id] = max(locked_until[account_id], t) + duration.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The max() formula tripped me up for a second.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the requirements and edge cases, then implement the method using a hash map to store locked_until times. Explain the formula and discuss potential concurrency issues and trade-offs.

Pro tip: Mention that the formula effectively extends the lock from the later of the current time and the existing lock, which prevents race conditions and ensures monotonic locking.

1. Clarify requirements

Ask about the data type of t and duration, whether account_id is guaranteed to exist, and if thread safety is required.

2. Design data structure

Use a hash map (dictionary) to map account_id to locked_until timestamp. Consider if additional metadata is needed.

3. Implement the method

Compute new_locked_until = max(existing_locked_until, t) + duration and update the map. Handle missing account_id by treating existing as 0 or -infinity.

4. Analyze complexity and trade-offs

Discuss O(1) time and space per operation, and trade-offs like memory usage vs. speed, and concurrency handling.

5. Test with edge cases

Consider cases where t is in the past, duration is zero, or multiple acquires overlap. Verify the formula's behavior.

Key Points to Mention

  • Use of a hash map for O(1) access
  • The max operation ensures locks are extended, not shortened
  • Handling of missing account_id (default to 0 or -infinity)
  • Thread safety considerations (e.g., locks, atomic operations)
  • Time and space complexity analysis
  • Potential overflow if timestamps are large

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Further extend the class with an auto_acquire(t, duration) method that automatically picks the least recently used available account, locks it, and returns its ID. Accounts never previously acquired should be treated as oldest.

Algorithms & Data StructuresSystem DesignTechnical Trade-offs
Author's notes

This is where it got interesting.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the requirements and constraints, then design a data structure that efficiently tracks the least recently used (LRU) available account. Implement the auto_acquire method using a combination of a hash map and a doubly linked list to achieve O(1) operations, and discuss trade-offs such as concurrency and persistence.

Pro tip: Emphasize the importance of handling edge cases like no available accounts and ensuring thread safety, as Stripe values robust and scalable solutions. Also, mention that you would write unit tests to verify the LRU behavior, especially for accounts never previously acquired.

1. Clarify Requirements

Ask questions to confirm assumptions: Is the method expected to be thread-safe? What should happen if no accounts are available? Should the method block or return an error? How is 'duration' used—does it set a lock timeout?

2. Choose Data Structures

Select a hash map for O(1) account lookup and a doubly linked list to maintain the LRU order. Accounts never acquired are placed at the tail (oldest) initially.

3. Implement LRU Logic

On acquire, remove the least recently used available account from the list, mark it as locked, and move it to the most recently used position. On release, move it back to the available list at the most recent position.

4. Handle Concurrency and Edge Cases

Use locks or concurrent data structures to ensure thread safety. Handle cases like no available accounts by throwing an exception or returning null, and consider lock expiration based on duration.

5. Discuss Trade-offs and Extensions

Talk about time/space complexity, potential bottlenecks, and how the design would scale. Mention alternatives like using a priority queue with timestamps if duration-based expiration is needed.

Key Points to Mention

  • LRU eviction policy and its implementation using a hash map and doubly linked list for O(1) operations.
  • Handling of accounts never previously acquired: treat them as oldest by initializing them at the tail of the LRU list.
  • Thread safety considerations: using locks, synchronized blocks, or concurrent collections to prevent race conditions.
  • Edge cases: no available accounts, lock duration expiration, and account release.
  • Time and space complexity analysis: O(1) for acquire and release, O(n) space for n accounts.
  • Testing strategy: unit tests for LRU order, concurrency tests, and failure scenarios.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.