問(wèn)題還有答案都在,歡迎大家一起討論指正。
如何實(shí)現(xiàn)動(dòng)態(tài)修改配置
我提到 1)通過(guò)MBean來(lái)保存配置信息,JMX來(lái)修改配置;還提到log4j2就是通過(guò)這種機(jī)制來(lái)實(shí)現(xiàn)日志級(jí)別的動(dòng)態(tài)修改;2)開(kāi)放telnet接口或者h(yuǎn)ttp接口來(lái)允許參數(shù)的修改;
他提到如何實(shí)現(xiàn)中心配置,我提到了zookeeper,而且提到一個(gè)好處,當(dāng)參數(shù)修改時(shí),可以實(shí)時(shí)通知;他提到zookeeper的客戶端需要保持長(zhǎng)連接才能接收參數(shù)變化的通知,這樣連接數(shù)會(huì)很多,有沒(méi)有其他方式;我提到可以通過(guò)push的方式,短連接來(lái)發(fā)送通知的方式。
Vertx的線程模式
線程模型和Netty的區(qū)別,回答不上來(lái),只說(shuō)了下Vertx的線程模型 - 分發(fā)線程和工作線程
Vertx和RxJava的區(qū)別
都是響應(yīng)式框架,區(qū)別是什么?回答不上來(lái)
用了什么validation框架
Vertx-contract,若干個(gè)內(nèi)置的validation rule,實(shí)質(zhì)是對(duì)應(yīng)一個(gè)正則表達(dá);可以自定義validation rule,例如某個(gè)API的枚舉類型數(shù)據(jù);
NIO的BIO的區(qū)別
我回答到NIO內(nèi)有selector,它可以注冊(cè)事件,從而提高線程的使用效率;他問(wèn)到selector背后的實(shí)現(xiàn),我提到了epoll;繼續(xù)問(wèn)我是否知道epoll的兩種觸發(fā)方式 - 水平觸發(fā)和邊緣觸發(fā),我回答不上來(lái)。
Redis分布式鎖的實(shí)現(xiàn)
我回答使用redisson的Redloc算法實(shí)現(xiàn)分布式鎖,它提到了這個(gè)算法還是會(huì)有問(wèn)題,但想不起來(lái)什么場(chǎng)景下會(huì)有問(wèn)題了。
他提到了一個(gè)場(chǎng)景:如果有三個(gè)請(qǐng)求,第一個(gè)請(qǐng)求加了分布式鎖,其他二個(gè)等待,在返回前第一個(gè)請(qǐng)求當(dāng)機(jī)了,沒(méi)有清除鎖,這種情況怎么辦?
我提到了通過(guò)TTL來(lái)防止死鎖;我還提到了用setnx來(lái)加鎖,用ttl來(lái)設(shè)置存活時(shí)間防止死鎖;他提到這是兩個(gè)命令,不是原子的,我回答可以將setnx的value內(nèi)設(shè)置存活時(shí)間,這樣當(dāng)?shù)诙?qǐng)求來(lái)的時(shí)候,盡管有分布式鎖,但是顯示鎖已經(jīng)過(guò)期,所以這個(gè)鎖不會(huì)生效;
這個(gè)地方有些模糊,需要好好看一下,有點(diǎn)蒙過(guò)去的感覺(jué)。
further: 如上我的solution也是會(huì)有問(wèn)題的,當(dāng)后續(xù)線程并行可能同時(shí)檢測(cè)到鎖已經(jīng)過(guò)期,例如B和C,這樣就會(huì)同時(shí)執(zhí)行delete操作,然后執(zhí)行set操作,這時(shí)可能c刪除的是B剛剛設(shè)置的鎖,而不是最初的A鎖。
所以可以這樣,
1. 用一個(gè)更多參數(shù)的set方法,同時(shí)有NX和PX語(yǔ)義,即只有當(dāng)不存在才設(shè)置,和同時(shí)設(shè)置過(guò)期時(shí)間在一個(gè)原子操作內(nèi),防止客戶端執(zhí)行第一步后宕機(jī)。
2. 兩個(gè)語(yǔ)句 - setnx和expire, 當(dāng)setnx失敗的時(shí)候,會(huì)檢測(cè)ttl是否存在,如果不存在則設(shè)置ttl防止死鎖,這樣即使A線程宕機(jī)沒(méi)有來(lái)得及執(zhí)行expire,也會(huì)被后續(xù)線程設(shè)置上。這樣的side-effect是鎖的持續(xù)時(shí)間會(huì)比預(yù)期要長(zhǎng)些。
TTL過(guò)期后,什么時(shí)候Redis真正刪除這個(gè)緩存?
回答不上來(lái)。過(guò)后查詢的答案是:Redis使用惰性刪除和定期刪除的策略,惰性刪除是在訪問(wèn)數(shù)據(jù)時(shí),首先判斷是否過(guò)期,如果過(guò)期,則刪除緩存返回為空;定期刪除是一定時(shí)間內(nèi)對(duì)數(shù)據(jù)庫(kù)進(jìn)行掃描,清除掉過(guò)期數(shù)據(jù),防止由于數(shù)據(jù)未被訪問(wèn)而內(nèi)存沒(méi)有釋放。定期刪除會(huì)設(shè)定最大的掃描時(shí)間以及每一個(gè)數(shù)據(jù)庫(kù)抽樣的個(gè)數(shù);并且下次掃描會(huì)從根據(jù)上次掃描到的數(shù)據(jù)庫(kù)繼續(xù)掃描下一個(gè)數(shù)據(jù)庫(kù)。
如上是刪除過(guò)期數(shù)據(jù),這里是刪除未過(guò)期數(shù)據(jù)-當(dāng)內(nèi)存使用達(dá)到maxmemory閾值時(shí),執(zhí)行maxmemory-policy的策略,一共有6種策略來(lái)刪除未過(guò)期的數(shù)據(jù)。
volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
volatile指設(shè)置了ttl的元素; allkey指所有元素
lru指least rencently used,去除最近最不常訪問(wèn)的元素; random指隨機(jī)刪除元素。
ttl指按照ttl優(yōu)先刪除即將過(guò)期的元素。
默認(rèn)是volatile-lru從設(shè)置過(guò)期時(shí)間的元素里刪除最不長(zhǎng)訪問(wèn)的元素。
分布式提交
是否用過(guò)分布式提交? 我提到二次提交,面試官說(shuō)這是傳統(tǒng)辦法,對(duì)于互聯(lián)網(wǎng)行業(yè)來(lái)說(shuō)用的比較少,因?yàn)樾阅懿粔颉?/p>
查詢文檔后,可以通過(guò)消息中間件轉(zhuǎn)為本地事務(wù)。
消息中間件
我提到了kafka,
順序存儲(chǔ)是如何實(shí)現(xiàn)的?
我說(shuō)不知道,應(yīng)該是文件的追加寫入,kafka不支持文件的隨機(jī)寫入;
是否知道zero-copy?
我回答的是有點(diǎn)類似堆外內(nèi)存,少了內(nèi)核態(tài)到用戶態(tài)的拷貝,所以加快速度;另外我還提到了kafka的作弊,可以直接把一個(gè)幾M文件直接返回,從而達(dá)到幾M/s的吞吐量。
有沒(méi)有了解push機(jī)制的中間件
不會(huì)回答
GC
Full GC頻繁,如何查錯(cuò)?
我提到首先了解當(dāng)前的配置信息,例如是那種GC collector,young/old區(qū)的大小;
開(kāi)啟GC日志來(lái)獲取更多信息;
dump堆找出異常大或者異常多的可以對(duì)象,查看代碼是否有內(nèi)存泄露;
如何寫代碼模擬出Full GC頻繁的現(xiàn)象
我回答 1)調(diào)節(jié)參數(shù)使得young區(qū)很小,這樣對(duì)象直接分配到old區(qū);2)調(diào)節(jié)參數(shù),使得promotion的閾值很小,甚至為0,這樣young區(qū)對(duì)象直接promote到old區(qū);3)創(chuàng)建大的數(shù)組對(duì)象,因?yàn)樾枰B續(xù)空間,所以很容易直接分配到堆中;
什么情況下對(duì)象會(huì)創(chuàng)建在棧內(nèi)?
我提到JVM有優(yōu)化,會(huì)把對(duì)象打散,將基本數(shù)據(jù)存儲(chǔ)在棧內(nèi);
是否聽(tīng)說(shuō)過(guò)逃逸分析?
我回答:判斷一個(gè)對(duì)象是否可能被其他線程調(diào)用,如果沒(méi)有,則說(shuō)明這個(gè)對(duì)象時(shí)線程安全的,不需要同步,即使有同步也會(huì)進(jìn)行同步消除來(lái)提高性能。
如何優(yōu)化spark程序?
1)改變數(shù)據(jù)的處理流程;2)充分利用DataFrame的緩存;3)調(diào)優(yōu)參數(shù)
是否遇到數(shù)據(jù)不平衡問(wèn)題
回答遇到過(guò),舉了分org存儲(chǔ)的實(shí)際解決方案。