java局域網聊天室小項目架構思路

java局域網聊天室小項目架構思路

項目需求

創建一個局域網聊天系統,要求:用戶在登錄界面登錄后進入聊天窗口界面,能實現多用戶同時在線聊天,并且用戶之間可以進行私聊

項目用到的技術棧

  1. java網絡編程
  2. java多線程
  3. java面向對象編程
  4. javaGUI技術(Swing)

第一步:創建項目并構建客戶端登錄界面與聊天窗口界面

創建項目

創建ChatRoom模塊用于存放整個項目,其下創建Chat-Client與Chat-Server兩個模塊分別用于客戶端與服務端的構建

登陸界面

登陸界面要有昵稱輸入框,用戶可輸入昵稱,輸入框下方有“登錄”和“取消”兩個按鈕,兩個按鈕要綁定事件監聽器,

登錄按鈕監測輸入框中是否有文字,是則點擊后關閉登錄窗口,否則提示輸入框不能為空,

取消按鈕一旦點擊則關閉登錄窗口

利用通義千問來輔助完成登錄界面

登錄界面代碼(初期)

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class ChatLoginUI extends JFrame implements ActionListener {// 定義界面組件private JLabel nicknameLabel;private JTextField nicknameField;private JButton loginButton;private JButton cancelButton;// 構造方法:初始化界面public ChatLoginUI() {// 設置窗口標題setTitle("聊天室登錄界面");// 設置窗口大小setSize(400, 200);// 設置窗口關閉操作(關閉窗口時退出程序)setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 設置窗口居中顯示setLocationRelativeTo(null);// 創建面板用于放置組件JPanel panel = new JPanel();panel.setLayout(new FlowLayout());// 創建昵稱標簽nicknameLabel = new JLabel("昵稱:");panel.add(nicknameLabel);// 創建昵稱輸入框nicknameField = new JTextField(20);panel.add(nicknameField);// 創建登錄按鈕loginButton = new JButton("登錄");loginButton.addActionListener(this); // 綁定事件監聽panel.add(loginButton);// 創建取消按鈕cancelButton = new JButton("取消");cancelButton.addActionListener(this); // 綁定事件監聽panel.add(cancelButton);// 將面板添加到窗口add(panel);// 設置窗口可見setVisible(true);}// 按鈕點擊事件處理@Overridepublic void actionPerformed(ActionEvent e) {if (e.getSource() == loginButton) {// 獲取輸入框內容String nickname = nicknameField.getText().trim();// 驗證昵稱是否為空if (nickname.isEmpty()) {JOptionPane.showMessageDialog(this, "昵稱不能為空!", "錯誤", JOptionPane.ERROR_MESSAGE);} else {// 顯示昵稱(示例:打印到控制臺)System.out.println("登錄成功,昵稱:" + nickname);// 這里可以添加跳轉到聊天室的邏輯dispose(); // 關閉登錄窗口}} else if (e.getSource() == cancelButton) {// 取消按鈕點擊事件:關閉窗口dispose();}}
}

聊天窗口界面

聊天窗口界面左側為聊天區右側實時展示當前登錄用戶下方為聊天輸入框和發送按鈕,當輸入文字后,點擊發送按鈕或者按下回車鍵即可發送消息到聊天區

借助通義千問來輔助完成

聊天窗口界面(初期)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class ChatRoom extends JFrame {private JTextArea chatTextArea;private JTextField messageField;private JButton sendButton;private JList<String> userList;private DefaultListModel<String> userListModel;public ChatRoom() {setTitle("Chat Room");setSize(800, 600);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);// 創建聊天區域chatTextArea = new JTextArea();chatTextArea.setEditable(false);JScrollPane chatScrollPane = new JScrollPane(chatTextArea);// 創建消息輸入框和發送按鈕JPanel inputPanel = new JPanel(new BorderLayout());messageField = new JTextField();sendButton = new JButton("Send");inputPanel.add(messageField, BorderLayout.CENTER);inputPanel.add(sendButton, BorderLayout.EAST);// 創建用戶列表userListModel = new DefaultListModel<>();userList = new JList<>(userListModel);JScrollPane userScrollPane = new JScrollPane(userList);// 設置布局JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, chatScrollPane, userScrollPane);splitPane.setDividerLocation(600);getContentPane().add(splitPane, BorderLayout.CENTER);getContentPane().add(inputPanel, BorderLayout.SOUTH);// 添加發送按鈕事件監聽器sendButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});// 按Enter鍵發送消息messageField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});}private void sendMessage() {String message = messageField.getText().trim();if (!message.isEmpty()) {chatTextArea.append("You: " + message + "\n");messageField.setText("");}}// 更新用戶列表的方法public void updateUserList(String[] users) {userListModel.clear();for (String user : users) {userListModel.addElement(user);}}
}

登錄窗口與聊天窗口正常啟動,第一步完成

第二步:構建局域網聊天室服務端

——先構建好服務器模塊,再依據服務端邏輯構建客戶端,因為服務端邏輯較為清晰簡潔——

1.創建服務器啟動端

  1. 由于聊天需要穩定傳輸,所以采用TCP通信方式
  2. 打印啟動日志表確認服務端啟動成功
  3. 循環監聽并捕獲客戶端鏈接請求,為每個請求啟動一個線程來處理(由于局域網通信人數少,并不會產生問題)

服務器啟動端代碼(初期)

package ServerTest;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;public class Server {public static void main(String[] args) {//創建服務器啟動端try {ServerSocket server = new ServerSocket(ConstantServer.SERVER_PORT);//打印啟動日志System.out.println("服務器啟動成功...");//循環監聽客戶端連接while (true) {Socket socket = server.accept();//啟動一個線程處理客戶端請求new ServerReaderThread(socket).start();}} catch (Exception e) {e.printStackTrace();}}
}

2.創建服務器處理端

  1. 由于所有請求處理是同時進行的,所以采用多線程
  2. 用戶發送來的消息包括1.登陸消息,2.群發消息,3.私聊消息
  3. 為每種消息設置標記進行區分,不同消息不同處理
  4. 客戶端下線處理

由于需要保存用戶信息,所以應該在服務器啟動端設置一個唯一數組用于存儲在線用戶昵稱在線用戶管道,由于具有映射關系所以采用Map數組

public static final Map<Socket,String> userMap = new HashMap<>();

服務器處理端代碼

package ServerTest;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Map;public class ServerReaderThread extends Thread{private Socket socket;public ServerReaderThread(Socket socket){this.socket = socket;}@Overridepublic void run(){//開發服務端實現方法//1.獲取客戶端輸入流try {DataInputStream dis = new DataInputStream(socket.getInputStream());//客戶端的信息包括1.登錄信息,2.群發消息,3.私聊消息while(true){int type = dis.readInt();switch (type) {case ConstantServer.LOGIN://登錄信息//獲取昵稱,并且更新當前用戶列表String nickname = dis.readUTF();Server.userMap.put(socket, nickname);updateUserList();break;case ConstantServer.GROUP_MESSAGE://群發消息String msg = dis.readUTF();String name = Server.userMap.get(socket);//設置群發消息方法groupMessage(msg,name);break;case ConstantServer.PRIVATE_MESSAGE://私聊消息String toName = dis.readUTF();String toMsg = dis.readUTF();privateMessage(toName,toMsg);}}} catch (Exception e) {System.out.println("客戶端下線:"+socket.getInetAddress().getHostAddress());Server.userMap.remove(socket);updateUserList();}}private void privateMessage(String toName, String toMsg) {//將私聊信息先進行封裝,再發送給指定客戶端的socket管道StringBuilder sb = new StringBuilder();String name = Server.userMap.get(socket);LocalDateTime now = LocalDateTime.now();DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");sb.append(name).append(" ").append(df.format(now)).append("\r\n").append(toMsg).append("\r\n");//如果對方不在線,則向發送消息的客戶端發送一個提示信息if(!Server.userMap.containsValue(toName)){try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantServer.PRIVATE_MESSAGE);dos.writeUTF("----對方不在線,請稍后再試----");return;} catch (Exception e) {e.printStackTrace();}}for(Socket socket:Server.userMap.keySet()){try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());if(Server.userMap.get(socket).equals(toName)){dos.writeInt(ConstantServer.PRIVATE_MESSAGE);dos.writeUTF(sb.toString());dos.flush();break;}} catch (Exception e) {e.printStackTrace();}}}private void groupMessage(String msg,String name) {//將群發消息轉發給所有在線客戶端Socket管道//封裝消息StringBuilder sb = new StringBuilder();LocalDateTime now = LocalDateTime.now();DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");sb.append(name).append(" ").append(df.format(now)).append("\r\n").append(msg).append("\r\n");//發送消息for (Socket socket:Server.userMap.keySet()) {try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantServer.GROUP_MESSAGE);dos.writeUTF(sb.toString());dos.flush();//及時刷新} catch (Exception e) {e.printStackTrace();}}}private void updateUserList() {//更新在線用戶列表//拿到所有在線客戶端用戶名稱,將這些數據轉發給全部在線客戶端Socket管道Collection<String> users = Server.userMap.values();for (Socket socket:Server.userMap.keySet()) {try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantServer.LOGIN);dos.writeInt(users.size());for(String user:users){dos.writeUTF(user);}dos.flush();} catch (Exception e) {e.printStackTrace();}}}}

3.服務端各種常量

由于IP與端口等可變,所以將所有可變常量存放在一個類中,便于修改

package ServerTest;public class ConstantServer {public static final String SERVER_IP = "127.0.0.1";public static final int SERVER_PORT = 8888;public static final int LOGIN = 1;public static final int GROUP_MESSAGE = 2;public static final int PRIVATE_MESSAGE = 3;
}

第三步:連接客戶端與服務端

1.完善登錄界面功能

  1. 實現登錄邏輯,將登錄信息發送給服務端
  2. 實現切換窗口邏輯

登陸界面代碼(完善后)

 @Overridepublic void actionPerformed(ActionEvent e) {if (e.getSource() == loginButton) {// 獲取輸入框內容String nickname = nicknameField.getText().trim();// 驗證昵稱是否為空if (nickname.isEmpty()) {JOptionPane.showMessageDialog(this, "昵稱不能為空!", "錯誤", JOptionPane.ERROR_MESSAGE);} else {// 實現登錄邏輯try {loginroom(nickname);} catch (Exception ex) {ex.printStackTrace();}// 這里可以添加跳轉到聊天室的邏輯new ChatRoomUI(nickname,socket);dispose(); // 關閉登錄窗口}} else if (e.getSource() == cancelButton) {// 取消按鈕點擊事件:關閉窗口dispose();}}private void loginroom(String nickname) throws Exception {//立即將登錄消息發送給服務器socket = new Socket(ConstantClient.SERVER_IP,ConstantClient.SERVER_PORT);DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantClient.LOGIN);dos.writeUTF(nickname);dos.flush();}

2.完善聊天窗口功能

  1. 創建一個客戶端接受信息類,用于接收服務端傳回的信息,1.更新用戶列表的消息,2.群發的消息,3.私聊的消息
  2. 將接收到的信息反映到用戶界面上

客戶端接受信息類

package UI;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;public class ClentReaderThread extends Thread{private Socket socket;private ChatRoomUI chatRoomUI;//每個管道對應一個界面private DataInputStream dis;public ClentReaderThread(Socket socket,ChatRoomUI chatRoomUI){this.socket = socket;this.chatRoomUI = chatRoomUI;}@Overridepublic void run(){try {dis = new DataInputStream(socket.getInputStream());//接受服務端發送的消息1.更新人數的消息,2.群發的消息,3.私聊的消息while(true){int type = dis.readInt();switch (type) {case ConstantClient.UPDATE_USERLIST://更新用戶列表updateUserList();break;case ConstantClient.GROUP_MESSAGE://群發消息gotoshowmsg();break;case ConstantClient.PRIVATE_MESSAGE://私聊消息gotoshowPrivatemsg();break;}}} catch (Exception e) {e.printStackTrace();}}//接收私聊消息方法private void gotoshowPrivatemsg() throws Exception {String msg = dis.readUTF();chatRoomUI.showPrivateMsg(msg);}//接收群發消息方法private void gotoshowmsg() throws Exception {String msg = dis.readUTF();chatRoomUI.showMsg(msg);}//接收更新的用戶列表方法private void updateUserList() throws Exception {int count = dis.readInt();String[] users = new String[count];for (int i = 0; i < count; i++) {users[i] = dis.readUTF();}chatRoomUI.updateUserList(users);}
}

聊天界面代碼(完善后)

新增雙擊私發消息的功能

package UI;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataOutputStream;
import java.net.Socket;public class ChatRoomUI extends JFrame {private JTextArea chatTextArea;private JTextField messageField;private JButton sendButton;private JList<String> userList;private DefaultListModel<String> userListModel;private Socket socket;private String nickname;public ChatRoomUI() {initFrame();setVisible(true);}public void initFrame(){setSize(800, 600);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);// 創建聊天區域chatTextArea = new JTextArea();chatTextArea.setEditable(false);JScrollPane chatScrollPane = new JScrollPane(chatTextArea);// 創建消息輸入框和發送按鈕JPanel inputPanel = new JPanel(new BorderLayout());messageField = new JTextField();sendButton = new JButton("Send");inputPanel.add(messageField, BorderLayout.CENTER);inputPanel.add(sendButton, BorderLayout.EAST);// 創建用戶列表userListModel = new DefaultListModel<>();userList = new JList<>(userListModel);JScrollPane userScrollPane = new JScrollPane(userList);// 設置布局JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, chatScrollPane, userScrollPane);splitPane.setDividerLocation(600);getContentPane().add(splitPane, BorderLayout.CENTER);getContentPane().add(inputPanel, BorderLayout.SOUTH);// 添加發送按鈕事件監聽器sendButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});// 按Enter鍵發送消息messageField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});// 添加用戶列表雙擊事件監聽器,用于私聊userList.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {// 判斷是否為雙擊事件if (e.getClickCount() == 2) {// 獲取選中的用戶索引int selectedIndex = userList.getSelectedIndex();if (selectedIndex != -1) {// 獲取選中的用戶名String selectedUser = userListModel.getElementAt(selectedIndex);// 不能給自己發私聊消息if (!selectedUser.equals(nickname)) {// 彈出輸入框,獲取私聊內容String privateMessage = JOptionPane.showInputDialog(ChatRoomUI.this,"發送私聊消息給 " + selectedUser + ":", "私聊", JOptionPane.PLAIN_MESSAGE);// 發送私聊消息if (privateMessage != null && !privateMessage.trim().isEmpty()) {sendPrivateMessage(selectedUser, privateMessage.trim());}} else {// 提示不能給自己發消息JOptionPane.showMessageDialog(ChatRoomUI.this, "不能給自己發送私聊消息", "提示", JOptionPane.WARNING_MESSAGE);}}}}});}public ChatRoomUI(String nickname, Socket socket) {this();setTitle(nickname+"的聊天窗口");this.nickname = nickname;this.socket = socket;new ClentReaderThread(socket,this).start();}//發送群發消息到服務器方法private void sendMessage() {String message = messageField.getText().trim();if (!message.isEmpty()) {//將消息發送給服務器try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantClient.GROUP_MESSAGE);dos.writeUTF(message);dos.flush();messageField.setText("");} catch (Exception e) {e.printStackTrace();}}}//發送私聊消息到服務器的方法private void sendPrivateMessage(String toUser, String message) {try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantClient.PRIVATE_MESSAGE);dos.writeUTF(toUser);dos.writeUTF(message);dos.flush();chatTextArea.append("[私聊給 " + toUser + "] " + message + "\n");} catch (Exception e) {e.printStackTrace();}}//展示更新用戶列表方法public void updateUserList(String[] users) {userListModel.clear();for (String user : users) {userListModel.addElement(user);}}//展示群發消息方法public void showMsg(String msg) {if (!msg.isEmpty()) {chatTextArea.append(msg + "\n");messageField.setText("");}}//展示私聊消息方法public void showPrivateMsg(String msg) {if (!msg.isEmpty()) {chatTextArea.append("[私聊] " + msg + "\n");}}
}

項目地址https://gitcode.com/2401_88685396/myfirstgitcodeofjava

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

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

相關文章

vulhub-corrosion2靶機

1.安裝靶機 https://download.vulnhub.com/corrosion/Corrosion2.ovahttps://download.vulnhub.com/corrosion/Corrosion2.ova 2.掃描IP 3.掃描端口 4.訪問端口 首先訪問一下80端口 訪問一個8080端口發現是一個apache的頁面 5.掃描目錄與漏洞探測 那么我們掃描一下目錄 80…

Mysql深入學習:慢sql執行

目錄 慢查詢日志 慢查詢主要步驟 11種慢查詢的場景分析 場景一&#xff1a;SQL 沒有建立索引 場景二&#xff1a;索引未生效的典型原因 場景三&#xff1a;LIMIT 深分頁導致性能下降 場景四&#xff1a;單表數據量過大導致 SQL 性能下降 場景五&#xff1a;ORDER BY 出現…

李宏毅深度學習教程 第8-9章 生成模型+擴散模型

【2025版】12 生成式對抗網絡GAN 一 – 基本概念介紹_嗶哩嗶哩_bilibili 目錄 1. GAN生成式對抗網絡 2. GAN的訓練 散度差異 3.WGAN 4.訓練GAN 5. 如何客觀評估GAN 6. 條件型生成&#xff08;按照要求&#xff09; 7. Cycle GAN&#xff08;互轉配對&#xff09; 8. d…

1.8 axios詳解

Axios的定義與核心特性Axios是一個基于Promise的現代化HTTP客戶端庫&#xff0c;主要用于在瀏覽器和Node.js 環境中發送HTTP請求&#xff0c;旨在簡化異步數據交互流程。其核心特性如下&#xff1a;跨平臺支持&#xff1a;在瀏覽器中通過XMLHttpRequest對象發送請求&#xff0c…

41.安卓逆向2-frida hook技術-過firda檢測(五)-利用ida分析app的so文件中frida檢測函數過檢測

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a;圖靈Python學院 工具下載&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取碼&#xff1…

安卓調javaScript Not find method “forceLogout“ implementatidsignature or namesp

核對一下是否實現對應的javaScript或者javaScript的方法參數對不對&#xff0c; 在這里插入圖片描述我這里一開始實現了這個方法但是沒有給參數&#xff0c;一直報異常&#xff0c;后臺說token沒給就查token的問題&#xff0c;最后發現是搞偏了&#xff0c;兩個原因&#xff0c…

【Linux網絡】:UDP(傳輸層協議)

目錄 一、鋪墊知識 1、傳輸層 2、端口號 2.1、五元組表示 一個進程通信 2.2、端口號范圍劃分 2.3、知名端口 2.4、查看端口號 2.5、問題 3、pidof & netstat 命令 ①netsate 命令 ②pidof命令 二、UDP協議 1、UDP協議格式 2、UDP報文 1.1、UDP數據封裝的過…

Effective C++ 條款19: 設計class猶如設計type

Effective C 條款19&#xff1a;設計class猶如設計type核心思想&#xff1a;設計新的class時&#xff0c;應當像語言設計者設計內置類型一樣慎重&#xff0c;考慮對象的創建、銷毀、初始化、拷貝、類型轉換等所有方面。 ?? 1. 類設計的關鍵問題域 對象生命周期管理&#xff1…

《匯編語言:基于X86處理器》第11章 MS-Windows編程(3)

本章展示的是如何用32 位Microsoft Windows API進行控制臺窗口編程。應用編程接口(API:ApplicationProgramming Interface)是類型、常數和函數的集合體&#xff0c;它提供了一種用計算機代碼操作對象的方式。本章將討論文本I/O、顏色選擇、時間與日期、數據文件I/O&#xff0c;…

在 macOS 上通過 Docker 部署DM8 (ARM 架構)

概述 達夢數據庫 (DM8) 無法直接在 Apple macOS 操作系統上原生安裝&#xff0c;通常需要通過虛擬機&#xff08;如 Parallels Desktop、VMware Fusion&#xff09;進行部署。另一種更輕量級且受 macOS 支持的方案是利用 Docker 容器技術來構建開發與測試環境。本文檔將詳細介…

網絡協議之路由是怎么回事?

寫在前面 要想去外面的世界看看, 就離不了路由器&#xff0c;而路由器工作的原理就是路由&#xff0c;那么具體是怎么路由的呢&#xff1f;本文就一起來看下這部分內容。 1&#xff1a;路由的配置 配置一條路由無非就是在配置以下三個信息&#xff1a; 1:包要去哪里&#x…

2106. 摘水果,梳理思路

文章目錄題目概要java 解法詳解題目概要 在一個無限的 x 坐標軸上&#xff0c;有許多水果分布在其中某些位置。給你一個二維整數數組 fruits &#xff0c;其中 fruits[i] [positioni, amounti] 表示共有 amounti 個水果放置在 positioni 上。fruits 已經按 positioni 升序排列…

深入理解消息隊列(MQ)核心原理與設計精髓

引言&#xff1a;從一個“不堪重負”的訂單系統說起想象一個簡化的電商下單流程&#xff1a;用戶點擊“下單”后&#xff0c;系統需要&#xff1a;在訂單數據庫中創建一條記錄。調用庫存服務&#xff0c;扣減商品庫存。調用營銷服務&#xff0c;給用戶發放積分和優惠券。調用通…

前端手撕題總結篇(算法篇——來自Leetcode牛客)

鏈表指定區域反轉 找到區間&#xff08;頭和為 for循環當**時&#xff09;->反轉鏈表&#xff08;返回反轉過后的頭和尾&#xff09;->連接 function reverseBetween( head , m , n ) {//preEnd&cur&nextStart cur.next斷開if(mn)return head;const vHeadNode…

從Excel到工時管理系統:企業如何選擇更高效的工時記錄工具?

還在為手工統計員工工時而頭疼嗎&#xff1f;月末堆積如山的Excel表格、反復核對的數據、層出不窮的差錯&#xff0c;這些問題正在拖慢企業的發展步伐。8Manage工時管理系統發現&#xff0c;傳統手工記錄不僅耗費大量人力&#xff0c;更讓寶貴的工時數據難以轉化為有效的管理決…

Java設計模式之《命令模式》

目錄 1、介紹 1.1、命令模式定義 1.2、對比 1.3、典型應用場景 2、命令模式的結構 2.1、組成部分&#xff1a; 2.2、整體流程 3、實現 3.1、沒有命令模式 3.2、命令模式寫法 4、命令模式的優缺點 前言 java設計模式分類&#xff1a; 1、介紹 1.1、命令模式定義 命…

【動態規劃算法】路徑問題

什么是動態規劃算法動態規劃&#xff08;Dynamic Programming&#xff0c;簡稱 DP&#xff09;是一種通過分解復雜問題為重疊子問題&#xff0c;并存儲子問題的解以避免重復計算&#xff0c;從而高效求解具有特定性質&#xff08;重疊子問題、最優子結構&#xff09;問題的算法…

Java基本技術講解

一、基礎語法三要素 暫時無法在飛書文檔外展示此內容 &#x1f511; 黃金法則?&#xff1a;每個變量都要聲明類型&#xff01;二、程序邏輯控制&#xff08;游戲行為核心&#xff09; 條件判斷&#xff1a;if-else - “岔路口選擇” // 撿到金幣邏輯 if (isTouching(Coin.clas…

【網絡基礎2】路由器的 “兩扇門”:二層接口和三層接口到底有啥不一樣?

目錄 前言:路由器不是只有 “插網線的口” 一、先搞懂一個基礎:路由器是 “網絡交通樞紐” 二、二層接口:“小區內部的單元門”,只認 “住戶身份證” 1. 啥是二層接口? 2. 用 “小區內部串門” 理解二層接口 步驟 1:手機打包數據,寫上 “收件人身份證” 步驟 2:二…

MLIR TableGen

簡介 TableGen 是一種領域特定語言&#xff08;DSL&#xff09;&#xff0c;TableGen 的設計目標是允許編寫靈活的描述&#xff0c;并將記錄的通用特性提取出來&#xff0c;從而減少重復代碼并提高代碼的可維護性。 TableGen的工作流程&#xff1a; 前端解析&#xff1a; Ta…