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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(二)

發(fā)布時(shí)間:2025/3/19 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(二) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者:egg

郵箱:xtfggef@gmail.com

微博:http://weibo.com/xtfggef

博客:http://blog.csdn.net/zhangerqing(轉(zhuǎn)載請(qǐng)說(shuō)明出處)

這章我們還是接著上一章的,繼續(xù)整理。

1、數(shù)組有沒(méi)有l(wèi)ength()這個(gè)方法? String有沒(méi)有l(wèi)ength()這個(gè)方法??
數(shù)組沒(méi)有l(wèi)ength()這個(gè)方法,有l(wèi)ength的屬性。String有有l(wèi)ength()這個(gè)方法。


2、下面這條語(yǔ)句一共創(chuàng)建了多少個(gè)對(duì)象:String s="a"+"b"+"c"+"d";
答:對(duì)于如下代碼:
  String s1 = "a";
  String s2 = s1 + "b";
  String s3 = "a" + "b";
  System.out.println(s2 == "ab");
  System.out.println(s3 == "ab");
  第一條語(yǔ)句打印的結(jié)果為false,第二條語(yǔ)句打印的結(jié)果為true,這說(shuō)明javac編譯可以對(duì)字符串常量直接相加的表達(dá)式進(jìn)行優(yōu)化,不必要等到運(yùn)行期去進(jìn)行加法運(yùn)算處理,而是在編譯時(shí)去掉其中的加號(hào),直接將其編譯成一個(gè)這些常量相連的結(jié)果。題目中的第一行代碼被編譯器在編譯時(shí)優(yōu)化后,相當(dāng)于直接定義了一個(gè)”abcd”的字符串,所以,上面的代碼應(yīng)該只創(chuàng)建了一個(gè)String對(duì)象。寫如下兩行代碼,
  String s = "a" + "b" + "c" + "d";
  System.out.println(s == "abcd"); ? ??

最終打印的結(jié)果應(yīng)該為true。關(guān)于字符串更多的介紹,請(qǐng)看:深入解讀Java字符串 ?http://blog.csdn.net/zhangerqing/article/details/8093919?


3、try {}里有一個(gè)return語(yǔ)句,那么緊跟在這個(gè)try后的finally {}里的code會(huì)不會(huì)被執(zhí)行,什么時(shí)候被執(zhí)行,在return前還是后??
也許你的答案是在return之前,但往更細(xì)地說(shuō),我的答案是在return中間執(zhí)行,請(qǐng)看下面程序代碼的運(yùn)行結(jié)果:

  • public class Test {
  • /**
  • * @param args add by zxx ,Dec 9, 2008
  • */
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • System.out.println(new Test().test());;
  • }
  • static int test()
  • {
  • int x = 1;
  • try
  • {
  • return x;
  • }
  • finally
  • {
  • ++x;
  • }
  • }
  • }
  • ---------執(zhí)行結(jié)果?---------

    1

    運(yùn)行結(jié)果是1,為什么呢?主函數(shù)調(diào)用子函數(shù)并得到結(jié)果的過(guò)程,好比主函數(shù)準(zhǔn)備一個(gè)空罐子,當(dāng)子函數(shù)要返回結(jié)果時(shí),先把結(jié)果放在罐子里,然后再將程序邏輯返回到主函數(shù)。所謂返回,就是子函數(shù)說(shuō),我不運(yùn)行了,你主函數(shù)繼續(xù)運(yùn)行吧,這沒(méi)什么結(jié)果可言,結(jié)果是在說(shuō)這話之前放進(jìn)罐子里的。

    4、下面的程序代碼輸出的結(jié)果是多少?

  • public class smallT
  • {
  • public static void main(String args[])
  • {
  • smallT t = new smallT();
  • int b = t.get();
  • System.out.println(b);
  • }
  • public int get()
  • {
  • try
  • {
  • return 1 ;
  • }
  • finally
  • {
  • return 2 ;
  • }
  • }
  • }
  • 返回的結(jié)果是2。

    我可以通過(guò)下面一個(gè)例子程序來(lái)幫助我解釋這個(gè)答案,從下面例子的運(yùn)行結(jié)果中可以發(fā)現(xiàn),try中的return語(yǔ)句調(diào)用的函數(shù)先于finally中調(diào)用的函數(shù)執(zhí)行,也就是說(shuō)return語(yǔ)句先執(zhí)行,finally語(yǔ)句后執(zhí)行,所以,返回的結(jié)果是2。Return并不是讓函數(shù)馬上返回,而是return語(yǔ)句執(zhí)行后,將把返回結(jié)果放置進(jìn)函數(shù)棧中,此時(shí)函數(shù)并不是馬上返回,它要執(zhí)行finally語(yǔ)句后才真正開(kāi)始返回。

    在講解答案時(shí)可以用下面的程序來(lái)幫助分析:

  • public class Test {
  • /**
  • * @param args add by zxx ,Dec 9, 2008
  • */
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • System.out.println(new Test().test());;
  • }
  • int test()
  • {
  • try
  • {
  • return func1();
  • }
  • finally
  • {
  • return func2();
  • }
  • }
  • int func1()
  • {
  • System.out.println("func1");
  • return 1;
  • }
  • int func2()
  • {
  • System.out.println("func2");
  • return 2;
  • }
  • }
  • -----------執(zhí)行結(jié)果-----------------

    func1

    func2

    2

    結(jié)論:finally中的代碼比return?和break語(yǔ)句后執(zhí)行


    5、final, finally, finalize的區(qū)別

    final?用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。?內(nèi)部類要訪問(wèn)局部變量,局部變量必須定義成final類型,例如,一段代碼……

    finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。

    finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。JVM不保證此方法總被調(diào)用


    6、運(yùn)行時(shí)異常與一般異常有何異同?

    異常表示程序運(yùn)行過(guò)程中可能出現(xiàn)的非正常狀態(tài),運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見(jiàn)運(yùn)行錯(cuò)誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運(yùn)行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常。


    7、error和exception有什么區(qū)別??

    error?表示恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問(wèn)題。比如說(shuō)內(nèi)存溢出。不可能指望程序能處理這樣的情況。?exception?表示一種設(shè)計(jì)或?qū)崿F(xiàn)問(wèn)題。也就是說(shuō),它表示如果程序運(yùn)行正常,從不會(huì)發(fā)生的情況。


    8、Java中的異常處理機(jī)制的簡(jiǎn)單原理和應(yīng)用

    異常是指java程序運(yùn)行時(shí)(非編譯)所發(fā)生的非正常情況或錯(cuò)誤,與現(xiàn)實(shí)生活中的事件很相似,現(xiàn)實(shí)生活中的事件可以包含事件發(fā)生的時(shí)間、地點(diǎn)、人物、情節(jié)等信息,可以用一個(gè)對(duì)象來(lái)表示,Java使用面向?qū)ο蟮姆绞絹?lái)處理異常,它把程序中發(fā)生的每個(gè)異常也都分別封裝到一個(gè)對(duì)象來(lái)表示的,該對(duì)象中包含有異常的信息。

    Java對(duì)異常進(jìn)行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個(gè)子類:Error和Exception,Error?表示應(yīng)用程序本身無(wú)法克服和恢復(fù)的一種嚴(yán)重問(wèn)題,程序只有死的份了,例如,說(shuō)內(nèi)存溢出和線程死鎖等系統(tǒng)問(wèn)題。Exception表示程序還能夠克服和恢復(fù)的問(wèn)題,其中又分為系統(tǒng)異常和普通異常,系統(tǒng)異常是軟件本身缺陷所導(dǎo)致的問(wèn)題,也就是軟件開(kāi)發(fā)人員考慮不周所導(dǎo)致的問(wèn)題,軟件使用者無(wú)法克服和恢復(fù)這種問(wèn)題,但在這種問(wèn)題下還可以讓軟件系統(tǒng)繼續(xù)運(yùn)行或者讓軟件死掉,例如,數(shù)組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉(zhuǎn)換異常(ClassCastException);普通異常是運(yùn)行環(huán)境的變化或異常所導(dǎo)致的問(wèn)題,是用戶能夠克服的問(wèn)題,例如,網(wǎng)絡(luò)斷線,硬盤空間不夠,發(fā)生這樣的異常后,程序不應(yīng)該死掉。

    java為系統(tǒng)異常和普通異常提供了不同的解決方案,編譯器強(qiáng)制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理,所以普通異常也稱為checked異常,而系統(tǒng)異常可以處理也可以不處理,所以,編譯器不強(qiáng)制用try..catch處理或用throws聲明,所以系統(tǒng)異常也稱為unchecked異常。

    提示答題者:就按照三個(gè)級(jí)別去思考:虛擬機(jī)必須宕機(jī)的錯(cuò)誤,程序可以死掉也可以不死掉的錯(cuò)誤,程序不應(yīng)該死掉的錯(cuò)誤;


    9、請(qǐng)寫出你最常見(jiàn)到的5個(gè)runtime?exception

    NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ClassNotFoundException

    更多可以參考本博關(guān)于異常的講解:Java中的異常:http://blog.csdn.net/zhangerqing/article/details/8248186


    10、sleep() 和 wait() 有什么區(qū)別??

    sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。?wait是Object類的方法,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。)?

    sleep就是正在執(zhí)行的線程主動(dòng)讓出cpu,cpu去執(zhí)行其他線程,在sleep指定的時(shí)間過(guò)后,cpu才會(huì)回到這個(gè)線程上繼續(xù)往下執(zhí)行,如果當(dāng)前線程進(jìn)入了同步鎖,sleep方法并不會(huì)釋放鎖,即使當(dāng)前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無(wú)法得到執(zhí)行。wait是指在一個(gè)已經(jīng)進(jìn)入了同步鎖的線程內(nèi),讓自己暫時(shí)讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖并運(yùn)行,只有其他線程調(diào)用了notify方法(notify并不釋放鎖,只是告訴調(diào)用過(guò)wait方法的線程可以去參與獲得鎖的競(jìng)爭(zhēng)了,但不是馬上得到鎖,因?yàn)殒i還在別人手里,別人還沒(méi)釋放。如果notify方法后面的代碼還有很多,需要這些代碼執(zhí)行完后才會(huì)釋放鎖,可以在notfiy方法后增加一個(gè)等待和一些代碼,看看效果),調(diào)用wait方法的線程就會(huì)解除wait狀態(tài)和程序可以再次得到鎖后繼續(xù)向下運(yùn)行。對(duì)于wait的講解一定要配合例子代碼來(lái)說(shuō)明,才顯得自己真明白。

  • package com.huawei.interview;
  • public class MultiThread {
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • new Thread(new Thread1()).start();
  • try {
  • Thread.sleep(10);
  • } catch (InterruptedException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • new Thread(new Thread2()).start();
  • }
  • private static class Thread1 implements Runnable
  • {
  • @Override
  • public void run() {
  • //由于這里的Thread1和下面的Thread2內(nèi)部run方法要用同一對(duì)象作為監(jiān)視器,我們這里不能用this,因?yàn)樵赥hread2里面的this和這個(gè)Thread1的this不是同一個(gè)對(duì)象。我們用MultiThread.class這個(gè)字節(jié)碼對(duì)象,當(dāng)前虛擬機(jī)里引用這個(gè)變量時(shí),指向的都是同一個(gè)對(duì)象。
  • synchronized (MultiThread.class) {
  • System.out.println("enter thread1...");
  • System.out.println("thread1 is waiting");
  • try {
  • //釋放鎖有兩種方式,第一種方式是程序自然離開(kāi)監(jiān)視器的范圍,也就是離開(kāi)了synchronized關(guān)鍵字管轄的代碼范圍,另一種方式就是在synchronized關(guān)鍵字管轄的代碼內(nèi)部調(diào)用監(jiān)視器對(duì)象的wait方法。這里,使用wait方法釋放鎖。
  • MultiThread.class.wait();
  • } catch (InterruptedException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • System.out.println("thread1 is going on...");
  • System.out.println("thread1 is being over!");
  • }
  • }
  • }
  • private static class Thread2 implements Runnable
  • {
  • @Override
  • public void run() {
  • // TODO Auto-generated method stub
  • synchronized (MultiThread.class) {
  • System.out.println("enter thread2...");
  • System.out.println("thread2 notify other thread can release wait status..");
  • //由于notify方法并不釋放鎖, 即使thread2調(diào)用下面的sleep方法休息了10毫秒,但thread1仍然不會(huì)執(zhí)行,因?yàn)閠hread2沒(méi)有釋放鎖,所以Thread1無(wú)法得不到鎖。
  • MultiThread.class.notify();
  • System.out.println("thread2 is sleeping ten millisecond...");
  • try {
  • Thread.sleep(10);
  • } catch (InterruptedException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • System.out.println("thread2 is going on...");
  • System.out.println("thread2 is being over!");
  • }
  • }
  • }
  • }

  • 11、啟動(dòng)一個(gè)線程是用run()還是start()??
    啟動(dòng)一個(gè)線程是調(diào)用start()方法,使線程就緒狀態(tài),以后可以被調(diào)度為運(yùn)行狀態(tài),一個(gè)線程必須關(guān)聯(lián)一些具體的執(zhí)行代碼,run()方法是該線程所關(guān)聯(lián)的執(zhí)行代碼。?


    12、當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后,其它線程是否可進(jìn)入此對(duì)象的其它方法??
    分幾種情況:
    ? ? ?1.其他方法前是否加了synchronized關(guān)鍵字,如果沒(méi)加,則能。
    ? ? ?2.如果這個(gè)方法內(nèi)部調(diào)用了wait,則可以進(jìn)入其他synchronized方法。
    ? ? ?3.如果其他個(gè)方法都加了synchronized關(guān)鍵字,并且內(nèi)部沒(méi)有調(diào)用wait,則不能。
    ? ? ?4.如果其他方法是static,它用的同步鎖是當(dāng)前類的字節(jié)碼,與非靜態(tài)的方法不能同步,因?yàn)榉庆o態(tài)的方法用的是this。


    13、線程的基本概念、線程的基本狀態(tài)以及狀態(tài)之間的關(guān)系?
    一個(gè)程序中可以有多條執(zhí)行線索同時(shí)執(zhí)行,一個(gè)線程就是程序中的一條執(zhí)行線索,每個(gè)線程上都關(guān)聯(lián)有要執(zhí)行的代碼,即可以有多段程序代碼同時(shí)運(yùn)行,每個(gè)程序至少都有一個(gè)線程,即main方法執(zhí)行的那個(gè)線程。如果只是一個(gè)cpu,它怎么能夠同時(shí)執(zhí)行多段程序呢?這是從宏觀上來(lái)看的,cpu一會(huì)執(zhí)行a線索,一會(huì)執(zhí)行b線索,切換時(shí)間很快,給人的感覺(jué)是a,b在同時(shí)執(zhí)行,好比大家在同一個(gè)辦公室上網(wǎng),只有一條鏈接到外部網(wǎng)線,其實(shí),這條網(wǎng)線一會(huì)為a傳數(shù)據(jù),一會(huì)為b傳數(shù)據(jù),由于切換時(shí)間很短暫,所以,大家感覺(jué)都在同時(shí)上網(wǎng)。?
    狀態(tài):就緒,運(yùn)行,synchronize阻塞,wait和sleep掛起,結(jié)束。wait必須在synchronized內(nèi)部調(diào)用。
    調(diào)用線程的start方法后線程進(jìn)入就緒狀態(tài),線程調(diào)度系統(tǒng)將就緒狀態(tài)的線程轉(zhuǎn)為運(yùn)行狀態(tài),遇到synchronized語(yǔ)句時(shí),由運(yùn)行狀態(tài)轉(zhuǎn)為阻塞,當(dāng)synchronized獲得鎖后,由阻塞轉(zhuǎn)為運(yùn)行,在這種情況可以調(diào)用wait方法轉(zhuǎn)為掛起狀態(tài),當(dāng)線程關(guān)聯(lián)的代碼執(zhí)行完后,線程變?yōu)榻Y(jié)束狀態(tài)。?


    14、簡(jiǎn)述synchronized和java.util.concurrent.locks.Lock的異同 ??
    主要相同點(diǎn):Lock能完成synchronized所實(shí)現(xiàn)的所有功能?
    主要不同點(diǎn):Lock有比synchronized更精確的線程語(yǔ)義和更好的性能。synchronized會(huì)自動(dòng)釋放鎖,而Lock一定要求程序員手工釋放,并且必須在finally從句中釋放。Lock還有更強(qiáng)大的功能,例如,它的tryLock方法可以非阻塞方式去拿鎖。?
    舉例說(shuō)明(對(duì)下面的題用lock進(jìn)行了改寫):

  • package com.huawei.interview;
  • import java.util.concurrent.locks.Lock;
  • import java.util.concurrent.locks.ReentrantLock;
  • public class ThreadTest {
  • private int j;
  • private Lock lock = new ReentrantLock();
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • ThreadTest tt = new ThreadTest();
  • for(int i=0;i<2;i++)
  • {
  • new Thread(tt.new Adder()).start();
  • new Thread(tt.new Subtractor()).start();
  • }
  • }
  • private class Subtractor implements Runnable
  • {
  • @Override
  • public void run() {
  • // TODO Auto-generated method stub
  • while(true)
  • {
  • /*synchronized (ThreadTest.this) {
  • System.out.println("j--=" + j--);
  • //這里拋異常了,鎖能釋放嗎?
  • }*/
  • lock.lock();
  • try
  • {
  • System.out.println("j--=" + j--);
  • }finally
  • {
  • lock.unlock();
  • }
  • }
  • }
  • }
  • private class Adder implements Runnable
  • {
  • @Override
  • public void run() {
  • // TODO Auto-generated method stub
  • while(true)
  • {
  • /*synchronized (ThreadTest.this) {
  • System.out.println("j++=" + j++);
  • }*/
  • lock.lock();
  • try
  • {
  • System.out.println("j++=" + j++);
  • }finally
  • {
  • lock.unlock();
  • }
  • }
  • }
  • }
  • }

  • 15、設(shè)計(jì)4個(gè)線程,其中兩個(gè)線程每次對(duì)j增加1,另外兩個(gè)線程對(duì)j每次減少1。寫出程序
  • public class ThreadTest1
  • {
  • private int j;
  • public static void main(String args[]){
  • ThreadTest1 tt=new ThreadTest1();
  • Inc inc=tt.new Inc();
  • Dec dec=tt.new Dec();
  • for(int i=0;i<2;i++){
  • Thread t=new Thread(inc);
  • t.start();
  • t=new Thread(dec);
  • t.start();
  • }
  • }
  • private synchronized void inc(){
  • j++;
  • System.out.println(Thread.currentThread().getName()+"-inc:"+j);
  • }
  • private synchronized void dec(){
  • j--;
  • System.out.println(Thread.currentThread().getName()+"-dec:"+j);
  • }
  • class Inc implements Runnable{
  • public void run(){
  • for(int i=0;i<100;i++){
  • inc();
  • }
  • }
  • }
  • class Dec implements Runnable{
  • public void run(){
  • for(int i=0;i<100;i++){
  • dec();
  • }
  • }
  • }
  • }

  • 16、子線程循環(huán)10次,接著主線程循環(huán)100,接著又回到子線程循環(huán)10次,接著再回到主線程又循環(huán)100,如此循環(huán)50次,請(qǐng)寫出程序
  • public class ThreadTest {
  • /**
  • * @param args
  • */
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • new ThreadTest().init();
  • }
  • public void init()
  • {
  • final Business business = new Business();
  • new Thread(
  • new Runnable()
  • {
  • public void run() {
  • for(int i=0;i<50;i++)
  • {
  • business.SubThread(i);
  • }
  • }
  • }
  • ).start();
  • for(int i=0;i<50;i++)
  • {
  • business.MainThread(i);
  • }
  • }
  • private class Business
  • {
  • boolean bShouldSub = true;//這里相當(dāng)于定義了控制該誰(shuí)執(zhí)行的一個(gè)信號(hào)燈
  • public synchronized void MainThread(int i)
  • {
  • if(bShouldSub)
  • try {
  • this.wait();
  • } catch (InterruptedException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • for(int j=0;j<5;j++)
  • {
  • System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j);
  • }
  • bShouldSub = true;
  • this.notify();
  • }
  • public synchronized void SubThread(int i)
  • {
  • if(!bShouldSub)
  • try {
  • this.wait();
  • } catch (InterruptedException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • for(int j=0;j<10;j++)
  • {
  • System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j);
  • }
  • bShouldSub = false;
  • this.notify();
  • }
  • }
  • }
  • 17、介紹Collection框架的結(jié)構(gòu)

    這道題不用說(shuō)了,去看我關(guān)于集合類的講解就能答好了:http://blog.csdn.net/zhangerqing/article/details/8122075


    18、Collection框架中實(shí)現(xiàn)比較要實(shí)現(xiàn)什么接口

    comparable/comparator


    19、ArrayList和Vector的區(qū)別
    這兩個(gè)類都實(shí)現(xiàn)了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲(chǔ)在這兩個(gè)集合中的元素的位置都是有順序的,相當(dāng)于一種動(dòng)態(tài)的數(shù)組,我們以后可以按位置索引號(hào)取出某個(gè)元素,,并且其中的數(shù)據(jù)是允許重復(fù)的,這是HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號(hào)去檢索其中的元素,也不允許有重復(fù)的元素(本來(lái)題目問(wèn)的與hashset沒(méi)有任何關(guān)系,但為了說(shuō)清楚ArrayList與Vector的功能,我們使用對(duì)比方式,更有利于說(shuō)明問(wèn)題)。

    接著才說(shuō)ArrayList與Vector的區(qū)別,這主要包括兩個(gè)方面:. (1)同步性:
    Vector是線程安全的,也就是說(shuō)是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不同步的。如果只有一個(gè)線程會(huì)訪問(wèn)到集合,那最好是使用ArrayList,因?yàn)樗豢紤]線程安全,效率會(huì)高些;如果有多個(gè)線程會(huì)訪問(wèn)到集合,那最好是使用Vector,因?yàn)椴恍枰覀冏约涸偃タ紤]和編寫線程安全的代碼。

    備注:對(duì)于Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問(wèn)題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時(shí)才提供的,它們是線程不安全的。所以,我們講課時(shí)先講老的。(2)數(shù)據(jù)增長(zhǎng):
    ArrayList與Vector都有一個(gè)初始的容量大小,當(dāng)存儲(chǔ)進(jìn)它們里面的元素的個(gè)數(shù)超過(guò)了容量時(shí),就需要增加ArrayList與Vector的存儲(chǔ)空間,每次要增加存儲(chǔ)空間時(shí),不是只增加一個(gè)存儲(chǔ)單元,而是增加多個(gè)存儲(chǔ)單元,每次增加的存儲(chǔ)單元的個(gè)數(shù)在內(nèi)存空間利用與程序效率之間要取得一定的平衡。Vector默認(rèn)增長(zhǎng)為原來(lái)兩倍,而ArrayList的增長(zhǎng)策略在文檔中沒(méi)有明確規(guī)定(從源代碼看到的是增長(zhǎng)為原來(lái)的1.5倍)。ArrayList與Vector都可以設(shè)置初始的空間大小,Vector還可以設(shè)置增長(zhǎng)的空間大小,而ArrayList沒(méi)有提供設(shè)置增長(zhǎng)空間的方法。
    ? ? 總結(jié):即Vector增長(zhǎng)原來(lái)的一倍,ArrayList增加原來(lái)的0.5倍。


    20、HashMap和Hashtable的區(qū)別 &&?List 和 Map

    去看我關(guān)于集合類的講解就能答好了:http://blog.csdn.net/zhangerqing/article/details/8122075


    21、Collection 和 Collections的區(qū)別?
    Collection是集合類的上級(jí)接口,繼承與他的接口主要有Set 和List.?
    Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。


    22、Set里的元素是不能重復(fù)的,那么用什么方法來(lái)區(qū)分重復(fù)與否呢? 是用==還是equals()? 它們有何區(qū)別??
    Set里的元素是不能重復(fù)的,元素重復(fù)與否是使用equals()方法進(jìn)行判斷的。?
    equals()和==方法決定引用值是否指向同一對(duì)象equals()在類中被覆蓋,為的是當(dāng)兩個(gè)分離的對(duì)象的內(nèi)容和類型相配的話,返回真值。

    去看我關(guān)于集合類的講解有很詳細(xì)的回答:http://blog.csdn.net/zhangerqing/article/details/8122075


    23、說(shuō)出一些常用的類,包,接口,請(qǐng)各舉5個(gè)?

    這種弱智的問(wèn)題,總會(huì)有人考,沒(méi)辦法,有人考,你就得會(huì)。

    要讓人家感覺(jué)你對(duì)java ee開(kāi)發(fā)很熟,所以,不能僅僅只列core java中的那些東西,要多列你在做ssh項(xiàng)目中涉及的那些東西。就寫你最近寫的那些程序中涉及的那些類。

    常用的類:BufferedReader ?BufferedWriter ?FileReader ?FileWirter ?String ?Integer?
    java.util.Date,System,Class,List,HashMap

    常用的包:java.lang ? java.io ?java.util ?java.sql ,javax.servlet,org.apache.strtuts.action,org.hibernate
    常用的接口:Remote ?List ?Map ?Document ?NodeList ,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)、Session(Hibernate),HttpSession


    24、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請(qǐng)說(shuō)出他們分別是哪些類??

    字節(jié)流,字符流。字節(jié)流繼承于InputStream OutputStream,字符流繼承于InputStreamReader OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便


    25、字節(jié)流與字符流的區(qū)別
    要把一片二進(jìn)制數(shù)據(jù)數(shù)據(jù)逐一輸出到某個(gè)設(shè)備中,或者從某個(gè)設(shè)備中逐一讀取一片二進(jìn)制數(shù)據(jù),不管輸入輸出設(shè)備是什么,我們要用統(tǒng)一的方式來(lái)完成這些操作,用一種抽象的方式進(jìn)行描述,這個(gè)抽象描述方式起名為IO流,對(duì)應(yīng)的抽象類為OutputStream和InputStream ,不同的實(shí)現(xiàn)類就代表不同的輸入和輸出設(shè)備,它們都是針對(duì)字節(jié)進(jìn)行操作的。在應(yīng)用中,經(jīng)常要完全是字符的一段文本輸出去或讀進(jìn)來(lái),用字節(jié)流可以嗎?計(jì)算機(jī)中的一切最終都是二進(jìn)制的字節(jié)形式存在。對(duì)于“中國(guó)”這些字符,首先要得到其對(duì)應(yīng)的字節(jié),然后將字節(jié)寫入到輸出流。讀取時(shí),首先讀到的是字節(jié),可是我們要把它顯示為字符,我們需要將字節(jié)轉(zhuǎn)換成字符。由于這樣的需求很廣泛,人家專門提供了字符流的包裝類。底層設(shè)備永遠(yuǎn)只接受字節(jié)數(shù)據(jù),有時(shí)候要寫字符串到底層設(shè)備,需要將字符串轉(zhuǎn)成字節(jié)再進(jìn)行寫入。字符流是字節(jié)流的包裝,字符流則是直接接受字符串,它內(nèi)部將串轉(zhuǎn)成字節(jié),再寫入底層設(shè)備,這為我們向IO設(shè)別寫入或讀取字符串提供了一點(diǎn)點(diǎn)方便。字符向字節(jié)轉(zhuǎn)換時(shí),要注意編碼的問(wèn)題,因?yàn)樽址D(zhuǎn)成字節(jié)數(shù)組,其實(shí)是轉(zhuǎn)成該字符的某種編碼的字節(jié)形式,讀取也是反之的道理。下面是一個(gè)小的案例:

  • import java.io.BufferedReader;
  • import java.io.FileInputStream;
  • import java.io.FileOutputStream;
  • import java.io.FileReader;
  • import java.io.FileWriter;
  • import java.io.InputStreamReader;
  • import java.io.PrintWriter;
  • public class IOTest {
  • public static void main(String[] args) throws Exception {
  • String str = "中國(guó)人";
  • /*FileOutputStream fos = new FileOutputStream("1.txt");
  • fos.write(str.getBytes("UTF-8"));
  • fos.close();*/
  • /*FileWriter fw = new FileWriter("1.txt");
  • fw.write(str);
  • fw.close();*/
  • PrintWriter pw = new PrintWriter("1.txt","utf-8");
  • pw.write(str);
  • pw.close();
  • /*FileReader fr = new FileReader("1.txt");
  • char[] buf = new char[1024];
  • int len = fr.read(buf);
  • String myStr = new String(buf,0,len);
  • System.out.println(myStr);*/
  • /*FileInputStream fr = new FileInputStream("1.txt");
  • byte[] buf = new byte[1024];
  • int len = fr.read(buf);
  • String myStr = new String(buf,0,len,"UTF-8");
  • System.out.println(myStr);*/
  • BufferedReader br = new BufferedReader(
  • new InputStreamReader(
  • new FileInputStream("1.txt"),"UTF-8"
  • )
  • );
  • String myStr = br.readLine();
  • br.close();
  • System.out.println(myStr);
  • }
  • }

  • 26、什么是java序列化,如何實(shí)現(xiàn)java序列化?或者請(qǐng)解釋Serializable接口的作用

    我們有時(shí)候?qū)⒁粋€(gè)java對(duì)象變成字節(jié)流的形式傳出去或者從一個(gè)字節(jié)流中恢復(fù)成一個(gè)java對(duì)象,例如,要將java對(duì)象存儲(chǔ)到硬盤或者傳送給網(wǎng)絡(luò)上的其他計(jì)算機(jī),這個(gè)過(guò)程我們可以自己寫代碼去把一個(gè)java對(duì)象變成某個(gè)格式的字節(jié)流再傳輸,但是,jre本身就提供了這種支持,我們可以調(diào)用OutputStream的writeObject方法來(lái)做,如果要讓java?幫我們做,要被傳輸?shù)膶?duì)象必須實(shí)現(xiàn)serializable接口,這樣,javac編譯時(shí)就會(huì)進(jìn)行特殊處理,編譯的類才可以被writeObject方法操作,這就是所謂的序列化。需要被序列化的類必須實(shí)現(xiàn)Serializable接口,該接口是一個(gè)mini接口,其中沒(méi)有需要實(shí)現(xiàn)的方法,implements?Serializable只是為了標(biāo)注該對(duì)象是可被序列化的。?

    例如,在web開(kāi)發(fā)中,如果對(duì)象被保存在了Session中,tomcat在重啟時(shí)要把Session對(duì)象序列化到硬盤,這個(gè)對(duì)象就必須實(shí)現(xiàn)Serializable接口。如果對(duì)象要經(jīng)過(guò)分布式系統(tǒng)進(jìn)行網(wǎng)絡(luò)傳輸或通過(guò)rmi等遠(yuǎn)程調(diào)用,這就需要在網(wǎng)絡(luò)上傳輸對(duì)象,被傳輸?shù)膶?duì)象就必須實(shí)現(xiàn)Serializable接口。


    27、GC是什么??為什么要有GC??

    本博客關(guān)于垃圾回收的詳細(xì)介紹:http://blog.csdn.net/zhangerqing/article/details/8214365


    28、什么時(shí)候用assert?
    assertion(斷言)在軟件開(kāi)發(fā)中是一種常用的調(diào)試方式,很多開(kāi)發(fā)語(yǔ)言中都支持這種機(jī)制。在實(shí)現(xiàn)中,assertion就是在程序中的一條語(yǔ)句,它對(duì)一個(gè)boolean表達(dá)式進(jìn)行檢查,一個(gè)正確程序必須保證這個(gè)boolean表達(dá)式的值為true;如果該值為false,說(shuō)明程序已經(jīng)處于不正確的狀態(tài)下,assert將給出警告或退出。一般來(lái)說(shuō),assertion用于保證程序最基本、關(guān)鍵的正確性。assertion檢查通常在開(kāi)發(fā)和測(cè)試時(shí)開(kāi)啟。為了提高性能,在軟件發(fā)布后,assertion檢查通常是關(guān)閉的。?

  • package com.huawei.interview;
  • public class AssertTest {
  • /**
  • * @param args
  • */
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • int i = 0;
  • for(i=0;i<5;i++)
  • {
  • System.out.println(i);
  • }
  • //假設(shè)程序不小心多了一句--i;
  • --i;
  • assert i==5;
  • }
  • }

  • 29、java中會(huì)存在內(nèi)存泄漏嗎,請(qǐng)簡(jiǎn)單描述?
    所謂內(nèi)存泄露就是指一個(gè)不再被程序使用的對(duì)象或變量一直被占據(jù)在內(nèi)存中。java中有垃圾回收機(jī)制,它可以保證一對(duì)象不再被引用的時(shí)候,即對(duì)象編程了孤兒的時(shí)候,對(duì)象將自動(dòng)被垃圾回收器從內(nèi)存中清除掉。由于Java 使用有向圖的方式進(jìn)行垃圾回收管理,可以消除引用循環(huán)的問(wèn)題,例如有兩個(gè)對(duì)象,相互引用,只要它們和根進(jìn)程不可達(dá)的,那么GC也是可以回收它們的,例如下面的代碼可以看到這種情況的內(nèi)存回收:

  • package com.huawei.interview;
  • import java.io.IOException;
  • public class GarbageTest {
  • /**
  • * @param args
  • * @throws IOException
  • */
  • public static void main(String[] args) throws IOException {
  • // TODO Auto-generated method stub
  • try {
  • gcTest();
  • } catch (IOException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • System.out.println("has exited gcTest!");
  • System.in.read();
  • System.in.read();
  • System.out.println("out begin gc!");
  • for(int i=0;i<100;i++)
  • {
  • System.gc();
  • System.in.read();
  • System.in.read();
  • }
  • }
  • private static void gcTest() throws IOException {
  • System.in.read();
  • System.in.read();
  • Person p1 = new Person();
  • System.in.read();
  • System.in.read();
  • Person p2 = new Person();
  • p1.setMate(p2);
  • p2.setMate(p1);
  • System.out.println("before exit gctest!");
  • System.in.read();
  • System.in.read();
  • System.gc();
  • System.out.println("exit gctest!");
  • }
  • private static class Person
  • {
  • byte[] data = new byte[20000000];
  • Person mate = null;
  • public void setMate(Person other)
  • {
  • mate = other;
  • }
  • }
  • }

  • java中的內(nèi)存泄露的情況:長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄露,盡管短生命周期對(duì)象已經(jīng)不再需要,但是因?yàn)殚L(zhǎng)生命周期對(duì)象持有它的引用而導(dǎo)致不能被回收,這就是java中內(nèi)存泄露的發(fā)生場(chǎng)景,通俗地說(shuō),就是程序員可能創(chuàng)建了一個(gè)對(duì)象,以后一直不再使用這個(gè)對(duì)象,這個(gè)對(duì)象卻一直被引用,即這個(gè)對(duì)象無(wú)用但是卻無(wú)法被垃圾回收器回收的,這就是java中可能出現(xiàn)內(nèi)存泄露的情況,例如,緩存系統(tǒng),我們加載了一個(gè)對(duì)象放在緩存中(例如放在一個(gè)全局map對(duì)象中),然后一直不再使用它,這個(gè)對(duì)象一直被緩存引用,但卻不再被使用。檢查java中的內(nèi)存泄露,一定要讓程序?qū)⒏鞣N分支情況都完整執(zhí)行到程序結(jié)束,然后看某個(gè)對(duì)象是否被使用過(guò),如果沒(méi)有,則才能判定這個(gè)對(duì)象屬于內(nèi)存泄露。如果一個(gè)外部類的實(shí)例對(duì)象的方法返回了一個(gè)內(nèi)部類的實(shí)例對(duì)象,這個(gè)內(nèi)部類對(duì)象被長(zhǎng)期引用了,即使那個(gè)外部類實(shí)例對(duì)象不再被使用,但由于內(nèi)部類持久外部類的實(shí)例對(duì)象,這個(gè)外部類對(duì)象將不會(huì)被垃圾回收,這也會(huì)造成內(nèi)存泄露。下面內(nèi)容來(lái)自于網(wǎng)上(主要特點(diǎn)就是清空堆棧中的某個(gè)元素,并不是徹底把它從數(shù)組中拿掉,而是把存儲(chǔ)的總數(shù)減少,本人寫得可以比這個(gè)好,在拿掉某個(gè)元素時(shí),順便也讓它從數(shù)組中消失,將那個(gè)元素所在的位置的值設(shè)置為null即可):我實(shí)在想不到比那個(gè)堆棧更經(jīng)典的例子了,以致于我還要引用別人的例子,下面的例子不是我想到的,是書上看到的,當(dāng)然如果沒(méi)有在書上看到,可能過(guò)一段時(shí)間我自己也想的到,可是那時(shí)我說(shuō)是我自己想到的也沒(méi)有人相信的。


    30、

    作者:egg

    郵箱:xtfggef@gmail.com

    微博:http://weibo.com/xtfggef

    博客:http://blog.csdn.net/zhangerqing(轉(zhuǎn)載請(qǐng)說(shuō)明出處)


    大家有什么補(bǔ)充的,在下面回復(fù),同時(shí)也希望提出寶貴的意見(jiàn)!

    題目和答案有些來(lái)自網(wǎng)絡(luò)和傳智播客張孝祥老師的整理,本人收集的,如果有回答不恰當(dāng)?shù)牡胤?#xff0c;還望及時(shí)指出、改正!

    與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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