去年面了多個候選人磷瘤,看看我挖的坑還有他們應(yīng)該要補(bǔ)的Java基礎(chǔ)(一)

看看我在基礎(chǔ)數(shù)據(jù)類型方面埋了什么坑

說說看,Java有多少種基本的數(shù)據(jù)類型搜变?多大采缚?

Java有8中基本的數(shù)據(jù)類型,分別是

  • byte挠他,占據(jù)1個字節(jié)8位
  • char扳抽,占據(jù)2個字節(jié)16位
  • short,占據(jù)2個字節(jié)16位
  • int殖侵,占據(jù)4個字節(jié)32位
  • float贸呢,占據(jù)4個字節(jié)32位
  • long,占據(jù)8個字節(jié)64位
  • double拢军,占據(jù)8個字節(jié)64位
  • boolean楞陷,占據(jù)一個字節(jié)8位

<u>錯,將boolean默認(rèn)為一個字節(jié)基本是所有初學(xué)者的通茉唉。</u>

注意:boolean的大小是未知的固蛾,雖然我們看boolean只有:true、false兩種情況赌渣,可以使用 1 bit 來存儲魏铅,但是實際上沒有明確規(guī)定是1bit,因為因為對虛擬機(jī)來說根本就不存在 boolean 這個類型坚芜。在《Java虛擬機(jī)規(guī)范》中給出了兩種定義览芳,分別是4個字節(jié)和boolean數(shù)組時1個字節(jié)的定義,但是具體還要看虛擬機(jī)實現(xiàn)是否按照規(guī)范來鸿竖,1個字節(jié)沧竟、4個字節(jié)都是有可能的铸敏。這其實是運(yùn)算效率和存儲空間之間的博弈,兩者都非常的重要悟泵。

那Integer這些算什么呢杈笔?

這些算是包裝類型,每個基本類型都有對應(yīng)的包裝類型糕非,基本類型與其對應(yīng)的包裝類型之間的賦值使用自動裝箱與拆箱完成蒙具。比如:

Integer number1 = 2;     // 裝箱 調(diào)用了 Integer.valueOf(2)
int number2 = number1;         // 拆箱 調(diào)用了 number1.intValue()

記得挺牢的,那 new Integer(1024) 和Integer.valueOf(1024) 有沒有什么區(qū)別呢朽肥?

首先禁筏,new Integer(1024) 每次都會新建一個對象,而Integer.valueOf(1024) 會使用緩沖池中的對象衡招,多次調(diào)用會取得同一個對象的引用篱昔。

我舉個例子:

image-20210109100030722

<u>錯,這是我埋著的坑點始腾,我曾經(jīng)用這一招坑了多個候選人州刽。</u>

image-20210109174541713

注意:Integer.valueOf(1024) 和Integer.valueOf(1024) 缺不等于true,而是false浪箭。Integer.valueOf從緩沖池取的數(shù)值是有大小限制的穗椅,并不是任何數(shù)

我們可以看看valueOf() 的源碼,其實也比較簡單奶栖,就是先判斷值是否在緩存池中房待,如果在的話就直接返回緩沖池的內(nèi)容。

image-20210109100401281

目前我的jdk版本是 8 驼抹,在jdk8中Integer 緩沖池的大小默認(rèn)為 -128~127。

image-20210109100503563

<u>做為一個面試官拜鹤,我很喜歡挖別人回答問題時暴露的細(xì)節(jié)點</u>框冀。你剛剛說到了自動裝箱和拆箱,說說看你的理解敏簿?

編譯器會在自動裝箱過程中調(diào)用 valueOf() 方法明也,因此多個值相同且值在緩存池范圍內(nèi)的 Integer 實例使用自動裝箱來創(chuàng)建,那么就會引用相同的對象惯裕,因此對比的時候會返回true温数。

image-20210109101748474

<u>繼續(xù)往深挖,看看候選人對知識點的掌握有多深蜻势。</u>那說說看你知道的緩沖池有哪些撑刺?

目前基本類型對應(yīng)的緩沖池如下:

  • boolean 緩沖池,true and false
  • byte緩沖池
  • short 緩沖池
  • int 緩沖池
  • char 緩沖池

因此我們在使用這些基本類型對應(yīng)的包裝類型時握玛,如果該數(shù)值范圍在緩沖池范圍內(nèi)够傍,那么就可以直接使用緩沖池中的對象甫菠。

<u>繼續(xù)挖,看看他有沒有看過緩沖池的源碼冕屯。</u>你說的這些緩沖池的上限下限都是不變的嗎寂诱?還是說可以設(shè)定的?

基本上都是不可變的安聘,不過在 jdk 1.8 中痰洒,Integer 的緩沖池 IntegerCache 很特殊,這個緩沖池的下界是 - 128浴韭,上界默認(rèn)是 127丘喻,但是這個上界是可調(diào)的。我們可以看源碼

image-20210109102339939

在啟動 jvm 的時候囱桨,我們可以通過通過 -XX:AutoBoxCacheMax=<size> 來指定這個緩沖池的大小仓犬,在JVM初始化的時候,這個設(shè)置會設(shè)定一個名為 java.lang.IntegerCache.high 系統(tǒng)屬性舍肠,然后 IntegerCache 初始化的時候就會讀取該系統(tǒng)屬性來決定上界搀继。

總結(jié):上面的坑分別有boolean的大小、緩沖池的大小翠语、自動拆箱和裝箱叽躯、緩沖池的大小是否可變,基本上這幾個坑點可以坑倒百分之六十的候選人肌括,其次是做為一個面試官点骑,我很喜歡挖候選人回答問題的細(xì)節(jié),畢竟深挖可以看得出你是不是真的有料5病:诘巍!

看看我在String方面埋了什么坑

你剛剛說了基本類型了紧索,說說看你對String的了解吧

String 被聲明為 final袁辈,因此它不可被繼承。在 Java 8 中珠漂,String 內(nèi)部使用 char 數(shù)組存儲數(shù)據(jù)晚缩,并且聲明為 final,這意味著 value 數(shù)組初始化之后就不能再引用其它數(shù)組媳危,String 內(nèi)部也沒有改變 value 數(shù)組的方法荞彼,因此可以保證 String 不可變。

<u>繼續(xù)深挖</u> 說說看不可變的好處待笑?

這個問題的回答比較泛鸣皂,可以說的點比較多,大致可以分為:

  • 首先是不可變自然意味著安全,當(dāng)String 作為參數(shù)引用的時候签夭,不可變性可以保證參數(shù)不可變齐邦。

  • 其次是可以緩存 hash 值,實際上第租,我們開發(fā)的時候經(jīng)常會用來當(dāng)做map的key措拇,不可變的特性可以使得 hash 值也不可變,因此只需要進(jìn)行一次計算慎宾。

  • 最后自然是String Pool 的需要丐吓,如果一個 String 對象已經(jīng)被創(chuàng)建過了,那么就會從 String Pool 中取得引用趟据,而自然只有 String 是不可變的券犁,才可能使用 String Pool。如果是可變的汹碱,那么 String Pool也就無法被設(shè)計出來了粘衬。

<u>繼續(xù)深挖</u> 有沒有用過StringBuffer 和 StringBuilder,說說看String, StringBuffer 以及StringBuilder三者的區(qū)別咳促?

首先他們都是被final修飾的類稚新,都是不可被繼承,不過從可變性上來說跪腹,String 我們剛剛說到了褂删,是不可變的,而StringBuffer 和 StringBuilder 可變的冲茸,這是內(nèi)部結(jié)構(gòu)導(dǎo)致的屯阀,StringBuffer 和StringBuilder 內(nèi)部放數(shù)據(jù)的數(shù)組沒有被final修飾。

其次從線程安全方面來說

  • String 不可變轴术,是線程安全的

  • StringBuilder 不是線程安全的难衰,因為內(nèi)部并沒有使用任何的安全處理

  • StringBuffer 是線程安全的,內(nèi)部使用 synchronized 進(jìn)行同步

<u>繼續(xù)挖細(xì)節(jié)點</u>你剛剛有說到String Pool 逗栽,說說看你的理解

String Pool也就是我們經(jīng)常說的字符串常量池召衔,它保存著所有字符串字面量,而且是在編譯時期就確定了祭陷。

String Pool是在編譯時期就確定了,那么請問是否不可變的呢趣席?

是的兵志。

<u>錯,所有初學(xué)者都會犯的一個問題宣肚,那就是忽略了String.intern的存在想罕,我經(jīng)常用這個坑點來區(qū)分初學(xué)者和中級水平的候選人的區(qū)別!!按价!</u>

image-20210109174601615

我們可以使用 String 的 intern() 方法在運(yùn)行過程將字符串添加到 String Pool 中惭适。

我們可以看到

image-20210109111528457

這是一個本地方法,看不到源碼楼镐,不過我們可以看到注釋

大致意思就是當(dāng)一個字符串調(diào)用 intern() 方法時癞志,如果 String Pool 中已經(jīng)存在一個字符串和該字符串值相等(使用 equals() 方法進(jìn)行確定),那么就會返回 String Pool 中字符串的引用框产;否則凄杯,就會在 String Pool 中添加一個新的字符串,并返回這個新字符串的引用秉宿。

用個demo來解釋這個流程

image-20210109111744460

我上面的s1 和 s2 采用 new String() 的方式新建了兩個不同字符串戒突,而 s3 和 s4 是通過 s1.intern() 和 s2.intern() 方法取得同一個字符串引用。第一個intern() 首先把 "飯談編程" 放到 String Pool 中描睦,然后返回這個字符串引用膊存,而第二個intern()則直接從String Pool 讀取了,因此 s3 和 s4 引用的是同一個字符串忱叭。

<u>繼續(xù)挖坑隔崎,準(zhǔn)備埋了候選人</u>剛剛說到 new String("飯談編程") != new String("飯談編程") ,那么 "飯談編程" 和 "飯談編程"相等嗎窑多?說下流程仍稀?

是相等的,我們可以看到

image-20210109112317572

流程是因為:采用這種字面量的形式創(chuàng)建字符串埂息,JVM會自動地將字符串放入 String Pool 中技潘,因此它們兩個是相等的。

<u>繼續(xù)往細(xì)節(jié)挖千康,這是一個比較刁鉆的問題</u> new String("飯談編程") JVM做了啥享幽?

首先使用這種方式一共會創(chuàng)建兩個字符串對象,當(dāng)然了拾弃,前提是 String Pool 中還沒有 "飯談編程" 這個字符串對象值桩,因此編譯時期會在 String Pool 中創(chuàng)建一個字符串對象,指向這個 "飯談編程" 字符串字面量豪椿。

然后在使用 new 的方式的時候奔坟,在堆中創(chuàng)建一個字符串對象,這一步我們可以結(jié)合String的構(gòu)造函數(shù)來看看

public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

可以看到搭盾,在將一個字符串對象作為另一個字符串對象的構(gòu)造函數(shù)參數(shù)時咳秉,JVM會從String Pool 中將這個字符串對象取出來,當(dāng)做參數(shù)傳進(jìn)String的構(gòu)造函數(shù)中鸯隅,將 value 數(shù)組和hash值賦予這個新的對象澜建。

總結(jié):String我們在日常開發(fā)中經(jīng)常用到,不過一個合格的候選人應(yīng)該要吃透String、StringBuilder 和StringBuffer的區(qū)別炕舵,并且要對String Pool的原理了解的盡量多一些何之,不要被我上面挖的坑給埋了。

看看我在運(yùn)算方面埋了什么坑

請問在Java中方法參數(shù)的傳遞方式是引用傳遞呢咽筋?還是值傳遞呢溶推?

這個要分情況,如果參數(shù)是基本類型的話晤硕,就是值傳遞悼潭,如果是引用類型的話,則是引用傳遞舞箍。

<u>錯舰褪,這是很多初學(xué)者容易搞錯的地方,也是我日常挖坑埋人的地方</u>

Java 的參數(shù)全都是是以值傳遞的形式傳入方法中疏橄,而不是引用傳遞占拍。如果參數(shù)是基本類型,則傳遞的是基本類型的字面量值的拷貝捎迫。而如果參數(shù)是引用類型的話晃酒,傳遞的則值該參數(shù)所引用的對象在堆中地址值的拷貝。

請看題 float f = 2.2窄绒,這么寫有沒有問題贝次?

看起來是沒問題的,其實是有問題的彰导,這個其實一般我不會用來面試蛔翅,而是用來放在筆試題中。

2.2這個字面量屬于 double 類型的位谋,因此不能直接將 2.2 直接賦值給 float 變量山析,因為這是向下轉(zhuǎn)型,記住Java 不能隱式執(zhí)行向下轉(zhuǎn)型掏父,因為這會使得精度降低笋轨。

正常寫法是

float f = 2.2f;

<u>繼續(xù)挖坑</u>,那么float f = 2.2f; f += 2.2;可以嗎

這同樣是我會放進(jìn)筆試題考研候選人基礎(chǔ)的一道題赊淑,是可以的爵政,因為使用 += 或者 ++ 運(yùn)算符,JVM會執(zhí)行隱式類型轉(zhuǎn)換陶缺。

上面的語句相當(dāng)于將 s1 + 1 的計算結(jié)果進(jìn)行了向下轉(zhuǎn)型:

f = (float) (f + 2.2);

總結(jié):在運(yùn)算方面埋的坑比較基礎(chǔ)钾挟,一般是放在面試題中,而且其實用idea開發(fā)的話實際上可以在開發(fā)期就會報錯了组哩,但是這并不意味著idea可以檢測出來的東西,你就可以不懂,特別是要來我司面試伶贰,這意味著你的專業(yè)能力是否過關(guān)蛛砰。

看看我在修飾符方面埋了什么坑

說說看對修飾符final的理解

首先是在變量上使用了final,意味著聲明數(shù)據(jù)為常量黍衙,可以是編譯時常量泥畅,也可以是在運(yùn)行時被初始化后不能被改變的常量,作用可以分為:

  • 對于基本類型琅翻,final 使數(shù)值不變位仁;
  • 對于引用類型,final 使引用不變方椎,也就不能引用其它對象聂抢。

如果是在方法上使用了final,則聲明方法不能被子類重寫棠众。

如果是在類上使用了final琳疏,則聲明方法不允許被繼承。

<u>開始挖坑了闸拿,等著你跳</u> 挺好的空盼,按照你的說法,final int b = 1; b之后是不可以改的新荤;那如果是這樣的例子揽趾,A對象的x可以改嗎

image-20210109123855200

是可以改的,這也是引用類型的那一種苛骨,fianl是作用在A對象的引用上篱瞎,而不是作用在A對象的數(shù)據(jù)成員x上,因此是可以改的智袭。

<u>繼續(xù)挖坑</u> 剛剛你說到聲明方法不能被子類重寫奔缠,那么問題來了,為啥這樣可以

image-20210109124438515

<u>一般候選人都會在這里支支吾吾的說不出個所以然來吼野。</u>

image-20210109174614608

其實他回答的理論是對的校哎,只是他沒有實際上嘗試過我這種寫法。實際上在private 方法隱式地被指定為 final的時候瞳步,如果在子類中定義的方法和基類中的一個 private 方法簽名相同闷哆,此時子類的方法并不是重寫了基類方法,而是在子類中定義了一個新的方法单起。

聊聊看你對修飾符static的了解

首先是用在變量上的話抱怔,這個變量我們一般稱之為靜態(tài)變量,也可以稱之為類變嘀倒,也就是說這個變量屬于類的屈留,類所有的實例都共享靜態(tài)變量局冰,一般我們是直接通過類名來訪問它,需要注意的一點事灌危,靜態(tài)變量在內(nèi)存中只存在一份康二。

而如果是用在方法上的話,就被稱之為靜態(tài)方法勇蝙,這個靜態(tài)方法在類加載的時候就存在了沫勿,它不依賴于任何實例,因此靜態(tài)方法必須有實現(xiàn)味混,也就是說它不能是抽象方法产雹。

<u>開始挖坑</u> 可以在靜態(tài)方法內(nèi)使用this或者super關(guān)鍵字嗎

不可以的,只能訪問所屬類的靜態(tài)字段和靜態(tài)方法翁锡,方法中不能有 this 和 super 關(guān)鍵字蔓挖,可以說static和this和super是互相矛盾的存在。

<u>坑點來了</u> 之前來了個實習(xí)生盗誊,寫代碼的時候就犯了這個錯时甚,你看看下面的執(zhí)行結(jié)果是啥

image-20210109125553717

正確答案是

image-20210109125704464

這里記住一個點就可以了,靜態(tài)語句塊優(yōu)先于普通語句塊哈踱,而普通語句塊優(yōu)先于構(gòu)造函數(shù)荒适。

<u>繼續(xù)深坑</u> 那么如果是有繼承關(guān)系在的時候呢?比如這道題开镣,說說他們的執(zhí)行順序

image-20210109130202218

大部分初級的候選人都會在這道題被絆倒刀诬,正確答案應(yīng)該是:

image-20210109130258183

也就是說,存在繼承的情況下邪财,初始化順序為:

  • 父類(靜態(tài)變量陕壹、靜態(tài)語句塊)
  • 子類(靜態(tài)變量、靜態(tài)語句塊)
  • 父類(實例變量树埠、普通語句塊)
  • 父類(構(gòu)造函數(shù))
  • 子類(實例變量糠馆、普通語句塊)
  • 子類(構(gòu)造函數(shù))

總結(jié):雖然看起來修飾符是一個比較小的東西,但是如果實際開發(fā)中采坑了怎憋,卻會造成比較大的風(fēng)險又碌,比如執(zhí)行順序搞錯了,而且也可以通過候選人對修飾符的了解情況绊袋,可以看出這個人實際的編程水平毕匀,這也是我們作為面試官想要迫切知道的地方。

最后

后續(xù)系列文章安排:

  • 談?wù)勎以贠bject挖的坑
  • 談?wù)勎以诩贤诘目?/li>
  • 談?wù)勎以趎etty系列挖的坑…

你好癌别,我是Java面試官飯談編程皂岔,我將會從面試官角度告訴你我面試候選人期間挖的坑。
好好面試系列將會分多篇文章進(jìn)行展姐,基本上看完該系列的文章躁垛,Java基礎(chǔ)這塊便可以遇神殺神了剖毯,畢竟來來去去就這些,后續(xù)精彩請等待教馆!

公眾號:飯談編程
原文鏈接:https://mp.weixin.qq.com/s/F73r_f5YcBOayPdsin4gBg
謝謝點贊支持??????速兔!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市活玲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谍婉,老刑警劉巖舒憾,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異穗熬,居然都是意外死亡镀迂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門唤蔗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來探遵,“玉大人,你說我怎么就攤上這事妓柜∠浼荆” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵棍掐,是天一觀的道長藏雏。 經(jīng)常有香客問我,道長作煌,這世上最難降的妖魔是什么掘殴? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮粟誓,結(jié)果婚禮上奏寨,老公的妹妹穿的比我還像新娘。我一直安慰自己鹰服,他們只是感情好病瞳,可當(dāng)我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著获诈,像睡著了一般仍源。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舔涎,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天笼踩,我揣著相機(jī)與錄音,去河邊找鬼亡嫌。 笑死嚎于,一個胖子當(dāng)著我的面吹牛掘而,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播于购,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼袍睡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肋僧?” 一聲冷哼從身側(cè)響起斑胜,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嫌吠,沒想到半個月后止潘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡辫诅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年凭戴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炕矮。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡么夫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肤视,到底是詐尸還是另有隱情档痪,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布邢滑,位于F島的核電站钞它,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏殊鞭。R本人自食惡果不足惜遭垛,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望操灿。 院中可真熱鬧锯仪,春花似錦、人聲如沸趾盐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽救鲤。三九已至久窟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間本缠,已是汗流浹背斥扛。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留丹锹,地道東北人稀颁。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓芬失,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匾灶。 傳聞我的和親對象是個殘疾皇子棱烂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一、數(shù)據(jù)類型基本類型包裝類型緩存池 二阶女、String概覽不可變的好處String, StringBuffer an...
    Juntech閱讀 232評論 0 0
  • (ps:該文章是本人在其他網(wǎng)站的面試題中看到并且收集下來的) 一颊糜、數(shù)據(jù)類型 1.基本類型 byte/8 char/...
    義無反顧00閱讀 182評論 0 0
  • 一、數(shù)據(jù)類型基本類型包裝類型緩存池 二秃踩、String概覽不可變的好處String, StringBuffer an...
    魔都云濤閱讀 161評論 0 0
  • 前言equals() 和 hashCode() 都是 Object 對象中的非 final 方法芭析,它們設(shè)計的目的就...
    sortinnauto閱讀 255評論 0 1
  • 漸變的面目拼圖要我怎么拼芍秆? 我是疲乏了還是投降了? 不是不允許自己墜落翠勉, 我沒有滴水不進(jìn)的保護(hù)膜妖啥。 就是害怕變得面...
    悶熱當(dāng)乘涼閱讀 4,238評論 0 13