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