1、什麼是Java虛擬機器?為什麼Java被稱為「平台無關的程式語言」?
(更多相關面試題推薦:java面試題及答案)
java虛擬機器是執行字節碼檔案(.class)的虛擬機器流程。 。 java原始程式(.java)被編譯器編譯成字節碼檔(.class)。然後字節碼文件,將由java虛擬機,解釋成機器碼(不同平台的機器碼不同)。利用機器碼操作硬體和作業系統。因為不同的平台裝有不同的JVM,它們能夠將相同的.class文件,解釋成不同平台所需的機器碼。正是因為有JVM的存在,java被稱為平台無關的程式語言。
2.JDK和JRE的差別是什麼?
Java開發工具包(JDK)是完整的Java軟體開發包,包含了JRE,編譯器和其他的工具(例如:JavaDoc,Java調試器),可以讓開發者開發、編譯、執行Java應用程式。 Java執行時期環境(JRE)。它包括Java虛擬機器、Java核心類別庫和支援文件。它不包含開發工具(JDK)、編譯器、偵錯器和其他工具。
3.”static」關鍵字是什麼意思? Java中是否可以覆寫(override)一個private或是static的方法?
「static」關鍵字表示一個成員變數或是成員方法可以在沒有所屬的類別的實例變數的情況下被存取。
Java中static方法不能被覆寫,因為方法覆寫是基於執行時間動態綁定的,而static方法是編譯時靜態綁定的。 static方法跟類別的任何實例都不相關,所以概念上不適用。 java中也不可以覆寫private的方法,因為private修飾的變數和方法只能在目前類別中使用,如果是其他的類別繼承目前類別是不能存取到private變數或方法的,當然也不能覆寫。
4.是否可以在static環境中存取非static變數?
static變數在Java中是屬於類別的,它在所有的實例中的值是一樣的。當類別被Java虛擬機器載入的時候,會對static變數進行初始化。如果你的程式碼嘗試不用實例來存取非static的變量,編譯器會報錯,因為這些變數還沒有被創建出來,還沒有跟任何實例關聯上。
5.Java支援的資料型別有哪些?什麼是自動拆裝箱?
Java支援的資料型別包含兩種:一種是基本資料型別,包含byte,char, short, boolean ,int, long, float, double;另一種是引用型別:如String等,其實是物件的引用,JVM中虛擬棧中存的是物件的位址,所建立的物件實質在堆中,透過位址來找到堆中的物件的過程,也就是為引用型別。自動裝箱就是Java編譯器在基本資料型別和對應的物件包裝類型間的轉化,也就是int轉化為Integer,自動拆箱是Integer呼叫其方法將其轉化為int的過程。
6.Java中的方法覆寫(Overriding)和方法重載(Overloading)是什麼意思?
Java中的方法重載發生在同一個類別裡面兩個或是多個方法的方法名稱相同但是參數不同的情況。重載Override是一個類別中多態性的一種表現。方法覆蓋是說子類別重新定義了父類別的方法。方法覆蓋必須有相同的方法名,參數清單和傳回類型。覆蓋者可能不會限制它所覆蓋的方法的存取。在java中,子類別可繼承父類別的方法,則不需要重新編寫相同的方法。但有時子類別不想原封不動繼承父類別的方法,而是想做一定的修改,這就採用方法重寫。方法重寫又稱方法覆蓋。
7.Java中,什麼是建構方法?什麼是構造方法重載?什麼是複製構造方法?
當新物件被建立的時候,建構方法會被呼叫。每一個類別都有構造方法。在程式設計師沒有提供類別建構方法的情況下,Java編譯器會為這個類別建立一個預設的構造方法。 Java中構造方法重載和方法重載很相似。可以為一個類別建立多個構造方法。每一個構造方法必須有它自己唯一的參數列表。 Java不支援複製構造方法,如果你不自己寫構造方法的情況下,Java不會建立預設的複製構造方法。
8. Java支援多繼承麼?
Java中類別不支援多重繼承,只支援單繼承(即一個類別只有一個父類別)。但是java中的介面支援多繼承,,即一個子介面可以有多個父介面。 (接口的作用是用來擴展對象的功能,一個子接口繼承多個父接口,說明子接口擴展了多個功能,當類實現接口時,類就擴展了相應的功能)。
9. 介面和抽象類別的差別是什麼?
從設計層面來說,抽像是對類別的抽象,是一種模板設計,介面是行為的抽象,是一種行為的規範。
Java提供和支援建立抽象類別和介面。它們的實現有共同點,不同點在於:
介面中所有的方法隱含的都是抽象的。而抽象類別則可以同時包含抽象和非抽象的方法;類別可以實現很多接口,但是只能繼承一個抽象類別;類別可以不實現抽象類別和接口聲明的所有方法,當然,在這種情況下,類別也必須宣告成是抽象的;抽象類別可以在不提供介面方法實作的情況下實作介面;Java介面中宣告的變數預設都是final的。抽象類別可以包含非final的變數;Java介面中的成員函數預設是public的。抽象類別的成員函數可以是private,protected或是public;介面是絕對抽象的,不可以被實例化。抽象類別也不可以被實例化,但是,如果它包含main方法的話是可以被呼叫的。
也可以參考JDK8中抽象類別和介面的差異。
10. 什麼是值傳遞和引用傳遞?
一般認為,java內的傳遞都是值傳遞. java中實例物件的傳遞是引用傳遞。
值傳遞是對基本型變數而言的,傳遞的是該變數的一個副本,改變副本不影響原變數;引用傳遞一般是對於物件型變數而言的,傳遞的是該對象地址的一個副本, 並不是原始物件本身。
11. 進程與執行緒的差別?
進程是執行著的應用程序,是程式的一種動態形式,是CPU、記憶體等資源佔用的基本單位,而且進程之間相互獨立,通訊比較困難,進程在執行過程中,包含比較固定的入口,執行順序,出口;線程是進程內部的執行序列,隸屬於某個進程,一個進程可以有多個線程,線程不能佔有CPU、記憶體等資源,而且線程之間共享一塊記憶體區域,通訊比較方便,執行緒的入口執行順序這些過程被應用程式所控制。
12. 建立執行緒有幾種不同的方式?你喜歡哪一種?為什麼?
有四種方式可以用來建立執行緒。
繼承Thread類別;實作Runnable介面;應用程式可以使用Executor框架來建立執行緒池;實作Callable介面。
實作Runnable介面這種方式比較受歡迎,因為這不需要繼承Thread類別。在應用程式設計中已經繼承了別的物件的情況下,這需要多繼承(而Java不支援多重繼承),只能實作介面。同時,線程池也是非常有效率的,很容易實現和使用。
13. 概括的解釋下線程的幾個可用狀態。
新建( new ):新建了一個執行緒物件。可運行( runnable ):執行緒物件建立後,其他執行緒(例如 main 執行緒)呼叫了該物件的start ()方法。此狀態的執行緒位於可運行執行緒池中,等待被執行緒調度選中,取得cpu的使用權。運行( running ):可運行狀態( runnable )的執行緒獲得了cpu時間片( timeslice ),執行程式碼。阻塞( block ):阻塞狀態是指執行緒因為某些原因放棄了cpu使用權,也即讓出了cpu timeslice ,暫時停止運作。直到執行緒進入可運行( runnable )狀態,才有機會再次獲得 cpu timeslice 轉到運行( running )狀態。阻塞的情況分三種:
(一). 等待阻塞:運行( running )的執行緒執行 o.wait ()方法,JVM會把該執行緒放入等待佇列( waitting queue )中。
(二). 同步阻塞:執行( running )的執行緒在取得物件的同步鎖定時,若該同步鎖定被別的執行緒佔用,則JVM 會把該執行緒放入鎖池( lock pool )中。
(三). 其他阻塞: 執行( running )的執行緒執行Thread.sleep ( long ms )或t.join ()方法,或發出了I/O 請求時,JVM會把該執行緒置為阻塞狀態。當 sleep ()狀態逾時、join()等待執行緒終止或逾時、或I/O 處理完畢時,執行緒重新轉入可運行( runnable )狀態。
死亡( dead ):執行緒run()、 main() 方法執行結束,或因例外而退出了run()方法,則該執行緒結束生命週期。死亡的線不可再復生。
14. 同步方法和同步程式碼區塊的差別是什麼?
為何要使用同步?
java允許多執行緒並發控制,當多個執行緒同時操作一個可共享的資源變數時(增刪改查),將會導致資料的不準確,相互之間產生衝突,因此加入同步鎖定以避免在該線程沒有完成操作之前,被其他線程的調用,從而保證了該變數的唯一性和準確性。
區別
同步方法預設用this或目前類別class物件作為鎖;同步程式碼區塊可以選擇以什麼來加鎖,比同步方法要更細顆粒度,我們可以選擇只同步會發生同步問題的部分程式碼而不是整個方法;同步方法使用關鍵字synchronized修飾方法,而同步程式碼區塊主要是修飾需要進行同步的程式碼,用synchronized(object){程式碼內容}進行修飾;
15. 在監視器(Monitor)內部,是如何做執行緒同步的?程式應該做哪種等級的同步?
監視器和鎖在Java虛擬機器中是一塊使用的。監視器監視一塊同步程式碼區塊,確保一次==只有一個執行緒執行同步程式碼區塊==。每一個監視器都和一個物件引用相關聯。線程在獲取鎖之前不允許執行同步程式碼。
16.什麼是死鎖(deadlock)?
所謂死鎖是指多個進 程因==競爭資源==而造成的一種僵局(互相等待),若無外力作用,這些進程都將無法向前推進。死鎖產生的4個必要條件:
互斥條件:進程要求對所分配的資源(如印表機)進行排他性控制,即在一段時間內某 資源僅為一個程序所佔有。此時若有其他進程請求該資源,則請求進程只能等待。不剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能 由獲得該資源的進程自己來釋放(只能是主動釋放)。請求與保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源 已被其他進程佔有,此時請求進程被阻塞,但對自己已獲得的資源保持不放。循環等待條件:存在一種進程資源的==循環等待鏈==,鏈中每一個進程已獲得的資源同時被鏈中下一個進程所請求。
17. 如何確保N個執行緒可以存取N個資源同時又不導致死鎖?
使用多執行緒的時候,一個非常簡單的避免死鎖的方式就是:==指定取得鎖的順序==,並強制執行緒依照指定的順序取得鎖。因此,如果所有的執行緒都是以同樣的順序加鎖和釋放鎖,就不會出現死鎖了。
18.Java集合類別框架的基本介面有哪些?
集合類別介面指定了一組叫做元素的物件。集合類別介面的每一種具體的實作類別都可以選擇以它自己的方式對元素進行保存和排序。有的集合類別允許重複的鍵,有些不允許。
Java集合類別提供了一套設計良好的支援對一組物件進行操作的介面和類別。 Java集合類別裡面最基本的介面有:
Collection:代表一組對象,每個物件都是它的子元素。 Set:不包含重複元素的Collection。 List:有順序的collection,可以包含重複元素。 Map:可以把鍵(key)對應到值(value)的對象,鍵不能重複。
19.為什麼集合類別沒有實作Cloneable和Serializable介面?
克隆(cloning)或是序列化(serialization)的語意和意義是跟具體的實作相關的。因此,應該由集合類別的具體實作來決定如何被複製或是序列化。
20.什麼是迭代器(Iterator)?
Iterator介面提供了許多對集合元素進行迭代的方法。每一個集合類別都包含了可以傳回迭代器實例的
迭代方法。迭代器可以在迭代的過程中刪除底層集合的元素,但是不可以直接呼叫集合的
remove(Object Obj)刪除,可以透過迭代器的remove()方法刪除。
21.Iterator和ListIterator的差別是什麼?
下面列出了他們的區別:
Iterator可用來遍歷Set和List集合,但是ListIterator只能用來遍歷List。 Iterator對集合只能是前向遍歷,ListIterator既可以前向也可以後向。 ListIterator實作了Iterator接口,並包含其他的功能,例如:增加元素,替換元素,取得前一個和後一個元素的索引,等等。
22.快速失敗(fail-fast)和安全失敗(fail-safe)的差別是什麼?
Iterator的安全失敗是基於對底層集合做拷貝,因此,它不受來源集合上修改的影響。 java.util套件下面的所有的集合類別都是快速失敗的,而java.util.concurrent套件下面的所有的類別都是安全失敗的。快速失敗的迭代器會拋出ConcurrentModificationException異常,而安全失敗的迭代器永遠不會拋出這樣的異常。
33.Java中的HashMap的工作原理是什麼?
Java中的HashMap是以鍵值對(key-value)的形式儲存元素的。 HashMap需要一個hash函數,它使用hashCode()和equals()方法來新增和擷取元素到集合/從集合。當呼叫put()方法的時候,HashMap會計算key的hash值,然後把鍵值對儲存在集合中適當的索引上。如果key已經存在了,value會被更新成新值。 HashMap的一些重要的特性是它的容量(capacity),負載因子(load factor)和擴容極限(threshold resizing)。
34.hashCode()和equals()方法的重要性體現在什麼地方?
Java中的HashMap使用hashCode()和equals()方法來決定鍵值對的索引,當根據鍵取得值的時候也會用到這兩個方法。如果沒有正確的實現這兩個方法,兩個不同的鍵可能會有相同的hash值,因此,可能會被集合認為是相等的。而且,這兩個方法也用來發現重複元素。所以這兩個方法的實現對HashMap的精確性和正確性是至關重要的。
35.HashMap和Hashtable有什麼差別?
HashMap和Hashtable都實作了Map接口,因此很多特性都非常相似。但是,他們有以下不同點:
HashMap允許鍵和值是null,而Hashtable不允許鍵或值是null。 Hashtable是同步的,而HashMap不是。因此,HashMap更適合單執行緒環境,而Hashtable適合於多執行緒環境。 HashMap提供了可供應用迭代的鍵的集合,因此,HashMap是快速失敗的。另一方面,Hashtable提供了對鍵的列舉(Enumeration)。一般認為Hashtable是遺留的類別。
36. 陣列(Array)和列表(ArrayList)有什麼不同?什麼時候應該使用Array而不是ArrayList?
Array可以包含基本類型和物件類型,ArrayList只能包含物件類型。 Array大小是固定的,ArrayList的大小是動態變化的。 ArrayList提供了更多的方法和特性,例如:addAll(),removeAll(),iterator()等等。對於基本類型數據,集合使用自動裝箱來減少編碼工作量。但是,當處理固定大小的基本資料類型的時候,這種方式相對比較慢。
37. ArrayList和LinkedList有什麼差別?
ArrayList和LinkedList都實作了List接口,他們有以下的不同點:
ArrayList是基於索引的資料接口,它的底層是數組。它可以以O(1)時間複雜度對元素進行隨機存取。與此對應,LinkedList是以==元素列表==的形式儲存它的數據,每一個元素都和它的前一個和後一個元素連結在一起,在這種情況下,查找某個元素的時間複雜度是O(n)。
相對於ArrayList,LinkedList的插入,添加,刪除操作速度更快,因為當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。 LinkedList比ArrayList更佔內存,因為LinkedList為每一個節點儲存了兩個引用,一個指向前一個元素,一個指向下一個元素。
38.Comparable和Comparator介面是做什麼的?列出它們的差異。
Java提供了只包含一個compareTo()方法的Comparable介面。這個方法可以個給兩個物件排序。具體來說,它會傳回負數,0,正數來表示已經存在的物件小於,等於,大於輸入物件。
Java提供了包含compare()和equals()兩個方法的Comparator介面。 compare()方法用來給兩個輸入參數排序,傳回負數,0,正數表示第一個參數是小於,等於,大於第二個參數。 equals()方法需要一個物件作為參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator並且輸入參數和當前comparator的排序結果是相同的時候,這個方法才會回傳true。
Comparable & Comparator 都是用來實現集合中元素的比較、排序的,只是 Comparable是在集合內部定義的方法實現的排序,Comparator 是在集合外部實現的排序,所以,如想實現排序,就需要在集合外定義Comparator 介面的方法或在集合內實作Comparable 介面的方法。 Comparator位於套件java.util下,而Comparable位於套件java.lang下Comparable 是一個物件本身就已經支援自比較所需實作的介面(如String、Integer 本身就可以完成比較大小操作,已經實作了Comparable介面)自訂的類別要在加入list容器中後能夠排序,可以實作Comparable接口,在用Collections類別的sort方法排序時,如果不指定Comparator,那麼就以自然順序排序, 這裡的自然順序就是實作Comparable介面設定的排序方式。
而 Comparator 是一個專用的比較器,當這個物件不支援自比較或自比較函數不能滿足你的要求時,你可以寫一個比較器來完成兩個物件之間大小的比較。可以說一個是自已完成比較,一個是外部程式實現比較的差異而已。用 Comparator 是策略模式(strategy design pattern),就是不改變物件自身,而用一個策略物件(strategy object)來改變它的行為。例如:你想對整數採用絕對值大小來排序,Integer 是不符合要求的,你不需要去修改Integer 類別(實際上你也不能這麼做)去改變它的排序行為,只要使用一個實現了Comparator 接口的物件來實現控制它的排序就行了。
39.什麼是Java優先權佇列(Priority Queue)?
PriorityQueue是基於優先權堆的無界隊列,它的元素是依照自然順序(natural order)排序的。在創建的時候,我們可以給它一個負責給元素排序的比較器。 PriorityQueue不允許null值,因為他們沒有自然順序,或者說他們沒有任何的相關聯的比較器。最後,PriorityQueue不是線程安全的,入隊和出隊的時間複雜度是O(log(n))。
40.你了解大O符號(big-O notation)麼?你能舉出不同資料結構的例子麼?
大O符號描述了當資料結構裡面的元素增加的時候,演算法的規模或是一個漸進上界 。
大O符號也可用來描述其他的行為,例如:記憶體消耗。因為集合類別其實是資料結構,我們一般使用大O符號是基於時間,記憶體和效能來選擇最好的實作。大O符號可以對大量資料的效能給出一個很好的說明。
41.Enumeration介面和Iterator介面的差別有哪些?
Enumeration速度是Iterator的2倍,同時佔用更少的記憶體。但是,Iterator遠遠比Enumeration安全,因為其他執行緒不能夠修改正在被iterator遍歷的集合裡面的物件。同時,Iterator允許呼叫者刪除底層集合裡面的元素,這對Enumeration來說是不可能的。
42.HashSet和TreeSet有什麼差別?
HashSet是由一個hash表來實現的,因此,它的元素是無序的。 add(),remove(),contains()方法的時間複雜度是O(1)。另一方面,TreeSet是由一個樹狀的結構來實現的,它裡面的元素是有序的。因此,add(),remove(),contains()方法的時間複雜度是O(logn)。
43.Java中垃圾回收有什麼目的?什麼時候進行垃圾回收?
垃圾回收是在記憶體中存在沒有引用的物件或超過作用域的物件時進行。
垃圾回收的目的是識別並且丟棄應用不再使用的物件來釋放和重複使用資源。
44.System.gc()和Runtime.gc()會做什麼事情?
這兩個方法用來提示JVM要進行垃圾回收。但是,立即開始還是延遲進行垃圾回收是取決於JVM的。
45.finalize()方法什麼時候被呼叫?析構函數(finalization)的目的是什麼?
垃圾回收器(garbage colector)決定回收某物件時,就會運行該物件的finalize()方法但是在Java中很不幸,如果記憶體總是充足的,那麼垃圾回收可能永遠不會進行,也就是說filalize()可能永遠不被執行,顯然指望它做收尾工作是靠不住的。那麼finalize()究竟是做什麼的呢?它最主要的用途是回收特殊渠道申請的記憶體。 Java程式有垃圾回收器,所以一般情況下記憶體問題不用程式設計師操心。但有一種JNI(Java Native Interface)呼叫non-Java程式(C或C ),finalize()的工作就是回收這部分的記憶體。
呼叫時機:當垃圾回收器要宣告一個物件死亡時,至少要經過兩次標記過程:如果物件在進行可達性分析後發現沒有和GC Roots連結的引用鏈,就會被第一次標記,並且判斷是否執行finalizer( )方法,如果物件覆寫finalizer( )方法且未被虛擬機器呼叫過,那麼這個物件會被放置在F-Queue佇列中,並在稍後由一個虛擬機自動建立的低優先順序的Finalizer執行緒區執行觸發finalizer( )方法,但不承諾等待其運行結束。
(推薦教學:java課程)
finalization的目的:物件逃脫死亡的最後一次機會。 (只要重新與引用鏈上的任何一個物件建立關聯即可。)但是不建議使用,運行代價高昂,不確定性大,且無法保證各個物件的呼叫順序。可用try-finally或其他替代品。
46.如果物件的參考被置為null,垃圾收集器是否會立即釋放物件所佔用的記憶體?
不會,在下一個垃圾回收週期中,這個物件將是可被回收的。
不會立即釋放物件佔用的記憶體。如果物件的參考被置為null,只是斷開了當前線程棧幀中對該物件的引用關係,而垃圾收集器是運行在後台的線程,只有當用戶線程運行到安全點(safe point)或安全區域才會掃描對象引用關係,掃描到對象沒有被引用則會標記對象,這時候仍然不會立即釋放該對象內存,因為有些對像是可恢復的(在finalize方法中恢復引用)。只有確定了物件無法恢復引用的時候才會清除物件記憶體。
47.Java堆的結構是什麼樣子的?什麼是堆中的永久代(Perm Gen space)?
JVM的堆是運行時資料區,所有類別的實例和陣列都是在堆上分配記憶體。它在JVM啟動的時候被創建。物件所佔的堆記憶體是由自動記憶體管理系統也就是垃圾收集器回收。
堆記憶體是由存活和死亡的物件組成的。存活的物件是應用可以存取的,不會被垃圾回收。死亡的對像是應用不可訪問尚且還沒有被垃圾收集器回收的物件。一直到垃圾收集器把這些物件回收掉之前,他們會一直佔據堆記憶體空間。
永久代是用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类,永久代中一般包含:
类的方法(字节码…)
类名(Sring对象)
.class文件读到的常量信息
class对象相关的对象列表和类型列表 (e.g., 方法对象的array).
JVM创建的内部对象
JIT编译器优化用的信息
48.串行(serial)收集器和吞吐量(throughput)收集器的区别是什么?
吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等规模和大规模数据的应用程序。而串行收集器对大多数的小应用(在现代处理器上需要大概100M左右的内存)就足够了。
49.在Java中,对象什么时候可以被垃圾回收?
当一个对象到GC Roots不可达时,在下一个垃圾回收周期中尝试回收该对象,如果该对象重写了finalize()方法,并在这个方法中成功自救(将自身赋予某个引用),那么这个对象不会被回收。但如果这个对象没有重写finalize()方法或者已经执行过这个方法,也自救失败,该对象将会被回收。
50.JVM的永久代中会发生垃圾回收么?
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。请参考下Java8:从永久代到元数据区
(注:Java8中已经移除了永久代,新加了一个叫做元数据区的native内存区)
51.Java中的两种异常类型是什么?他们有什么区别?
Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。这里有Java异常处理的一些小建议。
Throwable包含了错误(Error)和异常(Excetion两类)
Exception又包含了运行时异常(RuntimeException, 又叫非检查异常)和非运行时异常(又叫检查异常)
(1) Error是程序无法处理了, 如果OutOfMemoryError等, 这些异常发生时, java虚拟机一般会终止线程 .
(2) 运行时异常都是RuntimeException类及其子类,如 NullPointerException、IndexOutOfBoundsException等, 这些异常是不检查的异常, 是在程序运行的时候可能会发生的, 所以程序可以捕捉, 也可以不捕捉. 这些错误一般是由程序的逻辑错误引起的, 程序应该从逻辑角度去尽量避免.
(3) 检查异常是运行时异常以外的异常, 也是Exception及其子类, 这些异常从程序的角度来说是必须经过捕捉检查处理的, 否则不能通过编译. 如IOException、SQLException等。
52.Java中Exception和Error有什么区别?
Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况。Error定义了不期望被用户程序捕获的异常。
53.throw和throws有什么区别?
throw关键字用来在程序中明确的抛出异常,相反,throws语句用来表明方法不能处理的异常。每一个方法都必须要指定哪些异常不能处理,所以方法的调用者才能够确保处理可能发生的异常,多个异常是用逗号分隔的。
1、Throw用于方法内部,Throws用于方法声明上;
2、Throw后跟异常对象,Throws后跟异常类型;
3、Throw后只能跟一个异常对象,Throws后可以一次声明多种异常类型。
54. 异常处理完成以后,Exception对象会发生什么变化?、
Exception对象会在下一个垃圾回收过程中被回收掉。
55. finally代码块和finalize()方法有什么区别?
无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。
56. 什么是Applet?
java applet是能够被包含在HTML页面中并且能被启用了java的客户端浏览器执行的程序。Applet主要用来创建动态交互的web应用程序。
57. 解释一下Applet的生命周期。
applet可以经历下面的状态:
Init:每次被载入的时候都会被初始化。
Start:开始执行applet。
Stop:结束执行applet。
Destroy:卸载applet之前,做最后的清理工作。
58. 當applet被載入的時候會發生什麼事?
首先,建立applet控制類別的實例,然後初始化applet,最後開始運作。
59. Applet和普通的Java應用程式有什麼不同?
applet是運行在啟用了java的瀏覽器中,Java應用程式是可以在瀏覽器之外運行的獨立的Java程式。但是,它們都需要有Java虛擬機器。
進一步來說,Java應用程式需要一個有特定方法簽署的main函數來開始執行。 Java applet不需要這樣的函數來開始執行。
最後,Java applet一般會使用很嚴格的安全策略,Java應用一般使用較寬鬆的安全策略。
60. Java applet有哪些限制條件?
主要是由於安全的原因,給applet施加了以下的限制:
applet不能夠載入類別庫或定義本地方法;不能在宿主機上讀寫檔案;不能讀取特定的系統屬性;不能發起網路連接,除非是跟宿主機;無法開啟宿主機上其他任何的程式。
61. 什麼是不受信任的applet?
不受信任的applet是無法存取或是執行本機系統檔案的Java applet,預設情況下,所有下載的applet都是不受信任的。
62. 從網路上載入的applet和從本機檔案系統載入的applet有什麼差別?
當applet是從網路載入的時候,applet是由applet類別載入器載入的,它受applet安全管理器的限制。
當applet是從客戶端的本機磁碟載入的時候,applet是由檔案系統載入器載入的。
從文件系統載入的applet允許在客戶端讀取文件,寫文件,載入類別庫,也允許執行其他程序,但是,卻通不過字節碼校驗。
63. applet類別載入器是什麼?它會做哪些工作?
當applet是從網路上載入的時候,它是由applet類別載入器載入的。類別載入器有自己的java名稱空間等級結構。類別載入器會保證來自檔案系統的類別有唯一的名稱空間,來自網路資源的類別有唯一的名稱空間。
當瀏覽器透過網路載入applet的時候,applet的類別被放置在和applet的來源相關聯的私有的名稱空間中。然後,那些被類別載入器載入進來的類別都是經過了驗證器驗證的。驗證器會檢查類別檔案格式是否遵守Java語言規範,確保不會出現堆疊溢位(stack overflow)或是下溢(underflow),傳遞給字節碼指令的參數是正確的。
64. applet安全性管理器是什麼?它會做哪些工作?
applet安全管理器是給applet施加限制條件的一種機制。瀏覽器可以只有一個安全管理器。安全管理器在啟動的時候被創建,之後不能被替換覆蓋或擴充。
65. 彈出式選擇選單(Choice)和清單(List)有什麼不同?
Choice是以一種緊湊的形式展示的,需要下拉才能看到所有的選項。 Choice中一次只能選取一個選項。 List同時可以有多個元素可見,支援選取一個或多個元素。
66. 什麼是佈局管理器?
佈局管理器用來在容器中組織元件。
67. 滾動條(Scrollbar)和滾動面板(JScrollPane)有什麼不同?
Scrollbar是一個元件,不是容器。而ScrollPane是容器。 ScrollPane自己處理滾動事件。
68. 哪些Swing的方法是執行緒安全的?
只有3個執行緒安全的方法: repaint(), revalidate(), and invalidate()。
69. 舉出三種支援重繪(painting)的元件。
Canvas, Frame, Panel,和Applet支援重繪。
70. 什麼是JDBC?
JDBC是允許使用者在不同資料庫之間做選擇的一個抽象層。 JDBC允許開發者用JAVA寫入資料庫應用程序,而不需要關心底層特定資料庫的細節。
JDBC(Java DataBase Connectivity),是一套物件導向的應用程式介面(API),制定了統一的存取各類關係資料庫的標準接口,為各個資料庫廠商提供了標準的實作。透過JDBC技術,開發人員可以用純Java語言和標準的SQL語句編寫完整的資料庫應用程序,並且真正實現了軟體的跨平台性。
通常情況下使用JDBC完成以下操作:
1.同資料庫建立連線;
2.向資料庫傳送SQL語句;
3.處理從資料庫傳回的結果;
JDBC具有下列優點:
1.JDBC與ODBC(Open Database Connectivity,即開放資料庫互連)十分相似,便於軟體開發人員理解;
2.JDBC使軟體開發人員從複雜的驅動程式編寫工作中解脫出來,可以完全專注於業務邏輯開發;
3.JDBC支援多種關係型資料庫,大大增加了軟體的可移植性;
4.JDBC API是物件導向的,軟體開發人員可以將常用的方法進行二次封裝,從而提高程式碼的重用性;
71. 資料庫連接池是什麼意思?
像是開啟關閉資料庫連接這種和資料庫的互動可能是很費時的,尤其是當客戶端數量增加的時候,會消耗大量的資源,成本是非常高的。可以在應用程式伺服器啟動的時候建立很多資料庫連線並維護在一個池中。連線請求由池中的連線提供。在連線使用完畢以後,把連線歸還到池中,以用於滿足將來更多的請求。
72. 讓RMI程式能正確運作有哪些步驟?
為了讓RMI程式能正確運作必須要包含以下幾個步驟:
編譯所有的原始檔。
使用rmic產生stub。
啟動rmiregistry。
啟動RMI伺服器。
執行客戶端程式。
73. 解釋下Marshalling和demarshalling。
當應用程式希望把記憶體物件跨網路傳遞到另一台主機或是持久化到儲存的時候,就必須要把物件在記憶體裡面的表示轉換成合適的格式。這個過程就叫做Marshalling,反之就是demarshalling。
74. 解釋下Serialization和Deserialization。
Java提供了一種叫做物件序列化的機制,他把物件表示成一連串的字節,裡麵包含了物件的數據,物件的類型信息,物件內部的資料的類型資訊等等。因此,序列化可以看成是為了把物件儲存在磁碟上或是從磁碟上讀出來並重建物件而把物件扁平化的一種方式。反序列化是把物件從扁平狀態轉換成活動物件的相反的步驟。
75. 什麼是Servlet?
Servlet是用來處理客戶端請求並產生動態網頁內容的Java類別。 Servlet主要用來處理或是儲存HTML表單提交的數據,產生動態內容,在無狀態的HTTP協定下管理狀態資訊。
76. 說一下Servlet的體系結構。
所有的Servlet都必須實現的核心的介面是javax.servlet.Servlet。每一個Servlet都必須直接或是間接實作這個接口,或是繼承javax.servlet.GenericServlet或javax.servlet.http.HTTPServlet。最後,Servlet使用多執行緒可以並行的為多個請求服務。
77. 什麼是網頁應用程式?
Web應用程式是對Web或是應用程式伺服器的動態擴充。有兩種類型的Web應用:面向表現的和服務導向的。以表現為導向的網路應用程式會產生包含了很多種標記語言和動態內容的互動的web頁面作為對請求的回應。而服務導向的Web應用實現了Web服務的端點(endpoint)。一般來說,一個Web應用程式可以看成是一組安裝在伺服器URL名稱空間的特定子集下面的Servlet的集合。
78. 如何知道是哪一個客戶端的機器正在請求你的Servlet?
ServletRequest類別可以找出客戶端機器的IP位址或是主機名稱。 getRemoteAddr()方法取得客戶端主機的IP位址,getRemoteHost()可以取得主機名稱。
79. HTTP回應的結構是怎麼樣的?
HTTP回應由三個部分組成:
狀態碼(Status Code):描述了回應的狀態。可以用來檢查是否成功的完成了請求。在請求失敗的情況下,狀態碼可用來找出失敗的原因。如果Servlet沒有回傳狀態碼,預設會回傳成功的狀態碼HttpServletResponse.SC_OK。
HTTP頭(HTTP Header):它們包含了更多關於回應的資訊。例如:頭部可以指定認為回應過期的過期日期,或是指定用來給使用者安全的傳輸實體內容的編碼格式。如何在Serlet中檢索HTTP的頭部看這裡。
主體(Body):它包含了回應的內容。它可以包含HTML程式碼,圖片,等等。主體是由傳送在HTTP訊息中緊接在頭部後面的資料位元組所組成的。
80. 什麼是cookie? session和cookie有什麼差別?
cookie是Web伺服器傳送給瀏覽器的一塊資訊。瀏覽器會在本機檔案中儲存為每個Web伺服器cookie。以後瀏覽器在給特定的Web伺服器發送請求的時候,同時會發送所有為該伺服器儲存的cookie。下面列出了session和cookie的區別:
無論客戶端瀏覽器做怎麼樣的設置,session都應該能正常運作。客戶端可以選擇停用cookie,但是,session仍然是能夠運作的,因為客戶端無法停用服務端的session。
在儲存的資料量方面session和cookies也是不一樣的。 session能夠儲存任意的Java對象,cookie只能儲存String類型的物件。
81. JSP請求是如何被處理的?
瀏覽器首先要請求一個以.jsp副檔名結尾的頁面,發起JSP請求,然後,Web伺服器讀取這個請求,使用JSP編譯器把JSP頁面轉換成一個Servlet類別。要注意的是,只有當第一次請求頁面或是JSP檔案改變的時候JSP檔案才會被編譯,然後伺服器呼叫servlet類,處理瀏覽器的請求。一旦請求執行結束,servlet會把回應傳送給客戶端。
82. 封裝的定義和好處有哪些?
封裝給物件提供了隱藏內部特性和行為的能力。物件提供一些能被其他物件存取的方法來改變它內部的資料。在Java當中,有3種修飾符:public,private和protected。每一種修飾符都賦予其他的位於同一個套件或不同套件下面物件了不同的存取權限。
下面列出了使用封裝的一些好處:
透過隱藏物件的屬性來保護物件內部的狀態。
提高了程式碼的可用性和可維護性,因為物件的行為可以被單獨的改變或是擴展。
禁止物件之間的不良互動提高模組化。
參考這個文件以取得更多關於封裝的細節和範例。
或:
一是用private把類別的細節與外界隔離起來,從而實現資料項和方法的隱藏,而要存取這些資料項和方法唯一的途徑就是透過類本身,類別才有資格呼叫它所擁有的資源(方法,資料項屬性等等)。所以第一個好處就是資料的安全性提高了。
二是透過隱藏隔離,只允許外部對類別做有限的訪問,開發者可以自由的改變類別的內部實現,而無需修改使用該類別的那些程式。只要那些在類別外部就能被呼叫的方法保持其外部特徵不變,內部程式碼就可以自由改變,各取所需,利於分工。
三就是提高了程式碼的重用性,封裝成工具類別以後能夠減少很多繁瑣的步驟。
83.抽象的定義?抽象和封裝的不同點?
抽像是把想法從具體的實例中分離出來的步驟,因此,要根據他們的功能而不是實作細節來創建類別。 Java支援建立只暴漏介面而不包含方法實作的抽象的類別。這種抽象技巧的主要目的是把類別的行為和實作細節分開。抽象和封裝是互補的概念。一方面,抽象關注對象的行為。另一方面,封裝關注對象行為的細節。一般是透過隱藏物件內部狀態資訊做到封裝,因此,封裝可以看成是用來提供抽象的一種策略。
相關推薦:java入門
以上是常見java重點面試題分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!