文章分类 » 项目管理

提高代码质量之代码审查

写代码是一种创造性的劳动,是现在社会中少数的纯手工的工作之一。程序员就像手工艺人,代码就像手工艺品。手工艺品有自己独特的魅力,但是也缺乏流水线产品的严谨和一致性。所以代码审查(Code Review)就像是把玩鉴赏手工艺品一样,通过审查代码来体会编码者的思维逻辑,同时相互学习取长补短。代码审查是提高个人和团队的代码质量的一个很有用的方法。

个人对自己的代码可以进行代码审查,因为今天的你已经不是昨天的你,你可以站在不同的角度和不同的层次来审查自己过去的代码。子曰:温故而知新。所以对于自己的代码应该定期做Code Review。可以用好日程安排工具,比如Google Calendar之类。在自己做到觉得需要日后来审查一下的地方,就可以在日程安排上记录一笔。到时候就可以按照记录去审查了。作为一个想不断进取和自我提高的程序员来说,这是很高效的方法。

自己的代码审查很好进行,只要你有毅力。相比之下团队的代码审查就不是那么容易实施了。但是代码审查在团队中能体现出更大的促进作用。除了可以让团队成员之间相互学习进步、激发思考、统一编程风格之外,代码审查还能发现一些系统的潜在问题和QA测试不到的问题,从而提高代码质量。

但是在团队内进行代码审核的时候,也要注意方式方法,才能发挥其积极作用。否则还有可能产生负面的影响。

1. 引导团队成员对代码审核的正确认识

代码审核并非是给某人挑错,也不是瞻仰膜拜牛人的奇技淫巧,而是大家泡一杯咖啡端一杯茶,一起来鉴赏品玩代码而已。目的是为了促进团队成员的成长和提高。

如果在代码审查的时候发现bug,不要过于责问,而是应该从技术层面加以分析、建议和讨论。如果你是Manager, 一定要注意不要炫耀自己,低调一点,重点在做好组织工作。初期一定要引导好团队成员对代码审核的认识,不要变成个人代码秀或者挑错大会和批斗大会了。

2. 要让团队成员看到代码审查的好处

在组织Code Review的初期,一定要用心去挖掘一些可以让大家学到东西的代码段。让大家体会到,可以从别人严谨的逻辑和优雅的编码学习经验技术,也可以从自己和别人的脏代码以及疏忽大意来吸取教训。尝到了甜头,这么有好处有意思的事情,大家肯定乐意再来一次了。

3. 平等轻松的纯技术讨论

在做代码审查的时候,只能有组织者,不能有CTO、Manager、权威、叫兽砖家。这是一个平等的轻松的技术讨论会,可以佐以饮品和零食哈哈~要激励大家勇敢地说出自己的看法,置疑其他人的看法。这样才能激发出大家的参与热情和不断地思考。这种讨论其实就是一种头脑风暴。

4. 针对项目的热点和难点进行代码审查

针对一次代码审查进行选题的时候,可以多从项目的热点和难点入手,比如框架是怎么工作的?数据库是怎么封装的?缓存是怎么处理的?内存占用高的地方是怎么优化的?一些复杂的算法是怎么实现的?某个bug为什么会反复出现?————走进科学将带你走进代码审查的世界~~哈哈回到正题,代码审查的选题一定要对事不对人。记住!要避免针对某个程序员的代码审核。。。除非你想炒了他。

5. 少而精

代码审查是一项很激烈的脑力运动,而且在多人参与的时候尤其如此。和头脑风暴的本质差不多。不但自己要理清别人的代码,还要去审视和判断,还要说出自己和看法,还要听懂别人说出的看法。所以每次代码审查的内容和时间要少而精,否则大家疲劳之后,讨论就会变得冗余而无趣。

6. 发现问题由编码者自己去修正或者重写

当我们在审查时发现了问题、讨论了修正和改进的方案,我们肯定需要一个人来讲这些方案实现出来。这个时候就应该由造成问题的程序员来做了。因为只有真实去改动代码的时候,才会将问题最真实的原因暴露出来。这个程序员才能去彻底修复这个bug。同时在他也会从自己的错误中得到提高,在之后的职业生涯中应该不会再犯同样的错误。

7. 做好讨论记录和问题跟踪

在大家的思想相互撞击的时候肯定会有很多灵光闪呀闪,如果不记录下来就太可惜了,丧失了讨论的意义。所以每次代码审查一定要有专人来负责做记录。讨论之后将记录整理并email给所有人。

PM和Manager之类的就可以根据讨论记录来分配改进任务。每个团队都应该有自己的项目管理系统,或者说是bug追踪系统吧。如果没有,赶紧去搞一个。推荐开源的Redmine (Ruby on Rails)Mantis (PHP/MySQL),以及提供在线服务的Lighthouse

特别要说一下Redmine,支持中文,功能强大且简洁,跨平台使用很舒服,而且也支持多种数据库(MySQL, PostgreSQL or SQLite),同时可以和git集成使用(在git push时自动更新ticket状态)。

8. 使用适合自己团队的代码审查工具

现在很多团队都转向了使用GIT,那么就可以利用Github来作为代码审查的工具。在Github里面可以针对某个branch的某个commit提交评论,然后Github会给项目的参与者发送一封邮件。通过这种在线的评论来进行代码审查,让大家可以利用零散时间去看一些小的代码段,就像在论坛发帖回帖一样,不用一定要坐在一起,不会打断正常的工作,同时也完整地保留了讨论的过程。如果是个人或者小团队,不想开源自己的代码的话,也可以利用Bitbucket来建立私有库托管代码和进行代码审查。

总之

XXXX是一把双刃剑,代码审查也是如此。 进行代码审查对于组织者的能力要求比较高,要多思考和调整,激发大家一起来做好代码审查,发挥其最有益的效用。

Git与Github的使用(ubuntu)

Git的简介

Git是2005年Linus Torvalds 为了帮助管理 Linux(R) 内核开发而开发的一个开放源码的版本控制软件,正如所提供的文档中说的一样:

Git 是一个快速、可扩展的分布式版本控制系统,它具有极为丰富的命令集,对内部系统提供了高级操作和完全访问。

Git的安装与配置

安装Git

ubuntu 10.04源里有Git,直接用yum,apt-get安装即可。安装后直接使用即可,一些初始化的信息在下面有介绍。

配置ssh-key

Github使用ssh tunnel(加密通道,不做介绍了)。因此要先产生一枚ssh-key 上传到Github上。

$ ssh-keygen -C 'your@email.address' -t rsa

然后确认默认路径,再连续输入2次密码(直接回车则密码为空)即可。 (备注1)

配置git的输出格式和颜色

git默认的输出不是很友好,不容易阅读。不过我们可以通过修改git配置的方式来自定义git的输出格式和颜色,具体方法详见:让git的输出更友好

Github注册及Git的简单操作

http://github.com(支持汉语),注册后帐号右上角有”Your Repositories”,选择”Create One”。在”Project name”处输入名字后,它会显示出一个创建新项目的小教程。 说一下在本地的一些操作,假设你的代码文档已经存在了 ~/work文件夹中,那么:

Git的初始设置

$ git config --global user.name "Your Real Name"
$ git config --global user.email  you@email.address

这些是要在以后版本信息里面出现的东西。

初始化Git仓库(init)

$ cd ~/work
$ git init
# 然后会显示:
Initialized empty Git repository in $PROJECT/ .git/

表示在当前目录下闯将了一个.git的隐藏目录,这个就是所谓的Git仓库了。此时的~/work文件夹,我们也改名称之为工作树。

生成快照(take a snapshot)

将工作树中的一些文档存至Git仓库中,并且变成Git仓库能够识别的数据格式。

$ cd ~/work
$ git add .

注意:add 与后面的”.”是有一个空格的,这个”.”表示所有的文档。如果只生成一个文档,则将”.”改为文档名即可。

提交(commit)

所生成的快照被存放到一个临时的存储区域, 称该区域为索引。Git的每次更新都需要提交一次。

$ git commit
# 一般来说都需要对跟新的版本进行说明,则上述命令应为
$ git commit -m "你的版本更新信息"

提交密钥

还记得刚刚生成的密钥吧,现在我们要把它放到github上了

$ cd ~/.ssh
$ ls

会显示”idrsa     idrsa.pub” 两个文件,前一个是私钥,.pub的是公钥。将公钥粘贴到你github帐号中的 SSH Public Keys处即可。 (备注2)

文档忽略

提供了文档忽略机制,Git可以将工作树中你不希望接受 Git 管理的文档信息写到同一目录下的 .gitignore 文件中。以文件”dust”为例:

$ cd ~/work
$ echo "dust" > .gitignore
$ git add .

先叙述这么多,有更多的需要可以到git官网上去查http://git-scm.com

PULL/PUSH

  • git-pull:从远端仓库取回版本更新
  • git-push:可将本地版本更新推送到远端仓库中。

团队开发流程

$ git clone  用户名@IP:目标路径
    # 进行开发
$ git add 改动的文件
$ git commit
$ git pull
    # 解决合并问题
$ git push

push命令只能将代码push到你的分支上。

合并&分支

分支的作用有很多,并行开发多版本,并行开发新功能,测试某个独立功能点等。而这些总结起来,本 目的就是为了避免不同版本的代码之间互相影响而当这种影响已经不存在了,就需要合并了

1.产生新分支(名为local):

$ git branch local

2.查看存在多少分支

$ git branch
    local
    * master

3.切换到分支/主文件夹

$ git checkout local

4.分支的合并

$ git checkout master # 将当前分支切换为master
$ git merge local # 将local分支与当前分支合并

5.删除分支

$ git branch d local

备注1

关于ssh命令:

  • -keygen : 产生公开钥 (pulib key) 和私人钥 (private key)。
  • -c : 要求压缩所有资料(包含 stdin, stdout,stderr 和 X11 和 TCP/IP 连接) 压缩演算规则与 gzip 相同
  • -t : 强制配置 pseudo-tty。

备注2

注意:复制的时候要一点不差的拿过去,一个符号一个空格都可能会导致密钥不能使用,其中 Permission denied (publickey). fatal: The remote end hung up unexpectedly 这个问题就是因为不能识别密钥而没有权限导致的。

链接

  1. 一个很直观的git命令表: http://www.cnblogs.com/1-2-3/archive/2010/07/18/git-commands.html