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

2007年9月20日星期四

如何编写代码才能使得效率高

如何编写代码才能使得效率高

一、排版:
  1.关键词和操作符之间加适当的空格。
  2.相对独立的程序块与块之间加空行
  3.较长的语句、表达式等要分成多行书写。
  4.划分出的新行要进行适应的缩进,使排版整齐,语句可读。
  5.长表达式要在低优先级操作符处划分新行,操作符放在新行之首。
  6.循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分。
  7.若函数或过程中的参数较长,则要进行适当的划分。
  8.不允许把多个短语句写在一行中,即一行只写一条语句。
  9.函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格。
  10.C/C++语言是用大括号‘{’和‘}’界定一段程序块的,编写程序块时‘{’和
   ‘}’应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体
    的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、
    switch、case语句中的程序都要采用如上的缩进方式。

二、注释
  1.注释要简单明了。
  2.边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。
  3.在必要的地方注释,注释量要适中。注释的内容要清楚、明了,含义准确,防止
   注释二义性。保持注释与其描述的代码相邻,即注释的就近原则。
  4.对代码的注释应放在其上方相邻位置,不可放在下面。
  5.对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域
   的注释应放在此域的右方;同一结构中不同域的注释要对齐。
  6.变量、常量的注释应放在其上方相邻位置或右方。
  7.全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它
   以及存取时注意事项等的说明。
  8.在每个源文件的头部要有必要的注释信息,包括:文件名;版本号;作者;生成
   日期;模块功能描述(如功能、主要算法、内部各部分之间的关系、该文件与其
   它文件关系等);主要函数或过程清单及本文件历史修改记录等。
  9.在每个函数或过程的前面要有必要的注释信息,包括:函数或过程名称;功能描
   述;输入、输出及返回值说明;调用关系及被调用关系说明等。

三、命名
  1.较短的单词可通过去掉“元音”形成缩写;
  2.较长的单词可取单词的头几发符的优先级,并用括号明确表达式的操作顺序,避
   免使用默认优先级。
  3.使用匈牙利表示法

四、可读性
  1.避免使用不易理解的数字,用有意义的标识来替代。
  2.不要使用难懂的技巧性很高的语句。
  3.源程序中关系较为紧密的代码应尽可能相邻。

五、变量
  1.去掉没必要的公共变量。
  2.构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的公共
   变量,防止多个不同模块或函数都可以修改、创建同一公共变量的现象。
  3.仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系。
  4.明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等。
  5.当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生。
  6.防止局部变量与公共变量同名。
  7.仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减
   少引起误用现象。
  8.结构的设计要尽量考虑向前兼容和以后的版本升级,并为某些未来可能的应用保
   留余地(如预留一些空间等)。
  9.留心具体语言及编译器处理不同数据类型的原则及有关细节。
  10.严禁使用未经初始化的变量。声明变量的同时对变量进行初始化。
  11.编程时,要注意数据类型的强制转换。

六、函数、过程
  1.函数的规模尽量限制在200行以内。
  2.一个函数最好仅完成一件功能。
  3.为简单功能编写函数。
  4.函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输出。
  5.尽量不要编写依赖于其他函数内部实现的函数。
  6.避免设计多参数函数,不使用的参数从接口中去掉。
  7.用注释详细说明每个参数的作用、取值范围及参数间的关系。
  8.检查函数所有参数输入的有效性。
  9.检查函数所有非参数输入的有效性,如数据文件、公共变量等。
  10.函数名应准确描述函数的功能。
  11.避免使用无意义或含义不清的动词为函数命名
  12.函数的返回值要清楚、明了,让使用者不容易忽视错误情况。
  13/明确函数功能,精确(而不是近似)地实现函数设计。
  14.减少函数本身或函数间的递归调用。
  15.编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作)
    等手段对其加以保护。

七、可测性
  1.在编写代码之前,应预先设计好程序调试与测试的方法和手段,并设计好各种调
  测开关及相应测试代码如打印函数等。
  2.在进行集成测试/系统联调之前,要构造好测试环境、测试项目及测试用例,同时
  仔细分析并优化测试用例,以提高测试效率。

