Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Am I crazy or is the first answer terrible? I sat down and wrote out and answer for the problem and I initialized one integer and one timestamp. It should be O(1) time and O(1) memory easily, right? I'm seeing comments saying they'd use an array or a hash table -- why are you using any data structure? You don't need to remember how many times it was called 61 seconds ago; just keep a timestamp and the last time you reset the timestamp. If you need it to be clock-minutes instead of rolling (it doesn't; whose clock, anyway?), then just round the timestamp. The obvious follow-up question is "ok, what if it needs to be limited to 10,000 calls per minute?" You're going to keep 10,000+ elements in some collection for no reason? I wouldn't immediately reject a candidate for coming up with this answer but I would seriously question their thought process on this one.

In fact it's kind of ironic that his first example exposes how bad this advice is: by trying to meta-game, starting from a few example data structures, he shows he completely misses the solution that is both simpler and much more performant.



I don't think you can have a "sliding window" of time just based on that.

The next time you call the function, you need to count how many of the old calls are still "unexpired". This number (potentially) gets lower with each passing quantum of time.

How can you do that without holding a timestamp for each call? Please clarify if I misunderstood you.


I think you can have a more performant algorithm if you soften the constraint a little. (see my previous comment https://news.ycombinator.com/item?id=29776678 )

TLDR : You have a maximum of N credits, when time pass you earn credit at a rate of N credit by window_size, but if the time since previous request is less than window_size/N you lose 1 credit.

I don't think you can have more than 2*N requests in any sliding window without tripping the filter, but you can't consume more than the average of N requests / window_size without tripping the filter.

I think it's a better solution than the question asked by the author, because when you are rate limiting, you and the client may not have exactly the same time, and you might have edge cases like where the client batch 60 requests in a few ms every minute. If there is some time-jitter in the requests you may have 120 requests in 59.9 seconds. (Bonus question : What time-stamping of the request should be used ?)

Whereas with my solution it is more forgiving, it allow the client to use all its rate credit without risking to trip the filter if he respect the rate intent.


That's a better solution in general IMO, but the author's approach can guarantee that you'll never go over N calls in a sliding window rather than fixed windows. I don't believe that's possible with the timestamp + count solution. Gotta bring up both solutions and ask the interviewer what they want :)


What's the problem with a sliding window and the timestamp + count solution? lastTime is the timestamp of the last call. newTime is the timestamp of the incoming call. If newTime - lastTime > 60 seconds then you're good to proceed, set count to 1 change lastTime to newTime and go on. Otherwise, check whether count is less than n and proceed accordingly (incrementing count if so). This accomplishes the sliding window and rounding down to the last whole minute handles the fixed window - right?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: