PracHub
QuestionsCoachesLearningGuidesInterview Prep
|Home/Coding & Algorithms/Optiver

Thread-Safe Stock Inventory: Buy and Sell Without Overselling

Last updated: Jul 2, 2026

Thread-Safe Stock Inventory: Buy and Sell Without Overselling

Company: Optiver

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

## Thread-Safe Stock Inventory: Buy and Sell Without Overselling You are implementing the inventory-management core of a small brokerage service. The service tracks the number of shares of a single stock that are currently available, and it exposes two operations that will be called concurrently from many threads. Implement a class `StockInventory` with the following interface: - `StockInventory(initial)` — construct the inventory with `initial` shares available. - `buy(quantity)` — acquire `quantity` additional shares and add them to the available inventory. A buy always succeeds. Returns the number of shares available immediately after this purchase is applied. - `sell(quantity)` — attempt to sell `quantity` shares out of the available inventory. The sale is all-or-nothing: if at least `quantity` shares are available at the moment the sale is applied, deduct exactly `quantity` shares and return `true`; otherwise leave the inventory unchanged and return `false`. Partial fills are not allowed. ### Correctness requirements Your implementation must remain correct when an arbitrary number of threads call `buy` and `sell` simultaneously on the same `StockInventory` object: 1. **No overselling.** The available share count must never become negative at any point in time. Two concurrent `sell` calls must never both succeed if the inventory can only cover one of them. 2. **No lost updates.** Every `buy` and every successful `sell` must be reflected exactly once in the inventory. After all threads finish, the final count must equal `initial + (sum of all bought quantities) - (sum of all successfully sold quantities)`. 3. **Atomic check-then-act.** The availability check inside `sell` and the corresponding deduction must happen atomically with respect to all other `buy` and `sell` calls — no other operation may interleave between the check and the update. You may use the standard synchronization primitives provided by your language's library (mutexes/locks, atomic operations, condition variables, etc.). Keep the critical sections as small as correctness allows. ### Example Single-threaded illustration of the required semantics: ```text inv = StockInventory(100) inv.sell(30) -> true (70 shares remain) inv.sell(80) -> false (only 70 available; inventory unchanged at 70) inv.buy(50) -> 120 (70 + 50) inv.sell(120) -> true (0 shares remain) inv.sell(1) -> false (inventory unchanged at 0) ``` Under concurrency, any interleaving of the calls is acceptable as long as every individual operation is atomic, the no-overselling invariant holds, and the final count is consistent with the set of operations that succeeded. ### Constraints - `0 <= initial <= 10^9` - `1 <= quantity <= 10^9` for every `buy` and `sell` call - Up to `10^5` total operations, issued from up to `64` concurrent threads - Each operation should complete in amortized $O(1)$ time outside of contention for the synchronization primitive

Related Interview Questions

  • Build and Validate a Binary Tree from Parent-Child Pairs - Optiver (medium)
  • Days Between Two Calendar Dates - Optiver (medium)
  • Find missing numbers in sequences - Optiver (hard)
  • Design a circular queue data structure - Optiver (medium)
  • Optimize flight and cargo bookings for profit - Optiver (hard)
|Home/Coding & Algorithms/Optiver

Thread-Safe Stock Inventory: Buy and Sell Without Overselling

Optiver logo
Optiver
Apr 19, 2026, 12:00 AM
mediumSoftware EngineerTechnical ScreenCoding & Algorithms
0
0

Thread-Safe Stock Inventory: Buy and Sell Without Overselling

You are implementing the inventory-management core of a small brokerage service. The service tracks the number of shares of a single stock that are currently available, and it exposes two operations that will be called concurrently from many threads.

Implement a class StockInventory with the following interface:

  • StockInventory(initial) — construct the inventory with initial shares available.
  • buy(quantity) — acquire quantity additional shares and add them to the available inventory. A buy always succeeds. Returns the number of shares available immediately after this purchase is applied.
  • sell(quantity) — attempt to sell quantity shares out of the available inventory. The sale is all-or-nothing: if at least quantity shares are available at the moment the sale is applied, deduct exactly quantity shares and return true ; otherwise leave the inventory unchanged and return false . Partial fills are not allowed.

Correctness requirements

Your implementation must remain correct when an arbitrary number of threads call buy and sell simultaneously on the same StockInventory object:

  1. No overselling. The available share count must never become negative at any point in time. Two concurrent sell calls must never both succeed if the inventory can only cover one of them.
  2. No lost updates. Every buy and every successful sell must be reflected exactly once in the inventory. After all threads finish, the final count must equal initial + (sum of all bought quantities) - (sum of all successfully sold quantities) .
  3. Atomic check-then-act. The availability check inside sell and the corresponding deduction must happen atomically with respect to all other buy and sell calls — no other operation may interleave between the check and the update.

You may use the standard synchronization primitives provided by your language's library (mutexes/locks, atomic operations, condition variables, etc.). Keep the critical sections as small as correctness allows.

Example

Single-threaded illustration of the required semantics:

inv = StockInventory(100)
inv.sell(30)   -> true    (70 shares remain)
inv.sell(80)   -> false   (only 70 available; inventory unchanged at 70)
inv.buy(50)    -> 120     (70 + 50)
inv.sell(120)  -> true    (0 shares remain)
inv.sell(1)    -> false   (inventory unchanged at 0)

Under concurrency, any interleaving of the calls is acceptable as long as every individual operation is atomic, the no-overselling invariant holds, and the final count is consistent with the set of operations that succeeded.

Constraints

  • 0 <= initial <= 10^9
  • 1 <= quantity <= 10^9 for every buy and sell call
  • Up to 10^5 total operations, issued from up to 64 concurrent threads
  • Each operation should complete in amortized O(1)O(1)O(1) time outside of contention for the synchronization primitive

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More Coding & Algorithms•More Optiver•More Software Engineer•Optiver Software Engineer•Optiver Coding & Algorithms•Software Engineer Coding & Algorithms
PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.