一:Java核心基礎(chǔ)
1.Java中提供了抽象類和接口,開發(fā)中如何去選擇呢?
1.1.抽象類是為了代碼復(fù)用,is-a的關(guān)系,接口是對(duì)類行為進(jìn)行約束 has-a。
1.2.比如狗,他要吃飯和睡覺,這是天生的,但是對(duì)于是否會(huì)握手這個(gè)行為,則不是每個(gè)狗都有握手。
因此我們可以這樣設(shè)計(jì)。
public abstract class Dog{
public void eat(){};
public void sleep(){};
}
對(duì)于握手這個(gè)行為,我們可以定義接口;
interface HandShake{
void doHandShake();
}
1.3.現(xiàn)在一個(gè)會(huì)握手的狗就出現(xiàn)了
public class HandShakeDog extends Dog implement HandShake{
void doHandShake(){
System.out.println("do HandShake");
}
}
2.重載和重寫是什么意思,區(qū)別是什么?
- 重載 (overload) 一個(gè)類中有多個(gè)相同名字的方法
- 重寫 (override)重新寫,父類中的方法對(duì)子類來說,不適用時(shí),可以對(duì)父類的方法進(jìn)行重新寫。
3.靜態(tài)內(nèi)部類是什么?和非靜態(tài)內(nèi)部類的區(qū)別?
內(nèi)部類被static修飾就是靜態(tài)內(nèi)部類,只能訪問外部類的靜態(tài)變量,非靜態(tài)內(nèi)部類可以訪問外部類的靜態(tài)變量和非靜態(tài)變量.
4.equal和== 的區(qū)別。
4.1因?yàn)閖ava中所有的類都默認(rèn)繼承Object類,如果equals沒有被重寫,equals和 == 沒有啥區(qū)別,如果被重寫了,那么就需要equals方法的具體實(shí)現(xiàn)。
4.2.Object類中的equals方法
public boolean equals(Object obj){
return (this==obj);
}
4.3. == 比較的是什么呢?
- 基本數(shù)據(jù)類型 int long float double 比較的是它們的值。
- 引用數(shù)據(jù)類型 比較的是地址【引用】
4.4.以String.equals
public boolean equals(Object anObject){
if(this==anObject){
return true;
}
if(anObject instance String){
String anotherString=(String)anObject;
int n=length();
if(n==anotherString.length()){
int i=0;
while(n--!=0){
if (charAt(i) != anotherString.charAt(i)) {//逐個(gè)字符比較
return false;
}
i++;
}
return true;
}
}
return false;
}

5.String s=new String("xxx");創(chuàng)建了幾個(gè)String對(duì)象?
new 關(guān)鍵字存在,JVM會(huì)先創(chuàng)建一個(gè)String對(duì)象,因?yàn)闃?gòu)造方法中傳遞了"xxx" 這個(gè)常量,所以JVM會(huì)從常量池中獲取對(duì)應(yīng)的引用,如果不存在,會(huì)在堆中創(chuàng)建"xxx"的字符串常量對(duì)象,并將其引用保存到字符串常量中并返回.
6.finally中的代碼一定會(huì)執(zhí)行嗎?try里面有return,finally還執(zhí)行嗎?
一般會(huì)執(zhí)行,除非try代碼塊里面執(zhí)行System.exit(0)關(guān)閉虛擬機(jī),此時(shí)不會(huì)在執(zhí)行finally代碼塊,其他情況,都會(huì)執(zhí)行.
7.Java異常機(jī)制中,Exception和Error的區(qū)別?

