看到这个标题,你一定会有疑问,什么叫普通码农。
相对普通码农,自然会有超级码农。记得刚参加工作的时候,我被分到一个路由器的组,专门干移植bootloader的工作。同组还有一个同事干同样的工作,只是我们会跟进不同项目。有一天早上,当我还在研究初始化代码的时候,我看到他正在用GDB工具看反汇编出来的代码。我问他这是在干嘛,他说他已经完成了这几个项目的移植,现在正在考虑是否可以对初始化代码用汇编来写。我当时在想,Are you kidding me?不过过一段时间他居然真的用汇编把这些东西给折腾出来了。
似乎有些人,他们更擅长高强度的脑力劳动。当时我们常常上完一天班已经很累了,他还能精力十足地跑两公里回家。果然几年以后,他就成为了别人眼中的大牛。这是超级码农,当时同组还有另一位同事,他只是编写简单的html代码,但干了两个月就辞职了。辞职的时候兴冲冲地和我说,终于不用再看这些烦人的代码啦。码农有各种各样的,其中也有一大堆和我一样的人。我们对于编程,即没有那么绝对的擅长,也没有那么厌倦。这样的人,姑且称之为普通码农吧。
作为一个普通码农,这些年我在编码的时候走了不少弯路。所以我想总结一下其中的几个经验教训,顺便和大家交流一下。
经验一、只在同一个抽象层次进行思考
人的短期记忆是很有限的,带来的结果就是在一个时间点上,我们能记住的逻辑拓扑是有限的。因此编码的时候,最好不要进行太多的纵向跨层次的思考。
复杂的单一应用维护起来比较让人头疼,因此通常会被拆分成微服务或者多个组件。接着每个组件有对应的框架结构,以及常用的第三方依赖。到具体编码的时候,我们只需要设计一组类去解决实际的问题。
一个实际的问题由一个或者一组类来解决,这一组类和他们的之间的接口是一个层次。到具体某个类里,它的每个接口的实现是下一个层次。如果某个算法特别复杂,又可以再抽象出一个层次。这样,没有必要的话不要写太长的方法。
在编码的时候可以有意识地切换思考的层次,在设计类图的时候不要想实现细节,在写一个子方法的时候不要去想该如何改善接口。
很多Git Repo在commit的时候要求改动接口和具体实现要分开提交,就是遵循上述的原则。这么多的语言、框架、范例就是为了让我们在面对复杂问题的时候,有一个相对标准的解耦的思路,节省我们的脑力。
过去在看大量代码的时候,我常常很焦虑,甚至怀疑我自己的职业生涯。然而只要学会循序渐进,不要在某个单点上透支注意力,解决一个复杂问题的时候可能就没有那么吃力了。
经验二、定期整理自己的知识结构
科学家发现,儿童和成人学习语言的方式是不同的。儿童学习语言会增加大脑的神经突触,而成人则是强化神经网络之间的联结。
对于我们学习的知识来说,最好的结构是树状和网状,不要把它们像关系型数据库一样存在不同的表里。
人脑有两个系统,一个和直觉、联想有关,可以快速作出决策。另一个和分析、运算有关,推演起来十分缓慢。强化各个概念之间的联结,会把原来分散的短期记忆融合到自己长期的记忆中去。这样不仅不容易把自己所学的知识忘记,还会同时加快自己的思考过程。
你可以把自己想象成一个人工智能,虽然运算能力没那么强大,但是框架却要比tensorflow好上一万倍。你不需要太多的数据,也可以优化自己的模型。
其实仔细一想,很多知识是完全相通的。我在学习YARV的时候,发现它的指令集和一些cpu指令集比如x86或者mips的有很多共通之处。而js实现异步的原理,和实时性操作系统ucosii实现多进程的方式如出一辙。
过去我在学习的时候,总是想方设法让自己强记某些知识,最后发现这样不仅低效且很容易因为经常忘记而让自己失去信心。所以,学习新的知识时,要尽量把它和老的知识做比较,建立知识点之间的联系,才能事半功倍。
经验三、Plan yourself
从一个点上看,人的短期记忆有限。有一条时间线上看,人在一段时间内的精力是有限的。
不要胡乱投资时间。我在刚参加工作的那几年,因为几个对硬件的问题不了解,就买了好几本数字高频电路的书来看。然而这些问题我到现在也没有搞懂,纯粹浪费了大量的时间。
你可以对自己想干的事情和所需要的技能作一个评估,决定自己要把时间投资在哪个技术领域。当然这不仅仅限于技术,也可以把时间用在技术之外的地方,这个看个人喜好了。
这是一个升维的问题,时常跳出自己当前的任务,想一想自己的整个生活。不要盲目,当更高维度的问题解决以后,自己在面临当前任务的时候也会更加心无旁贷。
总结
编码和其他很多事情一样,都不是一件容易的事情。如果你想节约时间,可以快乐编码,上完班可以找三四个好友,聚在大排档,喝点啤酒,谈谈人生。那么可以学习一门为优雅而生的语言——ruby。
入坑以后,你就会发现,这TM还是要有这么多东西要学,一点也不轻松。于是你就会抛弃轻松编码的幻想,继续努力工作。
完。