文章转载自「开发者圆桌」一个关于开发者入门、进阶、踩坑的微信公众号web
问:搭过几个网站,在周围人看来彷佛好像我很厉害,作了那么多东西,可是我发现这些东西虽然是我作的,可是实际上我手把手本身写的代码却并无多少,不少都是用开源的东西,我写的代码无非是把别人的东西整合下,相似于胶水同样的工做。面试
我以前所认为的编程是全手动一行一行敲代码,可是如今我发现哪怕是工程上也有不少人是复制黏贴来解决问题的,而且提倡不要重复造轮子。算法
可是靠谷歌和复制别人的轮子,虽然我作出了不少东西,但是我并不以为本身能力上有提高,却是利用搜索引擎的能力的确提高了很多。而学校里另一部分在搞ACM「ACM程序设计大赛是大学级别最高的脑力竞赛,素来被冠以"程序设计的奥林匹克"的尊称。」的人,他们天天都在刷题练算法,但单凭我我的的感觉感受他们彷佛对工程上有些东西并不了解,或许算法的能力才算是实打实的编程能力?那"胶水"的能力和整合轮子的能力算不算编程能力呢?编程
因此我如今就很困惑,所谓的编程能力究竟是什么?该如何提高本身的编程能力?api
答:以问题为导向,编程只是手段,归根结底仍是解决问题的能力。浏览器
分清楚方向服务器
计算机科学有两类根本问题。一类是理论:算法,数据结构,复杂度,机器学习,模式识别,等等等。一类是系统:操做系统,网络系统,分布式系统,存储系统,游戏引擎,等等等等。微信
理论走的是深度,是在追问在给定的计算能力约束下如何把一个问题解决得更快更好。而系统走的是广度,是在追问对于一个现实的需求如何在众多的技术中设计出最多快好省的技术组合。网络
搞ACM的人,只练第一类。像你这样的更偏向于第二类。其实挺可贵的,但很惋惜的是第二类能力没有简单高效的测量考察方法,不像算法和数据结构有ACM竞赛,因此不少系统的苗子都由于缺乏激励和正确引导慢慢就消隐了。数据结构
因此比尔·盖茨才会说,看到如今学编程的人常常都把编程看做解各类脑筋急转弯的问题,他以为很遗憾。
以问题为导向
真正的编程能力其实并非对语法细节的理解,也不在于手写或者复制粘贴,更不在于对什么操做系统的使用,或者经常使用库的api的记忆。
而是找出解决方法的能力,把现实问题转换为代码逻辑的能力。这个是最重要的。语法很好学,只要看一看,再不行网上搜一搜都有,可是解决问题的能力,在网上搜不到,找不来,谁也帮不了。只能在长期的分析问题解决问题的过程当中获得。
在工做中,见过太多面试的时候打高分,把什么const char*, char const*, char*const i+++++i 这种奇技淫巧玩的烂熟,解决问题的时候束手无策的。只能你清晰明了的告诉他流程他才能实现。这样的人,要是不思进取,沉浸在这种不少公司禁用的语法技巧里沾沾自喜,可能永远只能是个代码流水线工人。
也有不少人面试的时候各类语法都模棱两可,提起作过的项目和程序,却可以条理清楚,头头是道。给他一个问题,他几分钟就给出还不错的解决方案。这样的人,随便什么语言,什么语法,什么库,对他来讲都是工具。他知道与否,都能最终解决问题。
其实无论是复制黏贴也好,本身手写也好,关键的是解决问题。编程最终仍是个生产工具,目的是解决问题,不能解决问题的,一切都是空中楼阁,毫无价值。
懂得取舍
曾经接手个项目,里面几乎全部的class,每一个都有interface,各类继承,各类实现,理由是灵活性高,易扩展。真的易扩展吗?
我不知道。没多久,客户的需求就改了,各类拎不清的继承实现都化为乌有,一大半要重写。
问题在哪里?
不是编程很差,而是取舍的很差。在那个阶段,为30%的需求,花200%的努力,追求设计的滴水不漏,却舍弃快速实现,取得反馈的时机,这就是失误。需求总会变,客户看到越早,修改越早,影响越小。
很聪明的人,也可能作出很难用的系统,不必定是编程很差,多是不肯,或不屑于取舍。不一样的阶段,不一样的项目,要取舍的东西也不一样。编程只是手段,目的是解决问题,能力高不高,要看问题解决的好很差。不在于使用了什么高端算法,或是复杂的框架。
懂得如何取舍并不容易,须要对问题的深入理解,对技术的成竹在胸,和身后无数个踩过的坑。但重要的是有取舍的意识,主动思考取舍什么,这样学的才会快。
该如何提高本身的系统编程能力呢?
算法和数据结构有ACM竞赛很容易评估能力的提高,而系统编程能力更多的表现为问题解决能力和综合知识应用能力,更加难以的评估和测量。所以,这里只讨论系统编程能力的提高问题。
作系统,确实不提倡“重复发明轮子”。但注意,是不提倡“重复发明”,不是不提倡“从新制造”。偏偏相反的,我觉得,系统的编程能力正体如今“从新制造”的能力。
能把已有的部件接起来,这很好。但当你刚好缺一种关键的胶水的时候,你能写出来吗?当一个已有的部件不彻底符合你的需求的时候,你能改进它吗?若是你用的部件中有bug,你能把它修好吗?在网上繁多的相似功能的部件中,谁好谁坏?为何?差异本质吗?一个开源代码库,你能把它从一个语言翻译到另外一个语言吗?从一个平台移植到另外一个平台吗?能准确估计本身翻译和移植的过程须要多少时间吗?能准确估计翻译和移植以后性能是会有提高仍是会有所降低吗?
系统编程能力体如今把已有的代码拿来并变成更好的代码,体如今把没用的代码拿来并变成有用的代码,体如今把一个作好的轮子拿来能画出来轮子的设计蓝图,并用道理解释出设计蓝图中哪些地方是关键的,哪些地方是次要的,哪些地方是不容触碰的,哪些地方是还能够改进的。
若是你一点不懂理论,仍是应该学点的。对于系统性能的设计上,算法和数据结构就像在本身手头的钱同样,它们不是万能的,但不懂是万万不行的。
怎么提升系统编程能力呢?土办法:多造轮子。就像学画画要画鸡蛋同样,不是这世界上没有人会画鸡蛋,但画鸡蛋能驯服手指,感觉阴影线条和笔触。因此,本身多写点东西吧。写个小玩意?编译器?渲染器?操做系统?web服务器?web浏览器?部件都一个个换成本身手写的,而后和已有的现成部件比一比,看看谁的性能好,谁的易用性好?好在哪儿?差在哪儿?为何?
更聪明一点的办法:多拆轮子。多研究别人的代码是怎么写的。然而这个实践起来常常很难。缘由:大部分工业上用的轮子可能设计上的思想和技术是好的,都设计和制造过程都很烂,里面乱成一团,让人乍一看毫无头绪,致使其对新手来讲很是难拆。这种情况其实很是糟糕。因此,此办法通常只对比较简单的轮子好使,对于复杂的轮子,请量力而行。
轮子很差拆,实际上是一个很是严重的问题。重复发明轮子当然是时间的浪费,但当轮子复杂而又很差拆的时候,尤为是原来造轮子的人已经不在场的时候,从新发明和建造轮子每每会成为无奈之下最好的选择。这是为何工业界在明知道重复发明/制造轮子很是很差的状况下还在不断重复发明/制造轮子的根本缘由。
程序本质是逻辑演绎的形式化表达,记载的是人类对这个世界的数字化理解。不能拆的轮子就像那一篇篇丢了乐谱的宋词同样,能读,却不能唱。