Homejunk第三次總結與囚猴困境
(同上,本文避免關鍵字)
在計算機軟件發展的最初階段,軟件往往邏輯簡單,用一些基礎的匯編語言就可以輕松的實現所有需求。但是隨著計算機處理能力不斷提升,軟件的復雜度也大幅度提升。為了解決匯編語言編程中遇到的種種不便,人們發明了各式各樣的高級語言。但是在這一階段,受限於存儲設備與處理器能力,程序的規模不會很大,更不會出現需要多人協作完成,或者反復修改軟件需求的情況。但即使使用了高級語言,當程序規模較大時,代碼維護與多人協作仍困難重重。此時,人們開始逐漸註重規格化與標準化編程中的重要性。通過引入這一機制,可以使程序員更好地理解代碼的含義,可以在不閱讀別人的代碼的情況下就能使用其所提供的功能。
規格bug
|
|
|
1 |
JSF位置錯誤 |
全體代碼(大概1000行吧,沒查過) |
2 |
我也不知道算哪類 |
80行 |
原因
第一次的bug是從群裏看的,助教說註釋可以寫在函數前面。可能對方的群裏沒這麽說吧。我也不愛浪費時間和別人爭。這也是為什麽我從來不給別人找bug的原因。
第二次對方以此為由給我報了個Incomplete類的bug,我代碼裏全部JSF都是亂寫的,拿來挑理我毫無異議。
5個前置條件不好寫法及改進
1.前置條件必須是布爾表達式
@ REQUIRES:time is long type; 改:time == long type;
2.前置條件需要更具體
public void randomMove() {
/** @ REQUIRES:None; 改:nowP.x>=0 && nowP.y>=0;
3.前置條件需要具體,不僅要考慮數據合法性,還要考慮空指針的問題
public long sleepTimeCaculate(long t,int s) {
/** @ REQUIRES:None; 改:t!=null && s!=null;
4.考慮需要用到的某些屬性是否已經被初始化
/** @ REQUIRES:None; 改:maps != null;
5. 對於數組,要對整個數組的合法性做判斷;
/** @ REQUIRES:code is valid; 改: 0=<i<=99 => 0<=code[i]<=99;
五個後置條件不好寫法及改進
a)使用自然語言。
public static void fileWriter(String file,String str){
/**
* @REQUIRES:
* file!=null;
* File(file).exist;
* @MODIFIED: File(file);
* @EFFECTS: write str to end of File(file);
*/
改進寫法:
public static void fileIn(String fileName,String str){//寫字符串str寫到文件File(fileName)中
/**
* @REQUIRES:
* File(fileName).exist==true;
* @MODIFIED: File(fileName);
* @EFFECTS: File(fileName)!=\old(File(fileName));
*/
b)後置條件為布爾表達式,不應用‘=’。
public boolean getArrived(){
/**
* @REQUIRES:None;
* @MODIFIES:None;
* @EFFECTS:\result=this.arrived;
*/
改進寫法:
public boolean getArrived(){
/**
* @REQUIRES:None;
* @MODIFIES:None;
* @EFFECTS:\result==this.arrived;
*/
c)後置條件表述不清晰。
void setReachable() {
/**
* @REQUIRES:
* map!=null;
* @MODIFIES:
* \this.reachable;
* @EFFECTS:
* (\all point p;point q.reaches(q)||p.reaches(q);reachable[p.x][p.y].contains(q);
*/
改進寫法:
void setReachable() {
/**
* @REQUIRES:
* map!=null;
* @MODIFIES:
* \this.reachable;
* @EFFECTS:
* (\all point p,q;q.reaches(q)==true&&p.reaches(q)==true;reachable[p.x][p.y].contains(q)==true
* &&reachable[q.x][q.y].contains(p)==true;
*/
d)使用自然語言。
String SPFA(point src,point des,Vector<point>[][] reachable) {
/**
* @REQUIRES:src!=null&&src.inMap==true;
* des!=null&&des.inMap==true;
* @MODIFIES: None;
* @EFFECTS:\result==String(shortest path from src to des);
*/
改進寫法:
String SPFA(point src,point des,Vector<point>[][] reachable) {
/**
* @REQUIRES:src!=null&&src.inMap;
* des!=null&&des.inMap;
* @MODIFIES: None;
* @EFFECTS:\result!=null&&\result.length()>=0;
*/
e)未書寫exception_behavior。
void initMap(String name,TaxiGUI gui) {
/**
* @REQUIRES:
* name!=null;
* gui!=null;
* File(filename).exist;
* @MODIFIES:
* \this.map;
* \this.numMap;
* @EFFECTS:
* \all int i;0<=i<80;this.map[i]==readLine(name);
* !MapReadSucceed==>output error information
*/
改進寫法:
void initMap(String name,TaxiGUI gui) {
/**
* @REQUIRES:
* name!=null;
* gui!=null;
* File(filename).exist;
* @MODIFIES:
* \this.map;
* @EFFECTS:normal_behavior
* \all int i;0<=i<80;this.map[i]==readLine(name);
* !MapReadSucceed==>exceptional_behavior (WrongFormatException);
*/
被報的功能bug與規格bug聚集關系
無。
體會
(這回之所以能寫這麽多,是因為調研的時候不小心多調研別人作業一部分)
我覺得與其浪費時間被強制寫現在看來沒有意義的規格,不如多讓人想一想那些幾萬行、幾十萬行的大項目是怎麽寫的,復雜的技術(光線追蹤或者其他方面)是怎麽實現的。
反正無論是我目前看過的項目(最小六萬行、最大沒查過),還是自己實現的萬級以上的代碼,均沒覺得一個用如此嚴謹的邏輯式表達的代碼存在的意義。無非最多是像用來作為sdk的代碼註釋很工整。至少我在使用別人的代碼時,只要了解整體的功能與像樣的函數名或註釋就能猜出人家是怎麽實現的。與其像這樣費盡心思理解別人代碼,不如去好好構架自己的代碼的結構。
無論是JSF規格也好,還是就程序正確性判定也好,單純擺出這麽空且無意義的要求有意思麽?實際中有人會在意出租車晚到1毫秒麽?實際中有人會註意電梯晚了2毫秒麽?把這些原本應該用來處理實際情況的問題的結果用這種要求來限定有意義麽?看我們這些菜雞互啄有意思麽?無非就是浪費時間而已。至少我並不願意花時間去爭那幾個分數,我也從來不認可用數字評判的能力。
不過話說回來,我就恰好第一時間看了最後一次作業的評測結果。對面的人也真是我難理解的大神級人物吧。單靠眼睛就能給我報5個功能相關的bug。我也特別想認識認識並且請教一下:搜索工具會用麽?執行不消耗時間的量子計算機好用麽?向量的點乘叉乘能判斷方向知道麽?
關於囚猴困境
(與博弈無關)
囚徒困境之所以能成為一個博弈的問題,是因為每個人都會努力爭取制定規則的人所認為的利益。然而隨著人數的增長,並不是每個人會以這為自己的利益去不擇手段。從另一個方面思考一下,一些觀點可能對那些按著規則努力拼搏的人有幫助:
1.人是自由的,除了無法突破的自然法則之外可以不聽從任何規則。
2.制定規則並讓人聽從的能力(也就是權力)是聽從規則的人賦予的。
3.現在的狀況就是幾個人高高在上看著一群猴在掐架。
這便是囚猴困境與囚徒困境的差異。
以上。
Homejunk第三次總結與囚猴困境