日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何设计登录接口,十分钟内连续登录5次失败,需要等待30分钟才能登录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正常業務里的實現不能這樣搞,合適的方法是走緩存,比如使用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分钟才能登录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。