假如程序员会武功?

从新给程序员下个定义

按照 Wikipedia 的定义,程序员又称为计算机程序员(Computer Programmer)、开发者(Developer)、编码者(Coder)或计算机工程师(Computer Engineer),和网络上普遍流传的码农或程序猿同义。我无心于也不可以为程序员给出一个精确的定义,这里,只是利用程序员的语言作一个简单描述。不是故弄玄虚,不过博取读者诸君一笑。程序员

class Programmer : public Thinker {
public:
void design(System &);
void model(Problem &);
void code(ProgrammingLanguage &);
void debug(Defect &);
void refactor(Code &);
void learn();
void communicate();
virtua voidl think(Logic &);
private:
vector _pls;
}


程序员是彻头彻尾的脑力工做者 (Mind Worker),怠于思考者绝对不能成为好的程序员。有鉴于此,类 Programmer 天生的就应该是 Thinker 的子类。就程序员所使用的思考技巧而言,Thinker 的具体内涵包括逻辑 (Logic) 和数学(Mathematics)。做为程序员,不必定非要达到逻辑或数学领域的专业水准,而是必须具备逻辑和数学的基本素养。逻辑用来推理,数学用来培养逻辑。另外,数学还有助于程序员训练另外两项必不可少的思考的技能,分析和抽象。下文还要展开讨论。算法

程序员的工具是编程语言,平常活动和主要工做包括设计(design)、建模(model)、编码(code)、调试(debug)、重构(refactor)、沟通(communicate)、学习(learn)和思考(think)。编程

有关程序员有一个流传甚广的误解,认为作程序员门槛低,没什么技术含量。即便没有学过计算机的课程如离散数学、数据结构、算法等,也能够写程序。写几行程序固然算不得什么,但要修炼成有必定思想境界的一流程序员,却殊非易事。这就如同会作饭的人不少,但真正的烹饪大师却并不常见。所谓码农者,乃是程序员的自我吐槽,岂足深信耶?因此,做为程序员要有持续进阶的强烈的进取心,断不可妄自菲薄,自怨自艾。网络

程序员的思惟“内力”数据结构

漫长的学生生涯中,我遇到的最好的数学老师是高中时的刘传禹老师。他上课时讲过这样一段话,当面对一个数学问题,一要想的明白,二要算的准确,三要写的清楚。直到今天,这句话对于个人程序员生涯也具备很强的现实意义,能不能想的明白实际上是考量一个程序员成败的相当重要的因素。架构

金庸的武侠小说中有一个广泛的规律,那就是武功一定之内力为根基。好比张君宝与昆仑三绝何足道在少林寺的那场经典之战中,张君宝可以“以少林拳中最平淡无奇的拳招,化解了最繁复的敌招”,始终不落下风,所恃者不过内力之浑厚尔。另外的著名战例还包括少林寺小和尚虚竹 VS 吐蕃国师鸠摩智以及聚贤庄萧峰 VS 玄难。内力达到登峰造极旷古绝伦的第一高手莫过于少林寺的扫地僧。也许风清扬是一个例外,好在咱们讨论的是通常规律,因此就顾不得他了。app

计算机编程所特有的思惟(Thinking)就是程序员的”内力“,思惟能力不济,功能再强大的编程语言也无用武之地。因此,我在这里特别强调程序员的思惟艺术。异步

程序员的思惟有一个专业术语,叫作计算思惟(Computational Thinking)。计算思惟是按照计算机科学的基本概念和方法,用来理解需求、设计系统、实现编程、解决问题的思惟方法。编程语言

简而言之,计算思惟就是程序员或计算机科学家是如何思考的。固然,计算机科学的理论知识如数理逻辑、离散数学、数据结构、算法以及面向对象是计算思惟的必要条件。计算思惟有一系列的智力工具,不能一一尽述,仅列举关键的几项以下:ide

抽象思惟(abstract thought)

