偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試率超高的JS事件循環(huán),看這篇就夠了

開發(fā) 前端
事件循環(huán)是 JavaScript 中一個(gè)非常重要的概念,下面就來(lái)看看瀏覽器和 Node.js 中的事件循環(huán)的原理,以及兩者之間的差異!

大家好,我是 CUGGZ。

事件循環(huán)是 JavaScript 中一個(gè)非常重要的概念,下面就來(lái)看看瀏覽器和 Node.js 中的事件循環(huán)的原理,以及兩者之間的差異!

1、異步執(zhí)行原理

(1)單線程的JavaScript

我們知道,JavaScript是一種單線程語(yǔ)言,它主要用來(lái)與用戶互動(dòng),以及操作DOM。

JavaScript 有同步和異步的概念,這就解決了代碼阻塞的問(wèn)題:

  • 同步:如果在一個(gè)函數(shù)返回的時(shí)候,調(diào)用者就能夠得到預(yù)期結(jié)果,那么這個(gè)函數(shù)就是同步的。
  • 異步:如果在函數(shù)返回的時(shí)候,調(diào)用者還不能夠得到預(yù)期結(jié)果,而是需要在將來(lái)通過(guò)一定的手段得到,那么這個(gè)函數(shù)就是異步的。

那單線程有什么好處呢?

  • 在 JS 運(yùn)行的時(shí)候可能會(huì)阻止 UI 渲染,這說(shuō)明了兩個(gè)線程是互斥的。這是因?yàn)?JS 可以修改 DOM,如果在 JS 執(zhí)行的時(shí)候 UI 線程還在工作,就可能導(dǎo)致不能安全的渲染 UI。
  • 得益于 JS 是單線程運(yùn)行的,可以達(dá)到節(jié)省內(nèi)存,節(jié)約上下文切換時(shí)間的好處。

(2)多線程的瀏覽器

JS 是單線程的,在同一個(gè)時(shí)間只能做一件事情,那為什么瀏覽器可以同時(shí)執(zhí)行異步任務(wù)呢?

這是因?yàn)闉g覽器是多線程的,當(dāng) JS 需要執(zhí)行異步任務(wù)時(shí),瀏覽器會(huì)另外啟動(dòng)一個(gè)線程去執(zhí)行該任務(wù)。也就是說(shuō),JavaScript是單線程的指的是執(zhí)行JavaScript代碼的線程只有一個(gè),是瀏覽器提供的JavaScript引擎線程(主線程)。除此之外,瀏覽器中還有定時(shí)器線程、 HTTP 請(qǐng)求線程等線程,這些線程主要不是來(lái)執(zhí)行 JS 代碼的。

比如主線程中需要發(fā)送數(shù)據(jù)請(qǐng)求,就會(huì)把這個(gè)任務(wù)交給異步 HTTP 請(qǐng)求線程去執(zhí)行,等請(qǐng)求數(shù)據(jù)返回之后,再將 callback 里需要執(zhí)行的 JS 回調(diào)交給 JS 引擎線程去執(zhí)行。也就是說(shuō),瀏覽器才是真正執(zhí)行發(fā)送請(qǐng)求這個(gè)任務(wù)的角色,而 JS 只是負(fù)責(zé)執(zhí)行最后的回調(diào)處理。所以這里的異步不是 JS 自身實(shí)現(xiàn)的,而是瀏覽器為其提供的能力。

下圖是Chrome瀏覽器的架構(gòu)圖:

圖片

可以看到,Chrome不僅擁有多個(gè)進(jìn)程,還有多個(gè)線程。以渲染進(jìn)程為例,就包含GUI渲染線程、JS引擎線程、事件觸發(fā)線程、定時(shí)器觸發(fā)線程、異步HTTP請(qǐng)求線程。這些線程為 JS 在瀏覽器中完成異步任務(wù)提供了基礎(chǔ)。

2、瀏覽器事件循環(huán)

JavaScript的任務(wù)分為兩種同步和異步:

  • 同步任務(wù): 在主線程上排隊(duì)執(zhí)行的任務(wù),只有一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行下一個(gè)任務(wù),
  • 異步任務(wù): 不進(jìn)入主線程,而是放在任務(wù)隊(duì)列中,若有多個(gè)異步任務(wù)則需要在任務(wù)隊(duì)列中排隊(duì)等待,任務(wù)隊(duì)列類似于緩沖區(qū),任務(wù)下一步會(huì)被移到執(zhí)行棧然后主線程執(zhí)行調(diào)用棧的任務(wù)。

