1. 程式人生 > >阿里面試經歷回顧(兩個執行緒分別列印0-100之間的奇偶數)

阿里面試經歷回顧(兩個執行緒分別列印0-100之間的奇偶數)

第一輪電話面試

年前在朋友的內推下,成功獲得了阿里的面試機會,第一輪電話面試記得是約在某一工作日的晚上進行,由於白天一直在忙於工作,確實不方便進行面試,我跟面試官說明了情況,面試官這才答應了在當天晚上8點進行面試(還是感謝阿里面試官的諒解)。當天掛完電話是無比的激動,因為之前壓根沒有想過能有面試機會,原本以為阿里對簡歷的要求比較高,不會給我機會進行面試的。當時接完電話那是一個開心的呀,心想一定要好好把握這次面試機會。

當天下班後立馬就回到住的地方,晚飯沒有吃,隨便搞了點零食吃,生怕時間趕不上,於是在那坐等面試官來電話。我就這樣坐等著時間一分分鐘過去,終於等到8點,此時手機鈴聲響了(阿里面試人的時間觀還是非常不錯的),接到電話,那頭就跟我說他是誰誰誰,負責這輪面試的,然後大家相互客氣的進行了問候下,然後面試官就開始正式的面試。第一個問題就是,讓我做一個簡單的自我介紹(這些都是套路,基本上所有面試的第一個問題都會先讓簡單自我介紹),我非常有禮貌地簡單做了下自我介紹,主要講一下自己的基本資訊情況,簡略說了下這些年待過的公司和參與過的專案。

自我介紹完後,就會對簡歷上寫的專案進行提問(一般只會問你目前做過的專案,幾年前的專案,我想應該也沒必要問了,畢竟時間隔了那麼久,誰也記不了那麼清楚),我也說了下目前做的專案的業務場景,和自己承擔的職責。

專案問完後,下面就是一系列的純技術問題,我這邊總結了下大致問我的一些技術問題,希望大家可以有所準備。

  • HashMap底層結構相關問題
  • 執行緒池的實現原理
  • JVM效能調優
  • 問我有沒有遇到過線上OOM問題,問我是如何排除並解決的
  • 用過MQ? 講一講底層實現機制
  • 設計模式相關,比如你用過哪些設計模式,然後講下UML(一般都會問)
  • 自定義一個java.lang.String 可以被載入麼?

以上是大致問我的一些技術相關問題,貌似就這個問題“有沒有遇到過線上OOM問題,問我是如何排除並解決的“ 沒有回答的很好,其他幾個都基本上沒問題。

面試官覺得問的差不多了,就問我有沒有什麼想問他的? (出於禮貌面試官都會這樣問下) ,當時我就問了下我目前應聘的這個崗位的主要負責的業務和所涉及的技術,然後面試官也很細心地對我進行解答。回答完後,就說今天這次面試就到這裡先結束了,如果有訊息會這幾天通知您。 我回答說好,謝謝,耽誤您這麼長時間,非常不好意思。(這也是一種態度和禮貌的表現)

面試官說本來面試是預計半小時的,沒想到竟然從8點面到9點多,說明面試官對我還是比較感興趣的~

總結:第一輪面試個人覺得自我表現還是不錯的,除了說話有點緊張外(還是以平常心去面對,不用太在意,這樣也許會發揮的更好),當時掛了電話,我心裡想著應該會有下一次的面試機會吧。

第二輪電話面試

過了一個週末,第二週週二收到了來自阿里的第二輪面試安排郵件,跟我當時面試後的預感差不多,不過沒想到這快;這次面試安排還是比較周全,提前告知我面試時間,記得就是年前我回家前一天,週四的下午2:00,這樣我也有一些時間做準備,不至於太突然,中間這幾天也準備了一些。為了可以準時赴約,我還特地請了一天假(總不能在公司面試吧),準備的過程中一直都比較興奮、激動,心想這次可能會問我什麼問題呢?

懷揣著激動與彭拜的心情,終於到了週四那一天,中午吃完午飯,睡了一覺,等待2點準時面試。當我等到2點的時候,並沒有電話過來,繼續等了10分鐘後,依然沒有電話過來,心裡有點不安,難道是忘了今天的面試麼?我可是特意請了一天假來面試的呢,不會吧。我當時這樣安慰自己,可能是人家面試官剛午睡完,需要緩一緩,於是乎我就繼續等待,又過了20分鐘,也就是等到2:30的時候,依然沒有電話,心想可能真的忘了這次面試的安排了,心中一絲涼意。 當天本來天氣並不怎麼好,全身還是有點微冷。坐了會兒正準備躲被子繼續睡覺的時候,突然電話鈴聲響起,拿起手機,看到來自於杭州的電話,心中無比的激動,接通了電話,聲音那一頭是一位聲音比較渾厚的男子(下文稱為傲視),聽說話的聲音,能感覺出來這次面試的人應該是招聘部門的老大,跟第一次面試的人語氣全然不同(第一次面試可以明顯感受出,問的問題都是經過實現準備並有一套流程),而這位老師談話語氣能感覺出比較隨意,下面講下這次面試的主要流程:

  1. 首先,簡單自我介紹,跟第一輪差不多
  2. 其次問專案情況
    根據是你的自我介紹和簡歷上寫的技術針對性問,比如我簡歷上有一個TPP-ORDER專案用到一個分散式任務排程框架xxl-job ,可能老師並不知道這個框架,於是就問我有那麼多開源的分散式任務排程框架,為什麼選擇這個? 其實我有了解過確實有其他的開源任務排程框架,但是當初選擇這個真的要說些什麼原因的話,我還真不知道如何去描述,當時我就說了xxl-job的幾個特點。其實這一題回答的不是很好。

  3. 再次問一些技術問題

    1 線上專案遇到過OOM異常麼,如何解決的?
    2 如何避免記憶體洩漏
    3 請講出你所知道的哪幾種記憶體溢位
    這裡可以根據jvm記憶體區域分別講講 比如堆這塊會出現堆記憶體溢位。

  4. 線上筆試

    電話裡講了半小時後,老師問我身邊有電腦沒?當時也是非常自然地回答說,有的,然後他說我給你郵箱發一個連結,給你出幾個題目。我當時心裡地第一反應就是,oh my god。還有這種操作麼? 完全沒有想到竟然有線上筆試這個幻覺。口頭上還是立馬說好的呢。 開啟QQ郵箱中的連線,是一個很簡單線上考試介面。

    打開了介面後,老師出了一套程式設計題

    程式設計題1:用兩個執行緒分別列印0-100之間的奇偶數。
    比如 有A,B兩個執行緒;
    A執行緒列印1,3,5,7,9 … 99
    B執行緒列印0,2,4,6,8 … 100

    然後控制檯輸出按順序輸出0-100, 如 0,1,2,3,4,5,…. 100

當時看到這題目立馬就有了一個思路,利用synchronized 互斥鎖,wait和notify 進行組合,經過一番思考除錯後,總算是成功實現效果,程式碼如下所示:

package com.xyq.maventest.alibaba;

/****
 * 兩個執行緒分別列印0-100之間的奇偶數
 * @author youqiang.xiong
 * <p> TODO 簡單描述此類的用途</p>
 * 2018年2月25日下午6:18:34
 */
public class ThreadPrintData {
    private static Object lock = new Object();

    private static int i = 0;
    private static int wait = 1;
    private static final int TOTAL = 100;


    public static void main(String[] args) {

        Thread thread1 = new Thread() {
            public void run() {
                while (i <= TOTAL) {
                    synchronized (lock) {
                        if (i % 2 == 1) {
                            System.out.println("thread1  " + i++);
                        } else {
                            lock.notifyAll();
                            try {
                                lock.wait(wait);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }
            }
        };

        Thread thread2 = new Thread() {
            public void run() {
                while (i <= TOTAL) {
                    synchronized (lock) {
                        if (i % 2 == 0) {
                            System.out.println("thread2  " + i++);
                        } else {
                            lock.notifyAll();
                            try {
                                lock.wait(wait);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }
            }
        };
        thread1.start();
        thread2.start();
    }
}

啟動main方法,Console列印如下結果:

這裡寫圖片描述

如結果所示,執行緒1,執行緒2分別間隔打印出0-100的奇偶數。

程式設計題2:編寫一個演算法實現倒序輸出一個字串,比如輸入hello world,輸出dlrow ollel.

這個題目實在是條件單了,即使剛學java的人都會寫了。

兩種實現方式

/* 
 * 字串反轉的兩種方法 
 */  
public class TestReverse {  
    public static void main(String[] args) {  
        String str2 = "Hello";  
        str2 = new StringBuffer(str2).reverse().toString();  
        System.out.println(str2);  

        String message = "Hello";  
        StringBuilder rev = new StringBuilder();  
        for (int i = message.length() - 1; i >= 0; i--){
            rev.append(message.charAt(i)); 
        } 
        System.out.println(rev.toString());   
    }  
}  

跟老師反饋說兩道程式設計題已編寫完成,然後老師看了會,就打電話過來問到說,你的第一道題利用synchronized 加鎖效率在高併發情況下效率會比較差 ,我思索了下確實是,然後老師問我可以進行優化麼?我當時一臉懵逼,然後支支吾吾地說,我試試看,其實當時內心本身就很緊張,加上以前實際工作中確實對於多執行緒程式設計接觸的並不多,突然問我如何優化,一下子把握給懵逼了,後來支支吾吾地說了下可以利用樂觀是,cas機制,然後他讓我寫出來,當時真的是特別緊張,臨時寫還真的不知道怎麼寫。(如果是工作中真遇到這個問題,肯定可以寫出來),在那種環境下確實就沒寫出來,後來就如實跟老師交代說,知道用什麼方法,但是現在比較緊張,狀態不好,暫時不知道怎麼寫具體的程式碼實現。後來老師回了句,哦,你工作中這塊的接觸的不多吧,我如實回答確實是,平時工作中多執行緒寫程式碼並不多。後來老師就沒有說什麼,就問我有沒有想問他的。 我這時候腦子裡立馬浮現的問題,就是您目前工作中都需要哪些技術,我說我可以往這方面多去學習,我是十分相信我的學習能力的。後來他大致說了下 他們目前所涉及的技術。 最後老師說到,這次面試的先到這裡,無論面試結果如何都會有郵件通知,然後我禮貌回答到謝謝。這次面試就此結束了。

總結: 這一輪面試的感覺還沒有第一輪面試感受好,雖然大部分的問題都能回答出來,但是回答的都不是那麼全,尤其是後面的線上程式設計題,如果當時能立馬這段程式碼進行優化的話,那麼這輪面試應該就差不多過了,自我感覺這次面試的通過率不高,雖然前後面試加起來也有1個多小時,不過心想沒出結果之前應該還是有希望的,畢竟也跟我聊了這麼久,不至於一個優化問題沒回答出來,就給我掛了吧。面試完第二天我就收拾行李回家了。

備註: 對於程式設計題1 哪位大神有優化的思路,歡迎留言。

面試結果

回家後上班的那一週的,也沒有收到任何阿里的面試反饋郵件,當時的想法是可能都快放假過年了,應該年前不會處理了。後來過完年回到公司,又過了幾天依然沒有收到阿里的郵件反饋,心想是不是真的掛了? 但是第二輪面試官跟我明確說了,不過是否通過,都會收到郵件的反饋的呢;至今沒有收到郵件,也想過是不是人家太忙了忘了,後來我還是忍不住找內推我的朋友,問了下具體面試情況,後來他等了一會兒(估計這會兒應該是去打聽我的面試情況),回覆了我:說應該是掛了,叫我繼續加油,好好修煉內功。 聽到這個回答,內心有點小失落。 不過也沒有關係了,畢竟當時面完試的時候 我早有預感,做好了心理準備,只是想得到一個明確的答案,心中也算了切一事。

收穫

雖然這次面試以失敗而告終,但是整個備戰的過程中,也讓我學到了不少東西,包括技術和態度上。 同時也認識到自己的不足,因此我會時刻在以後的生活和工作中提醒自己,一定要多看書,持續學習。因為深在IT技術這一行,如果你一直滿足於現狀,僅僅只用已有的技術做一些重複的事情,那麼你的技術水平只會停滯不前,以後等你到了中年的時候,自然就會遇到所謂的中年危機。為了在多年以後,自己還能保持競爭力,唯有一直學習。

我自己也是去年下半年意識到以前工作很多時候只是為了解決工作的問題,並沒有花太多時間去擴充自己的技術知識,當我意識到我的工作目前做的事情都是一些重複性的業務性工作時,我也會自我反思,學習是一種信仰,只要每天肯堅持一點點,日積月累,我堅信大家都能成為技術領域的大牛。

學習計劃

我從大學開始一直都是學的java程式設計開發,所以後續的學習計劃還是以深入java技術為主,畢竟我不想java還有很多未精通的,又去學習其他的語言,希望自己也能做到術業有專攻,再去了解其他的一些新技術(AI、大資料、區塊鏈、物聯網),能做到人家談這個技術的時候,你知道人家在聊什麼就可以了。

在這裡給講下我看過的書籍或者準備去看的學習書籍,希望對大家有所幫助 。

  • 深入理解Java虛擬機器:JVM高階特性與最佳實踐
  • 經典演算法大全
  • 劍指offer
  • 計算機組成與體系機構-效能設計
  • 大話設計模式
  • 阿里巴巴Java開發手冊
  • Java 併發程式設計實戰
  • 《淘寶技術這十年》完整版 帶批註
  • 經典SQL語句大全
  • Thinking in UML

雖然感覺書本有點多,其實只要每天都花時間去看,長此以往堅持下來,這些書也用不了多長時間就可以看完,過完年回來的兩天時間我就把阿里巴巴Java開發手冊 看完了,裡面分門別類講述瞭如何編寫優雅規範的java程式碼,建議大家有時間一定要去看看,再對比自己平時寫的程式碼,相信一定能從中收穫不少。