java判断时间区间 隔天_Java初中级程序员面试题宝典
Java基礎(chǔ)部分
&與&&區(qū)別?
&和&&都是邏輯運(yùn)算符,都是判斷兩邊同時(shí)真則為真,否則為假;但是&&當(dāng)?shù)谝粋€(gè)條件不成之后,后面的條件都不執(zhí)行了,而&則還是繼續(xù)執(zhí)行,直到整個(gè)條件語(yǔ)句執(zhí)行完為止。
使用 final 關(guān)鍵字修飾一個(gè)變量時(shí),是引用不能變,還是引用的對(duì)象不能變?
使用 final 關(guān)鍵字修飾一個(gè)變量時(shí),是指引用變量不能變,引用變量所指向的對(duì)象中的內(nèi)容 還是可以改變的。
靜態(tài)變量和實(shí)例變量的區(qū)別?
在語(yǔ)法定義上的區(qū)別:
靜態(tài)變量前要加 static 關(guān)鍵字,而實(shí)例變量前則不加。
在程序運(yùn)行時(shí)的區(qū)別:實(shí)例變量屬于某個(gè)對(duì)象的屬性,必須創(chuàng)建了實(shí)例對(duì)象,其中的實(shí)例變 量才會(huì)被分配空間,才能使用這個(gè)實(shí)例變量。
靜態(tài)變量不屬于某個(gè)實(shí)例對(duì)象,而是屬于類(lèi), 所以也稱(chēng)為類(lèi)變量,只要程序加載了類(lèi)的字節(jié)碼,不用創(chuàng)建任何實(shí)例對(duì)象,靜態(tài)變量就會(huì)被分配空間,靜態(tài)變量就可以被使用了。
總之,實(shí)例變量必須創(chuàng)建對(duì)象后才可以通過(guò)這個(gè)對(duì)象 來(lái)使用,靜態(tài)變量則可以直接使用類(lèi)名來(lái)引用。
靜態(tài)變量使用時(shí),通過(guò)類(lèi)名.名稱(chēng),實(shí)例變量必須要初始化后才能使用。實(shí)例變量是實(shí)例化后才會(huì)分配空間,而靜態(tài)變量當(dāng)類(lèi)加載時(shí)會(huì)分配空間。
是否可以從一個(gè) static 方法內(nèi)部發(fā)出對(duì)非 static 方法的調(diào)用?
不可以。因?yàn)榉?static 方法是要與對(duì)象關(guān)聯(lián)在一起的,必須創(chuàng)建一個(gè)對(duì)象后,才可以在該對(duì) 象上進(jìn)行方法調(diào)用,而 static 方法調(diào)用時(shí)不需要?jiǎng)?chuàng)建對(duì)象,可以直接調(diào)用。也就是說(shuō),當(dāng)一 個(gè) static 方法被調(diào)用時(shí),可能還沒(méi)有創(chuàng)建任何實(shí)例對(duì)象,如果從一個(gè) static 方法中發(fā)出對(duì)非 static 方法的調(diào)用,那個(gè)非 static 方法是關(guān)聯(lián)到哪個(gè)對(duì)象上的呢?這個(gè)邏輯無(wú)法成立,所以, 一個(gè) static 方法內(nèi)部發(fā)出對(duì)非 static 方法的調(diào)用。
非static方法可以訪(fǎng)問(wèn)static方法.
static方法不能訪(fǎng)問(wèn)非static方法
"=="和 equals 方法究竟有什么區(qū)別?
==如果判斷值類(lèi)型的話(huà),判斷內(nèi)容是否相同。如果判斷引用類(lèi)型則是判斷內(nèi)存地址是否相同
Equals判斷值內(nèi)容是否相等
Integer 與 int 的區(qū)別
Integer 是引用類(lèi)型,默認(rèn)值是null。而int是是值類(lèi)型默認(rèn)值是0
請(qǐng)說(shuō)出作用域 public, private, protected,以及不寫(xiě)時(shí)的區(qū)別
這四個(gè)作用域的可見(jiàn)范圍如下表所示。
說(shuō)明:如果在修飾的元素上面沒(méi)有寫(xiě)任何訪(fǎng)問(wèn)修飾符,則表示 friendly。
作用域 當(dāng)前類(lèi) 同一包( package) 子孫類(lèi) 其他包( package)
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
重載與重寫(xiě)區(qū)別?
重載是同一個(gè)類(lèi)中,方法名稱(chēng)相同, 但是參數(shù)或個(gè)數(shù)不同。與返回值沒(méi)有關(guān)系。
重寫(xiě)是在多個(gè)類(lèi)中, 產(chǎn)生繼承關(guān)系。父類(lèi)與子類(lèi)的方法方法必須相同。
接口與抽象類(lèi)的區(qū)別?
區(qū)別:定義接口的關(guān)鍵字是:interface 而定義抽象類(lèi)的關(guān)鍵字是:abstract。
接口中成員不能有私有, 抽象類(lèi)可以。
接口中定義的成員, 是finl public static 類(lèi)型, 抽象類(lèi)沒(méi)有。
接口中的不能有普通方法, 抽象類(lèi)中可以。
相同:
兩個(gè)都不new
但是 接口與抽象類(lèi)是面向?qū)ο蟊貍渲R(shí),設(shè)計(jì)模式、重構(gòu)代碼有必然作用
final, finally, finalize 的區(qū)別。
final 用于聲明屬性,方法和類(lèi),分別表示屬性不可變,方法不可覆蓋,類(lèi)不可繼承。
內(nèi)部類(lèi)要訪(fǎng)問(wèn)局部變量,局部變量必須定義成 final 類(lèi)型,例如,一段代碼……
finally 是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。
finalize 是 Object 類(lèi)的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可
以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。 JVM 不保證此方法總被
調(diào)用
String、StringBuffer與StringBuilder的區(qū)別
String 字符串常量
StringBuffer 字符串變量(線(xiàn)程安全)
StringBuilder 字符串變量(非線(xiàn)程安全)
所有的類(lèi)都繼承于object類(lèi),你用過(guò)的object類(lèi)的直接子類(lèi)有哪些,object類(lèi)常用的方法
有哪些
1.clone方法
保護(hù)方法,實(shí)現(xiàn)對(duì)象的淺復(fù)制,只有實(shí)現(xiàn)了Cloneable接口才可以調(diào)用該方法,否則拋出CloneNotSupportedException異常。
2.getClass方法
final方法,獲得運(yùn)行時(shí)類(lèi)型。
3.toString方法
該方法用得比較多,一般子類(lèi)都有覆蓋。
4.finalize方法
該方法用于釋放資源。因?yàn)闊o(wú)法確定該方法什么時(shí)候被調(diào)用,很少使用。
5.equals方法
該方法是非常重要的一個(gè)方法。一般equals和==是不一樣的,但是在Object中兩者是一樣的。子類(lèi)一般都要重寫(xiě)這個(gè)方法。
6.數(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è)方法。
7.hashCode方法
該方法用于哈希查找,重寫(xiě)了equals方法一般都要重寫(xiě)hashCode方法。這個(gè)方法在一些具有哈希功能的Collection中用到。
一般必須滿(mǎn)足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就滿(mǎn)足equals。不過(guò)為了提高效率,應(yīng)該盡量使上面兩個(gè)條件接近等價(jià)。
7.wait方法
wait方法就是使當(dāng)前線(xiàn)程等待該對(duì)象的鎖,當(dāng)前線(xiàn)程必須是該對(duì)象的擁有者,也就是具有該對(duì)象的鎖。wait()方法一直等待,直到獲得鎖或者被中斷。wait(long timeout)設(shè)定一個(gè)超時(shí)間隔,如果在規(guī)定時(shí)間內(nèi)沒(méi)有獲得鎖就返回。
調(diào)用該方法后當(dāng)前線(xiàn)程進(jìn)入睡眠狀態(tài),直到以下事件發(fā)生。
(1)其他線(xiàn)程調(diào)用了該對(duì)象的notify方法。
(2)其他線(xiàn)程調(diào)用了該對(duì)象的notifyAll方法。
(3)其他線(xiàn)程調(diào)用了interrupt中斷該線(xiàn)程。
(4)時(shí)間間隔到了。
此時(shí)該線(xiàn)程就可以被調(diào)度了,如果是被中斷的話(huà)就拋出一個(gè)InterruptedException異常。
8.notify方法
該方法喚醒在該對(duì)象上等待的某個(gè)線(xiàn)程。
9.notifyAll方法
該方法喚醒在該對(duì)象上等待的所有線(xiàn)程
反射的優(yōu)缺點(diǎn)?
反射:就是正在運(yùn)行動(dòng)態(tài)讀取這個(gè)類(lèi)的完整信息。
優(yōu)點(diǎn):java的反射機(jī)制就是增加程序的靈活性、
缺點(diǎn):缺點(diǎn):(1)性能問(wèn)題:使用反射基本上是一種解釋操作,
用于字段和方法接入時(shí)要遠(yuǎn)慢于直接代碼。因此反射機(jī)制主要應(yīng)用在對(duì)靈活性和擴(kuò)展性要求很高的系統(tǒng)框架上,普通程序不建議使用。
(2)使用反射會(huì)模糊程序內(nèi)內(nèi)部邏輯:程序員希望在源代碼中看到程序的邏輯,反射等繞過(guò)了源代碼的技術(shù),因而會(huì)帶來(lái)維護(hù)問(wèn)題。反射代碼比相應(yīng)的直接代碼更復(fù)雜。
那些地方用到了反射?
例如: jdbc、Java常用框架、jdk的動(dòng)態(tài)代理、android的加載布局文件
java 中有幾種類(lèi)型的流?JDK 為每種類(lèi)型的流提供了一些抽象類(lèi)以供繼承, 為每種類(lèi)型的流提供了一些抽象類(lèi)以供繼承,
請(qǐng)說(shuō)出他們分別是哪些類(lèi)?
字節(jié)流,字符流。字節(jié)流繼承于 InputStream OutputStream,字符流繼承于
InputStreamReaderOutputStreamWriter。在 http://java.io 包中還有許多其他的流,主要是為了提
高性能和使用方便。
多線(xiàn)程部分
什么是多線(xiàn)程?
在一個(gè)應(yīng)用程序中,同時(shí),有多個(gè)不同的執(zhí)行路徑。
說(shuō)一下多線(xiàn)程的好處?
提供程序效率。
線(xiàn)程和進(jìn)程有什么區(qū)別?
線(xiàn)程是進(jìn)程的一條執(zhí)行路徑,而進(jìn)程是線(xiàn)程的集合。
什么是線(xiàn)程同步、異步?
線(xiàn)程同步表示,當(dāng)前線(xiàn)程執(zhí)行完后下一個(gè)線(xiàn)程接著執(zhí)行。
線(xiàn)程異步表示, 在一個(gè)應(yīng)用程序中,同時(shí),有多個(gè)不同的執(zhí)行路徑。例如 javaweb ajax android handler
線(xiàn)程之間如何同步
線(xiàn)程之間同步使用 synchronized、wait 與 notify
什么是線(xiàn)程不安全?如何解決?(重點(diǎn))
就是在多個(gè)線(xiàn)程共享同一個(gè)數(shù)據(jù)會(huì)受到其他線(xiàn)程的干擾。如何解決:使用線(xiàn)程同步技術(shù), 用上鎖(synchronized)。 讓一個(gè)線(xiàn)程執(zhí)行完了,在讓另一個(gè)線(xiàn)程執(zhí)行。
如何創(chuàng)建一個(gè)線(xiàn)程?有幾種方法?
繼承thread類(lèi), 重寫(xiě)run方法、實(shí)現(xiàn)Runnalbe接口,重新run方法 , 啟動(dòng)一個(gè)線(xiàn)程用start();
是使用Runnalbe接口好?還是繼承Thread類(lèi)好?
是實(shí)現(xiàn)Runnalbe接口好,因?yàn)閷?shí)現(xiàn)的接口還可以繼續(xù)繼承。如果繼承了Thread類(lèi)不能在繼承。
sleep()和 wait()有什么區(qū)別?
a、sleep是讓當(dāng)前線(xiàn)程指定休眠時(shí)間,然后繼續(xù)工作 不釋放鎖
b、讓當(dāng)前線(xiàn)程wait則是等待,直到有線(xiàn)程通知notify()喚醒他才會(huì)重新工作。釋放鎖
集合相關(guān)面試題
說(shuō)一下數(shù)據(jù)結(jié)構(gòu)中的什么是數(shù)組?什么是鏈表?
所謂數(shù)組,是相同數(shù)據(jù)類(lèi)型的元素按一定順序排列的集合
數(shù)組:存儲(chǔ)區(qū)間是連續(xù)的,占用內(nèi)存嚴(yán)重,故空間復(fù)雜的很大。但數(shù)組的二分查找時(shí)間復(fù)雜度小,為O(1);數(shù)組的特點(diǎn)是:尋址容易,插入和刪除困難;
所謂鏈表,鏈表是一種物理存儲(chǔ)單元上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的。鏈表由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元素稱(chēng)為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域,另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。 相比于線(xiàn)性表順序結(jié)構(gòu),操作復(fù)雜。由于不必須按順序存儲(chǔ),鏈表在插入的時(shí)候可以達(dá)到O(1)的復(fù)雜度,比另一種線(xiàn)性表順序表快得多,但是查找一個(gè)節(jié)點(diǎn)或者訪(fǎng)問(wèn)特定編號(hào)的節(jié)點(diǎn)則需要O(n)的時(shí)間,而線(xiàn)性表和順序表相應(yīng)的時(shí)間復(fù)雜度分別是O(logn)和O(1)。
鏈表:鏈表存儲(chǔ)區(qū)間離散,占用內(nèi)存比較寬松,故空間復(fù)雜度很小,但時(shí)間復(fù)雜度很大,達(dá)O(N)。鏈表的特點(diǎn)是:尋址困難,插入和刪除容易。
說(shuō)一下什么是哈希表
那么我們能不能綜合兩者的特性,做出一種尋址容易,插入刪除也容易的數(shù)據(jù)結(jié)構(gòu)?答案是肯定的,這就是我們要提起的哈希表。哈希表((Hash table)既滿(mǎn)足了數(shù)據(jù)的查找方便,同時(shí)不占用太多的內(nèi)容空間,使用也十分方便。
哈希表有多種不同的實(shí)現(xiàn)方法,我接下來(lái)解釋的是最常用的一種方法—— 拉鏈法,我們可以理解為“鏈表的數(shù)組” ,如圖:
說(shuō)一下ArrayList底層實(shí)現(xiàn)方式?
①ArrayList通過(guò)數(shù)組實(shí)現(xiàn),一旦我們實(shí)例化ArrayList無(wú)參數(shù)構(gòu)造函數(shù)默認(rèn)為數(shù)組初始化長(zhǎng)度為10
②add方法底層實(shí)現(xiàn)如果增加的元素個(gè)數(shù)超過(guò)了10個(gè),那么ArrayList底層會(huì)新生成一個(gè)數(shù)組,長(zhǎng)度為原數(shù)組的1.5倍+1,然后將原數(shù)組的內(nèi)容復(fù)制到新數(shù)組當(dāng)中,并且后續(xù)增加的內(nèi)容都會(huì)放到新數(shù)組當(dāng)中。當(dāng)新數(shù)組無(wú)法容納增加的元素時(shí),重復(fù)該過(guò)程。是一旦數(shù)組超出長(zhǎng)度,就開(kāi)始擴(kuò)容數(shù)組。擴(kuò)容數(shù)組調(diào)用的方法 Arrays.copyOf(objArr, objArr.length + 1);
說(shuō)一下LinkedList底層實(shí)現(xiàn)方式?
LinkedList底層的數(shù)據(jù)結(jié)構(gòu)是基于雙向循環(huán)鏈表的,且頭結(jié)點(diǎn)中不存放數(shù)據(jù),如下:
既然是雙向鏈表,那么必定存在一種數(shù)據(jù)結(jié)構(gòu)——我們可以稱(chēng)之為節(jié)點(diǎn),節(jié)點(diǎn)實(shí)例保存業(yè)務(wù)數(shù)據(jù),前一個(gè)節(jié)點(diǎn)的位置信息和后一個(gè)節(jié)點(diǎn)位置信息,如下圖所示:
說(shuō)一下HashMap底層實(shí)現(xiàn)方式?
HashMap是由數(shù)組+鏈表組成
put方法底層實(shí)現(xiàn):
通過(guò)key的hash值%Entry[].length得到該存儲(chǔ)的下標(biāo)位置,如果多個(gè)key的hash值%Entry[].length 值相同話(huà)就就會(huì)存儲(chǔ)到該鏈表的后面。
ArrayList 和 Vector 的區(qū)別
這兩個(gè)類(lèi)都實(shí)現(xiàn)了 List 接口(List 接口繼承了Collection 接口),他們都是有序集合,即存儲(chǔ)在這兩個(gè)集合中的元素的位置都是有順序的,相當(dāng)于一種動(dòng)態(tài)的數(shù)組,我們以后可以按位置索引號(hào)取出某個(gè)元素,并且其中的數(shù)據(jù)是允許重復(fù)的,
ArrayList 與 Vector 的區(qū)別,這主要包括兩個(gè)方面:.
(1)同步性:
Vector 是線(xiàn)程安全的,也就是說(shuō)是它的方法之間是線(xiàn)程同步的,而 ArrayList 是線(xiàn)程序不安全的,它的方法之間是線(xiàn)程不同步的。如果只有一個(gè)線(xiàn)程會(huì)訪(fǎng)問(wèn)到集合,那最好是使用 ArrayList,因?yàn)樗豢紤]線(xiàn)程安全,效率會(huì)高些;如果有多個(gè)線(xiàn)程會(huì)訪(fǎng)問(wèn)到集合,那最好是使用 Vector,因?yàn)椴恍枰覀冏约涸偃タ紤]和編寫(xiě)線(xiàn)程安全的代碼。
(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)空間的方法。
HashMap 和 Hashtable 的區(qū)別
總結(jié):
hashmap
線(xiàn)程不安全
允許有null的鍵和值
效率高一點(diǎn)、
方法不是Synchronize的要提供外同步
有containsvalue和containsKey方法
HashMap 是Java1.2 引進(jìn)的Map interface 的一個(gè)實(shí)現(xiàn)
HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)
hashtable
線(xiàn)程安全
不允許有null的鍵和值
效率稍低、
方法是是Synchronize的
有contains方法方法
、Hashtable 繼承于Dictionary 類(lèi)
Hashtable 比HashMap 要舊
List 和Set、Map 區(qū)別?
Java中的集合包括三大類(lèi),它們是Set、List和Map,它們都處于java.util包中,Set、List和Map都是接口,它們有各自的實(shí)現(xiàn)類(lèi)。Set的實(shí)現(xiàn)類(lèi)主要有HashSet和TreeSet,List的實(shí)現(xiàn)類(lèi)主要有ArrayList,Map的實(shí)現(xiàn)類(lèi)主要有HashMap和TreeMap。
Set中的對(duì)象不按特定方式排序,并且沒(méi)有重復(fù)對(duì)象。但它的有些實(shí)現(xiàn)類(lèi)能對(duì)集合中的對(duì)象按特定方式排序,例如TreeSet類(lèi),它可以按照默認(rèn)排序,也可以通過(guò)實(shí)現(xiàn)java.util.Comparator<Type>接口來(lái)自定義排序方式。
List中的對(duì)象按照索引位置排序,可以有重復(fù)對(duì)象,允許按照對(duì)象在集合中的索引位置檢索對(duì)象,如通過(guò)list.get(i)方式來(lái)獲得List集合中的元素。
Map中的每一個(gè)元素包含一個(gè)鍵對(duì)象和值對(duì)象,它們成對(duì)出現(xiàn)。鍵對(duì)象不能重復(fù),值對(duì)象可以重復(fù)。
List、Map、Set 三個(gè)接口,存取元素時(shí),各有什么特點(diǎn)?
list:存儲(chǔ): 有序的 可重復(fù)的
訪(fǎng)問(wèn):可以for循環(huán),foreach循環(huán),iterator迭代器 迭代。
set:存儲(chǔ):無(wú)序的 不重復(fù)的
訪(fǎng)問(wèn):可以foreach循環(huán),iterator迭代器 迭代
map:存儲(chǔ):存儲(chǔ)的是一對(duì)一對(duì)的映射 ”key=value“,key值 是無(wú)序,不重復(fù)的。value值可重復(fù)
訪(fǎng)問(wèn):可以map中key值轉(zhuǎn)為為set存儲(chǔ),然后迭代這個(gè)set,用map.get(key)獲取value
也可以 轉(zhuǎn)換為entry對(duì)象 用迭代器迭代
說(shuō)出 ArrayList,Vector, LinkedList 的存儲(chǔ)性能和特性
ArrayList和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素,但是插入元素要涉及數(shù)組元素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線(xiàn)程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。
去掉一個(gè) Vector 集合中重復(fù)的元素
通過(guò)Vector.contains()方法判斷是否包含該元素,如果沒(méi)有包含就添加到新的集合當(dāng)中,適用于數(shù)據(jù)較小的情況下。
Collection 和 Collections 的區(qū)別。
Collection是集合類(lèi)的上級(jí)接口,繼承于它的接口主要有Set和List。 Collections是針對(duì)集合類(lèi)的一個(gè)幫助類(lèi),它提供了一系列靜態(tài)方法實(shí)現(xiàn)了對(duì)各種集合的排序,搜索和線(xiàn)程安全等操作。
Set 里的元素是不能重復(fù)的,那么用什么方法來(lái)區(qū)分重復(fù)與否呢?是用==還是equals()?它們有何區(qū)別?
set里的元素是不能重復(fù)的,用iterator()方法來(lái)區(qū)分重復(fù)與否。
equals 方法(是String類(lèi)從它的超類(lèi)Object中繼承的)被用來(lái)檢測(cè)兩個(gè)對(duì)象是否相等,即兩個(gè)對(duì)象的內(nèi)容是否相等。
==用于比較引用和比較基本數(shù)據(jù)類(lèi)型時(shí)具有不同的功能:
比較基本數(shù)據(jù)類(lèi)型,如果兩個(gè)值相同,則結(jié)果為true
而在比較引用時(shí),如果引用指向內(nèi)存中的同一對(duì)象,結(jié)果為true
HashMap面試題
HashMap的工作原理是近年來(lái)常見(jiàn)的Java面試題。幾乎每個(gè)Java程序員都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之間的區(qū)別,那么為何這道面試題如此特殊呢?是因?yàn)檫@道題考察的深度很深。這題經(jīng)常出現(xiàn)在高級(jí)或中高級(jí)面試中。投資銀行更喜歡問(wèn)這個(gè)問(wèn)題,甚至?xí)竽銓?shí)現(xiàn)HashMap來(lái)考察你的編程能力。ConcurrentHashMap和其它同步集合的引入讓這道題變得更加復(fù)雜。讓我們開(kāi)始探索的旅程吧!
先來(lái)些簡(jiǎn)單的問(wèn)題
“你用過(guò)HashMap嗎?” “什么是HashMap?你為什么用到它?”
幾乎每個(gè)人都會(huì)回答“是的”,然后回答HashMap的一些特性,譬如HashMap可以接受null鍵值和值,而Hashtable則不能;HashMap是非synchronized;HashMap很快;以及HashMap儲(chǔ)存的是鍵值對(duì)等等。這顯示出你已經(jīng)用過(guò)HashMap,而且對(duì)它相當(dāng)?shù)氖煜ぁ5敲嬖嚬賮?lái)個(gè)急轉(zhuǎn)直下,從此刻開(kāi)始問(wèn)出一些刁鉆的問(wèn)題,關(guān)于HashMap的更多基礎(chǔ)的細(xì)節(jié)。面試官可能會(huì)問(wèn)出下面的問(wèn)題:
“你知道HashMap的工作原理嗎?” “你知道HashMap的get()方法的工作原理嗎?”
你也許會(huì)回答“我沒(méi)有詳查標(biāo)準(zhǔn)的Java API,你可以看看Java源代碼或者Open JDK。”“我可以用Google找到答案。”
但一些面試者可能可以給出答案,“HashMap是基于hashing的原理,我們使用put(key, value)存儲(chǔ)對(duì)象到HashMap中,使用get(key)從HashMap中獲取對(duì)象。當(dāng)我們給put()方法傳遞鍵和值時(shí),我們先對(duì)鍵調(diào)用hashCode()方法,返回的hashCode用于找到bucket位置來(lái)儲(chǔ)存Entry對(duì)象。”這里關(guān)鍵點(diǎn)在于指出,HashMap是在bucket中儲(chǔ)存鍵對(duì)象和值對(duì)象,作為Map.Entry。這一點(diǎn)有助于理解獲取對(duì)象的邏輯。如果你沒(méi)有意識(shí)到這一點(diǎn),或者錯(cuò)誤的認(rèn)為僅僅只在bucket中存儲(chǔ)值的話(huà),你將不會(huì)回答如何從HashMap中獲取對(duì)象的邏輯。這個(gè)答案相當(dāng)?shù)恼_,也顯示出面試者確實(shí)知道hashing以及HashMap的工作原理。但是這僅僅是故事的開(kāi)始,當(dāng)面試官加入一些Java程序員每天要碰到的實(shí)際場(chǎng)景的時(shí)候,錯(cuò)誤的答案頻現(xiàn)。下個(gè)問(wèn)題可能是關(guān)于HashMap中的碰撞探測(cè)(collision detection)以及碰撞的解決方法:
“當(dāng)兩個(gè)對(duì)象的hashcode相同會(huì)發(fā)生什么?” 從這里開(kāi)始,真正的困惑開(kāi)始了,一些面試者會(huì)回答因?yàn)閔ashcode相同,所以?xún)蓚€(gè)對(duì)象是相等的,HashMap將會(huì)拋出異常,或者不會(huì)存儲(chǔ)它們。然后面試官可能會(huì)提醒他們有equals()和hashCode()兩個(gè)方法,并告訴他們兩個(gè)對(duì)象就算hashcode相同,但是它們可能并不相等。一些面試者可能就此放棄,而另外一些還能繼續(xù)挺進(jìn),他們回答“因?yàn)閔ashcode相同,所以它們的bucket位置相同,‘碰撞’會(huì)發(fā)生。因?yàn)镠ashMap使用鏈表存儲(chǔ)對(duì)象,這個(gè)Entry(包含有鍵值對(duì)的Map.Entry對(duì)象)會(huì)存儲(chǔ)在鏈表中。”這個(gè)答案非常的合理,雖然有很多種處理碰撞的方法,這種方法是最簡(jiǎn)單的,也正是HashMap的處理方法。但故事還沒(méi)有完結(jié),面試官會(huì)繼續(xù)問(wèn):
“如果兩個(gè)鍵的hashcode相同,你如何獲取值對(duì)象?” 面試者會(huì)回答:當(dāng)我們調(diào)用get()方法,HashMap會(huì)使用鍵對(duì)象的hashcode找到bucket位置,然后獲取值對(duì)象。面試官提醒他如果有兩個(gè)值對(duì)象儲(chǔ)存在同一個(gè)bucket,他給出答案:將會(huì)遍歷鏈表直到找到值對(duì)象。面試官會(huì)問(wèn)因?yàn)槟悴](méi)有值對(duì)象去比較,你是如何確定確定找到值對(duì)象的?除非面試者直到HashMap在鏈表中存儲(chǔ)的是鍵值對(duì),否則他們不可能回答出這一題。
其中一些記得這個(gè)重要知識(shí)點(diǎn)的面試者會(huì)說(shuō),找到bucket位置之后,會(huì)調(diào)用keys.equals()方法去找到鏈表中正確的節(jié)點(diǎn),最終找到要找的值對(duì)象。完美的答案!
許多情況下,面試者會(huì)在這個(gè)環(huán)節(jié)中出錯(cuò),因?yàn)樗麄兓煜薶ashCode()和equals()方法。因?yàn)樵诖酥癶ashCode()屢屢出現(xiàn),而equals()方法僅僅在獲取值對(duì)象的時(shí)候才出現(xiàn)。一些優(yōu)秀的開(kāi)發(fā)者會(huì)指出使用不可變的、聲明作final的對(duì)象,并且采用合適的equals()和hashCode()方法的話(huà),將會(huì)減少碰撞的發(fā)生,提高效率。不可變性使得能夠緩存不同鍵的hashcode,這將提高整個(gè)獲取對(duì)象的速度,使用String,Interger這樣的wrapper類(lèi)作為鍵是非常好的選擇。
如果你認(rèn)為到這里已經(jīng)完結(jié)了,那么聽(tīng)到下面這個(gè)問(wèn)題的時(shí)候,你會(huì)大吃一驚。“如果HashMap的大小超過(guò)了負(fù)載因子(load factor)定義的容量,怎么辦?”除非你真正知道HashMap的工作原理,否則你將回答不出這道題。默認(rèn)的負(fù)載因子大小為0.75,也就是說(shuō),當(dāng)一個(gè)map填滿(mǎn)了75%的bucket時(shí)候,和其它集合類(lèi)(如ArrayList等)一樣,將會(huì)創(chuàng)建原來(lái)HashMap大小的兩倍的bucket數(shù)組,來(lái)重新調(diào)整map的大小,并將原來(lái)的對(duì)象放入新的bucket數(shù)組中。這個(gè)過(guò)程叫作rehashing,因?yàn)樗{(diào)用hash方法找到新的bucket位置。
如果你能夠回答這道問(wèn)題,下面的問(wèn)題來(lái)了:“你了解重新調(diào)整HashMap大小存在什么問(wèn)題嗎?”你可能回答不上來(lái),這時(shí)面試官會(huì)提醒你當(dāng)多線(xiàn)程的情況下,可能產(chǎn)生條件競(jìng)爭(zhēng)(race condition)。
當(dāng)重新調(diào)整HashMap大小的時(shí)候,確實(shí)存在條件競(jìng)爭(zhēng),因?yàn)槿绻麅蓚€(gè)線(xiàn)程都發(fā)現(xiàn)HashMap需要重新調(diào)整大小了,它們會(huì)同時(shí)試著調(diào)整大小。在調(diào)整大小的過(guò)程中,存儲(chǔ)在鏈表中的元素的次序會(huì)反過(guò)來(lái),因?yàn)橐苿?dòng)到新的bucket位置的時(shí)候,HashMap并不會(huì)將元素放在鏈表的尾部,而是放在頭部,這是為了避免尾部遍歷(tail traversing)。如果條件競(jìng)爭(zhēng)發(fā)生了,那么就死循環(huán)了。這個(gè)時(shí)候,你可以質(zhì)問(wèn)面試官,為什么這么奇怪,要在多線(xiàn)程的環(huán)境下使用HashMap呢?:)
熱心的讀者貢獻(xiàn)了更多的關(guān)于HashMap的問(wèn)題:
為什么String, Interger這樣的wrapper類(lèi)適合作為鍵? String, Interger這樣的wrapper類(lèi)作為HashMap的鍵是再適合不過(guò)了,而且String最為常用。因?yàn)镾tring是不可變的,也是final的,而且已經(jīng)重寫(xiě)了equals()和hashCode()方法了。其他的wrapper類(lèi)也有這個(gè)特點(diǎn)。不可變性是必要的,因?yàn)闉榱艘?jì)算hashCode(),就要防止鍵值改變,如果鍵值在放入時(shí)和獲取時(shí)返回不同的hashcode的話(huà),那么就不能從HashMap中找到你想要的對(duì)象。不可變性還有其他的優(yōu)點(diǎn)如線(xiàn)程安全。如果你可以?xún)H僅通過(guò)將某個(gè)field聲明成final就能保證hashCode是不變的,那么請(qǐng)這么做吧。因?yàn)楂@取對(duì)象的時(shí)候要用到equals()和hashCode()方法,那么鍵對(duì)象正確的重寫(xiě)這兩個(gè)方法是非常重要的。如果兩個(gè)不相等的對(duì)象返回不同的hashcode的話(huà),那么碰撞的幾率就會(huì)小些,這樣就能提高HashMap的性能。
我們可以使用自定義的對(duì)象作為鍵嗎? 這是前一個(gè)問(wèn)題的延伸。當(dāng)然你可能使用任何對(duì)象作為鍵,只要它遵守了equals()和hashCode()方法的定義規(guī)則,并且當(dāng)對(duì)象插入到Map中之后將不會(huì)再改變了。如果這個(gè)自定義對(duì)象時(shí)不可變的,那么它已經(jīng)滿(mǎn)足了作為鍵的條件,因?yàn)楫?dāng)它創(chuàng)建之后就已經(jīng)不能改變了。
我們可以使用CocurrentHashMap來(lái)代替Hashtable嗎?這是另外一個(gè)很熱門(mén)的面試題,因?yàn)镃oncurrentHashMap越來(lái)越多人用了。我們知道Hashtable是synchronized的,但是ConcurrentHashMap同步性能更好,因?yàn)樗鼉H僅根據(jù)同步級(jí)別對(duì)map的一部分進(jìn)行上鎖。ConcurrentHashMap當(dāng)然可以代替HashTable,但是HashTable提供更強(qiáng)的線(xiàn)程安全性。看看這篇博客查看Hashtable和ConcurrentHashMap的區(qū)別。
我個(gè)人很喜歡這個(gè)問(wèn)題,因?yàn)檫@個(gè)問(wèn)題的深度和廣度,也不直接的涉及到不同的概念。讓我們?cè)賮?lái)看看這些問(wèn)題設(shè)計(jì)哪些知識(shí)點(diǎn):
hashing的概念
HashMap中解決碰撞的方法
equals()和hashCode()的應(yīng)用,以及它們?cè)贖ashMap中的重要性
不可變對(duì)象的好處
HashMap多線(xiàn)程的條件競(jìng)爭(zhēng)
重新調(diào)整HashMap的大小
總結(jié)
HashMap的工作原理
HashMap基于hashing原理,我們通過(guò)put()和get()方法儲(chǔ)存和獲取對(duì)象。當(dāng)我們將鍵值對(duì)傳遞給put()方法時(shí),它調(diào)用鍵對(duì)象的hashCode()方法來(lái)計(jì)算hashcode,讓后找到bucket位置來(lái)儲(chǔ)存值對(duì)象。當(dāng)獲取對(duì)象時(shí),通過(guò)鍵對(duì)象的equals()方法找到正確的鍵值對(duì),然后返回值對(duì)象。HashMap使用鏈表來(lái)解決碰撞問(wèn)題,當(dāng)發(fā)生碰撞了,對(duì)象將會(huì)儲(chǔ)存在鏈表的下一個(gè)節(jié)點(diǎn)中。 HashMap在每個(gè)鏈表節(jié)點(diǎn)中儲(chǔ)存鍵值對(duì)對(duì)象。
當(dāng)兩個(gè)不同的鍵對(duì)象的hashcode相同時(shí)會(huì)發(fā)生什么? 它們會(huì)儲(chǔ)存在同一個(gè)bucket位置的鏈表中。鍵對(duì)象的equals()方法用來(lái)找到鍵值對(duì)。
因?yàn)镠ashMap的好處非常多,我曾經(jīng)在電子商務(wù)的應(yīng)用中使用HashMap作為緩存。因?yàn)榻鹑陬I(lǐng)域非常多的運(yùn)用Java,也出于性能的考慮,我們會(huì)經(jīng)常用到HashMap和ConcurrentHashMap。你可以查看更多的關(guān)于HashMap的文章:
請(qǐng)講下Java里面的容器
分兩大類(lèi),Map和Collection。而Collection又有子接口List(數(shù)據(jù)存儲(chǔ)順序和插入順序是一樣的)、Set(里面的元素具有唯一性)
Map是存儲(chǔ)鍵值對(duì)的,里面的健不可以重復(fù),但值可以重復(fù)
a. 對(duì)于List主要有ArrayList和LinkedList兩種實(shí)現(xiàn)。實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)不同,所以主要的區(qū)別也都是和數(shù)據(jù)結(jié)構(gòu)相關(guān)的。 ArrayList基于數(shù)組,隨機(jī)訪(fǎng)問(wèn)快,而對(duì)于中間元素的插入刪除效率比較低,而且需要考慮擴(kuò)容問(wèn)題。LinkedList,則 基于鏈表,和ArrayList提到的正相反,隨機(jī)訪(fǎng)問(wèn)慢,但對(duì)于中間元素的插入和刪除更有效率。
Set也是一種Collection,和List比起來(lái)主要體現(xiàn)在元素唯一性。
請(qǐng)說(shuō)下Iterator的作用
迭代器可以實(shí)現(xiàn)Collection接口的方法,可以一個(gè)一個(gè)地獲取集合中的元素
在遍歷集合時(shí) 可判斷是否有下一個(gè)元素
說(shuō)下ArrayList和LinkedList的區(qū)別和聯(lián)系,并說(shuō)明什么情況下用它們
區(qū)別:ArrayList用于對(duì)象的隨機(jī)訪(fǎng)問(wèn)速度快,沒(méi)有順序
LinkedList實(shí)現(xiàn)機(jī)制是鏈表式的,和順序有關(guān),速度比ArrayList慢
聯(lián)系:ArrayList和LinkedList都是List接口的實(shí)現(xiàn)類(lèi)
當(dāng)要快速獲取一個(gè)值時(shí),用ArrayList,用于順序插入操作時(shí),用LinkedList.
說(shuō)下List,Set,Map三種集合各有什么特征
List集合中的元素可以重復(fù),
Set集合中的元素不可以重復(fù)
Map集合用鍵-值映射存放對(duì)象,Map容器中的鍵對(duì)象不能重復(fù),值對(duì)象可以重復(fù)
HashSet和TreeSet有什么區(qū)別,什么時(shí)候用它們
區(qū)別:HashSet中的元素不能重復(fù),沒(méi)有順序
TreeSet中的元素不能重復(fù),但有順序
當(dāng)集合中的元素需要排序時(shí),用TreeSet
一般情況下用HashSet,因?yàn)椴恍枰判?速度比TreeSet快
什么是泛型,怎么使用的,有什么好處?
答案
定義一個(gè)集合時(shí),可以知道里面定義的是什么類(lèi)型
使用:在集合類(lèi)型后面加< 數(shù)據(jù)類(lèi)型 >
使用泛型后,從集合中取得元素后就不用再用強(qiáng)轉(zhuǎn)
什么是for each循環(huán),它可以循環(huán)那些數(shù)據(jù)類(lèi)型
答案
也可以叫增強(qiáng)型循環(huán),通過(guò)對(duì)象拿到集合里的值,因?yàn)閿U(kuò)展性比較強(qiáng),建議多使用
可以用來(lái)循環(huán)集合和數(shù)組
比較下集合和數(shù)組的優(yōu)缺點(diǎn)
集合是多個(gè)對(duì)象的容器,可以將不同數(shù)據(jù)類(lèi)型的多個(gè)對(duì)象組織在一起
數(shù)組類(lèi)型是有相同數(shù)據(jù)類(lèi)型的數(shù)據(jù)集合,數(shù)組是很多語(yǔ)言都支持的底層數(shù)據(jù)結(jié)構(gòu),性能上是最高的
HashMap與LinkedHashMap,和TreeMap的區(qū)別。
共同點(diǎn):HashMap,LinkedHashMap,TreeMap都屬于Map的實(shí)現(xiàn)類(lèi).
不同點(diǎn): 1.HashMap里面存入的鍵值對(duì)在取出的時(shí)候是隨機(jī)的,
2.TreeMap取出來(lái)的是排序后的鍵值對(duì)。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會(huì)更好。
3. LinkedHashMap 是HashMap的一個(gè)子類(lèi),如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實(shí)現(xiàn).
在List里面怎么去掉重復(fù)的數(shù)?
通過(guò)把List里面的數(shù)據(jù)放入HashSet可以去除重復(fù)
HashMap和ArrayList是不是都是線(xiàn)程不安全的?
ArrayList是線(xiàn)程不安全的;HashMap是線(xiàn)程不安全的;還有我們常見(jiàn)的一些JAVA集合都是線(xiàn)程不安全,這樣做是為了提高性能
在JDK5以后提供了線(xiàn)程安全的并發(fā)包java.util.concurrent并發(fā)包,譬如里面的類(lèi)CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap等
ArrayList集合加入1萬(wàn)條數(shù)據(jù),應(yīng)該怎么提高效率
因?yàn)锳rrayList的底層是數(shù)組實(shí)現(xiàn),并且數(shù)組的默認(rèn)值是10,如果插入10000條要不斷的擴(kuò)容,耗費(fèi)時(shí)間,所以我們調(diào)用ArrayList的指定容量的構(gòu)造器方法ArrayList(int size) 就可以實(shí)現(xiàn)不擴(kuò)容,就提高了性能
網(wǎng)路通訊部分
Xml與JSON區(qū)別
數(shù)據(jù)交換格式
區(qū)別:
xml是重量級(jí)、json是輕量級(jí)
xml比較占帶寬、json占帶寬小,易于壓縮
json在webservice 用的比較少、xml用的較多
相同:
兩者都用在項(xiàng)目交互下 例如 移動(dòng)app接口用的就是json、在web項(xiàng)目中與其他項(xiàng)目對(duì)接用xml較多。
json常用解析方法 gson、jsonobject、jackson等 xml dom sax pull 解析
TCP與UDP區(qū)別?
udp: a、是面向無(wú)連接, 將數(shù)據(jù)及源的封裝成數(shù)據(jù)包中,不需要建立建立連接
b、每個(gè)數(shù)據(jù)報(bào)的大小在限制64k內(nèi)
c、因無(wú)連接,是不可靠協(xié)議
d、不需要建立連接,速度快
tcp: a、建議連接,形成傳輸數(shù)據(jù)的通道.
b、在連接中進(jìn)行大數(shù)據(jù)量傳輸,以字節(jié)流方式
c 通過(guò)三次握手完成連接,是可靠協(xié)議
d 必須建立連接m效率會(huì)稍低
聊天、網(wǎng)絡(luò)視頻會(huì)議、桌面共享用的就是 udp
說(shuō)說(shuō)三次握手?
1)第一次握手:建立連接時(shí),客戶(hù)端A發(fā)送SYN包(SYN=j)到服務(wù)器B,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器B確認(rèn)。
(2)第二次握手:服務(wù)器B收到SYN包,必須確認(rèn)客戶(hù)A的SYN(ACK=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(SYN=k),即SYN+ACK包,此時(shí)服務(wù)器B進(jìn)入SYN_RECV狀態(tài)。
(3)第三次握手:客戶(hù)端A收到服務(wù)器B的SYN+ACK包,向服務(wù)器B發(fā)送確認(rèn)包ACK(ACK=k+1),此包發(fā)送完畢,客戶(hù)端A和服務(wù)器B進(jìn)入ESTABLISHED狀態(tài),完成三次握手。
完成三次握手,客戶(hù)端與服務(wù)器開(kāi)始傳送數(shù)據(jù)。
什么是Webserivce?
Webservice就是提供不同的平臺(tái)相互通訊,基于Soap協(xié)議。
Web service 就是一個(gè)應(yīng)用程序,它向外界暴露出一個(gè)能夠通過(guò)Web進(jìn)行調(diào)用的API。
SOAP是一種簡(jiǎn)單基于xml的輕量協(xié)議,用戶(hù)web上交換結(jié)構(gòu)化信息和類(lèi)型信息。
soap請(qǐng)求是HTTP POST的一個(gè)專(zhuān)用版本,遵循一種特殊的xml消息格式Content-type設(shè)置為: text/xml任何數(shù)據(jù)都可以xml化。
WebService實(shí)現(xiàn)原理是?
HTTP協(xié)議+XML
說(shuō)一下什么是Http協(xié)議?
對(duì)器客戶(hù)端和 服務(wù)器端之間數(shù)據(jù)傳輸?shù)母袷揭?guī)范,格式簡(jiǎn)稱(chēng)為“超文本傳輸協(xié)議”。
什么是Http協(xié)議無(wú)狀態(tài)協(xié)議?怎么解決Http協(xié)議無(wú)狀態(tài)協(xié)議?(曾經(jīng)去某創(chuàng)業(yè)公司問(wèn)到)
1、無(wú)狀態(tài)協(xié)議對(duì)于事務(wù)處理沒(méi)有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息
2、無(wú)狀態(tài)協(xié)議解決辦法: 通過(guò)1、Cookie 2、通過(guò)Session會(huì)話(huà)保存。
說(shuō)一下Http協(xié)議中302狀態(tài)(阿里經(jīng)常問(wèn))
http協(xié)議中,返回狀態(tài)碼302表示重定向。
這種情況下,服務(wù)器返回的頭部信息中會(huì)包含一個(gè) Location 字段,內(nèi)容是重定向到的url
Http協(xié)議有什么組成?
請(qǐng)求報(bào)文包含三部分:
a、請(qǐng)求行:包含請(qǐng)求方法、URI、HTTP版本信息
b、請(qǐng)求首部字段
c、請(qǐng)求內(nèi)容實(shí)體
響應(yīng)報(bào)文包含三部分:
a、狀態(tài)行:包含HTTP版本、狀態(tài)碼、狀態(tài)碼的原因短語(yǔ)
b、響應(yīng)首部字段
c、響應(yīng)內(nèi)容實(shí)體
Http協(xié)議中有那些請(qǐng)求方式?
GET: 用于請(qǐng)求訪(fǎng)問(wèn)已經(jīng)被URI(統(tǒng)一資源標(biāo)識(shí)符)識(shí)別的資源,可以通過(guò)URL傳參給服務(wù)器
POST:用于傳輸信息給服務(wù)器,主要功能與GET方法類(lèi)似,但一般推薦使用POST方式。
PUT: 傳輸文件,報(bào)文主體中包含文件內(nèi)容,保存到對(duì)應(yīng)URI位置。
HEAD: 獲得報(bào)文首部,與GET方法類(lèi)似,只是不返回報(bào)文主體,一般用于驗(yàn)證URI是否有效。
DELETE:刪除文件,與PUT方法相反,刪除對(duì)應(yīng)URI位置的文件。
OPTIONS:查詢(xún)相應(yīng)URI支持的HTTP方法。
Http協(xié)議中Http1.0與1.1區(qū)別?
在http1.0中,當(dāng)建立連接后,客戶(hù)端發(fā)送一個(gè)請(qǐng)求,服務(wù)器端返回一個(gè)信息后就關(guān)閉連接,當(dāng)瀏覽器下次請(qǐng)求的時(shí)候又要建立連接,顯然這種不斷建立連接的方式,會(huì)造成很多問(wèn)題。
5.在http1.1中,引入了持續(xù)連接的概念,通過(guò)這種連接,瀏覽器可以建立一個(gè)連接之后,發(fā)送請(qǐng)求并得到返回信息,然后繼續(xù)發(fā)送請(qǐng)求再次等到返回信息,也就是說(shuō)客戶(hù)端可以連續(xù)發(fā)送多個(gè)請(qǐng)求,而不用等待每一個(gè)響應(yīng)的到來(lái)。
Http協(xié)議實(shí)現(xiàn)原理機(jī)制?
2.1、整個(gè)流程步驟
2.2、域名解析過(guò)程
2.3、三次握手過(guò)程
2.4、發(fā)起HTTP請(qǐng)求
2.5、響應(yīng)HTTP請(qǐng)求并得到HTML代碼
2.6、瀏覽器解析HTML代碼
2.7、瀏覽器對(duì)頁(yè)面進(jìn)行渲染呈現(xiàn)給用戶(hù)
get與post請(qǐng)求區(qū)別?(初級(jí)程序員必備問(wèn)題)
區(qū)別一:
get重點(diǎn)在從服務(wù)器上獲取資源,post重點(diǎn)在向服務(wù)器發(fā)送數(shù)據(jù);
區(qū)別二:
get傳輸數(shù)據(jù)是通過(guò)URL請(qǐng)求,以field(字段)= value的形式,置于URL后,并用"?"連接,多個(gè)請(qǐng)求數(shù)據(jù)間用"&"連接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,這個(gè)過(guò)程用戶(hù)是可見(jiàn)的;
post傳輸數(shù)據(jù)通過(guò)Http的post機(jī)制,將字段與對(duì)應(yīng)值封存在請(qǐng)求實(shí)體中發(fā)送給服務(wù)器,這個(gè)過(guò)程對(duì)用戶(hù)是不可見(jiàn)的;
區(qū)別三:
Get傳輸?shù)臄?shù)據(jù)量小,因?yàn)槭躑RL長(zhǎng)度限制,但效率較高;
Post可以傳輸大量數(shù)據(jù),所以上傳文件時(shí)只能用Post方式;
區(qū)別四:
get是不安全的,因?yàn)閁RL是可見(jiàn)的,可能會(huì)泄露私密信息,如密碼等;
post較get安全性較高;
區(qū)別五:
get方式只能支持ASCII字符,向服務(wù)器傳的中文字符可能會(huì)亂碼。
post支持標(biāo)準(zhǔn)字符集,可以正確傳遞中文字符。
9、Http請(qǐng)求報(bào)文與響應(yīng)報(bào)文格式?
請(qǐng)求報(bào)文包含三部分:
a、請(qǐng)求行:包含請(qǐng)求方法、URI、HTTP版本信息
b、請(qǐng)求首部字段
c、請(qǐng)求內(nèi)容實(shí)體
響應(yīng)報(bào)文包含三部分:
a、狀態(tài)行:包含HTTP版本、狀態(tài)碼、狀態(tài)碼的原因短語(yǔ)
b、響應(yīng)首部字段
c、響應(yīng)內(nèi)容實(shí)體
10、常見(jiàn)Http協(xié)議狀態(tài)?
200:請(qǐng)求被正常處理
204:請(qǐng)求被受理但沒(méi)有資源可以返回
206:客戶(hù)端只是請(qǐng)求資源的一部分,服務(wù)器只對(duì)請(qǐng)求的部分資源執(zhí)行GET方法,相應(yīng)報(bào)文中通過(guò)Content-Range指定范圍的資源。
301:永久性重定向
302:臨時(shí)重定向
303:與302狀態(tài)碼有相似功能,只是它希望客戶(hù)端在請(qǐng)求一個(gè)URI的時(shí)候,能通過(guò)GET方法重定向到另一個(gè)URI上
304:發(fā)送附帶條件的請(qǐng)求時(shí),條件不滿(mǎn)足時(shí)返回,與重定向無(wú)關(guān)
307:臨時(shí)重定向,與302類(lèi)似,只是強(qiáng)制要求使用POST方法
400:請(qǐng)求報(bào)文語(yǔ)法有誤,服務(wù)器無(wú)法識(shí)別
401:請(qǐng)求需要認(rèn)證
403:請(qǐng)求的對(duì)應(yīng)資源禁止被訪(fǎng)問(wèn)
404:服務(wù)器無(wú)法找到對(duì)應(yīng)資源
500:服務(wù)器內(nèi)部錯(cuò)誤
503:服務(wù)器正忙
Http協(xié)議首部字段?
a、通用首部字段(請(qǐng)求報(bào)文與響應(yīng)報(bào)文都會(huì)使用的首部字段)
Date:創(chuàng)建報(bào)文時(shí)間
Connection:連接的管理
Cache-Control:緩存的控制
Transfer-Encoding:報(bào)文主體的傳輸編碼方式
b、請(qǐng)求首部字段(請(qǐng)求報(bào)文會(huì)使用的首部字段)
Host:請(qǐng)求資源所在服務(wù)器
Accept:可處理的媒體類(lèi)型
Accept-Charset:可接收的字符集
Accept-Encoding:可接受的內(nèi)容編碼
Accept-Language:可接受的自然語(yǔ)言
c、響應(yīng)首部字段(響應(yīng)報(bào)文會(huì)使用的首部字段)
Accept-Ranges:可接受的字節(jié)范圍
Location:令客戶(hù)端重新定向到的URI
Server:HTTP服務(wù)器的安裝信息
d、實(shí)體首部字段(請(qǐng)求報(bào)文與響應(yīng)報(bào)文的的實(shí)體部分使用的首部字段)
Allow:資源可支持的HTTP方法
Content-Type:實(shí)體主類(lèi)的類(lèi)型
Content-Encoding:實(shí)體主體適用的編碼方式
Content-Language:實(shí)體主體的自然語(yǔ)言
Content-Length:實(shí)體主體的的字節(jié)數(shù)
Content-Range:實(shí)體主體的位置范圍,一般用于發(fā)出部分請(qǐng)求時(shí)使用
Http與Https優(yōu)缺點(diǎn)?
a、通信使用明文不加密,內(nèi)容可能被竊聽(tīng),也就是被抓包分析。
b、不驗(yàn)證通信方身份,可能遭到偽裝
c、無(wú)法驗(yàn)證報(bào)文完整性,可能被篡改
HTTPS就是HTTP加上加密處理(一般是SSL安全通信線(xiàn)路)+認(rèn)證+完整性保護(hù)
Http優(yōu)化
利用負(fù)載均衡優(yōu)化和加速HTTP應(yīng)用
利用HTTP Cache來(lái)優(yōu)化網(wǎng)站
Http協(xié)議有那些特征?
1、支持客戶(hù)/服務(wù)器模式;2、簡(jiǎn)單快速;3、靈活;4、無(wú)連接;5、無(wú)狀態(tài);
如果你還對(duì)Http協(xié)議不熟悉的話(huà),請(qǐng)參考Http協(xié)議http://www.itmayiedu.com/front/articleinfo/49.html文章
JavaWeb基礎(chǔ)部分
講下Servlet的執(zhí)行流程。doGet和doPost的區(qū)別
Servlet的執(zhí)行流程也就是servlet的生命周期,當(dāng)服務(wù)器啟動(dòng)的時(shí)候生命周期開(kāi)始,然后通過(guò)init()《啟動(dòng)順序根據(jù)web.xml里的startup-on-load來(lái)確定加載順序》方法初始化servlet,再根據(jù)不同請(qǐng)求調(diào)用doGet或doPost方法,最后再通過(guò)destroy()方法進(jìn)行銷(xiāo)毀。
doGet和doPost都是接受用戶(hù)請(qǐng)求的方法,doGet處理get請(qǐng)求,doPost處理post請(qǐng)求,doGet用于地址欄提交,doPost用于表單提交,在頁(yè)面提交數(shù)據(jù)時(shí),get的數(shù)據(jù)大小有限制4k,post沒(méi)有限制,get請(qǐng)求提交的數(shù)據(jù)會(huì)在地址欄顯示,post不顯示,所以post比get安全.
當(dāng)service有一個(gè)實(shí)例變量,doGet和doPost去調(diào)用這個(gè)變量,會(huì)出現(xiàn)什么問(wèn)題,你是如何解決的。
會(huì)出現(xiàn)線(xiàn)程不安全問(wèn)題。無(wú)論是doGet還是doPost去調(diào)用,服務(wù)器端處理的過(guò)程都是一樣的,那么我們可以把處理過(guò)程單獨(dú)寫(xiě)在另外一個(gè)方法handle里,讓兩個(gè)方法都去調(diào)用handle,根據(jù)不同請(qǐng)求去調(diào)用不同的方法。
如何處理servlet的線(xiàn)程不安全問(wèn)題
線(xiàn)程安全就是多線(xiàn)程操作同一個(gè)對(duì)象不會(huì)有問(wèn)題,線(xiàn)程同步一般來(lái)保護(hù)線(xiàn)程安全,所以可以在Servlet的線(xiàn)程里面加上同步方法或同步塊。(Synchronized)可以保證在同一時(shí)間只有一個(gè)線(xiàn)程訪(fǎng)問(wèn),(使用同步塊會(huì)導(dǎo)致性能變差,最好不去使用實(shí)例變量)
Jsp的重定向和轉(zhuǎn)發(fā)的流程有什么區(qū)別
重定向是客戶(hù)端行為,轉(zhuǎn)發(fā)是服務(wù)器端行為
重定向時(shí)服務(wù)器產(chǎn)生兩次請(qǐng)求,轉(zhuǎn)發(fā)產(chǎn)生一次請(qǐng)求,重定向時(shí)可以轉(zhuǎn)發(fā)到項(xiàng)目以外的任何網(wǎng)址,轉(zhuǎn)發(fā)只能在當(dāng)前項(xiàng)目里轉(zhuǎn)發(fā)
重定向會(huì)導(dǎo)致request對(duì)象信息丟失。轉(zhuǎn)發(fā)則不會(huì)
轉(zhuǎn)發(fā)的url不會(huì)變,request.getRequestDispatch()。forward()
重定向的url會(huì)改變,response.getRedirect();
Jsp和servlet的區(qū)別
jsp的可讀性強(qiáng),容易維護(hù),并且jsp在最后會(huì)編譯成servlet
servlet容易調(diào)試
Jsp的九大內(nèi)置對(duì)象,三大指令,七大動(dòng)作的具體功能
JSP九大內(nèi)置對(duì)象:
pageContext :只對(duì)當(dāng)前jsp頁(yè)面有效,里面封裝了基本的request和session的對(duì)象Request :對(duì)當(dāng)前請(qǐng)求進(jìn)行封裝Session :瀏覽器會(huì)話(huà)對(duì)象,瀏覽器范圍內(nèi)有效Application :應(yīng)用程序?qū)ο?#xff0c;對(duì)整個(gè)web工程都有效Out :頁(yè)面打印對(duì)象,在jsp頁(yè)面打印字符串Response :返回服務(wù)器端信息給用戶(hù)Config :單個(gè)servlet的配置對(duì)象,相當(dāng)于servletConfig對(duì)象Page :當(dāng)前頁(yè)面對(duì)象,也就是thisException :錯(cuò)誤頁(yè)面的exception對(duì)象,如果指定的是錯(cuò)誤頁(yè)面,這個(gè)就是異常對(duì)象
三大指令:
Page :指令是針對(duì)當(dāng)前頁(yè)面的指令I(lǐng)nclude :用于指定如何包含另一個(gè)頁(yè)面Taglib :用于定義和指定自定義標(biāo)簽
七大動(dòng)作:
Forward,執(zhí)行頁(yè)面跳轉(zhuǎn),將請(qǐng)求的處理轉(zhuǎn)發(fā)到另一個(gè)頁(yè)面Param :用于傳遞參數(shù)Include :用于動(dòng)態(tài)引入一個(gè)jsp頁(yè)面Plugin :用于下載javaBean或applet到客戶(hù)端執(zhí)行useBean :使用javaBeansetProperty :修改javaBean實(shí)例的屬性值getProperty :獲取javaBean實(shí)例的屬性值
獲取頁(yè)面的元素和值有幾種方式,分別說(shuō)一下
request.getParameter() 返回客戶(hù)端的請(qǐng)求參數(shù)與值request.getParameterNames() 返回所有可用屬性名的枚舉request.getParameterValues() 返回包含參數(shù)的所有值的數(shù)組
servlet和javaScript的區(qū)別,他們分別是什么作用
一個(gè)是服務(wù)端,一個(gè)是客戶(hù)端
Servlet是獨(dú)立于平臺(tái)和協(xié)議的服務(wù)器端的java應(yīng)用程序,可以動(dòng)態(tài)生成web頁(yè)面,并采用響應(yīng)--請(qǐng)求的模式提供web服務(wù)
javaScript是一種解釋性語(yǔ)言,用于向html頁(yè)面提供交互行為,通常被直接嵌入在html頁(yè)面中
servlet是java語(yǔ)言編寫(xiě)的web應(yīng)用
js是基于html上的一種解釋語(yǔ)言
會(huì)話(huà)跟蹤有哪些,他們的區(qū)別是什么
Cookie,session和application,Cookie是http對(duì)象,客戶(hù)端與服務(wù)端都可以操縱
cookie是在客戶(hù)端保持狀態(tài),session是在服務(wù)器端保持狀態(tài),由于cookie是保存在客戶(hù)端本地的,所以數(shù)據(jù)很容易被竊取,當(dāng)訪(fǎng)問(wèn)量很多時(shí),使用session則會(huì)降低服務(wù)器的性能,application的作用域是整個(gè)工程里只有一個(gè),可以在不同瀏覽器之間共享數(shù)據(jù),所有人都可以共享,因此application也是不安全的
說(shuō)說(shuō)jsp的隱藏對(duì)象有哪些
Request,out,response , pageContext , session , application , config , page , exception,也即jsp的九大內(nèi)置對(duì)象
request ,response,session 和 application是怎么用的
Request是客戶(hù)端向服務(wù)端發(fā)送請(qǐng)求
Response是服務(wù)端對(duì)客戶(hù)端請(qǐng)求做出響應(yīng)
Session在servlet中不能直接使用,需要通過(guò)getSession()創(chuàng)建,如果沒(méi)有設(shè)定它的生命周期,或者通過(guò)invildate()方法銷(xiāo)毀,關(guān)閉瀏覽器session就會(huì)消失
Application不能直接創(chuàng)建,存在于服務(wù)器的內(nèi)存中,由服務(wù)器創(chuàng)建和銷(xiāo)毀
jsp頁(yè)面跳轉(zhuǎn)
Jsp頁(yè)面跳轉(zhuǎn)有兩種方式,forward和redirect(轉(zhuǎn)發(fā)和重定向)
Forward只能在當(dāng)前項(xiàng)目里跳轉(zhuǎn),只產(chǎn)生一次請(qǐng)求,request保存的變量不會(huì)丟失,url地址不會(huì)改變
Redirect可跳轉(zhuǎn)到項(xiàng)目以外的任何頁(yè)面,產(chǎn)生兩次請(qǐng)求,request保存的變量會(huì)全部丟失,url地址會(huì)發(fā)生改變,變化為第二個(gè)請(qǐng)求的地址
話(huà)跟蹤
如果創(chuàng)建servlet實(shí)例不用構(gòu)造方法,怎么創(chuàng)建一個(gè)servlet實(shí)例
Web容器會(huì)自動(dòng)為servlet寫(xiě)一個(gè)無(wú)參的構(gòu)造器,它使用class.forName("").newInstance()反射來(lái)創(chuàng)建servlet實(shí)例的
Servlet是安全的嗎?當(dāng)service有一個(gè)實(shí)例變量,doGet和doPost去調(diào)用這個(gè)變量,會(huì)出現(xiàn)什么問(wèn)題,你是如何解決的
是線(xiàn)程不安全的,因?yàn)閟ervlet是單例模式,當(dāng)多個(gè)客戶(hù)端共同訪(fǎng)問(wèn)的時(shí)候線(xiàn)程不安全。
盡量用局部變量,同步塊,如果當(dāng)前字段是不會(huì)改變的,用final修飾
Java框架部分
說(shuō)說(shuō)Spring?
Spring的核心是控制反轉(zhuǎn)、依賴(lài)注入,Aop(面向切面)相當(dāng)于把每個(gè)bean與bean之間的關(guān)系交給第 三方容器進(jìn)行管理.
說(shuō)SpringIOC、SpringAOP?
SpringIOC ,其實(shí)就是依賴(lài)注入、控制反轉(zhuǎn)。相當(dāng)于把每個(gè)bean與bean之間的關(guān)系交給第三方容器管理。而這個(gè)容器就是spring
SpringAOP 面向切面的編程,或AOP,是一種編程技術(shù),允許程序模塊化橫向切割關(guān)注點(diǎn),或橫切典型的責(zé)任劃分,如日志和事務(wù)管理。 SpringAop 就是用 Javva的動(dòng)態(tài)代理
Spring的底層實(shí)現(xiàn)機(jī)制是什么?
使用Demo4j(解析XML)+Java反射機(jī)制
Demo4j 其實(shí)就是解析XML。使用反射機(jī)制實(shí)例化bean。
SpringAOP用到了什么代理?
JDK動(dòng)態(tài)代理:對(duì)實(shí)現(xiàn)了接口的類(lèi)生成代理
CGLib代理機(jī)制:對(duì)類(lèi)生成代理
動(dòng)態(tài)代理與靜態(tài)代理區(qū)別?
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類(lèi)的.class文件就已經(jīng)存在了。 動(dòng)態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。
Spring注入有那些方式?
Set注入
構(gòu)造器注入
靜態(tài)工廠(chǎng)的方法注入
實(shí)例工廠(chǎng)的方法注入
Spring有那些注解?
@Autowired(按類(lèi)型注入)
@Service(標(biāo)示為注入為服務(wù)層)
@Resource(按名稱(chēng)注入)
@Controller(標(biāo)識(shí)控制器bean id)
@RequestMapping(表示映射URL路徑)
簡(jiǎn)述Spring的優(yōu)缺點(diǎn)?
Spring 的優(yōu)點(diǎn)??
1.降低了組件之間的耦合性 ,實(shí)現(xiàn)了軟件各層之間的解耦
2.可以使用容易提供的眾多服務(wù),如事務(wù)管理,消息服務(wù)等
3.容器提供單例模式支持
4.容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限攔截,運(yùn)行期監(jiān)控等功能
5.容器提供了眾多的輔助類(lèi),能加快應(yīng)用的開(kāi)發(fā)
6.spring對(duì)于主流的應(yīng)用框架提供了集成支持,如hibernate,JPA,Struts等
7.spring屬于低侵入式設(shè)計(jì),代碼的污染極低
8.獨(dú)立于各種應(yīng)用服務(wù)器
9.spring的DI機(jī)制降低了業(yè)務(wù)對(duì)象替換的復(fù)雜性
10.Spring的高度開(kāi)放性,并不強(qiáng)制應(yīng)用完全依賴(lài)于Spring,開(kāi)發(fā)者可以自由選擇spring的部分或全部
缺點(diǎn):
使用到了大量反射機(jī)制。反射機(jī)制非常占內(nèi)存,
SpringMVC工程流程
1. 用戶(hù)向服務(wù)器發(fā)送請(qǐng)求,請(qǐng)求被Spring 前端控制Servelt DispatcherServlet捕獲;
2. DispatcherServlet對(duì)請(qǐng)求URL進(jìn)行解析,得到請(qǐng)求資源標(biāo)識(shí)符(URI)。然后根據(jù)該URI,調(diào)用HandlerMapping獲得該Handler配置的所有相關(guān)的對(duì)象(包括Handler對(duì)象以及Handler對(duì)象對(duì)應(yīng)的攔截器),最后以HandlerExecutionChain對(duì)象的形式返回;
3. DispatcherServlet 根據(jù)獲得的Handler,選擇一個(gè)合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時(shí)將開(kāi)始執(zhí)行攔截器的preHandler(...)方法)
4. 提取Request中的模型數(shù)據(jù),填充Handler入?yún)?#xff0c;開(kāi)始執(zhí)行Handler(Controller)。 在填充Handler的入?yún)⑦^(guò)程中,根據(jù)你的配置,Spring將幫你做一些額外的工作:
HttpMessageConveter: 將請(qǐng)求消息(如Json、xml等數(shù)據(jù))轉(zhuǎn)換成一個(gè)對(duì)象,將對(duì)象轉(zhuǎn)換為指定的響應(yīng)信息
數(shù)據(jù)轉(zhuǎn)換:對(duì)請(qǐng)求消息進(jìn)行數(shù)據(jù)轉(zhuǎn)換。如String轉(zhuǎn)換成Integer、Double等
數(shù)據(jù)根式化:對(duì)請(qǐng)求消息進(jìn)行數(shù)據(jù)格式化。 如將字符串轉(zhuǎn)換成格式化數(shù)字或格式化日期等
數(shù)據(jù)驗(yàn)證: 驗(yàn)證數(shù)據(jù)的有效性(長(zhǎng)度、格式等),驗(yàn)證結(jié)果存儲(chǔ)到BindingResult或Error中
5. Handler執(zhí)行完成后,向DispatcherServlet 返回一個(gè)ModelAndView對(duì)象;
6. 根據(jù)返回的ModelAndView,選擇一個(gè)適合的ViewResolver(必須是已經(jīng)注冊(cè)到Spring容器中的ViewResolver)返回給DispatcherServlet ;
7. ViewResolver 結(jié)合Model和View,來(lái)渲染視圖
8. 將渲染結(jié)果返回給客戶(hù)端。
SpringMVC工作流程描述
為什么SpringMVC只使用一個(gè)Servlet(DispatcherServlet)來(lái)處理所有請(qǐng)求?
詳細(xì)見(jiàn)J2EE設(shè)計(jì)模式-前端控制模式
Spring為什么要結(jié)合使用HandlerMapping以及HandlerAdapter來(lái)處理Handler?
符合面向?qū)ο笾械膯我宦氊?zé)原則,代碼架構(gòu)清晰,便于維護(hù),最重要的是代碼可復(fù)用性高。如HandlerAdapter可能會(huì)被用于處理多種Handler。
Hibernate面試題
什么是Hibernate?
hibernate是一個(gè)基于ORM持久框架,可以讓程序員以面向?qū)ο蟮乃枷氩僮鲾?shù)據(jù)庫(kù),提高生產(chǎn)效率.
什么是ORM?
orm不過(guò)是一種思想,對(duì)象關(guān)系映射。是對(duì)象關(guān)系模型,如hibernate,讓你以面向?qū)ο蟮姆绞饺ゾ幊獭7庋b了JDBC.
說(shuō)一下orm與jdbc的區(qū)別?
jdbc只是一個(gè)java操作數(shù)據(jù)庫(kù)的規(guī)范接口而已
orm不過(guò)是一種思想,對(duì)象關(guān)系映射。
ORM:是對(duì)象關(guān)系模型,如hibernate,讓你以面向?qū)ο蟮姆绞饺ゾ幊獭7庋b了JDBC.
JDBC:是從底層訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)服務(wù)器。一般銀行,金融行業(yè)為了安全起見(jiàn),直接用JDBC訪(fǎng)問(wèn)
Hibernate中g(shù)et和load有什么不同之處?
load :找不到數(shù)據(jù)的話(huà)會(huì)拋出org.hibernate.ObjectNotFoundException異常。此時(shí)hibernate會(huì)使用延遲加載加載機(jī)制
get找不到的話(huà)會(huì)返回null。
如果查詢(xún)不到數(shù)據(jù),get 會(huì)返回 null,但是不會(huì)報(bào)錯(cuò), load 如果查詢(xún)不到數(shù)據(jù),則報(bào)錯(cuò)ObjectNotFoundException
使用get 去查詢(xún)數(shù)據(jù),(先到一級(jí)/二級(jí))會(huì)立即向db發(fā)出查詢(xún)請(qǐng)求(select ...), 如果你使用的是 load查詢(xún)數(shù)據(jù),(先到一級(jí)、二級(jí)))即使查詢(xún)到對(duì)象,返回的是一個(gè)代理對(duì)象,如果后面沒(méi)有使用查詢(xún)結(jié)果,它不會(huì)真的向數(shù)據(jù)庫(kù)發(fā)select ,當(dāng)程序員使用查詢(xún)結(jié)果的時(shí)候才真的發(fā)出select ,這個(gè)現(xiàn)象我們稱(chēng)為懶加載(lazy)
hibernate的三種狀態(tài)?
在Hibernate中,對(duì)象有三種狀態(tài):臨 時(shí)狀態(tài)(Transient)、持久狀態(tài)(Persistent)和游離狀態(tài)(Detached)。
處于持久態(tài)的對(duì)象也稱(chēng)為 PO(PersistenceObject),臨時(shí)對(duì)象和游離對(duì)象也稱(chēng)為VO(ValueObject).
hibernate的懶加載? 有幾種禁用方法
在Hibernate框架中,當(dāng)我們要訪(fǎng)問(wèn)的數(shù)據(jù)量過(guò)大時(shí),明顯用緩存不太合適, 因?yàn)閮?nèi)存容量有限 ,為了減少并發(fā)量,減少系統(tǒng)資源的消耗,這時(shí)Hibernate用懶加載機(jī)制來(lái)彌補(bǔ)這種缺陷,但是這只是彌補(bǔ)而不是用了懶加載總體性能就提高了。
我們所說(shuō)的懶加載也被稱(chēng)為延遲加載,它在查詢(xún)的時(shí)候不會(huì)立刻訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),而是返回代理對(duì)象,當(dāng)真正去使用對(duì)象的時(shí)候才會(huì)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)。
1.使用代理對(duì)象:Hibernate.initialize("代理對(duì)象");
2.在需要禁用懶加載的映射文件中顯示的加入lazy = "false"
3.使用openSessionInView【需要借助于過(guò)濾器】 需要在web.xml文件中配置
hibernate有幾種查詢(xún)方式?
1、 屬性查詢(xún)2、 參數(shù)查詢(xún)、命名參數(shù)查詢(xún)3、 關(guān)聯(lián)查詢(xún)4、 分頁(yè)查詢(xún)5、 統(tǒng)計(jì)函數(shù)
Hibernate的優(yōu)缺點(diǎn)?
1.Hibernate的優(yōu)缺點(diǎn):優(yōu)點(diǎn):1、程序更加面向?qū)ο?#xff1b;2、提高了生產(chǎn)率;3、方便移植(修改配置文件);4、無(wú)侵入性。缺點(diǎn):1、效率比JDBC略差;2、不適合批量操作。
Hibernate的緩存機(jī)制
Hibernate緩存包括兩大類(lèi):Hibernate一級(jí)緩存和Hibernate二級(jí)緩存。
1.Hibernate一級(jí)緩存又稱(chēng)為“Session的緩存”。
Session內(nèi)置不能被卸載,Session的緩存是事務(wù)范圍的緩存(Session對(duì)象的生命周期通常對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù)事務(wù)或者一個(gè)應(yīng)用事務(wù))。
一級(jí)緩存中,持久化類(lèi)的每個(gè)實(shí)例都具有唯一的OID。
2.Hibernate二級(jí)緩存又稱(chēng)為“SessionFactory的緩存”。
由于SessionFactory對(duì)象的生命周期和應(yīng)用程序的整個(gè)過(guò)程對(duì)應(yīng),因此Hibernate二級(jí)緩存是進(jìn)程范圍或者集群范圍的緩存,有可能出現(xiàn)并發(fā)問(wèn)題,因此需要采用適當(dāng)?shù)牟l(fā)訪(fǎng)問(wèn)策略,該策略為被緩存的數(shù)據(jù)提供了事務(wù)隔離級(jí)別。
第二級(jí)緩存是可選的,是一個(gè)可配置的插件,默認(rèn)下SessionFactory不會(huì)啟用這個(gè)插件。
Hibernate提供了org.hibernate.cache.CacheProvider接口,它充當(dāng)緩存插件與Hibernate之間的適配器。
Hibernate延遲加載?
1) Hibernate2延遲加載實(shí)現(xiàn):a)實(shí)體對(duì)象 b)集合(Collection)
2) Hibernate3 提供了屬性的延遲加載功能 當(dāng)Hibernate在查詢(xún)數(shù)據(jù)的時(shí)候,數(shù)據(jù)并沒(méi)有存在與內(nèi)存中,當(dāng)程序真正對(duì)數(shù)據(jù)的操作時(shí),對(duì)象才存在與內(nèi)存中,就實(shí)現(xiàn)了延遲加載,他節(jié)省了服務(wù)器的內(nèi)存開(kāi)銷(xiāo),從而提高了服務(wù)器的性能。
Hibernate工作原理及為什么要用?
原理:
1) 讀取并解析配置文件
2) 讀取并解析映射信息
3) 創(chuàng)建SessionFactory
4) 打開(kāi)Sesssion
5) 創(chuàng)建事務(wù)Transation
6) 持久化操作
7) 提交事務(wù)
8) 關(guān)閉Session
9) 關(guān)閉SesstionFactory
為什么要用:
1) 對(duì)JDBC訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的代碼做了封裝,大大簡(jiǎn)化了數(shù)據(jù)訪(fǎng)問(wèn)層繁瑣的重復(fù)性代碼。
2) Hibernate是一個(gè)基于JDBC的主流持久化框架,是一個(gè)優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡(jiǎn)化DAO層的編碼工作
3) hibernate使用Java反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來(lái)實(shí)現(xiàn)透明性。
4) hibernate的性能非常好,因?yàn)樗莻€(gè)輕量級(jí)框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫(kù),從一對(duì)一到多對(duì)多的各種復(fù)雜關(guān)系。
什么是Mybatis?
Mybatis的前生是ibatis,最后升級(jí)版本后名稱(chēng)叫mybatis。mybatis是以純sql操作數(shù)據(jù)。
Mybatis與Hibernate區(qū)別?
Hibernate是面向?qū)ο蟮乃枷氩僮鲾?shù)據(jù)生成Sql語(yǔ)句,而mybatis是以純sql操作數(shù)據(jù)
相對(duì)于mybatis容易優(yōu)化.擴(kuò)展性好,但是移植性差。
設(shè)計(jì)模式部分
你熟悉那些設(shè)計(jì)模式?
總共有23種設(shè)計(jì)模式
總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類(lèi):
創(chuàng)建型模式,共五種:工廠(chǎng)方法模式、抽象工廠(chǎng)模式、單例模式、建造者模式、原型模式。
結(jié)構(gòu)型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀(guān)模式、橋接模式、組合模式、享元模式。
行為型模式,共十一種:策略模式、模板方法模式、觀(guān)察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪(fǎng)問(wèn)者模式、中介者模式、解釋器模式。
企業(yè)面試的時(shí)候,面試官非常喜歡考單例,而且非常喜歡考手寫(xiě)單例。
什么是單例?單例有那些寫(xiě)法?
單例分類(lèi):懶漢式單例、餓漢式單例單例模式有以下特點(diǎn):1、單例類(lèi)只能有一個(gè)實(shí)例。2、單例類(lèi)必須自己創(chuàng)建自己的唯一實(shí)例。3、單例類(lèi)必須給所有其他對(duì)象提供這一實(shí)例。
①懶漢式單例
②餓漢式單例
懶漢式與餓漢式區(qū)別?
從名字上來(lái)說(shuō),餓漢和懶漢,
餓漢就是類(lèi)一旦加載,就把單例初始化完成,保證getInstance的時(shí)候,單例是已經(jīng)存在的了,
而懶漢比較懶,只有當(dāng)調(diào)用getInstance的時(shí)候,才回去初始化這個(gè)單例。
另外從以下兩點(diǎn)再區(qū)分以下這兩種方式:
1、線(xiàn)程安全:
餓漢式天生就是線(xiàn)程安全的,可以直接用于多線(xiàn)程而不會(huì)出現(xiàn)問(wèn)題,
懶漢式本身是非線(xiàn)程安全的,為了實(shí)現(xiàn)線(xiàn)程安全有幾種寫(xiě)法,分別是上面的1、2、3,這三種實(shí)現(xiàn)在資源加載和性能方面有些區(qū)別。
2、資源加載和性能:
餓漢式在類(lèi)創(chuàng)建的同時(shí)就實(shí)例化一個(gè)靜態(tài)對(duì)象出來(lái),不管之后會(huì)不會(huì)使用這個(gè)單例,都會(huì)占據(jù)一定的內(nèi)存,但是相應(yīng)的,在第一次調(diào)用時(shí)速度也會(huì)更快,因?yàn)槠滟Y源已經(jīng)初始化完成,
而懶漢式顧名思義,會(huì)延遲加載,在第一次使用該單例的時(shí)候才會(huì)實(shí)例化對(duì)象出來(lái),第一次調(diào)用時(shí)要做初始化,如果要做的工作比較多,性能上會(huì)有些延遲,之后就和餓漢式一樣了。
項(xiàng)目相關(guān)面試題
你說(shuō)說(shuō)你做的最好的項(xiàng)目?
要重點(diǎn)介紹到①項(xiàng)目是做什么?②用到那些技術(shù)?③整個(gè)項(xiàng)目中最大的亮點(diǎn)是?核心部分④遇到bug是怎么解決的?
你項(xiàng)目遇到bug?怎么查問(wèn)題?
例如:首先遇到了bug,會(huì)查詢(xún)?nèi)罩?#xff0c;通過(guò)日志定位到某個(gè)類(lèi)的行數(shù),判斷是否有代碼問(wèn)題。
你遇到了什么bug?你是怎么解決?
例如我自己項(xiàng)目中,查詢(xún)量非常大。通過(guò)日志發(fā)現(xiàn)了堆內(nèi)存溢出,最后通過(guò)優(yōu)化代碼,減輕new和加大堆內(nèi)存。
你們項(xiàng)目人員是怎么分配的?
項(xiàng)目分配為:
產(chǎn)品經(jīng)理(負(fù)責(zé)提需求)
UI設(shè)計(jì)師(負(fù)責(zé)設(shè)計(jì)樣式文件)
Web前端(只做Web頁(yè)面前端靜態(tài)文件)
Java工程師(寫(xiě)業(yè)務(wù)邏輯)
測(cè)試人員(負(fù)責(zé)測(cè)試bug)
非技術(shù)項(xiàng)目經(jīng)理(負(fù)責(zé)項(xiàng)目管理、人員分配)
項(xiàng)目架構(gòu)師(負(fù)責(zé)架構(gòu)項(xiàng)目)
你們項(xiàng)目是怎么發(fā)布的?
企業(yè)當(dāng)中項(xiàng)目都是發(fā)布在linux環(huán)境上
小公司:使用maven編譯好通過(guò)打war包,放入到tomcat的webapps文件下
大公司:使用自動(dòng)部署系統(tǒng)jenkins jenkins直接關(guān)聯(lián)svn地址自動(dòng)打包、自動(dòng)部署等
說(shuō)說(shuō)linux常用命令?
Cat 查看某個(gè)文件
CP 拷貝
Ls 查看所有列表
Pwd 查看路徑
Tail 查看日志
Grep 搜索日志
總結(jié)
以上是生活随笔為你收集整理的java判断时间区间 隔天_Java初中级程序员面试题宝典的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 常吃重口味会越长越丑:高盐饮食会使人面部
- 下一篇: java map 值排序_使用Java8