1. 程式人生 > >一、技術面試題

一、技術面試題

1、寫幾個執行緒安全類,不安全的,支援排序的類名?

【參考答案】

Ø 執行緒安全類:Vector 、Hashtable、Stack。

Ø 執行緒不安全的類:ArrayList、Linkedlist、HashSet、TreeSet、HashMap、TreeMap等。

Ø 支援排序的類有HashSet、LinkedHashSet、TreeSet等(Set介面下的實現都支援排序)

【分析】

此題主要考查集合框架的知識。在集合框架中Collection介面為集合的根型別,提供集合操作的常用API方法,該介面下派生出兩個子介面,一個是不支援排序的List介面,一個是有自身排序的Set介面,所以回答排序與不排序分別從兩介面的實現中在作答。執行緒安全上來說,Vector類比同屬於List介面的ArrayList要早,是一個執行緒安全的類,在JDK1.2以後才推出一個非同步的ArrayList類,比Vector類效率高。同理Stack繼承自Vector也執行緒安全的類,另外在在Map介面的實現在Hashtable也是個執行緒安全的類。

 

2、哪幾個方法可以實現一個執行緒?

【參考答案】

一是繼承Thread ,重寫Thread 類的方法 run方法;另種是實現runnable 介面並實現 run方法。

【分析】

考查執行緒的基本實現,很多公司喜歡考查這方面知識,另外補充一下關於執行緒的run方法,在多執行緒API中啟動一個執行緒是呼叫start()方法,執行緒進入就緒狀態。

 

3、STOP()和SUSPEND()不推薦使用的原因?

【參考答案】

stop()是因為它不安全。它會解除由執行緒獲取的所有鎖定,當在一個執行緒物件上呼叫stop()方法時,這個執行緒物件所執行的執行緒就會立即停止,假如一個執行緒正在執行:synchronizedvoid { x = 3; y = 4;} 由於方法是同步的,多個執行緒訪問時總能保證x,y被同時賦值,而如果一個執行緒正在執行到x = 3;時,被呼叫了 stop()方法,即使在同步塊中,它也乾脆地stop了,這樣就產生了不完整的殘廢資料。而多執行緒程式設計中最最基礎的條件要保證資料的完整性,所以請忘記執行緒的stop方法,以後我們再也不要說“停止執行緒”了。而且如果物件處於一種不連貫狀態,那麼其他執行緒能在那種狀態下檢查和修改它們。

suspend()方法容易發生死鎖。呼叫suspend()的時候,目標執行緒會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何執行緒都不能訪問鎖定的資源,除非被"掛起"的執行緒恢復執行。對任何執行緒來說,如果它們想恢復目標執行緒,同時又試圖使用任何一個鎖定的資源,就 會造成死鎖。所以不應該使用suspend(),而應在自己的Thread類中置入一個標誌,指出執行緒應該活動還是掛起。若標誌指出執行緒應該掛起,便用 wait()命其進入等待狀態。若標誌指出執行緒應當恢復,則用一個notify()重新啟動執行緒。

【分析】

 

4、"=="和equals方法有什麼區別?

【參考答案】

==操作符專門用來比較兩個變數的值是否相等,也就是用於比較變數所對應的記憶體中所儲存的數值是否相同,要比較兩個基本型別的資料或兩個引用變數是否相等,只能用==操作符。

如果一個變數指向的資料是物件型別的,那麼,這時候涉及了兩塊記憶體,物件本身佔用一塊記憶體(堆記憶體),變數也佔用一塊記憶體,例如Objet obj = new Object();變數obj是一個記憶體,new Object()是另一個記憶體,此時,變數obj所對應的記憶體中儲存的數值就是物件佔用的那塊記憶體的首地址。對於指向物件型別的變數,如果要比較兩個變數是否指向同一個物件,即要看這兩個變數所對應的記憶體中的數值是否相等,這時候就需要用==操作符進行比較。

equals方法是用於比較兩個獨立物件的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個物件是獨立的。例如,對於下面的程式碼:

String a=new String("foo");

String b=new String("foo");

兩條new語句建立了兩個物件,然後用a,b這兩個變數分別指向了其中一個物件,這是兩個不同的物件,它們的首地址是不同的,即a和b中儲存的數值是不相同的,所以,表示式a==b將返回false,而這兩個物件中的內容是相同的,所以,表示式a.equals(b)將返回true。

在實際開發中,我們經常要比較傳遞進行來的字串內容是否等,例如,String input = …;input.equals(“quit”),如果一個類沒有自己定義equals方法,那麼它將繼承Object類的equals方法,Object類的equals方法的實現程式碼如下:

boolean equals(Object o){

return this==o;

}

這說明,如果一個類沒有自己定義equals方法,它預設的equals方法(從Object 類繼承的)就是使用==操作符,也是在比較兩個變數指向的物件是否是同一物件,這時候使用equals和使用==會得到同樣的結果,如果比較的是兩個獨立的物件則總返回false。如果你編寫的類希望能夠比較該類建立的兩個例項物件的內容是否相同,那麼你必須覆蓋equals方法,由你自己寫程式碼來決定在什麼情況即可認為兩個物件的內容是相同的。

 

5、靜態變數和例項變數的區別?

【參考答案】

在語法定義上的區別:靜態變數前要加static關鍵字,而例項變數前則不加。

在程式執行時的區別:例項變數屬於某個物件的屬性,必須建立了例項物件,其中的例項變數才會被分配空間,才能使用這個例項變數。靜態變數不屬於某個例項物件,而是屬於類,所以也稱為類變數,只要程式載入了類的位元組碼,不用建立任何例項物件,靜態變數就會被分配空間,靜態變數就可以被使用了。總之,例項變數必須建立物件後才可以通過這個物件來使用,靜態變數則可以直接使用類名來引用。

例如,對於下面的程式,無論建立多少個例項物件,永遠都只分配了一個staticVar變數,並且每建立一個例項物件,這個staticVar就會加1;但是,每建立一個例項物件,就會分配一個instanceVar,即可能分配多個instanceVar,並且每個instanceVar的值都只自加了1次。

publicclass VariantTest

{

     public static int staticVar = 0;

     public int instanceVar = 0;

     public VariantTest()

     {

         staticVar++;

         instanceVar++;

         System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar);

     }

}

備註:這個解答除了說清楚兩者的區別外,最後還用一個具體的應用例子來說明兩者的差異,體現了自己有很好的解說問題和設計案例的能力,思維敏捷,超過一般程式設計師,有寫作能力!

 

6、構造器的名能不能和類的名字相同?

【參考答案】

構造器的名稱必須與類名相同。

【分析】

 構造器或建構函式(有些書這樣叫)主要用來對類的成員變數進行初始化,當類建立例項時呼叫。

 

7、在一個主方法類可不可以呼叫一個非靜態的方法?

【參考答案】

可以呼叫。因為Java的主方法(main)方法本身也是static型別方法,一個static型別方法,發起對另一個static方法的呼叫沒有問題。

【分析】

靜態方法可以呼叫其它的靜態方法,但是不能呼叫非靜態方法,這個好比Java中的類變數與例項變數的關係。類變數是被所有類成員共享,而例項變數只被該例項共享,

 

8、一個類中可不可以有2個公共的方法?

【參考答案】

可以。Java中對公共方法的個數沒有約束,但是對公共的類有約束,一個Java原始檔中只能定義一個public型別的類。   

 

9、GC是什麼,為什麼要使用它?

【參考答案】

GC是垃圾收集的意思(GabageCollection),記憶體處理是程式設計人員容易出現問題的地方,忘記或者錯誤的記憶體回收會導致程式或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測物件是否超過作用域,從而達到自動回收記憶體的目的,Java語言沒有提供釋放已分配記憶體的顯示操作方法。

【分析】

 

10、說一下垃圾回收的原理,可以直接從記憶體中回收嗎?

【參考答案】

      Java語言中一個顯著的特點就是引入了垃圾回收機制,使c++程式設計師最頭疼的記憶體管理的問題迎刃而解,它使得Java程式設計師在編寫程式的時候不再需要考慮記憶體管理。垃圾回收可以有效的防止記憶體洩露,有效的使用可以使用的記憶體。垃圾回收器通常是作為一個單獨的低級別的執行緒執行,不可預知的情況下對記憶體堆中已經死亡的或者長時間沒有使用的物件進行清除和回收,程式設計師不能實時的呼叫垃圾回收器對某個物件或所有物件進行垃圾回收,因為Java語言規範並不保證GC一定會執行。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

【分析】

 

11、Java的異常有哪幾種,有什麼區別?

【參考答案】

兩大類,一般異常和執行時異常。一般異常,這些異常是在定義方法時宣告丟擲的,這些異常必需用try catch丟擲,或throws處理,如果不處理,程式將編譯失敗。比如:IOException、FileNotFoundException、SQLException等。

執行時異常是程式執行時可能報出的異常。可以用try catch抓取,也可以不做任何處理。例如:NullPointerException 異常就是一種比較常見的執行時異常。

【分析】

 

12、switch語句能否作用在byte上,能否作用在long上,能否作用在String上?

【參考答案】

在switch(表示式)中,括號表示式只能是一個整數表示式或者列舉常量(更大字型),整數表示式可以是int基本型別或Integer包裝型別,由於,byte,short,char都可以隱含轉換為int,所以,這些型別以及這些型別的包裝型別也是可以的。顯然,long和String型別都不符合switch的語法規定,並且不能被隱式轉換成int型別,所以,它們不能作用於swtich語句中。

 

13、Integer與int的區別?

【參考答案】

 int是java提供的8種原始資料型別之一,另外Java為每個原始型別提供了封裝類,Integer是java為int提供的封裝類。int的預設值為0,而Integer的預設值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況。

 

14、JavaReflection是什麼?

【參考答案】   

JAVA反射,Reflection是Java 程式開發語言的特徵之一,它允許執行中的 Java 程式對自身進行檢查,或者說"自審",並能直接操作程式的內部屬性。

【分析】

 

15、寫幾個java.lang.Object類中的方法名稱。

【參考答案】

主要有equals()、toString()、getClass()、hashCode()、clone()、notify()、wait()、notify()方法。

【分析】

這種題能記多少個就說多少個,不一定要求你所有的都記住,但是要理解其中部分重要方法的含義和作用。

 

16、&和&&的區別?

【參考答案】

&和&&都可以用作邏輯與的運算子,表示邏輯與(and),當運算子兩邊的表示式的結果都為true時,整個運算結果才為true,否則,只要有一方為false,則結果為false。

&&還具有短路的功能,即如果第一個表示式為false,則不再計算第二個表示式。

&還可以用作位運算子,當&操作符兩邊的表示式不是boolean型別時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來獲取該整數的最低4個bit位。

【分析】

 先說分別說兩者的作用,再說出&&和&各自的不同之處。

 

17、陣列有沒有length()這個方法,String有沒有length()這個方法。

【參考答案】

陣列沒有length()方法,但有length屬性
    String有length()方法。

【分析】

考查平時使用陣列和字串的一些細節,一般在使用

 

18、Strings=new String(“xyz”)建立了幾個物件

【參考答案】

2個string物件,一個是=null的s,一個是=“xyz”的string

   兩個或一個”xyz”對應一個物件,這個物件放在字串常量緩衝區,常量”xyz”不管出現多少遍,都是緩衝區中的那一個。New String每寫一遍,就建立一個新的物件,它一句那個常量”xyz”物件的內容來創建出一個新String物件。如果以前就用過’xyz’,這句代表就不會建立”xyz”自己了,直接從緩衝區拿。

【分析】

 

19、能不能自己寫個類,也叫java.lang.String?

可以,但在應用的時候,需要用自己的類載入器去載入,否則,系統的類載入器永遠只是去載入jre.jar包中的那個java.lang.String。由於在tomcat的web應用程式中,都是由webapp自己的類載入器先自己載入WEB-INF/classess目錄中的類,然後才委託上級的類載入器載入,如果我們在tomcat的web應用程式中寫一個java.lang.String,這時候Servlet程式載入的就是我們自己寫的java.lang.String,但是這麼幹就會出很多潛在的問題,原來所有用了java.lang.String類的都將出現問題。

雖然java提供了endorsed技術,可以覆蓋jdk中的某些類,具體做法是….。但是,能夠被覆蓋的類是有限制範圍,反正不包括java.lang這樣的包中的類。

 

例如,執行下面的程式:

package java.lang;

public class String {

    /**

     * @param args

     */

    publicstatic void main(String[] args) {

        // TODOAuto-generated method stub

        System.out.println("string");

    }

 

}

報告的錯誤如下:

java.lang.NoSuchMethodError: main

Exception in thread "main"

這是因為載入了jre自帶的java.lang.String,而該類中沒有main方法。

 

20、你對面向物件思想的理解?

【參考答案】

面向物件程式設計(Object-Oriented Programming)簡稱OOP技術,是開發計算機應用程式的一種新方法、新思想。過去的面向過程程式設計中常常會導致所有的程式碼都包含在幾個模組中,使程式難以閱讀和維護,在做一些修改時常常牽一動百,使以後的開發和維護難以為繼。而使用OOP技術,使用許多程式碼模組,每個模組都只提供特定的功能,它們是彼此獨立的,可以增加程式碼重用的機率,更加有利於軟體的開發、維護和升級。另外OOP的三大核心特性:繼承、封裝、多型的特性,使得在面對象編上能夠設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴充套件,而且成本較低,所以這一程式設計思想是目前一種應用最為普遍的軟體設計思想。

【分析】

 

21、最常見的runtime exception執行時異常?

【參考答案】

ClassCastException(型別轉換異常)、NumberFormatException(格式化異常)、            

ArrayIndexOutOfBoundsException(陣列越界異常)、ArithmeticException(算術異常)、  NullPointerException(空指標異常)等等

【分析】

這道題主要考查大家平時在專案開發過程中經常遇到的一些異常型別資訊,通過這些異常來考查大家的專案經驗與專案排錯能力。

 

22、用JDBC來實現訪問資料庫記錄可以採用下面的幾個步驟:

【參考答案】

1、 通過驅動器管理器獲取連線介面(Connection)。

2、 獲得Statement或它的子類。

3、 指定Statement中的引數。

4、 通過Statement傳送SQL語句。

5、 檢查並處理返回的結果。

6、 關閉Statement。

7、 關閉連線接

【分析】

 

23、Error和 exception的區別與聯絡?

【參考答案】

error 表示恢復不是不可能,但很困難的情況下的一種嚴重問題。比如說記憶體溢,網路故障等,不可能指望程式能處理的一類錯誤。 
    Exception 表示一種由程式設計或實現問題,像我們常說的異常處理,就是屬於這類,一般程式可以捕獲和處理這些異常。

【分析】

這道題的難點在Error很多時候由於我們無法重現這種Error導致很多同學甚至不知道Error到底是什麼,所以很容易把題目中的兩種錯誤劃上等號。

24、String s = "Hello";s = s + " world!";這兩行程式碼執行後,原始的String物件中的內容到底變了沒有?

【參考答案】
    沒有。因為String被設計成不可變(immutable)類,所以它的所有物件都是不可變物件。在這段程式碼中,s原先指向一個String物件,內容是 "Hello",然後我們對s進行了+操作,那麼s所指向的那個物件是否發生了改變呢?答案是沒有。這時,s不指向原來那個物件了,而指向了另一個 String物件,內容為"Hello world!",原來那個物件還存在於記憶體之中,只是s這個引用變數不再指向它了。
通過上面的說明,我們很容易匯出另一個結論,如果經常對字串進行各種各樣的修改,或者說,不可預見的修改,那麼使用String來代表字串的話會引起很大的記憶體開銷。因為 String物件建立之後不能再改變,所以對於每一個不同的字串,都需要一個String物件來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字串都要生成一個新的物件。並且,這兩種類的物件轉換十分容易。
同時,我們還可以知道,如果要使用內容相同的字串,不必每次都new一個String。例如我們要在構造器中對一個名叫s的String引用變數進行初始化,把它設定為初始值,應當這樣做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
後者每次都會呼叫構造器,生成新物件,效能低下且記憶體開銷大,並且沒有意義,因為String物件不可改變,所以對於內容相同的字串,只要一個String物件來表示就可以了。也就說,多次呼叫上面的構造器建立多個物件,他們的String型別屬性s都指向同一個物件。
上面的結論還基於這樣一個事實:對於字串常量,如果內容相同,Java認為它們代表同一個String物件。而用關鍵字new呼叫構造器,總是會建立一個新的物件,無論內容是否相同。
至於為什麼要把String類設計成不可變類,是它的用途決定的。其實不只String,很多Java標準類庫中的類都是不可變的。在開發一個系統的時候,我們有時候也需要設計不可變類,來傳遞一組相關的值,這也是面向物件思想的體現。不可變類有一些優點,比如因為它的物件是隻讀的,所以多執行緒併發訪問也不會有任何問題。當然也有一些缺點,比如每個不同的狀態都要一個物件來代表,可能會造成效能上的問題。所以Java標準類庫還提供了一個可變版本,即 StringBuffer。

 

25、Jdk1.5的新特性?

【參考答案】

    JDK1.5的一個重要主題就是通過新增一些特性來簡化開發,這些特性主要包括:泛型、ForEach迴圈、自動裝包/拆包、列舉、可變引數、靜態匯入這些。

【分析】

 

26、面向物件的特徵有哪些方面?

【參考答案】

面向物件的程式語言有封裝、繼承 、多型等3個主要的特徵。

u  封裝

封裝是保證軟體部件具有優良的模組性的基礎,封裝的目標就是要實現軟體部件的“高內聚、低耦合”,防止程式相互依賴性而帶來的變動影響。面向物件的封裝就是把描述一個物件的屬性和行為的程式碼封裝在一個“模組”中,也就是一個類中,屬性用變數定義,行為用方法進行定義,方法可以直接訪問同一個物件中的屬性。

u  繼承

在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,並可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類資料和方法的機制,這是類之間的一種關係,提高了軟體的可重用性和可擴充套件性。

u  多型

多型是指程式中定義的引用變數所指向的具體型別和通過該引用變數發出的方法呼叫在程式設計時並不確定,而是在程式執行期間才確定,即一個引用變數倒底會指向哪個類的例項物件,該引用變數發出的方法呼叫到底是哪個類中實現的方法,必須在由程式執行期間才能決定。因為在程式執行時才確定具體的類,這樣,不用修改源程式程式碼,就可以讓引用變數繫結到各種不同的類實現上,從而導致該引用呼叫的具體方法隨之改變,即不修改程式程式碼就可以改變程式執行時所繫結的具體程式碼,讓程式可以選擇多個執行狀態,這就是多型性。多型性增強了軟體的靈活性和擴充套件性。 

 

27、JVM工作原理?

執行jvm 字元碼的工作是由直譯器來完成的。解釋執行過程分三步進行: 

  程式碼的裝入、程式碼的校驗、和程式碼的執行。 

裝入程式碼的工作由“類裝載器classloader”完成。類裝載器負責裝入執行一個程式需要的所有程式碼,這也包括程式程式碼中的類所繼承的類和被呼叫的類。當類裝載器裝入一個類時,該類被放在自己的名字空間中。除了通過符號引用自己名字空間以外的類,類之間沒有其他辦法可以影響其他類。在本臺計算機的所有類都在同一地址空間中,而所有從外部引進的類,都有一個自己獨立的名字空間。這使得本地類通過共享相同的名字空間獲得較高的執行效率,同時又保證它們與從外部引進的類不會相互影響。當裝入了執行程式需要的所有類後,直譯器便可確定整個可執行程式的記憶體佈局。直譯器為符號引用與特定的地址空間建立對應關係及查詢表。通過在這一階段確定程式碼的內佈局,java很好地解決了由超類改變而使子類   

崩潰的問題,同時也防止了程式碼的非法訪問。隨後,被裝入的程式碼由位元組碼校驗器進行檢查。校驗器可以發現運算元棧益處、非法資料型別轉化等多種錯誤。通過校驗後,程式碼便開始執行了。  

Java位元組碼的執行有兩種方式:  

1)即時編譯方式:直譯器先將位元組編譯成機器碼,然後再執行該機器碼。 

2)解釋執行方式:直譯器通過每次解釋並執行一小段程式碼來完成java位元組。  

  碼程式的所有操作。  

 

28、說說Java中的記憶體分配?

 Java把記憶體分成兩種,一種叫做棧記憶體,一種叫做堆記憶體  

在函式中定義的一些基本型別的變數和物件的引用變數都是在函式的棧記憶體中分配。當在一段程式碼塊中定義一個變數時,java就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,java會自動釋放掉為該變數分配的記憶體空間,該記憶體空間可以立刻被另作它用。   

      堆記憶體用於存放由new建立的物件和陣列。在堆中分配的記憶體,由java虛擬機器自動垃圾回收器來管理。在堆中產生了一個數組或者物件後,還可以在棧中定義一個特殊的變數,這個變數的取值等於陣列或者物件在堆記憶體中的首地址,在棧中的這個特殊的變數就變成了陣列或者物件的引用變數,以後就可以在程式中使用棧記憶體中的引用變數來訪問堆中的陣列或者物件,引用變數相當於為陣列或者物件起的一個別名,或者代號。 

引用變數是普通變數,定義時在棧中分配記憶體,引用變數在程式執行到作用域外釋放。而陣列&物件本身在堆中分配,即使程式執行到使用new產生陣列和物件的語句所在地程式碼塊之外,陣列和物件本身佔用的堆記憶體也不會被釋放,陣列和物件在沒有引用變數指向它的時候,才變成垃圾,不能再被使用,但是仍然佔著記憶體,在隨後的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較佔記憶體的主要原因。但是在寫程式的時候,可以人為的控制。

29、final,finally, finalize的區別。

【參考答案】

final 用於宣告屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

內部類要訪問區域性變數,區域性變數必須定義成final型別,例如,一段程式碼……

finally是異常處理語句結構的一部分,表示總是執行。

finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。JVM不保證此方法總被呼叫

 

30、Extends和Implement的不同?

【參考答案】

extends是繼承父類,只要那個類不是宣告為final或者那個類定義為abstract的就能繼承,JAVA中不支援多重繼承,但是可以用介面來實現,這樣就要用到implements,繼承只能繼承一個類,但implements可以實現多個介面,用逗號分開就行了 

比如 class A extends B implements C,D,E

 

31、抽象類是否可以沒有抽象方法?為什麼?

【參考答案】

可以在java中用abstract關鍵字來修飾一個類時,這個類叫做抽象類。

抽象類中不一定要包含abstract方法,但一個類中包含了abstract方法,則這個類必須宣告為abstract類。

 

32、靜態的多型和動態的多型的區別?

【參考答案】

靜態的多型: 即為過載 ;方法名相同,引數個數或型別不相同。(overloading)

動態的多型: 即為重寫;子類覆蓋父類的方法,將子類的例項傳與父類的引用呼叫的是子類的方法  實現介面的例項傳與介面的引用呼叫的實現類的方法。

 

33、說出一些常用的類,包,介面,請各舉5個?

【參考答案】

常用的類:String、StringBuffer、 Integer 、Vector、ArrayList、Hashtable等

常用的包:java.lang   java.io java.util 、java.sql 。

常用的介面:集合中的List、Set、 Map介面;與Servlet API相關的Servlet介面、HttpServletRequest,HttpServletResponse,HttpSession介面等。

 

34、Collections和Collection的區別【天晟科技】

【參考答案】

Collection是個java.util下的介面,它是各種集合結構的父介面,定義了集合物件的基本操作方法。Collections是個java.util下的工具類,它包含有各種有關集合操作的靜態方法,主要是針對集合類的一個幫助類或者叫包裝類,它提供一系列對各種集合的搜尋,排序,執行緒安全化等操作方法。

 

35、Class.forName的作用?為什麼要用?

【參考答案】

按引數中指定的字串形式的類名去搜索並載入相應的類,如果該類位元組碼已經被載入過,則返回代表該位元組碼的Class例項物件,否則,按類載入器的委託機制去搜索和載入該類,如果所有的類載入器都無法載入到該類,則丟擲ClassNotFoundException。載入完這個Class位元組碼後,接著就可以使用Class位元組碼的newInstance方法去建立該類的例項物件了。有時候,我們程式中所有使用的具體類名在設計時(即開發時)無法確定,只有程式執行時才能確定,這時候就需要使用Class.forName去動態載入該類,這個類名通常是在配置檔案中配置的,例如,spring的ioc中每次依賴注入的具體類就是這樣配置的,jdbc的驅動類名通常也是通過配置檔案來配置的,以便在產品交付使用後不用修改源程式就可以更換驅動類名。

 

36、Socket如何獲取本地ip地址?

【參考答案】

 InetAddress類提供的API來訪問。InetAddress.getLocalAddress()

【分析】

 

37、介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承具體類

【參考答案】

介面可以繼承介面。抽象類可以實現(implements)介面,抽象類是否可繼承具體類。抽象類中可以有靜態的main方法。

備註:只要明白了介面和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支援,如果不提供的話,有什麼理由嗎?如果你沒有道理不提供,那答案就是肯定的了。

 只有記住抽象類與普通類的唯一區別就是不能建立例項物件和允許有abstract方法。

 

38、用最有效率的方法算出2乘以8等於幾?

【參考答案】

 2 << 3

【分析】

因為將一個數左移n位,就相當於乘以了2的n次方,那麼,一個數乘以8只要將其左移3位即可,而位運算cpu直接支援的,效率最高,所以2乘以8等於幾的最效率的方法是2<< 3。

39、char型變數中能不能存貯一箇中文漢字?為什麼?

【參考答案】

char型變數是用來儲存Unicode編碼的字元的,unicode編碼字符集中包含了漢字,所以,char型變數中當然可以儲存漢字啦。不過,如果某個特殊的漢字沒有被包含在unicode編碼字符集中,那麼,這個char型變數中就不能儲存這個特殊漢字。補充說明:unicode編碼佔用兩個位元組,所以,char型別的變數也是佔用兩個位元組。

 

40、寫clone()方法時,通常都有一行程式碼,是什麼?

【參考答案】

clone 有預設行為,super.clone();因為首先要把父類中的成員複製到位,然後才是複製自己的成員。

 

41、說說常用集合類有哪些?有哪些方法?

【參考答案】

通常我們使用的集合類都大多是由List、Set、Map這三類介面派生出來的類,例如:

ArrayList、Vector、LinkedList、Stack、TreeSet、Hashtable、HashMap等

集合類的大部分方法都是由Collection介面定義的,主要包括有:

add(E e)、remove(Object e)、addAll(),remove()、contains(Object obj)、clear()等

 

42、請說出作用域public,private,protected,以及不寫時的區別?

【參考答案】

 這四個作用域的可見範圍如下表所示。

說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。

 

作用域    同一類  同一package 子孫類 其他package

public    √     √          √       √

protected  √     √          √      ×

friendly   √     √          ×      ×

private    √     ×          ×      ×

備註:只要記住了有4種訪問許可權,4個訪問範圍,然後將全選和範圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。

 

43、構造器Constructor是否可被override? 

【參考答案】

構造器Constructor不能被繼承,因此不能重寫Override,但可以被過載Overload。

 

44、是否可以從一個static方法內部發出對非static方法的呼叫? 

【參考答案】

不可以。因為非static方法是要與物件關聯在一起的,必須建立一個物件後,才可以在該物件上進行方法呼叫,而static方法呼叫時不需要建立物件,可以直接呼叫。

 

45、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

【參考答案】

 Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對應,例如,ceil的英文意義是天花板,該方法就表示向上取整,所以,Math.ceil(11.3)的結果為12,Math.ceil(-11.3)的結果是-11;floor的英文意義是地板,該方法就表示向下取整,所以,Math.floor(11.6)的結果為11,Math.floor(-11.6)的結果是-12;最難掌握的是round方法,它表示“四捨五入”,演算法為Math.floor(x+0.5),即將原來的數字加上0.5後再向下取整,所以,Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11。

 

46、abstractclass(抽象類)和interface(介面)有什麼區別?   

【參考答案】

含有abstract修飾符的class即為抽象類,abstract 類不能建立的例項物件。含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義為abstract型別。

介面(interface)可以說成是抽象類的一種特例,介面中的所有方法都必須是抽象的。介面中的方法定義預設為public abstract型別,介面中的成員變數型別預設為public staticfinal。

下面比較一下兩者的語法區別:

1.抽象類可以有構造方法,介面中不能有構造方法。

2.抽象類中可以有普通成員變數,介面中沒有普通成員變數

3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。

4. 抽象類中的抽象方法的訪問型別可以是public,protected和(預設型別,雖然

eclipse下不報錯,但應該也不行),但介面中的抽象方法只能是public型別的,並且預設即為public abstract型別。

5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法

6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是public static final型別,並且預設即為public staticfinal型別。

7. 一個類可以實現多個介面,但只能繼承一個抽象類。

    下面接著再說說兩者在應用上的區別:

【分析】

這道題的思路是先從總體解釋抽象類和介面的基本概念,然後再比較兩者的語法細節,最後再說兩者的應用區別。比較兩者語法細節區別的條理是:先從一個類中的構造方法、普通成員變數和方法(包括抽象方法),靜態變數和方法,繼承性等方面來回答。

 

47、Collection框架中實現比較要實現什麼介面?

【參考答案】

Comparable、Comparator介面

 

48、是否可以繼承String類?

【參考答案】

 String類是final類故不可以繼承。

 

49、String和StringBuffer的區別

【參考答案】

JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字串,即包含多個字元的字元資料。String類表示內容不可改變的字串。而StringBuffer類表示內容可以被修改的字串。當你知道字元資料要改變的時候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動態構造字元資料。另外,String實現了equals方法,newString(“abc”).equals(newString(“abc”)的結果為true,而StringBuffer沒有實現equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結果為false。

String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer物件儲存進Java集合類中時會出現問題。

 

50、StringBuffer與StringBuilder的區別

【參考答案】

    StringBuffer和StringBuilder類都表示內容可以被修改的字串,StringBuilder是執行緒不安全的,執行效率高,如果一個字串變數是在方法裡面定義,這種情況只可能有一個執行緒訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類裡面定義成員變數,並且這個類的例項物件會在多執行緒環境下使用,那麼最好用StringBuffer。

 

51、try{}裡有一個return語句,那麼緊跟在這個try後的finally {}裡的code會不會被執行,什麼時候被執行,在return前還是後? 【杭州天眼科技】

【參考答案】

答案是在return之前。

【分析】

程式程式碼的執行結果:

public  classTest {

    public staticvoid main(String[] args) {

        // TODOAuto-generated method stub

        System.out.println(newTest().test());;

    }

    static inttest()

    {

        int x =1;

        try

        {

            returnx;

        }

        finally

        {

            ++x;

        }

    }

   

}

 

---------執行結果 ---------

1

執行結果是1,為什麼呢?主函式呼叫子函式並得到結果的過程,好比主函式準備一個空罐子,當子函式要返回結果時,先把結果放在罐子裡,然後再將程式邏輯返回到主函式。所謂返回,就是子函式說,我不運行了,你主函式繼續執行吧,這沒什麼結果可言,結果是在說這話之前放進罐子裡的。

下面的程式程式碼輸出的結果是多少?

public class  smallT

{

    public static void  main(String args[])

    {

        smallT t  = new smallT();

        int  b =  t.get();

        System.out.println(b);

    }

   

    public int  get()

    {

        try

        {

            return 1 ;

        }

        finally

        {

            return 2 ;

        }

    }

}

 

返回的結果是2。

我可以通過下面一個例子程式來幫助我解釋這個答案,從下面例子的執行結果中可以發現,try中的return語句呼叫的函式先於finally中呼叫的函式執行,也就是說return語句先執行,finally語句後執行,所以,返回的結果是2。Return並不是讓函式馬上返回,而是return語句執行後,將把返回結果放置進函式棧中,此時函式並不是馬上返回,它要執行finally語句後才真正開始返回。

在講解答案時可以用下面的程式來幫助分析:

public  classTest {

    /**

     * @param args add by zxx ,Dec 9, 2008

     */

    publicstatic void main(String[] args) {

        // TODOAuto-generated method stub

        System.out.println(newTest().test());;

    }

 

    int test()

    {

        try

        {

            returnfunc1();

        }

        finally

        {

            returnfunc2();

        }

    }

   

    int func1()

    {

        System.out.println("func1");

        return1;

    }

    int func2()

    {

        System.out.println("func2");

        return2;

    }  

}

-----------執行結果-----------------

func1

func2

2

結論:finally中的程式碼比return 和break語句後執行。

 

52、Java中的異常處理機制的簡單原理和應用。

【參考答案】

異常是指java程式執行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等資訊,可以用一個物件來表示,Java使用面向物件的方式來處理異常,它把程式中發生的每個異常也都分別封裝到一個物件來表示的,該物件中包含有異常的資訊。

Java對異常進行了分類,不同型別的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個子類:Error和Exception,Error 表示應用程式本身無法克服和恢復的一種嚴重問題,程式只有死的份了,例如,說記憶體溢位和執行緒死鎖等系統問題。Exception表示程式還能夠克服和恢復的問題,其中又分為系統異常和普通異常,系統異常是軟體本身缺陷所導致的問題,也就是軟體開發人員考慮不周所導致的問題,軟體使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟體系統繼續執行或者讓軟體死掉,例如,陣列指令碼越界(ArrayIndexOutOfBoundsException),空指標異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是執行環境的變化或異常所導致的問題,是使用者能夠克服的問題,例如,網路斷線,硬碟空間不夠,發生這樣的異常後,程式不應該死掉。

java為系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try..catch處理或用throws宣告繼續拋給上層呼叫方法處理,所以普通異常也稱為checked異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用try..catch處理或用throws宣告,所以系統異常也稱為unchecked異常。

 

53、多執行緒有幾種實現方法?同步有幾種實現方法?

【參考答案】

多執行緒有兩種實現方法,分別是繼承Thread類與實現Runnable介面。

同步的實現方面有兩種,分別是synchronized,wait與notify 。

a.        wait():使一個執行緒處於等待狀態,並且釋放所持有的物件的lock。

b.        sleep():使一個正在執行的執行緒處於睡眠狀態,是一個靜態方法,呼叫此方法要捕捉InterruptedException異常。

c.        notify():喚醒一個處於等待狀態的執行緒,注意的是在呼叫此方法的時候,並不能確切的喚醒某一個等待狀態的執行緒,而是由JVM確定喚醒哪個執行緒,而且不是按優先順序。

d.        allnotity():喚醒所有處入等待狀態的執行緒,注意並不是給所有喚醒執行緒一個物件的鎖,而是讓它們競爭。

54、啟動一個執行緒是用run()還是start()?

【參考答案】

啟動一個執行緒是呼叫start()方法,使執行緒就緒狀態,以後可以被排程為執行狀態,一個執行緒必須關聯一些具體的執行程式碼,run()方法是該執行緒所關聯的執行程式碼。

 

55、內部類可以引用外部類的成員嗎?有沒有什麼限制?

【參考答案】

完全可以。如果不是靜態內部類,那沒有什麼限制!

如果你把靜態巢狀類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變數,而只能訪問外部類中的靜態成員。

 

56、List和 Map 區別?

【參考答案】

一個是儲存單列資料的集合,另一個是儲存鍵和值這樣的雙列資料的集合,List中儲存的資料是有順序,並且允許重複;Map中儲存的資料是沒有順序的,其鍵是不能重複的,它的值是可以有重複的。

 

57、ArrayList和Vector的區別

【參考答案】

這兩個類都實現了List介面(List介面繼承了Collection介面),他們都是有序集合,即儲存在這兩個集合中的元素的位置都是有順序的,相當於一種動態的陣列,我們以後可以按位置索引號取出某個元素,並且其中的資料是允許重複的。

接著說ArrayList與Vector的區別,這主要包括兩個方面:
1、同步性:

    Vector是執行緒安全的,也就是說是它的方法之間是執行緒同步的,而ArrayList是執行緒序不安全的,它的方法之間是執行緒不同步的。如果只有一個執行緒會訪問到集合,那最好是使用ArrayList,因為它不考慮執行緒安全,效率會高些;如果有多個執行緒會訪問到集合,那最好是使用Vector,因為不需要我們自己再去考慮和編寫執行緒安全的程式碼。

備註:對於Vector&ArrayList、Hashtable&HashMap,要記住執行緒安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是執行緒安全的,ArrayList與HashMap是java2時才提供的,它們是執行緒不安全的。
2、資料增長:

    ArrayList與Vector都有一個初始的容量大小,當儲存進它們裡面的元素的個數超過了容量時,就需要增加ArrayList與Vector的儲存空間,每次要增加儲存空間時,不是隻增加一個儲存單元,而是增加多個儲存單元,每次增加的儲存單元的個數在記憶體空間利用與程式效率之間要取得一定的平衡。Vector預設增長為原來兩倍,而ArrayList的增長為原來的1.5倍。ArrayList與Vector都可以設定初始的空間大小,Vector還可以設定增長的空間大小,而ArrayList沒有提供設定增長空間的方法。

 

58、heap和stack有什麼區別。

【參考答案】

Java的記憶體分為兩類,一類是棧記憶體,一類是堆記憶體。棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變數也將隨之釋放。

堆是與棧作用不同的記憶體,一般用於存放不放在當前方法棧中的那些資料,例如,使用

new建立的物件都放在堆裡,所以,它不會隨方法的結束而消失。方法中的區域性變數使

用final修飾後,放在堆中,而不是棧中。

 

59、Java類實現序列化的方法(二種)?如在collection框架中實現排序,要實現什麼樣的介面 

【參考答案】

  java.io.Serializable介面或實現Externalizable 介面。

  Collection框架中實現比較要實現Comparable 介面或 Comparator 介面,並實現比較方法

 

60、JAVA實現向資料庫新增一列。

【參考答案】

Connection con = null;

ResultSet rs = null;

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

  Stringurl="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_name";

  Connection con =DriverManager.getConnection(url,"","");

StateManager  sm =con.createStateMent();

String sql = "alter table student  add  age  int;";

rs = sm.excute(sql);

 

61、什麼是Java序列化,如何實現java序列化?或者請解釋Serializable介面的作用。

【參考答案】

序列化就是一種用來處理物件流的機制,所謂物件流也就是將物件的內容進行流化。可以對流化後的物件進行讀寫操作,也可將流化後的物件傳輸於網路之間。序列化是為了解決在對物件流進行讀寫操作時所引發的問題。

序列化的實現:將需要被序列化的類實現Serializable介面,該介面沒有需要實現的方法,implements Serializable只是為了標註該物件是可被序列化的,然後使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(物件流)物件,使用ObjectOutputStream物件的writeObject(Object obj)方法就可以將引數為obj的物件寫出,那麼在另一端,通過ObjectInputStream物件的readObject(Object obj)獲取到位元組流資料後,要將位元組流轉換成原物件,這叫反序列化,以便將資料儲存在檔案中或在網路傳輸。

Serializable 介面描述啟用其序列化功能,未實現此介面的類將無法使其任何狀態序列化或反序列化。Serializable 介面沒有方法或欄位,僅用於標識可序列化的語義,標識實現了該介面的物件屬性可被序列化。

 

62、Java中有幾種型別的流?JDK為每種型別的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?

【參考答案】

    位元組流,字元流兩種型別流。位元組流繼承於InputStream、 OutputStream;字元流繼承於ReaderWriter。 其它與IO操作相關的類都是派生至上述4個抽象類,如位元組相關的:FileInputStream、FileOutputStream類;字元相關的:BufferedReader、BufferedWriter類

 

63、用JDBC如何呼叫儲存過程

【參考答案】

通過JDBC元件中的CallableStatement介面實現呼叫儲存過程。

核心程式碼如下:

            Class.forName("com.mysql.jdbc.Driver");

            Connection conn=

DriverManager.getConnection("jdbc:mysql:///test","root","root");

            CallableStatementcstmt = cn.prepareCall("{call insert_Student(?,?,?)}");

            cstmt.registerOutParameter(3,Types.INTEGER);

            cstmt.setString(1,"wangwu");

            cstmt.setInt(2,25);

            cstmt.execute();

 

64、JAVA事件有哪些模式?

【參考答案】

1、事件直接驅動模式。它的特點是直接而且快,是必須經常使用的,主要適合於迅速處理前臺的命令,通常就是我們說的command(命令)模式。。2.監控式事件模式。主要藉助第三者來監控和觸發事件,就是通常我們說的觀察者模式。特點是:有一個觀察者置身事外在定期獨立執行著,我們將我們要監聽的事件向這個觀察者註冊,這樣觀察者就代替我們來監聽這個事件,應用客戶端通過觀察者來獲得事件狀況。

【分析】

 

65、JVM載入class檔案原理?

【參考答案】

所謂裝載就是尋找一個類或是一個介面的二進位制形式並用該二進位制形式來構造代表這個類或是這個介面的class物件的過程.
    在Java中,類裝載器把一個類裝入Java虛擬機器中,要經過三個步驟來完成:裝載、連結和初始化,其中連結又可以分成校驗、準備、解析
    裝載:查詢和匯入類或介面的二進位制資料; 
    連結:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的; 
    校驗:檢查匯入類或介面的二進位制資料的正確性; 
    準備:給類的靜態變數分配並初始化儲存空間; 
    解析:將符號引用轉成直接引用; 
    初始化:啟用類的靜態變數的初始化Java程式碼和靜態Java程式碼塊
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java執行時系統元件。它負責在執行時查詢和裝入類檔案的類
一個Java應用程式使用兩種型別的類裝載器:根裝載器(bootstrap)和使用者定義的裝載器(user-defined)。
根裝載器以某種預設的方式將類裝入,包括那些Java API的類。在執行期間一個Java程式能安裝使用者自己定義的類裝載器。根裝載器是虛擬機器固有的一部分,而使用者定義的類裝載器則不是,它是用Java語言寫的,被編譯成class檔案之後然後再被裝入到虛擬機器,並像其它的任何物件一樣可以被例項化。 Java類裝載器的體系結構如下所示:
            Bootstrap(根裝載器)
                |
            Extension (擴充套件裝載器)
                 |
               System
                 |
              UserDefine1
                 /           \
UserDefine2  UserDefine3
                            | 
                                UserDefine4
Java的類裝載模型是一種代理(delegation)模型。當JVM 要求類裝載器CL(ClassLoader)裝載一個類時,CL首先將這個類裝載請求轉發給他的父裝載器。只有當父裝載器沒有裝載並無法裝載這個類時,CL才獲得裝載這個類的機會。這樣, 所有類裝載器的代理關係構成了一種樹狀的關係。樹的根是類的根裝載器(bootstrap ClassLoader) , 在JVM 中它以"null"表示。除根裝載器以外的類裝載器有且僅有一個父裝載器。在建立一個裝載器時, 如果沒有顯式地給出父裝載器, 那麼JVM將預設系統裝載器為其父裝載器
下面針對各種類裝載器分別進行詳細的說明:
  根(Bootstrap) 裝載器:該裝載器沒有父裝載器,它是JVM實現的一部分,從sun.boot.class.path裝載執行時庫的核心程式碼。 
  擴充套件(Extension) 裝載器:繼承的父裝載器為根裝載器,不像根裝載器可能與執行時的作業系統有關,這個類裝載器是用純Java程式碼實現的,它從java.ext.dirs (擴充套件目錄)中裝載程式碼。 
  系統(System or Application) 裝載器:裝載器為擴充套件裝載器,我們都知道在安裝JDK的時候要設定環境變數(CLASSPATH ),這個類裝載器就是從java.class.path(CLASSPATH 環境變數)中裝載程式碼的,它也是用純Java程式碼實現的,同時還是使用者自定義類裝載器的預設父裝載器。 
 小應用程式(Applet) 裝載器: 裝載器為系統裝載器,它從使用者指定的網路上的特定目錄裝載小應用程式程式碼。

 

66、SOCKET中有幾中連線方式,各有什麼區別?

【參考答案】

Sockets有兩種主要的操作方式:面向連線(TCP/IP)的和無連線(UDP)的。無連線的操作使用資料報協議,無連線的操作是快速的和