看到一篇不錯的java面試題的文章,本身整理一下,做爲備用吧!html
封裝java
最多見的是把屬性私有化封裝在一個類裏面,只能經過方法去訪問面試
繼承數組
子類繼承父類,從而繼承了父類的方法和屬性緩存
抽象安全
好比一個英雄類,抽象出了name,hp這些屬性,使得開發過程當中更加易於理解bash
多態ide
多態分操做符的多態和類的多態。 類的多態指父類引用指向子類對象,而且有繼承,有重寫。工具
String是類類型,不是基本類型。oop
基本類型有八種: 整型 (4種)字符型 (1種)浮點型 (2種)布爾型(1種)
int 是基本類型32位長度的整數,而Integer 是類類型,是int的封裝類
int和Integer之間能夠經過自動裝箱、自動拆箱互相轉換
String是immutable的,其內容一旦建立好以後,就不能夠發生改變。
StringBuffer 是能夠變長的,內容也能夠發生改變 改變的原理是StringBuffer內部採用了字符數組存放數據,在須要增長長度的時候,建立新的數組,而且把原來的數據複製到新的數組這樣的辦法來實現。
運行時異常 又叫作非可查異常,在編譯過程當中,不要求必須進行顯示捕捉
通常異常又叫作可查異常,在編譯過程當中,必須進行處理,要麼捕捉,要麼經過throws 拋出去.是如何實現的。
ArrayList和Vector
二者都繼承了抽象類AbstractList,可是Vector是線程安全的,而ArrayList是非線程安全的
ArrayList和LinkedList的區別
ArrayList 是數組結構,因此定位很快,可是插入和刪除很慢 LinkedList 是雙向鏈表結構,因此插入和刪除很快,可是定位很慢
首先不要說成了一個是單數,一個是複數。。。
Collection是接口,是List和Set的父接口
Collections是工具類,提供了排序,混淆等等不少實用方法
& 有兩個做用,分別是 位與 和 邏輯與,&& 就是邏輯與,做爲邏輯與, & 和 && 分別表示長路與和短路與
長路與 兩側,都會被運算 短路與 只要第一個是false,第二個就不進行運算了
HashMap和Hashtable都實現了Map接口,都是鍵值對保存數據的方式
區別1:
HashMap能夠存放 null Hashtable不能存放null
區別2:
HashMap不是線程安全的類 Hashtable是線程安全的類
final
final修飾類,方法,基本類型變量,引用的時候分別有不一樣的意思 修飾類 表示該類不能被繼承 修飾方法 表示該方法不能被重寫 修飾基本類型變量 表示該變量只能被賦值一次 修飾引用 表示該引用只有一次指向對象的機會
finally
finally 是用於異常處理的場面,不管是否有異常拋出,都會執行
finalize
finalize是Object的方法,全部類都繼承了該方法。 當一個對象知足垃圾回收的條件,而且被回收的時候,其finalize()方法就會被調用
Overload是方法重載的意思,指的是在同一個類裏面,方法名同樣,可是參數不同
Override是方法重寫的意思,指的是子類繼承了父類的某個方法後,從新又寫了一遍
Overloaded的方法是否能夠改變返回值的類型?
能夠,重載其實本質上就是徹底不一樣的方法,只是剛好取了相同的名字
Error和Exception都實現了Throwable接口
Error指的是JVM層面的錯誤,好比內存不足OutOfMemoryError
Exception 指的是代碼邏輯的異常,好比下標越界OutOfIndexException
abstract class 抽象類和interface接口的區別
使用方式:
抽象類只可以經過繼承被使用 接口必須經過實現被使用
實現方法:
抽象類不只能夠提供抽象方法,也能夠提供實現方法 接口只能提供抽象方法,不能提供實現方法。 可是在JAVA8版本開始,接口能夠提供實現方法了,前提是要在方法前加一個default修飾符
heap: 堆
stack: 棧 (在一些書籍裏,會被翻譯爲堆棧,實際上指的就是單純的這個棧)
存放的內容不同:
heap: 是存放對象的 stack: 是存放基本類型(int, float, boolean 等等)、引用(對象地址)、方法調用
存取方式不同:
heap: 是自動增長大小的,因此不須要指定大小,可是存取相對較慢 stack: 是固定大小的,而且是FILO 先入後出的順序,而且存取速度比較快
GC是Garbage Collection的縮寫,即垃圾回收 這裏所謂的垃圾,指的是那些再也不被使用的對象,JVM的垃圾回收機制使得開發人員從無聊、容易犯錯的手動釋放內存資源的過程當中解放出來。 開發人員能夠更加專一的進行業務功能的開發,而資源回收的工做交由更加專業的垃圾回收機制自動完成。
short s1 = 1; //這一句沒有錯誤,編譯器會自動把1這個整數處理爲short.
s1 = s1 + 1; //右側的表達式會返回一個Int類型的整數,再把這個int類型的整數賦給short類型的s1的時候,就會出現強制轉換錯誤
複製代碼
Math.round 的意思是+0.5 取整數
因此 Math.round(11.5) 即 11.5+0.5 = 12
Math.round(-11.5) 即 -11.5+0.5 = -11
複製代碼
String s = new String("xyz");
複製代碼
首先構造方法 new String("xyz"); 中的"xyz" 這自己就是一個字符串對象 而後 new 關鍵字必定會建立一個對象 因此總共建立了兩個String對象
接口是否可繼承接口?
能夠,好比List 就繼承了接口Collection
抽象類是否可實現(implements)接口?
能夠,好比 MouseAdapter鼠標監聽適配器 是一個抽象類,而且實現了MouseListener接口
抽象類是否可繼承實體類(concrete class)?
能夠,全部抽象類,都繼承了Object
List 和 Set 繼承了Collection接口
可是Map和Collection之間沒有繼承關係,由於一個是鍵值對容器,一個是單值容器,沒法兼容
abstract的method是否可同時是static,是否可同時是synchronized?
都不能夠
數組獲取長度的手段是 .length 屬性
String獲取長度的手段是 length()方法
集合獲取長度的手段是 size()方法
文件獲取長度的手段是 length()方法
以HashSet爲例,判斷重複的邏輯是:
首先看hashcode是否相同,若是不一樣,就是不重複的
若是hashcode同樣,再比較equals,若是不一樣,就是不重複的,不然就是重複的。
子類不能繼承父類的構造方法,因此就不存在重寫父類的構造方法。 注: super() 表示子類調用父類的構造方法,這不能被叫作繼承父類的構造方法
String是final修飾的,因此不可以被繼承
switch 能夠做用在 byte,short,int String,Enum(枚舉) 上,可是不能做用在long上面
**注:**switch 做用在String上從JDK1.7開始支持,實質是編譯時將字符串替換爲了其對應的hash值
try裏的return 和 finally裏的return 都會執行,可是當前方法只會採納finally中return的值
由於hashCode()方法和equals()方法均可以經過自定義類重寫,是能夠作到equals相同,可是hashCode不一樣的
可是,在Object類的equals()方法中有這麼一段話
* Note that it is generally necessary to override the {@code hashCode}
* method whenever this method is overridden, so as to maintain the
* general contract for the {@code hashCode} method, which states
* that equal objects must have equal hash codes.
複製代碼
一般來說,在重寫這個方法的時候,也須要對hashCode方法進行重寫,
以此來保證這兩個方法的一致性——
當equals返回true的時候,這兩個對象必定有相同的hashcode.
兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不對?
因此這個題的答案應該是否認的,可是得搞清楚裏面的原委
與C語言開發人員須要手動進行內存資源的釋放不一樣,Java提供垃圾回收機制,自動進行GC,將開發人員從容易犯錯的內存資源管理中解放出來。
原理:當某個一個對象,沒有任何引用指向它的時候,那麼它就知足垃圾回收的條件,在適當的時候,JVM虛擬機進行GC將其回收,釋放空間,以供後續再利用。
兩種常見的回收機制:
定時回收 每隔30分鐘進行一次回收,這種機制的弊端是若是垃圾產生的比較快,有可能30分鐘以內垃圾已經把內存佔用光了,致使性能變慢
當垃圾佔到某個百分比的時候,進行回收 好比,當垃圾佔到70%的時候,進行回收。 這種機制的弊端是,若是垃圾產生的頻率很快,那麼JVM就必須高頻率的進行垃圾回收。 而在垃圾回收的過程當中, JVM會停頓下來,只作垃圾回收,而影響業務功能的正常運行。
通常說來 JVM會採用兩種機制結合的方式進行垃圾回收。
常見的集合
ArrayList,LinkedList,HashSet,HashMap,TreeSet 等等
常見方法:
size()
add()
remove()
等等
複製代碼
char是16位的,佔兩個字節 漢字一般使用GBK或者UNICODE編碼,也是使用兩個字節 因此能夠存放漢字
主要是兩種,SAX和DOM:
SAX 就是逐行讀取,直到找到目標數據爲止
DOM 是先全文檔加載,而後讀取
throws 用在方法聲明上面,表示該方法有可能拋出某個異常
throw 拋出一個指定的異常
try catch 在try中有可能會拋出某個異常,一旦某個異常拋出後,就會在catch中進行捕捉,他倆通常說來都是成對出現的。
finally: 表示不管是否捕捉住異常,都會執行
能夠包括多個類,可是隻能出現一個public修飾的類,可是能夠出現多個非public修飾的類。
Java中全部的流都是基於字節流,因此最基本的流是
輸入輸出字節流
InputStream OutputStream
在字節流的基礎上,封裝了字符流
Reader Writer
進一步,又封裝了緩存流
BufferedReader PrintWriter
以及數據流
DataInputStream DataOutputStream
對象流
ObjectInputStream ObjectOutputStream
以及一些其餘的奇奇怪怪的流 ~~~
由於Java是自動進行垃圾回收管理的,因此不存在 C語言中同等概念的內存泄漏,可是存在Java特點的內存泄漏
當某些對象不被使用,可是又有非直接引用指向的時候,那麼就不知足垃圾回收的條件,而造成內存泄漏。
好比代碼中的例子,每一個Object建立的時候,有一個引用o指向,接着就被放進了集合al中。 下一個Object建立的時候,上一個Object就沒有引用指向了。
這些Object都沒有引用指向,可是卻放在ArrayList中,而這個Arraylist忘記了回收,那麼裏面的全部對象,都會一直存活下去,雖然再也不被使用了。
package exercise;
import java.util.ArrayList;
public class MemoryLeak {
static ArrayList<Object> al = new ArrayList<Object>();
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
Object o = new Object();
al.add(o);
}
}
}
複製代碼
父類(接口)引用指向子類對象
方法有重寫
靜態變量 直接經過類就能夠訪問,無需實例
實例變量 好比經過類的某個具體實例,才能夠訪問
序列化指的是把一個Java對象,經過某種介質進行傳輸,好比Socket輸入輸出流,或者保存在一個文件裏
實現java序列化的手段是讓該類實現接口 Serializable,這個接口是一個標識性接口,沒有任何方法,僅僅用於表示該類能夠序列化。
在外部循環的前一行,加上標籤
在break的時候使用該標籤
即能達到結束多重嵌套循環的效果
public class HelloWorld {
public static void main(String[] args) {
//打印單數
outloop: //outloop這個標示是能夠自定義的好比outloop1,ol2,out5
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println(i+":"+j);
if(0==j%2)
break outloop; //若是是雙數,結束外部循環
}
}
}
}
複製代碼