1. 程式人生 > >Java 30道經典筆試題

Java 30道經典筆試題

下面都是我自己的答案非官方,僅供參考,如果有疑問或錯誤請一定要提出來,大家一起進步啦~~~

  1. 下面哪些是Thread類的方法()
    A start() B run() C exit() D getPriority()

答案:ABD

  1. 下面關於java.lang.Exception類的說法正確的是()

A 繼承自Throwable B Serialable CD 不記得,反正不正確

答案:A

解析:Java異常的基類為java.lang.Throwable,java.lang.Error和java.lang.Exception繼承 Throwable,RuntimeException和其它的Exception等繼承Exception,具體的RuntimeException繼承RuntimeException。
擴充套件:錯誤和異常的區別(Error vs Exception)

1) java.lang.Error: Throwable的子類,用於標記嚴重錯誤。合理的應用程式不應該去try/catch這種錯誤。絕大多數的錯誤都是非正常的,就根本不該出現的。
java.lang.Exception: Throwable的子類,用於指示一種合理的程式想去catch的條件。即它僅僅是一種程式執行條件,而非嚴重錯誤,並且鼓勵使用者程式去catch它。

2) Error和RuntimeException 及其子類都是非檢查異常(unchecked exceptions),而所有其他的Exception類都是檢查異常(checked exceptions).
checked exceptions: 通常是從一個可以恢復的程式中丟擲來的,並且最好能夠從這種異常中使用程式恢復。比如FileNotFoundException, ParseException等。檢查異常發生在編譯階段,必須要使用try…catch(或者throws)否則編譯不通過。在Java的標準包java.lang java.util 和 java.net 中定義的異常都是非執行異常。
unchecked exceptions: 通常是如果一切正常的話本不該發生的異常,但是的確發生了。發生在執行期,具有不確定性,主要是由於程式的邏輯問題所引起的。比如ArrayIndexOutOfBoundException, ClassCastException等。從語言本身的角度講,程式不該去catch這類異常,雖然能夠從諸如RuntimeException這樣的異常中catch並恢復,但是並不鼓勵終端程式設計師這麼做,因為完全沒要必要。因為這類錯誤本身就是bug,應該被修復,出現此類錯誤時程式就應該立即停止執行。 因此,面對Errors和unchecked exceptions應該讓程式自動終止執行,程式設計師不該做諸如try/catch這樣的事情,而是應該查明原因,修改程式碼邏輯。

RuntimeException:RuntimeException體系包括錯誤的型別轉換、陣列越界訪問和試圖訪問空指標等等。

處理RuntimeException的原則是:如果出現 RuntimeException,那麼一定是程式設計師的錯誤。例如,可以通過檢查陣列下標和陣列邊界來避免陣列越界訪問異常。其他(IOException等等)checked異常一般是外部錯誤,例如試圖從檔案尾後讀取資料等,這並不是程式本身的錯誤,而是在應用環境中出現的外部錯誤。

  1. 下面程式的執行結果是()

String str1 = “hello”;
String str2 = “he” + new String(“llo”);
System.err.println(str1 == str2);
答案:false

解析:因為str2中的llo是新申請的記憶體塊,而==判斷的是物件的地址而非值,所以不一樣。如果是String str2 = str1,那麼就是true了。

  1. 下列說法正確的有()
    A. class中的constructor不可省略
    B. constructor必須與class同名,但方法不能與class同名
    C. constructor在一個物件被new時執行
    D.一個class只能定義一個constructor

答案:C

解析:這裡可能會有誤區,其實普通的類方法是可以和類名同名的,和構造方法唯一的區分就是,構造方法沒有返回值。

  1. 具體選項不記得,但用到的知識如下:

String []a = new String[10];
則:a[0]~a[9] = null
a.length = 10

如果是int []a = new int[10];
則:a[0]~a[9] = 0
a.length = 10

解析:引用型別與基本資料型別的預設值。

  1. 下面程式的執行結果:()
 public static void main(String args[]) {

        Thread t = new Thread() {

            public void run() {
                pong();
            }
        };

        t.run();
        System.out.print("ping");

    }

    static void pong() {

        System.out.print("pong");

    }

A pingpong B pongping C pingpong和pongping都有可能 D 都不輸出

答案:B

解析:這裡考的是Thread類中start()和run()方法的區別了。start()用來啟動一個執行緒,當呼叫start方法後,系統才會開啟一個新的執行緒,進而呼叫run()方法來執行任務,而單獨的呼叫run()就跟呼叫普通方法是一樣的,已經失去執行緒的特性了。因此在啟動一個執行緒的時候一定要使用start()而不是run()。

  1. 下列屬於關係型資料庫的是()

A. Oracle B MySql C IMS D MongoDB

答案:AB

