Android面試題總結(一)JAVA基礎篇

1.Java中==,equal和hashCode的區別

  • == : 該操作符生成的是一個boolean結果,它計算的是操作數的值之間的關係
  • equals : Object 的 實例方法,比較兩個對象的content是否相同,
    • equals方法本意是用來判斷引用的對象是否一致
  • hashCode : Object 的 native方法 , 獲取對象的哈希值,用於確定該對象在哈希表中的索引位置,它實際上是一個int型整數,
    • hashcode是系統用來快速檢索對象而使用

2.int和Integer的區別

(1)Integer是int的包裝類;int是基本數據類型; 
(2)Integer變量必須實例化後才能使用;int變量不需要; 
(3)Integer實際是對象的引用,指向此new的Integer對象;int是直接存儲數據值 ; 

(4)Integer的默認值是null;int的默認值是0。

3.Java中基本類型佔用字節數

在Java中一共有8種基本數據類型,其中有4種整型,2種浮點類型,1種用於表示Unicode編碼的字符單元的字符類型和1種用於表示真值的boolean類型。(一個字節等於8個bit)

1.整型
類型              存儲需求     bit數    取值範圍      備註
int                 4字節           4*8 
short             2字節           2*8    -32768~32767
long              8字節           8*8
byte              1字節           1*8     -128~127

2.浮點型
類型              存儲需求     bit數    取值範圍      備註
float              4字節           4*8                  float類型的數值有一個後綴F(例如:3.14F)
double          8字節           8*8                       沒有後綴F的浮點數值(如3.14)默認爲double類型

3.char類型
類型              存儲需求     bit數     取值範圍      備註
char              2字節          2*8

4.boolean類型
類型              存儲需求    bit數    取值範圍      備註

boolean        1字節          1*8      false、true

4.對java多態的理解

  1. 面向對象的三大特性封裝、繼承、多態。從一定角度來看,封裝和繼承幾乎都是爲多態而準備的。
  2. 多態的定義:指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而採用多種不同的行爲方式。(發送消息就是函數調用)
  3. 實現多態的技術稱爲:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
  4. 多態的作用:消除類型之間的耦合關係
  5. 現實中,關於多態的例子不勝枚舉。比方說按下 F1 鍵這個動作,如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;如果當前在 Word 下彈出的就是 Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支持。同一個事件發生在不同的對象上會產生不同的結果。

下面是多態存在的三個必要條件,要求大家做夢時都能背出來!

多態存在的三個必要條件
一、要有繼承;
二、要有重寫;
三、父類引用指向子類對象

 多態的好處

1.可替換性(substitutability)。多態對已存在代碼具有可替換性。例如,多態對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2.可擴充性(extensibility)。多態對代碼具有可擴充性。增加新的子類不影響已存在類的多態性、繼承性,以及其他特性的運行和操作。實際上新加子類更容易獲得多態功能。例如,在實現了圓錐、半圓錐以及半球體的多態基礎上,很容易增添球體類的多態性。
3.接口性(interface-ability)。多態是超類通過方法簽名,向子類提供了一個共同接口,由子類來完善或者覆蓋它而實現的。如圖8.3 所示。圖中超類Shape規定了兩個實現多態的接口方法,computeArea()以及computeVolume()。子類,如Circle和Sphere爲了實現多態,完善或者覆蓋這兩個接口方法。
4.靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。
5.簡化性(simplicity)。多態簡化對應用軟件的代碼編寫和修改過程,尤其在處理大量對象的運算和操作時,這個特點尤爲突出和重要。

例子:

void doSomething(Shape shape){
        shape.draw();
         .
         .
         shape.erase();
}

Circle circle = new Cricle();

Traingle traingle = new Traingle();

Line line = new Line();

doSonething(circle);

doSonething(traingle);

doSonething(line);

當Cricle被傳入到Shape時,Cricle 會被doSomething()看做是Shape,也就是說doSomething發送給Shape的任何消息,都會被Circle接受到,這樣就是合乎邏輯的。在此過程中用到了向上轉型(upcasting).

5.String,StringBuffer,StringBuilder的區別

java中String、StringBuffer、StringBuilder是編程中經常使用的字符串類,他們之間的區別也是經常在面試中會問到的問題。現在總結一下,看看他們的不同與相同。

1.可變與不可變

  String類中使用字符數組保存字符串,如下就是,因爲有“final”修飾符,所以可以知道string對象是不可變的。

    private final char value[];

  StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數組保存字符串,如下就是,可知這兩種對象都是可變的。

    char[] value;

2.是否多線程安全

  String中的對象是不可變的,也就可以理解爲常量,顯然線程安全

  AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

  StringBuffer對方法加了同步鎖或者對調用的方法加了同步鎖,所以是線程安全的。看如下源碼:

複製代碼
1 public synchronized StringBuffer reverse() {
2     super.reverse();
3     return this;
4 }
5 
6 public int indexOf(String str) {
7     return indexOf(str, 0);        //存在 public synchronized int indexOf(String str, int fromIndex) 方法
8 }
複製代碼

  StringBuilder並沒有對方法進行加同步鎖,所以是非線程安全的

 3.StringBuilder與StringBuffer共同點

  StringBuilder與StringBuffer有公共父類AbstractStringBuilder(抽象類)。

  抽象類與接口的其中一個區別是:抽象類中可以定義一些子類的公共方法,子類只需要增加新的功能,不需要重複寫已經存在的方法;而接口中只是對方法的申明和常量的定義。

  StringBuilder、StringBuffer的方法都會調用AbstractStringBuilder中的公共方法,如super.append(...)。只是StringBuffer會在方法上加synchronized關鍵字,進行同步。

  最後,如果程序不是多線程的,那麼使用StringBuilder效率高於StringBuffer。

6.什麼是內部類,內部類的作用?

內部類爲什麼存在

內部類 ( inner class ) : 定義在另一個類中的類

我們爲什麼需要內部類?或者說內部類爲啥要存在?其主要原因有如下幾點:

  • 內部類方法可以訪問該類定義所在作用域中的數據,包括被 private 修飾的私有數據
  • 內部類可以對同一包中的其他類隱藏起來
  • 內部類可以實現 java 單繼承的缺陷
  • 當我們想要定義一個回調函數卻不想寫大量代碼的時候我們可以選擇使用匿名內部類來實現

內部類可以實現 java 單繼承的缺陷

通過匿名內部類來"優化"簡單的接口實現

靜態內部類和非靜態內部類的區別

  1. 靜態內部類可以有靜態成員,而非靜態內部類則不能有靜態成員。
  2. 靜態內部類可以訪問外部類的靜態變量,而不可訪問外部類的非靜態變量;
  3. 非靜態內部類的非靜態成員可以訪問外部類的非靜態變量。
  4. 靜態內部類的創建不依賴於外部類,而非靜態內部類必須依賴於外部類的創建而創建。

7.抽象類和接口的區別

1、 抽象類在java語言中所表示的是一種繼承關係,一個子類只能存在一個父類,但是可以存在多個接口。

 2、 在抽象類中可以擁有自己的成員變量和非抽象類方法,但是接口中只能存在靜態的不可變的成員數據(不過一般都不在接口中定義成員數據),而且它的所有方法都是抽象的。

  3、抽象類和接口所反映的設計理念是不同的,抽象類所代表的是“is-a”的關係,而接口所代表的是“like-a”的關係。

      抽象類和接口是java語言中兩種不同的抽象概念,他們的存在對多態提供了非常好的支持,雖然他們之間存在很大的相似性。但是對於他們的選擇往往反應了您對問題域的理解。只有對問題域的本質有良好的理解,才能做出正確、合理的設計。

8.抽象類的意義

1,爲子類提供一個公共的類型;

2,封裝子類中重複內容(成員變量和方法);

3,定義有抽象方法,子類雖然有不同的實現,但該方法的定義是一致的。

9.抽象類與接口的應用場景

  1. 如果你擁有一些方法並且想讓它們中的一些有默認實現,那麼使用抽象類吧。
    如果你想實現多重繼承,那麼你必須使用接口。
    由於Java不支持多繼承,子類不能夠繼承多個類,但可以實現多個接口。因此你就可以使用接口來解決它。
    如果基本功能在不斷改變,那麼就需要使用抽象類。如果不斷改變基本功能並且使用接口,那麼就需要改變所有實現了該接口的類。
  1. 抽象類表示共有許要實現的方法 接口用來特定類有需要才實現 人都會吃飯 但有的人抽菸

  2. 抽象類是用來捕捉子類的通用特性的

  3. 抽象類是 is a關係;而接口是has a關係

  4. 看看jdk的api會發現大部分接口都是able結尾的,表示一種能力。馬士兵曰過:當你不知道用抽象類還是接口好時就用接口

10.泛型中extends和super的區別

extends 可用於返回類型限定,不能用於參數類型限定。
super 可用於參數類型限定,不能用於返回類型限定。
>帶有super超類型限定的通配符可以向泛型對易用寫入,帶有extends子類型限定的通配符可以向泛型對象讀取

11.父類中的靜態方法能否被子類重寫

不能,

因爲靜態方法從程序開始運行後就已經分配了內存,也就是說已經寫死了。所有引用到該方法的對象(父類的對象也好子類的對象也好)所指向的都是同一塊內存中的數據,也就是該靜態方法。子類中如果定義了相同名稱的靜態方法,並不會重寫,而應該是在內存中又分配了一塊給子類的靜態方法,沒有重寫這一說。(最後一句話是自己理解,不知道說的對不對,歡迎大家批評指正)

12.進程和線程的區別

進程和線程的主要差別在於它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程。

1) 簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.

2) 線程的劃分尺度小於進程,使得多線程程序的併發性高。

3) 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。

4) 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

5) 從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

13.final,finally,finalize的區別

final 用於聲明屬性,方法和類, 分別表示屬性不可變, 方法不可覆蓋, 類不可繼承.
finally 是異常處理語句結構的一部分,表示總是執行.

finalize 是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等. JVM不保證此方法總被調用.

14.什麼是序列化,以及Serializable和Parcelable 的區別

簡單地說,“序列化”就是將運行時的對象狀態轉換成二進制,然後保存到流、內存或者通過網絡傳輸給其他端。

Serializable 有以下幾個特點:

  • 可序列化類中,未實現 Serializable 的屬性狀態無法被序列化/反序列化
  • 也就是說,反序列化一個類的過程中,它的非可序列化的屬性將會調用無參構造函數重新創建
  • 因此這個屬性的無參構造函數必須可以訪問,否者運行時會報錯
  • 一個實現序列化的類,它的子類也是可序列化的

實現了 Parcelable 接口的類在序列化和反序列化時會被轉換爲 Parcel 類型的數據

15.靜態屬性和靜態方法是否可以被繼承,是否可以被重寫,以及原因

父類的靜態屬性和方法可以被子類繼承,但不能被重寫,

原因 
static修飾函數/變量時,其實是全局函數/變量,它只是因爲java強調對象的要 
掛,它與任何類都沒有關係。靠這個類的好處就是這個類的成員函數調用static方法不用帶類名。

注意:static關鍵字可以用修飾代碼塊.static代碼塊可以置於類中的任何一個位置,並可以有多個static代碼塊。在類初次被加載時,會按照靜態代碼塊的順序來執行,並且只會執行一次。

16.內部類和閉包

方法中的局部變量會在執行結束後就會被釋放,但是內部類訪問此變量就形成了閉包

內部類使用外部的局部變量,實際上形成了閉包,也就是捕獲了所在方法內的變量,這個被捕獲的變量不能隨着方法的執行完畢而消失,因爲內部類的實例可能還會用到這個變量,所以需要 final 關鍵字來讓這個變量不消失(final 修飾的變量會轉爲常量,因此不會隨着方法的執行完畢而消失)。 

如果在內部類中使用到了外部方法的變量,需要使用 final 修飾,否則無法編譯通過,但如果使用的是 JDK8,那麼即便你不加final 修飾,也是可以編譯過的,因爲編譯器替你加上了。

17.String轉換成Integer的方式及原理

integer.parseInt(string str)方法調用Integer內部的 
parseInt(string str,10)方法,默認基數爲10,parseInt內部首先 
判斷字符串是否包含符號(-或者+),則對相應的negative和limit進行 
賦值,然後再循環字符串,對單個char進行數值計算Character.digit(char ch, int radix) 
在這個方法中,函數肯定進入到0-9字符的判斷(相對於string轉換到int), 

否則會拋出異常,數字就是如上面進行拼接然後生成的int類型數值。


此上內容來源於網絡,通過自己刪減加工得總結而成,僅供參考(不喜勿噴)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章