1、Cookie 和 Session的區(qū)別居凶?
Session技術(shù):存到服務(wù)器端借助cookie存儲JSESSIONID
session生命周期
????創(chuàng)建:第一次指定request.getSession();
????銷毀:服務(wù)器關(guān)閉坝撑、session失效/過期脐恩、手動session.invalidate();
session作用范圍:默認(rèn)一會話中
Cookie技術(shù):存到客戶端废菱,cookie以響應(yīng)頭的形式發(fā)送給客戶端咖刃,cookie信息以請求頭的方式發(fā)送到服務(wù)器端的差油,Cookie中不能存儲中文拗军。
2、get 和 post請求的區(qū)別蓄喇?
GET產(chǎn)生一個(gè)TCP數(shù)據(jù)包发侵;POST產(chǎn)生兩個(gè)TCP數(shù)據(jù)包。
對于GET方式的請求公罕,瀏覽器會把http header和data一并發(fā)送出去器紧,服務(wù)器響應(yīng)200;
而對于POST楼眷,瀏覽器先發(fā)送header铲汪,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data罐柳,服務(wù)器響應(yīng)200掌腰。并不是所有瀏覽器都會在POST中發(fā)送兩次包,F(xiàn)irefox就只發(fā)送一次张吉。
3齿梁、WEB容器主要有哪些功能? 并請列出一些常見的WEB容器名字。
作用:通信支持肮蛹、servlet生命周期管理勺择、多線程支持、聲明式實(shí)現(xiàn)安全伦忠、jsp支持
Tomcat省核、JBoss、WebLogic昆码、WebSphere
4气忠、請簡述 Servlet 的生命周期及其相關(guān)的方法邻储?
servlet的生命周期:
a)實(shí)例化,由web容器實(shí)例化servlet實(shí)例
b)初始化旧噪,容器調(diào)用init()方法
c)服務(wù)吨娜,客戶端請求servlet時(shí),容器調(diào)用service()方法
d)銷毀淘钟,結(jié)束服務(wù)調(diào)用destroy()方法
e)垃圾回收
init方法:在一個(gè)Servlet的生命周期中宦赠,init方法只會被執(zhí)行一次,init方法負(fù)責(zé)簡單的創(chuàng)建或者加載一些數(shù)據(jù)米母,這些數(shù)據(jù)將用于該Servlet的整個(gè)生命周期中袱瓮。
service方法:service方法用來處理客戶端的請求,并生成格式化數(shù)據(jù)返回給客戶端爱咬。?每一次請求服務(wù)器都會開啟一個(gè)新的線程并執(zhí)行一次service方法,service根據(jù)客戶端的請求類型绊起,調(diào)用doGet精拟、doPost等方法。?
destroy方法:該方法在整個(gè)生命周期中虱歪,也是只會被調(diào)用一次蜂绎,在Servlet對象被銷毀是調(diào)用,在servlet中笋鄙,我們可以做一些資源的釋放等操作师枣,執(zhí)行destory方法之后的servlet對象,會等待jvm虛擬機(jī)的垃圾回收機(jī)制擇時(shí)回收萧落。
doGet践美、doPost方法:實(shí)際的業(yè)務(wù)處理流程,service根據(jù)客戶端的請求類型來自動匹配需要執(zhí)行哪個(gè)方法找岖。
5陨倡、簡單講講 Tomcat 結(jié)構(gòu),以及其類加載器流程许布?
模塊組成結(jié)構(gòu):Tomcat的核心組件就Connector和Container兴革,一個(gè)Connector+一個(gè)Container(Engine)構(gòu)成一個(gè)Service,Service就是對外提供服務(wù)的組件蜜唾,有了Service組件Tomcat就能對外提供服務(wù)了杂曲,但光有服務(wù)還不行,還需要有環(huán)境讓你提供服務(wù)才行袁余,所以最外層的Server就是為Service提供了生存的土壤擎勘。
Connector是一個(gè)連接器,主要負(fù)責(zé)接受請求并把請求交給Container泌霍,Container就是一個(gè)容器货抄,主要包含具有處理請求的組件述召。Service主要是為了關(guān)聯(lián)Container與Connect,只有兩個(gè)結(jié)合起來才能處理一個(gè)請求蟹地。Server負(fù)責(zé)管理Service集合积暖,具體工作包括:對外提供一個(gè)接口訪問Service,對內(nèi)維護(hù)Service集合怪与,包括管理Service生命周期等夺刑。
<Server>
? ? <Listener />
? ? <GlobaNamingResources></GlobaNamingResources>
? ? <!-- Service包含多個(gè)Connector元素,而這些Connector元素共享一個(gè)Engine元素分别。 -->
? ? <Service>
? ? <!-- Connector元素代表與客戶時(shí)間交互的組件遍愿,它負(fù)責(zé)接收客戶的請求,已經(jīng)向客戶響應(yīng)結(jié)果耘斩,配置http為https主要是修改Connector -->
? ? ? ? <Connector />
? ? ? ? <!-- 每個(gè)Service只能有一個(gè)Engine元素沼填,處理同一個(gè)Service中所有Connector元素接收到的客戶請求,Engine用來處理Connetcor收到的Http請求括授,匹配請求和自己的虛擬主機(jī)坞笙,并把請求轉(zhuǎn)給對應(yīng)的Host來處理 -->
? ? ? ? <Engine>
? ? ? ? ? ? <Logger />
? ? ? ? ? ? <Realm />
? ? ? ? ? ? <!-- 一個(gè)Engine包含多個(gè)host元素,每個(gè)host元素定義了一個(gè)虛擬主機(jī)荚虚,它包含一個(gè)或多個(gè)Web應(yīng)用 -->
? ? ? ? ? ? ? ? <host>
? ? ? ? ? ? ? ? ? ? <Logger />
? ? ? ? ? ? ? ? ? ? <!-- 由Context接口定義薛夜,是使用最頻繁的元素,對應(yīng)于一個(gè)Web App -->
? ? ? ? ? ? ? ? ? ? <Context />
? ? ? ? ? ? ? ? </host>
? ? ? ? </Engine>
? ? </Service>
</Server>
類加載器流程:Tomcat啟動時(shí)版述,會創(chuàng)建以下4種類加載器:
1)Bootstrap引導(dǎo)類加載器:加載JVM啟動所需的類梯澜,以及標(biāo)準(zhǔn)擴(kuò)展類(位于jar/lib/ext上)
2)System系統(tǒng)類加載器:加載Tomcat啟動時(shí)的類,比如bootstrap.jar通常在catalina.bat或catalina.sh中指定渴析。指定位置位于CATALINA_HOME/bin下晚伙。
3)Common通用類加載器:加載tomcat使用以及應(yīng)用通用的一些類,位于CATALINA_HOME/lib下俭茧,比如servlet-api.jar
4)webapp應(yīng)用類加載器:每個(gè)應(yīng)用在創(chuàng)建后撬腾,都會創(chuàng)建一個(gè)唯一的類加載器。該類加載器會加載位于WEB-INF/lib下的jar文件中的class和WEB-INF/classes下的class文件恢恼。
6民傻、CDN實(shí)現(xiàn)原理
CDN全稱是內(nèi)容分發(fā)網(wǎng)絡(luò)。其目的是通過在現(xiàn)有的Internet中增加一層新的網(wǎng)絡(luò)架構(gòu)场斑,將網(wǎng)站的內(nèi)容發(fā)布到最接近用戶的網(wǎng)絡(luò)“邊緣”漓踢,使用戶可以就近取得所需的內(nèi)容,提高用戶訪問網(wǎng)站的響應(yīng)速度漏隐。CDN=更智能的鏡像+緩存+流量導(dǎo)流喧半。
CDN的關(guān)鍵技術(shù):雙重認(rèn)證技術(shù)、負(fù)載均衡青责、內(nèi)容分發(fā)
CDN可簡單的分為核心層和接入層挺据。
1)核心層
核心層作為CDN網(wǎng)絡(luò)層次結(jié)構(gòu)中的頂端取具,核心節(jié)點(diǎn)是整個(gè)CDN網(wǎng)絡(luò)運(yùn)行、管理和維護(hù)的核心扁耐,所有的用戶內(nèi)容請求都會由核心節(jié)點(diǎn)進(jìn)入CDN網(wǎng)絡(luò)暇检,并由CDN網(wǎng)絡(luò)根據(jù)用戶和網(wǎng)絡(luò)的實(shí)際情況,為用戶指定一個(gè)合理的CDN接入層節(jié)點(diǎn)進(jìn)行服務(wù)婉称。完成如下的主要功能:
a)負(fù)責(zé)所有用戶的內(nèi)容請求根據(jù)用戶的信息做出準(zhǔn)確的用戶就近性判斷块仆,并根據(jù)判斷的結(jié)果,將用戶的請求分發(fā)到指定的分節(jié)點(diǎn)王暗。
b)負(fù)責(zé)CDN的內(nèi)容分發(fā)管理把需要服務(wù)的內(nèi)容通過合適的格式和方式悔据,分發(fā)到所有骨干CDN節(jié)點(diǎn)。
2)接入層
接入層作為CDN網(wǎng)絡(luò)的邊緣層俗壹,強(qiáng)調(diào)對用戶的分布式服務(wù)科汗,主要完成的功能包括:
●流媒體平臺的緩存節(jié)點(diǎn),提供分區(qū)高速內(nèi)容緩存绷雏;
●廣播業(yè)務(wù)分布點(diǎn)肛捍,提供兩級應(yīng)用廣播服務(wù);
●部分應(yīng)用前端分布節(jié)點(diǎn)之众;
●通過分布的服務(wù)機(jī)制,提高服務(wù)能力依许,實(shí)現(xiàn)對客戶服務(wù)的需求棺禾。
7、Maven和ANT有什么區(qū)別峭跳?
Ant僅僅是軟件構(gòu)建工具膘婶,而Maven的定位是軟件項(xiàng)目管理和理解工具。Maven除了具備Ant的功能外蛀醉,有以下主要的功能:
使用Project Object Model來對軟件項(xiàng)目管理悬襟;
內(nèi)置了更多的隱式規(guī)則,使得構(gòu)建文件更加簡單拯刁;
內(nèi)置依賴管理和Repository來實(shí)現(xiàn)依賴的管理和統(tǒng)一存儲脊岳;
內(nèi)置了軟件構(gòu)建的生命周期;
8垛玻、什么是restful割捅,講講你理解的restful?
REST:資源(Resources)的表現(xiàn)層狀態(tài)轉(zhuǎn)化帚桩∫诩荩可以用一個(gè)URI(統(tǒng)一資源標(biāo)識符)指向它,每種資源對應(yīng)一個(gè)特定的URI账嚎。
什么是RESTful架構(gòu):
1)每一個(gè)URI代表一種資源莫瞬;
2)客戶端和服務(wù)器之間儡蔓,傳遞這種資源的某種表現(xiàn)層;
3)客戶端通過四個(gè)HTTP動詞疼邀,對服務(wù)器端資源進(jìn)行操作喂江,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
9檩小、Web Server开呐、Web Container 與 Application Server 的區(qū)別是什么?
1)Webserver又名http server:主要處理靜態(tài)網(wǎng)頁http规求,css筐付,代表作apache,nginx阻肿,IIs瓦戚。速度快。
2)Web container(容器)能處理servlet丛塌,asp较解,php,cgi赴邻,但也可以處理靜態(tài)網(wǎng)頁印衔,就是不專業(yè),比如Tomcat姥敛。
3)Application server包括Web container奸焙,還包括JMS、JPA彤敛、Transactions与帆、Concurrency,ejb容器等技術(shù)墨榄,比如weblogic和webSphere玄糟,Sun Application server。tomcat+Spring+hibernate才能達(dá)到Applcaition server的功能袄秩。Application server能處理http阵翎,但不專業(yè)。
10之剧、微服務(wù)(MicroServices)與巨石型應(yīng)用(Monolithic Applications)之間的區(qū)別在哪里贮喧?
巨石型應(yīng)用:將所有功能都部署在一個(gè)web容器中運(yùn)行的系統(tǒng)。
優(yōu)點(diǎn):應(yīng)用不那么復(fù)雜猪狈。
缺點(diǎn):對于大規(guī)模的復(fù)雜應(yīng)用箱沦,巨石型應(yīng)用會顯得特別笨重:要修改一個(gè)地方就要將整個(gè)應(yīng)用全部部署;編譯時(shí)間過長雇庙;回歸測試周期過長谓形;開發(fā)效率降低等灶伊。另外,巨石應(yīng)用不利于更新技術(shù)框架寒跳,除非你愿意將系統(tǒng)全部重寫聘萨。
微服務(wù):將系統(tǒng)劃分為不同的服務(wù),服務(wù)劃分有兩個(gè)原則要遵循:
(1)每個(gè)服務(wù)應(yīng)該盡可能符合單一職責(zé)原則—Single Responsible Principle童太,即每個(gè)服務(wù)只做一件事米辐,并把這件事做好;
(2)參考Unix命令行工具的設(shè)計(jì)书释,Unix提供了大量的簡單易用的工具翘贮,例如grep、cat和find爆惧。每個(gè)工具都小而美狸页。
優(yōu)點(diǎn):
每個(gè)服務(wù)足夠內(nèi)聚,足夠小扯再,代碼容易理解芍耘、開發(fā)效率提高
服務(wù)之間可以獨(dú)立部署,微服務(wù)架構(gòu)讓持續(xù)部署成為可能熄阻;
每個(gè)服務(wù)可以各自進(jìn)行x擴(kuò)展和z擴(kuò)展斋竞,而且,每個(gè)服務(wù)可以根據(jù)自己的需要部署到合適的硬件服務(wù)器上秃殉;
容易擴(kuò)大開發(fā)團(tuán)隊(duì)坝初,可以針對每個(gè)服務(wù)(service)組件開發(fā)團(tuán)隊(duì);
提高容錯(cuò)性(fault isolation)复濒,一個(gè)服務(wù)的內(nèi)存泄露并不會讓整個(gè)系統(tǒng)癱瘓;
系統(tǒng)不會被長期限制在某個(gè)技術(shù)棧上乒省。
缺點(diǎn):
開發(fā)人員要處理分布式系統(tǒng)的復(fù)雜性巧颈;開發(fā)人員要設(shè)計(jì)服務(wù)之間的通信機(jī)制,對于需要多個(gè)后端服務(wù)的user case袖扛,要在沒有分布式事務(wù)的情況下實(shí)現(xiàn)代碼非常困難砸泛;涉及多個(gè)服務(wù)直接的自動化測試也具備相當(dāng)?shù)奶魬?zhàn)性;
服務(wù)管理的復(fù)雜性蛆封,在生產(chǎn)環(huán)境中要管理多個(gè)不同的服務(wù)的實(shí)例唇礁,這意味著開發(fā)團(tuán)隊(duì)需要全局統(tǒng)籌(PS:現(xiàn)在docker的出現(xiàn)適合解決這個(gè)問題)
11、描述 Cookie 和 Session 的作用惨篱,區(qū)別和各自的應(yīng)用范圍盏筐,Session工作原理?
Session:用于保存每個(gè)用戶的專用信息砸讳,每個(gè)客戶端用戶訪問時(shí)琢融,服務(wù)器都為每個(gè)用戶分配一個(gè)唯一的會話ID(Session ID) 界牡, 它的生存期是用戶持續(xù)請求時(shí)間再加上一段時(shí)間(一般是20分鐘左右),Session中的信息保存在Web服務(wù)器內(nèi)容中漾抬,保存的數(shù)據(jù)量可大可小宿亡。當(dāng) Session超時(shí)或被關(guān)閉時(shí)將自動釋放保存的數(shù)據(jù)信息,由于用戶停止使用應(yīng)用程序后它仍然在內(nèi)存中保持一段時(shí)間纳令,因此使用Session對象保存用戶數(shù)據(jù)的方法效率很低挽荠,對于小量的數(shù)據(jù)使用Session對象保存還是一個(gè)不錯(cuò)的選擇。
Cookie:用于保存客戶瀏覽器請求服務(wù)器頁面的請求信息平绩,程序員也可以用它存放非敏感性的用戶信息圈匆,信息保存的時(shí)間可以根據(jù)需要設(shè)置,如果沒有設(shè)置Cookie失效日期馒过,它們僅保存到關(guān)閉瀏覽器程序?yàn)橹钩襞АH绻麑ookie對象的Expires屬性設(shè)置為Minvalue,則表示Cookie永遠(yuǎn)不會過期,Cookie存儲的數(shù)據(jù)量很受限制腹忽,大多數(shù)瀏覽器支持最大容量為4K来累,因此不要用來保存數(shù)據(jù)集及其他大量數(shù)據(jù)。由于并非所有的瀏覽器都支持Cookie窘奏,并且數(shù)據(jù)信息是以明文文本的形式保存在客戶端的計(jì)算機(jī)中嘹锁,因此最好不要保存敏感的,未加密的數(shù)據(jù)着裹,否則會影響網(wǎng)站的安全性领猾。
session工作原理
(1)當(dāng)有Session啟動時(shí),服務(wù)器生成一個(gè)唯一值骇扇,稱為Session ID摔竿。
(2)然后服務(wù)器開辟一塊內(nèi)存,對應(yīng)于該Session ID少孝。
(3)服務(wù)器再將該Session ID寫入瀏覽器的cookie继低。
(4)服務(wù)器內(nèi)有一進(jìn)程,監(jiān)視所有Session的活動狀況稍走,如果有Session超時(shí)或是主動關(guān)閉袁翁,服務(wù)器就釋放該內(nèi)存塊。
(5)當(dāng)瀏覽器連入IIS時(shí)并請求的ASP內(nèi)用到Session時(shí)婿脸,IIS就讀瀏覽器Cookie中的Session ID粱胜。
(6)然后服務(wù)檢查該Session ID所對應(yīng)的內(nèi)存是否有效。
(7)如果有效狐树,就讀出內(nèi)存中的值焙压。
(8)如果無效,就建立新的Session。
12冗恨、什么是基于注解的切面實(shí)現(xiàn)答憔?
AOP :在程序運(yùn)行時(shí),動態(tài)的將代碼切入到類的指定方法掀抹、指定位置上的編程思想就是面向切面編程虐拓。AOP基本上是通過代理機(jī)制實(shí)現(xiàn)的。
總結(jié):Spring實(shí)現(xiàn)AOP傲武,動態(tài)代理技術(shù)的兩種實(shí)現(xiàn)是jdk動態(tài)代理蓉驹、cglib代理,根據(jù)被通知的方法是否為接口方法揪利,來選擇使用哪種代理生成策略态兴。
jdk動態(tài)代理:原理是實(shí)現(xiàn)接口的實(shí)例,攔截定于接口中的目標(biāo)方法疟位,性能更優(yōu)瞻润,是spring生成代理的優(yōu)先選擇。
cglib代理:原理是使用cglib庫中的字節(jié)碼動態(tài)生成技術(shù)甜刻,生成被代理類的子類實(shí)例绍撞,可以攔截代理類中的任一public方法的調(diào)用,無論目標(biāo)方法是否定義與接口中得院,更通用傻铣,但性能相對jdk代理差一些。
13祥绞、IOC的優(yōu)缺點(diǎn)是什么非洲?
優(yōu)點(diǎn):所有的對象都必須創(chuàng)建,我們可以從Ioc容器中直接獲得一個(gè)對象然后直接使用蜕径,無需事先創(chuàng)建它們两踏。
缺點(diǎn):生成一個(gè)對象的步驟變復(fù)雜了,對象生成是使用反射機(jī)制兜喻,在效率上有損耗梦染。
14、解釋一下什么叫AOP(面向切面編程)虹统?
Spring的AOP代理離不開Spring的IOC容器弓坞,代理的生成隧甚、管理及其依賴關(guān)系都是由IOC容器負(fù)責(zé)车荔,默認(rèn)使用JDK動態(tài)代理,在需要代理類而不是代理接口的時(shí)候戚扳,Spring會自動切換為使用CGLIB代理忧便。
1)Aspect(切面):通常是一個(gè)類,里面可以定義切入點(diǎn)和通知
2)JointPoint(連接點(diǎn)):程序執(zhí)行過程中明確的點(diǎn),一般是方法的調(diào)用
3)Advice(通知):AOP在特定的切入點(diǎn)上執(zhí)行的增強(qiáng)處理珠增,before超歌、after、afterReturning蒂教、
afterThrowing巍举、around
4)Pointcut(切入點(diǎn)):就是帶有通知的連接點(diǎn),在程序中主要體現(xiàn)為切入點(diǎn)表達(dá)式
5)AOP代理:AOP框架創(chuàng)建的對象凝垛,代理就是目標(biāo)對象的加強(qiáng)懊悯。Spring中的AOP代理可以使JDK動態(tài)代理,也可以是CGLIB代理梦皮,前者基于接口炭分,后者基于子類。
15剑肯、什么是 Web Service(Web服務(wù))捧毛?
WebService是一種跨編程語言和跨操作系統(tǒng)平臺的遠(yuǎn)程調(diào)用技術(shù)。采用HTTP協(xié)議傳輸數(shù)據(jù)让网,采用XML格式封裝數(shù)據(jù)呀忧。
XML+XSD,SOAP和WSDL就是構(gòu)成WebService平臺的三大技術(shù)。
16、JSWDL開發(fā)包的介紹。JAXP端蛆、JAXM渤早、SOAP、UDDI脯倒、WSDL解釋。
Web ServiceWeb Service是基于網(wǎng)絡(luò)的、分布式的模塊化組件铛碑,它執(zhí)行特定的任務(wù),遵守具體的技術(shù)規(guī)范虽界,這些規(guī)范使得Web Service能與其他兼容的組件進(jìn)行互操作汽烦。
JAXP(Java API for XML Parsing) 定義了在Java中使用DOM, SAX, XSLT的通用的接口。
JAXM(Java API for XML Messaging) 是為SOAP通信提供訪問方法和傳輸機(jī)制的API莉御。
SOAP即簡單對象訪問協(xié)議(Simple Object Access Protocol)撇吞,它是用于交換XML編碼信息的輕量級協(xié)議。
UDDI是一套基于Web的礁叔、分布式的牍颈、為Web?Service提供的、信息注冊中心的實(shí)現(xiàn)標(biāo)準(zhǔn)規(guī)范琅关,同時(shí)也包含一組使企業(yè)能將自身提供的Web Service注冊煮岁,以使別的企業(yè)能夠發(fā)現(xiàn)的訪問協(xié)議的實(shí)現(xiàn)標(biāo)準(zhǔn)。
WSDL是一種XML格式,用于將網(wǎng)絡(luò)服務(wù)描述為一組端點(diǎn)画机,這些端點(diǎn)對包含面向文檔信息或面向過程信息的消息進(jìn)行操作冶伞。這種格式首先對操作和消息進(jìn)行抽象描述,然后將其綁定到具體的網(wǎng)絡(luò)協(xié)議和消息格式上以定義端點(diǎn)步氏。相關(guān)的具體端點(diǎn)即組合成為抽象端點(diǎn)(服務(wù))响禽。
17、RPC 通信和RMI區(qū)別荚醒?
1)方法調(diào)用方式不同:
? RMI中是通過在客戶端的Stub對象作為遠(yuǎn)程接口進(jìn)行遠(yuǎn)程方法的調(diào)用金抡。每個(gè)遠(yuǎn)程方法都具有方法簽名。如果一個(gè)方法在服務(wù)器上執(zhí)行腌且,但是沒有相匹配的簽名被添加到這個(gè)遠(yuǎn)程接口(stub)上梗肝,那么這個(gè)新方法就不能被RMI客戶方所調(diào)用。
? RPC中是通過網(wǎng)絡(luò)服務(wù)協(xié)議向遠(yuǎn)程主機(jī)發(fā)送請求铺董,請求包含了一個(gè)參數(shù)集和一個(gè)文本值巫击,通常形成“classname.methodname(參數(shù)集)”的形式。RPC遠(yuǎn)程主機(jī)就去搜索與之相匹配的類和方法精续,找到后就執(zhí)行方法并把結(jié)果編碼坝锰,通過網(wǎng)絡(luò)協(xié)議發(fā)回。
?2)適用語言范圍不同:
? RMI只用于Java重付;
? RPC是網(wǎng)絡(luò)服務(wù)協(xié)議顷级,與操作系統(tǒng)和語言無關(guān)。
?3)調(diào)用結(jié)果的返回形式不同:
? Java是面向?qū)ο蟮娜返妫訰MI的調(diào)用結(jié)果可以是對象類型或者基本數(shù)據(jù)類型弓颈;
? RMI的結(jié)果統(tǒng)一由外部數(shù)據(jù)表示 (External Data Representation, XDR) 語言表示,這種語言抽象了字節(jié)序類和數(shù)據(jù)類型結(jié)構(gòu)之間的差異删掀。
18翔冀、什么是 N 層架構(gòu)?
分層架構(gòu)的一個(gè)重要原則是:每層只能與位于其下方的層發(fā)生耦合
19披泪、什么是CORBA纤子?用途是什么?
CORBA(Common Object Request Broker Architecture:公共對象請求代理體系結(jié)構(gòu)款票,通用對象請求代理體系結(jié)構(gòu))是由OMG組織制訂的一種標(biāo)準(zhǔn)的面向?qū)ο髴?yīng)用程序體系規(guī)范控硼。
用途:
1)存取來自現(xiàn)行桌面應(yīng)用程序的分布信息和資源;
2)使現(xiàn)有業(yè)務(wù)數(shù)據(jù)和系統(tǒng)成為可供利用的網(wǎng)絡(luò)資源艾少;
3)為某一特定業(yè)務(wù)用的定制的功能和能力來增強(qiáng)現(xiàn)行桌面工具和應(yīng)用程序卡乾;
4)改變和發(fā)展基于網(wǎng)絡(luò)的系統(tǒng)以反映新的拓?fù)浣Y(jié)構(gòu)或新資源;
20姆钉、什么是懶加載(Lazy Loading)说订?
“懶加載模式”又叫“懶漢模式”是指當(dāng)?shù)谝淮问褂玫竭@個(gè)屬性時(shí)才給這個(gè)屬性對應(yīng)的成員變量進(jìn)行初始化,如果程序還沒運(yùn)行到這個(gè)地方就不進(jìn)行相應(yīng)的創(chuàng)建和初始化有利于節(jié)省資源提高性能潮瓶。與之對應(yīng)的還用一種模式叫做“餓漢模式”就是程序一啟動就初始化相應(yīng)的成員變量陶冷,不管當(dāng)時(shí)有沒有用到先創(chuàng)建并初始化了再說,所以這種模式相對來說不需要程序員考慮那么詳細(xì)毯辅,會耗費(fèi)一點(diǎn)資源埂伦。
21、什么是尾遞歸思恐,為什么需要尾遞歸沾谜?
尾遞歸是指所有遞歸形式的調(diào)用,一定是發(fā)生在函數(shù)的末尾胀莹。形式上只要最后一個(gè)return語句是單純函數(shù)就可以基跑。
尾遞歸的好處:
尾遞歸和一般的遞歸不同在對內(nèi)存的占用,普通遞歸創(chuàng)建stack累積而后計(jì)算收縮描焰,尾遞歸只會占用恒量的內(nèi)存(和迭代一樣)媳否。
JVM本身是不支持尾遞歸優(yōu)化的,需要編譯器支持荆秦,而Java編譯器不支持篱竭,但是Scala支持。
22步绸、什么是控制反轉(zhuǎn)(Inversion of Control)與依賴注入(Dependency Injection)掺逼?
IoC (Inversion of Control),把對象的操控調(diào)用權(quán)交給容器瓤介,通過容器來實(shí)現(xiàn)對象組件的裝配和管理吕喘。所謂的“控制反轉(zhuǎn)”就是對組件對象控制權(quán)的轉(zhuǎn)移,從程序代碼本身轉(zhuǎn)移到了外部容器刑桑。
IoC主要實(shí)現(xiàn)方式有兩種:
1)依賴查找(Dependency Lookup):容器提供回調(diào)接口和上下文環(huán)境給組件兽泄。
2)依賴注入(Dependency Injection):組件不做定位查詢,只提供普通的Java方法讓容器去決定依賴關(guān)系漾月。后者是時(shí)下最流行的IoC類型病梢,其又有接口注入(Interface Injection),設(shè)值注入(Setter Injection)和構(gòu)造函數(shù)注入(Constructor Injection)三種方式梁肿。
23蜓陌、XML文檔定義有幾種形式?它們之間有何本質(zhì)區(qū)別吩蔑?解析XML有哪幾種方式钮热?DOM和SAX解析器有什么不同?
兩種形式:dtd烛芬、schema
區(qū)別:schema本身是xml的隧期,可以被XML解析器解析(這也是從DTD上發(fā)展schema的根本目的)飒责;
有DOM、SAX仆潮、STAX等方式
DOM:處理大型文件時(shí)性能下降的非常厲害宏蛉。這是由DOM的樹結(jié)構(gòu)造成的,這種結(jié)構(gòu)占用的內(nèi)存較多性置,而且DOM必須在解析文件前把整個(gè)文檔裝入內(nèi)存拾并,適合對XML的隨機(jī)訪問。
SAX:不限于DOM鹏浅,SAX是事件驅(qū)動型的XML解析方式嗅义。它順序讀取XML文件,不需要一次全部裝載整個(gè)文件隐砸。當(dāng)遇到像文件開頭之碗,文檔結(jié)束,或者標(biāo)簽開頭與標(biāo)簽結(jié)束時(shí)季希,它會觸發(fā)一個(gè)事件继控,用戶通過在其回調(diào)事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問胖眷。
STAX:Streaming API for XML (StAX)
24武通、Java解析XML的方式
XML解析方式分為四種:DOM、SAX珊搀、JDOM冶忱、DOM4J。
25境析、用jdom解析xml文件時(shí)如何解決中文問題囚枪?
XMLOutputter docWriter = new XMLOutputter();?
docWriter.setFormat(Format.getCompactFormat().setEncoding("GB2312"));
26、描述動態(tài)代理的幾種實(shí)現(xiàn)方式劳淆,分別說出相應(yīng)的優(yōu)缺點(diǎn)链沼?
動態(tài)代理有Java Proxy,CGLib沛鸵,JAVAssist等方式括勺。
jdk動態(tài)代理是由Java內(nèi)部的反射機(jī)制來實(shí)現(xiàn)的,cglib動態(tài)代理底層則是借助asm來實(shí)現(xiàn)的曲掰〖埠矗總的來說,反射機(jī)制在生成類的過程中比較高效栏妖,而asm在生成類之后的相關(guān)執(zhí)行過程中比較高效(可以通過將asm生成的類進(jìn)行緩存乱豆,這樣解決asm生成類過程低效問題)。注意:jdk動態(tài)代理的應(yīng)用前提吊趾,目標(biāo)類必須是基于統(tǒng)一的接口宛裕。
27瑟啃、解釋什么是MESI協(xié)議(緩存一致性)?
m:modified
e:exlusive
s:shared
i:invalid
四種狀態(tài)的轉(zhuǎn)換略過揩尸,現(xiàn)在討論為什么有這個(gè)協(xié)議蛹屿,i++在多線程上不是安全的。
兩個(gè)cpu A B同時(shí)執(zhí)行i++操作疲酌,假設(shè)i初始值為0
A讀入i,緩存行狀態(tài)為E
B讀入i了袁,發(fā)現(xiàn)A有朗恳,那么設(shè)置為s,A里面也設(shè)置為S
A cpu處理载绿,i值+1等于1粥诫,但只是在寄存器中,沒寫入緩存崭庸,此時(shí)狀態(tài)還是S
B cpu處理怀浆,i值+1等于1,同上還是S
A寫入緩存怕享,i值為1执赡,緩存行狀態(tài)為M,此時(shí)B的緩存行狀態(tài)為I(無效)
B cpu寫入的時(shí)候函筋,發(fā)現(xiàn)緩存行無效沙合,需要從內(nèi)存讀取,此時(shí)發(fā)現(xiàn)A的緩存行中有且為M狀態(tài)跌帐,那么要求A刷新入內(nèi)存首懈,此時(shí)內(nèi)存的i為1,A的緩存行為E谨敛,B讀入自己的緩存(還是從A那里獲染柯摹?)脸狸,此時(shí)AB的緩存行都為S最仑,i值都為1
B cpu寫入,注意炊甲,此時(shí)是把1盯仪,賦值給1,B的狀態(tài)為M蜜葱,A為I(以后略)
這樣就看出來了全景,緩存一致性協(xié)議是保證不了內(nèi)存一致性的。
28牵囤、談?wù)剅eactor模型
Reactor模型和AWT事件模型很像爸黄,就是將消息放到一個(gè)隊(duì)列中滞伟,通過異步線程池對其進(jìn)行消費(fèi)。
29炕贵、UML中有哪些常用的圖
UML定義了多種圖形化的符號來描述軟件系統(tǒng)部分或全部的靜態(tài)結(jié)構(gòu)和動態(tài)結(jié)構(gòu)梆奈,包括:用例圖(use case diagram)、類圖(class diagram)称开、時(shí)序圖(sequence diagram)亩钟、協(xié)作圖(collaboration diagram)、狀態(tài)圖(statechart diagram)鳖轰、活動圖(activity diagram)清酥、構(gòu)件圖(component diagram)、部署圖(deployment diagram)等蕴侣。
有三種圖最為重要焰轻,分別是:
用例圖(用來捕獲需求,描述系統(tǒng)的功能昆雀,通過該圖可以迅速的了解系統(tǒng)的功能模塊及其關(guān)系)
類圖(描述類以及類與類之間的關(guān)系辱志,通過該圖可以快速了解系統(tǒng))
時(shí)序圖(描述執(zhí)行特定任務(wù)時(shí)對象之間的交互關(guān)系以及執(zhí)行順序,通過該圖可以了解對象能接收的消息也就是說對象能夠向外界提供的服務(wù))狞膘。
30揩懒、什么是 N+1 難題
1+n是執(zhí)行一次查詢獲取n條主數(shù)據(jù)后,由于關(guān)聯(lián)引起的執(zhí)行n次查詢從數(shù)據(jù)挽封;它帶來了性能問題旭从;一般來說,通過懶加載可以部分緩解1+n帶來的性能問題场仲。
31和悦、介紹一下了解的 Java 領(lǐng)域的 Web Service 框架
開發(fā)Web Service的幾個(gè)框架,分別為Axis渠缕,Axis2鸽素,Xfire,CXF以及JWS亦鳞。
XFire:
XFire是一個(gè)高性能的WebService框架馍忽,優(yōu)點(diǎn)是開發(fā)方便,與現(xiàn)有的Web整合很好燕差,并且開發(fā)也很方便遭笋。但是對Java之外的語言,沒有提供相關(guān)的代碼工具徒探。
1瓦呼、支持一系列Web Service的新標(biāo)準(zhǔn)--JSR181、WSDL2.0 测暗、JAXB2央串、WS-Security等磨澡;?
2、使用Stax解釋XML,性能有了質(zhì)的提高质和。XFire采用Woodstox 作Stax實(shí)現(xiàn)稳摄;?
3、容易上手饲宿,可以方便快速地從pojo發(fā)布服務(wù)厦酬;?
4、Spring的結(jié)合瘫想;?
5仗阅、靈活的Binding機(jī)制,包括默認(rèn)的Aegis,xmlbeans,jaxb2,castor殿托。
XFire與Axis1性能的比較?
1霹菊、XFire比Axis1.3快2-6倍?
2剧蚣、XFire的響應(yīng)時(shí)間是Axis1.3的1/2到1/5
Axis2:
Axis2是Apache下的一個(gè)重量級WebService框架支竹,準(zhǔn)確說它是一個(gè)Web Services / SOAP / WSDL的引擎,是WebService框架的集大成者鸠按,它不但能制作和發(fā)布WebService礼搁,而且可以生成Java和其他語言版WebService客戶端和服務(wù)端代碼。這是它的優(yōu)勢所在目尖。但是馒吴,這也不可避免的導(dǎo)致了Axis2的復(fù)雜性,打包部署發(fā)布都比較麻煩瑟曲,不能很好的與現(xiàn)有應(yīng)用整合為一體饮戳。但是如果你要開發(fā)Java之外別的語言客戶端,Axis2提供的豐富工具將是你不二的選擇洞拨。
Axis2的開發(fā)方式類似一個(gè)小型的應(yīng)用服務(wù)器扯罐,Axis2的開發(fā)包要以WAR的形式部署到Servlet容器中,比如Tomcat烦衣,通過這些容器可以對工作中的Web Service進(jìn)行很好的監(jiān)控和管理歹河。Axis2的Web administrion模塊可以讓我們動態(tài)的配置Axis2。一個(gè)新的服務(wù)可以上載花吟,激活秸歧,使之失效,修改web服務(wù)的參數(shù)衅澈。管理UI也可以管理一個(gè)或者多個(gè)處于運(yùn)行狀態(tài)的服務(wù)键菱。這種界面化管理方式的一個(gè)弊端是所有在運(yùn)行時(shí)修改的參數(shù)沒有辦法保存,因?yàn)樵谥貑又蠼癫迹闼龅男薷木蜁渴闯堋xis2允許自己作為獨(dú)立的應(yīng)用來發(fā)布Web Service芭梯,并提供了大量的功能和一個(gè)很好的模型,這個(gè)模型可以通過它本身的架構(gòu)(modular architecture)不斷添加新的功能弄喘。
CXF:
CXF是Apache下一個(gè)重磅的SOA簡易框架玖喘,它實(shí)現(xiàn)了ESB(企業(yè)服務(wù)總線),來自于XFire項(xiàng)目,CXF不但是一個(gè)優(yōu)秀的Web Services / SOAP / WSDL 引擎蘑志,也是一個(gè)不錯(cuò)的ESB總線累奈,為SOA的實(shí)施提供了一種選擇方案,當(dāng)然他不是最好的急但,它僅僅實(shí)現(xiàn)了SOA架構(gòu)的一部分澎媒。
CXF更注重開發(fā)人員的工效(ergonomics)和嵌入能力(embeddability)。大多數(shù)都可以通過配置API來完成波桩,替代了比較繁瑣的XML配置文件戒努, Spring的集成性經(jīng)常的被提及,CXF支持Spring2.0和CXF's API和Spring的配置文件可以非常好的對應(yīng)镐躲。CXF強(qiáng)調(diào)代碼優(yōu)先的設(shè)計(jì)方式(code-first design)储玫,使用了簡單的API使得從現(xiàn)有的應(yīng)用開發(fā)服務(wù)變得方便。
JWS:
JWS是Java語言對WebService服務(wù)的一種實(shí)現(xiàn)萤皂,用來開發(fā)和發(fā)布服務(wù)撒穷。而從服務(wù)本身的角度來看JWS服務(wù)是沒有語言界限的。
如何抉擇:?
1裆熙、如果應(yīng)用程序需要多語言的支持端礼,Axis2是首選;?
2入录、如果應(yīng)用程序是遵循Spring哲學(xué)路線的話蛤奥,Apache CXF是一種更好的選擇,特別對嵌入式的 Web Services來說僚稿;?
3凡桥、如果應(yīng)用程序沒有新的特性需要的話,就仍是用原來項(xiàng)目所用的框架贫奠,比如 Axis1唬血,XFire
32、Nginx唤崭、lighttpd拷恨、Apache三大主流 Web服務(wù)器的區(qū)別?
(1) lighttpd
Lighttpd有非常低的內(nèi)存開銷谢肾,cpu占用率低腕侄,效能好,以及豐富的模塊等特點(diǎn)。支持FastCGI, CGI, Auth, 輸出壓縮(output compress), URL重寫, Alias等重要功能冕杠。Lighttpd使用fastcgi方式運(yùn)行php,它會使用很少的PHP進(jìn)程響應(yīng)很大的并發(fā)量微姊。
Fastcgi的優(yōu)點(diǎn)在于:
從穩(wěn)定性上看, fastcgi是以獨(dú)立的進(jìn)程池運(yùn)行來cgi,單獨(dú)一個(gè)進(jìn)程死掉,系統(tǒng)可以很輕易的丟棄,然后重新分配新的進(jìn)程來運(yùn)行邏輯.
從安全性上看, fastcgi和宿主的server完全獨(dú)立, fastcgi怎么down也不會把server搞垮,
從性能上看, fastcgi把動態(tài)邏輯的處理從server中分離出來, 大負(fù)荷的IO處理留給宿主server
從擴(kuò)展性上講, fastcgi是一個(gè)中立的技術(shù)標(biāo)準(zhǔn), 完全可以支持任何語言寫的處理程序
(2)apache
????1) 幾乎可以運(yùn)行在所有的計(jì)算機(jī)平臺上
????2) 支持最新的http/1.1協(xié)議
????3) 簡單而且強(qiáng)有力的基于文件的配置(httpd.conf)
????4) 支持通用網(wǎng)關(guān)接口(cgi)
????5) 支持虛擬主機(jī)
????6) 支持http認(rèn)證
????7) 集成perl
????8) 集成的代理服務(wù)器
????9) 可以通過web瀏覽器監(jiān)視服務(wù)器的狀態(tài), 可以自定義日志
????10) 支持服務(wù)器端包含命令(ssi)
????11) 支持安全socket層(ssl)
????12) 具有用戶會話過程的跟蹤能力
????13) 支持fastcgi
????14) 支持java servlets
(3)nginx
是一個(gè)高性能的HTTP和反向代理服務(wù)器,同時(shí)也是一個(gè)IMAP/POP3/SMTP 代理服務(wù)器分预。
Nginx以事件驅(qū)動的方式編寫兢交,所以有非常好的性能,同時(shí)也是一個(gè)非常高效的反向代理笼痹、負(fù)載平衡配喳。其擁有匹配Lighttpd的性能,同時(shí)還沒有Lighttpd的內(nèi)存泄漏問題凳干。但是Nginx并不支持cgi方式運(yùn)行晴裹,原因是可以減少因此帶來的一些程序上的漏洞。所以必須使用FastCGI方式來執(zhí)行PHP程序救赐。
nginx做為HTTP服務(wù)器涧团,有以下幾項(xiàng)基本特性:
處理靜態(tài)文件,索引文件以及自動索引经磅;打開文件描述符緩沖.
無緩存的反向代理加速泌绣,簡單的負(fù)載均衡和容錯(cuò).
FastCGI,簡單的負(fù)載均衡和容錯(cuò).
模塊化的結(jié)構(gòu)馋贤。包括gzipping, byte ranges, chunked responses,以及SSI-filter等filter赞别。如果由FastCGI或其它代理服務(wù)器處理單頁中存在的多個(gè)SSI畏陕,則這項(xiàng)處理可以并行運(yùn)行配乓,而不需要相互等待。
Nginx專為性能優(yōu)化而開發(fā)惠毁,性能是其最重要的考量,實(shí)現(xiàn)上非常注重效率犹芹。它支持內(nèi)核Poll模型,能經(jīng)受高負(fù)載的考驗(yàn),有報(bào)告表明能支持高達(dá)50,000個(gè)并發(fā)連接數(shù)鞠绰。
Nginx具有很高的穩(wěn)定性腰埂。其它HTTP服務(wù)器,當(dāng)遇到訪問的峰值蜈膨,或者有人惡意發(fā)起慢速連接時(shí)屿笼,也很可能會導(dǎo)致服務(wù)器物理內(nèi)存耗盡頻繁交換,失去響應(yīng)翁巍,只能重啟服務(wù)器驴一。例如當(dāng)前apache一旦上到200個(gè)以上進(jìn)程,web響應(yīng)速度就明顯非常緩慢了灶壶。而Nginx采取了分階段資源分配技術(shù)肝断,使得它的CPU與內(nèi)存占用率非常低。nginx官方表示保持10,000個(gè)沒有活動的連接,它只占2.5M內(nèi)存胸懈,所以類似DOS這樣的攻擊對nginx來說基本上是毫無用處的担扑。就穩(wěn)定性而言,nginx比lighthttpd更勝一籌。
Nginx支持熱部署趣钱。它的啟動特別容易, 并且?guī)缀蹩梢宰龅?*24不間斷運(yùn)行涌献,即使運(yùn)行數(shù)個(gè)月也不需要重新啟動。你還能夠在不間斷服務(wù)的情況下首有,對軟件版本進(jìn)行進(jìn)行升級洁奈。
(二)3種WEB服務(wù)器的比較:
Apache 后臺服務(wù)器(主要處理php及一些功能請求 如:中文url)
Nginx ?前端服務(wù)器(利用它占用系統(tǒng)資源少得優(yōu)勢來處理靜態(tài)頁面大量請求)
Lighttpd 圖片服務(wù)器
33、HTTP連接池實(shí)現(xiàn)原理
http連接池就是一個(gè)池子绞灼,里面裝滿了連接利术,有兩個(gè)特征:
1)連接池里面保存著可以馬上通信的連接,免除了重新建立連接的麻煩
2)連接如果長期不用低矮,就會掛斷印叁。
三個(gè)步驟:
1)查看有沒有過期的連接,有則干掉
2)查看空閑的連接是不是過多军掂,按時(shí)間順序干掉一部分轮蜕,先把老的干掉
3)如果沒有東西要清理,清理線程則休息一下蝗锥。當(dāng)有連接進(jìn)入的時(shí)候跃洛,就繼續(xù)干活。
34终议、HTTPS和HTTP的區(qū)別
1)https協(xié)議需要到ca申請證書汇竭,一般免費(fèi)證書較少,因而需要一定費(fèi)用穴张。
2)http是超文本傳輸協(xié)議细燎,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議皂甘。
3)http和https使用的是完全不同的連接方式玻驻,用的端口也不一樣,前者是80偿枕,后者是443璧瞬。
4)http的連接很簡單,是無狀態(tài)的渐夸;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸嗤锉、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全捺萌。
35档冬、HTTPS 的加密方式是什么膘茎,講講整個(gè)加密解密流程
HTTPS其實(shí)是有兩部分組成:HTTP + SSL / TLS,也就是在HTTP上又加了一層處理加密信息的模塊酷誓。服務(wù)端和客戶端的信息傳輸都會通過TLS進(jìn)行加密披坏,所以傳輸?shù)臄?shù)據(jù)都是加密后的數(shù)據(jù)。
1)客戶端發(fā)起HTTPS請求
2)服務(wù)端的配置
采用HTTPS協(xié)議的服務(wù)器必須要有一套數(shù)字證書盐数,可以自己制作棒拂,也可以向組織申請。區(qū)別就是自己頒發(fā)的證書需要客戶端驗(yàn)證通過玫氢,才可以繼續(xù)訪問帚屉,而使用受信任的公司申請的證書則不會彈出提示頁面。這套證書其實(shí)就是一對公鑰和私鑰漾峡。
3)傳送證書
這個(gè)證書其實(shí)就是公鑰攻旦,只是包含了很多信息,如證書的頒發(fā)機(jī)構(gòu)生逸,過期時(shí)間等等牢屋。
4)客戶端解析證書
這部分工作是有客戶端的TLS來完成的,首先會驗(yàn)證公鑰是否有效槽袄,比如頒發(fā)機(jī)構(gòu)烙无,過期時(shí)間等等,如果發(fā)現(xiàn)異常遍尺,則會彈出一個(gè)警告框截酷,提示證書存在問題。如果證書沒有問題乾戏,那么就生成一個(gè)隨機(jī)值迂苛。然后用證書對該隨機(jī)值進(jìn)行加密。
5)傳送加密信息
這部分傳送的是用證書加密后的隨機(jī)值歧蕉,目的就是讓服務(wù)端得到這個(gè)隨機(jī)值灾部,以后客戶端和服務(wù)端的通信就可以通過這個(gè)隨機(jī)值來進(jìn)行加密解密了康铭。
6)服務(wù)段解密信息
服務(wù)端用私鑰解密后惯退,得到了客戶端傳過來的隨機(jī)值(私鑰),然后把內(nèi)容通過該值進(jìn)行對稱加密从藤。所謂對稱加密就是催跪,將信息和私鑰通過某種算法混合在一起,這樣除非知道私鑰夷野,不然無法獲取內(nèi)容懊蒸,而正好客戶端和服務(wù)端都知道這個(gè)私鑰,所以只要加密算法夠彪悍悯搔,私鑰夠復(fù)雜骑丸,數(shù)據(jù)就夠安全。
7)傳輸加密后的信息
這部分信息是服務(wù)端用私鑰加密后的信息,可以在客戶端被還原通危。
8)客戶端解密信息
客戶端用之前生成的私鑰解密服務(wù)端傳過來的信息铸豁,于是獲取了解密后的內(nèi)容皆辽。整個(gè)過程第三方即使監(jiān)聽到了數(shù)據(jù)芍锦,也束手無策。
36调塌、什么是領(lǐng)域模型(domain model)逆害?貧血模型(anaemic domain model) 和充血模型(rich domain model)有什么區(qū)別?
領(lǐng)域模型:是領(lǐng)域內(nèi)的概念類或現(xiàn)實(shí)世界中對象的可視化表示头镊,又稱為概念模型或分析對象模型,它專注于分析問題領(lǐng)域本身魄幕,發(fā)掘重要的業(yè)務(wù)領(lǐng)域概念相艇,并建立業(yè)務(wù)領(lǐng)域概念之間的關(guān)系。
貧血模型:是指使用的領(lǐng)域?qū)ο笾兄挥衧etter和getter方法(POJO)纯陨,所有的業(yè)務(wù)邏輯都不包含在領(lǐng)域?qū)ο笾卸欠旁跇I(yè)務(wù)邏輯層厂捞。有人將貧血模型進(jìn)一步劃分成失血模型(領(lǐng)域?qū)ο笸耆珱]有業(yè)務(wù)邏輯)和貧血模型(領(lǐng)域?qū)ο笥猩倭康臉I(yè)務(wù)邏輯)。
充血模型:將大多數(shù)業(yè)務(wù)邏輯和持久化放在領(lǐng)域?qū)ο笾卸铀浚瑯I(yè)務(wù)邏輯只是完成對業(yè)務(wù)邏輯的封裝靡馁、事務(wù)和權(quán)限等處理。
37机久、什么是領(lǐng)域驅(qū)動開發(fā)(Domain Driven Development)
將問題抽象為一個(gè)領(lǐng)域解決方案臭墨。并針對此領(lǐng)域(即抽象)進(jìn)行開發(fā)的方式。
解決兩個(gè)問題:變化膘盖、復(fù)雜度胧弛。
38、反射機(jī)制提供了什么功能侠畔?
1)在運(yùn)行時(shí)判斷任意一個(gè)對象所屬的類结缚;
2)在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對象;
3)在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法软棺;
4)在運(yùn)行時(shí)調(diào)用任意一個(gè)對象的方法红竭;
5)生成動態(tài)代理;
39喘落、反射是如何實(shí)現(xiàn)的茵宪?
1)通過Class.forName()方法加載字符串,就可以得到該字符串做代表的Class對象瘦棋。
2)通過類名調(diào)用class屬性得到該類的Class對象稀火。
3)調(diào)用實(shí)例的getClass()方法。
4)如果是基本類型的包裝類赌朋,則可以通過調(diào)用包裝類的Type屬性來獲得該包裝類的Class對象凰狞。
40篇裁、哪里用到反射機(jī)制?
Tomcat服務(wù)器
41赡若、反射中 Class.forName 和 ClassLoader 區(qū)別茴恰?
Class.forName(className)方法,內(nèi)部實(shí)際調(diào)用的方法是Class.forName(className,true,classloader);
第2個(gè)boolean參數(shù)斩熊,表示類是否需要初始化往枣,Class.forName(className)默認(rèn)是需要初始化。
一旦初始化粉渠,就會觸發(fā)目標(biāo)對象的static塊代碼執(zhí)行分冈,static參數(shù)也也會被再次初始化。
ClassLoader.loadClass(className)方法霸株,內(nèi)部實(shí)際調(diào)用的方法是? ClassLoader.loadClass(className,false);
第2個(gè)boolean參數(shù)雕沉,表示目標(biāo)對象是否進(jìn)行鏈接,false表示不進(jìn)行鏈接去件,意味著不進(jìn)行包括初始化等一些列步驟坡椒,那么靜態(tài)塊和靜態(tài)對象就不會得到執(zhí)行。
42尤溜、反射創(chuàng)建類實(shí)例的三種方式是什么倔叼?
第一種,使用Class.forName靜態(tài)方法宫莱。已明確類的全路徑名丈攒。
第二種,使用.class 方法授霸。僅適合在編譯前就已經(jīng)明確要操作的Class
第三種巡验,使用類對象的 getClass() 方法,適合有對象示例的情況下
43碘耳、如何通過反射調(diào)用對象的方法显设?
1)通過Class.forName(“包名+方法的類名”)拿到方法的對象;
2)明確反射方法名稱 ;
3)明確方法的參數(shù)類型,就可以拿到對象的方法辛辨。
如:Method method = clazz.getMethod("test",String.class,int.class)捕捂;
4)用invoke()調(diào)用方法
Object?obj1?=?method.invoke(clazz.newInstance(),"test",23);
44、如何通過反射獲取和設(shè)置對象私有字段的值愉阎?
通過類對象的getDeclaredField()方法字段對象绞蹦,再通過字段對象的setAccessible(true)將其設(shè)置為可以訪問,就可以通過get/set方法來獲取/設(shè)置字段的值榜旦。
45、反射機(jī)制的優(yōu)缺點(diǎn)景殷?
優(yōu)點(diǎn):可以實(shí)現(xiàn)動態(tài)創(chuàng)建對象和編譯溅呢,體現(xiàn)出很大的靈活性
缺點(diǎn):對性能有影響澡屡,使用反射基本上是一種解釋操作
46、什么是 paxos 算法咐旧?
在paxos算法中分為4種角色:Proposer(提議者)驶鹉、Acceptor(決策者)、Client(產(chǎn)生議題者)铣墨、Learner(最終決策學(xué)習(xí)者)
上面4種角色中室埋,提議者和決策者是很重要的,Proposer就像Client的使者伊约,由Proposer使者拿著Client的議題去向Acceptor提議姚淆,讓Acceptor來決策。Acceptor必須是最少大于等于3個(gè)屡律,并且必須是奇數(shù)個(gè)腌逢,因?yàn)橐纬啥鄶?shù)派。該算法就是為了追求結(jié)果的一致性超埋。
paxos算法中所有的行為:
1)Proposer提出議題
2)Acceptor初步接受或者Acceptor初步不接受
3)如果上一步Acceptor初步接受則Proposer再次向Acceptor確認(rèn)是否最終接受
4)Acceptor最終接受或者Acceptor最終不接受
47搏讶、什么是 zab 協(xié)議?
1)ZAB協(xié)議是專門為zookeeper實(shí)現(xiàn)分布式協(xié)調(diào)功能而設(shè)計(jì)霍殴。zookeeper主要是根據(jù)ZAB協(xié)議實(shí)現(xiàn)分布式系統(tǒng)數(shù)據(jù)一致性媒惕。
2)zookeeper根據(jù)ZAB協(xié)議建立了主備模型完成zookeeper集群中數(shù)據(jù)的同步。這里所說的主備系統(tǒng)架構(gòu)模型是指来庭,在zookeeper集群中吓笙,只有一臺leader負(fù)責(zé)處理外部客戶端的事物請求(或?qū)懖僮?,然后leader服務(wù)器將客戶端的寫操作數(shù)據(jù)同步到所有的follower節(jié)點(diǎn)中巾腕。?
3)ZAB的協(xié)議核心是在整個(gè)zookeeper集群中只有一個(gè)節(jié)點(diǎn)即Leader將客戶端的寫操作轉(zhuǎn)化為事物(或提議proposal)面睛。Leader節(jié)點(diǎn)在數(shù)據(jù)寫完之后,將向所有的follower節(jié)點(diǎn)發(fā)送數(shù)據(jù)廣播請求(或數(shù)據(jù)復(fù)制)尊搬,等待所有的follower節(jié)點(diǎn)反饋叁鉴。在ZAB協(xié)議中,只要超過半數(shù)follower節(jié)點(diǎn)反饋OK佛寿,Leader節(jié)點(diǎn)就會向所有的follower服務(wù)器發(fā)送commit消息幌墓。即將leader節(jié)點(diǎn)上的數(shù)據(jù)同步到follower節(jié)點(diǎn)之上。
4)ZAB協(xié)議中主要有兩種模式冀泻,第一是消息廣播模式常侣;第二是崩潰恢復(fù)模式。
ZAB協(xié)議原理
1)ZAB協(xié)議要求每個(gè)leader都要經(jīng)歷三個(gè)階段弹渔,即發(fā)現(xiàn)胳施,同步,廣播肢专。
2)發(fā)現(xiàn):即要求zookeeper集群必須選擇出一個(gè)leader進(jìn)程舞肆,同時(shí)leader會維護(hù)一個(gè)follower可用列表焦辅。將來客戶端可以這follower中的節(jié)點(diǎn)進(jìn)行通信。
3)同步:leader要負(fù)責(zé)將本身的數(shù)據(jù)與follower完成同步椿胯,做到多副本存儲筷登。這樣也是體現(xiàn)了CAP中高可用和分區(qū)容錯(cuò)。follower將隊(duì)列中未處理完的請求消費(fèi)完成后哩盲,寫入本地事物日志中前方。
4)廣播:leader可以接受客戶端新的proposal請求,將新的proposal請求廣播給所有的follower廉油。
Zookeeper設(shè)計(jì)目標(biāo)
1)zookeeper作為當(dāng)今最流行的分布式系統(tǒng)應(yīng)用協(xié)調(diào)框架惠险,采用zab協(xié)議的最大目標(biāo)就是建立一個(gè)高可用可擴(kuò)展的分布式數(shù)據(jù)主備系統(tǒng)。即在任何時(shí)刻只要leader發(fā)生宕機(jī)娱两,都能保證分布式系統(tǒng)數(shù)據(jù)的可靠性和最終一致性莺匠。
2)深刻理解ZAB協(xié)議,才能更好的理解zookeeper對于分布式系統(tǒng)建設(shè)的重要性十兢。以及為什么采用zookeeper就能保證分布式系統(tǒng)中數(shù)據(jù)最終一致性趣竣,服務(wù)的高可用性。
48旱物、分布式事務(wù)的原理遥缕,優(yōu)缺點(diǎn),如何使用分布式事務(wù)宵呛?
定義:分布式事務(wù)就是指事務(wù)的參與者单匣、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上宝穗。簡單的說户秤,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的服務(wù)器上逮矛,且屬于不同的應(yīng)用鸡号,分布式事務(wù)需要保證這些小操作要么全部成功,要么全部失敗须鼎。本質(zhì)上來說鲸伴,分布式事務(wù)就是為了保證不同數(shù)據(jù)庫的數(shù)據(jù)一致性。
CAP定理
WEB服務(wù)無法同時(shí)滿足以下3個(gè)屬性:
一致性(Consistency) : 客戶端知道一系列的操作都會同時(shí)發(fā)生(生效)
可用性(Availability) : 每個(gè)操作都必須以可預(yù)期的響應(yīng)結(jié)束
分區(qū)容錯(cuò)性(Partition tolerance) : 即使出現(xiàn)單個(gè)組件無法可用,操作依然可以完成
BASE理論
Basically Available(基本可用)
Soft state(軟狀態(tài))
Eventually consistent(最終一致性)
BASE理論是對CAP中的一致性和可用性進(jìn)行一個(gè)權(quán)衡的結(jié)果晋控,核心思想就是:我們無法做到強(qiáng)一致汞窗,但每個(gè)應(yīng)用都可以根據(jù)自身的業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性(Eventual consistency)赡译。
解決方案:
一仲吏、兩階段提交(2PC)
兩階段提交就是使用XA協(xié)議的原理,XA是一個(gè)兩階段提交協(xié)議,該協(xié)議分為以下兩個(gè)階段:
第一階段:事務(wù)協(xié)調(diào)器要求每個(gè)涉及到事務(wù)的數(shù)據(jù)庫預(yù)提交(precommit)此操作蜘矢,并反映是否可以提交.
第二階段:事務(wù)協(xié)調(diào)器要求每個(gè)數(shù)據(jù)庫提交數(shù)據(jù)狂男。
優(yōu)點(diǎn):盡量保證了數(shù)據(jù)的強(qiáng)一致综看,適合對數(shù)據(jù)強(qiáng)一致要求很高的關(guān)鍵領(lǐng)域品腹。(其實(shí)也不能100%保證強(qiáng)一致)
缺點(diǎn):實(shí)現(xiàn)復(fù)雜,犧牲了可用性红碑,對性能影響較大舞吭,不適合高并發(fā)高性能場景,如果分布式系統(tǒng)跨接口調(diào)用
二析珊、補(bǔ)償事務(wù)(TCC)
TCC其實(shí)就是采用的補(bǔ)償機(jī)制羡鸥,其核心思想是:針對每個(gè)操作,都要注冊一個(gè)與其對應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作忠寻。它分為三個(gè)階段:
Try 階段主要是對業(yè)務(wù)系統(tǒng)做檢測及資源預(yù)留
Confirm 階段主要是對業(yè)務(wù)系統(tǒng)做確認(rèn)提交惧浴,Try階段執(zhí)行成功并開始執(zhí)行Confirm階段時(shí),默認(rèn)Confirm階段是不會出錯(cuò)的奕剃。即:只要Try成功衷旅,Confirm一定成功。
Cancel 階段主要是在業(yè)務(wù)執(zhí)行錯(cuò)誤纵朋,需要回滾的狀態(tài)下執(zhí)行的業(yè)務(wù)取消柿顶,預(yù)留資源釋放。
優(yōu)點(diǎn):跟2PC比起來操软,實(shí)現(xiàn)以及流程相對簡單一些嘁锯,但數(shù)據(jù)的一致性比2PC也要差一些
缺點(diǎn):在2,3步中都有可能失敗。TCC屬于應(yīng)用層的一種補(bǔ)償方式聂薪,所以需要程序員在實(shí)現(xiàn)的時(shí)候多寫很多補(bǔ)償?shù)拇a家乘,在一些場景中,一些業(yè)務(wù)流程可能用TCC不太好定義及處理藏澳。
三仁锯、本地消息表(異步確保)
本地消息表這種實(shí)現(xiàn)方式應(yīng)該是業(yè)界使用最多的,其核心思想是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理笆载,這種思路是來源于ebay扑馁。
基本思路就是:
消息生產(chǎn)方,需要額外建一個(gè)消息表凉驻,并記錄消息發(fā)送狀態(tài)腻要。消息表和業(yè)務(wù)數(shù)據(jù)要在一個(gè)事務(wù)里提交,也就是說他們要在一個(gè)數(shù)據(jù)庫里面涝登。然后消息會經(jīng)過MQ發(fā)送到消息的消費(fèi)方雄家。如果消息發(fā)送失敗,會進(jìn)行重試發(fā)送胀滚。
消息消費(fèi)方趟济,需要處理這個(gè)消息乱投,并完成自己的業(yè)務(wù)邏輯。此時(shí)如果本地事務(wù)處理成功顷编,表明已經(jīng)處理成功了戚炫,如果處理失敗,那么就會重試執(zhí)行媳纬。如果是業(yè)務(wù)上面的失敗双肤,可以給生產(chǎn)方發(fā)送一個(gè)業(yè)務(wù)補(bǔ)償消息,通知生產(chǎn)方進(jìn)行回滾等操作钮惠。
生產(chǎn)方和消費(fèi)方定時(shí)掃描本地消息表茅糜,把還沒處理完成的消息或者失敗的消息再發(fā)送一遍。如果有靠譜的自動對賬補(bǔ)賬邏輯素挽,這種方案還是非常實(shí)用的蔑赘。
優(yōu)點(diǎn):一種非常經(jīng)典的實(shí)現(xiàn),避免了分布式事務(wù)预明,實(shí)現(xiàn)了最終一致性缩赛。
缺點(diǎn):消息表會耦合到業(yè)務(wù)系統(tǒng)中,如果沒有封裝好的解決方案贮庞,會有很多雜活需要處理峦筒。
四、MQ 事務(wù)消息
有一些第三方的MQ是支持事務(wù)消息的窗慎,比如RocketMQ物喷,他們支持事務(wù)消息的方式也是類似于采用的二階段提交,但是市面上一些主流的MQ都是不支持事務(wù)消息的遮斥,比如RabbitMQ和Kafka都不支持峦失。
RocketMQ中間件其思路大致為:
第一階段Prepared消息,拿到消息的地址术吗。
第二階段執(zhí)行本地事務(wù)
第三階段通過第一階段拿到的地址去訪問消息尉辑,并修改狀態(tài)。
在業(yè)務(wù)方法內(nèi)要向消息隊(duì)列提交兩次請求较屿,一次發(fā)送消息和一次確認(rèn)消息隧魄。如果確認(rèn)消息發(fā)送失敗了RocketMQ會定期掃描消息集群中的事務(wù)消息,這時(shí)候發(fā)現(xiàn)了Prepared消息隘蝎,它會向消息發(fā)送者確認(rèn)购啄,所以生產(chǎn)方需要實(shí)現(xiàn)一個(gè)check接口,RocketMQ會根據(jù)發(fā)送端設(shè)置的策略來決定是回滾還是繼續(xù)發(fā)送確認(rèn)消息嘱么。這樣就保證了消息發(fā)送與本地事務(wù)同時(shí)成功或同時(shí)失敗狮含。
優(yōu)點(diǎn):?實(shí)現(xiàn)了最終一致性,不需要依賴本地?cái)?shù)據(jù)庫事務(wù)。
缺點(diǎn):?實(shí)現(xiàn)難度大几迄,主流MQ不支持蔚龙,沒有.NET客戶端,RocketMQ事務(wù)消息部分代碼也未開源映胁。
五木羹、Sagas 事務(wù)模型
Saga事務(wù)模型又叫做長時(shí)間運(yùn)行的事務(wù)(Long-running-transaction), 它描述的是另外一種在沒有兩階段提交的的情況下解決分布式系統(tǒng)中復(fù)雜的業(yè)務(wù)事務(wù)問題。
該模型核心思想就是拆分分布式系統(tǒng)中的長事務(wù)為多個(gè)短事務(wù)屿愚,或者叫多個(gè)本地事務(wù)汇跨,然后由Sagas 工作流引擎負(fù)責(zé)協(xié)調(diào)务荆,如果整個(gè)流程正常結(jié)束妆距,那么就算是業(yè)務(wù)成功完成,如果在這過程中出現(xiàn)失敗函匕,那么Sagas工作流引擎就會以相反的順序調(diào)用補(bǔ)償操作娱据,重新進(jìn)行業(yè)務(wù)回滾。
49盅惜、分布式集群下如何做到唯一序列號中剩?
1、數(shù)據(jù)庫自增長序列或字段
優(yōu)點(diǎn):
????1)簡單抒寂,代碼方便结啼,性能可以接受。
????2)數(shù)字ID天然排序屈芜,對分頁或者需要排序的結(jié)果很有幫助郊愧。
缺點(diǎn):
????1)不同數(shù)據(jù)庫語法和實(shí)現(xiàn)不同,數(shù)據(jù)庫遷移的時(shí)候或多數(shù)據(jù)庫版本支持的時(shí)候需要處理井佑。
????2)在單個(gè)數(shù)據(jù)庫或讀寫分離或一主多從的情況下属铁,只有一個(gè)主庫可以生成。有單點(diǎn)故障的風(fēng)險(xiǎn)躬翁。
????3)在性能達(dá)不到要求的情況下焦蘑,比較難于擴(kuò)展。
????4)如果遇見多個(gè)系統(tǒng)需要合并或者涉及到數(shù)據(jù)遷移會相當(dāng)痛苦盒发。
????5)分表分庫的時(shí)候會有麻煩例嘱。
優(yōu)化方案:
針對主庫單點(diǎn),如果有多個(gè)Master庫宁舰,則每個(gè)Master庫設(shè)置的起始數(shù)字不一樣拼卵,步長一樣,可以是Master的個(gè)數(shù)明吩。比如:Master1 生成的是 1间学,4,7,10低葫,Master2生成的是2,5,8,11 Master3生成的是 3,6,9,12详羡。這樣就可以有效生成集群中的唯一ID,也可以大大降低ID生成數(shù)據(jù)庫操作的負(fù)載嘿悬。
2实柠、UUID
優(yōu)點(diǎn):
????1)簡單,代碼方便善涨。
????2)生成ID性能非常好窒盐,基本不會有性能問題。
????3)全球唯一钢拧,在遇見數(shù)據(jù)遷移蟹漓,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫變更等情況下源内,可以從容應(yīng)對葡粒。
缺點(diǎn):
????1)沒有排序,無法保證趨勢遞增膜钓。
????2)UUID往往是使用字符串存儲嗽交,查詢的效率比較低。
????3)存儲空間比較大颂斜,如果是海量數(shù)據(jù)庫夫壁,就需要考慮存儲量的問題。
????4)傳輸數(shù)據(jù)量大
????5)不可讀沃疮。
3盒让、UUID的變種
????1)為了解決UUID不可讀,可以使用UUID to Int64的方法忿磅。
????2)為了解決UUID無序的問題糯彬,NHibernate在其主鍵生成方式中提供了Comb算法(combined guid/timestamp)。保留GUID的10個(gè)字節(jié)葱她,用另6個(gè)字節(jié)表示GUID生成的時(shí)間(DateTime)撩扒。
4、Redis生成ID
當(dāng)使用數(shù)據(jù)庫來生成ID性能不夠要求的時(shí)候吨些,可以嘗試使用Redis來生成ID搓谆。這主要依賴于Redis是單線程的,所以也可以用生成全局唯一的ID豪墅∪郑可以用Redis的原子操作 INCR和INCRBY來實(shí)現(xiàn)∨计鳎可以使用Redis集群來獲取更高的吞吐量斩萌。
優(yōu)點(diǎn):
????1)不依賴于數(shù)據(jù)庫缝裤,靈活方便,且性能優(yōu)于數(shù)據(jù)庫颊郎。
????2)數(shù)字ID天然排序憋飞,對分頁或者需要排序的結(jié)果很有幫助。
缺點(diǎn):
????1)如果系統(tǒng)中沒有Redis姆吭,還需要引入新的組件榛做,增加系統(tǒng)復(fù)雜度。
????2)需要編碼和配置的工作量比較大内狸。
5检眯、Twitter的snowflake算法
snowflake是Twitter開源的分布式ID生成算法,結(jié)果是一個(gè)long型的ID昆淡。其核心思想是:使用41bit作為毫秒數(shù)锰瘸,10bit作為機(jī)器的ID(5個(gè)bit是數(shù)據(jù)中心,5個(gè)bit的機(jī)器ID)瘪撇,12bit作為毫秒內(nèi)的流水號(意味著每個(gè)節(jié)點(diǎn)在每毫秒可以產(chǎn)生4096個(gè)ID)获茬,最后還有一個(gè)符號位,永遠(yuǎn)是0倔既。
snowflake算法可以根據(jù)自身項(xiàng)目的需要進(jìn)行一定的修改。比如估算未來的數(shù)據(jù)中心個(gè)數(shù)鹏氧,每個(gè)數(shù)據(jù)中心的機(jī)器數(shù)以及統(tǒng)一毫秒可以能的并發(fā)數(shù)來調(diào)整在算法中所需要的bit數(shù)渤涌。
優(yōu)點(diǎn):
????1)不依賴于數(shù)據(jù)庫,靈活方便把还,且性能優(yōu)于數(shù)據(jù)庫实蓬。
????2)ID按照時(shí)間在單機(jī)上是遞增的。
缺點(diǎn):在單機(jī)上是遞增的吊履,但是由于涉及到分布式環(huán)境安皱,每臺機(jī)器上的時(shí)鐘不可能完全同步,也許有時(shí)候也會出現(xiàn)不是全局遞增的情況艇炎。
6酌伊、利用zookeeper生成唯一ID
zookeeper主要通過其znode數(shù)據(jù)版本來生成序列號,可以生成32位和64位的數(shù)據(jù)版本號缀踪,客戶端可以使用這個(gè)版本號來作為唯一的序列號居砖。很少會使用zookeeper來生成唯一ID。主要是由于需要依賴zookeeper驴娃,并且是多步調(diào)用API奏候,如果在競爭較大的情況下,需要考慮使用分布式鎖唇敞。因此蔗草,性能在高并發(fā)的分布式環(huán)境下咒彤,也不甚理想。
7咒精、MongoDB的ObjectId
MongoDB的ObjectId和snowflake算法類似蔼紧。它設(shè)計(jì)成輕量型的,不同的機(jī)器都能用全局唯一的同種方法方便地生成它狠轻。MongoDB從一開始就設(shè)計(jì)用來作為分布式數(shù)據(jù)庫奸例,處理多個(gè)節(jié)點(diǎn)是一個(gè)核心要求。使其在分片環(huán)境中要容易生成得多向楼。
50查吊、闡述下SOLID原則
SOLID是面向?qū)ο笤O(shè)計(jì)5大重要原則:
1)單一職責(zé)原則(SRP):一個(gè)類有且只有一個(gè)職責(zé)
2)開放封閉原則(OCP):一個(gè)類應(yīng)該對擴(kuò)展開放,對修改關(guān)閉
3)里氏替換原則(LSP):派生的子類應(yīng)該是可替換基類的
4)接口隔離原則(ISP):類不應(yīng)該被迫依賴他們不使用的方法
5)依賴倒置原則(DIP):高層模塊不應(yīng)該依賴低層模塊湖蜕,應(yīng)該依賴抽象類或接口