java初中級程序員面試寶典-螞蟻課堂


Java基礎部分

&&&區別?

&和&&都是邏輯運算符,都是判斷兩邊同時真則為真,否則為假;但是&&當第一個條件不成之后,后面的條件都不執行了,而&則還是繼續執行,直到整個條件語句執行完為止。

使用 final 關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變?

使用 final 關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容 還是可以改變的。

靜態變量和實例變量的區別?

在語法定義上的區別:

靜態變量前要加 static 關鍵字,而實例變量前則不加。

在程序運行時的區別:實例變量屬於某個對象的屬性,必須創建了實例對象,其中的實例變 量才會被分配空間,才能使用這個實例變量。

靜態變量不屬於某個實例對象,而是屬於類, 所以也稱為類變量,只要程序加載了類的字節碼,不用創建任何實例對象,靜態變量就會被分配空間,靜態變量就可以被使用了。

總之,實例變量必須創建對象后才可以通過這個對象 來使用,靜態變量則可以直接使用類名來引用。

靜態變量使用時,通過類名.名稱,實例變量必須要初始化后才能使用。實例變量是實例化后才會分配空間,而靜態變量當類加載時會分配空間。

是否可以從一個 static 方法內部發出對非 static 方法的調用?

不可以。因為非 static 方法是要與對象關聯在一起的,必須創建一個對象后,才可以在該對 象上進行方法調用,而 static 方法調用時不需要創建對象,可以直接調用。也就是說,當一 個 static 方法被調用時,可能還沒有創建任何實例對象,如果從一個 static 方法中發出對非 static 方法的調用,那個非 static 方法是關聯到哪個對象上的呢?這個邏輯無法成立,所以, 一個 static 方法內部發出對非 static 方法的調用。

static方法可以訪問static方法.

static方法不能訪問非static方法

"==" equals 方法究竟有什么區別?

  ==如果判斷值類型的話,判斷內容是否相同。如果判斷引用類型則是判斷內存地址是否相同

Equals判斷值內容是否相等

Integer 與 int 的區別

Integer 是引用類型,默認值是null。而int是是值類型默認值是0

請說出作用域 public, private, protected,以及不寫時的區別

這四個作用域的可見范圍如下表所示。

說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示 friendly。

