← Coinbase Interview Insights

Coinbase·Software Engineer·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
May 2026Remote

Summary

Coinbase software engineer interview with a multi-level in-memory system design coding problem. The whole thing was structured as an incremental build, starting simple and getting more complex as you go. Pretty classic for this kind of role but the versioning level tripped me up more than I expected.

Questions Asked (4)

Q1

Design and implement basic CRUD operations for an in-memory recipe store: add, update, get, and delete, with clear behavior defined for edge cases like missing records.

System DesignAPI & IntegrationsData Modeling
Author's notes

Started fine, picked a hashmap keyed by recipeId and just rejected duplicates on add rather than overwriting.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and defining the data model and API contract, then implement the CRUD operations with explicit handling for edge cases like missing records. Emphasize thread safety and error handling, and discuss trade-offs of in-memory storage.

Pro tip: Mention that you would use a concurrent hash map or locking to ensure thread safety, and define clear error responses (e.g., 404 for missing records) to make the API robust and predictable.

1. Clarify Requirements and Define Data Model

Ask about expected operations, data fields, and concurrency needs. Define a Recipe class with id, name, ingredients, and instructions.

2. Design API Contract

Specify method signatures for add, update, get, and delete, including input parameters and return types. Define error behavior for missing records (e.g., throw exception or return null/optional).

3. Implement CRUD Operations

Use a thread-safe data structure like ConcurrentHashMap. For add, generate a unique ID; for update, check existence and replace; for get, return record or indicate not found; for delete, remove and indicate success/failure.

4. Handle Edge Cases and Concurrency

Address missing records, duplicate IDs, null inputs, and concurrent modifications. Use atomic operations or locks to prevent race conditions.

5. Discuss Trade-offs and Extensions

Talk about limitations of in-memory storage (persistence, scalability) and how you might extend to a database or add caching.

Key Points to Mention

  • Thread safety using ConcurrentHashMap or synchronized blocks
  • Clear error handling for missing records (e.g., return Optional.empty() or throw custom exception)
  • Unique ID generation for recipes (e.g., UUID or atomic counter)
  • Immutability of Recipe objects to prevent accidental modification
  • API design principles: consistent naming, input validation, and idempotency
  • Trade-offs of in-memory storage: fast access vs. data loss on restart

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

Q2

Implement a case-insensitive recipe search by name and a list function that sorts recipes by name or size, with a defined tie-breaking rule.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The substring vs exact match decision is where I wasted time second-guessing myself.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: case-insensitive search by name, sorting by name or size, and tie-breaking rule. Then design data structures and algorithms, discussing trade-offs (e.g., hash map for search, sorting with custom comparator). Finally, implement and test edge cases.

Pro tip: Demonstrate awareness of real-world constraints: mention that case-insensitive search often requires normalization (e.g., Unicode) and that sorting stability matters for tie-breaking. Also, discuss time/space complexity and potential optimizations like indexing.

1. Clarify Requirements

Ask about search specifics (exact match vs. substring), sorting criteria (ascending/descending), and tie-breaking rule (e.g., by name if sizes equal). Confirm input/output formats.

2. Design Data Structures

Choose appropriate structures: for search, a hash map with normalized keys (e.g., lowercase) or a trie; for sorting, a list of recipes with comparators. Consider memory vs. speed trade-offs.

3. Implement Search

Normalize query and stored names (e.g., to lowercase) for case-insensitive matching. If substring search is needed, consider more complex structures like suffix trees or simply iterate with normalization.

4. Implement Sorting

Define a comparator that sorts by the chosen key (name or size) and applies the tie-breaking rule (e.g., if sizes equal, sort by name). Ensure the sort is stable if needed.

5. Analyze and Test

Discuss time/space complexity of operations. Test edge cases: empty list, duplicate names/sizes, non-ASCII characters, and large datasets.

Key Points to Mention

  • Case-insensitive normalization techniques (e.g., toLowerCase, Unicode normalization)
  • Trade-offs between different data structures for search (hash map vs. trie vs. linear scan)
  • Comparator design and tie-breaking logic in sorting
  • Time and space complexity of search and sort operations
  • Handling edge cases: empty inputs, duplicates, special characters
  • Potential optimizations: indexing, caching, or using database features if applicable

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

Q3

Add user management to the system with an addUser operation. Define what happens on duplicate userId.

API & IntegrationsData Modeling
Author's notes

Easiest part of the whole thing.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then propose a data model and API contract for addUser, explicitly defining duplicate userId handling. Discuss trade-offs of different duplicate strategies (e.g., reject, idempotent success, upsert) and justify your choice based on system needs and Coinbase's context.

Pro tip: In fintech, idempotency and auditability are critical. Consider making addUser idempotent for duplicate userIds to avoid duplicate account creation, and always log attempts for compliance.

1. Clarify Requirements

Ask about expected behavior on duplicates, idempotency needs, and any regulatory constraints. Confirm whether userId is client-supplied or server-generated.

2. Design Data Model

Define the User entity with userId as a unique key. Consider using a database unique constraint to enforce uniqueness at the storage layer.

3. Define API Contract

Specify the addUser endpoint: request/response schema, HTTP status codes, and error format. For duplicates, choose a strategy (e.g., 409 Conflict, 200 OK with existing user, or 201 Created if idempotent).

4. Handle Duplicates

Implement duplicate detection: check existence before insert or catch unique constraint violation. Decide on the response: reject with error, return existing user, or update (upsert).

5. Discuss Trade-offs

Compare strategies: strict rejection ensures data integrity but may frustrate clients; idempotent success simplifies retries but may hide errors. Choose based on use case and document behavior.

Key Points to Mention

  • Idempotency: making addUser idempotent for duplicate userIds to support safe retries.
  • Database unique constraint on userId to prevent duplicates at the storage layer.
  • HTTP status codes: 201 Created for new user, 409 Conflict for duplicate, or 200 OK for idempotent success.
  • Error response format: consistent, machine-readable error codes and messages.
  • Concurrency: handling race conditions when two requests with same userId arrive simultaneously.
  • Audit logging: recording duplicate attempts for security and compliance.

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

Q4

Add version history and rollback support so that every mutating operation creates a new version and the system can be restored to any prior version by version ID.

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

This is where things got interesting and not in a good way.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: what entities need versioning, expected read/write patterns, and rollback semantics (e.g., full restore vs. selective). Then propose a design that captures each mutation as an immutable version, using a versioned data model (e.g., append-only log or versioned rows) and a rollback mechanism that creates a new version pointing to the old state. Discuss trade-offs around storage, consistency, and performance, and outline how you'd implement and test it.

Pro tip: Emphasize idempotency and auditability: every mutation should be idempotent and produce an immutable version, which is crucial for financial systems like Coinbase. Also, mention that rollback should itself be a versioned operation to maintain a complete history.

1. Clarify Requirements and Scope

Ask questions to understand which entities need versioning, what operations are considered mutations, and what 'restore' means (e.g., full entity state, partial fields). Determine read/write ratios and consistency requirements.

2. Design Versioned Data Model

Propose a schema where each version is immutable and identified by a version ID. Options include: append-only log with entity ID and version number, or a versioned table with valid-from/valid-to timestamps. Discuss how to efficiently retrieve the latest version and any version by ID.

3. Implement Rollback Mechanism

Define rollback as creating a new version that replicates the state of the target version. This preserves history and avoids destructive updates. Explain how to handle concurrent mutations and ensure atomicity.

4. Address Trade-offs and Scalability

Discuss storage overhead (e.g., full snapshots vs. deltas), read performance (indexing on version ID), and consistency (e.g., using transactions or event sourcing). Consider garbage collection or archival policies for old versions.

5. Outline Implementation and Testing

Sketch the API changes (e.g., endpoints for listing versions and rolling back), and describe how you'd test correctness (e.g., property-based tests for rollback) and performance under load.

Key Points to Mention

  • Immutable versions and append-only storage for auditability
  • Version ID as a unique identifier (e.g., UUID, timestamp, or monotonic counter)
  • Rollback as a new version to maintain history and idempotency
  • Trade-offs between storage cost and read performance (e.g., snapshots vs. deltas)
  • Concurrency control and atomicity for mutations and rollbacks
  • Indexing strategies to efficiently retrieve any version by ID

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