淺入淺出-java知識點

熟練掌握java是很關鍵的,大公司不僅僅要求你會使用幾個api,更多的是要你熟悉源碼實現(xiàn)原理,甚至要你知道有哪些不足,怎么改進,還有一些java有關的一些算法,設計模式等等。

(一) java基礎面試知識點

  • java中==和equals和hashCode的區(qū)別
    1.“==”運算符是用來比較兩個變量的值是否相等。也就是比較變量對應的內存中所存儲的數(shù)值是否相同,要比較兩個基本類型的數(shù)據(jù)或兩個引用類型變量是否相等只能使用“==”來比較。
    例:

String s = "hello";
String t = "hello";
s==t;

返回的是true。
如果變量是指向數(shù)據(jù)的對象(引用類型),那么此時涉及到兩塊內存,對象本身占用一塊內存空間(堆內存),變量也占用一塊內存。
如:

String s = new String("hello");

變量s占用一塊存儲空間,而new String("hello")則存儲在另一塊存儲空間里。此時,變量s的值就是new String("hello")占用內存的首地址。
例:

String s = new String("hello");
String t = new String("hello");
s==t;

返回的是false。

2.equals是Object類提供的方法之一。每一個Java類都繼承自Object類,所以每一個對象都具有equals這個方法。Object類中定義的equals(Object)方法是直接使用“==”運算符比較兩個對象,所以在沒有覆蓋equals(Object)方法的情況下,equals(Object)和“==”一樣,比較的是引用。

相比“==”運算符,equals(Object)方法的特殊之處在于它可以被覆蓋,所以通過覆蓋的方法讓它比較數(shù)據(jù)內容而不是比較引用。如String類覆蓋了equals(Object)方法(而StringBuffer的equals方法沒有覆蓋Object的方法),所以String類的equals()方法是用于比較兩個獨立對象的內容是否相同。
例如:

String s = new String("hello");
String t = new String("hello");
s==t;//s.equals(t);
返回的是false,而s.equals(t)將返回true。所以要比較量比較兩個實例對象的內容是否相同,那你必須覆蓋equals()方法,然后再進行比較。

3.hashCode()方法是從Object類中繼承過來的,它也用來鑒定兩個對象是否相等。Object類中的hashCode()方法返回對象是在內存中地址轉換成的一個int值,所以如果沒有重寫hashCode()方法,任何對象的hashCode()方法都是不相等的。
既然說hashCode()也是用來鑒定兩個對象是否相等,那么它和equals()方法有什么區(qū)別呢?
一般來說,equals()方法是給用戶調用的,如果你想判斷2個對象是否相等,你可以重寫equals()方法,然后在代碼中調用,就可以判斷他們是否相等了。簡單來講,equals()方法主要是用來判斷從表面上看或者從內容上看,2個對象是不是相等。舉個例子,有個學生類,屬性只有姓名和性別,那么我們可以認為只要姓名和性別相等,那么就說這2個對象是相等的。
而hashCode()方法一般用戶不會去調用它,比如在hashmap中,由于key是不可以重復的,它在判斷key是不是重復的時候就判斷了hashCode()這個方法,而且也用到了equals()方法。這里不可以重復是說equals()和hashCode()只要有一個不等就可以了!所以簡單來講,hashCode()相當于是一個對象的編碼,就好像文件中的md5,它與equals()不同就在于他返回的是int型的,比較起來不直觀。
一般在覆蓋equals()的同時也要覆蓋hashCode(),否則,就會違反Object.hashCode的通用約定,從而導致該類無法與所有基于散列值(hash)的集合類(HashMap、HashSet和Hashtable)結合在一起正常運行。
hashCode()方法的返回值和equals()方法發(fā)關系:

x.equals(y)

x.equals(y)
返回true,那么調用這2個對象中任意一個對象的hashCode()方法都必須產生同樣的整數(shù)結果
返回false,那么x和y的hashCode()方法發(fā)返回值有可能相等,也有可能不想等。
反之,hashCode()方法返回值不相等,equals()方法返回值一定不相等。hashCode()方法返回值相等,equals()方法返回值可能相等,也可能不相等。

  • int、char、long各占多少字節(jié)數(shù)
    Java基本類型占用的字節(jié)數(shù):
    1字節(jié): byte , boolean
    2字節(jié): short , char
    4字節(jié): int , float
    8字節(jié): long , double
    注:1字節(jié)(byte)=8位(bits)

  • int與integer的區(qū)別
    1、Integer是int的包裝類,int則是java的一種基本數(shù)據(jù)類型
    2、Integer變量必須實例化后才能使用,而int變量不需要
    3、Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲數(shù)據(jù)值
    4、Integer的默認值是null,int的默認值是0

  • 談談對java多態(tài)的理解
    多態(tài)就是同一事物在不同時刻表現(xiàn)出來的不同狀態(tài)。
    體現(xiàn)是父類引用指向子類對象,父類引用作為參數(shù)可以接收其子類對象,接口引用作為參數(shù)可以接收其實現(xiàn)類對象。
    前提是類與類之間要有關系,要么繼承,要么實現(xiàn),要有方法重寫,父類或者接口指向子類對象。
    好處是提高了代碼的維護性,提高了代碼的擴展性
    弊端是父類引用只能調用父類的方法,不能調用子類特有的方法和屬性。


    多態(tài).png

向上轉型:父類或者父接口指向子類對象。
向下轉型:把那個引用強制轉為子類對象。
多態(tài)中成員方法和變量的特點:一般方法編譯看左邊(父類)運行看右邊(子類),靜態(tài)方法編譯看左邊運行看左邊,變量是編譯看左邊運行看左邊。

  • String、StringBuffer、StringBuilder區(qū)別
    關于這三個類在字符串處理中的位置不言而喻,那么他們到底有什么優(yōu)缺點,到底什么時候該用誰呢?下面我們從以下幾點說明一下。
      1.三者在執(zhí)行速度方面的比較:StringBuilder > StringBuffer > String
      2.String <(StringBuffer,StringBuilder)的原因
        String:字符串常量
        StringBuffer:字符串變量
        StringBuilder:字符串變量
        從上面的名字可以看到,String是“字符串常量”,也就是不可改變的對象。對于這句話的理解你可能會產生這樣一個疑問 ,比如這段代碼:

String s = "abcd";
s = s+1;
System.out.print(s);// result : abcd1

我們明明就是改變了String型的變量s的,為什么說是沒有改變呢? 其實這是一種欺騙,JVM是這樣解析這段代碼的:首先創(chuàng)建對象s,賦予一個abcd,然后再創(chuàng)建一個新的對象s用來執(zhí)行第二行代碼,也就是說我們之前對象s并沒有變化,所以我們說String類型是不可改變的對象了,由于這種機制,每當用String操作字符串時,實際上是在不斷的創(chuàng)建新的對象,而原來的對象就會變?yōu)槔唬牵没厥盏?,可想而知這樣執(zhí)行效率會有多底。
  而StringBuffer與StringBuilder就不一樣了,他們是字符串變量,是可改變的對象,每當我們用它們對字符串做操作時,實際上是在一個對象上操作的,這樣就不會像String一樣創(chuàng)建一些而外的對象進行操作了,當然速度就快了。
  3.一個特殊的例子:

String str = “This is only a” + “ simple” + “ test”;
StringBuffer builder = new StringBuilder(“This is only a”).append(“simple”).append(“ test”);

你會很驚訝的發(fā)現(xiàn),生成str對象的速度簡直太快了,而這個時候StringBuffer居然速度上根本一點都不占優(yōu)勢。其實這是JVM的一個把戲,實際上:
String str = “This is only a” + “ simple” + “test”;
其實就是:
String str = “This is only a simple test”;
所以不需要太多的時間了。但大家這里要注意的是,如果你的字符串是來自另外的String對象的話,速度就沒那么快了,譬如:
String str2 = “This is only a”;
String str3 = “ simple”;
String str4 = “ test”;
String str1 = str2 +str3 + str4;
這時候JVM會規(guī)規(guī)矩矩的按照原來的方式去做。
4.StringBuilder與 StringBuffer:
StringBuilder:線程非安全的
StringBuffer:線程安全的
當我們在字符串緩沖去被多個線程使用是,JVM不能保證StringBuilder的操作是安全的,雖然他的速度最快,但是可以保證StringBuffer是可以正確操作的。當然大多數(shù)情況下就是我們是在單線程下進行的操作,所以大多數(shù)情況下是建議用StringBuilder而不用StringBuffer的,就是速度的原因。

對于三者使用的總結:
1.如果要操作少量的數(shù)據(jù)用 = String  
2.單線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuilder
3.多線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuffer

  • 什么是內部類?內部類的作用
    可以將一個類的定義放在另一個類的定義的內部,這就是內部類。
    內部類的作用:
    1、內部類可以很好的實現(xiàn)隱藏
    2、內部類擁有外圍類的所有元素的訪問權限
    3、可以實現(xiàn)多重繼承
    4、可以避免接口中的方法和同一個類中的方法同名的問題

  • 抽象類和接口區(qū)別
    1、概念不一樣。接口是對動作的抽象,抽象類是對本質的抽象。
    抽象類表示的是,這個對象是什么。接口表示的是,這個對象能做什么。比如,男人,女人,這兩個類(如果是類的話……),他們的抽象類是人。說明,他們都是人。人可以吃東西,狗也可以吃東西,你可以把“吃東西”定義成一個接口,然后讓這些類去實現(xiàn)它。所以,在高級語言上,一個類只能繼承一個類(抽象類)(正如人不可能同時是生物和非生物),但是可以實現(xiàn)多個接口(吃飯接口、走路接口)。
    2、使用情況:
    a.抽象類 和 接口 都是用來抽象具體對象的. 但是接口的抽象級別最高
    b.抽象類可以有具體的方法 和屬性, 接口只能有抽象方法和不可變常量
    c.抽象類主要用來抽象類別,接口主要用來抽象功能.
    d.抽象類中,且不包含任何實現(xiàn),派生類必須覆蓋它們。接口中所有方法都必須是未實現(xiàn)的。
    e.接口是設計的結果 ,抽象類是重構的結果
    3、使用方向:當你關注一個事物的本質的時候,用抽象類;當你關注一個操作的時候,用接口。

  • 抽象類的意義
    1,為子類提供一個公共的類型;
    2,封裝子類中重復內容(成員變量和方法);
    3,定義有抽象方法,子類雖然有不同的實現(xiàn),但該方法的定義是一致的。

  • 抽象類與接口的應用場景
    如果你擁有一些方法并且想讓它們中的一些有默認實現(xiàn),那么使用抽象類。
    如果你想實現(xiàn)多重繼承,那么你必須使用接口。
    由于Java不支持多繼承,子類不能夠繼承多個類,但可以實現(xiàn)多個接口。因此你就可以使用接口來解決它。
    如果基本功能在不斷改變,那么就需要使用抽象類。如果不斷改變基本功能并且使用接口,那么就需要改變所有實現(xiàn)了該接口的類。
    抽象類表示共有許要實現(xiàn)的方法 接口用來特定類有需要才實現(xiàn) 人都會吃飯 但有的人喝酒
    抽象類是用來捕捉子類的通用特性的
    抽象類是 is a關系;而接口是has a關系

  • 抽象類是否可以沒有方法和屬性?
    抽象類里面不一定有抽象方法 ,但是有抽象方法一定是抽象類,屬性和普通類屬性一樣

  • 接口的意義
    1、重要性:在Java語言中, abstract class 和interface 是支持抽象類定義的兩種機制。正是由于這兩種機制的存在,才賦予了Java強大的 面向對象能力。
    2、簡單、規(guī)范性:如果一個項目比較龐大,那么就需要一個能理清所有業(yè)務的架構師來定義一些主要的接口,這些接口不僅告訴開發(fā)人員你需要實現(xiàn)那些業(yè)務,而且也將命名規(guī)范限制住了(防止一些開發(fā)人員隨便命名導致別的程序員無法看明白)。
    3、維護、拓展性:比如你要做一個畫板程序,其中里面有一個面板類,主要負責繪畫功能,然后你就這樣定義了這個類。
    可是在不久將來,你突然發(fā)現(xiàn)這個類滿足不了你了,然后你又要重新設計這個類,更糟糕是你可能要放棄這個類,那么其他地方可能有引用他,這樣修改起來很麻煩。
    如果你一開始定義一個接口,把繪制功能放在接口里,然后定義類時實現(xiàn)這個接口,然后你只要用這個接口去引用實現(xiàn)它的類就行了,以后要換的話只不過是引用另一個類而已,這樣就達到維護、拓展的方便性。
    4、安全、嚴密性:接口是實現(xiàn)軟件松耦合的重要手段,它描敘了系統(tǒng)對外的所有服務,而不涉及任何具體的實現(xiàn)細節(jié)。這樣就比較安全、嚴密一些(一般軟件服務商考慮的比較多)。

  • 泛型中extends和super的區(qū)別
    <? extends T> 只能用于方法返回,告訴編譯器此返參的類型的最小繼承邊界為T,T和T的父類都能接收,但是入參類型無法確定,只能接受null的傳入
    <? super T>只能用于限定方法入參,告訴編譯器入參只能是T或其子類型,而返參只能用Object類接收
    ? 既不能用于入參也不能用于返參
    1,類型安全。 泛型的主要目標是提高 Java 程序的類型安全。通過知道使用泛型定義的變量的類型限制,編譯器可以在一個高得多的程度上驗證類型假設。沒有泛型,這些假設就只存在于程序員的頭腦中(或者如果幸運的話,還存在于代碼注釋中)。
    2,消除強制類型轉換。 泛型的一個附帶好處是,消除源代碼中的許多強制類型轉換。這使得代碼更加可讀,并且減少了出錯機會。
    3,潛在的性能收益。 泛型為較大的優(yōu)化帶來可能。在泛型的初始實現(xiàn)中,編譯器將強制類型轉換(沒有泛型的話,程序員會指定這些強制類型轉換)插入生成的字節(jié)碼中。但是更多類型信息可用于編譯器這一事實,為未來版本的 JVM 的優(yōu)化帶來可能。由于泛型的實現(xiàn)方式,支持泛型(幾乎)不需要 JVM 或類文件更改。所有工作都在編譯器中完成,編譯器生成類似于沒有泛型(和強制類型轉換)時所寫的代碼,只是更能確保類型安全而已。

  • 父類的靜態(tài)方法能否被子類重寫
    父類的靜態(tài)方法不能被子類繼承,更談不上重寫,就算是子類中有一個和父類一模一樣的靜態(tài)方法,那也是子類本身的,和父類的那個靜態(tài)方法不是一回事。方法加靜態(tài)后就屬于類不屬于對象了。

  • 進程和線程的區(qū)別
    一、關于進程和線程,首先從定義上理解就有所不同
    1、進程是什么?
    是具有一定獨立功能的程序、它是系統(tǒng)進行資源分配和調度的一個獨立單位,重點在系統(tǒng)調度和單獨的單位,也就是說進程是可以獨 立運行的一段程序。
    2、線程又是什么?
    線程是進程的一個實體,是CPU調度和分派的基本單位,他是比進程更小的能獨立運行的基本單位,線程自己基本上不擁有系統(tǒng)資源。 在運行時,只是暫用一些計數(shù)器、寄存器和棧 。
    二、他們之間的關系
    1、一個線程只能屬于一個進程,而一個進程可以有多個線程,但至少有一個線程(通常說的主線程)。
    2、資源分配給進程,同一進程的所有線程共享該進程的所有資源。
    3、線程在執(zhí)行過程中,需要協(xié)作同步。不同進程的線程間要利用消息通信的辦法實現(xiàn)同步。
    4、處理機分給線程,即真正在處理機上運行的是線程。
    5、線程是指進程內的一個執(zhí)行單元,也是進程內的可調度實體。
    三、從三個角度來剖析二者之間的區(qū)別
    1、調度:線程作為調度和分配的基本單位,進程作為擁有資源的基本單位。
    2、并發(fā)性:不僅進程之間可以并發(fā)執(zhí)行,同一個進程的多個線程之間也可以并發(fā)執(zhí)行。
    3、擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統(tǒng)資源,但可以訪問隸屬于進程的資源。

  • final,finally,finalize的區(qū)別
    1、final修飾符(關鍵字)。被final修飾的類,就意味著不能再派生出新的子類,不能作為父類而被子類繼承。因此一個類不能既被abstract聲明,又被final聲明。將變量或方法聲明為final,可以保證他們在使用的過程中不被修改。被聲明為final的變量必須在聲明時給出變量的初始值,而在以后的引用中只能讀取。被final聲明的方法也同樣只能使用,不能重載。
    2、finally是在異常處理時提供finally塊來執(zhí)行任何清除操作。不管有沒有異常被拋出、捕獲,finally塊都會被執(zhí)行。try塊中的內容是在無異常時執(zhí)行到結束。catch塊中的內容,是在try塊內容發(fā)生catch所聲明的異常時,跳轉到catch塊中執(zhí)行。finally塊則是無論異常是否發(fā)生,都會執(zhí)行finally塊的內容,所以在代碼邏輯中有需要無論發(fā)生什么都必須執(zhí)行的代碼,就可以放在finally塊中。
    3、finalize是方法名。java技術允許使用finalize()方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在object類中定義的,因此所有的類都繼承了它。子類覆蓋finalize()方法以整理系統(tǒng)資源或者被執(zhí)行其他清理工作。finalize()方法是在垃圾收集器刪除對象之前對這個對象調用的。

  • 序列化的方式
    第一種是實現(xiàn)Serializable接口(是JavaSE本身就支持的),第二種是實現(xiàn)Parcelable接口(是Android特有功能,效率比實現(xiàn)Serializable接口高效,可用于Intent數(shù)據(jù)傳遞,也可以用于進程間通信(IPC))。實現(xiàn)Serializable接口非常簡單,聲明一下就可以了,而實現(xiàn)Parcelable接口稍微復雜一些,但效率更高,推薦用這種方法提高性能。

  • Serializable 和Parcelable 的區(qū)別
    1)在使用內存的時候,Parcelable比Serializable性能高,所以推薦使用Parcelable。
    2)Serializable在序列化的時候會產生大量的臨時變量,從而引起頻繁的GC。
    3)Parcelable不能使用在要將數(shù)據(jù)存儲在磁盤上的情況,因為Parcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點,但此時還是建議使用Serializable。
    4)Serializable的實現(xiàn),只需要implements Serializable 即可。這只是給對象打了一個標記,系統(tǒng)會自動將其序列化。
    5)Parcelabel的實現(xiàn),不僅需要implements Parcelabel,還需要在類中添加一個靜態(tài)成員變量CREATOR,這個變量需要實現(xiàn) Parcelable.Creator 接口。

  1. Parcelable的性能比Serializable好,在內存開銷方面較小,所以在內存間數(shù)據(jù)傳輸時推薦使用Parcelable,如activity間傳輸數(shù)據(jù),而Serializable可將數(shù)據(jù)持久化方便保存,所以在需要保存或網絡傳輸數(shù)據(jù)時選擇Serializable,因為android不同版本Parcelable可能不同,所以不推薦使用Parcelable進行數(shù)據(jù)持久化
  • 靜態(tài)屬性和靜態(tài)方法是否可以被繼承?是否可以被重寫?以及原因?
    結論:java中靜態(tài)屬性和靜態(tài)方法可以被繼承,但是沒有被重寫(overwrite)而是被隱藏.
    原因:
    1). 靜態(tài)方法和屬性是屬于類的,調用的時候直接通過類名.方法名完成對,不需要繼承機制及可以調用。如果子類里面定義了靜態(tài)方法和屬性,那么這時候父類的靜態(tài)方法或屬性稱之為"隱藏"。如果你想要調用父類的靜態(tài)方法和屬性,直接通過父類名.方法或變量名完成,至于是否繼承一說,子類是有繼承靜態(tài)方法和屬性,但是跟實例方法和屬性不太一樣,存在"隱藏"的這種情況。
    2). 多態(tài)之所以能夠實現(xiàn)依賴于繼承、接口和重寫、重載(繼承和重寫最為關鍵)。有了繼承和重寫就可以實現(xiàn)父類的引用指向不同子類的對象。重寫的功能是:"重寫"后子類的優(yōu)先級要高于父類的優(yōu)先級,但是“隱藏”是沒有這個優(yōu)先級之分的。
    3). 靜態(tài)屬性、靜態(tài)方法和非靜態(tài)的屬性都可以被繼承和隱藏而不能被重寫,因此不能實現(xiàn)多態(tài),不能實現(xiàn)父類的引用可以指向不同子類的對象。非靜態(tài)方法可以被繼承和重寫,因此可以實現(xiàn)多態(tài)。

  • 靜態(tài)內部類的設計意圖

  • 成員內部類、靜態(tài)內部類、局部內部類和匿名內部類的理解,以及項目中的應用

  • 談談對kotlin的理解
    1,來自JetBrains公司,用了一個小島的名字來命名的,跟Java一樣..
    2,同樣運行在JVM上
    3,靜態(tài)強類型
    4,可編譯成JavaScript源碼
    5,與Java100%兼容

  • string 轉換成 integer的方式及原理

String str = "...";
Integer i = null;
if(str!=null){
i = Integer.valueOf(str);
}

//方法一:Integer類的靜態(tài)方法toString()
Integer a = 2;
String str = Integer.toString(a)
//方法二:Integer類的成員方法toString()
Integer a = 2;
String str = a.toString();
//方法三:String類的靜態(tài)方法valueOf()
Integer a = 2;
String str = String.valueOf(a);

(二) java深入源碼級的面試題(有難度)

  • 哪些情況下的對象會被垃圾回收機制處理掉?
    垃圾收集的算法分析
    引用計數(shù)法、tracing算法、compacting算法、copying算法、generation算法、adaptive算法
    System.gc()方法

https://blog.csdn.net/u010429311/article/details/50990441

  • 講一下常見編碼方式?
    ASCII 碼
    學過計算機的人都知道 ASCII 碼,總共有 128 個,用一個字節(jié)的低 7 位表示,0~31 是控制字符如換行回車刪除等;32~126 是打印字符,可以通過鍵盤輸入并且能夠顯示出來。

ISO-8859-1
128 個字符顯然是不夠用的,于是 ISO 組織在 ASCII 碼基礎上又制定了一些列標準用來擴展 ASCII 編碼,它們是 ISO-8859-1~ISO-8859-15,其中 ISO-8859-1 涵蓋了大多數(shù)西歐語言字符,所有應用的最廣泛。ISO-8859-1 仍然是單字節(jié)編碼,它總共能表示 256 個字符。

GB2312
它的全稱是《信息交換用漢字編碼字符集 基本集》,它是雙字節(jié)編碼,總的編碼范圍是 A1-F7,其中從 A1-A9 是符號區(qū),總共包含 682 個符號,從 B0-F7 是漢字區(qū),包含 6763 個漢字。

GBK
全稱叫《漢字內碼擴展規(guī)范》,是國家技術監(jiān)督局為 windows95 所制定的新的漢字內碼規(guī)范,它的出現(xiàn)是為了擴展 GB2312,加入更多的漢字,它的編碼范圍是 8140~FEFE(去掉 XX7F)總共有 23940 個碼位,它能表示 21003 個漢字,它的編碼是和 GB2312 兼容的,也就是說用 GB2312 編碼的漢字可以用 GBK 來解碼,并且不會有亂碼。

GB18030
全稱是《信息交換用漢字編碼字符集》,是我國的強制標準,它可能是單字節(jié)、雙字節(jié)或者四字節(jié)編碼,它的編碼與 GB2312 編碼兼容,這個雖然是國家標準,但是實際應用系統(tǒng)中使用的并不廣泛。

UTF-16
說到 UTF 必須要提到 Unicode(Universal Code 統(tǒng)一碼),ISO 試圖想創(chuàng)建一個全新的超語言字典,世界上所有的語言都可以通過這本字典來相互翻譯??上攵@個字典是多么的復雜,關于 Unicode 的詳細規(guī)范可以參考相應文檔。Unicode 是 Java 和 XML 的基礎,下面詳細介紹 Unicode 在計算機中的存儲形式。

UTF-16 具體定義了 Unicode 字符在計算機中存取方法。UTF-16 用兩個字節(jié)來表示 Unicode 轉化格式,這個是定長的表示方法,不論什么字符都可以用兩個字節(jié)表示,兩個字節(jié)是 16 個 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每兩個字節(jié)表示一個字符,這個在字符串操作時就大大簡化了操作,這也是 Java 以 UTF-16 作為內存的字符存儲格式的一個很重要的原因。

UTF-8
UTF-16 統(tǒng)一采用兩個字節(jié)表示一個字符,雖然在表示上非常簡單方便,但是也有其缺點,有很大一部分字符用一個字節(jié)就可以表示的現(xiàn)在要兩個字節(jié)表示,存儲空間放大了一倍,在現(xiàn)在的網絡帶寬還非常有限的今天,這樣會增大網絡傳輸?shù)牧髁?,而且也沒必要。而 UTF-8 采用了一種變長技術,每個編碼區(qū)域有不同的字碼長度。不同類型的字符可以是由 1~6 個字節(jié)組成。

  • utf-8編碼中的中文占幾個字節(jié);int型幾個字節(jié)?
    中文占3個字節(jié)、1 int = 4字節(jié)

  • 靜態(tài)代理和動態(tài)代理的區(qū)別,什么場景使用?

https://blog.csdn.net/WangQYoho/article/details/77584832

  • Java的異常體系
    1.異常的分類
    Error:一般為底層的不可恢復的類;
    Exception:分為未檢查異常(RuntimeException)和已檢查異常(非RuntimeException)。
    未檢查異常是因為程序員沒有進行必需要的檢查,因為疏忽和錯誤而引起的錯誤。幾個經典的RunTimeException如下:
    1.java.lang.NullPointerException;
    2.java.lang.ArithmaticException;
    3.java.lang.ArrayIndexoutofBoundsException;
    對于已檢查異常是必須進行處理的。
    應該在合適的位置處理異常,異常的處理準則如下:誰知情誰處理,誰負責誰處理,誰導致誰處理。
    2.異常的處理方法
    1.throws:直接往上一層拋出異常;
    2.try{}catch;
    3.finally;

  • 談談你對解析與分派的認識。

  • 修改對象A的equals方法的簽名,那么使用HashMap存放這個對象實例的時候,會調用哪個equals方法?

  • Java中實現(xiàn)多態(tài)的機制是什么?

  • 如何將一個Java對象序列化到文件里?

  • 說說你對Java反射的理解
    JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調用對象的方法的功能稱為java語言的反射機制。

https://blog.csdn.net/piaoyi493279486/article/details/45624257

  • 說說你對Java注解的理解

https://blog.csdn.net/briblue/article/details/73824058

  • 說說你對依賴注入的理解
    只要不是由內部生產(比如初始化、構造函數(shù) __construct 中通過工廠方法、自行手動 new 的),而是由外部以參數(shù)或其他形式注入的,都屬于依賴注入(DI) 。

https://blog.csdn.net/forlightway/article/details/56676734

  • 說一下泛型原理,并舉例說明
    1,類型安全。 泛型的主要目標是提高 Java 程序的類型安全。通過知道使用泛型定義的變量的類型限制,編譯器可以在一個高得多的程度上驗證類型假設。
    沒有泛型,這些假設就只存在于程序員的頭腦中(或者如果幸運的話,還存在于代碼注釋中)。
    2,消除強制類型轉換。 泛型的一個附帶好處是,消除源代碼中的許多強制類型轉換。這使得代碼更加可讀,并且減少了出錯機會。
    3,潛在的性能收益。 泛型為較大的優(yōu)化帶來可能。在泛型的初始實現(xiàn)中,編譯器將強制類型轉換(沒有泛型的話,程序員會指定這些強制類型轉換)插入生成的字節(jié)碼中。

  • Java中String的了解
    “String對象一旦被創(chuàng)建就是固定不變的了,對String對象的任何改變都不影響到原對象,相關的任何change操作都會生成新的對象”。
    1)String類是final類,也即意味著String類不能被繼承,并且它的成員方法都默認為final方法。在Java中,被final修飾的類是不允許被繼承的,并且該類中的成員方法都默認為final方法。
    2)上面列舉出了String類中所有的成員屬性,從上面可以看出String類其實是通過char數(shù)組來保存字符串的。

  • String為什么要設計成不可變的?
    設計考慮,效率優(yōu)化問題,以及安全性這三大方面.

  • Object類的equal和hashCode方法重寫,為什么?
    為了保證同一個對象,保證在equals相同的情況下hashcode值必定相同,如果重寫了equals而未重寫hashcode方法,可能就會出現(xiàn)兩個沒有關系的對象equals相同的(因為equal都是根據(jù)對象的特征進行重寫的),但hashcode確實不相同的。

(三) 數(shù)據(jù)結構

  • 常用數(shù)據(jù)結構簡介
    1、幾個基本概念
    數(shù)據(jù):數(shù)據(jù)是指計算機接受的輸入數(shù)據(jù),比如:整型、浮點型等數(shù)值類型以及聲音、圖像、視頻等非數(shù)值類型的數(shù)據(jù)
    數(shù)據(jù)元素:是組成數(shù)據(jù)有一定意義的基本單位,比如一個人的基本信息包括姓名、性別、年齡等
    數(shù)據(jù)對象:是性質相同的數(shù)據(jù)元素的集合,比如正整數(shù)數(shù)據(jù)對象N={1,2,3……}
    數(shù)據(jù)結構:是數(shù)據(jù)的組織形式,即數(shù)據(jù)元素之間存在的一種或幾種特定關系
    數(shù)據(jù)類型:是用來刻畫一組性質相同的數(shù)據(jù)及其上的操作??梢苑譃樵宇愋秃徒Y構類型。
    抽象數(shù)據(jù)類型:對具有某種邏輯關系的數(shù)據(jù)類型進行描述,并在該類型上進行的一組操作。比如C++中的結構體。
    2、數(shù)據(jù)結構
    數(shù)據(jù)結構的主要任務就是通過描述對象的結構特征,包括邏輯結構在內的聯(lián)系,然后把邏輯結構表示成計算機可實現(xiàn)的物理結構,從而方便計算機處理。
    邏輯結構:數(shù)據(jù)對象中數(shù)據(jù)元素之間的相互關系,即數(shù)據(jù)對象中的數(shù)據(jù)元素的所有分布情況滿足的規(guī)律。
    集合結構:這種結構中的數(shù)據(jù)元素除了屬于同一數(shù)據(jù)對象之外沒有其他的任何關系。
    線性結構:線性結構中的數(shù)據(jù)元素之間是一對一的關系,并且有一種先后次序關系。包括數(shù)組、線性表、棧、隊列和串等等。
    樹形結構:樹形結構中的數(shù)據(jù)元素之間是一對多的層次關系。
    圖形結構:圖形結構中的數(shù)據(jù)元素之間是多對多的關系。
    物理結構:又稱存儲結構,指的是邏輯結構在計算機中的存儲形式。
    順序存儲結構:把數(shù)據(jù)元素存放到地址連續(xù)的存儲單元里,數(shù)據(jù)間的邏輯關系和物理關系一致
    鏈式存儲結構:把數(shù)據(jù)元素存放到任意的存儲單元里,地址可以不連續(xù),通過指針實現(xiàn)數(shù)據(jù)元素之間的邏輯關系。
    3、算法
    算法的定義:描述解決問題的方法。使用不同的數(shù)據(jù)結構解決某一類或者具體的問題的策略。
    算法的特性:
    有窮性:算法執(zhí)行有限的步驟之后會結束而不會出現(xiàn)無限循環(huán)。
    確定性:對于相同的輸入只有唯一的輸出結果。
    可行性:算法的每一步都必須在有限執(zhí)行次數(shù)完成。
    輸入:算法有零個輸入或多個輸入。
    輸出:至少有一個或多個輸出。

  • 并發(fā)集合了解哪些?

  • 列舉java的集合以及集合之間的繼承關系

  • 集合類以及集合框架

  • 容器類介紹以及之間的區(qū)別(容器類估計很多人沒聽這個詞,Java容器主要可以劃分為4個部分:List列表、Set集合、Map映射、工具類(Iterator迭代器、Enumeration枚舉類、Arrays和Collections),具體的可以看看這篇博文 Java容器類)

  • List,Set,Map的區(qū)別

  • List和Map的實現(xiàn)方式以及存儲方式

  • HashMap的實現(xiàn)原理

  • HashMap數(shù)據(jù)結構?

  • HashMap源碼理解

  • HashMap如何put數(shù)據(jù)(從HashMap源碼角度講解)?

  • HashMap怎么手寫實現(xiàn)?

  • ConcurrentHashMap的實現(xiàn)原理

  • ArrayMap和HashMap的對比

  • HashTable實現(xiàn)原理

  • TreeMap具體實現(xiàn)

  • HashMap和HashTable的區(qū)別

  • HashMap與HashSet的區(qū)別

  • HashSet與HashMap怎么判斷集合元素重復?

  • 集合Set實現(xiàn)Hash怎么防止碰撞

  • ArrayList和LinkedList的區(qū)別,以及應用場景

  • 數(shù)組和鏈表的區(qū)別

  • 二叉樹的深度優(yōu)先遍歷和廣度優(yōu)先遍歷的具體實現(xiàn)

  • 堆的結構

  • 堆和樹的區(qū)別

  • 堆和棧在內存中的區(qū)別是什么(解答提示:可以從數(shù)據(jù)結構方面以及實際實現(xiàn)方面兩個方面去回答)?

  • 什么是深拷貝和淺拷貝

  • 手寫鏈表逆序代碼

  • 講一下對樹,B+樹的理解

  • 講一下對圖的理解

  • 判斷單鏈表成環(huán)與否?

  • 鏈表翻轉(即:翻轉一個單項鏈表)

  • 合并多個單有序鏈表(假設都是遞增的)

(四) 線程、多線程和線程池

  • 開啟線程的三種方式?
  • 線程和進程的區(qū)別?
  • 為什么要有線程,而不是僅僅用進程?
  • run()和start()方法區(qū)別
  • 如何控制某個方法允許并發(fā)訪問線程的個數(shù)?
  • 在Java中wait和seelp方法的不同;
  • 談談wait/notify關鍵字的理解
  • 什么導致線程阻塞?
  • 線程如何關閉?
  • 講一下java中的同步的方法
  • 數(shù)據(jù)一致性如何保證?
  • 如何保證線程安全?
  • 如何實現(xiàn)線程同步?
  • 兩個進程同時要求寫或者讀,能不能實現(xiàn)?如何防止進程的同步?
  • 線程間操作List
  • Java中對象的生命周期
  • Synchronized用法
  • synchronize的原理
  • 談談對Synchronized關鍵字,類鎖,方法鎖,重入鎖的理解
  • static synchronized 方法的多線程訪問和作用
  • 同一個類里面兩個synchronized方法,兩個線程同時訪問的問題
  • volatile的原理
  • 談談volatile關鍵字的用法
  • 談談volatile關鍵字的作用
  • 談談NIO的理解
  • synchronized 和volatile 關鍵字的區(qū)別
  • synchronized與Lock的區(qū)別
  • ReentrantLock 、synchronized和volatile比較
  • ReentrantLock的內部實現(xiàn)
  • lock原理
  • 死鎖的四個必要條件?
  • 怎么避免死鎖?
  • 對象鎖和類鎖是否會互相影響?
  • 什么是線程池,如何使用?
  • Java的并發(fā)、多線程、線程模型
  • 談談對多線程的理解
  • 多線程有什么要注意的問題?
  • 談談你對并發(fā)編程的理解并舉例說明
  • 談談你對多線程同步機制的理解?
  • 如何保證多線程讀寫文件的安全?
  • 多線程斷點續(xù)傳原理
  • 斷點續(xù)傳的實現(xiàn)

(五)并發(fā)編程有關知識點(這個是一般Android開發(fā)用的少的,所以建議多去看看):
平時Android開發(fā)中對并發(fā)編程可以做得比較少,Thread這個類經常會用到,但是我們想提升自己的話,一定不能停留在表面,,我們也應該去了解一下java的關于線程相關的源碼級別的東西。

學習的參考資料如下:
Java 內存模型
java線程安全總結
深入理解java內存模型系列文章
線程狀態(tài):
一張圖讓你看懂JAVA線程間的狀態(tài)轉換
鎖:
鎖機制:synchronized、Lock、Condition
Java 中的鎖
并發(fā)編程:
Java并發(fā)編程:Thread類的使用
Java多線程編程總結
Java并發(fā)編程的總結與思考
Java并發(fā)編程實戰(zhàn)——-synchronized
深入分析ConcurrentHashMap

本文內容轉載自 微信公眾號 伯特說 為了便于整理所以自己發(fā)了文章 如果侵犯將會刪除

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,896評論 0 11
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,791評論 11 349
  • 有些人 只一眼 就足夠讓你心翻云覆雨 有些話 只聽開頭 就能猜到結尾 雨 斷斷續(xù)續(xù)地下著 心 隱隱約約地疼痛 噩夢...
    蘇霉閱讀 547評論 3 3
  • 在我們的現(xiàn)實生活中,親子活動是少之再少,大多是父母長期工作,工作下班后又給料理飯菜,而孩子放學就是做作業(yè),...
    好哦123閱讀 273評論 0 1
  • 我的表帶 是在吉林 換的 那是商業(yè)區(qū) 一樓大廳的 鐘表鋪 然而 有生之年 我不會再去 吉林或者 那家鐘表鋪 這就是...
    苦桃1閱讀 188評論 0 0

友情鏈接更多精彩內容