国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

高并發(fā)架構(gòu)的TCP知識介紹

Carson / 560人閱讀

摘要:但是它不會發(fā)送的。先大概說下流量控制是根據(jù)接收方的窗口大小來感知我這次能夠傳多少數(shù)據(jù)給對方滑動窗口擁塞控制而擁塞控制主要是避免網(wǎng)絡(luò)擁塞,它考慮的問題更多。

做為一個有追求的程序員,不能只滿足增刪改查,我們要對系統(tǒng)全方面無死角掌控。掌握了這些基本的網(wǎng)絡(luò)知識后,相信一方面日常排錯中會事半功倍,另一方面日常架構(gòu)中不得不考慮的高并發(fā)問題,理解了這些底層協(xié)議也是會如虎添翼。

本文不會單純給大家講講TCP三次握手、四次揮手就完事了。如果只是哪樣的話,我直接貼幾個連接就完事了。我希望把實(shí)際工作中的很多點(diǎn)能夠串起來講給大家。當(dāng)然為了文章完整,我依然會從 三次握手 起頭。

再說TCP狀態(tài)變更過程

不管是三次握手、還是四次揮手,他們都是完成了TCP不同狀態(tài)的切換。進(jìn)而影響各種數(shù)據(jù)的傳輸情況。下面從三次握手開始分析。

本文圖片有部分來自網(wǎng)絡(luò),若有侵權(quán),告知即焚

三次握手

來看看三次握手的圖,估計(jì)大家看這圖都快看吐了,不過為什么每次面試、回憶的時候還是想不起呢?我再來抄抄這鍋剩飯吧!

首先當(dāng)服務(wù)端處于 listen 狀態(tài)的時候,我們就可以再客戶端發(fā)起監(jiān)聽了,此時客戶端會處于 SYN_SENT 狀態(tài)。服務(wù)端收到這個消息會返回一個 SYN 并且同時 ACK 客戶端的請求,之后服務(wù)端便處于 SYN_RCVD 狀態(tài)。這個時候客戶端收到了服務(wù)端的 SYN&ACK,就會發(fā)送對服務(wù)端的 ACK,之后便處于 ESTABLISHED 狀態(tài)。服務(wù)端收到了對自己的 ACK 后也會處于 ESTABLISHED 狀態(tài)。

經(jīng)常在面試中可能有人提問:為什么握手要3次,不是2次或者4次呢?

首先說4次握手,其實(shí)為了保證可靠性,這個握手次數(shù)可以一直循環(huán)下去;但是這沒有一個終止就沒有意義了。所以3次,保證了各方消息有來有回就足夠了。當(dāng)然這里可能有一種情況是,客戶端發(fā)送的 ACK 在網(wǎng)絡(luò)中被丟了。那怎么辦?

    其實(shí)大部分時候,我們連接建立完成就會立刻發(fā)送數(shù)據(jù),所以如果服務(wù)端沒有收到 ACK 沒關(guān)系,當(dāng)收到數(shù)據(jù)就會認(rèn)為連接已經(jīng)建立;

    如果連接建立后不立馬傳輸數(shù)據(jù),那么服務(wù)端認(rèn)為連接沒有建立成功會周期性重發(fā) SYN&ACK 直到客戶端確認(rèn)成功。

再說為什么2次握手不行呢?2次握手我們可以想象是沒有三次握手最后的 ACK, 在實(shí)際中確實(shí)會出現(xiàn)客戶端發(fā)送 ACK 服務(wù)端沒有收到的情況(上面的情況一),那么這是否說明兩次握手也是可行的呢? 看下情況二,2次握手當(dāng)服務(wù)端發(fā)送消息后,就認(rèn)為建立成功,而恰巧此時又沒有數(shù)據(jù)傳輸。這就會帶來一種資源浪費(fèi)的情況。比如:客戶端可能由于延時發(fā)送了多個連接情況,當(dāng)服務(wù)端每收到一個請求回復(fù)后就認(rèn)為連接建立成功,但是這其中很多求情都是延時產(chǎn)生的重復(fù)連接,浪費(fèi)了很多寶貴的資源。

