Java精選面試題(微信小程序):5000+道面試題和選擇題,包含Java基礎(chǔ)、并發(fā)、JVM、線程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架構(gòu)設(shè)計(jì)、大廠真題等,在線隨時(shí)刷題!
前言
我是[提前退休的java猿],一名7年java開發(fā)經(jīng)驗(yàn)的開發(fā)組長(zhǎng),分享工作中的各種問題!
我們公司都是只招 “高級(jí)java開發(fā)”,每個(gè)開發(fā)必須具備獨(dú)立主導(dǎo)項(xiàng)目研發(fā)的能力,需要需求評(píng)審、技術(shù)調(diào)研、技術(shù)方案選型,開發(fā)工時(shí)評(píng)估。
今天就來看看我們寫的代碼都會(huì)犯些什么錯(cuò),如果你是一名初中級(jí)開發(fā),那么這篇文章請(qǐng)你一定看完。最后還對(duì)我們公司中、高級(jí)開發(fā)的能力做了主觀的評(píng)價(jià)
“高級(jí)程序員”的代碼
一、分布式鎖運(yùn)用
簡(jiǎn)單描述一下業(yè)務(wù)場(chǎng)景,就是活動(dòng)報(bào)名。主要的邏輯就是判斷用戶是否報(bào)名,沒有報(bào)名就插入報(bào)名記錄,并且報(bào)名的剩余名額減一。
邏輯和秒殺的邏輯看起來還差不多呢,只是我們這個(gè)業(yè)務(wù)沒有什么并發(fā)量。看以下代碼吧,看看你能找出幾個(gè)問題。
原代碼
controller 層偽代碼如下:
![]()
點(diǎn)評(píng): 建議直接鎖用戶吧,Key改成活動(dòng) ID+userID ,這樣能提高并發(fā),提升用戶體驗(yàn) 不能立即獲取到鎖,直接返回 假設(shè)lock方法報(bào)錯(cuò),沒有獲取鎖,finally豈不是把其他請(qǐng)求的鎖給解開了
service 層代碼如下:
![]()
點(diǎn)評(píng): 事務(wù)的范圍可以縮小,HTTP請(qǐng)求不要放到事務(wù)內(nèi) 本身庫存扣減的時(shí)候,多加一個(gè)條件(加一個(gè)剩余名額大于1的判斷 )
優(yōu)化后的代碼
controller: 鎖用戶,防止用戶重復(fù)點(diǎn)擊;鎖優(yōu)化防止極端情況解鎖到其他線程的持有鎖;
![]()
service: 縮小事務(wù)范圍,用編程式事務(wù)或者把前置校驗(yàn)單獨(dú)提出來,寫到controller層。扣減優(yōu)化,防止鎖失效命令報(bào)超的情況。
![]()
二、定時(shí)發(fā)送短信、語音...
簡(jiǎn)單描述一下業(yè)務(wù)場(chǎng)景,用戶需要在后臺(tái)可以批量選擇用戶,同時(shí)可以多選發(fā)送的方式比如 短信+語音。
然后設(shè)計(jì)的思路是,RabbitMQ延遲隊(duì)列實(shí)現(xiàn)定時(shí)觸發(fā),策略模式來實(shí)現(xiàn)業(yè)務(wù)邏輯。
看一下代碼吧,看看你能發(fā)現(xiàn)這些問題么
原代碼
消費(fèi)者:
![]()
點(diǎn)評(píng): 沒有捕捉異常(沒有綁定死信),沒有做冪等;異常之后會(huì)出現(xiàn)重復(fù)消費(fèi)消息
處理業(yè)務(wù)邏輯:
![]()
點(diǎn)評(píng): 異常處理:for循環(huán)里面遍歷策略,可能中途的某個(gè)策略會(huì)報(bào)錯(cuò)。要么做好異常捕捉處理,要么丟盡線程池執(zhí)行 線程安全:這個(gè)把具體的策略實(shí)現(xiàn) 設(shè)置到smsStrategyContext的屬性上存在線程安全問題。 (比如我多個(gè)線程同時(shí)調(diào)用setSendSmsStrategy,執(zhí)行完成之后多個(gè)線程 在調(diào)用send的時(shí)候,執(zhí)行的策略就是最后生效的那一個(gè)了)
StrategyContext.java
![]()
線程安全問題如下圖:
![]()
上面這塊代碼確實(shí)問題也挺多的,結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景,按照嚴(yán)重級(jí)別排序的話,應(yīng)該是線程安全<----異常處理<------消息冪等
優(yōu)化后的代碼
消息消費(fèi):除了以下的修改,還綁定了死信隊(duì)列(出現(xiàn)了異常直接丟入到死信隊(duì)列)。
![]()
處理業(yè)務(wù)邏輯: 存在多個(gè)策略,各策略之間的執(zhí)行互不影響,且執(zhí)行策略的方法為線程安全.同時(shí)處理異常情況
![]()
StrategyContext.java: 調(diào)整成線程安全的類,加鎖或者使用ThreadLocal進(jìn)行策略接口的存儲(chǔ),下面就改成簡(jiǎn)單的方式把,用鎖的方式
![]()
三、一些細(xì)節(jié)和規(guī)范問題
多此一舉的分布式鎖
本身這個(gè)定時(shí)任務(wù)用的是Quartz定時(shí)任務(wù),配置中也是開啟了集群模式的,有些同事還是自己去實(shí)現(xiàn)了分布式鎖,多此一舉了哈
![]()
魔法變量、select*
數(shù)據(jù)量大的情況,mybatis plus 查詢不指定查詢字段,默認(rèn)查詢所有 還是比較吃性能。
![]()
“高級(jí)程序員”和 “中級(jí)程序員”的區(qū)別
基于我司的情況說一下個(gè)人主觀的感受吧,技術(shù)上表現(xiàn)最大的差別就是 設(shè)計(jì)思路 和 代碼規(guī)范(可讀性)上吧。綜合能力上就是 工時(shí)的評(píng)估、風(fēng)險(xiǎn)的預(yù)判。
中級(jí)程序員:
經(jīng)常設(shè)計(jì)的表有點(diǎn)死板了,不能很多的結(jié)合業(yè)務(wù)場(chǎng)景去設(shè)計(jì)表,經(jīng)常會(huì)出現(xiàn)表設(shè)計(jì)冗余,思路有點(diǎn)繞。以及代碼的可讀性,可維護(hù)性確實(shí)還是有明顯差別
明明一個(gè)表可以實(shí)現(xiàn)的,非得拆成多個(gè),同時(shí)還喜歡在SQL放很多case when 等邏輯;
頁面配置列表居然設(shè)計(jì)出來沒有ID,編輯一行數(shù)據(jù) 需要把整個(gè)列表全部提交全部覆蓋;
一個(gè)方法里面需要調(diào)用第三方的多個(gè)HTTP請(qǐng)求,異常也沒處理,中間步驟第三方可能需要等待一段時(shí)間才會(huì)查詢到結(jié)果,直接就對(duì)線程sleep一分鐘。 (請(qǐng)求多一點(diǎn)服務(wù)就炸,還會(huì)引起臟數(shù)據(jù))
高級(jí)程序員:
說一下我們公司的“高級(jí)程序員”吧
他們參與整個(gè)項(xiàng)目的周期上,從需求評(píng)估——>工時(shí)評(píng)估——>設(shè)計(jì)、編碼 這個(gè)過程沒有啥大問題,都能獨(dú)立的負(fù)責(zé)項(xiàng)目。
從技術(shù)上來說的話,基本的規(guī)范,代碼的擴(kuò)展性、可讀性、表設(shè)計(jì)都沒啥問題。但是在一些常用技術(shù)的原理理解上還是比較缺乏的。
比如上面說的分布式鎖的運(yùn)用,到底是鎖庫存還是鎖用戶。不會(huì)利用數(shù)據(jù)鎖,去實(shí)現(xiàn)超賣問題
解決問題的能很多還是停留在 search 階段,有明顯的報(bào)錯(cuò)的,但是網(wǎng)上沒有解決方案的,就不知道通過debug源碼的方式去解決
比如 一個(gè)left join 查詢緩慢,但是數(shù)據(jù)都不多,不知道去分析執(zhí)行計(jì)劃,不了解left join 的底層算法
當(dāng)然,技術(shù)的知識(shí)點(diǎn)很多,有些不知道 不了解的很正常。但是常用技術(shù)原理上,以及解決疑難雜癥問題的能力還有待提高。我們公司優(yōu)秀的高級(jí)開發(fā)也有,編碼速度非常快、bug還很少、代碼也非常的規(guī)范(還是名校)
分享了最近公司同事,出現(xiàn)的一些典型的代碼問題。同時(shí)在文章末尾也對(duì)身邊的高級(jí)開發(fā) 和 中級(jí)開發(fā)的能力做了一個(gè)主觀的評(píng)價(jià)。希望這篇文章能幫到你,感謝點(diǎn)贊評(píng)論的朋友!
作者:提前退休的java猿
https://juejin.cn/post/7537997532612984873
公眾號(hào)“Java精選”所發(fā)表內(nèi)容注明來源的,版權(quán)歸原出處所有(無法查證版權(quán)的或者未注明出處的均來自網(wǎng)絡(luò),系轉(zhuǎn)載,轉(zhuǎn)載的目的在于傳遞更多信息,版權(quán)屬于原作者。如有侵權(quán),請(qǐng)聯(lián)系,筆者會(huì)第一時(shí)間刪除處理!
最近有很多人問,有沒有讀者交流群!加入方式很簡(jiǎn)單,公眾號(hào)Java精選,回復(fù)“加群”,即可入群!
文章有幫助的話,點(diǎn)在看,轉(zhuǎn)發(fā)吧!
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.