显示标签为“Project Management”的博文。显示所有博文
显示标签为“Project Management”的博文。显示所有博文

2009年4月29日

[zz]项目经理成长日记(3/10): 给自己的定位

你有没有考虑过自己能够管理多大的项目,能够带领多少人员的项目团队?5人?10人?100人?还是千军万马?但是在现实的项目中,能够带领100人员的项目经理未必能够带好10人的团队,反之亦然。因为作为软件项目来说存在有非常大的差异?无论你是大才还是小才,我们首先要清楚的认识到自己的才能是否能符合项目的实际应用,5人的项目和100人的项目团队中项目经理的工作重心必然不同,如果不区别对待,那么你的结局是大才小用,或者是小才大用。

项目的差异性

我没有机会参加类似IBM的OS/360规模的项目,我所能够参与的最大项目规模不过是100人/月上下的项目,当然也做过产品线的长期开发项目。所以对于那种巨无霸形的项目也只能是望梅止渴,对于其中的奥妙也只能捧读《人月神话》这类的经典,希望能够从中吸取精华来强壮自身。

项目的规模不一样,项目所能够配备给定的人员也不一样,对于大型的项目,除了项目经理之外,还会配置项目辅助管理人员和咨询顾问管理人员等。如果说项目超过了10000人/月这个规模,项目往往会采用纵向切割来进行管理,整个项目会像工厂中产品线生产方式:系统需求;系统设计;配置管理;代码开发;系统测试;文档编写;产品构建等过程,整个项目会根据不同的分工被切割成每个小项目团队,虽然每个团队可能的工作都只是针对于局部,在各自的内部这些工作是相对独立的,但是每个项目又都对其他部分有比较严重的依托,比如系统设计是以项目需求为基础,代码开发是以系统设计为前提,所有的工作序列彼此关联,每个工作都可以独立安排二级甚至三级的项目经理,这样整个项目的组织管理模式也就形成了金字塔的模式,从项目经理到最底下的开发人员形成一个自顶向下的体系结构。这个时候对于项目经理的主要工作也就不能要求事必躬亲,小到一个螺丝钉都要亲自过问,对于这种项目经理的要求更多在于总体协调和整体的掌控上面,他就像一个元帅一般的任务,要的是果断的决策,准确的判断,良好的协调和丰富的管理经验。

实际上大部分的项目经理很难有机会成为如此大规模项目的最高决策者,即便有机会参与的时候,更多都是处在二线或者三线的位置,所能够管理的实际人员也大部分在10人或则20人左右。更多项目经理参与的项目都是中小规模的项目,毕竟中小的项目的数量还是非常巨大,所以有很多的项目经理在从事这种的开发工作。对于项目规模在100人/月的项目对于很多公司来说也算是具备有一定规模的项目,这些项目的人员投入一般都会在10人之上,不会有公司对这种项目采用投入一个人做一百个月的方式。对于10人规模的项目管理对于大部分的项目经理来说可以是一个不小的挑战,因为虽然说项目的规模不能与上述所说的超级项目抗衡,但是项目在整体过程中所做的事情和上述相当,系统需求,系统设计,配置管理,代码开发,系统测试,文档编写,产品构建等都不会缺少,但是在人员配备里面可没有二级或则三级的项目经理,甚至很多时候会有人力资源捉襟见肘的情况,在10人的规模里面可是要包含需求做成人员,项目开发人员,测试人员等。在很多的时候一个人需要充当多个角色,可能在某一个阶段你需要做需求,当需求做完了之后,你又需要投入开发,后期的时候可能需要做项目文档和项目部署,甚至用户培训。所以对于我的直观感觉来说,这种项目对于项目经理的能力要求可能更高,如果要做好这种项目的项目经理,首先最好有比较扎实的技术开发能力和工程背景,这样你的项目估算才能做得比较准确,为后续的开发赢得更多的时间;其次好需要又比较良好的业务知识,因为你可能更多需要做一个用户的接口,所有的需要都需要通过你和客户去沟通,以及最终的定案,所以对于业务的熟悉程度也至关重要;再者需要又良好的计划性,因为这种项目的变数比较多,项目不会像又很长的规划周期,所以如果控制好这些可变因素,已经如何协调内部的有限资源,让资源发挥最大的优势可能成为项目经理每日计划中关键的一部分。

还有不少的项目规模在10人/月左右的项目,这种项目对于很多公司来说属于不痛不痒的项目类型,因为同一个时期内公司可能会有多个这种类型的项目同时在进行中,在这种情况下项目所能够获得的资源就更加有限,往往项目的安置人员也就在5人左右,当然和上面两种情况类是,项目过程的事情还是不可省缺,但是由于项目总体的规模偏小,所以项目的复杂度也比较容易控制,但是这种项目对于项目经理的要求更多在于技术上的要求,因为如果这个时候在安排一个缺乏技术经验的人员做项目经理,那么整个项目组的安排出现一个外行领导四个内行的局面,而且四个内行中可能有一半以上是新人或者初级的开发人员,如果再包括测试等一系列的工作,人员分布上就缺乏合理性。所以这个时候的项目经理往往都是技术过硬的人员担任,这样可以化解人员不足的问题,但是也有一个问题,对于技术优秀的人员都会有一个通病,首先看不上别人的工作结果和质量,另外一方面往往会以自己的标准去衡量别人和给人安排工作,这样对于新人或者初级的开发人员来说,他们的工作就会出现不合理的问题。同时在做估算的时候也比较容易出现轻易的问题,以自己的能力估算项目进度,结果造成项目估算不准确,后期严重加班的问题。所以这种类型的项目经理需要又良好的技术背景,还需要学习项目的实际管理和合理的人员安排,以及如何做好与项目内部成员的友好沟通和关系。

最后一种项目类型就是那种一个人吃饱,全家不额的类型,项目规模非常小,不到1人/月,所以在这种项目的投入人数往往只有一个人或则两个人。当然这个时候也不会要求说项目开发的那一系列的工作都做到位,很多时候都是口头相传,这种项目的结果大部分之要求软件代码和程序能够满足要求。所以这个过程中很多人可能认为只要管好自己就可以了,但是我认为,时间虽然短,但是事情还是需要做足,比如说需求的明确文档化,还有与外界的沟通等一些列过程实际上都可以和正常的模式一样,对自己的工作也需要有一个良好的计划,这个时候对于自己的要求就是一个锻炼的机会,为今后做更大的项目准备好时机。所以这种项目经理的要求实际不抵,如何管理好自己可能会是一个比较大的难题。

项目类型的差异性

项目从规模差异上来说是对一个项目经理的开发能力,管理能力等有不同的要求。但是如果说从项目类型的差异的角度来看,就会对项目经理的一些其他能力又要求,如果说你做的是国内的项目,那么你需要有与客户沟通的良好能力,能够有足够的能力应对客户的各种要求,如何应对客户千奇百怪的要求,如何合理的说“NO.”都是你需要具备的能力。如果说是对日,对欧美的外包服务开发,需要有良好的语言沟通能力,比如说日语,英语。还需要了解不同国家的文化差异等等,这个时候你可能需要充当起桥梁的作用,如何与国外的客户进行沟通和交流,包括有工作安排,技术上等一系列问题的沟通工作。

给自己的定位

项目管理本身就是一个比较复杂的过程,不像行军打战那样,有了一盯一眼的制度就可以管理好项目,因为项目的变数太多,情况迥异,也就没有放之四海而皆准的管理方法。所以对于不同类型的项目来说,我们需要了解项目的特点,在我们有良好的基础准备的前提下,根据自己的能力特点,再结合项目的实际情款来不断调整工作中的方法和内容。

虽然我们很难有一个标准化的管理手册来指导每一个希望做项目经理的人,但是我们可以从别人身上去借鉴各种成功或则失败的经验,特别是别人失败的经验,因为别人的成功可能我们很难克隆,但是我们可以避免别人错误再我们身上重演。

不想当将军的士兵不是好士兵,但是不想当项目经理的程序员未必是坏的程序员。毕竟对于技术领域来说,程序员的最终发展方向项目经理未必是一个最优秀的方向,程序员可以走的道路有很多,可以往架构师,分析师,资深技术人员,咨询师等等。路可能有很多条,而且每一条对于人员的能力要求也都不一样,都有良好的发展机会。所以对于自己能力的判断和分析,认清自己,给自己合理的定位是直观重要。让自己的才华得到发展和认可是今后职业道路上一个关键,自己要才尽其用。

作者:Yice(小余)

出处:http://www.yice800.cn

2009年4月27日

[zz]项目经理成长日记(2/10): 你能承受多大责任

自己一个人独自回想工作了这么多年, 到底给自己留下了什么?如果要给自己找一个答案,或许有两个会在今后很长一段时间一直影响自己的东西,一个是在工作了这么多年让自己明白了我们要担负什么 样的责任,另外一件是工作这么多年给自己的颈椎留下了不小的病症。一好一坏或许是这么多年的最大收获。

我们该如何看待责任

时 至今日蒙牛老总牛根生说过的那句话还让我记忆犹新,“有德有才,破格重用;有德无才,培养使用;有才无德,限制录用;无德无才,坚决不用。”在我认为德的 基本就是这个人的责任心和他的态度。无论是软件行业还是其他的行业,在很多的时候考核一个人是否符合相应的工作岗位,职位技能往往不是最主要的考核标准, 而在所有的考核标准中,人的品性和责任态度才是考核的关键。

什么人活得最轻松,不负责人的人。丈夫有责任给妻子一个良好的生活环境;父 亲有责任给孩子一个良好的生长环境;孩子有责任赡养自己的父母;员工有责任做好自己的本职工作;所有的这些都是一些基本的责任。如果一个人富有责任心,生 活中的这些责任会让自己感觉到沉重的压力,一旦人在这些压力的之下,要想过的轻松舒服就很困难。所以如果你希望自己过得轻松写意,你放下一切的责任态度, 做个不负任何责任的人,那么或许你会过得比较轻松,但是你也将成为社会中一个不合格的人。

软件开发本身属于脑力密集型的劳动,所有的一 切都依托于人,软件行业本身和其它的制造行业有一个本质性的差异,软件主要依靠人的智慧来进行工作,虽然我们现在看到很多的软件工程管理书籍,无论是大师 的作品,还是坊间口声相传的经验之谈,我们都很难解决一个问题,我们很难像制造行业一样,让我们每个程序员写出来的代码都能够像机器加工出来的那样,每一 个行代码都能够像一个模子印出来的,很难做到整个团队写出的代码像出至一人之手。所以软件行业的工程管理比其它的工程来说要存在有更大的困难,那么在这些 问题困挠之下,整个行业对人的依赖尤为严重,对人的依赖程度也就造成对人本身品德和责任心的要求程度相对要高。

在自己工作这么多年来, 感觉最轻松的时候还是刚刚毕业的时候,那个时候是初出校门,作为一个新人进入项目组中,对于自己最大的挑战主要是能不能按时准确的完成自己相应的模块开发 工作。后来开始负责项目之后,虽然也在做编码开发工作,但是所担心的和让自己欢欣的事情和开始已经完全不同。如果你希望自己能够能够作为一个合格的项目经 理经理,那么你首先需要明确自己的肩上的担子的分量。在我们的工作中,我们每个人必须承担工作的各种责任,如果我们缺失这种看待责任的态度,那么工作最后 的结果往往将会以失败告终。

对于自己在这几年的最大一个一个收获就是让自己更明确到责任重于泰山的道理。当然也是这种态度让自己能够坚持着把一个一个项目做下去,做好这些项目。如果要对自己做一个评价,或许在技术上我不敢说自己有十足的优势,但是这些年养成的这种做事情的方法和态度还能值得一提。

在项目中你该承担什么责任

如 果你要问项目组中谁的压力最大,一般说来应该是项目经理,当然项目经理所拿的工资相对来说也会比较高,责任和压力本就应该和报酬成正向比例关系。项目经理 对下必须对项目团队成员负责,向上必须对公司负责,同时还需要纵向向客户负责,所以项目经理经理就像一个传动轴承,这个项目的运作应该在他驱使之下有效稳 定的运转。

项目经理需要考虑项目的成本因素,所有的公司都是以盈利为主要目的,有时候公司会出于其他的因素和目的,对于项目的盈利并没 有很严格的要求,但是项目经理要有成本的概念和意识,要有团队的总体成本和利润要有基本的计算方式。同时还需要控制项目的质量和进度,还有些项目还要求有 保密意识和其他的相关要求,这些都是项目经理需要向公司负责的地方。

如何组建好一个团队,如何培养团队的成员,让每个团员很够在一个比 较良好的环境中工作和学习,能够实现每个人的目标和各自的价值观,把团队建设成什么样类型,和项目经理所采取的方法有直接的关系,有些项目团队组建后团队 人员如走马灯似的换,有些团队组建后队员除了编码之后就没有任何的学习机会,如何利用有限的资源和合理的安排,让团队的成员都能够发挥各自的特长,让每个 人都能够体现自己的价值,有时候需要替项目组的成员去和公司去争取他们所应该有的福利和报酬,这就是对项目团队和团队成员所要承担的负责。

我 们每一个项目最终都将面对我们的客户,有时候我们的客户的要求会让我们很难接受,甚至有时候会让我们团队感觉到很恼火,但是作为一个项目经理需要化解这些 对项目团队一个不利的因素,一方面需要避免影响团队的士气,另外一方面需要和客户进行沟通,明确那些要求可行,那些要求不可行,对于不可行的要求需要给一 个比较合理的解释,避免由于后期无法完成对客户造成欺骗的行为。同时需要控制项目的整体进度和质量,保证项目最终能够解决客户的为,这些就是对客户负责的 一个态度。

如何树立团队的责任意识

对于项目组中项目尽力所承担的责任应该说是最大的,无论项目的成败都 和项目经理由直接的关系,所以任何一个项目做项目总结的时候,如果项目成功的话,需要给项目经理记上一功,如果项目失败的话,不论任何原因,棒子首先需要 打在项目经理的身上。项目经理需要对项目的得失成败负上完全的责任。

在一个项目团队中,需要有各个不同的角色相互配合才能最终完成项 目,需求调研人员,系统分析人员,高级程序员,初级程序员,测试人员,配置管理人员等,虽然项目经理在项目中的责任最大,但是项目中每一个成员都会有相应 承担的责任,或许说着这都是一些工作的职责,开发人员需要按照开发中的各种要求进行开发工作,测试人员需要按照测试的要求准备测试文档和数据等,所有的角 色都会有各自的工作内容,在实际工作中我们是每一个角色协作来完成项目,有时候由于项目的规模偏小,有些人可能会同时充当多个角色,比如说高级程序员有时 候需要同时兼顾系统分析人员,项目经理有时候还需要兼顾测试等等。但是不论规模的大小,项目经理需要非常清晰的意思到每个角色的工作职责,在项目分工中对 各种工作要比较清晰,合理化安排。同时也需要让每个工作的人员清楚的知道自己的工作要求和检验的方式,避免含糊性的安排,做到责任清晰。

明 确责任的首要是明确工作内容,对于团队成员中需要做到责任均衡,尽量避免能者多劳的问题,工作中进行工作安排时往往容易把工作重点都落到部分能力较强的人 员上,这种安排比较容易造成工作天平的倾斜,一旦倾斜的严重,这部分开发人员就比较容易造成由于精力不足造成质量问题。所以项目经理在安排工作中需要有个 权衡,如果说存在人员能力不均衡问题,那么在工作安排的时候,需要尽可能抽取重复性的工作,让能力欠缺的人员做这部分工作,同时需要协调他们学习,也需要 明确学习的目标和结果。

对于团队中我们需要树立一个责任意识,同时需要有合作精神,在项目开发中整个团队需要彼此合作,有时候一个人的 问题有时候会影响到整个团队的质量和进度。我们最终给客户交付的是一个完整的程序,其中任何一个部分出了问题,客户对整个产品的评价都会因此而改观,客户 不会说那个模块怎么怎么样,而是说你这个程序怎么怎么样,这就代表说是一个整体的结果,所以项目经理需要在团队中树立起这种整体的责任意识,避免团队中出 现个人自管门前雪,不理他人瓦上霜的现象。

你能承受多大责任

你有没有评价过你的项目经理,你有没有对你 的项目经理感到无奈和气氛,如果你希望自己能够往项目经理方向发展,在我看来你首先需要考虑的不是你的技术背景,你的管理经验是不是足够,首先要考虑的是 你是不是有能够承受那些责任的心态。如果你是项目经理的话,那么你负责管理的团队无论人员多少,他们需要在你的协调下工作,那么你肩上担负的就是那些人的 工作结果和评定,还有来自公司的各种压力和考核。这些比单纯写代码要劳心许多。

影响项目成败的因素有很多,但是如果说项目经理缺少责任心,我可以说项目必败无疑。正是因为这样,我才会在此一再强调责任心的问题。

作者:Yice(小余)

出处:http://www.yice800.cn

2009年4月26日

[zz]项目经理成长日记(1/10): 启言

实在值得收藏,将连续10天每天转载一篇 :)

如果你爱他,那么让他去当项目经理,因为那里会是他事业的天堂;如果你狠他,送他去当项目经理,因为那将是他的地狱。

软件开发工作应该属于分工比较明确的行业,每一个项目的启动,调研,开发,测试,部署,用户培训和后期维护等一系列的过程都有不同的角色参与其中。在这一系列的角色中项目经理是最直接的管理者,无疑显得格外的突出和重要。软件项目开发的成功率本身就不高,在众多的失败过程中,由于项目经理在管理上存在的问题造成项目无法按时交纳,质量不高甚至失败的例子在我看来数不胜数。虽然项目经理的能力并不是项目失败的直接原因,因为影响项目成败的因素有很多,但是如果一个合格的项目经理,对于项目的整个开发过程来说,如何利用他的经验和能力来有效合理的管理项目进度,从而避免很多无谓的失误,在项目的最终成败中还是占有关键作用。

对于很多从事软件开发的人来说,项目经理是他们事业上追求的目标,从初出校园的小牛犊,从最低级的学徒似的初级开发人员,再不断的努力和学习,慢慢得爬到有经验的中级程序员,再后来到高级程序员,到后来的大牛人才,慢慢开始带领新人,开始接触项目管理上的工作。我想很多人的轨迹都是这么一步一步的过来。在整个过程中我们彼此都在学习,关于很多的技术方面的知识可以通过网络和书籍进行学习。但是如何做一名项目经理,如何做好一名项目经理,倒缺乏一个系统的学习框架,包括我自己在内,也是跟随前人身边学习,自己观察,在一次次错误后进行反思后才有所进步。这个话题的文章我考虑了很久后才决定要写出来,在一系列的文章中结合我自己的项目和我自己身边的项目,希望能够将这些经验与大伙分享,通过讨论,彼此共勉。机会往往是给有所准备的人,不论你现在是否是充当项目经理的角色,但是如果你有所准备,我想对于你来说机会只是迟早的事情。

项目从规模来说,可以划分微型项目,小型项目,中型项目和大项目,当然还有超大型的项目,对于工数在一人/月(一个中级程序员开发一个月,总计21个工作日)的项目定为微型项目;对于工数在1人/月到10人/月之间的规模称为小型项目;对于工数在10人/月到100人/月之间的规模称为中型项目;如果超过 100人/月的项目称为大型项目;对于我们所讨论的项目管理中,对于超过1000人/月的项目不做讨论,因为一般的公司来说,还是比较少能够遇到中规模的项目。

如果从类型来说可以简单的划分为产品开发和项目开发,产品的开发一般会有后续定期的产品升级性开发,项目的开发时间跨度也会比较长,对于项目的开发来说,一般是指为了满足某一特定客户而开发的软件,其开发周期往往会比较紧张,后续的开发主要是针对客户的新功能追加,这种项目的开发往往会划分为几个阶段分步进行。

如果从合作方式上也可以划分为自主研发和外包开发,甚至还有部分项目使用外驻人员进行项目开发,有时候开发还受到地域性的影响,两地,三地合作开发,国内国外的合作开发,还有甚至多国之间的合作开发。

不同的项目开发方式都会有不同的问题出现,比如说小型项目和大型项目的人员配备上就不可能一样,外包开发和自主研发的项目计划也不一样,跨地域的合作上的时间差异和人员的沟通和本公司内部背靠背的模式也不一样。项目中实际可能发生的事情千奇百怪,这些问题绝大部分都需要项目经理来过问,分析和决策。所以说项目经理或许对于很多人来说将会是地狱,一旦深陷其中,很难有苦尽甘来的那一天。但是如果方法得当,管理手段有效,能够合理的规避风险呢?那你将会感到项目中的一切对你来说游刃有余,团队中每个人也都能相应发挥自己的特长,也都能从中找到各自的成就感。

生与死只在一线间,好和坏也是如此。希望能够从项目经理的角度来看看项目实际过程中我们会遇到哪些问题,该如何去处理这些问题,通过着一些列的文章能让你对项目的整体过程有更全面的了解,同时也能够让你更清楚项目经理的日常工作和行为职责。