8.序列Parcelbale,Serializable的區(qū)別?
序列化就是將對(duì)象轉(zhuǎn)換為可傳輸字節(jié)流的過程。
Serializable原理:使用IO(ObjectInputStream ,ObjectOutputStream)寫入和恢復(fù)數(shù)據(jù)?!綣ava自帶的序列化接口,頻繁的進(jìn)行IO操作,實(shí)現(xiàn)簡(jiǎn)單】
Parcelbale原理:使用Parcel對(duì)象寫入和恢復(fù)數(shù)據(jù),將一個(gè)完整的對(duì)象進(jìn)行分解,分解后的每一個(gè)部分都是Intent所支持的類型.【安卓提供序列化接口】
Parcel對(duì)象就是一個(gè)打包解壓類也是一個(gè)輕量級(jí)的數(shù)據(jù)容器或者數(shù)據(jù)載體(writeInt,writeString)
class TestBean implements Parcelable {
protected TestBean(Parcel in) {
}
public static final Creator<TestBean> CREATOR = new Creator<TestBean>() {
@Override
public TestBean createFromParcel(Parcel in) {
return new TestBean(in);
}
@Override
public TestBean[] newArray(int size) {
return new TestBean[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
}
}
public class Parcel{
//打包 序列化 writeToParcel(parcel)
void writeInt() //把對(duì)象中的int類型數(shù)據(jù)寫入Parcel對(duì)象
void writeFloat() //把對(duì)象中的float類型數(shù)據(jù)寫入Parcel對(duì)象
void writeString() //把對(duì)象中String類型數(shù)據(jù)寫入Parcel對(duì)象
...
//解壓 反序列換 createFromParcel(parcel)
int readInt() //從Parcel對(duì)象中讀取int類型數(shù)據(jù)
float readFloat() //從Parcel對(duì)象中讀取Float類型數(shù)據(jù)
String readString //從Parcel對(duì)象中讀取Float類型數(shù)據(jù)
}
Parcel傳遞數(shù)據(jù)原理圖:

如果只是在內(nèi)存中進(jìn)行數(shù)據(jù)傳輸,(Activity,Service)之間,那么使用Parcelbale,性能比Serializable高很多(10倍),不會(huì)頻繁的進(jìn)行IO操作。
如果是持久化操作或者網(wǎng)絡(luò)傳輸,使用Serializable,因?yàn)镻arcelable是把數(shù)據(jù)保存在內(nèi)存中,內(nèi)存可能被回收,數(shù)據(jù)是不持久。
9.Intent傳遞的對(duì)象為什么要序列化。
Intent傳輸數(shù)據(jù)的本質(zhì)還是通過Binder來完成的,Intent啟動(dòng)的,會(huì)借助AMS來完成,AMS是屬于System_server進(jìn)程,這就意味對(duì)象必須跨進(jìn)程傳輸,那就必須對(duì)對(duì)象進(jìn)行序列化。因此必須通過復(fù)制的手段將App進(jìn)程的對(duì)象復(fù)制到System_server進(jìn)程,然后在由System_server進(jìn)程傳遞給App進(jìn)程中的OtherActivity.
二 Java并發(fā)編程
10.假設(shè)只有一個(gè)單核CPU,多線程還有用嗎?
CPU的執(zhí)行速度遠(yuǎn)遠(yuǎn)大于IO(數(shù)據(jù)讀寫)的速度,假設(shè)只有一個(gè)線程在進(jìn)行IO操作,那么CPU大部分的時(shí)間都會(huì)閑置下來,其他的任務(wù)也沒有線程去處理,會(huì)導(dǎo)致CPU極大的浪費(fèi),效率極低。由于CPU頻率很高,所有CPU分給每個(gè)線程的時(shí)間片很短,所以單核也可以實(shí)現(xiàn)多線程機(jī)制,能夠減少用戶響應(yīng)的時(shí)間。
11.synchronized修飾普通方法和修飾靜態(tài)方法的區(qū)別?什么是原子性,有序性,可見性?
11.1.原子性,有序性,可見性。
- 原子性 :一個(gè)操作要么被全部執(zhí)行,要么不執(zhí)行,不會(huì)被其他線程中斷。
- 有序性:程序執(zhí)行的順序和代碼順序是一致的。(DCL)
- 可見性:一個(gè)線程對(duì)共享變量的修改,對(duì)其他線程來說是可見。
11.2.synchronized修飾普通方法和修飾靜態(tài)方法
- synchronized修飾靜態(tài)方法 ,鎖定的是當(dāng)前類;這意味著所有訪問該方法的線程都共享同一個(gè)鎖?!緎ynchronized(class)】
- synchronized修飾普通方法 ,鎖定的是當(dāng)前實(shí)例對(duì)象,這意味這每個(gè)對(duì)象都有一把屬于自己的獨(dú)立的鎖。【sychronized(this)】
- synchronized修飾代碼塊,可以是任意對(duì)象或者是類的class,【synchronized(this/class)】
public class ThreadManager {
private static ThreadPoolProxy mCachedPool = null;
private static Object mCachedLock = new Object();
public static ThreadPoolProxy getCachedThreadPool() {
synchronized (mCachedLock) {
if (mCachedPool == null) {
mCachedPool = new ThreadPoolProxy(0, Integer.MAX_VALUE, ALIVE_TIME);
}
return mCachedPool;
}
}
}