北航OO第三單元總結

2022-09-09 07:21:11 字數 2685 閱讀 1602

本單元作業為jml規格的學習與應用,要求我們在閱讀jml規格之後實現出完全符合規格要求的方法。當然在完成作業之前我又需要從0開始學習jml規格,但好在jml的入門難度並不大,短短幾個小時後就可以讀懂作業中的jml規格了。而其實規格就像是乙個指導你具體實現方法的說明書,它會為你指定這個方法的前置後置條件,指定完成怎麼樣的操作,因此其實本單元作業就是跟著jml的說明來寫**,因此其實三次作業我完成的都挺快的,難度主要在於需要高階演算法來避免卡時間(不然像就我偷懶導致強測被淦碎(霧))。

我在實現規格時總體採用的策略是從上到下,從整體到個體的思路。

首先整體瀏覽每個規格,不求完全看懂看仔細,但必須知道每個規格需要幹什麼,會對容器進行怎麼樣的操作。因為在實現規格時,選擇適用的容器是非常重要的,合適的容器能夠大大簡化我們實現規格時的寫**難度與可讀性,因此我認為在具體上手下**之前就確定下來使用什麼容器是最好的。

第二步我會先實現一些pure方法,這些方法一般邏輯簡單,也沒有***,先實現比較好。

最後啃難骨頭,對於規格複雜,需要演算法優化的方法,就需要仔細看仔細讀jml,確保自己寫出來的**符合規格的所有要求。我一般的方法是對每條jml語言用自己的語言翻譯一遍,完成**後對著我翻譯的語言一條條對比,看看是否符合要求,不然的話以我魚的記憶總是剛看完理解玩這條規格就忘記了上一條,很痛苦。

一些注意點

其實看方法名也是乙個提供思路的重要方法,一般方法的名字會最簡明扼要的提示這個方法幹了什麼事情,可不是什麼邪道(笑)。

每一次作業都要仔細對比規格發生了什麼變化,可不一定是只有新增的規格,也會有前面規格的修改,還記得第三次作業的jml中前面作業的sendmessage和addmessage方法發生了變化,但是藏在茫茫綠色中根本看不見,最後還是中測bug才讓我找出來,好險。

我的測試一般會以功能性測試-正確性測試-效能測試的順序進行。

1. 閱讀**

首先當然是閱讀自己的**咯,閱讀**是價效比很高的debug方式,一般也的確可以發現自己一些非常明顯的錯誤,另一方面也可以讓自己更加熟悉自己的**,也更加熟悉jml規格,非常值得。

2. 功能性測試

設計一些簡單的資料,來測試自己的**能不能正常執行。主要要測試一些規格比較複雜的方法,特別是自己使用了其他演算法進行優化的方法,這些方法的**一般寫的時候沒有完全跟著規格的腳步走,所以極有可能是會有錯誤的或者不能跑起來的。在這一步測試中力求能夠將自己**所有的re錯誤都找到,能夠讓自己的**執行起來,正常的執行功能。

3. 正確性測試

在功能性測試之後,就需要加強自己的測試資料來測試正確性了,最好的方法就是擴大測試資料量,覆蓋性測試,隨機測試。盡量自己構造一些測試資料,不要完全依靠評測機,這次評測機弱中測的資料及其簡單,一堆bug都可以通過評測,很多依靠評測機測試的同學都吃了大虧,(我也是嗚嗚嗚)。

4. 效能測試

主要是優化時間複雜度,可以看**找出一些自己時間複雜度高的方法,或者拿極限資料爆一下,看看是否會超時等等。

容器的選擇試來試去還是老三樣最好:

arraylisthashmaphasheset

可以根據功能需要與容器的特點來選擇合適的容器。

arraylist:一般的陣列結構,在遍歷操作較多的時候推薦這個容器。

hashmap:在需要根據對應關係快速查詢時,hashmap是最好的選擇,例如本單元作業中person,group,message都有其獨一無二的id,則根據id的對應關係建立hashmap容器,在使用時就可以非常方便地查詢。

hashset:處理集合關係時使用hashset比較好。

實際寫**時這三種容器足以瞞住我們的所有要求了,特別是hashmap容器還有很多妙用,例如在第三次作業中實現的emojimessage的相關方法,規格中要求建立了emojiidlist和emojiheatlist兩個陣列,但是在閱讀規格後就會發現,這兩個陣列的行為全程完全一致,完全可以用乙個idtoheat的對應關係使用乙個hashmap儲存,在新增刪除操作時也只要操作一次,方便很多,錯誤可能也更低。

(注意事項:使用hashmap和hashset若需要遍歷,建議使用迭代器來操作,一方面效率較高,另一方面也可以避免一些錯誤。)

本單元作業還是有很多設計效能問題的方法的,例如

前兩次作業的方法都是查詢方法,因此我採用空間換時間的方法來降低時間複雜度,提前存好需要查詢的變數,在每次涉及這些變數的改動時,及時修改,這樣下來查詢時直接返回就可以了。

然而第三次作業的求最短路徑方法顯然無法採取這種策略,因為要儲存的實在太多,每乙個都計算並儲存反而麻煩,這種情況下只能從演算法的角度解決。第三次作業時我採用了o(2*n^2)的迪傑斯特拉演算法,結果還是超時了,事後詢問同學才知道還可以使用堆優化來降低常數量。

架構其實沒啥好說的,按照規格來就完事了。

當然為了演算法實現的方便,我自己新增了不少方法。

學習jml(×)

練習演算法(√)

本單元作業其實還蠻有趣的,在學習了jml的語法後,跟著規格一步步來寫**也是一種船新的體驗,有一種玩拼圖遊戲的爽感,把每個方法都實現最後一下子跑起來的感覺就像把拼圖拼完了一樣。三次作業下來,閱讀規格的速度也越來越快了,對於不同的規格,也學會了選擇合適的容器,選擇合適的方法來實現,總體來說對我也是有不小提公升的。

但是最後都捲入卡時間寫演算法的痛苦中了,互測強測被各種大資料卡爆,就很痛苦(

OO第三單元總結

一 實現規格的設計策略 1.基於規格,設計方法 大部分需要我們寫的方法,都可以根據規格直接寫出來,這些方法一般都是比較簡單的,比如查詢有沒有這個元素 返回某個元素 增加或刪除某個元素。2.根據規格,了解方法功能,自行設計方法 規格怎麼描述,方法怎麼寫也是可行的,但是了解了方法功能,自行設計會更快,比...

OO第三單元總結

理論基礎 jml是用於對j a程式進行規格化設計的一種表示語言 注釋結構 jml以j adoc注釋的方式來表示規格,每行都以 起頭。有兩種注釋方式,行注釋和塊注釋。其中行注釋的表示方式 為 annotation,塊注釋的方式為 annotation 按照j adoc習慣,jml注釋一般放在被注釋成分...

OO第三單元作業總結

在起初剛學習完jml規格語法的時候,由於對jml規格不夠熟練,我選擇了讓自己的 與規格 基本保持一致來完成作業。意思是,jml使用陣列實現,我也會使用陣列實現 jml使用兩層for迴圈實現,我也會使用兩層for迴圈實現。並且,我選擇了每讀乙個方法的jml,就完成乙個方法。顯然,這樣的策略不會讓我產生...