通信網絡編程——JAVA

1.計算機網絡

IP

  • 定義與作用 :IP 地址是在網絡中用于標識設備的數字標簽,它允許網絡中的設備之間相互定位和通信。每一個設備在特定網絡環境下都有一個唯一的 IP 地址,以此來確定其在網絡中的位置。

  • 分類 :常見的 IP 地址分為 IPv4 和 IPv6。

  • IPv4 地址是一個 32 位的二進制數,通常被分為 4 個字節,表示為十進制形式,如 192.168.1.1。

  • 由于 IPv4 地址數量有限,逐漸出現了 IPv6 地址, 它是128 位的二進制數,通常表示為 8 組 16 進制數,如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。

端口

  • 定義與作用 :端口是操作系統中的一個抽象概念,用于區分同一設備上運行的不同程序。在 TCP/IP 協議族中,端口號是一個 16 位的數字,范圍從 0 到 65535。當數據到達設備后,系統會根據端口號將數據轉發給對應的程序進行處理。

  • 分類 :端口可以分為三大類。

  • 一類是熟知端口(0 - 1023),這些端口通常被系統服務所使用,如 HTTP 協議使用 80 端口,HTTPS 協議使用 443 端口等。

  • 另一類是注冊端口(1024 - 49151),這些端口可以被用戶進程或應用程序使用,但需要在相關機構進行注冊。

  • 還有一類是動態和 / 或私有端口(49152 - 65535),這些端口可以自由使用,通常用于臨時會話或應用程序內部通信。

TCP/UDP 傳輸協議

  • TCP 協議

    • 特點 :TCP(Transmission Control Protocol,傳輸控制協議)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。它在正式通信之前需要建立連接,如同打電話之前先撥號建立通話線路一樣。在數據傳輸過程中,TCP 通過三次握手建立連接,確保雙方都準備好數據進行傳輸。并且它采用流量控制、擁塞控制等機制,能夠有效避免網絡擁塞和數據丟失。

    • 應用場景 :適用于對數據準確性要求高、數據傳輸量較大的場景,如文件傳輸、郵件傳輸、網頁瀏覽等。

  • UDP 協議

    • 特點 :UDP(User Datagram Protocol,用戶數據報協議)是一種無連接的傳輸層協議。它不建立連接就直接發送數據,數據傳輸就像是直接投遞一封信,不考慮對方是否準備好接收。UDP 不保證的數據可靠傳輸,數據可能會丟失、重復或亂序到達。不過,UDP 的傳輸速度相對較快,因為它不需要進行繁瑣的連接建立和維護過程。

    • 應用場景 :適用于對實時性要求高、對數據丟失不太敏感的場景,如視頻直播、在線游戲、實時語音通信等。

服務器與客戶端

  • 服務器

    • 定義與作用 :服務器是網絡環境中的高性能計算機或設備,它運行特定的服務器軟件,為客戶端提供各種服務和資源。

    • 工作原理 :服務器通常會一直保持監聽狀態,等待客戶端的連接請求。當收到請求后,服務器會根據請求的內容和協議進行相應的處理,并將處理結果返回給客戶端。為了確保能夠同時處理多個客戶端的請求,服務器通常會采用多線程、多進程或異步 IO 等技術。

  • 客戶端

    • 定義與作用 :客戶端是用戶直接使用并與服務器進行交互的設備或軟件。它向服務器發送請求,并接收服務器返回的響應。

    • 工作原理 :客戶端一般需要知道服務器的 IP 地址和端口號,通過建立與服務器的連接,按照特定的協議格式發送請求消息。在接收到服務器的響應后,客戶端會對響應進行解析和處理,以實現用戶期望的功能。

