2008年9月11日星期四

完美To-do List: Toodledo

使用很多年to do list工具了。但是越来越发现难以找到能够完全满足要求的。
结合GTD理论以及柯维的First Things First理论,现在总结需求如下:
  1. 需要能对任务的内容(context)进行分类
  2. 需要能对任务的状态(status)进行分类(next action, action, waiting for, sometimes, finish...)
  3. 另外,各种任务有以下区别:
a. 某一阶段的目标Goal
b. 日常工作
c. 特定日期需要完成的任务Task
d. 某段时间需要不停关注,例如:项目(project),一般有起止时间。
e. 仅仅是某些想法,记录以备参考。Reference
  1. 任务管理需要能够集成日程表(calendar)
  2. 结合日历,可以每天记一些工作日志(相比BLOG应该更加偏向于一些机械性的工作内容)。
  3. 任务(task)不等于日程(appointment)

可用的软件中:
  • outlook理念落后(outlook2007还可以,但也不完全匹配)
  • GTD类软件普遍功能简单,而且不能集成日程表
  • Google Calendar只有日程,没有任务。
  • PlanPlus过于笨重,而且价格不菲。

直到最近看到了www.toodledo.com,发现其可以完全满足上述需求。而且还有额外的功能:
  • 集成Google Calendar
  • 合作与共享
  • 其他功能还在摸索中。

不过强烈建议使用。

新款密码管理工具: LastPass

经常上网的人,有许多username和password需要记住,例如:电子邮箱,网上银行,网上购物,论坛,求职网站,BLOG,社区网站,同学录等等等等。
想全部记住不同的密码,很难;全部使用相同的密码,极不安全。于是乎出现了很多密码管理的软件来帮助人们记住密码。流行的软件有以下一些种:
  1. AIRoboForm:这个领域最著名的产品。功能十分强大,使用方便,能够集成多种浏览器。能够自动识别网站切进行登录,能够管理注册表单,还能够记录一些与网站无关的个人保密数据。唯一的不足是无法进行网络存储且同步。虽然是收费的软件,但物有所值。
  2. KeePass / ALPass:免费产品。KeePass的缺点是操作比较繁琐。ALPass的缺点是仅仅支持IE浏览器。而且两款软件的数据也都是本地存储。
  3. Firefox插件,如Magic Password:免费产品,使用方便。这类软件多是利用网站的关键字和用户设置的主密码来自动计算网站登录的密码。优点是生成的密码非常规范,不易破解,而且没有任何数据进行本地或网络存储,非常安全。缺点是仅仅支持Firefox浏览器,且对插件的依赖性很大。
  4. 密码管理网站:优点是对本地系统没有任何要求,只要有浏览器即可,网络存储,所以随时可以使用。缺点是操作非常不便,基本上需要手工维护。典型的如:豌豆网, PassPack, Clipzz等等。
  5. 浏览器自带的密码管理功能,如IE, Firefox, Opera。功能往往很弱且不完整。
  6. Google Browser Sync:现已停止下载,主要是将Firefox的各种数据(包括书签、密码、Cookie等)同步到GMAIL帐号中。非常方便,缺点是只支持Firefox浏览器。

新产品LastPass与众不同:
  • 集成不同的浏览器,包括IE和Firefox。
  • 帐号密码网络加密存储,所以不需要进行备份。
  • 能够进行自动识别与自动填充,操作方便。
  • 能够自动生成密码,也可以手动输入密码,所以对软件本身没有很强的依赖。
  • 能够导入流行的密码管理软件的导出数据,包括:AIRoboForm,KeePass等。

结论:强烈推荐使用。

2008年9月3日星期三

Redmine试用

由于project server庞大而且安装使用复杂,所以正在考虑使用一些轻量级的项目管理软件。暂时选中Redmine。

  1. 安装
  • 安装instantrails
  • 启动instantrails服务
  • 使用phpmyadmin在mysql中建立数据库
  • 配置database.yaml
  • 启动webrick
  1. 特色
  • 建立项目
  • 建立子项目
  • 自定义项目角色
  • 自定义角色的权限
  • 自定义问题状态流程
  • 自定义问题状态
  • 自定义跟踪标签
  • 自定义版本(相当于里程碑)
  • 自定义问题类型
  • 分配任务
  • 任务日历
  • 任务甘特图
  • 项目成员根据问题(相当于任务)填报工时
  • 灵活的工作量统计报表
  • 基于项目的wiki
  • 基于项目的文档管理
  • 基于项目的论坛
  • 上传文件
  • 新闻/公告
  • 系统活动跟踪
  • 里程碑状态报告
  • 个人的dashboard
  • 缺陷跟踪(问题跟踪)
  • 多语言支持,多时区支持
  • email自动发送
  • 导出到csv/pdf…
  • 版本控制支持(包括subversion, cvs等等)
  1. 没有的功能
  • 人员成本
  • 项目预算
  • 问题不能有子问题(问题不能分层)
  • 问题只能分配给一个成员
  • 版本控制不支持:vss, clearcase, starteam
  • 甘特图的显示细节无法进行自定义
  • 没有pert图
  • 无法定义项目流程规范(模板)
  • 虽然可以进行缺陷跟踪,但是很遗憾无法同时集成test case管理(如果testlink能够集成redmine就好了)

结论:
  • 基于项目组级别的项目管理软件,轻量级的,足以应付一般的软件管理。
  • 不具备企业级的功能,但是如果能够配合一些管理手段的话,也足够用了。
  • 对于一款开源的产品来讲,Redmine已经非常出色了!

2008年9月2日星期二

谈谈人员素质

在国内的现状就是这样的:由于IT行业人员需求量大,而且平均工资水平也还过得去,所以有大批的人才虽然从性格、爱好、综合素质等多方面来看并不适合这一行业,但是出于就业的考虑,也加入了这一行。
在上一家软件外包公司,我参与了3年的毕业生招聘工作,就是说,招聘部门负责面试综合能力,我来负责面试技术。中国的高校发展参差不齐,所以我明白我不能过分苛求应届的毕业生要有某某项目的实战经验。于是乎,我对毕业生的考察以课内的基本功为主。

数据结构
第一题:没有指针机制的情况下,如何实现链表结构?(只有20%左右的人能够回答出使用数组,其中又有一半的人是蒙的而不知道如何实现。)
第二题:哈夫曼编码的作用是什么?(大约60%的学生能够提供正确的答案。)
第三题:列举出你所知道的排序算法的名称,仅仅是名称就可以?(大约90%的学生回答出了冒泡排序;有70%的学生同时回答出了插入排序;又有20%的学生同时答出了快速排序;在我的印象里,几乎没有人能够提及谢尔排序、归并排序和堆排序等等。)
操作系统
第一题:请解释一下什么是进程死锁?(令我吃惊的是,大约只有40%的学生能够让我确认他正确理解了进程死锁。)
第二题(如果你正确回答了第一题的话):最常用的避免进程死锁的方法是什么(提示:教材中所讲解过的)?(只有10%的人能够想起来PV信号灯)
第三题(如果前两道都答对的话):请解释一下操作系统的内存分页管理机制?(要求不高,能够提及局部性原理即可,但是只有零星几个人能够通过)
数据库原理
第一题:请列举出数据库表设计原则中,都有哪几种范式?(大约60%的人能够说出第一到第四范式)
第二题(如果答出第一题的话):其中那一种范式又叫做正规范式?(只有20%的人回答是第三范式,其实说第三范式也不准确,不过马马虎虎就算过了)
C语言
第一题:在struct中可以定义属性,但能否同时定义函数?(当然不可以,否则不成了class?这道题难住了40%的学生)
第二题:函数能否作为另一函数的参数?(呵呵,我相信很多人听到这个问题的时候都蒙了)

其实我从心里最想问的问题是:你们大学4年都学什么了?

我在上大学期间绝对不是什么好学生,在班里排名中等,逃课作弊不在话下,所以对不用功的学生绝对没有仇视心态。不过,我的同学当中,就算最不用功的学生也会非常用心的去听数据结构课程,因为我们都知道:我将来想干这个行业,就得指着这个吃饭啊。我们公司的生源学校也不全是二三流的学校,也包括了几个211工程中的国家重点院校。
不过,在面试的学生中,有两类人回答问题的结果不错:一是考研失败的学生,因为这些内容他刚刚复习过的(课程年了两遍,效果当然不同);二是工作几年之后又读了硕士的研究生毕业生,因为这些人在读研的时候更清楚自己想要学些什么。

我曾经面试过这样一个研究生毕业生,上面的所有问题对答如流,于是,我稍稍来了一点比较邪恶的:
问:C语言,现在有a, b两个变量,想把它们的值交换过来,有什么方法?
答:比较通常的做法是使用第三个临时变量,不过使用“异或”更有效率。

回答完这个问题之后,我告诉人力资源部门:这个人应该高于普通研究生入职标准2000元的水平进行招聘。后来我就再没有见过这个学生,很遗憾,可能多给2000还是少了点,要不然就是老板没有批准我的建议。

再说说在职人员的招聘。
由于以前的公司是做业务应用系统的,所以程序员需要天天和数据库打交道,SQL语句经常使用。所以在招聘的时候,我可以不太看重程序员对编程语言的熟悉程度,但是SQL语句必须熟练。针对这点,我编了两道SQL语言的笔试题。题目不太复杂,第一道主要是考group by 和case when,第二道主要是考union。我准备给候选人们半个小时的时间来完成这两道题。但是这两道题可是难住了一大部分前来面试的候选人。以至于我在怀疑这两道题是不是太难了?
于是我将这两道题发给了两个同事来做测试,其中一个是项目经理,另外一个是作为初级程序员的一个小女生。5分钟之后项目经理交卷。15分钟之后初级程序员交卷。两个人提供的答案和我的参考答案几乎完全相同。

有意思的是,后来我通过MSN MESSENGER将这两道题发给了我一个正在读研的师妹。大约半小时之后,答案发送回来。其中第二道题的答案思路非常奇特,我仔细的看了之后,发现不仅能够得到正确结果而且比我提供的算法效率还要高一些!非常遗憾,我最终没能说服她毕业之后来到我们公司。当然,这对她个人来讲不是坏事。

说到算法效率,还有一个有意思的故事:
我们曾经有一次给客户开发一个业务应用系统。系统的报表功能中,有一个关于返修率的报表。在系统试运行期间,发现该报表无法得出结果。后来,我发现,程序员在生成报表的后台SQL语句中使用了函数,在当时的数据量情况下,粗略的估计这条SQL语句执行完毕需要80几个小时!I am shocked by the result!
我只得亲自出手在客户现场进行优化。2个小时之后,将报表的生成时间控制在了5分钟之内。
后来,其他的项目组在对该客户进行别的项目时,也用到了返修率报表。当时那个项目组的人员并不太清楚返修率报表以前的故事,所以委派他们组里的一个小女生来开发这个报表。结果呢?新开发的报表平均生成时间在15秒之内!I am shocked by the result again!

很遗憾,最终我没能在我的部门中留住这个小姑娘——她后来被人力资源的人偷偷的卖到客户现场去了。为了此事,我和人力资源的经理直吵到了副总经理办公室。但是木已成舟,也无可奈何了。

2008年9月1日星期一

极限编程是否符合中国国情?

XP为什么不适合国内的现状?下面是我个人的一些看法。

