ZooKeeper
1. CAP定理
C:一致性(讀操作總能讀到以前的寫操作)
A:可用性(在單臺(tái)機(jī)器出錯(cuò)時(shí),仍然能正常工作,不用遷移到其他機(jī)器)
P:分區(qū)容錯(cuò)性 (異常情況下仍然能滿足CA)
該理論指出一個(gè)分布式系統(tǒng)不可能同時(shí)滿足CAP,ZooKeeper保證了CP,A的話在Leader選舉時(shí)會(huì)丟失部分請(qǐng)求
2. ZAB協(xié)議
分為消息廣播(半數(shù)follower收到請(qǐng)求即commit)和崩潰恢復(fù)(leader崩潰后選舉leader的過程)
3. Leader選舉算法和流程
每個(gè)ZooKeeper都有兩個(gè)Id,一個(gè)是代表自己的Pid,一個(gè)是代表本身所存儲(chǔ)的數(shù)據(jù)的Zid,
一開始還沒有l(wèi)eader也沒有數(shù)據(jù)的時(shí)候會(huì)選舉最大的Pid當(dāng)leader
當(dāng)運(yùn)行突然崩潰時(shí),先每個(gè)都選舉自己,廣播自己的Pid和Zid,然后收到的機(jī)器廣播最大的那個(gè)Zid對(duì)應(yīng)的Pid,當(dāng)半數(shù)+1ZooKeeper同意的時(shí)候即成為L(zhǎng)eader
Redis
1. Redis的應(yīng)用場(chǎng)景
緩存、簡(jiǎn)單消息隊(duì)列、分布式鎖、共享session。
2. Redis支持的數(shù)據(jù)類型(必考)
String(SDS字符串,簡(jiǎn)單key-value,并發(fā)計(jì)數(shù),簡(jiǎn)單緩存),
List(zipList,LinkedList,雙向隊(duì)列,可以用作消息隊(duì)列,可以先進(jìn)先出,也可以先進(jìn)后出),
Set(intSet,HashTable,交并合集),
ZSet(ZipList,SkipList,熱搜榜一類,有排名的Set集合,事實(shí)上還用Hashtable存了key-分值),
Hash(ZipList,HashTable,rehash概念、提高負(fù)載因子,符合多重 key的情況,比如用戶的購(gòu)物車?)
3. zset跳表的數(shù)據(jù)結(jié)構(gòu)(必考)
首先實(shí)現(xiàn)一個(gè)單項(xiàng)鏈表,然后在此之上比如說每隔一個(gè)節(jié)點(diǎn)指向往后數(shù)數(shù)第二個(gè)節(jié)點(diǎn)。這樣的跳層有很多層
查詢方式為,先跳,如果大于了要查的分值,就往下一層查。
補(bǔ)充:跳表能用紅黑樹實(shí)現(xiàn)嗎,跳表的自平衡怎么實(shí)現(xiàn)?
紅黑樹沒法實(shí)現(xiàn)區(qū)間查詢,跳表可以查到一個(gè)之后再前后查,時(shí)間復(fù)雜度為O(nlogn)
跳表是通過隨機(jī)函數(shù)來維護(hù)索引與原始鏈表大小之間的平衡
4. Redis的數(shù)據(jù)過期策略(必考)
比如1.每隔100ms,查詢一部分?jǐn)?shù)據(jù),過期就刪除
2.查詢的key是過期的,刪除
當(dāng)內(nèi)存不夠使
對(duì)設(shè)置了過期時(shí)間的key:
隨機(jī)刪除、刪除快要過期的、刪除最不常用的、刪除一段時(shí)間最少使用的
對(duì)沒設(shè)置過期的key:
隨機(jī)刪除、刪除最不常用的,刪除最少使用的
或者直接報(bào)錯(cuò)
5. Redis的LRU過期策略的具體實(shí)現(xiàn)
維護(hù)了一個(gè)大小固定的pool,每次隨機(jī)取值,將lru值最小的放到pool里來
6. 如何解決Redis緩存雪崩,緩存穿透問題
雪崩(隨機(jī)過期時(shí)間、永不過期)、
穿透(表示惡意請(qǐng)求,在系統(tǒng)端判斷是否符合規(guī)則,比如id<0,布隆過濾器)、
擊穿(查詢加for update,永不過期)
7. Redis的持久化機(jī)制(必考)
RDB(內(nèi)存快照),比較快,存儲(chǔ)的是內(nèi)容,可以BGSave,fork一個(gè)子進(jìn)程存儲(chǔ),對(duì)于Slave可以一開始用這個(gè)同步,之后再以aof的形式同步,開啟時(shí)會(huì)影響并發(fā)性能。進(jìn)行BGSave時(shí)服務(wù)可能會(huì)暫停幾秒(需要注意)
AOF(AppendOnlyFile),比如每隔一秒將操作追加到log中,開啟aof會(huì)導(dǎo)致吞吐量降低,但是比RDB可以更完整的保護(hù)數(shù)據(jù),可以將AOF文件轉(zhuǎn)成RDB,
8. Redis的管道pipeline
減少TCP連接次數(shù),由客戶端緩存一部分命令后一次性發(fā)送。
9.Redis和memcached的區(qū)別
redis支持多種數(shù)據(jù)結(jié)構(gòu),支持系列化,key-value可存儲(chǔ)上限為1G,單核
memcached只支持String,不支持序列化,value大小最大為1MB,支持多核
10.Redis并發(fā)競(jìng)爭(zhēng)key的解決方案
比如要set一個(gè)key,順序?yàn)?34 ,沒加鎖變成了432
zookeeper的分布式鎖實(shí)現(xiàn)(監(jiān)聽前面一個(gè)節(jié)點(diǎn),當(dāng)自己為第一個(gè)節(jié)點(diǎn)時(shí),獲得鎖)
1.redis的分布式鎖實(shí)現(xiàn)(setnx+看門狗(比如當(dāng)key過期快到的時(shí)候還沒有delete,自動(dòng)續(xù)時(shí)),或者直接redission)
2.消息隊(duì)列串行執(zhí)行
11.Redis與Mysql雙寫一致性方案
先更新mysql再刪除reids,或者直接串行執(zhí)行
Mysql
1. 事務(wù)的基本要素
原子性,隔離性,一致性,持久性
2. 事務(wù)隔離級(jí)別(必考)
Uncommited 臟讀
commitedread 不可重復(fù)度
repeatedtable 幻讀(mysql默認(rèn))
seriazable
3. 如何解決事務(wù)的并發(fā)問題(臟讀,幻讀)(必考)
直接上隔離級(jí)別就可解決
讀加共享鎖,寫加排它鎖
4. MVCC多版本并發(fā)控制(必考)
Inodb多 維護(hù)了兩個(gè)字段,一個(gè)是createversion,一個(gè)是deleteversion
update時(shí)會(huì)更新createversion
讀取到一行需要滿足該事務(wù)的version大于等于createversion,而小于deleteversion
5. binlog,redolog,undolog都是什么,起什么作用
binlog記錄的是sql語(yǔ)句,
redolog記錄是為了保證事務(wù)安全,當(dāng)數(shù)據(jù)庫(kù)掛掉之后重啟仍能通過redolog執(zhí)行未完成事務(wù)
undolog記錄的是上一個(gè)版本,用來回滾和快照讀,
6. InnoDB的行鎖/表鎖
不走索引會(huì)表鎖,走索引會(huì)行鎖,for update、update,insert都是行鎖
如果索引不為主鍵索引,且索引可重復(fù),會(huì)有間隙鎖
7. myisam和innodb的區(qū)別,什么時(shí)候選擇myisam
innodb提供事務(wù),可以崩潰恢復(fù),最低行鎖
myisam不支持事務(wù),不能崩潰恢復(fù),表鎖,
讀寫分離,讀庫(kù)可以選擇myisam
8. 為什么選擇B+樹作為索引結(jié)構(gòu)(必考)
B樹非葉子節(jié)點(diǎn)也會(huì)存,導(dǎo)致b樹高度變高,io次數(shù)變多,而且葉子節(jié)點(diǎn)沒有指向下一個(gè)葉子節(jié)點(diǎn)的指針
9. 索引B+樹的葉子節(jié)點(diǎn)都可以存哪些東西(必考)
索引值,下一個(gè)葉子節(jié)點(diǎn)的開頭(范圍查詢的實(shí)現(xiàn))
主鍵索引可以不用再次查詢,因?yàn)橹麈I索引與數(shù)據(jù)放在一起。
普通索引需要再次查詢主鍵索引之后再得到數(shù)據(jù)
10. 查詢?cè)谑裁磿r(shí)候不走(預(yù)期中的)索引(必考)
查詢字段中雖然為索引,但是索引大量重復(fù)
用了or,但是后面的字段沒有用到索引
11. sql如何優(yōu)化
創(chuàng)建索引,索引字段設(shè)置成notnull ,注意不走索引的情況:%打頭的like語(yǔ)句,!=用> union <實(shí)現(xiàn),is
null的查詢,注意最左匹配原則;再有就是去優(yōu)化limit,先查id再limit,查詢別用select*,防止表修改后報(bào)錯(cuò)或者查詢?nèi)哂?br> SQL的執(zhí)行順序:from---where--group by---having---select---order by
12. explain是如何解析sql的
explain ***之后會(huì)顯示sql走的類型,掃描的行數(shù)等等,可以根據(jù)這個(gè)判斷sql
13. order by原理
利用索引的有序性獲取有序數(shù)據(jù),比較快(索引排序)
通過相應(yīng)的排序算法,將取得的數(shù)據(jù)在內(nèi)存中進(jìn)行排序,比較慢(文件排序)
14.Mysql為什么不用紅黑樹?
紅黑樹每個(gè)節(jié)點(diǎn)下只有兩個(gè)子節(jié)點(diǎn),而硬盤IO時(shí)是按簇讀取的,兩個(gè)節(jié)點(diǎn)中的值可能不夠填滿簇導(dǎo)致每次IO的浪費(fèi),此時(shí)紅黑樹的高度會(huì)大于B+樹,導(dǎo)致IO次數(shù)增加。
JVM
1. 運(yùn)行時(shí)數(shù)據(jù)區(qū)域(內(nèi)存模型)(必考)
堆、方法區(qū)、虛擬機(jī)棧,本地方法棧、程序計(jì)數(shù)器
2. 垃圾回收機(jī)制(必考)
強(qiáng)引用:會(huì)爆出OOM也不會(huì)被回收
軟引用:在內(nèi)存不夠的時(shí)候被回收
弱引用:每次GC都會(huì)被回收(ThreadLocal中內(nèi)部類Map的key就是)
虛引用:可以用來跟蹤GC,對(duì)象準(zhǔn)備被回收時(shí)發(fā)現(xiàn)他還有虛引用,會(huì)把這個(gè)虛引用加入一個(gè)引用隊(duì)列,可以觀察這個(gè)隊(duì)列中虛引用是否存在來判斷對(duì)象是否被回收了。
3. 垃圾回收算法(必考)
引用計(jì)數(shù)(redis就是用的這個(gè))
GCRoots(GCRoots可以簡(jiǎn)單記憶為,如果被刪就一定會(huì)影響程序運(yùn)行的對(duì)象,比如有虛擬機(jī)棧/本地方法棧中的引用對(duì)象,synchronized持有的對(duì)象,方法區(qū)中的靜態(tài)對(duì)象、常量)
分代收集
標(biāo)記清除(內(nèi)存泄漏)
標(biāo)記整理
復(fù)制(一般不用在老年代,太耗時(shí),且浪費(fèi)空間)
補(bǔ)充:OOPMap和RememberSet
OOP是棧中所存儲(chǔ)的是引用的堆中的對(duì)象,可以快速枚舉GCRoots
RememberSet是為了加快新生代的GCRoots,他保存的是老年代中對(duì)象引用的新生代對(duì)象,
此時(shí)真正的新生代的GCRoots為 “新生代GCroot+rememberSet里的對(duì)象”
G1收集器將堆分為各個(gè)region,但是難免會(huì)有各個(gè)region互相引用的情況,所以G1也用到了RememberSet
4. Minor GC和Full GC觸發(fā)條件
MinorGC:Eden區(qū)滿
fullgc:大對(duì)象直接 到老年代,老年代空間不足,system.gc,minorgc后發(fā)現(xiàn)老年代大剩余空間大小小于平均每次從新生代進(jìn)入老年代的值
5. GC中Stop the world(STW)
CMS會(huì)在找GCroot時(shí)和第二次查找時(shí)STW ,查找完畢就結(jié)束STW開始清理垃圾
G1會(huì)在找GCRoot時(shí)和第二次查找時(shí)STW,需要等垃圾清理完才結(jié)束
6. 各垃圾回收器的特點(diǎn)及區(qū)別
serial:?jiǎn)尉€程,復(fù)制算法,與其他的交互少的交互和上下文切換,快。
parnew:serial的多線程版本,只有這個(gè)能配合CMS
scanvage:吞吐量?jī)?yōu)先(用戶代碼執(zhí)行時(shí)間/用戶代碼+垃圾回收?qǐng)?zhí)行的時(shí)間)
cms:老年代并發(fā)收集器,標(biāo)記清除算法,停頓時(shí)間段,無法清理浮動(dòng)垃圾,cpu敏感,線程數(shù)為(cpu數(shù)+3)/4,cpu少的用戶效率較低
G1 :強(qiáng)化分區(qū),弱化分代的概念,本質(zhì)上是復(fù)制算法,能預(yù)測(cè)時(shí)間停頓
7. 雙親委派模型
類先由父加載器加載,如果不能加載再由子類加載。
通過類本身與加載器來確定類的唯一性,防止 類被重復(fù)加載或者被修改核心的api
8. JDBC和雙親委派模型關(guān)系
簡(jiǎn)單來說就是JDK的庫(kù)里有數(shù)據(jù)庫(kù)連接的接口,而具體實(shí)現(xiàn)是在各個(gè)數(shù)據(jù)庫(kù)的jar包中,又因?yàn)樽罡呒?jí)的那個(gè)加載器默認(rèn)只加載最基礎(chǔ)的jar包,所以只能用其他加載器去加載數(shù)據(jù)庫(kù)的jar包,此時(shí)雙親委派模型已經(jīng)被破壞(可能說的比較亂,這塊我也不太理解,tomcat比較好懂一點(diǎn))
補(bǔ)充:tomcat與雙親委派模型
tomcat中能加載多個(gè)項(xiàng)目,為了防止多個(gè)項(xiàng)目不同jar包沖突,就不可能讓父加載器都去加載這些,只能用子加載器加載各個(gè)項(xiàng)目的jar包。而父級(jí)加載器加載tomcat本身所需的jar包來確保安全。
tomcat還實(shí)現(xiàn)了jsp的熱部署,這個(gè)也是通過類加載器實(shí)現(xiàn)的
我們都知道jsp本質(zhì)上是servlet,他被類加載器加載后,如果被修改了,此時(shí)類名還是一樣,類加載器還是會(huì)從方法區(qū)直接讀取已經(jīng)存在的“緩存”來加載,這樣我們就無法實(shí)現(xiàn)熱部署了。那么怎么讓這個(gè)“緩存“失效呢?就是用自己的一個(gè)jsp類加載器,每個(gè)加載完成之后就卸載掉,每次加載都會(huì)去讀取最新的。如果此時(shí)使用雙親委派的話,需要把父類加載器卸載,tomcat直接掛啦。
9. JVM鎖優(yōu)化和鎖膨脹過程
鎖消除 不會(huì)發(fā)生競(jìng)爭(zhēng)的情況下JVM會(huì)把鎖消除
鎖粗化 比如簡(jiǎn)單for循環(huán)內(nèi)的synchronized會(huì)放到for循環(huán)外
偏向鎖 對(duì)象頭MarkWord01,還保存有持有的線程ID,這個(gè)MarKWord與無鎖狀態(tài)是一樣的,每次線程進(jìn)來只要比較每次進(jìn)來用CAS的方式把線程id設(shè)置成自己的,然后直接運(yùn)行即可。輕量級(jí)鎖 對(duì)象頭MarkWord00,由偏向鎖膨脹而來,先通過cas設(shè)置線程id,設(shè)置失敗,說明已經(jīng)有其他線程拿到偏向鎖了,開始膨脹,剛才那個(gè)拿到那個(gè)偏向鎖的線程會(huì)在自己棧幀中創(chuàng)建一塊區(qū)域保存對(duì)象的MarkWord信息,然后用CAS指向?qū)ο蟮腗arkWord區(qū)域。設(shè)置成功就相當(dāng)于獲得了輕量級(jí)鎖
重量級(jí)鎖 在輕量級(jí)鎖CAS多次失敗后會(huì)膨脹成重量級(jí)鎖,此時(shí)其他線程過來的時(shí)候會(huì)直接掛起。喚醒需要由內(nèi)核態(tài)轉(zhuǎn)換到用戶態(tài),比較耗時(shí)。
自旋鎖,就是一直嘗試獲取鎖,建立在別的線程獲取鎖占用時(shí)間比較短的認(rèn)知上。
Java基礎(chǔ)
1. HashMap和ConcurrentHashMap區(qū)別(必考)
線程不安全/安全
允許key-value為null/不允許
2. ConcurrentHashMap的數(shù)據(jù)結(jié)構(gòu)(必考)
1.7 segement+hashtable,put時(shí)lock自帶的自旋,一定次數(shù)后阻塞。獲得size的方法比較有意思,先遍歷各個(gè)segement獲取下面的長(zhǎng)度和修改次數(shù),加起來后再獲取一次,相同就返回,不相同就常識(shí)多次,一定次數(shù)后加鎖
1.8 node數(shù)組+hashtable+紅黑樹,put時(shí)cas自旋,多次后synchronized,多線程會(huì)幫助擴(kuò)容
兩者的get都是不用加鎖的,都用volatile修飾了
3. 高并發(fā)HashMap的環(huán)是如何產(chǎn)生的
1.7以前頭插法,在高并發(fā)的時(shí)候發(fā)生數(shù)組擴(kuò)容
4. volatile作用(必考)
保證可見性(這里指主內(nèi)存與工作內(nèi)存間的可見性),防止指令重排(指令重排也會(huì)導(dǎo)致可見性問題)
5. Atomic類如何保證原子性(CAS操作)(必考)
unsafe類的CAS和volatile,注意ABA問題
6. synchronized和Lock的區(qū)別(必考)
Lock底層就是AQS,是CLH隊(duì)列的增強(qiáng),CLH是一個(gè)先進(jìn)先出隊(duì)列,lock中把每個(gè)線程映射成CLH隊(duì)列的節(jié)點(diǎn),CLH本身是自旋的,AQS在此基礎(chǔ)上增加了可中斷,可重入,阻塞等待而不是一直自旋,和非公平鎖,還包括資源的獨(dú)占和共享兩個(gè)功能
怎么實(shí)現(xiàn)非共平鎖,有什么好處?
非公平鎖簡(jiǎn)單來說就是當(dāng)線程即將進(jìn)入隊(duì)列時(shí),先cas爭(zhēng)取資源,若得到則運(yùn)行,一定次數(shù)后仍然失敗則加入隊(duì)列,此時(shí)已失去非公平的手段,只能等前面節(jié)點(diǎn)來喚醒他。
公平鎖可能會(huì)導(dǎo)致,前一個(gè)節(jié)點(diǎn)釋放后,喚醒下一個(gè)節(jié)點(diǎn),此時(shí)線程還在由內(nèi)核向用戶態(tài)轉(zhuǎn)變,需要較多的時(shí)間,而非公平鎖可以減少這種情況的發(fā)生。
7. 為什么要使用線程池(必考)
減少開銷,方便管理
8. 核心線程池ThreadPoolExecutor的參數(shù)(必考)
核心線程、最大線程、消息隊(duì)列、存活時(shí)間、拒絕策略
9. ThreadPoolExecutor的工作流程(必考)
來一個(gè)先到核心線程,核心線程滿了到消息隊(duì)列,消息隊(duì)列滿了最大線程還沒滿,就建非核心線程工作
10. 如何控制線程池線程的優(yōu)先級(jí)
image
11. 線程之間如何通信
鎖、信號(hào)
12. Boolean占幾個(gè)字節(jié)
百度到的 1或4
13. jdk1.8/jdk1.7都分別新增了哪些特性
1.8:lanmbd表達(dá)式,default關(guān)鍵字,紅黑樹,尾插法,concurrenthashmap的node數(shù)組
1.7:不太了解,只知道1.7將String常量池(我更喜歡把它叫做String的對(duì)象池)放到堆中
14. Exception和Error
Exception可以catch后處理,比如IOexception,出錯(cuò)后程序仍能運(yùn)行
error是非檢查性異常,比如OOM,
補(bǔ)充:
簡(jiǎn)單說說怎么讓三個(gè)線程循環(huán)打印
1.new 三個(gè) semaphere ,一個(gè)為1,其他為0.當(dāng)A線程執(zhí)行時(shí)對(duì)自己的semaphere執(zhí)行acquire方法,執(zhí)行完畢后對(duì)下一個(gè)線程的semaphere執(zhí)行release。
不多比比,上鏈接
如果讓你用三個(gè)線程循環(huán)打印ABC,你有幾種寫法?
Spring
1. Spring的IOC/AOP的實(shí)現(xiàn)(必考)
ioc:beanfactory,在用到的時(shí)候加載到concurrenthashmap中,如果對(duì)象需要其他依賴,會(huì)遞歸實(shí)現(xiàn)里面的依賴。applicationcontext就是在容器加載的時(shí)候就把全部的bean放到concurrenthashmap中啦
aop:切面編程,一般是將可復(fù)用的方法在切點(diǎn)前后執(zhí)行,實(shí)現(xiàn)方式有aspectj(靜態(tài)織入),cglib和jdk動(dòng)態(tài)代理
順帶一提,dubbo中用了裝飾器把invoker包裝成wrapper
2. 動(dòng)態(tài)代理的實(shí)現(xiàn)方式(必考)
cglib:利用asm框架,把代理對(duì)象的class文件加載進(jìn)來之后修改其字節(jié)碼生成子類。
JDK:利用反射機(jī)制生成一個(gè)實(shí)現(xiàn)代理接口的匿名類[圖片上傳失敗...(image-d456ea-1589373944230)]
[圖片上傳失敗...(image-e7c7f8-1589373944230)]
補(bǔ)充:2.9bean的創(chuàng)建流程
1.獲取bean的名字
2.從緩存中查詢是否有這個(gè)bean
3.沒有的話就需要通過反射創(chuàng)建bean的實(shí)例(注意此時(shí)bean為空,里面東西都沒注入)
4.標(biāo)記這個(gè)bean已經(jīng)被創(chuàng)建了(此時(shí)可能會(huì)有循環(huán)依賴的問題,Spring用三級(jí)緩存來解決,提前將bean曝光)
5.遞歸獲取依賴的其他的bean
6.給當(dāng)前bean綁定屬性
3. Spring如何解決循環(huán)依賴(三級(jí)緩存)(必考)
構(gòu)造器(初始化與賦值沒法分開)與prototype(沒有實(shí)現(xiàn)三級(jí)緩存)會(huì)報(bào)錯(cuò)
三級(jí)緩存分別為1.初始化完成的bean(singletonObjects)2.實(shí)例化的bean(尚未綁定屬性,earlySingletonObjects)3.beanfactory(singletonFactories)
比如有兩個(gè)beanA和B循環(huán)依賴
在A的實(shí)例化階段標(biāo)記,將自己曝光到第三級(jí)緩存中,發(fā)現(xiàn)自己依賴B,去初始化B,B初始化過程中發(fā)現(xiàn)自己依賴A,從第三級(jí)緩存中g(shù)etObject拿到A(注意此時(shí)A只是實(shí)例化完成,并沒有初始化),此時(shí)B順利進(jìn)行初始化,將自己放到一級(jí)緩存中,此時(shí)返回A中,A順利拿到B,完成了初始化階段,放到了一級(jí)緩存。
4. Spring的后置處理器
[圖片上傳失敗...(image-dc0be-1589373944230)]
5. Spring的@Transactional如何實(shí)現(xiàn)的(必考)
也是通過AOP實(shí)現(xiàn)的,順帶一提,如果方法B由@Transactional修飾,而A方法沒有此注解,此時(shí)A去調(diào)用方法B,@Transactional失效
6. Spring的事務(wù)傳播級(jí)別
[圖片上傳失敗...(image-a92544-1589373944230)]
7. BeanFactory和ApplicationContext的聯(lián)系和區(qū)別
beanfactory:懶加載,
applicationcontext:繼承了beanfactory接口,比beanfactory功能更多,加載時(shí)全部加載
其他
1. 高并發(fā)系統(tǒng)的限流如何實(shí)現(xiàn)
2. 高并發(fā)秒殺系統(tǒng)的設(shè)計(jì)
3. 負(fù)載均衡如何設(shè)計(jì)
某37互娛一面節(jié)選(Lucene篇)
1.Lucene為什么比數(shù)據(jù)庫(kù)快?
mysql的索引只是存儲(chǔ)field的內(nèi)容(如果過長(zhǎng),只是存前多少位的內(nèi)容為索引)并沒用分詞
es存儲(chǔ)的是分詞以后的索引,每個(gè)詞都在哪些文檔中出現(xiàn)過。
如果是搜索 keyword這種基本沒啥影響
但是如果是mysql的like "%word%" mysql全表查,es只需要查"word"這個(gè)詞包含的文檔id 速度明顯不是一個(gè)級(jí)別。
2.什么是倒排索引?
簡(jiǎn)單理解就是將文章分詞后,用分出來的詞連接一個(gè)表,這個(gè)表里面是出現(xiàn)過這個(gè)詞的文章列表,可以根據(jù)這種方法快速查詢一個(gè)詞之后定位到文章,而不用去每個(gè)文章查這個(gè)詞。
3.倒排索引有哪幾部分?分詞屬于那一部分(不確定)
暫時(shí)理解為三部分,單詞id,單詞,倒排列表
image
其他補(bǔ)充:
網(wǎng)絡(luò):
TCP和UDP的區(qū)別?
TCP保證數(shù)據(jù)安全,以流的形式傳輸,一對(duì)一雙全工,能保證數(shù)據(jù)順序
UDP不保證數(shù)據(jù)安全,以數(shù)據(jù)報(bào)的形式傳輸,一對(duì)多,不保證數(shù)據(jù)順序
TCP是怎么保證安全的?
校驗(yàn)和
應(yīng)答機(jī)制
超時(shí)重傳
擁塞控制
流量控制
https和http的區(qū)別?
https:443端口,在TCP/IP協(xié)議上封裝了一層TCL/SSL,以數(shù)字證書的形式來保證數(shù)據(jù)安全
(將用戶數(shù)據(jù)hash后由公鑰加密成密文,拿到報(bào)文后解密密文,并在次將數(shù)據(jù)hash,比較數(shù)據(jù)是否相同,第一次傳輸用RSA得到對(duì)稱加密的秘鑰,之后都用對(duì)稱加密)
http:80端口,明文傳輸,無狀態(tài)
get/post區(qū)別?
本質(zhì)上是無區(qū)別的,
在瀏覽器端,get一般由url調(diào)用,順帶一提url的限制也是瀏覽器的原因,事實(shí)上http標(biāo)準(zhǔn)協(xié)議對(duì)url的長(zhǎng)度沒有限制,而post一般由表單調(diào)用
在restful規(guī)范中,get被認(rèn)為是冪等的,用來請(qǐng)求數(shù)據(jù),而post不冪等,用來實(shí)現(xiàn)資源的創(chuàng)建
Http請(qǐng)求的完整過程
1.DNS解析,先從瀏覽器緩存、內(nèi)存緩存、host文件、DNS服務(wù)器一步步把url解析成ip地址
2.拿到ip地址之后如果是自己網(wǎng)段的,一般路由器里都有對(duì)應(yīng)的mac地址,可以直接獲得然后三次握手建立TCP連接,如果不是自己網(wǎng)段的,還需要發(fā)到網(wǎng)關(guān),由arp協(xié)議得到mac地址。因?yàn)槠邔幽P投际巧蠈右蕾囅聦?,你想傳輸肯定得把網(wǎng)絡(luò)和數(shù)據(jù)鏈路層搞定。
3.建立起TCP連接后就可以發(fā)送HTTP請(qǐng)求了,這個(gè)請(qǐng)求到了服務(wù)端可能會(huì)有負(fù)載均衡、重定向,
4.處理完請(qǐng)求后把請(qǐng)求返回,由瀏覽器解析數(shù)據(jù)時(shí)發(fā)現(xiàn)還有一些靜態(tài)資源比如CSS JS或圖片,又會(huì)發(fā)起另外的請(qǐng)求,這就是后話了。
5.處理完成后B/S架構(gòu)不像C/S,一般都是短連接,四次揮手就關(guān)閉了。
為什么連接的時(shí)候是三次握手,關(guān)閉的時(shí)候卻是四次握手
四次握手是因?yàn)閷?duì)比與握手的被動(dòng)接收方,他還需要一次握手傳輸未傳輸完的信息來保證信息的完整性。
cookie和session的區(qū)別
cookie保存在瀏覽器端,一般有4BK的大小限制,cookie會(huì)有cros的安全問題,簡(jiǎn)單來說就是別的惡心請(qǐng)求拿到了cookie之后每次請(qǐng)求都帶上,解決方法是用token或者直接禁用cookie,使用token可以讓特定的請(qǐng)求帶上而不是每次請(qǐng)求都帶上。
session保存在服務(wù)器端,需要用url或者cookie請(qǐng)求sessionid拿到,
xss攻擊和ddos?
xss其原理是攻擊者向有XSS漏洞的網(wǎng)站中輸入惡意的 HTML 代碼,當(dāng)用戶瀏覽該網(wǎng)站時(shí),這段 HTML 代碼會(huì)自動(dòng)執(zhí)行
ddos 簡(jiǎn)單來說就是大量請(qǐng)求去攻擊一個(gè)公用接口,使服務(wù)器負(fù)載上升
什么是 DDoS 攻擊?
你知道的協(xié)議有哪些,在哪個(gè)層,有什么用?
簡(jiǎn)單挑幾個(gè)記吧。。 TCP IP ARP RAPR PPPOE SSL HTTP FTP SMTP
image
常見狀態(tài)碼及原因短語(yǔ)
1XX請(qǐng)求成功,正在處理
2XX請(qǐng)求成功,已經(jīng)處理
3XX 重定向
301永久重定向
302臨時(shí)重定向
4XX
400 請(qǐng)求語(yǔ)法錯(cuò)誤
403 服務(wù)被拒絕
404頁(yè)面不存在
5XX
500服務(wù)器內(nèi)部錯(cuò)誤(報(bào)錯(cuò)了)
502 服務(wù)不可用
計(jì)算機(jī)系統(tǒng)
進(jìn)程和線程的區(qū)別
進(jìn)程是資源分配的最小單位,進(jìn)程間不共享資源,通信困難
線程是cpu執(zhí)行的最小單位,線程共享本進(jìn)程的資源如內(nèi)存、I/O、cpu。同一時(shí)間內(nèi)同一個(gè)cpu只能執(zhí)行一個(gè)線程。
進(jìn)程的調(diào)度算法
時(shí)間片、先來先服務(wù)、最短時(shí)間、優(yōu)先級(jí)
什么是虛擬內(nèi)存
虛擬內(nèi)存是為了解決如今在有限的內(nèi)存空間加載較大的應(yīng)用程序,根據(jù)需要在磁盤和主存之間來回傳送數(shù)據(jù),通過段頁(yè)表的形式,先在虛擬內(nèi)存中取一段連續(xù)的內(nèi)存空間,再將這段內(nèi)存空間映射到主內(nèi)存中,此時(shí)主內(nèi)存空間的程序段可以不連續(xù),我們可以用頁(yè)表的形式找到他。
進(jìn)程間的通信方式
匿名管道(fork,只能父子進(jìn)程通信)
有名管道(在內(nèi)核申請(qǐng)一塊區(qū)域,任何進(jìn)程都可同信)
信號(hào)(信號(hào)是進(jìn)程間通信機(jī)制中唯一的異步通信機(jī)制,內(nèi)核進(jìn)程可以利用他通知用戶空間進(jìn)程發(fā)生了哪些系統(tǒng)事件)
信號(hào)量(本質(zhì)是個(gè)計(jì)數(shù)器,用來同步)
socket(首先創(chuàng)建套接字,然后綁定一個(gè)端口再監(jiān)聽套接字,可以通過網(wǎng)絡(luò)連接不同計(jì)算機(jī)上的進(jìn)程進(jìn)行通信)
共享內(nèi)存區(qū)(快,需要考慮并發(fā)情況)
死鎖怎么形成的,怎么解決死鎖
請(qǐng)求保持,互斥,循環(huán)等待,不可剝奪
解決方案:設(shè)置優(yōu)先級(jí)、請(qǐng)求一段時(shí)間后阻塞,
死鎖預(yù)防(用戶需要一次性請(qǐng)求全部資源),檢測(cè)到死鎖后強(qiáng)行剝奪進(jìn)程資源
Dubbo
什么是spi?dubbo對(duì)其做了什么改動(dòng)?
spi全名叫server provider interface,是一種服務(wù)發(fā)現(xiàn)機(jī)制,可以在運(yùn)行時(shí),通過全限定路徑名,動(dòng)態(tài)的加載接口的實(shí)現(xiàn)類。
dubbo在這個(gè)基礎(chǔ)上做了擴(kuò)展,比如說jdk的spi,他會(huì)不管你需不需要用到這些類,只要你啟動(dòng)就加載進(jìn)來,而我們一些方法就想用到他的時(shí)候再用反射來加載,就像spring的beanfactory一樣。
此外,在如果一個(gè)類需要擴(kuò)展的話,dubbo用裝飾者模式來實(shí)現(xiàn)了對(duì)類的擴(kuò)展,相當(dāng)于aop的實(shí)現(xiàn)。
服務(wù)暴露流程和引用流程?
首先dubbo有幾個(gè)角色,provider,consumer,注冊(cè)中心和監(jiān)控中心
簡(jiǎn)單來說就是provider將接口暴露,把服務(wù)注冊(cè)到注冊(cè)中心,由consumer訂閱注冊(cè)中心,在啟動(dòng)的時(shí)候在注冊(cè)中心找到發(fā)布的接入入口,注冊(cè)到consumer服務(wù)里面,相當(dāng)于創(chuàng)建了一個(gè)代理對(duì)象把服務(wù)間的通信封裝成了一個(gè)對(duì)象的調(diào)用。底下涉及到了網(wǎng)絡(luò)通信、協(xié)議的轉(zhuǎn)換等。
具體一點(diǎn):
服務(wù)暴露:一開時(shí)就是解析一些配置文件,然后有一個(gè)serviceBean來執(zhí)行暴露邏輯,里面主要涉及到protocal協(xié)議類,這個(gè)servicebean在初始化完成的時(shí)候會(huì)把那些參數(shù)注入進(jìn)來,然后到ioc容器初始化完成的時(shí)候,開始來暴露方法,把要注冊(cè)的方法封裝成一個(gè)服務(wù)的執(zhí)行對(duì)象invoker,先把這個(gè)放到自己的緩存中,通過protocal協(xié)議類去把invoker通過協(xié)議暴露給外部。
服務(wù)引用:
引用與服務(wù)暴露類似,一開始也是初始化配置,然后有一個(gè)ReferenceBean來執(zhí)行引用邏輯,主要利用RegistryProtocol完成provider的訂閱、自己本身consumer的注冊(cè)、和執(zhí)行對(duì)象invoker的創(chuàng)建(這里訂閱完成后如果有變動(dòng)會(huì)調(diào)用notify方法去注冊(cè)和修改緩存里的invoker),把url和invoker的映射關(guān)系加到緩存之后還沒完,根據(jù)負(fù)載均衡算法拿到要執(zhí)行的invoker后,動(dòng)態(tài)代理生成代理類,通過代理類來完成請(qǐng)求遠(yuǎn)程dubbo服務(wù)并獲取響應(yīng)結(jié)果的功能。
dubbo的負(fù)載均衡機(jī)制?
輪詢、加權(quán)輪詢、一致性哈希、隨機(jī)、最少活躍數(shù)
dubbo的容錯(cuò)機(jī)制?
廣播 (一個(gè)報(bào)錯(cuò)就失敗,用于更新各個(gè)provider的本地資源信息)
多次發(fā)送(有一個(gè)成功就行,高時(shí)效性的讀)
失敗后重試(冪等)
失敗后報(bào)錯(cuò)(不冪等)
失敗后不報(bào)錯(cuò)記錄日志(審計(jì)日志)
失敗后按照配置策略一段時(shí)間后重試(消息通知)
dubbo支持的協(xié)議?
灰度發(fā)布了解嗎?
version標(biāo)簽為*,按照負(fù)載均衡的機(jī)制來找機(jī)器調(diào)方法,一部分機(jī)器更新為最新版
消息隊(duì)列
消息隊(duì)列的作用?
異步:比如訂單服務(wù)與下單后送的優(yōu)惠券服務(wù),兩者異步執(zhí)行。
削峰:大量寫操作,可以用消息隊(duì)列削峰。
解耦:仍然是訂單服務(wù)和優(yōu)惠券服務(wù),減少各個(gè)系統(tǒng)間的耦合,本系統(tǒng)只保證本系統(tǒng)的實(shí)現(xiàn)和消息隊(duì)列的落地,別的系統(tǒng)的落地由消息隊(duì)列來保證。image
kafka的角色組成?
imageProducer:服務(wù)生產(chǎn)者
Consumer:服務(wù)消費(fèi)者(注意下文與partition的關(guān)系)
Broker:代理,可以看作是一個(gè)kafka的實(shí)例,由多個(gè)Broker可以組成一個(gè)集群Cluster。一個(gè)Broker中還包含Topic(主題)和Partition(分區(qū))的概念
Topic:Producer 將消息發(fā)送到特定的主題,Consumer 通過訂閱特定的 Topic(主題) 來消費(fèi)消息。
Partition:分區(qū)屬于Topic的一部分,一個(gè) Topic 可以有多個(gè) Partion,在每個(gè)Broker中都有他的全部信息(高可用),而各個(gè)Consumer也可以去不同的partition去讀取。
重要:如果有三個(gè)partition,四個(gè)consumer,其中一個(gè)consumer會(huì)空閑。
kafka怎么保證高可用?
簡(jiǎn)單來說,就是備份分區(qū)僅僅用作備份,不做讀寫。如果某個(gè)Broker掛了,會(huì)選舉其他的partition來作為主分區(qū)。
如果重復(fù)消費(fèi)/消息消費(fèi)失敗怎么辦?怎么保證冪等?
此時(shí)就需要操作保證請(qǐng)求的冪等。 消息消費(fèi)失敗會(huì)有重試機(jī)制去保證他成功。
冪等的實(shí)現(xiàn)可以說多種多樣。
1.全局唯一id
比如用戶付費(fèi)成功(流水表里面有唯一id),然后用消息隊(duì)列調(diào)用其他業(yè)務(wù)(其他業(yè)務(wù)中會(huì)有流水表唯一id字段),可以先去查這個(gè)id存不存在,不存在就執(zhí)行。
2.表中狀態(tài)字段
比如訂單表中有一個(gè)是否已支付的字段,去查的時(shí)候可以通過這個(gè)字段來決定是否執(zhí)行。
3.唯一索引實(shí)現(xiàn)insert的冪等
比如已經(jīng)創(chuàng)建流水id,可以把這個(gè)設(shè)置成唯一索引,其他再次insert時(shí)就會(huì)報(bào)錯(cuò)。
再比如通過全局唯一id和用戶id設(shè)置成聯(lián)合唯一索引,可以實(shí)現(xiàn)秒殺場(chǎng)景下,一個(gè)用戶只能購(gòu)買一件的需求。
3.redis實(shí)現(xiàn)冪等
比如發(fā)驗(yàn)證短信的場(chǎng)景,先獲取一個(gè)token,保存在redis中,操作加入到消息隊(duì)列,然后判斷下redis中是否有這個(gè)token,有的話就消費(fèi)并且把reids中的token刪除,沒有的話就不執(zhí)行。
怎么保證消息的有序執(zhí)行?
1、當(dāng)消息加入到一個(gè)partition的時(shí)候,都是增量添加,所以都是有序的,所以可以設(shè)定只有一個(gè)partition。(不推薦這種方法,失去了kafka的高可用)
2、指定partition發(fā)送,Kafka 中發(fā)送 1 條消息的時(shí)候,可以指定topic, partition, key,data(數(shù)據(jù)) 4 個(gè)參數(shù)。如果你發(fā)送消息的時(shí)候指定了 partion 的話,所有消息都會(huì)被發(fā)送到指定的 partion。并且,同一個(gè) key 的消息可以保證只發(fā)送到同一個(gè) partition,比如我們可以把唯一訂單號(hào)作為key,這樣一個(gè)訂單的操作就能保證順序消費(fèi)了。
消息如何保證不丟失?
kafka在partition有數(shù)據(jù)進(jìn)來的時(shí)候會(huì)先緩存一部分,等數(shù)據(jù)量足夠多或者等待一定時(shí)間再批量寫到磁盤的消息日志上。
消息積壓怎么辦?
擴(kuò)展機(jī)器數(shù)量,創(chuàng)建新的topicB ,設(shè)定10個(gè)partition,之前A的消費(fèi)者邏輯改為獲取到topicA的消息之后,發(fā)topicB的消息,然后新的10臺(tái)機(jī)器來處理topicB的數(shù)據(jù),這樣效率是以前的3倍。
更多海量學(xué)習(xí)資源與面試指南,請(qǐng)觀柱貢眾呺 【程序論】,免費(fèi)領(lǐng)取。