因此綜上所述,從資源節(jié)省、效率3次握手都是最合適的。話又回來三次握手的真實(shí)意義其實(shí)就是協(xié)商傳輸數(shù)據(jù)用的:序列號與窗口大小

下面我們通過抓包再來看一下真實(shí)的情況是否如上所述。

20:33:26.583598 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [S], seq 621839080, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1050275400 ecr 0,sackOK,eol], length 0
20:33:26.660754 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [S.], seq 1754967387, ack 621839081, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0
20:33:26.660819 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967388, win 4096, length 0

抓包: sudo tcpdump -n host www.baidu.com -S


S 表示 SYN

. 表示 ACK

P 表示 傳輸數(shù)據(jù)

F 表示 FIN

四次揮手

揮手,就是說數(shù)據(jù)傳完了,同志們再見!

這里有個問題需要注意下,其實(shí)客戶端、服務(wù)端都能夠主動發(fā)起關(guān)閉操作,誰調(diào)用 close() 就先發(fā)送關(guān)閉的請求。當(dāng)然一般的流程,發(fā)起建立連接的一方會主動發(fā)起關(guān)閉請求(http中)。

關(guān)于4次揮手的過程,我就不多解釋了,這里有兩個重要的狀態(tài)我需要解釋下,這都是我親自經(jīng)歷過的線上故障,close_waittime_wait

先給大家一個命令,統(tǒng)計(jì)tcp的各種狀態(tài)情況。下面表格內(nèi)容就來自這個命令的統(tǒng)計(jì)。

netstat -n | awk "/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}"

Tcp狀態(tài) 連接數(shù)
CLOSE_WAIT 505
ESTABLISHED 808
TIME_WAIT 3481
SYN_SENT 1
SYN_RECV 1
LAST_ACK 2
FIN_WAIT2 2
FIN_WAIT1 1

大量的CLOSE_WAIT 這個在我之前的一篇文章 線上大量CLOSE_WAIT原因分析 已經(jīng)有過介紹,它會導(dǎo)致大量的socket無法釋放。而每個socket都是一個文件,是會占用資源的。這個問題主要是代碼問題。它出現(xiàn)在被動關(guān)閉的一方(習(xí)慣稱為server)。

大量的TIME_WAIT 這個問題在日常中經(jīng)常看到,流量一高就出現(xiàn)大量的該情況。該狀態(tài)出現(xiàn)在主動發(fā)起關(guān)閉的一方。該狀態(tài)一般等待的時間設(shè)為 2MSL后自動關(guān)閉,MSL是Maximum Segment Lifetime,報文最大生存時間,如果報文超過這個時間,就會被丟棄。處于該狀態(tài)下的socket也是不能被回收使用的。線上我就遇到這種情況,每次大流量的時候,每臺機(jī)器處于該狀態(tài)的socket就多達(dá)10w+,遠(yuǎn)遠(yuǎn)比處于 Established 狀態(tài)的socket多的多,導(dǎo)致很多時候服務(wù)響應(yīng)能力下降。這個一方面可以通過調(diào)整內(nèi)核參數(shù)處理,另一方面避免使用太多的短鏈接,可以采用連接池來提升性能。另外在代碼層面可能是由于某些地方?jīng)]有關(guān)閉連接導(dǎo)致的,也需要檢查業(yè)務(wù)代碼。

上面兩個狀態(tài)一定要牢記發(fā)生在哪一方,這方便我們快速定位問題。

最后這里還是放上揮手時的抓包數(shù)據(jù):

20:33:26.750607 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [F.], seq 621839159, ack 1754967720, win 4096, length 0
20:33:26.827472 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [.], ack 621839160, win 776, length 0
20:33:26.827677 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [F.], seq 1754967720, ack 621839160, win 776, length 0
20:33:26.827729 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967721, win 4096, length 0

不多不少,剛好4次。

TCP狀態(tài)變更

網(wǎng)絡(luò)上有一張TCP狀態(tài)機(jī)的圖,我覺得太復(fù)雜了,用自己的方式搞個簡單點(diǎn)的容易理解的。我從兩個角度來說明狀態(tài)的變更。

一個是客戶端

一個是服務(wù)端

看下面兩張圖的時候,請一定結(jié)合上面三次握手、四次揮手的時序圖一起看,加深理解。

客戶端狀態(tài)變更

通過這張圖,大家是否能夠清晰明了的知道 TCP 在客戶端上的變更情況了呢?

服務(wù)端狀態(tài)變更

這一張圖描述了 TCP 狀態(tài)在服務(wù)端的變遷。

TCP的流量控制與擁塞控制

我們常說TCP是面向連接的,UDP是無連接的。那么TCP這個面向連接主要解決的是什么問題呢?

這里繼續(xù)把三次握手的抓包數(shù)據(jù)貼出來分析下:

20:33:26.583598 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [S], seq 621839080, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1050275400 ecr 0,sackOK,eol], length 0
20:33:26.660754 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [S.], seq 1754967387, ack 621839081, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0
20:33:26.660819 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967388, win 4096, length 0

上面我們說到 TCP 的三次握手最重要的就是協(xié)商傳輸數(shù)據(jù)用的序列號。那這個序列號究竟有些什么用呢?這個序號能夠幫助后續(xù)兩端進(jìn)行確認(rèn)數(shù)據(jù)包是否收到,解決順序、丟包問題;另外我們還可以看到有一個 win 字段,這是雙方交流的窗口大小,這在每次傳輸數(shù)據(jù)過程中也會攜帶。主要是告訴對方,我窗口是這么大,別發(fā)多了或者別發(fā)太少。

總結(jié)下,TCP的幾個特點(diǎn)是:

順序問題,依靠序號

丟包問題,依靠序號

流量控制,依靠滑動窗口

擁塞控制,依靠擁塞窗口+滑動窗口

連接維護(hù),三次握手/四次揮手

順序與丟包問題

這個問題其實(shí)應(yīng)該很好理解。由于數(shù)據(jù)在傳輸前我們已經(jīng)有序號了,這里注意一下這個序號是隨機(jī)的,重復(fù)的概率極地,避免了程序發(fā)生亂入的可能性。

由于我們每個數(shù)據(jù)包有序號,雖然發(fā)送與到達(dá)可能不是順序的,但是TCP層收到數(shù)據(jù)后,可以根據(jù)序號進(jìn)行重新排列;另外在這個排列過程中,發(fā)現(xiàn)有了1,2,3,5,6這幾個包,一檢查就知道4要么延時未到達(dá),要么丟包了,等待重傳。

這里需要重要說明的一點(diǎn)是。為了提升效率,TCP其實(shí)并不是收到一個包就發(fā)一個ack。那是如何ACK的呢?還是以上面為例,TCP收到了1,2,3,5,6這幾個包,它可能會發(fā)送一個 ack ,seq=3 的確認(rèn)包,這樣次一次確認(rèn)了3個包。但是它不會發(fā)送 5,6 的ack。因?yàn)?沒有收到啊!一旦4延時到達(dá)或者重發(fā)到達(dá),就會發(fā)送一個 ack, seq=6,又一次確認(rèn)了3個包。

流量控制與擁塞控制

這兩個概念說實(shí)話,讓我理解了挺長時間,主要是對它們各自控制的內(nèi)容以及相互之間是否有作用一直沒有鬧清楚。

先大概說下:

流量控制:是根據(jù)接收方的窗口大小來感知我這次能夠傳多少數(shù)據(jù)給對方;———— 滑動窗口

擁塞控制:而擁塞控制主要是避免網(wǎng)絡(luò)擁塞,它考慮的問題更多。根據(jù)綜合因素來覺得發(fā)多少數(shù)據(jù)給對方;———— 滑動窗口&擁塞窗口