作者:Yice(小余)

出处:http://www.yice800.cn

2008年9月17日

不谈国事

让人心寒的国家大事一件又一件,金钱的魅力看来无比巨大啊。记得《康熙大帝》评书里,纪晓岚多次说过一句“钱真是好东西啊。”那种感慨和如今的世风,哎!

近日负责协助一个项目的管理,在启动阶段困难不少。好在每天看几页偶像陈儒推荐的《项目管理艺术》,总能联想到目前的处境,当然也能借鉴到一些书中推荐的方法。继续细细摸索和体味咯!

2008年3月26日

MoinMoin很好很强大

一直热爱Python的我,前年在选定Wiki系统时,首选了基于Python的MoinMoin,当时只是用来作为我们实验室外部能访问的一个Wiki。当时只是简单的一用,现在连地址都记不得了 :(

昨天在Lee师兄的询问下,我推荐了MoinMoin的Desktop版,经过试用,发现Desktop版在Windows上简直就是超级简单的Wiki系统,使用真是太方便了。但是后来发现这个版本存在一些问题,就又改到原始版本了。

原先Lee师兄问我这个Wiki能不能导出离线文档,方便别人查阅。经过寻找,不看不知道,一看吓了一大跳,看到了Moin网站上提供了大量的插件,几乎涵盖了能想到的各种功能。

刚才在国内Python圈内顶级著名的啄木鸟网站,看到这个网站也是基于Moin搭建的,而且具备了相当完善的功能,对于交流简直就是相当方便了。

在网上又找到了一篇详细介绍Moin的文章,看完顿觉Moin真是Wiki中的极品。现在决定了,以后的工作日志(个人研究以及项目管理)完全采用Moin来操作。期待Moin能像Biblioscape那样对我的科研和生活产生巨大影响。很希望自己也能搭建啄木鸟那样的社区来推广我们学校的机器学习小组,真正让广大朋友们对机器学习的交流成为习惯!

 

转载介绍Moin的文章如下:

Link: http://media.ccidnet.com/art/3023/20070926/1225599_1.html

--------------------------------------------------------------------------------

基于Python的MoinMoin
作者:杨晶

Wiki是一种知识共享工具,我们可利用它与远在大洋彼岸的朋友共同创作一篇文章。Wiki也是一个功能强大的内容管理平台,能帮助企业或个人管理知识。MoinMoin是众多Wiki Engine中的佼佼者,它将我们带入了一个充满新奇的Wiki世界。

自1995年3月25日第一个Wiki网站诞生以来,Wiki系统以其简洁的语法规则,方便的在线编辑和完善的版本管理功能,得到越来越多用户的青睐。已应用到企业内部网站、社区交流和个人知识管理等领域。

Wiki Engine也由最初的几个发展到上百个,使用各种开发语言开发的都有,比较有代表性的有用Python开发的MoinMoin和ZWiki;用Perl开发的TWiki、UseModWiki;用PHP开发的MediaWiki,PhpWiki;用Java开发的JSPWiki。其中MediaWiki就是著名的维基百科网站的支持系统。

MoinMoin是使用Python脚本语言开发的一套具有模块化设计和高灵活性的Wiki系统,以GPL协议发布,源代码开放。著名的Python社区和Debian社区的Wiki系统都是使用MoinMoin来搭建的。

追根溯源话Wiki

该项目最初由德国人发起,Moin是德国方言早上好的意思,MoinMoin的名称是借用了WikiWiki这种Wiki的习俗,使人感到亲切。

MoinMoin最初是在PikiPiki系统的基础上发展起来的。PikiPiki的作者叫MartinPool,由于想比较一下用Python实现的Wiki系统与Java或Perl语言实现的Wiki系统在代码质量和性能上的区别而开发了只有一个文件几百行代码的PikiPiki系统。

PikiPiki系统的代码量小,结构简单,但已具有了Wiki系统的基本功能,如在线编辑和全文搜索等。为Wiki系统的实现提供了一个简单而稳定的框架,其提出的以纯文本方式把数据存放在文件系统中的做法一直沿用到现在的MoinMoin系统。

除MoinMoin外,还有几个Wiki项目也是基于它的代码开发的,如MonkeyWiki和DiamondWiki等。现在,PikiPiki系统已停止开发,最后的版本为2000年发布的1.63版。

MoinMoin使用了Python脚本语言开发,是跨平台的,可运行在Linux/UNIX/BSD、Windows和Mac OSX系统上的Wiki系统。项目始于2000年,2000年7月29日发布了第一个以MoinMoin命名的版——MoinMoin 0.1,这个版本的作者是JurgenHermann,他在PikiPiki 1.62版代码的基础上进行开发。

第一版的MoinMoin的功能和PikiPiki是差不多的,只是修正了一些Bug和增强了显示的效果,没有增加新的功能。2002年5月10日,MoinMoin 1.0正式发布,MoinMoin开始完全转向Python 2.0,不再支持Python 1.5,同时该版本还增加了很多新的功能,如附件、Email通知、变量替换和预览等,这些新功能使得用户能够很容易的进行操作。

至此,MoinMoin已完全摆脱了PikiPiki的影子,自成一派。2004年12月6日,MoinMoin 1.3版发布,这是MoinMoin最重要的一次版本更新,以模块化的思路重新设计了内部代码结构,能在不改变核心代码的基础上很方便地通过宏(Macro)、分析器(Parser)、操作(Action)和主题(Theme)来扩展MoinMoin的功能。

使用UTF—8字符集,并作为MoinMoin系统惟一支持的字符集;可以使用高性能的Twisted服务器作为Web服务器以提升服务器的处理能力;支持ACL(访问控制列表)安全设置,这是MoinMoin Wiki开始支持内容管理系统(CMS)的一个重要改进;支持单实例多服务;支持更好的文本搜索引擎。从MoinMoin 1.3版开始,MoinMoin已完全可胜任企业网站和企业知识管理平台等关键应用领域的需求。

现在最新的MoinMoin发行版是1.5.8,支持GUI在线编辑器功能,MoinMoin 2.0版也已在开发当中。从JurgenHermann启动MoinMoin这个项目开始就吸引了大量优秀的Python程序员,他们为MoinMoin项目贡献了高质量的代码和文档,使MoinMoin不断创新,功能不断完善。MoinMoin社区很活跃,在各种大型的开源盛会上都能看到它的身影,如Google Summer Of Code 2006和EuroPython2006等。

如今,MoinMoin已成为互联网上最流行的Wiki系统之一,在http://www.c2.com/cgi/wiki网站评选的十大Wiki Engine排行中高居第一位,而紧随其后的分别是MediaWiki和PhpWiki。

MoinMoin活跃在各个社区

MoinMoin系统的官方网站既搭建在MoinMoin系统之上。用户可以在网站上找到很多有关MoinMoin的资料,包括MoinMoin的安装步骤、MoinMoin的Wiki语法参考和一些常用问题的FAQ等。这些资料都是世界各地的MoinMoin用户通过Internet贡献的。

在这个网站还能下载各种有用的扩展插件,以扩充MoinMoin的功能,如在线回复、在线投票和日历等。如果需要的功能现在MoinMoin还不具备,还可在网站上的FeatureRequests页面提出具体需求,在下一个版本就很有可能包含所提交的功能需求了,MoinMoin系统中的很多功能都是这样开发出来的。

在访问网站时,用户还可以发现MoinMoin系统的很多系统信息都是中文的,这得益于MoinMoin系统的i18n设计和世界各地使用中文用户的贡献,MoinMoin已被翻译成20多种语言。如果想对MoinMoin的中文化做出贡献,可以登录http://moinmaster.wikiwikiweb.de/ 网站,注册一个用户并加入一个语言组后就可以进行翻译。

MoinMoin开发社区充分利用了Wiki系统方便在线交流的特点,使社区与用户的联系更加紧密,更加有效。不仅仅MoinMoin项目采用这种方式,很多开源项目都是采用这种方式与用户沟通,使用户也渗透到软件开发过程中来,使用户与社区共同发展、成长,最终用户又会反馈社区,促进社区的发展状大。

在国内使用MoinMoin Wiki系统的网站还不多,远没有用MediaWiki的多,这主要跟系统的开发语言的流行程序有关。MediaWiki用PHP+MySQ开发,在国内,PHP脚本语言已成为最主要的Web开发语言,做过Web开发的没几个会不知道PHP和MySQL的。

但LAMP黄金组合中的另外一个P——Python,就不是很多人知道。相信随着MoinMoin、Plone、Zope3这些优秀的的Python应用被越来越多的国内用户所接受,MoinMoin将会成为国内Wiki系统的领导者。

国内知名的Python社区啄木鸟社区的网站就是使用MoinMoin来搭建的,该社区依靠MoinMoin强大的在线协作功能,编写和整理了大量有关Python的资料,具有很强的文档搜索和在线编写的功能,是学习MoinMoin和Python的好地方。

MoinMoin是一个成功的、优秀的开源项目,世界各地的志愿者通过国际互联网联系在一起,创造了MoinMoin Wiki系统,创造了MoinMoin开源社区。不论水平高低,贡献大小,只要有时间,有贡献的精神,都可为这个社区出一分力。作为回报,用户也将会得到更强大、更可靠、更安全的系统。

链 接

Wiki拟推新搜索挑战Google

维基百科(Wikipedia)创始人Jimmy Wales表示,他正着手筹备一个由社区协力发展的网络搜索服务,与Google或雅虎等现有的搜索引擎竞争。

开放式搜索有助于Wiki迈向更宏大的目标:促进免费内容在全球信息网上的散布。Wales的目标是促使网络搜寻系统,将其中涉及的编辑判断公开透明化。Google等专属搜索公司一向把自家搜寻系统运作的技术细节视为机密,Google宣称这是为了防止垃圾讯息泛滥,而另一方面也是基于竞争考虑。

2008年3月12日

zz 注重实效的程序员(The Pragmatic Programmer)

link: http://dev.csdn.net/article/65/65511.shtm

注重实效的程序员(The Pragmatic Programmer)
推荐一本好书 《The Pragmatic Programmer - From journeyman to master》

1、关心你的技艺
Care About Your Craft
除非你在乎能否漂亮地开发出软件,否则其它事情都是没有意义的。

2、思考!你的工作
Think!About Your Work
在你做某件事情的时候思考你在做什么。不间断地思考,实时地批判你的工作。这将占据你的一些宝贵时间,酬劳则是更为活跃地参与你喜爱的工作、感觉到自己在掌握范围日增的各种主题以及因感受到持续的进步而欢愉。从长远来说,你在时间上的投入将会随着你和你的团队变得更为高效、编写出更易于维护的代码以及开会时间的减少而得到回报。

3、提供各种选择,不要找蹩脚的借口
Provide Options,Don't Make Lame Excuses
不要说事情做不到;要说明能够做什么来挽回局面。不要害怕提出要求,也不要害怕承认你需要帮助。

4、不要容忍破窗户
Don't Live With Broken Windows
不要留着“破窗户”(低劣的设计、错误的决策、或者糟糕的代码)不修。发现一个就修一个。如果没有足够的时间进行适当的修理,采取某种行动防止进一步的破坏,并说明情势处在你的控制之下。
如果你发现你所在团队和项目的代码十分漂亮——编写整洁、设计良好,并且很优雅,你不会想成为第一个弄脏东西的人。

5、做变化的催化剂
Be a Catalyst for Change
你不能强迫人们改变。相反,要向他们展示未来可能会怎样,并帮助他们参与对未来的创造。
设计出你可以合理要求的东西,好好开发它。一旦完成,就拿给大家看,让他们大吃一惊。然后说:“要是我们增加...可能就会更好。”假装那并不重要。坐回椅子上,等着他们开始要你增加你本来就想要的功能。人们发现,参与正在发生的成功要更容易。让他们瞥见未来,你就能让他们聚集在你周围。

6、记住大图景
Remember the Big Picture
如果你抓一只青蛙放进沸水里,它会一下子跳出来。但是,如果你把青蛙放进冷水里,然后慢慢加热,青蛙不会注意到温度的缓慢变化,会呆在锅里,直到被煮熟。
不要像青蛙一样。留心大图景。要持续不断地观察周围发生的事情,而不只是你自己在做的事情。

7、使质量成为需求问题
Make Quality a Requirements Issue
你所制作的系统的范围和质量应该作为系统需求的一部分规定下来。让你的用户参与权衡,知道何时止步,提供足够好的软件。

8、定期为你的知识资产投资
Invest Regularly in Your Knowledge Portfolio

让学习成为习惯。
持续投入十分重要。一旦你熟悉了某种新语言或新技术,继续前进,学习另一种。
是否在某个项目中使用这些技术,或者是否把它们放入你的简历,这并不重要。学习的过程将扩展你的思维,使你向着新的可能性和新的做事方式拓展。思维的“异花授粉”十分重要;设法把你学到的东西应用到你当前的项目中。即使你的项目没有使用该技术,你或许也能借鉴一些想法。例如,熟悉了面向对象,你就会用不同的方式编写纯C程序。
如果你自己找不到答案,就去找出能找到答案的人。不要把问题搁在那里。

9、批判地分析你读到的和听到的
Critically Analyze What You Read and Hear
不要被供应商、媒体炒作、或教条左右。要依照你自己的看法和你的项目的情况去对信息进行分析。

10、你说什么和你怎么说同样重要
It's Both What You Say and the Way You Say It

作为开发者,我们必须在许多层面上进行交流。我们的时间有很大部分都花在交流上,所以我们需要把它做好。
如果你不能有效地向他人传达你的了不起的想法,这些想法就毫无用处。
知道你想要说什么;了解你的听众;选择时机;选择风格;让文档美观;让听众参与;做倾听者;回复他人。
交流越有效,你就越有影响力。

11、DRY原则——不要重复你自己
DRY - Don't Repeat Yourself
系统中的每一项知识都必须具有单一、无歧义、权威的表示。与此不同的做法是在两个或更多地方表达同一事物。如果你改变其中一处,你必须记得改变其它各处。这不是你能否记住的问题,而是你何时忘记的问题。

12、让复用变得容易
Make it Easy to Reuse
你要做的是营造一种环境,在其中要找到并复用已有的东西,比自己编写更容易。如果复用很容易,人们就会去复用。而如果不复用,你们就会有重复知识的风险。

13、消除无关事物之间的影响
Eliminate Effects Between Unrelated Things
我们想要设计自足(self-contained)的组件:独立,具有单一、良好定义的目的。如果组件是相互隔离的,你就知道你能够改变其中一个,而不用担心其余组件。只要你不改变组件的外部接口,你就可以放心:你不会造成波及整个系统的问题。
你得到两个主要好处:提高生产率与降低风险。

14、不存在最终决策
There Are No Final Decisions
没有什么永远不变——而如果你严重依赖某一事实,你几乎可以确定它将会变化。与我们开发软件的速度相比,需求、用以及硬件变得更快。通过DRY原则、解耦以及元数据的使用,我们不必做出许多关键的、不可逆转的决策。有许多人会设法保持代码的灵活性,而你还需要考虑维持架、部署及供应商集成等领域的灵活性。

15、用曳光弹找到目标
Use Tracer Bullets to Find the Target
曳光弹能通过试验各种事物并检查它们离目标有多远来让你追踪目标。
曳光弹代码含有任何一段产品代码都拥有的完整的错误检查、结构、文档、以及自查。它只不过功能不全而已。但是,一旦你在系统的各组件之间实现了端到端(end-to-end)的连接,你就可以检查你离目标还有多远,并在必要的情况下进行调整。一旦你完全瞄准,增加功能将是一件容易的事情。

16、为了学习而制作原型
Prototype to Learn
任何带有风险的事物。以前没有试过的事物,或是对于最终系统极其关键的事物。任何未被证明的、试验性的、或有疑问的事物。任何让你觉得不舒服的东西。都可以通过制作原型来研究。比如:架构;已有系统中的新功能;外部数据的结构或内容;第三方工具或组件;性能问题;用户界面设计等等。
原型制作是一种学习经验,其价值并不在于所产生的代码,而在于所学到的经验教训。

17、靠近问题领域编程
Program Close to The Problem domain
计算机语言会影响你思考问题的方式,以及你看待交流的方式。用你的用户的语言进行设计和编码。

18、估算,以避免发生意外
Estimate to Avoid Surprises
在着手之前先进行估算。你将提前发现潜在的问题。
1)要选择能反映你想要传达的精确度的单位;
2)基本的估算诀窍:去问已经做过这件事情的人;
3)理解提问内容;
4)根据对问题的理解,建立粗略、就绪的思维模型骨架;
5)把模型分解为组件,找出描述这些组件怎样交互的数学规则,确定每个组件的参数;
6)给每个参数指定值,找出哪些参数对结果的影响最大,并致力于让它们大致正确;
7)进行多次计算,改变关键参数的值,然后根据那些参数表达你的答案;
8)在被要求进行估算时说的话:“我等会回答你”。