IO 模型

  • 同步 IO 模型

    • 阻塞 IO :阻在塞 IO 模型下,客戶端調用 IO 操作后會一直阻塞,直到操作完成并返回結果。例如,在文件讀取操作中,如果采用阻塞 IO,那么在讀取文件內容的過程中,程序會暫停執行,等待文件讀取完成才能繼續向下執行。這種方式的缺點是資源利用率較低,因為線程或進程在等待 IO 完成期間無法進行其他工作。

    • 非阻塞 IO :非阻塞 IO 模型與阻塞 IO 不同,它在調用 IO 操作時會立即返回,不會一直等待操作完成。但需要客戶端不斷輪詢 IO 操作的狀態,直到操作完成。例如,客戶端發送一個非阻塞的網絡請求后,會不斷地詢問操作系統這個請求是否完成,這種方式會增加 CPU 的負擔,因為需要不斷地進行輪詢操作。

  • 異步 IO 模型

    • 特點 :異步 IO 模型是基于事件通知機制的。客戶端發起 IO 操作后,會立即返回,操作系統會在 IO 操作完成時主動通知客戶端。這樣客戶端可以在等待 IO 完成期間繼續執行其他任務,提高了資源的利用率。例如,在網頁瀏覽器中,當用戶點擊一個按鈕觸發一個異步請求時,瀏覽器可以繼續響應用戶的其他操作,如滾動頁面等,而不會被這個請求所阻塞。

    • 優勢 :可以提高程序的并發能力和響應速度,特別適用于高并發的場景,如 Web 服務器處理大量客戶端請求時,采用異步 IO 能夠更有效地利用系統資源,提高服務器的性能。

通信架構模式

  • C/S 架構(Client/Server 架構)

    • 特點 :C/S 架構是一種基于請求 - 響應模式的架構。客戶端負責與用戶交互,將用戶請求發送給服務器;服務器負責處理客戶端請求,并將處理結果返回給客戶端。這種架構需要在客戶端安裝專門的客戶端軟件,如銀行的客戶端應用程序、企業的內部辦公軟件等。

    • 優點 :客戶端軟件可以提供豐富的用戶界面和交互功能,能夠對硬件資源進行充分利用,同時可以更好地控制數據的安全性和完整性。

    • 缺點 :客戶端軟件的安裝和維護成本較高,當需要進行軟件升級時,需要對所有客戶端進行更新。并且客戶端對服務器的依賴性較強,服務器的性能和穩定性直接影響到整個系統的運行。

  • B/S 架構(Browser/Server 架構)

    • 特點 :B/S 架構是基于瀏覽器和服務器的架構。客戶端只需要安裝瀏覽器,通過瀏覽器訪問服務器上的 Web 應用程序。服務器負責處理所有請求和業務邏輯,并返回相應的網頁給客戶端進行展示。例如,各種在線購物網站、社交媒體平臺等都是基于 B/S 架構的。

    • 優點 :客戶端無需安裝專門的軟件,只要能夠訪問網絡并打開瀏覽器即可使用。軟件的升級和維護只需要在服務器端進行,降低了維護成本和復雜度。并且具有很好的兼容性和跨平臺性,可以在不同的操作系統和設備上使用。

    • 缺點 :相比 C/S 架構,B/S 架構下的網頁應用在用戶交互和界面體驗方面可能會受到瀏覽器的限制。同時,服務器端的負載相對較大,需要處理大量的請求和業務邏輯。

2.核心API

Socket

  • 定義與作用 :Socket(套接字)是網絡通信中的一種抽象概念,它是網絡通信過程中的一個端點,用于實現不同設備之間的雙向通信。通過 Socket,應用程序可以在網絡中進行數據的發送和接收,就好像在設備之間建立了一條虛擬的通信管道。

  • 使用流程 :對于 TCP Socket,客戶端先創建 Socket,然后連接到服務器的特定端口和 IP 地址;服務器端創建 Socket,綁定到本地的某個端口和 IP 地址,開始監聽連接請求,接收客戶端連接后,雙方就可以通過 Socket 進行數據的讀寫操作。對于 UDP Socket,不需要建立連接,客戶端和服務器端都可以直接發送和接收數據報。

