百度一面,頂不住
撈撈面經(jīng)
題目來源:https://www.nowcoder.com/feed/main/detail/d39aabc0debd4dba810b4b9671d54348
注:養(yǎng)成先看真題,自己模擬回答,再看解析參考(別忘隨手一鍵三連哦~)
1.基礎(chǔ)題
- 有幾種網(wǎng)絡(luò)io模型?
- 異步網(wǎng)絡(luò)模型在什么場(chǎng)景下你了解有應(yīng)用過?(回答了線程相關(guān)的場(chǎng)景)
- 除了用線程完成,還有什么操作可以完成異步操作?
- 同步阻塞和同步非阻塞在Java層面怎么實(shí)現(xiàn)?(說前面網(wǎng)絡(luò)io模型答得挺順暢,具體實(shí)現(xiàn)細(xì)節(jié)還需要提升一下)
- 描述一下一次完整的 Http 請(qǐng)求
- 知道的長連接有幾種實(shí)現(xiàn)方式?
- 一個(gè) Http 請(qǐng)求包含哪幾部分內(nèi)容?
2.代碼題
- 設(shè)計(jì)一個(gè) HashSet(完全不會(huì))
3.場(chǎng)景題
- 1T 的數(shù)據(jù)怎么加載到 200M 的內(nèi)存中,并且找到兩行一樣的數(shù)據(jù)?
- Java 打開 1T 文件,第一部操作做什么?
- 用代碼打開一個(gè)文件和用鼠標(biāo)打開一個(gè)文件有什么區(qū)別?
注意:博主基礎(chǔ)題即不過多介紹,只選經(jīng)典題目分析。
你了解哪些網(wǎng)絡(luò) IO 模型?
常見的網(wǎng)絡(luò)IO模型有以下幾種:
- 阻塞式IO模型(Blocking IO Model):在這種模型中,當(dāng)一個(gè)線程執(zhí)行一個(gè) IO 操作時(shí),它會(huì)一直阻塞,直到 IO 操作完成。
- 非阻塞式IO模型(Non-Blocking IO Model):在這種模型中,當(dāng)一個(gè)線程執(zhí)行一個(gè)IO操作時(shí),它不會(huì)一直阻塞,而是會(huì)立即返回,告訴調(diào)用者 IO 操作是否完成。
- 多路復(fù)用IO模型(Multiplexed IO Model):一個(gè)線程可以同時(shí)監(jiān)視多個(gè) IO 操作,當(dāng)有一個(gè) IO 操作完成時(shí),它會(huì)通知線程進(jìn)行處理。
- 信號(hào)驅(qū)動(dòng)式IO模型(Signal Driven IO Model):在這種模型中,當(dāng)一個(gè) IO 操作完成時(shí),操作系統(tǒng)會(huì)向應(yīng)用程序發(fā)送一個(gè)信號(hào),應(yīng)用程序在接收到信號(hào)后進(jìn)行處理。
- 異步IO模型(Asynchronous IO Model):應(yīng)用程序發(fā)起一個(gè) IO 操作后,不需要等待操作完成,而是可以繼續(xù)執(zhí)行其他操作,當(dāng) IO 操作完成后,操作系統(tǒng)會(huì)通知應(yīng)用程序進(jìn)行處理。
異步網(wǎng)絡(luò)模型你在什么場(chǎng)景下使用過,具體可以應(yīng)用到哪些地方?
- 高并發(fā)的Web應(yīng)用程序:在Web應(yīng)用程序中,異步網(wǎng)絡(luò)模型可以提高服務(wù)器的并發(fā)處理能力,減少線程的阻塞等待時(shí)間,提高系統(tǒng)的吞吐量。
- 高性能的網(wǎng)絡(luò)服務(wù)器:在網(wǎng)絡(luò)服務(wù)器中,異步網(wǎng)絡(luò)模型可以提高服務(wù)器的并發(fā)處理能力,減少線程的阻塞等待時(shí)間,提高系統(tǒng)的吞吐量。
- 大規(guī)模的實(shí)時(shí)數(shù)據(jù)處理系統(tǒng):在實(shí)時(shí)數(shù)據(jù)處理系統(tǒng)中,異步網(wǎng)絡(luò)模型可以提高數(shù)據(jù)的處理效率,減少數(shù)據(jù)處理的延遲時(shí)間,提高系統(tǒng)的實(shí)時(shí)性。
- 大規(guī)模的分布式系統(tǒng):在分布式系統(tǒng)中,異步網(wǎng)絡(luò)模型可以提高系統(tǒng)的并發(fā)處理能力,減少線程的阻塞等待時(shí)間,提高系統(tǒng)的吞吐量。
異步網(wǎng)絡(luò)模型可以應(yīng)用于任何需要高并發(fā)、高性能、高實(shí)時(shí)性的場(chǎng)景,以提高系統(tǒng)的性能和可擴(kuò)展性,提高用戶體驗(yàn)。
能結(jié)合具體業(yè)務(wù)場(chǎng)景舉個(gè)例嗎?
異步網(wǎng)絡(luò)模型在社交和購物等場(chǎng)景下也非常常見。比如:
- 社交應(yīng)用程序:在社交應(yīng)用程序中,異步網(wǎng)絡(luò)模型可以用于處理用戶的聊天消息、動(dòng)態(tài)更新等請(qǐng)求,提高系統(tǒng)的實(shí)時(shí)性和性能。
- 購物網(wǎng)站:在購物網(wǎng)站中,異步網(wǎng)絡(luò)模型可以用于處理用戶的訂單、支付、物流等請(qǐng)求,提高系統(tǒng)的并發(fā)處理能力和性能。
舉個(gè)具體實(shí)際的例子,常常玩的 王者榮耀。(個(gè)人看法)它需要處理大量的游戲玩家請(qǐng)求,包括登錄、注冊(cè)、查詢游戲數(shù)據(jù)、游戲操作等。如果使用阻塞式IO模型,每個(gè)請(qǐng)求都需要?jiǎng)?chuàng)建一個(gè)線程來處理,當(dāng)并發(fā)請(qǐng)求量較大時(shí),線程的創(chuàng)建和銷毀會(huì)帶來很大的開銷,導(dǎo)致服務(wù)器的性能和吞吐量下降。
而如果使用異步網(wǎng)絡(luò)模型,可以通過 事件驅(qū)動(dòng)的方式處理請(qǐng)求,當(dāng)有玩家請(qǐng)求到達(dá)時(shí),服務(wù)器不需要?jiǎng)?chuàng)建新的線程,而是通 過異步IO操作來處理請(qǐng)求,當(dāng)IO操作完成后,服務(wù)器會(huì)回調(diào)相應(yīng)的處理函數(shù)進(jìn)行處理,這樣可以大大減少線程的創(chuàng)建和銷毀開銷,提高服務(wù)器的性能和吞吐量。
另外,異步網(wǎng)絡(luò)模型還可以應(yīng)用于實(shí)時(shí)數(shù)據(jù)處理系統(tǒng),比如金融交易系統(tǒng)、在線廣告系統(tǒng)等,這些系統(tǒng)需要實(shí)時(shí)處理大量的數(shù)據(jù)請(qǐng)求,如果使用阻塞式IO模型,會(huì)導(dǎo)致數(shù)據(jù)處理的延遲時(shí)間較長,影響系統(tǒng)的實(shí)時(shí)性。而使用異步網(wǎng)絡(luò)模型,可以通過事件驅(qū)動(dòng)的方式實(shí)時(shí)處理數(shù)據(jù)請(qǐng)求,提高系統(tǒng)的實(shí)時(shí)性和性能。
怎樣可以完成異步操作?
- 回調(diào)函數(shù):在 Java 中,可以使用回調(diào)函數(shù)的方式來完成異步操作,比如使用 Java 的回調(diào)接口或者 Lambda 表達(dá)式來實(shí)現(xiàn)異步回調(diào)。
- Future對(duì)象:Future 對(duì)象是 Java 中的一種異步編程解決方案,它可以將異步操作封裝成一個(gè) Future 對(duì)象,然后使用 Future.get() 方法來等待異步操作的完成,從而實(shí)現(xiàn)異步操作的同步化編程。
- CompletableFuture對(duì)象:CompletableFuture是Java 8中新增的異步編程解決方案,它可以將異步操作封裝成一個(gè) CompletableFuture 對(duì)象,然后使用 CompletableFuture的方法來處理異步操作的結(jié)果,比如 thenApply()、thenAccept()、thenRun()等方法。
- 異步框架:可以采用一些異步框架可以用于實(shí)現(xiàn)異步操作,比如Netty、Vert.x等框架,它們可以通過事件驅(qū)動(dòng)的方式實(shí)現(xiàn)異步操作,提高系統(tǒng)的性能和可擴(kuò)展性。
在Java中,同步阻塞和同步非阻塞可以通過不同的IO模型來實(shí)現(xiàn)?
在Java中,同步阻塞和同步非阻塞可以通過不同的 IO 模型來實(shí)現(xiàn)。
- 同步阻塞 IO 模型:在Java中,同步阻塞 IO 模型是最常見的 IO 模型,它使用 InputStream 和 OutputStream 等阻塞式 IO 類來實(shí)現(xiàn)數(shù)據(jù)的讀寫操作。在同步阻塞 IO 模型中,當(dāng)一個(gè)線程調(diào)用阻塞式 IO 類的 read() 或 write() 方法時(shí),該線程會(huì)被阻塞,直到IO操作完成或者出現(xiàn)異常。
- 同步非阻塞 IO 模型:在Java中,同步非阻塞 IO 模型可以通過使用Java NIO(New IO)來實(shí)現(xiàn)。Java NIO 提供了一種基于通道和緩沖區(qū)的IO模型,可以實(shí)現(xiàn)非阻塞式的IO操作。在同步非阻塞 IO 模型中,當(dāng)一個(gè)線程調(diào)用 Java NIO 的通道的 read() 或 write() 方法時(shí),該線程不會(huì)被阻塞,而是立即返回,然后可以通過輪詢的方式來檢查 IO 操作的狀態(tài),從而實(shí)現(xiàn)非阻塞式的 IO 操作。
能結(jié)合具體場(chǎng)景講解嗎?
當(dāng)涉及到高并發(fā)、高性能、高可靠性的場(chǎng)景時(shí),選擇合適的 IO 模型非常重要。下面結(jié)合具體場(chǎng)景來講解:
- Web服務(wù)器:對(duì)于 Web 服務(wù)器來說,同步阻塞 IO 模型是最常用的IO模型,因?yàn)樗梢蕴峁┓€(wěn)定的性能和可靠性。在Java中,可以使用Servlet API來實(shí)現(xiàn)同步阻塞 IO 模型。如果需要更高的性能和可擴(kuò)展性,可以考慮使用異步 IO 模型,比如 Java NIO 或者 Netty 等框架。
- 游戲服務(wù)器:對(duì)于游戲服務(wù)器來說,需要處理大量的并發(fā)連接和實(shí)時(shí)數(shù)據(jù)交互,因此同步非阻塞 IO 模型是比較適合的選擇。在Java中,可以使用 Java NIO 或者 Netty 等框架來實(shí)現(xiàn)同步非阻塞IO模型。
- 數(shù)據(jù)庫訪問:對(duì)于數(shù)據(jù)庫訪問來說,同步阻塞IO模型是最常用的IO模型,因?yàn)樗梢蕴峁┓€(wěn)定的性能和可靠性。在 Java中,可以使用JDBC API 來實(shí)現(xiàn)同步阻塞 IO 模型。如果需要更高的性能和可擴(kuò)展性,可以考慮使用異步 IO 模型,比如使用異步數(shù)據(jù)庫驅(qū)動(dòng)程序,比如HikariCP等。
除了同步阻塞和同步非阻塞 IO 模型之外,還有一些其他的 IO 模型,比如異步IO模型、多路復(fù)用IO模型等。在實(shí)際應(yīng)用中,應(yīng)該根據(jù)具體的場(chǎng)景和需求來選擇合適的 IO 模型。
描述一下一次完整的 Http 請(qǐng)求?
一次完整的HTTP請(qǐng)求通常包括以下步驟:(如果是從瀏覽器發(fā)起地址請(qǐng)求,還需要地址各種解析哦~)
- 建立 TCP 連接:客戶端通過 TCP 協(xié)議與服務(wù)器建立連接,進(jìn)行 “三次握手”。客戶端發(fā)送 SYN 包,服務(wù)器回應(yīng) SYN+ACK 包,客戶端再回應(yīng) ACK 包,完成連接建立。
- 發(fā)送 HTTP 請(qǐng)求:客戶端向服務(wù)器發(fā)送 HTTP 請(qǐng)求,請(qǐng)求中包含請(qǐng)求行、請(qǐng)求頭和請(qǐng)求體。請(qǐng)求行包括請(qǐng)求方法、請(qǐng)求URL和HTTP協(xié)議版本;請(qǐng)求頭包括一些附加信息,比如請(qǐng)求頭部字段、Cookie 等;請(qǐng)求體包含請(qǐng)求的數(shù)據(jù),比如POST請(qǐng)求中的表單數(shù)據(jù)。
- 服務(wù)器處理請(qǐng)求:服務(wù)器接收到客戶端發(fā)送的 HTTP 請(qǐng)求后,會(huì)根據(jù)請(qǐng)求的內(nèi)容進(jìn)行處理,比如查詢數(shù)據(jù)庫、讀取文件等。
- 服務(wù)器返回 HTTP 響應(yīng):服務(wù)器處理完請(qǐng)求后,會(huì)向客戶端返回 HTTP 響應(yīng),響應(yīng)中包含響應(yīng)行、響應(yīng)頭和響應(yīng)體。響應(yīng)行包括 HTTP 協(xié)議版本、狀態(tài)碼和狀態(tài)描述;響應(yīng)頭包括一些附加信息,比如響應(yīng)頭部字段、Cookie 等;響應(yīng)體包含響應(yīng)的數(shù)據(jù),比如 HTML 頁面、JSON 數(shù)據(jù)等。
- 關(guān)閉TCP連接:客戶端接收到服務(wù)器返回的HTTP響應(yīng)后,會(huì)關(guān)閉TCP連接,進(jìn)行 “四次揮手”。客戶端發(fā)送 FIN 包,服務(wù)器回應(yīng) ACK 包,然后服務(wù)器發(fā)送 FIN 包,客戶端回應(yīng)ACK 包,完成連接關(guān)閉。
總之,一次完整的 HTTP 請(qǐng)求包括建立 TCP 連接、發(fā)送 HTTP 請(qǐng)求、服務(wù)器處理請(qǐng)求、服務(wù)器返回 HTTP 響應(yīng)和關(guān)閉 TCP 連接等步驟。在實(shí)際應(yīng)用中,還需要考慮 HTTP 緩存、Cookie、會(huì)話管理等問題。
長連接有哪些實(shí)現(xiàn)方式?
- 長連接是指客戶端和服務(wù)器之間保持連接狀態(tài),可以在一定時(shí)間內(nèi)進(jìn)行多次請(qǐng)求和響應(yīng),而不必每次請(qǐng)求都重新建立連接。
- 長連接可以減少連接建立和斷開的開銷,提高網(wǎng)絡(luò)傳輸效率,常用于實(shí)時(shí)通信、推送服務(wù)等場(chǎng)景。
常見的長連接實(shí)現(xiàn)方式包括:
- HTTP長連接:HTTP/1.1 協(xié)議支持長連接,客戶端和服務(wù)器之間可以保持連接狀態(tài),可以在一定時(shí)間內(nèi)進(jìn)行多次請(qǐng)求和響應(yīng)。在 HTTP 長連接中,客戶端發(fā)送請(qǐng)求后,服務(wù)器會(huì)保持連接狀態(tài),直到客戶端發(fā)送關(guān)閉連接的請(qǐng)求或者超時(shí)時(shí)間到達(dá)。
- WebSocket:WebSocket 是一種基于 HTTP 協(xié)議的長連接技術(shù),它可以在客戶端和服務(wù)器之間建立雙向通信的連接,實(shí)現(xiàn)實(shí)時(shí)通信和推送服務(wù)。WebSocket 協(xié)議通過 HTTP協(xié)議的升級(jí)實(shí)現(xiàn),客戶端和服務(wù)器之間可以發(fā)送和接收數(shù)據(jù)幀,而不必重新建立連接。
- TCP長連接:TCP 協(xié)議支持長連接,客戶端和服務(wù)器之間可以保持連接狀態(tài),可以在一定時(shí)間內(nèi)進(jìn)行多次請(qǐng)求和響應(yīng)。在TCP長連接中,客戶端和服務(wù)器之間建立連接后,可以保持連接狀態(tài),直到客戶端或服務(wù)器發(fā)送關(guān)閉連接的請(qǐng)求或者網(wǎng)絡(luò)異常斷開連接。
長連接可以提高網(wǎng)絡(luò)傳輸效率,常用于實(shí)時(shí)通信、推送服務(wù)等場(chǎng)景
設(shè)計(jì)一個(gè)Hashset?
我隨便設(shè)計(jì)的一個(gè)簡(jiǎn)單的 Hashset(僅供參考):
- 定義一個(gè)哈希表數(shù)組,數(shù)組的長度為質(zhì)數(shù),每個(gè)元素是一個(gè)鏈表,用于存儲(chǔ)哈希沖突的元素。
- 定義一個(gè)哈希函數(shù),將元素映射到哈希表數(shù)組中的一個(gè)位置。可以使用取模運(yùn)算或者位運(yùn)算等方式實(shí)現(xiàn)哈希函數(shù)。
- 實(shí)現(xiàn)添加元素的方法。首先根據(jù)哈希函數(shù)計(jì)算元素的哈希值,然后將元素添加到對(duì)應(yīng)位置的鏈表中。如果鏈表中已經(jīng)存在相同的元素,則不添加。
- 實(shí)現(xiàn)刪除元素的方法。首先根據(jù)哈希函數(shù)計(jì)算元素的哈希值,然后在對(duì)應(yīng)位置的鏈表中查找元素,如果找到則刪除。
- 實(shí)現(xiàn)查找元素的方法。首先根據(jù)哈希函數(shù)計(jì)算元素的哈希值,然后在對(duì)應(yīng)位置的鏈表中查找元素,如果找到則返回元素,否則返回null。
- 實(shí)現(xiàn)獲取元素個(gè)數(shù)的方法。遍歷哈希表數(shù)組,統(tǒng)計(jì)所有鏈表中元素的個(gè)數(shù)。
- 實(shí)現(xiàn)清空哈希表的方法。遍歷哈希表數(shù)組,將所有鏈表清空。
下面是一個(gè)簡(jiǎn)單的Java代碼實(shí)現(xiàn):
public class MyHashSet<T> {
private static final int DEFAULT_CAPACITY = 16;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
private Node<T>[] table;
private int size;
private int threshold;
private float loadFactor;
public MyHashSet() {
this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public MyHashSet(int initialCapacity, float loadFactor) {
table = new Node[initialCapacity];
this.loadFactor = loadFactor;
threshold = (int) (initialCapacity * loadFactor);
}
public boolean add(T value) {
int hash = hash(value);
int index = indexFor(hash, table.length);
Node<T> node = table[index];
while (node != null) {
if (node.value.equals(value)) {
return false;
}
node = node.next;
}
Node<T> newNode = new Node<>(value, table[index]);
table[index] = newNode;
size++;
if (size > threshold) {
resize(table.length * 2);
}
return true;
}
public boolean remove(T value) {
int hash = hash(value);
int index = indexFor(hash, table.length);
Node<T> node = table[index];
Node<T> prev = null;
while (node != null) {
if (node.value.equals(value)) {
if (prev == null) {
table[index] = node.next;
} else {
prev.next = node.next;
}
size--;
return true;
}
prev = node;
node = node.next;
}
return false;
}
public boolean contains(T value) {
int hash = hash(value);
int index = indexFor(hash, table.length);
Node<T> node = table[index];
while (node != null) {
if (node.value.equals(value)) {
return true;
}
node = node.next;
}
return false;
}
public int size() {
return size;
}
public void clear() {
Arrays.fill(table, null);
size = 0;
}
private int hash(T value) {
return value.hashCode();
}
private int indexFor(int hash, int length) {
return hash & (length - 1);
}
private void resize(int newCapacity) {
Node<T>[] newTable = new Node[newCapacity];
for (Node<T> node : table) {
while (node != null) {
Node<T> next = node.next;
int index = indexFor(hash(node.value), newCapacity);
node.next = newTable[index];
newTable[index] = node;
node = next;
}
}
table = newTable;
threshold = (int) (newCapacity * loadFactor);
}
private static class Node<T> {
T value;
Node<T> next;
public Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
}
1T 的數(shù)據(jù)怎么加載到 200M 的內(nèi)存中,并找到兩行一樣的數(shù)據(jù)?
將 1T 的數(shù)據(jù)加載到 200M 的內(nèi)存中是不可能的,因?yàn)?T 的數(shù)據(jù)遠(yuǎn)遠(yuǎn)超過了 200M 的內(nèi)存大小。因此,需要采用一些特殊的算法和技術(shù)來解決這個(gè)問題。
一種解決方案是使用 外部排序算法,將1T的數(shù)據(jù)分成多個(gè)小文件,每個(gè)小文件可以加載到內(nèi)存中進(jìn)行排序。然后,使用歸并排序的思想將這些小文件合并成一個(gè)大文件,并在合并的過程中找到兩行一樣的數(shù)據(jù)。
具體步驟如下(參考):
- 將 1T 的數(shù)據(jù)分成多個(gè)小文件,每個(gè)小文件的大小為 200M
- 對(duì)每個(gè)小文件進(jìn)行排序,可以使用快速排序等算法。
- 將排序后的小文件合并成一個(gè)大文件,可以使用歸并排序的思想。
- 在合并的過程中,記錄前一個(gè)文件的最后一行和當(dāng)前文件的第一行,比較這兩行是否相同,如果相同則找到了兩行一樣的數(shù)據(jù)。
- 最后,將找到的兩行一樣的數(shù)據(jù)輸出即可。
而在實(shí)際操作中,還需要考慮磁盤讀寫速度、文件的讀寫方式等因素,以提高算法的效率和準(zhǔn)確性。
Java打開 1T 的文件,第一步做什么?
在 Java 中打開 1T 的文件,第一步應(yīng)該是確定文件的讀取方式和讀取范圍。
- 確定文件的讀取方式:根據(jù)文件的類型和大小,選擇適當(dāng)?shù)奈募x取方式。如果文件是文本文件,可以使用 BufferedReader 逐行讀取;如果文件是二進(jìn)制文件,可以使用DataInputStream 或者 FileChannel 進(jìn)行讀取。
- 確定文件的讀取范圍:由于1T的文件非常大,無法一次性讀取到內(nèi)存中,因此需要確定讀取的范圍。可以將文件分成多個(gè)塊,每次讀取一個(gè)塊的數(shù)據(jù),處理完后再讀取下一個(gè)塊的數(shù)據(jù)。可以根據(jù)文件的大小和內(nèi)存的大小來確定塊的大小。
用代碼打開一個(gè)文件和用鼠標(biāo)打開用什么區(qū)別嗎?
其底層區(qū)別主要在于操作系統(tǒng)和文件系統(tǒng)的交互方式。
用鼠標(biāo)打開文件是通過操作系統(tǒng)提供的圖形用戶界面(GUI)來實(shí)現(xiàn)的,用戶點(diǎn)擊圖標(biāo),但實(shí)際操作系統(tǒng)會(huì)根據(jù)用戶的操作來調(diào)用相應(yīng)的API,從而實(shí)現(xiàn)文件的打開、讀取、寫入等操作。而這些 API 實(shí)際通常是操作系統(tǒng)提供的底層文件系統(tǒng)接口,例如 Windows 的 Win32 API、Linux 的 POSIX API 等。
而用代碼打開文件則是 **通過編程語言提供的文件操作API **來實(shí)現(xiàn)的,這些API通常是對(duì)操作系統(tǒng)底層文件系統(tǒng)接口的封裝和抽象。通常可以使用 File、FileInputStream、FileOutputStream 等類來實(shí)現(xiàn)文件的打開、讀取、寫入等操作,這些類會(huì)調(diào)用底層的操作系統(tǒng)文件系統(tǒng)接口來實(shí)現(xiàn)相應(yīng)的功能。
因此,從底層的角度來看,用代碼打開文件和用鼠標(biāo)打開文件的區(qū)別在于調(diào)用的API不同,但底層的文件系統(tǒng)接口是相同的。
一次 Http 請(qǐng)求包含哪幾部分內(nèi)容?
- 請(qǐng)求行(Request Line):包含請(qǐng)求方法、請(qǐng)求的URL和HTTP協(xié)議版本。常見的請(qǐng)求方法有 GET、POST、PUT、DELETE 等。
- 請(qǐng)求頭部(Request Headers):包含請(qǐng)求的各種頭部信息,例如 User-Agent、Content-Type、Cookie 等。頭部信息提供了關(guān)于請(qǐng)求的附加信息,用于服務(wù)器處理請(qǐng)求。
- 請(qǐng)求體(Request Body):對(duì)于 GET 請(qǐng)求,請(qǐng)求體通常為空。對(duì)于 POST 請(qǐng)求等需要傳遞數(shù)據(jù)的請(qǐng)求,請(qǐng)求體包含了要發(fā)送給服務(wù)器的數(shù)據(jù)。