Java常見面試題總結

Java常見面試題總結

@Date 2016.06.22

Java基礎知識

1.Java 中應該使用什麼數據類型來代表價格?

如果不是特別關心內存和性能的話,使用BigDecimal,否則使用預定義精度的 double 類型。

2.怎麼將 byte 轉換爲String,以及注意點?

可以使用 String 接收 byte[] 參數的構造器來進行轉換,需要注意的點是要使用的正確的編碼,否則會使用平臺默認編碼,這個編碼可能跟原來的編碼相同,也可能不同。

3.我們能將 int 強制轉換爲 byte 類型的變量嗎?如果該值大於 byte 類型的範圍,將會出現什麼現象?

可以做強制轉換,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果強制轉化是,int 類型的高 24 位將會被丟棄,byte 類型的範圍是從 -128 到 128。

4.clone方法在哪個類中?Cloneable 還是 Object?

java.lang.Cloneable 是一個標示性接口,不包含任何方法,clone 方法在 object 類中定義。並且需要知道 clone() 方法是一個本地方法,這意味着它是由 c 或 c++ 或 其他本地語言實現的。

5.Java 中 ++ 操作符是線程安全的嗎?

不是線程安全的操作。它涉及到多個指令,如讀取變量值,增加,然後存儲回內存,這個過程可能會出現多個線程交差。

6.a = a + b 與 a += b 的區別?

注意類型強勢轉換的問題

7.爲什麼 Java 中的 String 是不可變的?

Java 中的 String 不可變是因爲 Java 的設計者認爲字符串使用非常頻繁,將字符串設置爲不可變可以允許多個客戶端之間共享相同的字符串。

8.final都能修飾什麼,起到什麼作用?

final 是一個修飾符,可以修飾變量、方法和類。如果 final 修飾變量,意味着該變量的值在初始化後不能被改變。

9.什麼是強類型程序設計語言?

在強類型語言中,編譯器確保類型的正確性,例如你無法在String類型中存放數字,反之亦然。Java是強類型語言,因此存在各種數據類型(如int、float、String、char、boolean等)。你只能將兼容的值存入相應的類型中。與此相反,弱類型語言不要求在編譯時進行類型檢查,它們根據上下文處理值。Python和Perl是兩個常見的弱類型程序設計語言的例子,你可以將數字組成的字符串保存在數字類型中。

10.不可變(immutable)類是什麼意思?

一個類,如果在創建之後它的狀態就不能被改變,那麼他就是不可變的。例如Java中的String。一旦你創建了一個String,例如“Java”,你就不能再改變它的內容。任何對這個字符串的改變(例如轉換到大寫、與另一個String連接)將創建一個新的對象。不可變的對象在並行程序設計中很有用,因爲它們可以在進程間被共享,不需要擔心同步。事實上,整個函數是程序設計的模型都是在不可變對象上構建的。

11.接口和抽象類有什麼區別?

這是所有程序員面試最經典的問題。接口是最純粹的抽象形式,沒有任何具體的東西。抽象類是一些抽象和具體事物的組合體。這個區別在不同語言中可能會不同,例如在Java中你可以擴展(extend)多個接口,但只能繼承一個抽象類。

12.迭代和遞歸有什麼區別?

迭代通過循環來重複執行同一步驟,遞歸通過調用函數自身來做重複性工作。遞歸經常是複雜問題(例如漢諾塔、反轉鏈表或反轉字符串)的清晰簡潔的解決方案。遞歸的一個缺陷是深度,由於遞歸在棧中存儲中間結果,你只能進行一定深度的遞歸,在那之後你的程序會因爲StackOverFlowError而崩潰。這就是在產品代碼中優先使用迭代而不是遞歸的原因。

13.&和&&運算符的區別是什麼?

&是位運算符,&&是邏輯運算符。&和&&的一個區別是位運算符(&)可以被用於整型和布爾類型,邏輯運算符(&&)只能被用於布爾類型變量。當你寫a & b時,兩個整型數的每一位都會進行與運算。當你寫a && b時,第二個參數可能會也可能不會被執行,這也是它被稱爲短路運算符的原因,至少在Java中是這樣的。我很喜歡這個問題,經常對初級開發者和畢業生問這個問題。