八、程序效率
  1.编程时要经常注意代码的效率。
  2.在保证软件系统的正确性、稳定性、可读性及可测性的前提下,提高代码效率。
  3.不能一味地追求代码效率,而对软件的正确性、稳定性、可读性及可测性造成影
   响。
  4.编程时,要随时留心代码效率;优化代码时,要考虑周全。
  5.要仔细地构造或直接用汇编编写调用频繁或性能要求极高的函数。
  6.通过对系统数据结构划分与组织的改进,以及对程序算法的优化来提高空间效率。
  7.在多重循环中,应将最忙的循环放在最内层。
  8.尽量减少循环嵌套层次。
  9.避免循环体内含判断语句,应将循环语句置于判断语句的代码块之中。
  10.尽量用乘法或其它方法代替除法,特别是浮点运算中的除法。

九、质量保证
  1.在软件设计过程中构筑软件质量。
  代码质量保证优先原则
  (1)正确性,指程序要实现设计要求的功能。
  (2)稳定性、安全性,指程序稳定、可靠、安全。
  (3)可测试性,指程序要具有良好的可测试性。
  (4)规范/可读性,指程序书写风格、命名规则等要符合规范。
  (5)全局效率,指软件系统的整体效率。
  (6)局部效率,指某个模块/子模块/函数的本身效率。
  (7)个人表达方式/个人方便性,指个人编程习惯。
  2.只引用属于自己的存贮空间。
  3.防止引用已经释放的内存空间。
  4.过程/函数中分配的内存,在过程/函数退出之前要释放。
  5.过程/函数中申请的(为打开文件而使用的)文件句柄,在过程/函数退出前要关闭。
  6.防止内存操作越界。
  7.时刻注意表达式是否会上溢、下溢。
  8.认真处理程序所能遇到的各种出错情况。
  9.系统运行之初,要初始化有关变量及运行环境,防止未经初始化的变量被引用。
  10.系统运行之初,要对加载到系统中的数据进行一致性检查。
  11.严禁随意更改其它模块或系统的有关设置和配置。
  12.不能随意改变与其它模块的接口。
  13.充分了解系统的接口之后,再使用系统提供的功能。
  14.要时刻注意易混淆的操作符。当编完程序后,应从头至尾检查一遍这些操作符。
  15.不使用与硬件或操作系统关系很大的语句,而使用建议的标准语句。
  16.建议:使用第三方提供的软件开发工具包或控件时,要注意以下几点:
  (1)充分了解应用接口、使用环境及使用时注意事项。
  (2)不能过分相信其正确性。
  (3)除非必要,不要使用不熟悉的第三方工具包与控件。

十、代码编译
  1.编写代码时要注意随时保存,并定期备份,防止由于断电、硬盘损坏等原因造成
   代码丢失。
  2.同一项目组内,最好使用相同的编辑器,并使用相同的设置选项。
  3.合理地设计软件系统目录,方便开发人员使用。
  4.打开编译器的所有告警开关对程序进行编译。
  5.在同一项目组或产品组中,要统一编译开关选项。
  6.使用工具软件(如Visual SourceSafe)对代码版本进行维护。

十一、代码测试、维护
  1.单元测试要求至少达到语句覆盖。
  2.单元测试开始要跟踪每一条语句,并观察数据流及变量的变化。
  3.清理、整理或优化后的代码要经过审查及测试。
  4.代码版本升级要经过严格测试。

2007年9月10日星期一

Apache+Tomcat中支持“UTF-8”编码的中文地址

Apache+Tomcat中支持“UTF-8”编码的中文地址

  Tomcat默认安装时,是8080端口。这时,要使Tomcat支持“UTF-8”的中文地址,只需要在server.xml文件中,将8080端口的标签设置成URIEncoding="UTF-8":

<Connector port="8080" URIEncoding="UTF-8" />

  当Tomcat用JK与Apache集成时,用works.properties文件来配置Apache和tomcat连接时使用的一些参数。其中包括Apache要使用的Tomcat端口:

worker.list=ajp13
worker
.ajp13.port=8009
# 本机,若上面Tomcat主机不为localhost,作相应修改
worker.ajp13.host=192.168.1.5
# 类型
worker.ajp13.type=ajp13
# 代理数,不用修改
worker.ajp13.lbfactor=1

  文件中“rker.ajp13.port=8009”就是用来设置Apache要连接的Tomcat端口。因此,Apache和Tomcat集成后,要使服务器支持UTF-8的中文地址,应该设置8009端口的标签:

<Connector port="8009" URIEncoding="UTF-8" />

2007年8月10日星期五

Visual C++ 编码规范

1.说明

执行本规范的目的在于保证编码的规范性、和确保代码质量,提高软件代码的可读性、可修改性,避免在开发和调试过程中出现不必要的麻烦。此外,还可以统一代码风格,便于研发人员之间的技术交流。

2.适用范围

本标准适用于使用Visual C++进行软件程序开发的人员。

3.编码的基本要求

n 程序结构清晰,逐步求精,单个函数的程序行数一般不超过100行。

n 代码精简,避免编码拖沓冗长。

n 尽量使用标准库函数和公共函数。

n 不要随意定义全局变量,尽量使用局部变量、类的成员变量。

n 表达式复杂时,多使用括号以避免二义性。

3.1可读性

n 可读性第一,效率第二。

n 保持注释与代码完全一致。

n 每个源程序文件,都有文件头说明,说明规格见规范。

n 每个函数,都有函数头说明,说明规格见规范。

n 主要变量(结构、联合、类或对象)定义或引用时,注释能反映其含义。

n 常量定义(DEFINE)有相应说明。

n 处理过程的每个阶段都有相关注释说明。

n 在典型算法前都有注释。

n 利用缩进来显示程序的逻辑结构,缩进量一致并以空格键为单位,定义为 4个
字节,不建议用Tab键。

n 循环、分支层次不要超过五层。必要时,使用Goto 语句,减少层次。

n 注释可以与语句在同一行,也可以在上行。

n 空行和空白字符也是一种特殊注释。

n 一目了然的语句不加注释。

n 注释的作用范围可以为:定义、引用、条件分支以及一段代码。

n 注释行数(不包括程序头和函数头说明部份)应占总行数的 1/5 到 1/3 。

3.2结构化要求

n 代码严格缩进,缩进使用TAB键,设置TAB键等价于4个空格字符。

n 禁止出现两条等价的支路。

n 减少使用GOTO语句。为减少IF语句层次,也可以适当使用。

n CASE 实现多路分支。减少使用 ELSE IF句型。

n 避免从循环引出多个出口。

n 函数一般只有一个出口。为减少判断语句层次,可适当使用GOTO 语句。

n 不使用条件赋值语句。 如:if (a=b) …

n 不要轻易用条件分支去替换逻辑表达式。

n 考虑到代码量和可阅读性,有如下编码建议(非强制性规范):

1)减少括号的使用

if (!m_bIsOpen ) return FALSE;

如果写成,将大大增代码量,函数体代码语句多的时候不利于阅读:

if (!m_bIsOpen )

{

return FALSE;

}

else

{

// ......

}

2)使用GOTO语句减少语句层次

下面是函数体,使用GOTO语句减少代码层次的例子

该例子如使用IF语句做整体判断则明显增加代码缩进的层次。

{

if ( 条件不满足1 )

{

iret = -1;

goto label_end;

}

if ( 条件不满足2 )

{

iret = -2;

goto label_end;

}

label_end:

// ... ...

return iret;

}

3.3正确性与容错性要求

n 程序首先是正确,其次是才是优美。

n 无法证明你的程序没有错误,因此在编写完一段程序后,应先回头检查。

n 改一个错误时可能产生新的错误,因此在修改前首先考虑对其它程序的影响。

n 所有变量在调用前必须被初始化。数组、结构体要ZeroMemory 初始化。

n 对所有的用户输入,必须进行合法性检查。

n 不要比较浮点数的相等,如: 10.0 * 0.1 == 1.0 , 不可靠

n 程序与环境或状态发生关系时,必须主动去处理发生的意外事件,如文件能否逻辑锁定、打印机是否联机等。

n 单元测试也是编程的一部份,提交联调测试的程序必须先由程序员经过单元测试。

3.4可重用性要求

n 重复使用的、相对独立功能的算法或代码应抽象为公共控件或类。

n 公共控件或类应考虑使用OO编程思想,减少外界联系,考虑独立性和封装性。

n 公共控件或类应建立使用模板。

n 一些涉及到商业机密或者公司核心技术的部件,可使用DLL或者COM组件的形式对公用模块进行封装。

4. C++代码书写规范

4.1文件头的编写规范

每个文件开头部分至少应当包括下面几项内容:文件标题(Title )、版权说明(Copyright)、修改记录(Modification History)。

n Title 中包括文件的名称和文件的简单说明。Title 应该在一行内完成。

n Copyright 包括一个版权说明。

例如:

// Copyright (c) 2005 EASTCOM LingTong.

// All rights reserved.

n Modification History

记录文件修改的过程,只记录最主要的修改。当书写新的函数模块时,只需要使用

形如“add func1()”这样的说明;如果后面又对函数中的算法进行了修改,需要指出修改

的具体位置和修改方法。

Modification History 的具体格式为:

<版本号> <修改日期> < 修改人和修改动作>

如:

// V0.9.0 20050823 创建初始版本

// V0.9.1 20050830 修改结构体项目对齐方式为默认

一个文件头的具体范例如下:

//////////////////////////////////////////////////////////////////////

//

// Copyright (c) 2005 EASTCOM LingTong.

// All rights reserved.

//

// 文件名 CCFrmw.h

// 类型 HPP

// 版本号 0.9.1

// 编制 Trueway Lee

// 描述 用于实现 ABWOA 模块DLL

// 该模块内部实现了 EASTCOM-ABWOA 软件总线机制

//

//--------------------------------------------------------------------

// 版本历史

//--------------------------------------------------------------------

// V0.9.0 20050823 创建初始版本

// V0.9.1 20050830 修改结构体项目对齐方式为默认

//

//////////////////////////////////////////////////////////////////////

4.2变量命名

为了便于程序的阅读,变量命名必须具有一定的实际意义。

变量命名按照匈牙利命令风格:形式为xAbcFghx由变量类型确定,AbcFgh表示连续意义字符串,如果连续意义字符串仅两个,可都大写。如OK。

下面是常规数据类型的变量命名方法:

类型名

C/C++ 等价类型

定义实例

BOOL

int

BOOL fFlag

LPSTR

char *

LPSTR szText

HANDLE

void *

HANDLE hEvent1

HWND

void *

HWND hWnd

INT

int

INT iIndex

UINT

unsigned int

UINT nIndex

LPVOID

void *

LPVOID pData

WORD

unsigned short

WORD wData

DWORD

unsigned long

DWORD dwData

BYTE

unsigned char

BYTE bChar

CHAR

char

CHAR cChar

LONG

long

LONG lIndex

ULONG

unsigned long

ULONG ulData

WPARAM

unsigned int

WPARAM wParam

LPARAM

long

LPARAM lParam

这里只是列举了一部分,更详细的内容请查看 MSDN 文档。

4.3各作用域变量命名规则

n 全局变量(g_类型、)

“g_” + “类型标识”+“变量名”

例如:g_nMsg、g_bFlag

n 类成员变量(m_xxxx)

“m_” + “类型标识”+“变量名”

例如:m_szText、m_hEvent

n 局部变量

“类型标识”+“变量名”

局部变量中可采用如下几个通用变量:nTemp,iRet,I,J(一般用于循环变量)。

n 函数参数变量,参数变量是局部变量的特例

a_” +“类型标识”+“变量名”

例如:int test_fun(long a_lMode, LPSTR a_szData);

4.4常量命名和宏定义

下面是常量和宏定义方面的一般规则:

n 常量和宏定义必须具有一定的实际意义;

n 常量和宏定义在 #include 和函数定义之间;

