主頁 > 軟體設計 > 【JavaLearn】 #(14)網路及分類、TCP、UDP協議、IP、Socket、TCP編程、UDP編程

【JavaLearn】 #(14)網路及分類、TCP、UDP協議、IP、Socket、TCP編程、UDP編程

2021-09-19 09:43:30 軟體設計

1. 網路基本概念

1.1 計算機網路

定義:是指將地理位置不同的具有獨立功能(沒有網路可以獨立存在的)的多臺計算機及其外部設備,通過通信線路連接起來,在網路作業系統,網路管理軟體及網路通信協議的管理和協調下,實作資源共享和資訊傳遞的計算機系統

  • 主干:計算機網路是計算機系統
  • 網路功能:資源共享、資訊傳遞
  • 網路組成
    • 網路硬體:計算機、外部設備、通信連接
    • 網路軟體:網路作業系統、網路管理軟體、網路通信協議

分類–按照規模

  • 局域網 LAN
  • 城域網 MAN
  • 廣域網 WAN

分類–按照傳輸介質

  • 同軸電纜網路(類似于有線電視網的電纜)

  • 雙絞線網路

  • 光纖網路(傳輸的為光信號

  • 衛星網路

分類–拓撲結構

  • 星形網路(最常使用)

  • 總線網路:信號在傳遞程序中都能收到,辨別是自己的則接收

  • 環狀網路:同樣的傳遞方式

1.2 網路通信協議

在網路中實作通信,必須要有一些約定(通信協議),對速率、傳輸代碼、傳輸控制步驟等指定標準(好比交通規則)

問題:網路通信涉及內容很多:源地址、目標地址、加密解密、流量控制、路由控制等,如何實作如此復雜的網路協議?

===》分層:將復雜的成份分解成一些簡單的成份,再將它們復合起來(同層間可以通信、上一層可以呼叫下一層,而不與再下一層發生關系)

網路通信協議分層

  • 名義上的標準:ISO --> OSI 參考模型
  • 事實上的標準:TCP/IP協議堆疊

資料的封裝與拆封:在傳輸程序中,經過每一層,都需要添加各種資料,最終發送到另一端,另一端再拆解這些資料

1.3 TCP/IP協議堆疊

網路通信最常采用的協議

  • 網路層主要協議:IP協議
  • 傳輸層主要協議:TCP 和 UDP 協議

1.4 TCP協議

面向連接的、可靠的、基于位元組流的傳輸層通信協議(打電話的案例)

  • 面向連接(一段資訊分段后發送,發送順序和接收順序一致
  • 點到點的通信
  • 高可靠性:三次握手
  • 占用系統資源多、效率低

應用案列:HTTP、FTP、Telnet、SMTP

1.5 UDP協議

無連接的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務(發電報、發送群發短信)

  • 非面向連接,傳輸不可靠,可能丟失(一段資訊分段后發送,不一定哪一段先到達
  • 發送不管對方是否準備好,接收方收到后也不回復
  • 可以廣播發送
  • 非常簡單的協議,開銷少

應用案例:DNS、SNMP

1.6 IP地址和埠

IP地址,用來標志網路中的一個通信物體(計算機、路由器)的地址

分類

  • IPV4:32位地址,點分十進制表示,如192.168.0.1
  • IPV6:128位寫個8個16位的無符號整數,每個整數用4個十六進制位標識,數之間用 : 分割

特殊的 IP 地址

  • 127.0.0.1:本機地址
  • 192.168.0.0 – 192.168.255.255 私有地址,專門為組織機構內部使用

埠(port)

  • IP地址用來標志一臺計算機,但一個計算機可以提供多種應用程式,使用來區分應用程式
  • 范圍:0 – 65535(16位整數)

埠分類

  • 0 – 1023 :公認埠(比如 80給了 WWW,21給了 FTP等)
  • 1024 – 49151:注冊埠(分配給用戶或應用程式)
  • 49152 – 65535:動態/私有埠

IP和埠API

  • InetAddress 類:封裝計算機的 ip地址,沒有埠
  • InetSocketAddress:包含埠,用于 socket 通信

1.7 URL 統一資源定位符

Uniform Resource Locator:由 4部分組成:協議存放資源的主機域名埠號資源檔案名

image-20210906235312991

1.8 Socket 套接字

Socket實際是傳輸層供給應用層的編程介面

image-20210906235703863

類似于寄信:用戶(應用層)將信(資料)投入郵筒即可(郵筒的口,就是socket),進入Socket之后,怎么送信就是郵局、公路交管(傳輸層、網路層)等的事,

2. 網路編程常用類

2.1 封裝IP地址 – InetAddress

// 1.獲取 IP地址
InetAddress ia = InetAddress.getLocalHost();  // 本機的 ip

// 2.操作 IP地址
System.out.println(ia);  // DESKTOP-F31QQ1H/192.168.0.102
System.out.println(ia.getHostAddress()); // 192.168.0.102
System.out.println(ia.getHostName()); // DESKTOP-F31QQ1H

InetAddress ia2 = InetAddress.getByName("www.lwclick.com");  // 通過域名獲取ip
System.out.println(ia2);

2.2 封裝 IP 和 Port – InetSocketAddress

// 創建一個 InetSocketAddress 物件
InetSocketAddress isa = new InetSocketAddress("www.lwclick.com", 8888);

// 獲取物件內容
System.out.println(isa);  // www.lwclick.com/104.21.41.202:8888
System.out.println(isa.getAddress());  // www.lwclick.com/104.21.41.202
System.out.println(isa.getPort());  // 8888

2.3 URL類

// 創建一個 URL   協議:https    域名/IP地址:lwclick.com    埠:80     路徑:/categories/MySQL/
URL url = new URL("https://lwclick.com:80/categories/MySQL/");

// 獲取 URL 各個組成部分
System.out.println(url.getProtocol());  //  https
System.out.println(url.getHost());  //  lwclick.com
System.out.println(url.getPort());  //  80
System.out.println(url.getDefaultPort());  //  443 默認的 https 埠
System.out.println(url.getPath());  //  /categories/MySQL/

3. TCP編程

3.1 一次單向通信

  • 服務器端

    • 創建 ServerSocket,在指定埠監聽(accept()方法)

      并處理請求(如果客戶端請求到來,回傳對應的Socket,否則的話一直等待,執行緒也被阻塞)

  • 客戶端

    • 創建 Socket,需要指定服務器的 ip 和埠號,向服務器發送和接收回應
  • 發送資料

    • 需要使用輸出流(OutputStream),可以通過 DataOutputStream 和 ObjectOutputStream 進行包裝,提高效率
  • 接收資料

    • 使用輸入流(InputStream),使用 DataInputStream 和 ObjectInputStream 進行包裝
image-20210914224738599

服務器端

public class LoginServer {
    public static void main(String[] args) throws IOException {
        // 1.創建一個 ServerSocket,配置監聽埠
        ServerSocket serverSocket = new ServerSocket(8080);

        // 2.使用 ServerSocket 在指定埠監聽
        Socket socket = serverSocket.accept(); // 請求不到,在此阻塞;  請求到了,回傳一個socket,繼續執行

        // 3.接收客戶端的請求資料,輸出結果
        InputStream is = socket.getInputStream(); // 獲取流
        DataInputStream dis = new DataInputStream(is); // 同樣使用資料流進行包裝
        String info = dis.readUTF(); // 讀取對應型別的寫入的資料
        System.out.println("客戶端的請求:" + info);

        // 4.關閉資源
        dis.close();
        serverSocket.close();
    }
}

客戶端

public class LoginClient {
    public static void main(String[] args) throws IOException {
        // 1.創建一個 Socket,指明服務器端ip和埠
        Socket socket = new Socket(InetAddress.getLocalHost(), 8080); // InetAddress.getByName()獲取ip

        // 2.發送資料給服務器端
        OutputStream os = socket.getOutputStream(); // 資訊通過流發送,輸出流
        DataOutputStream dos = new DataOutputStream(os); // 資料流進行包裝
        dos.writeUTF("userName=lwclick&pwd=123");

        // 3.關閉資源
        dos.close(); // 關閉高層流,低層自動關閉
    }
}

注意:測驗時,服務器端需要先啟動,然后再啟動客戶端

3.2 一次雙向通信

服務器端

public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = new ServerSocket(8080);
    Socket socket = serverSocket.accept(); 
    InputStream is = socket.getInputStream();
    DataInputStream dis = new DataInputStream(is);
    String info = dis.readUTF(); 
    System.out.println("客戶端的請求:" + info);

    // ============================== 向客戶端發送資料 =====================================
    // 4. 給客戶端一個回應
    OutputStream os = socket.getOutputStream(); // 此處的socket為接收的客戶端的回應
    DataOutputStream dos = new DataOutputStream(os);
    dos.writeUTF("登錄成功,歡迎!");

    // 5.關閉資源
    dos.close();
    dis.close();
    serverSocket.close();
}

客戶端

public static void main(String[] args) throws IOException {
    Socket socket = new Socket(InetAddress.getL ocalHost(), 8080);
    OutputStream os = socket.getOutputStream();
    DataOutputStream dos = new DataOutputStream(os);
    dos.writeUTF("userName=lwclick&pwd=123");

    // ============================== 接收服務器端反饋 =====================================
    // 3.接收服務器端回應,并輸出
    InputStream is = socket.getInputStream();
    DataInputStream dis = new DataInputStream(is);
    String info = dis.readUTF();
    System.out.println("服務器端的回應:" + info);

    // 4.關閉資源
    dis.close();
    dos.close();
}

3.3 傳輸物件

User 類在網路上傳輸,類一定要實作序列化介面

public class User implements Serializable {
    private String userId;
    private String password;
    
    // getter / setter / toString / constructor
}

服務器端

public static void main(String[] args) throws IOException, ClassNotFoundException {
    ServerSocket serverSocket = new ServerSocket(8080);
    Socket socket = serverSocket.accept(); 
    InputStream is = socket.getInputStream(); 
    
    // =============== 此處使用【物件流】接收資料 ===================
    ObjectInputStream ois = new ObjectInputStream(is); 
    User user = (User)ois.readObject(); 
    System.out.println("客戶端的請求:" + user);
    
    OutputStream os = socket.getOutputStream(); 
    DataOutputStream dos = new DataOutputStream(os);
    if (user.getUserId().indexOf("lwclick") >= 0 && user.getPassword().length() > 6) {
        dos.writeUTF("登錄成功,歡迎!");
    } else {
        dos.writeUTF("登錄失敗,請重試!");
    }

    dos.close();
    ois.close();
    serverSocket.close();
}

客戶端

public static void main(String[] args) throws IOException {
    Socket socket = new Socket(InetAddress.getLocalHost(), 8080);

    // 獲取用戶輸入
    Scanner sc = new Scanner(System.in);
    System.out.print("userId:  ");
    String userId = sc.next();
    System.out.print("password:  ");
    String password = sc.next();
    User user = new User(userId, password);

    OutputStream os = socket.getOutputStream();
    // 【物件流】進行包裝
    ObjectOutputStream oos = new ObjectOutputStream(os); 
    oos.writeObject(user);

    InputStream is = socket.getInputStream();
    DataInputStream dis = new DataInputStream(is);
    String info = dis.readUTF();
    System.out.println("服務器端的回應:" + info);

    dis.close();
    oos.close();
}

3.4 引入多執行緒

將服務器端接到請求后的處理步驟,放到執行緒的 run()方法 中,每過來一個請求,就創建一個執行緒去執行

執行緒類

public class LoginThread extends Thread {
    private Socket socket;

    public LoginThread() {
    }
    
    public LoginThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        DataOutputStream dos = null;
        ObjectInputStream ois = null;
        try {
            InputStream is = socket.getInputStream();
            ois = new ObjectInputStream(is);
            User user = (User)ois.readObject();
            System.out.println("客戶端的請求:" + user);

            OutputStream os = socket.getOutputStream();
            dos = new DataOutputStream(os);
            if (user.getUserId().indexOf("lwclick") >= 0 && user.getPassword().length() > 6) {
                dos.writeUTF("登錄成功,歡迎!");
            } else {
                dos.writeUTF("登錄失敗,請重試!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (dos != null) {
                    dos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

服務器端為每一個登錄請求,創建一個執行緒來處理

public static void main(String[] args) throws IOException, ClassNotFoundException {
    ServerSocket serverSocket = new ServerSocket(8080);

    int i = 1;
    while (true) {
        Socket socket = serverSocket.accept();
        
        // 為每一個登錄請求,創建一個執行緒來處理
        new LoginThread(socket).start();

        // 統計客戶端的IP地址和總的請求次數
        InetAddress ia = socket.getInetAddress();
        System.out.println("這是第" + (i++) + "個請求,對方的IP地址是:" + ia.getHostAddress());
    }
}

客戶端:(無需改變)

public static void main(String[] args) throws IOException {
    Socket socket = new Socket(InetAddress.getLocalHost(), 8080);

    // 獲取用戶輸入
    Scanner sc = new Scanner(System.in);
    System.out.print("userId:  ");
    String userId = sc.next();
    System.out.print("password:  ");
    String password = sc.next();
    User user = new User(userId, password);

    OutputStream os = socket.getOutputStream();
    // 【物件流】進行包裝
    ObjectOutputStream oos = new ObjectOutputStream(os); 
    oos.writeObject(user);

    InputStream is = socket.getInputStream();
    DataInputStream dis = new DataInputStream(is);
    String info = dis.readUTF();
    System.out.println("服務器端的回應:" + info);

    dis.close();
    oos.close();
}

4. UDP編程

無連接的,客戶與咨詢師的在線交流

  • 使用基于 UDP 協議的 Socket 網路編程實作
  • 不需要使用 IO 流實作資料的傳輸
  • 每個資料發送單元被統一封裝成資料包(ip,介面,資料等)的方式,發送方將資料發到網路上,資料包在網路上尋找它要去的目的地

需要使用的類

  • DatagramSocket:用于發送或接收資料包
  • DatagramPacket:資料包

4.1 一次單向通信

客戶端

public static void main(String[] args) throws IOException {
    // 1.創建一個 Socket,用來發送和接收資料包
    DatagramSocket socket = new DatagramSocket(9999); // 客戶端監聽的介面

    // 2.使用 socket 發送一個資料包
    String str = "親,在嗎";
    byte[] buf = str.getBytes();
    InetAddress ia = InetAddress.getLocalHost();
    int port = 8888; // 服務器端接收資料的埠號
    DatagramPacket packet = new DatagramPacket(buf, buf.length, ia, port);
    // 發送資料包
    socket.send(packet);

    // 3.關閉 socket
    socket.close();
}

服務器端

public static void main(String[] args) throws IOException {
    // 1.創建一個 Socket,用來發送和接收資料包
    DatagramSocket socket = new DatagramSocket(8888);  // 服務器端監聽的介面

    // 2.使用 socket 接收一個資料包
    byte[] buf = new byte[128];
    DatagramPacket packet = new DatagramPacket(buf, buf.length);
    socket.receive(packet); // ip,port等資訊
    System.out.println(new String(packet.getData(), 0, packet.getLength()));
    System.out.println(packet.getAddress());
    System.out.println(packet.getPort());

    // 3.關閉 socket
    socket.close();
}

4.2 多次雙向通信

客戶端

public static void main(String[] args) throws IOException {
    // 1.創建一個 Socket,用來發送和接收資料包
    DatagramSocket socket = new DatagramSocket(9999); // 客戶端監聽的介面
    Scanner sc = new Scanner(System.in);
    while (true) {
        String line = sc.nextLine();
        // 2.使用 socket 發送一個資料包
        byte[] buf = line.getBytes();
        InetAddress ia = InetAddress.getLocalHost();
        int port = 8888; // 服務器端接收資料的埠號
        DatagramPacket packet = new DatagramPacket(buf, buf.length, ia, port);
        // 發送資料包
        socket.send(packet);

        // 如果客戶端輸入 bye,結束對話
        if ("bye".equals(line)) {
            break;
        }

        // 接收服務器端回傳的訊息
        byte[] bytes = new byte[128];
        DatagramPacket packetReceive = new DatagramPacket(bytes, bytes.length);
        socket.receive(packetReceive);
        System.out.println(new String(packetReceive.getData(), 0, packetReceive.getLength()));
    }

    // 3.關閉 socket
    socket.close();
}

服務器端

public static void main(String[] args) throws IOException {
    // 1.創建一個 Socket,用來發送和接收資料包
    DatagramSocket socket = new DatagramSocket(8888); // 服務器端監聽的介面
    Scanner sc = new Scanner(System.in);

    while (true) {
        // 2.使用 socket 接收一個資料包
        byte[] buf = new byte[128];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);
        socket.receive(packet); // ip,port等資訊
        String info = new String(packet.getData(), 0, packet.getLength());
        System.out.println(info);
        if ("bye".equals(info)) {
            break;
        }

        // 使用 socket 給客戶端發送一個資料包
        String str = sc.nextLine();
        byte[] bytes = str.getBytes();
        InetAddress address = packet.getAddress(); // 發送資料的客戶端地址
        int port = packet.getPort(); // 埠號
        DatagramPacket sendPacket = new DatagramPacket(bytes, bytes.length, address, port);
        socket.send(sendPacket);
    }

    // 3.關閉 socket
    socket.close();
}

5. 檔案上傳

使用 TCP編程 實作檔案上傳功能

  • 思路:進行兩次檔案的復制
    • 【客戶端】將檔案從【本地】復制到【網路】
    • 【服務端】將檔案從【網路】復制到【本地】

image-20210916235926621

客戶端

public class UploadClient {
    public static void main(String[] args) throws IOException {
        // 創建一個 socket,指明服務器端ip 和監聽埠
        Socket socket = new Socket(InetAddress.getLocalHost(), 8800);

        // ======================== 上傳檔案到服務端的目的埠 ===========================
        // 本機的源檔案
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("e:/readme.txt")); 
        // 將檔案寫到目的服務器埠的位置
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); 

        byte[] buf = new byte[1024];
        int len = bis.read(buf);
        while (len != -1) {
            bos.write(buf, 0, len);
            len = bis.read(buf);
        }

        bos.close();
        bis.close();
    }
}

服務器端

public class UploadServer {
    public static void main(String[] args) throws IOException {
        // 創建一個 ServerSocket
        ServerSocket serverSocket = new ServerSocket(8800);

        // 使用 ServerSocket 在指定埠監聽
        Socket socket = serverSocket.accept();

        // ===================== 從目的埠取檔案 ========================
        // 從目的埠取內容
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); 
        // 保存到服務器的本地
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:/readme2.txt")); 

        byte[] buf = new byte[1024];
        int len = bis.read(buf);
        while (len != -1) {
            bos.write(buf, 0, len);
            len = bis.read(buf);
        }

        bos.close();
        bis.close();
    }
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/301250.html

標籤:其他

上一篇:原生PHP、Laravel、MIXPHP、Go高并發性能測驗QPS

下一篇:Kubernetes應用Pod固定IP之kruise

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more