說來慚愧,在很久之前修這門課程的時候總是不能理解面向對象辯證思想的精髓所在,又沒有用軟體開發的標準嚴格要求自己,所以導致寫了一些類C程式後草草收場。時隔多年,課程的風格變化與老師和平臺提供的幫助,加上今年對於Java語言上更熟練的使用,讓我在第一個單元的學習中得到了很多,雖然並不能像大神一樣總結出技 ...
說來慚愧,在很久之前修這門課程的時候總是不能理解面向對象辯證思想的精髓所在,又沒有用軟體開發的標準嚴格要求自己,所以導致寫了一些類C程式後草草收場。時隔多年,課程的風格變化與老師和平臺提供的幫助,加上今年對於Java語言上更熟練的使用,讓我在第一個單元的學習中得到了很多,雖然並不能像大神一樣總結出技術上的種種共性要點,但仍然可以在說自己作業的具體問題之前,總結出幾點基礎的東西,也算是給和當時的我一樣基礎不好的同學一點幫助。
Part 1. 再次學習這門課總結的小TIPS
1. 面向對象設計形象化的理解
在各大搜索引擎如果你去搜索面向對象程式的特征和區別是什麼,你只會得到三個關鍵詞:封裝、繼承、多態。說的一點錯沒有,但是其實對初學者思想的轉變用處不大,無法讓你通過理解這三個詞就能一下子寫出典型的面向對象程式。如果你之前寫了一兩次類C程式,在思想的扭轉上苦苦不能完成轉變,我相信造飛機的例子就是一個非常典型的講解,會有所幫助。汽車是流水線的產物,強調整體性,裝配的連貫性;飛機則是組件外包,組件各自生產,統一完成組裝的產品,畢竟這個世界上沒有對應飛機那麼大的流水線。
我們在編寫C語言程式的時候,養成的是一種問題分解的思維步驟:這是一道怎樣的數學問題,輸入是啥,輸出是啥;弄明白要求後我們會按照輸入處理→數據計算儲存→數據輸出的線性方式對問題的解決進行構想。但寫面向對象的程式更像是畫設計圖,雖然我們仍然無法避免輸入,輸出,但你首要思考的是我們要用幾種類來處理這些問題,各種類之間如何設計方法,如何創建實例並調用。就好比我們處理了三次的字元串求導,對象有表達式,項,因數這三種,調用是層層遞進的關係,而我們只需要對處理不同的對象創建相應的方法,將類內部變數隱藏好,將該傳遞的參數設計好,問題就已經完成了分析,迎刃而解了。
萬事開頭難,你的思想如果從畫流程圖改成畫平面設計圖,那麼對於面向對象設計的初步轉變其實就完成了。
2. 標準與規範
之所以把這一點放在第二點,是因為課程引入的代碼風格檢測同樣是評價作業完成情況的標準,而且與我們其實是我們寫代碼時按順序來講關註的頭幾個問題之一,之前老師上課時調侃:“一些同學的風格分是一次一次從0變成100的”,這算是一個非常嚴肅的問題。我們的作業代碼其實是不要求註釋行數的,所以並不需要“照顧”互評同學的可讀性(這隻是一個不負責任的說法),你甚至可以不照顧自己的可讀性,但這並不意味著風格不重要。
課程提供的加上Idea上整合的一些checkstyle工具可以從最基礎的層面實時幫助我們改掉寫代碼的一些壞毛病、壞佈局等等,在寫的初期就堅持這麼做可以有效地為以後做工作避免麻煩(親身經歷)。課上舉例那個 int i = 0; int ii = 0;int iii = 0;,就是我一個學競賽的舍友出門工作第一個月寫的代碼風格,被BOSS瘋狂要求返工……按理來說演算法上我這位舍友應該遠超校招其他新人,但是代碼也是講究臉面的,不會有任何一個開發組領導會允許這種情況出現。
回到我們的課程初衷,除了面向對象的設計思想培養訓練,其實軟體開發素養的培養也是最初的目的之一,寫的時候按標準要求自己,不光意味著更高的風格分,還意味著你能更好的讀懂你寫的東西。行長度,布爾表達式複雜程度,方法長度,文件長度等等都會時時提醒你代碼設計上的不足,好的代碼不會超長,更不會在命名上出些亂七八糟的東西,所以如果能夠在寫的時候規避這些問題,可以從另一角度督促我們註意設計的細枝末節。
3.設計的重要性
這個應該已經適應這門課程的同學都有所體會,設計的時間本身並不是無效的、占用寫代碼時間的。在我看來,我們做一次作業用的總時間等於設計思考時間加上碼代碼時間,反而是一個定值。設計的時間越長,想的越清楚,碼代碼的時間耗費的其實越短(當然不要舉一些極端的例子來反駁這句話);看指導書的時間越長,DEBUG的時間就越短。我這幾次強測都有一點小錯,其中有兩個就是因為沒看到繫數的範圍,導致自己先入為主定義了一個LONG型,被同一測試組的同學瘋狂hack -_-||(畢竟是擺在明面上的錯)。
如果你在一周的作業上周二晚之前用的總時長是24小時,那我覺得,這裡面可以用2小時去通讀指導書,6小時設計,包括自己要用到的類,類中的方法,輸入處理,輸出處理,數據儲存處理等等,看的越全面越好,想的越細節越好,這樣編碼的過程中會省出很多南轅北轍的思考成本,DEBUG的時候也會遇上更少的BUG。
Part 2. 從自己作業中總結的一些問題
1. 輸入處理
這其實就是我說的思考的重要性的體現,我看一些同學其實已經用文法的格式總結了這次作業的輸入格式,應該說是比較清楚,但是在互評中也確實有沒想清楚的同學存在。正確的我就不寫在下麵了,第三次作業討論區有一些同學分享的清楚的定義。這裡說一下我聽到的某種問題。
比如:嵌套因數sin cos括弧內是因數而不是表達式,所以如果括弧內是一個表達式,那一定要是表達式因數,所以可以出現 sin((x+1)),不能出現sin(x+1)。這個是我聽說過的一個比較典型的理解錯誤,指導書沒讀懂,不過出這個錯的基本都自己DEBUG改過來了,否則中測都過不去(大概)。
2. 輸出處理
這個是我自己在第二次作業中出現的問題,還因此扣了代碼格式分,頂層沒設計好搞了好多布爾表達式,然後寫了個200行方法……
比如: 多因數輸出時處理開頭繫數為1,-1的情況就是用很多的布爾表達式去判斷如何化簡,而且還出錯了……,出現了形如“*sin(x)”的錯誤(繫數為1,化簡撲街),我後來想了想,在存數據的時候繫數不應該和後面的各項因數割裂開,然後輸出的時候挨個去判斷,才有了這種容易出錯的問題。
3. 存繫數用的long
感覺估計一個班並沒多少犯這個錯的,略。
4. 正則表達式的構建
這個嚴格來講不算個BUG,只是像之前研討課所說的,避免大正則出現(我前兩次寫的也是大正則),大正則一時爽,互評直奔火葬場。而且大正則寫對了還好說,寫錯了可就坑了DEBUG的自己了,所以,除了第三次作業,前兩次最好分層寫,這也是我從互評中學到的一些簡潔的典範,第三次涉及到遞歸,也沒法寫大正則,算是強制治了一下疑難雜症……
5. 對項的切割問題
集中體現在第三次作業,嵌套因數內的表達式有可能也會切出合乎正則的項,但由於我遞歸正則的處理問題,為了防止出現切除的項不在一層表達式中,我加了一個左右括弧的判定條件,這個判定條件直接導致了帶符號整數的檢測出現問題,互測被機槍掃射打成篩子……處理也比較簡單,直接識別正負號前面的符號是啥,如果是^*這種則不進行切割,如果不是就作為項分離的標誌。這種問題來源於自己測自己程式時不細緻,其實可以避免的。