Citadel logo

Citadel Interview Questions

24 practice questions for Citadel technical interviews

Citadel software engineer interviews cover algorithms, data structures, system design, and coding problems drawn from real interview rounds.

Software Engineer Backend Engineer Frontend Engineer Full Stack Engineer Mobile Engineer Data Engineer Data Scientist ML Engineer DevOps Engineer DevOps Engineer Product Manager SRE Security Engineer Engineering Manager Data Analyst UX/UI Designer QA Engineer
coding Medium Verified Question #1

1. DAG Order Validator


Category: Topological sort coding problem

DAG Order Validator Given a Directed Acyclic Graph (DAG) and a list of nodes, determine if the list represents a valid topological sort...

Input: Graph (nodes and edges)
Output: Computed result
coding Medium Verified Question #2

2. Expression Evaluator


Category: String coding problem

Expression Evaluator You need to design and implement an expression evaluator that parses and computes mathematical expressions formatted in...

Input: String
Output: Computed result
coding Medium Verified Question #3

3. Knight Moves on Phone


Category: String coding problem

Knight Moves on Phone This problem is split into two parts.

Input: List
Output: Integer
coding Medium Verified Question #4

4. Price Change Aggregator


Category: Algorithm coding problem

Price Change Aggregator You are building a system to aggregate price updates from multiple feeds to reconstruct the price history of an asset.

Input: List
Output: Computed result
coding Hard Verified Question #5

5. Visit All Cities


Category: Graph coding problem

Visit All Cities You are given a list of airline tickets where each ticket represents a directed edge from a departure airport to an arrival...

Input: Graph (nodes and edges)
Output: Computed result
coding Medium Verified Question #6

6. Social Network Friend Suggester


Category: Array coding problem
Build a friend recommendation system for a social network. Given n users (indexed 0 to n - 1) and a list of existing friendships (undirected...
Input: Array
Output: Array
coding Medium Verified Question #7

7. Minimum Sum Tree Path


Category: Binary tree coding problem

Minimum Sum Tree Path

Input: Binary tree
Output: Computed result
coding Medium Verified Question #8

8. Dial Pad Knight Paths


Category: Algorithm coding problem

Dial Pad Knight Paths

Input: Number(s)
Output: Integer
coding Hard Verified Question #9

9. Subsequence Goodness Values


Category: Array coding problem

Subsequence Goodness Values

Input: Array
Output: Integer
coding Medium Verified Question #10

10. Sliding Window Top K


Category: Sliding window coding problem

Sliding Window Top K

Input: Array of integers
Output: Computed result
coding Medium Verified Question #11

11. Price Stream Merger


Category: Heap-based coding problem

Price Stream Merger

Input: List
Output: Computed result
coding Hard Verified Question #12

12. Pandigital Addition Count


Category: Algorithm coding problem

Pandigital Addition Count

Input: Integer(s)
Output: Computed result
coding Medium Verified Question #13

13. Closest Point Pair


Category: Algorithm coding problem

Closest Point Pair

Input: List
Output: Integer
coding Hard Verified Question #14

14. Flight Itinerary Planner


Category: Graph coding problem

Flight Itinerary Planner

Input: Graph (nodes and edges)
Output: Computed result
coding Hard Verified Question #15

15. Process Schedule Counter


Category: Algorithm coding problem

Process Schedule Counter

Input: List
Output: Integer
coding Medium Verified Question #16

16. [CodeSignal] Common Free Slot


Category: Interval-based coding problem

[CodeSignal] Common Free Slot

Input: List
Output: Computed result
coding Easy Verified Question #17

17. [CodeSignal] Stable Server Segments


Category: Array coding problem

[CodeSignal] Stable Server Segments

Input: Array
Output: Computed result
coding Medium concurrency #1

1. [Concurrency] — Implementing a Thread-Safe In-Memory Order Book

Background: Citadel operates in the finance sector, where a high-performance order book is crucial for trading. Properly managing orders in a concurrent environment without losing data integrity is essential.
Problem statement: Implement a thread-safe in-memory order book that can handle incoming orders and allow retrieval of current orders. You need to ensure that multiple threads can add, remove, and view orders without data corruption. Use a data structure for storing orders, ensuring that concurrent modifications don't lead to inconsistent views of the orders.
Function/class signature:
  • class OrderBook:

  • def add_order(order_id: str, price: float, quantity: int) -> None: Adds an order to the order book.

  • def remove_order(order_id: str) -> bool: Removes an order from the order book by order ID.

  • def get_current_orders() -> List[Dict[str, Union[str, float, int]]]: Returns a list of current orders.

Example 1:
Input: add_order("123", 100.0, 5)
Output: None
Explanation: Adds an order with ID "123", price 100.0, and quantity 5.
Example 2:
Input: remove_order("123")
Output: True
Explanation: Removes the order with ID "123" successfully.
Constraints:
  • Order ID is a unique string.

  • Price is a positive float.

  • Quantity is a positive integer.

  • The maximum number of orders is 1,000,000.

  • The solution must be thread-safe.
coding Medium dynamic programming #2

2. Dynamic Programming — Longest Consecutive Sequence

Background: Citadel deals with a vast amount of data and needs to identify patterns quickly for data analysis and decision-making. Finding the longest consecutive sequence in a dataset could play a vital role in financial modeling and forecasting.
Problem statement: You are given an unsorted array of integers. Your task is to find the length of the longest consecutive elements sequence. The consecutive elements can be from any range of numbers. You need to return the length of this sequence.
Function/class signature:
  • def longest_consecutive(nums: List[int]) -> int:


Example 1:
  • Input: nums = [100, 4, 200, 1, 3, 2]

  • Output: 4

  • Explanation: The longest consecutive sequence is [1, 2, 3, 4], which has a length of 4.


Example 2:
  • Input: nums = [0, 3, 7, 2, 5, 8, 4, 6, 1]

  • Output: 9

  • Explanation: The longest consecutive sequence is [0, 1, 2, 3, 4, 5, 6, 7, 8], which has a length of 9.


Constraints:
  • 0 <= nums.length <= 10^4

  • -10^9 <= nums[i] <= 10^9
coding Hard concurrency #3

3. Concurrency — Optimize a function for concurrency

Background: In high-frequency trading systems at Citadel, optimizing for concurrency is crucial to maximize throughput and minimize latency. When managing trades and market data, optimizing access and updates to shared resources is essential.
Problem statement: You need to design a function optimizeConcurrency that takes a list of trades to process concurrently. Each trade requires an update to a shared orderBook, but the updates should not conflict. Use appropriate data structures to minimize locking and waiting.
Function/class signature:
  • def optimizeConcurrency(trades: List[Dict[str, int]]) -> List[Optional[int]]:

  • def updateOrderBook(trade: Dict[str, int]) -> None:


Example 1:
  • Input: trades = [{'id':1, 'amount':100}, {'id':2, 'amount':200}, {'id':1, 'amount':150}]

  • Output: None

  • Explanation: The function should process trades concurrently and reflect the latest amount for each unique trade ID in the order book without conflicts.


Example 2:
  • Input: trades = [{'id':3, 'amount':300}, {'id':4, 'amount':400}]

  • Output: None

  • Explanation: Similar processing for these trades, ensuring each update is atomic and thread-safe.


Constraints:
  • 1 <= trades.length <= 1000

  • Trade IDs are between 1 and 10000.

  • The function should handle up to 100 concurrent updates.
coding Hard concurrency #4

4. CODING — Optimize for Concurrency in an Order Book

Background: Citadel's trading strategies depend on efficient order book management. An in-memory order book allows traders to process orders quickly and adjust to market conditions dynamically.
Problem statement: You are tasked with optimizing a function that handles buy and sell orders in a thread-safe manner. You should implement a class that supports concurrent access while ensuring that orders are processed correctly. The order book allows for adding and removing orders and retrieving the current best buy and sell prices. The key requirements involve handling multiple threads without introducing race conditions.
Function/class signature:
  • class OrderBook

  • def add_order(self, order_id: str, price: float, quantity: int, order_type: str) -> None:

  • def remove_order(self, order_id: str) -> None:

  • def get_best_buy(self) -> Tuple[float, int]:

  • def get_best_sell(self) -> Tuple[float, int]:

Example 1:
  • Input: add_order('1', 100.0, 10, 'buy')

  • Output: None

  • Explanation: A buy order with ID '1' for 10 units at $100 is added.

Example 2:
  • Input: add_order('2', 105.0, 5, 'sell')

  • Output: None

  • Explanation: A sell order with ID '2' for 5 units at $105 is added. Now, get_best_buy() should return (100.0, 10) and get_best_sell() should return (105.0, 5).

Constraints:
  • 1 <= order_id <= 10^5

  • Price and quantity are non-negative floats and integers respectively.

  • Concurrent calls to add_order and remove_order may occur, but please ensure consistency in retrieval methods.
coding Medium graph #5

5. Graph — Find minimum number of steps to reach the target node

Background: In financial modeling and algorithmic trading, Citadel needs to navigate data structures efficiently for optimal decision-making. This problem relates to traversing market data represented in a graph.
Problem statement: Given a directed graph represented as an adjacency list, find the minimum number of edges required to reach from a start node to a target node. Consider each edge represents a possible market movements. The goal is to help traders optimize their strategies by determining the quickest route through the data structure.
Function/class signature:
  • def min_steps(graph: List[List[int]], start: int, target: int) -> int:

Example 1:
Input: graph = [[1,2],[2],[3],[4],[]], start=0, target=4
Output: 3
Explanation: 0 -> 1 -> 2 -> 4 requires 3 steps.
Example 2:
Input: graph = [[1],[2],[3],[4],[5],[]], start=0, target=5
Output: 5
Constraints:
  • The graph will have at most 100 nodes.

  • Each node will have at most 10 outgoing edges.

  • 0 <= start, target < 100

  • The input graph is zero-based indexed.
coding Hard graph #6

6. Graph — Find the shortest path in a trading network

Background: Citadel relies on efficient trading algorithms to quickly make transactions across different markets. Understanding the shortest routes between various venues can optimize trade execution.
Problem statement: In a network of trading venues represented as a directed graph, where each edge represents the time taken to execute a trade between two venues, your task is to find the shortest time to get from a source venue to a target venue. Implement Dijkstra's algorithm to determine the minimum execution time.
Function/class signature:
  • def shortest_time(venues: List[Tuple[int, int, int]], source: int, target: int) -> int:

Example 1:
  • Input: venues = [(0, 1, 5), (0, 2, 10), (1, 2, 2), (2, 3, 1)], source = 0, target = 3

  • Output: 8

  • Explanation: The shortest path is from 0 -> 1 -> 2 -> 3 with a total time of 5 + 2 + 1 = 8.

Example 2:
  • Input: venues = [(0, 1, 8), (1, 3, 6), (0, 2, 7), (2, 3, 2)], source = 0, target = 3

  • Output: 9

  • Explanation: The optimal path is 0 -> 2 -> 3 with a total time of 7 + 2 = 9.

Constraints:
  • 1 <= len(venues) <= 1000

  • 0 <= venue index < 100

  • Execution time is positive integer and does not exceed 1000.
coding Hard graph #7

7. Graph — Shortest Path in a Weighted Graph

Background: Citadel often deals with financial algorithms that require efficient pathfinding through complex market data represented as graphs. This problem is crucial for optimizing trade routes.
Problem statement: Given a weighted directed graph represented as an adjacency list, your task is to implement a function that calculates the shortest path from a source node to a target node using Dijkstra’s algorithm. Each edge weight represents the cost for trading between nodes, and you need to return the minimum trading cost.
Function/class signature:
  • def shortest_path(graph: Dict[int, List[Tuple[int, float]]], source: int, target: int) -> float:


Example 1:
Input: graph = {0: [(1, 2.0), (2, 4.0)], 1: [(2, 1.0)], 2: []}
Output: 3.0
Explanation: The shortest path from node 0 to node 2 is via node 1 with a total cost of 2.0 + 1.0 = 3.0.
Example 2:
Input: graph = {0: [(1, 10.0)], 1: [(2, 5.0)], 2: [(3, 1.0)], 3: []}
Output: 16.0
Explanation: The shortest path is from 0 to 1 to 2 to 3 with total cost 10.0 + 5.0 + 1.0 = 16.0.
Constraints:
  • 1 <= len(graph) <= 100

  • 0 <= source, target < len(graph)

  • weights are positive doubles.

Start practicing Citadel questions

Sign up for free to access walkthroughs, AI-generated questions, and more.

Get Started Free