你已经是个成熟的985大学了,请不要在大一教 C 语言!
昨天晚上回家后突然在朋友圈發(fā)了個問卷,看下國內(nèi)大學(xué)第一門語言到底有多少是用的 C 語言。
結(jié)果也是很符合預(yù)期,使用 C 語言做第一門編程語言課的大學(xué)達到了 90% 以上。
之前在知乎看見一個問題,問為什么還有985高校給大一上 C 語言課,如下:
原問題不過這個提問方式未免有引戰(zhàn)嫌疑,所以被知乎管理員編輯為如下問題:
現(xiàn)問題這樣顯然中立很多了,是在擺事實提問題。
接下來我們就聊聊 985 大學(xué)為什么還是給大一上 C 語言課。
一、為什么要學(xué) C 語言?
首先,我們學(xué)的是 Computer Science,而不是 Programming Language,語言真的真的真的不是重點。
語言只是工具,工具沒有優(yōu)劣,只有各自適用的場景不同。
所以,以下所有討論皆不涉及語言優(yōu)劣,一切論述以怎樣才是有利于學(xué)好 ?Computer Science 為原則(求生欲滿滿
大學(xué)教育,尤其是 985、211 這種國內(nèi)最頂尖的一批高校,應(yīng)該注重通識教育而不是專項教育,在專業(yè)上更要注重基礎(chǔ)、底層、偏向原理。
只有掌握了最核心的東西,學(xué)起那些偏技能的東西才會很快很輕松。
我記得當時大二需要寫爬蟲,大概看了一天左右的 Python 教程,會基本的循環(huán)、判斷、控制流、一些 builtin 函數(shù)和類,然后學(xué)了下 requests 庫就直接開干了。
其實像 JS、Python、Node、PHP 這些東西,科班學(xué)生幾乎都是自學(xué),哪還用得上單獨開一門課呀。
自學(xué)是最基本的要求,需要用到的時候自己去看教程、文檔,直接就上手寫了。
所以這種語言完全沒必要開一學(xué)期的課來學(xué),倒是非常適合放在計算機導(dǎo)論課程中,成為其中一個章節(jié)。
比如 Berkeley 開設(shè)的導(dǎo)論課 CS 61A 就是以 Python 作為練習(xí)語言,但是似乎國內(nèi)很少有高校開這種導(dǎo)論課。
但是 C、C++ 這種語言,不學(xué)個一兩個月,連個像樣的程序都寫出來,這種才是適合開一門課。
先說一下學(xué)習(xí) C 語言的目的,上面我說語言不是重點,這也包括 C 語言。
但是 C 語言特殊就特殊在它可能是唯一最適合用來學(xué)習(xí)一系列計算機基礎(chǔ)課的工具和媒介。
比如操作系統(tǒng),實驗幾乎都是用的純 C 寫的 lab;
又比如匯編,學(xué)習(xí)的時候可以和 C 語言對應(yīng)起來,了解if、for、while、數(shù)組訪問等對應(yīng)匯編是怎么樣的;
又比如學(xué)習(xí)計網(wǎng),這里面有很多的網(wǎng)絡(luò)協(xié)議,會有不同的 header 定義,這些 header 中很多都是按 bit 來劃分字段的,用 C 語言的 union 和 struct 是最好操作這些字段的,Java 和 Python 等語言雖然也能表示,但是可控性會差很多,以前嘗試過用 Python 去組裝 IP 包頭,非常的麻煩也不優(yōu)雅。
并且 C 語言本身抽象層次非常低,語法也很簡單,沒什么語法糖,很貼近操作系統(tǒng)。
而其它很多解釋型語言會存在虛擬機這一層,虛擬機對我們算是一個黑盒,不利于透過語言去理解計算機的一些行為。
所以我之前在《如何成為一個計算機知識體系完整的畢業(yè)生》中把 C 語言也列為計算機專業(yè)的基礎(chǔ),而且是程序員必學(xué)的知識。
二、C 語言的優(yōu)點
C 語言已經(jīng)走過了四十多年的歷史,但是在今天,任然常年霸占 TIOBE 編程語言排行榜前三,甚至榜首,這足以說明它是一門經(jīng)久不衰的語言。
在日新月異的計算機行業(yè),一個歷經(jīng)四十多年任然流行的技術(shù),才是需要我們?nèi)リP(guān)注和學(xué)習(xí)的經(jīng)典。
我在那篇文章中說 C 語言是最適合用來理解計算機系統(tǒng)底層機制的語言,那今天就詳細說說,這些底層機制都有哪些:
內(nèi)存
一名合格的程序員必須了解內(nèi)存,學(xué)習(xí) C 語言是了解內(nèi)存布局最直接、有效的途徑,大家可以看到之前講解指針那篇文章--深入理解內(nèi)存和指針,全部都是從內(nèi)存、內(nèi)存布局出發(fā)進行講解。
堆棧
理解不同的內(nèi)存分配和管理方式,一種編譯器自動管理,一種是手動管理。
函數(shù)調(diào)用棧、返回值
理解函數(shù)調(diào)用的本質(zhì),即跳轉(zhuǎn)指令,理解返回值是怎么返回的。
系統(tǒng)調(diào)用
比如理解文件描述符,知道文件、socket 這些都被抽象成了fd。
指針
指針也是其它語言中引用的基礎(chǔ),深入理解指針對于理解引用也有很大幫助。
就拿文件來說,在 C 語言 中經(jīng)常會接觸到 read、write 系統(tǒng)函數(shù),清楚操作的打開文件對應(yīng)的是文件描述符。
而文件描述符是有限的,所以你知道用完 fd 后要及時關(guān)閉。
甚至用到 socket 網(wǎng)絡(luò)編程的時候會發(fā)現(xiàn),socket 返回的也是 fd,居然網(wǎng)絡(luò)數(shù)據(jù)也能通過 read、write 去讀寫。
深刻的體會到 Unix 哲學(xué):一切皆文件。
而在 Java、Python、PHP 這些語言中,打開一個文件只需要調(diào)用 File.open 或是 open,然后就可以拿到一個對象,然后對這個對象去調(diào)用讀寫方法進行操作。
但這時候文件對于我們更像是一個資源,全部的細節(jié)都被對象屏蔽了,而老師說資源是有限的,所以用完了要及時釋放。
而你也不知道如果不釋放這些資源會有什么后果,只是聽老師說用完的資源及時釋放是個好習(xí)慣。
在這里,操作系統(tǒng)的文件系統(tǒng)、進程等很多實現(xiàn)機制就被 JVM、Python 虛擬機所隱藏了。
而和操作系統(tǒng)等密切相關(guān)的底層機制也只有通過學(xué)習(xí) C 語言才能透徹地理解它們。
這里又有個矛盾,上面說的這些內(nèi)容其實不單單是 C 語言課所教的,其中還包括《組成原理》、《匯編》、《操作系統(tǒng)》等。
所以就出現(xiàn)了很多同學(xué)說的,就算上了 C ?語言課,上面這些很多原理也還是不知道呀。
當然,這些內(nèi)容是需要在大二、大三上專業(yè)課逐漸補齊的,但是先學(xué) C 語言給學(xué)習(xí)這些內(nèi)容打下了一個基礎(chǔ),大一把內(nèi)存和指針理解透徹就好了,這就是前置條件。
而如果大一不上 C 語言,那么后續(xù)需要用到 C 語言的時候,自學(xué)的難度會高于自學(xué) Python、Java 等語言。
比如有些學(xué)校在操作系統(tǒng)課會引入一些國外的 Lab,諸如 MIT 6.828 xv6 那樣的 mini os,需要學(xué)生動手去完成一些內(nèi)存管理、多線程實現(xiàn)、文件系統(tǒng)等操作系統(tǒng)核心模塊。
比如清華 OS 課程用的 ucore,哈工大 OS 課程用的 linux-0.11,這些都是純 C 寫的。
如果沒 C 的基礎(chǔ),連實驗都沒法繼續(xù),而這些實驗算是操作系統(tǒng)課程的精髓了。
所以這才是我認為大一先上 C 語言的核心原因:
一是語法簡單,更加貼近計算機本質(zhì)的一些東西,學(xué) C 也不是簡單的學(xué)語言本身,而是想透過 C 語言去理解一些如寄存器、內(nèi)存、函數(shù)調(diào)用、跳轉(zhuǎn)等東西。
二是為大二、大三階段的專業(yè)課打下一個基礎(chǔ),當然很多同學(xué)說我不學(xué) C 一樣可以學(xué)操作系統(tǒng)、計網(wǎng)呀。
當然,這些和 C 沒必然關(guān)聯(lián),只是很多實驗?zāi)愦_實不好繼續(xù)做,除非你只打算看看概念,背背什么是進程、線程。
三、如何正確的打開 C 語言?
我認為 C 語言最為核心的有三塊:
指針
內(nèi)存
系統(tǒng)編程
首先指針和內(nèi)存是需要在學(xué)習(xí) C 語言過程中就理解、搞定的,推薦兩本書:
《C程序設(shè)計語言》、《C和指針》
如果你覺得初學(xué)看書過于困難,那么可以去中國大學(xué) MOOC 上浙大翁凱老師的 C 語言課,可以直接去 B 站搜。
視頻結(jié)合書一起看,相信會理解得更加深刻。
然后,學(xué)習(xí)完了 C 語言基本語法后,你會發(fā)現(xiàn)似乎只能開發(fā)在黑窗口里運行的程序,寫不出那些漂亮的 GUI。
確實,C 語言本來就不擅長做這些,C 語言擅長的是開發(fā)系統(tǒng)組件來支撐上層應(yīng)用。
但是如果你迫切的想做出一些可視化、有趣的東西,那么可以這樣做:
找一些 C 語言的圖形庫,比如 easyx,借助這些圖形庫,你完全可以實現(xiàn)一些圖形界面的游戲。
繼續(xù)去學(xué) Python、Java 這種語言,然后學(xué)習(xí) Web 開發(fā),寫寫網(wǎng)頁。
當然了,如果你對那些可視化的東西沒那么大興趣,甚至還挺喜歡黑窗口的,那么恭喜你,你有成為大佬的潛質(zhì)。
當你熟悉完 C 語言基本的語法以后,建議去學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法,用 C 語言去實現(xiàn)鏈表、樹、二叉樹、堆、排序、搜索等等。
推薦看看《算法:C語言實現(xiàn)》這本書。
如果能通過 void 指針實現(xiàn)一些泛型數(shù)據(jù)結(jié)構(gòu)就更棒了,比如標準庫里的 qsort 就能支持任意可比較結(jié)構(gòu)體排序。
然后,時間應(yīng)該很快來到了大二、大三,這時候你應(yīng)該學(xué)習(xí)系統(tǒng)編程,什么是系統(tǒng)編程呢,其實就是 CSAPP 這本書上所講授的內(nèi)容。
系統(tǒng)編程其實就是學(xué)習(xí)如何用 C 語言編寫出真正可用的軟件,比如像 http server、redis 這種,會涉及到:
如何在 Linux 環(huán)境下編程
系統(tǒng)級接口(system-level interface)究竟是什么
Linux 內(nèi)核和 C 標準庫提供了哪些能力
Linux 的系統(tǒng)調(diào)用是怎樣實現(xiàn)的
都有哪些系統(tǒng)調(diào)用,如何使用
其它諸如mutex、signal、select、epoll、ipc、socket、thread、process(fork)等等
當然,還有一些同學(xué)會選擇繼續(xù)學(xué)習(xí) Java 這種,比如 JVM、多線程、Java Web 等等,這也是沒問題的。
但是,相信我,就算你以后不會用到 C 去編程,利用大學(xué)大把的時間去深入學(xué)習(xí)一些底層的知識。
也是對深入學(xué)習(xí) Java 有好處的,比如你學(xué) Netty、 Java 的 NIO 最終都要回到 Linux 系統(tǒng)的 epoll、select 上。
系統(tǒng)編程推薦《深入理解計算機系統(tǒng)》、《Unix網(wǎng)絡(luò)編程》、《Unix高級環(huán)境編程》,Windows 下的我基本沒學(xué)過,所以就不推薦了。
虛擬機之下的世界這就是 Java、Python 之下的世界,相信 Javaer 都學(xué)習(xí)過 JVM 的原理,了解過 GC、類加載機制、運行時數(shù)據(jù)區(qū)等知識。
但實際上,JVM 也只是介于操作系統(tǒng)之間的一個中間層。
很多時候 JVM、Python 解釋器等本身都是需要 Native 本地方法棧去和 OS 打交道的,去和系統(tǒng)調(diào)用接口交互。
所以 Linux 系統(tǒng)編程對于深入學(xué)習(xí)編程一定是繞不開(因為很多服務(wù)端程序都是運行在Linux上的,所以忽略了Win/Mac
而這是 C 語言的世界:
C所以 C 的重要性不需要的多說了吧~
不少 Java、C#、PHP、Python 程序員工作幾年后會遇到瓶頸,有些會回來學(xué)習(xí) C 語言,重拾底層概念,尋求新的突破。
這里不是在否定其它非 C 程序員就沒技術(shù),實際上我本身也不寫 C,我只是想表達如果你想學(xué)習(xí)底層機制、操作系統(tǒng)等,請學(xué)習(xí) C 語言。
編程學(xué)到一定的時候,你就需要了解底層系統(tǒng)的機制,否則,知其然不知所以然。
真正的高手往往都是有很強的系統(tǒng)性基礎(chǔ)知識的,表面的東西永遠是膚淺的。
所以利用大學(xué)的時間恰恰是打好這些基礎(chǔ)的關(guān)鍵時間,等到工作了,大家都是更傾向于學(xué)習(xí)快速上手業(yè)務(wù)的技能。
所以,在大學(xué)里先學(xué)什么語言不重要,你可以先學(xué) Python、Java,但是無論如何,如果你想學(xué)好 Computer Science,C 語言一定繞不開。
也許以后實際工作中你完全沒有機會去寫 C,但是這并沒關(guān)系,打好了基礎(chǔ),學(xué)其它也會學(xué)得很快、很透徹。
對于計算機專業(yè)的同學(xué),還是建議學(xué)好 C 語言,與其它課程相結(jié)合,多懂一點程序背后的實現(xiàn)原理。
最后上兩張圖,什么叫真正的技術(shù)啊(戰(zhàn)術(shù)后仰
培訓(xùn)班還教微服務(wù),這種不是玩概念么?
不去公司上手真正的微服務(wù)項目,在學(xué)校、培訓(xùn)班搭微服務(wù)?
這種東西學(xué)習(xí)下概念和思想就好了,這些東西根本就是應(yīng)用層的東西,學(xué)習(xí)起來根本不費勁的好吧。
我敢保證,沒有一個 985 會教微服務(wù)這種東西,分布式理論倒是可能會單獨開一門課。
不過我相信上面圖片里的這個分布式一定不會教CAP、Raft、Paxos 這些東西,大概率是用 Springboot + Dubbo + Zookeeper 在幾臺機器搭建一個服務(wù)。。。
科班而這是科班的學(xué)習(xí)路線,先不說這些課程有多少是學(xué)過就忘了的,但至少你需要用到的時候知道去哪撿起來,怎么撿。
不過講道理兩張圖片,殊途同歸,最后都是碼農(nóng),只不過大概率決定了你在哪里敲代碼。
總結(jié)一下,BB 了這么多,就想表達一個意思,C 語言很重要,如果你正在大學(xué)學(xué) C,一定要掌握好,不要懷疑學(xué) C 有沒有用。
由于微信平臺算法改版,公號內(nèi)容將不再以時間排序展示,如果大家想第一時間看到我們的推送,強烈建議星標我們和給我們多點點【在看】。星標具體步驟為:
總結(jié)
以上是生活随笔為你收集整理的你已经是个成熟的985大学了,请不要在大一教 C 语言!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 资源分享 | 统计学最全思维导图,附下载
- 下一篇: 求你了,别再用 print 调试代码了