整理的java面試題目及相關答案,僅供參考

1.操做系統中 heap stack 的區別javascript

Heap堆和Satck棧是數據結構的兩種,堆主要用來存放對象的,棧主要是用來執行程序的堆是隊列優先,先進先出,棧是先進後出;html

棧用來存儲臨時變量,自動變量,保護現場,CPU會有一個寄存器叫作SP,棧指針,CPU通用寄存器是有限的,不能將每一個操做數都放在寄存器中,那暫時不用的就要放到棧內存,叫入棧,要用時在出棧,計算機常常會正在幹一件事,突然有了另外一件事,那前一件事的數據就不能繼續留在CPU中,作法就是入棧到內存保護現場,等另外一件事昨晚了,在將原來數據返回CPU繼續作;java

堆是預先申請一片內存,可能用到可能用不到,他的生存週期取決於編程者,以申請新的,也能夠隨時扔掉它,編程者使用到的主要的數據都在這裏;git

2.什麼是基於註解的切面實現:程序員

aspect中的註解實現就是用註解定義切面,切點,通常用在實物和日誌記錄中;web

3.什麼是 對象/關係 映射集成模塊:正則表達式

對象關係映射(Object Relational Mapping,簡稱ORM)是經過使用描述對象和數據庫之間映射的元數據,將面嚮對象語言程序中的對象自動持久化到關係數據庫中。本質上就是將數據從一種形式轉換到另一種形式。Spring經過提供ORM模塊在JDBC的基礎上支持對象關係映射工具。這樣的支持使得Spring能夠集成主流的ORM框架,包括Hibernatespring

  1. 什麼是 Java 的反射機制:

是指程序能夠訪問,檢測和修改它自己狀態或行爲的一種能力,經過反射機制訪問java對象的屬性,方法,構造方法等數據庫

優缺點:express

 

優勢:

1、反射提升了程序的靈活性和擴展性。

2、下降耦合性,提升自適應能力。

3、它容許程序建立和控制任何類的對象,無需提早硬編碼目標類。

 

缺點:

1、性能問題:使用反射基本上是一種解釋操做,用於字段和方法接入時要遠慢於直接代碼。所以反射機制主要應用在對靈活性和拓展性要求很高的系統框架上,普通程序不建議使用。

  

二、使用反射會模糊程序內部邏輯;程序員但願在源代碼中看到程序的邏輯,反射卻繞過了源代碼的技術,於是會帶來維護的問題,反射代碼比相應的直接代碼更復雜。

5什麼是 ACID

ACID,指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個支持事務(Transaction)的數據庫,必需要具備這四種特性,不然在事務過程(Transaction processing)當中沒法保證數據的正確性,交易過程很可能達不到交易方的要求

--原子性(Atomic):事務中各項操做,要麼全作要麼全不作,任何一項操做的失敗都會致使整個事務的失敗;

- 一致性(Consistent):事務結束後系統狀態是一致的;

- 隔離性(Isolated):併發執行的事務彼此沒法看到對方的中間狀態;

- 持久性(Durable):事務完成後所作的改動都會被持久化,即便發生災難性的失敗。經過日誌和同步備份能夠在故障發生後重建數據.

6.BSCS的聯繫與區別:

B/S模式是指在TCP/IP的支持下,以HTTP爲傳輸協議,客戶端經過Browser訪問Web服務器以及與之相連的後臺數據庫的技術及體系結構。它由瀏覽器、Web服務器、應用服務器和數據庫服務器組成。客戶端的瀏覽器經過URL訪問Web服務器,Web服務器請求數據庫服務器,並將得到的結果以HTML形式返回客戶端瀏覽器。

c/s在系統機構上和B/S類似,不過須要在客戶端安裝一個客戶端軟件,由這個軟件對服務器的數據進行讀寫,就像咱們經常使用的qq,就是這種模式

  1. Cookie Session的區別:

Cookie數據存放在客戶端,服務器知道其中的數據;Session數據存放在服務器,客戶端不知道其中的數據;

Session存放對象,cookie存放字符串;

Cookie不安全,別人能夠分析存放在cookie進行cookie欺騙;

Session會在一段時間內保存到服務器中,可是當訪問量比較多時,比較佔用資源;

單個cookie保存的數據通常不超過4k,通常瀏覽器限制最多保存20cookie

  1. fail-fast fail-safe 機制有什麼區別:

java.util包下面的全部的集合類都是快速失敗的,而java.util.concurrent包下面的全部的類都是安全失敗的。

fail-fast機制在遍歷一個集合時,當集合結構被修改,會拋出Concurrent Modification Exception

fail-fast會在如下兩種狀況下拋出ConcurrentModificationException

1)單線程環境

集合被建立後,在遍歷它的過程當中修改告終構。

注意 remove()方法會讓expectModcountmodcount 相等,因此是不會拋出這個異常。

2)多線程環境

當一個線程在遍歷這個集合,而另外一個線程對這個集合的結構進行了修改。

fail-safe任何對集合結構的修改都會在一個複製的集合上進行修改,所以不會拋出ConcurrentModificationException

fail-safe機制有兩個問題

1)須要複製集合,產生大量的無效對象,開銷大

2)沒法保證讀取的數據是目前原始數據結構中的數據。

9.get post請求的區別

GET方式:

1GET方式是以實體的方式獲得由請求URL所指定資源的信息,若是請求URL只是一個數據產生過程,那麼最終要在響應實體中返回的是處理過程的結果所指向的資源,而不是處理過程的描述。也就是說,GET的到的信息是資源,而不是資源的處理過程。

2、請的求的數據會附加在URL以後,以?分隔URL和傳輸數據,多個參數用&鏈接。URL編碼格式採用的是ASCII編碼,而不是Unicode,即全部的非ASCII字符都要編碼以後再傳輸。

3、由於URL的長度限制,GET方式傳輸的數據大小有所限制,傳送的數據量不超過2KB

4GET方式服務器端用Request.QueryString獲取變量的值。

5GET方式傳輸的參數安全性低,由於傳輸的數據會顯示在請求的URL中。

POST方式:

1、用來向目的服務器發出請求,要求它接收被附在請求後的實體,並把它當作請求隊列中請求URL所指定資源的附加新子項。

 

2POST方式將表單內各個字段和內容放置在HTML HEADER中一塊兒傳送到Action屬性所指定的URL地址,用戶是看不到這個過程的。

