当前位置: 主页 > C生活港 >工程师的江湖:技术为外功,思维乃内力 >

工程师的江湖:技术为外功,思维乃内力

作者: 分类: C生活港 发布于:2020-07-08 浏览(431)


工程师的江湖:技术为外功,思维乃内力

一个足球评论家可能并不会踢足球,却并不妨碍在解说比赛时对某某球星的技艺评头论足。同样也绝不敢以高明的工程师自居,而只是以类似金庸先生笔下的武林高手来阐述笔者对工程师的理解。这样,大家也许就不以笔者为鄙薄狂妄了,这是笔者必须首先声明的。

一、重新给工程师下个定义
工程师的江湖:技术为外功,思维乃内力

按照 Wikipedia 的定义,工程师又称为电脑程式设计人员、开发者、编码者或电脑工程师,和网络上广泛流传的码农同义。笔者无意于也不能够为工程师给出一个精确的定义,这里,只是利用工程师的语言做一个简单描述。不是故弄玄虚,不过博取读者诸君一笑。

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

工程师的工具是写程式语言,日常活动和主要工作包括设计、建模、编码、除错、重构、沟通、学习和思考。

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

2、工程师的思维「内力」
工程师的江湖:技术为外功,思维乃内力

漫长的学生生涯中,笔者遇到的最好的数学老师是高中时老师。他上课时讲过这样一段话,当面对一个数学问题,一要想的明白,二要算的準确,三要写的清楚。直到今天,这句话对于笔者的工程师生涯也具有很强的现实意义,能不能想的明白其实是考量一个工程师成败的至关重要的因素。

金庸的武侠小说中有一个普遍的规律,那就是武功必定以内力为根基。比如张君宝与崑仑三绝何足道在少林寺的那场经典之战中,张君宝能够「以少林拳中最平淡无奇的拳招,化解了最繁复的敌招」,始终不落下风,所恃者不过内力之浑厚尔。另外的着名战例还包括少林寺小和尚虚竹 VS 吐蕃国师鸠摩智以及聚贤庄萧峰 VS 玄难。内力达到登峰造极空前绝后的第一高手莫过于少林寺的扫地僧。也许风清扬是一个例外,好在我们讨论的是一般规律,所以就顾不得他了。

电脑程式所特有的思维就是工程师的「内力」,思维能力不济,功能再强大的程式语言也无用武之地。所以,笔者在这里特别强调工程师的思维艺术。

工程师的思维有一个专业术语,叫做计算思维。计算思维是按照电脑科学的基本概念和方法,用来理解需求、设计系统、实现编程、解决问题的思维方法。

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

抽象思维。给定一个问题,抽象就是去掉纷繁芜杂的与计算无关的部分,用规约的方法还原到问题的本质。所谓本质即把原来的问题转换为一个或几个可以使用电脑描述并解决的问题,进一步讲也就是转换为在算法上可计算的一个或几个问题,更準确更理论化更上档次的描述是转换为邱奇-图灵论题可计算的可数个问题。图灵机和 λ 演算本身就是对可计算性的漂亮的抽象,可以作为抽象思维的经典案例来揣摩学习。

一般在实际工作中,常常需要把问题的实体对象根据需求表示为各种数据结构如树、堆、栈等,而业务逻辑过程表示为各种算法如排序和查找等。表示是解决问题的第一步,也是关键的一步。在工程师的实践中,我们有很深的体会,一旦问题被準确的无歧义表示出来了,解决方案就烘云托月般地呈现出来了。这就是「数据即代码,代码即数据」的道理。

抽象思维也广泛用于数学家的工作。面对一个困难的问题,数学家们常从两个方向开展研究。一方面,从特殊情况入手,推广到更一般的情况;另一方面,将一个一般问题具体化成几种特殊情况。两个方向的结果最终汇聚在一起,就找到了问题的答案。笔者想这可能是论语中「我叩其两端而竭焉」的一个最好注解。而从特殊到一般就是不断抽象的过程。

笔者用一个具体的例子加以说明,有一个着名的 六度分隔理论讲的是世界上任意两个人都可以通过最多另外 6 个人相互认识,如果要验证这一理论,怎幺做呢?我们可以借助一个图来表示人与人之间的关係,每个人用图中的一个节点表示,如果 A 和 B 认识,那幺在代表他们的节点之间有一条连接。

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

逻辑推理。逻辑推理对于工程师的重要性不言而喻。与其说逻辑推理用于程式新功能的开发,毋宁说更多的应用在程式修改 BUG 的过程中。程式除错有点类似于 Sherlock Holmes 侦破案件的过程。

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

程式除错也是如此,首先必须掌握程式实际的执行过程的细节。然后从问题出发,分别朝着产生的原因和导致的后果前后两个方向推理。逐渐定位问题的範围,最终找到问题的根源和解决的方案。我们比 Sherlock Holmes 幸运的是可以借助于除错工具来了解程式运行的过程,所以一个不能使用除错工具的程式真是令工程师感到无比沮丧,只能通过 trace 资讯来跟蹤程式运行的过程。

如果不知道程式运行的过程,推理就只能靠猜,那幺修改 BUG 是非常危险的,很容易导致回退的错误,因为这种情况下如同瞎子摸象,根本不知道自己在做什幺。另外,Sherlock Holmes 还多次表达过这样的观点,案子越是离奇,越容易解决,因为 Singularity is almost invariable a clue。

对工程师来讲,也不必担心奇怪的问题,奇怪本身就是线索 。关键看对程式运行细节的了解程度和逻辑推理的技术水平。

分析。分析是上文提到的数学家所用思维方式中从一般到若干特殊情况的过程。面对一个问题,如果一下子描述不清楚或者表示不出来,可以先找出满足问题条件的几种特殊情况。通过仔细检查这几种特殊情况,求同存异,找出他们共同的规律或模式,并对这些模式或规律加以验证,就可以找出描述或表示问题的方法。这就是猜测加验证的过程。项目需求分析时常见的应用案例分析方法,就是用一个个具体的使用案例将模糊的项目需求生动的表达出来。

分解。把一个大问题分解为几个小问题,或者把一个複杂的过程分解为几个子过程,当然有助于问题的解决。这也是工程师常用的手段,如算法策咯中的分而治之和合併排序就是这方面的例子。

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

另外,有关计算思维的特有方法还有并行、异步 / 同步、模拟 / 近似、优化、分层、封装、解耦等等。工程师的思维艺术即计算思维不是一天两天短时间可以形成的,需要在实践中慢慢琢磨,不断提升,且永无止境。

3、工程师的「战斗力」技艺

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

初窥门径 。程式语言的初学者,如同小儿咿呀学语,也许可以写一个类似于「Hello World」这样的程式,但对语言的所有东西都是一知半解,不可能应用于实际的项目中。这是我们很容易就可以达到的级别。有些人初窥门径之后,往里面看看,感觉不容易,就放弃了。

登堂入室 。对程式语言所共有的基本表达方式有了一定的了解,如变量、赋值、循环、选择等。可以用在一般的目标中,但是写出来的程式码看起来滞涩笨拙,很难做出高品质的程式。这个时候,工程师很容易产生自满的情绪,以为完全掌握了这种程式语言,写程式也不过如此。如果陷入这种自满情绪中不能自拔,就失去了进一步进阶的机会。

熟能生巧 。掌握了程式语言特有的功能,并能驾轻就熟,灵活使用。因此,写出的代码更加的精炼易懂,常常使用简单的方法表达较为複杂的算法。这是一个成熟的工程师的水平,也是我们大多数工程师所能追求的目标。

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

4、工程师的精神「修炼」
工程师的江湖:技术为外功,思维乃内力

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

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

严谨缜密。在软体开发中,任何事情在逻辑上原因和结果都是清晰明了的,不存在任何意义上的说不清道不明的神秘主义。工程师讨论问题时,当然应该使用工程师的语言,即用数据而不是猜测,用逻辑而不是臆断,来表达自己观点。

有两种情况可能造成自己表述时似是而非,模稜两可:第一,数据掌握的不够;第二,没有「想的很明白」。例如,当我们讨论性能时,一定要用回应时间或吞吐量这样有意义的参数,而不只是泛泛的讲「这系统怎幺这幺慢啊」,「电脑在干什幺呢,等的时间太长了」,「简直受不了这样的程式了」。用户可以这样抱怨,而工程师则不可。

同样当我们讲到系统耗能时,要用 CPU 佔用率、记忆体这样定量的参数。因此,一个脑筋清楚的工程师不会把这样的话挂在嘴边,「太神奇了,不知道为什幺」,「弄不清楚是否可以解决这个问题」,「先这样吧,以后再说」。一般地讲,智慧和非智慧并没有清晰的界限,因为我们并不知道如何严格地定义智慧。

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

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

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

不幸的是,对工程师来说,变化就是家常便饭,如新的目标、新的应用领域、新的程式语言、新的技术架构、开发过程中新的问题、新的功能等,可以说不变的只有变化。其实,好逸恶劳是畏惧变化的根源。只有克服「懒」的思想,强迫走出自己的安乐窝,对新的事物充满好奇心和求知慾,才能适应永远的变化。

5、工程师的价值提升
工程师的江湖:技术为外功,思维乃内力

有的公司把工程师看作和水电、机器一样的冷冰冰资源,做专案计划时,一些专案经理以为只要给专案分配足够的资源并加以正确的管控,项目就可以预期的顺利完成。就好像做大锅炒,只要把各种食材往锅里一丢,开火等着就万事大吉了。

但是,工程师首先是有血有肉的人,绝不等同于毫无感情的机器。一个有雄心的公司要不断提升产品的竞争力,什幺是竞争力?就是把产品做的好到不能再好,天下第一,谁与争锋?产品向好的每一步都需要借助于工程师创造力和想象力,这才是工程师的价值之所在。没有工程师愿意把最宝贵的创造力和想像力奉献给只把自己看作资源的公司。所以,聪明的管理者会想方设法把工程师这种创造力和想像力激发出来。

欢迎加入「Inside」Line 官方帐号,关注最新创业、科技、网路、工作讯息
工程师的江湖:技术为外功,思维乃内力