面試指南(全部內容取自網絡,侵刪)

面試總結

1. Collection集合接口

1.1 Collection接口

是最基本的接口,派生了兩個子接口Set和List前端

1.2 Set接口

無序且不可重複java

1.2.1 HashSet接口

基於HashMap實現,全部元素都是保存在HashMap的key中,而value中保存了PRESENT。程序員

1.3 List接口

有序且可重複web

1.3.1 ArrayList,LinkedList接口(線程不安全)

總結面試

  • ArrayList內部結構是數組(Array),查找高效,修改低效。
  • LinkedList接口內部是鏈表Linked,查找低效,修改高效
  • ArrayList特色是有序可重複的,實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
  • ArrayList 採用的是數組形式來保存對象的,這種方式將對象放在連續的位置中,因此最大的缺點就是插入刪除時很是麻煩
  • LinkedList 採用的將對象存放在獨立的空間中,並且在每一個空間中還保存下一個連接的索引,可是缺點就是查找很是麻煩 要叢第一個索引開始
  • 對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針。
  • 對於新增和刪除操做add和remove,LinedList比較佔優點,由於ArrayList要移動數據。
  • 在ArrayList的中間插入或刪除一個元素意味着這個列表中剩餘的元素都會被移動。
  • ArrayList更適合讀取數據,linkedList更多的時候添加或刪除數據。

2. Map接口

Map也是接口,但沒有繼承Collection接口。該接口描述了從不重複的鍵到值的映射。Map接口用於維護鍵/值對算法

2.1HashMap(線程不一樣步)(Hashtable爲線程安全)

基於哈希表實現,特色就是鍵值對的映射關係。一個key對應一個Value。HashMap中元素的排列順序是不固定的。更加適合於對元素進行插入、刪除和定位。spring

2.1.1 HashMap和Hashtable的區別

HashMap和Hashtable都實現了Map接口,但決定用哪個以前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。sql

  • HashMap幾乎能夠等價於Hashtable,除了HashMap是非synchronized的,並能夠接受null(HashMap能夠接受爲null的鍵值(key)和值(value),而Hashtable則不行)。
  • HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程能夠共享一個Hashtable;而若是沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。
  • 另外一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。因此當有其它線程改變了HashMap的結構(增長或者移除元素),將會拋出ConcurrentModificationException,但迭代器自己的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並非一個必定發生的行爲,要看JVM。這條一樣也是Enumeration和Iterator的區別。
  • 因爲Hashtable是線程安全的也是synchronized,因此在單線程環境下它比HashMap要慢。若是你不須要同步,只須要單一線程,那麼使用HashMap性能要好過Hashtable。
  • HashMap不能保證隨着時間的推移Map中的元素次序是不變的。

2.1.2 讓HashMap同步

Map m = Collections.synchronizeMap(hashMap);數據庫

2.2 TreeMap(線程不一樣步)

基於紅黑樹實現。TreeMap中的元素保持着某種固定的順序。更加適合於對元素的順序遍歷。編程

3. 迭代器(Iterator和加強for循環)

迭代器是一種模式,它可使得對於序列類型的數據結構的遍歷行爲與被遍歷的對象分離

3.1 Iterator

Iterator對集合類中的任何一個實現類,均可以返回這樣一個Iterator對象。能夠適用於任何一個類。
由於集合類(List和Set等)能夠裝入的對象的類型是不肯定的,從集合中取出時都是Object類型,用時都須要進行強制轉化,這樣會很麻煩,用上泛型,就是提早告訴集合肯定要裝入集合的類型,這樣就能夠直接使用而不用顯示類型轉換.很是方便.

3.2 foreach

優點在於更加簡潔,更不容易出錯,沒必要關心下標的起始值和終止值

forEach不是關鍵字,關鍵字仍是for,語句是由iterator實現的,他們最大的不一樣之處就在於remove()方法上
若是在循環的過程當中調用集合的remove()方法,就會致使循環出錯,由於循環過程當中list.size()的大小變化了,就致使了錯誤。 因此,若是想在循環語句中刪除集合中的某個元素,就要用迭代器iterator的remove()方法,由於它的remove()方法不只會刪除元素,還會維護一個標誌,用來記錄目前是否是可刪除狀態,例如,你不能連續兩次調用它的remove()方法,調用以前至少有一次next()方法的調用。

3.3 區別

  • 採用ArrayList對隨機訪問比較快,而for循環中的get()方法,採用的便是隨機訪問的方法,所以在ArrayList裏,for循環較快
  • 採用LinkedList則是順序訪問比較快,iterator中的next()方法,採用的便是順序訪問的方法,所以在LinkedList裏,使用iterator較快
  • 從數據結構角度分析,for循環適合訪問順序結構,能夠根據下標快速獲取指定元素.而Iterator 適合訪問鏈式結構,由於迭代器是經過next()和Pre()來定位的.能夠訪問沒有順序的集合.
  • 而使用 Iterator 的好處在於可使用相同方式去遍歷集合中元素,而不用考慮集合類的內部實現(只要它實現了 java.lang.Iterable 接口),若是使用 Iterator 來遍歷集合中元素,一旦再也不使用 List 轉而使用 Set 來組織數據,那遍歷元素的代碼不用作任何修改,若是使用 for 來遍歷,那全部遍歷此集合的算法都得作相應調整,由於List有序,Set無序,結構不一樣,他們的訪問算法也不同.
  • map接口沒有迭代器,能夠Set keySet() :獲取到全部的鍵,存儲到一個Set集合中,並返回該集合,由於Set有迭代器,每次迭代出來的是一個鍵,再根據鍵來獲得值。

4. String與StringBuffer

簡單地說,就是一個變量和常量的關係。StringBuffer對象的內容能夠修改;而String對象一旦產生後就不能夠被修改,從新賦值實際上是兩個對象

4.1 String

在String類中沒有用來改變已有字符串中的某個字符的方法,因爲不能改變一個Java字符串中的某個單獨字符,因此在JDK文檔中稱String類的對象是不可改變的。然而,不可改變的字符串具備一個很大的優勢:編譯器能夠把字符串設爲共享的。

是對象不是原始類型.
爲不可變對象,一旦被建立,就不能修改它的值.
對於已經存在的String對象的修改都是從新建立一個新的對象,而後把新的值保存進去.
String 是final類,即不能被繼承.

4.2 StringBuffer

是一個可變對象,當對他進行修改的時候不會像String那樣從新創建對象
它只能經過構造函數來創建,
StringBuffer sb = new StringBuffer();
注意:不能經過賦值符號對他進行賦值.
sb = "welcome to here!";//error
對象被創建之後,在內存中就會分配內存空間,並初始保存一個null.向StringBuffer
中賦值的時候能夠經過它的append方法.
sb.append("hello");

可預先分配指定長度的內存塊創建一個字符串緩衝區。這樣使用StringBuffer類的append方法追加字符 比 String使用 + 操做符添加字符 到 一個已經存在的字符串後面有效率得多。由於使用 + 操做符每一次將字符添加到一個字符串中去時,字符串對象都須要尋找一個新的內存空間來容納更大的字符串,這無凝是一個很是消耗時間的操做。添加多個字符也就意味着要一次又一次的對字符串從新分配內存。使用StringBuffer類就避免了這個問題。

4.3區別

  • 三者在執行速度方面的比較:StringBuilder > StringBuffer > String
  • StringBuilder:線程非安全的;StringBuffer:線程安全的
  • 若是要操做少許的數據用 = String;單線程操做字符串緩衝區 下操做大量數據 = StringBuilder;多線程操做字符串緩衝區 下操做大量數據 = StringBuffer
  • 若是常常須要對一個字符串進行修改,例如插入、刪除等操做,使用StringBuffer要更加適合一些。

5. 線程

5.1 進程和線程的區別

  • 進程:每一個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷,一個進程包含1--n個線程。

  • 線程:同一類線程共享代碼和數據空間,每一個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。

  • 線程和進程同樣分爲五個階段:建立、就緒、運行、阻塞、終止。

  • 多進程是指操做系統能同時運行多個任務(程序)。

  • 多線程是指在同一程序中有多個順序流在執行。

線程

5.2 五種狀態(生命週期)

  • 新建狀態(New):當線程對象對建立後,即進入了新建狀態,如:Thread t = new MyThread();

  • 就緒狀態(Runnable):當調用線程對象的start()方法(t.start();),線程即進入就緒狀態。處於就緒狀態的線程,只是說明此線程已經作好了準備,隨時等待CPU調度執行,並非說執行了t.start()此線程當即就會執行;

  • 運行狀態(Running):當CPU開始調度處於就緒狀態的線程時,此時線程才得以真正執行,即進入到運行狀態。注:就 緒狀態是進入到運行狀態的惟一入口,也就是說,線程要想進入運行狀態執行,首先必須處於就緒狀態中;

  • 阻塞狀態(Blocked):處於運行狀態中的線程因爲某種緣由,暫時放棄對CPU的使用權,中止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再次被CPU調用以進入到運行狀態。根據阻塞產生的緣由不一樣,阻塞狀態又能夠分爲三種:

  • 1.等待阻塞:運行狀態中的線程執行wait()方法,使本線程進入到等待阻塞狀態;

  • 2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(由於鎖被其它線程所佔用),它會進入同步阻塞狀態;

  • 3.其餘阻塞 -- 經過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。

  • 死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。

5.2 實現方法

一種是繼承Thread類,另一種是實現Runable接口

5.2.1 擴展java.lang.Thread類

class MyThread extends Thread { 
         private int i = 0;
         @Override
         public void run() {
             for (i = 0; i < 100; i++) {
                 System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }
    }
public class ThreadTest {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                Thread myThread1 = new MyThread();     // 建立一個新的線程  myThread1  此線程進入新建狀態
                Thread myThread2 = new MyThread();     // 建立一個新的線程 myThread2 此線程進入新建狀態
                myThread1.start();                     // 調用start()方法使得線程進入就緒狀態
                myThread2.start();                     // 調用start()方法使得線程進入就緒狀態
            }
        }
    }
}

繼承Thread類,經過重寫run()方法定義了一個新的線程類MyThread,其中run()方法的方法體表明瞭線程須要完成的任務,稱之爲線程執行體。當建立此線程類對象時一個新的線程得以建立,並進入到線程新建狀態。經過調用線程對象引用的start()方法,使得該線程進入到就緒狀態,此時此線程並不必定會立刻得以執行,這取決於CPU調度時機。

5.2.2 實現Runnable接口

class MyRunnable implements Runnable {
    private int i = 0;
    @Override
    public void run() {
        for (i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}
public class ThreadTest {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                Runnable myRunnable = new MyRunnable(); // 建立一個Runnable實現類的對象
                Thread thread1 = new Thread(myRunnable); // 將myRunnable做爲Thread target建立新的線程
                Thread thread2 = new Thread(myRunnable);
                thread1.start(); // 調用start()方法使得線程進入就緒狀態
                thread2.start();
            }
        }
    }
}

5.3 線程控制

5.3.1 join()

讓一個線程等待另外一個線程完成才繼續執行。如A線程線程執行體中調用B線程的join()方法,則A線程被阻塞,知道B線程執行完爲止,A才能得以繼續執行。

5.3.2 sleep()

讓當前的正在執行的線程暫停指定的時間,並進入阻塞狀態。在其睡眠的時間段內,該線程因爲不是處於就緒狀態,所以不會獲得執行的機會。即便此時系統中沒有任何其餘可執行的線程,出於sleep()中的線程也不會執行。所以sleep()方法經常使用來暫停線程執行。

當調用了新建的線程的start()方法後,線程進入到就緒狀態,可能會在接下來的某個時間獲取CPU時間片得以執行,若是但願這個新線程必然性的當即執行,直接調用原來線程的sleep(1)便可。

5.3.3 後臺線程(Daemon Thread)

後臺線程主要是爲其餘線程(相對能夠稱之爲前臺線程)提供服務,或「守護線程」。如JVM中的垃圾回收線程。

生命週期:後臺線程的生命週期與前臺線程生命週期有必定關聯。主要體如今:當全部的前臺線程都進入死亡狀態時,後臺線程會自動死亡

5.3.4改變線程的優先級/setPriority()

每一個線程在執行時都具備必定的優先級,優先級高的線程具備較多的執行機會。每一個線程默認的優先級都與建立它的線程的優先級相同。main線程默認具備普通優先級。

設置線程優先級:setPriority(int priorityLevel)。參數priorityLevel範圍在1-10之間

5.3.5 線程讓步:yield()

當某個線程調用yiled()方法從運行狀態轉換到就緒狀態後,CPU從就緒狀態線程隊列中只會選擇與該線程優先級相同或優先級更高的線程去執行。

5.4 線程安全

是指多線程環境下對共享資源的訪問可能會引發此共享資源的不一致性。所以,爲避免線程安全問題,應該避免多線程環境下對此共享資源的併發訪問。

5.4.1 同步方法

