高效程序员的狂暴之路

不觉间已经工作六年,回想第一天实习的场景历历在目、恍若昨日。六年已足以令许多人转管理、转产品、转测试、转行,也一定有人还在坚守着编码,只因热爱。遇到过形形色色的经理、架构师、运维、性能工程师等等,还是觉得写代码的才是最厉害的!在这里分享一些这些年来修习到的个人心得。也许并不适用于其他人,但对于我却都是最珍贵的“宝藏”。也谨以此文纪念在代码堆里度过的青春~ 看到这些点点滴滴的收获,就会感到所有逝去的光阴和挥洒的汗水都是值得的。


1.启动:得心应手的工具

1.1 全能IDE

关于IDE,目前我使用Intellj IDEA和Sublime Text来应对各种语言的开发。

在大学期间初学Java时曾使用过MyEclipse,后来职业生涯的前期很自然的过渡到了更加灵活的Eclipse。但两年前经过不断的试用丢弃再试用,最终我成功从Eclipse转投到了Intellij IDEA阵营。在那之后就一发不可收拾,不仅重度使用Intellij,而且还短暂试用过JetBrains旗下的各种产品,Phpstorm,Pycharm,RubyMine包括最新的Clion。Google也选择Intellij作为其Android Studio的基础。作为Java开发者,当然最钟爱的还是Intellij,其智能程度实在是太震撼了!强烈建议还在观望的同学们去官网上看一下介绍它的各种操作的小动图。

好像很容易地,Intellj IDEA就成了我Java开发的不二选择。然而对于其他语言,尤其是C/C++却一直没找到合适的IDE。从Vim+各种插件打造IDE到Emacs到Visual Studio和CodeBlocks,一直没有令我满意的,直到碰见了Sublime Text。现在它不仅是我除了Java外所有语言的IDE,还是我的博客编写工具和代码库,在后面的3.2 Codebase一节你将会看到。详见《Sublime Text 3下C/C++开发环境搭建》

1.2 UML和设计

UML领域中的好软件不少,如Rose、EA,大多是商业付费软件。在开源免费软件中,StarUML比较不错,2.0版相比1.0做了不少改进,尤其是整体外观漂亮多了。配合Visio和Power Designer等补充UML以外的设计图,如业务泳道图、流程图、拓扑图、ER关系图等,几乎可以满足大部分日常需求。

1.3 Shell

日常工作中免不了要使用Unix/Linux命令,或者直接连接到远程的服务器上做一些操作。在Windows上模拟Unix/Linux命令当然要用Cygwin,在Windows上使用那些实用的Unix命令可以大幅度提升效率,特别是你经常需要处理文本时。而SSH客户端一般就用SSH Secure Shell或XShell,前者比较简单,后者更强大但文件传输功能却要装另外的软件XFtp。

当然,如果直接使用Linux做个人桌面那最好不过了,在Linux上开发和在Windows上不仅是工具多了顺手了,简直就是思维方式上的剧变!详见《Linux Mint 17一周使用体验》

1.4 虚拟环境

VirtualBox是个不错的小巧快速的虚拟机软件,VMWare也许更加强大,但是有些太重型了。用VirtualBox装一些常用的操作系统和软件,以及测试环境和测试数据,然后做成快照留作以后反复使用,可以免去很多做环境的麻烦。而且在虚拟机里怎么折腾都行,降低了使用实体机的风险。这方面,目前后起之秀应该是Docker吧,造福了广大的开发者。因为还没有研究过所以先不做评论了。


2.加速:简单有效的方法论

2.1 动手前先思考

作为一名程序员,拿到任务后就有要立即编码的冲动很正常,但为了减少走弯路,我们要克制这种冲动。大到大型产品和项目的开发,小到一个算法的实现,都少不了先行设计和思考。大项目要做高层次架构设计,提前识别出那些“坑”,可以有效地降低风险,避免返工。小算法要证明其正确性,避免一些逻辑思维上的漏洞。关于一段代码的正确性,详见《程序员修炼之路-(1)基础(下):正确性证明》

关于思考的程度也要掌握一个“度”,不然就可能出现“过度设计”的问题。这个“度”感觉很难掌握,只能靠时间和经验不断培养判断和直觉,一点点地就学会了评估哪些设计现在做很费时应该放后,哪些设计现在做不麻烦但要是不做以后改起来就很费时。

2.2 简洁的代码

说到简洁和干净,就不得不提一些经典书籍对我的巨大影响。在大学时入手了《Code Complete》(代码大全,听了这狗血的中译名真以为是各种代码的百科全书),很幸运地能在正式入行前就看到这本书,它让我少走了很多弯路,甚至养成了一些代码“洁癖”,有时甚至起个类名都要想半天,但时间证明一切都是值得的。

后来又看到了《Clean Code》,不仅讲述了简洁代码方方面面的技巧,还将写出简洁的代码上升到了职业宣言的高度。详情见《代码整洁之道》读书笔记

《Clean Code》中结尾的一段话令人印象深刻,至今难忘:
“2005年,Elisabeth递给我一条绿色腕带,上面写着Test Obsessed沉迷测试的字样,我高兴地带上。我发现自己无法取下腕带,不仅是因为腕带很紧,而且那也是精神上的紧箍咒。那腕带就是我职业道德的宣告,也是我承诺尽己所能写出最好代码的提示。写代码时,我用余光瞟见它。它一直提醒我,我做了写出整洁代码的承诺。”

2.3 重构

个人虽然没有深入接触过敏捷开发,但潜移默化中还是接触到了不少敏捷开发中好的思想和方法,比如接下来要说的重构。

重构的技巧有很多,可能不知不觉中我们就已经用到了。从最简单的重命名、成员变量提取,到类提取、继承层次中的上下移动等等。MF的那本《重构:改善既有代码的设计》配上侯捷的翻译非常经典!这里再次强烈推荐Intellij IDEA,因为它的重构功能实在太强大了,可以节省很多时间,大幅度提升我们的开发效率。

2.4 单元测试与TDD

测试驱动开发(TDD)的方法和技巧其实很简单,随之而来的好处却很多。一是对于很复杂的功能可以先实现最简单功能,再逐步完善;二是有了单元测试,可以通过失败的用例直接找到对应出问题的代码;三是通过TDD不断迭代出的代码,设计比较合理,后期更加容易维护。任何技术都不可避免的有两面性,TDD也不例外,详见《TDD实践感悟》

关于其他测试,如集成测试,使用Selenium还可以将测试自动化。录制好的测试脚本可以自动播放,鼠标键盘就像“无人自动驾驶”一样。

2.5 持续集成

持续集成(CI)被誉为项目的心跳。善加利用的话,不仅能统一大家开发的步调,集成上各种有用的插件,例如JCoverage、FindBugs、CheckStyle和各种打包部署脚本,就能有效地提高代码质量和开发测试速度。CI配合上UAT环境能让客户尽早地看到目前的产品是否是自己想要的那个样子,避免越到后期越是不好修改,尽早暴露问题。Java世界里最流行的开源CI服务器应该就是Jenkins了吧,参考《Jenkins持续集成环境搭建》

2.6 代码审查

尽管TDD和CI能自动化一部分工作,帮助我们提升代码质量和开发效率,但人工的代码审查还是少不了的。自查、互查、一起查,就像结对编程一样,这也是像高手“取经”的好机会!

2.7 领域模型

一套准确而稳定的模型层的价值是难以估量的,这对于当前业务代码以及未来升级版本都是具有很大作用的。这也是面向对象分析设计(OOAD)、领域驱动设计(DDD)等方法论的“战场”。虽然对DDD没有太多的实践经验,但还是推荐一下,不是要全盘接收,而是从中汲取最精华的思想。DDD Sample Application是不错的上手学习资料。此外,配合领域模型定制领域语言(DSL)也是个趋势,值得关注。


3.增压:持续的知识积累

3.1 知识体系

前两部分已经介绍了工具和方法论,能让我们迅速地加速到百公里。然而这些知识大部分是谁都可以从网上获得的。像工具谁都能安装,除非你有“私房”插件,像方法论也都有很多著作可以学习。要想彪到二百迈,唯有厚积薄发,形成个人风格和套路。因此,一定要有自己的长期计划,并坚定地实行,毕竟慢工出细活。这是我的长期计划《程序员修炼之路》

  • 计算机数学:离散数学与具体数学。
  • 算法分析设计:常用设计技巧和数据结构。
  • 系统平台:体系结构、操作系统、网络、编译原理和数据库。
  • 代码设计:架构设计、设计模式、方法论。
  • 代码实现:开发工具和主流编程语言。
  • 测试验证:单元测试、性能测试和优化。

3.2 Codebase

传说每个高手都有自己的一套代码库。为了成为高手,我也再不断积累自己的代码库。我的代码库主要来自工作中的项目实践和业务时间的编程练习。对应最常用的两种开发工具,我的代码库也分为两大部分:Java代码和LinuxC系统编程代码。

首先来看一下我个人Java库的编排,经过多次修改定为如下结构:cs算法/编译原理等计算机科学基础、java基础API、framework主流框架、mobile移动开发、bigdata大数据hadoop/缓存/机器学习等、ui用户界面、architecture架构设计、project业余和开源项目代码、verification测试验证代码等。依赖管理方面使用了最顺手的Maven。

$ tree -I "target|*.iml|pom.xml" -L 1 codebase/
codebase/
|-- 01-cs
|-- 02-java
|-- 03-framework
|-- 04-mobile
|-- 05-bigdata
|-- 06-ui
|-- 07-architecture
|-- 08-project
|-- 09-verification
|-- autobak.sh
`-- README.md

目前我使用Sublime Text管理Java领域外的各种知识和代码,其编排主要按照系统由底层向上分为:汇编语言、C语言(基础、算法、系统、实践、开源软件)、脚本(批处理、Shell脚本、Cheatsheet)、其他语言(Golang和Python等等)。

$ tree -L 2 syspace
syspace
|-- 1-assembly
|-- 2-ccpp
|   |-- 21-basic
|   |-- 22-algorithm
|   |-- 23-system
|   |-- 24-pragmatic
|   `-- 25-opensource
|-- 3-batch
|   |-- 31-bat
|   |-- 32-shell
|   `-- 33-cheatsheet
|-- 4-lang
|   |-- 41-golang
|   |-- 42-python
|   `-- 43-php
|-- autobak.sh
`-- index.md

此外,不仅要整理自己的代码,还可以收集一些小巧精悍的开源软件来学习,比如通过Nginx代码学习网络编程,通过Redis学习C语言和数据结构,通过Lua学习编译解释原理,通过libevent学习并发编程。

Linus说过:RTFSC(Read The F***ing Source Code)。实习时在OpenJPA源码里寻寻觅觅,因为找不到一个功能的扩展点而改了源码并替到Jar包里,最后还真好使了。然后就一发不可收拾,沉浸在了Spring源码的海洋。有时一马平川地,从上到下看到底,如当时OSGi有个开源的小内核Felix。有时也会碰壁而半途而废,记得有次看Derby,一直看到存储层,记得好像用antrl生成的SQL解释器吧,因为功力不够而搁浅了。现在不管是C、Java还是其他主流编程语言的开源代码,不能说毫不费力,但是很快速地就都能看出个大概流程,不得不说也是不断阅读的结果。总而言之,阅读优秀源码的收获之大是无法用语言形容的。

3.3 Cheatsheet

Cheatsheet小抄,也就是一些来自日常工作常用操作的速查表,主要由常用配置、命令、快捷键等组成。我目前分为数据库、IDE、各种语言、中间件、操作系统等。网上有一些现成的在线Cheatsheet,不过还是自己整理的比较熟悉。实际工作中它也帮助我节约了大量的重复查询工作和宝贵时间。

$ tree 33-cheatsheet/
33-cheatsheet/
|-- db
|-- ide
|-- lang
|-- midware
|-- os
`-- revctl

关于这一部分,每个人可能都会攒了一些实用的小脚本。但要注意的是,有些工作是不适合或者说不值得用脚本自动化的。《卓有成效的程序员》里说过:“别让自动化的努力变成剪牦牛毛”。剪牦牛毛是一件很危险的事,它会吃掉你大把的时间,得到的却只是一个不实用、只能用几次或者隐患很大的脚本工具。

3.4 脚手架

脚手架(Scaffold)是个好东西,它可以帮助我们自动生成代码的“骨架”。之后利用我们代码库的积累对骨架做微调,不断在上面添加功能就能快速地形成一个可用的应用程序。Maven提供的Archetype插件是个不错的脚手架,很多项目都基于它提供了代码模板。当然如果想要定制自己的模板也很简单,具体参照《Maven原型骨架及常见问题》

除了Maven这种构建工具外,IDE一般也提供了各种小脚手架来生成小段代码。最常见的就是IDE里的代码模板和补全功能,如果觉得不过瘾可以编写自己的模板和IDE扩展插件,就像RubyMine对Rails的脚手架的支持一样。详情见《Intellij IDEA插件开发入门》

3.5 Blog