19、通过代码对进度表进行迭代
Iterate the Schedule with the Code
实行增量开发。追踪你的估算能力,提炼对迭代次数、以及在每次迭代中可以包含的内容的猜想。提炼会变得一次比一次好,对进度表的信心也将随之增长。你将给予管理部门你所能给予的最精确的进度估算。

20、用纯文本保存知识
Keep Knowledge in Plain Text

保证不过时;
杠杆作用:每一样工具,都能够在纯文本上进行操作;
更易于测试;
你需要确保所有各方能够使用公共标准进行通信。纯文本就是那个标准。

21、利用命令shell的力量
Use the Power of Command Shells
GUI环境通常受限于它们的设计者想要提供的能力。当你想要快速地组合一些命令,以完成一次查询或某种其他的任务时,命令行要更为适宜。多使用你的命令shell,你会惊讶它能使你的生产率得到怎样的提高。

22、用好一种编辑器
Use a Single Editor Well
选一种编辑器,彻底了解它,并将其用于所有的编辑任务。如果你用一种编辑器进行所有的文本编辑活动,你就不必停下来思考怎样完成文本操纵:必需的键击将成为本能反应。编辑器将成为你双手的延伸;键会在滑过文本和思想时歌唱起来。这就是我们的目标。

23、总是使用源码控制
Always Use Source Code Control

总是。即使你的团队只有你一个人,你的项目只有一周时间;确保每样东西都处在源码控制之下。
源码控制是你的工作的时间机器——你能够回到过去。
把整个项目置于源码控制系统的保护之下具有一项很大的、隐蔽的好处:你可以进行自动的和可重复的产品构建。

24、要修正问题,而不是发出指责
Fix the Problem,Not the Blame
要接受事实:调试就是解决问题,要据此发起进攻。Bug是你的过错还是别人的过错,并不是真的很有关系。它仍然是你的问题。

25、不要恐慌
Don't Panic
做一次深呼吸,思考什么可能是bug的原因。

要总是设法找出问题的根源,而不只是问题的特定表现;
搜集所有的相关数据;
开始修正bug的最佳途径是让其可再现;
使你的数据可视化;
跟踪:观察程序或数据结构虽时间变化的状态;
找到问题的原因的一种非常简单、却又特别有用的技术是向别人解释它。你只是一步步解释代码要做什么,常常就能让问题从屏幕上跳出来,宣布自己的存在。

26、“Select”没有问题
"Select" Isn't Broken
Bug有可能存在于OS、编译器、或是第三方产品中——但这不应该是你的第一想法。有大得多的可能性的是,bug存在于正在开发的应用代码中。与假定库本身出了问题相比,假定应用代码对库的调用不正确通常更有好处。即使问题确实应归于第三方,在提交bug报告之前,你也必须先消除你的代码中的bug。

27、不要假定,要证明
Don't Assume it - Prove It
不要因为你“知道”它能工作而轻易放过与bug有牵连的例程或代码。证明它。在实际环境中——使用真正的数据和边界条件——证明你的假定。

28、学习一种文本操作语言
Learn a Text Manipulation Language
你用每天的很大一部分时间处理文本,为什么不让计算机替你完成部分工作呢?
应用示例:

数据库schema维护;
Java、C#属性(Property)访问;
测试数据生成。

29、编写能编写代码的代码
Write Code That Writes Code
代码生成器能提高你的生产率,并有助于避免重复。

30、你不可能写出完美的软件
You Can't Write Perfect Software
这刺痛了你?不应该。把它视为生活的公理,接受它,拥抱它,庆祝它。因为完美的软件不存在。在计算机简短的历史中,没有一个人曾经写出过一个完美的软件。你也不大可能成为第一个。除非你把这作为事实接受下来,否则你最终会把时间和精力浪费在追逐不可能实现的梦想上。

31、通过合约进行设计
Design with Contracts
什么是正确的程序?不多不少,做它声明要做的事情的程序。用文档记载这样的声明,并进行校验,是按合约设计(简称DBC)的核心所在。
这里,强调的重点是在“懒惰”的代码上:对在开始之前接受的东西要严格,而允诺返回的东西要尽可能少。
使用DBC的最大好处也许是它迫使需求与保证的问题走到前台来。在设计时简单地列举输入域的范围是什么、边界条件是什么、例程允诺交付什么——或者,更重要的,它不允诺交付什么——是向着编写更好的软件的一次飞跃。不对这些事项作出陈述,你就回到了靠巧合编程,那是许多项目开始、结束、失败的地方。

32、早崩溃
Crash Early
死程序不说谎。
当你的代码发现,某件被认为不可能发生的事情已经发生时,你的程序就不再有存活能力。从此时开始,它所做的任何事情都会变得可疑,所以要尽快终止它。死程序带来的危害通常比有问题的程序要小得多。

33、如果它不可能发生,用断言确保它不会发生
If It Can't Happen,Use Assertions to Ensure That It Won't
断言验证你的各种假定。在一个不确定的世界里,用断言保护你的代码。
不要用断言代替真正的错误处理。断言检查的是决不应该发生的事情。

34、将异常用于异常的问题
Use Exceptions for Exceptional Problems
异常表示即使的、非局部的控制转移——这是一种级联的(cascading)goto。异常应保留给意外事件。那些把异常用作其正常处理的一部分的程序,将遭受所有可读性和可维护性问题的折磨。这些程序破坏了封装:通过异常处理,例程和它们的调用者被更紧密地耦合在一起。

35、要有始有终
Finish What You Start
只要可能,分配某资源的例程或对象也应该负责解除其分配。

36、使模块之间的耦合减至最少
Minimize Coupling Between Modules

编写“羞怯”的代码;
函数的得墨忒耳(Demeter)法则规定,某个对象的任何方法都应该只调用属于以下情形的方法:
1)它自身;
2)传入该方法的任何参数;
3)它创建的任何对象;
4)任何直接持有的组件对象。
物理解耦。

37、要配置,不要集成
Configure,Don't Integrate
细节会弄乱我们整洁的代码——特别是如果它们经常变化。把它们赶出代码。当我们在于它作斗争时,我们可以让我们的代码变得高度可配置和“软和”——也就是,容易适应变化。
要用元数据(metadata)描述应用的配置选项:调谐参数、用户偏好(user preference)、安装目录,等等。

38、将抽象放进代码,细节放进元数据
Put Abstractions in Code,Details in Metadata
但我们不只是想把元数据用于简单的偏好。我们想要尽可能多地通过元数据配置和驱动应用。我们的目标是以声明方式思考(规定要做什么,而不是怎么做),并创建高度灵活和可适应的应用。我们通过采用一条一般准则来做到这一点:为一般情况编写程序,把具体情况放在别处——在编译的代码库之外。
也许你在编写一个具有可怕的工作流需求的系统。动作会根据复杂的(和变化的)商业规则启动和停止。考虑在某种基于规则的系统(即专家系统)中对它们进行编码,并嵌入到你的应用中。这样,你将通过编写规则、而不是修改代码来配置它。

39、分析工作流,以改善并发性
Analyze Workflow to Improve Concurrency
时间是软件架构的一个常常被忽视的方面。时间有两个方面对我们很重要:并发(事情在同一时间发生)和次序(事情在时间中的相对位置)。
我们在编写程序时,通常并没有把这两个方面放在心上。当人们最初坐下来开始设计架构,或是编写代码时,事情往往是线性的。那是大多数人的思考方式——总是先做这个,然后再做那个。但这样思考会带来时间耦合:方法A必须总是在方法B之前调用;同时只能运行一个报告;在接收到按钮点击之前,你必须等待屏幕重画。“嘀”必须在“嗒”之前发生。
这样的方法不那么灵活,也不那么符合实际。
我们需要容许并发,并考虑解除任何时间或者次序上的依赖。

40、用服务进行设计
Design Using Services
实际上我们创建的并不是组件,而是服务——位于定义良好的、一致的接口之后的独立、并发的对象。
通过把你的系统架构成多个独立的服务,你可以让配置成为动态的。

41、总是为并发进行设计
Always Design for Concurrency
首先,必须对任何全局或静态变量加以保护,使其免于并发访问,现在也许是问问你自己、你最初为何需要全局变量的好时候。此外,不管调用的次序是什么,你都需要确保你给出的是一致的状态信息。
在被调用时,对象必须总是处在有效的状态中,而且它们可能会在最尴尬的时候被调用。你必须确保,在任何可能被调用的时刻,对象都处在有效的状态中。这一问题常常出现在构造器与初始化例程分开定义的类中(构造器没有使对象进入已初始化状态)。
一旦你设计了具有并发要素的架构,你可以灵活地处理应用的部署方式:单机、客户-服务器、或是n层。

42、使视图与模型分离
Separate Views from Models
也就是常说的MVC模式(Model-View-Controller)。

模型。表示目标对象的抽象数据模型。模型对任何视图或控制器都没有直接的了解。
视图。解释模型的方式。它订阅模型中的变化和来自控制器的逻辑事件。
控制器。控制视图、并向模型提供新数据的途径。
通过松解模型与视图/控制器之间的耦合,你用低廉的代价为自己换来了许多灵活性。

43、用黑板协调工作流
Use Blackboards to Coordinate Workflow
用黑板协调完全不同的事实和因素,同时又使各参与方保持独立和隔离。
现代的分布式类黑板(blackboard-like)系统,比如JavaSpaces和T Spaces。

44、不要靠巧合编程
Don't Program by Coincidence

总是意识到你在做什么。
不要盲目地编程。试图构建你不完全理解的应用,或是使用你不熟悉的技术,就是希望自己被巧合误导。
按照计划行事。
依靠可靠的事物。如果你无法说出各种特定情形的区别,就假定是最坏的。
为你的假定建立文档。“按合约编程”有助于澄清你头脑中的假定,并且有助于把它们传达给别人。
不要只是测试你的代码,还要测试你的假定。
为你的工作划分优先级。
不要做历史的努力。不要让已有的代码支配将来的代码。
所以下次有什么东西看起来能工作,而你却不知道为什么,要确定它不是巧合。

45、估算你的算法的阶
Estimate the Order of Your Algorithms
在你编写代码之前,先大致估算事情需要多长时间。

46、测试你的估算
Test Your Estimates
对算法的数学分析并不会告诉你每一件事情。在你的代码的目标环境中测定它的速度。

47、早重构,常重构
Refactor Early,Refactor Often
在需要时对代码进行重写、重做和重新架构。要铲除问题的根源。不要容忍破窗户。
关于重构,详见Martin Fowler的《重构》一书。

48、为测试而设计
Design to Test
在你还没有编写代码时就开始思考测试问题。测试驱动开发?

49、测试你的软件,否则你的用户就得测试
Test Your Software,or Your Users Will
测试是技术,但更是文化。一点预先的准备可以大大降低维护费用、减少客户服务电话。

50、不要使用你不理解的向导代码
Don't Use Wizard Code You Don't Understand
向导很了不起。只需要点击一个按钮,回答一些简单的问题,向导就会自动为你生成骨架代码(skeleton code)。但如果你使用向导,却不理解它制作出的所有代码,你就无法控制你自己的应用。你没有能力维护它,而且在调试时会遇到很大的困难。

51、不要搜集需求——挖掘它们
Don't Gather Requirements - Dig for Them
需求很少存在于表面上。它们深深地埋藏在层层假定、误解和政治手段的下面。

52、与用户一同工作,以像用户一样思考
Work with a User to Think Like a User
要了解系统实际上将如何被使用,这是最好的方法。开采需求的过程也是开始与用户群建立和谐的关系、了解他们对你正在构建的系统的期许和希望的时候。

53、抽象比细节活得更长久
Abstractions Live Longer than Details
“投资”于抽象,而不是实现。抽象能在来自不同的实现和新技术的变化的“攻击”之下存活下去。

54、使用项目词汇表
Use a Project Glossary
如果用户和开发者用不同的名称指称同一事物,或是更糟,用同一名称指称不同事物,这样的项目很难取得成功。

55、不要在盒子外面思考——要找到盒子
Don't Think Outside the Box - Find the Box
在遇到不可能解决的问题时,问问自己以下问题:

有更容易的方法吗?
你是在设法解决真正的问题,还是被外围的技术问题转移了注意力?
这件事情为什么是一个问题?
是什么使它如此难以解决?
它必须以这种方式完成吗?
它真的必须完成吗?
很多时候,当你设法回答这些问题时,你会有让自己吃惊的发现。很多时候,对需求的重新诠释能让整个问题全部消失。
你所需要的只是真正的约束、令人误解的约束、还有区分它们的智慧。

56、倾听反复出现的疑虑——等你准备好再开始
Listen to Nagging Doubts - Start When You're Ready
你的一生都在积累经验与智慧。当你面对一件任务时,如果你反复感觉到疑虑,或是体验到某种勉强,要注意它。你可能无法准确地指出问题所在,但给它时间,你的疑虑很可能就会结晶成某种更坚实的东西,某种你可以处理的东西。软件开发仍然不是科学。让你的直觉为你的表演做出贡献。

57、对有些事情“做”胜于“描述”
Some Things Are Better Done Than Described
你应该倾向于把需求搜集、设计、以及实现视为同一个过程——交付高质量的系统——的不同方面。不要掉进规范的螺旋,在某个时刻,你需要开始编码。

58、不要做形式方法的奴隶
Don't Be a Slave to Formal Methods
如果你没有把某项技术放进你的开发实践和能力的语境中,不要盲目地采用它。

59、昂贵的工具不一定能制作出更好的设计
Expensive Tools Do Not Produce Better Designs
小心供应商的炒作、行业教条、以及价格标签的诱惑。在考察工具的产出时,试着不要考虑它值多少钱。

60、围绕功能、而不是工作职务进行组织
Organize Around Functionality,Not Job Functions
把你的人划分成小团队,分别负责最终系统的特定方面的功能。让团队按照个人的能力,在内部自行进行组织。
但是,只有在项目拥有负责的开发者、以及强有力的项目管理时,这种途径才有效。创立一组自行其是的团队并放任自流,是一种灾难性的处方。
要记住,团队是由个体组成的。让每个成员都能以他们自己的方式闪亮。

61、不要使用手工流程
Don't Use Manual Procedures
shell脚本或批处理文件会一次次地以同一顺序执行同样的指令。我们可以自动安排备份、夜间构建、网站维护、以及其他任何可以无人照管地完成的事情。让计算机去做重复、庸常的事情——它会做得比我们更好。我们有更重要、更困难的事情要做。

62、早测试,常测试,自动测试。
Test Early.Test Often.Test Automatically.
与呆在书架上的测试计划相比,每次构建时运行的测试要有效得多。

63、要等到通过全部测试,编码才算完成
Coding Ain't Done 'Til All the Tests Run
就是这样。

