作者:小傅哥
部落格:https://bugstack.cn
沉澱、分享、成長,讓自己和他人都能有所收穫!?
一、前言
學過的程式碼記不住?方式不對才記不住,你這麼記!
- Git:上廁所不叫上廁所,叫拉分支!
- Socket:廁所就是伺服器,坑就是埠!
- 佇列:上廁所?叫入佇列,先進先出!
- 棧:去廚房?叫進棧,後進先出!
- 架構:三居的格局叫MVC,四居的格局叫DDD!
- 理論:系統結構設計定的好,有點bug沒問題,能改。這就是茅坑跟坐便的區別。
除了有點味道以外,這回是不記住了,我們程式設計寫程式碼的過程和我們日常生活的例子,往往都是這樣可以對應上,有了真實可以觸及的實物,再去了解程式設計就會更加容易,也很難忘記。但可能會寫著寫著程式碼,就傻笑起來!
除了這些正能量學習的例子,我們接下來再看看哪些有毒的程式碼!
二、程式碼有毒!
以下程式碼用好了升職加薪,用不好開除走人!
1. 方法命名
public List<UserInfo> queryBitchUserInfo(String req) {
return null;
}
- 指數:⭐⭐⭐
- 解毒:小哥應該是想寫批量查詢使用者的方法名,結果把
batch
(批量),寫成了bitch
(婊子) - 點評:介面是上午寫的,人是下午走的!
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();
}
}
- 指數:⭐⭐⭐
- 解毒:用數字休眠時常排序,誰醒來的時間早,誰就先輸出。
- 點評:思路清奇,要不是這次排序等了一天,老闆也不能踢他!
3. 有點燒腦
@Test
public void test_idx_hashMap() {
Map<String, String> map = new HashMap<>(64);
map.put("alderney", "未實現服務");
map.put("luminance", "未實現服務");
map.put("chorology", "未實現服務");
map.put("carline", "未實現服務");
map.put("fluorosis", "未實現服務");
map.put("angora", "未實現服務");
map.put("insititious", "未實現服務");
map.put("insincere", "已實現服務");
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
map.get("insincere");
}
System.out.println("耗時(initialCapacity):" + (System.currentTimeMillis() - startTime));
}
-
指數:⭐⭐⭐⭐⭐
-
解毒:這是一個定義
HashMap
存放業務實現key,通過key呼叫服務的功能。但這裡的key
,只有insincere
有用,其他的都是未實現服務。那你看到有啥問題了嗎?- 這點程式碼乍一看沒什麼問題,看明白了就是程式碼裡下砒霜!它的目的就一個,要讓所有的key成一個連結串列放到HashMap中,而且把有用的key放到連結串列的最後,增加get時的耗時!
- 首先,
new HashMap<>(64);
為啥預設初始化64個長度?因為預設長度是8,插入元素時,當連結串列長度為8時候會進行擴容和連結串列樹化判斷,此時就會把原有的key雜湊了,不能讓所有key構成一個時間複雜度較高的連結串列。 - 其次,所有的
key
都是刻意選出來的,因為他們在HashMap
計算下標時,下標值都為0,idx =(size - 1) & (key.hashCode() ^ (key.hashCode() >>> 16))
,這樣就能讓所有key
都雜湊到同一個位置進行碰撞。而且單詞insincere
的意思是;不誠懇的、不真誠的
! - 最後,前7個key其實都是廢
key
,不起任何作用,只有最後一個 key 有服務。那麼這樣就可以在HashMap中建出來很多這樣耗時的碰撞連結串列,當然要滿足0.75
的負載因子,不要讓HashMap擴容。 - 整體的效果如下圖,key並沒有均勻雜湊;
-
點評:能寫出這種程式碼就是薪資沒給夠,等著程式碼優化提加薪呢!
4. 迷之求和
@Test
public void test_add(){
int num = 0;
for (int i = 0; i < 100; i++) {
num = num++;
}
System.out.println(num);
}
- 指數:⭐⭐
- 解毒:最終
num
結果為 0,num++
根本沒起啥作用。因為後++,是先用結果,在++操作,不會給賦值。正確寫法是:num = ++ num; - 點評:這種錯誤就跟開車闖紅燈似的,輕則扣分罰款,重則傾家蕩產。
5. 花裡胡哨
private boolean checkAge(int age ) {
boolean result;
if (age >18)
{
result=true;
} else {
result=false;
}
return result;
}
- 指數:⭐
- 解毒:程式碼可以執行,但是可以優化為
return age > 18
。 - 點評:你們公司是按照程式碼行數打績效?不做格式化、不整潔、不看IDEA工具提示,程式碼是寫給人看的!啥有不是!
6. 數字判斷
public boolean isNumber(String str) {
try {
Integer.parseInt(str);
return true;
} catch (Exception e) {
return false;
}
}
- 指數:⭐⭐
- 解毒:判斷是不是數字,不拋異常就是,拋異常就不是。這可以使用
StringUtils
工具包判斷,也可以自己寫正則判斷。 - 點評:這程式碼真燒,用異常做業務。這不是把?蘑菇給狗狗吃嗎!?狗狗沒死你到是吃蘑菇呀,你吃狗粑粑。
7. 程式碼健壯
public void neverStop(){
//一直迴圈
while (true) {
try {
//業務處理流程
} catch (Exception e) {
//抓到異常,不處理、不打日誌、就是不要停,繼續跑
continue ;
}
}
}
- 指數:⭐⭐⭐
- 解毒:把可能拋異常的程式碼用tryCatch包起來,一直跑,遇到異常也要跑。這個時候遇到異常,要做一些流程處理,最起碼要打日誌和報警。
- 點評:業務開發很多時候都是為了解決異常流程,就像
擦屁屁的紙80%的面積是保護手的。怎麼滴,我看你這程式碼,是非要一直摳破呀!
8. 效能優化
// APP首頁查詢,優化前
public void queryInitInfo(){
Thread.sleep(3000);
}
// APP首頁查詢,優化後
public void queryInitInfo(){
Thread.sleep(500);
}
- 指數:⭐⭐⭐
- 解毒:沒啥解毒的,一公斤鶴頂紅兌了一口口水!
- 點評:點評不了啦,抓到就開了吧!
9. 無用日誌
// 規則引擎校驗
public boolean ruleEngine(MatterReq req) {
try {
// 業務流程
} catch (Exception e) {
logger.error(e); // 只打異常,不打入參資訊
}
}
- 指數:⭐
- 解毒:日誌裡只打了異常,沒有入參資訊,當你的方法有大量的呼叫時,很難快速定位問題。
- 點評:下次記得把
產品經理
也打日誌裡去,要死一起死!
10. 耗時遍歷
@Test
public void test_LinkedList() {
// 初始化100萬資料
List<Integer> list = new LinkedList<Integer>(1000000);
// 遍歷求和
int sum = 0;
for (int i = 0; i < list.size(); i++) {
sum += list.get(i);
}
}
- 指數:⭐⭐⭐⭐
- 解毒:乍一看可能覺得沒什麼問題,但是這個遍歷求和會非常慢。主要因為連結串列的資料結構,每一次
list.get(i)
都是從連結串列的頭開始查詢,與ArrayList
不同,LinkedList
它時間複雜度是O(n)。那如果說你不知道對方傳過來的是LinkedList
還是ArrayList
呢,其實可以通過list instanceof RandomAccess
進行判斷。ArrayList
有隨機訪問的實現,LinkedList
是沒有。同時也可以使用增強的for迴圈或者Iterator
進行遍歷。 - 點評: 根基不牢,地動山搖!一知半解,坑了老鐵!
三、總結
好的程式碼千篇一律,差的程式升值加薪!,這些有毒的程式碼,淋漓盡致的展示了程式設計師的才華出眾,同時也嚴重懷疑就是錢給少了!
敲黑板:想在這編碼這條路上走的更遠,還是需要腳踏實地的把根基打牢。所以非常推進你閱讀以下系列專欄文章,夯實基礎、擴充能力、提升眼界;
- Java核心突破瓶頸篇:https://bugstack.cn/itstack/interview.html
- 重學Java設計模式篇:https://bugstack.cn/itstack/itstack-demo-design.html
- Java架構設計學習篇:https://bugstack.cn/itstack-demo-ddd/itstack-demo-ddd.html
好!,本篇文章就到這裡,有意思的程式碼還有很多,歡迎在評論區留下你的鬼畜程式碼!