基于Spring封裝一個websocket工具類使用事件發布進行解耦和管理

最近工作中,需要將原先的Http請求換成WebSocket,故此需要使用到WebSocket與前端交互。故此這邊需要研究一下WebSocket到底有何優點和不可替代性:

WebSocket優點:

WebSocket 協議提供了一種在客戶端和服務器之間進行全雙工通信的機制,這意味著客戶端和服務器可以在任何時候互相發送消息,而不需要預先建立請求。與傳統的 HTTP 輪詢相比,WebSocket 有以下不可替代的優點:

1.?低延遲: WebSocket 提供了真正的實時通信能力,因為它允許服務器在數據可用時立即將其推送到客戶端。這比 HTTP 輪詢的“詢問-回答”模式更高效,輪詢模式可能會引入不必要的延遲。

2.?減少網絡流量: 在 HTTP 輪詢中,客戶端需要定期發送請求以檢查更新,即使沒有更新也是如此。這會產生大量冗余的 HTTP 頭部信息和請求響應。相比之下,WebSocket 在建立連接后,只需要非常少的控制開銷就可以發送和接收消息。

3.?持久連接: WebSocket 使用單個持久連接進行通信,而不需要為每個消息或請求重新建立連接。這減少了頻繁建立和關閉連接的開銷,提高了效率。

4.?雙向通信: WebSocket 支持全雙工通信,客戶端和服務器可以同時發送消息,而不需要等待對方的響應。這對于需要快速雙向數據交換的應用程序來說是非常重要的。

5.?更好的服務器資源利用: 由于 WebSocket 連接是持久的,服務器可以更有效地管理資源,而不是在每個輪詢請求中重新初始化資源。

6.?協議開銷小: WebSocket 消息包含非常少的協議開銷,相比之下,HTTP 協議的每個請求/響應都包含了完整的頭部信息。

7.?支持二進制數據: WebSocket 不僅支持文本數據,還支持二進制數據,這使得它可以用于更廣泛的應用場景,如游戲、視頻流和其他需要高效二進制數據傳輸的應用。

8.?兼容性: 盡管是較新的技術,WebSocket 已經得到了現代瀏覽器的廣泛支持,并且可以通過 Polyfills 在不支持的瀏覽器上使用。

時序圖:

?

這個流程圖展示了以下步驟:

  1. 握手階段:客戶端向服務器發送 WebSocket 連接請求,服務器響應并切換協議。
  2. 連接建立:WebSocket 連接建立后,客戶端和服務器可以相互發送消息。
  3. 通信循環:客戶端和服務器在建立的 WebSocket 連接上進行消息交換。
  4. 關閉握手:客戶端或服務器發起關閉連接的請求,另一方響應,然后連接關閉。

因為以上優點這邊將需要重新構建一套WebSocket工具類實現這邊的要求:

工具類實現:

在 Spring 中封裝 WebSocket 工具類通常涉及使用 Spring 提供的 WebSocket API。

WebSocketUtils

WebSocket 工具類封裝示例,它使用 Spring 的 WebSocketSession 來發送消息給客戶端。

  1. 異常處理: 在發送消息時,如果發生異常,我們可以添加更詳細的異常處理邏輯。
  2. 會話管理: 我們可以添加同步塊或使用 ConcurrentHashMap 的原子操作來確保線程安全。
  3. 用戶標識符管理: 提供一個更靈活的方式來管理用戶標識符和會話之間的關系。
  4. 事件發布: 使用 Spring 事件發布機制來解耦和管理 WebSocket 事件。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/*** @Author derek_smart* @Date 202/5/11 10:05* @Description WebSocket 工具類*/
@Component
public class WebSocketUtils extends TextWebSocketHandler {private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();@Autowiredprivate ApplicationEventPublisher eventPublisher;public void registerSession(String userIdentifier, WebSocketSession session) {sessions.put(userIdentifier, session);// Publish an event when a session is registeredeventPublisher.publishEvent(new WebSocketSessionRegisteredEvent(this, session, userIdentifier));}public void removeSession(String userIdentifier) {WebSocketSession session = sessions.remove(userIdentifier);if (session != null) {// Publish an event when a session is removedeventPublisher.publishEvent(new WebSocketSessionRemovedEvent(this, session, userIdentifier));}}public void sendMessageToUser(String userIdentifier, String message) {WebSocketSession session = sessions.get(userIdentifier);if (session != null && session.isOpen()) {try {session.sendMessage(new TextMessage(message));} catch (IOException e) {// Handle the exception, e.g., logging or removing the sessionhandleWebSocketException(session, e);}}}public void sendMessageToAllUsers(String message) {TextMessage textMessage = new TextMessage(message);sessions.forEach((userIdentifier, session) -> {if (session.isOpen()) {try {session.sendMessage(textMessage);} catch (IOException e) {// Handle the exception, e.g., logging or removing the sessionhandleWebSocketException(session, e);}}});}private void handleWebSocketException(WebSocketSession session, IOException e) {// Log the exception// Attempt to close the session if it's still openif (session.isOpen()) {try {session.close();} catch (IOException ex) {// Log the exception during close}}// Remove the session from the mapsessions.values().remove(session);// Further exception handling...}@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {// This method can be overridden to handle connection established event}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {// This method can be overridden to handle connection closed event}// Additional methods like handleTextMessage can be overridden if needed// Custom eventspublic static class WebSocketSessionRegisteredEvent extends ApplicationEvent {private final WebSocketSession session;private final String userIdentifier;/*** Create a new WebSocketSessionRegisteredEvent.* @param source the object on which the event initially occurred (never {@code null})* @param session the WebSocket session which has been registered* @param userIdentifier the identifier of the user for whom the session is registered*/public WebSocketSessionRegisteredEvent(Object source, WebSocketSession session, String userIdentifier) {super(source);this.session = session;this.userIdentifier = userIdentifier;}public WebSocketSession getSession() {return session;}public String getUserIdentifier() {return userIdentifier;}}public static class WebSocketSessionRemovedEvent extends ApplicationEvent {private final WebSocketSession session;private final String userIdentifier;/*** Create a new WebSocketSessionRemovedEvent.* @param source the object on which the event initially occurred (never {@code null})*      * @param session the WebSocket session which has been removed*      * @param userIdentifier the identifier of the user for whom the session was removed*      */public WebSocketSessionRemovedEvent(Object source, WebSocketSession session, String userIdentifier) {super(source);this.session = session;this.userIdentifier = userIdentifier;}public WebSocketSession getSession() {return session;}public String getUserIdentifier() {return userIdentifier;}}
}

?

?

在這個工具類中,我們使用了 ConcurrentHashMap 來存儲和管理 WebSocket 會話。每個會話都與一個用戶標識符相關聯,這允許我們向特定用戶發送消息。 使用了 ApplicationEventPublisher 來發布會話注冊和移除事件,這樣可以讓其他組件在需要時響應這些事件。

另外,我們讓 WebSocketUtils 繼承了 TextWebSocketHandler,這樣它可以直接作為一個 WebSocket 處理器。這意味著你可以重寫
afterConnectionEstablished 和 afterConnectionClosed 方法來處理連接建立和關閉的事件,而不是在一個單獨的 WebSocketHandler 中處理它們。

通過這些優化,WebSocketUtils 工具類變得更加健壯和靈活,能夠更好地集成到 Spring 應用程序中

工具類提供了以下方法:

  • registerSession: 當新的 WebSocket 連接打開時,將該會話添加到映射中。
  • removeSession: 當 WebSocket 連接關閉時,從映射中移除該會話。
  • sendMessageToUser: 向特定用戶發送文本消息。
  • sendMessageToAllUsers: 向所有連接的用戶發送文本消息。
  • getSessions: 返回當前所有的 WebSocket 會話。

WebSocketHandler

為了完整地實現一個 WebSocket 工具類,你還需要創建一個?WebSocketHandler?來處理 WebSocket 事件,如下所示:

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
/*** @Author derek_smart* @Date 202/5/11 10:05* @Description WebSocketHandler*/
public class MyWebSocketHandler implements WebSocketHandler {private final WebSocketUtils webSocketUtils;public MyWebSocketHandler(WebSocketUtils webSocketUtils) {this.webSocketUtils = webSocketUtils;}@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {String userIdentifier = retrieveUserIdentifier(session);webSocketUtils.registerSession(userIdentifier, session);}@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {// Handle incoming messages}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {// Handle transport error}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {String userIdentifier = retrieveUserIdentifier(session);webSocketUtils.removeSession(userIdentifier);}@Overridepublic boolean supportsPartialMessages() {return false;}private String retrieveUserIdentifier(WebSocketSession session) {// Implement logic to retrieve the user identifier from the sessionreturn session.getId(); // For example, use the WebSocket session ID}
}

在 MyWebSocketHandler 中,我們處理了 WebSocket 連接的建立和關閉事件,并且在這些事件發生時調用 WebSocketUtils 的方法注冊或移除會話。

WebSocketConfig

要在 Spring 中配置 WebSocket,你需要在配置類中添加 WebSocketHandler 和 WebSocket 的映射。以下是一個簡單的配置示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {private final MyWebSocketHandler myWebSocketHandler;public WebSocketConfig(WebSocketUtils webSocketUtils) {this.myWebSocketHandler = new MyWebSocketHandler(webSocketUtils);}@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myWebSocketHandler, "/ws").setAllowedOrigins("*");}
}

WebSocketEventListener

我們擴展了 ApplicationEvent 類,這是所有 Spring 事件的基類。我們添加了兩個字段:session 和 userIdentifier,以及相應的構造函數和訪問器方法。這樣,當事件被發布時,監聽器可以訪問到事件的詳細信息。

要發布這個事件,你需要注入 ApplicationEventPublisher 到你的 WebSocketUtils 類中,并在會話注冊時調用 publishEvent 方法: 要發布這個事件,你需要在會話移除時調用 ApplicationEventPublisher 的 publishEvent 方法

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;@Component
public class WebSocketEventListener {@EventListenerpublic void handleWebSocketSessionRegistered(WebSocketUtils.WebSocketSessionRegisteredEvent event) {// 處理會話注冊事件WebSocketSession session = event.getSession();String userIdentifier = event.getUserIdentifier();// 你可以在這里添加你的邏輯,例如發送歡迎消息或記錄會話信息}@EventListenerpublic void handleWebSocketSessionRemoved(WebSocketUtils.WebSocketSessionRemovedEvent event) {// 處理會話移除事件WebSocketSession session = event.getSession();String userIdentifier = event.getUserIdentifier();// 你可以在這里添加你的邏輯,例如更新用戶狀態或釋放資源}}

類圖:

?

在這個類圖中,我們展示了以下類及其關系:

  • WebSocketUtils: 包含了會話管理和消息發送的方法。
  • WebSocketSessionRegisteredEvent: 一個自定義事件類,用于表示 WebSocket 會話注冊事件。
  • WebSocketSessionRemovedEvent: 一個自定義事件類,用于表示 WebSocket 會話移除事件。
  • WebSocketEventListener: 一個監聽器類,它監聽并處理 WebSocket 會話相關的事件。
  • WebSocketController: 一個控制器類,用于處理 HTTP 請求并使用 WebSocketUtils 類的方法。
  • ChatWebSocketHandler: 一個 WebSocket 處理器類,用于處理 WebSocket 事件。
  • WebSocketConfig: 配置類,用于注冊 WebSocket 處理器。

測試類實現:

WebSocketController

構建一個簡單的聊天應用程序,我們將使用 WebSocketUtils 來管理 WebSocket 會話并向用戶發送消息。 在這個示例中,我們將創建一個控制器來處理發送消息的請求,并使用 WebSocketUtils 類中的方法來實際發送消息。 首先,確保 WebSocketUtils 類已經被定義并包含了之前討論的方法。 接下來,我們將創建一個 WebSocketController 來處理發送消息的請求:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/*** @Author derek_smart* @Date 202/5/11 10:09* @Description WebSocket 測試類*/
@RestController
@RequestMapping("/chat")
public class WebSocketController {private final WebSocketUtils webSocketUtils;@Autowiredpublic WebSocketController(WebSocketUtils webSocketUtils) {  this.webSocketUtils = webSocketUtils;}// 發送消息給特定用戶@PostMapping("/send-to-user")public ResponseEntity<?> sendMessageToUser(@RequestParam String userIdentifier, @RequestParam String message) {try {webSocketUtils.sendMessageToUser(userIdentifier, message);return ResponseEntity.ok().build();} catch (IOException e) {// 日志記錄異常,返回錯誤響應return ResponseEntity.status(500).body("Failed to send message to user.");}}// 發送廣播消息給所有用戶@PostMapping("/broadcast")public ResponseEntity<?> broadcastMessage(@RequestParam String message) {webSocketUtils.sendMessageToAllUsers(message);return ResponseEntity.ok().build();}
}

在?WebSocketController?中,我們提供了兩個端點:一個用于向特定用戶發送消息,另一個用于廣播消息給所有連接的用戶。

?

ChatWebSocketHandler

現在,讓我們創建一個?WebSocketHandler?來處理 WebSocket 事件:

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;public class ChatWebSocketHandler extends TextWebSocketHandler {private final WebSocketUtils webSocketUtils;public ChatWebSocketHandler(WebSocketUtils webSocketUtils) {this.webSocketUtils = webSocketUtils;}@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {// 使用用戶的唯一標識符注冊會話String userIdentifier = retrieveUserIdentifier(session);webSocketUtils.registerSession(userIdentifier, session);}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 處理接收到的消息,例如在聊天室中廣播String userIdentifier = retrieveUserIdentifier(session);webSocketUtils.sendMessageToAllUsers("User " + userIdentifier + " says: " + message.getPayload());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {// 移除會話String userIdentifier = retrieveUserIdentifier(session);webSocketUtils.removeSession(userIdentifier);}private String retrieveUserIdentifier(WebSocketSession session) {// 根據實際情況提取用戶標識符,這里假設使用 WebSocketSession 的 IDreturn session.getId();}
}

在 ChatWebSocketHandler 中,我們處理了連接建立和關閉事件,并在這些事件發生時調用 WebSocketUtils 的方法注冊或移除會話。我們還實現了 handleTextMessage 方法來處理接收到的文本消息。

WebSocketConfig

最后,我們需要配置 WebSocket 端點:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {private final ChatWebSocketHandler chatWebSocketHandler;public WebSocketConfig(WebSocketUtils webSocketUtils) {this.chatWebSocketHandler = new ChatWebSocketHandler(webSocketUtils);}@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(chatWebSocketHandler, "/ws/chat").setAllowedOrigins("*");}
}

在 WebSocketConfig 配置類中,我們注冊了 ChatWebSocketHandler 到 /ws/chat 路徑。這樣,客戶端就可以通過這個路徑來建立 WebSocket 連接。

這個示例展示了如何使用 WebSocketUtils 工具類來管理 WebSocket 會話,并通過 REST 控制器端點發送消息。客戶端可以連接到 WebSocket 端點,并使用提供的 REST 端點發送和接收消息。

總結:

總的來說,WebSocket 在需要快速、實時、雙向通信的應用中提供了顯著的優勢,例如在線游戲、聊天應用、實時數據監控和協作工具。然而,不是所有的場景都需要 WebSocket 的能力,對于不需要實時通信的應用,傳統的 HTTP 請求或 HTTP 輪詢可能仍然是合適的。

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

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

相關文章

如何在MATALB中調用libMR

? 因為個人項目原因,我曾將參考OpenMax源碼GitHub - abhijitbendale/OSDN: Code and data for the research paper “Towards Open Set Deep Networks” A Bendale, T Boult, CVPR 2016將其轉換到MATLAB使用。 OpenMax 使用極值理論實現對開放集的篩選,在計算得分時需要用l…

異地組網群暉不能訪問怎么辦?

在日常使用群暉網絡儲存設備時&#xff0c;我們常常會遇到無法訪問的情況&#xff0c;特別是在異地組網時。這個問題很常見&#xff0c;但也很讓人困擾。本文將針對異地組網群暉無法訪問的問題進行詳細解答和分析。 異地組網的問題 在異地組網中&#xff0c;群暉設備無法訪問的…

Unity | Spine動畫動態加載

一、準備工作 Spine插件及基本知識可查看這篇文章&#xff1a;Unity | Spine動畫記錄-CSDN博客 二、Spine資源動態加載 1.官方說明 官方文檔指出不建議這種操作。但spine-unity API允許在運行時從SkeletonDataAsset或甚至直接從三個導出的資產實例化SkeletonAnimation和Skel…

被耽誤了的發明家

高三的某一天&#xff0c;數學焦老師在黑板上推公式&#xff0c;突然花屁股&#xff08;見另一篇博文《數學老師們》&#xff09;上出現了一個光圈。我心里一樂&#xff0c;有人在玩鏡子。本來大家對于焦老師的花屁股已經司空見慣了&#xff0c;可以不受干擾地聽課&#xff0c;…

HNU-算法設計與分析-作業3

第三次作業【動態規劃】 文章目錄 第三次作業【動態規劃】<1>算法實現題 3-1 獨立任務最優解問題<2>算法實現題 3-4 數字三角形問題<3>算法實現題 3-8 最小m段和問題<4>算法實現題 3-25 m處理器問題 <1>算法實現題 3-1 獨立任務最優解問題 ▲問…

postgresql安裝及性能測試

postgresql安裝及性能測試 1. Postgresql介紹 Postgresql是一款功能強大的開源對象關系型數據庫管理系統&#xff08;ORDBMS&#xff09;&#xff0c;以其穩定性、擴展性和標準的SQL支持而聞名。它支持復雜查詢、外鍵、觸發器、視圖、事務完整性、多版本并發控制&#xff08;MV…

Linux(七) 動靜態庫

目錄 一、動靜態庫的概念 二、靜態庫的打包與使用 2.1 靜態庫的打包 2.2 靜態庫的使用 三、動態庫的打包與使用 3.1 動態庫的打包 3.2 動態庫的使用 3.3 運行動態庫的四種方法 四、總makefile 一、動靜態庫的概念 靜態庫&#xff1a; Linux下&#xff0c;以.a為后綴的…

Python專題:十五、JSON數據格式

Python的數據處理&#xff1a;JOSN 計算機的主要工作&#xff1a;處理數據 最容易處理的數據就是結構化數據 非結構化數據&#xff1a;視頻&#xff0c;文件等 近些年的大數據、數據挖掘就是對互聯網中的各種非結構化的數據的分析和處理 半結構化數據 明確的結構屬性&…

陪診服務運用預約小程序的效果是什么

在中高型城市里&#xff0c;陪診師近些年也很有熱度&#xff0c;已經衍生成為一個新的小眾行業&#xff0c;不同醫院/不同科目等其它情況針對不同群體往往很難完善&#xff0c;比如部分老年人腿腳不便、不認識字、外地語言難以溝通等&#xff0c;陪診師的作用就尤為凸顯. 對相…

[Bootloader][uboot]code總結

文章目錄 1、U_BOOT_DRIVER2、DM框架dm_scan_platdatadm_extended_scan_fdt 1、U_BOOT_DRIVER 使用這個宏可以定義一個驅動實例&#xff0c;宏定義是 其中使用的struct driver結構體 使用的ll_entry_declare宏定義是 歸結為 2、DM框架 1、 DM框架 DM模型抽象出了以下四個…

16.投影矩陣,最小二乘

文章目錄 1. 投影矩陣1.1 投影矩陣P1.2 投影向量 1. 投影矩陣 1.1 投影矩陣P 根據上節知識&#xff0c;我們知道當我們在解 A X b AXb AXb的時候&#xff0c;發現當向量b不在矩陣A的列空間的時候&#xff0c;我們希望的是通過投影&#xff0c;將向量b投影到矩陣A的列空間中&…

ModuleNotFoundError: No module named ‘sklearn‘

ModuleNotFoundError: No module named sklearn 解決辦法&#xff1a; pip install scikit-learn

7B2 PRO主題5.4.2免授權直接安裝

B2 PRO 5.4.2 最新免授權版不再需要改hosts&#xff0c;直接在wordpress上傳安裝即可

網站接入百度云防護CDN后回源率非常高原因

最近&#xff0c;有站長反饋網站接入百度云防護后&#xff0c;網站回源率非常高。 今天百度云來給大家講解下&#xff0c;CDN回源高的原因&#xff1a; 1.動態請求比較多 網站的動態請求很多&#xff0c;一般是回源率高的主要原因&#xff0c;因為CDN對待動態請求是每個請求…

Vue的學習 —— <網絡請求庫Axios>

目錄 前言 正文 一、Axios基本概念 二、安裝Axios 三、Axios使用方法 四、向服務器發送請求 前言 在之前的開發案例中&#xff0c;我們通常直接在組件中定義數據。但在實際的項目開發中&#xff0c;我們需要從服務器獲取數據。當其他用戶希望訪問我們自己編寫的網頁時&a…

定檔 11.2-3,COSCon'24 第九屆中國開源年會暨開源社十周年嘉年華正式啟動!

中國開源年會 COSCon 是業界最具影響力的開源盛會之一&#xff0c;由開源社在2015年首次發起&#xff0c;今年將舉辦第九屆。 以其獨特定位及日益增加的影響力&#xff0c;COSCon 吸引了越來越多的國內外企業、高校、開源組織/社區的大力支持。與一般企業、IT 媒體、行業協會舉…

網絡安全快速入門(十三)linux及vmware軟件的網絡配置

13.1 前言 在通過我們前面的了解&#xff0c;我們現在已經對Linux的基礎知識有了大致的了解&#xff0c;今天我們來大概講一下關于linux系統及vmware的網絡配置問題&#xff0c;在這之前&#xff0c;我們需要對網絡有一個大概的認識和了解&#xff0c;話不多說&#xff0c;我們…

01記-“計算機基礎知識”

感覺媒體: 直接作用于人的感覺器官&#xff0c;使人產生直接感覺的媒體&#xff1a;聲音、圖形、圖像、動畫等。 表示媒體: 為了加工、處理和傳輸感覺媒體而人為研究、構造出來的一種媒體&#xff0c;常見的有各種編碼方式&#xff0c;如文本編碼、圖像編碼和聲音編碼等。 …

Java中靜態方法為什么不能調用非靜態成員?

在Java面試中&#xff0c;這個問題經常被問到&#xff0c;因為它不僅涉及到Java的基本語法規則&#xff0c;還深入到了JVM的工作機制。理解這個問題可以幫助面試者更好地掌握Java的靜態和非靜態成員的區別以及它們在內存中的分配和使用。 靜態成員 vs 非靜態成員 首先&#x…

AtCoder Beginner Contest 318 A題 Full Moon

A題&#xff1a;Full Moon 標簽&#xff1a;模擬、數學題意&#xff1a;給定一個起始 m m m和上限 n n n&#xff0c;每次增量 p p p&#xff0c;求能加幾次。題解&#xff1a;數據比較小&#xff0c;可以直接暴力&#xff1b;數學方法算的話&#xff0c;注意邊界。代碼&#…