五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

知識(shí)分享!10 道常見的 Java 面試題

2020-12-24 11:25 作者:光耀三十洲  | 我要投稿

有一天,小王告訴我,他去一家公司面試 Java 崗,結(jié)果被面試官虐哭了。整整 10 道 Java 面試題,小王一道也沒答正確。

他沮喪地給我說(shuō),“哥,說(shuō)點(diǎn)我的情況,你愿意聽嗎?我和一個(gè)女孩相處,女孩大我兩歲,我非科班。本來(lái)打算國(guó)慶換一家薪水高點(diǎn)的,好確認(rèn)關(guān)系。我經(jīng)驗(yàn)不多,技術(shù)一般般,之前在一家外包公司,有一個(gè)甲方內(nèi)推,我就魯莽地把外包的工作辭了,結(jié)果沒想到面試被虐了,我擔(dān)心女朋友會(huì)不會(huì)因?yàn)槲覜]有工作和我分手?!?/p>

聽他這么一說(shuō),確實(shí)挺虐心的。后來(lái)我就安慰他,要他端正心態(tài),先把這些面試題整明白,然后繼續(xù)找工作,不要想太多。

借這個(gè)機(jī)會(huì),我就把小王遇到的這 10 道面試題分享出來(lái),希望能對(duì)其他小伙伴一些幫助。

第一題,下面這串代碼打印的結(jié)果是什么

public class Test {

? ? public static void main(String[] args) {

? ? ? ? System.out.println(Math.min(Double.MIN_VALUE, 0.0d));

? ? }

}


小王之所以沒答對(duì)這道題,是因?yàn)樗X得 Double.MIN_VALUE 和 Integer.MIN_VALUE 一樣,是個(gè)負(fù)數(shù),應(yīng)該小于 0.0d。

但事實(shí)上,Double. MIN_VALUE 和 Double. MAX_VALUE 一樣,都是正數(shù),Double. MIN_VALUE 的值是 2^(-1074),直接打印 Double. MIN_VALUE 的話,輸出結(jié)果為 4.9E-324。

因此這道題的正確答案是輸出 0.0。

第二題,在 try 塊或者 catch 語(yǔ)句中執(zhí)行 return 語(yǔ)句或者 System.exit() 會(huì)發(fā)生什么,finally 語(yǔ)句還會(huì)執(zhí)行嗎?

小王之所以沒答對(duì)這道題,是因?yàn)樵谒目贪逵∠笾?,finally 語(yǔ)句是無(wú)論如何都會(huì)執(zhí)行的。

但事實(shí)上,在 try 塊或者 catch 語(yǔ)句中執(zhí)行 return 語(yǔ)句時(shí),finally 語(yǔ)句會(huì)執(zhí)行;在 try 塊或者 catch 語(yǔ)句中執(zhí)行 System.exit() 時(shí),finally 語(yǔ)句不會(huì)執(zhí)行。

public class Test1 {

? ? public static void main(String[] args) {

? ? ? ? returnTryExec();

? ? ? ? returnCatchExec();

? ? ? ? exitTryExec();

? ? ? ? exitCatchExec();

? ? }

? ? public static int returnTryExec() {

? ? ? ? try {

? ? ? ? ? ? return 0;

? ? ? ? } catch (Exception e) {

? ? ? ? } finally {

? ? ? ? ? ? System.out.println("finally returnTryExec");

? ? ? ? ? ? return -1;

? ? ? ? }

? ? }

? ? public static int returnCatchExec() {

? ? ? ? try { } catch (Exception e) {

? ? ? ? ? ? return 0;

? ? ? ? } finally {

? ? ? ? ? ? System.out.println("finally returnCatchExec");

? ? ? ? ? ? return -1;

? ? ? ? }

? ? }

? ? public static void exitTryExec() {

? ? ? ? try {

? ? ? ? ? ? System.exit(0);

? ? ? ? } catch (Exception e) {

? ? ? ? } finally {

? ? ? ? ? ? System.out.println("finally exitTryExec");

? ? ? ? }

? ? }

? ? public static void exitCatchExec() {

? ? ? ? try { } catch (Exception e) {

? ? ? ? ? ? System.exit(0);

? ? ? ? } finally {

? ? ? ? ? ? System.out.println("finally exitCatchExec");

? ? ? ? }

? ? }

}


程序執(zhí)行結(jié)果如下所示:

finally returnTryExec

finally returnCatchExec


第三題,私有方法或者靜態(tài)方法能被重寫(override)嗎?