舉個例子說下,比如:A給B發(fā)送數(shù)據(jù),通過握手后,A知道B一次可以收1000的數(shù)據(jù)(B有這么大的處理能力),那么這個時候滑動窗口就可以設(shè)置成1000。那是不是最后真的可以一次發(fā)這么多數(shù)據(jù)給B呢?還不是,這時候得問問擁塞窗口,老兄,現(xiàn)在網(wǎng)絡(luò)情況怎么樣?一次運(yùn)1000的數(shù)據(jù)有壓力嗎?擁塞窗口一通計(jì)算說不行,現(xiàn)在是高峰期,最多只能有600的貨上路。最終這次傳數(shù)據(jù)的時候就是 600 的標(biāo)注。大家也可以關(guān)注抓包數(shù)據(jù)的 win 值,一直在動態(tài)調(diào)整。

當(dāng)然另外一種情況是滑動窗口比擁塞窗口小,雖然運(yùn)輸能力強(qiáng),但是接收能力有限,這時候就要取滑動窗口的值來實(shí)際發(fā)生。所以它們二者之間是有關(guān)系的。

所以具體到每次能夠發(fā)送多少數(shù)據(jù),有這么一個公式:

LastByteSend - LastByteAcked <= min{cwnd,rwnd}

LastByteSend 是最后一個發(fā)送的字節(jié)的序號

LastByteAcked 最后一個被確認(rèn)的字節(jié)的序號

這兩個相減得到的是本次能夠發(fā)送的數(shù)據(jù),這個數(shù)據(jù)一定小于或等于 cwnd 與 rwnd 中最小的一個值。相信大家能夠理清楚。

那么這部分知識對于實(shí)際工作中有什么作用呢?指導(dǎo)意義就是:如果你的業(yè)務(wù)很重要、很核心一定不要混布;二是如果你的服務(wù)忽快忽慢,而確信依賴服務(wù)沒有問題,檢查下機(jī)器對應(yīng)的網(wǎng)絡(luò)情況;三是窗口這個速度控制機(jī)制,在我們進(jìn)行服務(wù)設(shè)計(jì)的時候,非常具有參考意義。是不是有點(diǎn)消息隊(duì)列的感覺?(很多消息隊(duì)列都是勻速的,我們是否可以加一個窗口的概念來進(jìn)行優(yōu)化呢?)

是什么限制了你的連接

到了最關(guān)鍵的地方了,精華我都是留到最后講。下面放一張網(wǎng)上找的socket操作步驟圖,畫的太好了我就直接用了。

我們假設(shè)我的服務(wù)端就是 Nginx ,我來嘗試解讀一下。當(dāng)客戶端調(diào)用 connect() 時候就會發(fā)起三次握手,這次握手的時候有幾個元素唯一確定了這次通信(或者說這個socket),[源IP:源Port, 目的IP:目的Port] ,當(dāng)然這個socket還不是最終用來傳輸數(shù)據(jù)的socket,一旦握手完成后,服務(wù)端會在返回一個 socket 專門用來后續(xù)的數(shù)據(jù)傳輸。這里暫且把第一個socket叫 監(jiān)聽socket,第二個叫 傳輸socket 方便后文敘述。

為什么要這么設(shè)計(jì)呢?大家想一想,如果監(jiān)聽的socket還要負(fù)責(zé)數(shù)據(jù)的收發(fā),請問這個服務(wù)端的效率如何提升?什么東西、誰都往這個socket里邊丟,太復(fù)雜!

提高連接常用套路

到了這一步,我們現(xiàn)在先停下來算算自己的服務(wù)器機(jī)器能夠有多少連接呢?這個極限又是如何一步步被突破呢?

先說 監(jiān)聽socket ,服務(wù)器的prot一般都是固定的,服務(wù)器的ip當(dāng)然也是固定的(單機(jī))。那么上面的結(jié)構(gòu) [源IP:源Port, 目的IP:目的Port] 其實(shí)只有客戶端的ip與端口可以發(fā)生變化。假設(shè)客戶端用的是IPv4,那么理論連接數(shù)是:2^32(ip數(shù)) * 2^16(端口數(shù)) = 2^48。

看起來這個值蠻大的。但是真的能夠有這么多連接嗎?不可能的,因?yàn)槊恳粋€socket都需要消耗內(nèi)存;以及每一個進(jìn)程的文件描述符是有上限的。這些都限制了最終的連接數(shù)。

