對程序員來講,什麼纔算是真正的編程能力?

能夠在業餘時間接app套殼上架的速速加我,長期合做,酬金豐厚,不容錯過!Q Q 273946117程序員

0:能夠徹底理解一問題,而且給出對應的代碼。算法

往窄了點說,這就是ACM在培養的東西。而且這不能靠調API徹底解決:有的時候,問題須要把多個標準算法串一塊兒。數據庫

好比說最近有個把STLC AST從implicit sharing變成explicit sharing的任務,這靠LCA+reverse topo dependency calculation(沒這步LCA的時候Scope跟着Term一塊兒被Reorder了,根本作不出),最後接上Metaocaml style letlist,搞定。編程

有的時候,根本沒有任何API,需求是從一個算法改爲另外一個。好比說D*算法複雜度是O(nv^3)的,很很差,想優化下,把複雜度往降低點,這同樣沒有任何包能夠調。app

往廣了說,大一點的需求也能用這種能力。既然有‘組合性’這個概念,就能倒過來,給出一個大型問題,分解成多個子問題,各個被單獨解決後再組合一塊兒。ide

名書SICP裏面就很推崇這種‘理解,分解,破解’的套路,而圖靈獎得主Edward Dijkstra甚至更極端,認爲這方法是惟一一種編程的方法。不管這是否是惟一法,這能力都是很不可或缺的基本功。工具

當掌握這方法之後,會發現作的不少是在腦殼中去推敲這問題的性質,試圖分解這個問題,若是能夠的話調用/組合已有API/算法。。是否是很像數學?由於計算機程序在某種意義上就是Mathematical Object - Curry Howard Isomorphism/Stepwise Refinement/Program Calculation都是在說這個。而當把這套玩熟,若是喜歡,甚至能夠作到正射必中:對於給定問題。性能

1:能在0之上加上工程方法。學習

有時候這套方法無論用:好比說跟其餘人在已有Code Base上協做,好比說需求變動了,好比說死活分解不出來,又好比說根本不知道具體的需求,得慢慢探索。其實這問題本質是,軟件實在太複雜了,一個數百萬行代碼的項目已經超越了人類物理意義上的理解極限 - 看都看不完。fetch

這也是爲何重頭起編寫一個系統很難:Spec太複雜,各個組件的Assumption太多,而且持續進化,不可能一口氣搞定,就算給定各個預先寫好的組件,也會由於Assumption不Match而難以組合在一塊兒,只能經過不停的Prototype,不停的重構,甚至不停的重寫來加深對系統的理解。

在這之上,SICP的‘一次性理解法’已經失效,這時候就須要不精確,比起邏輯學更像生物學的技巧 - 軟件工程了。

該怎麼設計?該怎麼重構?啥時候不重構而是頂着debt繼續往前(否則會無限重構作不出東西來)?該用啥技術?在各類tradeoff間如何選擇?再加上Debugger/Unit Test/CI/Git/Integration test這些Tool。

2:對整個計算機Stack有認識,能把各類技能混着耍

好比,學過計算機體系結構,明白Dennard Scaling死掉後單線程已經上不去,GPU等Massively Parallel Architecture是將來,而後給Neural network遷移上GPU(Deep Learning)。

而後,會Deep learning,發現給出的答案不必定是對的,可是能夠當Heuristic/Hint,給傳統方法加速(Alphago的MCTS(AI),Learn Indexed Structure中預測結果存在那(數據庫),AutoTVM的快速評分(編譯器),DeepCoder的下降搜索空間(Program Synthesis),Peloton的給數據庫預測負載(數據庫))

又或者,會FPGA,知道GPU之上還有不少優化空間,因而直接把整個Matrix Multiply Fuse成電路(TPU),又或者會Quantization,去研究怎麼給Quantized NN作ASIC(Bit Fusion)。

還有,會PL,發現Deep Learning的Computation Graph其實就是個first order PL,爲了加入控制流(RNN/LSTM/TreeLSTM)以Lambda Cube爲基礎設計一個IR,再想辦法在上面作反向傳播,來作Program optimization(TVM上的Relay)。

除了理解力到位,試圖把未知的新工具用上已知領域,還有個更簡單粗暴的用法:下降/消除低效接口帶來的額外開銷。

學了Memory Hierarchy之後,在用一個內存之前能夠提早fetch,下降軟件的Memory Access latency(Prefetching)

若是有FPGA,能夠把一部分任務Schedule並Offload上硬件,提升性能(Hardware/Software Codesign)

有Task要在Docker裏面跑?既然Docker都有保護了,那還憑啥要跑一個有保護模式的OS,要多個address space而且不停在Kernel/User上跑?Unikernel走起!

把這套玩到爐火純青,還能像Midori這樣,大手一揮,從新設計整個Software Stack,把裏面的各類多餘的抽象(Protection類型系統給了,就不須要OS上搞)整合掉。

對程序員來講,什麼纔算是真正的編程能力? 3:對不理解的CS&數學知識能在遇到的時候快速的補起來。

計算機科學實在太廣太深,學習中碰到不會的東西已是很正常了,因此說能力中還有一部分是:在代碼/paper中發現徹底不會的定義,如何在最短期內學習/跳過,並不影響後續理解/debug?

而這些概念不必定只有CS的,有時候還有數學,因此還要打好最低限度的數學基礎,達到‘看到不認識的數學定義不會去手足失措而是能慢慢啃/推敲’。不過還好,用到的數學跟數學系的雙比不深,挺喜歡的一篇paper,Partially-Static Data as Free Extension of Algebras 也就用到了Free Algebra,屬於很基礎的抽象代數,並沒深到那去,老闆給的Paper,Sampling Can Be Faster Than Optimization ,能抓出重點,搞懂Metropolis–Hastings跟MALA(Intro to Stats就會教了,很淺),而後明白主Theorem是啥,也就差很少了,畢竟CS水這麼深,主次要分清,數學能抓多少就抓多少吧。。

這些就是所認爲的不會隨着時間而失效,也不能被體力勞動+調包取代的,真正的編程能力:

不停擴充本身的toolbox,並對本身的tool或多或少有本質上的理解。(Machine Learning/GPU Programming)

根據本身對這些工具的理解,想出新的組合法。(Deep Learning)

把本身的idea構建成一個複雜,大而全的系統,而不只僅是一個玩具。(Pytorch)

落實到一個小功能的時候,能經過計算力,經過品味,設計出一個好用的API,編寫一個正確高效的實現。(Reverse Mode Automatic Differentiation)

若是要用一句話概況,猜編程能力是"對不一樣複雜度的問題(領域級/系統級/問題級),採用相對應工具下降複雜度,最後擊破"的能力吧。

相關文章
相關標籤/搜索