0、鍥子
一入編程深似海,編程世界Very深。
這裡是九神說編程,今天給大家說的是一個頂級大佬閒的無聊,在編程世界已經999級,閒來無事去新手村練小號的故事。
大佬本以為只要拿出0.001%的功力就可以輕鬆入職升級了,沒有想到卻遇上了變態面試官!
「看來,我需要使出我1%的功力了!」,大佬明悟道。
介紹一下作者本人,我雖名為九神,但在那場大戰中連觀戰的資格都沒有,以下的一切都是大佬小號口傳於我的。而我,只是以第一人稱口述,記錄下了那場對決的萬分之一!
1、面試開始我看到一個頭髮濃密,全身西服筆挺的30歲大叔面試官向我走來。
不經意間掃過這位大叔腕上的百達翡麗和標著「LOTOS」字樣的眼鏡。
看著對方這張好像在我長遠記憶中見過的帥氣臉龐,我突然意識到——有殺氣!
我認真的回答道:大叔你好!在Java中,一共有8種基本類型。分別是:整數類型:byte,short,int,lon;浮點數類型:float,double;字符類型:char;布爾類型:boolean。
注意:遇到面試官一定要禮貌!回答問題要有邏輯,按照種類歸類比你一口氣說出8種類型好的多。
2、在Java中(2.0-1.1 == 0.9)是true還是false?是false,因為2.0-1.1最終輸出的是0.89999999,而不是0.9。在Java中,(2.0-1.1 < 0.9)才是true。
因為在Java中浮點數值採用二進位表示,而在二進位系統中無法精準表示分數1/10。(就好像十進位沒法精準的表示1/3)。
如果想解決這個問題,就需要使用BigDecimal類而不是使用浮點數。
4、嗯,答得不錯,那你看看下面這個題的答案是什麼?為什麼會是這樣?大叔不想說話並向我丟我來一道題目:
答案是true,false,false。
因為Integer n1 = 100;這種語句實際上是自動裝箱,把int類型轉換成了int的包裝類Integer。在Integer中,Java為了提高運行效率,需要進行自動裝箱時,如果數字在一個字節內,也就是-128至127之間時,會直接使用緩存中的對象,而不是重新創建一個對象。
100在這個範圍內,所以第一個語句是true;200不在這個範圍內,所以第二個語句是false。
Java中Integer自動裝箱實際調用的是Integer.valueOf()方法,直接new一個並不是自動裝箱,而是新建了一個對象,所以第三個語句是false。
另外,在Java9之後,就不推薦使用new Integer()的做法了。
注意:講完原有知識點,帶出不同Java Version的不同,是很好地加分項。
5、有沒有辦法更改自動裝箱的範圍?可以通過修改JVM參數-XX:AutoBoxCacheMax=size來更改自動裝箱池的大小。
額,好像開始有點東西了啊!這是1級難度的問題麼?
6、嗯,小夥子看來還可以啊!那麼以下語句輸出的結果是什麼?我不假思索的回答:第一個是b,第二個是99。
因為'a'在Unicode字符集中的排序位置編碼是97,++之後自增+1變成了b,b的編碼是98,再調用x+1之後是直接被自動類型轉換為int類型,輸出99。
1級的題目就問Unicode編碼位置了,還好我是小號,這面試官誠心的吧?
7、那基本數據類型中自動類型轉換規則是什麼?是從存儲範圍小的類型到存儲範圍大的類型,也就是:byte ->short(char)->int->long->float->double這樣轉換。
8、不錯,你剛才講到了Unicode,Java中char採用的編碼方式是哪種?是UTF-16。
9、那Java為什麼會選擇UTF-16呢?因為歷史上 Java一開始選擇的是 UCS-2,是一個定長的編碼,在當時以單個碼元能表示所有字符,以下標獲取字符的開銷基本等同於在數組中索引一個字符,用起來是最方便的,多佔用的內存大小也是可以接受的。
到了後來 UCS-2 無法表示所有 Unicode 字符的時候,過渡到了兼容它的 UTF-16 上也是最自然以及遷移成本最低的選擇。
好像畫風開始不太對頭了?這是歷史題吧
10、UTF-16是怎麼實現Unicode編碼的?問道這題我感受到了面試官一陣殺氣,他是想壓住我麼?感覺1級小號不配全答對麼?
哈哈哈,幸虧我只是小號!待我用999級超凡的理解予以回擊!
於是,我鄭重言辭的說道:
這個想法很自然,我先講講設計思路。
在2個字節的Unicode字符集中,按道理能存放2的16次方,也就是65536個字符。但是為了擴容,特別的劃出了一片區域不存儲正常的字符。
這時候,只要拿兩個Unicode字符拼在一起形成4個字節,如果第一個Unicode字符對應那片本不應該存儲字符的區域,這兩個拼起來的Unicode字符就可以看成一個新的大字符。
這樣就能成倍數的擴增原有的字符集而不需要對原有的整個字符集做任何改動。還擁有看了首位Unicode字符就能判斷屬於哪個擴增類型的好處。
我再來說說具體的做法吧。
我們把Unicode中每個字符對應的16進位的值稱為代碼點(code point),並且加上前綴以示和16進位的區分,比如U+0097代表'a'。我們把擴充後的Unicode字符集劃分為17個代碼級別(code plane)。
第一個代碼級別稱為基本的多語言級別,也就是大家常說的BMP(basic multilingual plane),代碼點從U+0000到U+FFFF,其中包括了原有的經典Unicode字符集;
其餘的16個附加級別,代碼點從U+10000到U+10FFFF,這裡存放的都是輔助字符,也是擴充的部分。
UTF-16採用可變長度的編碼來表示所有Unicode的代碼點。在BMP中,每個都是2位元組字符,我們稱之為代碼單元(code unit);
而輔助字符採用一對連續的代碼單元進行編碼,其中第一個代碼單元採用的範圍正是BMP中空出的代替區域(surrogate area)中的值,即0xD800-0xDFFF這部分。
UTF-16就是通過這種可變長度的辦法來對應了Unicode編碼集中的每個字符的。
而Java中的char類型用UTF-16編碼描述一個代碼單元。
哈哈,這波面試官已經被團滅了吧!
這個回答,完全超越了教科書的回答啊!先講了設計思路,再談實現辦法,妥妥的向面試官證明自己能搞一套類似的字符集出來啊!這肯定直接拉到面試滿分了啊!
NICE!NICE!NICE!NICE!NICE!
UTF-8佔用的內存空間最小,根據碼不一樣分別佔據1~4個字節;UTF-32佔用的內存空間最大,每次都佔據4個字節。
對於超過佔用1個字節的Unicode碼時,UTF-8的因為需要運算所以速度就會比UTF-16和UTF-32慢;
對於超過佔用2個字節的Unicode碼時,UTF-16的因為需要運算所以速度就會比UTF-32慢。
因為我們日常使用的都是BMP中的碼,所以UTF-16是一個中庸的選擇。
這面試官還不死心麼?1級還問選型題?
2、面試結束面試官大叔看了一眼手腕上的百達翡麗,說時間不早了,要不先這樣吧,讓我回去等下次面試的通知。
我問道:那什麼時候下次面試呢?
「等你升到2級的時候吧!」,面試官留下這就話就走了。
這面試官如此變態麼?全對還要等我升級再面?
3、後續那大佬如何才能升級呢?據大佬透漏,需要有人給他的口述點讚達到一定數量方可升級,只有升級到2級,才能進入第二面!
這就是有幸聆聽大佬口述,我來執筆寫下這篇文章的緣由!
還不給點讚麼?沒下一篇了啊!
4、閒話在面試過程中,一般面試官都會根據面試者做過的項目為引子,引導面試者說出面試者所有會的內容,而並非隨機發問打地圖炮。
一個優秀的面試官往往是在不經意間已經知道你做的項目是否真實和你的水平。
類似本文中變態面試官持續高壓的提問式常見於年輕的面試官,覺得技術有高低,一定要壓到面試者才是勝利。
九神私以為技術只有是否匹配,並無高下之別。
有高下之別的更可能是每個人trouble shooting和理解學習的能力,招聘是case by case的事情,挖掘自身優秀的點就能進入好公司拿到高薪offer哦!
5、點關注,不迷路好了各位,以上就是這篇文章的全部內容了,能看到這裡的人呀,都是能進大廠的高端人才。
我後面會每周都更新幾篇網際網路大廠面試和常用技術棧相關的文章,非常感謝高端人才們能看到這裡。
如果這個文章寫得還不錯,覺得「九神說編程」有點東西的話 求點讚👍求關注❤️ 求分享👥 對九神來說真的 非常有用!!!
注意:博文會比公號晚一周哦!
白嫖不好,創作不易, 各位的支持和認可,就是我創作的最大動力,我們下篇文章見!