2017JAVA面試題附答案
宣告,本人能力有限,只是列出來參考,不對之處歡迎指正。
本人沒有什麼公眾號,評論裡面有人冒充我,大家注意甄別
JAVA基礎
JAVA中的幾種基本型別,各佔用多少位元組?
下圖單位是bit,非位元組 1B=8bit
String能被繼承嗎?為什麼?
不可以,因為String類有final修飾符,而final修飾的類是不能被繼承的,實現細節不允許改變。平常我們定義的String str=”a”;其實和String str=new String(“a”)還是有差異的。
前者預設呼叫的是String.valueOf來返回String例項物件,至於呼叫哪個則取決於你的賦值,比如String num=1,呼叫的是
public static String valueOf(int i) {
return Integer.toString(i);
}
後者則是呼叫如下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最後我們的變數都儲存在一個char陣列中
private final char value[];
##String, Stringbuffer, StringBuilder 的區別。
String 字串常量(final修飾,不可被繼承),String是常量,當建立之後即不能更改。(可以通過StringBuffer和StringBuilder建立String物件(常用的兩個字串操作類)。)
StringBuffer 字串變數(執行緒安全),其也是final類別的,不允許被繼承,其中的絕大多數方法都進行了同步處理,包括常用的Append方法也做了同步處理(synchronized修飾)。其自jdk1.0起就已經出現。其toString方法會進行物件快取,以減少元素複製開銷。
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder 字串變數(非執行緒安全)其自jdk1.5起開始出現。與StringBuffer一樣都繼承和實現了同樣的介面和類,方法除了沒使用synch修飾以外基本一致,不同之處在於最後toString的時候,會直接返回一個新物件。
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}
ArrayList 和 LinkedList 有什麼區別。
ArrayList和LinkedList都實現了List介面,有以下的不同點:
1、ArrayList是基於索引的資料介面,它的底層是陣列。它可以以O(1)時間複雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式儲存它的資料,每一個元素都和它的前一個和後一個元素連結在一起,在這種情況下,查詢某個元素的時間複雜度是O(n)。
2、相對於ArrayList,LinkedList的插入,新增,刪除操作速度更快,因為當元素被新增到集合任意位置的時候,不需要像陣列那樣重新計算大小或者是更新索引。
3、LinkedList比ArrayList更佔記憶體,因為LinkedList為每一個節點儲存了兩個引用,一個指向前一個元素,一個指向下一個元素。
講講類的例項化順序,比如父類靜態資料,建構函式,欄位,子類靜態資料,建構函式,欄位,當 new 的時候, 他們的執行順序。
此題考察的是類載入器例項化時進行的操作步驟(載入–>連線->初始化)。
父類靜態代變數、
父類靜態程式碼塊、
子類靜態變數、
子類靜態程式碼塊、
父類非靜態變數(父類例項成員變數)、
父類建構函式、
子類非靜態變數(子類例項成員變數)、
子類建構函式。
測試demo:http://blog.csdn.net/u014042066/article/details/77574956
參閱我的部落格《深入理解類載入》:http://blog.csdn.net/u014042066/article/details/77394480
用過哪些 Map 類,都有什麼區別,HashMap 是執行緒安全的嗎,併發下使用的 Map 是什麼,他們內部原理分別是什麼,比如儲存方式, hashcode,擴容, 預設容量等。
hashMap是執行緒不安全的,HashMap是陣列+連結串列+紅黑樹(JDK1.8增加了紅黑樹部分)實現的,採用雜湊表來儲存的,
參照該連結:https://zhuanlan.zhihu.com/p/21673805
JAVA8 的 ConcurrentHashMap 為什麼放棄了分段鎖,有什麼問題嗎,如果你來設計,你如何設計。
參照:https://yq.aliyun.com/articles/36781
有沒有有順序的 Map 實現類, 如果有, 他們是怎麼保證有序的。
TreeMap和LinkedHashMap是有序的(TreeMap預設升序,LinkedHashMap則記錄了插入順序)。
參照:http://uule.iteye.com/blog/1522291
抽象類和介面的區別,類可以繼承多個類麼,介面可以繼承多個介面麼,類可以實現多個介面麼。
1、抽象類和介面都不能直接例項化,如果要例項化,抽象類變數必須指向實現所有抽象方法的子類物件,介面變數必須指向實現所有介面方法的類物件。
2、抽象類要被子類繼承,介面要被類實現。
3、介面只能做方法申明,抽象類中可以做方法申明,也可以做方法實現
4、介面裡定義的變數只能是公共的靜態的常量,抽象類中的變數是普通變數。
5、抽象類裡的抽象方法必須全部被子類所實現,如果子類不能全部實現父類抽象方法,那麼該子類只能是抽象類。同樣,一個實現介面的時候,如不能全部實現介面方法,那麼該類也只能為抽象類。
6、抽象方法只能申明,不能實現。abstract void abc();不能寫成abstract void abc(){}。
7、抽象類裡可以沒有抽象方法
8、如果一個類裡有抽象方法,那麼這個類只能是抽象類
9、抽象方法要被實現,所以不能是靜態的,也不能是私有的。
10、介面可繼承介面,並可多繼承介面,但類只能單根繼承。
繼承和聚合的區別在哪。
繼承指的是一個類(稱為子類、子介面)繼承另外的一個類(稱為父類、父介面)的功能,並可以增加它自己的新功能的能力,繼承是類與類或者介面與介面之間最常見的關係;在Java中此類關係通過關鍵字extends明確標識,在設計時一般沒有爭議性;
聚合是關聯關係的一種特例,他體現的是整體與部分、擁有的關係,即has-a的關係,此時整體與部分之間是可分離的,他們可以具有各自的生命週期,部分可以屬於多個整體物件,也可以為多個整體物件共享;比如計算機與CPU、公司與員工的關係等;表現在程式碼層面,和關聯關係是一致的,只能從語義級別來區分;
參考:http://www.cnblogs.com/jiqing9006/p/5915023.html
講講你理解的 nio和 bio 的區別是啥,談談 reactor 模型。
IO是面向流的,NIO是面向緩衝區的
參考:https://zhuanlan.zhihu.com/p/23488863
http://developer.51cto.com/art/201103/252367.htm
http://www.jianshu.com/p/3f703d3d804c
反射的原理,反射建立類例項的三種方式是什麼
參照:http://www.jianshu.com/p/3ea4a6b57f87?amp
http://blog.csdn.net/yongjian1092/article/details/7364451
反射中,Class.forName 和 ClassLoader 區別。
https://my.oschina.net/gpzhang/blog/486743
描述動態代理的幾種實現方式,分別說出相應的優缺點。
Jdk cglib jdk底層是利用反射機制,需要基於介面方式,這是由於
Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
Cglib則是基於asm框架,實現了無反射機制進行代理,利用空間來換取了時間,代理效率高於jdk
http://lrd.ele.me/2017/01/09/dynamic_proxy/
##動態代理與 cglib 實現的區別
同上(基於invocationHandler和methodInterceptor)
為什麼 CGlib 方式可以對介面實現代理。
同上
final 的用途
類、變數、方法
http://www.importnew.com/7553.html
寫出三種單例模式實現。
懶漢式單例,餓漢式單例,雙重檢查等
參考:https://my.oschina.net/dyyweb/blog/609021
如何在父類中為子類自動完成所有的 hashcode 和 equals 實現?這麼做有何優劣。
同時複寫hashcode和equals方法,優勢可以新增自定義邏輯,且不必呼叫超類的實現。
參照:http://java-min.iteye.com/blog/1416727
請結合 OO 設計理念,談談訪問修飾符 public、private、protected、default 在應用設計中的作用。
訪問修飾符,主要標示修飾塊的作用域,方便隔離防護
同一個類 同一個包 不同包的子類 不同包的非子類
Private √
Default √ √
Protected √ √ √
Public √ √ √ √
public: Java語言中訪問限制最寬的修飾符,一般稱之為“公共的”。被其修飾的類、屬性以及方法不
僅可以跨類訪問,而且允許跨包(package)訪問。
private: Java語言中對訪問許可權限制的最窄的修飾符,一般稱之為“私有的”。被其修飾的類、屬性以
及方法只能被該類的物件訪問,其子類不能訪問,更不能允許跨包訪問。
protect: 介於public 和 private 之間的一種訪問修飾符,一般稱之為“保護形”。被其修飾的類、
屬性以及方法只能被類本身的方法及子類訪問,即使子類在不同的包中也可以訪問。
default:即不加任何訪問修飾符,通常稱為“預設訪問模式“。該模式下,只允許在同一個包中進行訪
問。
深拷貝和淺拷貝區別。
http://www.oschina.net/translate/java-copy-shallow-vs-deep-in-which-you-will-swim
陣列和連結串列資料結構描述,各自的時間複雜度
http://blog.csdn.net/snow_wu/article/details/53172721
error 和 exception 的區別,CheckedException,RuntimeException 的區別
http://blog.csdn.net/woshixuye/article/details/8230407
請列出 5 個執行時異常。
同上
在自己的程式碼中,如果建立一個 java.lang.String 物件,這個物件是否可以被類載入器載入?為什麼
類載入無須等到“首次使用該類”時載入,jvm允許預載入某些類。。。。
http://www.cnblogs.com/jasonstorm/p/5663864.html
說一說你對 java.lang.Object 物件中 hashCode 和 equals 方法的理解。在什麼場景下需要重新實現這兩個方法。
參考上邊試題
在 jdk1.5 中,引入了泛型,泛型的存在是用來解決什麼問題。
泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數,泛型的好處是在編譯的時候檢查型別安全,並且所有的強制轉換都是自動和隱式的,以提高程式碼的重用率
http://baike.baidu.com/item/java泛型
這樣的 a.hashcode() 有什麼用,與 a.equals(b)有什麼關係。
hashcode
hashcode()方法提供了物件的hashCode值,是一個native方法,返回的預設值與System.identityHashCode(obj)一致。
通常這個值是物件頭部的一部分二進位制位組成的數字,具有一定的標識物件的意義存在,但絕不定於地址。
作用是:用一個數字來標識物件。比如在HashMap、HashSet等類似的集合類中,如果用某個物件本身作為Key,即要基於這個物件實現Hash的寫入和查詢,那麼物件本身如何實現這個呢?就是基於hashcode這樣一個數字來完成的,只有數字才能完成計算和對比操作。
hashcode是否唯一
hashcode只能說是標識物件,在hash演算法中可以將物件相對離散開,這樣就可以在查詢資料的時候根據這個key快速縮小資料的範圍,但hashcode不一定是唯一的,所以hash演算法中定位到具體的連結串列後,需要迴圈連結串列,然後通過equals方法來對比Key是否是一樣的。
equals與hashcode的關係
equals相等兩個物件,則hashcode一定要相等。但是hashcode相等的兩個物件不一定equals相等。
https://segmentfault.com/a/1190000004520827
有沒有可能 2 個不相等的物件有相同的 hashcode。
有
Java 中的 HashSet 內部是如何工作的。
底層是基於hashmap實現的
http://wiki.jikexueyuan.com/project/java-collection/hashset.html
什麼是序列化,怎麼序列化,為什麼序列化,反序列化會遇到什麼問題,如何解決。
http://www.importnew.com/17964.html
JVM 知識
什麼情況下會發生棧記憶體溢位。
如果執行緒請求的棧深度大於虛擬機器所允許的深度,將丟擲StackOverflowError異常。 如果虛擬機器在動態擴充套件棧時無法申請到足夠的記憶體空間,則丟擲OutOfMemoryError異常。
參照:http://wiki.jikexueyuan.com/project/java-vm/storage.html
JVM 的記憶體結構,Eden 和 Survivor 比例。
eden 和 survior 是按8比1分配的
http://blog.csdn.net/lojze_ly/article/details/49456255
jvm 中一次完整的 GC 流程是怎樣的,物件如何晉升到老年代,說說你知道的幾種主要的jvm 引數。
物件誕生即新生代->eden,在進行minor gc過程中,如果依舊存活,移動到from,變成Survivor,進行標記代數,如此檢查一定次數後,晉升為老年代,
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037056.html
http://ifeve.com/useful-jvm-flags/
https://wangkang007.gitbooks.io/jvm/content/jvmcan_shu_xiang_jie.html
你知道哪幾種垃圾收集器,各自的優缺點,重點講下 cms,包括原理,流程,優缺點
Serial、parNew、ParallelScavenge、SerialOld、ParallelOld、CMS、G1
https://wangkang007.gitbooks.io/jvm/content/chapter1.html
垃圾回收演算法的實現原理。
http://www.importnew.com/13493.html
當出現了記憶體溢位,你怎麼排錯。
首先分析是什麼型別的記憶體溢位,對應的調整引數或者優化程式碼。
https://wangkang007.gitbooks.io/jvm/content/4jvmdiao_you.html
JVM 記憶體模型的相關知識瞭解多少,比如重排序,記憶體屏障,happen-before,主記憶體,工作記憶體等。
記憶體屏障:為了保障執行順序和可見性的一條cpu指令
重排序:為了提高效能,編譯器和處理器會對執行進行重拍
happen-before:操作間執行的順序關係。有些操作先發生。
主記憶體:共享變數儲存的區域即是主記憶體
工作記憶體:每個執行緒copy的本地記憶體,儲存了該執行緒以讀/寫共享變數的副本
http://ifeve.com/java-memory-model-1/
http://www.jianshu.com/p/d3fda02d4cae
http://blog.csdn.net/kenzyq/article/details/50918457
簡單說說你瞭解的類載入器。
類載入器的分類(bootstrap,ext,app,curstom),類載入的流程(load-link-init)
http://blog.csdn.net/gjanyanlig/article/details/6818655/
講講 JAVA 的反射機制。
Java程式在執行狀態可以動態的獲取類的所有屬性和方法,並例項化該類,呼叫方法的功能
http://baike.baidu.com/link?url=C7p1PeLa3ploAgkfAOK-4XHE8HzQuOAB7K5GPcK_zpbAa_Aw-nO3997K1oir8N--1_wxXZfOThFrEcA0LjVP6wNOwidVTkLBzKlQVK6JvXYvVNhDWV9yF-NIOebtg1hwsnagsjUhOE2wxmiup20RRa#7
你們線上應用的 JVM 引數有哪些。
-server
Xms6000M
-Xmx6000M
-Xmn500M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
g1 和 cms 區別,吞吐量優先和響應優先的垃圾收集器選擇。
Cms是以獲取最短回收停頓時間為目標的收集器。基於標記-清除演算法實現。比較佔用cpu資源,切易造成碎片。
G1是面向服務端的垃圾收集器,是jdk9預設的收集器,基於標記-整理演算法實現。可利用多核、多cpu,保留分代,實現可預測停頓,可控。
http://blog.csdn.net/linhu007/article/details/48897597
請解釋如下 jvm 引數的含義:
-server -Xms512m -Xmx512m -Xss1024K
-XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=20
XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly。
Server模式啟動
最小堆記憶體512m
最大512m
每個執行緒棧空間1m
永久代256
最大永久代256
最大轉為老年代檢查次數20
Cms回收開啟時機:記憶體佔用80%
命令JVM不基於執行時收集的資料來啟動CMS垃圾收集週期
#開源框架知識
##簡單講講 tomcat 結構,以及其類載入器流程。
Server- --多個service
Container級別的:–>engine–》host–>context
Listenter
Connector
Logging、Naming、Session、JMX等等
通過WebappClassLoader 載入class
http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/
http://blog.csdn.net/dc_726/article/details/11873343
http://www.cnblogs.com/xing901022/p/4574961.html
http://www.jianshu.com/p/62ec977996df
tomcat 如何調優,涉及哪些引數。
硬體上選擇,作業系統選擇,版本選擇,jdk選擇,配置jvm引數,配置connector的執行緒數量,開啟gzip壓縮,trimSpaces,叢集等
http://blog.csdn.net/lifetragedy/article/details/7708724
講講 Spring 載入流程。
通過listener入口,核心是在AbstractApplicationContext的refresh方法,在此處進行裝載bean工廠,bean,建立bean例項,攔截器,後置處理器等。
https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/
講講 Spring 事務的傳播屬性。
七種傳播屬性。
事務傳播行為
所謂事務的傳播行為是指,如果在開始當前事務之前,一個事務上下文已經存在,此時有若干選項可以指定一個事務性方法的執行行為。在TransactionDefinition定義中包括瞭如下幾個表示傳播行為的常量:
TransactionDefinition.PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務;如果當前沒有事務,則建立一個新的事務。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:建立一個新的事務,如果當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續執行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式執行,如果當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則丟擲異常。
TransactionDefinition.PROPAGATION_MANDATORY:如果當前存在事務,則加入該事務;如果當前沒有事務,則丟擲異常。
TransactionDefinition.PROPAGATION_NESTED:如果當前存在事務,則建立一個事務作為當前事務的巢狀事務來執行;如果當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。
https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/
Spring 如何管理事務的。
程式設計式和宣告式
同上
Spring 怎麼配置事務(具體說出一些關鍵的 xml 元素)。
<beans…>
…
<tx:advice id=“bankAdvice” transaction-manager=“transactionManager”>
tx:attributes
<tx:method name=“transfer” propagation=“REQUIRED”/>
</tx:attributes>
</tx:advice>
aop:config
<aop:pointcut id=“bankPointcut” expression=“execution(* *.transfer(…))”/>
<aop:advisor advice-ref=“bankAdvice” pointcut-ref=“bankPointcut”/>
</aop:config>
…
同上
說說你對 Spring 的理解,非單例注入的原理?它的生命週期?迴圈注入的原理, aop 的實現原理,說說 aop 中的幾個術語,它們是怎麼相互工作的。
核心元件:bean,context,core,單例注入是通過單例beanFactory進行建立,生命週期是在建立的時候通過介面實現開啟,迴圈注入是通過後置處理器,aop其實就是通過反射進行動態代理,pointcut,advice等。
Aop相關:http://blog.csdn.net/csh624366188/article/details/7651702/
Springmvc 中 DispatcherServlet 初始化過程。
入口是web.xml中配置的ds,ds繼承了HttpServletBean,FrameworkServlet,通過其中的init方法進行初始化裝載bean和例項,initServletBean是實際完成上下文工作和bean初始化的方法。
http://www.mamicode.com/info-detail-512105.html
作業系統
Linux 系統下你關注過哪些核心引數,說說你知道的。
Tcp/ip io cpu memory
net.ipv4.tcp_syncookies = 1
#啟用syncookies
net.ipv4.tcp_max_syn_backlog = 8192
#SYN佇列長度
net.ipv4.tcp_synack_retries=2
#SYN ACK重試次數
net.ipv4.tcp_fin_timeout = 30
#主動關閉方FIN-WAIT-2超時時間
net.ipv4.tcp_keepalive_time = 1200
#TCP傳送keepalive訊息的頻度
net.ipv4.tcp_tw_reuse = 1
#開啟TIME-WAIT重用
net.ipv4.tcp_tw_recycle = 1
#開啟TIME-WAIT快速回收
net.ipv4.ip_local_port_range = 1024 65000
#向外連線的埠範圍
net.ipv4.tcp_max_tw_buckets = 5000
#最大TIME-WAIT數量,超過立即清除
net.ipv4.tcp_syn_retries = 2
#SYN重試次數
echo “fs.file-max=65535” >> /etc/sysctl.conf
sysctl -p
http://www.haiyun.me/category/system/
Linux 下 IO 模型有幾種,各自的含義是什麼。
阻塞式io,非阻塞io,io複用模型,訊號驅動io模型,非同步io模型。
https://yq.aliyun.com/articles/46404
https://yq.aliyun.com/articles/46402
epoll 和 poll 有什麼區別。
select的本質是採用32個整數的32位,即3232= 1024來標識,fd值為1-1024。當fd的值超過1024限制時,就必須修改FD_SETSIZE的大小。這個時候就可以標識32max值範圍的fd。
對於單程式多執行緒,每個執行緒處理多個fd的情況,select是不適合的。
1.所有的執行緒均是從1-32*max進行掃描,每個執行緒處理的均是一段fd值,這樣做有點浪費
2.1024上限問題,一個處理多個使用者的程式,fd值遠遠大於1024
所以這個時候應該採用poll,
poll傳遞的是陣列頭指標和該陣列的長度,只要陣列的長度不是很長,效能還是很不錯的,因為poll一次在核心中申請4K(一個頁的大小來存放fd),儘量控制在4K以內
epoll還是poll的一種優化,返回後不需要對所有的fd進行遍歷,在核心中維持了fd的列表。select和poll是將這個核心列表維持在使用者態,然後傳遞到核心中。但是隻有在2.6的核心才支援。
epoll更適合於處理大量的fd ,且活躍fd不是很多的情況,畢竟fd較多還是一個序列的操作
https://yq.aliyun.com/articles/10525
平時用到哪些 Linux 命令。
Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等
https://yq.aliyun.com/articles/69417?spm=5176.100240.searchblog.18.Zrbh9R
用一行命令檢視檔案的最後五行。
Tail -n 5 filename
用一行命令輸出正在執行的 java 程式。
ps -ef|grep Java
介紹下你理解的作業系統中執行緒切換過程。
控制權的轉換,根據優先順序切換上下文(使用者,暫存器,系統)
http://www.cnblogs.com/kkshaq/p/4544426.html
程式和執行緒的區別。
Linux 實現並沒有區分這兩個概念(程式和執行緒)
- 程式:程式的一次執行
- 執行緒:CPU的基本排程單位
一個程式可以包含多個執行緒。
http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
多執行緒
多執行緒的幾種實現方式,什麼是執行緒安全。
實現runable介面,繼承thread類。
http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/
volatile 的原理,作用,能代替鎖麼。
Volatile利用記憶體柵欄機制來保持變數的一致性。不能代替鎖,其只具備資料可見性一致性,不具備原子性。
http://blog.csdn.net/gongzi2311/article/details/20715185
畫一個執行緒的生命週期狀態圖。
新建,可執行,執行中, 睡眠,阻塞,等待,死亡。
http://ifeve.com/thread-status
sleep 和 wait 的區別。
Sleep是休眠執行緒,wait是等待,sleep是thread的靜態方法,wait則是object的方法。
Sleep依舊持有鎖,並在指定時間自動喚醒。wait則釋放鎖。
http://www.jianshu.com/p/4ec3f4b3903d
Lock 與 Synchronized 的區別。
首先兩者都保持了併發場景下的原子性和可見性,區別則是synchronized的釋放鎖機制是交由其自身控制,且互斥性在某些場景下不符合邏輯,無法進行干預,不可人為中斷等。
而lock常用的則有ReentrantLock和readwritelock兩者,新增了類似鎖投票、定時鎖等候和可中斷鎖等候的一些特性。此外,它還提供了在激烈爭用情況下更佳的效能。
http://blog.csdn.net/vking_wang/article/details/9952063
synchronized 的原理是什麼,解釋以下名詞:重排序,自旋鎖,偏向鎖,輕量級鎖,可重入鎖,公平鎖,非公平鎖,樂觀鎖,悲觀鎖。
Synchronized底層是通過監視器的enter和exit實現
https://my.oschina.net/cnarthurs/blog/847801
http://blog.csdn.net/a314773862/article/details/54095819
用過哪些原子類,他們的原理是什麼。
AtomicInteger; AtomicLong; AtomicReference; AtomicBoolean;基於CAS原語實現 ,比較並交換、載入連結/條件儲存,最壞的情況下是旋轉鎖
https://www.ibm.com/developerworks/cn/java/j-jtp11234/index.html
http://www.jmatrix.org/java/848.html
用過執行緒池嗎,newCache 和 newFixed 有什麼區別,他們的原理簡單概括下,建構函式的各個引數的含義是什麼,比如 coreSize,maxsize 等。
newSingleThreadExecutor返回以個包含單執行緒的Executor,將多個任務交給此Exector時,這個執行緒處理完一個任務後接著處理下一個任務,若該執行緒出現異常,將會有一個新的執行緒來替代。
newFixedThreadPool返回一個包含指定數目執行緒的執行緒池,如果任務數量多於執行緒數目,那麼沒有沒有執行的任務必須等待,直到有任務完成為止。
newCachedThreadPool根據使用者的任務數建立相應的執行緒來處理,該執行緒池不會對執行緒數目加以限制,完全依賴於JVM能建立執行緒的數量,可能引起記憶體不足。
底層是基於ThreadPoolExecutor實現,藉助reentrantlock保證併發。
coreSize核心執行緒數,maxsize最大執行緒數。
http://ifeve.com/java-threadpoolexecutor/
執行緒池的關閉方式有幾種,各自的區別是什麼。
Shutdown shutdownNow tryTerminate 清空工作佇列,終止執行緒池中各個執行緒,銷燬執行緒池
http://blog.csdn.net/xxcupid/article/details/51993235
假如有一個第三方介面,有很多個執行緒去呼叫獲取資料,現在規定每秒鐘最多有 10 個執行緒同時呼叫它,如何做到。
ScheduledThreadPoolExecutor 設定定時,進行排程。
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
http://ifeve.com/java-scheduledthreadpoolexecutor/
spring 的 controller 是單例還是多例,怎麼保證併發的安全。
單例
通過單例工廠 DefaultSingletonBeanRegistry實現單例
通過保AsyncTaskExecutor持安全
用三個執行緒按順序迴圈列印 abc 三個字母,比如 abcabcabc。
public static void main(String[] args) {
final String str=“abc”;
ExecutorService executorService= Executors.newFixedThreadPool(3);
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(“1”+str);
}
});executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(“2”+str);
}
});executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(“2”+str);
}
});
}
ThreadLocal 用過麼,用途是什麼,原理是什麼,用的時候要注意什麼。
Threadlocal底層是通過threadlocalMap進行儲存鍵值 每個ThreadLocal類建立一個Map,然後用執行緒的ID作為Map的key,例項物件作為Map的value,這樣就能達到各個執行緒的值隔離的效果。
ThreadLocal的作用是提供執行緒內的區域性變數,這種變數線上程的生命週期內起作用,減少同一個執行緒內多個函式或者元件之間一些公共變數的傳遞的複雜度。
誰設定誰負責移除
http://qifuguang.me/2015/09/02/[Java併發包學習七]解密ThreadLocal/
如果讓你實現一個併發安全的連結串列,你會怎麼做。
Collections.synchronizedList() ConcurrentLinkedQueue
http://blog.csdn.net/xingjiarong/article/details/48046751
有哪些無鎖資料結構,他們實現的原理是什麼。
LockFree,CAS
基於jdk提供的原子類原語實現,例如AtomicReference
http://blog.csdn.net/b_h_l/article/details/8704480
講講 java 同步機制的 wait 和 notify。
首先這兩個方法只能在同步程式碼塊中呼叫,wait會釋放掉物件鎖,等待notify喚醒。
http://blog.csdn.net/ithomer/article/details/7685594
多執行緒如果執行緒掛住了怎麼辦。
根據具體情況(sleep,wait,join等),酌情選擇notifyAll,notify進行執行緒喚醒。
http://blog.chinaunix.net/uid-122937-id-215913.html
countdowlatch 和 cyclicbarrier 的內部原理和用法,以及相互之間的差別。
CountDownLatch是一個同步輔助類,在完成一組正在其他執行緒中執行的操作之前,它執行一個或者多個執行緒一直處於等待狀態。
CyclicBarrier要做的事情是,讓一組執行緒到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續執行。
CyclicBarrier初始化的時候,設定一個屏障數。執行緒呼叫await()方法的時候,這個執行緒就會被阻塞,當呼叫await()的執行緒數量到達屏障數的時候,主執行緒就會取消所有被阻塞執行緒的狀態。
前者是遞減,不可迴圈,後者是遞加,可迴圈用
countdowlatch 基於abq cb基於ReentrantLock Condition
http://www.jianshu.com/p/a101ae9797e3
http://blog.csdn.net/tolcf/article/details/50925145
使用 synchronized 修飾靜態方法和非靜態方法有什麼區別。
物件鎖和類鎖
https://yq.aliyun.com/articles/24226
簡述 ConcurrentLinkedQueue LinkedBlockingQueue 的用處和不同之處。
LinkedBlockingQueue 是一個基於單向連結串列的、範圍任意的(其實是有界的)、FIFO 阻塞佇列。
ConcurrentLinkedQueue是一個基於連結節點的無界執行緒安全佇列,它採用先進先出的規則對節點進行排序,當我們新增一個元素的時候,它會新增到佇列的尾部,當我們獲取一個元素時,它會返回佇列頭部的元素。它採用了“wait-free”演算法來實現,該演算法在Michael & Scott演算法上進行了一些修改, Michael & Scott演算法的詳細資訊可以參見參考資料一。
http://ifeve.com/concurrentlinkedqueue/
http://ifeve.com/juc-linkedblockingqueue/
http://blog.csdn.net/xiaohulunb/article/details/38932923
##導致執行緒死鎖的原因?怎麼解除執行緒死鎖。
死鎖問題是多執行緒特有的問題,它可以被認為是執行緒間切換消耗系統效能的一種極端情況。在死鎖時,執行緒間相互等待資源,而又不釋放自身的資源,導致無窮無盡的等待,其結果是系統任務永遠無法執行完成。死鎖問題是在多執行緒開發中應該堅決避免和杜絕的問題。
一般來說,要出現死鎖問題需要滿足以下條件:
- 互斥條件:一個資源每次只能被一個執行緒使用。
- 請求與保持條件:一個程式因請求資源而阻塞時,對已獲得的資源保持不放。
- 不剝奪條件:程式已獲得的資源,在未使用完之前,不能強行剝奪。
- 迴圈等待條件:若干程式之間形成一種頭尾相接的迴圈等待資源關係。
只要破壞死鎖 4 個必要條件之一中的任何一個,死鎖問題就能被解決。
https://www.ibm.com/developerworks/cn/java/j-lo-deadlock/
非常多個執行緒(可能是不同機器),相互之間需要等待協調,才能完成某種工作,問怎麼設計這種協調方案。
此問題的本質是保持順序執行。可以使用executors
#TCP 與 HTTP
http1.0 和 http1.1 有什麼區別。
HTTP 1.0主要有以下幾點變化:
請求和相應可以由於多行首部欄位構成
響應物件前面新增了一個響應狀態行
響應物件不侷限於超文字
伺服器與客戶端之間的連線在每次請求之後都會關閉
實現了Expires等傳輸內容的快取控制
內容編碼Accept-Encoding、字符集Accept-Charset等協商內容的支援
這時候開始有了請求及返回首部的概念,開始傳輸不限於文字(其他二進位制內容)
HTTP 1.1加入了很多重要的效能優化:持久連線、分塊編碼傳輸、位元組範圍請求、增強的快取機制、傳輸編碼及請求管道。
http://imweb.io/topic/554c5879718ba1240cc1dd8a
TCP 三次握手和四次揮手的流程,為什麼斷開連線要 4 次,如果握手只有兩次,會出現什麼。
-
第一次握手(SYN=1, seq=x):
客戶端傳送一個 TCP 的 SYN 標誌位置1的包,指明客戶端打算連線的伺服器的埠,以及初始序號 X,儲存在包頭的序列號(Sequence Number)欄位裡。
傳送完畢後,客戶端進入
SYN_SEND
狀態。 -
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
伺服器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均為1。伺服器端選擇自己 ISN 序列號,放到 Seq 域裡,同時將確認序號(Acknowledgement Number)設定為客戶的 ISN 加1,即X+1。
傳送完畢後,伺服器端進入SYN_RCVD
狀態。 -
第三次握手(ACK=1,ACKnum=y+1)
客戶端再次傳送確認包(ACK),SYN 標誌位為0,ACK 標誌位為1,並且把伺服器發來 ACK 的序號欄位+1,放在確定欄位中傳送給對方,並且在資料段放寫ISN的+1
傳送完畢後,客戶端進入 ESTABLISHED
狀態,當伺服器端接收到這個包時,也進入 ESTABLISHED
狀態,TCP 握手結束。
第一次揮手(FIN=1,seq=x)
假設客戶端想要關閉連線,客戶端傳送一個 FIN 標誌位置為1的包,表示自己已經沒有資料可以傳送了,但是仍然可以接受資料。
傳送完畢後,客戶端進入 FIN_WAIT_1 狀態。
第二次揮手(ACK=1,ACKnum=x+1)
伺服器端確認客戶端的 FIN 包,傳送一個確認包,表明自己接受到了客戶端關閉連線的請求,但還沒有準備好關閉連線。
傳送完畢後,伺服器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包之後,進入 FIN_WAIT_2 狀態,等待伺服器端關閉連線。
第三次揮手(FIN=1,seq=y)
伺服器端準備好關閉連線時,向客戶端傳送結束連線請求,FIN 置為1。
傳送完畢後,伺服器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個ACK。
第四次揮手(ACK=1,ACKnum=y+1)
客戶端接收到來自伺服器端的關閉請求,傳送一個確認包,並進入 TIME_WAIT狀態,等待可能出現的要求重傳的 ACK 包。
伺服器端接收到這個確認包之後,關閉連線,進入 CLOSED 狀態。
客戶端等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到伺服器端的 ACK ,認為伺服器端已經正常關閉連線,於是自己也關閉連線,進入 CLOSED 狀態。
兩次後會重傳直到超時。如果多了會有大量半連結阻塞佇列。
https://segmentfault.com/a/1190000006885287
https://hit-alibaba.github.io/interview/basic/network/TCP.html
TIME_WAIT 和 CLOSE_WAIT 的區別。
TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。
說說你知道的幾種 HTTP 響應碼,比如 200, 302, 404。
1xx:資訊,請求收到,繼續處理
2xx:成功,行為被成功地接受、理解和採納
3xx:重定向,為了完成請求,必須進一步執行的動作
4xx:客戶端錯誤,請求包含語法錯誤或者請求無法實現
5xx:伺服器錯誤,伺服器不能實現一種明顯無效的請求
200 ok 一切正常
302 Moved Temporatily 檔案臨時移出
404 not found
https://my.oschina.net/gavinjin/blog/42856
當你用瀏覽器開啟一個連結的時候,計算機做了哪些工作步驟。
Dns解析–>埠分析–>tcp請求–>伺服器處理請求–>伺服器響應–>瀏覽器解析—>連結關閉
TCP/IP 如何保證可靠性,說說 TCP 頭的結構。
使用序號,對收到的TCP報文段進行排序以及檢測重複的資料;使用校驗和來檢測報文段的錯誤;使用確認和計時器來檢測和糾正丟包或延時。//TCP頭部,總長度20位元組
typedef struct _tcp_hdr
{
unsigned short src_port; //源埠號
unsigned short dst_port; //目的埠號
unsigned int seq_no; //序列號
unsigned int ack_no; //確認號
#if LITTLE_ENDIAN
unsigned char reserved_1:4; //保留6位中的4位首部長度
unsigned char thl:4; //tcp頭部長度
unsigned char flag:6; //6位標誌
unsigned char reseverd_2:2; //保留6位中的2位
#else
unsigned char thl:4; //tcp頭部長度
unsigned char reserved_1:4; //保留6位中的4位首部長度
unsigned char reseverd_2:2; //保留6位中的2位
unsigned char flag:6; //6位標誌
#endif
unsigned short wnd_size; //16位視窗大小
unsigned short chk_sum; //16位TCP檢驗和
unsigned short urgt_p; //16為緊急指標
}tcp_hdr;
https://zh.bywiki.com/zh-hans/傳輸控制協議
如何避免瀏覽器快取。
無法被瀏覽器快取的請求:
HTTP資訊頭中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告訴瀏覽器不用快取的請求
需要根據Cookie,認證資訊等決定輸入內容的動態請求是不能被快取的
經過HTTPS安全加密的請求(有人也經過測試發現,ie其實在頭部加入Cache-Control:max-age資訊,firefox在頭部加入Cache-Control:Public之後,能夠對HTTPS的資源進行快取,參考《HTTPS的七個誤解》)
POST請求無法被快取
HTTP響應頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請求無法被快取
http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/
簡述 Http 請求 get 和 post 的區別以及資料包格式。
http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
http://www.360doc.com/content/12/0612/14/8093902_217673378.shtml
簡述 HTTP 請求的報文格式。
參考上面
HTTPS 的加密方式是什麼,講講整個加密解密流程。
加密方式是tls/ssl,底層是通過對稱演算法,非對稱,hash演算法實現
客戶端發起HTTPS請求 --》2. 服務端的配置 --》
3. 傳送證照 —》4. 客戶端解析證照 5. 傳送加密資訊 6. 服務段解密資訊 7. 傳輸加密後的資訊 8. 客戶端解密資訊
http://www.cnblogs.com/zhuqil/archive/2012/07/23/2604572.html
#架構設計與分散式
常見的快取策略有哪些,你們專案中用到了什麼快取系統,如何設計的。
Cdn快取,redis快取,ehcache快取等
Cdn 圖片資源 js等, redis一主一從 echcache快取資料
用 java 自己實現一個 LRU。
final int cacheSize = 100;
Map<String, String> map = new LinkedHashMap<String, String>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > cacheSize;
}
};
http://www.cnblogs.com/lzrabbit/p/3734850.html
分散式叢集下如何做到唯一序列號。
Redis生成,mongodb的objectId,zk生成
http://www.cnblogs.com/haoxinyue/p/5208136.html
設計一個秒殺系統,30 分鐘沒付款就自動關閉交易。
分流 – 限流–非同步–公平性(只能參加一次)–使用者體驗(第幾位,多少分鐘,一搶完)
容錯處理
Redis 佇列 mysql
30分鐘關閉 可以藉助redis的釋出訂閱機制 在失效時進行後續操作,其他mq也可以
http://www.infoq.com/cn/articles/yhd-11-11-queuing-system-design
如何使用 redis 和 zookeeper 實現分散式鎖?有什麼區別優缺點,分別適用什麼場景。
首先分散式鎖實現常見的有資料庫鎖(表記錄),快取鎖,基於zk(臨時有序節點可以實現的)的三種
Redis適用於對效能要求特別高的場景。redis可以每秒執行10w次,內網延遲不超過1ms
缺點是資料存放於記憶體,當機後鎖丟失。
鎖無法釋放?使用Zookeeper可以有效的解決鎖無法釋放的問題,因為在建立鎖的時候,客戶端會在ZK中建立一個臨時節點,一旦客戶端獲取到鎖之後突然掛掉(Session連線斷開),那麼這個臨時節點就會自動刪除掉。其他客戶端就可以再次獲得鎖。
非阻塞鎖?使用Zookeeper可以實現阻塞的鎖,客戶端可以通過在ZK中建立順序節點,並且在節點上繫結監聽器,一旦節點有變化,Zookeeper會通知客戶端,客戶端可以檢查自己建立的節點是不是當前所有節點中序號最小的,如果是,那麼自己就獲取到鎖,便可以執行業務邏輯了。
不可重入?使用Zookeeper也可以有效的解決不可重入的問題,客戶端在建立節點的時候,把當前客戶端的主機資訊和執行緒資訊直接寫入到節點中,下次想要獲取鎖的時候和當前最小的節點中的資料比對一下就可以了。如果和自己的資訊一樣,那麼自己直接獲取到鎖,如果不一樣就再建立一個臨時的順序節點,參與排隊。
單點問題?使用Zookeeper可以有效的解決單點問題,ZK是叢集部署的,只要叢集中有半數以上的機器存活,就可以對外提供服務。
http://www.hollischuang.com/archives/1716
如果有人惡意建立非法連線,怎麼解決。
可以使用filter過濾處理
分散式事務的原理,優缺點,如何使用分散式事務。
Two Phase commit協議
優點是可以管理多機事務,擁有無線擴充套件性 確定是易用性難,承擔延時風險
JTA,atomiks等
https://yq.aliyun.com/webinar/join/185?spm=5176.8067841.0.0.RL4GDa
什麼是一致性 hash。
一致性hash是一種分散式hash實現演算法。滿足平衡性 單調性 分散性 和負載。
http://blog.csdn.net/cywosp/article/details/23397179/
什麼是 restful,講講你理解的 restful。
REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程式或設計就是 RESTful。
http://baike.baidu.com/link?url=fTSAdL-EyYvTp9z7mZsCOdS3kbs4VKKAnpBLg3WS_1Z4cmLMp3S-zrjcy5wakLTO5AIoPTopWVkG-IenloPKxq
如何設計建立和保持 100w 的長連線。
伺服器核心調優(tcp,檔案數),客戶端調優,框架選擇(netty)
如何防止快取雪崩。
快取雪崩可能是因為資料未載入到快取中,或者快取同一時間大面積的失效,從而導致所有請求都去查資料庫,導致資料庫CPU和記憶體負載過高,甚至當機。
解決思路:
1,採用加鎖計數,或者使用合理的佇列數量來避免快取失效時對資料庫造成太大的壓力。這種辦法雖然能緩解資料庫的壓力,但是同時又降低了系統的吞吐量。
2,分析使用者行為,儘量讓失效時間點均勻分佈。避免快取雪崩的出現。
3,如果是因為某臺快取伺服器當機,可以考慮做主備,比如:redis主備,但是雙快取涉及到更新事務的問題,update可能讀到髒資料,需要好好解決。
http://www.cnblogs.com/jinjiangongzuoshi/archive/2016/03/03/5240280.html
解釋什麼是 MESI 協議(快取一致性)。
MESI是四種快取段狀態的首字母縮寫,任何多核系統中的快取段都處於這四種狀態之一。我將以相反的順序逐個講解,因為這個順序更合理:
失效(Invalid)快取段,要麼已經不在快取中,要麼它的內容已經過時。為了達到快取的目的,這種狀態的段將會被忽略。一旦快取段被標記為失效,那效果就等同於它從來沒被載入到快取中。
共享(Shared)快取段,它是和主記憶體內容保持一致的一份拷貝,在這種狀態下的快取段只能被讀取,不能被寫入。多組快取可以同時擁有針對同一記憶體地址的共享快取段,這就是名稱的由來。
獨佔(Exclusive)快取段,和S狀態一樣,也是和主記憶體內容保持一致的一份拷貝。區別在於,如果一個處理器持有了某個E狀態的快取段,那其他處理器就不能同時持有它,所以叫“獨佔”。這意味著,如果其他處理器原本也持有同一快取段,那麼它會馬上變成“失效”狀態。
已修改(Modified)快取段,屬於髒段,它們已經被所屬的處理器修改了。如果一個段處於已修改狀態,那麼它在其他處理器快取中的拷貝馬上會變成失效狀態,這個規律和E狀態一樣。此外,已修改快取段如果被丟棄或標記為失效,那麼先要把它的內容回寫到記憶體中——這和回寫模式下常規的髒段處理方式一樣。
說說你知道的幾種 HASH 演算法,簡單的也可以。
雜湊(Hash)演算法,即雜湊函式。 它是一種單向密碼體制,即它是一個從明文到密文的不可逆的對映,只有加密過程,沒有解密過程。 同時,雜湊函式可以將任意長度的輸入經過變化以後得到固定長度的輸出
MD4 MD5 SHA
http://blog.jobbole.com/106733/
什麼是 paxos 演算法。
Paxos演算法是萊斯利·蘭伯特(Leslie Lamport,就是 LaTeX 中的"La",此人現在在微軟研究院)於1990年提出的一種基於訊息傳遞的一致性演算法。
http://baike.baidu.com/item/Paxos 演算法
##什麼是 zab 協議。
ZAB 是 Zookeeper 原子廣播協議的簡稱
整個ZAB協議主要包括訊息廣播和崩潰恢復兩個過程,進一步可以分為三個階段,分別是:
發現 Discovery
同步 Synchronization
廣播 Broadcast
組成ZAB協議的每一個分散式程式,都會迴圈執行這三個階段,將這樣一個迴圈稱為一個主程式週期。
https://zzzvvvxxxd.github.io/2016/08/09/ZAB/
##一個線上文件系統,文件可以被編輯,如何防止多人同時對同一份文件進行編輯更新。
點選編輯的時候,利用redis進行加鎖setNX完了之後 expire 一下
也可以用版本號進行控制
線上系統突然變得異常緩慢,你如何查詢問題。
逐級排查(網路,磁碟,記憶體,cpu),資料庫,日誌,中介軟體等也可通過監控工具排查。
說說你平時用到的設計模式。
單例, 代理,模板,策略,命令
http://www.jianshu.com/p/bdf65e4afbb0
Dubbo 的原理,資料怎麼流轉的,怎麼實現叢集,負載均衡,服務註冊和發現。重試轉發,快速失敗的策略是怎樣的。
Dubbo[]是一個分散式服務框架,致力於提供高效能和透明化的RPC遠端服務呼叫方案,以及SOA服務治理方案。
##Cluster 實現叢集
在叢集負載均衡時,Dubbo提供了多種均衡策略,預設為random隨機呼叫。
Random LoadBalance:隨機,按權重比率設定隨機概率。
RoundRobin LoadBalance:輪循,按公約後的權重比率設定輪循比率。
LeastActive LoadBalance:最少活躍呼叫數,相同活躍數的隨機,活躍數指呼叫前後計數差。使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。
ConsistentHash LoadBalance:一致性Hash,相同引數的請求總是發到同一提供者。當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。
快速失敗,只發起一次呼叫,失敗立即報錯。
https://my.oschina.net/u/1378920/blog/693374
一次 RPC 請求的流程是什麼。
1)服務消費方(client)呼叫以本地呼叫方式呼叫服務;
2)client stub接收到呼叫後負責將方法、引數等組裝成能夠進行網路傳輸的訊息體;
3)client stub找到服務地址,並將訊息傳送到服務端;
4)server stub收到訊息後進行解碼;
5)server stub根據解碼結果呼叫本地的服務;
6)本地服務執行並將結果返回給server stub;
7)server stub將返回結果打包成訊息併傳送至消費方;
8)client stub接收到訊息,並進行解碼;
9)服務消費方得到最終結果。
非同步模式的用途和意義。
非同步模式使用與伺服器多核,併發嚴重的場景
可提高服務吞吐量大,不容易受到衝擊,可以採用併發策略,提高響應時間
快取資料過期後的更新如何設計。
失效:應用程式先從cache取資料,沒有得到,則從資料庫中取資料,成功後,放到快取中。
命中:應用程式從cache中取資料,取到後返回。
更新:先把資料存到資料庫中,成功後,再讓快取失效。
程式設計中自己都怎麼考慮一些設計原則的,比如開閉原則,以及在工作中的應用。
開閉原則(Open Close Principle)
一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。
里氏代換原則(Liskov Substitution Principle)
子型別必須能夠替換掉它們的父型別。
依賴倒轉原則(Dependence Inversion Principle)
高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。即針對介面程式設計,不要針對實現程式設計
介面隔離原則(Interface Segregation Principle)
建立單一介面,不要建立龐大臃腫的介面,儘量細化介面,介面中的方法儘量少
組合/聚合複用原則
說要儘量的使用合成和聚合,而不是繼承關係達到複用的目的
迪米特法則(Law Of Demeter)
迪米特法則其根本思想,是強調了類之間的鬆耦合,類之間的耦合越弱,越有利於複用,一個處在弱耦合的類被修改,不會對有關係的類造成影響,也就是說,資訊的隱藏促進了軟體的複用。
單一職責原則(Single Responsibility Principle)
一個類只負責一項職責,應該僅有一個引起它變化的原因
http://www.banzg.com/archives/225.html
設計一個社交網站中的“私信”功能,要求高併發、可擴充套件等等。 畫一下架構圖。
MVC 模式,即常見的 MVC 框架。
SSM SSH SSI等
聊了下曾經參與設計的伺服器架構。
應用伺服器怎麼監控效能,各種方式的區別。
如何設計一套高併發支付方案,架構如何設計。
如何實現負載均衡,有哪些演算法可以實現。
Zookeeper 的用途,選舉的原理是什麼。
Mybatis 的底層實現原理。
請思考一個方案,設計一個可以控制快取總體大小的自動適應的本地快取。
##請思考一個方案,實現分散式環境下的 countDownLatch。
後臺系統怎麼防止請求重複提交。
可以通過token值進行防止重複提交,存放到redis中,在表單初始化的時候隱藏在表單中,新增的時候在移除。判斷這個狀態即可防止重複提交。
如何看待快取的使用(本地快取,集中式快取),簡述本地快取和集中式快取和優缺點。本地快取在併發使用時的注意事項。
描述一個服務從釋出到被消費的詳細過程。
##講講你理解的服務治理。
如何做到介面的冪等性。
#演算法
10 億個數字裡裡面找最小的 10 個。
##有 1 億個數字,其中有 2 個是重複的,快速找到它,時間和空間要最優。
2 億個隨機生成的無序整數,找出中間大小的值。
給一個不知道長度的(可能很大)輸入字串,設計一種方案,將重複的字元排重。
遍歷二叉樹。
有 3n+1 個數字,其中 3n 箇中是重複的,只有 1 個是不重複的,怎麼找出來。
寫一個字串反轉函式。
##常用的排序演算法,快排,歸併、冒泡。 快排的最優時間複雜度,最差複雜度。氣泡排序的優化方案。
##二分查詢的時間複雜度,優勢。
##一個已經構建好的 TreeSet,怎麼完成倒排序。
什麼是 B+樹,B-樹,列出實際的使用場景。
資料庫知識
##資料庫隔離級別有哪些,各自的含義是什麼,MYSQL 預設的隔離級別是是什麼。
·未提交讀(Read Uncommitted):允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料
·提交讀(Read Committed):只能讀取到已經提交的資料。Oracle等多數資料庫預設都是該級別 (不重複讀)
·可重複讀(Repeated Read):可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB預設級別。在SQL標準中,該隔離級別消除了不可重複讀,但是還存在幻象讀
·序列讀(Serializable):完全序列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞
MYSQL預設是RepeatedRead級別
MYSQL 有哪些儲存引擎,各自優缺點。
MyISAM: 擁有較高的插入,查詢速度,但不支援事務
InnoDB :5.5版本後Mysql的預設資料庫,事務型資料庫的首選引擎,支援ACID事務,支援行級鎖定
BDB: 源自Berkeley DB,事務型資料庫的另一種選擇,支援COMMIT和ROLLBACK等其他事務特性
Memory :所有資料置於記憶體的儲存引擎,擁有極高的插入,更新和查詢效率。但是會佔用和資料量成正比的記憶體空間。並且其內容會在Mysql重新啟動時丟失
Merge :將一定數量的MyISAM表聯合而成一個整體,在超大規模資料儲存時很有用
Archive :非常適合儲存大量的獨立的,作為歷史記錄的資料。因為它們不經常被讀取。Archive擁有高效的插入速度,但其對查詢的支援相對較差
Federated: 將不同的Mysql伺服器聯合起來,邏輯上組成一個完整的資料庫。非常適合分散式應用
Cluster/NDB :高冗餘的儲存引擎,用多臺資料機器聯合提供服務以提高整體效能和安全性。適合資料量大,安全和效能要求高的應用
CSV: 邏輯上由逗號分割資料的儲存引擎。它會在資料庫子目錄裡為每個資料表建立一個.CSV檔案。這是一種普通文字檔案,每個資料行佔用一個文字行。CSV儲存引擎不支援索引。
BlackHole :黑洞引擎,寫入的任何資料都會消失,一般用於記錄binlog做複製的中繼
另外,Mysql的儲存引擎介面定義良好。有興趣的開發者通過閱讀文件編寫自己的儲存引擎。
http://baike.baidu.com/item/儲存引擎
高併發下,如何做到安全的修改同一行資料。
使用悲觀鎖 悲觀鎖本質是當前只有一個執行緒執行操作,結束了喚醒其他執行緒進行處理。
也可以快取佇列中鎖定主鍵。
樂觀鎖和悲觀鎖是什麼,INNODB 的行級鎖有哪 2 種,解釋其含義。
樂觀鎖是設定每次修改都不會衝突,只在提交的時候去檢查,悲觀鎖設定每次修改都會衝突,持有排他鎖。
行級鎖分為共享鎖和排他鎖兩種 共享鎖又稱讀鎖 排他鎖又稱寫鎖
http://www.jianshu.com/p/f40ec03fd0e8
SQL 優化的一般步驟是什麼,怎麼看執行計劃,如何理解其中各個欄位的含義。
檢視慢日誌(show [session|gobal] status ),定位慢查詢,檢視慢查詢執行計劃 根據執行計劃確認優化方案
Explain sql
select_type:表示select型別。常見的取值有SIMPLE(簡單表,即不使用連線或者子查詢)、PRIMARY(主查詢,即外層的查詢)、UNION(union中的第二個或者後面的查詢語句)、SUBQUERY(子查詢中的第一個SELECT)等。
talbe:輸出結果集的表。
type:表的連線型別。效能由高到底:system(表中僅有一行)、const(表中最多有一個匹配行)、eq_ref、ref、ref_null、index_merge、unique_subquery、index_subquery、range、idnex等
possible_keys:查詢時,可能使用的索引
key:實際使用的索引
key_len:索引欄位的長度
rows:掃描行的數量
Extra:執行情況的說明和描述
http://blog.csdn.net/hsd2012/article/details/51106285
資料庫會死鎖嗎,舉一個死鎖的例子,mysql 怎麼解決死鎖。
產生死鎖的原因主要是:
(1)系統資源不足。
(2) 程式執行推進的順序不合適。
(3)資源分配不當等。
如果系統資源充足,程式的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,程式執行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個程式使用。
(2) 請求與保持條件:一個程式因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:程式已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 迴圈等待條件:若干程式之間形成一種頭尾相接的迴圈等待資源關係。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
這裡提供兩個解決資料庫死鎖的方法:
1)重啟資料庫(誰用誰知道)
2)殺掉搶資源的程式:
先查哪些程式在搶資源:SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
殺掉它們:Kill trx_mysql_thread_id;
MYsql 的索引原理,索引的型別有哪些,如何建立合理的索引,索引如何優化。
索引是通過複雜的演算法,提高資料查詢效能的手段。從磁碟io到記憶體io的轉變
普通索引,主鍵,唯一,單列/多列索引建索引的幾大原則
1.最左字首匹配原則,非常重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整。
2.=和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式
3.儘量選擇區分度高的列作為索引,區分度的公式是count(distinct col)/count(*),表示欄位不重複的比例,比例越大我們掃描的記錄數越少,唯一鍵的區分度是1,而一些狀態、性別欄位可能在大資料面前區分度就是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不同,這個值也很難確定,一般需要join的欄位我們都要求是0.1以上,即平均1條掃描10條記錄
4.索引列不能參與計算,保持列“乾淨”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡單,b+樹中存的都是資料表中的欄位值,但進行檢索時,需要把所有元素都應用函式才能比較,顯然成本太大。所以語句應該寫成create_time = unix_timestamp(’2014-05-29’);
5.儘量的擴充套件索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那麼只需要修改原來的索引即可
http://tech.meituan.com/mysql-index.html
http://www.cnblogs.com/cq-home/p/3482101.html
##聚集索引和非聚集索引的區別。
“聚簇”就是索引和記錄緊密在一起。
非聚簇索引 索引檔案和資料檔案分開存放,索引檔案的葉子頁只儲存了主鍵值,要定位記錄還要去查詢相應的資料塊。
資料庫中 BTREE 和 B+tree 區別。
B+是btree的變種,本質都是btree,btree+與B-Tree相比,B+Tree有以下不同點:
每個節點的指標上限為2d而不是2d+1。
內節點不儲存data,只儲存key;葉子節點不儲存指標。
http://lcbk.net/9602.html
Btree 怎麼分裂的,什麼時候分裂,為什麼是平衡的。
Key 超過1024才分裂B樹為甚會分裂? 因為隨著資料的增多,一個結點的key滿了,為了保持B樹的特性,就會產生分裂,就向紅黑樹和AVL樹為了保持樹的性質需要進行旋轉一樣!
ACID 是什麼。
A,atomic,原子性,要麼都提交,要麼都失敗,不能一部分成功,一部分失敗。
C,consistent,一致性,事物開始及結束後,資料的一致性約束沒有被破壞
I,isolation,隔離性,併發事物間相互不影響,互不干擾。
D,durability,永續性,已經提交的事物對資料庫所做的更新必須永久儲存。即便發生崩潰,也不能被回滾或資料丟失。
##Mysql 怎麼優化 table scan 的。
避免在where子句中對欄位進行is null判斷
應儘量避免在where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。
避免在where 子句中使用or 來連線條件
in 和not in 也要慎用
Like查詢(非左開頭)
使用NUM=@num引數這種
where 子句中對欄位進行表示式操作num/2=XX
在where子句中對欄位進行函式操作
如何寫 sql 能夠有效的使用到複合索引。
由於複合索引的組合索引,類似多個木板拼接在一起,如果中間斷了就無法用了,所以要能用到複合索引,首先開頭(第一列)要用上,比如index(a,b) 這種,我們可以select table tname where a=XX 用到第一列索引 如果想用第二列 可以 and b=XX 或者and b like‘TTT%’
mysql 中 in 和 exists 區別。
mysql中的in語句是把外表和內表作hash 連線,而exists語句是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。一直大家都認為exists比in語句的效率要高,這種說法其實是不準確的。這個是要區分環境的。
如果查詢的兩個表大小相當,那麼用in和exists差別不大。
如果兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in:
not in 和not exists如果查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists都比not in要快。
1.EXISTS只返回TRUE或FALSE,不會返回UNKNOWN。
2.IN當遇到包含NULL的情況,那麼就會返回UNKNOWN。
資料庫自增主鍵可能的問題。
在分庫分表時可能會生成重複主鍵 利用自增比例達到唯一 自增1 2,3 等
https://yq.aliyun.com/articles/38438
#訊息佇列
##用過哪些 MQ,和其他 mq 比較有什麼優缺點,MQ 的連線是執行緒安全的嗎,你們公司的MQ 服務架構怎樣的。
根據實際情況說明
我們公司用activeMQ 因為業務比較簡單 只有轉碼功能,而amq比較簡單
如果是分散式的建議用kafka
http://blog.csdn.net/sunxinhere/article/details/7968886
MQ 系統的資料如何保證不丟失。
基本都是對資料進行持久化,多盤儲存
rabbitmq 如何實現叢集高可用。
叢集是保證服務可靠性的一種方式,同時可以通過水平擴充套件以提升訊息吞吐能力。RabbitMQ是用分散式程式設計語言erlang開發的,所以天生就支援叢集。接下來,將介紹RabbitMQ分散式訊息處理方式、叢集模式、節點型別,並動手搭建一個高可用叢集環境,最後通過java程式來驗證叢集的高可用性。
1. 三種分散式訊息處理方式
RabbitMQ分散式的訊息處理方式有以下三種:
1、Clustering:不支援跨網段,各節點需執行同版本的Erlang和RabbitMQ, 應用於同網段區域網。
2、Federation:允許單臺伺服器上的Exchange或Queue接收發布到另一臺伺服器上Exchange或Queue的訊息, 應用於廣域網,。
3、Shovel:與Federation類似,但工作在更低層次。
RabbitMQ對網路延遲很敏感,在LAN環境建議使用clustering方式;在WAN環境中,則使用Federation或Shovel。我們平時說的RabbitMQ叢集,說的就是clustering方式,它是RabbitMQ內嵌的一種訊息處理方式,而Federation或Shovel則是以plugin形式存在。
https://my.oschina.net/jiaoyanli/blog/822011
https://www.ibm.com/developerworks/cn/opensource/os-cn-RabbitMQ/
#Redis,Memcached
redis 的 list 結構相關的操作。
LPUSH LPUSHX RPUSH RPUSHX LPOP RPOP BLPOP BRPOP LLEN LRANGE
https://redis.readthedocs.io/en/2.4/list.html
Redis 的資料結構都有哪些。
字串(strings):儲存整數(比如計數器)和字串(廢話。。),有些公司也用來儲存json/pb等序列化資料,並不推薦,浪費記憶體
雜湊表(hashes):儲存配置,物件(比如使用者、商品),優點是可以存取部分key,對於經常變化的或者部分key要求atom操作的適合
列表(lists):可以用來存最新使用者動態,時間軸,優點是有序,確定是元素可重複,不去重
集合(sets):無序,唯一,對於要求嚴格唯一性的可以使用
有序集合(sorted sets):集合的有序版,很好用,對於排名之類的複雜場景可以考慮https://redis.readthedocs.io/en/2.4/list.html
##Redis 的使用要注意什麼,講講持久化方式,記憶體設定,叢集的應用和優劣勢,淘汰策略等。
持久化方式:RDB時間點快照 AOF記錄伺服器執行的所有寫操作命令,並在伺服器啟動時,通過重新執行這些命令來還原資料集。
記憶體設定 maxmemory used_memory
虛擬記憶體: vm-enabled yes
3.0採用Cluster方式,
Redis叢集相對單機在功能上存在一些限制, 需要開發人員提前瞭解,
在使用時做好規避。 限制如下:
1) key批量操作支援有限。 如mset、 mget, 目前只支援具有相同slot值的
ke
y執
行批量操作。 對於對映為不同slot值的key由於執行mget、 mget等操作可
能存在於多個節點上因此不被支援。
2) key事務操作支援有限。 同理只支援多key在同一節點上的事務操
作, 當多個key分佈在不同的節點上時無法使用事務功能。
3) key作為資料分割槽的最小粒度, 因此不能將一個大的鍵值物件如
ha
sh、 list等對映到不同的節點。
4) 不支援多資料庫空間。 單機下的Redis可以支援16個資料庫, 叢集模
式下只能使用一個資料庫空間, 即db0。
5) 複製結構只支援一層, 從節點只能複製主節點, 不支援巢狀樹狀復
制結構。
Redis Cluster是Redis的分散式解決方案, 在3.0版本正式推出, 有效地解
決了Redis分散式方面的需求。 當遇到單機記憶體、 併發、 流量等瓶頸時, 可
以採用Cluster架構方案達到負載均衡的目的。 之前, Redis分散式方案一般
有兩種:
·客戶端分割槽方案, 優點是分割槽邏輯可控, 缺點是需要自己處理資料路
由、 高可用、 故障轉移等問題。
·代理方案, 優點是簡化客戶端分散式邏輯和升級維護便利, 缺點是加
重架構部署複雜度和效能損耗。
現在官方為我們提供了專有的叢集方案: Redis Cluster, 它非常優雅地
解決了Redis叢集方面的問題, 因此理解應用好Redis Cluster將極大地解放我
們使用分散式Redis的工作量, 同時它也是學習分散式儲存的絕佳案例。
LRU(近期最少使用演算法)TTL(超時演算法) 去除ttl最大的鍵值
http://wiki.jikexueyuan.com/project/redis/data-elimination-mechanism.html
http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage
http://www.redis.cn/topics/cluster-tutorial.html
redis2 和 redis3 的區別,redis3 內部通訊機制。
叢集方式的區別,3採用Cluster,2採用客戶端分割槽方案和代理方案
通訊過程說明:
1) 叢集中的每個節點都會單獨開闢一個TCP通道, 用於節點之間彼此
通訊, 通訊埠號在基礎埠上加10000。
2) 每個節點在固定週期內通過特定規則選擇幾個節點傳送ping訊息。
3) 接收到ping訊息的節點用pong訊息作為響應。
##當前 redis 叢集有哪些玩法,各自優缺點,場景。
當快取使用 持久化使用
Memcache 的原理,哪些資料適合放在快取中。
基於libevent的事件處理
內建記憶體儲存方式SLab Allocation機制
並不單一的資料刪除機制
基於客戶端的分散式系統
變化頻繁,具有不穩定性的資料,不需要實時入庫, (比如使用者線上
狀態、線上人數…)
入口網站的新聞等,覺得頁面靜態化仍不能滿足要求,可以放入
到memcache中.(配合jquey的ajax請求)
##redis 和 memcached 的記憶體管理的區別。
Memcached預設使用Slab Allocation機制管理記憶體,其主要思想是按照預先規定的大小,將分配的記憶體分割成特定長度的塊以儲存相應長度的key-value資料記錄,以完全解決記憶體碎片問題。
Redis的記憶體管理主要通過原始碼中zmalloc.h和zmalloc.c兩個檔案來實現的。
在Redis中,並不是所有的資料都一直儲存在記憶體中的。這是和Memcached相比一個最大的區別。
http://lib.csdn.net/article/redis/55323
Redis 的併發競爭問題如何解決,瞭解 Redis 事務的 CAS 操作嗎。
Redis為單程式單執行緒模式,採用佇列模式將併發訪問變為序列訪問。Redis本身沒有鎖的概念,Redis對於多個客戶端連線並不存在競爭,但是在Jedis客戶端對Redis進行併發訪問時會發生連線超時、資料轉換錯誤、阻塞、客戶端關閉連線等問題,這些問題均是由於客戶端連線混亂造成。對此有2種解決方法:
1.客戶端角度,為保證每個客戶端間正常有序與Redis進行通訊,對連線進行池化,同時對客戶端讀寫Redis操作採用內部鎖synchronized。
2.伺服器角度,利用setnx實現鎖。
MULTI,EXEC,DISCARD,WATCH 四個命令是 Redis 事務的四個基礎命令。其中:
MULTI,告訴 Redis 伺服器開啟一個事務。注意,只是開啟,而不是執行
EXEC,告訴 Redis 開始執行事務
DISCARD,告訴 Redis 取消事務
WATCH,監視某一個鍵值對,它的作用是在事務執行之前如果監視的鍵值被修改,事務會被取消。
可以利用watch實現cas樂觀鎖
http://wiki.jikexueyuan.com/project/redis/transaction-mechanism.html
http://www.jianshu.com/p/d777eb9f27df
##Redis 的選舉演算法和流程是怎樣的
Raft採用心跳機制觸發Leader選舉。系統啟動後,全部節點初始化為Follower,term為0.節點如果收到了RequestVote或者AppendEntries,就會保持自己的Follower身份。如果一段時間內沒收到AppendEntries訊息直到選舉超時,說明在該節點的超時時間內還沒發現Leader,Follower就會轉換成Candidate,自己開始競選Leader。一旦轉化為Candidate,該節點立即開始下面幾件事情:
1、增加自己的term。
2、啟動一個新的定時器。
3、給自己投一票。
4、向所有其他節點傳送RequestVote,並等待其他節點的回覆。
如果在這過程中收到了其他節點傳送的AppendEntries,就說明已經有Leader產生,自己就轉換成Follower,選舉結束。
如果在計時器超時前,節點收到多數節點的同意投票,就轉換成Leader。同時向所有其他節點傳送AppendEntries,告知自己成為了Leader。
每個節點在一個term內只能投一票,採取先到先得的策略,Candidate前面說到已經投給了自己,Follower會投給第一個收到RequestVote的節點。每個Follower有一個計時器,在計時器超時時仍然沒有接受到來自Leader的心跳RPC, 則自己轉換為Candidate, 開始請求投票,就是上面的的競選Leader步驟。
如果多個Candidate發起投票,每個Candidate都沒拿到多數的投票(Split Vote),那麼就會等到計時器超時後重新成為Candidate,重複前面競選Leader步驟。
Raft協議的定時器採取隨機超時時間,這是選舉Leader的關鍵。每個節點定時器的超時時間隨機設定,隨機選取配置時間的1倍到2倍之間。由於隨機配置,所以各個Follower同時轉成Candidate的時間一般不一樣,在同一個term內,先轉為Candidate的節點會先發起投票,從而獲得多數票。多個節點同時轉換為Candidate的可能性很小。即使幾個Candidate同時發起投票,在該term內有幾個節點獲得一樣高的票數,只是這個term無法選出Leader。由於各個節點定時器的超時時間隨機生成,那麼最先進入下一個term的節點,將更有機會成為Leader。連續多次發生在一個term內節點獲得一樣高票數在理論上機率很小,實際上可以認為完全不可能發生。一般1-2個term類,Leader就會被選出來。
Sentinel的選舉流程
Sentinel叢集正常執行的時候每個節點epoch相同,當需要故障轉移的時候會在叢集中選出Leader執行故障轉移操作。Sentinel採用了Raft協議實現了Sentinel間選舉Leader的演算法,不過也不完全跟論文描述的步驟一致。Sentinel叢集執行過程中故障轉移完成,所有Sentinel又會恢復平等。Leader僅僅是故障轉移操作出現的角色。
選舉流程
1、某個Sentinel認定master客觀下線的節點後,該Sentinel會先看看自己有沒有投過票,如果自己已經投過票給其他Sentinel了,在2倍故障轉移的超時時間自己就不會成為Leader。相當於它是一個Follower。
2、如果該Sentinel還沒投過票,那麼它就成為Candidate。
3、和Raft協議描述的一樣,成為Candidate,Sentinel需要完成幾件事情
1)更新故障轉移狀態為start
2)當前epoch加1,相當於進入一個新term,在Sentinel中epoch就是Raft協議中的term。
3)更新自己的超時時間為當前時間隨機加上一段時間,隨機時間為1s內的隨機毫秒數。
4)向其他節點傳送is-master-down-by-addr命令請求投票。命令會帶上自己的epoch。
5)給自己投一票,在Sentinel中,投票的方式是把自己master結構體裡的leader和leader_epoch改成投給的Sentinel和它的epoch。
4、其他Sentinel會收到Candidate的is-master-down-by-addr命令。如果Sentinel當前epoch和Candidate傳給他的epoch一樣,說明他已經把自己master結構體裡的leader和leader_epoch改成其他Candidate,相當於把票投給了其他Candidate。投過票給別的Sentinel後,在當前epoch內自己就只能成為Follower。
5、Candidate會不斷的統計自己的票數,直到他發現認同他成為Leader的票數超過一半而且超過它配置的quorum(quorum可以參考《redis sentinel設計與實現》)。Sentinel比Raft協議增加了quorum,這樣一個Sentinel能否當選Leader還取決於它配置的quorum。
6、如果在一個選舉時間內,Candidate沒有獲得超過一半且超過它配置的quorum的票數,自己的這次選舉就失敗了。
7、如果在一個epoch內,沒有一個Candidate獲得更多的票數。那麼等待超過2倍故障轉移的超時時間後,Candidate增加epoch重新投票。
8、如果某個Candidate獲得超過一半且超過它配置的quorum的票數,那麼它就成為了Leader。
9、與Raft協議不同,Leader並不會把自己成為Leader的訊息發給其他Sentinel。其他Sentinel等待Leader從slave選出master後,檢測到新的master正常工作後,就會去掉客觀下線的標識,從而不需要進入故障轉移流程。
http://weizijun.cn/2015/04/30/Raft協議實戰之Redis Sentinel的選舉Leader原始碼解析/
redis 的持久化的機制,aof 和 rdb 的區別。
RDB 定時快照方式(snapshot): 定時備份,可能會丟失資料
AOF 基於語句追加方式 只追加寫操作
AOF 持久化和 RDB 持久化的最主要區別在於,前者記錄了資料的變更,而後者是儲存了資料本身
redis 的叢集怎麼同步的資料的。
redis replication redis-migrate-tool等方式
#搜尋
elasticsearch 瞭解多少,說說你們公司 es 的叢集架構,索引資料大小,分片有多少,以及一些調優手段。elasticsearch 的倒排索引是什麼。
ElasticSearch(簡稱ES)是一個分散式、Restful的搜尋及分析伺服器,設計用於分散式計算;能夠達到實時搜尋,穩定,可靠,快速。和Apache Solr一樣,它也是基於Lucence的索引伺服器,而ElasticSearch對比Solr的優點在於:
輕量級:安裝啟動方便,下載檔案之後一條命令就可以啟動。
Schema free:可以向伺服器提交任意結構的JSON物件,Solr中使用schema.xml指定了索引結構。
多索引檔案支援:使用不同的index引數就能建立另一個索引檔案,Solr中需要另行配置。
分散式:Solr Cloud的配置比較複雜。
倒排索引是實現“單詞-文件矩陣”的一種具體儲存形式,通過倒排索引,可以根據單詞快速獲取包含這個單詞的文件列表。倒排索引主要由兩個部分組成:“單詞詞典”和“倒排檔案”。
##elasticsearch 索引資料多了怎麼辦,如何調優,部署。
使用bulk API
初次索引的時候,把 replica 設定為 0
增大 threadpool.index.queue_size
增大 indices.memory.index_buffer_size
增大 index.translog.flush_threshold_ops
增大 index.translog.sync_interval
增大 index.engine.robin.refresh_interval
http://www.jianshu.com/p/5eeeeb4375d4
lucence 內部結構是什麼
索引(Index):
在Lucene中一個索引是放在一個資料夾中的。
如上圖,同一資料夾中的所有的檔案構成一個Lucene索引。
段(Segment):
一個索引可以包含多個段,段與段之間是獨立的,新增新文件可以生成新的段,不同的段可以合併。
如上圖,具有相同字首檔案的屬同一個段,圖中共三個段 “_0” 和 "_1"和“_2”。
segments.gen和segments_X是段的後設資料檔案,也即它們儲存了段的屬性資訊。
文件(Document):
文件是我們建索引的基本單位,不同的文件是儲存在不同的段中的,一個段可以包含多篇文件。
新新增的文件是單獨儲存在一個新生成的段中,隨著段的合併,不同的文件合併到同一個段中。
域(Field):
一篇文件包含不同型別的資訊,可以分開索引,比如標題,時間,正文,作者等,都可以儲存在不同的域裡。
不同域的索引方式可以不同,在真正解析域的儲存的時候,我們會詳細解讀。
詞(Term):
詞是索引的最小單位,是經過詞法分析和語言處理後的字串。
最後
作者:ricky
交流群: 244930845
相關文章
- 2017java筆試題及答案Java筆試
- 前端面試題(附答案)前端面試題
- Oracle面試題附帶答案Oracle面試題
- 基帶面試題附答案面試題
- .net 面試題與測試題(附答案)面試題
- Runtime經典面試題(附答案)面試題
- Python經典面試題(附答案)!Python面試題
- 最新精選Java面試題,附答案!Java面試題
- 最新PHP面試題彙總(附答案)PHP面試題
- 常用JAVA面試題庫(附答案)一Java面試題
- Java基礎面試題整理-50題(附答案)Java面試題
- IT面試題:附帶答案的14道Spring MVC面試題面試題SpringMVC
- 前端面試題 | JS部分(附帶答案)前端面試題JS
- 資料探勘面試筆試題(附答案)面試筆試
- 大資料某公司面試題-附答案大資料面試題
- 50道CSS基礎面試題(附答案)CSS面試題
- 50道 CSS 基礎面試題(附答案CSS面試題
- HTML+CSS+JS面試題(附帶答案)HTMLCSSJS面試題
- 你不知道的面試題(一)附答案面試題
- Android 面試題(附答案) | 掘金技術徵文Android面試題
- 前端一面高頻面試題(附答案)前端面試題
- J2EE面試題集錦(附答案)面試題
- 求職面試常見問題:Python常見面試題全解析附答案求職Python面試題
- 2021精選 Java面試題附答案(一)Java面試題
- 2022年最新iOS面試題(附答案)iOS面試題
- 史上最全Java多執行緒面試題,附答案Java執行緒面試題
- 搜遍全網,整理的MySQL面試題,附答案。MySql面試題
- 附答案!超全SpringBoot面試題總結Spring Boot面試題
- iOS常見基礎面試題(附參考答案)iOS面試題
- Android面試整理(附答案)Android面試
- 乾貨來臨:C語言面試54題附答案C語言面試
- 43道多執行緒面試題,附帶答案(三)執行緒面試題
- 25道多執行緒面試題,附帶答案(一)執行緒面試題
- 43道多執行緒面試題,附帶答案(二)執行緒面試題
- Python資料型別面試題集錦!(附答案)Python資料型別面試題
- Java基礎面試題型整理,附帶答案詳解Java面試題
- 15道基礎滲透測試面試題,附答案!面試題
- Google人工智慧面試·真·題(附參考答案+攻略)Go人工智慧面試