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)方法可以無需創(chuàng)建對(duì)象)2膨俐、靜態(tài)方法在訪問本類時(shí)不能直接調(diào)用實(shí)例成員(實(shí)例成員變量和實(shí)例方法)勇皇,只能調(diào)用靜態(tài)成員;而實(shí)例方法則都可以焚刺。
2敛摘、Java中的異常有哪幾類?分別怎么使用乳愉?
答:常見的異常有:
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)超過了數(shù)組的范圍备闲。
4挖滤、FileNotFoundException “文件未找到異常”浅役,檢查文件名是否正確或是否存在斩松。
5、IOException “輸入輸出流異尘跫龋” 惧盹,進(jìn)行輸入輸出操作時(shí)出問題或找不到文件。
6瞪讼、NoSuchMehodException “方法異尘”,調(diào)用的放法未定義符欠。
三嫡霞、常用的集合類有哪些?
答:List希柿,Set诊沪,Map。
1曾撤、List:實(shí)現(xiàn)類ArrayList和LinkedList
①端姚、ArrayList:索引從零開始,線性存儲(chǔ)挤悉,有索引渐裸,有順序、可重復(fù)
②、LinkedList:線性存儲(chǔ)昏鹃,有索引尚氛、有順序、鏈表結(jié)構(gòu)洞渤、可重復(fù)
2怠褐、Set:不需要編號(hào)與名,存放速度快但不好取您宪,不允許重復(fù)奈懒,具體的 Set 實(shí)現(xiàn)類依賴添加的對(duì)象的 equals() 方法來檢查等同性,實(shí)現(xiàn)類HashSet和TreeSet
①宪巨、HashSet:無序磷杏,調(diào)用對(duì)象的hashCode()方法,獲取哈希碼捏卓,從在集合中計(jì)算存放對(duì)象的位置极祸;底層通過比較哈希碼與equals()方法來判別是否重復(fù)。
②怠晴、TreeSet:樹型排序遥金,只能對(duì)實(shí)現(xiàn)了Comparable借口的對(duì)象排序。
3蒜田、Map:以鍵值對(duì)的形式存儲(chǔ)對(duì)象稿械,鍵不能重復(fù),實(shí)現(xiàn)類HashMap和TreeMap
①冲粤、HashMap:無序美莫、按照哈希算法來存取鍵對(duì)象,可重載hashCode()和equals()方法來比較鍵梯捕,但兩者必須一致厢呵。
②、TreeMap:可樹型排序傀顾,通過傳遞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)隆豹,通過內(nèi)部的一個(gè)元素類內(nèi)存放元素椭岩,增加和刪除只需要在上下指針增減新元素。
所以,ArrayList的讀取性較好判哥,基于數(shù)組索引的index索引献雅,但寫入率不太好,需要數(shù)據(jù)搬遷塌计,適合于隨機(jī)讀韧ι怼;而LinkedList的讀取率不太好锌仅,需要遍歷鏈表章钾,但寫入率可以,更適用于順序讀取热芹。
5贱傀、內(nèi)存溢出?
答:即運(yùn)行所需內(nèi)存超過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)行值比較姜性,所以如果沒有重寫父類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)開銷闯冷,不必創(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è)引用鏈條可能穿過數(shù)個(gè)對(duì)象層次谭网,算法基于有向圖汪厨,采用深度游戲搜索。先從GC roots開始遍歷所有引用愉择,對(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算法來進(jìn)行回收嫡纠,對(duì)于新生代就是就是在Eden和FromSpace或ToSpace之間copy,新生代采用空閑指針的方式來控制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ì)空出來的空間進(jìn)行合并,要么標(biāo)記出來便于下次分配待榔,總之減少內(nè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ì)象系瓢,但是該過程中阿纤,活對(duì)象可能轉(zhuǎn)變?yōu)槔荒艿却乱淮蜧C才能回收夷陋。
和其他Collector不同欠拾,CMS不是等到old滿時(shí)才GC,基于以前的統(tǒng)計(jì)數(shù)據(jù)(GC時(shí)間肌稻,Old空間消耗速度)來決定何時(shí)GC清蚀。CMS GC也可以基于old空間的占用率匕荸。
13爹谭、創(chuàng)建類的實(shí)例的方法?
①榛搔、用new語句創(chuàng)建對(duì)象诺凡,這是最常見的創(chuàng)建對(duì)象的方法。
②践惑、通過工廠方法返回對(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()方法。
⑤侦铜、通過I/O流(包括反序列化)专甩,如運(yùn)用反序列化手段,調(diào)用java.io.ObjectInputStream對(duì)象的 readObject()方法钉稍。
14涤躲、final/finally/finalize的區(qū)別?
答:①:final為用于標(biāo)示常量的關(guān)鍵字贡未,若定義的是基本類型种樱,表示基本類型被賦予的值不可變;若定義方法俊卤,表示方法不能被覆蓋嫩挤;若定義類,表示類不能被繼承消恍。
②:finally是異常處理try/catch語句的一部分岂昭,表示無論是try或catch,finally里的語句都會(huì)在最后被執(zhí)行哺哼。
③:finalize()是Object類的一個(gè)子方法佩抹,由垃圾收集器在確定這個(gè)對(duì)象沒有被引用時(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 中的奥洼,也就是說巷疼,如果瀏覽器禁用了 cookie ,同時(shí) session 也會(huì)失效(但是可以通過其它方式實(shí)現(xiàn)灵奖,比如在 url 中傳遞 session_id)
④嚼沿,session 可以放在 文件、數(shù)據(jù)庫瓷患、或內(nèi)存中都可以骡尽。
⑤,用戶驗(yàn)證這種場(chǎng)合一般會(huì)用 session
16擅编、StringBuffer/StringBuilder的區(qū)別攀细,擴(kuò)展再問他們的實(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等無非就是為了提高java中字符串連接的效率鱼的,因?yàn)橹苯邮褂?進(jìn)行字符串連接的話,jvm會(huì)創(chuàng)建多個(gè)String對(duì)象痘煤,因此造成一定的開銷凑阶。AbstractStringBuilder中采用一個(gè)char數(shù)組來保存需要append的字符串,char數(shù)組有一個(gè)初始大小衷快,當(dāng)append的字符串長度超過當(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)存并拷貝的開銷比較大环葵,所以每次重新申請(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)求的過程,首先客戶發(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中是沒有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。