点击上方设为星标
优质文章,及时送达作者 | 云风
出处 | blog.codingnow.com
经常有小(我 20 岁左右的)朋友问我,作为一个程序员该怎样提高自己。每个人的经历不同,所处环境不错,其实这个问题很难具体回答。不如好好写一篇总结,以后就不必每封 email 都重新写一次了。 纵观我近 30 年的编程生涯,在每个时期,我看到的东西都不同。想必再过 10 年还会有变迁。我只能写写当下眼界所及之处。 指引我爱上编程,并乐此不疲的学习,是 “我能写出更高效的代码” 这种乐趣。如果一个人在学习编程开始,不努力让自己的代码变得更高效,发现不了优化的乐趣,我想他很难爱上编程。Don Knuth 说,Premature optimization is the root of all evil ,这句话背后的道理,不必一开始就强行接受。evil 最能蛊惑人心,但是我们需要它引入门。 朝着优化这条路走下去,你会有自发的动力去了解计算机的本质架构,理解操作系统,理解内存模型,理解新的软硬件技术(它们大多数都是为了让程序跑的更快而发明出来)。否则,现在去学习这些东西,并不会体会到现实的意义。软件开发在今天,大部分的工作都在很高的层次了,大部分人的日常都在完成一些琐碎的业务,用不到这些。但实际上,你在融汇贯通后,可以在很高的层面凭经验就能从蛛丝马迹判断出底层发生的问题;可以从一些代码片段,判断出整个模块的设计意义。这些是无法作为单独的技能学会的。 精通一门语言是最基本的要求。所谓精通,就是要了解这门语言的各种阴暗角落。用每一样语言特性的背后的代价。知道在面临各种问题时用这门语言解决该问题的惯用法。大部分通用语言都会有设计缺陷,表现在具体方面就是面对某些问题,写起来直接了当,而另一类问题时却要绕很多弯弯,这些绕弯弯的部分就需要用某种模式去弥补。我认为,所谓编程的设计模式,并不是跨语言而独立存在的,它们是强烈依附于编程语言的。《设计模式》这本书,我读过的版本是基于 C++ 的,设计模式被谈论的更多的是在 Java 社区。这类模式都有很深的语言烙印。我们学习设计模式其实学的就是一门语言的惯用法。 初次学习设计模式时,肯定会有豁然开朗的感觉。但不应把自己陷入其中。为了提高一次层次,就必须精通至少第二门的语言。我的第一语言是 C ,第二语言是 Lua 。但对于许多人,肯定会有很多更好的选择。多看看不同的语言下解决问题的不同方式,有助于提高编程技能。 在我谈论程序员的编程技能的时候,我指的通常是两类能力:一是运用熟悉的编程语言,用在该语言下最高效的方法解决需求的能力;二是领域知识,尽量多的了解工作所处领域前人的积累,已存在的软件层次的接口,接口背后的代价。这两者缺一不可。不要用自己学习能力强为借口,认为随时可以进入一个新语言,一个新领域,而不会比别人差。不管是一门语言的使用,还是对一个领域的了解,都是需要长期的实践刻意积累的。 以上,都是我认为一个程序员对自己最基本的要求。这些东西多么精进都不为过。但还有一些更高层面的东西。 那就是分解问题,保持简洁的能力。也可以说是规划和构架的能力。这是超出编程语言,具体问题领域的,不过绝不能绕开它们。如果一个程序员编码很粗糙,或是对所在领域一知半解,我绝对不会信任他做的设计。 Keep It Simple, Stupid 谁都会说,但不受优化的蛊惑,我觉得很难。因为完全对优化代码免疫的人,我觉得他很难成为一名优秀的程序员。迈不过第一步,就谈不上在下一步有什么成就。大部分软件问题,本质上都是怎么把复杂问题分层次,分模块,化繁为简的过程。底层开发、基础设施建设为什么吸引了很多自命热爱编程的人,不是因为它们有挑战,相反,它们更纯粹,更简单,更容易做取舍。精益求精的人更容易做出成绩。 带着把各方各面都做到精益求精的心,跨越多个层次去看整个问题。奉着此心做取舍,知道封装和简化带来的代价,随时审视代价到底值不值。我很难总结出教条,这似乎真的只能用个人品味去解释:为什么这里要保持更朴素的数据结构,而牺牲高效的算法;那里为了少定义一个 api ,却让一件简单的任务变得更繁琐。 另一方面,规划不仅仅是针对代码,也包括了开发过程的一切。你不仅需要规划问题怎样划分,还要规划每个部分花多少时间和精力,区分轻重缓急。顺便谈谈超时工作的问题,我在前段谈 996 的时候就写过,超时工作其实反映的是规划的失误。找到正确的方法做事,最终需要投入的人力能有 10,100 倍的差距;而延长工作时间却无法超过 3 倍工时。提高自己的规划能力,应该先尽力减少超时工作。