JAVA基礎(chǔ)鞏固隨筆

1、實(shí)例方法和靜態(tài)方法有什么不一樣?

答:實(shí)例方法只能在其類下調(diào)用,而靜態(tài)方法可以直接調(diào)用。

答:1、在外部調(diào)用靜態(tài)方法時(shí)可以用“類名.方法名”和“對(duì)象名.方法名”調(diào)用方法;而實(shí)例方法只能用“對(duì)象名.方法名”調(diào)用方法。(調(diào)用靜態(tài)方法可以無(wú)需創(chuàng)建對(duì)象)2、靜態(tài)方法在訪問(wèn)本類時(shí)不能直接調(diào)用實(shí)例成員(實(shí)例成員變量和實(shí)例方法),只能調(diào)用靜態(tài)成員;而實(shí)例方法則都可以。

2、Java中的異常有哪幾類?分別怎么使用?

答:常見(jiàn)的異常有:

1、java.lang.nullpointerexception “程序遇上了空指針”,即調(diào)用了未經(jīng)初始化的對(duì)象或者是不存在。

2、java.lang.classnotfoundexception “指定類不存在”,這里主要注意類的名稱或路徑是否正確。

3、java.lang.arrayindexoutofboundsexception “數(shù)組下標(biāo)越界”,即調(diào)用的數(shù)組下標(biāo)超過(guò)了數(shù)組的范圍。

4、FileNotFoundException “文件未找到異常”,檢查文件名是否正確或是否存在。

5、IOException “輸入輸出流異常” ,進(jìn)行輸入輸出操作時(shí)出問(wèn)題或找不到文件。

6、NoSuchMehodException “方法異常”,調(diào)用的放法未定義。

三、常用的集合類有哪些?

答:List,Set,Map。

1、List:實(shí)現(xiàn)類ArrayList和LinkedList

①、ArrayList:索引從零開(kāi)始,線性存儲(chǔ),有索引,有順序、可重復(fù)

②、LinkedList:線性存儲(chǔ),有索引、有順序、鏈表結(jié)構(gòu)、可重復(fù)

2、Set:不需要編號(hào)與名,存放速度快但不好取,不允許重復(fù),具體的 Set 實(shí)現(xiàn)類依賴添加的對(duì)象的 equals() 方法來(lái)檢查等同性,實(shí)現(xiàn)類HashSet和TreeSet

①、HashSet:無(wú)序,調(diào)用對(duì)象的hashCode()方法,獲取哈希碼,從在集合中計(jì)算存放對(duì)象的位置;底層通過(guò)比較哈希碼與equals()方法來(lái)判別是否重復(fù)。

②、TreeSet:樹(shù)型排序,只能對(duì)實(shí)現(xiàn)了Comparable借口的對(duì)象排序。

3、Map:以鍵值對(duì)的形式存儲(chǔ)對(duì)象,鍵不能重復(fù),實(shí)現(xiàn)類HashMap和TreeMap

①、HashMap:無(wú)序、按照哈希算法來(lái)存取鍵對(duì)象,可重載hashCode()和equals()方法來(lái)比較鍵,但兩者必須一致。

②、TreeMap:可樹(shù)型排序,通過(guò)傳遞Comparator的實(shí)現(xiàn)類構(gòu)造TreeMap。

4、ArrayList和LinkedList的內(nèi)部實(shí)現(xiàn)?

答:ArrayList是基于數(shù)組的數(shù)據(jù)結(jié)構(gòu),其在增加時(shí)若數(shù)組不滿足增加量時(shí)會(huì)進(jìn)行數(shù)組擴(kuò)容,同時(shí)還需要數(shù)據(jù)搬遷,同理在刪除時(shí)也需要數(shù)據(jù)搬遷。

LinkedList是基于鏈表的數(shù)據(jù)結(jié)構(gòu),通過(guò)內(nèi)部的一個(gè)元素類內(nèi)存放元素,增加和刪除只需要在上下指針增減新元素。

所以,ArrayList的讀取性較好,基于數(shù)組索引的index索引,但寫入率不太好,需要數(shù)據(jù)搬遷,適合于隨機(jī)讀取;而LinkedList的讀取率不太好,需要遍歷鏈表,但寫入率可以,更適用于順序讀取。

5、內(nèi)存溢出?

答:即運(yùn)行所需內(nèi)存超過(guò)JVM所提供的內(nèi)存承受范圍,JVM所管理的內(nèi)存大致分為三部分區(qū)域:①永久保存區(qū)域 ? ②堆區(qū)域 ?③JAVA棧區(qū)域?

①永久保存區(qū)域:主要保存class 和 mete的信息,class需要保存的內(nèi)容主要包括方法和靜態(tài)屬性;

②堆區(qū)域:主要存放的是對(duì)象,每次用new創(chuàng)建一個(gè)對(duì)象實(shí)例時(shí),對(duì)象實(shí)例存儲(chǔ)于堆區(qū)域,這部分空間會(huì)被JVM的垃圾回收機(jī)制管理,堆區(qū)域只有一個(gè);

③JAVA棧區(qū)域:主要存放基本類型變量和方法的輸入輸出參數(shù)以及對(duì)象的引用,JAVA程序的每個(gè)線程就有一個(gè)獨(dú)立的Java棧。

6、ClassLoader?

答:類加載器。Java程序(class文件)并不是本地的可執(zhí)行文件。當(dāng)運(yùn)行Java文件時(shí),首先運(yùn)行JVM,然后再把Java class加載到JVM中運(yùn)行,負(fù)責(zé)加載Java class的部分就叫ClassLoader。

7、==和equals的區(qū)別?

答:對(duì)于基本數(shù)據(jù)類型,==比較的是值是否相同,對(duì)于引用對(duì)象,==比較的是一個(gè)對(duì)象在內(nèi)存中的地址。

而equals 不用于比較基本類型但可以用于比較基本數(shù)據(jù)類型包裝類的值是否相等,對(duì)于引用對(duì)象,equals在Java.lang.object中定義的是同樣用==對(duì)內(nèi)存地址進(jìn)行比較,而在許多類中都重寫類該方法,比如String會(huì)對(duì)內(nèi)存地址引用不相等時(shí),還會(huì)進(jìn)行值比較,所以如果沒(méi)有重寫父類object的equals時(shí),它用法與==一樣。

8、hashCode()方法的作用?

答:hashCode()在Object中定義,根據(jù)對(duì)象的特定字段運(yùn)用哈希算法得出特定的哈希碼,一般hashCode()方法運(yùn)用于集合中根據(jù)哈希碼加快查詢的速率,迅速地查找出相匹配的桶取出值,同時(shí)hashCode()常用于equals()方法中根據(jù)哈希碼比對(duì)對(duì)象的內(nèi)存地址是否相同。

9、Object類常用的方法?

答:boolean equals(Object object)判斷某對(duì)象是否與此對(duì)象“相等”。

int hashCode()返回對(duì)象的哈希碼值。

String toString()返回對(duì)象的字符串表達(dá)。

10、NIO是什么?

答:即non-blocking IO,為所有的原始類型提供緩存支持,定義為數(shù)據(jù)容器的緩沖區(qū)。其Channel不同于IO的單向Stream,Channel是雙向的可讀可寫;Buffer(緩沖區(qū))相當(dāng)于一個(gè)容器,NIO寫數(shù)據(jù)和讀數(shù)據(jù)放進(jìn)Buffer中;Selector是NIO的核心類,Selector能夠檢測(cè)多個(gè)注冊(cè)通道上是否有事件發(fā)生,若有,便獲取事件然后對(duì)事件進(jìn)行相應(yīng)的響應(yīng)。這樣便可以單個(gè)線程管理多個(gè)連接,同時(shí)大大減少了系統(tǒng)開(kāi)銷,不必創(chuàng)建多個(gè)線程。

11、GC(垃圾回收)算法?

答:①、引用計(jì)數(shù)(reference counting)原理:此對(duì)象有一個(gè)引用,則+1;此對(duì)象刪除一個(gè)引用,則-1。GC收集為0的對(duì)象。

②、復(fù)制(copying)原理:把內(nèi)存空間分為兩個(gè)相等的區(qū)域,每次只使用一個(gè)區(qū)域。垃圾回收時(shí),便利當(dāng)前區(qū)域把正在使用的對(duì)象復(fù)制到另一份區(qū)域。

③、標(biāo)記-清掃(Mark and sweep)原理:對(duì)于“活”的對(duì)象,一定可以追溯到其存活在堆棧和靜態(tài)存儲(chǔ)區(qū)的引用。這個(gè)引用鏈條可能穿過(guò)數(shù)個(gè)對(duì)象層次,算法基于有向圖,采用深度游戲搜索。先從GC roots開(kāi)始遍歷所有引用,對(duì)活的對(duì)象進(jìn)行標(biāo)記,然后對(duì)堆進(jìn)行遍歷把未標(biāo)記的對(duì)象清除。

④、標(biāo)記-壓縮(Mark-Compact)原理:同標(biāo)記-清除,標(biāo)記活的對(duì)象,然后將所有標(biāo)記了的對(duì)象整理到堆的底部。

⑤、分代(generationl collecting)原理:基于對(duì)象生命周期分析得出的垃圾回收算法。把對(duì)象分為年輕代、年老代、持久代,對(duì)不同的生命周期進(jìn)行不同的算法進(jìn)行回收。

新生代的GC(Minor GC)Minor GC非常頻繁,一般回收速度也比較快。新生代存活時(shí)間較短,因此基于Copying算法來(lái)進(jìn)行回收,對(duì)于新生代就是就是在Eden和FromSpace或ToSpace之間copy,新生代采用空閑指針的方式來(lái)控制GC觸發(fā),指針保持最后一個(gè)分配的對(duì)象在新生代區(qū)間的位置,當(dāng)有新的對(duì)象要分配內(nèi)存時(shí),用于檢查空間是否足夠,不夠就觸發(fā)GC。當(dāng)連續(xù)分配對(duì)象時(shí),對(duì)象會(huì)逐漸從eden到survivor。

舊生代的GC(MajorGC/FullGC)對(duì)象存活比較久,比較穩(wěn)定,因此采用Mark算法進(jìn)行回收,掃描標(biāo)記處活的對(duì)象,然后未標(biāo)記的對(duì)象進(jìn)行回收,回收后對(duì)空出來(lái)的空間進(jìn)行合并,要么標(biāo)記出來(lái)便于下次分配,總之減少內(nèi)存碎片帶來(lái)的損耗。

MajorGC 的速度一般會(huì)比 Minor GC 慢 10倍以上。

java GC即是“自適應(yīng)、分代的、停止-復(fù)制、標(biāo)記-掃描”式的垃圾回收器。

12、CMS(Concurrent Mark Sweep)?

答:并行垃圾處理機(jī)制,GC和程序并發(fā)執(zhí)行。

Young GC,Stop the world凍結(jié)所有內(nèi)存,程序執(zhí)行,但并發(fā)的程序需要一些Stop the world的時(shí)間和Copying collector,多線程操作掃描和Copy,減少Stop the world的時(shí)間。

Old GC,程序和GC并發(fā)執(zhí)行:

Initial Phase:短暫停,標(biāo)記GC根集合,單線程執(zhí)行。

Concurrent making phase:GC多線程標(biāo)記從根集合可達(dá)的所有活對(duì)象。由于程序和GC并發(fā)運(yùn)行,可能有活對(duì)象未被標(biāo)記。

Concurrent pre-clean:?jiǎn)尉€程,并發(fā)執(zhí)行。

Remark phase: 短暫停,多線程標(biāo)記在Concurrent marking phase中有變化的相關(guān)對(duì)象。

Concurrent sweep phase:和程序并發(fā)執(zhí)行。單線程執(zhí)行。不做compacting。

concurrent reset:?jiǎn)尉€程,并發(fā)執(zhí)行。

CMS需要更多的內(nèi)存空間,因?yàn)閙ark phase時(shí)程序還是在運(yùn)行,程序可以申請(qǐng)更多的old空間。在mark phase中,CMS保證標(biāo)識(shí)活對(duì)象,但是該過(guò)程中,活對(duì)象可能轉(zhuǎn)變?yōu)槔荒艿却乱淮蜧C才能回收。

和其他Collector不同,CMS不是等到old滿時(shí)才GC,基于以前的統(tǒng)計(jì)數(shù)據(jù)(GC時(shí)間,Old空間消耗速度)來(lái)決定何時(shí)GC。CMS GC也可以基于old空間的占用率。

13、創(chuàng)建類的實(shí)例的方法?

①、用new語(yǔ)句創(chuàng)建對(duì)象,這是最常見(jiàn)的創(chuàng)建對(duì)象的方法。

②、通過(guò)工廠方法返回對(duì)象,如:String str = String.valueOf(23);

③、運(yùn)用反射手段,調(diào)用java.lang.Class或者java.lang.reflect.Constructor類的newInstance()實(shí)例方法。如:Object obj = Class.forName("java.lang.Object").newInstance();

④、調(diào)用對(duì)象的clone()方法。

⑤、通過(guò)I/O流(包括反序列化),如運(yùn)用反序列化手段,調(diào)用java.io.ObjectInputStream對(duì)象的 readObject()方法。

14、final/finally/finalize的區(qū)別?

答:①:final為用于標(biāo)示常量的關(guān)鍵字,若定義的是基本類型,表示基本類型被賦予的值不可變;若定義方法,表示方法不能被覆蓋;若定義類,表示類不能被繼承。

②:finally是異常處理try/catch語(yǔ)句的一部分,表示無(wú)論是try或catch,finally里的語(yǔ)句都會(huì)在最后被執(zhí)行。

③:finalize()是Object類的一個(gè)子方法,由垃圾收集器在確定這個(gè)對(duì)象沒(méi)有被引用時(shí)對(duì)這個(gè)對(duì)象調(diào)用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。

15、Session/Cookie的區(qū)別?

答:①,session 在服務(wù)器端,cookie 在客戶端(瀏覽器)

②,session 默認(rèn)被存在在服務(wù)器的一個(gè)文件里(不是內(nèi)存)

③,session 的運(yùn)行依賴 session id,而 session id 是存在 cookie 中的,也就是說(shuō),如果瀏覽器禁用了 cookie ,同時(shí) session 也會(huì)失效(但是可以通過(guò)其它方式實(shí)現(xiàn),比如在 url 中傳遞 session_id)

④,session 可以放在 文件、數(shù)據(jù)庫(kù)、或內(nèi)存中都可以。

⑤,用戶驗(yàn)證這種場(chǎng)合一般會(huì)用 session

16、StringBuffer/StringBuilder的區(qū)別,擴(kuò)展再問(wèn)他們的實(shí)現(xiàn)?

①.? 在執(zhí)行速度方面的比較:StringBuilder >? StringBuffer

②.? StringBuffer與StringBuilder,他們是字符串變量,是可改變的對(duì)象,每當(dāng)我們用它們對(duì)字符串做操作時(shí),實(shí)際上是在一個(gè)對(duì)象上操作的,不像String一樣創(chuàng)建一些對(duì)象進(jìn)行操作,所以速度就快了。

③.? StringBuilder:線程非安全的

StringBuffer:線程安全的

StringBuffer與StringBuilder都繼承自AbstractStringBuilder

AbstractStringBuilder的實(shí)現(xiàn)原理:我們知道使用StringBuffer等無(wú)非就是為了提高java中字符串連接的效率,因?yàn)橹苯邮褂?進(jìn)行字符串連接的話,jvm會(huì)創(chuàng)建多個(gè)String對(duì)象,因此造成一定的開(kāi)銷。AbstractStringBuilder中采用一個(gè)char數(shù)組來(lái)保存需要append的字符串,char數(shù)組有一個(gè)初始大小,當(dāng)append的字符串長(zhǎng)度超過(guò)當(dāng)前char數(shù)組容量時(shí),則對(duì)char數(shù)組進(jìn)行動(dòng)態(tài)擴(kuò)展,也即重新申請(qǐng)一段更大的內(nèi)存空間,然后將當(dāng)前char數(shù)組拷貝到新的位置,因?yàn)橹匦路峙鋬?nèi)存并拷貝的開(kāi)銷比較大,所以每次重新申請(qǐng)內(nèi)存空間都是采用申請(qǐng)大于當(dāng)前需要的內(nèi)存空間的方式,這里是2倍。

17、Servlet的生命周期?

①、初始化階段,調(diào)用Init()方法。(Servlet初始化的時(shí)刻:①、Servlet容器啟動(dòng)時(shí)自動(dòng)裝載某些Servlet,實(shí)現(xiàn)它要在Web.xml文件中的<Servlet></Servlet>之間調(diào)到代碼;②、在Servlet容器啟動(dòng)時(shí),客戶首次向Servlet發(fā)送請(qǐng)求;③、Servlet類文件更新后,重新裝載Servlet。)

Servlet被裝載后,Servlet容器創(chuàng)建Servlet實(shí)例并調(diào)用Init()方法進(jìn)行初始化,整個(gè)Servlet周期內(nèi),Init()方法只被調(diào)用一次。

②、響應(yīng)客戶請(qǐng)求,調(diào)用Service()方法。

③、終止階段,調(diào)用Destory()方法。

Servlet工作原理:

首先簡(jiǎn)單解釋一下Servlet接收和響應(yīng)客戶請(qǐng)求的過(guò)程,首先客戶發(fā)送一個(gè)請(qǐng)求,Servlet是調(diào)用service()方法對(duì)請(qǐng)求進(jìn)行響應(yīng)的,service()方法中對(duì)請(qǐng)求的方式進(jìn)行了匹配,選擇調(diào)用doGet,doPost等這些方法,然后再進(jìn)入對(duì)應(yīng)的方法中調(diào)用邏輯層的方法,實(shí)現(xiàn)對(duì)客戶的響應(yīng)。在Servlet接口和GenericServlet中是沒(méi)有doGet,doPost等等這些方法的,HttpServlet中定義了這些方法,但是都是返回error信息,所以,我們每次定義一個(gè)Servlet的時(shí)候,都必須實(shí)現(xiàn)doGet或doPost等這些方法。

每一個(gè)自定義的Servlet都必須實(shí)現(xiàn)Servlet的接口,Servlet接口中定義了五個(gè)方法,其中比較重要的三個(gè)方法涉及到Servlet的生命周期,分別是上文提到的init(),service(),destroy()方法。GenericServlet是一個(gè)通用的,不特定于任何協(xié)議的Servlet,它實(shí)現(xiàn)了Servlet接口。而HttpServlet繼承于GenericServlet,因此HttpServlet也實(shí)現(xiàn)了Servlet接口。所以我們定義Servlet的時(shí)候只需要繼承HttpServlet即可。

Servlet接口和GenericServlet是不特定于任何協(xié)議的,而HttpServlet是特定于HTTP協(xié)議的類,所以HttpServlet中實(shí)現(xiàn)了service()方法,并將請(qǐng)求ServletRequest,ServletResponse強(qiáng)轉(zhuǎn)為HttpRequest和HttpResponse。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,372評(píng)論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,767評(píng)論 18 399
  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供...
    簡(jiǎn)欲明心閱讀 89,888評(píng)論 17 311
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,142評(píng)論 0 62
  • 妙語(yǔ)連珠 裊裊婷婷、耿耿于懷、山窮水盡、記憶開(kāi)始蘇醒、與世隔絕、避風(fēng)港、心靈無(wú)家可歸、太空電梯 心靈之約 葉文潔利...
    章魚閱讀 119評(píng)論 0 0