java常見面試題

5、String是最基本的數據類型嗎?前端

 基本數據類型包括byte、int、char、long、float、double、boolean和short。java

 java.lang.String類是final類型的,所以不能夠繼承這個類、不能修改這個類。爲了提升效率節省空間,咱們應該用StringBuffer類mysql

6、int 和 Integer 有什麼區別c++

 Java 提供兩種不一樣的類型:引用類型和原始類型(或內置類型)。Int是java的原始數據類型,Integer是java爲int提供的封裝類。Java爲每一個原始類型提供了封裝類。程序員

 引用類型和原始類型的行爲徹底不一樣,而且它們具備不一樣的語義。引用類型和原始類型具備不一樣的特徵和用法,它們包括:大小和速度問題,這種類型以哪一種類型的數據結構存儲,當引用類型和原始類型用做某個類的實例數據時所指定的缺省值。對象引用實例變量的缺省值爲 null,而原始類型實例變量的缺省值與它們的類型有關。web

7、String 和StringBuffer的區別算法

 JAVA平臺提供了兩個類:String和StringBuffer,它們能夠儲存和操做字符串,即包含多個字符的字符數據。這個String類提供了數值不可改變的字符串。而這個StringBuffer類提供的字符串進行修改。當你知道字符數據要改變的時候你就可使用StringBuffer。典型地,你可使用 StringBuffers來動態構造字符數據。spring

8、運行時異常與通常異常有何異同?sql

 異常表示程序運行過程當中可能出現的非正常狀態,運行時異常表示虛擬機的一般操做中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,可是並不要求必須聲明拋出未被捕獲的運行時異常。數據庫

9、說出Servlet的生命週期,並說出Servlet和CGI的區別。

 Servlet被服務器實例化後,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應的doXXX方法(doGet,doPost)等,當服務器決定將實例銷燬的時候調用其destroy方法。

與cgi的區別在於servlet處於服務器進程中,它經過多線程方式運行其service方法,一個實例能夠服務於多個請求,而且其實例通常不會銷燬,而CGI對每一個請求都產生新的進程,服務完成後就銷燬,因此效率上低於servlet。

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

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

12、Collection 和 Collections的區別。

  Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.

    Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做。

13、&和&&的區別。

&是位運算符,表示按位與運算,&&是邏輯運算符,表示邏輯與(and)。

15,HashMap和Hashtable的區別。

  都屬於Map接口的類,實現了將唯一鍵映射到特定的值上。

  HashMap 類沒有分類或者排序。它容許一個 null 鍵和多個 null 值。

  Hashtable 相似於 HashMap,可是不容許 null 鍵和 null 值。它也比 HashMap 慢,由於它是同步的。

15、final, finally, finalize的區別。

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

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

finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,能夠覆蓋此方法提供垃圾收集時的其餘資源回收,例如關閉文件等。

16、sleep() 和 wait() 有什麼區別?

    sleep是線程類(Thread)的方法,致使此線程暫停執行指定時間,把執行機會給其餘線程,可是監控狀態依然保持,到時後會自動恢復。調用sleep不會釋放對象鎖。

wait是Object類的方法,對此對象調用wait方法致使本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。

17、Overload和Override的區別。Overloaded的方法是否能夠改變返回值的類型?

 方法的重寫Overriding和重載Overloading是Java多態性的不一樣表現。重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。若是在子類中定義某方法與其父類有相同的名稱和參數,咱們說該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了。若是在一個類中定義了多個同名的方法,它們或有不一樣的參數個數或有不一樣的參數類型,則稱爲方法的重載(Overloading)。Overloaded的方法是能夠改變返回值的類型。

19、同步和異步有何異同,在什麼狀況下分別使用他們?舉例說明。

 若是數據將在線程間共享。例如正在寫的數據之後可能被另外一個線程讀到,或者正在讀的數據可能已經被另外一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。

當應用程序在對象上調用了一個須要花費很長時間來執行的方法,而且不但願讓程序等待方法的返回時,就應該使用異步編程,在不少狀況下采用異步途徑每每更有效率。

20、abstract class和interface有什麼區別?

 聲明方法的存在而不去實現它的類被叫作抽象類(abstract class),它用於要建立一個體現某些基本行爲的類,併爲該類聲明方法,但不能在該類中實現該類的狀況。不能建立abstract 類的實例。然而能夠建立一個變量,其類型是一個抽象類,並讓它指向具體子類的一個實例。不能有抽象構造函數或抽象靜態方法。Abstract 類的子類爲它們父類中的全部抽象方法提供實現,不然它們也是抽象類爲。取而代之,在子類中實現該方法。知道其行爲的其它類能夠在類中實現這些方法。

 接口(interface)是抽象類的變體。在接口中,全部方法都是抽象的。多繼承性可經過實現這樣的接口而得到。接口中的全部方法都是抽象的,沒有一個有程序體。接口只能夠定義static final成員變量。接口的實現與子類類似,除了該實現類不能從接口定義中繼承行爲。當類實現特殊接口時,它定義(即將程序體給予)全部這種接口的方法。而後,它能夠在實現了該接口的類的任何對象上調用接口的方法。因爲有抽象類,它容許使用接口名做爲引用變量的類型。一般的動態聯編將生效。引用能夠轉換到接口類型或從接口類型轉換,instanceof 運算符能夠用來決定某對象的類是否實現了接口。

22、forward 和redirect的區別

 forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,而後把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,因此它的地址欄中仍是原來的地址。

redirect就是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,通常來講瀏覽器會用剛纔請求的全部參數從新請求,因此session,request參數均可以獲取。

24、Static Nested Class 和 Inner Class的不一樣。

    Static Nested Class是被聲明爲靜態(static)的內部類,它能夠不依賴於外部類實例被實例化。而一般的內部類須要在外部類實例化後才能實例化。

25、JSP中動態INCLUDE與靜態INCLUDE的區別?

 動態INCLUDE用jsp:include動做實現<jsp:include page="included.jsp" flush="true" />它老是會檢查所含文件中的變化,適合用於包含動態頁面,而且能夠帶參數。

靜態INCLUDE用include僞碼實現,定不會檢查所含文件的變化,適用於包含靜態頁面<%@ include file="included.htm" %>

26、何時用assertion

assertion(斷言)在軟件開發中是一種經常使用的調試方式,不少開發語言中都支持這種機制。在實現中,assertion就是在程序中的一條語句,它對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值爲true;若是該值爲false,說明程序已經處於不正確的狀態下,系統將給出警告或退出。通常來講,assertion用於保證程序最基本、關鍵的正確性。assertion檢查一般在開發和測試時開啓。爲了提升性能,在軟件發佈後,assertion檢查一般是關閉的。

36、說出數據鏈接池的工做機制是什麼?

鏈接客戶端程序須要鏈接時,池驅動程序會返回一個未使用的池鏈接並將其表記爲忙。若是當前沒有空閒鏈接,池驅動程序就新建必定數量的鏈接,新建鏈接的數量有配置參數決定。當使用的池鏈接調用完成後,池驅動程序將此鏈接表記爲空閒,其餘調用就可使用這個鏈接。

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

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

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

 Set裏的元素是不能重複的,那麼用iterator()方法來區分重複與否。equals()是判讀兩個Set是否相等。

equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,爲的是當兩個分離的對象的內容和類型相配的話,返回真值。

43、try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,何時被執行,在return前仍是後?

 會執行,在return前執行。

47、當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?

 不能,一個對象的一個synchronized方法只能由一個線程訪問。

51、垃圾回收的優勢和原理。並考慮2種回收機制。

 Java語言中一個顯着的特色就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候再也不須要考慮內存管理。因爲有個垃圾回收機制, Java中的對象再也不有"做用域"的概念,只有對象的引用纔有"做用域"。垃圾回收能夠有效的防止內存泄露,有效的使用可使用的內存。垃圾回收器一般是做爲一個單獨的低級別的線程運行,不可預知的狀況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或全部對象進行垃圾回收。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

52、請說出你所知道的線程同步的方法。

wait():使一個線程處於等待狀態,而且釋放所持有的對象的lock。

sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。

notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM肯定喚醒哪一個線程,並且不是按優先級。

Allnotity():喚醒全部處入等待狀態的線程,注意並非給全部喚醒線程一個對象的鎖,而是讓它們競爭。

53、你所知道的集合類都有哪些?主要方法?

最經常使用的集合類是 List 和 Map。 List 的具體實現包括

ArrayList 和 Vector,它們是可變大小的列表,比較適合構建、存儲和操做任何類型對象的元素列表。

List 適用於按數值索引訪問元素的情形。

Map 提供了一個更通用的元素存儲方法。Map 集合類用於存儲元素對(稱做"鍵"和"值"),其中每一個鍵映射到一個值。

62、如何現實servlet的單線程模式

<%@ page isThreadSafe="false"%>

64、JSP和Servlet有哪些相同點和不一樣點,他們之間的聯繫是什麼?

 JSP 是Servlet技術的擴展,本質上是Servlet的簡易方式,更強調應用的外表表達。JSP編譯後是"類servlet"。Servlet和JSP最主要的不一樣點在於,Servlet的應用邏輯是在Java文件中,而且徹底從表示層中的HTML裏分離開來。而JSP的狀況是Java和HTML能夠組合成一個擴展名爲.jsp的文件。JSP側重於視圖,Servlet主要用於控制邏輯。

70、XML文檔定義有幾種形式?它們之間有何本質區別?解析XML文檔有哪幾種方式?

a: 兩種形式 dtd,schema,b: 本質區別:schema自己是xml的,能夠被XML解析器解析(這也是從DTD上發展schema的根本目的),c:有DOM,SAX,STAX等

    DOM:處理大型文件時其性能降低的很是厲害。這個問題是由DOM的樹結構所形成的,這種結構佔用的內存較多,並且DOM必須在解析文件以前把整個文檔裝入內存,適合對XML的隨機訪問

SAX:不現於DOM,SAX是事件驅動型的XML解析方式。它順序讀取XML文件,不須要一次所有裝載整個文件。當遇到像文件開頭,文檔結束,或者標籤開頭與標籤結束時,它會觸發一個事件,用戶經過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問STAX:Streaming API for XML (StAX)

92、j2ee經常使用的設計模式?說明工廠模式。

    Java中的23種設計模式:

Factory(工廠模式),Builder(建造模式),Factory Method(工廠方法模式),

Prototype(原始模型模式),Singleton(單例模式),Facade(門面模式),

Adapter(適配器模式),Bridge(橋樑模式),Composite(合成模式),

Decorator(裝飾模式),Flyweight(享元模式),Proxy(代理模式),

Command(命令模式),Interpreter(解釋器模式),Visitor(訪問者模式),

Iterator(迭代子模式),Mediator(調停者模式),Memento(備忘錄模式),

Observer(觀察者模式),State(狀態模式),Strategy(策略模式),

Template Method(模板方法模式),Chain Of Responsibleity(責任鏈模式)

工廠模式:工廠模式是一種常常被使用到的模式,根據工廠模式實現的類能夠根據提供的數據生成一組類中某一個類的實例,一般這一組類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做。首先須要定義一個基類,該類的子類經過不一樣的方法實現了基類中的方法。而後須要定義一個工廠類,工廠類能夠根據條件生成不一樣的子類實例。當獲得子類的實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例。

96、JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別表明什麼意義?在try塊中能夠拋出異常嗎?

 Java 經過面向對象的方法進行異常處理,把各類不一樣的異常進行分類,並提供了良好的接口。在Java中,每一個異常都是一個對象,它是Throwable類或其它子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法能夠捕獲到這個異常並進行處理。Java的異常處理是經過5個關鍵詞來實現的:try、catch、throw、throws和finally。通常狀況下是用try來執行一段程序,若是出現異常,系統會拋出(throws)一個異常,這時候你能夠經過它的類型來捕捉(catch)它,或最後(finally)由缺省處理器來處理。

用try來指定一塊預防全部"異常"的程序。緊跟在try程序後面,應包含一個catch子句來指定你想要捕捉的"異常"的類型。

throw語句用來明確地拋出一個"異常"。

throws用來標明一個成員函數可能拋出的各類"異常"。

Finally爲確保一段代碼無論發生什麼"異常"都被執行一段代碼。

能夠在一個成員函數調用的外面寫一個try語句,在這個成員函數內部寫另外一個try語句保護其餘代碼。每當遇到一個try語句,"異常"的框架就放到堆棧上面,直到全部的try語句都完成。若是下一級的try語句沒有對某種"異常"進行處理,堆棧就會展開,直到遇到有處理這種"異常"的try語句。

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

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

102、java中實現多態的機制是什麼?

 方法的重寫Overriding和重載Overloading是Java多態性的不一樣表現。重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。

103、垃圾回收器的基本原理是什麼?垃圾回收器能夠立刻回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?

 對於GC來講,當程序員建立對象時,GC就開始監控這個對象的地址、大小以及使用狀況。一般,GC採用有向圖的方式記錄和管理堆(heap)中的全部對象。經過這種方式肯定哪些對象是"可達的",哪些對象是"不可達的"。當GC肯定一些對象爲"不可達"時,GC就有責任回收這些內存空間。能夠。程序員能夠手動執行System.gc(),通知GC運行,可是Java語言規範並不保證GC必定會執行。

106、是否能夠從一個static方法內部發出對非static方法的調用?

不能夠,若是其中包含對象的method();不能保證對象初始化.

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

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

113、開發中都用到了那些設計模式?用在什麼場合?

每一個模式都描述了一個在咱們的環境中不斷出現的問題,而後描述了該問題的解決方案的核心。經過這種方式,你能夠無數次地使用那些已有的解決方案,無需在重複相同的工做。主要用到了MVC的設計模式。用來開發JSP/Servlet或者J2EE的相關應用。簡單工廠模式等。

117、BS與CS的聯繫與區別。

 C/S是Client/Server的縮寫。服務器一般採用高性能的PC、工做站或小型機,並採用大型數據庫系統,如Oracle、Sybase、Informix或 SQL Server。客戶端須要安裝專用的客戶端軟件。

 B/S是Brower/Server的縮寫,客戶機上只要安裝一個瀏覽器(Browser),如Netscape Navigator或Internet Explorer,服務器安裝Oracle、Sybase、Informix或 SQL Server等數據庫。在這種結構下,用戶界面徹底經過WWW瀏覽器實現,一部分事務邏輯在前端實現,可是主要事務邏輯在服務器端實現。瀏覽器經過Web Server 同數據庫進行數據交互。

C/S 與 B/S 區別:

1.硬件環境不一樣:

  C/S 通常創建在專用的網絡上, 小範圍裏的網絡環境, 局域網之間再經過專門服務器提供鏈接和數據交換服務.

  B/S 創建在廣域網之上的, 沒必要是專門的網絡硬件環境,例與電話上網, 租用設備. 信息本身管理. 有比C/S更強的適應範圍, 通常只要有操做系統和瀏覽器就行

2.對安全要求不一樣

  C/S 通常面向相對固定的用戶羣, 對信息安全的控制能力很強. 通常高度機密的信息系統採用C/S 結構適宜. 能夠經過B/S發佈部分可公開信息.

  B/S 創建在廣域網之上, 對安全的控制能力相對弱, 可能面向不可知的用戶。

3.對程序架構不一樣

  C/S 程序能夠更加註重流程, 能夠對權限多層次校驗, 對系統運行速度能夠較少考慮.

  B/S 對安全以及訪問速度的多重的考慮, 創建在須要更加優化的基礎之上. 比C/S有更高的要求 B/S結構的程序架構是發展的趨勢, 從MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持網絡的構件搭建的系統. SUN 和IBM推的JavaBean 構件技術等,使 B/S更加成熟.

4.軟件重用不一樣

  C/S 程序能夠不可避免的總體性考慮, 構件的重用性不如在B/S要求下的構件的重用性好.

  B/S 對的多重結構,要求構件相對獨立的功能. 可以相對較好的重用.就入買來的餐桌能夠再利用,而不是作在牆上的石頭桌子

5.系統維護不一樣

  C/S 程序因爲總體性, 必須總體考察, 處理出現的問題以及系統升級. 升級難. 多是再作一個全新的系統

  B/S 構件組成,方面構件個別的更換,實現系統的無縫升級. 系統維護開銷減到最小.用戶從網上本身下載安裝就能夠實現升級.

6.處理問題不一樣

  C/S 程序能夠處理用戶面固定, 而且在相同區域, 安全要求高需求, 與操做系統相關. 應該都是相同的系統

  B/S 創建在廣域網上, 面向不一樣的用戶羣, 分散地域, 這是C/S沒法做到的. 與操做系統平臺關係最小.

7.用戶接口不一樣

  C/S 可能是創建的Window平臺上,表現方法有限,對程序員廣泛要求較高

  B/S 創建在瀏覽器上, 有更加豐富和生動的表現方式與用戶交流. 而且大部分難度減低,減低開發成本.

8.信息流不一樣

  C/S 程序通常是典型的中央集權的機械式處理, 交互性相對低

B/S 信息流向可變化, B-B B-C B-G等信息、流向的變化, 更像交易中心。

119、STRUTS的應用(如STRUTS架構)

 Struts 是採用Java Servlet/JavaServer Pages技術,開發Web應用程序的開放源碼的framework。採用Struts能開發出基於MVC(Model-View-Controller)設計模式的應用構架。

Struts有以下的主要功能:

一.包含一個controller servlet,能將用戶的請求發送到相應的Action對象。

二.JSP自由tag庫,而且在controller servlet中提供關聯支持,幫助開發員建立交互式表單應用。

三.提供了一系列實用對象:XML處理、經過Java reflection APIs自動處理JavaBeans屬性、國際化的提示和消息。

48、編程題: 寫一個Singleton出來。

 Singleton模式主要做用是保證在Java應用程序中,一個類Class只有一個實例存在。

通常Singleton模式一般有幾種種形式:

第一種形式: 定義一個類,它的構造函數爲private的,它有一個static的private的該類變量,在類初始化時實例話,經過一個public的getInstance方法獲取對它的引用,繼而調用其中的方法。

public class Singleton {

private Singleton(){}

      //在本身內部定義本身一個實例,是否是很奇怪?

      //注意這是private 只供內部調用

  private static Singleton instance = new Singleton();

      //這裏提供了一個供外部訪問本class的靜態方法,能夠直接訪問  

  public static Singleton getInstance() {

        return instance;   

      }

    }  

第二種形式:

public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次    

  //使用時生成實例,提升了效率!

  if (instance==null)

    instance=new Singleton();

return instance;   }

選擇排序

public static void main(String[] args){

       int[]ary={8,6,3,5,2,1};

       ary=selectionSort(ary);

       String s=Arrays.toString(ary);

       System.out.print(s);

}

 

public static int[] selectionSort(int[] ary){

       for(int i=0;i<ary.length-1;i++){

       for(int j=i+1;j<ary.length;j++){

              if(ary[i]>ary[j]){

                     int temp=ary[i];

                     ary[i]=ary[j];

                     ary[j]=temp;

              }

       }

    }

       return ary;

}

冒泡排序

for(int i=0;i<ary.length-1;i++){

for(int j=0;j<ary.length-i-1;j++){

       if(ary[j]>ary[j+1]){

              int temp=ary[j];

              ary[j]=ary[j+1];

              ary[j+1]=temp;   

       }           

     }

}

       return ary;

  用二重循環實現,外循環變量設爲i,內循環變量設爲j。外循環重複9次,內循環依次重複9,8,...,1次。每次進行比較的兩個元素都是與內循環j有關的,它們能夠分別用a[j]和a[j+1]標識,i的值依次爲1,2,...,9,對於每個i, j的值依次爲1,2,...10-i。

插入排序

for(int i=1;i<ary.length;i++){

int temp=ary[i];

int j;

for(j=i-1;j>=0;j--){

       if(temp<ary[j]){

              ary[j+1]=ary[j];

       }else{

              break;          

       }

   }

       ary[j+1]=temp;   

}

       return ary;

 

打亂排序

import java.util.HashSet;

import java.util.Iterator;

import java,util.Set;

public class Iterator overSetDemo{

public static void main(String[] args){

       Set<String> set=new HashSet<String>();

       set.add("D");

       set.add("A");

       set.add("C");

       set.add("B");

       for(Iteractor i=set.iterator() : i.hasNext();){

              String s=(String)i.next();

              System.out.print(s+" ");          

       }

   }

}

//MySQL 中的分頁查詢實現

import java.io.InputStream;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

import week07.domain.Flight;

import week07.domain.News;

import week07.util.ConnectionUtils;

public class FlightDaoImplForMySQL {

       /**

        * 分頁查詢flight表的全部列的數據

        *

        * @param page

        *            第幾頁

        * @param rowsPerPages

        *            每頁顯示行數

        * @param con

        *            數據庫鏈接

        * @return 查詢到的數據以News對象的形式存儲到List中返回

        * @throws Exception

        */

       public List<Flight> listPagesNewsDB(int page, int rowsPerPage,

                     Connection con) throws Exception {

              int from = (page - 1) * rowsPerPage;

              String sql = "select * from flight limit ?, ?;";

              Connection conn = null;

              PreparedStatement pStmt = null;

              ResultSet rs = null;

              Flight flight = null;

              List<Flight> flights = new ArrayList<Flight>();

              try {

                     conn = ConnectionUtils.openConnection();

                     pStmt = conn.prepareStatement(sql);

                     pStmt.setInt(1, from);

                     pStmt.setInt(2, rowsPerPage);

                     rs = pStmt.executeQuery();

                     while (rs.next()) {

                            String id = rs.getString(1);

                            String num = rs.getString(2);

                            flight = new Flight(id, num);

                            flights.add(flight);

                     }

              } catch (SQLException e) {

                     e.printStackTrace();

              } finally {

                     ConnectionUtils.closeResultSet(rs);

                     ConnectionUtils.closeStatement(pStmt);

                     ConnectionUtils.closeConnection(conn);

              }

              return flights;

       }

       public static void main(String[] args) throws Exception {

              List<Flight> ff = new FlightDaoImplForMySQL().

              listPagesNewsDB(2, 3,

                            ConnectionUtils.openConnection());

              for(Flight f:ff){

                     System.out.println("=="+f.getId()+"="+f.getNum()+"==");

              }

       }

}

-------------------------------------------------------------------------------

//Oracle 中的分頁查詢實現

import java.io.FileInputStream;

import java.io.InputStream;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.List;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

import week07.domain.News;

import week07.util.ConnectionUtils;

public class NewsDaoImpl implements INewsDao {

       /**

        * 分頁查詢news表的全部列的數據

        *

        * @param page

        *            第幾頁

        * @param rowsPerPages

        *            每頁顯示行數

        * @param con

        *            數據庫鏈接

        * @return 查詢到的數據以News對象的形式存儲到List中返回

        * @throws Exception

        * select news_id, title, content, author, pubDate, rn from(

        *                       select news_id, title, content, author, pubDate, rownum rn

        *                       from news

        *                       where rownum < ? )

        * where rn >= ?;

        */

