88. 說一下你熟悉的設計模式?html
參考:Java常見的設計模式
前端
89. 簡單工廠和抽象工廠有什麼區別?java
簡單工廠模式:spring
這個模式自己很簡單並且使用在業務較簡單的狀況下。通常用於小項目或者具體產品不多擴展的狀況(這樣工廠類纔不用常常更改)。編程
它由三種角色組成:json
工廠類角色:這是本模式的核心,含有必定的商業邏輯和判斷邏輯,根據邏輯不一樣,產生具體的工廠產品。如例子中的Driver類。設計模式
抽象產品角色:它通常是具體產品繼承的父類或者實現的接口。由接口或者抽象類來實現。如例中的Car接口。安全
具體產品角色:工廠類所建立的對象就是此角色的實例。在java中由一個具體類實現,如例子中的Benz、Bmw類。服務器
來用類圖來清晰的表示下的它們之間的關係:session
抽象工廠模式:
先來認識下什麼是產品族: 位於不一樣產品等級結構中,功能相關聯的產品組成的家族。
圖中的BmwCar和BenzCar就是兩個產品樹(產品層次結構);而如圖所示的BenzSportsCar和BmwSportsCar就是一個產品族。他們均可以放到跑車家族中,所以功能有所關聯。同理BmwBussinessCar和BenzBusinessCar也是一個產品族。
能夠這麼說,它和工廠方法模式的區別就在於須要建立對象的複雜程度上。並且抽象工廠模式是三個裏面最爲抽象、最具通常性的。抽象工廠模式的用意爲:給客戶端提供一個接口,能夠建立多個產品族中的產品對象。
並且使用抽象工廠模式還要知足一下條件:
系統中有多個產品族,而系統一次只可能消費其中一族產品
同屬於同一個產品族的產品以其使用。
來看看抽象工廠模式的各個角色(和工廠方法的一模一樣):
抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。
具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以建立對應的具體產品的對象。在java中它由具體的類來實現。
抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在java中通常有抽象類或者接口來實現。
具體產品角色:具體工廠角色所建立的對象就是此角色的實例。在java中由具體的類來實現。
10、Spring / Spring MVC
90. 爲何要使用 spring?
1.簡介
目的:解決企業應用開發的複雜性
功能:使用基本的JavaBean代替EJB,並提供了更多的企業應用功能
範圍:任何Java應用
簡單來講,Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架。
2.輕量
從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架能夠在一個大小隻有1MB多的JAR文件裏發佈。而且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴於Spring的特定類。
3.控制反轉
Spring經過一種稱做控制反轉(IoC)的技術促進了鬆耦合。當應用了IoC,一個對象依賴的其它對象會經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象。你能夠認爲IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。
4.面向切面
Spring提供了面向切面編程的豐富支持,容許經過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該作的——完成業務邏輯——僅此而已。它們並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。
5.容器
Spring包含並管理應用對象的配置和生命週期,在這個意義上它是一種容器,你能夠配置你的每一個bean如何被建立——基於一個可配置原型(prototype),你的bean能夠建立一個單獨的實例或者每次須要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不該該被混同於傳統的重量級的EJB容器,它們常常是龐大與笨重的,難以使用。
6.框架
Spring能夠將簡單的組件配置、組合成爲複雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件裏。Spring也提供了不少基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。
全部Spring的這些特徵使你可以編寫更乾淨、更可管理、而且更易於測試的代碼。它們也爲Spring中的各類模塊提供了基礎支持。
91. 解釋一下什麼是 aop?
AOP(Aspect-Oriented Programming,面向方面編程),能夠說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來創建一種對象層次結構,用以模擬公共行爲的一個集合。當咱們須要爲分散的對象引入公共行爲的時候,OOP則顯得無能爲力。也就是說,OOP容許你定義從上到下的關係,但並不適合定義從左到右的關係。例如日誌功能。日誌代碼每每水平地散佈在全部對象層次中,而與它所散佈到的對象的核心功能毫無關係。對於其餘類型的代碼,如安全性、異常處理和透明的持續性也是如此。這種散佈在各處的無關的代碼被稱爲橫切(cross-cutting)代碼,在OOP設計中,它致使了大量代碼的重複,而不利於各個模塊的重用。
而AOP技術則偏偏相反,它利用一種稱爲「橫切」的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,並將其名爲「Aspect」,即方面。所謂「方面」,簡單地說,就是將那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減小系統的重複代碼,下降模塊間的耦合度,並有利於將來的可操做性和可維護性。AOP表明的是一個橫向的關係,若是說「對象」是一個空心的圓柱體,其中封裝的是對象的屬性和行爲;那麼面向方面編程的方法,就彷彿一把利刃,將這些空心圓柱體剖開,以得到其內部的消息。而剖開的切面,也就是所謂的「方面」了。而後它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡。
使用「橫切」技術,AOP把軟件系統分爲兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特色是,他們常常發生在覈心關注點的多處,而各處都基本類似。好比權限認證、日誌、事務處理。Aop 的做用在於分離系統中的各類關注點,將核心關注點和橫切關注點分離開來。正如Avanade公司的高級方案構架師Adam Magee所說,AOP的核心思想就是「將應用程序中的商業邏輯同對其提供支持的通用服務進行分離。」
92. 解釋一下什麼是 ioc?
IOC是Inversion of Control的縮寫,多數書籍翻譯成「控制反轉」。
1996年,Michael Mattson在一篇有關探討面向對象框架的文章中,首先提出了IOC 這個概念。對於面向對象設計及編程的基本思想,前面咱們已經講了不少了,再也不贅述,簡單來講就是把複雜系統分解成相互合做的對象,這些對象類經過封裝之後,內部實現對外部是透明的,從而下降了解決問題的複雜度,並且能夠靈活地被重用和擴展。
IOC理論提出的觀點大致是這樣的:藉助於「第三方」實現具備依賴關係的對象之間的解耦。以下圖:
圖 IOC解耦過程
你們看到了吧,因爲引進了中間位置的「第三方」,也就是IOC容器,使得A、B、C、D這4個對象沒有了耦合關係,齒輪之間的傳動所有依靠「第三方」了,所有對象的控制權所有上繳給「第三方」IOC容器,因此,IOC容器成了整個系統的關鍵核心,它起到了一種相似「粘合劑」的做用,把系統中的全部對象粘合在一塊兒發揮做用,若是沒有這個「粘合劑」,對象與對象之間會彼此失去聯繫,這就是有人把IOC容器比喻成「粘合劑」的由來。
咱們再來作個試驗:把上圖中間的IOC容器拿掉,而後再來看看這套系統:
圖 拿掉IOC容器後的系統
咱們如今看到的畫面,就是咱們要實現整個系統所須要完成的所有內容。這時候,A、B、C、D這4個對象之間已經沒有了耦合關係,彼此毫無聯繫,這樣的話,當你在實現A的時候,根本無須再去考慮B、C和D了,對象之間的依賴關係已經下降到了最低程度。因此,若是真能實現IOC容器,對於系統開發而言,這將是一件多麼美好的事情,參與開發的每一成員只要實現本身的類就能夠了,跟別人沒有任何關係!
咱們再來看看,控制反轉(IOC)到底爲何要起這麼個名字?咱們來對比一下:
軟件系統在沒有引入IOC容器以前,如圖1所示,對象A依賴於對象B,那麼對象A在初始化或者運行到某一點的時候,本身必須主動去建立對象B或者使用已經建立的對象B。不管是建立仍是使用對象B,控制權都在本身手上。
軟件系統在引入IOC容器以後,這種情形就徹底改變了,如圖3所示,因爲IOC容器的加入,對象A與對象B之間失去了直接聯繫,因此,當對象A運行到須要對象B的時候,IOC容器會主動建立一個對象B注入到對象A須要的地方。
經過先後的對比,咱們不難看出來:對象A得到依賴對象B的過程,由主動行爲變爲了被動行爲,控制權顛倒過來了,這就是「控制反轉」這個名稱的由來。
93. spring 有哪些主要模塊?
Spring框架至今已集成了20多個模塊。這些模塊主要被分以下圖所示的核心容器、數據訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測試模塊。
更多信息:howtodoinjava.com/java-spring-framework-tutorials/
94. spring 經常使用的注入方式有哪些?
Spring經過DI(依賴注入)實現IOC(控制反轉),經常使用的注入方式主要有三種:
構造方法注入
setter注入
基於註解的注入
95. spring 中的 bean 是線程安全的嗎?
Spring容器中的Bean是否線程安全,容器自己並無提供Bean的線程安全策略,所以能夠說spring容器中的Bean自己不具有線程安全的特性,可是具體仍是要結合具體scope的Bean去研究。
96. spring 支持幾種 bean 的做用域?
當經過spring容器建立一個Bean實例時,不只能夠完成Bean實例的實例化,還能夠爲Bean指定特定的做用域。Spring支持以下5種做用域:
singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例
prototype:原型模式,每次經過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例
request:對於每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不一樣的Bean實例。只有在Web應用中使用Spring時,該做用域纔有效
session:對於每次HTTP Session,使用session定義的Bean豆漿產生一個新實例。一樣只有在Web應用中使用Spring時,該做用域纔有效
globalsession:每一個全局的HTTP Session,使用session定義的Bean都將產生一個新實例。典型狀況下,僅在使用portlet context的時候有效。一樣只有在Web應用中使用Spring時,該做用域纔有效
其中比較經常使用的是singleton和prototype兩種做用域。對於singleton做用域的Bean,每次請求該Bean都將得到相同的實例。容器負責跟蹤Bean實例的狀態,負責維護Bean實例的生命週期行爲;若是一個Bean被設置成prototype做用域,程序每次請求該id的Bean,Spring都會新建一個Bean實例,而後返回給程序。在這種狀況下,Spring容器僅僅使用new 關鍵字建立Bean實例,一旦建立成功,容器不在跟蹤實例,也不會維護Bean實例的狀態。
若是不指定Bean的做用域,Spring默認使用singleton做用域。Java在建立Java實例時,須要進行內存申請;銷燬實例時,須要完成垃圾回收,這些工做都會致使系統開銷的增長。所以,prototype做用域Bean的建立、銷燬代價比較大。而singleton做用域的Bean實例一旦建立成功,能夠重複使用。所以,除非必要,不然儘可能避免將Bean被設置成prototype做用域。
97. spring 自動裝配 bean 有哪些方式?
Spring容器負責建立應用程序中的bean同時經過ID來協調這些對象之間的關係。做爲開發人員,咱們須要告訴Spring要建立哪些bean而且如何將其裝配到一塊兒。
spring中bean裝配有兩種方式:
隱式的bean發現機制和自動裝配
在java代碼或者XML中進行顯示配置
固然這些方式也能夠配合使用。
98. spring 事務實現方式有哪些?
編程式事務管理對基於 POJO 的應用來講是惟一選擇。咱們須要在代碼中調用beginTransaction()、commit()、rollback()等事務管理相關的方法,這就是編程式事務管理。
基於 TransactionProxyFactoryBean 的聲明式事務管理
基於 @Transactional 的聲明式事務管理
基於 Aspectj AOP 配置事務
99. 說一下 spring 的事務隔離?
事務隔離級別指的是一個事務對數據的修改與另外一個並行的事務的隔離程度,當多個事務同時訪問相同數據時,若是沒有采起必要的隔離機制,就可能發生如下問題:
髒讀:一個事務讀到另外一個事務未提交的更新數據。
幻讀:例如第一個事務對一個表中的數據進行了修改,好比這種修改涉及到表中的「所有數據行」。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入「一行新數據」。那麼,之後就會發生操做第一個事務的用戶發現表中還存在沒有修改的數據行,就好象發生了幻覺同樣。
不可重複讀:比方說在同一個事務中前後執行兩條如出一轍的select語句,期間在這次事務中沒有執行過任何DDL語句,但前後獲得的結果不一致,這就是不可重複讀。
100. 說一下 spring mvc 運行流程?
Spring MVC運行流程圖:
Spring運行流程描述:
1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;
2. DispatcherServlet對請求URL進行解析,獲得請求資源標識符(URI)。而後根據該URI,調用HandlerMapping得到該Handler配置的全部相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;
3. DispatcherServlet 根據得到的Handler,選擇一個合適的HandlerAdapter;(附註:若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法)
4. 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:
HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
5. Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;
6. 根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
7. ViewResolver 結合Model和View,來渲染視圖;
8. 將渲染結果返回給客戶端。
101. spring mvc 有哪些組件?
Spring MVC的核心組件:
DispatcherServlet:中央控制器,把請求給轉發到具體的控制類
Controller:具體處理請求的控制器
HandlerMapping:映射處理器,負責映射中央處理器轉發給controller時的映射策略
ModelAndView:服務層返回的數據和視圖層的封裝類
ViewResolver:視圖解析器,解析具體的視圖
Interceptors :攔截器,負責攔截咱們定義的請求而後作處理工做
102. @RequestMapping 的做用是什麼?
RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的全部響應請求的方法都是以該地址做爲父路徑。
RequestMapping註解有六個屬性,下面咱們把她分紅三類進行說明。
value:指定請求的實際地址,指定的地址能夠是URI Template 模式(後面將會說明);
method:指定請求的method類型, GET、POST、PUT、DELETE等;
consumes:指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;
produces:指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;
params: 指定request中必須包含某些參數值是,才讓該方法處理。
headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。