大家好,我是小北。
寫公眾號(hào)以來有很多同學(xué)向我提問,問題基本都是大同小異,核心就是剛轉(zhuǎn)到 CS 或者剛上大一不知道怎么學(xué)編程,還在背代碼、背語句......
所以今天聊聊計(jì)算機(jī)專業(yè)的學(xué)習(xí)以及一個(gè)升級(jí)打怪路線。
在這分享一下我學(xué)習(xí)過程中整理的書籍、面經(jīng)、博客等,不是在網(wǎng)上那種打包下載的,而是自己需要學(xué)到某個(gè)方向知識(shí)的時(shí)候,去挨個(gè)找的,最后匯總而成。
有需自取: 計(jì)算機(jī)必看經(jīng)典書單(含下載方式)
我一直的觀點(diǎn)就是,在具備基礎(chǔ)之后,學(xué)習(xí)任何新東西,都要抓住主線,突出重點(diǎn)。
對于關(guān)鍵理論的學(xué)習(xí),要集中精力,速戰(zhàn)速?zèng)Q。
而旁枝末節(jié)和非本質(zhì)性的知識(shí)內(nèi)容,完全可以留給實(shí)踐去零敲碎打。
戰(zhàn)線拉得越長學(xué)習(xí)效果越不好。
就是核心內(nèi)容,就是不會(huì)這些東西,你就不能算懂XX,比如 C++,我覺得核心就是 C 系的語法(if for那種)+ 類、繼承、虛函數(shù) + STL + RAII
如果 C++11,那就還要加上 auto、右值引用、lambda 這些。
其它類似怎么輸入輸出、怎么讀取文件、map、vector 有哪些方法都屬于支線,用到的時(shí)候再去學(xué)也無妨。
原因很簡單,對于重點(diǎn)知識(shí),只有集中學(xué)習(xí)其理論,才能確保體系性、連貫性、正確性,而對于那些旁枝末節(jié),只有邊干邊學(xué)能夠讓你了解它們的真實(shí)價(jià)值是大是小,才能讓你印象更加深刻。
比如 Unix編程中各種系統(tǒng)API,就屬于細(xì)枝末節(jié),對于 Unix 的各個(gè)內(nèi)核子模塊的整體實(shí)現(xiàn)、IPC 通信機(jī)制、IO 模型等才是重點(diǎn)。
(說個(gè)題外話,最近在制作一個(gè)《CSGuide》,會(huì)包含學(xué)習(xí)資料、路線、課程等等內(nèi)容,到時(shí)候弄好了會(huì)同步到 Github 去的:
上面說的是具體某個(gè)技術(shù)的核心,那么 CS 學(xué)習(xí)的核心有哪些呢?
大概是下面這些:
高級(jí)語言程序設(shè)計(jì)、數(shù)據(jù)結(jié)構(gòu)與算法、電路與電子技術(shù)、集合論與圖論、代數(shù)與邏輯、數(shù)字邏輯、計(jì)算機(jī)組成原理、操作系統(tǒng)原理、數(shù)據(jù)庫原理、編譯原理、軟件工程、計(jì)算機(jī)網(wǎng)絡(luò)。
學(xué)習(xí)計(jì)算機(jī)最核心的方法,也是小北一路走來總結(jié)的,按照學(xué)長推薦的這個(gè)路線走,大學(xué)畢業(yè)成為 Offer 收割機(jī),去 BAT TMD 這些都沒啥問題:
入門看視頻 + 不斷編碼 + 深入看源碼和經(jīng)典大黑書 + 做國外計(jì)算機(jī)硬核Lab
大黑書有哪些?
可以看看這篇高贊文章: 計(jì)算機(jī)必讀經(jīng)典書籍 (opens new window)
學(xué)習(xí)計(jì)算機(jī)一定不要想著速成,要下苦功夫,去啃那些經(jīng)典書和源碼,然后自己動(dòng)手寫代碼。
看書方法可以參考這篇文章:
如何閱讀計(jì)算機(jī)類書籍? (opens new window)
至于科班的課程,我們可以看下網(wǎng)易云課堂這個(gè)計(jì)算機(jī)科班的課程體系,雖然不是每個(gè)學(xué)校都一樣,但是大同小異:
比如計(jì)組、匯編、體系結(jié)構(gòu)等課程會(huì)讓我們明白計(jì)算機(jī)的構(gòu)成、運(yùn)行機(jī)制,以及典型的馮諾依曼結(jié)構(gòu),也會(huì)對于內(nèi)存和指針這樣兩塊在任何編程語言中都是極其重要的概念理解非常深入(不要扯Java這類語言沒指針,你完全可以把引用當(dāng)做受限指針)。
另外,像數(shù)字邏輯、模電這樣的課程主要是讓你明白數(shù)字:浮點(diǎn)數(shù)、整數(shù)都是如何在計(jì)算機(jī)內(nèi)部表示和存儲(chǔ)的,以及一些門電路的知識(shí)。
操作系統(tǒng)則讓你明白「一個(gè)程序是如何跑起來的」,一個(gè)它是如何編譯、鏈接、加載、運(yùn)行的,在這一整個(gè)過程幾乎會(huì)涉及到操作系統(tǒng)的所有環(huán)節(jié),學(xué)了這個(gè)你就會(huì)明白 synchronized 關(guān)鍵字在OS層面到底是如何保證的。
而計(jì)算機(jī)網(wǎng)絡(luò)則是讓你明白「一個(gè)數(shù)據(jù)包是如何從一臺(tái)主機(jī)發(fā)送到另外一臺(tái)主機(jī)的」,這里面涉及到路由算法、差錯(cuò)檢測、尋址、重試策略等等,包括 TCP/IP整個(gè)協(xié)議棧
編譯原理則是讓你明白高級(jí)語言都是如何被編譯程序識(shí)別、轉(zhuǎn)換為另外一種語言的,我認(rèn)為編譯器的本質(zhì)就是做轉(zhuǎn)換。
很多人覺得平常用不到編譯原理,其實(shí),,,真的用不到哈哈,但是在一些 DSL 方面還是會(huì)有用武之地的。
把操作系統(tǒng)、組成原理、系統(tǒng)編程這些學(xué)了,認(rèn)認(rèn)真真的把計(jì)算機(jī)基礎(chǔ)打扎實(shí)了,那你其實(shí)就是一個(gè)「計(jì)算機(jī)科班學(xué)生了」。
接下來說下我認(rèn)為對一個(gè)「計(jì)算機(jī)知識(shí)體系完整的畢業(yè)生」最重要的課程,你至少得把下面這些課 都學(xué)了:
1、 編程語言:C/C++ (學(xué)好了這兩門,基本其它編程語言一周就上手了)
2、《系統(tǒng)級(jí)編程》(我們教材是CSAPP,這是我本科上過最值的課!System Programing)
3、《數(shù)據(jù)結(jié)構(gòu)與算法》
4、《組成原理和體系結(jié)構(gòu)》
5、《操作系統(tǒng)》
6、《編譯原理》
7、《計(jì)算機(jī)網(wǎng)絡(luò)》
8、《數(shù)學(xué)課》:線代、離散、高數(shù)
首先,送大家一句話~:
萬丈高樓平地起,勿在浮沙筑高臺(tái)。
所以一定要在大學(xué)期間把基礎(chǔ)打牢固,整扎實(shí),這是科班的核心競爭力!
而且非科班同學(xué)學(xué)完這些課,也可以說是科班了!
看書 + 看視頻 + 實(shí)踐
接下來推薦一些我覺得特別好的資料,盡量保持精簡:
沒有比C語言更適合用來理解計(jì)算機(jī)系統(tǒng)了, 科班學(xué)生一定要學(xué)好 C語言。
推薦:《C程序設(shè)計(jì)語言》、《C與指針》、《C++ Primer》、《C++對象模型》、《Effective C++ 》
具體參考:
不用說肯定推薦《深入理解計(jì)算機(jī)系統(tǒng)》
其實(shí)它的簡介和第一章《計(jì)算機(jī)系統(tǒng)漫游》已經(jīng)寫得非常清楚了:
從一個(gè)簡單的hello world程序在計(jì)算機(jī)上的執(zhí)行過程:
預(yù)處理->編譯->匯編->鏈接->可執(zhí)行文件->裝載->數(shù)據(jù)流->屏幕輸出顯示
匯總成一句:信息 = 位+上下文。
另外還有一本就是《程序員自我修養(yǎng)》+ 《Unix環(huán)境編程》。
《算法第四版》、《算法導(dǎo)論》、《劍指offer》
不過這里說一下,算法導(dǎo)論不建議新手入門使用,容易被勸退,可以作為進(jìn)階閱讀使用。
具體參考:
《計(jì)算機(jī)組成與設(shè)計(jì):軟硬件接口》、《編碼》、《CSAPP》
操作系統(tǒng)我推薦 看書 + 做lab的方式,比如 MIT6.828 xv6
書可以看《現(xiàn)代操作系統(tǒng)》,如果你想學(xué)個(gè)os,可以看《操作系統(tǒng)真象還原》
我當(dāng)時(shí)應(yīng)該是看了不少網(wǎng)課,然后自己跟著教程”抄了“一個(gè) mini os。
學(xué)習(xí)操作系統(tǒng)一定不要去死看書,最好跟著那種有配套實(shí)驗(yàn)完成一個(gè)os的課程或者書。
就像這種:
具體參考:
如何系統(tǒng)學(xué)習(xí)操作系統(tǒng) (opens new window)
推薦《計(jì)算機(jī)網(wǎng)絡(luò)自頂向下》、《TCP/IP詳解》
具體參考:
直接看龍書(就叫《編譯原理》)就好了,想寫腳本可以看看《自制腳本語言》
說實(shí)話,把上面這幾門課學(xué)好了,國內(nèi)大廠offer幾乎隨便拿了。
但是很多人忽視了基礎(chǔ),往往在大學(xué)最該打基礎(chǔ)的時(shí)候去追求所謂的新技術(shù)。
所以不如談?wù)劦降住?strong>如何才能成為一個(gè)計(jì)算機(jī)知識(shí)體系完整的畢業(yè)生」吧?
在這里,我粗淺的把計(jì)算機(jī)編程領(lǐng)域的知識(shí)分為三個(gè)部分:
具體可以看下這個(gè)文章:
如何成為一個(gè)計(jì)算機(jī)知識(shí)體系完整的畢業(yè)生? (opens new window)
我推薦大家花在「基礎(chǔ) : 領(lǐng)域知識(shí) : 技能」 接近 7 : 2 : 1。
這也是我推薦你在大學(xué)期間分配學(xué)習(xí)時(shí)間的比例,至少學(xué)習(xí)基礎(chǔ)知識(shí)的時(shí)間不少于 50%,當(dāng)然,這些東西你都學(xué)完了那可以去找找感興趣的方向?qū)Q幸幌隆?/p>
不要大一、大二一上來就扎進(jìn) Java Web、Python 爬蟲這種東西,這些可以學(xué),但不是重點(diǎn)。
那么如何檢驗(yàn)學(xué)得如何呢?
想必你一定聽說這個(gè)計(jì)網(wǎng)面試題:
“從 URL 輸入到頁面展現(xiàn)到底發(fā)生什么?“
這個(gè)問題換個(gè)表達(dá)就是「一個(gè)數(shù)據(jù)包是如何發(fā)送到另外一臺(tái)電腦的」,如果你能完整的說出整個(gè)過程,那么計(jì)網(wǎng)你一定是學(xué)懂了!這就是為啥面試這么喜歡問這個(gè)問題的原因。
那么我們依葫蘆畫瓢提一個(gè)問題
“從代碼被寫下到程序運(yùn)行起來到底發(fā)生了什么?”
這個(gè)問題回答得越詳細(xì)越好,基本上能說清,你就理解了編譯原理、操作系統(tǒng)、組成原理這三座大三。
推薦閱讀:
四大基礎(chǔ)課網(wǎng)課:CS經(jīng)典課程,起飛! (opens new window)
聯(lián)系客服