
(This question has been seen in the interviews of the following companies: Dropbox)
Design a hit counter which counts the number of hits received in the past 5 minutes.
Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made to the system in chronological order (ie, the timestamp is monotonically increasing). You may assume that the earliest timestamp starts at 1.
Example:
HitCounter counter = new HitCounter();
// hit at timestamp 1.
counter.hit(1);
// hit at timestamp 2.
counter.hit(2);
// hit at timestamp 3.
counter.hit(3);
// get hits at timestamp 4, should return 3.
counter.getHits(4);
// hit at timestamp 300.
counter.hit(300);
// get hits at timestamp 300, should return 4.
counter.getHits(300);
// get hits at timestamp 301, should return 3.
counter.getHits(301);
Follow-up:
Due to latency, several hits arrive roughly at the same time and the order of timestamps is not guaranteed chronological.
Follow up 2:
What if the number of hits per second could be very large? Does your design scale?
Step 1, have a table to store all the visits sorted by time stamp.
or
have a queue to store the visits per second in the past 5 minute.
Follow-up:
Have two arrays hits[range] and lastupdated[range].
Range = 5 mins = 300 seconds in this case. Any hit within 'range' time from now is valid and should counted.
Index of a hit in the two arrays will be timestamp % 300.
Store the last updated time of a hit. Later if a query for the hit count arrives with a query timestamp, sum up all the valid hits from array 'hits'. Threshold for valid hits: query time - hit last updated time < 300.
public class HitCounter {
int[] times, hits;
int timeRange;
/** Initialize your data structure here. */
public HitCounter(int range) {
times = new int[range];
hits = new int[range];
timeRange = range;
}
/** Record a hit.
@param timestamp - The current timestamp (in seconds granularity). */
public void hit(int timestamp) {
int idx = timestamp % timeRange;
if (times[idx] != timestamp) {
times[idx] = timestamp;
hits[idx] = 1;
} else {
hits[idx];
}
}
/** Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity). */
public int getHits(int timestamp) {
int res = 0;
for (int i = 0; i < timeRange; i) {
if (timestamp - times[i] < timeRange) {
res = hits[i];
}
}
return res;
}
}
Get one-to-one training from Google Facebook engineers
Top-notch Professionals
Learn from Facebook and Google senior engineers interviewed 100+ candidates.
Most recent interview questions and system design topics gathered from aonecode alumnus.
One-to-one online classes. Get feedbacks from real interviewers.
Customized Private Class
Already a coding expert? - Advance straight to hard interview topics of your interest.
New to the ground? - Develop basic coding skills with your own designated mentor.
Days before interview? - Focus on most important problems in target company question bank.