写博客的作用可不容小觑!没做过总结的知识那只是别人的知识,没做过读书笔记的书不久后就变得跟没读过一样。当碰到了总结整理过的知识时,搜索你的Blog会给你最快速的答案。不要以为这跟用谷歌搜索一样,一遍遍翻看你自己用心写的东西和看别人的东西是完全不同的概念!而且中文技术文章里有太多的粗制滥造的内容、乱七八糟的排版和无数不注明出处的转发。所以看完书的一章或做完什么有用的练习后,一定要趁热打铁赶紧总结一下!

那么用什么写呢?之前试用过Emacs下的Orgmode,之前接触过轻量级标记语言,配合Emcas感觉挺惊艳的!后来遇到了Sublime后连写博客都迁到它上面了,因为它的Markdown插件实在是太好用了。详见《Markdown语法及SublimeText下使用技巧》

3.6 多元化

随着写代码的时间长了、见识多了,解决问题的手段就会多元化起来。什么样的编程语言适合用什么样的项目,什么样的架构设计适合什么样的场景。编程语言多元化,架构设计的多元化,开发工具的多元化,最终才能促成我们解决现实问题的思维的多元化。Thoughtworks维护了一个技术雷达,定期会更新技术、平台、工具等方面的技术趋势。


4.狂暴:专注与抗干扰

尽管有了上面各种辅助,但是如果不能静下心来编码一切都白费了。要么看会这儿看会那儿,要么就是在嘈杂的环境中无法集中注意力。尽管不起眼,这却是提高效率的“最后一公里”。

4.1 免分心模式

各种IDE一般都提供了全屏模式,像Sublime Text还额外提供了”Distraction Free Mode”抗干扰模式,让你专心地投入到一个打开文件的编辑工作。

4.2 虚拟桌面

用过Linux桌面版的都知道,很多Linux分发版都提供了4个独立的桌面工作区。一个工作区可以做交流用,像收发邮件、即时通讯等,一个工作区用来访问远程服务器或FTP环境,一个工作区则专心编码不受干扰。Windows下也有如Dexpot这样可以实现虚拟桌面的软件,不妨试用一下。

4.3 盲打与打字速度

一般大家经常网上聊天的话,打字速度应该不成问题。但除了盲打26个字母外,像常用的标点符号分号括号引号、数字1-3和8-0、功能键F1和F2、Ctrl/Alt/Shift等最好也能熟悉其位置,这样敲起来才能快如风。

此外,不管用什么IDE和工具,掌握快捷键,让双手留在键盘脱离鼠标是基本功。不然空有快如风的盲打速度也是不行的。关于我最常使用的IDE的快捷键介绍请参考《十大Intellij IDEA快捷键》。关于这一部分的积累,别忘了保存到自己的Cheatsheet里。

4.4 音乐

关于为什么编程时要听音乐有不少研究,还都挺有意思的,说是不仅抗干扰还能促兴奋。万能的知乎上还真有这个问题,以及一份推荐的榜单,见有哪些适合编程时听的音乐?。甚至还有个专门的网站http://musicforprogramming.net/。这方面因人而异,我个人还是比较习惯这种“抗噪”方式的,最近在听刚看完两季的《Silicon Valley》的OST。

4.5 面包屑

当然,被别人干扰和打断在所难免。在离开手头工作之前,一定留下一些线索,比如关键点、思考到哪了等,这就是“面包屑”。这样等继续时就能稍微快一些恢复出“现场”,就像进程的上下文切换一样。


5.高效编程=工具+方法+体系+专注

前面根据个人的经验,分享了一些提高编程效率的个人心得。每个人的经历经验不尽相同,相信其实每个人心中都有一份自己的清单。但最最重要的是坚持投入,不断地练习、练习、练习、练习、练习……

这里引用最近看到的名言自我勉励一下,来自Bruce Lee李小龙:

“I fear not the man who has practiced 10,000 kicks once, but I fear the man who has practiced one kick 10,000 times.”
我不惧怕把一万种踢法都练一次的人,但我害怕把一种踢法练一万次的人。

“There are many paths you can follow to reach your destination. However, you’ll never reach the end if you keep changing paths along the way.”
到达目的地的途径有多种。但如果你沿途不断变换路线,你是永远不会到达终点的。

李笑来老师在《把时间当作朋友》曾说过:“所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就应该是最重要的策略之一。”水滴石穿,绳锯木断。不要害怕走弯路,只要专注地一直走就一定会到终点!祝福大家都能抵达梦想的彼岸,成为自己心中最厉害的那个人!

posted on 2015-08-11 21:31  毛小娃  阅读(161)  评论(0编辑  收藏  举报

导航