【Java基礎】Java I/O模型解析:BIO、NIO、AIO的區別與聯系(Netty入門必備基礎)

Java I/O模型深度解析:BIO、NIO、AIO的區別與聯系

引言

在Java的網絡編程與文件操作中,I/O(輸入/輸出)模型是繞不開的核心話題。從早期的BIO(Blocking I/O)到Java 1.4引入的NIO(Non-blocking I/O),再到Java 7推出的AIO(Asynchronous I/O),Java的I/O體系經歷了三次重大演進。

這三種模型分別對應“同步阻塞”“同步非阻塞”“異步非阻塞”三種不同的I/O處理范式,各自適用于不同的業務場景。


一、I/O基礎:從操作系統到Java的抽象

1.1 I/O的本質與操作系統角色

I/O操作的本質是程序與外部設備(如磁盤、網絡)之間的數據傳輸。由于外部設備的速度遠慢于CPU,直接由CPU等待I/O完成會導致資源浪費。因此,操作系統通過內核緩沖區系統調用來優化I/O流程:程序發起I/O請求后,內核將數據從設備讀入內核緩沖區(讀操作)或從內核緩沖區寫入設備(寫操作),程序只需與內核緩沖區交互。

1.2 同步與異步、阻塞與非阻塞

理解BIO、NIO、AIO的關鍵在于區分兩組概念:

  • 同步(Synchronous)vs 異步(Asynchronous):描述“任務完成通知方式”。同步指程序主動查詢I/O是否完成;異步指內核在I/O完成后通過事件或回調通知程序。
  • 阻塞(Blocking)vs 非阻塞(Non-blocking):描述“線程在I/O操作期間的狀態”。阻塞指線程因等待I/O而掛起;非阻塞指線程在I/O未完成時立即返回,繼續執行其他任務。

1.3 Java I/O的演進邏輯

BIO是最原始的模型,簡單但低效;NIO通過“多路復用”解決了BIO的線程資源浪費問題;AIO則通過“異步回調”進一步釋放了線程在I/O等待期間的計算能力。三者的演進本質是用更高效的方式協調CPU與I/O設備的速度差異


二、BIO:同步阻塞I/O——最原始的“一對一”模型

2.1 BIO的核心特征

BIO(Blocking I/O)是Java最早的I/O模型(JDK 1.0引入),其核心特征是同步阻塞:當程序執行I/O操作(如read()write())時,線程會被阻塞,直到I/O完成。對于網絡編程,BIO的典型場景是“一個客戶端連接對應一個服務端線程”。

2.2 基礎代碼示例:傳統Socket服務器

