進階spring/Hibernate*框架精選面試題

  • 2019 年 10 月 5 日
  • 筆記

,今天給大家帶來的是一些Java框架的面試題,這些面試題涵蓋Hibernate框架,spring框架等,建議收藏

  • struts中的幾個關鍵對象的作用(說說幾個關鍵對象的作用)

對象名稱

作用

Action

控制器類

ActionForm

表單對象

DynaValidatorForm

動態form

ActonMapping

配置文件中action節點的信息

  • 介紹一下Hibernate的二級緩存

可按照以下思路來回答:(1)首先說清楚什麼是緩存,(2)再說有了hibernate的Session就是一級緩存,即有了一級緩存,為什麼還要有二級緩存,(3)最後再說如何配置Hibernate的二級緩存。

(1)緩存就是把以前從數據庫中查詢出來和使用過的對象保存在內存中(一個數據結構中),這個數據結構通常是或類似Hashmap,當以後要使用某個對象時,先查詢緩存中是否有這個對象,如果有則使用緩存中的對象,如果沒有則去查詢數據庫,並將查詢出來的對象保存在緩存中,以便下次使用。

(2)Hibernate的Session就是一種緩存,我們通常將之稱為Hibernate的一級緩存,當想使用session從數據庫中查詢出一個對象時,Session也是先從自己內部查看是否存在這個對象,存在則直接返回,不存在才去訪問數據庫,並將查詢的結果保存在自己內部。由於Session代表一次會話過程,一個Session與一個數據庫連接相關連,所以Session最好不要長時間保持打開,通常僅用於一個事務當中,在事務結束時就應關閉。並且Session是線程不安全的,被多個線程共享時容易出現問題。通常只有那種全局意義上的緩存才是真正的緩存應用,才有較大的緩存價值,因此,Hibernate的Session這一級緩存的緩存作用並不明顯,應用價值不大。Hibernate的二級緩存就是要為Hibernate配置一種全局緩存,讓多個線程和多個事務都可以共享這個緩存。我們希望的是一個人使用過,其他人也可以使用,session沒有這種效果。

(3)二級緩存是獨立於Hibernate的軟件部件,屬於第三方的產品,多個廠商和組織都提供有緩存產品,例如,EHCache和OSCache等等。在Hibernate中使用二級緩存,首先就要在hibernate.cfg.xml配置文件中配置使用哪個廠家的緩存產品,接着需要配置該緩存產品自己的配置文件,最後要配置Hibernate中的哪些實體對象要納入到二級緩存的管理中。明白了二級緩存原理和有了這個思路後,很容易配置起Hibernate的二級緩存。擴展知識:一個SessionFactory可以關聯一個二級緩存,也即一個二級緩存只能負責緩存一個數據庫中的數據,當使用Hibernate 的二級緩存後,注意不要有其他的應用或SessionFactory來更改當前數據庫中的數據,這樣緩存的數據就會與數據庫中的實際數據不一致。

  • 在hibernate 中,在配置文件呈標題一對多,多對多的標籤是什麼;2)Hibernate 的二級緩存是什麼;3)Hibernate 是如何處理事務的; 答:1)一對多的標籤為;多對多的標籤為;

2)sessionFactory 的緩存為hibernate 的二級緩存;

3)Hibernate 的事務實際上是底層的JDBC Transaction 的封裝或者是JTA

Transaction 的封裝;默認情況下使用JDBCTransaction。

  • 什麼是ORM?【基礎】

答:對象關係映射(Object—Relational Mapping,簡稱ORM)是一種為了解決面向對象與面向關係數據庫存在的互不匹配的現象的技術;簡單的說,ORM 是通過使用描述對象和數據庫之間映射的元數據,將java 程序中的對象自動持久化到關係數據庫中;本質上就是將數據從一種形式轉換到另外一種形式。

  • Hibernate中session的load()和get()的區別

hibernate對於load方法認為該數據在數據庫中一定存在,可以放心的使用代理來延遲加載,load默認支持延遲加載,在用到對象中的其他屬性數據時才查詢數據庫,但是萬一數據庫中不存在該記錄,只能拋異常ObjectNotFoundException;

所說的load方法拋異常是指在使用該對象的數據時,數據庫中不存在該數據時拋異常,而不是在創建這個對象時。

由於session中的緩存對於hibernate來說是個相當廉價的資源,所以在load時會先查一下session緩存看看該id對應的對象是否存在,

不存在則創建代理(load時候之查詢一級緩存,不存在則創建代理)。get()現在一級緩存找,沒有就去二級緩存找,沒有就去數據庫找,沒有就返回null ;

而對於get方法,hibernate一定要獲取到真實的數據,否則返回null。

  • Hibernate中標籤如何實現樂觀並發控制的:?

樂觀並發控制即所謂的樂觀鎖機制,他有好幾種實現方式,是其中一種:通過為數據增加一個版本標誌即version,讀取數據時一同讀出該數據的版本,更新數據時對數據的版本加1,在提交數據時與數據庫中的相應數據進行比較,若版本號大於數據庫中的版本號則認為是新數據,更新數據庫中的數據;

如果小於數據庫中的號則認為是過期數據。

  • 請寫出spring 中I0C 的三種實現機制。

答:三種機製為:通過setter 方法注入、通過構造方法注入和接口注入

  • spring在項目中如何充當粘合劑?

1、在項目中利用spring的IOC(控制反轉或依賴注入),明確地定義組件接口(如UserDAO),開發者可以獨立開發各個組件, 然後根據組件間的依賴關係組裝(UserAction依賴於UserBiz,UserBiz依賴於UserDAO)運行,很好的把Struts(Action)和hibernate(DAO的實現)結合起來了。

2、spring的事務管理把hibernate對數據庫的操作進行了事務配置。

  • 項目中如何體現Spring中的切面編程,舉例說明

面向切面編程:主要是橫切一個關注點,將一個關注點模塊化成一個切面。在切面上聲明一個通知(Advice)和切入點(Pointcut); 通知: 是指在切面的某個特定的連接點(代表一個方法的執行。通過聲明一個org.aspectj.lang.JoinPoint類型的參數可以使通知(Advice)的主體部分獲得連接點信息。)上執行的動作。通知中定義了要插入的方法。切入點:切入點的內容是一個表達式,以描述需要在哪些對象的哪些方法上插入通知中定義的方法。

項目中用到的Spring中的切面編程最多的地方:聲明式事務管理。

a、定義一個事務管理器

b、配置事務特性(相當於聲明通知。一般在業務層的類的一些方法上定義事務)

c、配置哪些類的哪些方法需要配置事務(相當於切入點。一般是業務類的方法上)

  • Spring對多種ORM框架提供了很好的支持,簡單描述在Spring中使用Hibernate的方法,並結合事務管理。

getHiberanteTemplate裏面提供了save,update,delete,find等方法。

簡單說一個:如果配置了聲明式事務,當執行getHibernateTemplate的各種方法的時候,事務會自動被加載;

如果沒有配置事務,那麼以上操作不會真正的被同步到數據庫,除非配置了hibernate的autocommit=true;

  • spring的事務有幾種方式?談談spring事務的隔離級別和傳播行為。

spring事務分兩種形式,聲明式事務和編程式事務,spring提供了一個事務的接口PaltformTractionManager接口,針對不同的事務,spring進行了不同的實現,對hibernate事務的實現HIbernateTractionManager,對JDBC的JdbcTractionManager,DataSourceTractionManager以及JdoTractionManager。接platformTractionManager提供了三個方法,獲取事務,提交和回滾的方法。

  • 解釋一下Dependency injection(DI,依賴注入)和IOC(Inversion of control,控制反轉)?

依賴注入DI是一個程序設計模式和架構模型, 一些時候也稱作控制反轉,儘管在技術上來講,依賴注入是一個IOC的特殊實現,依賴注入是指一個對象應用另外一個對象來提供一個特殊的能力,例如:把一個數據庫連接已參數的形式傳到一個對象的結構方法裏面而不是在那個對象內部自行創建一個連接。控制反轉和依賴注入的基本思想就是把類的依賴從類內部轉化到外部以減少依賴

應用控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用,傳遞給它。也可以說,依賴被注入到對象中。所以,控制反轉是,關於一個對象如何獲取他所依賴的對象的引用,這個責任的反轉

  • 介紹一下Spring的事務管理?

事務就是對一系列的數據庫操作(比如插入多條數據)進行統一的提交或回滾操作,如果插入成功,那麼一起成功,如果中間有一條出現異常,那麼回滾之前的所有操作。 這樣可以防止出現臟數據,防止數據庫數據出現問題。

開發中為了避免這種情況一般都會進行事務管理。Spring中也有自己的事務管理機制,一般是使用TransactionMananger進行管理,可以通過Spring的注入來完成此功能

  • 有哪些不同類型的IOC(依賴注入)方式?

構造器依賴注入:構造器依賴注入通過容器觸發一個類的構造器來實現的,該類有一系列參數,每個參數代表一個對其他類的依賴。

Setter方法注入:Setter方法注入是容器通過調用無參構造器或無參static工廠 方法實例化bean之後,調用該bean的setter方法,即實現了基於setter的依賴注入

  • SpringMVC與Struts2區別與比較總結?

1、Struts2是類級別的攔截, 一個類對應一個request上下文,SpringMVC是方法級別的攔截,一個方法對應一個request上下文,

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是不同的。以前認為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。

  • 使用Spring框架的好處是什麼?

輕量:Spring 是輕量的,基本的版本大約2MB。

控制反轉:Spring通過控制反轉實現了鬆散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。

面向切面的編程(AOP):Spring支持面向切面的編程,並且把應用業務邏輯和系統服務分開。

容器:Spring 包含並管理應用中對象的生命周期和配置。

MVC框架:Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。

事務管理:Spring 提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。

異常處理:Spring 提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate or JDO拋出的)轉化為一致的unchecked 異常。

  • Ibatis中#與$的區別?
  • #是把傳入的數據當作字符串,如#field#傳入的是id,則生成sql語句:order by 「id」;
  • $傳入的數據直接生成在sql里,如#field#傳入的是id,則sql語句生成是這樣,order by id ;
  • #方式能夠很大程度防止sql注入, 但$方式無法防止sql注入;
  • $方式一般用於傳入數據庫對象.例如傳入表名;
  • 一般能用#的就別用$ ;
  • Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理:

(1)JDK動態代理只提供接口的代理,不支持類的代理。核心InvocationHandler接口和Proxy類,InvocationHandler 通過invoke()方法反射來調用目標類中的代碼,動態地將橫切邏輯和業務編織在一起;接着,Proxy利用 InvocationHandler動態創建一個符合某一接口的的實例, 生成目標類的代理對象。

(2)如果代理類沒有實現 InvocationHandler 接口,那麼Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個代碼生成的類庫,可以在運行時動態的生成指定類的一個子類對象,並覆蓋其中特定方法並添加增強代碼,從而實現AOP。CGLIB是通過繼承的方式做的動態代理,因此如果某個類被標記為final,那麼它是無法使用CGLIB做動態代理的。

(3)靜態代理與動態代理區別在於生成AOP代理對象的時機不同,相對來說AspectJ的靜態代理方式具有更好的性能,但是AspectJ需要特定的編譯器進行處理,而Spring AOP則無需特定的編譯器處理。

  • BeanFactory和ApplicationContext有什麼區別?

BeanFactory和ApplicationContext是Spring的兩大核心接口,都可以當做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

一丶

BeanFactory:是Spring裏面最底層的接口,包含了各種Bean的定義,讀取bean配置文檔,管理bean的加載、實例化,控制bean的生命周期,維護bean之間的依賴關係。ApplicationContext接口作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能:

①繼承MessageSource,因此支持國際化。

②統一的資源文件訪問方式。

③提供在監聽器中註冊bean的事件。

④同時加載多個配置文件。

⑤載入多個(有繼承關係)上下文 ,使得每一個上下文都專註於一個特定的層次,比如應用的web層。

二丶

(1)BeanFactroy採用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調用getBean()),才對該Bean進行加載實例化。這樣,我們就不能發現一些存在的Spring的配置問題。如果Bean的某一個屬性沒有注入,BeanFacotry加載後,直至第一次使用調用getBean方法才會拋出異常。

(2)ApplicationContext,它是在容器啟動時,一次性創建了所有的Bean。這樣,在容器啟動時,我們就可以發現Spring中存在的配置錯誤,這樣有利於檢查所依賴屬性是否注入。 ApplicationContext啟動後預載入所有的單實例Bean,通過預載入單實例bean ,確保當你需要的時候,你就不用等待,因為它們已經創建好了。

(3)相對於基本的BeanFactory,ApplicationContext 唯一的不足是佔用內存空間。當應用程序配置Bean較多時,程序啟動較慢。

(4)BeanFactory通常以編程的方式被創建,ApplicationContext還能以聲明的方式創建,如使用ContextLoader。

(5)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動註冊,而ApplicationContext則是自動註冊。

  • Spring框架中的單例Beans是線程安全的么?

Spring框架並沒有對單例bean進行任何多線程的封裝處理。關於單例bean的線程安全和並發問題需要開發者自行去搞定。但實際上,大部分的Spring bean並沒有可變的狀態(比如Serview類和DAO類),所以在某種程度上說Spring的單例bean是線程安全的。如果你的bean有多種狀態的話(比如 View Model 對象),就需要自行保證線程安全。最淺顯的解決辦法就是將多態bean的作用域由「singleton」變更為「prototype」。

  • Spring如何處理線程並發問題?

在一般情況下,只有無狀態的Bean才可以在多線程環境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域,因為Spring對一些Bean中非線程安全狀態採用ThreadLocal進行處理,解決線程安全問題。

ThreadLocal和線程同步機制都是為了解決多線程中相同變量的訪問衝突問題。同步機制採用了「時間換空間」的方式,僅提供一份變量,不同的線程在訪問前需要獲取鎖,沒獲得鎖的線程則需要排隊。而ThreadLocal採用了「空間換時間」的方式。

ThreadLocal會為每一個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問衝突。因為每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。

  • Spring 框架中都用到了哪些設計模式?

(1)工廠模式:BeanFactory就是簡單工廠模式的體現,用來創建對象的實例;

(2)單例模式:Bean默認為單例模式。

(3)代理模式:Spring的AOP功能用到了JDK的動態代理和CGLIB位元組碼生成技術;

(4)模板方法:用來解決代碼重複的問題。比如. RestTemplate, JmsTemplate, JpaTemplate。

(5)觀察者模式:定義對象鍵一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都會得到通知被制動更新,如Spring中listener的實現–ApplicationListener。

  • spring有哪些模塊組成?

Spring Core:核心類庫,提供IOC服務;

Spring Context:提供框架式的Bean訪問方式,以及企業級功能(JNDI、定時任務等);

Spring AOP:AOP服務;

Spring DAO:對JDBC的抽象,簡化了數據訪問異常的處理;

Spring ORM:對現有的ORM框架的支持;

Spring Web:提供了基本的面向Web的綜合特性,例如多方文件上傳;

Spring MVC:提供面向Web應用的Model-View-Controller實現。