總結(jié)

設(shè)計模式

一.六大設(shè)計原則

1.開閉原則:針對擴展開放写半,修改關(guān)閉;

2.里氏替換原則:任何父類出現(xiàn)的地方都可由其子類進行替換尉咕;

3.依賴倒置原則:依賴于抽象而不是具體叠蝇,面向接口編程;

4.單一職能原則:使用多個隔離的接口年缎,比使用單個接口要好悔捶;

5.迪米特法則:一個類應(yīng)該盡可能少與其他類發(fā)生相互作用,保持系統(tǒng)模塊的相對獨立单芜;

6.合成復(fù)用原則:盡可能使用合成/聚合模式蜕该,而非繼承。

二洲鸠、模式分類

1.創(chuàng)建型模式:單例模式堂淡、工廠方法、抽象工廠扒腕、建造者模式以及原型(clone)模式绢淀;

2.結(jié)構(gòu)型模式:適配器模式、裝飾模式瘾腰、代理模式皆的、橋接模式、外觀模式蹋盆、組合模式祭务、享元模式

3.行為型模式:策略模式内狗,模板方法模式,責(zé)任鏈模式义锥,觀察者模式柳沙,迭代器模式,訪問者模式拌倍,中介器模式赂鲤,解釋器模式,命令模式柱恤,備忘錄模式以及狀態(tài)模式数初。

三、詳細(xì)模式分解

1.工廠方法:對于實現(xiàn)相同接口的一系列類的實例化操作梗顺,包括普通工廠(傳遞工廠值類型字符串)泡孩,多工廠方法(工廠類中提供多個工廠方法)以及靜態(tài)工廠方法(工廠類中方法均為靜態(tài)方法),缺點是類的創(chuàng)建依賴于工廠類寺谤,擴展需要修改工廠類眼俊,違背閉包原則创泄。

2.抽象工廠:解決工廠方法的弊端饭聚,程序的擴展只需要新增新的工廠類秒梳,而不需要修改之前的邏輯法绵。

3.單例模式:保障JVM中只有一個對象的實例存在,省去創(chuàng)建的繁瑣酪碘,降低系統(tǒng)內(nèi)存使用頻率朋譬,減輕GC壓力,保障核心業(yè)務(wù)不紊亂兴垦。(1)構(gòu)造方法私有徙赢;(2)懶加載,延遲加載考慮性能,安全需要做synchronize同步處理;(3)餓漢模式,簡單安全,性能有影響。

4.建造者模式(Builder):將各個產(chǎn)品幾種起來管理,創(chuàng)建復(fù)合對象,而工廠是創(chuàng)建單個產(chǎn)品。

5.原型模式(Prototype):將一個對象作為原型進行克隆匆赃,復(fù)制產(chǎn)生一個與原對象類似的新對象,clone(),深拷貝、淺拷貝。

6.適配器模式:將某個已有類的接口轉(zhuǎn)換為客戶期望的另一個接口表示,消除接口不匹配造成的類兼容問題,分為:

(1)類的適配器模式:創(chuàng)建新類,繼承原類,實現(xiàn)新接口;

(2)對象的適配器模式:創(chuàng)建wrapper類,持有原類,在Warpper類中調(diào)用原類實例的方法執(zhí)行肪康;

(3)接口的適配器模式:創(chuàng)建抽象類Wrapper,實現(xiàn)所有接口方法,再寫別的類時繼承抽象類。

7.裝飾模式:動態(tài)給被裝飾的對象添加額外的功能,通過持有被裝飾對象,重寫相同接口方法,在方法內(nèi)部調(diào)用被裝飾對象同名方法。

8.代理模式:多一個對象出來,替原有對象進行一系列操作,中介、律師。

9.外觀模式:提供一致的統(tǒng)一操作界面,如電腦開機(CPU,內(nèi)存,磁盤Startup方法),Spring的類關(guān)系配置。

10.橋接模式:把視圖與其具體實現(xiàn)分離,抽象化與實現(xiàn)化解耦戚啥,二者可以獨立變化拖云,如JDBC數(shù)據(jù)庫驅(qū)動程序汇荐,數(shù)據(jù)庫的切換不需要修改代碼革娄,通過JDBC橋接即可架忌。

11.組合模式:部分-整體樹形結(jié)構(gòu)問題處理井仰,將多個對象組合一起進行操作合是。

12.享元模式:實現(xiàn)對象的共享,即池化,當(dāng)系統(tǒng)中對象多的時候可以減少內(nèi)存的開銷,通常與工廠模式一起使用。sqlsession鏈接。

13.策略模式:定義一系列的算法失乾,每個算法封裝起來纽竣,可以相互替換穴吹,且算法本身的變化不會影響到使用算法的客戶。計算器,商城打折。

14.模板方法模式:使用一個抽象類,定義算法的骨架流程,而將差別細(xì)節(jié)留給具體的實現(xiàn)類實現(xiàn)。

15.觀察者模式:訂閱發(fā)布模式,一個對象發(fā)生變化時,其他依賴改對象的所有對象都會受到通知,并隨之發(fā)生改變。

16.迭代器模式:順序訪問結(jié)合中的所有元素。

17.責(zé)任鏈模式:每個對象持有下一個對象的引用饥伊,請求在這條鏈上進行傳遞茫因,直到某一對象決定處理改請求洛巢。

18.命令模式:命令模式的目的就是達到命令的發(fā)出者和執(zhí)行者之間解耦漓库,實現(xiàn)請求和執(zhí)行分開良瞧,熟悉Struts的同學(xué)應(yīng)該知道赞庶,Struts其實就是一種將請求和呈現(xiàn)分離的技術(shù)摊册,其中必然涉及命令模式的思想白修。數(shù)據(jù)庫事務(wù)機制的底層實現(xiàn)祖很。

19.備忘錄模式:副本,保存一個對象的狀態(tài),以便在適當(dāng)?shù)臅r候恢復(fù)對象,游戲副本。

20.狀態(tài)模式:當(dāng)對象的狀態(tài)改變時已卸,同時改變其行為。

21.訪問者模式:訪問者模式把數(shù)據(jù)結(jié)構(gòu)和作用于結(jié)構(gòu)上的操作解耦合,使得操作集合可相對自由地演化。

22.中介者模式:中介者模式也是用來降低類類之間的耦合的,因為如果類類之間有依賴關(guān)系的話玉锌,不利于功能的拓展和維護救湖,因為只要修改一個對象邑闺,其它關(guān)聯(lián)的對象都得進行修改靶衍。如果使用中介者模式掏缎,只需關(guān)心和Mediator類的關(guān)系酌儒,具體類類之間的關(guān)系及調(diào)度交給Mediator就行,這有點像spring容器的作用。

23.解釋器模式:

JVM

1.什么時候發(fā)生棧內(nèi)存溢出

· 棧是線程私有的,每個方法的調(diào)用都會產(chǎn)生一個棧幀字管,用來存儲局部變量表政己,操作數(shù)棧沦泌,動態(tài)鏈接以及方法返回值等没咙。

· 當(dāng)線程請求的棧深度大于虛擬機允許的最大深度涡驮,將拋出StackOverflowError異常(方法遞歸)

· 如果Java虛擬機棧嘗試動態(tài)擴展失敗棒口,無法申請足夠的內(nèi)存完成擴展或者新建立線程時沒有足夠的內(nèi)存去創(chuàng)建對應(yīng)的虛擬機棧,將拋出OutOfMemory異常(線程啟動過多)

· 參數(shù)-Xss調(diào)整JVM棧的大小

2.JVM 內(nèi)存模型

[圖片上傳失敗...(image-553b8b-1609729780955)]

image.png

· PC:線程執(zhí)行的字節(jié)碼的行號指示器,線程私有夜只;

· Java虛擬棧:棧幀結(jié)構(gòu),存放基本數(shù)據(jù)類型,對象引用儒搭,方法出口等默穴,線程私有仑氛;

· Native方法棧:與Java虛擬機棧相似遇伞,服務(wù)于Native方法渐排,線程私有可缚;

· Java堆:內(nèi)存最大的一塊,所有對象實例,數(shù)組存放區(qū)域,GC回收的地方榛斯,線程共享;

· 方法區(qū): 存放已經(jīng)被加載的類信息,常量,靜態(tài)變量,JIT熱點代碼焦读。回收目標(biāo)主要是常量池的回收和類型的卸載,線程共享。

3.JVM新生代、老年代、永久帶,新生代為什么分為Eden和Survivor

· 共享內(nèi)存=堆+永久帶

· 永久帶=方法區(qū)+其他

· java堆=老年代+新生帶(2:1通過-XX:NewRatio設(shè)置)

· 新生帶=Eden+S0+S1(8:1:1,通過-XX:SurvivorRatio設(shè)置,Survivor中對象被復(fù)制次數(shù)為15,-XX:MaxTenuringThreshold設(shè)置)

如果沒有Survivor區(qū),Eden每進行一次Minor GC,存活對象被送到老年代,老年代很快填滿,觸發(fā)Major GC啤呼。老年代空間大于新生代惕蹄,進行Full GC消耗比Minor GC大赶促,所以區(qū)分Eden與Survivor。只有經(jīng)歷過16次Minor GC還存活的對象才被送到老年代。兩個Survivor區(qū)的設(shè)置是為了解決內(nèi)存碎片化凸主。

4. Full GC****流程,對象晉升老年代

· 大對象直接進入老年代;

· 對象在Eden出生并存活了年齡次數(shù)(16),則進入老年帶婆咸;

· 當(dāng)老年代滿了無法容納更多的對象乖仇,觸發(fā)Full GC,清理整個內(nèi)存堆警儒,包括年輕代與老年代记劝;

· Major GC是在老年代的GC,清理老年代怒竿,至少伴隨一次Minor GC ,比Minor GC慢10倍以上朦肘。 空間分配擔(dān)保:在觸發(fā)minor GC時,虛擬機檢查老年代最大可用連續(xù)空間是否大于新生代所有對象空間领舰,如果條件成立锉桑,Minor GC確保是安全的攻柠,若老年代判斷到剩余空間不夠微驶,進行一次Full GC。

5. 垃圾回收器凶杖,各自優(yōu)缺點寻咒,重點講下CMS和G1,包括原理叫挟,流程奋献,優(yōu)缺點。

1.幾種垃圾回收器

· Serial收集器:單線程收集器窃这,發(fā)生STW杭攻,使用復(fù)制算法叼架;

· Parnew收集器:Serial收集器的多線程版本,發(fā)生STW,復(fù)制算法;

· Parallel Scavenge收集器:新生代收集器,復(fù)制算法已旧,并發(fā)的多線程收集器檀咙,目標(biāo)是達到一個可控的吞吐量侣诺。

· Serial Old收集器:Serial收集器的老年代版本彼棍,單線程收集器华匾,使用標(biāo)記整理算法旭旭;

· Parallel Old收集器:Parallel Scavenge收集器的老年代版本,使用多線程,標(biāo)記整理算法;

· CMS收集器:獲取最短回收停頓時間為目標(biāo)的收集器粪薛,標(biāo)記清除算法搞莺。運作過程: (1)初始標(biāo)記:只標(biāo)記GC Root直接關(guān)聯(lián)的對象挨摸,發(fā)生STW刨裆,速度快; (2)并發(fā)標(biāo)記:從GC Roots找到它能引用的所有其他對象的過程,可能產(chǎn)生浮動垃圾; (3)重新標(biāo)記:修正并發(fā)標(biāo)記期間因用戶線程繼續(xù)執(zhí)行導(dǎo)致標(biāo)記發(fā)生變動的那部分對象的標(biāo)記記錄布卡,發(fā)生STW庵寞,比初始標(biāo)記耗時将谊,低于并發(fā)標(biāo)記栋齿; (4)并發(fā)清理:

· G1收集器:標(biāo)記整理算法,運作流程:初始標(biāo)記-》并發(fā)標(biāo)記-》最終標(biāo)記-》篩選標(biāo)記,采用標(biāo)記整理算法不產(chǎn)生內(nèi)存空間碎片。

CMS vs G1

· CMS 只收集老年代瓣履,配合新生代的Serial與ParNew使用旷档,G1收集新生代與老年代兄渺,不需要結(jié)合其他收集器

· CMS以最小停頓時間為目標(biāo)瞎饲,G1可預(yù)測垃圾回收的停頓時間;

· CMS采用標(biāo)記清除算法回收垃圾驮捍,容易產(chǎn)生內(nèi)存碎片,G1使用標(biāo)記整理算法,空間整合無內(nèi)存碎片色查。

6.JVM****內(nèi)存模型,重排序,內(nèi)存屏障,happen-before

· 內(nèi)存模型:所有變量存儲于主內(nèi)存丈探,每條線程有獨立的工作線程,線程的工作內(nèi)存中保存了主內(nèi)存的副本,線程對變量的操作必須在工作內(nèi)存中進行爪幻,不能直接操作主內(nèi)存,不同線程之間無法直接訪問對方工作內(nèi)存中的變量篷店,線程間變量的傳遞需要工作內(nèi)存與主內(nèi)存間進行數(shù)據(jù)同步。

· 指令重排序:通過亂序執(zhí)行的技術(shù),處理器大大提高執(zhí)行效率窃爷,這就是指令重排。

· 內(nèi)存屏障:也叫內(nèi)存柵欄逮京,是一種CPU指令览绿,控制特定條件下的重排序與內(nèi)存可見性問題妻导。LoadLoad、LoadStore,StoreStore份名,StoreLoad屏障鲤孵。

7.****類加載器

類加載器就是根據(jù)指定的全限定名稱將class文件加載到JVM內(nèi)存,轉(zhuǎn)為class對象,分為啟動類加載器廊散,擴展類加載器,應(yīng)用程序類加載器缭受,其他類加載器宇智。

· 啟動類加載器:Native方法败明。將JAVA_HOME\lib目錄或-Xbootclasspath指定的路徑中的類加載到內(nèi)存蜒车;

· 擴展類加載器:負(fù)責(zé)加載JAVA_HOME\lib\ext目錄中的所有類;

· 應(yīng)用程序類加載器:負(fù)責(zé)加載用戶類路徑上的指定類庫嬉挡。

雙親委派模型:當(dāng)一個類加載器收到加載類的請求時,先不去嘗試加載颜懊,而是把這個請求委派給父類加載器完成, 每個加載器都是如此,只有父類加載器在自己的搜索范圍內(nèi)找不到指定類時媳维,子類加載器才去嘗試加載。確保了類唯一性唠梨,防止內(nèi)存出現(xiàn)多份同樣的字節(jié)碼盖灸。

打破雙親委派機制:繼承ClassLoader類醉箕,并重寫loadClass和findClass方法姻报。

8.****常用JVM參數(shù)

· 堆棧配置相關(guān):-Xmx,-Xms, -Xmn, -Xss损肛,-XX:MaxPermSize, -XX:NewRatio, -XX:SurvivorRatio,-XX:MaxTenuringThresholdd.

· 垃圾收集器相關(guān):-XX:+UserParallelGC,-XX:ParallelGCThreads=20摩泪,-XX:+UserConcMarkSweepGC,-XX:CMSFullGCsBeforeCompaction,-XX:+UseCMSCompactAtFullCollection

9.JVM****調(diào)優(yōu)工具

[圖片上傳失敗...(image-567be3-1609729780954)]

Spring同波,MyBatis

1. IOC

IOC:控制反轉(zhuǎn)戴尸,將原本在程序中手動創(chuàng)建對象的控制權(quán)交給Spring框架來管理悲雳。IOC容器是Spring用來實現(xiàn)IOC的載體坦胶,本質(zhì)就是一個Map,Map中存放各種對象。將對象的依賴關(guān)系交給IOC容器管理幔翰,由IOC完成對象的注入。

2.AOP:動態(tài)代理

面向切面編程:將那些與業(yè)務(wù)無關(guān)赋访,卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任(如事務(wù)處理渠牲,日志管理,權(quán)限控制)封裝起來铣除,減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度。

3.Spring****中bean的作用域

· singleton:唯一bean實例泽铛,Spring中bean默認(rèn)都是單例;

· prototype:每次請求創(chuàng)建一個新的bean實例;

· request:每一次HTTP請求創(chuàng)建一個新的bean撵幽,僅在當(dāng)前HTTP request塊內(nèi)有效;

· session:每一次HTTP請求產(chǎn)生一個新的bean, 僅在當(dāng)前HTTP session內(nèi)有效;

· global-session:全局session作用域强衡。

4.Bean****的生命周期

[圖片上傳失敗...(image-c62a37-1609729780954)]

image.png

配置文件中定義Bean-》反射實例化bean對象-》設(shè)置對象屬性-》檢查Aware相關(guān)接口并設(shè)置相關(guān)依賴-》BeanPostProcessor前置處理-》檢查是否是InitializingBean決定是否調(diào)用afterPropertiesSet方法-》檢查是否配置有自定義的init-method-》BeanPostProcessor后置處理-》注冊必要的Destruction相關(guān)回調(diào)接口-》使用bean-》是否實現(xiàn)DisposableBean接口-》是否配置有自定義的destory方法。

5.Spring MVC****的工作原理

[圖片上傳失敗...(image-4b2484-1609729780954)]

image.png

(1). 前端瀏覽器request請求url;
(2). 在處理器映射器(HandlerMapping)中請求查找handler触幼; (3).返回一個執(zhí)行鏈; (4).請求適配器執(zhí)行Handler; (5).Handler適配器調(diào)用Handler處理器執(zhí)行請求方法 (6).返回ModelAndView給處理器適配器;
(7).返回ModelAndView給前端控制器丝蹭; (8).前端控制器向視圖解析器請求進行視圖解析; (9).視圖解析器返回View給前端控制器 (10).視圖渲染,將模型數(shù)據(jù)填充到request域男摧; (11).response響應(yīng)瀏覽器。

6.Spring 框架中使用的設(shè)計模式

· 工廠設(shè)計模式:Spring使用工廠模式,通過BeanFactory與ApplicationContext創(chuàng)建bean對象竿刁;

· 代理設(shè)計模式:AOP實現(xiàn)使用動態(tài)代理;

· 單例設(shè)計模式:Spring的bean默認(rèn)都是單例的;

· 模板方法模式:Spring中的jdbcTemplate,hibernateTemplate等以Template結(jié)尾的對數(shù)據(jù)庫操作的類使用模板方法煮盼;

· 觀察者模式:Spring事件驅(qū)動模型就是觀察者模式的經(jīng)典應(yīng)用;

· 適配器模式: Spring AOP的增強或者通知Advice使用了適配器模式。Controller適配器查找也使用了千绪。

7.Spring****的事務(wù)傳播行為

支持事務(wù)情況

· PROPAGATION_REQUIRED:如果存在當(dāng)前事務(wù),則加入該事務(wù)瑞妇;如果沒有事務(wù),創(chuàng)建一個;

· PROPAGATION_SUPPORTS:如果存在當(dāng)前事務(wù)偶翅,則加入該事務(wù);如果沒有事務(wù),以非事務(wù)方式繼續(xù)運行骤宣;

· PROPAGATION_MANDATORY:如果存在當(dāng)前事務(wù),則加入該事務(wù)望门;如果當(dāng)前沒有事務(wù),則拋出異常;

不支持事務(wù)的情況

· PROPAGATION_REQUIRES_NEW :創(chuàng)建一個新的事務(wù)祷膳,如果當(dāng)前存在事務(wù)膨俐,則把當(dāng)前事務(wù)掛起儒士;
· PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式運行拖叙,如果存在當(dāng)前事務(wù),則把當(dāng)前事務(wù)掛起;
. PROPAGATION_NEVER:以非事務(wù)方式運行,如果當(dāng)前存在事務(wù)乳幸,則拋出異常;

其他情況

· PROPAGATION_NESTED :如果當(dāng)前存在事務(wù),則創(chuàng)建一個事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)運行;如果沒有事務(wù)寄锐,則該取值等價于PROPAGATION_REQUIRED。

8. Spring****注入方式

Spring通過DI(依賴注入)實現(xiàn)IOC(控制反轉(zhuǎn)),常用的注入方式主要有三種:構(gòu)造方法注入奠涌,setter注入,基于注解的注入怠晴。

9. Spring****事務(wù)的實現(xiàn)方式

· 使用TransactionTemplate事務(wù)模板對象

· 使用事務(wù)管理器PlatformTransactionManager對象

· 基于Aspectj AOP開啟事務(wù)

· 基于注解@Transactional聲明式事務(wù)管理

WEB

一物邑、轉(zhuǎn)發(fā)與重定向

轉(zhuǎn)發(fā)是服務(wù)器行為,重定向是客戶端行為

· 轉(zhuǎn)發(fā)在服務(wù)器端完成的;重定向是在客戶端完成的

· 轉(zhuǎn)發(fā)的速度快;重定向速度慢

· 轉(zhuǎn)發(fā)的是同一次請求;重定向是兩次不同請求

· 轉(zhuǎn)發(fā)不會執(zhí)行轉(zhuǎn)發(fā)后的代碼;重定向會執(zhí)行重定向之后的代碼

· 轉(zhuǎn)發(fā)地址欄沒有變化;重定向地址欄有變化

· 轉(zhuǎn)發(fā)必須是在同一臺服務(wù)器下完成;重定向可以在不同的服務(wù)器下完成

二科阎、GET和POST兩種基本請求方法的區(qū)別

· GET請求在URL中傳送的參數(shù)是有長度限制的错英,而POST沒有判哥。

· GET比POST更不安全,因為參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息剿吻。

· GET參數(shù)通過URL傳遞榄笙,POST放在Request body中巨朦。

· GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會被保留梭依。

· GET請求只能進行url編碼,而POST支持多種編碼方式典尾。

· GET請求會被瀏覽器主動cache役拴,而POST不會,除非手動設(shè)置扎狱。

· GET在瀏覽器回退時是無害的汞贸,而POST會再次提交請求奶是。

· GET****將header和data一并發(fā)送,POST分開發(fā)送,先發(fā)送header得到100響應(yīng)再發(fā)送data部分

Java多線程

1. ThreadLocal簡介

ThreadLocal線程變量芍殖,ThreadLocal中填充的變量屬于當(dāng)前線程计贰,該變量對于別的線程是隔離的。ThreadLocal為變量在每個線程中都創(chuàng)建了一個副本呛踊,每個線程訪問自己內(nèi)部的副本變量劫乱。

使用場景

· 進行對象跨層傳遞時候,使用ThreadLocal可以避免多次傳遞,打破層次間的約束嫡纠;

· 線程間數(shù)據(jù)隔離;

· 進行事務(wù)處理,用于存儲線程事務(wù)信息突想;

· 數(shù)據(jù)庫連接橘茉,Session會話管理歼争。

ThreadLocal注意點

  1. Thread中有一個map,就是ThreadLocalMap;

  2. ThreadLocalMap的key就是ThreadLocal,值是我們自己設(shè)定的取刃;

  3. ThreadLocal是一個弱引用啦膜,當(dāng)為null時涯塔,會被當(dāng)成垃圾回收;

  4. 當(dāng)ThreadLocal為null時凉袱,需要被垃圾回收篓叶,單此時ThreadLocalMap的生命周期與Thread一樣叼风,不會回收彬碱,就會導(dǎo)致內(nèi)存泄露忿檩,解決方法是使用完ThreadLocal后執(zhí)行remove操作,避免出現(xiàn)內(nèi)存溢出情況凑阶。

2.Volatile

為了確保多個線程之間對內(nèi)存寫入操作的可見性,用volatile修飾變量湿刽,告訴編譯器以及運行時該變量是共享的仁烹,通過“禁止指令重排序”保證其線程間的可見性扶歪。比synchronized更輕量級的同步機制,普通變量會被拷貝到CPU緩存岛宦,而volatile修飾的變量設(shè)置了內(nèi)存屏障,保證每次都是從內(nèi)存中讀徘熔。

· 保證變量對所有線程的可見性台谊;

· 禁止指令重排序優(yōu)化阶冈。

volatile 的讀性能消耗與普通變量幾乎相同,但是寫操作稍慢骏庸,因為它需要在本地代碼中插入許多內(nèi)存屏障指令來保證處理器不發(fā)生亂序執(zhí)行艾栋。

3.synchronized

解決Java并發(fā)問題的常用方法睁蕾,可重入寥枝,避免死鎖霉赡。底層使用monitor對象完成, MonitorEnter與MonitorExit指令结窘,主要的作用包括:

· 原子性:確保線程互斥的訪問同步代碼仑撞;

· 可見性:保證共享變量的修改能及時可見;

· 有序性:有效解決重排序問題读虏。

用法

· 作用實例方法姜挺,監(jiān)視器鎖是對象實例(this);

· 作用靜態(tài)方法腰涧,監(jiān)視器鎖是對象的Class實例颠猴,相當(dāng)于類的全局鎖;

· 作用在某一個對象實例,監(jiān)視器鎖是括號括起來的對象實例。

4. 鎖優(yōu)化

增加自適應(yīng)的CAS自旋鎖,鎖消除,鎖粗化猾愿,偏向鎖以及輕量級鎖等優(yōu)化策略提升性能松嘶,鎖的狀態(tài)有四種:無鎖狀態(tài)01巩踏,偏向鎖狀態(tài)0构哺,輕量級鎖狀態(tài)00以及重量級鎖狀態(tài)10枢析。

· 自旋鎖: 當(dāng)一個線程嘗試獲取某個鎖時,如果該鎖已經(jīng)被其他線程占用页慷,就循環(huán)檢測鎖是否釋放,而不是進入線程掛起或者睡眠狀態(tài)。避免了線程切換帶來的開銷萍肆,但是占用了CPU時間厨疙,如果長時間未釋放鎖虫溜,自旋的線程就浪費CPU,設(shè)置自旋次數(shù)優(yōu)化。

· 適應(yīng)性自選鎖:jdk1.6引入突照,自旋的次數(shù)不固定益缎,由前一次在同一個鎖上的自旋時間以及鎖的擁有狀態(tài)來決定典予。

· 鎖消除:為了數(shù)據(jù)完整性,在操作數(shù)據(jù)時對這部分操作做同步控制岛马,但是當(dāng)JVM檢測到不可能存在共享數(shù)據(jù)競爭時枫吧,JVM會對這些同步鎖進行鎖消除坞古。鎖消除的依據(jù)是逃逸分析的數(shù)據(jù)支持疏旨。

· 鎖粗化:將多個連續(xù)的加鎖暴氏,解鎖操作連接在一起敬拓,擴展成為范圍更大的鎖。

· 偏向鎖:為了在線程交替執(zhí)行同步塊時提高性能耍共,在只有一個線程執(zhí)行同步塊時提升性能,單線程執(zhí)行代碼塊時使用的機制崖面,在多線程并發(fā)環(huán)境下,轉(zhuǎn)換為輕量級鎖或者重量級鎖。

· 輕量級鎖:在沒有多線程競爭的前提下,減少傳統(tǒng)的重要級鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗懊亡。

· 重量級鎖:依賴于操作系統(tǒng)Mutex Lock所實現(xiàn)的鎖稱之為重量級鎖,實現(xiàn)線程間的切換需要從用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài)。這也是synchronized效率低下的原因。

[圖片上傳失敗...(image-ed90f-1609729780952)]

5. 悲觀鎖與樂觀鎖

樂觀鎖:每次操作不加鎖猜嘱,假設(shè)沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功汉买,使用volatile+CAS原語實現(xiàn); 悲觀鎖:導(dǎo)致其他需要鎖的線程掛起,等待鎖的持有線程釋放鎖,使用synchronized和Lock實現(xiàn)。

6. synchronized與Lock區(qū)別

· lock必須在finally釋放蹂析,否則如果異常展融,鎖可能永遠不會釋放闽瓢,而synchronized在發(fā)生異常時JVM確保鎖自動釋放;

· synchronized代碼塊無法控制進入同步塊線程的先后順序竖独;

· synchronized塊必須完整包含在單個函數(shù),而lock對象的lock()與unlock()方法調(diào)用可以放在不同方法里。

7. 線程同步的幾種方式

· synchronized修飾

· volatile實現(xiàn)同步(無法保證原子性涣澡,不安全)

· ThreadLocal

· 原子類:AtomicInteger,AtomicBoolean等

· 使用Lock

· 使用容器類(BlockQueue, ConcurrentHashMap)

8.死鎖條件

· 互斥條件:資源是獨占且排他使用辑舷;

· 不可剝奪條件:進程獲得的資源在未使用完畢之前不能被其他進程強行剝奪;

· 請求保持:進程每次申請所需要的一部分資源刚陡,在申請新的資源時惩妇,繼續(xù)占有已分配的資源株汉。

· 循環(huán)等待:在發(fā)生死鎖時由依賴環(huán)。

9 notify和notifyAll

notify()方法無法喚醒某個具體的線程歌殃,所以只適應(yīng)于單線程等待乔妈。而notifyALL()喚醒所有線程并允許他們爭奪鎖,確保至少有一個線程能繼續(xù)氓皱。

10.wait與sleep差別

· 使用限制:都需要放在synchronized代碼塊路召,sleep方法讓當(dāng)前線程休眠,時間到了自動恢復(fù)波材,wait必須調(diào)用notify/notifyAll()喚醒股淡;

· 使用場景:sleep用于當(dāng)前線程休眠,wait多用于多線程間通信廷区;

· 所屬類:sleep是Thread的靜態(tài)類唯灵,wait()是Object類本地方法

