Katkat

Design adjustable ID allocator

PinterestSoftware Engineer · Onsite

Last updated

A Pinterest software-engineer onsite coding problem: design an adjustable ID allocator over a fixed [0, 999] ID space with named, contiguous, non-overlapping bucket ranges. It covers initial allocation (packing from desired sizes and validating/normalizing proposed ranges), a resize operation that grows or shrinks a bucket by consuming adjacent free space and then minimally shifting or borrowing from neighbors under a deterministic policy, plus complexity analysis, boundary-case testing, and concurrency handling.

Question

You manage a fixed global integer ID space [0, 999] (1000 IDs total) and a set of named buckets. Each bucket has a unique name and occupies a contiguous, inclusive range of IDs [start, end]. Ranges must always stay non-overlapping, in bounds, and (depending on the variant) in a fixed order; any IDs not owned by a bucket are considered free. Design the data structures and APIs, then implement the following operations.

  1. Initial allocation / assignment. Implement an operation that takes the initial bucket specifications and assigns each bucket a valid contiguous range. Support both common framings:
  • Given a list of (name, desired_size) in a fixed order, pack the buckets contiguously from low IDs to high IDs, preserving the given order, and return [(name, start_id, end_id), ...]. Fail with a clear error if the sum of desired sizes exceeds 1000 (capacity).
  • Given a list of buckets that already carry proposed [start, end] ranges, validate and normalize them so they are within [0, 999], non-overlapping, and returned sorted by start. Leave any unassigned IDs free (allow gaps between buckets).
  1. Resize a bucket. Implement resize(name, new_desired_size) (or resize(buckets, name, desired_size)) that grows or shrinks the named bucket so it owns exactly new_desired_size IDs, while keeping every range contiguous, disjoint, in bounds, and (where required) in order:
  • When growing, prefer consuming immediately adjacent free space first.
  • If adjacent free space is insufficient, recover space by minimally shifting only the neighboring ranges, or by borrowing from neighboring buckets using a deterministic policy (e.g., take from the nearest bucket that has the largest surplus). Shifts/borrows must be the minimum needed to satisfy the request.
  • When shrinking, return the freed IDs to the free pool (or to neighbors per policy).
  • If the request cannot be satisfied within total capacity, return a clear, well-defined error and leave the layout unchanged.
  1. Analysis and follow-ups.
  • State the data structures you chose and the time/space complexity of each operation.
  • Describe how you would test boundary cases: empty bucket list, a zero-size bucket, full utilization (sum == 1000), expansions that would overflow capacity, resizing the first/last bucket, and resizing a non-existent name.
  • Discuss how you would handle concurrent or conflicting resize calls (e.g., locking, optimistic versioning, or a deterministic ordering/serialization of requests).