下圖單位是bit,非字節 1B=8bit
html
不能夠,由於String類有final修飾符,而final修飾的類是不能被繼承的,實現細節不容許改變。日常咱們定義的String str=」a」;其實和String str=new String(「a」)仍是有差別的。java
前者默認調用的是String.valueOf來返回String實例對象,至於調用哪一個則取決於你的賦值,好比String num=1,調用的是
public static String valueOf(int i) {
return Integer.toString(i);
}mysql
後者則是調用以下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最後咱們的變量都存儲在一個char數組中
private final char value[];react
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);
}linux
StringBuilder 字符串變量(非線程安全)其自jdk1.5起開始出現。與StringBuffer同樣都繼承和實現了一樣的接口和類,方法除了沒使用synch修飾之外基本一致,不一樣之處在於最後toString的時候,會直接返回一個新對象。
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}git
ArrayList和LinkedList都實現了List接口,有如下的不一樣點:
一、ArrayList是基於索引的數據接口,它的底層是數組。它能夠以O(1)時間複雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每個元素都和它的前一個和後一個元素連接在一塊兒,在這種狀況下,查找某個元素的時間複雜度是O(n)。
二、相對於ArrayList,LinkedList的插入,添加,刪除操做速度更快,由於當元素被添加到集合任意位置的時候,不須要像數組那樣從新計算大小或者是更新索引。
三、LinkedList比ArrayList更佔內存,由於LinkedList爲每個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。github
此題考察的是類加載器實例化時進行的操做步驟(加載–>鏈接->初始化)。
父類靜態代變量、
父類靜態代碼塊、
子類靜態變量、
子類靜態代碼塊、
父類非靜態變量(父類實例成員變量)、
父類構造函數、
子類非靜態變量(子類實例成員變量)、
子類構造函數。
測試demo:http://blog.csdn.net/u014042066/article/details/77574956
參閱個人博客《深刻理解類加載》:http://blog.csdn.net/u014042066/article/details/77394480 web
hashMap是線程不安全的,HashMap是數組+鏈表+紅黑樹(JDK1.8增長了紅黑樹部分)實現的,採用哈希表來存儲的,
參照該連接:https://zhuanlan.zhihu.com/p/21673805
JAVA8 的 ConcurrentHashMap 爲何放棄了分段鎖,有什麼問題嗎,若是你來設計,你如何設計。
參照:https://yq.aliyun.com/articles/36781ajax
TreeMap和LinkedHashMap是有序的(TreeMap默認升序,LinkedHashMap則記錄了插入順序)。
參照:http://uule.iteye.com/blog/1522291redis
一、抽象類和接口都不能直接實例化,若是要實例化,抽象類變量必須指向實現全部抽象方法的子類對象,接口變量必須指向實現全部接口方法的類對象。
二、抽象類要被子類繼承,接口要被類實現。
三、接口只能作方法申明,抽象類中能夠作方法申明,也能夠作方法實現
四、接口裏定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量。
五、抽象類裏的抽象方法必須所有被子類所實現,若是子類不能所有實現父類抽象方法,那麼該子類只能是抽象類。一樣,一個實現接口的時候,如不能所有實現接口方法,那麼該類也只能爲抽象類。
六、抽象方法只能申明,不能實現。abstract void abc();不能寫成abstract void abc(){}。
七、抽象類裏能夠沒有抽象方法
八、若是一個類裏有抽象方法,那麼這個類只能是抽象類
九、抽象方法要被實現,因此不能是靜態的,也不能是私有的。
十、接口可繼承接口,並可多繼承接口,但類只能單根繼承。
繼承指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並能夠增長它本身的新功能的能力,繼承是類與類或者接口與接口之間最多見的關係;在Java中此類關係經過關鍵字extends明確標識,在設計時通常沒有爭議性;
聚合是關聯關係的一種特例,他體現的是總體與部分、擁有的關係,即has-a的關係,此時總體與部分之間是可分離的,他們能夠具備各自的生命週期,部分能夠屬於多個總體對象,也能夠爲多個總體對象共享;好比計算機與CPU、公司與員工的關係等;表如今代碼層面,和關聯關係是一致的,只能從語義級別來區分;
參考:http://www.cnblogs.com/jiqing9006/p/5915023.html
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
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/
同上(基於invocationHandler和methodInterceptor)
同上
類、變量、方法
http://www.importnew.com/7553.html
懶漢式單例,餓漢式單例,雙重檢查等
參考:https://my.oschina.net/dyyweb/blog/609021
同時複寫hashcode和equals方法,優點能夠添加自定義邏輯,且沒必要調用超類的實現。
參照:http://java-min.iteye.com/blog/1416727
訪問修飾符,主要標示修飾塊的做用域,方便隔離防禦
同一個類 同一個包 不一樣包的子類 不一樣包的非子類
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
http://blog.csdn.net/woshixuye/article/details/8230407
同上
類加載無須等到「首次使用該類」時加載,jvm容許預加載某些類。。。。
http://www.cnblogs.com/jasonstorm/p/5663864.html
參考上邊試題
泛型的本質是參數化類型,也就是說所操做的數據類型被指定爲一個參數,泛型的好處是在編譯的時候檢查類型安全,而且全部的強制轉換都是自動和隱式的,以提升代碼的重用率
http://baike.baidu.com/item/java%E6%B3%9B%E5%9E%8B
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
有
底層是基於hashmap實現的
http://wiki.jikexueyuan.com/project/java-collection/hashset.html
什麼是序列化,怎麼序列化,爲何序列化,反序列化會遇到什麼問題,如何解決。
http://www.importnew.com/17964.html
若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError異常。 若是虛擬機在動態擴展棧時沒法申請到足夠的內存空間,則拋出OutOfMemoryError異常。
參照:http://wiki.jikexueyuan.com/project/java-vm/storage.html
eden 和 survior 是按8比1分配的
http://blog.csdn.net/lojze_ly/article/details/49456255
對象誕生即新生代->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
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
內存屏障:爲了保障執行順序和可見性的一條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程序在運行狀態能夠動態的獲取類的全部屬性和方法,並實例化該類,調用方法的功能
http://baike.baidu.com/link?url=C7p1PeLa3ploAgkfAOK-4XHE8HzQuOAB7K5GPcK_zpbAa_Aw-nO3997K1oir8N–1_wxXZfOThFrEcA0LjVP6wNOwidVTkLBzKlQVK6JvXYvVNhDWV9yF-NIOebtg1hwsnagsjUhOE2wxmiup20RRa#7
-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
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垃圾收集週期
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
硬件上選擇,操做系統選擇,版本選擇,jdk選擇,配置jvm參數,配置connector的線程數量,開啓gzip壓縮,trimSpaces,集羣等
http://blog.csdn.net/lifetragedy/article/details/7708724
經過listener入口,核心是在AbstractApplicationContext的refresh方法,在此處進行裝載bean工廠,bean,建立bean實例,攔截器,後置處理器等。
https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/
七種傳播屬性。
事務傳播行爲
所謂事務的傳播行爲是指,若是在開始當前事務以前,一個事務上下文已經存在,此時有若干選項能夠指定一個事務性方法的執行行爲。在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/
編程式和聲明式
同上
核心組件:bean,context,core,單例注入是經過單例beanFactory進行建立,生命週期是在建立的時候經過接口實現開啓,循環注入是經過後置處理器,aop其實就是經過反射進行動態代理,pointcut,advice等。
Aop相關:http://blog.csdn.net/csh624366188/article/details/7651702/
入口是web.xml中配置的ds,ds繼承了HttpServletBean,FrameworkServlet,經過其中的init方法進行初始化裝載bean和實例,initServletBean是實際完成上下文工做和bean初始化的方法。
http://www.mamicode.com/info-detail-512105.html
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/
阻塞式io,非阻塞io,io複用模型,信號驅動io模型,異步io模型。
https://yq.aliyun.com/articles/46404
https://yq.aliyun.com/articles/46402
select的本質是採用32個整數的32位,即32*32= 1024來標識,fd值爲1-1024。當fd的值超過1024限制時,就必須修改FD_SETSIZE的大小。這個時候就能夠標識32*max值範圍的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
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
ps -ef|grep Java
控制權的轉換,根據優先級切換上下文(用戶,寄存器,系統)
http://www.cnblogs.com/kkshaq/p/4544426.html
Linux 實現並無區分這兩個概念(進程和線程)
1. 進程:程序的一次執行
2. 線程: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利用內存柵欄機制來保持變量的一致性。不能代替鎖,其只具有數據可見性一致性,不具有原子性。
http://blog.csdn.net/gongzi2311/article/details/20715185
新建,可運行,運行中, 睡眠,阻塞,等待,死亡。
http://ifeve.com/thread-status
Sleep是休眠線程,wait是等待,sleep是thread的靜態方法,wait則是object的方法。
Sleep依舊持有鎖,並在指定時間自動喚醒。wait則釋放鎖。
http://www.jianshu.com/p/4ec3f4b3903d
首先二者都保持了併發場景下的原子性和可見性,區別則是synchronized的釋放鎖機制是交由其自身控制,且互斥性在某些場景下不符合邏輯,沒法進行干預,不可人爲中斷等。
而lock經常使用的則有ReentrantLock和readwritelock二者,添加了相似鎖投票、定時鎖等候和可中斷鎖等候的一些特性。此外,它還提供了在激烈爭用狀況下更佳的性能。
http://blog.csdn.net/vking_wang/article/details/9952063
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
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
ScheduledThreadPoolExecutor 設置定時,進行調度。
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
http://ifeve.com/java-scheduledthreadpoolexecutor/
單例
經過單例工廠 DefaultSingletonBeanRegistry實現單例
經過保AsyncTaskExecutor持安全
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底層是經過threadlocalMap進行存儲鍵值 每一個ThreadLocal類建立一個Map,而後用線程的ID做爲Map的key,實例對象做爲Map的value,這樣就能達到各個線程的值隔離的效果。
ThreadLocal的做用是提供線程內的局部變量,這種變量在線程的生命週期內起做用,減小同一個線程內多個函數或者組件之間一些公共變量的傳遞的複雜度。
誰設置誰負責移除
http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83]%E8%A7%A3%E5%AF%86ThreadLocal/
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
首先這兩個方法只能在同步代碼塊中調用,wait會釋放掉對象鎖,等待notify喚醒。
http://blog.csdn.net/ithomer/article/details/7685594
根據具體狀況(sleep,wait,join等),酌情選擇notifyAll,notify進行線程喚醒。
http://blog.chinaunix.net/uid-122937-id-215913.html
CountDownLatch是一個同步輔助類,在完成一組正在其餘線程中執行的操做以前,它運行一個或者多個線程一直處於等待狀態。
CyclicBarrier要作的事情是,讓一組線程到達一個屏障(也能夠叫同步點)時被阻塞,直到最後一個線程到達屏障時,屏障纔會開門,全部被屏障攔截的線程纔會繼續運行。
CyclicBarrier初始化的時候,設置一個屏障數。線程調用await()方法的時候,這個線程就會被阻塞,當調用await()的線程數量到達屏障數的時候,主線程就會取消全部被阻塞線程的狀態。
前者是遞減,不可循環,後者是遞加,可循環用
countdowlatch 基於abq cb基於ReentrantLock Condition
http://www.jianshu.com/p/a101ae9797e3
http://blog.csdn.net/tolcf/article/details/50925145
對象鎖和類鎖
https://yq.aliyun.com/articles/24226
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
死鎖問題是多線程特有的問題,它能夠被認爲是線程間切換消耗系統性能的一種極端狀況。在死鎖時,線程間相互等待資源,而又不釋放自身的資源,致使無窮無盡的等待,其結果是系統任務永遠沒法執行完成。死鎖問題是在多線程開發中應該堅定避免和杜絕的問題。
通常來講,要出現死鎖問題須要知足如下條件:
1. 互斥條件:一個資源每次只能被一個線程使用。
2. 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
3. 不剝奪條件:進程已得到的資源,在未使用完以前,不能強行剝奪。
4. 循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
只要破壞死鎖 4 個必要條件之一中的任何一個,死鎖問題就能被解決。
https://www.ibm.com/developerworks/cn/java/j-lo-deadlock/
此問題的本質是保持順序執行。能夠使用executors
HTTP 1.0主要有如下幾點變化:
請求和相應能夠因爲多行首部字段構成
響應對象前面添加了一個響應狀態行
響應對象不侷限於超文本
服務器與客戶端之間的鏈接在每次請求以後都會關閉
實現了Expires等傳輸內容的緩存控制
內容編碼Accept-Encoding、字符集Accept-Charset等協商內容的支持
這時候開始有了請求及返回首部的概念,開始傳輸不限於文本(其餘二進制內容)
HTTP 1.1加入了不少重要的性能優化:持久鏈接、分塊編碼傳輸、字節範圍請求、加強的緩存機制、傳輸編碼及請求管道。
http://imweb.io/topic/554c5879718ba1240cc1dd8a
第一次握手(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 狀態。
兩次後會重傳直到超時。若是多了會有大量半連接阻塞隊列。
http://www.javashuo.com/article/p-nqnxppnr-w.html
https://hit-alibaba.github.io/interview/basic/network/TCP.html
TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。
1xx:信息,請求收到,繼續處理
2xx:成功,行爲被成功地接受、理解和採納
3xx:重定向,爲了完成請求,必須進一步執行的動做
4xx:客戶端錯誤,請求包含語法錯誤或者請求沒法實現
5xx:服務器錯誤,服務器不能實現一種明顯無效的請求
200 ok 一切正常
302 Moved Temporatily 文件臨時移出
404 not found
https://my.oschina.net/gavinjin/blog/42856
Dns解析–>端口分析–>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/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE
沒法被瀏覽器緩存的請求:
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://www.w3school.com.cn/tags/html_ref_httpmethods.asp
http://www.360doc.com/content/12/0612/14/8093902_217673378.shtml
參考上面
加密方式是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緩存數據
final int cacheSize = 100;
Map
Redis生成,mongodb的objectId,zk生成
http://www.cnblogs.com/haoxinyue/p/5208136.html
分流 – 限流–異步–公平性(只能參加一次)–用戶體驗(第幾位,多少分鐘,一搶完)
容錯處理
Redis 隊列 mysql
30分鐘關閉 能夠藉助redis的發佈訂閱機制 在失效時進行後續操做,其餘mq也能夠
http://www.infoq.com/cn/articles/yhd-11-11-queuing-system-design
首先分佈式鎖實現常見的有數據庫鎖(表記錄),緩存鎖,基於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實現算法。知足平衡性 單調性 分散性 和負載。
http://blog.csdn.net/cywosp/article/details/23397179/
REST 指的是一組架構約束條件和原則。知足這些約束條件和原則的應用程序或設計就是 RESTful。
http://baike.baidu.com/link?url=fTSAdL-EyYvTp9z7mZsCOdS3kbs4VKKAnpBLg3WS_1Z4cmLMp3S-zrjcy5wakLTO5AIoPTopWVkG-IenloPKxq
服務器內核調優(tcp,文件數),客戶端調優,框架選擇(netty)
緩存雪崩多是由於數據未加載到緩存中,或者緩存同一時間大面積的失效,從而致使全部請求都去查數據庫,致使數據庫CPU和內存負載太高,甚至宕機。
解決思路:
1,採用加鎖計數,或者使用合理的隊列數量來避免緩存失效時對數據庫形成太大的壓力。這種辦法雖然能緩解數據庫的壓力,可是同時又下降了系統的吞吐量。
2,分析用戶行爲,儘可能讓失效時間點均勻分佈。避免緩存雪崩的出現。
3,若是是由於某臺緩存服務器宕機,能夠考慮作主備,好比:redis主備,可是雙緩存涉及到更新事務的問題,update可能讀到髒數據,須要好好解決。
http://www.cnblogs.com/jinjiangongzuoshi/archive/2016/03/03/5240280.html
MESI是四種緩存段狀態的首字母縮寫,任何多核系統中的緩存段都處於這四種狀態之一。我將以相反的順序逐個講解,由於這個順序更合理:
失效(Invalid)緩存段,要麼已經不在緩存中,要麼它的內容已通過時。爲了達到緩存的目的,這種狀態的段將會被忽略。一旦緩存段被標記爲失效,那效果就等同於它歷來沒被加載到緩存中。
共享(Shared)緩存段,它是和主內存內容保持一致的一份拷貝,在這種狀態下的緩存段只能被讀取,不能被寫入。多組緩存能夠同時擁有針對同一內存地址的共享緩存段,這就是名稱的由來。
獨佔(Exclusive)緩存段,和S狀態同樣,也是和主內存內容保持一致的一份拷貝。區別在於,若是一個處理器持有了某個E狀態的緩存段,那其餘處理器就不能同時持有它,因此叫「獨佔」。這意味着,若是其餘處理器本來也持有同一緩存段,那麼它會立刻變成「失效」狀態。
已修改(Modified)緩存段,屬於髒段,它們已經被所屬的處理器修改了。若是一個段處於已修改狀態,那麼它在其餘處理器緩存中的拷貝立刻會變成失效狀態,這個規律和E狀態同樣。此外,已修改緩存段若是被丟棄或標記爲失效,那麼先要把它的內容回寫到內存中——這和回寫模式下常規的髒段處理方式同樣。
哈希(Hash)算法,即散列函數。 它是一種單向密碼體制,即它是一個從明文到密文的不可逆的映射,只有加密過程,沒有解密過程。 同時,哈希函數能夠將任意長度的輸入通過變化之後獲得固定長度的輸出
MD4 MD5 SHA
http://blog.jobbole.com/106733/
Paxos算法是萊斯利·蘭伯特(Leslie Lamport,就是 LaTeX 中的」La」,此人如今在微軟研究院)於1990年提出的一種基於消息傳遞的一致性算法。
http://baike.baidu.com/item/Paxos%20%E7%AE%97%E6%B3%95
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[]是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。
在集羣負載均衡時,Dubbo提供了多種均衡策略,缺省爲random隨機調用。
Random LoadBalance:隨機,按權重比率設置隨機機率。
RoundRobin LoadBalance:輪循,按公約後的權重比率設置輪循比率。
LeastActive LoadBalance:最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差。使慢的提供者收到更少請求,由於越慢的提供者的調用先後計數差會越大。
ConsistentHash LoadBalance:一致性Hash,相同參數的請求老是發到同一提供者。當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更。
快速失敗,只發起一次調用,失敗當即報錯。
http://www.javashuo.com/article/p-kgamlnna-ep.html
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等
能夠經過token值進行防止重複提交,存放到redis中,在表單初始化的時候隱藏在表單中,添加的時候在移除。判斷這個狀態便可防止重複提交。
如何看待緩存的使用(本地緩存,集中式緩存),簡述本地緩存和集中式緩存和優缺點。本地緩存在併發使用時的注意事項。
·未提交讀(Read Uncommitted):容許髒讀,也就是可能讀取到其餘會話中未提交事務修改的數據
·提交讀(Read Committed):只能讀取到已經提交的數據。Oracle等多數數據庫默認都是該級別 (不重複讀)
·可重複讀(Repeated Read):可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB默認級別。在SQL標準中,該隔離級別消除了不可重複讀,可是還存在幻象讀
·串行讀(Serializable):徹底串行化的讀,每次讀都須要得到表級共享鎖,讀寫相互都會阻塞
MYSQL默認是RepeatedRead級別
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/%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E
使用悲觀鎖 悲觀鎖本質是當前只有一個線程執行操做,結束了喚醒其餘線程進行處理。
也能夠緩存隊列中鎖定主鍵。
樂觀鎖是設定每次修改都不會衝突,只在提交的時候去檢查,悲觀鎖設定每次修改都會衝突,持有排他鎖。
行級鎖分爲共享鎖和排他鎖兩種 共享鎖又稱讀鎖 排他鎖又稱寫鎖
http://www.jianshu.com/p/f40ec03fd0e8
查看慢日誌(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
產生死鎖的緣由主要是:
(1)系統資源不足。
(2) 進程運行推動的順序不合適。
(3)資源分配不當等。
若是系統資源充足,進程的資源請求都可以獲得知足,死鎖出現的可能性就很低,不然就會因爭奪有限的資源而陷入死鎖。其次,進程運行推動順序與速度不一樣,也可能產生死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
(3) 不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
(4) 循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不知足,就不會發生死鎖。
這裏提供兩個解決數據庫死鎖的方法:
1)重啓數據庫(誰用誰知道)
2)殺掉搶資源的進程:
先查哪些進程在搶資源:SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
殺掉它們:Kill trx_mysql_thread_id;
索引是經過複雜的算法,提升數據查詢性能的手段。從磁盤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
「聚簇」就是索引和記錄緊密在一塊兒。
非聚簇索引 索引文件和數據文件分開存放,索引文件的葉子頁只保存了主鍵值,要定位記錄還要去查找相應的數據塊。
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樹爲了保持樹的性質須要進行旋轉同樣!
A,atomic,原子性,要麼都提交,要麼都失敗,不能一部分紅功,一部分失敗。
C,consistent,一致性,事物開始及結束後,數據的一致性約束沒有被破壞
I,isolation,隔離性,併發事物間相互不影響,互不干擾。
D,durability,持久性,已經提交的事物對數據庫所作的更新必須永久保存。即使發生崩潰,也不能被回滾或數據丟失。
避免在where子句中對字段進行is null判斷
應儘可能避免在where 子句中使用!=或<>操做符,不然將引擎放棄使用索引而進行全表掃描。
避免在where 子句中使用or 來鏈接條件
in 和not in 也要慎用
Like查詢(非左開頭)
使用NUM=@num參數這種
where 子句中對字段進行表達式操做num/2=XX
在where子句中對字段進行函數操做
因爲複合索引的組合索引,相似多個木板拼接在一塊兒,若是中間斷了就沒法用了,因此要能用到複合索引,首先開頭(第一列)要用上,好比index(a,b) 這種,咱們能夠select table tname where a=XX 用到第一列索引 若是想用第二列 能夠 and b=XX 或者and b like‘TTT%’
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
根據實際狀況說明
咱們公司用activeMQ 由於業務比較簡單 只有轉碼功能,而amq比較簡單
若是是分佈式的建議用kafka
http://blog.csdn.net/sunxinhere/article/details/7968886
基本都是對數據進行持久化,多盤存儲
集羣是保證服務可靠性的一種方式,同時能夠經過水平擴展以提高消息吞吐能力。RabbitMQ是用分佈式程序設計語言erlang開發的,因此天生就支持集羣。接下來,將介紹RabbitMQ分佈式消息處理方式、集羣模式、節點類型,並動手搭建一個高可用集羣環境,最後經過java程序來驗證集羣的高可用性。
1. 三種分佈式消息處理方式
RabbitMQ分佈式的消息處理方式有如下三種:
一、Clustering:不支持跨網段,各節點需運行同版本的Erlang和RabbitMQ, 應用於同網段局域網。
二、Federation:容許單臺服務器上的Exchange或Queue接收發布到另外一臺服務器上Exchange或Queue的消息, 應用於廣域網,。
三、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/
LPUSH LPUSHX RPUSH RPUSHX LPOP RPOP BLPOP BRPOP LLEN LRANGE
https://redis.readthedocs.io/en/2.4/list.html
字符串(strings):存儲整數(好比計數器)和字符串(廢話。。),有些公司也用來存儲json/pb等序列化數據,並不推薦,浪費內存
哈希表(hashes):存儲配置,對象(好比用戶、商品),優勢是能夠存取部分key,對於常常變化的或者部分key要求atom操做的適合
列表(lists):能夠用來存最新用戶動態,時間軸,優勢是有序,肯定是元素可重複,不去重
集合(sets):無序,惟一,對於要求嚴格惟一性的能夠使用
有序集合(sorted sets):集合的有序版,很好用,對於排名之類的複雜場景能夠考慮https://redis.readthedocs.io/en/2.4/list.html
持久化方式: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
集羣方式的區別,3採用Cluster,2採用客戶端分區方案和代理方案
通訊過程說明:
1) 集羣中的每一個節點都會單獨開闢一個TCP通道, 用於節點之間彼此
通訊, 通訊端口號在基礎端口上加10000。
2) 每一個節點在固定週期內經過特定規則選擇幾個節點發送ping消息。
3) 接收到ping消息的節點用pong消息做爲響應。
當緩存使用 持久化使用
基於libevent的事件處理
內置內存存儲方式SLab Allocation機制
並不單一的數據刪除機制
基於客戶端的分佈式系統
變化頻繁,具備不穩定性的數據,不須要實時入庫, (好比用戶在線
狀態、在線人數..)
門戶網站的新聞等,以爲頁面靜態化仍不能知足要求,能夠放入
到memcache中.(配合jquey的ajax請求)
Memcached默認使用Slab Allocation機制管理內存,其主要思想是按照預先規定的大小,將分配的內存分割成特定長度的塊以存儲相應長度的key-value數據記錄,以徹底解決內存碎片問題。
Redis的內存管理主要經過源碼中zmalloc.h和zmalloc.c兩個文件來實現的。
在Redis中,並非全部的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。
http://lib.csdn.net/article/redis/55323
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
Raft採用心跳機制觸發Leader選舉。系統啓動後,所有節點初始化爲Follower,term爲0.節點若是收到了RequestVote或者AppendEntries,就會保持本身的Follower身份。若是一段時間內沒收到AppendEntries消息直到選舉超時,說明在該節點的超時時間內還沒發現Leader,Follower就會轉換成Candidate,本身開始競選Leader。一旦轉化爲Candidate,該節點當即開始下面幾件事情:
一、增長本身的term。
二、啓動一個新的定時器。
三、給本身投一票。
四、向全部其餘節點發送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僅僅是故障轉移操做出現的角色。
選舉流程
一、某個Sentinel認定master客觀下線的節點後,該Sentinel會先看看本身有沒有投過票,若是本身已經投過票給其餘Sentinel了,在2倍故障轉移的超時時間本身就不會成爲Leader。至關於它是一個Follower。
二、若是該Sentinel還沒投過票,那麼它就成爲Candidate。
三、和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。
四、其餘Sentinel會收到Candidate的is-master-down-by-addr命令。若是Sentinel當前epoch和Candidate傳給他的epoch同樣,說明他已經把本身master結構體裏的leader和leader_epoch改爲其餘Candidate,至關於把票投給了其餘Candidate。投過票給別的Sentinel後,在當前epoch內本身就只能成爲Follower。
五、Candidate會不斷的統計本身的票數,直到他發現認同他成爲Leader的票數超過一半並且超過它配置的quorum(quorum能夠參考《redis sentinel設計與實現》)。Sentinel比Raft協議增長了quorum,這樣一個Sentinel可否當選Leader還取決於它配置的quorum。
六、若是在一個選舉時間內,Candidate沒有得到超過一半且超過它配置的quorum的票數,本身的此次選舉就失敗了。
七、若是在一個epoch內,沒有一個Candidate得到更多的票數。那麼等待超過2倍故障轉移的超時時間後,Candidate增長epoch從新投票。
八、若是某個Candidate得到超過一半且超過它配置的quorum的票數,那麼它就成爲了Leader。
九、與Raft協議不一樣,Leader並不會把本身成爲Leader的消息發給其餘Sentinel。其餘Sentinel等待Leader從slave選出master後,檢測到新的master正常工做後,就會去掉客觀下線的標識,從而不須要進入故障轉移流程。
http://weizijun.cn/2015/04/30/Raft%E5%8D%8F%E8%AE%AE%E5%AE%9E%E6%88%98%E4%B9%8BRedis%20Sentinel%E7%9A%84%E9%80%89%E4%B8%BELeader%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/
RDB 定時快照方式(snapshot): 定時備份,可能會丟失數據
AOF 基於語句追加方式 只追加寫操做
AOF 持久化和 RDB 持久化的最主要區別在於,前者記錄了數據的變動,然後者是保存了數據自己
redis replication redis-migrate-tool等方式
ElasticSearch(簡稱ES)是一個分佈式、Restful的搜索及分析服務器,設計用於分佈式計算;可以達到實時搜索,穩定,可靠,快速。和Apache Solr同樣,它也是基於Lucence的索引服務器,而ElasticSearch對比Solr的優勢在於:
輕量級:安裝啓動方便,下載文件以後一條命令就能夠啓動。 Schema free:能夠向服務器提交任意結構的JSON對象,Solr中使用schema.xml指定了索引結構。 多索引文件支持:使用不一樣的index參數就能建立另外一個索引文件,Solr中須要另行配置。 分佈式:Solr Cloud的配置比較複雜。
倒排索引是實現「單詞-文檔矩陣」的一種具體存儲形式,經過倒排索引,能夠根據單詞快速獲取包含這個單詞的文檔列表。倒排索引主要由兩個部分組成:「單詞詞典」和「倒排文件」。
使用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
索引(Index): 在Lucene中一個索引是放在一個文件夾中的。 如上圖,同一文件夾中的全部的文件構成一個Lucene索引。 段(Segment): 一個索引能夠包含多個段,段與段之間是獨立的,添加新文檔能夠生成新的段,不一樣的段能夠合併。 如上圖,具備相同前綴文件的屬同一個段,圖中共三個段 「_0」 和 「_1」和「_2」。 segments.gen和segments_X是段的元數據文件,也即它們保存了段的屬性信息。 文檔(Document): 文檔是咱們建索引的基本單位,不一樣的文檔是保存在不一樣的段中的,一個段能夠包含多篇文檔。 新添加的文檔是單獨保存在一個新生成的段中,隨着段的合併,不一樣的文檔合併到同一個段中。 域(Field): 一篇文檔包含不一樣類型的信息,能夠分開索引,好比標題,時間,正文,做者等,均可以保存在不一樣的域裏。 不一樣域的索引方式能夠不一樣,在真正解析域的存儲的時候,咱們會詳細解讀。 詞(Term): 詞是索引的最小單位,是通過詞法分析和語言處理後的字符串。