← PayPal Interview Insights

PayPal·Software Engineer·Technical Phone Screen·Senior

Senior
Jul 2026

Summary

PayPal software engineer interview with a deep dive into Java internals. The question felt more like a grad-school exam than a typical coding screen, which I wasn't fully prepared for.

Questions Asked (2)

Q1

Walk me through how HashMap works internally in Java, including the underlying data structures and how the implementation changed across different Java versions.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

I knew the basics: array of buckets, linked list chaining, load factor.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by explaining the core data structure (array of buckets) and the put/get operations, then detail the collision resolution mechanism (linked list to red-black tree in Java 8+). Finally, highlight key changes across Java versions (e.g., treeification, hash function improvements) and discuss trade-offs like time complexity and resizing.

Pro tip: Mention that while HashMap is not thread-safe, ConcurrentHashMap uses similar principles with finer-grained locking; this shows awareness of concurrency trade-offs relevant to PayPal's high-throughput systems.

1. Core Data Structure

Explain that HashMap uses an array of Node objects (buckets) where each Node stores key, value, hash, and next pointer. The array size is a power of two for efficient indexing.

2. Put and Get Operations

Describe how put computes hash, finds bucket index via (n-1) & hash, and handles collisions by traversing the linked list or tree. Get follows the same process to locate the key.

3. Collision Resolution

Explain that collisions are resolved via chaining: initially linked lists, but since Java 8, if a bucket's list exceeds 8 nodes and array size >= 64, it converts to a red-black tree for O(log n) search.

4. Resizing and Load Factor

Discuss that when size exceeds load factor (default 0.75) * capacity, the array doubles and all entries are rehashed. This amortizes to O(1) but can cause temporary performance hits.

5. Version Changes and Trade-offs

Highlight Java 7 vs 8 differences: Java 7 used linked lists only and had a weaker hash function; Java 8 introduced treeification, improved hash spreading, and changed resize logic to avoid infinite loops. Mention trade-offs like memory overhead vs. performance.

Key Points to Mention

  • Array of buckets with power-of-two sizing for fast modulo via bitwise AND.
  • Hash function: key.hashCode() XOR (hashCode >>> 16) for better distribution.
  • Collision resolution: linked list chaining, upgraded to red-black tree in Java 8 when threshold exceeded.
  • Load factor and resizing: default 0.75, doubling capacity, rehashing all entries.
  • Java 8 improvements: treeification, better hash spreading, and resize logic to prevent infinite loops.
  • Time complexity: average O(1) for get/put, worst-case O(n) or O(log n) with tree, and O(n) during resize.

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

Q2

Beyond separate chaining, what other collision resolution strategies exist for hash maps, and what are the real trade-offs between them in terms of time complexity, memory usage, and cache performance?

Algorithms & Data StructuresTechnical Trade-offsSystem Design
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 acknowledging separate chaining, then introduce open addressing (linear probing, quadratic probing, double hashing) and other strategies like cuckoo hashing and robin hood hashing. Compare them across time complexity, memory usage, and cache performance, emphasizing real-world trade-offs and when each is preferable.

Pro tip: Mention that open addressing with linear probing often outperforms chaining in practice due to cache locality, but requires careful load factor management to avoid clustering. Also, note that Java's HashMap uses chaining while Python's dict uses open addressing, showing you know real implementations.

1. Define collision resolution

Briefly explain that collision resolution handles cases where two keys hash to the same index, and separate chaining is one approach.

2. List alternative strategies

Introduce open addressing (linear probing, quadratic probing, double hashing), cuckoo hashing, and robin hood hashing as key alternatives.

3. Compare time complexity

Discuss average and worst-case time complexities for insert, search, and delete, noting that open addressing degrades with high load factors.

4. Analyze memory usage

Compare memory overhead: chaining uses extra pointers and nodes, while open addressing stores entries directly in the table but may need larger table size.

5. Evaluate cache performance

Explain that open addressing has better cache locality due to contiguous memory access, while chaining suffers from pointer chasing and scattered memory.

Key Points to Mention

  • Open addressing: linear probing, quadratic probing, double hashing
  • Cuckoo hashing and robin hood hashing as advanced strategies
  • Time complexity: average O(1) for all, but worst-case O(n) for open addressing under high load
  • Memory usage: chaining has overhead for pointers and nodes; open addressing may waste space with tombstones
  • Cache performance: open addressing is cache-friendly; chaining causes cache misses
  • Load factor impact: open addressing requires lower load factor (e.g., 0.7) to maintain performance

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