java常用设计模式及其使用场景
設(shè)計(jì)模式的使用場(chǎng)景。
設(shè)計(jì)模式分為?3?大類型共?23?種:
創(chuàng)建型:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結(jié)構(gòu)型:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
行為型:策略模式、模板方法模式、觀察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問(wèn)者模式、中介者模式、解釋器模式。
?
最常見(jiàn)的設(shè)計(jì)模式有:單例模式、工廠模式、代理模式、構(gòu)造者模式、責(zé)任鏈模式、適配器模式、觀察者模式等
?
面試中對(duì)于設(shè)計(jì)模式,你應(yīng)該明白不同的設(shè)計(jì)用來(lái)解決什么場(chǎng)景問(wèn)題,對(duì)于常用的設(shè)計(jì)模式能夠靈活運(yùn)用。下面重點(diǎn)介紹幾種常用的設(shè)計(jì)模式。
?
單例模式
首先是單例模式,這個(gè)模式在實(shí)際業(yè)務(wù)中會(huì)經(jīng)常用到,也是設(shè)計(jì)模式中的主要考察點(diǎn)。這里介紹線程安全的單例模式實(shí)現(xiàn)方式。
單例模式常見(jiàn)的實(shí)現(xiàn)方式有三種。
第一種是靜態(tài)初始化方式,也叫作餓漢方式。實(shí)現(xiàn)的思路就是在類初始化時(shí)完成單例實(shí)例的創(chuàng)建,因此不會(huì)產(chǎn)生并發(fā)問(wèn)題,在這種方式下不管是否會(huì)使用到這個(gè)單例,都會(huì)創(chuàng)建這個(gè)單例。
第二種實(shí)現(xiàn)方式是雙重檢查,也叫作懶漢方式,只有在真正用到這個(gè)單例實(shí)例的時(shí)候才會(huì)去創(chuàng)建,如果沒(méi)有使用就不會(huì)創(chuàng)建。這個(gè)方式必然會(huì)面對(duì)多個(gè)線程同時(shí)使用實(shí)例時(shí)的并發(fā)問(wèn)題。為了解決并發(fā)訪問(wèn)問(wèn)題,通過(guò)?synchronized?或者?lock?進(jìn)行雙重檢查,保證只有一個(gè)線程能夠創(chuàng)建實(shí)例。這里要注意內(nèi)存可見(jiàn)性引起的并發(fā)問(wèn)題,必須使用?volatile?關(guān)鍵字修飾單例變量。
第三種是單例注冊(cè)表方式,Spring?中?Bean?的單例模式就是通過(guò)單例注冊(cè)表方式實(shí)現(xiàn)的。
下面結(jié)合設(shè)計(jì)模式的實(shí)際應(yīng)用,來(lái)介紹常用的設(shè)計(jì)模式,在面試時(shí)遇到類似問(wèn)題,記得要將設(shè)計(jì)模式與實(shí)際業(yè)務(wù)場(chǎng)景進(jìn)行結(jié)合,來(lái)體現(xiàn)對(duì)設(shè)計(jì)模式的理解和應(yīng)用能力。
?
? ???? ? ?
?
?
工廠模式
工廠模式是創(chuàng)建不同類型實(shí)例時(shí)常用的方式,例如?Spring?中的各種?Bean?是有不同?Bean?工廠類進(jìn)行創(chuàng)建的。
?
代理模式
代理模式,主要用在不適合或者不能直接引用另一個(gè)對(duì)象的場(chǎng)景,可以通過(guò)代理模式對(duì)被代理對(duì)象的訪問(wèn)行為進(jìn)行控制。Java?的代理模式分為靜態(tài)代理和動(dòng)態(tài)代理。靜態(tài)代理指在編譯時(shí)就已經(jīng)創(chuàng)建好了代理類,例如在源代碼中編寫的類;動(dòng)態(tài)代理指在?JVM?運(yùn)行過(guò)程中動(dòng)態(tài)創(chuàng)建的代理類,使用動(dòng)態(tài)代理的方法有?JDK?動(dòng)態(tài)代理、CGLIB、Javassist?等。面試時(shí)遇到這個(gè)問(wèn)題可以舉個(gè)動(dòng)態(tài)代理的例子,比如在?Motan RPC?中,是使用?JDK?的動(dòng)態(tài)代理,通過(guò)反射把遠(yuǎn)程請(qǐng)求進(jìn)行封裝,使服務(wù)看上去就像在使用本地的方法。
?
責(zé)任鏈模式
責(zé)任鏈模式有點(diǎn)像工廠的流水線,鏈上每一個(gè)節(jié)點(diǎn)完成對(duì)對(duì)象的某一種處理,例如?Netty?框架在處理消息時(shí)使用的?Pipeline?就是一種責(zé)任鏈模式。
?
適配器模式
適配器模式,類似于我們常見(jiàn)的轉(zhuǎn)接頭,把兩種不匹配的對(duì)象來(lái)進(jìn)行適配,也可以起到對(duì)兩個(gè)不同的對(duì)象進(jìn)行解藕的作用。例如我們常用的日志處理框架?SLF4J,如果我們使用了?SLF4J?就可以跟?Log4j?或者?Logback?等具體的日志實(shí)現(xiàn)框架進(jìn)行解藕。通過(guò)不同適配器將?SLF4J?與?Log4j?等實(shí)現(xiàn)框架進(jìn)行適配,完成日志功能的使用。
?
觀察者模式
觀察者模式也被稱作發(fā)布訂閱模式,適用于一個(gè)對(duì)象的某個(gè)行為需要觸發(fā)一系列事件的場(chǎng)景,例如?gRPC?中的?Stream?流式請(qǐng)求的處理就是通過(guò)觀察者模式實(shí)現(xiàn)的。
?
構(gòu)造者模式
構(gòu)造者模式,適用于一個(gè)對(duì)象有很多復(fù)雜的屬性,需要根據(jù)不同情況創(chuàng)建不同的具體對(duì)象,例如創(chuàng)建一個(gè)?PB?對(duì)象時(shí)使用的?builder?方式。
?
Java?語(yǔ)言特性知識(shí)點(diǎn)
Java?語(yǔ)言特性的知識(shí)點(diǎn)匯總?cè)缦?/p>
?
?? ? ???? ? ?
?
常用集合類實(shí)現(xiàn)與?Java?并發(fā)工具包?JUC?是常見(jiàn)考點(diǎn),JUC?會(huì)在后面的多線程課程中進(jìn)行詳細(xì)講解。
Java?的集合類中部分需要重點(diǎn)了解類的實(shí)現(xiàn)。例如,HashMap、TreeMap?是如何實(shí)現(xiàn)的等。
動(dòng)態(tài)代理與反射是?Java?語(yǔ)言的特色,需要掌握動(dòng)態(tài)代理與反射的使用場(chǎng)景,例如在?ORM?框架中會(huì)大量使用代理類。而?RPC?調(diào)用時(shí)會(huì)使用到反射機(jī)制調(diào)用實(shí)現(xiàn)類方法。
Java?基礎(chǔ)數(shù)據(jù)類型也常常會(huì)在面試中被問(wèn)到,例如各種數(shù)據(jù)類型占用多大的內(nèi)存空間、數(shù)據(jù)類型的自動(dòng)轉(zhuǎn)型與強(qiáng)制轉(zhuǎn)型、基礎(chǔ)數(shù)據(jù)類型與?wrapper?數(shù)據(jù)類型的自動(dòng)裝箱與拆箱等。
Java?對(duì)對(duì)象的引用分為強(qiáng)引用、軟引用、弱引用、虛引用四種,這些引用在?GC?時(shí)的處理策略不同,強(qiáng)引用不會(huì)被?GC?回收;軟引用內(nèi)存空間不足時(shí)會(huì)被?GC?回收;弱引用則在每次?GC?時(shí)被回收;虛引用必須和引用隊(duì)列聯(lián)合使用,主要用于跟蹤一個(gè)對(duì)象被垃圾回收的過(guò)程。
Java?的異常處理機(jī)制就是?try-catch-finally?機(jī)制,需要知道異常時(shí)在?try catch?中的處理流程;需要了解?Error?和?Exception?的區(qū)別。
最后?Java?的注解機(jī)制和?SPI?擴(kuò)展機(jī)制可以作為擴(kuò)展點(diǎn)適當(dāng)了解。
?
詳解?Map
關(guān)于?Java?的基礎(chǔ)知識(shí)重點(diǎn)講解最常考察點(diǎn)?HashMap?和?ConcurrentHashMap,以及?Java?的不同版本新技術(shù)特性
?
?? ? ???? ? ?
?
面試中,Map?的實(shí)現(xiàn)這個(gè)題目能夠考察到數(shù)據(jù)結(jié)構(gòu)、Java?基礎(chǔ)實(shí)現(xiàn)以及對(duì)并發(fā)問(wèn)題處理思路的掌握程度。
?
HashMap
先來(lái)看?HashMap?的實(shí)現(xiàn),簡(jiǎn)單來(lái)說(shuō),Java?的?HashMap?就是數(shù)組加鏈表實(shí)現(xiàn)的,數(shù)組中的每一項(xiàng)是一個(gè)鏈表。通過(guò)計(jì)算存入對(duì)象的?HashCode,來(lái)計(jì)算對(duì)象在數(shù)組中要存入的位置,用鏈表來(lái)解決散列沖突,鏈表中的節(jié)點(diǎn)存儲(chǔ)的是鍵值對(duì)。
除了實(shí)現(xiàn)的方式,我們還需要知道填充因子的作用與?Map?擴(kuò)容時(shí)的?rehash?機(jī)制,需要知道?HashMap?的容量都是?2?的冪次方,是因?yàn)榭梢酝ㄟ^(guò)按位與操作來(lái)計(jì)算余數(shù),比求模要快。另外需要知道?HashMap?是非線程安全的,在多線程?put?的情況下,有可能在容量超過(guò)填充因子時(shí)進(jìn)行?rehash,因?yàn)?HashMap?為了避免尾部遍歷,在鏈表插入元素時(shí)使用頭插法,多線程的場(chǎng)景下有可能會(huì)產(chǎn)生死循環(huán)。
ConcurrentHashMap????
從?HashMap?的非線程安全,面試官很自然地就會(huì)問(wèn)到線程安全的?ConcurrentHashMap。ConcurrentHashMap?采用分段鎖的思想來(lái)降低并發(fā)場(chǎng)景下的鎖定發(fā)生頻率,在?JDK1.7?與?1.8?中的實(shí)現(xiàn)差異非常大,1.7?中使用?Segment?進(jìn)行分段加鎖,降低并發(fā)鎖定;1.8?中使用?CAS?自旋鎖的樂(lè)觀鎖來(lái)提高性能,但是在并發(fā)度較高時(shí)性能會(huì)比較一般。另外?1.8?中的?ConcurrentHashMap?引入了紅黑樹來(lái)解決?Hash?沖突時(shí)鏈表順序查找的問(wèn)題。紅黑樹的啟用條件與鏈表的長(zhǎng)度和?Map?的總?cè)萘坑嘘P(guān),默認(rèn)是鏈表大于?8?且容量大于?64?時(shí)轉(zhuǎn)為紅黑樹。這部分內(nèi)容建議詳細(xì)閱讀源碼進(jìn)行學(xué)習(xí)。
?
詳解 Java 版本特性
? ? ? ? ? ? ?
?
?
Java?近些年一改以往的版本發(fā)布風(fēng)格,發(fā)布頻率提高了很多。目前大部分公司的生產(chǎn)環(huán)境使用的還是?1.8?版本,一少部分升級(jí)到?1.9?或?1.10 版本,Java?的?1.8?版本是一個(gè)長(zhǎng)期支持的版本,最新發(fā)布的?1.11?版本也是一個(gè)長(zhǎng)期支持的版本,1.11?版本中已經(jīng)包含了?1.9、1.10 版本的功能,所以?1.8?和?1.11?版本是我們要重點(diǎn)關(guān)注的版本。
在?1.8?版本中?Java?增加了對(duì)?lambda?表達(dá)式的支持,使?Java?代碼的編寫可以更簡(jiǎn)潔,也更方便支持并行計(jì)算。并且提供了很多?Stream?流式處理的?API。1.8?版本還支持了方法引用的能力,可以進(jìn)一步簡(jiǎn)化?lambda?表達(dá)式的寫法。
在?1.8?版本中,接口可以提供默認(rèn)方法了,這樣可以簡(jiǎn)化一些簡(jiǎn)單的抽象類。最后在?1.8?版本中對(duì)方法區(qū)進(jìn)行調(diào)整,使用?Metaspace?替換掉了?PermGen?的永久代。Metaspace?與?PermGen?之間最大的區(qū)別在于:Metaspace?并不在虛擬機(jī)中,而是使用本地內(nèi)存。替換的目的一方面是可以提升對(duì)元數(shù)據(jù)的管理同時(shí)提升?GC?效率,另一方面是方便后續(xù)?HotSpot?與?JRockit?合并
在?1.9、1.10?版本中的主要特性是增加了模塊系統(tǒng),將?G1?設(shè)為默認(rèn)垃圾回收器、支持局部變量推斷等功能。這些功能都已經(jīng)包含在?1.11?版本中。
1.11?版本是?Java?最新的長(zhǎng)期支持版本,也將會(huì)是未來(lái)一段時(shí)間的主要版本,1.11?版本中提供的最激動(dòng)人心的功能是?ZGC?這個(gè)新的垃圾回收器,ZGC?為大內(nèi)存堆設(shè)計(jì),有著非常強(qiáng)悍的性能,能夠?qū)崿F(xiàn)?10ms?以下的?GC?暫停時(shí)間。關(guān)于?ZGC?會(huì)在下一課中進(jìn)一步介紹。除此之外,1.11?版本對(duì)字符串處理?API?進(jìn)行了增強(qiáng),提供了字符復(fù)制等功能。1.11?版本還內(nèi)置了?HttpClient。
總結(jié)
以上是生活随笔為你收集整理的java常用设计模式及其使用场景的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DOxygen for C++使用说明—
- 下一篇: 微信小程序+.NET(十八) ffmpe