3POST方式傳送的數據量比較大,通常被默認爲沒有限制,可是根據IIS的配置,傳輸量也是不一樣的。

4POST方式在服務器端用Request.Form獲取提交的數據。

5POST方式傳輸的數據安全性較高,由於數據傳輸不是明顯顯示的。

10.Interface abstract 類的區別:

1.abstarct

  • 類中能夠出現abstract方法,也能夠就包含普通方法。(也就是說一旦出現了抽象方法,那這個類一定是抽象類)
  • 不能建立實例對象,就是不能使用new運算符建立類的對象。
  • abstract類的對象能夠成爲子類對象的上轉型對象,能夠調用子類重寫的方法。
  • abstract類是能夠不用有abstract方法的。
  • 若一個抽象類是另外一個抽象類的子類,那麼它能夠重寫父類的抽象類,也能夠直接繼承。

2 interface

  • 接口體中包含常量的聲明(無變量)和抽象方法2部分。
  • 只有抽象方法,沒有普通方法。
  • 常量的訪問權限都是public的,並且都是static常量(容許省略public,final,static修飾符)
  • 全部抽象方法的訪問權限必定都是public的(容許省略public,static修飾符)。
  • 當一個普通類實現了一個接口時,那麼必須重寫這個接口中的全部方法,並且訪問權限只能是
  • public.
  • 接口也有實現權限之分。
  • implements聲明實現這個接口。若父類實現了某個接口,那麼子類也就天然實現了該接口,子類也沒必要再顯示地使用關鍵
  • 接口能夠被繼承,能夠經過關鍵字extends聲明一個接口是另外一個接口的子接口。因爲接口的方法和常量都是public的,子接口講繼父接口的所有方法和常量。
  1. IOC的優勢是什麼:

IOC(Inversion of Control)控制反轉,將控制權(建立對象和對象之間的依賴關係的權利)交給

spring容器;

IOC模式將耦合代碼從程序中移出,放到統一的XML文件中管理。

IOC容器經過配置文件來管理對象的生命週期、依賴關係等,這樣就不用從新修改並編譯具體的代碼,從而實現組件之間的解耦

IOC的優勢:實現組件之間的解耦,提升程序的靈活性和可維護性。

  1. IO NIO的區別,NIO優勢:

IO是面向流的,NIO是面向緩衝區的

Java IO的各類流是阻塞的,這意味着,當一個線程調用read() write()時,該線程被阻塞,直到有一些數據被讀取,或數據徹底寫入。該線程在此期間不能再幹任何事情了。