       public List<News> listPagesNewsDB(int page, int rowsPerPage,

              Connection con) throws Exception {

              int from = (page - 1) * rowsPerPage + 1;

              int to = from + rowsPerPage;

              String sql = "select news_id, title, "

                            + "content, author, pubDate, rn " + "from "

                            + "(select news_id, title, content, "

                            + "author, pubDate, rownum rn "

                            + "from news where rownum < ? ) " + "where rn >= ?";

              Connection conn = null;

              PreparedStatement pStmt = null;

              ResultSet rs = null;

              News news = null;

              List<News> newses = new ArrayList<News>();

              try {

                     conn = ConnectionUtils.openConnection();

                     pStmt = conn.prepareStatement(sql);

                     pStmt.setInt(1, to);

                     pStmt.setInt(2, from);

                     rs = pStmt.executeQuery();

                     while (rs.next()) {

                            news = new News();

                            news.setNewsId(rs.getLong(1));

                            news.setTitle(rs.getString(2));

                            news.setContent(rs.getString(3));

                            news.setAuthor(rs.getString(4));

                            news.setPubdate(rs.getDate(5));

                            newses.add(news);

                     }

              } catch (SQLException e) {

                     e.printStackTrace();

              } finally {

                     ConnectionUtils.closeResultSet(rs);

                     ConnectionUtils.closeStatement(pStmt);

                     ConnectionUtils.closeConnection(conn);

              }

              return newses;

       }

}

17、JDBC,Hibernate 分頁怎樣實現?

答:方法分別爲:

1) Hibernate 的分頁:

Query query = session.createQuery("from Student");

query.setFirstResult(firstResult);//設置每頁開始的記錄號

query.setMaxResults(resultNumber);//設置每頁顯示的記錄數

Collection students = query.list();

2) JDBC 的分頁:根據不一樣的數據庫採用不一樣的sql 分頁語句

例如: Oracle 中的sql 語句爲: "SELECT * FROM (SELECT a.*, rownum r FROM

TB_STUDENT) WHERE r between 2 and 10" 查詢從記錄號2 到記錄號10 之間的全部記錄

倒三角

public class daosanjiao {

 

public static void main(String[] args) {

 

for(int i=0;i<4;i++)

      {

for(int k=0;k<i+1;k++)

        {

System.out.print(" ");

        }

 

for(int j=0;j<7-2*i;j++)

        {

System.out.print("*");

        }

System.out.println();

      }

 

  }

}

42、用你熟悉的語言寫一個鏈接ORACLE數據庫的程序,可以完成修改和查詢工做。答:JDBC示例程序

以下:public void testJdbc(){

Connection con = null;

PreparedStatement ps = null;

ResultSet rs = null;

try{

//step1:註冊驅動;

Class.forName("oracle.jdbc.driver.OracleDriver");

//step 2:獲取數據庫鏈接;

con=DriverManager.getConnection(

"jdbc:oracle:thin:@192.168.0.23:1521:tarena", "openlab","open123");

/************************查詢************************/

//step 3:建立Statement;

 String sql = "SELECT id, fname, lname, age, FROM Person_Tbl"; ps = con.prepareStatement(sql);

//step 4 :執行查詢語句,獲取結果集;

rs = ps.executeQuery();

//step 5:處理結果集—輸出結果集中保存的查詢結果;

while (rs.next()){

System.out.print("id = " + rs.getLong("id"));

System.out.print(" , fname = " + rs.getString("fname"));

System.out.print(" , lname = " + rs.getString("lname"));

System.out.print(" , age = " + rs.getInt("age")); }

/************************JDBC 修改*********************/

sql = "UPDATE Person_Tbl SET age=23 WHERE id = ?"; ps = con.prepareStatement(sql);

ps.setLong(1, 88);

int rows = ps.executeUpdate();

System.out.println(rows + " rows affected.");

 } catch (Exception e){

e.printStackTrace();

 } finally{

try{

//關閉數據庫鏈接,以釋放資源。

con.close(); 

} catch (Exception e1) {

       E1.printStackTrace();

} } }

31、Statement,PreparedStatement,CallableStatment的區別

答:區別有如下幾點: 1) Statement是PreparedStatement和CallableStatement的父類; 2)Statement是直接發送Sql語句到數據庫,事先沒有進行預編譯。

PreparedStatement會將sql進行預編譯,當sql語句要重複執行時,數據庫會調用之前預編譯好的sql語句,因此PreparedStatement在性能方面會更好;

 3)PreparedStatement在執行sql時,對傳入的參數能夠進行強制的類型轉換。以保證數據格式與底層的數據庫格式一致。

 4)CallableStatement 適用與存儲過程的查詢表達語句

aop稱爲是面向切面編程,那麼對它最好的解釋就是攔截器了,而他的aop原理呢就是:在執行某些代碼以前執行另外的代碼,是程序變的靈活,擴展性更靈活,能夠隨意的刪除和添加某些功能!你能夠參照filter過濾器,其實filter就是一個很好的對aop的解釋

AOP是OOP的延續,是(Aspect Oriented Programming)的縮寫,意思是面向切面編程。

  主要的功能是:日誌記錄,性能統計,安全控制,事務處理,異常處理等等。

  主要的意圖是:將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,經過對這些行爲的分離,咱們但願能夠將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。

  能夠經過預編譯方式和運行期動態代理實如今不修改源代碼的狀況下給程序動態統一添加功能的一種技術。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP能夠說也是這種目標的一種實現。

  在Spring中提供了面向切面編程的豐富支持,容許經過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該作的——完成業務邏輯——僅此而已。它們並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。能夠更好的將原本不該該粘合在一塊兒的功能分離開。

1.定義切入點:spring根據須要織入通知的類和方法來定義切入點

通知是根據他們的特性織入目標類和方法的,如類名和方法名

2.靜態切入點:spring爲建立靜態切入點提供了方便的父類--StaticMethodMatcherPointcut。

  1)要建立自制的靜態切入點,只須要繼承這個類,實現isMatch()方法

  2)當被調用方法的名字與給出的映射名字匹配時,切入點才匹配

  3)使用明確的方法名,也能夠在名字的起始和結束處使用通配符*。

8一、現有1~100共一百個天然數,已隨機放入一個有98個元素的數組a[98]。要求寫出一個儘可能簡單的方案,找出沒有被放入數組的那2個數,並在屏幕上打印這2個數。注意:程序不用實現天然數隨機放入數組的過程。答:

int[] b = new int[]{....存入98個隨機的1~100的整數};

int[] a = new int[100];

for(int t : b) a[t-1]=t;

for(int t=0; t < a.length; t++)

if(a[t]==0) System.out.println(t+1);

84、在web應用開發過程當中常常遇到輸出某種編碼的字符,如從GBK到iso8859-1等,如何輸出一個某種編碼的字符串?

答:public static String translate(String str) {

String tempStr = "";

try {

tempStr = new String(str.getBytes("GBK"), "ISO-8859-1");

tempStr = tempStr.trim();

} catch (Exception e) {

System.err.println(e.getMessage()); }

return tempStr; }

87JAVA實現一種排序

答:用插入法進行排序代碼以下

package com.tarena;

import java.util.*;

class InsertSort {

 ArrayList list;

public InsertSort(int num,int mod) {

list = new ArrayList(num);

 Random rand = new Random();

System.out.println("The ArrayList Sort Before:");

for (int i=0;i<num ;i++ ) {

 list.add(new Integer(Math.abs(rand.nextInt()) % mod + 1)); System.out.println("list["+i+"]="+list.get(i)); } }

public void SortIt() {

Integer tempInt; int MaxSize=1;

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

tempInt = (Integer)list.remove(i); if(tempInt.intValue()>=((Integer)list.get(MaxSize-1)).intValue()) { list.add(MaxSize,tempInt);

MaxSize++;

System.out.println(list.toString());.

} else { for (int j=0;j<MaxSize ;j++ ) {

if (((Integer)list.get(j)).intValue()>=tempInt.intValue()) {

 list.add(j,tempInt); MaxSize++; System.out.println(list.toString()); break; } } } } System.out.println("The ArrayList Sort After:");

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

System.out.println("list["+i+"]="+list.get(i)); } }

public static void main(String[] args) {

 InsertSort sort = new InsertSort(10,100); sort.SortIt(); } }

Copyright Tarena Corporation,2009.All rights reserved } public int getAge() { return age; } public boolean isSex() { return sex; } public int getWeight() { return weight; } }

89.編寫一個截取字符串的函數,輸入爲一個字符串和字節數,輸出爲按字節截取的字符串。可是要保證漢字不被截半個,如"ABC"4,應該截爲"AB",輸入"ABCDEF"6,應該輸出爲"ABC"而不是"ABC+漢的半個"

答:package com.tarena; class SplitString {

public static String split(String str,int num) {

byte[] strs = str.getBytes();

if(strs[num-1]<0)

{ num=num-1; }

byte[] news = new byte[num];

System.arraycopy(strs,0,news,0,num);

return new String(news); }

public static void main(String[] args) {

String str = split("我ABC", 4);

System.out.println(str);

 String str2 = split("我ABC走DEF", 6);

System.out.println(str2); } }

92、請用JAVA實現兩個類,分別實現堆棧(Stack)和隊列(Queue)操做。

答:public class MyStack {

private List list; public MyStack(){

list = new ArrayList(); }

public boolean isEmpty(){ return list.size() == 0; }

public void push(Object obj){ list.add(obj); }

public Object pop(){

if(list.size()>0){

 Object obj = list.get(list.size()-1);

list.remove(list.size()-1); return obj;

}else{ return null; }}

public int getNumber(){ return list.size(); } }

class IntegerQueue { public int[] integerQueue;

// 用來當隊列 public int tail;

// 隊尾 public int size

;// 隊的長度,也能夠設置一個默認值,溢出時重新申請

public IntegerQueue(int size) {

integerQueue = new int[size];

 this.size = size; tail = 0; }

public void inQueue(int i) {

if (tail < size) {

this.integerQueue[tail] = i; tail++;

 } else { System.err.println("溢出啦!"); } }

public int outQueue() { if (tail >= 0) {

int tmp = this.integerQueue[0]; tail--; return tmp;

 } else {

 System.err.println("隊列爲空!");

 throw new RuntimeException(); } } }

做用域當前類同包子類其它

public √√√√

protected √√√×

 private √×××

字符串倒轉

public class Main {

public static void main(String[] args){

        Scanner in = new Scanner(System.in);

System.out.println("Please input a String:");

        String st = in.nextLine();

        StringBuilder buffer = new StringBuilder(st);

st = buffer.reverse().toString();

System.out.println("The reverse of the string is: "+st);

    }

}

計算日期

DateFormat   df   =   new   SimpleDateFormat( "yyyy-MM-dd ");

                String   d   =   "2005-11-26 ";

                Calendar   c   =   Calendar.getInstance();

c.setTime(df.parse(d));

                //System.out.println(c.get                (Calendar.WEEK_OF_MONTH));

System.out.println(c.get(Calendar.DAY_OF_WEEK));

1.

以某天(a)爲基準,計算n天(b)以後是星期幾:

假設該天爲星期m,則n天以後是星期q:

   q = m + (n % 7)

2.

一年有365天,2001年的今天是星期2, 2002年的今天是:

    2 + 365 % 7 = 2 + 1 = 3, 不信你查日曆表。

由於 365 = 7 * x + 1, 所以,每過一年的同月同日星期數便加1。

3.

閏年有366天,所以若是月份大於2,則每過一年的同月同日星期數除了要加1,還要再加間隔的閏年數。

4.

每四年有一個閏年,每一百年要減去一個閏年,每四百年要加回一個閏年。

所以,今天是:

    (7 - 1) / 4 = 1

    (2 + (7 - 1) + 1) % 7 = 9 % 7 = 2, 不信你在窗口右下角的時間上雙擊鼠標看看是否是星期二。

5.

只要還有一點數學常識,星期的計算公式便可推導出來了。

遍歷概念

 所謂遍歷(Traversal)是指沿着某條搜索路線,依次對樹中每一個結點均作一次且僅作一次訪問。訪問結點所作的操做依賴於具體的應用問題。

 遍歷是二叉樹上最重要的運算之一,是二叉樹上進行其它運算之基礎。

遍歷方案

1.遍歷方案

 從二叉樹的遞歸定義可知,一棵非空的二叉樹由根結點及左、右子樹這三個基本部分組成。所以,在任一給定結點上,能夠按某種次序執行三個操做:

 (1)訪問結點自己(N),

 (2)遍歷該結點的左子樹(L),

 (3)遍歷該結點的右子樹(R)。

以上三種操做有六種執行次序:

 NLR、LNR、LRN、NRL、RNL、RLN。

注意:

 前三種次序與後三種次序對稱,故只討論先左後右的前三種次序。

2.三種遍歷的命名

 根據訪問結點操做發生位置命名:

  ① NLR:前序遍歷(PreorderTraversal亦稱(先序遍歷))

——訪問結點的操做發生在遍歷其左右子樹以前。

  ② LNR:中序遍歷(InorderTraversal)

——訪問結點的操做發生在遍歷其左右子樹之中(間)。

  ③ LRN:後序遍歷(PostorderTraversal)

——訪問結點的操做發生在遍歷其左右子樹以後。

注意:

 因爲被訪問的結點必是某子樹的根,因此N(Node)、L(Left subtlee)和R(Right subtree)又可解釋爲根、根的左子樹和根的右子樹。NLR、LNR和LRN分別又稱爲先根遍歷、中根遍歷和後根遍歷。

遍歷算法

1.中序遍歷的遞歸算法定義:

 若二叉樹非空,則依次執行以下操做:

         (1)遍歷左子樹;

         (2)訪問根結點;

         (3)遍歷右子樹。

 

2.先序遍歷的遞歸算法定義:

 若二叉樹非空,則依次執行以下操做:

         (1) 訪問根結點;

         (2) 遍歷左子樹;

         (3) 遍歷右子樹。

3.後序遍歷得遞歸算法定義:

 若二叉樹非空,則依次執行以下操做:

         (1)遍歷左子樹;

         (2)遍歷右子樹;

         (3)訪問根結點。

4.中序遍歷的算法實現

 用二叉鏈表作爲存儲結構,中序遍歷算法可描述爲:

void InOrder(BinTree T)

        { //算法裏①~⑥是爲了說明執行過程加入的標號

① if(T) { // 若是二叉樹非空

②    InOrder(T->lchild);

③    printf("%c",T->data); // 訪問結點

④    InOrder(T->rchild);

⑤  }

⑥ } // InOrder

把str1和str2合併成一個新的String [] 並去掉其中重複的部分

String [] str1={"1001","1002","1003"};

String [] str2={"1001","1005","1010","1003"};

Vector v = new Vector();

for (int i = 0; i < str1.length; i ++) {

if (!v.contains(str1[i])) {

v.add(str1[i]);

}

}

for (int i = 0; i < str2.length; i ++) {

if (!v.contains(str2[i])) {

v.add(str2[i]);

}

}

String[] str1= new String[]{"1001","1002","1003"};

String[] str2= new String[]{"1001","1005","1010","1003"};

HashMap hp = new HashMap();

for(int i = 0 ; i < str1.length;i++){

hp.put(str1[i],"");

}

for(int i = 0 ; i < str2.length;i++){

hp.put(str2[i],"");

}

 

import java.util.*;

public class test1{

public static void main(String [] args){

String [] str1={"1001","1002","1003"};

String [] str2={"1001","1005","1010","1003"};

HashSet sh = new HashSet();

for(int i=0;i<str1.length;i++)

sh.add(str1[i]);

for(int j=0;j<str2.length;j++)

sh.add(str2[j]);

Iterator i =sh.iterator();

while(i.hasNext()){

System.out.println(i.next());

}}}

手機號碼

import java.util.regex.Matcher;

  import java.util.regex.Pattern;

  public class ClassPathResource {

  public static boolean isMobileNO(String mobiles){

  Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");

  Matcher m = p.matcher(mobiles);

  System.out.println(m.matches()+"---");

  return m.matches();

  }

  public static void main(String[] args) throws IOException {

  System.out.println(ClassPathResource.isMobileNO("12016155153"));

  }}

第二種方法:

  import java.util.regex.Matcher;

  import java.util.regex.Pattern;

  String value="手機號";

  String regExp = "^[1]([3][0-9]{1}|59|58|88|89)[0-9]{8}$";

  Pattern p = Pattern.compile(regExp);

  Matcher m = p.matcher(value);

return m.find();//Boolean

sturts與jsp結合

struts2中的Action接收表單傳遞過來的參數有3種方法:

如,登錄表單login.jsp:

<form action="login" method="post" name="form1">

用戶名:<s:textfield name="username"/><br/>

密碼:<s:password name="password"/><br/>

<s:submit value="提交"/>

</form>

1.在Action類中定義表單屬性,二者屬性名稱必須一致。提供setter,getter方法。便可接收到表單傳過來的參數.

這種接收參數的方法,方便簡單,可是結構性不是很好,且當表單傳遞來的參數不少的時候,整個Action類中充斥着setter,getter方法,程序結構不是很美觀。

