java實(shí)習(xí)--每天打卡十道面試題!
1、Cookie的實(shí)現(xiàn)原理?
參考文章:
Cookie 工作原理如圖所示:

執(zhí)行流程:
- 瀏覽器向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器需要?jiǎng)?chuàng)建 cookie,服務(wù)器會(huì)通過(guò)響應(yīng)攜帶 cookie,在產(chǎn)生響應(yīng)時(shí)會(huì)產(chǎn)生 Set-Cookie 響應(yīng)頭,從而將 cookie 信息傳遞給了瀏覽器;
- 當(dāng)瀏覽器再次向服務(wù)器發(fā)送請(qǐng)求時(shí),會(huì)產(chǎn)生 cookie 請(qǐng)求頭,將之前服務(wù)器的 cookie 信息再次發(fā)送給了服務(wù)器,然后服務(wù)器根據(jù) cookie 信息跟蹤客戶端狀態(tài)。
Cookie 創(chuàng)建:
// 用響應(yīng)創(chuàng)建Cookie,等價(jià)于 response.addHeader("set-cookie", "name=value");
Cookie cookie = new Cookie(String name, String value); // Cookie: name=value
cookie.setMaxAge(seconds); // 設(shè)置Cookie的生命周期
cookie.setPath("/"); // 設(shè)置Cookie的共享范圍
response.addCookie(cookie); // 添加1個(gè)Cookie
Cookie 獲?。?/p>
// 用請(qǐng)求獲取Cookie Cookie[] cookies = request.getCookies(); // 獲取Cookies返回?cái)?shù)組 // 需遍歷 cookie.getName(); // 獲取鍵 cookie.getValue(); // 獲取值
Cookie 修改:
// 修改Cookie cookie.setValue(String name);
2、TCP斷開(kāi)連接時(shí),通信雙方的狀態(tài)變化?
參考文章:
TCP的三次握手與四次揮手
這道題是我在字節(jié)跳動(dòng)一面時(shí)候遇到的問(wèn)題,我以為會(huì)先從三次握手、四次揮手開(kāi)始問(wèn),沒(méi)想到面試官不按常理出牌,直接問(wèn)我 TCP 通信雙方的狀態(tài)變化。
這道題的答案,直接看上面提供的參考文章,講的非常透徹,也非常容易理解,只需要靜下心看完它!
3、GC垃圾回收時(shí),什么情況下會(huì)Stop The World?
在每次 FUll GC 的時(shí)候都會(huì) Stop The World (STW),即,掛起其他所有除了 GC 之外的線程,只讓 GC 垃圾回收線程工作,Young GC 不會(huì)觸發(fā) Stop The World。
- CMS 垃圾收集器:
- 新生代:不會(huì)觸發(fā) STW。
- 老年代:會(huì)觸發(fā) 2 次 STW,初始標(biāo)記 和 重新標(biāo)記 會(huì)觸發(fā)。當(dāng)年老代達(dá)到特定的占用比例時(shí),CMS 開(kāi)始執(zhí)行。
- G1 垃圾收集器:
- 新生代:新生對(duì)象會(huì)被疏散(復(fù)制、移動(dòng))到一個(gè)或多個(gè) Survivor 幸存區(qū)域。如果對(duì)象達(dá)到晉升總閾值,對(duì)象會(huì)晉升到年老代區(qū)域,這時(shí)候會(huì)觸發(fā)一次 STW 。
- 老年代:G1 老年代垃圾回收和 CMS 一樣,會(huì)觸發(fā) 2 次 STW,初始標(biāo)記 、重新標(biāo)記、清理、復(fù)制 時(shí),會(huì)觸發(fā) STW。
4、堆和棧的區(qū)別?
堆:
堆是一種常用的樹(shù)形結(jié)構(gòu),是一種特殊的完全二叉樹(shù),當(dāng)且僅當(dāng)滿足所有節(jié)點(diǎn)的值總是不大于或不小于其父節(jié)點(diǎn)的值的完全二叉樹(shù)被稱之為堆。堆的這一特性稱之為堆序性。因此,在一個(gè)堆中,根節(jié)點(diǎn)是最大(或最?。┕?jié)點(diǎn)。如果根節(jié)點(diǎn)最小,稱之為小頂堆(或小根堆),如果根節(jié)點(diǎn)最大,稱之為大頂堆(或大根堆)。堆的左右孩子沒(méi)有大小的順序。下面是一個(gè)小頂堆示例:

堆的存儲(chǔ)一般都用數(shù)組來(lái)存儲(chǔ)堆,i 節(jié)點(diǎn)的父節(jié)點(diǎn)下標(biāo)就為(i–1)/2,它的左右子節(jié)點(diǎn)下標(biāo)分別為2 ∗ i + 1 和 2 * i - 1,如第 0 個(gè)節(jié)點(diǎn)左右子節(jié)點(diǎn)下標(biāo)分別為 1 和 2。

棧:
棧是一種線性表,只僅允許在表的一端進(jìn)行插入和刪除操作,這一端被稱為棧頂(Top),相對(duì)地,把另一端稱為棧底(Bottom)。把新元素放到棧頂元素的上面,使之成為新的棧頂元素稱作進(jìn)棧、入?;驂簵#≒ush);把棧頂元素刪除,使其相鄰的元素成為新的棧頂元素稱作出棧或退棧(Pop)。

文章參考:堆與棧的區(qū)別
5、線程調(diào)度的方式?
- 分時(shí)調(diào)度:所有線程輪流使用 CPU 的使用權(quán),平均分配每個(gè)線程占用 CPU 的時(shí)間。
- '搶占式調(diào)度:優(yōu)先讓優(yōu)先級(jí)高的線程使用 CPU,如果線程的優(yōu)先級(jí)相同,那么會(huì)隨機(jī)選擇一個(gè)(線程隨機(jī)性),Java使用的為搶占式調(diào)度。
線程的調(diào)度,取決于支持的是內(nèi)核級(jí)線程還是用戶級(jí)線程?
- 對(duì)于用戶級(jí)線程,內(nèi)核不知道線程的存在,就給了進(jìn)程很大的自主權(quán)。內(nèi)核只是調(diào)度進(jìn)程,由進(jìn)程去選擇調(diào)度哪個(gè)線程來(lái)運(yùn)行。
- 對(duì)于內(nèi)核級(jí)線程,線程的調(diào)度就交給了系統(tǒng)完成。
6、Linux 下如何查看文件前幾行和后幾行的命令?
這個(gè)是近期面試字節(jié)一面的時(shí)候,面試官問(wèn)的問(wèn)題:
# /etc/profile 的前10行內(nèi)容,應(yīng)該是: head -n 10 /etc/profile # 查看/etc/profile 的最后5行內(nèi)容,應(yīng)該是: tail -n 5 /etc/profile # 將內(nèi)容輸出到/home/test文件中 head -n 10 /etc/profile >> /home/test tail -n 5 /etc/profile >> /home/test
7、TIME_WAIT為什么要等待2MSL,TIME_WAIT是客戶端狀態(tài)還是服務(wù)端狀態(tài)?
簡(jiǎn)短概括:① 防止服務(wù)沒(méi)有收到客戶端發(fā)送的最后一個(gè) ACK,則會(huì)重發(fā) FIN 請(qǐng)求,② 讓本次請(qǐng)求之前發(fā)送的請(qǐng)求都過(guò)期。
詳細(xì)介紹如下:
- 第一,保證客戶端發(fā)送的最后一個(gè) ACK 報(bào)文能夠到達(dá)服務(wù)器,由于這個(gè) ACK 報(bào)文可能丟失,站在服務(wù)器的角度看來(lái),我已經(jīng)發(fā)送了 FIN+ACK 報(bào)文請(qǐng)求斷開(kāi)了,客戶端還沒(méi)有給我回應(yīng),應(yīng)該是我發(fā)送的請(qǐng)求斷開(kāi)報(bào)文它沒(méi)有收到,于是服務(wù)器又會(huì)重新發(fā)送一次而客戶端就能在這個(gè) 2MSL 時(shí)間段內(nèi)收到這個(gè)重傳的報(bào)文,接著給出回應(yīng)報(bào)文,并且會(huì)重啟 2MSL 計(jì)時(shí)器。
- 第二,防止 “已經(jīng)失效的連接請(qǐng)求報(bào)文段” 出現(xiàn)在本次請(qǐng)求中??蛻舳税l(fā)送完最后一個(gè)確認(rèn)報(bào)文后,在這個(gè) 2MSL 時(shí)間中,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失。這樣新的連接中不會(huì)出現(xiàn)舊連接的請(qǐng)求報(bào)文。
8、為什么建立連接是三次握手,關(guān)閉連接確是四次揮手呢?
為什么要三次握手?
- 簡(jiǎn)短來(lái)說(shuō)就是,在建立通信連接之前,通信雙方都確保自己與對(duì)方的發(fā)送、接收功能是正常的。
為什么要四次揮手?
通信雙方的任何一方都可以在數(shù)據(jù)傳輸結(jié)束之后,發(fā)出連接釋放的請(qǐng)求,待對(duì)方確認(rèn)請(qǐng)求后進(jìn)入半關(guān)閉狀態(tài)。當(dāng)另一方也沒(méi)有數(shù)據(jù)再發(fā)送的時(shí)候,則發(fā)出連接釋放通知,對(duì)方確認(rèn)后就完全關(guān)閉了 TCP 連接。
總結(jié)一句話:確保通信雙方在互相都關(guān)閉通信連接之前,已經(jīng)沒(méi)有數(shù)據(jù)在雙方之間繼續(xù)傳輸了,使雙方可以安全的關(guān)閉連接。
9、TCP 滑動(dòng)窗口和流量控制機(jī)制?
TCP 利用滑動(dòng)窗口實(shí)現(xiàn)流量控制。流量控制是為了控制發(fā)送方發(fā)送速率,保證接收方來(lái)得及接收。
接收方發(fā)送的確認(rèn)報(bào)文中的窗口字段可以用來(lái)控制發(fā)送方窗口大小,從而影響發(fā)送方的發(fā)送速率。將窗口字段設(shè)置為 0,則發(fā)送方不能發(fā)送數(shù)據(jù)。
10、TCP 擁塞控制機(jī)制?
在某段時(shí)間,若對(duì)網(wǎng)絡(luò)中某一資源的需求超過(guò)了該資源所能提供的可用部分,網(wǎng)絡(luò)的性能就要變壞。這種情況就叫擁塞。擁塞控制就是為了防止過(guò)多的數(shù)據(jù)注入到網(wǎng)絡(luò)中,這樣就可以使網(wǎng)絡(luò)中的路由器或鏈路不致過(guò)載。擁塞控制所要做的都有一個(gè)前提,就是網(wǎng)絡(luò)能夠承受現(xiàn)有的網(wǎng)絡(luò)負(fù)荷。擁塞控制是一個(gè)全局性的過(guò)程,涉及到所有的主機(jī),所有的路由器,以及與降低網(wǎng)絡(luò)傳輸性能有關(guān)的所有因素。相反,流量控制往往是點(diǎn)對(duì)點(diǎn)通信量的控制,是個(gè)端到端的問(wèn)題。流量控制所要做到的就是抑制發(fā)送端發(fā)送數(shù)據(jù)的速率,以便使接收端來(lái)得及接收。
為了進(jìn)行擁塞控制,TCP 發(fā)送方要維持一個(gè) 擁塞窗口(cwnd) 的狀態(tài)變量。擁塞控制窗口的大小取決于網(wǎng)絡(luò)的擁塞程度,并且動(dòng)態(tài)變化。發(fā)送方讓自己的發(fā)送窗口取為擁塞窗口和接收方的接受窗口中較小的一個(gè)。
TCP的擁塞控制采用了四種算法,即 慢開(kāi)始 、 擁塞避免 、快重傳 和 快恢復(fù)。在網(wǎng)絡(luò)層也可以使路由器采用適當(dāng)?shù)姆纸M丟棄策略(如主動(dòng)隊(duì)列管理 AQM),以減少網(wǎng)絡(luò)擁塞的發(fā)生。
- 慢開(kāi)始: 慢開(kāi)始算法的思路是當(dāng)主機(jī)開(kāi)始發(fā)送數(shù)據(jù)時(shí),如果立即把大量數(shù)據(jù)字節(jié)注入到網(wǎng)絡(luò),那么可能會(huì)引起網(wǎng)絡(luò)阻塞,因?yàn)楝F(xiàn)在還不知道網(wǎng)絡(luò)的符合情況。經(jīng)驗(yàn)表明,較好的方法是先探測(cè)一下,即由小到大逐漸增大發(fā)送窗口,也就是由小到大逐漸增大擁塞窗口數(shù)值。cwnd初始值為1,每經(jīng)過(guò)一個(gè)傳播輪次,cwnd加倍。
- 擁塞避免: 擁塞避免算法的思路是讓擁塞窗口cwnd緩慢增大,即每經(jīng)過(guò)一個(gè)往返時(shí)間RTT就把發(fā)送放的cwnd加1.
- 快重傳與快恢復(fù): 在 TCP/IP 中,快速重傳和恢復(fù)(fast retransmit and recovery,F(xiàn)RR)是一種擁塞控制算法,它能快速恢復(fù)丟失的數(shù)據(jù)包。沒(méi)有 FRR,如果數(shù)據(jù)包丟失了,TCP 將會(huì)使用定時(shí)器來(lái)要求傳輸暫停。在暫停的這段時(shí)間內(nèi),沒(méi)有新的或復(fù)制的數(shù)據(jù)包被發(fā)送。有了 FRR,如果接收機(jī)接收到一個(gè)不按順序的數(shù)據(jù)段,它會(huì)立即給發(fā)送機(jī)發(fā)送一個(gè)重復(fù)確認(rèn)。如果發(fā)送機(jī)接收到三個(gè)重復(fù)確認(rèn),它會(huì)假定確認(rèn)件指出的數(shù)據(jù)段丟失了,并立即重傳這些丟失的數(shù)據(jù)段。有了 FRR,就不會(huì)因?yàn)橹貍鲿r(shí)要求的暫停被耽誤。 當(dāng)有單獨(dú)的數(shù)據(jù)包丟失時(shí),快速重傳和恢復(fù)(FRR)能最有效地工作。當(dāng)有多個(gè)數(shù)據(jù)信息包在某一段很短的時(shí)間內(nèi)丟失時(shí),它則不能很有效地工作。
總結(jié)
本篇文章的內(nèi)容就到這了,希望大家可以多多關(guān)注腳本之家的其他精彩內(nèi)容!
相關(guān)文章
基于Lucene的Java搜索服務(wù)器Elasticsearch安裝使用教程
Elasticsearch也是用Java開(kāi)發(fā)的,并作為Apache許可條款下的開(kāi)放源碼發(fā)布,能夠做到實(shí)時(shí)搜索,且穩(wěn)定、可靠、快速,安裝使用方便,這里我們就來(lái)看一下基于Lucene的Java搜索服務(wù)器Elasticsearch安裝使用教程:2016-06-06
Java可以寫(xiě)android的應(yīng)用程序嗎
在本篇文章里小編給大家整理的是一篇關(guān)于Java可以寫(xiě)android的應(yīng)用程序嗎的相關(guān)基礎(chǔ)文章,有興趣的朋友們可以學(xué)習(xí)下。2020-11-11
Java實(shí)現(xiàn)HTTP請(qǐng)求的4種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)HTTP請(qǐng)求的4種方式,在java開(kāi)發(fā)中,經(jīng)常遇到需要調(diào)用第三方提供的接口服務(wù)的需求,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2023-08-08
Java中使用json與前臺(tái)Ajax數(shù)據(jù)交互的方法
這篇文章主要為大家詳細(xì)介紹了Java中使用json與前臺(tái)Ajax數(shù)據(jù)交互的方法,分享Ajax獲取顯示Json數(shù)據(jù)的一種方法,感興趣的小伙伴們可以參考一下2016-06-06
SpringBoot在線代碼修改器的問(wèn)題及解決方法
這篇文章主要介紹了SpringBoot在線代碼修改器的問(wèn)題及解決方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
Java的RxJava庫(kù)操作符的用法及實(shí)例講解
RxJava由于提供異步和基于事件的支持在Android開(kāi)發(fā)者中獲得了不少人氣,這里我們就來(lái)看一下Java的RxJava庫(kù)操作符的用法及實(shí)例講解,需要的朋友可以參考下2016-06-06
基于Mybatis實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的示例代碼
在當(dāng)今的互聯(lián)網(wǎng)應(yīng)用中,微服務(wù)大行其道,隨著業(yè)務(wù)的發(fā)展和擴(kuò)展,單一的數(shù)據(jù)庫(kù)無(wú)法滿足日益增長(zhǎng)的數(shù)據(jù)需求,本文將基于 JDK17 + Spring Boot 3 和 MyBatis 框架實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源功能,需要的朋友可以參考下2024-09-09