小王之所以沒答對(duì)這道題,是因?yàn)樗淮_定私有方法或者靜態(tài)方法與重寫之間的關(guān)系。

重寫的兩個(gè)方法名相同,方法參數(shù)的個(gè)數(shù)也相同;不過(guò)一個(gè)方法在父類中,另外一個(gè)在子類中。

class LaoWang{

? ? public void write() {

? ? ? ? System.out.println("老王寫了一本《基督山伯爵》");

? ? }

}

class XiaoWang extends LaoWang {

? ? @Override

? ? public void write() {

? ? ? ? System.out.println("小王寫了一本《茶花女》");

? ? }

}

public class OverridingTest {

? ? public static void main(String[] args) {

? ? ? ? LaoWang wang = new XiaoWang();

? ? ? ? wang.write();

? ? }

}


父類 LaoWang 有一個(gè) write() 方法(無(wú)參),方法體是寫一本《基督山伯爵》;子類 XiaoWang 重寫了父類的 write() 方法(無(wú)參),但方法體是寫一本《茶花女》。

在 main 方法中,我們聲明了一個(gè)類型為 LaoWang 的變量 wang。在編譯期間,編譯器會(huì)檢查 LaoWang 類是否包含了 write() 方法,發(fā)現(xiàn) LaoWang 類有,于是編譯通過(guò)。在運(yùn)行期間,new 了一個(gè) XiaoWang 對(duì)象,并將其賦值給 wang,此時(shí) Java 虛擬機(jī)知道 wang 引用的是 XiaoWang 對(duì)象,所以調(diào)用的是子類 XiaoWang 中的 write() 方法而不是父類 LaoWang? 中的 write() 方法,因此輸出結(jié)果為“小王寫了一本《茶花女》”。

而私有方法對(duì)子類是不可見的,它僅在當(dāng)前聲明的類中可見,private 關(guān)鍵字滿足了封裝的最高級(jí)別要求。另外,Java 中的私有方法是通過(guò)編譯期的靜態(tài)綁定的方式綁定的,不依賴于特定引用變量所持有的對(duì)象類型。

方法重寫適用于動(dòng)態(tài)綁定,因此私有方法無(wú)法被重寫。

class LaoWang{

? ? public LaoWang() {

? ? ? ? write();

? ? ? ? read();

? ? }

? ? public void write() {

? ? ? ? System.out.println("老王寫了一本《基督山伯爵》");

? ? }

? ? private void read() {

? ? ? ? System.out.println("老王在讀《哈姆雷特》");

? ? }

}

class XiaoWang extends LaoWang {

? ? @Override

? ? public void write() {

? ? ? ? System.out.println("小王寫了一本《茶花女》");

? ? }

? ? private void read() {

? ? ? ? System.out.println("小王在讀《威尼斯商人》");

? ? }

}

public class PrivateOrrideTest {

? ? public static void main(String[] args) {

? ? ? ? LaoWang wang = new XiaoWang();

? ? }

}


程序輸出結(jié)果如下所示:

小王寫了一本《茶花女》

老王在讀《哈姆雷特》


在父類的構(gòu)造方法中,分別調(diào)用了 write() 和 read() 方法,write()

方法是 public 的,可以被重寫,因此執(zhí)行了子類的 write() 方法,read() 方法是私有的,無(wú)法被重寫,因此執(zhí)行的仍然是父類的 read() 方法。

和私有方法類似,靜態(tài)方法在編譯期也是通過(guò)靜態(tài)綁定的方式綁定的,不依賴于特定引用變量所持有的對(duì)象類型。方法重寫適用于動(dòng)態(tài)綁定,因此靜態(tài)方法無(wú)法被重寫。

public class StaticOrrideTest {

? ? public static void main(String[] args) {

? ? ? ? Laozi zi = new Xiaozi();

? ? ? ? zi.write();

? ? }

}

class Laozi{

? ? public static void write() {

? ? ? ? System.out.println("老子寫了一本《基督山伯爵》");

? ? }

}

class Xiaozi extends Laozi {

? ? public static void write() {

? ? ? ? System.out.println("小子寫了一本《茶花女》");

? ? }

}


程序輸出結(jié)果如下所示:

老子寫了一本《基督山伯爵》


引用變量 zi 的類型為 Laozi,所以 zi.write() 執(zhí)行的是父類中的 write() 方法。

靜態(tài)方法也叫類方法,直接通過(guò)類名就可以調(diào)用,通過(guò)對(duì)象調(diào)用的時(shí)候,IDE 會(huì)發(fā)出警告。

第四題,1.0/0.0 得到的結(jié)果是什么?會(huì)拋出異常嗎,還是會(huì)出現(xiàn)編譯錯(cuò)誤?

小王之所以沒答對(duì)這道題,是因?yàn)樗麤]有深入研究過(guò) double 類型和 int 類型的除法運(yùn)算。

數(shù)字在 Java 中可以分為兩種,一種是整形,一種是浮點(diǎn)型。不太清楚的小伙伴先去研究一下數(shù)據(jù)類型。

當(dāng)浮點(diǎn)數(shù)除以 0 的時(shí)候,結(jié)果為 Infinity 或者 NaN。

System.out.println(1.0 / 0.0); // Infinity

System.out.println(0.0 / 0.0); // NaN


Infinity 的中文意思是無(wú)窮大,NaN 的中文意思是這不是一個(gè)數(shù)字(Not a Number)。

當(dāng)整數(shù)除以 0 的時(shí)候(10 / 0),會(huì)拋出異常:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at com.itwanger.eleven.ArithmeticOperator.main(ArithmeticOperator.java:32)


通常,我們?cè)谶M(jìn)行整數(shù)的除法運(yùn)算時(shí),需要先判斷除數(shù)是否為 0,以免程序拋出異常。

第五題,Java 支持多重繼承嗎?

小王之所以沒答對(duì)這道題,是因?yàn)樗?,通過(guò)接口可以達(dá)到多重繼承的目的。

來(lái)定義兩個(gè)接口,F(xiàn)ly 會(huì)飛,Run 會(huì)跑。

public interface Fly {

? ? void fly();

}

public interface Run {

? ? void run();

}

然后讓一個(gè)類同時(shí)實(shí)現(xiàn)這兩個(gè)接口。

public class Pig implements Fly,Run{

? ? @Override

? ? public void fly() {

? ? ? ? System.out.println("會(huì)飛的豬");

? ? }

? ? @Override

? ? public void run() {

? ? ? ? System.out.println("會(huì)跑的豬");

? ? }

}


但說(shuō)到多重繼承,討論的關(guān)鍵字是 extends,而非 implements。

Java 只支持單一繼承,是因?yàn)樯婕暗搅庑螁栴}。如果有兩個(gè)類共同繼承一個(gè)有特定方法的父類,那么該方法可能會(huì)被兩個(gè)子類重寫。然后,如果你決定同時(shí)繼承這兩個(gè)子類,那么在你調(diào)用該重寫方法時(shí),編譯器不能識(shí)別你要調(diào)用哪個(gè)子類的方法。

類 C 同時(shí)繼承了類 A 和類 B,類 C 的對(duì)象在調(diào)用類 A 和類 B 中重寫的方法時(shí),就不知道該調(diào)用類 A 的方法,還是類 B 的方法。

第六題,當(dāng)在 HashMap 中放入一個(gè)已經(jīng)存在的 key 時(shí),會(huì)發(fā)生什么?

小王之所以沒答對(duì)這道題,是因?yàn)樗麤]有深入研究過(guò) HashMap 的工作原理。

Hash,一般譯作“散列”,也有直接音譯為“哈?!钡?,這玩意什么意思呢?就是把任意長(zhǎng)度的數(shù)據(jù)通過(guò)一種算法映射到固定長(zhǎng)度的域上(散列值)。

再直觀一點(diǎn),就是對(duì)一串?dāng)?shù)據(jù) wang 進(jìn)行雜糅,輸出另外一段固定長(zhǎng)度的數(shù)據(jù) er——作為數(shù)據(jù) wang 的特征。我們通常用一串指紋來(lái)映射某一個(gè)人,別小瞧手指頭那么大點(diǎn)的指紋,在你所處的范圍內(nèi)很難找出第二個(gè)和你相同的(人的散列算法也好厲害,有沒有)。

對(duì)于任意兩個(gè)不同的數(shù)據(jù)塊,其散列值相同的可能性極小,也就是說(shuō),對(duì)于一個(gè)給定的數(shù)據(jù)塊,找到和它散列值相同的數(shù)據(jù)塊極為困難。再者,對(duì)于一個(gè)數(shù)據(jù)塊,哪怕只改動(dòng)它的一個(gè)比特位,其散列值的改動(dòng)也會(huì)非常的大——這正是 Hash 存在的價(jià)值!

大家應(yīng)該知道,HashMap 的底層數(shù)據(jù)結(jié)構(gòu)是一個(gè)數(shù)組,通過(guò) hash() 方法來(lái)確定下標(biāo)。