64、通过“蓄意破坏”测试你的测试
Use Saboteurs to Test Your Testing
在单独的软件副本上故意引人bug,以检验测试能够抓住它们。

65、测试状态覆盖,而不是代码覆盖
Test State Coverage,Not Code Coverage
确定并测试重要的程序状态。只是测试代码行是不够的。即时具有良好的代码覆盖,你用于测试的数据仍然会有巨大的影响,而且,更为重要的是,你遍历代码的次序的影响可能是最大的。

66、一个bug只抓一次
Find Bugs Once
一旦测试员找到一个bug,这应该是测试员最后一次找到它。此后自动测试应该对其进行检查。

67、把英语当作又一种编程语言
Treat English as Just Another Programming Language
像你编写代码一样编写文档:遵守DRY原则、使用元数据、MVC、自动生成,等等。

68、把文档建在里面,不要拴在外面
Build Documentation In,Don't Bolt It On
与代码分离的文档不太可能被修正和更新。使用像JavaDoc和NDoc这样的工具,我们可以根据源码生成API级的文档。
文档和代码是同一底层模型的不同视图,但视图是唯一应该不同的东西。

69、温和地超出用户的期望
Gently Exceed Your Users' Expectations
要设法让你的用户惊讶。请注意,不是惊吓他们,而是要让他们高兴。要理解用户的期望,然后给他们的东西要多那么一点。给系统增加某种面向用户的特性所需的一点额外努力将一次又一次在商誉上带来回报。

70、在你的作品上签名
Sign Your Work
我们想要看到对所有权的自豪。“这是我编写的,我对自己的工作负责。”你的签名应该被视为质量的保证。当人们在一段代码上看到你的名字时,应该期望它是可靠的、用心编写的、测试过的和有文档的,一个真正的专业作品,由真正的专业人员编写。
一个注重实效的程序员。

2008年2月19日

学习单元测试

说到单元测试,我想很多朋友都听说过或者学过一点,但是真正贯彻执行的少之又少。我也是这样的 :)

为什么需要再学习一下单元测试呢?因为我现在正在进行的项目中遇到了很多的Bug,当然称之为Bug也不完全对,因为在最初编程的时候没有考虑到会出现这些情况。我想通过一种方法来加速我完成项目的时间以及提高完成代码的质量。

忽然在Yiyan上看到这样一篇文章《实践的一小步-代码质量的一大步》,其中提到了提高代码质量的三招实践攻略:单元测试,代码覆盖,持续整合。读罢顿觉不错,好的项目都是需要这个东西的。其实再仔细想想我们经常提到的发表论文前的相关实验,我敢保证,很少有人说他的实验部分的代码是100%没有Bug的。很多时候,实验结果都是会受到代码质量的影响的。

为了弥补自己软件开发方面的不足,我打算从单元测试开始学习。争取以后都能在写代码前写好测试用例。

在Google上随便转了一下,发现这篇文章《单元测试》写得很好。在提到测试用例和实际开发的顺序时,作者的态度是“在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适”。他的结论是“先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。”感觉这个经验相当不错,之所以很多人不愿意写测试用例,我想也是和没有找到这样的经验有关。

对于单元测试,一些流行的误解如下:

  • 它浪费了太多的时间
  • 它仅仅是证明这些代码做了什么
  • 我是个很棒的程序员, 我是不是可以不进行单元测试?
  • 不管怎样, 集成测试将会抓住所有的Bug
  • 它的成本效率不高

这里就不一一解答这些误解了,感兴趣的朋友可以看看《单元测试》中的解释。

单元测试的优点有:

  • 它是一种验证行为

程序中的每一项功能都是测试来验证它的正确性。它为以后的开发提供支缓。就算是开发后期,我们也可以轻松的增加功能或更改程序结构,而不用担心这个过程中会破坏重要的东西。而且它为代码的重构提供了保障。这样,我们就可以更自由的对程序进行改进。

  • 它是一种设计行为

编写单元测试将使我们从调用者观察、思考。特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。

  • 它是一种编写文档的行为

单元测试是一种无价的文档,它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,并且它保持最新,永远与代码同步。

  • 它具有回归性

自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地的快速运行测试。

单元测试主要包括黑盒测试以及白盒测试,黑盒测试主要是在函数功能上进行测试,不会深入到函数内部;白盒测试是对函数的逻辑进行测试,需要深入到函数的内部,需要覆盖的逻辑单位主要有:语句、分支、条件、条件值、条件值组合,路径。语句覆盖就是覆盖所有的语句,其他类推。另外还有一种判定条件覆盖,其实是分支覆盖与条件覆盖的组合。跟条件有关的覆盖就有三种,解释一下:条件覆盖是指覆盖所有的条件表达式,即所有的条件表达式都至少计算一次,不考虑计算结果;条件值覆盖是指覆盖条件的所有可能取值,即每个条件的取真值和取假值都要至少计算一次;条件值组合覆盖是指覆盖所有条件取值的所有可能组合。作者做过一些粗浅的研究,发现与条件直接有关的错误主要是逻辑操作符错误,例如:||写成&&,漏了写!什么的,采用分支覆盖与条件覆盖的组合,基本上可以发现这些错误,另一方面,条件值覆盖与条件值组合覆盖往往需要大量的测试用例,因此,在作者看来,条件值覆盖和条件值组合覆盖的效费比偏低。

作者认为效费比较高且完整性也足够的测试要求是这样的:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖。这种测试要求其实是比较高的,但是借助于一些相关的工具还是能方便的完成的。

 

工具篇:

        单元测试最著名的工具我想就是Unit系列吧,C++的CppUnit,Java的JUnit,Python的PyUnit等等,还有一些其他工具吧。由于目前我主要采用Java进行编程,搜罗一下Java的单元测试工具(Eclipse下使用的):JUnit4, TestNG。阅读了一篇关于这两个重量级工具的对比文章(《追求代码质量: JUnit 4 与 TestNG 的对比》)后,我决定使用TestNG来作为我的单元测试工具。

 

经过三个小时的尝试后,不得不放弃TestNG,原因是它不支持Eclipse 3.3,感觉好像支持jdk1.6也不太好,似乎TestNG跟不上时代啊!再一眼,发现Junit到是默认出现在了Eclipse 3.3里面,那就试试Junit4咯。呵呵,只要能提高效率就要,为什么一定要用TestNG呢 :)

 

学习几个相关的JUnit教程,感觉这个系列最好:

  1. 在Eclipse中使用JUnit4进行单元测试(初级篇)
  2. 在Eclipse中使用JUnit4进行单元测试(中级篇)
  3. 在Eclipse中使用JUnit4进行单元测试(高级篇)

学完后有这几个心得:

1. Eclipse下创建单元测试非常方便,很多时候只需要点击鼠标即可完成绝大多数的工作,而且可以通过创建很多的单元测试后用打包的方式全部执行。

2. JUnit4比JUnit3多出了许多TestNG具有的特性

3. JUnit4主要有如下几点:

  1. 包含必要地Package
  2. 测试类的声明
  3. 测试方法的声明,以@开头,例如@Before、@Test、@After
  4. 忽略测试某些尚未完成的方法@Ignore
  5. 限时测试,防止死循环,用timeout如@Test(timeout = 1000)
  6. 测试异常,用expected 如 @Test(expected = ArithmeticException.class)
  7. 选择运行器@RunWith(...)
  8. 参数化测试,用于实例数较多的测试,用@RunWith(Parameterized.class)配合Collection的asList
  9. 打包测试,import org.junit.runners.Suite; @RunWith(Suite.class)

4.JUnit4的功能非常强大,自己以后的编程习惯应该是先写整个程序的类及函数框架,然后生成大量的对各个相关函数的单元测试,并且写好打包测试,然后每次实现一个函数就运行一次打包测试,从而逐渐消除所有的Failure和Error,其间如果需要对类及函数框架做出增删改,都必须立即更新单元测试的结构和代码,直到完成

5. 对于具有单元测试的项目,代码的组织可以是在当前文件夹下新建两个文件夹java及test,分别存放正式的代码文件和测试文件,这样有利于最终的文件提取。

 

哈哈,一口气写了这么多,就这样吧!算是自己对单元测试的一次较为深入的学习。

2008年2月16日

zz 开源,选择Google Code还是Sourceforge?

 

这两日认真学习了一下Subversion的使用方法,现在使用Eclipse+Subclipse以及TortoiseSVN,感觉确实像是搭上了一趟时间列车,非常不错的说。顺带了解了一下Sourceforge和Google Code的对比。感觉项目管理还真是一个复杂的事情,Sourceforge的模式非常不错。

link: http://blog.csdn.net/xushiweizh/archive/2006/12/28/1466334.aspx

许式伟
2006-12-28

概要

提起Google Code,我需要很惭愧地承认一点,我一开始的时候“把它看扁了”。初接触Google Code的时候,我简单地认为,Google Code只是一个半成品,从各方面的功能来讲,似乎远不能够与Sourceforge的完备相比。但是,随着对Google Code了解的深入,我不能不承认我错了,Google Code再一次证明“简单是美”的法则:Google的服务似乎永远是看似简单(甚至让你觉得不够用),而实则非常完备。

如果你有开源的计划,或者已经开源,或者你有私人的项目希望有个完备的平台去管理它,那么本文值得你一读,因为这是我在这方面的一些心得。到目前为止,我开源了WINXDocX已经4个月多了,和Google Code、Sourceforge均有了较长时间的接触,希望借机会和大家交流下。

选择Google Code,还是Sourceforge?总体来讲,两者各有各的优势。从进入的门槛来讲,使用Google Code会比Sourceforge容易很多。

Google Code的优势与劣势

Google Code的优势

  • 速度第一。Google的服务以快速著称,Google Code亦不例外。当你上传新的Release时,你会特别感受到这一点。
  • 操作简洁。如果Sourceforge和Google Code提供了同样的功能,那么我可以毫不思索的讲,Google Code比Sourceforge快捷易用。我们后文将详细比较各个功能。

Google Code的劣势

  • 容易被盾。以我的经验,Google Code被盾比较频繁。这导致我有时无法浏览Bug列表,发布新的Release等等。所幸的是,Google Code的SVN连接从来没有出现访问障碍。因此这不算太大的问题。另外,按Google Code的说法,有些功能可以在命令行进行,而不需要到Web上,但是我本人尚未进行详细的验证。
  • 100M的容量限制。Google Code限制每个项目的SVN空间大小不能超过100M,发布的所有Release亦不能超过100M。由于目前我的项目刚刚开始,这一点还不是一个障碍。但是这是一个比较容易到达的数字。可以预见,你的项目要面临搬家的风险。我试图寻找办法来清除一部分SVN历史版本数据、删除一些历史Release 版本,未果。
  • 无数据统计功能。你无法得知你的Release被下载的情况(下载总数以及趋势)。

Sourceforge的优势与劣势

Sourceforge的优势

  • 更多的受众,已经形成第一开源社区。简单统计结果表明,Sourceforge上大约每5分钟就有一个新的Release。也就是说,一天大约有300个新的发布(这不是精确的统计,只是简单估算)。
  • 功能更加完备。目前来看,Google Code在功能上并不比Sourceforge成熟。如果Google Code是一个完整、快捷、功能足够的平台,那么Sourceforge则是一个方方面面均已经相当完备的开发平台。

Sourceforge的劣势

  • 操作繁复,速度较慢。

详细功能对比

下面我们展开来对比一下两者的功能:

  • 建立帐号。Google Code只要你有Gmail帐号即可。Sourceforge要求你进行注册。而且你发现,Sourceforge的注册流程十分罗嗦。
  • 建立项目。Google Code只要你简单填写一下项目的相关信息(http://code.google.com/hosting/createProject),仅一个页面即可完成申请。而Sourceforge的新Project申请流程是繁复的,有很多的下一步,并需要你阅读一些英文细节。另外,你的项目并不马上生效,而是需要进过审批。不出意外的话,在申请之后的第二天再上Sourceforge,你的项目应该通过审批了。
  • 代码管理。Google Code仅支持SVN库,Sourceforge支持SVN和CVS。Google SVN限制在100M内,Sourceforge则尚未见到明确的容量限制。
  • 代码库的权限管理。Google Code的代码库权限管理非常简单,在你登陆后,http://code.google.com/hosting/settings 将显示Google Code为你自动生成的随机密码。通过你的用户名和这个随机密码,你就可以访问SVN代码库,对其进行修改。sourceforge推荐使用putty套件,详细参考sourceforge上的说明,总的来说,相当繁复。
  • 发布版本。Google Code限制所有Release包不能超过100M,单个Release不能超过10M。Sourceforge尚未见到明确的限制。
    Google Code发布一个新的Release流程,仍然只需要一个页面即可完成。你只需要选择上传的文件,并为该文件加一些预定义的标签(用于告诉别人你的 Release支持的平台或其他信息,这些标签Google Code已经预定义部分,项目管理人员亦可以定义),确认即开始上传。特别地,如果一个Release被打上 Featured 标签,那么它将出现在项目首页。
    Sourceforge的流程则比较复杂:
    • 通过ftp上传你要发布的文件。上传地址:ftp://upload.sourceforge.net/incoming,这个过程匿名进行。上传的文件在你后续的步骤中进行“认领”,如果某个包长时间没人认领,Sourceforge将清理之。
    • 进入Sourceforge。用你的Sourceforge帐号登陆。
    • 进入项目主页,进入Admin -> FileReleases。
    • 选择已有的Package或者新建Package,向该Package中添加一个Release。在你的项目发布的文件比较多(不是发布的历史版本多,而是一次发布的文件多,你可能希望对他们进行归类)时,Package可以更加有条理地管理这些文件。
    • 为该Release添加ReleaseNote和ChangeLog。确认。
    • 认领你上传到ftp上的文件。打上勾,确认即可。
    • 为你发布的文件添加说明(支持的平台、包的格式及其他规格)。
    • 如果有人关注这个项目的Release,最后一步,你可以向这些人发送信息,告诉他们发布了新的Release。这一步很有意思,是Google Code不能做到的。
  • Bug报告。Google Code中的issues,Sourceforge的tracker。由于用的还不算多,暂时不做详细比较。
  • 论坛。Google Code中并不直接提供论坛功能,当然,这是因为它推荐你使用强大的Google Groups。Sourceforge则除了提供给用户的论坛(并把用户论坛分为两个,一个讨论产品功能的,一个属于头脑风暴型的开放式讨论),也提供开发者专用的论坛(对非项目成员不可见)。
  • Project Web。Google Code中没有提供项目主页,而是颇具创意的提供了一个Wiki Pages。Sourceforge提供了项目主页,项目主页的地址是:"项目名.sourceforge.net"。你可以利用这个网址来宣传项目、提供项目信息。这个空间是是php+mysql的,并且你可以通过远程Shell控制,极其灵活。
  • 团队成员管理。Google Code你可以通过添加其他Gmail帐号为项目成员(Members)或管理员(Administers),但似乎还不能进行更加详细的权限管理。Sourceforge提供了非常精细的项目成员的权限管理。
  • 下载与访问统计。Google Code无此功能。Sourceforge提供了最近7日、最近2个月、年、全部访问/下载统计。非常详细。
  • 软件截图(ScreenShots)。可以让用户迅速获得项目的第一印象,吸引眼球。Google Code无此功能。

2008年1月28日

[转]IT项目管理实务

1. 你们的项目组使用源代码管理工具了么?
应该用。VSS、CVS、PVCS、ClearCase、CCC/Harvest、FireFly都可以。我的选择是VSS。
2. 你们的项目组使用缺陷管理系统了么?
应该用。ClearQuest太复杂,我的推荐是BugZilla。
3. 你们的测试组还在用Word写测试用例么?
不要用Word写测试用例(Test Case)。应该用一个专门的系统,可以是Test Manager,也可以是自己开发一个ASP.NET的小网站。主要目的是Track和Browse。
4. 你们的项目组有没有建立一个门户网站?
要有一个门户网站,用来放Contact Info、Baselined Schedule、News等等。推荐Sharepoint Portal Server 2003来实现,15分钟就搞定。买不起SPS 2003可以用WSS (Windows Sharepoint Service)。
5. 你们的项目组用了你能买到最好的工具么?
应该用尽量好的工具来工作。比如,应该用VS.NET而不是Notepad来写C#。用Notepad写程序多半只是一种炫耀。但也要考虑到经费,所以说是“你能买到最好的”。
6. 你们的程序员工作在安静的环境里么?
需要安静环境。这点极端重要,而且要保证每个人的空间大于一定面积。
7. 你们的员工每个人都有一部电话么?
需要每人一部电话。而且电话最好是带留言功能的。当然,上这么一套带留言电话系统开销不小。不过至少每人一部电话要有,千万别搞得经常有人站起来喊:“某某某电话”。《人件》里面就强烈谴责这种做法。
8. 你们每个人都知道出了问题应该找谁么?
应该知道。任何一个Feature至少都应该有一个Owner,当然,Owner可以继续Dispatch给其他人。
9. 你遇到过有人说“我以为…”么?
要消灭“我以为”。Never assume anything。
10. 你们的项目组中所有的人都坐在一起么?
需要。我反对Virtual Team,也反对Dev在美国、Test在中国这种开发方式。能坐在一起就最好坐在一起,好处多得不得了。
11. 你们的进度表是否反映最新开发进展情况?
应该反映。但是,应该用Baseline的方法来管理进度表:维护一份稳定的Schedule,再维护一份最新更改。Baseline的方法也应该用于其它的Spec。Baseline是变更管理里面的一个重要手段。
12. 你们的工作量是先由每个人自己估算的么?
应该让每个人自己估算。要从下而上估算工作量,而不是从上往下分派。除非有其他原因,比如政治任务工期固定等。
13. 你们的开发人员从项目一开始就加班么?
不要这样。不要一开始就搞疲劳战。从项目一开始就加班,只能说明项目进度不合理。当然,一些对日软件外包必须天天加班,那属于剥削的范畴。
14. 你们的项目计划中Buffer Time是加在每个小任务后面的么?
不要。Buffer Time加在每个小任务后面,很容易轻易的就被消耗掉。Buffer Time要整段的加在一个Milestone或者checkpoint前面。
15. 值得再多花一些时间,从95%做到100%好
值得,非常值得。尤其当项目后期人困马乏的时候,要坚持。这会给产品带来质的区别。
16. 登记新缺陷时,是否写清了重现步骤?
要。这属于Dev和Test之间的沟通手段。面对面沟通需要,详细填写Repro Steps也需要。
17. 写新代码前会把已知缺陷解决么?
要。每个人的缺陷不能超过10个或15个,否则必须先解决老的bug才能继续写新代码。
18. 你们对缺陷的轻重缓急有事先的约定么?
必须有定义。Severity要分1、2、3,约定好:蓝屏和Data Lost算Sev 1,Function Error算Sev 2,界面上的算Sev 3。但这种约定可以根据产品质量现状适当进行调整。
19. 你们对意见不一的缺陷有三国会议么?
必须要有。要有一个明确的决策过程。这类似于CCB (Change Control Board)的概念。
20. 所有的缺陷都是由登记的人最后关闭的么?
Bug应该由Opener关闭。Dev不能私自关闭Bug。
21. 你们的程序员厌恶修改老的代码么?
厌恶是正常的。解决方法是组织Code Review,单独留出时间来。XP也是一个方法。
22. 你们项目组有Team Morale Activity么?
每个月都要搞一次,吃饭、唱歌、Outing、打球、开卡丁车等等,一定要有。不要剩这些钱。
23. 你们项目组有自己的Logo么?
要有自己的Logo。至少应该有自己的Codename。
24. 你们的员工有印有公司Logo的T-Shirt么?
要有。能增强归属感。当然,T-Shirt要做的好看一些,最好用80支的棉来做。别没穿几次就破破烂烂的。
25. 总经理至少每月参加次项目组会议
要的。要让team member觉得高层关注这个项目。
26. 你们是给每个Dev开一个分支么?
反对。Branch的管理以及Merge的工作量太大,而且容易出错。
27. 有人长期不Check-In代码么?
不可以。对大部分项目来说,最多两三天就应该Check-In。
28. 在Check-In代码时都填写注释了么?
要写的,至少一两句话,比如“解决了Bug No.225”。如果往高处拔,这也算做“配置审计”的一部分。
29. 有没有设定每天Check-In的最后期限?
要的,要明确Check-In Deadline。否则会Build Break。
30. 你们能把所有源码一下子编译成安装文件吗?
要的。这是每日编译(Daily Build)的基础。而且必须要能够做成自动的。
31. 你们的项目组做每日编译么?
当然要做。有三样东西是软件项目/产品开发必备的:1. bug management; 2. source control; 3. daily build。
32. 你们公司有没有积累一个项目风险列表?
要。Risk Inventory。否则,下个项目开始的时候,又只能拍脑袋分析Risk了。
33. 设计越简单越好
越简单越好。设计时候多一句话,将来可能就带来无穷无尽的烦恼。应该从一开始就勇敢的砍。这叫scope management。
34. 尽量利用现有的产品、技术、代码
千万别什么东西都自己Coding。BizTalk和Sharepoint就是最好的例子,有这两个作为基础,可以把起点提高很多。或者可以尽量多用现成的Control之类的。或者尽量用XML,而不是自己去Parse一个文本文件;尽量用RegExp,而不是自己从头操作字符串,等等等等。这就是“软件复用”的体现。
35. 你们会隔一段时间就停下来夯实代码么?
要。最好一个月左右一次。传言去年年初Windows组在Stevb的命令下停过一个月增强安全。Btw,“夯”这个字念“hang”,第一声。
36. 你们的项目组每个人都写Daily Report么?
要写。五分钟就够了,写10句话左右,告诉自己小组的人今天我干了什么。一则为了沟通,二则鞭策自己(要是游手好闲一天,自己都会不好意思写的)。
37. 你们的项目经理会发出Weekly Report么?
要。也是为了沟通。内容包括目前进度,可能的风险,质量状况,各种工作的进展等。
38. 你们项目组是否至少每周全体开会一次?
要。一定要开会。程序员讨厌开会,但每个礼拜开会时间加起来至少应该有4小时。包括team meeting, spec review meeting, bug triage meeting。千万别大家闷头写code。
39. 你们项目组的会议、讨论都有记录么?
会前发meeting request和agenda,会中有人负责主持和记录,会后有人负责发meeting minutes,这都是effective meeting的要点。而且,每个会议都要形成agreements和action items。
40. 其他部门知道你们项目组在干什么么?
要发一些Newsflash给整个大组织。Show your team’s value。否则,当你坐在电梯里面,其他部门的人问:“你们在干嘛”,你回答“ABC项目”的时候,别人全然不知,那种感觉不太好。
41. 通过Email进行所有正式沟通
Email的好处是免得抵赖。但也要避免矫枉过正,最好的方法是先用电话和当面说,然后Email来确认。
42. 为项目组建立多个Mailing Group
如果在AD+Exchange里面,就建Distribution List。比如,我会建ABC Project Core Team,ABC Project Dev Team,ABC Project All Testers,ABC Project Extended Team等等。这样发起Email来方便,而且能让该收到email的人都收到、不该收到不被骚扰。
43. 每个人都知道哪里可以找到全部的文档么?
应该每个人都知道。这叫做知识管理(Knowledge Management)。最方便的就是把文档放在一个集中的File Share,更好的方法是用Sharepoint。
44. 你做决定、做变化时,告诉大家原因了么?
要告诉大家原因。Empower team member的手段之一是提供足够的information,这是MSF一开篇的几个原则之一。的确如此,tell me why是人之常情,tell me why了才能有understanding。中国人做事喜欢搞限制,限制信息,似乎能够看到某一份文件的人就是有身份的人。大错特错。权威、权力,不在于是不是能access information/data,而在于是不是掌握资源。
45. Stay agile and expect change
要这样。需求一定会变的,已经写好的代码一定会被要求修改的。做好心理准备,对change不要抗拒,而是expect change。
46. 你们有没有专职的软件测试人员?
要有专职测试。如果人手不够,可以peer test,交换了测试。千万别自己测试自己的。
47. 你们的测试有一份总的计划来规定做什么和怎么做么?
这就是Test Plan。要不要做性能测试?要不要做Usability测试?什么时候开始测试性能?测试通过的标准是什么?用什么手段,自动的还是手动的?这些问题需要用Test Plan来回答。
48. 你是先写Test Case然后再测试的么?
应该如此。应该先设计再编程、先test case再测试。当然,事情是灵活的。我有时候在做第一遍测试的同时补上test case。至于先test case再开发,我不喜欢,因为不习惯,太麻烦,至于别人推荐,那试试看也无妨。
49. 你是否会为各种输入组合创建测试用例?
不要,不要搞边界条件组合。当心组合爆炸。有很多test case工具能够自动生成各种边界条件的组合——但要想清楚,你是否有时间去运行那么多test case。
50. 你们的程序员能看到测试用例么?
要。让Dev看到Test Case吧。我们都是为了同一个目的走到一起来的:提高质量。
51. 你们是否随便抓一些人来做易用性测试?
要这么做。自己看自己写的程序界面,怎么看都是顺眼的。这叫做审美疲劳——臭的看久了也就不臭了,不方便的永久了也就习惯了。
52. 你对自动测试的期望正确么?
别期望太高。依我看,除了性能测试以外,还是暂时先忘掉“自动测试”吧,忘掉WinRunner和LoadRunner吧。对于国内的软件测试的现状来说,只能“矫枉必须过正”了。
53. 你们的性能测试是等所有功能都开发完才做的么?
不能这样。性能测试不能被归到所谓的“系统测试”阶段。早测早改正,早死早升天。
54. 你注意到测试中的杀虫剂效应了么?
虫子有抗药性,Bug也有。发现的新Bug越来越少是正常的。这时候,最好大家交换一下测试的area,或者用用看其他工具和手法,就又会发现一些新bug了。
55. 你们项目组中有人能说出产品的当前整体质量情况么?
要有。当老板问起这个产品目前质量如何,Test Lead/Manager应该负责回答。
56. 你们有单元测试么?
单元测试要有的。不过没有单元测试也不是不可以,我做过没有单元测试的项目,也做成功了——可能是侥幸,可能是大家都是熟手的关系。还是那句话,软件工程是非常实践、非常工程、非常灵活的一套方法,某些方法在某些情况下会比另一些方法好,反之亦然。
57. 你们的程序员是写完代码就扔过墙的么?
大忌。写好一块程序以后,即便不做单元测试,也应该自己先跑一跑。虽然有了专门的测试人员,做开发的人也不可以一点测试都不做。微软还有Test Release Document的说法,程序太烂的话,测试有权踢回去。
58. 你们的程序中所有的函数都有输入检查么?
不要。虽然说做输入检查是write secure code的要点,但不要做太多的输入检查,有些内部函数之间的参数传递就不必检查输入了,省点功夫。同样的道理,未必要给所有的函数都写注释。写一部分主要的就够了。
59. 产品有统一的错误处理机制和报错界面么?
要有。最好能有统一的error message,然后每个error message都带一个error number。这样,用户可以自己根据error number到user manual里面去看看错误的具体描述和可能原因,就像SQL Server的错误那样。同样,ASP.NET也要有统一的Exception处理。可以参考有关的Application Block。
60. 你们有统一的代码书写规范么?
要有。Code Convention很多,搞一份来发给大家就可以了。当然,要是有FxCop这种工具来检查代码就更好了。
61. 你们的每个人都了解项目的商业意义么?
要。这是Vision的意思。别把项目只当成工作。有时候要想着自己是在为中国某某行业的信息化作先驱者,或者时不时的告诉team member,这个项目能够为某某某国家部门每年节省多少多少百万的纳税人的钱,这样就有动力了。平凡的事情也是可以有个崇高的目标的。
62. 产品各部分的界面和操作习惯一致么?
要这样。要让用户觉得整个程序好像是一个人写出来的那样。
63. 有可以作为宣传亮点的Cool Feature么?
要。这是增强团队凝聚力、信心的。而且,“一俊遮百丑”,有亮点就可以掩盖一些问题。这样,对于客户来说,会感觉产品从质量角度来说还是acceptable的。或者说,cool feature或者说亮点可以作为质量问题的一个事后弥补措施。
64. 尽可能缩短产品的启动时间
要这样。软件启动时间(Start-Up time)是客户对性能好坏的第一印象。
65. 不要过于注重内在品质而忽视了第一眼的外在印象
程序员容易犯这个错误:太看重性能、稳定性、存储效率,但忽视了外在感受。而高层经理、客户正相反。这两方面要兼顾,协调这些是PM的工作。
66. 你们根据详细产品功能说明书做开发么?
要这样。要有设计才能开发,这是必须的。设计文档,应该说清楚这个产品会怎么运行,应该采取一些讲故事的方法。设计的时候千万别钻细节,别钻到数据库、代码等具体实现里面去,那些是后面的事情,一步步来不能着急。
67. 开始开发和测试之前每个人都仔细审阅功能设计么?
要做。Function Spec review是用来统一思想的。而且,review过以后形成了一致意见,将来再也没有人可以说“你看,当初我就是反对这么设计的,现在吃苦头了吧”
68. 所有人都始终想着The Whole Image么?
要这样。项目里面每个人虽然都只是在制造一片叶子,但每个人都应该知道自己在制造的那片叶子所在的树是怎么样子的。我反对软件蓝领,反对过分的把软件制造看成流水线、车间。参见第61条。
69. Dev工作的划分是单纯纵向或横向的么?
不能单纯的根据功能模块分,或者单纯根据表现层、中间层、数据库层分。我推荐这么做:首先根据功能模块分,然后每个“层”都有一个Owner来Review所有人的设计和代码,保证consistency。
70. 你们的程序员写程序设计说明文档么?
要。不过我听说微软的程序员1999年以前也不写。所以说,写不写也不是绝对的,偷懒有时候也是可以的。参见第56条。
71. 你在招人面试时让他写一段程序么?
要的。我最喜欢让人做字符串和链表一类的题目。这种题目有很多循环、判断、指针、递归等,既不偏向过于考算法,也不偏向过于考特定的API。
72. 你们有没有技术交流讲座?
要的。每一两个礼拜搞一次内部的Tech Talk或者Chalk Talk吧。让组员之间分享技术心得,这笔花钱送到外面去培训划算。
73. 你们的程序员都能专注于一件事情么?
要让程序员专注一件事。例如说,一个部门有两个项目和10个人,一种方法是让10个人同时参加两个项目,每个项目上每个人都花50%时间;另一种方法是5个人去项目A,5个人去项目B,每个人都100%在某一个项目上。我一定选后面一种。这个道理很多人都懂,但很多领导实践起来就把属下当成可以任意拆分的资源了。
74. 你们的程序员会夸大完成某项工作所需要的时间么?
会的,这是常见的,尤其会在项目后期夸大做某个change所需要的时间,以次来抵制change。解决的方法是坐下来慢慢磨,磨掉程序员的逆反心理,一起分析,并把估算时间的颗粒度变小。
75. 尽量不要用Virtual Heads
最好不要用Virtual Heads。Virtual heads意味着resource is not secure,shared resource会降低resource的工作效率,容易增加出错的机会,会让一心二用的人没有太多时间去review spec、review design。一个dedicated的人,要强过两个只能投入50%时间和精力的人。我是吃过亏的:7个part time的tester,发现的Bug和干的活,加起来还不如两个full-time的。参见第73条。73条是针对程序员的,75条是针对Resource Manager的。