对程序员来讲,什么才算是真正的编程能力?

能够在业余时间接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)

若是要用一句话概况,猜编程能力是"对不一样复杂度的问题(领域级/系统级/问题级),采用相对应工具下降复杂度,最后击破"的能力吧。

相关文章
相关标签/搜索