作用域 當前類 同一包( package) 子孫類 其他包( package

public     √              √                                      √                 √

protected √            √                                      √                 ×

friendly     √             √                                      ×                ×

private      √              ×                                   ×                  ×

重載與重寫區別?

重載是同一個類中,方法名稱相同, 但是參數或個數不同。與返回值沒有關系。

重寫是在多個類中, 產生繼承關系。父類與子類的方法方法必須相同。

接口與抽象類的區別?

區別:定義接口的關鍵字是:interface 而定義抽象類的關鍵字是:abstract。

接口中成員不能有私有, 抽象類可以。

接口中定義的成員, 是finl public static 類型, 抽象類沒有。

接口中的不能有普通方法, 抽象類中可以。

相同: 

兩個都不new

但是 接口與抽象類是面向對象必備知識,設計模式、重構代碼有必然作用

final, finally, finalize 的區別。

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

內部類要訪問局部變量,局部變量必須定義成 final 類型,例如,一段代碼……

finally 是異常處理語句結構的一部分,表示總是執行。

finalize 是 Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可

以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。 JVM 不保證此方法總被

調用

String、StringBuffer與StringBuilder的區別

String 字符串常量

StringBuffer 字符串變量(線程安全)

StringBuilder 字符串變量(非線程安全)

所有的類都繼承於object類,你用過的object類的直接子類有哪些,object類常用的方法

有哪些

1.clone方法

保護方法,實現對象的淺復制,只有實現了Cloneable接口才可以調用該方法,否則拋出CloneNotSupportedException異常。

2.getClass方法

final方法,獲得運行時類型。

3.toString方法

該方法用得比較多,一般子類都有覆蓋。

4.finalize方法

該方法用於釋放資源。因為無法確定該方法什么時候被調用,很少使用。

5.equals方法

該方法是非常重要的一個方法。一般equals和==是不一樣的,但是在Object中兩者是一樣的。子類一般都要重寫這個方法。

6.數組有沒有length()這個方法? String有沒有length()這個方法?

答:數組沒有length()這個方法,有length的屬性。String有有length()這個方法。

 

7.hashCode方法

該方法用於哈希查找,重寫了equals方法一般都要重寫hashCode方法。這個方法在一些具有哈希功能的Collection中用到。

一般必須滿足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就滿足equals。不過為了提高效率,應該盡量使上面兩個條件接近等價。

7.wait方法

wait方法就是使當前線程等待該對象的鎖,當前線程必須是該對象的擁有者,也就是具有該對象的鎖。wait()方法一直等待,直到獲得鎖或者被中斷。wait(long timeout)設定一個超時間隔,如果在規定時間內沒有獲得鎖就返回。

調用該方法后當前線程進入睡眠狀態,直到以下事件發生。

(1)其他線程調用了該對象的notify方法。

(2)其他線程調用了該對象的notifyAll方法。

(3)其他線程調用了interrupt中斷該線程。

(4)時間間隔到了。

此時該線程就可以被調度了,如果是被中斷的話就拋出一個InterruptedException異常。

8.notify方法

該方法喚醒在該對象上等待的某個線程。

9.notifyAll方法

該方法喚醒在該對象上等待的所有線程

反射的優缺點?

反射:就是正在運行動態讀取這個類的完整信息。

優點:java的反射機制就是增加程序的靈活性、

缺點:缺點:(1)性能問題:使用反射基本上是一種解釋操作,

用於字段和方法接入時要遠慢於直接代碼。因此反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。

(2)使用反射會模糊程序內內部邏輯:程序員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,因而會帶來維護問題。反射代碼比相應的直接代碼更復雜。

那些地方用到了反射?

例如: jdbcJava常用框架、jdk的動態代理、android的加載布局文件

java  中有幾種類型的流?JDK 為每種類型的流提供了一些抽象類以供繼承, 為每種類型的流提供了一些抽象類以供繼承,

請說出他們分別是哪些類? 

   字節流,字符流。字節流繼承於 InputStream OutputStream,字符流繼承於

InputStreamReaderOutputStreamWriter。在 java.io 包中還有許多其他的流,主要是為了提

高性能和使用方便。

多線程部分

什么是多線程?

在一個應用程序中,同時,有多個不同的執行路徑。

說一下多線程的好處?

提供程序效率。

線程和進程有什么區別?

線程是進程的一條執行路徑,而進程是線程的集合。

什么是線程同步、異步?

線程同步表示,當前線程執行完后下一個線程接着執行。

線程異步表示,  在一個應用程序中,同時,有多個不同的執行路徑。例如 javaweb ajax android handler

線程之間如何同步

線程之間同步使用 synchronized、wait 與 notify

什么是線程不安全?如何解決?(重點)

就是在多個線程共享同一個數據會受到其他線程的干擾。如何解決:使用線程同步技術, 用上鎖(synchronized)。 讓一個線程執行完了,在讓另一個線程執行。

如何創建一個線程?有幾種方法?

繼承thread類, 重寫run方法、實現Runnalbe接口,重新run方法 , 啟動一個線程用start();

是使用Runnalbe接口好?還是繼承Thread類好?

 是實現Runnalbe接口好,因為實現的接口還可以繼續繼承。如果繼承了Thread類不能在繼承。

sleep()和 wait()有什么區別?

a、sleep是讓當前線程指定休眠時間,然后繼續工作  不釋放鎖

  b、讓當前線程wait則是等待,直到有線程通知notify()喚醒他才會重新工作。釋放鎖

 

集合相關面試題

 

 

說一下數據結構中的什么是數組?什么是鏈表?

所謂數組,是相同數據類型的元素按一定順序排列的集合

數組:存儲區間是連續的,占用內存嚴重,故空間復雜的很大。但數組的二分查找時間復雜度小,為O(1);數組的特點是:尋址容易,插入和刪除困難;

所謂鏈表,鏈表是一種物理存儲單元上非連續、非順序的存儲結構數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操作復雜。由於不必須按順序存儲,鏈表在插入的時候可以達到O(1)的復雜度,比另一種線性表順序表快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而線性表和順序表相應的時間復雜度分別是O(logn)和O(1)。

鏈表:鏈表存儲區間離散,占用內存比較寬松,故空間復雜度很小,但時間復雜度很大,達O(N)。鏈表的特點是:尋址困難,插入和刪除容易。

說一下什么是哈希表

那么我們能不能綜合兩者的特性,做出一種尋址容易,插入刪除也容易的數據結構?答案是肯定的,這就是我們要提起的哈希表。哈希表((Hash table)既滿足了數據的查找方便,同時不占用太多的內容空間,使用也十分方便。

  哈希表有多種不同的實現方法,我接下來解釋的是最常用的一種方法—— 拉鏈法,我們可以理解為“鏈表的數組” ,如圖:

 

 

 

說一下ArrayList底層實現方式?

①ArrayList通過數組實現,一旦我們實例化ArrayList無參數構造函數默認為數組初始化長度為10

②add方法底層實現如果增加的元素個數超過了10個,那么ArrayList底層會新生成一個數組,長度為原數組的1.5倍+1,然后將原數組的內容復制到新數組當中,並且后續增加的內容都會放到新數組當中。當新數組無法容納增加的元素時,重復該過程。是一旦數組超出長度,就開始擴容數組。擴容數組調用的方法 Arrays.copyOf(objArr, objArr.length + 1);

說一下LinkedList底層實現方式?

LinkedList底層的數據結構是基於雙向循環鏈表的,且頭結點中不存放數據,如下:

 

 

既然是雙向鏈表,那么必定存在一種數據結構——我們可以稱之為節點,節點實例保存業務數據,前一個節點的位置信息和后一個節點位置信息,如下圖所示:

 

 

說一下HashMap底層實現方式?

HashMap是由數組+鏈表組成

put方法底層實現:

通過key的hash值%Entry[].length得到該存儲的下標位置,如果多個key的hash值%Entry[].length 值相同話就就會存儲到該鏈表的后面。

ArrayList 和 Vector 的區別

這兩個類都實現了 List 接口(List 接口繼承了Collection 接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,相當於一種動態的數組,我們以后可以按位置索引號取出某個元素,並且其中的數據是允許重復的,

ArrayList 與 Vector 的區別,這主要包括兩個方面:.

(1)同步性:

Vector 是線程安全的,也就是說是它的方法之間是線程同步的,而 ArrayList 是線程序不安全的,它的方法之間是線程不同步的。如果只有一個線程會訪問到集合,那最好是使用 ArrayList,因為它不考慮線程安全,效率會高些;如果有多個線程會訪問到集合,那最好是使用 Vector,因為不需要我們自己再去考慮和編寫線程安全的代碼。

(2)數據增長:

ArrayList 與 Vector 都有一個初始的容量大小,當存儲進它們里面的元素的個數超過了容量時,就需要增加 ArrayList 與 Vector 的存儲空間,每次要增加存儲空間時,不是只增加一個存儲單元,而是增加多個存儲單元,每次增加的存儲單元的個數在內存空間利用與程序效率之間要取得一定的平衡。Vector 默認增長為原來兩倍,而 ArrayList 的增長策略在文檔中沒有明確規定(從源代碼看到的是增長為原來的1.5倍)。

ArrayList 與 Vector 都可以設置初始的空間大小,Vector 還可以設置增長的空間大小,而 ArrayList 沒有提供設置增長空間的方法。

HashMap 和 Hashtable 的區別

 

總結:

hashmap

線程不安全

允許有null的鍵和值

效率高一點、

方法不是Synchronize的要提供外同步

有containsvalue和containsKey方法

HashMap 是Java1.2 引進的Map interface 的一個實現

HashMap是Hashtable的輕量級實現

hashtable

線程安全

不允許有null的鍵和值

效率稍低、

方法是是Synchronize的

有contains方法方法

、Hashtable 繼承於Dictionary 類

Hashtable 比HashMap 要舊

 

List 和Set、Map 區別?

Java中的集合包括三大類,它們是Set、List和Map,它們都處於java.util包中,Set、List和Map都是接口,它們有各自的實現類。Set的實現類主要有HashSet和TreeSet,List的實現類主要有ArrayList,Map的實現類主要有HashMap和TreeMap。

  Set中的對象不按特定方式排序,並且沒有重復對象。但它的有些實現類能對集合中的對象按特定方式排序,例如TreeSet類,它可以按照默認排序,也可以通過實現java.util.Comparator<Type>接口來自定義排序方式。

  List中的對象按照索引位置排序,可以有重復對象,允許按照對象在集合中的索引位置檢索對象,如通過list.get(i)方式來獲得List集合中的元素。

  Map中的每一個元素包含一個鍵對象和值對象,它們成對出現。鍵對象不能重復,值對象可以重復。

List、Map、Set 三個接口,存取元素時,各有什么特點?

list:存儲: 有序的 可重復的

訪問:可以for循環,foreach循環,iterator迭代器 迭代。

set:存儲:無序的 不重復的

訪問:可以foreach循環,iterator迭代器 迭代

map:存儲:存儲的是一對一對的映射 ”key=value“,key值 是無序,不重復的。value值可重復

訪問:可以map中key值轉為為set存儲,然后迭代這個set,用map.get(key)獲取value

也可以 轉換為entry對象 用迭代器迭代

說出 ArrayList,Vector, LinkedList 的存儲性能和特性 

ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以索引數據快而插入數據慢,Vector由於使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或后向遍歷,但是插入數據時只需要記錄本項的前后項即可,所以插入速度較快。

去掉一個 Vector 集合中重復的元素

通過Vector.contains()方法判斷是否包含該元素,如果沒有包含就添加到新的集合當中,適用於數據較小的情況下。

Collection 和 Collections 的區別。

Collection是集合類的上級接口,繼承於它的接口主要有Set和List。 Collections是針對集合類的一個幫助類,它提供了一系列靜態方法實現了對各種集合的排序,搜索和線程安全等操作。

Set 里的元素是不能重復的,那么用什么方法來區分重復與否呢?是用==還是equals()?它們有何區別?

set里的元素是不能重復的,用iterator()方法來區分重復與否。

equals 方法(是String類從它的超類Object中繼承的)被用來檢測兩個對象是否相等,即兩個對象的內容是否相等。

==用於比較引用和比較基本數據類型時具有不同的功能:

比較基本數據類型,如果兩個值相同,則結果為true

而在比較引用時,如果引用指向內存中的同一對象,結果為true

HashMap面試題

HashMap的工作原理是近年來常見的Java面試題。幾乎每個Java程序員都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之間的區別,那么為何這道面試題如此特殊呢?是因為這道題考察的深度很深。這題經常出現在高級或中高級面試中。投資銀行更喜歡問這個問題,甚至會要求你實現HashMap來考察你的編程能力。ConcurrentHashMap和其它同步集合的引入讓這道題變得更加復雜。讓我們開始探索的旅程吧!

先來些簡單的問題

你用過HashMap嗎?” “什么是HashMap?你為什么用到它?”

幾乎每個人都會回答“是的”,然后回答HashMap的一些特性,譬如HashMap可以接受null鍵值和值,而Hashtable則不能;HashMap是非synchronized;HashMap很快;以及HashMap儲存的是鍵值對等等。這顯示出你已經用過HashMap,而且對它相當的熟悉。但是面試官來個急轉直下,從此刻開始問出一些刁鑽的問題,關於HashMap的更多基礎的細節。面試官可能會問出下面的問題:

你知道HashMap的工作原理嗎?” “你知道HashMap的get()方法的工作原理嗎?”

你也許會回答“我沒有詳查標准的Java API,你可以看看Java源代碼或者Open JDK。”“我可以用Google找到答案。”

但一些面試者可能可以給出答案,“HashMap是基於hashing的原理,我們使用put(key, value)存儲對象到HashMap中,使用get(key)從HashMap中獲取對象。當我們給put()方法傳遞鍵和值時,我們先對鍵調用hashCode()方法,返回的hashCode用於找到bucket位置來儲存Entry對象。”這里關鍵點在於指出,HashMap是在bucket中儲存鍵對象和值對象,作為Map.Entry。這一點有助於理解獲取對象的邏輯。如果你沒有意識到這一點,或者錯誤的認為僅僅只在bucket中存儲值的話,你將不會回答如何從HashMap中獲取對象的邏輯。這個答案相當的正確,也顯示出面試者確實知道hashing以及HashMap的工作原理。但是這僅僅是故事的開始,當面試官加入一些Java程序員每天要碰到的實際場景的時候,錯誤的答案頻現。下個問題可能是關於HashMap中的碰撞探測(collision detection)以及碰撞的解決方法:

當兩個對象的hashcode相同會發生什么?” 從這里開始,真正的困惑開始了,一些面試者會回答因為hashcode相同,所以兩個對象是相等的,HashMap將會拋出異常,或者不會存儲它們。然后面試官可能會提醒他們有equals()和hashCode()兩個方法,並告訴他們兩個對象就算hashcode相同,但是它們可能並不相等。一些面試者可能就此放棄,而另外一些還能繼續挺進,他們回答“因為hashcode相同,所以它們的bucket位置相同,‘碰撞’會發生。因為HashMap使用鏈表存儲對象,這個Entry(包含有鍵值對的Map.Entry對象)會存儲在鏈表中。”這個答案非常的合理,雖然有很多種處理碰撞的方法,這種方法是最簡單的,也正是HashMap的處理方法。但故事還沒有完結,面試官會繼續問:

如果兩個鍵的hashcode相同,你如何獲取值對象?” 面試者會回答:當我們調用get()方法,HashMap會使用鍵對象的hashcode找到bucket位置,然后獲取值對象。面試官提醒他如果有兩個值對象儲存在同一個bucket,他給出答案:將會遍歷鏈表直到找到值對象。面試官會問因為你並沒有值對象去比較,你是如何確定確定找到值對象的?除非面試者直到HashMap在鏈表中存儲的是鍵值對,否則他們不可能回答出這一題。

其中一些記得這個重要知識點的面試者會說,找到bucket位置之后,會調用keys.equals()方法去找到鏈表中正確的節點,最終找到要找的值對象。完美的答案!

許多情況下,面試者會在這個環節中出錯,因為他們混淆了hashCode()和equals()方法。因為在此之前hashCode()屢屢出現,而equals()方法僅僅在獲取值對象的時候才出現。一些優秀的開發者會指出使用不可變的、聲明作final的對象,並且采用合適的equals()和hashCode()方法的話,將會減少碰撞的發生,提高效率。不可變性使得能夠緩存不同鍵的hashcode,這將提高整個獲取對象的速度,使用String,Interger這樣的wrapper類作為鍵是非常好的選擇。

如果你認為到這里已經完結了,那么聽到下面這個問題的時候,你會大吃一驚。“如果HashMap的大小超過了負載因子(load factor)定義的容量,怎么辦?”除非你真正知道HashMap的工作原理,否則你將回答不出這道題。默認的負載因子大小為0.75,也就是說,當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)一樣,將會創建原來HashMap大小的兩倍的bucket數組,來重新調整map的大小,並將原來的對象放入新的bucket數組中。這個過程叫作rehashing,因為它調用hash方法找到新的bucket位置。

如果你能夠回答這道問題,下面的問題來了:“你了解重新調整HashMap大小存在什么問題嗎?”你可能回答不上來,這時面試官會提醒你當多線程的情況下,可能產生條件競爭(race condition)。

當重新調整HashMap大小的時候,確實存在條件競爭,因為如果兩個線程都發現HashMap需要重新調整大小了,它們會同時試着調整大小。在調整大小的過程中,存儲在鏈表中的元素的次序會反過來,因為移動到新的bucket位置的時候,HashMap並不會將元素放在鏈表的尾部,而是放在頭部,這是為了避免尾部遍歷(tail traversing)。如果條件競爭發生了,那么就死循環了。這個時候,你可以質問面試官,為什么這么奇怪,要在多線程的環境下使用HashMap呢?:)

熱心的讀者貢獻了更多的關於HashMap的問題:

為什么String, Interger這樣的wrapper類適合作為鍵? String, Interger這樣的wrapper類作為HashMap的鍵是再適合不過了,而且String最為常用。因為String是不可變的,也是final的,而且已經重寫了equals()和hashCode()方法了。其他的wrapper類也有這個特點。不可變性是必要的,因為為了要計算hashCode(),就要防止鍵值改變,如果鍵值在放入時和獲取時返回不同的hashcode的話,那么就不能從HashMap中找到你想要的對象。不可變性還有其他的優點如線程安全。如果你可以僅僅通過將某個field聲明成final就能保證hashCode是不變的,那么請這么做吧。因為獲取對象的時候要用到equals()和hashCode()方法,那么鍵對象正確的重寫這兩個方法是非常重要的。如果兩個不相等的對象返回不同的hashcode的話,那么碰撞的幾率就會小些,這樣就能提高HashMap的性能。

我們可以使用自定義的對象作為鍵嗎? 這是前一個問題的延伸。當然你可能使用任何對象作為鍵,只要它遵守了equals()和hashCode()方法的定義規則,並且當對象插入到Map中之后將不會再改變了。如果這個自定義對象時不可變的,那么它已經滿足了作為鍵的條件,因為當它創建之后就已經不能改變了。

我們可以使用CocurrentHashMap來代替Hashtable嗎?這是另外一個很熱門的面試題,因為ConcurrentHashMap越來越多人用了。我們知道Hashtable是synchronized的,但是ConcurrentHashMap同步性能更好,因為它僅僅根據同步級別對map的一部分進行上鎖。ConcurrentHashMap當然可以代替HashTable,但是HashTable提供更強的線程安全性。看看這篇博客查看Hashtable和ConcurrentHashMap的區別。

我個人很喜歡這個問題,因為這個問題的深度和廣度,也不直接的涉及到不同的概念。讓我們再來看看這些問題設計哪些知識點:

hashing的概念

HashMap中解決碰撞的方法

equals()和hashCode()的應用,以及它們在HashMap中的重要性

不可變對象的好處

HashMap多線程的條件競爭

重新調整HashMap的大小

總結

HashMap的工作原理

HashMap基於hashing原理,我們通過put()和get()方法儲存和獲取對象。當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashcode,讓后找到bucket位置來儲存值對象。當獲取對象時,通過鍵對象的equals()方法找到正確的鍵值對,然后返回值對象。HashMap使用鏈表來解決碰撞問題,當發生碰撞了,對象將會儲存在鏈表的下一個節點中。 HashMap在每個鏈表節點中儲存鍵值對對象。

當兩個不同的鍵對象的hashcode相同時會發生什么? 它們會儲存在同一個bucket位置的鏈表中。鍵對象的equals()方法用來找到鍵值對。

因為HashMap的好處非常多,我曾經在電子商務的應用中使用HashMap作為緩存。因為金融領域非常多的運用Java,也出於性能的考慮,我們會經常用到HashMap和ConcurrentHashMap。你可以查看更多的關於HashMap的文章:

請講下Java里面的容器 

 分兩大類,Map和Collection。而Collection又有子接口List(數據存儲順序和插入順序是一樣的)、Set(里面的元素具有唯一性) 

 Map是存儲鍵值對的,里面的健不可以重復,但值可以重復

a. 對於List主要有ArrayList和LinkedList兩種實現。實現的數據結構不同,所以主要的區別也都是和數據結構相關的。 ArrayList基於數組,隨機訪問快,而對於中間元素的插入刪除效率比較低,而且需要考慮擴容問題。LinkedList,則 基於鏈表,和ArrayList提到的正相反,隨機訪問慢,但對於中間元素的插入和刪除更有效率。

Set也是一種Collection,和List比起來主要體現在元素唯一性。

請說下Iterator的作用

 迭代器可以實現Collection接口的方法,可以一個一個地獲取集合中的元素

在遍歷集合時 可判斷是否有下一個元素

說下ArrayList和LinkedList的區別和聯系,並說明什么情況下用它們

 區別:ArrayList用於對象的隨機訪問速度快,沒有順序

LinkedList實現機制是鏈表式的,和順序有關,速度比ArrayList慢

聯系:ArrayList和LinkedList都是List接口的實現類

當要快速獲取一個值時,用ArrayList,用於順序插入操作時,用LinkedList.

說下List,Set,Map三種集合各有什么特征

List集合中的元素可以重復,

Set集合中的元素不可以重復

Map集合用鍵-值映射存放對象,Map容器中的鍵對象不能重復,值對象可以重復

HashSet和TreeSet有什么區別,什么時候用它們

 區別:HashSet中的元素不能重復,沒有順序

TreeSet中的元素不能重復,但有順序

當集合中的元素需要排序時,用TreeSet

一般情況下用HashSet,因為不需要排序,速度比TreeSet快

什么是泛型,怎么使用的,有什么好處?

答案

 定義一個集合時,可以知道里面定義的是什么類型

使用:在集合類型后面加< 數據類型 >

使用泛型后,從集合中取得元素后就不用再用強轉 

什么是for each循環,它可以循環那些數據類型

答案

 也可以叫增強型循環,通過對象拿到集合里的值,因為擴展性比較強,建議多使用

可以用來循環集合和數組

比較下集合和數組的優缺點

 集合是多個對象的容器,可以將不同數據類型的多個對象組織在一起

數組類型是有相同數據類型的數據集合,數組是很多語言都支持的底層數據結構,性能上是最高的

HashMap與LinkedHashMap,和TreeMap的區別。

共同點:HashMap,LinkedHashMap,TreeMap都屬於Map的實現類.

不同點: 1.HashMap里面存入的鍵值對在取出的時候是隨機的,

2.TreeMap取出來的是排序后的鍵值對。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會更好。

3. LinkedHashMap 是HashMap的一個子類,如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實現.

在List里面怎么去掉重復的數?

通過把List里面的數據放入HashSet可以去除重復

HashMap和ArrayList是不是都是線程不安全的? 

ArrayList是線程不安全的;HashMap是線程不安全的;還有我們常見的一些JAVA集合都是線程不安全,這樣做是為了提高性能

在JDK5以后提供了線程安全的並發包java.util.concurrent並發包,譬如里面的類CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap等

ArrayList集合加入1萬條數據,應該怎么提高效率

因為ArrayList的底層是數組實現,並且數組的默認值是10,如果插入10000條要不斷的擴容,耗費時間,所以我們調用ArrayList的指定容量的構造器方法ArrayList(int size) 就可以實現不擴容,就提高了性能

 

網路通訊部分

 

 

Xml與JSON區別

數據交換格式

區別:

xml是重量級、json是輕量級

xml比較占帶寬、json占帶寬小,易於壓縮

json在webservice 用的比較少、xml用的較多

相同:

兩者都用在項目交互下  例如  移動app接口用的就是json、在web項目中與其他項目對接用xml較多。

json常用解析方法 gson、jsonobject、jackson等 xml dom sax pull 解析

 

TCP與UDP區別?

 udp:  a、是面向無連接, 將數據及源的封裝成數據包中,不需要建立建立連接

      b、每個數據報的大小在限制64k內

      c、因無連接,是不可靠協議

       d、不需要建立連接,速度快

tcp:  a、建議連接,形成傳輸數據的通道.

     b、在連接中進行大數據量傳輸,以字節流方式

     c 通過三次握手完成連接,是可靠協議

     d 必須建立連接m效率會稍低

     聊天、網絡視頻會議、桌面共享用的就是  udp

 

說說三次握手?

 1)第一次握手:建立連接時,客戶端A發送SYN包(SYN=j)到服務器B,並進入SYN_SEND狀態,等待服務器B確認。 

(2)第二次握手:服務器B收到SYN包,必須確認客戶A的SYN(ACK=j+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器B進入SYN_RECV狀態。 

(3)第三次握手:客戶端A收到服務器B的SYN+ACK包,向服務器B發送確認包ACK(ACK=k+1),此包發送完畢,客戶端A和服務器B進入ESTABLISHED狀態,完成三次握手。 

完成三次握手,客戶端與服務器開始傳送數據。 

什么是Webserivce?

Webservice就是提供不同的平台相互通訊,基於Soap協議。

Web service 就是一個應用程序,它向外界暴露出一個能夠通過Web進行調用的API。

SOAP是一種簡單基於xml的輕量協議,用戶web上交換結構化信息和類型信息。

soap請求是HTTP POST的一個專用版本,遵循一種特殊的xml消息格式Content-type設置為: text/xml任何數據都可以xml化。

WebService實現原理是?

HTTP協議+XML

說一下什么是Http協議?

對器客戶端和 服務器端之間數據傳輸的格式規范,格式簡稱為“超文本傳輸協議”

什么是Http協議無狀態協議?怎么解決Http協議無狀態協議?(曾經去某創業公司問到)

1、無狀態協議對於事務處理沒有記憶能力。缺少狀態意味着如果后續處理需要前面的信息

2、無狀態協議解決辦法: 通過1、Cookie 2、通過Session會話保存。

說一下Http協議中302狀態(阿里經常問)

http協議中,返回狀態碼302表示重定向。

這種情況下,服務器返回的頭部信息中會包含一個 Location 字段,內容是重定向到的url

Http協議有什么組成?

請求報文包含三部分:

a、請求行:包含請求方法、URI、HTTP版本信息

b、請求首部字段

c、請求內容實體

響應報文包含三部分:

a、狀態行:包含HTTP版本、狀態碼、狀態碼的原因短語

b、響應首部字段

c、響應內容實體

Http協議中有那些請求方式?

GET: 用於請求訪問已經被URI(統一資源標識符)識別的資源,可以通過URL傳參給服務器

POST:用於傳輸信息給服務器,主要功能與GET方法類似,但一般推薦使用POST方式。

PUT: 傳輸文件,報文主體中包含文件內容,保存到對應URI位置。

HEAD: 獲得報文首部,與GET方法類似,只是不返回報文主體,一般用於驗證URI是否有效。

DELETE:刪除文件,與PUT方法相反,刪除對應URI位置的文件。

OPTIONS:查詢相應URI支持的HTTP方法。

Http協議中Http1.0與1.1區別?

在http1.0中,當建立連接后,客戶端發送一個請求,服務器端返回一個信息后就關閉連接,當瀏覽器下次請求的時候又要建立連接,顯然這種不斷建立連接的方式,會造成很多問題。

5.在http1.1中,引入了持續連接的概念,通過這種連接,瀏覽器可以建立一個連接之后,發送請求並得到返回信息,然后繼續發送請求再次等到返回信息,也就是說客戶端可以連續發送多個請求,而不用等待每一個響應的到來。

Http協議實現原理機制?

    2.1、整個流程步驟

               

 

  2.2、域名解析過程

               

 

 2.3、三次握手過程

     2.4、發起HTTP請求

     2.5、響應HTTP請求並得到HTML代碼

     2.6、瀏覽器解析HTML代碼

     2.7、瀏覽器對頁面進行渲染呈現給用戶

get與post請求區別?(初級程序員必備問題)

區別一:

  get重點在從服務器上獲取資源,post重點在向服務器發送數據;

區別二:

   get傳輸數據是通過URL請求,以field(字段)= value的形式,置於URL后,並用"?"連接,多個請求數據間用"&"連接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,這個過程用戶是可見的;

post傳輸數據通過Http的post機制,將字段與對應值封存在請求實體中發送給服務器,這個過程對用戶是不可見的;

區別三:

   Get傳輸的數據量小,因為受URL長度限制,但效率較高;

Post可以傳輸大量數據,所以上傳文件時只能用Post方式;

區別四:

   get是不安全的,因為URL是可見的,可能會泄露私密信息,如密碼等;

post較get安全性較高;

區別五:

   get方式只能支持ASCII字符,向服務器傳的中文字符可能會亂碼。

post支持標准字符集,可以正確傳遞中文字符。

9、Http請求報文與響應報文格式?

請求報文包含三部分:

a、請求行:包含請求方法、URI、HTTP版本信息

b、請求首部字段

c、請求內容實體

響應報文包含三部分:

a、狀態行:包含HTTP版本、狀態碼、狀態碼的原因短語

b、響應首部字段

c、響應內容實體

10、常見Http協議狀態?

200:請求被正常處理

204:請求被受理但沒有資源可以返回

206:客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法,相應報文中通過Content-Range指定范圍的資源。

301:永久性重定向

302:臨時重定向

303:與302狀態碼有相似功能,只是它希望客戶端在請求一個URI的時候,能通過GET方法重定向到另一個URI上

304:發送附帶條件的請求時,條件不滿足時返回,與重定向無關

307:臨時重定向,與302類似,只是強制要求使用POST方法

400:請求報文語法有誤,服務器無法識別

401:請求需要認證

403:請求的對應資源禁止被訪問

404:服務器無法找到對應資源

500:服務器內部錯誤

503:服務器正忙

Http協議首部字段?

a、通用首部字段(請求報文與響應報文都會使用的首部字段)

Date:創建報文時間

Connection:連接的管理

Cache-Control:緩存的控制

Transfer-Encoding:報文主體的傳輸編碼方式

b、請求首部字段(請求報文會使用的首部字段)

Host:請求資源所在服務器

Accept:可處理的媒體類型

Accept-Charset:可接收的字符集

Accept-Encoding:可接受的內容編碼

Accept-Language:可接受的自然語言

c、響應首部字段(響應報文會使用的首部字段)

Accept-Ranges:可接受的字節范圍

Location:令客戶端重新定向到的URI

Server:HTTP服務器的安裝信息

d、實體首部字段(請求報文與響應報文的的實體部分使用的首部字段)

Allow:資源可支持的HTTP方法

Content-Type:實體主類的類型

Content-Encoding:實體主體適用的編碼方式

Content-Language:實體主體的自然語言

Content-Length:實體主體的的字節數

Content-Range:實體主體的位置范圍,一般用於發出部分請求時使用

Http與Https優缺點?

a、通信使用明文不加密,內容可能被竊聽,也就是被抓包分析。

b、不驗證通信方身份,可能遭到偽裝

c、無法驗證報文完整性,可能被篡改

HTTPS就是HTTP加上加密處理(一般是SSL安全通信線路)+認證+完整性保護

Http優化

利用負載均衡優化和加速HTTP應用

利用HTTP Cache來優化網站

Http協議有那些特征?

1、支持客戶/服務器模式;2、簡單快速;3、靈活;4、無連接;5、無狀態;

如果你還對Http協議不熟悉的話,請參考Http協議http://www.itmayiedu.com/front/articleinfo/49.html文章

JavaWeb基礎部分

講下Servlet的執行流程。doGet和doPost的區別

  Servlet的執行流程也就是servlet的生命周期,當服務器啟動的時候生命周期開始,然后通過init()《啟動順序根據web.xml里的startup-on-load來確定加載順序》方法初始化servlet,再根據不同請求調用doGet或doPost方法,最后再通過destroy()方法進行銷毀。

doGet和doPost都是接受用戶請求的方法,doGet處理get請求,doPost處理post請求,doGet用於地址欄提交,doPost用於表單提交,在頁面提交數據時,get的數據大小有限制4k,post沒有限制,get請求提交的數據會在地址欄顯示,post不顯示,所以post比get安全.

當service有一個實例變量,doGet和doPost去調用這個變量,會出現什么問題,你是如何解決的。

會出現線程不安全問題。無論是doGet還是doPost去調用,服務器端處理的過程都是一樣的,那么我們可以把處理過程單獨寫在另外一個方法handle里,讓兩個方法都去調用handle,根據不同請求去調用不同的方法。

如何處理servlet的線程不安全問題

線程安全就是多線程操作同一個對象不會有問題,線程同步一般來保護線程安全,所以可以在Servlet的線程里面加上同步方法或同步塊。(Synchronized)可以保證在同一時間只有一個線程訪問,(使用同步塊會導致性能變差,最好不去使用實例變量)

Jsp的重定向和轉發的流程有什么區別

重定向是客戶端行為,轉發是服務器端行為

重定向時服務器產生兩次請求,轉發產生一次請求,重定向時可以轉發到項目以外的任何網址,轉發只能在當前項目里轉發

重定向會導致request對象信息丟失。轉發則不會

轉發的url不會變,request.getRequestDispatch()。forward()

重定向的url會改變,response.getRedirect();

Jsp和servlet的區別

jsp的可讀性強,容易維護,並且jsp在最后會編譯成servlet

servlet容易調試

Jsp的九大內置對象,三大指令,七大動作的具體功能

JSP九大內置對象:

pageContext :只對當前jsp頁面有效,里面封裝了基本的requestsession的對象
Request
:對當前請求進行封裝
Session
:瀏覽器會話對象,瀏覽器范圍內有效
Application
:應用程序對象,對整個web工程都有效
Out
:頁面打印對象,在jsp頁面打印字符串
Response
:返回服務器端信息給用戶
Config
:單個servlet的配置對象,相當於servletConfig對象
Page
:當前頁面對象,也就是this
Exception
:錯誤頁面的exception對象,如果指定的是錯誤頁面,這個就是異常對象

三大指令:

Page :指令是針對當前頁面的指令
Include
:用於指定如何包含另一個頁面
Taglib
:用於定義和指定自定義標簽

七大動作:

Forward,執行頁面跳轉,將請求的處理轉發到另一個頁面
Param
:用於傳遞參數
Include
:用於動態引入一個jsp頁面
Plugin
:用於下載javaBeanapplet到客戶端執行
useBean
:使用javaBean
setProperty
:修改javaBean實例的屬性值
getProperty
:獲取javaBean實例的屬性值

獲取頁面的元素和值有幾種方式,分別說一下

request.getParameter() 返回客戶端的請求參數與值

request.getParameterNames() 
返回所有可用屬性名的枚舉

request.getParameterValues() 
返回包含參數的所有值的數組

servlet和javaScript的區別,他們分別是什么作用

一個是服務端,一個是客戶端

Servlet是獨立於平台和協議的服務器端的java應用程序,可以動態生成web頁面,並采用響應--請求的模式提供web服務

javaScript是一種解釋性語言,用於向html頁面提供交互行為,通常被直接嵌入在html頁面中

servletjava語言編寫的web應用

js是基於html上的一種解釋語言

會話跟蹤有哪些,他們的區別是什么

Cookiesessionapplication
Cookie
http對象,客戶端與服務端都可以操縱

cookie是在客戶端保持狀態,session是在服務器端保持狀態,由於cookie是保存在客戶端本地的,所以數據很容易被竊取,當訪問量很多時,使用session則會降低服務器的性能,application的作用域是整個工程里只有一個,可以在不同瀏覽器之間共享數據,所有人都可以共享,因此application也是不安全的

說說jsp的隱藏對象有哪些

Request,out,response , pageContext , session , application , config , page , exception,也即jsp的九大內置對象

request ,response,session 和 application是怎么用的

Request是客戶端向服務端發送請求

Response是服務端對客戶端請求做出響應

Sessionservlet中不能直接使用,需要通過getSession()創建,如果沒有設定它的生命周期,或者通過invildate()方法銷毀,關閉瀏覽器session就會消失

Application不能直接創建,存在於服務器的內存中,由服務器創建和銷毀

jsp頁面跳轉

Jsp頁面跳轉有兩種方式,forwardredirect(轉發和重定向)

Forward只能在當前項目里跳轉,只產生一次請求,request保存的變量不會丟失,url地址不會改變

Redirect可跳轉到項目以外的任何頁面,產生兩次請求,request保存的變量會全部丟失,url地址會發生改變,變化為第二個請求的地址

話跟蹤

如果創建servlet實例不用構造方法,怎么創建一個servlet實例

Web容器會自動為servlet寫一個無參的構造器,它使用class.forName("").newInstance()反射來創建servlet實例的

Servlet是安全的嗎?當service有一個實例變量,doGet和doPost去調用這個變量,會出現什么問題,你是如何解決的

是線程不安全的,因為servlet是單例模式,當多個客戶端共同訪問的時候線程不安全。

盡量用局部變量,同步塊,如果當前字段是不會改變的,用final修飾

 

Java框架部分

說說Spring

Spring的核心是控制反轉、依賴注入,Aop(面向切面)相當於把每個bean與bean之間的關系交給第 三方容器進行管理.

SpringIOCSpringAOP?

SpringIOC ,其實就是依賴注入、控制反轉。相當於把每個bean與bean之間的關系交給第三方容器管理。而這個容器就是spring

SpringAOP 面向切面的編程,或AOP,是一種編程技術,允許程序模塊化橫向切割關注點,或橫切典型的責任划分,如日志和事務管理。 SpringAop 就是用 Javva的動態代理

 

Spring的底層實現機制是什么?

使用Demo4j(解析XML)+Java反射機制

Demo4j 其實就是解析XML。使用反射機制實例化bean。

 

SpringAOP用到了什么代理?

JDK動態代理:對實現了接口的類生成代理

CGLib代理機制:對類生成代理

動態代理與靜態代理區別?

靜態代理:由程序員創建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。 
動態代理:在程序運行時,運用反射機制動態創建而成。 

Spring注入有那些方式?

Set注入

構造器注入

靜態工廠的方法注入

實例工廠的方法注入

Spring有那些注解?

@Autowired(按類型注入)

@Service(標示為注入為服務層)

@Resource(按名稱注入)

@Controller(標識控制器bean id)

@RequestMapping(表示映射URL路徑)

簡述Spring的優缺點?

  Spring 的優點??

  1.降低了組件之間的耦合性 ,實現了軟件各層之間的解耦

  2.可以使用容易提供的眾多服務,如事務管理,消息服務等

  3.容器提供單例模式支持

  4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能

  5.容器提供了眾多的輔助類,能加快應用的開發

  6.spring對於主流的應用框架提供了集成支持,如hibernate,JPA,Struts等

  7.spring屬於低侵入式設計,代碼的污染極低

  8.獨立於各種應用服務器

  9.spring的DI機制降低了業務對象替換的復雜性

  10.Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可以自由選擇spring的部分或全部

缺點:

使用到了大量反射機制。反射機制非常占內存,

SpringMVC工程流程

1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

2. DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然后根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象(包括Handler對象以及Handler對象對應的攔截器),最后以HandlerExecutionChain對象的形式返回;

3. DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時將開始執行攔截器的preHandler(...)方法)

4.  提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,根據你的配置,Spring將幫你做一些額外的工作:

      HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息

      數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等

      數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等

      數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中

5.  Handler執行完成后,向DispatcherServlet 返回一個ModelAndView對象;

6.  根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經注冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;

7. ViewResolver 結合Model和View,來渲染視圖

8. 將渲染結果返回給客戶端。

 

SpringMVC工作流程描述

 為什么SpringMVC只使用一個Servlet(DispatcherServlet)來處理所有請求?

詳細見J2EE設計模式-前端控制模式

Spring為什么要結合使用HandlerMapping以及HandlerAdapter來處理Handler?

符合面向對象中的單一職責原則,代碼架構清晰,便於維護,最重要的是代碼可復用性高。如HandlerAdapter可能會被用於處理多種Handler。

 

Hibernate面試題

什么是Hibernate?

hibernate是一個基於ORM持久框架,可以讓程序員以面向對象的思想操作數據庫,提高生產效率.

什么是ORM?

orm不過是一種思想,對象關系映射。是對象關系模型,如hibernate,讓你以面向對象的方式去編程。封裝了JDBC.

 

說一下orm與jdbc的區別?

jdbc只是一個java操作數據庫的規范接口而已

orm不過是一種思想,對象關系映射。

ORM:是對象關系模型,如hibernate,讓你以面向對象的方式去編程。封裝了JDBC.

JDBC:是從底層訪問數據庫服務器。一般銀行,金融行業為了安全起見,直接用JDBC訪問

Hibernate中get和load有什么不同之處? 

load :找不到數據的話會拋出org.hibernate.ObjectNotFoundException異常。此時hibernate會使用延遲加載加載機制

 get找不到的話會返回null。 

如果查詢不到數據,get 會返回 null,但是不會報錯, load 如果查詢不到數據,則報錯ObjectNotFoundException

使用get 去查詢數據,(先到一級/二級)會立即向db發出查詢請求(select ...), 如果你使用的是 load查詢數據,(先到一級、二級))即使查詢到對象,返回的是一個代理對象,如果后面沒有使用查詢結果,它不會真的向數據庫發select ,當程序員使用查詢結果的時候才真的發出select ,這個現象我們稱為懶加載(lazy)

hibernate的三種狀態?

在Hibernate中,對象有三種狀態:臨 時狀態(Transient)、持久狀態(Persistent)和游離狀態(Detached)。

處於持久態的對象也稱為 PO(PersistenceObject),臨時對象和游離對象也稱為VO(ValueObject). 

 

hibernate的懶加載? 有幾種禁用方法

在Hibernate框架中,當我們要訪問的數據量過大時,明顯用緩存不太合適, 因為內存容量有限 ,為了減少並發量,減少系統資源的消耗,這時Hibernate用懶加載機制來彌補這種缺陷,但是這只是彌補而不是用了懶加載總體性能就提高了。

我們所說的懶加載也被稱為延遲加載,它在查詢的時候不會立刻訪問數據庫,而是返回代理對象,當真正去使用對象的時候才會訪問數據庫。

1.使用代理對象:Hibernate.initialize("代理對象");

2.在需要禁用懶加載的映射文件中顯示的加入lazy = "false"

3.使用openSessionInView【需要借助於過濾器】 需要在web.xml文件中配置

hibernate有幾種查詢方式?

1、 屬性查詢2、 參數查詢、命名參數查詢3、 關聯查詢4、 分頁查詢5、 統計函數

Hibernate的優缺點?

1.Hibernate的優缺點:
優點:1、程序更加面向對象;
2、提高了生產率;
3、方便移植(修改配置文件);
4、無侵入性。
缺點:
1、效率比JDBC略差;
2、不適合批量操作。

Hibernate的緩存機制

Hibernate緩存包括兩大類:Hibernate一級緩存和Hibernate二級緩存。

1.Hibernate一級緩存又稱為“Session的緩存”。

Session內置不能被卸載,Session的緩存是事務范圍的緩存(Session對象的生命周期通常對應一個數據庫事務或者一個應用事務)。

一級緩存中,持久化類的每個實例都具有唯一的OID。

2.Hibernate二級緩存又稱為“SessionFactory的緩存”。

由於SessionFactory對象的生命周期和應用程序的整個過程對應,因此Hibernate二級緩存是進程范圍或者集群范圍的緩存,有可能出現並發問題,因此需要采用適當的並發訪問策略,該策略為被緩存的數據提供了事務隔離級別。

第二級緩存是可選的,是一個可配置的插件,默認下SessionFactory不會啟用這個插件。

Hibernate提供了org.hibernate.cache.CacheProvider接口,它充當緩存插件與Hibernate之間的適配器。

Hibernate延遲加載?

1) Hibernate2延遲加載實現:a)實體對象 b)集合(Collection)

2) Hibernate3 提供了屬性的延遲加載功能 當Hibernate在查詢數據的時候,數據並沒有存在與內存中,當程序真正對數據的操作時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提高了服務器的性能。 

Hibernate工作原理及為什么要用?

原理:

1)        讀取並解析配置文件

2)        讀取並解析映射信息

3)        創建SessionFactory

4)        打開Sesssion

5)        創建事務Transation

6)        持久化操作

7)        提交事務

8)        關閉Session

9)        關閉SesstionFactory

為什么要用:

1)        對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重復性代碼。

2)        Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工作

3)        hibernate使用Java反射機制,而不是字節碼增強程序來實現透明性。

4)        hibernate的性能非常好,因為它是個輕量級框架。映射的靈活性很出色。它支持各種關系數據庫,從一對一到多對多的各種復雜關系。

 

什么是Mybatis?

Mybatis的前生是ibatis,最后升級版本后名稱叫mybatis。mybatis是以純sql操作數據。

Mybatis與Hibernate區別?

Hibernate是面向對象的思想操作數據生成Sql語句,而mybatis是以純sql操作數據

相對於mybatis容易優化.擴展性好,但是移植性差。

設計模式部分

你熟悉那些設計模式?

總共有23種設計模式

總體來說設計模式分為三大類:

創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

企業面試的時候,面試官非常喜歡考單例,而且非常喜歡考手寫單例。

什么是單例?單例有那些寫法?

單例分類:懶漢式單例、餓漢式單例
單例模式有以下特點:
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。

①懶漢式單例

  1. //懶漢式單例類.在第一次調用的時候實例化自己   
  2. public class Singleton {  
  3.     private Singleton() {}  
  4.     private static Singleton single=null;  
  5.     //靜態工廠方法   
  6.     public static Singleton getInstance () {  
  7.          if (single == null) {    
  8.              single = new Singleton();  
  9.          }    
  10.         return single;  
  11.     }  
  12. }  

②餓漢式單例

  1. //餓漢式單例類.在類初始化時,已經自行實例化   
  2. public class Singleton1 {  
  3.     private Singleton1() {}  
  4.     private static final Singleton1 single = new Singleton1();  
  5.     //靜態工廠方法   
  6.     public static Singleton1 getInstance() {  
  7.         return single;  
  8.     }  
  9. }  

懶漢式與餓漢式區別?

從名字上來說,餓漢和懶漢,

餓漢就是類一旦加載,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,

而懶漢比較懶,只有當調用getInstance的時候,才回去初始化這個單例。

另外從以下兩點再區分以下這兩種方式:

 

1、線程安全:

餓漢式天生就是線程安全的,可以直接用於多線程而不會出現問題,

懶漢式本身是非線程安全的,為了實現線程安全有幾種寫法,分別是上面的1、2、3,這三種實現在資源加載和性能方面有些區別。

 

2、資源加載和性能:

餓漢式在類創建的同時就實例化一個靜態對象出來,不管之后會不會使用這個單例,都會占據一定的內存,但是相應的,在第一次調用時速度也會更快,因為其資源已經初始化完成,

而懶漢式顧名思義,會延遲加載,在第一次使用該單例的時候才會實例化對象出來,第一次調用時要做初始化,如果要做的工作比較多,性能上會有些延遲,之后就和餓漢式一樣了。

 

項目相關面試題

你說說你做的最好的項目?

要重點介紹到①項目是做什么?②用到那些技術?③整個項目中最大的亮點是?核心部分④遇到bug是怎么解決的?

例如: 我認為我做的最好的項目是

創辦了螞蟻課堂it在線教學網站,螞蟻課堂在線教育網站,類似(慕課網、我要自學網)是一家為IT愛好者提供免費教學服務網站,分為首頁、課程、博客、問答四大專區,自己也錄制一些Java教學視頻發布在螞蟻課堂網站上。目前國內各大搜索引擎都可以通過搜索“螞蟻課堂”關鍵字找到螞蟻課堂網站,目前日均PV5000-7000等

使用技術SpringMVC+Mybatis+Spring+Maven,視頻接口才第三方樂視雲接口,使用反向代理nginx+tomcat實現負載均衡及集群減輕單台服務器壓力、使用CDN加速提高網絡分發。………

你項目遇到bug?怎么查問題?

例如:首先遇到了bug,會查詢日志,通過日志定位到某個類的行數,判斷是否有代碼問題。

你遇到了什么bug?你是怎么解決?

例如我自己項目中,查詢量非常大。通過日志發現了堆內存溢出,最后通過優化代碼,減輕new和加大堆內存。

你們項目人員是怎么分配的?

項目分配為:

產品經理(負責提需求)

UI設計師(負責設計樣式文件)

Web前端(只做Web頁面前端靜態文件)

Java工程師(寫業務邏輯)

測試人員(負責測試bug)

非技術項目經理(負責項目管理、人員分配)

項目架構師(負責架構項目)

你們項目是怎么發布的?

企業當中項目都是發布在linux環境上

小公司:使用maven編譯好通過打war包,放入到tomcat的webapps文件下

大公司:使用自動部署系統jenkins  jenkins直接關聯svn地址自動打包、自動部署等

說說linux常用命令?

Cat 查看某個文件

CP 拷貝

Ls  查看所有列表

Pwd  查看路徑

Tail 查看日志

Grep 搜索日志


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM