第一篇:軟件工程師筆試
一。填空
1在UNIX中用(cp)把A目錄下的F文件考貝到B目錄下
2在UNIX中用(find)找到但前目錄中的MOBILE文件
3在UNIX中-rxw。。其中的x是什么意思 執行
4軟件工程包括幾個部分,每個叫什么
需求分析,系統設計,編程實現,測試,維護
5白盒測試又叫做(結構化測試,基于代碼的測試)
二。選擇
一些對軟件測試看法的選擇
三。編程
1。關于SQL的告訴你一些學生的成績,所學科目,學號等等
要求a。編寫程序將科目編號為×××的成績增加××分
update student
set score = score + x
b。列出所有學生的班號,學號,所學科目等
selcet classno studyno course
from student
c。列出成績高于80分的學生班號,學號等
select studyno classno
from student
where score > 80
2。關于C++中的引用
引用增加40,要求寫出輸出結果
引用所指向的變量增加60,要求寫輸出結果
四問答
1。如果你是測試人員你對客戶需求的理解與開發人員不同,發生爭執,主管來調解,要求你寫一份書面報告給主管看
2。用英語寫出來你適合這個職位的character
responsibility smart action focus fast study smart
3。有三條邊,在不同的情況下分別組成等邊三角形,等腰三角形,普通三角形,不組成三角形要求寫出測試用例
4。寫出你對軟件測試的看法和理解,你是怎么以軟件測試作為自己將來職業規劃的1.首先是五道判斷題,具體忘記了,我只對了三道。
記得的考點有1)JAVA變量名字的合法性,好像是$number是不是合法的2)在linux下查看隱藏文件的命令,ls –a
2.然后是十幾道單選題,考點有數據庫的范式,白盒測試,瀑布模型有什么缺點,面向對象的基本知識,軟件工程的基本知識,LINUX的基本命令(都是很基本的知識)
3.動物都有咬的動作,其中貓和狗咬人的動作又有各自的特點,用面向對象的多態性來描述cat 和 dog 的 bit(JAVA 或 C++)
4.給出一段代碼,請指出錯誤。具體代碼忘記了,是考數組、數組指針的不同,還有傳參的方法(做錯了)
5.寫出以下代碼的輸出
#define AREA(a,b)a+b
#include
void main()
{
cout<
}
6.寫出以下代碼的輸出(代碼忘記了,但是在C++的課本上有類似的題,考指針、引用的,如下)
#include
void main()
{
int a = 100;
int *b;
b= &a;
cout<<*b< a += 20; cout< cout<<*b< *b += 20; cout< cout<<*b< } 7.一道簡單的計算題,移動的話費周一到周五9:00-23:00 1元/分鐘,周一到周五 23:00 – 9:00 0.5元一分鐘,周六周日全天0.8元/分鐘,節日全天0.7元/分鐘,小明9月30日晚上23:59:05 至第二天的 00:01:15,請問話費是多少?(不足一分鐘按一分鐘算,如有重合,按最低的優惠算) 8.智力題。一根材質不均的繩子,從頭燒到尾要一個小時,給你若干跟一模一樣的繩子,用燒繩子的方法計時一個小時十五分鐘。找出使用繩子最少的方法。 9.寫一篇英文文章,200+,描述大學生活中印象最深刻的一件事 10.職業生涯規劃的目標是什么?如何實現?在今后3-5年的目標是什么? 姓名: 一、問答題 1、頭文件中的 ifndef/define/endif 干什么用? 2、#include 3、在C語言中,修改符volatile的含義是什么?舉例說明其使用場合。 4、在C語言中,static函數與普通函數有什么區別? 5、什么是中斷?如果要防止中斷嵌套,可以采用什么方法? 6、靜態局部變量和普通局部變量有什么區別? 7、堆和棧的區別是? 二、編程題 請實現內存復制函數 void memcpy(void *dst,const void * src,int size); 三、閱讀題 1、C++可以采用動態內存分配在運行時為指針分配內存。下面()對一個100個元素的動態數組進行動態內存分配和釋放;()對一個單獨的int指針分配和釋放內存。 Aint *pi = new int;delete pi;pi = 0Bint *pi = new int;delete [] pi;pi =0 Cint *pi = new int(100);delete()pi;pi = 0Dint *pi = new int[100];delete[] pi;pi=02、指出下列程序中的錯誤并且修改 void GetMemory(char *p) { p=(char *)malloc(100); } void Test(void) { char *str=NULL; GetMemory=(str); strcpy(str,“hello world”); printf(str); } Java軟件工程師筆試面試必備 一.Java基礎部分.........................................................................................6 1、一個“.java”源文件中是否可以包括多個類(不是內部類)?有什么限制?.................................6 2、Java有沒有goto?..................................................................................6 3、說說&和&&的區別。.................................................................................6 4、在JAVA中如何跳出當前的多重嵌套循環?.............................................................6 5、switch語句能否作用在byte上,能否作用在long上,能否作用在String上?..............................6 6、short s1 = 1;s1 = s1 + 1;有什么錯? short s1 = 1;s1 += 1;有什么錯?...............................6 7、char型變量中能不能存貯一個中文漢字?為什么?........................................................7 8、用最有效率的方法算出2乘以8等於幾?...............................................................7 9、請設計一個一百億的計算器..........................................................................7 10、使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變?.............................8 11、“==”和equals方法究竟有什么區別?................................................................8 12、靜態變量和實例變量的區別?.......................................................................9 13、是否可以從一個static方法內部發出對非static方法的調用?.........................................9 14、Integer與int的區別..............................................................................9 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?.............................................9 16、下面的代碼有什么不妥之處?........................................................................9 17、請說出作用域public,private,protected,以及不寫時的區別.........................................9 18、Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?...........................10 19、構造器Constructor是否可被override?.............................................................10 20、接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中是否可以有靜態的main方法?.........................................................................10 21、寫clone()方法時,通常都有一行代碼,是什么?.....................................................10 22、面向對象的特征有哪些方面........................................................................10 23、java中實現多態的機制是什么?....................................................................11 24、abstract class和interface有什么區別?...........................................................11 25、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?.............13 26、什么是內部類?Static Nested Class 和 Inner Class的不同。........................................13 27、內部類可以引用它的包含類的成員嗎?有沒有什么限制?..............................................14 28、Anonymous Inner Class(匿名內部類)是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)?....................................................................................................14 29、super.getClass()方法調用........................................................................15 30、String是最基本的數據類型嗎?.....................................................................15 31、String s = “Hello”;s = s + “ world!”;這兩行代碼執行后,原始的String對象中的內容到底變了沒有?......15 32、是否可以繼承String類?..........................................................................16 33、String s = new String(“xyz”);創建了幾個String Object? 二者之間有什么區別?......................16 34、String 和StringBuffer的區別....................................................................16 35、如何把一段逗號分割的字符串轉換成一個數組?.......................................................16 36、數組有沒有length()這個方法? String有沒有length()這個方法?.....................................16 37、下面這條語句一共創建了多少個對象:String s=“a”+“b”+“c”+“d”;.....................................16 38、try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?.....................................................................................17 39、下面的程序代碼輸出的結果是多少?................................................................17 40、final, finally, finalize的區別。................................................................19 41、運行時異常與一般異常有何異同?..................................................................19 42、error和exception有什么區別?....................................................................19 43、Java中的異常處理機制的簡單原理和應用。..........................................................19 44、請寫出你最常見到的5個runtime exception。.......................................................19 45、JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎?..............................................................................................20 46、java中有幾種方法可以實現一個線程?用什么關鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用?20 47、sleep()和 wait()有什么區別?...................................................................20 48、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。........................................22 49.下面兩個方法同步嗎?(自己發明)................................................................22 50、多線程有幾種實現方法?同步有幾種實現方法?........................................................23 51、啟動一個線程是用run()還是start()?.............................................................23 52、當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法?............23 53、線程的基本概念、線程的基本狀態以及狀態之間的關系................................................23 54、簡述synchronized和java.util.concurrent.locks.Lock的異同 ?....................................23 55、設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。.................25 56、子線程循環10次,接著主線程循環100,接著又回到子線程循環10次,接著再回到主線程又循環100,如此循環50次,請寫出程序。....................................................................................26 57、介紹Collection框架的結構.......................................................................31 58、Collection框架中實現比較要實現什么接口..........................................................31 59、ArrayList和Vector的區別........................................................................31 60、HashMap和Hashtable的區別.......................................................................31 61、List 和 Map 區別?...............................................................................32 62、List, Set, Map是否繼承自Collection接口?........................................................32 63、List、Map、Set三個接口,存取元素時,各有什么特點?..............................................32 64、說出ArrayList,Vector, LinkedList的存儲性能和特性...............................................32 65、去掉一個Vector集合中重復的元素.................................................................33 66、Collection 和 Collections的區別。...............................................................33 67、Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用==還是equals()? 它們有何區別?.....33 68、你所知道的集合類都有哪些?主要方法?............................................................33 69、兩個對象值相同(x.equals(y)== true),但卻可有不同的hash code,這句話對不對?.....................33 70、TreeSet里面放對象,如果同時放入了父類和子類的實例對象,那比較時使用的是父類的compareTo方法,還是使用的子類的compareTo方法,還是拋異常!................................................................33 71、說出一些常用的類,包,接口,請各舉5個..........................................................34 72、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?......35 73、字節流與字符流的區別............................................................................35 74、什么是java序列化,如何實現java序列化?或者請解釋Serializable接口的作用。.....................36 75、描述一下JVM加載class文件的原理機制?...........................................................36 76、heap和stack有什么區別。........................................................................36 77、GC是什么? 為什么要有GC?........................................................................36 78、垃圾回收的優點和原理。并考慮2種回收機制。......................................................36 79、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收? 36 80、什么時候用assert。..............................................................................37 81、java中會存在內存泄漏嗎,請簡單描述。............................................................37 82、能不能自己寫個類,也叫java.lang.String?........................................................39 83.Java代碼查錯........................................................................................40 二.算法與編程...........................................................................................43 1、編寫一個程序,將a.txt文件中的單詞與b.txt文件中的單詞交替合并到c.txt文件中,a.txt文件中的單詞用回車符分隔,b.txt文件中用回車或空格進行分隔。.............................................................43 2、編寫一個程序,將d:java目錄下的所有.java文件復制到d:jad目錄下,并將原來文件的擴展名從.java改為.jad。....................................................................................................44 3、編寫一個截取字符串的函數,輸入為一個字符串和字節數,輸出為按字節截取的字符串,但要保證漢字不被截取半個,如“我ABC”,4,應該截取“我AB”,輸入“我ABC漢DEF”,6,應該輸出“我ABC”,而不是“我ABC+漢的半個”。..............................................................................................46 4、有一個字符串,其中包含中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。...............46 5、說明生活中遇到的二叉樹,用java實現二叉樹........................................................47 6、從類似如下的文本文件中讀取出所有的姓名,并打印出重復的姓名和重復的次數,并按重復次數排序:.......52 7、寫一個Singleton出來。...........................................................................54 8、遞歸算法題1......................................................................................56 9、遞歸算法題2......................................................................................57 10、排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。...........................................58 11、有數組a[n],用java代碼將數組元素順序顛倒.......................................................59 12.金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千零一拾一元整)輸出。.......59 三.html&JavaScript&ajax部分............................................................................60 1.判斷第二個日期比第一個日期大.....................................................................60 2.用table顯示n條記錄,每3行換一次顏色,即1,2,3用紅色字體,4,5,6用綠色字體,7,8,9用紅顏色字體。....................................................................................................61 3、HTML 的 form 提交之前如何驗證數值文本框的內容全部為數字? 否則的話提示用戶并終止提交?.............61 4、請寫出用于校驗HTML文本框中輸入的內容全部為數字的javascript代碼.................................62 5、說說你用過那些ajax技術和框架,說說它們的區別....................................................62 四.Java web部分........................................................................................62 1、Tomcat的優化經驗.................................................................................62 2、HTTP請求的GET與POST方式的區別..................................................................62 3、解釋一下什么是servlet;...........................................................................62 4、說一說Servlet的生命周期?........................................................................62 5、Servlet的基本架構................................................................................63 6、SERVLET API中forward()與redirect()的區別?.....................................................63 7、什么情況下調用doGet()和doPost()?...............................................................63 8、Request對象的主要方法:..........................................................................63 9、forward 和redirect的區別........................................................................64 10、request.getAttribute()和 request.getParameter()有何區別?......................................64 11.jsp有哪些內置對象?作用分別是什么? 分別有什么方法?..............................................64 12.jsp有哪些動作?作用分別是什么?...................................................................64 13、JSP的常用指令...................................................................................64 14.JSP中動態INCLUDE與靜態INCLUDE的區別?.........................................................64 15、兩種跳轉方式分別是什么?有什么區別?..............................................................64 16、頁面間對象傳遞的方法............................................................................65 17、JSP和Servlet有哪些相同點和不同點,他們之間的聯系是什么?.......................................65 18、MVC的各個部分都有那些技術來實現?如何實現?.......................................................65 19、我們在web應用開發過程中經常遇到輸出某種編碼的字符,如iso8859-1等,如何輸出一個某種編碼的字符串?65 20.現在輸入n個數字,以逗號,分開;然后可選擇升或者降序排序;按提交鍵就在另一頁面顯示按什么排序,結果為,提供reset...........................................................................................65 五.數據庫部分...........................................................................................65 1、用兩種方式根據部門號從高到低,工資從低到高列出每個員工的信息。...................................65 2、列出各個部門中工資高于本部門的平均工資的員工數和部門號,并按部門號排序...........................65 3、存儲過程與觸發器必須講,經常被面試到?............................................................66 4、數據庫三范式是什么?..............................................................................68 5、說出一些數據庫優化方面的經驗?....................................................................68 6、union和union all有什么不同?.....................................................................69 7.分頁語句..........................................................................................70 8.用一條SQL語句 查詢出每門課都大于80分的學生姓名..................................................72 9.所有部門之間的比賽組合............................................................................73 10.每個月份的發生額都比101科目多的科目.............................................................73 11.統計每年每月的信息...............................................................................74 12.顯示文章標題,發帖人、最后回復時間...............................................................75 13.刪除除了id號不同,其他都相同的學生冗余信息.......................................................75 14.航空網的幾個航班查詢題:.........................................................................76 15.查出比經理薪水還高的員工信息:...................................................................77 16、求出小于45歲的各個老師所帶的大于12歲的學生人數................................................77 17.求出發帖最多的人:...............................................................................78 18、一個用戶表中有一個積分字段,假如數據庫中有100多萬個用戶,若要在每年第一天凌晨將積分清零,你將考慮什么,你將想什么辦法解決?.............................................................................78 19、一個用戶具有多個角色,請查詢出該表中具有該用戶的所有角色的其他用戶。............................79 20.xxx公司的sql面試...............................................................................79 21、注冊Jdbc驅動程序的三種方式.....................................................................79 22、用JDBC如何調用存儲過程.........................................................................79 23、JDBC中的PreparedStatement相比Statement的好處..................................................80 24.寫一個用jdbc連接并訪問oracle數據的程序代碼....................................................81 25、Class.forName的作用?為什么要用?.................................................................81 26、大數據量下的分頁解決方法。......................................................................81 27、用 JDBC 查詢學生成績單, 把主要代碼寫出來(考試概率極大)........................................81 28、這段代碼有什么不足之處?.........................................................................82 29、說出數據連接池的工作機制是什么?.................................................................82 30、為什么要用 ORM? 和 JDBC 有何不一樣?............................................................82 六.XML部分.............................................................................................82 1、xml有哪些解析技術?區別是什么?....................................................................82 2、你在項目中用到了xml技術的哪些方面?如何實現的?...................................................82 3、用jdom解析xml文件時如何解決中文問題?如何解析?..................................................82 4、編程用JAVA解析XML的方式........................................................................83 5、XML文檔定義有幾種形式?它們之間有何本質區別?解析XML文檔有哪幾種方式?..........................85 七.流行的框架與新技術...................................................................................85 1、談談你對Struts的理解。..........................................................................85 2、談談你對Hibernate的理解。.......................................................................85 3、AOP的作用。......................................................................................86 4、你對Spring的理解。..............................................................................86 5、談談Struts中的Action servlet。..................................................................87 6、Struts優缺點 優點: 1.實現MVC模式,結構清晰,使開發者只關注業務邏輯的實現.....................87 7、STRUTS的應用(如STRUTS架構)......................................................................87 8、說說struts1與struts2的區別。...................................................................87 9、hibernate中的update()和saveOrUpdate()的區別,session的load()和get()的區別。...................88 10、簡述 Hibernate 和 JDBC 的優缺點? 如何書寫一個 one to many 配置文件..............................88 11、iBatis與Hibernate有什么不同?...................................................................88 12、寫Hibernate的一對多和多對一雙向關聯的orm配置?.................................................88 9、hibernate的inverse屬性的作用?...................................................................88 13、在DAO中如何體現DAO設計模式?...................................................................88 14、spring+Hibernate中委托方案怎么配置?.............................................................88 15、spring+Hibernate中委托方案怎么配置?.............................................................89 16.hibernate進行多表查詢每個表中各取幾個字段,也就是說查詢出來的結果集沒有一個實體類與之對應如何解決;....................................................................................................89 17.介紹一下Hibernate的二級緩存.....................................................................89 18、Spring 的依賴注入是什么意思? 給一個 Bean 的 message 屬性, 字符串類型, 注入值為 “Hello” 的 XML 配置文件該怎么寫?...........................................................................................90 19、Jdo是什么?......................................................................................90 20、什么是spring的IOC AOP.........................................................................90 21、STRUTS的工作流程!..............................................................................90 22、spring 與EJB的區別!.........................................................................90 八.軟件工程與設計模式...................................................................................90 1、UML方面..........................................................................................90 2、j2ee常用的設計模式?說明工廠模式。...............................................................90 3、開發中都用到了那些設計模式?用在什么場合?.........................................................91 九.j2ee部分............................................................................................91 1、BS與CS的聯系與區別。............................................................................91 2、應用服務器與WEB SERVER的區別?..................................................................91 3、應用服務器有那些?...............................................................................92 4、J2EE是什么?.....................................................................................92 5、J2EE是技術還是平臺還是框架? 什么是J2EE.........................................................92 6、請對以下在J2EE中常用的名詞進行解釋(或簡單描述)..................................................92 7、如何給weblogic指定大小的內存?...................................................................92 8、如何設定的weblogic的熱啟動模式(開發模式)與產品發布模式?.........................................92 9、如何啟動時不需輸入用戶名與密碼?..................................................................92 10、在weblogic管理制臺中對一個應用域(或者說是一個網站,Domain)進行jms及ejb或連接池等相關信息進行配置后,實際保存在什么文件中?.................................................................................92 11、說說weblogic中一個Domain的缺省目錄結構?比如要將一個簡單的helloWorld.jsp放入何目錄下,然的在瀏覽器上就可打入http://主機:端口號//helloword.jsp就可以看到運行結果了? 又比如這其中用到了一個自己寫的javaBean該如何辦?.................................................................................................92 12、在weblogic中發布ejb需涉及到哪些配置文件.......................................................92 13、如何在weblogic中進行ssl配置與客戶端的認證配置或說說j2ee(標準)進行ssl的配置?..................93 14、如何查看在weblogic中已經發布的EJB?.............................................................93 十.EBJ部分.............................................................................................93 1、EJB是基于哪些技術實現的?并說出SessionBean和EntityBean的區別,StatefulBean和StatelessBean的區別。....................................................................................................93 2、簡要講一下 EJB 的 7 個 Transaction Level?........................................................93 3、EJB與JAVA BEAN的區別?..........................................................................93 4、EJB包括(SessionBean,EntityBean)說出他們的生命周期,及如何管理事務的?..........................93 5、EJB容器提供的服務................................................................................93 6、EJB的激活機制....................................................................................93 7、EJB的幾種類型....................................................................................93 8、客服端調用EJB對象的幾個基本步驟.................................................................94 十一.webservice部分....................................................................................94 1、WEB SERVICE名詞解釋。JSWDL開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。................94 2、CORBA是什么?用途是什么?..........................................................................94 3.Linux.................................................................................................94 4、LINUX下線程,GDI類的解釋。......................................................................94 5.問得稀里糊涂的題......................................................................................94 6、四種會話跟蹤技術.................................................................................94 7、簡述邏輯操作(&,|,^)與條件操作(&&,||)的區別。.....................................................94 十二.其他...............................................................................................94 1、請用英文簡單介紹一下自己.........................................................................94 2、請把 http://tomcat.apache.org/ 首頁的這一段話用中文翻譯一下?.....................................94 3、美資軟件公司JAVA工程師電話面試題目..............................................................95 這套面試題主要目的是幫助那些還沒有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。 備注:這道題先說兩者的共同點,再說出&&和&的特殊之處,并列舉一些經典的例子來表明自己理解透徹深入、實際經驗豐富。 4、在JAVA中如何跳出當前的多重嵌套循環? 在Java中,要想跳出多重循環,可以在外面的循環語句前定義一個標號,然后在里層循環體的代碼中使用帶有標號的break 語句,即可跳出外層循環。例如,ok: for(int i=0;i<10;i++){ } 另外,我個人通常并不使用標號這種方式,而是讓外層的循環條件表達式的結果可以受到里層循環體代碼的控制,例如,要在二維數組中查找到某個數字。 int arr[][] = {{1,2,3},{4,5,6,7},{9}};boolean found = false;for(int i=0;i } 5、switch語句能否作用在byte上,能否作用在long上,能否作用在String上? 在switch(condition)中,condition只能是一個整數表達式或者枚舉常量(更大字體),整數表達式可以是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編譯器會對它進行特殊處理,因此可以正確編譯。for(int j=0;j } System.out.println(“i=” + i + “,j=” + j);if(arr[i][j] == 5){ } found = true;break; { for(int j=0;j<10;j++) } if(j == 5)break ok; { System.out.println(“i=” + i + “,j=” + j); 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類型來做演示這種問題和現象的實驗,大家可以用下面一個使用整數做實驗的例子程序體驗一下: 先不考慮long類型,由于int的正數范圍為2的31次方,表示的最大數值約等于2*1000*1000*1000,也就是20億的大小,所以,要實現一個一百億的計算器,我們得自己設計一個類可以用于表示很大的整數,并且提供了與另外一個整數進行加減乘除的功能,大概功能如下: ()這個類內部有兩個成員變量,一個表示符號,另一個用字節數組表示數值的二進制數()有一個構造方法,把一個包含有多位數值的字符串轉換到內部的符號和字節數組中()提供加減乘除的功能 public class BigInteger{ int sign;byte[] val;public Biginteger(String val) } public BigInteger add(BigInteger other)} public BigInteger subtract(BigInteger other){ } public BigInteger multiply(BigInteger other){ } public BigInteger divide(BigInteger other){ { sign =;val =; { int a = Integer.MAX_VALUE;int b = Integer.MAX_VALUE;int sum = a + b;System.out.println(“a=”+a+”,b=”+b+”,sum=”+sum); } 備注:要想寫出這個類的完整代碼,是非常復雜的,如果有興趣的話,可以參看jdk中自帶的java.math.BigInteger類的源碼。面試的人也知道誰都不可能在短時間內寫出這個類的完整代碼的,他要的是你是否有這方面的概念和意識,他最重要的還是考查你的能力,所以,你不要因為自己無法寫出完整的最終結果就放棄答這道題,你要做的就是你比別人寫得多,證明你比別人強,你有這方面的思想意識就可以了,畢竟別人可能連題目的意思都看不懂,什么都沒寫,你要敢于答這道題,即使只答了一部分,那也與那些什么都不懂的人區別出來,拉開了距離,算是矮子中的高個,機會當然就屬于你了。另外,答案中的框架代碼也很重要,體現了一些面向對象設計的功底,特別是其中的方法命名很專業,用的英文單詞很精準,這也是能力、經驗、專業性、英語水平等多個方面的體現,會給人留下很好的印象,在編程能力和其他方面條件差不多的情況下,英語好除了可以使你獲得更多機會外,薪水可以高出一千元。 10、使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變? 使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。例如,對于如下語句: 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 = new Object();變量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、靜態變量和實例變量的區別? 在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。 在程序運行時的區別:實例變量屬于某個對象的屬性,必須創建了實例對象,其中的實例變量才會被分配空間,才能使用這個實例變量。靜態變量不屬于某個實例對象,而是屬于類,所以也稱為類變量,只要程序加載了類的字節碼,不用創建任何實例對象,靜態變量就會被分配空間,靜態變量就可以被使用了。總之,實例變量必須創建對象后才可以通過這個對象來使用,靜態變量則可以直接使用類名來引用。 例如,對于下面的程序,無論創建多少個實例對象,永遠都只分配了一個staticVar變量,并且每創建一個實例對象,這個staticVar就會加1;但是,每創建一個實例對象,就會分配一個instanceVar,即可能分配多個instanceVar,并且每個instanceVar的值都只自加了1次。 public class VariantTest{ } 備注:這個解答除了說清楚兩者的區別外,最后還用一個具體的應用例子來說明兩者的差異,體現了自己有很好的解說問題和設計案例的能力,思維敏捷,超過一般程序員,有寫作能力! 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;public static int staticVar = 0;public int instanceVar = 0;public VariantTest(){ } staticVar++;instanceVar++;System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar); 17、請說出作用域public,private,protected,以及不寫時的區別 這四個作用域的可見范圍如下表所示。 說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。 作用域 當前類 同一package 子孫類 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × 備注:只要記住了有4種訪問權限,4個訪問范圍,然后將全選和范圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。 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、對于繼承來說,如果某一方法在父類中是訪問權限是private,那么就不能在子類對其進行重載,如果定義的話,也只是定義了一個新方法,而不會達到重載的效果。 19、構造器Constructor是否可被override? 構造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。 20、接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中是否可以有靜態的main方法? 接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承具體類。抽象類中可以有靜態的main方法。備注:只要明白了接口和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支持,如果不提供的話,有什么理由嗎?如果你沒有道理不提供,那答案就是肯定的了。 只有記住抽象類與普通類的唯一區別就是不能創建實例對象和允許有abstract方法。 21、寫clone()方法時,通常都有一行代碼,是什么? clone 有缺省行為,super.clone();因為首先要把父類中的成員復制到位,然后才是復制自己的成員。 22、面向對象的特征有哪些方面 計算機軟件系統是現實生活中的業務在計算機中的映射,而現實生活中的業務其實就是一個個對象協作的過程。面向對象編程就是按現實業務一樣的方式將程序代碼按一個個對象進行組織和編寫,讓計算機系統能夠識別和理解用對象方式組織和編寫的程序代碼,這樣就可以把現實生活中的業務對象映射到計算機系統中。 面向對象的編程語言有封裝、繼承、抽象、多態等4個主要的特征。 1封裝: 封裝是保證軟件部件具有優良的模塊性的基礎,封裝的目標就是要實現軟件部件的“高內聚、低耦合”,防止程序相互依賴性而帶來的變動影響。在面向對象的編程語言中,對象是封裝的最基本單位,面向對象的封裝比傳統語言的封裝更為清晰、更為有力。面向對象的封裝就是把描述一個對象的屬性和行為的代碼封裝在一個“模塊”中,也就是一個類中,屬性用變量定義,行為用方法進行定義,方法可以直接訪問同一個對象中的屬性。通常情況下,只要記住讓變量和訪問這個變量的方法放在一起,將一個類中的成員變量全部定義成私有的,只有這個類自己的方法才可以訪問到這些成員變量,這就基本上實現對象的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會面向對象的編程了。把握一個原則:把對同一事物進行操作的方法和相關的方法放在同一個類中,把方法和它操作的數據放在同一個類中。 例如,人要在黑板上畫圓,這一共涉及三個對象:人、黑板、圓,畫圓的方法要分配給哪個對象呢?由于畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,如果將它們在類中定義成了私有的成員變量,那么,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑這兩個屬性,人以后只是調用圓的畫圓方法、表示給圓發給消息而已,畫圓這個方法不應該分配在人這個對象上,這就是面向對象的封裝性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(屬性)由這個對象自己的行為(方法)來讀取和改變。一個更便于理解的例子就是,司機將火車剎住了,剎車的動作是分配給司機,還是分配給火車,顯然,應該分配給火車,因為司機自身是不可能有那么大的力氣將一個火車給停下來的,只有火車自己才能完成這一動作,火車需要調用內部的離合器和剎車片等多個器件協作才能完成剎車這個動作,司機剎車的過程只是給火車發了一個消息,通知火車要執行剎車動作而已。 抽象: 抽象就是找出一些事物的相似和共性之處,然后將這些事物歸為一個類,這個類只考慮這些事物的相似和共性之處,并且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。例如,看到一只螞蟻和大象,你能夠想象出它們的相同之處,那就是抽象。抽象包括行為抽象和狀態抽象兩個方面。例如,定義一個Person類,如下: class Person{ } 人本來是很復雜的事物,有很多方面,但因為當前系統只需要了解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標無關的細節。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,這樣涉及的內容就太多了,而是要善于劃分問題的邊界,當前系統需要什么,就只考慮什么。 繼承: 在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,并可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類數據和方法的機制,這是類之間的一種關系,提高了軟件的可重用性和可擴展性。 多態: 多態是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。因為在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。多態性增強了軟件的靈活性和擴展性。例如,下面代碼中的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 String name;int age; 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 class BaseServlet extends HttpServlet{ public final void service(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException { 記錄訪問日志 進行權限判斷 if(具有權限){ } } protected abstract void doService(HttpServletRequest request, HttpServletResponse response)throws try{ } catch(Excetpion e){ } 記錄異常信息 doService(request,response);IOExcetion,ServletException;//注意訪問權限定義成protected,顯得既專業,又嚴謹,因為它是專門給子類用的 } public class MyServlet1 extends BaseServlet { protected } 父類方法中間的某段代碼不確定,留給子類干,就用模板方法設計模式。 備注:這道題的思路是先從總體解釋抽象類和接口的基本概念,然后再比較兩者的語法細節,最后再說兩者的應用區別。比較兩者語法細節區別的條理是:先從一個類中的構造方法、普通成員變量和方法(包括抽象方法),靜態變量和方法,繼承性等6個方面逐一去比較回答,接著從第三者繼承的角度的回答,特別是最后用了一個典型的例子來展現自己深厚的技術功底。{ } 本Servlet只處理的具體業務邏輯代碼 void doService(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException 25、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized? abstract的method 不可以是static的,因為抽象的方法是要被子類實現的,而static與子類扯不上關系! native方法表示該方法要用另外一種依賴平臺的編程語言實現的,不存在著被子類實現的問題,所以,它也不能是抽象的,不能與abstract混用。例如,FileOutputSteam類要硬件打交道,底層的實現用的是操作系統相關的api實現,例如,在windows用c語言實現的,所以,查看jdk 的源代碼,可以發現FileOutputStream的open方法的定義如下: private native void open(String name)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 { } 在方法體外面定義的內部類的訪問類型可以是public,protecte,默認的,private等4種類型,這就好像類中定義的成員變量有4種訪問類型一樣,它們決定這個內部類的定義對其他類是否可見;對于這種情況,我們也可以在外面創建內部類的實例對象,創建內部類的實例對象時,一定要先創建外部類的實例對象,然后用這個外部類的實例對象去創建內部類的實例對象,代碼如下: Outer outer = new Outer();Outer.Inner1 inner1 = outer.new Innner1(); 在方法內部定義的內部類前面不能有訪問類型修飾符,就好像方法中定義的局部變量一樣,但這種內部類的前面可以使用final或abstract修飾符。這種內部類對其他類是不可見的其他類無法引用這種內部類,但是這種內部類創建的實例對象可以傳遞給其他類訪問。這種內部類必須是先定義,后使用,即內部類的定義代碼必須出現在使用該類之前,這與方法中的局部變量必須先定義后使用的道理也是一樣的。這種內部類可以訪問方法體中的局部變量,但是,該局部變量前必須加final修飾符。 對于這些細節,只要在eclipse寫代碼試試,根據開發工具提示的各類錯誤信息就可以馬上了解到。public class Inner1 //在方法體外面定義的內部類 { } int out_x = 0;public void method(){ } Inner1 inner1 = new Inner1();public class Inner2 //在方法體內部定義的內部類 { } Inner2 inner2 = new Inner2();public method(){ } out_x = 3; 在方法體內部還可以采用如下語法來創建一種匿名內部類,即定義某一接口或類的子類的同時,還創建了該子類的實例對象,無需為該子類定義名稱: public class Outer { public void start(){ new Thread(new Runable(){ }).start(); } 最后,在方法外部定義的內部類前面可以加上static關鍵字,從而成為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 = new Outer.Inner();由于static Nested Class不依賴于外部類的實例對象,所以,static Nested Class能訪問外部類的非static成員變量。當在外部類中訪問Static Nested Class時,可以直接使用Static Nested Class的名字,而不需要加上外部類的名字了,在Static Nested Class中也可以直接引用外部類的static的成員變量,不需要加上外部類的名字。 在靜態方法中定義的內部類也是Static Nested Class,這時候不能在類前面加static關鍵字,靜態方法中的Static Nested Class與普通方法中的內部類的應用方式很相似,它除了可以直接訪問外部類中的static的成員變量,還可以訪問靜態方法中的局部變量,但是,該局部變量前必須加final修飾符。 備注:首先根據你的印象說出你對內部類的總體方面的特點:例如,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態成員,這是大的特點。然后再說一些細節方面的知識,例如,幾種定義方式的語法區別,靜態內部類,以及匿名內部類。 27、內部類可以引用它的包含類的成員嗎?有沒有什么限制? 完全可以。如果不是靜態內部類,那沒有什么限制! 如果你把靜態嵌套類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員,例如,下面的代碼: class Outer { static int x;static class Inner { } } 答題時,也要能察言觀色,揣摩提問者的心思,顯然人家希望你說的是靜態內部類不能訪問外部類的成員,但你一上來就頂牛,這不好,要先順著人家,讓人家滿意,然后再說特殊情況,讓人家吃驚。 28、Anonymous Inner Class(匿名內部類)是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)? 可以繼承其他類或實現其他接口。不僅是可以,而是必須!void test(){ } syso(x);} public void run(){}; 29、super.getClass()方法調用 下面程序的輸出結果是多少? import java.util.Date;public class Test extends Date{ } 很奇怪,結果是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這個引用變量不再指向它了。 通過上面的說明,我們很容易導出另一個結論,如果經常對字符串進行各種各樣的修改,或者說,不可預見的修改,那么使用String來代表字符串的話會引起很大的內存開銷。因為 String對象建立之后不能再改變,所以對于每一個不同的字符串,都需要一個String對象來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。并且,這兩種類的對象轉換十分容易。 同時,我們還可以知道,如果要使用內容相同的字符串,不必每次都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對象。而用關鍵字new調用構 public static void main(String[] args){ } public void test(){ } System.out.println(super.getClass().getName());new Test().test(); 造器,總是會創建一個新的對象,無論內容是否相同。 至于為什么要把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(new String(“abc”)的結果為true,而StringBuffer沒有實現equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結果為false。 接著要舉一個具體的例子來說明,我們要把1到100的所有數字拼起來,組成一個串。StringBuffer sbf = new StringBuffer();for(int i=0;i<100;i++){ } 上面的代碼效率很高,因為只創建了一個StringBuffer對象,而下面的代碼效率很低,因為創建了101個對象。String str = new String();for(int i=0;i<100;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 s1 = ”a“;String s2 = s1 + ”b“;str = str + i;sbf.append(i); 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 class Test { static int test(){ } } ---------執行結果---------1 運行結果是1,為什么呢?主函數調用子函數并得到結果的過程,好比主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子里,然后再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什么結果可言,結果是在說這話之前放進罐子里的。 39、下面的程序代碼輸出的結果是多少? public class smallT { public static void main(String args[]){ smallT t = new smallT();int b = t.get();int x = 1;try { } finally { } ++x;return x;/** * @param args add by zxx ,Dec 9, 2008 */ public static void main(String[] args){ } // TODO Auto-generated method stub System.out.println(new Test().test());; } 返回的結果是2。 我可以通過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結果中可以發現,try中的return語句調用的函數先于finally中調用的函數執行,也就是說return語句先執行,finally語句后執行,所以,返回的結果是2。Return并不是讓函數馬上返回,而是return語句執行后,將把返回結果放置進函數棧中,此時函數并不是馬上返回,它要執行finally語句后才真正開始返回。 在講解答案時可以用下面的程序來幫助分析: public class Test { int test(){ } int func1(){ } int func2(){ System.out.println(”func1“);return 1;try { } finally { } return func2();return func1();/** * @param args add by zxx ,Dec 9, 2008 */ public static void main(String[] args){ } // TODO Auto-generated method stub System.out.println(new Test().test());;} public int get(){ } try { } finally { } return 2;return 1;System.out.println(b); }-----------執行結果-----------------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、} System.out.println(”func2“);return 2; ClassCastException。 45、JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎? 46、java中有幾種方法可以實現一個線程?用什么關鍵字修飾同步方法? 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(){ 從java5開始,還有如下一些線程池創建多線程的方式: ExecutorService pool = Executors.newFixedThreadPool(3)for(int i=0;i<10;i++){ pool.execute(new Runable(){public void run(){}});} Executors.newCachedThreadPool().execute(new Runable(){public void run(){}});Executors.newSingleThreadExecutor().execute(new Runable(){public void run(){}}); 有兩種實現方法,分別使用new Thread()和new Thread(runnable)形式,第一種直接調用thread的run方法,所以,我們往往使用Thread子類,即new SubThread()。第二種調用runnable的run方法。 有兩種實現方法,分別是繼承Thread類與實現Runnable接口 用synchronized關鍵字修飾同步方法 反對使用stop(),是因為它不安全。它會解除由線程獲取的所有鎖定,而且如果對象處于一種不連貫狀態,那么其他線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何線程都不能訪問鎖定的資源,除非被”掛起“的線程恢復運行。對任何線程來說,如果它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會造成死鎖。所以不應該使用suspend(),而應在自己的Thread類中置入一個標志,指出線程應該活動還是掛起。若標志指出線程應該掛起,便用wait()命其進入等待狀態。若標志指出線程應當恢復,則用一個notify()重新啟動線程。 47、sleep()和 wait()有什么區別?(網上的答案:sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep不會釋放對象鎖。wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。) } public void run(){ }).start(); sleep就是正在執行的線程主動讓出cpu,cpu去執行其他線程,在sleep指定的時間過后,cpu才會回到這個線程上繼續往下執行,如果當前線程進入了同步鎖,sleep方法并不會釋放鎖,即使當前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無法得到執行。wait是指在一個已經進入了同步鎖的線程內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖并運行,只有其他線程調用了notify方法(notify并不釋放鎖,只是告訴調用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手里,別人還沒釋放。如果notify方法后面的代碼還有很多,需要這些代碼執行完后才會釋放鎖,可以在notfiy方法后增加一個等待和一些代碼,看看效果),調用wait方法的線程就會解除wait狀態和程序可以再次得到鎖后繼續向下運行。對于wait的講解一定要配合例子代碼來說明,才顯得自己真明白。package com.huawei.interview; public class MultiThread { @Override public void run(){ // TODO Auto-generated method stub /** * @param args */ public static void main(String[] args){ } private static class Thread1 implements Runnable { // TODO Auto-generated method stub new Thread(new Thread1()).start();try { } new Thread(new Thread2()).start(); Thread.sleep(10);// TODO Auto-generated catch block e.printStackTrace();} catch(InterruptedException e){ //由于這里的Thread1和下面的Thread2內部run方法要用同一對象作為監視器,我們這里不能用this,因為在Thread2里面的this和這個Thread1的this不是同一個對象。我們用MultiThread.class這個字節碼對象,當前虛擬機里引用這個變量時,指向的都是同一個對象。 System.out.println(”enter thread1...“); System.out.println(”thread1 is waiting“);try { synchronized(MultiThread.class){ //釋放鎖有兩種方式,第一種方式是程序自然離開監視器的范圍,也就是離開了synchronized關鍵字管轄的代碼范圍,} System.out.println(”thread1 is going on...“);MultiThread.class.wait();// TODO Auto-generated catch block e.printStackTrace();另一種方式就是在synchronized關鍵字管轄的代碼內部調用監視器對象的wait方法。這里,使用wait方法釋放鎖。 } catch(InterruptedException e){ @Override public void run(){ // TODO Auto-generated method stub synchronized(MultiThread.class){ System.out.println(”enter thread2...“); System.out.println(”thread2 notify other thread can release wait status..“); } private static class Thread2 implements Runnable { } } System.out.println(”thread1 is being over!“); //由于notify方法并不釋放鎖,即使thread2調用下面的sleep方法休息了10毫秒,但thread1仍然不會執行,因為thread2沒有釋放鎖,所以Thread1無法得不到鎖。 } 48、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。 如果數據將在線程間共享。例如正在寫的數據以后可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那么這些數據就是共享數據,必須進行同步存取。 當應用程序在對象上調用了一個需要花費很長時間來執行的方法,并且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下采用異步途徑往往更有效率。 49.下面兩個方法同步嗎?(自己發明)class Test { synchronized static void sayHello3() } } } MultiThread.class.notify(); System.out.println(”thread2 is sleeping ten millisecond...“);try { } System.out.println(”thread2 is going on...“);System.out.println(”thread2 is being over!“);Thread.sleep(10);// TODO Auto-generated catch block e.printStackTrace();} catch(InterruptedException e){ } 50、多線程有幾種實現方法?同步有幾種實現方法? 多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口 同步的實現方面有兩種,分別是synchronized,wait與notify wait():使一個線程處于等待狀態,并且釋放所持有的對象的lock。 sleep():使一個正在運行的線程處于睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。 notify():喚醒一個處于等待狀態的線程,注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。 Allnotity():喚醒所有處入等待狀態的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。 51、啟動一個線程是用run()還是start()?.啟動一個線程是調用start()方法,使線程就緒狀態,以后可以被調度為運行狀態,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。 52、當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法? 分幾種情況: 1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。2.如果這個方法內部調用了wait,則可以進入其他synchronized方法。 3.如果其他個方法都加了synchronized關鍵字,并且內部沒有調用wait,則不能。 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; public class ThreadTest { 4.如果其他方法是static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能同步,因為非靜態的方法用的是this。synchronized void getX(){} { } @Override public void run(){ // TODO Auto-generated method stub while(true){ /*synchronized(ThreadTest.this){ } private class Adder implements Runnable { @Override public void run(){ } // TODO Auto-generated method stub while(true){ } /*synchronized(ThreadTest.this){ }*/ lock.lock();try { { } lock.unlock();System.out.println(”j--=“ + j--);}finally //這里拋異常了,鎖能釋放嗎? System.out.println(”j--=“ + j--);private class Subtractor implements Runnable { /** * @param args */ private int j;private Lock lock = new ReentrantLock();public static void main(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(); } 55、設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。 以下程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。public class ThreadTest1 { private int j;public static void main(String args[]){ ThreadTest1 tt=new ThreadTest1();Inc inc=tt.new Inc();Dec dec=tt.new Dec();for(int i=0;i<2;i++){ Thread t=new Thread(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(int i=0;i<100;i++){ inc();} } } class Dec implements Runnable{ public void run(){ for(int i=0;i<100;i++){ dec();} } } } System.out.println(”j++=“ + j++);}*/ lock.lock();try { { } lock.unlock(); System.out.println(”j++=“ + j++);}finally } } } ----------隨手再寫的一個-------------class A { JManger j =new JManager();main(){ new A().call();} void call { for(int i=0;i<2;i++){ } } } class JManager { private j = 0; public synchronized void subtract(){ } public synchronized void accumulate(){ } } 56、子線程循環10次,接著主線程循環100,接著又回到子線程循環10次,接著再回到主線程又循環100,如此循環50次,請寫出程序。 最終的程序代碼如下: public class ThreadTest { /** * @param args */ public static void main(String[] args){ j++;j--new Thread(new Runnable(){ public void run(){while(true){j.accumulate()}}}).start();new Thread(new Runnable(){ public void run(){while(true){j.sub()}}}).start(); } private class Business { boolean bShouldSub = true;//這里相當于定義了控制該誰執行的一個信號燈 public synchronized void MainThread(int i){ } if(bShouldSub) { } bShouldSub = true;this.notify();System.out.println(Thread.currentThread().getName()+ ”:i=“ + i +”,j=“ + j);try { } this.wait();// TODO Auto-generated catch block e.printStackTrace();} catch(InterruptedException e){).start(); for(int i=0;i<50;i++){ } business.MainThread(i); } public void run(){ } for(int i=0;i<50;i++){ } business.SubThread(i); public void init(){ final Business business = new Business();new Thread(new Runnable(){ } // TODO Auto-generated method stub new ThreadTest().init();for(int j=0;j<5;j++) } 備注:不可能一上來就寫出上面的完整代碼,最初寫出來的代碼如下,問題在于兩個線程的代碼要參照同一個變量,即這兩個線程的代碼要共享數據,所以,把這兩個線程的執行代碼搬到同一個類中去: package com.huawei.interview.lym; public class ThreadTest { new Thread(new Runnable() private static boolean bShouldMain = false; public static void main(String[] args){ // TODO Auto-generated method stub /*new Thread(){ public void run(){ } //final String str = new String(”“);for(int i=0;i<50;i++){ } for(int j=0;j<10;j++){ } System.out.println(”i=“ + i + ”,j=“ + j); } public synchronized void SubThread(int i){ } if(!bShouldSub) { } bShouldSub = false;this.notify(); System.out.println(Thread.currentThread().getName()+ ”:i=“ + i +”,j=“ + j);try { } this.wait();// TODO Auto-generated catch block e.printStackTrace();} catch(InterruptedException e){ for(int j=0;j<10;j++)}.start();*/ } for(int i=0;i<50;i++){ } synchronized(ThreadTest.class){ } if(!bShouldMain){ } { } bShouldMain = false;ThreadTest.class.notify(); System.out.println(Thread.currentThread().getName()+ ”i=“ + i + ”,j=“ + j); try { } ThreadTest.class.wait();} e.printStackTrace();catch(InterruptedException e){ { } public void run(){ } for(int i=0;i<50;i++){ } synchronized(ThreadTest.class){ } if(bShouldMain){ } for(int j=0;j<10;j++){ } bShouldMain = true;ThreadTest.class.notify(); System.out.println(Thread.currentThread().getName()+ ”i=“ + i + ”,j=“ + j); try { } ThreadTest.class.wait();} e.printStackTrace();catch(InterruptedException e){).start();for(int j=0;j<5;j++) } 下面使用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 Lock lock = new ReentrantLock();private static Condition subThreadCondition = lock.newCondition();private static boolean bBhouldSubThread = false;public static void main(String [] args){ ExecutorService threadPool = Executors.newFixedThreadPool(3);threadPool.execute(new Runnable(){ });threadPool.shutdown();for(int i=0;i<50;i++){ lock.lock();try { if(bBhouldSubThread)subThreadCondition.await(); public void run(){ } for(int i=0;i<50;i++){ } lock.lock();try { { } finally { } lock.unlock(); { } bBhouldSubThread = false;subThreadCondition.signal(); System.out.println(Thread.currentThread().getName()+ ”,j=“ + j); if(!bBhouldSubThread)subThreadCondition.await();for(int j=0;j<10;j++) }catch(Exception e) } 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方法容易讓人引起誤解。Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要自己為它的方法實現 } } { } finally { } lock.unlock(); for(int j=0;j<10;j++){ } bBhouldSubThread = true;subThreadCondition.signal(); System.out.println(Thread.currentThread().getName()+ ”,j=“ + j);}catch(Exception e) 同步,而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,obj value),每次存儲時,要存儲一對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 } 還有一種簡單的方式,HashSet set = new HashSet(vector);66、Collection 和 Collections的區別。 Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。67、Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用==還是equals()? 它們有何區別? Set里的元素是不能重復的,元素重復與否是使用equals()方法進行判斷的。 equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的內容和類型相配的話,返回真值。 68、你所知道的集合類都有哪些?主要方法? 最常用的集合類是 List 和 Map。List 的具體實現包括 ArrayList 和 Vector,它們是可變大小的列表,比較適合構建、存儲和操作任何類型對象的元素列表。List 適用于按數值索引訪問元素的情形。 Map 提供了一個更通用的元素存儲方法。Map 集合類用于存儲元素對(稱作”鍵“和”值“),其中每個鍵映射到一個值。 ArrayList/Vector?List ?Collection HashSet/TreeSet?Set Propeties?HashTable 我記的不是方法名,而是思想,我知道它們都有增刪改查的方法,但這些方法的具體名稱,我記得不是很清楚,對于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方法怎么做,就看當前這個對象的類中是如何編寫這個方法的)實驗代碼: public class Parent implements Comparable { private int age = 0;?Map Treemap/HashMap if(!newVector.contains(obj);newVector.add(obj); } public class Child extends Parent { } public class TreeSetTest { } 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 /** * @param args */ public static void main(String[] args){ } // TODO Auto-generated method stub TreeSet set = new TreeSet();set.add(new Parent(3));set.add(new Child());set.add(new Parent(4));System.out.println(set.size());} // TODO Auto-generated method stub System.out.println(”method of child“);Child o1 =(Child)o;return 1;public Child(){ } public int compareTo(Object o){ super(3);public Parent(int age){ } public int compareTo(Object o){ } // TODO Auto-generated method stub System.out.println(”method of parent“);Parent o1 =(Parent)o;return age>o1.age?1:age 常用的接口:Remote List Map Document NodeList ,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)、Session(Hibernate),HttpSession 72、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類? 字節流,字符流。字節流繼承于InputStream OutputStream,字符流繼承于InputStreamReader OutputStreamWriter。在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 = ”中國人“;/*FileOutputStream fos = new FileOutputStream(”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 = new char[1024];int len = fr.read(buf);String myStr = new String(buf,0,len);System.out.println(myStr);*/ /*FileInputStream fr = new FileInputStream(”1.txt“);byte[] buf = new byte[1024];int len = fr.read(buf);String myStr = new String(buf,0,len,”UTF-8“);System.out.println(myStr);*/ } } 74、什么是java序列化,如何實現java序列化?或者請解釋Serializable接口的作用。 我們有時候將一個java對象變成字節流的形式傳出去或者從一個字節流中恢復成一個java對象,例如,要將java對象存儲到硬盤或者傳送給網絡上的其他計算機,這個過程我們可以自己寫代碼去把一個java對象變成某個格式的字節流再傳輸,但是,jre本身就提供了這種支持,我們可以調用OutputStream的writeObject方法來做,如果要讓java 幫我們做,要被傳輸的對象必須實現serializable接口,這樣,javac編譯時就會進行特殊處理,編譯的類才可以被writeObject方法操作,這就是所謂的序列化。需要被序列化的類必須實現Serializable接口,該接口是一個mini接口,其中沒有需要實現的方法,implements Serializable只是為了標注該對象是可被序列化的。 例如,在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),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操作方法。 78、垃圾回收的優點和原理。并考慮2種回收機制。 Java語言中一個顯著的特點就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候不再需要考慮內存管理。由于有個垃圾回收機制,Java中的對象不再有”作用域“的概念,只有對象的引用才有”作用域“。垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存。垃圾回收器通常是作為一個單獨的低級別的線程運行,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。回收機制有分代復制垃圾回收和標記垃圾回收,增量垃圾回收。 79、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收? 對于GC來說,當程序員創建對象時,GC就開始監控這個對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是”可達的“,哪些對象是”不可達的“。當GC確定一些對象為”不可達“時,GC就有責任回收這些內存空間。可以。程序員可以手動執行System.gc(),通知GC運行,但是Java語言規范并不保證GC BufferedReader br = new BufferedReader(new InputStreamReader();new FileInputStream(”1.txt“),”UTF-8“)String myStr = br.readLine();br.close();System.out.println(myStr); 一定會執行。 80、什么時候用assert。 assertion(斷言)在軟件開發中是一種常用的調試方式,很多開發語言中都支持這種機制。在實現中,assertion就是在程序中的一條語句,它對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值為true;如果該值為false,說明程序已經處于不正確的狀態下,assert將給出警告或退出。一般來說,assertion用于保證程序最基本、關鍵的正確性。assertion檢查通常在開發和測試時開啟。為了提高性能,在軟件發布后,assertion檢查通常是關閉的。package com.huawei.interview; public class AssertTest { } 81、java中會存在內存泄漏嗎,請簡單描述。 所謂內存泄露就是指一個不再被程序使用的對象或變量一直被占據在內存中。java中有垃圾回收機制,它可以保證一對象不再被引用的時候,即對象編程了孤兒的時候,對象將自動被垃圾回收器從內存中清除掉。由于Java 使用有向圖的方式進行垃圾回收管理,可以消除引用循環的問題,例如有兩個對象,相互引用,只要它們和根進程不可達的,那么GC也是可以回收它們的,例如下面的代碼可以看到這種情況的內存回收: package com.huawei.interview; import java.io.IOException; public class GarbageTest { /** * @param args * @throws IOException */ public static void main(String[] args)throws IOException { // TODO Auto-generated method stub try { gcTest();// TODO Auto-generated catch block e.printStackTrace();} catch(IOException e){ /** * @param args */ public static void main(String[] args){ } // TODO Auto-generated method stub int i = 0;for(i=0;i<5;i++){ } //假設程序不小心多了一句--i;--i;assert i==5;System.out.println(i); } java中的內存泄露的情況:長生命周期的對象持有短生命周期對象的引用就很可能發生內存泄露,盡管短生命周期對象已經不再需要,但是因為長生命周期對象持有它的引用而導致不能被回收,這就是java中內存泄露的發生場景,通俗地說,就是程序員可能創建了一個對象,以后一直不再使用這個對象,這個對象卻一直被引用,即這個對象無用但是卻無法被垃圾回收器回收的,這就是java中可能出現內存泄露的情況,例如,緩存系統,我們加載了一個對象放在緩存中(例如放在一個全局map對象中),然后一直不再使用它,這個對象一直被緩存引用,但卻不再被使用。 檢查java中的內存泄露,一定要讓程序將各種分支情況都完整執行到程序結束,然后看某個對象是否被使用過,如果沒有,則才能判定這個對象屬于內存泄露。 如果一個外部類的實例對象的方法返回了一個內部類的實例對象,這個內部類對象被長期引用了,即使那個外部類實例對象不再被使用,但由于內部類持久外部類的實例對象,這個外部類對象將不會被垃圾回收,這也會造成內存泄露。 private static class Person { } byte[] data = new byte[20000000];Person mate = null;public void setMate(Person other){ } mate = other;private static void gcTest()throws IOException { } System.in.read();System.in.read();System.in.read();System.in.read();p1.setMate(p2);p2.setMate(p1);System.out.println(”before exit gctest!“);System.in.read();System.in.read();System.gc();System.out.println(”exit gctest!“); Person p2 = new Person(); Person p1 = new Person(); } } System.out.println(”has exited gcTest!“);System.in.read();System.in.read();for(int i=0;i<100;i++){ } System.gc();System.in.read();System.in.read(); System.out.println(”out begin gc!“); 下面內容來自于網上(主要特點就是清空堆棧中的某個元素,并不是徹底把它從數組中拿掉,而是把存儲的總數減少,本人寫得可以比這個好,在拿掉某個元素時,順便也讓它從數組中消失,將那個元素所在的位置的值設置為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); } } } 上面的原理應該很簡單,假如堆棧加了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個對象無法被回收其實這個應該很容易理解,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; public class String { } 報告的錯誤如下: java.lang.NoSuchMethodError: main Exception in thread ”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 /** * @param args */ public static void main(String[] args){ } // TODO Auto-generated method stub System.out.println(”string“); 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-static methods。可改成”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(”Do something...“); } } 這個好像很明顯。 答案: 正確。從來沒有人說過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 static final.所以可以通過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 = new Ball(”Football“); System.out.println(ball.getName()); } } 這個錯誤不容易發現。 答案: 錯。”interface Rollable extends Playable, Bounceable“沒有問題。interface可繼承多個interfaces,所以這里沒錯。問題出在interface Rollable里的”Ball ball = new Ball(“PingPang”);“。任何在interface里聲明的interface variable(接口變量,也可稱成員變量),默認為public static final。也就是說”Ball ball = new Ball(“PingPang”);“實際上是”public static final Ball ball = new Ball(“PingPang”);“。在Ball類的Play()方法中,”ball = new Ball(“Football”);“改變了ball的reference,而這里的ball來自Rollable interface,Rollable interface里的ball是public static final的,final的object是不能被改變reference的。因此編譯器將在”ball = new Ball(“Football”);“這里顯示有錯。二.算法與編程 1、編寫一個程序,將a.txt文件中的單詞與b.txt文件中的單詞交替合并到c.txt文件中,a.txt文件中的單詞用回車符分隔,b.txt文件中用回車或空格進行分隔。答: import java.io.File;import java.io.FileReader;import java.io.FileWriter; public class MainClass{ } class FileManager{ String[] words = null;public static void main(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){ } while((bWord = b.nextWord())!= null){ } c.write(bWord + ”n“);c.write(aWord + ”n“);bWord = b.nextWord();if(bWord!= null)c.write(bWord + ”n“); package cn.itcast;c.close(); } 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 boolean accept(File dir, String name){ } return name.endsWith(”.java“);public static void main(String[] args)throws Exception { File srcDir = new File(”java“);if(!(srcDir.exists()&& srcDir.isDirectory()))throw new Exception(”目錄不存在“);File[] files = srcDir.listFiles(new FilenameFilter(){ int pos = 0;public FileManager(String filename,char[] seperators)throws Exception{ } public String nextWord(){ } if(pos == words.length)return null;return words[pos++];File f = new File(filename);FileReader reader = new FileReader(f);char[] buf = new char[(int)f.length()];int len = reader.read(buf);String results = new String(buf,0,len);String regex = null;if(seperators.length >1){ } words = results.split(regex);regex = ”“ + seperators[0] + ”|“ + seperators[1];regex = ”“ + seperators[0];}else{ } 由本題總結的思想及策略模式的解析: 1.class jad2java{ } 分析listFiles方法內部的策略模式實現原理 File[] listFiles(FileFilter filter){ File[] files = listFiles();//Arraylist acceptedFilesList = new ArrayList();File[] acceptedFiles = new File[files.length];int pos = 0;1.得到某個目錄下的所有的java文件集合 1.1 得到目錄 File srcDir = new File(”d:java“);1.2 得到目錄下的所有java文件:File[] files = srcDir.listFiles(new MyFileFilter());1.3 只想得到.java的文件: class MyFileFilter implememyts FileFilter{ } 2.1 得到目標目錄,如果目標目錄不存在,則創建之 2.2 根據源文件名得到目標文件名,注意要用正則表達式,注意.的轉義。2.3 根據表示目錄的File和目標文件名的字符串,得到表示目標文件的File。 //要在硬盤中準確地創建出一個文件,需要知道文件名和文件的目錄。//方法接受的參數類型盡量面向父類,越抽象越好,這樣適應面更寬廣。2.4 將源文件的流拷貝成目標文件流,拷貝方法獨立成為一個方法,方法的參數采用抽象流的形式。public boolean accept(File pathname){ } return pathname.getName().endsWith(”.java“)} } private static void copy(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); System.out.println(files.length);File destDir = new File(”jad“);if(!destDir.exists())destDir.mkdir();for(File f :files){ } FileInputStream fis = new FileInputStream(f);String destFileName = f.getName().replaceAll(”.java$“, ”.jad“);FileOutputStream fos = new FileOutputStream(new File(destDir,destFileName));copy(fis,fos);fis.close();fos.close();2.將每個文件復制到另外一個目錄,并改擴展名 } 3、編寫一個截取字符串的函數,輸入為一個字符串和字節數,輸出為按字節截取的字符串,但要保證漢字不被截取半個,如“我ABC”,4,應該截取“我AB”,輸入“我ABC漢DEF”,6,應該輸出“我ABC”,而不是“我ABC+漢的半個”。答: 首先要了解中文字符有多種編碼及各種編碼的特征。 public static void main(String[] args)throws Exception{ } public static int trimGBK(byte[] buf,int n){ } int num = 0;boolean bChineseFirstHalf = false;for(int i=0;i } return num;if(buf[i]<0 &&!bChineseFirstHalf){ } bChineseFirstHalf = true;num++;bChineseFirstHalf = false; }else{ String str = ”我a愛中華abc我愛傳智def';String str = “我ABC漢”;int num = trimGBK(str.getBytes(“GBK”),5);System.out.println(str.substring(0,num));假設n為要截取的字節數。for(File file: files){ } Arrays.copyOf(acceptedFiles,pos);//return(File[])accpetedFilesList.toArray();boolean accepted = filter.accept(file);if(accepted){ } //acceptedFilesList.add(file);acceptedFiles[pos++] = file; 4、有一個字符串,其中包含中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。答:哈哈,其實包含中文字符、英文字符、數字字符原來是出題者放的煙霧彈。String content = “中國aadf的111薩bbb菲的zz薩菲”;HashMap map = new HashMap();for(int i=0;i char c = content.charAt(i);Integer num = map.get(c);if(num == null)num = 1;num = num + 1;else map.put(c,num); } for(Map.EntrySet entry : map){ } 估計是當初面試的那個學員表述不清楚,問題很可能是: 如果一串字符如“aaaabbc中國1512”要分別統計英文字符的數量,中文字符的數量,和數字字符的數量,假設字符中沒有中文字符、英文字符、數字字符之外的其他特殊字符。int engishCount;int chineseCount;int digitCount;for(int i=0;i } System.out.println(?????); 5、說明生活中遇到的二叉樹,用java實現二叉樹 這是組合設計模式。 我有很多個(假設10萬個)數據要保存起來,以后還需要從保存的這些數據中檢索是否存在某個數據,(我想說出二叉樹的好處,該怎么說呢?那就是說別人的缺點),假如存在數組中,那么,碰巧要找的數字位于99999那個地方,那查找的速度將很慢,因為要從第1個依次往后取,取出來后進行比較。平衡二叉樹(構建平衡二叉樹需要先排序,我們這里就不作考慮了)可以很好地解決這個問題,但二叉樹的遍歷(前序,中序,后序)效率要比數組低很多,原理如下圖: char ch = str.charAt(i);if(ch>=’0’ && ch<=’9’){ } else if((ch>=’a’ && ch<=’z’)||(ch>=’A’ && ch<=’Z’)){ } else { } chineseCount++;engishCount++;digitCount++ system.out.println(entry.getkey()+ “:” + entry.getValue()); 代碼如下: package com.huawei.interview; public class Node { public int value;public Node left;public Node right; public void store(int value){ if(value } else if(value>this.value){ } if(right == null){ } else { } right.store(value);right = new Node();right.value=value;if(left == null){ } else { } left.store(value);left = new Node();left.value=value; } public void preList(){ } public void middleList(){ } public void afterList(){ } { int [] data = new int[20];for(int i=0;i } System.out.println(); Node root = new Node();data[i] =(int)(Math.random()*100)+ 1;System.out.print(data[i] + “,”);if(left!=null)left.preList();if(right!=null)right.preList();System.out.print(this.value + “,”); if(left!=null)left.preList();System.out.print(this.value + “,”);if(right!=null)right.preList(); System.out.print(this.value + “,”);if(left!=null)left.preList();if(right!=null)right.preList();} public boolean find(int value){ System.out.println(“happen ” + this.value);if(value == this.value){ } else if(value>this.value){ { } if(left == null)return false;return left.find(value);if(right == null)return false;return right.find(value);return true;}else public static void main(String [] args) }-----------------又一次臨場寫的代碼---------------------------import java.util.Arrays;import java.util.Iterator; public class Node { private Node left;private Node right;private int value;//private int num; public Node(int value){ } public void add(int value){ } if(value > this.value){ } else{ } if(left!= null){ } Node node = new Node(value);left = node; left.add(value);else if(right!= null){ } Node node = new Node(value);right = node; right.add(value);else this.value = value; } root.value = data[0];for(int i=1;i root.find(data[19]); root.preList();System.out.println();root.middleList();System.out.println();root.afterList(); root.store(data[i]); 軟件測試工程師筆試試題 01.為什么要在一個團隊中開展軟件測試工作? 02.您是否了解以往所工作的企業的軟件測試過程?如果了解,請試述在這個過程中都有哪些工作要做?分別由哪些不同的角色來完成這些工作? 03.您是否了解以往所工作的企業的軟件開發過程?如果了解,請試述一個完整的開發過程需要完成哪些工作?分別由哪些不同的角色來完成這些工作?(對于軟件測試部分,可以簡述) 04.您在以往的測試工作中都曾經具體從事過哪些工作?其中最擅長哪部分工作? 05.您所熟悉的軟件測試類型都有哪些?請試著分別比較這些不同的測試類型的區別與聯系(如功能測試、性能測試??) 06.請試著比較一下黑盒測試、白盒測試、單元測試、集成測試、系統測試、驗收測試的區別與聯系。 07.測試計劃工作的目的是什么?測試計劃工作的內容都包括什么?其中哪些是最重要的? 08.您認為做好測試計劃工作的關鍵是什么? 09.您所熟悉的測試用例設計方法都有哪些?請分別以具體的例子來說明這些方法在測試用例設計工作中的應用。 10.您認為做好測試用例設計工作的關鍵是什么? 11.請以您以往的實際工作為例,詳細的描述一次測試用例設計的完整的過程。 12.您以往的工作中是否曾開展過測試用例的評審工作?如果有,請描述測試用例評審的過程和評審的內容。 13.您以往是否曾經從事過性能測試工作?如果有,請盡可能的詳細描述您以往的性能測試工作的完整過程。 14.您在從事性能測試工作時,是否使用過一些測試工具?如果有,請試述該工具的工作原理,并以一個具體的工作中的例子描述該工具是如何在實際工作中應用的。 15.您認為性能測試工作的目的是什么?做好性能測試工作的關鍵是什么? 16.在您以往的工作中,一條軟件缺陷(或者叫Bug)記錄都包含了哪些內容?如何提交高質量的軟件缺陷(Bug)記錄? 17.您以往所從事的軟件測試工作中,是否使用了一些工具來進行軟件缺陷(Bug)的管理? 如果有,請結合該工具描述軟件缺陷(Bug)跟蹤管理的流程。 18.您以往是否曾經從事過單元測試和集成測試?如果有,請談一下這些工作的實際開展情況。 19.您如何看待軟件過程改進?在您曾經工作過的企業中,是否有一些需要改進的東西呢?您期望的理想的測試人員的工作環境是怎樣的? 20.您以往工作過的企業中,是否開展了軟件配置管理工作?您能否描述一下這項工作的開展情況和您對這項工作的認識? 21.您是否熟悉一些主流的軟件工程方法論和思想,如RUP、CMM、CMMI、XP、PSP、TSP。如果熟悉,您是否可以談一下對這些方法論和思想的認識? 22.您認為在測試人員同開發人員的溝通過程中,如何提高溝通的效率和改善溝通的效果?維持測試人員同開發團隊中其他成員良好的人際關系的關鍵是什么? 23.在您以往的測試工作中,最讓您感到不滿意或者不堪回首的事情是什么?您是如何來對待這些事情的? 24.在即將完成這次筆試前,您是否愿意談一些自己在以往的學習和工作中獲得的工作經驗和心得體會?(可以包括軟件測試、過程改進、軟件開發或者與此無關的其他方面) 一、判斷題(每題1分,12 分,正確的√,錯誤的╳) 1.軟件測試的目的是盡可能多的找出軟件的缺陷。() 2.Beta 測試是驗收測試的一種。() 3.驗收測試是由最終用戶來實施的。() 4.項目立項前測試人員不需要提交任何工件。() 5.單元測試能發現約80%的軟件缺陷。() 6.代碼評審是檢查源代碼是否達到模塊設計的要求。() 7.自底向上集成需要測試員編寫驅動程序。() 8.負載測試是驗證要檢驗的系統的能力最高能達到什么程度。() 9.測試人員要堅持原則,缺陷未修復完堅決不予通過。() 10.代碼評審員一般由測試員擔任。() 11.我們可以人為的使得軟件不存在配置問題。() 12.集成測試計劃在需求分析階段末提交。() 二、不定項選擇題(每題2 分,10分) 1.軟件驗收測試的合格通過準則是:() A. 軟件需求分析說明書中定義的所有功能已全部實現,性能指標全部達到要求。 B. 所有測試項沒有殘余一級、二級和三級錯誤。 C. 立項審批表、需求分析文檔、設計文檔和編碼實現一致。 D. 驗收測試工件齊全。 2.軟件測試計劃評審會需要哪些人員參加?() A.項目經理 B.SQA 負責人 C.配置負責人 D.測試組 3.下列關于alpha 測試的描述中正確的是:() A.alpha 測試需要用戶代表參加 B.alpha 測試不需要用戶代表參加 C.alpha 測試是系統測試的一種 D.alpha 測試是驗收測試的一種 4.測試設計員的職責有:() A.制定測試計劃 B.設計測試用例 C.設計測試過程、腳本 D.評估測試活動 5.軟件實施活動的進入準則是:() A.需求工件已經被基線化 B.詳細設計工件已經被基線化 C.構架工件已經被基線化 D.項目階段成果已經被基線化 三、填空題(每空1分,24 分) 1.軟件驗收測試包括、、三種類型。 2.系統測試的策略有功能測試、、、、易用性測 試、、、、、、、、、、等15 種方法。 3.設計系統測試計劃需要參考的項目文檔有、和迭代計劃。 4.對面向過程的系統采用的集成策略有、兩種。 5.通過畫因果圖來寫測試用例的步驟為、、、及把因果圖轉 換為狀態圖共五個步驟。 四、簡答題(共37分) 1. 階段評審與同行評審的區別。(4 分). 什么是軟件測試。(3 分). 簡述集成測試的過程。(5 分). 怎樣做好文檔測試?(4 分) 5. 白盒測試有那幾種方法?(6 分) 6. 系統測試計劃是否需要同行評審,為什么?(4 分) 7. Alpha 測試與beta 測試的區別。(4 分). 比較負載測試、容量測試和強度測試的區別。(6 分). 測試結束的標準是什么?(3 分) 五、設計題(共15分) 對下面給出的程序控制圖,分別以各種不同的測試方法寫出最少的測試用例。 測試人員_考試試卷(考試時間100分鐘,滿分100分) 姓名:__________部門:__________員工號:__________ 一、填空題:(每一空格2分,共60分) 1、軟件實施活動的輸出工件有、、、。 2、代碼評審主要做 工作。 3、軟件實施活動中集成員的職責是。 4、驗證與確認軟件實施活動主要有、代碼評審、、、、SQA 驗證。 5、表明測試已經結束。 6、軟件測試的目的是。 7、軟件測試主要分為、、、四類測試。 8、軟件測試活動有制定測試計劃、、、、、、測 試評估、測試結束八個步驟。 9、軟件測試活動的輸出工件有_、、、、。 10、軟件測試角色有、、、。 二、不定項選擇題:(每題3 分,共15分) 1、軟件實施活動的進入準則是() A、需求工件已經被基線化 B、詳細設計工件已經被基線化 C、構架工件已經被基線化 D、項目階段成果已經被基線化 2、下面角色不屬于集成計劃評審的是() A、配置經理 B、項目經理 C、測試員 D、編碼員 3、軟件測試設計活動主要有() A、工作量分析 B、確定并說明測試用例 C、確立并結構化測試過程 D、復審并評估測試覆蓋 4、不屬于集成測試步驟的是() A、制定集成計劃 B、執行集成測試 C、記錄集成測試結果 D、回歸測試 5、屬于軟件測試活動的輸入工件的是() A、軟件工作版本 B、可測試性報告 C、軟件需求工件 D、軟件項目計劃 三、問答題:(共25 分) 1、項目的集中管理在軟件公司的哪一個層面?(2 分) 2、請描述軟件測試活動的生命周期。(8 分) 3、什么是測試評估,測試評估的范圍是什么?(5 分) 4、闡述工作版本的定義。(2 分)、請畫出軟件測試活動的流程圖。(8 分) 測試人員考試試卷(考試時間90分鐘,滿分100分) 姓名:__________部門:__________員工號:__________ 一、判斷題(每題2分,正確的“√”,錯誤的“╳”)、好的測試員不懈追求完美。() 2、測試程序僅僅按預期方式運行就行了。() 3、不存在質量很高但可靠性很差的產品。() 4、軟件測試員可以對產品說明書進行白盒測試。() 5、靜態白盒測試可以找出遺漏之處和問題。() 6、總是首先設計白盒測試用例。() 7、可以發布具有配置缺陷的軟件產品。() 8、所有軟件必須進行某種程度的兼容性測試。() 9、所有軟件都有一個用戶界面,因此必須測試易用性。() 10、測試組負責軟件質量。() 二、簡答題 1、軟件的缺陷等級應如何劃分?(3 分) 2、如果能夠執行完美的黑盒測試,還需要進行白盒測試嗎?為什么?(5 分) 3、你認為一個優秀的測試工程師應該具備哪些素質?(3 分) 4、產品測試到什么時候就算是足夠了?(2 分) 5、測試計劃的目的是什么?(2 分) 6、為什么要進行軟件測試?軟件測試的目的是什么?(5 分) 7、軟件測試應該劃分幾個階段?簡述各個階段應重點測試的點?各個階段的含義?(8、如何做一名合格的測試人員?(3 分) 9、針對缺陷采取怎樣的管理措施?(5 分) 三、專業詞語解釋(每題2 分) α測試: β測試: 驅動模塊: 樁模塊: 白盒測試: 靜態測試: 四、選擇題(每題2分) 1.下面哪些屬于動態分析()A. 代碼覆蓋率 B. 模塊功能檢查 C. 系統壓力測試 D. 程序數據流分析 2.下面哪些屬于靜態分析()A、代碼規則檢查 B、序結構分析 C、序復雜度分析 D、內存泄漏 五、設計題(10分)分) 在三角形計算中,要求三角型的三個邊長:A、B 和C。當三邊不可能構成三角形時提示錯誤,可構成三角 形時計算三角形周長。若是等腰三角形打印“等腰三角形”,若是等邊三角形,則提示“等邊三角形”。畫出程 序流程圖、控制流程圖、找出基本測試路徑 ,對此設計一個測試用例。 六、論述題 1、試敘述對一個軟件項目測試的全過程。(10 分) 2、簡述你對測試工作的認識過程、在以后的工作的一些建議。(6 分)、述靜態測試和動態測試的區別?(5 分) 測試人員_考試試卷(考試時間100分鐘,每題10 分,滿分100分) 姓名:__________部門:__________員工號:__________ 1. 什么是軟件測試,以及軟件測試的意義? 2. 什么是軟件測試靜態分析,軟件測試動態分析,3. 下面那些屬于靜態分析() A、編碼規則檢查 B、程序結構分析 C、程序復雜度分析 D、內存泄漏 4. 下面那些屬于動態分析() A、代碼覆蓋率 B、模塊功能檢查 C、系統壓力測試 D、程序數據流分析 5. 從測試技術角度,正確的選擇是(),給出各自的含義? A、靜態測試 B、黑盒測試 C、動態測試 D、白盒測試 6. 從測試階段角度,測試正確的順序是(),同時給出所選擇的正確策略含義和被測對象是什么? A、單元測試 B、集成測試 C、系統測試 D、確認測試 7. 針對缺陷采取怎樣的管理措施? 8. 在測試生命周期,測試過程分為幾個階段,以及各個階段的含義? 9. 簡要寫出自己在理解的基礎質上所認為引入測試管理的意義 10. 在三角形計算中,要求三角型的三個邊長:A、B 和C。當三邊不可能構成三角形時提示錯誤,可構成三角形時計算三角形周長。若是等腰三角形打印“等腰三角形”,若是等邊三角形,則提示“等 邊三角形”。畫出程序流程圖、控制流程圖、計算圈復雜度V(g),找出基本測試路徑。 試題二 姓名:聯系電話:電子郵箱 請認真思考,并回答如下問題: 1、是否曾寫過有關“我的理想”方面作文? 如有,請在括號內選擇在哪個階段寫的,并寫出那時候的理想是什么?(□無、□小學、□初中、□高中、□大學、□社會) “我的理想”,現在是什么?(并請列1-3項支持立此理想的理由、理據;如有興志,還可列出如何實現的路線圖) 2、請問我近兩年內對自己的人生或職業有何規劃或目標? 3、期望月薪?(注意:是已含單位依法應支社保各險、食宿交通等補貼等的總額) 4、何時能夠到崗?第二篇:軟件工程師筆試題目
第三篇:最新葵花寶典.Java軟件工程師筆試面試必備(定稿)
第四篇:軟件測試工程師筆試試題(大集合)
第五篇:軟件工程師崗位筆試試題二