1妄帘、微信紅包怎么實(shí)現(xiàn)楞黄。
2、海量數(shù)據(jù)分析抡驼。
3鬼廓、測(cè)試職位問的線程安全和非線程安全。
4致盟、HTTP2.0碎税、thrift
http2.0 主要是解決 head of line blocking問題,就是請(qǐng)求串行等待的問題馏锡,支持多路復(fù)用
http2.0 使用了新的二進(jìn)制格式傳輸雷蹂,一個(gè)request對(duì)應(yīng)一個(gè)stream分配一個(gè)stream id,每個(gè)frame可以混雜在一起
杯道,通過(guò)stream id查找到對(duì)應(yīng)的request
通過(guò)設(shè)置priority可以由服務(wù)端識(shí)別處理優(yōu)先級(jí)(并發(fā)請(qǐng)求原茅,優(yōu)先響應(yīng)的問題)
header壓縮
服務(wù)推送數(shù)據(jù)給客戶端
http層的流量控制(window窗口概念)
ssl支持黑白名單配置
thrift 是一種基于中間描述生成代碼
的協(xié)議(RPC框架)赘艳,靜態(tài)編譯浪蹂,數(shù)據(jù)的編碼和解析具有很好的性能【QPS > 1000】
hessian 是一種基于直接類型
的協(xié)議臂聋,需要通過(guò)反射進(jìn)行編譯和解析【QPS < 1000 】
5、先讓自我介紹齿拂。
6驳规、分布式事務(wù)一致性。
7署海、nio的底層實(shí)現(xiàn)
NIO = IO多路復(fù)用 + IO非阻塞快速反饋
IO多路復(fù)用
:提供注冊(cè)連接機(jī)制吗购,epoll只返回發(fā)出請(qǐng)求的連接
IO非阻塞快速反饋
:發(fā)出的請(qǐng)求不管是否有數(shù)據(jù)流,都理解反饋叹侄,不阻塞
8巩搏、jvm基礎(chǔ)是必問的昨登,jvm GC原理趾代,JVM怎么回收內(nèi)存。
答:清除方法區(qū)(不使用常量丰辣、不被引用的類和類加載器)
和堆棧(不使用對(duì)象)
撒强,計(jì)算出不使用的對(duì)象, 1.計(jì)數(shù)器(存在循環(huán)引用問題)2.可達(dá)性(GC Roots->局部變量表,static,final,native)
采用 標(biāo)記清理,復(fù)制,標(biāo)記整理
等方式進(jìn)行回收, 大對(duì)象/優(yōu)先eden/長(zhǎng)期存活/過(guò)半年齡/minor->old gc
搭配回收算法是:parNew + CMS(標(biāo)記整理)
禽捆、G1 + G1
9、Java是什么
10飘哨、API與SPI的區(qū)別
都是基于Interface接口
編程胚想,API
是調(diào)用接口,SPI
是實(shí)現(xiàn)接口
API
(接口位于實(shí)現(xiàn)方所在的包芽隆,實(shí)現(xiàn)包獨(dú)立)是提供給開發(fā)人員調(diào)用的接口來(lái)實(shí)現(xiàn)某個(gè)目的浊服,提供給程序開發(fā)人員
SPI
(接口位于調(diào)用方所在的包,實(shí)現(xiàn)包獨(dú)立 類似于Spring IoC的概念提供熱插拔)是提供框架規(guī)范胚吁,需要框架的開發(fā)人員去實(shí)現(xiàn)以達(dá)成某個(gè)目標(biāo)牙躺,提供給框架開發(fā)人員
SPI ->
概念上更依賴調(diào)用方。
組織上位于調(diào)用方所在的包中腕扶。
實(shí)現(xiàn)位于獨(dú)立的包中孽拷。
常見的例子是:插件模式的插件。
API ->
概念上更接近實(shí)現(xiàn)方半抱。
組織上位于實(shí)現(xiàn)方所在的包中脓恕。
實(shí)現(xiàn)和接口在一個(gè)包中。
11. dubbo如何一條鏈接并發(fā)多個(gè)以調(diào)用窿侈。Dubbo的原理炼幔,序列化相關(guān)問題
原理:
超時(shí)優(yōu)先級(jí)客戶端method>客戶端service>客戶端全局>服務(wù)端method>服務(wù)端service>服務(wù)端全局
存在一個(gè)configServer進(jìn)行provider/consumer注冊(cè)監(jiān)聽
,但是此服務(wù)down機(jī)不影響集群服務(wù)史简,每個(gè)provider/consumer都有本地緩存
注冊(cè)中心有multicast多播
江掩,zookeeper
,redis
負(fù)載均衡算法: roundrobin
乘瓤、random
环形、leastActivie
、constanthash
(一致性hash)使相同參數(shù)請(qǐng)求總是發(fā)到同一提供者
序列化:
- 使用的hessian方式進(jìn)行序列化衙傀,hessian的字節(jié)比serializable小抬吟,比protobuf大,但是支持多語(yǔ)言统抬,小服務(wù)體量適合使用
-
java 原生序列化的本質(zhì)是
ObjectStreamClass
中的writeNonProxy
方法. 會(huì)寫入整個(gè)對(duì)象的 name 和 SerialVersionUID(如果讀出的uid 和 內(nèi)存中的class uid不一致會(huì)報(bào)錯(cuò)), 并且寫下每個(gè)字段的type和name. 會(huì)加大序列化的存儲(chǔ)空間, 同時(shí)針對(duì) 嵌套對(duì)象也會(huì)重復(fù)存儲(chǔ).
通過(guò)重寫readClassDescriptor
和writeClassDescriptor
方法, 可以簡(jiǎn)單記錄元數(shù)據(jù). 起到壓縮作用. 參考CompactedObjectInputStream
類
協(xié)議:
dubbo
: 單連接火本,長(zhǎng)連接,TCP聪建,NIO(服務(wù)端線程復(fù)用)钙畔,hession序列化,適合小數(shù)據(jù)量大并發(fā)(由于使用單連接金麸,數(shù)據(jù)量大網(wǎng)絡(luò)會(huì)成為瓶頸)擎析,consumer要比producer多20倍才能壓滿千兆帶寬
rmi
:多連接,短連接挥下,TCP揍魂,BIO桨醋,Serializable,適合大文件傳輸现斋,consumer和producer差不多多
hessian/http
:多連接喜最,短連接,HTTP庄蹋,BIO瞬内,hession序列化/表單序列化,適合提供者比消費(fèi)者多
webservice
:多連接限书,短連接遂鹊,HTTP,BIO蔗包,SOAP文本序列化秉扑,適合x系統(tǒng)集成跨語(yǔ)言調(diào)用
memcached/redis
12、用過(guò)哪些中間件
rmq调限、redis舟陆、tair、zookeeper耻矮、memcached秦躯、eagle
13、做過(guò)工作流引擎沒有
// TODO
14裆装、以前的工作經(jīng)歷踱承,自己覺得出彩的地方(釘釘)
15、線程池的一些原理哨免,鎖的機(jī)制升降級(jí)(天貓茎活、螞蟻)
資源的池化技術(shù)是非常常見的一種使用空間緩存
緩解系統(tǒng)瞬時(shí)壓力
的解決方案(線程池、連接池琢唾、對(duì)象池)
線程池的作用是避免
頻繁地創(chuàng)建
和銷毀
線程载荔,達(dá)到線程對(duì)象的重用
繼承ThreadPoolExecutor來(lái)實(shí)現(xiàn)自定線程池,核心點(diǎn)有coreSize采桃、maxSize懒熙、BlockingQueue、ThreadFactory普办、RejectedHandler工扎、keepAliveTime
coreSize是線程池保持的最小線程數(shù)
當(dāng)超過(guò)coreSize進(jìn)入BlockingQueue
當(dāng)BlockingQueue滿了,創(chuàng)建線程到maxSize數(shù)量
超過(guò)maxSize執(zhí)行rejectedHandler解決異常
keepAliveTime在maxCoreSize超過(guò)多長(zhǎng)時(shí)間后衔蹲,銷毀
synchronized的內(nèi)置鎖肢娘,在JDK1.5后拆分了級(jí)別,將鎖級(jí)別
分為重量鎖,輕量鎖蔬浙,偏向鎖,還提供了自動(dòng)識(shí)別
鎖消除和鎖粗化的功能
鎖有升級(jí)的功能贞远,但是沒有降級(jí)的功能
16畴博、從系統(tǒng)層面考慮,分布式從哪些緯度考慮(天貓)
17蓝仲、Hadoop底層怎么實(shí)現(xiàn)(天貓)
18俱病、threadLocal,線程池袱结,hashMap/hashTable/coccurentHashMap等(天貓)
threadLocal
提供的隔離線程的副本值亮隙,每個(gè)線程內(nèi)置一個(gè)tableLocals[]
保存對(duì)應(yīng)的threadLocal值
hashMap
是非線程安全map,采用的是table數(shù)組+(鏈表+紅黑樹)
進(jìn)行存儲(chǔ)垢夹,其中每個(gè)獨(dú)立hash值
為一個(gè)鏈表
溢吻,先用hash值找到鏈表,再做val對(duì)比果元,擴(kuò)容方式用2進(jìn)制
存儲(chǔ)實(shí)現(xiàn)移位
擴(kuò)容促王,鏈表長(zhǎng)度超過(guò)8,轉(zhuǎn)為紅黑樹而晒,JDK1.8 -> 采用尾插法蝇狼,解決了擴(kuò)容死循環(huán)和倒序問題,hashcode只用了2次擾動(dòng)倡怎,不用每次都計(jì)算hashcode進(jìn)行定位迅耘,采用hashcode&oldCal來(lái)判斷是否需要移動(dòng)位置
concurrentHashMap
是線程安全map,不同點(diǎn)在于提供了TreeBin的讀寫鎖
监署,做讀取
時(shí)要加讀鎖
颤专,做變更
時(shí),針對(duì)鏈表頭
加寫鎖
钠乏,并且擴(kuò)容
時(shí)加入多線程輔助擴(kuò)容
機(jī)制血公,采用步長(zhǎng)
來(lái)減少
并發(fā)拷貝的沖突
hashTable
// TODO
19、秒殺系統(tǒng)的設(shè)計(jì)
加入認(rèn)證機(jī)制缓熟,減輕服務(wù)端負(fù)載累魔,也可以有熔斷
設(shè)置貢獻(xiàn)緩存和本地緩存
,每個(gè)服務(wù)器本地設(shè)置一個(gè)2倍的虛擬緩存够滑,再設(shè)置一個(gè)真實(shí)庫(kù)存的共享緩存
用戶請(qǐng)求先扣用戶機(jī)會(huì)垦写,然后扣減本地緩存,如果本地虛擬庫(kù)存不足彰触,直接拒絕梯投,如果有虛擬庫(kù)存,再競(jìng)爭(zhēng)貢獻(xiàn)緩存的庫(kù)存
20、虛擬機(jī)分蓖,IO相關(guān)知識(shí)點(diǎn)(天貓)
21尔艇、Linux的命令(天貓)
22、一個(gè)整形數(shù)組么鹤,給定一個(gè)數(shù)终娃,在數(shù)組中找出兩個(gè)數(shù)的和等于這個(gè)數(shù),并打印出來(lái)蒸甜,我寫的時(shí)間復(fù)雜度高棠耕,要求O(n)。(天貓)
快排能實(shí)現(xiàn)O(n)
23柠新、n個(gè)整數(shù)窍荧,找出連續(xù)的m個(gè)數(shù)加和是最大。(天貓)
// todo
24恨憎、更重視開源技術(shù)(螞蟻金服上海)
25蕊退、數(shù)據(jù)庫(kù)索引原理(螞蟻金服網(wǎng)商)
索引是采用b+樹來(lái)存儲(chǔ)
MySQL分為聚簇索引和非聚簇索引
所有的數(shù)據(jù)都存儲(chǔ)在聚簇索引的葉子節(jié)點(diǎn)上,聚簇索引以主鍵做有序的b+樹
非聚簇索引存儲(chǔ)的是索引的值憔恳,葉子節(jié)點(diǎn)保存的是聚簇索引的主鍵(因此走索引的查詢實(shí)際要查詢2次B+樹)
B+樹的好處是高度矮咕痛,能保存的值多(每個(gè)高度都是一次IO),比B-樹的好處是能存儲(chǔ)更多的數(shù)據(jù)
不支持間隔索引字段的查詢
26喇嘱、1000個(gè)線程同時(shí)運(yùn)行茉贡,怎么防止不卡(航旅)
加入線程池,減少同時(shí)運(yùn)行的線程者铜,如果是由于http服務(wù)器腔丧,選擇NIO可以降低線程數(shù)
27、并列的并發(fā)消費(fèi)問題(航旅)
28作烟、高并發(fā)量大的話怎么處理熱點(diǎn)愉粤,數(shù)據(jù)等(螞蟻金服)
散列數(shù)據(jù),這里要回憶下spark如何處理大數(shù)據(jù)時(shí)熱點(diǎn)問題
如果是業(yè)務(wù)上的拿撩,通過(guò)分庫(kù)分表解決
比如訂單衣厘,從業(yè)務(wù)上縱向拆分,然后進(jìn)行橫向擴(kuò)容压恒,比如影暴,按照用戶id的后4位中的前2位進(jìn)行分庫(kù),然后根據(jù)后2位進(jìn)行分表探赫,拿到用戶ID就能快速
29型宙、如何獲取一個(gè)本地服務(wù)器上可用的端口
30、流量控制相關(guān)問題(螞蟻金服)
-
計(jì)數(shù)器
(在段時(shí)間內(nèi)只允許計(jì)數(shù)器達(dá)到某個(gè)值通過(guò)伦吠,否則拒絕妆兑,段時(shí)間后魂拦,計(jì)數(shù)器清空)存在臨界點(diǎn)問題,比如在某個(gè)時(shí)間點(diǎn)(1s)內(nèi)爆發(fā)大量攻擊請(qǐng)求
滑動(dòng)窗口
-
漏桶
有一個(gè)固定的桶搁嗓,進(jìn)水的速率是不確定的芯勘,但是出水的速率是恒定的,當(dāng)水滿的時(shí)候是會(huì)溢出的(當(dāng)請(qǐng)求量大時(shí)腺逛,會(huì)有大部分請(qǐng)求被丟棄) -
令牌桶
生成令牌的速度是恒定的荷愕,而請(qǐng)求去拿令牌是沒有速度限制的(面對(duì)瞬時(shí)大流量,該算法可以在短時(shí)間內(nèi)請(qǐng)求拿到大量令牌屉来,而且拿令牌的過(guò)程并不是消耗很大的事情)
31路翻、數(shù)據(jù)庫(kù)TPS是多少狈癞,是否進(jìn)行測(cè)試過(guò)(天貓)
32茄靠、緩存擊穿有哪些方案解決(天貓)
- HTTP瀏覽器緩存
- CDN
-
服務(wù)器緩存(
本地緩存
、分布式緩存
)
在擊穿時(shí)蝶桶,線程保存舊緩存數(shù)據(jù)在本地慨绳,并且標(biāo)記有線程正在讀取數(shù)據(jù)庫(kù),其余請(qǐng)求擊穿時(shí)真竖,判斷是否線程正在請(qǐng)求脐雪,有則獲取舊緩存數(shù)據(jù)
1. 預(yù)估流量
2. 降級(jí)
3. 限流(token,請(qǐng)求隊(duì)列化恢共,計(jì)數(shù)器)
- 雪崩战秋,說(shuō)明服務(wù)器已經(jīng)出現(xiàn)問題,無(wú)法反饋讨韭,用戶反映往往是再刷一下脂信,加快服務(wù)器奔潰,需要采用斷路器透硝,快速失敗
- 隊(duì)列機(jī)制在處理時(shí)進(jìn)行判斷是否是無(wú)效值狰闪,如果已經(jīng)過(guò)期了,直接丟棄
33濒生、Java怎么挖取回收器相關(guān)原理(財(cái)富)
34埋泵、Java的集合都有哪些,都有什么特點(diǎn)(信息平臺(tái))
ArrayList 是數(shù)組集合罪治,支持隨機(jī)存取丽声,變更慢,讀取塊觉义,非線程安全
LinkedList 是鏈表集合恒序,支持順序存取,變更慢谁撼,讀取慢歧胁,非線程安全
BlockingQueue 是阻塞隊(duì)列滋饲,繼承自AQS架構(gòu),實(shí)現(xiàn)線程安全的消費(fèi)生產(chǎn)者
35喊巍、分布式鎖屠缭,redis緩存,spring aop崭参,系統(tǒng)架構(gòu)圖呵曹,MySQL的特性(信息平臺(tái))
36、場(chǎng)景何暮,同時(shí)給10萬(wàn)個(gè)人發(fā)工資奄喂,怎么樣設(shè)計(jì)并發(fā)方案,能確保在1分鐘內(nèi)全部發(fā)完 打個(gè)比方會(huì)提出類似的場(chǎng)景(信息平臺(tái))
1海洼、java事件機(jī)制包括哪三個(gè)部分跨新?分別介紹。
- 事件源
- 事件(
EventObject
) - 事件監(jiān)聽器(
EvenListener
)
- 事件隊(duì)列(event queue):接收事件的入口坏逢,存儲(chǔ)待處理事件
- 分發(fā)器(event mediator):將不同的事件分發(fā)到不同的業(yè)務(wù)邏輯單元
- 事件通道(event channel):分發(fā)器與處理器之間的聯(lián)系渠道
- 事件處理器(event processor):實(shí)現(xiàn)業(yè)務(wù)邏輯域帐,處理完成后會(huì)發(fā)出事件,觸發(fā)下一步操作
2是整、為什么要使用線程池肖揣?
每次請(qǐng)求都要不斷的創(chuàng)建和銷毀線程,一個(gè)線程的生命周期是
T1創(chuàng)建線程浮入,T2執(zhí)行線程龙优,T3銷毀線程
3、線程池有什么作用事秀?
如果T1+T3>T2
就可以使用線程池技術(shù)
池技術(shù)彤断,可以減少 創(chuàng)建/銷毀 線程的資源損耗,用空間換時(shí)間
避免無(wú)休止的創(chuàng)建線程秽晚,對(duì)線程數(shù)量進(jìn)行管理瓦糟,防止導(dǎo)致資源泄漏
4、說(shuō)說(shuō)幾種常見的線程池及使用場(chǎng)景
-
FixedThreadPool 固定線程池
重負(fù)載
的服務(wù)器赴蝇,合理使用資源菩浙,需要限制線程數(shù) -
SingleThreadPool 單例線程池
串行執(zhí)行任務(wù)
句伶,需要線程且方便使用 -
CachedThreadPool 無(wú)限制線程池 消費(fèi)者與生產(chǎn)者直接連接劲蜻,沒有緩存,沒有最大線程個(gè)數(shù)限制考余,適合
短期大量小任務(wù)先嬉,輕負(fù)載服務(wù)器
-
ScheduledThreadPool 定時(shí)調(diào)度線程池,提供按照速率/延遲執(zhí)行的調(diào)度執(zhí)行策略楚堤,適合執(zhí)行
多線程執(zhí)行周期性任務(wù)
web容器 每次用戶的請(qǐng)求都是一個(gè)獨(dú)立的無(wú)狀態(tài)的線程
疫蔓,而用戶體量遠(yuǎn)遠(yuǎn)大于服務(wù)器能創(chuàng)建的線程個(gè)數(shù)含懊,這時(shí)候就需要線程池來(lái)復(fù)用這些線程,縮短重復(fù)創(chuàng)建銷毀線程衅胀,同時(shí)限制線程創(chuàng)建的個(gè)數(shù)
消費(fèi)者 應(yīng)用動(dòng)的時(shí)候會(huì)啟動(dòng)固定的n個(gè)線程岔乔,來(lái)專門監(jiān)聽生產(chǎn)隊(duì)列
5、線程池都有哪幾種工作隊(duì)列滚躯?
- ArrayBlockingQueue -> 有限制隊(duì)列
- LinkedBlockingQueue -> 無(wú)限制隊(duì)列
- SynchronousQueue -> 連通隧道隊(duì)列
- DelayedWorkQueue -> 延遲工作隊(duì)列
- PriorityBlockingQueue -> 權(quán)限隊(duì)列
- ForwardBlockingQueue -> ???
6雏门、怎么理解無(wú)界隊(duì)列和有界隊(duì)列?
無(wú)界隊(duì)列是沒有設(shè)置隊(duì)列的大小掸掏,但實(shí)際上隊(duì)列還是有界的茁影,只是Integer.MAX_VALUE最大值上線,讀寫分成兩把lock丧凤,可以分開控制速率
有界隊(duì)列是設(shè)置了隊(duì)列的大小募闲,共享一把全局lock,size計(jì)算更精確
7息裸、線程池中的幾種重要的參數(shù)及流程說(shuō)明蝇更。
略
8沪编、什么是反射機(jī)制呼盆?
程序在運(yùn)行時(shí)能夠動(dòng)態(tài)的獲取自身的信息
通過(guò)指定類的全名,就可以動(dòng)態(tài)加載對(duì)象和查看所有方法和屬性
9蚁廓、說(shuō)說(shuō)反射機(jī)制的作用访圃。
- 增加程序的靈活性,避免將程序?qū)懰赖酱a里
- 可以運(yùn)行時(shí)獲取對(duì)象的所有屬性和方法相嵌,進(jìn)行代理和運(yùn)行時(shí)修改數(shù)據(jù)
- 開發(fā)各種通用框架
10腿时、反射機(jī)制會(huì)不會(huì)有性能問題?
對(duì)性能有影響
使用反射基本上是一種解釋操作
這類操作總是慢于只直接執(zhí)行(大概100倍)相同的操作
許多應(yīng)用中更嚴(yán)重的一個(gè)缺點(diǎn)
是使用反射會(huì)模糊程序內(nèi)部實(shí)際要發(fā)生的事情
解決方案:
1. 關(guān)閉校驗(yàn) .setAccessible(true);
2. 緩存反射出來(lái)的metadata至redis
3. 使用asm字節(jié)碼生成的方式實(shí)現(xiàn)了更為高效的反射機(jī)制饭宾,不依賴Java本身的反射機(jī)制
11批糟、你怎么理解http協(xié)議?
數(shù)據(jù)包在網(wǎng)絡(luò)中的傳輸
HTTP 是一個(gè)由請(qǐng)求和響應(yīng)組成的一種應(yīng)用層協(xié)議
12看铆、說(shuō)說(shuō)http協(xié)議的工作流程
13徽鼎、http有哪些請(qǐng)求提交方式?
14弹惦、http中的200,302,403,404,500,503都代表什么狀態(tài)否淤?
200 OK
302 重定向
403 服務(wù)器識(shí)別了并且主動(dòng)拒絕
404 沒有找到請(qǐng)求資源
500 服務(wù)器未知錯(cuò)誤
503 服務(wù)器當(dāng)前無(wú)法處理請(qǐng)求
15、http get和post有什么區(qū)別棠隐?
16石抡、你怎么理解cookie和session,有哪些不同點(diǎn)助泽?
17啰扛、什么是web緩存嚎京?有什么優(yōu)點(diǎn)?
18隐解、什么是https挖藏,說(shuō)說(shuō)https的工作原理?
19厢漩、什么是http代理服務(wù)器膜眠,有什么用?
20溜嗜、什么是虛擬主機(jī)及實(shí)現(xiàn)原理宵膨?
虛擬機(jī)是一種抽象化的計(jì)算機(jī),通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的
一臺(tái)服務(wù)器上可以提供多個(gè)虛擬主機(jī)炸宵,共享物理服務(wù)器的帶寬辟躏,cpu可以鎖定core,內(nèi)存可以固定劃分土全,存儲(chǔ)可以以目錄形式劃分
21捎琐、什么是Java虛擬機(jī),為什么要使用裹匙?
Java虛擬機(jī)有自己完善的硬體架構(gòu)瑞凑,如處理器、堆棧概页、寄存器(Java虛擬機(jī)沒有籽御、使用棧來(lái)存儲(chǔ))等,還具有相應(yīng)的指令系統(tǒng)惰匙。Java虛擬機(jī)屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息技掏,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行项鬼,實(shí)現(xiàn)跨平臺(tái)性
Java虛擬機(jī)規(guī)范定義了一個(gè)抽象的——而非實(shí)際的——機(jī)器或處理器哑梳。這個(gè)規(guī)范描述了一個(gè)指令集,一組寄存器绘盟,一個(gè)堆棧鸠真,一個(gè)“垃圾堆”,和一個(gè)方法區(qū)奥此。一旦一個(gè)Java虛擬機(jī)在給定的平臺(tái)上運(yùn)行弧哎,任何Java程序(編譯之后的程序,稱作字節(jié)碼)都能在這個(gè)平臺(tái)上運(yùn)行稚虎。Java虛擬機(jī)(JVM)可以以一次一條指令的方式來(lái)解釋字節(jié)碼(把它映射到實(shí)際的處理器指令)撤嫩,或者字節(jié)碼也可以由實(shí)際處理器中稱作just-in-time的編譯器進(jìn)行進(jìn)一步的編譯。
22蠢终、說(shuō)說(shuō)Java虛擬機(jī)的生命周期及體系結(jié)構(gòu)
執(zhí)行一個(gè)java程序序攘,就運(yùn)行一個(gè)Java虛擬機(jī)茴她。
通過(guò)一個(gè)main()函數(shù)開始 -> 運(yùn)行 -> 直到?jīng)]有普通線程運(yùn)行(非daemon
線程)終止程序
daemon線程 使用者之一是GC垃圾回收線程
體系結(jié)構(gòu):
- 通過(guò)
類加載系統(tǒng)
加載.class數(shù)據(jù) - 存儲(chǔ)到
運(yùn)行數(shù)據(jù)區(qū)
中 - 通過(guò)
執(zhí)行引擎
執(zhí)行裝載類中的指令
23、說(shuō)一說(shuō)Java內(nèi)存區(qū)域程奠。
運(yùn)行數(shù)據(jù)區(qū)
-> 內(nèi)存區(qū)域
獨(dú)享:
`程序計(jì)數(shù)器`丈牢、`虛擬方法棧`、`本地方法棧`
共享:
`堆`瞄沙、`方法區(qū)(常量池)`
24己沛、什么是分布式系統(tǒng)?
25距境、分布式系統(tǒng)你會(huì)考慮哪些方面申尼?
26、講一講TCP協(xié)議的三次握手和四次揮手流程
三次握手 雙方都能明確自己和對(duì)方的收垫桂、發(fā)能力是正常的
四次揮手
由于TCP連接是全雙工的师幕,因此每個(gè)方向都必須單獨(dú)進(jìn)行關(guān)閉
27、為什么TCP建立連接協(xié)議是三次握手诬滩,而關(guān)閉連接卻是四次握手呢霹粥?為什么不能用兩次握手進(jìn)行連接?
3次握手完成兩個(gè)重要的功能疼鸟,既要雙方做好發(fā)送數(shù)據(jù)的準(zhǔn)備工作
(雙方都知道彼此已準(zhǔn)備好)后控,也要允許雙方就初始序列號(hào)進(jìn)行協(xié)商
,這個(gè)序列號(hào)在握手過(guò)程中被發(fā)送和確認(rèn)
因?yàn)榉?wù)端的LISTEN狀態(tài)下的SOCKET當(dāng)收到SYN報(bào)文的連接請(qǐng)求后愚臀,它可以把ACK和SYN(ACK起應(yīng)答作用忆蚀,而SYN起同步作用)放在一個(gè)報(bào)文
里來(lái)發(fā)送矾利,通過(guò)序號(hào)(ISN)來(lái)按序組裝報(bào)文
關(guān)閉連接
時(shí)姑裂,當(dāng)收到對(duì)方的FIN報(bào)文通知時(shí),它僅僅表示對(duì)方?jīng)]有數(shù)據(jù)發(fā)送給你了男旗;但未必你所有的數(shù)據(jù)都全部發(fā)送給對(duì)方了舶斧,所以你可能未必會(huì)馬上會(huì)關(guān)閉SOCKET,也即你可能還需要發(fā)送一些數(shù)據(jù)給對(duì)方之后,再發(fā)送FIN報(bào)文給對(duì)方來(lái)表示你同意現(xiàn)在可以關(guān)閉連接了察皇,所以它這里的ACK報(bào)文和FIN報(bào)文多數(shù)情況下都是分開發(fā)送的茴厉。(服務(wù)端和客戶端都需要發(fā)送一次FIN
對(duì)應(yīng)的都要一次ACK
)
28、為什么TCP TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)什荣?
(MSL)是任何報(bào)文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長(zhǎng)時(shí)間矾缓,2MSL也就是這個(gè)時(shí)間的2倍
- 為了保證A發(fā)送的最有一個(gè)ACK報(bào)文段能夠到達(dá)B。這個(gè)ACK報(bào)文段有可能丟失稻爬,因而使處在LAST-ACK狀態(tài)的B收不到對(duì)已發(fā)送的FIN和ACK 報(bào)文段的確認(rèn)嗜闻。B會(huì)超時(shí)重傳這個(gè)FIN和ACK報(bào)文段,而A就能在2MSL時(shí)間內(nèi)收到這個(gè)重傳的ACK+FIN報(bào)文段桅锄。接著A重傳一次確認(rèn)琉雳。
- 就是防止上面提到的已失效的連接請(qǐng)求報(bào)文段出現(xiàn)在本連接中样眠,A在發(fā)送完最有一個(gè)ACK報(bào)文段后,再經(jīng)過(guò)2MSL翠肘,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失檐束。
TIME_WAIT狀態(tài)所帶來(lái)的影響:
--> 當(dāng)某個(gè)連接的一端處于TIME_WAIT狀態(tài)時(shí)稿壁,該連接將不能再被使用窒所。事實(shí)上鸥印,對(duì)于我們比較有現(xiàn)實(shí)意義的是醇份,這個(gè)端口將不能再被使用尼变。某個(gè)端口處于TIME_WAIT狀態(tài)(其實(shí)應(yīng)該是這個(gè)連接)時(shí)喇辽,這意味著這個(gè)TCP連接并沒有斷開(完全斷開)蜘犁,那么扔字,如果你bind這個(gè)端口喂急,就會(huì)失敗格嘁。對(duì)于服務(wù)器而言,如果服務(wù)器突然crash掉了廊移,那么它將無(wú)法再2MSL內(nèi)重新啟動(dòng)糕簿,因?yàn)?strong>bind會(huì)失敗。解決這個(gè)問題的一個(gè)方法就是設(shè)置socket的SO_REUSEADDR選項(xiàng)狡孔。這個(gè)選項(xiàng)意味著你可以重用一個(gè)地址懂诗,當(dāng)設(shè)置了SO_REUSEADDR選項(xiàng)時(shí),它可以在2MSL內(nèi)啟動(dòng)并listen成功
29苗膝、什么是DoS殃恒、DDoS、DRDoS攻擊辱揭?如何防御离唐?
30、描述一下Java異常層次結(jié)構(gòu)问窃。
31亥鬓、什么是檢查異常,不受檢查異常域庇,運(yùn)行時(shí)異常嵌戈?并分別舉例說(shuō)明。
32听皿、finally塊一定會(huì)執(zhí)行嗎熟呛?
- 在 try {} finally{} 之前return了,不會(huì)執(zhí)行
- 在try {} finally{} 之間執(zhí)行了System.exit(0); 不會(huì)執(zhí)行
- return i;后 finally {i++;} 不會(huì)改變返回的值尉姨,因?yàn)閞eturn 會(huì)拷貝一份副本作為返回值
33庵朝、正常情況下,當(dāng)在try塊或catch塊中遇到return語(yǔ)句時(shí),finally語(yǔ)句塊在方法返回之前還是之后被執(zhí)行偿短?
34欣孤、try、catch昔逗、finally語(yǔ)句塊的執(zhí)行順序降传。
try -> catch -> finally -> return
35、Java虛擬機(jī)中勾怒,數(shù)據(jù)類型可以分為哪幾類婆排?
-
原始類型
1.1 數(shù)值型 - int/float/double/long/char/byte/short
1.2 布爾型 - boolean
1.3 returnAddress -
引用類型
reference
36、怎么理解棧笔链、堆段只?堆中存什么?棧中存什么鉴扫?
-
棧
內(nèi)存存儲(chǔ)的是局部變量赞枕,而堆
內(nèi)存存儲(chǔ)的是實(shí)體 -
棧
內(nèi)存的更新速度要快于堆
內(nèi)存,因?yàn)榫植孔兞康纳芷诤芏?/li> -
棧
內(nèi)存存放的變量生命周期一旦結(jié)束就立即
會(huì)被釋放坪创,而堆
內(nèi)存存放的實(shí)體會(huì)被垃圾回收機(jī)制不定時(shí)
的回收
37炕婶、為什么要把堆和棧區(qū)分出來(lái)呢?棧中不是也可以存儲(chǔ)數(shù)據(jù)嗎莱预?
問題很棒~
棧是運(yùn)行時(shí)的單位柠掂,而堆是存儲(chǔ)的單位。
- 棧解決程序的運(yùn)行問題依沮,即程序如何執(zhí)行涯贞,或者說(shuō)如何處理數(shù)據(jù)
- 堆解決的是數(shù)據(jù)存儲(chǔ)的問題,即數(shù)據(jù)怎么放危喉、放在哪兒宋渔。
在Java中一個(gè)線程就會(huì)相應(yīng)有一個(gè)線程棧與之對(duì)應(yīng),因?yàn)椴煌木€程執(zhí)行邏輯有所不同姥饰,因此需要一個(gè)獨(dú)立的線程棧
堆則是所有線程共享的
棧因?yàn)槭沁\(yùn)行單位傻谁,因此里面存儲(chǔ)的信息都是跟當(dāng)前線程(或程序)相關(guān)信息的
- 包括局部變量、程序運(yùn)行狀態(tài)列粪、方法返回值等等
堆只負(fù)責(zé)存儲(chǔ)對(duì)象信息。
-
軟件設(shè)計(jì)
角度谈飒,棧
代表了處理邏輯
岂座,堆
代表了數(shù)據(jù)存儲(chǔ)
- 堆中的內(nèi)容可以被多個(gè)棧
共享
。一方面提供了一種有效的數(shù)據(jù)交互方式(如內(nèi)存共享)杭措,另一方面费什,節(jié)省內(nèi)存空間 - 棧因?yàn)檫\(yùn)行時(shí)的需要(如保存系統(tǒng)運(yùn)行的上下文),需要進(jìn)行址段的劃分手素。由于棧只能向上增長(zhǎng)鸳址,因此會(huì)限制住棧存儲(chǔ)內(nèi)容的能力瘩蚪。而堆不同,堆中的對(duì)象可以根據(jù)需要動(dòng)態(tài)增長(zhǎng)稿黍。因此疹瘦,堆與棧的分離,使得動(dòng)態(tài)增長(zhǎng)成為可能巡球,相應(yīng)棧中只需要記錄堆中的一個(gè)地址即可言沐。
- 堆和棧的完美結(jié)合就是面向?qū)ο蟮囊粋€(gè)實(shí)例
38、在Java中酣栈,什么是是棧的起始點(diǎn)险胰,同是也是程序的起始點(diǎn)?
main函數(shù)就是棧的起始點(diǎn)矿筝,也是程序的起始點(diǎn)
39起便、為什么不把基本類型放堆中呢?
占用的空間一般是1~8個(gè)字節(jié)——需要空間比較少窖维,而且因?yàn)槭腔绢愋陀圆粫?huì)出現(xiàn)動(dòng)態(tài)增長(zhǎng)的情況——長(zhǎng)度固定,因此棧中存儲(chǔ)就夠了陈辱,如果把他存在堆中是沒有什么意義的(還會(huì)浪費(fèi)空間奖年,后面說(shuō)明)∨嫣埃可以這么說(shuō)陋守,基本類型和對(duì)象的引用都是存放在棧中,而且都是幾個(gè)字節(jié)的一個(gè)數(shù)利赋,因此在程序運(yùn)行時(shí)水评,他們的處理方式是統(tǒng)一的。但是基本類型媚送、對(duì)象引用和對(duì)象本身就有所區(qū)別了中燥,因?yàn)橐粋€(gè)是棧中的數(shù)據(jù)一個(gè)是堆中的數(shù)據(jù)。最常見的一個(gè)問題就是塘偎,Java中參數(shù)傳遞時(shí)的問題疗涉。
40、Java中的參數(shù)傳遞是傳值呢吟秩?還是傳引用咱扣?
要說(shuō)明這個(gè)問題,先要明確兩點(diǎn):
1. 不要試圖與C進(jìn)行類比涵防,Java中沒有指針的概念
2. 程序運(yùn)行永遠(yuǎn)都是在棧中進(jìn)行的闹伪,因而參數(shù)傳遞時(shí),只存在傳遞基本類型和對(duì)象引用的問題。不會(huì)直接傳對(duì)象本身偏瓤。
明確以上兩點(diǎn)后杀怠。Java在方法調(diào)用傳遞參數(shù)時(shí),因?yàn)闆]有指針厅克,所以它都是進(jìn)行傳值調(diào)用(這點(diǎn)可以參考C的傳值調(diào)用)赔退。因此,很多書里面都說(shuō)Java是進(jìn)行傳值調(diào)用已骇,這點(diǎn)沒有問題离钝,而且也簡(jiǎn)化的C中復(fù)雜性。
但是傳引用的錯(cuò)覺是如何造成的呢褪储?在運(yùn)行棧中卵渴,基本類型和引用的處理是一樣的,都是傳值鲤竹,所以浪读,如果是傳引用的方法調(diào)用,也同時(shí)可以理解為“傳引用值”的傳值調(diào)用辛藻,即引用的處理跟基本類型是完全一樣的碘橘。但是當(dāng)進(jìn)入被調(diào)用方法時(shí),被傳遞的這個(gè)引用的值吱肌,被程序解釋(或者查找)到堆中的對(duì)象痘拆,這個(gè)時(shí)候才對(duì)應(yīng)到真正的對(duì)象。如果此時(shí)進(jìn)行修改氮墨,修改的是引用對(duì)應(yīng)的對(duì)象纺蛆,而不是引用本身,即:修改的是堆中的數(shù)據(jù)规揪。所以這個(gè)修改是可以保持的了桥氏。
對(duì)象,從某種意義上說(shuō)猛铅,是由基本類型組成的字支。可以把一個(gè)對(duì)象看作為一棵樹奸忽,對(duì)象的屬性如果還是對(duì)象堕伪,則還是一顆樹(即非葉子節(jié)點(diǎn)),基本類型則為樹的葉子節(jié)點(diǎn)月杉。程序參數(shù)傳遞時(shí)刃跛,被傳遞的值本身都是不能進(jìn)行修改的,但是苛萎,如果這個(gè)值是一個(gè)非葉子節(jié)點(diǎn)(即一個(gè)對(duì)象引用),則可以修改這個(gè)節(jié)點(diǎn)下面的所有內(nèi)容。
堆和棧中腌歉,棧是程序運(yùn)行最根本的東西蛙酪。程序運(yùn)行可以沒有堆,但是不能沒有棧翘盖。而堆是為棧進(jìn)行數(shù)據(jù)存儲(chǔ)服務(wù)桂塞,說(shuō)白了堆就是一塊共享的內(nèi)存。不過(guò)馍驯,正是因?yàn)槎押蜅5姆蛛x的思想阁危,才使得Java的垃圾回收成為可能。
Java中汰瘫,棧的大小通過(guò)-Xss來(lái)設(shè)置狂打,當(dāng)棧中存儲(chǔ)數(shù)據(jù)比較多時(shí),需要適當(dāng)調(diào)大這個(gè)值混弥,否則會(huì)出現(xiàn)java.lang.StackOverflowError異常趴乡。常見的出現(xiàn)這個(gè)異常的是無(wú)法返回的遞歸,因?yàn)榇藭r(shí)棧中保存的信息都是方法返回的記錄點(diǎn)蝗拿。
41晾捏、Java中有沒有指針的概念?
java中沒有指針的概念哀托,reference引用就是指針的概念
42惦辛、Java中,棧的大小通過(guò)什么參數(shù)來(lái)設(shè)置仓手?
43胖齐、一個(gè)空Object對(duì)象的占多大空間?
44俗或、對(duì)象引用類型分為哪幾類市怎?
45、講一講垃圾回收算法
通過(guò)可達(dá)性分析
算法辛慰,從GcRoots
標(biāo)記所有存活的對(duì)象
標(biāo)記-清除算法区匠,清除其余未存活對(duì)象
復(fù)制算法 ,將存儲(chǔ)空間分為2分帅腌,存儲(chǔ)對(duì)象只是用其中一份驰弄,在做垃圾回收的時(shí)候,將存活的對(duì)象拷貝到另外一份
標(biāo)記-整理算法速客,清除其余未存活對(duì)象戚篙,整理存活的對(duì)象到存儲(chǔ)空間頭/尾
分代 使用了復(fù)制算法,但是沒有浪費(fèi)一半內(nèi)存溺职,而是每代都有存活的對(duì)象岔擂,根據(jù)eden/s1/s2/old再使用不同的算法進(jìn)行處理
46位喂、如何解決內(nèi)存碎片的問題?
- 使用整理技術(shù)乱灵,每次回收完垃圾后塑崖,進(jìn)行一次整理
- 使用分代技術(shù),每次垃圾回收完痛倚,把存活的對(duì)象拷貝到下一級(jí)存儲(chǔ)空間规婆,然后清除這一級(jí)的空間
47、如何解決同時(shí)存在的對(duì)象創(chuàng)建和對(duì)象回收問題蝉稳?
48抒蚜、講一講內(nèi)存分代及生命周期。
內(nèi)存分為4代
耘戚,比例是8:1:1
eden: 絕大多數(shù)對(duì)象都在這里消亡嗡髓,頻繁的miniotr gc
s1:
s2:
old: full gc會(huì)導(dǎo)致STW
49、什么情況下觸發(fā)垃圾回收毕莱?
每次切換區(qū)的時(shí)候器贩,都會(huì)執(zhí)行一次minor gc
- 如果有限次minor gc還沒有回收此對(duì)象,進(jìn)入s1朋截,進(jìn)入s2蛹稍,進(jìn)入old,old會(huì)觸發(fā)full gc(每次gc都會(huì)增加一次對(duì)象的年齡作為計(jì)數(shù)器)
- 如果存在連續(xù)內(nèi)存的大對(duì)象部服,會(huì)直接進(jìn)入old區(qū)唆姐,以免無(wú)意義的重復(fù)拷貝
- 如果s區(qū)內(nèi)有一半以上對(duì)象存活時(shí)間相等,進(jìn)入old區(qū)
- s區(qū)往old區(qū)遷移的時(shí)候會(huì)判斷是否空間足夠廓八,否則會(huì)full gc(還有一個(gè)冗余位設(shè)置奉芦,如果設(shè)置為true還有30%的空間,再判斷后是否full gc)
50剧蹂、如何選擇合適的垃圾收集算法声功?
ParNew(young) + CMS(old)
G1(young) + G1(old)
年輕代需要快速回收,且空間足夠大宠叼,不能有大量碎片先巴,ParNew采用復(fù)制算法
老年代都是大對(duì)象長(zhǎng)期存活的,適用CMS采用標(biāo)記-清理算法冒冬,但是可能由于沒有連續(xù)空間導(dǎo)致頻繁full gc伸蚯,可以在有限次gc后執(zhí)行一次標(biāo)記-整理
51、JVM中最大堆大小有沒有限制简烤?
52剂邮、堆大小通過(guò)什么參數(shù)設(shè)置?
53横侦、JVM有哪三種垃圾回收器挥萌?
54绰姻、吞吐量?jī)?yōu)先選擇什么垃圾回收器?響應(yīng)時(shí)間優(yōu)先呢瑞眼?
55龙宏、如何進(jìn)行JVM調(diào)優(yōu)棵逊?有哪些方法伤疙?
56、如何理解內(nèi)存泄漏問題辆影?有哪些情況會(huì)導(dǎo)致內(nèi)存泄露徒像?如何解決?
57蛙讥、從分布式系統(tǒng)部署角度考慮锯蛀,分哪幾層?
58次慢、如何解決業(yè)務(wù)層的數(shù)據(jù)訪問問題旁涤?
59、為了解決數(shù)據(jù)庫(kù)服務(wù)器的負(fù)擔(dān)迫像,如何做數(shù)據(jù)庫(kù)的分布劈愚?
60、什么是著名的拜占庭將軍問題闻妓?
61菌羽、為什么說(shuō)TCP/IP協(xié)議是不可靠的?
62由缆、講講CAP理念
Consistent(一致性)
Available(可用性)
Partition tolerance(分布性容忍性)
P是必須保證的注祖,C和A選其一
選C的強(qiáng)一致性可用性很低互聯(lián)網(wǎng)公司不能接受
一般會(huì)選A,然后實(shí)現(xiàn)最終一致性
這時(shí)候引入BASE
[基本可用均唉,阮狀態(tài)是晨,最終一致性]
63、怎么理解強(qiáng)一致性舔箭、單調(diào)一致性和最終一致性罩缴?
強(qiáng)一致性:更新過(guò)的數(shù)據(jù)能被后續(xù)的訪問都能看到
弱一致性:能容忍后續(xù)的部分或者全部訪問不到
順序一致性:任何一次讀都能讀到某個(gè)數(shù)據(jù)的最近一次寫的數(shù)據(jù),系統(tǒng)的所有進(jìn)程的順序一致
最終一致性:經(jīng)過(guò)一段時(shí)間后要求能訪問到更新后的數(shù)據(jù)
64限嫌、分布式系統(tǒng)設(shè)計(jì)你會(huì)考慮哪些策略靴庆?
65、最常見的數(shù)據(jù)分布方式是什么怒医?
66炉抒、談一談一致性哈希算法。
67稚叹、paxos是什么焰薄?
68拿诸、什么是Lease機(jī)制?
69塞茅、如何理解選主算法亩码?
70、OSI有哪七層模型野瘦?TCP/IP是哪四層模型
OSI七層
應(yīng)用層->表示層->會(huì)話層->傳輸層->網(wǎng)絡(luò)層->數(shù)據(jù)鏈路層->物理層
TCP/IP四層
應(yīng)用層->傳輸(TCP)層->網(wǎng)絡(luò)(IP)層->物理鏈路層
1. spring/spring-bean 生命周期
spring只對(duì)singleton單例對(duì)象管理生命周期
spring實(shí)例化方式:setter描沟,constructor,factory
scope:singleton鞭光,prototype吏廉,request,session惰许,global-session
spring生命周期:define席覆,init-method,invoke汹买,destroy-method
spring-bean生命周期:
1. 實(shí)例化 2. 填充屬性(DI) 3. 設(shè)置bean name
4. 設(shè)置 beanFactory/applicationContext
5. init-method 前/后置 BeanPostProcessor-before/after
6. bean初始化完成
7. DisposableBean-destroy
8. destroy
只有無(wú)狀態(tài)的Bean才可以在多線程環(huán)境下共享佩伤,在Spring中,絕大部分Bean都可以聲明為singleton作用域晦毙。就是因?yàn)镾pring對(duì)一些Bean(如RequestContextHolder生巡、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全狀態(tài)采用ThreadLocal進(jìn)行處理结序,讓它們也成為線程安全的狀態(tài)障斋,因?yàn)橛袪顟B(tài)的Bean就可以在多線程中共享了
2. spring aop/ioc/di
IoC控制反轉(zhuǎn)是一種框架的概念
DI依賴注入是具體的實(shí)現(xiàn)
AOP彌補(bǔ)了面向?qū)ο缶幊蹋∣OP)的不足,通過(guò)Aspect切面的方式徐鹤,JoinPoint連接點(diǎn)和Advise通知(around
/before/afterReturn/afterThrow/afterFinally)來(lái)進(jìn)行Weaving織入垃环,Spring通過(guò)動(dòng)態(tài)代理(jdkProxy,gclib)將代理對(duì)象加強(qiáng)
BeanFactory:采取延遲加載
返敬,第一次getBean時(shí)才會(huì)初始化Bean
ApplicationContext:加載配置文件時(shí)初始化Bean遂庄,可以進(jìn)行國(guó)際化處理、事件傳遞和bean自動(dòng)裝配以及各種不同應(yīng)用層的Context實(shí)現(xiàn)
3. 一致性hash
一致性哈希將整個(gè)哈希值空間組織成一個(gè)虛擬的圓環(huán)劲赠,如假設(shè)某哈希函數(shù)H的值空間為0-2^32-1
4. hibernate 緩存
事務(wù)進(jìn)行控制
一級(jí)緩存(session):
隨著session.close釋放
持久化對(duì)象有三個(gè)狀態(tài)(瞬時(shí)態(tài)[無(wú)OID]
涛目、持久態(tài)[有OID有session]
、托管態(tài)[有OID無(wú)session]
)
Map<緩存
凛澎,快照
>
flush時(shí)會(huì)對(duì)比緩存
和快照
是否一致霹肝,不一致會(huì)提交更新
FlushMode.ALWAYS
AUTO(默認(rèn))
COMMIT
MANUAL
NEVER
二級(jí)緩存(sessionFactory)
5. 索引原理
INNODB UPDATE的原理,行級(jí)鎖的前提條件是建立索引塑煎,行級(jí)鎖并不是直接鎖記錄沫换,而是鎖索引后再鎖主鍵
聚集索引葉子節(jié)點(diǎn)
存放的是行數(shù)據(jù)本身
非聚集索引葉子節(jié)點(diǎn)
存放的是聚集索引的值
非聚集索引的查找[通常情況下]至少要經(jīng)過(guò)兩次B+樹的遍歷
6. MVCC
沒有意向鎖:做法是遍歷表A的所有行級(jí)鎖,看是否有X鎖最铁。
有意向鎖:做法判斷一下表A(意向鎖是表鎖)是否有IX就可以了讯赏。就可以判斷表A此時(shí)有沒有在寫的事務(wù)
MVCC (Multiversion Concurrency Control)垮兑,對(duì)數(shù)據(jù)庫(kù)的任何修改的提交都不會(huì)直接覆蓋之前的數(shù)據(jù),而是產(chǎn)生一個(gè)新的版本與老版本共存(快照)漱挎,使得讀取時(shí)可以完全不加鎖系枪。不再單純的使用行鎖來(lái)進(jìn)行數(shù)據(jù)庫(kù)的并發(fā)控制,取而代之的是把數(shù)據(jù)庫(kù)的行鎖與行的多個(gè)版本結(jié)合起來(lái)磕谅,只需要很小的開銷,就可以實(shí)現(xiàn)非鎖定讀私爷,從而大大提高數(shù)據(jù)庫(kù)系統(tǒng)的并發(fā)性能
InnoDB的MVCC,是通過(guò)在每行記錄后面保存兩個(gè)隱藏的列來(lái)實(shí)現(xiàn)的,這兩個(gè)列,分別保存了這個(gè)行的創(chuàng)建時(shí)間怜庸,一個(gè)保存的是行的刪除時(shí)間当犯。這里存儲(chǔ)的并不是實(shí)際的時(shí)間值,而是系統(tǒng)版本號(hào)(可以理解為事務(wù)的ID),沒開始一個(gè)新的事務(wù)割疾,系統(tǒng)版本號(hào)就會(huì)自動(dòng)遞增,事務(wù)開始時(shí)刻的系統(tǒng)版本號(hào)會(huì)作為事務(wù)的ID
7. NIO/IO
NIO
非
阻塞嘉栓、面向緩沖區(qū)
宏榕、有選擇器
線程通常將非阻塞IO的空閑時(shí)間用于在其它通道上執(zhí)行IO操作,所以一個(gè)單獨(dú)的線程(選擇器)
現(xiàn)在可以管理多個(gè)輸入和輸出通道(channel)
NIO可讓您只使用一個(gè)(或幾個(gè))單線程管理多個(gè)通道(網(wǎng)絡(luò)連接或文件)侵佃,但付出的代價(jià)是解析數(shù)據(jù)可能會(huì)比從一個(gè)阻塞流中讀取數(shù)據(jù)更復(fù)雜
優(yōu)勢(shì):大量連接麻昼,發(fā)送數(shù)據(jù)小
IO
阻塞、面向流
優(yōu)勢(shì):少量連接馋辈,發(fā)送數(shù)據(jù)大
8. JPA(hibernate)/MyBatis
JPA(hibernate):
使用注解@EnableJpaRepositories
指定EntityManager
和PlatformTransactionManager
以及scan的目錄范圍
支持Criteria
MyBatis:
使用mybatis-spring融合spring抚芦,@Bean初始化SqlSessionFactoryBean
對(duì)象,指定DataSource
迈螟,mapper.xml地址
叉抡,mybatis-config.xml
以及aliasesPackage
,在config里面可以配置插件答毫,比如PageableHelper
來(lái)簡(jiǎn)化分頁(yè)查詢
一級(jí)緩存:
Mybatis首先去緩存中查詢結(jié)果集褥民,如果沒有則查詢數(shù)據(jù)庫(kù),如果有則從緩存取出返回結(jié)果集就不走數(shù)據(jù)庫(kù)洗搂。Mybatis內(nèi)部存儲(chǔ)緩存使用一個(gè)HashMap消返,key為hashCode+sqlId+Sql語(yǔ)句。value為從查詢出來(lái)映射生成的java對(duì)象
二級(jí)緩存:
Mybatis的二級(jí)緩存即查詢緩存耘拇,它的作用域是一個(gè)mapper的namespace撵颊,即在同一個(gè)namespace
中查詢sql可以從緩存中獲取數(shù)據(jù)。二級(jí)緩存是可以跨SqlSession的
9. 事務(wù)
編程式:
重復(fù)代碼多
聲明式:
靈活
10. 擴(kuò)容
StringBuffer惫叛,默認(rèn)16倡勇,每次擴(kuò)容一倍(如果一倍還不夠直接擴(kuò)容到目標(biāo)大小)
HashMap挣棕,默認(rèn)2^4=16译隘,默認(rèn)負(fù)載因子0.75亲桥,當(dāng)容量達(dá)到四分之三進(jìn)行再散列(擴(kuò)容),擴(kuò)容一倍
ArrayList固耘,首先容量擴(kuò)大為原來(lái)的1.5倍题篷,判斷是否足夠,不夠擴(kuò)大為需要的大小厅目,再判斷是否超過(guò)上限(使用Integer.MAX_VALUE)
Vector番枚,每次擴(kuò)容是翻倍
11. dubbo/webservice
自帶負(fù)載均衡,服務(wù)治理
客戶端超時(shí)>服務(wù)端超時(shí)
客戶端重試>服務(wù)端重試
12. tair/redis
redis:
使用一致性hash解決擴(kuò)容和定位問題
支持存儲(chǔ)大/小對(duì)象
支持多集群损敷,但是讀寫分離
支持分組并發(fā)更新
tair:
使用一致性hash解決擴(kuò)容和定位問題
支持小對(duì)象
支持多集群
不支持分組并發(fā)更新
13. QPS/RT/threadNum
RT: 響應(yīng)時(shí)間(單位ms
)
QPS(最大吞吐能力): 每秒請(qǐng)求量(單位是s
)
ThreadNum: 并發(fā)數(shù)(并發(fā)數(shù)就是線程數(shù))
PV:訪問量即Page View, 即頁(yè)面瀏覽量或點(diǎn)擊量葫笼,用戶每次刷新即被計(jì)算一次(單臺(tái)服務(wù)器每天PV計(jì)算公式1:每天總PV = QPS * 3600 * 6)
UV:獨(dú)立訪客即Unique Visitor,訪問您網(wǎng)站的一臺(tái)電腦客戶端為一個(gè)訪客。00:00-24:00內(nèi)相同的客戶端只被計(jì)算一次
QPS = 并發(fā)數(shù) / 平均響應(yīng)時(shí)間
QPS = threadNum / RT
請(qǐng)求耗時(shí) = 用戶請(qǐng)求數(shù)(requests) / QPS
公式:( 總PV數(shù) * 80% ) / ( 每天秒數(shù) * 20% ) = 峰值時(shí)間每秒請(qǐng)求數(shù)(QPS)
每天300w PV 的在單臺(tái)機(jī)器上拗馒,這臺(tái)機(jī)器需要多少Q(mào)PS路星?
答:( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)
如果一臺(tái)機(jī)器的QPS是58,需要幾臺(tái)機(jī)器來(lái)支持诱桂?
答:139 / 58 = 3