TCP(Transmission Control Protocol)是一種面向連線的可靠的傳輸協定。類似於打電話,它通過建立一個連線和保證資料的可靠傳輸來提高通訊的可靠性。然而,由於要確保資料的可靠性,TCP協定會增加網路負擔,效率相對較低。
UDP(User Datagram Protocol)是一種無連線、不可靠的傳輸協定。類似於廣播,UDP協定可以實現一對多的通訊,且由於沒有連線的建立和資料的確認,所以傳輸效率相對較高。然而,由於缺乏連線和確認機制,UDP的可靠性較差。
在瞭解TCP和UDP之後,常見的面試題包括TCP的三次握手和四次揮手。為什麼要採用三次握手而不是兩次握手呢?這是因為網路傳輸本身具有不穩定性,例如網路超時和網路阻塞等問題。如果只進行兩次握手,當伺服器端返回第二次握手給使用者端後,無法確定使用者端是否成功建立連線。因此,必須進行第三次握手,以確保使用者端接收到了連線請求。否則,如果使用者端由於網路原因導致丟失了此次連線請求,伺服器將一直等待該連線的空閒超時才會關閉請求,這將嚴重消耗伺服器資源。
四次揮手也是類似於三次握手的原因。由於網路傳輸的不穩定性,斷開連線時需要確保雙方都收到斷開請求。在四次揮手中,首先使用者端傳送斷開連線請求,然後伺服器端傳送確認收到請求的訊息,接著伺服器端傳送斷開連線請求,最後使用者端傳送確認收到請求的訊息,完成連線的斷開。這樣可以確保雙方都能正確處理斷開連線的操作。
BIO是最簡單的一種I/O模型,它採用同步阻塞方式進行通訊。每個使用者端連線都需要獨立的執行緒進行處理,當有大量的並行請求時,執行緒數量會急劇增加,導致資源消耗增加,效能下降。
NIO是相對複雜的一種I/O模型,它使用了Channel、Selector和Buffer來實現非阻塞的通訊。通過Selector的多路複用機制,可以使用一個執行緒處理多個使用者端連線,從而提高並行能力。但是,NIO適合處理短請求,如果長時間佔用I/O,可能會導致伺服器資源耗盡。
以下是使用NIO實現一個簡單的伺服器範例:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class NioServerExample {
public static void main(String[] args) throws IOException {
// 建立ServerSocketChannel,並繫結埠
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
// 建立Selector,並將ServerSocketChannel註冊到Selector上
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 監聽事件
selector.select();
// 處理事件
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (key.isAcceptable()) {
// 接受使用者端連線
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
// 讀取使用者端資料
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
// 使用者端關閉連線
socketChannel.close();
} else {
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
String message = new String(data);
System.out.println("Received message: " + message);
// 響應使用者端
ByteBuffer responseBuffer = ByteBuffer.wrap("Hello, client!".getBytes());
socketChannel.write(responseBuffer);
}
}
}
}
}
}
AIO相對於NIO來說簡單一些,但是由於底層需要作業系統的支援,所以應用範圍相對較小。AIO是非同步非阻塞的I/O模型,在NIO的基礎上,通過另外的執行緒來處理業務的返回值,從而實現非同步操作。
JAVA NIO的核心元件包括緩衝區(buffer)、通道(channel)和選擇器(selector)。
通過這些核心元件,JAVA NIO模型實現了高效的非阻塞I/O操作,提升了伺服器的並行處理能力。
select、poll和epoll是Linux系統中的三種I/O多路複用機制。它們的目的是為了實現高效的事件驅動程式設計,以便在多個I/O操作中選擇可讀、可寫或異常事件。
檔案描述符是維護程序開啟檔案的記錄表。每個開啟的檔案都會被分配一個唯一的檔案描述符。
安全性:
埠號:
證書:
HTTPS協定增加了伺服器和使用者端之間的計算和通訊負擔,使得伺服器在處理大量請求時更容易受到壓力。雖然HTTPS可以提供一定程度的安全保護,但也會增加伺服器的負擔,使得伺服器更容易受到DDoS攻擊。
通過深入探索Java通訊面試的奧祕,我們將揭祕Java中的三種I/O模型(BIO、NIO和AIO)、選擇器(select、poll和epoll)以及網路協定(如HTTP和HTTPS),幫助您瞭解在面試中必備的知識點。這些知識點對於網路程式設計和系統安全方面的求職者來說至關重要,掌握它們將為您的職業發展打下堅實的基礎!