Implement Hit Counter
Reported by candidates from Apple's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The queue is the whole answer here. Apple reported this Implement Hit Counter OA in September 2026, and it's a design question dressed up as a string-array function. You get chronological hit and getHits operations, and a query counts hits from timestamp - 299 through timestamp, inclusive. That's a 300-second sliding window. It looks easy, and it is, if you pick the right structure fast. If you blank mid-assessment, StealthCoder runs invisibly as a safety net and reads the problem for you. Know the trick first, though, and you won't need it.
The problem
Process chronological hit and getHits operations. A query returns the number of hits in the inclusive interval from timestamp - 299 through timestamp. Return "null" for a hit and the decimal count for a query. Function runHitCounter(operations: String[], timestamps: int[]) → String[] Examples Example 1 operations = ["hit","hit","hit","getHits","hit","getHits"] timestamps = [1,2,3,4,300,301] return = ["null","null","null","3","null","3"] At time 301, the hit at time 1 has expired but the other three remain. Constraints Operation and timestamp arrays have equal non-zero length. Timestamps are positive and non-decreasing. There are at most 100000 operations.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Timestamps are non-decreasing, so hits arrive already sorted. That means a queue (or deque) works perfectly. On hit, push the timestamp. On getHits, pop from the front while front <= timestamp - 300, then return the queue size. The window is inclusive of timestamp - 299, so anything at timestamp - 300 or older is expired. That off-by-one is the classic pitfall. Check it against the example: at 301, hit at time 1 is expired since 1 <= 1, leaving 3. Another option is a fixed array of 300 buckets indexed by timestamp % 300, which keeps memory constant if hits are huge in number. With up to 100000 operations, the queue is amortized O(1) per operation. Watch the output format too. Hits return the string "null" and queries return the count as a string. If you freeze on the format or the boundary during the live OA, StealthCoder is the hedge that surfaces a working solution.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Implement Hit Counter cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as design hit counter. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Apple's OA.
Apple reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Implement Hit Counter FAQ
What's the trick in Implement Hit Counter?+
Use a queue of timestamps. Hits come in sorted order, so the oldest is always at the front. On a query, drop everything at or below timestamp - 300, then return the queue length. Each timestamp is pushed and popped once, so it's amortized O(1).
How do I avoid the off-by-one on the window?+
The window is timestamp - 299 through timestamp inclusive, which is 300 seconds. Expire a hit when it's <= timestamp - 300. Test with the example: at 301, the hit at time 1 must be gone, and at 300 it must still count.
Should I use a queue or a bucket array?+
Either passes. The queue is simpler and faster to write under pressure. The 300-slot bucket array, using timestamp % 300 with stored times and counts, uses fixed memory. With at most 100000 operations, the queue is fine and less error-prone.
How hard is this Apple OA question really?+
It's easy to medium. There's no tricky algorithm, just a sliding window on sorted input. Most failures come from the boundary condition or from returning the wrong output format, like an integer instead of the string "null" or a decimal string.
How do I prepare for this in 48 hours?+
Write the queue solution from scratch twice, then run the sample by hand. Add a test where hits share the same timestamp and one where a query lands exactly at the 300 boundary. Also practice building the String[] result so hits give "null" and queries give the count.