最詳細全面的Android客戶端面試題含答案錦集;持續更新

前言

本篇面試題是整理單獨整理的一篇客戶端面試題,如果有補充非常感謝在評論區留言。更多其它一線互聯網面試題請點擊獲取面試資料;《大廠面試資料含答案詳解錦集》

這些題目是今年群友去百度、小米、樂視、美團、58、獵豹、360、新浪、搜狐等一線互聯網公司面試被問到的題目。並且大多數都整理了答案,熟悉這些知識點會大大增加通過前兩輪技術面試的幾率,

JAVA SE

1.九種基本數據類型的大小,以及他們的封裝類。

int Integer

short Short

long Long

byte Byte

float Float

double Double

char Char

boolean Boolean

String(不算基本數據類型) Stringbuffer、Stringbuilder(非線程安全)

2. Switch能否用string做參數?

Java 1.7之前只能支持byte、short、int、char或其封裝類及enum類型,1.7及以上才支持string,boolean類型也是不支持的,會報以下錯誤:Cannot switch on a value of type boolean. Only convertible int values or enum constants are permitted

3.equals與==的區別。

(1) 對字元串變數來說:==比較兩個對象的地址是否一致,equals比較兩個對象的值.

String s3 = 「abc」, s4 = 「abc」

String s1 = new String(「abc」);

String s2 = new String(「abc」);

s1 == s2 //false 因為兩個對象存放的地址不一致

s1.equals(s2) // true 因為兩個對象的值都是」abc」

(2) 對於基本數據類型,只能用==判斷,不能用equals(),而對於基本數據類型的封裝類或者其他自定義類(沒有重寫equals方法)來說,==比較的是地址,equals()比較的是內容

(3) s3 == s4 // true,因為s3和s4指向的都是同一塊內存地址

(4) StringBuffer s5 = new StringBuffer(「a」) ;

StringBuffer s6 = new StringBuffer(「a」) ;

s5.equals(s6) // false ,因為StringBuffer沒有重寫equals()方法,比較的還是內存地址,顯然兩個對象內存地址是不一樣的。

4.Object有哪些公用方法?

wait()、notify()、notifyAll()、equals()---用來比較兩個對象地址是否一致

hashCode() – 標誌對象的唯一值

toString() – 對象的字元串表達形式

5. Java的四種引用,強弱軟虛,用到的場景。

強引用(StrongReference)--- 強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。當內存空間不足,Java虛擬機寧願拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。

軟引用(SoftReference)---如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。

軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收器回收,Java虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。SoftReference是強引用,它保存的對象實例,除非JVM即將OutOfMemory,否則不會被GC回收。這個特性使得它特別適合設計對象Cache。對於Cache,我們希望被緩存的對象最好始終常駐內存,但是如果JVM內存吃緊,為了不發生OutOfMemoryError導致系統崩潰,必要的時候也允許JVM回收Cache的內存,待後續合適的時機再把數據重新Load到Cache中

弱引用(WeakReference)---WeakReference是弱引用,其中保存的對象實例可以被GC回收掉。這個類通常用於在某處保存對象引用,而又不干擾該對象被GC回收,通常用於Debug、內存監視工具等程序中。因為這類程序一般要求即要觀察到對象,又不能影響該對象正常的GC過程。

虛引用(PhantomReference)---就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命周期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。

虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之 關聯的引用隊列中。

6.HashCode的作用

對象區別於其他對象的標識

7. ArrayList、LinkedList、Vector的區別

ArrayList類似於C中的數組,查找方便,插入複雜,LinedList類似於C中的鏈表,插入簡單,查找複雜度較高。而Vector類似於ArrayList,但是在Java 1.5以後就不推薦使用了。

8. String、StringBuffer與StringBuilder的區別。

StringBuffer是String的封裝類,都是線程安全的,如果字元串的內容經常改變,則最好用,StringBuffer,而StringBuilder也是可變字元串,但是非線程安全,因此正常情況下會比StringBuffer快。

9. Map、Set、List、Queue、Stack的特點與用法。

map 根據key 找value