2.把表單傳遞過來的參數封裝成一個類,而後調用其中的屬性.

如,把login.jsp頁面要傳來的參數進行封裝

private String username;

private String password;

public String getUsername() {

return username;

 }

public void setUsername(String username) {

  this.username = username;

 }

public String getPassword() {

return password;

 }

public void setPassword(String password) {

  this.password = password;

 }

而後再Action方法中,定義該類的對象就能夠了,如

public class loginAction extends ActionSupport{

private Users users;

public Users getUsers(){

return users;

}

public void setUsers(Users users){

this.users=users;

}

/*

傳遞過來的參數都封裝在users中了,用getter方法取值就能夠了

*/

}

經過這種方法傳值,還必須在jsp頁面作一下處理,login.jsp中from1的屬性名應該改爲這樣:

登錄表單login.jsp:

<form action="login" method="post" name="form1">

用戶名:<s:textfield name="users.username"/><br/>

密碼:<s:password name="users.password"/><br/>

<s:submit value="提交"/>

</form>

這種方法,在struts開發中是很經常使用的一種方法!

3.經過實現ModelDriven接口接收表單數據

首先Action類必須實現ModelDriven接口,一樣把表單傳來的數據封裝起來,Action類中必須實例化該對象,而且要重寫getModel()方法

public class loginAction extends ActionSupport implements ModelDriven<Users>{

private Users users =new Users();

public Users getModel(){

return users;

}

/*

表單傳來的參數封裝在users對象中

表單屬性名不須要加上引用users對象,直接傳參數名

*/

}

hibernate與jdbc優缺點

1.hibernate和jdbc主要區別就是,hibernate先檢索緩存中的映射對象( 即hibernate操做的是對象),而jdbc則是直接操做數據庫.

2.Hibernate是JDBC的輕量級的對象封裝,它是一個獨立的對象持久層框架,和App Server,和EJB沒有什麼必然的聯繫。Hibernate能夠用在任何JDBC可使用的場合

3.Hibernate是一個和JDBC密切關聯的框架,因此Hibernate的兼容性和JDBC驅動,和數據庫都有必定的關係,可是和使用它的Java程序,和App Server沒有任何關係,也不存在兼容性問題。

還有一點,正確的使用JDBC技術,它的效率必定比hibernate要好,由於hibernate是基於jdbc的技術.

hibernate是jdbc的輕量級封裝,包括jdbc的與數據庫的鏈接(用hibernate.property的配置文件實現固然本質是封裝了jdbc的forname),和查詢,刪除等代碼,都用面向對象的思想用代碼聯繫起來,hibernate經過hbm 配置文件把po類的字段和數據庫的字段關聯起來好比數據庫的id,在po類中就是pravite Long id;

public Long getId()

public setId(Long id);而後hql語句也是面向對象的,它的查詢語句不是查詢數據庫而是查詢類的,這些實現的魔法就是xml文件,其實hibernate=封裝的jdbc+xml文件

數據庫優化

設計數據庫的優化措施。這要看你對預期的數據量的一個估計,不一樣的數據量有不一樣的策略。100萬數據的表和1億的數據表的策略確定是不同的。一樣的設計,查詢語句不同,效果可能也不同。

比較經常使用的數據庫設計方面的處理措施是,

一、索引的創建,一張表,若是有一些常常查詢的字段上,要創建索引。好比庫存表,你會常常按廠家查詢,那麼在廠家這個字段上就要創建索引。如樓上所說,在某些時刻,要採起違反第3範式的一些數據庫設計手段。

二、分庫,分表技術。能夠按業務層次,或者日期、廠家、地區等字段,對錶進行橫向或縱向的分割。把事務表和數據倉庫表分開等。

三、事實上,對於系統的優化,從數據庫自己的優化,數據庫表的設計,以及應用程序的設計上,關聯是很密切的。好比在數據庫,能夠把臨時表,或者一些日誌類的表放在內存盤中。在程序設計上,採用緩存機制,分佈式數據庫機制等等,都是提升系統響應能力的方法。

數據庫的優化和你的業務、流量、硬件是分不開的

業務:主要指查詢的方式,讀寫權重,表大小

流量:主要考慮併發請求數

硬件:主要是內存、磁盤、CPU的環境

從業務角度講:

簡單查詢只須要對查詢條件的列創建索引

須要排序的查詢就應該使用符合索引,使排序從文件系統轉移到內存中

讀寫要考慮效率和鎖的問題,若是兩方面都比較突出,能夠考慮創建主從,主服務器作寫操做,從服務器作讀,讀的壓力大,能夠創建多個從

表的大小直接影響查詢效率,單個表的數據量有幾十萬效率就很低了,能夠考慮hash分表,利用表中的某個比較符合業務的字段作分表

如業務須要處理訂單之類,須要完整的處理過程,應該選擇帶有事務處理的存儲引擎,如mysql 的 innodb

從流量角度講:

最主要的是選擇適合的存儲引擎,mysql的myisam的表級鎖會對引擎適合併發較低的環境,但查詢速度較快,隨着併發的增長,效率支線降低,innodb的行級鎖查詢速度沒有myisam快,可是極大的減小了鎖,是併發的效率大大增長,對高併發的環境是不二選擇

從硬件角度講:

內存要合理分配,尤爲是事務型的存儲引擎,建議內存從小到大的逐漸調整,過大的使用內存會致使使用swap

磁盤的io一般是數據庫的主要瓶頸,在你表設計已經比較合理的狀況下,io效率依然低下,能夠考慮分磁盤存儲數據,最好可使用raid負載磁盤陣列,用多個磁盤分擔io的壓力

這個年代沒有人用單核的處理器,因此多核處理器是最佳選擇

總的來講數據庫的優化由sql、內存、磁盤IO、表結構、存儲引擎等幾個主要方面,優化是個過程,沒有標準,具體問題具體分析

相關文章
相關標籤/搜索