1.a>b與a-b>0的區別
參考文章:https://blog.csdn.net/asd991936157/article/details/52033118
總結:
- a>b在計算機中不一定等於a-b>0,比如Integer.MAX_VALUE-(-1)將得到一個-2147483648的負數。
- 比如一個32位的操作系統,會預留一位作爲符號位,比如Integer.MAX_VALUE二進制位數爲:01111111111111111111111111111111,加一後二進制位數爲:10000000000000000000000000000000紅色代表的是符號位這個時候變成了負數
2.一共瞭解幾種單例模式
參考文章:https://www.jianshu.com/p/3bfd916f2bb2
- 懶漢式、延遲初始化,線程不安全
- 餓漢式、線程安全,但是一開始就初始化
- 雙重檢查鎖模式、需要用volatile修飾否則,非線程安全
- 靜態內部類單例模式、只有一個線程可以獲得對象的初始化鎖,其他線程無法進行初始化,保證對象的唯一性。由jvm內部保證的線程安全,推薦使用
- 枚舉單例模式、線程安全但可讀性差
3.瞭解哪些設計模式以及裝飾模式與代理模式的區別
常用設計模式:
-
單例模式、避免創建多個實例造成資源浪費
-
工廠方法模式、生產對象的一種創建型模式,如FactoryBean
-
策略模式、在多種算法類似的情況下避免過多的if else、通常配合一個接口多個實現來實現的
-
模板模式、定義一個模板通常是接口,然後由子類去實現;很容易和策略模式混淆,
-
策略模式 核心在 使用者的策略。模板方法模式 核心在 子類的 怎麼實現,策略模式包含了模板模式。如jdbcTemp
-
代理模式、代理類在客戶端與目標對象之間起到一箇中介作用和保護目標對象的作用,其特徵是代理類和委託類實現相同的接口。可以用代理類來增強委託類的功能。
裝飾模式、現有的對象添加新的功能,同時又不改變其結構,保持類方法完整性的前提下,提供了額外的功能。但是會使類變得複雜 -
裝飾模式與代理模式的區別:
裝飾模式主要是強調對類中代碼的拓展,而代理模式則偏向於委託類(使用代理對象的類)的訪問限制,委託類不能直接訪問被代理的對象;
4.synchronized與lock的區別,AQS實現鎖的缺點
表面區別:
-
存在層面的區別、synchronized是關鍵字存在jvm層面,lock屬於類
-
釋放鎖的區別、synchronized會自動釋放鎖,lock需要手動釋放否者死鎖
-
獲取鎖的區別、synchronized獲取不到鎖會一直等待、lock可以根據返回不用等待
-
類型的區別、synchronized可重入 不可中斷 非公平,lock可重入可中斷可公平/不公平
實質區別:
-
synchronized基於監視器鎖(monitor)來實現的,每個對象都有一個監視器鎖,能自動權衡自旋與暫時放棄獲取鎖,同時有鎖的粒度的粗化等優化
-
lock鎖基於AQS實現,而AQS同步鎖的實現類似於CAS,長時間獲取不到鎖的情況下自旋將導致浪費cpu資源
5.緩存穿透、緩存雪崩解決方案
參考文章:https://mp.weixin.qq.com/s/JCFx-GNjueLLOEjWMKbLRQ
緩存雪崩
簡介:緩存設置相同的過期時間導致大面積失效、給數據庫造成巨大壓力
解決:加鎖通常是分佈式鎖、加隊列、設置不同的緩存時間、使用緩存標記:每個緩存額外增加一個是否存在的狀態,先判斷是否存在在取緩存的值,通常緩存的值的時間是緩存標記的時間兩倍用於髒讀
緩存穿透
簡介:通常是用戶查詢數據、數據庫中沒有,自然緩存中也沒有,導致每次從緩存中查不到數據每次都要去數據庫中查一遍
解決:空的記錄也要緩存避免緩存穿透
緩存擊穿
簡介:緩存擊穿表示數據庫中有緩存沒有,併發又太大數據庫壓力瞬間增大
解決:熱點數據用不過期、加互斥鎖、隊列
緩存擊穿與緩存雪崩的區別:擊穿是併發查詢同一條數據、雪崩是不同數據都過期了
6.多線程的幾種實現方式
- 繼承Thread類
- 實現Runnable接口
- 實現Callable接口通過FutureTask包裝器來創建Thread線程
- 線程池的方式
7.線程一共有哪些狀態
初始態(NEW)
運行態(RUNNABLE),運行態包括 就緒態 和 運行態。
阻塞態(BLOCKED)
等待態(WAITING)
超時等待態(TIMED_WAITING)
終止態(TERMINATED)
8.瞭解哪些內存溢出
以下均屬於錯誤而不是異常:
- java.lang.StackOverflowError
默認棧的大小爲0.5m~1m,超出這個大小將發生棧溢出錯誤。導致原因:深度的方法調用,出不來了。 - java.lang.OutOfMemoryError:Java heap space
堆內存溢出異常。導致原因:大對象無法被回收,或者大量對象無法回收,撐爆設定的虛擬機設置的空間 - java.lang.OutOfMemoryError:GC overhead limit exceeded
導致原因:GC回收時間過長,並且收效甚微,回收到很少的內存。如果不拋出內存很快填滿,GC再次運行,CPU100%,卻沒什麼成果。 - java.lang.OutOfMemoryError:Direct buffer memory
直接內存溢出異常,多見於nio與netty框架中,ByteBuffer.allocteDirect(capability),堆內存很少使用jvm也不會回收,但是本地內存已經使用完了,再次嘗試分配就會出現OutOfMemoryError - java.lang.OutOfMemoryError:unable to create new native thread
操作系統線程數量是有限制的,root用戶沒有限制普通用戶liunx默認最多爲1024個線程,如果超過這個數量就會報這個異常,當然是可配置的。 - java.lang.OutOfMemoryError:Metaspace
元空間溢出異常,元空間存儲虛擬機加載的類信息,常量池,靜態變量,即時編譯後的代碼,這些存放超過元空間指定大小就會報這個異常
9.內存溢出與內存泄露區別
內存溢出表示內存不夠用了,內存泄露表示使用結束時未及時釋放清理,導致一直佔用內存,使得實際內存減少好像內存泄露了一樣
10.如何快速定位內存溢出
- 根據日誌排查
- 使用jamp指令生成dump文件、然後使用MAT工具進行分析
11.服務器動態縮減方案
- LB(Load Balancing),負載均衡方案
- 代表:硬負載均衡F5、軟負載均衡nginx,HAProxy
- 根據負載均衡算法關閉某些服務費訪問
- 常用的負載均衡算法:最小請求、隨機、加權隨機、哈希、輪詢
12.一致性hash算法
https://mp.weixin.qq.com/s/AYwarOGR7We1WO5u41onGQ
- 假如redis使用hash算法,當需要增加一臺機器的時候需要全部重新計算hash值,擴容的這段時間內存失效的,容易造成內存雪崩。hashmap用的就是hash算法
- 一致性hash算法,構造出一個2^32個虛擬槽位置俗稱hash環、redis每個節點進行hash找到對應的槽的位置。數據key進行hash,確定在換的位置,然後從此位置順時針行走,遇到第一個節點就是應該定位的服務器。如果其中後一個不幸宕機了,它的數據會移動到其它的節點;
- 一致性hash數據傾斜問題:同一個節點可以多次hash構造多個hash節點
13.bio與nio的區別
http://www.pianshen.com/article/9423291755/
https://my.oschina.net/ljhlgj/blog/1811319
- BIO:同步阻塞IO、收到連接請求後一直阻塞(阻塞io),直到數據就緒後讀取或者寫入完成;
- NIO:同步非阻塞IO、收到連接請求後立即返回(非阻塞io),然後定時輪詢檢查是否有數據就緒;
- 同步:觸發IO操作並等待或者輪詢的去查看IO操作是否就緒(親力親爲且專注於一件事)
- 異步: 異步是指用戶進程觸發IO操作以後便開始做自己的事情
14.springboot配置文件加載順序
通過啓動命令配置spring.config.location 改變默認配置,此優先級最高
默認加載順序依次爲:
file:./config 文件根目錄的config目錄最高
file:./ 文件根目錄其次
classpath:/config/ classpath的config目錄下依次
classpath:/ classpath 目錄下最後
15.springboot獲取屬性有哪些方式
@value 適合單個值
@ConfigurationProperties 適合類對象