← Google Interview Insights

Google·Software Engineer·Onsite - Coding / Algorithms·Senior

SeniorPrefer not to say
Jun 2026

Summary

Google SWE interview, coding round focused on a data structure design problem that looked deceptively simple at first. The follow-up on concurrency is where things got real.

Questions Asked (2)

Q1

Design a data structure that supports insert, delete, and get-random-element, all in O(1) average time.

Algorithms & Data Structures
Author's notes

I knew this one.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Combine a dynamic array for O(1) random access with a hash map for O(1) insert/delete by storing each element's index. When deleting, swap the target with the last element, update the map, and pop the array. This ensures all operations average O(1).

Pro tip: Mention that the hash map must store indices, and that deletion requires swapping with the last element to maintain O(1) and avoid shifting. Also note that duplicates require careful handling, such as storing a set of indices per value.

1. Clarify requirements

Confirm that elements are unique or discuss handling duplicates, and that getRandom should return each element with equal probability.

2. Choose data structures

Select a dynamic array (e.g., ArrayList in Java, list in Python) for O(1) random access and a hash map (dictionary) for O(1) lookups.

3. Design insert operation

Append the new element to the array and record its index in the hash map.

4. Design delete operation

To delete, swap the target element with the last element in the array, update the hash map for the swapped element, then remove the last element from both the array and the map.

5. Design getRandom operation

Generate a random index within the array's bounds and return the element at that index.

Key Points to Mention

  • Use a dynamic array for O(1) random access by index.
  • Use a hash map to store element-to-index mappings for O(1) lookups.
  • For deletion, swap with the last element to avoid O(n) shifting.
  • Update the hash map when swapping to maintain correct indices.
  • Handle duplicates by storing a set of indices per value in the hash map.
  • Analyze time complexity: O(1) average for all operations, assuming hash map operations are O(1) on average.

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

Q2

How would you extend that data structure to be thread-safe under concurrent add, delete, and get-random operations? Walk through at least two designs and compare them.

System DesignTechnical Trade-offs
Author's notes

This is where I started sweating.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by briefly restating the data structure (e.g., dynamic array with hash map for O(1) operations) and its invariants. Then present two distinct concurrency designs: coarse-grained locking and fine-grained locking (or lock-free). For each, explain the mechanism, analyze trade-offs in performance, scalability, and complexity, and conclude with a recommendation based on expected workload.

Pro tip: Acknowledge that 'thread-safe' doesn't mean 'lock everything'—discuss how read-heavy workloads might benefit from read-write locks or copy-on-write, and mention that Google often values scalability and simplicity over micro-optimizations.

1. Restate the data structure and operations

Briefly describe the underlying data structure (e.g., array + hash map) and the add, delete, get-random operations, highlighting the invariants that must be preserved under concurrency.

2. Design 1: Coarse-grained locking

Propose a single mutex protecting the entire structure. Explain how each operation acquires the lock, performs the operation, and releases it. Discuss simplicity and correctness, but note limited scalability due to serialization.

3. Design 2: Fine-grained locking or lock-free

Propose a more concurrent design, such as per-bucket locks for the hash map and a separate lock for the array, or a lock-free approach using atomic operations. Explain how operations coordinate to maintain consistency.

4. Compare trade-offs

Analyze each design in terms of performance (throughput, latency), scalability (contention, number of cores), complexity (implementation, debugging), and memory overhead. Mention scenarios where each is preferable.

5. Recommend and conclude

Based on the comparison, recommend one design for a given workload (e.g., read-heavy vs write-heavy) and summarize key considerations.

Key Points to Mention

  • Invariants: array elements are contiguous, hash map maps values to indices, and get-random requires uniform selection.
  • Coarse-grained locking: single mutex, simple but serializes all operations, poor scalability.
  • Fine-grained locking: separate locks for array and hash map, or per-bucket locks, reducing contention but increasing complexity and potential deadlocks.
  • Lock-free approach: using atomic operations (e.g., CAS) for updates, but challenging to maintain consistency between array and hash map.
  • Read-write locks: allow concurrent reads (get-random) but exclusive writes (add/delete), improving read-heavy performance.
  • Performance metrics: throughput, latency, scalability with cores, and contention hotspots.

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