整理最全Java面試題一(附答案,歡迎指正)

說明:面試題爲網絡上整理,答案爲自己簡寫,能力有限,面試參考。

基礎篇一

一.基礎知識:

1)集合類:List和Set比較,各自的子類比較(ArrayList,,LinkedList;HashSet,TreeSet);
1.1 List接口繼承自Collection接口,是有序的,集合中的元素可以重複,常用兩個實現子類爲ArrayList和LinkedList,

  • 【Arraylist】基於數組實現,可以理解爲一種動態數組,查找速度快,增加和刪除操作慢,適用於查詢頻率高,增刪頻度低的情況;
  • 【LinkedList】基於鏈表實現,查找速度慢,增加和刪除速度快。

1.2 Set — 擴展了Collection的集合,集合中的元素不可以重複,即任意的兩個元素e1和e2都有e1.equals(e2) == false。訪問集合中的元素只能根據元素本身來訪問。

  • 【哈希表】HashSet:Set中訪問速度最快。原則上Set不能有重複的元素,但假設HashSet插入不同元素後,又將2個元素改成相同值也可以(這種屬於未定義行爲,即Set的各個實現可以自行處理這種情況,可以報異常也可以如HashSet般不聞不問,但是這種未定義行爲應儘量避免,而避免的方法就是使得插入的元素不可修改,也即使得元素爲不可變類,Map也有同樣問題);
    -【平衡樹】TreeSet:實現了SortedSet,可以提供排序功能;

2)HashMap的底層實現,之後會問ConcurrentHashMap的底層實現;

  • 1 HashMap 在java1.7使用的是數組加鏈表。通過hash算法計算出key所在的位置,然後進行存取操作。
    在java1.8中,如果鏈表長度過長,則會將鏈表調整爲紅黑樹,這樣很好的保證了查詢的效率,提升了hashMap的性能。
    hashMap 線程不安全。
  • 2 concurrentHashMap 1.7和1.8參考文章 https://juejin.im/post/5aba1030f265da23961269c6
    簡單講 concurrentHashmap就是對HashMap的加鎖實現,避免了hashMap在多線程環境下的不安全。
    1.7版本中,加鎖思路是ReentrantLock+Segment+HashEntry,鎖的最小單元爲Segment數組,包含多個hashEntry節點;
    1.8版本中,加鎖思路是synchronized+CAS+HashEntry+紅黑樹,鎖的最小單元就是HashEntry(首節點),鎖粒度變小了,併發性能提高了。

3)如何實現HashMap順序存儲:可以參考LinkedHashMap的底層實現;

4)HashTable和ConcurrentHashMap的區別;

  • 相同點: Hashtable 和 ConcurrentHashMap都是線程安全的,可以在多線程環境中運行; key跟value都不能是null
    同爲線程安全,但是HashTable
  • 區別: 兩者主要是性能上的差異,Hashtable的所有操作都會鎖住整個對象,雖然能夠保證線程安全,但是性能較差; ConcurrentHashMap內部使用Segment數組,每個Segment類似於Hashtable,在“寫”線程或者部分特殊的“讀”線程中鎖住的是某個Segment對象,其它的線程能夠併發執行其它的Segment對象。

5)String,StringBuffer和StringBuilder的區別;

  • 【String】爲final類,申明的對象不可變,當申明一個對象String a = "a"時,該對象便不可更改,改變a實際上是創建一個新的對象,然後將a的指針指向新對象,但是原對象依舊存在,並未改變;

  • 【 StringBuffer】StringBuffer大部分方法都是synchronized,線程安全。

  • 【StringBuilder】非線程安全,效率高。

6)Object的方法有哪些:比如有wait方法,爲什麼會有;
  hashcode();equals();wait();notify();notifyAll();finalize();gerClass();
  wait()的作用是讓當前線程進入等待狀態,同時,wait()也會讓當前線程釋放它所持有的鎖。
 
7)wait和sleep的區別,必須理解;
  1、每個對象都有一個鎖來控制同步訪問,Synchronized關鍵字可以和對象的鎖交互,來實現同步方法或同步塊。sleep()方法正在執行的線程主動讓出CPU(然後CPU就可以去執行其他任務),在sleep指定時間後CPU再回到該線程繼續往下執行(注意:sleep方法只讓出了CPU,而並不會釋放同步資源鎖!!!);wait()方法則是指當前線程讓自己暫時退讓出同步資源鎖,以便其他正在等待該資源的線程得到該資源進而運行,只有調用了notify()方法,之前調用wait()的線程纔會解除wait狀態,可以去參與競爭同步資源鎖,進而得到執行。(注意:notify的作用相當於叫醒睡着的人,而並不會給他分配任務,就是說notify只是讓之前調用wait的線程有權利重新參與線程的調度);
  2、sleep()方法可以在任何地方使用;wait()方法則只能在同步方法或同步塊中使用;
  3、sleep()是線程線程類(Thread)的方法,調用會暫停此線程指定的時間,但監控依然保持,不會釋放對象鎖,到時間自動恢復;wait()是Object的方法,調用會放棄對象鎖,進入等待隊列,待調用notify()/notifyAll()喚醒指定的線程或者所有線程,纔會進入鎖池,不再次獲得對象鎖纔會進入運行狀態。

8)JVM的內存結構,JVM的算法;
參考博客:https://blog.csdn.net/tonytfjing/article/details/44278233

9)強引用,軟引用和弱引用的區別;

10)數組在內存中如何分配;

11)用過哪些設計模式,手寫一個(除單例);

靜態代理

public interface A{
	public void msg();
}

public class B implements A{
 public void msg(){
		System.out.priintln("實現代理模式");
     }
}

publid class ProcyClass implements A{
  Private B b;
  public setB(B b){
  this.b = b;
   }
pubblic void msg(){
    b.msg();
  }
}

12)springmvc的核心是什麼,請求的流程是怎麼處理的,控制反轉怎麼實現的;
  springmvc的核心是DispatchServelet,前端控制區攔截請求,分發請求,相應客戶端。

總結一下springMVC幾個關鍵的步驟,總共可以分爲六個步驟,分別爲:

(1) 客戶端向spring容器發起一個http請求

(2) 發起的請求被前端控制起所攔截(DispatcherServlet),前端控制器會去找恰當的映射處理器來處理這次請求。

(3) 根據處理器映射(Handler Mapping)來選擇並決定將請求發送給那一個控制器。

(4) 在控制器中處理所發送的請求,並以modelAndView(屬性值和返回的頁面)的形式返回給向前端控制器。

(5) 前端控制器通過查詢viewResolver對象來試着解決從控制返回的視圖。

控制反轉應該是spring的核心思想,將bean對象交給spring容器,這樣原本需要你自己創建的對象,可以直接通過spring容器注入到需要使用的地方。

13)spring裏面的aop的原理是什麼;
 動態代理。

14)mybatis如何處理結果集:反射,建議看看源碼;

15)java的多態表現在哪裏;
  表現在子類對父類方法的複寫上。

16)接口有什麼用;
   接口是一個規範,可以統一繼承該接口的子類做什麼。

17)說說http,https協議;

18)tcp/ip協議簇;

19)osi五層網絡協議;

20)tcp,udp區別;

21)用過哪些加密算法:對稱加密,非對稱加密算法;

22)說說tcp三次握手,四次揮手;

23)cookie和session的區別,分佈式環境怎麼保存用戶狀態;
- cookie:

  - 1 cookie數據存放在客戶的瀏覽器上
  - 2 cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙考慮到安全應當使用session。
  - 3 單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。

session:

  • session數據放在服務器上
  • session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能

24)git,svn區別;

25)請寫一段棧溢出、堆溢出的代碼;

26)ThreadLocal可以用來共享數據嗎;

二. IO:

1)bio,nio,aio的區別;
參考文章: https://juejin.im/entry/598da7d16fb9a03c42431ed3

2)nio框架:dubbo的實現原理;

3)京東內部的jsf是使用的什麼協議通訊:可參見dubbo的協議;

三.算法:

1)java中常說的堆和棧,分別是什麼數據結構;另外,爲什麼要分爲堆和棧來存儲數據。

2)TreeMap如何插入數據:二叉樹的左旋,右旋,雙旋;

3)一個排序之後的數組,插入數據,可以使用什麼方法?答:二分法;問:時間複雜度是多少?

4)平衡二叉樹的時間複雜度;

5)Hash算法和二叉樹算法分別什麼時候用;

6)圖的廣度優先算法和深度優先算法:詳見jvm中垃圾回收實現;

四.多線程相關:

1)說說阻塞隊列的實現:可以參考ArrayBlockingQueue的底層實現(鎖和同步都行);

2)進程通訊的方式:消息隊列,共享內存,信號量,socket通訊等;

3)用過併發包的哪些類;

4)什麼地方用了多線程;

5)Excutors可以產生哪些線程池;

6)爲什麼要用線程池;

7)volatile關鍵字的用法:使多線程中的變量可見;

五.數據庫相關(mysql):

1)msyql優化經驗:

2)mysql的語句優化,使用什麼工具;

3)mysql的索引分類:B+,hash;什麼情況用什麼索引;

4)mysql的存儲引擎有哪些,區別是什麼;
innodb和myslam存儲引擎,現在默認都是使用innodb
innodb,默認使用行級鎖,支持事務,行級鎖,適合讀多寫少的場景,而實際項目中,讀寫比大概在10:1,所以大部分場景下,使用innodb。
muisam 默認使用表級鎖,不支持事務。

5)說說事務的特性和隔離級別;
原子性,一致性,隔離性,持久性。
隔離級別:

  • 串行化
  • 可重複讀
  • 讀已提交
  • 讀未提交

6)悲觀鎖和樂觀鎖的區別,怎麼實現;

六 .mq:

1)mq的原理是什麼:有點大。。都可以說;
mq作爲消息隊列,是將生產者將消息存放在隊列中,然後消費者監聽隊列,並對隊列中的消息進行消費。
常用語分佈式服務中的服務調用,可以一定程度上解耦,在高併發的服務中,還可以通過其異步操作來提高系統的穩定性和可用性。
2)mq如何保證實時性;

3)mq的持久化是怎麼做的;

七.nosql相關(主要是redis):

1)redis和memcache的區別;

2)用redis做過什麼;

3)redis是如何持久化的:rdb和aof;

4)redis集羣如何同步;

5)redis的數據添加過程是怎樣的:哈希槽;

6)redis的淘汰策略有哪些;

7)redis有哪些數據結構;

八.zookeeper:

1)zookeeper是什麼;

2)zookeeper哪裏用到;

3)zookeeper的選主過程;

4)zookeeper集羣之間如何通訊;

5)你們的zookeeper的節點加密是用的什麼方式;

6)分佈式鎖的實現過程;

九.linux相關:

1)linux常用的命令有哪些;
經常使用的 ls,mkdir,cd,pwd,mv,cp,rmdir,rm,cat,grep,netstat,tar,gzip,unzip,help,shutdown.

2)如何獲取java進程的pid;
答案下一題。

3)如何獲取某個進程的網絡端口號;

  • 1、先查看進程pid
    ps -ef | grep 進程名

  • 2、通過pid查看佔用端口
    netstat -nap | grep 進程pid

4)如何實時打印日誌;

5)如何統計某個字符串行數;

十.設計與思想:

1)重構過代碼沒有?說說經驗;

2)一千萬的用戶實時排名如何實現;

3)五萬人併發搶票怎麼實現;

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