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