1、為什么使用UDP協(xié)議?缺點?
使用UDP協(xié)議的主要原因是它能夠在網(wǎng)絡(luò)中提供快速和高效的數(shù)據(jù)傳輸。與TCP協(xié)議相比,UDP協(xié)議沒有建立連接和確認數(shù)據(jù)包的過程,因此具有更低的延遲和更高的吞吐量,適用于需要快速響應(yīng)的應(yīng)用場景,如在線游戲、視頻和音頻流等。
缺點,由于沒有可靠性保證,數(shù)據(jù)包可能會丟失或亂序到達,因此在傳輸質(zhì)量要求較高的應(yīng)用場景下不太適用。此外,UDP協(xié)議對網(wǎng)絡(luò)擁塞的控制能力很弱,如果網(wǎng)絡(luò)出現(xiàn)擁堵,則容易造成數(shù)據(jù)包的丟失或延遲,從而影響用戶體驗。
2、簡單說說Zookeper設(shè)計原理?怎么用的?
Zookeeper是一個分布式的協(xié)調(diào)服務(wù),它能夠提供分布式應(yīng)用程序所需的一致性、可靠性和高性能特性。在后端系統(tǒng)中,Zookeeper常常被用于實現(xiàn)集群管理、配置管理、命名服務(wù)等功能。
其基本原理如下:
集群管理:Zookeeper將整個集群作為一個整體來管理,可以監(jiān)控節(jié)點的狀態(tài)、健康狀況、可用性等信息,當某個節(jié)點宕機時,Zookeeper能夠自動進行故障轉(zhuǎn)移,保證整個系統(tǒng)的穩(wěn)定性和可用性。
配置管理:Zookeeper可以將系統(tǒng)中的配置信息存儲在其內(nèi)部的節(jié)點樹中,并且能夠監(jiān)聽節(jié)點變化的事件,當配置發(fā)生變化時,Zookeeper會及時通知相關(guān)的客戶端程序,以便客戶端程序能夠及時更新自身的配置信息。
命名服務(wù):Zookeeper將分布式應(yīng)用程序中的各種資源抽象成節(jié)點,每個節(jié)點都有一個唯一的路徑名稱,客戶端程序可以像訪問文件系統(tǒng)一樣訪問Zookeeper上的節(jié)點,從而實現(xiàn)對分布式資源的統(tǒng)一管理和訪問。
使用Zookeeper時,需要先搭建Zookeeper集群,并將自己的應(yīng)用程序注冊到其中。然后,可以通過Zookeeper提供的API來實現(xiàn)對節(jié)點的創(chuàng)建、刪除、修改、查詢等操作,以及對節(jié)點變化事件的監(jiān)聽和處理。同時,Zookeeper還提供了Java、C、Python等多種編程語言的客戶端庫,方便開發(fā)者進行集成和開發(fā)。
3、ZK還沒寫完時,讀請求過來能讀到嗎?提交一定能成功嗎?
在Zookeeper中,讀請求可以在寫請求未完成時進行。這是因為,Zookeeper使用了多版本并發(fā)控制(MVCC)來實現(xiàn)數(shù)據(jù)的一致性和可靠性。每個節(jié)點都有一個版本號,當節(jié)點數(shù)據(jù)被修改時,其版本號會自動增加。讀操作只會訪問指定版本的節(jié)點數(shù)據(jù),不會受到其他修改操作的影響,因此可以在寫操作未完成時進行。
但是,提交請求并不一定能夠成功。如果在提交請求的過程中,當前節(jié)點的狀態(tài)發(fā)生了變化(例如被其他客戶端修改),則該請求可能會失敗,需要重新嘗試提交。另外,如果在提交請求的過程中,網(wǎng)絡(luò)出現(xiàn)異?;蛘遉ookeeper服務(wù)器宕機了,也有可能導致請求失敗。
因此,在使用Zookeeper時,應(yīng)該對請求的提交結(jié)果進行檢查,并在必要情況下進行重試。同時,應(yīng)該采取一些策略來確保Zookeeper服務(wù)器的高可用性和穩(wěn)定性,例如搭建多個Zookeeper服務(wù)器構(gòu)成集群等。
4、服務(wù)實例起來到發(fā)現(xiàn)的過程?
服務(wù)實例起來到發(fā)現(xiàn)的過程可以分為以下幾個步驟:
服務(wù)實例啟動:服務(wù)啟動后會向注冊中心注冊自己的信息,包括服務(wù)名稱、IP地址、端口號等。
注冊中心存儲服務(wù)信息:注冊中心將服務(wù)實例的信息存儲在自己的數(shù)據(jù)庫中,以便其他客戶端能夠查詢和使用該服務(wù)。
服務(wù)發(fā)現(xiàn):客戶端需要使用某個服務(wù)時,會向注冊中心發(fā)送查詢請求。注冊中心根據(jù)客戶端的請求,從自己的數(shù)據(jù)庫中查詢相應(yīng)的服務(wù)實例信息,返回給客戶端。
客戶端調(diào)用服務(wù):客戶端獲取服務(wù)實例的信息后,就可以通過網(wǎng)絡(luò)協(xié)議(如HTTP、RPC等)與服務(wù)實例進行通信,調(diào)用其中提供的API接口,獲取所需的數(shù)據(jù)或執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。
5、調(diào)用方時實時從ZK上取數(shù)據(jù)嗎?
在Zookeeper中,服務(wù)提供者會將自己的信息注冊到Zookeeper上,而服務(wù)調(diào)用方則通過訪問Zookeeper來獲取可用的服務(wù)實例。服務(wù)調(diào)用方可以選擇不同的方式來從ZK上獲取數(shù)據(jù):
實時獲?。涸诜?wù)調(diào)用時,每次都向Zookeeper發(fā)送請求獲取最新的服務(wù)實例列表。這種方式可以保證服務(wù)實例列表的及時性和準確性,但會造成不必要的網(wǎng)絡(luò)開銷和負載。
緩存獲?。悍?wù)調(diào)用方定期從Zookeeper獲取服務(wù)實例列表,并緩存到本地。在服務(wù)調(diào)用時,直接從本地緩存中獲取可用的服務(wù)實例。這種方式可以減少網(wǎng)絡(luò)開銷和負載,但服務(wù)實例列表可能無法及時更新,存在數(shù)據(jù)不一致的風險。
6、ES怎么用的?為什么用ES?
Elasticsearch(ES)是一個開源的分布式搜索引擎,它可以快速、可靠地存儲和搜索大量的結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)。
使用ES需要先安裝和配置ES集群,并通過RESTful API來與其交互??梢酝ㄟ^Java、Python、Node.js等多種編程語言的客戶端庫來連接ES集群。在使用過程中,開發(fā)者需要定義好索引(Index)、類型(Type)和映射(Mapping),并將數(shù)據(jù)存儲到ES中。
為什么用ES?:
高性能:ES使用了多種優(yōu)化技術(shù),如倒排索引、分片、副本等,能夠提供高效的搜索和數(shù)據(jù)訪問性能。
易用性:ES提供了豐富的API和客戶端庫,易于開發(fā)者使用和集成到應(yīng)用程序中。
可擴展性:ES采用分布式架構(gòu),能夠?qū)?shù)據(jù)分散存儲在多個節(jié)點上,并支持水平擴展,能夠處理大規(guī)模數(shù)據(jù)。
穩(wěn)定性:ES具有良好的容錯和恢復(fù)機制,能夠保證系統(tǒng)的穩(wěn)定性和可靠性。
7、Redis怎么實現(xiàn)關(guān)注?兩個key怎么保證數(shù)據(jù)一致性?
Redis可以使用以下兩種方式來實現(xiàn)關(guān)注:
使用有序集合(Sorted Set):
每個用戶對應(yīng)一個有序集合,集合中存儲著該用戶關(guān)注的其他用戶的ID,以及對應(yīng)的關(guān)注時間(可以使用時間戳表示)。例如:對于用戶A來說,他關(guān)注了用戶B、C、D,那么A的有序集合就會存儲如下數(shù)據(jù):
ZADD user:A 1627039510 B
ZADD user:A 1627039515 C
ZADD user:A 1627039520 D
當用戶A要查看自己關(guān)注的用戶列表時,只需要使用ZRANGE命令按照關(guān)注時間順序取出即可。
使用列表(List)和集合(Set):
使用兩個key來存儲數(shù)據(jù),分別為用戶的關(guān)注列表和被關(guān)注列表。例如:對于用戶A來說,他關(guān)注了用戶B、C、D,那么A的關(guān)注列表就會存儲如下數(shù)據(jù):
LPUSH following:A B
LPUSH following:A C
LPUSH following:A D
被關(guān)注列表則是以被關(guān)注用戶的ID為key,對應(yīng)的value為一個集合,這個集合存儲了所有關(guān)注該用戶的用戶ID。例如:對于用戶B來說,他被用戶A、E、F關(guān)注,那么B的被關(guān)注列表就會存儲如下數(shù)據(jù):
SADD followers:B A
SADD followers:B E
SADD followers:B F
當用戶A要查看自己關(guān)注的用戶列表時,只需要使用LRANGE命令取出即可;當用戶B要查看關(guān)注他的用戶列表時,則需要使用SMEMBERS命令獲取到所有關(guān)注他的用戶ID,并根據(jù)這些ID去查詢對應(yīng)的用戶信息。
為了保證數(shù)據(jù)一致性,需要在每次添加、刪除關(guān)注關(guān)系時,同時修改兩個key中的數(shù)據(jù)??梢允褂肦edis事務(wù)來實現(xiàn)這一操作,例如:
MULTI
ZADD user:A 1627039510 B
LPUSH following:A B
SADD followers:B A
EXEC
這樣可以確保兩個key中的數(shù)據(jù)始終保持一致。
8、TCP三次握手四次揮手?
TCP三次握手:
客戶端向服務(wù)端發(fā)送一個SYN(同步)標志位為1的數(shù)據(jù)包,表示客戶端請求建立連接。
服務(wù)端接收到客戶端的SYN數(shù)據(jù)包后,會回復(fù)一個ACK(確認)標志位為1的數(shù)據(jù)包,表示服務(wù)端已經(jīng)收到了客戶端的請求,并表示服務(wù)端也愿意建立連接。此時服務(wù)端還會發(fā)送一個SYN標志位為1的數(shù)據(jù)包,表示服務(wù)端也要求建立連接。
客戶端收到服務(wù)端的SYN和ACK數(shù)據(jù)包后,會發(fā)送一個ACK標志位為1的數(shù)據(jù)包,表示客戶端已經(jīng)收到了服務(wù)端的確認,并進入已連接狀態(tài),雙方可以開始傳輸數(shù)據(jù)。
TCP四次揮手:
當客戶端想要關(guān)閉連接時,會向服務(wù)端發(fā)送一個FIN(結(jié)束)標志位為1的數(shù)據(jù)包,表示客戶端不再需要連接。
服務(wù)端收到客戶端的FIN數(shù)據(jù)包后,會發(fā)送一個ACK標志位為1的數(shù)據(jù)包,表示服務(wù)端已經(jīng)收到了客戶端的請求,但是服務(wù)端可能還有未傳輸完成的數(shù)據(jù)需要發(fā)送。
當服務(wù)端所有的數(shù)據(jù)都傳輸完成后,會向客戶端發(fā)送一個FIN標志位為1的數(shù)據(jù)包,表示服務(wù)端已經(jīng)完成了數(shù)據(jù)的傳輸。
客戶端收到服務(wù)端的FIN數(shù)據(jù)包后,會回復(fù)一個ACK標志位為1的數(shù)據(jù)包,表示客戶端已經(jīng)收到了服務(wù)端的結(jié)束請求,并且也沒有數(shù)據(jù)需要傳輸了。此時客戶端進入TIME_WAIT狀態(tài),等待2MSL(最長報文段壽命)之后才會徹底關(guān)閉連接。
在TCP連接中,三次握手是建立連接,四次揮手是斷開連接。三次握手保證了雙方都已經(jīng)準備好進行通信,四次揮手則保證了雙方都能夠安全、完整地結(jié)束通信。
9、Session和Cookie區(qū)別?
Session和Cookie都是Web開發(fā)中常用的技術(shù),它們都可以用來存儲用戶的數(shù)據(jù),但在實現(xiàn)方式和作用上有一些區(qū)別。
存儲位置
Cookie存儲在客戶端瀏覽器中,而Session存儲在服務(wù)器端內(nèi)存或者磁盤中。
安全性
由于Cookie存儲在客戶端瀏覽器中,因此Cookie存在被篡改的風險。如果使用明文存儲敏感信息,那么這些信息就可能被黑客竊取。而Session存儲在服務(wù)端,只要保證服務(wù)器端的安全性,就能夠保障用戶的信息安全。
大小限制
Cookie的大小通常受到瀏覽器對Cookie數(shù)量和大小限制的限制(不同瀏覽器限制不同),而Session的大小通常只受到服務(wù)器硬件和軟件的限制。
生命周期
Cookie可以設(shè)置生命周期,可以在客戶端指定一個過期時間,在過期時間之前,瀏覽器會一直保存該Cookie。而Session通常在客戶端關(guān)閉后就會被銷毀。
作用域
Cookie的作用域可以控制Cookie的訪問權(quán)限,可以設(shè)置為整個網(wǎng)站、某個目錄或者某個頁面。而Session通常只在當前應(yīng)用程序范圍內(nèi)有效。
使用場景
Cookie通常用于記錄用戶的登錄狀態(tài)、購物車信息等。而Session通常用于存儲用戶會話信息、權(quán)限驗證信息等。
10、常見的Linux IO模型?
常見的Linux IO模型有以下幾種:
-
阻塞IO模型(Blocking IO):當應(yīng)用程序調(diào)用read或write等IO操作時,如果內(nèi)核沒有準備好數(shù)據(jù),那么應(yīng)用程序就會一直阻塞等待,直到內(nèi)核準備好數(shù)據(jù)后才會返回。在這種模型下,應(yīng)用程序通常只能同時處理一個連接,效率較低。
-
非阻塞IO模型(Non-Blocking IO):應(yīng)用程序調(diào)用read或write等IO操作后,如果內(nèi)核沒有準備好數(shù)據(jù),那么應(yīng)用程序不會被阻塞,而是立即返回一個EAGAIN或EWOULDBLOCK錯誤碼,表示當前資源不可用。在這種模型下,應(yīng)用程序需要不斷輪詢來檢查是否有數(shù)據(jù)準備好,可以同時處理多個連接,但輪詢頻繁可能會占用過多CPU資源。
-
IO復(fù)用模型(IO Multiplexing):使用select、poll或epoll等系統(tǒng)調(diào)用來監(jiān)聽多個IO事件,當有IO事件發(fā)生時再進行處理。在這種模型下,應(yīng)用程序也只需要通過一個線程來監(jiān)聽多個連接,效率比非阻塞IO模型要高。
-
信號驅(qū)動IO模型(Signal Driven IO):應(yīng)用程序調(diào)用sigaction函數(shù)注冊一個信號處理函數(shù),在數(shù)據(jù)準備好時內(nèi)核會向應(yīng)用程序發(fā)送一個SIGIO信號,應(yīng)用程序收到信號后再進行IO操作。這種模型比較適合于處理低頻率的IO事件。
-
異步IO模型(Asynchronous IO):應(yīng)用程序調(diào)用aio_read或aio_write等異步IO函數(shù),內(nèi)核會在IO操作完成后通知應(yīng)用程序。在這種模型下,應(yīng)用程序不需要等待IO操作完成,可以繼續(xù)執(zhí)行其他任務(wù),當IO操作完成后再進行回調(diào)處理。異步IO模型在高并發(fā)場景下更具優(yōu)勢。
11、==和equals區(qū)別?hashCode和equals區(qū)別?HashMap的put操作流程?
==和equals區(qū)別:
==是比較兩個對象的內(nèi)存地址是否相同,即判斷兩個對象是否為同一個對象。而equals是比較兩個對象的內(nèi)容(屬性)是否相同,即判斷兩個對象是否等價。
hashCode和equals區(qū)別:
hashCode是Java中Object類的一個方法,在進行哈希映射時使用。它用于計算存儲對象的哈希碼,不同的對象可以有相同的哈希碼,但相等的對象必須具有相同的哈希碼。equals方法則用于比較兩個對象是否相等,如果兩個對象相等,則其hashCode方法返回的哈希值也必須相等。
HashMap的put操作流程:
HashMap是一種基于數(shù)組和鏈表實現(xiàn)的哈希表,用于存儲鍵值對數(shù)據(jù)。當執(zhí)行put操作時,假設(shè)需要將key-value對(K1, V1)加入到HashMap中,它的操作流程如下:
-
計算K1的hashCode值。
-
根據(jù)hashCode值找到K1在數(shù)組中的索引位置,如果該位置沒有元素,則將(K1, V1)插入到該位置,并返回null。
-
如果該位置已經(jīng)存在元素,那么需要將(K1, V1)與該位置上的所有元素進行比較,如果找到了一個key與K1相等的元素,則將該位置上的value替換為V1,并返回舊的value值。
-
如果該位置上的元素都和K1不相等,那么需要將(K1, V1)插入到該位置上的鏈表中,并返回null。
-
如果鏈表長度大于8(默認值),則會將鏈表轉(zhuǎn)化為紅黑樹,以提高查找效率。
-
如果數(shù)組中的元素個數(shù)超過了負載因子(默認是0.75),就需要進行擴容操作,將容量翻倍。
12、HashMap是線程安全的嗎?
HashMap是非線程安全的,它不是線程安全的容器。如果在多線程環(huán)境下使用HashMap進行讀寫操作,可能會導致數(shù)據(jù)不一致的問題。
13、實現(xiàn)懶漢式單例模式
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
// 私有構(gòu)造方法
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
在這個實現(xiàn)中,getInstance方法使用了synchronized關(guān)鍵字來保證線程安全,只有在instance為null時才創(chuàng)建LazySingleton對象,并返回該對象。由于synchronized關(guān)鍵字會降低性能,因此可以考慮使用雙重檢查鎖定(Double Check Locking)和靜態(tài)內(nèi)部類等方式來提高性能和代碼可讀性。文章來源:http://www.zghlxwxcb.cn/news/detail-420203.html
需要注意的是,懶漢式單例模式在多線程環(huán)境下可能會出現(xiàn)問題,例如當兩個線程同時進入if語句時,都判斷instance為null,然后都創(chuàng)建一個LazySingleton對象并返回,這就導致了多個對象實例的存在。因此,需要在getInstance方法上增加同步鎖或者使用volatile關(guān)鍵字來解決這個問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-420203.html
到了這里,關(guān)于美團后端開發(fā)暑期實習一面的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!