ServerSocket

  • 定義與作用 :ServerSocket 是服務器端用于監聽和接受客戶端連接請求的套接字。它在服務器端等待客戶端的連接,當客戶端請求連接時,ServerSocket 會接受請求并創建一個新的 Socket 來與客戶端進行通信,從而實現服務器與多個客戶端的同時通信。

  • 工作原理 :ServerSocket 綁定到本地的某個端口,然后開始監聽該端口的連接請求。當客戶端發送連接請求時,ServerSocket 會接受這個請求,并返回一個與客戶端通信的 Socket 對象。服務器端可以通過這個 Socket 對象與客戶端進行數據的讀寫操作,而 ServerSocket 則繼續監聽該端口,等待其他客戶端的連接請求。

DNS 域名解析服務器

  • 定義與作用 :DNS(Domain Name System)域名解析服務器是用于將域名轉換為 IP 地址的服務器。在互聯網中,用戶通常使用域名來訪問網站,而計算機之間通信需要使用 IP 地址。DNS 服務器的作用就是將用戶輸入的域名解析為對應的 IP 地址,使得用戶可以通過域名方便地訪問網站。

  • 工作原理 :當用戶在瀏覽器中輸入一個域名時,瀏覽器會首先向本地 DNS 服務器發送域名解析請求。本地 DNS 服務器會先在自己的緩存中查找該域名對應的 IP 地址,如果找到則直接返回給瀏覽器;如果沒有找到,本地 DNS 服務器會向根 DNS 服務器發送請求,根 DNS 服務器會根據域名的頂級域名(如.com、.net 等)返回相應的頂級域名服務器的地址,本地 DNS 服務器再向頂級域名服務器發送請求,頂級域名服務器會根據域名的二級域名返回相應的權威 DNS 服務器的地址,本地 DNS 服務器最后向權威 DNS 服務器發送請求,權威 DNS 服務器會返回該域名對應的 IP 地址,本地 DNS 服務器將這個 IP 地址緩存起來并返回給瀏覽器,瀏覽器就可以使用這個 IP 地址來訪問網站了。

InputStream

  • 定義與作用 :InputStream 是 Java 中的一個輸入流類,它用于從源讀取字節數據。源可以是文件、網絡連接、內存緩沖區等。InputStream 是所有字節輸入流的父類,它提供了一組基本的方法用于讀取數據,如 read() 方法用于讀取單個字節,read(byte[] b) 方法用于將數據讀入一個字節數組等。

  • 常見子類與特點

    • FileInputStream :用于從文件中讀取數據。它可以打開一個文件進行讀取,讀取到文件末尾時返回 - 1 表示結束。

    • BufferedInputStream :對其他輸入流進行緩沖處理,提高讀取效率。它通過內部維護一個緩沖區,減少對底層數據源的讀取次數,從而提高讀取速度。

    • ObjectInputStream :用于讀取 Java 對象序列化的數據。它可以將序列化的對象從輸入流中還原為 Java 對象,前提是該對象的類實現了 Serializable 接口。

OutputStream

  • 定義與作用 :OutputStream 是 Java 中的一個輸出流類,它用于將字節數據寫入目標。目標可以是文件、網絡連接、內存緩沖區等。OutputStream 是所有字節輸出流的父類,它提供了一組基本的方法用于寫入數據,如 write(int b) 方法用于寫入單個字節,write(byte[] b) 方法用于將字節數組中的數據寫入輸出流等。

  • 常見子類與特點

    • FileOutputStream :用于將數據寫入文件。它可以創建一個新文件或追加數據到現有文件中。

    • BufferedOutputStream :對其他輸出流進行緩沖處理,提高寫入效率。它通過內部維護一個緩沖區,減少對底層數據目標的寫入次數,從而提高寫入速度。

    • ObjectOutputStream :用于將 Java 對象序列化后寫入輸出流。它可以將 Java 對象轉換為字節流序列,便于存儲或傳輸,前提是該對象的類實現了 Serializable 接口。

3.代碼

服務器端代碼(MyChatServer)

服務器啟動

