怒肝1.3w+字給學姐講明白計算機專業(yè)大學四年到底該學什么?
為了保證這篇文章后續(xù)能夠繼續(xù)完善,我已近將其同步到了我的 Github:https://github.com/Snailclimb/cs-guide (無價值不分享。歡迎擴散,讓更多學姐看到。有幫助就點個 star 鼓勵一下 ?)
網(wǎng)上已經(jīng)有挺多關于“計算機專業(yè)大學四年到底應該學什么?”相關的文章了。不過,既然學姐問了我這個問題,我還是想再從我的角度來給她回答一下。安排!
另外,這篇文章中我不光會推薦你學習什么,還會推薦對應的比較好的學習資料給你。
這篇文章前前后后花了兩個月時間寫完,光是完善和修改就花了一周。即使,我盡量控制不說廢話,但是這篇文章的字數(shù)也還是超過了 1w 字 ,不過都是干貨!相信,不論是在校大學生還是已經(jīng)工作幾年的小伙伴都應該能夠從中有所收獲。如果有幫助點個贊/再看鼓勵一下就好!
另外, 這篇文章也要感謝我哈工大的一位朋友小明,畢竟自己離開學校已有 1 年多,沒有他的鼎力幫助,就沒有這篇文章。
下面這張圖是周末的時候在窗臺邊寫這篇文章的時候拍的。

首先,在學習編程之前,我覺得什么編程語言、數(shù)據(jù)結構、算法、操作系統(tǒng)這些都要統(tǒng)統(tǒng)一邊去。作為計算機專業(yè)的學生一定要首先養(yǎng)成下面幾個程序員必備的好習慣。
程序員必備的好習慣
使用 Google 搜索而不是百度。如果你實在訪問不了 Google 的話,替換成 Bing 也行。 經(jīng)常逛一些比較不錯的博客論壇比如國內(nèi)的掘金、博客園、CSDN,學有余力的小伙伴還可以去 GitHub、碼云上找一些開源項目,用來訓練自己的開發(fā)能力。 多關注一些你的領域的一些大牛在干嘛,多關注一些優(yōu)質原創(chuàng)博主的博客。舉個例子:Java 領域的話,你可以多關注一下我的 Github:https://github.com/Snailclimb[1] ,上面有很多干貨。 編程不只是要看,更要動手,這是一個特別需要實踐的專業(yè)。各個高校在編程課上可能會介紹自己校內(nèi)的 oj(online judge),題庫式的網(wǎng)站,可以做一些編程題目,還可以在線評測。一般適合初學者的簡單的 OJ 校內(nèi)都會提供,如果沒有的話,可以去校外找一些開放的簡單的 OJ 來刷題。 不要因為剛開始學習編程的不容易,而打擊自己的學習興趣和欲望。加油!奧利給!
我把我知道的一些程序員必備的好習慣毫無保留地都整理在了這個倉庫:https://github.com/Snailclimb/programmer-advancement [2] ,強烈推薦大家看看,同時也期待你的完善補充!

然后,就是編程語言了!
編程語言
幾乎所有的大學剛入學第一年就會開設一門編程語言課,一般是 C 語言偏多。
不論你的學校是否開設了 C 語言這門課,我建議大家最好還是學一下 C 語言。拿我從事的 Java 后端開發(fā)來說,很多 Java 從業(yè)者單純覺把 Java 學好就完全足夠了,并不需要再學習像 C、C++這種稍微更難一點的編程語言。我覺得對于剛能寫好 CRUD 的 Java 程序員來說確實是這樣的,但是對于想要成為比較頂尖的 Java 程序員來說肯定是不行的。很多開源項目都調用了 C 語言庫,所以, 作為 Java 程序員,不需要你 C 編碼能力多強,至少能夠看懂 C 代碼。
剛開始學習一門編程語言的時候,大部分人都挺吃力的。有時候一個環(huán)境搭建就折騰大半天。我記得,我那時候剛開始學,很多非常非常簡單的控制臺程序都寫不出來。不過,隨著后面學習的慢慢深入,我慢慢發(fā)現(xiàn)自己的編程思維和能力在變得越來越好。
在這里我想鼓舞一下初入計算機編程的各位小伙伴:萬事開頭難,你見過的所有大佬都是從懵懵懂懂的階段摸爬滾打過來的。 當你在 C 語言課上看著前面的老師在編譯器中飛快地輸入著代碼,自己卻連編譯器都配置不好的時候,心中難免會有失落,但這決非放棄的理由,只要堅持住,解決了一個又一個的難題,你也會成為曾經(jīng)心中的大佬。
如果想要看視頻提前學習或者上課沒學好 C 語言的話,推薦去 B 站搜索 C 語言郝斌。這個老師的課程很不錯,非常適合拿來作為初學者學習 C 語言的教程。并且,視頻中老師還會給你分享一些他自己的編程學習心得。
另外,如果你覺得譚浩強 老師的 《C 語言程序設計》 這本書比較難理解的話,可以看一下 《啊哈 C 語言!》,這本書非常通俗易懂,非常適合之前沒有學習過編程的新手。

還有開設 C++課程的高校也比較多。初學者學習 C++的教材可以使用《C++ Primer》,熟練掌握基礎語法后,為了進一步提高自己的編程開發(fā)能力,還可以讀一讀《C++ Primer Plus》和《Effective C++》。

實際上,大一初學編程的小伙伴在剛開始學編程語言的時候都會很吃力,以上推薦教材的正確使用方法有兩個要點:
結合課上老師所講和書上所講,在實際應用中去感悟“為什么” 把教材當成工具書、參考書,而非“教程”,結合參考書和網(wǎng)上搜索資源,來解決在實際編程中遇到的問題
計算機基礎課
計算機基礎的話,就是我們平時常提到的老四件:1.數(shù)據(jù)結構、2.算法、3.計算機網(wǎng)絡、4.操作系統(tǒng)。
要我說的話,這四門課是程序員最最最需要好好學的東西!另外,雖然四者都很重要,但是數(shù)據(jù)結構和算法相比于計算機網(wǎng)絡和操作系統(tǒng)要更加重要一些!
這四大件也就是我們常說的程序員內(nèi)功修煉最重要的一部分內(nèi)容!
“直接用框架不就好了么?為啥還要學習這些東西呢?” 這句話是很多初學編程的小伙伴最疑惑的問題。
簡單給大家聊聊為什么這四大件這么重要吧!
地基穩(wěn)固才能走的長遠 :這大件可以說是程序員未來發(fā)展的地基,你掌握的程度決定了你的地基打的有多深。工作不久之后,你就會發(fā)現(xiàn)你想要成為一位優(yōu)秀的程序員,而不是 API 調用者/低級 Bug 制造者,這些東西都是必備的! 技術更新?lián)Q代快 :我們前幾年可能還在用 Spring 基于傳統(tǒng)的 XML 開發(fā),現(xiàn)在幾乎大家都會用 Spring Boot 這個開發(fā)利器來提升開發(fā)速度,再比如幾年前我們使用消息隊列可能還在用 ActiveMQ,到今天幾乎都沒有人用它了,現(xiàn)在比較常用的就是 Rocket MQ、Kafka 。技術更新?lián)Q代這么快的今天,你是無法把每一個框架/工具都學習一邊的,底層技術就是你快速上手他們的瑞士軍刀。 懂得底層技術的人更有競爭力 :現(xiàn)在的程序員這么多,你如何能和別人拉開差距?單純就靠使用框架的能力么?這些隨便從培訓班抽一個人可能都會做的工作無法成為你的核心競爭力。
數(shù)據(jù)結構
關于數(shù)據(jù)結構,我想說的是,它是這四大件中最簡單、最基礎的一個。離開了數(shù)據(jù)結構,幾乎任何的程序都會失效,所以在討論數(shù)據(jù)結構的時候,常常要把算法也連帶著說一說。
要單純地掌握常見的數(shù)據(jù)結構,就如同拆解一個個精妙的儀器件一樣有趣和簡單。正因為數(shù)據(jù)結構這個東西在程序中的作用,和儀器部件特別相像,不同的數(shù)據(jù)結構有著不同的特性,因此要想學好數(shù)據(jù)結構,圖解是必備武器!
在數(shù)據(jù)結構的學習中,強烈建議跟著名校的網(wǎng)課學習,這些課程都經(jīng)過多次打磨,配套練習豐富,非常適合初學者。比如中國大學 MOOC 上的武漢大學開設的《數(shù)據(jù)結構》課程。

輔以教材參考書,強推《大話數(shù)據(jù)結構》,光看封面你就知道這本書的風格了,圖解學數(shù)據(jù)結構?選這本,沒錯的!

當用圖解理清了各種數(shù)據(jù)結構的原理和特性之后,還要在代碼中多加練習,熟能生巧。
編程是一個冒出一個問題,解決一個問題的有趣過程。
當有一個變量在腦海中出現(xiàn)的時候,要先思考該變量的作用是什么,以什么數(shù)據(jù)結構存儲這個變量,還要考慮在代碼中如何實現(xiàn)。比如說棧,在 C 語言中可以用數(shù)組輔以棧頂指針來實現(xiàn);在 Java 中可以直接調用 Stack 類來實現(xiàn)。只要你編程,就要用到數(shù)據(jù)結構,編的程序越復雜,用到的數(shù)據(jù)結構就可能越多,可以說它幾乎沒有什么難點,重點是熟能生巧。
算法
算法課常常和數(shù)據(jù)結構課放在一起,在有些高校中,會存在“數(shù)據(jù)結構與算法”和“算法設計與分析”這樣的兩門課。
前者可能相對簡單,介紹的是常用的數(shù)據(jù)結構和基礎的算法;后者就相對較難,講的是算法相關的概念,以及稍微比較復雜的算法思維和算法分析。前者側重的是基礎邏輯算法的應用,后者側重的是運用算法思想到實際問題中。
舉個例子,我們常用的排序算法就屬于前者的課程內(nèi)容,一個排序問題可以有多種算法解決方案,不同方案有不同的優(yōu)劣,也就有不同的應用場景,學習一題多解也可以加強編程熟練度。而貪心思想屬于后者的課程內(nèi)容,比如說經(jīng)典的活動選擇問題:
設 S={1,2,...,n}是 n 個活動的集合,各個活動的集合,各個活動使用同一個資源,資源在同一時間只能為一個活動使用?,F(xiàn)已知 n 個活動的開始時間 si 和 fi,設所有活動的最早開始時間和最晚結束時間都在資源可供利用的時間內(nèi),并規(guī)定若活動 i 和活動 j 滿足 fi≤sj(或 fj≤si),則稱他們是兼容的?,F(xiàn)求:最大活動集合,該活動集合內(nèi)的所有活動都是兼容的。
該問題的解決思想使用了貪心思想,貪心策略為:每次都選 fi 最小,即結束時間最早的活動(在滿足兼容的情況下)。以此貪心策略進行選取活動集合,可以滿足結果為最優(yōu)解(不唯一),該解法的最優(yōu)性可以用優(yōu)化子結構來證明。以上這些,對于初學者來說可能聽起來云山霧繞,但這都是算法設計與分析課上的內(nèi)容。
分治思想、貪心思想、動態(tài)規(guī)劃這三大算法在實際應用起來非常靈活,常常讓人摸不到頭腦。我給大家的建議是:
多多聯(lián)系圖解的方式,先接觸算法的思想。不管多復雜的算法,結合了圖解,總能對其有一個清晰的認識。 多多聯(lián)系實例,研究算法在問題中的應用。對算法有一個清晰的認識后,到了實際問題中還是不容易應用算法想出解題思路,需要大家勤動腦,勤動手,多做題,感悟算法在問題中的應用。 多多看博客、熱門筆記,聽聽前輩們的總結,爭取做到舉一反三。前輩們的筆記都是非常不錯的學習資源,如 網(wǎng)上一些熱門的開放的 OJ 也是大家訓練算法的好資源哦~,比如leetcode[3]
另外,如果你刷 Leetcode 的話,你會發(fā)現(xiàn)很多算法題都是通過動態(tài)規(guī)劃的方式來解決的,因此你務必要琢磨透動態(tài)規(guī)劃算法的思想。
再附上一些算法領域的經(jīng)典學習參考書(對于初學者,推薦程度從左向右……):

下面這兩篇文章都非常不錯,一定要好好看一下:
《硬核的算法學習書籍+資源推薦》[4] 。 如何刷 Leetcode?[5]
計算機網(wǎng)絡
計算機網(wǎng)絡是一門系統(tǒng)性比較強的計算機專業(yè)課,各大名校的計算機網(wǎng)絡課程打磨的應該都比較成熟。
要想學好計算機網(wǎng)絡,首先要了解的就是 OSI 七層模型或 TCP/IP 五層模型,即應用層(應用層、表示層、會話層)、傳輸層、網(wǎng)絡層、數(shù)據(jù)鏈路層、物理層。
Data to Drag
關于這門課,首先強烈推薦參考書是機械工業(yè)出版社的《計算機網(wǎng)絡——自頂向下方法》。該書目錄清晰,按照 TCP/IP 五層模型逐層講解,對每層涉及的技術都展開了詳細討論,基本上高校里開設的課程的教學大綱就是這本書的目錄了。

如果你覺得上面這本書看著比較枯燥的話,我強烈推薦+安利你看看下面這兩本非常有趣的網(wǎng)絡相關的書籍:
《圖解 HTTP》[6] :講漫畫一樣的講 HTTP,很有意思,不會覺得枯燥,大概也涵蓋也 HTTP 常見的知識點。因為篇幅問題,內(nèi)容可能不太全面。不過,如果不是專門做網(wǎng)絡方向研究的小伙伴想研究 HTTP 相關知識的話,讀這本書的話應該來說就差不多了。 《網(wǎng)絡是怎樣連接的》[7] :從在瀏覽器中輸入網(wǎng)址開始,一路追蹤了到顯示出網(wǎng)頁內(nèi)容為止的整個過程,以圖配文,講解了網(wǎng)絡的全貌,并重點介紹了實際的網(wǎng)絡設備和軟件是如何工作的。

