您的位置:首页 > 其它

高质量软件开发之道

2013-08-30 19:42 169 查看
1. 学习"高质量编程"的目的是要在干活的时候一次性编写出高质量的程序,而不是当程序出错后再去修补

2. 十大软件质量属性包括:

正确性(Correctness): 指软件按照需求正确执行任务的能力。正确性是第一重要的软件质量属性。

健壮性(Robustness): 指在异常情况下,软件能够正常运行。健壮性包括容错能力和恢复能力。

可靠性(Reliability): 指在一定环境下,在给定的时间内,系统不发生故障的概率。

性能(Performance): 通常是指软件的时空效率。程序员可通过优化数据结构、算法和代码来提高软件的性能。

易用性(Usability): 指用户使用软件的容易程序。

清晰性(Clarity): 意味着工作成果易读、易理解。

安全性(Security): 指防止系统被非法入侵的能力,即属于技术问题又属于管理问题。

可扩展性(Extendibility): 反映软件适应“变化”的能力。“变化”指需求、设计的变化,算法的改进,程序的变化等。

兼容性(Compatibility): 指两个或以上软件交换信息的能力。新软件应与已流行的软件相兼容,否则难以被市场接受。

可移植性(Portability): 指软件运行于不同软硬件环境的能力。软件设计时应将设备相关和设备无关的程序分开,功能模

块与用户界面分开,这样可以提高软件的可移植性。

3. 软件的高生产率必须以质量合格为前提,如果质量不合格,软件产品要么卖不出去,要么卖出去了再赔偿客户的损失。这种情况下“高生产率”变得毫无意义了。从短期效益看,追求高质量可能会延长软件开发时间,一定程序上降低了生产率。从长期效益看,追求高质量将使软件开发过程更加成熟和规范化。

4. 在某个领域,当市场上只出现尚未形成竞争格局的一个或几个产品时,产品价格基本上是由厂商自己制定,这里称其为“市场价(Marketing price)”。当产品之间形成竞争时,就会出现“杀价”现象。由于各家产品的功能、质量旗鼓相当,竞争实质上是在拼成本。谁的成本低,谁就有利可图。这时的产品价格称为“成本价(Cost price)”

5. CMM(Capability Maturity Model)是用于衡量软件过程能力的标准,分为5个级别,最低为1级,最高为5级。

6. 开发高质量的软件产品必需有条理地组织技术开发活动和项目管理活动,我们把这些活动的组织形式称为过程模型。关注技术开发活动的软件开发模型有“喷泉模型”、“增量模型”、“快速原型模型”、“螺旋模型”、“迭代模型”等。SPP是一个基于CMM3的软件过程模型。

7. 复用有利于提高软件质量、提高生产率和降低成本。

8. 测试的主要目的是为了发现尽可能多的缺陷,而成功的测试在于发现了迄今尚未发现的缺陷。

9. 测试阶段: 单元测试、集成测试、系统测试、验收测试

测试方式: 白盒测试、黑盒测试

测试内容: 功能测试、健壮性测试、性能测试、用户界面测试、安全性测试、压力测试、可靠性测试、安装/反安装测试...

测试流程: 制定测试计划 -> 设计测试用例 -> 执行测试 -> 撰写测试报告 -> 修改错误(回归测试) -> 完成测试

10. 改错过程很像侦破案件,有些坏事发生了,而仅有的信息就是它的确发生了。

11. 老板给程序员发工资,并不是让他们来享受的,而是希望他们创造比工资多得多的效益。所以要求程序员“在上班时间不干与工作无关的事情”是合情合理的。

12. 如果某人在汇报工作时口齿不清、结结巴巴,虽然令听者难受,但尚可接受。倘若说话吞吞吐吐、支支吾吾,则会令人恼火。前者是表达能力差(或者生理问题)导致的,可以被原谅。而后者是工作态度差并导致的,难以被原谅。

13. 为了让会议有成效,应该先让所有与会者明白究竟要做什么。而主持人在发开会通知前,应该先问自己这样的问题:这个会议是否真的重要,即使中断很多人的工作也值得?是否没有其他不影响别人工作的方法来取代开会?这次会议的目的是什么?我该怎样做才能达到目的?如果你能清楚地回答上述问题,一般不会让会议变成漫无目的的讨论。

14. 随时随地记录你在工作中遇到的问题,以及你产生的灵感,不要等到将来再靠回忆来写总结。

15. 项目经理是企业的基层干部,是推动企业发展的中坚分子。优秀的项目经理应该有丰富的产品开发经验和较高的技术水平,懂得管事和管人,有较好的人格魅力。

16. 管理的目的是让大家一起把工作做好,并且让各人获得各自的快乐和满足。当一个团队被出色地领导时,雇员甚至不知道他们已被领导。管理者不能老惦记着自己是一个官,而应时刻意识到自己是责任的主要承担者。如果领导缺乏人格魅力,很少有人会信服你。

17. 软件开发人员的“饭碗”是技术。

18. 有一些机会是靠运气得到的,而更多的机会是自己努力创造的。其实人在任何地方、任何时候都可以学习新知识。职位低、工资少都不可怕,可怕的是丧失了进取心。

19. 不想当将军的士兵不是好士兵。同理,不想当领导的开发人员也不是优秀的开发人员。

20. 缺乏表达能力和管理能力是软件开发人员的通病,值得业界关注。

21. 在允许自由竞争的环境中,如果有人埋怨其才能被“埋没”了,通常是他自己的错。如果真有本事,你就应该自己冒出来,怎么会被“埋没”呢?难道非要等着别人来照顾你不成?

22. 导致软件项目失败的因素很多,如果不去找借口的话,就会发现错误的根源在自己身上:知识贫乏、才能低下、经验不足、骄傲自负、...

 

23. “迷信”通常是傻子碰到骗子的结果。傻是内因,骗是外因。傻子碰到好人未必能做出好事,傻子碰到另一个骗子就会做出另一件傻事。

技术与技巧



1. 布尔变量与零值比较: if(flag) 或者 if(!flag)

2. 整型变量与零值比较: if(value==0) 或者 if(value!=0)

3. 浮点变量与零值比较: 应将 if(x==0.0) 转化为 if((x>=-EPSINON) && (x<=EPSINON)),其中EPSINON是精度

4. 指针变量与零值比较: if(p==NULL) 或者 if(p!=NULL)

5. 在多重循环中,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。如:

for(col=0; col<10; col++)

if(condition)

else

class Person

Person::A(int age):AGE(age) //initialization of AGE

Person wang(30); //wang's AGE is 30

Person xiao(20); //xiao's AGE is 20

10. 如果函数参数是指针,且仅做输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。例如:

void StringCopy(char *strDestination, const char *strSource);

11. 如果输入参数以值传递的方式传递对象,则宜改用 "const &" 方式来传递,这样可以省去临时对象的构造和析构过程,从而提高效率。

12. 不要省略返回值类型,没有返回值应声明为void类型。

13. 如果函数的返回值是一个对象,有些场合用“引用传递”能提高效率,而有些场合只能用“值传递”,否则会出错。

class String

String & String::operate=(const String &other)

String String::operate+(const String &str1, const String &str2)

char a[]="hello"; //数组a的容量是6个字符,内容为hello\0

a[0]='X'; //a的内容可以改变

cout<<a<<endl;

char *p="world"; //p指向常量字符串"world",位于静态存储区,内容为world\0

p[0]='X'; //常量字符串的内容不可以修改,编译器不能发现该错误

cout<<p<<endl;

char a[]="hello";

char b[10];

strcpy(b,a); //不能用b=a;否则产生编译错误

if(strcmp(b,a)==0) //不能用if(b==a)

int len=strlen(a); //strlen字符串的长度,不包括'\0'

char *p=(char *)malloc(sizeof(char)*(len+1));

strcpy(p,a); //不要用p=a; p=a是把a的地址赋给了p,要想复制a的内容,可以先用库函数

//malloc为p申请一块容量为strlen(a)+1个字符的内存,再用strcpy进行字符串复制

if(strcmp(p,a)==0) //不能用if(b==a),它比较的是地址,不是内容

char a[]="hello world";

char *p=a;

cout<<sizeof(a)<<endl; //12字节,sizeof计算数组的容量,包括'\0'

cout<<sizeof(p)<<endl; //4字节

void Func(char a[100])

char *p=(char *)malloc(100);

strcpy(p, "hello");

free(p); //p所指的内存被释放,但是p所指的地址仍然不变,delete同理

if(p!=NULL) //没有起到防错作用

void Func(void)

void Func(void)

extern "C"

extern "C"

#include<iostream.h>

void output(int x); //函数声明

void output(float x); //函数声明

void output(int x)

void output(float x)

void main(void)

#include<iostream.h>

class Base

class Derived : public Base

void main(void)

#include<iostream.h>

class Base

class Derived : public Base

void main(void)

class Base

class Derived : public Base

void Test(void)

class Derived : public Base

class A

class B : public A

B::B(int x, int y) : A(x) //在初始化表里调用A的构造函数

class A

class B

B::B(const A &a)

:m_a(a)

B::B(const A &a)

//String的普通构造函数

String::String(const char *str)

//String的析构函数

String::~String(void)

String a("hello");

String b("world");

String c=a; //调用了拷贝构造函数,最好写成c(a);

c=b; //调用了赋值函数

类String的拷贝构造函数与赋值函数



//拷贝构造函数

String::String(const String &other)

//赋值函数

String & String::operate=(const String &other)

{

//(1)检查自赋值

if(this==&other)

return *this;

//(2)释放原有的内存资源

delete []m_data;

//(3)分配新的内存资源,并复制内容

int length=strlen(other.m_data);

m_data=new char[length+1];

strcpy(m_data, other.m_data);

//(4)返回本对象的引用

return *this;

}

类String拷贝构造函数与普通构造函数的区别是:在函数入口处无需与NULL进行比较,这是因为“引用”不可能是NULL,而“指针”可以为NULL。

类String的赋值函数比构造数复杂得多,分四步实现:

第一步:检查自赋值。防止出现间接的自赋值。如间接的内容自赋值:b=a; ... c=b; ... a=c; 间接的地址自赋值:b=&a; ... a=*b; 如果不检查自赋值,看看第二步的delete,自杀后还能复制自己吗?

第二步:用delete释放原有的内存资源。如果现在不释放,以后就没机会邓,将造成内存泄漏。

第三步:分配新的内存资源,并复制字符串。注意函数strlen返回的是有效字符长度,不包含结束符'\0'。函数strcpy则边'\0'一起复制。

第四步:返回本对象的引用,目的是为了实现像a=b=c这样的链式表达。能否写成return
other呢?效果不是一样吗?不可以!因为我们不知道参数other的生命期。有可能other是个临时对象,在赋值结束后它马上消失,那么
return other返回的将是垃圾。

来源:http://www.cnblogs.com/JCSU/articles/1083052.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: