华为java面试题
?
1、Java 常用集合及特點(diǎn)?
List:ArrayList、LinkedList、Vector、Stack Set:LinkedSet、HashSet、TreeSet
Queue->Deque->LinkedList。
Map:HashMap、LinkedHashMap、TreeMap Dictionary->HashTable->Properties。
Vector: 底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢,線程安全,效率低,默認(rèn)長(zhǎng)度為 10,超過(guò)會(huì) 100%延長(zhǎng),變成 20,浪費(fèi)空間。
ArrayList :基于數(shù)組,便于按 index 訪問(wèn),超過(guò)數(shù)組需要擴(kuò)容,擴(kuò)容成本較高。
LinkedList:使用鏈表實(shí)現(xiàn),無(wú)需擴(kuò)容。
74HashSet:底層數(shù)據(jù)結(jié)構(gòu)是哈希表(無(wú)序,唯一),通過(guò) hashcode()和 equals()保證元素唯一。
LinkedHashSet: 底層數(shù)據(jù)結(jié)構(gòu)是鏈表和哈希表(FIFO 插入有序,唯一),由鏈表保證元素有序,由哈希表保證元素唯一。
TreeSet:底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹(shù)(唯一,有序),通過(guò)自然排序和比較器排序保證元素有序,根據(jù)比較返回值是否是 0 來(lái)保證元素唯一性。
TreeMap 是有序的。
HashMap :空間換時(shí)間,哈希沖突不大的情況下查找數(shù)據(jù)性能很高。
LinkedHashMap 基本特點(diǎn):繼承自 HashMap,對(duì) Entry 集合添加了一個(gè)雙向鏈表。
2、開(kāi)啟一個(gè)線程的方法?
◆?繼承 Thread 類(lèi),新建一個(gè)當(dāng)前類(lèi)對(duì)象,并且運(yùn)行其 start()方法
◆?實(shí)現(xiàn) Runnable 接口,然后新建當(dāng)前類(lèi)對(duì)象,接著新建 Thread 對(duì)象時(shí)把當(dāng)前類(lèi)對(duì)象傳進(jìn)去,最后運(yùn)行 Thread 對(duì)象的 start()方法
◆?實(shí)現(xiàn) Callable 接口,新建當(dāng)前類(lèi)對(duì)象,在新建 FutureTask 類(lèi)對(duì)象時(shí)傳入當(dāng)前類(lèi)對(duì)象,接著新建 Thread 類(lèi)對(duì)象時(shí)傳入 FutureTask 類(lèi)對(duì)象,最后運(yùn)行 Thread 對(duì)象的 start()
方法
3、Java 面向?qū)ο蟀男┨匦?#xff0c;怎么理解的?
◆?封裝:通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來(lái),對(duì)數(shù)據(jù)的訪問(wèn)只能通過(guò)已定義的接口。面向?qū)ο蟮谋举|(zhì)就是將現(xiàn)實(shí)世界描繪成一系列完全自治、封閉的對(duì)象。我們?cè)陬?lèi)中編寫(xiě)的方法就是對(duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫(xiě)一個(gè)類(lèi)就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝。
可以說(shuō),封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程接口。
◆?繼承:繼承是從已有類(lèi)得到繼承信息創(chuàng)建新類(lèi)的過(guò)程。提供繼承信息的類(lèi)被稱(chēng)為父類(lèi)(超類(lèi)、基類(lèi));得到繼承信息的類(lèi)被稱(chēng)為子類(lèi)(派生類(lèi))。繼承讓變化中的軟件系統(tǒng)有了一定的延續(xù)性,同時(shí)繼承也是封裝程序中可變因素的重要手段。
◆?多態(tài):多態(tài)性是指允許不同子類(lèi)型的對(duì)象對(duì)同一消息作出不同的響應(yīng)。簡(jiǎn)單的說(shuō)就是用同樣的對(duì)象引用調(diào)用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。如果將對(duì)象的方法視為對(duì)象向外界提供的服務(wù),那么運(yùn)行時(shí)的多態(tài)性可以解釋為:當(dāng) A 系統(tǒng)訪問(wèn) B 系統(tǒng)提供的服務(wù)時(shí),B 系統(tǒng)有多種提供服務(wù)的方式,但一切對(duì) A 系統(tǒng)來(lái)說(shuō)都是透明的。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱(chēng)為前綁定),而方法重寫(xiě)(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱(chēng)為后綁定)。運(yùn)行時(shí)的多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)多態(tài)需要做兩件事:
第一:方法重寫(xiě)(子類(lèi)繼承父類(lèi)并重寫(xiě)父類(lèi)中已有的或抽象的方法);
第二:對(duì)象造型(用父類(lèi)型引用指向子類(lèi)型對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù)子類(lèi)對(duì)象的不同而表現(xiàn)出不同的行為)。
◆?抽象:抽象是將一類(lèi)對(duì)象的共同特征總結(jié)出來(lái)構(gòu)造類(lèi)的過(guò)程,包括數(shù)據(jù)抽象和行為抽象兩方面。抽象只關(guān)注對(duì)象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是什么。
4、Java 如何保證線程安全?
◆?使用同步代碼塊
◆?使用同步方法
◆?使用 Lock 鎖機(jī)制, 通過(guò)創(chuàng)建 Lock 對(duì)象,采用 lock()加鎖,unlock()解鎖,來(lái)保護(hù)指定的代碼塊。
5、介紹 Spring MVC 的工作流程 ?
◆?用戶向服務(wù)端發(fā)送一次請(qǐng)求,這個(gè)請(qǐng)求會(huì)先到前端控制器 DispatcherServlet。
◆?DispatcherServlet 接收到請(qǐng)求后會(huì)調(diào)用 HandlerMapping 處理器映射器。由此得知,該請(qǐng)求該由哪個(gè) Controller 來(lái)處理(并未調(diào)用 Controller,只是得知)
◆?DispatcherServlet 調(diào)用 HandlerAdapter 處理器適配器,告訴處理器適配器應(yīng)該要去執(zhí)行哪個(gè) Controller
◆?HandlerAdapter 處理器適配器去執(zhí)行 Controller 并得到 ModelAndView(數(shù)據(jù)和視圖), 并層層返回給 DispatcherServlet
◆?DispatcherServlet 將 ModelAndView 交給 ViewReslover 視圖解析器解析,然后返回真正的視圖。
◆?DispatcherServlet 將模型數(shù)據(jù)填充到視圖中
◆?DispatcherServlet 將結(jié)果響應(yīng)給用戶
6、Spring 框架中用到了哪些設(shè)計(jì)模式?
◆?工廠設(shè)計(jì)模式 : Spring 使用工廠模式通過(guò) BeanFactory、ApplicationContext 創(chuàng)建bean 對(duì)象。
◆?代理設(shè)計(jì)模式 : Spring AOP 功能的實(shí)現(xiàn)。
◆?單例設(shè)計(jì)模式 : Spring 中的 Bean 默認(rèn)都是單例的。
◆?模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結(jié)尾的對(duì)數(shù)據(jù)庫(kù)操作的類(lèi),它們就使用到了模板模式。
◆?包裝器設(shè)計(jì)模式 : 我們的項(xiàng)目需要連接多個(gè)數(shù)據(jù)庫(kù),而且不同的客戶在每次訪問(wèn)中根據(jù)需要會(huì)去訪問(wèn)不同的數(shù)據(jù)庫(kù)。這種模式讓我們可以根據(jù)客戶的需求能夠動(dòng)態(tài)切換不同的數(shù)據(jù)源。
◆?觀察者模式: Spring 事件驅(qū)動(dòng)模型就是觀察者模式很經(jīng)典的一個(gè)應(yīng)用。
◆?適配器模式 : Spring AOP 的增強(qiáng)或通知(Advice)使用到了適配器模式、spring MVC 中也是用到了適配器模式適配 Controller。
767、Redis 的特點(diǎn)是什么?
Redis 本質(zhì)上是一個(gè) Key-Value 類(lèi)型的內(nèi)存數(shù)據(jù)庫(kù),很像 Memcached,整個(gè)數(shù)據(jù)庫(kù)統(tǒng)統(tǒng)加載在內(nèi)存當(dāng)中進(jìn)行操作,定期通過(guò)異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù) flush 到硬盤(pán)上進(jìn)行保存。
因?yàn)槭羌儍?nèi)存操作,Redis 的性能非常出色,每秒可以處理超過(guò) 10 萬(wàn)次讀寫(xiě)操作,是已知性能最快的 Key-Value DB。
Redis 的出色之處不僅僅是性能,Redis 最大的魅力是支持保存多種數(shù)據(jù)結(jié)構(gòu),此外單個(gè)value 的最大限制是 1GB,不像 Memcached 只能保存 1MB 的數(shù)據(jù),因此 Redis 可以用來(lái)實(shí)現(xiàn)很多有用的功能。
比方說(shuō)用他的 List 來(lái)做 FIFO 雙向鏈表,實(shí)現(xiàn)一個(gè)輕量級(jí)的高性 能消息隊(duì)列服務(wù),用他的Set 可以做高性能的 tag 系統(tǒng)等等。另外 Redis 也可以對(duì)存入的 Key-Value 設(shè)置 expire時(shí)間,因此也可以被當(dāng)作一 個(gè)功能加強(qiáng)版的 Memcached 來(lái)用。
Redis 的主要缺點(diǎn)是數(shù)據(jù)庫(kù)容量受到物理內(nèi)存的限制,不能用作海量數(shù)據(jù)的高性能讀寫(xiě),因此 Redis 適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上。
8、為什么使用 Redis,有什么好處?
◆?速度快,因?yàn)閿?shù)據(jù)存在內(nèi)存中,類(lèi)似于 HashMap,HashMap 的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是 O(1)
◆?支持豐富數(shù)據(jù)類(lèi)型,支持 string,list,set,sorted set,hash
◆?支持事務(wù),操作都是原子性,所謂的原子性就是對(duì)數(shù)據(jù)的更改要么全部執(zhí)行,要么全部不執(zhí)行
◆?豐富的特性:可用于緩存,消息,按 key 設(shè)置過(guò)期時(shí)間,過(guò)期后將會(huì)自動(dòng)刪除
9、Redis 雪崩和擊穿了解嗎?
緩存擊穿
◆?問(wèn)題:某個(gè) KEY 失效的時(shí)候,正好有大量并發(fā)請(qǐng)求訪問(wèn)這個(gè) KEY。
◆?分析:跟穿透其實(shí)很像,屬于比較偶然的。
◆?解決辦法:KEY 的更新操作添加全局互斥鎖。完全以緩存為準(zhǔn),使用延遲異步加載的策略(異步線程負(fù)責(zé)維護(hù)緩存的數(shù)據(jù),定期或根據(jù)條件觸發(fā)更新),這樣就不會(huì)觸發(fā)更新。
緩存雪崩
◆?問(wèn)題:當(dāng)某一時(shí)刻發(fā)生大規(guī)模的緩存失效的情況,導(dǎo)致大量的請(qǐng)求無(wú)法獲取數(shù)據(jù),從而將流量壓力傳導(dǎo)到數(shù)據(jù)庫(kù)上,導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大甚至宕機(jī)。
◆?原因:一般而言,緩存雪崩有 2 種可能性:大量的數(shù)據(jù)同一個(gè)時(shí)間失效:比如業(yè)務(wù)關(guān)系強(qiáng)相關(guān)的數(shù)據(jù)要求同時(shí)失效 Redis 宕機(jī)
◆?分析:一般來(lái)說(shuō),由于更新策略、或者數(shù)據(jù)熱點(diǎn)、緩存服務(wù)宕機(jī)等原因,可能會(huì)導(dǎo)致緩存數(shù)據(jù)同一個(gè)時(shí)間點(diǎn)大規(guī)模不可用,或者都更新。所以,需要我們的更新策略要在時(shí)間上合適,數(shù)據(jù)要均勻分享,緩存服務(wù)器要多臺(tái)高可用。
◆?解決辦法:更新策略在時(shí)間上做到比較平均。如果數(shù)據(jù)需要同一時(shí)間失效,可以給這批數(shù)據(jù)加上一些隨機(jī)值,使得這批數(shù)據(jù)不要在同一個(gè)時(shí)間過(guò)期,降低數(shù)據(jù)庫(kù)的壓力。使用的熱數(shù)據(jù)盡量分散到不同的機(jī)器上。多臺(tái)機(jī)器做主從復(fù)制或者多副本,實(shí)現(xiàn)高可用。做好主從的部署,當(dāng)主節(jié)點(diǎn)掛掉后,能快速的使用從結(jié)點(diǎn)頂上。實(shí)現(xiàn)熔斷限流機(jī)制,對(duì)系統(tǒng)進(jìn)行負(fù)載能力控制。對(duì)于非核心功能的業(yè)務(wù),拒絕其請(qǐng)求,只允許核心功能業(yè)務(wù)訪問(wèn)數(shù)據(jù)庫(kù)獲取數(shù)據(jù)。服務(wù)降價(jià):提供默認(rèn)返回值,或簡(jiǎn)單的提示信息。
10、什么是面向?qū)ο?#xff0c;談?wù)勀愕睦斫?#xff1f;
世間萬(wàn)物都可以看成一個(gè)對(duì)象。每個(gè)物體包括動(dòng)態(tài)的行為和靜態(tài)的屬性,這些就構(gòu)成了一個(gè)對(duì)象。
11、訪問(wèn)數(shù)據(jù)庫(kù)除了 JDBC 還有什么?
◆?自己封裝 JDBC 的工具類(lèi)
◆?Commons-Dbutils+dbcp【QueryRunner】
◆?SpringJDBC【JdbcTemplate】
◆?JPA【配置文件、domain 實(shí)體類(lèi)+注解、EntityManager】
◆?SpringDataJpa
◆?Hibernate 框架
◆?Mybatis
12、你知道有哪些設(shè)計(jì)原則?
◆?遵循單一職責(zé)原則
◆?開(kāi)放-封閉原則
◆?里氏代換原則(LSP)
◆?依賴倒置原則
◆?接口隔離原則(Interface Segregation Principle)
◆?迪米特法則(Law of Demeter)
13、在生產(chǎn)環(huán)境 Linux 服務(wù)器上,發(fā)現(xiàn)某臺(tái)運(yùn)行 Java 服務(wù)的服務(wù)器的CPU100%,不借助任何可視化工具,怎么進(jìn)行問(wèn)題的定位?
◆?top 找出進(jìn)程 CPU 比較高 PID
◆?top -Hp PID 打印 該 PID 進(jìn)程下哪條線程的 CPU 占用比較高 tid
◆?printf “%x\n” tid 將該 id 進(jìn)行 16 進(jìn)制轉(zhuǎn)換 tidhex
◆?jstack PID |grep tidhex 打印線程的堆棧信息
14、JDK 里面帶的工具你知道哪些?
◆?jstat:虛擬機(jī)進(jìn)程狀況工具
◆?jinfo:Java 配置信息工具
◆?jmap:Java 內(nèi)存映像工具
◆?jhat:虛擬機(jī)堆轉(zhuǎn)儲(chǔ)快照分析工具
◆?jstack:Java 堆棧跟蹤工具
◆?JConsole: Java 監(jiān)視與管理控制臺(tái)
◆?VisualVM: 多合一故障處理工具
15、基本數(shù)據(jù)類(lèi)型 bit 長(zhǎng)度?
◆?byte:1*8
◆?short:2*8
◆?int: 4*8
◆?long: 8*8
◆?float: 4*8
◆?double: 8*8
◆?char: 2*8
◆?boolean: 1*8
16、char 能不能存中文?
可以,不過(guò),如果某個(gè)特殊的漢字沒(méi)有被包含在 unicode 編碼字符集中,那么,這個(gè) char型變量中就不能存儲(chǔ)這個(gè)特殊漢字。
17、談?wù)勀銓?duì)泛型的理解?
Java 中的泛型有 3 種形式,泛型方法,泛型類(lèi),泛型接口。Java 通過(guò)在編譯時(shí)類(lèi)型擦除的方式來(lái)實(shí)現(xiàn)泛型。擦除時(shí)使用 Object 或者界定類(lèi)型替代泛型,同時(shí)在要調(diào)用具體類(lèi)型方法或者成員變量的時(shí)候插入強(qiáng)轉(zhuǎn)代碼,為了保證多態(tài)特性,Java 編譯器還會(huì)為泛型類(lèi)的子類(lèi)生成橋接方法。類(lèi)型信息在編譯階段被擦除之后,程序在運(yùn)行期間無(wú)法獲取類(lèi)型參數(shù)所對(duì)應(yīng)的具體類(lèi)型。
18、Java 程序是怎樣運(yùn)行的?
◆?首先通過(guò) Javac 編譯器將 .java 轉(zhuǎn)為 JVM 可加載的 .class 字節(jié)碼文件。
◆?Javac 是由 Java 編寫(xiě)的程序,編譯過(guò)程可以分為:
- 詞法解析,通過(guò)空格分割出單詞、 操作符、控制符等信息,形成 token 信息流,傳遞給語(yǔ)法解析器。
- ?語(yǔ)法解析,把token 信息流按照 Java 語(yǔ)法規(guī)則組裝成語(yǔ)法樹(shù)。
- ?語(yǔ)義分析,檢查關(guān)鍵字使用是否合理、類(lèi)型是否匹配、作用域是否正確等。
- 字節(jié)碼生成,將前面各個(gè)步驟的信息轉(zhuǎn)換為字節(jié)碼。
◆?字節(jié)碼必須通過(guò)類(lèi)加載過(guò)程加載到 JVM 后才可以執(zhí)行,執(zhí)行有三種模式,解釋執(zhí)行、JIT編譯執(zhí)行、JIT 編譯與解釋器混合執(zhí)行(主流 JVM 默認(rèn)執(zhí)行的方式)。混合模式的優(yōu)勢(shì)在于解釋器在啟動(dòng)時(shí)先解釋執(zhí)行,省去編譯時(shí)間。
◆?之后通過(guò)即時(shí)編譯器 JIT 把字節(jié)碼文件編譯成本地機(jī)器碼。
◆?Java 程序最初都是通過(guò)解釋器進(jìn)行解釋執(zhí)行的,當(dāng)虛擬機(jī)發(fā)現(xiàn)某個(gè)方法或代碼塊的運(yùn)行特別頻繁,就會(huì)認(rèn)定其為"熱點(diǎn)代碼",熱點(diǎn)代碼的檢測(cè)主要有基于采樣和基于計(jì)數(shù)器兩種方式,為了提高熱點(diǎn)代碼的執(zhí)行效率,虛擬機(jī)會(huì)把它們編譯成本地機(jī)器碼,盡可能對(duì)代碼優(yōu)化,在運(yùn)行時(shí)完成這個(gè)任務(wù)的后端編譯器被稱(chēng)為即時(shí)編譯器。
◆?還可以通過(guò)靜態(tài)的提前編譯器 AOT 直接把程序編譯成與目標(biāo)機(jī)器指令集相關(guān)的二進(jìn)制代碼。
19、GC root 有哪些?
◆?Thread-存活的線程。
◆?Java 虛擬機(jī)棧中的引用的對(duì)象。
◆?方法區(qū)中的類(lèi)靜態(tài)屬性引用的對(duì)象。 (一般指被 static 修飾的對(duì)象,加載類(lèi)的時(shí)候就加載到內(nèi)存中。)
◆?方法區(qū)中的常量引用的對(duì)象。
◆?本地方法棧中的 JNI(native 方法)引用的對(duì)象。
◆?Monitor Used-用于同步監(jiān)控的對(duì)象。
20、棧幀的大小什么時(shí)候確定?
有時(shí)候編譯期能夠確定,有些時(shí)候函數(shù)的棧幀的大小在編譯期并不確定。比如用了 VLA。所以一般會(huì)有兩個(gè)寄存器(IA-32 上就是 ebp 和 esp)來(lái)記錄棧幀的首尾地址。當(dāng)進(jìn)入一個(gè)函數(shù)時(shí),首先把上個(gè)棧幀的首尾地址分別保存起來(lái)(一般做法是將 ebp 壓棧、并將 esp 寫(xiě) ebp),接著再分配新的棧幀大小(先給 esp 減一個(gè)常數(shù),如果需要?jiǎng)討B(tài)分配再接著減)。
21、靜態(tài) filed 聲明和構(gòu)造器哪個(gè)先執(zhí)行?
filed 聲明先執(zhí)行。
22、線程創(chuàng)建方式是什么?
◆?通過(guò)繼承 Thread 類(lèi)創(chuàng)建線程類(lèi)
◆?實(shí)現(xiàn) Runnable 接口創(chuàng)建線程類(lèi)
◆?通過(guò) Callable 和 Future 接口創(chuàng)建線程81
23、傳統(tǒng) I/O 跟 NIO 的區(qū)別?
◆?所有 I/O 都被視為單個(gè)的字節(jié)的移動(dòng),通過(guò)一個(gè)稱(chēng)為 Stream 的對(duì)象一次移動(dòng)一個(gè)字節(jié)。
流 I/O 用于與外部世界接觸。它也在內(nèi)部使用,用于將對(duì)象轉(zhuǎn)換為字節(jié),然后再轉(zhuǎn)換回對(duì)象。傳統(tǒng)流 IO 的好處是使用簡(jiǎn)單,將底層的機(jī)制都抽象成流,但缺點(diǎn)就是性能不足。而且 IO 的各種流是阻塞的。這意味著,當(dāng)一個(gè)線程調(diào)用 read() 或 write()時(shí),該線程被阻塞,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫(xiě)入。該線程在此期間不能再干任何事情了。
◆?原來(lái)的 I/O 庫(kù)(在 java.io.*中) 與 NIO 最重要的區(qū)別是數(shù)據(jù)打包和傳輸?shù)姆绞健?原來(lái)的I/O 以流的方式處理數(shù)據(jù),而 NIO 以塊的方式處理數(shù)據(jù)。
◆?NIO 性能的優(yōu)勢(shì)就來(lái)源于緩沖的機(jī)制(buffer 機(jī)制),不管是讀或者寫(xiě)都需要以塊的形式寫(xiě)入到緩沖區(qū)中。NIO 實(shí)際上讓我們對(duì) IO 的操作更接近于操作系統(tǒng)的實(shí)際過(guò)程。
◆?NIO 作為非阻塞式的 IO,它的優(yōu)點(diǎn)就在于,1、它由一個(gè)專(zhuān)門(mén)的線程去處理所有的 IO
事件,并負(fù)責(zé)分發(fā);2、事件驅(qū)動(dòng),只有事件到了才會(huì)觸發(fā),而不是同步的監(jiān)聽(tīng)這個(gè)事件;
3、線程之間通過(guò) wait,notify 等方式通訊。保證每次上下文切換都是有意義的。減少無(wú)謂的線程切換。
◆?當(dāng)我們?cè)趫?zhí)行持續(xù)性的操作(如上傳下載)時(shí),IO 的方式是要優(yōu)于 NIO 的。分清情況,合理選用。
◆?NIO 相對(duì)于 IO 流的優(yōu)勢(shì):
非阻塞buffer 機(jī)制 流替代塊
24、消息隊(duì)列的在各種場(chǎng)景下如何選型?
◆?優(yōu)先級(jí)隊(duì)列;隊(duì)列設(shè)置最大的優(yōu)先級(jí),之后每條消息設(shè)置對(duì)應(yīng)的優(yōu)先級(jí),隊(duì)列根據(jù)消息優(yōu)先級(jí)進(jìn)行消費(fèi),(在有可能隊(duì)列堆積的情況才有意義);應(yīng)用場(chǎng)景:不同業(yè)務(wù)消息推送。
◆?延遲隊(duì)列:消息發(fā)送后,并不想讓消費(fèi)者立即拿到消息,等待特定的事件后,消費(fèi)者才能拿到并消費(fèi);應(yīng)用場(chǎng)景:訂單系統(tǒng)中訂單支付 30 分鐘內(nèi)沒(méi)有支付成功,那么將這個(gè)訂單進(jìn)行異常處理;遠(yuǎn)程操作智能設(shè)備在指定時(shí)間進(jìn)行工作等。(rabbit 中沒(méi)有延遲隊(duì)列,但可以借助死信隊(duì) 列與 TTL 設(shè)置來(lái)完成)
◆?死信隊(duì)列:當(dāng)消息在一個(gè)隊(duì)列中變成死信之后,它能被重新被發(fā)送到另一個(gè)交換器(DLX交換器)中,綁定 DLX 的隊(duì)列就稱(chēng)為死信隊(duì)列。
◆?重試隊(duì)列:消費(fèi)端,一直不回傳消費(fèi)的結(jié)果,rocketmq 認(rèn)為消息沒(méi)收到,consumer 下一次拉取,broker 依然會(huì)發(fā)送該消息(有次數(shù)限制)。重試隊(duì)列其實(shí)可以看成是一種回退隊(duì)列,具體指消費(fèi)端消費(fèi)消息失敗時(shí),為防止消息無(wú)故丟失而重新將消息回滾到Broker 中。
◆?消費(fèi)模式: 推模式:對(duì)于 kafka 而言,由 Broker 主動(dòng)推送消息至消費(fèi)端,實(shí)時(shí)性較好,不過(guò)需要一定的流 制機(jī)制來(lái)確保服務(wù)端推送過(guò)來(lái)的消息不會(huì)壓垮消費(fèi)端。拉模式:對(duì)于kafka 而言,消費(fèi)端主動(dòng)向 Broker 端請(qǐng)求拉取(一般是定時(shí)或者定量)消息,實(shí)時(shí)性較推模式差,但是可以根據(jù)自身的處理能力而控制拉取的消息量。
◆?消息回溯:重置消息 offset(如:kafka、rokcetMq) 一般消息在消費(fèi)完成之后就被處理了,之后再也不能消費(fèi)到該條消息。消息回溯正好相反,是指消息在消費(fèi)完成之后,還能消費(fèi)到之前被消費(fèi)掉的消息。對(duì)于消息而言,經(jīng)常面臨的問(wèn)題是“消息丟失”,至于是真正由于消息中間件的缺陷丟失還是由于使用方的誤用而丟失一般很難追查,如果消息中間件本身具備消息回溯功能的話,可以通過(guò)回溯消費(fèi)復(fù)現(xiàn)“丟失的”消息 進(jìn)而查出問(wèn)題的源頭之所在。消息回溯的作用遠(yuǎn)不止與此,比如還有索引恢復(fù)、本地緩存重建,有些業(yè)務(wù)補(bǔ)償方案也可以采用回溯的方式來(lái)實(shí)現(xiàn)。
◆?消息堆積:流量削峰是消息中間件的一個(gè)非常重要的功能,而這個(gè)功能其實(shí)得益于其消息堆積能力。從某種意義上來(lái)講,如果一個(gè)消息中間件不具備消息堆積的能力,那么就不能把它看做是一個(gè)合格的消息中間件。消息堆積分內(nèi)存式堆積和磁盤(pán)式堆積。
◆?消息持久化:持久化確保 MQ 的使用不只是一個(gè)部分場(chǎng)景的輔助工具,而是讓 MQ 能像數(shù)據(jù)庫(kù)一樣存儲(chǔ)核心的數(shù)據(jù)。有些功能是默認(rèn)不開(kāi)啟的,需要進(jìn)行配置。
◆?多租戶: 也可以稱(chēng)為多重租賃技術(shù),是一種軟件架構(gòu)技術(shù),主要用來(lái)實(shí)現(xiàn)多用戶的環(huán)境下公用相同的系統(tǒng)或程序組件,并且仍可以確保各用戶間數(shù)據(jù)的隔離性。RabbitMQ 就能夠支持多租戶技術(shù),每一個(gè)租戶表示為一個(gè) vhost,其本質(zhì)上是一個(gè)獨(dú)立的小型 RabbitMQ服務(wù)器,又有自己獨(dú)立 的隊(duì)列、交換器及綁定關(guān)系等,并且它擁有自己獨(dú)立的權(quán)限。vhost 就像是物理機(jī)中的虛擬機(jī) 一樣,它們?cè)诟鱾€(gè)實(shí)例間提供邏輯上的分離,為不同程序安全保密地允許數(shù)據(jù),它既能將同一 個(gè) RabbitMQ 中的眾多客戶區(qū)分開(kāi),又可以避免隊(duì)列和交換器等命名沖突。
◆?跨語(yǔ)言支持: 對(duì)很多公司而言,其技術(shù)棧體系中會(huì)有多種編程語(yǔ)言,如 C/C++、JAVA、Go、PHP 等,消息 中間件本身具備應(yīng)用解耦的特性,如果能夠進(jìn)一步的支持多客戶端語(yǔ)言,那么就可以將此特性 的效能擴(kuò)大。跨語(yǔ)言的支持力度也可以從側(cè)面反映出一個(gè)消息中間件的流行程度。
◆?消息順序消息:先進(jìn)先出、 逐條進(jìn)行消費(fèi)顧名思義,消息順序性是指保證消息有序。這個(gè)功能有個(gè)很常見(jiàn)的應(yīng)用場(chǎng)景就是 CDC(Change Data Chapture),以 MySQL 為例,如果其傳輸?shù)?binlog 的順序出錯(cuò),比如原本是先對(duì)一條數(shù)據(jù)加 1,然后再乘以 2,發(fā)送 錯(cuò)序之后就變成了先乘以 2 后加 1 了,造成了數(shù)據(jù)不一致。
◆?安全機(jī)制: 在 Kafka 0.9 版本之后就開(kāi)始增加了身份認(rèn)證和權(quán)限控制兩種安全機(jī)制。身份認(rèn)證是指客戶端與服務(wù)端連接進(jìn)行身份認(rèn)證,包括客戶端與 Broker 之間、Broker 與Broker 之間、Broker 與 ZooKeeper 之間的連接認(rèn)證,目前支持 SSL、SASL 等認(rèn)證機(jī)制。權(quán)限控制是指對(duì)客戶端的讀寫(xiě)操作進(jìn)行權(quán)限控制,包括對(duì)消息或 Kafka 集群操作權(quán)限控制。權(quán)限控制是可插拔的,并支持與外部的授權(quán)服務(wù)進(jìn)行集成。對(duì)于 RabbitMQ而言,其同樣提供身份認(rèn)證(TLS/SSL、SASL)和 權(quán)限控制(讀寫(xiě)操作)的安全機(jī)制。
◆?事務(wù)支持: 事務(wù)本身是一個(gè)并不陌生的詞匯,事務(wù)是由事務(wù)開(kāi)始(Begin Transaction)和事務(wù)結(jié)束(End Transaction)之間執(zhí)行的全體操作組成。支持事務(wù)的消息中間件并不在少數(shù),Kafka 和 RabbitMQ 都支持,不過(guò)此兩者的事務(wù)是指生產(chǎn)者發(fā)生消息的事務(wù),要么發(fā)送成功,要么發(fā)送失敗。消息中間件可以作為用來(lái)實(shí)現(xiàn)分布式事務(wù)的一種手段,但其本身并不提供全局分布式事務(wù)的功能。
25、Java 的安全性體現(xiàn)在哪里?
◆?Java SE 安全性概述 Java SE
◆?平臺(tái)基于一個(gè)動(dòng)態(tài)、可擴(kuò)展、基于標(biāo)準(zhǔn)、可互操作的安全架構(gòu)。加密、身份驗(yàn)證和授權(quán)、公共密鑰基礎(chǔ)架構(gòu)等安全特性是內(nèi)置的。Java
◆?安全模型基于一個(gè)可定制的“沙盒”,Java 軟件程序可在其中安全運(yùn)行,對(duì)系統(tǒng)或用戶無(wú)潛在風(fēng)險(xiǎn)。
◆?Java 編譯器和虛擬機(jī)強(qiáng)制實(shí)施的內(nèi)置的語(yǔ)言安全特性:
◆?強(qiáng)大的數(shù)據(jù)類(lèi)型管理
◆?自動(dòng)內(nèi)存管理
◆?字節(jié)碼驗(yàn)證
◆?安全的類(lèi)加載
26、static 方法怎么訪問(wèn)非 static 變量?
類(lèi)的靜態(tài)成員(變量和方法)都屬于類(lèi)本身,在類(lèi)加載的時(shí)候就會(huì)分配內(nèi)存,可以通過(guò)類(lèi)名直接訪問(wèn)
27、講下你理解的 Java 多繼承?
◆?若子類(lèi)繼承的父類(lèi)中擁有相同的成員變量,子類(lèi)在引用該變量時(shí)將無(wú)法判別使用哪個(gè)父類(lèi)的成員變量
◆?若一個(gè)子類(lèi)繼承的多個(gè)父類(lèi)擁有相同方法,同時(shí)子類(lèi)并未覆蓋該方法(若覆蓋,則直接使用子類(lèi)中該方法),那么調(diào)用該方法時(shí)將無(wú)法確定調(diào)用哪個(gè)父類(lèi)的方法。
28、Java 基本類(lèi)型有哪些?
◆?byte 1
◆?short 2
◆?int 4
◆?long 8
◆?float 4
◆?double 8
◆?char 2
◆?boolean 1
29、線程池如果滿了會(huì)怎么樣?
83◆?如果使用的是無(wú)界隊(duì)列 Linke dBlockingQueue,也就是無(wú)界隊(duì)列的話,沒(méi)關(guān)系,繼續(xù)添加任務(wù)到阻塞隊(duì)列中等待執(zhí)行,因?yàn)?LinkedBlockingQueue 可以近乎認(rèn)為是一個(gè)無(wú)窮大的隊(duì)列,可以無(wú)限存放任務(wù)
◆?如果使用的是有界隊(duì)列比如 ArrayBlockingQueue , 任務(wù)首先會(huì)被添加到ArrayBlockingQueue 中,ArrayBlockingQueue 滿了,會(huì)根據(jù) maximumPoolSize 的 值增加線程數(shù)量,如果增加了線程數(shù)量還是處理不過(guò)來(lái),ArrayBlockingQueue 繼續(xù)滿,那么則會(huì)使用拒絕策略 RejectedExecutionHandler 處理滿了的任務(wù),默認(rèn)是AbortPolicy。
30、什么是雙親委派機(jī)制,它有什么作用?
雙親委派機(jī)制的意思是除了頂層的啟動(dòng)類(lèi)加載器以外,其余的類(lèi)加載器,在加載之前,都會(huì)委派給它的父加載器進(jìn)行加載。這樣一層層向上傳遞,直到祖先們都無(wú)法勝任,它才會(huì)真正的加載。
◆?通過(guò)帶有優(yōu)先級(jí)的層級(jí)關(guān)可以避免類(lèi)的重復(fù)加載;
◆?保證 Java 程序安全穩(wěn)定運(yùn)行,Java 核心 API 定義類(lèi)型不會(huì)被隨意替換。
?
總結(jié)
- 上一篇: 手机c语言编译器ide文件位置,C语言编
- 下一篇: 图论及其应用 2016年 期末考试 答案