阿里面試題庫_第1頁
阿里面試題庫_第2頁
阿里面試題庫_第3頁
阿里面試題庫_第4頁
阿里面試題庫_第5頁
已閱讀5頁,還剩195頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

阿里面試題

?SpringBoot

?什么是SpringBoot?

SpringBoot是Spring開源組織下的子項(xiàng)目,是Spring組件一站式解決方案,主要是簡化了使

用Spring的難度,簡省了繁重的配置,提供了各種啟動(dòng)器,開發(fā)者能快速上手。

?為什么要用SpringBoot?

SpringBoot優(yōu)點(diǎn)非常多,如:獨(dú)立運(yùn)行簡化配置自動(dòng)配置無代碼生成和XML配置應(yīng)用監(jiān)控

上手容易

?Springboot啟動(dòng)方式

?SpringBoot的核心配置文件有哪幾個(gè)?它們的區(qū)別是什么?

SpringBoot的核心配置文件是application和bootstrap配置文件。application配置文件這個(gè)

主要用于SpringBoot項(xiàng)目的自動(dòng)化配置。bootstrap配置文件有以下幾個(gè)應(yīng)用場景。使用

SpringCloudConfig配置中心時(shí),這時(shí)需要在bootstrap配置文件中添加連接到配置中心的配置

屬性來加載外部配置中心的配置信息;一些固定的不能被覆蓋的屬性;一些加密/解密的場景;

?SpringBoot的配置文件有哪幾種格式?它們有什么區(qū)別?

.properties和.yml,它們的區(qū)別主要是書寫格式不同。1).properties=javastack

2),ymlapp:user:name:javastack另夕卜,.yml格式不支持@PropertySource注解導(dǎo)入配置。

?你如彳可理解SpringBoot中的Starters?

Starters可以理解為啟動(dòng)器,它包含了一系列可以集成到應(yīng)用里面的依賴包,你可以一站式集成

Spring及其他技術(shù),而不需要到處找示例代碼和依賴包。如你想使用SpringJPA訪問數(shù)據(jù)庫,

只要加入spring-boot-starter-data-jpa啟動(dòng)器依賴就能使用了。Starters包含了許多項(xiàng)目中需

要用到的依賴,它們能快速持續(xù)的運(yùn)行,都是一系列得到支持的管理傳遞性依賴。

?SpringBoot自動(dòng)配置原理是什么?

^@SpringBootApplication中有一個(gè);主解@EnableAutoConfiguration,翻譯成人話就是開啟自

動(dòng)配置而這個(gè)注解也是一個(gè)派生注解,其中的關(guān)鍵功能由@Import提供他有一個(gè)自動(dòng)裝配導(dǎo)入

轉(zhuǎn)換器的類的一個(gè)selectlmports()方法通過FactoryNames()方法掃描所有具有META-

INF/spring.factories的jar包然后將所有自動(dòng)配置類的值加載到Spring容器中。

?SpringBoot有哪幾種讀取配置的方式?

SpringBoot可以通過@PropertySource(加載制定文件),@Value,@Environment,

@ConfigurationProperties來綁定變量,

?SpringBoot實(shí)現(xiàn)熱部署有哪幾種方式?

SpringLoadedSpring-boot-devtools

?你如彳可理解SpringBoot酉己置加載順序?

1)properties文件;2)YAML文件;3)系統(tǒng)環(huán)境變量;4)命令行參數(shù);

?SpringBoot裝配Bean的原理

通過@EnableAutoConfiguration自動(dòng)獲取配置類信息,使用反射實(shí)例化為spring類,然后加載

到spring容器

?SpringBoot執(zhí)行流程

使用SpringApplication.run()啟動(dòng),在方法所在類上添加@SpringBootApplication注解,這個(gè)

注解由@EnableAutoConfiguration和(康盤門特)@ComponentScan等注解組成,

@EnableAutoConfiguration自動(dòng)加載SpringBoot配置和依賴包,默認(rèn)使用

@ComponentScan掃描當(dāng)前包及子包中的所有類,將有spring注解的類交給spring容器管理

?SpringCloud

?架構(gòu)演變

?傳統(tǒng)架構(gòu)一分布式架構(gòu)一SOA架構(gòu)一微服務(wù)架構(gòu)什么是分布式架構(gòu)分布式架構(gòu)就是將傳

統(tǒng)結(jié)構(gòu)按照模塊進(jìn)行拆分,不同的人負(fù)責(zé)不同的模塊,不會(huì)產(chǎn)生代碼沖突問題,方便開發(fā)。

?什么是SOA架構(gòu)SOA架構(gòu)就是將業(yè)務(wù)邏輯層提取出來,將相似的業(yè)務(wù)邏輯形成一個(gè)服務(wù),提

供外部訪問接口,服務(wù)之間訪問通過RPC調(diào)用實(shí)現(xiàn)。

?什么是微服務(wù)架構(gòu)微服務(wù)類似于SOA架構(gòu),但是比SOA架構(gòu)粒度更細(xì),更輕量。微服務(wù)架

構(gòu)與SOA架構(gòu)區(qū)別SOA是基于WebService和ESP實(shí)現(xiàn),底層基于HTTP協(xié)議和使用XML

方式傳輸,XML在網(wǎng)絡(luò)傳輸過程中會(huì)產(chǎn)生大量冗余。

?彳瓢員務(wù)由SOA架構(gòu)演變而來,繼承了SOA架構(gòu)的優(yōu)點(diǎn),同時(shí)對SOA架構(gòu)缺點(diǎn)進(jìn)行改善,數(shù)

據(jù)傳輸采用JSON格式,相比于XML更輕量和快捷,粒度更細(xì),更加便于敏捷開發(fā)。SOA數(shù)

據(jù)庫會(huì)存在共享,微服務(wù)提倡每個(gè)服務(wù)連接獨(dú)立的數(shù)據(jù)

?HTTP請求的執(zhí)行漏呈

?用戶在瀏覽器輸入網(wǎng)址瀏覽器拿到網(wǎng)址后,通過DNS服務(wù)器查詢網(wǎng)址的ip地址瀏覽器得到

ip地址后,和ip地址建立一條通道(TCP連接)三次握手

?瀏覽器向服務(wù)器發(fā)出一個(gè)請求,包括URL,協(xié)議版本號(hào)(http1.0等),協(xié)議頭(請求的方法get,客戶

端cookie,agent信息等等),協(xié)議內(nèi)容服務(wù)器拿到請求后,根據(jù)請求內(nèi)容尋找相應(yīng)的數(shù)據(jù)。

?如果找不到,返回錯(cuò)誤碼(例如404)如果能找到,返回內(nèi)容(包括狀態(tài)碼,header頭,例如是否

壓縮,是否分段傳輸?shù)鹊?返回實(shí)體內(nèi)容)斷開連接:T殳情況下,服務(wù)器關(guān)閉tcp連接,如果有

Connection:keep-alive,則不會(huì)關(guān)閉tcp,下次有請求的時(shí)候還是用同f連接瀏覽器拿到返回

數(shù)據(jù)后渲染頁面

?TCPHTTP

?https:〃/s/jTDU-zxP1INTYLpGLypiXO

?TCP是什么

TCP是面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。面向連接:一定是「一對一」

才能連接,不能像UDP協(xié)議可以一個(gè)主機(jī)同時(shí)向多個(gè)主機(jī)發(fā)送消息,也就是一對多是無法做

