java常見面試題
1 說說你關于常量的認識
常量是用final修飾的變量,定義的時候就要指派,并且值不能被修改,通常在定義的時候需要大寫,然後多個字母之間用下劃線分割。
2 說說關于++ 和 --的認識
++和–分别是自增和自減運算符,通常放在整型變量前後,運算方向從左往右
m=2 | m的值 | 表達式的值 | 分析 |
---|---|---|---|
m ++ | 3 | 2 | ++在變量的後面,先參與運算,然後在進行自增運算 |
++m | 3 | 3 | ++在變量的前面,先進行自增運算,然後再參與運算 |
m– | 1 | 2 | –在變量的後面,先參與運算,然後再進行自減運算 |
–m | 1 | 1 | –在變量的前面,先進行自減運算,然後再參與運算 |
3 解釋短路的概念
- &&短路與:全都為真才為真,一旦有假全為假,在一個短路與邏輯表達式裡,如果有一個表達式為假,那麼後面的所有的表達式都不參與運算,因為發生了短路,整個表達式的值為假,即false;如果是最後一個表達式是假的,則不發生短路
- ||短路或:有真則為真,在一個短路或邏輯表達式中,如果有一個表達式為真,那麼後面的所有表達式都不參與運算,即發生了短路,整個表達式的值為真,即為true;如果是最後一個表達式是真的,則不發生短路
4 說出8大基本資料類型及其包裝類
-
數字類型
整數類型:byte、short、int、long(輸出時需要加L,如100L)
浮點類型:float(輸出時需要加F,如3.14F)、double(浮點類型預設是double型)
- 字元類型:char(本身是一個整型,單輸出的是一個字元,很特殊!!!輸出的對應的是ASCII碼)
-
布爾類型:boolean,輸出的結果為true或者是false
(注):string不是基本類型)
5 請說出==和equals的差別
- ==對于基本類型比較的是直接值,對于引用類型比較的是記憶體位址
- equals是一個方法,在字元串比較中,是比較的字元串的内容;在對象之間的比較時,根據equals方法中的邏輯的不同,得到不同的結果
== :運算符
- 可以使用在基本資料類型變量和引用資料類型變量中
-
如果比較的是基本資料類型變量:比較兩個變量儲存的資料是否相等。(不一定類型要相同)
如果比較的是引用資料類型變量:比較兩個對象的位址值是否相同.即兩個引用是否指向同一個對象實體
補充: == 符号使用時,必須保證符号左右兩邊的變量類型一緻。
equals()方法的使用:
- 是一個方法,而非運算符
- 隻能适用于引用資料類型
- Object類中equals()的定義:
public boolean equals(Object obj) {
return (this == obj);
}
說明:Object類中定義的equals()和==的作用是相同的:比較兩個對象的位址值是否相同.即兩個引用是否指向同一個對象實體
-
像String、Date、File、包裝類等都重寫了Object類中的equals()方法。重寫以後,比較的不是
兩個引用的位址是否相同,而是比較兩個對象的"實體内容"是否相同。
-
通常情況下,我們自定義的類如果使用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 成員變量和臨時變量的差別和作用域
- 成員變量:定義在類中,方法之外的變量,其存儲在對記憶體的對象中,作用域是整個類
- 局部變量:定義在方法中或者{}語句裡面的變量,其存儲在棧記憶體的方法中,作用域是其所在的方法
12 方法的簽名四要素,方法傳回值的限制
簽名四要素:作用域,傳回值,方法名(參數清單)
如果方法具有傳回值,方法中必須使用關鍵字return傳回該值,傳回值類型為該值的類型,傳回值隻能有一個,傳回值類型可以是基本類型也可以是對象類型,如果方法沒有傳回值,傳回值類型為void。
13 方法的形參和實參
- 形參:在定義方法的時候,在方法的參數清單中寫入的叫形參
- 實參:在方法調用的時候,在調用方法的地方傳入的參數叫實參
14 方法參數的值傳遞和引用傳遞
- 值傳遞:在基本資料類型中,傳遞的是變量的值,改變一個變量的值不會影響另一個變量的值
- 引用傳遞:引用資料類型(類、數組和接口,統稱為引用類型),指派是把原對象位址傳遞給另一個引用,其中任何一個發生改變,都會影響到其他所有的引用
15 什麼是方法的重載
同一個類中,方法名相同,參數清單不同(個數或類型)與傳回值、通路修飾符無關
16 什麼是構造方法
構造方法是類的一種特殊方法,用來初始化類的一個新的對象,在建立對象之後自動調用
類中預設就有一個空參構造方法,在構造方法中隻有修飾符和方法名,方法名和類名相同,有無參數清單都行
但是如果有參數清單,則在建立隊形的時候就需要按照順序給出參數對應的值
17 this關鍵字和super關鍵字
- this關鍵詞主要用于構造方法中,指的是目前被建立的對象,用this關鍵字來調用目前對象的屬性變量。當類中存在成員變量和局部變量同名的時候為了區分,就需要使用this關鍵字。
-
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
- 抽象類:public abstract class 類名,和普通方法相比,有相同的屬性和方法,抽象方法不同。
- 抽象方法:public abstract void 方法名(Pet pet),抽象方法沒有方法體,抽象方法必須在抽象類中,抽象方法必須在子類中被實作,除非子類是抽象類。普通類繼承抽象類必須實作抽象方法,即重寫抽象方法,抽象類繼承抽象類,可以重寫也可以不重寫。
24 介紹一下接口
接口的關鍵字是interface用于定義一個接口,implements,使用者實作一個接口。
先繼承後實作,順序不能改變。
特點:接口不可以被執行個體化,實作類必須實作接口的所有的方法,實作類可以實作多個接口,多個接口用逗号隔開。接口中的變量都是靜态常量,public static final……
25 try catch finally的執行順序,如果catch中出現了return語句,會發生什麼情況
- 先執行try的代碼塊,然後執行catch對異常進行捕獲,如果有多個catch塊時,其中的異常類型需要前面的是子類異常後面的是父類異常,然後按順序逐個比對,無論前面有沒有捕獲到異常,都會執行finally。
- 如果catch中出現了return語句,會先執行finally然後再去執行catch中的return語句。
26 list和set的差別和聯系
- list接口存儲不唯一,有序的對象,也就是可以重複,有序,list隻能存儲對象類型的資料,不能存儲基礎類型資料,可以使用加強for循環
- 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 說說你關于程序和線程的認識
- 程序:應用程式的執行執行個體,每一個程序都有自己的位址空間,即程序是資源配置設定的最小機關。
- 線程:CPU排程和分派的基本機關,是作業系統能夠進行運算排程的最小機關,可完成一個獨立的順序控制流程,其中一個程序中可以并發多個線程。
31 什麼是多線程
多線程:如果在一個程序中同時運作了多個線程,用來完成不同的工作,則稱之為“多線程”。多個線程交替占用CPU資源,而非真正的并行執行,線程每次執行時長由配置設定的CPU時間片長度決定。
多線程是為了同步完成多項任務,不是為了提高運作效率,而是為了提高資源使用效率來提高系統的效率。多線程是在同一時間需要完成多項任務的時候實作的。
32 線程運作的5個狀态,簡單論述他們之間的關系
建立狀态:建立線程對象
就緒狀态:啟動線程
運作狀态:搶到了cpu資源
阻塞狀态:沒有搶到cpu資源(join或者sleep)
死亡狀态:程式正常結束或者外部幹涉終止
關系:
1、正常情況下是沒有發生意外,建立線程後,進入就緒狀态啟動線程,然後開始搶占CPU資源,搶到了則進行運作狀态,運作結束則進入死亡狀态。
2、另一種情況則是沒有搶到CPU資源或者是程式進入了休眠則進入阻塞狀态,當阻塞狀态解除後,則繼續搶占CPU資源,搶到了就繼續運作,運作結束後則進入死亡狀态。
33 建立對象的三種方式
- new關鍵字建立對象
- 通過調用類的newInstance方法可以建立對象(反射的方法)
- 對象流的方式輸入
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 的執行,進而達到提高速度的目的。