最近整理的一些常見的面試題,面試大全,黑馬程式設計師面試寶典題庫---框架--篇
框架(評論留言獲取原件)
一、 SpringMVC
1. SpringMVC 的工作原理
a. 使用者向伺服器傳送請求,請求被 springMVC 前端控制器 DispatchServlet 捕獲;
b. DispatcherServle 對請求 URL 進行解析,得到請求資源識別符號(URL),然後根據該 URL 呼叫 HandlerMapping
將請求對映到處理器 HandlerExcutionChain;
c. DispatchServlet 根據獲得 Handler 選擇一個合適的 HandlerAdapter 介面卡處理;
d. Handler 對資料處理完成以後將返回一個 ModelAndView()物件給 DisPatchServlet;
e. Handler 返回的 ModelAndView()只是一個邏輯檢視並不是一個正式的檢視, DispatcherSevlet 通過ViewResolver 試圖解析器將邏輯檢視轉化為真正的檢視 View;
h. DispatcherServle 通過 model 解析出 ModelAndView()中的引數進行解析最終展現出完整的 view 並返回給客戶端;
2. SpringMVC 常用註解都有哪些?
@requestMapping 用於請求 url 對映。
@RequestBody 註解實現接收 http 請求的 json 資料,將 json 資料轉換為 java 物件。
@ResponseBody 註解實現將 controller 方法返回物件轉化為 json 響應給客戶。
3. 如何開啟註解處理器和介面卡?
我們在專案中一般會在 springmvc.xml 中通過開啟 <mvc:annotation-driven>來實現註解處理器和介面卡的開啟。
4. 如何解決 get 和 post 亂碼問題?
解決 post 請求亂碼:我們可以在 web.xml 裡邊配置一個 CharacterEncodingFilter 過濾器。 設定為 utf-8.
解決 get 請求的亂碼:有兩種方法。對於 get 請求中文引數出現亂碼解決方法有兩個:
1. 修改 tomcat 配置檔案新增編碼與工程編碼一致。
2. 另 外 一 種 方 法 對 參 數 進 行 重 新 編 碼
String userName = New String(Request.getParameter(“userName”).getBytes(“ISO8859-1”), “utf-8”);
二、 Spring
1. 談談你對 Spring 的理解
Spring 是一個開源框架,為簡化企業級應用開發而生。 Spring 可以是使簡單的 JavaBean 實現以前只有 EJB 才能實現的功能。 Spring 是一個 IOC 和 AOP 容器框架。
Spring 容器的主要核心是:
控制反轉(IOC),傳統的 java 開發模式中,當需要一個物件時,我們會自己使用 new 或者 getInstance 等直接或者間接呼叫構造方法建立一個物件。而在 spring 開發模式中, spring 容器使用了工廠模式為我們建立了所需要的物件,不需要我們自己建立了,直接呼叫 spring 提供的物件就可以了,這是控制反轉的思想。
依賴注入(DI), spring 使用 javaBean 物件的 set 方法或者帶引數的構造方法為我們在建立所需物件時將其屬性自動設定所需要的值的過程,就是依賴注入的思想。
面向切面程式設計(AOP),在面向物件程式設計(oop)思想中,我們將事物縱向抽成一個個的物件。而在面向切面程式設計中,我們將一個個的物件某些類似的方面橫向抽成一個切面,對這個切面進行一些如許可權控制、事物管理,記錄日誌等公用操作處理的過程就是面向切面程式設計的思想。 AOP 底層是動態代理,如果是介面採用 JDK 動態代理,如果是類採用CGLIB 方式實現動態代理。
2. Spring 中的設計模式
a. 單例模式——spring 中兩種代理方式,若目標物件實現了若干介面,spring 使用 jdk 的 java.lang.reflect.Proxy感恩於心,回報於行。 面試寶典系列-Java類代理。若目標兌現沒有實現任何介面, spring 使用 CGLIB 庫生成目標類的子類。
單例模式——在 spring 的配置檔案中設定 bean 預設為單例模式。
b. 模板方式模式——用來解決程式碼重複的問題。
比如: RestTemplate、 JmsTemplate、 JpaTemplate
d. 前端控制器模式——spring 提供了前端控制器 DispatherServlet 來對請求進行分發。
e. 試圖幫助(view helper) ——spring 提供了一系列的 JSP 標籤,高效巨集來幫助將分散的程式碼整合在試圖中。
f. 依賴注入——貫穿於 BeanFactory/ApplacationContext 介面的核心理念。
g. 工廠模式——在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用同一個介面來指向新建立的物件。 Spring 中使用 beanFactory 來建立物件的例項。
3. Spring 的常用註解
Spring 在 2.5 版本以後開始支援註解的方式來配置依賴注入。可以用註解的方式來代替 xml 中 bean 的描述。註解注入將會被容器在 XML 注入之前被處理,所以後者會覆蓋掉前者對於同一個屬性的處理結果。
註解裝配在 spring 中預設是關閉的。所以需要在 spring 的核心配置檔案中配置一下才能使用基於註解的裝配模式。配置方式如下:
<context:annotation-config />
常用的註解:
@Required:該註解應用於設值方法
@Autowired:該註解應用於有值設值方法、非設值方法、構造方法和變數。
@Qualifier:該註解和@Autowired 搭配使用,用於消除特定 bean 自動裝配的歧義。
4. 簡單介紹一下 Spring bean 的生命週期
bean 定義:在配置檔案裡面用<bean></bean>來進行定義。
bean 初始化:有兩種方式初始化:
1.在配置檔案中通過指定 init-method 屬性來完成
2.實現 org.springframwork.beans.factory.InitializingBean 介面
bean 呼叫:有三種方式可以得到 bean 例項,並進行呼叫
bean 銷燬:銷燬有兩種方式
1.使用配置檔案指定的 destroy-method 屬性
2.實現 org.springframwork.bean.factory.DisposeableBean 介面
參考資料: https://www.cnblogs.com/zrtqsk/p/3735273.html
5. Spring 結構圖
(1) 核心容器:包括 Core、 Beans、 Context、 EL 模組。
Core 模組:封裝了框架依賴的最底層部分,包括資源訪問、型別轉換及一些常用工具類。
Beans 模組:提供了框架的基礎部分,包括反轉控制和依賴注入。其中 Bean Factory 是容器核心,本質是“工廠設計模式”的實現,而且無需程式設計實現“單例設計模式”,單例完全由容器控制,而且提倡面向介面程式設計,而非面向實現程式設計;所有應用程式物件及物件間關係由框架管理,從而真正把你從程式邏輯中把維護物件之間的依賴關係提取出來,所有這些依賴關係都由 BeanFactory 來維護。
Context 模組:以 Core 和 Beans 為基礎,整合 Beans 模組功能並新增資源繫結、資料驗證、國際化、 Java EE 支援、容器生命週期、事件傳播等;核心介面是 ApplicationContext。
EL 模組:提供強大的表示式語言支援,支援訪問和修改屬性值,方法呼叫,支援訪問及修改陣列、容器和索引器,命名變數,支援算數和邏輯運算,支援從 Spring 容器獲取 Bean,它也支援列表投影、選擇和一般的列表聚合等。
(2) AOP、 Aspects 模組:
AOP 模組:Spring AOP 模組提供了符合 AOP Alliance 規範的面向方面的程式設計(aspect-oriented programming)實現,提供比如日誌記錄、許可權控制、效能統計等通用功能和業務邏輯分離的技術,並且能動態的把這些功能新增到需要的程式碼中;這樣各專其職,降低業務邏輯和通用功能的耦合。
Aspects 模組:提供了對 AspectJ 的整合, AspectJ 提供了比 Spring ASP 更強大的功能。
資料訪問/整合模組:該模組包括了 JDBC、 ORM、 OXM、 JMS 和事務管理。
事務模組:該模組用於 Spring 管理事務,只要是 Spring 管理物件都能得到 Spring 管理事務的好處,無需在程式碼中進行事務控制了,而且支援程式設計和宣告性的事務管理。
JDBC 模組:提供了一個 JBDC 的樣例模板, 使用這些模板能消除傳統冗長的 JDBC 編碼還有必須的事務控制,而且能享受到 Spring 管理事務的好處。
ORM 模組:提供與流行的“物件-關係”對映框架的無縫整合,包括 Hibernate、 JPA、 MyBatis 等。而且可以使用 Spring 事務管理,無需額外控制事務。
OXM 模組:提供了一個對 Object/XML 對映實現,將 java 物件對映成 XML 資料,或者將 XML 資料對映成 java物件, Object/XML 對映實現包括 JAXB、 Castor、 XMLBeans 和 XStream。
JMS 模組:用於 JMS(Java Messaging Service),提供一套 “訊息生產者、訊息消費者”模板用於更加簡單的使用 JMS, JMS 用於用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。
Web/Remoting 模組: Web/Remoting 模組包含了 Web、 Web-Servlet、 Web-Struts、 Web-Porlet 模組。
Web 模組:提供了基礎的 web 功能。例如多檔案上傳、整合 IoC 容器、遠端過程訪問(RMI、 Hessian、 Burlap)以及 Web Service 支援,並提供一個 RestTemplate 類來提供方便的 Restful services 訪問。
Web-Servlet 模組:提供了一個 Spring MVC Web 框架實現。 Spring MVC 框架提供了基於註解的請求資源注入、更簡單的資料繫結、資料驗證等及一套非常易用的 JSP 標籤,完全無縫與 Spring 其他技術協作。
Web-Struts 模組:提供了與 Struts 無縫整合, Struts1.x 和 Struts2.x 都支援
Test 模組: Spring 支援 Junit 和 TestNG 測試框架,而且還額外提供了一些基於 Spring 的測試功能,比如在測試 Web 框架時,模擬 Http 請求的功能。
6. Spring 能幫我們做什麼?
a. Spring 能幫我們根據配置檔案建立及組裝物件之間的依賴關係。
Spring 根據配置檔案來進行建立及組裝物件間依賴關係,只需要改配置檔案即可
b. Spring 面向切面程式設計能幫助我們無耦合的實現日誌記錄,效能統計,安全控制。
Spring 面向切面程式設計能提供一種更好的方式來完成,一般通過配置方式,而且不需要在現有程式碼中新增任何額外程式碼,現有程式碼專注業務邏輯。
c. Spring 能非常簡單的幫我們管理資料庫事務。
採用 Spring,我們只需獲取連線,執行 SQL,其他事物相關的都交給 Spring 來管理了。
d. Spring 還能與第三方資料庫訪問框架(如 Hibernate、 JPA)無縫整合,而且自己也提供了一套 JDBC訪問模板,來方便資料庫訪問。
e. Spring 還能與第三方 Web(如 Struts、 JSF)框架無縫整合,而且自己也提供了一套 Spring MVC框架,來方便 web 層搭建。
f. Spring 能方便的與 Java EE(如 Java Mail、任務排程)整合,與更多技術整合(比如快取框架)。
7. 請描述一下 Spring 的事務
宣告式事務管理的定義:用在 Spring 配置檔案中宣告式的處理事務來代替程式碼式的處理事務。這樣的好處是,事務管理不侵入開發的元件,具體來說,業務邏輯物件就不會意識到正在事務管理之中,事實上也應該如此,因為事務管理是屬於系統層面的服務,而不是業務邏輯的一部分,如果想要改變事務管理策劃的話,也只需要在定義檔案中重新配置即可,這樣維護起來極其方便。
基於 TransactionInterceptor 的宣告式事務管理:兩個次要的屬性: transactionManager,用來指定一個事務治理器 ,並 將具體事務相關的操作請託給它 ;其他一個是 Properties 型別的transactionAttributes 屬性,該屬性的每一個鍵值對中,鍵指定的是方法名,方法名可以行使萬用字元,而值就是表現呼應方法的所運用的事務屬性。
程式設計式事務與宣告式事務的區別:
程式設計式事務是自己寫事務處理的類,然後呼叫
宣告式事務是在配置檔案中配置,一般搭配在框架裡面使用!
8. BeanFactory 常用的實現類有哪些?
Bean 工廠是工廠模式的一個實現,提供了控制反轉功能,用來把應用的配置和依賴從正真的應用程式碼中分離。常用的 BeanFactory 實現有 DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等。
XMLBeanFactory, 最常用的就是 org.springframework.beans.factory.xml.XmlBeanFactory ,它根據 XML 檔案中的定義載入 beans。該容器從 XML 檔案讀取配置元資料並用它去建立一個完全配置的系統或應用。
9. 解釋 Spring JDBC、 Spring DAO 和 Spring ORM
Spring-DAO 並非 Spring 的一個模組,它實際上是指示你寫 DAO 操作、寫好 DAO 操作的一些規範。因此,對於訪問你的資料它既沒有提供介面也沒有提供實現更沒有提供模板。在寫一個 DAO 的時候,你應該使用 @Repository 對其進行註解,這樣底層技術(JDBC, Hibernate, JPA,等等)的相關異常才能一致性地翻譯為相應的 DataAccessException 子類。
Spring-JDBC 提供了 Jdbc 模板類,它移除了連線程式碼以幫你專注於 SQL 查詢和相關引數。 Spring-JDBC 還提供了一個 JdbcDaoSupport,這樣你可以對你的 DAO 進行擴充套件開發。它主要定義了兩個屬性:一個 DataSource和一個 JdbcTemplate,它們都可以用來實現 DAO 方法。 JdbcDaoSupport 還提供了一個將 SQL 異常轉換為Spring DataAccessExceptions 的異常翻譯器。
Spring-ORM 是一個囊括了很多持久層技術(JPA, JDO, Hibernate, iBatis)的總括模組。對於這些技術中的每一個, Spring 都提供了整合類,這樣每一種技術都能夠在遵循 Spring 的配置原則下進行使用,並平穩地和 Spring 事務管理進行整合。
對 於 每 一 種 技 術 , 配 置 主 要 在 於 將 一 個 DataSource bean 注 入 到 某 種 SessionFactory 或者 EntityManagerFactory 等 bean 中。純 JDBC 不需要這樣的一個整合類(JdbcTemplate 除外),因為 JDBC 僅依賴於一個 DataSource。
如果你計劃使用一種 ORM 技術,比如 JPA 或者 Hibernate,那麼你就不需要 Spring-JDBC 模組了,你需要的是這個 Spring-ORM 模組。
10. 簡單介紹一下 Spring WEB 模組。
Spring 的 WEB 模組是構建在 application context 模組基礎之上,提供一個適合 web 應用的上下文。這個模組也包括支援多種面向 web 的任務,如透明地處理多個檔案上傳請求和程式級請求引數的繫結到你的業務物件。它也有對 Jakarta Struts 的支援。
11. Spring 配置檔案有什麼作用?
Spring 配置檔案是個 XML 檔案,這個檔案包含了類資訊,描述瞭如何配置它們,以及如何相互呼叫。
12. 什麼是 Spring IOC 容器?
IOC 控制反轉: Spring IOC 負責建立物件,管理物件。通過依賴注入(DI),裝配物件,配置物件,並且管理這些物件的整個生命週期。
13. IOC 的優點是什麼?
IOC 或 依賴注入把應用的程式碼量降到最低。它使應用容易測試,單元測試不再需要單例和 JNDI 查詢機制。最小的代價和最小的侵入性使鬆散耦合得以實現。 IOC 容器支援載入服務時的餓漢式初始化和懶載入。
14. ApplicationContext 的實現類有哪些?
FileSystemXmlApplicationContext :此容器從一個 XML 檔案中載入 beans 的定義, XML Bean 配置檔案的全路徑名必須提供給它的建構函式。
ClassPathXmlApplicationContext:此容器也從一個 XML 檔案中載入 beans 的定義,這裡,你需要正確設定classpath 因為這個容器將在 classpath 裡找 bean 配置。
WebXmlApplicationContext:此容器載入一個 XML 檔案,此檔案定義了一個 WEB 應用的所有 bean。
15. BeanFactory 與 AppliacationContext 有什麼區別
1. BeanFactory
基礎型別的 IOC 容器,提供完成的 IOC 服務支援。如果沒有特殊指定,預設採用延遲初始化策略。相對來說,容器啟動初期速度較快,所需資源有限。
2.ApplicationContext
ApplicationContext 是在 BeanFactory 的基礎上構建,是相對比較高階的容器實現,除了 BeanFactory 的所有支援外, ApplicationContext 還提供了事件釋出、國際化支援等功能。 ApplicationContext 管理的物件,在容器啟動後預設全部初始化並且繫結完成。
16. 什麼是 Spring 的依賴注入?
平常的 java 開發中,程式設計師在某個類中需要依賴其它類的方法,則通常是 new 一個依賴類再呼叫類例項的方法,這種開發存在的問題是 new 的類例項不好統一管理, spring 提出了依賴注入的思想,即依賴類不由程式設計師例項化,而是通過 spring 容器幫我們 new 指定例項並且將例項注入到需要該物件的類中。依賴注入的另一種說法是“控制反轉” ,通俗的理解是:平常我們 new 一個例項,這個例項的控制權是我們程式設計師,而控制反轉是指 new 例項工作不由我們程式設計師來做而是交給 spring 容器來做。
17. 有哪些不同型別的 IOC(依賴注入)方式?
Spring 提供了多種依賴注入的方式。
1.Set 注入
2.構造器注入
3.靜態工廠的方法注入
4.例項工廠的方法注入
參考資料: https://www.cnblogs.com/java-class/p/4727775.html
18. 什麼是 Spring beans?
Spring beans 是那些形成 Spring 應用的主幹的 java 物件。它們被 Spring IOC 容器初始化,裝配,和管理。這些 beans 通過容器中配置的元資料建立。比如,以 XML 檔案中<bean/> 的形式定義。
Spring 框架定義的 beans 都是單例 beans。
19. 一個 Spring Beans 的定義需要包含什麼?
一個 Spring Bean 的定義包含容器必知的所有配置元資料,包括如何建立一個 bean,它的生命週期詳情及它的依賴。
20. 你怎樣定義類的作用域?
當定義一個<bean> 在 Spring 裡,我們還能給這個 bean 宣告一個作用域。它可以通過 bean 定義中的 scope 屬性來定義。如,當 Spring 要在需要的時候每次生產一個新的 bean 例項, bean 的 scope 屬性被指定為 prototype。
另一方面,一個 bean 每次使用的時候必須返回同一個例項,這個 bean 的 scope 屬性必須設為 singleton。
21. Spring 支援的幾種 bean 的作用域。
Spring 框架支援以下五種 bean 的作用域:
singleton : bean 在每個 Spring ioc 容器中只有一個例項。
prototype:一個 bean 的定義可以有多個例項。
request:每次 http 請求都會建立一個 bean,該作用域僅在基於 web 的 Spring ApplicationContext 情形下有效。
session : 在 一 個 HTTP Session 中 , 一 個 bean 定 義 對 應 一 個 實 例 。 該 作 用 域 僅 在 基 於 web 的Spring ApplicationContext 情形下有效。
global-session:在一個全域性的 HTTP Session 中,一個 bean 定義對應一個例項。該作用域僅在基於 web 的Spring ApplicationContext 情形下有效。
預設的 Spring bean 的作用域是 Singleton。
22. Spring 框架中的單例 bean 是執行緒安全的嗎?
Spring 框架中的單例 bean 不是執行緒安全的。
23. 什麼是 Spring 的內部 bean?
當一個 bean 僅被用作另一個 bean 的屬性時,它能被宣告為一個內部 bean,為了定義 inner bean,在Spring 的 基於 XML 的 配置元資料中,可以在 <property/>或 <constructor-arg/> 元素內使用<bean/> 元素,內部 bean 通常是匿名的,它們的 Scope 一般是 prototype。
24. 在 Spring 中如何注入一個 java 集合?
Spring 提供以下幾種集合的配置元素:
<list>型別用於注入一列值,允許有相同的值。
<set> 型別用於注入一組值,不允許有相同的值。
<map> 型別用於注入一組鍵值對,鍵和值都可以為任意型別。
<props>型別用於注入一組鍵值對,鍵和值都只能為 String 型別。
25. 什麼是 bean 的自動裝配?
無須在 Spring 配置檔案中描述 javaBean 之間的依賴關係(如配置<property>、 <constructor-arg>)。 IOC 容器會自動建立 javabean 之間的關聯關係。
26. 解釋不同方式的自動裝配 。
有五種自動裝配的方式,可以用來指導 Spring 容器用自動裝配方式來進行依賴注入。
no:預設的方式是不進行自動裝配,通過顯式設定 ref 屬性來進行裝配。
byName:通過引數名自動裝配, Spring 容器在配置檔案中發現 bean 的 autowire 屬性被設定成 byname,之後容器試圖匹配、裝配和該 bean 的屬性具有相同名字的 bean。
byType::通過引數型別自動裝配, Spring 容器在配置檔案中發現 bean 的 autowire 屬性被設定成 byType,之後容器試圖匹配、裝配和該 bean 的屬性具有相同型別的 bean。如果有多個 bean 符合條件,則丟擲錯誤。
constructor:這個方式類似於 byType, 但是要提供給構造器引數,如果沒有確定的帶引數的構造器引數型別,將會丟擲異常。
autodetect:首先嚐試使用 constructor 來自動裝配,如果無法工作, 則使用 byType 方式。
27. 什麼是基於 Java 的 Spring 註解配置? 給一些註解的例子
基於 Java 的配置,允許你在少量的 Java 註解的幫助下,進行你的大部分 Spring 配置而非通過 XML 檔案。
以@Configuration 註解為例,它用來標記類可以當做一個 bean 的定義,被 Spring IOC 容器使用。另一個例子是@Bean 註解,它表示此方法將要返回一個物件,作為一個 bean 註冊進 Spring 應用上下文。
28. 什麼是基於註解的容器配置?
相對於 XML 檔案,註解型的配置依賴於通過位元組碼元資料裝配元件,而非尖括號的宣告。開發者通過在相應的類,方法或屬性上使用註解的方式,直接元件類中進行配置,而不是使用 xml 表述 bean 的裝配關係。
29. 怎樣開啟註解裝配?
注 解 裝 配 在 默 認 情 況 下 是 不 開 啟 的 , 為 了 使 用 注 解 裝 配 , 我 們 必 須 在 Spring 配 置 文 件 中 配置 <context:annotation-config/>元素。
30. 在 Spring 框架中如何更有效地使用 JDBC?
使用 SpringJDBC 框架, 資源管理和錯誤處理的代價都會被減輕。所以開發者只需寫 statements 和 queries 從資料存取資料, JDBC 也可以在 Spring 框架提供的模板類的幫助下更有效地被使用,這個模板叫 JdbcTemplate 。
JdbcTemplate 類提供了很多便利的方法解決諸如把資料庫資料轉變成基本資料型別或物件,執行寫好的或可呼叫的資料庫操作語句,提供自定義的資料錯誤處理。
31. 使用 Spring 通過什麼方式訪問 Hibernate?
在 Spring 中有兩種方式訪問 Hibernate:
控制反轉 HibernateTemplate 和 Callback。
繼承 HibernateDAOSupport 提供一個 AOP 攔截器。
32. Spring 支援的 ORM 框架有哪些?
Spring 支援以下 ORM:
Hibernate、 iBatis、 JPA (Java Persistence API)、 TopLink、 JDO (Java Data Objects)、 OJB
33. 簡單解釋一下 spring 的 AOP
AOP(Aspect Oriented Programming),即面向切面程式設計,可以說是 OOP(Object Oriented Programming,面向物件程式設計)的補充和完善。 OOP 引入封裝、繼承、多型等概念來建立一種物件層次結構,用於模擬公共行為的一個集合。不過 OOP 允許開發者定義縱向的關係,但並不適合定義橫向的關係,例如日誌功能。日誌程式碼往往橫向地散佈在所有物件層次中,而與它對應的物件的核心功能毫無關係對於其他型別的程式碼,如安全性、異常處理和透明的持續性也都是如此,這種散佈在各處的無關的程式碼被稱為橫切(cross cutting),在 OOP 設計中,它導致了大量程式碼的重複,而不利於各個模組的重用。
AOP 技術恰恰相反,它利用一種稱為"橫切"的技術,剖解開封裝的物件內部,並將那些影響了多個類的公共行為封裝到一個可重用模組,並將其命名為"Aspect",即切面。所謂"切面",簡單說就是那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性。
使用"橫切"技術, AOP 把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處基本相似,比如許可權認證、日誌、事物。 AOP 的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。
AOP 核心就是切面,它將多個類的通用行為封裝成可重用的模組,該模組含有一組 API 提供橫切功能。比如,一個日誌模組可以被稱作日誌的 AOP 切面。根據需求的不同,一個應用程式可以有若干切面。在 Spring AOP 中,切面通過帶有@Aspect 註解的類實現。
34. 在 Spring AOP 中,關注點和橫切關注的區別是什麼?
關注點是應用中一個模組的行為,一個關注點可能會被定義成一個我們想實現的一個功能。橫切關注點是一個關注點,此關注點是整個應用都會使用的功能,並影響整個應用,比如日誌,安全和資料傳輸,幾乎應用的每個模組都需要的功能。因此這些都屬於橫切關注點。
35. 什麼是連線點?
被攔截到的點,因為 Spring 只支援方法型別的連線點,所以在 Spring 中連線點指的就是被攔截到的方法,實際上連線點還可以是欄位或者構造器。
36. Spring 的通知是什麼?有哪幾種類型?
通知是個在方法執行前或執行後要做的動作,實際上是程式執行時要通過 SpringAOP 框架觸發的程式碼段。
Spring 切面可以應用五種型別的通知:
before:前置通知,在一個方法執行前被呼叫。
after: 在方法執行之後呼叫的通知,無論方法執行是否成功。
after-returning: 僅當方法成功完成後執行的通知。
after-throwing: 在方法丟擲異常退出時執行的通知。
around: 在方法執行之前和之後呼叫的通知。
37. 什麼是切點?
切入點是一個或一組連線點,通知將在這些位置執行。可以通過表示式或匹配的方式指明切入點。
38. 什麼是目標物件?
被一個或者多個切面所通知的物件。它通常是一個代理物件。也指被通知(advised)物件。
39. 什麼是代理?
代理是通知目標物件後建立的物件。從客戶端的角度看,代理物件和目標物件是一樣的。
40. 什麼是織入? 什麼是織入應用的不同點?
織入是將切面和到其他應用型別或物件連線或建立一個被通知物件的過程。織入可以在編譯時,載入時,或執行時完成。
三、 Shiro
1. 簡單介紹一下 Shiro 框架
Apache Shiro 是 Java 的一個安全框架。使用 shiro 可以非常容易的開發出足夠好的應用,其不僅可以用在 JavaSE環境,也可以用在 JavaEE 環境。 Shiro 可以幫助我們完成:認證、授權、加密、會話管理、與 Web 整合、快取等。
三個核心元件: Subject, SecurityManager 和 Realms.
Subject:即“當前操作使用者” 。但是,在 Shiro 中, Subject 這一概念並不僅僅指人,也可以是第三方程序、後臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著“當前跟軟體互動的東西” 。但考慮到大多數目的和用途,你可以把它認為是 Shiro 的“使用者” 概念。
Subject 代表了當前使用者的安全操作, SecurityManager 則管理所有使用者的安全操作。
SecurityManager:它是 Shiro 框架的核心,典型的 Facade 模式, Shiro 通過 SecurityManager 來管理內部元件例項,並通過它來提供安全管理的各種服務。
Realm: Realm 充當了 Shiro 與應用安全資料間的“橋樑” 或者“聯結器” 。也就是說,當對使用者執行認證(登入)和授權(訪問控制)驗證時, Shiro 會從應用配置的 Realm 中查詢使用者及其許可權資訊。
2. Shiro 主要的四個元件
SecurityManager
典型的 Facade, Shiro 通過它對外提供安全管理的各種服務。
Authenticator
對“Who are you ?”進行核實。通常涉及使用者名稱和密碼。 這個元件負責收集 principals 和 credentials,並將它們提交給應用系統。如果提交的 credentials 跟應用系統中提供的 credentials 吻合,就能夠繼續訪問,否則需要重新提交 principals 和 credentials, 或者直接終止訪問。
Authorizer
身份份驗證通過後,由這個元件對登入人員進行訪問控制的篩查,比如“who can do what”, 或者“who can do which actions”。 Shiro 採用“基於 Realm”的方法,即使用者(又稱 Subject)、 使用者組、角 色和permission 的聚合體。
Session Manager
這個元件保證了異構客戶端的訪問,配置簡單。它是基於 POJO/J2SE 的,不跟任何的客戶 端或者協議繫結。
3. Shiro 執行原理
1、 Application Code:應用程式程式碼,就是我們自己的編碼,如果在程式中需要進 行許可權控制,需要呼叫Subject 的 API。
2、 Subject:主體,代表的了當前使用者。所有的 Subject 都繫結到 SecurityManager, 與 Subject 的所有互動都會委託給 SecurityManager,可以將 Subject 當成一個 門面,而真正執行者是 SecurityManager 。
3、 SecurityManage:安全管理器,所有與安全有關的操作都會與 SecurityManager 互動,並且它管理所有的 Subject 。
4、 Realm:域 shiro 是從 Realm 來獲取安全資料(使用者,角色,許可權)。就是說 SecurityManager要驗證使用者身份, 那麼它需要從 Realm 獲取相應的使用者進行比較以確定使用者 身份是否合法;也需要從Realm 得到使用者相應的角色/許可權進行驗證使用者是否 能進行操作; 可以把 Realm 看成 DataSource,即安全資料來源 。
4. Shiro 的四種許可權控制方式
url 級別許可權控制
方法註解許可權控制
程式碼級別許可權控制
頁面標籤許可權控制
詳見網址: https://www.cnblogs.com/cocosili/p/7103025.html
5. 授權實現的流程
(1)、什麼是粗顆粒和細顆粒許可權?
對資源型別的管理稱為粗顆粒度許可權控制,即只控制到選單、按鈕、方法,粗粒度的例子比如:使用者具有使用者管理的許可權,具有匯出訂單明細的許可權。對資源例項的控制稱為細顆粒度許可權管理,即控制到資料級別的許可權,比如:使用者只允許修改本部門的員工資訊,使用者只允許匯出自己建立的訂單明細。
總結:
粗顆粒許可權:針對 url 連結的控制。
細顆粒許可權:針對資料級別的控制。
比如:查詢使用者許可權。
衛生局可以查詢所有使用者。
衛生室可以查詢本單位的使用者。
通常在 service 中程式設計實現。
(2)、粗顆粒和細顆粒如何授權?
對於粗顆粒度的授權可以很容易做系統架構級別的功能,即系統功能操作使用統一的粗顆粒度的許可權管理。
對於細顆粒度的授權不建議做成系統架構級別的功能,因為對資料級別的控制是系統的業務需求,隨著業務需求的變更業務功能變化的可能性很大,建議對資料級別的許可權控制在業務層個性化開發,比如:使用者只允許修改自己建立的商品資訊可以在 service 介面新增校驗實現, service 介面需要傳入當前操作人的標識,與商品資訊建立人標識對比,不一致則不允許修改商品資訊。
粗顆粒許可權:可以使用過慮器統一攔截 url。
細顆粒許可權:在 service 中控制,在程式級別來控制,個性化 程式設計。
四、 Mybatis
1. Mybatis 中#和$的區別?
#相當於對資料 加上 雙引號, $相當於直接顯示資料
1. #將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。如: order by #user_id#,如果傳入的值是111,那麼解析成 sql 時的值為 order by "111", 如果傳入的值是 id,則解析成的 sql 為 order by "id".
2. $將傳入的資料直接顯示生成在 sql 中。如: order by $user_id$,如果傳入的值是 111,那麼解析成 sql 時的值為order by user_id, 如果傳入的值是 id,則解析成的 sql 為 order by id.
3. #方式能夠很大程度防止 sql 注入。
4.$方式無法防止 Sql 注入。
5.$方式一般用於傳入資料庫物件,例如傳入表名.
6.一般能用#的就別用$.
2. Mybatis 的程式設計步驟是什麼樣的?
1、建立 SqlSessionFactory
2、通過 SqlSessionFactory 建立 SqlSession
3、通過 sqlsession 執行資料庫操作
4、呼叫 session.commit()提交事務
5、呼叫 session.close()關閉會話
3. JDBC 程式設計有哪些不足之處, MyBatis 是如何解決這些問題的?
1. 資料庫連結建立、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用資料庫連結池可解決此問題。
解決:在 SqlMapConfig.xml 中配置資料鏈接池,使用連線池管理資料庫連結。
2. Sql 語句寫在程式碼中造成程式碼不易維護,實際應用 sql 變化的可能較大, sql 變動需要改變 java 程式碼。
解決:將 Sql 語句配置在 XXXXmapper.xml 檔案中與 java 程式碼分離。
3. 向 sql 語句傳引數麻煩,因為 sql 語句的 where 條件不一定,可能多也可能少,佔位符需要和引數一一對應。
解決: Mybatis 自動將 java 物件對映至 sql 語句。
4. 對結果集解析麻煩, sql 變化導致解析程式碼變化,且解析前需要遍歷,如果能將資料庫記錄封裝成 pojo 物件解析比較方便。
解決: Mybatis 自動將 sql 執行結果對映至 java 物件。
4. 使用 MyBatis 的 mapper 介面呼叫時有哪些要求?
1. Mapper 介面方法名和 mapper.xml 中定義的每個 sql 的 id 相同
2. Mapper 介面方法的輸入引數型別和 mapper.xml 中定義的每個 sql 的 parameterType 的型別相同
3. Mapper 介面方法的輸出引數型別和 mapper.xml 中定義的每個 sql 的 resultType 的型別相同
4. Mapper.xml 檔案中的 namespace 即是 mapper 介面的類路徑。
5. Mybatis 中一級快取與二級快取?
1. 一級快取: 基於 PerpetualCache 的 HashMap 本地快取,其儲存作用域為 Session,當 Session flush 或close 之後,該 Session 中的所有 Cache 就將清空。
2. 二級快取與一級快取其機制相同,預設也是採用 PerpetualCache, HashMap 儲存,不同在於其儲存作用域為Mapper(Namespace),並且可自定義儲存源,如 Ehcache。作用域為 namespance 是指對該 namespance 對應的配置檔案中所有的 select 操作結果都快取,這樣不同執行緒之間就可以共用二級快取。
啟動二級快取:在 mapper 配置檔案中: <cache />。
二級快取可以設定返回的快取物件策略: <cache readOnly="true">。當 readOnly="true"時,表示二級快取返回給所有呼叫者同一個快取物件例項,呼叫者可以 update 獲取的快取例項,但是這樣可能會造成其他呼叫者出現數據不一致的情況(因為所有呼叫者呼叫的是同一個例項)。當 readOnly="false"時,返回給呼叫者的是二級快取總快取物件的拷貝,即不同調用者獲取的是快取物件不同的例項,這樣呼叫者對各自的快取物件的修改不會影響到其他的呼叫者,即是安全的,所以預設是 readOnly="false";
3. 對於快取資料更新機制,當某一個作用域(一級快取 Session/二級快取 Namespaces)的進行了 C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear。
6. MyBatis 在 insert 插入操作時返回主鍵 ID
資料庫為 MySql 時:
1. <insert id="insert" parameterType="com.test.User" keyProperty="userId" useGeneratedKeys="true" >
“keyProperty”表示返回的 id 要儲存到物件的那個屬性中,“useGeneratedKeys”表示主鍵 id 為自增長模式。
MySQL 中做以上配置就 OK 了
資料庫為 Oracle 時:
1. <insert id="insert" parameterType="com.test.User">
2. <selectKey resultType="INTEGER" order="BEFORE" keyProperty="userId">
3. SELECT SEQ_USER.NEXTVAL as userId from DUAL
4. </selectKey>
5. insert into user (user_id, user_name, modified, state)
6. values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR},
#{modified,jdbcType=TIMESTAMP}, #{state,jdbcType=INTEGER})
7. </insert>
由於 Oracle 沒有自增長一說法,只有序列這種模仿自增的形式,所以不能再使用“useGeneratedKeys”屬性。而是使用<selectKey>將 ID 獲取並賦值到物件的屬性中, insert 插入操作時正常插入 id。
五、 Struts2
1. 簡單介紹一下 Struts2
struts2 框架是一個按照 MVC 設計模式設計的 WEB 層框架,是在 struts 1 和 WebWork 的技術基礎上進行了合併的全新的框架。其全新的 Struts 2 的體系結構與 Struts 1 的體 繫結構差別巨大。 Struts 2 以 WebWork 為核心,採用攔截器的機制來處理使用者的請求, 這樣的設計也使得業務邏輯控制器能夠與 ServletAPI 完全脫離開。
我們可以把 struts2 理解為一個大大的 servlet,而這個 servlet 就是 ActionServlet。struts2 在處理客戶端請求時,會先讀取 web.xml 配置檔案,根據前端控制器將符合條件的請求 分給各個不同的 Action 處理。 在此之前,會把ActionServlet 會把資料封裝成一個 javaBean。
struts2 框架提供了許多的攔截器,在封裝資料的過程中,我們可以對資料進行一些操 作,例如:資料校驗等等。
當 Action 執行完後要返回一個結果檢視,這個結果檢視可以跟據 struts2 的配置檔案中 配置,選擇轉發或者重定向。
2. Struts2 的執行流程瞭解麼?
參考資料: https://blog.csdn.net/wjw0130/article/details/46371847
Struts2 的官方文件附帶了 Struts2 的架構圖。從這張圖可以很好的去理解 Struts2
關於圖中的 Key:
Servlet Filters:過濾器鏈,客戶端的所有請求都要經過 Filter 鏈的處理。
Struts Core: Struts2 的核心部分,但是 Struts2 已經幫我們做好了,我們不需要去做這個
Interceptors, Struts2 的攔截器。 Struts2 提供了很多預設的攔截器,可以完成日常開發的絕大部分工作;而我們自定義的攔截器,用來實現實際的客戶業務需要的功能。
User Created,由開發人員建立的,包括 struts.xml、 Action、 Template,這些是每個使用 Struts2 來進行開發的人員都必須會的。
1.FilterDispatcher 是整個 Struts2 的排程中心,也就是 MVC 中的 C(控制中心),根據 ActionMapper 的結果來決定是否處理請求,如果 ActionMapper 指出該 URL 應該被 Struts2 處理,那麼它將會執行 Action 處理,並停止過濾器鏈上還沒有執行的過濾器。
2.ActionMapper 會判斷這個請求是否應該被 Struts2 處理,如果需要 Struts2 處理, ActionMapper 會返回一個物件來描述請求對應的 ActionInvocation 的資訊。
3.ActionProxy,它會建立一個 ActionInvocation 例項,位於 Action 和 xwork 之間,使得我們在將來有機會引入更多的實現方式,比如通過 WebService 來實現等。
4.ConfigurationManager 是 xwork 配置的管理中心,可以把它看做 struts.xml 這個配置檔案在記憶體中的對應。
5.struts.xml,是開發人員必須光顧的地方。是 Stuts2 的應用配置檔案,負責諸如 URL 與 Action 之間對映關係的配置、以及執行後頁面跳轉的 Result 配置等。
6.ActionInvocation:真正呼叫並執行 Action,它擁有一個 Action 例項和這個 Action 所依賴的攔截器例項。ActionInvocation 會按照指定的順序去執行這些攔截器、 Action 以及相應的 Result。
Interceptor(攔截器):是 Struts2 的基石,類似於 JavaWeb 的 Filter, 攔截器是一些無狀態的類,攔截器可以自動攔截 Action,它們給開發者提供了在 Action 執行之前或 Result 執行之後來執行一些功能程式碼的機會。
7.Action:用來處理請求,封裝資料。
3. Struts2 中 Action 配置的注意事項有哪些?
1.name 包名稱,在 struts2 的配置檔案中,包名不能重複, name 並不是真正包名,只是為了管理 Action
2.namespace 和 <action>的 name 屬性,決定 Action 的訪問路徑 (以/開始 )
3.extends 繼承哪個包,通常開發中繼承 struts-default 包 (struts-default 包 在 struts-default.xml 中定義 【可 )
以使用包中預設的攔截器和結果集】
4. 攔截器和過濾器有哪些區別?
* 攔截器是基於 java 的反射機制的,而過濾器是基於函式回撥
* 攔截器不依賴與 servlet 容器,而過濾器依賴與 servlet 容器
* 攔截器只能對 action 請求起作用,而過濾器則可以對幾乎所有的請求起作用
* 攔截器可以訪問 action 上下文、值棧裡的物件,而過濾器不能
* 在 action 的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一 次
5. Struts2 的封裝方式有哪些?
一、屬性封裝
1.在 action 中設定成員變數,變數名與表單中的 name 屬性值相同
2.生成變數的 set 方法
例項
獲取使用者輸入的使用者名稱和密碼
jsp 頁面
java 程式碼
二、模型驅動(常用)
1.action 實現 ModeDriven 介面
2.在 action 裡建立實體類物件
3.實現介面的 getModel 方法並返回所建立的物件
示例
獲取使用者輸入的使用者名稱和密碼
jsp 頁面
java 程式碼
需注意的是表單 name 的值應與類的屬性名相同。
三、表示式封裝
1.在 action 中宣告實體類
2.生成實體類的 set 和 get 方法
3.在表單輸入項的 name 屬性值裡面寫表示式
jsp 頁面
java 程式碼
6. 簡單介紹一下 Struts2 的值棧。
值棧是對應每一個請求物件的資料儲存中心。 Struts2 的一個很重要的特點就是引入了值棧。之前我們通過快取或者模型驅動在 action 和頁面之間傳遞資料,資料混亂,並且難以管理,快取還有時間和數量限制,使用起來非常的困難。值棧的引入解決了這個問題,它可以統一管理頁面和action 之間的資料,供 action、 result、 interceptor 等使用。我們大多數情況下不需要考慮值棧在哪裡,裡面有什麼,只需要去獲取自己需要的資料就可以了,大大的降低了開發人員的工作量和邏輯複雜性。
參考資料: https://www.cnblogs.com/hlhdidi/p/6185836.html
7. SpringMVC 和 Struts2 的區別?
1、 Struts2 是類級別的攔截, 一個類對應一個 request 上下文, SpringMVC 是方法級別的攔截,一個方法對應一個request 上下文,而方法同時又跟一個 url 對應,所以說從架構本身上 SpringMVC 就容易實現 restful url,而 struts2 的架構實現起來要費勁,因為 Struts2 中 Action 的一個方法可以對應一個 url,而其類屬性卻被所有方法共享,這也就無法用註解或其他方式標識其所屬方法了。
2、由上邊原因, SpringMVC 的方法之間基本上獨立的,獨享 request response 資料,請求資料通過引數獲取,處理結果通過 ModelMap 交回給框架,方法之間不共享變數,而 Struts2 搞的就比較亂,雖然方法之間也是獨立的,但其所有 Action 變數是共享的,這不會影響程式執行,卻給我們編碼 讀程式時帶來麻煩,每次來了請求就建立一個 Action,一個 Action 物件對應一個 request 上下文。
3、由於 Struts2 需要針對每個 request 進行封裝,把 request, session 等 servlet 生命週期的變數封裝成一個一個Map,供給每個 Action 使用,並保證執行緒安全,所以在原則上,是比較耗費記憶體的。
4、 攔截器實現機制上,Struts2 有以自己的 interceptor 機制,SpringMVC 用的是獨立的 AOP 方式,這樣導致 Struts2的配置檔案量還是比 SpringMVC 大。
5、 SpringMVC 的入口是 servlet,而 Struts2 是 filter(這裡要指出, filter 和 servlet 是不同的。),這就導致了二者的機制不同,這裡就牽涉到 servlet 和 filter 的區別了。
6、 SpringMVC 集成了 Ajax,使用非常方便,只需一個註解@ResponseBody 就可以實現,然後直接返回響應文字即可,而 Struts2 攔截器集成了 Ajax,在 Action 中處理時一般必須安裝外掛或者自己寫程式碼整合進去,使用起來也相對不方便。
7、 SpringMVC 驗證支援 JSR303,處理起來相對更加靈活方便,而 Struts2 驗證比較繁瑣,感覺太煩亂。
8、 Spring MVC 和 Spring 是無縫的。從這個專案的管理和安全上也比 Struts2 高(當然 Struts2 也可以通過不同的目錄結構和相關配置做到 SpringMVC 一樣的效果,但是需要 xml 配置的地方不少)。
9、 設計思想上, Struts2 更加符合 OOP 的程式設計思想, SpringMVC 就比較謹慎,在 servlet 上擴充套件。
10、 SpringMVC 開發效率和效能高於 Struts2。
11、 SpringMVC 可以認為已經 100%零配置。
8. Struts2 中的 # 和 % 分別是做什麼的?
(1)使用#獲取 context 裡面資料
<s:iterator value = “list” var=” user” >
<s:property value = “#user.username” >
</s:iterator>
(2)向 request 域放值(獲取 context 裡面資料,寫 ognl 時候,首先新增符號#context 的 key 名稱.域物件名稱)
(3)在頁面中使用 ognl 獲取
<s:property value = “#request.req” >
(4) %在 struts2 標籤中表單標籤
在 struts2 標籤裡面使用 ognl 表示式,如果直接在 struts2 表單標籤裡面使用 ognl 表示式不識別,只有%之後才會識別。
<s:textfield name=” username” value=” %{#request.req}” >
9. Struts2 中有哪些常用結果型別?
1) dispatcher :預設的請求轉發的結果型別, Action 轉發給 JSP
2) chain : Action 轉發到另一個 Action (同一次請求)
3) redirect : 重定向,重定向到一個路徑資訊,路徑資訊沒有限制(不在一個請求中) , Action 重定向到 JSP
4) redirectAction : Action 重定向到另一個 Action
5) stream :將原始資料作為流傳遞迴瀏覽器端,該結果型別對下載的內容和圖片非常有用。
6) freemarker :呈現 freemarker 模板。
7) plaintext :返回普通文字內容。
六、 Hibernate
1. 簡述一下 hibernate 的開發流程
第一步:載入 hibernate 的配置檔案,讀取配置檔案的引數(jdbc 連線引數,資料 庫方言, hbm 表與物件關係對映檔案)
第二步:建立 SessionFactory 會話工廠(內部有連線池)
第三步:開啟 session 獲取連線,構造 session 物件(一次會話維持一個數據連線,
也是一級快取)
第四步:開啟事務
第五步:進行操作
第六步:提交事務
第七步:關閉 session(會話)將連線釋放
第八步:關閉連線池
2. hibernate 中物件的三種狀態
瞬時態:(臨時態、自由態):不存在持久化標識 OID,尚未與 Hibernate Session 關聯物件, 被認為處於瞬時態,失去引用將被 JVM 回收
持久態:存在持久化標識 OID,與當前 session 有關聯,並且相關聯的 session 沒有關閉 , 並且事務未提交
脫管態:(離線態、遊離態):存在持久化標識 OID,但沒有與當前 session 關聯,脫管狀態 改變 hibernate 不能檢測到
3. hibernate 的快取機制。
Hibernate 快取分為兩層: Hibernate 的一級快取和 Hibernate 二級快取。
1.Hibernate 一級快取(Session 的快取):
(1) Session 實現了第一級 Cache,屬於事務級資料緩衝。一旦事務結束,快取隨之失效。一個 Session 的生命週期對應一個數據庫事務或一個程式事務。
(2) Session-Cache 總是被開啟並且不能被關閉的。
(3) Session-Cache 保證一個 Session 中兩次請求同一個物件時,取得的物件是同一個 Java 例項,有時它可以避免不必要的資料衝突。
a.在對於同一個物件進行迴圈引用時,不至於產生堆疊溢位。
b.當資料庫事務結束時,對於同一資料錶行,不會產生資料衝突。因為對於資料庫中的一行,最多有一個物件來表示它。
c.一個事務中可能會有很多個處理單元,在每一個處理單元中做的操作都會立即被其他的資料單元得知。
2.Hibernate 二級快取(SessionFactory 的快取):
(1)二級快取是 SessionFactory 範圍內的快取,所有的 Session 共享同一個二級快取。在二級快取中儲存持久化實
例的散裝形式的資料。
(2)持久化不同的資料需要不同的 Cache 策略,比如一些因素將影響 Cache 策略的選擇:資料的讀/寫比例、資料表
是否能被其他的應用程式所訪問等。
(3)設定 Hibernate 二級快取需要分兩步:首先,確認使用什麼資料併發策略。然後,配置快取過期時間並設定 Cache
提供器。
4. Hibernate 的查詢方式有哪些?
Hibernate 的查詢方式常見的主要分為三種: HQL, QBC(命名查詢) , 以及使用原生 SQL 查詢(SqlQuery)
參考資料: https://blog.csdn.net/u010963948/article/details/16818043
5. Hibernate 和 Mybatis 的區別?
Hibernate 與 MyBatis 都可以是通過 SessionFactoryBuider 由 XML 配置檔案生成 SessionFactory,然後由SessionFactory 生成 Session,最後由 Session 來開啟執行事務和 SQL 語句。其中 SessionFactoryBuider,SessionFactory, Session 的生命週期都是差不多的。
Hibernate 和 MyBatis 都支援 JDBC 和 JTA 事務處理。
Mybatis 優勢:
MyBatis 可以進行更為細緻的 SQL 優化,可以減少查詢欄位。
MyBatis 容易掌握,而 Hibernate 門檻較高。
Hibernate 優勢:
Hibernate 的 DAO 層開發比 MyBatis 簡單, Mybatis 需要維護 SQL 和結果對映。
Hibernate 對物件的維護和快取要比 MyBatis 好,對增刪改查的物件的維護要方便。
Hibernate 資料庫移植性很好, MyBatis 的資料庫移植性不好,不同的資料庫需要寫不同 SQL。
Hibernate 有更好的二級快取機制,可以使用第三方快取。 MyBatis 本身提供的快取機制不佳。
6. Hibernate 和 JDBC 優缺點對比
相同點:
兩者都是 java 資料庫操作的中介軟體、
兩者對資料庫進行直接操作的物件都是執行緒不安全的,都需要及時關閉。
兩者都可對資料庫的更新操作進行顯式的事務處理。
不同點:
JDBC 是 SUN 公司提供一套操作資料庫的規範,使用 java 程式碼操作資料庫。 Hibernate 是一個基於 jdbc 的主流持久化框架,對 JDBC 訪問資料庫的程式碼做了封裝。
使用的 SQL 語言不同: JDBC 使用的是基於關係型資料庫的標準 SQL 語言, Hibernate 使用的是 HQL(Hibernate query language)語言。
操作的物件不同: JDBC 操作的是資料,將資料通過 SQL 語句直接傳送到資料庫中執行, Hibernate 操作的是持久化物件,由底層持久化物件的資料更新到資料庫中。
資料狀態不同: JDBC 操作的資料是“瞬時”的,變數的值無法與資料庫中的值保持一致,而 Hibernate 操作的資料是可持久的,即持久化物件的資料屬性的值是可以跟資料庫中的值保持一致的。
7. 關於 Hibernate 的 orm 思想你瞭解多少?
ORM 指的是物件關係型對映(Object RelationShip Mapping ), 指的就是我們通過建立實體類物件和資料庫中的表關係進行一一對應,來實現通過操作實體類物件來更改資料庫裡邊的資料資訊。這裡邊起到關鍵作用的是通過
Hibernate 的對映檔案+Hibernate 的核心配置檔案。
詳細內容請見: https://blog.csdn.net/wanghuan203/article/details/7566518
8. get 和 load 的區別?
(1) get 是立即載入, load 是延時載入。
(2) get 會先查一級快取,再查二級快取,然後查資料庫;load 會先查一級快取,如果沒有找到,就建立代理物件,等需要的時候去查詢二級快取和資料庫。 (這裡就體現 load 的延遲載入的特性。 )
(3) get 如果沒有找到會返回 null, load 如果沒有找到會丟擲異常。
(4)當我們使用 session.load()方法來載入一個物件時,此時並不會發出 sql 語句,當前得到的這個物件其實是一個代理物件,這個代理物件只儲存了實體物件的 id 值,只有當我們要使用這個物件,得到其它屬性時,這個時候才會發出 sql 語句,從資料庫中去查詢我們的物件;相對於 load 的延遲載入方式, get 就直接的多,當我們使用session.get()方法來得到一個物件時,不管我們使不使用這個物件,此時都會發出 sql 語句去從資料庫中查詢出來。
9. 如何進行 Hibernate 的優化?
(1) 資料庫設計調整。
(2) HQL 優化。
(3) API 的正確使用(如根據不同的業務型別選用不同的集合及查詢 API)。
(4) 主配置引數(日誌,查詢快取, fetch_size, batch_size 等)。
(5) 對映檔案優化(ID 生成策略,二級快取,延遲載入,關聯優化)。
(6) 一級快取的管理。
(7) 針對二級快取,還有許多特有的策略。
(8) 事務控制策略。
詳情解釋請見:https://www.cnblogs.com/xhj123/p/6106088.html
10. 什麼是 Hibernate 延遲載入?
延遲載入機制是為了避免一些無謂的效能開銷而提出來的,所謂延遲載入就是當在真正需要資料的時候,才真正執行資料載入操作。在 Hibernate 中提供了對實體物件的延遲載入以及對集合的延遲載入,另外在 Hibernate3 中還提供了對屬性的延遲載入。
延遲載入的過程:通過代理(Proxy)機制來實現延遲載入。 Hibernate 從資料庫獲取某一個物件資料時、獲取某一個物件的集合屬性值時,或獲取某一個物件所關聯的另一個物件時,由於沒有使用該物件的資料(除識別符號外),Hibernate 並不從資料庫載入真正的資料,而只是為該物件建立一個代理物件來代表這個物件,這個物件上的所有屬性都為預設值;只有在真正需要使用該物件的資料時才建立這個真正的物件,真正從資料庫中載入它的資料。
11. No Session 問題原理及解決方法?
Nosession 問題報錯如下:
根據字面上的意思,是指代理不能被初始化, session 已經關閉。
Nosession 問題產生的原因:
當執行 Session 的 load()方法時, Hibernate 不會立即執行查詢所查詢物件關聯的物件(在此我們統稱被關聯的物件類為 A 類),僅僅返回 A 類的代理類的例項,這個代理類具由以下特徵:
(1)由 Hibernate 在執行時動態生成,它擴充套件了 A 類,因此它繼承了 A 類的所有屬性和方法,但它的實現對於應用程式是透明的。
(2)當 Hibernate 建立 A 類代理類例項時,僅僅初始化了它的 OID 屬性,其他屬性都為 null,因此這個代理類例項佔用的記憶體很少。
(3)當應用程式第一次訪問 A 代理類例項時(例如呼叫 a..getXXX()或 a.setXXX()方法), Hibernate 會初始化代理類例項,在初始化過程中執行 select 語句,真正從資料庫中載入 A 物件的所有資料。但有個例外,那就是當應用程式訪問 A 代理類例項的 getId()方法時, Hibernate 不會初始化代理類例項,因為在建立代理類例項時 OID 就存在了,不必到資料庫中去查詢。
提示: Hibernate 採用 CGLIB 工具來生成持久化類的代理類。 CGLIB 是一個功能強大的 Java 位元組碼生成工具,它能夠在程式執行時動態生成擴充套件 Java 類或者實現 Java 介面的代理類。
因為 Hibernate 中如果採用 load 載入的話(預設的是延遲載入),也就是 lazy=true 操作,因此,當呼叫完 load後, session 即可關閉。因為我們的 session 只是放置到了 Dao 層,表現層根本獲取不到,所以在表現層呼叫的時候, session 已經關閉,報錯。
12. Spring 的兩種代理 JDK 和 CGLIB 的區別淺談
Java 動態代理是利用反射機制生成一個實現代理介面的匿名類,在呼叫具體方法前呼叫 InvokeHandler 來處理。而 cglib 動態代理是利用 asm 開源包,對代理物件類的 class 檔案載入進來,通過修改其位元組碼生成子類來處理。
1、如果目標物件實現了介面,預設情況下會採用 JDK 的動態代理實現 AOP
2、如果目標物件實現了介面,可以強制使用 CGLIB 實現 AOP
3、如果目標物件沒有實現了介面,必須採用 CGLIB 庫, spring 會自動在 JDK 動態代理和 CGLIB 之間轉換
參考資料: https://blog.csdn.net/tanga842428/article/details/52716875
13.敘述 Session 的快取的作用
(1)減少訪問資料庫的頻率。應用程式從記憶體中讀取持久化物件的速度顯然比到資料庫中查詢資料的速度快多了,因此 Session 的快取可以提高資料訪問的效能。
(2)保證快取中的物件與資料庫中的相關記錄保持同步。當快取中持久化物件的狀態發生了變換, Session 並不會立即執行相關的 SQL 語句,這使得 Session 能夠把幾條相關的 SQL 語句合併為一條 SQL 語句,以便減少訪問資料庫的次數,從而提高應用程式的效能。
14.Session 的清理和清空有什麼區別?
Session 清理快取是指按照快取中物件的狀態的變化來同步更新資料庫;清空是 Session 的關閉;
15.請簡述 Session 的特點有哪些?
(1)不是執行緒安全的,因此在設計軟體架構時,應該避免多個執行緒共享同一個 Session 例項。
(2)Session 例項是輕量級的,所謂輕量級是指它的建立和銷燬不需要消耗太多的資源。這意味著在程式中可以經常建立或銷燬 Session 物件,例如為每個客戶請求分配單獨的 Session 例項,或者為每個工作單元分配單獨的 Session 例項。
(3)在 Session 中,每個資料庫操作都是在一個事務(transaction)中進行的,這樣就可以隔離開不同的操作(甚至包括只讀操作)。
16.比較 Hibernate 三種檢索策略的優缺點
1、立即檢索
優點:對應用程式完全透明,不管物件處於持久化狀態,還是遊離狀態,應用程式都可以方便的從一個物件導航到與它關聯的物件;
缺點: 1.select 語句太多; 2.可能會載入應用程式不需要訪問的物件白白浪費許多記憶體空間;
2、延遲檢索
優點:由應用程式決定需要載入哪些物件,可以避免可執行多餘的 select 語句,以及避免載入應用程式不需要訪問的物件。因此能提高檢索效能,並且能節省記憶體空間;
缺點:應用程式如果希望訪問遊離狀態代理類例項,必須保證他在持久化狀態時已經被初始化;
3、 迫切左外連線檢索
優點: 1、對應用程式完全透明,不管物件處於持久化狀態,還是遊離狀態,應用程式都可以方便地衝一個物件導航到與它關聯的物件。 2、