Java NIO的非阻塞模式,,使一個線程從某通道發送請求讀取數據,可是它僅能獲得目前可用的數據,若是目前沒有數據可用時,就什麼都不會獲取,而不是保持線程阻塞,因此直至數據變的能夠讀取以前,該線程能夠繼續作其餘的事情。 非阻塞寫也是如此。一個線程請求寫入一些數據到某通道,但不須要等待它徹底寫入,這個線程同時能夠去作別的事情。 線程一般將非阻塞IO的空閒時間用於在其它通道上執行IO操做,因此一個單獨的線程如今能夠管理多個輸入和輸出通道(channel

 Java NIO的選擇器容許一個單獨的線程來監視多個輸入通道

13.Java 8 / Java 7 爲咱們提供了什麼新功能:

1.jdk7語法上:

1.1二進制變量的表示,支持將整數類型用二進制來表示,用0b開頭。

1.2  Switch語句支持string類型

3.1.能夠使用try-with-resources自動關閉Connection, ResultSet, 和 Statement資源對象

14.什麼是競態條件? 舉個例子說明。

當兩個線程競爭同一資源時,若是對資源的訪問順序敏感,就稱存在競態條件。

致使競態條件發生的代碼區稱做臨界區。

 

在臨界區中使用適當的同步就能夠避免競態條件。

臨界區實現方法有兩種,一種是用synchronized,一種是用Lock顯式鎖實現。

class Counter {

    protected long count = 0;

    public void add(long value) {

        this.count = this.count + value;

    }

}

 觀察線程A和B交錯執行會發生什麼,兩個線程分別加了2和3到count變量上,兩個線程執行結束後count變量的值應該等於5。然而因爲兩個線程是交叉執行的,兩個線程從內存中讀出的初始值都是0。而後各自加了2和3,並分別寫回內存。最終的值並非指望的5,而是最後寫回內存的那個線程的值,上面例子中最後寫回內存的是線程A,但實際中也多是線程B。若是沒有采用合適的同步機制,線程間的交叉執行狀況就沒法預料。

add()方法就是一個臨界區,它會產生競態條件。

  1. JRE、JDK、JVM 及 JIT 之間有什麼不一樣

java虛擬機(JVM)

    使用java編程語言的主要優點就是平臺的獨立性。你曾經想知道過java怎麼實現平臺的獨立性嗎?對,就是虛擬機,它抽象化了硬件設備,開發者和他們的程序的得以操做系統。虛擬機的職責就是處理和操做系統的交流。java不一樣的接口規範對任何平臺都有良好的支持,由於jvm很好的實現了每一個平臺的規範。jvm能夠理解僞代碼字節碼,在用戶和操做系統之間創建了一層樞紐。

 

java運行時環境(JRE)

    java運行時環境是JVM的一個超集。JVM對於一個平臺或者操做系統是明確的,而JRE確實一個通常的概念,他表明了完整的運行時環境。咱們在jre文件夾中看到的全部的jar文件和可執行文件都會變成運行時的一部分。事實上,運行時JRE變成了JVM。因此對於通常狀況時候使用JRE,對於明確的操做系統來講使用JVM。當你下載了JRE的時候,也就自動下載了JVM。

 

java開發工具箱(JDK)

    java開發工具箱指的是編寫一個java應用所須要的全部jar文件和可執行文件。事實上,JRE是JDK的一部分。若是你下載了JDK,你會看到一個名叫JRE的文件夾在裏面。JDK中要被牢記的jar文件就是tools.jar,它包含了用於執行java文檔的類還有用於類簽名的jar包。

 

即時編譯器(JIT)

即時編譯器是種特殊的編譯器,它經過有效的把字節碼變成機器碼來提升JVM的效率。JIT這種功效很特殊,由於他把檢測到的類似的字節碼編譯成單一運行的機器碼,從而節省了CPU的使用。這和其餘的字節碼編譯器不一樣,由於他是運行時(第一類執行的編譯?)the firs of its kind to perform the compilation(從字節碼到機器碼)而不是在程序運行以前。正是由於這些,動態編譯這個詞彙才和JIT有那麼緊密的關係

  1. MVC的各個部分都有那些技術來實現?如何實現?

MVC 是 Model-View-Controller 的簡寫。 Model 表明的是應用的業務邏輯( 經過

JavaBean, EJB 組件實現), View 是應用的表示面( 由 JSP 頁面產生), Controller 是提供應用的處理過程控制( 通常是一個 Servlet), 經過這種設計模型把應用邏輯, 處理過程和顯示邏輯分紅不一樣的組件實現。 這些組件能夠進行交互和重用。

  1. RPC 通訊和 RMI 區別

1. RPC 不支持對象, 採用http協議

2. RMI支持傳輸對象。採用tcp/ip 協議

3. RMI只限於JAVA語言,RPC跨語言

18.什麼是 Web Service(Web服務):

WebService是一種跨編程語言和跨操做系統平臺的遠程調用技術。

謂跨編程語言和跨操做平臺,就是說服務端程序採用java編寫,客戶端程序則能夠採用其餘編程語言編寫,反之亦然!跨操做系統平臺則是指服務端程序和客戶端程序能夠在不一樣的操做系統上運行。

所謂遠程調用,就是一臺計算機a上的一個程序能夠調用到另一臺計算機b上的一個對象的方法,譬如,銀聯提供給商場的pos刷卡系統,商場的POS機轉帳調用的轉帳方法的代碼實際上是跑在銀行服務器上。再好比,amazon,天氣預報系統,淘寶網,校內網,百度等把本身的系統服務以webservice服務的形式暴露出來,讓第三方網站和程序能夠調用這些服務功能,這樣擴展了本身系統的市場佔有率,往大的概念上吹,就是所謂的SOA應用。

19.WEB容器主要有哪些功能? 並請列出一些常見的WEB容器名字。.

Web容器給處於其中的應用程序組件(JSP,SERVLET)提供一個環境,使JSP,SERVLET直接跟容器中的環境變量交互,沒必要關注其它系統問題。主要有WEB服務器來實現。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。  

常見的有容器  Apache, IIS, Tomcat, Resin 等等

  1. 一個」.java」源文件中是否能夠包含多個類(不是內部類)?有什麼限制

這個是能夠的,一個「.java」源文件裏面能夠包含多個類,可是隻容許有一個public類,而且類名必須和文件名一致。

每一個編譯單元只能有一個public 類。這麼作的意思是,每一個編譯單元只能有一個公開的接口,而這個接口就由其public 類來表示。

你能夠根據須要,往這個文件裏面添加任意多個提供輔助功能的package 權限的類。可是若是這個編譯單元裏面有兩個或兩個以上的public 類的話,程序就不知道從哪裏導入了,編譯器就會報錯。

  1. 簡單說說你瞭解的類加載器。是否實現過類加載器

虛擬機設計團隊把類加載階段中「經過一個類的全限定名來獲取描述此類的二進制字節流」這個動做放到Java虛擬機外部去實現,以便讓應用程序本身決定如何去獲取所須要的類。實現這個動做的模塊稱爲「類加載器」。

  1. 解釋一下什麼叫AOP(面向切面編程)

在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。

  1. 請簡述 Servlet 的生命週期及其相關的方法

Servlet 生命週期:Servlet 加載--->實例化--->服務--->銷燬。

init():在Servlet的生命週期中,僅執行一次init()方法。它是在服務器裝入Servlet時執行的,負責初始化Servlet對象。能夠配置服務器,以在啓動服務器或客戶機首次訪問Servlet時裝入Servlet。不管有多少客戶機訪問Servlet,都不會重複執行init()。

service():它是Servlet的核心,負責響應客戶的請求。每當一個客戶請求一個HttpServlet對象,該對象的Service()方法就要調用,並且傳遞給這個方法一個「請求」(ServletRequest)對象和一個「響應」(ServletResponse)對象做爲參數。在HttpServlet中已存在Service()方法。默認的服務功能是調用與HTTP請求的方法相應的do功能。

destroy(): 僅執行一次,在服務器端中止且卸載Servlet時執行該方法。當Servlet對象退出生命週期時,負責釋放佔用的資源。一個Servlet在運行service()方法時可能會產生其餘的線程,所以須要確認在調用destroy()方法時,這些線程已經終止或完成。

  1. 請簡述一下 Ajax 的原理及實現步驟

Ajax的原理簡單來講經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用javascript來操做DOM而更新頁面。

一、建立XMLHttpRequest對象(須要考慮各瀏覽器兼容的問題)

二、使用XMLHttpRequest對象打開一個鏈接(指定鏈接方式<post/get>和鏈接地址以及是否同步);調用XMLHttpRequest對象的open方法。第一個參數是提交數據的方式,取值爲post/get;第二個參數是提交的目標頁面(也就是用於處理提交數據的頁面);第三個參數指定是否請求是異步的-缺省值爲true,爲了發送一個同步請求,須要把這個參數設置爲false。

三、設置請求的頭部(請求的類型和請求的編碼格式)

四、設置回調函數

主要用於處理從服務端發送給客戶端的數據,主要使用javascript去調用頁面中的元素,並根據服務端返回的結果去控制頁面中元素的更新。內部實現其實是javascript中的事件處理機制。

五、發送請求:調用XMLHttpRequest對象的send方法實現數據的發送。

六、更新頁面顯示

25.簡單描述Struts的主要功能

連接:https://www.cnblogs.com/god-1949-keshi/p/7124277.html

struts2的目的就是把請求和顯示的結果分開,而不是單純的運行一個jsp頁面

攔截器能夠說至關因而個過濾器:就是把 不想要的或不想顯示的內容給過濾掉。攔截器能夠抽象出一部分代碼能夠用來完善原來的action。同時能夠減輕代碼冗餘,提升重用率。

好比在登入一個頁面時,若是要求用戶密碼、權限等的驗證,就能夠用自定義的攔截器進行密碼驗證和權限限制。對符合的登入者才跳轉到正確頁面。這樣若是有新增權限的話,不用在action裏修改任何代碼,直接在interceptor裏修改就好了

26.什麼是Java虛擬機?爲何Java被稱做是「平臺無關的編程語言」

1、什麼是java虛擬機?

java虛擬機是執行字節碼文件(.class)的虛擬機進程。

java源程序(.java)被編譯器編譯成字節碼文件(.class)。而後字節碼文件,將由java虛擬機,解釋成機器碼(不一樣平臺的機器碼不一樣)。利用機器碼操做硬件和操做系統

 

2、爲何java被稱爲平臺無關的編程語言?

由於不一樣的平臺裝有不一樣的JVM,它們可以將相同的.class文件,解釋成不一樣平臺所須要的機器碼。正是由於有JVM的存在,java被稱爲平臺無關的編程語言

  1. 什麼是正則表達式?用途是什麼?哪一個包使用正則表達式來實現模式匹配

簡單的說就是,用一小段簡單的各類字符的組合,即叫作 正則表達式,去實現複雜的:

字符串匹配,查找你到你所須要的內容,以便後期提取出來你所要的內容;

java.util.regex

  1. 什麼是懶加載(Lazy Loading)

懶加載就是何時使用何時開闢空間,不用的時候只是一個指針不佔用內存,當使用的時候爲其alloc/init,這時候才佔用內存.只要不使用就永遠不會真正生成,不會佔用空間.

29什麼是尾遞歸,爲何須要尾遞歸

尾遞歸是指全部遞歸形式的調用,必定是發生在函數的末尾。形式上只要最後一個return語句是單純函數就能夠。

尾遞歸和通常的遞歸不一樣在對內存的佔用,普通遞歸建立stack累積然後計算收縮,尾遞歸只會佔用恆量的內存(和迭代同樣)

30.什麼是控制反轉(Inversion of Control)與依賴注入(Dependency Injection

IoCInversion of Control,控制反轉)。這是spring的核心,貫穿始終。所謂IoC,對於spring框架來講,就是由spring來負責控制對象的生命週期和對象間的關係。

這是什麼意思呢,舉個簡單的例子,咱們是如何找女友的?常見的狀況是,咱們處處去看哪裏有長得漂亮身材又好的mm,而後打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,而後嘿嘿……這個過程是複雜深奧的,咱們必須本身設計和麪對每一個環節。傳統的程序開發也是如此,在一個對象中,若是要使用另外的對象,就必須獲得它(本身new一個,或者從JNDI中查詢一個),使用完以後還要將對象銷燬(好比Connection等),對象始終會和其餘的接口或類藕合起來。

那麼IoC是如何作的呢?有點像經過婚介找女友,在我和女友之間引入了一個第三者:婚姻介紹所。婚介管理了不少男男女女的資料,我能夠向婚介提出一個列表,告訴它我想找個什麼樣的女友,好比長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,而後婚介就會按照咱們的要求,提供一個mm,咱們只須要去和她談戀愛、結婚就好了。簡單明瞭,若是婚介給咱們的人選不符合要求,咱們就會拋出異常。整個過程再也不由我本身控制,而是有婚介這樣一個相似容器的機構來控制。

 

關鍵字

 

finalize

 

什麼是finalize()方法

finalize()方法何時被調用

答:finalize()Objectprotected方法,子類能夠覆蓋該方法以實現資源清理工做,GC在回收對象以前調用該方法。

主要的用途是回收特殊渠道申請的內存。Java程序有垃圾回收器,因此通常狀況下內存問題不用程序員操心。但有一種JNI(Java Native Interface)調用non-Java程序(CC++),finalize()的工做就是回收這部分的內存。

 

final finalize 的區別

final關鍵字有哪些用法

final, finally, finalize的區別

finalfinalize finally 的不一樣之處?

一個類被聲明爲final類型,表示了什麼意思

 

答:

Final

final關鍵字能夠用於類,方法,變量前,用來表示該關鍵字修飾的類,方法,變量具備不可變的特性。

1final關鍵字用於基本數據類型前:這時代表該關鍵字修飾的變量是一個常量,在定義後該變量的值就不能被修改。

2final關鍵字用於方法聲明前:這時意味着該方法時最終方法,只能被調用,不能被覆蓋,可是能夠被重載。

3final關鍵字用於類名前:此時該類被稱爲最終類,該類不能被其餘類繼承。

Finalize

finalize方法來自於java.lang.Object,用於回收資源。

能夠爲任何一個類添加finalize方法。finalize方法將在垃圾回收器清除對象以前調用。

在實際應用中,不要依賴使用該方法回收任何短缺的資源,這是由於很難知道這個方法何時被調用。

Finally

當代碼拋出一個異常時,就會終止方法中剩餘代碼的處理,並退出這個方法的執行。假如咱們打開了一個文件,但在處理文件過程當中發生異常,這時文件尚未被關閉,此時就會產生資源回收問題。對此,java提供了一種好的解決方案,那就是finally子句,finally子句中的語句是必定會被執行的,因此咱們只要把前面說的文件關閉的語句放在finally子句中不管在讀寫文件中是否遇到異常退出,文件關閉語句都會執行,保證了資源的合理回收。

 

 

final static 關鍵字能夠用於哪裏?它們的做用是什麼

1static方法

  static方法通常稱做靜態方法,因爲靜態方法不依賴於任何對象就能夠進行訪問,所以對於靜態方法來講,是沒有this的,由於它不依附於任何對象,既然都沒有對象,就談不上this了。而且因爲這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,由於非靜態成員方法/變量都是必須依賴具體的對象纔可以被調用。

2static變量

  static變量也稱做靜態變量,靜態變量和非靜態變量的區別是:靜態變量被全部的對象所共享,在內存中只有一個副本,它當且僅當在類初次加載時會被初始化。而非靜態變量是對象所擁有的,在建立對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。

  static成員變量的初始化順序按照定義的順序進行初始化。

3static代碼塊

  static關鍵字還有一個比較關鍵的做用就是 用來造成靜態代碼塊以優化程序性能。static塊能夠置於類中的任何地方,類中能夠有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每一個static塊,而且只會執行一次

 

可否在運行時向 static final 類型的賦值

答:final static 變量就只能在定義的時候就初始化,不然既沒法在構造方法中初始化,系統又不會賦默認值,至關於這個變量被定義出來是毫無用處的。  所以javafinal static變量必須初始化。

 

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

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

throws, throw, try, catch, finally分別表明什麼意義

答:throws是獲取異常

throw是拋出異常

try是將會發生異常的語句括起來,從而進行異常的處理,

catch是若是有異常就會執行他裏面的語句,

finally不管是否有異常都會進行執行的語句。

throws是用來聲明一個方法可能拋出的全部異常信息,而throw則是指拋出的一個具體的異常類型。此外throws是將異常聲明可是不處理,而是將異常往上傳,誰調用我就交給誰處理;

1throws出如今方法函數頭;而throw出如今函數體。

2throws表示出現異常的一種可能性,並不必定會發生這些異常;throw則是拋出了異常,執行throw則必定拋出了某種異常。

3、二者都是消極處理異常的方式(這裏的消極並非說這種方式很差),只是拋出或者可能拋出異常,可是不會由函數去處理異常,真正的處理異常由函數的上層調用處理。

Java 有幾種修飾符?分別用來修飾什麼

答:

方法的修飾符有兩類:

1.訪問控制修飾符(public,private,protected,package)

2.方法自己修飾符(static,final,abstract,native,synchronized)

類的修飾符:

1.前綴修飾符(public,abstract,final)

2.後綴修飾符(extends,implements)

 

 

volatile

 

volatile 修飾符的有過什麼實踐

答:

一種實踐是用 volatile 修飾 long double 變量,使其能按原子類型來讀寫。double long 都是64位寬,所以對這兩種類型的讀是分爲兩部分的,第一次讀取第一個 32 位,而後再讀剩下的 32 位,這個過程不是原子的,但 Java volatile 型的 long double 變量的讀寫是原子的。volatile 修復符的另外一個做用是提供內存屏障(memory barrier),例如在分佈式框架中的應用。簡單的說,就是當你寫一個 volatile 變量以前,Java 內存模型會插入一個寫屏障(write barrier),讀一個 volatile 變量以前,會插入一個讀屏障(read barrier)。意思就是說,在你寫一個 volatile 域時,能保證任何線程都能看到你寫的值,同時,在寫以前,也能保證任何數值的更新對全部線程是可見的,由於內存屏障會將其餘全部寫的值更新到緩存。

volatile 變量是什麼?volatile 變量和 atomic 變量有什麼不一樣

答:volatile就是告訴程序,該變量是易變的,不穩定的,每次必須去主存讀取,而不要從本身的緩存中獲取副本

volatile 類型變量提供什麼保證?能使得一個非原子操做變成原子操做嗎

答:一個典型的例子是在類中有一個 long 類型的成員變量。若是你知道該成員變量會被多個線程訪問,如計數器、價格等,你最好是將其設置爲 volatile。爲何?由於 Java 中讀取 long 類型變量不是原子的,須要分紅兩步,若是一個線程正在修改該 long 變量的值,另外一個線程可能只能看到該值的一半(前 32 位)。可是對一個 volatile 型的 long double 變量的讀寫是原子。

能建立 volatile 數組嗎?

答:能,Java 中能夠建立 volatile 類型數組,不過只是一個指向數組的引用,而不是整個數組。個人意思是,若是改變引用指向的數組,將會受到 volatile 的保護,可是若是多個線程同時改變數組的元素,volatile 標示符就不能起到以前的保護做用了。

 

transient變量有什麼特色

答:transient是類型修飾符,只能用來修飾字段。在對象序列化的過程當中,標記爲transient的變量不會被序列化。

super何時使用

答:若是父類的構造函數是無參的,那子類構造函數會在第一行默認調用super().

說明一下public static void main(String args[])這段聲明裏每一個關鍵字的做用

答:

public: main方法是Java程序運行時調用的第一個方法,所以它必須對Java環境可見。因此可見性設置爲public.

static: Java平臺調用這個方法時不會建立這個類的一個實例,所以這個方法必須聲明爲static

void: main方法沒有返回值。

String:是命令行傳進參數的類型,args:是指命令行傳進的字符串數組。

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

答:private修飾的成員變量和函數只能在類自己和內部類中被訪問。

protected 修飾的成員變量和函數能被類自己、子類及同一個包中的類訪問。

public修飾的成員變量和函數能夠被類、子類、同一個包中的類以及任意其餘類訪問。

默認狀況(不寫)下,屬於一種包訪問,即能被類自己以及同一個包中的類訪問。

 

 

 

 

 

 

 

 

下面這個表能清楚的說明java中做用域操做符的做用:

 做用域       當前類    同一package      子孫類     其餘package
  public            √                √                   √                √

  protected      √                √                    √                ×

  friendly         √                 √                    ×                ×

  private          √                 ×                    ×                ×

                    

sizeof Java 的關鍵字嗎

static

 

static class non static class的區別

答:若是把類比喻成雞蛋,內部類爲蛋黃,外部類是蛋殼。那麼靜態類至關於熟雞蛋,就算蛋殼破碎(外部類沒有實例化),蛋黃依然無缺(內部類能夠實例化);而非靜態類至關於生雞蛋,蛋殼破碎(無實例化),蛋黃也會跟着xx(不能實例化)。

靜態類型有什麼特色static 關鍵字是什麼意思?

方便在沒有建立對象的狀況下來進行調用(方法/變量)。

main() 方法爲何必須是靜態的?能不能聲明 main() 方法爲非靜態

答:Main方法做爲程序的入口方法,在這以前是不可能有任何對象被創建的,也就在Main以前包括Main自身不多是非靜態方法。因此Main方法必定是靜態的

是否能夠從一個靜態(static)方法內部發出對非靜態(non-static)方法的調用

不能夠。由於非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,

 *    才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠

 *    直接調用。也就是說,當一個static方法被調用時,可能尚未建立任何實例

 *    對象,若是從一個static方法中發出對非static方法的調用,那個非static

 *    方法是關聯到哪一個對象上的呢?這個邏輯沒法成立,因此,一個static方法內部

 *    發出對非static方法的調用

靜態變量在何時加載?編譯期仍是運行期?靜態代碼塊加載的時機呢

靜態變量是在類加載的時候分配空間的

成員方法是否能夠訪問靜態變量?爲何靜態方法不能訪問成員變量

 

switch

 

switch 語句中的表達式能夠是什麼類型數據

switch(expression)中,expression只能是一個整數表達式或者枚舉常量,整數表達式能夠是int類型或Integer包裝類型。因爲,byteshortchar均可以隱式轉換爲int類型,因此,這些類型也能夠用做表達式。

另外jdk7之後,switch表達式也能夠爲String類型,

switch 是否能做用在byte 上,是否能做用在long 上,是否能做用在String

 switch可做用於char byte short int

 * switch可做用於char byte short int對應的包裝類

 * switch不可做用於long double float boolean,包括他們的包裝類

 * switch中能夠是字符串類型,String(jdk1.7以後才能夠做用在string)

 * switch中能夠是枚舉類型

 

 

操做符

 

&操做符和&&操做符有什麼區別?

&:表示普通與,全部的判斷條件都要依次執行;

&&:若干個條件,若是前面的條件返回false,那麼後面再也不判斷,就是false;

|:表示普通h或,全部的判斷條件都要依次執行;

||:若干個條件,若是前面的條件返回true,那麼後面再也不判斷,就是true;

位運算:&表示位與運算,|表示位或計算

 

a = a + b 與 a += b 的區別?

一、對於一樣類型的a,b來講

兩個式子執行的結果確實沒有什麼區別。可是從編譯的角度看吧(武讓說的),a+=b;執行的時候效率高。

二、對於不一樣類型的a,b來講

    2.1    不一樣類型的兩個變量在進行運算的時候,咱們常常說到的是類型的轉換問題。這裏,記住兩點:1、運算過程當中,低精度的類型向高精度類型轉換。2、若是將高精度的數值賦值給低精度類型變量,則必需要進行顯性的強制轉換。

     2.2    對於a+=b;這個式子,要明確的一點是,+=運算中,結合了強制類型轉換的功能,所以,不會出現編譯錯誤;而對於a=a+b;這個式子,由於是簡單的運算,沒有類型轉換,在編譯過程當中會報錯,

 

邏輯操做符 (&,|,^)與條件操做符(&&,||)的區別

a.條件操做只能操做布爾型的,而邏輯操做不只能夠操做布爾型,並且能夠操做數值型

b.邏輯操做不會產生短路.

 

3*0.1 == 0.3 將會返回什麼?true 仍是 false?

false,由於有些浮點數不能徹底精確的表示出來。

 

float f=3.4; 是否正確?

緣由:精度不許確,應該用強制類型轉換,以下所示:float f=(float)3.4 或float f = 3.4f

 

short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?

對於short s1 = 1; s1 = s1 + 1; 因爲s1+1運算時會自動提高表達式的類型,因此結果是int型,再賦值給short類型s1時,編譯器將報告須要強制轉換類型的錯誤。對於short s1 = 1; s1 += 1;因爲 += 是java語言規定的運算符,java編譯器會對它進行特殊處理,所以能夠正確編譯。

 

 

 

數據結構

 

基礎類型(Primitives)

 

基礎類型(Primitives)與封裝類型(Wrappers)的區別在哪裏?

1.基本類型只能按值傳遞,而每一個基本類型對應的封裝類是按引用傳遞的。

2.從性能上說java中的基本類型是在堆棧上建立的,而全部的對象類型都是在堆上建立的,(對象的引用在堆棧上建立)。

3.封裝類的出現,是爲了更方便的使用一些基本類型不具有的方法,好比valueOf(),toString()等等。

4.若是想傳遞一個int對象的引用,而不是值,那隻能用封裝類。

5.基本數據能夠自動封裝成封裝類,基本數據類型的好處就是速度快(不涉及到對象的構造和回收),封裝類的目的主要是更好的處理數據之間的轉換,方法不少,用起來也方便。

 

注意:

[在堆棧上分配內存的調用效率和在堆上分配內存的效率差太多了。雖然在堆棧上分配內存效率高,不過在堆棧上分配內存有內存泄露的問題。]

簡述九種基本數據類型的大小,以及他們的封裝類

float和double的默認值是多少?

 

基本類型

大小(字節)

默認值

封裝類

byte

1

(byte)0

Byte

short

2

(short)0

Short

int

4

0

Integer

long

8

0L

Long

float

4

0.0f

Float

double

8

0.0d

Double

boolean

-

false

Boolean

char

2

\u0000(null)

Character

void

-

-

Void

 

 

 

int 和 Integer 哪一個會佔用更多的內存?

Integer 對象會佔用更多的內存。Integer 是一個對象,須要存儲對象的元數據。

 

 

可是 int 是一個原始類型的數據,因此佔用的空間更少。

 

int 和 Integer 有什麼區別?

一、Integer是int的包裝類,int則是java的一種基本數據類型

二、Integer變量必須實例化後才能使用,而int變量不須要

三、Integer實際是對象的引用,當new一個Integer時,其實是生成一個指針指向此對象;而int則是直接存儲數據值

四、Integer的默認值是null,int的默認值是0

 

parseInt()函數在何時使用到?

parseInt() 函數可解析一個字符串,並返回一個整數。

轉換函數:把字符串轉換爲整數。

默認狀況下,以字符串形式存儲。

 

如何去小數四捨五入保留小數點後兩位

import java.math.BigDecimal;

import java.text.DecimalFormat;

import java.text.NumberFormat;

public class format {

    double f = 111231.5585;

    public void m1() {

        BigDecimal bg = new BigDecimal(f);

        double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

        System.out.println(f1);

    }

    /**

     * DecimalFormat轉換最簡便

     */

    public void m2() {

        DecimalFormat df = new DecimalFormat("#.00");

        System.out.println(df.format(f));

    }

    /**

     * String.format打印最簡便

     */

    public void m3() {

        System.out.println(String.format("%.2f", f));

    }

    public void m4() {

        NumberFormat nf = NumberFormat.getNumberInstance();

        nf.setMaximumFractionDigits(2);

        System.out.println(nf.format(f));

    }

    public static void main(String[] args) {

        format f = new format();

        f.m1();

        f.m2();

        f.m3();

        f.m4();

    }

}

 

 

結果:

111231.56

111231.56

111231.56

111,231.56

 

char 型變量中能不能存貯一箇中文漢字,爲何

char型變量是用來存儲Unicode編碼的字符的,unicode編碼字符集中包含了漢字,

 * 因此,char型變量中固然能夠存儲漢字啦。不過,若是某個特殊的漢字沒有被包含在

 * unicode編碼字符集中,那麼,這個char型變量中就不能存儲這個特殊漢字。補充

 * 說明:unicode編碼佔用兩個字節,因此,char類型的變量也是佔用兩個字節

 

類型轉換

 

怎樣將 bytes 轉換爲 long 類型

怎麼將 byte 轉換爲 String

byte[] srtbyte;

String res = new String(srtbyte);

System.out.println(res);

 

如何將數值型字符轉換爲數字

使用對象包裝類,如Integer.parseInt("1234")

 

咱們能將 int 強制轉換爲 byte 類型的變量嗎?若是該值大於 byte 類型的範圍,將會出現什麼現象?

  由於Java中byte是用8位來存儲,只能表示-128~127之間的數,當由int強制類型轉化爲byte時,系統就採起了截取int後8位的作法。

 

能在不進行強制轉換的狀況下將一個 double 值賦值給 long 類型的變量嗎

java double轉long型是取整運算;

 

 

數組

 

如何權衡是使用無序的數組仍是有序的數組

有序數組最大的好處:在於查找的時間複雜度是O(log n),而無序數組是O(n)。

有序數組的缺點是:插入操做的時間複雜度是O(n),由於值大的元素須要日後移動來給新元素騰位置。相反,無序數組的插入時間複雜度是常量O(1)。

 

怎麼判斷數組是 null 仍是爲空

int b[]=null;

int a[] = new int [10];

System.out.println("a數組的長度:"+a.length);

System.out.println("b數組的長度:"+b.length);//會空指針異常;

 

Array 和 ArrayList有什麼區別?何時應該使用Array而不是ArrayList

存儲內容比較:

Array數組能夠包含基本類型和對象類型,

ArrayList卻只能包含對象類型。

可是須要注意的是:Array數組在存放的時候必定是同種類型的元素。ArrayList就不必定了,由於ArrayList能夠存儲Object。

 

 

空間大小比較:

它的空間大小是固定的,空間不夠時也不能再次申請,因此須要事前肯定合適的空間大小。

ArrayList的空間是動態增加的,若是空間不夠,它會建立一個空間比原空間大一倍的新數組,而後將全部元素複製到新數組中,接着拋棄舊數組。並且,每次添加新的元素的時候都會檢查內部數組的空間是否足夠。(比較麻煩的地方)。

 

方法上的比較:

ArrayList做爲Array的加強版,固然是在方法上比Array更多樣化,好比添加所有addAll()、刪除所有removeAll()、返回迭代器iterator()等。

適用場景:

若是想要保存一些在整個程序運行期間都會存在並且不變的數據,咱們能夠將它們放進一個全局數組裏,可是若是咱們單純只是想要以數組的形式保存數據,而不對數據進行增長等操做,只是方便咱們進行查找的話,那麼,咱們就選擇ArrayList。並且還有一個地方是必須知道的,就是若是咱們須要對元素進行頻繁的移動或刪除,或者是處理的是超大量的數據,那麼,使用ArrayList就真的不是一個好的選擇,由於它的效率很低,使用數組進行這樣的動做就很麻煩,那麼,咱們能夠考慮選擇LinkedList。

 

數組和鏈表數據結構描述,各自的時間複雜度?

一、存取方式上,數組能夠順序存取或者隨機存取,而鏈表只能順序存取; 

二、存儲位置上,數組邏輯上相鄰的元素在物理存儲位置上也相鄰,而鏈表不必定; 

三、存儲空間上,鏈表因爲帶有指針域,存儲密度不如數組大; 

四、按序號查找時,數組能夠隨機訪問,時間複雜度爲O(1),而鏈表不支持隨機訪問,平均須要O(n); 

五、按值查找時,若數組無序,數組和鏈表時間複雜度均爲O(1),可是當數組有序時,能夠採用折半查找將時間複雜度降爲O(logn); 

六、插入和刪除時,數組平均須要移動n/2個元素,而鏈表只需修改指針便可; 

七、空間分配方面: 
  數組在靜態存儲分配情形下,存儲元素數量受限制,動態存儲分配情形下,雖然存儲空間能夠擴充,但須要移動大量元素,致使操做效率下降,並且若是內存中沒有更大塊連續存儲空間將致使分配失敗; 
  鏈表存儲的節點空間只在須要的時候申請分配,只要內存中有空間就能夠分配,操做比較靈活高效

 

 

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

數組中沒有length()這個方法,可是數組中有length這個屬性。用來表示數組的長度。

String中有length()這個方法。用來獲得字符串的長度。

 

隊列

 

隊列和棧是什麼,列出它們的區別

隊列先進先出,棧先進後出。

棧(Stack)是限定只能在表的一端進行插入和刪除操做的線性表。

隊列(Queue)是限定只能在表的一端進行插入和在另外一端進行刪除操做的線性表。

 

ArrayList、Vector、LinkedList的存儲性能和特性

1.ArrayList 採用的是數組形式來保存對象的,這種方式將對象放在連續的位置中,因此最大的缺點就是插入刪除時很是麻煩.

2.LinkedList 採用的將對象存放在獨立的空間中,並且在每一個空間中還保存下一個連接的索引 可是缺點就是查找很是麻煩 要叢第一個索引開始

3.ArrayList和Vector都是用數組方式存儲數據,此數組元素數要大於實際的存儲空間以便進行元素增長和插入操做,他們都容許直接用序號索引元素,可是插入數據元素涉及到元素移動等內存操做,因此索引數據快而插入數據慢.

4.Vector使用了sychronized方法(線程安全),因此在性能上比ArrayList要差些.

5.LinkedList使用雙向鏈表方式存儲數據,按序號索引數據須要前向或後向遍歷數據,因此索引數據慢,是插入數據時只須要記錄先後項便可,因此插入的速度快.

6.arraylist和vector的區別?

1).同步性:Vector是線程安全的,也就是說是同步的,而ArrayList是線程不安全的,不是同步的

