2019 Java常見面試題解析(二)

86.    如何實現跨域?

實現跨域有以下勵方案:

•     服務器端運行跨域設置CORS等於*;

•     在單個接口使用註解@CrossOrigin運行跨域;

•     使用jsonp跨域;

87.    說一下JSONP實現原理?

jsonp:JSON with Padding,它是利用script標籤的src連接可以訪問不同源的特性,力口載 遠程返回的“JS函數”來執行的。

設計模式

88.    說一下你熟悉的設計模式?

•     單例模式:保證被創建一次,節省系統開銷。

•     工廠模式(簡單工廠、抽象工廠):解耦代碼。

•     觀察者模式:定義了對象之間的一對多的依賴,這樣一來,當一個對象改變時,它的所有的依賴者都會收到通知並自動更新。

•     外觀模式:提供一個統一的接口,用來訪問子系統中的一羣接口,外觀定義了一個高層的接口”讓子系統更容易使用。

•     模版方法模式:定義了一個 算法的骨架,而將一些步驟延遲子類中,模版方法使 得子類可以在不改變算法結構的情況下”重新定義算法的步驟。

•     狀態模式:允許對象在內部狀態改變時改變它的行爲,對象看起來好像修改了它的 類。

89.    簡單工廠和抽象工廠有什麼區別?

•     簡單工廠:用來生產同一等級結構中的任意產品,對於增加新的產品,無能爲力。

•     工廠方法:用來生產同一等級結構中的固定產品,支持增加任意產品。

•     抽象工廠:用來生產不同產品族的全部產品,對於增加新的產品,無能爲力;支持增加產品族。

Spring/Spring MVC

90.爲什麼要使用spring?

•     spring提供ioc技術,容器會幫你管理依賴的對象,從而不需要自己創建和管理依賴對象了,更輕鬆的實現了程序的解耦。

•     spring提供了事務支持,使得事務操作變的更加方便。

•     spring提供了面向切片編程,這樣可以更方便的處理某一類的問題。

•     更方便的框架集成,spring可以很方便的集成其他框架,比如MyBatis、hibernate 等。

91.解釋一下什麼是aop?

aop是面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一 種技術。

簡單來說就是統一處某—“切面”(類)的問題的編程思想,比如統一處理日誌、異常等。

92.    解釋一下什麼是ioc?

ioc: Inversionof Control仲文:控制反轉)是spring的核心,對於spring框架來說,就是由spring來負責控制對象的生命週期和對象間的關係。

簡單來說,控制指的是當前對象對內部成員的控制權;控制反轉指的是,這種控制權不由當前對象管理了,由其他(類,第三方容器)來管理。

93.    spring有哪些主要模塊?

•     spring core:框架的最基礎部分,提供ioc和依賴注入特性。

•     spring context:構建於core封裝包基礎上的context封裝包,提供了一種框架式的對象訪問方法。

•     spring dao: Data Access Object 提供了JDBC的抽象層。

•     springaop:提供了面向切面的編程實現,讓你可以自定義攔截器、切點等。

•     spring Web :提供了針對Web開發的集成特性,例如文件上傳,利用servlet listeners 進行 ioc 容器初始化和針對 Web 的 Applicationcontext,,

•     spring Web mvc : spring 中的 mvc 封裝包提供了 Web 應用的 Model-ViewController (MVC)的實現。

94.    spring常用的注入方式有哪些?

•     setter屬性注入

•     構造方法注入

•     註解方式注入
95.    spring中的bean是線程安全的嗎?

spring中的bean默認是單例模式,spring框架並沒有對單例bean進行多線程的封裝處理。

實際上大部分時候spring bean無狀態的(比如dao類),所有某種程度上來說bean也 是安全的,但如果bean有狀態的話(比如view model對象),那就要開發者自己去保 證線程安全了,最簡單的就是改變bean的作用域,把"singleton”變更爲"prototype",這 樣請求bean相當於new Bean()了,所以就可以保證線程安全了。

•     有狀態就是有數據存儲功能。

•     無狀態就是不會保存數據。

96.    spring支持幾種bean的作用域?

spring支持5種作用域,如下:

•     singleton: springioc容器中只存在—bean實例,bean以單例模式存在,是系統 默認值;

•     prototype:每次從容器調用bean時都會創建一新的示例,既每次getBean()相當 於執行new Bean()操作;

•     Web環境下的作用域:

      •      request:每次http請求都會創建一個 bean;

      •      session:同— http session 共享一個 bean 實例;

      •      global-session :用於 portlet 容器,因爲每個 portlet 有單獨的 session , globalsession 提供一 全局性的 http session.

注意:使用prototype作用域需要慎重的思考”因爲頻繁創建和銷燬bean會帶來很大的性能開銷。

97.    spring自動裝配bean有哪些方式?

•     no:默認值,表示沒有自動裝配,應使用顯式bean引用進行裝配。

•     byName:它根據bean的名稱注入對象依賴項。

•     byType:它根據類型注入對象依賴項。

•     構造函數:通過構造函數來注入依賴項,需要設置大量的參數。

•     autodetect:容器首先通過構造函數使用autowire裝配,如果不能,則通過byType 自動裝配。

98.    spring事務實現方式有哪些?

•     聲明式事務:聲明式事務也有兩種實現方式,基於xml配置文件的方式和註解方式 (在類上添加©Transaction註解)。

•     編碼方式:提供編碼的形式管理和維護事務。
99.    說一下spring的事務隔離?

spring有五大隔離級別,默認值爲ISOLATION_DEFAULT (使用數據庫的設置),其他四個隔離級別和數據庫的隔離級別一致:

ISOLATION_DEFAULT:用底層數據庫的設置隔離級別,數據庫設置的是什麼我就用什 麼;

ISOLATION_READ_UNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其 他事務讀取(會出現幻讀、髒讀、不可重複讀);

ISOLATION_READ_COMMITTED:提交讀,—個事務提交後才能被其他事務讀取到(會造成幻讀、不可重複讀),SQL server的默認級別;

ISOLATION_REPEATABLE_READ:可重複讀,保證多次讀取同一個數據時,其值都和事務 開始時候的內容是一致”禁止讀取到別的事務未提交的數據(會造成幻讀)” MySQL的 默認級別;

ISOLATION_SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒 讀、不可重複讀、幻讀。

髒讀:表示一個事務能夠讀取另一個事務中還未提交的數據。比如,某個事務嘗試插入記錄A,此時該事務還未提交,然後另一個 事務嘗試讀取到了記錄A。

不可重複讀:是指在一個事務內,多次讀同一數據。

幻讀:指同一個事務內多次查詢返回的結果集不一樣。比如同一個事務A第一次查詢時 候有n條記錄,但是第二次同等條件下查詢卻有n+1條記錄,這就好像產生了幻覺。發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集裏面的數 據,同一個記錄的數據內容被修改了,所有數據行的記錄就變多或者變少了。

100.    說一下spring mvc運行流程?

•    spring mvc 先將請求發送給 DispatcherServlet.

•    DispatcherServlet查詢一 或多個 HandlerMapping,找到處理請求的 Controller。

•    DispatcherServlet再把請求提交到對應的Controller.

•    Controller進行業務邏輯處理後,會返回—個ModelAndView.

•    Dispathcher查詢一 或多個ViewResolver視圖解析器,找到ModelAndView對象指 定的視圖對象

•    視圖對象負責渲染返回給客戶端。

101.    spring mvc有哪些組件?

•    前置控制器 DispatcherServlet.

•    映射控制器 HandlerMapping。

•    處理器 Controller。

•    模型和視圖ModelAndView.

•    視圖解析器ViewResolver。

102.    @RequestMapping 的作用是什麼?

將http請求映射到相應的類/方法上。

103.    @Autowired的作用是什麼?

@Autowired它可以對類成員變量、方法及構造函數進行標註,完成自動裝配的工作,通 lS@Autowired的使用來消除set/get方法。

Spring Boot/Spring Cloud

104.    什麼是 spring boot?

spring boot是爲spring服務的,是用來簡化新spring應用的初始搭建以及開發過程的。

105.    爲什麼要用spring boot?

•    配置簡單

•    獨立運行

•    自動裝配

•    無代碼生成和xml配置

•    提供應用監控

•    易上手

•    提升開皴率

106.    spring boot核心酉己置文件是什麼?

spring boot核心的兩個配置文件:

•    bootstrap (. yml 或者.properties): boostrap 由父 Applicationcontext 加載的,比 applicaton優先加載,且boostrap裏面的屬性不能被覆蓋;

•    application (.yml或者. properties):用於spring boot項目的自動化酉己置。

107.    spring boot酉己置文件有哪幾種類型?它們有什麼區別?

配置文件有• properties格式和.yml格式,它們主要的區別是書法風格不同。

・properties配置如下:

     spring・ RabbitMQ・ port=5672

・yml配置如下:

  spring:

     RabbitMQ:

       port: 5672

・yml格式不支持@ Property Source註解導入。

108.    spring boot有哪些方式可以實現熱部署?

•    使用devtools啓動熱部署,添加devtools庫,在配置文件中把spring.devtools.restart.enabled 設置爲 true;

•    使用Intellij Idea編輯器,勾上自動編譯或手動重新編譯。

109.    jpa和hibernate有什麼區別?

jpa全稱Java Persistence API,是Java持久化接口規範,hibernate屬於jpa的具體實現。

110.    什麼是 spring cloud?

spring cloud是一系列框架的有序集合。它利用spring boot的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,都可以用spring boot的開發風格做到一鍵啓動和部署。

111.    spring cloud斷路器的作用是什麼?

在分佈式架構中,斷路器模式的作用也是類似的,當某個服務單元發生故障(類似用電 器發生短路)之後,通過斷路器的故障監控(類似熔斷保險絲),向調用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間佔用不釋放,避免了故障在分佈式系統中的蔓延。

112.    spring cloud的核心組件有哪些?

•    Eureka:服務註冊與發現。

•    Feign:基於動態代理機制,根據註解和選擇的機器,拼接請求url地址,發起請求。

•    Ribbon:實現負載均衡,從一個服務的多臺機器中選一臺。
•    Hystrix:提供線程池,不同的服務走不同的線程池,實現了不同服務調用的隔離, 避免了服務雪崩的問題。

•    Zuul:網關管理,由Zuul網關轉發請求給對應的服務。

Hibernate

113.    爲什麼要使用hibernate?

•    hibernate是對jdbc的封裝,大大簡化了數據訪問層的繁瑣的重複性代碼。

•    hibernate是一個優秀的ORM實現,很多程度上簡化了 DAO層的編碼功能。

•    可以很方便的進行數據庫的移植工作。

•    提供了緩存機制,是程序執行更加的高效。

114.    什麼是ORM 框架?

ORM (Object Relation Mapping)對象關係映射,是把數據庫中的關係數據映射成爲程序中的對象。

使用ORM的優點:提高了開發效率降低了開發成本、開發更簡單更對象化、可移植更強。

115.    hibernate中如何在控制檯查看打印的SQL語句?

在Config裏面把hibernate. show_SQL設置爲true就可以。但不建議開啓,開啓之後會降低程序的運行效率。

116.    hibernate有幾種查詢方式?

三種:hql、原生SQL、條件查詢Criteria。

117.    hibernate實體類可以被定義爲final嗎?

實體類可以定義爲final類,但這樣的話就不能使用hibernate代理模式下的延遲關聯提供性能了,所以不建議定義實體類爲final。

118.    在hibernate中使用Integer和int做映射有什麼區別?

Integer類型爲對象,它的值允許爲null,而int屬於基礎數據類型,值不能爲null。

119. hibernate是如何工作的?

•    讀取並解析配置文件。

•    讀取並解析映射文件,創建SessionFactory.

•    打開 Session。

•    創建事務。

•    進行持久化操作。

•    提交事務。

•    關閉 Session.

•    關閉 Session Factory。

120.    get()和 load()的區別?

•    數據查詢時,沒有OID指定的對象,get()返回null; load()返回一個代理對象。

•    load ()支持延遲加載;get()不支持延遲加載。

121.    說一下hibernate的緩存機制?

hibernate常用的緩存有一級緩存和二級緩存:

—級緩存:也叫Session緩存,只在Session作用範圍內有效,不需要用戶干涉,由 hibernate自身維護,可以通過:evict(object)清除object的緩存;clear()清除一級緩存中 的所有緩存;flush()刷出緩存;

二級緩存:應用級別的緩存,在所有Session中都有效,支持配置第三方的緩存,如: EhCache.

122.    hibernate對象有哪些狀態?

•    臨時/瞬時狀態:直接new出來的對象,該對象還沒被持久化(沒保存在數據庫 中),不受Session管理。

•    持久化狀態:當調用Session的save/saveOrupdate/get/load/list等方法的時候,對象是持久化狀態。

•    遊離狀態:Session關閉之後對象就是遊離狀態。

123.    在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?

•    getCurrentSession會綁定當前線程,而openSession則不會。

•    getCurrentSession事務是Spring控制的,並且不需要手動關閉,而openSession需 翹們自己手動開啓和提交事務。

124.    hibernate實體類必須要有無參構造函數嗎?爲什麼?

hibernate中每個實體類必須提供一個無參構造函數,因爲hibernate框架要使用 reflection api,通過調用Classnewlnstance()來創建實體類的實例,如果沒有無參的構造函數就會拋出異常。

MyBatis

125.    MyBatis中#{}和${}的區別是什麼?

\#{}是預編譯處理,${}是字符替換。

在使用#{}時,MyBatis會將SQL中的#{}替換成"?酉己合PreparedStatement的set 方法賦值,這樣可以有效的防止SQL注入,保證程序的運行安全。

126.    MyBatis有幾種分頁方式?

分頁方式:邏輯分頁和物理分頁。

邏輯分頁:使用MyBatis自帶的RowBounds進行分頁,它是一次性查詢很多數據,然後在數據中再進行檢索。

物理分頁:自己手寫SQL分頁或使用分頁插件PageHelper,去數據庫查詢指定條數的分頁數據的形式。

127.    RowBounds是一次性查詢全部結果嗎?爲什麼?

RowBounds表面是在“所有”數據中檢索數據”其實並非是一次性查詢出所有數據”因爲 MyBatis是對jdbc的封裝,在jdbc驅動中有一個Fetch Size的配置,它規定了每次最多從 數據庫查詢多少條數據,假如你要查詢更多數據,它會在你執行next()的時候,去查詢 更多的數據。就好比你去自動取款機取10000元但取款機每次最多能取2500元 所以 你要取4次才能把錢取完。只是對於jdbc來說,當你調用next()的時候會自動幫你完成 查詢工作。這樣做的好處可以有效的防止內存溢出。

Fetch Size 官方相關文檔:http://t. cn/EfSE2g3

128.    MyBatis邏輯分頁和物理分頁的區別是什麼?

•    邏輯分頁是一次性查詢很多數據,然後再在結果中檢索分頁的數據。這樣做弊端是 需要消耗大量的內存、有內存溢出的風險、對數據庫壓力較大。

•    物理分頁是從數據庫查詢指定條數的數據,彌補了一次性全部查出的所有數據的種種缺點,比如需要大量的內存,對數據庫查詢壓力較大等問題。

129.    MyBatis是否支持延遲加載?延遲加載的原理是什麼?

MyBatis 支持延遲加載,設置 lazyLoadingEnabled=true 即可。

延遲加載的原理的是調用的時候觸發加載,而不是在初始化的時候就加載信息。比如調 用a. getB(). getName(),這個時候發現a. getB()的值爲null,此時會單獨觸發事先保存好 的關聯B對象的SQL,先查詢出來B,然後再調用a.setB(b),而這時候再調用a.getB(). getName()就有值了,這就是延遲加載的基本原理。

130.    說一下MyBatis的一級緩存和二級緩存?

•    —級緩存:基於PerpetualCache的HashMap本地緩存,它的聲明週期是和 SQLSession—致的,有多個SQLSession或者分佈式的環境中數據庫操作,可能會 出現髒數據。當Session flush或close之後,該Session中的所有Cache就將清空, 默認一級緩存是開啓的。

•    二級緩存:也是基於PerpetualCache的HashMap本地緩存,不同在於其存儲作用 域爲Mapper級別的”如果多個SQLSession之間需要共享緩存”則需要使用到二級 緩存,並且二級緩存可自定義存儲源,如Ehcache.默認不打開二級緩存,要開啓 二級緩存,使用二級緩存屬性類需要實現Serializable序列化接口(可用來保存對象 的狀態)。

開啓二級緩存數據查詢流程:二級緩存-> 一級緩存-> 數據庫。

緩存更新機制:當某一個作用域(一級緩存Session/二級緩存Mapper)進行了C/U/D操作 後,默認該作用域下所有select中的緩存將被clear.

131.    MyBatis和hibernate的區別有哪些?

•    靈活性:MyBatis更加靈活,自己可以寫SQL語句,使用起來比較方便。

•    可移植性:MyBatis有很多自己寫的SQL,因爲每個數據庫的SQL可以不相同,所以可移植性比較差。

•    學習和使用門檻:MyBatis入門比較簡單,使用門檻也更低。

•    二級緩存:hibernate擁有更好的二級緩存,它的二級緩存可以自行更換爲第三方 的二級緩存。

132.    MyBatis有哪些執行器(Executor) ?

MyBatis有三種基本的Executor執行器:

•    SimpleExecutor:每執行一次 update或select就開啓一個 Statement對象,用完立刻關閉Statement對象;

•    ReuseExecutor:執行 update 或 select,以 SQL 作爲 key查找 Statement 對象,存在就使用,不存在就創建,用完後不關閉Statement對象,而是放置於Map內供下一 次使用。簡言之,就是重複使用Statement對象;

•    BatchExecutor:執行 update (沒有 select, jdbc 批處理不支持 select),將所有 SQL都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存 了多個Statement對象,每個Statement對象都是addBatch()完畢後,等待逐一執 行executeBatch()批處理,與jdbc批處理相同。
133.    MyBatis分頁插件的實現原理是什麼?

分頁插件的基本原理是使用MyBatis提供的插件接口,實現自定義插件,在插件的攔截 方法內攔截待執行的SQL,然後重寫SQL,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。

134.    MyBatis如何編寫一個自定義插件?

自定義插件的實現原理

MyBatis 自 定義插件針對 MyBatis 四大對象(Executor、StatementHandler、 ParameterHandler、ResultSetHandler)進行攔截:

•    Executor:攔截內部執行器,它負責調用StatementHandler操作數據庫,並把結果集通過ResultSetHandler進行自動映射,另外它還處理了二級緩存的操作;

•    StatementHandler:攔截SQL語法構建的處理,它是MyBatis直接和數據庫執行 SQL腳本的對象,另外它也實現了 MyBatis的一級緩存;

•    ParameterHandler:攔截參數的處理;

•    ResultSetHandler:攔截結果集的處理。

自定義的實現關鍵

MyBatis插件要實現Interceptor接口,接口包含的方法,如下:

public interface Interceptor {

Object invocation(InvocatTon invocation) throws Throwable;

Object plugin(Object target);

void setProperties(Properties properties);

}

•    setProperties方法是在MyBatis進行配置插件的時候可以配置自定義相關屬性, 即:接口實現對象的參數配置;

•    phgin方法是插件用於封裝目標對象的,通過該方法我們可以返回目標對象本身” 也可以返回一個它的代理”可以決定是否要進行攔截進而決定要返回一個什麼樣的目標對象,官方提供了示例: return Plugin. wrap(target, this);

•    intercept方:去就是要進行攔截的時候要執行的方法。

自定義插件實現示例

官方插件實現:

@Intercepts({@Signature(type = Executor.class, method = "query" args = {MappedStatement・ class, Object・ class3 RowBounds・ class, ResultHandler.class})})

public class Testinterceptor  implements Interceptor {

public Object intercept(InvocatTon invocation) throws Throwable {

Object target = invocation.getTarget(); //被代理對象

Method method = invocation.getMethod(); //代理方法

Object[] args = invocation.getArgs(); //方法參數

// do something    方法攔截前執行代碼塊

Object result = invocation. proceed();

// do something    方法攔截後執行代碼塊

return result;

}

public Object plugin(Object target) {

       return Plugin・ wrap(target5 this);

    }

}

 

RabbitMQ

135.    RabbitMQ的使用場景有哪些?

•    搶購活動,削峯填谷,防止系統崩塌。

•    延遲信息處理,比如10分鐘之後給下單未付款的用戶發送郵件提醒。

•    解耦系統,對於新增的功能可以單獨寫模塊擴展”比如用戶確認評價之後”新增了 給用戶返積分的功能”這個時候不用在業務代碼裏添加新增積分的功能,只需要把 新增積分的接口訂閱確認評價的消息隊列即可,後面再添加任何功能只需要訂閱對 應的消息隊列即可。

136.    RabbitMQ有哪些重要的角色?

RabbitMQ中重要的角色有:生產者、消費者和代理:

•    生產者:消息的創建者,負責創建和推送數據到消息服務器;

•    消費者:消息的接收方”用於處理數據和確認消息;

•    代理:就是RabbitMQ本身,用於扮演“快遞”的角色,本身不生產消息,只是扮演“快遞的角色。

137.    RabbitMQ有哪些重要的組件?

•    ConnectionFactory (連接管理器):應用程序與Rabbit之間建立連接的管理器,程序代碼中使用。

•    Channel (信道):消息推送使用的通道。

•    Exchange (交換器):用於接受、分配消息。

•    Queue (隊列):用於存儲生產者的消息。

•    RoutingKey (路由鍵):用於把生成者的數據分配到交換器上。

•    BindingKey (綁定鍵):用於把交換器的消息綁定到隊列上

138.    RabbitMQ中vhost的作用是什麼?

vhost:每個RabbitMQ都能創建很多vhost,我們稱之爲虛擬主機,每個虛擬主機其實都 是mini版的RabbitMQ,它擁有自己的隊列,交換器和綁定,擁有自己的權限機制。

139.    RabbitMQ的消息是怎麼發送的?

首先客戶端必須連接到RabbitMQ服務器才能發佈和消費消息,客戶端和rabbit server之 間會創建一個tcp連接,一旦tcp打開並通過了認證(認證就是你發送給rabbit服務器的 用戶名和密碼),你的客戶端和RabbitMQ就創建了一條amqp信道(channel),信道 是創建在"真實"tcp上的虛擬連接,amqp命令都是通過信道發送出去的,每個信道都會 有一個唯一的id,不論是發佈消息”訂閱隊列都是通過這個信道完成的。

140.    RabbitMQ怎麼保證消息的穩定性?

•    提供了事務的功能。

•    通過將channel設置爲confirm (確認)模式。

141.    RabbitMQ怎麼避免消息丟失?

•    把消息持久化磁盤,保證服務器重啓消息不丟失。

•    每個集羣中至少有一個物理磁盤,保證消息落入磁盤。

142.    要保證消息持久化成功的條件有哪些?

•    聲明隊列必須設置持久化durable設置爲true.

•    消息推送投遞模式必須設置持久化,deliveryMode設置爲2 (持久)。

•    消息已經到達持久化交換器。

•    消息已經到達持久化隊列。

以上四個條件都滿足才能保證消息持久化成功。

143.    RabbitMQ持久化有什麼缺點?

持久化的缺點就是降低了服務器的吞吐量,因爲使用的是磁盤而非內存存儲,從而降低 了吞吐量。可儘量使用ssd硬盤來緩解吞吐量的問題。

144.    RabbitMQ有幾種廣播類型?

•    direct (默認方式):最基礎最簡單的模式,發送方把消息發送給訂閱方,如果有 多個訂閱者,默認採取輪詢的方式進行消息發送。

•    headers:與direct類似,只是性能很差,此類型幾乎用不到。

•    fanout:分發模式,把消費分發給所有訂閱者。

•    topic:匹配訂閱模式,使用正則匹配到消息隊列,能匹配到的都能接收到。

145.    RabbitMQ怎麼實現延遲消息隊列?

隊列的實現有兩種方式:

•    通過消息過期後進入死信交換器”再由交換器轉發到延遲消費隊列,實現延遲功 能;

•    使用 RabbitMQ-delayed-message-exchange 插件實現延遲功能。

146.    RabbitMQ集羣有什麼用?

集羣主WW以下兩個用途:

•    高可用:某個服務器出現問題,整個RabbitMQ還可以繼續使用;

•    高容量:集羣可以承載更多的消息量。

147.    RabbitMQ節點的類型有哪些?

•    磁盤節點:消息會存儲到磁盤

•    內存節點:消息都存儲在內存中,重啓服務器消息丟失,性能高於磁盤類型。

148.    RabbitMQ集羣搭建需要注意哪些問題?

•    各節點之間使用“-link”連接,此屬性不能忽略。

•    各節點使用的erlang cookie值必須相同,此值相當於“祕鑰的功能,用於各節點的 認證。

•    整個集羣中必須包含一個磁盤節點。

149.    RabbitMQ每個節點是其他節點的完整拷貝嗎?爲什麼?

不是,原因有以下兩個:

•    存儲空間的考慮:如果環節點都擁有所有隊列的完全拷貝,這樣新增節點不但沒 有新增存儲空間,反而增加了更多的冗餘數據;

•    性能的考慮:如果每條消息都需要完整拷貝到每一個集羣節點,那新增節點並沒有 提升處理消息的能力,最多是保持和單節點相同的性能甚至是更糟。

150. RabbitMQ集羣中唯一 一個磁盤節點崩潰了會發生什麼情況?

如果唯一磁盤的磁盤節點崩潰了,不能進行以下操作:

•    不能創建隊列

•    不能創建交換器

•    不能創建綁定

•    不能添加用戶

•    不能更改權限

•    不能添加和刪除集羣節點

唯一一個集羣節點崩潰了,集羣是可以保持運行的”但你不能更改任何東西。

151. RabbitMQ對集羣節點停止順序有要求嗎?

RabbitMQ對集羣的停止的順序是有要求的,應該先關閉內存節點,最後再關閉磁盤節 點。如果順序恰好相反的話,可能會造成消息的丟失。

Kafka

152.    kafka可以脫離zookeeper單獨使用嗎?爲什麼?

kafka不能脫離zoo keeper單獨使用,因爲kafka使用zoo keeper管理和協調kafka的節點 服務器。

153.    kafka有幾種數據保留的策略?

kafka有兩種數據保存策略:按照過期時間保留和按照存儲的消息大小保留。

154.    kafka同時設置了 7天和10G清除數據,到第五天的時候消息達到 了 10G,這個時候kafka將如何處理?

這個時候kafka會執行數據清除工作,時間和大小不論那個滿足條件”都會清空數據。

155.    什麼情況會導致kafka運行變慢?

•    CPU性能瓶頸

•    磁盤讀寫瓶頸

•    網絡瓶頸

156.使用kafka集羣需要注意什麼?
•   集羣的數量不是越多越好,最好不要超過7個,因爲節點越多,消息複製需要的時 間就越長,整個羣組的吞吐量就越低。

•   塞羣數量最好是單數,因爲超過一半故障集羣就不能用了,設置爲單數容錯率更高。

Zookeeper

157.    zookeeper 是什麼?

zookeeper是一個分佈式的,開放源碼的分佈式應用程序協調服務,是google chubby的 開源實現,是hadoop和hbase的重要組件。它是一個爲分佈式應用提供一致性服務的 軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。

158.    zookeeper都有哪些功能?

•   集羣管理:監控節點存活狀態、運行請求等。

•   主節點選舉:主節點掛掉了之後可以從備用的節點開輪選主,主節點選舉說 的就是這個選舉的過程,使用zookeeper可以協助完成這個過程。

•   分佈式鎖:zookeeper提供兩種鎖:獨佔鎖、共享鎖。獨佔鎖即一次只能有一個線 程使用資源,共享鎖是讀鎖共享,讀寫互斥,即可以有多線線程同時讀同一個資 源,如果要使用寫鎖也只能有一個線程使用。zookeeper可以對分佈式鎖進行控 制。

•   命名服務:在分佈式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來 獲取資源或服務的地址提供者等信息。

159.    zookeeper有幾種部署模式?

zookeeper有三種部署模式:

•   單機部署:一臺集羣上運行;

•   集羣部署:多臺集羣運行;

•   僞集羣部署:一臺集羣啓動多個zookeeper實例運行。

160.    zookeeper怎麼保證主從節點的狀態同步?

zookeeper的核心是原子廣播,這個機制保證了各個server之間的同步。實現這個機制的 協議叫做zab協議。zab協議有兩種模式,分別是恢復模式(選主)和廣播模式(同 步)。當服務啓動或者在領導者崩潰後,zab就進入了恢復模式,當領導者被選舉出來,且大多數server完成了和leader的狀態同步以後,恢復模式就結束了。狀態同步保 證了 leader和server具有相同的系統狀態。

161.集羣中爲什麼要有主節點?

在分佈式環境中,有些業務邏輯只需要集羣中的某一臺機器進行執行,其他的機器可以共享這個結果,這樣可減少重複計算,提高性能,所以就需要主節點。

162.集羣中有3臺服務器,其中一個節點宕機,這個時候zookeeper還 可以使用嗎?

可以繼續使用,單數服務器只要沒超過一半的服務器宕機就可以繼續使用。

163.說一下zookeeper的通知機制?

客戶端端會對某個znode建立一個watcher事件,當該znode發生變化時,這些客戶端 會收到zookeeper的通知,然後客戶端可以根據znode變化來做出業務上的改變。

MySQL

164.數據庫的三範式是什麼?

•   第一範式:強調的是列的原子性,即數據庫表的每一列都是不可分割的原子數據項。

•   第二範式:要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性。

•   第三範式:任何非主屬性不依賴於其它非主屬性。

165•—張自增表裏面總共有7條數據,刪除了最後2條數據,重啓 MySQL數據庫,又插入了一條數據,此時id是幾?

•   表類型如果是MylSAM ,那id就是8.

•   表類型如果是InnoDB,那id就是6。

InnoDB表只會把自增主鍵的最大id記錄在內存中,所以重啓之後會導致最大id丟失。

166.如何獲取當前數據庫版本?

使用select version()獲取當前MySQL數據庫版本。

167.說一下ACID是什麼?
•    Atomicity (原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。

•    Consistency (一致性):在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設約束、觸發器、級聯回滾等。

•    Isolation (隔離性):數據庫允許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致數據的不一致。事務隔離分爲不同級別,包括讀未提交(Read uncommitted )、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable) „

•     Durability (持久性):事務處理結束後”對數據的修改就是永久的”即便系統故障也不會丟失。

168.    char和varchar的區別是什麼?

•      char(n):固定長度類型,比如訂閱char(10),當你輸入”abc”三個字符的時候,它們佔的空間還是10個字節,其他7個是空字節。

chat優點:效率高;缺點:佔用空間;適用場景:存儲密碼的md5值,固定長度的,使用char非常合適。

•     varchar(n):可變長度,存儲的值是每個值佔用的字節再加上一個用來記錄其長度的字節的長度

所以,從空間上考慮varcahr比較合適;從效率上考慮char比較合適,二者使用需要權衡。

169.    float和double的區別是什麼?

•      float最多可以存儲8位的十進制數,並在內存中佔4字節。

•      double最可可以存儲16位的十進制數,並在內存中佔8字節。

170.    MySQL的內連接、左連接、右連接有什麼區別?

內連接關鍵字:inner join;左連接:left join;右連接:right join.

內連接是把匹配的關聯數據顯示出來;左連接是左邊的表全部顯示出來”右邊的表顯示出符合條件的數據;右連接正好相反。

171.    MySQL索引是怎麼實現的?

索引是滿足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。

具體來說MySQL中的索引,不同的數據引擎實現有所不同,但目前主流的數據庫引擎的索引都是B+樹實現的” B+樹的搜索效率,可以到達二分法的性能,找到數據區域之後 就找到了完整的數據結構了,所有索引的性能也是更好的。

172.    怎麼驗證MySQL的索引是否滿足需求?

使用explain查看SQL如何執行查詢語句的,從而分析你的索引是否滿足需求。

explain 語法:explain select * from table where type=l„

173.    說一下數據庫的事務隔離?

MySQL的事務隔離是在MySQL.ini配置文件裏添加的,在文件的最後添加:

transaction-isolation = REPEATABLE-READ

可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、 SERIALIZABLE.

•      READ-UNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其他事務讀取(會出現幻讀、髒讀、不可重複讀).

•      READ-COMMITTED:提交讀,一個事務提交後才能被其他事務讀取到(會造成幻 讀、不可重複讀).

•      REPEATABLE-READ:可重複讀,默認級別,保證多次讀取同一個數據時,其值都和事務開始時候的內容是一致”禁止讀取到別的事務未提交的數據(會造成幻讀).

•      SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不 可重複讀、幻讀。

髒讀:表示一個事務能夠讀取另一個事務中還未提交的數據。比如,某個事務嘗試插入記錄A,此時該事務還未提交,然後另一個 事務嘗試讀取到了記錄A。

不可重複讀:是指在一個事務內,多次讀同一數據。

幻讀:指同一個事務內多次查詢返回的結果集不一樣。比如同一個事務A第一次查詢時 候有n條記錄,但是第二次同等條件下查詢卻有n+1條記錄,這就好像產生了幻覺。發 生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集裏面的數據,同一個記錄的數據內容被修改了”所有數據行的記錄就變多或者變少了。

174.說一下MySQL常用的引擎?

•      InnoDB引擎:InnoDB引擎提供了對數據庫acid事務的支持,並且還提供了行級鎖 和外鍵的約束,它的設計的目標就是處理大數據容量的數據庫系統。MySQL運行 的時候,InnoDB會在內存中建立緩衝池,用於緩衝數據和索引。但是該引擎是不支持全文搜索,同時啓動也比較的慢,它是不會保存表的行數的,所以當進行select count(*) from table指令的時候,需要進行掃描全表。由於鎖的粒度小,寫操 作是不會鎖定全表的,所以在併發度較高的場景下使用會提升效率的。

•      MylASM引擎:MySQL的默認引擎,但不提供事務的支持,也不支持行級鎖和外鍵。因此當執行插入和更新語句時,即執行寫操作的時候需要鎖定這個表,所以會導致效率會降低。不過和InnoDB不同的是,MylASM引擎是保存了表的行數,於是 當進行select count(*) from table語句時,可以直接的讀取已經保存的值而不需要進行掃描全表。所以,如果表的讀操作遠遠多於寫操作時”並且不需要事務的支持 的,可以將MylASM作爲數據庫引擎的首選。

175.    說一下MySQL的行鎖和表鎖?

MylSAM只支持表鎖,InnoDB支持表鎖和行鎖,默認爲行鎖。

•      表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的概率最高,

•      行級鎖:開銷尢力口鎖慢”會出現死鎖。鎖力度小,發生鎖衝突的概率小,併發度最高。

176.    說一下樂觀鎖和悲觀鎖?

•      樂觀鎖:每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。

•      悲觀鎖:每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。

數據庫的樂觀鎖需要自己實現,在表裏面添加一個version字段,每次修改成功值加1, 這樣每次修改的時候先對比一下,自己擁有的version和數據庫現在的version是否一 致,如果不一致就不修改,這樣就實現了樂觀鎖。

177.    MySQL問題排查都有哪些手段?

•     使用show processlist命令查看當前所有連接信息。

•     使用explain命令SQL語句執行計劃。

•     開啓慢查詢日誌,查看慢查詢的SQL。

178.    如何做MySQL的性能優化?

•     爲搜索字段創建索引。

•     避免使用select*,列出需要查詢的字段。

•     垂直分割分表。

•     選擇正確的存儲引擎。

Redis

179.    Redis是什麼?都有哪些使用場景?

Redis是一個使用C語言開發的高速緩存數據庫。

Redis使用場景:

•     記錄帖子點贊數、點擊數、評論數;

•     緩存近期熱帖;

•     緩存文章詳情信息;

•     記錄用戶會話信息。

180.    Redis有哪些功能?

•     數據緩存功能

•     分佈式鎖的功能

•     支持數持久化

•     支持事務

•     支持消息隊列

181.    Redis和memcache有什麼區別?

•     存儲方式不同:memcache把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小;Redis有部份存在硬盤上,這樣能保證數據的持久性。

•     數據支持類型:memcache對數據類型支持相對簡單;Redis有複雜的數據類型。

•     使用底層模型不同:它們之間底層實現方式,以及與客戶端之間通信的應用協議不 一樣,Redis自己構建了 vm機制,因爲一般的系統調用系統函數的話,會浪費一 定的時間去移動和請求。

•     value值大小不同:Redis最大可以達到1GB; memcache只有1MB。

182.    Redis爲什麼是單線程的?

因爲cpu不是Redis的瓶頸,Redis的瓶頸最有可能是機器內存或者網絡帶寬。既然單線程容易實現,而且cpu又不會成爲瓶頸,那就順理成章地採用單線程的方案了。

關於Redis的性能,官方網站也有,普通筆記本輕鬆處理每秒幾十萬的請求。

而且單線程並不代表就慢nginx和nodejs也都是高性能單線程的代表。

183•什麼是緩存穿透?怎麼解決?

緩存穿透:指查詢一個一定不存在的數據,由於緩存是不命中時需要從數據庫查詢,查 不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到數據庫去查詢,造成緩存穿透。

解決方案:最簡單粗暴的方法如果一個查詢返回的數據爲空(不管是數據不存在,還是系統故障),我們就把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分 鍾。

184.    Redis支持的數據類型有哪些?

Redis支持的數據類型:string (字符串)、list (列表)、hash (字典)、set (集合)、 zset (有序集合).

185.    Redis支持的Java客戶端都有哪些?

支持的 Java 客戶端有 Redisson、jedis、lettuce 等。

186.    jedis和Redisson有哪些區別?

•    jedis:提供了比較全面的Redis命令的支持。

•    Redisson:實現了分佈式和可擴展的Java數據結構,與jedis相比Redisson的功能相對簡單,不支持排序、事務、管道、分區等Redis特性。

187.    怎麼保證緩存和數據庫數據的一致性?

•     合理設置緩存的過期時間。

•     新增、更改、刪除數據庫操作時同步更新Redis,可以使用事物機制來保證數據的 —致性。

188.    Redis持久化有幾種方式?

Redis的持久化有兩種方式,或者說有兩種策略:

•    RDB (Redis Database):指定的時間間隔能對你的數據進行快照存儲。

•    AOF (Append Only File):每一 個收到的寫命令都通過write函數追加到文件中。

189.    Redis怎麼實現分佈式鎖?

Redis分佈式鎖其實就是在系統裏面佔一坑”,其他程序也要佔'坑的時候,佔用成功 了就可以繼續執行,失敗了就只能放棄或稍後重試。

佔坑—般使用setnx(set if not exists)指令,只允許被一個程序佔有,使用完調用del釋放 鎖。

190.    Redis分佈式鎖有什麼缺陷?

Redis分佈式鎖不能解決超時的問題,分佈式鎖有一個超時時間,程序的執行如果超出了 鎖的超時時間就會出現問題。

191.    Redis如何做內存優化?

儘量使用Redis的散列表,把相關的信息放到散列表裏面存儲,而不是把每個字段單獨 存儲,這樣可以有效的減少內存使用。比如將Web系統的用戶對象,應該放到散列表裏面再整體存儲到Redis,而不是把用戶的姓名、年齡、密碼、郵箱等字段分別設置key進行存儲。

192.    Redis淘汰策略有哪些?

•     volatile-lru:從已設置過期時間的數據集(server. db[i]. expires)中挑選最近最少使用的數據淘汰。

•     volatile-ttl:從已設置過期時間的數據集(server. db[i]. expires)中挑選將要過期的數據淘汰。

•     volatile-random:從已設置過期時間的數據集(server. db[i]. expires)中任意選擇數據淘汰。

•     allkeys-lru:從數據集(server. db[i]. dict)中挑選最近最少使用的數據淘汰。

•     allkeys-random:從數據集(server. db[i]. dict)中任意選擇數據淘汰。

•     no-enviction (驅逐):禁止驅逐數據。

193.    Redis常見的性能問題有哪些?該如何解決?

•     主服務器寫內存快照,會阻塞主線程的工作,當快照比較大時對性能影響是非常大 的,會間斷性暫停服務,所以主服務器最好不要寫內存快照。

•      Redis主從複製的性能問題,爲了主從複製的速度和連接的穩定性,主從庫最好在同一局域網內。

JVM

194.說一下JVM的主要組成部分?及其作用?

•     類加載器(ClassLoader)

•     運行時數據區(Runtime Data Area)

•     執行引擎(Execution Engine)

•     本地庫接口(Native Interface)

組件的作用:首先通過類加載器(ClassLoader)會把Java代碼轉換成字節碼”運行時 數據區(Runtime Data Area)再把字節碼加載d到內存中,而字節碼文件只是JVM的一套指令集規範,並不能直接交給底層操作系統去執行,因此需要特定的命令解析器執行引 擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由CPU去執行,而這個過程中需要調用其他語言的本地庫接口 (Native Interface)來實現整個程序的功能。

195.說一下JVM運行時數據區?

不同虛擬機的運行時數據區可能略微有所不同,但都會遵從Java虛擬機規範,Java虛 擬機規範規定的區域分爲以下5桶分:

•     程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工作是通過改變這個計數器的值”來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能”都需要依賴這個 計數器來完成;

•     Java虛擬機棧(Java Virtual Machine Stacks):用於存儲局部變量表、操作數棧、 動態鏈接、方法出口等信息;

•     本地方法棧(Native Method Stack):與虛擬機棧的作用是一樣的,只不過虛擬機棧是服務Java方法的,而本地方法棧是爲虛擬機調用Native方法服務的;

•     Java堆(Java Heap) : Java虛擬機中內存最大的一塊,是被所有線程共享的,幾乎所有的對象實例都在這裏分配內存;

•     方法區(MethedArea):用於存儲已被虛擬機加載的類信息、常量、靜態變量、 即時編譯後的代碼等數據。

196•說一下堆棧的區別?

•     功能方面:堆是用來存放對象的,棧是用來執行程序的。

•     共享性:堆是線程共享的,棧是線程私有的。

•     空間大小:堆大小遠遠大於棧。

197.隊列和棧是什麼?有什麼區別?

隊列和棧都是被用來預存儲數據的。

隊列允許先進先出檢索元素,但也有例外的情況,Deque接口允許從兩端檢索元素。

棧和隊列很相似,但它運行對元素進行後進先出進行檢索。

198.    什麼是雙親委派模型?

在介紹雙親委派模型之前先說下類加載器。對於任意一個類,都需要由加載它的類加載器和這個類本身一同確立在JVM中的唯一性”每一個類加載器,都有一個獨立的類名稱空間。類加載器就是根據指定全限定名稱將class文件加載到JVM內存,然後再轉化爲 class對象。

類加載器分類:

•     啓動類加載器(Bootstrap ClassLoader),是虛擬機自身的一部分,用來加載 Java_HOME/lib/目錄中的,或者被-Xbootclasspath參數所指定的路徑中並且被虛擬機識別的類庫;

•     其他類加載器:

     •     擴展類加載器(Extension ClassLoader):負責加載\lib\ext目錄或Java. ext. dirs系統變量指定的路徑中的所有類庫;

     •     應用程序類加載器(Application ClassLoader)。負責加載用戶類路徑 (classpath)上的指定類庫,我們可以直接使用這個類加載器。一般情況, 如果我們沒有自定義類加載器默認就是用這個加載器。

雙親委派模型:如果一個類加載器收到了類加載的請求,它首先不會自己去加載這個 類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣所有 的加載請求都會被傳送到頂層的啓動類加載器中,只有當父加載無法完成加載請求(它 的搜索範圍中沒找到所需的類)時,子加載器纔會嘗試去加載類。

199.    說一下類裝載的執行過程?

類裝載分爲以下5個步驟:

•     加載:根據查找路徑找到相應的class文件然後導入;

•     檢查:檢查加載的class文件的正確性;

•     準備:給類中的靜態變量分配內存空間;

•     解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解爲一 個標示,而在直接引用直接指向內存中的地址;

•     初始化:對靜態變量和靜態代碼塊執行初始化工作。

200.    怎麼判斷對象是否可以被回收?

一般有兩種方法來判斷:

•     引用計數器:爲每個對象創建一個引用計數,有對象引用時計數器+1,引用被釋放時計數-1當計數器爲0時就可以被回收。它有一個缺點不能解決循環引用的問題;

•     可達性分析:從GC Roots開始向下搜索,搜索所走過的路徑稱爲引用鏈。當一個 對象到GC Roots沒有任何引用鏈相連時,則證明此對象是可以被回收的。

201.    Java中都有哪些引用類型?

•     強引用:發生gc的時候不會被回收。

•     軟引用:有用但不是必須的對象,在發生內存溢出之前會被回收。

•     弱引用:有用但不是必須的對象,在下一次GC時會被回收。

•     虛引用(幽靈引用/幻影引用):無法通過虛引用獲得對象,用PhantomReference 實現虛引用,虛引用的用途是在gc時返回一個通知。

202.    說一下JVM有哪些垃圾回收算法?

•     標記-清除算法:標記無用對象,然後進行清除回收。缺點:效率不高,無法清除 垃圾碎片。

•     標記-整理算法:標記無用對象,讓所有存活的對象都向一端移動,然後直接清除 掉端邊界以外的內存。

•     複製算法:按照容量劃分二個大小相等的內存區域,當一塊用完的時候將活着的對 象複製到另一塊上,然後再把已使用的內存空間一次清理掉。缺點:內存使用率不高,只有原來的一半。

•     分代算法:根據對象存活週期的不同將內存劃分爲幾塊,一般是新生代和老年代, 新生代基本採用複製算法,老年代採用標記整理算法。

203.    說一下JVM有哪些垃圾回收器?

•     Serial:最早的單線程串行垃圾回收器。

•     Serial Old: Serial垃圾回收器的老年版本,同樣也是單線程的,可以作爲CMS垃圾 回收器的備選預案。

•     ParNew:是Serial的多線程版本,

•     Parallel和ParNew收集器類似是多線程的,但Parallel是吞吐量優先的收集器”可 以犧牲等待時間換取系統的吞吐量。

•     Parallel Old是Parallel老生代版本,Parallel使用的是複製的內存回收算法,Parallel Old使用的是標記-整理的內存回收算法。

•     CMS: 一種以獲得最短停頓時間爲目標的收集器”非常適用B/S系統。

•     G1:—種兼顧吞吐量和停頓時間的GC實現,是JDK9以後的默認GC選項。

204.    詳細介紹一下CMS垃圾回收器?

CMS是英文Concurrent Mark-Sweep的簡稱,是以犧牲吞吐量爲代價來獲得最短回收停頓時間的垃圾回收器。對於要求服務器響應速度的應用上,這種垃圾回收器非常適合。在 啓動JVM的參數加上"-XX:+UseConcMarkSweepGC"來指定使用CMS垃圾回收器。

CMS使用的是標記-清除的算法實現的,所以在gc的時候回產生大量的內存碎片,當剩餘內存不能滿足程序運行要求時,系統將會出現Concurrent Mode Failure,臨時CMS會 採用Serial Old回收器進行垃圾清除,此時的性能將會被降低。

205.    新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?

•     新生代回收器:Serial 、ParNew、Parallel Scavenge

•     老年代回收器:Serial Old、 Parallel Old、 CMS

•     整堆回收器:G1

新生代垃圾回收器一般採用的是複製算法,複製算法的優點是效率高,缺點是內存利用 率低;老年代回收器一般採用的是標記-整理的算:去進行垃圾回收。

206.    簡述分代垃圾回收器是怎麼工作的?

分代回收器有兩個分區:老生代和新生代,新生代默認的空間佔比總空間的1/3,老生代 的默認佔比是2/3。

新生代使用的是複製算法,新生代裏有3個分區:Eden、To Survivor、From Survivor, 它們的默認佔比是8:1:1,它的執行流程如下:

•     把 Eden + From Survivor存活的對象放入 To Survivor 區;

•     清空 Eden 和 From Survivor分區;

•      From Survivor和 To Survivor分區交換,From Survivor變 To Survivor, To Survivor 變 From Survivor.

每次在From Survivor到To Survivor移動時都存活的對象,年齡就+1,當年齡到達 15 (默認配置是⑸時,升級爲老生代。大對象也會直接進入老生代

老生代當空間佔用到達某個值之後就會觸發全局垃圾收回,一般使用標記整理的執行算法。以上這些循環往復就構成了整個分代垃圾回收的整體執行流程。

207.    說一下JVM調優的工具?

JDK自帶了很多監控工具,都位於JDK的bin目錄下,其中最常用的是jconsole和 jvisualvm這兩款視圖監控工具。

•     jconsole:用於對JVM中的內存、線程和類等進行監控;

•     jvisualvm: JDK自帶的全能分析工具,可以分析:內存快照、線程快照、程序死鎖、監控內存的變化、gc變化等。

208.    常用的JVM調優的參數都有哪些?

•     -Xms2g:初始化推大小爲2g;

•     -Xmx2g:堆最大內存爲2g;

•    -XX:NewRatio=4:設置年輕的和老年代的內存比例爲1:4;

•    -XX:SurvivorRatio=8:設置新生代 Eden 和 Survivor 比例爲8:2;

•    -XX:+UseParNewGC:指定使用ParNew +Serial Old垃圾回收器組合;

•    -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;

•    -XX:+UseConcMarkSweepGC:指定使用 CMS +Serial Old 垃圾回收器組合;

•    -XX:+PrintGC:開啓打印gc信息;

•    -XX:+PrintGCDetails:打印 gc 詳細信息。

結尾

這不止是一份面試清單,更是一種“被期望的責任”,因爲有無數個待面試者希望從這 篇文章中,找出通往期望公司的“鑰匙”,所以上面的每道選題都是結合我自身的經驗, 於幹萬個面試題中一個題一個題篩選出來再校對好答案和格式做出來的,面試的答案也是再三斟酌,生怕誤人子弟,影響他人的“仕途”纔是大過,所以如有紕漏,還請讀者朋友們在評論區不吝指出。

靖望您能把這篇文章分享給更多的朋友,讓它幫助更多的人。

幫助他人,快樂自己,最後,感謝您的閱讀。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章