· 釋放鎖:sleep不會釋放鎖,wait釋放當(dāng)前線程對鎖的持有隙轻;

· 線程切換:sleep會讓出CPU執(zhí)行時間強制切換上下文埠帕,wait不會。

11.SynchronizedMap與ConcurrentHashMap區(qū)別

SynchronizedMap和HashTable一樣,調(diào)用map的方法時鎖定整個Map,其他線程無法對map再做操作了河哑;而ConcurrentHashMap實現(xiàn)更為精細(xì)化的鎖定,采用Node+Synchronized+CAS實現(xiàn)桶的精細(xì)化控制呐籽,一個線程訪問Map的某個桶時,其他線程仍然可對map執(zhí)行其他操作蚀瘸。

12.CopyOnWriteArrayList

讀寫分離狡蝶,讀時不加鎖,寫時先拷貝一份苍姜,實現(xiàn)新舊版本分離牢酵,然后在拷貝的版本上進行修改操作,修改完成后再更新到舊版本中衙猪,避免頻繁讀時鎖定整個數(shù)據(jù)。

13.并發(fā)類CountDownLatch布近、Semaphore和CyclicBarrier

· CountDownLatch:計數(shù)器閉鎖垫释,阻塞當(dāng)前線程,一個或多個線程一致等待撑瞧,直到其他線程執(zhí)行的操作完成棵譬;

· Semaphore:與CountDownLatch類似,不同的是Semaphore的值被獲取后是可以釋放的预伺,用來限制流量订咸,限制資源最多被N個線程訪問曼尊,超過N個不允許再有線程訪問,使用資源的線程結(jié)束后釋放才允許新線程進來脏嚷;

· CyclicBarrier:同步輔助類骆撇,允許一組線程相互等待,直到到達某個公共屏障點;

14.CAS

CAS是樂觀鎖技術(shù)父叙,多個線程嘗試 使用CAS更新變量時神郊,只有一個線程能更新成功,其余線程都失敗趾唱,失敗的線程不會掛起涌乳,而會去重試。其實現(xiàn)原理是通過內(nèi)存位置(V)甜癞、預(yù)期原值(A)與新值(B)夕晓。如果內(nèi)存位置的值與預(yù)期原值匹配,處理器自動將該位置更新為新值悠咱,否則不做處理运授,返回V值。

· ABA問題:兩個線程同時讀取A乔煞,線程1取出A吁朦,線程2取出A后操作變成B,再操作變成A渡贾,線程1操作CAS發(fā)現(xiàn)仍然是A逗宜,操作成功。解決ABA問題空骚,每次比較數(shù)據(jù)的值與版本號纺讲。

15.讀寫鎖ReentrantReadWriteLock

面對多線程環(huán)境下,數(shù)據(jù)讀寫不一致的問題囤屹,采用不同的讀寫鎖機制:讀讀不互斥熬甚,讀寫互斥,寫寫互斥肋坚,ReentrantReadWriteLock允許多個讀線程獲取讀鎖乡括,但只允許一個寫線程獲取寫鎖。

16.進程智厌,線程诲泌,協(xié)程

進程:程序在一個數(shù)據(jù)集中的一次動態(tài)執(zhí)行過程,是CPU資源分配與調(diào)度的獨立單位铣鹏,由程序敷扫,數(shù)據(jù)集,進程控制塊組成诚卸。 線程:輕量級進程葵第,CPU的基本執(zhí)行單元绘迁,由線程ID,PC卒密,寄存器集合以及堆棧共同組成缀台,一個進程包含多個線程。 協(xié)程:用戶態(tài)的輕量級線程栅受,微線程将硝,協(xié)程的調(diào)度完全由用戶控制。通過yield轉(zhuǎn)移執(zhí)行權(quán)屏镊,與多線程對比依疼,其優(yōu)勢在于:(1)協(xié)程執(zhí)行效率高,不需要進行線程切換而芥;(2)不需要多線程鎖機制律罢,共享資源不加鎖,通過判斷狀態(tài)棍丐。

17. 線程轉(zhuǎn)態(tài)轉(zhuǎn)移

[圖片上傳失敗...(image-70834c-1609729780949)]

· 新建態(tài):調(diào)用start進入就緒態(tài)

· 就緒態(tài):獲得時間片進入運行態(tài)

· 運行態(tài):(1)運行任務(wù)結(jié)束進入死亡態(tài)误辑;(2)調(diào)用sleep,join,等待用戶輸入進入阻塞態(tài);(3)沒有獲取synchronized鎖歌逢,進入鎖池隊列巾钉;(4)調(diào)用wait方法,釋放鎖秘案,進入等待隊列

· 阻塞態(tài):sleep結(jié)束砰苍,join完成,或者用戶輸入完成進入就緒態(tài)

· 等待隊列:鎖對象調(diào)用notify/notifyAll通知線程進入鎖池隊列

· 鎖池隊列:獲得鎖阱高,進入就緒狀態(tài)

· 死亡態(tài):run()方法運行結(jié)束

18.線程池中submit()和execute()方法有什么區(qū)別

· execute() 參數(shù) Runnable 赚导;submit() 參數(shù) (Runnable) 或 (Runnable 和 結(jié)果 T) 或 (Callable)

· execute() 沒有返回值;而 submit() 有返回值

· submit() 的返回值 Future 調(diào)用get方法時赤惊,可以捕獲處理異常

19.****常見線程池

newFixedThreadPool:創(chuàng)建一個固定線程數(shù)的線程池 newSingleThreadExecutor:創(chuàng)建只有1個線程的線程池 newCachedThreadPool:返回一個可根據(jù)實際情況調(diào)整線程個數(shù)的線程池吼旧,不限制最大線程 數(shù)量,若用空閑的線程則執(zhí)行任務(wù)未舟,若無任務(wù)則不創(chuàng)建線程圈暗。并且每一個空閑線程會在60秒 后自動回收。 newScheduledThreadPool: 創(chuàng)建一個可以指定線程的數(shù)量的線程池处面,但是這個線程池還帶有 延遲和周期性執(zhí)行任務(wù)的功能厂置,類似定時器。 newSingleScheduledThreadPool: 創(chuàng)建一個單線程的線程池魂角,具備延遲和周期性執(zhí)行任務(wù)的功能。 ForkJoinPool:線程池中每個線程都有自己獨立的任務(wù)隊列智绸,常適合用于遞歸的場景野揪,例如樹的遍歷访忿、最優(yōu)路徑搜索等場景.

[圖片上傳失敗...(image-b2e253-1609729780949)]

image.png

20.****線程池常見拒絕策略

· ThreadPoolExecutor.AbortPolicy:丟棄任務(wù)并拋出RejectedExecutionException異常。

· ThreadPoolExecutor.DiscardPolicy:丟棄任務(wù)斯稳,但是不拋出異常海铆。

· ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務(wù),然后重新提交被拒絕的任務(wù) .

· ThreadPoolExecutor.CallerRunsPolicy:由調(diào)用線程(提交任務(wù)的線程)處理該任務(wù)

RabbitMQ

一挣惰、什么是RabbitMQ,有什么優(yōu)缺點卧斟?

RabbitMQ是一款開源的基于AMQP協(xié)議的消息中間件,可以用來解耦憎茂,異步以及削峰珍语。

優(yōu)點 1.解耦:系統(tǒng)間通過消息通信,不用關(guān)心其他系統(tǒng)的處理 2.削峰:可以通過消息隊列長度控制請求量竖幔;可以緩解短時間內(nèi)的高并發(fā)請求 3.異步:相比于傳統(tǒng)的串行板乙、并行方式,提高了系統(tǒng)吞吐量

缺點 1.降低了系統(tǒng)的穩(wěn)定性拳氢,消息系統(tǒng)掛掉會導(dǎo)致系統(tǒng)不可用募逞; 2.增加系統(tǒng)的復(fù)雜性:消息隊列加入考慮一致性問題,消息重復(fù)消費馋评,如何保障消息可靠傳輸?shù)取?/p>

考慮集群以及主從等模式保障RabbitMQ的高可用

二放接、如何保證RabbitMQ不被重復(fù)消費。

正常情況下留特,消費者在消費消息完后發(fā)送一個確認(rèn)消息給消息隊列纠脾,消息隊列再將消息從隊列中刪除。但因為網(wǎng)絡(luò)傳輸?shù)裙收峡某樱_認(rèn)消息沒有傳輸?shù)较㈥犃腥槲冢瑢?dǎo)致消息隊列不知道消息已經(jīng)被消費,再次將消息分發(fā)給其他消費者市咆。 針對上述問題汉操,解決思路是保證消息的唯一性,就算多次傳輸蒙兰,不要讓消息的多次消費帶來影響磷瘤,保證消息等冪性,如在寫入消息隊列的數(shù)據(jù)做唯一標(biāo)識搜变,消費消息時采缚,根據(jù)唯一標(biāo)識來判斷消息是否被消費過。

三挠他、如何保證RabbitMQ消息的可靠傳輸

消息不可靠的情況可能是消息丟失扳抽,消息劫持等。丟失又分為生產(chǎn)者丟失消息,消息列表丟失消息贸呢,消費者丟失消息镰烧。

  1. 生產(chǎn)者丟失消息:RabbitMQ提供了transaction與confirm模式確保生產(chǎn)者不丟消息。

· transaction機制就是消息發(fā)送前楞陷,開啟事務(wù)怔鳖,然后發(fā)送消息,如果發(fā)送過程中出現(xiàn)異常固蛾,回滾事務(wù)结执,如果發(fā)送成功就提交事務(wù),這種模式可能會導(dǎo)致吞吐量下降艾凯。

· confirm模式用的更多献幔,通過ACK確認(rèn)+重發(fā)消息保障。

  1. 消息隊列丟消息:消息持久化览芳。將消息持久化到磁盤斜姥,再給生產(chǎn)者發(fā)送ACK信號。

  2. 消費者丟失消息:消費者丟數(shù)據(jù)一般是因為采用了自動確認(rèn)消息模式沧竟,改為手動確認(rèn)消息即可铸敏。當(dāng)消息處理成功后,手動回復(fù)確認(rèn)消息悟泵。

四杈笔、如何保證RabbitMQ消息的順序性?

單線程消費保證消息的順序性糕非;對消息進行編號蒙具,消費者處理消息是根據(jù)編號處理消息;

Redis知識點

一朽肥、支持的數(shù)據(jù)類型5類

redis利用隊列技術(shù)將并發(fā)訪問變?yōu)榇性L問禁筏,消除了傳統(tǒng)數(shù)據(jù)庫串行控制的開銷

. String字符串,底層是SDS(Simple Dynamic String)衡招,動態(tài)擴容的簡單字符串篱昔,類似于Java的ArrayList。

· 預(yù)分配冗余空間:預(yù)分配冗余空間的方式減少內(nèi)存的頻繁分配始腾,小于1MB州刽,加倍擴容,超過1MB時浪箭,每次擴容1MB穗椅,最大512MB奶栖。

· 惰性空間釋放:惰性空間釋放匹表,當(dāng)需要縮短SDS保存的字符串時门坷,程序不立即使用內(nèi)存重分配來回收縮短后多出來的字節(jié),而是用free成員將這些字節(jié)記錄下來等待將來使用桑孩。

. Hash:哈希
. List:列表
. Set:集合
. ZSet:有序集合,支持ziplist以及skiplist兩種編碼拜鹤。

· ziplist:滿足元素小于128個并且所有member長度小于64字節(jié)框冀。使用緊挨在一起的壓縮列表節(jié)點來保存流椒,第一個節(jié)點保存member,第二個保存score明也,ziplist的集合元素按score排序宣虾,實質(zhì)上是雙向鏈表。

內(nèi)存結(jié)構(gòu):

[圖片上傳失敗...(image-927762-1609729780948)]

image.png

(1).zlbytes:存儲壓縮列表占用字節(jié)温数,重新分配內(nèi)存時使用绣硝,不用遍歷列表計算占用內(nèi)存大小撑刺; (2).zltail:表示ziplist表中最后一項在ziplist中的偏移位置鹉胖,方便定位到尾節(jié)點。 (3).zllen:ziplist包含的節(jié)點個數(shù)够傍,2個字節(jié)長度甫菠。 (4).entry:menber,存儲的數(shù)據(jù)項 (5).zlend:結(jié)束標(biāo)識冕屯,一字節(jié)固定值寂诱,255.

skiplist(重點考察):字典+跳表,不滿足ziplist條件都使用skiplist安聘。查找時間復(fù)雜度平均為log(N),最差為O(N),基本等效于平衡樹痰洒,但比平衡樹實現(xiàn)簡單。

跳表的特點

(1). 由許多層結(jié)構(gòu)組成浴韭; (2).每一層都是一個有序的鏈表丘喻; (3).最底層包含所有的元素; (4).如果一個元素在Level i的列表中出現(xiàn)念颈,則它在Level i之下的鏈表都會出現(xiàn)泉粉; (5).每個節(jié)點包含2個指針,一個指向同鏈表的下一個元素舍肠,另一個指向下面一層的元素搀继。

查找過程:

  1. 從鏈表頭部元素開始,遍歷鏈表翠语,直到找到元素大于或等于目標(biāo)元素的節(jié)點叽躯,如果當(dāng)前元素正好等于目標(biāo),直接返回它肌括;

  2. 如果當(dāng)前元素小于目標(biāo)元素点骑,垂直下降到下一層繼續(xù)搜索酣难;

  3. 如果當(dāng)前元素大于目標(biāo)或已經(jīng)達到鏈表尾部,則移動到前一個節(jié)點位置黑滴,再垂直下降到下一層憨募。

二、Redis持久化

持久化就是把內(nèi)存的數(shù)據(jù)寫到磁盤袁辈,防止服務(wù)器宕機內(nèi)存數(shù)據(jù)丟失菜谣。Redis提供2種持久化方式RDB和AOF。

RDB:

即redis database晚缩,功能核心函數(shù)rdbSave (生成RDB文件)和rdbLoad(從文件加載到內(nèi)存)

AOF:

Append-Only file,每次執(zhí)行服務(wù)器定時任務(wù)或者函數(shù)時flushAppendOnlyFile函數(shù)都會被調(diào)用尾膊,執(zhí)行2個工作,WRITE:根據(jù)條件將aof_buf中的緩存寫入到AOF文件荞彼;SAVE:根據(jù)條件調(diào)用fsync函數(shù)冈敛,將AOF文件保存在磁盤里。使用redis持久化協(xié)議RESP格式的命令存儲文本鸣皂。

RDB vs AOF

優(yōu)點:RDB文件緊湊抓谴,體積小,網(wǎng)絡(luò)傳輸快寞缝,適合全量復(fù)制癌压;恢復(fù)速度比AOF快很多。當(dāng)然第租,與AOF相比措拇,RDB最重要的優(yōu)點之一是對性能的影響相對較小。

缺點:RDB文件的致命缺點在于其數(shù)據(jù)快照的持久化方式?jīng)Q定了必然做不到實時持久化慎宾,而在數(shù)據(jù)越來越重要的今天丐吓,數(shù)據(jù)的大量丟失很多時候是無法接受的,因此AOF持久化成為主流趟据。此外券犁,RDB文件需要滿足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)汹碱。

  1. aof文件比rdb更新頻率高粘衬,優(yōu)先使用aof還原數(shù)據(jù)。

  2. aof比rdb更安全也更大咳促;

  3. rdb性能比aof好稚新;

  4. 優(yōu)先加載aof;

  5. 恢復(fù)難度aof高跪腹。

三褂删、Redis的淘汰策略

· noeviction:不刪除策略,達到最大內(nèi)存限制后冲茸,直接返回錯誤信息屯阀;

· allkeys-lru:優(yōu)先刪除最少使用的key;

· volatile-lru:只限于設(shè)置了expire的部分缅帘,優(yōu)先刪除最近最少使用的key;

· allkeys-random:隨機刪除一部分key;

· volatile-random:只限于設(shè)置了expire的部分,隨機刪除一部分key;

· volatile-ttl:只限于設(shè)置了expire的部分难衰,優(yōu)先刪除剩余時間短的key钦无。

四、Redis的并發(fā)競爭

單進程單線程模式盖袭,采用隊列模式將并行訪問變?yōu)榇性L問失暂。Redis本身沒有鎖概念,對于多個客戶端連接不存在競爭苍凛,利用setnx實現(xiàn)鎖趣席,并設(shè)置expire過期釋放鎖。

五. Redis單線程為什么這么快

  1. 完全基于內(nèi)存醇蝴,純粹的內(nèi)存操作非常迅速;

  2. 數(shù)據(jù)結(jié)構(gòu)簡單;

  3. 采用單線程,避免了不必要的上下文切換與競爭條件酣胀,不用考慮鎖的問題拟枚;

  4. 采用多路I/O復(fù)用模型,多個網(wǎng)絡(luò)連接使用一個線程處理拍摇。

  5. Redis自己構(gòu)建了VM機制。

六、Redis緩存被擊穿處理機制

使用mutex,當(dāng)緩存失效時癞志,不立即load db,SETNX去set一個mutex key,當(dāng)操作返回成功時在進行l(wèi)oad db操作并回設(shè)緩存框产,否則重試整個get緩存的方法凄杯。

七、Redis緩存穿透秉宿,緩存擊穿戒突,緩存雪崩

緩存穿透:key對應(yīng)的數(shù)據(jù)再數(shù)據(jù)源并不存在,每次針對此key的請求從緩存中獲取不到描睦,請求數(shù)據(jù)源膊存,就有可能壓垮數(shù)據(jù)源。 有效的解決方法包括:(1)為空值設(shè)置緩存忱叭;(2)使用布隆過濾器進行過濾. 緩存擊穿:key對應(yīng)的數(shù)據(jù)存在隔崎,但在redis中過期了,若此時大量并發(fā)請求過來韵丑,發(fā)現(xiàn)緩存過期后從后端數(shù)據(jù)源加載數(shù)據(jù)并回設(shè)緩存爵卒,此時大并發(fā)的請求可能壓垮數(shù)據(jù)源。 有效的解決辦法:使用互斥鎖mutex key埂息。 緩存雪崩:當(dāng)緩存服務(wù)器重啟或者大量緩存集中在某一個時間段失效技潘,會給后端數(shù)據(jù)源很大的壓力遥巴。 有效解決辦法:(1)用加鎖或者隊列的方式來保證不會有大量的線程對數(shù)據(jù)庫一次性進行讀寫,從而避免失效時大量的并發(fā)請求落到底層存儲系統(tǒng)上享幽。(2)緩存失效時間分散開值桩,為不同的key設(shè)置不同的過期時間。

八奔坟、Redis主從模型

典型的分布式讀寫模型咳秉,利用master插入數(shù)據(jù)婉支,slave提供檢索服務(wù)向挖,有效減少單個機器的并發(fā)訪問數(shù)量何之。原則:Master會將數(shù)據(jù)同步到slave溶推,而slave不會同步到master,Slave啟動時會鏈接master同步數(shù)據(jù)舰褪。 通過增加slave DB數(shù)量線性提高讀性能占拍;使用MasterDB雙機熱備避免Master單點故障。 缺陷:所有節(jié)點服務(wù)器都保存完整的數(shù)據(jù)贝次,數(shù)據(jù)量大的情況下敲茄,集群的擴展能力受限于單節(jié)點存儲能力堰燎,對于寫敏感的應(yīng)用秆剪,讀寫分離架構(gòu)不合適。解決洁灵,考慮數(shù)據(jù)分片处渣。

九黍衙、Redis架構(gòu)模式

https://www.cnblogs.com/jasontec/p/9699242.html
1.****單機模式

[圖片上傳失敗...(image-ac47be-1609729780947)]

image.png

特點

· 簡單

缺點

· 內(nèi)存容量有限

· 處理能力有限

· 無高可用

2.****主從復(fù)制(讀寫分離)

允許用戶創(chuàng)建多個Redis服務(wù)器的副本琅翻,Master和Slave方椎,將Master節(jié)點數(shù)據(jù)同步給Slave棠众,Slave擴展使得讀性能線性提升空盼。

[圖片上傳失敗...(image-6a5efd-1609729780947)]

image.png

特點

· Master/Slave角色

· Master/Slave數(shù)據(jù)相同

· 降低從Master讀壓力揽趾,轉(zhuǎn)交給Slave

缺點

· 沒有解決master寫壓力

· 無高可用

3.****哨兵

[圖片上傳失敗...(image-d5988e-1609729780947)]

image.png

Redis sentinel 是一個分布式系統(tǒng)中監(jiān)控 redis 主從服務(wù)器苟呐,并在主服務(wù)器下線時自動進行故障轉(zhuǎn)移。其中包含三個特性:(1)監(jiān)控:Sentinel不斷檢查主從服務(wù)器是否運作正常两波;(2)當(dāng)被監(jiān)控的Redis服務(wù)器出現(xiàn)問題是,Sentinel通過API發(fā)送通知劣坊;(3)自動故障遷移,當(dāng)一個主服務(wù)器不能正常工作是康二,Sentinel會開始一次自動故障遷移操作。

特點

· 保證高可用

· 監(jiān)控各個節(jié)點

· 自動故障遷移

缺點

  1. 仍是主從模式产雹,切換需要時間,丟數(shù)據(jù)

  2. 沒有解決master寫的壓力

4.****集群(proxy)

[圖片上傳失敗...(image-5eb5e1-1609729780947)]

image.png

多主從模式瘟判,實現(xiàn)數(shù)據(jù)分片,通過代理服務(wù)器將數(shù)據(jù)分片到不同的Redis主從集群刀诬,每個Redis集群單獨有Sentinel哨兵監(jiān)控质欲。發(fā)生故障時,故障的Redis集群自動下線九昧。缺點是:

· failover邏輯需要自己實現(xiàn),不支持故障自動轉(zhuǎn)移蹋笼,可擴展性差,進行擴縮容都需要手動干預(yù)逊谋。

5.****集群(直連)

[圖片上傳失敗...(image-abf9d1-1609729780947)]

image.png

redis3.0之后支持redis-cluster集群,采用無中心結(jié)構(gòu),每個節(jié)點保存數(shù)據(jù)與整個集群狀態(tài),每個節(jié)點與其他節(jié)點相互連接探遵。

特點

· 無中心架構(gòu),少了proxy層

· 數(shù)據(jù)按照slot存儲分布在多個節(jié)點藏雏,節(jié)點間數(shù)據(jù)共享赚瘦,可動態(tài)調(diào)整數(shù)據(jù)分布

· 可擴展性,支持節(jié)點動態(tài)添加與刪除

· 高可用揽咕,部分節(jié)點不可用,集群仍可用

· 實現(xiàn)自動故障failover,節(jié)點之間通過gossip協(xié)議交換狀態(tài)信息逗爹,采用投票機制完成Slave到Master的角色提升。

缺點

· 資源隔離線差,容易出現(xiàn)相互影響的情況斑胜;

· 數(shù)據(jù)通過異步復(fù)制,無法保證數(shù)據(jù)的強一致性凭戴。

Socket通信原理

一、Socket是什么?

Socket是應(yīng)用層與傳輸層之間的軟件抽象層腐螟,他是一組接口尼桶,使用外觀設(shè)計模式實現(xiàn),將復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面小腊。 Socket可以理解為一種特殊的文件,通過提供的函數(shù)進行文件操作(讀寫IO,打開芬失,關(guān)閉)。

連接過程 服務(wù)器端先初始化Socket颊糜,然后與端口綁定(bind),對端口進行監(jiān)聽(listen),調(diào)用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket荆虱,然后連接服務(wù)器(connect)诉位,如果連接成功,這時客戶端與服務(wù)器端的連接就建立了⊥ぃ客戶端發(fā)送數(shù)據(jù)請求,服務(wù)器端接收請求并處理請求,然后把回應(yīng)數(shù)據(jù)發(fā)送給客戶端捷沸,客戶端讀取數(shù)據(jù),最后關(guān)閉連接,一次交互結(jié)束试吁。

IP****唯一標(biāo)識網(wǎng)絡(luò)中的主機,傳輸中的協(xié)議+端口可以標(biāo)識主機中的應(yīng)用程序。(IP地址币喧,協(xié)議,端口)標(biāo)識網(wǎng)絡(luò)進程史翘。

[圖片上傳失敗...(image-5078e5-1609729780946)]

image.png

二、主要函數(shù)

1. socket()

socket()對應(yīng)普通文件的打開操作,普通文件返回文件描述符脉让,socket()返回一個socket描述字,唯一標(biāo)識socket,后續(xù)讀寫设捐,綁定等都用到存捺。

· domain協(xié)議族:決定socket的地址類型岗钩,IPV4,IPV6;

· type:指定socket類型,SOCKET_STREAM凶朗,SOCKET_DGRAM,SOCKET_RAW等;

· protocol:指定協(xié)議,如IPPROTO_TCP,IPPTOTO_UDP傳輸協(xié)議踏施。

2.bind()函數(shù)

將一個地址族中的特定地址賦給socket.例如AF_INET就是把一個ipv4地址和端口號組合賦給socket。

3.listen()與connect()

服務(wù)器調(diào)用socket()與bind()之后調(diào)用listen()監(jiān)聽socket,如果客戶端調(diào)用connect()發(fā)出連接請求,服務(wù)器就會接收這個請求(三次握手的第一次握手)怕敬。

4.accept()

TCP服務(wù)器依次調(diào)用socket(),bind(),listen()之后鹰溜,就會監(jiān)聽指定的socket地址斋日。TCP客戶端依次調(diào)用socket(),connect()之后就向TCP服務(wù)器發(fā)送一個連接請求第献。TCP服務(wù)器監(jiān)聽到這個請求之后,調(diào)用accept()接收請求并建立連接。(處于三次握手的第二次握手)

5.read()/write()函數(shù)

調(diào)用網(wǎng)絡(luò)I/O讀寫,實現(xiàn)網(wǎng)絡(luò)中不同進程之間的通信蔫慧。

6.close()函數(shù)

完成讀寫操作后關(guān)閉相應(yīng)的socket描述字崭闲,類似普通文件fclose().

三橄仍、TCP三次握手與四次揮手

[圖片上傳失敗...(image-38f3cf-1609729780946)]

image.png

[圖片上傳失敗...(image-b2b384-1609729780946)]

image.png

四如孝、epoll多路復(fù)用

解決單個RECV只能監(jiān)視單個的Socket,Select方法效率低下的問題锁孟。

· epoll將維護等待列表與阻塞進程拆分;

· 維護就緒列表,采用回調(diào)方式避免遍歷哪個Socket接收到了數(shù)據(jù)羽历。

JAVA 基礎(chǔ)

一、集合

1.常見的集合有哪些

Map接口和Collection集合是所有集合框架的父接口:

  1. Collection接口的子接口包括List和Set涂圆;

  2. Map接口的實現(xiàn)類主要有HashMap,TreeMap,HashTable,ConcurrentHashMap以及Properties;

  3. Set接口實現(xiàn)的類主要有:HashSet,TreeSet以及LinkedHashSet等;

  4. List接口的實現(xiàn)類主要有:ArrayList模狭,LinkedList驱富,Stack以及Vector

2.HashMap與HashTable的區(qū)別

· HashMap不考慮同步,是線程不安全的浑侥;Hashtable使用synchronized關(guān)鍵字修飾方法晰绎,是線程安全的寓落;

· HashMap允許K/V都為null;后者K/V都不允許為null;

· HashMap繼承自AbstractMap類荞下;Hashtable繼承自Dictionary;

紅黑樹: 平衡的二叉搜索樹锄弱,具有如下特點:1.樹中的節(jié)點要么是紅色要么是黑色考蕾;2.根節(jié)點是黑色;3.葉子節(jié)點都是null值得黑節(jié)點会宪;4.每個紅節(jié)點包含兩個黑節(jié)點肖卧;任意節(jié)點到其葉子節(jié)點路徑上的黑節(jié)點數(shù)目相同。插入和刪除可能破壞這些原則掸鹅,通過變色與旋轉(zhuǎn)自適應(yīng)塞帐。

3.HashMap的put方法的流程

4.HashMap的擴容拦赠,resize()函數(shù),根據(jù)是初始化還是達到閾值分情況擴容葵姥。

5.HashMap如何解決沖突

哈希是把任意長度的輸入通過散列算法荷鼠,變換成固定長度的輸出,輸出值就是散列值榔幸。通常散列值的空間遠小于輸入的空間允乐,因此不同的輸入可能會散列成相同的輸出,不能從散列值來唯一的確定輸入值削咆。 哈希沖突就是兩個不同的輸入牍疏,通過相同散列函數(shù)計算得出相同的散列值的現(xiàn)象,稱之為碰撞拨齐。

jdk1.8中鳞陨,將高位參與到hash key的計算中,降低hash碰撞的概率瞻惋,使得數(shù)據(jù)分布更加平均厦滤,我們把這樣的操作稱之為擾動,相比jdk1.7的4次位運算歼狼,5次異或(9次擾動)掏导,jdk1.8中只進行一次位運算和一次異或運算(2次擾動)。

Hashmap****如何解決哈希沖突

  1. 使用鏈地址法蹂匹,鏈接具有相同hash值的數(shù)據(jù)碘菜;

  2. 使用2次擾動函數(shù)降低哈希沖突的概率,使得數(shù)據(jù)分布更加平均限寞;

  3. 引入紅黑樹進一步降低遍歷的時間復(fù)雜度忍啸。

6. HashMap為什么不直接使用hashCode的哈希值作為table下表?

hashcode()返回的是int類型履植,范圍是-(231)~(231 -1)计雌,而HashMap的容量范圍在16~2 ^30,導(dǎo)致hashcode()計算出的哈希值可能不在數(shù)組大小范圍內(nèi)玫霎,進而無法匹配存儲位置凿滤。

如何解決?

  1. HashMap自己實現(xiàn)的hash()方法通過兩次擾動是的自己的哈希值高低位進行異或運算庶近,降低哈希碰撞概率翁脆,使數(shù)據(jù)分布更平均。

  2. 使用hash運算之后的值與運算獲取數(shù)組下標(biāo)進行存儲相對取模操作更加有效率鼻种;只有當(dāng)數(shù)組長度為2的冪次方時反番,h&(length-1)才等價于h%length;解決了哈希值與數(shù)組大小范圍不匹配的問題。

7.HashMap在jdk1.7和jdk1.8中的不同

· 存儲結(jié)構(gòu):jdk1.7采用數(shù)據(jù)+鏈表;jdk1.8采用數(shù)組+鏈表+紅黑樹罢缸。

· 初始化方法:jdk1.7單獨函數(shù)inflateTable();jdk1.8直接集成到擴容函數(shù)resize()中篙贸。

· hash計算方法:jdk1.7擾動處理=9次擾動=4次為運算+5次異或;jdk1.8只有2次擾動次數(shù)=1次位運算+1次異或運算枫疆。

· 存儲數(shù)據(jù)的規(guī)則:jdk1.7,無沖突放數(shù)組爵川,沖突時,放鏈表息楔;jdk1.8,無沖突放數(shù)組寝贡,沖突&鏈表長度<8,放鏈表;沖突&鏈表長度>8,樹化存放紅黑樹值依;

· 插入數(shù)據(jù)方式:jdk1.7頭插法兔甘,jdk1.8尾插法;

8.為什么HashMap中String鳞滨、Integer包裝類適合做K?

Integer蟆淀,String等包裝類的特性能保證Hash值得不可更改性(final修飾)與計算準(zhǔn)確性(重寫了equals()與hashcode()方法)拯啦,有效減少Hash碰撞的幾率。

9.ConcurrentHashMap和HashTable的區(qū)別

ConcurrentHashMap結(jié)合了HashMap與HashTable的優(yōu)勢熔任,HashMap沒有考慮同步褒链,而HashTable雖然考慮了同步但效率低下(鎖定整個哈希表),ConcurrentHashMap鎖是稍微細(xì)粒度的疑苔。

ConcurrentHashMap****的實現(xiàn)原理 在jdk1.7中甫匹,ConcurrenHashMap采用Segment+HashEntry方式實現(xiàn),結(jié)構(gòu)如下:

[圖片上傳失敗...(image-58f056-1609729780946)]

image.png

  1. 包含兩個靜態(tài)內(nèi)部類HashEntry和Segment:前者用來封裝映射表的鍵值對惦费,后者充當(dāng)鎖的角色兵迅;

  2. Segment使用重入鎖ReentrantLock,每個Segment守護一個HashEntry數(shù)組薪贫,對HashEntry數(shù)組的操作必須先獲得對應(yīng)的Segment鎖恍箭。

在jdk1.8中,放棄了Segment臃腫的設(shè)計瞧省,取而代之使用Node+CAS+Synchronized保證并發(fā)安全進行實現(xiàn):

[圖片上傳失敗...(image-de0393-1609729780946)]

image.png

二扯夭、泛型

1.Java泛型概念

泛型即參數(shù)化類型,引入目的包含:

  1. 類型安全

· 泛型的主要目的是提高java程序的類型安全鞍匾;

· 編譯期間可以檢查出因java類型不正確導(dǎo)致的ClassCastException異常交洗;

· 符合越早出錯代價越小的原則。

  1. 消除強制類型轉(zhuǎn)換:使用時直接得到目標(biāo)類型橡淑,消除強制類型轉(zhuǎn)換构拳,所得即所需。

  2. 潛在收益:支持泛型幾乎不需要JVM或類文件更改,所有轉(zhuǎn)換在編譯器中完成隐圾。

2.通配符super和extend

super 聲明類型的下界伍掀,表示參數(shù)化的類型可能是指定的類型或者是此類型的父類; extends聲明類型的上界暇藏,表示參數(shù)的類型可能是指定的類型或者是此類型的子類蜜笤; <? super E>用于靈活寫入或比較,使得對象可以寫入父類型的容器盐碱,父類型的比較方法可以應(yīng)用于子類對象把兔; <? extends E>用于靈活讀取,使得方法可以讀取E或E的任意子類型的容器對象瓮顽。 生產(chǎn)者有上限县好,消費者有下限。

3.泛型擦除

當(dāng)編譯器對帶有泛型的java代碼進行編譯時暖混,它會去執(zhí)行類型檢查和類型推斷缕贡,然后生成普通的不帶泛型的字節(jié)碼,這種普通的字節(jié)碼可以被一般的 Java 虛擬機接收并執(zhí)行拣播,這在就叫做 類型擦除(type erasure)晾咪。

三、IO

  1. IO流

[圖片上傳失敗...(image-e51f6a-1609729780945)]

image.png

2.BIO贮配,NIO谍倦,AIO

BIO :同步阻塞I/O,一個連接一個線程泪勒,客戶端有連接請求服務(wù)器就啟動一個線程處理昼蛀,線程池優(yōu)化,適用于連接數(shù)目比較小且固定的架構(gòu)圆存。 NIO:同步非阻塞I/O叼旋,一個請求一個線程,客戶端發(fā)送的連接請求注冊到多路復(fù)用器上沦辙,多路復(fù)用器輪詢到有I/O請求時才啟動一個線程進行處理送淆,適用于連接數(shù)目多且連接時間短的架構(gòu)。 AIO:異步非阻塞I/O怕轿,一個有效請求一個線程偷崩,客戶端的IO請求都是由操作系統(tǒng)完成之后再通知服務(wù)器啟動線程處理,AIO適用于連接數(shù)目多且連接比較長的架構(gòu)撞羽。

對于NIO阐斜,它是非阻塞式,核心類:

· Buffer為所有的原始類型提供 (Buffer)緩存支持诀紊。

· Charset字符集編碼解碼解決方案

· Channel一個新的原始 I/O抽象谒出,用于讀寫B(tài)uffer類型,通道可以認(rèn)為是一種連接,可以是到特定設(shè)備笤喳,程序或者是網(wǎng)絡(luò)的連接为居。

BIO 與 NIO區(qū)別

· BIO面向流,NIO面向緩沖區(qū)杀狡;

· BIO是阻塞的蒙畴,NIO是非阻塞的;

· Java NIO允許使用一個單獨的線程來監(jiān)視多個輸入通道呜象,可以注冊多個通道使用一個選擇器膳凝,然后用一個單獨的線程來選擇通道。

四恭陡、反射

  1. java反射機制

反射是在運行狀態(tài)中蹬音,對于任意一個類,都能夠知道這個類的所有屬性和方法休玩;對于任意一個對象著淆,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為 Java 語言的反射機制拴疤。ReflflectASM工具類牧抽,通過字節(jié)碼生成的方式加快反射速度。

優(yōu)點:反射可以動態(tài)執(zhí)行遥赚,運行期間根據(jù)業(yè)務(wù)功能動態(tài)執(zhí)行方法,訪問屬性阐肤,發(fā)揮java的靈活性凫佛; 缺點:對性能影響,操作慢于執(zhí)行java代碼孕惜。解決方法:(1)通過setAccessible(true)關(guān)閉JDK的安全檢查;(2)多次創(chuàng)建一個類的實例時使用緩存;(3)使用ReflectASM工具類匿醒,通過字節(jié)碼生成方式加快反射速度卵牍。

2.序列化

將對象中的數(shù)據(jù)編碼為字節(jié)序列的過程叫對象序列化,反之削罩,將對象的編碼字節(jié)重新反向解碼為對象的過程叫反序列化瞄勾,遵循約定:(1)、實現(xiàn)序列化接口弥激;(2)进陡、添加序列化版本號;(3)微服、不想序列化的字段用transient修飾趾疚。

  1. 動態(tài)代理 動態(tài)代理是運行時動態(tài)生成代理類,動態(tài)代理的應(yīng)用有Spring AOP數(shù)據(jù)查詢,Java注解對象的獲取等糙麦。實現(xiàn)動態(tài)代理包括JDK原生動態(tài)代理(基于接口實現(xiàn))以及cglib動態(tài)代理(基于繼承當(dāng)前類的子類實現(xiàn))

MySQL****知識點
1.為什么用自增列作為主鍵

  • 如果定義了主鍵辛孵,InNoDB選擇主鍵作為聚集索引,如果沒有選擇讀一個不包含NULL值得唯一索引作為主鍵索引赡磅,如果沒有這樣的列魄缚,選擇內(nèi)置的6字節(jié)長的ROWID作為隱含的聚集索引;

  • 數(shù)據(jù)記錄本身被存儲于B+樹的葉子節(jié)點上仆邓,同一葉子節(jié)點內(nèi)的數(shù)據(jù)記錄按主鍵 順序存放鲜滩,新記錄插入時,MySQL根據(jù)主鍵插入合適的節(jié)點和位置节值,如果達到裝載因子(InnoDB默認(rèn)是15/16)徙硅,則開辟新的頁;

  • 如果使用自增主鍵搞疗,每次插入新的記錄嗓蘑,記錄會順序添加到當(dāng)前索引節(jié)點的后續(xù)位置;

  • 如果使用非自增主鍵匿乃,每次主鍵值近似于隨機桩皿,每次新記錄要被插入到現(xiàn)有索引頁的中間某個位置,MySQL不得不為了將新記錄插入到合適位置而移動數(shù)據(jù)幢炸,目標(biāo)頁面可能已經(jīng)被回寫到磁盤而從緩存中清掉泄隔,此時又要從磁盤讀回來,增大了開銷宛徊,頻繁的移動佛嬉、分頁也會產(chǎn)生大量的碎片,為了緊湊索引結(jié)構(gòu)闸天,需要OPTIMIZE TABLE重建表并優(yōu)化填寫頁面暖呕。

2.什么是索引,什么是索引覆蓋苞氮?為什么索引能提高效率湾揽,什么時候索引失效,什么情況下不建立或者少建立索引?

索引是為了提高數(shù)據(jù)檢索效率的一種數(shù)據(jù)結(jié)構(gòu)笼吟,分為聚集索引库物,非聚集索引以及聯(lián)合索引。

· 聚集索引(主鍵索引):數(shù)據(jù)和索引在一起存儲的索引方式叫做聚簇索引贷帮,一個表只有一個聚集索引艳狐;

· 非聚集索引:非聚簇索引記錄的物理順序與邏輯順序沒有必然的聯(lián)系,與數(shù)據(jù)的存儲物理結(jié)構(gòu)沒有關(guān)系皿桑;

· 聯(lián)合索引:多個字段組成的索引毫目。

索引覆蓋:一個查詢語句的執(zhí)行只需要從索引中就能取得蔬啡,不必從數(shù)據(jù)表中讀取,不需要回表操作镀虐,減少了I/O箱蟆。

索引之所以能提高效率是因為:1.數(shù)據(jù)索引的存儲是有序的;2.有序的情況下刮便,通過索引查詢無需遍歷索引記錄空猜;3.極端情況下數(shù)據(jù)索引的查詢效率等效為二分查找效率,趨近于log2(N).

索引失效:

· %在前的模糊查找恨旱;

· 索引列進行計算辈毯;

· 索引列使用函數(shù)

· 索引列使用!=查詢。

少建索引時機:

· 表記錄太少搜贤;

· 經(jīng)常插入谆沃,刪除修改的表;

· 數(shù)據(jù)重復(fù)且分布平均的表字段仪芒;

· 經(jīng)常和主字段一塊查詢唁影,但主字段索引值比較多的表字段。

3.B+****樹索引與哈希索引的區(qū)別

B+樹是平衡多叉樹掂名,葉子節(jié)點間的高度差不超過1据沈,同級之間的節(jié)點間有指針相互連接且有序;

[圖片上傳失敗...(image-f20506-1609729780945)]

哈希索引是采用一定的哈希算法饺蔑,將鍵值換算成新的哈希值锌介,O(1)復(fù)雜度內(nèi)搜索,無序猾警。

哈希索引的優(yōu)勢 等值查詢孔祸,哈希索引具有絕對優(yōu)勢(前提:沒有大量重復(fù)鍵) 哈希索引不使用的場景:

· 不支持范圍查詢;

· 不支持索引完成排序肿嘲;

· 不支持聯(lián)合索引的最左前綴匹配規(guī)則。

4.B****樹與B+樹的區(qū)別筑公。

B樹雳窟,每個節(jié)點都存儲key和data,所有節(jié)點組成這顆樹匣屡,葉子節(jié)點指針為null,葉子節(jié)點不包含任何關(guān)鍵字信息封救。 B+樹,所有葉子節(jié)點中包含了全部關(guān)鍵字信息及指向含有這些關(guān)鍵字記錄的指針捣作,葉子節(jié)點本身根據(jù)關(guān)鍵字大小自小而大順序鏈接誉结,非終端節(jié)點可以看做是索引部分。

B+****樹相比B樹優(yōu)勢

1券躁、B+樹磁盤讀寫代價更低惩坑,B+樹內(nèi)部節(jié)點沒有指向關(guān)鍵字具體信息的指針掉盅,內(nèi)部節(jié)點相對B樹更小,如果把所有同一內(nèi)部節(jié)點的關(guān)鍵字存放在同一盤塊中以舒,那么盤快能容納的關(guān)鍵字?jǐn)?shù)量也越多趾痘,一次性讀入內(nèi)存中的所需要的關(guān)鍵字也越多,相對來說IO讀寫次數(shù)就降低了蔓钟。 2永票、B+樹的查詢效率更加穩(wěn)定:每次查詢效率相當(dāng),都是從根節(jié)點到葉子節(jié)點的全路徑滥沫。

5.****分庫侣集,分區(qū),分表

表分區(qū):根據(jù)一定規(guī)則兰绣,將數(shù)據(jù)庫中的一張表分解成更多個更小的世分,容易管理的部分,邏輯上看仍是一張表狭魂,但底層卻是由多個物理頁分區(qū)組成罚攀。 分表:通過一定的規(guī)則將表分解成多張不同的表,如將用戶訂單數(shù)據(jù)根據(jù)時間分成多個表雌澄。 分表與分區(qū)的區(qū)別在于:分區(qū)從邏輯上來講只有一張表斋泄,而分表則是將一張表分解成多張表

表分區(qū)的好處

· 存儲更多的數(shù)據(jù):將數(shù)據(jù)分布在不同的物理設(shè)備鎖,高效利用多個硬件設(shè)備镐牺,與單個設(shè)備相比炫掐,可以存儲更多數(shù)據(jù);

· 優(yōu)化查詢:where語句中包含分區(qū)條件時睬涧,可以只掃描部分分區(qū)提高查詢效率募胃,涉及聚合查詢時可以并行,再匯總畦浓。

· 分區(qū)表更容易維護:批量刪除或清除整個分區(qū)痹束。

· 避免某些特殊的瓶頸,例如InNoDB的單個索引的互斥訪問讶请,ext3文件系統(tǒng)的inode鎖競爭等祷嘶。

分區(qū)表限制因素

· 一個表最多只能有1024個分區(qū);

· MySQL 5.1中夺溢,分區(qū)表達式必須為整數(shù)论巍,MySQL5.5中提供了非整數(shù)表達式分區(qū)的支持;

· 分區(qū)字段要么不包含主鍵或者索引列风响,要么包含全部主鍵和索引列嘉汰;

· 分區(qū)表中無法使用外鍵約束;

· MySQL分區(qū)適用于一個表的所有數(shù)據(jù)和索引状勤,不能只對表數(shù)據(jù)分區(qū)而不對索引分區(qū)鞋怀,也不能只對索引分區(qū)不對表分區(qū)双泪,也不能只對表的一部分?jǐn)?shù)據(jù)分區(qū)。

判斷當(dāng)前MySQL是否支持分區(qū): show variables like '%partition%'

MySQL****支持的分區(qū)類型 1.RANGE分區(qū):允許數(shù)據(jù)劃分不同范圍接箫; 2.LIST分區(qū):允許系統(tǒng)通過預(yù)定義的列表的值來進行分割攒读; 3.HASH****分區(qū):允許對表的一個或多個列進行Hash Key進行計算,通過Hash碼值進行分區(qū)辛友; 4.KEY****分區(qū):Hash模式延伸薄扁,Hash Key由MySQL系統(tǒng)產(chǎn)生。

6.****數(shù)據(jù)庫隔離與數(shù)據(jù)不一致問題

[圖片上傳失敗...(image-49bda0-1609729780944)]

image.png

7.****并發(fā)控制

1.InnoDB實現(xiàn)的是多版本控制協(xié)議:MVVC
2.與之相對的是基于鎖的并發(fā)控制協(xié)議:LBCC

在MVVC并發(fā)控制中废累,讀操作分為兩類: 1.讀快照:讀取的是記錄的可見版本(有可能是歷史版本)邓梅,不用加鎖; 2.讀當(dāng)前:讀取的是記錄的最新版本邑滨,并且當(dāng)前讀返回的記錄都會上鎖日缨,保障其他事務(wù)不會再并發(fā)修改這條記錄。

8. mysql****鎖

鎖是計算機協(xié)調(diào)進程或者線程并發(fā)訪問某一資源的機制掖看。保證數(shù)據(jù)并發(fā)訪問的一致性有效性匣距。

共享鎖與排他鎖

· 共享鎖(讀鎖):其他事務(wù)可以讀,但不能寫哎壳。

· 排他鎖(寫鎖) :其他事務(wù)不能讀取毅待,也不能寫。 鎖粒度 MyISAM 和 MEMEORY 存儲引擎采用的是表級鎖归榕,InnoDB存儲因此既支持行級鎖也支持表級鎖尸红,默認(rèn)行級鎖。 行鎖優(yōu)缺點

[圖片上傳失敗...(image-d910d5-1609729780944)]

image.png

9.****慢查詢

slow_query_log與slow_query_log_file分析刹泄。 1.查看是否查詢的數(shù)據(jù)有冗余外里,去除不需要的冗余字段; 2.explain分析sql特石,查看分析索引命中情況盅蝗; 3.數(shù)據(jù)量過大,考慮分表姆蘸;

10.mysql****優(yōu)化

· 開啟查詢緩存墩莫,優(yōu)化查詢

· explain select查詢,分析查詢語句或表結(jié)構(gòu)的性能瓶頸乞旦,explain還會告訴你你的索引主鍵是如何利用贼穆,數(shù)據(jù)表是如何搜索和排序的题山。

· 只需要一條記錄時使用limit 1兰粉,找到記錄后停止掃描;

· 為搜索字段添加合適的索引顶瞳;

· 使用ENUM而不是VARCHAR玖姑,提高查詢效率

· 使用預(yù)編譯語句

· 垂直分表

· 選擇正確的存儲引擎

11.MySQL****中MyISAM與InNoDB的卻別愕秫。

區(qū)別

  1. InnoDB支持事務(wù),MyISAM不支持焰络;

  2. InNoDB支持外鍵戴甩,MyISAM不支持;

  3. InNoDB是聚集索引闪彼,數(shù)據(jù)文件與索引綁定甜孤,必須有主鍵,通過主鍵索引效率更高畏腕;

  4. InnoDB不保存表行數(shù)缴川,統(tǒng)計行需要全表掃描,而MyISAM用一個變量保存了整個表的行數(shù)描馅,查詢效率高把夸;

  5. InnoDB不支持全文檢索,而MyISAM支持全文檢索铭污,查詢效率高

  6. MyISAM不支持行級鎖恋日,只支持表級鎖。

常見的Web攻擊手段

一嘹狞、XSS攻擊

XSS(Cross Site Scripting跨站腳本): XSS定義的主語是“腳本”岂膳,是一種跨站執(zhí)行的腳本,在網(wǎng)站上注入javascript腳本刁绒,執(zhí)行非法操作闷营。

XSS攻擊發(fā)生的條件是可以執(zhí)行javascript腳本,一般在站點中總會有發(fā)表文章知市、留言等信息的表單傻盟,這種表單一般是寫入到數(shù)據(jù)庫中,然后在某個頁面進行展示嫂丙。我們可以在這些表單中直接編寫javascript代碼(<script>alert("哈哈哈哈娘赴,你被攻擊了!");</script>)進行測試,看是否可以執(zhí)行跟啤。如果在信息展示頁面js代碼可以執(zhí)行诽表,XSS攻擊就成功了。

解決方法 1.錯誤把數(shù)據(jù)當(dāng)做了代碼執(zhí)行隅肥,因此竿奏,對數(shù)據(jù)中的特殊字符做轉(zhuǎn)義處理。

二腥放、CSRF攻擊

CSRF(Cross-site request forgery跨站請求偽造): CSRF定義的主語是”請求“泛啸,是一種跨站的偽造的請求,指的是跨站偽造用戶的請求秃症,模擬用戶的操作.

CSRF攻擊能夠成功候址,是因為黑客可以完全偽造用戶的請求吕粹,該請求中所有的用戶驗證信息都是存在于cookie中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的cookie 來通過安全驗證岗仑。要抵御 CSRF匹耕,關(guān)鍵在于在請求中放入黑客所不能偽造的信息,并且該信息不存在于 cookie 之中荠雕∥绕洌可以在 HTTP 請求中以參數(shù)的形式加入一個隨機產(chǎn)生的 token,并在服務(wù)器端建立一個攔截器來驗證這個 token炸卑,如果請求中沒有token或者 token 內(nèi)容不正確欢际,則認(rèn)為可能是 CSRF 攻擊而拒絕該請求。這種方法要比檢查 Referer 要安全一些矾兜,token 可以在用戶登陸后產(chǎn)生并放于session之中损趋,然后在每次請求時把token 從 session 中拿出,與請求中的 token 進行比對.

解決方法 1.設(shè)置HttpOnly椅寺,程序無法讀取cookie浑槽; 2.請求參數(shù)增加token; 3.通過Referer識別返帕。

http://www.reibang.com/p/40a12ad4bb75

三桐玻、越權(quán)攻擊

越權(quán)是指一般一個用戶只能對自己本身的信息進行增刪改查,然而由于服務(wù)器的一些漏檢荆萤,導(dǎo)致信息在進行增刪改查時沒有對用戶進行判斷镊靴,從而導(dǎo)致用戶A可以對其他用戶進行增刪改查等操作。

1.水平越權(quán)和垂直越權(quán)链韭。

· 水平越權(quán):訪問控制攻擊漏洞偏竟。web應(yīng)用程序在接收用戶請求時,我們在進行增刪改查某條數(shù)據(jù)時候敞峭,沒有判斷數(shù)據(jù)所對應(yīng)的用戶或者判斷數(shù)據(jù)的用戶時是通過從用戶表單參數(shù)中獲取userid來實現(xiàn)的踊谋,因此,可以通過修改userid來實現(xiàn)水平越權(quán)旋讹。

· 垂直越權(quán):又稱為權(quán)限提升攻擊殖蚕,具體原因是web應(yīng)用沒有做用戶權(quán)限控制,或只是在菜單做了權(quán)限控制沉迹,導(dǎo)致惡意用戶只要猜測到其他管理頁面的URL睦疫,就可以訪問或者控制其他角色擁有的數(shù)據(jù)或頁面,達到權(quán)限提升的目的鞭呕。

2.越權(quán)防范

1.永遠不要相信客戶端的輸入蛤育; 2.執(zhí)行關(guān)鍵操作時必須驗證用戶身份,多階段功能每一步都驗證用戶身份; 3.對于直接對象引用缨伊,加密資源ID,防止攻擊者對ID進行枚舉进宝; 4.在前端的驗證不可靠刻坊,權(quán)限驗證在服務(wù)器端。

四党晋、DDos攻擊

DDos攻擊:分布式拒絕服務(wù)攻擊谭胚,利用合理的客戶端請求占用過多的服務(wù)器資源,從而使合法用戶無法得到服務(wù)器響應(yīng)未玻。DDos攻擊者借用公共網(wǎng)絡(luò)灾而,將數(shù)量龐大的計算機聯(lián)合起來作為攻擊平臺,對一個或多個目標(biāo)發(fā)動攻擊扳剿,從而達到癱瘓主機的目的旁趟。通常,在攻擊開始之前庇绽,攻擊者會提前控制大量的用戶計算機锡搜,稱之為肉雞,通過指令使大量肉雞在同一時刻對某個主機發(fā)起訪問瞧掺,從而達到癱瘓目標(biāo)主機的目的耕餐。

DDos常見手段

1.SYN Flood:利用TCP協(xié)議三次握手的過程達到攻擊的目的。攻擊者偽造大量的IP地址向服務(wù)器發(fā)送SYN報文辟狈,由于偽造的IP地址不存在肠缔,服務(wù)器不可能從客戶端得到任何回應(yīng),服務(wù)端維護一個非常的大半連接列表哼转,并不斷對這個列表中的IP進行遍歷與重試明未,占用大量的系統(tǒng)資源,當(dāng)大量惡意客戶端信息占滿服務(wù)器的等待列表時壹蔓,服務(wù)器不再接收新的SYN請求亚隅,用戶無法完成三次握手與服務(wù)器通信。

2.DNS Query Flood:UDPFlood變形攻擊庶溶,其原理是通過向被攻擊的服務(wù)器發(fā)送海量的域名解析請求煮纵,導(dǎo)致DNS服務(wù)器癱瘓。通常偏螺,請求解析的域名是隨機生成的行疏,大部分根本不存在,通過偽造端口和客戶端IP套像,防止查詢請求被ACL過濾酿联。被攻擊的DNS服務(wù)器在接收到域名解析請求時,會在服務(wù)器上查找是否有對應(yīng)的緩存,由于域名是隨機生成的贞让,幾乎不可能有相應(yīng)的緩存周崭,當(dāng)在服務(wù)器上無法直接解析域名時,DNS服務(wù)器向上層DNS服務(wù)器遞歸查詢域名信息喳张。大量不存在的域名解析請求給服務(wù)器帶來很大的負(fù)載续镇,當(dāng)解析請求超過一定量時,會造成DNS解析域名超時销部,從而達到攻擊目的摸航。

3.CC 攻擊:Challenge Collapsar攻擊,基于應(yīng)用層HTTP協(xié)議發(fā)起的DDos攻擊舅桩,也稱為HTTP Flood酱虎。CC攻擊的原理是攻擊者通過肉雞或者從互聯(lián)網(wǎng)上搜尋的大量知名的HTTP代理,模擬正常用戶給網(wǎng)站發(fā)起請求直到網(wǎng)站拒絕服務(wù)為止擂涛。大部分網(wǎng)站通過CDN或者分布式緩存加速服務(wù)端響應(yīng)读串,提升網(wǎng)站吞吐量,而構(gòu)造的HTTP請求往往有意避開這些緩存撒妈,需要進行多次查詢DB或者一次請求返回大量的數(shù)據(jù)加速系統(tǒng)資源消耗爹土,從而拖垮后端業(yè)務(wù)處理系統(tǒng)。

五踩身、SQL注入攻擊

SQL注入:就是通過把SQL命令偽裝成正常的HTTP請求參數(shù)胀茵,傳遞到服務(wù)端,欺騙服務(wù)器最終執(zhí)行惡意的SQL命令挟阻,達到入侵目的琼娘。攻擊者可以利用SQL注入漏洞,查詢非授權(quán)信息附鸽,修改數(shù)據(jù)庫服務(wù)器的數(shù)據(jù)脱拼,改變表結(jié)構(gòu),甚至是獲取服務(wù)器root權(quán)限坷备。

解決方法 1.使用預(yù)編譯語句熄浓; 2.使用ORM框架,支持相應(yīng)關(guān)鍵字或者特殊字符的轉(zhuǎn)義

六 劫持

運營商通過某些方式篡改用戶正常訪問的網(wǎng)頁省撑,插入廣告或針對一些廣告聯(lián)盟或帶推廣鏈接的網(wǎng)站赌蔑,加入推廣尾巴。

DNS劫持:用戶上網(wǎng)的DNS服務(wù)器是運營商分配的竟秫,所以娃惯,在這個節(jié)點上運營商可以為所欲為。例如肥败,對于用戶訪問的A網(wǎng)站趾浅,正常DNS解析后會返回A網(wǎng)站服務(wù)器IP愕提,而DNS劫持后,返回的是運營商的中間服務(wù)器IP。訪問該服務(wù)器會一致性的訪問302重定向,讓用戶瀏覽器跳轉(zhuǎn)到預(yù)處理好的網(wǎng)頁智玻,再在這個網(wǎng)頁中打開原來用戶請求的網(wǎng)頁。

HTTP 劫持:在運營商的路由器節(jié)點上如输,設(shè)置協(xié)議檢測,一旦發(fā)現(xiàn)是HTTP請求椎例,則攔截處理。后續(xù)做法请祖,一種是類似DNS劫持返回302讓用戶跳轉(zhuǎn)到另外的地址订歪,另外一種是在服務(wù)器返回的HTML數(shù)據(jù)中插入js或dom節(jié)點。

如何防范劫持

