java架構師面試題


menu

數據     2 jvm    3 redis    4 Mq      5 springcloud     6 系統解決方案    7 多線程     8 網絡

 

數據庫

為什么說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1、B+的磁盤讀寫代價更低。

B+的內部結點並沒有指向關鍵字具體信息的指針,因此其內部結點相對B樹更小。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

2、B+-tree的查詢效率更加穩定。

所有的記錄都存儲在葉子節點上面。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

3、葉子節點都是有序鏈表存儲的,更利於范圍存儲

 

MySQL InnoDB、Mysaim的特點?   

Innodb是聚集索引,支持事務,支持外鍵 ,支持行鎖,必須有唯一索引,適合修改刪除多的,回表查詢指的是innodb里面非聚集索引的查詢。

Myisam是非聚集索引,葉子節點保存指向數據的指針。不支持事務。

 

Mysql默認隔離級別

    可重復讀(RR),由於之前mysql的binlog同步模式為statement,RC會產生數據不一致。當前binlog已經支持row的格式,可以選擇RC+ROW,作為mysql的隔離級別和日記格式

 

數據庫隔離級別是什么?

A原子性(undo log)、C一致性(AID來保證)、I隔離性(加鎖、mvcc)、D持久性(redo log)

讀已提交(臟讀)、可重復讀(讀未提交)、序列化(幻讀)

 

MySQL主備同步的基本原理。 當slave連接到master的時候,master機器會為slave開啟binlog dump線程。當master 的 binlog發生變化的時候,binlog dump線程會通知slave,並將相應的binlog內容發送給slave

 

如何優化數據庫性能(索引、分庫分表、批量操作、分頁算法、升級硬盤SSD、業務優化、主從部署)

 

SQL什么情況下不會使用索引( select *、索引列上有函數、字段類型錯誤、like%、or、not in、not exist、order by 不加where,加了limit)

exists和in   如果兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in

 

MVCC

InnoDB中的實現主要是為了提高數據庫並發性能,用更好的方式去處理讀-寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞並發讀

通過readview 機制和 undo log 實現了讀不被阻塞,而且在一定程度上實現RC和RR,並且RR級別在大部分時候可以解決幻讀

 快照讀(select ...)的幻讀是用MVCC解決的,當前讀(select ... for update; update; delete)的幻讀是用間隙鎖解決的。

 

數據庫事務的幾種粒度

表鎖、行鎖(通過索引來加鎖)只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖

 

如何解決高並發減庫存問題

如何從一張表中查出name字段不包含“XYZ”的所有行?

not in where name LIKE "%XYZ%"

 

mysql主從同步延時分析  1.業務的持久化層的實現采用分庫架構,mysql服務可平行擴展,分散壓力。

2.單個庫讀寫分離,一主多從,主寫從讀,分散壓力。這樣從庫壓力比主庫高,保護主庫。

3.服務的基礎架構在業務和mysql之間加入memcache或者redis的cache層。降低mysql的讀壓力。

4.使用比主庫更好的硬件設備作為slave,mysql壓力小,延遲自然會變小。

 

加鎖原則

拿MySql的InnoDB引擎來說,對於insert、update、delete等操作。會自動給涉及的數據加排他鎖;

對於一般的select語句,InnoDB不會加任何鎖,事務可以通過以下語句給顯示加共享鎖或排他鎖。

共享鎖:SELECT ... LOCK IN SHARE MODE;

排他鎖:SELECT ... FOR UPDATE;

 

索引的優缺點:優點,提高查詢速度;缺點,更新數據時效率低,因為要同時更新索引

 

 

 

 

Spring Cloud

Eureka的源碼分析服務注冊和服務發現以及心跳機制和保護機制,對比eureka與zookeeper,什么是CAP原則?

服務注冊,客戶端啟動后向服務端發送一個心跳,如果返回404,證明未注冊,發起注冊

服務發現  客戶端定時拉去服務列表,保存在本地,使用時調用本地

心跳機制  客戶端每30s會向服務端發送一個心跳,如果90s沒有收到心跳,服務端會剔除客戶端

自我保護機制  服務端在發現一定時間內剔除的節點過多,就會觸發自我保護,不再剔除節點

 

Eureka支持AP  1、自我保護機制 2、server端低位平等,只要一個server存在就可以正常工作

Zookeeper支持CP  哨兵模式,需要選主,選舉過程停止服務,中心化思想

Nacos

 

Ribbon源碼分析和客服端負載均衡,客戶端負載均衡?服務端負載均衡? Ribbon核心組件IRule以及重寫IRule

客戶端負載均衡,Ribbon實現IRule接口來自定義負載均衡策略

 

Fegin源碼分析和聲明式服務調用,Fegin負載均衡,Fegin如何與Hystrix結合使用? 有什么問題?

