Java面試札記
Java面試札記
在最深的夜裡,即使是你的影子也會離你而去。
背景:願某人在中秋節之前吃上大廠月餅!!!@CDZ
1、Java的八種基本數據類型?
整型:byte、int、short、long;
浮點型:float、double;
布爾類型:boolean;
字元型:char。
2、什麼是重入鎖?
java.util.concurrent.ReentrantLock,這個是JDK1.5添加的一種顆粒度更小的鎖,它完全可以替代synchronized關鍵字來實現它的所有功能,而且ReentrantLock鎖的靈活度要遠遠大於synchronized關鍵字。
3、Controller是單例還是多例?
Spring管理的Controller,即加入@Controller注入的類,默認是單例的,因此建議:
1、不要在Controller中定義成員變數;
2、若必須要在Controller中定義一個非靜態成員變數,則通過註解@Scope(“prototype”),將其設置為多例模式;
4、StringBuffer和StringBuilder的區別?
StringBuffer是執行緒同步安全的,StringBuilder是非執行緒安全的一般用於單執行緒;
5、為什麼要加雙重鎖?
1、為什麼要進行第一次判空?
單例模式只有第一次執行create()方法的時候才會走synchronized中的程式碼,後面再次訪問的時候直接返回single對象;如果說我們沒有第一次校驗,每一個執行緒都要走sychronized中的程式碼,
而每一次執行緒都要去拿到同步鎖才能執行;在多執行緒情況下,每一個執行緒要拿到single對象都要排隊等待同步鎖釋放,因此第一次校驗就是為了提高程式的效率。
2、為什麼要進行第二次判空?
舉個例子:假如現在沒有第二次校驗,執行緒A執行帶第一次校驗那裡,它判斷到single==null,此時它的資源被執行緒B搶佔了,B執行程式,進入同步程式碼塊創建對象,然後釋放同步鎖,此時執行緒
A又拿到了資源,也拿到了同步鎖,然後執行同步程式碼塊,因為之前執行緒A它判斷到single==null,因此它會直接創建新的對象,所以就違反了我們設計的最終目的。
6、5L的桶和3L的桶如何量出4L的水?
把3L的桶裝滿水,然後全部倒入5L桶中,此時5L桶中有3L水;再把3L桶裝滿水,然後倒入裝有3L水的5L桶中直至滿,此時3L桶中有1L水;把5L桶中的水倒完,再把3L桶中剩餘的1L水倒入
5L桶中,此時5L桶中有1L水;再把3L桶裝滿水,全部倒入裝有1L水的5L桶中,此時5L桶中有4L水。
7、如何給一條資料庫記錄加鎖?
1、共享鎖:select * from table_name where …… lock in share mode;
2、排他鎖:select * from emp where empid > 100 for update;
加鎖後其他人不可操作,直到加鎖用戶解鎖,用commit或rollback解鎖。
8、如何捕獲執行緒異常?
方式1(setUncaughtExceptionHandler):
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler();
方式2:
使用Executors創建執行緒時,還可以在ThreadFactory中設置:
t.setUncaughtExceptionHandler(new MyUncheckedExceptionHandler());
該方法還需要提交執行緒異常:exec.execute(new ExceptionThread());
方式3:
利用執行緒池提交執行緒時返回的Future引用:
Integer result = future.get();
9、JDK1.8的日期類有哪些?
獲取當前時間:LocalDateTime、LocalTime、LocalDate
LocalDateTime d0 = LocalDateTime.now(); System.out.println(DataConvertUtil.localDateTimeToStr(d0,"yyyy-MM-dd HH:mm:ss"));
10、Redis集群策略
Redis包含三種集群策略:主從複製、哨兵、集群;
主從複製特點:
主資料庫負責讀寫操作,當讀寫操作導致數據變化時會自動將數據同步給從資料庫;從資料庫一般是只讀的,並且接受主資料庫同步過來的數據;一個master可以擁有多個slave,但是一個slave只能對應一個master。
主從複製工作機制:
當slave啟動後,主動向master發送SYNC命令,然後將保存的快照文件和快取的命令發送給slave,slave接收到快照文件和命令後載入快照文件和快取的執行命令;複製初始化後,master每次接收到的寫命令都會同步發送給slave,保證資料庫一致性。
主從複製配置:
Redis默認主資料庫,所以master無需配置,只需要修改slave的配置即可;在slave中設置需要連接的master的ip埠:slaveof 10.58.166.207 6379。
哨兵:
哨兵的作用是監控redis系統的運行狀況,其功能如下:
1、master出現故障時,自動將slave轉化為master;
2、多個哨兵可以監控同一個redis;
3、多哨兵配置時,哨兵之間會自動監控。
集群:
使用Redis集群,只需要將每個資料庫節點的cluster-enable配置打卡即可;每個集群中至少需要三個主資料庫才能正常運行。
11、快排思想?
快速排序是對冒泡排序的一種改進,通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另一部分的所有數據都要小。
12、桶排序演算法?
桶排序是常見排序演算法中速度最快的一種,假設有一個大小為n的數組int arr[n] ,遍曆數組找到最大值M,然後申請一個大小為M+1的數組int m[M+1],剛開始的時候將m[0]~m[M+1]都值都初始化為0,然後遍曆數組n,把對應的arr[n]填入日子m[M+1]都對應位置,如果有重複的元素則在此位置的基礎上+1。
13、MySQL的四種讀寫機制?
1、未提交讀 Read Uncommitted:允許臟讀,也就是可能讀取到其它會話中未提交事務修改的內容;
2、提交讀 Read Committed:只能讀取到已經提交了的數據;(不重複讀,Oracle資料庫默認該級別)
3、可重複讀 Repeated Read:在同一個事務內的查詢都是事務開始一刻一致的,InnoDB默認級別;(MySQL資料庫默認該級別)
4、串列讀 Serializeble:完全串列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞,級別最高。
14、使用什麼方法替代程式碼中的if-else?
1、使用工廠模式去耦合;
2、儘可能抽象方法、優化程式碼邏輯,減少判斷方法;
3、從業務邏輯上優化減少if-else或用switch。
15、Linux內部命令和外部命令的區別?
內外部命令的功能基本相同,但存在的位置有差異,可以通過type來查看是內部命令還是外建命令。
圖.內部命令/外部命令
內部命令:
內部命令是shell程式的一部分命令,包含一些簡單的Linux系統命令,內部命令是在bashy源碼中,其執行速度通常比外部命令要快;
外部命令:
每個外部命令對應系統中的一個文件,外部命令不包含在shell中,但是其命令執行過程是由shell程式控制的,如管理外部命令執行的路徑查找、載入存放和控制命令的執行,外部命令通常存放在/bin、/usr/sbin目錄下。
16、JVM演算法?
三種演算法:標記-清除演算法、複製演算法、標記整理演算法;
標記清除演算法:
採用從根集合進行掃描,對存活的對象進行標記,標記完畢後再掃描整個空間中未被標記的對象,並對其進行直接回收;該演算法不需要進行對象的移動,並且僅對不存活的對象進行處理,在存活的對象較多的情況下極為高效;但由於該演算法只回收不存活的對象,並沒有對存活的對象進行整理,因此會導致記憶體碎片。
複製演算法:
將記憶體劃為兩個分區,使用此演算法時,所有動態分配的對象只能分配其中的一個區間(活動區間),而另外一個區間則是空閑區間;其採用從根集合掃描,將存活的對象複製到空閑區間,當掃描
完畢活動區間後,會將活動區間一次性回收,此時原本的空閑區間變成了活動區間,下次GC的時候又會重複剛才的操作,如此循環;但是,此方法需要克服50%記憶體的浪費。
標記整理演算法:
採用標記-清除演算法一樣的方式進行對象的標記、清除,但在回收不存活的對象佔用的空間後,該演算法會將所有存活的對象往左端空閑區間移動,並更新對應的指針,其是在標記-清除演算法之上又
進行了對象的移動排序整理,因此成本更高,但也解決了記憶體碎片的問題。
17、HashMap簡單介紹下?
HashMap是用於存儲key-value鍵值對的集合,它是根據鍵的hashCode值存儲數據,可以直接定位到它的值,所以具有很快的訪問速度,是非執行緒安全的;從整體結構上看HashMap是由數組+鏈表+紅黑樹實現的。(簡單講下get、put、remove和擴容,擴容為原數組大小兩倍的新數組,新數組的索引位置要麼在原位置不變,要麼是原位置+舊數組長度)
18、常用設計模式?
單例模式、工廠模式、代理模式、觀察者模式、裝飾者模式、適配器模式、模版模式、策略模式、訪問者模式。
在最深的夜裡,即使是你的影子也會離你而去。