我的第一個上位機軟件

       2019年即將過去,這一年最值得開心、高興的事就是我參與研發的“全自動生化分析儀”終於上市了,並受到市場的歡迎;由於有非常給力的銷售團隊,機器的訂單一直不斷。當然機器研製成功是項目經理和團隊的功勞,而我只是參與其中的一部分而已,但這對我而言有特殊的意義;因爲這是我的第一個基於linux的商用上位機軟件。雖然以前在windows平臺折騰過java、C#、MFC的小上位機,但那些上位機無論從代碼量和功能上都無法和這個商用上位機相提並論。當年在做畢業設計時,見識到了linux系統功能的強大,一直想從事linux系統的軟件開發;但爲了儘快找到工作,只能先找擅長的單片機和stm32的軟件開發工作。然後利用業餘時間再學習linux系統相關知識。由於缺乏正確的引導,學習linux系統的應用程序開發走了很多彎路;選擇了一套課程,根據課程先學了linux的設備驅動開發,學習了linux的某個模塊源代碼;雖然這部分在後來的工作中也用到了一點點,但這畢竟和linux應用程序開發是兩個方向的工作;到了2016年初才學會如何在linux上開發Qt應用程序;造化弄人,到了2016年底終於有機會讓我開發基於linux的應用程序。

        由於加入項目組的時間比較晚,加上是第一次開發商用上位機,缺乏經驗,沒有針對需求做詳細的軟件架構設計,一上來就根據需求開始編碼;這種方式開發一些學習軟件沒有問題,但是開發功能繁多的商用軟件肯定不可取;就像壘一個雞窩前期可以不用設計圖紙,但是建一棟高樓大廈,如果前期沒詳細規劃和設計圖紙,那將會帶來無盡的問題。前期沒有詳細得設計軟件架構,就根據開發單片機軟件的經驗用C語言的思維去開發C++軟件,在剛開始開發一些調試執行機構的軟件時,還沒察覺到有什麼問題。隨着不斷的新增功能,代碼量越來越大,特別是在處理測試數據時,這時就不斷的暴露出一些致命的問題。導致項目經理在測試機器性能時,整個軟件bug滿天飛,黑屏不斷。項目經理雖然一直在催進度,但並沒給我很大的壓力,而是一直相信我能改好。剛開始調試bug時手段比較單一,只是把程序的運行情況打印到控制檯上,雖然這是很常用的調試手段,但侷限性也很大;因爲當機器在不同地方使用時就得在那的電腦安裝串口調試助手才能知道機器運行情況,若是交到客戶那使用呢?經過不斷查詢資料發現Qt提供了運行日誌的功能,雖然之前有通信日誌,但那遠遠不夠;熟練掌握了Qt運行日誌的功能後,就在軟件加上這個功能;果然收到了很好的效果,不管機器在哪裏運行,只要一出問題,就可以根據運行日誌和通信日誌很快定位到原因,而打印運行日誌時就很考驗經驗了,打印多了影響軟件性能,打印少了不利於定位原因。但在開發軟件的階段時要查看一些變量的值時,每次都得登錄後臺打開運行日誌進行查看,顯得很繁瑣。根據開發單片機軟件的經驗,每次遇到bug都是仿真,因此就引進了GDB調試,由於所用開發環境版本比較低,無法使用一鍵遠程調試,但是使用gdbserver的方式也可達到同樣的目的;使用了GDB調試後可定位到軟件運行的具體語句並查看變量的值;大大提高了開發效率。有次朋友問我當linux的應用程序崩潰時有沒有獲取Linux的core文件進行定位程序崩潰的原因;我直接回答:“沒有!”;然後朋友就用鄙視的眼神看了我一眼,那種鄙視的眼神讓我久久不能忘懷;沒方法學藝不精,只能在鄙視中成長!然後查閱了大量資料並做了相關實驗,瞭解linux的core文件是什麼以及如何使用;原來linux的core文件就像飛機失事後的黑匣子;當linux的應用程序崩潰時導致黑屏,core文件會記錄下應用程序最後運行的各種情況,然後再用GDB調試core文件即可定位到出問題的原因,甚至定位到具體哪一語句導致程序崩潰;有時根據core文件定位出問題的類型,然後根據運行日誌再定位到具體原因;兩種調試手段結合使用。在開發軟件過程中總會遇到各種各樣的bug,而豐富的調試手段將決定是否能很快定位原因並解決bug。從一開始遇到bug的慌張到最後的淡定;上述幾種調試方法給了我很大的底氣。

        雖然掌握了幾種調試方法,可以比較快速定位bug原因;但保證不了整個工程的代碼質量。由於前期缺乏整體軟件架構設計,到了中後期,進入代碼維護和新增需求時,修改代碼時經常是“牽一髮而動全身”,修復了一個bug往往會引進另一個bug;新增一個功能則是會牽動到其他的功能;整個軟件工程就像一個豆腐渣工程。爲了扭轉這種頹勢,買了很多書和在網上找各種相關的視頻教程。經常有人問買那麼多書看得完嗎?當然是看不完,但一個本書只要幫助解決一個小問題就賺了;更何況有的書不但可以協助解決問題還可以帶來有體系的知識點。找各種相關視頻教程是爲了看看其他大神寫的代碼,因爲提高寫代碼的能力就是看大神寫的優秀代碼然後模仿;在以前購買的教程學習羣裏有人介紹了狄泰軟件學院的課程,由於以前購買課程的陰影,剛開始我也猶豫了一段時間,後來遇到的問題實在太多,抱着試試的態度而且價格也不貴就買了一套Qt課程;看了課程後就有種“相見恨晚”的感覺。課程通過寫幾個小小項目來講解知識點;看老師寫小項目代碼時經常感到醍醐灌頂,原來還可以這樣寫代碼;其中項目界面的全用代碼生成,爲用代碼生成界面提供了模板;還有把C/C++的各種基礎知識巧妙靈活配合使用而不是簡單的“if else”和“switch case”;例如把C/C++的“短路原則”、“條件表達式”和“逗號語句”的作用發揮得淋漓盡致使得代碼簡潔清晰;因之前看過整套C++視頻,這些基礎知識雖然都懂,之前卻不知怎麼樣使用;這讓我堅信了基礎知識的重要,只有基礎知識紮實才能寫出有質量的代碼和設計出工業水平的軟件架構。看完了這些再對照自己寫的代碼,然後通過模仿課程的寫法幾乎重構了整個軟件代碼,也重新設計了整個軟件的編碼風格。

        雖然整個軟件有了良好的編碼風格,但卻找不到解決界面與數據分離的方法;直到看了課程中講解的自定義模型類,用分層思想實現了數據到視圖的控制流程,每層用一個類表示,用自定義的模型類組合了標準模型類,靈活顯示各種數據;定義數據源類操作底層數據文件,用於把數據對象轉換成字符串寫入數據文件,讓上層代碼只需操作數據對象即可,妥妥的面向對象編程;這樣就使得程序結構層次分明,代碼寫起來簡單明瞭便於維護。這套設計我只需做簡單的修改,增加少量的代碼,即可用於解決我的軟件界面與數據分離的問題;這套設計還讓我學會了如何面向對象編程,就是在解決問題時,先把問題抽象成類,然後再定義操作類解決問題後返回相應問題對象。這種思想在課程實現簡易網絡聊天軟件時得到了進一步的體現。在解決網絡通信的數據粘連時,定義了通信協議類,然後定義協議對象裝配類用於把通信數據裝配成協議對象並返回給上層代碼處理;通過舉一反三修改少量代碼即可用於解決我軟件的串口通信數據粘連的問題,相比於原來用C語言思維方式解決問題,代碼顯得有層次有模塊,完全符合“強內聚弱耦合”的設計原則。

        有了靈活巧妙運用各種基礎知識的模板,有了如何用代碼生成界面的模板,有了界面和數據分離的模板,有了運用面向對象編程思維解決通信數據粘連的模板;接下來就是模仿這些模板寫法,重構自己的軟件代碼;而整個工程代碼將近十萬行,幾乎是全推倒式的重構;而現實情況不可能是接下來幾個月不新增需求和修復bug;所以只能“亂中求治”,在新增功能和修復 bug時堅持“摳”一點時間或利用加班時間用於逐漸改善代碼設計,逐漸使代碼的質量越來越好。最終使整個工程代碼層次分明,結構簡潔清晰,模塊化,爲後期維護打堅實基礎。

        在完成整個軟件的功能中另一個困難就是各種非線性曲線的擬合,剛開始面對這種只有在研究生課程纔會學到的數值分析束手無策;後來由於時間關係,這部分就交給另一個同事,他用開源庫搞定了。但由於對其中各種擬合曲線的興趣,我開始翻閱各種資料,慢慢發現可以看懂簡易的樣條曲線擬合推導過程;這更激起了我的興趣,更加認真學樣條曲線擬合推導的全部過程,學習的過程就像柯南破案一樣,一點一點的接近真相,每次有進步一點都能讓我興奮不已;先是在馬東昇和董寧編寫的《數值計算方法》學了樣條曲線擬合的推導理論知識,並看懂其中的幾道例題;然後在王曉華編寫的《算法的樂趣》學會了把方程組變化成矩陣,通過克洛脫法分解成兩個三角矩陣,再用追趕法求得方程組的解。最後在John H.Mathews和Kurtis D.Fink著的《Numberical Methodes Using MATLAB》瞭解了樣條曲線端點約束的幾種情況,對樣條曲線有了全面的認識;同時也知道機器中樣本曲線擬合適那種端點約束。結合幾本書學到的知識點,最後編寫成了代碼,並且計算結果和用開源庫擬合的曲線參數是一樣的,這讓我成就感爆棚。擬合曲線完成後,在計算測試結果時,則是讓我學會了用牛頓迭代法求解一元三次方程;還有如何快速判斷拋物線在一個區間內的單調性,妥妥複習了一下高中數學。

        從寫下第一行代碼到軟件跟隨機器上市,這個過程遇到過千千萬萬的問題,而每一個詭異的bug和問題背後都隱藏着一個低級錯誤,每當解決一個詭異的bug都能帶來一點點成就感和一點點進步;這也是我從畢業後這幾年來,一直堅持學習linux應用開發的原因,雖然這幾年讓我失去其他的很多東西,思想也有過波動,最後慶幸堅持了下來,終於有一款基於linux的商用上位機,也算是隨了幾年前的心願。

                                                                                                                                                                               2019年12月31號

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章