1、面向對象的特徵有哪些方面?html
封裝:一般認爲封裝是把數據和操做數據的方法綁定起來,對數據的訪問只能經過已定義的接口。前端
多態性:多態性是指容許不一樣子類型的對象對同一消息做出不一樣的響應。簡單的說就是用一樣的對象引用調用一樣的方法可是作了不一樣的事情。多態性分爲編譯時的多態性和運行時的多態性。方法重載(overload)實現的是編譯時的多態性(也稱爲前綁定),而方法重寫(override)實現的是運行時的多態性(也稱爲後綁定)。java
2、訪問修飾符public,private,protected,以及不寫(默認)時的區別?node
做用域 當前類 同包 子類 其餘mysql
public √ √ √ √jquery
protected √ √ √ ×linux
default √ √ × ×nginx
private √ × × ×程序員
類的成員不寫訪問修飾時默認爲default。默認對於同一個包中的其餘類至關於公開 (public),對於不是同一個包中的其餘類至關於私有(private)。受保護 (protected)對子類至關於公開,對不是同一包中的沒有父子關係的類至關於私有。web
3、構造器(constructor)是否可被重寫(override)?
答:構造器不能被繼承,所以不能被重寫,但能夠被重載。
4、兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不對?
答:不對,若是兩個對象x和y知足x.equals(y) == true,它們的哈希碼(hash code)應當相同。Java對於eqauls方法和hashCode方法是這樣規定的:(1)若是兩個對象相同(equals方法返回true),那麼它們的hashCode值必定要相同;(2)若是兩個對象的hashCode相同,它們並不必定相同。
5、抽象類(abstract class)和接口(interface)有什麼異同?
答:抽象類和接口都不可以實例化,但能夠定義抽象類和接口類型的引用。一個類若是繼承了某個抽象類或者實現了某個接口都須要對其中的抽象方法所有進 行實現,不然該類仍然須要被聲明爲抽象類。接口比抽象類更加抽象,由於抽象類中能夠定義構造器,能夠有抽象方法和具體方法,而接口中不能定義構造器並且其 中的方法所有都是抽象方法。抽象類中的成員能夠是private、默認、protected、public的,而接口中的成員全都是public的。抽象 類中能夠定義成員變量,而接口中定義的成員變量實際上都是常量。有抽象方法的類必須被聲明爲抽象類,而抽象類未必要有抽象方法。抽象類和接口中均可以包含靜態成員變量。
6、抽象的(abstract)方法是否可同時是靜態的(static),是否可同時是本地方法(native),是否可同時被synchronized修飾?
答:都不能。抽象方法須要子類重寫,而靜態的方法是沒法被重寫的,所以兩者是矛盾的。本地方法是由本地代碼(如C代碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。synchronized和方法的實現細節有關,抽象方法不涉及實現細節,所以也是相互矛盾的。
7、接口是否可繼承(extends)接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)?
答:接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類可繼承具體類,但前提是具體類必須有明確的構造函數。
8、Anonymous Inner Class(匿名內部類)是否能夠繼承其它類?是否能夠實現接口?
答:能夠繼承其餘類或實現其餘接口,在Swing編程中經常使用此方式來實現事件監聽和回調。
9、數據類型之間的轉換:
1)如何將字符串轉換爲基本數據類型?
2)如何將基本數據類型轉換爲字符串?
1)調用基本數據類型對應的包裝類中的方法parseXXX(String)或valueOf(String)便可返回相應基本類型; Integer.parseInt(a) Integer.valueOf(a)
2)一種方法是將基本數據類型與空字符串(」」)鏈接(+)便可得到其所對應的字符串;另外一種方法是調用String 類中的valueOf(…)方法返回相應字符串 String.valueOf(int) Integer.toString
10、如何實現字符串的反轉及替換?
答:方法不少,能夠本身寫實現也能夠使用String或StringBuffer / StringBuilder中的方法。有一道很常見的面試題是用遞歸實現字符串反轉,代碼以下所示:
[java] view plain copy
1.public static String reverse(String originStr) {
1. 2. if(originStr == null || originStr.length() <= 1)
2. 3. return originStr;
3. 4. return reverse(originStr.substring(1)) + originStr.charAt(0);
4. 5. }
11、列出一些你常見的運行時異常?
答:
ArithmeticException(算術異常)
ClassCastException (類轉換異常)
IllegalArgumentException (非法參數異常)
IndexOutOfBoundsException (下表越界異常)
NullPointerException (空指針異常)
SecurityException (安全異常)
12、List、Map、Set三個接口存取元素時,各有什麼特色?
答:List以特定索引來存取元素,能夠有重複元素。Set不能存放重複元素(用對象的equals()方法來區分元素是否重複)。Map保存鍵值對 (key-value pair)映射,映射關係能夠是一對一或多對一。Set和Map容器都有基於哈希存儲和排序樹的兩種實現版本,基於哈希存儲的版本理論存取時間複雜度爲 O(1),而基於排序樹版本的實如今插入或刪除元素時會按照元素或元素的鍵(key)構成排序樹從而達到排序和去重的效果。
13、什麼是進程,什麼是線程?爲何須要多線程編程?
進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,是操做系統進行資源分配和調度的一個獨立單位;
線程是進程的一個實體,是CPU調度和分 派的基本單位,是比進程更小的能獨立運行的基本單位。
線程的劃分尺度小於進程,這使得多線程程序的併發性高;進程在執行時一般擁有獨立的內存單元,而線程之間能夠共享內存。使用多線程的編程一般可以帶來更好的性能和用戶體驗,可是多線程的程序對於其餘程序是不友好的,由於它佔用了更多的CPU資源。
14.闡述JDBC操做數據庫的步驟
答:下面的代碼以鏈接本機的Oracle數據庫爲例,演示JDBC操做數據庫的步驟。
1. 加載驅動。
[java] view plain copy
Class.forName("oracle.jdbc.driver.OracleDriver");
2. 建立鏈接。
[java] view plain copy
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");
3. 建立語句。
[java] view plain copy
PreparedStatement ps = con.prepareStatement("select * from emp where sal between ? and ?");
ps.setInt(1, 1000);
ps.setInt(2, 3000);
4. 執行語句。
[java] view plain copy
ResultSet rs = ps.executeQuery();
5. 處理結果。
[java] view plain copy
while(rs.next()) {
System.out.println(rs.getInt("empno") + " - " + rs.getString("ename")); }
6. 關閉資源。
[java] view plain copy
finally {
if(con != null) {
try {
con.close();
} catch (SQLException e) { e.printStackTrace();
}
}
}
15.Statement和PreparedStatement有什麼區別?哪一個性能更好?
與Statement相比
①PreparedStatement接口表明預編譯的語句,它主要的優點在於能夠減小SQL的編譯錯誤並增長SQL的安全性(減小SQL注射攻擊的可能性)
②PreparedStatement中的SQL語句是能夠帶參數的,避免了用字符串鏈接拼接SQL語句的麻煩和不安全;
③當批量處理SQL或頻繁執行相同的查詢時,PreparedStatement有明顯的性能上的優點,因爲數據庫能夠將編譯優化後的SQL語句緩存起來,下次執行相同結構的語句時就會很快(不用再次編譯和生成執行計劃)。
16、在進行數據庫編程時,鏈接池有什麼做用?
因爲建立鏈接和釋放鏈接都有很大的開銷(尤爲是數據庫服務器不在本地時,每次創建鏈接都須要進行TCP的三次握手,釋放鏈接須要進行TCP四次握手,形成的開銷是不可忽視的),爲了提高系統訪問數據庫的性能,能夠事先建立若干鏈接置於鏈接池中,須要時直接從鏈接池獲取,使用結束時歸還鏈接池而沒必要關閉鏈接,從而避免頻繁建立和釋放鏈接所形成的開銷,這是典型的用空間換取時間的策略(浪費了空間存儲鏈接,但節省了建立和釋放鏈接的時間)。池化技術在Java開發中是很常見的,在使用線程時建立線程池的道理與此相同。
17、Java中是如何支持正則表達式操做的?
答:Java中的String類提供了支持正則表達式操做的方法,包括:matches()、replaceAll()、replaceFirst()、split()。此外,Java中能夠用Pattern類表示正則表達式對象,它提供了豐富的API進行各類正則表達式操做,請參考下面面試題的代碼。
面試題: - 若是要從字符串中截取第一個英文左括號以前的字符串,例如:北京市(朝陽區)(西城區)(海淀區),截取結果爲:北京市,那麼正則表達式怎麼寫?
[java] view plain copy
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class RegExpTest {
public static void main(String[] args){
String str = "北京市(朝陽區)(西城區)(海淀區)";
Pattern p = Pattern.compile(".*?(?=\\()");
Matcher m = p.matcher(str);
if(m.find()) {
System.out.println(m.group()); }
}
}
18、得到一個類的類對象有哪些方式? 反射
答:
- 方法1:類型.class,例如:String.class
- 方法2:對象.getClass(),例如:"hello".getClass()
- 方法3:Class.forName(),例如:Class.forName("java.lang.String")
19、如何經過反射建立對象?
答:
- 方法1:經過類對象調用newInstance()方法,例如:String.class.newInstance()
- 方法2:經過類對象的getConstructor()或getDeclaredConstructor()方法得到構造器(Constructor)對象並調用其newInstance()方法建立對象,例如:String.class.getConstructor(String.class).newInstance("Hello");
20、如何經過反射調用對象的方法?
答:請看下面的代碼:
[java] view plain copy
import java.lang.reflect.Method;
class MethodInvokeTest {
public static void main(String[] args) throws Exception {
String str = "hello";
Method m = str.getClass().getMethod("toUpperCase");
System.out.println(m.invoke(str));
// HELLO
}
}
=-22.簡述一下你瞭解的設計模式
-工廠模式:工廠類能夠根據條件生成不一樣的子類實例,這些子類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做(多態方法)。當獲得子類的實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例。
- 代理模式:給一個對象提供一個代理對象,並由代理對象控制原對象的引用。0.實際開發中,按照使用目的的不一樣,代理能夠分爲:遠程代理、虛擬代理、保護代理、Cache代理、防火牆代理、同步化代理、智能引用代理。
- 適配器模式:把一個類的接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒使用的類可以一塊兒工做。
- 模板方法模式:提供一個抽象類,將部分邏輯以具體方法或構造器的形式實現,而後聲明一些抽象方法來迫使子類實現剩餘的邏輯。不一樣的子類能夠以不一樣的方式實現這些抽象方法(多態實現),從而實現不一樣的業務邏輯。
23、用Java寫一個單例類。
餓漢式單例
[java] view plain copy
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance(){ return instance;
}
}
懶漢式單例
[java] view plain copy
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static synchronized Singleton getInstance(){
if (instance == null)
instance = new Singleton();
return instance;
}
}
注意:實現一個單例有兩點注意事項,①將構造器私有,不容許外界經過構造器建立對象;②經過公開的靜態方法向外界返回類的惟一實例。這裏有一個問題能夠思考:spring的IoC容器能夠爲普通的類建立單例,它是怎麼作到的呢?
24.什麼是DAO模式?
答:DAO(DataAccess Object)顧名思義是一個爲數據庫或其餘持久化機制提供了抽象接口的對象,在不暴露數據庫實現細節的前提下提供了各類數據操做。將全部對數據源的訪問操做進行抽象化後封裝在一個公共API中。在這個應用程序中,當須要和數據源進行交互的時候則使用這個接口,而且編寫一個單獨的類來實現這個接口,在邏輯上該類對應一個特定的數據存儲。DAO模式實際上包含了兩個模式,一是Data Accessor(數據訪問器),二是Data Object(數據對象),前者要解決如何訪問數據的問題,然後者要解決的是如何用對象封裝數據。
25.Servlet的生命週期
Web容器加載Servlet並將其實例化後,Servlet生命週期開始,容器運行其init()方法進行Servlet的初始化;請求到達時調用Servlet的service方法,service方法會調用與請求對應的doGet或doPost等方法;當服務器關閉會項目被卸載時服務器會將Servlet實例銷燬,此時會調用Servlet的destroy方法。
26.轉發(forward)和重定向(redirect)的區別?
1)forward是容器中控制權的轉向,是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL 的響應內容讀取過來,而後把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,因此它的地址欄中仍是原來的地址。
2)redirect就是服務器端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,所以從瀏覽器的地址欄中能夠看到跳轉後的連接地址。
3)前者更加高效,在前者能夠知足須要時,儘可能使用轉發(經過RequestDispatcher對象的forward方法,RequestDispatcher對象能夠經過ServletRequest對象的getRequestDispatcher方法得到),而且,這樣也有助於隱藏實際的連接;在有些狀況下,好比,須要跳轉到一個其它服務器上的資源,則必須使用重定向(經過HttpServletResponse對象調用其sendRedirect方法)。
27.get和post請求的區別?
①get請求用來從服務器上得到資源,而post是用來向服務器提交數據;
②get將表單中數據按照name=value的形式,添加到action 所指向的URL 後面,而且二者使用「?」鏈接,而各個變量之間使用「&」鏈接;post是將表單中的數據放在HTML頭部(header),傳遞到action所指向URL;
③get傳輸的數據要受到URL長度限制(1024字節);而post能夠傳輸大量的數據,上傳文件只能使用post方式;
④使用get時參數會顯示在地址欄上,若是這些數據不是敏感數據,那麼能夠使用get;對於敏感數據仍是應用使用post;
28、JSP 和Servlet 有有什麼關係?
答:其實這個問題在上面已經闡述過了,Servlet是一個特殊的Java程序,它運行於服務器的JVM中,可以依靠服務器的支持向瀏覽器提供顯示內容。
JSP本質上是Servlet的一種簡易形式, JSP會被服務器處理成一個相似於Servlet的Java程序,能夠簡化頁面內容的生成。
Servlet和JSP最主要的不一樣點在於,Servlet 的應用邏輯是在Java 文件中,而且徹底從表示層中的HTML分離開來。而JSP的狀況是Java和HTML能夠組合成一個擴展名爲.jsp 的文件(有人說,Servlet就是在Java中寫HTML,而JSP就是在HTML中寫Java代碼,固然,這個說法仍是很片面的)。
JSP側重於視圖,Servlet更側重於控制邏輯,在MVC架構模式中,JSP適合充當視圖(view)而Servlet適合充當控制器(controller)。
29、JSP中的四種做用域?
答:page、request、session和application,具體以下:
①page 表明與一個頁面相關的對象和屬性。
②request 表明與Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web 組件;須要在頁面顯示的臨時數據能夠置於此做用域
③session表明與某個用戶與服務器創建的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶本身的session中
④application表明與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局做用域。
30.實現會話跟蹤的技術有哪些?
答:因爲HTTP協議自己是無狀態的,服務器爲了區分不一樣的用戶,就須要對用戶會話進行跟蹤,簡單的說就是爲用戶進行登記,爲用戶分配惟一的ID,下一次用戶在請求中包含此ID,服務器據此判斷究竟是哪個用戶。
①URL 重寫:在URL中添加用戶會話的信息做爲請求的參數,或者將惟一的會話ID添加到URL結尾以標識一個會話。
②設置表單隱藏域:將和會話跟蹤相關的字段添加到隱式表單域中,這些信息不會在瀏覽器中顯示可是提交表單時會提交給服務器。
③cookie:cookie當用戶經過瀏覽器和服務器創建一次會話後,會話ID就會隨響應信息返回存儲在基於窗口的cookie中,那就意味着只要瀏覽器沒有關閉,會話沒有超時,下一次請求時這個會話ID又會提交給服務器讓服務器識別用戶身份。會話中能夠爲用戶保存信息。會話對象是在服務器內存中的,而基於窗口的cookie是在客戶端內存中的。
④HttpSession:在全部會話跟蹤技術中,HttpSession對象是最強大也是功能最多的。當一個用戶第一次訪問某個網站時會自動建立HttpSession,每一個用戶能夠訪問他本身的HttpSession。與上面三種方式不一樣的是,HttpSession放在服務器的內存中
31.JSP中的靜態包含和動態包含有什麼區別?
答:靜態包含是經過JSP的include指令包含頁面,動態包含是經過JSP標準動做<jsp:forward>包含頁面。靜態包含是編譯時包含,若是包含的頁面不存在則會產生編譯錯誤,並且兩個頁面的"contentType"屬性應保持一致,由於兩個頁面會合二爲一,只產生一個class文件,所以被包含頁面發生的變更再包含它的頁面更新前不會獲得更新。動態包含是運行時包含,能夠向被包含的頁面傳遞參數,包含頁面和被包含頁面是獨立的,會編譯出兩個class文件,若是被包含的頁面不存在,不會產生編譯錯誤,也不影響頁面其餘部分的執行。代碼以下所示:
<%-- 靜態包含 --%><%@ include file="..." %> <%-- 動態包含 --%><jsp:include page="..."> <jsp:param name="..." value="..." /></jsp:include>
32、什麼是Web Service(Web服務)?
答:從表面上看,Web Service就是一個應用程序,它向外界暴露出一個可以經過Web進行調用的API。例如能夠建立一個提供天氣預報的Web Service,那麼不管你用哪一種編程語言開發的應用均可以經過調用它的API並傳入城市信息來得到該城市的天氣預報。
補充:這裏必需要說起的一個概念是SOA(Service-Oriented Architecture,面向服務的架構)顯然,Web Service是SOA的一種較好的解決方案,它更多的是一種標準,而不是一種具體的技術。
33、hashmap和hashtable區別
1.hashMap去掉了HashTable 的contains方法,可是加上了containsValue()和containsKey()方法。
2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
3.hashMap容許空鍵值,而hashTable不容許。
34、Socket的通訊機制?
套接字(socket)是通訊的基石,是支持TCP/IP協議的網絡通訊的基本操做單元。它是網絡通訊過程當中端點的抽象表示,包含進行網絡通訊必須的五種信息:鏈接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。
應用層經過傳輸層進行數據通訊時,TCP會遇到同時爲多個應用程序進程提供併發服務的問題。多個TCP鏈接或多個應用程序進程可能須要經過同一個
TCP協議端口傳輸數據。爲了區別不一樣的應用程序進程和鏈接,許多計算機操做系統爲應用程序與TCP/IP協議交互提供了套接字(Socket)接口。應用層能夠和傳輸層經過Socket接口,區分來自不一樣應用程序進程或網絡鏈接的通訊,實現數據傳輸的併發服務。
創建Socket鏈接至少須要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另外一個運行於服務器端,稱爲ServerSocket 。
套接字之間的鏈接過程分爲三個步驟:服務器監聽,客戶端請求,鏈接確認。
服務器監聽:服務器端套接字並不定位具體的客戶端套接字,而是處於等待鏈接的狀態,實時監控網絡狀態,等待客戶端的鏈接請求。
客戶端請求:指客戶端的套接字提出鏈接請求,要鏈接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要鏈接的服務器的套接字,指出服務器端套接字的地址和端口號,而後就向服務器端套接字提出鏈接請求。
鏈接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的鏈接請求時,就響應客戶端套接字的請求,創建一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式創建鏈接。而服務器端套接字繼續處於監聽狀態,繼續接收其餘客戶端套接字的鏈接請求。
35、Http的通訊機制?
HTTP協議即超文本傳送協議(Hypertext Transfer Protocol
),是Web聯網的基礎,也是手機聯網經常使用的協議之一,HTTP協議是創建在TCP協議之上的一種應用。
HTTP鏈接最顯著的特色是客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接。從創建鏈接到關閉鏈接的過程稱爲「一次鏈接」。
1)在HTTP 1.0中,客戶端的每次請求都要求創建一次單獨的鏈接,在處理完本次請求後,就自動釋放鏈接。
2)在HTTP
1.1中則能夠在一次鏈接中處理多個請求,而且多個請求能夠重疊進行,不須要等待一個請求結束後再發送下一個請求。
因爲HTTP在每次請求結束後都會主動釋放鏈接,所以HTTP鏈接是一種「短鏈接」,要保持客戶端程序的在線狀態,須要不斷地向服務器發起鏈接請求。一般的作法是即時不須要得到任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次「保持鏈接」的請求,服務器在收到該請求後對客戶端進行回覆,代表知道客戶端「在線」。若服務器長時間沒法收到客戶端的請求,則認爲客戶端「下線」,若客戶端長時間沒法收到服務器的回覆,則認爲網絡已經斷開。
因爲一般狀況下Socket鏈接就是TCP鏈接,所以Socket鏈接一旦創建,通訊雙方便可開始相互發送數據內容,直到雙方鏈接斷開。但在實際網絡應用中,客戶端到服務器之間的通訊每每須要穿越多箇中間節點,例如路由器、網關、防火牆等,大部分防火牆默認會關閉長時間處於非活躍狀態的鏈接而致使
Socket 鏈接斷連,所以須要經過輪詢告訴網絡,該鏈接處於活躍狀態。
而HTTP鏈接使用的是「請求—響應」的方式,不只在請求時須要先創建鏈接,並且須要客戶端向服務器發出請求後,服務器端才能回覆數據。
不少狀況下,須要服務器端主動向客戶端推送數據,保持客戶端與服務器數據的實時與同步。此時若雙方創建的是Socket鏈接,服務器就能夠直接將數據傳送給客戶端;若雙方創建的是HTTP鏈接,則服務器須要等到客戶端發送一次請求後才能將數據傳回給客戶端,所以,客戶端定時向服務器端發送鏈接請求,不只能夠保持在線,同時也是在「詢問」服務器是否有新的數據,若是有就將數據傳給客戶端。
36、HttpServlet容器響應Web客戶請求流程?
1)Web客戶向Servlet容器發出Http請求;
2)Servlet容器解析Web客戶的Http請求;
3)Servlet容器建立一個HttpRequest對象,在這個對象中封裝Http請求信息;
4)Servlet容器建立一個HttpResponse對象;
5)Servlet容器調用HttpServlet的service方法,這個方法中會根據request的Method來判斷具體是執行doGet仍是doPost,把HttpRequest和HttpResponse對象做爲service方法的參數傳給HttpServlet對象;
6)HttpServlet調用HttpRequest的有關方法,獲取HTTP請求信息;
7)HttpServlet調用HttpResponse的有關方法,生成響應數據;
8)Servlet容器把HttpServlet的響應結果傳給Web客戶
37、hibernate中Session的load和get方法的區別是什麼?
答:主要有如下三項區別:
① 若是沒有找到符合條件的記錄,get方法返回null,load方法拋出異常。
② get方法直接返回實體類對象,load方法返回實體類對象的代理。
③ 在Hibernate 3以前,get方法只在一級緩存中進行數據查找,若是沒有找到對應的數據則越過二級緩存,直接發出SQL語句完成數據讀取;load方法則能夠從二級緩存中獲取數據;從Hibernate 3開始,get方法再也不是對二級緩存只寫不讀,它也是能夠訪問二級緩存的。
說明:對於load()方法Hibernate認爲該數據在數據庫中必定存在能夠放心的使用代理來實現延遲加載,若是沒有數據就拋出異常,而經過get()方法獲取的數據能夠不存在。
38、如何理解Hibernate的延遲加載機制
答:延遲加載就是並非在讀取的時候就把數據加載進來,而是等到使用時再加載。Hibernate使用了虛擬代理機制實現延遲加載。返回給用戶的並非實體自己,而是實體對象的代理。代理對象在用戶調用getter方法時就會去數據庫加載數據。
39、簡述Hibernate常見優化策略。
①制定合理的緩存策略
② 採用合理的Session管理機制
③ 儘可能使用延遲加載特性
④若是能夠, 選用基於version的樂觀鎖替代悲觀鎖
⑤在開發過程當中, 開啓hibernate.show_sql選項查看生成的SQL, 從而瞭解底層的情況;開發完成後關閉此選項
40、什麼是IoC和DI?DI是如何實現的?
答:IoC叫控制反轉,是Inversion of Control的縮寫,控制反轉是把傳統上由程序代碼直接操控的對象的調用權交給容器,經過容器來實現對象組件的裝配和管理。所謂的"控制反轉"就是對組件對象控制權的轉移,從程序代碼自己轉移到了外部容器,由容器來建立對象並管理對象之間的依賴關係。
控制反轉——Spring經過一種稱做控制反轉(IoC)的技術促進了鬆耦合。當應用了IoC,一個對象依賴的其它對象會經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象,是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。經過IOC反轉控制DI依賴注入完成各個層之間的注入,使得層與層之間實現徹底脫耦,增長運行效率利於維護。
41、解釋一下什麼叫AOP(面向切面編程)?
答:
spring的AOP面向切面編程,實如今不改變代碼的狀況下完成對方法的加強。比較經常使用的就是spring的聲明式事務管理,底層經過AOP實現,避免了咱們每次都要手動開啓事物,提交事務的重複性代碼,使得開發邏輯更加清晰。
簡單點解釋,比方說你想在你的service層全部類中都加上一個打印‘你好’的功能這你經能夠用aop思想來作,你先寫個類寫個方法,方法經實現打印‘你好’而後你Ioc這個類 ref=「service.*」讓每一個類都注入。
aop就是面向切面的編程。好比說你每作一次對數據庫操做,都要生成一句日誌。若是,你對數據庫的操做有不少類,那你每一類中都要寫關於日誌的方法。可是若是你用aop,那麼你能夠寫一個方法,在這個方法中有關於數據庫操做的方法,每一次調用這個方法的時候,就加上生成日誌的操做。
42、選擇使用Spring框架的緣由(Spring框架爲企業級開發帶來的好處)?
答:能夠從如下幾個方面做答:
1. IoC容器:IoC容器幫助應用程序管理對象以及對象之間的依賴關係,對象之間的依賴關係若是發生了改變只須要修改配置文件而不是修改代碼,由於代碼的修改可能意味着項目的從新構建和完整的迴歸測試。有了IoC容器,程序員不再須要本身編寫工廠、單例,這一點特別符合Spring的精神「不要重複的發明輪子」。
2. AOP:面向切面編程,將全部的橫切關注功能封裝到切面(aspect)中,經過配置的方式將橫切關注功能動態添加到目標代碼上,進一步實現了業務邏輯和系統服務之間的分離。另外一方面,有了AOP程序員能夠省去不少本身寫代理類的工做。
3. MVC:Spring的MVC框架是很是優秀的,從各個方面均可以甩Struts 2幾條街,爲Web表示層提供了更好的解決方案。
4. 事務管理:Spring以寬廣的胸懷接納多種持久層技術,而且爲其提供了聲明式的事務管理,在不須要任何一行代碼的狀況下就可以完成事務管理。
43、 簡述攔截器的工做原理以及你在項目中使用過哪些自定義攔截器
答:Struts 2中定義了攔截器的接口以及默認實現,實現了Interceptor接口或繼承了AbstractInterceptor的類能夠做爲攔截器。接口中的init()方法在攔截器被建立後當即被調用,它在攔截器的生命週期內只被調用一次,能夠在該方法中對相關資源進行必要的初始化。每攔截一個請求,intercept()方法就會被調用一次。destory()方法將在攔截器被銷燬以前被調用, 它在攔截器的生命週期內也只被調用一次。
項目中使用過的有權限攔截器、執行時間攔截器、令牌攔截器等。
44、談一下攔截器和過濾器的區別
答:攔截器和過濾器均可以用來實現橫切關注功能,其區別主要在於:
1、攔截器是基於java反射機制的,而過濾器是基於函數回調的。
2、過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
3、攔截器只能對Action請求起做用,而過濾器則能夠對幾乎全部請求起做用。
4、攔截器能夠訪問Action上下文、值棧裏的對象,而過濾器不能。
5、在Action的生命週期中,攔截器能夠屢次調用,而過濾器只能在容器初始化時被調用一次。
過濾器,是在java web中,你傳入的request,response提早過濾掉一些信息,或者提早設置一些參數,而後再傳入servlet或者struts的 action進行業務邏輯,好比過濾掉非法url(不是login.do的地址請求,若是用戶沒有登錄都過濾掉),或者在傳入servlet或者struts的action前統一設置字符集,或者去除掉一些非法字符.
攔截器,是在面向切面編程的就是在你的service或者一個方法,前調用一個方法,或者在方法後調用一個方法好比動態代理就是攔截器的簡單實現,在你調用方法前打印出字符串(或者作其它業務邏輯的操做),也能夠在你調用方法後打印出字符串,甚至在你拋出異常的時候作業務邏輯的操做。
執行順序:過濾前 - 攔截前 - Action處理 - 攔截後 - 過濾後。
我的認爲過濾是一個橫向的過程,首先把客戶端提交的內容進行過濾(例如未登陸用戶不能訪問內部頁面的處理);過濾經過後,攔截器將檢查用戶提交數據的驗證,作一些前期的數據處理,接着把處理後的數據發給對應的Action;Action處理完成返回後,攔截器還能夠作其餘過程(還沒想到要作啥),再向上返回到過濾器的後續操做。
45、struts1.2和struts2.0的區別?
struts1.2和struts2.0的對比
a、Action類:
struts1.2要求Action類繼承一個基類。struts2.0 Action要求繼承ActionSupport基類
b、線程模式
struts1.2 Action是單例模式的而且必須是線程安全的有線程安全問題,由於僅有一個Action的實例來處理全部的請求。 struts2.0 Action爲每個請求產生一個實例,所以沒有線程安全問題。
c、Servlet依賴
struts1.2 Action依賴於Servlet API,由於當一個Action被調用時HttpServletRequest和HttpServletResponse被傳遞給execut方法。 struts2.0 Action不依賴於容器,容許Action脫離容器單獨測試。
46、常見的網絡協議有哪些?
1.IP協議:互聯網協議
主要用於負責IP尋址、路由選擇和IP數據包的分割和組裝。一般咱們所說的IP地址能夠理解爲符合IP協議的地址。
2.TCP協議:傳輸控制協議
該協議主要用於在主機間創建一個虛擬鏈接,以實現高可靠性的數據包交換。IP協議能夠進行IP數據包的分割和組裝,可是經過IP協議並不能清楚地瞭解到數據包是否順利地發送給目標計算機。而使用TCP協議就不一樣了,在該協議傳輸模式中在將數據包成功發送給目標計算機後,TCP會要求發送一個確認;若是在某個時限內沒有收到確認,那麼TCP將從新發送數據包。另外,在傳輸的過程當中,若是接收到無序、丟失以及被破壞的數據包,TCP還能夠負責恢復。
4.HTTP:超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲普遍的一種網絡協議。全部的WWW文件都必須遵照這個標準。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。
47、計算機網絡分層,每層所用協議,協議所佔端口
(1)應用層:與其餘計算機進行通信的一個應用,它是對應應用程序的通訊服務的。示例:telnet,HTTP,FTP,WWW,NFS,SMTP等。
(2)表示層:這一層的主要功能是定義數據格式及加密。示例:加密,ASII等。
(3)會話層:他定義瞭如何開始、控制和結束一個會話,包括對多個雙向小時的控制和管理,以便在只完成連續消息的一部分時能夠通知應用,從而使表示層看到的數據是連續的。示例:RPC,SQL等。
(4)傳輸層:這層的功能包括是否選擇差錯恢復協議仍是無差錯恢復協議,及在同一主機上對不一樣應用的數據流的輸入進行復用,還包括對收到的順序不對的數據包的從新排序功能。示例:TCP,UDP,SPX。
(5)網絡層:這層對端到端的包傳輸進行定義,他定義了可以標識全部結點的邏輯地址,還定義了路由實現的方式和學習的方式。。示例:IP,IPX等。
(6)數據鏈路層:他定義了在單個鏈路上如何傳輸數據。
(7)物理層:OSI的物理層規範是有關傳輸介質的特性標準,這些規範一般也參考了其餘組織制定的標準。
48、html訪問全過程
A)解析Web頁面的URL,獲得Web服務器的域名
B)經過DNS服務器得到Web服務器的IP地址
I)與Web服務器創建TCP鏈接
E)與Web服務器創建HTTP鏈接
C)從Web服務器得到URL指定的文檔
G)瀏覽器解釋頁面文檔,並顯示在屏幕
49、classloader原理
1.classLoader的介紹及加載過程
與普通程序不一樣的是,Java程序(class文件)並非本地的可執行程序。當運行Java程序時,首先運行JVM(Java虛擬機),而後再把Java class加載到JVM裏頭運行,負責加載Java class的這部分就叫作Class Loader。因此classLoader的目的在於把class文件裝入到jvm中。
那麼classLoader又在那裏的啦?又由誰調用呢?其實classLoader只是jvm的一個實現的一部分。Jvm提供的一個頂級的classLoader(bootStrap classLoader),bootStrap classLoader負責加載java核心的API以知足java程序最基本的需求。Jvm還提供的兩個classLoader,其中Extension ClassLoader負責加載擴展的Java class,Application ClassLoader負責加載應用程序自身的類。而Extension ClassLoader和Application ClassLoader則由bootStrap classLoader加載。
2.classLoader加載的基本流程
當運行一個程序的時候,JVM啓動,運行bootstrap classloader,該ClassLoader加載java核心API(ExtClassLoader和AppClassLoader也在此時被加載),而後調用ExtClassLoader加載擴展API,最後AppClassLoader加載CLASSPATH目錄下定義的Class,這就是一個程序最基本的加載流程。
3.classLoader加載的方式
其實classLoader在加載class文件的時候就採用的雙親委託模式。每個自定義ClassLoader都必須繼承ClassLoader這個抽象類,而每一個ClassLoader都會有一個parent ClassLoader,咱們能夠看一下ClassLoader這個抽象類中有一個getParent()方法,這個方法用來返回當前ClassLoader的parent。
50、快速排序原理
原理:
快速排序也是分治法思想的一種實現,他的思路是使數組中的每一個元素與基準值(Pivot,一般是數組的首個值,A[0])比較,數組中比基準值小的放在基準值的左邊,造成左部;大的放在右邊,造成右部;接下來將左部和右部分別遞歸地執行上面的過程:選基準值,小的放在左邊,大的放在右邊。。。直到排序結束。
步驟:
1.找基準值,設Pivot = a[0]
2.分區(Partition):比基準值小的放左邊,大的放右邊,基準值(Pivot)放左部與右部的之間。
3.進行左部(a[0] - a[pivot-1])的遞歸,以及右部(a[pivot+1] - a[n-1])的遞歸,重複上述步驟。
[java] view plain copy
1.//快速排序
2.void quick_sort(int s[], int l, int r)
3.{
1. 4. if (l < r)
2. 5. {
3. 6. //Swap(s[l], s[(l + r) / 2]); //將中間的這個數和第一個數交換 參見注1
4. 7. int i = l, j = r, x = s[l];
5. 8. while (i < j)
6. 9. {
7. 10. while(i < j && s[j] >= x) // 從右向左找第一個小於x的數
8. 11. j--;
9. 12. if(i < j)
10. 13. s[i++] = s[j];
11. 14.
12. 15. while(i < j && s[i] < x) // 從左向右找第一個大於等於x的數
13. 16. i++;
14. 17. if(i < j)
15. 18. s[j--] = s[i];
16. 19. }
17. 20. s[i] = x;
18. 21. quick_sort(s, l, i - 1); // 遞歸調用
19. 22. quick_sort(s, i + 1, r);
20. 23. }
24.}
51、各類集合類之間的區別
1.ArrayList: 元素單個,效率高,多用於查詢
2.Vector: 元素單個,線程安全,多用於查詢
3.LinkedList:元素單個,多用於插入和刪除
4.HashMap: 元素成對,元素可爲空
5.HashTable: 元素成對,線程安全,元素不可爲空
52、內存溢出和內存泄漏
內存溢出是指已有的數據超過了其得到到的內存所能存儲的範圍,好比用一個字節存放1000這個數字就屬於內存溢出。好比說你申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
Java內存泄漏就是沒有及時清理內存垃圾,致使系統沒法再給你提供內存資源(內存資源耗盡)。Java內存泄露是說程序邏輯問題,形成申請的內存沒法釋放.這樣的話不管多少內存,遲早都會被佔用光的.最簡單的例子就是死循環了.因爲程序判斷錯誤導常常發生此事。
53、jvm佈局
如下是JVM的一個基本架構圖,在這個基本架構圖中,棧有兩部份,Java線程棧以及本地方法棧
1.使用緩存的目的:
提升應用程序的性能,減小到數據庫的訪問次數,
舉個簡單應用場景,好比微信羣聊,當服務器收到一條消息的時候,須要把消息插入數據庫。
最原始的作法,就是每當有一條聊天記錄到達服務器的時候,就進行一次數據庫的插入操做。若是不考慮服務器帶寬,這種狀況下數據庫的每秒io次數約等於每秒聊天記錄插入的次數。
換一種實現思路,用redis作緩存,消息到達服務器的時候,並非馬上好比數據庫,而是存在redis裏。當redis聊天記錄到達60條的時候,再執行1次數據庫插入操做。
這樣子,粗略估計,服務器性能就提升了60倍
2.緩存的介質(緩存的存儲位置)
內存:臨時性存儲空間 存取數據快 減小網絡通訊量
硬盤:永久性存儲空間 存取速度慢
3.緩存的分類
客戶端緩存:瀏覽器 cookie
服務器緩存:oscache,redis,memcache,session
4.緩存什麼樣的數據?
常常訪問,又不常常修改的數據
5.緩存的有效性
爲了不髒數據的產生,要刷新緩存,這時就用到了事務爲了不頁面顯示問題,須要更新緩存和數據庫保證一致性
6.髒數據
若是緩存中的數據和數據庫中的數據不一致,那麼緩存中的數據就被稱之爲髒數據
7.刷新緩存的方式
手動刷新:寫程序的時候調用指定的代碼清除緩存數據
定時刷新:當到達緩存過時時間後,會自動刷新數據
8.緩存的層次(通常咱們將緩存加載service中)
jsp-->action-->service-->dao
緩存越靠前對性能的提升越大
9.緩存的清除策略:(緩存空間不足須要進行清理的時候使用)
LRU:最近最少使用原則.(理解:存儲書)
FIFO:先進先出的緩存策略.(理解:排隊)
10.何時使用緩存的清除策略?
當緩存中的數據已滿,又有新的數據進來時,執行緩存的清除策略
Maven兩個重點:根據Maven的約定因爲配置了四個文件的文件名必須是固定的,還有一個loge日誌的名字也是固定的,這樣不須要去加載這些文件直接經過Maven的約定因爲配置自動加載好
還有根據maven的依賴管理在pom.xml中配置jar與這個jar包相關的jar包自動配置好
我當時是怎麼配置maven的經過在服務端中setting 中配置這個mirror鏡像配置訪問nexus的訪問路徑
這樣咱們就能夠經過pom.xml先到咱們的本地去找,若是本地倉庫找不到在去maven私服去找若是私服找不到在去外網下載使用maven這樣能夠提升咱們的開發效率與節省了下載帶寬,以及jar包的重用性。
@Controller:使其普通的java類充當控制層的做用。
@RequestMapping:有兩個參數 url 表明要訪問的路徑 method請求方式
@Service::使其java類充當service層。
@Repository::使其java類充當持久層。Er4
@Resource:默認按照名字注入指定的bean。
@Autowired:默認按照類型進行注入能夠結合@Qualifier("bean的的名字 名字")使使其按照名字進行注入。他是 其按照名字進行注入。他是Spring中的註解。
@RespsonceBody:將controller的方法返回的對象經過適當的轉換器轉換爲指定個時候將其輸出(一般適用於返回json/xml)
@RequestParam
做用:1.在文件上傳時註解 @requestParam 後跟multilpartFile屬性
2.接收指定參數名的參數並對方法中的參數賦值而且能夠設置默認值
我對Spring MVC的理解和運用。
咱們一般使用Spring MVC來充當咱們項目中的控制層,咱們控制層的做用就是接受前臺傳遞的參數,調用業務邏輯層進行業務處理以及將返回的結果集返回前臺進行展現,首先咱們要在web.xml中配置Spring MVC的前端總控制器DispatcherServlet並加載Spring MVC的配置文件,咱們在Controller層上加上@Controller註解,使其充當控制層,而且要在Spring mvc的配置文件中經過component-scan對Controller層進行掃描從而使類中的@Controller註解生效,Spring mvc用方法來接收參數,因此咱們說Spring mvc是基於方法的設計,咱們也能夠經過@PathVariable從路徑中獲取信息,咱們一般經過@Resource這個註解來進行Bean注入,他是java中的註解,而不是Spring中的,默認是按照屬性名進行注入,咱們也能夠經過設置name屬性的值,讓其只能按照屬性名進行注入,咱們也能夠用@Autowired註解來進行Bean的注入,他默認是按照類型進行注入,若是要按屬性名進行注入咱們須要結合@Qualifier註解使其按照名字進行注入,咱們能夠將返回值的類型改成ModelAndView並在配置文件中配置視圖解析器的前綴和後綴,以此來給咱們前臺頁面傳遞數據,也能夠在方法中經過ModelMap進行返回數據。也能夠經過@ResponseBody將返回的實體類或者實體類的集合轉換爲指定的格式進行前臺頁面交互。而且要在配置文件中進行相關的配置。@RequestMapping是將Url映射到具體的方法上。文件上傳時咱們經過@RequestParam來接收前臺上傳的文件。以上就是我對Spring MVC的理解和運用。
SSH整合的流程
在項目中首先是經過在web.xml中配置strtus2的前端控制器filterDispatcher加載struts.xml
配置文件並對指定的後綴名進行攔截,而且經過配置spring的監聽器contextLoadListener
加載spring的相關配置文件如
spring-service.xml,spring-dao.xml,spring-common.xml,
以後新建控制層的類繼承於BaseAction,而BaseAction繼承於ActionSupport,
在BaseAction中封裝了經常使用的方法如getRealPath(),outJson()等,
以後控制層注入service層,service層注入dao,dao層繼承於HibernateDaoSupport
並注入spring-common.xml中配置的sessionFactory,sessionFactory注入dataSource鏈接數據庫,
注入hibernate.cfg.xml從而加載hbm.xml文件,
除此以外還經過Spring中的Aop配置了事務而且經過切點表達式對Servcie層代碼進行控制。
======================================================================SSM整合的流程
在項目中經過在web.xml配置springMVC的核心控制器DispatcherServlet
並加載Spring-mvc-controller.xml,而且經過配置Spring的監聽器contextLoaderListener
加載spring-common.xml,以後新建控制層並在類上加入@Controller和@RequestMapping註解,
並經過@Resouce注入service層,在
service的實現類上加入@Service註解並經過@Autowired注入dao層,
dao層只有接口並無實現類,
是經過在mybatis中對應的含有sql語句的xml文件中來經過namespace指明要實現的dao層的接口,
並使sql語句的id和dao層接口中的方法名一致從而明確調用指定dao層接口時要執行的sql語句。
而且在spring-mvc-controller.xml中配置了component-scan對controller
進行掃描從而使控制層的註解生效還配置了內部視圖解析器從而在控制層進行頁面跳轉時加上指定的前綴和後綴,
在spring-common.xml中配置了dbcp數據庫鏈接池以及sqlSession來加載mapper下全部的xml
並對全部的mapper層進行掃描也就是對dao層的掃描,
還經過Aop中的切點表達式對service層進行事務控制,而且對service層進行掃描使其註解生效。
Spring 是徹底面向接口的設計,下降程序耦合性,主要是事務控制並建立bean實例對象。在ssh整合時,充當黏合劑的做用。IOC(Inversion of Control) 控制反轉/依賴注入,又稱DI(Dependency Injection) (依賴注入)
IOC的做用:產生對象實例,因此它是基於工廠設計模式的
Spring IOC的注入
經過屬性進行注入,經過構造函數進行注入,
注入對象數組 注入List集合
注入Map集合 注入Properties類型
Spring IOC 自動綁定模式:
能夠設置autowire按如下方式進行綁定
按byType只要類型一致會自動尋找,
按byName自動按屬性名稱進行自動查找匹配.
AOP 面向方面(切面)編程
AOP是OOP的延續,是Aspect Oriented Programming的縮寫,
意思是面向方面(切面)編程。
注:OOP(Object-Oriented Programming ) 面向對象編程
AOP 主要應用於日誌記錄,性能統計,安全控制,事務處理(項目中使用的)等方面。
Spring中實現AOP技術:
在Spring中能夠經過代理模式來實現AOP
代理模式分爲
靜態代理:一個接口,分別有一個真實實現和一個代理實現。
動態代理:經過代理類的代理,接口和實現類之間能夠不直接發生聯繫,而 能夠在運行期(Runtime)實現動態關聯。
動態代理有兩種實現方式,能夠經過jdk的動態代理實現也能夠經過cglib
來實現而AOP默認是經過jdk的動態代理來實現的。jdk的動態代理必需要有
接口的支持,而cglib不須要,它是基於類的。
Spring AOP事務的描述:
在spring-common.xml裏經過<aop:config>裏面先設定一個表達式,設定對service裏那些方法 如:對add* ,delete*,update*等開頭的方法進行事務攔截。咱們須要配置事務的傳播(propagation="REQUIRED")特性,一般把增,刪,改之外的操做須要配置成只讀事務(read-only="true").只讀事務能夠提升性能。以後引入tx:advice,在tx:advice引用 transactionManager(事務管理),在事務管理裏再引入sessionFactory,sessionFactory注入 dataSource,最後經過<aop:config>引入txAdvice。
Spring實現ioc控制反轉描述:
原來須要咱們本身進行bean的建立以及注入,而如今交給
spring容器去完成bean的建立以及注入。
所謂的「控制反轉」就是 對象控制權的轉移,
從程序代碼自己轉移到了外部容器。
官方解釋:
控制反轉即IoC (Inversion of Control),
它把傳統上由程序代碼直接操控的對象的調用權交給容器,
經過容器來實現對象組件的裝配和管理。
所謂的「控制反轉」概念就是對組件對象控制權的轉移,
從程序代碼自己轉移到了外部容器。
HashMap底層就是一個數組結構,數組中的每一項又是一個鏈表。
當新建一個HashMap的時候,就會初始化一個數組。
Entry就是數組中的元素,每一個 Entry 其實就是一個key-value對,
它持有一個指向下一個元素的引用,這就構成了鏈表。
HashMap 在底層將 key-value 當成一個總體進行處理,這個總體就是一個 Entry 對象。
HashMap 底層採用一個 Entry[] 數組來保存全部的 key-value 對,
當須要存儲一個 Entry 對象時,會根據hash算法來決定其在數組中的存儲位置,
再根據equals方法決定其在該數組位置上的鏈表中的存儲位置;當須要取出一個Entry時,
也會根據hash算法找到其在數組中的存儲位置,
再根據equals方法從該位置上的鏈表中取出該Entry。
Jdk【Java Development ToolKit】就是java開發工具箱, JDK是整個JAVA的核內心邊包含了jre,它除了包含jre以外還包含了一些javac的工具類,把java源文件編譯成class文件,java文件是用來運行這個程序的,除此以外,裏邊還包含了java源生的API,java.lang.integer在rt的jar包裏邊【能夠在項目中看到】,經過rt這個jar包來調用咱們的這些io流寫入寫出等
JDK有如下三種版本:
J2SE,standard edition,標準版,是咱們一般用的一個版本
J2EE,enterpsise edtion,企業版,使用這種JDK開發J2EE應用程序
J2ME,micro edtion,主要用於移動設備、嵌入式設備上的java應用程序
Jre【Java Runtime Enviromental】是java運行時環境,那麼所謂的java運行時環境,就是爲了保證java程序可以運行時,所必備的一基礎環境,也就是它只是保證java程序運行的,不能用來開發,而jdk纔是用來開發的,全部的Java程序都要在JRE下才能運行。
包括JVM和JAVA核心類庫和支持文件。與JDK相比,它不包含開發工具——編譯器、調試器和其它工具。
Jre裏邊包含jvm
Jvm:【Java Virtual Mechinal】由於jre是java運行時環境,java運行靠什麼運行,而底層就是依賴於jvm,即java虛擬機,java虛擬機用來加載類文件,java中之因此有跨平臺的做用,就是由於咱們的jvm
關係:
J2se是基於jdk和jre,
JDK是整個JAVA的核內心邊包含了jre,
Jre裏邊包含jvm
1.List和Set都是接口,他們都繼承於接口Collection,List是一個有序的可重複的集合,而Set的無序的不可重複的集合。Collection是集合的頂層接口,Collections是一個封裝了衆多關於集合操做的靜態方法的工具類,由於構造方法是私有的,因此不能實例化。
2.List接口實現類有ArrayList,LinkedList,Vector。ArrayList和Vector是基於數組實現的,因此查詢的時候速度快,而在進行增長和刪除的時候速度較慢LinkedList是基於鏈式存儲結構,因此在進行查詢的時候速度較慢但在進行增長和刪除的時候速度較快。又由於Vector是線程安全的,因此他和ArrayList相比而言,查詢效率要低。
我負責項目中的系統管理模塊,其中包含用戶管理,菜單管理以及給用戶賦角色,給角色賦權限;涉及到的表有用戶表,角色表,用戶角色關聯表,菜單表,角色菜單關聯表。在菜單管理模塊採用ztree進行菜單的增刪改查操做,爲了將權限控制到按鈕級別咱們在進行菜單管理時會設置該菜單是屬於按鈕級別仍是普通菜單,經過在數據庫中增長一個type類型的字段來實現,如type爲1則是普通菜單,type爲2則是按鈕菜單。
這樣用戶在登陸的時候根據用戶名和密碼到用戶表驗證信息是否合法,若是合法則獲取用戶信息,以後根據用戶id再到用戶角色關聯表中獲得相關聯的角色id集合,以後根據角色id集合再到角色權限關聯表中獲取該角色所擁有的權限id集合,而後再根據權限id集合到權限表(菜單表)中獲取具體的菜單,展示給當前登陸用戶,從而達到不一樣用戶看到不一樣的菜單權限。
爲了防止用戶不登陸而直接訪問後臺資源我經過在項目中加入LoginInterceptor攔截器對未經認證的用戶進行攔截,若是未經認證則跳轉到登陸頁面使用戶再次登陸,除此以外還加入了PermissionInterceptor攔截器來對用戶無權訪問的資源進行攔截,若是無訪問權限則跳轉到沒rr4有訪問權限的頁面。
再者考慮到性能將用戶登陸後所擁有的資源權限經過OScache結合單例設計模式將數據存儲到了緩存中,這樣能夠避免每次操做都須要從新進行查詢的代價,減小和數據庫的交互次數,提升系統性能。考慮到單例的設計模式在多線程中會出現線程安全的問題,因此就給單例加了雙重判斷鎖,從而避免該問題的發生。
共同點:
1. 均可以寫抽象方法
2. 都不能被實例化對象
3. 類繼承抽象類須要重寫抽象方法,類實現接口也必須重寫抽象方法
不一樣點
1. 類和接口是兩個不一樣的概念,抽象類是由abstract修飾的類;接口不是類,用interface定義
2. 接口中只能有抽象方法,抽象類中既能夠有抽象方法,又能夠有普通方法
3. 類是單繼承多實現,實現一個抽象類,須要繼承.實現接口須要implements
4. 接口定義的變量默認是public static final的,而抽象類沒有這個限制
1.get是從服務器上獲取數據,post是向服務器傳送數據,
2.get傳送的數據量較小,不能大於2KB。post傳送的數據量較大,通常被默認爲不受限制。
3.get安全性很是低,post安全性較高。可是執行效率卻比Post方法好。
4.在進行文件上傳時只能使用post而不能是get。
5.不明確是post請求的都是get請求
1、從數據共享上
Forword是一個請求的延續,能夠共享request的數據
Redirect開啓一個新的請求,不能夠共享request的數據
2、從地址欄
Forword轉發地址欄不發生變化
Redirect轉發地址欄發生變化
HTTP是一個超文本傳輸協議,屬於OSI七層模型的應用層,由請求和響應構成,
是一個標準的客戶端服務器模型。HTTP是無狀態的也就是說同一個客戶端的此次請求和上次請求是沒有對應關係。
http的工做流程:
當發送一個http請求時,首先客戶機和服務器會創建鏈接,
以後發送請求到服務器,請求中包含了要訪問的url地址,請求的方式(get/post),
以及要傳遞的參數和頭信息,服務器接到請求後會進行響應,
包括狀態行,狀態碼,響應頭,以及要響應的主體內容。客戶端接收
到請求後將其展現到瀏覽器上而後斷開和服務器端的鏈接。
簡單說就是:創建鏈接--》發送請求--》響應--》斷開鏈接
在HTTP/1.0中,默認使用的是短鏈接。也就是說,瀏覽器和服務器每進行一次HTTP操做,就創建一次鏈接,
但任務結束就中斷鏈接。
從 HTTP/1.1起,默認使用長鏈接,用以保持鏈接特性。使用長鏈接的HTTP協議,會在響應頭有加入這行代碼:
Connection:keep-alive
在使用長鏈接的狀況下,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的 TCP鏈接不會關閉,
若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。
Keep-Alive不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件(如Apache)中設定這個時間。
實現長鏈接要客戶端和服務端都支持長鏈接。
HTTP協議的長鏈接和短鏈接,實質上是TCP協議的長鏈接和短鏈接。
jquery是一個輕量級的js框架,具備跨瀏覽器的特性,兼容性好,
而且封裝了不少工具,方便使用。
經常使用的有: 選擇器 ,dom操做 ,ajax(ajax不能跨域) ,特效,工具類
在數據庫中,所謂事務是指一組邏輯操做單元即一組sql語句。當這個單元中的一部分操做失敗,整個事務回滾,只有所有正確才完成提交。
判斷事務是否配置成功的關鍵點在於出現異常時事務是否會回滾
事務的ACID屬性
1. 原子性(Atomicity)
原子性是指事務是一個不可分割的工做單位,事務中的操做要麼都發生,
要麼都不發生。
2. 一致性(Consistency)
事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態。(數據不被破壞)
3. 隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其餘事務干擾.
4. 持久性(Durability)
持久性是指一個事務一旦被提交,
它對數據庫中數據的改變就是永久性的.即便系統重啓也不會丟失.
在JDBC中,
事務默認是自動提交的,
每次執行一個 SQL 語句時,若是執行成功,
就會向數據庫自動提交,而不能回滾
爲了讓多個 SQL 語句做爲一個事務執行:
(1)執行語句前調用 Connection 對象的 setAutoCommit(false);
以取消自動提交事務
(2)在全部的 SQL 語句都成功執行後,調用 commit(); 方法提交事務
(3)在出現異常時,調用 rollback(); 方法回滾事務。
1、索引的概念
索引就是爲了提升數據的檢索速度。
數據庫的索引相似於書籍的索引。
在書籍中,索引容許用戶不必翻閱完整個書就能迅速地找到所須要的信息。
在數據庫中,索引也容許數據庫程序迅速地找到表中的數據,
而沒必要掃描整個數據庫.
2、索引的優勢
1.建立惟一性索引,保證數據庫表中每一行數據的惟一性
2.大大加快數據的檢索速度,這也是建立索引的最主要的緣由
3.減小磁盤IO(向字典同樣能夠直接定位)
3、索引的缺點
1.建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長
2.索引須要佔用額外的物理空間
3.當對錶中的數據進行增長、刪除和修改的時候,
索引也要動態的維護,下降了數據的維護速度
4、索引的分類
1.普通索引和惟一性索引
普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
惟一性索引:保證在索引列中的所有數據是惟一的
CREATE unique INDEX mycolumn_index ON mytable (myclumn)
2. 單個索引和複合索引
單個索引:對單個字段創建索引
複合索引:又叫組合索引,在索引創建語句中同時包含多個字段名,
最多16個字段
CREATE INDEX name_index ON userInfo(firstname,lastname)
3.順序索引,散列索引,位圖索引
首先不考慮查詢條件 先寫分頁語句 在寫條件
1.例如:河北省不滿18週歲的男的4,5,6條信息
select * from
(select t.* ,rownum rn from
(select id,name, age,sex from t_student where name="河北" and age<18 and sex="男") t
where rownum <= 6)
where rn >=4
2.女生年齡從高到低排序 每頁3條 查詢第3條
select * from
(select t.*,rownum rn from
(select id,name,age from t_student order by age desc) t
where rownum <= 9)
where rn>=7
第一範式(1NF):強調的是列的原子性,即列不可以再分紅其餘幾列。
第二範式(2NF): 首先是知足第一範式,另外包含兩部份內容,一是表必須有一個主鍵;二是沒有包含在主鍵中的列必須徹底依賴於主鍵,而不是部分依賴。
第三範式(3NF): 首先知足第二範式,非主鍵列直接依賴於主鍵,間接傳遞依賴。
rowid物理位置的惟一標識。
而id是邏輯上的惟一標識,因此rowid查找速度要快於id,是目前最快的
定位一條記錄的方式
rowid和rownum都是"僞數列"
所謂「僞數列」也就是默認隱藏的一個數列。
rownum用於標記結果集中結果順序的一個字段,
它的特色是按順序標記,並且是連續的,
換句話說就是隻有有rownum=1的記錄,纔可能有rownum=2的記錄。
rownum關鍵字只能和<或者<=直接關聯
若是是>或者=則須要給他0起個別名
單例就是該類只能返回一個實例(實例只會建立一次)
單例所具有的特色:
1.私有的構造函數
2.私有的靜態的全局變量
3.公共的靜態的方法
雙重鎖定式
public class Singleton {
private Singleton(){};
private static Singleton single;
public static Singleton getInstance(){
if(null ==single){
Synchronized(single){
if(null == single){
single = new Singleton();
}
}
}
return single;
}
}
在建立主鍵的同時會生成對應的惟一索引,主鍵在保證數據惟一性的同時不容許爲 空,而惟一能夠有一個爲空數據項,一個表中只能有一個主鍵,可是一個主鍵能夠 有多個字段,一個表中能夠有多個惟一索引。
數據庫鏈接池的優勢運行原理:
在咱們不使用數據庫鏈接池的時候,每次訪問數據庫都須要建立鏈接,
使用完成以後須要釋放關閉鏈接,而這樣是很耗費資源的。當咱們使用
數據庫鏈接池的時候,在tomcat啓動的時候就建立了指定數量的鏈接,
以後當咱們程序使用的時候就直接從鏈接池裏面取,而不須要建立,同理,
當咱們使用完的時候也不須要關閉鏈接,而是將鏈接返回到鏈接池中,供
其餘請求繼續使用。
DBCP:比較穩定。
C3P0: 性能比較高。
Hibernate屬於全自動, Ibatis屬於半自動,Jdbc屬於手動,從開發效率上講hibernate較高,ibatis居中,jdbc較低,從執行效率上講hibernate較低,ibatis居中,jdbc較高,由於jdbc是手工寫sql語句,程序員對sql的控制能力更大,能夠根據業務須要進行優化,而ibatis雖然也能夠對sql進行優化,可是他裏面將resultset封裝爲實體的過程當中採用了反射機制因此必定程度上影響了性能,而hibernate由於高度封裝因此開發效率相對較高,但正由於這個緣由,因此程序員在對sql語句的控制和優化方面相對比較弱,並且在將resultset封裝成實體的過程當中也採用了反射機制,因此在性能方面較低
外鍵必須加索引。
避免在 where 子句中對有索引的字段進行運算,這會致使索引失效,從而進行全表掃描。
在 where 及 order by 涉及的列上創建索引,要儘可能避免全表掃描。
在設計表時要避免表中字段出現null的狀況,一般要爲其設置默認值。
避免在查找時放棄使用索引而進行全表掃描。
SELECT語句中避免使用'*’,只查詢須要返回的字段 ,這樣能夠減小oracle解析sql語句的時間。
用NOT EXISTS 替換 NOT IN 操做符,用 EXISTS 替換 IN
解析大文件的xml
數據使用sax替代dom4j,使用分段批量提交來完成大數據量的插入。
對於大批量字符串的拼接使用stringbuffer或者stringbuilder代替string進行+拼接。
根據業務狀況使用緩存減小對數據庫的訪問。
單線程應儘可能使用 HashMap, ArrayList,由於HashTable,Vector使用了同步機制,下降了性能。
在finally塊中關閉流,斷開鏈接,釋放資源。
避免在循環條件中使用複雜表達式 。
3.Hibernate優化:
在處理大數據量時,會有大量的數據緩衝保存在Session的一級緩存中,這緩存大太時會嚴重顯示性能,因此在使用Hibernate處理大數 據量的,能夠使用session. clear()或者session. evict(Object) ,在處理過程當中,清除所有的緩存或者清除某個對象。
經過使用Hibernate的一級緩存,二級緩存,查詢緩存等來提升性能 (必須)
Hibernate能夠經過設置hibernate.jdbc.fetch_size,hibernate.jdbc.batch_size等屬性,對Hibernate進行優化。
Batch Size是設定對數據庫進行批量刪除,批量更新和批量插入的時候的批次大小,Batch Size越大和數據庫交互的次數就越少,速度就越快, 但也不要無限的大下去,一般選擇一個合適的值,如100條;其次咱們在進行大批量數據的導入操做時,能夠結合batchsize進行分段批量提交,從而達到最優效果。
29.數據庫優化?(被動說)
數據庫優化:做爲開發人員最主要是從sql語句的優化方面考慮的,對於數據庫底層的優化,是由DBA完成的。
在咱們公司裏面作項目的時候,在開發過程當中最主要是由程序員對java代碼以及sql語句這方面進行優化,至於數據庫 底層的優化,則由DBA在項目基本結尾進行壓力測試的時候參與進來,經過對數據庫的分析,肯定影響性能的sql語句以及相關的表,經過和咱們進行交流而後對其進行適當的改進。
慢日誌就是在咱們設置的時間內執行慢的語句能夠在慢日誌看到!
2.分表:
時間劃分 地區劃分
水平劃分 垂直劃分(把日常常用的提取出來加上索引)
3.在mysql中經過explain查看執行計劃
在作XX電商項目的時候,考慮到提升網站前臺的性能,承受更大的併發,咱們將網站首頁和不少文章頁面都進行了靜態化。當時採用的方式是經過freemarker模板引擎和spring定時器來結合完成的。前臺美工經過網站管理後臺用freemarker編寫首頁模板以及相關的樣式,以後將模板信息存入模板表,我負責編寫spring定時器在每晚的凌晨從數據庫中的模板表中取出各類類型的模板並和相關的數據結合起來生成靜態的html頁面。而且考慮到減小前臺美工編寫freemarker標籤的難度,我將常常用到的一些功能像分頁,列表展現等經過#macro編寫爲freemarker的宏命令,方便前臺美工直接使用。對於及時性要求比較高的特別熱門的頻道,則在用戶點擊發布時直接調用編寫的接口經過freemarker和數據結合生成html靜態頁面。
redis是一個基於key,value的支持多種數據類型(String,List,Set,zSet,Hash)的可進行持久化的內存數據庫。咱們在項目中一般使用redis來充當緩存服務器來緩存分類列表,品牌列表,熱銷商品,推薦商品以及該商品的關聯商品等等。之前作項目的時候,咱們是把商品的信息存放在redis裏面,redis支持多種數據類型,有兩種方法存儲對象:1,能夠把對象序列化進行存儲,而後反序列化取出。2.用hash結構存儲,最後發現,仍是用hash存取比較快
當時咱們就是在redis中設置maxmemory【最大內存】,把maxmemory-policy【數據清除策略】設置爲allkeys-lru。爲了保證redis不會由於佔用內存過大而致使系統宕機,也會設置最大內存和數據清除策略。使用了jedis做爲客戶端,並考慮到性能問題使用了jedis鏈接池。考慮到redis服務器的高可用性,咱們作了redis的主從複製,剛開始配置redis的時候,我是關閉它的保護模式,雖然實現了功能,可是不安全,最後是在redis.conf配置文件中綁定具體的ip地址,這樣只有該ip地址才能訪問redis服務器,而且設置長度爲20位左右的密碼,從而保證只有進行了密碼受權才能進行相關的操做,爲了信息安全,咱們配置了redis的主從複製,在從服務器的配置文件中經過配置slaveof綁定主服務器的ip地址和端口號,
當設置好slave服務器後,slave會創建和master的鏈接,而後發送sync命令。不管是第一次同步創建的鏈接仍是鏈接斷開後的從新鏈接,master都會啓動一個後臺進程,將數據庫
快照保存到文件中,同時master主進程會開始收集新的寫命令並緩存起來。後臺進程完成寫文件後master就發送文件給slave,slave將文件保存到磁盤上,而後加載到內存恢復數據庫快照到slave上。接着master就會把緩存的命令轉發給slave。並且後續master收到的寫命令都會經過開始創建的鏈接發送給slave。從master到slave的同步數據的命令和從 client發送的命令使用相同的協議格式。當master和slave的鏈接斷開時slave能夠自動從新創建鏈接。若是master同時收到多個slave發來的同步鏈接命令,只會使用啓動一個進程來寫數據庫鏡像,而後發送給全部slave。
哨兵要監視 Redis 服務器,就必須鏈接 Redis 服務器。啓動哨兵的時候須要指定一個配置文件,程序初始化的時候會讀取這個配置文件,獲取被監視 Redis 服務器的 IP 地址和端口等信息。
哨兵鏈接redis服務器發送兩個鏈接一個是普通鏈接,另外一個是訂閱發佈專用鏈接。哨兵在初始化訂閱發佈鏈接的時候,作了兩個工做:一是,向 Redis 服務器發送 SUBSCRIBE SENTINEL_HELLO_CHANNEL命令;二是,註冊了回調函數 sentinelReceiveHelloMessages()。
哨兵會向 hello 頻道發送包括:哨兵本身的IP 地址和端口,runid,當前的配置版本;其所監視主機的 IP 地址,端口,當前的配置版本。【這裏要說清楚,什麼是 runid 和配置版本】雖然未知的信息不少,但咱們能夠得知,當一個哨兵新加入到一個 Redis 集羣中時,就能經過 hello 頻道,發現其餘更多的哨兵,而它本身也可以被其餘的哨兵發現,哨兵向與 Redis 服務器的命令鏈接通道上,發送了一個INFO 命令(字符串);並註冊了回調函數sentinelInfoReplyCallback()。Redis 服務器須要對 INFO 命令做出相應,能在 redis.c 主文件中找到 INFO 命令的處理函數:當 Redis 服務器收到INFO命令時候,會向該哨兵回傳數據,包括:
關於該 Redis 服務器的細節信息,rRedis 軟件版本,與其所鏈接的客戶端信息,內存佔用狀況,數據落地(持久化)狀況,各類各樣的狀態,主從複製信息,全部從機的信息,CPU 使用狀況,存儲的鍵值對數量等。
由此獲得最值得關注的信息,全部從機的信息都在這個時候曝光給了哨兵,哨兵由此就能夠監視此從機了。
Redis 服務器收集了這些信息回傳給了哨兵,剛纔所說哨兵的回調函數 sentinelInfoReplyCallback()會被調用,它的主要工做就是着手監視未被監視的從機;完成一些故障修復(failover)的工做。連同上面的一節,就是Redis 的 auto discover 的全貌了。
在哨兵的定時程序中,哨兵會向全部的服務器,包括哨兵服務器,發送 PING 心跳,而哨兵收到來自 Redis 服務器的迴應後,也會更新相應的時間點或者執行其餘操做,哨兵不只僅憑藉本身的信息,還依據其餘哨兵提供的信息判斷 Redis 服務器是否下線的方法稱爲客觀方法,即經過全部其餘哨兵報告的主機在線狀態來斷定某主機是否下線。
一個 Redis 集羣不免遇到主機宕機斷電的時候,哨兵若是檢測主機被大多數的哨兵斷定爲下線,就極可能會執行故障修復,從新選出一個主機。通常在 Redis 服務器集羣中,只有主機同時肩負讀請求和寫請求的兩個功能,而從機只負責讀請求,從機的數據更新都是由以前所提到的主從複製上獲取的。所以,當出現意外狀況的時候,頗有必要新選出一個新的主機。
優選選擇優先級高的從機
優先選擇主從複製偏移量高的從機,即從機從主機複製的數據越多
優先選擇有 runid 的從機
若是上面條件都同樣,那麼將 runid 按字典順序排序
而且經過加入哨兵來使redis主服務器宕機時,從服務器自動轉換爲主服務器繼續提供服務。
①加載數據庫驅動程序(Class.forName("數據庫驅動類");)
②鏈接數據庫(Connection con = DriverManager.getConnection();)
③操做數據庫(PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();)
④關閉數據庫,釋放鏈接(con.close();)
悲觀鎖/樂觀鎖:
悲觀鎖(Pessimistic Lock), 每次去查詢數據的時候都認爲別人會修改,
因此每次在查詢數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。
傳統的關係型數據庫裏邊就用到了這種鎖機制,好比經過select ....for update進行數據鎖定。
樂觀鎖(Optimistic Lock), 每次去查詢數據的時候都認爲別人不會修改,
因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,
能夠使用版本號,時間戳等機制。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量。
spring中事務的傳播特性好像有5個左右,
我作項目的時候使用最多的就是PROPAGATION_REQUIRED,
它所表明的意思支持當前事務,若是當前沒有事務,就新建一個事務。
spring中事務的隔離級別有5個,默認使用的是ISOLATION_DEFAULT,
它表明使用數據庫默認的事務隔離級別,也是咱們項目中最常使用的。
除此以外還有
讀未提交:
它充許另一個事務能夠看到這個事務未提交的數據,
這種隔離級別會產生髒讀,不可重複讀和幻像讀。
讀提交:
保證一個事務修改的數據提交後才能被另一個事務讀取,
也是大多數數據庫的默認值。能夠避免髒讀,但會產生不可重複讀和幻像讀。
重複讀:
在一個事務內兩次讀到的數據是不同的,所以稱爲是不可重複讀。
串行化:
順序執行事務。除了防止髒讀,不可重複讀外,還避免了幻像讀。
併發性也最低,但最安全。
不可重複讀的重點是修改 :
一樣的條件 , 你讀取過的數據 , 再次讀取出來發現值不同了 。
幻讀的重點在於新增或者刪除 :
一樣的條件 , 第 1 次和第 2 次讀出來的記錄數不同。
mongodb是一個nosql數據庫,咱們在項目中一般用它來存儲評論信息,
【評論id,商品id,標題,評分,內容,評論人信息,評論的發佈時間】
由於每一個商品都會有評論信息,並且某些熱門商品的評論信息多是數千條,
mongodb正好適用於這種大數據量、高併發、弱事務的互聯網應用。考慮
到mongodb的高可用性咱們搭建了3臺mongodb數據庫來實現副本集,這樣
不只能夠達到故障自動轉移的特性並且也能夠經過讀寫分離提升性能,即使
主服務器宕機了,還會經過投票選舉出下一個主服務器繼續提供服務。
再者考慮到咱們的項目最後要部署到多臺tomcat經過nginx來實現負載均衡,
爲了對項目中的文件以及圖片進行統一的管理,咱們就用mongodb來充當文件服務器。
對於大部分的單張圖片和單個文件來講小於16M,因此咱們就以常規的方式來將
文件轉換爲二進制的字節數組進行保存。考慮到高可用性以及爲了應對後期隨着文件數量的不斷
增長而可以方便進行擴容,咱們創建了3個分片並將分片和副本集作了整合,每一個分片都是一個副本集,這樣
不只知足了大數據量的存儲也避免了分片中單臺機器致使的單點故障問題。考慮到可能要處理
大於16M的文件,因此又增長了支持大文件存儲的gridfs,這樣即使再大的文件也會被gridfs分解爲多個
chunk進行存儲。
咱們在項目中一般用EasyUI來充當展現層,由於它是一個RIA富客戶端框架,
自身提供了不少功能強大的插件,能夠提升用戶的體驗度並且也有助於咱們
開發人員直接使用,提升開發效率。咱們在項目中使用到的EasyUI插件有Layout佈局,
EasyUI的tree,Tab頁面,datagrid,form表單,Dialog對話框,Messager提示信息還有
Accordion手風琴效果,progress進度條等。
EasyUI的tree的生成方式有兩種,一種是經過一條sql語句查詢全部的菜單信息,
而後在java中經過遞歸的方式將其拼裝成符合指定json格式的數據,這種適用
於數據量比較小的狀況,經過減小數據庫的訪問次數提升性能,另外一種是經過
ajax異步加載的方式,每點擊一下樹節點就向後臺發送一次請求,從而來獲取
該節點下的子節點,這種適用於數據量比較大的狀況。這時候若是採用取出全
部數據遞歸拼裝的話就有可能出現內存溢出。
咱們當時在項目中是經過Easyui的tree來生成菜單,考慮到菜單的
數據量也不是特別的大,因此就採用了第一種取出全部數據並遞歸將其
拼裝成指定Json的方式來提升性能,再者考慮到每一個用戶的菜單信息並
不是常常改變,因此又結合oscache緩存以及帶有雙重斷定鎖的單例模式
將其緩存到內存中,從而再次提升了性能。
在點擊樹形菜單,動態添加tab頁的時候必定要注意,爲了不每次點擊
都添加一個新的tab頁,咱們的作法是當點擊事件發生時,先判斷當前
選中的菜單所對應的tab頁是否已經存在,若是存在就將其激活選中,不然
再添加新的。多個tab頁出現的另外一個問題就是不一樣tab頁間的數據可能不
同步,因此咱們會在每一個tab頁上面都增長一個刷新按鈕,能夠經過點擊
該按鈕給該tab頁所對應的iframe的src屬性從新賦值,來起到刷新的做用。
datagrid也是咱們在項目中常用到的,在使用datagrid時應該注意的是
在拼裝好的json數據中,須要有total和rows這兩個屬性,其中total用來
指明數據的總條數,rows用來指明當前頁的數據列表;在前臺頁面中要保證
columns中的field和rows中的屬性名相對應,不然數據就展示不出來,並且
對於圖片等制定格式數據的展現須要結合formatter對其進行格式化才能進行
正確的顯示。最後就是在datagrid和form表單結合進行數據查詢時調用的是
load方法,進行增刪改後刷新datagrid調用的是reload方法。
Bootstrap是一個支持響應式的Css框架它提供了不少組件,
如導航條,面板,菜單,form表單,還有柵格,
並且他們這些都是支持響應式的,能夠在各類
設備上進行完美的展示。這裏面我感受最有價值的就是
bootstrap提供的柵格系統,這個柵格系統將
整個頁面分爲12列,並且能夠根據屏幕的寬窄進行自動
調節,這也是響應式的關鍵所在。在使用柵格系統的時候
要注意最外層樣式是Container,裏面是row,row裏面包含
的是列,列裏面能夠用來填充各類各樣的組件。
我在項目中使用bootstrap完成的狀況大概是這個樣子,
首先我使用了bootstrap的導航條,並將其固定在頂部,
使其在拖拉滾動條的時候不至於看不到,
以後在導航條的下面採用了bootstrap的柵格系統將其分爲左右兩部分,
左邊使用bootstrap的Treeview組件,將菜單展示出來,當點擊treeview
上的菜單節點時結合一個第三方的tab組件,將須要展現的內容放到tab頁內,
並進行上下切分,上面使用了bootstrap的form組件,
下面使用了它的響應式表格以及分頁組件,在進行增長修改時,
使用了第三方的bootbox彈出框。
北京市海定區阜外亮甲1號中關注聯網創意產業園27號樓 (豐臺區)
海淀區藍靛廠 晨月園小區 遠大路公交站上車 355/79/118線都能到 坐六站(定慧北橋下車)走大概5分鐘就到了
公司附近 在那邊有一個豐臺科技原生態主題公園
晨月園附近有個巨人學校
從育新坐606路公交到成府路南口下車而後在步行到公司
15K 14K 13K 1000
鄭州理工專修學院 計算機科學與技術 劉信古
有,還有,酒店服務管理 建築工程 行政管理 軌道交通運營 等等。。。
計算機原理 計算機網絡 高級語言 編程語言 操做系統 數據結構
26 馬
合同到期,想換一個新的環境,公司這邊也挽留我,可是在公司也呆了,2.3年了,
想換一個新的平臺,來不斷提高充實本身。
在上家公司的時候,人事說我們公司的五險一金若是要上的話都是從本身工資裏面扣的,
當時感受沒啥必要也就沒上。
這幾年作程序,由於要不斷的對代碼進行驗證確認,全部感受本身如今有點強迫症。
前2,3年繼續增強本身的技術功底,而後朝着項目經理(技術經理,產品經理)方面發展
2008年9月 2012年6月 下了火車打個車10來塊錢
(吹牛逼的活) 有一些賣衣服的 賣吃的 小超市 酒店什麼的....
養老保險,醫療保險,失業保險,工傷保險,生育險 住房公積金
60人左右 技術部 銷售部 行政部 人力資源部 財務部
ajax全稱是異步JavaScript及xml;
ajax的核心JavaScript中的xmlHttpRequest(XHR);
使用ajax能夠提升用戶的體驗度,進行異步數據傳輸從而提升性能。ajax不能跨域,所謂不能跨域就是不能跨多個網站(多個域名),不能跨多個項目能夠經過jsonp來解決ajax跨域的問題,而jsonp的實質就是經過動態添加script標籤來實現的
Ajax是默認沒有超時時間,若是咱們想要ajax超時在ajax中有一個timeout這個屬性設置它的時間是根據秒來設置
Ajax 異步是跳轉頁面加載一部分數據當點擊按鈕的時候加載另外一部分數據這樣的使用於大數據量的加載
Ajax同步 是跳轉頁面一會兒執行了說有的ajax請求加載了全部的數據這樣的若是在大量數據中頁面會卡
Ajax中有async屬性 async =」true」是同步flase是異步 默認的是異步
原生的ajax是xmlhttprequest
(主動說)
webservice是SOA(面向服務編程)的一種實現,
主要是用來實現異構平臺通訊也就
是不一樣平臺不一樣項目之間的數據傳輸,從而避免了信息孤島的問題,
它之因此可以
進行異構平臺通訊是由於它是徹底基於xml的,
因此說,webService是跨平臺,
跨語言,跨框架的,在java中一般有三種技術框架分別是xfire,cxf,axis2。
咱們爲了保證
webservice的安全性,採用了基於
WS-Security標準的安全驗證(使用回調函數)。
(不必主動說)
webservice的三要素分別是:
wsdl(webservice description language)
用來描述發佈的接口(服務)
soap(simple object access protocol)
是xml和http的結合,是webservice數據通訊的協議
uddi 用來管理,查詢webService的服務
(不必主動說)
webservice的具體三種實現方式(框架)或者三種實現框架的區別
1. Axis2:能夠用多種語言開發,
是一個重量級框架,功能很是強大,
可是它的性能比較低。
2. Xfire:它相比Axis2來講是一個輕量級框架,
它的性能要比Axis2高。
3. cxf:是Xfire的升級版,就比如是,
struts2是webwork的升級,
而後cxf和spring集成起來很是方便,簡易,
性能方面也要比Xfire高。
【注】jdk6 自帶的webservice jws
(主動說)
業務場景
我在之前作項目的時候,其中遇到一個功能,
須要進行兩個項目之間的數據的傳輸,
項目經理讓我去完成這個任務,我根據以往的項目經驗,
想到兩種解決方案,第一種
就是開放另一個項目的數據庫的權限給我,
而後我直接經過訪問另一個項目的數據
庫,來獲得須要的信息,但後來我分析了下,覺的這種方式不安全,
並且由於當時
這個項目是另一家公司負責在作,因此數據庫裏面的表結構,
以及之後牽涉
到的責任問題都不少,因此我就採用了第二種方案,
即經過webservices的方式,進行
異構系統之間數據信息的傳遞,webservices的具體實現,
有xfire,cxf,axis2,
我根據以往的項目經驗,瞭解到cxf是xfire的升級版本,適用於java語言,
xfire/cxf 性能比axis2要高,而且和spring整合起來也比較方便,
而axis2支持更多的語言,
性能相對於cxf要低,經過上面分析,
結合咱們目前的兩個項目都是基於java
語言的,因此我採用cxf這種方式實現了兩個項目之間數據的傳遞,
咱們爲了保證
webservice的安全性咱們採用了基於
WS-Security標準的安全驗證(使用CXF回調函數)。
(不必主動說)
webservice服務端配置流程
首先在web.xml中引入cxfServlet核心類,
指定對以/cxf開頭的url路徑提供webservice服務,
以後咱們在要發佈成webservice接口上添加@Webservice 註解,
並且還要在實現類上添加一樣的webservice註解而且要說明實現了哪一個接口,
以後在spring-webservice.xml中發佈webservice服務,
經過jaxws:endpoint這個標籤,
而且在標籤配置implementor和address來代表實現服務的類,
以及發佈的地址,
最後在瀏覽器中輸入相關的webservice地址?wsdl來驗證服務是否發佈成功。
(不必主動說)
webservice客戶端的配置
首先經過wsdl2java根據發佈的webservice服務端地址的wsdl
生成客戶端調用的中間橋樑java類,
將生成的java類拷貝到客戶端項目中,
配置spring-client.xml文件,
經過jaxws:client定義一個bean,
並經過address屬性指明要訪問的webservice的服務地址,
經過serviceClass指明充當中間橋樑的服務類,以後獲取該bean,
就能夠經過它來訪問發佈的webservice接口中的方法。
負載均衡:
(瞭解)
咱們在作這個項目時,考慮到服務器性能的問題,最開始想到使用縱向擴展,來增長硬件的配置提升其性能,但這樣作比較耗費資金,並且服務器內存空間也是有限的;因此後來就使用橫向擴展來達到這一目的.
(主動說)
當時咱們使用nginx(n g 個 s)+3個tomcat進行負載均衡,在咱們不進行負載均衡以前,那全部的請求都由一臺tomcat進行處理,這樣會使咱們的tomcat所承受的壓力增大,而咱們進行負載均衡以後,一樣數量的請求通過nginx將其分發到多臺tomcat進行處理,從而下降每臺tomcat所承受的壓力,並且當其中一臺機器宕機時,其餘機器還能夠繼續提供服務,保證服務不間斷。
當時項目在部署完成後,遇到這麼個問題,用戶登陸輸入驗證碼的時候,明明驗證碼輸入的正確,但老是提醒說驗證碼不正確從而不能正常登陸,通過分析後發現有可能第一次
請求被髮送到t1上,那麼放在session中的驗證碼就被放到了t1上,當用戶輸入驗證碼點擊登陸時,新發送的請求有可能被髮送到t2上面,這樣在進行對比時就確定會不一致從
而提示驗證碼輸入錯誤,後來我就考慮使用ip_hash這種負載均衡策略來代替默認的輪詢策略,雖然解決了驗證碼錯誤問題,可是在後續的測試中發現若是用戶在使用過程當中
忽然一臺服務器宕機了,那麼由於session在這臺服務器上存儲着,因此就會提示用戶從新登陸,這樣使用戶的體驗度很是很差,最後就經過將session信息保存到redis服務器中從而在
多臺web服務器中實現session共享,這樣就解決了上面所說的那些問題。
怎麼避免nginx產生單點故障(被動說)
同時咱們爲了不nginx的單點故障,達到高可用性,就在nginx的前面又加了一個F5,從而將請求分配給多個nginx,再經過nginx分配給多個不一樣的Tomcat。這樣大大的提升了服務的有效性,而且進一步提升了性能。
1.Linux下常見的分支:
CentOS:服務端【純開源】
RedHat:服務器端【收費】
Ubantu:我的電腦
2.訪問方式:經過SSH/Putty客戶端鏈接服務器
3.如何使用:
1.虛擬機的好處?
能夠在虛擬機中隨意操做系統,不怕影響或損害電腦;
2.克隆(備份):快速建立當前系統的備份,快速建立另一個虛擬系統;
在manage 下的clone中
linked(連接克隆) 軟克隆 優勢:速度快,生成文件小;
full(完整克隆) 硬克隆 優勢:文件大,速度比較慢;
選擇橋接模式;
只查出四行 ping Ip -c 4
3.快照:能夠將當前的虛擬系統快速還原到某一時刻;都是一個虛擬系統。
快照 Snapshot 下的 Take Snapshot
快照的好處:埋下幾個點,方便還原
4.命令:
注意:
rpm是Linux下一種軟件安轉包的後綴名。如*。rpm ,等同於windows中的exe.rpm是一個命令,用來進行和軟件安裝相關的操做。(安轉,卸載,查找)
linux下沒有盤符的概念,它是經過相關的目錄來管理資源的。咱們一般在/home中建立文件夾來存放須要安轉的軟件
tab鍵自動補全 *表明當前目錄下的全部文件
JDK默認安裝在 usr/java中
設置jdk的環境變量:
修改/etc/profile文件
用文本編輯器打開 /etc/profile
在profile文件末尾加入:
export JAVA_HOME = /usr/java/jdk.1.7.0_79
export PATH = $JAVA_HOME/binL$PATH
source /etc/profile 使修改當即生效
echo $PATH 查看PATH值
1.ifconfig:查看IP地址
2.java -version :查jdk的版本
3.rpm -qa | grep 軟件的名稱 :查找和指定名稱相關的軟件
4.rpm -e --nodeps 軟件的名稱 :卸載指定的軟件
5.rpm -ivh 軟件名稱 :安裝指定的軟件
6.uname -a 查看Linux系統的基本信息(計算機名,操做位數,版本號)
7.LL 查看文件夾下的文件
8.mkdir 建立文件夾
9.vi文件名: 對指定的文件名進行編譯。
按i進入編輯模式,
按ESC鍵進入命令模式
:wq! 強制保存並退出
:q!強制退出(!是強制的意思)
10.pwd :查看當前目錄的完整路徑
11.unzip 文件名.zip :解壓後綴名爲zip的壓縮文件
zip 文件名.zip 要壓縮的文件
12.mv 源文件 目標文件名(mv能夠移動/重命名)
13.rm -rf 文件夾名 :遞歸強制刪除文件夾及其下的文件
14.service iptables stop 禁用防火牆
15.chmod +x *.sh :使全部的後綴名爲sh的文件,擁有可執行的權限
16.在bin目錄下 ./startup.sh 啓動tomcat
17.在bin目錄下經過tail -f ../logs/catalina.out 來查看啓動日誌 tail -n 300 ../logs/catalina.out 查看最後三百行的信息
18.cat 文件名:查看整個文件內容
19. ps -ef | grep 進程名:查看指定進程是否啓動
20.kill -9 進程號 :強制殺死進程
killall -9 進程名
21. find / -name 文件名 -print :查看指定文件的路徑
vi 在命令模式下 yy複製當前光標所在行
p粘貼
dd 刪除當前行
vi /etc/sysconfig/iptables 更改防火牆的配置文件,開放新的端口號
重啓防火牆 service iptables restart
查看當前防火牆的狀態 service iptables status
export JAVA_HOME = /usr/java/jdk.1.7.0_79
export PATH = $JAVA_HOME/binL$PATH
source /etc/profile 使修改當即生效
echo $PATH 查看PATH值
咱們在項目中的關係型數據庫採用的是MySQL,考慮到對事務的支持使用的是InnoDB引擎,爲了保證數據庫數據的安全,達到高可用性,以及分擔服務器壓力咱們對MySQL進行了主從複製的配置並結合MyCat這個數據庫中間件進行讀寫分離。咱們項目 目前採用的是一主帶2或者3從的架構。由於互聯網項目通常都是讀的多,寫的少,因此經過這種一主多從的架構分擔了單臺數據庫的壓力而且在一臺服務器宕機的狀況下也能保證項目的基本運行。
主從複製的配置比較簡單,最主要是開啓主服務器的二進制日誌並指明一個惟一的標識,從服務器也要指明一個惟一的標識,而且在主服務器上建立帳號,開啓複製權限;在主服務器上運行show master status查看主服務器的狀態,以後在從服務器上用剛纔創建的帳號鏈接指定的的主服務器,並指明要複製的二進制文件以及起始位置,最後運行start slave就能夠了,而後一般運行show slave status查看從服務器的狀態,若是slave_io和slave_sql爲yes,就證實配置成功了。
最主要就是主服務器上的二進制日誌以及從服務器上的IO線程,SQL線程,以及中繼日誌。主服務器將其自身的改變存入到二進制日誌中去,從服務器鏈接主服務器並經過IO線程讀取主服務器上的二進制日誌,將讀取的內容存入自身的中繼日誌,以後SQL線程會讀取中繼日誌中的sql語句對其進行執行,這樣就保證了從服務和主服務器的一致性。MySQL的主從複製默認是基於sql語句進行的。
60.MyCat概述?
1.需求分析
2.概要設計
3.詳細設計(用例圖,流程圖,類圖)
4.數據庫設計(powerdesigner)
5.代碼開發(編寫)
6.單元測試(junit 白盒測試)(開發人員)
svn版本管理工具(提交,更新代碼,文檔)
7.集成測試 (黑盒測試,loadrunner(編寫測試腳本)(高級測試))
8.上線試運行 (用戶本身體驗)
9.壓力測試(loadrunner)
10.正式上線
11.維護
62.httpClient
httpClient是一個支持http協議的客戶端編程工具包,咱們在java中調用httpClient是經過url模擬了一個http請求,這樣就能夠經過java代碼直接發送請求得到服務端響應數據,首先構建HttpClient,new DefaultHttpClient(); httpClient發送請求的方式也分紅兩種形式:一個 new httpGet(),一個是new httpPost() 把請求的url放進去,而後用excute發送請求,獲取響應信息,裏面包含狀態碼,成功爲200,包含響應內容,將內容轉換爲字符串,最後關閉鏈接,其中post請求是模擬表單提交完成的、不能傳遞參數
63.多線程
1.java中實現線程的方式
在java中實現線程有兩種方式:繼承Thread類,實現Runable接口,一個java main程序默認會開啓兩個線程一個是主線程,一個垃圾回收線程。
2.線程不安全與安全:
多個線程訪問同一個資源,致使結果和指望值不一樣,咱們就說它是 非線程安全的(線程不安全),反之咱們就說它是 線程安全的。
瞭解:
a.多個線程訪問同一個資源(這裏的資源一般指的是全局變量或者靜態變量),若是每次運行結果和單線程運行的結果是同樣的,就是線程安
全的。
b.線程安全問題都是由全局變量及靜態變量引發的。
c.若每一個線程中對全局變量、靜態變量只有讀操做,而無寫操做,通常來講,這個全局變量是線程安全的;
如有多個線程同時執行寫操做,通常都須要考慮線程同步,不然的話就可能影響線程安全。
3.線程的狀態
1、新建狀態(New):新建立了一個線程對象。
2、就緒狀態(Runnable):線程對象建立後,其餘線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。
3、運行狀態(Running):就緒狀態的線程獲取了CPU,執行程序代碼。
4、阻塞狀態(Blocked):阻塞狀態是線程由於某種緣由放棄CPU使用權,暫時中止運行。直到線程進入就緒狀態,纔有機會轉到運行狀態。阻塞的狀況分三種:
(一)、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。
(二)、同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池中。
(三)、其餘阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置爲阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。
5、死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期
瞭解:
1、線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable接口,但無論怎樣,當咱們new了這個對象後,線程就進入了初始
狀態;
2、當該對象調用了start()方法,就進入可運行狀態;
3、進入可運行狀態後,當該對象被操做系統選中,得到CPU時間片就會進入運行狀態;
4、進入運行狀態後狀況就比較複雜了
4.1、run()方法或main()方法結束後,線程就進入終止狀態;
4.2、當線程調用了自身的sleep()方法或其餘線程的join()方法,就會進入阻塞狀態(該狀態既中止當前線程,但並不釋放所佔有的資
源)。當sleep()結束或join()結束後,該線程進入可運行狀態,繼續等待OS分配時間片;
4.3、線程調用了yield()方法,意思是放棄當前得到的CPU時間片,回到可運行狀態,這時與其餘進程處於同等競爭狀態,O566S有可能會接
着又讓這個進程進入運行狀態;
4.4、當線程剛進入可運行狀態(注意,還沒運行),發現將要調用的資源被synchronized(同步),獲取不到鎖標記,將會當即進入鎖
池狀態,等待獲取鎖標記(這時的鎖池裏也許已經有了其餘線程在等待獲取鎖標記,這時它們處於隊列狀態,既先到先得),一旦線程獲
得鎖標記後,就轉入可運行狀態,等待OS分配CPU時間片;
4.5、當線程調用wait()方法後會進入等待隊列(進入這個狀態會釋放所佔有的全部資源,與阻塞狀態不一樣),進入這個狀態後,是不能自
動喚醒的,必須依靠其餘線程調用notify()或notifyAll()方法才能被喚醒(因爲notify()只是喚醒一個線程,但咱們由不能肯定具體喚醒的
是哪個線程,也許咱們須要喚醒的線程不可以被喚醒,所以在實際使用時,通常都用notifyAll()方法,喚醒有所線程),線程被喚醒後
會進入鎖池,等待獲取鎖標記。
補充:(wait和sleep的區別)
wait時會釋放鎖資源但sleep不會釋放鎖資源,wait一般和notify以及notifyAll結合使用,須要notify或者notifyAll對其進行喚醒,sleep一般在指定的時間內自動喚醒。
4.解決線程安全的問題的方案:
a.經過加鎖(synchronized)的方式解決線程安全問題
1.synchronized 方法
2.synchronized 塊(同步代碼塊)
b.避免使用全局變量
使用volitile 使用線程同步類
c.使用ThreadLocal(參考:http://blog.csdn.net/drifterj/article/details/7782706)
1. 爲多線程併發的互斥控制提供了另外一種全新的解決思路
2. 經過ThreadLocal爲其餘模塊的API傳遞參數
5.java線程池 (可參考:http://www.oschina.net/question/565065_86540)
1.減小了建立和銷燬線程的次數,
每一個線程均可以被重複利用,
可執行多個任務。
2.能夠根據系統的承受能力,
調整線程池中線程的數目,
防止由於消耗過多的內存,
而致使服務器宕機
(每一個線程須要大約1MB內存,線程開的越多,
消耗的內存也就越大,最後宕機)。
一般咱們使用的線程池是實現了ExecutorService的ThreadPoolExecutor。
6.死鎖
死鎖是由於多線程訪問共享資源,因爲訪問的順序不當所形成的,一般是一個線程鎖定了一個資源A,而又想去鎖定資源B;在另外一個線程
中,鎖定了資源B,而又想去鎖定資源A以完成自身的操做,兩個線程都想獲得對方的資源,而不肯釋放本身的資源,形成兩個線程都在等
待,而沒法執行的狀況。
死鎖產生的緣由:是由訪問共享資源順序不當所形成的.
簡單的說:所謂死鎖,是指兩個或兩個以上的線程在執行過程當中,因爭奪資源而形成的一種互相等待的現象,若無外力做用,它們都將沒法推動下去。
7.守護線程
在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程)
用個比較通俗的好比,任何一個守護線程都是整個JVM中全部非守護線程的保姆:
只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就所有工做;只有當最後一個非守護線程結束時,守護線程隨着JVM
一同結束工做。
Daemon的做用是爲其餘線程的運行提供便利服務,守護線程最典型的應用就是 GC (垃圾回收器),它就是一個很稱職的守護者。
User和Daemon二者幾乎沒有區別,惟一的不一樣之處就在於虛擬機的離開:若是 User Thread已經所有退出運行了,只剩下Daemon
Thread存在了,虛擬機也就退出了。 由於沒有了被守護者,Daemon也就沒有工做可作了,也就沒有繼續運行程序的必要了。
1.AOP是OOP(面向對象編程)的延續,是Aspect Oriented Programming的縮寫,意思是面向方面編程或者面向切面編程。AOP是基於代理模式來實現的。(23種設計模式:工廠模式、代理模式、單例模式、適配器模式、責任鏈模式、裝飾模式,模式的應用場景不是很明確,什麼場景用什麼模式都是能夠理解或解釋的。一個項目並非運用的模式越多,則表明項目更強大,反而顯得臃腫,複雜度提升了,從而影響代碼的效率、開發人員的開發效率,項目的維護成等)
2.AOP主要應用於日誌記錄,性能統計,安全控制,事務處理等方面。它的主要意圖就要將日誌記錄,性能統計,安全控制等等代碼從
核心代碼中清楚的劃分出來。
3.AOP代理能夠經過jdk動態代理實現,也能夠經過cglib實現,默認是經過jdk動態代理實現的。jdk動態代理須要接口的支持,若是沒有接口只有類,則使用cglib來實現。
jdk基於接口,cglib基於類
所謂代理設計模式:在代理模式中有個接口,接口中有個代理實現和一個真實實現,要用代理實現去表明真實實現。
1. 靜態代理:
一個接口,分別有一個真實實現和一個代理實現。靜態代理中,真實實現和代理實現都是實現了同一個接口,而且把真實實現做爲參數傳遞給代理實現去調用。
缺點:這種模式的代理類只能爲一個接口的對象進行代理,這便是靜態代理。要解決這樣的問題,能夠採用動態代理。
1. 動態代理(基於jdk的動態代理):
使用一個代理類即可以代理全部接口動態代理,經過代理類的代理,接口和實現類之間能夠不直接發生聯繫,而能夠在運行期(Runtime)實現動態關聯,代理實現 都須要實現InvocationHandler接口,這個時候咱們須要用到Proxy裏面 的newProxyInstance須要有三個參數1.實現類,2.接口3.當前對象
1.切面(Aspect): 由切點(PointCut)和通知(Advice)組成,它既包括橫切邏輯的定義,也包括了鏈接點的定義。
2.切點(Pointcut):一個切點定位多個類中的多個方法。(定義類或者方法的)
3.通知也叫加強(Advice):由方位和橫切邏輯構成,所謂的方位指的是前置通知,後置通知,返回後通知,環繞通知,拋出異常後通知
4.鏈接點(JoinPoint):由切點和方位構成,用來描述在在哪些類的指定方法以前或以後執行
方位:
<1>.前置通知(Before advice):在某鏈接點(join point)以前執行的通知,但這個通知不能阻止鏈接點前的執行(除非它拋出一個異
常)。
<2>.返回後通知(After returning advice):在某鏈接點(join point)正常完成後執行的通知:例如,一個方法沒有拋出任何異常,正常返回。
<3>.拋出異常後通知(After throwing advice):在方法拋出異常退出時執行的通知。
<4>後置通知(After (finally) advice):當某鏈接點退出的時候執行的通知(不管是正常返回仍是異常退出)。
<5>環繞通知(Around Advice):包圍一個鏈接點(join point)的通知,如方法調用。這是最強大的一種通知類型。
環繞通知能夠在方法調用先後完成自定義的行爲。它也會選擇是否繼續執行鏈接點或直接返回它們本身的返回值或拋出異常來結束執行
文件一般是由一連串的字節或字符構成,組成文件的字節序列稱爲字節流,組成文件的字符序列稱爲字符流。Java中根據流的方向能夠分爲輸入流和輸出流。輸入流是將文件或其它輸入設備的數據加載到內存的過程;輸出流偏偏相反,是將內存中的數據保存到文件或其餘輸出設備,詳見下圖:
文件是由字符或字節構成,那麼將文件加載到內存或再將文件輸出到文件,須要有輸入和輸出流的支持,那麼在Java語言中又把輸入和輸出流分爲了兩個,字節輸入和輸出流,字符輸入和輸出流,見下表:
InputStream是字節輸入流,InputStream是一個抽象類,全部繼承了InputStream的類都是字節輸入流,主要了解如下子類便可:
主要方法介紹:
void |
close() |
abstract int |
read() |
int |
read(byte[] b) |
int |
read(byte[] b, int off, int len) |
全部繼承了Reader都是字符輸如流
主要方法介紹
abstract void |
close() |
int |
read() |
int |
read(char[] cbuf) |
abstract int |
read(char[] cbuf, int off, int len) |
全部繼承了OutputStream都是字節輸出流
主要方法介紹
void |
close() |
void |
flush() |
void |
write(byte[] b) |
void |
write(byte[] b, int off, int len) |
abstract void |
write(int b) |
示例代碼:
全部繼承了Writer都是字符輸出流
主要方法介紹
Writer |
append(char c) |
abstract void |
close() |
abstract void |
flush() |
void |
write(char[] cbuf) |
abstract void |
write(char[] cbuf, int off, int len) |
void |
write(int c) |
void |
write(String str) |
void |
write(String str, int off, int len) |
緩衝流主要是爲了提升效率而存在的,減小物理讀取次數,緩衝流主要有:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter,而且BufferedReader提供了實用方法readLine(),能夠直接讀取一行,BuffereWriter提供了newLine()能夠寫換行符。
67.從數組中獲取到最大的數據?
方式有不少
(遞歸)
經過先取出數組中的第一個值 而後用for依次循環是數組中的值是否大於第一個值若是大於第一個值 取出在用for循環 循環之後的值 按照這種方式找到數組中最大的值
工做流2.0的定義是:實現工做過程管理的自動化、智能化和整合化。工做流2.0最主要的特徵就是能夠靈便的實現數據整合和數據統計,消除信息孤島,既能實現OA辦公系統內部工做流之間的數據整合,如借款與報銷、預算與決算等,又能實現OA辦公系統工做流與其餘業務系統之間的數據整合,如HR、ERP、CRM等。工做流2.0能完全的彌補工做流1.0的不足,它不但實現OA辦公系統內部的數據整合,也實現OA辦公系統和第三方應用系統之間的數據整合。
若是給工做流1.0打上標籤的話,那就是「無紙化、重複工做、流程孤島、系統孤島、數據孤島」;工做流2.0對應的即是「智能化、效率質量提高、外部數據整合、消除信息孤島、內部數據整合」。毫無疑問,工做流2.0更加智能,更加整合,可以實現數據的同步交換和共享的特徵更受用戶歡迎,能有效幫助企業簡化多餘流程,是將來工做流技術發展的方向。
69.
JVM -- java virtual machine
JVM就是咱們常說的java虛擬機,它是整個java實現跨平臺的 最核心的部分,全部的java程序會首先被編譯爲.class的類文件,這種類文件可 以在虛擬機上執行,也就是說class並不直接與機器的操做系統相對應,而是通過虛擬機間接與操做系統交互,由虛擬機將程序解 釋給本地系統執行。
JVM 是 Java 平臺的基礎,和實際的機器同樣,它也有本身的指令集,而且在運行 時操做不一樣的內存區域。 JVM 經過抽象操做系統和 CPU 結構,提供了一種與平臺無關的代碼執行方法,即與特殊的實現方 法、主機硬件、主機操做系統無關。可是在一些小的方面, JVM 的實現也是互不相同的,好比垃圾回收 算法,線程調度算法(可能不一樣 OS 有不一樣的實現)。
JVM 的主要工做是解釋本身的指令集(即字節碼)到 CPU 的指令集或 OS 的系統調用,保護用戶免被惡意程序騷擾。 JVM 對上層的 Java 源文件是不關心的,它關注的只是由源文件生成的類文件( class file )。類文件的 組成包括 JVM 指令集,符號表以及一些補助信息。
JRE -- java runtime environment
JRE是指java運行環境。光有JVM還不能成class的 執行,由於在解釋class的時候JVM須要調用解釋所須要的類庫lib。 在JDK的安裝目 錄裏你能夠找到jre目錄,裏面有兩個文件夾bin和lib,在 這裏能夠認爲bin裏的就是jvm,lib中則是jvm工 做所須要的類庫,而jvm和 lib和起來就稱爲jre。因此,在你寫完java程序編譯成.class以後,你能夠把這個.class文件 和jre一塊兒打包發給朋友,這樣你的朋友就 能夠運行你寫程序了。(jre裏有運行.class的java.exe)
JRE 是 Sun 公司發佈的一個更大的系統,它裏面就有一個 JVM 。 JRE 就與具體的 CPU 結構和操做系統有關,咱們從 Sun 下載 JRE 的時候就看到了不一樣的各類版本。同 JVM 一塊兒組成 JRE 的還有一些 API (如 awt , swing 等)。 JRE 是運行 Java 程序必不可少的。
JRE ( Java Runtime Environment ),是運行 Java 程序必不可少的(除非用其餘一些編譯環境編譯成.exe可執行文件……),JRE的 地位就象一臺PC機同樣,咱們寫好的Win32應用程序須要操做系統幫 咱們運行,一樣的,咱們編寫的Java程序也必需要JRE才能運行。
JRE裏面有一個 JVM , JRE 與具體的 CPU 結構和操做系統有關,咱們從 Sun 下載 JRE 的時候就看到了不一樣的各類版本,,同 JVM 一塊兒組成 JRE 的還有 一些 API (如 awt , swing 等), JRE 是 運行 Java 程序必不可少的.
JDK -- java development kit
JDK是java開發工具包,基本上每一個學java的人都會先在機器 上裝一個JDK,那他都包含哪幾部分呢?讓咱們看一下JDK的安裝目錄。在目錄下面有 六個文件夾、一個src類庫源碼壓縮包、和其餘幾個聲明文件。其中,真正在運行java時起做用的 是如下四個文件夾:bin、include、lib、 jre。如今咱們能夠看出這樣一個關係,JDK包含JRE,而JRE包 含JVM。
bin:最主要的是編譯器(javac.exe)
include:java和JVM交互用的頭文件
lib:類庫
jre:java運行環境
(注意:這裏的bin、lib文件夾和jre裏的bin、lib是 不一樣的)總的來講JDK是用於java程序的開發,而jre則 是隻能運行class而沒有編譯的功能。
eclipse、idea等 其餘IDE有本身的編譯器而不是用JDK bin目錄中自帶的,因此在安裝時你會發現他們只要求你 選中jre路徑就ok了。
三者聯繫
Java 喊出的帶有標誌性的口號「 Write Once , Run Anywhere (一次編寫,處處運行)」,正是創建在 JRE 的基礎之上。何以實現?就是在 Java 應用程序和操做系統之間增長了一虛擬層—— JRE 。
程序源代碼不是直 接編譯、連接成機器代碼,而是先轉化到字節碼( bytecode ) 這種特殊的中間形式,字節碼再轉換成機器碼或系統調用。前者是傳統的編譯方法,生成的機器代碼就不可避免地跟特殊的操做系統和特殊的機器結構相關。
而 Java 程序的字節碼文件能夠放到任意裝有 JRE 的計算機運行,再由不一樣 JRE 的將它們轉化成相應的機器代碼,這就實現了 Java 程序的可移植性。這樣程序員也不用去 關心程序運行的具體環境,而能夠專心編寫軟件。這種分層抽象、隱藏細節的思想在計算機科學中到處可見,好比機器組織結構的設計、網絡協議的實現等。 Pascal 語言的發明者 Niklaus Wirth ,就富有預見性地指出應該有這樣一種可移植的語言,其生成的中間代碼能夠在一臺假想的機器( a hypothetical machine )上運行。
而 Java 虛擬機( Java virtual machine 或 JVM )就是這樣的一臺機器,它模擬實際處理器的結構,解釋字節碼。 怎麼一會說是 JRE ,一下子又成了 JVM ,二者是否同物不一樣名? 回答是否認的。
JRE的地位就象一臺PC機同樣,咱們寫好的Win32應用程序須要操做系統幫 咱們運行,一樣的,咱們編寫的Java程序也必需要JRE才能運行。
要運行Applet,在客戶端必須安裝有 JRE,即「運行時」,容易一點理解,就象所謂的「插件」,要開發JAVA應用程序\Web應用,就必須在服務器端安裝相應的 JVM+JDK 了(開發應用 Java web應用 時,客戶端不須要安裝任何的JVM)
若是你使用JAVA開發應用,就須要安裝 JRE+JDK,就是 J2SE.
若是在客戶端運行Applet,客戶端瀏覽器必須嵌有JAVA JVM,若是沒有,就須要安裝,即: 在客戶端建立JRE(運行時,包含JVM),而客戶端是不須要作開發的,因此,JDK就沒有必要安裝 了。
不一樣版本的Applet在不一樣的JVM下可能沒法正常運行,而Microsoft JVM只是Sun JVM的「低版本」,微軟在windows xp/2003中乾脆將JVM去掉了.
StringBuilder和StringBuffer都是可變字符串,前者線程不安全,後者線程安全。
StringBuilder和StringBuffer的大部分方法均調用父類AbstractStringBuilder的實現。其擴容機制首先是把容量變爲原來容量的2倍加2。最大容量是Integer.MAX_VALUE,也就是0x7fffffff。Rr54
StringBuilder和StringBuffer的默認容量都是16,最好預先估計好字符串的大小避免擴容帶來的時間消耗。
由於string是不可變的,因此絕對安全。StringBuilder實際上自身維護一個char[]數組,append是沒有synchronized。StringBuffer的append等不少操做都是帶有synchronized的,因此一樣線程安全。
因此單線程字符串拼接通常採用StringBuilder,效率高。多線程環境則採用Stringbuffer,雖然安全,可是相對效率會低些。
StringBuffer 類被final 修飾因此不能繼承沒有子類
2、StringBuffer 對象是可變對象,由於父類的 value [] char 沒有被final修飾因此能夠進行引用的改變,並且還提供了方法能夠修改被引用對象的內容即修改了數組內容。
3、在使用StringBuffer對象的時候儘可能指定大小這樣會減小擴容的次數,也就是會減小建立字符數組對象的次數和數據複製的次數,固然效率也會提高。存儲過程
攔截器:須要門寫一個普通類,繼承interceptorAdapter,裏面定義一個Adapter方法,咱們那會兒怎麼實現的呢,就是說當用戶登錄成功之後,我都會把它登錄後的信息放到session裏面,而後咱們取的時候能夠直接用看session裏面有沒有信息,若是有證實用戶已經登錄了,就讓他繼續執行,若是沒有信息springMVC裏面的response.send redrecte這個方法讓它重定向到登錄頁面,還需在配置文件裏面配置相應的標籤,標籤裏面有兩個屬性:1,path(就是攔截器須要攔截的路徑),而後就是引入我們的定義的攔截器類,這也就簡單實現e4我們攔截器這樣一個功能。
mybatis 是持久層它是ORM的一個實現,它是半自動化的框架,相比hibernate它的執行效率更高,它能夠直接經過寫sql這種方式來操做數據庫,而且對sql的優化也比較方便,hibernate呢它是對jdbc的高度封裝,因此對sql優化方面比較欠缺,在使用的時候呢,在它的配置文件裏面的namespacse與我們的接口進行匹配,像裏面的resultMap(返回值集合)resultType(返回對象) parameterType(參數類型對象)parameterMap(參數集合)
服務端:
1.提供json視圖/xml視圖
2.提供jsonp方式的數據
3.webservice[服務端]
客戶端:
1.ajax【jsonp】
2.httpclient
3.webservice[客戶端]
webservice用於傳統的企業[非互聯網企業]【CXF】
SOA[面向服務編程][思想/理念]
webservice[實現方式]
xfire[技術框架]
cxf
axis2【不少公司】【掌握】
解決了 信息孤島 的問題
跨語言,跨平臺。
webService的三要素
1.wsdl(webservie描述語言):描述發佈接口的信息
2.soap(簡單對象訪問協議)(webservice使用的協議):http+xml
3.uddi(查詢和管理webservice)
cxf:
服務端的配置:
1.在web.xml中經過cxfServlet這個核心類對指定的url進行攔截
2.經過在接口上加入@webservice的註解
3.經過配置spring-cxf-server.xml這個配置文件進行接口的發佈
4.在地址欄輸入http://ip地址:端口號/項目名/web.xml中配置的servlet的url-pattern/spring-cxf-
server.xml中發佈的接口的address?wsdl。【驗證】
客戶端的配置:【多種實現方式】【wsdl2java來生成客戶端】【導入jar包】
1.配置環境變量 path=D:\java\apache-cxf-2.7.18\bin
2.wsdl2java -p 包名 -d 目標路徑 服務器生成的接口路徑
3.經過spring-cxf-client.xml來配置客戶端
4.驗證客戶端代碼以及服務端【單元測試】
簡介
以前jsp-->controller-->service-->dao
webservice改變:
服務端:service-->dao
客戶端:jsp-->controller-->遠程service
httpclient/json視圖 改變:
服務端:controller-->service-->dao
客戶端:jsp-->controller-->service-->經過httpclient調用遠程的json視圖
ajax jsonp 改變:
服務端:controller-->service-->dao
客戶端:jsp-->ajax jsonp