5、String是最基本的數據類型嗎?
基本數據類型包括byte、int、char、long、float、double、boolean和short。
java.lang.String類是final類型的,因此不可以繼承這個類、不能修改這個類。為了提高效率節省空間,我們應該用StringBuffer類
6、int 和 Integer 有什么區別
Java 提供兩種不同的類型:引用類型和原始類型(或內置類型)。Int是java的原始數據類型,Integer是java為int提供的封裝類。Java為每個原始類型提供了封裝類。
引用類型和原始類型的行為完全不同,並且它們具有不同的語義。引用類型和原始類型具有不同的特征和用法,它們包括:大小和速度問題,這種類型以哪種類型的數據結構存儲,當引用類型和原始類型用作某個類的實例數據時所指定的缺省值。對象引用實例變量的缺省值為 null,而原始類型實例變量的缺省值與它們的類型有關。
7、String 和StringBuffer的區別
JAVA平台提供了兩個類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數據。這個String類提供了數值不可改變的字符串。而這個StringBuffer類提供的字符串進行修改。當你知道字符數據要改變的時候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers來動態構造字符數據。
8、運行時異常與一般異常有何異同?
異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。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)使用明確的方法名,也可以在名字的起始和結束處使用通配符*。
81、現有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; }
87、JAVA實現一種排序
答:用插入法進行排序代碼如下
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",輸入"我ABC漢DEF",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億的數據表的策略肯定是不一樣的。同樣的設計,查詢語句不一樣,效果可能也不一樣。
比較常用的數據庫設計方面的處理措施是,
1、索引的建立,一張表,如果有一些經常查詢的字段上,要建立索引。比如庫存表,你會經常按廠家查詢,那么在廠家這個字段上就要建立索引。如樓上所說,在某些時刻,要采取違反第3范式的一些數據庫設計手段。
2、分庫,分表技術。可以按業務層次,或者日期、廠家、地區等字段,對表進行橫向或縱向的分割。把事務表和數據倉庫表分開等。
3、事實上,對於系統的優化,從數據庫本身的優化,數據庫表的設計,以及應用程序的設計上,關聯是很密切的。比如在數據庫,可以把臨時表,或者一些日志類的表放在內存盤中。在程序設計上,采用緩存機制,分布式數據庫機制等等,都是提高系統響應能力的方法。
數據庫的優化和你的業務、流量、硬件是分不開的
業務:主要指查詢的方式,讀寫權重,表大小
流量:主要考慮並發請求數
硬件:主要是內存、磁盤、CPU的環境
從業務角度講:
簡單查詢只需要對查詢條件的列建立索引
需要排序的查詢就應該使用符合索引,使排序從文件系統轉移到內存中
讀寫要考慮效率和鎖的問題,如果兩方面都比較突出,可以考慮建立主從,主服務器做寫操作,從服務器做讀,讀的壓力大,可以建立多個從
表的大小直接影響查詢效率,單個表的數據量有幾十萬效率就很低了,可以考慮hash分表,利用表中的某個比較符合業務的字段做分表
如業務需要處理訂單之類,需要完整的處理過程,應該選擇帶有事務處理的存儲引擎,如mysql 的 innodb
從流量角度講:
最主要的是選擇適合的存儲引擎,mysql的myisam的表級鎖會對引擎適合並發較低的環境,但查詢速度較快,隨着並發的增加,效率支線下降,innodb的行級鎖查詢速度沒有myisam快,但是極大的減少了鎖,是並發的效率大大增加,對高並發的環境是不二選擇
從硬件角度講:
內存要合理分配,尤其是事務型的存儲引擎,建議內存從小到大的逐漸調整,過大的使用內存會導致使用swap
磁盤的io通常是數據庫的主要瓶頸,在你表設計已經比較合理的情況下,io效率依然低下,可以考慮分磁盤存儲數據,最好可以使用raid負載磁盤陣列,用多個磁盤分擔io的壓力
這個年代沒有人用單核的處理器,所以多核處理器是最佳選擇
總的來說數據庫的優化由sql、內存、磁盤IO、表結構、存儲引擎等幾個主要方面,優化是個過程,沒有標准,具體問題具體分析