天天看點

java常見面試題——持續更新中java常見面試題

java常見面試題

1 說說你關于常量的認識

常量是用final修飾的變量,定義的時候就要指派,并且值不能被修改,通常在定義的時候需要大寫,然後多個字母之間用下劃線分割。
           

2 說說關于++ 和 --的認識

++和–分别是自增和自減運算符,通常放在整型變量前後,運算方向從左往右

m=2 m的值 表達式的值 分析
m ++ 3 2 ++在變量的後面,先參與運算,然後在進行自增運算
++m 3 3 ++在變量的前面,先進行自增運算,然後再參與運算
m– 1 2 –在變量的後面,先參與運算,然後再進行自減運算
–m 1 1 –在變量的前面,先進行自減運算,然後再參與運算

3 解釋短路的概念

  1. &&短路與:全都為真才為真,一旦有假全為假,在一個短路與邏輯表達式裡,如果有一個表達式為假,那麼後面的所有的表達式都不參與運算,因為發生了短路,整個表達式的值為假,即false;如果是最後一個表達式是假的,則不發生短路
  2. ||短路或:有真則為真,在一個短路或邏輯表達式中,如果有一個表達式為真,那麼後面的所有表達式都不參與運算,即發生了短路,整個表達式的值為真,即為true;如果是最後一個表達式是真的,則不發生短路

4 說出8大基本資料類型及其包裝類

  1. 數字類型

    整數類型:byte、short、int、long(輸出時需要加L,如100L)

    浮點類型:float(輸出時需要加F,如3.14F)、double(浮點類型預設是double型)

  2. 字元類型:char(本身是一個整型,單輸出的是一個字元,很特殊!!!輸出的對應的是ASCII碼)
  3. 布爾類型:boolean,輸出的結果為true或者是false

    (注):string不是基本類型)

5 請說出==和equals的差別

  1. ==對于基本類型比較的是直接值,對于引用類型比較的是記憶體位址
  2. equals是一個方法,在字元串比較中,是比較的字元串的内容;在對象之間的比較時,根據equals方法中的邏輯的不同,得到不同的結果

== :運算符

  1. 可以使用在基本資料類型變量和引用資料類型變量中
  2. 如果比較的是基本資料類型變量:比較兩個變量儲存的資料是否相等。(不一定類型要相同)

    如果比較的是引用資料類型變量:比較兩個對象的位址值是否相同.即兩個引用是否指向同一個對象實體

    補充: == 符号使用時,必須保證符号左右兩邊的變量類型一緻。

equals()方法的使用:

  1. 是一個方法,而非運算符
  2. 隻能适用于引用資料類型
  3. Object類中equals()的定義:

public boolean equals(Object obj) {

return (this == obj);

}

說明:Object類中定義的equals()和==的作用是相同的:比較兩個對象的位址值是否相同.即兩個引用是否指向同一個對象實體
           
  1. 像String、Date、File、包裝類等都重寫了Object類中的equals()方法。重寫以後,比較的不是

    兩個引用的位址是否相同,而是比較兩個對象的"實體内容"是否相同。

  2. 通常情況下,我們自定義的類如果使用equals()的話,也通常是比較兩個對象的"實體内容"是否相同。那麼,我們

    就需要對Object類中的equals()進行重寫.

    重寫的原則:比較兩個對象的實體内容是否相同.

6 如何定義個數組,定義數組的4個關鍵元素是什麼

定義數組:
①int[] arr = {1,2,3}; //直接指派
②int[] arr = new int[5];//5代表數組長度
③int[] arr = new int[]{};
數組中的4個關鍵元素:數組類型、數組名、數組元素、元素下标
           

7 寫出常見異常

數組下标越界:`ArrayIndexOutOfBoundException` 
空指針異常:`NullPointerException`
處理數字轉換異常:`NumberFormatExcepthion`
           

索引越界異常:

java.lang.IndexOutOfBoundsException

數字格式異常:

java.lang.NumberFormatException

運作時異常:

RuntimeException

8 手寫冒泡排序

//降序從前往後排序
    System.out.print("降序從前往後排序後的數組為:");
    for(int i = 0; i < length - 1; i ++){
    	for(int j = 0; j< length -1 -i; j ++){
    		if(nums1[j] < nums1[j + 1]){
    			int temp = nums1[j];
       		    nums1[j] = nums1[j + 1] ;
       			nums1[j + 1] = temp;
    		}
   		}
   	}
   	System.out.println(Arrays.toString(nums1));
    	
    	//降序從後往前排序
    	System.out.print("降序從後往前排序後的數組為:");
    	for(int i = 0; i < length - 1; i ++){
    		for(int j = length - 1; j < i; j ++){
    			if(nums1[j] > nums1[j - 1]){
    				int temp = nums1[j];
        		    nums1[j] = nums1[j - 1] ;
        			nums1[j - 1] = temp;
    			}
    		}
    	}
    	System.out.println(Arrays.toString(nums1));
    	
    	//升序從前往後排序
    	System.out.print("升序從前往後排序後的數組為:");
    	for(int i = 0; i < length - 1; i ++){
    		for(int j = 0; j< length -1 -i; j ++){
    			if(nums1[j] > nums1[j + 1]){
    				int temp = nums1[j];
        		    nums1[j] = nums1[j + 1] ;
        			nums1[j + 1] = temp;
    			}
    		}
    	}
    	System.out.println(Arrays.toString(nums1));
    	
    	//升序從後往前排序
    	System.out.print("升序從後往前排序後的數組為:");
    	for(int i = 0; i < length - 1; i ++){
    		for(int j = length - 1; j < i; j ++){
    			if(nums1[j] < nums1[j - 1]){
    				int temp = nums1[j];
        		    nums1[j] = nums1[j - 1] ;
        			nums1[j - 1] = temp;
    			}
    		}
    	}
    	System.out.println(Arrays.toString(nums1));	
           

9 jvm記憶體的5個組成部分

堆:存儲被new出來的Java對象執行個體和數組
方法區:它用于存儲已被虛拟機加載的類資訊,常量,靜态變量 
虛拟機棧:虛拟機棧中執行每個方法的時候,則用于存儲局部變量表,操作數棧,動态連結,方法出口等資訊。
本地方法棧:本地方法棧為虛拟機使用的Native方法服務
程式計數器:訓示Java虛拟機下一條需要執行的位元組碼指令。
           

10 簡述一下面向對象你的了解

面向對象包括三大特征:封裝、繼承和多态
           

面向對象也就是說,對重複的東西不用多次定義,隻需調用同類型的類即可。把事物的屬性和行為抽象成一個類,使其屬性私有化,方法(也就是行為)公開化,提高了資料的隐秘性的同時,使代碼子產品化。這樣做使得代碼的複用性更高。

11 成員變量和臨時變量的差別和作用域

  1. 成員變量:定義在類中,方法之外的變量,其存儲在對記憶體的對象中,作用域是整個類
  2. 局部變量:定義在方法中或者{}語句裡面的變量,其存儲在棧記憶體的方法中,作用域是其所在的方法

12 方法的簽名四要素,方法傳回值的限制

簽名四要素:作用域,傳回值,方法名(參數清單)
           

如果方法具有傳回值,方法中必須使用關鍵字return傳回該值,傳回值類型為該值的類型,傳回值隻能有一個,傳回值類型可以是基本類型也可以是對象類型,如果方法沒有傳回值,傳回值類型為void。

13 方法的形參和實參

  1. 形參:在定義方法的時候,在方法的參數清單中寫入的叫形參
  2. 實參:在方法調用的時候,在調用方法的地方傳入的參數叫實參

14 方法參數的值傳遞和引用傳遞

  1. 值傳遞:在基本資料類型中,傳遞的是變量的值,改變一個變量的值不會影響另一個變量的值
  2. 引用傳遞:引用資料類型(類、數組和接口,統稱為引用類型),指派是把原對象位址傳遞給另一個引用,其中任何一個發生改變,都會影響到其他所有的引用

15 什麼是方法的重載

同一個類中,方法名相同,參數清單不同(個數或類型)與傳回值、通路修飾符無關
           

16 什麼是構造方法

構造方法是類的一種特殊方法,用來初始化類的一個新的對象,在建立對象之後自動調用
類中預設就有一個空參構造方法,在構造方法中隻有修飾符和方法名,方法名和類名相同,有無參數清單都行
但是如果有參數清單,則在建立隊形的時候就需要按照順序給出參數對應的值
           

17 this關鍵字和super關鍵字

  1. this關鍵詞主要用于構造方法中,指的是目前被建立的對象,用this關鍵字來調用目前對象的屬性變量。當類中存在成員變量和局部變量同名的時候為了區分,就需要使用this關鍵字。
  2. super關鍵字主要用于代表父類的引用,用于通路父類的屬性、方法和構造器

    通路父類的屬性,不能通路private屬性,在子類中用super.屬性名

    通路父類的方法,不能通路父類的private方法,在子類中用super.方法名(參數清單)

    通路父類的構造器:super(參數清單),隻能放在構造器的第一句

18 簡述java中的選擇結構和循環結構

選擇結構有:if(){}else{}和switch選擇,都用來處理多分支的結構
	if括号裡為真,則執行花括号裡的,如果為假,則執行else後大括号裡的
	Switch選擇,是等值選擇,根據switch括号裡的表達式值去跟case後的值進行比較來進行選擇
循環結構:有while(){}、do{}while()、for循環三個循環
		都包含循環條件,循環體,可用break來跳出整個循環
		用continue來結束目前本次循環,循環變量需要初始化
           

19 什麼是繼承

繼承發生的前提是,某一些類具有一些相同的屬性和方法,我們把這些具有的相同的屬性和方法抽取出來,放在同一個類中,讓這些類通過extends關鍵字繼承這個具有共同屬性和方法的類,得到共有的屬性和方法,這種行為,我們稱之為繼承。

其中繼承隻能繼承public和protected标注的方法和屬性,這樣需要子類和父類在同一個包中,若繼承預設權限修飾符修飾的屬性和方法,子類和父類必須在同一個包中,不能繼承private标注的方法和屬性。當父子類有繼承關系的時候,建立子類對象會自動調用父類的無參構造方法。

20 什麼是封裝

屬性私有化,方法公開化,這樣屬性不會任意被改變,設定不合理的值。
屬性用private來聲明,用公共的get方法擷取屬性,用公共的set方法傳值
不對外暴露的私有的方法、單例模式等等..
           

21 什麼是多态

多态是同一個引用類型,使用不同的執行個體而執行不同的操作。即不同的子類在繼承父類後分别都重寫覆寫了父類的對象,即父類同一個方法,在繼承的子類中表現出不同的形式。
關鍵點:父類引用指向子類對象
	   其中用instanceof來判斷某個對象是否是某個類型
           

多态發生的條件(繼承,重寫,父類引用指向子類對象)

22 什麼是方法的重寫

1.重寫方法的方法名稱、參數清單必須與原方法的相同,傳回類型可以相同也可以是原類型的子類型(從Java SE5開始支援)。
2.重寫方法不能比原方法通路性差(即通路權限不允許縮小)。
3.重寫方法不能比原方法抛出更多的異常。
4.被重寫的方法不能是final類型,因為final修飾的方法是無法重寫的。
5.被重寫的方法不能為private,否則在其子類中隻是新定義了一個方法,并沒有對其進行重寫。
6.被重寫的方法不能為static。如果父類中的方法為靜态的,而子類中的方法不是靜态的,但是兩個方法除了這一點外其他都滿足重寫條件,那麼會發生編譯錯誤;反之亦然。即使父類和子類中的方法都是靜态的,并且滿足重寫條件,但是仍然不會發生重寫,因為靜态方法是在編譯的時候把靜态方法和類的引用類型進行比對。
7.重寫是發生在運作時的,因為編譯期編譯器不知道并且沒辦法确定該去調用哪個方法,JVM會在代碼運作的時候作出決定。
           

23 介紹一下抽象類和抽象方法,與普通類和普通方法的相同和不同

關鍵字abstract
           
  1. 抽象類:public abstract class 類名,和普通方法相比,有相同的屬性和方法,抽象方法不同。
  2. 抽象方法:public abstract void 方法名(Pet pet),抽象方法沒有方法體,抽象方法必須在抽象類中,抽象方法必須在子類中被實作,除非子類是抽象類。普通類繼承抽象類必須實作抽象方法,即重寫抽象方法,抽象類繼承抽象類,可以重寫也可以不重寫。

24 介紹一下接口

接口的關鍵字是interface用于定義一個接口,implements,使用者實作一個接口。
先繼承後實作,順序不能改變。
           

特點:接口不可以被執行個體化,實作類必須實作接口的所有的方法,實作類可以實作多個接口,多個接口用逗号隔開。接口中的變量都是靜态常量,public static final……

25 try catch finally的執行順序,如果catch中出現了return語句,會發生什麼情況

  1. 先執行try的代碼塊,然後執行catch對異常進行捕獲,如果有多個catch塊時,其中的異常類型需要前面的是子類異常後面的是父類異常,然後按順序逐個比對,無論前面有沒有捕獲到異常,都會執行finally。
  2. 如果catch中出現了return語句,會先執行finally然後再去執行catch中的return語句。

26 list和set的差別和聯系

  1. list接口存儲不唯一,有序的對象,也就是可以重複,有序,list隻能存儲對象類型的資料,不能存儲基礎類型資料,可以使用加強for循環
  2. set接口存儲唯一,無序的對象。也就是不能重複,無序,不能使用加強for循環

27 ArrayList和LinkList的差別

1、ArrayList實作了長度可變的數組,在記憶體中配置設定連續的空間,周遊元素和随機通路元素的效率比較高。查詢快、增删慢
2、LinkedList采用連結清單存儲方法,插入、删除元素時效率比較高。增删快,查詢慢
           

28 什麼是序列化和反序列化

1、序列化:将對象某個時間的狀态通過流存儲起來,具體指的是過程不是結果,如果要實作序列化,必須實作Serializable

2、反序列化:反序列化則是從特定的流中擷取資料重新建構對象的過程,意思是,将存儲起來的序列化資訊還原成對象。

29 建立線程的方法有哪些,如何啟動一個線程

1、繼承Thread類并且重寫run(),然後在main方法中,建立線程對象,調用線程對象的

//start方法來啟動一個線程
//建立線程類對象:
MyThread thread2 =new MyThread();
//調用線程對象的start方法:  
a.start( )
           

2、實作Runnable接口,在類中覆寫Runnable接口中的run方法,在main方法中,建立此類的對象然後再建立線程對象,并且以此類對象作為線程對象中的參數傳入進去,也是用線程對象調用start()方法來啟動線程。

//建立MyRunnable對象
MyRunnable thread = new MyRunnable();
//建立目前類對象
Student student = new Student();
//建立線程類對象 
Thread  t  =  new Thread(student );
//調用線程對象的start方法:       
t.start( )  
           

30 說說你關于程序和線程的認識

  1. 程序:應用程式的執行執行個體,每一個程序都有自己的位址空間,即程序是資源配置設定的最小機關。
  2. 線程:CPU排程和分派的基本機關,是作業系統能夠進行運算排程的最小機關,可完成一個獨立的順序控制流程,其中一個程序中可以并發多個線程。

31 什麼是多線程

多線程:如果在一個程序中同時運作了多個線程,用來完成不同的工作,則稱之為“多線程”。多個線程交替占用CPU資源,而非真正的并行執行,線程每次執行時長由配置設定的CPU時間片長度決定。

多線程是為了同步完成多項任務,不是為了提高運作效率,而是為了提高資源使用效率來提高系統的效率。多線程是在同一時間需要完成多項任務的時候實作的。

32 線程運作的5個狀态,簡單論述他們之間的關系

建立狀态:建立線程對象
就緒狀态:啟動線程
運作狀态:搶到了cpu資源
阻塞狀态:沒有搶到cpu資源(join或者sleep)
死亡狀态:程式正常結束或者外部幹涉終止
           

關系:

1、正常情況下是沒有發生意外,建立線程後,進入就緒狀态啟動線程,然後開始搶占CPU資源,搶到了則進行運作狀态,運作結束則進入死亡狀态。

2、另一種情況則是沒有搶到CPU資源或者是程式進入了休眠則進入阻塞狀态,當阻塞狀态解除後,則繼續搶占CPU資源,搶到了就繼續運作,運作結束後則進入死亡狀态。

33 建立對象的三種方式

  1. new關鍵字建立對象
  1. 通過調用類的newInstance方法可以建立對象(反射的方法)
  1. 對象流的方式輸入

34 sleep,yield為什麼是靜态方法

Tread類的sleep()和yield()将在目前正在執行的線程上運作,主要針對目前線程進行操作,在其他處于等待狀态的線程上調用這些方法是沒有意義的。可以在目前正在執行的線程中工作,并且避免我們會錯誤的認為其可以在其他非運作線程調用這些方法。

35 談談對索引的認識

索引主要分為主鍵索引,唯一索引,正常索引,全文索引。建立索引主要是為了加快查詢速度,同時有索引也可以對資料庫進行優化,提高系統的性能。但是不要對經常變動的資料加索引,比如我們人的身份證号是唯一辨別我們的,不會随意變動,是以可以作為索引,此外小資料量的表建議不要加索引。對于一張表中有很多個字段,可以把一張表分為兩張或多張表,通過給各個表加索引來關聯各個表,如果表很多,甚至可以把一個資料庫分為多個資料庫。

36 什麼是事務,事務的acid原則

事務就是一個完整的增删改查的行為,完成的多個增删改查統稱為一個事務

事務的acid原則:

原子性:是指一個事務要麼全部執行,要麼不執行。

一緻性:事務的運作,如果改變了資料庫中的一個資料,那麼其他資料也随之改變。

獨立性:兩個或者多個事務均是獨立執行的,不會交叉執行,彼此互不影響。

持久性:一個事務執行成功以後,對資料庫中的資料的更改所儲存的資料是具有持久性,不會無緣無故復原。

37 如何優化資料庫

優化資料庫主要是通過給資料庫加索引來實作的,給不經常更改的字段添加索引更有助于資料的查詢,此外小資料量的資料表不建議加索引。對于一張表中有很多個字段,可以把一張表分為兩張或多張表,通過給各個表加索引來關聯各個表,如果表很多,甚至可以把一個資料庫分為多個資料庫。這樣分表分庫更有助于資料的查詢。

38 session和cookie的差別

不同點:

cookie可以設定作用域,該作用域向下相容,session作用域是整個伺服器

cookie在浏覽器中使用,session在伺服器中使用

cookie存儲的資訊較少,session存儲的資訊較多

相同點:都可以存儲出資料,都可以确認使用範圍,都可以設定生命周期

39 轉發和重定向的差別

答:轉發的實作通過request.getRequestDispatcher(“login.jsp”).forward(request, response)實作的

重定向的實作是通過response.sendRedirect(“url”),将使用者請求重新定位到一個新的URL,重定向會丢失原來存在request中資料

二者的差別是:轉發URL不會變化,重定向則是湖重新定位到一個新的URL中;轉發則是會攜帶目前發出的請求,不會重新送出請求,而重定向則是丢棄了目前的請求,重新發出一個請求;轉發隻适用本Web應用下,重定向可以适用于任意URL。

40 request和session的相同和不同

答:相同點:都可以存儲屬性

不同點:request中存儲的資料僅在一個請求中可用,session中存儲的資料在一個會話的有效期内可用。

41 servlet的定義

答:servlet是一個架構,是為了解決java程式的通信問題,用java語言寫的一堆程式的集合,servlet提供了很多可以在網絡調用的接口,這些能調用的接口被稱為api,api本質是方法,他可以傳參,可以有傳回值;如果放在網絡上,那麼參數可以在網絡提供,傳回值可以在網絡上獲得,實作網絡通信

42 簡述servlet的生命周期

答:1.加載和執行個體化:當Servlet容器啟動或者容器檢測到用戶端請求時

2.初始化:執行個體化後,容器調用Servlet的init()初始化對象

3.處理請求:得到用戶端請求并做出處理時

4.銷毀:當程式中的Servlet對象不再使用的時候,或者Web伺服器停止運作的時候

43 什麼是單例模式,如何實作單例模式,懶漢模式/餓漢模式

答: 單例模式:系統運作期間,有且僅有一個執行個體,就叫單例模式。其中隻提供私有構造器,定義靜态的該類私有對象,必須自行向整個系統提供這個執行個體,提供一個靜态的公有方法,傳回建立或者擷取本身的靜态私有對象。

懶漢模式:在類加載時不建立執行個體,采用延遲加載的方式,在運作調用時才建立執行個體,類加載的較快,但擷取對象速度較慢。懶漢模式會導緻線程不安全,解決同步安全問題。

餓漢模式:在類加載的時候,就完成初始化,是以類加載的較慢,但擷取對象速度較快。餓漢模式線程安全,不具備延遲加載特性。

44 請介紹mybatis的一級緩存和二級緩存

答:一級緩存:Mybatis對緩存提供支援,但是在沒有配置的預設情況下,它隻開啟一級緩存,一級緩存隻是相對于同一個SqlSession而言。是以在參數和SQL完全一樣的情況下,我們使用同一個SqlSession對象調用一個Mapper方法,往往隻執行一次SQL,因為使用SelSession第一次查詢後,MyBatis會将其放在緩存中,以後再查詢的時候,如果沒有聲明需要重新整理,并且緩存沒有逾時的情況下,SqlSession都會取出目前緩存的資料,而不會再次發送SQL到資料庫。除非sql改變。

二級緩存:當會話被關閉的時候,這個會話對應的一級緩存被清除;但當我們開啟二級緩存的時候,這個緩存會被存入二級緩存中。新的會話查詢資訊,可以從二級緩存中擷取内容。不同的mapper查詢的資料會放在自己對應的mapper中。

45 請介紹mybatis如何設定延遲加載,延遲加載的效果是什麼

答:在config.xml中配置

<settings>
        <setting name="lazyLoadingEnabled" value="true"/>
 </settings>
           

延遲加載的效果:可以不通路某些資料表,盡量減少 SQL 的執行,進而達到提高速度的目的。