做软件这行,我觉得如果刚去一家公司,有很多东西需要适应,其中很重要的一个方面就是工作过程中用到的软件。我刚来Oracle的时候,有不少软件是我从来没有用过的,花了一段时间才适应下来,现在感觉非常得心应手,那些原本觉得很不好用的软件,比如vi,现在是我每天必须使用的,包括现在在写的这篇文章,就是用vi编写的。所以我们就先从vi说起吧。下面提到的软件除了Visual
Studio外,都是开源的,可以免费使用。你去google用本文的软件名做关键字可以很容易地搜索到这些软件,以及它们的文档和用户手册,来学习使用。它们是全世界乐于奉献的软件高手们智慧的结晶,好用不是吹的。
1. vi
现在人们所说的vi,都是指vim(
http://www.vim.org/),它是一个功能十分强大的快速编辑工具,不仅可以用它写普通文章,还能够编写各种语言的代码,而且如果你有相应的配置文件,就可以支持关键字多色彩显示。而它灵活的快速编辑功能,更是我的最爱。你可以不使用鼠标而十分便捷地移动光标,或者删除、更改、替换,而移动或者编辑的单位,可以是一个字符、一个单词、一句、一行、一段、句首、句尾等等,这样你就可以完全不使用鼠标而快速编辑,比起使用鼠标,要快很多。
而用vi写代码还有不少很好用的功能,首先是可以限制行宽。我们的代码需要限制行宽在80个字符,刚开始不适应这个要求,因为这个要求最初是为了适应那种老古董终端的,而现在那种东东都进了垃圾堆和博物馆。但是,由于已有的代码都保持了这样的格式,而且组内的很多专家级开发者30多年来一直是这样的习惯,所以,我们新人必须去适应。使用vi可以设置列宽为80个字符,这样超出后就折行了,很容易辨认。
第二,vi可以与cscope合作,完成代码浏览的功能。cscope我在后面还会介绍,有了vi和cscope,我们就有了大部分Visual
C++的功能,还有不少超越,而且可以避开它的很多缺点。
第三,vi有丰富的插件,可以完成很多辅助功能,比如拼写检查。第三,针对代码编写,有很多体贴的辅助功能,比如写c代码的多行注释时候,当输入回车换行后,自动有一个星号放在新行并且与上一行的星号在同一列;写c++代码多行注释时也自动有一个//放到新行。
vi的windows版本gvim还支持windows的编辑命令,比如Ctrl-c, Ctrl-v, Ctrl-x,
Ctrl-p, Ctrl-z, Ctrl-y等等,对于习惯了Windows文本编辑器的用户,很容易适应。
vi也有一些缺陷,首先是对汉语的支持比较差,你没办法使用w或者b向后、向前移动一个词,因为vi没有分词能力,它会把光标移动到下一个非汉语字符的位置,当然它也没办法完成针对汉语的拼写检查。即便如此,并不影响我使用vi的兴趣,事实上,虽然我的机器上有公司购买的正版的ms
office办公软件,我只用过powerpoint来创作一些ppt用于演讲,其余的时候,都是在用vi。
新手对于vi还有一个困惑,就是命令比较多,很难掌握,不好记住。我最初就是这样,后来发现了一些规律:vi的命令都是动宾结构的,可选地前缀一个数目。比如2dw删除当前光标后面两个单词,这里面的2就是数目,表示执行这个命令两次,而真正的命令dw就是一个动宾短语,d表示删除,w表示当前光标后面两个单词。于是我们只要记住所有的动词和所有的可以操作的对象即可。对文本的动作无非这些:删除(d)、更改(c)、复制(y)、移动
(<,>),而可以操作的对象是从当前光标位置开始,到一定范围结束的所有字符,这个范围包括词首(b)、词尾(w)、句首(()、句尾
())、行首(^)、行尾($)、上一行(-)、下一行(+)、上一段({)、下一段(})
。所以一个命令是这样的形式:数目-动作-对象,这样你输入2dw时候,vi就把当前光标位置开始的两个单词删除。如果你不输入动作,那么默认的动作是移动光标而不改变文件内容,这样你可以很快地把光标移动到目标位置,然后进入输入模式来输入字符,这远比抓住鼠标,然后转滚轮或者移动鼠标来定位要快很多。当然,有少数命令还是要特殊记忆,比如针对字符的删除是x,替换是r,这时自然没有了范围因为范围已经固定成为光标下面的单个字符了,所以你可以用3x来删除从当前光标位置开始的3个字符。
vi特意为编码准备了一个[和]命令,在命令模式下两次输入[或者]字符,你好发现光标移动到了上一个{的位置或者下一个}的位置,这可以帮助我们快速地定位到上一个函数或者类、下一个函数或者类。
要有效地使用vi的搜索和替换功能,你就要掌握一些正则表达式(regular
expression, regex)
的知识了,可以说,在*nix上面工作,正则表达式是基本要求,因为shell, sed,
perl等等的脚本,都会或多或少地使用到它。
2. cscope
这个软件可以做代码快速浏览,你可以快速找到一个函数、类、变量、宏的定义,一个函数调用了那些其他函数,以及那些其他函数调用了它,等等。这里(
http://cscope.sourceforge.net/)
可以下载cscope,还有使用手册。在Linux上,它是我所知道的最有效的代码浏览工具。它可以和vi密切配合。首先,你可以在vi里面输入命令来调用cscope完成上述代码浏览功能,同时,当cscope列出一系列符合条件的条目后(比如你要找到所有调用了printf的函数,cscope返回给你一个列表,里面每一个都是一个这样的函数),选择一个,cscope又会启动vi来显示代码,而这样的嵌套不受数目限制。cscope的另一个强大功能是,它支持各种各样的编程语言,默认是c语言。这个教程全面地介绍了如何让vi和cscope协同工作:
http://cscope.sourceforge.net/cscope_vim_tutorial.html3. gcc
gcc恐怕是当今全世界使用的最多的编译工具了,很重要的一个原因是:它包含了很多种语言的编译器
:) .
使用编译器的方式是写Makefile,而我写出第一个Makefile的方式是修改一个简单的已有的Makefile。后来仔细看过了很多
Makefile,对它们越来越熟悉了,觉得它们越来越亲切了,它好过visual
studio的很重要的一个原因是,你从Makefile中可以清楚地看到整个编译、链接的过程。而configure脚本自动产生Makefile,然后由Makefile编译链接这种工作方式,是*nix平台上非常有特色的一种发布方式。gcc比较新的版本都是完全遵循c++语言标准的,而且它有逐步替代各个平台上的c/c++编译器的趋势。
4. gdb
gdb是一个功能很强大的调试工具,它的影响力很大,以至于诸如perl,
python等的调试器,都是用和gdb一样的调试命令集。但是在用户友好性方面,说实话,我用过的最好的调试工具还是MS
的Visual
Studio,毕竟gdb输出的密密麻麻的纯文本看起来还是很费神,特别是当你的代码中有很多c++类模板时候,一个模板类可能要占据调试输出的好几行,看起来相当头大。要不是我的显示器屏幕够大,我想我前段时间会崩溃于此的。所以当可以在windows上面调试时,我先用vc调试通过,然后放到*nix
上面编译链接运行测试、这时常常会祈祷万事大吉,但偏偏有几次在*nix上面有问题而不得不调试。
上面四个工具的有机组合,基本上构成了在*nix上面的集成开发环境,虽然在用户友好性方面它们比不过visual
studio,但是你不可能囿于ms
的小世界,否则你的产品很可能发展空间不大;而对于我们的产品Berkeley
DB,其多平台的支持是最基本的特征之一,所以,这些工具是肯定要使用的。刚开始觉得他们像旧石器时代的产品,但是现在觉得它们是我离不开的好朋友了,它们虽然没有花哨的外表,虽然没有那么体贴入微,但是他们的稳定可靠、不思索取只求贡献、优秀的技术品质等等,都是现在很吸引我的方面,自由软件的世界正是由于这些坚硬的磐石做根基而如此稳定可靠。
5. visual studio
在微软的平台上开发时,我会用到它,另外就是,调试时尽量使用它。它的代码编辑器有些缺点,首先是编辑速度较vi慢,而且,如果你没有选择等宽的字体,就不方便保持代码格式,或者本来对齐格式良好的代码,在vc里面反而不对齐了,等等。当然,浏览代码还是很方便,虽然有时候索引数据旧了却不更新,以至于"
转到定义"等功能不准确了。vc自负地相信它自己能够自动地做好索引更新,可惜它没有完全做好,我只好忍受索引不一致期间的痛苦;cscope则相反,用户命令它更新索引它才这样做,这样至少我可以"要求"它立刻更新索引,它会忠实的执行我的命令.
6. gprof
这是与gcc协作的一个profiling工具,不能对其他编译器创建的可执行文件做profiling。通过把你的软件用profiling模式编译,然后运行软件,你就得到了一个profiling数据文件,把这个文件送给gprof,gprof就能够产生一个
profiling报告,它能给你报告你的代码中各个函数执行花费的总的时间、被调用的总次数,以及任意一个函数调用了那些函数,每个函数各花费了多少时间、被调用了多少次。用这些数据我们可以分析软件的性能,比如某个函数花费了过多的时间,或者被调用了过多的次数,就要分析原因,这很可能能够帮助你找到影响性能提高的不良设计。这些数据可以帮助我们找到软件中影响性能的代码,以及不良的设计,以便改正。通常,应该对软件的所有的测试程序跑
profiling
test,并且我有一个tip,就是你的测试程序要持续很长一段时间,这样计时才准确。因为计时的时间单位是0.01毫秒,而profile的代码单位是函数,所以如果一个函数只执行了几次,它的总时间在报告中可能是0.02毫秒,而这个数字是不准确的,很可能你下一次得到的结果是0,或者0.06毫秒。为了准确,我们的测试必须要尽可能多地覆盖到代码的各个角落,并且测试最好在同一个进程中重复很多很多次,这样绝大多数比较复杂的函数都可以执行足够多次以便每个函数耗时多十几倍于计时单位0.01毫秒,这样计时才是准确的。如果用脚本多次运行同一个测试程序,结果还是不准确的,因为它们在不同的进程中执行,时间没有累积起来。
7. gcov
这也是gnu的一个很有用的工具,它能产生测试覆盖统计数据,以便我们搞清楚软件的那些地方还没有测试到,从而增加更多的测试来覆盖到那里。当测试覆盖率提高后,不仅软件的质量更加可信和可靠,上面的gprof产生的profiling报告也会更加全面准确,从而对性能分析和提升也有益处。
gcov产生的覆盖报告是纯文本的,看上去比较枯燥,而lcov能够把这种结果转换为html页面,这样看起来直观很多。
8. cygwin
这是一个运行在Windows上面的用于模拟*nix用户使用环境的软件,完全安装后,它包含了几乎所有*nix上面常用的软件工具,这让我们在
windows上面高效地工作成为可能。我的感觉是,当完全习惯了在*nix环境下工作,适应了使用shell和各种脚本来批处理的工作模式后,工作效率会比原来Windows上面提高很多,并且完全离不开cygwin了。
9. mercurial
这是一个分布式的源码控制系统,它的功能比cvs或者svn要强大的多,支持各种复杂的版本控制任务,比如多个分支的管理等。所谓分布式的,是说如果多人协作工作,每个人的机器(site)上面都有关于这个代码库的所有信息,它们是平等的,当然,在实际使用中,我们还是会使用一个中心服务器,所有开发者向这个site提交更改。现在有windows上的图形界面版本TortoiseHg,以及Eclipse插件。如果加上MqExtension,使用就更加方便了。以前一直在用cvs,也用过一段时间svn,感觉还是mercurial更好用更强大。
10. patch
与mercurial以及其他版本控制工具紧密相关的,就是
patch工具,它用于把版本控制软件产生的补丁文件(diff 文件,也叫做patch)
应用(apply)到代码库中。另外,偶尔还需要独立的 diff 工具比较文件。
11. Eclipse
我用的是Eclipse的各种变体,比如vxworks,
qnx等的IDE,他们附带在这些嵌入式平台提供的整套开发环境中。它们都是在Eclipse的基础上略作改动的,我几乎找不到多少它们与正宗的
Eclipse的不同。这就是开源的好处---大家不用重复开发功能相近的一大堆IDE了,全世界的高手们认认真真做好一个IDE,大家一起受益。
12. Putty
我用这个软件来连接我的Linux服务器,在真实的Linux环境中工作。它还有一个小兄弟,叫做WinSCP,类似
ftp,用于在两台机器之间传递文件。当然,使用putty还会间接地用到ssh,来安全地连接远程机器。 与putty类似功能的还有vnc,
vnc是一个c/s架构的软件, 在远程服务器上面安装上vnc服务器并且启动服务器后,客户端与之连接,它的好处是当客户端断开连接后,对于远端的服务器来说,你仍然在登录状态,这样,如果你需要运行一些持续几天的脚本的话(在命令上追加后台运行'&'指令并不总是管用),
可以用vnc。
13. Thunderbird
我用它收发邮件,我的感觉是,它比outlook好用很多,另外,由于我在linux上面也是在用它,所以统一使用一个软件还是简单的多。
14. firefox
功能强大的浏览器,除了在淘宝交易外,我都用firefox上网,实在找不到更多不用它而使用ie的理由。
15. pidgin
公司内部的IM协议是Jabber,而自己还有msn、yahoo账户,所以直接使用pidgin,简单方便。最欣赏它的有两点:首先是多协议,多平台,开源,开放,稳定可靠;第二是,它没有任何广告,而这是值得敬重的--pidgin的开发团队值得我们用户尊敬。如果pidgin也动不动喷出一个广告,像拉出一坨屎一样的话,我会对它很反感的,这个世界上除了钱之外,还有更多其他东西值得珍惜和追求。在中国现在这个铜臭气熏天的时代,能有多少个
IM开发商做到这一点?
16. bash
它是*nix的常用 shell之一,
很多批处理的工作可以写出shell脚本来运行。用习惯了bash,包括cygwin上面的bash,觉得Windows的Explorer以及其他管理工具太慢太麻烦了,更别提自动化了。
17. ssh
用它安全地登录另一台机器,并且在其上执行各种操作。例如,我们可以通过ssh登录到远程机器上面运行各种shell脚本执行批处理任务,这通常是自动化测试当中重要的一步。
18. doxygen
用它可以自动产生代码API文档,只要我们在代码中用特殊标记来标记文档格式即可。这样做的好处是,软件的文档和代码更新可以同步进行,因为这些文档就是写在代码文件中的。更新代码的同时更新文档,然后运行doxygen,新的文档就产生出来了。在Berkeley
DB的下一个发布版本中有我完成的一个规模较大的功能模块,
其中使用了doxygen格式的API 文档,感觉相当不错!
如果一个软件不是一个类似Berkeley
DB的程序库,而是一个直接面对用户的GUI软件,我们仍然有必要在所有代码文件中添加doxygen标记的文档,这样可以产生出供开发者使用的文档。
19. docbook
它也是用来产生文档的,不过文档内容是单独维护的。这是因为,除了API
文档以外还有一些文档不针对某个类或者函数,而是介绍性的或者全局性的文档,这是放在代码文件中不合适。所以,我们可以使用还有docbook标记的
xml文档来记录这类文档的内容和格式,然后使用docbook产生各种输出,包括html网页,WinHelp文件,pdf文件,ps文件,等等。
从下一个版本开始,我们内部使用docbook格式的xml文档,所有的文档包括API
文档使用docbook的xml格式来标记。那么,是不是使用了doxgen标记的源代码中的API
文档还要重新写成docbook的呢?这是我前段时间遇到的一个现实的棘手的问题,
在google、百度都没有搜到自动转换工具。doxygen可以输出xml格式的文档,于是我自己动手写了一个python脚本,把doxygen的xml输出文档转换为docbook的xml输入文档,完成了这种自动转换。这样,我可以首先使用doxygen产生xml格式的文档,然后运行python脚本转换为docbook的xml输入文档,然后运行docbook处理这些文档,产生最终的与其他docbook
API 文档兼容的API 文档。 以后有机会给大家详细介绍这个自动转换工具。
20. Linux
公司内部有大量的机器安装着Linux操作系统,除了保留一些Windows系统的机器用于对windows平台的支持、开发和测试外,公司的各种
IT系统以及对各种产品的开发、测试的机器都是Linux系统。当然,非技术员工的笔记本电脑还是在使用windows。我用到的Linux系统包括
Ubuntu和Oracle Enterprise
Linux,都是很好用的Linux操作系统。有些同事在自己的笔记本上面也换装了linux系统,我还没有,因为ubuntu的qq不可以视频、语音聊天,而虚拟机还是有些慢。强烈建议腾讯为中国的linux普及做出自己的贡献---开发出支持主流桌面linux(ubuntu,
fedora)的完全功能的qq,事实上,国家信息产业部应该以行政命令的形式要求腾讯予以支持。如果这一点做到了,那么广泛地普及linux会容易得多。
大家可以发现,我们使用的软件当中,除了微软的少数几个软件外,都是开源的软件。事实上,据我所知,我们公司的标配软件中,有相当大一部分是开源软件,我所知道的付费软件只有微软的windows,
office,visual studio等少数几个。