以TCP服務端為例,BIO的實現邏輯如下:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class BioServer {public static void main(String[] args) throws IOException {// 1. 創建服務端Socket,綁定8080端口ServerSocket serverSocket = new ServerSocket(8080);System.out.println("BIO服務器啟動,監聽端口8080...");// 2. 使用線程池處理客戶端連接(避免頻繁創建線程)ExecutorService threadPool = Executors.newFixedThreadPool(10);while (true) {// 3. 阻塞等待客戶端連接(accept()方法阻塞)Socket clientSocket = serverSocket.accept(); System.out.println("客戶端[" + clientSocket.getInetAddress() + "]連接成功");// 4. 為每個客戶端分配一個線程處理請求threadPool.execute(() -> {try (InputStream inputStream = clientSocket.getInputStream()) {byte[] buffer = new byte[1024];int len;// 5. 阻塞讀取客戶端數據(read()方法阻塞)while ((len = inputStream.read(buffer)) != -1) { String message = new String(buffer, 0, len);System.out.println("收到客戶端消息:" + message);}} catch (IOException e) {e.printStackTrace();} finally {try {clientSocket.close();} catch (IOException e) {e.printStackTrace();}}});}}
}

2.3 關鍵操作與阻塞點分析

  • ServerSocket.accept():阻塞等待客戶端連接。若沒有客戶端連接,線程一直掛起。
  • InputStream.read():阻塞讀取客戶端數據。若客戶端未發送數據,線程一直等待。
  • 線程模型:每個客戶端連接需要獨立線程處理,線程數與連接數1:1。

2.4 優缺點與適用場景

  • 優點:邏輯簡單,易于理解和調試;適合處理短連接、低并發場景(如小型工具類服務)。
  • 缺點:線程資源浪費嚴重(連接數大時線程數爆炸);線程阻塞期間無法執行其他任務,CPU利用率低。
  • 適用場景:連接數少且固定的場景(如數據庫直連、內部系統間的短連接通信)。

三、NIO:同步非阻塞I/O——用“多路復用”打破線程限制

3.1 NIO的核心組件

NIO(Non-blocking I/O,JDK 1.4引入)通過通道(Channel)、**緩沖區(Buffer)選擇器(Selector)**三大核心組件實現非阻塞I/O。其核心思想是“一個線程管理多個連接”,通過Selector輪詢多個Channel的I/O就緒狀態,避免為每個連接分配獨立線程。

3.1.1 通道(Channel)

Channel是數據傳輸的雙向通道,類似BIO中的InputStream/OutputStream,但支持非阻塞操作。常見實現類:

  • FileChannel(文件I/O)
  • SocketChannel(TCP客戶端)
  • ServerSocketChannel(TCP服務端)
  • DatagramChannel(UDP通信)
3.1.2 緩沖區(Buffer)

Buffer是NIO的“數據容器”,所有數據操作必須通過Buffer完成。Buffer是一個固定大小的內存塊,支持讀/寫模式切換(通過flip()方法)。常見實現類:ByteBuffer(最常用)、IntBufferCharBuffer等。

3.1.3 選擇器(Selector)

Selector是NIO的“事件引擎”,通過select()方法輪詢注冊在其上的Channel,檢測哪些Channel處于可讀、可寫或連接就緒狀態。一個Selector可以管理成千上萬個Channel,實現“單線程處理多連接”。

3.2 基礎代碼示例:NIO Socket服務器

以TCP服務端為例,NIO的實現邏輯如下:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;public class NioServer {public static void main(String[] args) throws IOException {// 1. 創建ServerSocketChannel并綁定端口ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.bind(new InetSocketAddress(8080));serverChannel.configureBlocking(false); // 關鍵:設置為非阻塞模式// 2. 創建Selector并注冊Accept事件Selector selector = Selector.open();serverChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("NIO服務器啟動,監聽端口8080...");while (true) {// 3. 阻塞等待就緒事件(超時時間可設,0表示永久阻塞)int readyChannels = selector.select(); if (readyChannels == 0) continue;// 4. 處理所有就緒事件Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> keyIterator = selectedKeys.iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();keyIterator.remove(); // 必須手動移除,避免重復處理// 5. 處理Accept事件(新客戶端連接)if (key.isAcceptable()) {ServerSocketChannel ssc = (ServerSocketChannel) key.channel();SocketChannel clientChannel = ssc.accept(); // 非阻塞,可能返回nullif (clientChannel != null) {clientChannel.configureBlocking(false); // 注冊Read事件到Selector,使用1024字節的BufferclientChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));System.out.println("客戶端[" + clientChannel.getRemoteAddress() + "]連接成功");}}// 6. 處理Read事件(客戶端數據可讀)else if (key.isReadable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = (ByteBuffer) key.attachment(); // 獲取綁定的Buffertry {int len = clientChannel.read(buffer); if (len > 0) {buffer.flip(); // 切換為讀模式String message = new String(buffer.array(), 0, buffer.limit());System.out.println("收到客戶端消息:" + message);buffer.clear(); // 清空Buffer,準備下次寫入} else if (len == -1) {// 客戶端關閉連接clientChannel.close();System.out.println("客戶端斷開連接");}} catch (IOException e) {clientChannel.close();System.out.println("客戶端異常斷開");}}}}}
}

3.3 關鍵操作與非阻塞原理

  • configureBlocking(false):將Channel設置為非阻塞模式。此時accept()read()等方法不會阻塞,若I/O未就緒則立即返回(如read()返回0或-1)。
  • Selector的輪詢機制:通過selector.select()阻塞等待至少一個Channel就緒(可設置超時時間),避免無意義的空循環。
  • 事件驅動:僅處理就緒的事件(如OP_ACCEPT、OP_READ),線程無需為未就緒的連接浪費資源。

3.4 與BIO的核心差異

維度BIONIO
線程模型1連接1線程(線程池優化)1線程管理N連接(事件驅動)
阻塞點accept()read()全程阻塞selector.select()阻塞
資源消耗高(線程數隨連接數線性增長)低(線程數與連接數解耦)
編程復雜度低(邏輯簡單)高(需處理Buffer、事件輪詢)

3.5 適用場景與注意事項

  • 適用場景:高并發、短連接場景(如HTTP服務器、即時通訊);需注意Selector的輪詢效率(避免空輪詢導致CPU100%)。
  • Buffer的使用技巧:優先使用DirectByteBuffer(堆外內存)減少內存拷貝;根據業務場景調整Buffer大小(過小導致頻繁讀寫,過大浪費內存)。

四、AIO:異步非阻塞I/O——真正的“回調驅動”模型

4.1 AIO的核心思想

AIO(Asynchronous I/O,JDK 7引入,又稱NIO.2)是Java中唯一的異步非阻塞I/O模型。其核心思想是:程序發起I/O操作后立即返回,內核在I/O完成后通過回調函數Future對象通知程序。線程無需等待I/O完成,可繼續執行其他任務,真正實現了“I/O與計算并行”。

4.2 核心組件與異步機制

  • AsynchronousChannel:異步通道接口,實現類包括AsynchronousServerSocketChannel(服務端)、AsynchronousSocketChannel(客戶端)。
  • CompletionHandler:回調接口,定義completed()(I/O成功)和failed()(I/O失敗)方法。
  • Future:表示異步操作的結果,可通過get()方法阻塞等待結果(但會退化為同步)。

4.3 基礎代碼示例:AIO Socket服務器

以TCP服務端為例,AIO的實現邏輯如下:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;public class AioServer {public static void main(String[] args) throws IOException {// 1. 創建異步服務端Channel并綁定端口AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080));System.out.println("AIO服務器啟動,監聽端口8080...");// 2. 注冊Accept回調(匿名內部類實現CompletionHandler)serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {@Overridepublic void completed(AsynchronousSocketChannel clientChannel, Void attachment) {// 3. 接受新連接后,遞歸調用accept()以繼續監聽其他連接serverChannel.accept(null, this); try {System.out.println("客戶端[" + clientChannel.getRemoteAddress() + "]連接成功");ByteBuffer buffer = ByteBuffer.allocate(1024);// 4. 注冊Read回調(異步讀取客戶端數據)clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer len, ByteBuffer buffer) {if (len > 0) {buffer.flip();String message = new String(buffer.array(), 0, buffer.limit());System.out.println("收到客戶端消息:" + message);buffer.clear();// 繼續異步讀取(遞歸調用read())clientChannel.read(buffer, buffer, this);} else if (len == -1) {try {clientChannel.close();System.out.println("客戶端斷開連接");} catch (IOException e) {e.printStackTrace();}}}@Overridepublic void failed(Throwable exc, ByteBuffer buffer) {try {clientChannel.close();System.out.println("客戶端異常斷開:" + exc.getMessage());} catch (IOException e) {e.printStackTrace();}}});} catch (IOException e) {e.printStackTrace();}}@Overridepublic void failed(Throwable exc, Void attachment) {System.out.println("Accept失敗:" + exc.getMessage());}});// 保持主線程不退出(實際生產環境需更優雅的退出機制)try {Thread.sleep(Long.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}
}

4.4 異步操作的底層實現

AIO的異步特性依賴于操作系統的異步I/O支持(如Linux的aio、Windows的IOCP)。Java通過本地方法(JNI)調用系統API,內核完成I/O后觸發回調。與NIO的“輪詢”不同,AIO的“通知”是真正的異步。

4.5 與NIO的核心差異

維度NIO(同步非阻塞)AIO(異步非阻塞)
阻塞模型線程需主動輪詢I/O狀態內核主動通知I/O完成
線程行為線程在select()時阻塞線程完全不阻塞(僅回調執行)
編程范式事件驅動(輪詢+事件處理)回調驅動(內核觸發回調)
適用場景高并發短連接(如HTTP)高并發長連接(如文件傳輸)

4.6 適用場景與注意事項

  • 適用場景:I/O操作耗時較長的場景(如大文件傳輸、數據庫批量操作);需要充分利用CPU資源的高并發場景。
  • 回調地獄問題:多層嵌套的回調可能導致代碼可讀性下降(可通過CompletableFuture優化);需注意回調函數的線程安全(避免共享變量沖突)。

五、三者對比:從阻塞到異步的演進邏輯

5.1 核心指標對比表

為更直觀地理解三者差異,我們從關鍵維度進行橫向對比:

維度BIO(同步阻塞)NIO(同步非阻塞)AIO(異步非阻塞)
I/O范式同步阻塞同步非阻塞異步非阻塞
線程模型1連接1線程(線程池優化)1線程管理N連接(事件驅動)0線程等待I/O(回調驅動)
阻塞點accept()read()全程阻塞selector.select()阻塞無顯式阻塞(回調觸發時執行)
I/O通知方式程序主動等待(無通知)程序輪詢Selector獲取就緒事件內核主動回調通知I/O完成
資源消耗高(線程數與連接數線性相關)中(線程數固定,與連接數解耦)低(線程僅處理回調邏輯)
編程復雜度低(線性流程,易調試)中(需處理Buffer、事件輪詢)高(回調嵌套,需處理異步狀態)
內核交互方式多次系統調用(阻塞等待)單次系統調用(多路復用查詢)單次系統調用(異步注冊+回調)
典型適用場景低并發短連接(如內部工具)高并發短連接(如HTTP服務器)高并發長I/O(如文件/數據庫操作)

5.2 演進邏輯:從“等待I/O”到“利用I/O”

Java I/O模型的三次演進,本質是對“CPU與I/O速度差異”這一核心矛盾的逐步優化:

  • BIO時代:線程直接綁定I/O操作,CPU被迫“等待I/O”。此時I/O效率完全由線程數量決定,但線程是稀缺資源(Java線程默認棧大小1MB,1000個線程需1GB內存),高并發場景下必然崩潰。
  • NIO時代:通過Selector的“多路復用”,將線程從“等待單個連接”解放為“管理多個連接”。CPU不再為未就緒的I/O空轉,而是“按需處理”就緒事件,實現了“用更少線程處理更多連接”,但線程仍需主動輪詢I/O狀態(同步非阻塞的本質)。
  • AIO時代:內核接管I/O的全流程,線程僅需定義“I/O完成后做什么”(回調)。CPU與I/O真正并行——I/O操作在內核空間執行時,線程可繼續處理其他任務,徹底釋放了“等待時間”,實現“計算與I/O同時進行”。

5.3 如何選擇:場景決定模型

實際開發中,I/O模型的選擇需結合業務場景的連接數I/O耗時資源約束

  • 選BIO:連接數少(<100)、I/O耗時短(如查詢數據庫單條記錄)、需快速實現的場景。例如小型內部系統的API網關。
  • 選NIO:連接數高(1000+)、I/O耗時短(如HTTP請求處理)、服務器資源有限的場景。例如Spring Boot的默認嵌入式服務器(Tomcat)在高并發時可切換為NIO模式。
  • 選AIO:連接數高(1000+)、I/O耗時長(如大文件上傳、數據庫批量寫入)、需最大化CPU利用率的場景。例如云存儲服務的文件傳輸模塊。

5.4 未來趨勢:異步化與事件驅動

隨著微服務、云原生的普及,高并發、低延遲的需求日益增長。AIO的“異步回調”模式與Reactor(響應式編程)、Netty(高性能網絡框架)等技術高度契合,已成為現代分布式系統的底層支撐。未來,結合CompletableFuture的鏈式回調、Quarkus/Helidon等異步框架的優化,AIO將在更多場景中替代NIO,成為“高效I/O”的代名詞。


結語

BIO、NIO、AIO的演進史,是Java對“高效I/O”的持續探索史。從阻塞到非阻塞,從同步到異步,每一次迭代都在更精準地協調CPU與I/O的速度差異。開發者需理解三者的底層邏輯,結合業務場景選擇最適合的模型——沒有“最好”的I/O模型,只有“最適合”的模型。未來,隨著操作系統異步I/O支持的完善(如Linux的io_uring),Java的I/O體系還將繼續演進,但“用最少資源完成最多I/O”的核心目標始終不變。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/95126.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/95126.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/95126.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windows PowerToys之無界鼠標:一套鍵鼠控制多臺設備

&#x1f4bb;簡介 在多設備協作的工作場景中&#xff0c;如何實現一套鍵鼠控制多臺設備了&#xff1f;微軟推出的 PowerToys 工具集中的 Mouse Without Borders&#xff08;無界鼠標&#xff09;&#xff0c;通過軟件層實現跨設備的鍵鼠共享與數據同步功能&#xff0c;為多臺…

一道比較難的sql題,篩選出重復字段的行數

select * from 導入數據表; id city_column 1 北京,上海,廣州 2 上海,上海,深圳 3 北京,杭州,北京 4 上海,廣州,深圳select substring_index(khmc,,,1), * from 導入數據表 truncate table 導入數據表 select count(distinct khmc) from 導入數據表; …

【K8s】整體認識K8s之與集群外部訪問--service

這一篇文章主要是對service發現新的理解 為什么要使用service服務發現&#xff1f; 首先pod的IP&#xff0c;是動態的&#xff0c;當我們重啟一個pod的時候&#xff0c;它會給它分配一個新的IP&#xff0c;但是如果微服務a想要去調用微服務b&#xff0c;他是需要知道微服務b所有…

k8s(自寫)

kubernetes k8s是什么&#xff1f;Kubernetes是什么&#xff1f;架構是怎么樣的&#xff1f;6分鐘快速入門_嗶哩嗶哩_bilibili kubernetes是google開源神器&#xff0c;介于應用服務和服務器之間&#xff0c;能夠通過策略協調和管理多個應用服務&#xff0c;只需要一個yaml文…

實現微信小程序的UniApp相機組件:拍照、錄像與雙指縮放

在微信小程序開發中&#xff0c;相機功能已成為許多應用的核心組成部分。本文將介紹如何使用UniApp框架實現一個功能豐富的相機組件&#xff0c;支持拍照、錄像、前后攝像頭切換以及雙指縮放等功能。功能概述這個相機組件具備以下核心功能&#xff1a;拍照功能&#xff1a;支持…

python pyqt5開發DoIP上位機【診斷回復的函數都是怎么調用的?】

目錄 文章合集 一、底層網絡接收:`_receive_loop`(觸發起點) 調用時機: 核心代碼: 作用: 二、數據解析:`handle_received_data`(判斷是否為診斷回復) 調用時機: 核心代碼(診斷回復相關部分): 作用: 三、UI顯示:`add_trace_entry`(展示到界面) 調用時機: 信號…

談物質的運動與運動的物質

運動的物質是不是物質的運動&#xff0c;如果假設是&#xff08;第一假設&#xff09;&#xff0c;那末運動的物質是物質的運動&#xff0c;而運動是物質的根本屬性&#xff0c;又運動的物質是物質&#xff0c;則物質的運動是物質&#xff0c;既然運動是物質的根本屬性&#xf…

【MLLM】多模態理解Ovis2.5模型架構和訓練流程

note 模型架構&#xff1a;延續 Ovis 系列創新的結構化嵌入對齊設計。 Ovis2.5 由三大組件構成&#xff1a;動態分辨率 ViT 高效提取視覺特征&#xff0c;Ovis 視覺詞表模塊實現視覺與文本嵌入的結構對齊&#xff0c;最后由強大的 Qwen3 作為語言基座&#xff0c;處理多模態嵌…

3.3單鏈表專題

順序表這種在標準庫已經實現好了&#xff0c;直接調用 pushback pushfront 這些o(1)表示不額外開辟空間src為value繼續走&#xff0c;下一個不是value&#xff0c;src值給dst空間&#xff0c;dst&#xff0c;dst剛好等于2&#xff0c;就是新數組長度。若從前向后兩個數組元素依…

linux系統學習(15.啟動管理)

目錄 一、運行級別 1.運行級別 2.運行級別命令 (1)runlevel (2)init 運行級別 3.永久修改啟動級別&#xff08;ubantu20.04&#xff09; 二、啟動過程 &#x1f539; 總結 三、啟動引導程序grub配置文件 一、運行級別 1.運行級別 2.運行級別命令 (1)runlevel (2)ini…

檢索優化-混合檢索

混合檢索&#xff08;Hybrid Search&#xff09;是一種結合了 稀疏向量&#xff08;Sparse Vectors&#xff09; 和 密集向量&#xff08;Dense Vectors&#xff09; 優勢的先進搜索技術。旨在同時利用稀疏向量的關鍵詞精確匹配能力和密集向量的語義理解能力&#xff0c;以克服…

Day17(前端:JavaScript基礎階段)

接續上文:Day16(前端:JavaScript基礎階段)_前端題目 csdn-CSDN博客 點關注不迷路喲。你的點贊、收藏&#xff0c;一鍵三連&#xff0c;是我持續更新的動力喲&#xff01;&#xff01;&#xff01; 主頁:一位搞嵌入式的 genius-CSDN博客 系列文章專欄: https://blog.csdn.ne…

OpenCV 輪廓分析實戰:從檢測到形狀匹配的完整指南

輪廓&#xff08;Contour&#xff09;是圖像中連續且具有相同灰度值的像素集合&#xff0c;是描述目標形狀、位置和結構的核心特征。在計算機視覺中&#xff0c;輪廓分析廣泛應用于目標定位、形狀識別、尺寸測量等場景&#xff08;如工業零件檢測、手寫數字識別&#xff09;。本…

2025最新uni-app橫屏適配方案:微信小程序全平臺兼容實戰

以下為uni-app實現微信小程序橫屏適配技術方案&#xff0c;包含核心原理、配置方法、代碼示例和注意事項&#xff1a;一、橫屏適配原理 微信小程序默認采用豎屏模式&#xff0c;橫屏適配需通過以下機制實現&#xff1a; 全局配置&#xff1a;在app.json中聲明支持橫屏頁面級配置…

深入解析Nginx常見模塊1

在Web服務器和反向代理服務器領域,Nginx憑借其高性能、穩定性和豐富的功能獲得了廣泛的應用。本文將介紹一些Nginx中常見的模塊,幫助你更好地理解和使用它們。 Nginx模塊簡介 Nginx的模塊系統是其強大功能的核心所在,它允許用戶根據需要靈活配置服務器的行為。Nginx的模塊大…

淺談new與::operator new

目錄 前言 1.為什么C要引入new/delete&#xff1f; 2.operator new與operator delete函數 它們的實際作用 Placement New&#xff08;定位new表達式&#xff09; 總結 前言 在寫上一篇博客“vector的模擬實現”時&#xff0c;我一直很好奇vector的private成員為什么要用三個封…

Java中Integer轉String

在 Java 中&#xff0c;將 Integer 轉換為 String 有多種方法&#xff0c;以下是常見的幾種方式&#xff1a;1. 使用 Integer.toString() 方法javaInteger num 123; String str Integer.toString(num); // 直接調用 Integer 的靜態方法2. 使用 String.valueOf()javaInteger n…

智能裝備如何與軟件結合?

一、什么是智能裝備&#xff1f; 智能裝備是具備“感知-決策-執行-自適應”閉環能力的智能化系統&#xff0c;本質是“傳統物理裝備”與“數字智能”的深度融合。它不僅能完成預設動作&#xff08;如傳統機械臂焊接&#xff09;&#xff0c;還能通過傳感器“觀察”環境、用算法…

react性能優化有哪些

React 性能優化的手段比較多&#xff0c;既有代碼層面的&#xff0c;也有構建層面的&#xff0c;還涉及到運行時調優。我幫你系統性梳理一份&#xff1a;&#x1f539; 一、渲染性能優化1. 減少不必要的渲染React.memo&#xff1a;對函數組件做淺比較&#xff0c;避免相同 prop…

騰訊云OpenCloudOS 9系統部署OpenTenBase數據庫詳細教程

OpenTenBase簡介OpenTenBase是一個關系型數據庫集群平臺&#xff0c;提供寫入可靠性和多節點數據同步功能。可以在一臺或多臺主機上配置OpenTenBase&#xff0c;并將數據存儲在多個物理主機上。OpenTenBase架構組件&#xff1a;Coordinator Node (CN)&#xff1a;應用程序訪問入…