客戶端發起http請求,web服務器將請求發送到servlet容器,servlet容器解析url並根據web.xml找到相對應的servlet,並將request、response對象傳遞給找到的servlet,java
servlet根據request就知道誰發出的請求、請求信息以及其餘信息,當servlet處理完業務邏輯後會將信息放入到response,並響應客戶端;web
SpringMVC是有DispatchServlet爲核心的分層控制框架,首先客戶端發出一個請求,web服務器解析請求的url並匹配DispatchServlet的映射url,若是匹配的上就將這個請求放入到DispatchServlet,面試
DispatchServlet根據mapping映射配置去尋找相對應的Handle,而後把處理權給找到的Handle,Handle封裝了處理業務邏輯的代碼,當Handle處理完後會返回一個邏輯視圖ModelAndView給DispatchServlet,sql
此時ModelAndView是一個邏輯試圖不是一個正式試圖,因此DispatchServlet會經過ViewResource視圖資源去解析ModelAndView,而後將解析後的參數放到View中返回到客戶端並展示;數據庫
單例模式核心只要new一個實例對象的模式;好比數據庫的鏈接,在線人數統計等;apache
一些網站上的在線人數統計就是經過單例模式實現的,把一個計時器放在數據庫或者內存中,當有人登陸的時候取出來加一而後再放回去;可是當有兩我的同時登陸的時候,會出現同時取出計時器,同時加一,編程
同時放回去,這樣就的話數據就會出錯,因此咱們須要一個全局變量給所有人用,只須要new出一個實例對象,這就是單例模式應用,而且單例模式節省資源,由於它控制這實例對象的個數,有利於GC回收;後端
策略模式就是將幾個類中公共的方法提取到一個新的類中,從而使擴展更容易,保證代碼的可移植性,可維護性強;設計模式
好比有一個需求是寫鴨子對象,鴨子有叫、飛、外形這三種方法;若是每一個鴨子類都寫這三個方法,會出現代碼冗餘;這時候咱們能夠把鴨子的叫、飛、外形這三個方法提取出來,放到鴨父類中,讓每一個鴨子都繼承這個鴨父類,重寫這三個方法,這樣封裝的代碼可移植性強;數組
當客戶提出新的需求,好比鴨子會游泳,那麼咱們只要在鴨父類中,添加游泳方法,便可使使得全部的鴨子會游泳,讓會游泳的鴨子從新鴨父類的游泳方法便可;
簡單的工廠模式主要是統一提供對象實例的引用,經過工廠模式接口獲取實例對象的引用。
好比一個登陸功能,後端有三個類:Controller類、Interface類、實現接口的實現類;當客戶端發出一個請求,當請求傳送到Controller類中時,Controller類獲取接口的引用對象,而實現接口的實現類的實現類中封裝好的登陸業務邏輯代碼。當你須要加一個註冊需求的時候,只須要在接口中增長一個註冊方法,實現類中實現方法,Controller類獲取接口的引用對象便可,不須要改動原來的代碼,實現可拓展性強;
public static void mp(int a[]){ int swap = 0; for(int i=0;i<a.length;i++){ for(int j=i;j<a.lenrth;j++){ if(a[j]>a[i]){ swap = a[j]; a[j] = a[i]; a[i] = swap; } } } System.out.println(""+Arrays.toString(a)); }
//a[]是一個升序的數值數組 public static int ef(int a[],int tag){ int first = 0; int end = a.length; for(int i=0;i<a.length;i++){ int middle = (first + end)/2; if(tag = a[middle]){ return middle; } if(tag > a[niddle]){ first = middle + 1; } if(tag < a[middle]){ end = middle -1; } } return 0; }
Ajax爲異步請求,局部刷新技術;
在傳統的頁面中,用戶須要點擊按鈕或者事件觸發請求來實現頁面的刷新;而異步技術不須要用戶點擊便可觸發事件,這樣使得用戶體驗感加強;
好比商城的購物車的異步加載,當你點擊商品時無需請求後臺而直接動態修改參數;
(1)父類靜態代碼塊
(2)子類靜態代碼塊
(3)父類構造方法
(4)子類構造方法
(5)子類普通方法
(6)重寫父類的方法(重寫後的方法)
(1)內部類能夠直接調用外部類包括private類,使用外部類引用的this關鍵字調用便可;
(2)外部類調用內部類須要創建內部類對象;
(1)一個進程是一個獨立的運行環境,能夠看做是一個程序;而線程能夠看做是進程的一個任務;好比QQ是一個進程,一個QQ窗口是一個線程;
(2)在多線程程序中,多線程併發能夠提升程序的效率,CPU不會由於某個線程等待資源而進入空閒狀態,它會把資源讓給其餘的線程;
(3)用戶線程就是咱們開發程序時建立的線程,而守護線程爲系統進程,如JVM虛擬中的GC;
(4)線程的有限級別:每個線程都有優先級別,有限級別高的能夠先獲取CPU資源使該線程從就緒狀態轉爲運行狀態;也能夠自定義有限級別;
(5)死鎖:至少兩個以上線程爭奪兩個以上CPU資源,避免死鎖就避免使用嵌套鎖,只須要在他們須要同步的地方加鎖和無限等待;
(1)AOP:面向切面編程,主要是管理系統層的業務,好比日誌、權限、事物等;
AOP是將封裝好的對象剖開,找出其中對多個對象產生的影響的公共行爲,並將其封裝爲一個可重用的模塊,這個模塊命名爲切面(Aspect);
切面將那些與業務邏輯無關的,卻被業務模塊共同調用的邏輯提取並封裝起來,減小了系統中的重複代碼,下降了模塊的耦合度,同時提升了系統的可維護性;
(2)IOC:Spring是開源框架,使用框架能夠減小咱們的工做量,提升工做效率而且它是分層結構,即相對應的層處理相對應的業務邏輯,減小代碼的耦合度;而Spring的核心IOC控制反轉和AOP面向切面編程。
IOC控制反轉主要強調的是程序之間的關係是由容器控制的;容器控制對象,控制了對外部資源的獲取;
而反轉即爲,在傳統的編程中都是由咱們建立對象獲取依賴對象,正式容器幫咱們查找和注入對象,對象是被獲取,因此叫反轉;
Hibernate的核心思想是ROM對象關係映射機制;它是將表與表之間的操做映射成對象與對象之間的操做;也就是從數據庫中提取的信息會自動按照你設置的映射要求封裝成待定的對象;因此Hibernate就是經過將數據庫表和實體類映射,使得對對象的修改即對數據對應的行進行修改;
Struts2是一個兼容Struts1和WebWork的MVC框架;
二者的區別:
(1)Action類
(2)線程模式
(3)Servlet依賴
(4)可測性
(5)捕獲輸入
(7)表達式語言
(8)綁定值到頁面(view)
(9)類型轉換
(10)校驗
(11)Action執行控制
//String.replace()方法用法 String b = "abcabcabc"; b=b.replace("b","");
兩者都是實現List接口的列表;Arraylist是基於數組的數據結構,Linkedlist是基於鏈表的數據結構;
當獲取特定元素時,Arraylist效率比較快,它經過數組小標便可獲取;而Linkedlist須要移動指針;
當存儲和刪除元素時,Linkedlist效率快,只須要將指針移動指定位置增長或者刪除便可;而Arraylist須要移動數據;
隨着開發團隊轉投Google Code旗下,ibatis3.x正式改名爲Mybatis;
Mybatis與Ibatis2.x區別:
(1)Mybatis實現了接口綁定(最重要的改進)
在Ibatis2.x中咱們須要在DAO的實現類中指定具體對應哪一個xml映射文件,而Mybatis實現了DAO接口與xml映射文件的綁定,自動爲咱們生成接口的具體實現,使用起來變得更加省事和方便。
注意: 雖然Mybatis支持在接口中直接使用annotation的配置方式來簡化配置,不過強烈建議仍然使用xml配置的方式。畢竟annotation的配置方式功能有限且代碼入侵性太強。使用xml配置方式才能體現出Mybatis的優點所在;
(2)對象關係映射的改進(效率更高)
在使用ibatis2.x的朋友並無經過ibatis的xml映射文件來實現對象間的關係映射。其實也確實沒有必要那麼作,由於ibatis2.x採用的是「嵌套查詢」的方式將對象之間的關係經過查詢語句的直接拼裝來實現,其效果和在DAO或Service中自行封裝是同樣的。
不過這種方式存在「N+1查詢問題」。
歸納地講,N+1查詢問題能夠是這樣引發的:
你執行了一個單獨的SQL語句來獲取結果列表(就是+1)。
對返回的每條記錄,你執行了一個查詢語句來爲每一個加載細節(就是N)。
這個問題會致使成百上千的SQL語句被執行。這一般不是指望的。
而在Mybatis中,除了兼容ibatis2.x中的「嵌套查詢」方式外,還提供了直接「嵌套結果」的方式,其效果至關於直接經過一句sql將查詢出的dto對象自動封裝成所需的對象。
不過實際上這一改進所帶來的好處也是頗有限的。由於這一方式在使用分頁的時候並不起做用,或者說嵌套對象的結果集是不容許進行分頁的。這一點在Mybatis框架中已經作出了明確的限制org.apache.ibatis.executor.resultset.NestedResultSetHandler裏34行),而實際項目中須要分頁的狀況又特別多……
仔細一想,一對多映射確實不能經過配置文件來分頁,由於這時查詢出的記錄數並不等於實際返回對象的size,不過一對一映射爲何也不容許就不太明白了。多是由於一對一是一對多的特例,而在設計框架的時候並無考慮去處理或是難於處理這一特例吧。
(3)MyBatis採用功能強大的基於OGNL的表達式來消除其餘元素
MyBatis採用OGNL表達式簡化了配置文件的複雜性,使用起來更簡潔。
(1)選擇合適的字段,好比郵箱字段能夠設爲char(6),儘可能把字段設置爲not null,這樣查詢的時候數據庫就不須要比較null值
(2)使用關聯查詢( left join on)查詢代替子查詢
(3)使用union聯合查詢手動建立臨時表
(4)開啓事物,當數據庫執行多條語句出現錯誤時,事物會回滾,能夠維護數據庫的完整性
(5)使用外鍵,事物能夠維護數據的完整性可是它卻不能保證數據的關聯性,使用外鍵能夠保證數據的關聯性
(6)使用索引,索引是提升數據庫性能的經常使用方法,它能夠令數據庫服務器以比沒有索引快的多的速度檢索特定的行,特別是對於max,min,order by查詢時,效果更明顯
(7)優化的查詢語句,絕大多數狀況下,使用索引能夠提升查詢的速度,但若是sql語句使用不恰當的話,索引沒法發揮它的特性。
(1)內存優化:主要是對Tomcat啓動參數進行優化,咱們能夠在Tomcat啓動腳本中修改它的最大內存數等等。
(2)線程數優化:Tomcat的併發鏈接參數,主要在Tomcat配置文件中server.xml中配置,好比修改最小空閒鏈接線程數,用於提升系統處理性能等等。
(3)優化緩存:打開壓縮功能,修改參數,好比壓縮的輸出內容大小默認爲2KB,能夠適當的修改。
(1)經常使用的請求方法有get、post
(2)Get與post的區別:傳送數據,get攜帶參數與訪問地址傳送,用戶能夠看見,這的話信息會不安全,致使信息泄露。而post則將字段與對應值封裝在實體中傳送,這個過程用戶是不可見的。Get傳遞參數有限制,而post無限制。
(1)TCP協議:面向鏈接(如打電話須要先撥號鏈接);
UDP協議:無鏈接,即發送數據以前不須要先創建鏈接;
(2)TCP協議:提供可靠的服務,即經過TCP傳輸的數據,無差錯,不丟失,不重複,且按序到達;
UDP協議:盡最大努力交付,即不保證可靠交付;
(3)TCP協議:TCP面向字節流,其實是TCP把數據看出一串無結構的字節流;
UDP協議:UDP是面向報文的,UDP沒有擁塞控制,所以網絡出現擁塞不會使源主機的發送速率下降(對實時應用頗有用,如IP電話、視頻會議等);
(4)TCP協議:每一條TCP鏈接只能點到點;
UDP協議:UDP支持一對1、一對多、多對1、多對多的交互通信;
(5)TCP協議:TCP首部開銷20個字節;
UDP協議:UDP首部開銷8個字節;
(6)TCP協議:TCP的邏輯通訊信道是全雙工的可靠信道;
UDP協議:是不可靠信道;
(1)List接口:繼承Collection接口,有序元素集合,元素可重複;
<1> ArrayList類:實現List接口,基於數組的數據結構,適合查詢,不適合增刪;
<2> LinkedList類:實現List接口,基於鏈表的數據結構(底層是雙向循環鏈表),適合增刪,不適合查詢;
<3> Vector類:實現List接口;
① Stack類:繼承Vector類;
(2)Set接口:繼承Collection接口,無序元素集合,元素不可重複;
<1> HashSet類:實現Set接口,根據對象的哈希值肯定元素在集合中的位置;
<2> SortedSet類:實現Set接口;
① TreeSet類:繼承SortedSet類,以二叉樹的方式存儲元素,實現對集合中的元素進行排序;
(1)hashMap類:實現Map接口,性能好;
(2)HashTable類:實現Map接口,線程安全;
(3)SortedMap類:實現Map接口,用於存儲鍵值的映射關係,不能出現重複的鍵(key);
① TreeMap類:繼承SortedMap類,用於存儲鍵值的映射關係,不能出現重複的鍵(key),全部的鍵按照二叉樹的方式排列;
java.util.Collection [I] |—java.util.List [I] |—java.util.ArrayList [C] |—java.util.LinkedList [C] |—java.util.Vector [C] |—java.util.Stack [C] |—java.util.Set [I] |—java.util.HashSet [C] |—java.util.SortedSet [I] |—java.util.TreeSet [C] java.util.Map [I] |—java.util.SortedMap [I] |—java.util.TreeMap [C] |—java.util.Hashtable [C] |—java.util.HashMap [C] |—java.util.LinkedHashMap [C] |—java.util.WeakHashMap [C]
遇到一個新的類時,首先會在方法區去找class文件,若是沒有找到就會去硬盤中找class文件,找到後返回將class文件加載到方法區中;在類加載的時候,靜態成員變量會被分配到方法區的靜態區域;非靜態成員變量分配到非靜態區;而後開始給靜態成員變量初始化,賦默認值;賦完默認值後,會根據靜態成員變量的書寫位置賦顯示值,而後執行靜態代碼;當全部的靜態代碼執行完,類加載纔算完成;
對象建立的過程:
(1)遇到一個新類時,會進行類加載,定位到class文件;
(2)對全部靜態成員變量初始化,靜態代碼塊也會執行,並且只在類加載的時候執行一次;
(3)NEW對象時,JVM會在堆中分配一個足夠大的存儲空間;
(4)存儲空間清空,爲全部的變量賦默認值,全部對象的引用賦值爲NULL;
(5)根據書寫的位置給變量一些初始化的操做;
(6)調用構造器方法(沒有繼承);
(1)設置參數,設置JVM的最大內存數;
(2)垃圾回收器的選擇;
(1)代碼層次:Java的同步鎖,典型的就是同步關鍵字Synchronized;
(2)數據庫層次:悲觀鎖和樂觀鎖;
<1> 悲觀鎖:是指對數據被外界(包括本系統當前的其餘事物,以及來自外部系統的事物處理)修改保持保守態度,所以,在整個數據處理過程當中,將數據處於鎖定狀態;
悲觀鎖的實現,每每依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,不然,即便在本系統中實現了加鎖機制,也沒法保證外部系統不會修改數據);
<2> 樂觀鎖:樂觀鎖機制採起了更加寬鬆的加鎖機制,大多數基於數據版本(Version)記錄機制實現;
樂觀鎖的實現,是將數據表增長一個字段版本(Version),對於不一樣的人員操做數據庫時,都會有個版本好1,2,3這樣的數字;
當數據庫接受更新數據的時候,會根據「提交數據版本大 於數據庫記錄當前版本」來判斷是否更新或者駁回的樂觀鎖策略;
因爲整個過程沒有對數據庫進行數據加鎖,因此大大提升了大併發量下的系統總體性能表現;
樂觀鎖機制每每基於系統中的數據存儲邏輯,所以有必定的侷限性(外部系統對數據的更新操做,咱們能夠採用將樂觀鎖策略在數據存儲過程當中實現來解決,開放存儲過程更新路徑,不直接開放數據表);
(3)常見案例
<1> 案例一:訂票系統,某航班只有一張機票,假定有1W人打開你的網站來訂票,問你如何解決併發問題(能夠擴展到任何高併發網站要考慮的並讀寫問題)
問題分析:a:1W人來訪問,票沒出去前要保證你們都能看到有票,不可能一我的在看到票的時候其餘人就都看不到了;到底誰能搶到,那得看網速;
b:併發問題,1W人同時點擊購買,到底誰能成交?總共就一張票;
解決方案:採用樂觀鎖;樂觀鎖是在不鎖表的狀況下,利用業務的控制來解決併發問題,這樣既保證了數據的併發可讀性又保證了數據的排他性,保證性能的同時解決了併發帶來的髒數據問題;
實現思路:Hibernate實現樂觀鎖;
前提:在表中增長一個冗餘字段,Version版本號,long類型;
原理:只有當前版本號>=數據庫版本號,才能提交;提交成功後,版本號Version++;
代碼:在ormpping增長一屬性optimistic-lock = "version"便可,
<hibernate-mapping>
<class name = "com.insigma.stock.ABC" optimistic-lock = "version" table = "T_Stock" schema = "STOCK">
</hibernate-mapping>
<2> 案例二:股票交易系統,銀行系統,大數據量你是如何考慮
問題分析:Oracle數據單張表達到100萬記錄後,查詢性能就不好;
解決方案:大數據量系統必須考慮表拆分(表名字不同,但結構徹底同樣)
a:按業務分:好比手機號的表,咱們能夠根據前3位數來拆分表;
b:利用Oracle的表拆分機制作分表;
c:若是是交易系統,咱們能夠考慮採用時間軸來拆分;
注意:還要考慮緩存:hibernate自己提供的一級二級緩存、內存緩存;
好比常常搜索的商品,將信息放在內存緩存中,能夠大大的提升性能;專業的獨立緩存框架memcached等,可獨立部署一個緩存服務器;
事物具備原子性、一致性、持久性、隔離性;
(1)原子性:是指一個事物中,要麼所有執行,要麼所有失敗回滾;
(2)一致性:事物執行以前和執行以後都出於一致性狀態;
(3)持久性:事物對數據的操做是永久性;
(4)隔離性:當一個事物正在對數據進行操做時,另外一個事物是不能夠對數據進行操做,也就是多個事物之間是相互隔離的;
(1)客戶端發出一個請求到servlet容器;
(2)請求通過一些列過濾FilterDispatch調用,FilterDispatch經過ActionMapper去找相對應的Action;
(3)ActionMapper找到相對應的Action返回給FilteDispatch,Dispatch把處理權交給ActionProxy
(4)ActionProxy經過配置文件找到對應的Action類;
(5)ActionProxy建立一個ActionLinvocation的實例處理業務邏輯;
(6)Action處理完畢,ActionInocation負責根據struts.xml的配置找到對應的返回結果(返回結果一般是Jsp頁面);