Hibernate的緩存機制
一、Hibernate是一個持久層框架,常常訪問物理數據庫,爲了下降應用程序對物理數據源訪問的頻次,從而提升應用程序的運行性能。
緩存內的數據是對物理數據源中的數據的複製,應用程序在運行時從緩存讀寫數據,在特定的時刻或事件會同步緩存和物理數據源的數據。
二、Hibernate一級緩存又稱爲「Session的緩存」,它是內置的,不能被卸載(不能被卸載的意思就是這種緩存不具備可選性,
必須有的功能,不能夠取消session緩存)。
因爲Session對象的生命週期一般對應一個數據庫事務或者一個應用事務,所以它的緩存是事務範圍的緩存。
三、Hibernate二級緩存又稱爲「SessionFactory的緩存」,因爲SessionFactory對象的生命週期和應用程序的整個過程對應,
所以Hibernate二級緩存是進程範圍或者集羣範圍的緩存,有可能出現併發問題,所以須要採用適當的併發訪問策略,
該策略爲被緩存的數據提供了事務隔離級別。
四、不管什麼時候,咱們在管理Hibernate緩存(Managing the caches)時,當你給save()、update()或saveOrUpdate()方法傳遞一個對象時,
或使用load()、 get()、list()、iterate() 或scroll()方法得到一個對象時, 該對象都將被加入到Session的內部緩存中。前端
二、什麼是線程,線程和進程的區別 ,java如何實現線程
線程是操做系統可以進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運做單位。java
區別:線程是進程的子集,一個進程能夠有不少線程,每條線程並行執行不一樣的任務。不一樣的進程使用不一樣的內存空間,而全部的線程共享一片相同的內存空間。每一個線程都擁有單獨的棧內存用來存儲本地數據。程序員
實現線程:繼承Thread或實現Runnable接口 ;這兩種方法都能實現線程 區別是 java 不支持類的多重繼承, 但容許調用多個接口,若是要繼承其餘類 只能調用Runnable接口算法
三、 Thread 類中的start() 和 run() 方法有什麼區別?
start()方法被用來啓動新建立的線程,並且start內部調用了run()方法,這和直接調用run()方法的效果不同。當你調用run()方法的時候,
只會是在原來的線程中調用,沒有新的線程啓動,start()方法纔會啓動新線程。數據庫
四、Java中的volatile 變量是什麼?
volatile是一個特殊的修飾符,只有成員變量才能使用它。在Java併發程序缺乏同步類的狀況下,多線程對成員變量的操做對其它線程是透明的。
volatile變量能夠保證下一個讀取操做會在前一個寫操做以後發生 編程
五、什麼是線程安全?Vector是一個線程安全類嗎?
若是你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。若是每次運行結果和單線程運行的結果是同樣的,並且其餘的變量的值也和預期的是同樣的,就是線程安全的。一個線程安全的計數器類的同一個實例對象在被多個線程使用的狀況下也不會出現計算失誤。
Vector 是用同步方法來實現線程安全的, 而和它類似的ArrayList不是線程安全的。設計模式
六、Java中如何中止一個線程?
Java提供了很豐富的API但沒有爲中止線程提供API。
JDK 1.0原本有一些像stop(), suspend() 和 resume()的控制方法可是因爲潛在的死鎖威脅所以在後續的JDK版本中他們被棄用了,
以後Java API的設計者就沒有提供一個兼容且線程安全的方法來中止一個線程。
當run() 或者 call() 方法執行完的時候線程會自動結束,若是要手動結束一個線程,你能夠用volatile 布爾變量來退出run()方法的循環或者是取消任務來中斷線程。數組
七、一個線程運行時發生異常會怎樣?
若是異常沒有被捕獲該線程將會中止執行。Thread.UncaughtExceptionHandler是用於處理未捕獲異常形成線程忽然中斷狀況的一個內嵌接口。
當一個未捕獲異常將形成線程中斷的時候JVM會使用Thread.getUncaughtExceptionHandler()來查詢線程的UncaughtExceptionHandler並將線程和異常做爲參數傳遞給handler的uncaughtException()方法進行處理。緩存
八、Java中notify 和 notifyAll有什麼區別?
由於多線程能夠等待單監控鎖,Java API 的設計人員提供了一些方法當等待條件改變的時候通知它們,可是這些方法沒有徹底實現。
notify()方法不能喚醒某個具體的線程,因此只有一個線程在等待的時候它纔有用武之地。
而notifyAll()喚醒全部線程並容許他們爭奪鎖確保了至少有一個線程能繼續運行。安全
九、爲何wait, notify 和 notifyAll這些方法不在thread類裏面?
一個很明顯的緣由是JAVA提供的鎖是對象級的而不是線程級的,每一個對象都有鎖,經過線程得到。
若是線程須要等待某些鎖那麼調用對象中的wait()方法就有意義了。若是wait()方法定義在Thread類中,線程正在等待的是哪一個鎖就不明顯了。
簡單的說,因爲wait,notify和notifyAll都是鎖級別的操做,因此把他們定義在Object類中由於鎖屬於對象。
十、Java中的同步集合與併發集合有什麼區別?
同步集合與併發集合都爲多線程和併發提供了合適的線程安全的集合,不過併發集合的可擴展性更高。
併發集合像ConcurrentHashMap,不只提供線程安全還用鎖分離和內部分區等現代技術提升了可擴展性。
十一、Java中堆和棧有什麼不一樣?
每一個線程都有本身的棧內存,用於存儲本地變量,方法參數和棧調用,一個線程中存儲的變量對其它線程是不可見的。
而堆是全部線程共享的一片公用內存區域。對象都在堆裏建立,爲了提高效率線程會從堆中弄一個緩存到本身的棧,若是多個線程使用該變量就可能引起問題,這時volatile 變量就能夠發揮做用了,它要求線程從主存中讀取變量的值。
十二、什麼是線程池? 爲何要使用它?
建立線程要花費昂貴的資源和時間,若是任務來了才建立線程那麼響應時間會變長,並且一個進程能建立的線程數有限。
爲了不這些問題,在程序啓動的時候就建立若干線程來響應處理,它們被稱爲線程池,裏面的線程叫工做線程。從JDK1.5開始,Java API提供了Executor框架讓你能夠建立不一樣的線程池。好比單線程池,每次處理一個任務;數目固定的線程池或者是緩存線程池(一個適合不少生存期短的任務的程序的可擴展線程池)。
1三、如何避免死鎖?
Java多線程中的死鎖死鎖是指兩個或兩個以上的進程在執行過程當中,因爭奪資源而形成的一種互相等待的現象,若無外力做用,它們都將沒法推動下去。
死鎖的發生必須知足如下四個條件:
互斥條件:一個資源每次只能被一個進程使用。
請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
避免死鎖最簡單的方法就是阻止循環等待條件,將系統中全部的資源設置標誌位、排序,規定全部的進程申請資源必須以必定的順序(升序或降序)作操做來避免死鎖。
1四、 Java中活鎖和死鎖有什麼區別?
這是上題的擴展,活鎖和死鎖相似,不一樣之處在於處於活鎖的線程或進程的狀態是不斷改變的,活鎖能夠認爲是一種特殊的飢餓。一個現實的活鎖例子是兩我的在狹小的走廊碰到,兩我的都試着避讓對方好讓彼此經過,可是由於避讓的方向都同樣致使最後誰都不能經過走廊。簡單的說就是,活鎖和死鎖的主要區別是前者進程的狀態能夠改變可是卻不能繼續執行。
1五、怎麼檢測一個線程是否擁有鎖?
在java.lang.Thread中有一個方法叫holdsLock(),當且僅當當前線程擁有某個具體對象的鎖它返回true。
1六、有三個線程T1,T2,T3,怎麼確保它們按順序執行?
在多線程中有多種方法讓線程按特定順序執行,你能夠用線程類的join()方法在一個線程中啓動另外一個線程,另一個線程完成該線程繼續執行。爲了確保三個線程的順序你應該先啓動最後一個(T3調用T2,T2調用T1),這樣T1就會先完成而T3最後完成。
1七、 Java線程池中submit() 和 execute()方法有什麼區別?
兩個方法均可以向線程池提交任務,execute()方法的返回類型是void,它定義在Executor接口中, 而submit()方法能夠返回持有計算結果的Future對象,它定義在ExecutorService接口中,它擴展了Executor接口,其它線程池類像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有這些方法。
1八、什麼是阻塞式方法?
阻塞式方法是指程序會一直等待該方法完成期間不作其餘事情,ServerSocket的accept()方法就是一直等待客戶端鏈接。這裏的阻塞是指調用結果返回以前,當前線程會被掛起,直到獲得結果以後纔會返回。此外,還有異步和非阻塞式方法在任務完成前就返回。
1九、多線程中的忙循環是什麼?
忙循環就是程序員用循環讓一個線程等待,不像傳統方法wait(), sleep() 或 yield() 它們都放棄了CPU控制,而忙循環不會放棄CPU,它就是在運行一個空循環。這麼作的目的是爲了保留CPU緩存,在多核系統中,一個等待線程醒來的時候可能會在另外一個內核運行,這樣會重建緩存。爲了不重建緩存和減小等待重建的時間就可使用它了。
20、若是同步塊內的線程拋出異常會發生什麼?
不管你的同步塊是正常仍是異常退出的,裏面的線程都會釋放鎖,因此對比鎖接口我更喜歡同步塊,由於它不用我花費精力去釋放鎖,
該功能能夠在finally block裏釋放鎖實現。
2一、Java多線程中調用wait() 和 sleep()方法有什麼不一樣?
Java程序中wait 和 sleep都會形成某種形式的暫停,它們能夠知足不一樣的須要。
wait()方法用於線程間通訊,若是等待條件爲真且其它線程被喚醒時它會釋放鎖,而sleep()方法僅僅釋放CPU資源或者讓當前線程中止執行一段時間,
但不會釋放鎖。
2二、數據庫的優化
一、硬件優化,提升機器性能,增長硬件等;
二、優化查詢語句,將限定性強的where條件放前,用exists代替in操做等;
三、優化索引,創建有效的索引並檢查和修復缺乏的統計信息等
四、數據庫系統文件優化,將數據文件、索引文件、日誌文件放置在不一樣的磁盤上,提升並行度等
五、大數據分割,當一個表的數據規模達到數億條時,索引已基本發揮不了做用:創建索引要花費大量時間,查詢時因爲要掃描大的索引表也要花費大量時間。爲了發揮索引的做用,能夠將大表按照某個字段拆分爲若干個小表。
2三、抽象類(abstract class)和接口(interface)有什麼異同?
答:抽象類和接口都不可以實例化,但能夠定義抽象類和接口類型的引用。一個類若是繼承了某個抽象類或者實現了某個接口都須要對其中的抽象方法所有進行實現,不然該類仍然須要被聲明爲抽象類。接口比抽象類更加抽象,由於抽象類中能夠定義構造器,能夠有抽象方法和具體方法,而接口中不能定義構造器並且其中的方法所有都是抽象方法。抽象類中的成員能夠是private、默認、protected、public的,而接口中的成員全都是public的。抽象類中能夠定義成員變量,而接口中定義的成員變量實際上都是常量。有抽象方法的類必須被聲明爲抽象類,而抽象類未必要有抽象方法
2四、闡述final、finally、finalize的區別。
答:
- final:修飾符(關鍵字)有三種用法:若是一個類被聲明爲final,意味着它不能再派生出新的子類,即不能被繼承,所以它和abstract是反義詞。將變量聲明爲final,能夠保證它們在使用中不被改變,被聲明爲final的變量必須在聲明時給定初值,而在之後的引用中只能讀取不可修改。被聲明爲final的方法也一樣只能使用,不能在子類中被重寫。
- finally:一般放在try…catch…的後面構造老是執行代碼塊,這就意味着程序不管正常執行仍是發生異常,這裏的代碼只要JVM不關閉都能執行,能夠將釋放外部資源的代碼寫在finally塊中。
- finalize:Object類中定義的方法,Java中容許使用finalize()方法在垃圾收集器將對象從內存中清除出去以前作必要的清理工做。這個方法是由垃圾收集器在銷燬對象時調用的,經過重寫finalize()方法能夠整理系統資源或者執行其餘清理工做。
2五、闡述ArrayList、Vector、LinkedList的存儲性能和特性。
答:ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector中的方法因爲添加了synchronized修飾,所以Vector是線程安全的容器,但性能上較ArrayList差,所以已是Java中的遺留容器。LinkedList使用雙向鏈表實現存儲(將內存中零散的內存單元經過附加的引用關聯起來,造成一個能夠按序號索引的線性結構,這種鏈式存儲方式與數組的連續存儲方式相比,內存的利用率更高),按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。Vector屬於遺留容器(Java早期的版本中提供的容器,除此以外,Hashtable、Dictionary、BitSet、Stack、Properties都是遺留容器),已經不推薦使用,可是因爲ArrayList和LinkedListed都是非線程安全的,若是遇到多個線程操做同一個容器的場景,則能夠經過工具類Collections中的synchronizedList方法將其轉換成線程安全的容器後再使用(這是對裝潢模式的應用,將已有對象傳入另外一個類的構造器中建立新的對象來加強實現)。
2六、List、Map、Set三個接口存取元素時,各有什麼特色?
答:List以特定索引來存取元素,能夠有重複元素。Set不能存放重複元素(用對象的equals()方法來區分元素是否重複)。Map保存鍵值對(key-value pair)映射,映射關係能夠是一對一或多對一。Set和Map容器都有基於哈希存儲和排序樹的兩種實現版本,基於哈希存儲的版本理論存取時間複雜度爲O(1),而基於排序樹版本的實如今插入或刪除元素時會按照元素或元素的鍵(key)構成排序樹從而達到排序和去重的效果。
2七、TreeMap和TreeSet在排序時如何比較元素?Collections工具類中的sort()方法如何比較元素?
答:TreeSet要求存放的對象所屬的類必須實現Comparable接口,該接口提供了比較元素的compareTo()方法,當插入元素時會回調該方法比較元素的大小。TreeMap要求存放的鍵值對映射的鍵必須實現Comparable接口從而根據鍵對元素進行排序。Collections工具類的sort方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對象比較實現Comparable接口以實現元素的比較;第二種不強制性的要求容器中的元素必須可比較,可是要求傳入第二個參數,參數是Comparator接口的子類型(須要重寫compare方法實現元素的比較),至關於一個臨時定義的排序規則,其實就是經過接口注入比較元素大小的算法,也是對回調模式的應用(Java中對函數式編程的支持)。
2八、Java中如何實現序列化,有什麼意義?
答:序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決對象流讀寫操做時可能引起的問題(若是不進行序列化可能會存在數據亂序的問題)。
要實現序列化,須要讓一個類實現Serializable接口,該接口是一個標識性接口,標註該類對象是可被序列化的,而後使用一個輸出流來構造一個對象輸出流並經過writeObject(Object)方法就能夠將實現對象寫出(即保存其狀態);若是須要反序列化則能夠用一個輸入流創建對象輸入流,而後經過readObject方法從流中讀取對象。序列化除了可以實現對象的持久化以外,還可以用於對象的深度克隆
2九、簡述一下你瞭解的設計模式。
工廠模式:工廠類能夠根據條件生成不一樣的子類實例,這些子類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做(多態方法)。當獲得子類的實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例。
- 代理模式:給一個對象提供一個代理對象,並由代理對象控制原對象的引用。實際開發中,按照使用目的的不一樣,代理能夠分爲:遠程代理、虛擬代理、保護代理、Cache代理、防火牆代理、同步化代理、智能引用代理。
30、JSP有哪些內置對象?做用分別是什麼?
答:JSP有9個內置對象:
- request:封裝客戶端的請求,其中包含來自GET或POST請求的參數;
- response:封裝服務器對客戶端的響應;
- pageContext:經過該對象能夠獲取其餘對象;
- session:封裝用戶會話的對象;
- application:封裝服務器運行環境的對象;
- out:輸出服務器響應的輸出流對象;
- config:Web應用的配置對象;
- page:JSP頁面自己(至關於Java程序中的this);
- exception:封裝頁面拋出異常的對象。
3一、get和post請求的區別?
答:
①get請求用來從服務器上得到資源,而post是用來向服務器提交數據;
②get將表單中數據按照name=value的形式,添加到action 所指向的URL 後面,而且二者使用"?"鏈接,而各個變量之間使用"&"鏈接;post是將表單中的數據放在HTTP協議的請求頭或消息體中,傳遞到action所指向URL;
③get傳輸的數據要受到URL長度限制(1024字節);而post能夠傳輸大量的數據,上傳文件一般要使用post方式;
④使用get時參數會顯示在地址欄上,若是這些數據不是敏感數據,那麼可使用get;對於敏感數據仍是應用使用post;
⑤get使用MIME類型application/x-www-form-urlencoded的URL編碼(也叫百分號編碼)文本的格式傳遞參數,保證被傳送的參數由遵循規範的文本組成,例如一個空格的編碼是"%20"。
3二、講解JSP中的四種做用域。
答:JSP中的四種做用域包括page、request、session和application,具體來講:
- page表明與一個頁面相關的對象和屬性。
- request表明與Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web組件;須要在頁面顯示的臨時數據能夠置於此做用域。
- session表明與某個用戶與服務器創建的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶本身的session中。
- application表明與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局做用域
3三、Hibernate中Session的load和get方法的區別是什麼?
答:主要有如下三項區別:
① 若是沒有找到符合條件的記錄,get方法返回null,load方法拋出異常。
② get方法直接返回實體類對象,load方法返回實體類對象的代理。
③ 在Hibernate 3以前,get方法只在一級緩存中進行數據查找,若是沒有找到對應的數據則越過二級緩存,直接發出SQL語句完成數據讀取;load方法則能夠從二級緩存中獲取數據;從Hibernate 3開始,get方法再也不是對二級緩存只寫不讀,它也是能夠訪問二級緩存的。
3四、Hibernate如何實現分頁查詢?
答:經過Hibernate實現分頁查詢,開發人員只須要提供HQL語句(調用Session的createQuery()方法)或查詢條件(調用Session的createCriteria()方法)、設置查詢起始行數(調用Query或Criteria接口的setFirstResult()方法)和最大查詢行數(調用Query或Criteria接口的setMaxResults()方法),並調用Query或Criteria接口的list()方法,Hibernate會自動生成分頁查詢的SQL語句
3五、解釋一下什麼叫AOP(面向切面編程)?
答:AOP(Aspect-Oriented Programming)指一種程序設計範型,該範型以一種稱爲切面(aspect)的語言構造爲基礎,切面是一種新的模塊化機制,用來描述分散在對象、類或方法中的橫切關注點(crosscutting concern)
3六、Spring MVC的工做原理是怎樣的?
答:Spring MVC的工做原理以下圖所示:
① 客戶端的全部請求都交給前端控制器DispatcherServlet來處理,它會負責調用系統的其餘模塊來真正處理用戶的請求。
②DispatcherServlet收到請求後,將根據請求的信息(包括URL、HTTP協議方法、請求頭、請求參數、Cookie等)以及HandlerMapping的配置找處處理該請求的Handler(任何一個對象均可以做爲請求的Handler)。
③在這個地方Spring會經過HandlerAdapter對該處理器進行封裝。
④ HandlerAdapter是一個適配器,它用統一的接口對各類Handler中的方法進行調用。
⑤ Handler完成對用戶請求的處理後,會返回一個ModelAndView對象給DispatcherServlet,ModelAndView顧名思義,包含了數據模型以及相應的視圖的信息。
⑥ ModelAndView的視圖是邏輯視圖,DispatcherServlet還要藉助ViewResolver完成從邏輯視圖到真實視圖對象的解析工做。
⑦ 當獲得真正的視圖對象後,DispatcherServlet會利用視圖對象對模型數據進行渲染。
⑧ 客戶端獲得響應,多是一個普通的HTML頁面,也能夠是XML或JSON字符串,還能夠是一張圖片或者一個PDF文件。
3七、選擇使用Spring框架的緣由(Spring框架爲企業級開發帶來的好處有哪些)?
答:能夠從如下幾個方面做答:
- 非侵入式:支持基於POJO的編程模式,不強制性的要求實現Spring框架中的接口或繼承Spring框架中的類。
- IoC容器:IoC容器幫助應用程序管理對象以及對象之間的依賴關係,對象之間的依賴關係若是發生了改變只須要修改配置文件而不是修改代碼,由於代碼的修改可能意味着項目的從新構建和完整的迴歸測試。有了IoC容器,程序員不再須要本身編寫工廠、單例,這一點特別符合Spring的精神」不要重複的發明輪子」。
- AOP(面向切面編程):將全部的橫切關注功能封裝到切面(aspect)中,經過配置的方式將橫切關注功能動態添加到目標代碼上,進一步實現了業務邏輯和系統服務之間的分離。另外一方面,有了AOP程序員能夠省去不少本身寫代理類的工做。
- MVC:Spring的MVC框架是很是優秀的,從各個方面均可以甩Struts 2幾條街,爲Web表示層提供了更好的解決方案。
- 事務管理:Spring以寬廣的胸懷接納多種持久層技術,而且爲其提供了聲明式的事務管理,在不須要任何一行代碼的狀況下就可以完成事務管理。
- 其餘:選擇Spring框架的緣由還遠不止於此,Spring爲Java企業級開發提供了一站式選擇,你能夠在須要的時候使用它的部分和所有,更重要的是,你甚至能夠在感受不到Spring存在的狀況下,在你的項目中使用Spring提供的各類優秀的功能。
3八、闡述Spring框架中Bean的生命週期?
答:
① Spring IoC容器找到關於Bean的定義並實例化該Bean。
② Spring IoC容器對Bean進行依賴注入。
③ 若是Bean實現了BeanNameAware接口,則將該Bean的id傳給setBeanName方法。
④ 若是Bean實現了BeanFactoryAware接口,則將BeanFactory對象傳給setBeanFactory方法。
⑤ 若是Bean實現了BeanPostProcessor接口,則調用其postProcessBeforeInitialization方法。
⑥ 若是Bean實現了InitializingBean接口,則調用其afterPropertySet方法。
⑦ 若是有和Bean關聯的BeanPostProcessors對象,則這些對象的postProcessAfterInitialization方法被調用。
⑧ 當銷燬Bean實例時,若是Bean實現了DisposableBean接口,則調用其destroy方法。
16二、依賴注入時如何注入集合屬性?答:能夠在定義Bean屬性時,經過<list> / <set> / <map> / <props>分別爲其注入列表、集合、映射和鍵值都是字符串的映射屬性。