日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

think in java interview-高级开发人员面试宝典(二)

發(fā)布時(shí)間:2025/7/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 think in java interview-高级开发人员面试宝典(二) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
think in java interview-高級(jí)開發(fā)人員面試寶典(二)分類: 面經(jīng)18634人閱讀評(píng)論(58)收藏舉報(bào)

目錄(?)[+]

從現(xiàn)在開始,以樣題的方式一一列出各種面試題以及點(diǎn)評(píng),考慮到我在前文中說的,對(duì)于一些大型的外資型公司,你將會(huì)面臨全程英語面試,因此我在文章中也會(huì)出現(xiàn)許多全英語樣題。

這些題目來自于各個(gè)真實(shí)的公司,公司名我就不一一例舉了,是本人一直以來苦心收藏的。

一個(gè)JAVA 的MAIN方法引發(fā)的一場(chǎng)血案



Q: ? ?What if the main method is declared as private?

A: ? ? The program compiles properly but at run time it will give "Main method not public." message.



Q: What if the static modifier is removed from the signature of the main method?

A: Program compiles. But at run time throws an error "NoSuchMethodError".


Q: What if I write static public void instead of public static void?

A: ?Program compiles and runs properly.



Q: What if I do not provide the String array as the argument to the method?

A: ?Program compiles but throws a run time error "NoSuchMethodError".



Q: What is the first argument of the String array in main method?

A: ?The String array is empty. It does not have any element. This is unlike C/C++(讀作plus plus) where the first element by default is the program name.


Q: If I do not provide any arguments on the command line, then the String array of Main method will be empty or null?

A: ?It is empty. But not null.



Q: How can one prove that the array is notnull but empty using one line of code?

A: ?Print args.length. It will print 0. That means it is empty. But if it would have been null then it would have thrown a NullPointerException on attempting to print args.length.


仔細(xì)看完后有人直接吐血了,拿個(gè)eclipse,這幾個(gè)問題全部模擬一邊就可以了,即無算法也不需要死記硬背


有人會(huì)說了,唉,我怎么寫了5年的JAVA怎么就沒記得多寫多看,多想想這個(gè)public static void main(String[] args)方法呢?唉。。。


再來!!!


hashcode & equals之5重天

何時(shí)需要重寫equals()


當(dāng)一個(gè)類有自己特有的“邏輯相等”概念(不同于對(duì)象身份的概念)。



如何覆寫equals()和hashcode



覆寫equals方法

1 ?使用instanceof操作符檢查“實(shí)參是否為正確的類型”。

2 ?對(duì)于類中的每一個(gè)“關(guān)鍵域”,檢查實(shí)參中的域與當(dāng)前對(duì)象中對(duì)應(yīng)的域值。

3. 對(duì)于非float和double類型的原語類型域,使用==比較;

4 ?對(duì)于對(duì)象引用域,遞歸調(diào)用equals方法;

5 ?對(duì)于float域,使用Float.floatToIntBits(afloat)轉(zhuǎn)換為int,再使用==比較;

6 ?對(duì)于double域,使用Double.doubleToLongBits(adouble)轉(zhuǎn)換為int,再使用==比較;

7 ?對(duì)于數(shù)組域,調(diào)用Arrays.equals方法。

覆寫hashcode


1. 把某個(gè)非零常數(shù)值,例如17,保存在int變量result中;

2. 對(duì)于對(duì)象中每一個(gè)關(guān)鍵域f(指equals方法中考慮的每一個(gè)域):

3, boolean型,計(jì)算(f? 0 : 1);

4. byte,char,short型,計(jì)算(int);

5. long型,計(jì)算(int)(f ^ (f>>>32));

6. float型,計(jì)算Float.floatToIntBits(afloat);

7. double型,計(jì)算Double.doubleToLongBits(adouble)得到一個(gè)long,再執(zhí)行[2.3];

8. 對(duì)象引用,遞歸調(diào)用它的hashCode方法;

9. 數(shù)組域,對(duì)其中每個(gè)元素調(diào)用它的hashCode方法。

10. 將上面計(jì)算得到的散列碼保存到int變量c,然后執(zhí)行result=37*result+c;

11. 返回result。


舉個(gè)例子:


[java]view plaincopy
  • publicclass MyUnit{ ?

  • privateshort ashort; ?

  • privatechar achar; ?

  • privatebyte abyte; ?

  • privateboolean abool; ?

  • privatelong along; ?

  • privatefloat afloat; ?

  • privatedouble adouble; ?

  • private Unit aObject; ?

  • privateint[] ints; ?

  • private Unit[] units; ?

  • publicboolean equals(Object o) { ?

  • if (!(o instanceof Unit)) ?

  • returnfalse; ?

  • ? ? ? Unit unit = (Unit) o; ?

  • return unit.ashort == ashort ?

  • ? ? ? ? ? ? ?&& unit.achar == achar ?

  • ? ? ? ? ? ? ?&& unit.abyte == abyte ?

  • ? ? ? ? ? ? ?&& unit.abool == abool ?

  • ? ? ? ? ? ? ?&& unit.along == along ?

  • ? ? ? ? ? ? ?&& Float.floatToIntBits(unit.afloat) == Float ?

  • ? ? ? ? ? ? ? ? ? ? .floatToIntBits(afloat) ?

  • ? ? ? ? ? ? ?&& Double.doubleToLongBits(unit.adouble) == Double ?

  • ? ? ? ? ? ? ? ? ? ? .doubleToLongBits(adouble) ?

  • ? ? ? ? ? ? ?&& unit.aObject.equals(aObject) ?

  • ? ? ? ? ? ? ?&& equalsInts(unit.ints) ?

  • ? ? ? ? ? ? ?&& equalsUnits(unit.units); ?

  • ? ?} ?

  • privateboolean equalsInts(int[] aints) { ?

  • return Arrays.equals(ints, aints); ?

  • ? ?} ?

  • privateboolean equalsUnits(Unit[] aUnits) { ?

  • return Arrays.equals(units, aUnits); ?

  • ? ?} ?

  • publicint hashCode() { ?

  • int result = 17; ?

  • ? ? ? result = 31 * result + (int) ashort; ?

  • ? ? ? result = 31 * result + (int) achar; ?

  • ? ? ? result = 31 * result + (int) abyte; ?

  • ? ? ? result = 31 * result + (abool ? 0 : 1); ?

  • ? ? ? result = 31 * result + (int) (along ^ (along >>> 32)); ?

  • ? ? ? result = 31 * result + Float.floatToIntBits(afloat); ?

  • long tolong = Double.doubleToLongBits(adouble); ?

  • ? ? ? result = 31 * result + (int) (tolong ^ (tolong >>> 32)); ?

  • ? ? ? result = 31 * result + aObject.hashCode(); ?

  • ? ? ? result = 31 * result + intsHashCode(ints); ?

  • ? ? ? result = 31 * result + unitsHashCode(units); ?

  • return result; ?

  • ? ?} ?

  • privateint intsHashCode(int[] aints) { ?

  • int result = 17; ?

  • for (int i = 0; i < aints.length; i++) ?

  • ? ? ? ? ? result = 31 * result + aints[i]; ?

  • return result; ?

  • ? ?} ?

  • privateint unitsHashCode(Unit[] aUnits) { ?

  • int result = 17; ?

  • for (int i = 0; i < aUnits.length; i++) ?

  • ? ? ? ? ? result = 31 * result + aUnits[i].hashCode(); ?

  • return result; ?

  • ? ?} ?

  • } ?





  • 當(dāng)改寫equals()的時(shí)候,總是要改寫hashCode()


    根據(jù)一個(gè)類的equals方法(改寫后),兩個(gè)截然不同的實(shí)例有可能在邏輯上是相等的,但是,根據(jù)Object.hashCode方法,它們僅僅是兩個(gè)對(duì)象。因此,違反了“相等的對(duì)象必須具有相等的散列碼”。


    兩個(gè)對(duì)象如果equals那么這兩個(gè)對(duì)象的hashcode一定相等,如果兩個(gè)對(duì)象的hashcode相等那么這兩個(gè)對(duì)象是否一定equals?

    回答是不一定,這要看這兩個(gè)對(duì)象有沒有重寫Object的hashCode方法和equals方法。如果沒有重寫,是按Object默認(rèn)的方式去處理。

    試想我有一個(gè)桶,這個(gè)桶就是hashcode,桶里裝的是西瓜我們認(rèn)為西瓜就是object,有的桶是一個(gè)桶裝一個(gè)西瓜,有的桶是一個(gè)桶裝多個(gè)西瓜。

    比如String重寫了Object的hashcode和equals,但是兩個(gè)String如果hashcode相等,那么equals比較肯定是相等的,但是“==”比較卻不一定相等。如果自定義的對(duì)象重寫了hashCode方法,有可能hashcode相等,equals卻不一定相等,“==”比較也不一定相等。

    此處考的是你對(duì)object的hashcode的意義的真正的理解!!!如果作為一名高級(jí)開發(fā)人員或者是架構(gòu)師,必須是要有這個(gè)概念的,否則,直接ban掉了。

    為什么我們?cè)诙xhashcode時(shí)如: h = 31*h + val[off++]; ?要使用31這個(gè)數(shù)呢?
    public int hashCode() {
    int h = hash;
    int len = count;
    if (h == 0 && len > 0) {
    int off = offset;
    char val[] = value;
    for (int i = 0; i < len; i++) {
    h = 31*h + val[off++];
    }
    hash = h;
    }
    return h;
    }

    來看一段hashcode的覆寫案例:

    其實(shí)上面的實(shí)現(xiàn)也可以總結(jié)成數(shù)數(shù)里面下面這樣的公式:

    s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]

    我們來看這個(gè)要命的31這個(gè)系數(shù)為什么總是在里面乘啊乘的?為什么不適用32或者其他數(shù)字?

    大家都知道,計(jì)算機(jī)的乘法涉及到移位計(jì)算。當(dāng)一個(gè)數(shù)乘以2時(shí),就直接拿該數(shù)左移一位即可!選擇31原因是因?yàn)?1是一個(gè)素?cái)?shù)!

    所謂素?cái)?shù):

    質(zhì)數(shù)又稱素?cái)?shù)

    素?cái)?shù)在使用的時(shí)候有一個(gè)作用就是如果我用一個(gè)數(shù)字來乘以這個(gè)素?cái)?shù),那么最終的出來的結(jié)果只能被素?cái)?shù)本身和被乘數(shù)還有1來整除!如:我們選擇素?cái)?shù)3來做系數(shù),那么3*n只能被3和n或者1來整除,我們可以很容易的通過3n來計(jì)算出這個(gè)n來。這應(yīng)該也是一個(gè)原因!

    在存儲(chǔ)數(shù)據(jù)計(jì)算hash地址的時(shí)候,我們希望盡量減少有同樣的hash地址,所謂“沖突”

    31是個(gè)神奇的數(shù)字,因?yàn)槿魏螖?shù)n * 31就可以被JVM優(yōu)化為 (n << 5) -n,移位和減法的操作效率要比乘法的操作效率高的多,對(duì)左移現(xiàn)在很多虛擬機(jī)里面都有做相關(guān)優(yōu)化,并且31只占用5bits!

    hashcode & equals基本問到第三問,很多人就已經(jīng)掛了,如果問到了為什么要使用31比較好呢,90%的人無法回答或者只回答出一半。

    此處考的是編程者在平時(shí)開發(fā)時(shí)是否經(jīng)常考慮“性能”這個(gè)問題。



    轉(zhuǎn)載于:https://blog.51cto.com/longx/1351866

    總結(jié)

    以上是生活随笔為你收集整理的think in java interview-高级开发人员面试宝典(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。