安卓面試題

橫豎屏切換時候Activity的生命周期

他切換時具體的生命周期是怎么樣的:

1、新建一個Activity,并把各個生命周期打印出來

2、運行Activity,得到如下信息

onCreate-->

onStart-->

onResume-->

3、按crtl+f12切換成橫屏時

onSaveInstanceState-->

onPause-->

onStop-->

onDestroy-->

onCreate-->

onStart-->

onRestoreInstanceState-->

onResume-->

4、再按crtl+f12切換成豎屏時,發(fā)現(xiàn)打印了兩次相同的log

onSaveInstanceState-->

onPause-->

onStop-->

onDestroy-->

onCreate-->

onStart-->

onRestoreInstanceState-->

onResume-->

onSaveInstanceState-->

onPause-->

onStop-->

onDestroy-->

onCreate-->

onStart-->

onRestoreInstanceState-->

onResume-->

不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執(zhí)行一次,切豎屏時會執(zhí)行兩次

設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執(zhí)行一次

設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執(zhí)行onConfigurationChanged方法

當前Activity產生事件彈出Toast和AlertDialog的時候Activity的生命周期不會有改變

Activity運行時按下HOME鍵(跟被完全覆蓋是一樣的):onSaveInstanceState --> onPause --> onStop,再次進入激活狀態(tài)時: onRestart -->onStart--->onResume

(1) final:修飾符(關鍵字),如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載

(2) finally:在異常處理時提供 finally 塊來執(zhí)行任何清除操作。如果拋出一個異常,那么相匹配的 catch 子句就會執(zhí)行,然后控制就會進入 finally塊(如果有的話)。

(3) finalize:方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。

如果兩個對象equals,Java運行時環(huán)境會認為他們的hashcode一定相等。

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

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

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

sleep()和wait()的區(qū)別

sleep()使當前線程進入停滯狀態(tài)(阻塞當前線程),讓出CUP的使用、目的是不讓當前線程獨自霸占該進程所獲的CPU資源,以留一定時間給其他線程執(zhí)行的機會;

   sleep()是Thread類的Static(靜態(tài))的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖并木有被釋放,其他線程無法訪問這個對象(即使睡著也持有對象鎖)。

  在sleep()休眠時間期滿后,該線程不一定會立即執(zhí)行,這是因為其它線程可能正在運行而且沒有被調度為放棄執(zhí)行,除非此線程具有更高的優(yōu)先級。

wait()方法是Object類里的方法;當一個線程執(zhí)行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去(釋放)了對象的機鎖(暫時失去機鎖,wait(long timeout)超時時間到后還需要返還對象鎖);其他線程可以訪問;

  wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。

  wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。

所以sleep()和wait()方法的最大區(qū)別是:

sleep()睡眠時,保持對象鎖,仍然占有該鎖;

wait()睡眠時,釋放對象鎖。

但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態(tài),從而使線程立刻拋出InterruptedException(但不建議使用該方法)。

Java GC機制主要完成3件事:

確定哪些內存需要回收

確定什么時候需要執(zhí)行GC

如何執(zhí)行GC

Java內存分配和回收的機制概括的說,就是:分代分配,分代回收。對象將根據存活的時間被分為:年輕代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法區(qū))

Java內存泄露與溢出的區(qū)別:

內存溢出就是你要求分配的內存超出了系統(tǒng)能給你的,系統(tǒng)不能滿足需求,于是產生溢出

而Java內存泄漏就是沒有及時清理內存垃圾,導致系統(tǒng)無法再給你提供內存資源

如何避免內存溢出:

從代碼層面進行優(yōu)化完善,盡量避免該情況發(fā)生

調整優(yōu)化服務器配置:

設置-Xms、-Xmx相等

設置NewSize、MaxNewSize相等

設置Heap size, PermGen space:

? Tomcat 的配置示例:修改 %TOMCAT_HOME%/bin/catalina.bat or catalina.sh

? 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:

?set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

如何避免內存泄露:

盡早釋放無用對象的引用

程序進行字符串處理時,盡量避免使用String,而應使用StringBuffer

盡量少用靜態(tài)變量

避免集中創(chuàng)建對象尤其是大對象,如果可以的話盡量使用流操作

盡量運用對象池技術以提高系統(tǒng)性能

不要在經常調用的方法中創(chuàng)建對象,尤其是忌諱在循環(huán)中創(chuàng)建對象

優(yōu)化配置

單例模式

? ?public class Singleton{}

懶漢模式

?private static Singleton instance = null;

?private Singleton() {

?}

?public static Singleton getInstance() {

? ? ?//懶漢模式(線程不安全)

? ? ?return instance == null ? new Singleton() : instance;

?}

線程安全懶漢模式

?private static Singleton instance = null;

?private Singleton() {

?}

?public static ?synchronized Singleton getInstance() {

? ? ?//懶漢模式(加鎖,線程安全)

? ? ? ? ?return instance == null ? new Singleton() : instance;

?}

餓漢模式

?//餓漢模式

?private static Singleton instance = new Singleton();

?private Singleton() {

?}

?public static Singleton getInstance() {

? ? ?return instance;

?}

變種餓漢模式

?餓漢變種模式

?private static Singleton instance = null;

?private Singleton() {

?}

?static {

? ? ?instance = new Singleton();

?}

?public static Singleton getInstance(){

? ? ?return instance;

?}

靜態(tài)內部類

? //靜態(tài)內部類

?private static class SingletonHolder {

? ? ?private static final Singleton INSTANCE = new Singleton();

?}

?private Singleton() {

?}

?public static Singleton getInstance() {

? ? ?return SingletonHolder.INSTANCE;

?}

雙重校驗鎖

?//雙重校驗鎖

?//volatile是一個類型[修飾符]

//(type specifier)。

// 它是被設計用來修飾被不同線程訪問和修改的變量。

// ?如果不加入 volatile,基本上會導致這樣的結果:

// 要么無法編寫多線程 程序,要么[編譯器] 失去大量優(yōu)化的機會

?private volatile static Singleton instance;

?private Singleton() {

?}

?public static Singleton getSingleton() {

? ? ?if (instance == null) {

? ? ? ? ?synchronized (Singleton.class) {

? ? ? ? ? ? ?if (instance == null) {

? ? ? ? ? ? ? ? ?instance = new Singleton();

? ? ? ? ? ? ?}

? ? ? ? ?}

? ? ?}

? ? ?return instance;

?}

觀察者模式

eg:

OnCLickListener

EventBus

冒泡排序

? ?public void bubbleSort(int[] a) {

? ?int temp = 0;

? ?for (int i = 0; i < a.length - 1; i++) {

? ? ? ?for (int j = 0; j < a.length - i - 1; j++) {

? ? ? ? ? ?if (a[j] > a[j + 1]) {

? ? ? ? ? ? ? ?temp = a[j];

? ? ? ? ? ? ? ?a[j] = a[j + 1];

? ? ? ? ? ? ? ?a[j + 1] = temp;

? ? ? ? ? ?}

? ? ? ?}

? ?}

}

查找排序

? ?public void selectorSort(int[] a) {

? ?for (int i = 0; i < a.length; i++) {

? ? ? ?int min = i;

? ? ? ?for (int j = i + 1; j < a.length; j++) {

? ? ? ? ? ?if (a[j] < a[min]) {

? ? ? ? ? ? ? ?min = j;

? ? ? ? ? ?}

? ? ? ?}

? ? ? ?if (i != min) {

? ? ? ? ? ?int tmp = a[i];

? ? ? ? ? ?a[i] = a[min];

? ? ? ? ? ?a[min] = tmp;

? ? ? ?}

? ?}

}

快速排序

? ?public void quickSort(int[] data, int start, int end) {

? ?// 設置關鍵數(shù)據key為要排序數(shù)組的第一個元素,

? ?// 即第一趟排序后,key右邊的數(shù)全部比key大,key左邊的數(shù)全部比key小

? ?int key = data[start];

? ?// 設置數(shù)組左邊的索引,往右移動比key大的數(shù)

? ?int i = start;

? ?// 設置數(shù)組右邊的索引,往左移動比key小的數(shù)

? ?int j = end;

? ?// 如果左邊索引比右邊索引小,則還有數(shù)據沒有排序

? ?while (i < j) {

? ? ? ?while (data[j] >= key && j > i) {

? ? ? ? ? ?j--;

? ? ? ?}

? ? ? ?data[i] = data[j];

? ? ? ?while (data[i] < key && i < j) {

? ? ? ? ? ?i++;

? ? ? ?}

? ? ? ?data[j] = data[i];

? ?}

? ?// 此時 i==j

? ?data[i] = key;

? ?// 遞歸調用

? ?if (i - 1 > start) {

? ? ? ?// 遞歸調用,把key前面的完成排序

? ? ? ?quickSort(data, start, i - 1);

? ?}

? ?if (i + 1 < end) {

? ? ? ?// 遞歸調用,把key后面的完成排序

? ? ? ?quickSort(data, i + 1, end);

? ?}

}

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

相關閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • 小編費力收集:給你想要的面試集合 1.C++或Java中的異常處理機制的簡單原理和應用。 當JAVA程序違反了JA...
    八爺君閱讀 5,152評論 1 114
  • 一、 1、請用Java寫一個冒泡排序方法 【參考答案】 public static void Bubble(int...
    獨云閱讀 1,494評論 0 6
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,753評論 11 349
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,988評論 0 11

友情鏈接更多精彩內容