Programmer
Programmer是软件开发的初学者,在这一层,掌握2~3种常用的语言,了解SDK常用的部分,有过2~3个正式的项目经验,产出代码行在1万左右(平均每个项目3000左右),能够独立胜任常见的开发任务。

 

Developer
Developer在团队中跨度较大,从Lead Developer到Code Robot,承担设计、编码、单元测试、代码审核、评审;都是这类好手级人物。Lead Developer是系统中的核心模块开发者,而Designer特质的Developer可以辅助评审设计,Code Robot类人物是最高效的开发者。Developer通常有3年以上的开发经验,有过项目失败的先例,在许多Why和How的问题上不会像新手般不停追问和执着。他们会主动修饰和优化自己和团队的代码,让整个系统变得更加有机;也会评估和尝试更好的开发方式和代码工具和框架,来改进系统开发效率和通用性。

 

Engineer
Engineer是一个专家级Developer,他的专长不仅仅体现在程序上,而是整个软件。即应用领域、行业参考、业务……等等一切让软件“可用性”更强的方面。他不仅能够设计出有效的系统方案,还能够从业务层面直接解决问题而提出最优的技术方案,重要的是他有足够的沟通技巧与不懂得技术的人谈话并解释他的方案。Engineer一般有5~8年的经验,有过跨行业经历,并且是他自己选择在这个行业继续停留下去。
posted @ 2011-08-30 21:33 Justina Chen 阅读(228) 评论(0) 编辑

从07年中初次接触Scrum的概念到其中几年项目中逐渐实践CI、TDD,到亲自掌握项目实践Scrum近一年,最终我们放弃了Scrum这个框架和所谓的“自组织”。原因为何?

 

1.成员放弃了Scrum所“赋予”的“权利”

比如领用任务、评估工作量、自组织协作、决策等。在第一次Scrum计划会议上排出任务让大家领用时,成员的态度可以用“反感”来形容。在经历四个Sprint后成员依然坚持认为,应为PM完成这些工作,故放弃。

 

2.团队成员能力参差不齐

我很主观地认为,现在国内的开发团队都会是一部分高级工程师搭配一部分初、中级工程师,这种搭配本身就决定了领用任务时的混乱,尤其是团队中一部分成员极度渴望去做那些自己没有经验的任务。结果造成一部分人一直搞不清楚自己在团队中的定位,一直处于“费力不讨好”的挫折中。高级工程师对另一些成员的效率、成果也颇有微词,对团队分工非常不满。

 

3.没有清晰的设计阶段是造成上面第2个问题的另一个因素

众所周知,敏捷倡导演进式架构,其本质是,在目标不确定性极大的情况下,通过一次又一次短周期的反馈修正来不断接近目标,固在敏捷中,每项任务、剩余工时、成本燃尽,控制得如此之细,CMMI根本扛不起这样恐怖的基线变化次数。取消清晰的设计阶段,以及采用大量并行的测试,可谓敏捷的一种取舍,赢取更短的发布周期。也正因为如此,在任务分解时,无法清晰地定义设计任务,而将其混杂在功能化的任务中,事实说明,这里有大量的重复工作并且交付良莠不齐。

 

4.高估了工程师的成熟度

敏捷对工程师的心智有过高的要求。为什么说是过高?其实,在公司里担任高层管理人员的,恐怕都不具备成熟的心智,何况处于一线年轻又尚轻的程序员?现在的程序员,从学校或从培训班子里出来,人际圈子小,知识面狭窄,遇事仅能从自身考虑,常常因生活中一些事情影响情绪和工作,遇到难题就放弃,全力投入到项目开发中来的,并不多见。所以,在项目和开发过程中,监控、管理,催促、激励甚至批评,是必须的!

 

5.Scrum缺乏领导者

