&和&&都是邏輯運算符,都是判斷兩邊同時真則爲真,不然爲假;可是&&當第一個條件不成以後,後面的條件都不執行了,而&則仍是繼續執行,直到整個條件語句執行完爲止。html
使用 final 關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容 仍是能夠改變的。前端
在語法定義上的區別:java
靜態變量前要加 static 關鍵字,而實例變量前則不加。linux
在程序運行時的區別:實例變量屬於某個對象的屬性,必須建立了實例對象,其中的實例變 量纔會被分配空間,才能使用這個實例變量。android
靜態變量不屬於某個實例對象,而是屬於類, 因此也稱爲類變量,只要程序加載了類的字節碼,不用建立任何實例對象,靜態變量就會被分配空間,靜態變量就能夠被使用了。nginx
總之,實例變量必須建立對象後才能夠經過這個對象 來使用,靜態變量則能夠直接使用類名來引用。程序員
靜態變量使用時,經過類名.名稱,實例變量必需要初始化後才能使用。實例變量是實例化後纔會分配空間,而靜態變量當類加載時會分配空間。web
不能夠。由於非 static 方法是要與對象關聯在一塊兒的,必須建立一個對象後,才能夠在該對 象上進行方法調用,而 static 方法調用時不須要建立對象,能夠直接調用。也就是說,當一 個 static 方法被調用時,可能尚未建立任何實例對象,若是從一個 static 方法中發出對非 static 方法的調用,那個非 static 方法是關聯到哪一個對象上的呢?這個邏輯沒法成立,因此, 一個 static 方法內部發出對非 static 方法的調用。面試
非static方法能夠訪問static方法.ajax
static方法不能訪問非static方法
==若是判斷值類型的話,判斷內容是否相同。若是判斷引用類型則是判斷內存地址是否相同
Equals判斷值內容是否相等
Integer 是引用類型,默認值是null。而int是是值類型默認值是0
這四個做用域的可見範圍以下表所示。
說明:若是在修飾的元素上面沒有寫任何訪問修飾符,則表示 friendly。
做用域 當前類 同一包( package) 子孫類 其餘包( package)
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
重載是同一個類中,方法名稱相同, 可是參數或個數不一樣。與返回值沒有關係。
重寫是在多個類中, 產生繼承關係。父類與子類的方法方法必須相同。
區別:定義接口的關鍵字是:interface 而定義抽象類的關鍵字是:abstract。
接口中成員不能有私有, 抽象類能夠。
接口中定義的成員, 是finl public static 類型, 抽象類沒有。
接口中的不能有普通方法, 抽象類中能夠。
相同:
兩個都不new
可是 接口與抽象類是面向對象必備知識,設計模式、重構代碼有必然做用
final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
內部類要訪問局部變量,局部變量必須定義成 final 類型,例如,一段代碼……
finally 是異常處理語句結構的一部分,表示老是執行。
finalize 是 Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可
以覆蓋此方法提供垃圾收集時的其餘資源回收,例如關閉文件等。 JVM 不保證此方法總被
調用
String 字符串常量
StringBuffer 字符串變量(線程安全)
StringBuilder 字符串變量(非線程安全)
接口中不能有構造方法,抽象類中能夠有
抽象類中能夠包含普通方法,接口中的方法都被隱式指定爲public abstract方法而且只能是public abstract的、
抽象類能夠有普通的成員變量,接口中的成員變量必須是public static final 的
抽象類中的方法的訪問能夠是public ,protected和默認類型
抽象類中能夠包含靜態方法,接口中不能包含靜態方法
一個類能夠實現多個接口,可是隻能繼承一個抽象類
自動數據類型轉換
Byte>short>char>int>long>float>double>long
運算中數據類型轉換
一類型 二類型 轉換後的類型
Byte,short,char int int
Byte,short,char,int long long
Byte,short,char,int,long float float
Byte,short,char,int,long,float double double
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)使用反射會模糊程序內內部邏輯:程序員但願在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,於是會帶來維護問題。反射代碼比相應的直接代碼更復雜。
例如: jdbc、Java經常使用框架、jdk的動態代理、android的加載佈局文件
字節流,字符流。字節流繼承於 InputStream OutputStream,字符流繼承於
InputStreamReaderOutputStreamWriter。在 java.io 包中還有許多其餘的流,主要是爲了提
高性能和使用方便。
在一個應用程序中,同時,有多個不一樣的執行路徑。
提供程序效率。
線程是進程的一條執行路徑,而進程是線程的集合。
線程同步表示,當前線程執行完後下一個線程接着執行。
線程異步表示, 在一個應用程序中,同時,有多個不一樣的執行路徑。例如 javaweb ajax android handler
線程之間同步使用 synchronized、wait 與 notify
就是在多個線程共享同一個數據會受到其餘線程的干擾。如何解決:使用線程同步技術, 用上鎖(synchronized)。 讓一個線程執行完了,在讓另外一個線程執行。
繼承thread類, 重寫run方法、實現Runnalbe接口,從新run方法 , 啓動一個線程用start();
是實現Runnalbe接口好,由於實現的接口還能夠繼續繼承。若是繼承了Thread類不能在繼承。
a、sleep是讓當前線程指定休眠時間,而後繼續工做 不釋放鎖
b、讓當前線程wait則是等待,直到有線程通知notify()喚醒他纔會從新工做。釋放鎖
所謂數組,是相同數據類型的元素按必定順序排列的集合
數組:存儲區間是連續的,佔用內存嚴重,故空間複雜的很大。但數組的二分查找時間複雜度小,爲O(1);數組的特色是:尋址容易,插入和刪除困難;
所謂鏈表,鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是經過鏈表中的指針連接次序實現的。鏈表由一系列結點(鏈表中每個元素稱爲結點)組成,結點能夠在運行時動態生成。每一個結點包括兩個部分:一個是存儲數據元素的數據域,另外一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操做複雜。因爲沒必要須按順序存儲,鏈表在插入的時候能夠達到O(1)的複雜度,比另外一種線性表順序錶快得多,可是查找一個節點或者訪問特定編號的節點則須要O(n)的時間,而線性表和順序表相應的時間複雜度分別是O(logn)和O(1)。
鏈表:鏈表存儲區間離散,佔用內存比較寬鬆,故空間複雜度很小,但時間複雜度很大,達O(N)。鏈表的特色是:尋址困難,插入和刪除容易。
那麼咱們能不能綜合二者的特性,作出一種尋址容易,插入刪除也容易的數據結構?答案是確定的,這就是咱們要提起的哈希表。哈希表((Hash table)既知足了數據的查找方便,同時不佔用太多的內容空間,使用也十分方便。
哈希表有多種不一樣的實現方法,我接下來解釋的是最經常使用的一種方法—— 拉鍊法,咱們能夠理解爲「鏈表的數組」 ,如圖:
①ArrayList經過數組實現,一旦咱們實例化ArrayList無參數構造函數默認爲數組初始化長度爲10
②add方法底層實現若是增長的元素個數超過了10個,那麼ArrayList底層會新生成一個數組,長度爲原數組的1.5倍+1,而後將原數組的內容複製到新數組當中,而且後續增長的內容都會放到新數組當中。當新數組沒法容納增長的元素時,重複該過程。是一旦數組超出長度,就開始擴容數組。擴容數組調用的方法 Arrays.copyOf(objArr, objArr.length + 1);
LinkedList底層的數據結構是基於雙向循環鏈表的,且頭結點中不存放數據,以下:
既然是雙向鏈表,那麼一定存在一種數據結構——咱們能夠稱之爲節點,節點實例保存業務數據,前一個節點的位置信息和後一個節點位置信息,以下圖所示:
HashMap是由數組+鏈表組成
put方法底層實現:
經過key的hash值%Entry[].length獲得該存儲的下標位置,若是多個key的hash值%Entry[].length 值相同話就就會存儲到該鏈表的後面。
這兩個類都實現了 List 接口(List 接口繼承了Collection 接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,至關於一種動態的數組,咱們之後能夠按位置索引號取出某個元素,而且其中的數據是容許重複的,
ArrayList 與 Vector 的區別,這主要包括兩個方面:.
(1)同步性:
Vector 是線程安全的,也就是說是它的方法之間是線程同步的,而 ArrayList 是線程序不安全的,它的方法之間是線程不一樣步的。若是隻有一個線程會訪問到集合,那最好是使用 ArrayList,由於它不考慮線程安全,效率會高些;若是有多個線程會訪問到集合,那最好是使用 Vector,由於不須要咱們本身再去考慮和編寫線程安全的代碼。
(2)數據增加:
ArrayList 與 Vector 都有一個初始的容量大小,當存儲進它們裏面的元素的個數超過了容量時,就須要增長 ArrayList 與 Vector 的存儲空間,每次要增長存儲空間時,不是隻增長一個存儲單元,而是增長多個存儲單元,每次增長的存儲單元的個數在內存空間利用與程序效率之間要取得必定的平衡。Vector 默認增加爲原來兩倍,而 ArrayList 的增加策略在文檔中沒有明確規定(從源代碼看到的是增加爲原來的1.5倍)。
ArrayList 與 Vector 均可以設置初始的空間大小,Vector 還能夠設置增加的空間大小,而 ArrayList 沒有提供設置增加空間的方法。
總結:
hashmap |
線程不安全 |
容許有null的鍵和值 |
效率高一點、 |
方法不是Synchronize的要提供外同步 |
有containsvalue和containsKey方法 |
HashMap 是Java1.2 引進的Map interface 的一個實現 |
HashMap是Hashtable的輕量級實現 |
hashtable |
線程安全 |
不容許有null的鍵和值 |
效率稍低、 |
方法是是Synchronize的 |
有contains方法方法 |
、Hashtable 繼承於Dictionary 類 |
Hashtable 比HashMap 要舊 |
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:存儲: 有序的 可重複的
訪問:能夠for循環,foreach循環,iterator迭代器 迭代。
set:存儲:無序的 不重複的
訪問:能夠foreach循環,iterator迭代器 迭代
map:存儲:存儲的是一對一對的映射 」key=value「,key值 是無序,不重複的。value值可重複
訪問:能夠map中key值轉爲爲set存儲,而後迭代這個set,用map.get(key)獲取value
也能夠 轉換爲entry對象 用迭代器迭代
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector因爲使用了synchronized方法(線程安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。
經過Vector.contains()方法判斷是否包含該元素,若是沒有包含就添加到新的集合當中,適用於數據較小的狀況下。
Collection是集合類的上級接口,繼承於它的接口主要有Set和List。 Collections是針對集合類的一個幫助類,它提供了一系列靜態方法實現了對各類集合的排序,搜索和線程安全等操做。
set裏的元素是不能重複的,用iterator()方法來區分重複與否。
equals 方法(是String類從它的超類Object中繼承的)被用來檢測兩個對象是否相等,即兩個對象的內容是否相等。
==用於比較引用和比較基本數據類型時具備不一樣的功能:
比較基本數據類型,若是兩個值相同,則結果爲true
而在比較引用時,若是引用指向內存中的同一對象,結果爲true
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基於hashing原理,咱們經過put()和get()方法儲存和獲取對象。當咱們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashcode,讓後找到bucket位置來儲存值對象。當獲取對象時,經過鍵對象的equals()方法找到正確的鍵值對,而後返回值對象。HashMap使用鏈表來解決碰撞問題,當發生碰撞了,對象將會儲存在鏈表的下一個節點中。 HashMap在每一個鏈表節點中儲存鍵值對對象。
當兩個不一樣的鍵對象的hashcode相同時會發生什麼? 它們會儲存在同一個bucket位置的鏈表中。鍵對象的equals()方法用來找到鍵值對。
由於HashMap的好處很是多,我曾經在電子商務的應用中使用HashMap做爲緩存。由於金融領域很是多的運用Java,也出於性能的考慮,咱們會常常用到HashMap和ConcurrentHashMap。你能夠查看更多的關於HashMap的文章:
分兩大類,Map和Collection。而Collection又有子接口List(數據存儲順序和插入順序是同樣的)、Set(裏面的元素具備惟一性)
Map是存儲鍵值對的,裏面的健不能夠重複,但值能夠重複
a. 對於List主要有ArrayList和LinkedList兩種實現。實現的數據結構不一樣,因此主要的區別也都是和數據結構相關的。 ArrayList基於數組,隨機訪問快,而對於中間元素的插入刪除效率比較低,並且須要考慮擴容問題。LinkedList,則 基於鏈表,和ArrayList提到的正相反,隨機訪問慢,但對於中間元素的插入和刪除更有效率。
Set也是一種Collection,和List比起來主要體如今元素惟一性。
迭代器能夠實現Collection接口的方法,能夠一個一個地獲取集合中的元素
在遍歷集合時 可判斷是否有下一個元素
區別:ArrayList用於對象的隨機訪問速度快,沒有順序
LinkedList實現機制是鏈表式的,和順序有關,速度比ArrayList慢
聯繫:ArrayList和LinkedList都是List接口的實現類
當要快速獲取一個值時,用ArrayList,用於順序插入操做時,用LinkedList.
List集合中的元素能夠重複,
Set集合中的元素不能夠重複
Map集合用鍵-值映射存放對象,Map容器中的鍵對象不能重複,值對象能夠重複
區別:HashSet中的元素不能重複,沒有順序
TreeSet中的元素不能重複,但有順序
當集合中的元素須要排序時,用TreeSet
通常狀況下用HashSet,由於不須要排序,速度比TreeSet快
答案
定義一個集合時,能夠知道里面定義的是什麼類型
使用:在集合類型後面加< 數據類型 >
使用泛型後,從集合中取得元素後就不用再用強轉
答案
也能夠叫加強型循環,經過對象拿到集合裏的值,由於擴展性比較強,建議多使用
能夠用來循環集合和數組
集合是多個對象的容器,能夠將不一樣數據類型的多個對象組織在一塊兒
數組類型是有相同數據類型的數據集合,數組是不少語言都支持的底層數據結構,性能上是最高的
共同點:HashMap,LinkedHashMap,TreeMap都屬於Map的實現類.
不一樣點: 1.HashMap裏面存入的鍵值對在取出的時候是隨機的,
2.TreeMap取出來的是排序後的鍵值對。但若是您要按天然順序或自定義順序遍歷鍵,那麼TreeMap會更好。
3. LinkedHashMap 是HashMap的一個子類,若是須要輸出的順序和輸入的相同,那麼用LinkedHashMap能夠實現.
經過把List裏面的數據放入HashSet能夠去除重複
ArrayList是線程不安全的;HashMap是線程不安全的;還有咱們常見的一些JAVA集合都是線程不安全,這樣作是爲了提升性能
在JDK5之後提供了線程安全的併發包java.util.concurrent併發包,譬如裏面的類CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap等
由於ArrayList的底層是數組實現,而且數組的默認值是10,若是插入10000條要不斷的擴容,耗費時間,因此咱們調用ArrayList的指定容量的構造器方法ArrayList(int size) 就能夠實現不擴容,就提升了性能
網路通信部分
數據交換格式
區別:
xml是重量級、json是輕量級
xml比較佔帶寬、json佔帶寬小,易於壓縮
json在webservice 用的比較少、xml用的較多
相同:
二者都用在項目交互下 例如 移動app接口用的就是json、在web項目中與其餘項目對接用xml較多。
json經常使用解析方法 gson、jsonobject、jackson等 xml dom sax pull 解析
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狀態,完成三次握手。
完成三次握手,客戶端與服務器開始傳送數據。
Webservice就是提供不一樣的平臺相互通信,基於Soap協議。
Web service 就是一個應用程序,它向外界暴露出一個可以經過Web進行調用的API。
SOAP是一種簡單基於xml的輕量協議,用戶web上交換結構化信息和類型信息。
soap請求是HTTP POST的一個專用版本,遵循一種特殊的xml消息格式Content-type設置爲: text/xml任何數據均可以xml化。
HTTP協議+XML
對器客戶端和 服務器端之間數據傳輸的格式規範,格式簡稱爲「超文本傳輸協議」。
一、無狀態協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息
二、無狀態協議解決辦法: 經過一、Cookie 二、經過Session會話保存。
http協議中,返回狀態碼302表示重定向。
這種狀況下,服務器返回的頭部信息中會包含一個 Location 字段,內容是重定向到的url
請求報文包含三部分:
a、請求行:包含請求方法、URI、HTTP版本信息
b、請求首部字段
c、請求內容實體
響應報文包含三部分:
a、狀態行:包含HTTP版本、狀態碼、狀態碼的緣由短語
b、響應首部字段
c、響應內容實體
GET: 用於請求訪問已經被URI(統一資源標識符)識別的資源,能夠經過URL傳參給服務器
POST:用於傳輸信息給服務器,主要功能與GET方法相似,但通常推薦使用POST方式。
PUT: 傳輸文件,報文主體中包含文件內容,保存到對應URI位置。
HEAD: 得到報文首部,與GET方法相似,只是不返回報文主體,通常用於驗證URI是否有效。
DELETE:刪除文件,與PUT方法相反,刪除對應URI位置的文件。
OPTIONS:查詢相應URI支持的HTTP方法。
在http1.0中,當創建鏈接後,客戶端發送一個請求,服務器端返回一個信息後就關閉鏈接,當瀏覽器下次請求的時候又要創建鏈接,顯然這種不斷創建鏈接的方式,會形成不少問題。
5.在http1.1中,引入了持續鏈接的概念,經過這種鏈接,瀏覽器能夠創建一個鏈接以後,發送請求並獲得返回信息,而後繼續發送請求再次等到返回信息,也就是說客戶端能夠連續發送多個請求,而不用等待每個響應的到來。
2.一、整個流程步驟
2.二、域名解析過程
2.三、三次握手過程
2.四、發起HTTP請求
2.五、響應HTTP請求並獲得HTML代碼
2.六、瀏覽器解析HTML代碼
2.七、瀏覽器對頁面進行渲染呈現給用戶
區別一:
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支持標準字符集,能夠正確傳遞中文字符。
請求報文包含三部分:
a、請求行:包含請求方法、URI、HTTP版本信息
b、請求首部字段
c、請求內容實體
響應報文包含三部分:
a、狀態行:包含HTTP版本、狀態碼、狀態碼的緣由短語
b、響應首部字段
c、響應內容實體
200:請求被正常處理
204:請求被受理但沒有資源能夠返回
206:客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法,相應報文中經過Content-Range指定範圍的資源。
301:永久性重定向
302:臨時重定向
303:與302狀態碼有類似功能,只是它但願客戶端在請求一個URI的時候,能經過GET方法重定向到另外一個URI上
304:發送附帶條件的請求時,條件不知足時返回,與重定向無關
307:臨時重定向,與302相似,只是強制要求使用POST方法
400:請求報文語法有誤,服務器沒法識別
401:請求須要認證
403:請求的對應資源禁止被訪問
404:服務器沒法找到對應資源
500:服務器內部錯誤
503:服務器正忙
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:實體主體的位置範圍,通常用於發出部分請求時使用
a、通訊使用明文不加密,內容可能被竊聽,也就是被抓包分析。
b、不驗證通訊方身份,可能遭到假裝
c、沒法驗證報文完整性,可能被篡改
HTTPS就是HTTP加上加密處理(通常是SSL安全通訊線路)+認證+完整性保護
一、支持客戶/服務器模式;二、簡單快速;三、靈活;四、無鏈接;五、無狀態;
若是你還對Http協議不熟悉的話,請參考Http協議http://www.itmayiedu.com/front/articleinfo/49.html文章
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安全.
會出現線程不安全問題。不管是doGet仍是doPost去調用,服務器端處理的過程都是同樣的,那麼咱們能夠把處理過程單獨寫在另一個方法handle裏,讓兩個方法都去調用handle,根據不一樣請求去調用不一樣的方法。
線程安全就是多線程操做同一個對象不會有問題,線程同步通常來保護線程安全,因此能夠在Servlet的線程裏面加上同步方法或同步塊。(Synchronized)能夠保證在同一時間只有一個線程訪問,(使用同步塊會致使性能變差,最好不去使用實例變量)
重定向是客戶端行爲,轉發是服務器端行爲
重定向時服務器產生兩次請求,轉發產生一次請求,重定向時能夠轉發到項目之外的任何網址,轉發只能在當前項目裏轉發
重定向會致使request對象信息丟失。轉發則不會
轉發的url不會變,request.getRequestDispatch()。forward()
重定向的url會改變,response.getRedirect();
jsp的可讀性強,容易維護,而且jsp在最後會編譯成servlet
servlet容易調試
JSP九大內置對象:
pageContext :只對當前jsp頁面有效,裏面封裝了基本的request和session的對象
Request :對當前請求進行封裝
Session :瀏覽器會話對象,瀏覽器範圍內有效
Application :應用程序對象,對整個web工程都有效
Out :頁面打印對象,在jsp頁面打印字符串
Response :返回服務器端信息給用戶
Config :單個servlet的配置對象,至關於servletConfig對象
Page :當前頁面對象,也就是this
Exception :錯誤頁面的exception對象,若是指定的是錯誤頁面,這個就是異常對象
三大指令:
Page :指令是針對當前頁面的指令
Include :用於指定如何包含另外一個頁面
Taglib :用於定義和指定自定義標籤
七大動做:
Forward,執行頁面跳轉,將請求的處理轉發到另外一個頁面
Param :用於傳遞參數
Include :用於動態引入一個jsp頁面
Plugin :用於下載javaBean或applet到客戶端執行
useBean :使用javaBean
setProperty :修改javaBean實例的屬性值
getProperty :獲取javaBean實例的屬性值
request.getParameter() 返回客戶端的請求參數與值
request.getParameterNames() 返回全部可用屬性名的枚舉
request.getParameterValues() 返回包含參數的全部值的數組
一個是服務端,一個是客戶端
Servlet是獨立於平臺和協議的服務器端的java應用程序,能夠動態生成web頁面,並採用響應--請求的模式提供web服務
javaScript是一種解釋性語言,用於向html頁面提供交互行爲,一般被直接嵌入在html頁面中
servlet是java語言編寫的web應用
js是基於html上的一種解釋語言
Cookie,session和application,
Cookie是http對象,客戶端與服務端均可以操縱
cookie是在客戶端保持狀態,session是在服務器端保持狀態,因爲cookie是保存在客戶端本地的,因此數據很容易被竊取,當訪問量不少時,使用session則會下降服務器的性能,application的做用域是整個工程裏只有一個,能夠在不一樣瀏覽器之間共享數據,全部人均可以共享,所以application也是不安全的
Request,out,response , pageContext , session , application , config , page , exception,也即jsp的九大內置對象
Request是客戶端向服務端發送請求
Response是服務端對客戶端請求作出響應
Session在servlet中不能直接使用,須要經過getSession()建立,若是沒有設定它的生命週期,或者經過invildate()方法銷燬,關閉瀏覽器session就會消失
Application不能直接建立,存在於服務器的內存中,由服務器建立和銷燬
Jsp頁面跳轉有兩種方式,forward和redirect(轉發和重定向)
Forward只能在當前項目裏跳轉,只產生一次請求,request保存的變量不會丟失,url地址不會改變
Redirect可跳轉到項目之外的任何頁面,產生兩次請求,request保存的變量會所有丟失,url地址會發生改變,變化爲第二個請求的地址
話跟蹤
Web容器會自動爲servlet寫一個無參的構造器,它使用class.forName("").newInstance()反射來建立servlet實例的
是線程不安全的,由於servlet是單例模式,當多個客戶端共同訪問的時候線程不安全。
儘可能用局部變量,同步塊,若是當前字段是不會改變的,用final修飾
Spring的核心是控制反轉、依賴注入,Aop(面向切面)至關於把每一個bean與bean之間的關係交給第 三方容器進行管理.
SpringIOC ,其實就是依賴注入、控制反轉。至關於把每一個bean與bean之間的關係交給第三方容器管理。而這個容器就是spring
SpringAOP 面向切面的編程,或AOP,是一種編程技術,容許程序模塊化橫向切割關注點,或橫切典型的責任劃分,如日誌和事務管理。 SpringAop 就是用 Javva的動態代理
使用Demo4j(解析XML)+Java反射機制
Demo4j 其實就是解析XML。使用反射機制實例化bean。
JDK動態代理:對實現了接口的類生成代理
CGLib代理機制:對類生成代理
靜態代理:由程序員建立或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。
動態代理:在程序運行時,運用反射機制動態建立而成。
Set注入
構造器注入
靜態工廠的方法注入
實例工廠的方法注入
@Autowired(按類型注入)
@Service(標示爲注入爲服務層)
@Resource(按名稱注入)
@Controller(標識控制器bean id)
@RequestMapping(表示映射URL路徑)
Spring 的優勢??
1.下降了組件之間的耦合性 ,實現了軟件各層之間的解耦
2.可使用容易提供的衆多服務,如事務管理,消息服務等
3.容器提供單例模式支持
4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能
5.容器提供了衆多的輔助類,能加快應用的開發
6.spring對於主流的應用框架提供了集成支持,如hibernate,JPA,Struts等
7.spring屬於低侵入式設計,代碼的污染極低
8.獨立於各類應用服務器
9.spring的DI機制下降了業務對象替換的複雜性
10.Spring的高度開放性,並不強制應用徹底依賴於Spring,開發者能夠自由選擇spring的部分或所有
缺點:
使用到了大量反射機制。反射機制很是佔內存,
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只使用一個Servlet(DispatcherServlet)來處理全部請求?
詳細見J2EE設計模式-前端控制模式
Spring爲何要結合使用HandlerMapping以及HandlerAdapter來處理Handler?
符合面向對象中的單一職責原則,代碼架構清晰,便於維護,最重要的是代碼可複用性高。如HandlerAdapter可能會被用於處理多種Handler。
hibernate是一個基於ORM持久框架,可讓程序員以面向對象的思想操做數據庫,提升生產效率.
orm不過是一種思想,對象關係映射。是對象關係模型,如hibernate,讓你以面向對象的方式去編程。封裝了JDBC.
jdbc只是一個java操做數據庫的規範接口而已
orm不過是一種思想,對象關係映射。
ORM:是對象關係模型,如hibernate,讓你以面向對象的方式去編程。封裝了JDBC.
JDBC:是從底層訪問數據庫服務器。通常銀行,金融行業爲了安全起見,直接用JDBC訪問
load :找不到數據的話會拋出org.hibernate.ObjectNotFoundException異常。此時hibernate會使用延遲加載加載機制
get找不到的話會返回null。
若是查詢不到數據,get 會返回 null,可是不會報錯, load 若是查詢不到數據,則報錯ObjectNotFoundException
使用get 去查詢數據,(先到一級/二級)會當即向db發出查詢請求(select ...), 若是你使用的是 load查詢數據,(先到一級、二級))即便查詢到對象,返回的是一個代理對象,若是後面沒有使用查詢結果,它不會真的向數據庫發select ,當程序員使用查詢結果的時候才真的發出select ,這個現象咱們稱爲懶加載(lazy)
在Hibernate中,對象有三種狀態:臨 時狀態(Transient)、持久狀態(Persistent)和遊離狀態(Detached)。
處於持久態的對象也稱爲 PO(PersistenceObject),臨時對象和遊離對象也稱爲VO(ValueObject).
在Hibernate框架中,當咱們要訪問的數據量過大時,明顯用緩存不太合適, 由於內存容量有限 ,爲了減小併發量,減小系統資源的消耗,這時Hibernate用懶加載機制來彌補這種缺陷,可是這只是彌補而不是用了懶加載整體性能就提升了。
咱們所說的懶加載也被稱爲延遲加載,它在查詢的時候不會馬上訪問數據庫,而是返回代理對象,當真正去使用對象的時候纔會訪問數據庫。
1.使用代理對象:Hibernate.initialize("代理對象");
2.在須要禁用懶加載的映射文件中顯示的加入lazy = "false"
3.使用openSessionInView【須要藉助於過濾器】 須要在web.xml文件中配置
一、 屬性查詢二、 參數查詢、命名參數查詢三、 關聯查詢四、 分頁查詢五、 統計函數
1.Hibernate的優缺點:
優勢:一、程序更加面向對象;
二、提升了生產率;
三、方便移植(修改配置文件);
四、無侵入性。
缺點:
一、效率比JDBC略差;
二、不適合批量操做。
Hibernate緩存包括兩大類:Hibernate一級緩存和Hibernate二級緩存。
1.Hibernate一級緩存又稱爲「Session的緩存」。
Session內置不能被卸載,Session的緩存是事務範圍的緩存(Session對象的生命週期一般對應一個數據庫事務或者一個應用事務)。
一級緩存中,持久化類的每一個實例都具備惟一的OID。
2.Hibernate二級緩存又稱爲「SessionFactory的緩存」。
因爲SessionFactory對象的生命週期和應用程序的整個過程對應,所以Hibernate二級緩存是進程範圍或者集羣範圍的緩存,有可能出現併發問題,所以須要採用適當的併發訪問策略,該策略爲被緩存的數據提供了事務隔離級別。
第二級緩存是可選的,是一個可配置的插件,默認下SessionFactory不會啓用這個插件。
Hibernate提供了org.hibernate.cache.CacheProvider接口,它充當緩存插件與Hibernate之間的適配器。
1) Hibernate2延遲加載實現:a)實體對象 b)集合(Collection)
2) Hibernate3 提供了屬性的延遲加載功能 當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的前生是ibatis,最後升級版本後名稱叫mybatis。mybatis是以純sql操做數據。
Hibernate是面向對象的思想操做數據生成Sql語句,而mybatis是以純sql操做數據
相對於mybatis容易優化.擴展性好,可是移植性差。
設計模式部分
總共有23種設計模式
整體來講設計模式分爲三大類:
建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。
企業面試的時候,面試官很是喜歡考單例,並且很是喜歡考手寫單例。
單例分類:懶漢式單例、餓漢式單例
單例模式有如下特色:
一、單例類只能有一個實例。
二、單例類必須本身建立本身的惟一實例。
三、單例類必須給全部其餘對象提供這一實例。
①懶漢式單例
//懶漢式單例類.在第一次調用的時候實例化本身
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//靜態工廠方法
public static Singleton getInstance () {
if (single == null) {
single = new Singleton();
}
return single;
}
}
②餓漢式單例
//餓漢式單例類.在類初始化時,已經自行實例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//靜態工廠方法
public static Singleton1 getInstance() {
return single;
}
}
從名字上來講,餓漢和懶漢,
餓漢就是類一旦加載,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,
而懶漢比較懶,只有當調用getInstance的時候,纔回去初始化這個單例。
另外從如下兩點再區分如下這兩種方式:
一、線程安全:
餓漢式天生就是線程安全的,能夠直接用於多線程而不會出現問題,
懶漢式自己是非線程安全的,爲了實現線程安全有幾種寫法,分別是上面的一、二、3,這三種實如今資源加載和性能方面有些區別。
二、資源加載和性能:
餓漢式在類建立的同時就實例化一個靜態對象出來,無論以後會不會使用這個單例,都會佔據必定的內存,可是相應的,在第一次調用時速度也會更快,由於其資源已經初始化完成,
而懶漢式顧名思義,會延遲加載,在第一次使用該單例的時候纔會實例化對象出來,第一次調用時要作初始化,若是要作的工做比較多,性能上會有些延遲,以後就和餓漢式同樣了。
項目相關面試題
要重點介紹到①項目是作什麼?②用到那些技術?③整個項目中最大的亮點是?核心部分④遇到bug是怎麼解決的?
例如: 我認爲我作的最好的項目是
創辦了螞蟻課堂it在線教學網站,螞蟻課堂在線教育網站,相似(慕課網、我要自學網)是一家爲IT愛好者提供免費教學服務網站,分爲首頁、課程、博客、問答四大專區,本身也錄製一些Java教學視頻發佈在螞蟻課堂網站上。目前國內各大搜索引擎均可以經過搜索「螞蟻課堂」關鍵字找到螞蟻課堂網站,目前日均PV5000-7000等
使用技術SpringMVC+Mybatis+Spring+Maven,視頻接口才第三方樂視雲接口,使用反向代理nginx+tomcat實現負載均衡及集羣減輕單臺服務器壓力、使用CDN加速提升網絡分發。………
例如:首先遇到了bug,會查詢日誌,經過日誌定位到某個類的行數,判斷是否有代碼問題。
例如我本身項目中,查詢量很是大。經過日誌發現了堆內存溢出,最後經過優化代碼,減輕new和加大堆內存。
項目分配爲:
產品經理(負責提需求)
UI設計師(負責設計樣式文件)
Web前端(只作Web頁面前端靜態文件)
Java工程師(寫業務邏輯)
測試人員(負責測試bug)
非技術項目經理(負責項目管理、人員分配)
項目架構師(負責架構項目)
企業當中項目都是發佈在linux環境上
小公司:使用maven編譯好經過打war包,放入到tomcat的webapps文件下
大公司:使用自動部署系統jenkins jenkins直接關聯svn地址自動打包、自動部署等
Cat 查看某個文件
CP 拷貝
Ls 查看全部列表
Pwd 查看路徑
Tail 查看日誌
Grep 搜索日誌
HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完成了Map接口,主要區別在於HashMap容許空(null)鍵值(key),因爲非線程安全,效率上可能高於Hashtable。
HashMap容許將null做爲一個entry的key或者value,而Hashtable不容許。
HashMap把Hashtable的contains方法去掉了,改爲containsvalue和containsKey。由於contains方法容易讓人引發誤解。
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。
最大的不一樣是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不須要本身爲它的方法實現同步,而HashMap 就必須爲之提供外同步(若是是ArrayList:List lst = Collections.synchronizedList(new ArrayList());若是是HashMap:Map map = Collections.synchronizedMap(new HashMap());)。
Hashtable和HashMap採用的hash/rehash算法都大概同樣,因此性能不會有很大的差別。