Goldman Sachs OA has always been a bit "out of the ordinary." Unlike other financial firms that favor mathematical derivation or SQL cases, its questions feel more like algorithm competitions—clear logic, high implementation bar, with a touch of engineering flavor. The two questions this time, one on data structures and one on number-theory optimization, were both clever—the kind you keep mulling over after finishing.
1. Overall Process and Difficulty
| Item | Detail |
|---|---|
| Platform | HackerRank |
| Duration | ~90 minutes (two questions) |
| Language | Python / C++ / Java (your choice) |
| Difficulty | Upper-middle (hardcore logic, not math-heavy) |
GS OA generally looks at three areas:
- Data structures and implementation: whether you flexibly pick the right structure (queue, hash, sorted table, etc.);
- Algorithms and complexity control: the problems aren't large, but all demand efficient implementation within the time limit;
- Logic and boundary thinking: especially details like data-flow updates, synchronized deletions, and range statistics.
2. Question 1: Log Buffer Analyzer (Circular Log Buffer)
Problem
Implement a circular log buffer that stores logs with timestamps and tags. Every time a new log arrives:
- If the buffer is full, delete the oldest one first;
- Then immediately "send" all logs with the same tag within the given time window;
- Finally, count how many were sent throughout the process.
Approach
On the surface an implementation problem; in substance it tests fluency with combining data structures. My approach:
- Use a queue to maintain log order so the oldest can be deleted fast;
- Build a sorted list of timestamps per tag;
- On insert, use binary search to count same-tag logs within the time range and add to the result;
- When full, synchronously delete the head log and its timestamp record.
from collections import deque
import bisect
class LogBufferAnalyzer:
def __init__(self, capacity: int, window: int):
self.capacity = capacity
self.window = window
self.buf = deque() # (timestamp, tag), maintains insertion order
self.tag_times = {} # tag -> sorted timestamp list
self.sent = 0
def _remove_oldest(self):
ts, tag = self.buf.popleft()
arr = self.tag_times[tag]
idx = bisect.bisect_left(arr, ts) # sync-delete this timestamp under the tag
if idx < len(arr) and arr[idx] == ts:
arr.pop(idx)
def add(self, ts: int, tag: str):
if len(self.buf) >= self.capacity:
self._remove_oldest()
self.buf.append((ts, tag))
arr = self.tag_times.setdefault(tag, [])
bisect.insort(arr, ts) # keep sorted, O(log n) locate + insert
# send same-tag logs in [ts - window, ts]
lo = bisect.bisect_left(arr, ts - self.window)
hi = bisect.bisect_right(arr, ts)
self.sent += (hi - lo)
def total_sent(self) -> int:
return self.sent
It's much like the "streaming log + time window" system-design problems, where the focus is update synchronization and boundary control. With a steady mindset, the whole thing stays at the O(log n) level and flows smoothly.
3. Question 2: Password Lock Decryption
Problem
Given an integer array and an upper bound upper. You may spend 1 unit of cost to change any element to a number ≤ upper. Find a candidate that is coprime with all elements after modification. Define:
Lock Code = candidate - total_modification_cost
Goal: maximize the Lock Code.
Approach
This one is fun—it looks like a brainteaser but is essentially number theory + enumeration optimization. Key observations:
- candidate is coprime with an element iff their
gcd == 1; - For a given candidate, elements already coprime with it need no change (cost 0); non-coprime ones cost 1 to change into something coprime with candidate (as long as candidate > 1, you can always change to 1, which is coprime with everything—so each non-coprime element costs exactly 1);
- Therefore
cost(candidate) = number of elements not coprime with candidate, andLock Code = candidate - cost.
from math import gcd
def max_lock_code(nums: list[int], upper: int) -> int:
best = float("-inf")
# larger candidate raises the Lock Code base, but cost may rise too; enumerate to upper
for candidate in range(1, upper + 1):
cost = sum(1 for x in nums if gcd(candidate, x) != 1)
best = max(best, candidate - cost)
return best
Optimization directions (interviewer follow-ups):
- Naive enumeration is O(upper · n · log). If upper is large, bucket by prime factors: precompute each element's prime factors, then the non-coprime count for a candidate equals the count of elements sharing any prime factor with it—accelerate via inclusion-exclusion or prime-factor counting.
- candidate being a prime is often better (coprime with most elements, low cost), so enumerate primes first to shrink the search space.
4. Summary
The two GS OA questions are very typical in style: Q1 system implementation + data-structure synergy (queue + sorted table + binary search), Q2 number theory + optimization (coprimality + cost modeling). When preparing, don't just grind algorithm templates—practice picking the right data structure and translating business/math rules into an optimizable model, and always be ready for complexity-optimization follow-ups.
FAQ
Q1: What platform and how many questions in the Goldman Sachs OA?
HackerRank, ~90 minutes, two questions, Python / C++ / Java. Difficulty is upper-middle, hardcore logic rather than math, testing data structures, complexity control, and boundary thinking.
Q2: What is the key to the Log Buffer question?
Combining data structures: a queue for order to delete the oldest in O(1), a sorted timestamp list per tag, binary search to count same-tag logs in the time window, and synchronous cleanup of the tag table on deletion. Overall O(log n).
Q3: How do I model the password lock question?
Turn "coprime" into gcd==1, notice each non-coprime element's modification cost is exactly 1, so cost = count of non-coprime elements, Lock Code = candidate - cost, enumerate candidate for the max. For large upper, bucket by prime factors + inclusion-exclusion.
Q4: How should I prepare for the GS OA?
Practice data-structure-combination problems (queue/heap/sorted table/binary search) and number-theory modeling, focusing on translating rules into optimizable models, and prepare complexity-optimization follow-ups. For timed mock practice on these two questions, send the job JD so we can predict the question types and build a plan.
Preparing for the Goldman Sachs OA?
The GS OA leans toward hardcore logic + engineering implementation, testing data-structure synergy and number-theory modeling. oavoservice offers full GS mock support: timed simulations of log-buffer / number-theory problems, complexity-optimization follow-up drills, and HackerRank pacing practice, with question-type prediction tailored to your role. Coaches include senior engineers from top tech companies who know the GS scoring style.
Add WeChat Coding0201 now to get GS questions and mock practice.
Contact
- WeChat: Coding0201
- Email: [email protected]
- Telegram: @OAVOProxy