成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

代碼Review,瑞出事來了!

開發
我實在是想不通,代碼review就是用來發現問題的。結果這review會一開下來,大家都在背后諷刺我。這到底是我的問題呢?還是這個團隊的問題呢?讓人搞不懂。

不久之前,部門進行了一次代碼評審。

代碼整體比較簡單,該吹B的地方都已經吹過了,無非是些if else的老問題而已。當翻到一段定時任務的一步執行代碼時,我的雙眼一亮,覺得該BB兩句了。

誰知這群家伙,評審的時候滿滿的認同感,但評審結束不久,就給我冠了個事B的稱號。

今天我就把當時的這些話兒整理整理,讓大家說道說道,我到底是不是個事B

一個任務處理例子

代碼的結構大體是這樣的。

通過定時,這段代碼每天晚上凌晨都要對數據庫的記錄進行一遍對賬。主要的邏輯,就是使用獨立的線程,漸進式的讀取數據庫中的相關記錄,然后把這些記錄,放在循環中逐條進行處理。

ExecutorService service = Executors.newFixedThreadPool(10);
...
service.submit(()->{
while(true){
if(CollectionUtils.isEmpty(items)){
break;
}
List<Data> items = queryPageData(start, end); // 分頁邏輯
for(Data item : items){
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
//noop
}
processItem(item);
}
}
});ExecutorService service = Executors.newFixedThreadPool(10);
...
service.submit(()->{
while(true){
if(CollectionUtils.isEmpty(items)){
break;
}
List<Data> items = queryPageData(start, end); // 分頁邏輯
for(Data item : items){
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
//noop
}
processItem(item);
}
}
});

等一下。在代碼馬上被翻過去的時候,我叫停了,這里的processItem沒有捕獲異常。

通常情況下,這不會有什么問題。但靜好的歲月,總是偶爾會被一些隨機的事故打斷。如果這是你任務的完整代碼,那它就有一種非常隱晦的故障處理方式。即使你的單元測試寫的再好,這段代碼我們依然可以通過遠程投毒的方式,通過問題記錄來讓它產生問題。

是的。以上代碼的根本原因,就是沒有捕捉processItem函數可能產生的異常。如果在記錄處理的時候,有任何一條拋出了異常,不管是checked異常還是unchecked異常,整個任務的執行都會終止!

不要覺得簡單哦,踩過這個坑的同學,請記得扣個666。或者翻一下你的任務執行代碼,看看是不是也有這個問題。

Java編譯器在很多情況下都會提示你把異常給捕捉了,但總有些異常會逃出去,比如空指針異常。如下圖,RuntimeException和Error都屬于unchecked異常。

RuntimeException可以不用try...catch進行處理,但是如果一旦出現異常,則會導致程序中斷執行,JVM將統一處理這些異常。

你捕捉不到它,它自然會讓你的任務完蛋。

如果你想要異步的執行一些任務,最好多花一點功夫到異常設計上面。在這上面翻車的同學比比皆是,這輛車并不介意再帶上你一個。

評審的小伙很謙虛,馬上就現場修改了代碼。

不要生吞異常

且看修改后的代碼。

ExecutorService service = Executors.newFixedThreadPool(10);
...
service.submit(()->{
while(true){
if(CollectionUtils.isEmpty(items)){
break;
}
List<Data> items = queryPageData(start, end); // 分頁邏輯
for(Data item : items){
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
//noop
}
try{
processItem(item);
}catch(Exception ex){
LOG.error(...,ex);
}
}
}
});
...
service.shutdownNow();

為了控制任務執行的頻率,sleep大法是個有效的方法。

代碼里考慮的很周到,按照我們上述的方式捕捉了異常。同時,還很貼心的把sleep相關的異常也給捕捉了。這里不貼心也沒辦法,因為不補齊這部分代碼的話,編譯無法通過,我們姑且認為是開發人員的水平夠屌。

由于sleep拋出的是InterruptedException,所以代碼什么也沒處理。這也是我們代碼里常見的操作。不信打開你的項目,忽略InterruptedException的代碼肯定多如牛毛。

此時,你去執行這段代碼,雖然線程池使用了暴力的shutdownNow函數,但你的代碼依然無法終止,它將一直run下去。因為你忽略了InterruptedException異常。

當然,我們可以在捕捉到InterruptedException的時候,終止循環。

try {
Thread.sleep(10L);
} catch (InterruptedException e) {
break;
}

雖然這樣能夠完成預期,但一般InterruptedException卻不是這么處理的。正確的處理方式是這樣的:

while (true) {
Thread currentThread = Thread.currentThread();
if(currentThread.isInterrupted()){
break;
}
try {
Thread.sleep(1L);
} catch (InterruptedException e) {
currentThread.interrupt();
}
}

除了捕捉它,我們還要再次把interrupt狀態給復位,否則它就隨著捕捉給清除了。InterruptedException在很多場景非常的重要。當有些方法一直阻塞著線程,比如耗時的計算,會讓整個線程卡在那里什么都干不了,InterruptedException可以中斷任務的執行,是非常有用的。