Scrum把团队想象得太完美了,如果有完美的团队,开发方法根本就不重要。工作、项目在进行的过程中,必须会遇到困难、遇到卡壳、团队发生冲突和争吵,这时候,必须有一个人挺身而出,作出决定,解决问题,为大家指明方向,平息争端,警告不利分子,这个人只能是领导人物,能力、权力和职位比团队成员高的人。扁平式组织,想象得太完美了,团队里各种性格的人都有,不服你不爽你的也总有人在,吵个没完没了,各做一套,家常便饭。

 

最后我想说说Scrum适合的团队,这样的团队需要有一些技术成熟度比较高(五至八年经验)、并且比较稳定地做技术的成员,使用Scrum可以使团队日益默契,并改善技术团队沟通交流不善、积累反思不多的常见问题,基本上,Scrum的正面意义在于,以前的项目管理、开发管理都只注意到了需求、技术、测试等机械性问题,而Scrum把团队管理、团队建设的思路引进到了技术团队。而在这个范畴里,Scrum还比较轻量级,它的回顾会议在工业产品开发中随处可见,可作入门指南,大家会问,进阶怎么走?我想未来软件开发团队的路子会和工业产品相似,渐渐地把决策过程、分析思路引进到团队中,这样子的团队才真正是一个“工程师团队”。

posted @ 2011-05-17 10:16 Justina Chen 阅读(3319) 评论(49) 编辑

本文适合对Team Foundation Server 2010的部署和管理、模板配置有经验的人员阅读。

在阅读本文之前,需了解Scrum的一些基本知识;其次,需对Visual Studio Scrum 1.0模板有基本的了解。

Scrum的资料:http://msdn.microsoft.com/en-us/library/dd997796.aspx

Scrum 1.0的资料:http://msdn.microsoft.com/en-us/library/ff731587.aspx

每个Sprint正式开始之前的准备

在Scrum 1.0中正式创建一个Sprint之前,要将所有的Backlog填写完成,与团队成员一起分解Task,将Task以“相关”的关系与对应的Backlog进行关联以方便开发人员在浏览Task时查看相关Backlog的描述(Task不能拥有两个不同的父级Backlog,故将关系设置为相关)。

你可以为Task/Backlog创建子级Task/Backlog,但注意父级Task/Backlog的状态、迭代范围的变动无法影响子级,我认为层次关系已失去意义,可以不建。

注:在Task中也有前置关系,没有试过是否有MS Project一样的强制效果(你可以试一下)。

以保守的态度估算每项Backlog的Effort(花费,可代表有效产出),Task的Remaining Work(剩余工作量)。对第一次估算的Task,剩余工作量即总计工作量。

Backlog填写界面
Screenshot showing a new product backlog item

Task填写界面
Screenshot showing a new task work item

Backlog的Effort将在Velocity报表计算在对应的Sprint之中,要注意,这份报表只会计算第一次填写的Effort,之后的更新不作计算,所以,对每个Backlog,最好先用Excel等工具记录好Effort,与各干系人确定好后再填入TFS.

Velocity报表
Screenshot showing a velocity chart

我们采用Visual Studio 2010旗舰版的测试管理工具进行测试计划、测试用例、自动化测试的管理,测试计划的编写是在Backlog评审完成之后进行。在测试计划中需与测试人员约定可测试版本的生成质量,我们的约定是“初次测试已通过”,测试人员可以直接使用这个生成定义来筛选待测试版本,每次的自动化测试都可以生成Bug快照和报表,这里就不详述了。

Sprint计划会议要做的事

准备投影仪,将TFS Product Backlog投放到屏幕上,与团队、产品负责人一起评审每项Backlog和Task:

  1. 将评审通过的Backlog/Task状态更新为Approved,不通过项置为Removed。这个操作只有Scrum 1.0项目中Project Administrator、Contributor两个角色中的成员可以完成。
  2. 与团队确定交付目标、期限。在TFS上创建Sprint,指定迭代路径、起始时间。
  3. 将与团队确定的交付目标相关的Backlog、Task的迭代路径指定为刚刚创建的Sprint。
  4. 为每个Task指派开发人员。为每个Backlog指派负责人。

Sprint填写界面
Screenshot showing a new sprint work item.

这个事情如果一次会议不能完成,也可以开两次。第一次确定交付目标、计划,第二次对目标细化出来的Backlog、Task进行评审,看时间是否与计划相符,进行裁减或增加。

但要注意,填写TFS的Backlog、Task、Sprint先后顺序,以及要“一气呵成”,否则各种报表会很难看(不真实)。

如果是第N个Sprint并且是在有交付品之后,在新的一个Sprint开始之前,需对开发环境进行整理,保持干净,这包括:

  1. 使用与交付品一致的数据库脚本重新创建和初始化数据库。
  2. 使用上一个Sprint最新的正确版本部署开发环境。
  3. 验证各项功能是否正确。

开发开始后马上要做的事

建立持续集成的生成定义。在这里,我们采用的是TFS 2010的生成服务,具体如何配置可见:http://www.justinablog.com/?p=417

给团队成员一个简单的培训,识别持续集成结果列表、报表中各种图例代表的含义(有编译通过、编译通过测试不通过、编译通过代码覆盖率低等几种状态)。

开发过程中要做的事

Scrum Master/Project Manager

时间点 应做事项
每日早会前 检查被标记为In the progress的Task,将关联的Backlog标记为Committed
每日早会中 与团队查看燃尽图,确认每个被标记为In the progress的Task是否需要协助,确认未关闭的Impediment是否需要协助
每日早会后 检查标记为Done的Task,选择前一个工作日最后一个成功的持续集成版本,将生成质量标记为“初次测试已准备就绪”,发布到开发环境上进行功能的验证;如验证通过,将关联的Backlog由Committed更新为Done,如不通过,提交一个Impediment,指派给开发人员
将状态为New的Bug进行审核,通过标记为Approved,指派开发人员
每日下班前 检查当日的持续集成生成列表与报表,如有红色部分,与团队一起排除错误,直到最后一次生成变为绿色
每周二、四、五下班前 将最新的一个生成质量为“初次测试已准备就绪”的持续集成版本标记为“初次测试已通过”
测试通过 将持续集成该版本的生成质量由“初次测试已通过”变更为“实验室测试已通过”
交付品β版本发布 将持续集成该版本的生成质量由“实验室测试已通过”变更为“部署准备工作就绪”
用户验收结束 将生成质量由“部署准备工作就绪”变更为“用户验收测试已通过”
上线 将生成质量由“用户验证测试已通过”变更为“已发布”

项目经理检查表

Impediment填写界面
Screenshot showing impediment work item

Developer

时间点 应做事项
每日早会前 将计划当天待做Task标记为In the progress,将计划当天暂停的Task标记为To do,两项操作均需再次评估剩余工时,即还需要多少工时来完成这项Task
检查分配给自己的Impediment和Bug,在开始修复之前,将对应的Task状态由Done改为In the progress,填写所需剩余工时
每次签入之后 检查持续集成发起者为自己的生成项,如有错误,进行修复;检查代码覆盖率(我们的要求是关键功能的方法达到100%)
下班前 将已完成的Task状态设置为Done,更新所有状态依然为In the progress的Task的剩余工时

开发人员检查表

注:关于生成定义和代码覆盖率方面,可以看这份资料:http://msdn.microsoft.com/zh-cn/library/bb558973(v=VS.90).aspx

Tester

时间点 应做事项
每周一、周三、周五早会后
(功能持续集成测试)
获取生成质量为“初次测试已通过”的最新版本,发布到测试环境,检查状态为Done的Backlog/Bug,验证是否通过;如不通过,将Bug状态重置为Committed,将新发现的Bug提交到TFS
发布任何版本之前
(集成测试)
获取最新的生成质量为“初次测试已通过”的版本,发布到测试环境,验证所有的Backlog、Bug是否通过

测试人员检查表

Bug填写界面
Screenshot showing a new bug work item

燃尽图

燃尽图上展示的是这个Sprint所有Task的剩余工时,黄色部分是正在进行中的工作,蓝色部分是未开始的工作。

Scrum 1.0的燃尽图是每日更新一次,在每个早会,须与团队成员一起查看燃尽图的状态,基本原理就是,面积图在黑色斜线之下,意味着整个团队的进度是安全的,否则意味着延期的风险

Screenshot showing a sprint burndown chart

posted @ 2011-01-06 13:39 Justina Chen 阅读(1791) 评论(3) 编辑

现在我们来讲讲存储服务(Storage Service)和管理工具(Fabric)。

存储服务(Storage Service)

Windows Azure为应用程序提供了几种形式的数据存储,如下图所示:

最简单的数据存储是使用Blobs,它是一个层次数据存储。如图所示,一个数据存储帐户包含一个或多个容器,每个容器中包括一个或多个blob,blog用于存储二进制格式的数据,容量可以很大,并且,它们还可以关联元数据,如JPEG图片的拍摄信息和MP3文件的歌手信息。Blobs用于XDrives,一种查看本地磁盘数据的工具)的数据存储。

但Blobs并不能用于所有的存储场景,Windows Azure为应用程序提供了另一种方式:Tables,但它并非关系数据库中的表。实际上,Table中存储的是一组包含属性的实体(听起来更像对象数据库)。应用程序可以直接使用ADO.NET Data Services就可以访问Table,而不是用SQL.之所以可以直接进行对象访问的原因是,Tables允许scale-out存储——将数据散列在几台服务器上进行存储——这远比关系数据库更加高效。实际应用中,一个Table可以存储上亿的对象。

Blobs和Tables都应用于数据的存取,Windows Azure提供的第三种存储机制,Queues,却有所不同。它应用于Web role实例与Worker role实例之间的异步通信。举个例子,当一个请求发送到Web role实例时,Web role将会在Queue中写入一条消息,描述应该怎么做。一个等待消息的Worker role实例读取到消息并执行操作,执行结果将被返回到另一个Queue或以其它方式进行处理。

Blobs,Tables和Queues,所有的数据在Windows Azure中会被存储三份,但我们不需要关心具体实现。这些拷贝可以容纳错误,一个拷贝的丢失不至于造成灾难。Windows Azure会自动为所有数据进行备份,一但主数据丢失,备份将变得可用。

Windows Azure存储数据在已授权的条件下,可以被Windows Azure应用程序、托管应用程序、其它云平台应用程序访问。三种数据都可以用REST机制进行认证和读取数据,Blobs、Tables和Queues都将以URIs的形式被HTTP操作请求,一个.NET客户端可以使用ADO.NET Data Services去访问数据,也可以直接使用HTTP去直接调用。

除此之外,Windows Azure应用程序也可以选择其它的存储机制,例如,Windows Azure Platform还提供了SQL Azure Database,它是一种访问上类似于SQL数据库的组件,可以在云平台上进行关系数据的存储。

管理工具(Fabric)

Fabric为所有的Windows Azure应用程序和存储提供了管理工具,它管理的对象包括计算机、交换机、负载均衡器等等,它也可以浏览存储的数据、监控应用程序每分钟的操作并记录。你还可以在Fabric中决定应用程序运行在哪台机器上,通过一个XML格式的配置文件进行管理。 

posted @ 2010-07-25 21:12 Justina Chen 阅读(1100) 评论(3) 编辑

本系列将系统地介绍Windows Azure,包括基本名词、编程以及Windows Azure的应用,并探讨Windows Azure可能给我们现行模式带来的变化。

先把晦涩的关于云计算的概念放到一边,来看看我们在“平步青云”之前的一些处境。

  1. 大量数据实时处理、计算时,用户不得不等待,我们不得不在编码中考虑是否采用缓存并通过性能测试,同时我们还要编写一些代码保证缓存的更新与擦除;
  2. 采用异步编程去解决用户等待问题;
  3. 各种应用程序、Web Service统一的集成平台与五花八门的交互方式,每一次发布都让你头痛;
  4. 海量数据存储的问题;
  5. 公共模块如日志记录。

