OO_第四單元總結
架構設計
第一次作業
主要實現對UML類圖的解析和查詢。
解析:
UML圖的.mdj
檔案經由官方提供的jar包可以轉換為多個UmlElement。由於輸入的json資料無序,因此需要通過三個迴圈來根據元素的type分層解析。同一層的元素解析順序不會影響結果,而下一層的元素會依賴上一層解析完畢的元素。
第一層:UmlClass
, UmlInterface
第二層:UmlAttribute
, UmlOperation
, UmlAssociationEnd
,
UmlGeneralization
UmlInterfaceRealization
第三層:UmlParameter
, UmlAssociation
自己設計了MyUmlClass
、MyUmlInterface
、 MyUmlInteraction
、MyUmlOperation
包裝了對應的類並添加了新的屬性和方法。例如MyUmlClass
增加了父類、attributes
、operations
、implementInterfaces
、associations
等屬性以及相關方法。在解析時,將關鍵資訊提取並存儲。
查詢:
在頂層類MyUmlInteraction
中實現儲存並分配解析到的資料,以及根據相應的查詢操作呼叫自定義類例項的方法從中獲取相應的資料。
第二次作業
新增解析並查詢狀態圖和順序圖的功能。
頂層的MyUmlGeneralInteraction
將所有元素按照類別劃分給類圖互動模組、順序圖互動模組、狀態圖互動模組。注意UmlAttribute
這一元素在類圖和順序圖中均存在,因此需要分配給兩個模組令其自行判斷是否為自己的attribute。
MyUmlStateChartInteraction
負責解析並查詢狀態圖。MyUmlCollaborationInteraction
負責解析並查詢順序圖。
與解析類圖思想相似,在解析狀態圖和順序圖時,我們仍然分層解析,並在statemodel
包下自定義普通狀態、起止狀態、狀態轉換等類,在collaborationmodel
EndPoint
、Interaction
、LifeLine
等類,用於包裝對應的UmlElement並新增屬性和方法。
第三次作業
新增對解析格式規範的檢查,若有錯誤格式需要丟擲異常。架構與第二次作業基本相同。
架構設計及OO方法理解的演進
第一單元
第一單元中切實體會到了面向過程到面向物件的轉換。在此之前所寫的程式碼還是演算法題居多,讀取輸入、存到資料結構中,經過特定的演算法得到結果,簡短的程式程式碼量一般最多隻有數百行。此外用python跟著書做過幾個小專案,的確實現了面向物件思想的運用,但許多地方只是跟著書實現,並不瞭解為何要如此設計,做完之後仍對於面向物件的理解尚淺。
在本單元第一次作業中,思維還只是像做演算法題一樣,侷限於“完成本個任務”,沒有考慮後續迭代的可擴充套件性、可維護性,所以只是用一個大正則表示式來迴圈提取表示式的項,甚至用了replaceAll
來預處理加減號,這種解析方式太依賴於具體場景,可擴充套件性弱,因此在第二次作業需要表示式支援()
後,便不得不重構。
第二三次作業中需要表示式增加支援三角函式以及括號巢狀的求導,那麼將因子、項、表示式等實際模型設計成類,而後根據形式化表述,從頂向下遞迴解析。每一層的導數都是下一層導數的乘積、加減的組合。
第一單元的設計偏重於多種類的組合,通過自行設計架構,也確實對OO的理解以及優勢更進一步。因此本單元對於OO的理解更側重於“封裝”這一維度,可以劃分為一個模組的程式碼設計成一個類,高內聚,將細節封裝在類內部,對外暴露方法,實現特定功能。類之間鬆耦合,可以通過提取抽象成介面,減少類之間相互之間的依賴,實現未來需要對某個類改動時,對其他的類影響儘量小。
第二單元
第二單元引入了併發的設計,需要我們建立執行緒安全的協作結構。
主要是輸入執行緒+排程器執行緒+電梯執行緒三類之間的協調配合。採用生產者-消費者模式,通過wait
和notifyAll
操作實現執行緒配合,將請求佇列設定為執行緒安全類,就可以更加妥善管理鎖的分佈,使得鎖不會雜亂。
本單元的實踐帶著入門了執行緒併發,在一次次與死鎖、輪詢、無法正常結束等情況打交道之後,也對執行緒安全的設計與debug有了一定的經驗。在大規模應用系統中,高併發是一個十分重要的問題,在本單元的入門引領下,個人也出於興趣對多執行緒進一步瞭解了一些,正在閱讀《圖解java多執行緒設計模式》,並打算在暑假讀完。
第三單元
本單元主要側重對JML規格的閱讀理解與實現。通過閱讀了大量JML規格語言,對於JML的理解由初始的晦澀逐步熟練。對OO 的理解更加開闊,可以為對架構進行設定,可以為需求做模型,提高pm與實現人員的互動準確程度。
此外,本單元涉及到了比較多的圖論演算法,通過JML語言,我們要儘量去理解其表達的核心實現需求,將其抽離並通過較好的演算法實現(連通塊、最短路、快取等),如果只按照JML中的多重迴圈,時間複雜度無疑是很高的。
第四單元
本單元主要通過對UML圖元素的解析以及建模,對UML圖進行一個更深刻的瞭解。架構在前文已有表述。本單元對於OO認知的進步主要體現在對於UML圖的認識、熟悉到可以自己作圖。通過UML圖我們可以直觀的理解陌生專案的架構與設計,也可以方便地對別人表述自己專案的設計。
測試理解與實踐的演進
第一單元中黑盒測試運用較多,通過形式化表述來遞迴生成隨機資料,構造資料生成器,將個人標準輸出與標準庫的正確輸出對比,初步瞭解了自動化測試的思想與實踐。此外學習到了構建“常量池”等方法來針對性生成滿足條件的資料(小資料、爆int的資料、爆long的資料)。
第二單元中,生成隨機資料比較容易編寫,但難點在於如何測試輸出的正確性,畢竟如果採用的排程策略不同,那麼輸出也並不相同,無法採用對拍的形式來驗證結果。這就需要我們自己構建規則,檢查輸出的合法性(是否運送完所有乘客、是否到達指定樓層等等)。除了輸出的合法性,死鎖、執行緒未被喚醒等造成的程式無法正常結束的問題也需要重視,這種bug無法複線,需要通過檢查程式邏輯、打斷點測試等白盒測試方法來修復bug。
第三單元中,主要運用的是圖論的演算法,我們可以採用類似第一單元的自動測試的黑盒方法。此外,首次接觸JUnit單元測試,單元測試能夠檢查我們在迭代之後是否對原功能造成了影響。是一個良好的測試習慣。在大型專案中,我們沒有標準庫提供標準資料,也沒有同功能專案來和我們對拍,此時單元測試便顯得十分重要。此外,由於方法均有完善的JML規格表述,因此重新閱讀JML、檢查對比程式碼邏輯也是一個良好的測試方法。
第四單元,主要通過手動在startUml中搭建UML圖,將.mdj
檔案通過官方jar包轉換為輸入資料來觀察輸出。當輸入資料構建邏輯比較複雜時,手動構造邊界資料也是一個良好的測試方法。
可以說,測試是我們編寫程式碼十分重要的一環,在參與一些團隊專案、開源社群專案中,自己能夠編寫的程式碼可能並不會很多,但一定要經過一系列測試確保功能正確,才能merge到專案當中。
課程收穫
- 面向物件思想
之前對於面向物件的理解侷限於一個class
,通過課程教學,也逐漸擴充了對面向物件思想的認知,封裝、多型、繼承體現了面向物件的特徵,但OOP的核心在於這種思想,即隱藏細節、狀態通過訊息傳遞的方式來修改等,從而為編寫龐大、複雜的系統而服務。
- Java基礎的熟練
大量的程式碼練習,夯實了個人對於java基礎的認識與理解。現在回顧廖雪峰的Java教程,許多之前感到晦澀難懂的地方,都有一種撥雲見日豁然開朗的感覺。
- 自主設計較大規模程式結構的經驗
在設計程式結構時,有時能夠將一些學習到的設計模式的思想融入其中。也逐漸明白了一個良好程式架構的重要性。
- 引路人
多執行緒單元的設計編寫,引導設計一個初具規模的多執行緒專案,同時也為大家打開了多執行緒的大門。通過個人探索,也瞭解到高併發對於大規模企業及應用的重要作用,或許之後會找一找相關方面的原始碼來讀一讀。
JML規格語言,初窺團隊開發規範的表現形式。之後如果參與到大規模團隊開發中,相信會大有裨益。
UML圖,通過解析的實踐的形式,更容易對UML圖印象更深刻,瞭解更充分。因為之前閱讀一些專案的設計文件,也會見到UML圖的形式的解析,可見能夠對UML圖有一個良好的理解熟練度是十分重要的
- 部落格
能夠寫出一篇邏輯清晰、深入淺出的好部落格並不容易,同時這樣一個輸出過程也很重要。自己之前的部落格多是筆記性質的文章,個人輸出很少。課程組要求的部落格也算是令本人體驗了原創博文的感覺,但總體感覺寫出的文章還是處於胡言亂語的狀態。希望自己之後能夠有能力寫一些邏輯清晰、文筆細膩、深入淺出的文章,做一些輸出。
- 講座
在兩場講座中的收穫還是很不錯的,但感覺麥和音響裝置有待提升,不坐前排大部分分享都聽不清。講座相當於開了幾個與工業界的介面,從中得以一窺工業界核心專案方向(阿里雲這種toB型團隊對於大規模資料的處理方式、中臺成熟度,給中小企業提供輪子的情況等等)以及演算法落地(CV/NLP/RI方向研究員/工程師在實際場景中需要處理的工作等)。相信大部分同學的目標還是工業界方面的發展,一些不同團隊、不同方向的業界一線人員的分享總還是能帶給大家一些視野的開闊,如果能找到自己感興趣的方向,那自然是很好的。同時這也驅動著我對於開發/演算法方向的發展做了一些更深入的瞭解,瞭解過程中也更新了我之前對於就業/讀研方面的認知。之前覺得深度學習相關領域很高大上,很火,在6系all in ai的氛圍下也跟著加了實驗室,想著打打雜爭取發個paper再申個黴國的ms/phd。但現在演算法崗待遇基本和開發差不多競爭卻激烈得多,並且碩士大部分拿到的演算法崗也只是演算法工程師,乾的活和開發基本也差不多,和博士出來的研究員還是有很大差別的。而且開發也有很多值得研究的領域:分散式、高併發等等,目前開發崗大趨勢是本碩同薪,這麼一看國內3年讀個研似乎很虧。而且現在簽證政策很不友好,出國也不怎麼打算了。(怎麼寫著寫著寫出了職業規劃課的感覺...果然是最近這方面東西刷太多了嗎)
改進建議
- 希望能夠給出實驗課結果。
雖然實驗課大部分情況下偏簡單,但確實有時候會有幾個點不確定,還是希望看一下答案查缺補漏的。
- 討論區發言的排布形式有待改進。
目前的排布應該是假設所有人都對發帖人做回覆,但如果要對該帖下發言的其他人回覆,就只能順序排布到所有發言的最後,顯的回覆物件並不明確。如果帖子下發言多,就顯得很亂,也不知道誰回覆誰。或許可以考慮加一個層次化的回覆結構?
- 難度安排與時間安排
實際開發過程中還是能明顯感覺到某次作業相比於其他幾次作業而言過於複雜。比較突出的是第一單元第二次作業、第二單元第一次作業。如果能將工程量勻給其他作業,體驗應該會比較舒服。
以及整個時間流程,感覺對於其他課程排課時間考慮比較少,例如互測,週一晚開放,週二晚截止,但週二大部分人一天都是滿課,並且週一的那段時間還要貢獻給明天扎心的os上機,很難抽出什麼時間讀程式碼、hack(除非利用上課時間,不過不少人就是這麼做的hhh)。然後任務量大的話,基本就是週六日殺器,現在回憶起來這學期的週六日基本都是在oo中度過的。
- 研討課安排
研討課的形式或許值得商榷,目前研討課的知識傳遞效率可以說並不高,課堂狀態怎麼樣或許大家也瞭解。以我不專業的眼光來看,一是語言資訊獲取密度低,二是講述的形式天然提不起學生興趣。竊以為,希望分享的同學將內容分享給助教/老師,由老師/助教挑選一些亮點內容,將所有班級的內容整合放到oo平臺上,讓學生坐到機房看這些內容,相信知識吸收效率應該遠超這個。也可以加入一些互動元素,有什麼問題去找分享者問,有什麼新的思考可以實時發出。