← Uber Interview Insights

Uber·Software Engineer·Technical Phone Screen·Senior

Senior
Apr 2026

Summary

Uber SWE interview with a concurrency-heavy coding question that felt more like a systems puzzle than a typical algo problem. The synchronization angle made it trickier than it looked on the surface.

Questions Asked (1)

Q1

Design a class with three methods alpha(), beta(), and gamma() that can be called by three separate threads in any order, but must always print output in the sequence A, B, C, repeated for N cycles. You need to use proper synchronization (no busy-waiting), and be ready to talk through fairness, deadlock risks, and performance tradeoffs.

System DesignTechnical Trade-offsAlgorithms & Data Structures
Author's notes

I went straight to semaphores and sketched out a solution where each method waits on a permit before printing and then signals the next one.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem constraints and then propose a solution using a shared lock and condition variables to enforce the A→B→C order without busy-waiting. Explain how each method waits for its turn, prints, updates the shared state, and signals the next thread, ensuring thread safety and liveness. Finally, discuss trade-offs like fairness, deadlock avoidance, and performance under contention.

Pro tip: Mention that using a single lock with condition variables is simpler and less error-prone than multiple locks, but if performance is critical, consider a lock-free approach with atomic variables and careful memory ordering. Also, highlight that you would test with stress tests and thread sanitizers to catch subtle bugs.

1. Clarify requirements and constraints

Confirm the exact output sequence, the number of cycles N, and that threads may call methods in any order. Ask about performance expectations and whether busy-waiting is strictly prohibited.

2. Design synchronization mechanism

Choose a shared lock (e.g., ReentrantLock) and condition variables (or wait/notify) to coordinate threads. Each method waits until it's its turn, based on a shared state variable indicating whose turn it is.

3. Implement the coordination logic

In each method, acquire the lock, wait while it's not the thread's turn, print the letter, update the turn to the next thread, signal the next thread, and release the lock. Ensure the loop runs N times.

4. Analyze correctness and liveness

Verify that the solution avoids deadlock (e.g., by ensuring the lock is always released and signals are sent), and that all threads eventually make progress. Discuss fairness and potential starvation.

5. Discuss trade-offs and alternatives

Compare the lock-based approach with alternatives like semaphores or atomic variables. Discuss performance implications, such as context switching overhead and scalability.

Key Points to Mention

  • Use of a shared lock and condition variables (or wait/notify) to avoid busy-waiting.
  • Maintaining a shared state variable (e.g., turn) to track whose turn it is.
  • Ensuring proper signaling to wake up the next thread and avoid missed signals.
  • Deadlock avoidance by always releasing locks and using timeouts if necessary.
  • Fairness considerations: whether threads are guaranteed to progress in order without starvation.
  • Performance trade-offs: lock contention, context switching overhead, and potential for lock-free alternatives.

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