“面试不败计划”:面试题基础二
11、switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?
**答:**在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。從Java 5開始,Java中引入了枚舉類型,expr也可以是enum類型,從Java 7開始,expr還可以是字符串(String),但是長整型(long)在目前所有的版本中都是不可以的。
12、用最有效率的方法計算2乘以8?
答: 2 << 3(左移3位相當于乘以2的3次方,右移3位相當于除以2的3次方)。
**補充:**我們?yōu)榫帉懙念愔貙慼ashCode方法時,可能會看到如下所示的代碼,其實我們不太理解為什么要使用這樣的乘法運算來產(chǎn)生哈希碼(散列碼),而且為什么這個數(shù)是個素數(shù),為什么通常選擇31這個數(shù)?前兩個問題的答案你可以自己百度一下,選擇31是因為可以用移位和減法運算來代替乘法,從而得到更好的性能。說到這里你可能已經(jīng)想到了:31 * num 等價于(num << 5) - num,左移5位相當于乘以2的5次方再減去自身就相當于乘以31,現(xiàn)在的VM都能自動完成這個優(yōu)化。
public class PhoneNumber {private int areaCode;private String prefix;private String lineNumber;@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + areaCode;result = prime * result+ ((lineNumber == null) ? 0 : lineNumber.hashCode());result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;PhoneNumber other = (PhoneNumber) obj;if (areaCode != other.areaCode)return false;if (lineNumber == null) {if (other.lineNumber != null)return false;} else if (!lineNumber.equals(other.lineNumber))return false;if (prefix == null) {if (other.prefix != null)return false;} else if (!prefix.equals(other.prefix))return false;return true;}}13、數(shù)組有沒有l(wèi)ength()方法?String有沒有l(wèi)ength()方法?
**答:**數(shù)組沒有l(wèi)ength()方法,有l(wèi)ength 的屬性。String 有l(wèi)ength()方法。JavaScript中,獲得字符串的長度是通過length屬性得到的,這一點容易和Java混淆。
14、在Java中,如何跳出當前的多重嵌套循環(huán)?
**答:**在最外層循環(huán)前加一個標記如A,然后用break A;可以跳出多重循環(huán)。(Java中支持帶標簽的break和continue語句,作用有點類似于C和C++中的goto語句,但是就像要避免使用goto一樣,應該避免使用帶標簽的break和continue,因為它不會讓你的程序變得更優(yōu)雅,很多時候甚至有相反的作用,所以這種語法其實不知道更好)
15、構造器(constructor)是否可被重寫(override)?
**答:**構造器不能被繼承,因此不能被重寫,但可以被重載。
16、兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
**答:**不對,如果兩個對象x和y滿足x.equals(y) == true,它們的哈希碼(hash code)應當相同。Java對于eqauls方法和hashCode方法是這樣規(guī)定的:(1)如果兩個對象相同(equals方法返回true),那么它們的hashCode值一定要相同;(2)如果兩個對象的hashCode相同,它們并不一定相同。當然,你未必要按照要求去做,但是如果你違背了上述原則就會發(fā)現(xiàn)在使用容器時,相同的對象可以出現(xiàn)在Set集合中,同時增加新元素的效率會大大下降(對于使用哈希存儲的系統(tǒng),如果哈希碼頻繁的沖突將會造成存取性能急劇下降)。
**補充:**關于equals和hashCode方法,很多Java程序都知道,但很多人也就是僅僅知道而已,在Joshua Bloch的大作《Effective Java》(很多軟件公司,《Effective Java》、《Java編程思想》以及《重構:改善既有代碼質量》是Java程序員必看書籍,如果你還沒看過,那就趕緊去亞馬遜買一本吧)中是這樣介紹equals方法的:首先equals方法必須滿足自反性(x.equals(x)必須返回true)、對稱性(x.equals(y)返回true時,y.equals(x)也必須返回true)、傳遞性(x.equals(y)和y.equals(z)都返回true時,x.equals(z)也必須返回true)和一致性(當x和y引用的對象信息沒有被修改時,多次調(diào)用x.equals(y)應該得到同樣的返回值),而且對于任何非null值的引用x,x.equals(null)必須返回false。實現(xiàn)高質量的equals方法的訣竅包括:
17、是否可以繼承String類?
答: String 類是final類,不可以被繼承。
**補充:**繼承String本身就是一個錯誤的行為,對String類型最好的重用方式是關聯(lián)關系(Has-A)和依賴關系(Use-A)而不是繼承關系(Is-A)。
18、當一個對象被當作參數(shù)傳遞到一個方法后,此方法可改變這個對象的屬性,并可返回變化后的結果,那么這里到底是值傳遞還是引用傳遞?
**答:**是值傳遞。Java語言的方法調(diào)用只支持參數(shù)的值傳遞。當一個對象實例作為一個參數(shù)被傳遞到方法中時,參數(shù)的值就是對該對象的引用。對象的屬性可以在被調(diào)用過程中被改變,但對對象引用的改變是不會影響到調(diào)用者的。C++和C#中可以通過傳引用或傳輸出參數(shù)來改變傳入的參數(shù)的值。在C#中可以編寫如下所示的代碼,但是在Java中卻做不到。
using System;namespace CS01 {class Program {public static void swap(ref int x, ref int y) {int temp = x;x = y;y = temp;}public static void Main (string[] args) {int a = 5, b = 10;swap (ref a, ref b);// a = 10, b = 5;Console.WriteLine ("a = {0}, b = {1}", a, b);}} }說明: Java中沒有傳引用實在是非常的不方便,這一點在Java 8中仍然沒有得到改進,正是如此在Java編寫的代碼中才會出現(xiàn)大量的Wrapper類(將需要通過方法調(diào)用修改的引用置于一個Wrapper類中,再將Wrapper對象傳入方法),這樣的做法只會讓代碼變得臃腫,尤其是讓從C和C++轉型為Java程序員的開發(fā)者無法容忍。
19、String和StringBuilder、StringBuffer的區(qū)別?
答: Java平臺提供了兩種類型的字符串:String和StringBuffer/StringBuilder,它們可以儲存和操作字符串。其中String是只讀字符串,也就意味著String引用的字符串內(nèi)容是不能被改變的。而StringBuffer/StringBuilder類表示的字符串對象可以直接進行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,區(qū)別在于它是在單線程環(huán)境下使用的,因為它的所有方面都沒有被synchronized修飾,因此它的效率也比StringBuffer要高。
-
面試題1 - 什么情況下用+運算符進行字符串連接比調(diào)用StringBuffer/StringBuilder對象的append方法連接字符串性能更好?
-
面試題2 - 請說出下面程序的輸出。
**補充:**解答上面的面試題需要清除兩點:
20、重載(Overload)和重寫(Override)的區(qū)別。重載的方法能否根據(jù)返回類型進行區(qū)分?
**答:**方法的重載和重寫都是實現(xiàn)多態(tài)的方式,區(qū)別在于前者實現(xiàn)的是編譯時的多態(tài)性,而后者實現(xiàn)的是運行時的多態(tài)性。重載發(fā)生在一個類中,同名的方法如果有不同的參數(shù)列表(參數(shù)類型不同、參數(shù)個數(shù)不同或者二者都不同)則視為重載;重寫發(fā)生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的返回類型,比父類被重寫方法更好訪問,不能比父類被重寫方法聲明更多的異常(里氏代換原則)。重載對返回類型沒有特殊的要求。
- 面試題:華為的面試題中曾經(jīng)問過這樣一個問題 - “為什么不能根據(jù)返回類型來區(qū)分重載”,快說出你的答案吧!
總結
以上是生活随笔為你收集整理的“面试不败计划”:面试题基础二的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC响应Restful风格
- 下一篇: NIO基础详解