多項式求導系列——OO Unit1分析和總結

来源:https://www.cnblogs.com/kortez/archive/2019/03/27/10607491.html
-Advertisement-
Play Games

本文是BUAA OO課程Unit1在課程講授、三次作業完成、自測和互測時發現的問題,以及傾聽別人的思路分享所引起個人的一些思考的總結性博客。本文第二部分介紹三次作業的設計思路,主要以類圖的形式展現,並有簡單的優劣分析;第三部分為程式代碼複雜度的分析(二、三兩部分為基於度量的對自己程式結構的分析);第... ...


一、摘要

   本文是BUAA OO課程Unit1在課程講授、三次作業完成、自測和互測時發現的問題,以及傾聽別人的思路分享所引起個人的一些思考的總結性博客。本文第二部分介紹三次作業的設計思路,主要以類圖的形式展現,並有簡單的優劣分析;第三部分為程式代碼複雜度的分析(二、三兩部分為基於度量的對自己程式結構的分析);第四部分為對自己、對他人程式的測試、DEBUG、Hack的思考;第五部分是分析作業中可以應用對象創建模式的可能性,和重構的思考。

二、開發設計思路

 1.程式類圖展示

第一次作業

第二次作業

第三次作業

 

2.簡單分析

  這三次作業我基本上採用了完全不同的方法,感覺到其實非常有趣並且很有收穫。

  第一次作業的時候我的所有代碼都在一個.class文件內,設計了一個沒有什麼意義的主類Derivation,包含了一個多項式類和一個單項式類。這種設計除了在文件管理上不容易丟失文件以外基本沒有什麼好處。第二次和第三次作業中代碼才越來越面向對象。第三次中有一些體現抽象工廠的設計,使用了Factor介面和Item抽象類,顯然第三次作業的程式更具有可擴展性。實際上我在第二次作業中就有意識地在降低模塊的耦合以方便單元測試。

  第二次和第三次的作業實際上採用了不同的設計思路,主要在於第二次是為了提高對輸出優化處理的可擴展性,第三次是為了提高支持輸入的項的類型的可擴展性。第二次中的對象保存的是對一個多項式的各種處理方法,而第三次的對象保存的是多項式的各種組成成分。這兩個程式一個在怎麼處理產品的方法上有較好擴展性,一個在能處理的產品種類上有較好擴展性。此外,第三次作業我嘗試直接使用字元串來保存數據,無意中使用了Creative Pattern。前兩次作業中,會牽涉到對象的拷貝等,容易發生錯誤,某些對象的方法可能不具有可再現性,引入不安全性並且不利於單元測試;第三次作業中,由於沒有計劃做詳細的優化,使用了直接進行字元串操作的簡化設計,但非常不利於優化。此外,前兩次作業使用的容器還較為傳統(定長數組),不利於利用現有的包進行合併同類項優化而自己寫了優化的方法,雖然實現簡單,但是也浪費了空間資源。

三、程式結構分析

1.度量分析

第一次作業

 

第二次作業

第三次作業

 

從三次作業來看,代碼結構的基本複雜度、模塊複雜度和圈複雜度呈現明顯的逐次下降趨,體現出我的程式更加結構化、模塊化,這有利於代碼的理解和結構化、模塊化的維護、測試和功能擴展;各模塊之間耦合度降低,有利於模塊的隔離、維護和復用;程式獨立路徑的數量也在減少,則出現錯誤的幾率會降低,亦有利於測試和維護。

四、測試、DEBUG與互評

1.個人BUG分析

第一次作業:

  • 引發錯誤的數據:“+x+x+x...”(大量“+x”構成的長輸入)
  • 引發的錯誤:正則表達式匹配棧溢出錯誤
  • 沒有測出的原因:本地使用JDK版本比評測機高,該版本正則表達式並不會發生這樣的匹配導致棧溢出的錯誤,所以雖然本地也測試過這種數據,但是並不會引發錯誤
  • 錯誤的代碼:
123   "|\\d+)[ \t]*)*[ \t]*";
  • 修改後的代碼:
123   "|\\d+)[ \t]*)*+[ \t]*";
  • 分析:使用在匹配中使用獨占模式即可使得程式在對整個輸入進行匹配後不進行回溯,從而避免棧溢出的錯誤。

