柚子快報(bào)激活碼778899分享:java 【天機(jī)學(xué)堂】面試總結(jié)
寫在前面,首先要將天機(jī)學(xué)堂包裝一下,智慧教育平臺,暫時(shí)就想到這個(gè)。天機(jī)學(xué)堂文檔
1.包裝簡歷
2.簡單介紹一下你的項(xiàng)目
智慧教育平臺是一個(gè)基于微服務(wù)架構(gòu)的生產(chǎn)級在線教育項(xiàng)目,我們的核心用戶是面向15-22歲的C端的學(xué)生和非學(xué)歷職業(yè)技能培訓(xùn)平臺。智慧教育平臺是一個(gè)B2C類型(企業(yè)對消費(fèi)者的電子商務(wù)模式,一般以網(wǎng)絡(luò)零售業(yè)為主,主要借助于Internet開展在線銷售活動)的教育網(wǎng)站,因此分為管理端和也用戶端(PC網(wǎng)站)。用戶端包括:學(xué)習(xí)中心(例如學(xué)習(xí)記錄,學(xué)習(xí)計(jì)劃等),個(gè)人中心(例如信息管理和登錄等),交易中心(購物車,支付和退款等),管理端包括:課程管理,用戶管理,交易管理,營銷活動,學(xué)習(xí)管理。我主要負(fù)責(zé)的是點(diǎn)贊功能,用戶學(xué)習(xí)模塊中的學(xué)習(xí)進(jìn)度管理,用戶積分系統(tǒng)中的排行榜管理,優(yōu)惠券管理。該項(xiàng)目技術(shù)包括:SSM+SpringBoot+Redis+MySQL+MyBatisPlus+RabbitMQ+xxl-job等。
3.你在開發(fā)中參與了哪些功能開發(fā)讓你覺得比較有挑戰(zhàn)性?
我參與了整個(gè)學(xué)習(xí)中心的功能開發(fā),其中有很多的學(xué)習(xí)輔助功能都很有特色。比如視頻播放的進(jìn)度記錄。我們網(wǎng)站的課程是以錄播視頻為主,位了提供用戶的學(xué)習(xí)體驗(yàn),需要實(shí)現(xiàn)視頻的續(xù)播功能。這個(gè)功能實(shí)現(xiàn)邏輯本身不復(fù)雜,但是我們產(chǎn)品提出的要求比較高:首先續(xù)播時(shí)間誤差要控制在30秒以內(nèi)。然后要做到用戶突然斷開或者切換設(shè)備,都可以繼續(xù)上一次播放。要達(dá)到這個(gè)目的,我們必須把播放進(jìn)度保存在服務(wù)端。其次要做到續(xù)播誤差不超過30秒,那播放進(jìn)度的記錄頻率就需要比較高。我們會在前端每隔15秒發(fā)起一次心跳請求,提交最新的播放進(jìn)度,記錄到服務(wù)端。這樣用戶下一次續(xù)播時(shí)直接讀取服務(wù)端的播放進(jìn)度,就可以將時(shí)間誤差控制在15秒左右。現(xiàn)在面試官可能會追問,如果把播放數(shù)據(jù)存入到數(shù)據(jù)庫,當(dāng)用戶量比較大時(shí),前端每隔15秒就要提交一次請求,如果直接寫入數(shù)據(jù)庫,會對數(shù)據(jù)庫造成的壓力很大。請問你們是怎么解決的?我們當(dāng)時(shí)也考慮到了這樣的情況,我們思考了整個(gè)流程發(fā)現(xiàn)有問題沒有解決。
每個(gè)用戶提交的播放記錄數(shù)據(jù),只有在視頻關(guān)閉之前的那個(gè)提交才有效,其他的視頻播放效率是無效的。
解決辦法:我們當(dāng)時(shí)定義了一個(gè)延時(shí)任務(wù)類,將播放記錄加入到延時(shí)隊(duì)列里,每個(gè)任務(wù)倒計(jì)時(shí)20秒,20秒過后就會彈出,我們當(dāng)時(shí)是這樣想的一個(gè)邏輯,當(dāng)用戶在播放視頻時(shí),前端每隔15秒會提交一次請求,我們將前端提交的請求存到緩存中,然后再提交延時(shí)任務(wù),延時(shí)任務(wù)每次出來的播放記錄都會與緩存中的播放記錄做一個(gè)比較,如果不相同,則播放記錄在一直提交,如果相同則未提交,也就是視頻暫停了。(我們使用JDK自帶的DelayQueue,因?yàn)檫@種方案使用成本最低,而且不依賴任何第三方服務(wù),減少了網(wǎng)絡(luò)交互。但缺點(diǎn)也很明顯,就是需要占用JVM內(nèi)存,在數(shù)據(jù)量非常大的情況下可能會有問題。但考慮到任務(wù)存儲時(shí)間比較短(只有20秒),因此也可以接收。) 每個(gè)用戶是同步提交的視頻播放記錄,所以整個(gè)播放記錄的緩存業(yè)務(wù)的響應(yīng)時(shí)間就是每一次數(shù)據(jù)庫寫業(yè)務(wù)的響應(yīng)時(shí)間之和,并發(fā)能力肯定不會太好。
解決辦法:我們利用MQ將同步業(yè)務(wù)編程異步,我們將每個(gè)用戶的播放記錄先緩存到Redis中,然后定義一個(gè)定時(shí)任務(wù),將這些數(shù)據(jù)合并寫到數(shù)據(jù)庫中。
4. 你能講一講項(xiàng)目中課程管理是怎么設(shè)計(jì)的,有哪些接口?
作為一個(gè)在線教育項(xiàng)目,為了讓學(xué)員有一個(gè)更好的學(xué)習(xí)體驗(yàn),促進(jìn)學(xué)員,幫助學(xué)員學(xué)習(xí),課表管理非常重要。因?yàn)檫@個(gè)項(xiàng)目是我和同學(xué)一起做的,他把搜索課程和報(bào)名課程都寫好了。我拿到課程管理的任務(wù)后,先按照分析產(chǎn)品原型,設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),然后實(shí)現(xiàn)功能接口和測試+前后端聯(lián)調(diào)。
第一步是分析產(chǎn)品原型:根據(jù)需求,分析業(yè)務(wù)流程,設(shè)計(jì)業(yè)務(wù)接口,通過需求分析到有加入課表、分頁查詢課表、查詢學(xué)習(xí)進(jìn)度、查詢指定課程學(xué)習(xí)狀態(tài)、根據(jù)id查詢某課程學(xué)習(xí)狀態(tài)。第二步是設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),通過第一步的分析產(chǎn)品原型的過程中,其實(shí)我們就已經(jīng)知道數(shù)據(jù)庫需要哪些字段,根據(jù)需求和原型圖畫出ER圖,再設(shè)計(jì)數(shù)據(jù)表。第三步是實(shí)現(xiàn)接口:根據(jù)接口設(shè)計(jì)(yapi)來實(shí)現(xiàn)功能,一般來說我們不能直接在dev分支上直接開發(fā),會創(chuàng)建一個(gè)新的feature分支,用這個(gè)分支來實(shí)現(xiàn)課程管理功能,實(shí)現(xiàn)和測試完后,再合并到dev分支,刪除這個(gè)分支。第四步進(jìn)行測試:測試我們使用的是Postman和Swagger兩個(gè)工具來測的,我主要用的Postman。根據(jù)請求方式,請求路徑和請求參數(shù)格式,通過數(shù)據(jù)庫查詢數(shù)據(jù),進(jìn)行測試。第五步進(jìn)行前后端聯(lián)調(diào),一般是通過postman測試完沒問題,然后再通過前后端聯(lián)調(diào)測試。 如果給一個(gè)類似的場景題,也是根據(jù)這個(gè)過程來設(shè)計(jì)。
5.我看你簡歷個(gè)人貢獻(xiàn)寫了學(xué)習(xí)進(jìn)度管理,那請你講一下是怎么設(shè)計(jì)的?
學(xué)習(xí)進(jìn)度統(tǒng)計(jì)的問題在在線教育、視頻播放領(lǐng)域是一個(gè)非常常見的問題。學(xué)習(xí)進(jìn)度管理關(guān)聯(lián)到兩個(gè)業(yè)務(wù),學(xué)習(xí)計(jì)劃和學(xué)習(xí)進(jìn)度統(tǒng)計(jì)。
學(xué)習(xí)計(jì)劃:當(dāng)我們買了課程后,就會有一個(gè)創(chuàng)建學(xué)習(xí)計(jì)劃的按鈕,例如選擇某個(gè)課程后,創(chuàng)建每周學(xué)習(xí)章節(jié)數(shù),然后有一個(gè)預(yù)計(jì)學(xué)習(xí)完成時(shí)間(這是仿照扇貝單詞軟件的背單詞計(jì)劃設(shè)計(jì)的)。頁面就有了本周進(jìn)度,本周計(jì)劃這些顯示。學(xué)習(xí)進(jìn)度統(tǒng)計(jì):那學(xué)習(xí)進(jìn)度統(tǒng)計(jì),就是方便我們下一次點(diǎn)進(jìn)來能夠直接瀏覽到我們上次觀看的時(shí)間點(diǎn)。我們設(shè)計(jì)了兩種小節(jié),一種是視頻,一種是考試,考試提交完了,那么就表示學(xué)完了,而視頻的話我們不需要要求用戶一定要播放進(jìn)度達(dá)到100%,而我們是這樣設(shè)計(jì)的,只要當(dāng)前是第一次學(xué)習(xí)且視頻播放進(jìn)度超過50%則顯示已學(xué)習(xí)狀態(tài)。(如果面試官,問怎么記錄視頻播放進(jìn)度超過50%,那么你就回答上面第三個(gè)問題)
6.回答系統(tǒng)你是怎么設(shè)計(jì)的?
回答系統(tǒng)的整個(gè)流程是這樣的:在某個(gè)課程的某個(gè)章節(jié)下學(xué)員提出的問題,老師和其他學(xué)員可以進(jìn)行回答(并且可以進(jìn)行多次回答),老師和其他學(xué)員可以對某個(gè)回答進(jìn)行評論,并且對評論進(jìn)行回復(fù)也是評論(可以進(jìn)行多次評論),老師在管理端管理問題、回答和評論的狀態(tài)。 追問:你能講一講管理端和用戶端分別要實(shí)現(xiàn)哪些接口嗎?
用戶端:對問題的帶條件過濾的分頁查詢,提問的增刪查改。對問題的回答和評論有,根據(jù)id查詢問題詳情(我們要點(diǎn)擊某個(gè)問題進(jìn)行查看,是一個(gè)因此的接口),分頁查詢問題下的所有回答,分頁查詢回答下的評論,點(diǎn)贊和取消點(diǎn)贊某個(gè)回答和評論,回答某個(gè)提問、評論他人回答。管理端:和用戶端相同的接口(有一些獨(dú)有的字段,問題是否被查看,問題是否被隱藏),另外還有管理端分頁查詢問題列表,隱藏或顯示指定問題。
7. 我看你的項(xiàng)目里點(diǎn)贊數(shù)據(jù)是用Redis存的,為什么會選擇用Redis呢,怎么做持久化的?
點(diǎn)贊它是一個(gè)高并發(fā)寫的過程,因?yàn)榭赡軙谕粫r(shí)間段內(nèi)大量的用戶在點(diǎn)贊和取消贊的過程,如果這些請求都打在MySQL上,給MySQL帶來了很大的壓力,可能會使其宕機(jī)。因此對于高并發(fā)寫的常見優(yōu)化有,優(yōu)化SQL和代碼、變同步寫為異步寫、合并寫請求。而使用MQ異步是用來解耦的,數(shù)據(jù)庫的寫次數(shù)并沒有減少,因此我們這里采用了合并寫。合并寫操作是有使用場景的(對中間的N次寫操作不明感的情況下),而剛好用戶只關(guān)注最終的點(diǎn)贊結(jié)果。 合并寫有哪些注意的點(diǎn)?
1.數(shù)據(jù)如何緩存 這里有兩個(gè)數(shù)據(jù)需要緩存:用戶是否點(diǎn)贊,某業(yè)務(wù)的點(diǎn)贊總次數(shù)(某個(gè)回答,筆記,課程等)
用戶是否點(diǎn)贊:我們可以選用Redis里面的set,將業(yè)務(wù)類型+業(yè)務(wù)id作為key,value緩存每一個(gè)用戶的id的set集合 可以使用以下命令來完成點(diǎn)贊功能: 判斷用戶是否點(diǎn)贊(判斷bizId集合中有無userId):sismember bizId userId 點(diǎn)贊,如果返回1則代表點(diǎn)贊成功,返回0則代表點(diǎn)贊失敗(value是否push成功):sadd bizId userId 取消贊:就是刪除一個(gè)元素:srem bizId userId 統(tǒng)計(jì)點(diǎn)贊數(shù)(求bizId這個(gè)集合元素的個(gè)數(shù)):scard bizId 然后這一部分?jǐn)?shù)據(jù)我們可以直接存到緩存,不用持久化到數(shù)據(jù)庫,因?yàn)槊總€(gè)業(yè)務(wù)只有一個(gè)數(shù)據(jù),數(shù)據(jù)量很小的,然后當(dāng)Redis宕機(jī)了也不用擔(dān)心,有AOF提供的數(shù)據(jù)可靠性。如果實(shí)在不夠,再結(jié)合MySQL做持久化。 我們在判斷用戶是否點(diǎn)贊使用的是Redis里面的sisremember命令,但是我們對多次調(diào)用這個(gè)命令,就需要向Redis發(fā)起多次Redis請求,就會給網(wǎng)絡(luò)帶寬帶來非常大的壓力,所以我們使用了Redis里面的管道(Pipelining)來提高查詢速度。某業(yè)務(wù)的點(diǎn)贊次數(shù)(必須持久化) 這里我們選用了SortedSet方法,利用key作為業(yè)務(wù)類型,member作為業(yè)務(wù)Id,score作為點(diǎn)贊數(shù)。 2.緩存何時(shí)寫入數(shù)據(jù)庫 我們使用定時(shí)任務(wù)來做持久化,每隔20秒遍歷每個(gè)業(yè)務(wù)做持久化,由于業(yè)務(wù)過多,我們每次處理30個(gè)業(yè)務(wù)。
這里會追問,為什么要用zset,而不用list和set呢?
首先list不具備去重的能力,因?yàn)閷I(yè)務(wù)id和點(diǎn)贊數(shù)一并存到list里面,如果業(yè)務(wù)在一分鐘內(nèi)被點(diǎn)過多次贊,那么就會存入多個(gè)相同的業(yè)務(wù)id,而我們只需要最后的一次。而用set的話,因?yàn)閟et里只放業(yè)務(wù)id,而在通過業(yè)務(wù)id去通過MQ來查詢,這樣做的話會經(jīng)過多次網(wǎng)絡(luò)通信從而給系統(tǒng)網(wǎng)絡(luò)增加負(fù)擔(dān)。zset可以同時(shí)保存業(yè)務(wù)id和最新點(diǎn)贊數(shù),就少了多次查詢的操作。但并不是zset就是完美的,只是綜合考慮下選擇了zset,因?yàn)閦set底層是使用的哈希結(jié)構(gòu)+跳表實(shí)現(xiàn)的,會占用額外的內(nèi)存,當(dāng)然我們在做定時(shí)任務(wù)時(shí),每次查詢都會把Zset刪除。
8.你的簽到功能使用的BitMap,為什么會使用這個(gè)結(jié)構(gòu),怎么存儲的。
我剛開始是想的使用數(shù)據(jù)庫表來存,但是一個(gè)用戶每一次簽到,用一張表來存就是一條記錄,如果一個(gè)用戶一年簽到了100次,而網(wǎng)站有100萬用戶,就會產(chǎn)生1億條記錄。隨著用戶的增多,時(shí)間的推移,這張表占用的空間將會越來越大。然后我想的是每個(gè)用戶記錄每天是否簽到,就是01數(shù)據(jù),那么有沒有只保存01數(shù)據(jù)的結(jié)構(gòu),而如果只保存01數(shù)據(jù)(數(shù)據(jù)量?。┯胷edis處理起來很快,redis里面有一種天然的保存01數(shù)據(jù)的結(jié)構(gòu)BitMap。 1.怎么簽到:使用setbit key offset value,將地offset 的bit位改為value數(shù)據(jù),例如第三天簽到,就改為setbit bm 2 1.(這里用的是setbit第1天在最左邊,當(dāng)天的數(shù)據(jù)在最后一位) 2.如何查詢簽到記錄:使用bitfield key get encoding offset, 從offset的bit位開始讀取,u2,就是讀取兩個(gè)bit位。例如我想要第一天到第三天的簽到記錄,就用bitfield bm get u3 0。 然后我們設(shè)計(jì)的有積分簽到獎勵(lì),每天簽到有1個(gè)積分,每連續(xù)簽到7天得10的積分。這些積分就用到后面的排行榜功能。如果說統(tǒng)計(jì)一個(gè)區(qū)間里有多少天的簽到數(shù),可以使用bitfield,但是如果統(tǒng)計(jì)當(dāng)前有多少連續(xù)的簽到數(shù),就不能使用bitfield命令,只能去模擬,使用當(dāng)前的二進(jìn)制去不斷的右移與1做與運(yùn)算,如果等于1表示當(dāng)前有簽到,直到為0就沒有簽到。
9.你是怎么設(shè)計(jì)積分功能的,有那些獎勵(lì)?
首先剛剛說到的簽到,每次簽到+1積分,而每連續(xù)簽到7天就會加10的積分獎勵(lì)。寫課程評價(jià)+10積分,寫問答 +5積分(每日上限20積分)。這里我們用的MQ,當(dāng)簽到功能寫完后,就會將積分和當(dāng)前用戶通過MQ發(fā)送給處理方,而業(yè)務(wù)類型就是mq的類型。學(xué)習(xí)系統(tǒng)監(jiān)聽到mq做處理,會先去判斷是否積分是否超上限(也就是在數(shù)據(jù)庫中查詢今天的數(shù)據(jù))。
10.你使用Redis來保存簽到數(shù)據(jù),如果Redis宕機(jī)了怎么辦?
其實(shí)我們可以給Redis添加數(shù)據(jù)持久化機(jī)制,比如使用AOF持久化機(jī)制(保存每一條插入語句命令,AOF命令是默認(rèn)關(guān)閉的,要在redis.conf配置文件里開啟)。這樣宕機(jī)后也丟失的數(shù)量不多,可以接受。當(dāng)然Redis持久化還有RDB(數(shù)據(jù)快照),把內(nèi)存中的所有數(shù)據(jù)記錄到磁盤中,當(dāng)Redis宕機(jī)重啟后,從磁盤中讀取快照文件,恢復(fù)數(shù)據(jù)。我們這里使用的是AOF,因?yàn)閿?shù)據(jù)完整性更高。 或者我們可以搭建Redis主從集群,再結(jié)合Redis哨兵。主節(jié)點(diǎn)會把數(shù)據(jù)持續(xù)的同步給從節(jié)點(diǎn),宕機(jī)后會有哨兵從從節(jié)點(diǎn)中選取主節(jié)點(diǎn),基本不用擔(dān)心數(shù)據(jù)丟失問題。 當(dāng)然,如果對于數(shù)據(jù)的安全性要求非常高??隙ㄟ€是要結(jié)合傳統(tǒng)數(shù)據(jù)庫來實(shí)現(xiàn),但是為了解決簽到數(shù)據(jù)量較大的問題,我們可能就需要對數(shù)據(jù)做分表處理了?;蛘呒皶r(shí)將歷史數(shù)據(jù)存檔。 總的來說,簽到數(shù)據(jù)使用Redis的BitMap無論是安全性還是數(shù)據(jù)內(nèi)存占用情況,都是可以接受的。但是具體是選擇Redis還是數(shù)據(jù)庫方案,最終還是要看公司的要求來選擇。
11. 答::你在項(xiàng)目中負(fù)責(zé)積分排行榜功能,說說看你的排行榜怎么設(shè)計(jì)實(shí)現(xiàn)的?
我們的排行榜功能分為兩部分:一個(gè)是當(dāng)前賽季排行榜,一個(gè)是歷史排行榜。 因?yàn)槲覀兊漠a(chǎn)品設(shè)計(jì)是每個(gè)月為一個(gè)賽季,月初清零積分記錄,這樣學(xué)員就有持續(xù)的動力去學(xué)習(xí)。這就有了賽季的概念,因此也就有了當(dāng)前賽季榜單和歷史榜單的區(qū)分,其實(shí)現(xiàn)思路也不一樣。 首先說當(dāng)前賽季榜單,我們采用了Redis的SortedSet來實(shí)現(xiàn)。member是用戶id,score就是當(dāng)月積分總值。每當(dāng)用戶產(chǎn)生積分行為的時(shí)候,獲取積分時(shí),就會更新score值。這樣Redis就會自動形成榜單了。非常方便且高效。 然后再說歷史榜單,歷史榜單肯定是保存到數(shù)據(jù)庫了。不過由于數(shù)據(jù)過多,所以需要對數(shù)據(jù)做水平拆分,我們目前的思路是按照賽季來拆分,也就是每一個(gè)賽季的榜單單獨(dú)一張表。這樣做有幾個(gè)好處:
拆分?jǐn)?shù)據(jù)時(shí)比較自然,無需做額外處理查詢數(shù)據(jù)時(shí)往往都是按照賽季來查詢,這樣一次只需要查一張表,不存在跨表查詢問題 因此我們就不需要用到分庫分表的插件了,直接在業(yè)務(wù)層利用MybatisPlus就可以實(shí)現(xiàn)動態(tài)表名,動態(tài)插入了。簡單高效。 我們會利用一個(gè)定時(shí)任務(wù)在每月初生成上賽季的榜單表,然后再用一個(gè)定時(shí)任務(wù)讀取Redis中的上賽季榜單數(shù)據(jù),持久化到數(shù)據(jù)庫中。最后再有一個(gè)定時(shí)任務(wù)清理Redis中的歷史數(shù)據(jù)。 這里要說明一下,這里三個(gè)任務(wù)是有關(guān)聯(lián)的,之所以讓任務(wù)分開定義,是為了避免任務(wù)耦合。這樣在部分任務(wù)失敗時(shí),可以單獨(dú)重試,無需所有任務(wù)從頭重試。(這里我們設(shè)置的子任務(wù)id是,將創(chuàng)建榜單的子任務(wù)id設(shè)置為持久化Redis上賽季榜單,再將持久化Redis上賽季榜單的子任務(wù)id設(shè)置為清除上賽季榜單) 當(dāng)然,最終我們肯定要確保這三個(gè)任務(wù)的執(zhí)行順序,一定是依次執(zhí)行的。
12.你使用Redis的SortedSet來保存榜單數(shù)據(jù),如果用戶量非常多怎么辦?
首先Redis的SortedSet底層利用了跳表機(jī)制,性能還是非常不錯(cuò)的。即便有百萬級別的用戶量,利用SortedSet也沒什么問題,性能上也能得到保證。在我們的項(xiàng)目用戶量下,完全足夠。 當(dāng)系統(tǒng)用戶量規(guī)模達(dá)到數(shù)千萬,乃至數(shù)億時(shí),我們可以采用分治的思想,將用戶數(shù)據(jù)按照積分范圍劃分為多個(gè)桶。 然后為每個(gè)桶創(chuàng)建一個(gè)SortedSet類型的key,這樣就可以將數(shù)據(jù)分散,減少單個(gè)KEY的數(shù)據(jù)規(guī)模了。 而要計(jì)算排名時(shí),只需要按照范圍查詢出用戶積分所在的桶,再累加分值范圍比他高的桶的用戶數(shù)量即可。依然非常簡單、高效。
13.你們使用歷史榜單采用的定時(shí)任務(wù)框架是XXL-JOB,和SpringTask比起來有什么優(yōu)點(diǎn)?處理數(shù)百萬的榜單數(shù)據(jù)時(shí)任務(wù)是如何分片的?你們是如何確保多個(gè)任務(wù)依次執(zhí)行的呢?
SpringTask存在一些問題:
當(dāng)微服務(wù)多實(shí)例部署時(shí),定時(shí)任務(wù)會被執(zhí)行多次。而事實(shí)上我們只需要這個(gè)任務(wù)被執(zhí)行一次即可。我們除了要定時(shí)創(chuàng)建表,還要定時(shí)持久化Redis數(shù)據(jù)到數(shù)據(jù)庫,我們希望這多個(gè)定時(shí)任務(wù)能夠按照順序依次執(zhí)行,SpringTask無法控制任務(wù)順序
XXL-JOB自帶任務(wù)分片廣播機(jī)制,每一個(gè)任務(wù)執(zhí)行器都能通過API得到自己的分片編號、總分片數(shù)量。在做榜單數(shù)據(jù)批處理時(shí),我們是按照分頁查詢的方式:
每個(gè)執(zhí)行器的讀取的起始頁都是自己的分片編號+1,例如第一個(gè)執(zhí)行器,其起始頁就是1,第二個(gè)執(zhí)行器,其起始頁就是2,以此類推然后不是逐頁查詢,而是有一個(gè)頁的跨度,跨度值就是分片總數(shù)量。例如分了3片,那么跨度就是3 此時(shí),第一個(gè)分片處理的數(shù)據(jù)就是第1、4、7、10、13等幾頁數(shù)據(jù),第二個(gè)分片處理的就是第2、5、8、11、14等頁的數(shù)據(jù),第三個(gè)分片處理的就是第3、6、9、12、15等頁的數(shù)據(jù)。 這樣就能確保所有數(shù)據(jù)都會被處理,而且每一個(gè)執(zhí)行器都執(zhí)行的是不同的數(shù)據(jù)了。 最后,要確保多個(gè)任務(wù)的執(zhí)行順序,可以利用XXL-JOB中的子任務(wù)功能。比如有任務(wù)A、B、C,要按照字母順序依次執(zhí)行,我們就可以將C設(shè)置為B的子任務(wù),再將B設(shè)置為A的子任務(wù)。然后給A設(shè)置一個(gè)觸發(fā)器。 這樣,當(dāng)A觸發(fā)時(shí),就會依次執(zhí)行這三個(gè)任務(wù)了。
持續(xù)更新:正在復(fù)習(xí)過程中,盡量做到每日一更,面試遇到的項(xiàng)目問題也會更新在這里面。
柚子快報(bào)激活碼778899分享:java 【天機(jī)學(xué)堂】面試總結(jié)
文章來源
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。