解答:IMS(Information Management System )資料庫是IBM公司開發的兩種資料庫型別之一;
一種是關係資料庫,典型代表產品:DB2;
另一種則是層次資料庫,代表產品:IMS層次資料庫。
非關係型資料庫有MongoDB、memcachedb、Redis等。

  1. GC執行緒是否為守護執行緒?()
    答案:是
    解析:執行緒分為守護執行緒和非守護執行緒(即使用者執行緒)。
    只要當前JVM例項中尚存在任何一個非守護執行緒沒有結束,守護執行緒就全部工作;只有當最後一個非守護執行緒結束時,守護執行緒隨著JVM一同結束工作。
    守護執行緒最典型的應用就是 GC (垃圾回收器)

  2. volatile關鍵字是否能保證執行緒安全?()
    答案:不能
    解析:volatile關鍵字用在多執行緒同步中,可保證讀取的可見性,JVM只是保證從主記憶體載入到執行緒工作記憶體的值是最新的讀取值,而非cache中。但多個執行緒對
    volatile的寫操作,無法保證執行緒安全。例如假如執行緒1,執行緒2 在進行read,load 操作中,發現主記憶體中count的值都是5,那麼都會載入這個最新的值,線上程1堆count進行修改之後,會write到主記憶體中,主記憶體中的count變數就會變為6;執行緒2由於已經進行read,load操作,在進行運算之後,也會更新主記憶體count的變數值為6;導致兩個執行緒及時用volatile關鍵字修改之後,還是會存在併發的情況。

  3. 下列說法正確的是()
    A LinkedList繼承自List
    B AbstractSet繼承自Set
    C HashSet繼承自AbstractSet
    D WeakMap繼承自HashMap
    答案:AC
    解析:下面是一張下載的Java中的集合型別的繼承關係圖,一目瞭然。
    這裡寫圖片描述

這裡寫圖片描述

java.util.concurrent.ConcurrentHashMap繼承AbstractMap

擴充套件:Collections與Collection的區別:
1、Collection是集合類的一個頂級介面,其直接繼承介面有List與Set

Collection是個Java.util下的介面,它是各種集合結構的父介面。
Collection 層次結構中的根介面。Collection 表示一組物件,這些物件也稱為 collection的元素。一些 collection 允許有重複的元素,而另一些則不允許。一些 collection 是有序的,而另一些則是無序的。JDK 不提供此介面的任何直接 實現:它提供更具體的子介面(如 Set 和 List)實現。此介面通常用來傳遞 collection,並在需要最大普遍性的地方操作這些 collection。

2、Collections則是集合類的一個工具類/幫助類,其中提供了一系列靜態方法,用於對集合中元素進行排序、搜尋以及執行緒安全等各種操作。Collections.sort();
Collections是個java.util下的類,它包含有各種有關集合操作的靜態方法。
collections 此類完全由在 collection 上進行操作或返回 collection 的靜態方法組成。它包含在 collection 上操作的多型演算法,即“包裝器”,包裝器返回由指定 collection 支援的新 collection,以及少數其他內容。 如果為此類的方法所提供的 collection 或類物件為 null,則這些方法都會丟擲 NullPointerException。

WeakHashMap:
1. 以弱鍵 實現的基於雜湊表的 Map。在 WeakHashMap 中,當某個鍵不再正常使用時( 當除了自身有對key的引用外,此key沒有其他引用那麼此map會自動丟棄此值),將自動移除其條目。更精確地說,對於一個給定的鍵,其對映的存在並不阻止垃圾回收器對該鍵的丟棄,這就使該鍵成為可終止的,被終止,然後被回收。丟棄某個鍵時,其條目從對映中有效地移除
2. WeakHashMap 類的行為部分取決於垃圾回收器的動作。因為垃圾回收器在任何時候都可能丟棄鍵,WeakHashMap 就像是一個被悄悄移除條目的未知執行緒。特別地,即使對 WeakHashMap 例項進行同步,並且沒有呼叫任何賦值方法,在一段時間後 size 方法也可能返回較小的值,對於 isEmpty 方法,返回 false,然後返回true,對於給定的鍵,containsKey 方法返回 true 然後返回 false,對於給定的鍵,get 方法返回一個值,但接著返回 null,對於以前出現在對映中的鍵,put 方法返回 null,而 remove 方法返回 false,對於鍵 set、值 collection 和條目 set 進行的檢查,生成的元素數量越來越少。
3. WeakHashMap 中的每個鍵物件間接地儲存為一個弱引用的指示物件。因此,不管是在對映內還是在對映之外,只有在垃圾回收器清除某個鍵的弱引用之後,該鍵才會自動移除。

  1. 存在使i + 1 < i的數嗎()
    答案:存在
    解析:如果i為int型,那麼當i為int能表示的最大整數時,i+1就溢位變成負數了,此時不就小於i了嗎。
    擴充套件:存在使i > j || i <= j不成立的數嗎()
    答案:存在
    解析:比如Double.NaN或Float.NaN。
    NaN,是Not a Number的縮寫.
    NaN 用於處理計算中出現的錯誤情況,比如 0.0 除以 0.0 或者求負數的平方根.由上面的表中可以看出,對於單精度浮點數,NaN 表示為指數為 emax + 1 = 128(指數域全為 1),且尾數域不等於零的浮點數.IEEE 標準沒有要求具體的尾數域,所以 NaN 實際上不是一個,而是一族.不同的實現可以自由選擇尾數域的值來表達 NaN,比如 Java 中的常量 Float.NaN 的浮點數可能表達為 01111111110000000000000000000000,其中尾數域的第一位為 1,其餘均為 0(不計隱藏的一位),但這取決系統的硬體架構.Java 中甚至允許程式設計師自己構造具有特定位模式的 NaN 值(通過 Float.intBitsToFloat() 方法).比如,程式設計師可以利用這種定製的 NaN 值中的特定位模式來表達某些診斷資訊.

  2. 0.6332的資料型別是()
    A float B double C Float D Double
    答案:B
    解析:預設為double型,如果為float型需要加上f顯示說明,即0.6332f

  3. 下面哪個流類屬於面向字元的輸入流( )
    A BufferedWriter B FileInputStream C ObjectInputStream D InputStreamReader
    答案:D
    解析:Java的IO操作中有面向位元組(Byte)和麵向字元(Character)兩種方式。
    面向位元組的操作為以8位為單位對二進位制的資料進行操作,對資料不進行轉換,這些類都是InputStream和OutputStream的子類。
    面向字元的操作為以字元為單位對資料進行操作,在讀的時候將二進位制資料轉為字元,在寫的時候將字元轉為二進位制資料,這些類都是Reader和Writer的子類。
    總結:以InputStream(輸入)/OutputStream(輸出)為字尾的是位元組流;以Reader(輸入)/Writer(輸出)為字尾的是字元流。
    擴充套件:Java流類圖結構:
    這裡寫圖片描述

  4. Java介面的修飾符可以為()
    A private B protected C final D abstract
    答案:CD
    解析:介面很重要,為了說明情況,這裡稍微囉嗦點:
    (1)介面用於描述系統對外提供的所有服務,因此介面中的成員常量和方法都必須是公開(public)型別的,確保外部使用者能訪問它們;
    (2)介面僅僅描述系統能做什麼,但不指明如何去做,所以介面中的方法都是抽象(abstract)方法;
    (3)介面不涉及和任何具體例項相關的細節,因此介面沒有構造方法,不能被例項化,沒有例項變數,只有靜態(static)變數;
    (4)介面的中的變數是所有實現類共有的,既然共有,肯定是不變的東西,因為變化的東西也不能夠算共有。所以變數是不可變(final)型別,也就是常量了。
    (5) 介面中不可以定義變數?如果介面可以定義變數,但是介面中的方法又都是抽象的,在介面中無法通過行為來修改屬性。有的人會說了,沒有關係,可以通過 實現介面的物件的行為來修改介面中的屬性。這當然沒有問題,但是考慮這樣的情況。如果介面 A 中有一個public 訪問許可權的靜態變數 a。按照 Java 的語義,我們可以不通過實現介面的物件來訪問變數 a,通過 A.a = xxx; 就可以改變介面中的變數 a 的值了。正如抽象類中是可以這樣做的,那麼實現介面 A 的所有物件也都會自動擁有這一改變後的 a 的值了,也就是說一個地方改變了 a,所有這些物件中 a 的值也都跟著變了。這和抽象類有什麼區別呢,怎麼體現介面更高的抽象級別呢,怎麼體現介面提供的統一的協議呢,那還要介面這種抽象來做什麼呢?所以介面中 不能出現變數,如果有變數,就和介面提供的統一的抽象這種思想是抵觸的。所以介面中的屬性必然是常量,只能讀不能改,這樣才能為實現介面的物件提供一個統 一的屬性。

通俗的講,你認為是要變化的東西,就放在你自己的實現中,不能放在介面中去,介面只是對一類事物的屬性和行為更高層次的抽象。對修改關閉,對擴充套件(不同的實現 implements)開放,介面是對開閉原則的一種體現。
所以:
介面的方法預設是public abstract;
介面中不可以定義變數即只能定義常量(加上final修飾就會變成常量)。所以介面的屬性預設是public static final 常量,且必須賦初值。
注意:final和abstract不能同時出現。

  1. 不通過建構函式也能建立物件嗎()
    A 是 B 否
    答案:A
    解析:Java建立物件的幾種方式(重要):
    (1) 用new語句建立物件,這是最常見的建立物件的方法。
    (2) 運用反射手段,呼叫java.lang.Class或者java.lang.reflect.Constructor類的newInstance()例項方法。
    (3) 呼叫物件的clone()方法。
    (4) 運用反序列化手段,呼叫java.io.ObjectInputStream物件的 readObject()方法。
    (1)和(2)都會明確的顯式的呼叫建構函式 ;(3)是在記憶體上對已有物件的影印,所以不會呼叫建構函式 ;(4)是從檔案中還原類的物件,也不會呼叫建構函式。

  2. ArrayList list = new ArrayList(20);中的list擴充幾次()
    A 0 B 1 C 2 D 3
    答案:A
    解析:這裡有點迷惑人,大家都知道預設ArrayList的長度是10個,所以如果你要往list裡新增20個元素肯定要擴充一次(擴充為原來的1.5倍),但是這裡顯示指明瞭需要多少空間,所以就一次性為你分配這麼多空間,也就是不需要擴充了。

  3. 下面哪些是對稱加密演算法()
    A DES B AES C DSA D RSA
    答案:AB
    解析:常用的對稱加密演算法有:DES、3DES、RC2、RC4、AES
    常用的非對稱加密演算法有:RSA、DSA、ECC
    使用單向雜湊函式的加密演算法:MD5、SHA

18.新建一個流物件,下面哪個選項的程式碼是錯誤的?()
A)new BufferedWriter(new FileWriter(“a.txt”)); //BufferedWriter(Writer out) BufferedWriter(Writer out, int sz)
B)new BufferedReader(new FileInputStream(“a.dat”)); //BufferedReader(Reader in) BufferedReader(Reader in, int sz)
C)new GZIPOutputStream(new FileOutputStream(“a.zip”));//
D)new ObjectInputStream(new FileInputStream(“a.dat”));
答案:B
解析:Reader只能用FileReader進行例項化。

  1. 下面程式能正常執行嗎()
public class NULL {

    public static void haha(){
        System.out.println("haha");
    }
    public static void main(String[] args) {
        ((NULL)null).haha();
    }

}

答案:能正常執行
解析:輸出為haha,因為null值可以強制轉換為任何java類型別,(String)null也是合法的。但null強制轉換後是無效物件,其返回值還是為null,而static方法的呼叫是和類名繫結的,不借助物件進行訪問所以能正確輸出。反過來,沒有static修飾就只能用物件進行訪問,使用null呼叫物件肯定會報空指標錯了。這裡和C++很類似

  1. 下面程式的執行結果是什麼()
public class HelloB extends HelloA{
            public HelloB(){
                        System.out.println("HelloB");
            }

            {
                        System.out.println("I am  HelloB.class");
            }

            static{
                        System.out.println("Static HelloB ");
            }

            public static void main(String[] args) {
                        System.out.println("-------main start-------");
                        new HelloB();
                        System.out.println("-------main end-------");
            }
}
class HelloA{
            public HelloA(){
                        System.out.println("HelloA");
            }

            {
                        System.out.println("I am  HelloA.class");
            }

            static{
                        System.out.println("Static HelloA ");
            }
}

答案:
Static HelloA
Static HelloB
——-main start——-
I am HelloA.class
HelloA
I am HelloB.class
HelloB
——-main end——-

解析:說實話我覺得這題很好,考查靜態語句塊、構造語句塊(就是隻有大括號的那塊)以及建構函式的執行順序。
物件的初始化順序:
(1)類載入之後,按從上到下(從父類到子類)執行被static修飾的語句;
(2)當static語句執行完之後,再執行main方法;
(3)如果有語句new了自身的物件,將從上到下執行構造程式碼塊、構造器(兩者可以說繫結在一起)。

  1. getCustomerInfo()方法如下,try中可以捕獲三種類型的異常,如果在該方法執行中產生了一個IOException,將會輸出什麼結果()
  public void getCustomerInfo() {

        try {

            // do something that may cause an Exception
        } catch (java.io.FileNotFoundException ex) {

            System.out.print("FileNotFoundException!");

        } catch (java.io.IOException ex) {

            System.out.print("IOException!");

        } catch (java.lang.Exception ex) {

            System.out.print("Exception!");

        }

    }

A IOException!
B IOException!Exception!
C FileNotFoundException!IOException!
D FileNotFoundException!IOException!Exception!
答案:A
解析:考察多個catch語句塊的執行順序。當用多個catch語句時,catch語句塊在次序上有先後之分。從最前面的catch語句塊依次先後進行異常型別匹配,這樣如果父異常在子異常類之前,那麼首先匹配的將是父異常類,子異常類將不會獲得匹配的機會,也即子異常型別所在的catch語句塊將是不可到達的語句。所以,一般將父類異常類即Exception老大放在catch語句塊的最後一個。

  1. 下面程式碼的執行結果為:()
import java.io.*;
import java.util.*;

public class foo{

    public static void main (String[] args){

        String s;

        System.out.println("s=" + s);

    }

}

A 程式碼得到編譯,並輸出“s=”
B 程式碼得到編譯,並輸出“s=null”
C 由於String s沒有初始化,程式碼不能編譯通過
D 程式碼得到編譯,但捕獲到 NullPointException異常
答案:C
解析:開始以為會輸出null什麼的,執行後才發現Java中所有定義的基本型別或物件都必須初始化才能輸出值。

  1. System.out.println(“5” + 2);的輸出結果應該是()。
    A 52 B7 C2 D5
    答案:A
    解析:Java會自動將2轉換為字串。

  2. 指出下列程式執行的結果 ()

public class Example {

    String str = new String("good");

    char[] ch = { 'a', 'b', 'c' };

    public static void main(String args[]) {

        Example ex = new Example();

        ex.change(ex.str, ex.ch);

        System.out.print(ex.str + " and ");

        System.out.print(ex.ch);

    }

    public void change(String str, char ch[]) {

        str = "test ok";

        ch[0] = 'g';

    }
}

A、 good and abc
B、 good and gbc
C、 test ok and abc
D、 test ok and gbc
答案:B
解析:大家可能以為Java中String和陣列都是物件所以肯定是物件引用,然後就會選D,其實這是個很大的誤區:因為在java裡沒有引用傳遞,只有值傳遞
這個值指的是實參的地址的拷貝,得到這個拷貝地址後,你可以通過它修改這個地址的內容(引用不變),因為此時這個內容的地址和原地址是同一地址,
但是你不能改變這個地址本身使其重新引用其它的物件,也就是值傳遞,可能說的不是很清楚,下面給出一個完整的能說明情況的例子吧:

import java.util.Arrays;
public class ReferencePkValue {
            public static void main(String[] args) {
                        ReferencePkValue pkValue=new ReferencePkValue();
                        String string="String";
                        pkValue.changeString(string);
                        System.out.println("String 傳遞後的值:"+string);

                        StringBuffer buffer=new StringBuffer("StringBuffer");
                        pkValue.changeStringBuffer(buffer);
                        System.out.println("StringBuffer 傳遞後的值為:"+buffer);

                        Integer integer=99;
                        pkValue.changeInteger(integer);
                        System.out.println("Integer 傳遞後的值為:"+integer);

                        String[] strings={"value","strings"};
                        pkValue.changeArray(strings);
                        System.out.println("StringArray 傳遞後的值為:"+Arrays.asList(strings));
            }

            public void changeString(String str){
                        str=str+" change";
            }

            public void changeStringBuffer(StringBuffer buffer){
                        buffer.append(" change");
            }

            public void changeInteger(Integer i){
                        i=i+1;
            }

            public void changeArray(String[] chars){
                        chars[0]="change";
            }
}

執行結果:
String 傳遞後的值:String
StringBuffer 傳遞後的值為:StringBuffer change
Integer 傳遞後的值為:99
StringArray 傳遞後的值為:[change, strings]

結論:
(1)基本資料型別傳值,對形參的修改不會影響實參;
(2)引用型別傳引用,形參和實參指向同一個記憶體地址(同一個物件),所以對引數的修改會影響到實際的物件;
(3)String, Integer, Double等immutable的型別特殊處理,可以理解為傳值,最後的操作不會修改實參物件。

  1. 要從檔案”file.dat”中讀出第10個位元組到變數c中,下列哪個方法適合? ()
    A FileInputStream in=new FileInputStream(“file.dat”); in.skip(9); int c=in.read();
    B FileInputStream in=new FileInputStream(“file.dat”); in.skip(10); int c=in.read();
    C FileInputStream in=new FileInputStream(“file.dat”); int c=in.read();
    D RandomAccessFile in=new RandomAccessFile(“file.dat”); in.skip(9); int c=in.readByte();
    答案:A?D?
    解析:long skip(long n)作用是跳過n個位元組不讀,主要用在包裝流中的,因為一般流(如FileInputStream)只能順序一個一個的讀不能跳躍讀,但是包裝流可以用skip方法跳躍讀取。那麼什麼是包裝流呢?各種位元組節點流類,它們都只具有讀寫位元組內容的方法,以FileInputStream與FileOutputStream為例,它們只能在檔案中讀取或者向檔案中寫入位元組,在實際應用中我們往往需要在檔案中讀取或者寫入各種型別的資料,就必須先將其他型別的資料轉換成位元組陣列後寫入檔案,或者從檔案中讀取到的位元組陣列轉換成其他資料型別,想想都很麻煩!!因此想通過FileOutputStream將一個浮點小數寫入到檔案中或將一個整數寫入到檔案時是非常困難的。這時就需要包裝類DataInputStream/DataOutputStream,它提供了往各種輸入輸出流物件中讀入或寫入各種型別的資料的方法。
    DataInputStream/DataOutputStream並沒有對應到任何具體的流裝置,一定要給它傳遞一個對應具體流裝置的輸入或輸出流物件,完成類似 DataInputStream/DataOutputStream功能的類就是一個包裝類,也叫過濾流類或處理流類。它對InputOutStream/OutputStream流類進行了包裝,使程式設計人員使用起來更方便。其中DataInputStream包裝類的建構函式語法:public DataInputStream(InputStream in)。包裝類也可以包裝另外一個包裝類。