第二次作業:

  • 引發錯誤的數據:“x^2*cos(x)^6*sin(x)^7+x*cos(x)^6*sin(x)^7”
  • 引發的錯誤:優化時引入了計算錯誤
  • 沒有測出錯誤的原因:測試不充分
  • 錯誤的代碼:
47     boolean canOptimizeWith(Monomial m) {
48         return ((this.power.equals(m.power) &&
49                 (this.sinPower.equals(
50                         m.sinPower.add(new BigInteger("2")))
51                        && m.cosPower.equals(
52                         this.cosPower.add(new BigInteger("2"))))
53                 || (this.cosPower.equals(
54                 m.cosPower.add(new BigInteger("2")))
55                 && m.sinPower.equals(this.sinPower.add(new BigInteger("2")))))));
56      }
  • 修改後的代碼:
48         return (this.power.equals(m.power) &&
 
55                         this.cosPower.add(new BigInteger("2")))
  • 分析:判斷兩項是否滿足優化條件的方法錯誤,邏輯太複雜導致的括弧錯誤。

第三次作業:

  • 引發錯誤的數據:cos((-x^+7*x^7))^+1
  • 引發的錯誤:對象調用了自己的方法導致迴圈調用,引發棧溢出錯誤
  • 沒有測試出的原因:測試不充分
  • 錯誤的代碼:
47    public void optimize() {
48        if (super.getData().matches(".*\\^0*1")) {
49            setData(getData().replaceAll("\\^0*1", ""));
50        } else if (super.getData().matches(".*\\^0*")) {
51            setData("1");
52        }
53    }
  • 正確的代碼:
47     public void optimize() {
48         if (super.getData().matches(".*\\^0*1")) {
49             setData(super.getData().replaceAll("\\^0*1", ""));
50         } else if (super.getData().matches(".*\\^0*")) {
51             setData("1");
52        }
53    }
  • 分析:我的設計中getData時要優化,優化的時候要調用父類的getData,如果調用自己的,則會迴圈調用。

2.互測BUG分析和Hack技巧

  我互測中遇到的BUG主要是對數據的輸入處理的問題,例如未判斷正負號使用是否正確就先去除了重覆的正負號,或者在正則表達式中使用“\s”從而引入了不允許的特殊字元的可能性,或者某些位置應該允許輸入多個空格只允許了單個。還有對不完整的輸入,比如“+x+”,"45*"等沒有進行判斷。第三次作業中,還有同學沒有使用BigInteger處理數據,或者對指數為000000000000000000001的輸入進行了報錯,說明這方面沒有處理得當。還有對於如“x*+1”的乘法內含有帶符號整數因數處理錯誤的情況。

  主要通過閱讀代碼針對性測試和構造測試數據盲測結合進行測試。JUnit的Series能夠排列組合生成一些數據,同學分享的隨機生成字元串也能生成數據,但主要還是人工設計的邊界條件數據或者特殊情況數據更容易測出錯誤。在時間允許的情況下,閱讀代碼是最有效的找到別人BUG的方法。當然,自己設計時積攢或出錯過的測試數據也有使用的價值。

3.對提高DEBUG效率的思考

What Information

More Information Less Information

Trail

Step by step

Conditional Breakpoints

 Code

The whole code 

Coverage 

 Value of variables

 Variables

Watches/Evaluation

Exception 

 Throw an exception

 ...

 Anything

Hiearchy + 

 Hiearchy -

  我認為DEBUG也是值得思考的事情。DEBUG是根據提供的信息尋找所寫代碼中錯誤並改正的過程。通過IDEA和Eclipse所支持的豐富的功能,我們可以輕易的獲得包括代碼覆蓋、變數值、代碼軌跡等信息,通過增加和減少信息結合自己程式的設計結構,可以大大減少鎖定bug的時間。利用條件斷點實現分級的DEBUG信息輸出也是有價值的DEBUG方法。

五、對象創建模式的應用思考

   第一次作業中,我沒有實現多項式類,將多項式當做多個單項式存儲在數組中進行處理,並編寫相應的各種方法。可以重構,設計多項式類,僅包含HashMap類,而且由於多項式求導後還是多項式,求導方法可以使用new的方法返回一個多項式。

  第二次作業中,也沒有實現多項式類。仍可設計多項式類,各種多項式處理器與主函數的數據交流也可以重構為對象創建的方法,每次返回一個new多項式,可以使得各種求導、優化、合併同類項、根據三角函數公式優化等方法可以獨立地開發和測試。

  第三次作業我已經有使用工廠模式的影子,仍有很多可以改進的地方。可以完成部分優化工作,這裡就需要註意equals方法的重寫以支持合併同類項。此外,在我設計中使用了替換字元以屏蔽括弧內正負號和乘號的處理方法來應對多層嵌套,分割後再將字元換回,這個有很大的不安全性,也可以重構,將這種乘積和單項式匹配方法(即遞歸地根據+、*分割輸入)改為expression tree對象的處理,改為工廠模式,可以減少正則表達式的使用和避免對輸入數據的改動引起的不安全性。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.自我代碼分析 1.度量: 第一次作業: 第二三次作業(改動很小,給出第三次作業結果): 2.總體自我評價: 第一次作業代碼實現糟糕,可以從代碼統計結果看到這一點,第二三次感覺比較滿意,思路順暢方法簡單可擴展性強但面向對象思想還不夠(甚至沒有繼承和介面),倒算是比較精緻的面向過程,不過類的高內聚低 ...
  • 一、作業結構分析 第一次作業: 類圖(真·一類到底) 方法複雜度、類複雜度、類間依賴 第二次作業: 類圖 方法複雜度、類複雜度、類間依賴 第三次作業: 類圖 方法複雜度、類複雜度、類間依賴 結果一目瞭然:方法複雜度、類複雜度逐漸減少;類間依賴程度增加、類的層級化更加明顯。 應用工具度量得到的結果和我 ...
  • 深層理解-棧平衡原理-底層是如何實現棧平衡的? 在iOS、android操作系統中,經常會遇到入棧出棧的操作。 那麼現在操作系統已經不需要我們去關心堆棧的操作。 比如:iOS中的ARC模式,android中的JVM都會幫我們自動釋放記憶體,自動保持堆棧平衡。但是對於開發者來說,還是很有必要掌握堆棧平衡 ...
  • 對於一個的坐擁1.4億多用戶,平均日活躍用戶量超過 3400 萬,人均日訪問時長 1 小時,月累計頁面訪問量達到 230 億的大廠來說(數據截止2018年 3 月),知乎的AI都到底應用在了哪些領域,這中間應用到了哪些技術和模型,又產生了哪些作用?今日第1期數智方法論將從內容生產、內容消費與分發、內... ...
  • 那個時候初入java這個大家庭,學習的方向很亂。畢業後,在公司磨練了一年,總想著是該交一份答卷了,可能成績不會很好,但求及格!那麼考試題目呢,我計劃搭建一個橫向可擴展的項目,可以在平臺自擴展各種子項目,包括 後臺許可權控制,日誌分析,秒殺,微信小程式,愛代客(www.idaike.com)項目等等,所 ...
  • OO第一單元作業總結 在第一單元作業中,我們只做了一件事情:求導,對多項式求導,對帶三角函數的表達式求導,對有括弧嵌套的表達式求導。作業難度依次遞增,讓我們熟悉面向對象編程方法,開始從面向過程向面向對象轉變。本文中,我將介紹我個人每一次作業的做法,以及三次作業的分析,互測時策略。 第一次作業 第一次 ...
  • 第一次OO博客作業 前言 面向對象課程已經經過了4周的時間。前三次作業全部是關於多項式求導的相關內容,內容由易到難,同時我也開始逐漸深入感受學習面向對象的各項特征,逐漸將自己的編程風格從C向真正的面向對象語言轉換。同時我還接觸了DEBUG和互測屋這樣嶄新的學習方式,在閱讀別人代碼的過程中不斷增強自己 ...
  • 一、由於項目需要進行手機看板展示設計及開發展示效果圖如下: 上圖為概況(點擊相應模塊進入詳情頁面) 上圖為運營統計(一些統計類圖標狀圖折線圖等......) 車輛分佈狀況(展示在地圖上分佈) 上圖為點擊一輛車的軌跡和運行情況 此產品唯一亮點在於完全可以把利用HTML5和echarts開發大數據大屏展 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...