到的;可靠的:無論的網(wǎng)絡(luò)鏈路中出現(xiàn)了怎樣的鏈路變化,TCP都可以保證一個(gè)報(bào)文一定能夠

到達(dá)接收端;字節(jié)流:消息是「沒有邊界」的,所以無論我們消息有多大都可以進(jìn)行傳輸。并

且消息是I■有序的」,當(dāng)「前一個(gè)」消息沒有收到的時(shí)候,即使它先收到了后面的字節(jié)已經(jīng)收

至IJ,那么也不能扔給應(yīng)用層去處理,同時(shí)對「重復(fù)」的報(bào)文會(huì)自動(dòng)丟棄。

?TCP三次握手過程

先是初始狀態(tài):客戶端處于closed(關(guān)閉)狀態(tài),服務(wù)器處于listen(監(jiān)聽)狀態(tài)。第一次握手:

建立連接時(shí),客戶端發(fā)送syn包(syn=j)到服務(wù)器,并進(jìn)入SYN_SENT請求狀態(tài),等待服務(wù)

器確認(rèn);SYN:同步序列編號(hào)。第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN

(ack=j+l),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入

SYN_RECV接收狀態(tài);第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)

包ACK(ack=k+l),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED(已確認(rèn)TCP連接

成功)狀態(tài),完成三次握手。

?如何在Linux系統(tǒng)中查看TCP狀態(tài)?

TCP的連接狀態(tài)查看,在Linux可以通過netstat-napt命令直看。

?為什么不是一次、二次握手?

防止了服務(wù)器端的一直等待而浪費(fèi)資源。三次握手才可以同步雙方的初始序列號(hào)三次握手才可

以阻止歷史重復(fù)連接的初始化(主要原因)不使用「兩次握手」和「四次握手」的原因:

「兩次握手」:無法防止歷史連接的建立,會(huì)造成雙方資源的浪費(fèi),也無法可靠的同步雙方序

列號(hào);「四次握手」:三次握手就已經(jīng)理論上最少可靠連接建立,所以不需要使用更多的通信

次數(shù)。

?TCP四次分手

?初始化狀態(tài):客戶端和服務(wù)端都在連接狀態(tài),接下來開始進(jìn)行四次分手?jǐn)嚅_連接操作。

?第一次分手:第一次分手無論是客戶端還是服務(wù)端都可以發(fā)起這個(gè)請求

?第二次分手:服務(wù)端接收到客戶端的釋放請求連接之后,知道客戶端沒有數(shù)據(jù)要發(fā)給自己

了,然后服務(wù)端發(fā)送ACK=1告訴客戶端收到你發(fā)給我的信息,此時(shí)服務(wù)端處于

CLOSE_WAIT等待關(guān)閉狀態(tài)。

?第三次分手:此時(shí)服務(wù)端向客戶端把所有的數(shù)據(jù)發(fā)送完了,然后發(fā)送一個(gè)FIN=1,用于告

訴客戶端,服務(wù)端的所有數(shù)據(jù)發(fā)送完畢,客戶端你也可以關(guān)閉接受數(shù)據(jù)連接了。此時(shí)服務(wù)

端狀態(tài)處于LAT_ACK狀態(tài),來等待確認(rèn)客戶端是否收到了自己的請求。

?第四次分手:此時(shí)如果客戶端收到了服務(wù)端發(fā)送完的信息之后,就發(fā)送ACK=1,告訴服

務(wù)端,客戶端已經(jīng)收到了你的信息,還會(huì)有一個(gè)2MSL的延遲等待,如果沒問題就直接關(guān)

閉了

?為什么會(huì)有2MSL等待

因?yàn)橐獙?yīng)這樣一種情況,最后客戶端發(fā)送的ACK=1給服務(wù)端的過程中丟失了,服務(wù)端

沒收到,服務(wù)端會(huì)認(rèn)為我已經(jīng)發(fā)送完數(shù)據(jù)了,怎么客戶端為什么沒回應(yīng)我?是不是中途丟

失了?然后服務(wù)端再次發(fā)起斷開連接的請求,一個(gè)來回就是2MSL客戶端給服務(wù)端發(fā)送

的ACK=1丟失,服務(wù)端等待1MSL沒收到,然后重新發(fā)送消息需要1MSL。如果再次接

收到服務(wù)端的消息,則重啟2MSL計(jì)時(shí)器,發(fā)送確認(rèn)請求??蛻舳酥恍璧却?MSL,如果

沒有再次收到服務(wù)端的消息,就說明服務(wù)端已經(jīng)接收到自己確認(rèn)消息;此時(shí)雙方就都關(guān)閉

的連接,TCP四次分手就執(zhí)行完畢了。

?為什么揮手需要四次?

關(guān)閉連接時(shí),客戶端向服務(wù)端發(fā)送FIN時(shí),僅僅表示客戶端不再發(fā)送數(shù)據(jù)了但是還能接收

數(shù)據(jù)。服務(wù)器收到客戶端的FIN報(bào)文時(shí),先回一個(gè)ACK應(yīng)答報(bào)文,而服務(wù)端可能還有數(shù)

據(jù)需要處理和發(fā)送,等服務(wù)端不再發(fā)送數(shù)據(jù)時(shí),才發(fā)送FIN報(bào)文給客戶端來表示同意現(xiàn)在

關(guān)閉連接。從上面過程可知,服務(wù)端通常需要等待完成數(shù)據(jù)的發(fā)送和處理,所以服務(wù)端

的ACK和FIN一般都會(huì)分開發(fā)送,從而比三次握手導(dǎo)致多了一次。

?TCP與UDP區(qū)別

LTCP面向連接,UDP是無連接的2、TCP保證數(shù)據(jù)正確性,UDP可能丟包3、TCP保證

數(shù)據(jù)順序,UDP不保證4、TCP面向字節(jié)流;UDP是面向報(bào)文的5、TCP要求系統(tǒng)資源較多,

UDP較少;

?網(wǎng)絡(luò)七層模型

物理層:物理層負(fù)責(zé)最后將信息編碼成電流脈沖或其它信號(hào)用于網(wǎng)上傳輸;數(shù)據(jù)鏈路層:數(shù)據(jù)

鏈路層通過物理網(wǎng)絡(luò)鏈路供數(shù)據(jù)傳輸。不同的數(shù)據(jù)鏈路層定義了不同的網(wǎng)絡(luò)和特征,其中包括物

理編址、網(wǎng)絡(luò)結(jié)構(gòu)、錯(cuò)誤校驗(yàn)這些網(wǎng)絡(luò)層網(wǎng)絡(luò)層就是說負(fù)責(zé)在開始和終點(diǎn)之間建立連接;可以

理解為,要確定計(jì)算機(jī)的位置,怎么來確定?就可以用IPv4,IPv6!傳輸層就是說每一個(gè)應(yīng)

用程序都會(huì)在網(wǎng)卡注冊一個(gè)端口號(hào),用來端口與端口的通信!常用的(TCP/IP)協(xié)議;會(huì)話

層會(huì)話層建立、管理和終止表示層與實(shí)體之間的通信會(huì)話;建立一個(gè)連接(自動(dòng)的手機(jī)信息、

自動(dòng)的網(wǎng)絡(luò)尋址);表示層:好像是可以解決不同系統(tǒng)之間的通信,eg:Linux下的QQ和

Windows下的QQ可以通信;應(yīng)用層:

?UDP應(yīng)用場景