1.對外網(wǎng)檢測肆捕,上報被劫持的情況刷晋;

2.針對被iframe加載的情況,找到運營商設(shè)置的劫持規(guī)律(請求url或者cookie被做了標(biāo)記)慎陵;

  1. 針對dom節(jié)點注入情況眼虱,初始化時做檢查,后續(xù)dom注入也做檢查席纽,如果檢查dom中含有白名單外的http連接捏悬,判定為http劫持。

  2. (1)終端攔截所有返回包润梯,判斷ip來自黑名單則丟棄返回包过牙;(2)終端攔截請求包,拆包發(fā)送(只檢測TCP連接后第一個包是否是HTTP協(xié)議纺铭,將包拆細(xì)寇钉,使其無法被是被為HTTP協(xié)議);

  3. 根本解決辦法舶赔,用HTTPS代替HTTP扫倡。

linux進程通信關(guān)

1.linux進程通信,RPC竟纳,共享內(nèi)存等基本概念撵溃;

進程相互獨立,內(nèi)部變量別的進程不可見锥累,由內(nèi)核提供一份公共資源讓多個進程訪問征懈。

· 獨立性;

· 通過資源共享相互通信揩悄;

· 共享由操作系統(tǒng)內(nèi)核實現(xiàn)卖哎。

1 匿名管道與命名管道:

內(nèi)核提供一段內(nèi)存(隊列),通過內(nèi)存借助這段內(nèi)存,完成進程間通信亏娜。然后將這段內(nèi)存抽象成文件焕窝,通過訪問文件描述符的形式讀寫這塊內(nèi)存中的數(shù)據(jù)。

特點:

· 只適用于具有親緣關(guān)系的進程(匿名管道,pipe函數(shù)創(chuàng)建)维贺,適用任何進程(命名管道它掂,mkfifo創(chuàng)建);

· 單向通信溯泣;

· 面向字節(jié)流虐秋;

· 內(nèi)置同步互斥機制;

· 生命周期隨內(nèi)存

2 消息隊列

本質(zhì)是內(nèi)核中的一個鏈表垃沦,在訪問消息隊列的時候客给,按照節(jié)點為單元,訪問數(shù)據(jù)的讀和寫肢簿。

特點

· 適用于任何進程靶剑;

· 全雙工,半通信

· 面向數(shù)據(jù)報池充,按照節(jié)點為單位桩引,一個一個讀,一個一個寫收夸。

· 內(nèi)置同步互斥機制

· 生命周期隨內(nèi)核坑匠,進程沒了,消息隊列還在卧惜,IPC rm指令手動刪除或者重啟笛辟。

3.共享內(nèi)存

同一塊物理內(nèi)存通過頁表分表映射到不同進程的虛擬地址空間,從而導(dǎo)致序苏,第一個內(nèi)存變量的修改手幢,物理內(nèi)存發(fā)生變化,第二個內(nèi)存再去讀取時能感知到變量的改變忱详。結(jié)合信號量使用围来,從而達到進程間的同步與互斥。

特點

· 適用于任何進程匈睁;

· 雙向通信

· 無同步互斥機制

· 不存在面向字節(jié)流與數(shù)據(jù)報的概念监透,只是一塊內(nèi)存,可以隨意讀寫數(shù)據(jù)航唆,隨機訪問(shmget創(chuàng)建胀蛮,shmat分配,shmdt共享內(nèi)存段與當(dāng)前進程脫離糯钙,shmctl控制共享內(nèi)存)粪狼;

· 共享內(nèi)存效率極高:訪問共享內(nèi)存與普通內(nèi)存沒有差別退腥,而要進行管道或者消息隊列的話涉及反復(fù)把數(shù)據(jù)從內(nèi)核拷貝到用戶,又從用戶拷貝到內(nèi)存再榄,反復(fù)拷貝狡刘,開銷大。

· 生命周期隨內(nèi)核

4 信號量

信號量本身是計數(shù)器困鸥,通過自身計數(shù)的性質(zhì)完成進程之間的同步和互斥嗅蔬。

特點

· 適用任何進程

· 生命周期隨內(nèi)核

TCP,UDP

一、基本概念

· 序列號seq:四個字節(jié)疾就,標(biāo)記數(shù)據(jù)段的順序澜术,第一個字節(jié)本地隨機產(chǎn)生;

· 確認(rèn)號ack:四個字節(jié)猬腰,期待收到對方下一個報文段的第一個數(shù)據(jù)字節(jié)的序號鸟废;

· 確認(rèn)ACK:1位,ACK=1時漆诽,確認(rèn)還ack才有效侮攀,否則ack無效锣枝;

· 同步SYN:建立連接時用于同步序號厢拭,SYN=1表示一個連接請求,或連接接受報文撇叁。

· 終止FIN:用來釋放一個連接供鸠,F(xiàn)IN=1表示,報文段的發(fā)送方數(shù)據(jù)已發(fā)送完畢陨闹,等待釋放運輸連接楞捂。 ps:ACK, SYN, FIN都是標(biāo)志位,其值要么是1趋厉,要么是0寨闹;ack、seq小寫單詞表示序號君账。

客戶端狀態(tài)轉(zhuǎn)移:CLOSED->SYN_SENT->ESTABLISED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED 服務(wù)器狀態(tài)轉(zhuǎn)移:CLOSED->LISTENING->SYN_RCVD->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

二繁堡、三次握手過程

[圖片上傳失敗...(image-b3b4d2-1609729780943)]

image.png

第一次握手:建立連接,客戶端發(fā)送sync包(syn=c)到服務(wù)器乡数,并進入SYN_SENT狀態(tài)椭蹄,等待服務(wù)器確認(rèn);

第二次握手:服務(wù)器收到syn包净赴,必須確認(rèn)客戶的SYN(ack=x+1)绳矩,同時自己發(fā)送一個SYN包(syn=y),即SYN+ACK包玖翅,此時服務(wù)器進入SYN_RECV狀態(tài)翼馆;

第三次握手:客戶端收到服務(wù)器的SYN+ACK包割以,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=y+1),發(fā)送完畢后,客戶端與服務(wù)器進入ESTABLISHED(TCP連接成功)狀態(tài)写妥,完成三次握手拳球。

三、四次揮手過程

[圖片上傳失敗...(image-ef90b6-1609729780943)]

image.png

1.客戶端進程發(fā)送FIN連接釋放包珍特,并停止發(fā)送數(shù)據(jù)祝峻,F(xiàn)IN=1,seq=u,客戶端進入FIN_WAIT_1狀態(tài);

2.服務(wù)器接收客戶端傳遞過來的FIN包扎筒,發(fā)出確認(rèn)報文ACK=1莱找,ack=u+1,并帶上自己的序列號seq=v,此時嗜桌,客戶端進入FIN_WAIT_2狀態(tài)奥溺,服務(wù)器進入CLOSE_WAIT狀態(tài);

3.服務(wù)端將最后的數(shù)據(jù)發(fā)送完畢后骨宠,向客戶端發(fā)送連接釋放報文浮定,F(xiàn)IN=1,ack=u+1,服務(wù)器可能再次中間過程又發(fā)送了一些數(shù)據(jù)层亿,此時的序列號為w,發(fā)送完成之后服務(wù)端進入LAST_ACK狀態(tài)桦卒,等待客戶端最后確認(rèn);

4.客戶端收到服務(wù)器發(fā)送過來的連接釋放報文后匿又,發(fā)送確認(rèn)ACK包方灾,ACK=1,seq=u+1,ack=w+1,客戶端進入TIME_WAIT狀態(tài)碌更,并在等待2**MSL后裕偿,當(dāng)客戶端撤銷相應(yīng)的TCB后,進入CLOSE狀態(tài)痛单;服務(wù)器接收到客戶端發(fā)送出的確認(rèn)包后嘿棘,同樣撤銷TCB后,結(jié)束TCP連接旭绒,因此服務(wù)器結(jié)束要比客戶端早一些鸟妙。

四、TCP與UDP區(qū)別

[圖片上傳失敗...(image-5e1371-1609729780943)]

五快压、擁塞控制與流量控制

擁塞控制與流量控制是TCP用來解決傳輸數(shù)據(jù)過程中產(chǎn)生的問題而采取的兩種優(yōu)化方法圆仔。

· 流量控制:為了解決發(fā)送發(fā)與接收方速度不同而導(dǎo)致的數(shù)據(jù)丟失問題,當(dāng)數(shù)據(jù)發(fā)送過快蔫劣,接收方來不及接收就會導(dǎo)致數(shù)據(jù)丟失坪郭,流量控制采用滑動窗口的形式解決問題。

· 擁塞控制:為了解決過多數(shù)據(jù)注入到網(wǎng)絡(luò)脉幢,導(dǎo)致網(wǎng)絡(luò)奔潰歪沃,超過負(fù)荷嗦锐。當(dāng)發(fā)送方發(fā)送大量數(shù)據(jù)注入到網(wǎng)絡(luò)液走,如果沒有限制该抒,網(wǎng)絡(luò)就會超負(fù)荷變卡欧引,擁塞控制采用擁塞窗口解決問題瞬哼。

窗口的意義

窗口就是緩存區(qū)赞咙,用于暫時存儲數(shù)據(jù)等待發(fā)送與接收歹垫,就是對每一次發(fā)送的數(shù)據(jù)大小進行限制暮芭,每個窗口都有大小限制匾效,超過部分不能發(fā)送河胎,可以不用每次發(fā)送報文等待ACK確認(rèn)胚迫,只需要保證發(fā)送的報文在發(fā)送窗口內(nèi)部就行,消除了等待確認(rèn)的時間遣总,大大提高了效率。

流量控制

流量控制通過滑動窗口來實現(xiàn)算芯,發(fā)送窗口的大小取決于接收方ACK提供的大小和發(fā)送方的擁塞窗口大小的最小值柒昏。發(fā)送窗口大小不能超過滑動窗口的大小。發(fā)送方接收到數(shù)據(jù)的確認(rèn)信息熙揍,滑動窗口會根據(jù)返回的序號動態(tài)的改變窗口的位置职祷。滑動窗口的大小得到重置届囚,同時有梆,滑動窗口會根據(jù)網(wǎng)絡(luò)狀況動態(tài)變化。

擁塞控制

擁塞控制為了解決過多數(shù)據(jù)注入到網(wǎng)絡(luò)意系,導(dǎo)致網(wǎng)絡(luò)奔潰泥耀,超過負(fù)荷,擁塞控制主要包含四個策略蛔添。

[圖片上傳失敗...(image-c830b6-1609729780943)]

image.png

· 慢開始:窗口先設(shè)置為1痰催,每次傳輸輪次大小增長一倍,直達達到慢開始的門限值迎瞧,慢開始階段結(jié)束夸溶;

· 擁塞避免:慢開始結(jié)束后,就是擁塞避免夹攒,這個階段擁塞窗口每個傳輸輪次加1蜘醋,直到觸發(fā)網(wǎng)絡(luò)擁塞胁塞,窗口大小和門限都變?yōu)閾砣麜r最大值的一半咏尝,然后重新開始慢開始階段。

· 快重傳:接收方收到順序錯誤的數(shù)據(jù)時不接收數(shù)據(jù)啸罢,同時重復(fù)發(fā)起對于之前數(shù)據(jù)的確認(rèn)编检,發(fā)動到第三次,發(fā)送方得知自己的一部分?jǐn)?shù)據(jù)丟失立刻重傳扰才,不需要等待下一次發(fā)送信息時一起發(fā)送過去允懂,且重傳時觸發(fā)與擁塞一樣的情況,進入快恢復(fù)階段衩匣。

· 快恢復(fù):

  1. 當(dāng)收到3個重復(fù)ACK時蕾总,把ssthresh設(shè)置為cwnd的一半粥航,把cwnd設(shè)置為ssthresh的值加3,然后重傳丟失的報文段生百,加3的原因是因為收到3個重復(fù)的ACK递雀,表明有3個“老”的數(shù)據(jù)包離開了網(wǎng)絡(luò)。

  2. 再收到重復(fù)的ACK時蚀浆,擁塞窗口增加1缀程。

  3. 當(dāng)收到新的數(shù)據(jù)包的ACK時,把cwnd設(shè)置為第一步中的ssthresh的值市俊。原因是因為該ACK確認(rèn)了新的數(shù)據(jù)杨凑,說明從重復(fù)ACK時的數(shù)據(jù)都已收到,該恢復(fù)過程已經(jīng)結(jié)束摆昧,可以回到恢復(fù)之前的狀態(tài)了撩满,也即再次進入擁塞避免狀態(tài)。注意绅你,如果在此過程出現(xiàn)超時鹦牛,則重新進入慢啟動階段。

六勇吊、常見面試題

【問題1】為什么連接的時候是三次握手曼追,關(guān)閉的時候卻是四次握手?

答:因為當(dāng)Server端收到Client端的SYN連接請求報文后汉规,可以直接發(fā)送SYN+ACK報文礼殊。其中ACK報文是用來應(yīng)答的,SYN報文是用來同步的针史。但是關(guān)閉連接時晶伦,當(dāng)Server端收到FIN報文時,很可能并不會立即關(guān)閉SOCKET啄枕,所以只能先回復(fù)一個ACK報文婚陪,告訴Client端,"你發(fā)的FIN報文我收到了"频祝。只有等到我Server端所有的報文都發(fā)送完了泌参,我才能發(fā)送FIN報文,因此不能一起發(fā)送常空。故需要四步握手沽一。

【問題2】為什么TIME_WAIT狀態(tài)需要經(jīng)過2MSL(最大報文段生存時間)才能返回到CLOSE狀態(tài)?

答:雖然按道理漓糙,四個報文都發(fā)送完畢铣缠,我們可以直接進入CLOSE狀態(tài)了,但是我們必須假象網(wǎng)絡(luò)是不可靠的,有可能最后一個ACK丟失蝗蛙。所以TIME_WAIT狀態(tài)就是用來重發(fā)可能丟失的ACK報文蝇庭。在Client發(fā)送出最后的ACK回復(fù),但該ACK可能丟失捡硅。Server如果沒有收到ACK遗契,將不斷重復(fù)發(fā)送FIN片段。所以Client不能立即關(guān)閉病曾,它必須確認(rèn)Server接收到了該ACK牍蜂。Client會在發(fā)送出ACK之后進入到TIME_WAIT狀態(tài)。Client會設(shè)置一個計時器泰涂,等待2MSL的時間鲫竞。如果在該時間內(nèi)再次收到FIN,那么Client會重發(fā)ACK并再次等待2MSL逼蒙。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)从绘。MSL指一個片段在網(wǎng)絡(luò)中最大的存活時間,2MSL就是一個發(fā)送和一個回復(fù)所需的最大時間是牢。如果直到2MSL僵井,Client都沒有再次收到FIN,那么Client推斷ACK已經(jīng)被成功接收驳棱,則結(jié)束TCP連接批什。

【問題3】為什么不能用兩次握手進行連接?

答:3次握手完成兩個重要的功能社搅,既要雙方做好發(fā)送數(shù)據(jù)的準(zhǔn)備工作(雙方都知道彼此已準(zhǔn)備好)驻债,也要允許雙方就初始序列號進行協(xié)商,這個序列號在握手過程中被發(fā)送和確認(rèn)形葬。 現(xiàn)在把三次握手改成僅需要兩次握手合呐,死鎖是可能發(fā)生的。作為例子笙以,考慮計算機S和C之間的通信淌实,假定C給S發(fā)送一個連接請求分組,S收到了這個分組猖腕,并發(fā)送了確認(rèn)應(yīng)答分組拆祈。按照兩次握手的協(xié)定,S認(rèn)為連接已經(jīng)成功地建立了谈息,可以開始發(fā)送數(shù)據(jù)分組缘屹。可是,C在S的應(yīng)答分組在傳輸中被丟失的情況下侠仇,將不知道S 是否已準(zhǔn)備好,不知道S建立什么樣的序列號,C甚至懷疑S是否收到自己的連接請求分組逻炊。在這種情況下互亮,C認(rèn)為連接還未建立成功,將忽略S發(fā)來的任何數(shù)據(jù)分組余素,只等待連接確認(rèn)應(yīng)答分組豹休。而S在發(fā)出的分組超時后,重復(fù)發(fā)送同樣的分組桨吊。這樣就形成了死鎖威根。

【問題4】如果已經(jīng)建立了連接,但是客戶端突然出現(xiàn)故障了怎么辦视乐?

TCP還設(shè)有一個甭宀螅活計時器,顯然佑淀,客戶端如果出現(xiàn)故障留美,服務(wù)器不能一直等下去,白白浪費資源伸刃。服務(wù)器每收到一次客戶端的請求后都會重新復(fù)位這個計時器谎砾,時間通常是設(shè)置為2小時,若兩小時還沒有收到客戶端的任何數(shù)據(jù)捧颅,服務(wù)器就會發(fā)送一個探測報文段景图,以后每隔75秒鐘發(fā)送一次。若一連發(fā)送10個探測報文仍然沒反應(yīng)碉哑,服務(wù)器就認(rèn)為客戶端出了故障症歇,接著就關(guān)閉連接。

HTTP 1.0 1.1 2.0****區(qū)別

同步滾動:關(guān)

一谭梗、****HTTP****發(fā)展歷史

· HTTP 1.0 -1996年

· HTTP 1.1 - 1999年

· HTTP 2.0 - 2015年

二忘晤、****HTTP****基本優(yōu)化

影響HTTP網(wǎng)絡(luò)請求的兩個主要因素:帶寬與延遲。

· 帶寬:現(xiàn)在網(wǎng)絡(luò)基礎(chǔ)建設(shè)帶寬已得到極大提升激捏,不再是瓶頸设塔。

· 延遲:

  1. 瀏覽器阻塞:瀏覽器阻塞請求,瀏覽器對于同一個域名同時只能有4個鏈接远舅,超過瀏覽器最大連接數(shù)限制闰蛔,后續(xù)請求就被阻塞;

2.DNS查詢:瀏覽器需要知道目標(biāo)服務(wù)器IP才能建立連接图柏,DNS將域名解析為IP序六,這個過程可能耗時,利用DNS緩存結(jié)果減少這個耗時蚤吹;

3.建立連接:HTTP基于TCP協(xié)議例诀,三次握手后才能捎帶HTTP請求報文達到真正的連接随抠,這些連接都無法復(fù)用導(dǎo)致請求都經(jīng)歷三次握手與慢啟動。三次握手在高延遲的場景下影響很明顯繁涂,慢啟動則對文件類大請求影響較大拱她。

三、****HTTP1.0 與****HTTP1.1****區(qū)別

1.緩存處理:HTTP1.0中主要使用header里的If-Modified-Since,Expires作為緩存判斷的依據(jù)扔罪,HTTP1.1引入了更多的緩存控制策略秉沼,如Entity tag, If-Unmodified-Since, If-Match, If-None-Match等。

  1. 帶寬優(yōu)化與網(wǎng)絡(luò)連接使用:HTTP1.0中矿酵,存在浪費帶寬的現(xiàn)象唬复,例如客戶端只需要某個對象的一部分,而服務(wù)器將整個對象送來全肮,且不支持?jǐn)帱c續(xù)傳功能敞咧;HTTP1.1中則在請求頭引入了range頭域,其允許只請求資源的某個部分倔矾,返回碼206妄均。

3.錯誤通知的管理:HTTP1.1新增了24個錯誤狀態(tài)響應(yīng)碼。(409,410等資源訪問沖突哪自,資源被永久性刪除等)丰包。

4.Host頭處理:HTTP1.0中認(rèn)為每臺服務(wù)器綁定唯一的IP地址,因此壤巷,請求的URL不傳遞主機名邑彪。而虛擬技術(shù)的發(fā)展,在一臺物理服務(wù)器上可以存在多個虛擬主機胧华,并且共享一個IP地址寄症。HTTP1.1的請求消息與響應(yīng)消息都支持Host頭域,如果沒有Host頭域報告一個400錯誤矩动。

5.長連接:HTTP1.1支持長連接與請求的流水線處理有巧,可以在一個TCP連接上傳送多個HTTP請求與響應(yīng),減少建立與關(guān)閉連接的消耗和延時悲没。

四篮迎、****HTTP2.0****擴充

1.支持多路復(fù)用:允許同時通過單一的HTTP2.0連接發(fā)起多重的請求-響應(yīng)消息,減少因HTTP連接多而引起的網(wǎng)絡(luò)擁塞示姿,解決了慢啟動針對突發(fā)性與短時性的http鏈接低效的問題甜橱。

2.將通信的基本單位縮小為幀

3.首部壓縮:支持DEFLATE和HPACK算法的壓縮

4.服務(wù)器推送: 客戶端請求之前發(fā)送數(shù)據(jù)的機制,在HTTP2.0中栈戳,服務(wù)器可與對客戶端的一個請求發(fā)送多個響應(yīng)岂傲。

session與cooking

基本概念

cookie是服務(wù)端識別客戶的唯一標(biāo)識依據(jù),客戶在訪問服務(wù)端時子檀,服務(wù)端為了記住這個客戶,在服務(wù)端按照它的規(guī)則制作一個cookie數(shù)據(jù),將這個cookie數(shù)據(jù)保留在服務(wù)端一段時間,同時回傳給客戶端保留一份,這樣就無需每次登錄都來認(rèn)證客戶端身份了磺浙。

1.無狀態(tài)的HTTP協(xié)議:協(xié)議是計算機網(wǎng)絡(luò)通信中兩臺計算機之間進行通信必須遵守的規(guī)則或約定,HTTP是一種通信協(xié)議舍肠,它允許將HTML文檔從WEB服務(wù)器傳送到客戶端的瀏覽器奕巍。HTTP是無狀態(tài)的協(xié)議,一旦數(shù)據(jù)交換完畢驶冒,客戶端與服務(wù)端的鏈接就會關(guān)閉苟翻,再次交換數(shù)據(jù)就需要建立新的鏈接,服務(wù)器無法從連接上跟蹤會話骗污。

2.會話跟蹤:會話是指用戶登錄網(wǎng)站后的一系列動作崇猫,會話跟蹤是WEB程序中常用的技術(shù)用來跟蹤用戶的整個會話。 session和cookie是常用的會話跟蹤技術(shù)需忿,cookie在客戶端記錄信息確認(rèn)用戶身份诅炉,session在服務(wù)端記錄信息確認(rèn)。

Cookie

· Cookie的由來屋厘?Cookie的工作原理是什么涕烧? 由于HTTP是無狀態(tài)的連接,服務(wù)器無法從網(wǎng)絡(luò)連接上識別客戶身份汗洒,為了識別客戶身份议纯,服務(wù)端給每個客戶辦法一個訪問的通行證,服務(wù)端從通信證上確認(rèn)客戶的身份溢谤,這個通行證就是cookie的工作原理瞻凤。cookie實際上就是一小段文本,客戶請求服務(wù)器世杀,如果服務(wù)器需要記錄用戶狀態(tài)阀参,就用response向客戶端瀏覽器頒發(fā)一個Cookie,客戶端把cookie存起來瞻坝,當(dāng)下次客戶端再次請求服務(wù)端時蛛壳,會將請求連同cookie一起提交給服務(wù)器,服務(wù)器用過檢查cookie用來辨識用戶的狀態(tài)湿镀。

cookie的主要內(nèi)容包括:Name炕吸,Value,Domain勉痴,Path和Expires屬性

· Name和Value有程序設(shè)定赫模,默認(rèn)都是空引用。

· Domain 屬性默認(rèn)值是當(dāng)前URL的域名部分蒸矛。

· Path默認(rèn)是跟目錄瀑罗,即“/”,可以由程序設(shè)定為一定的路徑進一步限制cookie的作用范圍胸嘴。

· Expires屬性:設(shè)置cookie的過期日期和時間。不設(shè)置斩祭,cookie生命周期為瀏覽器會話期間劣像,關(guān)閉瀏覽器,cookie消失摧玫。如果設(shè)置了過期時間會將cookie保存在硬盤耳奕,關(guān)閉瀏覽器再次打開只要沒超過設(shè)定時間仍可使用。

· secure 是否使用安全傳輸協(xié)議诬像,HTTPS與SSL等屋群,傳輸數(shù)據(jù)之前先加密,默認(rèn)是false坏挠。

Cookie具有不可跨域名性特點芍躏。

Session

Session是另一種記錄用戶狀態(tài)的機制,與cookie不同的是降狠,session是保存在服務(wù)端对竣,用戶與服務(wù)器建立連接的同時,服務(wù)器會自動分配一個SessionId.

1.session的重要性:Cookie將Sessionid帶到服務(wù)器榜配,用戶提交表單時否纬,瀏覽器將用戶的SessionId自動附加到HTTP頭部信息中,服務(wù)器處理表單結(jié)束后芥牌,將SessionId返回給對應(yīng)的用戶烦味。服務(wù)器通過SessionId作為key,讀寫對應(yīng)的value壁拉,以達到保持會話信息的目的谬俄。

2.session的創(chuàng)建:當(dāng)程序需要為某個客戶端的請求創(chuàng)建一個session時,服務(wù)器首先檢查客戶端的請求里是否已包含了sessionId,如果已經(jīng)包含弃理,說明此前已經(jīng)創(chuàng)建過溃论,服務(wù)器按照sessionId把相應(yīng)的session檢索出來(檢索不到嗎,new一個)痘昌,如果不包含钥勋,則為此客戶端創(chuàng)建一個session并生產(chǎn)一個與此session相關(guān)的sessionID,sessionId值不能重復(fù)又難以偽造辆苔,這個sessionId會被在本次相應(yīng)中返回給客戶端保存算灸。

3.禁用cookie與session共享 禁用cookie:如果客戶端禁用cookie,通常有兩種方式實現(xiàn)session而不依賴cookie
1)URL重寫驻啤,把sessionId直接附加在URL路徑后面 2)表單隱藏字段菲驴。添加一個隱藏字段,在表單提交時候把session id傳遞給服務(wù)器骑冗。 session共享:對于多網(wǎng)站(同一父域不同子域)單服務(wù)器赊瞬,我們需要解決的就是來自不同網(wǎng)站之間SessionId的共享先煎。由于域名不同(aaa.test.com和bbb.test.com),而SessionId又分別儲存在各自的cookie中巧涧,因此服務(wù)器會認(rèn)為對于兩個子站的訪問,是來自不同的會話薯蝎。解決的方法是通過修改cookies的域名為父域名達到cookie共享的目的,從而實現(xiàn)SessionId的共享。帶來的弊端就是谤绳,子站間的cookie信息也同時被共享了占锯。

總結(jié)

· cookie在客戶端,session在服務(wù)端闷供,cookie的產(chǎn)生是在服務(wù)端產(chǎn)生的;

· cookie只是一個通行證烟央,但并不是安全的统诺,任何安全的校驗必須要在服務(wù)端上完成歪脏,cookie只是存在客戶端上面的一個唯一標(biāo)識它且由服務(wù)端定制的信息,本地可以改粮呢,但是不管怎么改婿失,最后還是需要把它拿上發(fā)送給服務(wù)端進行匹配校驗;

· session和cookie的存儲都存在時效性,這是很有必要的;

· 單個cookie保存的數(shù)據(jù)不能超過4kb啄寡,很多瀏覽器都限制了一個站點最多保存20個cookie;

· 不管是cookie還是session豪硅,都是建立在安全性的大前提下,session中不僅僅有cookie的信息挺物,同時會有該用戶的相關(guān)重要且安全的信息存儲懒浮,所以session是在服務(wù)器的,而cookie只是服務(wù)器將一些不重要的信息拿出來丟給客戶的存在识藤,以備以后快速匹配校驗用砚著。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市痴昧,隨后出現(xiàn)的幾起案子稽穆,更是在濱河造成了極大的恐慌,老刑警劉巖赶撰,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舌镶,死亡現(xiàn)場離奇詭異,居然都是意外死亡豪娜,警方通過查閱死者的電腦和手機餐胀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瘤载,“玉大人否灾,你說我怎么就攤上這事√杪牵” “怎么了坟冲?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵磨镶,是天一觀的道長。 經(jīng)常有香客問我健提,道長琳猫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任私痹,我火速辦了婚禮脐嫂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘紊遵。我一直安慰自己账千,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布暗膜。 她就那樣靜靜地躺著匀奏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪学搜。 梳的紋絲不亂的頭發(fā)上娃善,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機與錄音瑞佩,去河邊找鬼聚磺。 笑死,一個胖子當(dāng)著我的面吹牛炬丸,可吹牛的內(nèi)容都是我干的瘫寝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼稠炬,長吁一口氣:“原來是場噩夢啊……” “哼焕阿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酸纲,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捣鲸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后闽坡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栽惶,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年疾嗅,在試婚紗的時候發(fā)現(xiàn)自己被綠了外厂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡代承,死狀恐怖汁蝶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤掖棉,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布墓律,位于F島的核電站,受9級特大地震影響幔亥,放射性物質(zhì)發(fā)生泄漏耻讽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一帕棉、第九天 我趴在偏房一處隱蔽的房頂上張望针肥。 院中可真熱鬧,春花似錦香伴、人聲如沸慰枕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽具帮。三九已至,卻和暖如春崇裁,著一層夾襖步出監(jiān)牢的瞬間匕坯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工拔稳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锹雏。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓巴比,卻偏偏與公主長得像,于是被迫代替她去往敵國和親礁遵。 傳聞我的和親對象是個殘疾皇子轻绞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容