n 常量和宏定义一般全部以大写字母来撰写,中间可根据意义的连续性用下划线连接,每一条定义的右侧必须有一简单的注释,说明其作用。

#define _POSIX_ARG_MAX 4096

#define _POSIX_CHILD_MAX 6

#define _POSIX_LINK_MAX 8

#define _POSIX_MAX_CANON 255

#define _POSIX_MAX_INPUT 255

#define _POSIX_NAME_MAX 14

考虑到阅读的方便性,也可以使用大小写混合的形式定义常量,但第一段必须是大写,标识该常量的使用访问或者类别。

#define ERROR_SSIPC_Name_Error (-1)

#define ERROR_SSIPC_Time_Out (-2)

#define ERROR_SSIPC_Call_Failture (-3)

#define ERROR_SSIPC_Pack_Data (-4)

n 资源名字定义格式:
菜单:IDM_XX或者CM_XX
位图:IDB_XX
对话框:IDD_XX
字符串:IDS_XX
DLGINIT:DIALOG_XX
ICON:IDR_XX

4.5函数命名

n 函数原型说明包括引用外来函数及内部函数,外部引用须在右侧注明函数来源:模
块名及文件名, 如是内部函数,不需要特殊说明。

n 函数名第一个字母大写,其他部分要求用大小写字母组合命名。

必要时可用下划线间隔。

示例如下:

extern void UpdateDB_Tfgd (TRACK_NAME) //Module Name r01/sdw.c
extern PrintTrackData (TRACK_NAME)
//Module Name
r04/tern.c
extern ImportantPoint (void)
//Module Name
r01/sdw.c
void ShowChar (int
int long)

void ScrollUp_V (int
int)

4.6结构体

n 结构体类型命名使用大写字母,原则上前面以下划线开始;

n 结构体变量用大小写字母组合,第一个字母大写,必要时可用下划线间隔;

n 对于私有数据区,须注明其所属的进程。全局数据定义只需注明其用途。


示例如下:
typedef struct
{
char szProductName[20]

char szAuthor[20]

char szReleaseDate[16]

char szVersion[10]

unsigned long MaxTables

unsigned long UsedTables

}DBS_DATABASE, * LPDBS_DATABASE

DBS_DATABASE g_dataBase

4.7控件的命名

用小写前缀表示类别
fm 窗口
cmd 按钮
cob combo,下拉式列表框
txt 文本输入框
lab label,标签
img image,图象
pic picture
grd Grid,网格
scr 滚动条
lst 列表框
frm fram

控件命名可以为:

n 小写类别+大小写混合的控件标识

n 小写类别+“__”+ 控件标识

比如: labText、lab_text 都可以。

4.8注释

n 原则上注释要求使用中文;

n 文件开始注释内容包括:公司名称、版权、作者名称、时间、模块用途、背景介绍等;

n 复杂的算法需要加上流程说明;

n 函数注释包括:输入、输出、函数描述、流程处理、全局变量、调用样例等;

n 复杂的函数需要加上变量用途说明;

n 程序中注释(阶段注释)包括:修改时间和作者、方便理解的注释等;

注释主要分为三类,文件头注释、函数体内阶段注释、函数注释

引用一: 文件开头的注释模板

//////////////////////////////////////////////////////////////////////

//

// Copyright (c) 2005 EASTCOM LingTong.

// All rights reserved.

//

// 文件名: cccdmfw_xpp.h

// 类型: XPP

// 版本号: 0.1

// 编制: jjt

// 描述: 用于实现 ABWOA 出钞机构模块定义

// 该模块内部实现了 EASTCOM-ABWOA 模块出钞机构的动作,

// 基于ABWOA模块的出钞机构CCCdmFW类定义

//

//--------------------------------------------------------------------

// 版本历史:

//--------------------------------------------------------------------

// V0.1 2005-9-22 10:30 创建初始版本

//

//

//////////////////////////////////////////////////////////////////////


引用二: 程序中的注释模板

if ( ( pBuff->sCallType == SWBUS_Asynchronization_Mode ) &&

( pBuff->pJobState ) )

