Katkat

Design a Recipe and Inventory Ordering Service

StackAdaptSoftware Engineer · Technical Screen

Last updated

Design an object-oriented recipe service where nested dishes consume raw inventory and an order either succeeds atomically or changes nothing. The prompt tests typed references, cycle detection, quantity expansion, overflow handling, concurrent stock updates, immutable views, and explicit replacement and query semantics.

Design a Recipe and Inventory Ordering Service

Scenario

Design an object-oriented service with recipes, supplies, and orders. A recipe has a unique name, a stored preparation time, and ingredient requirements with positive integer quantities. A supply entry represents the available count of a raw ingredient. A recipe may use another recipe as an ingredient, so ordering a dish recursively consumes the required raw supplies.

For this exercise, recipe dependencies must be acyclic. placeOrder(recipeName) returns true only when the recipe exists, its dependency graph is valid, and all required raw inventory can be decremented atomically; otherwise it returns false and changes nothing. A getter that filters by preparation time uses each recipe's stored time rather than summing nested times. If you choose different semantics, state them before designing the API.

Part 1: Model recipes, ingredient references, and supply

Define the core types, invariants, and public operations such as addRecipe, addSupply, placeOrder, and query methods.

What This Part Should Cover

  • Unique identifiers or namespace rules for recipes and raw ingredients.
  • Positive quantities, nonnegative stock, and preparation-time validation.
  • A typed way to distinguish a raw ingredient reference from a nested recipe reference.
  • Whether add operations replace, reject, or version an existing definition.
  • Encapsulation that prevents callers from mutating stored objects behind the service.

Part 2: Validate and expand nested recipes

Explain how adding or ordering a recipe detects cycles and turns nested requirements into aggregate raw-ingredient quantities.

What This Part Should Cover

  • Missing references and direct or indirect dependency cycles.
  • Multiplication and aggregation when the same raw ingredient appears through several paths.
  • Integer overflow or maximum-quantity handling.
  • Memoization or another way to avoid repeatedly expanding shared sub-recipes.

Part 3: Make placeOrder atomic

Design the check-and-decrement operation so insufficient stock or concurrent orders cannot produce partial or negative inventory.

What This Part Should Cover

  • Expanding and aggregating all raw requirements before changing stock.
  • Checking every required count before applying any decrement.
  • A locking, transaction, or version-check strategy for concurrent calls.
  • Clear failure behavior for unknown dishes, invalid graphs, overflow, and insufficient stock.

Part 4: Define getters and tests

Specify useful read methods, including a query for recipes with preparation time greater than a threshold, and the tests needed for boundary cases.

What This Part Should Cover

  • Deterministic ordering and immutable return values.
  • Whether the threshold comparison is strict or inclusive.
  • Tests for nested quantities, shared ingredients, missing references, cycles, exact stock, insufficient stock, and concurrent orders.
  • Behavior after recipe replacement or supply replenishment.

Hints

Hint 1

Make references unambiguous: A plain ingredient-name string becomes ambiguous if a recipe and a raw supply can share the same name.

Hint 2

Track traversal states: Treat recipe expansion as a graph problem and distinguish nodes currently being visited from nodes already completed.

Hint 3

Close the concurrency gap: Separating validation from mutation is necessary but not sufficient if another order can modify stock between those steps.

Hint 4

Turn ambiguity into a contract: Make every ambiguous boundary visible in a method contract before writing its test.

Follow-up questions

  • How would you support ordering more than one serving at a time?
  • What changes if recipes and inventory definitions must be versioned?
  • How would you reserve stock for an order that is prepared asynchronously?
  • How would you expose the exact shortage without weakening atomicity?