2).數據增加:當須要增加時,Vector默認增加爲原來一培,而ArrayList倒是原來的一半

3).Vector不能有種復的值,ArrayList則可有重複的值。

 

 

 

String

StringBuffer

StringBuilder

  1. 三者在執行速度方面的比較:StringBuilder >  StringBuffer  >  String
  2. StringBuilder:線程非安全的
  3. StringBuffer:線程安全的
  4. 若是要操做少許的數據用 = String
  5. 單線程操做字符串緩衝區 下操做大量數據 = StringBuilder
  6. 多線程操做字符串緩衝區 下操做大量數據 = StringBuffer

 

HashMap

 

HashMap的工做原理是什麼?

經過hash的方法,經過putget存儲和獲取對象。存儲對象時,咱們將K/V傳給put方法時,它調用hashCode計算hash從而獲得bucket位置,進一步存儲,HashMap會根據當前bucket的佔用狀況自動調整容量(超過Load Facotrresize爲原來的2)。獲取對象時,咱們將K傳給get,它調用hashCode計算hash從而獲得bucket位置,並進一步調用equals()方法肯定鍵值對。若是發生碰撞的時候,Hashmap經過鏈表將產生碰撞衝突的元素組織起來,在Java 8中,若是一個bucket中碰撞衝突的元素超過某個限制(默認是8),則使用紅黑樹來替換鏈表,從而提升速度。

 

