1、 Java語言有哪些特點
(1)簡單易學、有豐富的類別庫
(2)面向物件(Java最重要的特性,讓程式耦合度更低,內聚性更高)
(3)與平臺無關性(JVM是Java跨平臺使用的根本)
(4)可靠安全
(5)支持多執行緒
2、面向物件和面向程序的區別
面向程序:是分析解決問題的步驟,然后用函式把這些步驟一步一步地實作,然后在使用的時候一一呼叫則可,性能較高,所以單片機、嵌入式開發等一般采用面向程序開發
面向物件:是把構成問題的事務分解成各個物件,而建立物件的目的也不是為了完成一個個步驟,而是為了描述某個事物在解決整個問題的程序中所發生的行為,面向物件有封裝、繼承、多型的特性,所以易維護、易復用、易擴展,可以設計出低耦合的系統,但是性能上來說,比面向程序要低,
3 、八種基本資料型別的大小,以及他們的封裝類基本型別 大小(位元組) 默認值 封裝類
注:

1.int是基本資料型別,Integer是int的封裝類,是參考型別,int默認值是0,而Integer默認值是null,所以Integer能區分出0和null的情況,一旦java看到null,就知道這個參考還沒有指向某個物件,
2.基本資料型別在宣告時系統會自動給它分配空間,而參考型別宣告時只是分配了參考空間,必須通過實體化開辟資料空間之后才可以賦值,陣列物件也是一個參考物件,將一個陣列賦值給另一個陣列時只是復制了一個參考,所以通過某一個陣列所做的修改在另一個陣列中也看的見,
雖然定義了boolean這種資料型別,但是只對它提供了非常有限的支持,在Java虛擬機中沒有任何供boolean值專用的位元組碼指令,Java語言運算式所操作的boolean值,在編譯之后都使用Java虛擬機中的int資料型別來代替,而boolean陣列將會被編碼成Java虛擬機的byte陣列,每個元素boolean元素占8位,這樣我們可以得出boolean型別占了單獨使用是4個位元組,在陣列中又是1個位元組,使用int的原因是,對于當下32位的處理器(CPU)來說,一次處理資料是32位(這里不是指的是32/64位系統,而是指CPU硬體層面),具有高效存取的特點,
4、識別符號的命名規則,
識別符號的含義:
是指在程式中,我們自己定義的內容,譬如,類的名字,方法名稱以及變數名稱等等,都是識別符號,
命名規則:(硬性要求)
識別符號可以包含英文字母,0-9的數字,$以及_
識別符號不能以數字開頭
識別符號不是關鍵字
命名規范:(非硬性要求)
類名規范:首字符大寫,后面每個單詞首字母大寫(大駝峰式),
變數名規范:首字母小寫,后面每個單詞首字母大寫(小駝峰式),
方法名規范:同變數名,
5、instanceof 關鍵字的作用
instanceof 嚴格來說是Java中的一個雙目運算子,用來測驗一個物件是否為一個類的實體,用法為:
Boolean result = obj instanceof Class
其中 obj 為一個物件,Class 表示一個類或者一個介面,當 obj 為 Class 的物件,或者是其直接或間接子類,或者是其介面的實作類,結果result 都回傳 true,否則回傳false,
注意:編譯器會檢查 obj 是否能轉換成右邊的class型別,如果不能轉換則直接報錯,如果不能確定型別,則通過編譯,具體看運行時定,
int i = 0;
System.out.println(i instanceof Integer);//編譯不通過 i必須是參考型別,不能是基本型別
System.out.println(i instanceof Object);//編譯不通過
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
//false ,在 JavaSE規范 中對 instanceof 運算子的規定就是:如果 obj 為 null,那么將回傳
false,
6、Java自動裝箱與拆箱
裝箱就是自動將基本資料型別轉換為包裝器型別(int-->Integer);呼叫方法:Integer的valueOf(int) 方法
拆箱就是自動將包裝器型別轉換為基本資料型別(Integer-->int),呼叫方法:Integer的intValue方法
在Java SE5之前,如果要生成一個數值為10的Integer物件,必須這樣進行:
Integer i = new Integer(10);
而在從Java SE5開始就提供了自動裝箱的特性,如果要生成一個數值為10的Integer物件,只需要這
樣就可以了:
Integer i = 10;
7、 多載和重寫的區別
重寫(Override)
從字面上看,重寫就是 重新寫一遍的意思,其實就是在子類中把父類本身有的方法重新寫一遍,子類繼承了父類原有的方法,但有時子類并不想原封不動的繼承父類中的某個方法,所以在方法名,引數串列,回傳型別(除過子類中方法的回傳值是父類中方法回傳值的子類時)都相同的情況下, 對方法體進行修改或重寫,這就是重寫,但要注意子類函式的訪問修飾權限不能少于父類的,
public class Father {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
s.sayHello();
}
public void sayHello() {
System.out.println("Hello");
}
}
class Son extends Father{
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("hello by ");
}
}
重寫 總結:
(1)發生在父類與子類之間
(2)方法名,引數串列,回傳型別(除過子類中方法的回傳型別是父類中回傳型別的子類)必須相同
(3)訪問修飾符的限制一定要大于被重寫方法的訪問修飾符(public>protected>default>private)
(4)重寫方法一定不能拋出新的檢查例外或者比被重寫方法申明更加寬泛的檢查型例外
多載(Overload)
在一個類中,同名的方法如果有不同的引數串列(引數型別不同、引數個數不同甚至是引數順序不同)
則視為多載,同時,多載對回傳型別沒有要求,可以相同也可以不同,但不能通過回傳型別是否相同來
判斷多載,
public static void main(String[] args) {
// TODO Auto-generated method stub
Father s = new Father();
s.sayHello();
s.sayHello("wintershii");
}
public void sayHello() {
System.out.println("Hello");
}
public void sayHello(String name) {
System.out.println("Hello" + " " + name);
}
}
多載 總結:
(1)多載Overload是一個類中多型性的一種表現
(2)多載要求同名方法的引數串列不同(引數型別,引數個數甚至是引數順序)
(3)多載的時候,回傳值型別可以相同也可以不相同,無法以回傳型別作為多載函式的區分標準
8、 equals與==的區別
== :
== 比較的是變數(堆疊)記憶體中存放的物件的(堆)記憶體地址,用來判斷兩個物件的地址是否相同,即是否是指相同一個物件,比較的是真正意義上的指標操作,
(1)比較的是運算子兩端的運算元是否是同一個物件,
(2)兩邊的運算元必須是同一型別的(可以是父子類之間)才能編譯通過,
(3)比較的是地址,如果是具體的阿拉伯數字的比較,值相等則為true,如:
int a=10 與 long b=10L 與 double c=10.0都是相同的(為true),因為他們都指向地址為10的堆,
equals:
equals用來比較的是兩個物件的內容是否相等,由于所有的類都是繼承自java.lang.Object類的,所以適用于所有物件,如果沒有對該方法進行覆寫的話,呼叫的仍然是Object類中的方法,而Object中的equals方法回傳的卻是==的判斷,
總結:
所有比較是否相等時,都是用equals 并且在對常量相比較時,把常量寫在前面,因為使用object的equals object可能為null 則空指標在阿里的代碼規范中只使用equals ,阿里插件默認會識別,并可以快速修改,推薦安裝阿里插件來排查老代碼使用“==”,替換成equals
![
9、 Hashcode的作用
java的集合有兩類,一類是List,還有一類是Set,前者有序可重復,后者無序不重復,當我們在set中插入的時候怎么判斷是否已經存在該元素呢,可以通過equals方法,但是如果元素太多,用這樣的方法就會比較滿,
于是有人發明了哈希演算法來提高集合中查找元素的效率,這種方式將集合分成若干個存盤區域,每個物件可以計算出一個哈希碼,可以將哈希碼分組,每組分別對應某個存盤區域,根據一個物件的哈希碼就可以確定該物件應該存盤的那個區域,
hashCode方法可以這樣理解:它回傳的就是根據物件的記憶體地址換算出的一個值,這樣一來,當集合要添加新的元素時,先呼叫這個元素的hashCode方法,就一下子能定位到它應該放置的物理位置上,如果這個位置上沒有元素,它就可以直接存盤在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,就呼叫它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址,這樣一來實際呼叫equals方法的次數就大大降低了,幾乎只需要一兩次,
10、String、String StringBu?er 和 StringBuilder 的區別是什么?
String是只讀字串,它并不是基本資料型別,而是一個物件,從底層原始碼來看是一個?nal型別的字符陣列,所參考的字串不能被改變,一經定義,無法再增刪改,每次對String的操作都會生成新的String物件,
private final char value[];
每次+操作 :隱式在堆上new了一個跟原字串相同的StringBuilder物件,再呼叫append方法 拼接+后面的字符,
StringBu?er和StringBuilder他們兩都繼承了AbstractStringBuilder抽象類,從AbstractStringBuilder抽象類中我們可以看到
/**
* The value is used for character storage.
*/
char[] value;
他們的底層都是可變的字符陣列,所以在進行頻繁的字串操作時,建議使用StringBu?er和StringBuilder來進行操作,另外StringBu?er 對方法加了同步鎖或者對呼叫的方法加了同步鎖,所以是執行緒安全的,StringBuilder 并沒有對方法進行加同步鎖,所以是非執行緒安全的,
11、ArrayList和linkedList的區別
Array(陣列)是基于索引(index)的資料結構,它使用索引在陣列中搜索和讀取資料是很快的,
Array獲取資料的時間復雜度是O(1),但是要洗掉資料卻是開銷很大,因為這需要重排陣列中的所有資料,(因為洗掉資料以后, 需要把后面所有的資料前移)
缺點: 陣列初始化必須指定初始化的長度, 否則報錯
例如:
int[] a = new int[4];
//推介使用int[] 這種方式初始化
int c[] = {23,43,56,78};
//長度:4,索引范圍:[0,3]
List—是一個有序的集合,可以包含重復的元素,提供了按索引訪問的方式,它繼承Collection,
List有兩個重要的實作類:ArrayList和LinkedList
ArrayList: 可以看作是能夠自動增長容量的陣列
ArrayList的toArray方法回傳一個陣列
ArrayList的asList方法回傳一個串列
ArrayList底層的實作是Array, 陣列擴容實作
LinkList是一個雙鏈表,在添加和洗掉元素時具有比ArrayList更好的性能.但在get與set方面弱于
ArrayList.當然,這些對比都是指資料量很大或者操作很頻繁,
12、 HashMap和HashTable的區別
(1)兩者父類不同
HashMap是繼承自AbstractMap類,而Hashtable是繼承自Dictionary類,不過它們都實作了同時實作了map、Cloneable(可復制)、Serializable(可序列化)這三個介面,
(2)對外提供的介面不同
Hashtable比HashMap多提供了elments() 和contains() 兩個方法,
elments() 方法繼承自Hashtable的父類Dictionnary,elements() 方法用于回傳此Hashtable中的value的列舉,
contains()方法判斷該Hashtable是否包含傳入的value,它的作用與containsValue()一致,事實上,contansValue() 就只是呼叫了一下contains() 方法,
(3)對null的支持不同
Hashtable:key和value都不能為null,
HashMap:key可以為null,但是這樣的key只能有一個,因為必須保證key的唯一性;可以有多個key值對應的value為null,
(4)安全性不同
HashMap是執行緒不安全的,在多執行緒并發的環境下,可能會產生死鎖等問題,因此需要開發人員自己處理多執行緒的安全問題,
Hashtable是執行緒安全的,它的每個方法上都有synchronized 關鍵字,因此可直接用于多執行緒中,雖然HashMap是執行緒不安全的,但是它的效率遠遠高于Hashtable,這樣設計是合理的,因為大部分的使用場景都是單執行緒,當需要多執行緒操作的時候可以使用執行緒安全的ConcurrentHashMap,
ConcurrentHashMap雖然也是執行緒安全的,但是它的效率比Hashtable要高好多倍,因為
ConcurrentHashMap使用了分段鎖,并不對整個資料進行鎖定,
(5)計算hash值的方法不同
13、 Collection包結構,與Collections的區別
Collection是集合類的上級介面,子介面有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;Collections是集合類的一個幫助類, 它包含有各種有關集合操作的靜態多型方法,用于實作對各種集合的搜索、排序、執行緒安全化等操作,此類不能實體化,就像一個工具類,服務于Java的Collection框架,
14、 Java的四種參考,強弱軟虛
強參考
強參考是平常中使用最多的參考,強參考在程式記憶體不足(OOM)的時候也不會被回收,使用方式:
String str = new String("str");
軟參考
軟參考在程式記憶體不足時,會被回收,使用方式:
// 注意:wrf這個參考也是強參考,它是指向SoftReference這個物件的,
// 這里的軟參考指的是指向new String("str")的參考,也就是SoftReference類中T
SoftReference<String> wrf = new SoftReference<String>(new String("str"));
可用場景:創建快取的時候,創建的物件放進快取中,當記憶體不足時,JVM就會回收早先創建的物件,
弱參考
弱參考就是只要JVM垃圾回收器發現了它,就會將之回收,使用方式:
WeakReference<String> wrf = new WeakReference<String>(str);
可用場景:Java原始碼中的 java.util.WeakHashMap中的 key就是使用弱參考,我的理解就是,一旦我不需要某個參考,JVM會自動幫我處理它,這樣我就不需要做其它操作,
虛參考
虛參考的回識訓制跟弱參考差不多,但是它被回收之前,會被放入 ReferenceQueue中,注意哦,其它參考是被JVM回收后才被傳入 ReferenceQueue中的,由于這個機制,所以虛參考大多被用于參考銷毀前的處理作業,還有就是,虛參考創建的時候,必須帶有 ReferenceQueue,使用
例子:
PhantomReference<String> prf = new PhantomReference<String>(new
String("str"), new ReferenceQueue<>());
可用場景:物件銷毀前的一些操作,比如順澩釋放等,** Object.finalize()雖然也可以做這類動作,但是這個方式即不安全又低效
15、 泛型常用特點 (待補充)
泛型是Java SE 1.5之后的特性, 《Java 核心技術》中對泛型的定義是:
“泛型” 意味著撰寫的代碼可以被不同型別的物件所重用,
“泛型”,顧名思義,“泛指的型別”,我們提供了泛指的概念,但具體執行的時候卻可以有具體的規則來約束,比如我們用的非常多的ArrayList就是個泛型類,ArrayList作為集合可以存放各種元素,如Integer, String,自定義的各種型別等,但在我們使用的時候通過具體的規則來約束,如我們可以約束集合中只存放Integer型別的元素,如
List<Integer> iniData = https://www.cnblogs.com/MonsterJ/p/new ArrayList<>()
使用泛型的好處?
以集合來舉例,使用泛型的好處是我們不必因為添加元素型別的不同而定義不同型別的集合,如整型集合類,浮點型集合類,字串集合類,我們可以定義一個集合來存放整型、浮點型,字串型資料,而這并不是最重要的,因為我們只要把底層存盤設定了Object即可,添加的資料全部都可向上轉型為Object,更重要的是我們可以通過規則按照自己的想法控制存盤的資料型別,
16、Java創建物件有幾種方式?
java中提供了以下四種創建物件的方式:
(1)new創建新物件
(2)通過反射機制
(3)采用clone機制
(4)通過序列化機制
17、有沒有可能兩個不相等的物件有相同的hashcode
有可能.在產生hash沖突時,兩個不相等的物件就會有相同的 hashcode 值.當hash沖突產生時,一般有以下幾種方式來處理:
(1)拉鏈法:每個哈希表節點都有一個next指標,多個哈希表節點可以用next指標構成一個單向鏈表,被分配到同一個索引上的多個節點可以用這個單向鏈表進行存盤.
(2)開放定址法:一旦發生了沖突,就去尋找下一個空的散列地址,只要散串列足夠大,空的散列地址總能找到,并將記錄存入
(3)再哈希:又叫雙哈希法,有多個不同的Hash函式.當發生沖突時,使用第二個,第三個….等哈希函式計算地址,直到無沖突.
18、深拷貝和淺拷貝的區別是什么?
淺拷貝:被復制物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的參考仍然指向原來的物件.換言之,淺拷貝僅僅復制所考慮的物件,而不復制它所參考的物件.
深拷貝:被復制物件的所有變數都含有與原來的物件相同的值.而那些參考其他物件的變數將指向被復制過的新物件.而不再是原有的那些被參考的物件.換言之.深拷貝把要復制的物件所參考的物件都
19、?nal有哪些用法?
?nal也是很多面試喜歡問的地方,但我覺得這個問題很無聊,通常能回答下以下5點就不錯了:
(1)被?nal修飾的類不可以被繼承
(2)被?nal修飾的方法不可以被重寫
(3)被?nal修飾的變數不可以被改變.如果修飾參考,那么表示參考不可變,參考指向的內容可變.
(4)被?nal修飾的方法,JVM會嘗試將其行內,以提高運行效率
(5)被?nal修飾的常量,在編譯階段會存入常量池中.
除此之外,編譯器對?nal域要遵守的兩個重排序規則更好:
在建構式內對一個?nal域的寫入,與隨后把這個被構造物件的參考賦值給一個參考變數,這兩個操作之間不能重排序
初次讀一個包含?nal域的物件的參考,與隨后初次讀這個?nal域,這兩個操作之間不能重排序.
20、static都有哪些用法?
所有的人都知道static關鍵字這兩個基本的用法:靜態變數和靜態方法.也就是被static所修飾的變數/方法都屬于類的靜態資源,類實體所共享.
除了靜態變數和靜態方法之外,static也用于靜態塊,多用于初始化操作:
public calss PreCache{
static{
//執行相關操作
}
}
此外static也多用于修飾內部類,此時稱之為靜態內部類.
最后一種用法就是靜態導包,即 import static.import static是在JDK 1.5之后引入的新特性,可以用來指定匯入某個類中的靜態資源,并且不需要使用類名,可以直接使用資源名,比如:
import static java.lang.Math.*;
public class Test{
public static void main(String[] args){
//System.out.println(Math.sin(20));傳統做法
System.out.println(sin(20));
}
}
21、3*0.1 0.3回傳值是什么
false,因為有些浮點數不能完全精確的表示出來.
22、a=a+b與a+=b有什么區別嗎?
運算子會進行隱式自動型別轉換,此處a+=b隱式的將加操作的結果型別強制轉換為持有結果的型別,
byte a = 127;
byte b = 127;
b = a + b;
// 報編譯錯誤:cannot convert from int to byte
b += a;
以下代碼是否有錯,有的話怎么改?
short s1= 1;
s1 = s1 + 1;
有錯誤.short型別在進行運算時會自動提升為int型別,也就是說 s1+1的運算結果是int型別,而s1是short型別,此時編譯器會報錯.
正確寫法:
short s1= 1;
s1 += 1;
+=運算子會對右邊的運算式結果強轉匹配左邊的資料型別,所以沒錯.
23、try catch ?nally,try里有return,?nally還執行么?
執行,并且?nally的執行早于try里面的return
結論:
(1)不管有木有出現例外,?nally塊中代碼都會執行;
(2)當try和catch中有return時,?nally仍然會執行;
(3)?nally是在return后面的運算式運算后執行的(此時并沒有回傳運算后的值,而是先把要回傳的值保存起來,管?nally中的代碼怎么樣,回傳的值都不會改變,任然是之前保存的值),所以函式回傳值是在?nally執行前確定的;
(4)?nally中最好不要包含return,否則程式會提前退出,回傳值不是try或catch中保存的回傳值,
24、 Excption與Error包結構
Java可拋出(Throwable)的結構分為三種型別:被檢查的例外(CheckedException),運行時例外(RuntimeException),錯誤(Error),
運行時例外
定義:RuntimeException及其子類都被稱為運行時例外,
特點:Java編譯器不會檢查它,也就是說,當程式中可能出現這類例外時,倘若既"沒有通過throws宣告拋出它",也"沒有用try-catch陳述句捕獲它",還是會編譯通過,例如,除數為零時產生的
ArithmeticException例外,陣列越界時產生的IndexOutOfBoundsException例外,fail-fast機制產生的ConcurrentModi?cationException例外(java.util包下面的所有的集合類都是快速失敗的,“快速失敗”也就是fail-fast,它是Java集合的一種錯誤檢測機制,當多個執行緒對集合進行結構上的改變的操作時,有可能會產生fail-fast機制,記住是有可能,而不是一定,例如:假設存在兩個執行緒(執行緒1、執行緒2),執行緒1通過Iterator在遍歷集合A中的元素,在某個時候執行緒2修改了集合A的結構(是結構上面的
ConcurrentModi?cationException 例外,從而產生fail-fast機制,這個錯叫并發修改例外,Fail-safe,java.util.concurrent包下面的所有的類都是安全失敗的,在遍歷程序中,如果已經遍歷的陣列上的內容變化了,迭代器不會拋出ConcurrentModi?cationException例外,如果未遍歷的陣列上的內容發生了變化,則有可能反映到迭代程序中,這就是ConcurrentHashMap迭代器弱一致的表現,ConcurrentHashMap的弱一致性主要是為了提升效率,是一致性與效率之間的一種權衡,要成為強一致性,就得到處使用鎖,甚至是全域鎖,這就與Hashtable和同步的HashMap一樣了,)等,都屬于運行時例外,
常見的五種運行時例外:
(1)ClassCastException(類轉換例外)
(2)IndexOutOfBoundsException(陣列越界)
(3)NullPointerException(空指標例外)
(4)ArrayStoreException(資料存盤例外,操作陣列是型別不一致)
(5)Bu?erOver?owException
被檢查例外
定義:Exception類本身,以及Exception的子類中除了"運行時例外"之外的其它子類都屬于被檢查例外,
特點 : Java編譯器會檢查它,此類例外,要么通過throws進行宣告拋出,要么通過try-catch進行捕獲處理,否則不能通過編譯,例如,CloneNotSupportedException就屬于被檢查例外,當通過clone()介面去克隆一個物件,而該物件對應的類沒有實作Cloneable介面,就會拋出CloneNotSupportedException例外,被檢查例外通常都是可以恢復的,
如:
IOException
FileNotFoundException
SQLException
被檢查的例外適用于那些不是因程式引起的錯誤情況,比如:讀取檔案時檔案不存在引發的
FileNotFoundException ,然而,不被檢查的例外通常都是由于糟糕的編程引起的,比如:在物件引
用時沒有確保物件非空而引起的 NullPointerException ,
錯誤
定義 : Error類及其子類,
特點 : 和運行時例外一樣,編譯器也不會對錯誤進行檢查,
當資源不足、約束失敗、或是其它程式無法繼續運行的條件發生時,就產生錯誤,程式本身無法修復這些錯誤的,例如,VirtualMachineError就屬于錯誤,出現這種錯誤會導致程式終止運行,OutOfMemoryError、ThreadDeath,
Java虛擬機規范規定JVM的記憶體分為了好幾塊,比如堆,堆疊,程式計數器,方法區等
25、OOM你遇到過哪些情況,SOF你遇到過哪些情況
OOM:
(1)OutOfMemoryError例外
Java Heap 溢位:
一般的例外資訊:java.lang.OutOfMemoryError:Java heap spacess,
java堆用于存盤物件實例,我們只要不斷的創建物件,并且保證GC Roots到物件之間有可達路徑來避免垃圾回識訓制清除這些物件,就會在物件數量達到最大堆容量限制后產生記憶體溢位例外,
出現這種例外,一般手段是先通過記憶體映像分析工具(如Eclipse Memory Analyzer)對dump出來的堆轉存快照進行分析,重點是確認記憶體中的物件是否是必要的,先分清是因為記憶體泄漏(Memory Leak)還是記憶體溢位(Memory Over?ow),
如果是記憶體泄漏,可進一步通過工具查看泄漏物件到GCRoots的參考鏈,于是就能找到泄漏物件是通過怎樣的路徑與GC Roots相關聯并導致垃圾收集器無法自動回收,
如果不存在泄漏,那就應該檢查虛擬機的引數(-Xmx與-Xms)的設定是否適當,
(2)虛擬機堆疊和本地方法堆疊溢位
如果執行緒請求的堆疊深度大于虛擬機所允許的最大深度,將拋出StackOver?owError例外,
如果虛擬機在擴展堆疊時無法申請到足夠的記憶體空間,則拋出OutOfMemoryError例外
這里需要注意當堆疊的大小越大可分配的執行緒數就越少,
(3)運行時常量池溢位
例外資訊:java.lang.OutOfMemoryError:PermGenspace
如果要向運行時常量池中添加內容,最簡單的做法就是使用String.intern()這個Native方法,該方法的作用是:如果池中已經包含一個等于此String的字串,則回傳代表池中這個字串的String物件;否則,將此String物件包含的字串添加到常量池中,并且回傳此String物件的參考,由于常量池分配在方法區內,我們可以通過-XX:PermSize和-XX:MaxPermSize限制方法區的大小,從而間接限制其中常量池的容量,
(4)方法區溢位
方法區用于存放Class的相關資訊,如類名、訪問修飾符、常量池、欄位描述、方法描述等,也有可能是方法區中保存的class物件沒有被及時回收掉或者class資訊占用的記憶體超過了我們配置,
例外資訊:java.lang.OutOfMemoryError:PermGenspace
方法區溢位也是一種常見的記憶體溢位例外,一個類如果要被垃圾收集器回收,判定條件是很苛刻的,在經常動態生成大量Class的應用中,要特別注意這點,
SOF(堆疊溢位StackOver?ow):
StackOver?owError 的定義:當應用程式遞回太深而發生堆疊溢位時,拋出該錯誤,
因為堆疊一般默認為1-2m,一旦出現死回圈或者是大量的遞回呼叫,在不斷的壓堆疊程序中,造成堆疊容量超過1m而導致溢位,
堆疊溢位的原因:遞回呼叫,大量回圈或死回圈,全域變數是否過多,陣列、List、map資料過大,
26、 簡述執行緒、程式、行程的基本概念,以及他們之間關系是什么?
執行緒與行程相似,但執行緒是一個比行程更小的執行單位,一個行程在其執行的程序中可以產生多個執行緒,與行程不同的是同類的多個執行緒共享同一塊記憶體空間和一組系統資源,所以系統在產生一個執行緒,或是在各個執行緒之間作切換作業時,負擔要比行程小得多,也正因為如此,執行緒也被稱為輕量級行程,程式是含有指令和資料的檔案,被存盤在磁盤或其他的資料存盤設備中,也就是說程式是靜態的代碼,
行程是程式的一次執行程序,是系統運行程式的基本單位,因此行程是動態的,系統運行一個程式即是一個行程從創建,運行到消亡的程序,簡單來說,一個行程就是一個執行中的程式,它在計算機中一個指令接著一個指令地執行著,同時,每個行程還占有某些系統資源如 CPU 時間,記憶體空間,檔案,輸入輸出設備的使用權等等,換句話說,當程式在執行時,將會被作業系統載入記憶體中,執行緒是行程劃分成的更小的運行單位,執行緒和行程最大的不同在于基本上各行程是獨立的,而各執行緒則不一定,因為同一行程中的執行緒極有可能會相互影響,從另一角度來說,行程屬于作業系統的范疇,主要是同一段時間內,可以同時執行一個以上的程式,而執行緒則是在同一程式內幾乎同時執行一個以上的程式段,
27、執行緒有哪些基本狀態?(補充)
Java 執行緒在運行的生命周期中的指定時刻只可能處于下面 6 種不同狀態的其中一個狀態(圖源《Java并發編程藝術》4.1.4 節),
28、Java 序列化中如果有些欄位不想進行序列化,怎么辦?
對于不想進行序列化的變數,使用 transient 關鍵字修飾,
transient 關鍵字的作用是:阻止實體中那些用此關鍵字修飾的的變數序列化;當物件被反序列化時,被 transient 修飾的變數值不會被持久化和恢復,transient 只能修飾變數,不能修飾類和方法,
29、Java 中 IO 流
Java 中 IO 流分為幾種?
(1)按照流的流向分,可以分為輸入流和輸出流;
(2)按照操作單元劃分,可以劃分為位元組流和字符流;
(3)按照流的角色劃分為節點流和處理流,
Java Io 流共涉及 40 多個類,這些類看上去很雜亂,但實際上很有規則,而且彼此之間存在非常緊密的聯系, Java I0 流的 40 多個類都是從如下 4 個抽象類基類中派生出來的,
InputStream/Reader: 所有的輸入流的基類,前者是位元組輸入流,后者是字符輸入流,
OutputStream/Writer: 所有輸出流的基類,前者是位元組輸出流,后者是字符輸出流,
按操作方式分類結構圖:

按操作物件分類結構圖:

30、 Java IO與 NIO的區別(補充)
NIO即New IO,這個庫是在JDK1.4中才引入的,NIO和IO有相同的作用和目的,但實作方式不同,NIO主要用到的是塊,所以NIO的效率要比IO高很多,在Java API中提供了兩套NIO,一套是針對標準輸入輸出NIO,另一套就是網路編程NIO,
31、java反射的作用于原理
(1)定義:
反射機制是在運行時,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意個物件,都能夠呼叫它的任意一個方法,在java中,只要給定類的名字,就可以通過反射機制來獲得類的所有資訊,
這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為Java語言的反射機制,
(2)哪里會用到反射機制?
jdbc就是典型的反射
Class.forName('com.mysql.jdbc.Driver.class');
//加載MySQL的驅動類
這就是反射,如hibernate,struts等框架使用反射實作的,
第一步:獲取Class物件,有4中方法:
1)Class.forName(“類的路徑”);
2)類名.class
3)物件名.getClass()
4)基本型別的包裝類,可以呼叫包裝類的Type屬性來獲得該包裝類的Class物件
(3)實作Java反射的類:
1)Class:表示正在運行的Java應用程式中的類和介面
注意:所有獲取物件的資訊都需要Class類來實作,
2)Field:提供有關類和介面的屬性資訊,以及對它的動態訪問權限,
3)Constructor:提供關于類的單個構造方法的資訊以及它的訪問權限
4)Method:提供類或介面中某個方法的資訊
(4)反射機制的優缺點:
優點:
1)能夠運行時動態獲取類的實體,提高靈活性;
2)與動態編譯結合
缺點:
1)使用反射性能較低,需要決議位元組碼,將記憶體中的物件進行決議,
解決方案:
1、通過setAccessible(true)關閉JDK的安全檢查來提升反射速度;
2、多次創建一個類的實體時,有快取會快很多
3、Re?ectASM工具類,通過位元組碼生成的方式加快反射速度
2)相對不安全,破壞了封裝性(因為通過反射可以獲得私有方法和屬性)
32、說說List,Set,Map三者的區別?
List(對付順序的好幫手):List介面存盤一組不唯一(可以有多個元素參考相同的物件),有序的物件
Set(注重獨一無二的性質): 不允許重復的集合,不會有多個元素參考相同的物件,
Map(用Key來搜索的專家): 使用鍵值對存盤,Map會維護與Key有關聯的值,兩個Key可以參考相同的物件,但Key不能重復,典型的Key是String型別,但也可以是任何物件,
最后
私信回復 資料 領取一線大廠Java面試題總結+各知識點學習思維導+一份300頁pdf檔案的Java核心知識點總結!
這些資料的內容都是面試時面試官必問的知識點,篇章包括了很多知識點,其中包括了有基礎知識、Java集合、JVM、多執行緒并發、spring原理、微服務、Netty 與RPC 、Kafka、日記、設計模式、Java演算法、資料庫、Zookeeper、分布式快取、資料結構等等,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/147652.html
標籤:Java
下一篇:python_函式的基本操作