针对极限编程的准则:

  1. 用户故事
    先说说XP的描述:不需要在一开始完全了解需求,因为以后很可能会变化。不需要一开始就了解详细的需求,只需要到可以估算的程度就可以了,可以一边实现一边详细了解,因为有现场客户在。不需要详细的需求文档,代之以用户故事,因为沟通胜过文档,而且用户故事简单又容易编写。
    我的想法:用户故事体现了将需求分解为条目的思想,在这点上来说,是可取的。但是其他的说法就有问题了。
    首先是不需要一开始就完全了解需求的说法。对于互联网项目来讲,这种说法可能是正确的,因为需求变化非常快速。但是对于一般的业务应用系统来讲呢?需求会变化,但是关键的业务流程是相对比较稳定的。当你明明可以掌握全局的时候如果还要偏激的从局部开始着眼的话,岂不是有些钻牛角尖了?就好比要盖一座房子,在初期我可以不清楚将来的卫生间如何装修,但是总是需要在一开始的时候就了解需要打多深的地基吧?全面了解需求肯定有助于在项目开始时候建立正确的系统架构方案。
    其次是关于需求文档的问题。不可否认,在一定的项目规模内,有现场客户在,再加上充分的沟通,能够达到比文档更好的效果。但是,限定条件是不是太多了一点啊?大一点的项目,如果需要40个成员都需要和现场客户进行沟通怎么办?另外,我们知道,很多项目都会一期一期的做下去,铁打的营盘流水的兵,几期项目做下来,项目组成员甚至现场客户早就不是原来的人了,这些人靠什么来对项目进行了解呢?是不是项目组的老员工每个人都能够知道项目的所有细节呢?有很多情况,如果想要比较透彻的理解需求和业务,则需要对该业务的发展背景以及生成原因有所了解,程序员和测试人员当然有权了解这些。而这些当然都需要有文档来进行传承,仅靠用户故事显然不能胜任。有很多情况,我们需要从更高的层面来观察客户的业务,需要看到一张客户业务的全局性视图,而从用户故事那里我们能够得到什么呢,全部都是局部的片段。有很多时候,一些非常复杂的业务流程是技术人员和客户进行艰苦的讨论得出的成果,这些讨论的过程和结果如果不能够记录下来的话,早晚有一天,你会发现艰苦的讨论经常会重复的出现。
    第三,我们需要在项目初期就明确项目的business goal,明确项目边界,我们还需要明确项目的非功能需求,这些都是用户故事所无法承担的工作。
    最后,用户故事代替需求需要有一个非常严格的配合条件:必须要有现场客户,并且进行结对编程。
  2. 紧急设计过程
    XP的原则:对于每个故事做少于15分钟的预先设计,主要设计工具是白板和CRC卡片,使用最简单的方式来实现眼前的问题。对于系统中出现的问题,使用重构来解决。
    我的看法:XP承认这样会带来一些问题,所以必须严格执行配合条件:持续的重构
    同样,对于互联网项目来讲,有一定的道理,但也是局部的。而对于业务应用系统来讲呢?对于相对比较稳定的需求,我们仍然需要走到哪里设计到哪里并且修改的哪里吗?设计阶段多花些时间能够避免的问题依靠编码之后的重构来进行解决吗?重构的工作量会比预先设计的工作量小吗?(按照教科书的说法应该是被放大10倍了吧?)这不是人为的造成的浪费吗?你的客户除非就是你某个uncle,能够允许你如此糟蹋他的资金。
    中国古人扁鹊曾经介绍:真正的医术高手其实是他的师兄,但是他的师兄为什么没有他的名气大呢?因为扁鹊的师兄总是在别人的健康又出现问题的前兆的时候,就已经出手化解了。(这才是高手中的高手啊!)亡羊补牢虽不算晚,但是防患于未然岂不是更好?
    事无巨细的预先设计是不现实的,但是完全省略也不是个办法。
    设计文档需要吗?显然非常需要。还是那句话,很多项目是需要进行延续的。对于一个新的项目组成员来讲,源代码就算再规范,其可读性也比不上设计文档。做人真的不能只想着自己方便……
    说的更远一些,你的项目组中的经验丰富的有设计能力的成员将无法充分发挥他的聪明才智。他将经常看到别的一些经验不够多的程序员对子写的低水平代码,然后对他们进行重构。这种感觉就像经常需要给别人擦屁股。
  3. 现场客户
    XP的原则:客户长期与开发人员在同一间办公室办公,随时解决开发人员关于需求的问题。现场客户负责编写用户故事,负责决定用户故事的优先级以及实现顺序。现场客户负责编写验收测试用例。
    说说实话吧,你见过这样的客户吗?
    哪个客户的公司能够安排一个全职的客户代表来参与到项目中呢?如果真的安排了一个客户代表的话,他真的能够全面了解需求并对之进行把握吗?
    哪个客户公司的客户代表有能力完成这些任务呢?如果有的话,我看其他的XP原则就算都不坚持,项目结果也不会差到哪里去,因为你的客户代表本身就应该是一个很有经验的项目经理了。
    我们对客户的要求过高了一点点吧?
    而且,如果你所负责的项目的业务在客户公司是跨部门的,那该怎么办?每个部门派一个客户代表来吗?
    我看最有希望实施现场客户原则的项目应该是那种为公司内部开发的业务系统。即便如此,也很玄。
  4. 小型发布
    XP的原则:每隔一到两个月对客户进行一次系统发布,尽量早的让客户看到可执行的系统。
    我的看法:非常好。但是发布规模小到什么程度不能一概而论,只能说是尽量小。要做到小型发布,则必须先实现持续集成,否则很难承担多次的发布成本。
  5. 规划
    XP强调了对每个迭代进行规划。
    我的看法:XP的说法并没有错,只是还缺了一些东西。我们需要对整个项目进行规划,虽然越远期的计划可能越粗略,但是还是很有必要的。
    软件开发的合同不仅仅只是要求“我限定你这些时间,你看你能完成什么?”,还会要求“我需要完成这些功能,你看看你需要多长时间?”所以,做到哪里算哪里的想法似乎只能存在于政府或高校的研发部门吧。
  6. 隐喻
    在XP中,隐喻用来使项目成员对于系统的实现方式达成共识,但是似乎XP的教科书中对隐喻也没有进行很透彻的讲解。
    在我看来:隐喻是设计和沟通的辅助手段,适当的应用效果理想。但是也仅仅就是一种辅助手段而已。
  7. 简单设计
    XP的原则:力求使用最简单的方式实现当前的需求。简单的就是最好的。
    我的看法:这个说法本身就非常模糊,无法度量。简单与复杂都是相对的,仅仅存在于人们的头脑中,我觉得简单的问题可能你就觉得非常复杂。现实当中无法一概而论。
    另外,所有的时候最简单的就是最好的吗?典型的如8皇后问题,8重循环是最简单的解决方案……
    其实我们所追求的应该是不做不必要的复杂设计。
    同样,如果需要保持简单设计原则有效,则必须配合重构原则
  8. 结对编程
    XP的原则:结对编程的优势在于:代码会被100%review,有效地降低代码缺陷率,提供了很好的机会进行知识传递,使每个成员都有机会了解系统的全貌,提高生产效率。更换结对的周期从半天到3天不等。
    我的看法:结对编程优点与缺点都很明显。
    每个项目组的成员都是有自己的特长和喜好的。最成功的管理是充分发挥每个人的优势,而不是将每个人编程一模一样的编程机器。有的人一边讨论一边工作时思维会更加活跃,而有的人则是喜欢独自安静的思考。同样,遇到不解的问题时,有的人喜欢立刻向别人请教,有的人喜欢现场是自己解决。我们必须面对这些差异性,而不是试图将它们消除。从这个方面来讲,XP显得不那么以人为本。
    开发人员作为技术人员群体,其中有相当一部分人个性很强但主动沟通能力不足。在国内,这样的情况则更为夸张一些。而往往这些技术强人在项目组成员当中有很有影响力。在这样的情况下,如果我们不得不强迫进行结对编程的话,我想,管理层后面将面临非常棘手的问题。
    结论:结对编程是好东西,但需要根据具体情况适度运用。要想进行结对编程,必须具备项目组统一的编码标准
  9. 代码集体拥有
    XP原则:项目组的所有开发人员有权更改所有的代码。每个人都对所有的代码负有责任。
    我的看法:容易落入的陷阱是:没有人对代码负有责任。
    代码集体拥有的前提是结对编程。否则的话,这就是一句空话。
    编程有时候和体育竞技有些类似的地方:高手的某个出招(实现技巧)在庸手看来是非常愚蠢的。在这样的情况下,庸手会根据代码集体所有权理直气壮的对高手的精品代码进行重构……
    结论:代码集体拥有可以实施,但是不能简单处理,需要进行更多的沟通和一些技巧。
  10. 持续集成
    XP原则:开发人员坚持随时进行提交,系统每天一次集成。
    我的想法:这是很好的原则。但愿我们能够做到。
  11. 编码标准
    XP原则:实行项目组统一的编码标准,严格执行。
    我的看法:这是最基本的。而且越严格越好。我们时刻需要提醒自己:软件项目的产出是产品而不是艺术品。开发人员的想象力不需要浪费在这样的地方。每个人写的代码不仅仅是给自己看的。
  12. 测试先行
    XP原则:对于每一个用户故事,在开始代码之前,现场客户就需要编写验收用例,而开发人员需要先编写单元测试。这样能够保证每一个用户故事是可测的而且是自动化测试。
    我的看法:这是个非常令人憧憬的奋斗目标。但是,理想很美好,现实很残酷。
    作为一个典型的国内软件公司来讲,你所处的项目小组是什么样的人员素质呢?如果项目组有10个人的话,那么其中3 个有经验的开发人员,具有一定的设计能力。3个经验稍差的熟练工,另外大约还会有2个应届的毕业生。2个专职的测试人员,大约1-2年的工作经验。这应该算是平均水平了吧,很多团队连这个水平也达不到。这样一个团队存在什么问题呢?
    开发人员不会做测试,更加不会写测试用例。个别开发人员甚至不太清楚单元测试是程序员的责任之一。测试人员不会写代码,多数都是高校it专业能力不足的毕业生,接收单位经考察认为无法胜任开发工作,所以就去做测试吧。并不夸张,现状就是如此。
    在这样一个团队中强制执行测试先行,简直就是自虐。
    要实现这样的目标需要循序渐进:第一步要求编码人员自己完成单元测试并养成习惯,要求测试人员能够撰写全面的系统测试案例;第二步要求编码人员能够编写单元测试代码,要求测试人员能够运用自动化测试工具进行回归测试;第三步要求编码人员将单元测试编码工作提前到编程之前进行,要求测试人员提前根据需求编写自动化测试脚本。
  13. 重构
    XP的原则:随时对代码进行重构,要进行残忍的重构。
    我的看法:有时候重构是必需的,但是重构不能代替预先设计。
    进行重构时也需要小心,基于两个因素:
    第一,你的项目组成员有没有能力进行正确的重构?中国的开发人员有百分之多少充分理解了设计模式呢?而耐心学习过重构的人会更少一些吧?我看你还是现在项目组内部做一些技术培训再说吧。
    第二,你的老板或客户能否允许你这样做?重构是一件需要消耗成本、不产生利润又需要冒很大风险的活动,至少表面看上去是这样的。去说服你的老板支持你的做法对每个人来讲都是挑战。
    实施重构原则的前提是:必须实施代码集体拥有原则
  14. 每周工作40小时
    XP原则:加班只会造成质量低下,要坚持每周工作40小时。
    我的看法:这个不难,我所管理的项目没有实施XP,也都轻松实现了这个原则。

上面就是我对极限编程的一些看法,极限编程并非一无是处,而是不适合中国国情。而且极限编程的各个实施原则之间是紧密耦合互相补充的,所以很难进行裁剪。

在我看来,极限编程的最大问题就在于“极限”二字。“水满则溢,月盈而亏”是国人都明白的道理,所以对于极限编程而言,我们都需要问一句:“把所有的事情都做到极端就好吗?”

最后,推荐ICONIX过程,一个相对比较中庸的敏捷过程,实施起来也不困难,指导明确,效果明显。