<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官發(fā)問:什么是高并發(fā)下的請(qǐng)求合并?

          共 7822字,需瀏覽 16分鐘

           ·

          2020-11-27 12:03

          從一道面試題說起

          ??????????????????????????前段時(shí)間一個(gè)在深圳的,兩年經(jīng)驗(yàn)的小伙伴出去面試了一圈,收割了幾個(gè)大廠 offer 的同時(shí),還總結(jié)了一下面試的過程中遇到的面試題,面試題有很多,文末的時(shí)候我會(huì)分享給大家。

          這次的文章主要分享他面試過程中遇到的一個(gè)場景題:

          他說對(duì)于這個(gè)場景題,面試的時(shí)候沒有什么思路。

          說真的,請(qǐng)求合并我知道,高并發(fā)無非就是快速的請(qǐng)求合并。

          但是在我有限的認(rèn)知里面,如果類似于秒殺的高并發(fā)扣庫存這個(gè)場景,用請(qǐng)求合并的方式來做,我個(gè)人感覺是有點(diǎn)怪怪的不夠傳統(tǒng)。

          在傳統(tǒng)的,或者說是業(yè)界常用的秒殺解決方案中,從前端到后臺(tái),你也找不到請(qǐng)求合并的字樣。

          我理解請(qǐng)求合并更加適用的場景是查詢類的,或者說是數(shù)值增加類的需求,對(duì)于庫存扣減這種,你稍不留神,就會(huì)出現(xiàn)超賣的情況。

          當(dāng)然也有可能是我理解錯(cuò)題意了,看到高并發(fā)扣庫存就想到秒殺場景了。

          但是不重要,我們也不能直接和面試官硬剛。

          我會(huì)重新給個(gè)我覺得合理的場景,告訴大家我理解的請(qǐng)求合并和高并發(fā)下的請(qǐng)求合并是什么玩意。

          請(qǐng)求合并

          現(xiàn)在我們拋開秒殺這個(gè)場景。

          換一個(gè)更加合適,大家可能更容易理解的場景來聊聊什么是請(qǐng)求合并。

          就是熱點(diǎn)賬戶。

          什么是熱點(diǎn)賬戶呢?

          在第三方支付系統(tǒng)或者銀行這類交易機(jī)構(gòu)中,每產(chǎn)生一筆轉(zhuǎn)入或者轉(zhuǎn)出的交易,就需要對(duì)交易涉及的賬戶進(jìn)行記賬操作。

          記賬一般來說涉及到兩個(gè)部分。

          • 交易系統(tǒng)記錄這一筆交易的信息。
          • 賬戶系統(tǒng)需要增加或減少對(duì)應(yīng)的賬戶余額。

          如果對(duì)于某個(gè)賬戶操作非常的頻繁,那么當(dāng)我們對(duì)賬戶余額進(jìn)行操作的時(shí)候,就會(huì)涉及到并發(fā)處理的問題。

          并發(fā)了怎么辦?

          是的,我們可以對(duì)賬戶進(jìn)行加鎖處理。這樣一來,這個(gè)賬戶就涉及到頻繁的加鎖解鎖操作。

          這樣我們可以保證數(shù)據(jù)不出問題,但是隨之帶來的問題是隨著并發(fā)的提高,賬戶系統(tǒng)性能下降。

          這個(gè)賬戶,就是熱點(diǎn)賬戶,就是性能瓶頸點(diǎn)。

          熱點(diǎn)賬戶是業(yè)界的一個(gè)非常常見的問題。

          我所了解到的常規(guī)解決方案大概可以分為三種:

          • 異步緩沖記賬。
          • 設(shè)立影子賬戶。
          • 多筆合一記賬。

          本小節(jié)主要是介紹“多筆合一記賬”解決方案,從而引出請(qǐng)求合并的概率。

          對(duì)于另外兩個(gè)解決方案,就先簡單的說一下。

          首先異步緩沖記賬。

          我先不解釋,你就看著這個(gè)名字,想著這個(gè)場景,你覺得你會(huì)想到什么?

          異步,是不是想到了 MQ?

          那么請(qǐng)問你系統(tǒng)里面為什么要引入 MQ 呢?

          來,面試八股文背起來:異步處理、系統(tǒng)解耦、削峰填谷。

          你說我們當(dāng)前的這個(gè)場景下屬于哪一種情況?

          肯定是為了做削峰填谷呀。

          假設(shè)賬務(wù)系統(tǒng)的 TPS 是 200 筆每秒,當(dāng)請(qǐng)求低于 200 筆每秒的時(shí)候,賬務(wù)服務(wù)基本上能夠及時(shí)處理馬上返回。

          從用戶的角度來說就是:啪的一下,很快啊。我就收到了記賬成功的通知了,也看到賬戶余額發(fā)生了變化。

          但是在業(yè)務(wù)高峰期的時(shí)候,流量直接翻倍,每秒過來了 400 筆請(qǐng)求,這個(gè)時(shí)候?qū)τ谫~務(wù)系統(tǒng)來說就是流量洪峰,需要進(jìn)行削峰了,隊(duì)列里面開始堆積著請(qǐng)求,開始排隊(duì)處理了。

          在流量低谷的時(shí)候,就可以把這部分?jǐn)?shù)據(jù)消費(fèi)完成。

          相當(dāng)于數(shù)據(jù)扔到隊(duì)列里面之后,就可以告訴用戶記賬成功了,錢馬上就到。

          但是這個(gè)方案帶來的問題也是很明顯的,如果流量真的爆了,一天都沒有谷讓你填,隊(duì)列里面堆積著大量的請(qǐng)求還沒來得及處理,你怎么辦?

          這對(duì)于用戶而言就是:你明明告訴我記賬成功了,為什么我的賬戶余額遲遲沒有變化呢?是不是想陰我錢,我反手就是一波投訴。

          另外一個(gè)風(fēng)險(xiǎn)點(diǎn)就是對(duì)于支出類的請(qǐng)求,如果被削峰,很明顯,我們提前就告訴了用戶操作成功,但是真正動(dòng)賬戶余額的時(shí)候已經(jīng)延遲了,所以可能會(huì)出現(xiàn)賬戶透支的情況。

          另外一個(gè)設(shè)立影子賬戶的方案,其實(shí)和我們本次的請(qǐng)求合并的主題是另外一個(gè)不同的方向。

          它的思想是拆分。

          熱點(diǎn)賬戶說到底還是一個(gè)單點(diǎn)問題,那么對(duì)于單點(diǎn)問題,我們用微服務(wù)的思想去解決的話是什么方案?

          就是拆分。

          假設(shè)這個(gè)熱點(diǎn)賬戶上有 100w,我設(shè)立 10 個(gè)影子賬戶,每個(gè)賬戶 10w ,那么是不是我們的流量就分散了?從一個(gè)賬戶變成了 10 個(gè)賬戶。

          壓力也就進(jìn)行了分?jǐn)偂?/p>

          這個(gè)方案就有點(diǎn)類似于秒殺場景中的庫存了,庫存我們也可以拆多份。

          但是帶來的問題也很明顯。

          一是獲取賬戶余額的時(shí)候需要進(jìn)行匯總操作。

          二是假設(shè)用戶要扣 11w 呢?我們總余額是夠的,但是每個(gè)影子賬戶上的錢是不夠的。

          三是你的影子賬戶選擇的算法是很重要的,是用隨機(jī)?輪訓(xùn)?加權(quán)?這些對(duì)于賬務(wù)成功率都是有比較大的影響的。

          另外這個(gè)思想,我在之前的文章中也提到過,有興趣的可以看看其在 JDK 源碼中的應(yīng)用:我從LongAdder中窺探到了高并發(fā)的秘籍,上面只寫了兩個(gè)字...

          好了,回到本次的主題:多筆合一筆記賬。

          有個(gè)網(wǎng)紅店,生意非常的好,每天很多人在店里面消費(fèi)。

          當(dāng)用戶掃碼支付后,請(qǐng)求會(huì)發(fā)送到這個(gè)店對(duì)接的第三方支付公司。

          當(dāng)支付公司收到請(qǐng)求,并完成記賬操作后才會(huì)告知商戶用戶支付成功??梢越o用戶商品了。

          隨著店里生意越來越好,帶來的問題是第三方支付公司的系統(tǒng)壓力增加,扛不住這么大的并發(fā)了。導(dǎo)致用戶支付成功率的下降或者用戶支付成功后很長時(shí)間才通知到商戶。

          那么針對(duì)這個(gè)商戶的賬戶,我們就可以做多筆合一筆處理。

          當(dāng)記錄進(jìn)入緩沖流水記錄表之后,我們就可以通知商戶用戶支付成功了,至于錢,你放心,我有定時(shí)任務(wù),一會(huì)就到賬:

          所以當(dāng)用戶下單之后,我們只是先記錄數(shù)據(jù),并不去實(shí)際動(dòng)賬戶。等著定時(shí)任務(wù)去觸發(fā)記賬,進(jìn)行多筆合并一筆的操作。

          比如下面的這個(gè)示意圖:

          商戶實(shí)際有 5 個(gè)用戶支付記錄,但是這 5 筆記錄對(duì)應(yīng)著一條賬戶流水。我們拿著賬戶流水,也是可以追溯到這 5 筆交易記錄的。

          這樣的好處是吞吐量上來了,通知及時(shí),用戶體驗(yàn)也好了。但是帶來的弊端是余額并不是一個(gè)準(zhǔn)確的值。

          假設(shè)我們的定時(shí)任務(wù)是一小時(shí)匯總一次,那么商戶在后端看到的交易金額可能是一小時(shí)之前的數(shù)據(jù)。

          而且這種方案對(duì)于賬戶收錢的場景非常的適合,但是減錢的場景,也是有可能會(huì)出現(xiàn)金額為負(fù)的情況。

          不知道你有沒有看出多筆合一筆處理方案的秘密。

          如果我們把緩沖流水記錄表看作是一個(gè)隊(duì)列。那么這個(gè)方案抽象出來就是隊(duì)列加上定時(shí)任務(wù)。

          所以,請(qǐng)求合并的關(guān)鍵點(diǎn)也是隊(duì)列加上定時(shí)任務(wù)。

          文章看到現(xiàn)在,請(qǐng)求合并我們應(yīng)該是大概的了解到了,也確實(shí)是有真實(shí)的應(yīng)用場景。

          除了我上面的例子外,比如還有 redis里面的 mget,數(shù)據(jù)庫里面的批量插入,這玩意不就是一個(gè)請(qǐng)求合并的真實(shí)場景嗎?

          比如 redis 把多個(gè) get 合并起來,然后調(diào)用 mget。多次請(qǐng)求合并成一次請(qǐng)求,節(jié)約的是網(wǎng)絡(luò)傳輸時(shí)間。

          還有真實(shí)的案例是轉(zhuǎn)賬的場景,有的轉(zhuǎn)賬渠道是按次收費(fèi)的,那么作為第三方公司,我們就可以把用戶的請(qǐng)求先放到表里記錄著,等一小時(shí)之后,一起匯總發(fā)起,假設(shè)這一小時(shí)內(nèi)發(fā)生了 10 次轉(zhuǎn)賬,那么 10 次收費(fèi)就變成了 1 次收費(fèi),雖然讓客戶等的稍微久了點(diǎn),但還是在可以接受的范圍內(nèi),這操作節(jié)約的就是真金白銀了。

          高并發(fā)的請(qǐng)求合并

          理解了請(qǐng)求合并,那我們?cè)賮碚f說當(dāng)他前面加上高并發(fā)這三個(gè)字之后,會(huì)發(fā)生什么變化。

          首先不論是在請(qǐng)求合并的前面加上多么狂拽炫酷吊炸天的形容詞,說的多么的天花亂墜,它也還是一個(gè)請(qǐng)求合并。

          那么隊(duì)列和定時(shí)任務(wù)的這個(gè)基礎(chǔ)結(jié)構(gòu)肯定是不會(huì)變的。

          高并發(fā)的情況下,就是請(qǐng)求量非常的大嘛,那我們把定時(shí)任務(wù)的頻率調(diào)高一點(diǎn)不就行了?

          以前 100ms 內(nèi)就會(huì)過來 50 筆請(qǐng)求,我每收到一筆就是立即處理了。

          現(xiàn)在我們把請(qǐng)求先放到隊(duì)列里面緩存著,然后每 100ms 就執(zhí)行一次定時(shí)任務(wù)。

          100ms 到了之后,就會(huì)有定時(shí)任務(wù)把這 100ms 內(nèi)的所有請(qǐng)求取走,統(tǒng)一處理。

          同時(shí),我們還可以控制隊(duì)列的長度,比如只要 50ms 隊(duì)列的長度就達(dá)到了 50,這個(gè)時(shí)候我也進(jìn)行合并處理。不需要等待到 100ms 之后。

          其實(shí)寫到這里,高并發(fā)的請(qǐng)求合并的答案已經(jīng)出來了。關(guān)鍵點(diǎn)就三個(gè):

          一是需要借助隊(duì)列加定時(shí)任務(wù)實(shí)現(xiàn)。

          二是控制定時(shí)任務(wù)的執(zhí)行時(shí)間.

          三是控制緩沖隊(duì)列的任務(wù)長度。

          方案都想到了,把代碼寫出來豈不是很容易的事情。而且對(duì)于這種面試的場景圖,一般都是討論技術(shù)方案,而不太會(huì)去討論具體的代碼。

          當(dāng)討論到具體的代碼的時(shí)候,要么是對(duì)你的方案存疑,想具體的探討一下落地的可行性。要么就是你答對(duì)了,他要準(zhǔn)備從代碼的交易開始衍生另外的面試題了。

          總之,大部分情況下,不會(huì)在你給了一個(gè)面試官覺得錯(cuò)誤的方案之后,他還和你討論代碼細(xì)節(jié)。你們都不在一個(gè)頻道了,趕緊換題吧,還聊啥啊。

          實(shí)在要往代碼實(shí)現(xiàn)上聊,那么大概率他是在等著你說出一個(gè)框架:Hystrix。?????????????

          Hystrix框架

          其實(shí)這題,你要是知道 Hystrix,很容易就能給出一個(gè)比較完美的回答。

          因?yàn)?Hystrix 就有請(qǐng)求合并的功能。給大家演示一下。

          假設(shè)我們有一個(gè)學(xué)生信息查詢接口,調(diào)用頻率非常的高。對(duì)于這個(gè)接口我們需要做請(qǐng)求合并處理。

          做請(qǐng)求合并,我們至少對(duì)應(yīng)著兩個(gè)接口,一個(gè)是接收單個(gè)請(qǐng)求的接口,一個(gè)處理把單個(gè)請(qǐng)求匯總之后的請(qǐng)求接口。

          所以我們需要先提供兩個(gè) service:

          其中根據(jù)指定 id 查詢的接口,對(duì)應(yīng)的 Controller 是這樣的:

          服務(wù)啟動(dòng)起來后,我們用線程池結(jié)合 CountDownLatch 模擬 20 個(gè)并發(fā)請(qǐng)求:

          從控制臺(tái)可以看到,瞬間接受到了 20 個(gè)請(qǐng)求,執(zhí)行了 20 次查詢 sql:

          很明顯,這個(gè)時(shí)候我們就可以做請(qǐng)求合并。每收到 10 次請(qǐng)求,合并為一次處理,結(jié)合 Hystrix 代碼就是這樣的,為了代碼的簡潔性,我采用的是注解方式:

          在上面的圖片中,有兩個(gè)方法,一個(gè)是 getUserId,直接返回的是null,因?yàn)檫@個(gè)方法體不重要,根本就不會(huì)執(zhí)行。

          在 @HystrixCollapser 里面可以看到有一個(gè) batchMethod 的屬性,其值是 getUserBatchById。

          也就是說這個(gè)方法對(duì)應(yīng)的批量處理方法就是 getUserBatchById。當(dāng)我們請(qǐng)求 getUserById 方法的時(shí)候,Hystrix 會(huì)通過一定的邏輯,幫我們轉(zhuǎn)發(fā)到 getUserBatchById 上。

          所以我們調(diào)用的還是 getUserById 方法:

          同樣,我們用線程池結(jié)合 CountDownLatch 模擬 20 個(gè)并發(fā)請(qǐng)求,只是變換了請(qǐng)求地址:

          調(diào)用之后,神奇的事情就出現(xiàn)了,我們看看日志:

          同樣是接受到了 20 個(gè)請(qǐng)求,但是每 10 個(gè)一批,只執(zhí)行了兩個(gè)sql語句。

          從 20 個(gè) sql 到 2 個(gè) sql,這就是請(qǐng)求合并的威力。請(qǐng)求合并的處理速度甚至比單個(gè)處理還快,這也是性能的提升。

          那假設(shè)我們只有 5 個(gè)請(qǐng)求過來,不滿足 10 個(gè)這個(gè)條件呢?

          別忘了,我們還有定時(shí)任務(wù)呢。

          在 Hystrix 中,定時(shí)任務(wù)默認(rèn)是每 10ms 執(zhí)行一次:

          同時(shí)我們可以看到,如果不設(shè)置 maxRequestsInBatch,那么默認(rèn)是 Integer.MAX_VALUE。

          也就是說,在 Hystrix 中做請(qǐng)求合并,它更加側(cè)重的是時(shí)間方面。

          功能演示,其實(shí)就這么簡單,代碼量也不多,有興趣的朋友可以直接搭個(gè) Demo 跑跑看??纯?Hystrix 的源碼。

          我這里只是給大家指幾個(gè)關(guān)鍵點(diǎn)吧。

          第一個(gè)肯定是我們需要找到方法入口。

          你想,我們的 getUserById 方法的方法體里面直接是 return null,也就是說這個(gè)方法體是什么根本就不重要,因?yàn)椴粫?huì)去執(zhí)行方法體中的代碼。它只需要攔截到方法入?yún)ⅲ⒕彺嫫饋?,然后轉(zhuǎn)發(fā)到批量方法中去即可。

          然后方法體上面有一個(gè) @HystrixCollapser 注解。

          那么其對(duì)應(yīng)的實(shí)現(xiàn)方式你能想到什么?

          肯定是 AOP 了嘛。

          所以,我們拿著這個(gè)注解的全路徑,進(jìn)行搜索,啪的一下,很快啊,就能找到方法的入口:

          com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect#methodsAnnotatedWithHystrixCommand

          在入口處打上斷點(diǎn),就可以開始調(diào)試了:

          第二個(gè)我們看看定時(shí)任務(wù)是在哪兒進(jìn)行注冊(cè)的。

          這個(gè)就很好找了。我們已經(jīng)知道默認(rèn)參數(shù)是 10ms 了,只需要順著鏈路看一下,哪里的代碼調(diào)用了其對(duì)應(yīng)的 get 方法即可:

          同時(shí),我們可以看到,其定時(shí)功能是基于java.util.concurrent.ScheduledThreadPoolExecutor#scheduleAtFixedRate實(shí)現(xiàn)的。

          第三個(gè)我們看看是怎么控制超過指定數(shù)量后,就不等待定時(shí)任務(wù)執(zhí)行,而是直接發(fā)起匯總操作的:

          可以看到,在com.netflix.hystrix.collapser.RequestBatch#offer方法中,當(dāng) argumentMap 的 size 大于我們指定的 maxBatchSize 的時(shí)候返回了 null。

          如果,返回為 null ,那么說明已經(jīng)不能接受請(qǐng)求了,需要立即處理,代碼里面的注釋也說的很清楚了:

          以上就是三個(gè)關(guān)鍵的地方,Hystrix 的源碼讀起來,需要下點(diǎn)功夫,大家自己研究的時(shí)候需要做好心理準(zhǔn)備。

          最后再貼一個(gè)官方的請(qǐng)求合并工作流程圖:

          打完收工。

          面試題分享

          前面說的深圳的,兩年經(jīng)驗(yàn)的小伙伴把面試題匯總了一份給我,我也分享給大家吧。

          Java基礎(chǔ)

          • volatile關(guān)鍵字底層原理
          • 線程池各個(gè)參數(shù)含義
          • lock、Synn區(qū)別
          • ReentrantLock鎖公平與非公平實(shí)現(xiàn)、重入原理
          • HashMap擴(kuò)容時(shí)機(jī)(容量初始化為1000和10000是否觸發(fā)擴(kuò)容)、機(jī)制、1.7與1.8的差異
          • ConcurrentHashMap1.7、1.8的優(yōu)化與差異,size方法實(shí)現(xiàn)差異
          • ThreadLocal原理與風(fēng)險(xiǎn)、為什么會(huì)內(nèi)存泄露
          • 阻塞隊(duì)列的用途、區(qū)別
          • LinkedBlockingQueue對(duì)列的add、put區(qū)別,實(shí)際過程中如何使用
          • 悲觀鎖、樂觀鎖、自旋鎖的使用場景、實(shí)現(xiàn)方式、優(yōu)缺點(diǎn)
          • Class.forName、loanClass區(qū)別;
          • 線程生命周期、死鎖條件與死鎖避免、狀態(tài)轉(zhuǎn)換關(guān)系(源碼級(jí)別);
          • String intern方法;
          • cas的優(yōu)缺點(diǎn)與解決方案、ABA問題;

          JVM相關(guān)

          • CMS垃圾回收的碎片解決方式
          • 常用的垃圾回收器
          • JVM垃圾回收器CMS的優(yōu)缺點(diǎn)、與G1的區(qū)別、進(jìn)入老年代的時(shí)機(jī)
          • JVM內(nèi)存模型
          • JVM調(diào)優(yōu)思路
          • GC Root、ModUnionTable
          • 偏向鎖、輕量級(jí)鎖、重量級(jí)鎖底層原理、升級(jí)過程
          • jmap、jstat、top、MAT
          • CMS與G1對(duì)別
          • GC Root、ModUnionTable;

          Redis相關(guān)

          • Redis高性能原因
          • Redis的部署模式
          • RedisCluster底層原理
          • Redis持久化機(jī)制
          • 緩存淘汰機(jī)制
          • 緩存穿透、緩存雪崩、緩存擊穿發(fā)生場景與解決方案

          SQL相關(guān)

          • MyBatis攔截器的用途
          • MyBatis動(dòng)態(tài)SQL原理
          • 分庫分表方案設(shè)計(jì)
          • MySQL怎么解決幻讀、原理(源碼級(jí)別)
          • Gap鎖的作用域原理
          • RR、RC區(qū)別
          • MySQL默認(rèn)的事務(wù)隔離級(jí)別、Oracle默認(rèn)的事務(wù)隔離級(jí)別
          • MySQL為啥使用B+樹索引
          • redo log、binlog、undo
          • log寫入順序、分別保證了ACID的什么特性
          • 數(shù)據(jù)庫樂觀鎖
          • MySQL優(yōu)化
          • MySQL底層原理

          Spring相關(guān)

          • @Bean注解、@Component注解區(qū)別
          • Spring Aop原理
          • @Aspect和普通AOP區(qū)別
          • 自定義攔截器和Aop那個(gè)先執(zhí)行
          • web 攔截器
          • DispatchServlet原理

          Dubbo相關(guān)

          • Dubbo負(fù)載均衡、集群容錯(cuò)
          • Dubbo SPI機(jī)制、Route重寫使用場景
          • Dubbo RPC底層原理
          • 全鏈路監(jiān)控實(shí)現(xiàn)原理

          分布式相關(guān)

          • 分布式鎖的實(shí)現(xiàn)方式
          • 漏斗算法、令牌桶算法
          • 事務(wù)最終一致性解決方案
          • SLA
          • 分布式事務(wù)實(shí)現(xiàn)方式與區(qū)別
          • Tcc Confirm失敗怎么辦?
          • 分布式鎖的各種實(shí)現(xiàn)方式、對(duì)比
          • 分布式ID的各種實(shí)現(xiàn)方式、對(duì)比
          • 雪花算法時(shí)鐘回?fù)軉栴}與應(yīng)對(duì)方案
          • 紅鎖算法

          設(shè)計(jì)模式

          • 常用的設(shè)計(jì)模式
          • 狀態(tài)模式
          • 責(zé)任鏈模式解決了什么問題
          • 餓漢式、懶漢式優(yōu)缺點(diǎn)、使用場景
          • 模板方法模式、策略模式、單例模式、責(zé)任鏈模式

          Zookeeper

          • Zookeeper底層架構(gòu)設(shè)計(jì)
          • zk一致性

          MQ

          • Kafka順序消息
          • MQ消息冪等
          • Kafka高性能秘訣
          • Kafka高吞吐原理
          • Rocket事務(wù)消息、延時(shí)隊(duì)列

          計(jì)算機(jī)網(wǎng)絡(luò)

          • 瀏覽器輸入一個(gè)url發(fā)生了什么
          • Http 1.0、1.1、2.0差異
          • IO多路復(fù)用
          • TCP四次揮手過程、狀態(tài)切換
          • XSS、CRSF攻擊與預(yù)防
          • 301、302區(qū)別

          Tomcat

          • Tomcat大概原理

          代碼

          • 手寫發(fā)布訂閱模式
          • 大數(shù)(兩個(gè)String)相加

          場景問題

          • 打賞排行榜實(shí)現(xiàn)
          • 高并發(fā)下的請(qǐng)求合并
          • CPU 100%處理經(jīng)驗(yàn)
          • 短鏈系統(tǒng)設(shè)計(jì)
          • 附近的人項(xiàng)目實(shí)現(xiàn)
          • 10w個(gè)紅包秒級(jí)發(fā)送方案
          • 延時(shí)任務(wù)的實(shí)現(xiàn)方案與優(yōu)缺點(diǎn)對(duì)比

          說來慚愧,有些題我也答不上來,所以和大家一起查漏補(bǔ)缺吧。

          哦,對(duì)了,那個(gè)小伙子最終收割了好幾個(gè)大廠 offer,跑來問我哪個(gè) offer 好。

          你說這問題對(duì)我來說那不是超綱了嗎?我也沒在大廠體驗(yàn)過啊。所以我懷疑他不講武德,來騙,來偷襲我這個(gè)老實(shí)巴交的小號(hào)主,我希望他能耗子尾汁,在鵝廠好好發(fā)展:

          荒腔走板

          周六早上起來,看到新聞?wù)f北京下雪了。成都最近也降溫了。上面的圖片還是我在北京的時(shí)候拍的。

          剛剛懷念完北京個(gè)性鮮明的秋天,又迎來了我最喜歡的冬天。

          我懷念北方的冬天,那種一進(jìn)屋,眼鏡上蒙起一層薄薄的霧,然后里面就被暖氣包裹起來的感覺。

          在北京,冬天進(jìn)屋是先脫下厚厚的棉衣,而在成都,冬天進(jìn)屋是先下意識(shí)的裹緊了身上的衣服。

          當(dāng)然,我作為一個(gè)南方人,最喜歡的還是下雪的時(shí)候。在成都的市區(qū)里面,是極少極少能遇到下雪天的,偶爾碰見飄著幾粒雪花,落在地上也決然是不會(huì)有積雪形成的。

          而在北京的時(shí)候,看天氣預(yù)報(bào)說是晚上會(huì)下雪,那第二天早上起來都是滿懷期待的拉開窗簾,急迫的想看看白雪覆蓋的北京。

          我喜歡那種穿著大頭靴子,踩在積雪上軟軟的,發(fā)出格嘰格嘰的聲音,那是一種屬于北方的聲音。

          說來也是可惜,每次北京下雪的時(shí)候,都不合時(shí)宜,導(dǎo)致我都沒有時(shí)間能去故宮。下雪的時(shí)候去故宮,可能也是無數(shù)人可遇而不可求的事情吧。

          寫到這里的時(shí)候我本來想多描述一下我多懷念北京的雪景的,但是給家里安裝投影幕布的師傅打電話過來說他已經(jīng)在等電梯了。

          那我必須的快速的收尾了。

          這個(gè)周末一直在忙著裝家具,弄軟裝方面的事情,有點(diǎn)疲倦。又想著今年馬上就要結(jié)束了。我計(jì)劃的每年都要寫的《我這一年》還沒開始動(dòng)筆,一想著堅(jiān)持寫了 7 年,不會(huì)在今年真的給斷了吧?

          一股焦慮就隨之而來。那能怎么辦呢?要么休息休息,要么繼續(xù)肝唄。沒所謂的,焦慮大多是因?yàn)榭吹奶h(yuǎn)了。

          沒關(guān)系,那就先走好腳下的路吧。

          哦,對(duì)了,新家還沒安裝網(wǎng)絡(luò),我周末在那邊待了兩個(gè)下午,所以這篇文章是我開手機(jī)熱點(diǎn),用流量寫的。不斷更,是我最后的倔強(qiáng)。

          好了,師傅在敲門了。

          就這樣吧。

          最后說一句(求關(guān)注)

          好了,看到了這里安排個(gè)“一鍵三連”(轉(zhuǎn)發(fā)、在看、點(diǎn)贊)吧,周更很累的,不要白嫖我,需要一點(diǎn)正反饋。

          才疏學(xué)淺,難免會(huì)有紕漏,如果你發(fā)現(xiàn)了錯(cuò)誤的地方,可以在后臺(tái)提出來,我對(duì)其加以修改。

          感謝您的閱讀,十分歡迎并感謝您的關(guān)注。



          0、你這么努力,為什么能力提升還這么慢?

          1、十月豐收季,看看我都收獲了什么?

          瀏覽 60
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  玩弄粉嫩护士小泬20p | 日韩三级在线 | 国产靠逼视频 | 国产一级二级黄色片 | 国产在线网 |