網(wǎng)絡(luò)數(shù)據(jù)大多為短消息對數(shù)據(jù)安全性無特殊要求網(wǎng)絡(luò)負(fù)擔(dān)非常重,但對響應(yīng)速度要求高

?如果雙方建立連接,一方出問題怎么辦?

如果已經(jīng)建立連接,但是服務(wù)端一直等待接收,發(fā)送端出現(xiàn)問題一直不能發(fā)送。所以可以設(shè)計(jì)

一個(gè)?;畹挠?jì)時(shí)器,如果一方出現(xiàn)問題,另一方過了這個(gè)計(jì)時(shí)器的時(shí)間,就發(fā)送試探報(bào)文,以

后每隔75秒發(fā)送一次。若一連發(fā)送10個(gè)探測報(bào)文仍然沒反應(yīng),服務(wù)器就認(rèn)為客戶端出了故障,

接著就關(guān)閉連接。

?TCP字段意思

?TCP頭部報(bào)文

一個(gè)是源端口號(hào)和目的端口號(hào),源端口號(hào)就是指本地端口,目的端口就是遠(yuǎn)程端口。

?SequenceNumbe=序歹!I號(hào)

這個(gè)就是用于TCP通信過程中某T專輸方向上一個(gè)字節(jié)流的每個(gè)字節(jié)的編號(hào),就是為了確

保數(shù)據(jù)通信的有序性,避免網(wǎng)絡(luò)中亂序的問題。接收端根據(jù)這個(gè)編號(hào)進(jìn)行確認(rèn),保證分割

的數(shù)據(jù)段在原始數(shù)據(jù)包的位置。再通俗一點(diǎn)的講,每個(gè)字段在傳送中用序列號(hào)來標(biāo)記自己

位置的,而這個(gè)字段就是用來完成雙方傳輸中確保字段原始位置是按照傳輸順序的。(發(fā)

送方是數(shù)據(jù)是怎樣一個(gè)順序,到了接受方也要確保是這個(gè)順序)

?AcknowledgmentNumbe=確認(rèn)序列號(hào)

確認(rèn)序列號(hào)是用來接收,確認(rèn)端就是說一個(gè)所期望收到的下一序列號(hào)。確認(rèn)序號(hào)應(yīng)該是是

上次已成功收到數(shù)據(jù)字節(jié)序號(hào)加1,只有當(dāng)標(biāo)志位中的ACK標(biāo)志為1時(shí)該確認(rèn)序列號(hào)的字

段才有效。主要用來解決不丟包的問題。

?TCPFlag

TCP首部中有6個(gè)標(biāo)志比特,它們中的多個(gè)可同時(shí)被設(shè)置為1,主要是用于操控TCP的狀

態(tài)機(jī)的,依次為URG,ACK,PSH,RST,SYN,FIN。

?ACK

這個(gè)標(biāo)識(shí)可以理解為發(fā)送端發(fā)送數(shù)據(jù)到接收端,發(fā)送的時(shí)候ACK為0,標(biāo)識(shí)接收端還未應(yīng)

答,一旦接收端接收數(shù)據(jù)之后,就將ACK置為1,發(fā)送端接收到之后,就知道了接收端已

經(jīng)接收了數(shù)據(jù)。

?SYN

就是用來建立TCP的連接,SYN標(biāo)志位是和ACK標(biāo)志位搭配使用,當(dāng)連接請求的時(shí)候,

SYN=1,ACK=0連接被響應(yīng)的時(shí)候,SYN=1,ACK=1;這個(gè)標(biāo)志的數(shù)據(jù)包經(jīng)常被用來進(jìn)

行端口掃描。掃描者發(fā)送一個(gè)只有SYN的數(shù)據(jù)包,如果對方主機(jī)響應(yīng)了一個(gè)數(shù)據(jù)包回來,

就表明這臺(tái)主機(jī)存在這個(gè)端口。

?FIN

表示發(fā)送端已經(jīng)達(dá)到數(shù)據(jù)末尾,也就是說雙方的數(shù)據(jù)傳送完成,沒有數(shù)據(jù)可以傳送了,發(fā)

送FIN標(biāo)志位的TCP數(shù)據(jù)包后,連接就會(huì)被斷開。這個(gè)很好理解,就是說,發(fā)送端只剩最

后的一段數(shù)據(jù)了,同時(shí)要告訴接收端后邊沒有數(shù)據(jù)可以接受了,所以用FIN標(biāo)識(shí)一下,接

收端看到這個(gè)FIN之后,哦!這是接受的最后的數(shù)據(jù),接受完就關(guān)閉了。

?Http協(xié)議的交互流程,和https的差異,ssl的交互流程

?Rest和Http什么關(guān)系?如彳于里解Rest風(fēng)格

?TCP的滑動(dòng)窗口

?HTTP常見的狀態(tài)碼,有哪些?

?204206200表示成功接收報(bào)文

?301302304重定向,資源位置發(fā)生變化,需要重新發(fā)送請求

?400403404客戶端請求錯(cuò)誤,請求報(bào)文有誤,服務(wù)器無法處理

?500501502503服務(wù)器錯(cuò)誤,處理請求發(fā)送錯(cuò)誤

?說一下GET和POST的區(qū)別?

?Get方法的含義是請求從服務(wù)器獲取資源,這個(gè)資源可以是靜態(tài)的文本、頁面、圖片視頻

等.

?比如,你打開我的文章,瀏覽器就會(huì)發(fā)送GET請求給服務(wù)器,服務(wù)器就會(huì)返回文章的所有

文字及資源。

?而POST方法則是相反操作,它向URI指定的資源提交數(shù)據(jù),數(shù)據(jù)就放在報(bào)文的body里。

?比如,你在我文章底部,敲入了留言后點(diǎn)擊「提交」(暗示你們留言),瀏覽器就會(huì)執(zhí)行

一次POST請求,把你的留言文字放進(jìn)了報(bào)文body里,然后拼接好POST請求頭,通過

TCP協(xié)議發(fā)送給服務(wù)器。

?GET和POST方法都是安全和幕等的嗎?

?在HTTP協(xié)議里,所謂的「安全」是指請求方法不會(huì)「破壞」服務(wù)器上的資源。

?所謂的「鬲等」,意思是多次執(zhí)行相同的操作,結(jié)果都是「相同」的。

?那么很明顯GET方法就是安全且幕等的,因?yàn)樗恰钢蛔x」操作,無論操作多少次,服務(wù)

器上的數(shù)據(jù)都是安全的,且每次的結(jié)果都是相同的。

?POST因?yàn)槭恰感略龌蛱峤粩?shù)據(jù)」的操作,會(huì)修改服務(wù)器上的資源,所以是不安全的,且多

次提交數(shù)據(jù)就會(huì)創(chuàng)建多個(gè)資源,所以不是鬲等的。

?你知道的HTTP(1.1)的優(yōu)點(diǎn)有哪些,怎么體現(xiàn)的?

?HTTP最凸出的優(yōu)點(diǎn)是「簡單、靈活和易于擴(kuò)展、應(yīng)用廣泛和跨平臺(tái)」。

?1.簡單

?HTTP基本的報(bào)文格式就是header+body,頭部信息也是key-value簡單文本的形式,

易于理解,降低了學(xué)習(xí)和使用的門檻。

?2.靈活和易于擴(kuò)展

?HTTP協(xié)議里的各類請求方法、URI/URL、狀態(tài)碼、頭字段等每個(gè)組成要求都沒有被固定死,

都允許開發(fā)人員自定義和擴(kuò)充。

?同時(shí)HTTP由于是工作在應(yīng)用層(OSI第七層),則它下層可以隨意變化。

?HTTPS也就是在HTTP與TCP層之間增加了SSL/TLS安全傳輸層,HTTP/3甚至把

TCPP層換成了基于UDP的QUIC.

?3.應(yīng)用廣泛和跨平臺(tái)

?互聯(lián)網(wǎng)發(fā)展至今,HTTP的應(yīng)用范圍非常的廣泛,從臺(tái)式機(jī)的瀏覽器到手機(jī)上的各種APP,

從看新聞、刷貼吧到購物、理財(cái)、吃雞,HTTP的應(yīng)用片地開花,同時(shí)天然具有跨平臺(tái)的優(yōu)

越性。

?那它的缺點(diǎn)呢?

?1無狀態(tài)雙刃劍

HTTP協(xié)議里有優(yōu)缺點(diǎn)一體的雙刃劍,分別是「無狀態(tài)、明文傳輸」,同時(shí)還有一大缺點(diǎn)

「不安全」。1.無狀態(tài)雙刃劍無狀態(tài)的好處,因?yàn)榉?wù)器不會(huì)去記憶HTTP的狀態(tài),所以

不需要額外的資源來記錄狀態(tài)信息,這能減輕^務(wù)器的負(fù)擔(dān),能夠把更多的CPU和內(nèi)存用

來對外提供服務(wù)。無狀態(tài)的壞處,既然服務(wù)器沒有記憶能力,它在完成有關(guān)聯(lián)性的操作時(shí)

會(huì)非常麻煩。例如登錄->添加購物車->下單->結(jié)算->支付,這系列操作都要知道用戶的

身份才行。但服務(wù)器不知道這些請求是有關(guān)聯(lián)的,每次都要問一遍身份信息。這樣每操作

一次,都要驗(yàn)證信息,這樣的購物體驗(yàn)還能愉快嗎?別問,問就是酸爽!對于無狀態(tài)的問

題,解法方案有很多種,其中比較簡單的方式用Cookie技術(shù)。Cookie通過在請求和響應(yīng)

報(bào)文中寫入Cookie信息來控制客戶端的狀態(tài)。相當(dāng)于,在客戶端第一次請求后,服務(wù)器

會(huì)下發(fā)一個(gè)裝有客戶信息的「小貼紙」,后續(xù)客戶端請求服務(wù)器的時(shí)候,帶上「小貼紙」,

服務(wù)器就能認(rèn)得了了,

?2明文傳輸雙刃劍

明文意味著在傳輸過程中的信息,是可方便閱讀的,通過瀏覽器的F12控制臺(tái)或

Wireshark抓包都可以直接肉眼查看,為我們調(diào)試工作帶了極大的便利性。但是這正是這

樣,HTTP的所有信息都暴露在了光天化日下,相當(dāng)于信息裸奔。在傳輸?shù)穆L的過程中,

信息的內(nèi)容都毫無隱私可言,很容易就能被竊取,如果里面有你的賬號(hào)密碼信息,那你號(hào)

沒了。

?3不安全

HTTP比較嚴(yán)重的缺點(diǎn)就是不安全:通信使用明文(不加密),內(nèi)容可能會(huì)被竊聽。比如,

賬號(hào)信息容易泄漏,那你號(hào)沒了。不驗(yàn)證通信方的身份,因此有可能遭遇偽裝。比如,訪

問假的淘寶、拼多多,那你錢沒了。無法證明報(bào)文的完整性,所以有可能已遭篡改。比如,

網(wǎng)頁上植入垃圾廣告,視覺污染,眼沒了。HTTP的安全問題,可以用HTTPS的方式解決,

也就是通過引入SSL/TLS層,使得在安全上達(dá)到了極致。

?HTTP與HTTPS有哪些區(qū)別?

HTTP是超文本傳輸協(xié)議,信息是明文傳輸,存在安全風(fēng)險(xiǎn)的問題。HTTPS則解決HTTP不安

全的缺陷,在TCP和HTTP網(wǎng)絡(luò)層之間加入了SSL/TLS安全協(xié)議,使得報(bào)文能夠加密傳輸。

HTTP連接建立相對簡單,TCP三次握手之后便可進(jìn)行HTTP的報(bào)文傳輸。而HTTPS在TCP

三次握手之后,還需進(jìn)行SSL/TLS的握手過程,才可進(jìn)入加密報(bào)文傳輸。HTTP的端口號(hào)是

80,HTTPS的端口號(hào)是443。HTTPS協(xié)議需要向CA(證書權(quán)威機(jī)構(gòu))申請數(shù)字證書,來保

證^務(wù)器的身份是可信的。

?HTTPS解決了HTTP的哪些問題?

HTTP由于是明文傳輸,所以安全上存在以下三個(gè)風(fēng)險(xiǎn):竊聽風(fēng)險(xiǎn),比如通信鏈路上可以獲取

通信內(nèi)容,用戶號(hào)容易沒。篡改風(fēng)險(xiǎn),比如強(qiáng)制入垃圾廣告,視覺污染,用戶眼容易瞎。冒充

風(fēng)險(xiǎn),比如冒充淘寶網(wǎng)站,用戶錢容易沒。HTTPS在HTTP與TCP層之間加入了SSL/TLS協(xié)

議。可以很好的解決了上述的風(fēng)險(xiǎn):信息加密:交互信息無法被竊取,但你的號(hào)會(huì)因?yàn)椤缸?/p>

身忘記」賬號(hào)而沒。校驗(yàn)機(jī)制:無法篡改通信內(nèi)容,篡改了就不能正常顯示,但百度I■競價(jià)排

名」依然可以搜索垃圾廣告。身份證書:證明淘寶是真的淘寶網(wǎng),但你的錢還是會(huì)因?yàn)镮■剁手」

而沒??梢姡灰陨聿蛔觥笎骸?,SSL/TLS協(xié)議是能保證通信是安全的。

?HTTP協(xié)議有哪些方法

?一次HTTP請求的全過程,包括域名解析、定位主機(jī)等

?微服務(wù)遇見的坑

?SpringCloud有什么優(yōu)勢

?為什么需要學(xué)習(xí)SpringCloud

?不論是商業(yè)應(yīng)用還是用戶應(yīng)用,在業(yè)務(wù)初期都很簡單,我們通常會(huì)把它實(shí)現(xiàn)為單體結(jié)構(gòu)的應(yīng)用。

?但是,隨著業(yè)務(wù)逐漸發(fā)展,產(chǎn)品思想會(huì)變得越來越復(fù)雜,單體結(jié)構(gòu)的應(yīng)用也會(huì)越來越復(fù)雜。

?這就會(huì)給應(yīng)用帶來很多問題:代碼結(jié)構(gòu)混亂:業(yè)務(wù)復(fù)雜,導(dǎo)致代碼量很大,管理會(huì)越來越困難。

同時(shí),這也會(huì)給業(yè)務(wù)的快速迭代帶來巨大挑戰(zhàn);開發(fā)效率變低:開發(fā)人員同時(shí)開發(fā)一套代碼,

很難避免代碼沖突。

?開發(fā)過程會(huì)伴隨著不斷解決沖突的過程,這會(huì)嚴(yán)重的影響開發(fā)效率;排查解決問題成本高:

線上業(yè)務(wù)發(fā)現(xiàn)bug,修復(fù)bug的過程可能很簡單。

?什么是SpringCloud

