一道面试题,在网上搜了一下答案,都是抄来抄去的,还一大堆代码,看都懒得看了
此处应该加锁,但是加锁会影响登录效率.看这里的参数,是一个用户id当做key,所以我们可不可以拿用户id作为一个锁呢?这样就只会锁住该用户,而不会锁住别人.
懒得实验了,这次的博客重点是"如题",不是效率.
2016年12月09日 14:07:07
/**
* 请用Redis和任意语言实现一段恶意登录保护的代码,限制1小时内每用户Id最多只能登录5次。
* 具体登录函数或功能用空函数即可,不用详细写出
*/
@Test
public void loginTest(){
Object countObj = redisTemplate.execute(new RedisCallback() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
return connection.incr("用户id".getBytes());
}
});
int count = Integer.parseInt(countObj.toString());
//expire:设置key的时间,第三个参数是时间的单位,这里设置为"秒"
if(count == 1)
redisTemplate.expire("用户id",30, TimeUnit.SECONDS);
if(count <= 5)
System.out.println("第"+count+"次登录"+"================登陆成功");
else
System.out.println("第"+count+"次登录"+"================超过五次");
}
感谢“哪时我还小”的提醒,上面的代码确实是错误的,今天又重新写了一段代码。更新于2018年5月29日
@Test
public void loginTest2(){
String key = "用户id";
for(int i=0;i<5;i++){
long size = redisTemplate.opsForList().size(key);
if(size<=5){
redisTemplate.opsForList().rightPush(key,System.currentTimeMillis()+"");
}else{
List<String> t = redisTemplate.opsForList().range(key,0,size);
Long now = System.currentTimeMillis();
if(now-Long.valueOf(t.get(0))>30000){//三十秒内
redisTemplate.opsForList().leftPop(key);
redisTemplate.opsForList().rightPush(key,System.currentTimeMillis()+"");
//登录成功
}else{
//登录失败
System.out.print("一小时内不能登录超过五次");
}
}
}
}