阿里大佬總結的Java面試資料_第1頁
阿里大佬總結的Java面試資料_第2頁
阿里大佬總結的Java面試資料_第3頁
阿里大佬總結的Java面試資料_第4頁
阿里大佬總結的Java面試資料_第5頁
已閱讀5頁,還剩278頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1.目錄目錄 1JVM 192.1. 線程 20JVM內(nèi)存區(qū)域 21程序計數(shù)器(線程私有) 22虛擬機棧(線程私有) 22本地方法區(qū)(線程私有) 23堆(Heap-線程共享)-運行時數(shù)據(jù)區(qū) 23方法區(qū)/永久代(線程共享) 23JVM運行時內(nèi)存 24新生代 24Eden區(qū) 24ServivorFrom 24ServivorTo 24MinorGC的過程(復制->清空->互換) 24復制到ServicorTo,年齡+1 252:清空eden、servicorFrom 253:ServicorTo和ServicorFrom互換 25老年代 25永久代 25JAVA8與元數(shù)據(jù) 25垃圾回收與算法 26如何確定垃圾 26引用計數(shù)法 26可達性分析 26標記清除算法(Mark-Sweep) 27復制算法(copying) 27標記整理算法(Mark-Compact) 28分代收集算法 29新生代與復制算法 29老年代與標記復制算法 29JAVA四中引用類型 30強引用 30軟引用 30弱引用 30虛引用 30GC分代收集算法VS分區(qū)收集算法 30分代收集算法 30在新生代-復制算法 30在老年代-標記整理算法 30分區(qū)收集算法 31GC垃圾收集器 31Serial垃圾收集器(單線程、復制算法) 31ParNew垃圾收集器(Serial+多線程) 31ParallelScavenge收集器(多線程復制算法、高效) 32SerialOld收集器(單線程標記整理算法) 32ParallelOld收集器(多線程標記整理算法) 33CMS收集器(多線程標記清除算法) 33初始標記 33并發(fā)標記 34重新標記 34并發(fā)清除 34G1收集器 34JAVAIO/NIO 34阻塞IO模型 34非阻塞IO模型 35多路復用IO模型 35信號驅動IO模型 36異步IO模型 36JAVAIO包 36JAVANIO 37NIO的緩沖區(qū) 38NIO的非阻塞 38Channel 40Buffer 40Selector 40JVM類加載機制 4.加載 4.驗證 4.準備 4.解析 41符號引用 42直接引用 42初始化 42類構造器<client> 42類加載器 42啟動類加載器(BootstrapClassLoader) 43擴展類加載器(ExtensionClassLoader) 43應用程序類加載器(ApplicationClassLoader): 43雙親委派 43OSGI(動態(tài)模型系統(tǒng)) 44動態(tài)改變構造 44模塊化編程與熱插拔 44JAVA集合 45接口繼承關系和實現(xiàn) 45LIST 47ArrayList(數(shù)組) 47Vector(數(shù)組實現(xiàn)、線程同步) 47LinkList(鏈表) 47SET 48HashSet(Hash表) 48TreeSet(二叉樹) 49LinkHashSet(HashSet+LinkedHashMap) 49MAP 50HashMap(數(shù)組+鏈表+紅黑樹) 50JAVA7實現(xiàn) 50JAVA8實現(xiàn) 51ConcurrentHashMap 51Segment段 51繼承ReentrantLock加鎖) 5.并行度(默認16) 5.Java8實現(xiàn)(引入了紅黑樹) 52HashTable(線程安全) 53TreeMap(可排序) 53LinkHashMap(記錄插入順序) 53JAVA多線程并發(fā) 54JAVA并發(fā)知識庫 54JAVA線程實現(xiàn)/創(chuàng)建方式 54繼承Thread類 54實現(xiàn)Runnable接口。 54ExecutorService、Callable<Class>、Future有返回值線程 55基于線程池的方式 564種線程池 56newCachedThreadPool 57newFixedThreadPool 57newScheduledThreadPool 58newSingleThreadExecutor 58線程生命周期(狀態(tài)) 58新建狀態(tài)(NEW) 58就緒狀態(tài)(RUNNABLE): 59運行狀態(tài)(RUNNING): 59阻塞狀態(tài)(BLOCKED): 59等待阻塞(o.wait->等待對列): 59同步阻塞(lock->鎖池) 59其他阻塞(sleep/join) 59線程死亡(DEAD) 59正常結束 59異常結束 59調(diào)用stop 59終止線程4種方式 60正常運行結束 60使用退出標志退出線程 60Interrupt方法結束線程 60stop方法終止線程(線程不安全) 61sleep與wait區(qū)別 61start與run區(qū)別 62JAVA后臺線程 62JAVA鎖 63樂觀鎖 63悲觀鎖 63自旋鎖 63自旋鎖的優(yōu)缺點 63自旋鎖時間閾值(1.6引入了適應性自旋鎖) 63自旋鎖的開啟 64Synchronized同步鎖 64Synchronized作用范圍 64Synchronized核心組件 64Synchronized實現(xiàn) 64ReentrantLock 66Lock接口的主要方法 66非公平鎖 66公平鎖 67ReentrantLock與synchronized 67ReentrantLock實現(xiàn) 67Condition類和Object類鎖方法區(qū)別區(qū)別 68tryLock和lock和lockInterruptibly的區(qū)別 68Semaphore信號量 68實現(xiàn)互斥鎖(計數(shù)器為1) 68代碼實現(xiàn) 68Semaphore與ReentrantLock 69AtomicInteger 69可重入鎖(遞歸鎖) 69公平鎖與非公平鎖 70公平鎖(Fair) 70非公平鎖(Nonfair) 70ReadWriteLock讀寫鎖 70讀鎖 70寫鎖 70共享鎖和獨占鎖 70獨占鎖 70共享鎖 70重量級鎖(MutexLock) 71輕量級鎖 71鎖升級 71偏向鎖 71分段鎖 71鎖優(yōu)化 71減少鎖持有時間 72減小鎖粒度 72鎖分離 72鎖粗化 72鎖消除 72線程基本方法 72線程等待(wait) 73線程睡眠(sleep) 73線程讓步(yield) 73線程中斷(interrupt) 73Join等待其他線程終止 74為什么要用join()方法? 74線程喚醒(notify) 74其他方法: 74線程上下文切換 7. 進程 75上下文 75寄存器 75程序計數(shù)器 75PCB-“切換楨” 75上下文切換的活動: 76引起線程上下文切換的原因 76同步鎖與死鎖 76同步鎖 7. 死鎖 76線程池原理 76線程復用 76線程池的組成 76拒絕策略 78Java線程池工作過程 78JAVA阻塞隊列原理 79阻塞隊列的主要方法 80插入操作: 80獲取數(shù)據(jù)操作: 81Java中的阻塞隊列 81ArrayBlockingQueue(公平、非公平) 82LinkedBlockingQueue(兩個獨立鎖提高并發(fā)) 82PriorityBlockingQueue(compareTo排序實現(xiàn)優(yōu)先) 82DelayQueue(緩存失效、定時任務) 82SynchronousQueue(不存儲數(shù)據(jù)、可用于傳遞數(shù)據(jù)) 83LinkedTransferQueue 83LinkedBlockingDeque 83CyclicBarrier、CountDownLatch、Semaphore的用法 84CountDownLatch(線程計數(shù)器) 84CyclicBarrier(回環(huán)柵欄-等待至barrier狀態(tài)再全部同時執(zhí)行) 84Semaphore(信號量-控制同時訪問的線程個數(shù)) 85volatile關鍵字的作用(變量可見性、禁止重排序) 87變量可見性 87禁止重排序 87比sychronized更輕量級的同步鎖 87適用場景 87如何在兩個線程之間共享數(shù)據(jù) 88將數(shù)據(jù)抽象成一個類,并將數(shù)據(jù)的操作作為這個類的方法 88Runnable對象作為一個類的內(nèi)部類 89ThreadLocal作用(線程本地存儲) 90ThreadLocalMap(線程的一個屬性) 90使用場景 91synchronized和ReentrantLock的區(qū)別 91兩者的共同點: 91兩者的不同點: 92ConcurrentHashMap并發(fā) 92減小鎖粒度 92ConcurrentHashMap分段鎖 92數(shù)組結構和HashEntry數(shù)組結構組成 93Java中用到的線程調(diào)度 93搶占式調(diào)度: 93協(xié)同式調(diào)度: 93JVM的線程調(diào)度實現(xiàn)(搶占式調(diào)度) 94線程讓出cpu的情況: 94進程調(diào)度算法 94優(yōu)先調(diào)度算法 94高優(yōu)先權優(yōu)先調(diào)度算法 95基于時間片的輪轉調(diào)度算法 96什么是CAS(比較并交換-樂觀鎖機制-鎖自旋) 96概念及特性 96原子包java.util.concurrent.atomic(鎖自旋) 97ABA問題 98什么是AQS(抽象的隊列同步器) 98Exclusive獨占資源-ReentrantLock 99Share共享資源-Semaphore/CountDownLatch 99是ABS核心(state資源狀態(tài)計數(shù)) 100ReentrantReadWriteLock實現(xiàn)獨占和共享兩種方式 100JAVA基礎 101JAVA異常分類及處理 10. 概念 101異常分類 101Error 101Exception(RuntimeException、CheckedException) 101異常的處理方式 102進行具體處理,而是繼續(xù)拋給調(diào)用者(throw,throws) 102trycatch捕獲異常針對性處理方式 102Throw和throws的區(qū)別: 102位置不同 102功能不同: 102JAVA反射 103動態(tài)語言 103反射機制概念(運行狀態(tài)中知道類所有的屬性和方法) 103反射的應用場合 103編譯時類型和運行時類型 103的編譯時類型無法獲取具體方法 104Java反射API 104反射API用來生成JVM中的類、接口或則對象的信息。 104反射使用步驟(獲取Class對象、調(diào)用對象方法) 104獲取Class對象的3種方法 104調(diào)用某個對象的getClass()方法 104性來獲取該類對應的Class對象 104使用Class類中的forName()靜態(tài)方法(最安全/性能最好) 104創(chuàng)建對象的兩種方法 105Class對象的newInstance() 105調(diào)用Constructor對象的newInstance() 105JAVA注解 10.概念 1064種標準元注解 106@Target修飾的對象范圍 106@Retention定義被保留的時間長短 106@Documented描述-javadoc 106@Inherited闡述了某個被標注的類型是被繼承的 106注解處理器 107JAVA內(nèi)部類 109靜態(tài)內(nèi)部類 109成員內(nèi)部類 110局部內(nèi)部類(定義在方法中的類) 110部類(要繼承一個父類或者實現(xiàn)一個接口、直接使用new來生成一個對象的引用) 111JAVA泛型 1. 泛型方法(<E>) 1.泛型類<T> 112類型通配符? 113類型擦除 113JAVA序列化(創(chuàng)建可復用的Java對象) 113保存(持久化)對象及其狀態(tài)到內(nèi)存或者磁盤 113序列化對象以字節(jié)數(shù)組保持-靜態(tài)成員不保存 113序列化用戶遠程對象傳輸 113Serializable實現(xiàn)序列化 113對對象進行序列化及反序列化 113自定義序列化策略 113序列化ID 113序列化并不保存靜態(tài)變量 114序列化子父類說明 114Transient關鍵字阻止該變量被序列化到文件中 114JAVA復制 114直接賦值復制 114淺復制(復制引用但不復制引用的對象) 114深復制(復制對象和其應用對象) 115序列化(深clone一中實現(xiàn)) 115SPRING原理 116Spring特點 1. 輕量級 116控制反轉 116面向切面 1. 容器 1. 框架集合 116Spring核心組件 117Spring常用模塊 117Spring主要包 118Spring常用注解 118Spring第三方結合 119SpringIOC原理 1.概念 120Spring容器高層視圖 120IOC容器實現(xiàn) 120BeanFactory-框架基礎設施 1201.1..1.1.1BeanDefinitionRegistry注冊表 1211.1..1.1.2BeanFactory頂層接口 1211.1..1.1.3ListableBeanFactory 1211.1..1.1.4HierarchicalBeanFactory父子級聯(lián) 1211.1..1.1.5ConfigurableBeanFactory 1211.1..1.1.6AutowireCapableBeanFactory自動裝配 122運行期間注冊單例Bean 1221.1..1.1.8依賴日志框框 122ApplicationContext面向開發(fā)應用 122WebApplication體系架構 123SpringBean作用域 123singleton:單例模式(多線程下不安全) 123prototype:原型模式每次使用時創(chuàng)建 124Request:一次request一個實例 124session 124globalSession 124SpringBean生命周期 124實例化 124IOC依賴注入 124setBeanName實現(xiàn) 124BeanFactoryAware實現(xiàn) 124ApplicationContextAware實現(xiàn) 125postProcessBeforeInitialization接口實現(xiàn)-初始化預處理 125init-method 125postProcessAfterInitialization 125Destroy過期自動清理階段 125destroy-method自配置清理 125Spring依賴注入四種方式 126構造器注入 126setter方法注入 127靜態(tài)工廠注入 127實例工廠 1275種不同方式的自動裝配 128SpringAPO原理 12.概念 12.AOP核心概念 129AOP兩種代理方式 130JDK動態(tài)接口代理 130CGLib動態(tài)代理 131實現(xiàn)原理 131SpringMVC原理 132MVC流程 132請求到DispatcherServlet 133HandlerMapping尋找處理器 133調(diào)用處理器Controller 133邏輯處理后,返回ModelAndView 133DispatcherServlet查詢ModelAndView 133ModelAndView反饋瀏覽器 13.MVC常用注解 133SpringBoot原理 134創(chuàng)建獨立的Spring應用程序 134嵌入的Tomcat,無需部署WAR文件 134簡化Maven配置 134自動配置Spring 134提供生產(chǎn)就緒型功能,如指標,健康檢查和外部配置 134成和對XML沒有要求配置[1] 134JPA原理 13. 事務 13. 本地事務 13. 分布式事務 13. 兩階段提交 1361準備階段 1362提交階段: 136Mybatis緩存 137Mybatis的一級緩存原理(sqlsession級別) 138二級緩存原理(mapper基本) 138具體使用需要配置: 139Tomcat架構 1397. 微服務 140服務注冊發(fā)現(xiàn) 140客戶端注冊(zookeeper) 140第三方注冊(獨立的服務Registrar) 140客戶端發(fā)現(xiàn) 141服務端發(fā)現(xiàn) 142Consul 142Eureka 142SmartStack 142Etcd 142API網(wǎng)關 142請求轉發(fā) 143響應合并 143協(xié)議轉換 143數(shù)據(jù)轉換 143安全認證 144配置中心 144zookeeper配置中心 144配置中心數(shù)據(jù)分類 144事件調(diào)度(kafka) 144服務跟蹤(starter-sleuth) 144服務熔斷(Hystrix) 145Hystrix斷路器機制 146API管理 1468. NETTY與RPC 147Netty原理 147Netty高性能 147多路復用通訊方式 147異步通訊NIO 148零拷貝(DIRECTBUFFERS使用堆外直接內(nèi)存) 149內(nèi)存池(基于內(nèi)存池的緩沖區(qū)重用機制) 149高效的Reactor線程模型 149Reactor單線程模型 149Reactor多線程模型 150主從Reactor多線程模型 150無鎖設計、線程綁定 151高性能的序列化框架 151小包封大包,防止網(wǎng)絡阻塞 152軟中斷Hash值和CPU綁定 152NettyRPC實現(xiàn) 15.概念 152關鍵技術 152核心流程 15.消息編解碼 153息數(shù)據(jù)結構(接口名稱+方法名+參數(shù)類型和參數(shù)值+超時時間+requestID) 153序列化 15.通訊過程 154核心問題(線程暫停、消息亂序) 154通訊流程 154requestID生成-AtomicLong 154局ConcurrentHashMap 154的鎖并自旋wait 154到消息,找到callback上的鎖并喚醒 155RMI實現(xiàn)方式 155實現(xiàn)步驟 155ProtoclolBuffer 15.特點 157Thrift 1579. 網(wǎng)絡 159網(wǎng)絡7層架構 159TCP/IP原理 160網(wǎng)絡訪問層(NetworkAccessLayer) 160網(wǎng)絡層(InternetLayer) 160傳輸層(TramsportLayer-TCP/UDP) 160應用層(ApplicationLayer) 160TCP三次握手/四次揮手 161數(shù)據(jù)包說明 161三次握手 162四次揮手 163原理 164傳輸流程 1641:地址解析 1642:封裝請求數(shù)據(jù)包 1653:封裝成TCP包并建立連接 1654:客戶機發(fā)送請求命 1655:服務器響應 1656:服務器關閉TCP連接 165狀態(tài) 165S 166建立連接獲取證書 167證書驗證 167數(shù)據(jù)加密和傳輸 167CDN原理 167分發(fā)服務系統(tǒng) 167負載均衡系統(tǒng): 16.管理系統(tǒng): 16810. 日志 16910.1.1.Slf4j 16910.1.2.Log4j 169LogBack 169Logback優(yōu)點 16910.1.4.ELK 170ZOOKEEPER 17111.1.1.Zookeeper概念 171Zookeeper角色 171Leader 171Follower 171Observer 171ZAB協(xié)議 172事務請求計數(shù)器+epoch) 172epoch 172Zab協(xié)議有兩種模式-恢復模式(選主)、廣播模式(同步) 172ZAB協(xié)議4階段 172Leaderelection(選舉階段-選出準Leader) 172接受提議、生成epoch、接受epoch) 173同步階段-同步follower副本) 173Broadcast(廣播階段-leader消息廣播) 173發(fā)現(xiàn)階段和同步合并為RecoveryPhase(恢復階段)) 173投票機制 173Zookeeper工作原理(原子廣播) 174Znode有四種形式的目錄節(jié)點 174KAFKA 175Kafka概念 175Kafka數(shù)據(jù)存儲設計 175partition的數(shù)據(jù)文件(offset,MessageSize,data) 175數(shù)據(jù)文件分段segment(順序讀寫、分段命令、二分查找) 176數(shù)據(jù)文件索引(分段索引、稀疏存儲) 176生產(chǎn)者設計 176負載均衡(partition會均衡分布到不同broker上) 176批量發(fā)送 177壓縮(GZIP或Snappy) 177消費者設計 177ConsumerGroup 178RABBITMQ 17913.1.1.概念 179RabbitMQ架構 179Message 180Publisher 180Exchange(將消息路由給隊列) 180Binding(消息隊列和交換器之間的關聯(lián)) 180Queue 180Connection 180Channel 180Consumer 180VirtualHost 180Broker 181Exchange類型 181Direct鍵(routingkey)分布: 181Fanout(廣播分發(fā)) 181topic交換器(模式匹配) 182HBASE 18314.1.1.概念 183列式存儲 183Hbase核心概念 184ColumnFamily列族 184Rowkey(Rowkey查詢,Rowkey范圍掃描,全表掃描) 184Region分區(qū) 184TimeStamp多版本 184Hbase核心架構 184Client: 185Zookeeper: 185Hmaster 185HregionServer 185Region尋址方式(通過zookeeper.META) 186HDFS 186Hbase的寫邏輯 187Hbase的寫入流程 187187求寫Hlog 187MemStore 187MemStore刷盤 187全局內(nèi)存控制 188MemStore達到上限 188數(shù)量達到上限 188手工觸發(fā) 188觸發(fā) 188恢復完數(shù)據(jù)后觸發(fā) 188HBasevsCassandra 188MONGODB 19015.1.1.概念 19015.1.2.特點 190CASSANDRA 19216.1.1.概念 192數(shù)據(jù)模型 192對應SQL數(shù)據(jù)庫中的database) 192對應SQL數(shù)據(jù)庫中的主鍵) 192對應SQL數(shù)據(jù)庫中的列) 192supercolumn(SQL數(shù)據(jù)庫不支持) 192Family(相對應SQL數(shù)據(jù)庫中的table) 192SuperColumnFamily(SQL數(shù)據(jù)庫不支持) 192Cassandra一致Hash和虛擬節(jié)點 192多米諾down機) 192虛擬節(jié)點(down機多節(jié)點托管) 193Gossip協(xié)議 193Gossip節(jié)點的通信方式及收斂性 194Gossip兩個節(jié)點(A、B)之間存在三種通信方式(push、pull、push&pull) 194和seedlist(防止集群分列) 194數(shù)據(jù)復制 194Partitioners(計算primarykeytoken的hash函數(shù)) 194兩種可用的復制策略: 194SimpleStrategy:僅用于單數(shù)據(jù)中心, 194將第一個replica放在由partitioner確定的節(jié)點中,其余的replicas放在上述節(jié)點順時針方向的后續(xù)節(jié)點中。 NetworkTopologyStrategy:可用于較復雜的多數(shù)據(jù)中心。 194可以指定在每個數(shù)據(jù)中心分別存儲多少份replicas。 194數(shù)據(jù)寫請求和協(xié)調(diào)者 195協(xié)調(diào)者(coordinator) 195數(shù)據(jù)讀請求和后臺修復 195數(shù)據(jù)存儲(CommitLog、MemTable、SSTable) 196SSTable文件構成(BloomFilter、index、data、static) 196二級索引(對要索引的value摘要,生成RowKey) 196數(shù)據(jù)讀寫 197數(shù)據(jù)寫入和更新(數(shù)據(jù)追加) 197數(shù)據(jù)的寫和刪除效率極高 197錯誤恢復簡單 197讀的復雜度高 197數(shù)據(jù)刪除(column的墓碑) 197墓碑 198垃圾回收compaction 198數(shù)據(jù)讀?。╩emtable+SStables) 198行緩存和鍵緩存請求流程圖 199RowCache(SSTables中頻繁被訪問的數(shù)據(jù)) 199查找數(shù)據(jù)可能對應的SSTable) 200KeyCache(查找數(shù)據(jù)可能對應的Partitionkey) 200內(nèi)存中存儲一些partitionindex的樣本) 200PartitionIndex(磁盤中) 200Compressionoffsetmap(磁盤中) 200設計模式 201設計原則 201工廠方法模式 201抽象工廠模式 201單例模式 201建造者模式 201原型模式 201適配器模式 201裝飾器模式 201代理模式 201外觀模式 201橋接模式 201組合模式 201享元模式 201策略模式 201模板方法模式 201觀察者模式 201迭代子模式 201責任鏈模式 201命令模式 201備忘錄模式 201狀態(tài)模式 202訪問者模式 202中介者模式 202解釋器模式 202負載均衡 203四層負載均衡vs七層負載均衡 203四層負載均衡(目標地址和端口交換) 203F5:硬件負載均衡器,功能很好,但是成本很高。 203lvs:重量級的四層負載軟件。 203nginx:輕量級的四層負載軟件,帶緩存功能,正則表達式較靈活。 203haproxy:模擬四層轉發(fā),較靈活。 203七層負載均衡(內(nèi)容交換) 203haproxy:天生負載均衡技能,全面支持七層代理,會話保持,標記,路徑轉移; 204nginx:只在協(xié)議和mail協(xié)議上功能比較好,性能與haproxy差不多; 204apache:功能較差 204Mysqlproxy:功能尚可。 204負載均衡算法/策略 204輪循均衡(RoundRobin) 204權重輪循均衡(WeightedRoundRobin) 204隨機均衡(Random) 204權重隨機均衡(WeightedRandom) 204響應速度均衡(ResponseTime探測時間) 204最少連接數(shù)均衡(LeastConnection) 205處理能力均衡(CPU、內(nèi)存) 205DNS響應均衡(FlashDNS) 205哈希算法 205IP地址散列(保證客戶端服務器對應關系穩(wěn)定) 205URL散列 20518.1.3.LVS 206. LVS原理 206IPVS 206LVSNAT模式 207模式(局域網(wǎng)改寫mac地址) 208LVSTUN模式(IP封裝、跨網(wǎng)段) 209LVSFULLNAT模式 210Keepalive 211Nginx反向代理負載均衡 211upstream_module和健康檢測 21. proxy_pass請求轉發(fā) 212HAProxy 21319. 數(shù)據(jù)庫 21419.1.1.存儲引擎 214. 概念 214InnoDB(B+樹) 214TokuDB(FractalTree-節(jié)點帶數(shù)據(jù)) 215MyIASM 215Memory 21519.1.2.索引 215常見索引原則有 216選擇唯一性索引 216為經(jīng)常需要排序、分組和聯(lián)合操作的字段建立索引: 216為常作為查詢條件的字段建立索引。 216限制索引的數(shù)目: 216盡量使用數(shù)據(jù)量少的索引 216盡量使用前綴來索引 2167.刪除不再使用或者很少使用的索引 2168.最左前綴匹配原則,非常重要的原則。 216.盡量選擇區(qū)分度高的列作為索引 216.索引列不能參與計算,保持列“干凈”:帶函數(shù)的查詢不參與索引。 216.盡量的擴展索引,不要新建索引。 216數(shù)據(jù)庫三范式 216第一范式(1stNF-列都是不可再分) 216第二范式(2ndNF-每個表只描述一件事情) 216NF-不存在對非主鍵列的傳遞依賴) 217數(shù)據(jù)庫是事務 217原子性(Atomicity) 217一致性(Consistency) 217隔離性(Isolation) 218永久性(Durability) 218存儲過程(特定功能的SQL語句集) 218存儲過程優(yōu)化思路: 218觸發(fā)器(一段能自動執(zhí)行的程序) 218數(shù)據(jù)庫并發(fā)策略 218. 樂觀鎖 218. 悲觀鎖 219. 時間戳 219數(shù)據(jù)庫鎖 219. 行級鎖 219. 表級鎖 219. 頁級鎖 219基于Redis分布式鎖 219分區(qū)分表 220垂直切分(按照功能模塊) 220水平切分(按照規(guī)則劃分存儲) 220兩階段提交協(xié)議 220準備階段 221提交階段 22.缺點 221同步阻塞問題 221單點故障 221數(shù)據(jù)不一致(腦裂問題) 221二階段無法解決的問題(數(shù)據(jù)狀態(tài)不確定) 221三階段提交協(xié)議 222CanCommit階段 222PreCommit階段 222doCommit階段 222柔性事務 222柔性事務 222兩階段型 222補償型 222異步確保型 223最大努力通知型(多次嘗試) 22319.1.14. CAP 224一致性(C): 224可用性(A): 224分區(qū)容忍性(P): 224一致性算法 225Paxos 225Paxos三種角色:Proposer,Acceptor,Learners 225Proposer: 225Acceptor: 225Learner: 225Paxos算法分為兩個階段。具體如下: 225階段一(準leader確定): 225階段二(leader確認): 22520.1.2.Zab 225崩潰恢復:主要就是Leader選舉過程 226數(shù)據(jù)同步:Leader服務器與其他服務器進行數(shù)據(jù)同步 226消息廣播:Leader服務器將數(shù)據(jù)發(fā)送給其他服務器 22620.1.3.Raft 226. 角色 226Leader(領導者-日志管理) 226Follower(追隨者-日志同步) 226Candidate(候選者-負責選票) 226Term(任期) 226選舉(Election) 227選舉定時器 227安全性(Safety) 227raft協(xié)議和zab協(xié)議區(qū)別 22720.1.4.NWR 228N:在分布式存儲系統(tǒng)中,有多少份備份數(shù)據(jù) 228一次成功的更新操作要求至少有w份數(shù)據(jù)寫入成功 228一次成功的讀數(shù)據(jù)操作要求至少有R份數(shù)據(jù)成功讀取 228Gossip 228一致性Hash 229一致性Hash特性 229一致性Hash原理 229建構環(huán)形hash空間: 229把需要緩存的內(nèi)容(對象)映射到hash空間 229把服務器(節(jié)點)映射到hash空間 229把對象映射到服務節(jié)點 229考察cache的變動 230虛擬節(jié)點 230JAVA算法 232二分查找 232冒泡排序算法 232插入排序算法 233快速排序算法 234希爾排序算法 236歸并排序算法 237桶排序算法 240基數(shù)排序算法 241剪枝算法 243回溯算法 243最短路徑算法 243最大子數(shù)組算法 243最長公共子序算法 243最小生成樹算法 243數(shù)據(jù)結構 245棧(stack) 245隊列(queue) 245鏈表(Link) 245散列表(HashTable) 246排序二叉樹 246插入操作 246刪除操作 247查詢操作 24822.1.6.紅黑樹 248. 紅黑樹的特性 248. 左旋 248. 右旋 249. 添加 250. 刪除 25122.1.7.B-TREE 25222.1.8.位圖 254加密算法 25523.1.1.AES 25523.1.2.RSA 25523.1.3.CRC 25623.1.4.MD5 256分布式緩存 257緩存雪崩 257緩存穿透 257緩存預熱 257緩存更新 257緩存降級 257HADOOP 25925.1.1.概念 259HDFS 259Client 259NameNode 259SecondaryNameNode 259DataNode 259MapReduce 260Client 260JobTracker 260TaskTracker 261Task 261ReduceTask執(zhí)行過程 261HadoopMapReduce作業(yè)的生命周期 262作業(yè)提交與初始化 262任務調(diào)度與監(jiān)控。 262任務運行環(huán)境準備 262任務執(zhí)行 262作業(yè)完成。 262SPARK 26326.1.1.概念 263核心架構 263SparkCore 263SparkSQL 263SparkStreaming 263Mllib 263GraphX 263核心組件 264ClusterManager-制整個集群,監(jiān)控worker 264Worker節(jié)點-負責控制計算節(jié)點 264行Application的main()函數(shù) 264Executor:執(zhí)行器,是為某個Application運行在workernode上的一個進程 264SPARK編程模型 264SPARK計算模型 265SPARK運行流程 266的運行環(huán)境,啟動SparkContext 267Standalone,Mesos,Yarn)申請運行Executor資源,并啟申請Task 267將應用程序分發(fā)給Executor 267DAG圖分解成Stage、將Taskset發(fā)送給TaskScheduler,最將Task發(fā)送給Executor運行 上運行,運行完釋放所有資源 267SPARKRDD流程 267SPARKRDD 267RDD的創(chuàng)建方式 267RDD的兩種操作算子(轉換(Transformation)與行動(Action)) 268STORM 26927.1.1.概念 269集群架構 269代碼分發(fā)給Supervisor) 269Supervisor(slave-管理Worker進程的啟動和終止) 269Worker(具體處理組件邏輯的進程) 269Task 270ZooKeeper 270編程模型(spout->tuple->bolt) 270Topology 270Spout 270Bolt 270Tuple 270Stream 271Topology運行 271進程)(2).Executor(線程)(3).Task 271Worker(1個worker進程執(zhí)行的是1個topology的子集) 271Executor(executor是1個被worker進程啟動的單獨線程) 271Task(最終運行spout或bolt中代碼的單元) 272StormStreamingGrouping 272huffleGrouping 273FieldsGrouping 273Allgrouping:廣播 273Globalgrouping 274Nonegrouping:不分組 274:直接分組指定分組 274YARN 27528.1.1.概念 275ResourceManager 275NodeManager 275ApplicationMaster 276YARN運行流程 277機器學習 27829.1.1.決策樹 278隨機森林算法 278邏輯回歸 27829.1.4.SVM 278樸素貝葉斯 278K最近鄰算法 278K均值算法 278Adaboost算法 278神經(jīng)網(wǎng)絡 278馬爾可夫 27830. 云計算 279SaaS 279PaaS 279IaaS 279Docker 279. 概念 279Namespaces 280進程(CLONE_NEWPID實現(xiàn)的進程隔離) 281Libnetwork與網(wǎng)絡隔離 281資源隔離與CGroups 282鏡像與UnionFS 282存儲驅動 282Openstack 283JVM 基本概念:JVMJava代碼的假想計算機,包括一套字節(jié)碼指令集、一組寄存器、一個棧、一個垃圾回收,堆和一個存儲方法域。JVM是運行在操作系統(tǒng)之上的,它與硬件沒有直接的交互。運行過程:我們都知道Java源文件,通過編譯器,能夠生產(chǎn)相應的.Class文件,也就是字節(jié)碼文件,Java也就是如下:JavaJVM—->機器碼每一種平臺的解釋器是不同的,但是實現(xiàn)的虛擬機是相同的,這也就是Java為什么能夠存在多個虛擬機實例。程序退出或者關閉,則虛擬機實例消亡,多個虛擬機實例之間數(shù)據(jù)不能共享。線程JVMHotspotJVM中的Java線程與原生操作系統(tǒng)線程有直接的映射關系。當線程本地存儲、緩沖區(qū)分配、同步對象、棧、程序計數(shù)器等準備好以后,就會創(chuàng)建一個操作系統(tǒng)原生線程。Java用的CPU上。當原生線程初始化完畢,就會調(diào)用Java線程的run()方法。當線程結束時,JavaHotspotJVM虛擬機線程(VMthread)JVMJVMstop-the-worlddump、線程暫停、線程偏向鎖(biasedlocking)解除。周期性任務線程(也就是中斷),用來調(diào)度周期性操作的執(zhí)行。GC線程JVM編譯器線程信號分發(fā)線程JVMJVM方法處理。JVM內(nèi)存區(qū)域JVM內(nèi)存區(qū)域主要分為線程私有區(qū)域【程序計數(shù)器、虛擬機棧、本地方法區(qū)】、線程共享區(qū)域【JAVA線程私有數(shù)據(jù)區(qū)域生命周期與線程相同,依賴用戶線程的啟動/結束而創(chuàng)建/銷毀(在HotspotVM內(nèi),每個線程都與操作系統(tǒng)的本地線程直接映射,因此這部分內(nèi)存區(qū)域的存/否跟隨本地線程的生/死對應)。。JVMJDK1.4NIO供了基于Channel與Buffer的IO方式,它可以使用Native函數(shù)庫直接分配堆外內(nèi)存,然后使用DirectByteBufferJavaI/O擴展),這樣就避免了在Java堆和Native。程序計數(shù)器(線程私有)一塊較小的內(nèi)存空間,是當前線程所執(zhí)行的字節(jié)碼的行號指示器,每條線程都要有一個獨立的程序計數(shù)器,這類內(nèi)存也稱為“線程私有”的內(nèi)存。正在執(zhí)行java方法的話,計數(shù)器記錄的是虛擬機字節(jié)碼指令的地址(當前指令的地址)。如Native這個內(nèi)存區(qū)域是唯一一個在虛擬機中沒有規(guī)定任何OutOfMemoryError虛擬機棧(線程私有)是描述java(StackFrame)用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。每一個方法從調(diào)用直至執(zhí)行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。棧幀(Frame)是用來存儲數(shù)據(jù)和部分過程結果的數(shù)據(jù)結構,同時也被用來處理動態(tài)鏈接(DynamicLinking(DispatchException)。棧幀隨著方法調(diào)用而創(chuàng)建,隨著方法結束而銷毀——無論方法是正常完成還是異常完成(拋出了在方法內(nèi)未被捕獲的異常)都算作方法結束。本地方法區(qū)(線程私有)本地方法區(qū)和JavaStackJava本地方法棧則為Native,如果一個VM實現(xiàn)使用C-linkage模型來支持NativeCHotSpotVM堆(Heap-線程共享)-運行時數(shù)據(jù)區(qū)是被線程共享的一塊內(nèi)存區(qū)域,創(chuàng)建的對象和數(shù)組都保存在Java堆內(nèi)存中,也是垃圾收集器進行垃圾收集的最重要的內(nèi)存區(qū)域VM分代收集算法Java堆從GC細分為:新生代(Eden、FromSurvivorToSurvivor)和老年代。方法區(qū)/永久代(線程共享)即我們常說的永久代(PermanentGeneration),用于存儲被JVM加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼HotSpotVMGC使用Java堆的永久代來實現(xiàn)方法區(qū),這樣HotSpotJava而不必為方法區(qū)開發(fā)專門的內(nèi)存管理器(永久帶的內(nèi)存回收的主要目標是針對常量池的回收和類型的卸載運行時常量池(RuntimeConstantPool)是方法區(qū)的一部分。Class本、字段、方法、接口等描述等信息外,還有一項信息是常量池(ConstantPoolTable),用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加載后存放到方法區(qū)的運行時常量池中。Java虛擬機對Class文件的每一部分(自然也包括常量池)的格式都有嚴格的規(guī)定,每一個字節(jié)用于存儲哪種數(shù)據(jù)都必須符合規(guī)范上的要求,這樣才會被虛擬機認可、裝載和執(zhí)行。JVM運行時內(nèi)存Java堆從GC的角度還可以細分為:新生代(Eden區(qū)、FromSurvivor區(qū)和ToSurvivor區(qū))和老年代。新生代1/3MinorGCEdenServivorFrom、ServivorToEden區(qū)(如果新創(chuàng)建的對象占用內(nèi)存很大,則直接分配到老MinorGC,對新生代區(qū)進行一次垃圾回收。ServivorFromGCGCServivorToMinorGCMinorGC(復制->清空->互換)MinorGC復制算法。1:eden、servicorFrom復制到ServicorTo,年齡+1EdenServivorFromServicorTo(如果有對象的年齡以及達到了老年的標準,則賦值到老年代區(qū)),同時把這些對象的年齡+1(ServicorTo夠位置了就放到老年區(qū));2:清空eden、servicorFrom然后,清空EdenServicorFrom3:ServicorToServicorFrom互換ServicorFromServicorToGCServicorFrom區(qū)。老年代主要存放應用程序中生命周期長的內(nèi)存對象。老年代的對象比較穩(wěn)定,所以MajorGC不會頻繁執(zhí)行。在進行MajorGC前一般都先進行了一次MinorGC,使得有新生代的對象晉身入老年代,導致空間不夠用時才觸發(fā)。當無法找到足MajorGCMajorGC采用標記清除算法:首先掃描一次所有老年代,標記出存活的對象,然后回收沒有標記的對象。MajorGCMajorGC少內(nèi)存損耗,我們一般需要進行合并或者標記出來方便下次直接分配。當老年代也滿了裝不下的OOM(OutofMemory)異常。永久代指內(nèi)存的永久保存區(qū)域,主要存放Class和Meta(元數(shù)據(jù))的信息,Class在被加載的時候被放入永久區(qū)域,它和和存放實例的區(qū)域不同,GC不會在主程序運行期對永久區(qū)域進行清理。所以這Class的增多而脹滿,最終拋出OOMJAVA8在Java8永久代已經(jīng)被移除,被一個稱為“元數(shù)據(jù)區(qū)”(元空間)的區(qū)域所取代。元空間的本質和永久代類似,元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機中,而是使用本地內(nèi)存。因此,默認情況下,元空間的大小僅受本地內(nèi)存限制。類的元數(shù)據(jù)放入nativememory,字符串池和類的靜態(tài)變量放入java堆中,這樣可以加載多少類的元數(shù)據(jù)就不再由MaxPermSize垃圾回收與算法如何確定垃圾引用計數(shù)法在Java中,引用和對象是有關聯(lián)的。如果要操作對象則必須用引用進行。因此,很顯然一個簡單的辦法是通過引用計數(shù)來判斷一個對象是否可以回收。簡單說,即一個對象如果沒有任何與之關聯(lián)的引用,即他們的引用計數(shù)都不為0,則說明對象不太可能再被用到,那么這個對象就是可回收對象??蛇_性分析為了解決引用計數(shù)法的循環(huán)引用問題,Java使用了可達性分析的方法。通過一系列的“GCroots”對象作為起點搜索。如果在“GCroots”和一個對象之間沒有可達路徑,則稱該對象是不可達的。要注意的是,不可達對象不等價于可回收對象,不可達對象變?yōu)榭苫厥諏ο笾辽僖?jīng)過兩次標記過程。兩次標記后仍然是可回收對象,則將面臨回收。(Mark-Sweep)最基礎的垃圾回收算法,分為兩個階段,標注和清除。標記階段標記出所有需要回收的對象,清除階段回收被標記的對象所占用的空間。如圖從圖中我們就可以發(fā)現(xiàn),該算法最大的問題是內(nèi)存碎片化嚴重,后續(xù)可能發(fā)生大對象不能找到可利用空間的問題。復制算法(copying)Mark-Sweep的兩塊。每次只使用其中一塊,當這一塊內(nèi)存滿后將尚存活的對象復制到另一塊上去,把已使用的內(nèi)存清掉,如圖:這種算法雖然實現(xiàn)簡單,內(nèi)存效率高,不易產(chǎn)生碎片,但是最大的問題是可用內(nèi)存被壓縮到了原本的一半。且存活對象增多的話,Copying(Mark-Compact)Mark-Sweep標記后不是清理對象,而是將存活對象移向內(nèi)存的一端。然后清除端邊界外的對象。如圖:分代收集算法JVMGCTenured/OldGeneration)和新生代(YoungGeneration)。老生代的特點是每次垃圾回收時只有少量對象需要被回收,新生代的特點是每次垃圾回收時都有大量垃圾需要被回收,因此可以根據(jù)不同區(qū)域選擇不同的算法。新生代與復制算法JVMGC對于新生代都采取Copying1:1EdenSurvivorFromSpace,ToSpace),每次使用Eden空間和其中的一塊SurvivorSurvivor老年代與標記復制算法Mark-Compact方法區(qū)的永生代(PermanetGenerationclass常量,方法描述等。對永生代的回收主要包括廢棄常量和無用的類。EdenSpaceSurvivorSpaceFromSpace(Survivor前存放對象的那一塊),少數(shù)情況會直接分配到老生代。當新生代的EdenSpaceFromSpaceGCGCEdenSpace和FromSpace區(qū)的存活對象會被挪到ToSpaceEdenSpace和FromSpaceToSpaceGCEdenSpaceToSpaceSurvivorGC1。15移到老生代中。JAVA四中引用類型強引用在Java中最常見的就是強引用,把一個對象賦給一個引用變量,這個引用變量就是一個強引用。當一個對象被強引用變量引用時,它處于可達狀態(tài),它是不可能被垃圾回收機制回收的,即JVMJava一。軟引用軟引用需要用SoftReference類來實現(xiàn),對于只有軟引用的對象來說,當系統(tǒng)內(nèi)存足夠時它不會被回收,當系統(tǒng)內(nèi)存空間不足時它會被回收。軟引用通常用在對內(nèi)存敏感的程序中。弱引用弱引用需要用WeakReferenceJVM虛引用虛引用需要PhantomReference虛引用的主要作用是跟蹤對象被垃圾回收的狀態(tài)。GC分代收集算法VS分區(qū)收集算法分代收集算法VM(GenerationalCollection)JVM新生代、老年代、永久代,這樣就可以根據(jù)GC復制算法存活對象的復制成本就可以完成收集.標記—清理”或“標記—整理”分區(qū)收集算法分區(qū)算法則將整個堆空間劃分為連續(xù)的不同小區(qū)間,每個小區(qū)間獨立使用,獨立回收.這樣做的好處是可以控制一次回收多少個小區(qū)間,根據(jù)目標停頓時間,每次合理地回收若干個小區(qū)間(而不是GCGC垃圾收集器Java堆內(nèi)存被劃分為新生代和年老代兩部分,新生代主要使用復制和標記-清除垃圾回收算法;年老代主要使用標記-整理垃圾回收算法,因此java虛擬中針對新生代和年老代分別提供了多種不同的垃圾收集器,JDK1.6SunHotSpotSerial垃圾收集器(單線程、復制算法)Serial(英文連續(xù))是最基本垃圾收集器,使用復制算法,曾經(jīng)是JDK1.3.1收集器。Serial是一個單線程的收集器,它不但只會使用一個CPU或一條線程去完成垃圾收集工作,并且在進行垃圾收集的同時,必須暫停其他所有的工作線程,直到垃圾收集結束。Serial垃圾收集器雖然在收集垃圾過程中需要暫停所有其他的工作線程,但是它簡單高效,對于限定單個CPU環(huán)境來說,沒有線程交互的開銷,可以獲得最高的單線程垃圾收集效率,因此Serial垃圾收集器依然是javaClient。ParNew垃圾收集器(Serial+多線程)Serial,也使用復制算法,除了使用多線程進行垃SerialParNew要暫停所有其他的工作線程。ParNew收集器默認開啟和CPU數(shù)目相同的線程數(shù),可以通過-XX:ParallelGCThreads參數(shù)來限制垃圾收集器的線程數(shù)?!綪arallel:平行的】ParNewSerialParNewjavaServer。ParallelScavenge收集器(多線程復制算法、高效)ParallelScavenge收集器也是一個新生代垃圾收集器,同樣使用復制算法,也是一個多線程的垃圾收集器,它重點關注的是程序達到一個可控制的吞吐量(Thoughput,CPU用于運行用戶代碼的時間/CPU總消耗時間,即吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)),高吞吐量可以最高效率地利用CPU時間,盡快地完成程序的運算任務,主要適用于在后臺運算而不需要太多交互的任務。自適應調(diào)節(jié)策略也是ParallelScavengeParNew收集器的一個重要區(qū)別。SerialOld收集器(單線程標記整理算法)SerialOld是Serial垃圾收集器年老代版本,它同樣是個單線程的收集器,使用標記-整理算法,這個收集器也主要是Client默認的java。ServerJDK1.5之前版本中與新生代的ParallelScavenge作為年老代中使用CMSSerialSerialOldParallelScavengeParNew用的是復制算法,在垃圾收集過程中都需要暫停所有的工作線程。新生代ParallelScavenge/ParNewSerialOldParallelOld收集器(多線程標記整理算法)ParallelOldParallelScavengeJDK1.6才開始提供。在JDK1.6之前,新生代使用ParallelScavenge收集器只能搭配年老代的SerialOld收集器,只能保證新生代的吞吐量優(yōu)先,無法保證整體的吞吐量,ParallelOld正是為了在年老代同樣提供吞吐量優(yōu)先的垃圾收集器,如果系統(tǒng)對吞吐量要求比較高,可以優(yōu)先考慮新生代ParallelScavenge和年老代ParallelOldParallelScavengeParallelOldCMS收集器(多線程標記清除算法)Concurrentmarksweep(CMS)收集器是一種年老代垃圾收集器,其最主要目標是獲取最短垃圾回收停頓時間,和其他年老代使用標記-整理算法不同,它使用多線程的標記-清除算法。CMS4初始標記只是標記一下GCRoots并發(fā)標記GCRoots重新標記為了修正在并發(fā)標記期間,因用戶程序繼續(xù)運行而導致標記產(chǎn)生變動的那一部分對象的標記記錄,仍然需要暫停所有的工作線程。并發(fā)清除GCRoots發(fā)標記和并發(fā)清除過程中,垃圾收集線程可以和用戶現(xiàn)在一起并發(fā)工作,所以總體上來看CMSCMSG1收集器GarbagefirstCMSG1集器兩個最突出的改進是:G1收集器避免全區(qū)域垃圾收集,它把堆內(nèi)存劃分為大小固定的幾個獨立區(qū)域,并且跟蹤這些區(qū)域的垃圾收集進度,同時在后臺維護一個優(yōu)先級列表,每次根據(jù)所允許的收集時間,優(yōu)先回收垃圾最多的區(qū)域。區(qū)域劃分和優(yōu)先級區(qū)域回收機制,確保G1收集器可以在有限時間獲得最高的垃圾收集效率。JAVAIO/NIOIO模型IOIO核會去查看數(shù)據(jù)是否就緒,如果沒有就緒就會等待數(shù)據(jù)就緒,而用戶線程就會處于阻塞狀態(tài),用戶線程交出CPU。當數(shù)據(jù)就緒之后,內(nèi)核會將數(shù)據(jù)拷貝到用戶線程,并返回結果給用戶線程,用戶線程才解除blockIOdatasocket.read();如果數(shù)據(jù)沒有就緒,就會一直阻塞在readIO模型當用戶線程發(fā)起一個readerrorread好了,并且又再次收到了用戶線程的請求,那么它馬上就將數(shù)據(jù)拷貝到了用戶線程,然后返回。IOIO不會交出CPU,而會一直占用CPU。典型的非阻塞IOwhile(true){while(true){data=socket.read();if(data!=error){處理數(shù)據(jù)break;}}但是對于非阻塞IOwhile緒,這樣會導致CPUwhileIO模型IOJavaNIO實際上就是多路復用IO。在多路復用IO模型中,會有一個線程不斷去輪詢多個socketsocketIOIOsocket,系統(tǒng)不需要建立新的進程或者線程,也不必維護這些線程和進程,并且只有在真正有socketIOJavaNIOselector.select()去查詢每個通道是否有到達事件,如果沒有事件,則一直阻塞在那里,因此這IO模式,通過一個線程就可以管理多個socket,只有當socketIO接數(shù)比較多的情況。IOIOIO中,不斷地詢問socketIOsocket率要比用戶線程要高的多。IOIO一旦事件響應體很大,那么就會導致后續(xù)的事件遲遲得不到處理,并且會影響新的事件輪詢。IO模型IOIO請求操作,會給對應的socket數(shù),然后用戶線程會繼續(xù)執(zhí)行,當內(nèi)核數(shù)據(jù)就緒時會發(fā)送一個信號給用戶線程,用戶線程接收到IOIOIO模型IOIOIO模型中,當用戶線程發(fā)起read可以開始去做其它的事。而另一方面,從內(nèi)核的角度,當它受到一個asynchronousread它會立刻返回,說明readblock。然后,內(nèi)核會等待數(shù)據(jù)準備完成,然后將數(shù)據(jù)拷貝到用戶線程,當這一切都完成之后,內(nèi)核會給用戶線程發(fā)送一個信號,告訴它readIO進行的,IO去使用數(shù)據(jù)了。IOIOIO讀寫。這點是和信號驅動模型有所不同的,在信號驅動模型中,當用戶線程接收到信號表示數(shù)據(jù)IOIOIOIOIOJava7中,提供了AsynchronousIO。://.importnew/19816.htmlJAVAIO包JAVANIONIO:Channel(通道),BufferSelectorIO符流進行操作,而NIOChannelBuffer(緩沖區(qū))進行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。Selector(選擇區(qū))用于監(jiān)聽多個通道的事件(比如:連接打開,數(shù)據(jù)到達)。因此,單個線程可以監(jiān)聽多個數(shù)據(jù)通道。NIOIOIONIO。NIOJavaIO地方。此外,它不能前后移動流中的數(shù)據(jù)。如果需要前后移動從流中讀取的數(shù)據(jù),需要先將它緩存到一個緩沖區(qū)。NIO緩沖區(qū)中前后移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區(qū)中包含所有您需要處理的數(shù)據(jù)。而且,需確保當更多的數(shù)據(jù)讀入緩沖區(qū)時,不要覆蓋緩沖區(qū)里尚未處理的數(shù)據(jù)。NIOIOread(write()時,該線程被阻塞,直到有NIO使一個線程從某通道發(fā)送請求讀取數(shù)據(jù),但是它僅能得到目前可用的數(shù)據(jù),如果目前沒有數(shù)據(jù)可用時,就什么都不會獲取。而不是保持線程阻塞,所以直至數(shù)據(jù)變的可以讀取之前,該線程可以IOIO(channel)。13/04/2018 Page39of283Channel首先說一下Channel,國內(nèi)大多翻譯成“通道”。ChannelIOStream(流)是差不多一個等級的。Stream,譬如:InputStreamOutputStream,Channel的,既可以用來進行讀操作,又可以用來進行寫操作。NIOChannelFileChannelDatagramChannelSocketChannelServerSocketChannelIO、UDPTCP(ServerClient)。4ChannelBuffer緩沖區(qū),實際上是一個容器,是一個連續(xù)數(shù)組。ChannelBuffer。上面的圖描述了從一個客戶端向服務端發(fā)送數(shù)據(jù),然后服務端接收數(shù)據(jù)的過程??蛻舳税l(fā)送BufferBufferChannelBufferBufferNIOBufferBufferByteBuffer、IntBufferCharBufferLongBufferDoubleBuffer、FloatBuffer、ShortBufferSelectorNIOSelector件發(fā)生,便獲取事件然后針對每個事件進行相應的響應處理。這樣一來,只是用一個單線程就可以管理多個通道,也就是管理多個連接。這樣使得只有在連接真正有讀寫事件發(fā)生時,才會調(diào)用函數(shù)來進行讀寫,就大大地減少了系統(tǒng)開銷,并且不必為每個連接都創(chuàng)建一個線程,不用去維護多個線程,并且避免了多線程之間的上下文切換導致的開銷。JVM類加載機制JVM類加載機制分為五個部分:加載,驗證,準備,解析,初始化,下面我們就分別來看一下這五個過程。加載加載是類加載過程中的一個階段,這個階段會在內(nèi)存中生成一個代表這個類的java.lang.Class象,作為方法區(qū)這個類的各種數(shù)據(jù)的入口。注意這里不一定非得要從一個ClassZIP(比如從jarwar),也可以在運行時計算生成(動態(tài)代理),也可以由其它文件生成(JSP文件轉換成對應的Class)。驗證這一階段的主要目的是為了Class,并且不會危害虛擬機自身的安全。準備準備階段是正式為類變量分配內(nèi)存并設置類變量的初始值階段,即在方法區(qū)中分配這些變量所使用的內(nèi)存空間。注意這里所說的初始值概念,比如一個類變量定義為:publicpublicstaticintv=8080;實際上變量v08080,v8080putstatic程序被編譯后,存放于類構造器<client>方法之中。但是注意如果聲明為:publicpublicstaticfinalintv=8080;在編譯階段會為vConstantValueConstantValuev8080。解析解析階段是指虛擬機將常量池中的符號引用替換為直接引用的過程class的:CONSTANT_Class_infoCONSTANT_Field_infoCONSTANT_Method_info等類型的常量。符號引用符號引用與虛擬機實現(xiàn)的布局無關,引用的目標并不一定要已經(jīng)加載到內(nèi)存中。各種虛擬機實現(xiàn)的內(nèi)存布局可以各不相同,但是它們能接受的符號引用必須是一致的,因為符號引Java虛擬機規(guī)范的Class直接引用直接引用可以是指向目標的指針,相對偏移量或是一個能間接定位到目標的句柄。如果有了直接引用,那引用的目標必定已經(jīng)在內(nèi)存中存在。初始化初始化階段是類加載最后一個階段,前面的類加載階段之后,除了在加載階段可以自定義類加載JVMJavaclient>初始化階段是執(zhí)行類構造器<client>方法的過程。<client>方法是由編譯器自動收集類中的類變量的賦值操作和靜態(tài)語句塊中的語句合并而成的。虛擬機會保證子<client>方法執(zhí)行之前,父類的<client>方法已經(jīng)執(zhí)行完畢,如果一個類中沒有對靜態(tài)變量賦值也沒有靜態(tài)語句塊,那么編譯器可以不為這個類生成<client>()方法。定義對象數(shù)組,不會觸發(fā)該類的初始化。常量在編譯期間會存入調(diào)用類的常量池中,本質上并沒有直接引用定義常量的類,不會觸發(fā)定義常量所在的類。通過類名獲取Class通過Class.forNameinitialize為false始化,其實這個參數(shù)是告訴虛擬機,是否要對類進行初始化。通過ClassLoader默認的loadClass類加載器JVMJVM3啟動類加載器(BootstrapClassLoader)JAVA_HOME\lib目錄中的,或通過-Xbootclasspath虛擬機認可(rt.jar)的類。擴展類加載器(ExtensionClassLoader)JAVA_HOME\lib\ext目錄中的,或通過java.ext.dirs庫。應用程序類加載器(ApplicationClassLoader):負責加載用戶路徑(classpath)上的類庫。JVMjava.lang.ClassLoader實現(xiàn)自定義的類加載器。雙親委派當一個類收到了類加載請求,他首先不會嘗試自己去加載這個類,而是把這個請求委派給父類去完成,每一個層次類加載器都是如此,因此所有的加載請求都應該傳送到啟動類加載其中,只有當父類加載器反饋自己無法完成這個請求的時候(在它的加載路徑下沒有找到所需加載的Class),子類加載器才會嘗試自己去加載。采用雙親委派的一個好處是比如加載位于rt.jar包中的類java.lang.Object,不管是哪個加載器加載這個類,最終都是委托給頂層的啟動類加載器進行加載,這樣就保證了使用不同的類加載Object動態(tài)模型系統(tǒng))OSGi(OpenServiceGatewayInitiativeJava的動態(tài)模型系統(tǒng),是Java統(tǒng)的一系列規(guī)范。動態(tài)改變構造OSGi服務平臺提供在多種網(wǎng)絡設備上無需重啟的動態(tài)改變構造的功能。為了最小化耦合度和促使這些耦合度可管理,OSGi模塊化編程與熱插拔OSGiJavaOSGi實現(xiàn)模塊級的熱插拔功能,當程序升級更新時,可以只停用、重新安裝然后啟動程序的其中一部分,這對企業(yè)級程序開發(fā)來說是非常具有誘惑力的特性。OSGi描繪了一個很美好的模塊化開發(fā)目標,而且定義了實現(xiàn)這個目標的所需要服務與架構,同時OSGi功能同時,也引入了額外的復雜度,因為它不遵守了類加載的雙親委托模型。JAVA集合接口繼承關系和實現(xiàn)集合類存放于Java.util3set(集)、list(列表包含Queue)map(映射)。Collection:CollectionList、Set、QueueIterator:迭代器,可以通過迭代器遍歷集合中的數(shù)據(jù)Map:是映射表的基礎接口ListJavaListList是有序的Collection。JavaListArrayList、VectorLinkedList。數(shù)組)ArrayList是最常用的List實現(xiàn)類,內(nèi)部是通過數(shù)組實現(xiàn)的,它允許對元素進行快速隨機訪問。數(shù)組的缺點是每個元素之間不能有間隔,當數(shù)組大小不滿足時需要增加存儲能力,就要將已經(jīng)有數(shù)組的數(shù)據(jù)復制到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時,需要對數(shù)組進行復制、移動、代價比較高。因此,它適合隨機查找和遍歷,不適合插入和刪除。Vector(數(shù)組實現(xiàn)、線程同步)Vector與ArrayList它支持線程的同步,即某一時刻只有一個線程能夠寫Vector問它比訪問ArrayListLinkList(鏈表)LinkedList,隨機訪問和遍歷速度比較List棧、隊列和雙向隊列使用。Set值不能重復hashCode(java)判斷的,ObjecthashCodeequals法。表)哈希表邊存放的是哈希值。HashSet(List同)hashcodeHashSetequalsequlstrueHashSetequalsfalse同一個元素。equalsfalse(可以認為哈希值相同的元素放在一個哈希桶中)1hashCode2hashCodeequalsHashSethashCodehashCode素。二叉樹)add()的對象按照指定的順序排序(升序、降序),每增加一個對象都會進行排序,將對象插入的二叉樹指定的位置。IntegerStringTreeSet自己定義的類必須實現(xiàn)ComparablecompareTo()函數(shù),才可以正常使用。compare(TreeSet比較此對象與指定對象的順序。如果該對象小于、等于或大于指定對象,則分別返回負整數(shù)、零或正整數(shù)。LinkHashSet(HashSet+LinkedHashMap)對于LinkedHashSet而言,它繼承與HashSet、又基于LinkedHashMap來實現(xiàn)的。LinkedHashSet底層使用LinkedHashMapHashSet,其所有的方法操作上又與HashSetLinkedHashSet通過傳遞一個標識參數(shù),調(diào)用父類的構造器,底層構造一個LinkedHashMap來實現(xiàn),在相關操作上與父類HashSetHashSetMapHashMap(數(shù)組+鏈表+紅黑樹)HashMap根據(jù)鍵的hashCodeHashMapnull,允許多條記錄的值為null。HashMap非線程安全,即任一時刻可以有多個線程同時寫HashMap,可能會導致數(shù)據(jù)的不一致。如果需要滿足線程安全,可以用Collections的synchronizedMap方法使HashMap具有線程安全的能力,或者使用ConcurrentHashMap。我們用下面這張圖來介紹HashMapJAVA7實現(xiàn)大方向上,HashMap里面是一個數(shù)組,然后數(shù)組中每個元素是一個單向鏈表。上圖中,每個綠色的EntryEntrykey,value,hash值和用于單向鏈表next。capacity2^n2loadFactor0.75。thresholdcapacity*loadFactorJAVA8實現(xiàn)Java8對HashMap進行了一些修改,樹組成。根據(jù)Java7HashMap的介紹,我們知道,查找的時候,根據(jù)hash值我們能夠快速定位到數(shù)組的具體下標,但是之后的話,需要順著鏈表一個個比較下去才能找到我們需要的,時間復雜度取決于O(n)。為了降低這部分的開銷,在Java8中,當鏈表中的元素超過了8將鏈表轉換為紅黑樹O(logN)。ConcurrentHashMapSegment段ConcurrentHashMapHashMapConcurrentHashMapSegmentSegment意思,所以很多地方都會將其描述為分段鎖。注意,行文中,我很多地方用了“槽”來代表一個segment。ReentrantLock加鎖)簡單理解就是,ConcurrentHashMapSegment數(shù)組,SegmentReentrantLocksegm

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論