- Java程序員面試筆試寶典(第2版)
- 何昊等編著
- 3477字
- 2022-06-17 16:00:52
1.21 常見面試筆試真題
(1)下面程序的輸出結(jié)果是什么?


A.Finally
B.編譯失敗
C.代碼正常運(yùn)行但沒有任何輸出
D.運(yùn)行時拋出異常
答案:A。
(2)下面程序能否編譯通過?如果把ArithmeticException換成IOException呢?

答案:能編譯通過。由于ArithmeticException屬于運(yùn)行時異常,編譯器沒有強(qiáng)制對其進(jìn)行捕獲并處理,因此編譯可以通過。但是如果換成IOException后,由于IOException屬于檢查異常,編譯器強(qiáng)制去捕獲此類型的異常。因此如果不對異常進(jìn)行捕獲將會有編譯錯誤。
(3)異常包含下列哪些內(nèi)容?( )
A.程序中的語法錯誤
B.程序的編譯錯誤
C.程序執(zhí)行過程中遇到的事先沒有預(yù)料到的情況
D.程序事先定義好的可能出現(xiàn)的意外情況
答案:C。
(4)以下關(guān)于異常的說法正確的是( )
A.一旦出現(xiàn)異常,程序運(yùn)行就終止了
B.如果一個方法聲明將拋出某個異常,它就必須真的拋出那個異常
C.在catch子句中匹配異常是一種精確匹配
D.可能拋出系統(tǒng)異常的方法是不需要聲明異常的
答案:D。
(5)下面的代碼運(yùn)行的結(jié)果是什么?


A.Load B1 Load B2 Create B Load A Create A
B.Load B1 Load B2 Load A Create B Create A
C.Load B2 Load B1 Create B Create A Load A
D.Create B Create A Load B1 Load B2 Load A
答案:B。
(6)下面代碼的輸出結(jié)果是什么?

A.AC
B.ABC
C.C
D.BC
答案:A。類加載的初始化階段會執(zhí)行靜態(tài)代碼塊中的代碼。訪問B.c的時候需要加載父類A,因此會執(zhí)行父類的靜態(tài)代碼塊,首先輸出A然后才輸出B,因?yàn)轭怋不需要加載,所以不會輸出C。
(7)下面代碼的輸出結(jié)果是什么?


A.TestA
B.A Test A
C.A Test
D.Test
答案:A。使用ClassLoader加載類,不會導(dǎo)致類的初始化,也就是說不會調(diào)用clinit方法,因此類A的靜態(tài)代碼塊不會被執(zhí)行。而Class.forName()方法不僅會加載類,而且還會執(zhí)行類的初始化方法,因此會執(zhí)行靜態(tài)代碼塊。
(8)下列關(guān)于構(gòu)造方法的敘述中,錯誤的是( )
A.Java語言規(guī)定構(gòu)造方法名與類名必須相同
B.Java語言規(guī)定構(gòu)造方法沒有返回值,但不用void聲明
C.Java語言規(guī)定構(gòu)造方法不可以重載
D.Java語言規(guī)定構(gòu)造方法只能通過new自動調(diào)用
答案:C。可以定義多個構(gòu)造方法,只要不同的構(gòu)造方法有不同的參數(shù)即可。
(9)下列說法正確的有( )
A:class中的constructor不可省略
B:constructor必須與class同名,但方法不能與class同名
C:constructor在一個對象被new時執(zhí)行
D:一個class只能定義一個constructor
答案:C。
(10)Java中提供了哪兩種用于多態(tài)的機(jī)制?
答案:編譯時多態(tài)和運(yùn)行時多態(tài)。編譯時多態(tài)是通過方法重載實(shí)現(xiàn)的,運(yùn)行時多態(tài)是通過方法重寫(子類覆蓋父類方法)實(shí)現(xiàn)的。
(11)下面代碼的運(yùn)行結(jié)果是什么?


A.B.g() is called
B.編譯錯誤
C.運(yùn)行時錯誤
答案:B。因?yàn)锳中沒有方法g(),所以會有編譯錯誤。
(12)如下代碼輸出結(jié)果是什么?

