數(shù)據(jù)結(jié)構(gòu)
- HashMap的原理蛾洛,內(nèi)部數(shù)據(jù)結(jié)構(gòu)?
- 底層使用哈希表(數(shù)組 + 鏈表)雁芙,當(dāng)鏈表過(guò)長(zhǎng)會(huì)將鏈表轉(zhuǎn)成 紅黑樹(shù)以實(shí)現(xiàn) O(logn) 時(shí)間復(fù)雜度內(nèi)查找
- 講一下 HashMap 中 put 方法過(guò)程轧膘?
- 對(duì) Key 求 Hash 值,然后再計(jì)算 下標(biāo)兔甘。
- 如果沒(méi)有碰撞谎碍,直接放入桶中,
- 如果碰撞了洞焙,以鏈表的方式鏈接到后面蟆淀,
- 如果鏈表長(zhǎng)度超過(guò)閥值(TREEIFY_THRESHOLD == 8),就把鏈表轉(zhuǎn)成紅黑樹(shù)澡匪。
- 如果節(jié)點(diǎn)已經(jīng)存在就替換舊值
- 如果桶滿了(容量 * 加載因子)扳碍,就需要 resize。
- HashMap 中 hash 函數(shù)怎么是是實(shí)現(xiàn)的仙蛉? 還有哪些 hash 的實(shí)現(xiàn)方式笋敞?
- 高 16bit 不變,低 16bit 和高 16bit 做了一個(gè)異或
- (n - 1) & hash --> 得到下標(biāo)
- 還有哪些 Hash 實(shí)現(xiàn)方式:可以參考之前的博客
- HashMap 怎樣解決沖突荠瘪,講一下擴(kuò)容過(guò)程夯巷,假如一個(gè)值在原數(shù)組中,現(xiàn)在移動(dòng)了新數(shù)組哀墓,位置肯定改變了趁餐,那是什么定位到在這個(gè)值新數(shù)組中的位置,
- 將新節(jié)點(diǎn)加到鏈表后篮绰,
- 容量擴(kuò)充為原來(lái)的兩倍后雷,然后對(duì)每個(gè)節(jié)點(diǎn)重新計(jì)算哈希值。
- 這個(gè)值只可能在兩個(gè)地方吠各,一個(gè)是原下標(biāo)的位置臀突,另一種是在下標(biāo)為 <原下標(biāo)+原容量> 的位置。
- 拋開(kāi) HashMap贾漏,hash 沖突有那些解決辦法候学?
- 開(kāi)放定址,鏈地址法
- 針對(duì) HashMap 中某個(gè) Entry 鏈太長(zhǎng)纵散,查找的時(shí)間復(fù)雜度可能達(dá)到 O(n)梳码,怎么優(yōu)化隐圾?
- 將鏈表轉(zhuǎn)為紅黑樹(shù), JDK1.8 已經(jīng)實(shí)現(xiàn)了掰茶。
- 數(shù)組和 ArrayList 的區(qū)別暇藏;
- 數(shù)組可以包含基本類型和對(duì)象類型,ArrayList 只能包含對(duì)象類型
- 數(shù)組大小固定濒蒋,ArrayList 大小可以動(dòng)態(tài)變化
- ArrayList 提供了更多的特性(
addAll
叨咖、removeAll
)。
- Arraylist 如何實(shí)現(xiàn)排序
-
Collections.sort(List<T> list)
; -
sort(List<T> list, Comparator<? super T> c)
;
-
- HashMap
- 數(shù)組 + 鏈表方式存儲(chǔ)
- 默認(rèn)容量: 16(2^n 為宜,若定義的初始容量不是 2^n啊胶,容量會(huì)定義為大于該初始容量的最小 2^n)
- 例如:初始容量為 13甸各,則真正的容量是 16.
- put:
- 索引計(jì)算 : ((key.hashCode() ^ (key.hashCode() >>> 16)) & (table.length - 1))
- 在鏈表中查找,并記錄鏈表長(zhǎng)度焰坪,若鏈表長(zhǎng)度達(dá)到了 TREEIFY_THRESHOLD(8)趣倾,則將該鏈轉(zhuǎn)成紅黑樹(shù)。
- 若在鏈表中找到了某饰,則替換舊值儒恋,若未找到則繼續(xù)
- 當(dāng)總元素個(gè)數(shù)超過(guò)容量*加載因子時(shí),擴(kuò)容為原來(lái) 2 倍并重新散列
- (元素的下標(biāo)要么不變黔漂,要么變?yōu)椤驹聵?biāo)+原容量】)诫尽。
- 將新元素加到鏈表尾部
- 線程不安全
- HashTable
- 數(shù)組 + 鏈表方式存儲(chǔ)
- 默認(rèn)容量: 11(質(zhì)數(shù) 為宜)
- put:
- 索引計(jì)算 : (key.hashCode() & 0x7FFFFFFF)% table.length
- 若在鏈表中找到了,則替換舊值炬守,若未找到則繼續(xù)
- 當(dāng)總元素個(gè)數(shù)超過(guò)容量*加載因子時(shí)牧嫉,擴(kuò)容為原來(lái) 2 倍并重新散列。
- 將新元素加到鏈表頭部
- 對(duì)修改 Hashtable 內(nèi)部共享數(shù)據(jù)的方法添加了 synchronized减途,保證線程安全酣藻。
- HashMap ,HashTable 區(qū)別
- 默認(rèn)容量不同鳍置。
- 索引計(jì)算方式不同辽剧。
- HashMap 特有的將過(guò)長(zhǎng)鏈表轉(zhuǎn)換為紅黑樹(shù)。
- 新元素的位置不同税产。
- 線程安全性
- HashMap怕轿、ConcurrentHashMap 區(qū)別。
- 索引計(jì)算消除了最高位的影響
- 默認(rèn)容量: 16(若定義了初始容量(c)辟拷,容量會(huì)定義為大于(c + (c >>> 1) +1) 的最小 2^n)
- 例如:初始容量為 13撞羽,則真正的容量是 32.
- 線程安全,并發(fā)性能較好
- 并發(fā)性能好的原因是 ConcurrentHashMap 并不是定義 synchronized 方法梧兼,而是在鏈表頭上同步放吩,不同的鏈表之間是互不影響的智听。
- ConcurrentHashMap 原理
- 最大特點(diǎn)是引入了 CAS(借助 Unsafe 來(lái)實(shí)現(xiàn)【native code】)
- CAS有3個(gè)操作數(shù)羽杰,內(nèi)存值V渡紫,舊的預(yù)期值A(chǔ),要修改的新值B考赛。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí)惕澎,將內(nèi)存值V修改為B,否則什么都不做颜骤。
- Unsafe 借助 CPU 指令 cmpxchg 來(lái)實(shí)現(xiàn)
- 使用實(shí)例:
- 對(duì) sizeCtl 的控制都是用 CAS 來(lái)實(shí)現(xiàn)的
- 最大特點(diǎn)是引入了 CAS(借助 Unsafe 來(lái)實(shí)現(xiàn)【native code】)
- sizeCtl :默認(rèn)為0唧喉,用來(lái)控制 table 的初始化和擴(kuò)容操作。
- -1 代表table正在初始化
- N 表示有 -N-1 個(gè)線程正在進(jìn)行擴(kuò)容操作
- 如果table未初始化忍抽,表示table需要初始化的大小八孝。
- 如果table初始化完成,表示table的容量鸠项,默認(rèn)是table大小的0.75倍干跛,居然用這個(gè)公式算0.75(n - (n >>> 2))。
1. CAS 會(huì)出現(xiàn)的問(wèn)題:ABA
- 對(duì)變量增加一個(gè)版本號(hào)祟绊,每次修改楼入,版本號(hào)加 1,比較的時(shí)候比較版本號(hào)牧抽。
- TreeMap 和 TreeSet 區(qū)別和實(shí)現(xiàn)原理
-
TreeSet
底層是TreeMap
嘉熊,TreeMap
是基于紅黑樹(shù)來(lái)實(shí)現(xiàn)的。
-
- 紅黑樹(shù)的特點(diǎn)及相比平衡二叉樹(shù)的優(yōu)點(diǎn)(先介紹各自特點(diǎn))扬舒?
- 紅黑樹(shù)
- 每個(gè)節(jié)點(diǎn)要么是紅色阐肤,要么是黑色。
- 根節(jié)點(diǎn)永遠(yuǎn)是黑色的讲坎。
- 所有的葉節(jié)點(diǎn)都是空節(jié)點(diǎn)(即 null)泽腮,并且是黑色的。
- 每個(gè)紅色節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)都是黑色衣赶。(從每個(gè)葉子到根的路徑上不會(huì)有兩個(gè)連續(xù)的紅色節(jié)點(diǎn))
- 從任一節(jié)點(diǎn)到其子樹(shù)中每個(gè)葉子節(jié)點(diǎn)的路徑都包含相同數(shù)量的黑色節(jié)點(diǎn)诊赊。
- 平衡二叉樹(shù)
- 任何節(jié)點(diǎn)的兩個(gè)兒子子樹(shù)的高度最大差別為一
- 紅黑樹(shù)并不追求“完全平衡”——它只要求部分地達(dá)到平衡要求,降低了對(duì)旋轉(zhuǎn)的要求府瞄,從而提高了性能碧磅。
- 紅黑樹(shù)
- B+樹(shù)的了解
- 多分支結(jié)構(gòu)有效降低了樹(shù)的高度
- B 樹(shù)的各種操作能使 B 樹(shù)保持較低的高度,從而達(dá)到有效避免磁盤過(guò)于頻繁的查找存取操作遵馆,從而有效提高查找效率
- Trie-Tree 原理及其應(yīng)用鲸郊;
- 字典樹(shù)
- 特點(diǎn)
- 根節(jié)點(diǎn)不包含字符,除根節(jié)點(diǎn)外的每一個(gè)子節(jié)點(diǎn)都包含一個(gè)字符货邓。
- 從根節(jié)點(diǎn)到某一個(gè)節(jié)點(diǎn)秆撮,路徑上經(jīng)過(guò)的字符連接起來(lái),為該節(jié)點(diǎn)對(duì)應(yīng)的字符串换况。
- 每個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)包含的字符互不相同职辨。
- 核心思想是空間換時(shí)間
- 應(yīng)用
- 字符串檢索
- 詞頻統(tǒng)計(jì)
算法題(劍指 Offer 上原題不少)
- 怎么查詢一個(gè)單向鏈表的倒數(shù)第五個(gè)節(jié)點(diǎn)
- 判斷鏈表是否成環(huán)
- 兩條相交的單向鏈表盗蟆,如何求他們的第一個(gè)公共節(jié)點(diǎn)
- 在無(wú)序數(shù)組中找最大的K個(gè)數(shù)?
- 給定n個(gè)數(shù),尋找第k小的數(shù)舒裤,同時(shí)給出時(shí)間復(fù)雜度
- 找一個(gè)數(shù)組中的第三大數(shù)
- 找出數(shù)組中第一個(gè)出現(xiàn)2次的數(shù)喳资,
- 求 1-N 中數(shù)字 1 的個(gè)數(shù)。
- 判斷一個(gè)數(shù)是不是丑數(shù)腾供;
- 求第 K 個(gè)丑數(shù)仆邓;
- 10w行數(shù)據(jù),每行一個(gè)單詞伴鳖,統(tǒng)計(jì)出現(xiàn)次數(shù)出現(xiàn)最多的前100個(gè)节值。
- 一個(gè)文本文件,給你一個(gè)單詞榜聂,判斷單詞是否出現(xiàn)察署。
- 一進(jìn)去要求敲代碼二叉排序樹(shù)的插入、刪除及查找
- 某海量用戶網(wǎng)站峻汉,用戶擁有積分贴汪,積分可能會(huì)在使用過(guò)程中隨時(shí)更新。現(xiàn)在要為該網(wǎng)站設(shè)計(jì)一種算法休吠,在每次用戶登錄時(shí)顯示其當(dāng)前積分排名扳埂。用戶最大規(guī)模為2 億;積分為非負(fù)整數(shù)瘤礁,且小于 100 萬(wàn)阳懂;
- 判斷一棵二叉樹(shù)是否是 BST。
- 一副撲克 54 張牌柜思,現(xiàn)在分成 3 份岩调,每份 18 張,問(wèn)大小王出現(xiàn)在同一份中的概率是多少赡盘;
- 50個(gè)白球50個(gè)紅球号枕,兩個(gè)盒子,怎么放讓人隨機(jī)在一個(gè)盒子里抽到紅球概率最高陨享。葱淳。。這個(gè)就是一個(gè)盒子放一個(gè)紅球抛姑,另一個(gè)盒子放99個(gè)球赞厕。
- logN 查找一個(gè)有序數(shù)組移動(dòng)后類似 4 5 6 7 1 2 3里面的一個(gè)數(shù)
- 0 ~ n 連續(xù) n + 1 數(shù),現(xiàn)在有一個(gè)長(zhǎng)度為 n 的數(shù)組存放了上面 n + 1 個(gè)數(shù)的其中 n 個(gè)定硝,找出哪一個(gè)數(shù)沒(méi)有被放進(jìn)數(shù)組
- 將M個(gè)平均長(zhǎng)度為N的有序隊(duì)列組合成一個(gè)有序隊(duì)列
- 10億條短信皿桑,找出前一萬(wàn)條重復(fù)率高的
- 對(duì)一萬(wàn)條數(shù)據(jù)排序,你認(rèn)為最好的方式是什么
- 假如有100萬(wàn)個(gè)玩家,需要對(duì)這100W個(gè)玩家的積分中前100名的積分诲侮,按照順序顯示在網(wǎng)站中镀虐,要求是實(shí)時(shí)更新的。積分可能由做的任務(wù)和獲得的金錢決定浆西。問(wèn)如何對(duì)著100萬(wàn)個(gè)玩家前100名的積分進(jìn)行實(shí)時(shí)更新粉私?
- 除了前100名顽腾,后100W-100名玩家的積分近零,讓變化的積分跟第100名比較,如果比第100名高抄肖,那就替換的原則久信。
Java 基礎(chǔ)
-
Java 的優(yōu)勢(shì)
- 語(yǔ)法簡(jiǎn)單
- 跨平臺(tái)
- 當(dāng)開(kāi)發(fā)規(guī)模膨脹到一定程度,Java在規(guī)范漓摩、協(xié)作和性能調(diào)優(yōu)上還是占有很大優(yōu)勢(shì),在大型應(yīng)用裙士,尤其是企業(yè)應(yīng)用上,Java的地位仍然難以撼動(dòng)
-
boolean 占幾個(gè)字節(jié)
- 如果 boolean 變量在棧上管毙,那么它占用一個(gè)棧單元(32-bits)
- 如果在堆上腿椎,那么就跟 JVM 的實(shí)現(xiàn)有關(guān)了
- 在 Oracle 的 JVM 實(shí)現(xiàn),boolean[] 中每個(gè)元素占用一個(gè)字節(jié)(8-bits)
-
Java 訪問(wèn)修飾符權(quán)限的區(qū)別夭咬;
-
public
所有類都可訪問(wèn) -
protected
只允許包內(nèi)啃炸、子類訪問(wèn)。 -
默認(rèn)
只允許包內(nèi)訪問(wèn) -
private
只允許類內(nèi)訪問(wèn)
-
-
String 是否可以繼承卓舵, “+” 怎樣實(shí)現(xiàn)?
-
String
是final
類南用,不可繼承。 -
+
是通過(guò)StringBuilder
(或StringBuffer
) 類掏湾,和append
方法實(shí)現(xiàn)
-
-
String裹虫,StringBuffer,StringBuilder融击,區(qū)別筑公,項(xiàng)目中那里用到了 StringBuffer 或者 StringBuilder
-
String
不可變 -
StringBuffer
,可變尊浪,線程安全 -
Stringbuilder
十酣,可變,線程不安全
-
-
String為啥不可變际长,在內(nèi)存中的具體形態(tài)耸采?
-
String
使用final char value[]
來(lái)存放字符序列。
-
-
Comparable 接口和 Comparator 接口實(shí)現(xiàn)比較
- Comparable 是直接在"被比較"的類內(nèi)部來(lái)實(shí)現(xiàn)的
- Comparator則是在被比較的類外部實(shí)現(xiàn)的
-
Arrays 靜態(tài)類如何實(shí)現(xiàn)排序的工育?
- 雙軸快排
- 首先檢查數(shù)組長(zhǎng)度虾宇,如果比閥值(286)小,直接使用雙軸快排
- 否則先檢查數(shù)組中數(shù)據(jù)的連續(xù)性如绸,標(biāo)記連續(xù)升序嘱朽,反轉(zhuǎn)連續(xù)降序旭贬,如果連續(xù)性好,使用 TimSort 算法(可以很好的利用數(shù)列中的原始順序)
- 否則使用雙軸快排 + 成對(duì)插入排序
-
Java 中異常機(jī)制搪泳。
- Java 中所有異常都是
Throwable
的子類稀轨,他的直接子類有兩個(gè),一個(gè)是Error
, 一個(gè)是Exception
岸军。-
Error
一般表示 JVM 出現(xiàn)了嚴(yán)重問(wèn)題奋刽,比如說(shuō)棧溢出或 OOM, -
Exception
中異常分為兩類,- 一類是
RuntimeException
表示運(yùn)行期間出現(xiàn)的錯(cuò)誤艰赞,比較常見(jiàn)的是空指針異常和數(shù)組下標(biāo)越界佣谐,出現(xiàn)這種異常一般是程序出現(xiàn)了邏輯錯(cuò)誤,也就是代碼有 Bug方妖。 - 另一類是編譯時(shí)異常(除了
RuntimeException
以外的異常)狭魂,常見(jiàn)的一般有IOException
等, 出現(xiàn)這種錯(cuò)誤程序編譯會(huì)不通過(guò)党觅。
- 一類是
-
- 還有一種分類方式是
checked exception
和uncheck exception
雌澄。unchecked exception
包括Error
和RuntimeExcetion
,checked exception
指之前所說(shuō)的編譯時(shí)異常杯瞻。
- Java 中所有異常都是
-
Java 中異常怎么處理镐牺,什么時(shí)候拋出,什么時(shí)候捕獲又兵;
- 一般原則是提早拋出任柜,延遲捕獲
- 出現(xiàn)異常時(shí),若當(dāng)前無(wú)法處理則拋沛厨,否則捕獲異常宙地,嘗試恢復(fù)。
-
說(shuō)一說(shuō)對(duì) java io 的理解
- 按照使用的 IO 模型逆皮,大致可以分為三類:
- BIO:JDK1.4 之前的阻塞 IO
- NIO:JDK1.4 及以后的版本,非阻塞 IO
- AIO:JDK1.7 之后宅粥,又叫 NIO.2,異步 IO
- IO 總的來(lái)說(shuō)分為兩個(gè)階段,第一階段是等待數(shù)據(jù)到達(dá)內(nèi)核緩沖區(qū)电谣,第二階段是將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)秽梅。
- 阻塞 IO 是兩個(gè)階段都保持阻塞狀態(tài)。
- 非阻塞 IO 第一個(gè)階段不阻塞剿牺,但是需要輪詢來(lái)查看第一階段是否完成企垦,完成以后進(jìn)行第二階段,第二階段也是需要阻塞的晒来。
- IO 復(fù)用使用 select/poll钞诡,阻塞在這兩個(gè)系統(tǒng)調(diào)用上,而不是真正的 IO 操作上,這種方式的優(yōu)勢(shì)是可以同時(shí)監(jiān)聽(tīng)多個(gè)文件描述符荧降。檢查文件描述符是否就緒的工作是由 select/poll 系統(tǒng)調(diào)用來(lái)負(fù)責(zé)的蓖救。Java 的 NIO 組合使用了 IO 復(fù)用 + 非阻塞 IO 兩種 IO 模型班眯。不過(guò) Linux 版的 JDK 底層使用的系統(tǒng)調(diào)用是 epoll,它使用的模型類似與信號(hào)驅(qū)動(dòng)式 IO 模型捌袜,當(dāng) IO 就緒時(shí)會(huì)受到消息不需要自己去做輪詢工作所以叉谜,效率相比 select/poll 會(huì)好上很多孕豹。但是 epoll 的缺點(diǎn)是可移植性較差捧挺,是 Linux 平臺(tái)專有的系統(tǒng)調(diào)用倚搬,select/poll 就比較通用了。
- 信號(hào)驅(qū)動(dòng)式 IO 在第一階段完成后發(fā)送信號(hào)随夸,該階段不阻塞九默,不輪詢震放,然后阻塞進(jìn)行第二階段宾毒。
- 異步 IO 在兩個(gè)階段都完成以后才發(fā)送信號(hào),數(shù)據(jù)是直接可用的殿遂。
- 按照 IO 的對(duì)象诈铛,可以分為 4 類。分別是:
- 基于字節(jié)操作的 I/O 接口:InputStream 和 OutputStream
- 基于字符操作的 I/O 接口:Writer 和 Reader
- 基于磁盤操作的 I/O 接口:File
- 基于網(wǎng)絡(luò)操作的 I/O 接口:Socket
- 按照使用的 IO 模型逆皮,大致可以分為三類:
-
知不知道 NIO
- 三個(gè)特點(diǎn):
- Channels and Buffers // 通過(guò) Channels 訪問(wèn) Buffers墨礁, 一個(gè)Channel 代表一個(gè)文件描述符
- Non-blocking IO // 非阻塞 IO
- Selectors // 單線程幢竹,監(jiān)控 nultiple Channels
- 三個(gè)特點(diǎn):
Java 鎖機(jī)制
重入鎖、對(duì)象鎖恩静、類鎖的關(guān)系
-
哪些方法實(shí)現(xiàn)線程安全焕毫?
- synchronized,volatile驶乾,然后重點(diǎn)說(shuō)了下 volatile 在某些情況下可以實(shí)現(xiàn)線程安全邑飒,然后就把面試官注意力往 volatile 上引,因?yàn)関olatile 這個(gè)專門看了一下级乐,果然疙咸,面試官馬上問(wèn)了 volatile。
Java 中的同步機(jī)制风科,synchronized 關(guān)鍵字撒轮,鎖(重入鎖)機(jī)制,其他解決同步的方 volatile 關(guān)鍵字 ThreadLocal 類的實(shí)現(xiàn)原理要懂贼穆。
Synchronized 和 lock 區(qū)別
-
鎖的優(yōu)化策略
- 讀寫(xiě)分離
- 分段加鎖
- 減少鎖持有的時(shí)間
- 多個(gè)線程盡量以相同的順序去獲取資源
-
Java線程阻塞調(diào)用 wait 函數(shù)和 sleep 區(qū)別和聯(lián)系题山,還有函數(shù) yield,notify 等的作用故痊。
-
sleep
時(shí)線程的方法(讓出 CPU)顶瞳,wait
是對(duì)象的方法。
-
-
談?wù)劦?Java 反射的理解,怎么通過(guò)反射訪問(wèn)某各類的私有屬性
- 通過(guò)反射浊仆,我們可以獲取類的運(yùn)行時(shí)內(nèi)部結(jié)構(gòu)客峭。
- 反射 API 中有個(gè)方法
getDeclaredFields()
-
動(dòng)態(tài)代理的原理
- 動(dòng)態(tài)代理基于反射實(shí)現(xiàn),調(diào)用者通過(guò)代理對(duì)象來(lái)訪問(wèn)方法的時(shí)候抡柿,代理對(duì)象可以做相應(yīng)的處理舔琅,然后通過(guò)反射調(diào)用被代理對(duì)象的方法。
-
項(xiàng)目中都是用的框架洲劣,用過(guò) Servlet 嗎备蚓? Servlet 是單例嗎?多線程下 Servlet 怎么保證數(shù)據(jù)安全的囱稽?Servlet 的生命周期郊尝?
- 一般是單例,我們用的都是 Servlet 的 service战惊,其中一般不包含實(shí)例變量流昏,只有共享代碼,所以一般是安全的吞获,如果有實(shí)例變量的話可以使用 synchronized 關(guān)鍵字進(jìn)行加鎖况凉。當(dāng) Servlet 實(shí)現(xiàn) SingleThreadModel 接口后,Tomcat 會(huì)為該 Servlet建一個(gè)對(duì)象池各拷,這是享元模式刁绒。
- 生命周期
-
init
一般在 web 容器初始化,或第一次調(diào)用 servlet 時(shí)烤黍。 -
service
提供服務(wù) -
destroy
終結(jié) - 回收
-
Thread 狀態(tài)有哪些
Java實(shí)現(xiàn)線程的方式知市;哪種好;為什么好
-
單例模式的生命周期
- 一般來(lái)說(shuō)單例模式創(chuàng)建的對(duì)象是由類的 static 變量引用著的速蕊,JVM 如果采用可達(dá)性分析算法來(lái)回收的話嫂丙,該對(duì)象是永遠(yuǎn)不可能被回收的(從創(chuàng)建以后)。
繼承和多態(tài)的區(qū)別互例;
Java8 的新特性奢入。
Java 高級(jí)
-
GC 算法,除了常見(jiàn)的復(fù)制算法媳叨,標(biāo)記整理腥光,標(biāo)記清除算法,還有哪些糊秆?
- 增量算法武福。主要思想是垃圾收集線程與用戶線程交替執(zhí)行。也可以說(shuō)一邊執(zhí)行垃圾回收一遍執(zhí)行用戶代碼痘番。但是這種方法會(huì)造成系統(tǒng)吞吐量下降捉片。
- 分代收集平痰。這種方法沒(méi)有使用新算法,只是根據(jù)對(duì)象的特點(diǎn)將堆分為年輕代和老年代伍纫,年輕代使用復(fù)制算法宗雇,老年代使用標(biāo)記整理算法。
-
垃圾收集器
-
收集器 收集算法 收集區(qū)域 線程 停頓 特點(diǎn) serial 復(fù)制算法 新生代 單線程 收集時(shí)必須停頓其他所有工作線程 簡(jiǎn)單高效 serial old 標(biāo)記整理 老年代 單線程 收集時(shí)必須停頓其他所有工作線程 PerNew 復(fù)制算法 新生代 多線程 serial 的多線程版本 Server 模式下首選 parallel Scavenge 復(fù)制算法 新生代 多線程 收集時(shí)必須停頓其他所有工作線程 注重吞吐量莹规,適合后臺(tái)計(jì)算多 parallel old 標(biāo)記整理 老年代 多線程 收集時(shí)必須停頓其他所有工作線程 同 parallel Scavenge -
收集器搭配推薦
- parallel Scavenge + parallel old //注重吞吐量的應(yīng)用
- CMS + PerNew //注重停頓時(shí)間的應(yīng)用赔蒲,強(qiáng)交互環(huán)境
- G1 // 未來(lái)替代 CMS + PerNew
-
CMS(concurrent mark sweep)并發(fā)收集、低停頓
- 初始標(biāo)記(CMS initial mark):僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象良漱,速度很快舞虱,需要“Stop The World”。
- 并發(fā)標(biāo)記(CMS concurrent mark):進(jìn)行GC Roots Tracing的過(guò)程母市,在整個(gè)過(guò)程中耗時(shí)最長(zhǎng)矾兜。
- 重新標(biāo)記(CMS remark):為了修正并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,這個(gè)階段的停頓時(shí)間一般會(huì)比初始標(biāo)記階段稍長(zhǎng)一些患久,但遠(yuǎn)比并發(fā)標(biāo)記的時(shí)間短椅寺。此階段也需要“Stop The World”。
- 并發(fā)清除(CMS concurrent sweep)
-
G1
- 將整個(gè)Java堆劃分為多個(gè)大小相等的獨(dú)立區(qū)域(Region)墙杯,雖然還保留新生代和老年代的概念配并,但新生代和老年代不再是物理隔離的了括荡,而都是一部分Region(不需要連續(xù))的集合高镐。
- 整體使用標(biāo)記整理,局部使用復(fù)制算法畸冲。
- 初始標(biāo)記(Initial Marking) 僅僅只是標(biāo)記一下GC Roots 能直接關(guān)聯(lián)到的對(duì)象嫉髓,并且修改TAMS(Nest Top Mark Start)的值,讓下一階段用戶程序并發(fā)運(yùn)行時(shí)邑闲,能在正確可以的Region中創(chuàng)建對(duì)象算行,此階段需要停頓線程,但耗時(shí)很短苫耸。
- 并發(fā)標(biāo)記(Concurrent Marking) 從GC Root 開(kāi)始對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析州邢,找到存活對(duì)象,此階段耗時(shí)較長(zhǎng)褪子,但可與用戶程序并發(fā)執(zhí)行量淌。
- 最終標(biāo)記(Final Marking) 為了修正在并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分標(biāo)記記錄,虛擬機(jī)將這段時(shí)間對(duì)象變化記錄在線程的Remembered Set Logs里面嫌褪,最終標(biāo)記階段需要把Remembered Set Logs的數(shù)據(jù)合并到Remembered Set中呀枢,這階段需要停頓線程,但是可并行執(zhí)行笼痛。
- 篩選回收(Live Data Counting and Evacuation) 首先對(duì)各個(gè)Region中的回收價(jià)值和成本進(jìn)行排序裙秋,根據(jù)用戶所期望的GC 停頓是時(shí)間來(lái)制定回收計(jì)劃琅拌。此階段其實(shí)也可以做到與用戶程序一起并發(fā)執(zhí)行,但是因?yàn)橹换厥找徊糠諶egion摘刑,時(shí)間是用戶可控制的进宝,而且停頓用戶線程將大幅度提高收集效率。
-
G1 vs CMS
- 我們選擇哪個(gè)收集器是由我們垃圾回收的目標(biāo)來(lái)決定的枷恕,主要考慮以下幾點(diǎn):
- 吞吐量
- 停頓時(shí)間
- 堆容量
- G1 vs CMS
- G1 基本不用配置即彪,低停頓,用于大容量的堆活尊。但是他犧牲了應(yīng)用程序的吞吐量和部分堆空間隶校。
- CMS 配置比較復(fù)雜,合理的低停頓蛹锰,用于中等或更小的堆深胳。
- 所以當(dāng)你覺(jué)得配置 CMS 太難了,或你的堆在 2 G 以上铜犬,或你想要顯式的指定停頓時(shí)間那么你可以使用 G1舞终。否則使用 CMS
- 我們選擇哪個(gè)收集器是由我們垃圾回收的目標(biāo)來(lái)決定的枷恕,主要考慮以下幾點(diǎn):
-
-
問(wèn) JVM 內(nèi)存分代機(jī)制(會(huì)問(wèn)分為那幾個(gè)代,各個(gè)代特點(diǎn))癣猾,分代回收的優(yōu)點(diǎn)(這個(gè)問(wèn)了很多次)敛劝。
- 分為年輕代和老年代,年輕代中的對(duì)象生命周期短纷宇,基本是朝生夕死夸盟,所以需要頻繁的回收;老年代中的對(duì)象一般都能熬過(guò)多次 GC 所以他們不需要頻繁回收像捶。分代收集利用了這種特點(diǎn)上陕,年輕代使用復(fù)制算法,老年代使用標(biāo)記整理算法拓春,所以總的來(lái)說(shuō)分代收集的效率相對(duì)還是不錯(cuò)的释簿。
Java 虛擬機(jī)類加載機(jī)制,雙親委派模型
-
minor GC 和 Full GC 的觸發(fā)時(shí)機(jī)
- minor GC: 當(dāng) eden 區(qū)滿以后會(huì)觸發(fā)硼莽。
- Full GC:
- JVM 的一些特性比如分配擔(dān)保庶溶,大對(duì)象直接進(jìn)入老年代,長(zhǎng)期存活的對(duì)象進(jìn)入老年代等等都會(huì)不斷增加老年代的使用率懂鸵,當(dāng)老年代空間不足以支持下一次 Minor GC 時(shí)會(huì)觸發(fā)一次 Full GC
- 當(dāng)用戶代碼調(diào)用 System.gc 時(shí)偏螺,系統(tǒng)系統(tǒng)建議執(zhí)行 Full GC,但是否進(jìn)行是由 JVM 來(lái)決定的矾瑰。
-
JVM 中什么樣的對(duì)象是可以回收的砖茸,對(duì)象從新年代到老年代的轉(zhuǎn)移過(guò)程,JVM 哪些地方會(huì)溢出(除了程序計(jì)數(shù)器都有)
- GC roots 不可達(dá)的對(duì)象是可以回收的殴穴。
- 棧中的引用的對(duì)象
- 方法區(qū)常量引用的對(duì)象
- 方法區(qū)靜態(tài)域引用的對(duì)象
- JNI 引用的對(duì)象
- 轉(zhuǎn)移過(guò)程
- 當(dāng)對(duì)象熬過(guò)一定次數(shù)的 GC 后凉夯,會(huì)被轉(zhuǎn)移到老年代
- 當(dāng) Eden + From surviver 中存活對(duì)象過(guò)多货葬,To surviver 區(qū)存放不下的時(shí)候,剩余的對(duì)象會(huì)進(jìn)入老年代
- GC roots 不可達(dá)的對(duì)象是可以回收的殴穴。
-
什么情況會(huì)棧溢出
- 如果線程請(qǐng)求的棧容量超過(guò)棧允許的最大容量的話劲够,Java 虛擬機(jī)將拋出一個(gè) StackOverflow 異常
-
JDK1.8 中 JVM 做了那些改變
- 主要是撤銷了永久代震桶,引入元空間(本地內(nèi)存)
常用 JVM 調(diào)優(yōu)工具有哪些(Jstatus,JStack征绎,Jmap等)蹲姐,有沒(méi)有調(diào)有經(jīng)驗(yàn).
-
知道 OOM 嗎,舉一個(gè) OOM 的例子
- 內(nèi)存中加載的數(shù)據(jù)量過(guò)于龐大人柿,如一次從數(shù)據(jù)庫(kù)取出過(guò)多數(shù)據(jù)柴墩;
- 啟動(dòng)參數(shù)內(nèi)存值設(shè)定的過(guò)小凫岖;
-
介紹一下 Java 的強(qiáng)軟弱虛四種引用江咳,問(wèn)什么時(shí)候使用軟引用
- 一般
new
出來(lái)的對(duì)象都是強(qiáng)引用,GC 不會(huì)回收強(qiáng)引用的對(duì)象 - 軟引用:軟引用的對(duì)象不那么重要哥放,當(dāng)內(nèi)存不足時(shí)可以被回收歼指。非常適合于創(chuàng)建緩存。
- 弱引用:只是引用一個(gè)對(duì)象甥雕,若一個(gè)對(duì)象的所有引用都是弱引用的話踩身,下次 GC 會(huì)回收該對(duì)象。一般用在集合類中社露,特別是哈希表挟阻。
- 虛引用:一般用于對(duì)實(shí)現(xiàn)比較精細(xì)的內(nèi)存使用控制。對(duì)于移動(dòng)設(shè)備來(lái)說(shuō)比較有意義
- 一般
RPC 原理呵哨;
三大框架
-
Spring 主要思想是什么赁濒,回答 IOC 和AOP,怎么自己實(shí)現(xiàn) AOP 孟害?
- IOC 的好處:阿里一面總結(jié) 12 題
- 使用基于反射的動(dòng)態(tài)代理
-
SpringAOP 用的哪一種代理
- JDK 動(dòng)態(tài)代理,這種是一般意義上的動(dòng)態(tài)代理挪拟;用一個(gè)代理類來(lái)間接調(diào)用目標(biāo)類的方法挨务。目標(biāo)類如果實(shí)現(xiàn)了接口那就用這種方式代理。
- cglib 動(dòng)態(tài)代理玉组。通過(guò)框架轉(zhuǎn)換字節(jié)碼生成目標(biāo)類的子類谎柄,并覆蓋其中的方法實(shí)現(xiàn)增強(qiáng),因?yàn)椴捎玫氖抢^承惯雳,所以不能對(duì) final 類進(jìn)行代理朝巫。目標(biāo)類沒(méi)有實(shí)現(xiàn)任何接口,就使用這種方法
-
spring bean 初始化過(guò)程
- 讀取 XML 資源石景,并解析劈猿,最終注冊(cè)到 Bean Factory 中
-
spring bean 對(duì)象的生命周期
- 當(dāng)一個(gè) bean 被實(shí)例化時(shí)拙吉,它需要執(zhí)行一些初始化(init-method)使它轉(zhuǎn)換成可用狀態(tài)。同樣揪荣,當(dāng) bean 不再需要筷黔,并且從容器中移除時(shí),需要做一些清除工作(destroy-method)
-
講講 Spring 中 ApplicationContext 初始化過(guò)程仗颈。
- ApplicationContext 的初始化重點(diǎn)是在
refresh
方法佛舱,其中最關(guān)鍵的幾步是:- 創(chuàng)建 bean Factory
- 初始化消息源
- 初始化應(yīng)用事件傳播器
- 初始化單例 bean
- ApplicationContext 的初始化重點(diǎn)是在
-
SpringMVC 處理請(qǐng)求的流程
- 收到用戶請(qǐng)求
- dispatcher Servlet 將請(qǐng)求轉(zhuǎn)發(fā)到相應(yīng)的 Controller
- 通過(guò) View Resolver 進(jìn)行視圖解析
- 返回給用戶
SpringMVC 的設(shè)計(jì)模式
Spring 的 annotation 如何實(shí)現(xiàn)
-
Spring攔截器怎么使用,Controller是單例嗎
- 基于 XML 配置文件
- 基于注解
- 基于 Spring 定義的 MethodInterceptor 接口
- Controller 是單例的挨决,跟 Servlet 一樣请祖。
數(shù)據(jù)庫(kù)
-
SQL 優(yōu)化方案
根據(jù)我目前的知識(shí)水平,大概分為兩類:
- 多表連接時(shí)不直接連接表脖祈,而是先用
where
篩選出符合條件的記錄然后進(jìn)行連接损拢。一般情況下,篩選一次會(huì)除去相當(dāng)多的無(wú)效記錄撒犀,這會(huì)極大的提高效率福压。 - 判斷當(dāng)前的 SQL 是否合理的使用了索引。如果設(shè)置的索引沒(méi)有使用的話或舞,會(huì)導(dǎo)致全表掃描荆姆。效率上會(huì)差很多。沒(méi)有利用索引的情況一般有以下幾種:
- 以“%”開(kāi)頭的LIKE語(yǔ)句映凳,模糊匹配
- OR 語(yǔ)句前后沒(méi)有同時(shí)使用索引
- 數(shù)據(jù)類型出現(xiàn)隱式轉(zhuǎn)化(如varchar不加單引號(hào)的話可能會(huì)自動(dòng)轉(zhuǎn)換為int型)
- where 子句中對(duì)字段進(jìn)行表達(dá)式操作
- 在where子句中對(duì)字段進(jìn)行函數(shù)操作
- 多表連接時(shí)不直接連接表脖祈,而是先用
-
索引有哪些胆筒?分別有什么特點(diǎn)?
- 從底層數(shù)據(jù)結(jié)構(gòu)來(lái)劃分的話诈豌,主要有兩種:一種是基于 B+ 樹(shù)的索引仆救,一種是基于哈希表的索引〗糜妫基于哈希表的索引在等值查詢上有絕對(duì)的優(yōu)勢(shì)彤蔽,但其他方面就不是很好了。B+ 樹(shù)是一種多分支的樹(shù)結(jié)構(gòu)庙洼,相比二叉樹(shù)來(lái)說(shuō)高度降低了很多顿痪,能夠有效的減少磁盤 IO,所以我們平時(shí)使用的都是基于 B+ 樹(shù)的索引
-
索引為什么用 B 樹(shù)不用二叉樹(shù)油够,有什么好處蚁袭?
- 基于 B 樹(shù)的索引實(shí)現(xiàn),降低了樹(shù)的高度石咬,減少了磁盤 IO 的次數(shù)揩悄。
-
數(shù)據(jù)庫(kù)索引優(yōu)點(diǎn)和缺點(diǎn)
- 優(yōu)點(diǎn):有效加速查詢;
- 缺點(diǎn):操作數(shù)據(jù)時(shí)需要對(duì)索引進(jìn)行更新鬼悠,效率上稍微差一點(diǎn)删性;索引需要占用一定的空間亏娜。
-
數(shù)據(jù)庫(kù)事務(wù)的四個(gè)隔離級(jí)別,MySql 在哪一個(gè)級(jí)別
- MySQL 默認(rèn)隔離級(jí)別為
Repeatable read
- MySQL 默認(rèn)隔離級(jí)別為
-
數(shù)據(jù)庫(kù)镇匀,兩次相同的 select 操作照藻,期間沒(méi)有發(fā)生增,刪汗侵,改操作幸缕,返回的結(jié)果是否相同;
- 如果是多線程 select 數(shù)據(jù)晰韵,那么數(shù)據(jù)很大可能不相同(select 操作中有排序操作除外)
- 如果是單線程的发乔,那么一定相同。
-
怎么設(shè)計(jì)數(shù)據(jù)庫(kù)表(從范式角度雪猪,可以加一些設(shè)計(jì)慣例)
- 理論上說(shuō)達(dá)到第三范式是符合要求的但是一般生產(chǎn)環(huán)境下為了數(shù)據(jù)查詢方便栏尚,數(shù)據(jù)會(huì)有一定的冗余,也就是說(shuō)一般達(dá)到第二范式即可只恨。
- 第一范式:字段不可分
- 第二范式:非主屬性必須完全函數(shù)依賴于主屬性
- 第三范式:消除了第二范式中的傳遞函數(shù)依賴
-
MySQL 存儲(chǔ)引擎有哪些译仗,INNODB 和 MYISAM 的區(qū)別
- MySQL 支持 8 種存儲(chǔ)引擎,其中最主要的有兩個(gè):InnoDB官觅、MyISAM纵菌。
- MyISAM 支持表級(jí)鎖。適用于選擇密集型和插入密集型的表
- InnoDB 是 5.7.16-log MySQL Community Server 默認(rèn)的存儲(chǔ)引擎休涤,支持事務(wù)咱圆,行級(jí)鎖,外鍵功氨,聚集索引序苏。適用于更新密集的表,容災(zāi)性也較好捷凄。
- MySQL 支持 8 種存儲(chǔ)引擎,其中最主要的有兩個(gè):InnoDB官觅、MyISAM纵菌。
-
實(shí)踐中如何優(yōu)化 MySQL
- SQL語(yǔ)句及索引的優(yōu)化
- 數(shù)據(jù)庫(kù)表結(jié)構(gòu)的優(yōu)化
- 系統(tǒng)配置的優(yōu)化
- 硬件的優(yōu)化
-
慢查詢
- MySQL 慢查詢就是在日志中記錄運(yùn)行比較慢的 SQL 語(yǔ)句忱详,這個(gè)功能需要開(kāi)啟才能用。
-
int(8) 和 int(10) 的區(qū)別是什么
- 與
zerofill
結(jié)合使用才有意義纵势,默認(rèn)是 int(10)踱阿,也就是說(shuō)定義字段時(shí)加上zerofill
,如果插入的值不足 10 位的話钦铁,select 的時(shí)候會(huì)加上前導(dǎo) 0 補(bǔ)足 10 位,如果插入的值大于等于 10 位則直接顯示原值才漆。所以這個(gè)地方 8 和 10 的區(qū)別就在于是補(bǔ)足 8 位還是 10 位牛曹。
- 與
操作系統(tǒng)
- 進(jìn)程和線程的區(qū)別
- 進(jìn)程是擁有資源的基本單位,線程是 CPU 調(diào)度的基本單位
- 進(jìn)程擁有獨(dú)立的地址空間醇滥,同一個(gè)進(jìn)程的線程共享該進(jìn)程的地址空間
- 進(jìn)程上下文切換相對(duì)線程上下文切換會(huì)消耗更多的資源
- 一個(gè)進(jìn)程必須至少擁有一個(gè)線程
- 一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉黎比,所以多進(jìn)程的程序相對(duì)于多線程的程序來(lái)說(shuō)會(huì)更健壯
- 通信方式不同超营,線程通過(guò)進(jìn)程內(nèi)的資源進(jìn)行通信,進(jìn)程的通信有多種方式阅虫,包括管道演闭、共享內(nèi)存、消息等等颓帝。
- 進(jìn)程間通信
- 管道(Pipe)及有名管道(named pipe):管道可用于具有親緣關(guān)系進(jìn)程間的通信米碰,有名管道克服了管道沒(méi)有名字的限制,因此购城,除具有管道所具有的功能外吕座,它還允許無(wú)親緣關(guān)系進(jìn)程間的通信;
- 信號(hào)(Signal):信號(hào)是比較復(fù)雜的通信方式瘪板,用于通知接受進(jìn)程有某種事件發(fā)生吴趴,除了用于進(jìn)程間通信外,進(jìn)程還可以發(fā)送信號(hào)給進(jìn)程本身侮攀;
- 報(bào)文(Message)隊(duì)列(消息隊(duì)列):消息隊(duì)列是消息的鏈接表锣枝。有足夠權(quán)限的進(jìn)程可以向隊(duì)列中添加消息,被賦予讀權(quán)限的進(jìn)程則可以讀走隊(duì)列中的消息兰英。消息隊(duì)列克服了信號(hào)承載信息量少撇叁,管道只能承載無(wú)格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。
- 共享內(nèi)存:使得多個(gè)進(jìn)程可以訪問(wèn)同一塊內(nèi)存空間箭昵,是最快的可用IPC形式税朴。是針對(duì)其他通信機(jī)制運(yùn)行效率較低而設(shè)計(jì)的。往往與其它通信機(jī)制家制,如信號(hào)量結(jié)合使用正林,來(lái)達(dá)到進(jìn)程間的同步及互斥。
- 信號(hào)量(semaphore):主要作為進(jìn)程間以及同一進(jìn)程不同線程之間的同步手段颤殴。
- 套接口(Socket):更為一般的進(jìn)程間通信機(jī)制觅廓,可用于不同機(jī)器之間的進(jìn)程間通信。
- 在共享內(nèi)存中如何使用 mutex
- select 和 epoll
- 操作系統(tǒng)由哪幾部分組成涵但,進(jìn)程結(jié)構(gòu)
- 多進(jìn)程和多線程的區(qū)別
- 什么時(shí)候使用多線程杈绸,什么時(shí)候使用多進(jìn)程
- Java 多線程與操作系統(tǒng)線程的關(guān)系
- 一般線程和守護(hù)線程的區(qū)別
- 多線程與多線程的實(shí)現(xiàn)方式
- 死鎖的條件,死鎖避免矮瘟。
- 互斥條件
- 占有和等待條件
- 不剝奪條件
- 循環(huán)等待
- linux中如何查看進(jìn)程等命令
- 不同進(jìn)程打開(kāi)了同一個(gè)文件瞳脓,那么這兩個(gè)進(jìn)程得到的文件描述符(fd)相同嗎
- 不一定,因?yàn)榇蜷_(kāi)文件有三個(gè)表澈侠,inode 表劫侧,系統(tǒng)文件描述符表,進(jìn)程文件描述符表。不同進(jìn)程的文件描述符的范圍是一樣的烧栋,有可能剛好相同,也有可能不相同
- 兩個(gè)線程如何同時(shí)監(jiān)聽(tīng)一個(gè)端口审姓。
- SO_REUSEPORT 參數(shù)。
計(jì)算機(jī)網(wǎng)絡(luò)
-
HTTP 狀態(tài)碼有哪些扎筒,一一解釋含義
- 1xx 消息
- 100 服務(wù)器僅接收到部分請(qǐng)求画畅,但是一旦服務(wù)器并沒(méi)有拒絕該請(qǐng)求,客戶端應(yīng)該繼續(xù)發(fā)送其余的請(qǐng)求症脂。
- 2xx 成功
- 200 OK 請(qǐng)求成功(其后是對(duì)GET和POST請(qǐng)求的應(yīng)答文檔淫僻。)
- 3xx 重定向
- 304 Not Modified 未修改的文檔诱篷。客戶端有緩沖的文檔并發(fā)出了一個(gè)條件性的請(qǐng)求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)雳灵。服務(wù)器告訴客戶棕所,原來(lái)緩沖的文檔還可以繼續(xù)使用。
- 4xx: 客戶端錯(cuò)誤
- 400 Bad Request 服務(wù)器未能理解請(qǐng)求悯辙。
- 404 Not Found 服務(wù)器無(wú)法找到被請(qǐng)求的頁(yè)面琳省。
- 5xx: 服務(wù)器錯(cuò)誤
- 500 Internal Server Error 請(qǐng)求未完成。服務(wù)器遇到不可預(yù)知的情況躲撰。
- 1xx 消息
-
HTTP 請(qǐng)求頭有哪些针贬,介紹平時(shí)見(jiàn)過(guò)的,怎么利用這些信息來(lái)進(jìn)行前后端調(diào)試
-
Host
, 請(qǐng)求的域名 -
User-Agent
拢蛋,用戶的瀏覽器版本信息 -
Accept
桦他,響應(yīng)的內(nèi)容類型 -
Accept-Language
, 接受的語(yǔ)言 -
Accept-Encoding
, 可接受的編碼方式 -
Cookie
,本地的 Cookie 信息 -
if-Modified-Since
, 本地有緩存谆棱,如果在那之后沒(méi)有做修改快压,則可以直接使用本地緩存。
-
TCP 和 UDP 的區(qū)別
-
TCP 如何保證可靠性
- 累計(jì)確認(rèn)
- 超時(shí)重傳
- 超時(shí)間隔加倍
- 快速重傳
-
擁塞控制與流量控制的區(qū)別
- 流量控制是由接收方來(lái)控制的垃瞧,擁塞控制由當(dāng)前的網(wǎng)絡(luò)環(huán)境來(lái)控制蔫劣。
OSI七層模型,每層對(duì)應(yīng)的協(xié)議有哪些个从,每層有何含義
-
網(wǎng)絡(luò)瀏覽器訪問(wèn)一個(gè)網(wǎng)址發(fā)生了什么過(guò)程
- 在地址欄輸入 URL拦宣,并回車
- 瀏覽器查詢域名的 IP。一般會(huì)有以下幾個(gè)地方:
- 瀏覽器緩存
- 操作系統(tǒng)緩存
- 路由器緩存
- 本地 DNS 服務(wù)器
- 如果本地 DNS 服務(wù)器上沒(méi)有的話信姓,它會(huì)遞歸的從根 DNS 服務(wù)器鸵隧、頂級(jí) DNS 服務(wù)器豆瘫、權(quán)威 DNS 服務(wù)器請(qǐng)求外驱,然后把獲取到的 IP 返回給瀏覽器(DNS 協(xié)議基于 UDP)。
- 瀏覽器向 web 服務(wù)器發(fā)送 HTTP 請(qǐng)求
- HTTP 協(xié)議基于 TCP瓦哎,建立連接需要經(jīng)過(guò)三次握手蒋譬,并且該連接是長(zhǎng)連接,即
keep-alive
- IP 數(shù)據(jù)包在網(wǎng)絡(luò)傳輸中還需要經(jīng)過(guò)域間選路和域內(nèi)選路剂买。
- 若長(zhǎng)時(shí)間接收不到應(yīng)答瞬哼,TCP 會(huì)進(jìn)行重傳和擁塞控制。
- BLABLABLA...
- HTTP 協(xié)議基于 TCP瓦哎,建立連接需要經(jīng)過(guò)三次握手蒋譬,并且該連接是長(zhǎng)連接,即
- web 服務(wù)器處理請(qǐng)求
- web 服務(wù)器回傳一個(gè) HTTP 相應(yīng)
- 瀏覽器接收到以后解析 HTML并顯示
- 瀏覽器請(qǐng)求嵌入在 HTML 中的對(duì)象
- 最終瀏覽器呈現(xiàn)一個(gè)圖文并茂的頁(yè)面
-
Cookie 和 Session 的區(qū)別
- Session 是存儲(chǔ)在服務(wù)器端的讨越,Cookie 是存儲(chǔ)在客戶端的 //TODO
-
HTTP1.0 和 1.1 的區(qū)別
- 最主要的區(qū)別是 1.1 支持持久連接把跨。Connection 請(qǐng)求頭的值為 Keep-Alive 時(shí),客戶端通知服務(wù)器返回本次請(qǐng)求結(jié)果后保持連接耸别;Connection 請(qǐng)求頭的值為 close 時(shí)慈迈,客戶端通知服務(wù)器返回本次請(qǐng)求結(jié)果后關(guān)閉連接痒留。
- 1.1 支持?jǐn)帱c(diǎn)續(xù)傳。
RANGE:bytes=XXX
表示要求服務(wù)器從文件 XXX 字節(jié)處開(kāi)始傳送 - 還有一些其他的改進(jìn)恤磷,有興趣可以自行查閱相關(guān)資料
-
HTTP 和 HTTPS 的主要區(qū)別
- 安全碗殷。HTTP 直接與 TCP 通信,而 HTTPS 是先與 SSL(加密) 通信仿粹,然后再由 SSL 和 TCP 通信
-
滑動(dòng)窗口算法
- 又稱回退 N 步(go-back-N),發(fā)送方的窗口滑動(dòng)是由接收方是否已成功收到數(shù)據(jù)包來(lái)決定的吭历。即接收方的窗口向前滑動(dòng)后發(fā)送方的窗口才會(huì)向前滑動(dòng)。//TODO
域名解析詳細(xì)過(guò)程
-
IP 地址分為幾類通贞,每類都代表什么哭懈,私網(wǎng)是哪些
- A:前 1 byte 為網(wǎng)絡(luò)標(biāo)識(shí)遣总,剩下的是主機(jī)標(biāo)識(shí)
- B:前 2 bytes 為網(wǎng)絡(luò)標(biāo)識(shí)
- C:前 3 bytes 為網(wǎng)絡(luò)標(biāo)識(shí)
- D:為多播地址旭斥,最高位為 1110
- E:特殊 IP董饰。例如 0.0.0.0,127.0.0.1,255.255.255.255 等等
- 私網(wǎng)
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
IP 頭組成娄帖;
計(jì)算機(jī)網(wǎng)絡(luò)中的同步和異步
-
發(fā)現(xiàn)百度上不去近速,怎么辦
- 查看 DNS 解析是否正確。若有錯(cuò)誤析砸,刪除本地 DNS 緩存
- 若 DNS 沒(méi)有問(wèn)題首繁,使用 traceroute 檢測(cè)路徑,若路徑不通則說(shuō)明網(wǎng)路阻塞胁塞,暫時(shí)就別上網(wǎng)了
- traceroute 沒(méi)有問(wèn)題啸罢,ping 也能通一般就是服務(wù)器端出問(wèn)題了。
分布式/集群等高級(jí)主題
- Session 集群同步問(wèn)題训桶。
- 首先 Session 集群的話會(huì)有兩種方式存放 Session舵揭。
- 一種是將同一個(gè)用戶每次都負(fù)載均衡到同一個(gè)請(qǐng)求處理服務(wù)器置侍,這樣不需要考慮 Session 同步的問(wèn)題
- 一種是每臺(tái) Session 服務(wù)器都保存所有的 Session 信息蜡坊,當(dāng)一臺(tái) Session 服務(wù)器中的 Session 有更新了就將更新同步到其他所有的 Session 服務(wù)器上
- Session 的持久性類型
- 內(nèi)存
- 數(shù)據(jù)庫(kù)
- 文件系統(tǒng)
- 首先 Session 集群的話會(huì)有兩種方式存放 Session舵揭。
- 負(fù)載均衡原理
- 負(fù)載均衡有硬件和軟件兩種,一般用的都是基于軟件的負(fù)載均衡僵刮。軟件負(fù)載均衡一般分為四層和七層:
- 四層的工作在 TCP/IP 協(xié)議棧上通過(guò)修改數(shù)據(jù)包的 IP 和 端口號(hào) 來(lái)轉(zhuǎn)發(fā),效率相對(duì)七層的來(lái)說(shuō)會(huì)更高一點(diǎn)勇吊,一般在前端服務(wù)器中使用。LVS 就是用這種方式實(shí)現(xiàn)的鲫忍。
- 七層的工作在應(yīng)用層悟民,可以做到更智能的負(fù)載均衡。一般部署在前臺(tái)服務(wù)器和應(yīng)用服務(wù)器之間智润。Apache 和 Nginx 都是七層的。
- 負(fù)載均衡有硬件和軟件兩種,一般用的都是基于軟件的負(fù)載均衡僵刮。軟件負(fù)載均衡一般分為四層和七層:
- 負(fù)載均衡算法
- 隨機(jī):負(fù)載均衡方法隨機(jī)的把負(fù)載分配到各個(gè)可用的服務(wù)器上兼蜈。
- 輪詢:按順序?qū)⑿碌倪B接請(qǐng)求分配給下一個(gè)服務(wù)器
- 加權(quán)輪詢:每臺(tái)服務(wù)器接受到的連接數(shù)按權(quán)重分配歼郭,一般是用在應(yīng)用服務(wù)器的處理能力大小不同的情況下病曾。
- 最少連接:把新連接分配給當(dāng)前連接最少的服務(wù)器
- BLABAL...
- 分布式數(shù)據(jù)庫(kù)
- 分布式數(shù)據(jù)庫(kù)提供了原來(lái)集中式數(shù)據(jù)庫(kù)不具備的高可用性和拓展能力
- 分布式數(shù)據(jù)庫(kù)的架構(gòu)一般有以下幾個(gè)
- 廠商提供的集群產(chǎn)品
- 數(shù)據(jù)分片立叛。將原來(lái)集中式數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行切分秘蛇,分別存放在不同的服務(wù)器中。
- 優(yōu)點(diǎn): 集群擴(kuò)展能力很強(qiáng)艘策,幾乎可以做到線性擴(kuò)展朋蔫,而且整個(gè)集群的可用性也 很高,部分節(jié)點(diǎn)故障青扔,不會(huì)影響其他節(jié)點(diǎn)提供服務(wù)
- 缺點(diǎn):如果需要跨不同的節(jié)點(diǎn)做 join,或者統(tǒng)計(jì)類型的操作凛剥,將會(huì)變得非常困難
- 讀寫(xiě)分離逻炊。使用數(shù)據(jù)庫(kù)的復(fù)制技術(shù)嗅骄,每臺(tái)服務(wù)器上都有完整的數(shù)據(jù)副本。讀和寫(xiě)分布在不同的處理節(jié)點(diǎn)上屏积。比較適合讀操作較多的應(yīng)用
- 優(yōu)點(diǎn):可以通過(guò)增加提供讀操作的服務(wù)器數(shù)量來(lái)線性增加讀操作的性能
- 缺點(diǎn):每個(gè)節(jié)點(diǎn)都必須保存完整的數(shù)據(jù),在數(shù)據(jù)量很大時(shí)集群的拓展能力還受限于單個(gè)節(jié)點(diǎn)的存儲(chǔ)能力磅甩。不適合寫(xiě)操作較多的應(yīng)用
- 一般來(lái)說(shuō)緩存 + DB 的讀寫(xiě)分離架構(gòu)用的是比較多的炊林。緩存層使用 key-value 的形式來(lái)承載大量的讀操作,DB 承載數(shù)據(jù)持久化卷要。一般過(guò)程如下(基于 memcached):用戶的讀請(qǐng)求會(huì)首先訪問(wèn)緩存渣聚,如果緩存命中,則返回僧叉;如果沒(méi)有命中則將數(shù)據(jù)加載到緩存中再返回。對(duì)于插入、修改宛蚓、刪除操作表谊,一般使用延緩加載的策略余佃,也就是直到下次讀取時(shí)才更新緩存背犯。(刪除和修改操作會(huì)將緩存中的數(shù)據(jù)標(biāo)記為已失效)
技術(shù)開(kāi)放題
- 如何設(shè)計(jì)一個(gè)高并發(fā)的系統(tǒng)
- 數(shù)據(jù)庫(kù)的優(yōu)化,包括合理的事務(wù)隔離級(jí)別匹层、SQL語(yǔ)句優(yōu)化剪决、索引的優(yōu)化
- 使用緩存览露,盡量減少數(shù)據(jù)庫(kù) IO
- 分布式數(shù)據(jù)庫(kù)、分布式緩存
- 服務(wù)器的負(fù)載均衡
- 現(xiàn)在一個(gè)網(wǎng)頁(yè)響應(yīng)速度明顯變慢了搭伤,假如我把這個(gè)任務(wù)交給你,你怎么處理這個(gè)問(wèn)題
- 負(fù)載均衡的大題仲翎,數(shù)千萬(wàn)的負(fù)載部署到機(jī)器上湿镀,要求對(duì)問(wèn)題進(jìn)行抽象,建模停忿,提出解決方案。
- 美團(tuán)面試官來(lái)到一個(gè)城市面試應(yīng)聘者,面試有三天,每天面試官上午可以面試三場(chǎng)梆靖,下午可以面試四場(chǎng)磁携,怎么設(shè)計(jì)面試系統(tǒng),面試者可以選擇面試日期这难,面試時(shí)間和面試官学少。
- 有一些爬蟲(chóng)IP不斷的訪問(wèn)美團(tuán)網(wǎng)站,現(xiàn)在美團(tuán)設(shè)定一個(gè)IP5分鐘之內(nèi)訪問(wèn)美團(tuán)網(wǎng)站超過(guò)100次健提,就判定為爬蟲(chóng)IP,怎么設(shè)計(jì)這個(gè)程序捂人?如果100改成10000御雕,怎么設(shè)計(jì)?
- 假設(shè)在某一時(shí)刻由幾萬(wàn)個(gè)并發(fā)請(qǐng)求同時(shí)產(chǎn)生滥搭,請(qǐng)?jiān)O(shè)計(jì)一個(gè)方案來(lái)處理這種情況酸纲。
- 問(wèn)我簡(jiǎn)歷上學(xué)校 oj 平臺(tái)這個(gè)項(xiàng)目怎么實(shí)現(xiàn)1000人并發(fā)?并發(fā)的性能瓶頸在哪?
- 因?yàn)檫€沒(méi)完成,現(xiàn)處于開(kāi)發(fā)階段瑟匆,只跟面試官說(shuō)了下自己的構(gòu)想闽坡,nginx+tomcat集群,性能瓶頸可能出現(xiàn)在網(wǎng)絡(luò)io和java gc上愁溜,然后說(shuō)了下jvm gc的優(yōu)化无午,如何實(shí)現(xiàn)session共享。最后我問(wèn)了下面試官這樣設(shè)計(jì)可以嗎祝谚,他說(shuō)這樣設(shè)計(jì)不行可能有問(wèn)題,沒(méi)有告訴我問(wèn)題出現(xiàn)在哪里酣衷。