天天看點

面試彙總2020 04 19

2020 04 19

面試遇到被提問到的問題

1、說說你對微服務的了解

2、redis是單線程的還是多線程的

3、redis高并發如何解決

一、說說你對微服務的了解

1、 什麼是單體架構,以及單體架構的優缺點

1.1 單體架構的概述:

一般的單體架構分三層,表現層,業務邏輯層,持久層(資料通路層),這樣子的架構把所用的業務場景都放在一個工程中,一次編譯,部署在一個伺服器。架構圖如下
           
面試彙總2020 04 19
1.2、單體架構的優缺點
優點:單體架構的開發難度相對較低,開發成本低,開發速度快
缺點:單體架構的業務耦合度相對較高,而且,随着并發量越來越高,單體架構的并發能力短闆就顯露出來了
(如果一個系統部署在一個tomcat上,一個tomcat的同時通路量是500),随着代碼量的增加,代碼的可讀性就
降低了,而且業務功能的疊加也困難
           

2、微服務

微服務架構是分布式架構的一種,簡單來說微服務是把一個系統拆分成若幹個功能子產品,通過子產品間的互相調用來完成
系統的工作内容。
好處:1、每個微服務的可以單獨部署,運作,利于分工,将複雜的問題簡單化,微服務之間不互相影響,一個微服務挂了不影響其它的微服務。 
	 2、微服務是一個分布式架構,業務與業務之間完全解耦,具有極強的橫向擴充能力。
	 3、微服務技術棧不受限,不同的微服務完全可以用不同的程式設計語言來寫
	 4、局部修改容易部署,哪個子產品出現了bug我們隻需要解決那個子產品的bug就可以了,解決完bug之後,我們隻需要重新開機這個子產品的服務即可,部署相對簡單,不必重新開機整個項目進而大大節約時間
	 5、由于微服務單個子產品就相當于一個項目,開發這個子產品我們就隻需關心這個子產品的邏輯即可,代碼量和邏輯複雜度都會降低,進而易于開發和維護
缺點:
	 1、運維要求較高
	 	對于單體架構來講,我們隻需要維護好這一個項目就可以了,但是對于微服務架構來講,由于項
	 目是由多個微服務構成的,每個子產品出現問題都會造成整個項目運作出現異常,想要知道是哪個子產品造成的問題往往
	 是不容易的,因為我們無法一步一步通過debug的方式來跟蹤,這就對運維人員提出了很高的要求。
	 2、分布式的複雜性
		 對于單體架構來講,我們可以不使用分布式,但是對于微服務架構來說,分布式幾乎是必會用的技術,由于分布式
	本身的複雜性,導緻微服務架構也變得複雜起來。
	 3、接口調整成本高
	 	比如,使用者微服務是要被訂單微服務和電影微服務所調用的,一旦使用者微服務的接口發生大的變動,那麼所有依賴
	它的微服務都要做相應的調整,由于微服務可能非常多,那麼調整接口所造成的成本将會明顯提高。
           

二、redis是單線程的還是多線程的

redis是單線程的

(1) 絕大部分請求是純粹的記憶體操作(非常快速)

(2) 采用單線程,避免了不必要的上下文切換和競争條件

(3) 非阻塞IO - IO多路複用

IO多路複用中有三種方式:select,poll,epoll。需要注意的是,select,poll是線程不安全的,epoll是線程安全的

redis内部實作采用epoll,采用了epoll+自己實作的簡單的事件架構。epoll中的讀、寫、關閉、連接配接都轉化成了事件,然後利用epoll的多路複用特性,絕不在io上浪費一點時間 這3個條件不是互相獨立的,特别是第一條,如果請求都是耗時的,采用單線程吞吐量及性能可想而知了。應該說redis為特殊的場景選擇了合适的技術方案。

線程池的原理及作用
線程集合workerSet和一個阻塞隊列
		多線程技術主要解決處理器單元内多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,
		增加處理器單元的吞吐能力
           
線程池的使用
一個線程池包括以下四個基本組成部分:
            1、線程池管理器(ThreadPool):用于建立并管理線程池,包括 建立線程池,銷毀線程池,添加新任務;
            2、工作線程(PoolWorker):線程池中線程,在沒有任務時處于等待狀态,可以循環的執行任務;
            3、任務接口(Task):每個任務必須實作的接口,以供工作線程排程任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀态等;
            4、任務隊列(taskQueue):用于存放沒有處理的任務。提供一種緩沖機制。
           
線程池的建立
- 建立一個單線程的線程池:Executors.newSingleThreadExecutor()
		- 建立一個固定線程的線程池:Executors.newFixedThreadPool()
		- 建立一個可緩存的先程池:Executors.newCachedThreadPool()
		- 建立一個無限大小的線程池:Executors.newScheduledThreadPool()
           
hashTable和hashMap的差別
* 1.HashMap是線程不安全的,效率高,JDK1.2版本
		* Hashtable是線程安全的,效率低,JDK1.0版本
		* 2.HashMap可以存儲null鍵和null值
		* Hashtable不可以存儲null鍵和null值
           
springboot常用注解
mysql髒讀,幻讀,不可重複讀
- 髒讀:指一個事務讀取到了另一個事務未送出的資料,造成了與資料庫中的資料不一緻的情況
		- 幻讀:即一個事務A兩次或多次讀取資料,在此期間,事務B新增了N條資料,然後送出了,造成了事務A兩次或多次讀取資料出現了資料條數不一緻的情況。
		- 不可重複讀:即一個事務A兩次或多次讀取資料,在此期間,事務B讀取同一資料,并修改了此資料,然後送出了,造成了事務A兩次或多次讀取資料出現了資料不一緻的情況。
           
mysql,innoDb原理
redis排序
SORT<key>  指令來實作,例如:SORT numbers 對number清單元素進行排序
           
為什麼重寫equals()方法的同時也要重寫hashCode()方法
為了保證相同的兩個對象的hashCode值相等。
				兩個對象相等,hashcode一定相等
				兩個對象不等,hashcode不一定不等
				hashcode相等,兩個對象不一定相等
				hashcode不等,兩個對象一定不等
           
什麼是redis緩存擊穿
緩存穿透:某個key無論在緩存還是資料庫中都沒有,這時候請求會到達資料庫,大量這種重複的請求把資料庫壓垮,稱為緩存穿透
 緩存擊穿:某個key在緩存中存在但是已經過期,這時候需要去查資料庫,短時間内大量這樣的請求會把資料庫壓垮,稱為緩存擊穿
 緩存雪崩:緩存伺服器重新開機或者大量緩存在同一時間失效,會觸發大量的資料庫查詢,這樣會壓垮資料庫,稱為緩存雪崩
           
Redis支援資料類型:
Str,list,hash,set,zset
           
Redis持久化方式:
RDB:指定的時間間隔把緩存中的資料寫入磁盤
  AOF:以日志的形式記錄每一個,寫,和删除的操作,讀資料不會記錄
           
Java中的隊列
Queue
        Deque:雙端隊列
        BlockingQueue:阻塞隊列
        AbstractQueue:非阻塞隊列
           
線程實作方式
1、繼承Thread類
    2、實作Runnable接口
    3、實作Callable接口
    4、匿名内部類
           
Jwt實作原理
Nginx的負載均衡原理
Redis的資料淘汰機智
1、從設定了過期時間的資料集中選擇已經過期的淘汰
    2、從設定了過期時間的資料集中選擇用的最少的淘汰
    3、從設定了過期時間的資料集中随意淘汰
    4、從資料集中選擇最少用的淘汰
    5、從資料集中随意淘汰
    6、不淘汰(預設)
           
HashMap的底層結構
每個元素都是連結清單(可能表述不準确)的數組,當添加一個元素(key-value)時,就首先計算元素key的hash值,
		以此确定插入數組中的位置,但是可能存在同一hash值的元素已經被放在數組同一位置了,這時就添加到同一hash
		值的元素的後面,他們在數組的同一位置,但是形成了連結清單,同一各連結清單上的Hash值是相同的,是以說數組存放的
		是連結清單。而當連結清單長度太長時,連結清單就轉換為紅黑樹,這樣大大提高了查找的效率
           
分布式事務
4大特點:
          1、原子性:要麼都成功,要麼都失敗
          2、一緻性:事務執行之後,從一個一緻性狀态變成另一個一緻性态。
          3、隔離性:事物之間不互相幹擾。
          4、持久性:事務執行之後是永久的變更,不可以更改。