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

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

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

溫馨提示

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

評(píng)論

0/150

提交評(píng)論