首先BC肯定 是錯的,那A正確嗎?按上面的解析應該也不對,但我試了下,發現A也是正確的,與網上解析的資料有些出入。
那麼D呢,RandomAccessFile是IO包的類,但是其自成一派,從Object直接繼承而來。可以對檔案進行讀取和寫入。支援檔案的隨機訪問,即可以隨機讀取檔案中的某個位置內容,這麼說RandomAccessFile肯定可以達到題目的要求,但是選項有些錯誤,比如RandomAccessFile的初始化是兩個引數而非一個引數,採用的跳躍讀取方法是skipBytes()而非skip(),即正確的寫法是:

RandomAccessFile in = new RandomAccessFile("file.dat", "r"); in.skipBytes(9); int c = in.readByte();

這樣也能讀到第十個位元組,也就是A和D都能讀到第十個位元組,那麼到底該選哪個呢?A和D有啥不同嗎?求大神解答~~~

  1. 下列哪種異常是檢查型異常,需要在編寫程式時宣告 ()
    A NullPointerException B ClassCastException C FileNotFoundException D IndexOutOfBoundsException
    答案:C
    解析:看第2題的解析。

  2. 下面的方法,當輸入為2的時候返回值是多少?()

public static int getValue(int i) {
        int result = 0;
        switch (i) {
        case 1:
            result = result + i;
        case 2:
            result = result + i * 2;
        case 3:
            result = result + i * 3;
        }
        return result;
    }

A 0 B 2 C 4 D 10
答案:D
解析:注意這裡case後面沒有加break,所以從case 2開始一直往下執行。

  1. 選項中哪一行程式碼可以替換題目中//add code here而不產生編譯錯誤?()
public abstract class MyClass {
    public int constInt = 5;
     //add code here
     public void method() {
     }
}

A public abstract void method(int a);
B constInt = constInt + 5;
C public int method();
D public abstract void anotherMethod() {}
答案:A
解析:考察抽象類的使用。
抽象類遵循的原則:
(1)abstract關鍵字只能修飾類和方法,不能修飾字段。
(2)抽象類不能被例項化(無法使用new關鍵字建立物件例項),只能被繼承。
(3)抽象類可以包含屬性,方法,構造方法,初始化塊,內部類,列舉類,和普通類一樣,普通方法一定要實現,變數可以初始化或不初始化但不能初始化後在抽象類中重新賦值或操作該變數(只能在子類中改變該變數)。
(4)抽象類中的抽象方法(加了abstract關鍵字的方法)不能實現。
(5)含有抽象方法的類必須定義成抽象類。

所以:
對於選項B中:變數可以初始化或不初始化但不能初始化後在抽象類中重新賦值或操作該變數(只能在子類中改變該變數)。
對於選項C:普通方法必須實現。應為:public int method(){}
對於選項D:抽象方法不能實現,在子類中實現。應為:public abstract void anotherMethod();

擴充套件:抽象類和介面的區別,做個總結吧:
(1)介面是公開的,裡面不能有私有的方法或變數,是用於讓別人使用的,而抽象類是可以有私有方法或私有變數的。

(2)abstract class 在 Java 語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。但是,一個類卻可以實現多個interface,實現多重繼承。介面還有標識(裡面沒有任何方法,如Remote介面)和資料共享(裡面的變數全是常量)的作用。
(3)在abstract class 中可以有自己的資料成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的資料成員(也就是必須是 static final的,不過在 interface中一般不定義資料成員),所有的成員方法預設都是 public abstract 型別的。
(4)abstract class和interface所反映出的設計理念不同。其實abstract class表示的是”is-a”關係,interface表示的是”has-a”關係。
(5)實現介面的一定要實現接口裡定義的所有方法,而實現抽象類可以有選擇地重寫需要用到的方法,一般的應用裡,最頂級的是介面,然後是抽象類實現介面,最後才到具體類實現。抽象類中可以有非抽象方法。介面中則不能有實現方法。
(6)介面中定義的變數預設是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。抽象類中的變數預設是 friendly 型,其值可以在子類中重新定義,也可以在子類中重新賦值。

  1. 閱讀Shape和Circle兩個類的定義。在序列化一個Circle的物件circle到檔案時,下面哪個欄位會被儲存到檔案中? ( )
class Shape {
       public String name;
}

class Circle extends Shape implements Serializable{

       private float radius;

       transient int color;

       public static String type = "Circle";

}

A name
B radius
C color
D type
答案:B
解析:transient修飾的變數不能序列化。序列化是針對例項,而static代表的是類。

30.下面是People和Child類的定義和構造方法,每個構造方法都輸出編號。在執行new Child(“mike”)的時候都有哪些構造方法被順序呼叫?請選擇輸出結果 ( )

class People {
    String name;

    public People() {
        System.out.print(1);
    }

    public People(String name) {
        System.out.print(2);
        this.name = name;
    }
}

class Child extends People {
    People father;

    public Child(String name) {
        System.out.print(3);
        this.name = name;
        father = new People(name + ":F");
    }

    public Child() {
        System.out.print(4);
    }

}

A312 B 32 C 432 D 132
答案:D
解析:考察的又是父類與子類的建構函式呼叫次序。在Java中,子類的構造過程中必須呼叫其父類的建構函式,是因為有繼承關係存在時,子類要把父類的內容繼承下來。但如果父類有多個建構函式時,該如何選擇呼叫呢?
第一個規則:子類的構造過程中,必須呼叫其父類的構造方法。一個類,如果我們不寫構造方法,那麼編譯器會幫我們加上一個預設的構造方法(就是沒有引數的構造方法),但是如果你自己寫了構造方法,那麼編譯器就不會給你添加了,所以有時候當你new一個子類物件的時候,肯定呼叫了子類的構造方法,但是如果在子類構造方法中我們並沒有顯示的呼叫基類的構造方法,如:super(); 這樣就會呼叫父類沒有引數的構造方法。
第二個規則:如果子類的構造方法中既沒有顯示的呼叫基類構造方法,而基類中又沒有無參的構造方法,則編譯出錯,所以,通常我們需要顯示的:super(引數列表),來呼叫父類有引數的建構函式,此時無參的建構函式就不會被呼叫。
總之,一句話:子類沒有顯示呼叫父類建構函式,不管子類建構函式是否帶引數都預設呼叫父類無參的建構函式,若父類沒有則編譯出錯。

最後,給大家出個思考題:下面程式的執行結果是什麼?

public class Dervied extends Base {

    private String name = "dervied";

    public Dervied() {
        tellName();
        printName();
    }

    public void tellName() {
        System.out.println("Dervied tell name: " + name);
    }

    public void printName() {
        System.out.println("Dervied print name: " + name);
    }

    public static void main(String[] args){

        new Dervied();   
    }
}

class Base {

    private String name = "base";

    public Base() {
        tellName();
        printName();
    }

    public void tellName() {
        System.out.println("Base tell name: " + name);
    }

    public void printName() {
        System.out.println("Base print name: " + name);
    }
}

執行結果為:
Dervied tell name: null
Dervied print name: null
Dervied tell name: dervied
Dervied print name: dervied

解析:首先new Dervied()時,先執行了Base的構造方法,繼而去執行了Base的tellName()與printName()這兩個方法,但是由於Dervied繼承了Base,所以執行的是子類也就是Dervied中的
tellName()與printName()的方法,但是由於此時Dervied的構造方法沒有執行,訪問不到name,所以此時的name是null。

相關推薦

Java 30經典試題

下面都是我自己的答案非官方,僅供參考,如果有疑問或錯誤請一定要提出來,大家一起進步啦~~~ 下面哪些是Thread類的方法() A start() B run() C exit() D getPriority()

網絡工程師30必備試題、答案

方便 怎麽 tom tar 解析 centos arrays 菜單 22端口 請簡單描述 IPv4 地址的分類和範圍? 答案: A 類 1 - 127 網+主+主+主 B 類 128 -191 網+網+主+主 C 類 192 -223 網+網+網+主 D 類

30經典試題

1.HashMap是如何擴容的? 當hashmap中的元素個數超過陣列大小*loadFactor時,就會進行陣列擴容,loadFactor的預設值為0.75,也就是說,預設情況下,陣列大小為16,那麼當hashmap中元素個數超過16*0.75=12的時候,

經典】《Java170面試試題全面含答案》涉及java/資料庫/Spring框架/JVM/資料結構演算法/設計模式相關

《Java170道面試筆試題全集》 -更新版-8.302018/4/7 日常修復2017/12/28 更新文章1、新增二級目錄2、對部分問題進行了補充9/24緊急修改以下問題(存在嚴重錯誤)問題3;完善問題10、11問題目錄:1、面向物件的特徵有哪些方面?2、訪問修飾符pub

大數乘法[JAVA實現]-經典試題

大數乘法 基本思想: 輸入字串,轉成char陣列,轉成int陣列。採用分治思想,每一位的相乘; * 公式:AB*CD = AC (BC+AD) BD * 然後從後到前滿十進位,順序如右(B

Java 經典試題

 文章轉載自:http://blog.csdn.net/hdwt/article/details/1294558         這些題目對我的筆試幫助很大,有需要的朋友都可以來看看,在筆試中能遇到的題目基本上下面都會出現,雖然形式不同,當考察的基本的知識點還是相同的。

Java經典試題

1.請看下列程式碼: class ClassA {} class ClassB extends ClassA {} class ClassC extends ClassA {} public class Test{  public static void main(Stri

Linux下C語言的幾經典試題

ref 使用 linu 學習資源 chan ima 什麽 img c語言 本篇文章整理了幾道Linux下C語言的經典面試題,相信對大家更好的理解Linux下的C語言會有很大的幫助,歡迎大家探討指正。 1、如果在Linux下使用GCC編譯器執行下列程序,輸出結果是什麽? 答

Linux大牛分享的7經典試題和秒收 offer 的技巧

開發技能 多個 ins 主從架構 統計 mongo 交換 到你 移動客戶端 筆者其實沒有想到去面試,只是在智聯上更新了一下簡歷,就陸陸續續接到很多獵頭的郵件和電話,閑話少說,下面就分享給大家Linuxer的面試經歷: 首先,獵頭或者公司人資會把公司的介紹及崗位要求發到你郵箱

JAVA多線程試題

技術 答案 args disable this arraylist null mit tex 一、題目內容 二、我的答案   利用了線程池、考慮了超時處理、不知道這樣寫是否還有其他問題,或者更好更優的解決方案? import java.util.;import java.

sql經典試題

詳見此處   表結構 1.自行新增測試資料 2.查詢平均成績大於60分的同學的學號和平均成績; SELECT t1.sid 學生編號, AVG( t2.number ) 平均分 FROM student t1 LEFT JOIN score t2 O

產品經理經典試題

第一個問題 作為產品經理,競品分析是一項基本能力。請對比百度外賣、美團外賣、餓了麼的評價功能,做一次競品分析,說出優勢和劣勢。 1、評價功能包括兩個方向:使用者評價和檢視店鋪評價,關係如下圖: 根據上圖關係顯示,將對使用者評價進行詳細分析,檢視店鋪評價輔助分析 2、使用者評價體系流程對比

Bat大廠出場率最高的50經典試題!iOS開發者們不要錯過咯!

小編整理了一個PDF文件的面試題,由於平臺不能上傳檔案,需要答案可以加小編的QQ交流群656315826,在裡面獲取文件,也歡迎招聘者,找工作的來,提供一個更大的平臺(需要的朋友可以獲取,希望可以幫助到大家) ⽬錄: 基礎 1、如何令⾃⼰所寫的物件具有拷⻉功能? 2、說說你理解

No.25 經典試題(二):模擬實現strcpy,strcat,strcmp,strstr,memcpy

直接上程式碼: 1. //模擬實現strcpy #include <stdio.h> #include <assert.h> char* my_strcpy(char* dest, const char* src) { char* ret = dest ;

No.23 經典試題(一):用巨集來計算偏移量,判斷大小端(聯合體法,指標法)

寫一個巨集,計算結構體中某變數相對於首地址的偏移,並給出說明 判斷大小端 程式碼1: //寫一個巨集,計算結構體中某變數相對於首地址的偏移,並給出說明 //定義的這個巨集將結構體裡邊的變數的地址取出後再強轉成char型,然後進行相減。 //注意:&s ==

MySql_34經典Sql試題

from copyright update ges mysql 直接 info 1.2 class MySql_34道經典Sql試題 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/xi

30Redis面試題

什麼是Redis?簡述它的優缺點? A Redis本質上是一個Key-Value型別的記憶體資料庫,很像memcached,整個資料庫統統載入在記憶體當中進行操作,定期通過非同步操作把資料庫資料flush到硬碟上進行儲存。 因為是純記憶體操作,Redis的效能非常出色,每秒可以處理超過

81經典Vue試題總結

寫在前面 參考答案在看雲平臺釋出,如果大家想閱讀參考答案,可直接購買, 或通過 申請看雲平臺賬號,然後新增微信 hanxuming888 來免費開通閱讀許可權, 或者留言回覆賬號,開通許可權! 本文件基於vue-cli技術棧總結了 vue-cli工程 vue.js核心

30Redis面試題,面試官能問的都被我找到了

1、什麼是Redis?簡述它的優缺點? Redis本質上是一個Key-Value型別的記憶體資料庫,很像memcached,整個資料庫統統載入在記憶體當中進行操作,定期通過非同步操作把資料庫資料flush到硬碟上進行儲存。 因為是純記憶體操作,Redis的效能非常出色,每

分享30Redis面試題,面試官能問到的我都找到了

1、什麼是Redis?簡述它的優缺點? Redis本質上是一個Key-Value型別的記憶體資料庫,很像memcached,整個資料庫統統載入在記憶體當中進行操作,定期通過非同步操作把資料庫資料flush到硬碟上進行儲存。 因為是純記憶體操作,Redis的效能非常出色