最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?IO多路復(fù)用之select、poll、epoll示例詳解

 更新時(shí)間:2026年05月11日 09:34:22   作者:程序員懶洋洋  
IO多路復(fù)用是解決高并發(fā)IO的核心技術(shù),select、poll、epoll是Linux系統(tǒng)下三種主流的多路復(fù)用機(jī)制,這篇文章主要介紹了Java IO多路復(fù)用之select、poll、epoll的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考下

一、整體知識(shí)體系:用戶態(tài)、內(nèi)核態(tài)、IO 多路復(fù)用

在理解 select、poll、epoll 之前,先建立一條主線:

用戶態(tài):我們寫的 Java 代碼運(yùn)行的地方
內(nèi)核態(tài):操作系統(tǒng)內(nèi)核運(yùn)行的地方
IO 多路復(fù)用:用戶態(tài)線程通過(guò)系統(tǒng)調(diào)用,讓內(nèi)核幫忙監(jiān)聽(tīng)多個(gè) socket 的 IO 事件

在 Java 后端里,我們寫的代碼,比如 NIO、Netty、業(yè)務(wù)邏輯,都是運(yùn)行在用戶態(tài)。

但是網(wǎng)絡(luò) IO 的底層,比如 TCP 協(xié)議棧、socket 緩沖區(qū)、網(wǎng)卡數(shù)據(jù)接收,這些都由操作系統(tǒng)內(nèi)核管理,也就是在內(nèi)核態(tài)完成。

所以用戶程序不能直接判斷某個(gè) socket 有沒(méi)有數(shù)據(jù),它需要通過(guò)系統(tǒng)調(diào)用進(jìn)入內(nèi)核態(tài),讓內(nèi)核幫它檢查。

一句話總結(jié):

IO 多路復(fù)用就是一個(gè)用戶線程通過(guò) select、poll、epoll 這樣的系統(tǒng)調(diào)用,讓內(nèi)核同時(shí)監(jiān)聽(tīng)多個(gè) fd,哪個(gè) fd 就緒了,用戶線程就處理哪個(gè) fd。

二、fd 是什么?

fd 全稱是:

File Descriptor
文件描述符

它是操作系統(tǒng)給當(dāng)前進(jìn)程打開(kāi)的 IO 資源分配的一個(gè)編號(hào)。

在 Linux 里,很多東西都被抽象成文件,比如:

普通文件
socket 連接
管道
標(biāo)準(zhǔn)輸入
標(biāo)準(zhǔn)輸出
標(biāo)準(zhǔn)錯(cuò)誤

所以這些資源都會(huì)有 fd。

例如:

標(biāo)準(zhǔn)輸入 stdin   -> fd = 0
標(biāo)準(zhǔn)輸出 stdout  -> fd = 1
標(biāo)準(zhǔn)錯(cuò)誤 stderr  -> fd = 2
某個(gè) socket 連接 -> fd = 3
另一個(gè) socket 連接 -> fd = 4
某個(gè)日志文件     -> fd = 5

所以要注意:

fd 不是連接數(shù)量本身,而是操作系統(tǒng)給某個(gè) IO 資源分配的編號(hào)。

但是在網(wǎng)絡(luò)編程里,一個(gè) socket 通常對(duì)應(yīng)一個(gè) fd,所以很多時(shí)候我們說(shuō)“監(jiān)聽(tīng)多個(gè) fd”,本質(zhì)上就是監(jiān)聽(tīng)多個(gè) socket 連接。

三、fd 和 socket 連接的關(guān)系

在服務(wù)端網(wǎng)絡(luò)編程里,一般有兩類 socket。

1. 監(jiān)聽(tīng) socket

服務(wù)端啟動(dòng)時(shí),會(huì)創(chuàng)建一個(gè)監(jiān)聽(tīng)端口的 socket。

比如服務(wù)端監(jiān)聽(tīng) 8080 端口:

ServerSocketChannel 監(jiān)聽(tīng) 8080
listenFd = 3

這個(gè) listenFd 是監(jiān)聽(tīng) socket 的 fd。

它的作用是接收新的客戶端連接,不代表某一個(gè)具體客戶端連接。

2. 已連接 socket

當(dāng)客戶端連接進(jìn)來(lái)之后,服務(wù)端通過(guò) accept() 得到一個(gè)新的 socket。

例如:

客戶端 A 連接進(jìn)來(lái) -> connFd = 4
客戶端 B 連接進(jìn)來(lái) -> connFd = 5
客戶端 C 連接進(jìn)來(lái) -> connFd = 6

這些 fd 才分別對(duì)應(yīng)一個(gè)個(gè)客戶端連接。

所以服務(wù)端中可能是這樣的:

fd = 3:監(jiān)聽(tīng) socket,負(fù)責(zé)接收新連接
fd = 4:客戶端 A 的連接 socket
fd = 5:客戶端 B 的連接 socket
fd = 6:客戶端 C 的連接 socket

面試時(shí)可以這樣說(shuō):

fd 是操作系統(tǒng)層面對(duì) IO 資源的編號(hào)。一個(gè) socket 通常對(duì)應(yīng)一個(gè) fd;在服務(wù)端中,監(jiān)聽(tīng) socket 有一個(gè)監(jiān)聽(tīng) fd,每 accept 一個(gè)客戶端連接,內(nèi)核會(huì)為這個(gè)已連接 socket 分配一個(gè)新的 fd。

四、IO 多路復(fù)用監(jiān)聽(tīng)的到底是什么?

嚴(yán)格來(lái)說(shuō),IO 多路復(fù)用監(jiān)聽(tīng)的是:

多個(gè) fd 上的 IO 就緒事件

它不是直接監(jiān)聽(tīng)“連接個(gè)數(shù)”。

但是在網(wǎng)絡(luò)編程場(chǎng)景中,大多數(shù) fd 都是 socket fd,所以可以近似理解為:

監(jiān)聽(tīng)多個(gè) fd
≈ 監(jiān)聽(tīng)多個(gè) socket
≈ 監(jiān)聽(tīng)多個(gè)客戶端連接

更嚴(yán)謹(jǐn)?shù)谋磉_(dá)是:

IO 多路復(fù)用監(jiān)聽(tīng)的是多個(gè)文件描述符 fd 的 IO 就緒事件。在網(wǎng)絡(luò)編程里,一個(gè)已連接 socket 通常對(duì)應(yīng)一個(gè) fd,所以監(jiān)聽(tīng)多個(gè) fd 就相當(dāng)于監(jiān)聽(tīng)多個(gè) socket 連接。

五、BIO 和 IO 多路復(fù)用的區(qū)別

假設(shè)服務(wù)端有三個(gè)客戶端連接:

客戶端 A -> fd = 4
客戶端 B -> fd = 5
客戶端 C -> fd = 6

1. BIO 的處理方式

BIO 通常是:

一個(gè)連接對(duì)應(yīng)一個(gè)線程

例如:

線程 1 阻塞等待 fd=4 的數(shù)據(jù)
線程 2 阻塞等待 fd=5 的數(shù)據(jù)
線程 3 阻塞等待 fd=6 的數(shù)據(jù)

如果連接數(shù)很多,線程數(shù)量就會(huì)爆炸。

這會(huì)帶來(lái)幾個(gè)問(wèn)題:

線程占用內(nèi)存
線程上下文切換成本高
大量線程阻塞在 IO 上
CPU 利用率不高
并發(fā)擴(kuò)展能力差

2. IO 多路復(fù)用的處理方式

IO 多路復(fù)用是一個(gè)線程調(diào)用 select、poll 或 epoll,把多個(gè) fd 交給內(nèi)核監(jiān)聽(tīng):

一個(gè)線程監(jiān)聽(tīng) fd=4、fd=5、fd=6

內(nèi)核負(fù)責(zé)檢查:

fd=4 有沒(méi)有數(shù)據(jù)?
fd=5 有沒(méi)有數(shù)據(jù)?
fd=6 有沒(méi)有數(shù)據(jù)?

如果某一刻:

fd=5 有數(shù)據(jù)可讀
fd=6 有數(shù)據(jù)可讀

內(nèi)核就通知用戶態(tài)線程:

fd=5 就緒了
fd=6 就緒了

然后用戶態(tài)線程再去處理對(duì)應(yīng)連接的數(shù)據(jù)。

核心區(qū)別是:

BIO 是一個(gè)線程阻塞在一個(gè) socket 上;IO 多路復(fù)用是一個(gè)線程阻塞在多路復(fù)用器上,讓內(nèi)核幫它監(jiān)聽(tīng)多個(gè) socket。

六、select 的工作原理

select 是比較早期的 IO 多路復(fù)用機(jī)制。

它的核心流程是:

1. 用戶態(tài)應(yīng)用程序準(zhǔn)備一批 fd 集合
2. 通過(guò) select 系統(tǒng)調(diào)用把 fd 集合傳給內(nèi)核
3. 內(nèi)核遍歷 fd 集合,檢查哪些 fd 就緒
4. 內(nèi)核把結(jié)果寫回用戶傳入的數(shù)據(jù)結(jié)構(gòu)
5. select 返回用戶態(tài)
6. 用戶態(tài)程序再次遍歷 fd 集合,找出真正就緒的 fd
7. 處理對(duì)應(yīng)連接

例如用戶態(tài)有這些 fd:

fd = 3
fd = 4
fd = 5
fd = 6
fd = 7

應(yīng)用程序調(diào)用 select 后,內(nèi)核遍歷這些 fd,發(fā)現(xiàn):

fd = 4 可讀
fd = 7 可讀

select 返回后,用戶態(tài)程序還要自己再遍歷一遍 fd 集合,才能知道到底是 fd=4 和 fd=7 就緒了。

select 的缺點(diǎn)

1. fd 數(shù)量有限制

select 使用 fd_set 保存 fd 集合,常見(jiàn)限制是 1024。

也就是說(shuō),一個(gè) select 能監(jiān)聽(tīng)的 fd 數(shù)量通常有限。

2. 每次調(diào)用都要重復(fù)傳遞 fd 集合

每次調(diào)用 select,都要把 fd 集合從用戶態(tài)拷貝到內(nèi)核態(tài)。

連接數(shù)量越多,這個(gè)拷貝成本越高。

3. 內(nèi)核和用戶態(tài)都要遍歷所有 fd

即使只有一個(gè) fd 就緒,內(nèi)核也要遍歷所有 fd。

返回用戶態(tài)后,用戶程序還要再遍歷所有 fd。

所以時(shí)間復(fù)雜度是:

O(n)

一句話總結(jié):

select 有 fd 數(shù)量限制,每次調(diào)用都要傳入全部 fd,內(nèi)核和用戶態(tài)都要遍歷全部 fd。

七、poll 的工作原理

poll 的整體思想和 select 很像,也是:

用戶態(tài)把一批 fd 交給內(nèi)核
內(nèi)核檢查哪些 fd 就緒
返回后用戶態(tài)再遍歷

不同點(diǎn)是:

poll 不再使用固定大小的 fd_set,而是使用 pollfd 數(shù)組,因此解決了 select 的 fd 數(shù)量限制問(wèn)題。

pollfd 可以簡(jiǎn)單理解為:

fd:要監(jiān)聽(tīng)哪個(gè)連接
events:關(guān)心什么事件,比如可讀、可寫
revents:內(nèi)核返回實(shí)際發(fā)生了什么事件

poll 的流程是:

1. 用戶態(tài)準(zhǔn)備 pollfd 數(shù)組
2. 調(diào)用 poll 進(jìn)入內(nèi)核態(tài)
3. 內(nèi)核遍歷 pollfd 數(shù)組,檢查每個(gè) fd 是否就緒
4. 內(nèi)核把結(jié)果寫到 revents 字段
5. poll 返回用戶態(tài)
6. 用戶態(tài)遍歷 pollfd 數(shù)組,找出 revents 有事件的 fd

poll 的優(yōu)點(diǎn)

相比 select,poll 的主要優(yōu)點(diǎn)是:

解決了 fd 數(shù)量限制問(wèn)題

poll 的缺點(diǎn)

但是 poll 沒(méi)有解決核心性能問(wèn)題:

每次調(diào)用仍然要傳遞全部 fd
內(nèi)核仍然要遍歷全部 fd
返回用戶態(tài)后仍然要遍歷全部 fd

所以 poll 的時(shí)間復(fù)雜度仍然是:

O(n)

一句話總結(jié):

poll 解決了 select 的 fd 數(shù)量限制,但沒(méi)有解決全量傳遞和全量遍歷的問(wèn)題。

八、epoll 的工作原理

epoll 是 Linux 對(duì) IO 多路復(fù)用的優(yōu)化,更適合高并發(fā)場(chǎng)景。

它和 selectpoll 最大的區(qū)別是:

select/poll 是每次調(diào)用都把全部 fd 傳給內(nèi)核;epoll 是先把 fd 注冊(cè)到內(nèi)核,后續(xù)只等待就緒事件。

epoll 的三個(gè)核心系統(tǒng)調(diào)用

epoll_create:創(chuàng)建 epoll 實(shí)例
epoll_ctl:添加、修改、刪除要監(jiān)聽(tīng)的 fd
epoll_wait:等待就緒事件

epoll 的流程

1. 用戶態(tài)調(diào)用 epoll_create 創(chuàng)建 epoll 對(duì)象
2. 用戶態(tài)調(diào)用 epoll_ctl 把 socket fd 注冊(cè)到內(nèi)核
3. 內(nèi)核維護(hù)這些 fd 的監(jiān)聽(tīng)關(guān)系
4. 當(dāng)某個(gè) fd 就緒時(shí),內(nèi)核把它放入就緒隊(duì)列
5. 用戶態(tài)調(diào)用 epoll_wait 等待事件
6. epoll_wait 返回的就是已經(jīng)就緒的 fd
7. 用戶態(tài)程序直接處理這些就緒 fd

假設(shè)服務(wù)端維護(hù) 10000 個(gè)連接,但只有 10 個(gè)連接有數(shù)據(jù)。

select/poll 的做法是:

遍歷 10000 個(gè) fd,找到 10 個(gè)就緒 fd

epoll 的做法是:

內(nèi)核把 10 個(gè)就緒 fd 放入就緒隊(duì)列
epoll_wait 直接返回這 10 個(gè) fd

所以 epoll 更適合:

大量連接
少量活躍
高并發(fā)網(wǎng)絡(luò)服務(wù)

九、epoll 為什么性能更好?

epoll 性能更好的原因主要有三個(gè)。

1. 不需要每次重復(fù)傳遞全部 fd

select/poll 每次調(diào)用都要把 fd 集合從用戶態(tài)傳給內(nèi)核。

epoll 是先通過(guò) epoll_ctl 注冊(cè) fd,之后由內(nèi)核自己維護(hù)這些 fd。

所以后續(xù) epoll_wait 不需要每次重復(fù)傳遞全部 fd。

2. 不需要遍歷全部 fd 找就緒事件

select/poll 返回后,用戶態(tài)程序還要遍歷所有 fd,找出真正就緒的連接。

epoll 中,內(nèi)核會(huì)把已經(jīng)就緒的 fd 放到就緒隊(duì)列里。