對共享資源進行訪問的方法定義中加上synchronized關鍵字修飾,使得此方法稱爲同步方法。能夠簡單理解成對此方法進行了加鎖,其鎖對象爲當前方法所在的對象自身。多線程環境下,當執行此方法時,首先都要得到此同步鎖(且同時最多隻有一個線程可以得到),只有當線程執行完此同步方法後,纔會釋放鎖對象,其餘的線程纔有可能獲取此同步鎖,以此類推...

public synchronized void run() { }

使用同步方法時,使得整個方法體都成爲了同步執行狀態,會使得可能出現同步範圍過大的狀況,因而,針對須要同步的代碼能夠直接另外一種同步方式——同步代碼塊來解決。

synchronized (obj) { }

5.5 wait()/notify()/notifyAll()線程通訊

這三個方法主要都是用於多線程中,都是Object類中的本地方法。

在實際的多線程編程中,只有同步鎖對象調這三個方法,才能完成對多線程間的線程通訊。

  • wait():致使當前線程等待並使其進入到等待阻塞狀態。直到其餘線程調用該同步鎖對象的notify()或notifyAll()方法來喚醒此線程。

  • notify():喚醒在此同步鎖對象上等待的單個線程,若是有多個線程都在此同步鎖對象上等待,則會任意選擇其中某個線程進行喚醒操做,只有當前線程放棄對同步鎖對象的鎖定,纔可能執行被喚醒的線程。

  • notifyAll():喚醒在此同步鎖對象上等待的全部線程,只有當前線程放棄對同步鎖對象的鎖定,纔可能執行被喚醒的線程。

須要注意的是:

  1. wait()方法執行後,當前線程當即進入到等待阻塞狀態,其後面的代碼不會執行;

  2. notify()/notifyAll()方法執行後,將喚醒此同步鎖對象上的(任意一個-notify()/全部-notifyAll())線程對象,可是,此時還並無釋放同步鎖對象,也就是說,若是notify()/notifyAll()後面還有代碼,還會繼續進行,知道當前線程執行完畢纔會釋放同步鎖對象;

  3. notify()/notifyAll()執行後,若是右面有sleep()方法,則會使當前線程進入到阻塞狀態,可是同步對象鎖沒有釋放,依然本身保留,那麼必定時候後仍是會繼續執行此線程,接下來同2;

  4. wait()/notify()/nitifyAll()完成線程間的通訊或協做都是基於不一樣對象鎖的,所以,若是是不一樣的同步對象鎖將失去意義,同時,同步對象鎖最好是與共享資源對象保持一一對應關係;

  5. 當wait線程喚醒後並執行時,是接着上次執行到的wait()方法代碼後面繼續往下執行的。

5.6 currentThread()

做用就是獲得當前線程的對象。

經過currentThread()咱們能夠輕易的就獲得當前線程的名稱,咱們還能夠經過線程對象,獲得其餘的屬性。

注意:

currentThread()方法返回的是對當前正在執行的線程對象的引用,this表明的是當前調用它所在函數所屬的對象的引用

6 數據庫

6.1 存儲引擎

MySQL經常使用存儲引擎:InnoDB適用於頻繁維護修改插入等數據表,MyISAM適合少改寫,少插入的頻繁讀取的表。經常使用InnoDB存儲引擎

6.2 事務

Innodb才支持事務

主要是爲了解決併發狀況下保持數據一致性的問題。

如下4個基本特徵:

  • Atomic(原子性):事務中包含的操做被看作一個邏輯單元,這個邏輯單元中的操做要麼所有成功,要麼所有失敗。

  • Consistency(一致性):只有合法的數據能夠被寫入數據庫,不然事務應該將其回滾到最初狀態。

  • Isolation(隔離性):事務容許多個用戶對同一個數據進行併發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其餘並行事務的修改相互獨立。

  • Durability(持久性):事務結束後,事務處理的結果必須可以獲得固化。

6.2.1 處理事務

Java事務的類型有三種:JDBC事務、JTA(Java Transaction API)事務、容器事務

處理事務:spring的事務是經過「聲明式事務」的方式對事務進行管理,即在配置文件中進行聲明,經過AOP將事務切面切入程序,最大的好處是大大減小了代碼量,提升了工做效率。

6.3 left join、right join、inner join

百度一下

6.4 數據庫優化

  1. 減小查詢字段數
  2. 表關聯儘可能用主鍵
  3. 查詢條件儘可能避免模糊查詢
  4. 避免使用排序字段,排序字段儘可能使用主鍵
  5. 儘可能使用限制查詢條件
  6. 查詢條件使用有效索引

7 項目相關

7.1 對MVC的理解

MVC是model-view-controler的簡稱。也就是模型-視圖-控制器。mvc是一種設計模式,他強制性的把應用程序的輸入、處理和輸出分開。mvc中的模型、視圖、控制器分別擔任着不一樣的任務。

視圖:視圖是用戶看到並與之交互的界面。視圖向用戶顯示相關的數據,並接受用戶的輸入。視圖不進行任何業務邏輯處理。

模型:模型表示業務數據和業務處理。至關於javaBean。一個模型能爲多個視圖提供數據。這提升了應用程序的重用性。

控制器:當用戶單擊web頁面中的提交按鈕時,控制器接收請求並調用相應的模型去處理請求。而後根據處理的結果調用相應的視圖來顯示處理的結構。

MVC的處理過程:首先控制器接收用戶的請求,調用相應的模型來進行業務處理,並返回數據給控制器。控制器調用相應的視圖來顯示處理的結構。並經過視圖呈現給用戶。如在項目中要對應MVC的話;View對應項目中的jsp,controler對應action,model對應service+dao層的業務邏輯和持久層的操做。

7.2 框架的優勢

7.2.1 Hibernate(持久層)

工做原理:

  1. 讀取並解析配置文件
  2. 讀取並解析映射信息,建立SessionFactory
  3. 打開Session
  4. 建立事務Transaction
  5. 持久化操做
  6. 提交事務
  7. 關閉Session
  8. 關閉SessionFactory

優化:
Hibernate對數據的緩存包括兩個級:一級緩存,在Session的級別上進行,主要是對象緩存,以其id爲鍵保存對象,在Session的生命期間存在;二級緩存,在SessionFactory的級別上進行,有對象緩存和查詢緩存,查詢緩存以查詢條件爲鍵保存查詢結果,在SessionFactory的生命期間存在,默認地,Hibernate只啓用一級緩存

優勢:

  1. Hibernate是JDBC的輕量級的對象封裝,它是一個獨立的對象持久層框架。Hibernate能夠用在任何JDBC可使用的場合,例如Java應用程序的數據庫訪問代碼,DAO接口的實現類,甚至能夠是BMP裏面的訪問數據庫的代碼。

  2. Hibernate是一個和JDBC密切關聯的框架,因此Hibernate的兼容性和JDBC驅動,和數據庫都有必定的關係,可是和使用它的Java程序,和App Server沒有任何關係,也不存在兼容性問題。

  3. Hibernate不能用來直接和Entity Bean作對比,只有放在整個J2EE項目的框架中才能比較。而且即便是放在軟件總體框架中來看,Hibernate也是作爲JDBC的替代者出現的,而不是Entity Bean的替代者出現的。

  4. Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了很是輕量級的對象封裝,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操控數據庫。

  5. Hibernate能夠應用在任何使用JDBC的場合。

  6. Hibernate 使用Java 反射機制而不是字節碼加強程序來實現透明性。

  7. Hibernate 的性能很是好,由於它是個輕量級框架。映射的靈活性很出色。它支持各類關係數據庫,從一對一到多對多的各類複雜關係。

7.2.2 mybatis(持久層)

  1. 易於上手和掌握。

  2. sql寫在xml裏,便於統一管理和優化。

  3. 解除sql與程序代碼的耦合。

  4. 提供映射標籤,支持對象與數據庫的orm字段關係映射

  5. 提供對象關係映射標籤,支持對象關係組建維護

  6. 提供xml標籤,支持編寫動態sql。

7.2.3 優點對比

  1. Mybatis優點MyBatis能夠進行更爲細緻的SQL優化,能夠減小查詢字段。

  2. MyBatis容易掌握,而Hibernate門檻較高。

  3. Hibernate優點Hibernate的DAO層開發比MyBatis簡單,Mybatis須要維護SQL和結果映射。

  4. Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。

  5. Hibernate數據庫移植性很好,MyBatis的數據庫移植性很差,不一樣的數據庫須要寫不一樣SQL。

  6. Hibernate有更好的二級緩存機制,可使用第三方緩存。MyBatis自己提供的緩存機制不佳。

7.2.4 Spring(控制層+業務層)

它基於IoC(Inversion of Control,反向控制)和AOP的構架多層j2ee系統的框架,但它不強迫你必須在每一層中必須使用Spring,由於它模塊化的很好,容許你根據本身的須要選擇使用它的某一個模塊;它實現了很優雅的MVC,對不一樣的數據訪問技術提供了統一的接口,採用IoC使得能夠很容易的實現bean的裝配,提供了簡潔的AOP並據此實現Transcation Managment,等等

  • 在項目中利用spring的ioc(控制反轉或依賴注入),明確的定義組件接口(如UserDao),開發者能夠獨立開發各個組件,而後根據組件間的依賴關係組裝(UserAction依賴於UserService,UserService依賴於Userdao)運行,很好的把struts(Action)和hibernate(dao的實現)結合起來;
  • spring的事務管理把hibernate對數據庫的操做進行了事務配置

事務控制:

  • spring事務包括編程事務和聲明式事務。在系統中使用了聲明式的事務管理是用spring的AOP來實現的;配置了只讀事務和回滾事務(傳播行爲爲REQUIRED)當出現錯誤後進行事務回滾操做。在項目中經過aop切入事務到service層,這樣作能使一次業務邏輯操做若是包括幾個數據庫操做都控制在一個事務中。
  1. 低侵入式設計,代碼污染極低

  2. 獨立於各類應用服務器,基於Spring框架的應用,能夠真正實現Write Once,Run Anywhere的承諾

  3. Spring的DI機制下降了業務對象替換的複雜性,提升了組件之間的解耦

  4. Spring的AOP支持容許將一些通用任務如安全、事務、日誌等進行集中式管理,從而提供了更好的複用

  5. Spring的ORM和DAO提供了與第三方持久層框架的良好整合,並簡化了底層的數據庫訪問

  6. Spring並不強制應用徹底依賴於Spring,開發者可自由選用Spring框架的部分或所有

7.2.5 struts2

工做原理:

  • 發送http請求
  • web服務器(tomcat、weblogic)
  • 執行struts核心過濾器StrutsprepareAndExecuteFilter
  • 加載struts配置文件中配置信息,找到對應的Action類並實例化
  • 執行各種攔截器和action中對應方法
  • 配置文件中找到返回結果
  • 轉發到具體頁面或其餘操做
  1. 實現了MVC模式,層次結構清晰,使程序員只需關注業務邏輯的實現。

  2. 豐富的標籤庫,大大提升了開發的效率。

  3. Struts2提供豐富的攔截器實現。

  4. 經過配置文件,就能夠掌握整個系統各個部分之間的關係。

  5. 異常處理機制,只需在配置文件中配置異常的映射,便可對異常作相應的處理。

  6. Struts2的可擴展性高。

  7. 面向切面編程的思想在Strut2中也有了很好的體現。最重要的體現就是攔截器的使用

7.2.6 springMVC

第一步:發起請求到前端控制器(DispatcherServlet)

第二步:前端控制器請求HandlerMapping查找 Handler,能夠根據xml配置、註解進行查找

第三步:處理器映射器HandlerMapping向前端控制器返回Handler

第四步:前端控制器調用處理器適配器去執行Handler

第五步:處理器適配器去執行Handler

第六步:Handler執行完成給適配器返回ModelAndView

第七步:處理器適配器向前端控制器返回ModelAndView,ModelAndView是springmvc框架的一個底層對象,包括Model和view

第八步:前端控制器請求視圖解析器去進行視圖解析,根據邏輯視圖名解析成真正的視圖(jsp)

第九步:視圖解析器向前端控制器返回View

第十步:前端控制器進行視圖渲染,視圖渲染將模型數據(在ModelAndView對象中)填充到request域

第十一步:前端控制器向用戶響應結果工做流程:

優勢:

  1. 進行更簡潔的Web層的開發
  2. 天生與Spring框架集成(如IoC容器、AOP等)
  3. 提供強大的約定大於配置的契約式編程支持
  4. 很是靈活的數據驗證、格式化和數據綁定機制
  5. 支持Restful風格

7.3 框架應用

  1. 在表示層中,首先經過jsp頁面實現交互界面,負責傳送請求(request)和接收響應(response),而後struts根據配置文件(struts。xml)將actionServlet接收到的request委派給響應的action處理。
  2. 在業務層中,管理服務組件的spring ioc容器負責向action提供業務模型(model)組件和組件的協做對象數據處理(dao)組件完成業務邏輯,並提供事務處理、緩衝池等容器組件以提高系統性能和保證數據的完整性。
  3. 在持久層中,則依賴於hibernate的對象化映射和數據庫交互,處理dao組件請求的數據,並返回處理結果。
相關文章
相關標籤/搜索