14.如何得到一個整型數的最後一位?

用取模運算符,數字 % 10返回數字的最後一位。例如2345 % 10會返回5,567 % 10會返回7。類似的,除運算符可以用來去掉數字的最後一位,例如2345 / 10的結果是234,567 / 10的結果是56。這是值得了解的一個重要技巧,可以用來解決類似迴文數、反轉數的問題。

15.鏈表和數組有哪些重要區別?

鏈表和數組都是程序設計世界中重要的數據結構。它們間最明顯的區別是,數組將元素存放在連續的地址中,鏈表將數據存放在內存中任意的位置。這使得鏈表有巨大的擴展自己的靈活性,因爲內存總是分散的。這種情況總是可能的:你無法創建一個數組來存放一百萬個整數,但可以用鏈表來存放,因爲空間是存在的,只是不連續。其他的不同都是源於這項事實。例如,在數組中,如果你知道下標,可以用O(1)的時間得到一個元素,但在鏈表中要花O(n)的時間。

16.有沒有可能兩個不相等的對象有有相同的 hashcode?

有可能,兩個不相等的對象可能會有相同的 hashcode 值,這就是爲什麼在 hashmap 中會有衝突。相等 hashcode 值的規定只是說如果兩個對象相等,必須有相同的hashcode 值,但是沒有關於不相等對象的任何規定。

17.兩個相同的對象會有不同的的 hash code 嗎?

不能,根據 hash code 的規定,這是不可能的。

18.我們可以在 hashcode() 中使用隨機數字嗎?

不行,因爲對象的 hashcode 值必須是相同的。參見答案獲取更多關於 Java 中重寫 hashCode() 方法的知識。

19.爲什麼在重寫 equals 方法的時候需要重寫 hashCode 方法?

因爲有強制的規範指定需要同時重寫 hashcode 與 equal 是方法,許多容器類,如 HashMap、HashSet 都依賴於 hashcode 與 equals 的規定。


Java集合框架

1.List、Set之間的區別

List 是一個有序集合,允許元素重複。它的某些實現可以提供基於下標值的常量訪問時間,但是這不是 List 接口保證的。Set 是一個無序集合。

2.隊列操作poll() 方法和 remove() 方法的區別?

poll() 和 remove() 都是從隊列中取出一個元素,但是 poll() 在獲取元素失敗的時候會返回空,但是 remove() 失敗的時候會拋出異常。

3.Java 中 LinkedHashMap 和 PriorityQueue 的區別是什麼?

PriorityQueue 保證最高或者最低優先級的的元素總是在隊列頭部,但是 LinkedHashMap 維持的順序是元素插入的順序。當遍歷一個 PriorityQueue 時,沒有任何順序保證,但是 LinkedHashMap 課保證遍歷順序是元素插入的順序。

4.ArrayList 與 LinkedList 的不區別?

最明顯的區別是 ArrrayList 底層的數據結構是數組,支持隨機訪問,而 LinkedList 的底層數據結構書鏈表,不支持隨機訪問。使用下標訪問一個元素,ArrayList 的時間複雜度是 O(1),而 LinkedList 是 O(n)。

5.用哪兩種方式來實現集合的排序?

你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有順序的的集合,如 list,然後通過 Collections.sort() 來排序。

6.Java 中的 LinkedList 是單向鏈表還是雙向鏈表?

是雙向鏈表,你可以檢查 JDK 的源碼。

7.Java 中的 TreeMap 是採用什麼樹實現的?

Java 中的 TreeMap 是使用紅黑樹實現的。(紅黑樹的數據結構)

8.Hashtable 與 HashMap 有什麼不同之處?

這兩個類有許多不同的地方,下面列出了一部分:

(1)HashMap允許key和value爲null,而HashTable不允許。

(2)HashTable是同步的,而HashMap不是。所以HashMap適合單線程環境,HashTable適合多線程環境。

(3)在Java1.4中引入了LinkedHashMap,HashMap的一個子類,假如你想要遍歷順序,你很容易從HashMap轉向LinkedHashMap,但是HashTable不是這樣的,它的順序是不可預知的。