但是對我們現在代碼的邏輯來說,并沒有什么影響。被評審的小伙伴不滿意的說。

還有問題!

有沒有影響是一回事,是不是好的習慣是另一回事 。我盡量的裝了一下B,其實,你的異常處理代碼里還有另外隱藏的問題。

還有什么問題?大家都一改常日慵懶的表情,你倒是說說。

我們來看一下小伙伴現場改的問題。他直接使用catch捕獲了這里的異常,然后記錄了相應的日志。我要說的問題是,這里的Exception粒度是不對的,太粗魯。

try{
processItem(item);
}catch(Exception ex){
LOG.error(...,ex);
}

processItem函數拋出了IOException,同時也拋出了InterruptedException,但我們都一致對待為普通的Exception,這樣就無法體現上層函數拋出異常的意圖。

比如processItem函數拋出了一個TimeoutExcepiton,期望我們能夠基于它做一些重試;或者拋出了SystemBusyExcption,期望我們能夠多sleep一會,給服務器一點時間。這種粗粒度的異常一股腦的將它們捕捉,在新異常添加的時候根本無法發現這些代碼,會發生風險。

一時間會議室里寂靜無比。

我覺得你說的很對 ,一位比較資深的老鳥說, 你的意思是把所有的異常情況都分別捕捉,進行精細化處理。但最后你還是要使用Exception來捕捉RuntimeException,異常還是捕捉不到啊。

果然是不同凡響的發問。

優秀的、標準的代碼寫法,其中無法實施的一個重要因素,就是項目中的其他代碼根本不按規矩來。如果我們下層的代碼,進行了正確的空指針判斷、數組越界操作,或者使用類似guava的Preconditions這類API進行了前置的異常翻譯,上面的這種問題根本不用回答。

但上面這種代碼的情況,我們就需要手動的捕捉RuntimeException,進行單獨的處理。

你們這個項目,爛代碼太多了,所以不好改。我雖然有情商,但我更有脾氣。

大家不歡而散。

End

我實在是想不通,代碼review就是用來發現問題的。結果這review會一開下來,大家都在背后諷刺我。這到底是我的問題呢?還是這個團隊的問題呢?讓人搞不懂。

你們在糾結使用Integer還是int的時候,我也沒說什么呀,現在就談點異常處理的問題,就那么玻璃心受不了了。這B不能全都讓你們裝了啊。

什么?你要review一下我的代碼?看看我到底有沒有像我說的一樣寫代碼,有沒有以身作則?是在不好意思,我可是架構師哎,我已經很多年沒寫代碼了。

你的這個愿望讓你落空了!

責任編輯:趙寧寧 來源: 小姐姐味道
相關推薦

2021-03-03 07:28:58

ReviewAuthor代碼

2013-10-24 09:43:58

代碼代碼審查

2012-07-05 09:45:02

代碼審查

2009-08-05 09:59:40

Code Review代碼審查工具

2012-09-03 13:41:50

Code Review

2022-06-23 09:57:01

code-revie前端代碼

2020-09-22 08:06:45

代碼事故

2021-06-07 16:01:15

代碼開發工具

2021-05-13 11:35:54

K8STerraform代碼倉庫

2018-08-16 15:11:47

Code ReviewPPT代碼

2020-03-06 10:14:18

IT支出IT投資

2020-11-02 09:03:22

代碼開發工具

2015-11-17 16:11:07

Code Review

2022-10-27 10:33:48

敏捷開發開發

2020-02-10 20:16:04

程序員AI人工智能

2023-11-22 11:22:57

AI模型

2024-11-08 14:18:38

2011-05-16 14:12:30

QuickWidgetQML

2023-05-31 14:49:07

Firefox火狐瀏覽器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.99久久.com | 九九综合九九 | 中文字幕97 | 一级毛片网 | 国产成人久久精品一区二区三区 | 国产情侣在线看 | 色先锋影音 | 国内精品99 | 最新免费视频 | 在线色网址 | 国产免费一级片 | 欧美理论| 欧美精品91| 青青久草 | 亚洲精选久久 | 日韩精品一区二区三区在线播放 | 涩爱av一区二区三区 | 成人免费视频在线观看 | 精品视频久久久 | 亚洲 欧美 日韩 精品 | 欧美日韩最新 | 99在线播放 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 一区二区精品 | 日韩高清在线 | 黄色在线观看 | 99久久精品免费看国产四区 | 老司机狠狠爱 | 国产网站在线播放 | 亚洲国产一区在线 | 国产免费看 | 在线观看欧美日韩视频 | 在线观看黄免费 | 三区四区在线观看 | 91亚洲国产成人精品一区二三 | 亚洲精品乱码久久久久久按摩观 | 在线视频日韩 | 亚洲精品久久久蜜桃 | 精品国产一二三区 | 精品综合久久 | 在线国产视频 |