回答者1
電腦科學有兩類根本問題。一類是理論:演算法,資料結構,複雜度,機器學習,模式識別,等等等。一類是系統:作業系統,網路系統,分布式系統,儲存系統,遊戲引擎,等等等等。
理論走的是深度,是在追問在給定的計算能力約束下如何把乙個問題解決得更快更好。而系統走的是廣度,是在追問對於乙個現實的需求如何在眾多的技術中設計出最多快好省的技術組合。
搞acm的人,只練第一類。像你這樣的更偏向於第二類。其實挺難得的,但很可惜的是第二類能力沒有簡單高效的測量考察方法,不像演算法和資料結構有acm競賽,所以很多系統的苗子都因為缺少激勵和正確引導慢慢就消隱了。
所以比爾蓋茨才會說,看到現在學程式設計的人經常都把程式設計看作解各種腦筋急轉彎的問題,他覺得很遺憾。
做系統,確實不提倡「重**明輪子」。但注意,是不提倡「重**明」,不是不提倡「重新製造」。恰恰相反的,我以為,系統的程式設計能力正體現在「重新製造」的能力。
能把已有的部件接起來,這很好。但當你恰好缺一種關鍵的膠水的時候,你能寫出來嗎?當乙個已有的部件不完全符合你的需求的時候,你能改進它嗎?如果你用的部件中有bug,你能把它修好嗎?在網上繁多的類似功能的部件中,誰好誰壞?為什麼?差別本質嗎?乙個開源**庫,你能把它從乙個語言翻譯到另乙個語言嗎?從乙個平台移植到另乙個平台嗎?能準確估計自己翻譯和移植的過程需要多少時間嗎?能準確估計翻譯和移植之後效能是會有提公升還是會有所下降嗎?
系統程式設計能力體現在把已有的**拿來並變成更好的**,體現在把沒用的**拿來並變成有用的**,體現在把乙個做好的輪子拿來能畫出來輪子的設計藍圖,並用道理解發布設計藍圖中哪些地方是關鍵的,哪些地方是次要的,哪些地方是不容觸碰的,哪些地方是還可以改進的。
如果你一點不懂理論,還是應該學點的。對於系統效能的設計上,演算法和資料結構就像在自己手頭的錢一樣,它們不是萬能的,但不懂是萬萬不行的。
怎麼提高系統程式設計能力呢?土辦法:多造輪子。就像學畫畫要畫雞蛋一樣,不是這世界上沒有人會畫雞蛋,但畫雞蛋能馴服手指,感受陰影線條和筆觸。所以,自己多寫點東西吧。寫個編譯器?渲染器?作業系統?web伺服器?web瀏覽器?部件都乙個個換成自己手寫的,然後和已有的現成部件比一比,看看誰的效能好,誰的易用性好?好在哪兒?差在哪兒?為什麼?
更聰明一點的辦法:多拆輪子。多研究別人的**是怎麼寫的。然而這個實踐起來經常很難。原因:大部分工業上用的輪子可能設計上的思想和技術是好的,都設計和製造過程都很爛,裡面亂成一團,讓人乍一看毫無頭緒,導致其對新手來說非常難拆。這種狀況其實非常糟糕。所以,此辦法一般只對比較簡單的輪子好使,對於複雜的輪子,請量力而行。
輪子不好拆,其實是乙個非常嚴重的問題。重**明輪子固然是時間的浪費,但當輪子複雜而又不好拆的時候,尤其是原來造輪子的人已經不在場的時候,重新發明和建造輪子往往會成為無奈之下最好的選擇。這是為什麼工業界在明知道重**明/製造輪子非常不好的情況下還在不斷重**明/製造輪子的根本原因。
程式本質是邏輯演繹的形式化表達,記載的是人類對這個世界的數位化理解。不能拆的輪子就像那一篇篇丟了曲譜的宋詞一樣,能讀,卻不能唱。
回答者2
懂得取捨。
在有限的時間內,幾乎沒有系統可以做到完美。要快,要安全,高併發,易擴充套件,效率高,容易讀,高內聚,低耦合…
大到乙個**,小到幾個class,工程師都要清楚,要取什麼,舍什麼,這並不是那麼容易的事。我們都有自己的性格,有的求新,有的求穩,有的求快,但具體到乙個專案時,知道如何取捨對這個專案最好,很重要。
學校裡的作業,沒人在意你是不是寫在乙個大的main()裡面,能跑就行。但做專案的時候,太多的東西要考慮,有時候,寧可簡單易讀,也不用快那麼一點點;有時候,要做太多看不到的工作,卻絲毫馬虎不得;有時候,寫了不如不寫,留白也是乙個學問。
曾經接手個專案,裡面幾乎所有的class,每個都有inte***ce,各種繼承,各種實現,理由是靈活性高,易擴充套件。真的易擴充套件嗎?
我不知道。沒多久,客戶的需求就改了,各種拎不清的繼承實現都化為烏有,一大半要重寫。
問題在**?
不是程式設計不好,而是取捨的不好。在那個階段,為30%的需求,花200%的努力,追求設計的滴水不漏,卻捨棄快速實現,取得反饋的時機,這就是失誤。需求總會變,客戶看到越早,修改越早,影響越小。
很聰明的人,也可能做出很難用的系統,不一定是程式設計不好,可能是不願,或不屑於取捨。不同的階段,不同的專案,要取捨的東西也不同。程式設計只是手段,目的是解決問題,能力高不高,要看問題解決的好不好。不在於使用了什麼高階演算法,或是複雜的框架。
懂得如何取捨並不容易,需要對問題的深刻理解,對技術的胸有成竹,和身後無數個踩過的坑。但重要的是有取捨的意識,主動思考取捨什麼,這樣學的才會快。
回答者3
既然說的是程式設計能力,那首先就先把學術相關的能力排除才能說的清楚
接下來是我對程式設計的定義:所謂程式設計,就是預先設計好方案來指揮行為可**的系統來自動(與臨時手動相對)達到的想要的結果。從廣義上說,企業家對乙個公司的運作方式進行設計,然後這個公司自動執行產生利潤也是一種程式設計
那麼程式設計能力體現在兩點
1.對可**系統的理解:理解越深,**能力越強,自己的智慧型才越好發揮。這就是為什麼學習軟體程式設計最快的方式之一是「造輪子」
2.如何把自己的目標轉化成指揮方案,這其實就是「做應用題」的能力,我們從小學就在練習這個能力。現實世界的應用題可不會告訴你用什麼知識點去建模,也不會透露全部必要條件,因此增強這個能力需要深刻理解現實世界的運作方式。在軟體行業,這被稱作「理解垂直行業的業務邏輯」
順帶說一下,所謂「hacking」,其實就是在深刻理解乙個系統的基礎上,用最小的代價改變這個系統來達到自己的目的。「hacking」之所以看起來出人意料,就是因為理解越深刻,需要的做的改動越少。如果理解不深刻,那就要從頭造乙個系統了,那就不聰明了
回答者4
對於程式設計能力這個問題其實我也想過很久,這個東西確實非常難界定。單純靠演算法水平、程式設計速度、工程經驗都很難說是程式設計能力。
雖然這個東西的影響因素非常龐大,但從我日常的工作來看,其實我覺得衡量程式設計水平最靠譜的方法是觀察這個程式設計師 debug 的能力。
程式從本質上來說就是 輸入 -> 處理 -> 輸出 的過程,而中間的處理就像是乙個巨大的黑盒子。而這個黑盒子的本身就是程式,在大多數情況下你並不能看到這個黑盒子的全貌。從常識上寫乙個不存在 bug 的程式是一件 幾乎 不可能完成的任務。即使是敲個最簡單的 hello world 程式,你也很難保證編譯器不給你抽幾下風。尤其是當這個程式變得非常龐大時,寫程式這件事的本身就是 盲人摸象 的過程。程式設計師必須要有相當好的 全域性觀 ,才能保證自己的程式良好執行而不出問題,並能在出了問題之後能夠做出迅速的定位和修復。
所以觀察乙個程式設計師能否 迅速debug 的過程就是乙個很好的判斷依據。我舉個例子來說,我幾周前給手機刷了機,第二天早上準備去晨跑,發現手機 gps 不工作。於是我立刻分析了出現問題可能的地方:
gps 模組硬體 -> gps 驅動 -> 系統配置 -> gps 許可權 -> 軟體相容性
由於想起剛刷了機,基本可以排除硬體問題。而軟體之前同樣在其它 android 5.1 機器上跑過,同時跑了下 google maps 也不能定位,排除相容性問題。原生系統的許可權系統非常簡單,基本排除是許可權。出問題的可能是第三方 rom 的驅動有問題或者配置檔案。觀察到 a-gps 基站輔助定位也不工作,基本排除 gps 驅動問題。確認是配置檔案有問題,檢查 /etc/gps.conf 竟是空檔案。於是就在手機上用文字編輯器順手碼了一段配置,重啟後問題修復。
這就是一次非常流暢準確的對乙個未知的 bug 定位和修復的過程。
由於 bug 的未知性,可以很好避免一些你在判斷時可能遇到的 作弊 情況,我們知道現在很多人為了面試無所不用其極。就算是以前非常經典的面試問題,現在也很不靠譜。現在你問 「如何理解物件導向程式設計?」 和你對答如流的人可能並不真正理解 oop,不過背的很熟而已。以前覺得演算法是個很好驗證水平的切入點,自從 leetcode 背題流的出現,這招現在也不怎麼靠譜。而 debug 是個無法 提前準備的東西,所以對於程式設計能力的校驗通常很準確。
而且,debug 的過程中會接觸到自己很多不熟悉的知識。由於程式設計本身就是乙個 engineering,正常的過程就是在 碼字 -> 出問題 -> 學習 -> 修改 的過程中迴圈。如果你對演算法不熟悉,那麼遇到程式效能問題的時候你硬著頭皮也要用學習演算法知識來解決掉。所以這是一項非常綜合的能力,是程式設計師 知識、智力、經驗 的綜合體現。
至於如何提公升程式設計能力?
多寫、多錯、多學。沒有捷徑,捷徑只不過是作弊。作弊能幫你找到工作,但並不能真正解決問題。
回答者5
mit演算法導論第一堂課:
每天都程式設計 x年後一定會變成專家 (忘了x多少 不是重點
輪子多造多模仿 能力自然提公升
什麼發展都是從量到質的 要相信
現在我也是搞系統程式設計 除了看source code和造輪
也是可以有空刷刷acm的
而且只有幫助沒有壞處喔
系統程式設計一旦考慮到效能問題 離不開經典的一些演算法的
顯然大部分的我們都不會成為高手如溫趙輪
但是成為程式設計好手 進個好公司 錢多賺些 生活舒服些 應該是普遍程式設計師的共同目標
不要想太多 拼命code就是了
都不知道宣傳不要重複造輪子的人是懷著什麼險惡的用心,原話明明是不要重新發明輪子。
這是什麼意思呢?就是說你要多看**多看書,少抄**。
回答者6
程式設計師就是把人類的需求語言翻譯成計算機語言的人,所以可以通用譯事三難:「信、達、雅」。
回答者7
其實,搭**,寫mis/cms/erp這些,就算是一行行的寫**,結果也只能是你的領域知識不斷提公升,對於「程式設計能力」的提公升沒有多少的。就像是你根本無法解釋在你寫的系統中哪個地方應用了動態規劃一樣。
所以相對來說你所需要的是一些電腦科學內的領域知識。
還有,假如你寫了**要給別人看和給其他程式設計師用,應該就開始慢慢考慮介面和設計了。
或者你需要的是一本分析模式?
回答者8
看看別人的輪子的形貌(主要是介面,其次是效率)之後自己造乙個輪子
其實 stl 原始碼剖析 和 modern c++ design 不錯,唯一問題是選擇了 c++ 做教學語言
有興趣可以學點認知和設計來了解好的介面長得是怎樣的
回答者9
第1層:能做成東西(能執行)
第2層:做的東西能長時間或高負荷地執行
第3層:做的東西能長時間在高負荷下執行
第4層:能預先知道什麼才是客戶/行業需要的功能,並以最符合的代價(金錢、硬體、期限、人力)實現
什麼才算是真正的程式設計能力?
知乎上看到一題主的發問 還在讀書,也在實驗室幫忙做了些東西,自己也搭過幾個 在周圍人看來似乎好像我很厲害,做了那麼多東西,但是我發現這些東西雖然是我做的,但是實際上我手把手自己寫的 卻並沒有多少,很多都是用開源的東西,我寫的 無非是把別人的東西整合下,類似於膠水一樣的工作。我之前所認為的程式設計是全...
什麼才算是真正的程式設計能力?
電腦科學有兩類根本問題。一類是理論 演算法,資料結構,複雜度,機器學習,模式識別,等等等。一類是系統 作業系統,網路系統,分布式系統,儲存系統,遊戲引擎,等等等等。理論走的是深度,是在追問在給定的計算能力約束下如何把乙個問題解決得更快更好。而系統走的是廣度,是在追問對於乙個現實的需求如何在眾多的技術...
什麼才算是真正的程式設計能力?
電腦科學有兩類根本問題。一類是理論 演算法,資料結構,複雜度,機器學習,模式識別,等等等。一類是系統 作業系統,網路系統,分布式系統,儲存系統,遊戲引擎,等等等等。理論走的是深度,是在追問在給定的計算能力約束下如何把乙個問題解決得更快更好。而系統走的是廣度,是在追問對於乙個現實的需求如何在眾多的技術...