十、Spring/Spring MVC
90.為什么要使用 spring?
1.方便解耦,便於開發(Spring就是一個大工廠,可以將所有對象的創建和依賴關系維護都交給spring管理)
2.spring支持aop編程(spring提供面向切面編程,可以很方便的實現對程序進行權限攔截和運行監控等功能)
3.聲明式事務的支持(通過配置就完成對事務的支持,不需要手動編程)
4.方便程序的測試,spring 對junit4支持,可以通過注解方便的測試spring 程序
5.方便集成各種優秀的框架()
6.降低javaEE API的使用難度(Spring 對javaEE開發中非常難用的一些API 例如JDBC,javaMail,遠程調用等,都提供了封裝,是這些API應用難度大大降低)
91.解釋一下什么是 aop?
在軟件業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
92.解釋一下什么是 ioc?
控制反轉(Inversion of Control,縮寫為IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中。
93.spring 有哪些主要模塊?
Spring有七大功能模塊,分別是Spring Core,AOP,ORM,DAO,MVC,WEB,Context。
1,Spring Core
Core模塊是Spring的核心類庫,Spring的所有功能都依賴於該類庫,Core主要實現IOC功能,Sprign的所有功能都是借助IOC實現的。
2,AOP
AOP模塊是Spring的AOP庫,提供了AOP(攔截器)機制,並提供常用的攔截器,供用戶自定義和配置。
3,ORM
Spring 的ORM模塊提供對常用的ORM框架的管理和輔助支持,Spring支持常用的Hibernate,ibtas,jdao等框架的支持,Spring本身並不對ORM進行實現,僅對常見的ORM框架進行封裝,並對其進行管理
4,DAO模塊
Spring 提供對JDBC的支持,對JDBC進行封裝,允許JDBC使用Spring資源,並能統一管理JDBC事物,並不對JDBC進行實現。(執行sql語句)
5,WEB模塊
WEB模塊提供對常見框架如Struts1,WEBWORK(Struts 2),JSF的支持,Spring能夠管理這些框架,將Spring的資源注入給框架,也能在這些框架的前后插入攔截器。
6,Context模塊
Context模塊提供框架式的Bean訪問方式,其他程序可以通過Context訪問Spring的Bean資源,相當於資源注入。
7,MVC模塊
WEB MVC模塊為Spring提供了一套輕量級的MVC實現,在Spring的開發中,我們既可以用Struts也可以用Spring自己的MVC框架,相對於Struts,Spring自己的MVC框架更加簡潔和方便。
94.spring 常用的注入方式有哪些?
構造器注入,set注入,基於注解的注入。常用的注入注解有@Autowired和@Resource。
95.spring 中的 bean 是線程安全的嗎?
不是
96.spring 支持幾種 bean 的作用域?
① singleton 使用該屬性定義Bean時,IOC容器僅創建一個Bean實例,IOC容器每次返回的是同一個Bean實例。
② prototype 使用該屬性定義Bean時,IOC容器可以創建多個Bean實例,每次返回的都是一個新的實例。
③ request 該屬性僅對HTTP請求產生作用,使用該屬性定義Bean時,每次HTTP請求都會創建一個新的Bean,適用於WebApplicationContext環境。
④ session 該屬性僅用於HTTP Session,同一個Session共享一個Bean實例。不同Session使用不同的實例。
⑤ global-session 該屬性僅用於HTTP Session,同session作用域不同的是,所有的Session共享一個Bean實例。
97.spring 自動裝配 bean 有哪些方式?
no:默認方式,手動裝配方式,需要通過ref設定bean的依賴關系
byName:根據bean的名字進行裝配,當一個bean的名稱和其他bean的屬性一致,則自動裝配
byType:根據bean的類型進行裝配,當一個bean的屬性類型與其他bean的屬性的數據類型一致,則自動裝配
constructor:根據構造器進行裝配,與 byType 類似,如果bean的構造器有與其他bean類型相同的屬性,則進行自動裝配
autodetect:如果有默認構造器,則以constructor方式進行裝配,否則以byType方式進行裝配
98.spring 事務實現方式有哪些?
1. 編程式事務管理 通過代碼實現。2. 聲明式事務管理 基於注解 @Transactional
99.說一下 spring 的事務隔離?
991. 事務的傳播行為
992.事務的特性
⑴ 原子性(Atomicity)
原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾,這和前面兩篇博客介紹事務的功能是一樣的概念,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。
⑵ 一致性(Consistency)
一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處於一致性狀態。
拿轉賬來說,假設用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。
⑶ 隔離性(Isolation)
隔離性是當多個用戶並發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個並發事務之間要相互隔離。
即要達到這么一種效果:對於任意兩個並發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在並發地執行。
關於事務的隔離性數據庫提供了多種隔離級別,稍后會介紹到。
⑷ 持久性(Durability)
持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
100.說一下 spring mvc 運行流程?
101.spring mvc 有哪些組件?
1. 前端控制器組件(DispatcherServlet)
2. 處理器組件(Controller)
3. 處理器映射器組件(HandlerMapping)
4. 處理器適配器組件(HandlerAdapter)
5. 攔截器組件(HandlerInterceptor)
6. 視圖解析器組件(ViewResolver)
7. 視圖組件(View)
8. 數據轉換組件(DataBinder)
9. 消息轉換器組件(HttpMessageConverter)
102.@RequestMapping 的作用是什么?
@RequestMapping 是一個注解,用來標識 http 請求地址與 Controller 類的方法之間的映射。
可作用於類和方法上,方法匹配的完整是路徑是 Controller 類上 @RequestMapping 注解的 value 值加上方法上的 @RequestMapping 注解的 value 值。
103.@Autowired 的作用是什么?
@Autowired 是一個注釋,它可以對類成員變量、方法及構造函數進行標注,讓 spring 完成 bean 自動裝配的工作。
@Autowired 默認是按照類去匹配,配合 @Qualifier 指定按照名稱去裝配 bean。
1031. @Autowired、@Inject、@Resource三者區別
1、@Autowired是spring自帶的,@Inject是JSR330規范實現的,@Resource是JSR250規范實現的,需要導入不同的包
2、@Autowired、@Inject用法基本一樣,不同的是@Autowired有一個request屬性
3、@Autowired、@Inject是默認按照類型匹配的,@Resource是按照名稱匹配的
4、@Autowired如果需要按照名稱匹配需要和@Qualifier一起使用,@Inject和@Name一起使用
十一、Spring Boot/Spring Cloud
104.什么是 spring boot?
Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。
105.為什么要用 spring boot?
約定大約配置
106.spring boot 核心配置文件是什么?
SpringBoot的核心配置文件有application和bootstarp配置文件。
107.spring boot 配置文件有哪幾種類型?它們有什么區別?
yml 和properties
108.spring boot 有哪些方式可以實現熱部署?
spring-boot-devtools
109.jpa 和 hibernate 有什么區別?
Hibernate是JPA規范的一個具體實現
hibernate有JPA沒有的特性
hibernate 的效率更快
JPA 有更好的移植性,通用性
110.什么是 spring cloud?
Spring Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分布式系統基礎設施的開發,如服務發現注冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring Cloud並沒有重復制造輪子,它只是將各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過Spring Boot風格進行再封裝屏蔽掉了復雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分布式系統開發工具包。
111.spring cloud 斷路器的作用是什么?
當一個服務調用另一個服務由於網絡原因或者自身原因出現問題時 調用者就會等待被調用者的響應 當更多的服務請求到這些資源時導致更多的請求等待 這樣就會發生連鎖效應(雪崩效應) 斷路器就是解決這一問題
斷路器有完全打開狀態 一定時間內 達到一定的次數無法調用 並且多次檢測沒有恢復的跡象 斷路器完全打開,那么下次請求就不會請求到該服務
半開 短時間內 有恢復跡象 斷路器會將部分請求發給該服務 當能正常調用時 斷路器關閉
關閉 當服務一直處於正常狀態 能正常調用 斷路器關閉
112.spring cloud 的核心組件有哪些?
服務發現——Netflix Eureka
客服端負載均衡——Netflix Ribbon
斷路器——Netflix Hystrix
服務網關——Netflix Zuul
分布式配置——Spring Cloud Config
十二、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。
- 關閉 SessionFactory。
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,通過調用 ClassnewInstance() 來創建實體類的實例,如果沒有無參的構造函數就會拋出異常。
十三、Mybatis
125.mybatis 中 #{}和 ${}的區別是什么?
(1)mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值。
(2)mybatis在處理${}時,就是把${}替換成變量的值。
(3)使用#{}可以有效的防止SQL注入,提高系統安全性。原因在於:預編譯機制。
126.mybatis 有幾種分頁方式?
1. 代碼自己寫分頁。2. sql limit 分頁 3. 攔截器分頁 4. pageHelper分頁。5. RowBounds分頁
127.RowBounds 是一次性查詢全部結果嗎?為什么?
RowBounds 表面是在“所有”數據中檢索數據,其實並非是一次性查詢出所有數據,因為 MyBatis 是對 jdbc 的封裝,在 jdbc 驅動中有一個 Fetch Size 的配置,它規定了每次最多從數據庫查詢多少條數據,假如你要查詢更多數據,它會在你執行 next()的時候,去查詢更多的數據。就好比你去自動取款機取 10000 元,但取款機每次最多能取 2500 元,所以你要取 4 次才能把錢取完。只是對於 jdbc 來說,當你調用 next()的時候會自動幫你完成查詢工作。這樣做的好處可以有效的防止內存溢出。
128.mybatis 邏輯分頁和物理分頁的區別是什么?
邏輯分頁是一次性查詢很多數據,然后再在結果中檢索分頁的數據。這樣做弊端是需要消耗大量的內存、有內存溢出的風險、對數據庫壓力較大。 物理分頁是從數據庫查詢指定條數的數據,彌補了一次性全部查出的所有數據的種種缺點,比如需要大量的內存,對數據庫查詢壓力較大等問題。
129.mybatis 是否支持延遲加載?延遲加載的原理是什么?
MyBatis 支持延遲加載,設置 lazyLoadingEnabled=true 即可。
延遲加載的原理的是調用的時候觸發加載,而不是在初始化的時候就加載信息。比如調用 a. getB(). getName(),這個時候發現 a. getB() 的值為 null,此時會單獨觸發事先保存好的關聯 B 對象的 SQL,先查詢出來 B,然后再調用 a. setB(b),而這時候再調用 a. getB(). getName() 就有值了,這就是延遲加載的基本原理。
130.說一下 mybatis 的一級緩存和二級緩存?
131.mybatis 和 hibernate 的區別有哪些?
靈活性:MyBatis 更加靈活,自己可以寫 SQL 語句,使用起來比較方便。
可移植性:MyBatis 有很多自己寫的 SQL,因為每個數據庫的 SQL 可以不相同,所以可移植性比較差。
學習和使用門檻:MyBatis 入門比較簡單,使用門檻也更低。
二級緩存:hibernate 擁有更好的二級緩存,它的二級緩存可以自行更換為第三方的二級緩存。
132.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,然后根據設置的dialect(方言),和設置的分頁參數,重寫SQL ,生成帶有分頁語句的SQL,執行重寫后的SQL,從而實現分頁
134.mybatis 如何編寫一個自定義插件?
http://www.mianshigee.com/question/10514euq
十四、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 集群有什么用?
集群主要有以下兩個用途:
高可用:某個服務器出現問題,整個 RabbitMQ 還可以繼續使用;
高容量:集群可以承載更多的消息量。
147.rabbitmq 節點的類型有哪些?
磁盤節點:消息會存儲到磁盤。
內存節點:消息都存儲在內存中,重啟服務器消息丟失,性能高於磁盤類型。
148.rabbitmq 集群搭建需要注意哪些問題?
各節點之間使用“–link”連接,此屬性不能忽略。
各節點使用的 erlang cookie 值必須相同,此值相當於“秘鑰”的功能,用於各節點的認證。
整個集群中必須包含一個磁盤節點。
149.rabbitmq 每個節點是其他節點的完整拷貝嗎?為什么?
不是,原因有以下兩個:
存儲空間的考慮:如果每個節點都擁有所有隊列的完全拷貝,這樣新增節點不但沒有新增存儲空間,反而增加了更多的冗余數據;
性能的考慮:如果每條消息都需要完整拷貝到每一個集群節點,那新增節點並沒有提升處理消息的能力,最多是保持和單節點相同的性能甚至是更糟。
150.rabbitmq 集群中唯一一個磁盤節點崩潰了會發生什么情況?
不能進行以下操作:
不能創建隊列
不能創建交換器
不能創建綁定
不能添加用戶
不能更改權限
不能添加和刪除集群節點
唯一磁盤節點崩潰了,集群是可以保持運行的,但你不能更改任何東西。
151.rabbitmq 對集群節點停止順序有要求嗎?
RabbitMQ 對集群的停止的順序是有要求的,應該先關閉內存節點,最后再關閉磁盤節點。如果順序恰好相反的話,可能會造成消息的丟失。
十五、Kafka
152.kafka 可以脫離 zookeeper 單獨使用嗎?為什么?
kafka 不能脫離 zookeeper 單獨使用,
因為 kafka 使用 zookeeper 管理和協調 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的重要組件。它是一個為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。
ZooKeeper的目標就是封裝好復雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。
ZooKeeper包含一個簡單的原語集,提供Java和C的接口。
ZooKeeper代碼版本中,提供了分布式獨享鎖、選舉、隊列的接口,代碼在$zookeeper_home\src\recipes。其中分布鎖和隊列有Java和C兩個版本,選舉只有Java版本。
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.數據庫的三范式是什么?
1、第一范式:
當關系模式R的所有屬性都不能在分解為更基本的數據單位時,稱R是滿足第一范式的,簡記為1NF。滿足第一范式是關系模式規范化的最低要求,否則,將有很多基本操作在這樣的關系模式中實現不了。
2、第二范式:
如果關系模式R滿足第一范式,並且R得所有非主屬性都完全依賴於R的每一個候選關鍵屬性,稱R滿足第二范式,簡記為2NF。
3、第三范式:
設R是一個滿足第一范式條件的關系模式,X是R的任意屬性集,如果X非傳遞依賴於R的任意一個候選關鍵字,稱R滿足第三范式,簡記為3NF。
165.一張自增表里面總共有 7 條數據,刪除了最后 2 條數據,重啟 mysql 數據庫,又插入了一條數據,此時 id 是幾?
表類型如果是 MyISAM ,那 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的長度是不可變的,而varchar的長度是可變的,
-
定義一個char[10]和varchar[10],如果存進去的是‘abcd’,那么char所占的長度依然為10,除了字符‘abcd’外,后面跟六個空格,而varchar就立馬把長度變為4了,取數據的時候,char類型的要用e69da5e6ba90e799bee5baa631333366303062trim()去掉多余的空格,而varchar是不需要的,
-
char的存取數度還是要比varchar要快得多,因為其長度固定,方便程序的存儲與查找;但是char也為此付出的是空間的代價,因為其長度固定,所以難免會有多余的空格占位符占據空間,可謂是以空間換取時間效率,而varchar是以空間效率為首位的。
-
char的存儲方式是,對英文字符(ASCII)占用1個字節,對一個漢字占用兩個字節;而varchar的存儲方式是,對每個英文字符占用2個字節,漢字也占用2個字節,兩者的存儲數據都非unicode的字符數據。
169.float 和 double 的區別是什么?
float 最多可以存儲 8 位的十進制數,並在內存中占 4 字節。
double 最可可以存儲 16 位的十進制數,並在內存中占 8 字節。
170.mysql 的內連接、左連接、右連接有什么區別?
171.mysql 索引是怎么實現的?
索引是滿足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。 具體來說 MySQL 中的索引,不同的數據引擎實現有所不同,但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜索效率,可以到達二分法的性能,找到數據區域之后就找到了完整的數據結構了,所有索引的性能也是更好的。
172.怎么驗證 mysql 的索引是否滿足需求?
使用 explain 查看 SQL 是如何執行查詢語句的,從而分析你的索引是否滿足需求。 explain 語法:explain select * from table where type=1。
173.說一下數據庫的事務隔離?
讀未提交(Read Uncommitted)讀提交(Read Committed)可重復讀(Repeated Read)串行化(Serializable)
174.說一下 mysql 常用的引擎?
175.說一下 mysql 的行鎖和表鎖?
MyISAM 只支持表鎖,InnoDB 支持表鎖和行鎖,默認為行鎖。 表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖沖突的概率最高,並發量最低。 行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖沖突的概率小,並發度最高。
176.說一下樂觀鎖和悲觀鎖?
樂觀鎖:每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
悲觀鎖:每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。 數據庫的樂觀鎖需要自己實現,在表里面添加一個 version 字段,每次修改成功值加 1,這樣每次修改的時候先對比一下,自己擁有的 version 和數據庫現在的 version 是否一致,如果不一致就不修改,這樣就實現了樂觀鎖。
177.mysql 問題排查都有哪些手段?
使用 show processlist 命令查看當前所有連接信息。 使用 explain 命令查詢 SQL 語句執行計划。 開啟慢查詢日志,查看慢查詢的 SQL。
178.如何做 mysql 的性能優化?
為搜索字段創建索引。
避免使用 select *,列出需要查詢的字段。
垂直分割分表。
選擇正確的存儲引擎。
十八、Redis
179.redis 是什么?都有哪些使用場景?
Redis 是一個使用 C 語言開發的高速緩存數據庫。 redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave主從同步【主從同步:數據可以從主服務器向任意數量的從服務器上同步】。 Redis 是一個高性能的key-value數據庫。redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關系數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。
Redis 使用場景:記錄帖子點贊數、點擊數、評論數; 緩存近期熱帖; 緩存文章詳情信息; 記錄用戶會話信息。
180.redis 有哪些功能?
- 數據緩存功能
- 分布式鎖的功能
- 支持數據持久化
- 支持事務
- 支持消息隊列
181.redis 和 memecache 有什么區別?
1、存儲方式不同
memecache 把數據全部存在內存之中,斷電后會掛掉,數據不能超過內存大小;redis有部份存在硬盤上,這樣能保證數據的持久性,支持數據的持久化(筆者注:有快照和AOF日志兩種持久化方式,在實際應用的時候,要特別注意配置文件快照參數,要不就很有可能服務器頻繁滿載做dump)。
2、數據支持類型不同
redis在數據支持上要比memecache多的多。
3、使用底層模型不同
新版本的redis直接自己構建了VM 機制 ,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。
4、運行環境不同
redis目前官方只支持LINUX 上去行,從而省去了對於其它系統的支持,這樣的話可以更好的把精力用於本系統 環境上的優化,雖然后來微軟有一個小組為其寫了補丁。但是沒有放到主干上
182.redis 為什么是單線程的?
因為 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機器內存或者網絡帶寬。既然單線程容易實現,而且 cpu 又不會成為瓶頸,那就順理成章地采用單線程的方案了。 關於 Redis 的性能,官方網站也有,普通筆記本輕松處理每秒幾十萬的請求。而且單線程並不代表就慢, nginx 和 node.js 也都是高性能單線程的代表
183.什么是緩存穿透?怎么解決?
一般的緩存系統,都是按照key去緩存查詢,如果不存在對應的value,就應該去數據庫查詢。一些惡意的請求會故意大量查詢不存在的key,就會對數據庫造成很大的壓力。這就叫做緩存穿透。
①采用布隆過濾器,將所有可能存在的數據存到一個bitMap中,不存在的數據就會進行攔截。
②對查詢結果為空的情況也進行緩存,緩存時間設置短一點,不超過5分鍾。
184.redis 支持的數據類型有哪些?
五種,string,list,hash ,set,zset
185.redis 支持的 java 客戶端都有哪些?
支持的 Java 客戶端有 Redisson、jedis、lettuce 等。
186.jedis 和 redisson 有哪些區別?
Jedis 和 Redisson 都是Java中對Redis操作的封裝。Jedis 只是簡單的封裝了 Redis 的API庫,可以看作是Redis客戶端,它的方法和Redis 的命令很類似。Redisson 不僅封裝了 redis ,還封裝了對更多數據結構的支持,以及鎖等功能,相比於Jedis 更加大。但Jedis相比於Redisson 更原生一些,更靈活。
187.怎么保證緩存和數據庫數據的一致性?
對刪除緩存進行重試,數據的一致性要求越高,我越是重試得快。
定期全量更新,簡單地說,就是我定期把緩存全部清掉,然后再全量加載。
給所有的緩存一個失效期。
188.redis 持久化有幾種方式?
兩種,RDB 和AOF
189.redis 怎么實現分布式鎖?
https://www.jianshu.com/p/47fd7f86c848
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)再把字節碼加載到內存中,而字節碼文件只是 JVM 的一套指令集規范,並不能直接交個底層操作系統去執行,因此需要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程中需要調用其他語言的本地庫接口(Native Interface)來實現整個程序的功能。
195.說一下 jvm 運行時數據區?
程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工作是通過改變這個計數器的值,來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能,都需要依賴這個計數器來完成;
Java 虛擬機棧(Java Virtual Machine Stacks):用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息;
本地方法棧(Native Method Stack):與虛擬機棧的作用是一樣的,只不過虛擬機棧是服務 Java 方法的,而本地方法棧是為虛擬機調用 Native 方法服務的;
Java 堆(Java Heap):Java 虛擬機中內存最大的一塊,是被所有線程共享的,幾乎所有的對象實例都在這里分配內存;
方法區(Methed Area):用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯后的代碼等數據。
196.說一下堆棧的區別?
功能方面:堆是用來存放對象的,棧是用來執行程序的。
共享性:堆是線程共享的,棧是線程私有的。
空間大小:堆大小遠遠大於棧。
197.隊列和棧是什么?有什么區別?
隊列和棧都是被用來預存儲數據的。
隊列允許先進先出檢索元素,但也有例外的情況,Deque 接口允許從兩端檢索元素。
棧和隊列很相似,但它運行對元素進行后進先出進行檢索。
198.什么是雙親委派模型?
先加載父類,然后再加載子類。
199.說一下類加載的執行過程?
java程序在執行過程中,類,對象以及它們成員來加載、初始化的順序如下:
1、首先加載要創建對象的類及其直接與間接父類。
2、在類被加載的同時會將靜態成員進行加載,主要包括靜態成員變量的初始化,靜態語句塊的執行,在加載時按代碼的先后順序進行。
3、需要的類加載完成后,知開始創建對象,首先會加載非靜態道的成員,主要包括非靜態成員變量的初始化,非靜態語句塊的執行,在加載時按代碼的先后順序進行。
4、最后執行構造器,構造器執行完畢,對象生成。
200.怎么判斷對象是否可以被回收?
可達性分型
201.java 中都有哪些引用類型?
強引用,軟引用,弱引用,虛引用。
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 實現,是 JDK 9 以后的默認 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(默認配置是 15)時,升級為老生代。大對象也會直接進入老生代。
老生代當空間占用到達某個值之后就會觸發全局垃圾收回,一般使用標記整理的執行算法。
以上這些循環往復就構成了整個分代垃圾回收的整體執行流程。
207.說一下 jvm 調優的工具?
1. jps 主要用來顯示當前java進程的ID號。
2. jstat JVM統計監測工具,主要用於監測並顯示JVM的性能統計信息。
3. jconsole 圖形化用戶界面的監測工具,主要用於監測並顯示用於運行於Java平台上的應用程序的性能和資源的占用信息。
4. Jmap Java內存映射工具,主要用於打印指定的Java進程,核心文件或遠程調用服務器的共享對象內存映射或堆內存細節。
5. jstact Java堆棧跟蹤工具,主要用於打印指定Java進程,核心文件或遠程調試服務器的java線程的堆棧跟蹤信息。
6. jvisualvm.exe jvm監測,故障排除,分析工具,主要以圖形界面的方式提供運行於指定虛擬機的Java應用程序的詳細信息。
208.常用的 jvm 調優的參數都有哪些?
XX:+HeapDumpOnOutOfMemoryError 默認關閉 在發生內存溢出異常時是否生成堆轉儲快照,
-Xloggc:D:/gc.log 打印GC的日志到文件
若為jdk1.8的編譯器,設置垃圾回收器為G1
-XX:+UseG1GC
-Xmn2g 設置年輕代的大小2G 經驗值 1/4-1/3 , Age =15的值。
-XX:SurvivorRatio=4 設置Eden,S0,S1區域的比例,默認為8:1:1
-server 以sever模式運行
備注:Java里面有兩種參數,一種是標准參數,它是不以jdk的版本變化而變化的,可以通過java -X help 查看,他所有添加的參數都是 -Xms:500m 這種。
第二種是非標准參數:這種參數相對來說不穩定,隨着JVM版本的變化可能會發生變化。
-
首先明確的是,char的長度是不可變的,而varchar的長度是可變的,
-
定義一個char[10]和varchar[10],如果存進去的是‘abcd’,那么char所占的長度依然為10,除了字符‘abcd’外,后面跟六個空格,而varchar就立馬把長度變為4了,取數據的時候,char類型的要用
trim()去掉多余的空格,而varchar是不需要的, -
char的存取數度還是要比varchar要快得多,因為其長度固定,方便程序的存儲與查找;但是char也為此付出的是空間的代價,因為其長度固定,所以難免會有多余的空格占位符占據空間,可謂是以空間換取時間效率,而varchar是以空間效率為首位的。
-
char的存儲方式是,對英文字符(ASCII)占用1個字節,對一個漢字占用兩個字節;而varchar的存儲方式是,對每個英文字符占用2個字節,漢字也占用2個字節,兩者的存儲數據都非unicode的字符數據。
分頁插件的原理就是使用MyBatis提供的插件接口,實現自定義插件,在插件的攔截方法內,攔截待執行的SQL,然后根據設置的dialect(方言),和設置的分頁參數,重寫SQL ,生成帶有分頁語句的SQL,執行重寫后的SQL,從而實現分頁