1、闡述下對象的自動裝箱和拆箱 2
基本數據類型的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。
自動裝箱是java編譯器在java原生類型和對應的對象包裝類型上做的自動轉換。
自動裝箱:Integer i = 1;其實編譯器為你自動實現了:Integer i = Integer.valueOf(1);自動拆箱:Integer i = 1;int a = i;實際上執行了:int a = i.intValue();
復制代碼
int與integer的區別:
int 是基本類型,直接存數值,進行初始化時int類的變量初始為0。
integer是對象,用一個引用指向這個對象,Integer的變量則初始化為null。
復制代碼
2、switch支持的數據類型
包括byte、short、char、int 和 enum ,及包裝類型Character、Byte、Short和Integer,java7后又加入了對String的支持。闡述下支持String的原理:使用字符串的hash值作為表達式的值,而由于相同哈希值的情況下仍存在沖突的可能,所有在case語句塊時仍需要通過equals方法來判斷相等。
復制代碼
3、equals、==、hashCode:
== : 比較引用地址的相等或基本數據類型/枚舉類型的相等Equal:對象的值情況的相等hashCode:返回對象的存儲地址關系:兩對象比較:euqals返回true時,hashCode也相等。hashCode相等時,equals返回不一定相等。instanceof: 判斷對象類型5是否相等,當父、子類判斷時存在單向情況。 對象判斷equals方法:1、 == 判斷引用地址 2、instanceof 判斷類型 3、屬性匹配4、自反性、對稱性、傳遞性、一致性 5、重寫hashcode
復制代碼
甲學生的年齡 :16 ,學號: 12345 乙學生的年齡 :16, 學號: 54321 這樣甲和乙的hashcode 重寫方式一樣的 1 + 2+ 3+ 4+ 5 +(16*1 )= 31 但是 12345 不equals 54321
4、創建對象:
主要有以下四種對象創建方式:
1、new 2、反射 (這倆要調用構造函數) 3、clone 4、 反序列化
其中:
克隆:通過實現Cloneable、Serializable(序列化、反序列化實現)來實現對象的克隆反射:該方式的表現主要有:1、運行時取得字段與方法和修改(包括常量) 2、創建對象原理:jvm通過字節碼文件生成相應的對象或獲取其信息優缺點:增加了程序設計的靈活性;性能消耗較大
復制代碼
5、簡述下多態,Java多態的實現原理?動態綁定的理解?:
1、面向對象的三大特性:封裝、繼承、多態。
2、多態的定義:同一消息可以根據函數調用的不同而采用多種不同的行為方式。(發送消息就是函數調用)
3、多態的作用:消除類型之間的耦合關系(解耦)。
4、三個必要條件: 一、要有繼承; 二、要有重寫; 三、父類引用指向子類對象。重載:同一類中,同名函數不同的參數形式,基于對象實際的類型來選擇所調用的方法,達到動態綁定的目的。重寫:父類、子類中,同名同參方法,重新定義方法實現。區別: 前者編譯時多態性、后者運行時多態性(靜態方法除外,多態是針對實例方法)
復制代碼
將一個方法調用同一個方法主體關聯起來被稱作綁定,JAVA中分為 前期綁定和后期綁定(動態綁定或運行時綁定),
前期綁定: 在程序執行之前進行綁定(由編譯器和連接程序實現)叫做前期綁定,因為在編譯階段被調用方法的直接地址就已經存儲在方法所屬類的常量池中了,程序執行時直接調用。
后期綁定: 含義就是在程序運行時根據對象的類型進行綁定,想實現后期綁定,就必須具有某種機制,以便在運行時能判斷對象的類型,從而找到對應的方法,簡言之就是必須在對象中安置某種“類型信”,JAVA中除了static方法、final方法(private方法屬于)之外,其他的方法都是后期綁定。
Java技術----多態的實現原理
6、簡述下抽象類和接口區別:
1、接口是對動作的抽象(實現),抽象類是對根源的抽象。(繼承)
2、接口是抽象類的變體,接口中所有的方法都是抽象的。而抽象類是聲明方法的存在而不去實現它的類。
3、抽象類要被子類繼承,接口要被類實現。
4、接口里定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量。
5、抽象類里的抽象方法必須全部被子類所實現,如果子類不能全部實現父類抽象方法,那么該子類只能是抽象類。同樣,一個實現接口的時候,如不能全部實現接口方法,那么該類也只能為抽象類。
6、抽象類里可以沒有抽象方法
7、如果一個類里有抽象方法,那么這個類只能是抽象類抽象類:區別與普通的類,不能直接被實例化,可以有構造函數,并且子類可不實現其抽象方法。接口:修飾符為public、變量為final,沒有實際的方法,可實現多繼承。復制代碼
抽象類的意義:
抽象方法:由abstract修飾的方法為抽象方法,抽象方法只有方法的定義,沒有方法的實現。
抽象類:一個類中如果包含抽象方法,該類應該用abstract關鍵字聲明為抽象類。
抽象類不可以實例化,即使一個類中沒有抽象方法,也可以將其定義為抽象類意義:
a.為子類提供公共的方法
b.封裝子類中重復內容(成員變量和方法)
c.定義有抽象方法,子類有不同的實現,
復制代碼
7、簡述public、protected、private、default 的區別:2
也叫 作用域修飾詞public 作用范圍:當前類、同一個包、子類、其他包;
protected 作用范圍:當前類、同一個包、子類;
default 作用范圍:當前類、同一個包;
private 作用范圍:當前類;
復制代碼
8、簡述下創建線程的方式:
1、直接通過new thread 的方式;2、實現runnable接口;3、通過接口callable (callable能拿到返回值和拋出異常);4、通過線程池來生成線程;
復制代碼
9、sleep、wait、yield、notify、notifyall:
sleep和yield區別:sleep 給予線程的運行機會 不考慮優先級,then 阻塞 yield:給優先級高的線程執行,然后進入就緒狀態wait和sleep區別:wait:釋放對象鎖 object的方法 —> notifysleep:不釋放鎖 thread的方法兩者都可通過interrupted 打斷暫 notify和notifyall區別:notify:喚醒的某一線程去得到鎖notifyall:喚醒所有等待線程去競爭鎖wait/notify/notifyall : 它們都需在同步塊中調用 ,均可釋放對象鎖;wait:立即釋放控制權 然阻塞(需notify) notify:執行完再釋放復制代碼
10、synchronized 、Lock區別:
synchronized:關鍵字
Lock:對象 可控制獲取鎖的時間與獲取鎖的信息
手動釋放鎖、讓線程響應中斷、可知獲得鎖與否
多線程競爭較激烈時,Lock較優上下文切換:cpu控制權由一個正在運行的線程切換到另一個就緒狀態的線程
復制代碼
11、異常處理:
Error、Exception:
父類:Throwable :含異常出現時的log
Error:系統級錯誤,如OOM
Exception:需程序捕捉和處理的程序設計性錯誤被檢查異常(throw、try catch)、運行時異常Throw:方法中拋出異常
Throws:申明異常
try catch finally:try中有return 會記錄返回值 待finally執行完 返回值不變如finally中有return 則值會變finally:釋放外部資源
復制代碼
12、簡述下JVM內存模型: 2
JVM的內存模型主要可以分為線程共享區和線程私有區,
線程共享區:java堆(放對象和數組、GC)、方法區(類信息、常量、靜態變量等,永久代);
線程私有區:程序計數器(指示代碼執行、無oom)、Java虛擬機棧(java方法調用)、native方法棧;
而每個線程都有自己的棧內存, 堆是共享的,線程會緩存對象到棧中使用,而volatile則可要求線程從內存中讀取
復制代碼
13、簡述下GC機制:2
判斷對象內存是否該被回收:JVM根據可達性分析(引用計數會出現互相引用的情況)
java內存回收算法大概可分為:分年代回收:年輕代(創建)、老年代(呆的久)、永久代標記-復制算法:區域分兩塊 一塊使用另一塊回收 交替使用空閑區滿時 就被復制到老年代區標記-清除、標記-整理算法
復制代碼
14、算法
排序(必須手寫會)
//冒泡 排序
public static void BubbleSort(int [] arr){int temp;//臨時變量for(int i=0; i<arr.length-1; i++){ //表示趟數,一共arr.length-1次。for(int j=arr.length-1; j>i; j--){if(arr[j] < arr[j-1]){temp = arr[j];arr[j] = arr[j-1];arr[j-1] = temp;}}}}復制代碼
排序算法總結
查找()
復制代碼
15、java中的基本數據類型?各占多少位?多少字節?取值范圍?String是基本類型還是引用類型?
基本數據類型(8種):
1.Int 32 4 -2,147,483,648 ~ 2,147,483,647
2.Short 16 2 -32768 ~ 32678
3.long 64 8 -9,223,372,036,854,775,808~+9,223,372,036,854,775,807
4.float 32 4 -3,40292347E+38 ~ +3,40292347E+38
5.double 64 8 -1.79769313486231576E+308 ~ 1.79769313486231576E+308
6.char 16 2 ‘\u0000′ ~ ‘\uFFFF’
7.boolean 1 0.125 true/false
8.byte 8 1 -128 ~ 127String是引用類型,
復制代碼
16、Java什么時候是值傳遞什么時候是引用傳遞?
值傳遞的時候,將實參的值,copy一份給形參;
引用傳遞的時候,將實參的地址值,copy一份給形參。
不管是值傳遞還是引用傳遞,形參拿到的僅僅是實參的副本,而不是實參本身。
復制代碼
Java到底是值傳遞?還是引用傳遞?
17、String相關的。String常量池,StringBuffer,StringBuilder。String不可變的理解。String的intern方法不同版本的實現原理的區別。
String常量池:
JVM為了提高性能和減少內存開銷,在實例化字符串常量的時候進行了一些優化。為了減少在JVM中創建的字符串的數量,字符串類維護了一個字符串池,每當代碼創建字符串常量時,JVM會首先檢查字符串常量池。如果字符串已經存在池中,就返回池中的實例引用。如果字符串不在池中,就會實例化一個字符串并放到池中。 Java能夠進行這樣的優化是因為字符串是不可變的,可以不用擔心數據沖突進行共享.
留意文章中的面試題: (貌似被虐過!!!) String之常量池小結
String常量池,StringBuffer,StringBuilder, CharSequence的區別:
1、執行效率 :StringBuilder > StingBuffer > String
2、String 字符串常量 不可變,(通過不斷的創建新的對象修改長度)
StringBuffer 字符串變量(線程安全)
StringBuilder 字符串變量(非線程安全)
3、String 、StringBuffer 、StringBuilder 都實現了:CharSequence接口。
a++與++a的區別,如果單獨使用沒有任何區別,如果在運算中就有區別了,
a++是先運算在賦值,
而++a是先賦值在運算!!
String不可變的理解:
舉個例子:String str = "aa"; str = "aa"+"bb";
此時str的值為"aabb",但是"aabb"不是在開始的字符串"aa"后面直接連接的"bb",而是又新生成了字符串"aabb",字符串"aa"一旦被初始化,那么它的值不可能再改變了。
StringBuffer strb = StringBuffer("aa"); strb.append("bb");
此時的strb的值也為"aabb",但是"aabb"是直接在開始的字符串"aa"后面連接的“bb”,并沒有生成新的字符串。String對象的底層實際上是一個char[]數組:
private final char value[];
用final修飾的對象值可變,但是引用不變,StringBuffer對象的底層也是一個char[]數組:
char[] value; 復制代碼
為什么String對象不可變,而StringBuffer可變?
18、JAVA集合框架
-
Collection:存儲單個數據或者對象。
- |-List:列表:
- |-LinkedList :基于鏈表的List
- |-ArrayList :基于數組的List
- |-SubList:一個List的視圖
- |-Vector:一個線程安全的List
- |-Stack:棧
- **|-Queue:隊列 ,通常作為數據存儲結構,不作為操作容器。**集合框架中應用比較少,主要在在并發包(java.util.concurrent)中實現的阻塞隊列(消息隊列)。
- |-ArrayDeque:基于數組實現的尾插隊列(包含head,tail頭尾指針).
- |-PriorityQueue:基于數組的自排序優先級隊列(基于數組實現存儲的二叉樹堆排)。
- |-Set:一個不允許重復數據的集合
- |-HashSet:基于Hash+數組+鏈表實現的Set。
- |-LinkedHashSet:一個基于LinkedHashMap實現的Set。
- |-TreeSet:一個基于TreeMap實現的Set。
- |-EnumSet:
- |-JumboEnumSet
- |-RegularEnumSet
- |-HashSet:基于Hash+數組+鏈表實現的Set。
- |-List:列表:
-
Map:存儲一組K-V鍵值對。
- |-HashMap:基于Hash+數組+鏈表實現的Map。
- |-LinkedHashMap:基于HashMap實現的雙向鏈表。LruCache實現基礎
- |-HashTable:基于Hash+數組+鏈表實現的線程安全(sync)Map。
- |-TreeMap:基于紅黑樹實現的有序Map。
- |-WeakHashMap:K為弱引用的HashMap,使用中,若k沒有被引用則會自動回收掉
- |-HashMap:基于Hash+數組+鏈表實現的Map。
集合框架中唯一的兩個線程安全集合
Vector(Stack是Vector的子類也是安全的)
Hashtable
復制代碼
ArrayList,LinkedList異同點:
- 相同點:
- List是數組的封裝接口,所有實現類都可與數組轉換,且進行index(索引下標)獲取,對于ArrayList和LinkedList只不過是不同的實現方式
- 不同點:
- ArrayList是對數組的封裝,使得對數組的操作更加方便,查詢快,增刪慢。LinkedList是鏈表的實現,增刪快,查詢慢
HashMap,HashTable中的關聯和差異:
HashMap與HashTable最大的區別在于hashtable是線程安全的, hashMap K-V都可為null,hashTable K-V都不能夠為null.
ArrayList和Vector的比較:
- 相同點: 兩個類都實現了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,相當于一種動態的數組,
- 不同點:
- Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不同步的
- ArrayList與Vector都有一個初始的容量大小,當存儲進它們里面的元素的個數超過了容量時,就需要增加ArrayList與Vector的存儲空間,Vector增長原來的一倍,ArrayList增加原來的0.5倍。
補充: 底部的數據結構?散列表沖突的處理方法,散列表是一個什么樣的數據結構?HashMap是采用什么方法處理沖突的?
HashMap 采用一種所謂的“Hash 算法”來決定每個元素的存儲位置。
當程序執行 map.put(String,Obect)方法 時,系統將調用String的 hashCode() 方法得到其 hashCode 值——每個 Java 對象都有 hashCode() 方法,都可通過該方法獲得它的 hashCode 值。
得到這個對象的 hashCode 值之后,系統會根據該 hashCode 值來決定該元素的存儲位置。
HashMap采用的鏈表法的方式,鏈表是單向鏈表。
鏈表法就是將相同hash值的對象組織成一個鏈表放在hash值對應的槽位;當創建 HashMap 時,有一個默認的負載因子(load factor),其默認值為 0.75,
增大負載因子可以減少 Hash 表(就是那個 Entry 數組)所占用的內存空間,但會增加查詢數據的時間開銷,而查詢是最頻繁的的操作(HashMap 的 get() 與 put() 方法都要用到查詢);
減小負載因子會提高數據查詢的性能,但會增加 Hash 表所占用的內存空間。http://blog.csdn.net/u011202334/article/details/51498893
復制代碼
集合面試題1 集合面試題2 集合框架 Java容器框架
19、Java容器相關的輔助類Arrays和Collections了解一下(看那個傻逼問!)。
- Array與Arrays的區別:
- Array :數組類 ,提供了動態創建和訪問 Java 數組的方法。
- Arrays:工具類,該類中包含了一些方法用來直接操作數組,比如可直接實現數組的排序(sort())、搜索(binarySearch())等。
- Collection和Collections的區別:
- Collection:集合接口(集合類的一個頂級接口)
- Collections:集合類的一個工具類/幫助類,其中提供了一系列靜態方法,用于對集合中元素進行排序、搜索以及線程安全等各種操作。
20、Java中final,finalize()和finally的區別:
- final:關鍵字,可以用于類,方法,變量前,用來表示該關鍵字修飾的類,方法,變量具有不可變的特性
- final關鍵字用于基本數據類型前:這時表明該關鍵字修飾的變量是一個常量,在定義后該變量的值就不能被修改。
- final關鍵字用于方法聲明前:這時意味著該方法時最終方法,只能被調用,不能被覆蓋,但是可以被重載。
- final關鍵字用于類名前:此時該類被稱為最終類,該類不能被其他類繼承。
- finalize():finalize方法來自于java.lang.Object,用于回收資源。
- 可以為任何一個類添加finalize方法。finalize方法將在垃圾回收器清除對象之前調用。 在實際應用中,不要依賴使用該方法回收任何短缺的資源,這是因為很難知道這個方法什么時候被調用。
- finally:當代碼拋出一個異常時,就會終止方法中剩余代碼的處理,并退出這個方法(代碼塊)的執行。 finally try catch 順序問題
21、Java怎樣開啟一個線程。線程池是干什么的?有哪些常用的線程池?優缺點是什么?
開啟線程的方式:
1、繼承Thread類:
//1):定義一個類A繼承于java.lang.Thread類.
class MusicThread extends Thread{ //2):在A類中覆蓋Thread類中的run方法. public void run() { //3):在run方法中編寫需要執行的操作 for(int i = 0; i < 50; i ++){ System.out.println("播放音樂"+i); } }
} public class ExtendsThreadDemo { public static void main(String[] args) { for(int j = 0; j < 50; j ++){ System.out.println("運行游戲"+j); if(j == 10){ //4):在main方法(線程)中,創建線程對象,并啟動線程. MusicThread music = new MusicThread(); music.start(); } } } }
復制代碼
2、實現Runnable接口:
//1):定義一個類A實現于java.lang.Runnable接口,注意A類不是線程類.
class MusicImplements implements Runnable{ //2):在A類中覆蓋Runnable接口中的run方法. public void run() { //3):在run方法中編寫需要執行的操作 for(int i = 0; i < 50; i ++){ System.out.println("播放音樂"+i); } }
} public class ImplementsRunnableDemo { public static void main(String[] args) { for(int j = 0; j < 50; j ++){ System.out.println("運行游戲"+j); if(j == 10){ //4):在main方法(線程)中,創建線程對象,并啟動線程 MusicImplements mi = new MusicImplements(); Thread t = new Thread(mi); t.start(); } } } }
復制代碼
3、直接在函數體使用(特殊的第二種):
void java_thread()
{ Thread t = new Thread(new Runnable(){ public void run(){ // run方法具體重寫mSoundPoolMap.put(index, mSoundPool.load(filePath, index)); getThis().LoadMediaComplete(); }}); t.start();
}
復制代碼
補:繼承方式和實現方式的區別?(遇到過)
- 繼承方式:
- 從設計上分析,Java中類是單繼承的,如果繼承了Thread了,該類就不能再有其他的直接父類了.
- 從操作上分析,繼承方式更簡單,獲取線程名字也簡單.(操作上,更簡單)
- 從多線程共享同一個資源上分析,繼承方式不能做到.
- 實現方式:
- 從設計上分析,Java中類可以多實現接口,此時該類還可以繼承其他類,并且還可以實現其他接口,設計更為合理.
- 從操作上分析,實現方式稍微復雜點,獲取線程名字也比較復雜,得使用Thread.currentThread()來獲取當前線程的引用.
- 從多線程共享同一個資源上分析,實現方式可以做到(是否共享同一個資源).
線程池構成
- 線程池管理器(ThreadPool):用于創建并管理線程池,包括 創建線程池,銷毀線程池,添加新任務;
- 工作線程(PoolWorker):線程池中線程,在沒有任務時處于等待狀態,可以循環的執行任務;
- 任務接口(Task):每個任務必須實現的接口,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完后的收尾工作,任務的執行狀態等;
- 任務隊列(taskQueue):用于存放沒有處理的任務。提供一種緩沖機制。
有哪些常用的線程池?優缺點是什么?
線程生命周期:
幾個方法的比較:
-
Thread.sleep(long millis),thread 方法,一定是當前線程調用此方法,當前線程進入阻塞,但**不釋放對象鎖,millis后線程自動蘇醒進入可運行狀態。**作用:給其它線程執行機會的最佳方式。
-
obj.wait(),obj方法,當前線程調用對象的wait()方法,當前線程釋放對象鎖,進入等待隊列。依靠notify()/notifyAll()喚醒或者wait(long timeout)timeout時間到自動喚醒。
-
Thread.yield(),一定是當前線程調用此方法,當前線程放棄獲取的cpu時間片,**由運行狀態變會可運行狀態,讓OS再次選擇線程。**作用:讓相同優先級的線程輪流執行,但并不保證一定會輪流執行。實際中無法保證yield()達到讓步目的,因為讓步的線程還有可能被線程調度程序再次選中。Thread.yield()不會導致阻塞。
-
t.join()/t.join(long millis),當前線程里調用其它線程1的join方法,當前線程阻塞,但不釋放對象鎖,直到線程1執行完畢或者millis時間到,當前線程進入可運行狀態。
-
obj.notify() 喚醒在此對象監視器上等待的單個線程,選擇是任意性的。notifyAll()喚醒在此對象監視器上等待的所有線程。
22、volidate關鍵字的作用?
- volatile關鍵字不但可以防止指令重排
- 保證線程訪問的變量值是主內存中的最新值。
什么是單例模式? Volidate的原理和指令重排序
23、Java clone的使用。
Person p = new Person(23, "zhang");
Person p1 = (Person) p.clone(); System.out.println(p);
System.out.println(p1); 打印結果:
//com.pansoft.zhangjg.testclone.Person@2f9ee1ac
//com.pansoft.zhangjg.testclone.Person@67f1fba0
復制代碼
Java中的clone方法
24、Java反射機制
反射機制:是程序在運行時能夠獲取自身的信息。
在java中,只要給定類的名字,那么就可以通過反射機制來獲得類的所有信息。
復制代碼
提供的功能: 在運行時能夠判斷任意一個對象所屬的類 在運行時構造任意一個類的對象 在運行時判斷任意一個類所具有的成員變量和方法 在運行時調用任一對象的方法 在運行時創建新類對象
反射機制的優缺點:
- 優點:反射機制的優點就是可以實現動態創建對象和編譯,體現出很大的靈活性
- 缺點:對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿足我們的要求。這類操作總是慢于只直接執行相同的操作。
25、Java靜態代理和動態代理
Java靜態代理和動態代理
26、類的加載過程,Person person = new Person();為例進行說明
類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然后在堆區創建一個這個類的java.lang.Class對象,用來封裝類在方法區類的對象。
類從被加載到內存開始,到卸載出內存為止,其整個生命周期: 加載,驗證,準備,解析,初始化,使用,卸載
其中:驗證,準備,解析三個階段又統稱為“連接”
類加載的過程:
包括:加載,驗證,準備,解析和初始化等5個階段。
阿里、百度 都問過 自己看著辦!
27、什么是內部類?內部類的作用
1、內部類( Inner Class )就是定義在另外一個類里面的類。與之對應,包含內部類的類被稱為外部類。2、作用:a.內部類提供了更好的封裝,可以把內部類隱藏在外部類之內,不允許同一個包中的其他類訪問該類b.內部類的方法可以直接訪問外部類的所有數據,包括私有的數據c.內部類所實現的功能使用外部類同樣可以實現,只是有時使用內部類更方便
復制代碼
28、泛型通配符extends與super的區別:
<? extends T> 限定參數類型的上界:參數類型必須是T或T的子類型<? super T> 限定參數類型的下界:參數類型必須是T或T的超類型
復制代碼
29、進程和線程的區別
1、一個程序至少有一個進程,一個進程至少有一個線程.
2、進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
3、每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中
復制代碼
30、序列化的方式,以及Serializable 和Parcelable 的區別:
- Serializable和Parcelable接口可以完成對象的序列化過程,當我們需要通過Intent和Binder傳輸數據時就需要使用者兩種序列化方式。
- Serializable 屬于JAVA API,Parcelable 屬于Android SDK,
- Serializable 序列化和反序列化過程需要大量的I/O操作,Parcelable 不需要。
- Serializable 開銷大,效率低,Parcelable 反之。
- Serializable 序列化到本地或者通過網絡傳輸, Parcelable 內存序列化
31、靜態內部類與非靜態內部類之間區別
非靜態內部類在編譯完成之后會隱含地保存著一個引用,該引用是指向創建它的外圍內,但是靜態內部類卻沒有。
復制代碼
java中靜態內部類的設計意圖
32、Thread中start()和run()的區別;
start():作用是啟動一個新線程,新線程會執行相應的run()方法。start()不能被重復調用。
run():和普通的成員方法一樣,可以被重復調用。單獨調用run()的話,會在當前線程中執行run(),
而并不會啟動新線程!
復制代碼
java高級部分:都搞明白 就要30K吧!!!
- 哪些情況下的對象會被垃圾回收機制處理掉?
- 講一下常見編碼方式?
- utf-8編碼中的中文占幾個字節;int型幾個字節?
- 靜態代理和動態代理的區別,什么場景使用?
- Java的異常體系
- 談談你對解析與分派的認識。
- 修改對象A的equals方法的簽名,那么使用HashMap存放這個對象實例的時候,會調用哪個equals方法?
- Java中實現多態的機制是什么?
- 如何將一個Java對象序列化到文件里?
- 說說你對Java反射的理解
- 說說你對Java注解的理解
- 說說你對依賴注入的理解
- 說一下泛型原理,并舉例說明
- Java中String的了解
- String為什么要設計成不可變的?
- Object類的equal和hashCode方法重寫,為什么?
https://www.jianshu.com/p/c70989bd5f29