?
今天我們的高級開發工程師張曉培將會帶領大家一起探索開發中遇到的各種問題,
培哥(法號:西街惡人)用詼諧幽默的言語為大家迅速打開了開發的大門,
從走入Web Development、繼續探索Web Server以及Pair Programming三個方面共同領略開發的魅力。
CargoWare開發問題集錦
——培哥
走入前端世界
萬惡的NullPointerException
Memory爆了
Flex開發中所使用的ActionScript語言(簡稱AS)也是一種支持GC的語言。
經過編譯后的AS代碼運行在AS虛擬機(簡稱AVM)中,由AVM自動完成垃圾內存回收的工作;
Flash Player垃圾回收工作是由垃圾回收器(garbage collection)完成的,運行在后臺的一個Process;
AS采用兩種方法來判定一個對象是否還有活動的引用,從而決定是否可以將其回收。
一種方法是引用計數法,另一種方法是標記清除法。
Memory Leak原因舉例
引用泄露:對子對象的引用,外部對本對象或子對象的引用都需要置null ;
系統類泄露:使用了系統類而忘記做刪除操作了,如BindingUtils.bindSetter() ,ChangeWatcher.watch() 函數時候
完畢后需要調用ChangeWatcher.unwatch() 函數來清除引用,否則使用此函數的對象將不會被刪除;
類似的還有MUSIC ,VIDEO ,IMAGE ,TIMER ,EVENT ,BINDING 等。
效果泄露:當對組件應用效果Effect 的時候,當本對象本刪除時需要把本對象和子對象上的Effect 動畫停止掉,
然后把Effect 的target 對象置null; 如果不停止掉動畫直接把Effect 置null 將不能正常移除對象。
SWF 泄露:要完全刪除一個SWF 要調用它的unload() 方法并且把對象置null;
圖片泄露:當Image 對象使用完畢后要把source 置null;( 為測試) ;
聲音、視頻泄露: 當不需要一個音樂或視頻是需要停止音樂,刪除對象,引用置null。
Memory Leak解決方法
在組件的REMOVED_FROM_STAGE 事件回掉中做垃圾處理操作(移除所有對外引用(不管是VO 還是組件的都需要刪除),
刪除監聽器,調用系統類的清除方法),先remove 再置null, 確保被remove 或者removeAll 后的對象在外部的引用全部釋放干凈;
利用Flex 的性能優化工具Profile 來對項目進程進行監控,可知道歷史創建過哪些對象,
目前有哪些對象沒有被刪除,創建的數量,占用的內存比例和用量,創建過程等信息。
正確的使用集合
Flex中集合有Array、ArrayCollection、Vector,
以下是插入和遍歷10000項性能對比:
插入10000項
Array耗時:465
ArrayCollection耗時:788
Vector耗時:444
遍歷10000項
Array耗時:2
ArrayCollection耗時:98
Vector耗時:2
Array與Vector性能接近,插入時Vector略快,遍歷相近,
Vector的優點是強類型,缺點是要Flash Player 10,所以作數據存儲運算等建議使用Array。
ArrayCollection性能最差,插入時約比Array慢了一倍,遍歷慢了幾十倍,
ArrayCollection的優勢是界面的數據綁定以及支持數據排序等高級方法。
我們可以更快
①Load on demand ②返回指定的字段
③Minimum nested ④使用正確的組件
繼續探索后端
Hibernate自動更新的坑
之前有個開發的同學遇到一個問題,跑來問培哥,hibernate查詢出來的對象集合,
根據業務需要遍歷賦值,結果賦值的對象都會更新到數據庫...
在培哥看來,這明顯是有問題的。
在查看日志后發現,系統總是會打印出一個update語句,
說明系統的確是執行了更新操作的,但是這里并沒有調用任何和update相關的方法。
通過hibernate中hql查詢出的實體都是持久化對象,拿到該對象后,如果調用了該對象的set方法,
那么在事務遞交的時候,Hibernate會把設置的值自動更新到數據庫中。
如何處理這個問題?
采用getCurrentSession().evict(entity),懶加載獲取的實體后,
通過調用evict(entity)的方法,把緩存持久化對象變成托管狀態。
變成托管狀態后,Hibernate就不會再去自動更新該實體。
什么是懶加載?以及他的作用
延遲加載,也叫懶加載,它是Hibernate為提高程序執行效率而提供的一種機制,即只有真正使用該對象的數據時才會創建。
當我們要修改這個對象的數據時,可能會發生no session的錯誤,
這是因為事務已經提交session已經關閉,而我們還要去查詢數據庫,所以hibernate就報錯。
解決方案
通過對象的主鍵查詢一次數據庫賦給新的對象,再進行數據操作。
高效操作LIST
查找不同元素
兩層遍歷查找,遍歷次數為list1.size()*list2.size(),有點蠢;
兩層遍歷查找,用retainAll()方法查找,也很蠢,方法底層依舊是兩層遍歷;
用Map存放List1和List2的元素作為key,value為其在List1和List2中出現的次數。
學以致用
查詢結果需要計算某個字段;計算交集、差集。
發現更新結果不對
ExecuteUpdate介紹
executeUpdate用來執行HQL的更新或者刪除語句。
返回結果為整數型,可能有些時候程序會根據更新的返回結果來執行下一步操作,
這會導致判斷不正確,具體要看程序配置mysql鏈接useAffectedRows設置是否正確;
useAffectedRows的含義 :是否用受影響的行數替代查找到的行數來返回數據,也就是查找到了 但卻不一定真正修改了。
結對編程
什么是結對編程?
在此模式下,一對程序員并肩作戰,平等互補進行開發工作。
兩個程序員并排坐在一臺電腦前,同對一臺顯示器,使用同一個鍵盤,同一個鼠標進行工作。
一起分析,一起測試,一起設計,一起編程。
結對編程的好處
互相鼓勵,不容易沮喪;互相監督,不容易偷懶;互相學習編程技巧;
可以培養和訓練新人;多雙眼睛,少點 bug。
結對編程的壞處
1、與合不來的人一起編程容易發生爭執,不利于團隊和諧;
2、經驗豐富的老手可能會對新手產生不滿的情緒;
3、一山不容二虎,開發者之間可能就某一問題發生分歧,產生矛盾,造成不必要的內耗;
4、開發人員可能會在工作時交談一些與工作無關的事,分散注意力,造成效率低下。
什么時候采用結對編程?
最主要的因素是技術與挑戰相匹配。
在獨自編程中,如果技能和挑戰能互相匹配,最高產的模式就是流模式。
結對編程添加了一個更有效的模式——指導模式,它能夠提高全隊當前與未來任務的生產率。
A)成功的模式
1. 流模式(Flow)——兩個程序員共同從事一個有趣又有挑戰性的問題。
他們會有不同的技術、遇到不同的挑戰,但是它們都善于找到好的解決方法。
例如,其中 一個人可能是javascript專家,另一個人可能是強大的后臺程序員。
他們能夠結合彼此的腦力、知識及經驗來共同處理復雜的AJAX任務,從而創造出 最好的解決方案。
2. 指導模式(Coaching)——老練的程序員在解決問題方面有經驗和知識,可以與其他不能有效地獨自解決問題的程序員分享。
后來加入的程序員有足夠的理論基礎來理解這些解決方法和程序的實現。他會在學習中慢慢進步,成為更優秀的程序員。
B)失敗的模式
3. 浪費專家時間(Wasting expert time)——問題太簡單,以致專家的經驗無指導意義
4. 不知所措的新手(Overwhelmed novice)——問題太過復雜或者需要太多新知識,使程序員學不到任何有用的東西。
C)有疑問的模式
5. 兩個專家共事一個易管理的任務——若兩個程序員都了解如何實現任務并且之前都成功地解決過相似的問題,那么結對編程就沒有太多的用處了。
6. 一個程序員處于流模式(Flow),另一個在一旁學習(Learning)——若另一個程序員時不時地打斷他,
并要求對一些基本的但與挑戰性問題沒有直接關系的事情做出解釋,那么他很難專注于解決挑戰性的問題。
7. 一個程序員處于流模式,另一個專注于指導(Coaching)——如果想讓這種模式獲得成功,指導者應該思想開放,避免指導過多,
同時也可以給另一個程序員想出自己的(甚至是更好的)解決方法的機會。
END
專家招募活動進行中~
WallTech誠邀我們的客戶大佬們
成為常年客座講師傳道受業解惑
有想要報名的大佬們歡迎聯系市場部哦~
科技改變生活,也在改變我們的工作!
CargoWare一小步,
貨代轉型一大步!
如此方便快捷的工具!
還不速速來一套?