static final int hash(Object key) {

? ? int h;

? ? return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

}

當(dāng)我們放入一個(gè)鍵值對(duì)的時(shí)候,會(huì)先調(diào)用 hash() 方法對(duì) key 進(jìn)行哈希算法,如果 key 是相同的,那么哈希后的結(jié)果也是相同的,意味著數(shù)組中的下標(biāo)是相同的,新放入的值就會(huì)覆蓋原來(lái)的值。

第七題,下面這段代碼將會(huì)打印出什么?

public class Test {

? ? public static void main(String[] args) {

? ? ? ? char[] chars = new char[]{'\u0097'};

? ? ? ? String str = new String(chars);

? ? ? ? byte[] bytes = str.getBytes();

? ? ? ? System.out.println(Arrays.toString(bytes));

? ? }

}


小王之所以沒答對(duì)這道題,是因?yàn)樗麤]有深入研究過(guò)字符編碼方面的一些知識(shí)。

在這段程序中,我們通過(guò)一個(gè)字符數(shù)組創(chuàng)建了一個(gè)字符串對(duì)象,然后調(diào)用 String 類的 getByte() 方法得到字節(jié)數(shù)組并將其打印到控制臺(tái)。

這道面試題考察的核心并不是最終的打印結(jié)果(結(jié)果是不確定的),而是字符編碼。通常情況下,我們?cè)谡{(diào)用 getBytes() 方法時(shí),要指定編碼,比如說(shuō) str.getBytes(StandardCharsets.UTF_8)。

當(dāng)我們沒有指定編碼的時(shí)候,JDK 會(huì)調(diào)用平臺(tái)默認(rèn)的字符編碼,而不同的操作系統(tǒng),編碼不盡相同的,bytes 的結(jié)果也就會(huì)不同。

當(dāng)使用 UTF_8 時(shí),結(jié)果為 -62, -105,當(dāng)使用 GB2312 時(shí),結(jié)果為 63。

第八題,當(dāng)方法在父類中拋出 NullPointerException 時(shí),是否可以使用拋出 RuntimeException 的方法來(lái)重寫它?

小王之所以沒答對(duì)這道題,是因?yàn)樗恢貙懀╫verriding)和重載(overloading)的概念搞混了。

方法重寫和方法重載時(shí),方法名可以完全相同,但根本的不同在于方法重寫時(shí)發(fā)生在運(yùn)行時(shí),方法重載時(shí)發(fā)生在編譯時(shí)。

另外,方法重寫和方法重載時(shí)的規(guī)則也不盡相同。在 Java 中,不能重寫 private、static 和 final 方法,但可以重載它們。

我們來(lái)重點(diǎn)看一下方法重寫時(shí)的規(guī)則:

1)方法簽名必須相同,包括返回類型、參數(shù)的數(shù)量、參數(shù)的類型和參數(shù)的順序。

2)重寫后的方法不能拋出比父類中更高級(jí)別的異常。舉例來(lái)說(shuō),如果父類中的方法拋出的是 IOException,那么子類中重寫的方法不能拋出 Exception,可以是 IOException 的子類或者不拋出任何異常。這條規(guī)則只適用于可檢查的異常。

可檢查(checked)異常必須在源代碼中顯式地進(jìn)行捕獲處理,不檢查(unchecked)異常就是所謂的運(yùn)行時(shí)異常,比如說(shuō) NullPointerException、ArrayIndexOutOfBoundsException 之類的,不會(huì)在編譯器強(qiáng)制要求。

3)重寫后的方法訪問權(quán)限不能比父類中的方法低,比如說(shuō)父類中的方法是 public,重寫后的方法就不能是 protected。

public class ExceptionDemo {

? ? public static void main(String[] args) {

? ? ? ? Super s = new Child();

? ? ? ? s.write();

? ? }

}

class Super{

? ? public void write() throws NullPointerException { }

}

class Child extends Super {

? ? @Override

? ? public void write() throws RuntimeException { }

}

RuntimeException 和 NullPointerException 屬于不檢查異常,所以本題的答案是可以的。如果是可檢查異常的話,IDE 就會(huì)發(fā)出警告。

第九題,下面這段代碼使用了?compareTo()?方法,有問題嗎?

class Employee implements Comparable {

? ? private int id;

? ? @Override

? ? public int compareTo(Object o) {

? ? ? ? Employee emp = (Employee) o;

? ? ? ? return this.id - emp.id;

? ? }

}

小王之所以沒答對(duì)這道題,是因?yàn)樗氘?dāng)然地認(rèn)為 id 的都是正整數(shù)。

當(dāng)我們需要按照一定的規(guī)則進(jìn)行排序的時(shí)候,通常要實(shí)現(xiàn) Comparable 接口,并實(shí)現(xiàn) compareTo 方法,規(guī)則如下:

1)如果當(dāng)前對(duì)象小于另外一個(gè)對(duì)象,則 compareTo 方法必須返回負(fù)數(shù);如果當(dāng)前對(duì)象大于另外一個(gè)對(duì)象,則必須返回正數(shù);如果兩個(gè)對(duì)象相等,則返回零。

2)通常來(lái)說(shuō),compareTo 方法必須和 equals 方法一致,如果兩個(gè)對(duì)象通過(guò) equals 方法判斷的結(jié)果為 true,那么 compareTo 必須返回零。

不過(guò),JDK 中有一個(gè)反例,就是 BigDecimal。

BigDecimal bd1 = new BigDecimal("2.0");

BigDecimal bd2 = new BigDecimal("2.00");

System.out.println("equals: " + bd1.equals(bd2));

System.out.println("compareTo: " + bd1.compareTo(bd2));


輸出結(jié)果如下所示:

equals: false

compareTo: 0


這是因?yàn)?JDK 認(rèn)為 2.0 和 2.00 的精度不一樣,所以不能 equals,但值確實(shí)是相等的。

3)不能使用減法來(lái)比較整數(shù)值,因?yàn)闇p法的結(jié)果可能溢出。應(yīng)該使用 Integer.compareTo() 來(lái)進(jìn)行比較。如果你想通過(guò)減法操作來(lái)提高性能,必須得確保兩個(gè)操作數(shù)是正整數(shù),或者確保兩者相差的值小于 Integer.MAX_VALUE。

public class CompareDemo {

? ? public static void main(String[] args) {

? ? ? ? List<Employee> list = new ArrayList<>();

? ? ? ? list.add(new Employee(1));

? ? ? ? list.add(new Employee(Integer.MIN_VALUE));

? ? ? ? list.add(new Employee(Integer.MAX_VALUE));

? ? ? ? Collections.sort(list);

? ? ? ? System.out.println(list);

? ? }

}

class Employee implements Comparable {

? ? private int id;

? ? public Employee(int id) {

? ? ? ? this.id = id;

? ? }

? ? @Override

? ? public int compareTo(Object o) {

? ? ? ? Employee emp = (Employee) o;

? ? ? ? return this.id - emp.id;

? ? }

? ? @Override

? ? public String toString() {

? ? ? ? return "Employee{" +

? ? ? ? ? ? ? ? "id=" + id +

? ? ? ? ? ? ? ? '}';

? ? }

}


程序的輸出結(jié)果如下所示:

[Employee{id=1}, Employee{id=2147483647}, Employee{id=-2147483648}]


排序就亂了。因?yàn)?Integer.MIN_VALUE - 1 變成了正數(shù) 2147483647。

第十題,StringBuffer 和 StringBuilder 之間有什么區(qū)別?

小王之所以沒答對(duì)這道題,是因?yàn)樗X得這道題太簡(jiǎn)單了,結(jié)果說(shuō)反了,大意了啊。

StringBuilder 是 JDK 1.5 之后引入的,它和 StringBuffer 最大的區(qū)別就在于它的一系列方法都是非同步的。

好了,以上就是小王這次面試遇到的 10 道虐心的面試題,本來(lái)最后一道是送分題,結(jié)果大意說(shuō)反了,讓小王更加懊惱。年后是跳槽的高峰期,有打算的小伙伴要提前準(zhǔn)備了,希望大家都能夠順利面上心儀的崗位。

了解更多,請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1L7411N77n



作者:沉默王二

鏈接:https://juejin.cn/post/6909309870344765448

來(lái)源:掘金

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。


知識(shí)分享!10 道常見的 Java 面試題的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
无为县| 土默特左旗| 武川县| 商都县| 秦皇岛市| 杭锦旗| 朝阳区| 武功县| 宜章县| 徐汇区| 区。| 临汾市| 张掖市| 河源市| 舒兰市| 日喀则市| 沙洋县| 牡丹江市| 新源县| 丹江口市| 崇礼县| 靖西县| 阿荣旗| 土默特右旗| 淮滨县| 河东区| 南充市| 红桥区| 大厂| 宿松县| 江永县| 桃园县| 安义县| 资中县| 铜鼓县| 徐水县| 奉新县| 邳州市| 获嘉县| 平乐县| 陆川县|