(4)HashMap提供對key的Set進行遍歷,因此它是fail-fast的,但HashTable提供對key的Enumeration進行遍歷,它不支持fail-fast。

(5)HashTable被認爲是個遺留的類,如果你尋求在迭代的時候修改Map,你應該使用CocurrentHashMap。

9.Java 中的 HashSet,內部是如何工作的?

HashSet 的內部採用 HashMap來實現。由於 Map 需要 key 和 value,所以所有 key 的都有一個默認 value。類似於 HashMap,HashSet 不允許重複的 key,只允許有一個null key,意思就是 HashSet 中只允許存儲一個 null 對象。

10.寫一段代碼在遍歷 ArrayList 時移除一個元素?

該問題的關鍵在於面試者使用的是 ArrayList 的 remove() 還是 Iterator 的 remove()方法。使用迭代器更加線程安全,因爲它可以確保,在當前遍歷的集合元素被更改的時候,它會拋出ConcurrentModificationException。

11.ArrayList 和 HashMap 的默認大小是多數?

在 Java 7 中,ArrayList 的默認大小是 10 個元素,HashMap 的默認大小是16個元素(必須是2的冪)。這就是 Java 7 中 ArrayList 和 HashMap 類的代碼片段:

// from ArrayList.java JDK 1.7
private static final int DEFAULT_CAPACITY = 10;
 
//from HashMap.java JDK 7
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

12.Java 中,Comparator 與 Comparable 有什麼不同?

Comparable 接口用於定義對象的自然順序,而 comparator 通常用於定義用戶定製的順序。Comparable 總是隻有一個,但是可以有多個 comparator 來定義對象的順序。

13.Java集合框架的基礎接口有哪些?

Collection爲集合層級的根接口。一個集合代表一組對象,這些對象即爲它的元素。Java平臺不提供這個接口任何直接的實現。

Set是一個不能包含重複元素的集合。這個接口對數學集合抽象進行建模,被用來代表集合,就如一副牌。

List是一個有序集合,可以包含重複元素。你可以通過它的索引來訪問任何元素。List更像長度動態變換的數組。

Map是一個將key映射到value的對象.一個Map不能包含重複的key:每個key最多隻能映射一個value。

一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

14.Iterator是什麼?

Iterator接口提供遍歷任何Collection的接口。我們可以從一個Collection中使用迭代器方法來獲取迭代器實例。迭代器取代了Java集合框架中的Enumeration。迭代器允許調用者在迭代過程中移除元素。

15.Enumeration和Iterator接口的區別?

Enumeration的速度是Iterator的兩倍,也使用更少的內存。Enumeration是非常基礎的,也滿足了基礎的需要。但是,與Enumeration相比,Iterator更加安全,因爲當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。
迭代器取代了Java集合框架中的Enumeration。迭代器允許調用者從集合中移除元素,而Enumeration不能做到。爲了使它的功能更加清晰,迭代器方法名已經經過改善。

16.Iterater和ListIterator之間有什麼區別?

(1)我們可以使用Iterator來遍歷Set和List集合,而ListIterator只能遍歷List。

(2)Iterator只可以向前遍歷,而LIstIterator可以雙向遍歷。

(3)ListIterator從Iterator接口繼承,然後添加了一些額外的功能,比如添加一個元素、替換一個元素、獲取前面或後面元素的索引位置。

17.在迭代一個集合的時候,如何避免ConcurrentModificationException?

在遍歷一個集合的時候,我們可以使用併發集合類來避免ConcurrentModificationException,比如使用CopyOnWriteArrayList,而不是ArrayList。

18.UnsupportedOperationException是什麼?

UnsupportedOperationException是用於表明操作不支持的異常。在JDK類中已被大量運用,在集合框架java.util.Collections.UnmodifiableCollection將會在所有add和remove操作中拋出這個異常。

19.在Java中,HashMap是如何工作的?

HashMap在Map.Entry靜態內部類實現中存儲key-value對。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。當我們通過傳遞key-value對調用put方法的時候,HashMap使用Key hashCode()和哈希算法來找出存儲key-value對的索引。Entry存儲在LinkedList中,所以如果存在entry,它使用equals()方法來檢查傳遞的key是否已經存在,如果存在,它會覆蓋value,如果不存在,它會創建一個新的entry然後保存。當我們通過傳遞key調用get方法時,它再次使用hashCode()來找到數組中的索引,然後使用equals()方法找出正確的Entry,然後返回它的值。
其它關於HashMap比較重要的問題是容量、負荷係數和閥值調整。HashMap默認的初始容量是32,負荷係數是0.75。閥值是爲負荷係數乘以容量,無論何時我們嘗試添加一個entry,如果map的大小比閥值大的時候,HashMap會對map的內容進行重新哈希,且使用更大的容量。容量總是2的冪,所以如果你知道你需要存儲大量的key-value對,比如緩存從數據庫裏面拉取的數據,使用正確的容量和負荷係數對HashMap進行初始化是個不錯的做法。
和HashMap一起問的會有ConcurrentHashMap的底層結構,關於這塊他們倆的底層結構,之後會寫一個源碼分析出來。

20.hashCode()和equals()方法有何重要性?

HashMap使用Key對象的hashCode()和equals()方法去決定key-value對的索引。當我們試着從HashMap中獲取值的時候,這些方法也會被用到。如果這些方法沒有被正確地實現,在這種情況下,兩個不同Key也許會產生相同的hashCode()和equals()輸出,HashMap將會認爲它們是相同的,然後覆蓋它們,而非把它們存儲到不同的地方。同樣的,所有不允許存儲重複數據的集合類都使用hashCode()和equals()去查找重複,所以正確實現它們非常重要。equals()和hashCode()的實現應該遵循以下規則:

(1)如果o1.equals(o2),那麼o1.hashCode() == o2.hashCode()總是爲true的。

(2)如果o1.hashCode() == o2.hashCode(),並不意味着o1.equals(o2)會爲true。

21.我們能否使用任何類作爲Map的key?

我們可以使用任何類作爲Map的key,然而在使用它們之前,需要考慮以下幾點:

(1)如果類重寫了equals()方法,它也應該重寫hashCode()方法。

(2)類的所有實例需要遵循與equals()和hashCode()相關的規則。請參考之前提到的這些規則。

(3)如果一個類沒有使用equals(),你不應該在hashCode()中使用它。

(4)用戶自定義key類的最佳實踐是使之爲不可變的,這樣,hashCode()值可以被緩存起來,擁有更好的性能。不可變的類也可以確保hashCode()和equals()在未來不會改變,這樣就會解決與可變相關的問題了。

// 比如,我有一個類MyKey,在HashMap中使用它。
// 傳遞給MyKey的name參數被用於equals()和hashCode()中
MyKey key = new MyKey('Pankaj'); //assume hashCode=1234
myHashMap.put(key, 'Value');
// 以下的代碼會改變key的hashCode()和equals()值
key.setName('Amit'); //assume new hashCode=7890
// 下面會返回null,因爲HashMap會嘗試查找存儲同樣索引的key,而key已被改變了,匹配失敗,返回null
myHashMap.get(new MyKey('Pankaj'));
// 那就是爲何String和Integer被作爲HashMap的key大量使用。

22.如何決定選用HashMap還是TreeMap?

對於在Map中插入、刪除和定位元素這類操作,HashMap是最好的選擇。然而,假如你需要對一個有序的key集合進行遍歷,TreeMap是更好的選擇。基於你的collection的大小,也許向HashMap中添加元素會更快,將map換爲TreeMap進行有序key的遍歷。

23.BlockingQueue是什麼?

Java.util.concurrent.BlockingQueue是一個隊列,在進行檢索或移除一個元素的時候,它會等待隊列變爲非空;當在添加一個元素時,它會等待隊列中的可用空間。BlockingQueue接口是Java集合框架的一部分,主要用於實現生產者-消費者模式。我們不需要擔心等待生產者有可用的空間,或消費者有可用的對象,因爲它都在BlockingQueue的實現類中被處理了。Java提供了集中BlockingQueue的實現,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,、SynchronousQueue等。
(後續也會對隊列這塊做一個源碼分析)

24.隊列和棧是什麼,列出它們的區別?

棧和隊列兩者都被用來預存儲數據。java.util.Queue是一個接口,它的實現類在Java併發包中。隊列允許先進先出(FIFO)檢索元素,但並非總是這樣。Deque接口允許從兩端檢索元素。
棧與隊列很相似,但它允許對元素進行後進先出(LIFO)進行檢索。
Stack是一個擴展自Vector的類,而Queue是一個接口。

25.我們如何對一組對象進行排序?

如果我們需要對一個對象數組進行排序,我們可以使用Arrays.sort()方法。如果我們需要排序一個對象列表,我們可以使用Collection.sort()方法。兩個類都有用於自然排序(使用Comparable)或基於標準的排序(使用Comparator)的重載方法sort()。

26.當一個集合被作爲參數傳遞給一個函數時,如何纔可以確保函數不能修改它?

在作爲參數傳遞之前,我們可以使用Collections.unmodifiableCollection(Collection c)方法創建一個只讀集合,這將確保改變集合的任何操作都會拋出UnsupportedOperationException。

37.我們如何從給定集合那裏創建一個synchronized的集合?

27.與Java集合框架相關的有哪些最好的實踐?

(1)根據需要選擇正確的集合類型。比如,如果指定了大小,我們會選用Array而非ArrayList。如果我們想根據插入順序遍歷一個Map,我們需要使用TreeMap。如果我們不想重複,我們應該使用Set。

(2)一些集合類允許指定初始容量,所以如果我們能夠估計到存儲元素的數量,我們可以使用它,就避免了重新哈希或大小調整。

(3)基於接口編程,而非基於實現編程,它允許我們後來輕易地改變實現。

(4)總是使用類型安全的泛型,避免在運行時出現ClassCastException。

(5)使用JDK提供的不可變類作爲Map的key,可以避免自己實現hashCode()和equals()。

(6)儘可能使用Collections工具類,或者獲取只讀、同步或空的集合,而非編寫自己的實現。它將會提供代碼重用性,它有着更好的穩定性和可維護性。


Spring框架

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

  • 輕量:Spring 是輕量的,基本的版本大約2MB。
  • 控制反轉:Spring通過控制反轉實現了鬆散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。
  • 面向切面的編程(AOP):Spring支持面向切面的編程,並且把應用業務邏輯和系統服務分開。
  • 容器:Spring 包含並管理應用中對象的生命週期和配置。
  • MVC框架:Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。
  • 事務管理:Spring 提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。
  • 異常處理:Spring 提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate or JDO拋出的)轉化爲一致的unchecked 異常。
  1. 什麼是Spring IOC 容器?

Spring IOC 負責創建對象,管理對象(通過依賴注入(DI),裝配對象,配置對象,並且管理這些對象的整個生命週期。

3.IOC的優點是什麼?

IOC 或 依賴注入把應用的代碼量降到最低。它使應用容易測試,單元測試不再需要單例和JNDI查找機制。最小的代價和最小的侵入性使鬆散耦合得以實現。IOC容器支持加載服務時的餓漢式初始化和懶加載。

4.ApplicationContext通常的實現是什麼?

  • FileSystemXmlApplicationContext :此容器從一個XML文件中加載beans的定義,XML Bean 配置文件的全路徑名必須提供給它的構造函數。
  • ClassPathXmlApplicationContext:此容器也從一個XML文件中加載beans的定義,這裏,你需要正確設置classpath因爲這個容器將在classpath裏找bean配置。
  • WebXmlApplicationContext:此容器加載一個XML文件,此文件定義了一個WEB應用的所有bean。
  1. 有哪些不同類型的IOC(依賴注入)方式?
  • 構造器依賴注入:構造器依賴注入通過容器觸發一個類的構造器來實現的,該類有一系列參數,每個參數代表一個對其他類的依賴。
  • Setter方法注入:Setter方法注入是容器通過調用無參構造器或無參static工廠 方法實例化bean之後,調用該bean的setter方法,即實現了基於setter的依賴注入。

6.解釋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情形下有效。

7.Spring框架中的單例bean是線程安全的嗎?

不,Spring框架中的單例bean不是線程安全的。

8.解釋Spring框架中bean的生命週期?

  • Spring容器 從XML 文件中讀取bean的定義,並實例化bean。
  • Spring根據bean的定義填充所有的屬性。
  • 如果bean實現了BeanNameAware 接口,Spring 傳遞bean 的ID 到 setBeanName方法。
  • 如果Bean 實現了 BeanFactoryAware 接口, Spring傳遞beanfactory 給setBeanFactory 方法。
  • 如果有任何與bean相關聯的BeanPostProcessors,Spring會在postProcesserBeforeInitialization()方法內調用它們。
  • 如果bean實現IntializingBean了,調用它的afterPropertySet方法,如果bean聲明瞭初始化方法,調用此初始化方法。
  • 如果有BeanPostProcessors 和bean 關聯,這些bean的postProcessAfterInitialization() 方法將被調用。
  • 如果bean實現了 DisposableBean,它將調用destroy()方法。

9.哪些是重要的bean生命週期方法? 你能重載它們嗎?

有兩個重要的bean 生命週期方法,第一個是setup , 它是在容器加載bean的時候被調用。第二個方法是 teardown 它是在容器卸載類的時候被調用。

The bean 標籤有兩個重要的屬性(init-method和destroy-method)。用它們你可以自己定製初始化和註銷方法。它們也有相應的註解(@PostConstruct和@PreDestroy)。

10.解釋不同方式的自動裝配 ?

有五種自動裝配的方式,可以用來指導Spring容器用自動裝配方式來進行依賴注入。

  • no:默認的方式是不進行自動裝配,通過顯式設置ref 屬性來進行裝配。
  • byName:通過參數名 自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byname,之後容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。
  • byType::通過參數類型自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byType,之後容器試圖匹配、裝配和該bean的屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。
  • constructor:這個方式類似於byType, 但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。
  • autodetect:首先嚐試使用constructor來自動裝配,如果無法工作,則使用byType方式。

11.各個註解的含義?

  • @Required:這個註解表明bean的屬性必須在配置的時候設置,通過一個bean定義的顯式的屬性值或通過自動裝配,若@Required註解的bean屬性未被設置,容器將拋出BeanInitializationException。
  • @Autowired:註解提供了更細粒度的控制,包括在何處以及如何完成自動裝配。它的用法和@Required一樣,修飾setter方法、構造器、屬性或者具有任意名稱多個參數的PN方法。
  • @Qualifier:當有多個相同類型的bean卻只有一個需要自動裝配時,將@Qualifier 註解和@Autowire 註解結合使用以消除這種混淆,指定需要裝配的確切的bean。

12.Spring支持的事務管理類型?

  • 編程式事務管理:這意味你通過編程的方式管理事務,給你帶來極大的靈活性,但是難維護。
  • 聲明式事務管理:這意味着你可以將業務代碼和事務管理分離,你只需用註解和XML配置來管理事務。

13.有幾種不同類型的自動代理?

  • BeanNameAutoProxyCreator
  • DefaultAdvisorAutoProxyCreator
  • Metadata autoproxying

14.Aspect 切面

AOP核心就是切面,它將多個類的通用行爲封裝成可重用的模塊,該模塊含有一組API提供橫切功能。比如,一個日誌模塊可以被稱作日誌的AOP切面。根據需求的不同,一個應用程序可以有若干切面。在Spring AOP中,切面通過帶有@Aspect註解的類實現。

15.在Spring AOP 中,關注點和橫切關注的區別是什麼?

  • 關注點是應用中一個模塊的行爲,一個關注點可能會被定義成一個我們想實現的一個功能。
  • 橫切關注點是一個關注點,此關注點是整個應用都會使用的功能,並影響整個應用,比如日誌,安全和數據傳輸,幾乎應用的每個模塊都需要的功能。因此這些都屬於橫切關注點。

16.通知

通知是個在方法執行前或執行後要做的動作,實際上是程序執行時要通過SpringAOP框架觸發的代碼段。

Spring切面可以應用五種類型的通知:

  • before:前置通知,在一個方法執行前被調用。
  • after: 在方法執行之後調用的通知,無論方法執行是否成功。
  • after-returning: 僅當方法成功完成後執行的通知。
  • after-throwing: 在方法拋出異常退出時執行的通知。
  • around: 在方法執行之前和之後調用的通知。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章