给定一个问题,抽象就是去掉纷繁芜杂的与计算无关的部分,用规约(Reduction)的方法还原到问题的本质。所谓本质即把原来的问题转换为一个或几个可使用计算机描述并解决的问题,进一步讲也就是转换为在算法上可计算的(algorithmically computable)一个或几个问题,更准确更理论化更上档次的描述是转换为邱奇 - 图灵论题(TChurch-Turing thesis)可计算的可数个问题。图灵机(Turing Machine)和λ演算(Lambda calculus)自己就是对可计算性(Computability)的漂亮的抽象,能够做为抽象思惟的经典案例来揣摩学习。

通常在实际工做中,经常须要把问题的实体对象根据需求表示为各类数据结构如树、堆、栈等,而业务逻辑(Business Logic)过程表示为各类算法如排序和查找等。表示(Presentation)是解决问题的第一步,也是关键的一步。在程序员的实践中,咱们都有很深的体会,一旦问题被准确的无歧义表示出来了,解决方案就烘云托月般地呈现出来了。这就是“数据即代码,代码即数据”的道理。

抽象思惟也普遍用于数学家的工做。面对一个困难的问题,数学家们常从两个方向开展研究。一方面,从特殊状况入手,推广到更通常的状况;另外一方面,将一个通常问题具体化成几种特殊状况。两个方向的结果最终汇聚在一块儿,就找到了问题的答案。我想这多是论语中“我叩其两端而竭焉”的一个最好注解。而从特殊到通常就是不断抽象的过程。

咱们用一个具体的例子加以说明,有一个著名的六度分隔理论(Six Degrees of Separation)讲的是世界上任意两我的均可以经过最多另外 6 我的相互认识,若是要验证这一理论,怎么作呢?咱们能够借助一个图(graph)来表示人与人之间的关系,每一个人用图中的一个节点表示,若是 A 和 B 认识,那么在表明他们的节点之间有一条边链接。

那么如今的问题就转换为检查这个图的直径是否大于 6。考虑到世界人口众多,且有生老病死,图的规模必然超大,而且是动态的不断变化的,算出它的直径仍须要更多的简化。这里就到此为止了。

逻辑推理(Reasoning)

逻辑推理对于程序员的重要性不言而喻。与其说逻辑推理用于程序新功能的开发,毋宁说更多的应用在程序调试修改 BUG 的过程当中。程序调试有点相似于 Sherlock Holmes 侦破案件的过程。

和 Dr. Wason 比较起来,Holmes 的推理优于常人的地方有两点:第一,在观察现场或听取来访者叙述时,他可以获得更多的的数据,尤为是一些别人容易忽略的关键的细节,这得益于他对犯罪领域知识的丰富积累,知道什么才是更重要的数据;第二,根据获得的数据,他可以联想到更多的可能的结论,这得益于他大量的案例储存。有了这两点,就可以经过一环套一环的推理链逐渐缩小侦察范围,最终认清犯罪事实。

程序调试也是如此,首先必须掌握程序实际的执行过程的细节。而后从问题出发,分别朝着产生的缘由和致使的后果先后两个方向推理。逐渐定位问题的范围,最终找到问题的根源和解决的方案。咱们比 Sherlock Holmes 幸运的是 能够借助于调试工具来了解程序运行的过程,因此一个不能使用调试工具的程序真是令程序员感到无比沮丧,只能经过 trace 信息来跟踪程序运行的过程。

若是不知道程序运行的过程,推理就只能靠猜,那么修改 BUG 是很是危险的,很容易致使回退(Regression)的错误,由于这种状况下如同瞎子摸象,根本不知道本身在作什么。另外,Sherlock Holmes 还屡次表达过这样的观点,案子越是离奇,越容易解决,由于 Singularity is almost invariable a clue。

对程序员来说,也没必要担忧奇怪的问题,奇怪自己就是线索。关键看对程序运行细节的了解程度和逻辑推理的技术水平。

分析(Analysis)

分析是上文提到的数学家所用思惟方式中从通常到若干特殊状况的过程。面对一个问题,若是一会儿描述不清楚或者表示不出来,能够先找出知足问题条件的几种特殊状况。经过仔细检查这几种特殊状况,求同存异,找出他们共同的规律或模式,并对这些模式或规律加以验证,就能够找出描述或表示问题的方法。这就是猜想加验证(guess-and-verify)的过程。项目需求分析时常见的应用案例分析(Use Case Analysis)方法,就是用一个个具体的使用案例将模糊的项目需求生动的表达出来。

分解(Decomposing)

把一个大问题分解为几个小问题,或者把一个复杂的过程分解为几个子过程,固然有助于问题的解决。这也是程序员经常使用的手段,如算法策咯中的分而治之(Divide-and-Conquer)和合并排序就是这方面的例子。

递归(Recursion)

对于初学编程的人,递归多是一个比较诡异的较难掌握的概念。可是一个程序员若是不懂递归,很难再称之为程序员。由于不少稍微复杂的算法他都不可能理解,如回溯和动态规划,甚至于树的遍历。递归经常能够用简单的方法很是优雅的表达复杂的算法。

另外,有关计算思惟的特有方法还有并行、异步 / 同步、模拟 / 近似、优化、分层、封装、解耦等等。程序员的思惟艺术即计算思惟不是一天两天短期能够造成的,须要在实践中慢慢琢磨,不断提高,且永无止境

程序员的“战斗力”技艺

图片

程序员的思惟艺术融化到到对编程语言的使用上,最终造成程序员的技艺。所以,编程语言之于程序员,就如同青龙偃月刀之于关羽,如意金箍棒之于孙悟空。离开了青龙偃月刀和如意金箍棒,关羽和孙悟空的战斗力就无从谈起。因此,脱离编程语言来讨论程序员的技艺也无异于缘木求鱼,自欺欺人。结合编程语言,程序员的技艺有四个境界,从低到高分别是

初窥门径

编程语言的初学者,如同小儿咿呀学语,也许能够写一个相似于“Hello World”这样的程序,但对语言的全部东西都是只知其一;不知其二,不可能应用于实际的项目中。这是咱们很容易就能够达到的级别。有些人初窥门径以后,往里面看看,感受不容易,就放弃了。

登堂入室

对编程语言所共有的基本表达方式有了必定的了解,如变量、赋值、循环、选择等。能够用在通常的项目中,可是写出来的代码看起来滞涩笨拙,很难作出高质量的程序。这个时候,程序员很容易产生自满的情绪,觉得彻底掌握了这种编程语言,编程也不过如此。若是陷入这种自满情绪中不能自拔,就失去了进一步进阶的机会。

熟能生巧

掌握了编程语言特有的功能,并能得心应手,灵活使用。所以,写出的代码更加的精炼易懂,经常使用简单的方法表达较为复杂的算法。这是一个成熟的程序员的水平,也是咱们大多数程序员所能追求的目标。

妙趣横生

这是传说中神龙见首不见尾大师级的境界。柏杨在《中国人史纲》描述李白的才华称,李白写诗时,对汉语的使用就像魔术师手中翻转的手帕同样,神鬼莫测。如同李白做诗同样,我想这个境界的程序员对编程的各类精微之处了如指掌,可以将编程语言的各类功能特性发挥到极致,且恰到好处。运用之妙,存乎一心。而且每每可以别出机杼,奇思妙想,层出不穷。写出的程序优雅、高效、别致。这是咱们通常程序员望尘莫及的。

程序员的精神“修炼”

开放

在以往的工做中,曾经遇到过这样的程序员,自觉得掌握了某些核心的、关键的技术或技能,却不肯意和别人共享,处心积虑的保护着他的“地盘”,担忧别人染指他的工做。也遇到过这样的组织,几个被信任的程序员把持着产品的所谓关键模块,其余人莫想参与,即使再有才华,也只能扮演跑龙套的角色。

