最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java面試題沖刺第二十六天--實(shí)戰(zhàn)編程

 更新時(shí)間:2021年08月27日 10:33:41   作者:_陳哈哈  
這篇文章主要為大家分享了最有價(jià)值的三道java實(shí)戰(zhàn)面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下

面試題1:你們是怎樣保存用戶密碼等敏感數(shù)據(jù)的?

本題回答參考朱曄的《Java業(yè)務(wù)開發(fā)常見錯(cuò)誤100例》

在這里插入圖片描述

我們知道,用戶名、密碼、身份證等都屬于用戶敏感信息,其中最敏感的數(shù)據(jù)恐怕就是用戶的密碼了。黑客一旦竊取了用戶密碼,就可以登錄進(jìn)用戶的賬號(hào),消耗其資產(chǎn)、發(fā)布不良信息等;更可怕的是,有些用戶至始至終都是使用一套密碼,密碼一旦泄露,就可以被黑客通過撞庫來登錄全網(wǎng)各大平臺(tái),嘿嘿嘿。

為了防止密碼泄露,最重要的原則是不要在數(shù)據(jù)庫保存用戶原始密碼。

大家經(jīng)常說,不要明文保存用戶密碼,應(yīng)該把密碼通過 MD5 加密后保存。這的確是一個(gè)正確的方向,但這個(gè)說法并不準(zhǔn)確。

首先,MD5 其實(shí)不是真正的加密算法。所謂加密算法,是可以使用密鑰把明文加密為密文,隨后還可以使用密鑰解密出明文,是雙向的。而 MD5 是散列、哈希算法或者摘要算法。不管多長(zhǎng)的數(shù)據(jù),使用 MD5 運(yùn)算后得到的都是固定長(zhǎng)度的摘要信息或指紋信息,無法再解密為原始數(shù)據(jù)。所以,MD5 是單向的。最重要的是,僅僅使用 MD5 對(duì)密碼進(jìn)行摘要,并不安全。

比如,使用如下代碼在保持用戶信息時(shí),對(duì)密碼進(jìn)行了 MD5 計(jì)算:

UserData userData = new UserData();
userData.setId(1L);
userData.setName(name);
//密碼字段使用MD5哈希后保存
userData.setPassword(DigestUtils.md5Hex(password));
return userRepository.save(userData);

通過輸出,可以看到密碼是 32 位的 MD5:

"password": "325a2cc052914ceeb8c19016c091d2ac"

然后,再去破解網(wǎng)站試一下這個(gè) MD5,就可以得到原始密碼是 salt,也就知道了鹽值是 salt:

其實(shí),知道鹽是什么沒什么關(guān)系,關(guān)鍵的是我們是在代碼里寫死了鹽,并且鹽很短、所有用戶都是這個(gè)鹽。這么做就會(huì)有三個(gè)問題:

  • 因?yàn)辂}太短、太簡(jiǎn)單了,如果用戶原始密碼也很簡(jiǎn)單,那么整個(gè)拼起來的密碼也很短,這樣一般的 MD5 破解網(wǎng)站都可以直接解密這個(gè) MD5,除去鹽就是原始密碼了。
  • 相同的鹽,意味著使用相同密碼的用戶 MD5 值是一樣的,知道了一個(gè)用戶的密碼就可能知道了多個(gè)。
  • 黑客也可以使用這個(gè)鹽來構(gòu)建一張彩虹表,也就是字典表,雖然會(huì)花不少代價(jià),但是一旦構(gòu)建完成,所有人的密碼都可以被破解。

所以,最好是每一個(gè)密碼都有獨(dú)立的鹽,并且鹽要長(zhǎng)一點(diǎn),比如超過 20 位。

第二,雖然說每個(gè)人的鹽最好不同,但也不建議將一部分用戶數(shù)據(jù)作為鹽。比如,使用用戶名作為鹽:

userData.setPassword(DigestUtils.md5Hex(name + password));

如果世界上所有的系統(tǒng)都是按照這個(gè)方案來保存密碼,那么 root、admin 這樣的用戶使用再?gòu)?fù)雜的密碼也總有一天會(huì)被破解,因?yàn)楹诳蛡兺耆梢葬槍?duì)這些常用用戶名來做彩虹表。所以,鹽最好是隨機(jī)的值,并且是全球唯一的,意味著全球不可能有現(xiàn)成的彩虹表給你用。

正確的做法是,使用全球唯一的、和用戶無關(guān)的、足夠長(zhǎng)的隨機(jī)值作為鹽。比如,可以使用 UUID 作為鹽,把鹽一起保存到數(shù)據(jù)庫中:

userData.setSalt(UUID.randomUUID().toString());
userData.setPassword(DigestUtils.md5Hex(userData.getSalt() + password));

并且每次用戶修改密碼的時(shí)候都重新計(jì)算鹽,重新保存新的密碼。

需要注意的是,這么做雖然黑客已經(jīng)很難通過彩虹表來破解密碼了,但是仍然有可能暴力破解密碼,也就是對(duì)于同一個(gè)用戶名使用常見的密碼逐一嘗試登錄。因此,除了做好密碼哈希保存的工作外,我們還要建設(shè)一套完善的安全防御機(jī)制,在感知到暴力破解危害的時(shí)候,開啟短信驗(yàn)證、圖形驗(yàn)證碼、賬號(hào)暫時(shí)鎖定等防御機(jī)制來抵御暴力破解。

那么姓名和身份證又是怎么保存的?

我們把姓名和身份證,叫做二要素。

現(xiàn)在互聯(lián)網(wǎng)非常發(fā)達(dá),很多服務(wù)都可以在網(wǎng)上辦理,很多網(wǎng)站僅僅依靠二要素來確認(rèn)你是誰。所以,二要素是比較敏感的數(shù)據(jù),如果在數(shù)據(jù)庫中明文保存,那么數(shù)據(jù)庫被攻破后,黑客就可能拿到大量的二要素信息。如果這些二要素被用來申請(qǐng)貸款等,后果不堪設(shè)想。

之前我們提到的單向散列算法(MD5),顯然不適合用來加密保存二要素,因?yàn)閿?shù)據(jù)無法解密。這個(gè)時(shí)候,我們需要選擇真正的加密算法??晒┻x擇的算法,包括對(duì)稱加密和非對(duì)稱加密算法兩類。

  • 對(duì)稱加密算法:是使用相同的密鑰進(jìn)行加密和解密。使用對(duì)稱加密算法來加密雙方的通信的話,雙方需要先約定一個(gè)密鑰,加密方才能加密,接收方才能解密。如果密鑰在發(fā)送的時(shí)候被竊取,那么加密就是白忙一場(chǎng)。因此,這種加密方式的特點(diǎn)是,加密速度比較快,但是密鑰傳輸分發(fā)有泄露風(fēng)險(xiǎn)。

在這里插入圖片描述

  • 非對(duì)稱加密算法:或者叫公鑰密碼算法。公鑰密碼是由一對(duì)密鑰對(duì)構(gòu)成的,使用公鑰或者說加密密鑰來加密,使用私鑰或者說解密密鑰來解密,公鑰可以任意公開,私鑰不能公開。使用非對(duì)稱加密的話,通信雙方可以僅分享公鑰用于加密,加密后的數(shù)據(jù)沒有私鑰無法解密。因此,這種加密方式的特點(diǎn)是,加密速度比較慢,但是解決了密鑰的配送分發(fā)安全問題。

在這里插入圖片描述

但是,對(duì)于保存敏感信息的場(chǎng)景來說,加密和解密都是我們的服務(wù)端程序,不太需要考慮密鑰的分發(fā)安全性,也就是說使用非對(duì)稱加密算法沒有太大的意義。我們一般會(huì)使用對(duì)稱加密算法來加密數(shù)據(jù)。常見的對(duì)稱加密算法有:DES、3DES 和 AES。

在這里插入圖片描述

面試題2:怎么控制用戶請(qǐng)求的冪等性的?

冪等性:對(duì)于同一筆業(yè)務(wù)操作,不管調(diào)用多少次,得到的結(jié)果都是一樣的。

當(dāng)然,有些操作是天然冪等的,如:

  • 查詢操作:查詢一次和查詢多次,在數(shù)據(jù)不變的情況下,查詢結(jié)果是一樣的。select是天然的冪等操作;
  • 刪除操作:刪除操作也是冪等的,刪除一次和多次刪除都是把數(shù)據(jù)刪除。

后臺(tái)控制冪等性的幾種途徑:

1.設(shè)置唯一索引:防止新增臟數(shù)據(jù)

比如支付寶的資金賬戶,支付寶也有用戶賬戶,每個(gè)用戶只能有一個(gè)資金賬戶,怎么防止給用戶創(chuàng)建資金賬戶多個(gè),那么給資金賬戶表中的用戶ID加唯一索引,所以一個(gè)用戶新增成功一個(gè)資金賬戶記錄。要點(diǎn):唯一索引或唯一組合索引來防止新增數(shù)據(jù)存在臟數(shù)據(jù)(當(dāng)表存在唯一索引,并發(fā)時(shí)新增報(bào)錯(cuò)時(shí),再查詢一次就可以了,數(shù)據(jù)應(yīng)該已經(jīng)存在了,返回結(jié)果即可);

