java工程師面試題_第1頁
java工程師面試題_第2頁
java工程師面試題_第3頁
java工程師面試題_第4頁
java工程師面試題_第5頁
已閱讀5頁,還剩23頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、1 . struts1 和 struts2區(qū)別:Struts2 從本質(zhì)上講已不是從 Struts1 擴展而來的, 說它是一個換了品牌標簽的 WebWork 更合適。從 Struts1 升級到 Struts2:Struts1 里使用 ActionServlet 作為控制器; Struts2 使用了一個過濾器作為控制器Struts1 中每個 HTML 表單都對應(yīng)一個 ActionForm 實例. Struts2 中, HTML 表單將被直接映射到一個 POJO.Struts1 的驗證邏輯編寫在 ActionForm 中; Struts2 中的驗證邏輯編寫在 Action 中.Struts1 中,

2、Action 類必須繼承類; Struts2 中任何一個 POJO 都可以是一個 Action 類. Struts2 在頁面里使用 OGNL 來顯示各種對象模型, 可以不再使用 EL 和 JSTLPS:POJO(Plain Ordinary Java Object)簡單的Java對象,實際就是普通JavaBeans2. struts1的缺陷: 1).單元測試困難: HttpServletRequest和HttpServletResponse是由Servlet容器負責實例化的,因此Acton類的測試就要依賴于Web容器,單元測試很難實現(xiàn)。當然,也可以使用第三方的測試工具-JUnit的擴展工具St

3、rutsTestCase來對Action進行單元測試,但是測試相對來說比較困難這是不爭的事實! 2) Action是單例模式并且必須是線程安全的 因為僅有Action的一個實例來處理求。單例策略限制了Struts1Action能作的事,并且要在開發(fā)時特別小心。Action資源必須是線程安全的或同步的。 3).對Servlet的依賴性太大 4). Struts1使用ActionForm對象捕獲輸入 所有的ActionForm必須繼承一個基類。因為其他JavaBean不能用作ActionForm,開發(fā)者經(jīng)常創(chuàng)建多余的類捕獲輸入。動態(tài)Bean(DynaBeans)可以作為創(chuàng)建傳統(tǒng)ActionForm

4、的選擇,但是,開發(fā)者可能是在重新描述(創(chuàng)建)已經(jīng)存在的JavaBean(仍然會導(dǎo)致有冗余的javabean) 5)每配置一下 struts-config,須重新啟動tomcat,而且配置煩所,頁面轉(zhuǎn)向過多,導(dǎo)致forword配置過多使得 struts-config文件內(nèi)容過多,尋找東西比較困難 6)到了struts3.0的時候,發(fā)現(xiàn)建一個action就必須要有相應(yīng)的actionform與之對應(yīng)。導(dǎo)致沒必要有actionform的action都要建立actionform。要不然web頁面是提交不到action的。3. 分布式存儲集群文件系統(tǒng)是指運行在多臺計算機之上,之間通過某種方式相互通信從而將

5、集群內(nèi)所有存儲空間資源整合、虛擬化并對外提供文件訪問服務(wù)的文件系統(tǒng)。其與NTFS、EXT等本地文件系統(tǒng)的目的不同,前者是為了擴展性,后者運行在單機環(huán)境,純粹管理塊和文件之間的映射以及文件屬性。集群文件系統(tǒng)分為多類,按照對存儲空間的訪問方式,可分為共享存儲型集群文件系統(tǒng)和分布式集群文件系統(tǒng),前者是多臺計算機識別到同樣的存儲空間,并相互協(xié)調(diào)共同管理其上的文件,又被稱為共享文件系統(tǒng);后者則是每臺計算機各自提供自己的存儲空間,并各自協(xié)調(diào)管理所有計算機節(jié)點中的文件。Veritas的VxFS/VCS,昆騰Stornext,中科藍鯨BWFS,EMC的MPFS,屬于共享存儲型集群文件系統(tǒng)。而HDFS、Glus

6、ter、Ceph、Swift等互聯(lián)網(wǎng)常用的大規(guī)模集群文件系統(tǒng)無一例外都屬于分布式集群文件系統(tǒng)。分布式集群文件系統(tǒng)可擴展性更強,目前已知最大可擴展至10K節(jié)點。按照元數(shù)據(jù)的管理方式,可分為對稱式集群文件系統(tǒng)和非對稱式集群文件系統(tǒng)。前者每個節(jié)點的角色均等,共同管理文件元數(shù)據(jù),節(jié)點間通過高速網(wǎng)絡(luò)進行信息同步和互斥鎖等操作,典型代表是Veritas的VCS。而非對稱式集群文件系統(tǒng)中,有專門的一個或者多個節(jié)點負責管理元數(shù)據(jù),其他節(jié)點需要頻繁與元數(shù)據(jù)節(jié)點通信以獲取最新的元數(shù)據(jù)比如目錄列表文件屬性等等,后者典型代表比如HDFS、GFS、BWFS、Stornext等。對于集群文件系統(tǒng),其可以是分布式+對稱式、

7、分布式+非對稱式、共享式+對稱式、共享式+非對稱式,兩兩任意組合。按照文件訪問方式來分類,集群文件系統(tǒng)可分為串行訪問式和并行訪問式,后者又被俗稱為并行文件系統(tǒng)。串行訪問是指客戶端只能從集群中的某個節(jié)點來訪問集群內(nèi)的文件資源,而并行訪問則是指客戶端可以直接從集群中任意一個或者多個節(jié)點同時收發(fā)數(shù)據(jù),做到并行數(shù)據(jù)存取,加快速度。HDFS、GFS、pNFS等集群文件系統(tǒng),都支持并行訪問,需要安裝專用客戶端,傳統(tǒng)的NFS/CIFS客戶端不支持并行訪問。對于分布式集群,其對文件元數(shù)據(jù)的管理方式又可以分為single path image和single filesystem image兩種方式,具體可以參考

8、大話存儲終極版中對集群文件系統(tǒng)的描述。以上總結(jié)于大話存儲終極版4. JVM底層結(jié)構(gòu)Java虛擬機(Java Virtual Machine) 簡稱JVM Java虛擬機是一個想象中的機器,在實際的計算機上通過軟件模擬來實現(xiàn)。Java虛擬機有自己想象中的硬件,如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。下面我們就來看一下這幾部分比較重要的java虛擬機的結(jié)構(gòu)JVM寄存器所有的CPU均包含用于保存系統(tǒng)狀態(tài)和處理器所需信息的寄存器組。如果虛擬機定義義較多的寄存器,便可以從中得到更多的信息而不必對棧或內(nèi)存進行訪問,這有利于提高運行速度。然而,如果虛擬機中的寄存器比實際CPU的寄存器多,在實現(xiàn)虛擬機

9、時就會占用處理器大量的時間來用常規(guī)存儲器模擬寄存器,這反而會降低虛擬機的效率。針對這種情況,JVM只設(shè)置了4個最為常用的寄存器。它們是:pc程序計數(shù)器,optop操作數(shù)棧頂指針 ,frame當前執(zhí)行環(huán)境指針, vars指向當前執(zhí)行環(huán)境中第一個局部變量的指針, 所有寄存器均為32位。pc用于記錄程序的執(zhí)行。optop,frame和vars用于記錄指向Java棧區(qū)的指針。JVM棧結(jié)構(gòu)作為基于棧結(jié)構(gòu)的計算機,Java棧是JVM存儲信息的主要方法。當JVM得到一個java字節(jié)碼應(yīng)用程序后,便為該代碼中一個類的每一個方法創(chuàng)建一個??蚣埽员4嬖摲椒ǖ臓顟B(tài)信息。每個??蚣馨ㄒ韵氯愋畔ⅲ壕植孔兞繄?zhí)行環(huán)境

10、操作數(shù)棧 局部變量用于存儲一個類的方法中所用到的局部變量。vars寄存器指向該變量表中的第一個局部變量。執(zhí)行環(huán)境用于保存解釋器對Java字節(jié)碼進行解釋過程中所需的信息。它們是:上次調(diào)用的方法、局部變量指針和操作數(shù)棧的棧頂和棧底指針。執(zhí)行環(huán)境是一個執(zhí)行一個方法的控制中心。例如:如果解釋器要執(zhí)行iadd(整數(shù)加法),首先要從frame寄存器中找到當前執(zhí)行環(huán)境,而后便從執(zhí)行環(huán)境中找到操作數(shù)棧,從棧頂彈出兩個整數(shù)進行加法運算,最后將結(jié)果壓入棧頂。操作數(shù)棧用于存儲運算所需操作數(shù)及運算的結(jié)果。JVM碎片回收堆Java類的實例所需的存儲空間是在堆上分配的。解釋器具體承擔為類實例分配空間的工作。解釋器在為一個

11、實例分配完存儲空間后,便開始記錄對該實例所占用的內(nèi)存區(qū)域的使用。一旦對象使用完畢,便將其回收到堆中。在Java語言中,除了new語句外沒有其他方法為一對象申請和釋放內(nèi)存。對內(nèi)存進行釋放和回收的工作是由Java運行系統(tǒng)承擔的。這允許Java運行系統(tǒng)的設(shè)計者自己決定碎片回收的方法。在SUN公司開發(fā)的Java解釋器和Hot Java環(huán)境中,碎片回收用后臺線程的方式來執(zhí)行。這不但為運行系統(tǒng)提供了良好的性能,而且使程序設(shè)計人員擺脫了自己控制內(nèi)存使用的風(fēng)險。JVM存儲區(qū)JVM有兩類存儲區(qū):常量緩沖池和方法區(qū)。常量緩沖池用于存儲類名稱、方法和字段名稱以及串常量。方法區(qū)則用于存儲Java方法的字節(jié)碼。對于這兩

12、種存儲區(qū)域具體實現(xiàn)方式在JVM規(guī)格中沒有明確規(guī)定。這使得Java應(yīng)用程序的存儲布局必須在運行過程中確定,依賴于具體平臺的實現(xiàn)方式。JVM是為Java字節(jié)碼定義的一種獨立于具體平臺的規(guī)格描述,是Java平臺獨立性的基礎(chǔ)。目前的JVM還存在一些限制和不足,有待于進一步的完善,但無論如何,JVM的思想是成功的。對比分析:如果把Java原程序想象成我們的C+原程序,Java原程序編譯后生成的字節(jié)碼就相當于C+原程序編譯后的80x86的機器碼(二進制程序文件),JVM虛擬機相當于80x86計算機系統(tǒng),Java解釋器相當于80x86CPU。在80x86CPU上運行的是機器碼,在Java解釋器上運行的是Ja

13、va字節(jié)碼。Java解釋器相當于運行Java字節(jié)碼的“CPU”,但該“CPU”不是通過硬件實現(xiàn)的,而是用軟件實現(xiàn)的。Java解釋器實際上就是特定的平臺下的一個應(yīng)用程序。只要實現(xiàn)了特定平臺下的解釋器程序,Java字節(jié)碼就能通過解釋器程序在該平臺下運行,這是Java跨平臺的根本。當前,并不是在所有的平臺下都有相應(yīng)Java解釋器程序,這也是Java并不能在所有的平臺下都能運行的原因,它只能在已實現(xiàn)了Java解釋器程序的平臺下運行。Java虛擬機從啟動到結(jié)束的生命周期,當java虛擬機啟動后,在如下幾種情況下,Java虛擬機將結(jié)束生命周期:1.執(zhí)行了System.exit()方法 2.程序正常執(zhí)行結(jié)束

14、 3.程序在執(zhí)行過程中遇到了異常或錯誤而異常終止4.由于操作系統(tǒng)出現(xiàn)錯誤而導(dǎo)致Java虛擬機進程終止 Java虛擬機的棧有三個區(qū)域:局部變量區(qū)、運行環(huán)境區(qū)、操作數(shù)區(qū)。局部變量區(qū)每個Java方法使用一個固定大小的局部變量集。它們按照與vars寄存器的字偏移量來尋址。局部變量都是32位的。長整數(shù)和雙精度浮點數(shù)占據(jù)了兩個局部變量的空間,卻按照第一個局部變量的索引來尋址。(例如,一個具有索引n的局部變量,如果是一個雙精度浮點數(shù),那么它實際占據(jù)了索引n和n+1所代表的存儲空間)虛擬機規(guī)范并不要求在局部變量中的64位的值是64位對齊的。虛擬機提供了把局部變量中的值裝載到操作數(shù)棧的指令,也提供了把操作數(shù)棧中

15、的值寫入局部變量的指令。運行環(huán)境區(qū)在運行環(huán)境中包含的信息用于動態(tài)鏈接,正常的方法返回以及異常捕捉。操作數(shù)棧區(qū)機器指令只從操作數(shù)棧中取操作數(shù),對它們進行操作,并把結(jié)果返回到棧中。選擇棧結(jié)構(gòu)的原因是:在只有少量寄存器或非通用寄存器的機器(如Intel486)上,也能夠高效地模擬虛擬機的行為。操作數(shù)棧是32位的。它用于給方法傳遞參數(shù),并從方法接收結(jié)果,也用于支持操作的參數(shù),并保存操作的結(jié)果。例如,iadd指令將兩個整數(shù)相加。相加的兩個整數(shù)應(yīng)該是操作數(shù)棧頂?shù)膬蓚€字。這兩個字是由先前的指令壓進堆棧的。這兩個整數(shù)將從堆棧彈出、相加,并把結(jié)果壓回到操作數(shù)棧中。每個原始數(shù)據(jù)類型都有專門的指令對它們進行必須的操

16、作。每個操作數(shù)在棧中需要一個存儲位置,除了long和double型,它們需要兩個位置。操作數(shù)只能被適用于其類型的操作符所操作。例如,壓入兩個int類型的數(shù),如果把它們當作是一個long類型的數(shù)則是非法的。在Sun的虛擬機實現(xiàn)中,這個限制由字節(jié)碼驗證器強制實行。但是,有少數(shù)操作(操作符dupe和swap),用于對運行時數(shù)據(jù)區(qū)進行操作時是不考慮類型的。本地方法棧,當一個線程調(diào)用本地方法時,它就不再受到虛擬機關(guān)于結(jié)構(gòu)和安全限制方面的約束,它既可以訪問虛擬機的運行期數(shù)據(jù)區(qū),也可以使用本地處理器以及任何類型的棧。例如,本地棧是一個C語言的棧,那么當C程序調(diào)用C函數(shù)時,函數(shù)的參數(shù)以某種順序被壓入棧,結(jié)果則

17、返回給調(diào)用函數(shù)。在實現(xiàn)Java虛擬機時,本地方法接口使用的是C語言的模型棧,那么它的本地方法棧的調(diào)度與使用則完全與C語言的棧相同。 Java虛擬機的運行過程:上面對虛擬機的各個部分進行了比較詳細的說明,下面通過一個具體的例子來分析它的運行過程。虛擬機通過調(diào)用某個指定類的方法main啟動,傳遞給main一個字符串數(shù)組參數(shù),使指定的類被裝載,同時鏈接該類所使用的其它的類型,并且初始化它們。例如對于程序:class HelloApp public static void main(String args) "Hello World!"); for (int i = 0; i &l

18、t; args.length; i+ ) argsi); 編譯后在命令行模式下鍵入: java HelloApp run virtual machine將通過調(diào)用HelloApp的方法main來啟動java虛擬機,傳遞給main一個包含三個字符串"run"、"virtual"、"machine"的數(shù)組。現(xiàn)在我們略述虛擬機在執(zhí)行HelloApp時可能采取的步驟。 開始試圖執(zhí)行類HelloApp的main方法,發(fā)現(xiàn)該類并沒有被裝載,也就是說虛擬機當前不包含該類的二進制代表,于是虛擬機使用ClassLoader試圖尋找這樣的二進制代表。如果

19、這個進程失敗,則拋出一個異常。類被裝載后同時在main方法被調(diào)用之前,必須對類HelloApp與其它類型進行鏈接然后初始化。鏈接包含三個階段:檢驗,準備和解析。檢驗檢查被裝載的主類的符號和語義,準備則創(chuàng)建類或接口的靜態(tài)域以及把這些域初始化為標準的默認值,解析負責檢查主類對其它類或接口的符號引用,在這一步它是可選的。類的初始化是對類中聲明的靜態(tài)初始化函數(shù)和靜態(tài)域的初始化構(gòu)造方法的執(zhí)行。一個類在初始化之前它的父類必須被初始化。整個過程如下:5. 面向?qū)ο蟮娜筇卣?、五大基本原則:三大特性是:封裝,繼承,多態(tài) 所謂封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象

20、操作,對不可信的進行信息隱藏。封裝是面向?qū)ο蟮奶卣髦?,是對象和類概念的主要特性?簡單的說,一個類就是一個封裝了數(shù)據(jù)以及操作這些數(shù)據(jù)的代碼的邏輯實體。在一個對象內(nèi)部,某些代碼或某些數(shù)據(jù)可以是私有的,不能被外界訪問。通過這種方式,對象對內(nèi)部數(shù)據(jù)提供了不同級別的保護,以防止程序中無關(guān)的部分意外的改變或錯誤的使用了對象的私有部分。所謂繼承是指可以讓某個類型的對象獲得另一個類型的對象的屬性的方法。它支持按級分類的概念。繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。 通過繼承創(chuàng)建的新類稱為“子類”或“派生類”,被繼承的類稱為“基類”、“父類”或“

21、超類”。繼承的過程,就是從一般到特殊的過程。要實現(xiàn)繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來實現(xiàn)。繼承概念的實現(xiàn)方式有二類:實現(xiàn)繼承與接口繼承。實現(xiàn)繼承是指直接使用基類的屬性和方法而無需額外編碼的能力;接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實現(xiàn)的能力;所謂多態(tài)就是指一個類實例的相同方法在不同情形有不同表現(xiàn)形式。多態(tài)機制使具有不同內(nèi)部結(jié)構(gòu)的對象可以共享相同的外部接口。這意味著,雖然針對不同對象的具體操作不同,但通過一個公共的類,它們(那些操作)可以通過相同的方式予以調(diào)用。五大基本原則 單一職責原則SRP(Single Responsibi

22、lity Principle):指一個類的功能要單一,不能包羅萬象。如同一個人一樣,分配的工作不能太多,否則一天到晚雖然忙忙碌碌的,但效率卻高不起來。開放封閉原則OCP(OpenClose Principle) :一個模塊在擴展性方面應(yīng)該是開放的而在更改性方面應(yīng)該是封閉的。比如:一個網(wǎng)絡(luò)模塊,原來只服務(wù)端功能,而現(xiàn)在要加入客戶端功能,那么應(yīng)當在不用修改服務(wù)端功能代碼的前提下,就能夠增加客戶端功能的實現(xiàn)代碼,這要求在設(shè)計之初,就應(yīng)當將服務(wù)端和客戶端分開,公共部分抽象出來。替換原則(the Liskov Substitution Principle LSP) :子類應(yīng)當可以替換父類并出現(xiàn)在父類能夠

23、出現(xiàn)的任何地方。比如:公司搞年度晚會,所有員工可以參加抽獎,那么不管是老員工還是新員工,也不管是總部員工還是外派員工,都應(yīng)當可以參加抽獎,否則這公司就不和諧了。依賴原則(the Dependency Inversion Principle DIP): 具體依賴抽象,上層依賴下層。假設(shè)B是較A低的模塊,但B需要使用到A的功能,這個時候,B不應(yīng)當直接使用A中的具體類: 而應(yīng)當由B定義一抽象接口,并由A來實現(xiàn)這個抽象接口,B只使用這個抽象接口:這樣就達到了依賴倒置的目的,B也解除了對A的依賴,反過來是A依賴于B定義的抽象接口。通過上層模塊難以避免依賴下層模塊,假如B也直接依賴A的實現(xiàn),那么就可能造成

24、循環(huán)依賴。一個常見的問題就是編譯A模塊時需要直接包含到B模塊的cpp文件,而編譯B時同樣要直接包含到A的cpp文件。接口分離原則(the Interface Segregation Principle ISP) :模塊間要通過抽象接口隔離開,而不是通過具體的類強耦合起來6、String、StringBuilder與StringBuffer的區(qū)別(1)可變與不可變:String類中使用字符數(shù)組保存字符串,如下就是,因為有“final”修飾符,所以可以知道string對象是不可變的。private final char value;StringBuilder與StringBuffer都繼承自Abs

25、tractStringBuilder類,在AbstractStringBuilder中也是使用字符數(shù)組保存字符串,如下就是,可知這兩種對象都是可變的。char value;(2).是否多線程安全String中的對象是不可變的,也就可以理解為常量,顯然線程安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對方法加了同步鎖或者對調(diào)用的方法加了同步鎖,所以是線程安全的??慈缦略创a:復(fù)制代碼 publi

26、c synchronized StringBuffer reverse() super.reverse(); return this; public int indexOf(String str) return indexOf(str, 0); /存在 public synchronized int indexOf(String str, int fromIndex) 方法 StringBuilder并沒有對方法進行加同步鎖,所以是非線程安全的。 (3)StringBuilder與StringBuffer共同點StringBuilder與StringBuffer有公共父類AbstractStr

27、ingBuilder(抽象類)。抽象類與接口的其中一個區(qū)別是:抽象類中可以定義一些子類的公共方法,子類只需要增加新的功能,不需要重復(fù)寫已經(jīng)存在的方法;而接口中只是對方法的申明和常量的定義。StringBuilder、StringBuffer的方法都會調(diào)用AbstractStringBuilder中的公共方法,如super.append(.)。只是StringBuffer會在方法上加synchronized關(guān)鍵字,進行同步。最后,如果程序不是多線程的,那么使用StringBuilder效率高于StringBuffer。7. Map 集合(1)什么是Java集合API:Java集合框架API是用來

28、表示和操作集合的統(tǒng)一框架,它包含接口、實現(xiàn)類、以及幫助程序員完成一些編程的算法。簡言之,API在上層完成以下幾件事: 編程更加省力,提高城程序速度和代碼質(zhì)量非關(guān)聯(lián)的API提高互操作性 節(jié)省學(xué)習(xí)使用新API成本 節(jié)省設(shè)計新API的時間 鼓勵、促進軟件重用具體來說,有6個集合接口,最基本的是Collection接口,由三個接口Set、List、SortedSet繼承,另外兩個接口是Map、SortedMap,這兩個接口不繼承Collection,表示映射而不是真正的集合。(2) 什么是Iterator一些集合類提供了內(nèi)容遍歷的功能,通過接口。這些接口允許遍歷對象的集合。依次操作每個元素對象。當使用

29、 Iterators時,在獲得Iterator的時候包含一個集合快照。通常在遍歷一個Iterator的時候不建議修改集合本省。(3)、Iterator與ListIterator有什么區(qū)別?Iterator:只能正向遍歷集合,適用于獲取移除元素。ListIerator:繼承Iterator,可以雙向列表的遍歷,同樣支持元素的修改。(4) 什么是HaspMap和Map?Map是接口,Java 集合框架中一部分,用于存儲鍵值對,HashMap是用哈希算法實現(xiàn)Map的類。(5)、HashMap與HashTable有什么區(qū)別?對比Hashtable VS HashMap兩者都是用key-value方式獲

30、取數(shù)據(jù)。Hashtable是原始集合類之一(也稱作遺留類)。HashMap作為新集合框架的一部分在Java2的1.2版本中加入。它們之間有一下區(qū)別:HashMap和Hashtable大致是等同的,除了非同步和空值(HashMap允許null值作為key和value,而Hashtable不可以)。 HashMap沒法保證映射的順序一直不變,但是作為HashMap的子類LinkedHashMap,如果想要預(yù)知的順序迭代(默認按照插入順序),你可以很輕易的置換為HashMap,如果使用Hashtable就沒那么容易了。 HashMap不是同步的,而Hashtable是同步的。 迭代HashMap采用

31、快速失敗機制,而Hashtable不是,所以這是設(shè)計的考慮點。(6)、在Hashtable上下文中同步是什么意思?同步意味著在一個時間點只能有一個線程可以修改哈希表,任何線程在執(zhí)行hashtable的更新操作前需要獲取對象鎖,其他線程等待鎖的釋放。(7)、什么叫做快速失敗特性從高級別層次來說快速失敗是一個系統(tǒng)或軟件對于其故障做出的響應(yīng)。一個快速失敗系統(tǒng)設(shè)計用來即時報告可能會導(dǎo)致失敗的任何故障情況,它通常用來停止正常的操作而不是嘗試繼續(xù)做可能有缺陷的工作。當有問題發(fā)生時,快速失敗系統(tǒng)即時可見地發(fā)錯錯誤告警。在Java中,快速失敗與iterators有關(guān)。如果一個iterator在集合對象上創(chuàng)建了

32、,其它線程欲“結(jié)構(gòu)化”的修改該集合對象,并發(fā)修改異常 (ConcurrentModificationException) 拋出。(8)、怎樣使Hashmap同步?HashMap可以通過Map m = Collections.synchronizedMap(hashMap)來達到同步的效果。(9)、什么時候使用Hashtable,什么時候使用HashMap基本的不同點是Hashtable同步HashMap不是的,所以無論什么時候有多個線程訪問相同實例的可能時,就應(yīng)該使用Hashtable,反之使用HashMap。非線程安全的數(shù)據(jù)結(jié)構(gòu)能帶來更好的性能。如果在將來有一種可能你需要按順序獲得鍵值對的方

33、案時,HashMap是一個很好的選擇,因為有HashMap的一個子類 LinkedHashMap。所以如果你想可預(yù)測的按順序迭代(默認按插入的順序),你可以很方便用LinkedHashMap替換HashMap。反觀要是使用的Hashtable就沒那么簡單了。同時如果有多個線程訪問HashMap,Collections.synchronizedMap()可以代替,總的來說HashMap更靈活。(10)、為什么Vector類認為是廢棄的或者是非官方地不推薦使用?或者說為什么我們應(yīng)該一直使用ArrayList而不是Vector你應(yīng)該使用ArrayList而不是Vector是因為默認情況下你是非同步訪

34、問的,Vector同步了每個方法,你幾乎從不要那樣做,通常有想要同步的是整個操作序列。同步單個的操作也不安全(如果你迭代一個Vector,你還是要加鎖,以避免其它線程在同一時刻改變集合).而且效率更慢。當然同樣有鎖的開銷即使你不需要,這是個很糟糕的方法在默認情況下同步訪問。你可以一直使用Collections.sychronizedList來裝飾一個集合。事實上Vector結(jié)合了“可變數(shù)組”的集合和同步每個操作的實現(xiàn)。這是另外一個設(shè)計上的缺陷。Vector還有些遺留的方法在枚舉和元素獲取的方法,這些方法不同于List接口,如果這些方法在代碼中程序員更趨向于想用它。盡管枚舉速度更快,但是他們不能

35、檢查如果集合在迭代的時候修改了,這樣將導(dǎo)致問題。盡管以上諸多原因,oracle也從沒宣稱過要廢棄Vector。8、Socket通信過程:10、查詢、插入、刪除等幾種情況,分別選用ArrayList、LinkList、Vector哪一個合適?ArrayList底層使用的是數(shù)組數(shù)據(jù)結(jié)構(gòu),因為數(shù)組有索引(角標)所以ArrayList的查詢速度快,而添加刪除元素速度稍慢。因為,你每刪除或者添加一個元素,你都要移動所添加或刪除元素后面的所有數(shù)據(jù),該集合是線程不同步的LinkedList底層使用的是鏈表數(shù)據(jù)結(jié)構(gòu),鏈表數(shù)據(jù)結(jié)構(gòu)是沒有索引的,當前元素只和他的前一個和后一個元素有關(guān)聯(lián)就像一串珠子一樣,該數(shù)據(jù)結(jié)構(gòu)

36、的特點是,增加刪除快,而查詢比較慢,因為增加刪除只需要找到當前元素,然后斷掉當前元素與它前一個和后一個元素的關(guān)聯(lián)即可,和數(shù)組比,鏈表不用重復(fù)大部分的數(shù)據(jù)移動工作,但是因為沒有索引所以鏈表數(shù)據(jù)結(jié)構(gòu)要一個一個的查詢數(shù)據(jù),所以LinkedList的查詢速度稍慢Vector:底層使用的是數(shù)組數(shù)據(jù)結(jié)構(gòu),和ArrayList的功能相當,但是Vector是線程同步的,JDK已經(jīng)對Vector的底層源碼中可能出現(xiàn)同步的操作加上了同步鎖,但是線程同步之后有弊端,那就是每當操作Vector集合,都會去判斷同步鎖,較為浪費系統(tǒng)資源。而我們完全可以使用ArrayList來代替Vector,如果需要同步代碼,我們也可以

37、自己手動加上同步鎖11. Java訪問數(shù)據(jù)庫的過程?JDBC連接數(shù)據(jù)庫 創(chuàng)建一個以JDBC連接數(shù)據(jù)庫的程序,包含7個步驟: (1)、加載JDBC驅(qū)動程序: 在連接數(shù)據(jù)庫之前,首先要加載想要連接的數(shù)據(jù)庫的驅(qū)動到JVM(Java虛擬機), 這通過類的靜態(tài)方法forName(String className)實現(xiàn)。 例如: try /加載MySql的驅(qū)動類 Class.forName( catch(ClassNotFoundException e) 找不到驅(qū)動程序類 ,加載驅(qū)動失??!"); e.printStackTrace() ; 成功加載后,會將Driver類的實例注冊到DriverM

38、anager類中。 (2)、提供JDBC連接的URL 連接URL定義了連接數(shù)據(jù)庫時的協(xié)議、子協(xié)議、數(shù)據(jù)源標識。 書寫形式:協(xié)議:子協(xié)議:數(shù)據(jù)源標識 協(xié)議:在JDBC中總是以jdbc開始 子協(xié)議:是橋連接的驅(qū)動程序或是數(shù)據(jù)庫管理系統(tǒng)名稱。 數(shù)據(jù)源標識:標記找到數(shù)據(jù)庫來源的地址與連接端口。 例如:(MySql的連接URL) jdbc:mysql: /localhost:3306/test?useUnicode=true&characterEncoding=gbk ; useUnicode=true:表示使用Unicode字符集。如果characterEncoding設(shè)置為 gb2312或G

39、BK,本參數(shù)必須設(shè)置為true 。characterEncoding=gbk:字符編碼方式。 (3)、創(chuàng)建數(shù)據(jù)庫的連接 要連接數(shù)據(jù)庫,需要向請求并獲得Connection對象, 該對象就代表一個數(shù)據(jù)庫的連接。 使用DriverManager的getConnectin(String url , String username , String password )方法傳入指定的欲連接的數(shù)據(jù)庫的路徑、數(shù)據(jù)庫的用戶名和 密碼來獲得。 例如: /連接MySql數(shù)據(jù)庫,用戶名和密碼都是root String url = "jdbc:mysql:/localhost:3306/test"

40、; ; String username = "root" ; String password = "root" ; try Connection con = DriverManager.getConnection(url , username , password ) ; catch(SQLException se) 數(shù)據(jù)庫連接失敗!"); se.printStackTrace() ; (4)、創(chuàng)建一個Statement 要執(zhí)行SQL語句,必須獲得實例,Statement實例分為以下3 種類型: 執(zhí)行靜態(tài)SQL語句。通常通過Statement實

41、例實現(xiàn)。 執(zhí)行動態(tài)SQL語句。通常通過PreparedStatement實例實現(xiàn)。 執(zhí)行數(shù)據(jù)庫存儲過程。通常通過CallableStatement實例實現(xiàn)。 具體的實現(xiàn)方式: Statement stmt = con.createStatement() ; PreparedStatement pstmt = con.prepareStatement(sql) ; CallableStatement cstmt = con.prepareCall("CALL demoSp(? , ?)") ; (5)、執(zhí)行SQL語句 Statement接口提供了三種執(zhí)行SQL語句的方法:ex

42、ecuteQuery 、executeUpdate 和execute ResultSet executeQuery(String sqlString):執(zhí)行查詢數(shù)據(jù)庫的SQL語句 ,返回一個結(jié)果集(ResultSet)對象。 int executeUpdate(String sqlString):用于執(zhí)行INSERT、UPDATE或 DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等 execute(sqlString):用于執(zhí)行返回多個結(jié)果集、多個更新計數(shù)或二者組合的 語句。 具體實現(xiàn)的代碼: ResultSet rs = stmt.executeQ

43、uery("SELECT * FROM .") ; int rows = stmt.executeUpdate("INSERT INTO .") ; boolean flag = stmt.execute(String sql) ; (6)、處理結(jié)果 兩種情況: 執(zhí)行更新返回的是本次操作影響到的記錄數(shù)。 執(zhí)行查詢返回的結(jié)果是一個ResultSet對象。 ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些 行中數(shù)據(jù)的訪問。 使用結(jié)果集(ResultSet)對象的訪問方法獲取數(shù)據(jù): while(rs.next() Str

44、ing name = rs.getString("name") ; String pass = rs.getString(1) ; / 此方法比較高效 (列是從左到右編號的,并且從列1開始) (7)、關(guān)閉JDBC對象 操作完成以后要把所有使用的JDBC對象全都關(guān)閉,以釋放JDBC資源,關(guān)閉順序和聲 明順序相反: 關(guān)閉記錄集 關(guān)閉聲明 關(guān)閉連接對象 if(rs != null) / 關(guān)閉記錄集 try rs.close() ; catch(SQLException e) e.printStackTrace() ; if(stmt != null) / 關(guān)閉聲明 try stm

45、t.close() ; catch(SQLException e) e.printStackTrace() ; if(conn != null) / 關(guān)閉連接對象 try conn.close() ; catch(SQLException e) e.printStackTrace() ; 11、數(shù)據(jù)庫索引什么是索引?數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。例如這樣一個查詢:select * from table1 where id=44。如果沒有索引,必須遍歷整個表,直到ID等于44的這一行被找到為止;有了索引之后(必須是在ID這一列上建立的索引),直接在索引里面找 44(也

46、就是在ID這一列找),就可以得知這一行的位置,也就是找到了這一行??梢?,索引是用來定位的。索引分為聚簇索引和非聚簇索引兩種,聚簇索引 是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對于單行的檢索很快。建立索引的目的是加快對表中記錄的查找或排序。為表設(shè)置索引要付出代價的:一是增加了數(shù)據(jù)庫的存儲空間,二是在插入和修改數(shù)據(jù)時要花費較多的時間(因為索引也要隨之變動)。為什么要創(chuàng)建索引?創(chuàng)建索引可以大大提高系統(tǒng)的性能。第一,通過創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性。第二,可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。第三,

47、可以加速表和表之間的連接,特別是在實現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。第四,在使用分組和排序子句進行數(shù)據(jù)檢索時,同樣可以顯著減少查詢中分組和排序的時間。第五,通過使用索引,可以在查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。也許會有人要問:增加索引有如此多的優(yōu)點,為什么不對表中的每一個列創(chuàng)建一個索引呢?因為,增加索引也有許多不利的方面。第一,創(chuàng)建索引和維護索引要耗費時間,這種時間隨著數(shù)據(jù)量的增加而增加。第二,索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。第三,當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)的維護

48、,這樣就降低了數(shù)據(jù)的維護速度。在哪建索引?索引是建立在數(shù)據(jù)庫表中的某些列的上面。在創(chuàng)建索引的時候,應(yīng)該考慮在哪些列上可以創(chuàng)建索引,在哪些列上不能創(chuàng)建索引。一般來說,應(yīng)該在這些列上創(chuàng)建索引:(1)在經(jīng)常需要搜索的列上,可以加快搜索的速度;(2).在作為主鍵的列上,強制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu);(3)在經(jīng)常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;在經(jīng)常需要根據(jù)范圍進行搜索的列上創(chuàng)建索引,因為索引已經(jīng)排序,其指定的范圍是連續(xù)的;(4).在經(jīng)常需要排序的列上創(chuàng)建索引,因為索引已經(jīng)排序,這樣查詢可以利用索引的排序,加快排序查詢時間;(5).在經(jīng)常使用在WHERE子句中的列上

49、面創(chuàng)建索引,加快條件的判斷速度。對于有些列不應(yīng)該創(chuàng)建索引。一般來說,不應(yīng)該創(chuàng)建索引的的這些列具有下列特點:第一,對于那些在查詢中很少使用或者參考的列不應(yīng)該創(chuàng)建索引。這是因為,既然這些列很少使用到,因此有索引或者無索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統(tǒng)的維護速度和增大了空間需求。第二,對于那些只有很少數(shù)據(jù)值的列也不應(yīng)該增加索引。這是因為,由于這些列的取值很少,例如人事表的性別列,在查詢的結(jié)果中,結(jié)果集的數(shù)據(jù)行占了表中數(shù)據(jù)行的很大比例,即需要在表中搜索的數(shù)據(jù)行的比例很大。增加索引,并不能明顯加快檢索速度。第三,對于那些定義為text, image和bit數(shù)據(jù)類型的列不應(yīng)該增

50、加索引。這是因為,這些列的數(shù)據(jù)量要么相當大,要么取值很少,不利于使用索引。第四,當修改性能遠遠大于檢索性能時,不應(yīng)該創(chuàng)建索引。這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改操作遠遠多于檢索操作時,不應(yīng)該創(chuàng)建索引。索引的數(shù)據(jù)結(jié)構(gòu):B-tree,B是balance,一般用于數(shù)據(jù)庫的索引。使用B-tree結(jié)構(gòu)可以顯著減少定位記錄時所經(jīng)歷的中間過程,從而加快存取速度。而B+tree是B-tree的一個變種,大名鼎鼎的MySQL就普遍使用B+tree實現(xiàn)其索引結(jié)構(gòu)。插入(insert)操作:插入一個元素

51、時,首先在B-tree中是否存在,如果不存在,即在葉子結(jié)點處結(jié)束,然后在葉子結(jié)點中插入該新的元素,注意:如果葉子結(jié)點空間足夠,這里需要向右移動該葉子結(jié)點中大于新插入關(guān)鍵字的元素,如果空間滿了以致沒有足夠的空間去添加新的元素,則將該結(jié)點進行“分裂”,將一半數(shù)量的關(guān)鍵字元素分裂到新的其相鄰右結(jié)點中,中間關(guān)鍵字元素上移到父結(jié)點中(當然,如果父結(jié)點空間滿了,也同樣需要“分裂”操作),而且當結(jié)點中關(guān)鍵元素向右移動了,相關(guān)的指針也需要向右移。如果在根結(jié)點插入新元素,空間滿了,則進行分裂操作,這樣原來的根結(jié)點中的中間關(guān)鍵字元素向上移動到新的根結(jié)點中,因此導(dǎo)致樹的高度增加一層。刪除(delete)操作:首先查

52、找B-tree中需刪除的元素,如果該元素在B-tree中存在,則將該元素在其結(jié)點中進行刪除,如果刪除該元素后,首先判斷該元素是否有左右孩子結(jié)點,如果有,則上移孩子結(jié)點中的某相近元素到父節(jié)點中,然后是移動之后的情況;如果沒有,直接刪除后,移動之后的情況.。刪除元素,移動相應(yīng)元素之后,如果某結(jié)點中元素數(shù)目小于ceil(m/2)-1,則需要看其某相鄰兄弟結(jié)點是否豐滿(結(jié)點中元素個數(shù)大于ceil(m/2)-1),如果豐滿,則向父節(jié)點借一個元素來滿足條件;如果其相鄰兄弟都剛脫貧,即借了之后其結(jié)點數(shù)目小于ceil(m/2)-1,則該結(jié)點與其相鄰的某一兄弟結(jié)點進行“合并”成一個結(jié)點,以此來滿足條件。下面結(jié)合

53、例子詳細講解mysql中索引的使用索引是快速搜索的關(guān)鍵。MySQL索引的建立對于MySQL的高效運行是很重要的。下面介紹幾種常見的MySQL索引類型。在數(shù)據(jù)庫表中,對字段建立索引可以大大提高查詢速度。假如我們創(chuàng)建了一個 mytable表:CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL ); 我們隨機向里面插入了10000條記錄,其中有一條:5555, admin。在查找username="admin"的記錄 SELECT * FROM mytable WHERE username=&#

54、39;admin'時,如果在username上已經(jīng)建立了索引,MySQL無須任何掃描,即準確可找到該記錄。相反,MySQL會掃描所有記錄,即要查詢10000條記錄。索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索包含多個列。MySQL索引類型包括:(1)普通索引這是最基本的索引,它沒有任何限制。它有以下幾種創(chuàng)建方式:創(chuàng)建索引CREATE INDEX indexName ON mytable(username(length); 如果是CHAR,VARCHAR類型,length可以小于字段實際長度;如果是BLOB和T

55、EXT類型,必須指定 length,下同。修改表結(jié)構(gòu)ALTER mytable ADD INDEX indexName ON (username(length)創(chuàng)建表的時候直接指定CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX indexName (username(length) ); 刪除索引的語法:DROP INDEX indexName ON mytable;(2)唯一索引它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創(chuàng)建方式:創(chuàng)建索引CREATE UNIQUE INDEX indexName

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論