苦闷的项目经理

项目启动会议开始, 项目经理拿出自己的项目计划信心满满的想要告诉大家接下来的项目实施应该如何展开. 可是刚刚开始就被需求分析师和产品经理质疑:
模块划分不合理,应该按照业务场景制定发布计划.
这意味着项目经理原本按照功能和系统模块制定的计划被90%的推翻.
为什么会有这样的问题?
项目经理的技术出身导致其对项目的scope估计无可避免的过早考虑到设计(甚至是代码重用)
而产品经理和需求方更多关注的是产品提供的feature,或者说一个”完整的”功能点.在scrum里我们称为”用户故事”.
而项目经理的项目计划又有两份,一份是给”上面”看的,也就是用户,产品经理,需求方;而另一份是给”下面”看的,也就是系统设计/开发人员.而这里显然是第一份.因为关注点不同.
这也是项目驱动(project-oriented)和产品驱动(product-oriented)的交付方式和内容的不同.
项目驱动更多的是在整个项目结束后交付完整的代码和所有的功能.因为项目(开发)的周期相对较短.
而产品驱动则是要在不同的阶段都要交付feature和功能(当然你觉得每个阶段都可以用项目驱动来做也没什么不妥),同时还要兼顾整体的系统设计和重用性/维护性等问题.因为产品(开发)的周期通常较长,夜长也就梦多了,开发周期可能同时伴随的维护任务和设计重构.在产品驱动模式中,项目经理需要更好的平衡能力和全局掌控能力.

项目启动会议开始, 项目经理拿出自己的项目计划信心满满的想要告诉大家接下来的项目实施应该如何展开. 可是刚刚开始就被需求分析师和产品经理质疑:

模块划分不合理,应该按照业务场景制定发布计划.

这意味着项目经理原本按照功能和系统模块制定的计划被90%的推翻.

为什么会有这样的问题?

项目经理的技术出身导致其对项目的scope估计无可避免的过早考虑到设计(甚至是代码重用)

而产品经理和需求方更多关注的是产品提供的feature,或者说一个”完整的”功能点.在scrum里我们称为”用户故事”.

而项目经理的项目计划又有两份,一份是给”上面”看的,也就是用户,产品经理,需求方;而另一份是给”下面”看的,也就是系统设计/开发人员.而这里显然是第一份.因为关注点不同.

这也是项目驱动(project-oriented)和产品驱动(product-oriented)的交付方式和内容的不同.

项目驱动更多的是在整个项目结束后交付完整的代码和所有的功能.因为项目(开发)的周期相对较短.

而产品驱动则是要在不同的阶段都要交付feature和功能(当然你觉得每个阶段都可以用项目驱动来做也没什么不妥),同时还要兼顾整体的系统设计和重用性/维护性等问题.因为产品(开发)的周期通常较长,夜长也就梦多了,开发周期可能同时伴随的维护任务和设计重构.在产品驱动模式中,项目经理需要更好的平衡能力和全局掌控能力.

团队持续集成手记

早就想试试持续集成.终于有机会了.
刚开始用cruise-control但是免费版有使用限制,而且界面似乎也不是很友好.没用的信息比较多.所以在忍受了1周以后废弃,改用hudson.
hudson比想象中的简单.安装和配置过程不说了.没什么难的东西,多尝试几次即可.
我们的项目用到的是ivy和ant,据说如果项目使用了maven的话就更简单了.”因为hudson和maven的搭配几乎可以用天衣无缝来形容”.
在使用了hudson将我们的所有模块导入后,整个构建越来越稳定了.而且build fail总是可以在第一时间捕捉并消灭掉.团队初尝ci的好处.
之后我们在构建过程中加入了自动化单元测试和覆盖率工具,当我们发现项目中broken的测试时,团队成员居然自发的去修复他们.在引入单元测试和覆盖率工具3天后,所有单元测试都pass,测试通过率100%.但团队对覆盖率这个东东还不是很了解.似乎也没有多少动力去提高他.此时,覆盖率只有40%左右.
之后我们又引入了findbugs和PMD,发现代码中存在的大量坏味道.此时ci-game插件起了作用.因为每改一个相应的”bug”都会有相应的分数.整个团队掀起了”打怪”狂潮.甚至加班打怪的情况.1周后,我们消灭了90%的不良代码.期间虽然会出现一些改错的地方.但基本上通过持续的代码review(因为所有团队成员都在不停的review代码),即便少有的几次改错的地方也是在第一时间发现并纠正了.
此时,似乎没有什么”怪”可以打了,但ci-game的竞争仍然激烈.此时团队发起了覆盖率提升行动,通过将不同的模块划拨给不同的小组,然后设置一个预期的目标(比如让aaa模块的测试行覆盖率从50%提升到70%.并且每提升1%都可以有5分.ci-game再一次大显神威.覆盖率行动成功并按照计划达到目标.
其实所有这些自动化的事情都可以在每ci工具的情况做到,也可以有类似ci-game这样的机制来提高团队对提高代码质量的积极性.但hudson提供的对代码的”透明”,让所有人都可以随时看到代码有哪些问题,改进的如何,更重要的是意识到自己写的代码是会被别人看到的!
hudson,很和谐!

早就想试试持续集成.终于有机会了.

刚开始用cruise-control但是免费版有使用限制,而且界面似乎也不是很友好.没用的信息比较多.所以在忍受了1周以后废弃,改用hudson.

hudson比想象中的简单.安装和配置过程不说了.没什么难的东西,多尝试几次即可.

我们的项目用到的是ivy和ant,据说如果项目使用了maven的话就更简单了.”因为hudson和maven的搭配几乎可以用天衣无缝来形容”.

在使用了hudson将我们的所有模块导入后,整个构建越来越稳定了.而且build fail总是可以在第一时间捕捉并消灭掉.团队初尝ci的好处.

之后我们在构建过程中加入了自动化单元测试和覆盖率工具,当我们发现项目中broken的测试时,团队成员居然自发的去修复他们.在引入单元测试和覆盖率工具3天后,所有单元测试都pass,测试通过率100%.但团队对覆盖率这个东东还不是很了解.似乎也没有多少动力去提高他.此时,覆盖率只有40%左右.

之后我们又引入了findbugs和PMD,发现代码中存在的大量坏味道.此时ci-game插件起了作用.因为每改一个相应的”bug”都会有相应的分数.整个团队掀起了”打怪”狂潮.甚至加班打怪的情况.1周后,我们消灭了90%的不良代码.期间虽然会出现一些改错的地方.但基本上通过持续的代码review(因为所有团队成员都在不停的review代码),即便少有的几次改错的地方也是在第一时间发现并纠正了.

此时,似乎没有什么”怪”可以打了,但ci-game的竞争仍然激烈.此时团队发起了覆盖率提升行动,通过将不同的模块划拨给不同的小组,然后设置一个预期的目标(比如让aaa模块的测试行覆盖率从50%提升到70%.并且每提升1%都可以有5分.ci-game再一次大显神威.覆盖率行动成功并按照计划达到目标.

其实所有这些自动化的事情都可以在每ci工具的情况做到,也可以有类似ci-game这样的机制来提高团队对提高代码质量的积极性.但hudson提供的对代码的”透明”,让所有人都可以随时看到代码有哪些问题,改进的如何,更重要的是意识到自己写的代码是会被别人看到的!

当基础模块部分基本稳定后,我们将应用模块也做到自动化构建和发布到开发集成环境.每小时进行一次发布.确保了我们集成开发环境始终都有最新的版本. 后续我们准备将自动化smoke test也做一些,也许不需要很彻底,只需要基本的接口可用即可.

hudson,不,持续集成,很和谐!

面试官基本礼仪

一个有礼貌的面试官代表了一个公司的形象,同时也能折射出这个公司对人(无论是否人才)的态度.所以面试官的礼仪和精神状态非常重要. 以下列一些基本的注意事项.

  1. 见面握手寒暄,聊聊诸如天气,久等这样的话题让对方心情尽可能轻松一些。
  2. 面试开始,如果之前没有水,要倒上一杯水。面试官自我介绍,还是让面试者没有级别感,放松。只有在放松的情况下才能真正全面的考察一个人。
  3. 面试过程要始终看着对方 不要埋头/皱眉头/大笑/冷场. 如果时间允许,可以在面试者回答完问题后,告诉他正确答案.
  4. 面试结束握手道别。并亲自把对方引送到门口.

Powered by MoFire

[笔记]敏捷估计与规划

敏捷估计与规划笔记

敏捷宣言推崇:
1.个人与交互重于开发过程和工具
–敏捷开发小组认为: 一个由使用普通工具的优秀人员组成的/运行良好的小组,总是会比由使用优秀工具和过程的普通人组成的,紊乱的小组做的更好.
–我们花了太多的时间试图定义一个开发过程,以便把人当作机器上可被替换的齿轮,却没有取得成功
2.可用的软件重于复杂的文档
–每次迭代结束时获得一个稳定的,逐渐增强的版本,比便更频繁的收集对产品和开发过程的反馈
–将反馈回馈到开发过程,以保证开发小组始终在处理最有价值的功能
3.寻求客户的合作重于对合同的谈判
–这是一个希望,也许不是开发小组可以控制的 –我认为
4.对变化的响应重于始终遵循固定的计划
–最终的目标!!是向项目客户和用户交付更多的价值(或者更多的必要特性,更合理的时间,更小的成本)
–而切记计划是为目标服务的 –我认为

基于活动而不是基于功能进行规划 (是不好的!)
基于活动的规划分散了我们对功能的注意力,而功能才是衡量客户价值的担忧
忽视关于用户最终需要什么的不确定性,会导致虽然然按时完成了项目,却没有包含在制定计划以后发现的那些重要功能.

敏捷开发小组的主要工作方式:
1.作为一个整体工作
2.按短迭代周期工作
3.每次迭代交付一些成果
4.关注业务优先级
5.检查与调整

如何分割用户故事
1.按照数据边界分割
按照用户故事所支持数据的边界分割大型用户故事
2.按照操作边界分割
把大型用户故事分割成独立的建立/读取/更新/删除操作
3.去除横切考虑
为用户故事建立两个版本:一个具备对横切考虑的支持,另一个不具备这种支持.
4.不用满足性能限制
5.分割具有混合优先级的用户故事
6.不要把故事分割成任务
而是寻找一个方法来让曳光弹穿过整个故事
7.避免相关变化的诱惑
在一个适当规模的功能中增加相关变化会把事情弄糟,除非这些变化具有同样的优先级
8.组合用户故事
对按照2周一次的迭代周期工作的开发小组来说,合适的做法是3~5天做完

速度驱动的迭代规划步骤
调整优先级/确定目标速度->确定迭代目标->选择用户故事->分解任务->对任务估计

承诺驱动的迭代规划
调整优先级->确定迭代目标->选择要增加的用户故事/把故事扩展成任务/对任务估计->要求小组作出承诺<->移除一个用户故事(如果无法承诺)->迭代规划完成(可以承诺)

[翻译]API设计黄金法则

API设计黄金法则

原文: http://programmer.97things.oreilly.com/wiki/index.php/The_Golden_Rule_of_API_Design
API的设计通常是一项艰巨的任务,尤其当设计的API非常庞大时. 如果你设计的API将会有成百上千的用户时,你要考虑今后应该如何扩展来避免不小心把客户端的代码搞挂. 除此之外,你还要考虑用户在使用API的过程中对你的影响.如果你的API类使用它内部的一个方法时,你要记得 – 用户可以通过子类复写(override)他,而这,可能会是灾难性的. 你将不能修改那些方法,因为用户已经这样使用它们了. 你今后的内部实现将无可避免的由你的用户来决定,而不再是你.

API程序员有各种各样的方法来解决这个问题,但最简单的还是禁止用户修改API.如果你用的是Java你可能会把所有的类都声明为final,如果用C#,则声明所有的方法为sealed.无论用什么语言,你都可以通过单例(singleton)或者静态工厂方法来避免用户复写代码,或者不当的扩展和使用你的代码.这些听起来很有道理,但,真是这样吗?

在过去的10年,我们渐渐意识到单元测试是一种非常非常重要的实践,但这一实践却并没有完全被整个行业所认可. 显而易见的是,大多数情况下,为一个未经测试的类编写测试用例时总是很难.你会发现使用了API的代码和API耦合的就像是上了强力胶一样.没有办法去模拟API类的行为,进而容易的测试API和你的代码之间的交互.

经过一段时间后也许会有改善,但只有我们在开始设计API时就考虑到测试问题.不幸的是,这可能需要你(API的设计者)多花一点时间 – 不仅测试自己的代码,还要考虑用户如何测试他们的代码. 这里就引出了伟大的”API设计黄金法则”: 仅仅给API写测试用例是不够的;你还要为使用API的代码写单元测试.只有这样做了,你才会在第一时间体会用户在使用你的API时进行测试时的种种问题.

让API易于测试的方法有很多.static,final和sealed并不见得是不合理的,他们有相应的使用场景.但意识到测试问题是很重要的,最好的办法就是自己去感受.一旦你这样做了,你将更加胜任各种设计挑战.

By Michael Feathers