如果說學習計算機網(wǎng)絡要圍繞的 TCP/IP 五層模型逐層展開學習的話,那么針對每層的學習,就要以協(xié)議為單位了。一言以蔽之,我們學習計算機網(wǎng)絡需要的協(xié)議有:
應用層協(xié)議 HTTP 協(xié)議(超文本傳輸協(xié)議,網(wǎng)頁瀏覽常用的協(xié)議) DHCP 協(xié)議(動態(tài)主機配置) DNS 系統(tǒng)原理(域名系統(tǒng)) FTP 協(xié)議(文件傳輸協(xié)議) 電子郵件協(xié)議等(SMTP、POP3、IMAP) P2P 架構 傳輸層協(xié)議 報文段結構 RDT(可靠數(shù)據(jù)傳輸協(xié)議) 報文段結構 可靠數(shù)據(jù)傳輸 流量控制 擁塞控制 TCP 協(xié)議 UDP 協(xié)議 網(wǎng)絡層協(xié)議 IP 協(xié)議(TCP/IP 協(xié)議的基礎,分為 IPv4 和 IPv6) ARP 協(xié)議(地址解析協(xié)議,用于解析 IP 地址和 MAC 地址之間的映射) ICMP 協(xié)議(控制報文協(xié)議,用于發(fā)送控制消息) NAT 協(xié)議(網(wǎng)絡地址轉換協(xié)議) RIP 協(xié)議、OSPF 協(xié)議、BGP 協(xié)議(路由選擇協(xié)議) 鏈路層 差錯檢測技術 多路訪問協(xié)議(信道復用技術) CSMA/CD 協(xié)議 MAC 協(xié)議 以太網(wǎng)技術 物理層(對計算機專業(yè)的小伙伴來說,在課程要求中,物理層的內(nèi)容可能相對不那么重要)
操作系統(tǒng)
操作系統(tǒng)也是一門比較重要的學科。為何這樣說呢?
操作系統(tǒng)中的很多思想、很多經(jīng)典的算法,你都可以在我們?nèi)粘i_發(fā)使用的各種工具或者框架中找到它們的影子。
比如說我們開發(fā)的系統(tǒng)使用的緩存(比如 Redis)和操作系統(tǒng)的高速緩存就很像。CPU 中的高速緩存有很多種,不過大部分都是為了解決 CPU 處理速度和內(nèi)存處理速度不對等的問題。我們還可以把內(nèi)存可以看作外存的高速緩存,程序運行的時候我們把外存的數(shù)據(jù)復制到內(nèi)存,由于內(nèi)存的處理速度遠遠高于外存,這樣提高了處理速度。同樣地,我們使用的 Redis 緩存就是為了解決程序處理速度和訪問常規(guī)關系型數(shù)據(jù)庫速度不對等的問題。
高速緩存一般會按照局部性原理(2-8 原則)根據(jù)相應的淘汰算法保證緩存中的數(shù)據(jù)是經(jīng)常會被訪問的。我們平常使用的 Redis 緩存很多時候也會按照 2-8 原則去做,很多淘汰算法都和操作系統(tǒng)中的類似。
既說了 2-8 原則,那就不得不提命中率了,這是所有緩存概念都通用的。簡單來說也就是你要訪問的數(shù)據(jù)有多少能直接在緩存中直接找到。命中率高的話,一般表明你的緩存設計比較合理,系統(tǒng)處理速度也相對較快。
總結來說,我覺得學好操作系統(tǒng)能夠提高自己思考的深度以及對技術的理解力。
操作系統(tǒng)內(nèi)容比較多,如果說你單純是為了應付面試的話,你可以看我之前總結的一篇文章:https://snailclimb.gitee.io/javaguide/#/docs/operating-system/basis[8] 。
這篇文章的目錄如下,涵蓋了操作系統(tǒng)一些比較常見的問題。

如果你要系統(tǒng)地學習操作系統(tǒng)的話,最硬核最權威的書籍是**《操作系統(tǒng)導論》** 。你可以再配套一個 《深入理解計算機系統(tǒng)》 加深你對計算機系統(tǒng)本質的認識,美滋滋!

如果你比較喜歡動手,對于理論知識比較抵觸的話,我推薦你看看《30 天自制操作系統(tǒng)》,這本書會手把手教你編寫一個操作系統(tǒng)。

計算機專業(yè)課
本章設計的課程并不是說專業(yè)課,只是說相比于上面的四大件,專業(yè)性更強,主要包括面向對象程序設計、形式語言與自動機、機器學習、數(shù)據(jù)庫系統(tǒng)、編譯原理。
面向對象程序設計
面向對象程序設計(OOP)是程序員編程的核心思想,如果以后走軟件開發(fā)路線,OOP 是必須要精通的。OOP 給程序員提供了一種思維模式,將現(xiàn)實生活中的事務抽象成為“對象”,面向對象進行程序設計。
舉個例子,OOP 中有三大要素——類、繼承、多態(tài)(也有封裝、繼抽象、繼承、多態(tài)四大要素)。如果把杯子抽象成為類的話,那么咖啡杯、茶杯、馬克杯等等都屬于對杯子的繼承,在該繼承中,被繼承者——杯子,被稱為父類,繼承者——咖啡杯、茶杯、馬克杯,被稱為子類。子類繼承父類,即父類有的子類一定有(除父類私有),而子類有的父類不一定有。而多態(tài)的概念是在繼承之中的,在繼承中,子類擁有父類的方法,都是杯子,那么就都能裝水。而不同的杯子可以定制自己的方法,即重載父類“裝水”的方法——裝咖啡、裝茶水等。
OOP 中還有六大原則:
單一責任原則(Single Responsibility Principle) :一個類盡量只負責一種事務的抽象,功能盡量單一,降低耦合。 開放-封閉原則(Open-Closed Principle) :在類的設計中,要盡量保證“對擴展性的開放,對修改的封閉”。 Liskov 替換原則(Liskov Substitution Principle) :Liskov 規(guī)則嚴格規(guī)定,“子類型必須能夠替換其基類型,派生類必須能夠通過其基類的接口使用,客戶端無需了解二者之間的差異?!?/section> 接口聚合原則(Interface Segregation Principle) :該原則要求,不能強迫客戶端依賴于它們不需要的接口,只提供必需的接口。“大”接口盡量分割為若干個”小“接口,不同的接口向不同的客戶端提供服務,客戶端只訪問自己需要的接口。 依賴轉置原則(Dependency Inversion Principle) :抽象的模塊不應該依賴于具體的模塊,具體應依賴于抽象。 最少知識原則(Least Knowledge Principle) :一個類對其他類的內(nèi)部實現(xiàn),知道的越少越好,如果一定要和不太相干的類通信,盡量使用第三者作為轉達。