所以 epoll_wait 返回的就是就緒 fd。

3. 監(jiān)聽(tīng)集合和就緒集合分離

epoll 內(nèi)部可以簡(jiǎn)單理解為:

紅黑樹:管理所有注冊(cè)的 fd
就緒鏈表:保存已經(jīng)就緒的 fd

紅黑樹用于管理監(jiān)聽(tīng)集合。

就緒鏈表用于保存已經(jīng)發(fā)生事件的 fd。

這就是 epoll 的核心優(yōu)勢(shì):

監(jiān)聽(tīng)集合和就緒集合分離。

十、select、poll、epoll 核心區(qū)別對(duì)比

對(duì)比項(xiàng)selectpollepoll
監(jiān)聽(tīng) fd 數(shù)量有限制,常見(jiàn) 1024理論上無(wú)固定限制理論上無(wú)固定限制
數(shù)據(jù)結(jié)構(gòu)fd_set / bitmappollfd 數(shù)組紅黑樹 + 就緒鏈表
是否每次傳全部 fd否,先注冊(cè)后等待
內(nèi)核是否遍歷全部 fd不需要全量遍歷就緒結(jié)果
用戶態(tài)是否遍歷全部 fd只遍歷就緒事件
時(shí)間復(fù)雜度O(n)O(n)和就緒 fd 數(shù)量更相關(guān)
適合場(chǎng)景少量連接中等連接高并發(fā)、大量連接、少量活躍

最關(guān)鍵的區(qū)別:

select 有 fd 數(shù)量限制,并且每次都要全量傳遞、全量遍歷;poll 解決了 fd 數(shù)量限制,但仍然要全量傳遞、全量遍歷;epoll 通過(guò)事件驅(qū)動(dòng)和就緒隊(duì)列,只返回真正就緒的 fd,更適合高并發(fā)場(chǎng)景。

十一、epoll 的 LT 和 ET 模式

epoll 有兩種觸發(fā)模式:

LT:Level Trigger,水平觸發(fā)
ET:Edge Trigger,邊緣觸發(fā)

1. LT 水平觸發(fā)

LT 是默認(rèn)模式。

特點(diǎn)是:

只要 fd 中還有數(shù)據(jù)沒(méi)讀完,epoll_wait 就會(huì)一直通知你。

例如 socket 緩沖區(qū)里有 100 字節(jié)數(shù)據(jù),這次只讀了 50 字節(jié),那么下次 epoll_wait 還會(huì)繼續(xù)通知這個(gè) fd 可讀。

優(yōu)點(diǎn):

編程簡(jiǎn)單
不容易漏事件

缺點(diǎn):

可能重復(fù)通知
效率相對(duì)低一些

2. ET 邊緣觸發(fā)

ET 模式是:

只有 fd 狀態(tài)發(fā)生變化時(shí)才通知一次。

比如從“沒(méi)有數(shù)據(jù)”變成“有數(shù)據(jù)”時(shí)通知一次。

如果這次沒(méi)有把數(shù)據(jù)讀完,后續(xù)不一定繼續(xù)通知。

所以 ET 模式通常要求:

必須配合非阻塞 IO,并且一次性循環(huán)讀到 EAGAIN 為止。

優(yōu)點(diǎn):

通知次數(shù)少
效率更高

缺點(diǎn):

編程復(fù)雜
容易漏讀數(shù)據(jù)

面試表達(dá):

LT 模式下,只要數(shù)據(jù)沒(méi)讀完,epoll 會(huì)反復(fù)通知;ET 模式下,只在狀態(tài)變化時(shí)通知一次,所以必須循環(huán)讀到 EAGAIN,否則可能漏事件。ET 性能更高,但編碼要求也更高。

十二、用戶態(tài)和內(nèi)核態(tài)在 select/poll/epoll 中如何配合

select/poll 的用戶態(tài)和內(nèi)核態(tài)流程

用戶態(tài)應(yīng)用程序準(zhǔn)備 fd 集合
        ↓
通過(guò) select/poll 系統(tǒng)調(diào)用進(jìn)入內(nèi)核態(tài)
        ↓
內(nèi)核遍歷全部 fd,檢查哪些 fd 就緒
        ↓
內(nèi)核把結(jié)果寫回用戶傳入的數(shù)據(jù)結(jié)構(gòu)
        ↓
系統(tǒng)調(diào)用返回用戶態(tài)
        ↓
用戶態(tài)程序再次遍歷全部 fd,找出真正就緒的 fd

所以 select/poll 的問(wèn)題是:

內(nèi)核遍歷一遍,用戶態(tài)返回后還要再遍歷一遍。

epoll 的用戶態(tài)和內(nèi)核態(tài)流程

用戶態(tài)通過(guò) epoll_create 創(chuàng)建 epoll 實(shí)例
        ↓
用戶態(tài)通過(guò) epoll_ctl 把 fd 注冊(cè)到內(nèi)核
        ↓
內(nèi)核維護(hù)監(jiān)聽(tīng)集合和就緒隊(duì)列
        ↓
用戶態(tài)調(diào)用 epoll_wait 等待事件
        ↓
某些 fd 就緒后,內(nèi)核把它們放入就緒隊(duì)列
        ↓
epoll_wait 返回用戶態(tài)
        ↓
用戶態(tài)只處理返回的就緒 fd

所以 epoll 的優(yōu)勢(shì)是:

fd 只需要注冊(cè)一次,后續(xù) epoll_wait 只返回就緒 fd,減少了重復(fù)拷貝和無(wú)意義遍歷。

十三、和 Java NIO 的關(guān)系

Java NIO 中的 Selector 本質(zhì)上是對(duì)操作系統(tǒng) IO 多路復(fù)用能力的封裝。

Java 代碼里可能這樣寫:

Selector selector = Selector.open();

while (true) {
    selector.select();

    Set<SelectionKey> keys = selector.selectedKeys();

    for (SelectionKey key : keys) {
        if (key.isReadable()) {
            // 處理讀事件
        }
    }
}

這里的:

selector.select();

底層會(huì)通過(guò) JVM native 方法調(diào)用操作系統(tǒng)的多路復(fù)用機(jī)制。

在 Linux 下,通常底層就是 epoll。

對(duì)應(yīng)關(guān)系可以這樣理解:

Java 層:SocketChannel / ServerSocketChannel
        ↓
JVM native 層:調(diào)用操作系統(tǒng) socket API
        ↓
操作系統(tǒng)層:socket fd
        ↓
Selector 底層:select / poll / epoll

所以:

SocketChannel 是 Java 對(duì) socket fd 的封裝;Selector 是 Java 層的多路復(fù)用器;epoll/select/poll 是操作系統(tǒng)層的多路復(fù)用機(jī)制。

十四、完整理解鏈路

可以把 IO 多路復(fù)用理解成下面這條鏈路:

客戶端連接
   ↓
服務(wù)端 accept 得到 socket
   ↓
操作系統(tǒng)給這個(gè) socket 分配 fd
   ↓
Java 的 SocketChannel 封裝這個(gè) fd
   ↓
把 Channel 注冊(cè)到 Selector
   ↓
Selector 底層把 fd 注冊(cè)給 epoll/select/poll
   ↓
內(nèi)核監(jiān)聽(tīng)這些 fd 的 IO 狀態(tài)
   ↓
fd 可讀/可寫時(shí),內(nèi)核通知用戶態(tài)
   ↓
Java 線程處理對(duì)應(yīng) Channel 的讀寫事件

關(guān)鍵對(duì)應(yīng)關(guān)系:

fd:操作系統(tǒng)層面的資源編號(hào)
Channel:Java 層面對(duì) fd 的封裝
Selector:Java 層的多路復(fù)用器
epoll/select/poll:操作系統(tǒng)層的多路復(fù)用機(jī)制

總結(jié)

到此這篇關(guān)于Java IO多路復(fù)用之select、poll、epoll的文章就介紹到這了,更多相關(guān)IO多路復(fù)用select、poll、epoll內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java并發(fā)編程實(shí)例分析

    java并發(fā)編程實(shí)例分析

    在本文里我們給大家分享了關(guān)于java并發(fā)編程實(shí)例分析以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-03-03
  • Spring Boot 集成 MyBatis 全攻略(最新整理)

    Spring Boot 集成 MyBatis 全攻略(最新整理)

    本文詳解SpringBoot集成MyBatis的流程,涵蓋依賴配置、數(shù)據(jù)源設(shè)置、實(shí)體類與Mapper編寫(注解/XML)、Service/Controller開(kāi)發(fā)及分頁(yè)、緩存、動(dòng)態(tài)SQL等優(yōu)化,助力建設(shè)高效全棧應(yīng)用,感興趣的朋友跟隨小編一起看看吧
    2025-08-08
  • 解決Eclipse/STS中出現(xiàn)Resource is out of sync with the file system的異常問(wèn)題

    解決Eclipse/STS中出現(xiàn)Resource is out of sync with the file system

    今天小編就為大家分享一篇關(guān)于解決Eclipse/STS中出現(xiàn)Resource is out of sync with the file system的異常問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • java 取模與取余的區(qū)別說(shuō)明

    java 取模與取余的區(qū)別說(shuō)明

    這篇文章主要介紹了java 取模與取余的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • Kotlin教程之函數(shù)和包的定義和流程控制

    Kotlin教程之函數(shù)和包的定義和流程控制

    這篇文章主要介紹了Kotlin教程之函數(shù)和包的定義和流程控制的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java爬蟲爬取漫畫示例

    Java爬蟲爬取漫畫示例

    這篇文章主要介紹了Java爬蟲爬取漫畫示例,大部分的爬蟲入門教學(xué)都是爬取圖片的,本文就來(lái)測(cè)試一下爬取網(wǎng)站的漫畫,需要的朋友可以參考下
    2023-04-04
  • Java8中Stream流求最大值最小值的實(shí)現(xiàn)示例

    Java8中Stream流求最大值最小值的實(shí)現(xiàn)示例

    本文主要介紹了Java8中Stream流求最大值最小值的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • IDEA的run maven方式啟動(dòng)步驟詳解

    IDEA的run maven方式啟動(dòng)步驟詳解

    這篇文章主要介紹了IDEA的run maven方式啟動(dòng)步驟,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • mybatis水平分表實(shí)現(xiàn)動(dòng)態(tài)表名的項(xiàng)目實(shí)例

    mybatis水平分表實(shí)現(xiàn)動(dòng)態(tài)表名的項(xiàng)目實(shí)例

    本文主要介紹了mybatis水平分表實(shí)現(xiàn)動(dòng)態(tài)表名的項(xiàng)目實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java中的接口多繼承機(jī)制

    Java中的接口多繼承機(jī)制

    大家好,本篇文章主要講的是Java中的接口多繼承機(jī)制,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02

最新評(píng)論

建阳市| 新建县| 历史| 从化市| 大方县| 屯留县| 麻城市| 三台县| 湛江市| 漳州市| 孝感市| 友谊县| 新营市| 宜宾县| 信阳市| 都昌县| 邮箱| 靖西县| 庄浪县| 麦盖提县| 勐海县| 永兴县| 手机| 赤水市| 长宁区| 抚顺市| 贵港市| 积石山| 余干县| 泸西县| 历史| 诸暨市| 台山市| 绥德县| 馆陶县| 那坡县| 罗平县| 台中县| 盘锦市| 凤台县| 泰宁县|