2019年7月Android面試題總結(初中級)附詳細答案——Java篇

目錄

1.Java的四個基本特性

2.抽象類和接口的區別

3.線程實現的方式

4.什麼是重載,什麼是重寫,有什麼區別?

5.關鍵字 final 和 static 是怎麼使用的

6.你所知道的設計模式有哪些

7.如何保證線程安全

8.多線程的等待喚醒主要方法

9.進程的優先級

11.進程和線程的區別

12.Serializable 和Parcelable 的區別

13.成員內部類、靜態內部類、局部內部類和匿名內部類的理解,以及項目中的應用

14.List,Set,Map的區別

15.ArrayMap和HashMap的對比

16.HashMap和HashTable的區別

17.ArrayList和LinkedList的區別,以及應用場景

18.數組和鏈表的區別

19.run()和start()方法區別


彙總一下最近面試碰到的問題,和一些我覺得需要特別注意的問題

Android面試題總結(初中級)附詳細答案——Android篇

1.Java的四個基本特性

  • 抽象:把現實生活某一類東西提取出來,成爲該類東西的共有特性。抽象一般分爲數據抽象和過程抽象,數據抽象是對象的屬性,過程抽象是對象的行爲特徵
  • 封裝:把客觀事物進行封裝成抽象類,該類的數據和方法只讓可信的類操作,對不可信的類隱藏。封裝分爲屬性的封裝和方法的封裝
  • 繼承:從已有的類中派生出新的類,新的類能吸收已有類的數據屬性和行爲,並能擴展新的能力
  • 多態:同一個行爲具有多個不同表現形式或形態的能力,多態的前提是類與類之間必須存在關係,要麼繼承,要麼實現

2.抽象類和接口的區別

  • 抽象類和接口分別給出了不同的語法定義(包括方法體、成員變量修飾符、方法修飾符)
  • 抽象是對類的抽象,接口是對行爲的抽象
  • 抽象所體現的是繼承關係,是一種”is-a”的關係,接口僅僅實現接口定義的契約,是一種”like-a”的關係
  • 抽象是自底向上抽象的,接口是自頂向下設計出來的

3.線程實現的方式

繼承Thread類、實現Runnable接口、使用ExecutorService、Callable、Future實現有返回結果的線程

4.什麼是重載,什麼是重寫,有什麼區別?

重載(Overloading):
(1)Overloading 是一個類中多態性的一種表現,讓類以統一的方式處理不同類型數據的一種手段。
多個同名函數同時存在,具有不同的參數個數/類型。
(2)重載的時候,方法名要一樣,但是參數類型和個數不一樣,返回值類型可以相同,也可以不相
同。無法以返回型別作爲重載函數的區分標準。
重寫(Overriding):
(1) 父類與子類之間的多態性,對父類的函數進行重新定義。即在子類中定義某方法與其父類有相
同的名稱和參數。
(2)若子類中的方法與父類中的某一方法具有相同的方法名、返回類型和參數表,則新方法將覆蓋
原有的方法。如需父類中原有的方法,可使用 super 關鍵字,該關鍵字引用了當前類的父類

5.關鍵字 final 和 static 是怎麼使用的

final 有着“終態的”“這是無法改變的”含義,阻止了多態和繼承。
具體使用有:
final 類不能被繼承,沒有子類,final 類中的方法默認是 final 的。
final 方法不能被子類的方法覆蓋,但可以被繼承。
final 成員變量表示常量,只能被賦值一次,賦值後值不再改變。
final 不能用於修飾構造方法。
注意:父類的 private 成員方法是不能被子類方法覆蓋的,因此 private 類型的方法默認是 final 類型
的。
static 表示“全局”或者“靜態”的意思,用來修飾成員變量和成員方法,也可以形成靜態 static 代
碼塊,但是 Java 語言中沒有全局變量的概念。

被 static 修飾的成員變量和成員方法獨立於該類的任何對象,static 對象可以在它的任何對象創建之
前訪問,無需引用任何對象。
static 前面也可用 public 或 private 來修飾,其中 private 是訪問權限限定,static 表示不要實例化
就可以使用。
主要用於靜態變量,靜態方法,static 代碼塊
靜態變量:對於靜態變量在內存中只有一個拷貝(節省內存),JVM 只爲靜態分配一次內存,在加
載類的過程中完成靜態變量的內存分配,可用類名直接訪問(方便),當然也可以通過對象來訪問(但
是這是不推薦的)。
靜態方法: 靜態方法可以直接通過類名調用,任何的實例也都可以調用,因此靜態方法中不能用 this
和 super 關鍵字,不能直接訪問所屬類的實例變量和實例方法(就是不帶 static 的成員變量和成員成
員方法),只能訪問所屬類的靜態成員變量和成員方法。因爲實例成員與特定的對象關聯!
static 代碼塊:atic 代碼塊也叫靜態代碼塊,是在類中獨立於類成員的 static 語句塊,可以有多個,
位置可以隨便放,它不在任何的方法體內,JVM 加載類時會執行這些靜態的代碼塊,如果 static 代
碼塊有多個,JVM 將按照它們在類中出現的先後順序依次執行它們,每個代碼塊只會被執行一次
static 和 final 一起使用:
static final 用來修飾成員變量和成員方法,可簡單理解爲“全局常量”!
對於變量,表示一旦給值就不可修改,並且通過類名可以訪問。
對於方法,表示不可覆蓋,並且可以通過類名直接訪問。
特別要注意一個問題:
對於被 static 和 final 修飾過的實例常量,實例本身不能再改變了,但對於一些容器類型(比如,
ArrayList、HashMap)的實例變量,不可以改變容器變量本身,但可以修改容器中存放的對象,這
一點在編程中用到很多。

6.你所知道的設計模式有哪些

Java 中一般認爲有 23 種設計模式,我們不需要所有的都會,但是其中常用的幾種設計模式應該去掌
握。下面列出了所有的設計模式。需要掌握的設計模式我單獨列出來了,當然能掌握的越多越好。
總體來說設計模式分爲三大類:
創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元
模式。
行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模
式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

6.1單例設計模式

最好理解的一種設計模式,分爲懶漢式和餓漢式

餓漢式:

public class Singleton {
// 直接創建對象
public static Singleton instance = new Singleton();
// 私有化構造函數
private Singleton() {
}
// 返回對象實例
public static Singleton getInstance() {
return instance;
}
}

懶漢式:

public class Singleton {
// 聲明變量
private static volatile Singleton singleton2 = null;
// 私有構造函數
private Singleton2() {
}
// 提供對外方法
public static Singleton2 getInstance() {
if (singleton2 == null) {
synchronized (Singleton2.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}

6.2工廠設計模式

工廠模式分爲工廠方法模式和抽象工廠模式。

1.工廠方法模式

工廠方法模式分爲三種:

普通工廠模式,就是建立一個工廠類,對實現了同一接口的一些類進行實例的創建。
多個工廠方法模式,是對普通工廠方法模式的改進,在普通工廠方法模式中,如果傳遞的字符串出錯,
則不能正確創建對象,而多個工廠方法模式是提供多個工廠方法,分別創建對象。
靜態工廠方法模式,將上面的多個工廠方法模式裏的方法置爲靜態的,不需要創建實例,直接調用即
可。

  • 普通工廠模式
public interface Sender {
public void Send();
}
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mail sender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
public class SendFactory {
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("請輸入正確的類型!");
return null;
}
}
}

 

  • 多個工廠方法模式

該模式是對普通工廠方法模式的改進,在普通工廠方法模式中,如果傳遞的字符串出錯,則不能正確
創建對象,而多個工廠方法模式是提供多個工廠方法,分別創建對象。

public class SendFactory {
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.send();
}
}
  • 靜態工廠方法模式,將上面的多個工廠方法模式裏的方法置爲靜態的,不需要創建實例,直接調用即可。
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.send();
}
}

 

2.抽象工廠模式

工廠方法模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包原則,所以,從設計角度考慮,有一定的問題,如何解決?就用到抽象工廠模式,創建多個工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼
 

public interface Provider {
public Sender produce();
}
public interface Sender {
public void send();
}
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("this is mail sender!");
}
}
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("this is sms sender!");
}
}
public class SendSmsFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
public class SendMailFactory implements Provider {
@Override
public Sender produce() {
return new MailSender();
}
}
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.send();
}
}


6.3建造者模式(Builder)

工廠類模式提供的是創建單個類的模式,而建造者模式則是將各種產品集中起來進行管理,用來
創建複合對象,所謂複合對象就是指某個類具有不同的屬性,其實建造者模式就是前面抽象工廠模式
和最後的 Test 結合起來得到的。

public class Builder {
private List<Sender> list = new ArrayList<Sender>();
public void produceMailSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new MailSender());
}
}
public void produceSmsSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new SmsSender());
}
}
}
public class TestBuilder {
public static void main(String[] args) {
Builder builder = new Builder();
builder.produceMailSender(10);
}
}

7.如何保證線程安全
 

  • 對非安全的代碼進行加鎖操作
  • 使用線程安全的類
  • 不要跨線程訪問共享變量
  • 使用final類型作爲共享變量
  • 對共享變量加鎖操作

8.多線程的等待喚醒主要方法

  • void notify():喚醒在此對象監視器上等待的單個線程
  • void notifyAll():喚醒在此對象監視器上等待的所有線程
  • void wait():導致當前的線程等待,直到其他線程調用此對象的notify()方法或notifyAll()方法
  • void wait(long timeout):導致當前的線程等待,直到其他線程調用此對象的notify()方法或notifyAll()方法,或者超過指定的時間量
  • void wait(long timeout, int nanos):導致當前的線程等待,直到其他線程調用此對象的notify()方法或notifyAll()方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量

9.進程的優先級

優先級從低到高排列,優先級最高的進程,最先獲取資源,最後釋放

1、空進程

這是Android系統優先殺死的,因爲此時該進程已經沒有任何用途

2、後臺進程

包含不可見的Activity,即跳轉到其他Activity後,由於資源不足,系統會將原來的Activity殺死(即跳轉的來源)

3、服務進程

即Service,當系統資源不足時,系統可能會殺掉正在執行任務的Service,因此在Service執行比較耗時的操作,並不能保證一定能執行完畢

4、可見進程

當前屏幕上可以看到的Activity,例如顯示一個對話框的Activity,那麼對話框變成了前臺進程,而調用他的Activity是可見進程,但並不是前臺的

5、前臺進程

當前處於最前端的Activity,也就是Android最後考慮殺死的對象,一般來說,前臺進程Android系統是不會殺死的,只有當前4個都殺掉資源依舊不夠纔可能會發生
10.java中==和equals和hashCode的區別

基本數據類型的==比較的值相等.

類的==比較的內存的地址,即是否是同一個對象,在不覆蓋equals的情況下,同比較內存地址,原實現也爲 == ,如String等重寫了equals方法.

hashCode也是Object類的一個方法。返回一個離散的int型整數。在集合類操作中使用,爲了提高查詢速度。(HashMap,HashSet等比較是否爲同一個)

如果兩個對象equals,Java運行時環境會認爲他們的hashcode一定相等。

如果兩個對象不equals,他們的hashcode有可能相等。

如果兩個對象hashcode相等,他們不一定equals。

如果兩個對象hashcode不相等,他們一定不equals。

11.進程和線程的區別

進程是cpu資源分配的最小單位,線程是cpu調度的最小單位。

進程之間不能共享資源,而線程共享所在進程的地址空間和其它資源。

一個進程內可擁有多個線程,進程可開啓進程,也可開啓線程。

一個線程只能屬於一個進程,線程可直接使用同進程的資源,線程依賴於進程而存在。

12.Serializable 和Parcelable 的區別

Serializable Java 序列化接口 在硬盤上讀寫 讀寫過程中有大量臨時變量的生成,內部執行大量的i/o操作,效率很低。

Parcelable Android 序列化接口 效率高 使用麻煩 在內存中讀寫(AS有相關插件 一鍵生成所需方法) ,對象不能保存到磁盤中

13.成員內部類、靜態內部類、局部內部類和匿名內部類的理解,以及項目中的應用

內部類主要分爲成員內部類局部內部類(嵌套在方法和作用域內)、匿名內部類(沒構造方法)、靜態內部類(static修飾的類,不能使用任何外圍類的非static成員變量和方法, 不依賴外圍類)

使用內部類最吸引人的原因是:每個內部類都能獨立地繼承一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。

因爲Java不支持多繼承,支持實現多個接口。但有時候會存在一些使用接口很難解決的問題,這個時候我們可以利用內部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設計問題。可以這樣說,接口只是解決了部分問題,而內部類使得多重繼承的解決方案變得更加完整。

14.List,Set,Map的區別

 

Set是最簡單的一種集合。集合中的對象不按特定的方式排序,並且沒有重複對象。 Set接口主要實現了兩個實現類:HashSet: HashSet類按照哈希算法來存取集合中的對象,存取速度比較快

TreeSet :TreeSet類實現了SortedSet接口,能夠對集合中的對象進行排序。

List的特徵是其元素以線性方式存儲,集合中可以存放重複對象。

ArrayList() : 代表長度可以改變得數組。可以對元素進行隨機的訪問,向ArrayList()中插入與刪除元素的速度慢。

LinkedList(): 在實現中採用鏈表數據結構。插入和刪除速度快,訪問速度慢。

Map 是一種把鍵對象和值對象映射的集合,它的每一個元素都包含一對鍵對象和值對象。 Map沒有繼承於Collection接口 從Map集合中檢索元素時,只要給出鍵對象,就會返回對應的值對象。

HashMap:Map基於散列表的實現。插入和查詢“鍵值對”的開銷是固定的。可以通過構造器設置容量capacity和負載因子load factor,以調整容器的性能。

LinkedHashMap: 類似於HashMap,但是迭代遍歷它時,取得“鍵值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點。而在迭代訪問時發而更快,因爲它使用鏈表維護內部次序。

TreeMap : 基於紅黑樹數據結構的實現。查看“鍵”或“鍵值對”時,它們會被排序(次序由Comparabel或Comparator決定)。TreeMap的特點在 於,你得到的結果是經過排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個子樹。

WeakHashMao :弱鍵(weak key)Map,Map中使用的對象也被允許釋放: 這是爲解決特殊問題設計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。

15.ArrayMap和HashMap的對比

1、存儲方式不同

HashMap內部有一個HashMapEntry<K, V>對象,每一個鍵值對都存儲在這個對象裏,當使用put方法添加鍵值對時,就會new一個HashMapEntry對象,

2、添加數據時擴容時的處理不一樣,進行了new操作,重新創建對象,開銷很大。ArrayMap用的是copy數據,所以效率相對要高。

3、ArrayMap提供了數組收縮的功能,在clear或remove後,會重新收縮數組,是否空間

4、ArrayMap採用二分法查找;

16.HashMap和HashTable的區別

HashMap不是線程安全的,效率高一點、方法不是Synchronize的要提供外同步,有containsvalue和containsKey方法。

hashtable是線程安全,不允許有null的鍵和值,效率稍低,方法是是Synchronize的。有contains方法方法。Hashtable 繼承於Dictionary 類

17.ArrayList和LinkedList的區別,以及應用場景

ArrayList是基於數組實現的,ArrayList線程不安全。

LinkedList是基於雙鏈表實現的:

使用場景:

(1) 如果應用程序對各個索引位置的元素進行大量的存取或刪除操作,ArrayList對象要遠優於LinkedList對象;

(2) 如果應用程序主要是對列表進行循環,並且循環時候進行插入或者刪除操作,LinkedList對象要遠優於ArrayList對象;

18.數組和鏈表的區別

數組:是將元素在內存中連續存儲的;它的優點:因爲數據是連續存儲的,內存地址連續,所以在查找數據的時候效率比較高;它的缺點:在存儲之前,我們需要申請一塊連續的內存空間,並且在編譯的時候就必須確定好它的空間的大小。在運行的時候空間的大小是無法隨着你的需要進行增加和減少而改變的,當數據兩比較大的時候,有可能會出現越界的情況,數據比較小的時候,又有可能會浪費掉內存空間。在改變數據個數時,增加、插入、刪除數據效率比較低。

鏈表:是動態申請內存空間,不需要像數組需要提前申請好內存的大小,鏈表只需在用的時候申請就可以,根據需要來動態申請或者刪除內存空間,對於數據增加和刪除以及插入比數組靈活。還有就是鏈表中數據在內存中可以在任意的位置,通過應用來關聯數據(就是通過存在元素的指針來聯繫)

19.run()和start()方法區別

這個問題經常被問到,但還是能從此區分出面試者對Java線程模型的理解程度。start()方法被用來啓動新創建的線程,而且start()內部調用了run()方法,這和直接調用run()方法的效果不一樣。當你調用run()方法的時候,只會是在原來的線程中調用,沒有新的線程啓動,start()方法纔會啓動新線程。

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