2025年Java常見面試題(持續更新)
- 數據庫事務特性。原子性、一致性、隔離性、持久性
- 如何防止SQL注入:使用#不要使用$符號;對所有的入參做校驗;使用存儲過程;執行預處理語句和參數化查詢;最低權限原則;
- 微服務拆分的原則:微服務的拆分應該從業務、技術、組織結構三個維度進行考慮。業務上按照DDD領域驅動設計原則來進行拆分,然后根據持續演進原則先粗后細逐步的進行迭代。
技術上按照單一責任、閉包、服務自治、高內聚低耦合、數據隔離原則進行拆分,也需要考慮性能問題將性能要求高或性能壓力大的服務單拆出來,比如流量較大的服務可以做讀寫分離。還需要考慮穩定性原則,將成熟改動不大的服務拆分為穩定服務,避免頻繁發布,改動多業務迭代快的拆分為變動服務。還可以根據安全隔離進行拆分,區分為對外的跟對內的。還要對重復功能進行沉淀,沉淀為通用服務避免重復造輪子。還有不同語言的可以異構成獨立服務。
組織上,根據公司的組織結構來設計,按照康威定律 - 拆分完如何驗證合理性:還是要從業務、技術、組織結構上來評估合理性,業務上能不能滿足當前跟未來的發展;技術上性能、安全性、部署維護成本;組織上是不是促進團隊協作跟溝通。微服務的拆分跟合并是一個持續演進的過程,需要不斷的迭代優化。
- kafka為什么支持高吞吐。
分區分段與并行處理。topic分成多個分區,不同分區在不同服務器上,還對數據進行分段分段之后再加索引,生產者消費者并行處理。
批量讀寫、批量壓縮
直接用系統的page Cache,讀寫都基于內存。又使用了零copy技術直接將數據copy到nic緩沖區,減少數據在用戶空間跟內核空間復制。
順序寫磁盤技術。減少磁盤尋址時間,當然帶來的問題就是不能刪數據 - 使用kafka如何避免消息丟失。
生產者使用ack機制,0消息發出就算成功、1broker的Leader副本收到就算成功、-1Leader跟follower都寫入成功;
broker是異步刷盤也有可能失敗,但是設置了一個分區幾個副本,設置刷盤頻率
消費者這邊設置提交offset的機制,關閉自動提交消費完成之后再提交,支持冪等消費 - 數據庫三范式。原子性、唯一性、冗余性
- MySQL優化。
連接數優化。增加最大連接數、修改默認超時時間釋放不活躍的連接,但不要釋放連接池;客戶端連接池的合理利用
集群優化,讀寫分離,分庫分表,垂直分庫水平分表
打開慢查詢日志,分析慢查詢情況
優化SQL語句,通過explain 執行計劃,創建合適的索引,唯一索引、普通索引、復合索引。SQL語句優化,不在索引列使用函數,不在where語句上使用操作符,不在where上進行null判斷,不在where使用or來連接條件,模糊查詢%在后面。查詢多行一定要分頁;盡量用連接查詢代替子查詢 - 怎么排查Java程序占用CPU過高。
JPS查看本機線程信息。
top命令找到占用最高的進程PID,
在用(top -hp PID)查看進程下的線程ID轉換為16進制線程ID TID(printf"%x\n" tid),
jstack打印線程堆棧。jstack PID命令生成Java進程的線程快照,在快照里面通過TID找到堆棧(jstack pid | grep tid -A 60)
Jstat監控JVM內存。如果gc過高繼續用 jstat -gc pid 3000,如果fgc頻率高就用jstack跟jmap分析堆內存使用情況
Jmap生成內存快照。用jmap -dump:format=b,file=heapdump.phrof pid命令去生成dump文件然后用專用軟件如jprofiler - 常用的設計模式
單例、工廠、適配器、觀察者、建造者、策略模式、責任鏈、代理模式 synchronized
和Lock
的區別
synchronized:Java關鍵字,jvm層面實現的隱式鎖不需要自己釋放,可以加在方法或者代碼塊,可重入不可中斷非公平鎖。低競爭模式下性能好,因為使用了CPU的悲觀鎖,并且排它鎖第二個線程獲取不到鎖會一直等待。偏向鎖、輕量級鎖、重量級鎖
Lock:是一個類,需要自己手動釋放,可重入可中斷可以是公平鎖也可以非公平,高并發時候性能好,因為是樂觀鎖,AQS+CAS實現的,AQS就是維護鎖狀態跟先進先出隊列,CAS是硬件級別的原子操作會嘗試更新鎖狀態。- 線程池
FixedThreadPool,固定大小線程池,比如查詢數據庫,阻塞隊列
SingleThreadExecutor,單線程,比如處理文件讀寫,阻塞隊列
CachedThreadPool,動態線程池
ScheduledThreadPool,定時執行的線程池
實際使用中自己通過ThreadPoolExecutor創建線程,CPU密集型任務比如視頻解碼數據加密,核心線程數跟最大線程都可以是CPU線程數+1,線程超過CPU核心數增加上下文切換開銷,額外一個線程是因為某線程因為頁缺失等原因阻塞時可以繼續利用CPU。IO密集型任務可以配置CPU的2倍,最大線程可以設置2~3倍 - thrift
支持二進制跟文本傳輸協議,支持基本類型、結構體、集合、異常類型、服務類型,底層是RPC遠程調用,定義好協議格式,主要是數字 - char 跟 varchar區別
char,固定長度適合保存手機號、身份證號等定長數據,
varchar,可變長度,適合存name、地址信息,多一位存儲長度 - MySQL數據庫索引
通過B+樹存儲,葉子結點存放key跟value,其他節點存放key,葉子結點有引用指向相鄰的葉子節點。數據量增加、插入刪除數據時會進行重平衡, - SynchronizedMap
使用分段鎖保證性能,一次鎖住一個桶默認16個桶,jdk8之后也改用CAS(Compare And Swap) - 并發編程三要素
原子性、有序性、可見性 - CyclicBarrier 和 CountDownLatch 的區別
count 是線程等待其他線程都執行完當前線程才繼續執行,定時任務中并行計算結果出來之后統一處理,計數器只能用一次,
cyclicBarrier 是所有線程都進入await方法后同時執行, 計數器可以reset,處理復雜場景比如計算錯誤再來一遍 - 技術難點
如何讓上游無感知遷移流量。在原有SDK接口上面增加一個切面吧流量拿到改成調用服務B;處理蜂窩刷新問題,將門店切成10份分散執行,執行中使用線程池并行計算,拿到結果再批量入庫。 - JVM內存
堆、方法區是線程共享,虛擬機棧、本地方法棧、程序計數器是線程獨有。垃圾回收主要針對堆,堆主要存放new出來的對象(方法中對象引用沒有被返回或沒有在方法體外被使用),新生代(eden、from suvivor、to suvivor)、老年代。方法區之前存在永久代8之后被元空間替代,永久代有內存溢出風險、垃圾回收效率低、無法動態調整大小、無法回收常量池中的內存。元空間存儲在本地內存不在jvm,突破內存限制減少OOM,可以動態調整大小。缺點也可能內存溢出、需要重新考慮內存管理和調優 - Sping事務失效
數據庫引擎不支持;沒有被Spring管理;非public方法(通過AspectJ代理模式也可以)或者方法被final、static修飾;是否是自調用情況;數據源沒配置事務管理器;異常被吞掉沒有正確拋出或者拋出的異常類型錯誤;多線程 - ES深分頁怎么解決
Scroll API?適合遍歷大量數據,他像一個游標會生成快照,后續分頁都按照快照避免了重復排序的開銷,適合需要大量遍歷數據的場景;Search After 5.0之后引入的分頁方式,會基于上一個分頁最后一條記錄的排序值進行下一個分頁查詢,避免from + size帶來的開銷。適合實時分頁場景。 - Scroll API的快照有啥問題
新數據寫入或者已有數據刪除、更新這些變化不會反應在快照中,查詢結果不實時;維護快照占用內存資源多;適合一次性批量導出數據,不適合實時交互的分頁查詢;Scroll Id 游標存在過期問題默認5分鐘
本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912777.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912777.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912777.shtml
如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!