这让我想起《三国演义》中诸葛亮舌战群儒的情节,在回答江东首席谋士张召的诘难时,诸葛亮将儒生分为君子之儒和小人之儒。这里不妨将这样的程序员称为“小”程序员吧。程序员的技艺根植于计算思惟中,没有所谓的不传的绝招或秘笈。交流和实践是程序员持续进阶的必要且有效途径。固步自封和抱残守缺是程序员的大忌,彻底是做茧自缚,毫无出息

严谨缜密

在软件开发中,任何事情在逻辑上缘由和结果都是清晰明了的,不存在任何意义上的说不清道不明的神秘主义。程序员也是软件工程师,讨论问题时,固然应该使用工程师的语言,即用数据而不是猜想,用逻辑而不是臆断,来表达本身观点。

有两种状况可能形成本身表述时似是而非,模棱两可:第一,数据掌握的不够;第二,没有“想的很明白”。例如,当咱们讨论性能(Performance)时,必定要用响应时间(Response Time)或吞吐量(Throughput)这样有意义的参数,而不仅是泛泛的讲“这系统咋这么慢啊”,“计算机在干什么呢,等的时间太长了”,“简直受不了这样的程序了”。用户能够这样抱怨,而程序员则不可。

一样当咱们讲到系统开销时,要用 CPU 占用率、内存这样定量的参数。所以,一个脑筋清楚的程序员不会把这样的话挂在嘴边,“太神奇了,不知道为何”,“弄不清楚是否能够解决这个问题”,“先这样吧,之后再说”。通常地讲,智能和非智能并无清晰的界限,由于咱们并不知道如何严格地定义智能。

然而,有了图灵—邱奇论题,可计算的和不可计算的确实有明肯定义的界限,也就是说,计算机能够解决的问题和不能够解决的问题是泾渭分明的,且是能够区分的。对于一个问题,可以解决就是可以解决,不能解决就是不能解决,不至于难以肯定是否能够解决。因此,全部以上这些说法都不该该是程序员使用的语言,程序员就是要把一切都弄得清清楚楚,不放过任何潜在的问题。

完美主义

我不了解完美主义的真实意义,也不大拿得准完美主义是褒义词和贬义词。我用这个词是为了 强调程序员要坚持追求工做的完美。写代码时是要有洁癖,不容许有任何瑕疵,这样的代码才可能正确、易读、高效、简单、优雅。对一项任务,不只仅是作完就算了,还应该仔细想一想是不是否能够作的再好一点。对遇到的问题,即便看似解决了,也要从头到尾彻底弄明白,不能似是而非,不求甚解。

面对变化

变化意味着在新的征程上,要面对许多未知的东西,加之对安定状态下的安乐窝(Comfortable Zone)的眷恋,让咱们有着或多或少的畏惧和抗拒。我认为这些都是人之常情, 无可厚非。

不幸的是,对程序员来讲,变化就是屡见不鲜,如新的项目、新的应用领域、新的编程语言、新的技术架构、开发过程当中新的问题、新的功能等,能够说不变的只有变化。其实,好逸恶劳是畏惧变化的根源。只有克服“懒”的思想,强迫走出本身的安乐窝,对新的事物充满好奇心和求知欲,才能适应永远的变化

程序员的价值提高

有的公司把程序员看做和水电、机器同样的冷冰冰资源,作项目计划时,一些项目经理觉得只要给项目分配足够的资源(包括程序员、水电、机器)并加以正确的管控,项目就能够预期的顺利完成。就好像作东北乱炖,只要把各类食材往锅里一丢,开火等着就万事大吉了。

可是,程序员首先是有血有肉的人,毫不等同于毫无感情的机器。一个有雄心的公司要不断提高产品的竞争力,什么是竞争力?就是把产品作的好到不能再好,天下第一,谁与争锋?产品向好的每一步都须要借助于程序员创造力和想象力,这才是程序员的价值之所在。没有程序员愿意把最宝贵的创造力和想象力奉献给只把本身看做资源的公司。因此,聪明的管理者会千方百计把程序员这种创造力和想象力激发出来。

相关文章
相关标签/搜索