新來(lái)的小哥這樣寫(xiě)代碼!同事直呼“中毒了”~
閱讀本文大概需要 5.5 分鐘。
沉淀、分享、成長(zhǎng),讓自己和他人都能有所收獲!?
目錄
一、前言
二、代碼有毒!
1. 方法命名
2. 最佳排序
3. 有點(diǎn)燒腦
4. 迷之求和
5. 花里胡哨
6. 數(shù)字判斷
7. 代碼健壯
8. 性能優(yōu)化
9. ?無(wú)用日志
10. 耗時(shí)遍歷
三、總結(jié)
一、前言
學(xué)過(guò)的代碼記不住?方式不對(duì)才記不住,你這么記!Git:上廁所不叫上廁所,叫拉分支! Socket:廁所就是服務(wù)器,坑就是端口! 隊(duì)列:上廁所
叫入隊(duì)列,先進(jìn)先出!棧:去廚房?叫進(jìn)棧,后進(jìn)先出! 架構(gòu):三居的格局叫MVC,四居的格局叫DDD! 理論:系統(tǒng)結(jié)構(gòu)設(shè)計(jì)定的好,有點(diǎn)bug沒(méi)問(wèn)題,能改。這就是茅坑跟坐便的區(qū)別。
二、代碼有毒!
以下代碼用好了升職加薪,用不好開(kāi)除走人!1. 方法命名
public?List ?queryBitchUserInfo(String?req)? {
????return?null;
}
指數(shù):??? 解毒:小哥應(yīng)該是想寫(xiě)批量查詢(xún)用戶(hù)的方法名,結(jié)果把 batch(批量),寫(xiě)成了bitch(婊子)點(diǎn)評(píng):接口是上午寫(xiě)的,人是下午走的!
2. 最佳排序
public?static?void?main(String[]?args)?{
????int[]?numbers?=?new?int[]{2,?30000000,?1,?6,?40000000,?5};
????for?(final?int?number?:?numbers)?{
????????new?Thread(new?Runnable()?{
????????????@Override
????????????public?void?run()?{
????????????????try?{
????????????????????Thread.sleep(number);
????????????????????System.out.println(number);
????????????????}?catch?(InterruptedException?ignore)?{
????????????????}
????????????}
????????}).start();
????}
}
指數(shù):??? 解毒:用數(shù)字休眠時(shí)常排序,誰(shuí)醒來(lái)的時(shí)間早,誰(shuí)就先輸出。 點(diǎn)評(píng):思路清奇,要不是這次排序等了一天,老板也不能踢他!
3. 有點(diǎn)燒腦
@Test
public?void?test_idx_hashMap()?{
????Map?map?=?new?HashMap<>(64);
????map.put("alderney",?"未實(shí)現(xiàn)服務(wù)");
????map.put("luminance",?"未實(shí)現(xiàn)服務(wù)");
????map.put("chorology",?"未實(shí)現(xiàn)服務(wù)");
????map.put("carline",?"未實(shí)現(xiàn)服務(wù)");
????map.put("fluorosis",?"未實(shí)現(xiàn)服務(wù)");
????map.put("angora",?"未實(shí)現(xiàn)服務(wù)");
????map.put("insititious",?"未實(shí)現(xiàn)服務(wù)");
????map.put("insincere",?"已實(shí)現(xiàn)服務(wù)");
????
????long?startTime?=?System.currentTimeMillis();
????for?(int?i?=?0;?i?100000000;?i++)?{
????????map.get("insincere");
????}
????System.out.println("耗時(shí)(initialCapacity):"?+?(System.currentTimeMillis()?-?startTime));
}
指數(shù):?????
解毒:這是一個(gè)定義
HashMap存放業(yè)務(wù)實(shí)現(xiàn)key,通過(guò)key調(diào)用服務(wù)的功能。但這里的key,只有insincere有用,其他的都是未實(shí)現(xiàn)服務(wù)。那你看到有啥問(wèn)題了嗎?這點(diǎn)代碼乍一看沒(méi)什么問(wèn)題,看明白了就是代碼里下砒霜!它的目的就一個(gè),要讓所有的key成一個(gè)鏈表放到HashMap中,而且把有用的key放到鏈表的最后,增加get時(shí)的耗時(shí)! 首先, new HashMap<>(64);為啥默認(rèn)初始化64個(gè)長(zhǎng)度?因?yàn)槟J(rèn)長(zhǎng)度是8,插入元素時(shí),當(dāng)鏈表長(zhǎng)度為8時(shí)候會(huì)進(jìn)行擴(kuò)容和鏈表樹(shù)化判斷,此時(shí)就會(huì)把原有的key散列了,不能讓所有key構(gòu)成一個(gè)時(shí)間復(fù)雜度較高的鏈表。其次,所有的? key?都是刻意選出來(lái)的,因?yàn)樗麄冊(cè)?HashMap?計(jì)算下標(biāo)時(shí),下標(biāo)值都為0,idx =?(size - 1) & (key.hashCode() ^ (key.hashCode() >>> 16)),這樣就能讓所有key?都散列到同一個(gè)位置進(jìn)行碰撞。而且單詞?insincere的意思是;不誠(chéng)懇的、不真誠(chéng)的!最后,前7個(gè)key其實(shí)都是廢? key,不起任何作用,只有最后一個(gè) key 有服務(wù)。那么這樣就可以在HashMap中建出來(lái)很多這樣耗時(shí)的碰撞鏈表,當(dāng)然要滿(mǎn)足0.75的負(fù)載因子,不要讓HashMap擴(kuò)容。整體的效果如下圖,key并沒(méi)有均勻散列; 
點(diǎn)評(píng):能寫(xiě)出這種代碼就是薪資沒(méi)給夠,等著代碼優(yōu)化提加薪呢!
4. 迷之求和
@Test
public?void?test_add(){
????int?num?=?0;
????for?(int?i?=?0;?i?100;?i++)?{
????????num?=?num++;
????}
????System.out.println(num);
}
指數(shù):?? 解毒:最終? num?結(jié)果為 0,num++?根本沒(méi)起啥作用。因?yàn)楹?+,是先用結(jié)果,在++操作,不會(huì)給賦值。正確寫(xiě)法是:num = ++ num;點(diǎn)評(píng):這種錯(cuò)誤就跟開(kāi)車(chē)闖紅燈似的,輕則扣分罰款,重則傾家蕩產(chǎn)。
5. 花里胡哨
private?boolean?checkAge(int?age?)?{
????boolean?result;
????if?(age?>18)?
????{
????????result=true;
????}?else?{
????????result=false;
????}
????
????
????return?result;
}
指數(shù):? 解毒:代碼可以運(yùn)行,但是可以?xún)?yōu)化為 return age > 18。點(diǎn)評(píng):你們公司是按照代碼行數(shù)打績(jī)效?不做格式化、不整潔、不看IDEA工具提示,代碼是寫(xiě)給人看的!啥有不是!
6. 數(shù)字判斷
public?boolean?isNumber(String?str)?{
????try?{
????????Integer.parseInt(str);
????????return?true;
????}?catch?(Exception?e)?{
????????return?false;
????}
}
指數(shù):?? 解毒:判斷是不是數(shù)字,不拋異常就是,拋異常就不是。這可以使用? StringUtils?工具包判斷,也可以自己寫(xiě)正則判斷。點(diǎn)評(píng):這代碼真燒,用異常做業(yè)務(wù)。這不是把?蘑菇給狗狗吃嗎!?狗狗沒(méi)死你到是吃蘑菇呀,你吃狗粑粑。
7. 代碼健壯
public?void?neverStop(){
????//一直循環(huán)
????while?(true)?{
????????try?{
????????????//業(yè)務(wù)處理流程
????????}?catch?(Exception?e)?{
????????????//抓到異常,不處理、不打日志、就是不要停,繼續(xù)跑
????????????continue?;
????????}
????}
}
指數(shù):??? 解毒:把可能拋異常的代碼用tryCatch包起來(lái),一直跑,遇到異常也要跑。這個(gè)時(shí)候遇到異常,要做一些流程處理,最起碼要打日志和報(bào)警。 點(diǎn)評(píng):業(yè)務(wù)開(kāi)發(fā)很多時(shí)候都是為了解決異常流程,就像 擦屁屁的紙80%的面積是保護(hù)手的。怎么滴,我看你這代碼,是非要一直摳破呀!
8. 性能優(yōu)化
//?APP首頁(yè)查詢(xún),優(yōu)化前
public?void?queryInitInfo(){
????Thread.sleep(3000);
}
//?APP首頁(yè)查詢(xún),優(yōu)化后
public?void?queryInitInfo(){
????Thread.sleep(500);
}
指數(shù):??? 解毒:沒(méi)啥解毒的,一公斤鶴頂紅兌了一口口水! 點(diǎn)評(píng):點(diǎn)評(píng)不了啦,抓到就開(kāi)了吧!
9. ?無(wú)用日志
//?規(guī)則引擎校驗(yàn)
public?boolean?ruleEngine(MatterReq?req)?{
????try?{
????????//?業(yè)務(wù)流程
????}?catch?(Exception?e)?{
????????logger.error(e);??//?只打異常,不打入?yún)⑿畔?/span>
????}
}
指數(shù):? 解毒:日志里只打了異常,沒(méi)有入?yún)⑿畔ⅲ?dāng)你的方法有大量的調(diào)用時(shí),很難快速定位問(wèn)題。 點(diǎn)評(píng):下次記得把 產(chǎn)品經(jīng)理也打日志里去,要死一起死!
10. 耗時(shí)遍歷
@Test
public?void?test_LinkedList()?{
?//?初始化100萬(wàn)數(shù)據(jù)
????List?list?=?new?LinkedList (1000000);
????
????//?遍歷求和
????int?sum?=?0;
????for?(int?i?=?0;?i?????????sum?+=?list.get(i);
????}
????
}
指數(shù):???? 解毒:乍一看可能覺(jué)得沒(méi)什么問(wèn)題,但是這個(gè)遍歷求和會(huì)非常慢。主要因?yàn)殒湵淼臄?shù)據(jù)結(jié)構(gòu),每一次 list.get(i)都是從鏈表的頭開(kāi)始查找,與ArrayList不同,LinkedList它時(shí)間復(fù)雜度是O(n)。那如果說(shuō)你不知道對(duì)方傳過(guò)來(lái)的是LinkedList還是ArrayList呢,其實(shí)可以通過(guò)list instanceof RandomAccess進(jìn)行判斷。ArrayList?有隨機(jī)訪(fǎng)問(wèn)的實(shí)現(xiàn),LinkedList?是沒(méi)有。同時(shí)也可以使用增強(qiáng)的for循環(huán)或者Iterator進(jìn)行遍歷。點(diǎn)評(píng):根基不牢,地動(dòng)山搖!一知半解,坑了老鐵!
三、總結(jié)
好書(shū)推薦

推薦閱讀:
IDEA 上位?不!Eclipse Theia 1.0 發(fā)布!
微信掃描二維碼,關(guān)注我的公眾號(hào)
朕已閱?
評(píng)論
圖片
表情

