项目管理的可控性讨论

3 月 29th, 2010 | Posted by | Filed under 未分类

上学期一篇很扯淡的软件工程报告,仅作存档。

项目管理的可控性讨论

040630520 彭立勋

项目管理中两个重要的内容是进度可控和质量可控。项目进度可控,可以依靠项目生命周期中有三个与时间相关的重要概念,这三个概念分别是: 检查点(Checkpoint)、里程碑(Mile Stone)和基线(Base Line),它们一起描述了在什么时候(When)对项目进行什么样控制。项目质量可控,则是靠建立完善的流程规范,从分析到建模,从编码到测试,再到最后的交付,都要有一套质量可控的规范在运作,它们描述什么人(Who)需要再项目的每个部分做什么(What)。
有了3个W(When/Who/What),就明确了什么人在什么时间做什么事,就能够保证项目的可控。虽然项目的成功依赖的因素远比这些多,但有了可控,至少能保证在规定的时间内现有技术可以解决的问题都可以被实现。

进度可控
项目进度可控,可以依靠项目生命周期中有三个与时间相关的重要概念,这三个概念分别是: 检查点(Checkpoint)、里程碑(Mile Stone)和基线(Base Line),它们一起描述了在什么时候(When)对项目进行什么样控制。

检查点

检查点指在规定的时间间隔内对项目进行检查,比较实际与计划之间的差异,并根据差异进行调整。可将检查点看作是一个固定“采样”时间点,而时间间隔根据项目周期长短不同而不同,频度过小会失去意义,频度过大会增加管理成本。常见的间隔是每周一次,项目经理需要召开例会并上交周报。
例如在我实习的公司,每天都是一个检查点,需要上报每天的工作日志,总监可以根据工作日志来判断每个人的工作情况,对工作较慢的成员进行催促,保证整体进度。然后每周提交任务完成情况,总监根据完成情况判定成员是否努力工作了。将大任务分解成小任务,小任务再分解成可查看的小目标,这样一步步控制,在最小的地方及早发现进度问题,及时催促,保证了项目整体进度不拖延。

里程碑

完成阶段性工作的标志,不同类型的项目里程碑不同。里程碑在项目管理中具有重要意义,用一个例子说明:
情况一:让一个程序员一周内编写一个模块,前3天大家可能都挺悠闲,可后2天就得拼命加班编程序了,而到周末时又发现系统有错误和遗漏,必须修改和返工,于是周末又得加班了。
情况二:实际上还有另一种选择,即周一与程序员一起列出所有需求,并请业务人员评审,这时就可能发现遗漏并即时修改;周二要求程序员完成模块设计并由项目经理确认,如果没有大问题,周三、周四就可让程序员编程。同时项目经理准备测试案例,周五完成测试;一般经过需求、设计确认,如果程序员合格则不会有太大问题,周末可以休息了。
第二种方式增加了“需求”和“设计” 两个里程碑,这看似增加了额外工作,但其实有很大意义:首先,对一些复杂的项目,需要逐步逼近目标,里程碑产出的中间“交付物” 是每一步逼近的结果,也是控制的对象。如果没有里程碑,中间想知道“他们做的怎么样了” 是很困难的。其次,可以降低项目风险。通过早期评审可以提前发现需求和设计中的问题,降低后期修改和返工的可能性。另外,还可根据每个阶段产出结果分期确认收入,避免血本无归。第三,一般人在工作时都有“前松后紧”的习惯,而里程碑强制规定在某段时间做什么,从而合理分配工作,细化管理“粒度”。

基线

指一个(或一组)配置项在项目生命周期的不同时间点上通过正式评审而进入正式受控的一种状态。基线其实是一些重要的里程碑,但相关交付物要通过正式评审并作为后续工作的基准和出发点。基线一旦建立后变化需要受控制。
重要的检查点是里程碑,重要的需要客户确认的里程碑,就是基线。
在我们实际的项目中,周例会是检查点的表现形式,高层的阶段汇报会是基线的表现形式。

质量可控
项目质量可控,则是靠建立完善的流程规范,从分析到建模,从编码到测试,再到最后的交付,都要有一套质量可控的规范在运作,它们描述什么人(Who)需要再项目的每个部分做什么(What)。

需求分析

