Android&java基礎面試題總結(一)

java 創建對象的幾種方式

  1. 採用new
  2. 通過反射
  3. 採用clone:注意深度可能和淺度克隆
  4. 通過序列化機制
  • 面向對象的三個特徵
    封裝,繼承,多態
    封裝:把對象特徵數據化封裝起來
    繼承:繼承父類,複用數據和方法
    多態:重載和重寫的時候,對相同方法(方法名相同)做出不同的操作

  • 成員變量,

  1. 成員變量也稱爲實例變量,成員變量存儲在堆內存的對象中,所以也叫對象的特有數據。
  2. 靜態變量也稱爲類變量,靜態變量數據存儲在方法區(共享數據區)的靜態區,所以也叫對象的共享數據
  3. 局部變量只定義在局部範圍內,局部變量存在於棧內存中,作用的範圍結束,變量空間會自動釋放。

method(方法區)又叫靜態區,存放所有的①類(class),②靜態變量(static變量),③靜態方法,④常量和⑤成員方法。被所有的線程共享。方法區中存放的都是在整個程序中永遠唯一的元素。這也是方法區被所有的線程共享的原因。

String對象的intern()

public class Test1 {
    public static void main(String[] args) {
        String s11 = new String("aa");
        String s2 = s11.intern();
        String s3 = s11;
        String s1 = "aa";
        System.out.println(s1 == s2);//返回true
        System.out.println(s1 == s3);//返回false
    }
}

返回具體常量池裏具有相同值的字符串對象.
intern方法首先會查找常量池是否有相同值的字符串,如果有就返回,沒有就在常量池上創建對應字符串並返回.注意:如果本身這個字符串就在常量池裏,就返回對象本身,否則返回在常量池上新創建的對象,

String s1=”ab”, String s2=”a”+”b”, String s3=”a”, String s4=”b”, s5=s3+s4請問s5==s2返回什麼?

返回false。在編譯過程中,編譯器會將s2直接優化爲”ab”,會將其放置在常量池當中,s5則是被創建在堆區,相當於s5=new String(“ab”);

public class Test2 {
    public static void main(String[] args) {
    
        String s1 = "ab";
        String s2 = "a" + "b";
        String s3 = "a";
        String s4 = "b";
        String s5 = s3 + s4;//
        // 請問s5 == s2\

        System.out.println(s5 == s1);//false
        System.out.println(s2 == s1);//true
        System.out.println(s5 == s2);//false
    }
}

String s1=”ab” ;位於常量池
String s2=”a”+”b”;編譯的時候轉化成 s2=”ab”,類似s1,在常量池
String s3=”a”, String s4=”b”;在常量池,類似s1
String s5=s3+s4;位於堆,編譯器不知道這個s3,s4是否在常量池上,字符串實例化在堆上.

java中==和eqauls()的區別,equals()和hashcode相等的區別

==是一個比較運算符,基本數據類型比較的是值,引用數據類型比較的是地址值。
(比較地址值即是指是否爲同一個對象的引用)。

equals()是一個方法,只能比較引用數據類型。重寫前比較的是地址值,重寫後比一般是比較對象的屬性。
如果equals,那麼hashcode也要設計爲相等,否則會找出list的contains錯誤。所以在重寫eqauls方法的時候一定要重寫hashcode方法

深拷貝和淺拷貝的區別是什麼?

淺拷貝:被複制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。換言之,淺拷貝僅僅複製所考慮的對象,而不復制它所引用的對象。

深拷貝:被複制對象的所有變量都含有與原來的對象相同的值,而那些引用其他對象的變量將指向被複制過的新對象,而不再是原有的那些被引用的對象。換言之,深拷貝把要複製的對象所引用的對象都複製了一遍。

JAVA中的幾種基本數據類型是什麼,各自佔用多少字節

  • byte(1),char(2),short(2),int(4),boolean(4),float(4),long(8),double(8),boolean由環境虛擬機決定
  • 單例模式的幾種實現
    懶漢,餓漢,雙重檢驗,靜態內部類,枚舉
  • 在自己的代碼中,如果創建一個java.lang.String類,這個類是否可以被類加載器加
    載?
    不會,java類加載順序,優先加載系統的類

Java中字佔用字節

取決於java的編碼,linux裏面java默認編碼是utf-8,所佔字節有下面幾種情況:

  1. 佔2個字節的:帶有附加符號的拉丁文、希臘文、西裏爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則需要二個字節編碼
  2. 佔3個字節的:基本等同於GBK,含21000多個漢字
  3. 佔4個字節的:中日韓超大字符集裏面的漢字,有5萬多個;少數是漢字每個佔用3個字節,多數佔用4個字節。
  4. 一個utf8數字佔1個字節
  5. 一個utf8英文字母佔1個字節

JAVA運行時異常及常見的5中RuntimeExecption

ClassCastException(類轉換異常)
IndexOutOfBoundsException(數組越界)
NullPointerException(空指針)
SecurityException
數學上除以0的異常

hashmap 和hashtable;StringBuilder和StringBuffer的區別

  • hashmap key可以null,value 可以null,hashtable均不能爲null
  • hashtable線程安全,效率低,hashmap線程不安全,效率高
  • StringBuffer線程安全,效率低,StringBuilder線程不安全,效率高

hashSet,linkhashset,TreeSet

  • hashSet 效率最高,無序
  • linkhashset效率略低,有序
  • TreeSet效率最低,可以排序

Parcelable與Serializable的

序列化的目的:

  • 持久保存對象數據;講對象保存在文件中
  • 將對象數據序列化通過網絡以字節流方式進行傳輸
  • 序列化後進程間通訊

實現的兩種方式Serializable,Parcelable

  • Implements Serializable 接口 (聲明一下即可)
  • Implements Parcelable 接口(不僅僅需要聲明,還需要實現內部的相應方法)

Parcelable與Serializable的性能比較
Parcelable性能明顯高於Serializable

Serializable是通過ObjectOutputStram把序列化數據保存在磁盤,Parcelable一般跨進程傳遞保存在內存的數據,Parcelable如果也要保存到本地,需要利用Parcel方法marshall 和 unmarshall,把對數轉換爲byte數組。
Parcelable不能使用在要將數據存儲在磁盤上的情況,因爲Parcelable不能很好的保證數據的持續性在外界有變化的情況下。儘管Serializable效率低點,但此時還是建議使用Serializable 。

如何理解在外界發生改變後,Parcelable不能使用在要將數據存儲在磁盤上的情況不能很好的保證數據的持續性?
應該是磁盤序列化後在改變Parcelable實現類之後(外界發生改變後),Parcelable反序列會出現問題(不能保證數據的持續性).

java類中serialversionuid 作用 是什麼?舉個例子說明

serialVersionUID適用於Java的序列化機制。簡單來說,Java的序列化機制是通過判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,如果相同就認爲是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常,即是InvalidCastException。

具體的序列化過程是這樣的:序列化操作的時候系統會把當前類的serialVersionUID寫入到序列化文件中,當反序列化時系統會去檢測文件中的serialVersionUID,判斷它是否與當前類的serialVersionUID一致,如果一致就說明序列化類的版本與當前類版本是一樣的,可以反序列化成功,否則失敗。

幾種情況A端序列化,B端反序列化,參考https://www.cnblogs.com/duanxz/p/3511695.html:

  • 情況一:A端和B端都需要存在一個相同的類。如果兩處的serialVersionUID不一致,異常java.io.InvalidClassException

  • 情況二:假設兩處serialVersionUID一致,如果A端增加一個字段,然後序列化,而B端不變,然後反序列化;執行序列化,反序列化正常,但是A端增加的字段丟失(被B端忽略)

  • 情況三:serialVersionUID一致,如果B端減少一個字段,A端不變;序列化,反序列化正常,B端字段少於A端,A端多的字段值丟失(被B端忽略)。

  • 情況四:假設兩處serialVersionUID一致,如果B端增加一個字段,A端不變;說明序列化,反序列化正常,B端新增加的int字段被賦予了默認值

    情況三四五就是最終反序列化總是得到a和b兩最少的數據

靜態變量序列化:
序列化保存的是對象的狀態(成員變量的值),靜態變量屬於類的狀態,因此 序列化並不保存靜態變量
父類的序列化與 Transient 關鍵字
問題:一個子類實現了 Serializable 接口,它的父類都沒有實現 Serializable 接口,序列化該子類對象,然後反序列化後輸出父類定義的某變量的數值,該變量數值與序列化時的數值不同.
解決:要想將父類對象也序列化,就需要讓父類也實現Serializable 接口。如果父類不實現的話的,就 需要有默認的無參的構造函數。在父類沒有實現 Serializable 接口時,虛擬機是不會序列化父對象的,而一個 Java 對象的構造必須先有父對象,纔有子對象,反序列化也不例外。所以反序列化時,爲了構造父對象,只能調用父類的無參構造函數作爲默認的父對象。因此當我們取父對象的變量值時,它的值是調用父類無參構造函數後的值。如果你考慮到這種序列化的情況,在父類無參構造函數中對變量進行初始化,否則的話,父類變量值都是默認聲明的值,如 int 型的默認是 0,string 型的默認是 null。

Transient 關鍵字的作用是控制變量的序列化,在變量聲明前加上該關鍵字,可以阻止該變量被序列化到文件中,在被反序列化後,transient 變量的值被設爲初始值,如 int 型的是 0,對象型的是 null。

特性使用案例

我們熟悉使用 Transient 關鍵字可以使得字段不被序列化,那麼還有別的方法嗎?根據父類對象序列化的規則,我們可以將不需要被序列化的字段抽取出來放到父類中,子類實現 Serializable 接口,父類不實現,根據父類序列化規則,父類的字段數據將不被序列化

View的繪製流程(工作流程)

measure過程、layout過程、draw過程
measure:測量VIew的高度,寬度
layout:確定view的位置
draw:繪製view

service生命週期

startservice:onCreate->onstarCommand->onDestory
onbindeService:onCreate->onbind->onUnbide->onDestory

如何理解Activity,View,Window三者之間的關係?

這個問題真的很不好回答。所以先比較恰當的比喻來形容下它們的關係,Activity像一個工匠(控制單元),Window像窗戶(承載模型),View像窗花(顯示視圖)LayoutInflater像剪刀,Xml配置像窗花圖紙。

1:Activity構造的時候會初始化一個Window,準確的說是PhoneWindow。

2:這個PhoneWindow有一個“ViewRoot”,這個“ViewRoot”是一個View或者說ViewGroup,是最初始的根視圖。

3:“ViewRoot”通過addView方法來一個個的添加View。比如TextView,Button等

4:這些View的事件監聽,是由WindowManagerService來接受消息,並且回調Activity函數。比如onClickListener,onKeyDown等。

什麼情況下Activity走了onCreat(),而不走onStart()

直接在onCreate就finish掉activity、

Activity生命週期

  • onCreate:activity創建
  • onstart:顯示出界面,但是還不可以交互
  • onResume:可以交互,獲取焦點
  • onPaushe失去焦點
  • onStop:界面完全消失
  • onDestory:activity銷燬

請問Android中跨進程通訊有幾種方式

  • AIDL,binder
  • 廣播
  • 調用其他應用Activity
  • ContentProvider

ACtivity四種狀態

graph LR
開始 --> onCreate,onStart,onRestart,onResume
onCreate,onStart,onRestart,onResume --> 運行
運行 --> onpause
onpause --> 暫停
暫停 --> onstop
onstop --> 停止
停止 --> onDestory
onDestory --> 銷燬

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