1.java基礎
1.1 說一說java有哪些集合
答:分層次記憶:第一層:Collection芬沉;第二層:List望蜡、Set棍厂、Queue;第三層:Vector扯俱、ArrayList书蚪、Deque、PriorityQueue迅栅、HashSet殊校、SortedSet、EnumSet库继;第四層:Stack、LinkedList窜醉、ArrayQueue宪萄、LinkedHashSet、TreeSet榨惰;
集合主要還是指collection下面的接口拜英,如果問的是容器的話還需要回答map相關內容;
同樣用分層記憶:第一層:Map琅催;第二層:IdentityHashMap居凶、SortedMap、WeakHashMap藤抡、HashTable侠碧、EnumMap;第三層:LinkedHashMap缠黍、Properties弄兜、TreeMap;
1.2 說一說ArrayList跟LinkedList的區(qū)別;
答:ArrayList底層結構是數(shù)組替饿,隨機查詢效率較高,增刪元素慢语泽;
LinkedList底層結構是鏈表,隨機查詢效率比較慢视卢,但是增刪元素快踱卵;
1.3 說一下HashMap實現(xiàn)原理
答:1.jdk1.8之前是數(shù)組加上鏈表,1.8以后是數(shù)組加上鏈表加上紅黑樹据过;
2.默認初始化容量為16惋砂,且每次擴容為2的n次冪,負載因子為0.75,鏈表閾值為8蝶俱;
3.每次擴容后這個值只可能在兩個地方班利,一個是原下標的位置,另一種是在下標為 <原下標+原容量> 的位置榨呆;
4.加入紅黑樹的原因是因為hash碰撞過多產(chǎn)生的鏈表過長會導致查詢效率降低罗标,轉變紅黑樹以后查詢效率更改,查詢時間復雜度在O(logN);
5.hashCode計算方法為积蜻,i.高 16bit 不變闯割,低 16bit 和高 16bit 做了一個異或;
6.hashMap是線程不安全的容器竿拆,情況1:在put的時候宙拉,當hashcode一樣時,會覆蓋值丙笋;情況2:并發(fā)擴容的時候也會存在同時擴容谢澈,最終只留下了最后一次擴容的數(shù)據(jù),導致數(shù)據(jù)丟失御板;
7.當容量大于容量*0.75時锥忿,put后進行擴容;
1.4 說一說volatile關鍵字的原理
答:1.volatile用來標明屬性內存可見性怠肋,即程序每一個獲取到的volatile的標量都是最新的敬鬓;
2.volatile還可以防止指令重排序;
3.voltile修飾后會在操作系統(tǒng)層面笙各,對變量的存取加內存屏障钉答,使其每次獲取值都是從主存拿;
1.5 說一下ConcurrentHashMap
答:1.這是一個線程安全的hashMap容器杈抢,采用分段鎖實現(xiàn)数尿;
2.jdk1.8之前用的是segment加鎖來實現(xiàn),1.8之后使用volatile+CAS來實現(xiàn)惶楼,降低了復雜度以及提供了性能砌创;
3.get操作時虏缸,沒有加任何鎖,因為Node的成員val是用volatile修飾的嫩实;
4.put時刽辙,使用鎖和cas實現(xiàn)線程安全;
5.內部node上加volatile修飾是為了保證擴容時對其他線程可見;
1.6 說一說java I/O
答:IO 總的來說分為兩個階段:第一階段是等待數(shù)據(jù)到達內核緩沖區(qū)甲献,第二階段是將數(shù)據(jù)從內核緩沖區(qū)復制到用戶緩沖區(qū)宰缤。
1.javaI/O氛圍BIO、NIO晃洒、AIO慨灭;
2.傳統(tǒng)形式的InputStream等類為BIO;
3.NIO主要涉及Channel,Buffers,Selectors 球及;代表框架為netty;
4.AIO在兩個階段都完成以后才發(fā)送信號氧骤,數(shù)據(jù)是直接可用的;
1.7 java鎖機制
答:這里主要說兩個類吃引,Synchronized和ReentrantLock筹陵;
1.Synchronized是一個關鍵字,只要給加上這個關鍵字镊尺,jvm底層會幫我們做同步
如果加在靜態(tài)方法上,那么鎖對象為該類庐氮;
如果加在普通方法上弄砍,那么鎖對象為該實例仙畦;
如果是靜態(tài)同步塊,那么鎖對象為括號里的對象音婶;
加上該關鍵字后慨畸,jvm字節(jié)碼會多出兩個指令,一個monitorEnter和monitorExit桃熄;理解為獲取鎖和釋放鎖先口;
2.ReentrantLock是一個類型奥,我們可以通過new 來獲取鎖對象瞳收,用這個類來控制鎖的獲取和釋放更加靈活;
每次在同步塊之前通過tryLock()方法嘗試獲取鎖厢汹,但是必須在退出同步方法中自己手動釋放鎖螟深,否則下一個線程永遠都獲取不到鎖,導致程序崩烫葬;
3.jvm底層有無鎖界弧,偏向鎖凡蜻,輕量級鎖,重量級鎖的概念垢箕,且鎖只能升級不能降級划栓;鎖標志是放在java對象的頭里Mark word,獲取到鎖后条获,會在mark word里面記錄當前線程的id忠荞;
1.8 Thread.sleep()跟object.wait()的區(qū)別;
答:sleep方法只是阻塞了線程帅掘,不釋放鎖委煤;而wait方法調用后不僅阻塞線程,還釋放鎖并且需要等到notify喚醒修档;調用后線程都是進入阻塞狀態(tài)碧绞;
1.9 公平鎖與非公平鎖底層實現(xiàn)原理
答:公平鎖是指按照線程等待順序獲取鎖,這種方式會造成性能低下吱窝,大量的時間花費在線程調度上讥邻;
非公平鎖是指不管等待順序,隨機獲妊⒂铡计维;
都是基于AQS實現(xiàn),內部維護一個雙向鏈表撕予,表結點Node的值就是每一個請求當前鎖的線程鲫惶,公平鎖每次從隊首取,非公平鎖不去判斷隊列直接搶占实抡,如果獲取不到就放入隊列欠母,后續(xù)就一個個來獲取鎖了;
具體底層使用volatile 修飾的state字段和CAS操作來實現(xiàn)吆寨;
1.10 紅黑樹特點
答:1.每個節(jié)點不是紅色就是黑色
2.根節(jié)點必須為黑色
3.紅色節(jié)點的葉節(jié)點只能是黑色
4.從任意節(jié)點到它的每個葉子結點的所有路徑都包含相同的黑色結點
1.11 java8的新特性
答:1.函數(shù)式編程赏淌,新增lambda表達式
2.Opntional類
3.時間相關類,例如LocalDate等
4.jvm變更啄清,取消了PermGen六水,新增了元數(shù)據(jù)區(qū),這個區(qū)域跟本地內存共享
5.接口允許添加默認方法
1.12 一個類的字節(jié)碼由哪些部分組成
答:1.魔術辣卒,表示文件類型掷贾,防止篡改
2.jdk版本號
3.常量池相關信息,如容量荣茫,類型想帅,字面量符號引用,類型啡莉,結構等
4.訪問標志
5.索引港准、父類索引旨剥、接口索引
6.字段表,方發(fā)表浅缸,屬性表
1.13 對用引用類型
答:1.強引用:直接new 轨帜,可以顯示地將引用賦值為null,這樣一來的話衩椒,JVM在合適的時間就會回收該對象阵谚。
2.軟引用:SoftReference ,只有在內存不足的時候JVM才會回收該對象烟具,適合用來做緩存
3.弱引用:WeakReference梢什,當JVM進行垃圾回收時,無論內存是否充足朝聋,都會回收被弱引用關聯(lián)的對象
4.虛引用:PhantomReference嗡午,如果一個對象與虛引用關聯(lián),則跟沒有引用與之關聯(lián)一樣冀痕,在任何時候都可能被垃圾回收器回收
2.spring相關
2.1 什么是IOC
答:ioc就是控制反轉的意思荔睹,將bean的管理權交給spring管理,就不需要自己new言蛇,也叫依賴注入僻他,將每個bean所以依賴的對象交由spring框架來自動注入;
2.2 什么是AOP
答:1.aop就是面向切面編程腊尚,通過代理的方式實現(xiàn)吨拗,主要用來做統(tǒng)一處理,例如登錄攔截婿斥,日志記錄劝篷,日志埋點等操作;事務實現(xiàn)其實也是通過aop來的民宿;
2.aop有多種通知娇妓,分別為前置,后置活鹰,環(huán)繞哈恰,異常等;切點可以用相關表達式去匹配志群,也可以自己去定義注解實現(xiàn)着绷;
3.動態(tài)代理又分jdk動態(tài)代理和cglib動態(tài)代理,當有實現(xiàn)接口時默認使用jdk赖舟,沒有實現(xiàn)接口時使用cglib蓬戚;
2.3 spring bean的初始化過程
答:創(chuàng)建上下文環(huán)境(beanFactory)-->準備容器--->加載xml內容---
->初始化bean到BeanDefinition-->實例化bean--->設置屬性---->對于實現(xiàn)了相關Aware接口的調用方法-->調用BeanPostProcess的postProcessBeforeInitialization方法---->調用InitializingBean的afterPropertiesSet方法--->調用指定的初始化方法----->調用BeanPostProcess的postProcessAfterInitialization方法--->bean準備就緒------->調用Dispostblebean的destory方法----->調用指定的銷毀方法
整個圖片就是:
這里可以擴展下spring循環(huán)依賴的實現(xiàn)夸楣,由于先實例化bean然后再設置屬性宾抓,由此解決了循環(huán)依賴的問題子漩,spring會將實例化后的bean放入一個標記容器里面,等到設置屬性的時候就會到相關容器里面去仁础幢泼;由此引出spring使用三級緩存來解決該問題;
三級緩存分別為:singletonObjects(一級)指單例對象的cache讲衫,singletonFactories(三級)指單例對象工廠的cache缕棵,earlySingletonObjects(二級)指提前曝光的單例對象的cache;
spring在實例化的時候會將還未初始化完全的對象放入三級緩存中涉兽;且這里用ObjectFactory來生產(chǎn)對象招驴;
例如:我們在編寫代碼時,兩個service類有時候會互相引用枷畏,但是程序運行時卻沒有報錯;
但是使用構造方法實例化的和多態(tài)的bean還是存在循環(huán)依賴問題的;
2.4 BeanFactory跟applicationContext的區(qū)別
答:1.beanFactory面向spring桦踊,而applicationContext面向spring開發(fā)者拳恋;
2.applicationContext擴展了beanFactory,實現(xiàn)了更多的功能渴肉,例如:支持aop冗懦,web等插件,國際化仇祭,事件傳遞等披蕉;
2.5 SpringMVC的流程圖
答:2.6 Spring boot的優(yōu)點
答:1.簡化配置,不需要xml文件
2.自動配置乌奇,許多的插件只需要引入相關依賴包嚣艇,并配置上相關參數(shù)就可以使用
3.應用監(jiān)控強大,提供一系列端點可以監(jiān)控服務及應用华弓,做健康檢測食零。
4.內置了tomcat容器,部署起來方便
2.6 Spring boot初始化流程
答:1.SpringApplication的main方法調用run時寂屏,主要做三件事:
根據(jù)classpath下是否存在(ConfigurableWebApplicationContext)判斷是否要啟動一個web applicationContext贰谣。
SpringFactoriesInstances加載classpath下所有可用的ApplicationContextInitializer
SpringFactoriesInstances加載classpath下所有可用的ApplicationListener
2.遍歷初始化過程中加載的SpringApplicationRunListeners,然后調用starting(),開始監(jiān)聽springApplication的啟動
3.加載SpringBoot配置環(huán)境(ConfigurableEnvironment)
4.banner配置
5.ConfigurableApplicationContext(應用配置上下文)創(chuàng)建迁霎,根據(jù)webEnvironment是否是web環(huán)境創(chuàng)建默認的contextClass吱抚,通過BeanUtils實例化上下文對象,并返回
6.prepareContext()方法將listeners考廉、environment秘豹、applicationArguments、banner等重要組件與上下文對象關聯(lián)昌粤。
7.refreshContext(context),bean的實例化完成IoC容器可用的最后一道工序
3. mybatis相關
3.1 mybatis有幾級緩存既绕,分別是
答:mybatis分二級緩存啄刹,分別sqlsession和namespace,默認開啟一級緩存
3.2 mybatis“$“和“#”的區(qū)別
答:“$“不做預編譯凄贩,“#”會進行預編譯誓军,可以有效防止sql注入問題;
4.數(shù)據(jù)庫相關
4.1 mysql事務的隔離級別
答:讀未提交疲扎,讀已提交昵时,不可重復讀,序列化椒丧,mysql默認級別為不可重復讀壹甥;
4.2 什么是臟讀,什么是幻讀壶熏,什么是不可重復讀盹廷;
答:1.臟讀:臟讀即為事務1第二次讀取時,讀到了事務2未提交的數(shù)據(jù)。若事務2回滾,則事務1第二次讀取時,讀到了臟數(shù)據(jù)
2.幻讀:事務1第二次查詢時久橙,讀到了事務2提交的數(shù)據(jù)俄占。
2.不可重復讀:不可重復讀與臟讀邏輯類似。主要在于事務2在事務1第二次讀取時淆衷,提交了數(shù)據(jù)缸榄。導致事務1前后兩次讀取的數(shù)據(jù)不一致。
4.3 事務的特性
答:acid分別為原子性祝拯,一致性甚带,隔離性,持久性佳头;
4.4 事務的傳播行為
答:PROPAGATION_REQUIRED 支持當前事務鹰贵,假設當前沒有事務。就新建一個事務
PROPAGATION_SUPPORTS 支持當前事務康嘉,假設當前沒有事務碉输,就以非事務方式運行
PROPAGATION_MANDATORY 支持當前事務,假設當前沒有事務亭珍,就拋出異常
PROPAGATION_REQUIRES_NEW 新建事務敷钾,假設當前存在事務。把當前事務掛起
PROPAGATION_NOT_SUPPORTED 以非事務方式運行操作肄梨。假設當前存在事務阻荒,就把當前事務掛起
PROPAGATION_NEVER 以非事務方式運行,假設當前存在事務众羡,則拋出異常
PROPAGATION_NESTED 如果當前存在事務侨赡,則在嵌套事務內執(zhí)行。如果當前沒有事務,則執(zhí)行與PROPAGATION_REQUIRED類似的操作羊壹。
4.5 如何優(yōu)化sql
答:1.首先查看是否是聯(lián)表查詢蓖宦,如果是就進行語句拆分;
2.拆分以后如果還是慢舶掖,就進行sql語句分析利用explain語句;
3.如果發(fā)現(xiàn)沒有使用索引尔店,那么就修改語句使走索引眨攘,如果沒有,那就考慮是否需要建立嚣州;
這里需要注意:聯(lián)合索引的最左匹配原則鲫售;
4.6 哪些情況下不會走索引
答:1.or語句,如果or前后有一個不走索引就不會走索引该肴;
2.like匹配情竹,只有前綴匹配才走索引;
3.等號前面進行運算
4.用聯(lián)合索引時匀哄,沒有使用第一個索引字段
5.如果列類型是字符串則必須用引號,否則不走索引
6.如果存在隱式轉換也是不走索引的
4.7 說一下數(shù)據(jù)庫的數(shù)據(jù)結構
答:這里拿innodb來說明:
1.B+tree的數(shù)據(jù)結構秦效,為什么不用Btree是因為B+tree的每一層能放下更多地址,只索引到下一個節(jié)點涎嚼,不保存數(shù)據(jù)阱州,這樣的話就降低了樹的高度,減少了查詢時的磁盤io法梯;
B+tree的特點:
非葉子節(jié)點只存儲鍵值信息苔货。
所有葉子節(jié)點之間都有一個鏈指針。
數(shù)據(jù)記錄都存放在葉子節(jié)點中立哑。
這里也可以引申說明下:當我們使用其余索引查詢時夜惭,如果只需要查詢索引數(shù)據(jù)最好就只寫該字段值,可以減少回表操作铛绰,提高性能诈茧;
4.8 說一下數(shù)據(jù)庫的mvcc
答:即多版本并發(fā)控制,在并發(fā)訪問的時候捂掰,數(shù)據(jù)存在版本的概念若皱,可以有效地提升數(shù)據(jù)庫并發(fā)能力,讀寫不沖突尘颓,利用快照實現(xiàn)讀走触;通過保存數(shù)據(jù)在某個時間點的快照來實現(xiàn)的。這意味著一個事務無論運行多長時間疤苹,在同一個事務里能夠看到數(shù)據(jù)一致的視圖互广。根據(jù)事務開始的時間不同,同時也意味著在同一個時刻不同事務看到的相同表里的數(shù)據(jù)可能是不同的。
innodb實現(xiàn):在每一行數(shù)據(jù)中額外保存兩個隱藏的列:當前行創(chuàng)建時的版本號和刪除時的版本號惫皱。這里的版本號并不是實際的時間值像樊,而是系統(tǒng)版本號。每開始新的事務旅敷,系統(tǒng)版本號都會自動遞增生棍。事務開始時刻的系統(tǒng)版本號會作為事務的版本號,用來和查詢每行記錄的版本號進行比較媳谁。
4.9 mysql explain type類型
答:1.all:全表掃描
2.index:另一種形式的全表掃描涂滴,只是掃描順序根據(jù)索引順序
3.range:有范圍的索引掃描,優(yōu)于index
4.ref:使用了索引晴音,但該索引列的值并不唯一柔纵,有重復
5.ref_eq:唯一查詢,只有一個
5. 線程池相關
5.1 如何new線程池
答:一般使用ThreadPoolExecute來創(chuàng)建線程池锤躁,參數(shù)詳解:
corePoolSize:核心可運行線程數(shù)
maximumPoolSize:最大可運行運行程數(shù)
workQueue:阻塞隊列
keepAliveTime:當線程大于核心線程數(shù)時搁料,且阻塞隊列沒有元素,最大等待時間
threadFactory:生成線程的工廠類
handler:超出線程池最大承受能力之后的失敗策略方法對象
5.2 為什么不用靜態(tài)方法創(chuàng)建
答:1.new CachedThreadPool系羞,new ScheduledThreadPool線程池無限大郭计,當任務過大時會導致oom;
2.new FixedThreadPool椒振,new SingleThreadpool拣宏,當請求隊列過大時,會導致oom杠人;
5.3 線程池submit和execute方法的區(qū)別
答:submit有返回值勋乾,execute沒有返回值,當我們需要方法運行后返回值來做處理時應該使用submit嗡善;
5.4 線程的生命周期
答:1.新建(new Thread())
2.就緒(Runnable)調用 start啟動
3.運行(Running)
4.堵塞(blocked)sleep辑莫、wait、join罩引、suspend 都會阻塞各吨;
5.死亡(dead)
6.jvm相關
6.1 說一下jvm內存模型;
答:jvm分為堆袁铐、棧揭蜒、程序計數(shù)器、本地方法棧剔桨、方法區(qū)屉更、元數(shù)據(jù)區(qū)(這里需要說下jdk1.8以前和以后的區(qū)別),堆又分年輕代洒缀,幸存區(qū)瑰谜,和老年代欺冀;
可以擴展說明下:年輕代使用復制算法,老年代是用標記-整理萨脑;
6.2 說下jvm是如何標記存存活對象
答:1.可達性分析法:通過將一些稱為”GC Roots”的對象作為起始點隐轩,從這些節(jié)點開始搜索,搜索和該節(jié)點發(fā)生直接或者間接引用關系的對象渤早,將這些對象以鏈的形式組合起來职车,形成一張“關系網(wǎng)”,又叫做引用鏈
2.引用計數(shù)法:就是給對象添加一個引用計數(shù)器鹊杖,每當有一個地方引用它時就加1悴灵,引用失效時就減1,當計數(shù)器為0的時候就標記為可回收
6.3例舉jvm的垃圾收集器
答:1.Serial 復制算法
2.Serial old 標記整理
3.PerNew 復制算法
4.parallel nScavenge 復制算法
5.parallel old 標記整理
再主要說明下cms和G1
1.G1 基本不用配置仅淑,低停頓称勋,用于大容量的堆胸哥。但是他犧牲了應用程序的吞吐量和部分堆空間涯竟。
2.CMS 配置比較復雜,合理的低停頓空厌,用于中等或更小的堆庐船。
3.所以當你覺得配置 CMS 太難了,或你的堆在 2 G 以上嘲更,或你想要顯式的指定停頓時間那么你可以使用 G1筐钟。否則使用 CMS
關于jvm調用還是要具體看你的目標是吞吐量還是程序停頓時間;
6.4 常用jvm的相關工具
答:Jstatus赋朦,JStack篓冲,Jmap等
6.5 什么是雙親委派模型
答:當需要加載一個類的時候,子類加載器并不會馬上去加載宠哄,而是依次去請求父類加載器加載壹将,一直往上請求到最高類加載器:啟動類加載器。當啟動類加載器加載不了的時候毛嫉,依次往下讓子類加載器進行加載诽俯。當達到最底下的時候,如果還是加載不到該類承粤,就會出現(xiàn)ClassNotFound的情況暴区。(自己不去加載交由父類去加載,一直往上辛臊,如果頂層加載不到然后依次往下)
6.6 哪些對象能作為GC root
答:1.由系統(tǒng)類加載器加載的對象仙粱;
2.Thread,活著的線程彻舰;
3.java方法的local變量缰盏;
4.JNI方法的local變量;
5.JNI全局引用;
6.用于JVM特殊目的由GC保留的對象口猜;
7.用于同步的監(jiān)控對象负溪;
6.7 虛擬機棧使用是否會內存溢出
答:內存溢出分為多種情況:
1.堆棧溢出
2.PermGen的溢出
3.使用ByteBuffer中的allocateDirect方法的,沒有做clear济炎,jvm垃圾回收不會回收這部分的內存川抡;
4.堆設置過大,導致機器內存分配線程不夠须尚;
5.地址空間不夠崖堤;
所以虛擬機棧使用會內存溢出;
7.redis相關
7.1 redis的兩種持久化機制
答:1.aof耐床,和rdb
2.rdb適合大規(guī)模數(shù)據(jù)恢復密幔,會存在數(shù)據(jù)丟失情況, 如果對數(shù)據(jù)一致性要求不高可以選擇這種
3.aof數(shù)據(jù)完整性更高撩轰,但是數(shù)據(jù)文件比較大胯甩,運行效率上比較慢
7.2 redis單線程為什么快
答:1.完全基于內存
2.數(shù)據(jù)結構簡單
3.采用單線程,避免了不必要的上下文切換
4.使用多路I/O復用模型
5.使用底層模型不同堪嫂,Redis直接自己構建了VM 機制
7.3 什么是緩存穿透偎箫,什么是緩存擊穿,什么是緩存雪崩
答:1.緩存穿透:緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù)皆串,而用戶不斷發(fā)起請求淹办,如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)。這時的用戶很可能是攻擊者恶复,攻擊會導致數(shù)據(jù)庫壓力過大怜森。
- 緩存擊穿是指緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù)(一般是緩存時間到期),這時由于并發(fā)用戶特別多谤牡,同時讀緩存沒讀到數(shù)據(jù)副硅,又同時去數(shù)據(jù)庫去取數(shù)據(jù),引起數(shù)據(jù)庫壓力瞬間增大拓哟,造成過大壓力
3.緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時間想许,而查詢數(shù)據(jù)量巨大,引起數(shù)據(jù)庫壓力過大甚至down機断序。和緩存擊穿不同的是流纹,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過期了违诗,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫漱凝。
8. dubbo相關
8.1說一下dubbo跟java的spi機制
答:java:java spi機制的優(yōu)點是解耦,但是缺點也有诸迟,比如說茸炒,不能指定獲取哪個實現(xiàn)類愕乎,寫在配置里面的都會被加載進來。 ServiceLoader
dubbo:支持指定實現(xiàn)類壁公,支持切面感论,支持依賴注入 ExtensionLoader、@Adaptive標記適配器類紊册、@SPI("值")使用默認的實現(xiàn)類
9.mq相關
9.1 說一下mq使用場景
答:解耦比肄、異步、削峰
9.2 mq對比
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
單機吞吐量 | 萬級囊陡,比 RocketMQ芳绩、Kafka 低一個數(shù)量級 | 同 ActiveMQ | 10 萬級,支撐高吞吐 | 10 萬級撞反,高吞吐妥色,一般配合大數(shù)據(jù)類的系統(tǒng)來進行實時數(shù)據(jù)計算、日志采集等場景 |
topic 數(shù)量對吞吐量的影響 | - | - | topic 可以達到幾百/幾千的級別遏片,吞吐量會有較小幅度的下降嘹害,這是 RocketMQ 的一大優(yōu)勢,在同等機器下丁稀,可以支撐大量的 topic | topic 從幾十到幾百個時候吼拥,吞吐量會大幅度下降倚聚,在同等機器下线衫,Kafka 盡量保證 topic 數(shù)量不要過多,如果要支撐大規(guī)模的 topic惑折,需要增加更多的機器資源 |
時效性 | ms 級 | 微秒級授账,這是 RabbitMQ 的一大特點,延遲最低 | ms 級 | 延遲在 ms 級以內 |
可用性 | 高惨驶,基于主從架構實現(xiàn)高可用 | 同 ActiveMQ | 非常高白热,分布式架構 | 非常高,分布式粗卜,一個數(shù)據(jù)多個副本屋确,少數(shù)機器宕機,不會丟失數(shù)據(jù)续扔,不會導致不可用 |
消息可靠性 | 有較低的概率丟失數(shù)據(jù) | - | 經(jīng)過參數(shù)優(yōu)化配置攻臀,可以做到 0 丟失 | 同 RocketMQ |
功能支持 | MQ 領域的功能極其完備 | 基于 erlang 開發(fā),并發(fā)能力很強纱昧,性能極好刨啸,延時很低 | MQ 功能較為完善,還是分布式的识脆,擴展性好 | 功能較為簡單设联,主要支持簡單的 MQ 功能善已,在大數(shù)據(jù)領域的實時計算以及日志采集被大規(guī)模使用 |
9.3 kafka offset相關
答:kafka offset分為兩種,一種是Current offset离例,保存在消費者端换团,決定調用poll方法時,拉取消息的順序宫蛆,
保證收到的消息不重復啥寇;
第二種是Commited offset,保存在broker洒扎,通過commitSync和commitAsync方法來操作辑甜,是用于Consumer Rebalance過程的,能夠保證新的Consumer能夠從正確的位置開始消費一個partition袍冷,從而避免重復消費磷醋。
10.其他
10.1 如何保證接口冪等性
答:使用唯一索引和token機制
10.2 分布式優(yōu)缺點
答:優(yōu)點:1.便于開發(fā)和擴展;
2.每個服務足夠內聚胡诗,降低耦合度邓线;
3.提高代碼復用性;
4.增加功能只需要增加子項目煌恢;
缺點:1.提高了系統(tǒng)復雜度
2.部署多個服務比較復雜骇陈;
3.因為服務多導致運維變得復雜;
4.架構復雜導致學習慢瑰抵;
5.測試和查錯復雜度上升你雌;
10.2 什么是線程安全;
答:多個線程執(zhí)行同一段代碼跟單線程執(zhí)行同一段代碼結果一樣二汛;主要是通過鎖機制來解決婿崭;
10.3 分布式事務的原則
答:柔性事務:遵循CAP理論或者其變種BASE理論的事務。分布式事務基本上都是柔性事務肴颊。具有弱一致性氓栈,也就是最終一致性
10.4 CopyOnWriteArrayList實現(xiàn)原理
答:讀寫分離的思想,copy出原來的數(shù)據(jù)然后做操作婿着,最終把引用指向新的容器授瘦,最終一致性;
10.5 RocketMQ是如何實現(xiàn)分布式事務的
答:通過事務消息來實現(xiàn)竟宋,發(fā)到broker的消息并不能馬上消息提完,稱為半消息,需要producer進行二次確認袜硫,如果二次確認途中丟失氯葬,有回查機制來解決;
10.6 讀寫鎖實現(xiàn)原理
答:與傳統(tǒng)鎖的區(qū)別是讀讀不互斥婉陷,讀寫互斥帚称,寫寫互斥官研,核心類為Sync,基于AQS的實現(xiàn)闯睹,可以用2個int變量來實現(xiàn)戏羽;AQS中的stata字段高16位是讀鎖個數(shù),低16位是寫鎖個數(shù)楼吃;
10.7 如何實現(xiàn)分布式鎖
答:分布式鎖實現(xiàn)主要有三種方式
分布式鎖實現(xiàn)方式 | 數(shù)據(jù)庫實現(xiàn) | redis實現(xiàn) | zookeeper實現(xiàn) |
---|---|---|---|
實現(xiàn)原理 | 1.通過給數(shù)據(jù)庫記錄加樂觀鎖或者悲觀鎖始花;2.通過數(shù)據(jù)庫記錄,獲取鎖insert一條記錄孩锡,釋放鎖刪除記錄 | 1.通過setnx方法實現(xiàn)酷宵,然后設置過期時間;2.與1一樣躬窜,但是key的值為當前時間+上過期的時間 | 利用zookeeper的臨時有序節(jié)點浇垦,所有線程都去創(chuàng)建臨時節(jié)點,但是序列最小的獲取到鎖荣挨,釋放只要刪除節(jié)點就可以 |
優(yōu)點 | 1.悲觀鎖是一種比較安全的實現(xiàn)男韧;2.樂觀鎖性能高于悲觀鎖,不容易出現(xiàn)死鎖默垄;3.增加記錄實現(xiàn)方式簡單 | 1.性能高此虑,實現(xiàn)比較方便 | 1.可靠性高 |
缺點 | 1.悲觀鎖性能低,容易出現(xiàn)死鎖口锭;2.樂觀鎖只能對一張表的數(shù)據(jù)加記錄朦前,需要操作多張表是辦不到的;3.不具備可重入性讹弯,沒有鎖失效機制况既,不具備阻塞鎖特性 | 1.鎖超時機制不是很可靠这溅,如果處理時間過長就會導致鎖實現(xiàn)组民;2.主從環(huán)境下可能存在key同步問題 | 1.性能比不上redis緩存鎖,因為需要頻繁的創(chuàng)建臨時節(jié)點 |
10.8 什么是無鎖編程
答:無鎖編程就是指利用CAS操作和volatile關鍵字實現(xiàn)線程安全悲靴;
10.9 什么是模塊化
答:就是講復雜系統(tǒng)拆分出一個個的模塊臭胜,模塊開發(fā)就是封裝細節(jié),提供接口癞尚;重點關注內聚度以及耦合度
優(yōu)點:1.可維護性高
2.靈活架構耸三,焦點分離
3.方便模塊間組合
4.多人協(xié)作,互不干擾
5.方便單個模塊的調試和測試
缺點:
1.系統(tǒng)分層浇揩,調用鏈長
2.模塊間發(fā)送消息仪壮,損耗性能
10.10 秒殺需要考慮的點
答:1.獨立部署,防止影響其他業(yè)務
2.靜態(tài)化相關商品描述信息胳徽;
3.增大秒殺帶寬积锅;
4.動態(tài)隨機成下單url爽彤,可以說獲取token,然后下單
5.限流缚陷,控制少量請求進入
3.23 新增
11 面試題
11.1 HTTP适篙、TCP、UDP的區(qū)別
答:1.osi 七層中的層級不同箫爷,http就屬于應用層,tcp與udp是屬于傳輸層嚷节;
2.http基于tcp
3.http長連接、短連接虎锚;就是tcp長連接硫痰、短連接
4.tcp面向連接,udp不是,如三次握手窜护,四次揮手碍论;
11.2 websocket和tcp的關系
答:1.跟http一樣,都是基于tcp;
11.3 jdk動態(tài)代理與cglib的區(qū)別,為什么要基于接口
答:1.jdk動態(tài)代理只能對實現(xiàn)了接口的類做代理柄慰,而cglib沒有這個限制鳍悠;
基于接口是因為:
1.生成的代理類繼承了Proxy,由于java是單繼承坐搔,所以只能實現(xiàn)接口藏研,通過接口實現(xiàn)
2.從代理模式的設計來說,充分利用了java的多態(tài)特性概行,也符合基于接口編碼的規(guī)范
11.4 分布式事務
答:1.指事務的每個操作步驟都位于不同的節(jié)點蠢挡,需要保證事務的acid特性;
產(chǎn)生原因:是分布式服務中凳忙,分庫分表业踏;
應用場景:下單:減少庫存以及更新訂單狀態(tài);支付:買家和商家同時扣款:前提:兩個賬戶都不在一個庫或者一個表涧卵;
解決方案:
1.兩階段提交協(xié)議
使用XA來實現(xiàn)勤家,XA分為事務管理器和本地資源管理器,本地資源管理一般由數(shù)據(jù)庫實現(xiàn)
2.使用消息中間件
11.5 ThreadLocalMap原理
答:ThreadLocalMap其實是線程自身的一個成員屬性threadLocals的類型柳恐,內部實現(xiàn)跟普通的map不一樣栗恩,內部用了一個ertry數(shù)組顾瞻,該數(shù)組繼承自WeakReference,WeakReference(弱引用)的特性:大家都知道WeakReference(弱引用)的特性,只要從根集出發(fā)的引用中沒有有效引用指向該對象磷瘤,則該對象就可以被回收裤纹,但是這里的有效引用并不包含WeakReference爵憎,所以弱引用不影響對象被GC鸡岗。WeakReference被ThreadLocal自身強引用,也就是說ThreadLocal自身的回收不受ThreadLocalMap的這個弱引用的影響戈锻;
3.24 面試題新增
12 面試題
12.1 TCP連接為什么可靠
答:1.超時重傳:發(fā)送后啟動一個定時器歼跟,等待目的確認收到却嗡,如果不及時確認,就會重發(fā)
2.給數(shù)據(jù)包編號嘹承,接收方對數(shù)據(jù)包排序窗价,有序傳給應用層;
3.校驗:保持首部和數(shù)據(jù)的校驗和叹卷,如果校驗有錯誤就丟棄撼港;
4.TCP接收端會丟棄重復數(shù)據(jù);
5.擁塞控制骤竹,當網(wǎng)絡擁塞時帝牡,減少數(shù)據(jù)的發(fā)送;
12.2 CGLIB是如何實現(xiàn)動態(tài)代理的
答:通過asm字節(jié)碼處理框架來實現(xiàn)的一個code生產(chǎn)類庫蒙揣;
12.3 http 和https的區(qū)別靶溜,以及https是如何保證安全的;
答: 1.http是明文傳輸懒震,https是加密傳輸
2.https加了一層ssl/tls協(xié)議
3.https需要使用ca證書罩息,且收費;
https加密過程:1.服務器將公鑰給瀏覽器 -->2.瀏覽器拿到公鑰之后个扰,生成一個“會話密鑰"--->3.用公鑰加密這個“會話密鑰”發(fā)送給服務器--->4.數(shù)據(jù)傳輸?shù)倪^程中瓷炮,就用這個會話密鑰來加密數(shù)據(jù)
12.4 進程和線程的區(qū)別
答:根本區(qū)別:進程是操作系統(tǒng)資源分配的基本單位,而線程是任務調度和執(zhí)行的基本單位
在開銷方面:進程切換上下文開銷大递宅;線程可以看做輕量級的線程娘香,開銷小办龄;
所處環(huán)境:在操作系統(tǒng)中運行多個進程烘绽,在一個進程中運行多個線程,
內存分配:系統(tǒng)會給進程分配內存俐填;對于線程只會分配cpu安接;
2020.03.25面試題新增
13 面試題
13.1 如何判斷連接是活的
答:1.應用程序自我探測;2.應用程序的探測 玷禽;3.TCP 協(xié)議層的焙斩危活探測
13.2 數(shù)據(jù)庫死鎖
答:1.以固定的順序訪問表和行。即按順序申請鎖矢赁,這樣就不會造成互相等待的場面。
2.大事務拆小贬丛。大事務更傾向于死鎖撩银,如果業(yè)務允許,將大事務拆小
3.在同一個事務中豺憔,盡可能做到一次鎖定所需要的所有資源额获,減少死鎖概率够庙。
4.降低隔離級別。如果業(yè)務允許抄邀,將隔離級別調低也是較好的選擇耘眨,比如將隔離級別從RR調整為RC,可以避免掉很多因為gap鎖造成的死鎖境肾。
5.為表添加合理的索引剔难。如果不走索引將會為表的每一行記錄添加上鎖,死鎖的概率大大增大奥喻。
6.通過添加鎖偶宫,集群就分布式鎖。
13.3 java內存模型
答:簡稱JMM环鲤,分為主內存和線程內存纯趋,共享變量存放在主內存;
13.4 什么是zero copy
答:減少了內核空間和用戶空間的copy冷离,用sendfile
13.5 如何判斷連接存活
答:使用netstat 命令吵冒;
14 2020.04.15更新
14.1 rabbitmq消息持久化的三個必要條件
答:1.消息隊列持久化。(設置durable)
2.exchange持久化西剥。(設置durable)
3.消息持久化桦锄。(deliveryMode為2)
14.2 Spring 父子容器訪問關系
答:springMVC可以訪問Spring容器的bean,但是Spring容器不能訪問SpringMVC容器的bean蔫耽。
14.3 Servlet什么時候初始化
答:看web.xml里面的配置结耀,loadestartup值為正數(shù)即容器啟動時候初始化,為負數(shù)則第一次請求時初始化匙铡;
14.4 cloud如何自己實現(xiàn)負責均衡算法
答:1.集成AbstractLoadBalanceRule類图甜;
2.注意:這個自定義的類不能放在@ComponentScan所掃描的當前包以及子包下,否則我們自定義的這個配置類就會被所有的Ribbon客戶端所共享鳖眼,也就是我們達不到特殊化指定的目的了黑毅。
3.使用方式:@RibbonClient(name = "MICROSERVICECLOUD-DEPT", configuration = MySelfRule.class)
14.5 aio、nio與bio中的阻塞點
答:首先一次io分2個階段:
1.等待數(shù)據(jù)準備
是否阻塞指的就是這一個階段钦讳。
2.將數(shù)據(jù)從內核拷貝到進程中
是否同步指的就是這一個階段矿瘦。
bio 兩個階段都阻塞
nio第一階段不阻塞,第二階段阻塞愿卒,通過輪詢數(shù)據(jù)是否準備好
aio兩個階段都不阻塞缚去,由內核完成,完成后通過信號告知
屬性\模型 | 阻塞BIO | 非阻塞NIO | 異步AIO |
---|---|---|---|
blocking | 阻塞并同步 | 非阻塞但同步 | 非阻塞并異步 |
線程數(shù)(server:client) | 1:1 | 1:N | 0:N |
復雜度 | 簡單 | 較復雜 | 復雜 |
吞吐量 | 低 | 高 | 高 |
場景 | 適用于連接數(shù)目比較小且固定的架構 | 連接數(shù)目多且連接比較短(輕操作)的架構琼开,比如聊天服務器 | 連接數(shù)目多且連接比較長(重操作)的架構易结,比如相冊服務器 |
14.6 linux如何查看端口占用情況
答:lsof,netstat命令;
15. 2020.04.21 面試提更新
15.1 jvm GC問題
答:GC 分為young gc搞动、major jc躏精、full gc;
1.young gc(minor gc) 主要針對新生代鹦肿;
2.majorgc 主要針對老生代矗烛;
3.full gc是針對整個堆;
以上三種gc都會出現(xiàn)stw箩溃,且任何垃圾回收器都無法避免stw瞭吃,jvm調優(yōu)就是為了是stw的時間縮短;
出發(fā)full gc的條件:
1.代碼中顯示調用system.gc()碾篡,調用后不一定馬上觸發(fā)虱而,需要jvm自行決定;
- young gc 之前判斷老年代可用的連續(xù)空間是否大于新生代的所有對象總空間开泽;
①.如果大于牡拇,直接進行young gc;
②.如果小于穆律,判斷是否開啟HandlerPromotionFailure惠呼,沒有開啟就直接full gc;
③.如果小于峦耘,且開啟該參數(shù)剔蹋,判斷是否大于歷次晉升的平均值,如果小于直接full gc辅髓,大于就young gc泣崩;
3.如果創(chuàng)建大對象時,老年代不足以存放洛口;
4.當持久代(方法區(qū))空間不足矫付,即元數(shù)據(jù)區(qū);
15.2 官方rocketmq 跟開源 rocketmq的區(qū)別
答:
功能 | 阿里rocketmq | 開源rocketmq |
---|---|---|
安全防護 | 支持 | 不支持 |
主子賬號 | 支持 | 不支持 |
可靠性 | 高第焰,超三分數(shù)據(jù)副本 | 不高 |
可用性 | 非常好 | 好 |
橫向擴展能力 | 支持平滑擴展买优,百萬級qps | 支持 |
low latency | 支持 | 不支持 |
定時消息 | 支持(精確到秒) | 支持(只支持18個level) |
事務消息 | 支持 | 不支持 |
全鏈路消息軌跡 | 支持 | 不支持 |
消息堆積能力 | 百億級別 不影響性能 | 百億級別 影響性能 |
性能(萬級topic場景) | 非常好,百萬級qps | 非常挺举,十萬級qps |
15.3 自定義實現(xiàn)lru算法
答:直接編寫類繼承LinkedHashMap類杀赢,構造方法時候傳入true,表示根據(jù)最近訪問時間排列湘纵,即設置accessOrder這個字段脂崔,重寫removeEldestEntry方法,也就是制定刪除策略;
如下就是瞻佛,容量超過最大值時脱篙,會刪除最少訪問的數(shù)據(jù)娇钱;
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
{
return size() > MAX_ELEMENTS;
}
15.4 后臺刷新緩存伤柄,前臺短時間內大量請求穿透到db绊困;
答:通過熔斷器以及限流技術,防止大量請求穿透到db适刀,以至于db崩掉秤朗;
15.5 為什么String是不可變得
答:
1..不可變對象可以提高String Pool的效率和安全性,直接復制地址笔喉,不需要復制數(shù)據(jù)
2.不可變對象對于多線程是安全的取视,修改不可變對象會報錯;
3.字符串常量池的需要常挚,常量池中存在時就不會創(chuàng)建新對象作谭;
4.允許String對象緩存HashCode,不可變就不需要重新計算hashcode奄毡;
5.安全性折欠,用戶名,密碼無法修改吼过;
15.6 Spring aop中用到的技術
答:1.動態(tài)代理技術
2.asm字節(jié)碼框架
3.代理設計模式
15.7 事務的作用范圍
答:作用于service層锐秦,第一次訪問數(shù)據(jù)庫時開啟,service層執(zhí)行完畢后盗忱,事務關閉/提交酱床;
15.8 java中的不可變對象
答:String ,原生類型的包裝器如Integer趟佃、Double扇谣、Long,BigInteger闲昭,LocalDate等
2020.04.23 面試題新增
16.1 dubbo spi用到的設計模式
答:在加載類的時候用到了工廠的設計模式罐寨,在方法調用時用到了代理模式;通過Adaptive汤纸,在調用階段動態(tài)地根據(jù)參數(shù)決定調用哪個實現(xiàn)類衩茸。
16.2 dubbo的注冊原理
答:利用Javassist技術生成invoker,然后調用DubboProtocol的export方法贮泞,最終會調用ZookeeperRegistryFactory的createRegistry進行注冊楞慈;
16.3 redis分布式鎖與zk分布式鎖的對比
答:1.redis分布式鎖,其實需要自己不斷去嘗試獲取鎖啃擦,比較消耗性能囊蓝;
2.zk分布式鎖,獲取不到鎖令蛉,注冊個監(jiān)聽器即可聚霜,不需要不斷主動嘗試獲取鎖狡恬,性能開銷較小蝎宇;
3.如果是redis獲取鎖的那個客戶端bug了或者掛了弟劲,那么只能等待超時時間之后才能釋放鎖,而zk的話姥芥,因為創(chuàng)建的是臨時znode兔乞,只要客戶端掛了,znode就沒了凉唐,此時就自動釋放鎖庸追。
16.4 double check問題
答:寫單例類時,有時用到double check台囱,這個時候還需要把單利對象用volatile修飾淡溯,這個有兩個作用
1.內存可見性;2.防止指令重排序簿训;
因為new一個對象有四個步驟咱娶,1.堆內存分配;2.初始化值煎楣;3.在棧中創(chuàng)建引用變量豺总;4.然后將堆內對象的地址賦值給引用變量;
如果不用volatile關鍵字择懂,那么上面四部就會被打亂喻喳;
2020.11.24 新增
17.如何保證kafka有序消費
答:1.單線程,單分區(qū)困曙,單消費者表伦;
2.多線程生產(chǎn),多quenue慷丽,多消費者就通過業(yè)務key去路由到指定的分區(qū)蹦哼,使統(tǒng)一業(yè)務的key路由到同一個分區(qū),同樣消費這也消費同一個分區(qū)要糊;
18.線程池參數(shù)詳解纲熏,以及工作原理
答:①corePoolSize:線程池的核心線程數(shù),說白了就是锄俄,即便是線程池里沒有任何任務局劲,也會有corePoolSize個線程在候著等任務。
②maximumPoolSize:最大線程數(shù)奶赠,不管你提交多少任務鱼填,線程池里最多工作線程數(shù)就是maximumPoolSize。
③keepAliveTime:線程的存活時間毅戈。當線程池里的線程數(shù)大于corePoolSize時苹丸,如果等了keepAliveTime時長還沒有任務可執(zhí)行愤惰,則線程退出。
⑤unit:這個用來指定keepAliveTime的單位赘理,比如秒:TimeUnit.SECONDS宦言。
⑥workQueue:一個阻塞隊列,提交的任務將會被放到這個隊列里感憾。
⑦threadFactory:線程工廠蜡励,用來創(chuàng)建線程令花,主要是為了給線程起名字,默認工廠的線程名字:pool-1-thread-3嫂沉。
⑧handler:拒絕策略扮碧,當線程池里線程被耗盡,且隊列也滿了的時候會調用慎王。
1.ThreadPoolExecutor.AbortPolicy:丟棄任務并拋出RejectedExecutionException異常。
2.ThreadPoolExecutor.DiscardPolicy:丟棄任務赖淤,但是不拋出異常蜀漆。如果線程隊列已滿,則后續(xù)提交的任務都會被丟棄咱旱,且是靜默丟棄确丢。
3.ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然后重新提交被拒絕的任務吐限。
4.ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務
19.jvm為什么1.8要將永久代變?yōu)樵獢?shù)據(jù)區(qū)鲜侥?
答:1.字符串存在永久代中,容易出現(xiàn)性能問題和內存溢出诸典;
2.類及方法的信息等比較難確定其大小描函,因此對于永久代的大小指定比,較困難狐粱,太小容易出現(xiàn)永久代溢出舀寓,太大則容易導致老年代溢出;
3.永久代會為 GC 帶來不必要的復雜度脑奠,并且回收效率偏低
4.將 HotSpot 與 JRockit 合二為一基公;
20.如何防止緩存擊穿
答:1.做無效key的空緩存;
2.利用bitmap實現(xiàn)過濾宋欺;
3.查庫之前先獲取分布式鎖轰豆;
21.當同一組kafka消費者數(shù)量大于kafka分區(qū)數(shù)的時候會出現(xiàn)什么胰伍?
答:有一部分消費者永遠都無法消費到數(shù)據(jù);
22.seata支持高并發(fā)么酸休?
答:不支持骂租,因為整個業(yè)務期間需要獨占資源;
23.es的索引結構
答:倒排索引和正排索引斑司;
24.mysql聚簇索引和非聚簇索引
答:1.聚簇索引葉子結點存放具體數(shù)據(jù)渗饮,且邏輯有序;非聚簇索引葉子節(jié)點存放聚簇索引的指針互站;
25.spring和spring boot的區(qū)別
答:spring boot是對spring做的擴展胡桃;
優(yōu)點是:
1:創(chuàng)建獨立的spring應用翠胰。
2:嵌入Tomcat, Jetty Undertow 而且不需要部署他們之景。
3:提供的“starters” poms來簡化Maven配置
4:盡可能自動配置spring應用。
5:提供生產(chǎn)指標,健壯檢查和外部化配置
6:絕對沒有代碼生成和XML配置要求
26.eureka失效剔除的時間以及次數(shù)戏罢,客戶端的同步時間間隔等
答:1.心跳間隔時間:30s
2.收到最后一次心跳過多久剔除:默認90s
3.進入自我保護的默認時間:15分鐘內統(tǒng)計的心跳比例地低于85%時會進入
27.熔斷器的默認配置桐磁,什么時候產(chǎn)生熔斷
答:1.10s內出先20次失斘依蕖校摩;
2.5s后重試;
3.錯誤率達到50%時也會短路溪窒;
28.mysql單表的數(shù)據(jù)量應控制在多少?
答:應該控制在500W左右灼狰,這與 MySQL 的配置以及機器的硬件有關交胚;InnoDB buffer size 足夠的情況下,其能完成全加載進內存军熏,查詢不會有問題。但是晤锹,當單表數(shù)據(jù)庫到達某個量級的上限時鞭铆,導致內存無法存儲其索引车遂,使得之后的 SQL 查詢會產(chǎn)生磁盤 IO舶担,從而導致性能下降衣陶;
29.分表路由策略
1.對分表參數(shù)進行哈希并取余路由剪况。
優(yōu)點:請求可均衡分布。
缺點:當表庫變更或悲,擴容時,會導致數(shù)據(jù)位置變更羔杨,處理繁瑣兜材。因此需要提前規(guī)劃好容量曙寡,一次分好。
場景:在線高性能服務
2.將分表參數(shù)劃分為不同的范圍户侥。不同范圍內的參數(shù)映射到不同的庫表蕊唐。例如用時間替梨,根據(jù)時間段劃分。
優(yōu)點:當表庫變更恋谭,擴容時處理較方便铜幽。
缺點:可能導致請求不均勻除抛,造成某個庫表被頻繁訪問到忽,其它庫表訪問頻率較低喘漏。
場景:非在線高性能服務持灰。日志服務堤魁。運營服務
30.聯(lián)合索引妥泉,最左匹配原則
答:當創(chuàng)建(col1,col2,col3)聯(lián)合索引時盲链,相當于創(chuàng)建了(col)單列索引刽沾,(clo1,clo2)聯(lián)合索引以及(col1,col2,col3)聯(lián)合索引想要索引生效,只能使用col1和col1,col2和col1,col2,col3三種組合;當然鉴象,col1,col3組合也可以牛欢,但實際上只用到了col1的索引傍睹,col3并沒有用到拾稳!
31.線程池中的核心線程數(shù)是如何保活的悍抑?
答:死循環(huán)從quenue中獲取任務,當不為空時拂盯,返回任務,否則一直阻塞榕订;
32.threadLocal原理
答:每個thread內部都維護了一個map劫恒,而這個map又是threadlocal維護的,由threadlocal對其進行get族壳,set操作贰您;這樣對于不同的線程锦亦,每次獲取副本值時杠园,別的線程并不能獲取到當前線程的副本值抛蚁,這樣就形成了副本隔離瞧甩,互不干擾亲配;
33.threadlocalmap是如何解決地址沖突的以及它擴容過程;
答:他是采用開放地址發(fā)解決地址沖突的玷犹,擴容時先清除key為null的value歹颓,然后在判斷當前容量是否大于負載因子的3/4,如果大于就進行擴容乏德,擴容方式和hashmap差不多胧瓜;
34.redis自己實現(xiàn)的數(shù)據(jù)結構有哪些?
答:
1.string -----> simple synamic string - 支持自動動態(tài)擴容的字節(jié)數(shù)組
2..list------>ziplist 壓縮列表钝满,節(jié)省內存,存儲不同類型的數(shù)據(jù)
3.hash----->當保存的鍵值大小都小于64時且個數(shù)小于512時偶洋,使用ziplist,否則使用散列表
4.set------->當存儲數(shù)據(jù)都為整數(shù)且個數(shù)小于512個使用有序數(shù)組存儲恩脂,否則使用散列表
5.sortSet----->當所有數(shù)據(jù)的大小都要小于64字節(jié)且元素個數(shù)要小于128個使用壓縮表,否則使用跳表趣斤;