pBuff->pJobState->sJobState = CCFRMW_JOB_RUNNING;// 设置任务状态

//---------------------------------------------------------------------

// 获得模块信息

//---------------------------------------------------------------------

LPMYMODULENODE lpInfo = NULL;

int iret = g_load.GetModuleInfo(pBuff->szFWName, &lpInfo);

if ( iret != CCFRMW_RC_OK ) return iret;

//---------------------------------------------------------------------

// 获得模块相关的对象信息(找到最后的子类,作为服务对象)

//---------------------------------------------------------------------

LPMYMODULEDETAIL lpDetail = NULL;

iret = g_load.GetFirstObjectInfo(lpInfo, &lpDetail);

if ( iret != CCFRMW_RC_OK ) return iret;


引用三: 函数开头的注释模板,考虑到编码的方便性,函数注释可以简单一点

// 获得DD变量值

SHORT CCDataDicFW::GetDataItem( // get the data item - USHORT

CHAR * pszDataItemName, // (in) property name

USHORT & rusVar, // (out) buffer for retrieved data

ULONG ulIndex) // (in) index (used for indexing arrays)

{

SHORT sRc = CCDATADICTFW_OK;

char ownerFW[NODE_VALUE_LEN];

SHORT funcId;

TrcWritef(TRC_ENTRY,"> CCDataDicFW::GetDataItem(%s)",pszDataItemName);

sRc = GetDataInfo(GET,ownerFW,funcId,pszDataItemName);

if(sRc == CCDATADICTFW_OK)

{

sRc = FrmResolve(ownerFW,funcId, pszDataItemName, strlen(pszDataItemName)+1, (void *)&rusVar, sizeof(USHORT), NULL, 0, ulIndex);

}

TrcWritef(TRC_ENTRY,"<>

return sRc;

}

4.9 限制使用全局变量

考虑到代码移植方面和出现信息存贮冲突,在代码中,避免使用全局变量。

可以进行替代:

n 使用类的成员变量

n 使用类的静态变量

n 线程入口函数使用参数传递指针

n 一些不能避免的情况,如:WINPROC 中的变量访问,仍可以使用全局变量。

4.10 数据初始化

与很多语言不同,C/C++一般不提供对结构体变量、字符数组、整形等数据的初始化控制。比如 integer I; 此语句执行后,I 里面的值是一个随机数字。

char buff[100]; 执行后,buff 的每个单元的内容也是一个随机值。

为了避免出现问题,要求变量申明后,一定要初始化,这里还包括了类的成员变量。

比如:

char buff[100];

ZeroMemory(buff, sizeof(buff));

下面针对各类数据类型做数据初始化的规范说明:

n 简单类型数据,需要在变量标识后加“=初始值;”

integer i = 0;

char c = 0;

double d = 12.0;

n 指针变量、类似指针的变量,在申请内存前和使用完成后,都要使值保持NULL

HANDLE p = NULL;

// ......

if (p )

{

CloseHandle(p);

p = NULL;

}

n 字符数组,注意{0} 的妙用

char buff[100];

ZeroMemory(buff, sizeof(buff));

也可以写成一句话:

char buff[100] ={0};

n 结构体变量,注意{0} 的妙用

MYSTRUCTA bb;

ZeroMemory(&bb, sizeof(MYSTRUCTA ));

也可以写成一句话:

MYSTRUCTA bb = {0};

n C++类中,在类的构造子中完成对成员变量数据的初始化

5.调试规范

5.1 Trace跟踪

n 程序中应该包括足够的调试信息。调试信息一律使用Trace跟踪。

n 在函数入口处,推荐使用assert() 对于参数的有效性进行判断。

n 对于入口参数是指针的,必须使用Assert()进行判断。

n assert()的使用方法为:assert(<逻辑表达式>)assert()的具体使用方法请参考MSDN文档,这里不做详细说明。

n 在代码中易出现问题的地方,也应该使用assert()、或者其他的机制进行相应的检测。

5.2调试记录、测试报告

调试记录是软件产品的一个重要组成部分。在软件的调试过程中,应做好调试记录,以便于软件的后续开发和维护工作。

调试的文档包括两个内容:

n 调试记录

即发现软件中的Bug 并进行修改的记录。

在软件编码过程中的修改很频繁,对每个发现的问题都记录下来是不现实的。在实际记录过程中可选择以下信息的部分作为记录内容,调试记录一般需要包括如下内容:

(日期)

[如:2000 6 26 ]

(问题编号)

[如:1]

(问题征兆)

[如:发现缓冲中的报文被无端修改]

(问题根源及解决方法)

[如:由于在多任务环境中对共享资源没有使用互斥机制,对于缓冲增加一个信号量进行保护(修改位于buffer.c 中)]

n 测试报告

在软件项目实现阶段,除了要编写好代码以外,经常需要对实现的子模块进行测试,尤其是对提供给他人使用的模块,必须进行测试。

在测试前,需要做测试计划,测试中做好零散的记录,测试完成后,整理成报告。测试报告是一笔宝贵的财富,当软件做到一定程度的功能,以后对软件的更新,可以参照历史测试报告进行回归测试。减少重新编制测试报告的工作量,同时能保存测试指标,使软件再测试具有延续性。

5.3测试用例、测试代码

为使测试自动化和更具全面性,需花费时间和精力制作测试用例和编写测试代码,比如测试类的功能,就需要编写测试代码。

测试用例需要按照软件工程学的相关规范来制作。最简单的原则是,测试用例要能覆盖问题可能出现的范围。详细测试用例的制作方法参考软件工程学资料。

测试代码需要实现对单个模块的模拟调用,在整个项目相关的软件模块并为一一齐备的情况下,也需要模拟实现未真正实现的功能模块。此外,测试代码还可以用于构建软件模块的压力测试、内存泄漏测试。

5.4调试、测试要求

n 对于测试代码和测试用例,要注意保存,并适当使用文档加以说明。

文档中应该说明测试代码的测试目的。如果测试代码和文档分别存放,还需要在文档中对测试代码的保存位置加以说明。

n 写好测试报告。例如:对某个模块的若干接口加以测试,要记录测试的目的、具体的测试方法和测试的结果(如:通过测试,或测试失败)。

n 出现问题,及时通知相关模块具体负责人。

测试人员在测出问题后,除完成测试报告外,还需要和模块负责人进行必要的沟通。

6.源码管理办法

1. 修改及时提交

源码完成编制、修改后,须提交到配置库。使用指定的版本管理软件实施控制。

当某功能模块完成编程后,使用软件管理工具提交。在进行提交之前,必须对新加入的功能进行一定的测试,在尽量保证正确性后在进行提交。

避免出现长时间修改而不提交的情况,因为可能出现多人修改同一模块的情况。长时间不提交将导致并发的修改方每次修改前不能获得最新的版本。

2. 提交要完整

每次提交,要注意完成性,把本次涉及到的修改都做提交,否则容易出现别处下载更新代码后不能编译、调试的情况。

3. 先更新,再修改

每次进行修改前,从配置库“Check out”最新版本到本地,以免在老版本上做修改。

4. 写修改说明

每次提交,须在提交报告中注明新加入功能的内容、修改的文件范围等内容。

5. 定期更新本地版本

需要定期对本地版本的代码、文档做全面更新,特别是在软件项目庞大或者项目组人员较多的情况下,需要定期更新本地版本,特别是非自身负责的模块,以便能在最新版本的代码上进行联合编译、调试和测试。

6. 共用的.H、.CPP、.LIB、.DLL文件单独存放

类似VC++的安装目录安排,需设置INCLUDE、LIB、SRC等共有目录,将共有代码放置其内,避免出现每个模块将共有代码放在各自的项目内的情况。

单独存放共用代码,利于统一更新。

7. 配置库中除管理源代码外,还管理 BIN 内容

阶段编译结果的EXE、DLL、OCX等内容,也作为配置项,减少不必要的重新编译。

8. 阶段成果分开保存

针对相对稳定的阶段成果,需和主配置分开保存。以避免最新的修改影响阶段成果。