計算與軟件工程 作業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));
		}
	};
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM