Design Hit Counter

URL: https://leetcode.com/problems/design-hit-counter/description/

这是一道典型的从最基本的算法入手,到设计一个复杂的系统的综合题。

最容易想到的解法

前提:不考虑并发,不考虑数据量。单机作战。

利用一个Queue,每次 hit 的时候往 Queue 里加当前时间戳,每次 getHits 的时候从 Queue 的头部开始扫,将所有超过当前window size的元素出队,最后Queue的size即为答案。

然而,这里有一个问题。

如果 hit 被调用很多次,而 getHits 的调用次数很少,那么Queue的size必然会很大,这将是对space的一种浪费。Can we improve space usage?

从不定长到定长

我们需要一个滚动数组,即以 window size 为长度的一个int[] time。该数组用来记录时间戳,同时我们需要记录每一个时间戳的 hit number,所以再建一个 array int[] hit

当 hit 的时候,将 timestamp 对 window size 取余,存入 int[] time 中,并且更新对应的 hit number。当 getHits 的时候,扫一遍int[] time ,计算 window size 以内的即可。

这里,可以引入 Concurrency 问题。

如果有多个请求同时访问,怎么办?

利用 Lock。

这里,可以引入 Distributed System 问题。

如果数据量很大,lock 的 performance 会成为整个系统的 bottleneck,怎么办?

多个系统共同协作。

可以设置一个Master Node,好几个Worker Node。由Master Node来分配不同的请求。这里,Master Node分配的时候要尽可能地均匀分配,不然某些 Worker 工作量太大会影响整个系统的性能。均匀分配的方法有很多,比如对请求进行 hash,再根据 hash 值进行分配。

当要 getHits 的时候,每个 Worker Node 独立进行 count,然后返回给 Master Node,并由 Master Node 进行统计并返回。

Reference

http://blog.gainlo.co/index.php/2016/09/12/dropbox-interview-design-hit-counter/

Last updated