給feigin類寫一個實現類fallback,里面定義一些方法,在feigin調用的時候,在類上引入fallback

 

Hystrix實現服務限流、降級,大型分布式項目服務雪崩如何解決? 服務熔斷到底是什么?一線公司的解決方案

服務降級:返回一個友好提示,場景:程序運行異常、超時、服務熔斷、服務限流

服務熔斷:當失敗達到一定閾值之后,停止服務調用,直接降級。等待一個時間窗口之后,繼續重試

服務限流:采用線程池和信號量的方式對服務調用進行限流

 

Zuul統一網關詳解、服務路由、過濾器使用等,從源頭來攔截掉一些不良請求

路由 : 網關的基本模塊,有ID,目標URI,一組斷言和一組過濾器組成

斷言:就是訪問該路由的訪問規則,可以用來匹配來自http請求的任何內容,例如headers或者參數

過濾器:這個就是我們平時說的過濾器,用來過濾一些請求的,gateway有自己默認的過濾器,我們也可以自定義過濾器,但是要實現兩個接口,ordered和globalfilter

 

分布式鏈路跟蹤詳解,串聯調用鏈,,讓Bug無處可藏,如何厘清微服務之間的依賴關系?如何跟蹤業務流的處理順序?

 

Redis

2、 持久化:RDB、AOF

3、 緩存擊穿:1、查詢之后將數據刷新到redis中 2、避免一些熱點數據在同一時間失效、

      緩存雪崩:同時失效或者redis掛掉。1、分散過期時間,2、通過hystrix進行訪問降級或者限流 3、redis進行分布式部署

      緩存穿透:1、增加查詢限制條件  2、在特殊值加載到緩存里面  3布隆過濾器

5、 使用場景:1、會話緩存 2、熱點數據緩存 3、搜索歷史記錄 4、分布式鎖

6、單線程,I/O多路復用,  通過數組的方式同時處理多個I/O

7、高可用方案:主從、哨兵、cluster(hash槽)https://blog.csdn.net/u014209205/article/details/82113258

8、redis如何實現多寫入,通過事務中添加watch來檢測,要修改的key是否已經被其他客戶端修改

9、redis腦裂:出現了兩個master節點,clientA繼續往舊的master寫入,舊master降級成為slave節點,會進行全量同步,會把clientA寫入的數據清空。解決方案:參數配置,min-slave-to-write 2、min-slaves-max-lag 5:至少2個slave對master的同步復制延遲不能超過5秒,如果達不到要求,master停止接受請求

10、redis主從節點是長連接

11、redis如何判斷某個節點是否正常工作?通過心跳檢測機制,主節點10秒發送一次心跳檢測從節點 ,從節點1秒發送一次心跳給主節點同步自己的復制偏移量

12、主從如何判斷全量同步還是增量同步?從節點slave到主節點之后,如果是首次直接全量同步,如果存在偏移量,比較偏移量和主節點的緩沖區大小,如果比緩存區小,那么可以進行增量同步,不然進行全量同步

13、redis不同數據類型的作用

  • String:緩存,限流,計數器,分布式鎖,分布式Session
  • Hash:儲存用戶信息,用戶主頁訪問量,組合查詢
  • List:微博關注人時間軸列表,簡單隊列
  • Set:贊,踩,標簽,好友關系
  • Zset:排行榜

14.Redis為什么這么快?官方使用的基准測試結果表明,單線程的Redis可以達到10W/S的吞吐量。

a.基於內存操作:Redis的所有數據都存在內存中,因此所有的運算都是內存級別的,所以它的性能比較高。

b.數據結構簡單:Redis的數據結構比較簡單,是為Redis專門設計的,而這些簡單的數據結構的查找和操作的時間復雜度都是O(1)。

c.多路復用和非阻塞IO:Redis使用IO多路復用功能來監聽多個socket連接的客戶端,這樣就可以使用一個線程來處理多個情況,從而減少線程切換帶來的開銷,同時也避免了IO阻塞操作,從而大大提高了Redis的性能。

d.避免上下文切換:因為是單線程模型,因此就避免了不必要的上下文切換和多線程競爭,這就省去了多線程切換帶來的時間和性能上的開銷,而且單線程不會導致死鎖的問題發生。

Redis在4.0之前單線程依然快的原因:基於內存操作、數據結構簡單、IO多路復用和非阻塞IO、避免了不必要的線程上下文切換。並且在Redis4.0開始支持多線程,主要體現在大數據的異步刪除方面,例如:unlink key、flushdb async、flushall async等。而Redis6.0的多線程則增加了對IO讀寫的並發能力,用於更好的提升Redis的性能

 

 

多線程

1、notify喚醒哪一個線程?

notify方法只喚醒一個等待(對象的)線程並使該線程開始執行。所以如果有多個線程等待一個對象,這個方法只會喚醒其中一個線程,選擇哪個線程取決於操作系統對多線程管理的實現。

notifyAll會喚醒所有等待(對象的)線程,盡管哪一個線程將會第一個處理取決於操作系統的實現。如果當前情況下有多個線程需要被喚醒,推薦使用notifyAll方法。

2、如何停止一個線程的運行

stop()、interrupt() 設置一個標志位,在run方法內部進行判斷。

https://www.nowcoder.com/discuss/740580?source_id=discuss_experience_nctrack&channel=-1

3、線程如何同、進程如何同步

 

 

Mq

1、Mq如何保證消息不丟失  : 1、生產者:采用confirm機制(同步、異步)    2、mq本身:消息持久化,可以結合confirm機制   3、消費者:關閉自動的ack

2、消息隊列機制  https://blog.csdn.net/h2604396739/article/details/81136527

3、消息堆積:會阻塞生產者,必須提高消費端能力,還可以增加隊列容量,

 

 

網絡

tcp如何保證傳輸可靠性,tcp的報文頭包含什么

https: 1、非對稱+對稱:先用非對稱瀏覽器將對稱秘鑰傳給服務器,之后服務器和瀏覽器通過對稱加密傳輸    2、防止公鑰被篡改,采用證書

 

JVM

java對象內存分布

1,對象頭  2,實例數據    3,對齊填充字節

對象頭:1,Mark Word    2,指向類的指針   3,數組長度(只有數組對象才有)

mark word :鎖、分代年齡、gc標記

 JVM一般是這樣使用鎖和Mark Word的:

 1,當沒有被當成鎖時,這就是一個普通的對象,Mark Word記錄對象的HashCode,鎖標志位是01,是否偏向鎖那一位是0。

 2,當對象被當做同步鎖並有一個線程A搶到了鎖時,鎖標志位還是01,但是否偏向鎖那一位改成1,前23bit記錄搶到鎖的線程id,表示進入偏向鎖狀態。

 3,當線程A再次試圖來獲得鎖時,JVM發現同步鎖對象的標志位是01,是否偏向鎖是1,也就是偏向狀態,Mark Word中記錄的線程id就是線程A自己的id,表示線程A已經獲得了這個偏向鎖,可以執行同步鎖的代碼。

 4,當線程B試圖獲得這個鎖時,JVM發現同步鎖處於偏向狀態,但是Mark Word中的線程id記錄的不是B,那么線程B會先用CAS操作試圖獲得鎖,這里的獲得鎖操作是有可能成功的,因為線程A一般不會自動釋放偏向鎖。如果搶鎖成功,就把Mark Word里的線程id改為線程B的id,代表線程B獲得了這個偏向鎖,可以執行同步鎖代碼。如果搶鎖失敗,則繼續執行步驟5。

 5,偏向鎖狀態搶鎖失敗,代表當前鎖有一定的競爭,偏向鎖將升級為輕量級鎖。JVM會在當前線程的線程棧中開辟一塊單獨的空間,里面保存指向對象鎖Mark Word的指針,同時在對象鎖Mark Word中保存指向這片空間的指針。上述兩個保存操作都是CAS操作,如果保存成功,代表線程搶到了同步鎖,就把Mark Word中的鎖標志位改成00,可以執行同步鎖代碼。如果保存失敗,表示搶鎖失敗,競爭太激烈,繼續執行步驟6。

 6,輕量級鎖搶鎖失敗,JVM會使用自旋鎖,自旋鎖不是一個鎖狀態,只是代表不斷的重試,嘗試搶鎖。從JDK1.7開始,自旋鎖默認啟用,自旋次數由JVM決定。如果搶鎖成功則執行同步鎖代碼,如果失敗則繼續執行步驟7。

 7,自旋鎖重試之后如果搶鎖依然失敗,同步鎖會升級至重量級鎖,鎖標志位改為10。在這個狀態下,未搶到鎖的線程都會被阻塞。

 

 2,指向類的指針

該指針在32位JVM中的長度是32bit,在64位JVM中長度是64bit。Java對象的類數據保存在方法區。

 3,數組長度

只有數組對象保存了這部分數據。該數據在32位和64位JVM中長度都是32bit。

 

GCRoots的對象包括下面幾種

(1). 虛擬機棧(棧幀中的局部變量區,也叫做局部變量表)中引用的對象。

(2). 方法區中的類靜態屬性引用的對象。

(3). 方法區中常量引用的對象。

(4). 本地方法棧中JNI(Native方法)引用的對象。

sychronized底層實現邏輯、

volatile 內存屏障

 

系統方案

防重放:1、增加時間戳,請求超時后端不處理   2、請求攜帶uuid

大文件下載

token機制、spring注解原理、、cpu彪高處理、數據庫慢排查方式、索引失效、CDN刷新不一致

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM