[面試題]自己邊面試邊總結的Java開發工程師筆記

面經


下面是我自己面試的時候整理的
有很多都是自己被問到了及時記錄整理的
【注意】我被問到的題全部會這樣黃色標註出來

業務背景題

問:業務背景:某浪微博平臺有很多用戶時常的會發布微博,當某個用戶發佈一條微博的時候,TA的所有關注着都可以接收到這條信息。那麼怎麼樣設計一個合理的解決方案來讓用戶快速將他所發佈的微博信息推送給所有的關注者呢?

答:
第一種方案,每個用戶所發送的微博都存儲起來(時間上有序)。當用戶要刷新微博的時候就可以直接拉取TA所關注的人在這個時間內的微博,然後按照時間排序之後再推送過來。(當然,這裏的什麼延遲拉取之類的細節優化就不做詳述了。)

機智的小夥伴可能也發現了這種方案的問題,對於某浪微博這種級別的平臺,他所支撐的用戶都是數以億計的,這樣的方案對於讀的壓力將會是巨大的

那麼怎麼辦呢?當我們試圖開始要優化一個系統的時候,有個相對無腦而又實用的方案就是——上緩存

方案二具體操作說起來也比較簡單,對每個用戶都維護一塊緩存。當用戶發佈微博的時候,相應的後臺程序可以先查詢一下他的關注者,然後將這條微博插入到所有關注着的緩存中。(當然這個緩存會按時間線排序,也會有一定的容量大小限制等,這些細節也不多做贅述。)這樣當用戶上線逛微博的時候,那麼TA就可以直接從緩存中讀取,讀取的性能有了質的飛昇。

如此就OK了嗎?顯然不是,這種方案的問題在於麼有考慮到大V的存在,大V具有很龐大的流量扇出。比如微博女王謝娜的粉絲將近1.25億,那麼她發一條微博(假設爲1KB)所要佔用的緩存大小爲1KB * 1.25 * 10^8 = 125GB。對於這個量我們思考一下幾個點:

  1. 對於1.25億人中有多少人會在這個合適的時間在線,有多少人會刷到這條微博,很多像皮皮這種的半殭屍用戶也不會太少,這塊裏面的很多容量都是浪費。
  2. 1.25億次的緩存寫入,雖然不需要瞬時寫入,但好歹也要在幾秒內完成的吧。這個流量的劇增帶來的影響也不容忽視。
  3. 微博上雖然上億粉絲的大V不多,但是上千萬、上百萬的大V也是一個不小的羣體。某個大V發1條微博就佔用了這麼大的緩存,這個機器成本也太龐大了,得不償失。
    【注】這種案例比較典型,比如某直播平臺,當PDD上線直播時(直播熱度一般在幾百萬甚至上千萬級別)所用的後臺支撐策略與某些小主播(直播熱度幾千之內的)的後臺支撐的策略肯定是不一樣的。

從微觀角度而言,計算機應用是0和1的世界,而從宏觀角度來看,計算機應用的藝術確是在0-1之間。通用型業務設計的難點在於要考慮很多種方面的因數,然後權衡利弊,再對症下藥。業務架構本沒有什麼銀彈,有的是對系統的不斷認知和優化改進。

對於本文這個問題的解決方法是將方案一和二合併,以粉絲數來做區分。也就是說,對於大V發佈的微博我們用方案一處理,而對於普通用戶而言我們就用方案二來處理。當某個用戶逛微博的時候,後臺程序可以拉取部分緩存中的信息,與此同時可以如方案一中的方式讀取大V的微博信息,最後將此二者做一個時間排序合併後再推送給用戶。

———————————————— 版權聲明:本文爲CSDN博主「朱小廝」的原創文章,遵循 CC 4.0 BY-SA
版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u013256816/article/details/100570732

計算機網網絡

一、交換機和路由器有什麼區別?

答:
1、路由器可以給你的局域網自動分配IP,虛擬撥號,就像一個交通警察,指揮着你的電腦該往哪走,你自己不用操心那麼多了。交換機只是用來分配網絡數據的。
2、路由器在網絡層,路由器根據IP地址尋址,路由器可以處理TCP/IP協議,交換機不可以。交換機在中繼層,交換機根據MAC地址尋址。
3、路由器可以把一個IP分配給很多個主機使用,這些主機對外只表現出一個IP。交換機可以把很多主機連起來,這些主機對外各有各的IP。
4、路由器可以提供防火牆,交換機不能提供該功能。集線器、交換機都是做端口擴展的,就是擴大局域網(通常都是以太網)的接入點,也就是能讓局域網可以連進來更多的電腦。路由器是用來做網間連接,也就是用來連接不同的網絡。

二、OSI七層參考模型

重點,這個我被問過好幾次,各種變換着法問,但是知識點都是一個地方的

1、直接讓你說有幾層,並分別說出每一層的名字(建議回答的時候儘量按順序說)
2、會挑出其中的一兩層讓你說有什麼作用
3、會說出一個協議讓你說屬於哪一層
4、會讓你說出某一層中常見的有哪些協議

OSI(Open System Interconnect),即開放式系統互聯。
ISO爲了更好的使網絡應用更爲普及,推出了OSI參考模型。其含義就是推薦所有公司使用這個規範來控制網絡。這樣所有公司都有相同的規範,就能互聯了。

OSI七層模型的劃分
在這裏插入圖片描述
(1)應用層
OSI參考模型中最靠近用戶的一層,是爲計算機用戶提供應用接口,也爲用戶直接提供各種網絡服務。我們常見應用層的網絡服務協議有:HTTP,HTTPS,FTP,POP3、SMTP等。
(2)表示層
表示層提供各種用於應用層數據的編碼和轉換功能,確保一個系統的應用層發送的數據能被另一個系統的應用層識別。如果必要,該層可提供一種標準表示形式,用於將計算機內部的多種數據格式轉換成通信中採用的標準表示形式。數據壓縮和加密也是表示層可提供的轉換功能之一。
(3)會話層
會話層就是負責建立、管理和終止表示層實體之間的通信會話。該層的通信由不同設備中的應用程序之間的服務請求和響應組成。
(4)傳輸層
傳輸層建立了主機端到端的鏈接,傳輸層的作用是爲上層協議提供端到端的可靠和透明的數據傳輸服務,包括處理差錯控制和流量控制等問題。該層向高層屏蔽了下層數據通信的細節,使高層用戶看到的只是在兩個傳輸實體間的一條主機到主機的、可由用戶控制和設定的、可靠的數據通路。我們通常說的,TCP 、UDP就是在這一層。端口號既是這裏的“端”。
(5)網絡層
本層通過IP尋址來建立兩個節點之間的連接,爲源端的運輸層送來的分組,選擇合適的路由和交換節點,正確無誤地按照地址傳送給目的端的運輸層。就是通常說的IP層。這一層就是我們經常說的IP協議層。IP協議是Internet的基礎。
(6)數據鏈路層
將比特組合成字節,再將字節組合成幀,使用鏈路層地址 (以太網使用MAC地址)來訪問介質,並進行差錯檢測
數據鏈路層又分爲2個子層:邏輯鏈路控制子層(LLC)媒體訪問控制子層(MAC)
MAC子層處理CSMA/CD算法、數據出錯校驗、成幀等;LLC子層定義了一些字段使上次協議能共享數據鏈路層。 在實際使用中,LLC子層並非必需的。
(7)物理層
實際最終信號的傳輸是通過物理層實現的。通過物理介質傳輸比特流。規定了電平、速度和電纜針腳。常用設備有(各種物理設備)集線器、中繼器、調制解調器、網線、雙絞線、同軸電纜。這些都是物理層的傳輸介質

通信特點:對等通信,在每一層通信過程中,使用本層自己協議進行通信。源端OSI模型的每一層都必須與目的端的對等層進行通信,這種通信方式稱爲對等層通信。

三、TCP/IP五層模型

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

四、tcp和udp的區別

這裏被問過兩次
答:tcp和udp他們都是傳輸層的協議;然後tcp是可靠傳輸,udp是盡最大努力交付,不可靠;tcp主要應用於端到端的比如電話這種服務,udp應用於廣播,收音機等服務;tcp頭部含有更多的如目標地址等信息,比udp頭部開銷更大。

五、TCP握手過程 爲什麼是4次

被問過一次
三次握手(Three-way Handshake),一個虛擬連接的建立是通過三次握手來實現的。
四次握手(Four-way Handshake) , 四次握手用來關閉已建立的TCP連接

問:爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?
答:這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。

詳細分析:
(1)三次握手建立連接,客戶端發送syn包到服務器,服務器收到syn包,確認客戶的syn包並且自己也發送一個syn包和ACK確認包,客戶端收到後確認服務器的syn包,連接建立。
詳細過程如下:

1、 (B) --> [SYN] --> (A)
假如服務器A和客戶機B通訊. 當A要和B通信時,B首先向A發一個SYN (Synchronize)
標記的包,告訴A請求建立連接.
注意: 一個 SYN包就是僅SYN標記設爲1的TCP包(參見TCP包頭Resources). 認識
到這點很重要,只有當A受到B發來的SYN包,纔可建立連接,除此之外別無他法。因此,
如果你的防火牆丟棄所有的發往外網接口的SYN包,那麼你將不能讓外部任何主機主動建立連接。
2.、(B) <-- [SYN/ACK] <–(A) 接着,A收到後會發一個對SYN包的確認包(SYN/ACK)回去,表示對第一個SYN包的確認,並繼續握手操作.
注意: SYN/ACK包是僅SYN 和 ACK 標記爲1的包.
3、 (B) --> [ACK] --> (A)
B收到SYN/ACK 包,B發一個確認包(ACK),通知A連接已建立。至此,三次握手完成,一個TCP連接完成
Note: ACK包就是僅ACK 標記設爲1的TCP包. 需要注意的是當三此握手完成、連接建立以後,TCP連接的每個包都會設置ACK位

這就是爲何連接跟蹤很重要的原因了. 沒有連接跟蹤,防火牆將無法判斷收到的ACK包是否屬於一個已經建立的連接.一般的包過濾(Ipchains)收到ACK包時,會讓它通過(這絕對不是個好主意). 而當狀態型防火牆收到此種包時,它會先在連接表中查找是否屬於哪個已建連接,否則丟棄該包

(2)四次握手 Four-way Handshake
四次握手用來關閉已建立的TCP連接

  1. (B) --> ACK/FIN --> (A)
  2. (B) <-- ACK <-- (A)
  3. (B) <-- ACK/FIN <-- (A)
  4. (B) --> ACK --> (A)

注意: 由於TCP連接是雙向連接, 因此關閉連接需要在兩個方向上做。ACK/FIN 包(ACK 和FIN 標記設爲1)通常被認爲是FIN(終結)包.然而, 由於連接還沒有關閉, FIN包總是打上ACK標記. 沒有ACK標記而僅有FIN標記的包不是合法的包,並且通常被認爲是惡意的

連接復位Resetting a connection
四次握手不是關閉TCP連接的唯一方法. 有時,如果主機需要儘快關閉連接(或連接超時,端口或主機不可達),RST (Reset)包將被髮送. 注意在,由於RST包不是TCP連接中的必須部分, 可以只發送RST包(即不帶ACK標記). 但在正常的TCP連接中RST包可以帶ACK確認標記 .

請注意RST包是可以不要收到方確認的

無效的TCP標記Invalid TCP Flags
到目前爲止,你已經看到了 SYN, ACK, FIN, 和RST 標記. 另外,還有PSH (Push) 和URG (Urgent)標記.

最常見的非法組合是SYN/FIN 包. 注意:由於 SYN包是用來初始化連接的, 它不可能和 FIN和RST標記一起出現. 這也是一個惡意攻擊.

由於現在大多數防火牆已知 SYN/FIN 包, 別的一些組合,例如SYN/FIN/PSH,
SYN/FIN/RST, SYN/FIN/RST/PSH。很明顯,當網絡中出現這種包時,很你的網絡肯定受到攻擊了。
別的已知的非法包有FIN (無ACK標記)和"NULL"包。如同早先討論的,由於ACK/FIN包的出現是爲了關閉一個TCP連接,那麼正常的FIN包總是帶有 ACK 標記。"NULL"包就是沒有任何TCP標記的包(URG,ACK,PSH,RST,SYN,FIN都爲0)。

到目前爲止,正常的網絡活動下,TCP協議棧不可能產生帶有上面提到的任何一種標記組合的TCP包。當你發現這些不正常的包時,肯定有人對你的網絡不懷好意。

補問:

問:爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?
答:這是因爲雖然雙方都同意關閉連接了,而且握手的4個報文也都協調和發送完畢,按理可以直接回到CLOSED狀態(就好比從SYN_SEND狀態到ESTABLISH狀態那樣);但是因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於LAST_ACK狀態下的SOCKET可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的ACK報文。

超時重傳:超時重傳機制用來保證TCP傳輸的可靠性。每次發送數據包時,發送的數據報都有seq號(seq的話就是一個臨時交互號,是自身的一個標識),接收端收到數據後,會回覆ack進行確認,表示某一seq 號數據已經收到。發送方在發送了某個seq包後,等待一段時間,如果沒有收到對應的ack回覆,就會認爲報文丟失,會重傳這個數據包。

快速重傳:接受數據一方發現有數據包丟掉了。就會發送ack報文告訴發送端重傳丟失的報文。如果發送端連續收到標號相同的ack包,則會觸發客戶端的快速重 傳。比較超時重傳和快速重傳,可以發現超時重傳是發送端在傻等超時,然後觸發重傳;而快速重傳則是接收端主動告訴發送端數據沒收到,然後觸發發送端重傳

流量控制:接收端告訴發送端自己還有多少緩衝區可以接受數據(只考慮接收端和發送端)

擁塞控制:慢啓動、擁塞避免、擁塞發生、快速恢復(考慮整個網絡的狀況)

四次握手斷開連接

第一次:主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發數據了(當 然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些數據),但此時主動關閉方還可以接受數據。
第二次:被動關閉方收到FIN包後,發送一個ACK給對方,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號)。
第三次:被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,我的數據也發送完了,不會再給你發數據了。
第四次:主動關閉方收到FIN後,發送一個ACK給被動關閉方,確認序號爲收到序號+1,至此,完成四次揮手。

SYN標誌建立一個新連接,FIN標誌釋一個連接,RST重置連接

三次握手用於防止“已失效的連接請求報文段”,報文段沒有丟失,而是在某個節點長時間滯留。
四次揮手:由於TCP連接是全雙工的。所以每個方向都必須單獨進行關閉

六、https 瞭解嗎

https=http+ssl
https 的 SSL 加密是在傳輸層實現的。

http: 超文本傳輸協議

https: 是以安全爲目標的 HTTP 通道,簡單講是 HTTP 的安全版,即 HTTP 下加入
SSL 層,HTTPS 的安全基礎是 SSL,因此加密的詳細內容就需要 SSL。

https 協議的主要作用是:建立一個信息安全通道,來確保數組的傳輸,確保網
站的真實性。

七、HTTP 與 HTTPS 的區別

被簡單問過一次,只是簡單提了一下

1、HTTP 明文傳輸,數據都是未加密的,安全性較差,HTTPS(SSL+HTTP) 數據傳輸過程是加密的,安全性較好。
2、使用 HTTPS 協議需要到 CA(Certificate Authority,數字證書認證機構) 申請證書,一般免費證書較少,因而需要一定費用。證書頒發機構如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
3、HTTP 頁面響應速度比 HTTPS 快,主要是因爲 HTTP 使用 TCP 三次握手建立連接,客戶端和服務器需要交換 3 個包,而 HTTPS除了 TCP 的三個包,還要加上 ssl 握手需要的 9 個包,所以一共是 12 個包。
4、http 和 https 使用的是完全不同的連接方式,用的端口也不一樣,前者是 80,後者是 443。
5、HTTPS 其實就是建構在 SSL/TLS 之上的 HTTP 協議,所以,要比較 HTTPS 比 HTTP 要更耗費服務器資源。

HTTP超文本傳輸協議(HyperText Transfer Protocol)是一種用於分佈式、協作式和超媒體信息系統的應用層協議。 簡單來說就是一種發佈和接收 HTML 頁面的方法,被用於在 Web 瀏覽器和網站服務器之間傳遞信息。

HTTP 默認工作在 TCP 協議 80 端口,用戶訪問網站 http:// 打頭的都是標準 HTTP 服務。
HTTP 協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此,HTTP協議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。

HTTPS超文本傳輸安全協議(Hypertext Transfer Protocol Secure:)是一種透過計算機網絡進行安全通信的傳輸協議。HTTPS 經由 HTTP 進行通信,但利用SSL/TLS 來加密數據包。HTTPS 開發的主要目的,是提供對網站服務器的身份認證,保護交換數據的隱私與完整性。HTTPS 默認工作在 TCP 協議443端口。
工作流程一般如以下方式:

1、TCP 三次同步握手
2、客戶端驗證服務器數字證書
3、DH 算法協商對稱加密算法的密鑰、hash 算法的密鑰
4、SSL安全加密隧道協商完成
5、網頁以加密的方式傳輸,用協商的對稱加密算法和密鑰加密,保證數據機密性;用協商的hash算法進行數據完整性保護,保證數據不被篡改。

八、HTTPs的加密算法是什麼

參考鏈接:https://blog.csdn.net/qq_32998153/article/details/80022489

在交換密鑰階段使用公開密鑰加密方式,之後建立通信交換報文階段則使用共享密鑰加密方式。

共享密鑰加密(對稱密鑰加密):加密和解密同用一個密鑰。加密時就必須將密鑰傳送給對方,那麼如何安全的傳輸呢?

公開密鑰加密(非對稱密鑰加密):公開密鑰加密使用一對非對稱的密鑰。一把叫做私有密鑰,一把叫做公開密鑰。私有密鑰不能讓其他任何人知道,而公開密鑰則可以隨意發佈,任何人都可以獲得。使用此加密方式,發送密文的一方使用公開密鑰進行加密處理,對方收到被加密的信息後,再使用自己的私有密鑰進行解密。利用這種方式,不需要發送用來解密的私有密鑰,也不必擔心密鑰被攻擊者竊聽盜走。
但由於公開密鑰比共享密鑰要慢,所以我們就需要綜合一下他們兩者的優缺點,使他們共同使用,而這也是HTTPS採用的加密方式。在交換密鑰階段使用公開密鑰加密方式,之後建立通信交換報文階段則使用共享密鑰加密方式。

這裏就有一個問題,如何證明公開密鑰本省是貨真價實的公開密鑰。如,正準備和某臺服務器建立公開密鑰加密方式下的通信時,如何證明收到的公開密鑰就是原本預想的那臺服務器發行的公開密鑰。或許在公開密鑰傳輸過程中,真正的公開密鑰已經被攻擊者替換掉了。爲了解決這個問題,可以使用由數字證書認證機構(CA,Certificate Authority) 和其他相關機關頒發的 公開密鑰證書

接收到證書的客戶端可以使用數字證書認證機構的公開密鑰,對那張證書上的數字簽名進行驗證,一旦驗證通過,客戶端便可以明確兩件事:
(1)認證服務器的公開密鑰的是真實有效的數字證書認證機構。
(2)服務器的公開密鑰是值得信賴的。

九、TCP相比於UDP爲什麼可靠

被問過,當時自己沒答對方向,所以整理補充了
(1)確認和重傳機制

建立連接時三次握手同步雙方的“序列號 + 確認號 + 窗口大小信息”,是確認重傳、流量控制的基礎
傳輸過程中,如果Checksum校驗失敗、丟包或延時,發送端重傳

(2)數據排序

TCP有專門的序列號SN字段,可提供數據re-order

(3)流量控制

窗口和計時器的使用。TCP窗口中會指明雙方能夠發送接收的最大數據量

(4)擁塞控制

TCP的擁塞控制由4個核心算法組成。
“慢啓動”(Slow Start)
“擁塞避免”(Congestion avoidance)
“快速重傳 ”(Fast Retransmit)
“快速恢復”(Fast Recovery)

十、爲什麼發送 http 請求,卻建立的是 TCP 連接?

被問過,剛自己前一天整理,然後第二天面試就被問到了,開心
幾乎所有的 HTTP 通信都是由 TCP/IP 承載的
HTTP 協議是在 TCP/IP 傳輸層上的應用層協議,TCP 爲 HTTP 提供了一條可靠的
比特傳輸管道。
tcp 是運輸層,http 是應用層。
利用 http 協議傳送數據時建立在 tcp/ip 協議的基礎之上的,所以發送 http 請求,建立的是 TCP 連接。

這裏也可以思考一下,Socket編程又是建立的什麼協議呢,Socket又處於七層模型的哪一層呢?面試官稍微提了一下,這裏自己網上找一下整理一下~~

十一、HTTP狀態碼

被問了兩次
自己整理了一下:HTTP的狀態碼及含義

操作系統

操作系統參考鏈接:https://www.cnblogs.com/edisonchou/p/5094066.html

一、線程和進程區別

這裏擦邊問了一下
進程是資源分配最小單位,線程是程序執行的最小單位;
區別如下:
(1)進程有自己獨立的地址空間,每啓動一個進程,系統都會爲其分配地址空間,建立數據表來維護代碼段、堆棧段和數據段,線程沒有獨立的地址空間,它使用相同的地址空間共享數據;
(2)CPU 切換一個線程比切換進程花費小;創建一個線程比進程開銷小;線程佔用的資源要比進程少很多。
(3)線程之間通信更方便,同一個進程下,線程共享全局變量,靜態變量等數據,進程之間的通信需要以通信的方式(IPC)進行;(但多線程程序處理好同步與互斥是個難點)
(4)多進程程序更安全,生命力更強,一個進程死掉不會對另一個進程造成影響(源於有獨立的地址空間),多線程程序更不易維護,一個線程死掉,整個進程就死掉了(因爲共享地址空間);

二、進程切換和線程切換

被問過一次
進程切換和線程切換分別需要哪些處理過程,我當時不太記得了就隨便按照自己的理解答得,這裏可以自己查閱一下資料,根據前面進程和線程的區別整理一下。

三、死鎖,四個必要條件,怎麼避免

如果一組進程中的每一個進程都在等待僅由該組進程中的其它進程才能引發的事件,那麼該組進程就是死鎖的。

產生死鎖的四個必要條件
(1)互斥條件:一個資源每次只能被一個進程使用,即在一段時間內某資源僅爲一個進程所佔有。此時若有其他進程請求該資源,則請求進程只能等待。
(2)請求與保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求時,該資源已被其他進程佔有,此時請求進程被阻塞,但對自己已獲得的資源保持不放。
(3)不可剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能由獲得該資源的進程自己來釋放(只能是主動釋放)。
(4)循環等待條件: 若干進程間形成首尾相接循環等待資源的關係

怎麼避免
(1)系統對進程發出每一個系統能夠滿足的資源申請進行動態檢查,並根據檢查結果決定是否分配資源,如果分配後系統可能發生死鎖,則不予分配,否則予以分配。這是一種保證系統不進入死鎖狀態的動態策略。
(2)破壞不可搶佔條件:允許對資源實行搶奪

利用銀行家算法避免死鎖
所謂銀行家算法,是指在分配資源之前先看清楚,資源分配後是否會導致系統死鎖。如果會死鎖,則不分配,否則就分配。

四、內存分頁以及怎麼處理內存碎片

內存分頁:分頁系統的核心在於,將虛擬內存空間和物理內存空間皆劃分爲大小相同的頁面,如4KB、8KB或16KB等,並以頁面作爲內存空間的最小分配單位,一個程序的一個頁面可以存放在任意一個物理頁面裏。

(1)解決空間浪費碎片化問題
由於將虛擬內存空間和物理內存空間按照某種規定的大小進行分配,這裏我們稱之爲頁(Page),然後按照頁進行內存分配,也就克服了外部碎片的問題。
(2)解決程序大小受限問題
程序增長有限是因爲一個程序需要全部加載到內存才能運行,因此解決的辦法就是使得一個程序無須全部加載就可以運行。使用分頁也可以解決這個問題,只需將當前需要的頁面放在內存裏,其他暫時不用的頁面放在磁盤上,這樣一個程序同時佔用內存和磁盤,其增長空間就大大增加了。而且,分頁之後,如果一個程序需要更多的空間,給其分配一個新頁即可(而無需將程序倒出倒進從而提高空間增長效率)。

內存碎片通常分爲內部碎片外部碎片

  1. 內部碎片是由於採用固定大小的內存分區,當一個進程不能完全使用分給它的固定內存區域時就產生了內部碎片,通常內部碎片難以完全避免;
  2. 外部碎片是由於某些未分配的連續內存區域太小,以至於不能滿足任意進程的內存分配請求,從而不能被進程利用的內存區域。
    現在普遍採用的段頁式內存分配方式就是將進程的內存區域分爲不同的段,然後將每一段由多個固定大小的頁組成。通過頁表機制,使段內的頁可以不必連續處於同一內存區域,從而減少了外部碎片,然而同一頁內仍然可能存在少量的內部碎片,只是一頁的內存空間本就較小,從而使可能存在的內部碎片也較少。

1、虛擬地址的構成
  在分頁系統下,一個程序發出的虛擬地址由兩部分組成:頁面號和頁內偏移值,如下圖所示:
在這裏插入圖片描述
例如,對於32位尋址的系統,如果頁面大小爲4KB,則頁面號佔20位,頁內偏移值佔12位。
2、地址翻譯:虛擬地址→物理地址(映射)
分頁系統的核心是頁面的翻譯,即從虛擬頁面到物理頁面的映射(Mapping)。該翻譯過程如下僞代碼所示:

if(虛擬頁面非法、不在內存中或被保護)
{
    陷入到操作系統錯誤服務程序
}
else
{
    將虛擬頁面號轉換爲物理頁面號
    根據物理頁面號產生最終物理地址
}

這個翻譯是怎麼實現的呢?
答:查頁表。對於每個程序,內存管理單元MMU都爲其保存一個頁表,該頁表中存放的是虛擬頁面到物理頁面的映射。每當爲一個虛擬頁面尋找到一個物理頁面之後,就在頁表裏增加一條記錄來保留該映射關係。當然,隨着虛擬頁面進出物理內存,頁表的內容也會不斷更新變化。
在這裏插入圖片描述
頁表
頁表的根本功能是提供從虛擬頁面到物理頁面的映射
因此,頁表的記錄條數與虛擬頁面數相同。此外,內存管理單元依賴於頁表來進行一切與頁面有關的管理活動,這些活動包括判斷某一頁面號是否在內存裏,頁面是否受到保護,頁面是否非法空間等等。
頁表的一個記錄所包括的內容如下圖所示:
在這裏插入圖片描述

由於頁表的特殊地位,決定了它是由硬件直接提供支持,即頁表是一個硬件數據結構。

五、缺頁中斷及處理

這裏被問過
在分頁系統中,一個虛擬頁面既有可能在物理內存,也有可能保存在磁盤上。如果CPU發出的虛擬地址對應的頁面不在物理內存,就將產生一個缺頁中斷,而缺頁中斷服務程序負責將需要的虛擬頁面找到並加載到內存。缺頁中斷的處理步驟如下,省略了中間很多的步驟,只保留最核心的幾個步驟:
在這裏插入圖片描述

六、頁面調度置換算法中的FiFO、LRU和LFU

然後給了些例子要求解釋最近應該要調那個頁,簡單。
頁面置換時挑選頁面的目標主要在於降低隨後發生缺頁中斷的次數或概率。

FIFO先進先出 First In First Out,這個沒啥好講的;
LRU最近最少使用頁面置換算法(Least Recently Used),選擇近期最少訪問的頁作爲被替換頁。即首先淘汰最長時間未被使用的頁面!
LFU最近最不常用頁面置換算法(Least Frequently Used),淘汰一定時期內被訪問次數最少的頁,在內存保留的都是一些經常訪問的對象。對於大部分網站項目,該算法比較適用。

比如,第二種方法的時期T爲10分鐘,如果每分鐘進行一次調頁,主存塊爲3,若所需頁面走向爲2 1 2 1 2 3 4
注意,當調頁面4時會發生缺頁中斷
若按LRU算法,應換頁面1(1頁面最久未被使用) 但按LFU算法應換頁面3(十分鐘內,頁面3只使用了一次)
可見LRU是看頁面最後一次被使用 到 發生調度的時間
而LFU是看一定時間段內頁面被使用的頻率!

七、進程間通信方式:信號、管道、消息隊列、共享內存

  1. 管道pipe:管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
  2. 命名管道FIFO:有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
  3. 消息隊列MessageQueue:消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
  4. 共享存儲SharedMemory:共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
  5. 信號量Semaphore:信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
  6. 套接字Socket:套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。
  7. 信號 ( sinal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。

1、信號

信號是Linux系統中用於進程之間通信或操作的一種機制,信號可以在任何時候發送給某一進程,而無須知道該進程的狀態。如果該進程並未處於執行狀態,則該信號就由內核保存起來,知道該進程恢復執行並傳遞給他爲止。如果一個信號被進程設置爲阻塞,則該信號的傳遞被延遲,直到其阻塞被取消時才被傳遞給進程。

信號是在軟件層次上對中斷機制的一種模擬,是一種異步通信方式,信號可以在用戶空間進程和內核之間直接交互。內核也可以利用信號來通知用戶空間的進程來通知用戶空間發生了哪些系統事件。信號事件有兩個來源:
1)硬件來源,例如按下了cltr+C,通常產生中斷信號sigint
2)軟件來源,例如使用系統調用或者命令發出信號。最常用的發送信號的系統函數是kill,raise,setitimer,sigation,sigqueue函數。軟件來源還包括一些非法運算等操作。

用戶進程對信號產生的響應有三種方式:執行默認操作、捕捉信號、忽略信號

1)執行默認操作,linux對每種信號都規定了默認操作。
2)捕捉信號,定義信號處理函數,當信號發生時,執行相應的處理函數。
3)忽略信號,當不希望接收到的信號對進程的執行產生影響,而讓進程繼續執行時,可以忽略該信號,即不對信號進程作任何處理。
管道允許在進程之間按先進先出的方式傳送數據,是進程間通信的一種常見方式。

2、管道
管道是Linux 支持的最初Unix IPC形式之一,具有以下特點:

  1. 管道是半雙工的,數據只能向一個方向流動;需要雙方通信時,需要建立起兩個管道;
  2. 匿名管道只能用於父子進程或者兄弟進程之間(具有親緣關係的進程);
  3. 單獨構成一種獨立的文件系統:管道對於管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬於某種文件系統,而是自立門戶,單獨構成一種文件系統,並且只存在與內存中。

管道分爲 pipe(無名管道)fifo(命名管道) 兩種,除了建立、打開、刪除的方式不同外,這兩種管道幾乎是一樣的。他們都是通過內核緩衝區實現數據傳輸。
pipe用於相關進程之間的通信,例如父進程和子進程,它通過pipe()系統調用來創建並打開,當最後一個使用它的進程關閉對他的引用時,pipe將自動撤銷。
FIFO即命名管道,在磁盤上有對應的節點,但沒有數據塊——換言之,只是擁有一個名字和相應的訪問權限,通過mknode()系統調用或者mkfifo()函數來建立的。一旦建立,任何進程都可以通過文件名將其打開和進行讀寫,而不侷限於父子進程,當然前提是進程對FIFO有適當的訪問權。當不再被進程使用時,FIFO在內存中釋放,但磁盤節點仍然存在。

管道的實質是一個內核緩衝區,進程以先進先出的方式從緩衝區存取數據:管道一端的進程順序地將進程數據寫入緩衝區,另一端的進程則順序地讀取數據,該緩衝區可以看做一個循環隊列,讀和寫的位置都是自動增加的,一個數據只能被讀一次,讀出以後再緩衝區都不復存在了。當緩衝區讀空或者寫滿時,有一定的規則控制相應的讀進程或寫進程是否進入等待隊列,當空的緩衝區有新數據寫入或慢的緩衝區有數據讀出時,就喚醒等待隊列中的進程繼續讀寫。

3、消息隊列
消息隊列,就是一個消息的鏈表,是一系列保存在內核中消息的列表。用戶進程可以向消息隊列添加消息,也可以向消息隊列讀取消息。

消息隊列與管道通信相比,其優勢是對每個消息指定特定的消息類型,接收的時候不需要按照隊列次序,而是可以根據自定義條件接收特定類型的消息。

可以把消息看做一個記錄,具有特定的格式以及特定的優先級。對消息隊列有寫權限的進程可以向消息隊列中按照一定的規則添加新消息,對消息隊列有讀權限的進程可以從消息隊列中讀取消息。

4、共享內存
共享內存允許兩個或多個進程共享一個給定的存儲區,這一段存儲區可以被兩個或兩個以上的進程映射至自身的地址空間中,一個進程寫入共享內存的信息,可以被其他使用這個共享內存的進程,通過一個簡單的內存讀取錯做讀出,從而實現了進程間的通信。

採用共享內存進行通信的一個主要好處是效率高,因爲進程可以直接讀寫內存,而不需要任何數據的拷貝,對於像管道和消息隊裏等通信方式,則需要再內核和用戶空間進行四次的數據拷貝,而共享內存則只拷貝兩次:一次從輸入文件到共享內存區,另一次從共享內存到輸出文件。
共享內存有兩種實現方式:1、內存映射 2、共享內存機制

參考連接:https://www.cnblogs.com/LUO77/p/5816326.html

進程間通信的方式:信號量、管道…
內存分頁以及怎麼處理內存碎片
————————————————
版權聲明:本文爲CSDN博主「Alva112358」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Alva112358/article/details/93934413

八、linux搜索出log文本中出現次數最多的IP,並且給出次數

建議簡歷裏如果寫了Linux這個東西的話,可以稍微簡單準備一下Linux的基礎的文件目錄操作。

數據庫

一、數據庫的四大特徵(ACID)

這個非常重要!!!死背也得背住,我被問了四次,頻率被問的最高的

這裏一定要能說出自己對每一個特性的理解,也就是對這每一個特性的概念,說一遍。。。

(1)原子性(Atomicity)
原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾。

(2)一致性(Consistency)
一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之後都必須處於一致性狀態。

(3)隔離性(Isolation)
隔離性是當多個用戶併發訪問數據庫時,比如操作同一張表時,數據庫爲每一個用戶開啓的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離。

(4)持久性(Durability)
持久性是指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

參考鏈接:https://www.cnblogs.com/fjdingsd/p/5273008.html

二、如果不考慮事務的隔離性,會發生幾種問題

1、髒讀
髒讀是指在一個事務處理過程裏讀取了另一個未提交的事務中的數據。
2、不可重複讀
不可重複讀是指在對於數據庫中的某個數據,一個事務範圍內多次查詢卻返回了不同的數據值,這是由於在查詢間隔,被另一個事務修改並提交了。
3、虛讀(幻讀)
幻讀是事務非獨立執行時發生的一種現象。
幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個數據項,而幻讀針對的是一批數據整體(比如數據的個數)。

三、MySQL數據庫提供的四種隔離級別

被問過兩次
① Serializable (串行化):可避免髒讀、不可重複讀、幻讀的發生。
② Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
③ Read committed (讀已提交):可避免髒讀的發生。
④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。

以上四種隔離級別最高的是Serializable級別,最低的是Read uncommitted級別,當然級別越高,執行效率就越低。像Serializable這樣的級別,就是以鎖表的方式(類似於Java多線程中的鎖)使得其他的線程只能在鎖外等待,所以平時選用何種隔離級別應該根據實際情況。在MySQL數據庫中默認的隔離級別爲Repeatable read (可重複讀)。

在MySQL數據庫中,支持上面四種隔離級別,默認的爲Repeatable read (可重複讀);而在Oracle數據庫中,只支持Serializable (串行化)級別和Read committed (讀已提交)這兩種級別,其中默認的爲Read committed級別。

四、數據庫怎麼分頁

MySQL 實現分頁效果比較簡單,只有一個 limit 關鍵字就可以解決。

五、內連接外連接左連接右連接

被問過兩次
一、內連接
關鍵字:inner join on
說明:組合兩個表中的記錄,返回關聯字段相符的記錄,也就是返回兩個表的交
集(陰影)部分。

二、左連接(左外連接)
關鍵字:left join on / left outer join on
它的全稱是左外連接,是外連接中的一種。
左(外)連接,左表(a_table)的記錄將會全部表示出來,而右表(b_table)只會顯示符
合搜索條件的記錄。右表記錄不足的地方均爲 NULL。

三、右連接(右外連接)
關鍵字:right join on / right outer join on
它的全稱是右外連接,是外連接中的一種。
與左(外)連接相反,右(外)連接,左表(a_table)只會顯示符合搜索條件的記錄,而
右表(b_table)的記錄將會全部表示出來。左表記錄不足的地方均爲 NULL。

四、全外連接(FULL JOIN 或 FULL OUTER JOIN)
完整外部聯接返回左表和右表中的所有行。

六、Group By 語句

Group By 語句從英文的字面意義上理解就是“根據(by)一定的規則進行分組(Group)”。
作用:通過一定的規則將一個數據集劃分成若干個小的區域,然後針對若干個小區域進行數據處理。
注意:group by 是先排序後分組

七、聚合函數有什麼特點?

聚合函數對一組值執行計算並返回單一的值。
除了 COUNT 以外,聚合函數忽略空值。
聚合函數經常與 SELECT 語句的 GROUP BY 子句一同使用。
所有聚合函數都具有確定性。任何時候用一組給定的輸入值調用它們時,都返回相同的值。
1、求個數/記錄數/項目數等:count()
2、求某一列平均數 :avg()
3、求總和,總分等:sum() --必須爲數字列
4、求最大值,最高分,最高工資等:max()

在實際應用中,聚合函數常和分組函數 group by 結合使用,用來查詢.where 子句的作用對象一般只是行,用來作爲過濾數據的條件。

標量函數:只能對單個的數字或值進行計算。主要包括字符函數、日期/時間函數、數值函數和轉換函數這四類。

八、索引的作用

數據庫索引被問過兩到三次,建議看幾篇和數據庫索引相關的博客
創建索引可以大大提高系統的性能。
第一,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
第二,可以大大加快 數據的檢索速度,這也是創建索引的最主要的原因。
第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

九、怎麼建立索引?

學生學號姓名年級成績老師入學時間 可以根據什麼來建立索引

建議將學號建爲主鍵。主鍵 建個聚集索引 其他兩個建立非聚集的。

算法

一、說一下hashmap這個數據結構

他現在的實現方式是數組+鏈表+紅黑樹,通過計算hash,將對象存進hashmap中,當鏈表的長度大於8,鏈表進化爲紅黑樹,鏈表小於6,紅黑樹退化爲鏈表,這樣能防止頻繁的進行紅黑樹的轉化,然後紅黑樹的話通過着色和旋轉進行自平衡。

二、進行一次查找,haspmap的時間複雜度是多少

O(1),這個是作爲數組的查詢複雜度。

三、有一個無限長的整型數組,從小到大排序,非遞增。那麼怎麼找到數組中一個key

模仿計算機網絡的慢開始,第一次步長爲2,第二次步長爲4,第三次爲8,持續爲2的冪次,大於key時,再在當前位置和當前位置-步長範圍內查找。
時間複雜度多少? O(logn)

Java基礎

強烈推薦這個博主的專欄Java筆試面試

然後先畫個重點,關於JVM,如果自己時間很緊,不是追求大企業,我覺得看我這一篇文章應該就可以應付:Java虛擬機JVM的內存數據區域

下面這些自己整理的內容是參考:https://www.jianshu.com/p/01f0cb5d4e67

後面這些看一遍,理解了有個印象就行。。。

什麼是線程局部變量?

線程局部變量是侷限於線程內部的變量,屬於線程自身所有,不在多個線程間共享。Java 提供 ThreadLocal 類來支持線程局部變量,是一種實現線程安全的方式。但是在管理環境下(如 web 服務器)使用線程局部變量的時候要特別小心,在這種情況下,工作線程的生命週期比任何應用變量的生命週期都要長。任何線程局部變量一旦在工作完成後沒有釋放,Java 應用就存在內存泄露的風險。

Java 中 sleep 方法和 wait 方法的區別?

雖然兩者都是用來暫停當前運行的線程,但是 sleep() 實際上只是短暫停頓,因爲它不會釋放鎖,而 wait() 意味着條件等待,這就是爲什麼該方法要釋放鎖,因爲只有這樣,其他等待的線程才能在滿足條件時獲取到該鎖。

什麼是不可變對象?Java 怎麼創建?

不可變對象(immutable object)
不可變對象指對象一旦被創建,狀態就不能再改變。任何修改都會創建一個新的對象,如 String、Integer及其它包裝類。詳情參見答案,一步一步指導你在 Java 中創建一個不可變的類。

怎麼將 byte 轉換爲 String?

可以使用 String 接收 byte[] 參數的構造器來進行轉換,需要注意的點是要使用的正確的編碼,否則會使用平臺默認編碼,這個編碼可能跟原來的編碼相同,也可能不同。

哪個類包含 clone 方法?是 Cloneable 還是 Object?

clone 方法在 object 類中定義。
java.lang.Cloneable 是一個標示性接口,不包含任何方法,並且需要知道 clone() 方法是一個本地方法,這意味着它是由 c 或 c++ 或 其他本地語言實現的。

a = a + b 與 a += b 的區別

+= 隱式的將加操作的結果類型強制轉換爲持有結果的類型。如果兩這個整型相加,如 byte、short 或者 int,首先會將它們提升到 int 類型,然後在執行加法操作。如果加法操作的結果比 a 的最大值要大,則 a+b 會出現編譯錯誤,但是 a += b 沒問題,如下:
byte a = 127;
byte b = 127;
b = a + b; // error : cannot convert from int to byte
b += a; // ok
(譯者注:這個地方應該表述的有誤,其實無論 a+b 的值爲多少,編譯器都會報錯,因爲 a+b 操作會將 a、b 提升爲 int 類型,所以將 int 類型賦值給 byte 就會編譯出錯)

Java 中的構造器鏈是什麼?

當你從一個構造器中調用另一個構造器,就是Java 中的構造器鏈。這種情況只在重載了類的構造器的時候纔會出現。

JVM和GC

Serial 與 Parallel GC之間的不同之處?

Serial 與 Parallel 在GC執行的時候都會引起 stop-the-world。它們之間主要不同 serial 收集器是默認的複製收集器,執行 GC 的時候只有一個線程,
而 parallel 收集器使用多個 GC 線程來執行。

WeakReference 與 SoftReference的區別?

雖然 WeakReference 與 SoftReference 都有利於提高 GC 和 內存的效率,但是 WeakReference ,一旦失去最後一個強引用,就會被 GC 回收,
而軟引用雖然不能阻止被回收,但是可以延遲到 JVM 內存不足的時候。

WeakHashMap 是怎麼工作的?

WeakHashMap 的工作與正常的 HashMap 類似,但是使用弱引用作爲 key,意思就是當 key 對象沒有任何引用時,key/value 鍵值對將會被回收。

JVM 選項 -XX:+UseCompressedOops 有什麼作用?爲什麼要使用?

當你將你的應用從 32 位的 JVM 遷移到 64 位的 JVM 時,由於對象的指針從 32 位增加到了 64 位,因此堆內存會突然增加,差不多要翻倍。這也會對 CPU 緩存(容量比內存小很多)的數據產生不利的影響。因爲,遷移到 64 位的 JVM 主要動機在於可以指定最大堆大小,通過壓縮 OOP 可以節省一定的內存。通過 -XX:+UseCompressedOops 選項,JVM 會使用 32 位的 OOP,而不是 64 位的 OOP。

JRE、JDK、JVM 及 JIT 之間有什麼不同?

JRE 代表 Java 運行時(Java run-time),是運行 Java 引用所必須的。
JDK 代表 Java 開發工具(Java development kit),是 Java 程序的開發工具,如 Java 編譯器,它也包含 JRE。
JVM 代表 Java 虛擬機(Java virtual machine),它的責任是運行 Java 應用。
JIT 代表即時編譯(Just In Time compilation),當代碼執行的次數超過一定的閾值時,會將 Java 字節碼轉換爲本地代碼,如主要的熱點代碼會被轉換爲本地代碼,這樣有利大幅度提高 Java 應用的性能。

解釋 Java 堆空間及 GC?

當通過 Java 命令啓動 Java 進程的時候,會爲它分配內存。內存的一部分用於創建堆空間,當程序中創建對象的時候,就從對空間中分配內存。
GC 是 JVM 內部的一個進程,回收無效對象的內存用於將來的分配。

Java 中堆和棧有什麼區別?

JVM 中堆和棧屬於不同的內存區域,使用目的也不同。棧常用於保存方法幀和局部變量,而對象總是在堆上分配。
棧通常都比堆小,也不會在多個線程之間共享,而堆被整個 JVM 的所有線程共享。

hashCode() 的作用?a.equals(b) 有何關係?

hashCode() 方法是相應對象整型的 hash 值。它常用於基於 hash 的集合類,如 Hashtable、HashMap、LinkedHashMap等等。它與 equals() 方法關係特別緊密。根據 Java 規範,兩個使用 equal() 方法來判斷相等的對象,必須具有相同的 hash code。

final、finalize 和 finally 的不同之處?

final 是一個修飾符,可以修飾變量、方法和類。如果 final 修飾變量,意味着該變量的值在初始化後不能被改變
finalize() 方法是在對象被回收之前調用的方法,給對象自己最後一個復活的機會,但是什麼時候調用 finalize 沒有保證。
finally 是一個關鍵字,與 try 和 catch 一起用於異常的處理。finally 塊一定會被執行,無論在 try 塊中是否有發生異常。

Java 中的編譯期常量是什麼?使用它又什麼風險?

公共靜態不可變public static final )變量也就是我們所說的編譯期常量,這裏的 public 可選的。實際上這些變量在編譯時會被替換掉,因爲編譯器知道這些變量的值,並且知道這些變量在運行時不能改變。這種方式存在的一個問題是你使用了一個內部的或第三方庫中的公有編譯時常量,但是這個值後面被其他人改變了,但是你的客戶端仍然在使用老的值,甚至你已經部署了一個新的jar。爲了避免這種情況,當你在更新依賴 JAR 文件時,確保重新編譯你的程序。

List、Set、Map 和 Queue 之間的區別(答案)

List 是一個有序集合,允許元素重複。它的某些實現可以提供基於下標值的常量訪問時間,但是這不是 List 接口保證的。
Set 是一個無序集合。

poll() 方法和 remove() 方法的區別?

poll() 和 remove() 都是從隊列中取出一個元素,但是 poll() 在獲取元素失敗的時候會返回空,但是 remove() 失敗的時候會拋出異常。

Java 中 LinkedHashMap 和 PriorityQueue 的區別

PriorityQueue 保證最高或者最低優先級的的元素總是在隊列頭部,但是 LinkedHashMap 維持的順序是元素插入的順序。
當遍歷一個 PriorityQueue 時,沒有任何順序保證,但是 LinkedHashMap 課保證遍歷順序是元素插入的順序。

ArrayList 與 LinkedList 的區別?

ArrrayList 底層的數據結構是數組,支持隨機訪問
而 LinkedList 的底層數據結構書鏈表,不支持隨機訪問。
使用下標訪問一個元素,ArrayList 的時間複雜度是 O(1),而 LinkedList 是 O(n)。

用哪兩種方式來實現集合的排序?

可以使用無序集合,如 TreeSet 或 TreeMap,你也可以使用有順序的的集合,如 list,然後通過 Collections.sort() 來排序。

Java 中怎麼打印數組?

你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法來打印數組。由於數組沒有實現 toString() 方法,所以如果將數組傳遞給 System.out.println() 方法,將無法打印出數組的內容,但是 Arrays.toString() 可以打印每個元素。

Java 中的 LinkedList 是單向鏈表還是雙向鏈表?

是雙向鏈表,你可以檢查 JDK 的源碼。在 Eclipse,你可以使用快捷鍵 Ctrl + T,直接在編輯器中打開該類。

Java 中的 TreeMap 是採用什麼樹實現的?

Java 中的 TreeMap 是使用紅黑樹實現的。

Hashtable 與 HashMap 有什麼不同之處?(答案)

這兩個類有許多不同的地方,下面列出了一部分:
a) Hashtable 是 JDK 1 遺留下來的類,而 HashMap 是後來增加的。
b)Hashtable 是同步的,比較慢,但 HashMap 沒有同步策略,所以會更快。
c)Hashtable 不允許有個空的 key,但是 HashMap 允許出現一個 null key。

Java 中的 HashSet,內部是如何工作的?

HashSet 的內部採用 HashMap來實現。由於 Map 需要 key 和 value,所以所有 key 的都有一個默認 value。類似於 HashMap,HashSet 不允許重複的 key,只允許有一個null key,意思就是 HashSet 中只允許存儲一個 null 對象。

寫一段代碼在遍歷 ArrayList 時移除一個元素?

public class test{
	public static void main(String[] args){
		ArrayList<Sting> aList = new ArrayList<String>();
		aList.add("a");
		aList.add("ab");  
        aList.add("abc");  
        aList.add("abcr");  
        aList.add("abc");  
        aList.add("abcf");  
        aList.add("abc");  
        aList.add("abdc");  
		Itrator<Sting> it = aList.iterator();
		while(it.hasNext()){
			if(it.next().equals("abc"))
				it.remove();
		}
	}
}

能自己寫一個容器類,然後使用 for-each 循環碼?

可以,你可以寫一個自己的容器類。如果你想使用 Java 中增強的循環來遍歷,你只需要實現 Iterable 接口。如果你實現 Collection 接口,默認就具有該屬性。

ArrayList 和 HashMap 的默認大小是多數?

在 Java 7 中,ArrayList 的默認大小是 10 個元素,HashMap 的默認大小是16個元素(必須是2的冪)。

說下java的GC

答:現在是分代收集方式,首先進行垃圾對象的判斷,判斷的話有兩種方法:引用計數和可達性分析。
引用計數就是有一處引用了該對象就計數+1,當計數器爲0時,代表沒有地方引用他,可以回收,但是沒法解決循環引用問題,現在主流虛擬機都不用這種辦法。
可達性分析是選了一些對象作爲GCROOTS,當從gcroots出發沒有引用線時可回收。
垃圾回收的話就是有三種,標記清除標記整理複製算法

我寫的簡歷裏項目常問的題

下面這些是針對我自己簡歷的項目,做出的一些總結,對於我簡歷裏的項目,我基本就都是講的這些知識點。

*一、SSM框架的理解

SSM框架是spring MVC ,spring和mybatis框架的整合,是標準的MVC模式。
將整個系統劃分爲 表現層,controller層,service層,DAO層 四層

使用spring MVC負責請求的轉發和視圖管理

spring實現業務對象管理,mybatis作爲數據對象的持久化引擎

SpringMVC的原理

1.客戶端發送請求到DispacherServlet(分發器)

2.由DispacherServlet控制器查詢HanderMapping,找到處理請求的Controller

3.Controller調用業務邏輯處理後,返回ModelAndView

4.DispacherSerclet查詢視圖解析器,找到ModelAndView指定的視圖

5.視圖負責將結果顯示到客戶端
在這裏插入圖片描述
————————————————
版權聲明:本文爲CSDN博主「bieleyang」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bieleyang/article/details/77862042

*二、談談對spring的理解

Spring:我們平時開發接觸最多的估計就是IOC容器,它可以裝載bean(也就是我們Java中的類,當然也包括service dao裏面的),有了這個機制,我們就不用在每次使用這個類的時候爲它初始化,很少看到關鍵字new。另外spring的aop,事務管理等等都是我們經常用到的。

1.spring的工作原理
spring 是按照設計模式精心打造的,它實現了工廠模式的工廠類,這個類名爲BeanFactory(接口),在程序中通常使用它的子類ApplicationContext(也是接口)。

