問題:甚么才算是真實的編程能力?
還 在讀書,也在實驗室幫忙做了些東西,自己也搭過幾個網站。在周圍人看來似乎好像我很利害,做了那末多東西,但是我發現這些東西雖然是我做的,但是實際上我 手把手自己寫的代碼卻并沒有多少,很多都是用開源的東西,我寫的代碼不過是把他人的東西整合下,類似于膠水1樣的工作。
我之前所認為的編程是全手動1行1行敲代碼,但是現在我發現哪怕是工程上也有很多人是復制黏貼來解決問題的,并且提倡不要重復造輪子。
但是靠谷歌和復制他人的輪子,雖然我做出了很多東西,可是我其實不覺得自己能力上有提升,倒是利用搜索引擎的能力的確提升了很多。而學校里另外1波弄ACM的人,他們每天刷題練算法,也許倒是的確提升了點編程能力,但是對工程幾近1竅不通。
所以我現在就很困惑,所謂的編程能力究竟是甚么,我該如何提升自己的編程能力?
回答者:劉賀,...
非常好的1個問題。這多是我在知乎見到過的問編程有關的問題中問得最好的1個了。我非常喜歡這個問題。
計算機科學有兩類根本問題。1類是理論:算法,數據結構,復雜度,機器學習,模式辨認,等等等。1類是系統:操作系統,網絡系統,散布式系統,存儲系統,游戲引擎,等等等等。
理論走的是深度,是在追問在給定的計算能力束縛下如何把1個問題解決得更快更好。而系統走的是廣度,是在追問對1個現實的需求如何在眾多的技術中設計出最多快好省的技術組合。
弄ACM的人,只練第1類。像你這樣的更偏向于第2類。其實挺難得的,但很惋惜的是第2類能力沒有簡單高效的丈量考察方法,不像算法和數據結構有ACM比賽,所以很多系統的苗子都由于缺少鼓勵和正確引導漸漸就消隱了。
所以比爾蓋茨才會說,看到現在學編程的人常常都把編程看做解各種腦筋急轉彎的問題,他覺得很遺憾。
做系統,確切不提倡“重復發明輪子”。但注意,是不提倡“重復發明”,不是不提倡“重新制造”。恰恰相反的,我以為,系統的編程能力正體現在“重新制造”的能力。
能 把已有的部件接起來,這很好。但當你恰好缺1種關鍵的膠水的時候,你能寫出來嗎?當1個已有的部件不完全符合你的需求的時候,你能改進它嗎?如果你用的部 件中有bug,你能把它修睦嗎?在網上繁多的類似功能的部件中,誰好誰壞?為何?差別本質嗎?1個開源代碼庫,你能把它從1個語言翻譯到另外一個語言嗎? 從1個平臺移植到另外一個平臺嗎?能準確估計自己翻譯和移植的進程需要多少時間嗎?能準確估計翻譯和移植以后性能是會有提升還是會有所降落嗎?
系統編程能力體現在把已有的代碼拿來并變成更好的代碼,體現在把沒用的代碼拿來并變成有用的代碼,體現在把1個做好的輪子拿來能畫出來輪子的設計藍圖,并用道理解釋出設計藍圖中哪些地方是關鍵的,哪些地方是次要的,哪些地方是不容觸碰的,哪些地方是還可以改進的。
如果你1點不懂理論,還是應當學點的。對系統性能的設計上,算法和數據結構就像在自己手頭的錢1樣,它們不是萬能的,但不懂是萬萬不行的。
怎 么提高系統編程能力呢?土辦法:多造輪子。就像學畫畫要畫雞蛋1樣,不是這世界上沒有人會畫雞蛋,但畫雞蛋能馴服手指,感受陰影線條和筆觸。所以,自己多 寫點東西吧。寫個編譯器?渲染器?操作系統?web服務器?web閱讀器?部件都1個個換成自己手寫的,然后和已有的現成部件比1比,看看誰的性能好,誰 的易用性好?好在哪兒?差在哪兒?為何?
更 聰明1點的辦法:多拆輪子。多研究他人的代碼是怎樣寫的。但是這個實踐起來常常很難。緣由:大部份工業上用的輪子可能設計上的思想和技術是好的,都設計和 制造進程都很爛,里面亂成1團,讓人乍1看毫無頭緒,致使其對新手來講非常難拆。這類狀態其實非常糟。所以,此辦法1般只對照較簡單的輪子好使,對復 雜的輪子,請實事求是。
輪 子不好拆,實際上是1個非常嚴重的問題。重復發明輪子固然是時間的浪費,但當輪子復雜而又不好拆的時候,特別是原來造輪子的人已不在場的時候,重新發明和 建造輪子常常會成為無奈之下最好的選擇。這是為何工業界在明知道重復發明/制造輪子非常不好的情況下還在不斷重復發明/制造輪子的根本緣由。
程序本質是邏輯演繹的情勢化表達,記載的是人類對這個世界的數字化理解。不能拆的輪子就像那1篇篇丟了曲譜的宋詞1樣,能讀,卻不能唱。
鄙人不才,正在自己研究怎樣設計建造1種既好用又好拆的輪子。您沒那末榮幸,恐怕是等不到鄙人的技術做出來并發揚光大了。在那之前,多造輪子,多拆好拆的小輪子,應當是提高編程能力最好的辦法了。
回答者:mu peng,less is more
曉得取舍。
在有限的時間內,幾近沒有系統可以做到完善。要快,要安全,高并發,易擴大,效力高,容易讀,高內聚,低耦合...
大到1個網站,小到幾個class,工程師都要清楚,要取甚么,舍甚么,這其實不是那末容易的事。我們都有自己的性格,有的求新,有的求穩,有的求快,但具體到1個項目時,知道如何取舍對這個項目最好,很重要。
學校里的作業,沒人在乎你是否是寫在1個大的main()里面,能跑就行。但做項目的時候,太多的東西要斟酌,有時候,寧可簡單易讀,也不用快那末1點點;有時候,要做太多看不到的工作,卻絲毫馬虎不得;有時候,寫了不如不寫,留白也是1個學問。
曾接手個項目,里面幾近所有的class,每一個都有interface,各種繼承,各種實現,理由是靈活性高,易擴大。真的易擴大嗎?
我不知道。沒多久,客戶的需求就改了,各種拎不清的繼承實現都子虛烏有,1大半要重寫。
問題在哪里?
不是編程不好,而是取舍的不好。在那個階段,為30%的需求,花200%的努力,尋求設計的滴水不漏,卻舍棄快速實現,獲得反饋的時機,這就是失誤。需求總會變,客戶看到越早,修改越早,影響越小。
很聰明的人,也可能做出很難用的系統,不1定是編程不好,多是不愿,或不屑于取舍。不同的階段,不同的項目,要取舍的東西也不同。編程只是手段,目的是解決問題,能力高不高,要看問題解決的好不好。不在于使用了甚么高端算法,或是復雜的框架。
曉得如何取舍其實不容易,需要對問題的深入理解,對技術的成竹在胸,和身后無數個踩過的坑。但重要的是有取舍的意識,主動思考取舍甚么,這樣學的才會快。
回答者:李遙,A Programmer
既然說的是編程能力,那首先就先把學術相干的能力排除才能說的清楚
接下來是我對編程的定義:所謂編程,就是預先設計好方案來指揮行動可預測的系統來自動(與臨時手動相對)到達的想要的結果。從廣義上說,企業家對1個公司的運作方式進行設計,然后這個公司自動運行產生利潤也是1種編程
那末編程能力體現在兩點
1.對可預測系統的理解:理解越深,預測能力越強,自己的智慧才越好發揮。這就是為何學習軟件編程最快的方式之1是“造輪子”
2. 如何把自己的目標轉化成指揮方案,這其實就是“做利用題”的能力,我們從小學就在練習這個能力。現實世界的利用題可不會告知你用甚么知識點去建模,也不會 流露全部必要條件,因此增強這個能力需要深入理解現實世界的運作方式。在軟件行業,這被稱作“理解垂直行業的業務邏輯”
順帶說1下,所謂“Hacking”,其實就是在深入理解1個系統的基礎上,用最小的代價改變這個系統來到達自己的目的。“Hacking”之所以看起來出人意料,就是由于理解越深入,需要的做的改動越少。如果理解不深入,那就要從頭造1個系統了,那就不聰明了
回答者:丁盛豪,網絡媒體HeckPsi.com開創人
對編程能力這個問題其實我也想過很久,這個東西確切非常難界定。單純靠算法水平、編程速度、工程經驗都很難說是編程能力。
雖然這個東西的影響因素非常龐大,但從我平常的工作來看,其實我覺得衡量編程水平最靠譜的方法是視察這個程序員 Debug 的能力。
程 序從本質上來講就是 輸入 -> 處理 -> 輸出 的進程,而中間的處理就像是1個巨大的黑盒子。而這個黑盒子的本身就是程序,在大多數情況下你其實不能看到這個黑盒子的全貌。從常識上寫1個不存在 bug 的程序是1件 幾近 不可能完成的任務。即便是敲個最簡單的 Hello World 程序,你也很難保證編譯器不給你抽幾下風。特別是當這個程序變得非常龐大時,寫程序這件事的本身就是 盲人摸象 的進程。程序員必須要有相當好的 全局觀 ,才能保證自己的程序良好運行而不出問題,并能在出了問題以后能夠做出迅速的定位和修復。
所以視察1個程序員能否 迅速Debug 的進程就是1個很好的判斷根據。我舉個例子來講,我幾周前給手機刷了機,第2天早上準備去晨跑,發現手機 GPS 不工作。因而我立刻分析了出現問題可能的地方:
GPS 模塊硬件 -> GPS 驅動 -> 系統配置 -> GPS 權限 -> 軟件兼容性
由 于想起剛刷了機,基本可以排除硬件問題。而軟件之前一樣在其它 Android 5.1 機器上跑過,同時跑了下 Google Maps 也不能定位,排除兼容性問題。原生系統的權限系統非常簡單,基本排除是權限。出問題的多是第3方 ROM 的驅動有問題或配置文件。視察到 A-GPS 基站輔助定位也不工作,基本排除 GPS 驅動問題。確認是配置文件有問題,檢查 /etc/gps.conf 竟是空文件。因而就在手機上用文本編輯器順手碼了1段配置,重啟后問題修復。
這就是1次非常流暢準確的對1個未知的 Bug 定位和修復的進程。
由 于 Bug 的未知性,可以很好避免1些你在判斷時可能遇到的 做弊 情況,我們知道現在很多人為了面試無所不用其極。就算是之前非常經典的面試問題,現在也很不靠譜。現在你問 “如何理解面向對象編程?” 和你對答如流的人可能其實不真正理解 OOP,不過背的很熟而已。之前覺得算法是個很好驗證水平的切入點,自從 LeetCode 背題流的出現,這招現在也不怎樣靠譜。而 Debug 是個沒法 提早準備的東西,所以對編程能力的校驗通常很準確。
而 且,Debug 的進程中會接觸到自己很多不熟習的知識。由于編程本身就是1個 Engineering,正常的進程就是在 碼字 -> 出問題 -> 學習 -> 修改 的進程中循環。如果你對算法不熟習,那末遇到程序性能問題的時候你硬著頭皮也要用學習算法知識來解決掉。所以這是1項非常綜合的能力,是程序員 知識、智力、經驗 的綜合體現。
至于如何提升編程能力?
多寫、多錯、多學。沒有捷徑,捷徑只不過是做弊。做弊能幫你找到工作,但其實不能真正解決問題。
回答者:陳浩駿,call me Reid / 會寫Java的猴子
MIT算法導論第1堂課:
每天都編程 x年后1定會變成專家 (忘了x多少 不是重點
輪子多造多模仿 能力自然提升
甚么發展都是從量到質的 要相信
現在我也是弄系統編程 除看source code和造輪
也是可以有空刷刷acm的
而且只有幫助沒有壞處喔
系統編程1旦斟酌到效能問題 離不開經典的1些算法的
明顯大部份的我們都不會成為高手如溫趙輪
但是成為編程好手 進個好公司 錢多賺些 生活舒服些 應當是普遍程序員的共同目標
不要想太多 拼命code就是了
共勉
如此。
回答者:vczh,專業造輪子 https://github.com/vczh-libraries
都不知道宣揚不要重復造輪子的人是懷著甚么險惡的用心,原話明明是不要重新發明輪子。
這是甚么意思呢?就是說你要多看論文多看書,少抄代碼。
回答者:達達,服務端程序員
程序員就是把人類的需求語言翻譯成計算機語言的人,所以可以通用譯事3難:“信、達、雅”。
回答者:Kim Leo
其實,搭網站,寫MIS/CMS/ERP這些,就算是1行行的寫代碼,結果也只能是你的領域知識不斷提升,對“編程能力”的提升沒有多少的。就像是你根本沒法解釋在你寫的系統中哪一個地方利用了動態計劃1樣。
所以相對來講你所需要的是1些計算機科學內的領域知識。
還有,假設你寫了代碼要給他人看和給其他程序員用,應當就開始漸漸斟酌接口和設計了。
或你需要的是1本分析模式?
回答者:JX Consp
看看他人的輪子的形貌(主要是接口,其次是效力)以后自己造1個輪子
其實 STL 源碼剖析 和 modern c++ design 不錯,唯1問題是選擇了 c++ 做教學語言
有興趣可以學點認知和設計來了解好的接口長得是怎樣的
回答者:海濤,軟件開發需要低本錢、快速響應
第1層:能做成東西(能運行)
第2層:做的東西能長時間或高負荷地運行
第3層:做的東西能長時間在高負荷下運行
第4層:能預先知道甚么才是客戶/行業需要的功能,并以最符合的代價(金錢、硬件、期限、人力)實現
回答者:DreamPiggy
多看書
多思考
改他人代碼
學他人的架構
做自己的軟件
寫自己的架構
也許如此循環就入坑了吧。