之前突然蹦出来新想法. 编码的过程就是知识构建的过程. 写代码的过程其实只是程序员学习的过程, 一个项目的形成过程, 就是程序员的知识体系的构建过程. 这样的话, 可以解释很多问题.
1 为毛重构
因为我们是在不断学习的. 我们的知识体系是随着自己的学习的过程不断变化的, 变得范围更大, 更加系统化. 代码只是我们知识体系的映射, 一旦知识体系发生了变化, 我们的映射也是需要变化的. 当然, 如果代码已经不再需要映射新的知识体系, 我们是不需要(但是也可以)进行重构的, 比如, 已经废弃的版本, 不再增加新功能的版本(而且没有需要使用新的知识体系来修补的bug的出现).
但是, 一旦代码需要和我们自己新的知识体系建立映射, 我们就需要将这个映射也修改成符合我们知识体系的结构. 这就是为什么, 在一个项目上一段时间后, 我们就会忍不住的推导重来自己的代码, 因为, 我们通过一段时间的学习, 脑中的知识体系已经与之前的知识体系完全不同了, 代码作为之前的知识体系的映射, 往往无法承载新的体系. 这种错位, 会让我们编码的过程中感到处处受制. 因为我们脑中的东西与编写的代码产生了不一致. 而代码本身就是映射, 出现了错位, 就失去了代码的意义.
那么, 通过更加有经验的架构设计能否避免这一问题? 在我看来, 不可能. 架构设计不过是尽量抽象, 以符合未来的各项要求, 比如性能, 可扩展性等. 但是, 知识体系本身不是抽象的, 是实实在在的东西, 代码最终落地, 都是知识体系的映射. 实在的东西变了, 映射就不可以避免的发生变化.
所以, 只要知识体系发生了变化, 重构不可避免, 无论前期架构上预留多少空间. 那么, 什么时候重构? 知识体系发生了变化, 影响了代码这一映射时.
2 项目成功率
大型项目成功率必然底下, 成为了这一前提的推论. 首先, 什么是大型项目? 这里就不再是代码量或者数据量, 而是这一项目代码对应的知识体系. 一个几十万行代码的项目或许背后的知识体系规模很小, 那么这就不是一个大型项目. 一个几万行的项目或许背后的知识体系十分复杂, 那么这就是一个大项目.
举个例子, 自己最近用的Deep Learning的工具库Caffe. 这一项目的代码量有120K C++代码, 按照代码量来看, 绝对不是一个小项目, 但是DL工具库本身的知识体系规模是很小的. 最简单的情况下, 只需要知道矩阵操作, 梯度下降的优化算法. 而且这一知识体系十分稳定, 都是几十年来没什么太大变化的. 所以, 这是一个小项目, 所以作者作为一个PhD, 已经掌握了稳定的知识体系的情况下, 可以一次成功, 快速开发出来(当时, 作者可是赶着自己的学位论文的deadline写项目的).
另外, 自己之前维护过一年的C++项目, 代码量在50K以内, 一个类似搜索的程序, 倒排表索引加上层的复杂逻辑代码. 索引部分的知识体系小而稳定, 但是上层的复杂逻辑代码, 甚至完全不成知识体系, 而且变化量很大. 所以, 这个项目相比Caffe, 规模应该算大. 其结果是, 完全另外开发一套, 在Lucene基础上, Java开发, 换句话, 100%重构. 自己只是简单维护, 后面就换其他同事重新实现, 算是幸运.
所以, 什么样的项目能够最终成功?
2.1 知识体系稳定的
稳定的知识体系, 代表有大量的人才有相关的知识体系, 有之前的开发经验可参考. 无论这一知识体系规模大小与否, 只要知识体系不变, 项目就可高概率的获得成功.
2.2 知识体系规模小的
这就不算是大项目了. 但是即使知识体系很小, 如果体系的变化非常频繁, 也让人受不了. 如果代码量尚可, 重构难度小, 还可以保持良好的维护. 否则, 也会难以保持高质量.
2.3 有大量投入的
可以负担知识体系的变化, 甚至这次失败了下次再来. 直到烧钱烧到知识体系稳定.
3 软件延期
因为谁都没法准确量化知识体系构建的成本. 就像学校的学习一样, 同样的时间, 同样的资源最后的结果都不一样, 何况实际情况中, 所有的变量都没法控制.
所以, 需要有开发经验的人员, 因为知识体系已经有了, 剩下的过程就是实现这一映射. 不过, 每个人的知识体系的掌握都是不一样的, 所以, 即使你用的是有开发经验的人员, 你也要确认其知识体系是否达到了标准. 不过这个测试应该怎么做? 天知道.
4 试验性代码, 知识融合与创新
编码过程中, 往往都会编写试验性代码. 有两个可能,
- 这其实是验证知识体系的过程.
- 这是验证在知识体系基础上自己的提出的假设.
前者, 在我看来, 就是知识的融合(学习). 后者, 就是研究的过程, 是自我知识体系下的创新(因为, 你无法保证自己的研究是不是已经被人做过了).
5 什么才是好的Coder
以我的尿性, 我更加喜欢简单粗暴单因素. 只有一个, 构建知识体系的能力, 或者说学习能力. 有历史经验更好, 如果可以验证有学习能力, 那么历史经验也可以保证其知识体系是构建的很好的1.
表达能力重要么? 我看不重要, 只要有代码映射的能力就足够. 你把知识体系映射成为代码就可以. 那么如果多人合作呢, 表达能力是否重要? 我看还是不重要, 因为每个人的知识体系都不一样. 如果要十分强调表达能力, 那么结果就是每个人都把自己的知识体系给很好表达出来, 结果就是互相不兼容. 只要在各自的知识体系的基础上, 获得一个兼容层, 多人协作的开发就可以顺利进行. 那么唯一的问题就限制在兼容层这一小范围内了.
我们可以进一步的跳出表达能力这一问题, 表达能力是可学习的么? 如果可以学习, 那么还是最终回到了学习能力上. 而我对这个问题的回答是: 是. 但是, 我强调的是, 看起来好的Coder似乎是因为表达能力强, 但这只是表象. 表达能力强是因为人家学习能力强, 而表达能力强会更加容易给别人留下印象. 最终, 我们会有一种错觉, 好的Coder都是表达能力强的. 在我看来, 这个问题解释应该是, 好的Coder都是学习能力强的, 给大家留下深刻印象的好的Coder则是顺路把表达能力给学了. 好的Coder表达能力强, 这是一种幸存者偏差.
那么, 学习能力怎么看呢? 测智商……以我的尿性, 我喜欢简单粗暴单因素.
Footnotes:
知识体系好不好又如何定义?