后臺開發工程師面經
2018年3月13號
浪潮一面二面
總體來說,浪潮面試很倉促,我記得是前一天晚上在公眾號上投完簡歷,然后當天晚上11點就發下通知第二天10點開始面試。從面試過程中的問題和招聘結果來看,浪潮公司需要掌握云服務技術和Java開發的人比較多。
面試中主要就是探討所做項目,針對項目,面試官提出一些問題對基礎進行考察。
云服務:OpenStack之類的,不了解。
web開發:
1. 參數綁定:有個人的項目中用到了SpringMVC,因此面試官問了他項目中參數綁定的問題。要了解參數綁定,可以先了解下幾種前后臺傳參方式,具體參考:前后臺交互之傳參方式 - 名字被占用。 - 博客園,重點了解get和post的區別。結合項目,以FindME的更新操作為例,首先要根據list查到對應修改的Id,并根據Id獲取該id所對應project全部信息,該Id參數是綁定在路徑上傳到后臺的,即 someUrl/{Id}, 這時的Id可通過 @Pathvariable注解綁定它傳過來的值到方法的參數上。此外,還有@RequestParam用于簡單類型的處理和@ModelAttribute用于綁定指定的model,例如用于add和change時候,把對應屬性的值綁定與注解參數model上。
具體參數的綁定注解和原理參考:
SpringMvc之參數綁定注解詳解 - Frank_Lei - 博客園
SpringMVC源碼之參數解析綁定原理 - 臥顏沉默 - 博客園
2. servlet生命周期:init() service() destroy()
3. Linux系統分區時哪兩個區是必須的?根分區和交換分區,一個是放系統啟動時的文件和系統配置文件,一個充當虛擬內存。此外/etc和/bin是必須放在根分區的目錄,其實還有/sbin,/dev,/lib。
美團一面
2018.3.21
1. 容器類問了兩個,HashMap()和HashSet(),前者還知道一點,后者只知道往里面放的元素不能重,可以做字符串去重工具。針對于HashMap(),先問了我些基本問題,也就是數組+鏈表,解決沖突等等,后來問到了一個底層實現方法indexFor(),具體實現如下:
static int indexFor (int h,int length){
????????return h & (length-1);
}
首先,為什么取&,其實對length取%也是可以的,但是效率會降低,因為邏輯運算比模運算時間更快(其實&運算還有別的玄機)。其次,為什么要length-1,因為Node[]數組初始大小是16,按照2^n來擴容,以16為例,即2^n-1之后從10000變為01111,用01111與h做與運算減少了碰撞的可能性,因為1與任何數與,可能為0,可能為1,而0與任何數與只能為0,那么這意味著0001,0011,0101,1001,1011,0111,1101等位置永遠都不能存放元素了,空間浪費相當大,更糟的是,在這種情況中,數組可以使用的位置比數組長度小了很多,這意味著進一步增加了碰撞的幾率,減慢了查詢的效率。前方高能哈~面試官又問了,為什么Node[]擴容是按照2^n呢?即2倍形式擴容,初始為16(2^4),擴容一次為32(2^5)…經過林哥和嘉輝的不懈努力,破解了這個謎題,我們可以這樣思考,我們認為oldcap=10000,而oldcap-1=01111,擴容之后的newcap-1=11111,這樣的設計使得擴容之后的HashMap所有節點重新進行了一次重排,而每個節點是否去重排僅僅取決于h的最高位,為0不重排,為1重排。至于重排的位置,也是由最高位決定。因此,HashMap()解決沖突的辦法首先是擴容,然后所有節點進行充分散列重排,萬不得已才會轉化為紅黑樹,可以看得出來HashMap的設計是多么的精巧,&與-1與2^n三個trick環環相扣。
2. 面試官直接問,請你解釋解釋上鎖,多線程
這道題回答的不好,因為我只知道需要哪個線程訪問什么資源的時候,就把它上鎖,用synchronized,然后說了說死鎖和生產者消費者模式。但是他想看我了解更深層次的東西,也就是底層,原話幾乎是“你說說synchronized”。
3. 數組鏈表區別
區別請看:2018 美團 春招 iOS面試分享(一面)附答案 - 簡書,面試官又問數組的查找方式,我當時一愣,數組查找方式不是直接獲取下標嘛,但是答案是:隨機查找(好好記住這四個字,說明該了解的專業術語是需要了解的),面試官問既然數組插入效率低,那你說說Java中的ArrayList是如何優化這個問題的?(倒吸一口涼氣,原來如此簡單)
4. 散列表解決沖突的方法(一定注意專業術語的表達,Hash表是HashMap的說法,散列表才是數據結構正統說法,雖然二者幾乎沒什么不同)
答:開放地址法(增量設定方法有:線性探測法,平方探測法,再散列法和偽隨機序列法)和偉大的拉鏈法+解釋。
5. 給定一個鏈表,判斷其是否有環。
設定兩個指針,一個慢,一個快,如果快的追上慢的就說明有環,面試官又問,如果快的把慢的越過去了怎么辦呢?當時的想法只是個初步想法,所以這個問題一下把我問懵,答案是不可能越過,因為運動是相對的,快慢指針的相對速度只差1,當快追慢的時候,結局就是二者可能差1步或者差2步。以慢的先走為例,假如差1步,慢的走1步,此時差兩步,快的走兩步直接遇到,假如差兩步,慢的走1步,快的追兩步,此時二者差1步,回到了第一種可能性。當然這只是快慢指針速度差1,可能后續還會討論速度差2,差3…網上還有些關于這個問題的延伸,比如環的長度,入口等等。
環長:當兩個指針在環上從第一次相遇到第二次相遇,而二者速度差1時:慢+環=快,2*慢 = 快,所以從第一次相遇到第二次相遇,慢所走的距離就是環長。
入口:二者在環上相遇時可以得到,慢=頭結點到環入口的距離+環上距離x,快=頭結點到環入口的距離+環上距離x+n倍的環長,而2*慢=快。因此可以得到,頭結點到環入口的距離=n倍的環長-環上距離x,所以令一個指針在鏈表頭結點,另一個慢指針在當前環上相遇結點,二者一起走,相遇結點即為入口。
參考:判斷單鏈表中是否有環,找到環的入口節點 - CSDN博客,數據結構面試 之 單鏈表是否有環及環入口點 附有最詳細明了的圖解 - 簡書
6. SQL語句
7. 給一個數字序列,里面有正數和負數沒有0,返回最大值。
面試官沒讓我遠程寫,但是讓我把自己的思路說清楚,比如第一層循環怎么寫,從哪到哪,聲明了什么變量,第二層……我用的是下面鏈接的第二種方法,面試官希望我能優化一下,我提出的優化方案是個很粗略的方案,因此面試官直接提出了自己的想法,即……下面鏈接的第四種方法。