正常业务里的实现不能这样搞,合适的方法是走缓存,比如使用redis,我当时就只有原生Java API能用,请大家把这个当成算法题来看待

常言道:字数越短问题越大。
  今天阿里的面试官小哥哥让我实现一个登录接口,同一个用户10分钟内连续登陆5次失败,则需要等到30分钟才能登陆。
  当然大佬估计一看到这种题目会很难过,一丁点算法都没有,妙解没意思。我上来就被唬住了。登录接口?10分钟内连续5次??等待30分钟才能登陆???登陆验证????
  问号一下子就冒出来了,当然最开始我想定义一个变量firstFailTime来记录第一次失败的时间,再仔细一想不对啊,firstFailTime是动态的额,要不断变化,单一个变量不好实现啊,第一次登录失败可以记录,但如果出现前十分钟失败了4次,第11分钟又失败了一次的话,firstFailTime应该往后取第二次失败登录的时间啊,我总不能手动定义100个变量吧。。。面试官看到估计脸都绿了。恨不得给我一个Mysql数据表,把每次登陆都给存下来,这样就可以很方便的查出某个时间区间登陆的情况。
  不慌,咱们虽然不是大佬,但一点一点分析还是可以的,沉住气!等等,刚刚说到数据库存所有的登录数据??其实思考到上面已经快接近了,我不能手动创建100个变量,但我可以用一种数据结构依次记录登录失败的时间啊,突然想到LRU算法对不对!!能从数据顺序看出来时间顺序的数据结构不就是链表吗!!!还有登录验证的问题,不如偷个懒,用一个boolean控制。解决,cool~
P.S:我没考虑开多个线程去测试,因为我个人感觉用户登录不会出现在高并发的环境里,几万个人同时登陆同一个账号想想就离谱…但为了保险起见我还是给map加了synchronize关键字

package exam;import java.util.LinkedList;/*** Created by Enzo Cotter on 2021/3/10.*/
public class Person {/*** 重置时间*/private static final int RESET_TIME = 30;/*** 密码连续输入5次失败的持续时间*/private static final int DURATION = 10;/*** 最大输入失败次数*/private static final int MAX_TIMES = 5;/*** 用户id*/private String id;/*** 登录失败次数*/private int failCount;/*** 第一次失败的时间*/private long firstFailTime;/*** 登录失败的时间*/private LinkedList<Long> times;private boolean lock;public String getId() {return id;}public void setId(String id) {this.id = id;}public int getFailCount() {return failCount;}public void setFailCount(int failCount) {this.failCount = failCount;}public long getFirstFailTime() {return firstFailTime;}public void setFirstFailTime(long firstFailTime) {this.firstFailTime = firstFailTime;}public LinkedList<Long> getTimes() {return times;}public void setTimes(LinkedList<Long> times) {this.times = times;}public Person() {}public Person(String id, int failCount, long firstFailTime, LinkedList<Long> times, boolean lock) {this.id = id;this.failCount = failCount;this.firstFailTime = firstFailTime;this.times = times;this.lock = false;}/*** 密码输错了进入此方法*/public void isValid(){long thisTime = System.currentTimeMillis() / 1000;System.out.println("第一次登录失败时间" + thisTime);// 超过30分钟,重置if(thisTime > firstFailTime + RESET_TIME){this.failCount = 1;firstFailTime = thisTime;times = new LinkedList<>();times.addLast(thisTime);this.lock = false;return;}else{ // 没有超过30分钟if (lock){System.out.println("账户锁定,请" + RESET_TIME + "分钟后再来");return;}// 之前记录的第一次登录失败时间在10分钟之前了,要换while(!times.isEmpty() && thisTime > times.getFirst() + DURATION){times.removeFirst();this.failCount --;this.firstFailTime = times.isEmpty() ? thisTime : times.getFirst();}if(this.failCount >= 5 && thisTime < firstFailTime + DURATION){System.out.println("10分钟内密码错误大于等于5次,登录失败");times.addLast(thisTime);this.lock = true;}else if(failCount < MAX_TIMES){this.failCount ++;System.out.println("密码错误" + this.failCount + "次");times.addLast(thisTime);}}}
}
package exam;import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;/*** Created by Enzo Cotter on 2021/3/10.*/
public class FlowLimit {private static Map<String, Person> map = new HashMap<>();/*** 登录* @param id* @param flag  是否成功*/public static void login(String id, boolean flag){if (flag){// 登陆成功return;}else{Person p = null;// 登录失败synchronized (map) {p = map.get(id);if (p == null){p = new Person(id, 0, System.currentTimeMillis() / 1000,new LinkedList<>(), false);map.put(id, p);return;}p.isValid();}}}public static void main(String[] args) {for(int i = 0; i < 20; i ++){login("aaa", false);}}
}

如何设计登录接口,十分钟内连续登录5次失败,需要等待30分钟才能登录相关推荐

  1. 登录安全性 一天内连续输入密码错误3次,第二天才能登录(过了当天凌晨24点),实现原理

    登录安全性 一天内连续输入密码错误3次,第二天才能登录(过了当天凌晨24点)下面我们先在数据库中建立一个试验表,id,用户名username,密码pwd,次数num,时间time(date):这个功能 ...

  2. php新浪微博第三方登录接口,手机第三方新浪微博登录php api实现分析

    提供api,POST方式,根据传递过来的微博uid/appkey,判断该用户的ID是否在自己的数据库中. 如果有,直接登录返回用户登录api的json. 如果没有,就将该用户的ID+token请求微博 ...

  3. C#.NET 大型通用信息化系统集成快速开发平台 4.6 版本 - SSO单点登录接口

    当开发的系统多了.用户多了.合作伙伴多了.对接厂商多了.开发人员多了.部署的服务器也多了,各种安全问题就暴露出来了. 如何安全的把这些系统集成在一起?实现集群的单点登录.严格统一的用户安全体系管理? ...

  4. 开盘15分钟内扑捉当天黑马

    开盘15分钟内扑捉当天黑马               在9:30开市前, 通过集合竟价开盘时,我们都有几分钟的时间浏览大盘和个股, 这是一天中最宝贵的时间!是扑捉当日黑马的最佳时刻! 因为能看出大盘 ...

  5. flash写保护原理_为什么固态会掉盘?著名的30分钟大法修复是什么原理?

    如果现代的台式机或者笔记本忽然断电(Power Loss),你觉得哪个硬件部分容易损坏?出乎大多数人的意料的是,固态硬盘SSD最脆弱,容易出现掉盘的现象,也就是BIOS和操作系统不认盘的情况.今天我们 ...

  6. java 错误登陆次数_纯java代码实现登陆次数验证,登陆错误5次之后锁定30分钟

    本方法因为是根据思路纯手写,代码可以再简化,功能尝试没问题,最主要就是在登陆验证中的逻辑,checkLogin()方法是登录前的验证,而真正的登陆方式采用的是Shiro,若不是采用Shiro登陆,将该 ...

  7. Android 实现计时器功能,Android实现倒计时30分钟功能

    以30分钟为例写的一个倒计时: 直接上代码 public class MainActivity extends AppCompatActivity { private int minute = 30; ...

  8. js 将日期增加30分钟为支付过期时间

    addTime(add){ // 1.将日期转换为中国标准时间 let date = new Date(add); // 2. 获取当前分钟 let min = date.getMinutes(); ...

  9. bootstrap设计登录页面_前端小白如何在10分钟内打造一个爆款Web响应式登录界面?...

    对于前端小白(例如:专注后端代码N年的攻城狮),自己编写一个漂亮的Web登录页面似乎在设计上有些捉襟见肘,不懂UI设计,颜色搭配极度的混乱(主色,辅助色,配色,色彩渐变,动画效果等等,看起来一堆乱七八 ...

最新文章

  1. portal开发下拉框“日期框”查询要怎么配置
  2. springboot yml怎么建常量_Springboot中加载自定义的yml配置文件
  3. 《Non-invasive Fetal ECG Signal Quality Assessment for Multichannel Heart Rate Estimation》论文解读-废弃
  4. 执行execute时对象名 retime_record 无效_MyBatis 的执行流程怎么可以讲的这么透彻
  5. centos8 挂载ntfs_CentOS 8 挂载NTFS系统磁盘方案
  6. 微服务与单体架构:IT变革中企业及个体如何自处?
  7. 数值计算方法(高斯消元以及LU分解)
  8. db2连接工具_ETL工具(kettl)使用系列(一)
  9. 以后的blog将转移到微信公众号,请扫码关注谢谢!
  10. python之七行代码制作GIF动画
  11. 为什么你的数据库经常会被破防呢?原因原来是这——Sql注入问题(源码+文字深度解析)
  12. Flutter仿美团应用开发笔记-入门篇
  13. html5移动web开发黑马掌上商城_月入35k大佬总结:web前端必须学习的内容(附全套前端教程)...
  14. 依赖注入(DI)入门
  15. 求数组子序列和最大值
  16. qfile.remove 删除已经被加载的文件_Milvus数据管理:删除的实现原理
  17. mtkwin10驱动_Windows系统MTK手动安装驱动教程(Win10通用)
  18. 由入门C语言题目浅析gets()函数的用法
  19. 苹果手机数据能恢复吗
  20. Rich Dad Poor Dad

热门文章

  1. 下载服务器 linux系统,如何搭建Linux服务器
  2. 需要排序的最短子数组长度
  3. pytorch笔记:torch.nn.GRU torch.nn.LSTM
  4. 从无到有算法养成篇-单向循环链表的常规操作
  5. Python入门100题 | 第051题
  6. Agisoft PhotoScan Professional软件处理无人机航拍照片基本流程
  7. 非平衡数据集的机器学习常用处理方法
  8. 35+ Top Apache Tomcat Interview Questions And Answers【转】
  9. 供应链金融3.0化解新车流通金融难题
  10. 【采用】反欺诈之血缘关系分析和犯罪传导监测 - 知识图谱