05 August 2008
设计一个验证系统,每一次验证中,用户会收到一个新的验证码,这个验证码在 currentTime 时刻之后 timeToLive 秒过期。如果验证码被更新了,那么它会在 currentTime (可能与之前的 currentTime 不同)时刻延长 timeToLive 秒。
实现 AuthenticationManager 类:
AuthenticationManager(int timeToLive) 构造 AuthenticationManager 并设置 timeToLive 参数
generate(string tokenId, int currentTime) 给定 tokenId ,在当前时间 currentTime 生成一个新的验证码
renew(string tokenId, int currentTime) 将给定 tokenId 且 未过期 的验证码在 currentTime 时刻更新。如果给定 tokenId 对应的验证码不存在或已过期,请你忽略该操作,不会有任何更新操作发生。
countUnexpiredTokens(int currentTime) 请返回在给定 currentTime 时刻,未过期 的验证码数目。
如果一个验证码在时刻 t 过期,且另一个操作恰好在时刻 t 发生(renew 或者 countUnexpiredTokens 操作),过期事件 优先于 其他操作。
思路其实是在模拟缓存中的 token 操作。 首先创建一个哈希表,哈希表中的:
key : tokenId value : 生成时间,也就是调用 generate 或者 renew 时带进来的 currentTime。 更具体的就看下面注释吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class AuthenticationManager {
private int timeToLive;
private Map<String, Integer> tokens;
public AuthenticationManager(int timeToLive) {
tokens = new HashMap<>();
this.timeToLive = timeToLive;
}
/**
* 根据题意,不需要考虑是否之前已经存在了,只需要把 tokenId-currentTime 更新/添加到哈希表中就好
*/
public void generate(String tokenId, int currentTime) {
tokens.put(tokenId, currentTime);
}
public void renew(String tokenId, int currentTime) {
// 首先看看缓存(哈希表)中里面有没有对应的 tokenId,如果没有就什么都不用做了
if (tokens.containsKey(tokenId)) {
// 如果有的话,先记录下来它的上次生成时间
int time = tokens.get(tokenId);
// currentTime - time 就是上次生成时间和当前时间的差值
// 如果差值严格小于生存时间 timeToLive ,那么就可以更新了,否则什么都不做
if (currentTime - time < timeToLive) tokens.put(tokenId, currentTime);
}
}
public int countUnexpiredTokens(int currentTime) {
int result = 0;
// 对缓存(哈希表)中的每一个对象进行遍历,检查他们的生成时间和当前时间的差值是否满足要求
for (Map.Entry<String, Integer> entry : tokens.entrySet()) {
if (currentTime - entry.getValue() < timeToLive) ++result;
}
return result;
}
}
/**
* Your AuthenticationManager object will be instantiated and called as such:
* AuthenticationManager obj = new AuthenticationManager(timeToLive);
* obj.generate(tokenId,currentTime);
* obj.renew(tokenId,currentTime);
* int param_3 = obj.countUnexpiredTokens(currentTime);
*/