可能有很多小伙伴在學完了 OOP,編了兩三年程序也沒完全弄清楚這六大原則。其實他們無處不在,這里我盡量舉例子來形象地說明這六大原則。
假設杯子分為咖啡杯和牛奶杯:
單一責任原則要求,不應該有一種杯子既能裝咖啡又能裝面包,如果可以的話,那么當客戶需要一個裝面包的容器時,被提供了一只杯子,這樣當裝面包的容器發(fā)生變化時,就波及到了杯子功能的實現(xiàn),耦合度較高不利于維護。 開放封閉原則要求,杯子現(xiàn)在可能很簡單,但最好支持將來的拓展,如加入量度、加入杯蓋等。但請不要再做修改,咖啡杯就是咖啡杯,如果需要改造出一個茶杯,請新繼承一個茶杯,而不要在已有的咖啡杯上修改。 Liskov 替換原則要求,顧客在買杯子的時候,只需要說”我要買杯子,裝咖啡用“,就可以提供咖啡杯給該顧客,滿足顧客的所有需求。 接口聚合原則要求,不應該有一種杯子既能裝咖啡又能裝牛奶,如果顧客需要裝咖啡的杯子,請不要提供給他”咖啡牛奶杯“,裝牛奶的功能是他不需要的。 依賴轉置原則要求,咖啡杯的設計一定要依賴”杯子具有盛裝液體“的功能,而非杯子能裝液體依賴于咖啡杯的設計。這一原則和”面向過程程序設計“思想恰恰相反。 最少知識原則,嗯...用杯子舉例就不太恰當了,就拿企業(yè)里各個部門之間運作舉例吧,兩個不相關部門之間不要直接通信,如果要通信的話,用第三個部門統(tǒng)籌安排,降低耦合度,提高效率。
關于 OOP 大的概況,我只能用三大特性和六大原則來概括,真要學習起來,OOP 中的每一個細節(jié)都值得深入討論。OOP 早在上世紀八十年代就開始流行,作為提高程序設計生產(chǎn)力的重要思想,一直沿用到現(xiàn)在。C++和 Java 是現(xiàn)在比較主流的 OOP 編程語言,也是高校中 OOP 課程的主力教學語言。如果接觸的第一門語言的是 C 語言的話,也不用太過抵觸,雖然 C 語言是面向過程程序設計,接觸過這種稍稍比較原始的編程思想,再學習 OOP 的話,會有更不一樣的感覺。
形式語言與自動機
“計算機專業(yè)大學四年到底應該學什么?”,我想很多人在這個問題下的回答不會包括這門課——形式語言與自動機。
這門課包括兩個部分:
形式語言。 自動機。
形式語言更像是計算機專業(yè)的數(shù)學課,它研究的是嚴格的語法規(guī)則下,語義的表示?;谛问秸Z言課程的后續(xù)課程其實也不算多,編譯原理、自然語言處理等專業(yè)課程可能會用到形式語言的知識,但形式語言帶給學生的更偏向于一種思想,在給定條件下對問題的定義能力和抽象能力。
自動機是算法的一種。自動機可以理解為一臺在給定狀態(tài)下、給定輸入得到確定的輸出(集)的機器,核心是狀態(tài) × 輸入 →{狀態(tài)}的映射。他也是代表著一類思想。自動機思想在算法中的應用常常被看作是傳統(tǒng)算法,由于他的思路非常簡單,運行效率高,在一些特定的場景下有著高效地運用。但自動機的缺點在于其定義非常復雜,正因為此,適用面也比較窄。
總的來說,形式語言跟正則表達式還有點關系,自動機的學習過程更像是解一道道的智力題,這門課應該還算比較有趣的一門課。

如果你要學習這門課的話,可以去中國大學 Mooc 看看哈工大的形式語言與自動機理論這門課。
機器學習
機器學習這門課不一定每個高校都開設,有的高校可能開設的是領域性更強的深度學習,有的高校可能把機器學習當作選修課開設,但在現(xiàn)在的人工智能技術橫行的 IT 行業(yè)中,要掌握 AI 技術,機器學習屬于一門很好的入門專業(yè)課(并不是通識課)。
機器學習中涉及了大量的概率論的知識,需要扎實的概率論基礎,還夾雜著一些不簡單的線性代數(shù)知識。 機器學習的工作是在研究一種算法,在某些任務中,利用一些經(jīng)驗,研究該算法的性能。任務的種類大體可以分為分類問題和回歸問題。 分類問題,就是在給定已知條件的情況下,決定該情況屬于哪一類,比如經(jīng)典的航班預測問題,給定某一班航班的信息,預測該航班是否可能會晚點。而回歸問題是在給定已知條件的情況下,計算該情況的回歸值,在航班預測問題中,可能并不是預測是否晚點(二分類問題),而是預測該航班的到達時間(相比于基準時間的晚點時間或早到時間),這就是回歸問題。
機器學習中比較簡單的算法有決策樹、多項式擬合、邏輯回歸等,相對較難的算法有支持向量機(SVM)算法、EM 算法等,就不一一列舉了。機器學習在一些算法上可以看作是數(shù)值分析課程和概率論的延伸,因此在學習機器學習之前,一定要打好扎實的數(shù)值分析基礎,學好概率論,順便別把大一學的線性代數(shù)都忘光了。
在學習的過程中,除了跟著老師在課堂上的逐步講解和推導,課下還可以結合著 B 站上的 “白板機器學習” 來看,推導非常詳細,小哥哥也非常耐心。

