這是一本我希望自己在大學就能看到的一本書。在我讀大學的時候,跟很多同學一樣也走過不少彎路:艱難地啃著計算機必修課,被里面的指針和對象搞的暈頭轉向,對i++和++i區別死活不理解,為操作系統的調度策略而抓狂,很難對專業書產生興趣,只是想著去應付考試和學分。當我們畢業后,雖然有了計算機學位和實際工作經歷,但其實還是不知道最想得到什么。我當時心中有個情節,就是希望能去最好的公司,比如Google,因為聽說那里面都是最聰明的人,有著最好的待遇和福利,做著最有影響力的事情。當我鼓起勇氣去嘗試的時候,我失敗了,并且要進入6個月的冷藏期(失去在一段時期內繼續面試的機會)。而我發現當時的面試表現是那么的稚嫩和糟糕,我開始懊惱,開始反省,開始重新準備,這樣才有了我下一個面試機會和其他的Offer。當然如果一切可以重新再來,我可以更有自信更好地發揮我的能力,也許當時的理想公司就會給我Offer。
有些朋友會認為只要能混過面試,拿到工作之后有的是時間可以繼續學習。這話聽起來有道理,但我在這里給出一個反例:我記得多年前第一份實習的任務是對某個大型應用程序進行性能測試。我不知道如何創建一個用戶界面,然后隨意定義文本字段、菜單和按鈕。我不知道如何用線程來思考,我錯誤調用整個緩存和線程池。我也不知道如何去做代碼維護,并且沒有單元測試和編寫基本的文檔,最后我還是寫了幾千行的Java代碼,這是個無法維護的巨大的類。而如果我在工作之前多一些積累和看一些代碼,或許不會那么尷尬。
也有些同學說面試中只會考沒有用的算法,這跟工作沒有任何直接關系。我同意工作中大多數情況是不會用到復雜的算法的,但如果你沒有過硬的基本功,在面對一些新情況的時候,你就很難舉一反三,靈活運用了。我記得我在第一家公司第一個項目是在一個新城市中增加新的排序選項來選擇上市的所有租房。這是一個緊急任務,上司希望我盡快熟悉代碼庫,我當時也頂著壓力,做到了一周上線。不久后,我就在總裁面前演示:我看著他點擊了某個區的房源,選擇了新的排序選項,結果花了幾分鐘去加載頁面。我之前也驗證過應該沒問題,平常只需要幾秒鐘的時間。我當時滿頭大汗,真是搞砸了。那天晚上,我思考了很久才想通。我選擇的新代碼做兩個數據庫調用需要遍歷其中的每一個,它需要的n \* log n比較的次數,而對于那個區域,其中大約有n =1000個房源,那么大約要2萬次數據庫調用才能完成一個頁面加載。當然,知道了原因,優化起來就簡單了,通過調用緩沖,把數據切成更小塊,做數據量的控制,最后性能提高了100倍,所以說系統優化是離不開算法和扎實計算機基本功的。
其實每個工程師都討厭Bug、代碼不整潔、性能太差、用戶界面不人性化等,這些都是一些技術細節,是可以慢慢體會和提高,總能找到答案去改進的。但在工作中,我應該學習和使用什么樣的技術?為什么要自動化測試?如何搭建一個產品,看起來比較靠譜?我怎么去選擇一份工作?如果我在一家大公司工作,如何跳槽到創業公司?我如何談判取得更多的薪金或獎金?什么是股票激勵?這些問題倒是更棘手,我也會在第1章給出一些介紹和輔助工具。
回看我走過的一路艱辛,我嘗試反思學到了什么,我發現其中大部分經驗都來自痛苦的反復試驗的結果。當我意識到成千上萬的面試者或者IT開發人員正在經歷同樣的試錯,犯同樣的錯誤, 我覺得應該做一些更有意義的事情:這本書就是一個工具。誠然,有些教訓只能從在自己的錯誤中學習,但我希望本書能夠幫助你從別人的經驗中獲得通向成功的捷徑。
- 內容提要
- 作者簡介
- 前言
- 我的故事,你的故事
- 現狀
- 目的
- 特色
- 第1章 簡歷、面試和Offer
- 1.1 簡歷
- 1.1.1 格式
- 1.1.2 內容安排
- 1.1.3 描述技巧
- 1.2 面試
- 1.2.1 HR
- 1.2.2 技術面試官
- 1.2.3 老板
- 1.3 Offer
- 1.4 常見問題
- 1.5 工具箱
- 第2章 數組和字符串
- 2.1 知識要點
- 2.1.1 數組
- 2.1.2 哈希表
- 2.1.3 String
- 2.2 模式識別
- 2.2.1 使用哈希表
- 2.2.2 利用哈希表實現動態規劃的思想
- 2.2.3 String相關問題的處理技巧
- 2.3 工具箱
- 第3章 鏈表
- 3.1 知識要點
- 3.2 模式識別
- 3.2.1 鏈表的基本操作
- 3.2.2 啞節點
- 3.2.3 Runner和Chaser
- 3.2.4 遍歷并處理節點
- 3.2.5 交換節點的問題
- 3.2.6 同時操作兩個鏈表
- 3.2.7 倒序處理
- 3.3 工具箱
- 第4章 棧和隊列
- 4.1 知識要點
- 4.1.1 棧
- 4.1.2 隊列
- 4.2 模式識別
- 4.2.1 通過棧實現特殊順序的讀取
- 4.2.2 “Save for later”問題
- 4.2.3 用棧解決自上而下結構的問題
- 4.3 工具箱
- 第5章 樹和圖
- 5.1 知識要點
- 5.1.1 樹
- 5.1.2 字典樹
- 5.1.3 堆與優先隊列
- 5.1.4 圖
- 5.1.5 圖的遍歷
- 5.1.6 單源最短路徑問題
- 5.1.7 任意兩點之間的最短距離
- 5.2 模式識別
- 5.2.1 利用分而治之(D&C)策略判斷樹、圖的性質
- 5.2.3 樹和其他數據結構的相互轉換
- 5.2.4 尋找特定節點
- 5.2.5 圖的訪問
- 5.3 工具箱
- 第6章 位操作
- 6.1 知識要點
- 6.2 模式識別
- 6.2.1 基本的位操作
- 6.2.2 位掩碼
- 6.3 工具箱
- 第7章 面向對象的設計
- 7.1 知識要點
- 7.1.1 設計題解答要領
- 7.1.2 模擬面試
- 7.1.3 抽象、面向對象和解耦(Decoupling)
- 7.1.4 繼承/組合/參數化類型
- 7.1.5 設計模式
- 7.2 模式識別
- 7.3 工具箱
- 第8章 遞歸和動態規劃
- 8.1 知識要點
- 8.1.1 構建從子問題到最終目標的方法
- 8.1.2 遞歸的空間與時間成本
- 8.1.3 自底向上與自頂向下
- 8.1.4 算法策略
- 8.2 模式識別
- 8.2.1 用動態規劃(自底向上)解決收斂結構問題
- 8.2.2 最長子序列類型的問題
- 8.2.3 用Memorization(自頂向下)解決收斂結構問題
- 8.2.4 用回溯法(自上而下)解決發散結構問題
- 8.2.5 用D&C策略解決獨立子問題
- 第9章 排序和搜索
- 9.1 知識要點
- 9.1.1 常見的內排序算法
- 9.1.2 常見的外排序算法
- 9.1.3 快速選擇算法
- 9.1.4 二分查找
- 9.2 模式識別
- 9.2.1 動態數據結構的維護
- 9.2.2 對于有序/部分有序容器的搜索,用二分查找
- 9.2.3 數據范圍有限、離散的排序問題
- 9.2.4 Scalability & Memory Limits 問題
- 9.3 工具箱
- 第10章 測試
- 10.1 知識要點
- 10.1.1 測試現實世界的物體、軟件或函數
- 10.1.2 故障排除
- 10.2 模式識別
- 10.3 工具箱
- 第11章 網絡
- 11.1 知識要點
- 11.1.1 網絡分層
- 11.1.2 路由
- 11.1.3 常用網絡統計指標
- 11.1.4 TCP vs. UDP
- 11.2 模式識別
- 11.3 工具箱
- 第12章 計算機底層知識
- 12.1 知識要點
- 12.1.1 進程vs.線程
- 12.1.2 上下文切換
- 12.1.3 系統調用
- 12.1.4 Semaphore/Mutex
- 12.1.5 死鎖
- 12.1.6 生產者消費者
- 12.1.7 進程間通信
- 12.1.8 邏輯地址/物理地址/虛擬內存
- 12.1.9 文件系統
- 12.1.10 實時vs.分時操作系統
- 12.1.11 編譯器
- 版權信息
- 看完了