一修壕、寫一個單例
現(xiàn)在有很經(jīng)典的五種創(chuàng)建方式爽待,這里不再贅述损同,當(dāng)時我寫的一個靜態(tài)內(nèi)部類形式。
public static class Singleton{
private Singleton(){};
public static getInstance(){
return Holder.singleton;
}
private static class Holder{
private static final Singleton singleton = new Singleton();
}
}
寫完就后悔了鸟款,還是應(yīng)該寫經(jīng)常用的雙重檢驗(yàn)鎖模式膏燃,恩...果然面試官就問了這樣寫能保證線程安全嗎?答案是肯定的何什!但是他叫我分析一下组哩,當(dāng)時就懵逼了。接下來就開始懷疑人生了处渣,沒有一個鎖是如何保證線程安全的...感覺是不是自己寫錯了伶贰,還是不應(yīng)該裝逼,老老實(shí)實(shí)寫DCL模式罐栈。
其實(shí)當(dāng)時我是想講靜態(tài)變量是屬于程序本身黍衙,第一次加載該類時才會為其分配內(nèi)存空間初始化。但當(dāng)時在腦海中盤旋的是當(dāng)兩個線程同時調(diào)用getInstance()方法時該怎么辦荠诬?當(dāng)時腦海中反駁自己的理由是創(chuàng)建一個對象并非是原子操作...最后給面試官老老實(shí)實(shí)說了因?yàn)樽约浩綍r不常用靜態(tài)內(nèi)部類的緣故琅翻。
還是感覺自己太緊張了,我把它理解為
public static class Singleton{
private static final Singleton singleton;
private Singleton(){};
public static getInstance(){
if(singleton==null)
singleton = new Singleton;
return singleton;
}
}
這里也需要惡補(bǔ)一下實(shí)例變量類變量的初始化時機(jī)柑贞,類變量是當(dāng)我們程序第一次加載到內(nèi)存的時候初始化望迎,并且初始化時在靜態(tài)代碼塊中(javap命令查看編譯后的字節(jié)碼可以發(fā)現(xiàn)初始化是在靜態(tài)代碼塊中,而實(shí)例變量初始化是在構(gòu)造方法中)凌外,所以創(chuàng)建靜態(tài)變量是在第一次加載到內(nèi)容的時候創(chuàng)建的,并且保證只創(chuàng)建過一次涛浙,無論哪個線程調(diào)用的時候都是調(diào)用的一個已經(jīng)實(shí)例化的對象康辑,都是線程安全的。只不過靜態(tài)內(nèi)部類采用的延時創(chuàng)建對象的策略轿亮,只有我們調(diào)用getInstance()方法的時候才把靜態(tài)內(nèi)部類加載到內(nèi)存中疮薇,從而實(shí)例化我們的對象。
二我注、向容量為100的int型數(shù)組中隨機(jī)插入0~99
當(dāng)時我的第一反應(yīng)是去隨機(jī)數(shù)按咒,插入數(shù)組中,如果檢測到當(dāng)前下標(biāo)位置發(fā)生碰撞則向前或向后移動但骨,但是感覺這樣時間復(fù)雜度太大了励七,可能會達(dá)到n^2智袭,所以能否將數(shù)組類似于希爾排序一樣分為10個組,又想了一下能否在010中取隨機(jī)數(shù)掠抬,并且額外增加一個長度為10的數(shù)組記錄每組容量的多少吼野。如果當(dāng)前組滿了則向前或向后移動。就這樣胡思亂想了十分鐘两波,最后給面試官說了一下思路瞳步,面試官建議我下次按照最自己最原始的做法完成,再去想優(yōu)化腰奋,就這樣GG了单起。最后還是得多去看看算法,大公司還是很注意這方面的內(nèi)容劣坊。最后一個朋友提醒了我嘀倒,應(yīng)該使用類似洗牌的算法~果然是刷了劍指offer和程序之美的老鳥!
void shuffle(int counts[]){
Random random = new Random();
int temp;
for(int i = 0;i < counts.length;i++){
//這樣做保證了每次交換的都大于i讼稚,防止與已經(jīng)交換過的數(shù)再交換一次括儒,保證打亂的順序
int j = i+random.nextInt(counts.length-i);
//i,j進(jìn)行順序交換
temp = counts[i];
counts[i] = counts[j];
counts[j] = temp;
}
}
三、邏輯問題:取100個小球锐想,每次只能去一個或者兩個帮寻,假設(shè)你先取,如何保證你能贏赠摇。
這個問題自己有點(diǎn)略傻固逗,當(dāng)時想的是100個太多,嘗試一下逆推藕帜,最后想出最后剩3個的時候自己肯定會贏的烫罩。面試官說思路是對的,讓我回去再想一想洽故,真蠢贝攒,每次自己取完后保證是3的倍數(shù)最后肯定會剩3個的。
其他的問題都是基礎(chǔ)的java面試題时甚,唯一的遺憾就是沒有問到android的面試題隘弊。