《劍指 offer》小結

前言:

經歷這半年的洗禮,本身的綜合能力和素質都獲得了一個質的提高。c++

實話說對於將來去哪裏,即將如何發展尚未清晰的規劃。迷茫老是會有的,但這並非中止腳步的理由。找工做是在漫長的職業生涯中時常出現的轉折點,而學習和和積累是終生的任務。這裏不打算對這一段時間的各項細節和收穫展開太多討論,後續將會專門進行整理。git

本文主要是對《劍指 offer》這本面試經典進行一個小結,也是將來繼續堅持刷題的一個開端。程序員

在準備面試過程當中手寫 bug free 代碼的環節是必不可少的。本人並不是 ACM 出身,雖然說在學校基礎課程學得還不錯,但對於刷題並沒有太多經驗,一開始仍是吃力的。慢慢的發現這一過程仍是挺有意思的,雖然校招找工做已結束,但這刷算法題會成爲我新的愛好。最近將《劍指 offer》這本經典的面試寶典梳理了一遍,並實現和整理了書中的全部題目,並在「牛客網」上提交測試以保證代碼的正確性。github

平時有時間也能夠刷一刷 leetcodehihocoder,不少題目思考起來仍是頗有意思的。對於其餘的課本,我以爲《算法導論》《編程珠璣》《編程之美》都是不錯的經典教材,若是之後有時間也會一一對這幾本書進行總結。面試

對於刷題,談談個人幾點感覺:算法

  1. 熟練一門編程語言很重要,這決定了你能不能將 idea 儘快實現並印證。在一開始能夠先寫一些 easy 的題,主要是將本身的編程語言練熟。本人主要使用 c++ 實現,其實算法涉及的結構不是不少,stl 基本就能夠很好的 cover。
  2. 凡事開頭難,堅持老是會有收穫的。我建議刷題要有一個持續的過程,不要間斷,最好一段時間集中攻克一件事情。好比 x 天完成一本書,或者一塊內容,這樣有助於集中精力突破。若是三天打魚兩天曬網,每次撿起來都很吃力,會造成惡性循環。題目刷多了之後會培養出感受和思考問題的思路。
  3. 不管簡單與否都要思考清楚再開始寫代碼。分析題目時能夠將問題進行分解,還能夠藉助實例,作圖抽象等方法幫助理解。
  4. 注意細節,寫 bug free 的代碼(應該成爲一種追求)。實現代碼過程當中應該分析好輸入輸出,考慮好特殊狀況和邊界條件等。好比字符串轉換成整數須要考慮:不合法輸入,溢出等狀況。使用指針時刻注意是否爲空的判斷等。
  5. 優美,魯棒的高質量代碼。不只僅是追求完成功能,還應該對代碼的佈局,變量名見名見意,關鍵邊界條件的檢查等。代碼是程序員交流的語言,所以應該寫得優美
  6. 重複檢查,人腦 debug。不管是否在手寫代碼的環境中,寫完代碼都應該養成重複 review 的習慣,本身跑幾個測試用例,肯定沒有問題以後再把你代碼交給面試官。
  7. 沒有完美的代碼,注意溝通完成知足需求的代碼。每個程序均可以當作是輸入到輸出的映射過程,而輸入和輸出老是有不少可能的,咱們一個程序不可能 cover 掉大千世界,函數 function,也能夠叫作「功能」,即完成必定任務的函數,這就須要咱們經過溝通去了解用戶的意圖,將問題抽象,並基於某些假設去完成這樣的 function。
  8. 解決問題的方法老是多樣的。無論是作題仍是平時練習,在完成任務的基礎上應該還要發散性思考,一個題目的不一樣解法,類似題目的解法,類似場景的結局等。
  9. 在進行時間和空間複雜度分析時,要注意考慮實際使用的語言,其內置數據結構或函數的複雜度會影響你實際程序的複雜度。好比 C++ 中 map 和 unordered_map,set 和 unordered_set 的區別等。
  10. 一味的 practice,還要適時的總結和 review 才能及時的查漏補缺,讓本身能更好的成長。

下面是課本中的一些總結,其實主要是經典語錄。因爲本人平時很喜歡記錄一些大師/大神們的話,所以在總結中也是重點摘抄了不少大牛們的切身感悟和體驗。有時候看看不只是一種學習更是一種前人的激勵。編程

第1章:面試的流程

面試官談面試:

「對於初級程序員,我通常會偏向考察算法和數據結構,看應聘者的基本功;對於高級程序員,我會多關注專業技能和項目經驗」——何幸傑(SAP,高級工程師)設計模式

「應聘者要事先作好準備,對公司近況、項目狀況有所瞭解,對所應聘的工做真的頗有熱情。另外,應聘者還要準備好合適的問題問面試官。」——韓偉東(盛大,高級研究員)api

「應聘者在面試過程首先要放鬆,不要過於緊張,這有助於後面解決問題時開拓思路。其次不要急於編寫代碼,應該先了解清楚所要解決的問題。這時候最好先和麪試官多作溝通,而後開始作一些總體的設計和規劃,這有助於編寫高質量和高可讀性的代碼。寫完代碼後不要立刻提交,最後本身review並藉助一些測試用例來走幾遍代碼,找出可能出現的錯誤。」—— 堯敏(淘寶,資深經歷)安全

「‘神馬’,都是浮雲,應聘技術崗位就是要踏實寫程序。」——田超(微軟,SDE II)

面試

面試的三種形式:

1.電話面試(聽不清楚時要勇於說pardon)

2.共享桌面遠程面試(最關心的應聘者的編程習慣以及調試能力,幾種編程習慣:思考清楚再開始編碼,良好的代碼命名和縮進對齊習慣,可以單元測試。)

3.現場面試 (準備:規劃好路線並估算出行時間,準備好得體的衣服,注意面試邀請函裏面的面試流程,準備幾個問題。面試:面試官經過應聘者的語言和行動,考察他的溝通能力、學習能力、編程能力等綜合實力。)

面試的是三個環節:

1.行爲面試(5~10min,過一遍簡歷內容)

1.1 自我介紹30s-1m

主要學習、工做經歷以及意向,面試官若對某些細節感興趣會提問

1.2 項目經歷(注意「參與」vs 「負責」):STAR模型描述

  • situation(簡短的項目背景)
  • task(完成的任務)
  • action(爲了完成任務作了哪些工做,怎麼作的)
  • result(本身的貢獻,用數字說話,多少功能?優化後提升百分比?修復了多少個bug?)

    例子:Winforms是微軟.NET中一個成熟的UI平臺(Situation)。本人的工做是在添加少許新功能以外主要負責維護已有的功能(Task)。新的功能主要是讓Winforms的控件的風格和Vista, Windows 7 的風格保持一致。在維護方面,對於較難的問題我用WinDbg等工具進行調試( Action)。在過去兩年中我總共修改了200個Bug(Result)。
    常見問題:(1)你在該項目中碰到的最大的問題是什麼,你是怎麼解決的?(2)從這個項目中你學到了什麼?(3)何時會和其餘團隊成員(包括開發人員、測試人員、設計人員、項目經理等)有什麼樣的衝突,大家是怎麼解決衝突的?
    要作好準備!!!!
    小提示:在介紹項目經驗(包括簡歷和口述)時,應聘者沒必要詳述項目的背景,而要突出介紹本身完成的工做以及取得的成績。

1.3 應聘者掌握的技能(注意「瞭解」 vs 「熟悉」 vs 「精通」):

瞭解:對某一個技術知識上過課或看過書,但沒有作過實際的項目。(一般不建議在簡歷中列出只是膚淺地瞭解一點的技能,除非這項技術應聘的職位的確須要。)

熟悉:(大多狀況下使用)在實踐項目中適用某一項技術已經有較長的時間,經過查閱相關的文檔能夠獨立解決大部分問題,咱們就熟悉它了。對於應屆畢業生而言,畢業設計所用到的技能;對於已工做過的,在項目開發過程當中所用到的技能。

精通:對一項技術駕輕就熟,在項目開發過程當中當同窗或同事向咱們請教這個領域的問題咱們都有信心也有能力解決。(應聘者不要試圖在簡歷中把本身修飾成「高人」而輕易適用「精通」,除非本身可以很輕鬆地回答這個領域裏的絕大多數問題,不然就會拔苗助長。)

1.4 回答爲何跳槽:

瞭解應聘者的性格,能夠大膽的回答本身真實的想法,但也不能想說什麼就說什麼,以避免給面試官留下負面的印象。

避免一下幾個緣由:老闆太苛刻,同事太難相處,加班太頻繁,工資過低。

筆者在面試的時候,一般給出的答案是:如今的工做作了一段時間了,已經沒有太多的激情了,所以但願尋找一份更有挑戰的工做。而後具體論述爲何有些厭倦如今的職位,以及面試的職位我爲何會有興趣。

第一次跳槽(從Autodesk -> 微軟):我在Autodesk 開發的軟件Civil 3D 是一款面向土木行業的設計軟件。若是我想在如今的職位上獲得提高,就必須增強土木行業的學習,可我對諸如計算土方量、道路設計等沒有太多興趣,所以出來尋找機會。

第二次跳槽(從微軟->思科):我在微軟的主要工做是開發和維護.NET的UI平臺Windows。因爲Windows已經很是成熟,不須要添加多少新功能,所以個人大部分工做都是維護和修改BUG。兩年下來,調試的能力獲得了很大的提升,但長期如此本身的軟件開發和設計能力將不能獲得提升,所以想出來尋找能夠設計和開發系統的職位。同時,我在過去幾年裏的工做都是開發桌面軟件,對網絡瞭解甚少,所以但願下一個工做能與網絡相關(思科是網絡公司)。

2.技術面試 (40~50min)

5種素質:紮實的基礎知識(編程語言、數據結構、算法等)、能寫高質量的代碼(正確的、完整的、魯棒的)、分析問題時思路清晰(思路清晰分析和解決複雜問題)、能優化時間效率和空間效率(從時間和空間角度優化算法)、學習溝通等各方面的能力(溝通能力、學習能力和發散思惟能力)。

3.應聘者提問(5~10min)

爲每一輪面試準備2~3個問題。至少要問一兩個問題。

不要問的問題:(1)不要問和本身的職位沒有關係的問題,好比問「公司將來五年的發展戰略是什麼?」(2)不要問薪水,等過了技術面到HR面再說。(3)不要當即打聽面試結果。

推薦問的問題:與招聘職位或者項目相關的問題,若是這類問題問得很到位,那麼面試官就會以爲你對應聘的職位很感興趣。從兩個方面收集信息:(1)面試前要作足功課,到網上收集一些相關信息,作到對公司成立時間、主要業務、職位要求瞭然於胸;(2)面試過程當中留心面試官說過的話。
好比:如何對新員工進行培訓?須要掌握什麼樣的知識?

第2章:面試須要的基礎知識

面試官談基礎知識

c++的基礎知識,如面向對象的特性、構造函數、析構函數、動態綁定等,可以反映出應聘者是否善於把握問題本質,有沒有耐心深刻一個問題。另外還有經常使用的設計模式、UML圖等,這些都能體現應聘者是否有軟件工程方面的經驗。—— 王海波(Autodesk,軟件工程師)

對基礎知識的考察我特別重視c++中對內存的適用管理。我以爲內存管理是c++程序員特別要注意的,由於內存的適用和管理會影響程序的效率和穩定性。—— 藍誠 (Autodesk, 軟件工程師)

基礎知識反映了一我的的基本能力和基礎素質、是之後工做中最核心的能力要求。我通常考察:(1)數據結構和算法;(2)編程能力;(3)部分數學知識,如機率;(4)問題的分析和推理能力。 —— 張曉禹(百度,技術經理)

我比較重視四塊基礎知識:(1)編程基本功(特別喜歡字符串處理這一類的問題);(2)併發控制;(3)算法、複雜度;(4)語言的基本概念。 —— 張珺(百度,高級軟件工程師)

我會考察編程基礎、計算機系統基礎知識、算法以及設計能力。這些是一個軟件工程師的最基本的東西,這些方面表現出色的人,咱們通常認爲是有發展潛力的。—— 韓偉東(盛大,高級研究員)

(1)對os的理解程度。這些知識對於工做中常遇到的內存管理、文件操做、程序性能、多線程、程序安全等有重要幫助。對於os理解比較深刻的人對於偏底層的工做上手通常比快。(2)對於一門編程語言的掌握程度。一個熱愛編程的人應該對某種語言有比較深刻的瞭解。一般這樣的人對於新的編程語言上手也比較快,並且理解比較深刻。(3)經常使用的算法和數據結構。不瞭解這些的程序員基本只能寫寫「hello world」。 —— 陳黎明(微軟, SDE II)

推薦的c++書籍:

《Effective C++》, 《C++ Primer》, 《Inside C++ Object Model》, 《The C++ Programming Language》

基礎知識:

編程語言 + 數據結構 + 算法和數據操做

第3章:高質量的代碼

面試官談代碼質量

通常會考察代碼的容錯處理能力,針對一些特別的輸入會詢問應聘人員是否考慮,如何處理。不能容忍代碼只是針對一種遐想的‘正常值’進行處理,不考慮異常情況,也不考慮資源的回收等問題。 —— 殷焰(支付寶,高級安全測試工程師)

若是是由於粗心犯錯,能夠原諒,由於畢竟面試的時候會緊張;不能容忍的是,該掌握的知識點卻沒有掌握,並且提醒了還不知道。好比下面的:double d1, d2; .... if(d1 == d2) ... —— 馬凌洲(Autodesk, Software Development Manager)
(解釋:猶豫精度緣由不能用等號判斷兩個小數是否相等)

最不能容忍功能錯誤,忽略邊界狀況。 —— 尹彥 (Intel, Software Engineer)

若是一個程序員連變量、函數命名都毫無章法,解決一個具體問題都找不到一個最合適的數據結果,這會讓面試官印象大打折扣,由於這個只能說明他程序寫得太少,不夠熟悉。—— 吳斌 (NVidia, Graphics Architect)

我會從程序的正確性和魯棒性兩方面檢查代碼的質量。會關注對輸入參數的檢查、處理錯誤和異常的方式、命名方式等。對於沒有工做經驗的學生,程序正確性以外的錯誤基本都能容忍,但通過提示後但願可以很快解決。對於有工做經驗的人,不能容忍考慮不周到、有明顯的魯棒性錯誤。 —— 田超 (微軟,SDE II)

代碼質量

代碼的規範性: 清晰的書寫、清晰的佈局、合理的命名

代碼的完整性: 3個方面保證代碼完整性:功能測試、邊界測試、負面測試 (溢出、遞歸正確退出、不合法的輸入)。3種錯誤處理方法:返回值、全局變量、異常

. 優勢 缺點
返回值 和系統api一致 不能方便地適用計算結果
全局變量 可以方便地適用計算結果 用戶可能忘記檢查全局變量
異常 能夠爲不一樣出錯緣由定義不一樣異常類型,邏輯清晰明瞭 有些語言不支持異常,拋出異常時對性能有負面影響。

代碼的魯棒性:採起防護式編程、處理無效的輸入

第4章:解決面試題的思路

面試官談面試思路

編碼前講本身的思路是一個考查指標。一個合格的應聘者應該在他作事以前明白本身要作的事情到底是什麼,以及該怎麼作。一開始就編碼的人員,除非後面表現很是優秀,不然很容易通不過。 —— 殷焰(支付寶,高級安全測試工程師)

讓應聘者給我講具體的問題分析過程,常常會要求他證實。 —— 張曉禹(百度,技術經理)

我的比較傾向於讓應聘者在寫代碼以前解釋他的思路。應聘者若是沒有想清楚就動手自己就不是太好。應聘者能夠採用舉例子、畫圖等多種方式,解釋清楚問題自己和問題解決方案是關鍵。 —— 何幸傑(SAP,高級工程師)

對於比較複雜的算法和設計,通常來說最好是在開始寫代碼前講清楚思路和設計。 —— 堯敏(淘寶,資深經理)

喜歡應聘者先講清思路。若是覺察到方案的錯誤和漏洞,我會讓他證實是否正確,主要是但願他能在分析的過程當中發現這些錯誤和漏洞並加以改正。 —— 陳黎明(微軟,SDE II)

喜歡應聘者在寫代碼以前先講思路,舉例子和畫圖都是很好的方法。 —— 田超(微軟, SDE II)

複雜問題解決思路

畫圖 、舉例子 、 分解

第5章:優化時間和空間效率

面試官談效率

一般針對一些senior的candidates會問一些關於時間、空間效率的問題,這可以體現一個應聘者較好的編程素養和能力。 —— 劉景勇(Autodesk, 軟件工程師)

面試時通常會直接要求空間和時間複雜度,這二者都很重要。 —— 張珺(百度,高級軟件工程師)

咱們有不少考查時間、空間效率方面的問題。一般二者都給應聘者限定,而後讓他給出解決方案。 —— 張曉禹(百度,技術經理)

只要不是特別大的內存開銷,時間複雜度比較重要。由於改進時間複雜度對算法的要求更高。 —— 吳斌(NVidia, Graphics Architect)

空間換時間仍是時間換空間,這要看具體的題目了。對於普通的應用,通常是空間換時間,由於一般用戶更關心速度,並且通常有足夠的存儲空間容許這麼作。但對於如今的通常嵌入式設備,不少時候空間換時間就不現實了,由於存儲空間太少了。 —— 陳黎明 (微軟, SDE II)

一些小提示

c/c++程序員養成採用引用(或指針)傳遞複雜類型參數的習慣。若是採用值傳遞的方式,從形參到實參會產生一次複製操做。

循環和遞歸。循環通常效率較高,遞歸通常較爲簡潔。遞歸須要適用函數棧,嚴格來講分析的時候要考慮。
展示敏捷的思惟能力和追求完美的激情。(先給出直觀的辦法,而後繼續優化)

第6章:面試中的各項能力

面試官談能力

應聘者可以禮貌平和、不卑不亢地和麪試官交流,邏輯清晰、詳略得當地介紹本身及項目經歷,談論題目時可以發現問題的細節並向面試官進行詢問,這些都是比較好的溝通表現。對本身作的項目可以瞭解很深刻、對面試題可以快速尋找解決方法是判斷應聘者學習能力的一個方法。這兩個能力都很重要,基本可以起到一票否決的做用。 —— 殷焰(支付寶,高級安全測試工程師)

有時候會問一些應聘者不是很熟悉的領域,看應聘者在遇到難題時的反映,在他們回答不出時會有人員提供解答,在解答過程當中觀察他們的溝通能力及求知慾。 —— 朱麟(交通銀行,項目經理)

溝通能力其實整個過程都在考覈,包括詢問他過往的經歷,也一般會涉及溝通能力。學習能力是在考查算法或者項目經驗過程當中,經過提問,尤爲是一些他沒有接觸過的問題來考覈的。溝通能力和學習能力很重要,在某種程度上這些都是潛力。若是應聘者溝通能力不行、難以合做,咱們不會錄取。 —— 何幸傑(SAP,高級工程師)

讓其介紹過往項目其實就是在考查溝通和表達能力。學習能力經過問其看書和關注什麼來考查。溝通能力、學習能力對最終面試結果會有必定的影響。對於資深的應聘者,影響要大些。—— 韓偉東(盛大,高級研究員)

應聘者會被問及一些需求不是很明確的問題,解決這些問題須要應聘者和麪試官進行溝通,以及在講解設計思路和代碼的過程當中也須要和麪試官交流互動。溝通及學習能力是面試成績中關鍵的考查點。 —— 堯敏(淘寶,資深經理)

溝通、學習能力就是看面試者可否清晰、有條理地表達本身,是否會在本身所獲得的信息不夠的狀況下主動發問澄清,可否在獲得一些暗示以後迅速作出反映糾正錯誤。 —— 陳黎明(微軟,SDE II)

綜合能力

編程能力、溝通能力、學習能力、知識遷移能力、抽象建模能力、發散思惟能力....

第7章:題目和源碼

https://github.com/hfl15
相關文章
相關標籤/搜索