摘要:地址面試必備最最最常見的面試題總結(jié)第一周一中的值傳遞和引用傳遞非常重要首先要明確的是對象傳遞數(shù)組類接口是引用傳遞,原始類型數(shù)據(jù)整型浮點型字符型布爾型傳遞是值傳遞。這個哈希碼的作用是確定該對象在哈希表中的索引位置。
這里會分享一些出現(xiàn)頻率極其極其高的面試題,初定周更一篇,什么時候更完什么時候停止。
Github地址:https://github.com/Snailclimb/Java-Guide/blob/master/面試必備/最最最常見的Java面試題總結(jié)/第一周(2018-8-7).md
一 Java中的值傳遞和引用傳遞(非常重要)首先要明確的是:“對象傳遞(數(shù)組、類、接口)是引用傳遞,原始類型數(shù)據(jù)(整型、浮點型、字符型、布爾型)傳遞是值傳遞。”
那么什么是值傳遞和應(yīng)用傳遞呢?值傳遞是指對象被值傳遞,意味著傳遞了對象的一個副本,即使副本被改變,也不會影響源對象。(因為值傳遞的時候,實際上是將實參的值復(fù)制一份給形參。)
引用傳遞是指對象被引用傳遞,意味著傳遞的并不是實際的對象,而是對象的引用。因此,外部對引用對象的改變會反映到所有的對象上。(因為引用傳遞的時候,實際上是將實參的地址值復(fù)制一份給形參。)
有時候面試官不是單純問你“Java中是值傳遞還是引用傳遞”是什么啊,騷年?而是給出一個例子,然后讓你寫出答案,這種也常見在筆試題目中!所以,非常重要了,請看下面的例子:
值傳遞和應(yīng)用傳遞實例 1. 值傳遞public static void main(String[] args) { int num1 = 10; int num2 = 20; swap(num1, num2); System.out.println("num1 = " + num1); System.out.println("num2 = " + num2); } public static void swap(int a, int b) { int temp = a; a = b; b = temp; System.out.println("a = " + a); System.out.println("b = " + b); }
結(jié)果:
a = 20 b = 10 num1 = 10 num2 = 20
解析:
在swap方法中,a、b的值進行交換,并不會影響到num1、num2。因為,a、b中的值,只是從num1、num2的復(fù)制過來的。
也就是說,a、b相當(dāng)于num1、num2的副本,副本的內(nèi)容無論怎么修改,都不會影響到原件本身。
public static void main(String[] args) { int[] arr = {1,2,3,4,5}; change(arr); System.out.println(arr[0]); } public static void change(int[] array) { //將數(shù)組的第一個元素變?yōu)? array[0] = 0; }
結(jié)果:
1 0
解析:
無論是主函數(shù),還是change方法,操作的都是同一個地址值對應(yīng)的數(shù)組。 。因此,外部對引用對象的改變會反映到所有的對象上。
一些特殊的例子 1. StringBuffer類型傳遞// 測試引用傳遞:StringBuffer @org.junit.Test public void method1() { StringBuffer str = new StringBuffer("公眾號:Java面試通關(guān)手冊"); System.out.println(str); change1(str); System.out.println(str); } public static void change1(StringBuffer str) { str = new StringBuffer("abc");//輸出:“公眾號:Java面試通關(guān)手冊” //str.append("歡迎大家關(guān)注");//輸出:公眾號:Java面試通關(guān)手冊歡迎大家關(guān)注 //str.insert(3, "(編程)");//輸出:公眾號(編程):Java面試通關(guān)手冊 }
結(jié)果:
公眾號:Java面試通關(guān)手冊 公眾號:Java面試通關(guān)手冊
解析:
很多要這個時候要問了:StringBuffer創(chuàng)建的明明也是對象,那為什么輸出結(jié)果依然是原來的值呢?
因為在change1方法內(nèi)部我們是新建了一個StringBuffer對象,所以str指向了另外一個地址,相應(yīng)的操作也同樣是指向另外的地址的。
那么,如果將change1方法改成如下圖所示,想必大家應(yīng)該知道輸出什么了,如果你還不知道,那可能就是我講的有問題了,我反思(開個玩笑,上面程序中已經(jīng)給出答案):
public static void change1(StringBuffer str) { str.append("歡迎大家關(guān)注"); str.insert(3, "(編程)"); }2. String類型傳遞
// 測試引用傳遞:Sring @org.junit.Test public void method2() { String str = new String("公眾號:Java面試通關(guān)手冊"); System.out.println(str); change2(str); System.out.println(str); } public static void change2(String str) { // str="abc"; //輸出:公眾號:Java面試通關(guān)手冊 str = new String("abc"); //輸出:公眾號:Java面試通關(guān)手冊 }
結(jié)果:
公眾號:Java面試通關(guān)手冊 公眾號:Java面試通關(guān)手冊
可以看到不論是執(zhí)行str="abc;"還是str = new String("abc");str的輸出的值都不變。
按照我們上面講“StringBuffer類型傳遞”的時候說的,str="abc;"應(yīng)該會讓str的輸出的值都不變。為什么呢?因為String在創(chuàng)建之后是不可變的。
下面的程序輸出是什么?
public class Demo { public static void main(String[] args) { Person p = new Person("張三"); change(p); System.out.println(p.name); } public static void change(Person p) { Person person = new Person("李四"); p = person; } } class Person { String name; public Person(String name) { this.name = name; } }
很明顯仍然會輸出張三。因為change方法中重新創(chuàng)建了一個Person對象。
那么,如果把 change方法改為下圖所示,輸出結(jié)果又是什么呢?
public static void change(Person p) { p.name="李四"; }
答案我就不說了,我覺得大家如果認(rèn)真看完上面的內(nèi)容之后應(yīng)該很很清楚了。
二 ==與equals(重要)== : 它的作用是判斷兩個對象的地址是不是相等。即,判斷兩個對象是不是同一個對象。(基本數(shù)據(jù)類型==比較的是值,引用數(shù)據(jù)類型==比較的是內(nèi)存地址)
equals() : 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況:
情況1:類沒有覆蓋equals()方法。則通過equals()比較該類的兩個對象時,等價于通過“==”比較這兩個對象。
情況2:類覆蓋了equals()方法。一般,我們都覆蓋equals()方法來兩個對象的內(nèi)容相等;若它們的內(nèi)容相等,則返回true(即,認(rèn)為這兩個對象相等)。
舉個例子:
public class test1 { public static void main(String[] args) { String a = new String("ab"); // a 為一個引用 String b = new String("ab"); // b為另一個引用,對象的內(nèi)容一樣 String aa = "ab"; // 放在常量池中 String bb = "ab"; // 從常量池中查找 if (aa == bb) // true System.out.println("aa==bb"); if (a == b) // false,非同一對象 System.out.println("a==b"); if (a.equals(b)) // true System.out.println("aEQb"); if (42 == 42.0) { // true System.out.println("true"); } } }
說明:
String中的equals方法是被重寫過的,因為object的equals方法是比較的對象的內(nèi)存地址,而String的equals方法比較的是對象的值。
當(dāng)創(chuàng)建String類型的對象時,虛擬機會在常量池中查找有沒有已經(jīng)存在的值和要創(chuàng)建的值相同的對象,如果有就把它賦給當(dāng)前引用。如果沒有就在常量池中重新創(chuàng)建一個String對象。
三 hashCode與equals(重要)面試官可能會問你:“你重寫過 hashcode 和 equals 么,為什么重寫equals時必須重寫hashCode方法?”
hashCode()介紹hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實際上是返回一個int整數(shù)。這個哈希碼的作用是確定該對象在哈希表中的索引位置。hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函數(shù)。
散列表存儲的是鍵值對(key-value),它的特點是:能根據(jù)“鍵”快速的檢索出對應(yīng)的“值”。這其中就利用到了散列碼?。梢钥焖僬业剿枰膶ο螅?/p> 為什么要有hashCode
我們以“HashSet如何檢查重復(fù)”為例子來說明為什么要有hashCode:
當(dāng)你把對象加入HashSet時,HashSet會先計算對象的hashcode值來判斷對象加入的位置,同時也會與其他已經(jīng)加入的對象的hashcode值作比較,如果沒有相符的hashcode,HashSet會假設(shè)對象沒有重復(fù)出現(xiàn)。但是如果發(fā)現(xiàn)有相同hashcode值的對象,這時會調(diào)用equals()方法來檢查hashcode相等的對象是否真的相同。如果兩者相同,HashSet就不會讓其加入操作成功。如果不同的話,就會重新散列到其他位置。(摘自我的Java啟蒙書《Head fist java》第二版)。這樣我們就大大減少了equals的次數(shù),相應(yīng)就大大提高了執(zhí)行速度。
hashCode()與equals()的相關(guān)規(guī)定如果兩個對象相等,則hashcode一定也是相同的
兩個對象相等,對兩個對象分別調(diào)用equals方法都返回true
兩個對象有相同的hashcode值,它們也不一定是相等的
因此,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
hashCode()的默認(rèn)行為是對堆上的對象產(chǎn)生獨特值。如果沒有重寫hashCode(),則該class的兩個對象無論如何都不會相等(即使這兩個對象指向相同的數(shù)據(jù))
寫在最后 推薦一個自己的開源的后端文檔Java-Guide: Java面試通關(guān)手冊(Java學(xué)習(xí)指南)Java Interview Customs Manual (Java Study Guide)。star:1.4k。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76647.html
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識點總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機制解讀抽象類與三大特征時間和時間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識點總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機制解讀抽象類與三大特征時間和時間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識點總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機制解讀抽象類與三大特征時間和時間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
閱讀 1310·2021-11-11 16:55
閱讀 1571·2021-10-08 10:16
閱讀 1225·2021-09-26 10:20
閱讀 3609·2021-09-01 10:47
閱讀 2489·2019-08-30 15:52
閱讀 2711·2019-08-30 13:18
閱讀 3223·2019-08-30 13:15
閱讀 1162·2019-08-30 10:55