首先來看一幅圖:
![面試了這麼多人,我總結了這些](http://p2.ttnews.xyz/loading.gif)
其實這幅圖一直在鞭策著我,很多人專業技能與工作年限不匹配,
對於那個工作了9年的面試者,我印象很深刻,因為最開始拿到簡歷的時候,我一摸:"這簡歷,好厚啊!"再一看,工作9年。於是我去找了我的領導,我說:"這人我應該沒法面試,我工作經驗都才3年,這哥們是我的3倍啊。咋面?"領導說:"沒事,你先去聊聊,怕什麼,就當是技術交流,別當成面試。"
面試的過程中我們聊的技術問題,他都沒有回答的很好,他的技能就像一塊大平板,一眼望去,什麼都會一點,但是稍微一深入探討,就兩眼一抹黑了。
面試的最後,我直接給他說:"在整個面試的過程中,其實你有些問題回答的是不太好的,可能今天我們的面試就到這裡了,但是我還想請問你一個問題,你可以不回答。你工作了9年了,應該有很多行業內的朋友呀,為什麼沒有內推呢?而且你的技術能力和你的工作年限有點不太匹配。"
他回答了我,大概的意思是這樣的:
我剛參加工作的時候,計算機行業還沒那麼火,大多數都是傳統公司,所以我一直就在傳統行業裡面,屬於比較內向的人,也沒有刻意的去積累人脈。
期間換了幾家公司,沒有一家是真正意義上的互聯網科技公司,我也一直是做開發工作。
最後的這家公司是把我辭退了,辭退之前,我還是一個底層的老員工。
但是我努力想往管理崗發展,但是最終不得人意。
由於最近幾年一直想往管理方向發展,更多的是注重業務了,家庭方面的事情也越來越多,有時會影響工作。
技術方面就有點停滯不前了。最終導致這樣的局面。
聽了之後,我說:
你是我的前輩,我很尊重你,但是我從我從業三年的角度再加上你剛剛的面試表現來說,你說的這是一部分原因,而且不是主要原因。我覺得主要原因是,對於技術你失去了追尋的態度。在過去的這幾年裡面,你只要對於每次碰到的問題,稍微深入地研究一下,思考一下,整理一下,然後再找一項技能深挖下去,日積月累下來,今天的結果應該會大不一樣。
我理解你,也許是在家庭和工作的雙重壓力下,迷失了方向。
後來,我把他送到公司門口,他已經走出去了,又轉過身來和我握了一下手,他握的很用力,說:"謝謝!"
我在面試結果描述那一欄寫的是:
此人專業技能與工作年限不匹配。不建議進入下一輪面試。
我沒考過研,所以我沒有話語權說應該怎麼去考研。但是我建議有能力的話可以考研。多的不能再說了,放一張圖吧。僅供參考。
![面試了這麼多人,我總結了這些](http://p2.ttnews.xyz/loading.gif)
但是很不幸,你可能和我一樣,沒有機會考研了,和同事之間有一道不可逾越的學歷帶來的鴻溝。那麼你只有拼命的學習,瘋狂的汲取知識,對技術保持求真的敬畏之心,學歷幹不過別人已成定局,但是你技術牛逼,那就能讓鴻溝變窄。現在學習的渠道這麼多,知識全在網上,觸手可及。就看你願不願意把自己的手,從追劇、遊戲、綜藝、發呆中抽出來。畢竟一個人最多隻有2隻手。
下面我以面試中的實際問題給大家建議吧!
基礎不牢,地動山搖 --- 集合
有一個面試者也說他熟悉集合,我問他:
為什麼我們建議在定義HashMap的時候,就指定它的初始化大小呢?
正確的回答是:
在當我們對HashMap初始化時沒有設置初始化容量,系統會默認創建一個容量為16的大小的集合。當HashMap的容量值超過了臨界值(默認16*0.75=12)時,HashMap將會重新擴容到下一個2的指數冪(16->32)。HashMap擴容將要進行resize的操作,頻繁resize,會導致降低性能。
你要是能補充一句:
HashMap是線程不安全的,它的不安全就體現在resize的時候,多線程的情況下,可能會形成環形鏈表,導致下一次讀取的時候可能會出現死循環。
要能再說說畫畫,具體是怎麼死循環的,那就很不不錯了。
然而他說:"這個我不太清楚,我用的時候沒有指定過大小,但是我知道默認大小是16。"
當他這樣回答的時候,我大概就判斷他可能只是看過幾個集合相關的面試題,並沒有進行過深入的研究,遠達不到熟悉的標準。
我說的熟悉是禁得住比較深入的探討。
可能他理解的熟悉是熟悉的使用吧。
我準備引導他,看看他自己通過幾個題,能不能聯繫起來,然後回答這個問題,所以我接著問:
1.那HashMap什麼時候擴容呢?
2.擴容到多少?
3.怎麼擴容呢?
參考答案:
1.添加元素的時候會檢查容器當前元素個數。當HashMap的容量值超過了臨界值(默認16*0.75=12)時擴容。
2.HashMap將會重新擴容到下一個2的指數冪(16->32)。
3.調用resize方法,定義長度為新長度(32)的數組,然後對原數組數據進行再Hash。這個過程是一個性能損耗點。
我是想先問擴容,再問擴容帶來的問題。
因為會帶來問題,所以我們就儘量減少擴容。
為了減少擴容,在我們已經知道集合具體多大,或者有個預估值的情況下
就設置一個初始化大小就好了。
我想這樣引導他,但是他...
結果他說:"當集合大小大於默認大小16的時候,會擴容,擴容的大小是原來的1.5倍。具體這麼擴容的我不太清楚,我記得好像是會新建一個集合,把原集合拷貝過去"。(注意這是個錯誤回答!!!)
當他說完之後,氣氛突然尷尬了起來。很明顯,他把ArrayList和HashMap的擴容記錯了,基礎不牢的表現。當時我內心就有一個大大的問號:你不是說你熟悉集合嗎?
基礎不牢,地動山搖 --- 線程
多線程編程,這是基礎且關鍵的技術吧?
因為是應屆生,在學校裡面學了各種各樣的語言。所以面試的時候我會問面試者:你的主要開發語言是什麼?
只要面試者說,他的主要開發語言是java。那我就會問線程池:
瞭解JDK Executors線程池嗎?
知道JDK提供了哪些默認的實現嗎?
看過阿里巴巴java開發手冊嗎?知道為啥不允許使用默認的實現嗎?
你們沒有用默認的吧?那來介紹一下你們自定義線程池的幾個常用參數唄?
你這個幾個參數的值是怎麼得來的呀?算出來的?怎麼算出來的?
好,現在我們有一個自定義線程池了,來說一下你這個線程池的工作流程唄?
那你這個線程池滿了怎麼辦呀?拒絕?咋拒絕?有哪些拒絕策略呢?
別緊張,隨便說兩個就行。
......
(這裡不作回答,如果你不太清楚的話。建議去了解一下。)
大多數面試者,在我問到有哪些默認實現的時候,他們就能自動的把下面的問題都回答的差不多。
但是有幾個面試者,他們的回答是:僅僅是用過默認實現,具體內部細節沒有了解。
那我就會覺得,額,怎麼說呢,這感覺不好說,你自己的體會吧。
我問的另外一個關於線程池的問題,我面試的15位,沒有一位回答正確,但是我都告訴他們:沒關係的,這個回答不上來的話,不減分,下去可以瞭解一下。
我問的是:
一個線程池中的線程異常了,那麼線程池會怎麼處理這個線程?
然後,關於線程這塊,我還會問一個題,這題是我們的宣講會的初選題,他們都做過:
<code>對於方法sleep() 和wat() , 描述錯誤的是()
A、sleep() 暫停線程, 但監控狀態仍然保持, 結束後會自動恢復
B、sleep() 是線程類Thread的方法, wait() 是object類的方法
C、wait() 後進入等待鎖定池, 只有針對此對象發出notify方法後獲得對象鎖進入運行狀態
D、sleep() 不釋放對象鎖, wait() 放棄對象鎖/<code>
大多數面試者,看了十幾秒就說選C,並且告訴我理由。
有個面試者他看了一分鐘,思考的很認真的樣子,然後說他選擇D選項,因為選項內容說反了。
我說,你確定嗎?
他說:我很確定。
我說:下去之後再瞭解一下吧。
有的面試者看了一分多鐘後,沒給出答案,由於面試時間寶貴,我就說:這樣吧,這題選C。你告訴我C為什麼錯了呢?
這個時候,大多數面試者都會給出一個正確的答案:
wait()方法會導致線程放棄對象鎖,進入等待此對象的等待鎖定池,
只有針對此對象調用notify()方法或者notifyAll()方法後本線程才進入對象鎖定池準備獲取對象鎖進入運行狀態。
注意是準備獲取對象鎖進入運行狀態,而不是立即獲得。
再看一下《Java併發編程的藝術》裡面是怎麼說的,有這樣一段話:
《Java併發編程的藝術》第100頁
但是有的面試者,對於C為什麼錯了,還是給不出詳細分析。
這裡反映出了兩個問題:
第一個問題是:基礎不牢,地動山搖。
第二個問題是:這題他們都做過,但是做完了就做完了,甚至不知道自己哪些題對,哪些題錯。沒有加以總結。這是不好的表現。
概念模糊,似是而非
另外一個面試者回答說他對Redis瞭解的比較多一點,項目裡面用過。
我問了他:"Redis你是拿來做緩存嗎?有沒有考慮過緩存擊穿、緩存穿透、緩存雪崩的情況呢?"。
他說:"Redis在我的這個項目裡面,就是拿來做緩存的。你剛剛說的那幾個概念,我有聽說過。但是我們的項目還沒遇到這樣的問題。"。
我說:"明白,沒有關係,你給我介紹一下相關概念和對應的解決方案吧"。
他說:"這個不太清楚。"
好的,我想可能是關於Redis的理論知識比較強吧。我接著問:"那你給我介紹一下Redis的兩種持久化策略唄?"
他倒是說了一些上來,但是整個回答聽起來,概念模糊,似是而非。需要我主動去找他回答裡面過濾掉一些口水話,提取到幾個關鍵詞:AOF,RDB,異步刷盤,可配置,命令追加.....
而且說著說著卡殼了,有一種背課文的感覺。
我理解,這個程度,不能叫做熟悉。
送分失敗,大失所望
面試的最後幾分鐘,我都會問一個問題:最近在看什麼技術相關的書籍或者文章嗎?
典型的送分題呀。這題很難回答嗎?你甚至可以說,學業繁忙,主要看的還是課堂上的東西。
這題你不回答,不減分。回答的好可以加分,回答的不好會減分。
有一個哥們回答說:我最近在看《深入理解Java虛擬機》。
我一聽,有點意思,可以探討一下了。這書我前後加起來看了五次,
我問他:"你看了這本書後印象最深的點有哪些呢?"
他說:"我印象最深的是垃圾回收會導致用戶線程停止。因為我之前遇見過這樣的問題,我的程序經常跑著跑著就停了,我當時不知道為什麼。後來瞭解到,是垃圾回收的時候導致的用戶線程暫停。"
我聽到他這個描述我想的是:那這個程序有問題呀,為什麼會這麼頻繁且長時間的進行FullGC呢。
於是,我問他:"你是怎麼排查這個問題的呢?"
他說:"不是我解決的,是實驗室其他的同學解決的,同學給我說是垃圾回收的時候導致的問題。我最近看《深入理解Java虛擬機》的時候也聯想到了這個問題。"
聽到這裡我已經有點失望了,他遇到了問題沒有主動去解決問題。同學告訴他原因了,他也沒有繼續深究下去。
算了,還是回到書上去吧。我問:jvm在回收哪塊區域或者進行什麼操作的時候會出現你剛剛說的暫停(Stop The World --> STW)用戶線程的情況呢?
其實書上寫的很明確了。老年代進行Full GC的時候會STW,而老年代常用的垃圾收集器是CMS:
《深入理解Java虛擬機(第二版)》第81頁
更深一層次的原因書上也寫了:
《深入理解Java虛擬機(第二版)》第72頁
而他的回答是:不太清楚。
失望。
你要說你沒看過回答不上來,我還可以理解。但是你說你最近在看,卻沒有回答上來。那我可以理解為:你僅僅是看了,卻沒有留下任何的東西嗎?
而且我沒有問你類似於字節碼解讀、不常用參數介紹這樣的刁鑽問題吧。
不是我在難為你,是你在難為你自己。
失望。
其他的表現
除了上面說的這些情況,當然還有其他的一些表現。
比如說簡歷上寫了,熟悉單例模式。我讓手寫個線程安全的單例。然後他寫了一個雙重檢查鎖定。卻忘了加volatile關鍵字。
我說你考慮過重排序嗎?說到重排序你想到了java的哪個關鍵字呢?
他說想到了volatile。
我說那你這裡為什麼沒有加volatile關鍵字呢,他說這裡不需要加。
簡單的解釋了幾句後我給他說去看看《Java併發編程的藝術》這本書,裡面專門說到了這個問題。
《Java併發編程的藝術》第71頁
通過前面介紹的校招面試出現的一些問題,可以看到,我面試的時候已經盡力把主動權交給面試者了,但是有的面試者沒有好好把握。
但是隻要能好好把握這個主動權,把自己儘量多的展現出來,讓我知道你是有技術且是熱情的。語言表達清楚,動作不太浮誇,態度不卑不亢,表情輕鬆自然。
現在很多人面試之前都喜歡看一些面試技巧相關的東西。這沒有問題,我自己也看。
但是面試技巧只是錦上添花,你的真實實力才是錦上添花的對象。
在對象還不夠堅固的情況下,應該把花在錦上添花的時間,花到加固對象的時間上。
在絕對的實力面前,任何的錦上添花都會顯得蒼白無力。
閱讀更多 湛神帶你寫代碼 的文章