• 9.质量保证


    1.在软件设计过程中构筑软件质量。

     

    2.代码质量保证优先原则。

    (1)正确性,指程序要实现设计要求的功能。     

    (2)稳定性、安全性,指程序稳定、可靠、安全。     

    (3)可测试性,指程序要具有良好的可测试性。     

    (4)规范/可读性,指程序书写风格、命名规则等要符合规范。     

    (5)全局效率,指软件系统的整体效率。     

    (6)局部效率,指某个模块/子模块/函数的本身效率。     

    (7)个人表达方式/个人方便性,指个人编程习惯。

    3.只引用属于自己的存储空间。

    说明:若模块封装的较好,那么一般不会发生非法引用他人的空间。

     

    4.防止引用已经释放的空间。

    说明:在实际编程过程中,稍不留心就会出现在一个模块中释放了某个内存块(如 C 语言 指针),而另一模块在随后的某个时刻又使用了它。要防止这种情况发生。

    5.过程/函数中分配的内存,在过程/函数退出之前释放。

     

    6.过程/函数中申请的(为打开文件而使用的)文件句柄,在过程/函数退出之前要关闭。

    说明:分配的内存不释放以及文件句柄不关闭,是较常见的错误,而且稍不注意就可能发生。这类错误往往会引起很严重的后果,且难以定位。

    示例:下函数在退出之前,没有把分配的内存释放。

    typedef unsigned char BYTE;
    
    int example_fun(BYTE gt_len, BYTE* gt_code) 
    {
        BYTE* gt_buf;
    
        gt_buf = (BYTE*)malloc(MAX_GT_LENGTH);     
        ...  //program code, include check gt_buf if or not NULL
        /* global title length error */     
        if (gt_len > MAX_GT_LENGTH) 
        {
            return GT_LENGTH_ERROR;   
        }         
        ...  // other program code 
    }

    应改为如下:

    typedef unsigned char BYTE;
    
    int example_fun(BYTE gt_len, BYTE* gt_code) 
    {
        BYTE* gt_buf;
    
        gt_buf = (BYTE*)malloc(MAX_GT_LENGTH);     
        ...  //program code, include check gt_buf if or not NULL
        /* global title length error */     
        if (gt_len > MAX_GT_LENGTH) 
        {
            free(gt_buf);
            return GT_LENGTH_ERROR;   
        }         
        ...  // other program code 
    }

     

    7.防止内存操作越界。

    说明:内存操作主要是指对数组、指针、内存地址等的操作。内存操作越界是软件系统主要错误之一,后果往往非常严重,所以当我们进行这些操作时一定要仔细小心。

    示例:假设某软件系统多可由 10 个用户同时使用,用户号为 1-10,那么如下程序存在问题。

    #define MAX_USR_NUM 10 
    unsigned char usr_login_flg[MAX_USR_NUM]= ""; 
    
    void set_usr_login_flg(unsigned char usr_no) 
    { 
        if (!usr_login_flg[usr_no]) 
        { 
            usr_login_flg[usr_no] = TRUE; 
        } 
    }

    当 usr_no 为 10 时,将使用 usr_login_flg 越界。可采用如下方式解决。

    #define MAX_USR_NUM 10 
    unsigned char usr_login_flg[MAX_USR_NUM]= ""; 
    
    void set_usr_login_flg(unsigned char usr_no) 
    { 
        if (!usr_login_flg[usr_no - 1]) 
        { 
            usr_login_flg[usr_no] = TRUE; 
        } 
    }

    8.认真处理程序所能遇到的各种出错情况。

    9.系统运行之初,要初始化有关变量及运行环境,防止未经初始化的变量被引用。

    10.系统运行之初,要对加载到系统中的数据进行一致性检查。

    说明:使用不一致的数据,容易使系统进入混乱状态和不可知状态。

    11.严禁随意更改其他模块或系统有关设置和配置。

    说明:编程时,不能随心所欲地更改不属于自己模块的有关设置如常量、数组的大小等。

     

    12.不能随意更改其他模块的接口。

     

    13.充分了解系统的接口之后,再使用系统提供的功能。

    示例:在 B 型机的各模块与操作系统的接口函数中,有一个要由各模块负责编写的初始化过程,此过程在软件系统加载完成后,由操作系统发送的初始化消息来调度。因此就涉及到初始化消息的类型与消息发送的顺序问题,特别是消息顺序,若没搞清楚就开始编程,很容易引起严重后果。以下示例引自 B 型曾出现过的实际代码,其中使用了 FID_FETCH_DATA 与 FID_INITIAL 初始化消息类型,注意 B 型机的系统是在FID_FETCH_DATA 之前发送 FID_INITIAL 的。

    MID alarm_module_list[MAX_ALARM_MID];
    
    int FAR SYS_ALARM_proc(FID function_id, int handle) 
    {
        _UI i, j;
    
        switch (function_id) 
        {
            ... // program code              
        
            case FID_INITAIL:             
                for (i = 0; i < MAX_ALARM_MID; i++)             
                {                 
                    if (alarm_module_list[i]== BAM_MODULE // **)                    
                        || (alarm_module_list[i]== LOCAL_MODULE)                 
                    { 
                            for (j = 0; j < ALARM_CLASS_SUM; j++) 
                        { 
                            FAR_MALLOC(...); 
                        }
                    }
                }
    
                ... // program code 
    
                break;              
            
            case FID_FETCH_DATA:
    
                    ... // program code 
    
                    Get_Alarm_Module();  // 初始化 alarm_module_list 
                    break;              
                ... // program code     
        } 
    }

    由于 FID_INITIAL 是在 FID_FETCH_DATA 之前执行的,而初始化 alarm_module_list 是在 FID_FETCH_DATA 中进行的,故在 FID_INITIAL 中(**) 处引用 alarm_module_list 变量时,它还没有被初始化。这是个严重错误。 应如下改正:要么把 Get_Alarm_Module 函数放在 FID_INITIAL 中(**)之前;要 么就必须考虑(**)处的判断语句是否可以用(不使用 alarm_module_list 变量的) 其它方式替代,或者是否可以取消此判断语。

    14.编程时,要防止差1错误。

    说明:此类错误一般是由于把“<=”误写成“<”或“>=”误写成“>”等造成的,由此引起的后果,很多情况下是很严重的,所以编程时,一定要在这些地方小心。当编完程序后,应对这些操作符进行彻底检查。

     

    15.要时刻注意易混淆的操作符。当编程程序后,应从头至尾检查一遍这些操作符,以防止拼写错误。

    说明:形式相近的操作符容易引起误用,如 C/C++中的“=”与“==”、“|”与“||” 、 “&”与“&&”等,若拼写错了,编译器不一定能够检查出来。

    示例:如把“&”写成“&&”,或反之。

    ret_flg = (pmsg->ret_flg & RETURN_MASK);

    被写成:

    ret_flg = (pmsg->ret_flg && RETURN_MASK);

    rpt_flg = (VALID_TASK_NO( taskno ) && DATA_NOT_ZERO( stat_data ));

    被写成:

    rpt_flg = (VALID_TASK_NO( taskno ) & DATA_NOT_ZERO( stat_data ));

    16.有可能的话,if语句尽量加上else分支,对于没有else分支的语句要小心对待;switch语句必须有default分支。

     

    17.Unix下,多线程中的子线程退出必须采用主动退出方式,即子线程应return出口。

     

    18.不要滥用goto语句。

    说明:goto 语句会破坏程序的结构性,所以除非确实需要,好不使用 goto 语句。

    19.不使用与硬件或操作系统关系很大的语句,而使用建议的标准语句,以提高软件的可移植性和可重用性。

    20.除非为了满足特殊要求,避免使用嵌入式汇编。

    说明:程序中嵌入式汇编,一般都对可移植性有较大的影响。

    21.精心地构造、划分子模块,并按“接口”部分及“内核”部分合理地组织子模块,以提高“内核”部分地可移植性和可重用性。

    说明:对不同产品中的某个功能相同的模块,若能做到其内核部分完全或基本一致,那么无论对产品的测试、维护,还是对以后产品的升级都会有很大帮助。

    22.精心构造算法,并对其性能、效率进行测试。

     

    23.对较关键的算法最好使用其他算法来确认。

     

    24.时刻注意表达式是否会上溢、下溢。

    示例:如下程序将造成变量下溢。

    unsigned char size; 
    while (size-- >= 0) // 将出现下溢 
    {     
        ... // program code 
    }

    当size 等于0时,再减1也不会小于0,而是0xFF,故程序是一个死循环。应如下修改:

    char size; 
    while (size-- >= 0) // 将出现下溢 
    {     
        ... // program code 
    }

    25.使用变量时注意其边界值的情况。

    示例:如 C 语言中字符型变量,有效值范围为-128 到 127。故以下表达式的计算存在一 定风险。

    char chr = 127; 
    int sum = 200;
    
    chr += 1; // 127 为 chr 的边界值,再加 1 将使 chr 上溢到-128,而不是 128。 
    sum += chr; // 故 sum 的结果不是 328,而是 72

    若 chr 与 sum 为同一种类型,或表达式按如下方式书写,可能会好些。

    sum = sum + chr + 1;  

    26.留心程序机器码大小(如指令空间大小、数据空间大小、堆栈空间大小)是否超出了系统有关限制。

     

    27.为用户提供良好的接口界面,是用户较充分地连接系统内部运行状态及有关系统出错情况。

     

    28.系统应具有一定地容错能力,对一些错误时间(如用户误操作等)能进行自救。

    29.对一些具有危险性地操作代码(如写硬盘、删数据等)要仔细考虑,防止对数据、硬件等地安全构造危害,以提高系统地安全性。

    30.使用第三方提供地软件开发工具包或控件时,要注意以下几点:

    (1)充分了解应用接口、使用环境及使用时注意事项。

    (2)不能过分相信其正确性。

    (3)除非必要,不要使用不熟悉的第三方工具包与控件。

    说明:使用工具包与控件,可加快程序开发速度,节省时间,但使用之前一定对它有较充

    分的了解,同时第三方工具包与控件也有可能存在问题。

    31. 资源文件(多语言版本支持),如果资源是对语言敏感的,应让该资源与源代码文件脱离,具体方法有下面几种:使用单独的资源文件、 DLL 文件或其它单独的描述文件(如数据库格式。

  • 相关阅读:
    今天实现了 沿路径移动
    enum类型的本质(转)
    (转)成为优秀技术人员的两点建议
    深入理解 C# 协变和逆变
    web通信
    ajax入门(复习)
    git版本管理工具的使用
    在asp.net 中使用httpmodules对网页进行处理
    asp.net http概念原理复习
    web page复习笔记
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11718747.html
Copyright © 2020-2023  润新知