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