答案:編譯錯誤。因?yàn)榉椒ú荒芤苑祷刂祦韰^(qū)分,雖然父類與子類中的方法有著不同的返回值,但是它們有著相同的方法簽名,所以無法區(qū)分。
(13)在接口中以下哪條定義是正確的?
A.void methoda();
B.public double methoda();
C.public final double methoda();
D.static void methoda(double d1);
E.protected void methoda(double d1);
F.int a;
G.int b=1;
答案:A、B、G。從上面的分析可知,接口中的方法只能用關(guān)鍵字public和abstract來修飾,因此選項(xiàng)C、E都是錯誤的。被static修飾的方法必須有方法的實(shí)現(xiàn),因此選項(xiàng)D是錯誤的。接口中的屬性默認(rèn)都為public static final,由于屬性被final修飾,它是常量,常量在定義的時候就必須初始化,因此F是錯誤的。
(14)下列正確的說法有( )
A.聲明抽象方法,大括號可有可無
B.聲明抽象方法不可寫出大括號
C.抽象方法有方法體
D.abstract可修飾屬性、方法和類
答案:B。抽象方法不能有方法體,同理也就不能有大括號。abstract只能用來修飾類與方法,不能用來修飾屬性。
(15)不能用來修飾外部interface的有( )
A.private
B.public
C.protected
D.static
答案:A、C、D。
(16)JDK中哪些類是不能被繼承的?
答案:從上面的介紹可以知道,不能繼承的類是那些用final關(guān)鍵字修飾的類。一般比較基本的類型為防止擴(kuò)展類無意間破壞原來方法的實(shí)現(xiàn)都應(yīng)該是final的,在JDK中,String、StringBuffer等都是基本類型。所以,String和StringBuffer等類似不能繼承的。
(17)下面程序的運(yùn)行結(jié)果是什么?

A.ABCD
B.ACDB
C.ACBD
D.不確定
答案:C。finally語句在任何情況下都會被執(zhí)行,當(dāng)前面有return語句時,首先執(zhí)行return的語句但不返回,然后執(zhí)行finally塊,最后才返回。
(18)下面代碼的輸出結(jié)果是什么?

A.0
B.1
C.2
D.編譯失敗
答案:D。在Java語言中,不能在成員函數(shù)內(nèi)部定義static變量。
(19)是否可以把一個數(shù)組修飾為volatile?
答案:在Java中可以用volatile來修飾數(shù)組,但是volatile只作用在這個數(shù)組的引用上,而不是整個數(shù)組的內(nèi)容。也就是說如果一個線程修改了這個數(shù)組的引用,這個修改會對其他所有線程可見。但是如果只是修改了數(shù)組的內(nèi)容,則無法保證這個修改對其他數(shù)組可見。
(20)下列表達(dá)式正確的是( )
A.byte b=128;
B.boolean flag=null;
C.float f=0.9239;
D.long a=2147483648L;
答案:D。A中byte能表示的取值范圍為[-128, 127],因此不能表示128。B中boolean的取值只能是true或false,不能為null。C中0.9239為double類型,需要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換。
(21)String是最基本的數(shù)據(jù)類型嗎?
答案:不是。基本數(shù)據(jù)類型包括byte、int、char、long、float、double、boolean和short。
(22)int和Integer有什么區(qū)別?
答案:Java語言提供兩種不同的類型:引用類型和原始類型(或內(nèi)置類型)。int是Java語言的原始數(shù)據(jù)類型,Integer是Java語言為int提供的封裝類。Java為每個原始類型提供了封裝類。
引用類型與原始類型的行為完全不同,并且它們具有不同的語義。而且,引用類型與原始類型具有不同的特征和用法。
(23)賦值語句float f=3.4是否正確?
答案:不正確。3.4默認(rèn)情況下是double類型,即雙精度浮點(diǎn)數(shù),將double類型數(shù)值賦值給float類型的變量,會造成精度損失,因此需要強(qiáng)制類型轉(zhuǎn)換,即將3.4轉(zhuǎn)換成float類型或者將3.4強(qiáng)制寫成float類型。所以,float f=(float)3.4或者float f=3.4F寫法都是可以的。
(24)下面代碼的輸出結(jié)果是什么?

答案:運(yùn)行結(jié)果為:

分析:在解答這道題前首先需要掌握下面幾個知識點(diǎn):
1)使用==比較的時候比較的是兩個對象的引用(也就是地址);
2)使用equals比較的是兩個Integer對象的數(shù)值;
3)Long對象的equals方法,它會首先檢查方法的參數(shù)是否也是Long類型,如果不是則直接返回false;
4)在Java中,Integer內(nèi)部維護(hù)了一個可以保存-128~127的緩存池。
5)如果比較的某一邊有操作表達(dá)式(例如a+b),那么比較的是具體數(shù)值。
根據(jù)以上的知識點(diǎn),可以得出下面的分析結(jié)果:
1)Integer c=3;內(nèi)部會調(diào)用Integer.valueOf(3)方法,這個方法的源碼如下:

從上面的代碼可以看出:
1)c和d都是用過valueOf方法獲取的且指向相同的對象,因此c==d為true。
2)e和f超出了緩存池緩存的范圍,因此會對e和f創(chuàng)建兩個不同的對象,它們的地址不相等,所以e==f為false。
3)對于c==(a+b),由于比較的一邊有表達(dá)式,比較的是具體數(shù)值,因此它的值為true。
4)對于g.equals(a+b),由于g的類型為Long,但是a+b的類型為Integer,因此equals方法會返回false。
5)對于i==j,當(dāng)使用new實(shí)例化對象的時候,它會在堆上創(chuàng)建新的對象并返回,i和j是兩個獨(dú)立的對象,它們有著不同的地址,因此比較結(jié)果為false。
(25)在Java中,哪個數(shù)據(jù)類型可以用來表示Money?
答案:可以用BigDecimal來表示Money,可能很多程序員都會有疑問,為什么不能使用float或者double呢?因?yàn)閒loat與double只是計(jì)算了一個近似值,無法表示非常精確的值。float與double類型數(shù)據(jù)的計(jì)算結(jié)果在不同的JVM上可能會有不同的實(shí)現(xiàn)。而要表示Money,就必須使用一個非常精確的值。需要注意的是,在使用BigDecimal時候,需要使用String類型的構(gòu)造方法,不能使用參數(shù)類型為double的構(gòu)造方法,因?yàn)閰?shù)類型為double時,BigDecimal內(nèi)部還是使用double作為類型進(jìn)行運(yùn)算的,從而會導(dǎo)致計(jì)算結(jié)果不精確。下面給出一個示例代碼:

程序運(yùn)行結(jié)果為:

(26)下例說法正確的是( )
A.call by value(值傳遞)不會改變實(shí)際參數(shù)的值
B.call by reference(引用傳遞)能改變實(shí)際參數(shù)
C.call by reference(引用傳遞)不能改變實(shí)際參數(shù)的地址
D.call by reference(引用傳遞)能改變實(shí)際參數(shù)的內(nèi)容
答案:A、C、D。見上面講解。
(27)設(shè)x=1,y=2,z=3,則表達(dá)式y(tǒng)+=z--/++x的值是( )
A.3
B.3.5
C.4
D.5
答案:A。
(28)i++是線程安全的嗎?
答案:因?yàn)閕++在底層實(shí)現(xiàn)的時候是通過下面三個步驟來實(shí)現(xiàn)的:

由此可見,i++不是一個原子操作,因此不是線程安全的,那么如何能實(shí)現(xiàn)i++的線程安全呢?這里重點(diǎn)介紹三種實(shí)現(xiàn)方式:使用原子變量、sychronized關(guān)鍵字和Lock鎖實(shí)現(xiàn)。下面通過示例代碼來說明它們的用法。
1)原子變量。AtomicInteger是一個提供原子操作的Integer類,通過線程安全的方式操作加減,示例代碼如下:

程序運(yùn)行結(jié)果為:

每次運(yùn)行可能會得到不同的答案,但是從運(yùn)行結(jié)果可以看出有5個線程同時運(yùn)行的時候,使用AtomicInteger方法每個線程輸出的值都不同,而且最大的值為4;而使用num1++,不同的線程可能會輸出相同的值,而且最大值也沒有到4。
2)sychronized關(guān)鍵字。使用sychronized來修飾getIncrease方法,確保在同一時刻只會有一個線程調(diào)用getIncrease方法,從而實(shí)現(xiàn)線程安全。

3)Lock。把++操作放在鎖內(nèi)從而實(shí)現(xiàn)++操作的線程安全。

(29)假設(shè)有以下代碼String s="hello";String t="hello";char c[]={'h','e','l','l','0'},下列選項(xiàng)中返回false語句的是( )
A.s.equals(t)
B.t.equals(c)
C.s==t
D.t.equals(new String("hello"))
答案:B。A與D顯然會返回true,選項(xiàng)C的返回值也為true。對于B,由于t與c分別為字符串類型和數(shù)組類型,因此返回值為false。
(30)下面程序的輸出結(jié)果是什么?

答案:true。"ab"+"c"在編譯器就被轉(zhuǎn)換為"abc",存放在常量區(qū),因此輸出結(jié)果為true。
(31)Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分是否重復(fù)呢?是用“==”還是equals()?它們有何差別?
答案:用equals()方法來區(qū)分是否重復(fù)。
- Practical Internet of Things Security
- RTC程序設(shè)計(jì):實(shí)時音視頻權(quán)威指南
- Git高手之路
- The Data Visualization Workshop
- Redis Essentials
- Asynchronous Android Programming(Second Edition)
- 代替VBA!用Python輕松實(shí)現(xiàn)Excel編程
- Red Hat Enterprise Linux Troubleshooting Guide
- Modern C++ Programming Cookbook
- 深度探索Go語言:對象模型與runtime的原理特性及應(yīng)用
- 奔跑吧 Linux內(nèi)核
- 量子計(jì)算機(jī)編程:從入門到實(shí)踐
- MySQL核心技術(shù)與最佳實(shí)踐
- Python GUI設(shè)計(jì)tkinter菜鳥編程(增強(qiáng)版)
- R統(tǒng)計(jì)應(yīng)用開發(fā)實(shí)戰(zhàn)