public class MyChatServer {public static void main(String[] args) {try {// 創建服務器套接字,監聽端口12000ServerSocket serverSocket = new ServerSocket(12000);System.out.println("服務器啟動,等待客戶端連接......");
  • ServerSocket:用于監聽特定端口的傳入連接請求。

  • serverSocket.accept():阻塞等待客戶端連接,直到有客戶端連接時返回一個Socket對象。

處理客戶端連接

            // 接受客戶端連接Socket socket = serverSocket.accept();System.out.println("客戶端已連接:" + socket.getInetAddress() + ":" + socket.getPort());
  • socket.getInetAddress():獲取客戶端的IP地址。

  • socket.getPort():獲取客戶端的端口號。

獲取輸入輸出流

            // 獲取輸入輸出流InputStream is = socket.getInputStream();OutputStream os = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 從控制臺讀取消息BufferedReader serverIn = new BufferedReader(new InputStreamReader(is)); // 讀取客戶端消息
  • socket.getInputStream():獲取輸入流,用于讀取客戶端發送的數據。

  • socket.getOutputStream():獲取輸出流,用于向客戶端發送數據。

  • BufferedReader:用于從控制臺或輸入流讀取文本數據。

通信循環

            System.out.println("等待客戶端消息......");while (true) {// 讀取客戶端發送的消息int messageLength = is.read();  // 讀取消息長度byte[] messageBuffer = new byte[messageLength];for (int i = 0; i < messageBuffer.length; i++) {messageBuffer[i] = (byte) is.read();}String clientMessage = new String(messageBuffer);System.out.println("收到客戶端消息:" + clientMessage);// 檢查是否是退出命令if ("exit".equalsIgnoreCase(clientMessage)) {System.out.println("客戶端已斷開連接");break;}// 從控制臺讀取要發送給客戶端的消息System.out.print("請輸入要發送的消息:");String serverMessage = br.readLine();// 發送消息給客戶端os.write(serverMessage.getBytes().length);  // 發送消息長度os.write(serverMessage.getBytes());  // 發送消息內容os.flush();// 檢查是否是退出命令if ("exit".equalsIgnoreCase(serverMessage)) {System.out.println("服務器將斷開連接");break;}}
  • 服務器首先讀取消息的長度,然后根據長度讀取消息內容。

  • 消息以字節數組的形式傳輸,然后轉換為字符串。

  • 如果收到"exit"消息,服務器將退出通信循環。

  • 服務器從控制臺讀取消息,并將其發送給客戶端。

  • 消息發送前,先發送消息長度,以便客戶端知道要讀取多少字節。

關閉資源

            // 關閉資源br.close();os.close();is.close();socket.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();}}
}
  • 逐個關閉資源,確保沒有資源泄漏。

完整代碼

public class MyChatServer {public static void main(String[] args) {try {// 創建服務器套接字,監聽端口12000ServerSocket serverSocket = new ServerSocket(12000);System.out.println("服務器啟動,等待客戶端連接......");// 接受客戶端連接Socket socket = serverSocket.accept();System.out.println("客戶端已連接:" + socket.getInetAddress() + ":" + socket.getPort());// 獲取輸入輸出流InputStream is = socket.getInputStream();OutputStream os = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 從控制臺讀取消息BufferedReader serverIn = new BufferedReader(new InputStreamReader(is)); // 讀取客戶端消息System.out.println("等待客戶端消息......");while (true) {// 讀取客戶端發送的消息int messageLength = is.read();byte[] messageBuffer = new byte[messageLength];for (int i = 0; i < messageBuffer.length; i++) {messageBuffer[i] = (byte) is.read();}String clientMessage = new String(messageBuffer);System.out.println("收到客戶端消息:" + clientMessage);// 檢查是否是退出命令if ("exit".equalsIgnoreCase(clientMessage)) {System.out.println("客戶端已斷開連接");break;}// 從控制臺讀取要發送給客戶端的消息System.out.print("請輸入要發送的消息:");String serverMessage = br.readLine();// 發送消息給客戶端os.write(serverMessage.getBytes().length);os.write(serverMessage.getBytes());os.flush();// 檢查是否是退出命令if ("exit".equalsIgnoreCase(serverMessage)) {System.out.println("服務器將斷開連接");break;}}// 關閉資源br.close();os.close();is.close();socket.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();}}
}

客戶端代碼(ChatClient)

連接到服務器

public class ChatClient {public static void main(String[] args) {try {// 連接到服務器Socket socket = new Socket("127.0.0.1", 12000);System.out.println("客戶端已連接到服務器");
  • Socket:用于建立與服務器的連接。