參考書的話,這里有兩本推薦的書,一本是“西瓜書”——周志華的《機器學習》。 西瓜書中的案例場景圍繞著“種西瓜”展開,比較能帶動讀者興趣,但是該書涉及符號較多,讀者最好有一定的代數(shù)能力素養(yǎng),可以盡快適應該書的符號表達和公式推導。該書比較適合慢慢研讀,內(nèi)容在機器學習領域不算深,一點點啃會有不小的收獲。另一本書是李航的《統(tǒng)計學習方法》, 該書不僅適合計算機專業(yè)的學生,也適合數(shù)理統(tǒng)計專業(yè)的學生,書中每章都圍繞著一個個經(jīng)典算法展開,推導過程詳細,篇幅也不長,但內(nèi)容相對西瓜書來說比較枯燥,適合作為工具書來讀,需要學習某個算法的時候,去該書上找那一章節(jié),快速讀完,不懂的話可以多讀幾遍。

數(shù)據(jù)庫系統(tǒng)
數(shù)據(jù)庫系統(tǒng)這門課在程序員的職業(yè)規(guī)劃中也是非常重要的一門課,甚至有些信息管理的專業(yè)的也要開設這門課。說這門課重要,是因為對于程序員的發(fā)展來說,一方面關系數(shù)據(jù)庫系統(tǒng)、SQL 語言以及數(shù)據(jù)庫的三段設計(概念設計、邏輯設計和物理設計)都是開發(fā)數(shù)據(jù)庫應用程序的必備技能,通常在數(shù)據(jù)庫應用開發(fā)崗位的面試中,數(shù)據(jù)庫的設計是面試官青睞的考點,如何能根據(jù)需求分析并設計出完善的數(shù)據(jù)庫系統(tǒng),是程序員的必備技能,設計好了完善的數(shù)據(jù)庫系統(tǒng)之后,再用 SQL 語言等工具對其進行實現(xiàn),那么這些其實就是個人的編碼能力了。另一方面,數(shù)據(jù)庫中的查詢處理、查詢優(yōu)化、并發(fā)控制、事務管理、日志管理等內(nèi)容,都是數(shù)據(jù)庫中稍微進階一點的技能,對于一些對崗位要求比較高的,這些技術同樣要求熟練掌握。 對一些查詢優(yōu)化的等數(shù)據(jù)庫底層實現(xiàn)的內(nèi)容,也是新型數(shù)據(jù)庫開發(fā)的前置基礎技能,對于一些研究型人才來說,也是非常重要的。
數(shù)據(jù)庫系統(tǒng)與其他計算機專業(yè)課一樣,知識體系非常清晰,而且他有一個非常突出的特點,就是實際與理論相結合。SQL 語言,數(shù)據(jù)庫設計等,這些都屬于實踐應用部分,而對于一些范式定義,兩段鎖協(xié)議并發(fā)控制等,這些就偏向于理論多一些。要想學好數(shù)據(jù)庫系統(tǒng),建議大家:
在課程的前期階段,熟練掌握 SQL 語言的應用,同時不要忘了訓練關系代數(shù)的應用能力。 關系代數(shù)雖然在數(shù)據(jù)庫的實現(xiàn)上作用較小,但在學習階段,結合關系代數(shù)和 SQL 語言學習,可以更加有體系地理清 SQL 語言各個子句之間的邏輯關系,有助于 SQL 語言的學習和記憶。關系代數(shù)的學習更像是建立一種思維,這種思維到了數(shù)據(jù)庫底層實現(xiàn)學習環(huán)節(jié)也是非常有用的。 在課程的中期階段,熟練掌握 ER 圖的應用,并強化數(shù)據(jù)庫設計中的理論部分。 ER 圖的熟練應用可以更加輕松地設計出關系數(shù)據(jù)庫模式,而理論部分同樣不能忽視,設計理論的運用決定了數(shù)據(jù)庫的正確性和健壯性。 而在課程的后期階段,主要就是以理論居多,而且這些理論并不容易能找到配套的實驗練習。這里再次強調,凡是理論知識的學習,盡量要結合圖解的方式。
教材的話,強烈推薦《數(shù)據(jù)庫系統(tǒng)概念》(機械工業(yè)出版社),這本書涵蓋了數(shù)據(jù)庫系統(tǒng)的全套概念,知識體系清晰,是學習數(shù)據(jù)庫系統(tǒng)非常經(jīng)典的教材!不是參考書!

參考書的話,可以看一看《深入淺出 MySQL:數(shù)據(jù)庫開發(fā)、優(yōu)化與管理維護》,該書非常適合 MySQL 開發(fā)的從業(yè)者,完全可以作為 MySQL 學習的參考書,相比《數(shù)據(jù)庫系統(tǒng)概念》來說,該書更加傾向于基于 MySQL 技術的全套開發(fā),一共分為基礎篇、開發(fā)篇、優(yōu)化篇、管理維護篇和架構篇。

編譯原理
編譯原理相比于前面介紹的專業(yè)課,地位顯得不那么重要了。編譯原理的重要性主要體現(xiàn)在:
底層語言、引擎或高級語言的開發(fā),如 MySQL,Java 等 操作系統(tǒng)或嵌入式系統(tǒng)的開發(fā) 詞法、語法、語義的思想,以及自動機思想
編譯原理的重要前置課程就是形式語言與自動機,自動機的思想在詞法分析當中有著重要應用,學習了這門課后,應該就會發(fā)現(xiàn)許多場景下,自動機算法的妙用了。
總的來說,這門課對于各位程序員的職業(yè)發(fā)展來說,相對不那么重要,但是從難度上來說,學習這門課可以對編程思想有一個較好的鞏固。學習資源的話,除了課堂上的幻燈片課件以外,還可以把《編譯原理》(機械工業(yè)出版社)這本書作為參考書,用以輔助自己學不懂的地方(大家口中的龍書,想要啃下來還是有一定難度的)。

通用課
通用課的部分我想分為兩大部分來介紹,主要就是數(shù)學和英語,一般在大一和大二兩學年就可以全部修完,大二大三逐漸接觸專業(yè)課。通用課作為許多高中生升入大學的第一門課,算是高中階段到本科階段的一個過渡,從職業(yè)生涯重要性上來說,遠不及專業(yè)課重要,但是在本科階段的學習生活規(guī)劃中,有著非常重要的地位。由于通用課的課程多,學分重,占據(jù)了本科階段績點的主要部分,影響到學生在前兩年的專業(yè)排名,也影響到大三結束時的推免資格分配,也就是保研。而從升學角度來看,對于攻讀研究生和博士生的小伙伴來說,數(shù)學和英語這兩大基礎課,還是十分有用的。
數(shù)學
微積分(高等數(shù)學)
微積分,即傳說中的高數(shù),成為了無數(shù)新大一心中的痛。但好在,大學的課程考核沒那么嚴格,期末想要拿高分,也不至于像高中那樣刷題刷的那么狠。微積分對于計算機專業(yè)學生的重要性,主要體現(xiàn)在計算機圖形學中的函數(shù)變換,機器學習中的梯度算法,信號處理等領域。
微積分的知識體系包括微分和積分兩部分,一般會先學微分,再學積分,也有的學校把高數(shù)分為兩個學期。微分就是高中的導數(shù)的升級版,對于大一萌新來說還算比較友好。積分恰好是微分的逆運算,思想上對大一萌新來說比較新,一時半會可能接受不了。不過這門課所有的高校都有開設,而且大部分的名校都有配套的網(wǎng)課,教材也都打磨的非常出色,結合網(wǎng)課和教材的“啃書”學習模式,這門課一定不會落下。
線性代數(shù)(高等代數(shù))
線性代數(shù)的思維模式就更加復雜了一些,它定義了一個全新的數(shù)學世界,所有的符號、定理都是全新的,唯一能嘗試的去理解的方式,大概就是用幾何的方式去理解線性代數(shù)了。由于線性代數(shù)和幾何學有著密不可分的關系,比如空間變換的理論支撐就是線性代數(shù),因此,網(wǎng)上有著各種“可視化學習線性代數(shù)”的學習資源,幫助理解線性代數(shù)的意義,有助于公式的記憶。

概率論與數(shù)理統(tǒng)計
對于計算機專業(yè)的小伙伴來說,這門課可能是概率論更有用一點,而非數(shù)理統(tǒng)計??赡苣承W校只開設概率論課程,也可能數(shù)理統(tǒng)計也教,但僅僅是皮毛。概率論的學習路線和微積分相似,就是一個個公式輔以實例,不像線性代數(shù)那么抽象,比較貼近生活。在現(xiàn)在的就業(yè)形勢下,概率論與數(shù)理統(tǒng)計專業(yè)的學生,應該是數(shù)學專業(yè)最好就業(yè)的了,他們通常到崗位上會做一些數(shù)據(jù)分析的工作,因此,這門課程確實是數(shù)據(jù)分析的重要前置課程,概率論在機器學習中的重要性也就不言而喻了。
離散數(shù)學(集合論、圖論、近世代數(shù)等)
離散數(shù)學是計算機專業(yè)的專屬數(shù)學,但實際上對于本科畢業(yè)找工作的小伙伴來說,離散數(shù)學還并沒有發(fā)揮它的巨大作用。離散數(shù)學的作用主要在在圖研究等領域,理論性極強,需要讀研深造的小伙伴盡可能地扎實掌握。
英語
英語算是大學里面比較靈活的一項技能了,有的人會說,“英語學的越好,對個人發(fā)展越有利”,此話說的沒錯,但是對于一些有著明確發(fā)展目標的小伙伴,可能英語技能并不在他們的技能清單內(nèi)。接下來的這些話只針對計算機專業(yè)的小伙伴們哦。
英語課在大學本科一般只有前兩年開設,小伙伴們可以記住,想用英語課來提升自己的英語水平的,可以打消這個念頭了。 英語水平的提高全靠自己平時的積累和練習,以及有針對性的刷題。
英語的大學四六級一定要過。 這是必備技能,絕大部分就業(yè)崗位都要看四六級水平的,最起碼要通過的。四級比高中英語稍微難一些,一般的小伙伴可能會卡在六級上,六級需要針對性的訓練一下,因為大學期間能接觸英語的實在太少了,每學期一門英語課是不足以保持自己的英語水平的。對于一些來自于偏遠地區(qū),高中英語基礎薄弱的,考四六級會更加吃力。建議考前集中訓練一下歷年真題,輔以背一下高頻詞匯,四六級通過只需要 425 分,這個分數(shù)線還是比較容易達到的。稍微好一點的小伙伴可能沖一下 500 分,要是能考到 600 分的話,那是非常不錯的水平了,算是簡歷上比較有亮點的一項。
英語的雅思托??荚囍幌抻谙胍鰢男』锇?,以及應聘崗位對英語能力有特殊要求的。雅思托??荚嚶憧疾蝗菀淄ㄟ^,花錢去比較靠譜的校外補課班應該是一個比較好的選擇。
對于計算機專業(yè)的小伙伴來說,英語能力還是比較重要的,雖然應聘的時候不會因為沒有雅思托福成績卡人,但是你起碼要能夠:
熟練使用英文界面的軟件、系統(tǒng)等 對于外網(wǎng)的一些博客、bug 解決方案等,閱讀無壓力 熟練閱讀英文文獻 具備一定的英文論文的撰寫能力
畢竟計算機語言就是字符語言,聽說讀寫中最起碼要滿足讀寫這兩項不過分吧。
Q&A
1.感覺學校教的都聯(lián)系不到實際,我本科畢業(yè)真的能找到工作嗎?
就筆者所就讀的高校來說,我是相信它的培養(yǎng)方案是有能力培養(yǎng)出具有就業(yè)能力的本科畢業(yè)生的。我相信很多名校的培養(yǎng)方案也都不會差。如果你就讀的學校不是那么出色,并且質疑自己學校的培養(yǎng)能力的話,建議你多到名校的網(wǎng)課上取取經(jīng)。如果你是就讀于國內(nèi)名校的話,請相信的自己專業(yè)的培養(yǎng)方案,下限不會低。
另外,如果你的學校比較差的話,大學期間一定要盡全力讓自己的簡歷更好看,你可以出去實習、參加一些含金量比較高的比賽、跟著老師做一些項目。
2.學校里需要參加一些社團、學生會之類的嗎?
筆者只參加過社團,并未參加過學生會。對于這個問題,我結合我所接觸的人來簡單回答一下。針對不同的發(fā)展定位,可以選擇自己投入社團、學生會的精力。比如,你是一個技術宅,那么我想你就算加入了社團之類的團體,也收獲不到自己想要的能力,其實就沒有參加的必要了。如果你是一個學生干部,或者擅長和人打交道,也許畢業(yè)之后從事產(chǎn)品經(jīng)理之類的工作,那么在學生會的經(jīng)歷應該是蠻鍛煉你的能力的。是否要選擇參加團體活動,投入多少精力,完全取決你對自己的定位如何,請把你自己放到合適的環(huán)境下培養(yǎng),不必人云亦云。
3.在大學里一定要參加競賽比賽嗎?
競賽比賽對于學生的好處有,得獎了的話可能會獲得保研加分、豐富個人簡歷,在應聘中拿到不錯的印象分。保研加分具體涉及到的競賽需要咨詢所在學院,并非所有競賽獲獎都能加分的。
那么競賽比賽有沒有壞處呢?也會有一點吧,就是指那些能力并不算強,但仍然把大量時間花在了打比賽這上面,這其實并不是壞處,這對個人能力仍有提高,壞處指的是因為打競賽耽誤了專業(yè)課的學習。這樣一來,基礎也沒扎實,突出能力也沒訓練出來,撿了芝麻丟了西瓜,就不好了。
總的來說,打競賽利大于弊,不要低估的自己的能力而排斥參加競賽,也不要高估自己的能力過分癡迷競賽。
以上是我針對本科計算機專業(yè)各個課程的傾力解讀,如有不妥,請多加指正!
參考資料
https://github.com/Snailclimb: https://github.com/Snailclimb
[2]https://github.com/Snailclimb/programmer-advancement : https://github.com/Snailclimb/programmer-advancement
[3]leetcode: https://leetcode-cn.com/
[4]《硬核的算法學習書籍+資源推薦》: docs/dataStructures-algorithms/算法學習資源推薦.md
[5]如何刷 Leetcode?: https://www.zhihu.com/question/31092580/answer/1534887374
[6]《圖解 HTTP》: https://book.douban.com/subject/25863515/
[7]《網(wǎng)絡是怎樣連接的》: https://book.douban.com/subject/26941639/
[8]https://snailclimb.gitee.io/javaguide/#/docs/operating-system/basis: https://snailclimb.gitee.io/javaguide/#/docs/operating-system/basis
后記
最近寫的一些干貨,每篇都很用心,歡迎各位小伙伴閱讀/點贊/分享:
我是Guide哥,Java后端開發(fā),會一點前端知識,喜歡烹飪,自由的少年。一個三觀比主角還正的技術人。我們下期再見!
