自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

挨踢部落故事匯(32): Java深坑如何填?

原創(chuàng)
移動(dòng)開發(fā)
世上本沒有坑,踩的人多了也便成了坑。每遇到一次困難,每踩一個(gè)坑,對(duì)程序員來說都是一筆財(cái)富。持續(xù)學(xué)習(xí)是程序員保持競爭力的源泉。本期將分享一個(gè)踩坑無數(shù)的Java程序猿填坑秘籍。

【51CTO.com原創(chuàng)稿件】世上本沒有坑,踩的人多了也便成了坑。每遇到一次困難,每踩一個(gè)坑,對(duì)程序員來說都是一筆財(cái)富。持續(xù)學(xué)習(xí)是程序員保持競爭力的源泉。本期將分享一個(gè)踩坑無數(shù)的Java程序猿填坑秘籍。

榆木,一個(gè)閱歷無數(shù)(踩坑)的技術(shù)宅男,喜歡了解新技術(shù)卻不愛太鉆研新技術(shù)(因?yàn)閼?,猿屆反面角色一枚)?4年畢業(yè)至今,在Java開發(fā)這條道路上可謂是坑過好些人、也埋過好些坑、也被坑過好些次。因?yàn)閼?,沒有針對(duì)他遇到過的問題做過太多的筆記(記錄一些棘手問題的解決方法還是個(gè)不錯(cuò)的習(xí)慣),只是習(xí)慣性的去分析為什么出現(xiàn)這樣的問題,我們?cè)撛趺慈ケ苊庵貜?fù)出現(xiàn)。在這里榆木share一下***次做獨(dú)立需求的過程。

[[211461]]

榆木·Java開發(fā)工程師

要成為一個(gè)合格的Java程序猿,獨(dú)立完成需求是一個(gè)必須經(jīng)歷的階段,在這個(gè)過程中可能會(huì)遇到很多問題,要學(xué)會(huì)合理的利用資源(官方文檔、社區(qū)論壇等)去解決問題。在這個(gè)階段應(yīng)該是踩坑最多、收獲最多、成長最快的階段。

在榆木入職的前3個(gè)月里,做的都是一些改bug、完善需求的活,他不需要太多思考,根據(jù)客戶說的做就成了。三個(gè)月之后他的公司順利拿下了該客戶的二期項(xiàng)目,由于人手不夠,再加上他在一期維護(hù)的時(shí)候?qū)I(yè)務(wù)比較熟悉,老大便讓榆木獨(dú)自承擔(dān)該項(xiàng)目前置子系統(tǒng)的全部需求。剛開始的時(shí)候榆木是很激動(dòng)的,隨之而來的卻是不知所措。

榆木都是如何踩坑又填坑的呢?分享一下他的幾點(diǎn)經(jīng)驗(yàn),希望對(duì)開發(fā)者有所幫助。

如何同時(shí)開啟兩個(gè)SVN服務(wù)

因?yàn)楣举Y源不夠,老大就要求在原有的服務(wù)器上再弄一個(gè)SVN服務(wù),于是他開始各種搗騰,可是不管怎么樣就是沒有辦法同時(shí)起來兩個(gè)服務(wù)。怎么辦,只能找哥哥(google)幫忙咯,因?yàn)镾VN服務(wù)的啟動(dòng)(/etc/init.d/svnserve start )是包含一些默認(rèn)參數(shù),如 --listen-port指定服務(wù)端口 默認(rèn)是3691,如果要同時(shí)起兩個(gè)SVN服務(wù)只需要在啟動(dòng)時(shí)指定兩個(gè)不同的listen-port就OK了。

如下,問題解決:

  1. /etc/init.d/svnserve start   -d -r /svn/repo  ***次***個(gè)庫啟動(dòng)  默認(rèn)3691 
  2. /etc/init.d/svnserve --listen-port 9999 -d -r /svn/svndata  第二次指定端口啟動(dòng) 

問題搞定,緊接著就是緊張的代碼開發(fā),事情有點(diǎn)想不到的順利,后端接口順利完工通過測試,榆木開始和前端對(duì)接聯(lián)調(diào),好激動(dòng),搞不好可以提前完成任務(wù)了。噼里啪啦的搞完就開始測試了。

fastJson序列化問題

所謂沒有遇到過bug的程序猿就不是正常的程序猿,一點(diǎn)都不意外,問題來了。同一個(gè)對(duì)象賦值給HashMap中不同的key 傳到前端后,第二個(gè)value竟然不能被正常解析....... 他自己寫的代碼必須不能慫,有問題那就解決問題,于是榆木開始找問題所在,開始模擬數(shù)據(jù),發(fā)現(xiàn)返回結(jié)果如下:

  1. {"o1":{"age":16,"name":"o1"},"2":{"$ref":"$.o1"}}  

很容易就能看出來,第二value在這個(gè)返回結(jié)果中用類似指針的方法("$ref":"$.o1")表示它和“o1”的值一樣,看起來像是同一個(gè)對(duì)象的循環(huán)引用哦,那是不是可以把這個(gè)循環(huán)引用禁止呢?答案是可以的。(有必要說明一下,這里使用的是fastJson)通過SerializerFeature指定禁用循環(huán)依賴就可以了。修改前代碼如下:

  1. public static void test1() { 
  2.         TestObject object = new TestObject("o1", 16); 
  3.         Map<String, TestObject> map = new HashMap<String, TestObject>(); 
  4.         map.put("o1", object); 
  5.         map.put("o2", object); 
  6.         System.out.println(new String(JSON.toJSONBytes(map))); 
  7.     }        

輸出結(jié)果:{"o1":{"age":16,"name":"o1"},"o2":{"$ref":"$.o1"}}

在一個(gè)集合對(duì)象中存在多條相同數(shù)據(jù)時(shí),將ist集合對(duì)象轉(zhuǎn)化為json對(duì)象輸出到前臺(tái)時(shí),JSON默認(rèn)對(duì)第二條數(shù)據(jù)處理時(shí)用"$ref":"$.object".<這里object指***條數(shù)據(jù)>,這樣的json轉(zhuǎn)化結(jié)果輸出到前臺(tái)肯定是不可以使用的,好在JSON有提供禁止關(guān)閉引用循環(huán)檢測的方法,只需要在轉(zhuǎn)化的時(shí)候加上SerializerFeature.DisableCircularReferenceDetect  就可以解決了。修改后代碼如下:

  1. public static void test1() { 
  2.        TestObject object = new TestObject("s1", 16); 
  3.        Map<String, TestObject> map = new HashMap<String, TestObject>(); 
  4.        map.put("o1", object); 
  5.        map.put("o2", object); 
  6.        SerializerFeature feature = SerializerFeature.DisableCircularReferenceDetect; 
  7.        System.out.println(new String(JSON.toJSONBytes(map, feature))); 
  8.    } 

輸出結(jié)果如下:{"o1":{"age":16,"name":"o1"},"o2":{"age":16,"name":"o1"}}

到這里問題就解決了。不久之后測試通過了,交付客戶測試版本,開始和中心聯(lián)調(diào)測試了。

OOM異常處理

榆木以為到這里就萬事大吉了,然而是不可能的。聯(lián)調(diào)測試兩天之后,客戶反饋說:“我們的XXX報(bào)文數(shù)據(jù)已經(jīng)往中心發(fā)過了呀,可是中心說他們沒有收到,你們查下是什么問題唄!”客戶就是上帝呀,榆木和他的同事開始查詢?nèi)罩?,發(fā)現(xiàn)有一些OOM的異常。異常產(chǎn)生的場景是在取數(shù)據(jù)-組報(bào)文-MQ轉(zhuǎn)發(fā)這個(gè)環(huán)節(jié),然后就開始一個(gè)一個(gè)點(diǎn)的排查了。

榆木首先想到的可能原因有:

1、數(shù)據(jù)取出來生成報(bào)文這個(gè)過程都是在內(nèi)存中做的,會(huì)不會(huì)是這里數(shù)據(jù)太多導(dǎo)致?

2、會(huì)不會(huì)是報(bào)文生成過程產(chǎn)生了過多Object沒有來得及回收?

3、會(huì)不會(huì)是數(shù)據(jù)發(fā)送慢于報(bào)文生成的速到導(dǎo)致等待隊(duì)列爆滿?

然后開始針對(duì)性的做修改測試,他將一次性取數(shù)據(jù)生成報(bào)文的過程改成批量去做,然后測試運(yùn)行一段時(shí)間沒有問題(排除 1);在生成保溫過程中,將每一個(gè)轉(zhuǎn)化后的對(duì)象置為空Object=null,以便及時(shí)回收,測試運(yùn)行一段時(shí)間沒有問題(排除2);在第三點(diǎn)上面,他***想的是增加線程數(shù)量( 服務(wù)器開啟超線程、應(yīng)用中增加線程數(shù)量)去提升處理速率,運(yùn)行一段時(shí)間之后還是會(huì)出現(xiàn)OOM。怎么辦呢?再次回到了等待隊(duì)列上面來,能不能在一定程度上對(duì)等待隊(duì)列做個(gè)限制呢?于是榆木在每次從MQ取消息之前增加了對(duì)等待隊(duì)列的深度的判斷,如果深度大于***線程數(shù)量的2倍,就放棄本次MQ隊(duì)列消息的處理。然后繼續(xù)測試,問題沒有再出現(xiàn)。

查詢慢怎么辦?

最終項(xiàng)目上線了,終于可以松一口氣了。可是有一天,榆木的老大說客戶反映部分查詢很慢,讓他去處理一下。榆木心里想著,這個(gè)應(yīng)該是個(gè)小問題,給數(shù)據(jù)表加索引就能搞定。到了客戶現(xiàn)場之后發(fā)現(xiàn),原來的表是有索引的,可查詢還是慢,不得已只能去找原因了。不得不說,explain SQL是個(gè)不錯(cuò)的命令,發(fā)現(xiàn)索引沒有生效,經(jīng)過仔細(xì)的比對(duì),發(fā)現(xiàn)該關(guān)聯(lián)查詢的關(guān)聯(lián)字段在兩個(gè)表中都有索引, 兩個(gè)表的字符集都是UTF8,但是排序規(guī)則一個(gè)是utf-bin(二進(jìn)制存儲(chǔ)數(shù)據(jù),大小寫區(qū)分),一個(gè)是utf8_general_ci(大小寫不敏感),所以把數(shù)據(jù)排序規(guī)則改成一致索引生效,查詢速度也就上來了。

PS: mysql中的UTF-8編碼的排序規(guī)則說明

utf8_bin將字符串中的每一個(gè)字符用二進(jìn)制數(shù)據(jù)存儲(chǔ),區(qū)分大小寫。

utf8_genera_ci不區(qū)分大小寫,ci為case insensitive的縮寫,即大小寫不敏感。

utf8_general_cs區(qū)分大小寫,cs為case sensitive的縮寫,即大小寫敏感。

【寫在***】

榆木整理了下這些年踩的坑,給自己也給正在和他掙扎在挨踢坑里的小伙伴們一些啟發(fā)與鼓勵(lì)。持續(xù)學(xué)習(xí)是保持競爭力的前提;夯實(shí)的基礎(chǔ)是進(jìn)階的墊腳石。抬頭走不獨(dú)行(exchange)、埋頭干(code),就算被稱作屌絲,也還是要有夢想,萬一逆襲了呢。

 如果你也愿意分享你的故事,請(qǐng)加51CTO開發(fā)者QQ交流群 114915964聯(lián)系群主小官,期待你精彩的故事!

51CTO開發(fā)者交流群⑥群114915964

【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】

責(zé)任編輯:何星 來源: 51CTO
相關(guān)推薦

2016-12-30 16:43:53

開發(fā)者故事

2017-03-21 11:19:57

開發(fā)者故事

2017-09-15 11:39:47

2017-01-18 16:37:43

開發(fā)者故事

2017-01-11 17:25:23

開發(fā)者故事

2017-03-01 15:57:48

開發(fā)者故事

2017-01-10 14:59:03

開發(fā)者故事

2017-01-18 11:07:20

開發(fā)者故事

2017-01-16 17:24:08

開發(fā)者故事

2017-01-19 13:40:56

開發(fā)者故事

2017-03-10 11:32:49

開發(fā)者故事

2017-01-05 15:30:59

開發(fā)者故事

2017-07-06 14:59:27

2017-04-25 15:39:30

開發(fā)者故事

2018-07-04 17:42:58

開發(fā)者故事

2017-01-13 16:36:29

開發(fā)者故事

2017-06-09 16:27:40

開發(fā)者故事

2017-03-24 16:43:09

開發(fā)者故事

2017-04-21 15:50:52

開發(fā)者故事

2017-10-23 13:15:51

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)