2.token機(jī)制:防止頁面重復(fù)提交

原理上通過session token來實(shí)現(xiàn)的(也可以通過redis來實(shí)現(xiàn))。當(dāng)客戶端請(qǐng)求頁面時(shí),服務(wù)器會(huì)生成一個(gè)隨機(jī)數(shù)Token,并且將Token放置到session當(dāng)中,然后將Token發(fā)給客戶端(一般通過構(gòu)造hidden表單)。下次客戶端提交請(qǐng)求時(shí),Token會(huì)隨著表單一起提交到服務(wù)器端。

服務(wù)器端第一次驗(yàn)證相同過后,會(huì)將session中的Token值更新下,若用戶重復(fù)提交,第二次的驗(yàn)證判斷將失敗,因?yàn)橛脩籼峤坏谋韱沃械腡oken沒變,但服務(wù)器端session中Token已經(jīng)改變了。

3.悲觀鎖

獲取數(shù)據(jù)的時(shí)候加鎖獲取。

select * from table_xxx where id='xxx' for update;

注意:id字段一定是主鍵或者唯一索引,不然是鎖表,會(huì)死人的;悲觀鎖使用時(shí)一般伴隨事務(wù)一起使用,數(shù)據(jù)鎖定時(shí)間可能會(huì)很長(zhǎng),根據(jù)實(shí)際情況選用;

4.樂觀鎖

樂觀鎖只是在更新數(shù)據(jù)那一刻鎖表,其他時(shí)間不鎖表,所以相對(duì)于悲觀鎖,效率更高。樂觀鎖的實(shí)現(xiàn)方式多種多樣,可以通過version或者其他狀態(tài)條件判斷:

  • 通過版本號(hào)實(shí)現(xiàn)

update table_xxx set name=#name#,version=version+1 where version=#version#;

  • 通過條件限制

update table_xxx set avai_amount=avai_amount where avai_amount >= 0

5.分布式鎖

如果是分布式系統(tǒng),構(gòu)建全局唯一索引比較困難,例如唯一性的字段沒法確定,這時(shí)候可以引入分布式鎖,通過第三方的系統(tǒng)(redis或zookeeper),在業(yè)務(wù)系統(tǒng)插入數(shù)據(jù)或者更新數(shù)據(jù),獲取分布式鎖,然后做操作,之后釋放鎖,這樣其實(shí)是把多線程并發(fā)的鎖的思路,引入多多個(gè)系統(tǒng),也就是分布式系統(tǒng)中得解決思路。

要點(diǎn):某個(gè)長(zhǎng)流程處理過程要求不能并發(fā)執(zhí)行,可以在流程執(zhí)行之前根據(jù)某個(gè)標(biāo)志(用戶ID+后綴等)獲取分布式鎖,其他流程執(zhí)行時(shí)獲取鎖就會(huì)失敗,也就是同一時(shí)間該流程只能有一個(gè)能執(zhí)行成功,執(zhí)行完成后,釋放分布式鎖(分布式鎖要第三方系統(tǒng)提供);

面試題3:你們是如何預(yù)防SQL注入問題的?

SQL注入攻擊的總體思路

  • 尋找到SQL注入的位置
  • 判斷服務(wù)器類型和后臺(tái)數(shù)據(jù)庫類型
  • 針對(duì)不通的服務(wù)器和數(shù)據(jù)庫特點(diǎn)進(jìn)行SQL注入攻擊

預(yù)防方式:

1、PreparedStatement(簡(jiǎn)單有效)

采用預(yù)編譯語句集,它內(nèi)置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。

sql注入只對(duì)sql語句的準(zhǔn)備(編譯)過程有破壞作用,而PreparedStatement在執(zhí)行階段只是把輸入串作為數(shù)據(jù)處理,不再對(duì)sql語句進(jìn)行解析,因此也就避免了sql注入問題。

2、使用正則表達(dá)式過濾傳入的參數(shù)

要引入的包:

import java.util.regex.*;

正則表達(dá)式:

private String CHECKSQL =^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”;

判斷是否匹配:

Pattern.matches(CHECKSQL,targerStr);

下面是常用來過濾參數(shù)是否存在SQL注入的正則表達(dá)式:

  • 檢測(cè)SQL meta-characters的正則表達(dá)式 : /(\%27)|(\')|(\-\-)|(\%23)|(#)/ix
  • 修正檢測(cè)SQL meta-characters的正則表達(dá)式 : /((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|(\%3B)|(:))/i
  • 典型的SQL 注入攻擊的正則表達(dá)式 : /\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
  • 檢測(cè)SQL注入,UNION查詢關(guān)鍵字的正則表達(dá)式 : /((\%27)|(\'))union/ix(\%27)|(\')

3.使用正則表達(dá)式過濾傳入的URL

比較通用的一個(gè)方法,jsp中調(diào)用該函數(shù)檢查是否包函非法字符,防止SQL從URL注入:

(||之間的參數(shù)可以根據(jù)自己程序的需要添加)

public static boolean sql_inj(String str){
    String inj_str = "'|and|exec|insert|select|delete|update|
    count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
    String inj_stra[] = split(inj_str,"|");
    for (int i=0 ; i < inj_stra.length ; i++ ){
        if (str.indexOf(inj_stra[i])>=0){
        return true;
        }
    }
    return false;
}

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Java中類的定義和初始化示例詳解

    Java中類的定義和初始化示例詳解

    這篇文章主要給大家介紹了關(guān)于Java中類的定義和初始化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 在Java程序中使用數(shù)據(jù)庫的新方法

    在Java程序中使用數(shù)據(jù)庫的新方法

    這篇文章主要介紹了在Java程序中使用數(shù)據(jù)庫的新方法,講述了Java8以來數(shù)據(jù)庫API的一些新特性,需要的朋友可以參考下
    2015-07-07
  • restTemplate超時(shí)處理的策略方案

    restTemplate超時(shí)處理的策略方案

    這篇文章主要為大家介紹了restTemplate超時(shí)處理的策略方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Java設(shè)計(jì)模式之單例模式Singleton Pattern詳解

    Java設(shè)計(jì)模式之單例模式Singleton Pattern詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之單例模式Singleton Pattern詳解,一些常用的工具類、線程池、緩存,數(shù)據(jù)庫,數(shù)據(jù)庫連接池、賬戶登錄系統(tǒng)、配置文件等程序中可能只允許我們創(chuàng)建一個(gè)對(duì)象,這就需要單例模式,需要的朋友可以參考下
    2023-12-12
  • Java正則驗(yàn)證字串符RegexValidator類使用

    Java正則驗(yàn)證字串符RegexValidator類使用

    正則驗(yàn)證字串符是一種強(qiáng)大的工具,可以幫助程序員在處理字符串時(shí)輕松進(jìn)行復(fù)雜匹配,本文將介紹正則表達(dá)式的概念、語法和在編程中的應(yīng)用,并通過實(shí)例演示如何使用正則表達(dá)式進(jìn)行字符串匹配、替換和提取等操作
    2023-11-11
  • SpringBoot+Ant Design Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出功能方式

    SpringBoot+Ant Design Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出功能方式

    這篇文章主要介紹了SpringBoot+Ant Design Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出功能方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java并發(fā)編程-volatile可見性詳解

    Java并發(fā)編程-volatile可見性詳解

    這篇文章主要介紹了Java并發(fā)編程-volatile可見性詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • JavaFX實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘效果

    JavaFX實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘效果

    這篇文章主要為大家詳細(xì)介紹了JavaFX實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Spring Cloud Gateway打造可擴(kuò)展的微服務(wù)網(wǎng)關(guān)

    Spring Cloud Gateway打造可擴(kuò)展的微服務(wù)網(wǎng)關(guān)

    微服務(wù)網(wǎng)關(guān)是一個(gè)位于客戶端和后端微服務(wù)之間的服務(wù)器,用于處理所有與客戶端的通信,Spring Cloud Gateway都是一個(gè)值得考慮的選擇,它將幫助您更好地管理和保護(hù)您的微服務(wù),感興趣的朋友一起看看吧
    2023-11-11
  • SpringBoot如何使用TestEntityManager進(jìn)行JPA集成測(cè)試

    SpringBoot如何使用TestEntityManager進(jìn)行JPA集成測(cè)試

    TestEntityManager是Spring Framework提供的一個(gè)測(cè)試框架,它可以幫助我們進(jìn)行 JPA 集成測(cè)試,在本文中,我們將介紹如何使用 TestEntityManager 進(jìn)行 JPA 集成測(cè)試,感興趣的跟著小編一起來學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

景德镇市| 布拖县| 成都市| 河间市| 施甸县| 菏泽市| 罗城| 扶沟县| 达尔| 襄城县| 太和县| 克拉玛依市| 福清市| 东乡县| 九龙城区| 梓潼县| 高邑县| 丰顺县| 卢湾区| 忻城县| 渝北区| 武安市| 突泉县| 瑞安市| 孟州市| 天柱县| 旬阳县| 西藏| 贡觉县| 双柏县| 班戈县| 玉环县| 都江堰市| 郧西县| 哈巴河县| 科技| 临潭县| 桂东县| 顺义区| 讷河市| 义马市|