开发小结-杂项类
本文總結在平時開發工作中一些雜項零碎知識點。
SVN操作
改名操作
移動文件
更新失敗處理
若在文件正在被占用時執行svn update,svn會提示更新失敗,此時整個svn狀態不正確,右鍵點擊目錄無正確的入口菜單,可以通過如下方法來解決:
sqlite3 .svn/wc.db "delete from work_queue" ---> 刪除這些更新失敗的記錄
sqlite3 .svn/wc.db "select * from work_queue" ---> 確認是否刪除完畢
經過如上操作,就能清除更新失敗的文件,再重新update一下。
查看文件版本信息
查看項目目錄的右鍵屬性
查看項目修訂記錄中的記錄,當前標記為黑色的為當前項目的版本號
JIRA問題單號需要和SVN的提交編號綁定起來,那樣在查找問題時,方便雙向回溯查找。
問題搜索
看書的時候,帶著問題和自己預期的答案去在書中查找對應的知識點,或印證,或加強,或反思。對于好的東西,我們不光要學習,而且要把它內化為自己的東西。我們要學習別人的先進經驗,辦事方法,但在運用中要實事求是,具體問題具體分析。
以尋找解決"獲取操作系統所在磁盤分區信息"方案為例子,在剛開始時,我犯了一個錯誤具體表現為,沒有將注意力關注于問題域,而是在網上大范圍的搜索獲取磁盤信息做法,在找到的這些通用做法中,不僅會有需要的內容,也有大量不需要關系的內容。在面對這些內容,本著多學一點是一點的心態,開始寫些demo來學習,但做到后面,越發覺得距離最原始的問題越來越遠。就算把整個相關知識點全部吃透,再回到原始問題上,花費的精力相當于殺雞用牛刀。雖說最終還是解決了問題,但從時間和效率上,還有大大的優化的空間。
反思下,以后在針對問題進行方案搜索時,要先定義問題域范圍并且了解基本背景知識。然后,針對待解決的問題,只搜索關聯度高的網頁,大致瀏覽一片,若覺的合適,則可寫些測試代碼,這里的測試不要摻雜與待解決問題無關的代碼,只關心待解決的問題,能簡則簡。
效率提高點
在進行會議討論(需求討論、方案論證等)時,就討論的問題,陳述的中心思路是講解問題的背景、問題的現狀、問題的困難點,而不是講述自己對該問題心中默認的結論,我們討論的是問題,而不是問題提出者的結論。
工作用到的IDE,最多只能打開兩個,在一個IDE中完成一個任務后,如果沒有其他的任務,要關閉它。防止在太多IDE中切換,耗費無用時間,就像進程調度一樣,進程切換的成本很高,無論是機器還是人,都要一段時間才能進入全速運行狀態。
刪除Dll時提示被占用
在 Windows 下面刪除dll時,提示被系統使用,無法刪除。較好的思考路徑是:
1. 找到該 dll 被哪個進程占用?Windows下可以使用 tasklist /m XXX.dll 來找 2. 在任務管理器中,暫時中止該進程(如果是窗口管理器占用,那么中止后,任務欄會消失) 3. 通過 dos 命令來刪除文件和文件夾(刪除文件使用 del, 刪除空文件夾使用 rd)代碼小技巧
針對動態空間的,若已知空間大小,可以使用
int nReqSize = 1024; string strBuf(nReqSize, ' '); char* pReqBuf = (char*)strBuf.c_str();do...while(false),配合break可實現類似goto的功能,用于簡化多級判斷代碼的跳出處理。
do{if (condition1)break;if (condition2)break;}while(0)在一系列計算的中間過程,只要有一處臨時變量在計算過程中,可能超過相關數據類型能夠表達的最大范圍,那么最終結果就很可能會出錯,這種錯誤很難發現,要滿足特定的場景才會發現,在后續涉及到較大數量的計算時,一定要注意。
利用靜態代碼檢查工具cppcheck,cpplint來輔助檢查你的代碼。針對資源泄露的問題,注意相關資源申請和釋放函數的配對使用
調試經驗
在需要查看數據發送內容,而又不想通過斷點來中斷執行流程,可以通過 VS 的 條件斷點 配合特定的條件,在調試輸出窗口中查看收發內容。
找內存泄漏:根據vld輸出的信息,找到泄露內存的具體字節數和內存分配序號,然后在 dbgheap.c 文件中的 391 行出 打上條件斷點,通過申請的具體字節數來大致定位是哪一個文件上申請了內容,可以大致定位內存泄漏的源頭。
描述類與類,窗體與窗體之間的相互交互的關系,最好用序列圖來描述。流程圖中異步處理,可通過帶箭頭的虛線來表示異步響應的流程。
- 永遠不要混合Tab鍵和Space鍵。 VS設置,將TAB鍵轉換為4個空格
在程序中,全角和半角英文混用,容易造成顯示不一致,在設計的時候要注意。
在工程實踐中,多線程開始初始化之前,對整個工程中所涉及到的單例按照前后的邏輯順序,完成手動的初始化,這可避免首次調用時的不確定性,簡單明確。
當一個條件判斷(if,while)比較復雜,并且是隱含有一定的業務背景知識的,一定要寫好注釋,不僅是給自己方便,也是給其他人方便.
從接口中返回const char*指針給外部的string變量,所對應的一塊內存是如何響應外部變化的?實際上是調用 string::operator=(const _Elem* _Ptr) 賦值構造函數來完成對應地址內容的拷貝的.
提示:在VS調試,無法進入到stl的內部函數中去,因為用到 破解的VS助手,把VS助手給禁用掉,重新啟動VS,就可以調試進入stl內部。
發布給別人的軟件,一定要先在自己虛擬機上面跑一次,防止一些軟件依賴的dll在用戶機器上沒有,啟動時爆出“未找到 mfc100.dll”的問題。多在自己本地測試下,確保在各種情況下正確后,再交付給用戶。
C++本身提供了四種標準異常: 只能通過 傳值 或者 引用 來捕獲, 傳值捕獲異常,會將異常對象拷貝兩次,效率較低。
bad_alloc --> operator new 不能分配足夠內存時拋出
bad_cast --> 當 dynamic_cast 針對一個引用reference操作失敗時,拋出
bad_typeid --> 當 dynamic_cast 對空指針進行操作時,拋出
bad_exception --> 用于 unexcepted 異常總結:優先使用傳引用來傳遞異常
對象構造要做到線程安全,要求在構造函數期間,不對外暴露this指針。作為class數據成員的mutex,只能用于同步本class的其他數據成員的讀和寫,它不能安全的保護析構.因為類成員的生命周期最多與對象一樣長,而析構動作發生在對象銷毀之時。
二進制兼容性
二進制兼容性指的是在升級庫文件時,不必重新編譯使用了這個庫的可執行文件或者其他庫文件,程序的功能不被破壞。
C++二進制兼容性,在于以虛函數作為庫接口時,更新庫接口后調用的不確定性。本質在于虛函數是以vtable[offset]方式實現虛函數調用,offset又是根據虛函數聲明的位置隱式確定,一旦新舊版本的虛函數相對位置有變化,就可能帶來兼容性問題。
解決方法:
可以使用 靜態鏈接
用 pimpl 技法: 在頭文件中只暴露 non-virtual 接口,并且class的大小固定為 sizeof(Impl*),這樣可以隨意更新庫文件而不影響可執行文件。
在什么場景下,需要考慮二進制兼容性? 當你是一個shared library的維護者,你提供的庫被其他團隊、其他公司、其他社區所使用時,需要考慮。這里面有兩點:共享庫的維護者,并且該庫被不受你控制的團隊所使用。
如果只是開發團隊內部特定場景下特定功能的庫,使用范圍較窄可以不用太在意二進制兼容性,發布新版本(修復Bug或者增加功能),通知外部使用者重新編譯,使用即可。
修補Bug的patch應該做到二進制兼容,比如1.1.1應該和1.1.0,兼容,修復了一些bug,或者增加不影響二進制兼容的功能如果新增功能與原有版本的二進制不兼容,那就應該發布到1.3.0版本上去。
如果需要hot fix,那么一定要發布為動態庫,否則,在分布式系統中使用靜態庫更容易部署。
作為一個庫來說,以什么方式暴露庫的接口?一般來說有以下三種方式:
以全局(含namespace級別)的函數為接口
以class的non-virtual成員函數為接口,內部輔以 pimpl(pointer to implementation) 來提供具體實現。<-- 推薦采用這種方式,可以確保二進制兼容性
并考慮多采用 non-member,non-firend function in namespace 作為接口,對外暴露的接口不要有虛函數,不要有數據成員。
以class的virtual函數為接口(interface),客戶端繼承這個interface,然后將對象實例注冊到庫中,由庫來回調自己
Debug和Release庫兼容性
- 在Windows上,比如Visual C++編譯的時候要選擇Debug或者Release模式,而且Debug模式編譯出來的library通常不能在Release binary中使用,反之亦然。這是因為在這兩種模式下的CRT二進制不兼容,主要是內存分配方面的,Debug有自己的堆。
在linux下,編譯時涉及到調試的選項為 -g,增加調試開關宏-DDEBUG,編譯發布版本時,一般加上 -O3 ,然后利用strip,去掉調試信息.
從這上面來看,linux下的庫是不區分Debug模式和Release模式,只不過是運行效率的不同而已。
配置文件實時更新讀取
要做到修改配置文件能夠實時生效,要做到兩點:
當配置文件被外部修改時,要主動向外投遞"配置已改動"的消息,相關進程要被動。
本模塊針對獲得配置文件數據的數據時,在本地不維護配置屬性副本,每次使用時,主動從配置文件接口中去讀取。
字體配置
比如,目前A處和B處目前顯示字體都是微軟雅黑字體ID,現在來需求了:要求B處顯示為微軟雅黑加粗字體,怎么做比較好?
方案一:每一個字體ID都在配置文件里,若要顯示為對應加粗字體,那就新增一個字體配置。如果存在多種字體風格配置文件,那么在每個配置文件中都需要添加該新增字體。
優點:現有獲取字體邏輯不變,新增字體對應新增字體ID而已。
缺點:每新增一個與現有字體樣式風格差別很小的字體,都要在眾多配置文件中新增。
方案二: 基礎默認字體這三五種,在不新增字體種類的情況下,提供一個 GetBoldFont(nFondId, BoldFont)接口函數,可將基礎字體顯示風格微調,有其他屬性,可以增加其他微調接口。
優點:在不新增字體種類的情況下,增加靈活性,如果有其他風格類型的字體需求,直接使用該函數即可。
缺點:在獲得加粗字體,需要使用特定的函數來實現。
個人認為,方案二是較好的方式?;A數據提供一套,微調接口提供一套,外部可任意組合實現自定義需求。
界面數據請求
當有一個界面,需要請求數據A,數據B。又有一個新界面,也要請求數據A,數據B,再來了一個新界面,也要請求數據A,數據B。如何減少重復請求代碼?
總體思想:將各個界面重復性的請求代碼邏輯抽離出來,抽離出來放在哪里呢?
有兩個選擇,一是放到基類中去,二是放置在獨立實現中。
方案一會在基類業務中混雜具體的業務數據請求邏輯,本來基類應該是業務無關的,加上去會混淆職責,以后有新的通用數據需求,可能還會增加到基類中,長此以往,基類會越來越龐大,不利于維護。
方案二,將通用的操作放到獨立數據收發類中去,對外提供統一接口,具體來說,各類數據的請求接口是類似的,細分需求可通過傳參來區分。不同界面對數據的響應處理是互不相同的,因此,響應的處理要抽離成虛函數,留給各個界面去處理。各個業務界面繼承該數據收發類,重載響應虛函數即可。
方案三:將通用的操作放到獨立數據收發類中去,對外提供統一接口,但是,數據收發類和具體的業務類之間是通過注入的方式完成關聯,每個請求關聯一個發送請求頁面的指針,當數據返回時,請響應數據回調給發送請求頁面即可。
個人認為,方案二和方案三都有適用場景,需要具體問題具體分析。
轉載于:https://www.cnblogs.com/cherishui/p/10455418.html
總結
- 上一篇: jquery选择器和基本操作
- 下一篇: Jenkins环境搭建(2)-搭建jme