HashMap、LinkedMap、TreeMap的區別

A:HashMap 參考其餘問題;

LinkedHashMap 保存了記錄的插入順序,在用 Iterator 遍歷時,先取到的記錄確定是先插入的;遍歷比 HashMap 慢;

TreeMap 實現 SortMap 接口,可以把它保存的記錄根據鍵排序(默認按鍵值升序排序,也能夠指定排序的比較器)

 

Set

 

Set 裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用 == 仍是 equals()? 它們有何區別?

 

一、什麼是Set?(what)

     Set是Collection容器的一個子接口,它不容許出現重複元素,固然也只容許有一個null對象。

 

二、如何來區分重複與否呢?(how)

 

     「 用 iterator() 方法來區分重複與否 」,這是在網上流傳的答案,我的認爲這是個錯誤的答案。API中寫的很明白:「set 不包含知足

e1.equals(e2) 的元素對 e1 和 e2 」,因而可知回答使用equals()區分更合適。

 

三、爲何用equals()而不用==來區分?(why)

 

     應該從它倆的區別談起,==是用來判斷二者是不是同一對象(同一事物),而equals是用來判斷是否引用同一個對象。再看一下Set裏面存的是

對象,仍是對象的引用。根據java的存儲機制可知,set裏面存放的是對象的引用,因此當兩個元素只要知足了equals()時就已經指向同一個對象,

也就出現了重複元素。因此應該用equals()來判斷。

 

List

 

List, Set, Map三個接口,存取元素時各有什麼特色?

List與Set都是單列元素的集合,它們有一個功共同的父接口Collection。

Set裏面不容許有重複的元素,

存元素:add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true;當集合含有與某個元素equals相等的元素時,此時add方法沒法加入該元素,返回結果爲false。

取元素:無法說取第幾個,只能以Iterator接口取得全部的元素,再逐一遍歷各個元素。

 

List表示有前後順序的集合,

存元素:屢次調用add(Object)方法時,每次加入的對象按先來後到的順序排序,也能夠插隊,即調用add(int index,Object)方法,就能夠指定當前對象在集合中的存放位置。

取元素:方法1:Iterator接口取得全部,逐一遍歷各個元素

 

        方法2:調用get(index i)來明確說明取第幾個。

 

Map是雙列的集合,存放用put方法:put(obj key,obj value),每次存儲時,要存儲一對key/value,不能存儲重複的key,這個重複的規則也是按equals比較相等。

取元素:用get(Object key)方法根據key得到相應的value。

 

        也能夠得到全部的key的集合,還能夠得到全部的value的集合,

 

        還能夠得到key和value組合成的Map.Entry對象的集合。

List以特定次序來持有元素,可有重複元素。Set 沒法擁有重複元素,內部排序。Map 保存key-value值,value可多值。

 

List, Set, Map 是否繼承自 Collection 接口

遍歷一個 List 有哪些不一樣的方式

List遍歷方式:

第一種:

for(Iterator iterator = list.iterator();iterator.hasNext();){                    

    int i = (Integer) iterator.next();                   

    System.out.println(i);               

}

第二種:

Iterator iterator = list.iterator();

while(iterator.hasNext()){

    int i = (Integer) iterator.next();

    System.out.println(i);

}

第三種:

for (Object object : list) {

    System.out.println(object);

}

第四種:

for(int i = 0 ;i<list.size();i++) {  

    int j= (Integer) list.get(i);

    System.out.println(j);  

}

 

LinkedList

 

LinkedList 是單向鏈表仍是雙向鏈表

雙向鏈表

LinkedList 與 ArrayList 有什麼區別

 1.ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。

 2.對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針。

 3.對於新增和刪除操做add和remove,LinedList比較佔優點,由於ArrayList要移動數據

描述下 Java 中集合(Collections),接口(Interfaces),實現(Implementations)的概念。

插入數據時,ArrayList, LinkedList, Vector誰速度較快?

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

 

ArrayList

 

ArrayList 和 HashMap 的默認大小是多數?

List 元素是有序的、可重複

 

ArrayList、Vector默認初始容量爲10

 

Vector:線程安全,但速度慢

 

    底層數據結構是數組結構

 

    加載因子爲1:即當 元素個數 超過 容量長度 時,進行擴容

 

    擴容增量:原容量的 1倍

 

      如 Vector的容量爲10,一次擴容後是容量爲20

 

ArrayList:線程不安全,查詢速度快

 

    底層數據結構是數組結構

 

    擴容增量:原容量的 0.5倍+1

 

      如 ArrayList的容量爲10,一次擴容後是容量爲16

 

 

 

Set(集) 元素無序的、不可重複。

 

HashSet:線程不安全,存取速度快

 

     底層實現是一個HashMap(保存數據),實現Set接口

 

     默認初始容量爲16(爲什麼是16,見下方對HashMap的描述)

 

     加載因子爲0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容

 

     擴容增量:原容量的 1 倍

 

      如 HashSet的容量爲16,一次擴容後是容量爲32

 

 

 

Map是一個雙列集合

 

HashMap:默認初始容量爲16

 

     (爲什麼是16:16是2^4,能夠提升查詢效率,另外,32=16<<1       -->至於詳細的緣由可另行分析,或分析源代碼)

 

     加載因子爲0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容

 

     擴容增量:原容量的 1 倍

 

      如 HashSet的容量爲16,一次擴容後是容量爲32

相關文章
相關標籤/搜索