计算与软件工程 作业3

计算与软件工程 作业3

作业要求 https://edu.cnblogs.com/campus/jssf/infor_computation17-31/homework/10454
课程目标 完成简单软件功能的开发,会辨别和修改简单地代码漏洞,可根据现有代码实现改编从而实现现下需求
该次作业在程序效能方面实现我的目标 代码测试可以实现对代码整体的掌控,保证代码可靠性。帮助我完成对部分代码漏洞的检测与修补
参考文献 https://www.cnblogs.com/njzy123456/p/9755642.html https://www.cnblogs.com/wolfrickwang/p/3767306.html https://blog.csdn.net/duoduo18up/article/details/79526659 https://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html https://www.cnblogs.com/SivilTaram/p/software_pretraining_cpp.html
作业正文 https:////www.cnblogs.com/yangqiuyan/p/12434874.html

课前阅读阶段:

1. 技能的反面 - 魔方和模仿
关于技能的真正掌握,老师用了很简单的魔方例子进行了比喻,真正想掌握技能需要通过不断的练习, 把那些低层次的问题都解决了, 变成不用经过大脑的自动操作, 然后才有时间和脑力来解决较高层次的问题。而为了真正地“与众不同”甚至脱颖而出更应该真正掌握精髓,不断创新,在练习中真正提高技能水准,而不是抄袭水准。
2. 现代软件工程-软件工程师能力自我评价表
对软实力提升方面及技巧:保持高标准,不要受制于破窗理论;主动解决问题;经常给自己充电,多学多练;别重复;消除不相关模块之间的影响;估计任务所花费的时间,避免意外;
有很多代码编辑器,请把其中一个用得非常熟练;理解常用的设计模式,并知道择机而用。

课后作业阶段:

一.代码设计

1.需求分析及目标要求
求出指定数组最大的子数组和(用类/函数实现)
需要返回三种信息
1).最大子数组的和
2).最大子数组开始的下标
3).最大子数组结束的下标
2.具体实现效果截图(代码见附录及文末给出的码云链接)

3.结果分析
实现以上要求的算法主要有三种:暴力求解,运行时间是n²;分治策略,运行时间是nlogn;贪心算法,运行时间是n。显然贪心算法具有优势且运行效率更高。为了测试如上函数的功能,我针对该文件进行如下一部分的单元测试。

二.单元测试

1.测试目的及知识背景
从层次的纬度,可以将测试分为三类
1).单元测试
2).集成测试
3).性能测试
·单元测试(Unit Test)是面向函数级别的测试用例,由开发人员编写,测试某个或者多个函数的功能。单元测试环境应该容易搭建和运行,运行时一般不依赖其它的服务:如数据库,缓存,第三方服务等,所以在产生其它依赖的地方往往需要 mock 框架,如此有利于提升开发效率。单元测试注重覆盖率,通常情况下,70-80% 左右的覆盖率往往满足绝大部分场景。
·集成测试(Integration Test)是面向 API 级别的测试用例,由开发/测试人员编写,测试一个或者多个 API 的功能是否正常,多个组件之间是否互相配合,正常工作。集成测试环境的搭建相对比较复杂,它可能依赖数据库,缓存,第三方服务等,一般为大家共用。
·性能测试(Performance Test)主要用于测试性能,分析性能瓶颈等,属于高级别的测试类似。受多种条件影响,不同应用的性能测试方式各有差异,在此不多展开。
·整个项目的代码量越大,越需要测试用例来保障其质量。代码量越大,意味着越难以熟谙所有的逻辑,每次 commit 带来的不确定影响越大。通常情况下,每次 commit 都应该先跑通单元测试和集成测试后才能提交 merge request。每次发布上线时,一定要确保发布的版本能通过单元测试和集成测试,某些应用甚至要求跑通性能测试。
2.测试过程及要求
1).过程:开始时所有单元测试都失败,后改进程序,加入正确的逻辑,看到有单元测试通过,并且看到代码覆盖率的增加重复,直到所有单元测试都通过,代码覆盖率达到满意的结果。
2).要求:类开始是空的,返回都是简单的数值,例如0.测试包括测试文件读入与计算。
3.具体实现及效果截图(代码见附录及文末给出的码云链接)


4.结果分析
·简化步骤:完成单元测试时,先在解决方案里面添加一个单元测试项目名称为UnitTestMain,将main工程文件目录 添加到UnitTestMain工程中的包含目录,然后在解决方案资源管理器右键单击UnitTestMain工程属性->VC++目录->包含目录更改,最后编辑UnitTestMain工程的unittest1.cpp。
·问题:在运行测试cpp文件时,一开始写完测试代码后一直无法实现测试(头文件划红线),后查阅资料发现必须先配置属性如下图所示:

三.博客作业

·三年学习回顾:大一开始接触简单地计算机应用软件(MS Office)及基本的C++语言编程,学习了类函数,类库,流文件操作等知识。对word,ppt,excel的用法较为熟练,而代码编程则会简单地冒泡排序算法等代码量50行以内的简单算法。大二学习了更高级的计算机语言Java语言,会做一些简单的图形界面,会用java语言进行类似C++语言的编程;还进一步学习了数据结构课程,可根据提供代码修改完成一些相对复杂的需求实现,了解了计算机数据的基本知识。大三学习了数据库,操作系统,ASP,MATLAB科学计算等课程更加具体了解了计算机代码编写的操作。学习了网站的建立技巧,会实现基本的网站操作,完成较为复杂的类似网上聊天室,图书馆光盘借阅系统的建立。对Matlab的学习更多是为了满足数学计算的需要,会某些的数学算法的编写以方便数据统计与比较,会搭建数据库,完成大数据后台的基本操作。了解了类似于贪心算法,银行家算法,哈希算法等经典的计算机算法。
·未来展望:希望在这学期的计算与软件工程课程的学习中能通过自行学习和老师的帮助完成简单地软件开发,了解软件开发的过程后能自己或合作完成现实意义比较大的软件开发项目。能串联自己以前学过的基本课程的学习知识,提高代码编程能力,锻炼自己的逻辑能力和修改代码漏洞的能力。

四.预习讲义

(a)代码规范
·代码风格的原则是:简明,易读,无二义性。
代码规范:
(1)代码风格规范。可以从下面几个方面进行改进:缩进、行宽、括号、断行与空白的{ }行、 分行、命名、下划线问题、大小写问题、注释(复杂的注释应该放在函数头)
(2)代码设计规范。可以从下面几个方面进行改进:函数、 goto、错误处理(参数处理、断言)、如何处理C++中的类
·重点:处理C++中的类
1)类:使用类来封装面向对象的概念和多态(Polymorphism)。避免传递类型实体的值,应该用指针传递。换句话说,对于简单的数据类型,没有必要用类来实现。对于有显式的构造和析构函数,不要建立全局的实体,因为你不知道它们在何时创建和消除。只有在必要的时候,才使用“类”。
2)虚函数(Virtual Functions):使用虚函数来实现多态(Polymorphism)。只有在非常必要的时候,才使用虚函数。如果一个类型要实现多态,在基类(Base Class)中的析构函数应该是虚函数。
3)构造函数Constructors:不要在构造函数中做复杂的操作,简单初始化所有数据成员即可。
构造函数不应该返回错误(事实上也无法返回)。把可能出错的操作放到HrInit()或FInit()中。
4)析构函数:把所有的清理工作都放在析构函数中。如果有些资源在析构函数之前就释放了,记住要重置这些成员为0或NULL。析构函数也不应该出错。
5)类型继承(Class Inheritance)当有必要的时候,才使用类型继承。用Const标注只读的参数(参数指向的数据是只读的,而不是参数本身)。用Const标注不改变数据的函数。
(b)代码复审
·目的:找出代码的错误;发现逻辑错误;发现算法错误;发现潜在的错误和回归性错误;发现可能改进的地方;教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识。
·步骤:确保代码必须成功地编译,程序员必须测试过代码;程序员必须提供新的代码,以及文件差异分析工具,在面对面的复审中,一般是开发者控制流程,讲述修改的前因后果。但是复审者有权在任何时候打断叙述,提出自己的意见,复审者必须把反馈意见逐一提出;对于复审的结果,双方必须达成一致的意见。
(c)结对编程
·结对编程中有两个角色:驾驶员(Driver)是控制键盘输入的人;领航员(Navigator)起到领航、提醒的作用。
·优点:1)在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作能有更强的解决问题的能力。2)对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带来更高的满足感。3)在心理上,  当有另一个人在你身边和你紧密配合, 做同样一件事情的时候,  你不好意思开小差, 也不好意思糊弄。4)在企业管理层次上,结对能更有效地交流,相互学习和传递经验,能更好地处理人员流动。因为一个人的知识已经被其他人共享。
·方法:断言、桥梁、说服、吸引
(d)给人意见的方法
“影响 + 反馈 ”
针对三个层次:最外层(行为和后果)中间层(习惯和动机)最内层(本质和基本属性)

五.代码托管

此次托管只需将新的两个cpp文件直接提交到个人仓库中。

码云链接:

https://gitee.com/yang_qiu_yan/ruangong

附录代码

//maxarray.cpp
#include<iostream>
#include<cstdlib>
using namespace std;
int getmax(int array[],int length)
{
    int sum = 0;    
    int max = 0;   
    int startIndex = 0; //记录子数组的起始位置
    int endIndex = 0;   //记录子数组的终止位置
    int newStartIndex = 0;  
    for (int i = 0; i < length; i++)    //遍历整个目标数组
    {
        if (max < 0)  
        {
            max = array[i];    
            newStartIndex = i;  
        }
        else
        {
            max += array[i];   
        }
        if (sum < max) //如果此时 sum < temp;
        {
            sum = max; 
            startIndex = newStartIndex; 
            endIndex = i;   
        }
    }
    return max;
}

int getstartIndex(int array[],int length)
{
    int sum = 0;    
    int max = 0;   
    int startIndex = 0; 
    int endIndex = 0;   
    int newStartIndex = 0;  
    for (int i = 0; i < length; i++)    
    {
        if (max < 0)   
        {
            max = array[i];    
            newStartIndex = i; 
        }
        else
        {
            max += array[i];   
        }
        if (sum < max) 
        {
            sum = max;
            startIndex = newStartIndex; 
            endIndex = i;   
        }
    }
    return startIndex;
}
int getendIndex(int array[],int length)
{
    int sum = 0;    
    int max = 0;   
    int startIndex = 0;
    int endIndex = 0;   
    int newStartIndex = 0;  
    for (int i = 0; i < length; i++)    
    {
        if (max < 0)  
        {
            max = array[i];    
            newStartIndex = i;  
        }
        else
        {
            max += array[i];   
        }
        if (sum < max) 
        {
            sum = max; 
            startIndex = newStartIndex; 
            endIndex = i;  
        }
    }
    return endIndex;
}


int main()
{
    int array[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
    int length=17;
    cout<<"Sum of the largest subarray:"<<getmax(array,length)<<endl;
    cout<<"Maximum subarray end superscript(strart):"<<getstartIndex(array,length)<<endl;
    cout<<"Maximum subarray end subscript(end):"<<getendIndex(array,length)<<endl;
    system("pause");
    return 0;
}
//unittest1.cpp
#include "stdafx.h"
#include "CppUnitTest.h"
#include "maxarray.cpp"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:
        
        TEST_METHOD(TestMethod1)
        {
            // TODO: 在此输入测试代码
            int a[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
            Assert::AreEqual(111,getmax(a,17));
        }
        TEST_METHOD(getstartIndex_Test)
        {
            // TODO: 在此输入测试代码
            int a[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
            Assert::AreEqual(12,getstartIndex(a,17));
        }
        TEST_METHOD(getendIndex_Test)
        {
            // TODO: 在此输入测试代码
            int a[]={-32,-10,33,-23,32,-12,41,-12,1,3,5,-98,70,-21,10,-9,61};
            Assert::AreEqual(16,getendIndex(a,17));
        }
    };
}

猜你喜欢

转载自www.cnblogs.com/yangqiuyan/p/12434874.html