面試的最新問題

主鍵是一種約束,唯一索引是一種索引,兩者在本質上是不同的。
主鍵創建後一定包含一個唯一性索引,唯一性索引並不一定就是主鍵。
唯一性索引列允許空值,而主鍵列不允許爲空值。
主鍵列在創建時,已經默認爲空值 + 唯一索引了。
主鍵可以被其他表引用爲外鍵,而唯一索引不能。
一個表最多隻能創建一個主鍵,但可以創建多個唯一索引。
主鍵更適合那些不容易更改的唯一標識,如自動遞增列、身份證號等。

數據庫中的B+Tree索引可以分爲聚集索引(clustered index)和輔助索引(secondary index)。上面的B+Tree示例圖在數據庫中的實現即爲聚集索引,聚集索引的B+Tree中的葉子節點存放的是整張表的行記錄數據。輔助索引與聚集索引的區別在於輔助索引的葉子節點並不包含行記錄的全部數據,而是存儲相應行數據的聚集索引鍵,即主鍵。當通過輔助索引來查詢數據時,InnoDB存儲引擎會遍歷輔助索引找到主鍵,然後再通過主鍵在聚集索引中找到完整的行記錄數據。
 

1 事務的傳播屬性(Propagation) 

1) REQUIRED ,這個是默認的屬性 
Support a current transaction, create a new one if none exists. 
如果存在一個事務,則支持當前事務。如果沒有事務則開啓一個新的事務。 
被設置成這個級別時,會爲每一個被調用的方法創建一個邏輯事務域。如果前面的方法已經創建了事務,那麼後面的方法支持當前的事務,如果當前沒有事務會重新建立事務。 
如圖所示: 

2) MANDATORY 
Support a current transaction, throw an exception if none exists.支持當前事務,如果當前沒有事務,就拋出異常。 

3) NEVER 
Execute non-transactionally, throw an exception if a transaction exists. 
以非事務方式執行,如果當前存在事務,則拋出異常。

用戶發送請求至前端控制器DispatcherServlet。

DispatcherServlet收到請求調用HandlerMapping處理器映射器。

處理器映射器找到具體的處理器(可以根據xml配置、註解進行查找),生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。

DispatcherServlet調用HandlerAdapter處理器適配器。

HandlerAdapter經過適配調用具體的處理器(Controller,也叫後端控制器)。

Controller執行完成返回ModelAndView。

HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。

DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。

ViewReslover解析後返回具體View。

DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。

DispatcherServlet響應用戶。
 

內存泄漏是指程序由於錯誤或漏洞造成的內存佔用過多,或佔用內存後無法釋放
內存溢出是指已有的數據超過了其獲得到的內存所能存儲的範圍,比如用一個字節存放1000這個數字就屬於內存溢出

 

聯合索引的使用情況

https://blog.csdn.net/Abysscarry/article/details/80792876

當你創建一個索引 create index xxx on t(a,b), 則索引文件邏輯上等同於如下
a b rowid
1 1 1
1 1 12
1 1 14
1 2 6
1 2 8
1 3 4
1 3 9
2 1 2
2 1 15
2 2 3
2 2 10
2 2 11
2 3 5
2 3 7
2 3 13

當select * from T where a=1 and b=3 的時候, 數據庫系統可以直接從索引文件中直接二分法找到A=1的記錄,然後再B=3的記錄。
但如果你 where b=3 則需要遍歷這個索引表的全部

 

設計模式六大原則

單一職責原則: 應該有且只有一個原因引起類的變化
里氏代換原則:只要父類出現的地方子類就一定可以出現,而且替換爲子類也不會出現任何異常或錯誤,使用者不需要知道是父類還是子類.但是返回來就不行了,有子類出現的地方,不一定能使用父類
依賴倒置原則:高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象,抽象不應該依賴細節,細節應該依賴抽象
接口隔離原則:針對接口編程,依賴於抽象而不依賴於具體。
迪米特法則:一個對象應該對其他對象有最少的瞭解,,就是降低各模塊之間的耦合
開閉原則:模塊和函數應該對擴展開放,對修改關閉, 

消息隊列的特點:

 rabbitMQ穩定,可靠,數據一致,支持多協議,有消息確認,性能一般,基於erlang語言,二次開發困難.
    kafka高吞吐,高性能,快速持久化,無消息確認,無消息遺漏,可能會有有重複消息,依賴於zookeeper,成本高.
    ZeroMQ靈活快速,不支持持久化,需要大量編碼來實現穩定可靠.
    ActiveMQ不夠靈活輕巧,對隊列較多情況支持不好.
    rocketMQ性能好,高吞吐,高可用性,支持大規模分佈式.

    ZeroMQ小而美,RabbitMQ大而穩,Kakfa和RocketMQ快而強勁

 

線程池的種類,區別和使用場景
newCachedThreadPool:適用:執行很多短期異步的小程序或者負載較輕的服務器; 高併發 大數據的時候
可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。
newFixedThreadPool:適用:執行長期的任務,性能好很多  多用於數據庫執行時
定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
newSingleThreadExecutor: 適用:一個任務一個任務執行的場景
單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
NewScheduledThreadPool: 適用:週期性執行任務的場景    
定長線程池,支持定時及週期性任務執行。

 

equals和==的區別小結
 == 
 1、用於基本數據類型的比較

2、判斷引用是否指向堆內存的同一塊地址
比較的是變量(棧)內存中存放的對象的(堆)內存地址,用來判斷兩個對象的地址是否相同,即是否是指相同一個對象。比較的是真正意義上的指針操作
 equals用來比較的是兩個對象的內容是否相等,由於所有的類都是繼承自java.lang.Object類的,所以適用於所有對象,如果沒有對該方法進行覆蓋的話,調用的仍然是Object類中的方法,而Object中的equals方法返回的卻是==的判斷
 
 如String、Integer、Date。在這些類當中equals有其自身的實現(一般都是用來比較對象的成員變量值是否相同),而不再是比較類在堆內存中的存放地址了。 
所以說,對於複合數據類型之間進行equals比較,在沒有覆寫equals方法的情況下,他們之間的比較還是內存中的存放位置的地址值,跟雙等號(==)的結果相同;如果被複寫,按照複寫的要求來。

2.spring 事務,7中傳播行爲

嵌套事務不能夠提交,它必須通過外層事務來完成提交的動作,外層事務的回滾也會造成內部事務的回滾。

 

三:RPC與REST的區別 
如果你想只記住一點,那麼就請記住 RPC是以動詞爲中心的, REST是以名詞爲中心的, 此處的 動詞指的是一些方法, 名詞是指資源.

你會發現,以動詞爲中心,意味着,當你要需要加入新功能時,你必須要添加更多的動詞, 這時候服務器端需要實現 相應的動詞(方法), 客戶端需要知道這個新的動詞並進行調用.

而以名詞爲中心, 假使我請求的是 hostname/friends/, 無論這個URI對應的服務怎麼變化,客戶端是無需 關注和更新的,而這種變化對客戶端也是透明的.
 

synchronized與Lock的區別

兩者區別:

1.首先synchronized是java內置關鍵字,在jvm層面,Lock是個java類;

2.synchronized無法判斷是否獲取鎖的狀態,Lock可以判斷是否獲取到鎖;

3.synchronized會自動釋放鎖(a 線程執行完同步代碼會釋放鎖 ;b 線程執行過程中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),否則容易造成線程死鎖;

4.用synchronized關鍵字的兩個線程1和線程2,如果當前線程1獲得鎖,線程2線程等待。如果線程1阻塞,線程2則會一直等待下去,而Lock鎖就不一定會等待下去,如果嘗試獲取不到鎖,線程可以不用一直等待就結束了;

5.synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(兩者皆可)

6.Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少量的同步問題。

 

1.Spring實例化bean的四種方式
本文主要介紹四種實例化bean的方式(注入方式) 或者叫依賴對象實例化的四種方式。上面的程序,創建bean 對象,用的是什麼方法 ,用的是構造函數的方式 (Spring 可以在構造函數私有化的情況下把類對象創建出來)
常用的創建方式有以下四種:
1) setter 方法
2) 構造函數
3) 靜態工廠
4) 實例工廠

2.

tomcat的調優 增加JVM堆內存大小
      修復JRE內存泄漏
      線程池設置
      壓縮
      數據庫性能調優
      Tomcat本地庫

   1.系統性能優越

   2.java虛擬機調優(10.JVM的調優:
    a 將新對象預留在年輕代;    b 讓大對象進入年老代;    c 設置對象進入年老代的年齡    d 嘗試使用大的內存分頁;    f 增大吞吐量提升系統性能;    g 年老代年輕代大小劃分
    h 內存泄漏     I 垃圾回收算法設置合理)

   3.web服務器專門處理http請求

   4.把Apache和Tomcat集成起來

3.AOP

。 將系統中非核心的業務提取出來,進行單獨處理
可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術
AOP只是一種編程範式,用於提供從另一角度來考慮程序結構以完善面向對象編程。主要優點有:1-降低模塊之間的耦合度。2-使系統容易擴展。3-更好的代碼複用
AOP簡單來說是面向切面編程,就是可以規定在你運行某些特定方法之前或者之後進行的另外一種操作,比如打印日誌,這種編程方法的好處是,當你有一些方法中會有基本相同的操作進行時,可以抽取出來,通過配置文件放進方法中,而它需要修改的時候只需要動抽取出來的這個方法就好了,而不用一個一個的挨着改,達到低耦合的效果。

一、基於XML配置的Spring AOP
採用聲明的方式實現(在XML文件中配置),大致步驟爲:配置文件中配置pointcut, 在java中用編寫實際的aspect 類, 針對對切入點進行相關的業務處理。
常見有三種實現方式:
1.利用代理模式動態的實現AOP,從具體的技術細節又可以分爲靜態代理,動態代理,CGLIB生成子類代理。
2.使用預編譯的方法靜態進行代理。
3.使用自定義加載器的方法動態進行代理

 

4.反射

v

通過反射,我們可以在運行時獲得程序或程序集中每一個類型成員和成員變量的信息。
程序中一般的對象類型都是在編譯期就確定下來的,而Java 反射機制可以動態的創建對象並調用其屬性,這樣對象的類型在編譯期是未知的。所以我們可以通過反射機制直接創建對象即使這個對象在編譯期是未知的,
反射的核心:是 JVM 在運行時 才動態加載的類或調用方法或屬性,他不需要事先(寫代碼的時候或編譯期)知道運行對象是誰。
 反射可以擬用於判斷任意對象所屬的類,獲得 Class對象,構造人一個對象以及調用一個對象
 (1)、使用 Class類的 forName() 靜態方法:
public static Class<?> forName(String className)
……
在JDBC開發中常用此方法加載數據庫驅動:
……java
Class.forName(driver)
(3)、調用某個對象的getClass() 方法,比如:
StringBuilder str = new StringBuilder("123");
Class<?> klass = str.getClass();


①、獲得 Class 對象     
②、判斷是否爲某個類的實例     
③、創建實例

 

1。java8中對hashmap和concurrentHashMap的優化 
     在JDK8中,單純的HashMap數據結構增加了紅黑樹是一個大的優化,此外根據上面的遷移擴容策略,我們發現JDK8裏面HashMap沒有采用頭插法轉移鏈表數據,而是保留了元素的順序位置,新的代碼裏面採用:    JDK7裏面是先判斷table的存儲元素的數量是否超過當前的threshold=table.length*loadFactor(默認0.75),如果超過就先擴容,在JDK8裏面是先插入數據,插入之後在判斷下一次++size的大小是否會超過當前的閾值,如果超過就擴容。
    java7ConcurrentHashMap採用了分段鎖的設計,只有在同一個分段內才存在競態關係,不同的分段鎖之間沒有鎖競爭。HashEntry中的value以及next都被volatile修飾,這樣在多線程讀寫過程中能夠保持它們的可見性,
    在JDK8中徹底拋棄了JDK7的分段鎖的機制,sizeCtl 控制標識符,。新的版本主要使用了Unsafe類的CAS自旋賦值+synchronized同步+LockSupport阻塞等手段實現的高效併發,
    最大的區別在於JDK8的鎖粒度更細,理想情況下talbe數組元素的大小就是其支持併發的最大個數,
    
2。volatile與synchronized
volatile本質是在告訴jvm當前變量在寄存器中的值是不確定的,需要從主存中讀取,synchronized則是鎖定當前變量,只有當前線程可以訪問該變量,其他線程被阻塞住.
volatile僅能使用在變量級別,synchronized則可以使用在變量,方法.
volatile僅能實現變量的修改可見性,但不具備原子特性,而synchronized則可以保證變量的修改可見性和原子性.
volatile不會造成線程的阻塞,而synchronized可能會造成線程的阻塞.

3.mysql行鎖是否會有死鎖的情況
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。

行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高
死鎖的關鍵在於:兩個(或以上)的Session加鎖的順序不一致。

當對存在的行進行鎖的時候(主鍵),mysql就只有行鎖。

當對未存在的行進行鎖的時候(即使條件爲主鍵),mysql是會鎖住一段範圍(有gap鎖)

4.ThreadLocal的應用場景

它是線程的局部變量,這些變量只能在這個線程內被讀寫,在其他線程內是無法訪問的。
:就是當我們只想在本身的線程內使用的變量,可以用 ThreadLocal 來實現,並且這些變量是和線程的生命週期密切相關的,線程結束,變量也就銷燬了。
1、比如線程中處理一個非常複雜的業務,可能方法有很多,那麼,使用 ThreadLocal 可以代替一些參數的顯式傳遞;
2、比如用來存儲用戶 Session。
4、還有像線程內上線文管理器、數據庫連接等可以用到 ThreadLocal;

5.java的GC機制,GC Roots有哪些

GC管理的主要區域是Java堆,一般情況下只針對堆進行垃圾回收。方法區、棧和本地方法區不被GC所管理,因而選擇這些區域內的對象作爲GC roots,
在Java語言裏,可作爲GC Roots對象的包括如下幾種: 
a.虛擬機棧(棧楨中的本地變量表)中的引用的對象 
b.方法區中的類靜態屬性引用的對象 
c.方法區中的常量引用的對象 
d.本地方法棧中JNI的引用的對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章