?SpringCloud是很多框架的一個(gè)集合。

?它利用SpringBoot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā),如服務(wù)發(fā)現(xiàn)注冊、

配置中心、智能路由、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等,都可以用SpringBoot的

開發(fā)風(fēng)格做到一鍵啟動(dòng)和部署。

?SpringCloud并沒有重復(fù)制造輪子,它只是將很多家公司開發(fā)的比較成熟、經(jīng)得起實(shí)際考驗(yàn)的

服務(wù)框架組合起來,通過SpringBoot風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終

給開發(fā)者留出了一套比較簡單易懂、容易易部署和維護(hù)的分布式系統(tǒng)的一個(gè)開發(fā)工具包。

?SpringCloud優(yōu)缺點(diǎn)

優(yōu)點(diǎn):出生Spring大家族,可以保證后續(xù)的更新、完善。組件和功能很豐富也很齊全,例如、配

置管理、服務(wù)發(fā)現(xiàn)、斷路器、微服務(wù)網(wǎng)關(guān)等;SpringCloud社區(qū)活躍度很高,教程也很豐富,遇

到問題很容易找到解決方案;服務(wù)拆分粒度更細(xì),耦合度比較低,有利于資源重復(fù)利用,有利于

提高開發(fā)效率可以更精準(zhǔn)的制定優(yōu)化服務(wù)方案,提高系統(tǒng)的可維護(hù)性也減輕團(tuán)隊(duì)的成本,可以并

行開發(fā),不用關(guān)注其他人怎么開發(fā),專業(yè)的人做專業(yè)的事嘛先他適于互聯(lián)網(wǎng)時(shí)代,產(chǎn)品迭代周期也

比較短缺點(diǎn):微服務(wù)過多,治理成本高,不利于維護(hù)系統(tǒng)分布式系統(tǒng)開發(fā)的成本高有(容錯(cuò),分

布式事務(wù)等問題)

?SpringCloud組件

SpringCloudNetflix:NetflixOSS開源組件集成,包括Eureka、Hystrix,Ribbon,Feign、

Zuul等核心組件。Eureka:服務(wù)治理組件,包括服務(wù)端的注冊中心和客戶端的服務(wù)發(fā)現(xiàn)機(jī)制;

Ribbon:負(fù)載均衡的服務(wù)調(diào)用組件,具有多種負(fù)載均衡調(diào)用策略;Hystrix:服務(wù)容錯(cuò)組件,實(shí)現(xiàn)

了斷路器模式,為依賴服務(wù)的出錯(cuò)和延遲提供了容錯(cuò)能力;Feign:基于Ribbon和Hystrix的聲

明式服務(wù)調(diào)用組件;Zuul:API網(wǎng)關(guān)組件,對請求提供路由及過濾功能。SpringCloudBus:用

于傳播集群狀態(tài)變化的消息總線,使用輕量級(jí)消息代理鏈接分布式系統(tǒng)中的節(jié)點(diǎn),可以用來動(dòng)態(tài)刷

新集群中的服務(wù)配置。SpringCloudSecurity(思ki味兒提)他是安全工具包,有一個(gè)

OAuth2客戶端及登錄認(rèn)證進(jìn)行支持。SpringCloudSleuth(蘇斯)SpringCloud應(yīng)用程序的分

布式請求鏈路跟蹤,支持使用Zipkin、HTrace和基于日志(例如ELK)的跟蹤。SpringCloud

GatewayAPI網(wǎng)關(guān)組件,對請求提供路由及過濾功能。SpringCloudOpenFeign基于Ribbon

和Hystrix的聲明式服務(wù)調(diào)用組件,可以動(dòng)態(tài)創(chuàng)建基于SpringMVC注解的接口實(shí)現(xiàn)用于服務(wù)調(diào)用,

在SpringCloud2.0中已經(jīng)取代Feign.

?SpringBoot和SpringCloud的區(qū)別?

SpringBoot專注于快速方便的開發(fā)單個(gè)個(gè)體微服務(wù)。SpringCloud是關(guān)注全局的微服務(wù)的協(xié)調(diào)整

理和治理框架,它將SpringBoot開發(fā)的一個(gè)個(gè)單體微服務(wù)整合并管理起來,還為各個(gè)微服務(wù)之間

提供,配置管理、服務(wù)發(fā)現(xiàn)、斷路器、路由、微代理、事件總線、全局鎖、決策競選、分布式會(huì)話

等等集成服務(wù)SpringBoot可以離開SpringCloud獨(dú)立使用開發(fā)項(xiàng)目,但是SpringCloud離不開

SpringBoot,屬于依賴的關(guān)系SpringBoot專注于快速、方便的開發(fā)單個(gè)微服務(wù)個(gè)體,

SpringCloud關(guān)注全局的服務(wù)治理框架。

?SpringBoot開發(fā)分布式微服務(wù)時(shí),我們面I缶的問題

(1)與分布式系統(tǒng)相關(guān)的復(fù)雜性-這種開銷包括網(wǎng)絡(luò)問題,延遲開銷,帶寬問題,安全問題。(2)

服務(wù)發(fā)現(xiàn)-服務(wù)發(fā)現(xiàn)工具管理群集中的流程和服務(wù)如何查找和互相交談.它涉及一個(gè)服務(wù)目錄,在

該目錄中注冊服務(wù),然后能夠查找并連接到該目錄中的服務(wù)。(3)冗余-分布式系統(tǒng)中的冗余問題。

(4)負(fù)載平衡--負(fù)載平衡改善跨多個(gè)計(jì)算資源的工作負(fù)荷,諸如計(jì)算機(jī),計(jì)算機(jī)集群,網(wǎng)絡(luò)鏈路,

中央處理單元,或磁盤驅(qū)動(dòng)器的分布。(5)性能-問題由于各種運(yùn)營開銷導(dǎo)致的性能問題。(6)

部署復(fù)雜性-Devops技能的要求。

?服務(wù)注冊和發(fā)現(xiàn)是什么意思?SpringCloud如何實(shí)現(xiàn)?

就是說當(dāng)我們開始一個(gè)項(xiàng)目時(shí),我們通常在屬性文件中進(jìn)行所有的配置。隨著越來越多的服務(wù)開發(fā)

和部署,添加和修改這些屬性變得更加復(fù)雜。有些服務(wù)性能可能會(huì)下降,而某些位置可能會(huì)發(fā)生變

化.手動(dòng)更改屬性可能會(huì)產(chǎn)生問題。Eureka服務(wù)注冊和發(fā)現(xiàn)可以解決這個(gè)問題將所有服務(wù)都在

Eureka服務(wù)器上注冊并通過調(diào)用Eureka服務(wù)器完成查找,就可以解決服務(wù)任何更改和處理了。

?SpringCloud和dubbo區(qū)別?

dubbo由于是二進(jìn)制的傳輸,占用帶寬會(huì)更少SpringCloud是http協(xié)議傳輸,帶寬會(huì)比較多,同

時(shí)使用http協(xié)議一般會(huì)使用JSON報(bào)文,消耗會(huì)更大dubbo的開發(fā)難度較大,好像是是dubbo

有jar包依賴問題,不知道現(xiàn)在解決沒有dubbo的注冊中心可以選擇zk,redis等多種,

springcloud的注冊中心只能用eureka或者自研dubbo服務(wù)網(wǎng)關(guān),分布式配置服務(wù)追蹤什么的好

像都不是很完善,cloud的話則提供的還可以

?Eureka和Zookeeper區(qū)另!|

?1.Eureka取CAP的AP,注重可用性,Zookeeper取CAP的CP注重一致性。2.Zookeeper

在選舉期間注冊服務(wù)會(huì)癱瘓,雖然服務(wù)最終會(huì)恢復(fù),但選舉期間不可用。

?3.eureka的自我保護(hù)機(jī)制,他不會(huì)再從注冊列表去移除因長時(shí)間沒收到心跳而過期的服務(wù)。依

然能接受新服務(wù)的注冊和查詢請求,但不會(huì)被同步到其他節(jié)點(diǎn)。不會(huì)服務(wù)癱瘓。

?4.Zookeeper有Leader和Follower角色,Eureka各個(gè)節(jié)點(diǎn)平等。

?5.Zookeeper采用過半數(shù)存活原則,Eureka采用自我保護(hù)機(jī)制解決分區(qū)問題。

?6.eureka本質(zhì)是一個(gè)工程,Zookeeper只是一個(gè)進(jìn)程。

?eureka自我保護(hù)機(jī)制是什么?

當(dāng)EurekaServer節(jié)點(diǎn)在短時(shí)間內(nèi)丟失了過多實(shí)例的連接時(shí)(比如網(wǎng)絡(luò)故障或頻繁啟動(dòng)關(guān)閉客戶端)

節(jié)點(diǎn)會(huì)進(jìn)入自我保護(hù)模式,保護(hù)注冊信息,不再刪除注冊數(shù)據(jù),故障恢復(fù)時(shí),就會(huì)自動(dòng)退出自我保

護(hù)模式。

?Nginx與Ribbon的區(qū)另[|

Nginx是反向代理,同時(shí)可以實(shí)現(xiàn)負(fù)載均衡,nginx攔截客戶端請求采用負(fù)載均衡策略根據(jù)

upstream配置進(jìn)行轉(zhuǎn)發(fā),相當(dāng)于請求通過nginx服務(wù)器進(jìn)行轉(zhuǎn)發(fā)。Ribbon是客戶端負(fù)載均衡,

從注冊中心讀取目標(biāo)服務(wù)器信息,然后客戶端采用輪詢策略對服務(wù)直接訪問,全程在客戶端操作。

?Ribbon底層實(shí)現(xiàn)原理

Ribbon使用(迪斯卡娃兒瑞可藍(lán)的)discoveryclient從注冊中心讀取目標(biāo)服務(wù)信息,對同一接

口請求進(jìn)行計(jì)數(shù),使用%取余算法獲取目標(biāo)服務(wù)集群索引,返回獲取到的目標(biāo)服務(wù)信息。

?常見的限流手段

計(jì)數(shù)器、滑動(dòng)窗口、漏桶、令牌。

?計(jì)數(shù)器

"計(jì)數(shù)器是一種比較簡單的限流算法,用途比較廣泛,在接口層面,很多地方使用這種方式限

流。在一段時(shí)間內(nèi),進(jìn)行計(jì)數(shù),與閥值進(jìn)行比較,到了時(shí)間臨界點(diǎn),將計(jì)數(shù)器清0。

?java

?Hashmap

?如何解決hash沖突問題?

使用鏈表存放hash值,相等且內(nèi)容不等,存放在同一個(gè)鏈表里面

?HashmapPUT方法底層實(shí)現(xiàn)

L判斷table是否為空,是空的就執(zhí)行resize擴(kuò)容2.如果不為空就根據(jù)key計(jì)算hash值得到

數(shù)組索引,如果table為空直接,新建節(jié)點(diǎn)添加,如果不為空就判斷table的首個(gè)元素是否和

key一樣,如果相同就直接覆蓋3.還會(huì)判斷table是否是紅黑樹,如果是就在紅黑樹里面插入

鍵值對4.如果不是則會(huì)遍歷table,判斷鏈表長度是否大于8,大于8就把鏈表轉(zhuǎn)換為紅黑樹,

否則進(jìn)行鏈表的插入操作,如果key已經(jīng)存在,直接覆蓋value即可5.插入成功以后判斷實(shí)際

存在的鍵值對是否超出了最大容量,如果超出就擴(kuò)容默認(rèn)初始容量為16.加載因子大小是

16*0.75=12,大于12,每次擴(kuò)容是*2GET實(shí)現(xiàn):獲取首節(jié)點(diǎn),hash碰撞概率小,通常鏈表

第一個(gè)節(jié)點(diǎn)就是值,沒必要去循環(huán)如果不止一個(gè)節(jié)點(diǎn),就需要循環(huán)遍歷,存在多個(gè)hash碰撞

判斷是否是紅黑樹,如果是則調(diào)用樹的查找

?Hashmap加載因子為什么是0.75?

?折中方案,空間利用率高,沖突少0.75最合適

?Hashmapl.7數(shù)組擴(kuò)容死循環(huán)問題

因?yàn)閙ap數(shù)組擴(kuò)容的鏈表采用頭插入法頭插入法相當(dāng)于讓最新的沖突節(jié)點(diǎn)存放到最前,在多

線程的情況下操作map,導(dǎo)致死循環(huán)問題尾插入相反

?hashmap底層

?hash方法:讓key的hash值的高十六位也參與運(yùn)算,key如果等于null,hash就是0,

存放在數(shù)組0的位置

?Hap根據(jù)key查詢時(shí)間復(fù)雜度是多少

Map根據(jù)key直接計(jì)算index值,直接從數(shù)組中查詢數(shù)據(jù)如何indxe沒沖突直接獲取復(fù)雜度

為01如果沖突,遍歷鏈表就是on

?1.8改進(jìn)了哪些地方

1.1.8map采用尾部插入法2.解決了map死循環(huán)的問題3.鏈表長度大于8轉(zhuǎn)成紅黑樹小于

6轉(zhuǎn)換成鏈表

?為什么要引入紅黑樹

?紅黑樹,為什么允許局部不平衡

?因?yàn)閕ndex沖突過多,導(dǎo)致鏈表過長,為了解決鏈表直詢效率慢,這時(shí)候大于8數(shù)組容量

大于64就轉(zhuǎn)換成了紅黑樹存放,時(shí)間復(fù)雜度從On變?yōu)镺(logn)

?Map不安全有安全的替代方案嘛

?ConcurrentHashm叩采用分段鎖16段,1.8引入了CAS無鎖機(jī)制

?ConcurrentHashMap

ConcurrentHashM叩線程安全的Map,hashtable類基本上所有的方法都是采用

synchronized進(jìn)行線程安全控制高并發(fā)情況下效率就降低ConcurrentHashMap是采用了

分段鎖的思想提高性能,鎖粒度更細(xì)化

?jdkl.7和jdkl.8里面ConcurrentHashMap實(shí)現(xiàn)的區(qū)別有沒了解

JDK8之前,ConcurrentHashMap使用鎖分段技術(shù),將數(shù)據(jù)分成一段段存儲(chǔ),每個(gè)數(shù)據(jù)段配

置一把鎖,即segment類,這個(gè)類繼承ReentrantLock來保證線程安全技術(shù)點(diǎn):

Segment+HashEntryJKD8的版本取消Segment這個(gè)分段鎖數(shù)據(jù)結(jié)構(gòu),底層也是使用Node

數(shù)組+鏈表+紅黑樹,從而實(shí)現(xiàn)對每一段數(shù)據(jù)就行加鎖,也減少了并發(fā)沖突的概率,

CAS(讀)+Synchronized(寫)技術(shù)點(diǎn):Node+Cas+Synchronized

?ConcurrentHashMapPUT的核心邏輯(1.8)

put的核心流程1、key進(jìn)行重哈希spread(key.hashCode())2、對當(dāng)前table進(jìn)行無條件循

環(huán)3、如果沒有初始化table,則用initTable進(jìn)行初始化4、如果沒有hash沖突,則直接用

cas插入新節(jié)點(diǎn),成功后則直接判斷是否需要擴(kuò)容,然后結(jié)束5、(fh=f.hash)==MOVED如

果是這個(gè)狀態(tài)則是擴(kuò)容操作,先進(jìn)行擴(kuò)容6、存在hash沖突,利用synchronized(f)加鎖保證

線程安全7、如果是鏈表,則直接遍歷插入,如果數(shù)量大于8,則需要轉(zhuǎn)換成紅黑樹8、如果是

紅黑樹則按照紅黑樹規(guī)則插入9、最后是檢查是否需要擴(kuò)容addCount()

?Hashmap工作原理

我們通過put()和get()方法儲(chǔ)存和獲取對象。當(dāng)我們將鍵值對傳遞給put()方法時(shí),它調(diào)用健對

象的hashCodeO方法來計(jì)算hashcode,讓后找到bucket位置來儲(chǔ)存值對象。當(dāng)獲取對象時(shí),

通過鍵對象的equals。方法找到正確的鍵值對,然后返回值對象。HashMap使用鏈表來解決

碰撞問題,當(dāng)發(fā)生碰撞了,對象將會(huì)儲(chǔ)存在鏈表的下一個(gè)節(jié)點(diǎn)中.HashMap在每個(gè)鏈表節(jié)點(diǎn)

中儲(chǔ)存鍵值對對象。

?當(dāng)兩個(gè)不同的健對象的hashcode相同時(shí)會(huì)發(fā)生什么?

它們會(huì)儲(chǔ)存在同一個(gè)bucket位置的鏈表中。鍵對象的equals。方法用來找到鍵值對。

?為什么重寫了equals方法要重寫hashcode

?重寫equals。方法同時(shí)重寫hashcode()方法,就是為了保證當(dāng)兩個(gè)對象通過equals。方法

比較相等時(shí),那么他們的hashCode值也一定要保證相等,如果不這樣的話,只重寫

equals,判斷值相等,但是無法判斷同一個(gè)對象是否相等,不重寫用的就是。bject里面的

hashcode方法

?兩個(gè)對象相等,hashcode一定相等

?兩個(gè)對象不等,hashcode不一定不等

?hashcode相等,兩個(gè)對象不一定相等

?hashcode不等,兩個(gè)對象一定不等

?hashmap容量為什么是2的幕次

?hash算法考慮的點(diǎn)有哪些

?什么是hash

?hash也稱散列,哈希,原理就是把任何長度的輸入,通過hash算法變成固定的長度的輸

?hash特點(diǎn):從hash值不可以反向推導(dǎo)出原始數(shù)據(jù)

?輸入的數(shù)據(jù)微小變化,會(huì)得到不同的hash值,相同的數(shù)據(jù)會(huì)得到相同的值

?hash算法執(zhí)行效率要高,長文本也要快速算出哈希值

?hash算法沖突概率要小

?hashmap結(jié)構(gòu)

?Node

?Node實(shí)現(xiàn)了Map.Entry里面有四個(gè)屬性

?hash

?key

?value

?next

?你知道hash的實(shí)現(xiàn)嗎?為什么要這樣實(shí)現(xiàn)?

JDK1.8中,是通過hashCodeO的高16位異或低16位實(shí)現(xiàn)的:(h=k.hashCodeO)A

(h>>>16),主要是從速度,功效和質(zhì)量來考慮的,減少系統(tǒng)的開銷,也不會(huì)造成因?yàn)楦呶粵]

有參與下標(biāo)的計(jì)算,從而引起的碰撞。

?為什么要用異或運(yùn)算符?

保證了對象的hashCode的32位值只要有一位發(fā)生改變,整個(gè)hash()返回值就會(huì)改變。盡可

能的減少碰撞。

?HashMap的table的容量如何確定?loadFactor是什么?該容量如何變化?這種變化會(huì)帶來

什么問題?

?①、table數(shù)組大小是由opacity這個(gè)參數(shù)確定的,默認(rèn)是16,也可以構(gòu)造時(shí)傳入,最大

限制是1<<30;

?②、loadFactor是裝載因子,主要目的是用來確認(rèn)table數(shù)組是否需要?jiǎng)討B(tài)擴(kuò)展,默認(rèn)值

是0.75,比如table數(shù)組大小為16,裝載因子為0.75時(shí),threshold就是12,當(dāng)table

的實(shí)際大小超過12時(shí),table就需要?jiǎng)討B(tài)擴(kuò)容;

?③、擴(kuò)容時(shí),調(diào)用resizeO方法,將table長度變?yōu)樵瓉淼膬杀?注意是table長度,而

不是threshold)

?④、如果數(shù)據(jù)很大的情況下,擴(kuò)展時(shí)將會(huì)帶來性能的損失,在性能要求很高的地方,這種

損失很可能很致命。

?HashMap中put方法的過程?

?調(diào)用哈希函數(shù)獲取Key對應(yīng)的hash值,再計(jì)算其數(shù)組下標(biāo);

?如果沒有出現(xiàn)哈希沖突,則直接放入數(shù)組;如果出現(xiàn)哈希沖突,則以鏈表的方式放在鏈表

后面;

?如果鏈表長度超過閥值(TREEIFYTHRESHOLD==8),就把鏈表轉(zhuǎn)成紅黑樹,鏈表長度低

于6,就把紅黑樹轉(zhuǎn)回鏈表;

?如果結(jié)點(diǎn)的key已經(jīng)存在,則替換其value即可;

?如果集合中的鍵值對大于12,調(diào)用resize方法進(jìn)行數(shù)組擴(kuò)容。"

?數(shù)組擴(kuò)容的過程?

?創(chuàng)建一個(gè)新的數(shù)組,其容量為舊數(shù)組的兩倍,并重新計(jì)算舊數(shù)組中結(jié)點(diǎn)的存儲(chǔ)位置。結(jié)點(diǎn)

在新數(shù)組中的位置只有兩種,原下標(biāo)位置或原下標(biāo)+舊數(shù)組的大小。

?拉鏈法導(dǎo)致的鏈表過深問題為什么不用二叉查找樹代替,而選擇紅黑樹?為什么不一直使用紅

黑樹?

?所以選擇紅黑樹是為了解決二叉查找樹的缺陷,二叉查找樹在特殊情況下會(huì)變成一條線性

結(jié)構(gòu)(這就跟原來使用鏈表結(jié)構(gòu)一樣了,造成很深的問題),遍歷查找會(huì)非常慢。

?而紅黑樹在插入新數(shù)據(jù)后可能需要通過左旋,右旋、變色這些操作來保持平衡,引入紅黑

樹就是為了查找數(shù)據(jù)快,解決鏈表查詢深度的問題,我們知道紅黑樹屬于平衡二叉樹,但

是為了保持"平衡”是需要付出代價(jià)的,但是該代價(jià)所損耗的資源要比遍歷線性鏈表要少,

所以當(dāng)長度大于8的時(shí)候,會(huì)使用紅黑樹,如果鏈表長度很短的話,根本不需要引入紅黑

樹,引入反而會(huì)慢。

?說說你對紅黑樹的見解?

?L每個(gè)節(jié)點(diǎn)非紅即黑

?2、根節(jié)點(diǎn)總是黑色的

?3、如果節(jié)點(diǎn)是紅色的,則它的子節(jié)點(diǎn)必須是黑色的(反之不一定)

?4、每個(gè)葉子節(jié)點(diǎn)都是黑色的空節(jié)點(diǎn)(NIL節(jié)點(diǎn))

?5、從根節(jié)點(diǎn)到葉節(jié)點(diǎn)或空子節(jié)點(diǎn)的每條路徑,必須包含相同數(shù)目的黑色節(jié)點(diǎn)(即相同的黑

色高度)

?jdk8中對HashMap做了哪些改變?

?在java1.8中,如果鏈表的長度超過了8,那么鏈表將轉(zhuǎn)換為紅黑樹。(桶的數(shù)量必須大

于64,小于64的時(shí)候只會(huì)擴(kuò)容)

?發(fā)生hash碰撞時(shí),java1.7會(huì)在鏈表的頭部插入,而java1.8會(huì)在鏈表的尾部插入

?在java1.8中,Entry被Node替代(換了一個(gè)馬甲)。

?JDK7存在死循環(huán)和數(shù)據(jù)丟失問題

?數(shù)據(jù)丟失

?并發(fā)賦值被覆蓋:在createEntry方法中,新添加的元素直接放在頭部,使元素之后

可以被更快訪問,但如果兩個(gè)線程同時(shí)執(zhí)行到此處,會(huì)導(dǎo)致其中一個(gè)線程的賦值被覆蓋。

?已遍歷區(qū)間新增元素丟失:當(dāng)某個(gè)線程在transfer方法遷移時(shí),其他線程新增的元素

可能落在已遍歷過的哈希槽上。遍歷完成后,table數(shù)組引用指向了newTable,新增

元素丟失。

?新表被覆蓋:如果resize完成,執(zhí)行了table=newTable,則后續(xù)元素就可以在新

表上進(jìn)行插入。但如果多線程同時(shí)resize,每個(gè)線程都會(huì)new一個(gè)數(shù)組,這是線程內(nèi)

的局部對象,線程之間不可見。遷移完成后resize的線程會(huì)賦值給table線程共享變

量,可能會(huì)覆蓋其他線程的操作,在新表中插入的對象都會(huì)被丟棄。

?死循環(huán)

?擴(kuò)容時(shí)resize調(diào)用transfer使用頭插法遷移元素,雖然newTable是局部變量,但原

先table中的Entry鏈表是共享的,問題根源是Entry的next指針并發(fā)修改,某線程

還沒有將table設(shè)為newTable時(shí)用完了CPU時(shí)間片,導(dǎo)致數(shù)據(jù)丟失或死循環(huán)。

?JDK8在resize方法中完曲廣容,并改用尾插法,不會(huì)產(chǎn)生死循環(huán),但并發(fā)下仍可能丟

失數(shù)據(jù)。可用ConcurrentHashMap或Collections.synchronizedMap包裝成同步集

合。

?HashMap,LinkedHashMap,TreeMap有什么區(qū)另!J?

?HashMap參考其他問題;

?LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷時(shí),先取到的記錄肯定是先

插入的;遍歷比HashMap慢;

?TreeMap實(shí)現(xiàn)SortMap接口,能夠把它保存的記錄根據(jù)鍵排序(默認(rèn)按鍵值升序排序,

也可以指定排序的比較器)

?HashMap&TreeMap&LinkedHashMap使用場景?

?一般情況下,使用最多的是HashMap。

?HashMap:在Map中插入、刪除和定位元素時(shí);

?TreeMap:在需要按自然順序或自定義順序遍歷鍵的情況下;

?LinkedHashM叩:在需要輸出的順序和輸入的順序相同的情況下。

?HashMap和HashTable有什么區(qū)別?

?①、HashM叩是線程不安全的,HashTable是線程安全的;

?②、由于線程安全,所以HashTable的效率比不上HashMap;

?③、HashMap最多只允許一條記錄的key為null,存放在第0個(gè)位置,允許多條記錄的

值為null,而HashTable不允許;

?④、HashMap默認(rèn)初始化數(shù)組的大小為16,HashTable為11,前者擴(kuò)容時(shí),擴(kuò)大兩倍,

后者擴(kuò)大兩倍+1;

?⑤、HashMap需要重新計(jì)算hash值,而HashTable直接使用對象的hashCode

?HashMap&ConcurrentHashMap的區(qū)另!l?

?除了加鎖,原理上無太大區(qū)別。另外,HashMap的鍵值對允許有null,但是

ConCurrentHashMap都不允許。

?為什么ConcurrentHashMap比HashTable效率要高?

?HashTable使用一把鎖(鎖住整個(gè)鏈表結(jié)構(gòu))處理并發(fā)問題,多個(gè)線程競爭一把鎖,容易

阻塞;

?ConcurrentHashMap

?JDK1.7中使用分段鎖(ReentrantLock+Segment+HashEntry),相當(dāng)于把一個(gè)

HashMap分成多個(gè)段,每段分配一把鎖,這樣支持多線程訪問。鎖粒度:基于Segment,

包含多個(gè)HashEntry.

?JDK1.8中使用CAS+synchronized+Node+紅黑樹。鎖粒度:Node(首結(jié)點(diǎn))(實(shí)

現(xiàn)M叩.Entry<K,V>)。鎖粒度降低了。

?針對ConcurrentHashMap鎖機(jī)制具體分析(JDK1.7VSJDK1.8)?

?JDK1.7中,采用分段鎖的機(jī)制,實(shí)現(xiàn)并發(fā)的更新操作,底層采用數(shù)組+鏈表的存儲(chǔ)結(jié)構(gòu),

包括兩個(gè)核心靜態(tài)內(nèi)部類Segment和HashEntry。

?①、Segment繼承ReentrantLock(重入鎖)用來充當(dāng)鎖的角色,每個(gè)Segment對象

守護(hù)每個(gè)散列映射表的若干個(gè)桶;

.②、HashEntry用來封裝映射表的鍵-值對;

?③、每個(gè)桶是由若干個(gè)HashEntry對象鏈接起來的鏈表

?JDK1.8中,采用Node+CAS+Synchronized來保證并發(fā)安全。取消類Segment,直

接用table數(shù)組存儲(chǔ)鍵值對;

?當(dāng)HashEntry對象組成的鏈表長度超過TREEIFY_THRESHOLD時(shí),鏈表轉(zhuǎn)換為紅黑樹,

提升性能。底層變更為數(shù)組+鏈表+紅黑樹。

?ConcurrentHashMap在JDK1.8中,為什么要使用內(nèi)置鎖synchronized來代替重入鎖

ReentrantLock?

?①、粒度降低了;

?②、JVM開發(fā)團(tuán)隊(duì)沒有放棄synchronized,而且基于JVM的synchronized優(yōu)化空間更

大,更加自然。

?③、在大量的數(shù)據(jù)操作下,對于JVM的內(nèi)存壓力,基于API的ReentrantLock會(huì)開銷更

多的內(nèi)存。

?為什么ConcurrentHashMap的讀操作不需要加鎖?

?jdkl.7中是采用Segment+HashEntry+ReentrantLock的方式進(jìn)行實(shí)現(xiàn)的,而1.8中

放棄了Segment臃腫的設(shè)計(jì),取而代之的是采用Node+

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論