spring的核心是IOC(反轉控制)容器,IOC也是一種編程思想,用於實現模塊之間的解耦,在Spring中它的作用是對對象的創建,維護和銷燬等生命週期的控制。IOC:把對象的創建、初始化、銷燬交給spring來管理,而不是由開發者控制,實現控制反轉。

spring是一個大的工廠類,spring的特點就是基於配置,在其配置文件中通過元素來創建實例對象。

根據業務邏輯來看,對象經常不是獨立的,一個對象的創建往往涉及另一個對象的創建,當然這個對象也要由IOC容器負責,負責的方式就是依賴注入DI,通過反射機制實現。有三種注入方式:(1)接口注入(2)構造器注入(3)Setter方法注入。

2.spring的核心技術
spring的核心技術有:IOC,AOP

java 的 高級特性:反射機制,代理

AOP:面向切面編程,系統中有很多各不相干的類的方法,在這衆多方法中加入某種系統功能的代碼,如加入日誌,權限判斷等,AOP可以實現橫切關注點(如日誌,安全,緩存和事務管理)與他們所影響的對象之間的解耦。

實現AOP 功能採用的是代理技術,調用代理類,代理類與目標類具有相同的方法聲明。

AOP 在spring中主要表現在兩個方面:提供聲明式的事務管理 、spring支持用戶自定義切面。

spring AOP的使用在另外一位同學的博客中可以看到:Java Spring AOP用法

AOP主要包括通知(Advice)切點(PointCut)連接點(JoinPoint)

下面貼一段在springboot 中使用AOP的代碼:

        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

@Aspect
@Component
public class ControllerInterceptor {
 
    private final Logger logger = LogManager.getLogger(this.getClass());
    @Pointcut("execution(public * com.example.homework.controller..*(..))")
    public void controllerMethodPointcut(){}
 
    @Before("controllerMethodPointcut()") //指定攔截器規則
    public Object interceptor(JoinPoint jp){
        MethodSignature signature = (MethodSignature) jp.getSignature();
        Method method = signature.getMethod(); //獲取被攔截的方法
        String methodName = method.getName(); //獲取被攔截的方法名
        logger.info("interceptor ***************************");
        logger.info("methodName: "+methodName);
        return null;
    }
}
2018-08-21 11:07:22.906  INFO 10392 --- [nio-8088-exec-1] a.s.s.m.AbstractValidatingSessionManager : Enabling session validation scheduler...
2018-08-21 11:07:22.987  INFO 10392 --- [nio-8088-exec-1] c.e.h.controller.ControllerInterceptor   : interceptor ***************************
2018-08-21 11:07:22.987  INFO 10392 --- [nio-8088-exec-1] c.e.h.controller.ControllerInterceptor   : methodName: loginIn

3.spring 的優缺點
Spring 的核心概念是IOC和AOP,這兩個核心服務的對象算是bean(POJO),定位是一個輕量級的框架,但是隨着他的發展變得很龐大,我們稱它爲spring 全家桶。

它具備以下優點:

  1. spring中避免了關鍵字new造成的耦合問題。
  2. spring本身就是一個工廠,不需要再編寫工廠類了。
  3. spring不需要進行明確的引用關係的傳遞,直接通過配置完成
  4. 所有框架幾乎都可以在spring中整合在一起使用。
  5. spring編程=factory設計模式+proxy設計模式

當然,它的缺點也是不少的:
spring基於大量的xml 配置文件,使得我們花了大量的時間放在配置上,拖慢了開發的進度,springboot 問世後,提倡代碼優於配置解決了這個問題。

spring 的內容太龐大,隨便打斷點查看的時候會出現十幾二十層代碼,閱覽性不強,在實際開發的過程中spring的角色更像是膠水一樣,充當整合各種技術的角色,同時作爲bean的容器。

————————————————
版權聲明:本文爲CSDN博主「花豬秀兒」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wolf_goat/article/details/81874862

*三、SSM開發的流程

正向從entity到dao 到mapper到service到controller。
1、首先根據業務,確定實體類(一般與數據庫的表一一對應)和封裝類(Controller返回的對象類,一般是實體類的部分字段或是實體類的List或者業務衍生出的字段的集合)
2、根據第一步的封裝類,編寫dao以及對應的mapper,dao的邏輯就是爲了產生封裝類的屬性(部分屬性可直接產生,還有一部分屬性需要到service層對數據處理才能產生)。
3、根據業務需求,編寫service層,service層對dao層產生的數據進行處理,把封裝類的屬性全部設置進去返回。
4、最後編寫controller層代碼,需提前與前端確定好URL規範,調用service得到返回的封裝類,加上@ResponseBody註解返回

我們把所有的dao和service都交由spring來管理,在spring-mybatis.xml文件中,我們指定了dao的位置,所以dao層不需要手動加註解,但是service,controller層需要我們手動加上註解@Service(此註解加在Service的實現類上) @Controller。
——————————————————————————————————
參考:https://blog.csdn.net/qq_33591903/article/details/81101975

*四、MyBatis及工作原理

mybatis是對jdbc的封裝,它讓數據庫底層操作變的透明。mybatis的操作都是圍繞一個sqlSessionFactory實例展開的。mybatis通過配置文件關聯到各實體類的Mapper文件,Mapper文件中配置了每個類對數據庫所需進行的sql語句映射。在每次與數據庫交互時,通過sqlSessionFactory拿到一個sqlSession,再執行sql命令。

原理圖如下:
在這裏插入圖片描述
(1)mybatis應用程序通過SqlSessionFactoryBuilder從mybatis-config.xml配置文件(也可以用Java文件配置的方式,需要添加@Configuration)來構建SqlSessionFactory(SqlSessionFactory是線程安全的);
(2)SqlSessionFactory的實例直接開啓一個SqlSession,再通過SqlSession實例獲得Mapper對象並運行Mapper映射的SQL語句,完成對數據庫的CRUD和事務提交,之後關閉SqlSession。

說明:SqlSession是單線程對象,因爲它是非線程安全的,是持久化操作的獨享對象,類似jdbc中的Connection,底層就封裝了jdbc連接。

詳細流程如下
1、加載mybatis全局配置文件(數據源、mapper映射文件等),解析配置文件,MyBatis基於XML配置文件生成Configuration,和一個個MappedStatement(包括了參數映射配置、動態SQL語句、結果映射配置),其對應着<select | update | delete | insert>標籤項。
2、SqlSessionFactoryBuilder通過Configuration對象生成SqlSessionFactory,用來開啓SqlSession。
3、SqlSession對象完成和數據庫的交互:

  • a、用戶程序調用mybatis接口層api(即Mapper接口中的方法)
  • b、SqlSession通過調用api的Statement ID找到對應的MappedStatement對象
  • c、通過Executor(負責動態SQL的生成和查詢緩存的維護)將MappedStatement對象進行解析,sql參數轉化、動態sql拼接,生成jdbc Statement對象
  • d、JDBC執行sql。
  • e、藉助MappedStatement中的結果映射關係,將返回結果轉化成HashMap、JavaBean等存儲結構並返回。

————————————————————————————————
學習參考網站:
[1] http://c.biancheng.net/view/4304.html
[2]https://blog.csdn.net/u014745069/article/details/80788127

補充:cookie 和session 的區別:

1、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
3、session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能考慮到減輕服務器性能方面,應當使用COOKIE。
4、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
5、所以個人建議:
將登陸信息等重要信息存放爲SESSION
其他信息如果需要保留,可以放在COOKIE中

*Maven項目的生命週期

開始—>Validate驗證—>Compile編譯—>Test測試—>Package打包—>Verify檢查—>Install安裝—>Deploy部署—>開始

*Servelet的生命週期

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章