更新時間:2019-10-16 15:56:24 來源:動力節點 瀏覽29682次
今天動力節點java培訓機構小編為大家匯總了史上最全的中高級JAVA工程師面試題及答案,分別是java緩存技術面試題和java中的hashmap面試題,希望能夠幫助到正在找工作的中高級JAVA程序員,下面就隨小編一起來看看吧。
1.memcache的分布式原理
memcached 雖然稱為 “ 分布式 ” 緩存服務器,但服務器端并沒有 “ 分布式 ” 功能。每個服務器都是完全獨立和隔離的服務。memcached 的分布式,則是完全由客戶端程序庫實現的。這種分布式是 memcached 的最大特點。
2.memcache的內存分配機制
如何存放數據到memcached緩存中?(memcache內存分配機制)
Slab Allocator內存分配機制:預先將內存分配成數個slab倉庫,每個倉庫再切出不同大小的chunk,去適配收到的數據。多余的只能造成浪費,不可避免。 增長因子(Grace factor):一般而言觀察數據大小的變化規律設置合理的增長因子,默認1.25倍. 太大容易造成浪費。memcached.exe -m 64 -p 11211 -f 1.25
如果有100byte的內容要存儲,但122大小的倉庫的chunk用滿了怎么辦?
答:是并不會尋找更大倉庫的chunk來存儲,而是把122倉庫中的舊數據踢掉!
3.memcache的惰性失效機制
4.memcache緩存的無底洞現象
5.一致性Hash算法的實現原理
(1)Hash環
我們把232次方想成一個環,比如鐘表上有60個分針點組成一個圓,那么hash環就是由232個點組成的圓。第一個點是0,最后一個點是232-1,我們把這232個點組成的環稱之為HASH環。
(2)一致性Hash算法
將memcached物理機節點通過Hash算法虛擬到一個虛擬閉環上(由0到232構成),key請求的時候通過Hash算法計算出Hash值然后對232取模,定位到環上順時針方向最接近的虛擬物理節點就是要找到的緩存服務器。
假設有ABC三臺緩存服務器:我們使用這三臺服務器各自的IP進行hash計算然后對232取模即:==**Hash(服務器IP)%232== 計算出來的結果是0到232-1的一個整數,那么Hash環上必有一個點與之對應。比如:
現在緩存服務器已經落到了Hash環上,接下來我們就看我們的數據是怎么放到緩存服務器的?我們可以同樣對Object取Hash值然后對232取模,比如落到了接近A的一個點上:
那么這個數據理應存到A這個緩存服務器節點上
所以,在緩存服務器節點數量不變的情況下,緩存的落點是不會變的。
但是如果B掛掉了呢? 按照hash且取模的算法,圖中3這個Object理應就分配到了C這個節點上去了,所以就會到C上找緩存數據,結果當然是找不到,進而從DB讀取數據重新放到了C上。
但是對于編號為1,2的Object還是落到A,編號為4的Object還是落到C,B宕機所影響的僅僅是3這個Object。這就是一致性Hash算法的優點。
(3)Hash環的傾斜
前面我們理想化的把三臺memcache機器均勻分到了Hash環上:
但是現實情況可能是:
如果Hash環傾斜,即緩存服務器過于集中將會導致大量緩存數據被分配到了同一個服務器上。比如編號1,2,3,4,6的Object都被存到了A,5被存到B,而C上竟然一個數據都沒有,這將造成內存空間的浪費。為了解決這個問題,一致性Hash算法中使用“虛擬節點”解決。
虛擬節點解決Hash環傾斜
“虛擬節點”是“實際節點”在hash環上的復制品,一個實際節點可能對應多個虛擬節點。這樣就可以將ABC三臺服務器相對均勻分配到Hash環上,以減少Hash環傾斜的影響,使得緩存被均勻分配到hash環上。
6.hash算法平衡性
平衡性指的是hash的結果盡可能分布到所有的緩存中去,這樣可以使得所有的緩存空間都可以得到利用。但是hash算法不保證絕對的平衡性,為了解決這個問題一致性hash引入了“虛擬節點”的概念。虛擬節點”( virtual node )是實際節點在 hash 空間的復制品( replica ),一實際個節點對應了若干個“虛擬節點”,這個對應個數也成為“復制個數”,“虛擬節點”在 hash 空間中以 hash 值排列。“虛擬節點”的hash計算可以采用對應節點的IP地址加數字后綴的方式。
例如假設 cache A 的 IP 地址為202.168.14.241 。引入“虛擬節點”前,計算 cache A 的 hash 值:Hash(“202.168.14.241”); 引入“虛擬節點”后,計算“虛擬節”點 cache A1 和 cache A2 的 hash 值:
Hash(“202.168.14.241#1”); // cache A1 ?
Hash(“202.168.14.241#2”); // cache A2 ??
這樣只要是命中cacheA1和cacheA2節點,就相當于命中了cacheA的緩存。這樣平衡性就得到了提高。
7.memcached與redis的區別
8.Redis的主從復制
9.Redis的部分復制過程
部分同步工作原理如下:
10.Redis的主從復制阻塞模式
11.Redis的數據持久化方式
Rdb快照和aof ?RDB快照:可以配置在n秒內有m個key修改就做自動化快照方式 ?AOF:每一個收到的寫命令都通過write函數追加到文件中。更安全。
12.Redis的高可用部署方式
(1)哨兵模式
redis3.0之前的Sentinel哨兵機制,redis3.0之前只能使用一致性hash方式做分布式緩存。哨兵的出現主要是解決了主從復制出現故障時需要人為干預的問題。
(2)Redis哨兵主要功能
(3)Redis哨兵的高可用
原理:當主節點出現故障時,由Redis Sentinel自動完成故障發現和轉移,并通知應用方,實現高可用性
(4)哨兵如何判斷redis主從節點是否正常?
涉及兩個新的概念:主觀下線和客觀下線。
原理:基本上哪個哨兵節點最先判斷出這個主節點客觀下線,就會在各個哨兵節點中發起投票機制Raft算法(選舉算法),最終被投為領導者的哨兵節點完成主從自動化切換的過程。
(5)集群模式
redis3.0之后的容錯集群方式,無中心結構,每個節點保存數據和整個集群狀態,每個節點都和其他所有節點連接,需要至少三個master提供寫的功能。
因此集群中至少應該有奇數個節點,因此至少有三個節點,每個節點至少有一個備份節點,所以redis集群應該至少6個節點。
每個Master有一個范圍的slot槽位用于寫數據。
13.Redis可以在線擴容嗎?zk呢
Reids的在線擴容,不需要重啟服務器,動態的在原始集群中添加新的節點,并分配slot槽。但是zk不能在線擴容,需要重啟,但是我們可以選擇一個一個重啟。
14.Redis高并發和快速的原因
缺點:無法發揮多核CPU性能
15.瀏覽器本地緩存的了解和使用
資源在瀏覽器端的本地緩存可以通過Expires和Last-Modified返回頭信息進行有效控制。
(1)Expires告訴瀏覽器在該指定過期時間前再次訪問同一URL時,直接從本地緩存讀取,無需再向服務器發起http請求;
(2)當服務器返回設置了Last-Modified頭,下次發起同一URL的請求時,請求頭會自動包含If-Modified-Since頭信息,服務器對靜態內容會根據該信息跟文件的最后修改時間做比較,如果最后修改時間不大于If-Modified-Since頭信息,則返回304:告訴瀏覽器請求內容未更新可直接使用本地緩存。(注意:只對靜態內容有效,如js/css/image/html等,不包括動態內容,如JSP)
16.緩存雪崩
如果緩存集中在一段時間內失效,發生大量的緩存穿透,所有的查詢都落在數據庫上,造成了緩存雪崩。
解決辦法:沒有完美的解決方案,可以通過隨機算法讓失效時間隨機分布,避免同一時刻失效。
17.緩存穿透
訪問一個不存在的key,緩存不起作用,請求會穿透到DB,可能DB也沒查到,流量大時DB會掛掉。
解決辦法: 1.采用布隆過濾器,使用一個足夠大的bitmap,用于存儲可能訪問的key,不存在的key直接被過濾;2訪問key未在DB查詢到值,也將空值寫進緩存,但可以設置較短過期時間。
HashMap的Hash碰撞
Hash值沖突問題是Hash表存儲模型需要解決的一個問題。通常有兩種方法:
將相同Hash值的Entry對象組織成一個鏈表放置在hash值對應的槽位。HashMap采用的是鏈表法,且是單向鏈表(通過head元素就可以操作后續所有元素,對鏈表而言,新加入的節點會從頭節點加入。) 核心源碼:
private void addEntry(int hash, K key, V value, int bucketIndex) {
Entrye = table[bucketIndex];
table[bucketIndex] = new Entry(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
以上代碼說明:系統總是將新添加的 Entry 對象放入 table 數組的 bucketIndex 索引處。
18.HashMap的get和put原理
PUT原理:當調用HashMap的put方法傳遞key和value時,先調用key的hashcode方法。通過key的Hash值來找到Bucket----‘桶’的位置,然后迭代這個位置的Entry列表 判斷是否存在key的hashcode和equals完全相同的key,如果完全相同則覆蓋value, 否則插入到entry鏈的頭部。
HashMap在put時的Entry鏈形成的場景?
當程序試圖將一個key-value對放入HashMap中時,程序首先根據該 key 的 hashCode() 返回值決定該 Entry 的存儲位置:
如果這兩個 Entry 的 key 的 hashCode() 返回值相同,那它們的存儲位置相同。
如果這兩個 Entry 的 key 通過 equals 比較返回 true,新添加 Entry 的 value 將覆蓋集合中原有 Entry 的 value,但key不會覆蓋。
如果這兩個 Entry 的 key 通過 equals 比較返回 false,新添加的 Entry 將與集合中原有 Entry 形成 Entry 鏈,而且新添加的 Entry 位于 Entry 鏈的頭部
GET原理:根據該 key 的 hashCode 值計算它的 hash 碼,遍歷并循環取出 Entry 數組中指定索引處的Entry值,如果該 Entry 的 key 與被搜索 key 相同 ,且Enrty的hash值跟key的hash碼相同,然后看是否是Entry鏈,如果是則迭代這個位置的Entry列表,判斷是否存在key的hashcode和equals完全相同的key,如果完全相同則獲取value。
19.HashMap的rehash
HashMap初始容量大小為16,一般來說,當有數據要插入時,都會檢查容量有沒有超過設定的thredhold,如果超過,需要增大Hash表的尺寸,但是這樣一來,整個Hash表里的元素都需要被重算一遍。這叫rehash,這個成本相當的大
20.HashMap的線程不安全問題
比如put操作時,有兩個線程A和B,首先A希望插入一個key-value對到HashMap中,首先計算記錄所要落到的桶的索引BucketIndex坐標,然后獲取到該桶里面的Entry鏈表header頭結點,此時線程A的時間片用完了,而此時線程B被調度得以執行,和線程A一樣執行,只不過線程B成功將記錄插到了桶里面,假設線程A插入的記錄計算出來的桶索引和線程B要插入的記錄計算出來的桶索引是一樣的,那么當線程B成功插入之后,線程A再次被調度運行時,它依然持有過期的鏈表頭但是它對此一無所知,以至于它認為它應該這樣做,如此一來就覆蓋了線程B插入的記錄,這樣線程B插入的記錄就憑空消失了,造成了數據不一致的行為。另一個不安全的體現是是get操作可能由于resize而死循環。
21.HashMap和Hashtable的區別
相同點:
不同點:
22.為什么collection沒有實現clonable接口
Collection接口有很多不同的集合實現形式,而clonable只對具體的對象有意義。
23.為什map沒有實現collection接口
Set 和List 都繼承了Conllection,Map沒有繼承于Collection接口,Map提供的是key-Value的映射,而Collection代表一組對象。
24.Map接口的實現有哪些,區別是什么
HashMap,LinkedHashMap,Hashtable,TreeMap。
LinkedHashMap 是HashMap的一個子類,保存了記錄的插入順序 Hashtable和HashMap類似,它繼承自Dictionary類,不同的是它不允許鍵或值為空。TreeMap實現SortMap接口,能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器。
以上就是動力節點java培訓機構小編介紹的“中高級JAVA工程師面試題及答案”的內容,希望對大家有幫助,更多中高級java面試題請繼續關注動力節點java培訓機構官網,每天會有精彩內容分享與你。
?由于“史上最全的中高級JAVA工程師面試題及答案”內容太多,本文已滿,請看下文鏈接
25~52道中高級JAVA工程師面試題及答案請看鏈接:http://www.dabaquan.cn/javazixun/2191.html
53~64道中高級JAVA工程師面試題及答案請看鏈接:http://www.dabaquan.cn/javazixun/2169.html
java面試題推薦
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習