  • "127.0.0.1":本地主機IP地址,表示客戶端和服務器在同一臺機器上。

  • 12000:服務器監聽的端口號。

獲取輸入輸出流

            // 獲取輸入輸出流InputStream is = socket.getInputStream();OutputStream os = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 從控制臺讀取消息
  • 客戶端同樣需要獲取輸入輸出流,用于與服務器通信。

通信循環

            System.out.println("等待服務器消息......");while (true) {// 從控制臺讀取要發送的消息System.out.print("請輸入要發送的消息:");String clientMessage = br.readLine();// 發送消息給服務器os.write(clientMessage.getBytes().length);  // 發送消息長度os.write(clientMessage.getBytes());  // 發送消息內容os.flush();// 檢查是否是退出命令if ("exit".equalsIgnoreCase(clientMessage)) {System.out.println("客戶端將斷開連接");break;}// 讀取服務器的響應消息int messageLength = is.read();  // 讀取消息長度byte[] messageBuffer = new byte[messageLength];for (int i = 0; i < messageBuffer.length; i++) {messageBuffer[i] = (byte) is.read();}String serverMessage = new String(messageBuffer);System.out.println("收到服務器消息:" + serverMessage);// 檢查是否是退出命令if ("exit".equalsIgnoreCase(serverMessage)) {System.out.println("服務器已斷開連接");break;}}
  • 客戶端的通信邏輯與服務器類似,先發送消息,然后等待服務器的響應。

  • 如果收到"exit"消息,客戶端將退出通信循環。

關閉資源

            // 關閉資源br.close();os.close();is.close();socket.close();} catch (IOException e) {e.printStackTrace();}}
}

完整代碼

public class ChatClient {public static void main(String[] args) {try {// 連接到服務器Socket socket = new Socket("127.0.0.1", 12000);System.out.println("客戶端已連接到服務器");// 獲取輸入輸出流InputStream is = socket.getInputStream();OutputStream os = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 從控制臺讀取消息System.out.println("等待服務器消息......");while (true) {// 從控制臺讀取要發送的消息System.out.print("請輸入要發送的消息:");String clientMessage = br.readLine();// 發送消息給服務器os.write(clientMessage.getBytes().length);os.write(clientMessage.getBytes());os.flush();// 檢查是否是退出命令if ("exit".equalsIgnoreCase(clientMessage)) {System.out.println("客戶端將斷開連接");break;}// 讀取服務器的響應消息int messageLength = is.read();byte[] messageBuffer = new byte[messageLength];for (int i = 0; i < messageBuffer.length; i++) {messageBuffer[i] = (byte) is.read();}String serverMessage = new String(messageBuffer);System.out.println("收到服務器消息:" + serverMessage);// 檢查是否是退出命令if ("exit".equalsIgnoreCase(serverMessage)) {System.out.println("服務器已斷開連接");break;}}// 關閉資源br.close();os.close();is.close();socket.close();} catch (IOException e) {e.printStackTrace();}}
}

這個示例展示了一個基本的客戶端-服務器Socket通信模型。服務器監聽特定端口,客戶端連接到該端口,雙方可以通過輸入輸出流互相發送和接收消息。消息傳輸時,先發送消息長度,然后發送消息內容,這樣可以確保接收方能夠完整地讀取消息。

效果展示

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

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

相關文章

#在 CentOS 7 中手動編譯安裝軟件操作及原理

在 CentOS 7 中&#xff0c;手動編譯安裝軟件&#xff08;即從源代碼編譯安裝&#xff09;是一種高度靈活的方式&#xff0c;適用于需要定制化軟件功能、優化性能或安裝官方倉庫未提供的軟件版本的場景。以下是針對手動編譯安裝的詳細說明&#xff0c;包括原理、步驟、注意事項…

菊廠0510面試手撕題目解答

題目 輸入一個整數數組&#xff0c;返回該數組中最小差出現的次數。 示例1&#xff1a;輸入&#xff1a;[1,3,7,5,9,12]&#xff0c;輸出&#xff1a;4&#xff0c;最小差為2&#xff0c;共出現4次&#xff1b; 示例2&#xff1a;輸入&#xff1a;[90,98,90,90,1,1]&#xf…

C——五子棋小游戲

前言 五子棋&#xff0c;又稱連珠棋&#xff0c;是一種雙人對弈的棋類游戲。游戲目標是在一個棋盤上&#xff0c;通過在橫、豎、斜線上依次放置棋子&#xff0c;使自己的五個棋子連成一線&#xff0c;即橫線、豎線或斜線&#xff0c;且無被對手堵住的空位&#xff0c;從而獲勝…

ik 分詞器 設置自定義詞典

進入 ES 的安裝目錄&#xff0c;進入 /elasticsearch-8.10.0/plugins/ik/config/ 文件夾目錄&#xff0c;打開 IKAnalyzer.cfg.xml 文件進行配置。 一、添加 自定義擴展詞典 擴展詞&#xff1a;就是不想哪些詞分開&#xff0c;讓他們成為一個詞&#xff0c;比如“蒙的全是對…

Linux筆記---信號(上)

1. 信號的概念 Linux下的信號機制是一種進程間通信&#xff08;IPC&#xff09;的方式&#xff0c;用于在不同進程之間傳遞信息。 信號是一種異步的信息傳遞方式&#xff0c;這意味著發送信號的進程只發送由信號作為載體的命令&#xff0c;而并不關心接收信號的進程如何處置這…

UG 二次開發- UG內部調用DLL

【1】用VS新建一個dll工程 將項目設置為x64平臺&#xff08;這步很重要&#xff0c;否則程序無法編譯成功&#xff09; 【2】添加UG頭文件目錄&#xff0c;屬性頁->C/C->常規->附加包含目錄 【3】添加UG庫所在目錄&#xff0c;屬性頁->鏈接器->常規->附加庫目…

wordcount在mapreduce的例子

1.啟動集群 2.創建項目 項目結構為&#xff1a; 3.pom.xml文件為 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://mave…

智慧城市綜合運營管理系統Axure原型

這款Axure原型的設計理念緊緊圍繞城市管理者的需求展開。它旨在打破傳統城市管理中信息孤島的局面&#xff0c;通過統一標準接入各類業務系統&#xff0c;實現城市運營管理信息資源的全面整合與共享。以城市管理者為中心&#xff0c;為其提供一個直觀、便捷、高效的協同服務平臺…

Go語言:json 作用和語法

在 Go 語言中&#xff0c;JSON 字段&#xff08;也稱為 JSON Tag&#xff09;是附加在結構體字段上的元數據&#xff0c;用于控制該字段在 JSON 編碼&#xff08;序列化&#xff09;和解碼&#xff08;反序列化&#xff09; 時的行為。它的語法是&#xff1a; type StructName…

MATLAB復制Excel數據到指定區域

Matlab中如何將Excel表中的265-528行F-AA列數據復制到1-263行AE-AZ中 版本&#xff1a;MatlabR2018b clc; clear; %舊Excel文件名 oldFile ; %新Excel文件名 newFile ; % 工作表名稱&#xff08;舊表和新表一致&#xff09; sheetName Sheet1; % 舊文件中待復制的數據范…

vue3+flask+sqlite前后端項目實戰

基礎環境安裝 pycharm 下載地址&#xff1a; https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows vscode 下載地址 https://code.visualstudio.com/docs/?dvwin64user python 下載地址 https://www.python.org/downloads/windows/ Node.js&#xff08;含npm…

Java 內存模型(JMM)與內存屏障:原理、實踐與性能權衡

Java 內存模型&#xff08;JMM&#xff09;與內存屏障&#xff1a;原理、實踐與性能權衡 在多線程高并發時代&#xff0c;Java 內存模型&#xff08;JMM&#xff09; 及其背后的內存屏障機制&#xff0c;是保障并發程序正確性與性能的基石。本文將系統梳理 JMM 的核心原理、內…

動手學深度學習12.3.自動并行-筆記練習(PyTorch)

以下內容為結合李沐老師的課程和教材補充的學習筆記&#xff0c;以及對課后練習的一些思考&#xff0c;自留回顧&#xff0c;也供同學之人交流參考。 本節課程地址&#xff1a;無 本節教材地址&#xff1a;12.3. 自動并行 — 動手學深度學習 2.0.0 documentation 本節開源代…

C++類和對象之初始化列表

初始化列表 C初始化列表詳解&#xff1a;性能優化與正確實踐什么是初始化列表&#xff1f;初始化列表的三大核心作用1. 性能優化&#xff1a;避免不必要的賦值操作2. 強制初始化&#xff1a;處理const和引用成員3. 基類初始化&#xff1a;正確調用父類構造函數4.必須使用初始化…

continue通過我們的開源 IDE 擴展和模型、規則、提示、文檔和其他構建塊中心,創建、共享和使用自定義 AI 代碼助手

?一、軟件介紹 文末提供程序和源碼下載 Continue 使開發人員能夠通過我們的開源 VS Code 和 JetBrains 擴展以及模型、規則、提示、文檔和其他構建塊的中心創建、共享和使用自定義 AI 代碼助手。 二、功能 Chat 聊天 Chat makes it easy to ask for help from an LLM without…

基于Spring Boot + Vue的母嬰商城系統( 前后端分離)

一、項目背景介紹 隨著母嬰行業在互聯網平臺的快速發展&#xff0c;越來越多的家庭傾向于在線選購母嬰產品。為了提高商品管理效率和用戶購物體驗&#xff0c;本項目開發了一個基于 Spring Boot Vue 技術棧的母嬰商城系統&#xff0c;實現了商品分類、商品瀏覽、資訊展示、評…

實戰演練:用 AWS Lambda 和 API Gateway 構建你的第一個 Serverless API

實戰演練:用 AWS Lambda 和 API Gateway 構建你的第一個 Serverless API 理論千遍,不如動手一遍!在前面幾篇文章中,我們了解了 Serverless 的概念、FaaS 的核心原理以及 BaaS 的重要作用。現在,是時候把這些知識運用起來,親手構建一個簡單但完整的 Serverless 應用了。 …

node.js 實戰——express圖片保存到本地或服務器(七牛云、騰訊云、阿里云)

本地 ? 使用formidable 讀取表單內容 npm i formidable ? 使用mime-types 獲取圖片后綴 npm install mime-types? js 中提交form表單 document.getElementById(uploadForm).addEventListener(submit, function(e){e.preventDefault();const blob preview._blob;if(!blob)…

2025最新:3分鐘使用Docker快速部署單節點Redis

&#x1f9d1;?&#x1f3eb; 詳細教程&#xff1a;通過 Docker 安裝單節點 Redis &#x1f6e0;? 前提條件&#xff1a; 你需要在 Ubuntu 系統上進行操作&#xff08;如果你在其他系統上操作&#xff0c;可以按相似步驟進行調整&#xff09;。已安裝 Docker 和 Docker Com…

CentOS 7 系統下安裝 OpenSSL 1.0.2k 依賴問題的處理

前面有提到過這個openssl的版本沖突問題&#xff0c;也是在這次恢復服務器時遇到的問題&#xff0c;我整理如下&#xff0c;供大家參考。小小一個軟件的安裝&#xff0c;挺坑的。 一、問題 項目運行環境需要&#xff0c;指定PHP7.0.9這個版本&#xff0c;但是?系統版本與軟件…