然后我告诉你,Windows Azure为我们提供了上面五个问题的解决方案,也许你就有兴趣来了解它了。

这就是Windows Azure的一个典型应用:它在Windows Data Center的一台机器上运行,以服务的方式为用户提供商业应用程序的使用和数据存取。

Windows Azure能做什么

  1. 软件服务商可以在Windows Azure上为特定的商业公司创建应用程序,然后以SaaS的方式提供给商业公司。
  2. 软件服务商可以为特定用户创建应用程序,如需要扩大市场为顾客创建的商业站点,Windows Azure都能够支持。
  3. 企业为内部员工创建应用程序,Windows Azure也是一个好的选择。

接下来,让我们看看Windows Azure的组成:

计算服务(Compute service)负责运行应用程序,存储服务(Storage service)提供数据存储。第三个组件,Fabric,是一个管理和监控云平台上应用程序的工具。本文中将介绍第一个组件。

计算服务(Compute service)

Compute service支持多种多样的应用程序,它的首要任务就是,解决大量用户并发请求的瓶颈问题:此前我们采用硬件不断升级的方式,而现在Compute service支持应用程序以多个相同代码版本的实例运行在多个服务器上,并且,还支持虚拟机,我们可以通过Hyper-V的操作界面对每个虚拟机进行管理。需要运行程序时,开发人员从浏览器使用Windows Live ID登录,然后自定义应用程序的托管帐户以及数据存储的帐户。拥有托管帐户的开发人员就可以在Windows Azure平台上上载他的程序并定义其配置了。

Windows Azure提供了两种运行应用程序实例的方式:Web role实例和Worker role实例。

如名称所示,Web role实例可以接收HTTP和HTTPS请求,它必须运行在IIS 7中。开发人员可以创建ASP.NET、WCF或其它可运行在IIS上的.NET应用程序;也可以创建非.NET的应用程序,如PHP和部署在Tomcat上的Java程序。图三中我们可以看到,Windows Azure内置了硬件负载均衡(load balancing),以为每个服务器上相同的应用程序实例分配Web请求,并管理这些实例的生命周期。因为Windows Azure并未为应用程序的每个实例建立关联,所以无法保证同一用户的一系列请求只被发送到唯一的一个实例上。因此,Web role实例是无状态的,所有客户端特定的状态都会被写入到Windows Azure存储上并在请求完成时发回客户端。

Worker role实例与Web role实例的不同之处在于,它不需要配置也不运行在IIS中,大多数时候,他们是以后台工作的方式运行。我们还可以在Worker role中运行Web server,如Apache Web server。

开发人员可以只使用一个Web role实例、一个Worker role实例,或将两者结合起来使用。如果应用程序的性能下降,他可以通过Windows Azure增加Web role实例,或增加Worker role实例,或两者同时增加。如果性能超过要求标准,他可以降低这些实例的数目,开发人员可以通过关闭所有的实例来停止应用运程的运行。Windows Azure还提供了API,允许通过编程方式动态改变Web role、Worker role实例的数目,但无法自动关闭应用程序。

进行Windows Azure开发时,开发人员并不需要在自己的机器上运行云平台,而是向运行的云平台上载、配置和调试自己开发的程序,可以使用日志API对平台上的应用程序进行调试,也可以使用配置工具来监控应用程序,如性能计数器、CPU占用、存储错误等等。这些应用程序都是以用户模式(User mode)运行,Windows Azure自己管理自身的系统更新,所以不必担心应用程序带来系统级(System level)的破坏,这在目前的企业平台上,是经常发生的:一些应用程序集成之后,影响到众多其它程序,甚至给平台造成破坏。

光是运行代码功能,显然不是Windows Azure的全部,在下一篇,我们将讲讲存储服务(Storage service)。

 

posted @ 2010-07-22 22:40 Justina Chen 阅读(1674) 评论(9) 编辑