set 元素不能重複

list 類似數組

Queue 隊列,先進先出

Stack 棧,後進先出

10. HashMap和HashTable的區別。

1. 當需要同步時,用Hashtable,反之用HashMap。但是,因為在需要時,HashMap可以被同步,HashMap的功能比Hashtable的功能更多,而且它不是基於一個陳舊的類的,所以有人認為,在各種情況下,HashMap都優先於Hashtable。

2. 只有HashMap可以讓你將空值作為一個表的條目的key或value。HashMap中只有一條記錄可以是一個空的key,但任意數量的條目可以是空的value

11. HashMap和ConcurrentHashMap的區別,HashMap的底層源碼。

有並發訪問的時候用ConcurrentHashMap,效率比用鎖的HashMap好。

HashMap底層源碼用(Entry)數組+鏈表的形式實現

12. TreeMap、HashMap、LindedHashMap的區別。

LinkedHashMap也是一個HashMap,但是內部維持了一個雙向鏈表,可以保持順序

TreeMap 可以用於排序(根據鍵排序,默認是升序),HashSet是通過HashMap實現的,TreeSet是通過TreeMap實現的,只不過Set用的只是Map的key,Map的key和Set都有一個共同的特性就是集合的唯一性.TreeMap更是多了一個排序的功能.

13.Collection包結構,與Collections的區別。

Collection ---List ---ArrayList, LinkedList, Vector

Set ---HashSet, TreeSet

Map—HashMap,TreeMap,HashTable

Collection是集合類的上級介面,子介面主要有Set 和List、Map。

Collections是針對集合類的一個幫助類,提供了操作集合的工具方法:一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。

14. try catch finally,try里有return,finally還執行么?

必須執行.如果try里有return,finally也有return,會執行finally中的return.

15. Excption與Error包結構。OOM你遇到過哪些情況,SOF你遇到過哪些情況。

16. Java面向對象的三個特徵與含義。

繼承

封裝

多態.

17. Override和Overload的含義去區別。

override --- 重寫父類的函數

overload – 是函數重載,根據傳入的參數(個數、類型)不同來區別

18. Interface與abstract類的區別。

interface 是介面,可以有常量,所有方法都默認是public,而且不能實現

abstract類 比其他普通類多了個抽象方法,而且是必須有抽象方法

19. Static class 與non static class的區別。

內部靜態類不需要有指向外部類的引用。但非靜態內部類需要持有對外部類的引用。非靜態內部類能夠訪問外部類的靜態和非靜態成員。靜態類不能訪問外部類的非靜態成員。他只能訪問外部類的靜態成員

20. java多態的實現原理。

java中 實例方法才有多態的在運行時動態綁定類的成員變數是在編譯時就決定了

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: &quot;Courier New&quot; !important; font-size: 12px !important;">class A { int a =1; int method() { return a ;
}
} class B extends A { int a = 2 ; int Method() { return a ;
}
}
B bb = new B() ;
System.out.println(bb.a) //結果是2
System.out.println(bb.method() ) //結果是2
A aa =(B) new B() ;
System.out.println(aa.a ) // 結果是1
System.out.println(aa.method() ) //結果還是是2多態</pre>

21.實現多線程的兩種方法:Thread與Runable。

  1. 繼承Thread類,重寫run方法
  2. 實現Runnable介面
  3. 想要有返回值,用FutureTask,和Callable介面

例子:

public class CallableTest {
// 創建一個計算任務,返回累加結果,構造器的參數是上界
static class SumCaller implements Callable<Long> {
private Integer count;

public SumCaller(Integer count) {
this.count = count;
}

public Long call() throws Exception {
long sum = 0;
for (int i = 0; i < count; i++) {
sum += i;
}
return sum;
}
}

private static Integer COUNT = 1000000000;

public static void main(String[] args) throws InterruptedException,
ExecutionException {
SumCaller caller = new SumCaller(COUNT);
FutureTask<Long> task = new FutureTask<Long>(caller);

Thread thread = new Thread(task);
thread.start();

long sum = task.get();
System.out.println("sum from 1 to " + COUNT + " result = " + sum);

}
}

22. 線程同步的方法:synchronized、lock、reentrantLock等。

lock.lock(),加鎖,lock.unlock()釋放鎖,

reentrantLock,可重入鎖

synchronized 只有單一條件,不能設置加鎖時間等,也不能設置多個鎖

23. 鎖的等級:方法鎖、對象鎖、類鎖。

對象鎖是用於對象實例方法,或者一個對象實例上的,類鎖是用於類的靜態方法或者一個類的class對象上的,我們知道,類的對象實例可以有很多個,但是每個類只有一個class對象,所以不同對象實例的對象鎖是互不干擾的,但是每個類只有一個類鎖。

24. 寫出生產者消費者模式。

25. ThreadLocal的設計理念與作用。

Java中的ThreadLocal類允許我們創建只能被同一個線程讀寫的變數因此如果一段代碼含有一個ThreadLocal變數的引用即使兩個線程同時執行這段代碼它們也無法訪問到對方的ThreadLocal變數雖然所有的線程都能訪問到這個ThreadLocal實例但是每個線程卻只能訪問到自己通過調用ThreadLocal的set()方法設置的值即使是兩個不同的線程在同一個ThreadLocal對象上設置了不同的值他們仍然無法訪問到對方的值內部實現用同步Map
public class ThreadLocalExample {
public static class MyRunnable implements Runnable {
private ThreadLocal threadLocal = new ThreadLocal();
@Override
public void run() {
threadLocal.set((int) (Math.random() * 100D));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(threadLocal.get());
}
}
public static void main(String[] args) {
MyRunnable sharedRunnableInstance = new MyRunnable();
Thread thread1 = new Thread(sharedRunnableInstance);
Thread thread2 = new Thread(sharedRunnableInstance);
thread1.start();
thread2.start();
}
}

26. ThreadPool用法與優勢。

在多線程環境中使用Thread Pool,可以提高運行效率,不用每次新建一個線程,循環利用線程。

public class TestFixedThreadPool {
public static void main(String[] args) {
//創建一個可重用固定線程數的線程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//創建實現了Runnable介面對象,Thread對象當然也實現了Runnable介面
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
Thread t4 = new MyThread();
Thread t5 = new MyThread();
//將線程放入池中進行執行
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
//關閉線程池
pool.shutdown();
}
}

27. Concurrent包里的其他東西:ArrayBlockingQueue、CountDownLatch等等。

28. wait()和sleep()的區別。

1. sleep()不釋放同步鎖,wait()釋放同步鎖.

2. sleep是Thread類的方法,wait是Object的方法。wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用

29.foreach與正常for循環效率對比。

使用for,更高效率。 使用foreach,更安全。

如果在使用foreach遍歷對象的過程中,其他線程修改了List的內容,例如添加或者刪除,就會出現不可知的錯誤,而使用foreach則能夠正確拋出錯誤信息。

30. Java IO與NIO。

字元流:reader

writer

位元組流:inputStream

outputStream

NIO : Buffer和channel

31. 反射的作用與原理。

指的是我們可以於運行時載入、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以載入一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods.</pre>

用途:Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變數和方法;在運行時調用任意一個對象的方法;生成動態代理。</pre>

32.泛型常用特點,List<String>能否轉為List<Object>。

如果List<Object>作為函數參數,List<String>作為要傳進來的參數,答案是不能。正確理解泛型概念的首要前提是理解類型擦除(type erasure)。 Java中的泛型基本上都是在編譯器這個層次來實現的。在生成的Java位元組代碼中是不包含泛型中的類型信息的。使用泛型的時候加上的類型參數,會被編譯器在編譯的時候去掉。這個過程就稱為類型擦除。如在代碼中定義的List<Object>和List<String>等類型,在編譯之後都會變成List。JVM看到的只是List,而由泛型附加的類型信息對JVM來說是不可見的。

public void inspect(List<Object> list) {

for (Object obj : list) {

System.out.println(obj);

}

list.add(1); //這個操作在當前方法的上下文是合法的。 }public void test() {

List<String> strs = new ArrayList<String>();

inspect(strs); //編譯錯誤

}

public void wildcard(List<?> list) {

list.add(1);//編譯錯誤

}

如上所示,試圖對一個帶通配符的泛型類進行操作的時候,總是會出現編譯錯誤。其原因在於通配符所表示的類型是未知的。

因為對於List<?>中的元素只能用Object來引用,在有些情況下不是很方便。在這些情況下,可以使用上下界來限制未知類型的範圍。 如List<? extends Number>說明List中可能包含的元素類型是Number及其子類。而List<? super Number>則說明List中包含的是Number及其父類。當引入了上界之後,在使用類型的時候就可以使用上界類中定義的方法。比如訪問 List<? extends Number>的時候,就可以使用Number類的intValue等方法。

33. 解析XML的幾種方式的原理與特點:DOM、SAX、PULL。

DOM解析:將整個XML載入到內存中,比較方便插入和查找相鄰節點,但是耗內存,手機用得較少

SAX解析:simple API for XML,SAX解析XML文件採用的是事件驅動,進而調用一些回調方法(CallBack),比如

startDocument()

endDocument()

startElement(String namespaceURI, String localName, String qName, Attributes atts)

endElement(String uri, String localName, String name)

characters(char[] ch, int start, int length)

SAX解析適用於移動設備

PULL解析和SAX類似Android自帶jar包根據EventType來進行比如
XmlPullParser.START_DOCUMENT

XmlPullParser.END_DOCUMENT

XmlPullParser.START_TAG

XmlPullParser.END_TAG

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

XmlPullParser parser = factory.newPullParser();

parser.setInput(inputStream, "utf-8");

int eventType = parser.getEventType();

eventType = parser.next();

34. Java與C++對比。

35. Java1.7與1.8新特性。

1.7;

1. map集合支持並發請求,且可以寫成 Map map = {name:"xxx",age:18};

2.switch中可以使用字串了

3. 運用List<String> tempList = new ArrayList<>(); 即泛型實例化類型自動推斷

4. 兩個char間的equals bool Character.equalsIgnoreCase(char ch1, char ch2)

1.8;

1. lambda 表達式:

原來代碼:

List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");

Collections.sort(names, new Comparator<String>() {

@Override

public int compare(String a, String b) {

return b.compareTo(a);

}

});

加入lambda表達式:

Collections.sort(names, (String a, String b) -> {

return b.compareTo(a);

});

更簡潔:

Collections.sort(names, (String a, String b) -> b.compareTo(a));

更更簡潔:

Collections.sort(names, (a, b) -> b.compareTo(a));

36. 設計模式:單例、工廠、適配器、責任鏈、觀察者等等。

37. JNI的使用

JVM

  1. 內存模型以及分區,需要詳細到每個區放什麼。
  2. 堆裡面的分區:Eden,survival from to,老年代,各自的特點。
  3. 對象創建方法,對象的內存分配,對象的訪問定位。
  4. GC的兩種判定方法:引用計數與引用鏈。
  5. GC的三種收集方法:標記清除、標記整理、複製演算法的原理與特點,分別用在什麼地方,如果讓你優化收集方法,有什麼思路?
  6. GC收集器有哪些?CMS收集器與G1收集器的特點。
  7. Minor GC與Full GC分別在什麼時候發生?
  8. 幾種常用的內存調試工具:jmap、jstack、jconsole。
  9. 類載入的五個過程:載入、驗證、準備、解析、初始化。
  10. 雙親委派模型:Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader。
  11. 分派:靜態分派與動態分派。

持續更新中~

更多其它一線互聯網面試題請點擊獲取面試資料;《大廠面試資料含答案詳解錦集》


推薦閱讀:

如何在Android Studio下進行NDK開發
有哪些 Android 功能讓你相見恨晚?
為什麼蘋果手機的觸摸體驗比安卓好?
安卓和蘋果哪個更適合父母用?
手機(硬體或者系統)上有那些神一般的設計?

TAG:Android | 程序員面試 |