1、一個".java"源文件裏可否夠包含多個類(不是內部類)?有什麼限制?.....2html
3、說說&和&&的差異。......................................................................................2java
4、在JAVA中怎樣跳出當前的多重嵌套循環?...................................................2node
5、switch語句是否能做用在byte上,是否能做用在long上,是否能做用在String上?...2mysql
6、short s1 =1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?..................2c++
7、char型變量中能不能存貯一箇中文漢字?爲何?............................................2git
9、請設計一個一百億的計算器..........................................................................2面試
10、使用finalkeyword修飾一個變量時,是引用不能變,仍是引用的對象不能變?2
11、"=="和equals方法到底有什麼差異?...........................................................2
12、靜態變量和實例變量的差異?.....................................................................2
13、可否夠從一個static方法內部發出對非static方法的調用?........................2
15、Math.round(11.5)等於多少?Math.round(-11.5)等於多少?...............................2
16、如下的代碼有什麼不妥之處?.......................................................................2
17、請說出做用域public,private,protected,以及不寫時的差異.......................2
18、Overload和Override的差異。Overloaded的方法可否夠改變返回值的類型?2
19、構造器Constructor是否可被override?..........................................................2
21、寫clone()方法時,一般都有一行代碼,是什麼?.........................................2
22、面向對象的特徵有哪些方面.........................................................................2
23、java中實現多態的機制是什麼?..................................................................2
24、abstractclass和interface有什麼差異?...........................................................2
25、abstract的method是否可同一時候是static,是否可同一時候是native,是否可同一時候是synchronized?2
26、什麼是內部類?StaticNested Class 和 Inner Class的不一樣。..........................2
27、內部類可以引用它的包括類的成員嗎?有沒有什麼限制?...........................2
29、super.getClass()方法調用.....................................................................2
30、String是最主要的數據類型嗎?.....................................................................2
31、String s = "Hello";s = s + " world!";這兩行代碼運行後,原始的String對象中的內容究竟變了沒有? 2
32、可否夠繼承String類?..............................................................................2
33、String s =new String("xyz");建立了幾個String Object?兩者之間有什麼差異? 2
34、String和StringBuffer的差異.......................................................................2
35、怎樣把一段逗號切割的字符串轉換成一個數組?...........................................2
36、數組有沒有length()這種方法?String有沒有length()這種方法?...................2
37、如下這條語句一共建立了多少個對象:Strings="a"+"b"+"c"+"d";.................2
39、如下的程序代碼輸出的結果是多少?...........................................................2
40、final,finally, finalize的差異。......................................................................2
41、執行時異常與通常異常有何異同?..............................................................2
42、error和exception有什麼差異?.....................................................................2
43、Java中的異常處理機制的簡單原理和應用。................................................2
44、請寫出你最多見到的5個runtimeexception。...............................................2
47、sleep()和 wait() 有什麼差異?.....................................................................2
48、同步和異步有何異同,在什麼狀況下分別使用他們?舉例說明。.................2
49.如下兩個方法同步嗎?(本身發明)...........................................................2
50、多線程有幾種實現方法?同步有幾種實現方法?.............................................2
51、啓動一個線程是用run()仍是start()?............................................................2
52、當一個線程進入一個對象的一個synchronized方法後,其餘線程是否可進入此對象的其餘方法? 2
53、線程的基本概念、線程的基本狀態以及狀態之間的關係...............................2
54、簡述synchronized和java.util.concurrent.locks.Lock的異同?.......................2
55、設計4個線程,當中兩個線程每次對j添加1,另外兩個線程對j每次下降1。寫出程序。 2
57、介紹Collection框架的結構..........................................................................2
58、Collection框架中實現比較要實現什麼接口..................................................2
59、ArrayList和Vector的差異............................................................................2
60、HashMap和Hashtable的差異.......................................................................2
62、List, Set,Map是否繼承自Collection接口?....................................................2
63、List、Map、Set三個接口,存取元素時,各有什麼特色?............................2
64、說出ArrayList,Vector,LinkedList的存儲性能和特性......................................2
65、去掉一個Vector集合中反覆的元素..............................................................2
66、Collection和 Collections的差異。...............................................................2
67、Set裏的元素是不能反覆的,那麼用什麼方法來區分反覆與否呢?是用==仍是equals()?它們有何差異? 2
68、你所知道的集合類都有哪些?主要方法?....................................................2
69、兩個對象值一樣(x.equals(y)== true),但卻可有不一樣的hash code,這句話對不正確? 2
71、說出一些常用的類,包,接口,請各舉5個................................................2
72、java中有幾種類型的流?JDK爲每種類型的流提供了一些抽象類以供繼承,請說出他們各自是哪些類? 2
73、字節流與字符流的差異................................................................................2
74、什麼是java序列化,怎樣實現java序列化?或者請解釋Serializable接口的做用。 2
75、描寫敘述一下JVM載入class文件的原理機制?...................................................2
76、heap和stack有什麼差異。..........................................................................2
77、GC是什麼?爲何要有GC?.......................................................................2
78、垃圾回收的長處和原理。並考慮2種回收機制。.........................................2
80、何時用assert。.....................................................................................2
81、java中會存在內存泄漏嗎,請簡單描寫敘述。....................................................2
82、能不能本身寫個類,也叫java.lang.String?.................................................2
4、有一個字符串,當中包括中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。 2
5、說明生活中遇到的二叉樹,用java實現二叉樹..............................................2
6、從相似例如如下的文本文件裏讀取出所有的姓名,並打印出反覆的姓名和反覆的次數,並按反覆次數排序: 2
7、寫一個Singleton出來。................................................................................2
10、排序都有哪幾種方法?請列舉。用JAVA實現一個高速排序。.....................2
11、有數組a[n],用java代碼將數組元素順序顛倒.............................................2
12.金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千零一拾一元整)輸出。 2
1.推斷第二個日期比第一個日期大....................................................................2
3、HTML的 form 提交以前怎樣驗證數值文本框的內容全部爲數字?不然的話提示用戶並終止提交? 2
4、請寫出用於校驗HTML文本框中輸入的內容全部爲數字的javascript代碼......2
5、說說你用過那些ajax技術和框架,說說它們的差異.......................................2
2、HTTP請求的GET與POST方式的差異.........................................................2
3、解釋一下什麼是servlet;.................................................................................2
4、說一說Servlet的生命週期?...........................................................................2
6、SERVLET API中forward()與redirect()的差異?...........................................2
7、什麼狀況下調用doGet()和doPost()?............................................................2
8、Request對象的主要方法:.............................................................................2
9、forward和redirect的差異.............................................................................2
10、request.getAttribute()和 request.getParameter() 有何差異?............................2
11.jsp有哪些內置對象?做用各自是什麼?分別有什麼方法?..............................2
12.jsp有哪些動做?做用各自是什麼?..................................................................2
14.JSP中動態INCLUDE與靜態INCLUDE的差異?.........................................2
15、兩種跳轉方式各自是什麼?有什麼差異?........................................................2
16、頁面間對象傳遞的方法................................................................................2
17、JSP和Servlet有哪些一樣點和不一樣點,他們之間的聯繫是什麼?................2
18、MVC的各個部分都有那些技術來實現?怎樣實現?........................................2
1、用兩種方式依據部門號從高到低,工資從低到高列出每個員工的信息。........2
2、列出各個部門中工資高於本部門的平均工資的員工數和部門號,並按部門號排序 2
3、存儲過程與觸發器必須講,經常被面試到?....................................................2
4、數據庫三範式是什麼?...................................................................................2
5、說出一些數據庫優化方面的經驗?..................................................................2
6、union和union all有什麼不一樣?.......................................................................2
8.用一條SQL語句查詢出每門課都大於80分的學生姓名..................................2
9.所有部門之間的比賽組合................................................................................2
10.每個月份的發生額都比101科目多的科目......................................................2
11.統計每一年每個月的信息......................................................................................2
12.顯示文章標題,發帖人、最後回覆時間..........................................................2
13.刪除除了id號不一樣,其它都一樣的學生冗餘信息.............................................2
14.航空網的幾個航班查詢題:...........................................................................2
15.查出比經理薪水還高的員工信息:.................................................................2
16、求出小於45歲的各個老師所帶的大於12歲的學生人數...............................2
17.求出發帖最多的人:......................................................................................2
19、一個用戶具備多個角色,請查詢出該表中具備該用戶的所有角色的其它用戶。 2
21、註冊Jdbc驅動程序的三種方式....................................................................2
22、用JDBC怎樣調用存儲過程.........................................................................2
23、JDBC中的PreparedStatement相比Statement的優勢.....................................2
24.寫一個用jdbc鏈接並訪問oracle數據的程序代碼..........................................2
25、Class.forName的做用?爲何要用?..............................................................2
26、大數據量下的分頁解決方法。.....................................................................2
27、用 JDBC 查詢學生成績單,把主要代碼寫出來(考試機率極大)................2
28、這段代碼有什麼不足之處?...........................................................................2
29、說出數據鏈接池的工做機制是什麼?.............................................................2
30、爲何要用ORM? 和 JDBC 有何不同?.................................................2
1、xml有哪些解析技術?差異是什麼?.................................................................2
2、你在項目中用到了xml技術的哪些方面?怎樣實現的?....................................2
3、用jdom解析xml文件時怎樣解決中文問題?怎樣解析?...................................2
4、編程用JAVA解析XML的方式......................................................................2
5、XML文檔定義有幾種形式?它們之間有何本質差異?解析XML文檔有哪幾種方式? 2
1、談談你對Struts的理解。...............................................................................2
2、談談你對Hibernate的理解。.........................................................................2
4、你對Spring的理解。....................................................................................2
5、談談Struts中的Actionservlet。.....................................................................2
6、Struts優缺點 長處: 1.實現MVC模式,結構清晰,使開發人員僅僅關注業務邏輯的實現. 2
7、STRUTS的應用(如STRUTS架構).................................................................2
8、說說struts1與struts2的差異。......................................................................2
9、hibernate中的update()和saveOrUpdate()的差異,session的load()和get()的差異。 2
10、簡述Hibernate和 JDBC 的優缺點?怎樣書寫一個 one to many配置文件..2
11、iBatis與Hibernate有什麼不一樣?....................................................................2
12、寫Hibernate的一對多和多對一雙向關聯的orm配置?...................................2
9、hibernate的inverse屬性的做用?.....................................................................2
13、在DAO中怎樣體現DAO設計模式?............................................................2
14、spring+Hibernate中託付方案怎麼配置?........................................................2
15、spring+Hibernate中託付方案怎麼配置?........................................................2
17.介紹一下Hibernate的二級緩存......................................................................2
20、什麼是spring的IOC AOP.........................................................................2
21、STRUTS的工做流程!................................................................................2
22、spring與EJB的差異!!............................................................................2
2、j2ee常用的設計模式?說明工廠模式。.........................................................2
3、開發中都用到了那些設計模式?用在什麼場合?...............................................2
1、BS與CS的聯繫與差異。..............................................................................2
2、應用server與WEBSERVER的差異?..........................................................2
3、應用server有那些?.....................................................................................2
5、J2EE是技術仍是平臺仍是框架?什麼是J2EE.............................................2
6、請對下面在J2EE中常用的名詞進行解釋(或簡單描寫敘述)...................................2
7、怎樣給weblogic指定大小的內存?..................................................................2
8、怎樣設定的weblogic的熱啓動模式(開發模式)與產品公佈模式?.....................2
9、怎樣啓動時不需輸入username與password?..............................................................2
12、在weblogic中公佈ejb需涉及到哪些配置文件..............................................2
13、怎樣在weblogic中進行ssl配置與client的認證配置或說說j2ee(標準)進行ssl的配置? 2
14、怎樣查看在weblogic中已經公佈的EJB?......................................................2
2、簡要講一下 EJB 的 7 個Transaction Level?.................................................2
3、EJB與JAVA BEAN的差異?........................................................................2
4、EJB包含(SessionBean,EntityBean)說出他們的生命週期,及怎樣管理事務的? 2
5、EJB容器提供的服務.....................................................................................2
8、客服端調用EJB對象的幾個基本步驟............................................................2
1、WEBSERVICE名詞解釋。JSWDL開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。 2
2、CORBA是什麼?用途是什麼?.........................................................................2
4、LINUX下線程,GDI類的解釋。..................................................................2
6、四種會話跟蹤技術........................................................................................2
7、簡述邏輯操做(&,|,^)與條件操做(&&,||)的差異。............................................2
1、請用英文簡介一下本身..........................................................................2
2、請把http://tomcat.apache.org/ 首頁的這一段話用中文翻譯一下?.....................2
3、美資軟件公司JAVAproject師電話面試題目......................................................2
這套面試題主要目的是幫助那些尚未java軟件開發實際工做經驗,而正在努力尋找java軟件開發工做的朋友在筆試時更好地贏得筆試和麪試。由於這套面試題涉及的範圍很是泛,很是廣,很是雜,你們不可能一天兩天就看完和學完這套面試寶典,即便你已經學過了有關的技術,那麼至少也需要一個月的時間才幹消化和掌握這套面試寶典,因此,你們應該早做準備,從拿到這套面試寶典之日起,就要堅持在天天閒暇之餘學習當中幾道題目,日積月累,等到出去面試時,一切都水到渠成,面試時就天然會遊刃有餘了。
答題時,先答是什麼,再答有什麼做用和要注意什麼(這部分最重要,展示本身的心得)
答案的段落分別,井井有條,條理清晰都很重要,從這些表面的東西也可以看出一我的的習慣、辦事風格、條理等。
要講你作出答案的思路過程,或者說你記住答案的思想都寫下來。把答題想着是辯論賽。答題就是給別人講道理、擺事實。答題不侷限於什麼格式和形式,就是要將本身的學識展示出來!
別因爲人家題目原本就模棱兩可,你就內心膽怯和沒底氣了,不敢回答了。你要大膽地指出對方題目很是模糊和你的觀點,不要把面試官想得有多高,事實上他和你就是差點兒相同的,你想一想,假設他把你招進去了,大家之後就是同事了,可不是差點兒相同的嗎?
關於就業薪水,假設你是應屆生,那不能要高工資,比如大餅的故事,沒有文憑還想拿高工資,就去中關村缺什麼補什麼吧!少數人基礎確實很是好,在校期間確實又作過一些項目,那仍然是可以要到相對高的工資的。
1. Java基礎部分
基礎部分的順序:基本的語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語法,集合的語法,io的語法,虛擬機方面的語法。
1、一個".java"源文件裏可否夠包含多個類(不是內部類)?有什麼限制?
可以有多個類,但僅僅能有一個public的類,並且public的類名必須與文件名稱相一致。
2、Java有沒有goto?
java中的保留字,現在沒有在java中使用。
3、說說&和&&的差異。
&和&&都可以用做邏輯與的運算符,表示邏輯與(and),當運算符兩邊的表達式的結果都爲true時,整個運算結果才爲true,不然,僅僅要有一方爲false,則結果爲false。
&&還具備短路的功能,即假設第一個表達式爲false,則再也不計算第二個表達式,好比,對於if(str != null&& !str.equals(「」))表達式,當str爲null時,後面的表達式不會運行,因此不會出現NullPointerException假設將&&改成&,則會拋出NullPointerException異常。If(x==33 &++y>0) y會增加,If(x==33 && ++y>0)不會增加
&還可以用做位運算符,當&操做符兩邊的表達式不是boolean類型時,&表示按位與操做,咱們一般使用0x0f來與一個整數進行&運算,來獲取該整數的最低4個bit位,好比,0x31 & 0x0f的結果爲0x01。
備註:這道題先說二者的共同點,再說出&&和&的特殊之處,並列舉一些經典的樣例來代表本身理解透徹深刻、實際經驗豐富。 f
4、在JAVA中怎樣跳出當前的多重嵌套循環?
在Java中,要想跳出多重循環,可以在外面的循環語句前定義一個標號,而後在裏層循環體的代碼中使用帶有標號的break語句,就能夠跳出外層循環。好比,
ok:
for(int i=0;i<10;i++) {
for(int j=0;j<10;j++) {
System.out.println(「i=」 + i + 「,j=」 + j);
if(j == 5) break ok;
}
}
另外,我我的一般並不使用標號這樣的方式,而是讓外層的循環條件表達式的結果可以受到裏層循環體代碼的控制,好比,要在二維數組中查找到某個數字。
int arr[][] ={{1,2,3},{4,5,6,7},{9}};
boolean found = false;
for(int i=0;i<arr.length&& !found;i++) {
for(int j=0;j<arr[i].length;j++){
System.out.println(「i=」 + i + 「,j=」 + j);
if(arr[i][j] ==5) {
found = true;
break;
}
}
}
5、switch語句是否能做用在byte上,是否能做用在long上,是否能做用在String上?
在switch(expr1)中,expr1僅僅能是一個整數表達式或者枚舉常量(更大字體),整數表達式可以是int基本類型或Integer包裝類型,由於,byte,short,char都可以隱含轉換爲int,因此,這些類型以及這些類型的包裝類型也是可以的。顯然,long和String類型都不符合switch的語法規定,並且不能被隱式轉換成int類型,因此,它們不能做用於swtich語句中。
6、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編譯器會對它進行特殊處理,所以可以正確編譯。
7、char型變量中能不能存貯一箇中文漢字?爲何?
char型變量是用來存儲Unicode編碼的字符的,unicode編碼字符集中包括了漢字,因此,char型變量中固然可以存儲漢字啦。只是,假設某個特殊的漢字沒有被包括在unicode編碼字符集中,那麼,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼佔用兩個字節,因此,char類型的變量也是佔用兩個字節。
備註:後面一部分回答儘管不是在正面回答題目,但是,爲了展示本身的學識和表現本身對問題理解的透徹深刻,可以回答一些相關的知識,作到知無不言,言無不盡。
8、用最有效率的方法算出2乘以8等於幾?
2 << 3,
因爲將一個數左移n位,就至關於乘以了2的n次方,那麼,一個數乘以8僅僅要將其左移3位就能夠,而位運算cpu直接支持的,效率最高,因此,2乘以8等於幾的最效率的方法是2 << 3。
9、請設計一個一百億的計算器
首先要明確這道題目的考查點是什麼,一是你們首先要對計算機原理的底層細節要清楚、要知道加減法的位運算原理和知道計算機中的算術運算會發生越界的狀況,二是要具有必定的面向對象的設計思想。
首先,計算機中用固定數量的幾個字節來存儲的數值,因此計算機中能夠表示的數值是有必定的範圍的,爲了便於解說和理解,咱們先以byte類型的整數爲例,它用1個字節進行存儲,表示的最大數值範圍爲-128到+127。-1在內存中相應的二進制數據爲11111111,假設兩個-1相加,不考慮Java運算時的類型提高,運算後會產生進位,二進制結果爲1,11111110,由於進位後超過了byte類型的存儲空間,因此進位部分被捨棄,即終於的結果爲11111110,也就是-2,這正好利用溢位的方式實現了負數的運算。-128在內存中相應的二進制數據爲10000000,假設兩個-128相加,不考慮Java運算時的類型提高,運算後會產生進位,二進制結果爲1,00000000,由於進位後超過了byte類型的存儲空間,因此進位部分被捨棄,即終於的結果爲00000000,也就是0,這種結果顯然不是咱們指望的,這說明計算機中的算術運算是會發生越界狀況的,兩個數值的運算結果不能超過計算機中的該類型的數值範圍。由於Java中涉及表達式運算時的類型本身主動提高,咱們沒法用byte類型來作演示這種問題和現象的實驗,你們能夠用如下一個使用整數作實驗的樣例程序體驗一下:
int a = Integer.MAX_VALUE;
int b = Integer.MAX_VALUE;
int sum = a + b;
System.out.println(「a=」+a+」,b=」+b+」,sum=」+sum);
先不考慮long類型,由於int的正數範圍爲2的31次方,表示的最大數值約等於2*1000*1000*1000,也就是20億的大小,因此,要實現一個一百億的計算器,咱們得本身設計一個類可以用於表示很是大的整數,並且提供了與另一個整數進行加減乘除的功能,大概功能例如如下:
()這個類內部有兩個成員變量,一個表示符號,還有一個用字節數組表示數值的二進制數
()有一個構造方法,把一個包括有多位數值的字符串轉換到內部的符號和字節數組中
()提供加減乘除的功能
public class BigInteger{
int sign;
byte[] val;
public Biginteger(String val) {
sign = ;
val = ;
}
public BigInteger add(BigInteger other) {
}
public BigInteger subtract(BigInteger other) {
}
public BigInteger multiply(BigInteger other){
}
public BigInteger divide(BigInteger other){
}
}
備註:要想寫出這個類的完整代碼,是很是複雜的,假設有興趣的話,可以參看jdk中自帶的java.math.BigInteger類的源代碼。面試的人也知道誰都不可能在短期內寫出這個類的完整代碼的,他要的是你是否有這方面的概念和意識,他最重要的仍是考查你的能力,因此,你不要因爲本身沒法寫出完整的終於結果就放棄答這道題,你要作的就是你比別人寫得多,證實你比別人強,你有這方面的思想意識就可以了,畢竟別人可能連題目的意思都看不懂,什麼都沒寫,你要勇於答這道題,即便僅僅答了一部分,那也與那些什麼都不懂的人差異出來,拉開了距離,算是矮子中的高個,機會固然就屬於你了。另外,答案中的框架代碼也很是重要,體現了一些面向對象設計的功底,特別是當中的方法命名很是專業,用的英文單詞很是精準,這也是能力、經驗、專業性、英語水平等多個方面的體現,會給人留下很是好的印象,在編程能力和其它方面條件差點兒相同的狀況下,英語好除了可以使你得到不少其它機會外,薪水可以高出一千元。
10、使用finalkeyword修飾一個變量時,是引用不能變,仍是引用的對象不能變?
使用finalkeyword修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容仍是可以改變的。好比,對於例如如下語句:
final StringBuffer a=new StringBuffer("immutable");
運行例如如下語句將報告編譯期錯誤:
a=new StringBuffer("");
但是,運行例如如下語句則可以經過編譯:
a.append(" broken!");
有人在定義方法的參數時,可能想採用例如如下形式來阻止方法內部改動傳進來的參數對象:
public void method(final StringBuffer param){
}
實際上,這是辦不到的,在該方法內部仍然可以添加例如如下代碼來改動參數對象:
param.append("a");
11、"=="和equals方法到底有什麼差異?
(單獨把一個東西說清楚,而後再說清楚還有一個,這樣,它們的差異天然就出來了,混在一塊兒說,則很是難說清楚)
==操做符專門用來比較兩個變量的值是否相等,也就是用於比較變量所相應的內存中所存儲的數值是否一樣,要比較兩個基本類型的數據或兩個引用變量是否相等,僅僅能用==操做符。
假設一個變量指向的數據是對象類型的,那麼,這時候涉及了兩塊內存,對象自己佔用一塊內存(堆內存),變量也佔用一塊內存,好比Objet obj = newObject();變量obj是一個內存,new Object()是還有一個內存,此時,變量obj所相應的內存中存儲的數值就是對象佔用的那塊內存的首地址。對於指向對象類型的變量,假設要比較兩個變量是否指向同一個對象,即要看這兩個變量所相應的內存中的數值是否相等,這時候就需要用==操做符進行比較。
equals方法是用於比較兩個獨立對象的內容是否一樣,就比如去比較兩我的的長相是否一樣,它比較的兩個對象是獨立的。好比,對於如下的代碼:
String a=new String("foo");
String b=new String("foo");
兩條new語句建立了兩個對象,而後用a/b這兩個變量分別指向了當中一個對象,這是兩個不一樣的對象,它們的首地址是不一樣的,即a和b中存儲的數值是不一樣樣的,因此,表達式a==b將返回false,而這兩個對象中的內容是一樣的,因此,表達式a.equals(b)將返回true。
在實際開發中,咱們經常要比較傳遞進行來的字符串內容是否等,好比,String input = …;input.equals(「quit」),不少人稍不注意就使用==進行比較了,這是錯誤的,隨便從網上找幾個項目實戰的教學視頻看看,裏面就有大量這種錯誤。記住,字符串的比較基本上都是使用equals方法。
假設一個類沒有自定義equals方法,那麼它將繼承Object類的equals方法,Object類的equals方法的實現代碼例如如下:
boolean equals(Object o){
return this==o;
}
這說明,假設一個類沒有自定義equals方法,它默認的equals方法(從Object類繼承的)就是使用==操做符,也是在比較兩個變量指向的對象是不是同一對象,這時候使用equals和使用==會獲得一樣的結果,假設比較的是兩個獨立的對象則總返回false。假設你編寫的類但願能夠比較該類建立的兩個實例對象的內容是否一樣,那麼你必須覆蓋equals方法,由你本身寫代碼來決定在什麼狀況就能夠以爲兩個對象的內容是一樣的。
12、靜態變量和實例變量的差異?
在語法定義上的差異:靜態變量前要加statickeyword,而實例變量前則不加。
在程序執行時的差異:實例變量屬於某個對象的屬性,必須建立了實例對象,當中的實例變量纔會被分配空間,才幹使用這個實例變量。靜態變量不屬於某個實例對象,而是屬於類,因此也稱爲類變量,僅僅要程序載入了類的字節碼,不用建立不論什麼實例對象,靜態變量就會被分配空間,靜態變量就可以被使用了。總之,實例變量必須建立對象後才幹夠經過這個對象來使用,靜態變量則可以直接使用類名來引用。
好比,對於如下的程序,無論建立多少個實例對象,永遠都僅僅分配了一個staticVar變量,並且每建立一個實例對象,這個staticVar就會加1;但是,每建立一個實例對象,就會分配一個instanceVar,就能夠能分配多個instanceVar,並且每個instanceVar的值都僅僅自加了1次。
public class VariantTest{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest(){
staticVar++;
instanceVar++;
System.out.println(「staticVar=」 + staticVar + 」,instanceVar=」+ instanceVar);
}
}
備註:這個解答除了說清楚二者的差異外,最後還用一個詳細的應用樣例來講明二者的差別,體現了本身有很是好的講解問題和設計案例的能力,思惟敏捷,超過通常程序猿,有寫做能力!
13、可否夠從一個static方法內部發出對非static方法的調用?
不可以。因爲非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,才幹夠在該對象上進行方法調用,而static方法調用時不需要建立對象,可以直接調用。也就是說,當一個static方法被調用時,可能尚未建立不論什麼實例對象,假設從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪一個對象上的呢?這個邏輯沒法成立,因此,一個static方法內部發出對非static方法的調用。
14、Integer與int的差異
int是java提供的8種原始數據類型之中的一個。Java爲每個原始類型提供了封裝類,Integer是java爲int提供的封裝類。int的默認值爲0,而Integer的默認值爲null,即Integer可以區分出未賦值和值爲0的差異,int則沒法表達出未賦值的狀況,好比,要想表達出沒有參加考試和考試成績爲0的差異,則僅僅能使用Integer。在JSP開發中,Integer的默以爲null,因此用el表達式在文本框中顯示時,值爲空白字符串,而int默認的默認值爲0,因此用el表達式在文本框中顯示時,結果爲0,因此,int不適合做爲web層的表單數據的類型。
在Hibernate中,假設將OID定義爲Integer類型,那麼Hibernate就可以依據其值是否爲null而推斷一個對象是不是暫時的,假設將OID定義爲了int類型,還需要在hbm映射文件裏設置其unsaved-value屬性爲0。
另外,Integer提供了多個與整數相關的操做方法,好比,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。
15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的做用與它們的英文名稱的含義相相應,好比,ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果爲12,Math.ceil(-11.3)的結果是-11;floor的英文意義是地板,該方法就表示向下取整,Math.ceil(11.6)的結果爲11,Math.ceil(-11.6)的結果是-12;最難掌握的是round方法,它表示「四捨五入」,算法爲Math.floor(x+0.5),即將原來的數字加上0.5後再向下取整,因此,Math.round(11.5)的結果爲12,Math.round(-11.5)的結果爲-11。
16、如下的代碼有什麼不妥之處?
1. if(username.equals(「zxx」){}
2. int x = 1;
return x==1?true:false;
17、請說出做用域public,private,protected,以及不寫時的差異
這四個做用域的可見範圍例如如下表所看到的。
說明:假設在修飾的元素上面沒有寫不論什麼訪問修飾符,則表示friendly。
做用域 當前類同一package子孫類其它package
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
備註:僅僅要記住了有4種訪問權限,4個訪問範圍,而後將全選和範圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很是easy畫出上面的圖了。
18、Overload和Override的差異。Overloaded的方法可否夠改變返回值的類型?
Overload是重載的意思,Override是覆蓋的意思,也就是重寫。
重載Overload表示同一個類中可以有多個名稱一樣的方法,但這些方法的參數列表各不一樣樣(即參數個數或類型不一樣)。
重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數全然一樣,經過子類建立的實例對象調用這種方法時,將調用子類中的定義方法,這至關於把父類中定義的那個全然一樣的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,僅僅能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因爲子類可以解決父類的一些問題,不能比父類有不少其它的問題。子類方法的訪問權限僅僅能比父類的更大,不能更小。假設父類的方法是private類型,那麼,子類則不存在覆蓋的限制,至關於子類中添加了一個全新的方法。
至於Overloaded的方法可否夠改變返回值的類型這個問題,要看你倒底想問什麼呢?這個題目很是模糊。假設幾個Overloaded的方法的參數列表不同,它們的返回者類型固然也可以不同。但我預計你想問的問題是:假設兩個方法的參數列表全然同樣,可否夠讓它們的返回值不一樣來實現重載Overload。這是不行的,咱們可以用反證法來講明這個問題,因爲咱們有時候調用一個方法時也可以不定義返回結果變量,即不要關心其返回結果,好比,咱們調用map.remove(key)方法時,儘管remove方法有返回值,但是咱們一般都不會定義接收返回結果的變量,這時候假設該類中有兩個名稱和參數列表全然一樣的方法,不過返回類型不一樣,java就沒法肯定編程者倒底是想調用哪一個方法了,因爲它沒法經過返回結果類型來推斷。
override可以翻譯爲覆蓋,從字面就可以知道,它是覆蓋了一個方法並且對其重寫,以求達到不一樣的做用。對咱們來講最熟悉的覆蓋就是對接口方法的實現,在接口中通常僅僅是對方法進行了聲明,而咱們在實現時,就需要實現接口聲明的所有方法。除了這個典型的使用方法之外,咱們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意下面的幾點:
1、覆蓋的方法的標誌必須要和被覆蓋的方法的標誌全然匹配,才幹達到覆蓋的效果;
2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
4、被覆蓋的方法不能爲private,不然在其子類中僅僅是新定義了一個方法,並無對其進行覆蓋。
overload對咱們來講可能比較熟悉,可以翻譯爲重載,它是指咱們可以定義一些名稱一樣的方法,經過定義不一樣的輸入參數來區分這些方法,而後再調用時,VM就會依據不一樣的參數樣式,來選擇合適的方法運行。在使用重載要注意下面的幾點:
1、在使用重載時僅僅能經過不一樣的參數樣式。好比,不一樣的參數類型,不一樣的參數個數,不一樣的參數順序(固然,同一方法內的幾個參數類型必須不同,好比可以是fun(int,float),但是不能爲fun(int,int));
2、不能經過訪問權限、返回類型、拋出的異常進行重載;
3、方法的異常類型和數目不會對重載形成影響;
4、對於繼承來講,假設某一方法在父類中是訪問權限是priavte,那麼就不能在子類對其進行重載,假設定義的話,也僅僅是定義了一個新方法,而不會達到重載的效果。
19、構造器Constructor是否可被override?
構造器Constructor不能被繼承,所以不能重寫Override,但可以被重載Overload。
20、接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承詳細類(concrete class)?抽象類中可否夠有靜態的main方法?
接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承詳細類。抽象類中可以有靜態的main方法。
備註:僅僅要明確了接口和抽象類的本質和做用,這些問題都很是好回答,你想一想,假設你是java語言的設計者,你是否會提供這種支持,假設不提供的話,有什麼理由嗎?假設你沒有道理不提供,那答案就是確定的了。
僅僅有記住抽象類與普通類的惟一差異就是不能建立實例對象和贊成有abstract方法。
21、寫clone()方法時,一般都有一行代碼,是什麼?
clone 有缺省行爲,super.clone();因爲首先要把父類中的成員拷貝到位,而後纔是複製本身的成員。
22、面向對象的特徵有哪些方面
計算機軟件系統是現實生活中的業務在計算機中的映射,而現實生活中的業務事實上就是一個個對象協做的過程。面向對象編程就是按現實業務同樣的方式將程序代碼按一個個對象進行組織和編寫,讓計算機系統能夠識別和理解用對象方式組織和編寫的程序代碼,這樣就行把現實生活中的業務對象映射到計算機系統中。
面向對象的編程語言有,嗎等4個基本的特徵。
1封裝:
封裝是保證軟件部件具備優良的模塊性的基礎,封裝的目標就是要實現軟件部件的「高內聚、低耦合」,防止程序相互依賴性而帶來的變更影響。在面向對象的編程語言中,對象是封裝的最基本單位,面向對象的封裝比傳統語言的封裝更爲清晰、更爲有力。面向對象的封裝就是把描寫敘述一個對象的屬性和行爲的代碼封裝在一個「模塊」中,也就是一個類中,屬性用變量定義,行爲用方法進行定義,方法可以直接訪問同一個對象中的屬性。一般狀況下,僅僅要記住讓變量和訪問這個變量的方法放在一塊兒,將一個類中的成員變量全部定義成私有的,僅僅有這個類本身的方法才幹夠訪問到這些成員變量,這就基本上實現對象的封裝,就很是easy找出要分配到這個類上的方法了,就基本上算是會面向對象的編程了。把握一個原則:把對同一事物進行操做的方法和相關的方法放在同一個類中,把方法和它操做的數據放在同一個類中。
好比,人要在黑板上畫圓,這一共涉及三個對象:人、黑板、圓,畫圓的方法要分配給哪一個對象呢?因爲畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,假設將它們在類中定義成了私有的成員變量,那麼,畫圓的方法必須分配給圓,它才幹訪問到圓心和半徑這兩個屬性,人之後僅僅是調用圓的畫圓方法、表示給圓發給消息而已,畫圓這種方法不該該分配在人這個對象上,這就是面向對象的封裝性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(屬性)由這個對象本身的行爲(方法)來讀取和改變。一個更便於理解的樣例就是,司機將火車剎住了,剎車的動做是分配給司機,仍是分配給火車,顯然,應該分配給火車,因爲司機自身是不可能有那麼大的力氣將一個火車給停下來的,僅僅有火車本身才幹完畢這一動做,火車需要調用內部的離合器和剎車片等多個器件協做才幹完畢剎車這個動做,司機剎車的過程僅僅是給火車發了一個消息,通知火車要運行剎車動做而已。
抽象:
抽象就是找出一些事物的類似和共性之處,而後將這些事物歸爲一個類,這個類僅僅考慮這些事物的類似和共性之處,並且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。好比,看到一僅僅螞蟻和大象,你能夠想象出它們的一樣之處,那就是抽象。抽象包含行爲抽象和狀態抽象兩個方面。好比,定義一個Person類,例如如下:
classPerson{
String name;
int age;
}
人原本是很是複雜的事物,有很是多方面,但因爲當前系統僅僅需要了解人的姓名和年齡,因此上面定義的類中僅僅包括姓名和年齡這兩個屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標無關的細節。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,這樣涉及的內容就太多了,而是要善於劃分問題的邊界,當前系統需要什麼,就僅僅考慮什麼。
繼承:
在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容做爲本身的內容,並可以增長若干新的內容,或改動原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類本身主動共享父類數據和方法的機制,這是類之間的一種關係,提升了軟件的可重用性和可擴展性。
多態:
多態是指程序中定義的引用變量所指向的詳細類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序執行期間才肯定,即一個引用變量倒底會指向哪一個類的實例對象,該引用變量發出的方法調用到底是哪一個類中實現的方法,必須在由程序執行期間才幹決定。因爲在程序執行時才肯定詳細的類,這樣,不用改動源程序代碼,就可以讓引用變量綁定到各類不一樣的類實現上,從而致使該引用調用的詳細方法隨之改變,即不改動程序代碼就可以改變程序執行時所綁定的詳細代碼,讓程序可以選擇多個執行狀態,這就是多態性。多態性加強了軟件的靈活性和擴展性。好比,如下代碼中的UserDao是一個接口,它定義引用變量userDao指向的實例對象由daofactory.getDao()在執行的時候返回,有時候指向的是UserJdbcDao這個實現,有時候指向的是UserHibernateDao這個實現,這樣,不用改動源碼,就可以改變userDao指向的詳細類實現,從而致使userDao.insertUser()方法調用的詳細代碼也隨之改變,即有時候調用的是UserJdbcDao的insertUser方法,有時候調用的是UserHibernateDao的insertUser方法:
UserDao userDao =daofactory.getDao();
userDao.insertUser(user);
比喻:人吃飯,你看到的是左手,仍是右手?
23、java中實現多態的機制是什麼?
靠的是父類或接口定義的引用變量可以指向子類或詳細實現類的實例對象,而程序調用的方法在執行期才動態綁定,就是引用變量所指向的詳細實例對象的方法,也就是內存里正在執行的那個對象的方法,而不是引用變量的類型中定義的方法。
24、abstract class和interface有什麼差異?
含有abstract修飾符的class即爲抽象類,abstract類不能建立的實例對象。含有abstract方法的類必須定義爲abstract class,abstract class類中的方法沒必要是抽象的。abstract class類中定義抽象方法必須在詳細(Concrete)子類中實現,因此,不能有抽象構造方法或抽象靜態方法。假設的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義爲abstract類型。
接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口中的方法定義默以爲public abstract類型,接口中的成員變量類型默以爲public static final。
如下比較一下二者的語法差異:
1.抽象類可以有構造方法,接口中不能有構造方法。
2.抽象類中可以有普通成員變量,接口中沒有普通成員變量
3.抽象類中可以包括非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。
4. 抽象類中的抽象方法的訪問類型可以是public,protected和(默認類型,儘管
eclipse下不報錯,但應該也不行),但接口中的抽象方法僅僅能是public類型的,並且默認即爲public abstract類型。
5. 抽象類中可以包括靜態方法,接口中不能包括靜態方法
6. 抽象類和接口中都可以包括靜態成員變量,抽象類中的靜態成員變量的訪問類型可以隨意,但接口中定義的變量僅僅能是public static final類型,並且默認即爲public static final類型。
7. 一個類可以實現多個接口,但僅僅能繼承一個抽象類。
如下接着再說說二者在應用上的差異:
接口不少其它的是在系統架構設計方法發揮做用,主要用於定義模塊之間的通訊契約。而抽象類在代碼實現方面發揮做用,可以實現代碼的重用,好比,模板方法設計模式是抽象類的一個典型應用,若是某個項目的所有Servlet類都要用一樣的方式進行權限推斷、記錄訪問日誌和處理異常,那麼就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完畢權限推斷、記錄訪問日誌和處理異常的代碼,在各個子類中僅僅是完畢各自的業務邏輯代碼,僞代碼例如如下:
public abstract classBaseServlet extends HttpServlet{
public final void service(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException {
記錄訪問日誌
進行權限推斷
if(具備權限){
try{
doService(request,response);
}
catch(Excetpion e) {
記錄異常信息
}
}
}
protected abstract void doService(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException;
//注意訪問權限定義成protected,顯得既專業,又嚴謹,因爲它是專門給子類用的
}
public class MyServlet1 extendsBaseServlet
{
protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException
{
本Servlet僅僅處理的詳細業務邏輯代碼
}
}
父類方法中間的某段代碼不肯定,留給子類幹,就用模板方法設計模式。
備註:這道題的思路是先從總體解釋抽象類和接口的基本概念,而後再比較二者的語法細節,最後再說二者的應用差異。比較二者語法細節差異的條理是:先從一個類中的構造方法、普通成員變量和方法(包含抽象方法),靜態變量和方法,繼承性等6個方面逐一去比較回答,接着從第三者繼承的角度的回答,特別是最後用了一個典型的樣例來展示本身深厚的技術功底。
25、abstract的method是否可同一時候是static,是否可同一時候是native,是否可同一時候是synchronized?
abstract的method不可以是static的,因爲抽象的方法是要被子類實現的,而static與子類扯不上關係!
native方法表示該方法要用第二種依賴平臺的編程語言實現的,不存在着被子類實現的問題,因此,它也不能是抽象的,不能與abstract混用。好比,FileOutputSteam類要硬件打交道,底層的實現用的是操做系統相關的api實現,好比,在windows用c語言實現的,因此,查看jdk的源碼,可以發現FileOutputStream的open方法的定義例如如下:
private native void open(Stringname) throws FileNotFoundException;
假設咱們要用java調用別人寫的c語言函數,咱們是沒法直接調用的,咱們需要依照java的要求寫一個c語言的函數,又咱們的這個c語言函數去調用別人的c語言函數。由於咱們的c語言函數是按java的要求來寫的,咱們這個c語言函數就可以與java對接上,java那邊的對接方式就是定義出與咱們這個c函數相相應的方法,java中相應的方法不需要寫詳細的代碼,但需要在前面聲明native。
關於synchronized與abstract合用的問題,我認爲也不行,因爲在我幾年的學習和開發中,歷來沒見到過這樣的狀況,而且我認爲synchronized應該是做用在一個詳細的方法上纔有意義。而且,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上沒法肯定this是什麼。
26、什麼是內部類?Static Nested Class和Inner Class的不一樣。
內部類就是在一個類的內部定義的類,內部類中不能定義靜態成員(靜態成員不是對象的特性,僅僅是爲了找一個容身之處,因此需要放到一個類中而已,這麼一點小事,你還要把它放到類內部的一個類中,過度了啊!提供內部類,不是爲讓你幹這樣的事情,無聊,不讓你幹。我想多是既然靜態成員相似c語言的全局變量,而內部類通常是用於建立內部對象用的,因此,把「全局變量」放在內部類中就是毫無心義的事情,既然是毫無心義的事情,就應該被禁止),內部類可以直接訪問外部類中的成員變量,內部類可以定義在外部類的方法外面,也可以定義在外部類的方法體中,例如如下所看到的:
public class Outer
{
int out_x = 0;
public void method()
{
Inner1 inner1 = new Inner1();
public class Inner2 //在方法體內部定義的內部類
{
public method()
{
out_x = 3;
}
}
Inner2 inner2 = new Inner2();
}
public class Inner1 //在方法體外面定義的內部類
{
}
}
在方法體外面定義的內部類的訪問類型可以是public,protecte,默認的,private等4種類型,這就好像類中定義的成員變量有4種訪問類型同樣,它們決定這個內部類的定義對其它類是否可見;對於這樣的狀況,咱們也可以在外面建立內部類的實例對象,建立內部類的實例對象時,必定要先建立外部類的實例對象,而後用這個外部類的實例對象去建立內部類的實例對象,代碼例如如下:
Outer outer = new Outer();
Outer.Inner1 inner1 = outer.newInnner1();
在方法內部定義的內部類前面不能有訪問類型修飾符,就好像方法中定義的局部變量同樣,但這樣的內部類的前面可以使用final或abstract修飾符。這樣的內部類對其它類是不可見的其它類沒法引用這樣的內部類,但是這樣的內部類建立的實例對象可以傳遞給其它類訪問。這樣的內部類必須是先定義,後使用,即內部類的定義代碼必須出現在使用該類以前,這與方法中的局部變量必須先定義後使用的道理也是同樣的。這樣的內部類可以訪問方法體中的局部變量,但是,該局部變量前必須加final修飾符。
對於這些細節,僅僅要在eclipse寫代碼試試,依據開發工具提示的各種錯誤信息就可以當即瞭解到。
在方法體內部還可以採用例如如下語法來建立一種匿名內部類,即定義某一接口或類的子類的同一時候,還建立了該子類的實例對象,無需爲該子類定義名稱:
public class Outer
{
public void start()
{
new Thread(
new Runable(){
public void run(){};
}
).start();
}
}
最後,在方法外部定義的內部類前面可以加上statickeyword,從而成爲Static Nested Class,它再也不具備內部類的特性,所有,從狹義上講,它不是內部類。Static Nested Class與普通類在執行時的行爲和功能上沒有什麼區別,僅僅是在編程引用時的語法上有一些區別,它可以定義成public、protected、默認的、private等多種類型,而普通類僅僅能定義成public和默認的這兩種類型。在外面引用Static Nested Class類的名稱爲「外部類名.內部類名」。在外面不需要建立外部類的實例對象,就可以直接建立Static Nested Class,好比,若是Inner是定義在Outer類中的Static Nested Class,那麼可以使用例如如下語句建立Inner類:
Outer.Inner inner = newOuter.Inner();
由於static Nested Class不依賴於外部類的實例對象,因此,static Nested Class能訪問外部類的非static成員變量。當在外部類中訪問Static Nested Class時,可以直接使用Static Nested Class的名字,而不需要加上外部類的名字了,在Static Nested Class中也可以直接引用外部類的static的成員變量,不需要加上外部類的名字。
在靜態方法中定義的內部類也是Static Nested Class,這時候不能在類前面加statickeyword,靜態方法中的Static Nested Class與普通方法中的內部類的應用方式很是類似,它除了可以直接訪問外部類中的static的成員變量,還可以訪問靜態方法中的局部變量,但是,該局部變量前必須加final修飾符。
備註:首先依據你的印象說出你對內部類的總體方面的特色:好比,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態成員,這是大的特色。而後再說一些細節方面的知識,好比,幾種定義方式的語法差異,靜態內部類,以及匿名內部類。
27、內部類可以引用它的包括類的成員嗎?有沒有什麼限制?
全然可以。假設不是靜態內部類,那沒有什麼限制!
假設你把靜態嵌套類看成內部類的一種特例,那在這樣的狀況下不可以訪問外部類的普通成員變量,而僅僅能訪問外部類中的靜態成員,好比,如下的代碼:
class Outer
{
static int x;
static class Inner
{
void test()
{
syso(x);
}
}
}
答題時,也要能察言觀色,揣摩提問者的心思,顯然人家但願你說的是靜態內部類不能訪問外部類的成員,但你一上來就頂牛,這很差,要先順着人家,讓人家愜意,而後再說特殊狀況,讓人家驚訝。
28、Anonymous Inner Class (匿名內部類)可否夠extends(繼承)其餘類,可否夠implements(實現)interface(接口)?
可以繼承其它類或實現其它接口。不只是可以,而是必須!
29、super.getClass()方法調用
如下程序的輸出結果是多少?
importjava.util.Date;
public classTestextends Date{
public static voidmain(String[] args) {
new Test().test();
}
public void test(){
System.out.println(super.getClass().getName());
}
}
很是奇怪,結果是Test
這屬於腦筋急轉彎的題目,在一個qq羣有個網友正好問過這個問題,我認爲挺有趣,就研究了一下,沒想到今天還被你面到了,哈哈。
在test方法中,直接調用getClass().getName()方法,返回的是Test類名
由於getClass()在Object類中定義成了final,子類不能覆蓋該方法,因此,在
test方法中調用getClass().getName()方法,事實上就是在調用從父類繼承的getClass()方法,等效於調用super.getClass().getName()方法,因此,super.getClass().getName()方法返回的也應該是Test。
假設想獲得父類的名稱,應該用例如如下代碼:
getClass().getSuperClass().getName();
30、String是最主要的數據類型嗎?
基本數據類型包含byte、int、char、long、float、double、boolean和short。
java.lang.String類是final類型的,所以不可以繼承這個類、不能改動這個類。爲了提升效率節省空間,咱們應該用StringBuffer類
31、String s = "Hello";s = s + " world!";這兩行代碼運行後,原始的String對象中的內容究竟變了沒有?
沒有。因爲String被設計成不可變(immutable)類,因此它的所有對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內容是 "Hello",而後咱們對s進行了+操做,那麼s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了還有一個 String對象,內容爲"Hello world!",原來那個對象還存在於內存之中,僅僅是s這個引用變量再也不指向它了。
經過上面的說明,咱們很是easy導出還有一個結論,假設經常對字符串進行各類各樣的改動,或者說,不可預見的改動,那麼使用String來表明字符串的話會引發很是大的內存開銷。因爲 String對象創建以後不能再改變,因此對於每一個不一樣的字符串,都需要一個String對象來表示。這時,應該考慮使用StringBuffer類,它贊成改動,而不是每一個不一樣的字符串都要生成一個新的對象。並且,這兩種類的對象轉換十分easy。
同一時候,咱們還可以知道,假設要使用內容一樣的字符串,沒必要每次都new一個String。好比咱們要在構造器中對一個名叫s的String引用變量進行初始化,把它設置爲初始值,應當這樣作:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
後者每次都會調用構造器,生成新對象,性能低下且內存開銷大,並且沒有意義,因爲String對象不可改變,因此對於內容一樣的字符串,僅僅要一個String對象來表示就可以了。也就說,屢次調用上面的構造器建立多個對象,他們的String類型屬性s都指向同一個對象。
上面的結論還基於這樣一個事實:對於字符串常量,假設內容一樣,Java以爲它們表明同一個String對象。而用keywordnew調用構造器,老是會建立一個新的對象,無論內容是否一樣。
至於爲何要把String類設計成不可變類,是它的用途決定的。事實上不只僅String,很是多Java標準類庫中的類都是不可變的。在開發一個系統的時候,咱們有時候也需要設計不可變類,來傳遞一組相關的值,這也是面向對象思想的體現。不可變類有一些長處,比方因爲它的對象是僅僅讀的,因此多線程併發訪問也不會有不論什麼問題。固然也有一些缺點,比方每個不一樣的狀態都要一個對象來表明,可能會形成性能上的問題。因此Java標準類庫還提供了一個可變版本號,即 StringBuffer。
32、可否夠繼承String類?
String類是final類故不可以繼承。
33、String s = new String("xyz");建立了幾個String Object?兩者之間有什麼差異?
兩個或一個,」xyz」相應一個對象,這個對象放在字符串常量緩衝區,常量」xyz」不管出現多少遍,都是緩衝區中的那一個。New String每寫一遍,就建立一個新的對象,它一句那個常量」xyz」對象的內容來建立出一個新String對象。假設曾經就用過’xyz’,這句表明就不會建立」xyz」本身了,直接從緩衝區拿。
34、String和StringBuffer的差異
JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操做字符串,即包括多個字符的字符數據。這個String類提供了數值不可改變的字符串。而這個StringBuffer類提供的字符串進行改動。當你知道字符數據要改變的時候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動態構造字符數據。另外,String實現了equals方法,new String(「abc」).equals(newString(「abc」)的結果爲true,而StringBuffer沒有實現equals方法,因此,new StringBuffer(「abc」).equals(newStringBuffer(「abc」)的結果爲false。
接着要舉一個詳細的樣例來講明,咱們要把1到100的所有數字拼起來,組成一個串。
StringBuffer sbf = new StringBuffer();
for(int i=0;i<100;i++)
{
sbf.append(i);
}
上面的代碼效率很是高,因爲僅僅建立了一個StringBuffer對象,而如下的代碼效率很是低,因爲建立了101個對象。
String str = new String();
for(int i=0;i<100;i++)
{
str = str + i;
}
在講二者差異時,應把循環的次數搞成10000,而後用endTime-beginTime來比較二者運行的時間差別,最後還要講講StringBuilder與StringBuffer的差異。
String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,因此,將StringBuffer對象存儲進Java集合類中時會出現故障。
35、怎樣把一段逗號切割的字符串轉換成一個數組?
假設不查jdk api,我很是難寫出來!我可以說說個人思路:
1 用正則表達式,代碼大概爲:String [] result = orgStr.split(「,」);
2 用 StingTokenizer ,代碼爲:StringTokenizer tokener = StringTokenizer(orgStr,」,」);
String [] result =new String[tokener .countTokens()];
Int i=0;
while(tokener.hasNext(){result[i++]=toker.nextToken();}
36、數組有沒有length()這種方法? String有沒有length()這種方法?
數組沒有length()這種方法,有length的屬性。String有有length()這種方法。
37、如下這條語句一共建立了多少個對象:String s="a"+"b"+"c"+"d";
答:對於例如如下代碼:
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一條語句打印的結果爲false,第二條語句打印的結果爲true,這說明javac編譯可以對字符串常量直接相加的表達式進行優化,沒必要要等到執行期去進行加法運算處理,而是在編譯時去掉當中的加號,直接將其編譯成一個這些常量相連的結果。
題目中的第一行代碼被編譯器在編譯時優化後,至關於直接定義了一個」abcd」的字符串,因此,上面的代碼應該僅僅建立了一個String對象。寫例如如下兩行代碼,
String s ="a" + "b" + "c" + "d";
System.out.println(s== "abcd");
終於打印的結果應該爲true。
38、try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被運行,何時被運行,在return前仍是後?
或許你的答案是在return以前,但往更細地說,個人答案是在return中間執行,請看如下程序代碼的執行結果:
public classTest {
/**
* @paramargs add by zxx ,Dec 9, 2008
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
System.out.println(newTest().test());;
}
static int test()
{
int x = 1;
try
{
returnx;
}
finally
{
++x;
}
}
}
---------運行結果 ---------
1
執行結果是1,爲何呢?主函數調用子函數並獲得結果的過程,比如主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子裏,而後再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不執行了,你主函數繼續執行吧,這沒什麼結果可言,結果是在說這話以前放進罐子裏的。
39、如下的程序代碼輸出的結果是多少?
public class smallT
{
public staticvoid main(String args[])
{
smallT t = new smallT();
int b = t.get();
System.out.println(b);
}
public int get()
{
try
{
return1 ;
}
finally
{
return2 ;
}
}
}
返回的結果是2。
我可以經過如下一個樣例程序來幫助我解釋這個答案,從如下樣例的運行結果中可以發現,try中的return語句調用的函數先於finally中調用的函數運行,也就是說return語句先運行,finally語句後運行,因此,返回的結果是2。Return並不是讓函數當即返回,而是return語句運行後,將把返回結果放置進函數棧中,此時函數並不是當即返回,它要運行finally語句後才真正開始返回。
在解說答案時可以用如下的程序來幫助分析:
public classTest {
/**
* @paramargs add by zxx ,Dec 9, 2008
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
System.out.println(newTest().test());;
}
int test()
{
try
{
return func1();
}
finally
{
return func2();
}
}
int func1()
{
System.out.println("func1");
return 1;
}
int func2()
{
System.out.println("func2");
return 2;
}
}
-----------運行結果-----------------
func1
func2
2
結論:finally中的代碼比return和break語句後運行
40、final, finally, finalize的差異。
final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
內部類要訪問局部變量,局部變量必須定義成final類型,好比,一段代碼……
finally是異常處理語句結構的一部分,表示老是運行。
finalize是Object類的一個方法,在垃圾收集器運行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其它資源回收,好比關閉文件等。JVM不保證此方法總被調用
41、執行時異常與通常異常有何異同?
異常表示程序執行過程當中可能出現的非正常狀態,執行時異常表示虛擬機的一般操做中可能遇到的異常,是一種常見執行錯誤。java編譯器要求方法必須聲明拋出可能發生的非執行時異常,但是並不要求必須聲明拋出未被捕獲的執行時異常。
42、error和exception有什麼差異?
error 表示恢復不是不可能但很是困難的狀況下的一種嚴重問題。比方說內存溢出。不可能期望程序能處理這種狀況。 exception表示一種設計或實現問題。也就是說,它表示假設程序執行正常,從不會發生的狀況。
43、Java中的異常處理機制的簡單原理和應用。
異常是指java程序執行時(非編譯)所發生的非正常狀況或錯誤,與現實生活中的事件很是類似,現實生活中的事件可以包括事件發生的時間、地點、人物、情節等信息,可以用一個對象來表示,Java使用面向對象的方式來處理異常,它把程序中發生的每個異常也都分別封裝到一個對象來表示的,該對象中包括有異常的信息。
Java對異常進行了分類,不一樣類型的異常分別用不一樣的Java類表示,所有異常的根類爲java.lang.Throwable,Throwable如下又派生了兩個子類:Error和Exception,Error表示應用程序自己沒法克服和恢復的一種嚴重問題,程序僅僅有死的份了,好比,說內存溢出和線程死鎖等系統問題。Exception表示程序還能夠克服和恢復的問題,當中又分爲系統異常和普通異常,系統異常是軟件自己缺陷所致使的問題,也就是軟件開發者考慮不周所致使的問題,軟件使用者沒法克服和恢復這樣的問題,但在這樣的問題下還可讓軟件系統繼續執行或者讓軟件死掉,好比,數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是執行環境的變化或異常所致使的問題,是用戶能夠克服的問題,好比,網絡斷線,硬盤空間不夠,發生這樣的異常後,程序不該該死掉。
java爲系統異常和普通異常提供了不一樣的解決方式,編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,因此普通異常也稱爲checked異常,而系統異常可以處理也可以不處理,因此,編譯器不強制用try..catch處理或用throws聲明,因此係統異常也稱爲unchecked異常。
提示答題者:就依照三個級別去思考:虛擬機必須宕機的錯誤,程序可以死掉也可以不死掉的錯誤,程序不該該死掉的錯誤;
44、請寫出你最多見到的5個runtime exception。
這道題主要考你的代碼量究竟多大,假設你長期寫代碼的,應該經常都看到過一些系統方面的異常,你不必定真要回答出5個詳細的系統異常,但你要能夠說出什麼是系統異常,以及幾個系統異常就好了,固然,這些異常全然用其英文名稱來寫是最好的,假設實在寫不出,那就用中文吧,有總比沒有強!
所謂系統異常,就是…..,它們都是RuntimeException的子類,在jdk doc中查RuntimeException類,就可以看到其所有的子類列表,也就是看到了所有的系統異常。我比較有印象的系統異常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。
45、JAVA語言怎樣進行異常處理,keyword:throws,throw,try,catch,finally分別表明什麼意義?在try塊中可以拋出異常嗎?
46、java中有幾種方法可以實現一個線程?用什麼keyword修飾同步方法? stop()和suspend()方法爲什麼不推薦使用?
java5曾經,有例如如下兩種:
第一種:
new Thread(){}.start();這表示調用Thread子類對象的run方法,new Thread(){}表示一個Thread的匿名子類的實例對象,子類加上run方法後的代碼例如如下:
new Thread(){
public void run(){
}
}.start();
另一種:
new Thread(new Runnable(){}).start();這表示調用Thread對象接受的Runnable對象的run方法,new Runnable(){}表示一個Runnable的匿名子類的實例對象,runnable的子類加上run方法後的代碼例如如下:
new Thread(new Runnable(){
public voidrun(){
}
}
).start();
從java5開始,還有例如如下一些線程池建立多線程的方式:
ExecutorService pool = Executors.newFixedThreadPool(3)
for(int i=0;i<10;i++)
{
pool.execute(newRunable(){public void run(){}});
}
Executors.newCachedThreadPool().execute(new Runable(){publicvoid run(){}});
Executors.newSingleThreadExecutor().execute(new Runable(){publicvoid run(){}});
有兩種實現方法,分別使用new Thread()和new Thread(runnable)形式,第一種直接調用thread的run方法,因此,咱們每每使用Thread子類,即new SubThread()。另一種調用runnable的run方法。
有兩種實現方法,各自是繼承Thread類與實現Runnable接口
用synchronizedkeyword修飾同步方法
反對使用stop(),是因爲它不安全。它會解除由線程獲取的所有鎖定,而且假設對象處於一種不連貫狀態,那麼其它線程能在那種狀態下檢查和改動它們。結果很是難檢查出真正的問題所在。suspend()方法easy發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這以前得到的鎖定。此時,其它不論什麼線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復執行。對不論什麼線程來講,假設它們想恢復目標線程,同一時候又試圖使用不論什麼一個鎖定的資源,就會形成死鎖。因此不該該使用suspend(),而應在本身的Thread類中置入一個標誌,指出線程應該活動仍是掛起。若標誌指出線程應該掛起,便用wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()又一次啓動線程。
47、sleep()和 wait()有什麼差異?
(網上的答案:sleep是線程類(Thread)的方法,致使此線程暫停運行指定時間,給運行機會給其它線程,但是監控狀態依舊保持,到時後會本身主動恢復。調用sleep不會釋放對象鎖。 wait是Object類的方法,對此對象調用wait方法致使本線程放棄對象鎖,進入等待此對象的等待鎖定池,僅僅有針對此對象發出notify方法(或notifyAll)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。)
sleep就是正在運行的線程主動讓出cpu,cpu去運行其它線程,在sleep指定的時間事後,cpu纔會回到這個線程上繼續往下運行,假設當前線程進入了同步鎖,sleep方法並不會釋放鎖,即便當前線程使用sleep方法讓出了cpu,但其它被同步鎖擋住了的線程也沒法獲得運行。wait是指在一個已經進入了同步鎖的線程內,讓本身臨時讓出同步鎖,以便其它正在等待此鎖的線程可以獲得同步鎖並運行,僅僅有其它線程調用了notify方法(notify並不釋放鎖,僅僅是告訴調用過wait方法的線程可以去參與得到鎖的競爭了,但不是當即獲得鎖,因爲鎖還在別人手裏,別人還沒釋放。假設notify方法後面的代碼還有很是多,需要這些代碼運行完後纔會釋放鎖,可以在notfiy方法後添加一個等待和一些代碼,看看效果),調用wait方法的線程就會解除wait狀態和程序可以再次獲得鎖後繼續向下運行。對於wait的解說必定要配合樣例代碼來講明,才顯得本身真明確。
package com.huawei.interview;
publicclass MultiThread {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
new Thread(newThread1()).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catchblock
e.printStackTrace();
}
new Thread(newThread2()).start();
}
private static classThread1implements Runnable
{
@Override
public void run() {
// TODO Auto-generated methodstub
//因爲這裏的Thread1和如下的Thread2內部run方法要用同一對象做爲監視器,咱們這裏不能用this,因爲在Thread2裏面的this和這個Thread1的this不是同一個對象。咱們用MultiThread.class這個字節碼對象,當前虛擬機裏引用這個變量時,指向的都是同一個對象。
synchronized (MultiThread.class){
System.out.println("enterthread1...");
System.out.println("thread1is waiting");
try {
//釋放鎖有兩種方式,第一種方式是程序天然離開監視器的範圍,也就是離開了synchronizedkeyword管轄的代碼範圍,還有一種方式就是在synchronizedkeyword管轄的代碼內部調用監視器對象的wait方法。這裏,使用wait方法釋放鎖。
MultiThread.class.wait();
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
System.out.println("thread1is going on...");
System.out.println("thread1is being over!");
}
}
}
private static classThread2implements Runnable
{
@Override
public void run() {
// TODO Auto-generated methodstub
synchronized (MultiThread.class){
System.out.println("enterthread2...");
System.out.println("thread2notify other thread can release wait status..");
//因爲notify方法並不釋放鎖,即便thread2調用如下的sleep方法歇息了10毫秒,但thread1仍然不會運行,因爲thread2沒有釋放鎖,因此Thread1沒法得不到鎖。
MultiThread.class.notify();
System.out.println("thread2is sleeping ten millisecond...");
try {
Thread.sleep(10);
} catch (InterruptedExceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
System.out.println("thread2is going on...");
System.out.println("thread2is being over!");
}
}
}
}
48、同步和異步有何異同,在什麼狀況下分別使用他們?舉例說明。
假設數據將在線程間共享。好比正在寫的數據之後可能被還有一個線程讀到,或者正在讀的數據可能已經被還有一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。
當應用程序在對象上調用了一個需要花費很是長時間來運行的方法,並且不但願讓程序等待方法的返回時,就應該使用異步編程,在很是多狀況下採用異步途徑每每更有效率。
49. 如下兩個方法同步嗎?(本身發明)
class Test
{
synchronizedstatic voidsayHello3()
{
}
synchronizedvoid getX(){}
}
50、多線程有幾種實現方法?同步有幾種實現方法?
多線程有兩種實現方法,各自是繼承Thread類與實現Runnable接口
同步的實現方面有兩種,各自是synchronized,wait與notify
wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock。
sleep():使一個正在執行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM肯定喚醒哪一個線程,而且不是按優先級。
Allnotity():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。
51、啓動一個線程是用run()仍是start()? .
啓動一個線程是調用start()方法,使線程就緒狀態,之後可以被調度爲運行狀態,一個線程必須關聯一些詳細的運行代碼,run()方法是該線程所關聯的運行代碼。
52、當一個線程進入一個對象的一個synchronized方法後,其餘線程是否可進入此對象的其餘方法?
分幾種狀況:
1.其它方法前是否加了synchronizedkeyword,假設沒加,則能。
2.假設這種方法內部調用了wait,則可以進入其它synchronized方法。
3.假設其它個方法都加了synchronizedkeyword,並且內部沒有調用wait,則不能。
4.假設其它方法是static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能同步,因爲非靜態的方法用的是this。
53、線程的基本概念、線程的基本狀態以及狀態之間的關係
一個程序中可以有多條運行線索同一時候運行,一個線程就是程序中的一條運行線索,每個線程上都關聯有要運行的代碼,即可以有多段程序代碼同一時候運行,每個程序至少都有一個線程,即main方法運行的那個線程。假設僅僅是一個cpu,它怎麼可以同一時候運行多段程序呢?這是從宏觀上來看的,cpu一會運行a線索,一會運行b線索,切換時間很是快,給人的感受是a,b在同一時候運行,比如你們在同一個辦公室上網,僅僅有一條連接到外部網線,事實上,這條網線一會爲a傳數據,一會爲b傳數據,由於切換時間很是短暫,因此,你們感受都在同一時候上網。
狀態:就緒,執行,synchronize堵塞,wait和sleep掛起,結束。wait必須在synchronized內部調用。
調用線程的start方法後線程進入就緒狀態,線程調度系統將就緒狀態的線程轉爲執行狀態,遇到synchronized語句時,由執行狀態轉爲堵塞,當synchronized得到鎖後,由堵塞轉爲執行,在這樣的狀況可以調用wait方法轉爲掛起狀態,當線程關聯的代碼執行完後,線程變爲結束狀態。
54、簡述synchronized和java.util.concurrent.locks.Lock的異同?
主要一樣點:Lock能完畢synchronized所實現的所有功能
主要不一樣點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會本身主動釋放鎖,而Lock必定要求程序猿手工釋放,並且必須在finally從句中釋放。Lock還有更強大的功能,好比,它的tryLock方法可以非堵塞方式去拿鎖。
舉例說明(對如下的題用lock進行了改寫):
package com.huawei.interview;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
publicclass ThreadTest {
/**
* @paramargs
*/
private int j;
private Lock lock =newReentrantLock();
public static voidmain(String[] args) {
// TODO Auto-generated method stub
ThreadTest tt = new ThreadTest();
for(int i=0;i<2;i++)
{
new Thread(tt.new Adder()).start();
new Thread(tt.new Subtractor()).start();
}
}
private class SubtractorimplementsRunnable
{
@Override
public void run() {
// TODO Auto-generated methodstub
while(true)
{
/*synchronized (ThreadTest.this) {
System.out.println("j--="+ j--);
//這裏拋異常了,鎖能釋放嗎?
}*/
lock.lock();
try
{
System.out.println("j--="+ j--);
}finally
{
lock.unlock();
}
}
}
}
private class AdderimplementsRunnable
{
@Override
public void run() {
// TODO Auto-generated methodstub
while(true)
{
/*synchronized (ThreadTest.this) {
System.out.println("j++="+ j++);
}*/
lock.lock();
try
{
System.out.println("j++="+ j++);
}finally
{
lock.unlock();
}
}
}
}
}
55、設計4個線程,當中兩個線程每次對j添加1,另外兩個線程對j每次下降1。寫出程序。
下面程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。
public class ThreadTest1
{
private int j;
public static void main(String args[]){
ThreadTest1 tt=newThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(inti=0;i<2;i++){
Thread t=newThread(inc);
t.start();
t=new Thread(dec);
t.start();
}
}
private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable{
public void run(){
for(inti=0;i<100;i++){
inc();
}
}
}
class Dec implements Runnable{
public void run(){
for(inti=0;i<100;i++){
dec();
}
}
}
}
----------隨手再寫的一個-------------
class A
{
JManger j =new JManager();
main()
{
new A().call();
}
void call
{
for(int i=0;i<2;i++)
{
new Thread(
newRunnable(){ public void run(){while(true){j.accumulate()}}}
).start();
new Thread(newRunnable(){ public void run(){while(true){j.sub()}}}).start();
}
}
}
class JManager
{
private j = 0;
public synchronized voidsubtract()
{
j--
}
public synchronized voidaccumulate()
{
j++;
}
}
56、子線程循環10次,接着主線程循環100,接着又回到子線程循環10次,接着再回到主線程又循環100,如此循環50次,請寫出程序。
終於的程序代碼例如如下:
publicclass ThreadTest {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
new ThreadTest().init();
}
public void init()
{
final Business business =newBusiness();
new Thread(
new Runnable()
{
public voidrun() {
for(inti=0;i<50;i++)
{
business.SubThread(i);
}
}
}
).start();
for(int i=0;i<50;i++)
{
business.MainThread(i);
}
}
private class Business
{
booleanbShouldSub =true;//這裏至關於定義了控制該誰運行的一個信號燈
public synchronized voidMainThread(int i)
{
if(bShouldSub)
try {
this.wait();
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
for(int j=0;j<5;j++)
{
System.out.println(Thread.currentThread().getName()+ ":i=" + i +",j=" + j);
}
bShouldSub =true;
this.notify();
}
public synchronized voidSubThread(int i)
{
if(!bShouldSub)
try {
this.wait();
} catch (InterruptedExceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
for(intj=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName()+ ":i=" + i +",j=" + j);
}
bShouldSub =false;
this.notify();
}
}
}
備註:不可能一上來就寫出上面的完整代碼,最初寫出來的代碼例如如下,問題在於兩個線程的代碼要參照同一個變量,即這兩個線程的代碼要共享數據,因此,把這兩個線程的運行代碼搬到同一個類中去:
package com.huawei.interview.lym;
publicclass ThreadTest {
private static booleanbShouldMain=false;
public static void main(String[]args) {
// TODO Auto-generated method stub
/*new Thread(){
public void run()
{
for(int i=0;i<50;i++)
{
for(int j=0;j<10;j++)
{
System.out.println("i="+ i + ",j=" + j);
}
}
}
}.start();*/
//final String str = newString("");
new Thread(
new Runnable()
{
public voidrun()
{
for(inti=0;i<50;i++)
{
synchronized(ThreadTest.class) {
if(bShouldMain)
{
try {
ThreadTest.class.wait();}
catch(InterruptedException e) {
e.printStackTrace();
}
}
for(intj=0;j<10;j++)
{
System.out.println(
Thread.currentThread().getName()+
"i="+ i + ",j=" + j);
}
bShouldMain= true;
ThreadTest.class.notify();
}
}
}
}
).start();
for(int i=0;i<50;i++)
{
synchronized (ThreadTest.class){
if(!bShouldMain)
{
try {
ThreadTest.class.wait();}
catch(InterruptedException e) {
e.printStackTrace();
}
}
for(intj=0;j<5;j++)
{
System.out.println(
Thread.currentThread().getName()+
"i=" + i +",j=" + j);
}
bShouldMain =false;
ThreadTest.class.notify();
}
}
}
}
如下使用jdk5中的併發庫來實現的:
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
public class ThreadTest
{
private static Locklock = new ReentrantLock();
private staticCondition subThreadCondition = lock.newCondition();
private staticboolean bBhouldSubThread = false;
public static voidmain(String [] args)
{
ExecutorServicethreadPool = Executors.newFixedThreadPool(3);
threadPool.execute(newRunnable(){
publicvoid run()
{
for(inti=0;i<50;i++)
{
lock.lock();
try
{
if(!bBhouldSubThread)
subThreadCondition.await();
for(intj=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName()+ ",j=" + j);
}
bBhouldSubThread= false;
subThreadCondition.signal();
}catch(Exceptione)
{
}
finally
{
lock.unlock();
}
}
}
});
threadPool.shutdown();
for(inti=0;i<50;i++)
{
lock.lock();
try
{
if(bBhouldSubThread)
subThreadCondition.await();
for(intj=0;j<10;j++)
{
System.out.println(Thread.currentThread().getName()+ ",j=" + j);
}
bBhouldSubThread= true;
subThreadCondition.signal();
}catch(Exceptione)
{
}
finally
{
lock.unlock();
}
}
}
}
57、介紹Collection框架的結構
答:任意發揮題,天南海北誰便談,僅僅要讓別認爲你知識淵博,理解透徹就能夠。
58、Collection框架中實現比較要實現什麼接口
comparable/comparator
59、ArrayList和Vector的差異
答:
這兩個類都實現了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,至關於一種動態的數組,咱們之後可以按位置索引號取出某個元素,,並且當中的數據是贊成反覆的,這是HashSet之類的集合的最大不一樣處,HashSet之類的集合不可以按索引號去檢索當中的元素,也不一樣意有反覆的元素(原本題目問的與hashset沒有不論什麼關係,但爲了說清楚ArrayList與Vector的功能,咱們使用對例如式,更有利於說明問題)。
接着才說ArrayList與Vector的差異,這主要包含兩個方面:.
(1)同步性:
Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不一樣步的。假設僅僅有一個線程會訪問到集合,那最好是使用ArrayList,因爲它不考慮線程安全,效率會高些;假設有多個線程會訪問到集合,那最好是使用Vector,因爲不需要咱們本身再去考慮和編寫線程安全的代碼。
備註:對於Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時才提供的,它們是線程不安全的。因此,咱們講課時先講老的。
(2)數據增加:
ArrayList與Vector都有一個初始的容量大小,當存儲進它們裏面的元素的個數超過了容量時,就需要添加ArrayList與Vector的存儲空間,每次要添加存儲空間時,不是僅僅添加一個存儲單元,而是添加多個存儲單元,每次添加的存儲單元的個數在內存空間利用與程序效率之間要取得必定的平衡。Vector默認增加爲原來兩倍,而ArrayList的增加策略在文檔中沒有明白規定(從源碼看到的是增加爲原來的1.5倍)。ArrayList與Vector都可以設置初始的空間大小,Vector還可以設置增加的空間大小,而ArrayList沒有提供設置增加空間的方法。
總結:即Vector增加原來的一倍,ArrayList添加原來的0.5倍。
60、HashMap和Hashtable的差異
(條理上還需要整理,也是先說一樣點,再說不一樣點)
HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完畢了Map接口,主要差異在於HashMap贊成空(null)鍵值(key),由於非線程安全,在僅僅有一個線程訪問的狀況下,效率要高於Hashtable。
HashMap贊成將null做爲一個entry的key或者value,而Hashtable不一樣意。
HashMap把Hashtable的contains方法去掉了,改爲containsvalue和containsKey。因爲contains方法easy讓人引發誤解。
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。
最大的不一樣是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要本身爲它的方法實現同步,而HashMap就必須爲之提供外同步。
Hashtable和HashMap採用的hash/rehash算法都大概同樣,因此性能不會有很是大的差別。
就HashMap與HashTable主要從三方面來講。
一.歷史緣由:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現
二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的
三.值:僅僅有HashMap可以讓你將空值做爲一個表的條目的key或value
61、List和 Map差異?
一個是存儲單列數據的集合,還有一個是存儲鍵和值這種雙列數據的集合,List中存儲的數據是有順序,並且贊成反覆;Map中存儲的數據是沒有順序的,其鍵是不能反覆的,它的值是可以有反覆的。
62、List, Set, Map是否繼承自Collection接口?
List,Set是,Map不是
63、List、Map、Set三個接口,存取元素時,各有什麼特色?
這種題屬於任意發揮題:這種題比較考水平,兩個方面的水平:一是要真正明確這些內容,二是要有較強的總結和表述能力。假設你明確,但表述不清楚,在別人那裏則等同於不明確。
首先,List與Set具備類似性,它們都是單列元素的集合,因此,它們有一個功共同的父接口,叫Collection。Set裏面不一樣意有反覆的元素,所謂反覆,即不能有兩個相等(注意,不是不過一樣)的對象,即若是Set集合中有了一個A對象,現在我要向Set集合再存入一個B對象,但B對象與A對象equals相等,則B對象存儲不進去,因此,Set集合的add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功增長該元素時,則返回true,當集合含有與某個元素equals相等的元素時,此時add方法沒法增長該元素,返回結果爲false。Set取元素時,無法說取第幾個,只能以Iterator接口取得所有的元素,再逐一遍歷各個元素。
List表示有前後順序的集合,注意,不是那種按年齡、按大小、按價格之類的排序。當咱們屢次調用add(Obj e)方法時,每次增長的對象就像火車站買票有排隊順序同樣,按先來後到的順序排序。有時候,也可以插隊,即調用add(int index,Obj e)方法,就可以指定當前對象在集合中的存放位置。一個對象可以被重複存儲進List中,每調用一次add方法,這個對象就被插入進集合中一次,事實上,並不是把這個對象自己存儲進了集合中,而是在集合中用一個索引變量指向這個對象,當這個對象被add屢次時,即至關於集合中有多個索引指向了這個對象,如圖x所看到的。List除了可以以Iterator接口取得所有的元素,再逐一遍歷各個元素以外,還可以調用get(index i)來明白說明取第幾個。
Map與List和Set不一樣,它是雙列的集合,當中有put方法,定義例如如下:put(obj key,objvalue),每次存儲時,要存儲一對key/value,不能存儲反覆的key,這個反覆的規則也是按equals比較相等。取則可以依據key得到相應的value,即get(Object key)返回值爲key所相應的value。另外,也可以得到所有的key的結合,還可以得到所有的value的結合,還可以得到key和value組合成的Map.Entry對象的集合。
List 以特定次序來持有元素,可有反覆元素。Set沒法擁有反覆元素,內部排序。Map保存key-value值,value可多值。
HashSet依照hashcode值的某種運算方式進行存儲,而不是直接按hashCode值的大小進行存儲。好比,"abc"---> 78,"def" ---> 62,"xyz" ---> 65在hashSet中的存儲順序不是62,65,78,這些問題感謝曾經一個叫崔健的學員提出,最後經過查看源代碼給他解釋清楚,看本次培訓學員其中有多少能看懂源代碼。LinkedHashSet按插入的順序存儲,那被存儲對象的hashcode方法還有什麼做用呢?學員想一想!hashset集合比較兩個對象是否相等,首先看hashcode方法是否相等,而後看equals方法是否相等。new兩個Student插入到HashSet中,看HashSet的size,實現hashcode和equals方法後再看size。
同一個對象可以在Vector中增長屢次。往集合裏面加元素,至關於集合裏用一根繩子鏈接到了目標對象。往HashSet中卻加不了屢次的。
64、說出ArrayList,Vector, LinkedList的存儲性能和特性
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便添加和插入元素,它們都贊成直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector由於使用了synchronized方法(線程安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或後向遍歷,但是插入數據時僅僅需要記錄本項的先後項就能夠,因此插入速度較快。
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被看成堆棧和隊列來使用。
65、去掉一個Vector集合中反覆的元素
Vector newVector = new Vector();
For (int i=0;i<vector.size();i++)
{
Object obj = vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
另外一種簡單的方式,HashSet set = new HashSet(vector);
66、Collection和 Collections的差異。
Collection是集合類的上級接口,繼承與他的接口主要有Set和List.
Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做。
67、Set裏的元素是不能反覆的,那麼用什麼方法來區分反覆與否呢?是用==仍是equals()?它們有何差異?
Set裏的元素是不能反覆的,元素反覆與否是使用equals()方法進行推斷的。
equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,爲的是當兩個分離的對象的內容和類型相配的話,返回真值。
最常用的集合類是 List 和 Map。 List的詳細實現包含 ArrayList和 Vector,它們是可變大小的列表,比較適合構建、存儲和操做不論什麼類型對象的元素列表。 List適用於按數值索引訪問元素的情形。
Map 提供了一個更通用的元素存儲方法。 Map集合類用於存儲元素對(稱做"鍵"和"值"),當中每個鍵映射到一個值。
ArrayList/VectoràList
àCollection
HashSet/TreeSetàSet
PropetiesàHashTable
àMap
Treemap/HashMap
我記的不是方法名,而是思想,我知道它們都有增刪改查的方法,但這些方法的詳細名稱,我記得不是很是清楚,對於set,大概的方法是add,remove, contains;對於map,大概的方法就是put,remove,contains等,因爲,我僅僅要在eclispe下按點操做符,很是天然的這些方法就出來了。我記住的一些思想就是List類會有get(int index)這個方案,因爲它可以按順序取元素,而set類中沒有get(int index)這個方案。List和set都可以迭代出所有元素,迭代時先要獲得一個iterator對象,因此,set和list類都有一個iterator方法,用於返回那個iterator對象。map可以返回三個集合,一個是返回所有的key的集合,另一個返回的是所有value的集合,再一個返回的key和value組合成的EntrySet對象的集合,map也有get方法,參數是key,返回值是key相應的value。
69、兩個對象值一樣(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不正確?
對。
假設對象要保存在HashSet或HashMap中,它們的equals相等,那麼,它們的hashcode值就必須相等。
假設不是要保存在HashSet或HashMap,則與hashcode沒有什麼關係了,這時候hashcode不等是可以的,好比arrayList存儲的對象就不用實現hashcode,固然,咱們沒有理由不實現,一般都會去實現的。
70、TreeSet裏面放對象,假設同一時候放入了父類和子類的實例對象,那比較時使用的是父類的compareTo方法,仍是使用的子類的compareTo方法,仍是拋異常!
(應該是沒有針對問題的確切的答案,當前的add方法放入的是哪一個對象,就調用哪一個對象的compareTo方法,至於這個compareTo方法怎麼作,就看當前這個對象的類中是怎樣編寫這種方法的)
實驗代碼:
publicclass ParentimplementsComparable {
private int age = 0;
public Parent(int age){
this.age = age;
}
public int compareTo(Object o){
// TODO Auto-generated method stub
System.out.println("method ofparent");
Parent o1 = (Parent)o;
returnage>o1.age?1:age<o1.age?-1:0;
}
}
publicclass Childextends Parent {
public Child(){
super(3);
}
public int compareTo(Object o){
// TODO Auto-generated methodstub
System.out.println("methodof child");
// Child o1 = (Child)o;
return 1;
}
}
publicclass TreeSetTest {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
TreeSet set = new TreeSet();
set.add(newParent(3));
set.add(new Child());
set.add(newParent(4));
System.out.println(set.size());
}
}
71、說出一些常用的類,包,接口,請各舉5個
要讓人家感受你對java ee開發很是熟,因此,不能只只列core java中的那些東西,要多列你在作ssh項目中涉及的那些東西。就寫你近期寫的那些程序中涉及的那些類。
常用的類:BufferedReader BufferedWriter FileReader FileWirter String Integer
java.util.Date,System,Class,List,HashMap
常用的包:java.lang java.io java.util java.sql,javax.servlet,org.apache.strtuts.action,org.hibernate
常用的接口:Remote List Map Document NodeList,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)、Session(Hibernate),HttpSession
72、java中有幾種類型的流?JDK爲每種類型的流提供了一些抽象類以供繼承,請說出他們各自是哪些類?
字節流,字符流。字節流繼承於InputStream OutputStream,字符流繼承於InputStreamReaderOutputStreamWriter。在java.io包中還有更多的流,主要是爲了提升性能和使用方便。
73、字節流與字符流的差異
要把一片二進制數據數據逐一輸出到某個設備中,或者從某個設備中逐一讀取一片二進制數據,不管輸入輸出設備是什麼,咱們要用統一的方式來完畢這些操做,用一種抽象的方式進行描寫敘述,這個抽象描寫敘述方式起名爲IO流,相應的抽象類爲OutputStream和InputStream,不一樣的實現類就表明不一樣的輸入和輸出設備,它們都是針對字節進行操做的。
在應用中,經常要全然是字符的一段文本輸出去或讀進來,用字節流可以嗎?計算機中的一切終於都是二進制的字節形式存在。對於「中國」這些字符,首先要獲得其相應的字節,而後將字節寫入到輸出流。讀取時,首先讀到的是字節,可是咱們要把它顯示爲字符,咱們需要將字節轉換成字符。由於這種需求很是普遍,人家專門提供了字符流的包裝類。
底層設備永遠僅僅接受字節數據,有時候要寫字符串究竟層設備,需要將字符串轉成字節再進行寫入。字符流是字節流的包裝,字符流則是直接接受字符串,它內部將串轉成字節,再寫入底層設備,這爲咱們向IO設別寫入或讀取字符串提供了一點點方便。
字符向字節轉換時,要注意編碼的問題,因爲字符串轉成字節數組,
事實上是轉成該字符的某種編碼的字節形式,讀取也是反之的道理。
解說字節流與字符流關係的代碼案例:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class IOTest {
public static void main(String[]args) throws Exception {
String str = "中國人";
/*FileOutputStreamfos = newFileOutputStream("1.txt");
fos.write(str.getBytes("UTF-8"));
fos.close();*/
/*FileWriter fw =new FileWriter("1.txt");
fw.write(str);
fw.close();*/
PrintWriter pw =new PrintWriter("1.txt","utf-8");
pw.write(str);
pw.close();
/*FileReader fr =new FileReader("1.txt");
char[] buf = newchar[1024];
int len =fr.read(buf);
String myStr = newString(buf,0,len);
System.out.println(myStr);*/
/*FileInputStreamfr = new FileInputStream("1.txt");
byte[] buf = newbyte[1024];
int len =fr.read(buf);
String myStr = newString(buf,0,len,"UTF-8");
System.out.println(myStr);*/
BufferedReader br =new BufferedReader(
newInputStreamReader(
newFileInputStream("1.txt"),"UTF-8"
)
);
String myStr =br.readLine();
br.close();
System.out.println(myStr);
}
}
74、什麼是java序列化,怎樣實現java序列化?或者請解釋Serializable接口的做用。
咱們有時候將一個java對象變成字節流的形式傳出去或者從一個字節流中恢復成一個java對象,好比,要將java對象存儲到硬盤或者傳送給網絡上的其它計算機,這個過程咱們可以本身寫代碼去把一個java對象變成某個格式的字節流再傳輸,但是,jre自己就提供了這樣的支持,咱們可以調用OutputStream的writeObject方法來作,假設要讓java幫咱們作,要被傳輸的對象必須實現serializable接口,這樣,javac編譯時就會進行特殊處理,編譯的類才幹夠被writeObject方法操做,這就是所謂的序列化。需要被序列化的類必須實現Serializable接口,該接口是一個mini接口,當中沒有需要實現的方法,implementsSerializable僅僅是爲了標註該對象是可被序列化的。
好比,在web開發中,假設對象被保存在了Session中,tomcat在從新啓動時要把Session對象序列化到硬盤,這個對象就必須實現Serializable接口。假設對象要通過分佈式系統進行網絡傳輸或經過rmi等遠程調用,這就需要在網絡上傳輸對象,被傳輸的對象就必須實現Serializable接口。
75、描寫敘述一下JVM載入class文件的原理機制?
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader是一個重要的Java執行時系統組件。它負責在執行時查找和裝入類文件的類。
76、heap和stack有什麼差異。
java的內存分爲兩類,一類是棧內存,一類是堆內存。棧內存是指程序進入一個方法時,會爲這種方法單獨分配一塊私屬存儲空間,用於存儲這種方法內部的局部變量,當這種方法結束時,分配給這種方法的棧會釋放,這個棧中的變量也將隨之釋放。
堆是與棧做用不一樣的內存,通常用於存放不放在當前方法棧中的那些數據,好比,使用new建立的對象都放在堆裏,因此,它不會隨方法的結束而消失。方法中的局部變量使用final修飾後,放在堆中,而不是棧中。
77、GC是什麼?爲何要有GC?
GC是垃圾收集的意思(Gabage Collection),內存處理是編程人員easy出現故障的地方,忘記或者錯誤的內存回收會致使程序或系統的不穩定甚至崩潰,Java提供的GC功能可以本身主動監測對象是否超過做用域從而達到本身主動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操做方法。
78、垃圾回收的長處和原理。並考慮2種回收機制。
Java語言中一個顯著的特色就是引入了垃圾回收機制,使c++程序猿最頭疼的內存管理的問題迎刃而解,它使得Java程序猿在編敲代碼的時候再也不需要考慮內存管理。由於有個垃圾回收機制,Java中的對象再也不有"做用域"的概念,僅僅有對象的引用纔有"做用域"。垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存。垃圾回收器通常是做爲一個單獨的低級別的線程執行,不可預知的狀況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序猿不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。
79、垃圾回收器的基本原理是什麼?垃圾回收器可以當即回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?
對於GC來講,當程序猿建立對象時,GC就開始監控這個對象的地址、大小以及使用狀況。一般,GC採用有向圖的方式記錄和管理堆(heap)中的所有對象。經過這樣的方式肯定哪些對象是"可達的",哪些對象是"不可達的"。當GC肯定一些對象爲"不可達"時,GC就有責任回收這些內存空間。可以。程序猿可以手動運行System.gc(),通知GC運行,但是Java語言規範並不保證GC必定會運行。
80、何時用assert。
assertion(斷言)在軟件開發中是一種常用的調試方式,很是多開發語言中都支持這樣的機制。在實現中,assertion就是在程序中的一條語句,它對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值爲true;假設該值爲false,說明程序已經處於不對的狀態下,assert將給出警告或退出。通常來講,assertion用於保證程序最基本、關鍵的正確性。assertion檢查一般在開發和測試時開啓。爲了提升性能,在軟件公佈後,assertion檢查通常是關閉的。
package com.huawei.interview;
publicclass AssertTest {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
int i = 0;
for(i=0;i<5;i++)
{
System.out.println(i);
}
//若是程序不當心多了一句--i;
--i;
assert i==5;
}
}
81、java中會存在內存泄漏嗎,請簡單描寫敘述。
所謂內存泄露就是指一個再也不被程序使用的對象或變量一直被佔領在內存中。java中有垃圾回收機制,它可以保證一對象再也不被引用的時候,即對象編程了孤兒的時候,對象將本身主動被垃圾回收器從內存中清除掉。由於Java使用有向圖的方式進行垃圾回收管理,可以消除引用循環的問題,好比有兩個對象,相互引用,僅僅要它們和根進程不可達的,那麼GC也是可以回收它們的,好比如下的代碼可以看到這樣的狀況的內存回收:
package com.huawei.interview;
import java.io.IOException;
publicclass GarbageTest {
/**
* @paramargs
* @throwsIOException
*/
public static voidmain(String[] args)throws IOException {
// TODO Auto-generated method stub
try {
gcTest();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("hasexited gcTest!");
System.in.read();
System.in.read();
System.out.println("out begingc!");
for(int i=0;i<100;i++)
{
System.gc();
System.in.read();
System.in.read();
}
}
private static voidgcTest()throws IOException {
System.in.read();
System.in.read();
Person p1 = new Person();
System.in.read();
System.in.read();
Person p2 = new Person();
p1.setMate(p2);
p2.setMate(p1);
System.out.println("beforeexit gctest!");
System.in.read();
System.in.read();
System.gc();
System.out.println("exitgctest!");
}
private static classPerson
{
byte[] data =new byte[20000000];
Person mate = null;
public void setMate(Personother)
{
mate = other;
}
}
}
java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就很是可能發生內存泄露,雖然短生命週期對象已經再也不需要,但是因爲長生命週期對象持有它的引用而致使不能被回收,這就是java中內存泄露的發生場景,通俗地說,就是程序猿可能建立了一個對象,之後一直再也不使用這個對象,這個對象卻一直被引用,即這個對象無用但是卻沒法被垃圾回收器回收的,這就是java中可能出現內存泄露的狀況,好比,緩存系統,咱們載入了一個對象放在緩存中(好比放在一個全局map對象中),而後一直再也不使用它,這個對象一直被緩存引用,但卻再也不被使用。
檢查java中的內存泄露,必定要讓程序將各類分支狀況都完整運行到程序結束,而後看某個對象是否被使用過,假設沒有,則才幹斷定這個對象屬於內存泄露。
假設一個外部類的實例對象的方法返回了一個內部類的實例對象,這個內部類對象被長期引用了,即便那個外部類實例對象再也不被使用,但由於內部類持久外部類的實例對象,這個外部類對象將不會被垃圾回收,這也會形成內存泄露。
如下內容來自於網上(主要特色就是清空堆棧中的某個元素,並不是完全把它從數組中拿掉,而是把存儲的總數下降,本人寫得可以比這個好,在拿掉某個元素時,順便也讓它從數組中消失,將那個元素所在的位置的值設置爲null就能夠):
我實在想不到比那個堆棧更經典的樣例了,以至於我還要引用別人的樣例,如下的樣例不是我想到的,是書上看到的,固然假設沒有在書上看到,可能過一段時間我本身也想的到,可是那時我說是我本身想到的也沒有人相信的。
public class Stack {
private Object[] elements=new Object[10];
private int size = 0;
public void push(Object e){
ensureCapacity();
elements[size++] = e;
}
public Object pop(){
if( size == 0)
throw new EmptyStackException();
return elements[--size];
}
private void ensureCapacity(){
if(elements.length == size){
Object[] oldElements = elements;
elements = new Object[2 * elements.length+1];
System.arraycopy(oldElements,0, elements, 0, size);
}
}
}
上面的原理應該很是easy,假如堆棧加了10個元素,而後全部彈出來,儘管堆棧是空的,沒有咱們要的東西,但是這是個對象是沒法回收的,這個才符合了內存泄露的兩個條件:無用,沒法回收。
但是就是存在這種東西也不必定會致使什麼樣的後果,假設這個堆棧用的比較少,也就浪費了幾個K內存而已,反正咱們的內存都上G了,哪裏會有什麼影響,再說這個東西很是快就會被回收的,有什麼關係。如下看兩個樣例。
樣例1
public class Bad{
public static Stack s=Stack();
static{
s.push(new Object());
s.pop(); //這裏有一個對象發生內存泄露
s.push(new Object()); //上面的對象可以被回收了,等因而自愈了
}
}
因爲是static,就一直存在到程序退出,但是咱們也可以看到它有自愈功能,就是說假設你的Stack最多有100個對象,那麼最多也就僅僅有100個對象沒法被回收事實上這個應該很是easy理解,Stack內部持有100個引用,最壞的狀況就是他們都是沒用的,因爲咱們一旦放新的進取,曾經的引用天然消失!
內存泄露的第二種狀況:當一個對象被存儲進HashSet集合中之後,就不能改動這個對象中的那些參與計算哈希值的字段了,不然,對象改動後的哈希值與最初存儲進HashSet集合中時的哈希值就不一樣了,在這樣的狀況下,即便在contains方法使用該對象的當前引用做爲的參數去HashSet集合中檢索對象,也將返回找不到對象的結果,這也會致使沒法從HashSet集合中單獨刪除當前對象,形成內存泄露。
82、能不能本身寫個類,也叫java.lang.String?
可以,但在應用的時候,需要用本身的類載入器去載入,不然,系統的類載入器永遠僅僅是去載入jre.jar包中的那個java.lang.String。由於在tomcat的web應用程序中,都是由webapp本身的類載入器先本身載入WEB-INF/classess文件夾中的類,而後才託付上級的類載入器載入,假設咱們在tomcat的web應用程序中寫一個java.lang.String,這時候Servlet程序載入的就是咱們本身寫的java.lang.String,但是這麼幹就會出很是多潛在的問題,原來所有用了java.lang.String類的都將出現故障。
儘管java提供了endorsed技術,能夠覆蓋jdk中的某些類,詳細作法是….。但是,能夠被覆蓋的類是有限制範圍,反正不包含java.lang這種包中的類。
(如下的好比主要是便於你們學習理解僅僅用,不要做爲答案的一部分,不然,人家懷疑是題目泄露了)好比,執行如下的程序:
package java.lang;
publicclass String {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
System.out.println("string");
}
}
報告的錯誤例如如下:
java.lang.NoSuchMethodError:main
Exception inthread "main"
這是因爲載入了jre自帶的java.lang.String,而該類中沒有main方法。
83. Java代碼查錯
1.
abstract class Name {
private String name;
public abstract boolean isStupidName(String name) {}
}
大俠們,這有何錯誤?
答案: 錯。abstract method必須以分號結尾,且不帶花括號。
2.
public class Something {
void doSomething () {
private String s = "";
int l = s.length();
}
}
有錯嗎?
答案: 錯。局部變量前不能放置不論什麼訪問修飾符 (private,public,和protected)。final可以用來修飾局部變量
(final如同abstract和strictfp,都是非訪問修飾符,strictfp僅僅能修飾class和method而非variable)。
3.
abstract class Something {
private abstract String doSomething ();
}
這好像沒什麼錯吧?
答案: 錯。abstract的methods不能以private修飾。abstract的methods就是讓子類implement(實現)詳細細節的,怎麼可以用private把abstract
method封鎖起來呢? (同理,abstract method前不能加final)。
4.
public class Something {
public int addOne(final int x) {
return ++x;
}
}
這個比較明顯。
答案: 錯。int x被修飾成final,意味着x不能在addOne method中被改動。
5.
public class Something {
public static void main(String[] args) {
Other o = new Other();
new Something().addOne(o);
}
public void addOne(final Other o) {
o.i++;
}
}
class Other {
public int i;
}
和上面的很是類似,都是關於final的問題,這有錯嗎?
答案: 正確。在addOne method中,參數o被修飾成final。假設在addOne method裏咱們改動了o的reference
(比方: o = new Other();),那麼如同上例這題也是錯的。但這裏改動的是o的member vairable
(成員變量),而o的reference並無改變。
6.
class Something {
int i;
public void doSomething() {
System.out.println("i = "+ i);
}
}
有什麼錯呢? 看不出來啊。
答案: 正確。輸出的是"i = 0"。int i屬於instant variable (實例變量,或叫成員變量)。instant variable有default value。int的default value是0。
7.
class Something {
final int i;
public void doSomething() {
System.out.println("i = "+ i);
}
}
和上面一題僅僅有一個地方不一樣,就是多了一個final。這難道就錯了嗎?
答案: 錯。final int i是個final的instant variable (實例變量,或叫成員變量)。final的instant variable沒有default value,必須在constructor (構造器)結束以前被賦予一個明白的值。可以改動爲"final int i =0;"。
8.
public class Something {
public static void main(String[] args) {
Something s = new Something();
System.out.println("s.doSomething() returns " + doSomething());
}
public String doSomething() {
return "Do something ...";
}
}
看上去很是完美。
答案: 錯。看上去在main裏call doSomething沒有什麼問題,畢竟兩個methods都在同一個class裏。但細緻看,main是static的。static method不能直接call non-staticmethods。可改爲"System.out.println("s.doSomething()returns " + s.doSomething());"。同理,static method不能訪問non-static instant variable。
9.
此處,Something類的文件名稱叫OtherThing.java
class Something {
private static void main(String[] something_to_do){
System.out.println("Dosomething ...");
}
}
這個好像很是明顯。
答案: 正確。歷來沒有人說過Java的Class名字必須和其文件名稱一樣。但public class的名字必須和文件名稱一樣。
10.
interface A{
int x = 0;
}
class B{
int x =1;
}
class C extends B implements A {
public void pX(){
System.out.println(x);
}
public static void main(String[] args) {
new C().pX();
}
}
答案:錯誤。在編譯時會錯誤發生(錯誤描寫敘述不一樣的JVM有不一樣的信息,意思就是未明白的x調用,兩個x都匹配(就象在同一時候import java.util和java.sql兩個包時直接聲明Date同樣)。對於父類的變量,可以用super.x來明白,而接口的屬性默認隱含爲 public staticfinal.因此可以經過A.x來明白。
11.
interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable, Bounceable {
Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name =name;
}
public void play() {
ball = newBall("Football");
System.out.println(ball.getName());
}
}
這個錯誤不easy發現。
答案: 錯。"interfaceRollable extends Playable, Bounceable"沒有問題。interface可繼承多個interfaces,因此這裏沒錯。問題出在interface Rollable裏的"Ball ball =new Ball("PingPang");"。不論什麼在interface裏聲明的interface variable (接口變量,也可稱成員變量),默以爲public static final。也就是說"Ball ball = new Ball("PingPang");"其實是"public staticfinal Ball ball = new Ball("PingPang");"。在Ball類的Play()方法中,"ball = newBall("Football");"改變了ball的reference,而這裏的ball來自Rollable interface,Rollable interface裏的ball是public static final的,final的object是不能被改變reference的。所以編譯器將在"ball = newBall("Football");"這裏顯示有錯。
二.算法與編程
1、編寫一個程序,將a.txt文件裏的單詞與b.txt文件裏的單詞交替合併到c.txt文件裏,a.txt文件裏的單詞用回車符分隔,b.txt文件裏用回車或空格進行分隔。
答:
packagecn.itcast;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class MainClass{
public static voidmain(String[] args) throws Exception{
FileManager a= new FileManager("a.txt",new char[]{'\n'});
FileManager b= new FileManager("b.txt",new char[]{'\n',' '});
FileWriter c= new FileWriter("c.txt");
String aWord= null;
String bWord= null;
while((aWord= a.nextWord()) !=null ){
c.write(aWord+ "\n");
bWord= b.nextWord();
if(bWord!= null)
c.write(bWord+ "\n");
}
while((bWord= b.nextWord()) != null){
c.write(bWord+ "\n");
}
c.close();
}
}
class FileManager{
String[] words =null;
int pos = 0;
publicFileManager(String filename,char[] seperators) throws Exception{
File f = newFile(filename);
FileReaderreader = new FileReader(f);
char[] buf =new char[(int)f.length()];
int len =reader.read(buf);
Stringresults = new String(buf,0,len);
String regex= null;
if(seperators.length>1 ){
regex= "" + seperators[0] + "|" + seperators[1];
}else{
regex= "" + seperators[0];
}
words =results.split(regex);
}
public StringnextWord(){
if(pos ==words.length)
returnnull;
returnwords[pos++];
}
}
2、編寫一個程序,將d:\java文件夾下的所有.java文件拷貝到d:\jad文件夾下,並將原來文件的擴展名從.java改成.jad。
(你們正在作上面這道題,網上遲到的朋友也請作作這道題,找工做必須能編寫這些簡單問題的代碼!)
答:listFiles方法接受一個FileFilter對象,這個FileFilter對象就是過慮的策略對象,不一樣的人提供不一樣的FileFilter實現,即提供了不一樣的過濾策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Jad2Java {
public static voidmain(String[] args) throws Exception {
File srcDir =new File("java");
if(!(srcDir.exists()&& srcDir.isDirectory()))
thrownew Exception("文件夾不存在");
File[] files= srcDir.listFiles(
newFilenameFilter(){
publicboolean accept(File dir, String name) {
returnname.endsWith(".java");
}
}
);
System.out.println(files.length);
File destDir= new File("jad");
if(!destDir.exists())destDir.mkdir();
for(File f:files){
FileInputStream fis = new FileInputStream(f);
StringdestFileName = f.getName().replaceAll("\\.java$", ".jad");
FileOutputStreamfos = new FileOutputStream(new File(destDir,destFileName));
copy(fis,fos);
fis.close();
fos.close();
}
}
private static voidcopy(InputStream ips,OutputStream ops) throws Exception{
int len = 0;
byte[] buf =new byte[1024];
while((len =ips.read(buf)) != -1){
ops.write(buf,0,len);
}
}
}
由本題總結的思想及策略模式的解析:
1.
class jad2java{
1. 獲得某個文件夾下的所有的java文件集合
1.1 獲得文件夾 File srcDir = newFile("d:\\java");
1.2 獲得文件夾下的所有java文件:File[] files =srcDir.listFiles(new MyFileFilter());
1.3 僅僅想獲得.java的文件: class MyFileFilterimplememyts FileFilter{
publicboolean accept(File pathname){
returnpathname.getName().endsWith(".java")
}
}
2.將每個文件拷貝到另一個文件夾,並改擴展名
2.1 獲得目標文件夾,假設目標文件夾不存在,則建立之
2.2 依據源文件名稱獲得目標文件名稱,注意要用正則表達式,注意.的轉義。
2.3 依據表示文件夾的File和目標文件名稱的字符串,獲得表示目標文件的File。
//要在硬盤中準確地建立出一個文件,需要知道文件名稱和文件的文件夾。
2.4 將源文件的流拷貝成目標文件流,拷貝方法獨立成爲一個方法,方法的參數採用抽象流的形式。
//方法接受的參數類型儘可能面向父類,越抽象越好,這樣適應面更寬廣。
}
分析listFiles方法內部的策略模式實現原理
File[] listFiles(FileFilter filter){
File[] files =listFiles();
//ArraylistacceptedFilesList = new ArrayList();
File[] acceptedFiles= new File[files.length];
int pos = 0;
for(File file:files){
booleanaccepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++]= file;
}
}
Arrays.copyOf(acceptedFiles,pos);
//return(File[])accpetedFilesList.toArray();
}
3、編寫一個截取字符串的函數,輸入爲一個字符串和字節數,輸出爲按字節截取的字符串,但要保證漢字不被截取半個,如「我ABC」,4,應該截取「我AB」,輸入「我ABC漢DEF」,6,應該輸出「我ABC」,而不是「我ABC+漢的半個」。
答:
首先要了解中文字符有多種編碼及各類編碼的特徵。
若是n爲要截取的字節數。
public static voidmain(String[] args) throws Exception{
String str ="我a愛中華abc我愛傳智def';
String str ="我ABC漢";
int num =trimGBK(str.getBytes("GBK"),5);
System.out.println(str.substring(0,num));
}
public staticint trimGBK(byte[] buf,int n){
int num = 0;
booleanbChineseFirstHalf = false;
for(inti=0;i<n;i++)
{
if(buf[i]<0&& !bChineseFirstHalf){
bChineseFirstHalf= true;
}else{
num++;
bChineseFirstHalf= false;
}
}
return num;
}
4、有一個字符串,當中包括中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。
答:哈哈,事實上包括中文字符、英文字符、數字字符原來是出題者放的煙霧彈。
String content = 「中國aadf的111薩bbb菲的zz薩菲」;
HashMap map = new HashMap();
for(int i=0;i<content.length;i++)
{
char c =content.charAt(i);
Integer num =map.get(c);
if(num == null)
num = 1;
else
num = num +1;
map.put(c,num);
}
for(Map.EntrySet entry : map)
{
system.out.println(entry.getkey()+ 「:」 + entry.getValue());
}
預計是當初面試的那個學員表述不清楚,問題很是多是:
若是一串字符如"aaaabbc中國1512"要分別統計英文字符的數量,中文字符的數量,和數字字符的數量,若是字符中沒有中文字符、英文字符、數字字符以外的其它特殊字符。
int engishCount;
int chineseCount;
int digitCount;
for(int i=0;i<str.length;i++)
{
charch = str.charAt(i);
if(ch>=’0’&& ch<=’9’)
{
digitCount++
}
elseif((ch>=’a’&& ch<=’z’) || (ch>=’A’ && ch<=’Z’))
{
engishCount++;
}
else
{
chineseCount++;
}
}
System.out.println(……………);
5、說明生活中遇到的二叉樹,用java實現二叉樹
這是組合設計模式。
我有很是多個(若是10萬個)數據要保存起來,之後還需要從保存的這些數據中檢索是否存在某個數據,(我想說出二叉樹的優勢,該怎麼說呢?那就是說別人的缺點),假如存在數組中,那麼,碰巧要找的數字位於99999那個地方,那查找的速度將很是慢,因爲要從第1個依次日後取,取出來後進行比較。平衡二叉樹(構建平衡二叉樹需要先排序,咱們這裏就不做考慮了)可以很是好地解決問題,但二叉樹的遍歷(前序,中序,後序)效率要比數組低很是多,原理例如如下圖:
代碼例如如下:
package com.huawei.interview;
publicclass Node {
public int value;
public Node left;
public Node right;
public void store(intvalue)
{
if(value<this.value)
{
if(left ==null)
{
left = new Node();
left.value=value;
}
else
{
left.store(value);
}
}
else if(value>this.value)
{
if(right ==null)
{
right = new Node();
right.value=value;
}
else
{
right.store(value);
}
}
}
public boolean find(intvalue)
{
System.out.println("happen" +this.value);
if(value ==this.value)
{
return true;
}
else if(value>this.value)
{
if(right ==null)returnfalse;
return right.find(value);
}else
{
if(left ==null)returnfalse;
return left.find(value);
}
}
public void preList()
{
System.out.print(this.value+ ",");
if(left!=null)left.preList();
if(right!=null) right.preList();
}
public void middleList()
{
if(left!=null)left.preList();
System.out.print(this.value+ ",");
if(right!=null)right.preList();
}
public void afterList()
{
if(left!=null)left.preList();
if(right!=null)right.preList();
System.out.print(this.value+ ",");
}
public static voidmain(String [] args)
{
int [] data =new int[20];
for(inti=0;i<data.length;i++)
{
data[i] = (int)(Math.random()*100)+ 1;
System.out.print(data[i] +",");
}
System.out.println();
Node root = new Node();
root.value = data[0];
for(inti=1;i<data.length;i++)
{
root.store(data[i]);
}
root.find(data[19]);
root.preList();
System.out.println();
root.middleList();
System.out.println();
root.afterList();
}
}
-----------------從新臨場寫的代碼---------------------------
importjava.util.Arrays;
importjava.util.Iterator;
public class Node{
private Node left;
private Node right;
private int value;
//private int num;
public Node(int value){
this.value = value;
}
public void add(int value){
if(value > this.value)
{
if(right != null)
right.add(value);
else
{
Node node = new Node(value);
right = node;
}
}
else{
if(left != null)
left.add(value);
else
{
Node node = new Node(value);
left = node;
}
}
}
public boolean find(int value){
if(value == this.value) return true;
else if(value > this.value){
if(right == null) return false;
else return right.find(value);
}else{
if(left == null) return false;
else return left.find(value);
}
}
public void display(){
System.out.println(value);
if(left != null) left.display();
if(right != null) right.display();
}
/*public Iterator iterator(){
}*/
public static void main(String[] args){
int[] values = new int[8];
for(int i=0;i<8;i++){
int num = (int)(Math.random() * 15);
//System.out.println(num);
//if(Arrays.binarySearch(values,num)<0)
if(!contains(values,num))
values[i] = num;
else
i--;
}
System.out.println(Arrays.toString(values));
Node root = new Node(values[0]);
for(int i=1;i<values.length;i++){
root.add(values[i]);
}
System.out.println(root.find(13));
root.display();
}
public static boolean contains(int [] arr,int value){
int i = 0;
for(;i<arr.length;i++){
if(arr[i] == value) return true;
}
return false;
}
}
6、從相似例如如下的文本文件裏讀取出所有的姓名,並打印出反覆的姓名和反覆的次數,並按反覆次數排序:
1,張三,28
2,李四,35
3,張三,28
4,王五,35
5,張三,28
6,李四,35
7,趙六,28
8,田七,35
程序代碼例如如下(答題要博得用人單位的喜歡,包名用該公司,面試前就提早查好該公司的網址,假設查不到,現場問也是可以的。還要加上實現思路的凝視):
package com.huawei.interview;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
publicclass GetNameTest {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
//InputStream ips =GetNameTest.class.getResourceAsStream("/com/huawei/interview/info.txt");
//用上一行凝視的代碼和下一行的代碼都可以,因爲info.txt與GetNameTest類在同一包如下,因此,可以用如下的相對路徑形式
Map results = new HashMap();
InputStream ips = GetNameTest.class.getResourceAsStream("info.txt");
BufferedReader in = newBufferedReader(new InputStreamReader(ips));
String line = null;
try {
while((line=in.readLine())!=null)
{
dealLine(line,results);
}
sortResults(results);
} catch (IOException e) {
// TODO Auto-generated catchblock
e.printStackTrace();
}
}
static class User
{
public String name;
public Integer value;
public User(String name,Integervalue)
{
this.name = name;
this.value = value;
}
@Override
public booleanequals(Object obj) {
// TODO Auto-generated methodstub
//如下的代碼沒有運行,說明往treeset中添加數據時,不會使用到equals方法。
boolean result =super.equals(obj);
System.out.println(result);
return result;
}
}
private static voidsortResults(Map results) {
// TODO Auto-generated method stub
TreeSet sortedResults =newTreeSet(
new Comparator(){
public intcompare(Object o1, Object o2) {
// TODOAuto-generated method stub
User user1 = (User)o1;
User user2 = (User)o2;
/*假設compareTo返回結果0,則以爲兩個對象相等,新的對象不會添加到集合中去
* 因此,不能直接用如下的代碼,不然,那些個數一樣的其它姓名就打印不出來。
* */
//returnuser1.value-user2.value;
//returnuser1.value<user2.value?-1:user1.value==user2.value?0:1;
if(user1.value<user2.value)
{
return -1;
}else if(user1.value>user2.value)
{
return 1;
}else
{
returnuser1.name.compareTo(user2.name);
}
}
}
);
Iterator iterator =results.keySet().iterator();
while(iterator.hasNext())
{
String name = (String)iterator.next();
Integer value =(Integer)results.get(name);
if(value > 1)
{
sortedResults.add(newUser(name,value));
}
}
printResults(sortedResults);
}
private static voidprintResults(TreeSet sortedResults)
{
Iterator iterator = sortedResults.iterator();
while(iterator.hasNext())
{
User user = (User)iterator.next();
System.out.println(user.name +":" + user.value);
}
}
public static voiddealLine(String line,Map map)
{
if(!"".equals(line.trim()))
{
String [] results =line.split(",");
if(results.length == 3)
{
String name = results[1];
Integer value =(Integer)map.get(name);
if(value ==null)value = 0;
map.put(name,value + 1);
}
}
}
}
7、寫一個Singleton出來。
第一種:飽漢模式
public classSingleTon {
private SingleTon(){
}
//實例化放在靜態代碼塊裏可提升程序的運行效率,但也可能更佔用空間
private final static SingleTon instance =new SingleTon();
public static SingleTon getInstance(){
return instance;
}
}
另一種:飢漢模式
public classSingleTon {
private SingleTon(){}
private static instance = null;//newSingleTon();
public static synchronized SingleTongetInstance(){
if(instance == null)
instance = new SingleTon();
return instance;
}
}
第三種:用枚舉
public enum SingleTon{
ONE;
}
第三:更實際的應用(在什麼狀況用單例)
public classSequenceGenerator{
//如下是該類自身的業務功能代碼
private int count = 0;
public synchronized int getSequence(){
++count;
}
//如下是把該類變成單例的代碼
private SequenceGenerator(){}
private final static instance = newSequenceGenerator();
public static SingleTon getInstance(){
return instance;
}
}
第四:
public class MemoryDao
{
private HashMap map = new HashMap();
publicvoid add(Student stu1){
map.put(SequenceGenerator.getInstance().getSequence(),stu1);
}
//把MemoryDao變成單例
}
Singleton模式主要做用是保證在Java應用程序中,一個類Class僅僅有一個實例存在。
通常Singleton模式一般有幾種種形式:
第一種形式: 定義一個類,它的構造函數爲private的,它有一個static的private的該類變量,在類初始化時實例話,經過一個public的getInstance方法獲取對它的引用,繼而調用當中的方法。
public class Singleton {
private Singleton(){}
//在本身內部定義本身一個實例,是否是很是奇怪?
//注意這是private僅僅供內部調用
private staticSingleton instance = new Singleton();
//這裏提供了一個供外部訪問本class的靜態方法,可以直接訪問
public staticSingleton getInstance() {
return instance;
}
}
另一種形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//這種方法比上面有所改進,不用每次都進行生成對象,僅僅是第一次
//使用時生成實例,提升了效率!
if (instance==null)
instance=new Singleton();
return instance;
}
}
其它形式:
定義一個類,它的構造函數爲private的,所有方法爲static的。
通常以爲第一種形式要更加安全些
8、遞歸算法題1
一個整數,大於0,不用循環和本地變量,依照n,2n,4n,8n的順序遞增,當值大於5000時,把值依照指定順序輸出來。
例:n=1237
則輸出爲:
1237,
2474,
4948,
9896,
9896,
4948,
2474,
1237,
提示:敲代碼時,先致謝按遞增方式的代碼,寫好遞增的之後,再添加考慮遞減部分。
public static void doubleNum(int n)
{
System.out.println(n);
if(n<=5000)
doubleNum(n*2);
System.out.println(n);
}
|
9、遞歸算法題2
第1我的10,第2個比第1我的大2歲,依次遞推,請用遞歸方式計算出第8我的多大?
package cn.itcast;
import java.util.Date;
publicclass A1 {
public static voidmain(String [] args)
{
System.out.println(computeAge(8));
}
public static int computeAge(intn)
{
if(n==1)return 10;
returncomputeAge(n-1) + 2;
}
}
public static voidtoBinary(int n,StringBuffer result)
{
if(n/2 != 0)
toBinary(n/2,result);
result.append(n%2);
}
10、排序都有哪幾種方法?請列舉。用JAVA實現一個高速排序。
本人僅僅研究過冒泡排序、選擇排序和高速排序,如下是高速排序的代碼:
public class QuickSort {
/**
* 高速排序
* @param strDate
* @param left
* @param right
*/
public void quickSort(String[] strDate,int left,int right){
String middle,tempDate;
int i,j;
i=left;
j=right;
middle=strDate[(i+j)/2];
do{
while(strDate[i].compareTo(middle)<0&& i<right)
i++; //找出左邊比中間值大的數
while(strDate[j].compareTo(middle)>0&& j>left)
j--; //找出右邊比中間值小的數
if(i<=j){ //將左邊大的數和右邊小的數進行替換
tempDate=strDate[i];
strDate[i]=strDate[j];
strDate[j]=tempDate;
i++;
j--;
}
}while(i<=j); //當二者交錯時中止
if(i<right){
quickSort(strDate,i,right);//從
}
if(j>left){
quickSort(strDate,left,j);
}
}
/**
* @param args
*/
public static void main(String[] args){
String[] strVoid=newString[]{"11","66","22","0","55","22","0","32"};
QuickSort sort=new QuickSort();
sort.quickSort(strVoid,0,strVoid.length-1);
for(int i=0;i<strVoid.length;i++){
System.out.println(strVoid[i]+" ");
}
}
}
11、有數組a[n],用java代碼將數組元素順序顛倒
//用如下的也可以
//for(inti=0,int j=a.length-1;i<j;i++,j--)是否等效於for(int i=0;i<a.length/2;i++)呢?
importjava.util.Arrays;
public classSwapDemo{
public static void main(String[] args){
int [] a = new int[]{
(int)(Math.random() *1000),
(int)(Math.random() * 1000),
(int)(Math.random() *1000),
(int)(Math.random() *1000),
(int)(Math.random() * 1000)
};
System.out.println(a);
System.out.println(Arrays.toString(a));
swap(a);
System.out.println(Arrays.toString(a));
}
public static void swap(int a[]){
int len = a.length;
for(int i=0;i<len/2;i++){
int tmp = a[i];
a[i] = a[len-1-i];
a[len-1-i] = tmp;
}
}
}
12.金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千零一拾一元整)輸出。
去零的代碼:
returnsb.reverse().toString().replaceAll("零[拾佰仟]","零").replaceAll("零+萬","萬").replaceAll("零+元","元").replaceAll("零+","零");
public class RenMingBi {
/**
* @param args add by zxx ,Nov 29, 2008
*/
private static finalchar[] data = new char[]{
'零','壹','貳','叄','肆','伍','陸','柒','捌','玖'
};
private static finalchar[] units = new char[]{
'元','拾','佰','仟','萬','拾','佰','仟','億'
};
public static voidmain(String[] args) {
// TODOAuto-generated method stub
System.out.println(
convert(135689123));
}
public static Stringconvert(int money)
{
StringBuffersbf = new StringBuffer();
int unit = 0;
while(money!=0)
{
sbf.insert(0,units[unit++]);
intnumber = money%10;
sbf.insert(0,data[number]);
money/= 10;
}
returnsbf.toString();
}
}
三. html&JavaScript&ajax部分
1. 推斷第二個日期比第一個日期大
怎樣用腳本推斷用戶輸入的的字符串是如下的時間格式2004-11-21必須要保證用戶的輸入是此格式,並且是時間,比方說月份不大於12等等,另外我須要用戶輸入兩個,並且後一個要比前一個晚,僅僅贊成用JAVASCRIPT,請具體幫助做答,,
//這裏可用正則表達式推斷提早推斷一下格式,而後按下提取各時間字段內容
<script type="text/javascript">
window.onload =function()
{
//這麼寫是爲了實現js代碼與html代碼的分離,當我改動js時,不能影響html代碼。
document.getElementById("frm1").onsubmit=
function(){
vard1 = this.d1.value;
vard2 = this.d2.value;
if(!verifyDate(d1)) {alert("第一個日期格式不正確");return false;}
if(!verifyDate(d2)) {alert("第二個日期格式不正確");return false;}
if(!compareDate(d1,d2)){alert("第二個日期比第一日期小");return false;}
};
}
functioncompareDate(d1,d2)
{
var arrayD1= d1.split("-");
var date1 =new Date(arrayD1[0],arrayD1[1],arrayD1[2]);
var arrayD2= d2.split("-");
var date2 =new Date(arrayD2[0],arrayD2[1],arrayD2[2]);
if(date1> date2) return false;
return true;
}
functionverifyDate(d)
{
vardatePattern = /^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;
returndatePattern.test(d);
}
</script>
<form id="frm1" action="xxx.html">
<input type="text" name="d1" />
<input type="text" name="d2" />
<input type="submit"/>
</form>
2. 用table顯示n條記錄,每3行換一次顏色,即1,2,3用紅色字體,4,5,6用綠色字體,7,8,9用紅顏色字體。
<body>
<table id="tbl">
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td>4</td></tr>
<tr><td>5</td></tr>
<tr><td>6</td></tr>
<tr><td>7</td></tr>
<tr><td>8</td></tr>
<tr><td>9</td></tr>
<tr><td>10</td></tr>
</table>
</body>
<script type="text/javascript">
window.onload=function()
{
var tbl =document.getElementById("tbl");
rows =tbl.getElementsByTagName("tr");
for(i=0;i<rows.length;i++)
{
var j= parseInt(i/3);
if(j%2==0)rows[i].style.backgroundColor="#f00";
else rows[i].style.backgroundColor="#0f0";
}
}
</script>
3、HTML的 form提交以前怎樣驗證數值文本框的內容全部爲數字?不然的話提示用戶並終止提交?
<form onsubmit=’return chkForm(this)’>
<input type="text" name="d1"/>
<input type="submit"/>
</form>
<script type=」text/javascript」 />
function chkForm(this)
{
var value = thist.d1.value;
var len =value.length;
for(vari=0;i<len;i++)
{
if(value.charAt(i)>"9"|| value.charAt(i)<"0")
{
alert("含有非數字字符");
returnfalse;
}
}
return true;
}
</script>
4、請寫出用於校驗HTML文本框中輸入的內容全部爲數字的javascript代碼
<input type="text" id="d1" onblur=" chkNumber(this)"/>
<script type=」text/javascript」 />
function chkNumber(eleText)
{
var value =eleText.value;
var len =value.length;
for(vari=0;i<len;i++)
{
if(value.charAt(i)>"9"|| value.charAt(i)<"0")
{
alert("含有非數字字符");
eleText.focus();
break;
}
}
}
</script>
除了寫完代碼,還應該在網頁上寫出實驗步驟和在代碼中增長實現思路,讓面試官一看就明確你的意圖和檢查你的結果。
5、說說你用過那些ajax技術和框架,說說它們的差異
四. Java web部分
1、Tomcat的優化經驗
答:去掉對web.xml的監視,把jsp提早編輯成Servlet。
有富餘物理內存的狀況,加大tomcat使用的jvm的內存
2、HTTP請求的GET與POST方式的差異
答:servlet有良好的生存期的定義,包含載入和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
3、解釋一下什麼是servlet;
答:servlet有良好的生存期的定義,包含載入和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
4、說一說Servlet的生命週期?
答:servlet有良好的生存期的定義,包含載入和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
Servlet被server實例化後,容器執行其init方法,請求到達時執行其service方法,service方法本身主動派遣執行與請求相應的doXXX方法(doGet,doPost)等,當server決定將實例銷燬的時候調用其destroy方法。
web容器載入servlet,生命週期開始。經過調用servlet的init()方法進行servlet的初始化。經過調用service()方法實現,依據請求的不一樣調用不一樣的do***()方法。結束服務,web容器調用servlet的destroy()方法。
5、Servlet的基本架構
public class ServletName extends HttpServlet {
public void doPost(HttpServletRequest request,HttpServletResponse response) throws
ServletException, IOException {
}
public void doGet(HttpServletRequest request,HttpServletResponse response) throws
ServletException, IOException {
}
}
6、SERVLET API中forward()與redirect()的差異?
答:前者僅是容器中控制權的轉向,在client瀏覽器地址欄中不會顯示出轉向後的地址;後者則是全然的跳轉,瀏覽器將會獲得跳轉的地址,並又一次發送請求連接。這樣,從瀏覽器的地址欄中可以看到跳轉後的連接地址。因此,前者更加高效,在前者可以知足需要時,儘可能使用forward()方法,並且,這樣也有助於隱藏實際的連接。在有些狀況下,比方,需要跳轉到一個其餘server上的資源,則必須使用
sendRedirect()方法。
7、什麼狀況下調用doGet()和doPost()?
Jsp頁面中的FORM標籤裏的method屬性爲get時調用doGet(),爲post時調用doPost()。
8、Request對象的主要方法:
setAttribute(String name,Object):設置名字爲name的request的參數值
getAttribute(String name):返回由name指定的屬性值
getAttributeNames():返回request對象所有屬性的名字集合,結果是一個枚舉的實例
getCookies():返回client的所有Cookie對象,結果是一個Cookie數組
getCharacterEncoding():返回請求中的字符編碼方式
getContentLength():返回請求的Body的長度
getHeader(String name):得到HTTP協議定義的文件頭信息
getHeaders(String name):返回指定名字的request Header的所有值,結果是一個枚舉的實例
getHeaderNames():返回因此request Header的名字,結果是一個枚舉的實例
getInputStream():返回請求的輸入流,用於得到請求中的數據
getMethod():得到client向server端傳送數據的方法
getParameter(String name):得到client傳送給server端的有name指定的參數值
getParameterNames():得到client傳送給server端的所有參數的名字,結果是一個枚舉的實例
getParametervalues(String name):得到有name指定的參數的所有值
getProtocol():獲取client向server端傳送數據所根據的協議名稱
getQueryString():得到查詢字符串
getRequestURI():獲取發出請求字符串的client地址
getRemoteAddr():獲取client的IP地址
getRemoteHost():獲取client的名字
getSession([Boolean create]):返回和請求相關Session
getServerName():獲取server的名字
getServletPath():獲取client所請求的腳本文件的路徑
getServerPort():獲取server的port號
removeAttribute(String name):刪除請求中的一個屬性
9、forward和redirect的差異
forward是server請求資源,server直接訪問目標地址的URL,把那個URL的響應內容讀取過來,而後把這些內容再發給瀏覽器,瀏覽器根本不知道server發送的內容是從哪兒來的,因此它的地址欄中仍是原來的地址。
redirect就是服務端依據邏輯,發送一個狀態碼,告訴瀏覽器又一次去請求那個地址,通常來講瀏覽器會用剛纔請求的所有參數又一次請求,因此session,request參數都可以獲取。
10、request.getAttribute()和 request.getParameter()有何差異?
11. jsp有哪些內置對象?做用各自是什麼?分別有什麼方法?
答:JSP共同擁有下面9個內置的對象:
request 用戶端請求,此請求會包括來自GET/POST請求的參數
response 網頁傳回用戶端的迴應
pageContext 網頁的屬性是在這裏管理
session 與請求有關的會話期
application servlet 正在運行的內容
out 用來傳送回應的輸出
config servlet的構架部件
page JSP網頁自己
exception 針對錯誤網頁,未捕捉的例外
request表示HttpServletRequest對象。它包括了有關瀏覽器請求的信息,並且提供了幾個用於獲取cookie, header,和session數據的實用的方法。
response表示HttpServletResponse對象,並提供了幾個用於設置送回瀏覽器的響應的方法(如cookies,頭信息等)
out對象是javax.jsp.JspWriter的一個實例,並提供了幾個方法使你能用於向瀏覽器回送輸出結果。
pageContext表示一個javax.servlet.jsp.PageContext對象。它是用於方便存取各類範圍的名字空間、servlet相關的對象的API,並且包裝了通用的servlet相關功能的方法。
session表示一個請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶的狀態信息
applicaton 表示一個javax.servle.ServletContext對象。這有助於查找有關servlet引擎和servlet環境的信息
config表示一個javax.servlet.ServletConfig對象。該對象用於存取servlet實例的初始化參數。
page表示從該頁面產生的一個servlet實例
12. jsp有哪些動做?做用各自是什麼?
(這個問題彷佛不重要,不明確爲什麼有此題)
答:JSP共同擁有下面6種基本動做
jsp:include:在頁面被請求的時候引入一個文件。
jsp:useBean:尋找或者實例化一個JavaBean。
jsp:setProperty:設置JavaBean的屬性。
jsp:getProperty:輸出某個JavaBean的屬性。
jsp:forward:把請求轉到一個新的頁面。
jsp:plugin:依據瀏覽器類型爲Java插件生成OBJECT或EMBED標記
13、JSP的常用指令
isErrorPage(可否使用Exception對象),isELIgnored(是否忽略表達式)
14. JSP中動態INCLUDE與靜態INCLUDE的差異?
答:動態INCLUDE用jsp:include動做實現
<jsp:include page=included.jsp flush=true />它老是會檢查所含文件裏的變化,適合用於包括動態頁面,並且可以帶參數靜態INCLUDE用include僞碼實現,定不會檢查所含文件的變化,適用於包括靜態頁面 <%@include file=included.htm %>
15、兩種跳轉方式各自是什麼?有什麼差異?
(如下的回答嚴重錯誤,應該是想問forward和sendRedirect的差異,畢竟出題的人不是專業搞文字藝術的人,可能表達能力並不見得很是強,用詞不必定精準,加之其自身的技術面也可能存在一些問題,不必定真正將他的意思表達清楚了,嚴格意思上來說,一些題目可能根本就無人能答,因此,答題時要掌握主動,僅僅要把本身知道的表達清楚就夠了,而不要去推敲原始題目的詳細含義是什麼,不要一味想着是在答題)
答:有兩種,分別爲:
<jsp:include page=included.jsp flush=true>
<jsp:forward page= nextpage.jsp/>
前者頁面不會轉向include所指的頁面,僅僅是顯示該頁的結果,主頁面仍是原來的頁面。運行完後還會回來,至關於函數調用。並且可以帶參數.後者全然轉向新頁面,不會再回來。至關於go to 語句。
16、頁面間對象傳遞的方法
request,session,application,cookie等
17、JSP和Servlet有哪些一樣點和不一樣點,他們之間的聯繫是什麼?
JSP是Servlet技術的擴展,本質上是Servlet的簡易方式,更強調應用的外表表達。JSP編譯後是"類servlet"。Servlet和JSP最基本的不一樣點在於,Servlet的應用邏輯是在Java文件裏,並且全然從表示層中的HTML裏分離開來。而JSP的狀況是Java和HTML可以組合成一個擴展名爲.jsp的文件。JSP側重於視圖,Servlet主要用於控制邏輯。
18、MVC的各個部分都有那些技術來實現?怎樣實現?
答:MVC是Model-View-Controller的簡寫。Model表明的是應用的業務邏輯(經過JavaBean,EJB組件實現),View是應用的表示面(由JSP頁面產生),Controller是提供應用的處理過程控制(一般是一個Servlet),經過這樣的設計模型把應用邏輯,處理過程和顯示邏輯分紅不一樣的組件實現。這些組件可以進行交互和重用。
19、咱們在web應用開發過程當中經常遇到輸出某種編碼的字符,如iso8859-1等,怎樣輸出一個某種編碼的字符串?
Public String translate(String str) {
String tempStr ="";
try {
tempStr = newString(str.getBytes("ISO-8859-1"), "GBK");
tempStr =tempStr.trim();
}
catch (Exception e) {
System.err.println(e.getMessage());
}
return tempStr;
}
20.現在輸入n個數字,以逗號,分開;而後可選擇升或者降序排序;按提交鍵就在還有一頁面顯示按什麼排序,結果爲,提供reset
五.數據庫部分
1、用兩種方式依據部門號從高到低,工資從低到高列出每個員工的信息。
employee:
eid,ename,salary,deptid;
select * from employeeorder by deptid desc,salary
2、列出各個部門中工資高於本部門的平均工資的員工數和部門號,並按部門號排序
建立表:
mysql> createtable employee921(id int primary key auto_increment,name varchar(5
0),salary bigint,deptid int);
插入實驗數據:
mysql> insert into employee921values(null,'zs',1000,1),(null,'ls',1100,1),(null
,'ww',1100,1),(null,'zl',900,1) ,(null,'zl',1000,2), (null,'zl',900,2),(null,'z
l',1000,2) , (null,'zl',1100,2);
編寫sql語句:
()select avg(salary) from employee921 group by deptid;
()mysql> selectemployee921.id,employee921.name,employee921.salary,employee921.dep
tid tid from employee921where salary > (select avg(salary) from employee921 where deptid = tid);
效率低的一個語句,僅供學習參考使用(在group by以後不能使用where,僅僅能使用having,在group by以前可以使用where,即表示對過濾後的結果分組):
mysql> selectemployee921.id,employee921.name,employee921.salary,employee921.dep
tid tid from employee921where salary > (select avg(salary) from employee921 group by deptid havingdeptid = tid);
()select count(*) ,tid
from (
selectemployee921.id,employee921.name,employee921.salary,employee921.deptid tid
from employee921
where salary>
(selectavg(salary) from employee921 where deptid = tid)
) as t
group by tid ;
第二種方式:關聯查詢
select a.ename,a.salary,a.deptid
from emp a,
(selectdeptd,avg(salary) avgsal from emp group by deptid ) b
where a.deptid=b.deptidand a.salary>b.avgsal;
3、存儲過程與觸發器必須講,經常被面試到?
create procedure insert_Student (_name varchar(50),_age int ,out_id int)
begin
insert into studentvalue(null,_name,_age);
select max(stuId)into _id from student;
end;
call insert_Student('wfz',23,@id);
select @id;
mysql> create trigger update_Student BEFORE update on studentFOR EACH ROW
-> select * from student;
觸發器不一樣意返回結果
create trigger update_StudentBEFORE update on student FOR EACH ROW
insert into student value(null,'zxx',28);
mysql的觸發器眼下不能對當前表進行操做
create trigger update_StudentBEFORE update on student FOR EACH ROW
delete from articles where id=8;
這個樣例不是很是好,最好是用刪除一個用戶時,順帶刪除該用戶的所有帖子
這裏要注意使用OLD.id
觸發器用處仍是很是多的,比方校內網、開心網、Facebook,你發一個日誌,本身主動通知好友,事實上就是在添加日誌時作一個後觸發,再向通知表中寫入條目。因爲觸發器效率高。而UCH沒實用觸發器,效率和數據處理能力都很是低。
存儲過程的實驗步驟:
mysql> delimiter |
mysql> create procedureinsertArticle_Procedure (pTitle varchar(50),pBid int,out
pId int)
-> begin
-> insert into article1value(null,pTitle,pBid);
-> select max(id) into pId fromarticle1;
-> end;
-> |
Query OK, 0 rows affected (0.05sec)
mysql> callinsertArticle_Procedure('傳智播客',1,@pid);
-> |
Query OK, 0 rows affected (0.00sec)
mysql> delimiter ;
mysql> select @pid;
+------+
| @pid |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
mysql> select * fromarticle1;
+----+--------------+------+
| id | title | bid |
+----+--------------+------+
| 1 | test | 1 |
| 2 | chuanzhiboke | 1 |
| 3 | 傳智播客 | 1 |
+----+--------------+------+
3 rows in set (0.00 sec)
觸發器的實驗步驟:
create table board1(id intprimary key auto_increment,name varchar(50),ar
ticleCount int);
create table article1(id intprimary key auto_increment,title varchar(50)
,bid int referencesboard1(id));
delimiter |
create triggerinsertArticle_Trigger after insert on article1 for each ro
w begin
-> update board1 setarticleCount=articleCount+1 where id= NEW.bid;
-> end;
-> |
delimiter ;
insert into board1 value(null,'test',0);
insert into article1value(null,'test',1);
還有,每插入一個帖子,都但願將版面表中的最後發帖時間,帖子總數字段進行同步更新,用觸發器作效率就很是高。下次課設計這樣一個案例,寫觸發器時,對於最後發帖時間可能需要用declare方式聲明一個變量,或者是用NEW.posttime來生成。
4、數據庫三範式是什麼?
第一範式(1NF):字段具備原子性,不可再分。所有關係型數據庫系統都知足第一範式)
數據庫表中的字段都是單一屬性的,不可再分。好比,姓名字段,當中的姓和名必須做爲一個整體,沒法區分哪部分是姓,哪部分是名,假設要區分出姓和名,必須設計成兩個獨立的字段。
第二範式(2NF):
第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必須先知足第一範式(1NF)。
要求數據庫表中的每個實例或行必須可以被唯一地區分。一般需要爲表加上一個列,以存儲各個實例的唯一標識。這個唯一屬性列被稱爲主keyword或主鍵。
第二範式(2NF)要求實體的屬性全然依賴於主keyword。所謂全然依賴是指不能存在僅依賴主keyword一部分的屬性,假設存在,那麼這個屬性和主keyword的這一部分應該分離出來造成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分一般需要爲表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二範式就是非主屬性非部分依賴於主keyword。
第三範式的要求例如如下:
知足第三範式(3NF)必須先知足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包括已在其餘表中已包括的非主keyword信息。
因此第三範式具備例如如下特徵:
1,每一列僅僅有一個值
2,每一行都能區分。
3,每一個表都不包括其它表已經包括的非主keyword信息。
好比,帖子表中僅僅能出現發帖人的id,而不能出現發帖人的id,還同一時候出現發帖人姓名,不然,僅僅要出現同一發帖人id的所有記錄,它們中的姓名部分都必須嚴格保持一致,這就是數據冗餘。
5、說出一些數據庫優化方面的經驗?
用PreparedStatement通常來講比Statement性能高:一個sql發給server去運行,涉及步驟:語法檢查、語義分析,編譯,緩存
「inert into user values(1,1,1)」-à二進制
「inert into user values(2,2,2)」-à二進制
「inert into user values(?,?,?)」-à二進制
有外鍵約束會影響插入和刪除性能,假設程序能夠保證數據的完整性,那在設計數據庫時就去掉外鍵。(比喻:就比如免檢產品,就是爲了提升效率,充分相信產品的製造商)
(對於hibernate來講,就應該有一個變化:empleyee->Deptment對象,現在設計時就成了employeeàdeptid)
看mysql幫助文檔子查詢章節的最後部分,好比,依據掃描的原理,如下的子查詢語句要比第二條關聯查詢的效率高:
1. select e.name,e.salarywhere e.managerid=(select id from employee where name='zxx');
2. select e.name,e.salary,m.name,m.salary fromemployees e,employees m where
e.managerid = m.id andm.name='zxx';
表中贊成適當冗餘,譬如,主題帖的回覆數量和最後回覆時間等
將姓名和password單獨從用戶表中獨立出來。這可以是很好的一對一的案例喲!
sql語句全部大寫,特別是列名和表名都大寫。特別是sql命令的緩存功能,更加需要統一大寫和小寫,sql語句à發給oracleserverà語法檢查和編譯成爲內部指令à緩存和運行指令。依據緩存的特色,不要拼湊條件,而是用?和PreparedStatment
還有索引對查詢性能的改進也是值得關注的。
備註:如下是關於性能的討論舉例
4航班 3個城市
m*n
select * from flight,city where flight.startcityid=city.cityidand city.name='beijing';
m + n
select * from flight where startcityid = (select cityid fromcity where cityname='beijing');
select flight.id,'beijing',flight.flightTime from flight wherestartcityid = (select cityid from city where cityname='beijing')
6、union和union all有什麼不一樣?
若是咱們有一個表Student,包含下面字段與數據:
drop table student;
create table student
(
id int primary key,
name nvarchar2(50) not null,
score number not null
);
insert into student values(1,'Aaron',78);
insert into student values(2,'Bill',76);
insert into student values(3,'Cindy',89);
insert into student values(4,'Damon',90);
insert into student values(5,'Ella',73);
insert into student values(6,'Frado',61);
insert into student values(7,'Gill',99);
insert into student values(8,'Hellen',56);
insert into student values(9,'Ivan',93);
insert into student values(10,'Jay',90);
commit;
Union和Union All的差異。
select *
from student
where id < 4
union
select *
from student
where id > 2 and id < 6
結果將是
1 Aaron 78
2 Bill 76
3 Cindy 89
4 Damon 90
5 Ella 73
假設換成Union All鏈接兩個結果集,則返回結果是:
1 Aaron 78
2 Bill 76
3 Cindy 89
3 Cindy 89
4 Damon 90
5 Ella 73
可以看到,Union和Union All的差異之中的一個在於對反覆結果的處理。
UNION在進行表連接後會篩選掉反覆的記錄,因此在表連接後會對所產生的結果集進行排序運算,刪除反覆的記錄再返回結果。實際大部分應用中是不會產生反覆的記錄,最多見的是過程表與歷史表UNION。如:
select * from gc_dfys
union
select * from ls_jg_dfys
這個SQL在執行時先取出兩個表的結果,再用排序空間進行排序刪除反覆的記錄,最後返回結果集,假設表數據量大的話可能會致使用磁盤進行排序。
而UNION ALL僅僅是簡單的將兩個結果合併後就返回。這樣,假設返回的兩個結果集中有反覆的數據,那麼返回的結果集就會包括反覆的數據了。
從效率上說,UNION ALL要比UNION快很是多,因此,假設可以確認合併的兩個結果集中不包括反覆的數據的話,那麼就使用UNION ALL,
7.分頁語句
取出sql表中第31到40的記錄(以本身主動增加ID爲主鍵)
sql server方案1:
selecttop 10 * from t where id not in (select top 30 id from t order by id ) orde byid
sql server方案2:
selecttop 10 * from t where id in (select top 40 id from t order by id) order by iddesc
mysql方案:select * from t order by idlimit 30,10
oracle方案:select * from (select rownum r,* from t where r<=40) wherer>30
--------------------待整理進去的內容-------------------------------------
pageSize=20;
pageNo = 5;
1.分頁技術1(直接利用sql語句進行分頁,效率最高和最推薦的)
mysql:sql = "select * from articles limit " +(pageNo-1)*pageSize + "," + pageSize;
oracle: sql = "select * from " +
"(selectrownum r,* from " +
"(select* from articles order by postime desc)" +
"whererownum<= " + pageNo*pageSize +") tmp " +
"wherer>" + (pageNo-1)*pageSize;
凝視:第7行保證rownum的順序是肯定的,因爲oracle的索引會形成rownum返回不一樣的值
簡洋提示:沒有order by時,rownum按順序輸出,一旦有了order by,rownum不按順序輸出了,這說明rownum是排序前的編號。假設對order by從句中的字段創建了索引,那麼,rownum也是按順序輸出的,因爲這時候生成原始的查詢結果集時會參照索引表的順序來構建。
sqlserver:sql = "select top 10 * from id not id(select top" + (pageNo-1)*pageSize + "id from articles)"
DataSource ds = new InitialContext().lookup(jndiurl);
Connection cn = ds.getConnection();
//"select * from user where id=?" --->binary directive
PreparedStatement pstmt = cn.prepareSatement(sql);
ResultSet rs = pstmt.executeQuery()
while(rs.next())
{
out.println(rs.getString(1));
}
2.不可滾動的遊標
pageSize=20;
pageNo = 5;
cn = null
stmt = null;
rs = null;
try
{
sqlserver:sql = "select * from articles";
DataSource ds = new InitialContext().lookup(jndiurl);
Connection cn = ds.getConnection();
//"select * from user where id=?" --->binary directive
PreparedStatement pstmt = cn.prepareSatement(sql);
ResultSet rs = pstmt.executeQuery()
for(int j=0;j<(pageNo-1)*pageSize;j++)
{
rs.next();
}
int i=0;
while(rs.next() && i<10)
{
i++;
out.println(rs.getString(1));
}
}
cacth(){}
finnaly
{
if(rs!=null)try{rs.close();}catch(Exceptione){}
if(stm.........
if(cn............
}
3.可滾動的遊標
pageSize=20;
pageNo = 5;
cn = null
stmt = null;
rs = null;
try
{
sqlserver:sql = "select * from articles";
DataSource ds = new InitialContext().lookup(jndiurl);
Connection cn = ds.getConnection();
//"select * from user where id=?" --->binary directive
PreparedStatement pstmt = cn.prepareSatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,...);
//依據上面這行代碼的異常SQLFeatureNotSupportedException,就可推斷驅動是否支持可滾動遊標
ResultSet rs = pstmt.executeQuery()
rs.absolute((pageNo-1)*pageSize)
int i=0;
while(rs.next() && i<10)
{
i++;
out.println(rs.getString(1));
}
}
cacth(){}
finnaly
{
if(rs!=null)try{rs.close();}catch(Exceptione){}
if(stm.........
if(cn............
}
8.用一條SQL語句查詢出每門課都大於80分的學生姓名
name kecheng fenshu
張三 語文 81
張三 數學 75
李四 語文 76
李四 數學 90
王五 語文 81
王五 數學 100
王五 英語 90
準備數據的sql代碼:
create table score(id int primary key auto_increment,namevarchar(20),subject varchar(20),score int);
insert into score values
(null,'張三','語文',81),
(null,'張三','數學',75),
(null,'李四','語文',76),
(null,'李四','數學',90),
(null,'王五','語文',81),
(null,'王五','數學',100),
(null,'王五 ','英語',90);
提示:當百思不得其解時,請理想思惟,把小變成大作,把大變成小作,
答案:
A: select distinct name from score where name not in (selectdistinct name from score where score<=80)
B:select distince name t1 from score where 80< all (selectscore from score where name=t1);
9.所有部門之間的比賽組合
一個叫department的表,裏面僅僅有一個字段name,一共同擁有4條紀錄,各自是a,b,c,d,相應四個球對,現在四個球對進行比賽,用一條sql語句顯示所有可能的比賽組合.
答:select a.name,b.name
from team a, team b
where a.name < b.name
10.每個月份的發生額都比101科目多的科目
請用SQL語句實現:從TestDB數據表中查詢出所有月份的發生額都比101科目對應月份的發生額高的科目。請注意:TestDB中有很是多科目,都有1-12月份的發生額。
AccID:科目代碼,Occmonth:發生額月份,DebitOccur:發生額。
數據庫名:JcyAudit,數據集:Select * from TestDB
準備數據的sql代碼:
drop table if exists TestDB;
create table TestDB(id int primary key auto_increment,AccIDvarchar(20), Occmonth date, DebitOccur bigint);
insert into TestDB values
(null,'101','1988-1-1',100),
(null,'101','1988-2-1',110),
(null,'101','1988-3-1',120),
(null,'101','1988-4-1',100),
(null,'101','1988-5-1',100),
(null,'101','1988-6-1',100),
(null,'101','1988-7-1',100),
(null,'101','1988-8-1',100);
--複製上面的數據,有益把第一個月份的發生額數字改小一點
insert into TestDB values
(null,'102','1988-1-1',90),
(null,'102','1988-2-1',110),
(null,'102','1988-3-1',120),
(null,'102','1988-4-1',100),
(null,'102','1988-5-1',100),
(null,'102','1988-6-1',100),
(null,'102','1988-7-1',100),
(null,'102','1988-8-1',100);
--複製最上面的數據,有益把所有發生額數字改大一點
insert into TestDB values
(null,'103','1988-1-1',150),
(null,'103','1988-2-1',160),
(null,'103','1988-3-1',180),
(null,'103','1988-4-1',120),
(null,'103','1988-5-1',120),
(null,'103','1988-6-1',120),
(null,'103','1988-7-1',120),
(null,'103','1988-8-1',120);
--複製最上面的數據,有益把所有發生額數字改大一點
insert into TestDB values
(null,'104','1988-1-1',130),
(null,'104','1988-2-1',130),
(null,'104','1988-3-1',140),
(null,'104','1988-4-1',150),
(null,'104','1988-5-1',160),
(null,'104','1988-6-1',170),
(null,'104','1988-7-1',180),
(null,'104','1988-8-1',140);
--複製最上面的數據,有益把第二個月份的發生額數字改小一點
insert into TestDB values
(null,'105','1988-1-1',100),
(null,'105','1988-2-1',80),
(null,'105','1988-3-1',120),
(null,'105','1988-4-1',100),
(null,'105','1988-5-1',100),
(null,'105','1988-6-1',100),
(null,'105','1988-7-1',100),
(null,'105','1988-8-1',100);
答案:
select distinct AccID from TestDB
where AccID not in
(selectTestDB.AccIDfrom TestDB,
(select * from TestDB where AccID='101') asdb101
whereTestDB.Occmonth=db101.Occmonth and TestDB.DebitOccur<=db101.DebitOccur
);
11.統計每一年每個月的信息
year monthamount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成這樣一個結果
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
提示:這個與工資條很是相似,與學生的科目成績也很是類似。
準備sql語句:
drop table if existssales;
create table sales(idint auto_increment primary key,year varchar(10), month varchar(10), amountfloat(2,1));
insert into salesvalues
(null,'1991','1',1.1),
(null,'1991','2',1.2),
(null,'1991','3',1.3),
(null,'1991','4',1.4),
(null,'1992','1',2.1),
(null,'1992','2',2.2),
(null,'1992','3',2.3),
(null,'1992','4',2.4);
答案1、
select sales.year ,
(select t.amount fromsales t where t.month='1' and t.year= sales.year) '1',
(select t.amount fromsales t where t.month='1' and t.year= sales.year) '2',
(select t.amount fromsales t where t.month='1' and t.year= sales.year) '3',
(select t.amount fromsales t where t.month='1' and t.year= sales.year) as '4'
from sales group by year;
12.顯示文章標題,發帖人、最後回覆時間
表:id,title,postuser,postdate,parentid
準備sql語句:
drop table if exists articles;
create table articles(id int auto_increment primary key,titlevarchar(50), postuser varchar(10), postdate datetime,parentid int referencesarticles(id));
insert into articles values
(null,'第一條','張三','1998-10-10 12:32:32',null),
(null,'第二條','張三','1998-10-10 12:34:32',null),
(null,'第一條回覆1','李四','1998-10-10 12:35:32',1),
(null,'第二條回覆1','李四','1998-10-10 12:36:32',2),
(null,'第一條回覆2','王五','1998-10-10 12:37:32',1),
(null,'第一條回覆3','李四','1998-10-10 12:38:32',1),
(null,'第二條回覆2','李四','1998-10-10 12:39:32',2),
(null,'第一條回覆4','王五','1998-10-10 12:39:40',1);
答案:
select a.title,a.postuser,
(selectmax(postdate) from articles where parentid=a.id) reply
from articles a where a.parentid is null;
凝視:子查詢可以用在選擇列中,也可用於where的比較條件中,還可以用於from從句中。
13.刪除除了id號不一樣,其它都一樣的學生冗餘信息
2.學生表例如如下:
id號 學號 姓名課程編號課程名稱分數
1 2005001 張三 0001 數學 69
2 2005002 李四 0001 數學 89
3 2005001 張三 0001 數學 69
A: delete from tablename where id號 not in(select min(id號) from tablename group by學號,姓名,課程編號,課程名稱,分數)
實驗:
create table student2(id int auto_increment primary key,codevarchar(20),name varchar(20));
insert into student2 values(null,'2005001','張三'),(null,'2005002','李四'),(null,'2005001','張三');
//例如如下語句,mysql報告錯誤,可能刪除依賴後面統計語句,而刪除又致使統計語句結果不一致。
delete from student2 where id not in(select min(id) fromstudent2 group by name);
//但是,例如如下語句沒有問題:
select * from student2where id not in(select min(id) from student2 group by name);
//因而,我想先把分組的結果作成虛表,而後從虛表中選出結果,最後再將結果做爲刪除的條件數據。
delete from student2 where id not in(select mid from (selectmin(id) mid
from student2 group by name) as t);
或者:
delete from student2 where id not in(select min(id) from (select* from s
tudent2) as t group by t.name);
14.航空網的幾個航班查詢題:
表結構例如如下:
flight{flightID,StartCityID ,endCityID,StartTime}
city{cityID, CityName)
實驗環境:
create table city(cityID int auto_increment primary key,cityNamevarchar(20));
create table flight (flightID int auto_increment primary key,
StartCityID intreferences city(cityID),
endCityID int references city(cityID),
StartTimetimestamp);
//航班原本應該沒有日期部分纔好,但是如下的題目其中涉及到了日期
insert into city values(null,'北京'),(null,'上海'),(null,'廣州');
insert into flight values
(null,1,2,'9:37:23'),(null,1,3,'9:37:23'),(null,1,2,'10:37:23'),(null,2,3,'10:37:23');
1、查詢起飛城市是北京的所有航班,按到達城市的名字排序
參與運算的列是我起碼能夠顯示出來的那些列,但終於我不必定把它們顯示出來。各個表組合出來的中間結果字段中必須包括所有運算的字段。
select * from flight f,city c
where f.endcityid =c.cityid and startcityid =
(select c1.cityidfrom city c1 where c1.cityname = "北京")
order by c.citynameasc;
mysql> select flight.flightid,'北京' startcity, e.cityname from flight,city e wh
ere flight.endcityid=e.cityid and flight.startcityid=(selectcityid from city wh
ere cityname='北京');
mysql> select flight.flightid,s.cityname,e.cityname fromflight,city s,city e wh
ere flight.startcityid=s.cityid and s.cityname='北京' andflight.endCityId=e.cit
yID order by e.cityName desc;
2、查詢北京到上海的所有航班紀錄(起飛城市,到達城市,起飛時間,航班號)
select c1.CityName,c2.CityName,f.StartTime,f.flightID
from city c1,city c2,flight f
where f.StartCityID=c1.cityID
and f.endCityID=c2.cityID
and c1.cityName='北京'
and c2.cityName='上海'
3、查詢詳細某一天(2005-5-8)的北京到上海的的航班次數
select count(*) from
(select c1.CityName,c2.CityName,f.StartTime,f.flightID
from city c1,city c2,flight f
where f.StartCityID=c1.cityID
and f.endCityID=c2.cityID
and c1.cityName='北京'
and c2.cityName='上海'
and 查幫助得到的某個日期處理函數(startTime) like '2005-5-8%'
mysql中提取日期部分進行比較的演示樣例代碼例如如下:
select * from flight wheredate_format(starttime,'%Y-%m-%d')='1998-01-02'
15.查出比經理薪水還高的員工信息:
Drop table if not exists employees;
create table employees(id int primary key auto_increment,namevarchar(50)
,salary int,managerid intreferences employees(id));
insert into employees values (null,' lhm',10000,null), (null,'zxx',15000,1
),(null,'flx',9000,1),(null,'tg',10000,2),(null,'wzg',10000,3);
Wzg大於flx,lhm大於zxx
解題思路:
依據sql語句的查詢特色,是逐行進行運算,不可能兩行同一時候參與運算。
涉及了員工薪水和經理薪水,所有,一行記錄要同一時候包括兩個薪水,所有想到要把這個表自關聯組合一下。
首先要組合出一個包括有各個員工及該員工的經理信息的長記錄,譬如,左半部分是員工,右半部分是經理。而迪卡爾積會組合出很是多垃圾信息,先去除這些垃圾信息。
select e.* from employees e,employees m where e.managerid=m.idand e.sala
ry>m.salary;
16、求出小於45歲的各個老師所帶的大於12歲的學生人數
數據庫中有3個表 teacher表,student表,tea_stu關係表。
teacher 表 teaID name age
student 表 stuID name age
teacher_student表 teaID stuID
要求用一條sql查詢出這種結果
1.顯示的字段要有老師name, age每個老師所帶的學生人數
2 僅僅列出老師age爲40下面,學生age爲12以上的記錄
預備知識:
1.sql語句是對每一條記錄依次處理,條件爲真則運行動做(select,insert,delete,update)
2.僅僅要是迪卡爾積,就會產生「垃圾」信息,因此,僅僅要迪卡爾積了,咱們首先就要想到清除「垃圾」信息
實驗準備:
drop table if exists tea_stu;
drop table if exists teacher;
drop table if exists student;
create table teacher(teaID int primarykey,name varchar(50),age int);
create table student(stuID int primarykey,name varchar(50),age int);
create table tea_stu(teaID int referencesteacher(teaID),stuID int references student(stuID));
insertinto teacher values(1,'zxx',45), (2,'lhm',25) , (3,'wzg',26) , (4,'tg',27);
insertinto student values(1,'wy',11), (2,'dh',25) , (3,'ysq',26) , (4,'mxc',27);
insertinto tea_stu values(1,1), (1,2), (1,3);
insertinto tea_stu values(2,2), (2,3), (2,4);
insert into tea_stu values(3,3), (3,4), (3,1);
insertinto tea_stu values(4,4), (4,1), (4,2) , (4,3);
結果:2à3,3à2,4à3
解題思路:(真實面試答題時,也要寫出每個分析步驟,假設紙張不夠,就找別人要)
1要會統計分組信息,統計信息放在中間表中:
selectteaid,count(*) from tea_stu group by teaid;
2接着事實上應該是篩除掉小於12歲的學生,而後再進行統計,中間表必須與student關聯才幹獲得12歲下面學生和把該學生記錄從中間表中剔除,代碼是:
selecttea_stu.teaid,count(*) total from student,tea_stu
wherestudent.stuid=tea_stu.stuid and student.age>12 group by tea_stu.teaid
3.接着把上面的結果作成虛表與teacher進行關聯,並篩除大於45的老師
selectteacher.teaid,teacher.name,total from teacher ,(select tea_stu.tea
id,count(*)total from student,tea_stu where student.stuid=tea_stu.stuid and stu
dent.age>12group by tea_stu.teaid) as tea_stu2where teacher.teaid=tea_stu2.tea
idand teacher.age<45;
17.求出發帖最多的人:
select authorid,count(*) total from articles
group by authorid
having total=
(select max(total2) from(select count(*) total2 from articles group by authorid) as t);
select t.authorid,max(t.total) from
(select authorid,count(*) total from articles)as t
這條語句不行,因爲max僅僅有一列,不能與其它列混淆。
select authorid,count(*) total from articles
group by authorid having total=max(total)也不行。
18、一個用戶表中有一個積分字段,假如數據庫中有100多萬個用戶,若要在每一年第一天凌晨將積分清零,你將考慮什麼,你將想什麼辦法解決?
alter table drop column score;
alter table add colunm score int;
可能會很是快,但是需要試驗,試驗不能拿真實的環境來操刀,並且要注意,
這種操做時沒法回滾的,在個人印象中,僅僅有inert update delete等DML語句才幹回滾,
對於create table,drop table ,alter table等DDL語句是不能回滾。
解決方式一,update user set score=0;
解決方式二,若是上面的代碼要運行好長時間,超出咱們的容忍範圍,那我就alter table user drop columnscore;alter table user add column score int。
如下代碼實現每一年的那個凌晨時刻進行清零。
Runnable runnable =
new Runnable(){
public voidrun(){
clearDb();
schedule(this,newDate(new Date().getYear()+1,0,0));
}
};
schedule(runnable,
new Date(newDate().getYear()+1,0,1));
19、一個用戶具備多個角色,請查詢出該表中具備該用戶的所有角色的其它用戶。
select count(*) as num,tb.id
from
tb,
(select role from tbwhere id=xxx) as t1
where
tb.role = t1.role andtb.id != t1.id
group by tb.id
having
num = select count(role)from tb where id=xxx;
20. xxx公司的sql面試
Table EMPLOYEES Structure:
EMPLOYEE_ID NUMBER Primary Key,
FIRST_NAME VARCHAR2(25),
LAST_NAME VARCHAR2(25),
Salary number(8,2),
HiredDate DATE,
Departmentid number(2)
TableDepartments Structure:
Departmentid number(2) Primary Key,
DepartmentName VARCHAR2(25).
(2)基於上述EMPLOYEES表寫出查詢:寫出僱用日期在今年的,或者工資在[1000,2000]之間的,或者員工姓名(last_name)以’Obama’打頭的全部員工,列出這些員工的全部我的信息。(4分)
select* from employees
whereYear(hiredDate) = Year(date())
or (salary between 1000 and 200)
or left(last_name,3)='abc';
(3) 基於上述EMPLOYEES表寫出查詢:查出部門平均工資大於1800元的部門的全部員工,列出這些員工的全部我的信息。(4分)
mysql>select id,name,salary,deptid did from employee1 where (select avg(salary)
from employee1 where deptid = did) > 1800;
(4) 基於上述EMPLOYEES表寫出查詢:查出我的工資高於其所在部門平均工資的員工,列出這些員工的全部我的信息及該員工工資高出部門平均工資百分比。(5分)
selectemployee1.*,(employee1.salary-t.avgSalary)*100/employee1.salary
fromemployee1,
(select deptid,avg(salary) avgSalary fromemployee1 group by deptid) as t
whereemployee1.deptid = t.deptid and employee1.salary>t.avgSalary;
21、註冊Jdbc驅動程序的三種方式
22、用JDBC怎樣調用存儲過程
代碼例如如下:
package com.huawei.interview.lym;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
publicclass JdbcTest {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
Connection cn = null;
CallableStatement cstmt =null;
try {
//這裏最好不要這麼幹,因爲驅動名寫死在程序中了
Class.forName("com.mysql.jdbc.Driver");
//實際項目中,這裏應用DataSource數據,假設用框架,
//這個數據源不需要咱們編碼建立,咱們僅僅需Datasource ds =context.lookup()
//cn = ds.getConnection();
cn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
cstmt = cn.prepareCall("{callinsert_Student(?,?,?)}");
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1,"wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
//get第幾個,不一樣的數據庫不同,建議不寫
System.out.println(cstmt.getString(3));
} catch (Exception e) {
// TODO Auto-generated catchblock
e.printStackTrace();
}
finally
{
/*try{cstmt.close();}catch(Exceptione){}
try{cn.close();}catch(Exceptione){}*/
try {
if(cstmt !=null)
cstmt.close();
if(cn !=null)
cn.close();
} catch (SQLException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
23、JDBC中的PreparedStatement相比Statement的優勢
答:一個sql命令發給server去運行的步驟爲:語法檢查,語義分析,編譯成內部指令,緩存指令,運行指令等過程。
select * from student where id =3----緩存--àxxxxx二進制命令
select * from student where id =3----直接取-àxxxxx二進制命令
select * from student where id =4--- -à會怎麼幹?
假設當初是select * from student where id =?--- -à又會怎麼幹?
上面說的是性能提升
可以防止sql注入。
24. 寫一個用jdbc鏈接並訪問oracle數據的程序代碼
25、Class.forName的做用?爲何要用?
答:按參數中指定的字符串形式的類名去搜索並載入對應的類,假設該類字節碼已經被載入過,則返回表明該字節碼的Class實例對象,不然,按類載入器的託付機制去搜索和載入該類,假設所有的類載入器都沒法載入到該類,則拋出ClassNotFoundException。載入完這個Class字節碼後,接着就可以使用Class字節碼的newInstance方法去建立該類的實例對象了。
有時候,咱們程序中所有使用的詳細類名在設計時(即開發時)沒法肯定,僅僅有程序執行時才幹肯定,這時候就需要使用Class.forName去動態載入該類,這個類名通常是在配置文件裏配置的,好比,spring的ioc中每次依賴注入的詳細類就是這樣配置的,jdbc的驅動類名一般也是經過配置文件來配置的,以便在產品交付使用後不用改動源程序就可以更換驅動類名。
26、大數據量下的分頁解決方法。
答:最好的辦法是利用sql語句進行分頁,這樣每次查詢出的結果集中就僅僅包括某頁的數據內容。再sql語句沒法實現分頁的狀況下,可以考慮對大的結果集經過遊標定位方式來獲取某頁的數據。
sql語句分頁,不一樣的數據庫下的分頁方案各不同,如下是主流的三種數據庫的分頁sql:
sql server:
String sql =
"select top" + pageSize + " * from students where id not in" +
"(select top "+ pageSize * (pageNumber-1) + " id from students order by id)" +
"order by id";
mysql:
String sql =
"select * fromstudents order by id limit " + pageSize*(pageNumber-1) + "," +pageSize;
oracle:
String sql =
"select * from " +
(select *,rownum rid from (select * fromstudents order by postime desc) where rid<=" + pagesize*pagenumber +") as t" +
"where t>" +pageSize*(pageNumber-1);
27、用 JDBC查詢學生成績單,把主要代碼寫出來(考試機率極大).
Connection cn = null;
PreparedStatement pstmt =null;
Resultset rs = null;
try
{
Class.forname(driveClassName);
cn = DriverManager.getConnection(url,username,password);
pstmt =cn.prepareStatement(「select score.* fromscore ,student 「 +
「wherescore.stuId = student.id and student.name = ?」);
pstmt.setString(1,studentName);
Resultset rs =pstmt.executeQuery();
while(rs.next())
{
system.out.println(rs.getInt(「subject」) + 「 」 + rs.getFloat(「score」) );
}
}catch(Exception e){e.printStackTrace();}
finally
{
if(rs != null) try{rs.close() }catch(exception e){}
if(pstmt != null)try{pstmt.close()}catch(exception e){}
if(cn != null) try{cn.close() }catch(exception e){}
}
28、這段代碼有什麼不足之處?
try {
Connection conn = ...;
Statement stmt = ...;
ResultSet rs =stmt.executeQuery("select * from table1");
while(rs.next()) {
}
} catch(Exception ex) {
}
答:沒有finally語句來關閉各個對象,另外,使用finally以後,要把變量的定義放在try語句塊的外面,以便在try語句塊以外的finally塊中仍可以訪問這些變量。
29、說出數據鏈接池的工做機制是什麼?
J2EEserver啓動時會創建必定數量的池鏈接,並一直維持很多於此數目的池鏈接。client程序需要鏈接時,池驅動程序會返回一個未使用的池鏈接並將其表記爲忙。假設當前沒有空暇鏈接,池驅動程序就新建必定數量的鏈接,新建鏈接的數量有配置參數決定。當使用的池鏈接調用完畢後,池驅動程序將此鏈接表記爲空暇,其它調用就可以使用這個鏈接。
實現方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正關鏈接,而是把它代理的Connection對象還回到鏈接池中。
30、爲何要用 ORM? 和 JDBC有何不同?
orm是一種思想,就是把object轉變成數據庫中的記錄,或者把數據庫中的記錄轉變成objecdt,咱們可以用jdbc來實現這樣的思想,事實上,假設咱們的項目是嚴格依照oop方式編寫的話,咱們的jdbc程序不管是有意仍是無心,就已經在實現orm的工做了。
現在有不少orm工具,它們底層調用jdbc來實現了orm工做,咱們直接使用這些工具,就省去了直接使用jdbc的繁瑣細節,提升了開發效率,現在用的較多的orm工具是hibernate。也據說一些其它orm工具,如toplink,ojb等。
六. XML部分
1、xml有哪些解析技術?差異是什麼?
答:有DOM,SAX,STAX等
DOM:處理大型文件時其性能降低的很厲害。這個問題是由DOM的樹結構所形成的,這樣的結構佔用的內存較多,而且DOM必須在解析文件以前把整個文檔裝入內存,適合對XML的隨機訪問SAX:不現於DOM,SAX是事件驅動型的XML解析方式。它順序讀取XML文件,不需要一次全部裝載整個文件。當遇到像文件開頭,文檔結束,或者標籤開頭與標籤結束時,它會觸發一個事件,用戶經過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問
STAX:Streaming API for XML (StAX)
解說這些差異是不需要特別去比較,就像說傳智播客與其它培訓機構的差異時,咱們僅僅需說清楚傳智播客有什麼特色和長處便可了,這就已經間接回答了彼此的差異。
2、你在項目中用到了xml技術的哪些方面?怎樣實現的?
答:用到了數據存貯,信息配置雙方面。在作數據交換平臺時,將不能數據源的數據組裝成XML文件,而後將XML文件壓縮打包加密後經過網絡傳送給接收者,接收解密與解壓縮後再同XML文件裏還原相關信息進行處理。在作軟件配置時,利用XML可以很是方便的進行,軟件的各類配置參數都存貯在XML文件裏。
3、用jdom解析xml文件時怎樣解決中文問題?怎樣解析?
答:看例如如下代碼,用編碼方式加以解決
package test;
import java.io.*;
public class DOMTest
{
private String inFile = "c:\\people.xml"
private String outFile = "c:\\people.xml"
public static void main(String args[])
{
new DOMTest();
}
public DOMTest()
{
try
{
javax.xml.parsers.DocumentBuilder builder =
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
org.w3c.dom.Document doc = builder.newDocument();
org.w3c.dom.Element root = doc.createElement("老師");
org.w3c.dom.Element wang = doc.createElement("王");
org.w3c.dom.Element liu = doc.createElement("劉");
wang.appendChild(doc.createTextNode("我是王老師"));
root.appendChild(wang);
doc.appendChild(root);
javax.xml.transform.Transformer transformer =
javax.xml.transform.TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING,"gb2312");
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT,"yes");
transformer.transform(newjavax.xml.transform.dom.DOMSource(doc),
new
javax.xml.transform.stream.StreamResult(outFile));
}
catch (Exception e)
{
System.out.println (e.getMessage());
}
}
}
4、編程用JAVA解析XML的方式.
答:用SAX方式解析XML,XML文件例如如下:
<?xml version=1.0 encoding=gb2312?>
<person>
<name>王小明</name>
<college>信息學院</college>
<telephone>6258113</telephone>
<notes>男,1955年生,博士,95年調入海南大學</notes>
</person>
事件回調類SAXHandler.java
import java.io.*;
import java.util.Hashtable;
import org.xml.sax.*;
public class SAXHandler extends HandlerBase
{
private Hashtable table = new Hashtable();
private String currentElement = null;
private String currentValue = null;
public void setTable(Hashtable table)
{
this.table = table;
}
public Hashtable getTable()
{
return table;
}
public void startElement(String tag, AttributeList attrs)
throws SAXException
{
currentElement = tag;
}
public void characters(char[] ch, int start, int length)
throws SAXException
{
currentValue = new String(ch, start, length);
}
public void endElement(String name) throws SAXException
{
if (currentElement.equals(name))
table.put(currentElement, currentValue);
}
}
JSP內容顯示源代碼,SaxXml.jsp:
<HTML>
<HEAD>
<TITLE>剖析XML文件people.xml</TITLE>
</HEAD>
<BODY>
<%@ page errorPage=ErrPage.jsp
contentType=text/html;charset=GB2312 %>
<%@ page import=java.io.* %>
<%@ page import=java.util.Hashtable %>
<%@ page import=org.w3c.dom.* %>
<%@ page import=org.xml.sax.* %>
<%@ page import=javax.xml.parsers.SAXParserFactory %>
<%@ page import=javax.xml.parsers.SAXParser %>
<%@ page import=SAXHandler %>
<%
File file = new File(c:\people.xml);
FileReader reader = new FileReader(file);
Parser parser;
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
SAXHandler handler = new SAXHandler();
sp.parse(new InputSource(reader), handler);
Hashtable hashTable = handler.getTable();
out.println(<TABLE BORDER=2><CAPTION>教師信息表</CAPTION>);
out.println(<TR><TD>姓名</TD> + <TD> +
(String)hashTable.get(new String(name)) +</TD></TR>);
out.println(<TR><TD>學院</TD> + <TD> +
(String)hashTable.get(newString(college))+</TD></TR>);
out.println(<TR><TD>電話</TD> + <TD> +
(String)hashTable.get(new String(telephone)) +</TD></TR>);
out.println(<TR><TD>備註</TD> + <TD> +
(String)hashTable.get(new String(notes)) +</TD></TR>);
out.println(</TABLE>);
%>
</BODY>
</HTML>
5、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 forXML (StAX)
七.流行的框架與新技術
1、談談你對Struts的理解。
答:
1. struts是一個按MVC模式設計的Web層框架,事實上它就是一個大大的servlet,這個Servlet名爲ActionServlet,或是ActionServlet的子類。咱們可以在web.xml文件裏將符合某種特徵的所有請求交給這個Servlet處理,這個Servlet再參照一個配置文件(一般爲/WEB-INF/struts-config.xml)將各個請求分別分配給不一樣的action去處理。
一個擴展知識點:struts的配置文件可以有多個,可以按模塊配置各自的配置文件,這樣可以防止配置文件的過分膨脹;
2.ActionServlet把請求交給action去處理以前,會將請求參數封裝成一個formbean對象(就是一個java類,這個類中的每個屬性相應一個請求參數),封裝成一個什麼樣的formbean對象呢?看配置文件。
3.要說明的是, ActionServlet把formbean對象傳遞給action的execute方法以前,可能會調用formbean的validate方法進行校驗,僅僅有校驗經過後纔將這個formbean對象傳遞給action的execute方法,不然,它將返回一個錯誤頁面,這個錯誤頁面由input屬性指定,(看配置文件)做者爲何將這裏命名爲input屬性,而不是error屬性,咱們後面結合實際的執行效果進行分析。
4.action運行完後要返回顯示的結果視圖,這個結果視圖是用一個ActionForward對象來表示的,actionforward對象經過struts-config.xml配置文件裏的配置關聯到某個jsp頁面,因爲程序中使用的是在struts-config.xml配置文件爲jsp頁面設置的邏輯名,這樣可以實現action程序代碼與返回的jsp頁面名稱的解耦。
你對struts可能還有本身的應用方面的經驗,那也要一併說出來。
2、談談你對Hibernate的理解。
答:
1. 面向對象設計的軟件內部執行過程可以理解成就是在不斷建立各類新對象、創建對象之間的關係,調用對象的方法來改變各個對象的狀態和對象消亡的過程,不管程序執行的過程和操做怎麼樣,本質上都是要獲得一個結果,程序上一個時刻和下一個時刻的執行結果的差別就表現在內存中的對象狀態發生了變化。
2.爲了在關機和內存空間不夠的情況下,保持程序的執行狀態,需要將內存中的對象狀態保存到持久化設備和從持久化設備中恢復出對象的狀態,一般都是保存到關係數據庫來保存大量對象信息。從Java程序的執行功能上來說,保存對象狀態的功能相比系統執行的其它功能來講,應該是一個很是不起眼的附屬功能,java採用jdbc來實現這個功能,這個不起眼的功能卻要編寫大量的代碼,而作的事情不過保存對象和恢復對象,並且那些大量的jdbc代碼並無什麼技術含量,基本上是採用一套例行公事的標準代碼模板來編寫,是一種苦活和反覆性的工做。
3.經過數據庫保存java程序執行時產生的對象和恢復對象,事實上就是實現了java對象與關係數據庫記錄的映射關係,稱爲ORM(即Object RelationMapping),人們可以經過封裝JDBC代碼來實現了這樣的功能,封裝出來的產品稱之爲ORM框架,Hibernate就是當中的一種流行ORM框架。使用Hibernate框架,不用寫JDBC代碼,不過調用一個save方法,就可以將對象保存到關係數據庫中,不過調用一個get方法,就可以從數據庫中載入出一個對象。
4.使用Hibernate的基本流程是:配置Configuration對象、產生SessionFactory、建立session對象,啓動事務,完畢CRUD操做,提交事務,關閉session。
5.使用Hibernate時,先要配置hibernate.cfg.xml文件,當中配置數據庫鏈接信息和方言等,還要爲每個實體配置對應的hbm.xml文件,hibernate.cfg.xml文件裏需要登記每個hbm.xml文件。
6.在應用Hibernate時,重點要了解Session的緩存原理,級聯,延遲載入和hql查詢。
3、AOP的做用。
4、你對Spring的理解。
1.Spring實現了工廠模式的工廠類(在這裏有必要解釋清楚什麼是工廠模式),這個類名爲BeanFactory(其實是一個接口),在程序中一般BeanFactory的子類ApplicationContext。Spring至關於一個大的工廠類,在其配置文件裏經過<bean>元素配置用於建立實例對象的類名和實例對象的屬性。
2. Spring提供了對IOC良好支持,IOC是一種編程思想,是一種架構藝術,利用這樣的思想可以很是好地實現模塊之間的解耦。IOC也稱爲DI(Depency Injection),什麼叫依賴注入呢?
譬如,Class Programmer
{
Computer computer =null;
public void code()
{
//Computercomputer = new IBMComputer();
//Computercomputer = beanfacotry.getComputer();
computer.write();
}
public voidsetComputer(Computer computer)
{
this.computer= computer;
}
}
另外兩種方式都由依賴,第一個直接依賴於目標類,第二個把依賴轉移到工廠上,第三個完全與目標和工廠解耦了。在spring的配置文件裏配置片斷例如如下:
<bean id=」computer」 class=」cn.itcast.interview.Computer」>
</bean>
<bean id=」programmer」 class=」cn.itcast.interview.Programmer」>
<property name=」computer」 ref=」computer」></property>
</bean>
3. Spring提供了對AOP技術的良好封裝, AOP稱爲面向切面編程,就是系統中有很是多各不相干的類的方法,在這些衆多方法中要增長某種系統功能的代碼,好比,增長日誌,增長權限推斷,增長異常處理,這樣的應用稱爲AOP。實現AOP功能採用的是代理技術,client程序再也不調用目標,而調用代理類,代理類與目標類對外具備一樣的方法聲明,有兩種方式可以實現一樣的方法聲明,一是實現一樣的接口,二是做爲目標的子類在,JDK中採用Proxy類產生動態代理的方式爲某個接口生成實現類,假設要爲某個類生成子類,則可以用CGLI B。在生成的代理類的方法中增長系統功能和調用目標類的對應方法,系統功能的代理以Advice對象進行提供,顯然要建立出代理對象,至少需要目標類和Advice類。spring提供了這樣的支持,僅僅需要在spring配置文件裏配置這兩個元素就能夠實現代理和aop功能,好比,
<bean id=」proxy」 type=」org.spring.framework.aop.ProxyBeanFactory」>
<property name=」target」ref=」」></property>
<property name=」advisor」ref=」」></property>
</bean>
5、談談Struts中的Action servlet。
6、Struts優缺點
長處:
1. 實現MVC模式,結構清晰,使開發人員僅僅關注業務邏輯的實現.
2.有豐富的tag可以用 ,Struts的標記庫(Taglib),如能靈活動用,則能大大提升開發效率
3. 頁面導航
使系統的脈絡更加清晰。經過一個配置文件,就能夠把握整個系統各部分之間的聯繫,這對於後期的維護有着莫大的優勢。尤爲是當還有一批開發人員接手這個項目時,這樣的優點體現得更加明顯。
4. 提供Exception處理機制 .
5. 數據庫連接池管理
6. 支持I18N
缺點
1、 轉到展現層時,需要配置forward,假設有十個展現層的jsp,需要配置十次struts,而且還不包含有時候文件夾、文件變動,需要又一次改動forward,注意,每次改動配置以後,要求又一次部署整個項目,而tomcate這種server,還必須又一次啓動server
2、 2、 Struts的Action必需是thread-safe方式,它只贊成一個實例去處理所有的請求。因此action用到的所有的資源都必需統一同步,這個就引發了線程安全的問題。
3、 測試不方便. Struts的每個Action都同Web層耦合在一塊兒,這樣它的測試依賴於Web容器,單元測試也很是難實現。只是有一個Junit的擴展工具Struts TestCase可以實現它的單元測試。
4、 類型的轉換. Struts的FormBean把所有的數據都做爲String類型,它可以使用工具Commons-Beanutils進行類型轉化。但它的轉化都是在Class級別,而且轉化的類型是不可配置的。類型轉化時的錯誤信息返回給用戶也是很困難的。
5、 對Servlet的依賴性過強. Struts處理Action時必需要依賴ServletRequest和ServletResponse,所有它擺脫不了Servlet容器。
6、 前端表達式語言方面.Struts集成了JSTL,因此它主要使用JSTL的表達式語言來獲取數據。可是JSTL的表達式語言在Collection和索引屬性方面處理顯得很是弱。
7、 對Action運行的控制困難. Struts建立一個Action,假設想控制它的運行順序將會很困難。甚至你要又一次去寫Servlet來實現你的這個功能需求。
8、 對Action運行前和後的處理. Struts處理Action的時候是基於class的hierarchies,很是難在action處理前和後進行操做。
9、 對事件支持不夠.在struts中,實際是一個表單Form相應一個Action類(或DispatchAction),換一句話說:在Struts中實際是一個表單僅僅能相應一個事件,struts這樣的事件方式稱爲application event,application event和component event相比是一種粗粒度的事件
7、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屬性、國際化的提示和消息。
8、說說struts1與struts2的差異。
1.都是MVC的WEB框架,
2 struts1的老牌框架,應用很是普遍,有很是好的羣衆基礎,使用它開發風險很是小,成本更低!struts2儘管基於這個框架,但是應用羣衆並多,相對不成熟,未知的風險和變化很是多,開發者相對很差招,使用它開發項目的風險係數更大,用人成本更高!
3.struts2畢竟是站在前輩的基礎設計出來,它會改善和無缺struts1中的一些缺陷,struts1中一些懸而未決問題在struts2獲得瞭解決。
4.struts1的前端控制器是一個Servlet,名稱爲ActionServlet,struts2的前端控制器是一個filter,在struts2.0中叫FilterDispatcher,在struts2.1中叫StrutsPrepareAndExecuteFilter。
5.struts1的action需要繼承Action類,struts2的action可以不繼承不論什麼類;struts1對同一個路徑的所有請求共享一個Action實例,struts2對同一個路徑的每個請求分別使用一個獨立Action實例對象,所有對於struts2的Action不用考慮線程安全問題。
6.在struts1中使用formbean封裝請求參數,在struts2中直接使用action的屬性來封裝請求參數。
7.struts1中的多個業務方法放在一個Action中時(即繼承DispatchAction時),要麼都校驗,要麼都不校驗;對於struts2,可以指定僅僅對某個方法進行校驗,當一個Action繼承了ActionSupport且在這個類中僅僅編寫了validateXxx()方法,那麼則僅僅對Xxx()方法進行校驗。
(一個請求來了的運行流程進行分析,struts2是本身主動支持分模塊開發,並可以不一樣模塊設置不一樣的url前綴,這是經過package的namespace來實現的;struts2是支持多種類型的視圖;struts2的視圖地址可以是動態的,即視圖的名稱是支持變量方式的,舉例,論壇發帖失敗後回來還要傳遞boardid。視圖內容顯示方面:它的標籤用ognl,要el強大很是多,在國際化方面支持分模塊管理,兩個模塊用到相同的key,相應不一樣的消息;)
與Struts1不一樣,Struts2對用戶的每一次請求都會建立一個Action,因此Struts2中的Action是線程安全的。
給我印象最深入的是:struts配置文件裏的redirect視圖的url不能接受參數,而struts2配置文件裏的redirect視圖可以接受參數。
9、hibernate中的update()和saveOrUpdate()的差異,session的load()和get()的差異。
10、簡述 Hibernate和 JDBC的優缺點?怎樣書寫一個 one to many配置文件.
11、iBatis與Hibernate有什麼不一樣?
一樣點:屏蔽jdbc api的底層訪問細節,使用咱們不用與jdbc api打交道,就可以訪問數據。
jdbc api編程流程固定,還將sql語句與java代碼混雜在了一塊兒,經常需要拼湊sql語句,細節很是繁瑣。
ibatis的優勢:屏蔽jdbc api的底層訪問細節;將sql語句與java代碼進行分離;提供了將結果集本身主動封裝稱爲實體對象和對象的集合的功能,queryForList返回對象集合,用queryForObject返回單個對象;提供了本身主動將實體對象的屬性傳遞給sql語句的參數。
Hibernate是一個全本身主動的orm映射工具,它可以本身主動生成sql語句,ibatis需要咱們本身在xml配置文件裏寫sql語句,hibernate要比ibatis功能負責和強大很是多。因爲hibernate本身主動生成sql語句,咱們沒法控制該語句,咱們就沒法去寫特定的高效率的sql。對於一些不太複雜的sql查詢,hibernate可以很是好幫咱們完畢,但是,對於特別複雜的查詢,hibernate就很是難適應了,這時候用ibatis就是不錯的選擇,因爲ibatis仍是由咱們本身寫sql語句。
12、寫Hibernate的一對多和多對一雙向關聯的orm配置?
9、hibernate的inverse屬性的做用?
解決方式一,依照Object[]數據取出數據,而後本身組bean
解決方式二,對每個表的bean寫構造函數,比方表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1filed1,type2
field2) ,而後在hql裏面就可以直接生成這個bean了。
13、在DAO中怎樣體現DAO設計模式?
解決方式一,依照Object[]數據取出數據,而後本身組bean
解決方式二,對每個表的bean寫構造函數,比方表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1filed1,type2
field2) ,而後在hql裏面就可以直接生成這個bean了。
14、spring+Hibernate中託付方案怎麼配置?
解決方式一,依照Object[]數據取出數據,而後本身組bean
解決方式二,對每個表的bean寫構造函數,比方表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1filed1,type2
field2) ,而後在hql裏面就可以直接生成這個bean了。
15、spring+Hibernate中託付方案怎麼配置?
解決方式一,依照Object[]數據取出數據,而後本身組bean
解決方式二,對每個表的bean寫構造函數,比方表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1filed1,type2
field2) ,而後在hql裏面就可以直接生成這個bean了。
16. hibernate進行多表查詢每個表中各取幾個字段,也就是說查詢出來的結果集沒有一個實體類與之相應怎樣解決;
解決方式一,依照Object[]數據取出數據,而後本身組bean
解決方式二,對每個表的bean寫構造函數,比方表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1filed1,type2
field2) ,而後在hql裏面就可以直接生成這個bean了。
17.介紹一下Hibernate的二級緩存
依照下面思路來回答:(1)首先說清楚什麼是緩存,(2)再說有了hibernate的Session就是一級緩存,即有了一級緩存,爲何還要有二級緩存,(3)最後再說怎樣配置Hibernate的二級緩存。
(1)緩存就是把曾經從數據庫中查詢出來和使用過的對象保存在內存中(一個數據結構中),這個數據結構通常是或相似Hashmap,當之後要使用某個對象時,先查詢緩存中是否有這個對象,假設有則使用緩存中的對象,假設沒有則去查詢數據庫,並將查詢出來的對象保存在緩存中,以便下次使用。如下是緩存的僞代碼:
引出hibernate的第二級緩存,用如下的僞代碼分析了Cache的實現原理
Dao
{
hashmap map = newmap();
User getUser(integerid)
{
User user =map.get(id)
if(user ==null)
{
user =session.get(id);
map.put(id,user);
}
return user;
}
}
Dao
{
Cache cache = null
setCache(Cachecache)
{
this.cache =cache
}
User getUser(int id)
{
if(cache!=null)
{
Useruser = cache.get(id);
if(user==null)
{
user= session.get(id);
cache.put(id,user);
}
returnuser;
}
returnsession.get(id);
}
}
(2)Hibernate的Session就是一種緩存,咱們一般將之稱爲Hibernate的一級緩存,當想使用session從數據庫中查詢出一個對象時,Session也是先從本身內部查看是否存在這個對象,存在則直接返回,不存在纔去訪問數據庫,並將查詢的結果保存在本身內部。由於Session表明一次會話過程,一個Session與一個數據庫鏈接相關連,因此Session最好不要長時間保持打開,一般僅用於一個事務其中,在事務結束時就應關閉。並且Session是線程不安全的,被多個線程共享時easy出現故障。一般僅僅有那種全局意義上的緩存纔是真正的緩存應用,纔有較大的緩存價值,所以,Hibernate的Session這一級緩存的緩存做用並不明顯,應用價值不大。Hibernate的二級緩存就是要爲Hibernate配置一種全局緩存,讓多個線程和多個事務都可以共享這個緩存。咱們但願的是一我的使用過,其它人也可以使用,session沒有這樣的效果。
(3)二級緩存是獨立於Hibernate的軟件部件,屬於第三方的產品,多個廠商和組織都提供有緩存產品,好比,EHCache和OSCache等等。在Hibernate中使用二級緩存,首先就要在hibernate.cfg.xml配置文件裏配置使用哪一個廠家的緩存產品,接着需要配置該緩存產品本身的配置文件,最後要配置Hibernate中的哪些實體對象要歸入到二級緩存的管理中。明確了二級緩存原理和有了這個思路後,很是easy配置起Hibernate的二級緩存。擴展知識:一個SessionFactory可以關聯一個二級緩存,也即一個二級緩存僅僅能負責緩存一個數據庫中的數據,當使用Hibernate的二級緩存後,注意不要有其它的應用或SessionFactory來更改當前數據庫中的數據,這樣緩存的數據就會與數據庫中的實際數據不一致。
18、Spring的依賴注入是什麼意思?給一個 Bean 的 message屬性,字符串類型,注入值爲"Hello"的 XML配置文件該怎麼寫?
19、Jdo是什麼?
JDO是Java對象持久化的新的規範,爲java data object的簡稱,也是一個用於存取某種數據倉庫中的對象的標準化API。JDO提供了透明的對象存儲,所以對開發者來講,存儲數據對象全然不需要額外的代碼(如JDBC API的使用)。這些繁瑣的例行工做已經轉移到JDO產品提供商身上,使開發者解脫出來,從而集中時間和精力在業務邏輯上。另外,JDO很是靈活,因爲它可以在不論什麼數據底層上執行。JDBC僅僅是面向關係數據庫(RDBMS)JDO更通用,提供到不論什麼數據底層的存儲功能,比方關係數據庫、文件、XML以及對象數據庫(ODBMS)等等,使得應用可移植性更強。
20、什麼是spring的IOC AOP
21、STRUTS的工做流程!
22、spring與EJB的差異!!
八.軟件project與設計模式
1、UML方面
標準建模語言UML。用例圖,靜態圖(包含類圖、對象圖和包圖),行爲圖,交互圖(順序圖,合做圖),實現圖。
2、j2ee常用的設計模式?說明工廠模式。
總共23種,分爲三大類:建立型,結構型,行爲型
我僅僅記得當中常用的6、7種,各自是:
建立型(工廠、工廠方法、抽象工廠、單例)
結構型(包裝、適配器,組合,代理)
行爲(觀察者,模版,策略)
而後再針對你熟悉的模式談談你的理解就能夠。
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(責任鏈模式)
工廠模式:工廠模式是一種經常被使用到的模式,依據工廠模式實現的類可以依據提供的數據生成一組類中某一個類的實例,一般這一組類有一個公共的抽象父類並且實現了一樣的方法,但是這些方法針對不一樣的數據進行了不一樣的操做。首先需要定義一個基類,該類的子類經過不一樣的方法實現了基類中的方法。而後需要定義一個工廠類,工廠類可以依據條件生成不一樣的子類實例。當獲得子類的實例後,開發者可以調用基類中的方法而沒必要考慮究竟返回的是哪個子類的實例。
3、開發中都用到了那些設計模式?用在什麼場合?
每個模式都描寫敘述了一個在咱們的環境中不斷出現的問題,而後描寫敘述了該問題的解決方式的核心。經過這樣的方式,你可以無數次地使用那些已有的解決方式,無需在反覆一樣的工做。主要用到了MVC的設計模式。用來開發JSP/Servlet或者J2EE的相關應用。簡單工廠模式等。
九. j2ee部分
1、BS與CS的聯繫與差異。
C/S是Client/Server的縮寫。server一般採用高性能的PC、工做站或小型機,並採用大型數據庫系統,如Oracle、Sybase、InFORMix或 SQL Server。client需要安裝專用的client軟件。
B/S是Brower/Server的縮寫,客戶機上僅僅要安裝一個瀏覽器(Browser),如Netscape Navigator或Internet Explorer,server安裝Oracle、Sybase、InFORMix或 SQL Server等數據庫。在這樣的結構下,用戶界面全然經過WWW瀏覽器實現,一部分事務邏輯在前端實現,但是主要事務邏輯在server端實現。瀏覽器經過Web Server同數據庫進行數據交互。
C/S 與 B/S差異:
1.硬件環境不一樣:
C/S 通常創建在專用的網絡上,小範圍裏的網絡環境,局域網之間再經過專門server提供鏈接和數據交換服務.
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 2000Exchange 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等信息、流向的變化,更像交易中心。
2、應用server與WEB SERVER的差異?
應用server:Weblogic、Tomcat、Jboss
WEB SERVER:IIS、 Apache
3、應用server有那些?
BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i ApplicationServer,jBoss,Tomcat
4、J2EE是什麼?
答:Je22是Sun公司提出的多層(multi-diered),分佈式(distributed),基於組件(component-base)的企業級應用模型(enterpriese applicationmodel).在這種一個應用系統中,可依照功能劃分爲不一樣的組件,這些組件又可在不一樣計算機上,並且處於對應的層次(tier)中。所屬層次包含客戶層(clietn tier)組件,web層和組件,Business層和組件,企業信息系統(EIS)層。
一個另類的回答:j2ee就是增刪改查。
5、J2EE是技術仍是平臺仍是框架?什麼是J2EE
J2EE自己是一個標準,一個爲企業分佈式應用的開發提供的標準平臺。
J2EE也是一個框架,包含JDBC、JNDI、RMI、JMS、EJB、JTA等技術。
6、請對下面在J2EE中常用的名詞進行解釋(或簡單描寫敘述)
web容器:給處於當中的應用程序組件(JSP,SERVLET)提供一個環境,使JSP,SERVLET直接更容器中的環境變量接口交互,沒必要關注其餘系統問題。主要有WEBserver來實現。好比:TOMCAT,WEBLOGIC,WEBSPHERE等。該容器提供的接口嚴格遵照J2EE規範中的WEB APPLICATION 標準。咱們把遵照以上標準的WEBserver就叫作J2EE中的WEB容器。
EJB容器:Enterprise java bean容器。更具備行業領域特點。他提供給執行在當中的組件EJB各類管理功能。僅僅要知足J2EE規範的EJB放入該容器,當即就會被容器進行高效率的管理。並且可以經過現成的接口來得到系統級別的服務。好比郵件服務、事務管理。
JNDI:(Java Naming & Directory Interface)JAVA命名文件夾服務。主要提供的功能是:提供一個文件夾系統,讓其餘各地的應用程序在其上面留下本身的索引,從而知足高速查找和定位分佈式應用程序的功能。
JMS:(Java Message Service)JAVA消息服務。主要實現各個應用程序之間的通信。包含點對點和廣播。
JTA:(Java Transaction API)JAVA事務服務。提供各類分佈式事務服務。應用程序僅僅需調用其提供的接口就能夠。
JAF:(Java Action FrameWork)JAVA安全認證框架。提供一些安全控制方面的框架。讓開發人員經過各類部署和本身定義實現本身的個性安全控制策略。
RMI/IIOP:(Remote Method Invocation /internet對象請求中介協議)他們主要用於經過遠程調用服務。好比,遠程有一臺計算機上執行一個程序,它提供股票分析服務,咱們可以在本地計算機上實現對其直接調用。固然這是要經過必定的規範才幹在異構的系統之間進行通訊。RMI是JAVA特有的。
7、怎樣給weblogic指定大小的內存?
(這個問題不做詳細回答,列出來僅僅是告訴讀者可能會遇到什麼問題,你不需要面面俱到,什麼都精通。)
在啓動Weblogic的腳本中(位於所在Domian相應server文件夾下的startServerName),添加set MEM_ARGS=-Xms32m-Xmx200m,可以調整最小內存爲32M,最大200M
8、怎樣設定的weblogic的熱啓動模式(開發模式)與產品公佈模式?
可以在管理控制檯中改動相應server的啓動模式爲開發或產品模式之中的一個。或者改動服務的啓動文件或者commenv文件,添加setPRODUCTION_MODE=true。
9、怎樣啓動時不需輸入username與password?
改動服務啓動文件,添加 WLS_USER和WLS_PW項。也可以在boot.properties文件裏添加加密過的username和password.
10、在weblogic管理制臺中對一個應用域(或者說是一個站點,Domain)進行jms及ejb或鏈接池等相關信息進行配置後,實際保存在什麼文件裏?
保存在此Domain的config.xml文件裏,它是server的核心配置文件。
11、說說weblogic中一個Domain的缺省文件夾結構?比方要將一個簡單的helloWorld.jsp放入何文件夾下,然的在瀏覽器上就可打入http://主機:port號//helloword.jsp就可以看到執行結果了?又比方這當中用到了一個本身寫的javaBean該怎樣辦?
Domain文件夾server文件夾applications,將應用文件夾放在此文件夾下將可以做爲應用訪問,假設是Web應用,應用文件夾需要知足Web應用文件夾要求,jsp文件可以直接放在應用文件夾中,Javabean需要放在應用文件夾的WEB-INF文件夾的classes文件夾中,設置server的缺省應用將可以實現在瀏覽器上無需輸入應用名。
12、在weblogic中公佈ejb需涉及到哪些配置文件
不一樣類型的EJB涉及的配置文件不一樣,都涉及到的配置文件包含ejb-jar.xml,weblogic-ejb-jar.xmlCMP實體Bean通常還需要weblogic-cmp-rdbms-jar.xml
13、怎樣在weblogic中進行ssl配置與client的認證配置或說說j2ee(標準)進行ssl的配置?
缺省安裝中使用DemoIdentity.jks和DemoTrust.jks KeyStore實現SSL,需要配置server使用Enable SSL,配置其port,在產品模式下需要從CA獲取私有密鑰和數字證書,建立identity和trust keystore,裝載得到的密鑰和數字證書。可以配置此SSL鏈接是單向仍是雙向的。
14、怎樣查看在weblogic中已經公佈的EJB?
可以使用管理控制檯,在它的Deployment中可以查看所有已公佈的EJB
十. EBJ部分
1、EJB是基於哪些技術實現的?並說出SessionBean和EntityBean的差異,StatefulBean和StatelessBean的差異。
EJB包含Session Bean、Entity Bean、Message Driven Bean,基於JNDI、RMI、JAT等技術實現。
SessionBean在J2EE應用程序中被用來完畢一些server端的業務操做,好比訪問數據庫、調用其它EJB組件。EntityBean被用來表明應用系統中用到的數據。
對於客戶機,SessionBean是一種非持久性對象,它實現某些在server上執行的業務邏輯。
對於客戶機,EntityBean是一種持久性對象,它表明一個存儲在持久性存儲器中的實體的對象視圖,或是一個由現有企業應用程序實現的實體。
Session Bean 還可以再細分爲 Stateful Session Bean與 Stateless SessionBean,這兩種的 Session Bean都可以將系統邏輯放在 method之中運行,不一樣的是 Stateful SessionBean可以記錄呼叫者的狀態,所以一般來講,一個使用者會有一個相相應的 Stateful SessionBean的實體。Stateless SessionBean儘管也是邏輯組件,但是他卻不負責記錄使用者狀態,也就是說當使用者呼叫 Stateless SessionBean的時候,EJB Container並不會找尋特定的 Stateless SessionBean的實體來運行這個 method。換言之,很是可能數個使用者在運行某個 Stateless SessionBean的 methods時,會是同一個 Bean的 Instance在運行。從內存方面來看, Stateful SessionBean與Stateless SessionBean比較, Stateful SessionBean會消耗 J2EE Server較多的內存,然而 Stateful SessionBean的優點卻在於他可以維持使用者的狀態。
2、簡要講一下 EJB的 7個 Transaction Level?
3、EJB與JAVA BEAN的差異?
Java Bean 是可複用的組件,對Java Bean並無嚴格的規範,理論上講,不論什麼一個Java類都可以是一個Bean。但一般狀況下,由於Java Bean是被容器所建立(如Tomcat)的,因此Java Bean應具備一個無參的構造器,另外,一般Java Bean還要實現Serializable接口用於實現Bean的持久性。Java Bean實際上至關於微軟COM模型中的本地進程內COM組件,它是不能被跨進程訪問的。Enterprise Java Bean至關於DCOM,即分佈式組件。它是基於Java的遠程方法調用(RMI)技術的,因此EJB可以被遠程訪問(跨進程、跨計算機)。但EJB必須被佈署在諸如Webspere、WebLogic這種容器中,EJB客戶從不直接訪問真正的EJB組件,而是經過其容器訪問。EJB容器是EJB組件的代理,EJB組件由容器所建立和管理。客戶經過容器來訪問真正的EJB組件。
4、EJB包含(SessionBean,EntityBean)說出他們的生命週期,及怎樣管理事務的?
SessionBean:Stateless Session Bean的生命週期是由容器決定的,當客戶機發出請求要創建一個Bean的實例時,EJB容器不必定要建立一個新的Bean的實例供客戶機調用,而是隨便找一個現有的實例提供給客戶機。當客戶機第一次調用一個Stateful SessionBean 時,容器必須立刻在server中建立一個新的Bean實例,並關聯到客戶機上,之後此客戶機調用Stateful SessionBean的方法時容器會把調用分派到與此客戶機相關聯的Bean實例。
EntityBean:Entity Beans能存活相對較長的時間,並且狀態是持續的。僅僅要數據庫中的數據存在,Entity beans就一直存活。而不是依照顧用程序或者服務進程來講的。即便EJB容器崩潰了,Entity beans也是存活的。Entity Beans生命週期能夠被容器或者 Beans本身管理。
EJB經過下面技術管理實務:對象管理組織(OMG)的對象實務服務(OTS),Sun Microsystems的Transaction Service(JTS)、Java Transaction API(JTA),開發組(X/Open)的XA接口。
5、EJB容器提供的服務
主要提供聲明週期管理、代碼產生、持續性管理、安全、事務管理、鎖和併發行管理等服務。
6、EJB的激活機制
以Stateful Session Bean爲例:其Cache大小決定了內存中可以同一時候存在的Bean實例的數量,依據MRU或NRU算法,實例在激活和去激活狀態之間遷移,激活機制是當client調用某個EJB實例業務方法時,假設相應EJB Object發現本身沒有綁定相應的Bean實例則從其去激活Bean存儲中(經過序列化機制存儲實例)回覆(激活)此實例。狀態變遷前會調用相應的ejbActive和ejbPassivate方法。
7、EJB的幾種類型
會話(Session)Bean,實體(Entity)Bean消息驅動的(Message Driven)Bean
會話Bean又可分爲有狀態(Stateful)和無狀態(Stateless)兩種
實體Bean可分爲Bean管理的持續性(BMP)和容器管理的持續性(CMP)兩種
8、客服端調用EJB對象的幾個基本步驟
設置JNDI服務工廠以及JNDI服務地址系統屬性,查找Home接口,從Home接口調用Create方法建立Remote接口,經過Remote接口調用其業務方法。
十一. webservice部分
1、WEB SERVICE名詞解釋。JSWDL開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。
Web ServiceWeb Service是基於網絡的、分佈式的模塊化組件,它運行特定的任務,遵照詳細的技術規範,這些規範使得Web Service能與其它兼容的組件進行互操做。
JAXP(Java API for XML Parsing) 定義了在Java中使用DOM, SAX, XSLT的通用的接口。這樣在你的程序中你僅僅要使用這些通用的接口,當你需要改變詳細的實現時候也不需要改動代碼。
JAXM(Java API for XML Messaging) 是爲SOAP通訊提供訪問方法和傳輸機制的API。
WSDL是一種 XML格式,用於將網絡服務描寫敘述爲一組端點,這些端點對包括面向文檔信息或面向過程信息的消息進行操做。這樣的格式首先對操做和消息進行抽象描寫敘述,而後將其綁定到詳細的網絡協議和消息格式上以定義端點。相關的詳細端點即組合成爲抽象端點(服務)。
SOAP即簡單對象訪問協議(Simple Object Access Protocol),它是用於交換XML編碼信息的輕量級協議。
UDDI 的目的是爲電子商務創建標準;UDDI是一套基於Web的、分佈式的、爲Web Service提供的、信息註冊中心的實現標準規範,同一時候也包括一組使企業能將自身提供的Web Service註冊,以使別的企業能夠發現的訪問協議的實現標準。
2、CORBA是什麼?用途是什麼?
CORBA 標準是公共對象請求代理結構(Common Object Request Broker Architecture),由對象管理組織 (Object ManagementGroup,縮寫爲 OMG)標準化。它的組成是接口定義語言(IDL),語言綁定(binding:也譯爲聯編)和贊成應用程序間互操做的協議。其目的爲:用不一樣的程序設計語言書寫在不一樣的進程中執行,爲不一樣的操做系統開發。
4、LINUX下線程,GDI類的解釋。
LINUX實現的就是基於核心輕量級進程的"一對一"線程模型,一個線程實體相應一個核心輕量級進程,而線程之間的管理在覈外函數庫中實現。
GDI類爲圖像設備編程接口類庫。
5. 問得稀裏糊塗的題
6、四種會話跟蹤技術
會話做用域ServletsJSP頁面描寫敘述
page否是表明與一個頁面相關的對象和屬性。一個頁面由一個編譯好的 Java servlet類(可以帶有不論什麼的include指令,但是沒有 include動做)表示。這既包含 servlet又包含被編譯成 servlet的 JSP頁面
request是是表明與 Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web組件(由於 forward指令和 include動做的關係)
session是是表明與用於某個 Web客戶機的一個用戶體驗相關的對象和屬性。一個 Web會話可以也經常會跨越多個客戶機請求
application是是表明與整個 Web應用程序相關的對象和屬性。這實質上是跨越整個 Web應用程序,包含多個頁面、請求和會話的一個全局做用域
7、簡述邏輯操做(&,|,^)與條件操做(&&,||)的差異。
差異主要答兩點:a.條件操做僅僅能操做布爾型的,而邏輯操做不只可以操做布爾型,而且可以操做數值型
b.邏輯操做不會產生短路
十二.其它
1、請用英文簡介一下本身.
4、WEB SERVICE名詞解釋。JSWDL開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。
2、請把http://tomcat.apache.org/ 首頁的這一段話用中文翻譯一下?
Apache Tomcat is the servlet container that is used in the officialReference Implementation for theJava ServletandJavaServerPages technologies. The Java Servlet and JavaServer Pagesspecifications are developed by Sun under theJavaCommunity Process.
Apache Tomcat is developed in an open andparticipatory environment and released under theApacheSoftware License. Apache Tomcat is intended to be a collaboration ofthe best-of-breed developers from around the world. We invite you toparticipate in this open development project. To learn more about gettinginvolved,click here.
ApacheTomcat powers numerous large-scale, mission-critical web applications across adiverse range of industries and organizations. Some of these users and theirstories are listed on the