上面提到了任務(wù)隊(duì)列和執(zhí)行棧,下面就先來(lái)看看這兩個(gè)概念。

(1)執(zhí)行棧與任務(wù)隊(duì)列

執(zhí)行棧:從名字可以看出,執(zhí)行棧使用到的是數(shù)據(jù)結(jié)構(gòu)中的棧結(jié)構(gòu), 它是一個(gè)存儲(chǔ)函數(shù)調(diào)用的棧結(jié)構(gòu),遵循先進(jìn)后出的原則。它主要負(fù)責(zé)跟蹤所有要執(zhí)行的代碼。 每當(dāng)一個(gè)函數(shù)執(zhí)行完成時(shí),就會(huì)從堆棧中彈出(pop)該執(zhí)行完成函數(shù);如果有代碼需要進(jìn)去執(zhí)行的話,就進(jìn)行 push 操作。以下圖為例:

圖片

當(dāng)執(zhí)行這段代碼時(shí),首先會(huì)執(zhí)行一個(gè) main 函數(shù),然后執(zhí)行我們的代碼。根據(jù)先進(jìn)后出的原則,后執(zhí)行的函數(shù)會(huì)先彈出棧,在圖中也可以發(fā)現(xiàn),foo 函數(shù)后執(zhí)行,當(dāng)執(zhí)行完畢后就從棧中彈出了。

JavaScript在按順序執(zhí)行執(zhí)行棧中的方法時(shí),每次執(zhí)行一個(gè)方法,都會(huì)為它生成獨(dú)有的執(zhí)行環(huán)境(上下文),當(dāng)這個(gè)方法執(zhí)行完成后,就會(huì)銷毀當(dāng)前的執(zhí)行環(huán)境,并從棧中彈出此方法,然后繼續(xù)執(zhí)行下一個(gè)方法。

任務(wù)隊(duì)列: 從名字中可以看出,任務(wù)隊(duì)列使用到的是數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列結(jié)構(gòu),它用來(lái)保存異步任務(wù),遵循先進(jìn)先出的原則。它主要負(fù)責(zé)將新的任務(wù)發(fā)送到隊(duì)列中進(jìn)行處理。

JavaScript在執(zhí)行代碼時(shí),會(huì)將同步的代碼按照順序排在執(zhí)行棧中,然后依次執(zhí)行里面的函數(shù)。當(dāng)遇到異步任務(wù)時(shí),就將其放入任務(wù)隊(duì)列中,等待當(dāng)前執(zhí)行棧所有同步代碼執(zhí)行完成之后,就會(huì)從異步任務(wù)隊(duì)列中取出已完成的異步任務(wù)的回調(diào)并將其放入執(zhí)行棧中繼續(xù)執(zhí)行,如此循環(huán)往復(fù),直到執(zhí)行完所有任務(wù)。

JavaScript任務(wù)的執(zhí)行順序如下:

圖片

在事件驅(qū)動(dòng)的模式下,至少包含了一個(gè)執(zhí)行循環(huán)來(lái)檢測(cè)任務(wù)隊(duì)列中是否有新任務(wù)。通過(guò)不斷循環(huán),去取出異步任務(wù)的回調(diào)來(lái)執(zhí)行,這個(gè)過(guò)程就是事件循環(huán),每一次循環(huán)就是一個(gè)事件周期。

(2)宏任務(wù)和微任務(wù)

任務(wù)隊(duì)列其實(shí)不止一種,根據(jù)任務(wù)種類的不同,可以分為微任務(wù)(micro task)隊(duì)列宏任務(wù)(macro task)隊(duì)列。常見的任務(wù)如下:

  • 宏任務(wù): script( 整體代碼)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 環(huán)境)。
  • 微任務(wù): Promise、MutaionObserver、process.nextTick(Node.js 環(huán)境)。

任務(wù)隊(duì)列執(zhí)行順序如下:

圖片

可以看到,Eventloop 在處理宏任務(wù)和微任務(wù)的邏輯時(shí)的執(zhí)行情況如下:

  1. JavaScript 引擎首先從宏任務(wù)隊(duì)列中取出第一個(gè)任務(wù);
  2. 執(zhí)行完畢后,再將微任務(wù)中的所有任務(wù)取出,按照順序分別全部執(zhí)行(這里包括不僅指開始執(zhí)行時(shí)隊(duì)列里的微任務(wù)),如果在這一步過(guò)程中產(chǎn)生新的微任務(wù),也需要執(zhí)行,也就是說(shuō)在執(zhí)行微任務(wù)過(guò)程中產(chǎn)生的新的微任務(wù)并不會(huì)推遲到下一個(gè)循環(huán)中執(zhí)行,而是在當(dāng)前的循環(huán)中繼續(xù)執(zhí)行。
  3. 然后再?gòu)暮耆蝿?wù)隊(duì)列中取下一個(gè),執(zhí)行完畢后,再次將 microtask queue 中的全部取出,循環(huán)往復(fù),直到兩個(gè) queue 中的任務(wù)都取完。

也是就是說(shuō),一次 Eventloop 循環(huán)會(huì)處理一個(gè)宏任務(wù)和所有這次循環(huán)中產(chǎn)生的微任務(wù)。

下面通過(guò)一個(gè)例子來(lái)體會(huì)事件循環(huán):

console.log('同步代碼1');

setTimeout(() {
console.log('setTimeout')
}, 0)

new Promise((resolve) => {
console.log('同步代碼2')
resolve()
}).then(() {
console.log('promise.then')
})

console.log('同步代碼3');

代碼輸出結(jié)果如下:

"同步代碼1"
"同步代碼2"
"同步代碼3"
"promise.then"
"setTimeout"

那這段代碼執(zhí)行過(guò)程是怎么的呢?

  1. 遇到第一個(gè)console,它是同步代碼,加入執(zhí)行棧,執(zhí)行并出棧,打印出"同步代碼1"。
  2. 遇到setTimeout,它是一個(gè)宏任務(wù),加入宏任務(wù)隊(duì)列。
  3. 遇到new Promise 中的console,它是同步代碼,加入執(zhí)行棧,執(zhí)行并出棧,打印出"同步代碼2"。
  4. 遇到Promise then,它是一個(gè)微任務(wù),加入微任務(wù)隊(duì)列。
  5. 遇到第三個(gè)console,它是同步代碼,加入執(zhí)行棧,執(zhí)行并出棧,打印出"同步代碼3"。
  6. 此時(shí)執(zhí)行棧為空,去執(zhí)行微任務(wù)隊(duì)列中所有任務(wù),打印出"promise.then"。
  7. 執(zhí)行完微任務(wù)隊(duì)列中的任務(wù),就去執(zhí)行宏任務(wù)隊(duì)列中的一個(gè)任務(wù),打印出"setTimeout"。

從上面的宏任務(wù)和微任務(wù)的工作流程中,可以得出以下結(jié)論:

  • 微任務(wù)和宏任務(wù)是綁定的,每個(gè)宏任務(wù)在執(zhí)行時(shí),會(huì)創(chuàng)建自己的微任務(wù)隊(duì)列。
  • 微任務(wù)的執(zhí)行時(shí)長(zhǎng)會(huì)影響當(dāng)前宏任務(wù)的時(shí)長(zhǎng)。比如一個(gè)宏任務(wù)在執(zhí)行過(guò)程中,產(chǎn)生了 10 個(gè)微任務(wù),執(zhí)行每個(gè)微任務(wù)的時(shí)間是 10ms,那么執(zhí)行這 10 個(gè)微任務(wù)的時(shí)間就是 100ms,也可以說(shuō)這 10 個(gè)微任務(wù)讓宏任務(wù)的執(zhí)行時(shí)間延長(zhǎng)了 100ms。
  • 在一個(gè)宏任務(wù)中,分別創(chuàng)建一個(gè)用于回調(diào)的宏任務(wù)和微任務(wù),無(wú)論什么情況下,微任務(wù)都早于宏任務(wù)執(zhí)行(優(yōu)先級(jí)更高)。

那么問(wèn)題來(lái)了,為什么要將任務(wù)隊(duì)列分為微任務(wù)和宏任務(wù)呢,他們之間的本質(zhì)區(qū)別是什么呢?

JavaScript在遇到異步任務(wù)時(shí),會(huì)將此任務(wù)交給其他線程來(lái)執(zhí)行(比如遇到setTimeout任務(wù),會(huì)交給定時(shí)器觸發(fā)線程去執(zhí)行,待計(jì)時(shí)結(jié)束,就會(huì)將定時(shí)器回調(diào)任務(wù)放入任務(wù)隊(duì)列等待主線程來(lái)取出執(zhí)行),主線程會(huì)繼續(xù)執(zhí)行后面的同步任務(wù)。

對(duì)于微任務(wù),比如promise.then,當(dāng)執(zhí)行promise.then時(shí),瀏覽器引擎不會(huì)將異步任務(wù)交給其他瀏覽器的線程去執(zhí)行,而是將任務(wù)回調(diào)存在一個(gè)隊(duì)列中,當(dāng)執(zhí)行棧中的任務(wù)執(zhí)行完之后,就去執(zhí)行promise.then所在的微任務(wù)隊(duì)列。

所以,宏任務(wù)和微任務(wù)的本質(zhì)區(qū)別如下:

  • 微任務(wù):不需要特定的異步線程去執(zhí)行,沒有明確的異步任務(wù)去執(zhí)行,只有回調(diào)。
  • 宏任務(wù):需要特定的異步線程去執(zhí)行,有明確的異步任務(wù)去執(zhí)行,有回調(diào)。

3、Node.js的事件循環(huán)

(1)事件循環(huán)的概念

對(duì)于Node.js的事件循環(huán),官網(wǎng)的描述如下:

When Node.js starts, it initializes the event loop, processes the provided input script (or drops into the REPL, which is not covered in this document) which may make async API calls, schedule timers, or call process.nextTick(), then begins processing the event loop.

翻譯一下就是:當(dāng)Node.js啟動(dòng)時(shí),它會(huì)初始化一個(gè)事件循環(huán),來(lái)處理輸入的腳本,這個(gè)腳本可能進(jìn)行異步API的調(diào)用、調(diào)度計(jì)時(shí)器或調(diào)用process.nextTick(),然后開始處理事件循環(huán)。

JavaScript和Node.js是基于V8 引擎的,瀏覽器中包含的異步方式在 NodeJS 中也是一樣的。除此之外,Node.js中還有一些其他的異步形式:

  • 文件 I/O:異步加載本地文件。
  • setImmediate():與 setTimeout 設(shè)置 0ms 類似,在某些同步任務(wù)完成后立馬執(zhí)行。
  • process.nextTick():在某些同步任務(wù)完成后立馬執(zhí)行。
  • server.close、socket.on('close',...)等:關(guān)閉回調(diào)。

這些異步任務(wù)的執(zhí)行就需要依靠Node.js的事件循環(huán)機(jī)制了。

Node.js 中的 Event Loop 和瀏覽器中的是完全不相同的東西。Node.js使用V8作為js的解析引擎,而I/O處理方面使用了自己設(shè)計(jì)的libuv,libuv是一個(gè)基于事件驅(qū)動(dòng)的跨平臺(tái)抽象層,封裝了不同操作系統(tǒng)一些底層特性,對(duì)外提供統(tǒng)一的API,事件循環(huán)機(jī)制也是它里面的實(shí)現(xiàn)的,如下圖所示:

圖片

根據(jù)上圖,可以看到Node.js的運(yùn)行機(jī)制如下:

  1. V8引擎負(fù)責(zé)解析JavaScript腳本。
  2. 解析后的代碼,調(diào)用Node API。
  3. libuv庫(kù)負(fù)責(zé)Node API的執(zhí)行。它將不同的任務(wù)分配給不同的線程,形成一個(gè)Event Loop(事件循環(huán)),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給V8引擎。
  4. V8引擎將結(jié)果返回給用戶。

(2)事件循環(huán)的流程

其中l(wèi)ibuv引擎中的事件循環(huán)分為 6 個(gè)階段,它們會(huì)按照順序反復(fù)運(yùn)行。每當(dāng)進(jìn)入某一個(gè)階段的時(shí)候,都會(huì)從對(duì)應(yīng)的回調(diào)隊(duì)列中取出函數(shù)去執(zhí)行。當(dāng)隊(duì)列為空或者執(zhí)行的回調(diào)函數(shù)數(shù)量到達(dá)系統(tǒng)設(shè)定的閾值,就會(huì)進(jìn)入下一階段。下面 是Eventloop 事件循環(huán)的流程:

圖片

整個(gè)流程分為六個(gè)階段,當(dāng)這六個(gè)階段執(zhí)行完一次之后,才可以算得上執(zhí)行了一次 Eventloop 的循環(huán)過(guò)程。下面來(lái)看下這六個(gè)階段都做了哪些事:

  1. timers 階段:執(zhí)行timer(setTimeout、setInterval)的回調(diào),由 poll 階段控制。
  2. I/O callbacks 階段:主要執(zhí)行系統(tǒng)級(jí)別的回調(diào)函數(shù),比如 TCP 連接失敗的回調(diào)。
  3. idle, prepare 階段:僅Node.js內(nèi)部使用,可以忽略。
  4. poll 階段:輪詢等待新的鏈接和請(qǐng)求等事件,執(zhí)行 I/O 回調(diào)等。
  5. check 階段:執(zhí)行 setImmediate() 的回調(diào)。
  6. close callbacks 階段:執(zhí)行關(guān)閉請(qǐng)求的回調(diào)函數(shù),比如socket.on('close', ...)。

注意:上面每個(gè)階段都會(huì)去執(zhí)行完當(dāng)前階段的任務(wù)隊(duì)列,然后繼續(xù)執(zhí)行當(dāng)前階段的微任務(wù)隊(duì)列,只有當(dāng)前階段所有微任務(wù)都執(zhí)行完了,才會(huì)進(jìn)入下個(gè)階段,這里也是與瀏覽器中邏輯差異較大的地方。

其中,這里面比較重要的就是第四階段:poll,這一階段中,系統(tǒng)主要做兩件事:

  • 回到 timer 階段執(zhí)行回調(diào)。
  • 執(zhí)行 I/O 回調(diào)。

在進(jìn)入該階段時(shí)如果沒有設(shè)定了 timer 的話,會(huì)出現(xiàn)以下情況:

(1)如果 poll 隊(duì)列不為空,會(huì)遍歷回調(diào)隊(duì)列并同步執(zhí)行,直到隊(duì)列為空或者達(dá)到系統(tǒng)限制。

(2)如果 poll 隊(duì)列為空時(shí),會(huì)出現(xiàn)以下情況:

  • 如果有 setImmediate 回調(diào)需要執(zhí)行,poll 階段會(huì)停止并且進(jìn)入到 check 階段執(zhí)行回調(diào)。
  • 如果沒有 setImmediate 回調(diào)需要執(zhí)行,會(huì)等待回調(diào)被加入到隊(duì)列中并立即執(zhí)行回調(diào),這里同樣會(huì)有個(gè)超時(shí)時(shí)間設(shè)置防止一直等待下去。

當(dāng)設(shè)定了 timer 且 poll 隊(duì)列為空,則會(huì)判斷是否有 timer 超時(shí),如果有的就會(huì)回到 timer 階段執(zhí)行回調(diào)。

這一過(guò)程的具體執(zhí)行流程如下圖所示:

圖片

(3)宏任務(wù)和微任務(wù)

Node.js事件循環(huán)的異步隊(duì)列也分為兩種:宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列。

  • 常見的宏任務(wù):setTimeout、setInterval、 setImmediate、script(整體代碼)、 I/O 操作等。
  • 常見的微任務(wù):process.nextTick、new Promise().then(回調(diào))等。

(4)process.nextTick()

上面提到了process.nextTick(),它是node中新引入的一個(gè)任務(wù)隊(duì)列,它會(huì)在上述各個(gè)階段結(jié)束時(shí),在進(jìn)入下一個(gè)階段之前立即執(zhí)行。

Node.js官方文檔的解釋如下:

process.nextTick()is not technically part of the event loop. Instead, thenextTickQueuewill be processed after the current operation is completed, regardless of the current phase of the event loop. Here, an operation is defined as a transition from the underlying C/C++ handler, and handling the JavaScript that needs to be executed.

例如下面的代碼:

setTimeout(() {
console.log('timeout');
}, 0);

Promise.resolve().then(() {
console.error('promise')
})

process.nextTick(() {
console.error('nextTick')
})

輸出結(jié)果如下:

nextTick
promise
timeout

可以看到,process.nextTick()是優(yōu)先于promise的回調(diào)執(zhí)行。

(5)setImmediate 和 setTimeout

上面還提到了setImmediate 和 setTimeout,這兩者很相似,主要區(qū)別在于調(diào)用時(shí)機(jī)的不同:

  • setImmediate:在poll階段完成時(shí)執(zhí)行,即check階段。
  • setTimeout:在poll階段為空閑時(shí),且設(shè)定時(shí)間到達(dá)后執(zhí)行,但它在timer階段執(zhí)行。

例如下面的代碼:

setTimeout(() {
console.log('timeout');
}, 0);
setImmediate(() {
console.log('setImmediate');
});

輸出結(jié)果如下:

timeout
setImmediate

在上面代碼的執(zhí)行過(guò)程中,第一輪循環(huán)后,分別將 setTimeout  和 setImmediate 加入了各自階段的任務(wù)隊(duì)列。第二輪循環(huán)首先進(jìn)入timers 階段,執(zhí)行定時(shí)器隊(duì)列回調(diào),然后 pending callbacks和poll 階段沒有任務(wù),因此進(jìn)入check 階段執(zhí)行 setImmediate 回調(diào)。所以最后輸出為timeout、setImmediate。###= 4. Node與瀏覽器事件循環(huán)的差異 Node.js與瀏覽器的事件循環(huán)的差異如下:

  • Node.js:microtask 在事件循環(huán)的各個(gè)階段之間執(zhí)行。
  • 瀏覽器:microtask 在事件循環(huán)的 macrotask 執(zhí)行完之后執(zhí)行。?圖片 ?

Nodejs和瀏覽器的事件循環(huán)流程對(duì)比如下:

  1. 執(zhí)行全局的 Script 代碼(與瀏覽器無(wú)差)。
  2. 把微任務(wù)隊(duì)列清空:注意,Node 清空微任務(wù)隊(duì)列的手法比較特別。在瀏覽器中,我們只有一個(gè)微任務(wù)隊(duì)列需要接受處理;但在 Node 中,有兩類微任務(wù)隊(duì)列:next-tick 隊(duì)列和其它隊(duì)列。其中這個(gè) next-tick 隊(duì)列,專門用來(lái)收斂 process.nextTick 派發(fā)的異步任務(wù)。在清空隊(duì)列時(shí),優(yōu)先清空 next-tick 隊(duì)列中的任務(wù),隨后才會(huì)清空其它微任務(wù)
  3. 開始執(zhí)行 macro-task(宏任務(wù))。注意,Node 執(zhí)行宏任務(wù)的方式與瀏覽器不同:在瀏覽器中,我們每次出隊(duì)并執(zhí)行一個(gè)宏任務(wù);而在 Node 中,我們每次會(huì)嘗試清空當(dāng)前階段對(duì)應(yīng)宏任務(wù)隊(duì)列里的所有任務(wù)(除非達(dá)到系統(tǒng)限制)。
  4. 步驟3開始,會(huì)進(jìn)入 3 -> 2 -> 3 -> 2…的循環(huán)。
責(zé)任編輯:姜華 來(lái)源: 前端充電寶
相關(guān)推薦

2023-06-11 23:59:59

2024-08-27 11:00:56

單例池緩存bean

2019-08-16 09:41:56

UDP協(xié)議TCP

2021-09-30 07:59:06

zookeeper一致性算法CAP

2022-03-29 08:23:56

項(xiàng)目數(shù)據(jù)SIEM

2021-05-07 07:52:51

Java并發(fā)編程

2022-05-27 08:18:00

HashMapHash哈希表

2021-12-13 10:43:45

HashMapJava集合容器

2023-09-25 08:32:03

Redis數(shù)據(jù)結(jié)構(gòu)

2021-09-10 13:06:45

HDFS底層Hadoop

2023-10-04 00:32:01

數(shù)據(jù)結(jié)構(gòu)Redis

2021-07-28 13:29:57

大數(shù)據(jù)PandasCSV

2023-11-07 07:46:02

GatewayKubernetes

2023-12-07 09:07:58

2022-08-18 20:45:30

HTTP協(xié)議數(shù)據(jù)

2017-03-30 22:41:55

虛擬化操作系統(tǒng)軟件

2023-11-22 07:54:33

Xargs命令Linux

2018-09-11 14:47:51

面試Java虛擬機(jī)

2023-11-03 08:53:15

StrconvGolang

2021-10-21 06:52:17

ZooKeeper分布式配置
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)