第一篇:學(xué)習(xí)廠java軟件開發(fā)好不好
學(xué)習(xí)甲骨文原廠java軟件開發(fā)永不過時
各行各業(yè)領(lǐng)域技術(shù)都有競爭者,現(xiàn)在技術(shù)也受到了人們關(guān)注,現(xiàn)在金錢社會不就是想學(xué)一個好的技術(shù)嗎!選擇一個好技術(shù)就是人生的最大的收獲,經(jīng)過介紹和了解我明白現(xiàn)在Java軟件開發(fā)是一個前途無量的一門技術(shù),然后我就來到了參加開發(fā)
經(jīng)過在甲骨文盈佳科技學(xué)習(xí)的一段時間,在盈佳科技沒有你學(xué)不會的,在各個老師和項目經(jīng)理的監(jiān)督下學(xué)習(xí)的更多,每周都會有小小的考試測試,去解決一些什么知識沒有掌握。以前在網(wǎng)絡(luò)上玩的一些東西但是不明白這些東西是怎么來的,又是怎么弄的,學(xué)了軟件開發(fā)我明白了,原來是通過學(xué)Java編程這個途徑來的,一目了然很多,也越來越對Java編程越來越感興趣了,也知道了以后是離不開這方面的,也知道軟件開發(fā)工程師在技術(shù)上發(fā)展的領(lǐng)域和互聯(lián)網(wǎng)緊密相連。我發(fā)現(xiàn)了選擇Java軟件開發(fā)是現(xiàn)在時代和以后未來的發(fā)展最好的職業(yè),也是永不過時的技術(shù)。
第二篇:Java軟件開發(fā)工程師個人簡歷
個 人 簡 歷 模 板
【個人信息】:
姓名:
年齡:
學(xué)歷:
聯(lián)系電話: 楊** 21歲 本科 138******11
Java軟件工程師
學(xué)習(xí)時間
2008/9-2012/6 性別: 項目經(jīng)驗 : 專業(yè): 電子郵箱: 男 一年 計算機(jī)科學(xué)與技術(shù)y****t@***.com 目標(biāo)地點: 專業(yè) 計算機(jī)科學(xué)與技術(shù) 深圳 上海 北京 【求職意向】: 目標(biāo)職位: 【教育背景】: 學(xué)校名稱 湖南師范大學(xué)
【自我評價】:
本人有責(zé)任感、學(xué)習(xí)能力強(qiáng)、有上進(jìn)心、具有很強(qiáng)的團(tuán)隊精神,善于與人溝通,表達(dá)能力良好;喜好編程開發(fā),并且有一定的編程功底,在工作上積極負(fù)責(zé),能夠很好的根據(jù)項目計劃書完成軟件的開發(fā)。
【技能專長】:
1.熟練使用Jsp,Javabean,Servlet,JDBC等Web開發(fā)技術(shù)進(jìn)行開發(fā)
2.熟練使用HTML、Javascript、Ajax等表現(xiàn)層技術(shù),了解XML;
3.熟悉Struts、Hibernate、Spring等開源框架,熟悉MVC三層架構(gòu)開發(fā)模式;
4.熟練掌握SQL Server 2000/2005、Oracle數(shù)據(jù)庫的操作;
5.熟練使用Eclipse,能夠使用PowerDesigner、Visio等建模工具;
6.熟練掌握Tomcat,了解Jboss;
7.了解C/C++等;
8.在項目開發(fā)過程中善于交流,有良好的開發(fā)及協(xié)同團(tuán)隊工作能力。
【項目經(jīng)驗:】:
項目名稱:迅捷物流管理系統(tǒng)
周期:3個月
開發(fā)工具:Eclipse,PowerDesigner,SVN,Dreamweaver
開發(fā)環(huán)境:Windows xp,Oracle 9g,JDK1.6,Tomcat6.0
開發(fā)人數(shù):6人
技術(shù)框架:Struts + Hibernate + Spring + Ajax + Log4j等
項目描述:
1.使用本系統(tǒng)可以大大提高物流業(yè)務(wù)公司的運作效率。通過全面的信息管理與分析,輔助提高物流公司業(yè)務(wù)的決策水平。本系統(tǒng)可以迅速提升公司管理水平,為降低公司運營成本,提高效率提供有力的技術(shù)保障。
2.本系統(tǒng)采用B/S模型,采用4層架構(gòu)。分為:視圖層、控制層、業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層,使用Log4j 實現(xiàn)日志管理和系統(tǒng)異常處理。
主要模塊:
1.客戶服務(wù)(客戶管理、訂單管理、操作員工作量查詢)
2.調(diào)度中心(訂單調(diào)度、任務(wù)單管理)
3.分站管理(分站管理、發(fā)票管理)
4.庫房管理(中心庫房購貨入庫/調(diào)撥出庫、分站庫房調(diào)撥入庫、領(lǐng)/退貨管理)
5.配送管理(進(jìn)/退貨管理、商品管理、庫房管理、供應(yīng)商管理、業(yè)務(wù)統(tǒng)計查詢)
6.財務(wù)管理(結(jié)算管理、發(fā)票管理,報表管理)
項目責(zé)任:參與文檔的編寫和數(shù)據(jù)庫設(shè)計,主要負(fù)責(zé)財務(wù)管理模塊開發(fā)的功能實現(xiàn)以及系統(tǒng)的集成測試。
對jfreechart有了更深一步的了解。
項目名稱:聊天室系統(tǒng)
周期:3個月
開發(fā)工具:Eclipse,PowerDesigner,Dreamweaver
開發(fā)環(huán)境:Windows xp,Oracle 9g,JDK1.6,Tomcat6.0
開發(fā)人數(shù):1人
技術(shù)框架: jsp+ Ajax等
功能描述:
1.登錄模塊: 用戶登錄,包括驗證用戶是否在線。
2.管理模塊:實時顯示在線人員列表及在線人數(shù)。
3.聊天模塊: 用戶發(fā)言,包括選擇表情和字體顏色功能。
4.退出模塊: 安全退出聊天室。
項目責(zé)任:這個聊天室系統(tǒng)是我在學(xué)習(xí)了Ajax之后,通過在網(wǎng)上查找資料和使用樂趣聊天室系統(tǒng)后的體會進(jìn)行了文檔和數(shù)據(jù)庫的設(shè)計及后面的代碼編寫。
第三篇:java軟件開發(fā)工程師 簡歷
個人簡歷
個人基本信息姓名:性別:聯(lián)系方式:出生年月:
電子郵箱:畢業(yè)院校:北京化工大學(xué)北方學(xué)院專業(yè):軟件工程學(xué)歷:本科(統(tǒng)招)求職意向
Java軟件開發(fā)工程師
教育背景2008年 9月~2012年 7月北京化工大學(xué)北方學(xué)院軟件工程本科專業(yè)技能?
?
?
?
?
?
?
?
?
?
? 熟練掌握Core Java基礎(chǔ),具有良好的編碼風(fēng)格和編程習(xí)慣;熟練掌握基于Servlet、JSP、HTML的Web編程;熟悉JQuery、Struts2、Hibernate、Spring等應(yīng)用開發(fā)框架及MVC模式;熟悉Ajax,JavaScript,XML,Css等技術(shù); 熟悉JSP頁面上的標(biāo)簽技術(shù)如EL、JSTL;熟悉MySQL、Oracle數(shù)據(jù)庫,熟練書寫基于標(biāo)準(zhǔn)的SQL語句; 了解常用的commons組件(log4j,ant),掌握應(yīng)用log4j記錄日志;熟悉Unix/Linux操作系統(tǒng)的常用命令;熟練使用MyEclipse工具進(jìn)行開發(fā),Tomcat服務(wù)器;熟悉Java設(shè)計模式:單例模式、工廠模式等;能夠獨立思考和解決常見問題,有查閱資料解決技術(shù)問題的能力。項目經(jīng)驗網(wǎng)上購物系統(tǒng)開發(fā)環(huán)境: Linux, MyEclipse, Tomcat, MySQL
使用技術(shù): Struts2+ Hibernate + JSP + Spring + Jquery + Ajax 等
項目描述:
1.注冊模塊: 使用JQuery和Ajax技術(shù)對表單進(jìn)行驗證,struts框架進(jìn)行后臺驗證, 注冊成功后向用戶郵箱發(fā)送激活碼。
2.帳號激活: 解析用戶提交的激活碼, 相應(yīng)地修改其激活狀態(tài), 激活后方能登錄。
3.瀏覽商品: 主頁面左邊是商品分類列表, 根據(jù)用戶所選的類別, 分頁顯示所有該類商品。
4.購 物 車: 用戶購買商品后, 生成商品條目添加到購物車中, 并且通過cookie技術(shù)將用戶所購買商品的信息保存到瀏覽器, 如果用戶禁止cookie使用session機(jī)制保存在服務(wù)器, 可以根據(jù)cookie、session恢復(fù)購物車.用戶可以進(jìn)入購物車對商品進(jìn)行增, 刪, 改以及恢復(fù)操作。
5.生成訂單: 用戶必須登錄后才能結(jié)算, 結(jié)算后, 生成訂單, 并且清空購物車以及對應(yīng)的Cookie、session。
6.動態(tài)更新: 根據(jù)商品的交易量, 更新網(wǎng)站主頁的 ”熱銷榜”。
責(zé)任描述: 在既有的體系結(jié)構(gòu)設(shè)計和數(shù)據(jù)表的條件下, 完成所有模塊的編碼和測試。該系
統(tǒng)基于MVC框架,使用JSP完成顯示邏輯, 頁面中使用到了Struts2標(biāo)簽和ognl
表達(dá)式進(jìn)行數(shù)據(jù)的動態(tài)綁定, 并且運用Ajax異步請求方式完成頁面的局部更新,比如用戶注冊頁面驗證,驗證碼的更新,商品瀏覽頁面的各個模塊的更新,模塊
內(nèi)頁面的翻頁。利用Cookie和Session機(jī)制對購物車?yán)锷唐愤M(jìn)行保存,快速選
取送貨地址??刂破饔蒘truts2框架提供支持,通過攔截器、action和XML的搭配很好的處理頁面發(fā)送的請求。通過Hibernate實現(xiàn)數(shù)據(jù)庫的訪問和數(shù)據(jù)的持久化,提高了程序的靈活性。DAO、工廠模式的應(yīng)用降低了組件之間的聯(lián)系。
采用Spring的IOC和DI技術(shù)實現(xiàn)頁面以及組件的注入,AOP實現(xiàn)對日志的記錄、用戶的登錄檢查和事務(wù)管理。
項目心得:
1.對于Struts2,Hibernate,Spring框架和MVC設(shè)計模式有了更深入的理解。
2.編碼時不要心急,耐心的完成每一個方法的邏輯和測試, 步步為營, 增量式開發(fā)。
編碼時, 積極和團(tuán)隊中的其他成員交流與溝通可以事半功倍。有些問題和細(xì)節(jié)自己
是很難發(fā)現(xiàn), 經(jīng)常是小組談?wù)摃r, 受到隊友的啟發(fā),順利的解決問題。
其他
1.在線考試系統(tǒng)
2.貪吃蛇
2.簡單相冊
3.五子棋
4.簡單的HTML打字游戲
5.webQQ
培訓(xùn)經(jīng)歷自我評價2011年6月~2011年11月北京達(dá)內(nèi)科技有限公司Java軟件開發(fā)實習(xí)生
1.具有一定的邏輯思維能力, 對計算機(jī)編程有著濃厚的興趣。
2.敢于接受挑戰(zhàn),喜歡鉆研, 具備獨立解決問題的能力。
3.沉穩(wěn),工欲善其事, 必先利其器, 在寫代碼之前我習(xí)慣花一些時間將邏輯關(guān)系理順,把一些細(xì)節(jié)考慮清楚, 每一步都盡量做到心里有數(shù)。
4.具有一定的英文閱讀能力,能夠閱讀英文文檔。
5.為人誠懇,熱心,具有團(tuán)隊合作精神,小組遇到問題時一起談?wù)摚业阶罴训慕鉀Q方
案。
6.性格隨和, 樂觀, 懂得及時釋放壓力, 保持積極飽滿的工作狀態(tài)。
7.經(jīng)過培訓(xùn),技能得到了很大的提升,如果還有機(jī)會充實自己,我也會非常珍惜。
第四篇:Java軟件開發(fā)實習(xí)報告(本站推薦)
Java軟件開發(fā)實習(xí)報告范文
同學(xué)們可以通過實習(xí)對java語言、JavaWeb、Oracle數(shù)據(jù)庫應(yīng)用設(shè)計及SQL語言的復(fù)習(xí)和鍛煉,并且通過使用MyEclipse 開發(fā)平臺設(shè)計庫存管理系統(tǒng)項目,以達(dá)到充分熟悉開發(fā)平臺及其應(yīng)用設(shè)計。下面帶來Java軟件開發(fā)實習(xí)報告范文,歡迎閱讀!Java軟件開發(fā)實習(xí)報告范文一
一、實習(xí)目的
通過對java語言、JavaWeb、Oracle數(shù)據(jù)庫應(yīng)用設(shè)計及SQL語言的復(fù)習(xí)和鍛煉,并且通過使用MyEclipse 開發(fā)平臺設(shè)計庫存管理系統(tǒng)項目,以達(dá)到充分熟悉開發(fā)平臺及其應(yīng)用設(shè)計。同時掌握并實踐軟件項目設(shè)計規(guī)范及其開發(fā)流程:需求分析、概要設(shè)計、詳細(xì)設(shè)計、代碼編寫、系統(tǒng)測試及軟件手冊編寫,以便提前適應(yīng)軟件公司開發(fā)流程、環(huán)境和工作要求進(jìn)一步了解java開發(fā)的相關(guān)知識,掌握java開發(fā)的基本技術(shù),豐富java開發(fā)的實戰(zhàn)經(jīng)驗。學(xué)習(xí)SQL的基礎(chǔ)知識及正確的運用方法,和有用的相關(guān)技術(shù),提高自己的工作效率。通過實習(xí),培養(yǎng)我們綜合運用已學(xué)知識Java語言的面向?qū)ο缶幊棠芰?培養(yǎng)我們動手能力;培養(yǎng)我們良好編程規(guī)范、編程方法;以便能較全面地理解、掌握和綜合運用所學(xué)的知識,提高自身的編程能力;增強(qiáng)自己的團(tuán)隊協(xié)作意識,了解軟件開發(fā)的思考角度和主要流程。為畢業(yè)之后能夠更快地進(jìn)入工作狀態(tài)并且能夠更好的工作,打好一定的基礎(chǔ)。
二、實習(xí)主要流程
1、公司管理規(guī)則,程序員素質(zhì),程序員編碼規(guī)范;
2、需求開發(fā)與管理;
3、面向?qū)ο蠓治雠c設(shè)計,面向?qū)ο缶幊痰奶匦?
4、javaSE、javaWeb、頁面設(shè)計JSP頁面;
5、數(shù)據(jù)庫設(shè)計、SQL應(yīng)用;
6、軟件需求分析與設(shè)計;
7、項目實戰(zhàn)
三、實習(xí)內(nèi)容
Oracle數(shù)據(jù)庫
數(shù)據(jù)庫是數(shù)據(jù)的結(jié)構(gòu)化集合。計算機(jī)是處理大量數(shù)據(jù)的理想工具,因此,數(shù)據(jù)庫管理系統(tǒng)在計算方面扮演著關(guān)鍵的中心角色,或是作為獨立的實用工具,或是作為其他應(yīng)用程序的組成部分。
Oracle服務(wù)器還有一套實用的特性集合,這些特性是通過與我們用戶的密切合作而開發(fā)的。在我們的基準(zhǔn)測試主頁上,給出了Oracle服務(wù)器和其他數(shù)據(jù)庫管理器的比較結(jié)果。
Oracle服務(wù)器最初是為處理大型數(shù)據(jù)庫而開發(fā)的,與已有的解決方案相比,它的速度更快,多年以來,它已成功用于眾多要求很高的生產(chǎn)環(huán)境。盡管Oracle始終在不斷發(fā)展,但目前Oracle服務(wù)器已能提供豐富和有用的功能。它具有良好的連通性、速度和安全性,這使的Oracle十分適合于訪問Internet上的數(shù)據(jù)庫。
java與SQL的應(yīng)用
Java語言是編寫數(shù)據(jù)庫應(yīng)用程序的杰出語言之一,它提供了方便訪問數(shù)據(jù)的技術(shù)。利用Java語言中的JDBC技術(shù),用戶能方便地開發(fā)出基于Web頁的數(shù)據(jù)庫訪問程序,從而擴(kuò)充絡(luò)應(yīng)用功能。JDBC(Java Database Connectivity,Java數(shù)據(jù)庫連接)是一種用于執(zhí)行SQL語句的Java API,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一的訪問接口。JDBC由一組用Java語言編寫的類與接口組成,通過調(diào)用這些類和接口所提供的方法,用戶能夠以一致的方式連接多種不同的數(shù)據(jù)庫系統(tǒng)(如Access、SQL Server XX、Oracle、Sybase等),進(jìn)而可使用標(biāo)準(zhǔn)的SQL語言來存取數(shù)據(jù)庫中的數(shù)據(jù),而不必再為每一種數(shù)據(jù)庫系統(tǒng)編寫不同的Java程序代碼。
控制技術(shù)Servlet技術(shù)
1)什么是Servlet
一個servlet就是Java編程語言中的一個類,它被用來擴(kuò)展服務(wù)器的性能,服務(wù)器上駐留著可以通過“請求響應(yīng)”編程模型來訪問的應(yīng)用程序。雖然servlet可以對任何類型的請求產(chǎn)生響應(yīng),但通常只用來擴(kuò)展Web服務(wù)器的應(yīng)用程序。Java Servlet技術(shù)為這些應(yīng)用程序定義了一個特定于HTTP的 servlet類。
和包為編寫servlet提供了接口和類。所有的servlet都必須實現(xiàn)Servlet接口,該接口定義了生命周期方法。
2)Servlet的生命周期
一個servlet的生命周期由部署servlet的容器來控制。當(dāng)一個請求映射到一個servlet時,該容器執(zhí)行下列步驟。
頁面設(shè)計JSP頁面
1)MVC 模式
為了把表現(xiàn)層presentation從請求處理request processing 和數(shù)據(jù)存儲data storage中分離開來,SUN公司推薦在JSP文件中使用一種“模型視圖控制器”Modelviewcontroller 模式。規(guī)范的SERVLET或者分離的JSP文件用于處理請求。當(dāng)請求處理完后,控制權(quán)交給一個只作為創(chuàng)建輸出作用的JSP頁。有幾種平臺都基于服務(wù)于絡(luò)層的模視圖控件 模式(比如Struts 和Spring framework)。
2)JSP技術(shù)的強(qiáng)勢
(1)一次編寫,到處運行。在這一點上Java比PHP更出色,除了系統(tǒng)之外,代碼不用做任何更改。
(2)系統(tǒng)的多平臺支持?;旧峡梢栽谒衅脚_上的任意環(huán)境中開發(fā),在任意環(huán)境中進(jìn)行系統(tǒng)部署,在任意環(huán)境中擴(kuò)展。相比ASP/PHP的局限性是顯而易見的。
(3)強(qiáng)大的可伸縮性。從只有一個小的Jar文件就可以運行Servlet/JSP,到由多臺服務(wù)器進(jìn)行集群和負(fù)載均衡,到多臺Application進(jìn)行事務(wù)處理,消息處理,一臺服務(wù)器到無數(shù)臺服務(wù)器,Java顯示了一個巨大的生命力。
(4)多樣化和功能強(qiáng)大的開發(fā)工具支持。這一點與ASP很像,Java已經(jīng)有了許多非常優(yōu)秀的開發(fā)工具,而且許多可以免費得到,并且其中許多已經(jīng)可以順利的運行于多種平臺之下。
3)JSP技術(shù)的弱勢
(1)與ASP一樣,Java的一些優(yōu)勢正是它致命的問題所在。正是由于為了跨平臺的功能,為了極度的伸縮能力,所以極大的增加了產(chǎn)品的復(fù)雜性。
(2)Java的運行速度是用class常駐內(nèi)存來完成的,所以它在一些情況下所使用的內(nèi)存比起用戶數(shù)量來說確實是“最低性能價格比”了。從另一方面,它還需要硬盤空間來儲存一系列的.java文件和.class文件,以及對應(yīng)的版本文件。
四、實習(xí)總結(jié)
通過這一期的實訓(xùn),雖然實訓(xùn)的時間不長,但是總體上收獲挺大的,學(xué)習(xí)中我不但有了學(xué)習(xí)成果的喜悅,而且自己也日漸成熟,有種說不出的喜悅。
當(dāng)我們正式準(zhǔn)備學(xué)習(xí)實訓(xùn)java編程技術(shù)時,讓我倍感興奮,畢竟java是自己以后想主攻技術(shù),所以自然也就非常的亢奮。剛開始實訓(xùn)的第一天,同學(xué)們就推薦我為組長,我感覺肩上責(zé)任之重大,那一刻起,我就決心帶領(lǐng)我們小組,奮戰(zhàn)我們的實訓(xùn)路。當(dāng)然開始學(xué)習(xí)后也并非是想象中那樣順利,開始的學(xué)習(xí)讓我異常感到學(xué)習(xí)任務(wù)的艱巨,因為學(xué)習(xí)中我們遇到了很多以前未曾遇到的難點,有時難免冥思苦想也無濟(jì)于事,通過我們小組的積極努力協(xié)作,同時請教老師和其他同學(xué),我們順利的化解了一道道的障礙。
這讓我不斷的對學(xué)習(xí)技術(shù)又有了新的認(rèn)識:學(xué)習(xí)中我們必須邊總結(jié)邊學(xué)習(xí),開始階段對老師交代的任何方法和類都不要放過,不管是否簡單與否都要樂于地接受,因為老師肯定有他的道理,相信老師走過的路比我們長,那么其經(jīng)驗也就肯定比我們豐富。上課時一定要專心聽講,一個關(guān)鍵的知識點聽漏了,可能會使一個人在課下花很多時間去消化,這樣也就會花掉做其他事情的大量時間,同時也使得學(xué)習(xí)不能和老師的講的課程同步,以至出現(xiàn)以后就跟不上老師講課的進(jìn)度而掉隊。所以學(xué)習(xí)中我們寧可先勞其筋骨,苦其心志,惡其體膚,也不能掉隊跟不上學(xué)習(xí)進(jìn)度。
在這里,我非常感謝實訓(xùn)的指導(dǎo)老師,在老師的幫助和指導(dǎo)下,我克服了Java學(xué)習(xí)上的一道道難關(guān),課上認(rèn)真聽講,摘好必要的筆記,并通過自己課后的不斷消化學(xué)習(xí),現(xiàn)在自己已經(jīng)基本掌握了java的基礎(chǔ)知識,并且能獨立的開發(fā)出系統(tǒng)。
實訓(xùn)即將結(jié)束了,我非常懷念廈門萬策在南昌大學(xué)的校內(nèi)實訓(xùn),在實訓(xùn)的這短短兩周的時間里,我每一天過的都市踏實的,充實的;我相信,只要我秉持艱苦奮斗,為理想拼搏的精神,盡管在未來的java路上荊棘叢叢,我一定可以披荊斬刺,度過重重難關(guān),實現(xiàn)自己未來的理想!
實習(xí)是為將來打基礎(chǔ)的重要階段,珍惜自己每一個工作的機(jī)會,不論什么人,什么學(xué)歷,從事什么工作,好好的表現(xiàn)、展示自己的能力,不要錯過好的機(jī)遇。沒有一件事情是輕輕松松的,但每一件事都是讓人成長的,經(jīng)歷一段過程,喜悅或是艱辛,盡管經(jīng)歷的方式不盡相同,但它的結(jié)果是相同的,我們都會因涉事而成長。
通過實習(xí),我自身發(fā)生了重大的轉(zhuǎn)變。首先,進(jìn)入公司,你就是一名職業(yè)人,不再是一名學(xué)生,你要具備一名職業(yè)人應(yīng)具備的素養(yǎng),不遲到不早退是必然的,而且還要時刻嚴(yán)格要求自己,公司的規(guī)定要嚴(yán)格遵守。然后,在技術(shù)上也有了很大的提高,學(xué)習(xí)了很多公司自己的框架和工具,這都是一些前輩的寶貴經(jīng)驗。而且所作的軟件應(yīng)用性更強(qiáng)。所以,我要堅定自己的信念,在公司好好實習(xí),爭取提早轉(zhuǎn)正,我相信我會在JAVA開發(fā)這條路上走的更長更遠(yuǎn)。
有些知識點以前沒有學(xué)過,但我也沒有去研究,實訓(xùn)時突然間覺得自己真的有點無知,雖然現(xiàn)在去看依然可以解決問題,但要浪費許多時間,這一點是我必須在以后的學(xué)習(xí)中加以改進(jìn)的地方,同時也要督促自己在學(xué)習(xí)的過程中不斷的完善自我。另外一點,也是在實訓(xùn)中必不可少的部分,就是同學(xué)之間的互相幫助。所謂”當(dāng)局者迷,旁觀者清”,有些東西感覺自己做的是時候明明沒什么錯誤,偏偏程序運行時就是有錯誤,讓其他同學(xué)幫忙看了一下,發(fā)現(xiàn)其實是個很小的錯誤。所以說,相互幫助是很重要的一點,這在以后的工作或生活中也是很關(guān)鍵的。俗話說:“要想為事業(yè)多添一把火,自己就得多添一捆材”。此次實訓(xùn),我深深體會到了積累知識的重要性。在實訓(xùn)當(dāng)中我們遇到了不少難題,但是經(jīng)過我們大家的討論和老師細(xì)心的一一指導(dǎo),問題得到了解決。兩個禮拜的實訓(xùn)結(jié)束了,收獲頗豐,同時也更深刻的認(rèn)識到要做一個合格的程序員并非我以前想像的那么容易,最重要的還是細(xì)致嚴(yán)謹(jǐn)。社會是不會要一個一無是處的人的,所以我們要更多更快地從一個學(xué)生向工作者轉(zhuǎn)變,總的來說我對這次實習(xí)還是比較滿意的,它使我學(xué)到了很多東西,為我以后的學(xué)習(xí)做了引導(dǎo),點明了方向,我相信在不遠(yuǎn)的未來定會有屬于我們自己的一片美好天空!
Java軟件開發(fā)實習(xí)報告范文二
一、實習(xí)目的
進(jìn)一步了解java開發(fā)的相關(guān)知識,掌握java開發(fā)的基本技術(shù),豐富java開發(fā)的實戰(zhàn)經(jīng)驗。學(xué)習(xí)SQL的基礎(chǔ)知識及正確的運用方法,和有用的相關(guān)技術(shù),提高自己的工作效率。通過實習(xí),培養(yǎng)我們綜合運用Java語言的面向?qū)ο缶幊棠芰?培養(yǎng)我們動手能力;培養(yǎng)我們良好編程規(guī)范、編程方法;以便能較全面地理解、掌握和綜合運用所學(xué)的知識,提高自身的編程能力;增強(qiáng)自己的團(tuán)隊協(xié)作意識,了解軟件開發(fā)的思考角度和主要流程。為畢業(yè)之后能夠更快地進(jìn)入工作狀態(tài)并且能夠更好的工作,打好一定的基礎(chǔ)。
二、實習(xí)單位及崗位介紹
1、實習(xí)單位介紹
2、實習(xí)崗位介紹
我的崗位是Java軟件工程師。實習(xí)期間參與人力管理系統(tǒng)的開發(fā),根據(jù)開發(fā)規(guī)范和流程獨立完成模塊設(shè)計、編碼、測試。編寫相關(guān)應(yīng)用系統(tǒng)的開發(fā)文檔、數(shù)據(jù)庫設(shè)計文檔等。較為詳細(xì)和系統(tǒng)的掌握了軟件開發(fā)的知識體系。把所學(xué)知識與解決實際問題相聯(lián)系,培養(yǎng)了自己發(fā)現(xiàn)問題、分析問題和解決問題的能力,從而提高了自己從事實際工作的能力。
三、實習(xí)內(nèi)容及過程
1、Java基礎(chǔ)知識
Java的基礎(chǔ)知識對于一個Java軟件工程師來說就好比是人的靈魂,現(xiàn)在的公司在招聘的時候很多都不在乎你會不會流行的技術(shù),如(Struts、Hibernate、Spring、ibatis等)。他看重的是你的基礎(chǔ)扎不扎實,對于易、騰訊等大公司來說更是如此,我們在開發(fā)過程中運用了大量的Java基礎(chǔ)知識,如類、對象、方法、成員變量、靜態(tài)變量、封裝、繼承、多態(tài)、異常、接口、抽象類、IO流等等,所以一個系統(tǒng)對于Java編程基礎(chǔ)的依賴便不言而喻。
2、MySQL、Oracle數(shù)據(jù)庫
MySQL是最流行的開放源碼SQL數(shù)據(jù)庫管理系統(tǒng),它是由MySQL AB公司開發(fā)、發(fā)布并支持的。MySQL AB是由多名MySQL開發(fā)人創(chuàng)辦的一家商業(yè)公司。它是一家第二代開放源碼公司,結(jié)合了開放源碼價值取向、方法和成功的商業(yè)模型。Oracle則是以穩(wěn)定性著稱,在訪問量和數(shù)據(jù)大量交換的服務(wù)器中,Oracle占了大臂的江山,在開發(fā)中主要用到了數(shù)據(jù)庫的查詢語句、數(shù)據(jù)庫的關(guān)系、事物等。
3、Servlet和JSP
一個Servlet就是Java編程語言中的一個類,它被用來擴(kuò)展服務(wù)器的性能,服務(wù)器上駐留著可以通過“請求響應(yīng)”編程模型來訪問的應(yīng)用程序。雖然Servlet可以對任何類型的請求產(chǎn)生響應(yīng),但通常只用來擴(kuò)展Web服務(wù)器的應(yīng)用程序。Java Servlet技術(shù)為這些應(yīng)用程序定義了一個特定于HTTP的 Servlet類。javax、servlet和javax、servlet、http包為編寫Servlet提供了接口和類。所有的Servlet都必須實現(xiàn)Servlet接口,該接口定義了生命周期方法。
JSP是由Sun Microsystems公司倡導(dǎo)、許多公司參與一起建立的一種動態(tài)技術(shù)標(biāo)準(zhǔn)。在傳統(tǒng)的頁HTML文件(*、htm,*、html)中加入Java程序片段(Scriptlet)和JSP標(biāo)簽,就構(gòu)成了JSP頁Java程序片段可以操縱數(shù)據(jù)庫、重新定向頁以及發(fā)送Email等,實現(xiàn)建立動態(tài)站所 需要的功能。所有程序操作都在服務(wù)器端執(zhí)行,絡(luò)上傳送給客戶端的僅是得到的結(jié)果,這樣大大降低了對客戶瀏覽器的要求,即使客戶瀏覽器端不支持Java,也可以訪問JSP頁。
Java Servlet是JSP技術(shù)的基礎(chǔ),而且大型的Web應(yīng)用程序的開發(fā)需要JavaServlet和JSP配合才能完成?,F(xiàn)在許多Web服務(wù)器都支持Servlet,即使不直接支持Servlet的Web服務(wù)器,也可以通過附件的應(yīng)用服務(wù)器和模塊來支持Servlet,這得益于Java的跨平臺特性。另外,由于Servlet內(nèi)部以線程方式提供提供服務(wù),不必對于每個請求都啟動一個進(jìn)程,并且利用多線程機(jī)制可以同時為多個請求服務(wù),因此Servlet的效率非常高。
4、三大框架
Struts 2是Struts的下一代產(chǎn)品,是在 struts 1和WebWork的技術(shù)基礎(chǔ)上進(jìn)行了合并的全新的Struts 2框架。其全新的Struts 2的體系結(jié)構(gòu)與Struts 1的體系結(jié)構(gòu)差別巨大。Struts 2以WebWork為核心,采用攔截器的機(jī)制來處理用戶的請求,這樣的設(shè)計也使得業(yè)務(wù)邏輯控制器能夠與Servlet API完全脫離開,所以Struts 2可以理解為WebWork的更新產(chǎn)品。雖然從Struts 1到Struts 2有著太大的變化,但是相對于WebWork,Struts 2的變化很小。
Hibernate是一個開放源代碼的對象關(guān)系映射框架,它對JDBC進(jìn)行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數(shù)據(jù)庫。Hibernate可以應(yīng)用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應(yīng)用中使用,最具革命意義的是,Hibernate可以在應(yīng)用EJB的J2EE架構(gòu)中取代CMP,完成數(shù)據(jù)持久化的重任。
Spring 也表示是一個開源框架,是為了解決企業(yè)應(yīng)用程序開發(fā)復(fù)雜性由Rod Johnson創(chuàng)建的。框架的主要優(yōu)勢之一就是其分層架構(gòu),分層架構(gòu)允許使用者選擇使用哪一個組件,同時為 J2EE 應(yīng)用程序開發(fā)提供集成的框架。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限于服務(wù)器端的開發(fā)。從簡單性、可測試性和松耦合的角度而言,任何Java應(yīng)用都可以從Spring中受益。
5、管理系統(tǒng)的開發(fā)
四、實習(xí)總結(jié)及體會
通過這次實習(xí)機(jī)會,我主要學(xué)習(xí)了以上這些java編程的技術(shù),同時也明白了身處公司中如何更好地與同事配合,畢竟在軟件開發(fā)中,你不可能一個人干完一個系統(tǒng),大家都是通過svn等團(tuán)隊管理工具互相配合完成編程任務(wù)。在實習(xí)之前,我對軟件開發(fā)的過程只有一個模糊地印象,以為只要把代碼編寫完之后就算
基本上一個項目開發(fā)完畢了。然而通過這次實習(xí),徹底顛覆了我的認(rèn)知,我當(dāng)時的認(rèn)知無疑是非常幼稚和可笑的,完全的軟件開發(fā)過程不只只是編寫代碼,在編寫代碼之前還有好多的事情要做,比如文檔的編寫、對項目進(jìn)行需求分析、數(shù)據(jù)庫設(shè)計等等。代碼編寫完成之后還要進(jìn)行測試,以及人員的培訓(xùn),這些都是必須做,也是必不可少的項目,甚至比代碼的編寫還重要。
我在開發(fā)期間遇到很多問題,但是我會試著到絡(luò)去找答案,如果實在找不到我會試著問問我的上級,或者跟一些朋友討論一下,如果發(fā)現(xiàn)了這個問題的答案我會及時把它記錄下來,方便以后遇到問題可以隨時翻閱,我相信好記性不如爛筆頭這句話,我也相信如果一個程序員寫的代碼沒有錯誤那只能證明他沒寫過代碼,雖然我比較懶,但我現(xiàn)在有空的時候都會對著電腦敲代碼,我相信手感是敲出來的,你看10遍都不如你敲一遍來得印象深刻。
通過這次實習(xí),我認(rèn)識到了一個軟件開發(fā)的完整的過程,為我今后進(jìn)行實際的工作奠定了堅實的基礎(chǔ)。首先,進(jìn)入公司,你就是一名職業(yè)人,不再是一名學(xué)生,你要具備一名職業(yè)人應(yīng)具備的素養(yǎng),不遲到不早退是必然的,而且還要時刻嚴(yán)格要求自己,公司的規(guī)定要嚴(yán)格遵守。然后,在技術(shù)上也有了很大的提高,學(xué)習(xí)了很多公司自己的框架和工具,這都是一些前輩的寶貴經(jīng)驗。而且所作的軟件應(yīng)用性更強(qiáng)。所以,在今后的學(xué)習(xí)中我會嚴(yán)于律己,認(rèn)真學(xué)習(xí)有關(guān)軟件編程的課,為以后的工作打好堅實的基礎(chǔ)。
Java軟件開發(fā)實習(xí)報告范文三
一、實訓(xùn)目的 1.熟練掌握J(rèn)ava面向?qū)ο蟪绦蛟O(shè)計的基礎(chǔ)知識。
2.熟練掌握J(rèn)ava中常用的Swing組件的使用方法。
3.熟練掌握J(rèn)ava程序中圖形用戶界面設(shè)計的方法。
4.熟練掌握使用JDBC操作數(shù)據(jù)庫的方法。
5.通過實訓(xùn),培養(yǎng)學(xué)生分析和解決實際問題的能力,提高調(diào)試和分析應(yīng)用程序的能力,并為后續(xù)Java高級編程等專業(yè)課程的學(xué)習(xí)奠定良好的基礎(chǔ)。
二、課程設(shè)計報告內(nèi)容
實訓(xùn)內(nèi)容
本課程設(shè)計的題目是設(shè)計一個簡化的圖書管理系統(tǒng)。該系統(tǒng)從圖書館管理人員的角度出發(fā),實現(xiàn)對圖書信息、讀者信息的瀏覽、添加、刪除和查詢,同時還可以對讀者借書、還書過程進(jìn)行操作和控制。設(shè)計內(nèi)容主要包括系統(tǒng)分析、數(shù)據(jù)庫、數(shù)據(jù)表的創(chuàng)建、系統(tǒng)各個窗體的布局及其編碼實現(xiàn)。
系統(tǒng)功能分析是在系統(tǒng)開發(fā)的總體任務(wù)的基礎(chǔ)上完成的。該管理系統(tǒng)需要完成的基本功能主要有:
查詢。
查詢。
實訓(xùn)設(shè)備或軟、硬件
硬件:PⅣ及以上性能的PC機(jī);
軟件:Windows XX或Windows XP系統(tǒng);JDK工具;環(huán)境
功能設(shè)計及思想
首先設(shè)計測試登錄窗口:
接下來設(shè)計(登錄窗口)、MainFrame(主窗體)
(圖書入庫窗口)、(添加讀者窗口)、(添加用戶窗口)、(借書窗口)、(還書窗口)、(圖書查詢窗口)。
導(dǎo)入部分及實現(xiàn)的接口
三、結(jié)論
Java實訓(xùn)在不知不覺中就結(jié)束了,我感覺自己還有好多東西要學(xué),還有好多的東西不懂呢!這是我大學(xué)以來第3次實訓(xùn),每次實訓(xùn)我都感覺學(xué)到了好多東西!因為是一天到晚的不間斷訓(xùn)練,所以記的會非常牢固。不像平時上課,每上兩次的理論課卻只有45分鐘的實際操作。在課上,有老師在前面演示我們都還能跟著做,可輪到我們獨立完成的時候,因為實際操作的少,早就忘光了!我很感謝學(xué)校有實訓(xùn)這樣的安排,把我們這一學(xué)期學(xué)的東西系統(tǒng)的集中的進(jìn)行訓(xùn)練,對我們計算機(jī)水平的提高發(fā)揮著重要作用!還要感謝我們的侯老師,侯老師學(xué)識淵博,也很有耐心,即使老師講了很多遍的問題,我們不會,老師還是會走進(jìn)我們給我們耐心的指導(dǎo),還給我們講一些學(xué)習(xí)java的方法,讓我們知道自己在哪方面不足,需要加強(qiáng),也讓我們了解到哪些需要認(rèn)真的學(xué)習(xí),那些是重點,不是沒有方向的亂學(xué)一通,什么也學(xué)不好!
經(jīng)過這次的實訓(xùn),我真真確確的感受到了這些開發(fā)工具能讓我們提高工作的效率,更直觀更便捷的切入主題。這次我們學(xué)習(xí)的是制作圖書信息管理系統(tǒng),由老師給我們指導(dǎo)。當(dāng)然,在學(xué)習(xí)的過程中并不是一帆風(fēng)順的,在這之中,因為要操作的東西很多,有時錯一步,后面的結(jié)果就無法顯示,而自己的耐心與細(xì)心又太差,根本檢查不出來是哪里出了錯!這時候,侯老師都會耐心的過來幫助我,我很感謝侯老師也很感謝學(xué)校能安排這么優(yōu)秀的侯老師來教我們!只是,我們太頑皮,有很多東西老師講了我們也沒能記住,我想在此說一句:老師,您辛苦了,下學(xué)期我們一定認(rèn)認(rèn)真真的好好學(xué)!
實訓(xùn)課是在學(xué)習(xí)與探索中度過的,短暫的15天實訓(xùn)是結(jié)束了,但其中讓我們學(xué)到了許多知識,出現(xiàn)許多未知的為什么,如圖書管理數(shù)據(jù)庫的初步設(shè)置、JDBC和SQL Server服務(wù)器的連接、數(shù)據(jù)備份與還原的步驟,報表的設(shè)計與實現(xiàn)、如何設(shè)置數(shù)據(jù)源、通過ADO訪問數(shù)據(jù)庫的方法、監(jiān)聽器、各種Java Swing組件的使用,綁定控件的屬性設(shè)置、如何實現(xiàn)Click事件、實現(xiàn)它的獲得方法、設(shè)置注冊焦點
監(jiān)聽器、獲取當(dāng)前日期、以及利用函數(shù)之間的相互轉(zhuǎn)換等等一系列的問題,正是在老師和同學(xué)的共同努力之下,我才一步步把問題解決了,最終完成了不可能完成的任務(wù)。
為期15天的實訓(xùn)課就這樣結(jié)束了,我發(fā)現(xiàn)我對java有了新的認(rèn)識,以前只知道玩游戲、娛樂和簡單的應(yīng)用。通過這次的實訓(xùn),我了解到,要真真正正的掌握這些開發(fā)工具還不是一件簡單容易的事兒,但真正掌握后,它帶個我們的將是無窮的便捷與科技,我喜歡高端便捷的生活。我希望我能做計算機(jī)這個萬能機(jī)器人的主人而不是奴隸,我會努力加油的!
通過實訓(xùn),我不僅鞏固了舊知識,也學(xué)到了新的知識,并且把所學(xué)的應(yīng)用到實際操作中,提高了我們的實際動手能力和邏輯思維能力。也讓我們對軟件開發(fā)的流程有一定了解,并且對開發(fā)軟件有了一些初步的經(jīng)驗。真正做到了學(xué)習(xí)與實際應(yīng)用相結(jié)合,真的很感謝老師為我們爭取的這次實訓(xùn)機(jī)會,在這次實訓(xùn)期間我獲益匪淺。
最后,謝謝老師在實習(xí)過程給予的幫助!老師辛苦了!感謝學(xué)校,感謝老師給我的幫助,讓我的思想、技能又上了一個臺階!
四、結(jié)束語
Java圖書管理系統(tǒng)項目心得:
其實在學(xué)習(xí)圖書管理系統(tǒng)實訓(xùn)時,我們就已經(jīng)開展了SQL的學(xué)習(xí),雖然它們之間存在不同,但是屬于同一種語言——計算機(jī)語言,但是實際上呢!它們的思想是不同的,JAVA只是一種面向?qū)ο笳Z言,而該項目實戰(zhàn)是教我們?nèi)绾沃谱饕粋€實用型的軟件,從實際出發(fā),一步一步的按照老師的規(guī)定進(jìn)行,按正規(guī)模式的方式制作軟件,從初期的項目分析,書寫可行性報告,到項目分工,最后開始書寫代碼,一天一天的寫編程日記,把每一天遇到或完成的事情記錄下來,一步步設(shè)計完成自已的工作,想象自己是一個程序設(shè)計師,我主要完成界面及其代碼的設(shè)計,而其中有很多東西是我們所不知道,正向所有編程人員一樣,我們是邊學(xué)邊作,而且書寫代碼的速度要很快,因為一個項目不應(yīng)該在書寫代碼的方面浪費時間,在這期間很訓(xùn)練人,因為每天寫代碼時,都寫的一身熱汗,著急呀!可是當(dāng)完成每天的任務(wù),而多完成時有很大的成就感了,這當(dāng)然是一個心里成就了,因為我暫時還沒有寫完這個程序了。說真的,我寫完這個圖書信息管理系統(tǒng)時,真的感覺很累了,不過又很輕松了,因為終于完成了,不過在看了其他同學(xué)設(shè)計的程序時,心里也感到眾多不足,因為我們設(shè)計的程序,在判斷某些輸入資料時,總是不嚴(yán)謹(jǐn),可能給日后用戶帶來很多不方便,而且在日后的維護(hù)工作會很大,這樣的程序,作為一個日后的程序員是不應(yīng)該出現(xiàn)的。
其中,對了SQL語言的使用是相當(dāng)?shù)闹匾?,因為沒有了SQL語言的支持,對數(shù)據(jù)庫表的操作,是根本無法實現(xiàn)的,對數(shù)據(jù)的增加、刪除、修改,都是一樣的。發(fā)現(xiàn)對于軟件來說,對數(shù)據(jù)庫的操作是至關(guān)重要的,因為有很多軟件都是這樣的,無論是什么都要對數(shù)據(jù)進(jìn)行操作,統(tǒng)計、分類、查詢、修改、刪除等,而正因為這樣,我在開始寫程序時的SQL基礎(chǔ)不好,所以出現(xiàn)在眾多難題,而翻書查尋便是經(jīng)常事情了,因為知識用到時方恨少了,其實我感覺用JAVA設(shè)計圖形界面,是很費勁的,嗯??用它作手機(jī)游戲看起來還不錯,或者用它絡(luò)B/S、都是很好的,因為它就是為了絡(luò)而生的??偟膩碚f,對于開展這樣的實用型項目,我個人認(rèn)為是非常重要的,這種實訓(xùn)突破了以前我的思維模式和慣性作法,以前對于程序來說,一開始就制作從來也不計劃,如果遇到了與想象中的不一樣的難題,就把這部分刪除掉,最近制作出來的程序,往往是功能不完善、功能不明確,沒有具體的規(guī)劃和文檔,到最后讓別人很難理解,自已也是很難弄明白。沒有一個良好的程序設(shè)計思想,當(dāng)然了學(xué)習(xí)項目實戰(zhàn)后,丟掉了那樣壞毛病,建立了良好的設(shè)計思想和編程過程。有很多不理解現(xiàn)在變成了現(xiàn)在的理解感謝,因為往往一些正確的思想,總是一開始不被人接受,而到最近時才會被理解認(rèn)同,我也這樣認(rèn)為了。
通過這次的訓(xùn)練,掌握運用了java程序設(shè)計的一些思想,了解了Java面向?qū)ο蟪绦蛟O(shè)計的基礎(chǔ)知識,熟練掌握了Java中常用的Swing組件的使用方法以及Java程序中圖形用戶界面設(shè)計的方法、使用JDBC操作數(shù)據(jù)庫的方法。初步了解了如何將復(fù)雜的問題層層分析成較小的子問題,實現(xiàn)Java編程的實際操作,掌握如何運用Java解決一些常見的編程問題,并學(xué)會、掌握分析解決問題的方法,并運用Java的程序結(jié)合自己對Java程序的初步認(rèn)識與理解進(jìn)行對照,查找自己與Java程序設(shè)計的偏差與不足之處,培養(yǎng)自己Java的思維。
本次實訓(xùn)項目通過分析并實現(xiàn)了圖書管理系統(tǒng)。本系統(tǒng)的設(shè)計讓大家了解如何根據(jù)實際問題,分析功能需求,將復(fù)雜的問題分析成子問題,達(dá)到模塊化設(shè)計系統(tǒng)功能的目標(biāo)。同時,可以利用這種方法制作通訊錄管理、課程管理、工資管理、圖書管理等小型管理系統(tǒng),此外,此次實訓(xùn)培養(yǎng)了我們java 的思維能力,讓我們對java有了更深層次的學(xué)習(xí)與理解,通過兩周的實訓(xùn)可以去解決一些簡單的編程問題,并對其出現(xiàn)的錯誤能以與改正和討論同時,也對以前自己朦朧而不解的問題有了很好的理解,也知道了一些貴重的資料為何要施加密碼,如銀行卡。對java的理論有了更深的理解,同時也可以運用本次的實訓(xùn)設(shè)置一些簡單的系統(tǒng),總之,我們從這次的實訓(xùn)中受益匪淺,我對這次實訓(xùn)還是比較滿意的,它使我學(xué)到了很多東西、學(xué)到了更深刻的知識,為我以后的學(xué)習(xí)做了引導(dǎo),點明了方向,我相信在不遠(yuǎn)的未來定會有屬于我們自己的一片美好天空!漫漫長路任我行,我需踏實腳下的路,一步步的前行。用現(xiàn)在的付出和汗水去勾畫未來美好的明天。
最后,在侯老師的細(xì)心輔導(dǎo)下,我有了很大的進(jìn)步,知識得到了擴(kuò)充,認(rèn)識得到了加深,也使得我的自學(xué)能力得到了很大的提高,在此,我向侯老師表示由衷地感謝。
第五篇:Java軟件開發(fā)工程師面試題寶典
這套面試題主要目的是幫助那些還沒有java軟件開發(fā)實際工作經(jīng)驗,而正在努力尋找java軟件開發(fā)工作的朋友在筆試時更好地贏得筆試和面試。由于這套面試題涉及的范圍很泛,很廣,很雜,大家不可能一天兩天就看完和學(xué)完這套面試寶典,即使你已經(jīng)學(xué)過了有關(guān)的技術(shù),那么至少也需要一個月的時間才能消化和掌握這套面試寶典,所以,大家應(yīng)該早作準(zhǔn)備,從拿到這套面試寶典之日起,就要堅持在每天閑暇之余學(xué)習(xí)其中幾道題目,日積月累,等到出去面試時,一切都水到渠成,面試時就自然會游刃有余了。
答題時,先答是什么,再答有什么作用和要注意什么(這部分最重要,展現(xiàn)自己的心得)
答案的段落分別,層次分明,條理清晰都非常重要,從這些表面的東西也可以看出一個人的習(xí)慣、辦事風(fēng)格、條理等。
要講你做出答案的思路過程,或者說你記住答案的思想都寫下來。把答題想著是辯論賽。答題就是給別人講道理、擺事實。答題不局限于什么格式和形式,就是要將自己的學(xué)識展現(xiàn)出來!
別因為人家題目本來就模棱兩可,你就心里膽怯和沒底氣了,不敢回答了。你要大膽地指出對方題目很模糊和你的觀點,不要把面試官想得有多高,其實他和你就是差不多的,你想想,如果他把你招進(jìn)去了,你們以后就是同事了,可不是差不多的嗎?
關(guān)于就業(yè)薪水,如果你是應(yīng)屆生,那不能要高工資,好比大餅的故事,沒有文憑還想拿高工資,就去中關(guān)村缺什么補(bǔ)什么吧!少數(shù)人基礎(chǔ)確實很好,在校期間確實又做過一些項目,那仍然是可以要到相對高的工資的。
1.Java基礎(chǔ)部分
基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語法,集合的語法,io 的語法,虛擬機(jī)方面的語法。
1、一個“.java”源文件中是否可以包括多個類(不是內(nèi)部類)?有什么限制?
可以有多個類,但只能有一個public的類,并且public的類名必須與文件名相一致。
2、Java有沒有g(shù)oto?
java中的保留字,現(xiàn)在沒有在java中使用。
3、說說&和&&的區(qū)別。
&和&&都可以用作邏輯與的運算符,表示邏輯與(and),當(dāng)運算符兩邊的表達(dá)式的結(jié)果都為true時,整個運算結(jié)果才為true,否則,只要有一方為false,則結(jié)果為false。
&&還具有短路的功能,即如果第一個表達(dá)式為false,則不再計算第二個表達(dá)式,例如,對于if(str!= null &&!str.equals(“”))表達(dá)式,當(dāng)str為null時,后面的表達(dá)式不會執(zhí)行,所以不會出現(xiàn)NullPointerException如果將&&改為&,則會拋出NullPointerException異常。If(x==33 & ++y>0)y會增長,If(x==33 && ++y>0)不會增長
&還可以用作位運算符,當(dāng)&操作符兩邊的表達(dá)式不是boolean類型時,&表示按位與操作,我們通常使用0x0f來與一個整數(shù)進(jìn)行&運算,來獲取該整數(shù)的最低4個bit位,例如,0x31 & 0x0f的結(jié)果為0x01。
備注:這道題先說兩者的共同點,再說出&&和&的特殊之處,并列舉一些經(jīng)典的例子來表明自己理解透徹深入、實際經(jīng)驗豐富。
4、在JAVA中如何跳出當(dāng)前的多重嵌套循環(huán)?
在Java中,要想跳出多重循環(huán),可以在外面的循環(huán)語句前定義一個標(biāo)號,然后在里層循環(huán)體的代碼中使用帶有標(biāo)號的break 語句,即可跳出外層循環(huán)。例如,ok: for(int i=0;i<10;i++){
}
另外,我個人通常并不使用標(biāo)號這種方式,而是讓外層的循環(huán)條件表達(dá)式的結(jié)果可以受到里層循環(huán)體代碼的控制,例如,要在二維數(shù)組中查找到某個數(shù)字。
int arr[][] = {{1,2,3},{4,5,6,7},{9}};boolean found = false;for(int i=0;i } 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); 5、switch語句能否作用在byte上,能否作用在long上,能否作用在String上? 在switch(expr1)中,expr1只能是一個整數(shù)表達(dá)式或者枚舉常量(更大字體),整數(shù)表達(dá)式可以是int基本類型或Integer包裝類型,由于,byte,short,char都可以隱含轉(zhuǎn)換為int,所以,這些類型以及這些類型的包裝類型也是可以的。顯然,long和String類型都不符合switch的語法規(guī)定,并且不能被隱式轉(zhuǎn)換成int類型,所以,它們不能作用于swtich語句中。 6、short s1 = 1;s1 = s1 + 1;有什么錯? short s1 = 1;s1 += 1;有什么錯? 對于short s1 = 1;s1 = s1 + 1;由于s1+1運算時會自動提升表達(dá)式的類型,所以結(jié)果是int型,再賦值給short類型s1時,編譯器將報告需要強(qiáng)制轉(zhuǎn)換類型的錯誤。 對于short s1 = 1;s1 += 1;由于 += 是java語言規(guī)定的運算符,java編譯器會對它進(jìn)行特殊處理,因此可以正確編譯。 7、char型變量中能不能存貯一個中文漢字?為什么? char型變量是用來存儲Unicode編碼的字符的,unicode編碼字符集中包含了漢字,所以,char型變量中當(dāng)然可以存儲漢字啦。不過,如果某個特殊的漢字沒有被包含在unicode編碼字符集中,那么,這個char型變量中就不能存儲這個特殊漢字。補(bǔ)充說明:unicode編碼占用兩個字節(jié),所以,char類型的變量也是占用兩個字節(jié)。 備注:后面一部分回答雖然不是在正面回答題目,但是,為了展現(xiàn)自己的學(xué)識和表現(xiàn)自己對問題理解的透徹深入,可以回答一些相關(guān)的知識,做到知無不言,言無不盡。 8、用最有效率的方法算出2乘以8等於幾? << 3,因為將一個數(shù)左移n位,就相當(dāng)于乘以了2的n次方,那么,一個數(shù)乘以8只要將其左移3位即可,而位運算cpu直接支持的,效率最高,所以,2乘以8等於幾的最效率的方法是2 << 3。 9、請設(shè)計一個一百億的計算器 首先要明白這道題目的考查點是什么,一是大家首先要對計算機(jī)原理的底層細(xì)節(jié)要清楚、要知道加減法的位運算原理和知道計算機(jī)中的算術(shù)運算會發(fā)生越界的情況,二是要具備一定的面向?qū)ο蟮脑O(shè)計思想。 首先,計算機(jī)中用固定數(shù)量的幾個字節(jié)來存儲的數(shù)值,所以計算機(jī)中能夠表示的數(shù)值是有一定的范圍的,為了便于講解和理解,我們先以byte 類型的整數(shù)為例,它用1個字節(jié)進(jìn)行存儲,表示的最大數(shù)值范圍為-128到+127。-1在內(nèi)存中對應(yīng)的二進(jìn)制數(shù)據(jù)為11111111,如果兩個-1相加,不考慮Java運算時的類型提升,運算后會產(chǎn)生進(jìn)位,二進(jìn)制結(jié)果為1,11111110,由于進(jìn)位后超過了byte類型的存儲空間,所以進(jìn)位部分被舍棄,即最終的結(jié)果為11111110,也就是-2,這正好利用溢位的方式實現(xiàn)了負(fù)數(shù)的運算。-128在內(nèi)存中對應(yīng)的二進(jìn)制數(shù)據(jù)為10000000,如果兩個-128相加,不考慮Java運算時的類型提升,運算后會產(chǎn)生進(jìn)位,二進(jìn)制結(jié)果為1,00000000,由于進(jìn)位后超過了byte類型的存儲空間,所以進(jìn)位部分被舍棄,即最終的結(jié)果為00000000,也就是0,這樣的結(jié)果顯然不是我們期望的,這說明計算機(jī)中的算術(shù)運算是會發(fā)生越界情況的,兩個數(shù)值的運算結(jié)果不能超過計算機(jī)中的該類型的數(shù)值范圍。由于Java中涉及表達(dá)式運算時的類型自動提升,我們無法用byte類型來做演示這種問題和現(xiàn)象的實驗,大家可以用下面一個使用整數(shù)做實驗的例子程序體驗一下: 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的正數(shù)范圍為2的31次方,表示的最大數(shù)值約等于2*1000*1000*1000,也就是20億的大小,所以,要實現(xiàn)一個一百億的計算器,我們得自己設(shè)計一個類可以用于表示很大的整數(shù),并且提供了與另外一個整數(shù)進(jìn)行加減乘除的功能,大概功能如下: ()這個類內(nèi)部有兩個成員變量,一個表示符號,另一個用字節(jié)數(shù)組表示數(shù)值的二進(jìn)制數(shù)()有一個構(gòu)造方法,把一個包含有多位數(shù)值的字符串轉(zhuǎn)換到內(nèi)部的符號和字節(jié)數(shù)組中()提供加減乘除的功能 public class BigInteger{ } 備注:要想寫出這個類的完整代碼,是非常復(fù)雜的,如果有興趣的話,可以參看jdk中自帶的java.math.BigInteger類的源碼。面試的人也知道誰都不可能在短時間內(nèi)寫出這個類的完整代碼的,他要的是你是否有這方面的概念和意識,他最重要的還是考查你的能力,所以,你不要因為自己無法寫出完整的最終結(jié)果就放棄答這道題,你要做的就是你比別人寫得多,證明你比別人強(qiáng),你有這方面的思想意識就可以了,畢竟別人可能連題目的意思都看不懂,什么都沒寫,你要敢于答這道題,即使只答了一部分,那也與那些什么都不懂的人區(qū)別出來,拉開了距離,算是矮子中的高個,機(jī)會當(dāng)然就屬于你了。另外,答案中的框架代碼也很重要,體現(xiàn)了一些面向?qū)ο笤O(shè)計的功底,特別是其中的方法命名很專業(yè),用的英文單詞很精準(zhǔn),這也是能力、經(jīng)驗、專業(yè)性、英語水平等多個方面的體現(xiàn),會給人留下很好的印象,在編程能力和其他方面條件差不多的情況下,英語好除了可以使你獲得更多機(jī)會外,薪水可以高出一千元。 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 =; 10、使用final關(guān)鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變? 使用final關(guān)鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內(nèi)容還是可以改變的。例如,對于如下語句: final StringBuffer a=new StringBuffer(“immutable”);執(zhí)行如下語句將報告編譯期錯誤: a=new StringBuffer(“");但是,執(zhí)行如下語句則可以通過編譯: a.append(” broken!“); 有人在定義方法的參數(shù)時,可能想采用如下形式來阻止方法內(nèi)部修改傳進(jìn)來的參數(shù)對象: public void method(final StringBuffer param){ } 實際上,這是辦不到的,在該方法內(nèi)部仍然可以增加如下代碼來修改參數(shù)對象: param.append(”a“); 11、”==“和equals方法究竟有什么區(qū)別? (單獨把一個東西說清楚,然后再說清楚另一個,這樣,它們的區(qū)別自然就出來了,混在一起說,則很難說清楚) ==操作符專門用來比較兩個變量的值是否相等,也就是用于比較變量所對應(yīng)的內(nèi)存中所存儲的數(shù)值是否相同,要比較兩個基本類型的數(shù)據(jù)或兩個引用變量是否相等,只能用==操作符。 如果一個變量指向的數(shù)據(jù)是對象類型的,那么,這時候涉及了兩塊內(nèi)存,對象本身占用一塊內(nèi)存(堆內(nèi)存),變量也占用一塊內(nèi)存,例如Objet obj = new Object();變量obj是一個內(nèi)存,new Object()是另一個內(nèi)存,此時,變量obj所對應(yīng)的內(nèi)存中存儲的數(shù)值就是對象占用的那塊內(nèi)存的首地址。對于指向?qū)ο箢愋偷淖兞?,如果要比較兩個變量是否指向同一個對象,即要看這兩個變量所對應(yīng)的內(nèi)存中的數(shù)值是否相等,這時候就需要用==操作符進(jìn)行比較。 equals方法是用于比較兩個獨立對象的內(nèi)容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的。例如,對于下面的代碼: String a=new String(”foo“);String b=new String(”foo“);兩條new語句創(chuàng)建了兩個對象,然后用a,b這兩個變量分別指向了其中一個對象,這是兩個不同的對象,它們的首地址是不同的,即a和b中存儲的數(shù)值是不相同的,所以,表達(dá)式a==b將返回false,而這兩個對象中的內(nèi)容是相同的,所以,表達(dá)式a.equals(b)將返回true。 在實際開發(fā)中,我們經(jīng)常要比較傳遞進(jìn)行來的字符串內(nèi)容是否等,例如,String input = …;input.equals(“quit”),許多人稍不注意就使用==進(jìn)行比較了,這是錯誤的,隨便從網(wǎng)上找?guī)讉€項目實戰(zhàn)的教學(xué)視頻看看,里面就有大量這樣的錯誤。記住,字符串的比較基本上都是使用equals方法。 如果一個類沒有自己定義equals方法,那么它將繼承Object類的equals方法,Object類的equals方法的實現(xiàn)代碼如下: boolean equals(Object o){ return this==o;} 這說明,如果一個類沒有自己定義equals方法,它默認(rèn)的equals方法(從Object 類繼承的)就是使用==操作符,也是在比較兩個變量指向的對象是否是同一對象,這時候使用equals和使用==會得到同樣的結(jié)果,如果比較的是兩個獨立的對象則總返回false。如果你編寫的類希望能夠比較該類創(chuàng)建的兩個實例對象的內(nèi)容是否相同,那么你必須覆蓋equals方法,由你自己寫代碼來決定在什么情況即可認(rèn)為兩個對象的內(nèi)容是相同的。 12、靜態(tài)變量和實例變量的區(qū)別? 在語法定義上的區(qū)別:靜態(tài)變量前要加static關(guān)鍵字,而實例變量前則不加。 在程序運行時的區(qū)別:實例變量屬于某個對象的屬性,必須創(chuàng)建了實例對象,其中的實例變量才會被分配空間,才能使用這個實例變量。靜態(tài)變量不屬于某個實例對象,而是屬于類,所以也稱為類變量,只要程序加載了類的字節(jié)碼,不用創(chuàng)建任何實例對象,靜態(tài)變量就會被分配空間,靜態(tài)變量就可以被使用了??傊?,實例變量必須創(chuàng)建對象后才可以通過這個對象來使用,靜態(tài)變量則可以直接使用類名來引用。 例如,對于下面的程序,無論創(chuàng)建多少個實例對象,永遠(yuǎn)都只分配了一個staticVar變量,并且每創(chuàng)建一個實例對象,這個staticVar就會加1;但是,每創(chuàng)建一個實例對象,就會分配一個instanceVar,即可能分配多個instanceVar,并且每個instanceVar的值都只自加了1次。 public class VariantTest{ } 備注:這個解答除了說清楚兩者的區(qū)別外,最后還用一個具體的應(yīng)用例子來說明兩者的差異,體現(xiàn)了自己有很好的解說問題和設(shè)計案例的能力,思維敏捷,超過一般程序員,有寫作能力!public static int staticVar = 0;public int instanceVar = 0;public VariantTest(){ } staticVar++;instanceVar++;System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar); 13、是否可以從一個static方法內(nèi)部發(fā)出對非static方法的調(diào)用? 不可以。因為非static方法是要與對象關(guān)聯(lián)在一起的,必須創(chuàng)建一個對象后,才可以在該對象上進(jìn)行方法調(diào)用,而static方法調(diào)用時不需要創(chuàng)建對象,可以直接調(diào)用。也就是說,當(dāng)一個static方法被調(diào)用時,可能還沒有創(chuàng)建任何實例對象,如果從一個static方法中發(fā)出對非static方法的調(diào)用,那個非static方法是關(guān)聯(lián)到哪個對象上的呢?這個邏輯無法成立,所以,一個static方法內(nèi)部發(fā)出對非static方法的調(diào)用。 14、Integer與int的區(qū)別 int是java提供的8種原始數(shù)據(jù)類型之一。Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類。int的默認(rèn)值為0,而Integer的默認(rèn)值為null,即Integer可以區(qū)分出未賦值和值為0的區(qū)別,int則無法表達(dá)出未賦值的情況,例如,要想表達(dá)出沒有參加考試和考試成績?yōu)?的區(qū)別,則只能使用Integer。在JSP開發(fā)中,Integer的默認(rèn)為null,所以用el表達(dá)式在文本框中顯示時,值為空白字符串,而int默認(rèn)的默認(rèn)值為0,所以用el表達(dá)式在文本框中顯示時,結(jié)果為0,所以,int不適合作為web層的表單數(shù)據(jù)的類型。 在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據(jù)其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm映射文件中設(shè)置其unsaved-value屬性為0。 另外,Integer提供了多個與整數(shù)相關(guān)的操作方法,例如,將一個字符串轉(zhuǎn)換成整數(shù),Integer中還定義了表示整數(shù)的最大值和最小值的常量。 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? Math類中提供了三個與取整有關(guān)的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對應(yīng),例如,ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結(jié)果為12,Math.ceil(-11.3)的結(jié)果是-11;floor的英文意義是地板,該方法就表示向下取整,Math.ceil(11.6)的結(jié)果為11,Math.ceil(-11.6)的結(jié)果是-12;最難掌握的是round方法,它表示“四舍五入”,算法為Math.floor(x+0.5),即將原來的數(shù)字加上0.5后再向下取整,所以,Math.round(11.5)的結(jié)果為12,Math.round(-11.5)的結(jié)果為-11。 16、下面的代碼有什么不妥之處? 1.if(username.equals(“zxx”){} 2.int x = 1; return x==1?true:false; 17、請說出作用域public,private,protected,以及不寫時的區(qū)別 這四個作用域的可見范圍如下表所示。 說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。 作用域 當(dāng)前類 同一package 子孫類 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × 備注:只要記住了有4種訪問權(quán)限,4個訪問范圍,然后將全選和范圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。 18、Overload和Override的區(qū)別。Overloaded的方法是否可以改變返回值的類型? Overload是重載的意思,Override是覆蓋的意思,也就是重寫。 重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數(shù)列表各不相同(即參數(shù)個數(shù)或類型不同)。 重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數(shù)完全相同,通過子類創(chuàng)建的實例對象調(diào)用這個方法時,將調(diào)用子類中的定義方法,這相當(dāng)于把父類中定義的那個完全相同的方法給覆蓋了,這也是面向?qū)ο缶幊痰亩鄳B(tài)性的一種表現(xiàn)。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權(quán)限只能比父類的更大,不能更小。如果父類的方法是private類型,那么,子類則不存在覆蓋的限制,相當(dāng)于子類中增加了一個全新的方法。 至于Overloaded的方法是否可以改變返回值的類型這個問題,要看你倒底想問什么呢?這個題目很模糊。如果幾個Overloaded的方法的參數(shù)列表不一樣,它們的返回者類型當(dāng)然也可以不一樣。但我估計你想問的問題是:如果兩個方法的參數(shù)列表完全一樣,是否可以讓它們的返回值不同來實現(xiàn)重載Overload。這是不行的,我們可以用反證法來說明這個問題,因為我們有時候調(diào)用一個方法時也可以不定義返回結(jié)果變量,即不要關(guān)心其返回結(jié)果,例如,我們調(diào)用map.remove(key)方法時,雖然remove方法有返回值,但是我們通常都不會定義接收返回結(jié)果的變量,這時候假設(shè)該類中有兩個名稱和參數(shù)列表完全相同的方法,僅僅是返回類型不同,java就無法確定編程者倒底是想調(diào)用哪個方法了,因為它無法通過返回結(jié)果類型來判斷。 override可以翻譯為覆蓋,從字面就可以知道,它是覆蓋了一個方法并且對其重寫,以求達(dá)到不同的作用。對我們來說最熟悉的覆蓋就是對接口方法的實現(xiàn),在接口中一般只是對方法進(jìn)行了聲明,而我們在實現(xiàn)時,就需要實現(xiàn)接口聲明的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意以下的幾點: 1、覆蓋的方法的標(biāo)志必須要和被覆蓋的方法的標(biāo)志完全匹配,才能達(dá)到覆蓋的效果; 2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致; 3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類; 4、被覆蓋的方法不能為private,否則在其子類中只是新定義了一個方法,并沒有對其進(jìn)行覆蓋。 overload對我們來說可能比較熟悉,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入?yún)?shù)來區(qū)分這些方法,然后再調(diào)用時,VM就會根據(jù)不同的參數(shù)樣式,來選擇合適的方法執(zhí)行。在使用重載要注意以下的幾點: 1、在使用重載時只能通過不同的參數(shù)樣式。例如,不同的參數(shù)類型,不同的參數(shù)個數(shù),不同的參數(shù)順序(當(dāng)然,同一方法內(nèi)的幾個參數(shù)類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int)); 2、不能通過訪問權(quán)限、返回類型、拋出的異常進(jìn)行重載; 3、方法的異常類型和數(shù)目不會對重載造成影響; 4、對于繼承來說,如果某一方法在父類中是訪問權(quán)限是priavte,那么就不能在子類對其進(jìn)行重載,如果定義的話,也只是定義了一個新方法,而不會達(dá)到重載的效果。 19、構(gòu)造器Constructor是否可被override? 構(gòu)造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。 20、接口是否可繼承接口? 抽象類是否可實現(xiàn)(implements)接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中是否可以有靜態(tài)的main方法? 接口可以繼承接口。抽象類可以實現(xiàn)(implements)接口,抽象類是否可繼承具體類。抽象類中可以有靜態(tài)的main方法。 備注:只要明白了接口和抽象類的本質(zhì)和作用,這些問題都很好回答,你想想,如果你是java語言的設(shè)計者,你是否會提供這樣的支持,如果不提供的話,有什么理由嗎?如果你沒有道理不提供,那答案就是肯定的了。 只有記住抽象類與普通類的唯一區(qū)別就是不能創(chuàng)建實例對象和允許有abstract方法。 21、寫clone()方法時,通常都有一行代碼,是什么? clone 有缺省行為,super.clone();因為首先要把父類中的成員復(fù)制到位,然后才是復(fù)制自己的成員。 22、面向?qū)ο蟮奶卣饔心男┓矫?/p> 計算機(jī)軟件系統(tǒng)是現(xiàn)實生活中的業(yè)務(wù)在計算機(jī)中的映射,而現(xiàn)實生活中的業(yè)務(wù)其實就是一個個對象協(xié)作的過程。面向?qū)ο缶幊叹褪前船F(xiàn)實業(yè)務(wù)一樣的方式將程序代碼按一個個對象進(jìn)行組織和編寫,讓計算機(jī)系統(tǒng)能夠識別和理解用對象方式組織和編寫的程序代碼,這樣就可以把現(xiàn)實生活中的業(yè)務(wù)對象映射到計算機(jī)系統(tǒng)中。 面向?qū)ο蟮木幊陶Z言有封裝、繼承、抽象、多態(tài)等4個主要的特征。1封裝: 封裝是保證軟件部件具有優(yōu)良的模塊性的基礎(chǔ),封裝的目標(biāo)就是要實現(xiàn)軟件部件的“高內(nèi)聚、低耦合”,防止程序相互依賴性而帶來的變動影響。在面向?qū)ο蟮木幊陶Z言中,對象是封裝的最基本單位,面向?qū)ο蟮姆庋b比傳統(tǒng)語言的封裝更為清晰、更為有力。面向?qū)ο蟮姆庋b就是把描述一個對象的屬性和行為的代碼封裝在一個“模塊”中,也就是一個類中,屬性用變量定義,行為用方法進(jìn)行定義,方法可以直接訪問同一個對象中的屬性。通常情況下,只要記住讓變量和訪問這個變量的方法放在一起,將一個類中的成員變量全部定義成私有的,只有這個類自己的方法才可以訪問到這些成員變量,這就基本上實現(xiàn)對象的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會面向?qū)ο蟮木幊塘?。把握一個原則:把對同一事物進(jìn)行操作的方法和相關(guān)的方法放在同一個類中,把方法和它操作的數(shù)據(jù)放在同一個類中。 例如,人要在黑板上畫圓,這一共涉及三個對象:人、黑板、圓,畫圓的方法要分配給哪個對象呢?由于畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,如果將它們在類中定義成了私有的成員變量,那么,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑這兩個屬性,人以后只是調(diào)用圓的畫圓方法、表示給圓發(fā)給消息而已,畫圓這個方法不應(yīng)該分配在人這個對象上,這就是面向?qū)ο蟮姆庋b性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(tài)(屬性)由這個對象自己的行為(方法)來讀取和改變。一個更便于理解的例子就是,司機(jī)將火車剎住了,剎車的動作是分配給司機(jī),還是分配給火車,顯然,應(yīng)該分配給火車,因為司機(jī)自身是不可能有那么大的力氣將一個火車給停下來的,只有火車自己才能完成這一動作,火車需要調(diào)用內(nèi)部的離合器和剎車片等多個器件協(xié)作才能完成剎車這個動作,司機(jī)剎車的過程只是給火車發(fā)了一個消息,通知火車要執(zhí)行剎車動作而已。 抽象: 抽象就是找出一些事物的相似和共性之處,然后將這些事物歸為一個類,這個類只考慮這些事物的相似和共性之處,并且會忽略與當(dāng)前主題和目標(biāo)無關(guān)的那些方面,將注意力集中在與當(dāng)前目標(biāo)有關(guān)的方面。例如,看到一只螞蟻和大象,你能夠想象出它們的相同之處,那就是抽象。抽象包括行為抽象和狀態(tài)抽象兩個方面。例如,定義一個Person類,如下: class Person{ } 人本來是很復(fù)雜的事物,有很多方面,但因為當(dāng)前系統(tǒng)只需要了解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標(biāo)無關(guān)的細(xì)節(jié)。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,這樣涉及的內(nèi)容就太多了,而是要善于劃分問題的邊界,當(dāng)前系統(tǒng)需要什么,就只考慮什么。 String name;int age;繼承: 在定義和實現(xiàn)一個類的時候,可以在一個已經(jīng)存在的類的基礎(chǔ)之上來進(jìn)行,把這個已經(jīng)存在的類所定義的內(nèi)容作為自己的內(nèi)容,并可以加入若干新的內(nèi)容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類數(shù)據(jù)和方法的機(jī)制,這是類之間的一種關(guān)系,提高了軟件的可重用性和可擴(kuò)展性。 多態(tài): 多態(tài)是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個類中實現(xiàn)的方法,必須在由程序運行期間才能決定。因為在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現(xiàn)上,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態(tài),這就是多態(tài)性。多態(tài)性增強(qiáng)了軟件的靈活性和擴(kuò)展性。例如,下面代碼中的UserDao是一個接口,它定義引用變量userDao指向的實例對象由daofactory.getDao()在執(zhí)行的時候返回,有時候指向的是UserJdbcDao這個實現(xiàn),有時候指向的是UserHibernateDao這個實現(xiàn),這樣,不用修改源代碼,就可以改變userDao指向的具體類實現(xiàn),從而導(dǎo)致userDao.insertUser()方法調(diào)用的具體代碼也隨之改變,即有時候調(diào)用的是UserJdbcDao的insertUser方法,有時候調(diào)用的是UserHibernateDao的insertUser方法: UserDao userDao = daofactory.getDao(); userDao.insertUser(user); 比喻:人吃飯,你看到的是左手,還是右手? 23、java中實現(xiàn)多態(tài)的機(jī)制是什么? 靠的是父類或接口定義的引用變量可以指向子類或具體實現(xiàn)類的實例對象,而程序調(diào)用的方法在運行期才動態(tài)綁定,就是引用變量所指向的具體實例對象的方法,也就是內(nèi)存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。 24、abstract class和interface有什么區(qū)別? 含有abstract修飾符的class即為抽象類,abstract 類不能創(chuàng)建的實例對象。含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現(xiàn),所以,不能有抽象構(gòu)造方法或抽象靜態(tài)方法。如果的子類沒有實現(xiàn)抽象父類中的所有抽象方法,那么子類也必須定義為abstract類型。 接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口中的方法定義默認(rèn)為public abstract類型,接口中的成員變量類型默認(rèn)為public static final。 下面比較一下兩者的語法區(qū)別: 1.抽象類可以有構(gòu)造方法,接口中不能有構(gòu)造方法。2.抽象類中可以有普通成員變量,接口中沒有普通成員變量 3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。 4.抽象類中的抽象方法的訪問類型可以是public,protected和(默認(rèn)類型,雖然 eclipse下不報錯,但應(yīng)該也不行),但接口中的抽象方法只能是public類型的,并且默認(rèn)即為public abstract類型。 5.抽象類中可以包含靜態(tài)方法,接口中不能包含靜態(tài)方法 6.抽象類和接口中都可以包含靜態(tài)成員變量,抽象類中的靜態(tài)成員變量的訪問類型可以任意,但接口中定義的變量只能是public static final類型,并且默認(rèn)即為public static final類型。7.一個類可以實現(xiàn)多個接口,但只能繼承一個抽象類。下面接著再說說兩者在應(yīng)用上的區(qū)別: 接口更多的是在系統(tǒng)架構(gòu)設(shè)計方法發(fā)揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實現(xiàn)方面發(fā)揮作用,可以實現(xiàn)代碼的重用,例如,模板方法設(shè)計模式是抽象類的一個典型應(yīng)用,假設(shè)某個項目的所有Servlet類都要用相同的方式進(jìn)行權(quán)限判斷、記錄訪問日志和處理異常,那么就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完成權(quán)限判斷、記錄訪問日志和處理異常的代碼,在各個子類中只是完成各自的業(yè)務(wù)邏輯代碼,偽代碼如下: public abstract class BaseServlet extends HttpServlet{ public final void service(HttpServletRequest request, HttpServletResponse response)throws { 記錄訪問日志 進(jìn)行權(quán)限判斷 if(具有權(quán)限){ try{ } catch(Excetpion e) { 記錄異常信息 doService(request,response);IOExcetion,ServletException } } } protected abstract void doService(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException; //注意訪問權(quán)限定義成protected,顯得既專業(yè),又嚴(yán)謹(jǐn),因為它是專門給子類用的 } public class MyServlet1 extends BaseServlet { protected void doService(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException } 父類方法中間的某段代碼不確定,留給子類干,就用模板方法設(shè)計模式。 備注:這道題的思路是先從總體解釋抽象類和接口的基本概念,然后再比較兩者的語法細(xì)節(jié),最后再說兩者的應(yīng)用區(qū)別。比較兩者語法細(xì)節(jié)區(qū)別的條理是:先從一個類中的構(gòu)造方法、普通成員變量和方法(包括抽象方法),靜態(tài)變量和方法,繼承性等6個方面逐一去比較回答,接著從第三者繼承的角度的回答,特別是最后用了一個典型的例子來展現(xiàn)自己深厚的技術(shù)功底。{ } 本Servlet只處理的具體業(yè)務(wù)邏輯代碼 25、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized? abstract的method 不可以是static的,因為抽象的方法是要被子類實現(xiàn)的,而static與子類扯不上關(guān)系!native方法表示該方法要用另外一種依賴平臺的編程語言實現(xiàn)的,不存在著被子類實現(xiàn)的問題,所以,它也不能是抽象的,不能與abstract混用。例如,F(xiàn)ileOutputSteam類要硬件打交道,底層的實現(xiàn)用的是操作系統(tǒng)相關(guān)的api實現(xiàn),例如,在windows用c語言實現(xiàn)的,所以,查看jdk 的源代碼,可以發(fā)現(xiàn)FileOutputStream的open方法的定義如下: private native void open(String name)throws FileNotFoundException;如果我們要用java調(diào)用別人寫的c語言函數(shù),我們是無法直接調(diào)用的,我們需要按照java的要求寫一個c語言的函數(shù),又我們的這個c語言函數(shù)去調(diào)用別人的c語言函數(shù)。由于我們的c語言函數(shù)是按java的要求來寫的,我們這個c語言函數(shù)就可以與java對接上,java那邊的對接方式就是定義出與我們這個c函數(shù)相對應(yīng)的方法,java中對應(yīng)的方法不需要寫具體的代碼,但需要在前面聲明native。 關(guān)于synchronized與abstract合用的問題,我覺得也不行,因為在我?guī)啄甑膶W(xué)習(xí)和開發(fā)中,從來沒見到過這種情況,并且我覺得synchronized應(yīng)該是作用在一個具體的方法上才有意義。而且,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上無法確定this是什么。 26、什么是內(nèi)部類?Static Nested Class 和 Inner Class的不同。 內(nèi)部類就是在一個類的內(nèi)部定義的類,內(nèi)部類中不能定義靜態(tài)成員(靜態(tài)成員不是對象的特性,只是為了找一個容身之處,所以需要放到一個類中而已,這么一點小事,你還要把它放到類內(nèi)部的一個類中,過分了??!提供內(nèi)部類,不是為讓你干這種事情,無聊,不讓你干。我想可能是既然靜態(tài)成員類似c語言的全局變量,而內(nèi)部類通常是用于創(chuàng)建內(nèi)部對象用的,所以,把“全局變量”放在內(nèi)部類中就是毫無意義的事情,既然是毫無意義的事情,就應(yīng)該被禁止),內(nèi)部類可以直接訪問外部類中的成員變量,內(nèi)部類可以定義在外部類的方法外面,也可以定義在外部類的方法體中,如下所示: public class Outer { } 在方法體外面定義的內(nèi)部類的訪問類型可以是public,protecte,默認(rèn)的,private等4種類型,這就好像類中定義的成員變量有4種訪問類型一樣,它們決定這個內(nèi)部類的定義對其他類是否可見;對于這種情況,我們也可以在外面創(chuàng)建內(nèi)部類的實例對象,創(chuàng)建內(nèi)部類的實例對象時,一定要先創(chuàng)建外部類的實例對象,然后用這個外部類的實例對象去創(chuàng)建內(nèi)部類的實例對象,代碼如下: Outer outer = new Outer();Outer.Inner1 inner1 = outer.new Innner1(); 在方法內(nèi)部定義的內(nèi)部類前面不能有訪問類型修飾符,就好像方法中定義的局部變量一樣,但這種內(nèi)部類的前面可以使用final或abstract修飾符。這種內(nèi)部類對其他類是不可見的其他類無法引用這種內(nèi)部類,但是這種內(nèi)部類創(chuàng)建的實例對象可以傳遞給其他類訪問。這種內(nèi)部類必須是先定義,后使用,即內(nèi)部類的定義代碼必須出現(xiàn)在使用該類之前,這與方法中的局部變量必須先定義后使用的道理也是一樣的。這種內(nèi)部類可以訪問方法體中的局部變量,但是,該局部變量前必須加final修飾符。 對于這些細(xì)節(jié),只要在eclipse寫代碼試試,根據(jù)開發(fā)工具提示的各類錯誤信息就可以馬上了解到。public class Inner1 //在方法體外面定義的內(nèi)部類 { } int out_x = 0;public void method(){ } Inner1 inner1 = new Inner1();public class Inner2 //在方法體內(nèi)部定義的內(nèi)部類 { } Inner2 inner2 = new Inner2();public method(){ } out_x = 3; 在方法體內(nèi)部還可以采用如下語法來創(chuàng)建一種匿名內(nèi)部類,即定義某一接口或類的子類的同時,還創(chuàng)建了該子類的實例對象,無需為該子類定義名稱: public class Outer { public void start(){ new Thread(new Runable(){ }).start();} 最后,在方法外部定義的內(nèi)部類前面可以加上static關(guān)鍵字,從而成為Static Nested Class,它不再具有內(nèi)部類的特性,所有,從狹義上講,它不是內(nèi)部類。Static Nested Class與普通類在運行時的行為和功能上沒有什么區(qū)別,只是在編程引用時的語法上有一些差別,它可以定義成public、protected、默認(rèn)的、private等多種類型,而普通類只能定義成public和默認(rèn)的這兩種類型。在外面引用Static Nested Class類的名稱為“外部類名.內(nèi)部類名”。在外面不需要創(chuàng)建外部類的實例對象,就可以直接創(chuàng)建Static Nested Class,例如,假設(shè)Inner是定義在Outer類中的Static Nested Class,那么可以使用如下語句創(chuàng)建Inner類: Outer.Inner inner = new Outer.Inner();由于static Nested Class不依賴于外部類的實例對象,所以,static Nested Class能訪問外部類的非static成員變量。當(dāng)在外部類中訪問Static Nested Class時,可以直接使用Static Nested Class的名字,而不需要加上外部類的名字了,在Static Nested Class中也可以直接引用外部類的static的成員變量,不需要加上外部類的名字。 在靜態(tài)方法中定義的內(nèi)部類也是Static Nested Class,這時候不能在類前面加static關(guān)鍵字,靜態(tài)方法中的Static Nested Class與普通方法中的內(nèi)部類的應(yīng)用方式很相似,它除了可以直接訪問外部類中的static的成員變量,還可以訪問靜態(tài)方法中的局部變量,但是,該局部變量前必須加final修飾符。 備注:首先根據(jù)你的印象說出你對內(nèi)部類的總體方面的特點:例如,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態(tài)成員,這是大的特點。然后再說一些細(xì)節(jié)方面的知識,例如,幾種定義方式的語法區(qū)別,靜態(tài)內(nèi)部類,以及匿名內(nèi)部類。} public void run(){}; 27、內(nèi)部類可以引用它的包含類的成員嗎?有沒有什么限制? 完全可以。如果不是靜態(tài)內(nèi)部類,那沒有什么限制! 如果你把靜態(tài)嵌套類當(dāng)作內(nèi)部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態(tài)成員,例如,下面的代碼: class Outer { static int x;static class Inner { } } void test(){ } syso(x);答題時,也要能察言觀色,揣摩提問者的心思,顯然人家希望你說的是靜態(tài)內(nèi)部類不能訪問外部類的成員,但你一上來就頂牛,這不好,要先順著人家,讓人家滿意,然后再說特殊情況,讓人家吃驚。 28、Anonymous Inner Class(匿名內(nèi)部類)是否可以extends(繼承)其它類,是否可以implements(實現(xiàn))interface(接口)? 可以繼承其他類或?qū)崿F(xiàn)其他接口。不僅是可以,而是必須! 29、super.getClass()方法調(diào)用 下面程序的輸出結(jié)果是多少? import java.util.Date;public class Test extends Date{ } 很奇怪,結(jié)果是Test 這屬于腦筋急轉(zhuǎn)彎的題目,在一個qq群有個網(wǎng)友正好問過這個問題,我覺得挺有趣,就研究了一下,沒想到今天還被你面到了,哈哈。 在test方法中,直接調(diào)用getClass().getName()方法,返回的是Test類名 由于getClass()在Object類中定義成了final,子類不能覆蓋該方法,所以,在 test方法中調(diào)用getClass().getName()方法,其實就是在調(diào)用從父類繼承的getClass()方法,等效于調(diào)用 super.getClass().getName()方法,所以,public static void main(String[] args){ } public void test(){ } System.out.println(super.getClass().getName());new Test().test();super.getClass().getName()方法返回的也應(yīng)該是Test。如果想得到父類的名稱,應(yīng)該用如下代碼: getClass().getSuperClass().getName(); 30、String是最基本的數(shù)據(jù)類型嗎? 基本數(shù)據(jù)類型包括byte、int、char、long、float、double、boolean和short。 java.lang.String類是final類型的,因此不可以繼承這個類、不能修改這個類。為了提高效率節(jié)省空間,我們應(yīng)該用StringBuffer類 31、String s = ”Hello“;s = s + ” world!“;這兩行代碼執(zhí)行后,原始的String對象中的內(nèi)容到底變了沒有? 沒有。因為String被設(shè)計成不可變(immutable)類,所以它的所有對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內(nèi)容是 ”Hello“,然后我們對s進(jìn)行了+操作,那么s所指向的那個對象是否發(fā)生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另一個 String對象,內(nèi)容為”Hello world!“,原來那個對象還存在于內(nèi)存之中,只是s這個引用變量不再指向它了。 通過上面的說明,我們很容易導(dǎo)出另一個結(jié)論,如果經(jīng)常對字符串進(jìn)行各種各樣的修改,或者說,不可預(yù)見的修改,那么使用String來代表字符串的話會引起很大的內(nèi)存開銷。因為 String對象建立之后不能再改變,所以對于每一個不同的字符串,都需要一個String對象來表示。這時,應(yīng)該考慮使用StringBuffer類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。并且,這兩種類的對象轉(zhuǎn)換十分容易。 同時,我們還可以知道,如果要使用內(nèi)容相同的字符串,不必每次都new一個String。例如我們要在構(gòu)造器中對一個名叫s的String引用變量進(jìn)行初始化,把它設(shè)置為初始值,應(yīng)當(dāng)這樣做: public class Demo { private String s;...public Demo { s = ”Initial Value“;}...} 而非 s = new String(”Initial Value“);后者每次都會調(diào)用構(gòu)造器,生成新對象,性能低下且內(nèi)存開銷大,并且沒有意義,因為String對象不可改變,所以對于內(nèi)容相同的字符串,只要一個String對象來表示就可以了。也就說,多次調(diào)用上面的構(gòu)造器創(chuàng)建多個對象,他們的String類型屬性s都指向同一個對象。 上面的結(jié)論還基于這樣一個事實:對于字符串常量,如果內(nèi)容相同,Java認(rèn)為它們代表同一個String對象。而用關(guān)鍵字new調(diào)用構(gòu)造器,總是會創(chuàng)建一個新的對象,無論內(nèi)容是否相同。至于為什么要把String類設(shè)計成不可變類,是它的用途決定的。其實不只String,很多Java標(biāo)準(zhǔn)類庫中的類都是不可變的。在開發(fā)一個系統(tǒng)的時候,我們有時候也需要設(shè)計不可變類,來傳遞一組相關(guān)的值,這也是面向?qū)ο笏枷氲捏w現(xiàn)。不可變類有一些優(yōu)點,比如因為它的對象是只讀的,所以多線程并發(fā)訪問也不會有任何問題。當(dāng)然也有一些缺點,比如每個不同的狀態(tài)都要一個對象來代表,可能會造成性能上的問題。所以Java標(biāo)準(zhǔn)類庫還提供了一個可變版本,即 StringBuffer。 32、是否可以繼承String類? String類是final類故不可以繼承。 33、String s = new String(”xyz“);創(chuàng)建了幾個String Object? 二者之間有什么區(qū)別? 兩個或一個,”xyz”對應(yīng)一個對象,這個對象放在字符串常量緩沖區(qū),常量”xyz”不管出現(xiàn)多少遍,都是緩沖區(qū)中的那一個。New String每寫一遍,就創(chuàng)建一個新的對象,它一句那個常量”xyz”對象的內(nèi)容來創(chuàng)建出一個新String對象。如果以前就用過’xyz’,這句代表就不會創(chuàng)建”xyz”自己了,直接從緩沖區(qū)拿。 34、String 和StringBuffer的區(qū)別 JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數(shù)據(jù)。這個String類提供了數(shù)值不可改變的字符串。而這個StringBuffer類提供的字符串進(jìn)行修改。當(dāng)你知道字符數(shù)據(jù)要改變的時候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動態(tài)構(gòu)造字符數(shù)據(jù)。另外,String實現(xiàn)了equals方法,new String(“abc”).equals(new String(“abc”)的結(jié)果為true,而StringBuffer沒有實現(xiàn)equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結(jié)果為false。 接著要舉一個具體的例子來說明,我們要把1到100的所有數(shù)字拼起來,組成一個串。StringBuffer sbf = new StringBuffer(); for(int i=0;i<100;i++){ sbf.append(i);} 上面的代碼效率很高,因為只創(chuàng)建了一個StringBuffer對象,而下面的代碼效率很低,因為創(chuàng)建了101個對象。 String str = new String(); for(int i=0;i<100;i++){ str = str + i;} 在講兩者區(qū)別時,應(yīng)把循環(huán)的次數(shù)搞成10000,然后用endTime-beginTime來比較兩者執(zhí)行的時間差異,最后還要講講StringBuilder與StringBuffer的區(qū)別。 String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對象存儲進(jìn)Java集合類中時會出現(xiàn)問題。 35、如何把一段逗號分割的字符串轉(zhuǎn)換成一個數(shù)組? 如果不查jdk api,我很難寫出來!我可以說說我的思路: 1.用正則表達(dá)式,代碼大概為: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、數(shù)組有沒有l(wèi)ength()這個方法? String有沒有l(wèi)ength()這個方法? 數(shù)組沒有l(wèi)ength()這個方法,有l(wèi)ength的屬性。String有有l(wèi)ength()這個方法。 37、下面這條語句一共創(chuàng)建了多少個對象:String s=”a“+”b“+”c“+”d“;答:對于如下代碼: String s1 = ”a“;String s2 = s1 + ”b“;String s3 = ”a“ + ”b“;System.out.println(s2 == ”ab“);System.out.println(s3 == ”ab“);第一條語句打印的結(jié)果為false,第二條語句打印的結(jié)果為true,這說明javac編譯可以對字符串常量直接相加的表達(dá)式進(jìn)行優(yōu)化,不必要等到運行期去進(jìn)行加法運算處理,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結(jié)果。 題目中的第一行代碼被編譯器在編譯時優(yōu)化后,相當(dāng)于直接定義了一個”abcd”的字符串,所以,上面的代碼應(yīng)該只創(chuàng)建了一個String對象。寫如下兩行代碼,String s = ”a“ + ”b“ + ”c“ + ”d“; System.out.println(s == ”abcd“);最終打印的結(jié)果應(yīng)該為true。 38、try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執(zhí)行,什么時候被執(zhí)行,在return前還是后? 也許你的答案是在return之前,但往更細(xì)地說,我的答案是在return中間執(zhí)行,請看下面程序代碼的運行結(jié)果: public class Test { static int test(){ } } ---------執(zhí)行結(jié)果---------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());;1 運行結(jié)果是1,為什么呢?主函數(shù)調(diào)用子函數(shù)并得到結(jié)果的過程,好比主函數(shù)準(zhǔn)備一個空罐子,當(dāng)子函數(shù)要返回結(jié)果時,先把結(jié)果放在罐子里,然后再將程序邏輯返回到主函數(shù)。所謂返回,就是子函數(shù)說,我不運行了,你主函數(shù)繼續(xù)運行吧,這沒什么結(jié)果可言,結(jié)果是在說這話之前放進(jìn)罐子里的。 39、下面的程序代碼輸出的結(jié)果是多少? public class smallT { } public static void main(String args[]){ smallT t = new smallT();int b = t.get();System.out.println(b);} public int get(){ try { return 1;} finally { return 2;} } 返回的結(jié)果是2。 我可以通過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結(jié)果中可以發(fā)現(xiàn),try中的return語句調(diào)用的函數(shù)先于finally中調(diào)用的函數(shù)執(zhí)行,也就是說return語句先執(zhí)行,finally語句后執(zhí)行,所以,返回的結(jié)果是2。Return并不是讓函數(shù)馬上返回,而是return語句執(zhí)行后,將把返回結(jié)果放置進(jìn)函數(shù)棧中,此時函數(shù)并不是馬上返回,它要執(zhí)行finally語句后才真正開始返回。 在講解答案時可以用下面的程序來幫助分析: public class Test { int test(){ try { } 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());; } } finally { } return func2();int func1(){ } int func2(){ System.out.println(”func2“);return 2;System.out.println(”func1“);return 1;} -----------執(zhí)行結(jié)果----------------- func1 func2 2 結(jié)論:finally中的代碼比return 和break語句后執(zhí)行 40、final, finally, finalize的區(qū)別。 final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 內(nèi)部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼…… finally是異常處理語句結(jié)構(gòu)的一部分,表示總是執(zhí)行。 finalize是Object類的一個方法,在垃圾收集器執(zhí)行的時候會調(diào)用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關(guān)閉文件等。JVM不保證此方法總被調(diào)用 41、運行時異常與一般異常有何異同? 異常表示程序運行過程中可能出現(xiàn)的非正常狀態(tài),運行時異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。 42、error和exception有什么區(qū)別? error 表示恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問題。比如說內(nèi)存溢出。不可能指望程序能處理這樣的情況。exception 表示一種設(shè)計或?qū)崿F(xiàn)問題。也就是說,它表示如果程序運行正常,從不會發(fā)生的情況。 43、Java中的異常處理機(jī)制的簡單原理和應(yīng)用。 異常是指java程序運行時(非編譯)所發(fā)生的非正常情況或錯誤,與現(xiàn)實生活中的事件很相似,現(xiàn)實生活中的事件可以包含事件發(fā)生的時間、地點、人物、情節(jié)等信息,可以用一個對象來表示,Java使用面向?qū)ο蟮姆绞絹硖幚懋惓?,它把程序中發(fā)生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。 Java對異常進(jìn)行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個子類:Error和Exception,Error 表示應(yīng)用程序本身無法克服和恢復(fù)的一種嚴(yán)重問題,程序只有死的份了,例如,說內(nèi)存溢出和線程死鎖等系統(tǒng)問題。Exception表示程序還能夠克服和恢復(fù)的問題,其中又分為系統(tǒng)異常和普通異常,系統(tǒng)異常是軟件本身缺陷所導(dǎo)致的問題,也就是軟件開發(fā)人員考慮不周所導(dǎo)致的問題,軟件使用者無法克服和恢復(fù)這種問題,但在這種問題下還可以讓軟件系統(tǒng)繼續(xù)運行或者讓軟件死掉,例如,數(shù)組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉(zhuǎn)換異常(ClassCastException);普通異常是運行環(huán)境的變化或異常所導(dǎo)致的問題,是用戶能夠克服的問題,例如,網(wǎng)絡(luò)斷線,硬盤空間不夠,發(fā)生這樣的異常后,程序不應(yīng)該死掉。 java為系統(tǒng)異常和普通異常提供了不同的解決方案,編譯器強(qiáng)制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理,所以普通異常也稱為checked異常,而系統(tǒng)異??梢蕴幚硪部梢圆惶幚?,所以,編譯器不強(qiáng)制用try..catch處理或用throws聲明,所以系統(tǒng)異常也稱為unchecked異常。 提示答題者:就按照三個級別去思考:虛擬機(jī)必須宕機(jī)的錯誤,程序可以死掉也可以不死掉的錯誤,程序不應(yīng)該死掉的錯誤; 44、請寫出你最常見到的5個runtime exception。 這道題主要考你的代碼量到底多大,如果你長期寫代碼的,應(yīng)該經(jīng)常都看到過一些系統(tǒng)方面的異常,你不一定真要回答出5個具體的系統(tǒng)異常,但你要能夠說出什么是系統(tǒng)異常,以及幾個系統(tǒng)異常就可以了,當(dāng)然,這些異常完全用其英文名稱來寫是最好的,如果實在寫不出,那就用中文吧,有總比沒有強(qiáng)! 所謂系統(tǒng)異常,就是…..,它們都是RuntimeException的子類,在jdk doc中查RuntimeException類,就可以看到其所有的子類列表,也就是看到了所有的系統(tǒng)異常。我比較有印象的系統(tǒng)異常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。 45、JAVA語言如何進(jìn)行異常處理,關(guān)鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎? 46、java中有幾種方法可以實現(xiàn)一個線程?用什么關(guān)鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用? java5以前,有如下兩種: 第一種: new Thread(){}.start();這表示調(diào)用Thread子類對象的run方法,new Thread(){}表示一個Thread的匿名子類的實例對象,子類加上run方法后的代碼如下: new Thread(){ public void run(){ } }.start(); 第二種: new Thread(new Runnable(){}).start();這表示調(diào)用Thread對象接受的Runnable對象的run方法,new Runnable(){}表示一個Runnable的匿名子類的實例對象,runnable的子類加上run方法后的代碼如下: new Thread(new Runnable(){ public void run(){ } }).start(); 從java5開始,還有如下一些線程池創(chuàng)建多線程的方式: 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(){}}); 有兩種實現(xiàn)方法,分別使用new Thread()和new Thread(runnable)形式,第一種直接調(diào)用thread的run方法,所以,我們往往使用Thread子類,即new SubThread()。第二種調(diào)用runnable的run方法。 有兩種實現(xiàn)方法,分別是繼承Thread類與實現(xiàn)Runnable接口 用synchronized關(guān)鍵字修飾同步方法 反對使用stop(),是因為它不安全。它會解除由線程獲取的所有鎖定,而且如果對象處于一種不連貫狀態(tài),那么其他線程能在那種狀態(tài)下檢查和修改它們。結(jié)果很難檢查出真正的問題所在。suspend()方法容易發(fā)生死鎖。調(diào)用suspend()的時候,目標(biāo)線程會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何線程都不能訪問鎖定的資源,除非被”掛起“的線程恢復(fù)運行。對任何線程來說,如果它們想恢復(fù)目標(biāo)線程,同時又試圖使用任何一個鎖定的資源,就會造成死鎖。所以不應(yīng)該使用suspend(),而應(yīng)在自己的Thread類中置入一個標(biāo)志,指出線程應(yīng)該活動還是掛起。若標(biāo)志指出線程應(yīng)該掛起,便用wait()命其進(jìn)入等待狀態(tài)。若標(biāo)志指出線程應(yīng)當(dāng)恢復(fù),則用一個notify()重新啟動線程。 47、sleep()和 wait()有什么區(qū)別? (網(wǎng)上的答案:sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時間,給執(zhí)行機(jī)會給其他線程,但是監(jiān)控狀態(tài)依然保持,到時后會自動恢復(fù)。調(diào)用sleep不會釋放對象鎖。wait是Object類的方法,對此對象調(diào)用wait方法導(dǎo)致本線程放棄對象鎖,進(jìn)入等待此對象的等待鎖定池,只有針對此對象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對象鎖定池準(zhǔn)備獲得對象鎖進(jìn)入運行狀態(tài)。) sleep就是正在執(zhí)行的線程主動讓出cpu,cpu去執(zhí)行其他線程,在sleep指定的時間過后,cpu才會回到這個線程上繼續(xù)往下執(zhí)行,如果當(dāng)前線程進(jìn)入了同步鎖,sleep方法并不會釋放鎖,即使當(dāng)前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無法得到執(zhí)行。wait是指在一個已經(jīng)進(jìn)入了同步鎖的線程內(nèi),讓自己暫時讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖并運行,只有其他線程調(diào)用了notify方法(notify并不釋放鎖,只是告訴調(diào)用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手里,別人還沒釋放。如果notify方法后面的代碼還有很多,需要這些代碼執(zhí)行完后才會釋放鎖,可以在notfiy方法后增加一個等待和一些代碼,看看效果),調(diào)用wait方法的線程就會解除wait狀態(tài)和程序可以再次得到鎖后繼續(xù)向下運行。對于wait的講解一定要配合例子代碼來說明,才顯得自己真明白。 package com.huawei.interview; public class MultiThread { /** * @param args */ public static void main(String[] args){ // TODO Auto-generated method stub new Thread(new Thread1()).start();try { } } Thread.sleep(10);// TODO Auto-generated catch block e.printStackTrace(); } catch(InterruptedException e){ new Thread(new Thread2()).start();private static class Thread1 implements Runnable { @Override public void run(){ // TODO Auto-generated method stub //由于這里的Thread1和下面的Thread2內(nèi)部run方法要用同一對象作為監(jiān)視器,我們這里不能用this,因為在Thread2里面的this和這個Thread1的this不是同一個對象。我們用MultiThread.class這個字節(jié)碼對象,當(dāng)前虛擬機(jī)里引用這個變量時,指向的都是同一個對象。 System.out.println(”enter thread1...“); System.out.println(”thread1 is waiting“);try { synchronized(MultiThread.class){ //釋放鎖有兩種方式,第一種方式是程序自然離開監(jiān)視器的范圍,也就是離開了synchronized關(guān)鍵字管轄的代碼范圍,另一種方式就是在synchronized關(guān)鍵字管轄的代碼內(nèi)部調(diào)用監(jiān)視器對象的wait方法。這里,使用wait方法釋放鎖。 MultiThread.class.wait(); } private static class Thread2 implements Runnable { } } } catch(InterruptedException e){ } System.out.println(”thread1 is going on...“);System.out.println(”thread1 is being over!“); // TODO Auto-generated catch block e.printStackTrace(); @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..“);//由于notify方法并不釋放鎖,即使thread2調(diào)用下面的sleep方法休息了10毫秒,但thread1仍然不會執(zhí)行,因為thread2沒有釋放鎖,所以Thread1無法得不到鎖。 } } } MultiThread.class.notify(); System.out.println(”thread2 is sleeping ten 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){ millisecond...“);} 48、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。 如果數(shù)據(jù)將在線程間共享。例如正在寫的數(shù)據(jù)以后可能被另一個線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個線程寫過了,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進(jìn)行同步存取。 當(dāng)應(yīng)用程序在對象上調(diào)用了一個需要花費很長時間來執(zhí)行的方法,并且不希望讓程序等待方法的返回時,就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率。 49.下面兩個方法同步嗎?(自己發(fā)明) class Test { synchronized static void sayHello3() } synchronized void getX(){} { } 50、多線程有幾種實現(xiàn)方法?同步有幾種實現(xiàn)方法? 多線程有兩種實現(xiàn)方法,分別是繼承Thread類與實現(xiàn)Runnable接口 同步的實現(xiàn)方面有兩種,分別是synchronized,wait與notify wait():使一個線程處于等待狀態(tài),并且釋放所持有的對象的lock。 sleep():使一個正在運行的線程處于睡眠狀態(tài),是一個靜態(tài)方法,調(diào)用此方法要捕捉InterruptedException異常。 notify():喚醒一個處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時候,并不能確切的喚醒某一個等待狀態(tài)的線程,而是由JVM確定喚醒哪個線程,而且不是按優(yōu)先級。 Allnotity():喚醒所有處入等待狀態(tài)的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。 51、啟動一個線程是用run()還是start()?.啟動一個線程是調(diào)用start()方法,使線程就緒狀態(tài),以后可以被調(diào)度為運行狀態(tài),一個線程必須關(guān)聯(lián)一些具體的執(zhí)行代碼,run()方法是該線程所關(guān)聯(lián)的執(zhí)行代碼。 52、當(dāng)一個線程進(jìn)入一個對象的一個synchronized方法后,其它線程是否可進(jìn)入此對象的其它方法? 分幾種情況: 1.其他方法前是否加了synchronized關(guān)鍵字,如果沒加,則能。 2.如果這個方法內(nèi)部調(diào)用了wait,則可以進(jìn)入其他synchronized方法。 3.如果其他個方法都加了synchronized關(guān)鍵字,并且內(nèi)部沒有調(diào)用wait,則不能。 4.如果其他方法是static,它用的同步鎖是當(dāng)前類的字節(jié)碼,與非靜態(tài)的方法不能同步,因為非靜態(tài)的方法用的是this。 53、線程的基本概念、線程的基本狀態(tài)以及狀態(tài)之間的關(guān)系 一個程序中可以有多條執(zhí)行線索同時執(zhí)行,一個線程就是程序中的一條執(zhí)行線索,每個線程上都關(guān)聯(lián)有要執(zhí)行的代碼,即可以有多段程序代碼同時運行,每個程序至少都有一個線程,即main方法執(zhí)行的那個線程。如果只是一個cpu,它怎么能夠同時執(zhí)行多段程序呢?這是從宏觀上來看的,cpu一會執(zhí)行a線索,一會執(zhí)行b線索,切換時間很快,給人的感覺是a,b在同時執(zhí)行,好比大家在同一個辦公室上網(wǎng),只有一條鏈接到外部網(wǎng)線,其實,這條網(wǎng)線一會為a傳數(shù)據(jù),一會為b傳數(shù)據(jù),由于切換時間很短暫,所以,大家感覺都在同時上網(wǎng)。 狀態(tài):就緒,運行,synchronize阻塞,wait和sleep掛起,結(jié)束。wait必須在synchronized內(nèi)部調(diào)用。 調(diào)用線程的start方法后線程進(jìn)入就緒狀態(tài),線程調(diào)度系統(tǒng)將就緒狀態(tài)的線程轉(zhuǎn)為運行狀態(tài),遇到synchronized語句時,由運行狀態(tài)轉(zhuǎn)為阻塞,當(dāng)synchronized獲得鎖后,由阻塞轉(zhuǎn)為運行,在這種情況可以調(diào)用wait方法轉(zhuǎn)為掛起狀態(tài),當(dāng)線程關(guān)聯(lián)的代碼執(zhí)行完后,線程變?yōu)榻Y(jié)束狀態(tài)。 54、簡述synchronized和java.util.concurrent.locks.Lock的異同 ? 主要相同點:Lock能完成synchronized所實現(xiàn)的所有功能 主要不同點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock一定要求程序員手工釋放,并且必須在finally從句中釋放。Lock還有更強(qiáng)大的功能,例如,它的tryLock方法可以非阻塞方式去拿鎖。 舉例說明(對下面的題用lock進(jìn)行了改寫): package com.huawei.interview; import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock; public class ThreadTest { /** * @param args */ private int j; private Lock lock = new ReentrantLock();public static void main(String[] args){ } private class Subtractor implements Runnable { } private class Adder implements Runnable { @Override public void run(){ // TODO Auto-generated method stub while(true){ @Override public void run(){ } // TODO Auto-generated method stub while(true){ } /*synchronized(ThreadTest.this){ System.out.println(”j--=“ + j--);//這里拋異常了,鎖能釋放嗎? }*/ lock.lock();try { { } lock.unlock();System.out.println(”j--=“ + j--);}finally // 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(); /*synchronized(ThreadTest.this){ System.out.println(”j++=“ + j++); }*/ lock.lock(); try { System.out.println(”j++=“ + j++); }finally { lock.unlock(); } } } } } 55、設(shè)計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。 以下程序使用內(nèi)部類實現(xiàn)線程,對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(); } } } } ----------隨手再寫的一個-------------class A { JManger j =new JManager();main(){ new A().call();} void call { for(int i=0;i<2;i++){ new Thread(new Runnable(){ public void run(){while(true){j.accumulate()}}}).start(); new Thread(new Runnable(){ public void run(){while(true){j.sub()}}}).start();} } } class JManager { private j = 0; public synchronized void subtract(){ j--} public synchronized void accumulate(){ j++;} } 56、子線程循環(huán)10次,接著主線程循環(huán)100,接著又回到子線程循環(huán)10次,接著再回到主線程又循環(huán)100,如此循環(huán)50次,請寫出程序。 最終的程序代碼如下: public class ThreadTest { } 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(){ } /** * @param args */ public static void main(String[] args){ // TODO Auto-generated method stub new ThreadTest().init(); }).start(); for(int i=0;i<50;i++){ business.MainThread(i);} private class Business { boolean bShouldSub = true;//這里相當(dāng)于定義了控制該誰執(zhí)行的一個信號燈 public synchronized void MainThread(int i){ } public synchronized void SubThread(int i){ if(!bShouldSub) try { this.wait();// TODO Auto-generated catch block e.printStackTrace();} catch(InterruptedException e){ if(bShouldSub) { } bShouldSub = true;this.notify();System.out.println(Thread.currentThread().getName()+ try { this.wait();// TODO Auto-generated catch block e.printStackTrace(); } catch(InterruptedException e){ } for(int j=0;j<5;j++)”:i=“ + i +”,j=“ + j);} for(int j=0;j<10;j++) } } } { } bShouldSub = false;this.notify(); System.out.println(Thread.currentThread().getName()+ ”:i=“ + i +”,j=“ + j);備注:不可能一上來就寫出上面的完整代碼,最初寫出來的代碼如下,問題在于兩個線程的代碼要參照同一個變量,即這兩個線程的代碼要共享數(shù)據(jù),所以,把這兩個線程的執(zhí)行代碼搬到同一個類中去: package com.huawei.interview.lym; public class ThreadTest { new Thread(new Runnable(){ public void run(){ 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);} }.start();*/ } } 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(”i=“ + i + ”,j=“ + j); try { } ThreadTest.class.wait();} e.printStackTrace(); catch(InterruptedException e){ Thread.currentThread().getName()+ } }).start();for(int i=0;i<50;i++){ synchronized(ThreadTest.class){ } ”i=“ + i + ”,j=“ + j);if(!bShouldMain){ try { } ThreadTest.class.wait();} e.printStackTrace();catch(InterruptedException e){ } { for(int j=0;j<5;j++)System.out.println(Thread.currentThread().getName()+ } } } bShouldMain = false;ThreadTest.class.notify(); } 下面使用jdk5中的并發(fā)庫來實現(xiàn)的: 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(){ public void run() { for(int i=0;i<50;i++) { lock.lock(); try { if(!bBhouldSubThread) subThreadCondition.await(); for(int j=0;j<10;j++) { System.out.println(Thread.currentThread().getName()+ ”,j=“ + j); } bBhouldSubThread = false; subThreadCondition.signal(); }catch(Exception e) { } finally { } } lock.unlock(); } } } });threadPool.shutdown();for(int i=0;i<50;i++){ lock.lock(); try { if(bBhouldSubThread) subThreadCondition.await(); } for(int j=0;j<10;j++){ System.out.println(Thread.currentThread().getName()+ ”,j=“ + j);} bBhouldSubThread = true;subThreadCondition.signal(); }catch(Exception e){ } finally { lock.unlock();} 57、介紹Collection框架的結(jié)構(gòu) 答:隨意發(fā)揮題,天南海北誰便談,只要讓別覺得你知識淵博,理解透徹即可。 58、Collection框架中實現(xiàn)比較要實現(xiàn)什么接口 comparable/comparator 59、ArrayList和Vector的區(qū)別 答: 這兩個類都實現(xiàn)了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,相當(dāng)于一種動態(tài)的數(shù)組,我們以后可以按位置索引號取出某個元素,并且其中的數(shù)據(jù)是允許重復(fù)的,這是HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號去檢索其中的元素,也不允許有重復(fù)的元素(本來題目問的與hashset沒有任何關(guān)系,但為了說清楚ArrayList與Vector的功能,我們使用對比方式,更有利于說明問題)。 接著才說ArrayList與Vector的區(qū)別,這主要包括兩個方面:.(1)同步性: Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不同步的。如果只有一個線程會訪問到集合,那最好是使用ArrayList,因為它不考慮線程安全,效率會高些;如果有多個線程會訪問到集合,那最好是使用Vector,因為不需要我們自己再去考慮和編寫線程安全的代碼。 備注:對于Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時才提供的,它們是線程不安全的。所以,我們講課時先講老的。(2)數(shù)據(jù)增長: ArrayList與Vector都有一個初始的容量大小,當(dāng)存儲進(jìn)它們里面的元素的個數(shù)超過了容量時,就需要增加ArrayList與Vector的存儲空間,每次要增加存儲空間時,不是只增加一個存儲單元,而是增加多個存儲單元,每次增加的存儲單元的個數(shù)在內(nèi)存空間利用與程序效率之間要取得一定的平衡。Vector默認(rèn)增長為原來兩倍,而ArrayList的增長策略在文檔中沒有明確規(guī)定(從源代碼看到的是增長為原來的1.5倍)。ArrayList與Vector都可以設(shè)置初始的空間大小,Vector還可以設(shè)置增長的空間大小,而ArrayList沒有提供設(shè)置增長空間的方法。 總結(jié):即Vector增長原來的一倍,ArrayList增加原來的0.5倍。 60、HashMap和Hashtable的區(qū)別 (條理上還需要整理,也是先說相同點,再說不同點)HashMap是Hashtable的輕量級實現(xiàn)(非線程安全的實現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,在只有一個線程訪問的情況下,效率要高于Hashtable。 HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。 Hashtable繼承自Dictionary類,而HashMap是Java1.2引進(jìn)的Map interface的一個實現(xiàn)。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要自己為它的方法實現(xiàn)同步,而HashMap 就必須為之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。 就HashMap與HashTable主要從三方面來說。 一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進(jìn)的Map接口的一個實現(xiàn) 二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的 三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value 61、List 和 Map 區(qū)別? 一個是存儲單列數(shù)據(jù)的集合,另一個是存儲鍵和值這樣的雙列數(shù)據(jù)的集合,List中存儲的數(shù)據(jù)是有順序,并且允許重復(fù);Map中存儲的數(shù)據(jù)是沒有順序的,其鍵是不能重復(fù)的,它的值是可以有重復(fù)的。 62、List, Set, Map是否繼承自Collection接口? List,Set是,Map不是 63、List、Map、Set三個接口,存取元素時,各有什么特點? 這樣的題屬于隨意發(fā)揮題:這樣的題比較考水平,兩個方面的水平:一是要真正明白這些內(nèi)容,二是要有較強(qiáng)的總結(jié)和表述能力。如果你明白,但表述不清楚,在別人那里則等同于不明白。 首先,List與Set具有相似性,它們都是單列元素的集合,所以,它們有一個功共同的父接口,叫Collection。Set里面不允許有重復(fù)的元素,所謂重復(fù),即不能有兩個相等(注意,不是僅僅是相同)的對象,即假設(shè)Set集合中有了一個A對象,現(xiàn)在我要向Set集合再存入一個B對象,但B對象與A對象equals相等,則B對象存儲不進(jìn)去,所以,Set集合的add方法有一個boolean的返回值,當(dāng)集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true,當(dāng)集合含有與某個元素equals相等的元素時,此時add方法無法加入該元素,返回結(jié)果為false。Set取元素時,沒法說取第幾個,只能以Iterator接口取得所有的元素,再逐一遍歷各個元素。 List表示有先后順序的集合,注意,不是那種按年齡、按大小、按價格之類的排序。當(dāng)我們多次調(diào)用add(Obj e)方法時,每次加入的對象就像火車站買票有排隊順序一樣,按先來后到的順序排序。有時候,也可以插隊,即調(diào)用add(int index,Obj e)方法,就可以指定當(dāng)前對象在集合中的存放位置。一個對象可以被反復(fù)存儲進(jìn)List中,每調(diào)用一次add方法,這個對象就被插入進(jìn)集合中一次,其實,并不是把這個對象本身存儲進(jìn)了集合中,而是在集合中用一個索引變量指向這個對象,當(dāng)這個對象被add多次時,即相當(dāng)于集合中有多個索引指向了這個對象,如圖x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍歷各個元素之外,還可以調(diào)用get(index i)來明確說明取第幾個。 Map與List和Set不同,它是雙列的集合,其中有put方法,定義如下:put(obj key,obj value),每次存儲時,要存儲一對key/value,不能存儲重復(fù)的key,這個重復(fù)的規(guī)則也是按equals比較相等。取則可以根據(jù)key獲得相應(yīng)的value,即get(Object key)返回值為key 所對應(yīng)的value。另外,也可以獲得所有的key的結(jié)合,還可以獲得所有的value的結(jié)合,還可以獲得key和value組合成的Map.Entry對象的集合。 List 以特定次序來持有元素,可有重復(fù)元素。Set 無法擁有重復(fù)元素,內(nèi)部排序。Map 保存key-value值,value可多值。 HashSet按照hashcode值的某種運算方式進(jìn)行存儲,而不是直接按hashCode值的大小進(jìn)行存儲。例如,”abc“---> 78,”def“---> 62,”xyz“---> 65在hashSet中的存儲順序不是62,65,78,這些問題感謝以前一個叫崔健的學(xué)員提出,最后通過查看源代碼給他解釋清楚,看本次培訓(xùn)學(xué)員當(dāng)中有多少能看懂源碼。LinkedHashSet按插入的順序存儲,那被存儲對象的hashcode方法還有什么作用呢?學(xué)員想想!hashset集合比較兩個對象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new 兩個Student插入到HashSet中,看HashSet的size,實現(xiàn)hashcode和equals方法后再看size。 同一個對象可以在Vector中加入多次。往集合里面加元素,相當(dāng)于集合里用一根繩子連接到了目標(biāo)對象。往HashSet中卻加不了多次的。 64、說出ArrayList,Vector, LinkedList的存儲性能和特性 ArrayList和Vector都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素數(shù)大于實際存儲的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數(shù)組元素移動等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現(xiàn)存儲,按序號索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時只需要記錄本項的前后項即可,所以插入速度較快。 LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被當(dāng)作堆棧和隊列來使用。 65、去掉一個Vector集合中重復(fù)的元素 Vector newVector = new Vector();For(int i=0;i newVector.add(obj);} 還有一種簡單的方式,HashSet set = new HashSet(vector);66、Collection 和 Collections的區(qū)別。 Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.Collections是針對集合類的一個幫助類,他提供一系列靜態(tài)方法實現(xiàn)對各種集合的搜索、排序、線程安全化等操作。 67、Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢? 是用==還是equals()? 它們有何區(qū)別? Set里的元素是不能重復(fù)的,元素重復(fù)與否是使用equals()方法進(jìn)行判斷的。 equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當(dāng)兩個分離的對象的內(nèi)容和類型相配的話,返回真值。 68、你所知道的集合類都有哪些?主要方法? 最常用的集合類是 List 和 Map。List 的具體實現(xiàn)包括 ArrayList 和 Vector,它們是可變大小的列表,比較適合構(gòu)建、存儲和操作任何類型對象的元素列表。List 適用于按數(shù)值索引訪問元素的情形。 Map 提供了一個更通用的元素存儲方法。Map 集合類用于存儲元素對(稱作”鍵“和”值“),其中每個鍵映射到一個值。 ArrayList/Vector?List ?Collection HashSet/TreeSet?Set Propeties?HashTable ?Map Treemap/HashMap 我記的不是方法名,而是思想,我知道它們都有增刪改查的方法,但這些方法的具體名稱,我記得不是很清楚,對于set,大概的方法是add,remove, contains;對于map,大概的方法就是put,remove,contains等,因為,我只要在eclispe下按點操作符,很自然的這些方法就出來了。我記住的一些思想就是List類會有g(shù)et(int index)這樣的方法,因為它可以按順序取元素,而set類中沒有g(shù)et(int index)這樣的方法。List和set都可以迭代出所有元素,迭代時先要得到一個iterator對象,所以,set和list類都有一個iterator方法,用于返回那個iterator對象。map可以返回三個集合,一個是返回所有的key的集合,另外一個返回的是所有value的集合,再一個返回的key和value組合成的EntrySet對象的集合,map也有g(shù)et方法,參數(shù)是key,返回值是key對應(yīng)的value。 69、兩個對象值相同(x.equals(y)== true),但卻可有不同的hash code,這句話對不對? 對。 如果對象要保存在HashSet或HashMap中,它們的equals相等,那么,它們的hashcode值就必須相等。 如果不是要保存在HashSet或HashMap,則與hashcode沒有什么關(guān)系了,這時候hashcode不等是可以的,例如arrayList存儲的對象就不用實現(xiàn)hashcode,當(dāng)然,我們沒有理由不實現(xiàn),通常都會去實現(xiàn)的。 70、TreeSet里面放對象,如果同時放入了父類和子類的實例對象,那比較時使用的是父類的compareTo方法,還是使用的子類的compareTo方法,還是拋異常! (應(yīng)該是沒有針對問題的確切的答案,當(dāng)前的add方法放入的是哪個對象,就調(diào)用哪個對象的compareTo方法,至于這個compareTo方法怎么做,就看當(dāng)前這個對象的類中是如何編寫這個方法的)實驗代碼: public class Parent implements Comparable { } public class Child extends Parent { // TODO Auto-generated method stub public Child(){ } public int compareTo(Object o){ super(3);private int age = 0;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 } } System.out.println(”method of child“);Child o1 =(Child)o;return 1;// public class TreeSetTest { /** * @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());} 71、說出一些常用的類,包,接口,請各舉5個 要讓人家感覺你對java ee開發(fā)很熟,所以,不能僅僅只列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為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類? 字節(jié)流,字符流。字節(jié)流繼承于InputStream OutputStream,字符流繼承于InputStreamReader OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便。 73、字節(jié)流與字符流的區(qū)別 要把一片二進(jìn)制數(shù)據(jù)數(shù)據(jù)逐一輸出到某個設(shè)備中,或者從某個設(shè)備中逐一讀取一片二進(jìn)制數(shù)據(jù),不管輸入輸出設(shè)備是什么,我們要用統(tǒng)一的方式來完成這些操作,用一種抽象的方式進(jìn)行描述,這個抽象描述方式起名為IO流,對應(yīng)的抽象類為OutputStream和InputStream,不同的實現(xiàn)類就代表不同的輸入和輸出設(shè)備,它們都是針對字節(jié)進(jìn)行操作的。 在應(yīng)用中,經(jīng)常要完全是字符的一段文本輸出去或讀進(jìn)來,用字節(jié)流可以嗎?計算機(jī)中的一切最終都是二進(jìn)制的字節(jié)形式存在。對于“中國”這些字符,首先要得到其對應(yīng)的字節(jié),然后將字節(jié)寫入到輸出流。讀取時,首先讀到的是字節(jié),可是我們要把它顯示為字符,我們需要將字節(jié)轉(zhuǎn)換成字符。由于這樣的需求很廣泛,人家專門提供了字符流的包裝類。 底層設(shè)備永遠(yuǎn)只接受字節(jié)數(shù)據(jù),有時候要寫字符串到底層設(shè)備,需要將字符串轉(zhuǎn)成字節(jié)再進(jìn)行寫入。字符流是字節(jié)流的包裝,字符流則是直接接受字符串,它內(nèi)部將串轉(zhuǎn)成字節(jié),再寫入底層設(shè)備,這為我們向IO設(shè)別寫入或讀取字符串提供了一點點方便。 字符向字節(jié)轉(zhuǎn)換時,要注意編碼的問題,因為字符串轉(zhuǎn)成字節(jié)數(shù)組,其實是轉(zhuǎn)成該字符的某種編碼的字節(jié)形式,讀取也是反之的道理。 講解字節(jié)流與字符流關(guān)系的代碼案例: 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);*/ BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(”1.txt“),”UTF-8“));String myStr = br.readLine();br.close();System.out.println(myStr);74、什么是java序列化,如何實現(xiàn)java序列化?或者請解釋Serializable接口的作用。 我們有時候?qū)⒁粋€java對象變成字節(jié)流的形式傳出去或者從一個字節(jié)流中恢復(fù)成一個java對象,例如,要將java對象存儲到硬盤或者傳送給網(wǎng)絡(luò)上的其他計算機(jī),這個過程我們可以自己寫代碼去把一個java對象變成某個格式的字節(jié)流再傳輸,但是,jre本身就提供了這種支持,我們可以調(diào)用OutputStream的writeObject方法來做,如果要讓java 幫我們做,要被傳輸?shù)膶ο蟊仨殞崿F(xiàn)serializable接口,這樣,javac編譯時就會進(jìn)行特殊處理,編譯的類才可以被writeObject方法操作,這就是所謂的序列化。需要被序列化的類必須實現(xiàn)Serializable接口,該接口是一個mini接口,其中沒有需要實現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對象是可被序列化的。 例如,在web開發(fā)中,如果對象被保存在了Session中,tomcat在重啟時要把Session對象序列化到硬盤,這個對象就必須實現(xiàn)Serializable接口。如果對象要經(jīng)過分布式系統(tǒng)進(jìn)行網(wǎng)絡(luò)傳輸或通過rmi等遠(yuǎn)程調(diào)用,這就需要在網(wǎng)絡(luò)上傳輸對象,被傳輸?shù)膶ο缶捅仨殞崿F(xiàn)Serializable接口。75、描述一下JVM加載class文件的原理機(jī)制? JVM中類的裝載是由ClassLoader和它的子類來實現(xiàn)的,Java ClassLoader 是一個重要的Java運行時系統(tǒng)組件。它負(fù)責(zé)在運行時查找和裝入類文件的類。 76、heap和stack有什么區(qū)別。 java的內(nèi)存分為兩類,一類是棧內(nèi)存,一類是堆內(nèi)存。棧內(nèi)存是指程序進(jìn)入一個方法時,會為這個方法單獨分配一塊私屬存儲空間,用于存儲這個方法內(nèi)部的局部變量,當(dāng)這個方法結(jié)束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。 堆是與棧作用不同的內(nèi)存,一般用于存放不放在當(dāng)前方法棧中的那些數(shù)據(jù),例如,使用new創(chuàng)建的對象都放在堆里,所以,它不會隨方法的結(jié)束而消失。方法中的局部變量使用final修飾后,放在堆中,而不是棧中。 77、GC是什么? 為什么要有GC? GC是垃圾收集的意思(Gabage Collection),內(nèi)存處理是編程人員容易出現(xiàn)問題的地方,忘記或者錯誤的內(nèi)存回收會導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java提供的GC功能可以自動監(jiān)測對象是否超過作用域從而達(dá)到自動回收內(nèi)存的目的,Java語言沒有提供釋放已分配內(nèi)存的顯示操作方法。 78、垃圾回收的優(yōu)點和原理。并考慮2種回收機(jī)制。 Java語言中一個顯著的特點就是引入了垃圾回收機(jī)制,使c++程序員最頭疼的內(nèi)存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候不再需要考慮內(nèi)存管理。由于有個垃圾回收機(jī)制,Java中的對象不再有”作用域“的概念,只有對象的引用才有”作用域“。垃圾回收可以有效的防止內(nèi)存泄露,有效的使用可以使用的內(nèi)存。垃圾回收器通常是作為一個單獨的低級別的線程運行,不可預(yù)知的情況下對內(nèi)存堆中已經(jīng)死亡的或者長時間沒有使用的對象進(jìn)行清楚和回收,程序員不能實時的調(diào)用垃圾回收器對某個對象或所有對象進(jìn)行垃圾回收?;厥諜C(jī)制有分代復(fù)制垃圾回收和標(biāo)記垃圾回收,增量垃圾回收。 79、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內(nèi)存嗎?有什么辦法主動通知虛擬機(jī)進(jìn)行垃圾回收? 對于GC來說,當(dāng)程序員創(chuàng)建對象時,GC就開始監(jiān)控這個對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是”可達(dá)的“,哪些對象是”不可達(dá)的“。當(dāng)GC確定一些對象為”不可達(dá)“時,GC就有責(zé)任回收這些內(nèi)存空間??梢浴3绦騿T可以手動執(zhí)行System.gc(),通知GC運行,但是Java語言規(guī)范并不保證GC一定會執(zhí)行。 80、什么時候用assert。 assertion(斷言)在軟件開發(fā)中是一種常用的調(diào)試方式,很多開發(fā)語言中都支持這種機(jī)制。在實現(xiàn)中,assertion就是在程序中的一條語句,它對一個boolean表達(dá)式進(jìn)行檢查,一個正確程序必須保證這個boolean表達(dá)式的值為true;如果該值為false,說明程序已經(jīng)處于不正確的狀態(tài)下,assert將給出警告或退出。一般來說,assertion用于保證程序最基本、關(guān)鍵的正確性。assertion檢查通常在開發(fā)和測試時開啟。為了提高性能,在軟件發(fā)布后,assertion檢查通常是關(guān)閉的。 package com.huawei.interview; public class AssertTest { } /** * @param args */ public static void main(String[] args){ } // TODO Auto-generated method stub int i = 0;for(i=0;i<5;i++){ } //假設(shè)程序不小心多了一句--i;--i;assert i==5; System.out.println(i); 81、java中會存在內(nèi)存泄漏嗎,請簡單描述。 所謂內(nèi)存泄露就是指一個不再被程序使用的對象或變量一直被占據(jù)在內(nèi)存中。java中有垃圾回收機(jī)制,它可以保證一對象不再被引用的時候,即對象編程了孤兒的時候,對象將自動被垃圾回收器從內(nèi)存中清除掉。由于Java 使用有向圖的方式進(jìn)行垃圾回收管理,可以消除引用循環(huán)的問題,例如有兩個對象,相互引用,只要它們和根進(jìn)程不可達(dá)的,那么GC也是可以回收它們的,例如下面的代碼可以看到這種情況的內(nèi)存回收: package com.huawei.interview; import java.io.IOException; public class GarbageTest { 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(); Person p2 = new Person(); Person p1 = new Person();/** * @param args * @throws IOException */ public static void main(String[] args)throws IOException { } // TODO Auto-generated method stub try { } System.out.println(”has exited gcTest!“);System.in.read();System.in.read(); System.out.println(”out begin gc!“);for(int i=0;i<100;i++){ } System.gc();System.in.read();System.in.read();gcTest();// TODO Auto-generated catch block e.printStackTrace();} catch(IOException e){ } } System.out.println(”exit gctest!");private static class Person { } byte[] data = new byte[20000000];Person mate = null;public void setMate(Person other){ } mate = other; java中的內(nèi)存泄露的情況:長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內(nèi)存泄露,盡管短生命周期對象已經(jīng)不再需要,但是因為長生命周期對象持有它的引用而導(dǎo)致不能被回收,這就是java中內(nèi)存泄露的發(fā)生場景,通俗地說,就是程序員可能創(chuàng)建了一個對象,以后一直不再使用這個對象,這個對象卻一直被引用,即這個對象無用但是卻無法被垃圾回收器回收的,這就是java中可能出現(xiàn)內(nèi)存泄露的情況,例如,緩存系統(tǒng),我們加載了一個對象放在緩存中(例如放在一個全局map對象中),然后一直不再使用它,這個對象一直被緩存引用,但卻不再被使用。 檢查java中的內(nèi)存泄露,一定要讓程序?qū)⒏鞣N分支情況都完整執(zhí)行到程序結(jié)束,然后看某個對象是否被使用過,如果沒有,則才能判定這個對象屬于內(nèi)存泄露。 如果一個外部類的實例對象的方法返回了一個內(nèi)部類的實例對象,這個內(nèi)部類對象被長期引用了,即使那個外部類實例對象不再被使用,但由于內(nèi)部類持久外部類的實例對象,這個外部類對象將不會被垃圾回收,這也會造成內(nèi)存泄露。 下面內(nèi)容來自于網(wǎng)上(主要特點就是清空堆棧中的某個元素,并不是徹底把它從數(shù)組中拿掉,而是把存儲的總數(shù)減少,本人寫得可以比這個好,在拿掉某個元素時,順便也讓它從數(shù)組中消失,將那個元素所在的位置的值設(shè)置為null即可): 我實在想不到比那個堆棧更經(jīng)典的例子了,以致于我還要引用別人的例子,下面的例子不是我想到的,是書上看到的,當(dāng)然如果沒有在書上看到,可能過一段時間我自己也想的到,可是那時我說是我自己想到的也沒有人相信的。 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); } } } 上面的原理應(yīng)該很簡單,假如堆棧加了10個元素,然后全部彈出來,雖然堆棧是空的,沒有我們要的東西,但是這是個對象是無法回收的,這個才符合了內(nèi)存泄露的兩個條件:無用,無法回收。 但是就是存在這樣的東西也不一定會導(dǎo)致什么樣的后果,如果這個堆棧用的比較少,也就浪費了幾個K內(nèi)存而已,反正我們的內(nèi)存都上G了,哪里會有什么影響,再說這個東西很快就會被回收的,有什么關(guān)系。下面看兩個例子。 例子1 public class Bad{ public static Stack s=Stack(); static{ s.push(new Object()); s.pop();//這里有一個對象發(fā)生內(nèi)存泄露 s.push(new Object());//上面的對象可以被回收了,等于是自愈了 } } 因為是static,就一直存在到程序退出,但是我們也可以看到它有自愈功能,就是說如果你的Stack最多有100個對象,那么最多也就只有100個對象無法被回收其實這個應(yīng)該很容易理解,Stack內(nèi)部持有100個引用,最壞的情況就是他們都是無用的,因為我們一旦放新的進(jìn)取,以前的引用自然消失! 內(nèi)存泄露的另外一種情況:當(dāng)一個對象被存儲進(jìn)HashSet集合中以后,就不能修改這個對象中的那些參與計算哈希值的字段了,否則,對象修改后的哈希值與最初存儲進(jìn)HashSet集合中時的哈希值就不同了,在這種情況下,即使在contains方法使用該對象的當(dāng)前引用作為的參數(shù)去HashSet集合中檢索對象,也將返回找不到對象的結(jié)果,這也會導(dǎo)致無法從HashSet集合中單獨刪除當(dāng)前對象,造成內(nèi)存泄露。