那么如何進(jìn)行調(diào)和呢?我知道的操作有:多進(jìn)程、多線程、IO多路服用、協(xié)程等手段組合使用。

多進(jìn)程

也就是監(jiān)聽是一個進(jìn)程,一旦accept后,對于 傳輸socket 我們就fork一個新的子進(jìn)程來處理。但是這種方式太重,fork一個進(jìn)程、銷毀一個進(jìn)程都是特別費(fèi)事的。單機(jī)對進(jìn)程的創(chuàng)建上限也是有限制的。

多線程

線程比進(jìn)程要輕量級的多,它會共享父進(jìn)程的很多資源,比如:文件描述符、進(jìn)程空間,它就是多了一個引用。因此它的創(chuàng)建、銷毀更加容易。每一個 傳輸socket 在這里就交給了線程來處理。

但是不管是多進(jìn)程、還是多線程都存在一個問題,一個連接對應(yīng)一個進(jìn)程或者協(xié)程。這都很難逃脫 C10K 的問題。那么該怎么辦呢?

IO多路復(fù)用

IO多路復(fù)用是什么意思呢?在上面單純的多進(jìn)程、多線程模型中,一個進(jìn)程或線程只能處理一個連接。用了IO多路復(fù)用后,我一個進(jìn)程或線程就能處理多個連接。

我們都知道 Nginx 非常高效,它的結(jié)構(gòu)是:master + worker,worker 會在 80、443端口上來監(jiān)聽請求。它的worker一般設(shè)置為 cpu 的cores數(shù),那么這么少的子進(jìn)程是如何解決超多連接的呢?這里其實(shí)每個worker就采用了 epoll 模型(當(dāng)然IO多路復(fù)用還有個select,這里就不說了)。

處于監(jiān)聽狀態(tài)的worker,會把所有 監(jiān)聽socket 加入到自己的epoll中。當(dāng)這些socket都在epoll中時,如果某個socket有事件發(fā)生就會立即被回調(diào)喚醒(這涉及epoll的紅黑樹,講不清楚不細(xì)說了)。這種模式,大大增加了每個進(jìn)程可以管理的socket數(shù)量,上限直接可以上升到進(jìn)程能夠操作的最大文件描述符。

一般機(jī)器可以設(shè)置百萬級別文件描述符,所以單機(jī)單進(jìn)程就是百萬連接,epoll是解決C10K的利器,很多開源軟件用到了它。

這里說下,并不是所有的worker都是同時處于監(jiān)聽端口的狀態(tài),這涉及到nginx驚群、搶自旋鎖的問題,不再本文范圍內(nèi)不多說。

關(guān)于ulimit

在文章的最后,補(bǔ)充一些單機(jī)文件描述符設(shè)置的問題。我們常說連接數(shù)受限于文件描述符,這是為什么?

因?yàn)樵趌inux上一切皆文件,故每一個socket都是被當(dāng)作一個文件看待,那么每個文件就會有一個文件描述符。在linux中每一個進(jìn)程中都有一個數(shù)組保存了該進(jìn)程需要的所有文件描述符。這個文件描述符其實(shí)就是這個數(shù)組的 key ,它的 value 是一個指針,指向的就是打開的對應(yīng)文件。

關(guān)于文件描述符有兩點(diǎn)注意:

    它對應(yīng)的其實(shí)是一個linux上的文件

    文件描述符本身這個值在不同進(jìn)程中是可以重復(fù)的

另外補(bǔ)充一點(diǎn),單機(jī)設(shè)置的ulimit的上線受限與系統(tǒng)的兩個配置:

fs.nr_open,進(jìn)程級別

fs.file-max,系統(tǒng)級別

fs.nr_open 總是應(yīng)該小于等于 fs.file-max,這兩個值的設(shè)置也不是隨意可以操作,因?yàn)樵O(shè)置的越大,系統(tǒng)資源消耗越多,所以需要根據(jù)真實(shí)情況來進(jìn)行設(shè)置。


至此,本篇長文就完結(jié)了。這跟上篇 高并發(fā)架構(gòu)的CDN知識介紹 屬于一個系列,高并發(fā)架構(gòu)需要理解的網(wǎng)絡(luò)基礎(chǔ)知識。

后面還會寫一下 HTTP/HTTPS 的知識。然后關(guān)于高并發(fā)網(wǎng)絡(luò)相關(guān)的東西就算完結(jié)。我會開啟下一個篇章。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/7382.html

相關(guān)文章

  • Java面試 32個核心必考點(diǎn)完全解析

    摘要:如問到是否使用某框架,實(shí)際是是問該框架的使用場景,有什么特點(diǎn),和同類可框架對比一系列的問題。這兩個方向的區(qū)分點(diǎn)在于工作方向的側(cè)重點(diǎn)不同。 [TOC] 這是一份來自嗶哩嗶哩的Java面試Java面試 32個核心必考點(diǎn)完全解析(完) 課程預(yù)習(xí) 1.1 課程內(nèi)容分為三個模塊 基礎(chǔ)模塊: 技術(shù)崗位與面試 計(jì)算機(jī)基礎(chǔ) JVM原理 多線程 設(shè)計(jì)模式 數(shù)據(jù)結(jié)構(gòu)與算法 應(yīng)用模塊: 常用工具集 ...

    JiaXinYi 評論0 收藏0
  • 網(wǎng)絡(luò)編程 - 收藏集 - 掘金

    摘要:個高級多線程面試題及回答后端掘金在任何面試當(dāng)中多線程和并發(fā)方面的問題都是必不可少的一部分。目前在生產(chǎn)環(huán)基于的技術(shù)問答網(wǎng)站系統(tǒng)實(shí)現(xiàn)后端掘金這一篇博客將詳細(xì)介紹一個基于的問答網(wǎng)站的實(shí)現(xiàn),有詳細(xì)的代碼。 15 個高級 Java 多線程面試題及回答 - 后端 - 掘金在任何Java面試當(dāng)中多線程和并發(fā)方面的問題都是必不可少的一部分。如果你想獲得任何股票投資銀行的前臺資訊職位,那么你應(yīng)該準(zhǔn)備很多...

    justCoding 評論0 收藏0
  • 網(wǎng)絡(luò)編程 - 收藏集 - 掘金

    摘要:個高級多線程面試題及回答后端掘金在任何面試當(dāng)中多線程和并發(fā)方面的問題都是必不可少的一部分。目前在生產(chǎn)環(huán)基于的技術(shù)問答網(wǎng)站系統(tǒng)實(shí)現(xiàn)后端掘金這一篇博客將詳細(xì)介紹一個基于的問答網(wǎng)站的實(shí)現(xiàn),有詳細(xì)的代碼。 15 個高級 Java 多線程面試題及回答 - 后端 - 掘金在任何Java面試當(dāng)中多線程和并發(fā)方面的問題都是必不可少的一部分。如果你想獲得任何股票投資銀行的前臺資訊職位,那么你應(yīng)該準(zhǔn)備很多...

    selfimpr 評論0 收藏0
  • 阿里之路+Java面經(jīng)考點(diǎn)

    摘要:我的是忙碌的一年,從年初備戰(zhàn)實(shí)習(xí)春招,年三十都在死磕源碼,三月份經(jīng)歷了阿里五次面試,四月順利收到實(shí)習(xí)。因?yàn)槲倚睦砗芮宄业哪繕?biāo)是阿里。所以在收到阿里之后的那晚,我重新規(guī)劃了接下來的學(xué)習(xí)計(jì)劃,將我的短期目標(biāo)更新成拿下阿里轉(zhuǎn)正。 我的2017是忙碌的一年,從年初備戰(zhàn)實(shí)習(xí)春招,年三十都在死磕JDK源碼,三月份經(jīng)歷了阿里五次面試,四月順利收到實(shí)習(xí)offer。然后五月懷著忐忑的心情開始了螞蟻金...

    姘擱『 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<