需求分析指的是在建立一个新的或改变一个现存的电脑系统时描写新系统的目的、范围、定义和功能时所要做的所有的工作。需求分析是软件工程中的一个关键过程。在这个过程中,系统分析员和软件工程师确定顾客的需要。只有在确定了这些需要后他们才能够分析和寻求新系统的解决方法。
只有通过正确的需求分析,才能提炼出客户需求中的对象及数据,以及功能,这是进行开发的关键所在,保证需求分析的质量是保证整个软件工程质量的基础保证。

系统建模

软件工程中的系统建模是指,将需求分析所得到的系统中的对象、数据、功能进行合理的设计、整合,得出满足客户需求的以用代码实现的系统模型。
系统建模的质量决定了系统实现出来的质量,可扩展性、高可用性、系统整体效率都是在系统建模这一层就已经固化,因而系统建模是保证软件质量的最核心部分!

程序编码

无论再好的设计,都是需要靠最终的代码来实现,编码的质量和规范,决定了代码的可读性和可修改性已经程序的效率。
编码中需要有注释规范、排版规范、命名规范、优化规范等等组成,有了这些规范,才能保证每个参与系统开发的人之间代码可以交流,有良好的可维护性。
例如在我实习公司的开发中,我们指定了通用于HTML、JavaScript、Java、PHPSQL等语言的标准命名规范和标准注释规范,这样即使跨不同的语言可以读懂变量及函数的含义,具有两好的可读性,保证代码可维护。另外我们还制定了适用于各种不同语言的排版规范,通过良好的排版,代码的可读性会大大增加,后来的维护人员更容易看懂代码。

系统测试

系统测试是项目进程中的重要部分,测试是保证代码质量的最后一关,编码过程中出现的问题都靠测试环节进行检查。
系统测试分为:单元测试、功能测试、系统集成测试。
单元测试是在软件开发过程中要进行的最低级别的测试活动,在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
功能测试是根据产品特征、操作描述和用户方案,测试一个产品的特性和可操作行为以确定它们满足设计需求。本地化软件的功能测试,用于验证应用程序或网站对目标用户能正确工作。使用适当的平台、浏览器和测试脚本,以保证目标用户的体验将足够好,就像应用程序是专门为该市场开发的一样。 功能测试也叫黑盒子测试或数据驱动测试,只需考虑各个功能,不需要考虑整个软件的内部结构及代码。一般从软件产品的界面、架构出发,按照需求编写出来的测试用例,输入数据在预期结果和实际结果之间进行评测,进而提出更加使产品达到用户使用的要求。
集成测试是在单元测试的基础上,将所有模块按照设计要求,如根据结构图,组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。程序在某些局部反映不出来的问题,在全局上很可能暴露出来,影响功能的实现。
在我实习公司的开发中,主要进行单元测试来保证代码质量,功能测试由业务人员参与,集成测试难度太大,没有进行。

系统交付

在所有的测试完成之后,就是最终的交付了。系统的交付也是需要规范的流程,打包的方式,部署的形式,版本控制,后期维护等等都需要全面的考虑,才能保证客户获得的是高质量的软件。

  项目管理的可控性讨论.pdf (389.7 KiB, 2,217 hits)

每周推特 2010-03-28

3 月 28th, 2010 | Posted by | Filed under 生活轨迹
  • Code Bubbles,为什么没有下载的地址 #
  • 我的博客PR是0,内容有这么差么……飙泪…… #
  • 要在笔记本上装MacOS,不在虚拟机里玩了 #
  • 我的X200啥时候能到我手上哇…… #
  • 我的X200到了,试了下Ubuntu 10.04 beta,体验非常好,觉得就用Ubuntu也行,在我的神舟破本上装个Mac装B好了 #
  • @newcomer2009 公司配的 in reply to newcomer2009 #
  • RT @Fenng:Digg 用客户端排序,而非服务器端排序,据说性能提升了 40 倍 #
  • 折腾Gentoo…… #
  • Linux内核编译ing…… #
  • 经过不断地尝试,终于编译出3M的内核,可以启动我的X200 #
  • 工作也是个调度问题,按优先级排队,分片集中操作,减少任务的切换,可以有效提高工作效率。 #
  • Gentoo真的非常好用,稍微改动一下影响不大的Linux源码,加入个性化定制,编译出的内核只有3M. #
  • 原来xorg -config后黑屏是正常了,难怪我把日志看了一遍都没发现一个error,Xorg能不能设计得像个人类使用的东西,鬼知道黑屏就是正常啊…… #
  • 2005年:人民网发表《云南:遭遇罕见大旱 农民照样增收》。2006年:中新社发表《云南遭遇20年来最严重旱情 被指是山火频袭主因 》。2009年:中国新闻网发表《云南高温大旱 滇池水位急降》。2010年:《云南五十年一遇大旱旱情持续 各界捐款力挺灾区》。 #
  • 2005年:新华网《天降大旱 地质科技引来“保苗水”》。2009年:新华网《云南:灾年粮食获丰收 持续15年增产》。2010年:《西南大旱超五千万人受灾 灾民吃野菜充饥》。这是为什么捏? #
  • 政府撒谎也要查下记录,这忽悠傻子呢…… #
  • 巨多的SQL审核练就了在大脑中生成执行计划的能力…… #
  • RT @newsinchina: RT @love_stef: 本来就是这样啊。我们学校的校园网20元套餐只能访问国内IP和少数国外网站。50的才能有国际网访问权限//如果这是中国大学的普遍现象,那教育部那些叉叉们还梦想着建设世界一流大学//我们也是不一样的价,一流大学做梦去吧 #
  • 用Gentoo唯一的不爽就是无止境的编译,不过对我这种编译控,这是一种乐趣~ #
  • RT @virushuo: 不会这就打起来了吧?这样打下去朝鲜人民比我们先解放啊,太令人不平衡了。 #
  • RT @blogtd: _3月27日的“地球一小时”关灯活动偶们干嘛好呢?_当然是做爱做的事啦!_你坏!那剩下那55分钟呢?_-__-/// #
  • RT @rtmeme: RT @heartboy3 RT @kalhaslichking: 大新闻!我刚刚看的韩国电视SBS台,下面有个字幕!是紧急新闻!刚才朝鲜发动偷袭,击沉韩国军舰,韩国死亡45人,59人幸存,青瓦台召开紧急安全会议!via baidu //国军也得学学 #
  • RT @digitalboy: #20156
    标签:

计数表的技巧

3 月 21st, 2010 | Posted by | Filed under 未分类

对于InnoDB及其他一些不能很快统计行数的存储引擎,对于频繁的count(*)操作,就是一种噩梦了,它可能要遍历一遍索引或者数据行才能知道有多少行。

这种时候我们比较容易想到的方法就是设计一个计数表,每次增删记录,就更新这个表:

CREATE TABLE cnt_tbl (
    tbl VARCHAR(20) NOT NULL PRIMARY KEY COMMENT '表名',
    cnt INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '计数'
);

先为要计数的表初始化

INSERT INTO cnt_tbl(tbl, cnt) VALUES('A', 0);

每当A表做一次INSERT,就更新一次计数表

UPDATE cnt_tbl SET cnt = cnt+1 WHERE tbl = 'A';

每当A表做一次DELETE,也更新一次计数表

UPDATE cnt_tbl SET cnt = cnt-1 WHERE tbl = 'A';

需要查询计数时只要做一次查表:

SELECT cnt FROM cnt_tbl WHERE tbl = 'A';

这种方法看似很好,但是如果A表更新频繁,计数表本身会成为一个悲剧。

于是我们做一个小改进,把更新的压力分散到多行,计数的时候做个SUM(需要支持行锁的数据库或存储引擎):

CREATE TABLE cnt_tbl (
    tbl VARCHAR(20) NOT NULL COMMENT '表名',
    slt TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '多个计数槽',
    cnt INT NOT NULL DEFAULT 0 COMMENT '计数',
    PRIMARY KEY (tbl, slt)
);

这里我去掉了cnt列的UNSIGNED属性,为什么呢?因为这里会随机选一个计数槽更新,可能这个槽还没有被+1,但是已经被-1了,于是就有了负数。
可以先初始化256个计数槽

从INSERT INTO cnt_tbl(tbl, slt, cnt) VALUES('A',0,0)
到INSERT INTO cnt_tbl(tbl, slt, cnt) VALUES('A',255,0)

也可以写存储过程一次性搞定。
每当A表做一次INSERT,选择一个槽更新一次计数表

UPDATE cnt_tbl SET cnt = cnt+1 WHERE tbl = 'A' AND slt = RAND()*255;

每当A表做一次DELETE,选择一个槽更新一次计数表

UPDATE cnt_tbl SET cnt = cnt-1 WHERE tbl = 'A' AND slt = RAND()*255;

需要查询计数时需要做一次和:

SELECT SUM(cnt) FROM cnt_tbl WHERE tbl = 'A';

这样已经可以比较分散压力了,但是经常我们count(*)的时候是带有条件的,这又怎么处理呢?

对于带有条件的count(*),假设我们需要按天计数,例如:

SELECT count(*) FROM A WHERE time BETWEEN '2010-03-21' AND '2010-03-22';

我们可以对计数表再做个改进,以达到这个目的:

CREATE TABLE cnt_tbl (
    tbl VARCHAR(20) NOT NULL COMMENT '表名',
    time DATE NOT NULL DEFAULT '0000-00-00' COMMENT 'WHERE条件',
    slt TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '多个计数槽',
    cnt INT NOT NULL DEFAULT 0 COMMENT '计数',
    PRIMARY KEY (tbl, time, slt),
    KEY (time)
);

这种情况下不可能预先插入行的,所以采用ON DUPLICATE KEY UPDATE
每当A表做一次INSERT,选择一个槽更新一次计数表

INSERT INTO cnt_tbl(tbl, time, slt, cnt) 
VALUES('A', CURRENT_DATE(), RAND()*255, 1)
ON DUPLICATE KEY UPDATE cnt = cnt+1;

每当A表做一次DELETE,选择一个槽更新一次计数表

INSERT INTO cnt_tbl(tbl, time, slt, cnt) 
VALUES('A', CURRENT_DATE(), RAND()*255, 1)
ON DUPLICATE KEY UPDATE cnt = cnt-1;

查询某个时间段的计数就可以这么做

SELECT SUM(cnt) FROM cnt_tbl WHERE time BETWEEN '2010-03-21' AND '2010-03-22';

如果需要其他WHERE条件,也可以利用这个思路相应的修改字段。
如果数据已经过期,不再被UPDATE,也可以考虑把它所有的计数槽合并到一个计数槽中,例如slt=0的槽,这样可以减少表的行数。

每周推特 2010-03-21

3 月 21st, 2010 | Posted by | Filed under 生活轨迹
  • 看了公司的机房,好壮观,主力服务器好庞大 #
  • 看旺旺的文章还是有不少看不懂,作为OCP我内牛满面…… #
  • 这几天做梦都是梦见我造出的智能机器反过来K我,早上起来背上一身汗,靠~ #
  • 发现163邮箱的登陆页面做了小小的改动,像iPhone一样会显示最后一位输入的密码,这样不错 #
  • @whitepoplar 可以在sql文件中加一个use db就行了呀。 in reply to whitepoplar #
  • MySQL的索引策略令我想砸了电脑,白痴都知道要走索引 #
  • 分页是一个很麻烦的业务,很容易产生性能瓶颈,最好能想出好的呈现方式,把分页这种操作消除掉,UED应该想想 #
  • 没工作不光荣是正确的,没钱不光荣是民族观念的扭曲 #
  • timestamp类型竟然不能创建分区,改成datetime就OK,我汗 #
  • @heysql MySQL提示依赖随机和时区的函数不能作为分区函数。 in reply to heysql #
  • 阅读全文…

标签:

MySQL索引与存储方式对性能的影响

3 月 20th, 2010 | Posted by | Filed under 未分类

本文配图来自《高性能MySQL(第二版)》。

在数据库中,对性能影响最大的几个策略包括数据库的锁策略、缓存策略、索引策略、存储策略、执行计划优化策略。
索引策略决定数据库快速定位数据的效率,存储策略决定数据持久化的效率。
MySQL中两大主要存储引擎MyISAM和InnoDB采用了不同的索引和存储策略,本文将分析它们的异同和性能。

MySQL主要提供2种方式的索引:B-Tree(包括B+Tree)索引,Hash索引。
B树索引具有范围查找和前缀查找的能力,对于N节点的B树,检索一条记录的复杂度为O(LogN)。
哈希索引只能做等于查找,但是无论多大的Hash表,查找复杂度都是O(1)。
显然,如果值的差异性大,并且以等于查找为主,Hash索引是更高效的选择,它有O(1)的查找复杂度。如果值的差异性相对较差,并且以范围查找为主,B树是更好的选择,它支持范围查找。

阅读全文…