總結了一套比較新的面試題挺全面的,多方面都有涉及到

一、數據庫左鏈接右鏈接html

1.內聯接(典型的聯接運算,使用像 = 或 <> 之類的比較運算符)。包括相等聯接和天然聯接。     
內聯接使用比較運算符根據每一個表共有的列的值匹配兩個表中的行。例如,檢索 students和courses表中學生標識號相同的全部行。   
 2.外聯接。外聯接能夠是左向外聯接、右向外聯接或完整外部聯接。     
在 FROM子句中指定外聯接時,能夠由下列幾組關鍵字中的一組指定:     前端

1)LEFT JOIN或LEFT OUTER JOIN     
左向外聯接的結果集包括LEFT OUTER子句中指定的左表的全部行,而不只僅是聯接列所匹配的行。若是左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的全部選擇列表列均爲空值。   java

2)RIGHT JOIN 或 RIGHT OUTER JOIN     
右向外聯接是左向外聯接的反向聯接。將返回右表的全部行。若是右表的某行在左表中沒有匹配行,則將爲左表返回空值。       
    3)FULL JOIN 或 FULL OUTER JOIN
完整外部聯接返回左表和右表中的全部行。當某行在另外一個表中沒有匹配行時,則另外一個表的選擇列表列包含空值。若是表之間有匹配行,則整個結果集行包含基表的數據值。   
 3、交叉聯接   
交叉聯接返回左表中的全部行,左表中的每一行與右表中的全部行組合。交叉聯接也稱做笛卡爾積。 node

 

二、IOC AOPmysql

IOC就是典型的工廠模式,經過sessionfactory去注入實例。git

AOP就是典型的代理模式的體現。程序員

代理模式是經常使用的java設計模式,他的特徵是代理類與委託類有一樣的接口,代理類主要負責爲委託類預處理消息、過濾消息、把消息轉發給委託類,以及過後處理消息等。代理類與委託類之間一般會存在關聯關係,一個代理類的對象與一個委託類的對象關聯,代理類的對象自己並不真正實現服務,而是經過調用委託類的對象的相關方法,來提供特定的服務。 web

spring的IoC容器是spring的核心,spring AOP是spring框架的重要組成部分。redis

在傳統的程序設計中,當調用者須要被調用者的協助時,一般由調用者來建立被調用者的實例。但在spring裏建立被調用者的工做再也不由調用者來完成,所以控制反轉(IoC);建立被調用者實例的工做一般由spring容器來完成,而後注入調用者,所以也被稱爲依賴注入(DI),依賴注入和控制反轉是同一個概念。算法

面向方面編程(AOP)是以另外一個角度來考慮程序結構,經過分析程序結構的關注點來完善面向對象編程(OOP)。OOP將應用程序分解成各個層次的對象,而AOP將程序分解成多個切面。spring AOP 只實現了方法級別的鏈接點,在J2EE應用中,AOP攔截到方法級別的操做就已經足夠。在spring中,將來使IoC方便地使用健壯、靈活的企業服務,須要利用spring AOP實現爲IoC和企業服務之間創建聯繫。
IOC:控制反轉也叫依賴注入。利用了工廠模式
將對象交給容器管理,你只須要在spring配置文件總配置相應的bean,以及設置相關的屬性,讓spring容器來生成類的實例對象以及管理對象。在spring容器啓動的時候,spring會把你在配置文件中配置的bean都初始化好,而後在你須要調用的時候,就把它已經初始化好的那些bean分配給你須要調用這些bean的類(假設這個類名是A),分配的方法就是調用A的setter方法來注入,而不須要你在A裏面new這些bean了。

AOP:面向切面編程。(Aspect-Oriented Programming)
AOP能夠說是對OOP的補充和完善。OOP引入封裝、繼承和多態性等概念來創建一種對象層次結構,用以模擬公共行爲的一個集合。當咱們須要爲分散的對象引入公共行爲的時候,OOP則顯得無能爲力。也就是說,OOP容許你定義從上到下的關係,但並不適合定義從左到右的關係。例如日誌功能。日誌代碼每每水平地散佈在全部對象層次中,而與它所散佈到的對象的核心功能毫無關係。在OOP設計中,它致使了大量代碼的重複,而不利於各個模塊的重用。
將程序中的交叉業務邏輯(好比安全,日誌,事務等),封裝成一個切面,而後注入到目標對象(具體業務邏輯)中去。

實現AOP的技術,主要分爲兩大類:一是採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;二是採用靜態織入的方式,引入特定的語法建立「方面」,從而使得編譯器能夠在編譯期間織入有關「方面」的代碼.

 

三、線程實現方式

1、繼承Thread類建立線程類

(1)定義Thread類的子類,並重寫該類的run方法,該run方法的方法體就表明了線程要完成的任務。所以把run()方法稱爲執行體。

(2)建立Thread子類的實例,即建立了線程對象。

(3)調用線程對象的start()方法來啓動該線程。

2、經過Runnable接口建立線程類

(1)定義runnable接口的實現類,並重寫該接口的run()方法,該run()方法的方法體一樣是該線程的線程執行體。

(2)建立 Runnable實現類的實例,並依此實例做爲Thread的target來建立Thread對象,該Thread對象纔是真正的線程對象。

(3)調用線程對象的start()方法來啓動該線程。

3、經過Callable和Future建立線程

(1)建立Callable接口的實現類,並實現call()方法,該call()方法將做爲線程執行體,而且有返回值。

(2)建立Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。

(3)使用FutureTask對象做爲Thread對象的target建立並啓動新線程。

(4)調用FutureTask對象的get()方法來得到子線程執行結束後的返回值

2、建立線程的三種方式的對比

採用實現Runnable、Callable接口的方式創見多線程時,優點是:

線程類只是實現了Runnable接口或Callable接口,還能夠繼承其餘類。

在這種方式下,多個線程能夠共享同一個target對象,因此很是適合多個相同線程來處理同一份資源的狀況,從而能夠將CPU、代碼和數據分開,造成清晰的模型,較好地體現了面向對象的思想。

劣勢是:

編程稍微複雜,若是要訪問當前線程,則必須使用Thread.currentThread()方法。

使用繼承Thread類的方式建立多線程時優點是:

編寫簡單,若是須要訪問當前線程,則無需使用Thread.currentThread()方法,直接使用this便可得到當前線程。

劣勢是:

線程類已經繼承了Thread類,因此不能再繼承其餘父類。

四、Spring

   Spring是一個開放源代碼的設計層面框架,他解決的是業務邏輯層和其餘各層的鬆耦合問題,所以它將面向接口的編程思想貫穿整個系統應用。Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson建立。簡單來講,Spring是一個分層的JavaSE/EEfull-stack(一站式) 輕量級開源框架。

spring 的優勢有:
1.下降了組件之間的耦合性 ,實現了軟件各層之間的解耦 
2.能夠使用容易提供的衆多服務,如事務管理,消息服務等 
3.容器提供單例模式支持 
4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能 
5.容器提供了衆多的輔助類,能加快應用的開發 
6.spring對於主流的應用框架提供了集成支持,如hibernate,JPA,Struts等 
7.spring屬於低侵入式設計,代碼的污染極低 
8.獨立於各類應用服務器 
9.spring的DI機制下降了業務對象替換的複雜性 
10.Spring的高度開放性,並不強制應用徹底依賴於Spring,開發者能夠自由選擇spring的部分或所有 

 

五、ActivityMQ引用場景

   ①.異步處理:用戶註冊後,須要發註冊郵件和註冊短信。傳統的作法有兩種 1.串行的方式;2.並行方式(通常是先發短信再發郵件,可是這裏能夠同時發)

     ②.應用解耦:在下單(下單和庫存)時庫存系統不能正常使用。也不影響正常下單,由於下單後,訂單系統寫入消息隊列就再也不關心其餘的後續操做了。實現訂單系統與庫存系統的應用解耦

     ③.流量削鋒:秒殺活動,通常會由於流量過大,致使流量暴增,應用掛掉。爲解決這個問題,通常須要在應用前端加入消息隊列。a、能夠控制活動的人數。b、能夠緩解短期內高流量壓垮應用

     ④.日誌處理:日誌處理是指將消息隊列用在日誌處理中,日誌採集客戶端,負責日誌數據採集,定時寫受寫入Kafka隊列

 ⑤.JMS消息服務:JMS(JAVA Message Service,java消息服務)API是一個消息服務的標準/規範,容許應用程序組件基於JavaEE平臺建立、發送、接收和讀取消息。它使分佈式通訊耦合度更低,消息服務更加可靠以及異步性。

 

六、數據庫事物

   事務(Transaction)是併發控制的基本單位。所謂的事務,它是一個操做序列,這些操做要麼都執行,要麼都不執行,它是一個不可分割的工做單位。

事務具備如下4個基本特徵。

 Atomic(原子性):事務中包含的操做被看作一個邏輯單元,這個邏輯單元中的操做要麼所有成功,要麼所有失敗。

●   Consistency(一致性):只有合法的數據能夠被寫入數據庫,不然事務應該將其回滾到最初狀態。

●   Isolation(隔離性):事務容許多個用戶對同一個數據進行併發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其餘並行事務的修改相互獨立。

●   Durability(持久性):事務結束後,事務處理的結果必須可以獲得固化。

2.事務的語句
 開始事物:BEGIN TRANSACTION
 提交事物:COMMIT TRANSACTION
 回滾事務:ROLLBACK TRANSACTION
3.事務的4個屬性
     ①原子性(Atomicity):事務中的全部元素做爲一個總體提交或回滾,事務的個元素是不可分的,事務是一個完整操做。
  ②一致性(Consistemcy):事物完成時,數據必須是一致的,也就是說,和事物開始以前,數據存儲中的數據處於一致狀態。保證數據的無損。
  ③隔離性(Isolation):對數據進行修改的多個事務是彼此隔離的。這代表事務必須是獨立的,不該該以任何方式以來於或影響其餘事務。
  ④持久性(Durability):事務完成以後,它對於系統的影響是永久的,該修改即便出現系統故障也將一直保留,真實的修改了數據庫

七、Solo配置

  

八、序列化方式

1、Java原生序列化

Java原生序列化方法即經過Java原生流(InputStream和OutputStream之間的轉化)的方式進行轉化。須要注意的是JavaBean實體類必須實現Serializable接口,不然沒法序列化。

2、Json序列化

Json序列化通常會使用jackson包,經過ObjectMapper類來進行一些操做,好比將對象轉化爲byte數組或者將json串轉化爲對象。如今的大多數公司都將json做爲服務器端返回的數據格式。好比調用一個服務器接口,一般的請求爲xxx.json?a=xxx&b=xxx的形式。

3、FastJson序列化

fastjson 是由阿里巴巴開發的一個性能很好的Java 語言實現的 Json解析器和生成器。特色:速度快,測試代表fastjson具備極快的性能,超越任其餘的Java json parser。功能強大,徹底支持java bean、集合、Map、日期、Enum,支持範型和自省。無依賴,可以直接運行在Java SE 5.0以上版本 支持Android。使用時候需引入FastJson第三方jar包

4、ProtoBuff序列化

ProtocolBuffer是一種輕便高效的結構化數據存儲格式,能夠用於結構化數據序列化。適合作數據存儲或 RPC 數據交換格式。可用於通信協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。

優勢:跨語言;序列化後數據佔用空間比JSON小,JSON有必定的格式,在數據量上還有能夠壓縮的空間。

缺點:它以二進制的方式存儲,沒法直接讀取編輯,除非你有 .proto 定義,不然沒法直接讀出 Protobuffer的任何內容。

九、Json

  • JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation)
  • JSON 是輕量級的文本數據交換格式
  • JSON 獨立於語言:JSON 使用 Javascript語法來描述數據對象,可是 JSON 仍然獨立於語言和平臺。JSON 解析器和 JSON 庫支持許多不一樣的編程語言。 目前很是多的動態(PHP,JSP,.NET)編程語言都支持JSON。
  • JSON 具備自我描述性,更易理解

與 XML 相同之處

  • JSON 是純文本
  • JSON 具備"自我描述性"(人類可讀)
  • JSON 具備層級結構(值中存在值)
  • JSON 可經過 JavaScript 進行解析
  • JSON 數據可以使用 AJAX 進行傳輸

與 XML 不一樣之處

  • 沒有結束標籤
  • 更短
  • 讀寫的速度更快
  • 可以使用內建的 JavaScript eval() 方法進行解析
  • 使用數組
  • 不使用保留字

十、     Angularjs

   AngularJS 使得開發現代的單一頁面應用程序(SPAs:Single Page Applications)變得更加容易。

  • AngularJS 把應用程序數據綁定到 HTML 元素。
  • AngularJS 能夠克隆和重複 HTML 元素。
  • AngularJS 能夠隱藏和顯示 HTML 元素。
  • AngularJS 能夠在 HTML 元素"背後"添加代碼。
  • AngularJS 支持輸入驗證。

十一、     Redis使用場景

1、顯示最新的項目列表

2、排行榜應用,取TOP N操做

3、刪除與過濾

4、按照用戶投票和時間排序

5、處理過時項目

6、計數

7、特定時間內的特定項目

8、查找某個值所在的區間(區間無重合) :(Sorted Set)

9、交集,並集,差集:(Set)

十二、     算法

一、算法概要      
  算法是用於計算、數據處理和自動推理使用的。算法主要是作精確計算和表示一個有限長列的有效方法。算法通常包含清晰定義的指令用於計算函數。基本上也屬於一種思考最簡潔的方式。 
二、算法特徵 
  算法主要包含五個特徵 
  2.一、有窮性; 
   是指算法必須能在執行有限個步驟後終止; 
  2.二、確切性; 
   算法的每個步驟必須有確切的定義; 
  2.三、輸入項; 
   一個算法輸入有0或多個輸入,以刻畫預算對象的初始狀況,所謂0就是初始化條件; 
  2.四、輸出項; 
   反饋對數據加工後的結果。沒有輸出的算法無心義。 
  2.五、可行性; 
    算法中執行的任何計算均可以分步驟進行,每一個步驟並在有限時間內完成。 
三、算法經常使用的設計模式 
  主要有十個設計模式 
  3.一、徹底遍歷法      
    在驗證一個問題集合時,且以驗證正確性和最優性的時候,就會採用徹底遍歷法。但在便利的過程當中就會消耗大量的內存。 
  3.二、不徹底遍歷法 
   當便利時佔用的內存空間特別龐大時,能夠使用不徹底遍歷法來實現。例如各類規則算法和搜索算法便是。 
  3.三、分治法 
   把一個問題分區成互相獨立的部分,分別求解。分治法的好處在

能夠並行計算。 

  分治法所能解決的問題通常具備如下幾個特徵: 
    (1) 該問題的規模縮小到必定的程度就能夠容易地解決; 
    (2) 該問題能夠分解爲若干個規模較小的相同問題,即該問題具備最優子結構性質; 
    (3) 利用該問題分解出的子問題的解能夠合併爲該問題的解; 
    (4) 該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。 
   3.四、動態規劃法 
    當問題總體的最優解是由局部最優解組成的時候,會常常採用這種規劃方法。用於求解包含重疊子問題的最優化問題的方法。 
   3.五、貪婪算法(也叫貪心算法) 
    常見的近似求解思路。當問題的總體最優解不是(或沒法證實是)由局部最優解組成,且對解的最優性沒有要求的時候,能夠採用的一種方法。 
   3.六、線性規則法 
    問題是目標函數和約束條件都是線性的最優化 
   3.七、簡併法 
    把一個問題經過邏輯或數學推理,簡化成與之等價或者近似的、相對簡單的模型,進而求解的方法。 
   3.八、窮舉法 
     窮舉法,或稱爲暴力破解法,其基本思路是:對於要解決的問題,列舉出它的全部可能的狀況,逐個判斷有哪些是符合問題所要求的條件,從而獲得問題的解。它也經常使用於對於密碼的破譯。 
   3.九、分枝界限法 
     分枝界限法是一個用途十分普遍的算法,運用這種算法的技巧性很強,不一樣類型的問題解法也各不相同。分支定界法的基本思想是對有約束條件的最優化問題的全部可行解(數目有限)空間進行搜索 
   3.十、回溯法 
     運用這種算法的技巧性很強,不一樣類型的問題解法也各不相同。分支定界法的基本思想是對有約束條件的最優化問題的全部可行解(數目有限)空間進行搜索

1三、     JAVA實現排序

  

最後總結一下:

穩定性:
   一、穩定:冒泡排序、插入排序、歸併排序和基數排序
   二、 不穩定:選擇排序、快速排序、希爾排序、堆排序
平均時間複雜度
  一、O(n^2):直接插入排序,簡單選擇排序,冒泡排序。
        二、在數據量特別大的時候,冒泡排序基本是最慢的。
  三、在數據規模較小時(9W內),直接插入排序,簡單選擇排序差很少。當數據較大時,冒泡排序算法的時間代價最高。性能爲O(n^2)的算法基本
上是相鄰元素進行比較,基本上都是穩定的。
  一、O(nlogn):快速排序,歸併排序,希爾排序,堆排序。
  二、其中,快排是最好的, 其次是歸併和希爾,但數據量特別大的時候,歸併排序很容易出現內存溢出的錯誤,如普通機器n>1000萬時。
空間複雜度
         一、O(1):冒泡排序、直接插入排序、二分插入排序、希爾排序、直接選擇排序、堆排序
         二、 O(n):歸併排序
         三、 O(nlog2n):快速排序
         四、O(rd+n):基數排序
排序算法的選擇
  一、數據規模較小
    (1)待排序列基本序的狀況下,能夠選擇直接插入排序;
    (2)對穩定性不做要求宜用簡單選擇排序,對穩定性有要求宜用插入或冒泡
  二、數據規模不是很大
    (1)徹底能夠用內存空間,序列雜亂無序,對穩定性沒有要求,快速排序,此時要付出log(N)的額外空間。
    (2)序列自己可能有序,對穩定性有要求,空間容許下,宜用歸併排序
   三、數據規模很大
        (1)對穩定性有求,則可考慮歸併排序。
        (2)對穩定性沒要求,能夠用快速排序。
  四、數組初始基本有序的時候,宜用直接插入排序,不然,能夠用希爾排序。

代碼的實現:

  1. package sort;  
  2.   
  3. /**   
  4.  * Package: sort   
  5.  *   
  6.  * File: JavaSorts.java    
  7.  *   
  8.  * Copyright @ 2015 Corpration Name   
  9.  *    
  10.  */  
  11. public class JavaSorts {  
  12.   
  13.     /** 
  14.      * 希爾排序 
  15.      * @param array 
  16.      */  
  17.     public static void ShellSort(int[] array){  
  18.         int d = array.length;  
  19.         do {  
  20.             d /= 2;   //設置增量,經過設置增量來進行分組,分組後,每一組內採用直接插入排序  
  21.             OneShell(array, d);//一個增量對應一趟希爾排序  
  22.         } while (d > 1);  
  23.     }  
  24.       
  25.     /** 
  26.      * 一趟希爾排序 
  27.      * @param array 
  28.      * @param d 
  29.      */  
  30.     public static void OneShell(int[] array,int d){  
  31.           
  32.         for (int i = 0; i < array.length - d; i++) {  
  33.             int temp = array[i+d]; //array[i+d]的拷貝,每一次插入操做因此插入的值  
  34.             if (array[i] > array[i + d]) {  
  35.                 int j = i;  
  36.                 //此時分組爲:j,j+d,j+2d,j+3d····,組內採用直接插入排序  
  37.                 while(j >= 0 && array[j] > temp){  
  38.                     array[j + d] = array[j];    //使用while循環尋找temp可以插入的位置,從右往左尋找,大於temp的日後移動  
  39.                     j -= d;  
  40.                 }  
  41.                 array[j + d] = temp;   //插入數據  
  42.             }  
  43.         }     
  44.     }  
  45.       
  46.     /** 
  47.      * 快速排序 
  48.      * @param array 
  49.      * @param l 
  50.      * @param r 
  51.      */  
  52.     public static void QuickSort(int[] array,int l,int r){  
  53.         if (l < r) {  
  54.             int i = l,j = r,temp = array[l];  
  55.             while(i < j){  
  56.                 while(i < j && array[j] > temp){  
  57.                     j--;         //從右邊開始尋找比temp小的數  
  58.                 }  
  59.                 if(i < j){  
  60.                     array[i++] = array[j]; //找到後,將這個數賦值到i位置上,而後i+1,由於下一輪尋找比temp大的數,從i+1位置開始  
  61.                 }  
  62.                 while(i < j && array[i] < temp){  
  63.                     i++;          //從左邊尋找比temp大的數  
  64.                 }  
  65.                 if(i < j){  
  66.                     array[j--] = array[i]; //找到後,將這個數賦值到j位置上,而後j-1,由於下一輪尋找比temp小的數從j-1位置開始  
  67.                 }  
  68.             }  
  69.             array[i] = temp;  //此時比temp小的數都移動到左邊,比temp大的數都移動到了右邊,最後將temp賦值到中間位置  
  70.               
  71.             QuickSort(array, l, i - 1); //對temp左邊的數進行遞歸  
  72.             QuickSort(array, i + 1, r); //對temp右邊的數進行遞歸  
  73.         }  
  74.     }  
  75.       
  76.     /** 
  77.      * 堆排序 
  78.      * @param array 
  79.      */  
  80.     public static void HeapSort(int[] array){  
  81.         for (int i = 0; i < array.length; i++) {  
  82.             BuildMaxHeap(array, array.length - 1 - i);  
  83.             Swap(array, 0, array.length - 1 - i);  
  84.         }  
  85.     }  
  86.     /** 
  87.      * 建立最大堆 
  88.      * @param array 
  89.      * @param lastOneIndex 
  90.      */  
  91.     public static void BuildMaxHeap(int[] array,int lastOneIndex){  
  92.           
  93.         for (int i = (lastOneIndex - 1)/2; i >= 0; i--) {  
  94.             int k = i;  
  95.             while(2*k + 1 <= lastOneIndex){  
  96.                 int bigIndex = 2*k + 1;   //bigIndex用於記錄一個節點樹中最大數的索引  
  97.                 if (bigIndex < lastOneIndex) {  //知足這個條件,說明堆中有array[2*k+2]這個節點  
  98.                     if (array[bigIndex] < array[bigIndex + 1]) {  
  99.                         bigIndex++;      //若知足這個條件,說明k節點下的右子節點大於左子結點,於是bigIndex加1  
  100.                     }  
  101.                 }  
  102.                   
  103.                 if (array[k] < array[bigIndex]) {  
  104.                     Swap(array, bigIndex, k); //若k節點小於它其中一個子節點,則與這個子節點交換值  
  105.                     k = bigIndex;  //交換完值後,此時k節點下面的bigIndex節點可能不知足堆的性質,因此賦值給k,從新進入下一輪while循環  
  106.                 }else {  
  107.                     break;//若k節點知足堆的性質,則直接跳出循環  
  108.                 }  
  109.             }  
  110.         }  
  111.           
  112.     }  
  113.       
  114.     /** 
  115.      * 交換array中array[a]、array[b] 
  116.      * @param array 
  117.      * @param a 
  118.      * @param b 
  119.      */  
  120.     public static void Swap(int[] array,int a,int b){  
  121.         if (a < array.length && b < array.length) {  
  122.             int temp = array[a];  
  123.             array[a] = array[b];  
  124.             array[b] = temp;  
  125.         }  
  126.     }  
  127.       
  128.     /** 
  129.      * 直接插入排序 
  130.      * @param array 
  131.      */  
  132.     public static void DirectInsertSort(int[] array){  
  133.         for (int i = 0; i < array.length - 1; i++) {  
  134.             int temp = array[i + 1];  
  135.             if (array[i] > array[i + 1]) {  
  136.                 int j = i;  
  137.                 while(j >= 0 && array[j] > temp){  
  138.                     array[j + 1] = array[j];  
  139.                     j--;  
  140.                 }  
  141.                 array[j + 1] = temp;  
  142.             }  
  143.         }  
  144.     }  
  145.       
  146.     /** 
  147.      * 二分插入排序 
  148.      * @param array 
  149.      */  
  150.     public static void BinaryInsertSort(int[] array){  
  151.         for (int i = 0; i < array.length - 1; i++) {  
  152.             int temp = array[i + 1];  //須要插入的數  
  153.             if(array[i] > array[i + 1]){  
  154.                 int l = 0;   //有序隊列中左邊標識  
  155.                 int r = i;   //有序隊列中右邊標識  
  156.                 while(l < r){  
  157.                     int mid = (l + r) / 2; //永遠指向l->r中間的那個值,中間值與temp(須要插入的值)比較  
  158.                     if (array[mid] > temp) {  
  159.                         r--;              //經過while循環,二分折半搜索temp應該插入的位置  
  160.                     }else {  
  161.                         l++;  
  162.                     }  
  163.                 }  
  164.                 //運行到這裏,l==r,便是temp應該插入的位置是array[l](或者array[r])  
  165.                 for (int j = i + 1; j > l; j--) {     
  166.                     array[j] = array[j - 1];  //將l -> i的數都日後移動一位  
  167.                 }  
  168.                 array[l] = temp;  //將temp插入到l位置  
  169.                   
  170.             }  
  171.                   
  172.             }  
  173.     }  
  174.     /** 
  175.      * 直接選擇排序 
  176.      * @param array 
  177.      */  
  178.     public static void DirectSelectSort(int[] array){  
  179.         for (int i = 0; i < array.length - 1; i++) {  
  180.             int min = array[i];  
  181.             for (int j = i + 1; j < array.length; j++) {  
  182.                 if (array[j] < min) {  
  183.                     min = array[j];  
  184.                     array[j] = array[i];  
  185.                     array[i] = min;  
  186.                 }  
  187.             }  
  188.         }  
  189.     }  
  190.     /** 
  191.      * 冒泡排序 
  192.      * @param array 
  193.      */  
  194.     public static void BubbleSort(int[] array){  
  195.         int temp = 0;  
  196.         for (int i = 0; i < array.length; i++) {  
  197.             for (int j = 0; j < array.length - 1; j++) {  
  198.                 if (array[j] > array[j+1]) {  
  199.                     temp = array[j];  
  200.                     array[j] = array[j+1];    
  201.                     array[j+1] = temp;  
  202.                 }  
  203.             }  
  204.         }  
  205.     }  
  206.       
  207.     /** 
  208.      * 歸併排序 
  209.      * @param array 
  210.      */  
  211.     public static void MergeSort(int[] array){  
  212.         int left = 0;  
  213.         int right = array.length - 1;  
  214.         MergeSortRecursive(array, left, right);  000000000000000000000000000000000000000
  215.     }  
  216.     /** 
  217.      * 歸併排序的遞歸方法 
  218.      * @param array 
  219.      * @param left 
  220.      * @param right 
  221.      */  
  222.     public static void MergeSortRecursive(int[] array,int left,int right){  
  223.         if (left >= right) {  
  224.             return;  //遞歸的中止判斷,沒有這個判斷會報StackOverflowError  
  225.         }  
  226.         int mid = (left + right)/2;  
  227.         MergeSortRecursive(array, left, mid);  
  228.         MergeSortRecursive(array, mid+1, right);  
  229.         Merge(array, left, mid, right);  
  230.     }  
  231.       
  232.     /** 
  233.      * 歸併排序中合併方法 
  234.      * @param array 
  235.      * @param left 
  236.      * @param mid 
  237.      * @param right 
  238.      */  
  239.     public static void Merge(int[] array,int left,int mid,int right){  
  240.         int r_left = mid + 1; //須要合併數組中右邊數組第一個數索引  
  241.         int[] tempArray = new int[array.length];//一個臨時數組,用於合併時暫時存儲  
  242.         int newIndex = left;   //臨時數組索引  
  243.         int tempLeft = left;   //合併完了之後,用於複製數組的索引  
  244.         while(left <= mid && r_left <= right){   //將部分的數放入到臨時數組中  
  245.             if (array[left] < array[r_left]) {  
  246.                 tempArray[newIndex++] = array[left++];  
  247.             }else {  
  248.                 tempArray[newIndex++] = array[r_left++];  
  249.             }  
  250.         }  
  251.         while (left <= mid) {  
  252.             tempArray[newIndex++] = array[left++];  //將左邊還剩餘的數放入臨時數組(若須要合併的左邊還剩餘數)  
  253.         }  
  254.           
  255.         while(r_left <= right){  
  256.             tempArray[newIndex++] = array[r_left++];//將右邊還剩餘的數放入臨時數組(若須要和並的右邊還剩餘數)  
  257.         }  
  258.         while(tempLeft <= right){  
  259.             array[tempLeft] = tempArray[tempLeft++];  //將臨時數組複製到array  
  260.         }  
  261.     }  
  262.       
  263.     /** 
  264.      * 基數排序 
  265.      * @param array 
  266.      */  
  267.     public static void RadixSort(int[] array){  
  268.         int bits = FindMaxBit(array);  //獲得數組中最大的那個數的位數  
  269.         for (int i = 0; i < bits; i++) {  
  270.             OneBitSort(array, i+1);  //一位基數的排序  
  271.         }  
  272.     }  
  273.     /** 
  274.      * 一位基數的排序 
  275.      * @param array 
  276.      * @param bit 
  277.      */  
  278.     public static void OneBitSort(int[] array,int bit){  
  279.         int[] tempArray = new int[array.length];  
  280.         int index = 0;  
  281.         int tempIndex = 0;  
  282.         for (int i = 0; i < 10; i++) {  
  283.             for (int j = 0; j < array.length; j++) {  
  284.                 if (FindBitNum(array[j], bit) == i) {  
  285.                     tempArray[index++] = array[j];  
  286.                 }  
  287.             }  
  288.         }  
  289.         while(tempIndex < array.length){  
  290.             array[tempIndex] = tempArray[tempIndex++]; //複製數組  
  291.         }  
  292.     }  
  293.     /** 
  294.      * 獲得某個數某一位的數(例如:num=1234,n=2,FindBitNum(1234,2)=3) 
  295.      * @param num 
  296.      * @param n 
  297.      * @return 
  298.      */  
  299.     public static int FindBitNum(int num,int n){  
  300.         int key1 = (int)Math.pow(10, n);  
  301.         int key2 = (int)Math.pow(10, n-1);  
  302.         num %= key1;  
  303.         num /= key2;  
  304.         return num;  
  305.     }  
  306.     /** 
  307.      * 獲得一個數組中最大數的位數 
  308.      * @param array 
  309.      * @return 
  310.      */  
  311.     public static int FindMaxBit(int[] array){  
  312.           
  313.         if (array == null || array.length ==0) {  
  314.             return 0;  
  315.         }  
  316.         int max = array[0];  
  317.         for (int i = 1; i < array.length; i++) {  
  318.             if (array[i] > max) {  
  319.                 max = array[i];  
  320.             }  
  321.         }  
  322.         int bit = 0;  
  323.         while(max / 10 != 0 || max % 10 != 0){  
  324.             max /= 10;  
  325.             bit++;  
  326.         }  
  327.         return bit;  
  328.           
  329.     }  
  330.     public static void main(String[] args) {  
  331.           
  332.         System.out.println("冒泡排序:"+SortThreads.getBubbleSortTime());  
  333.         System.out.println("直接選擇排序:"+SortThreads.getDirSelectSortTime());  
  334.         System.out.println("直接插入排序:"+SortThreads.getDirInsertSortTime());  
  335.         System.out.println("二分插入排序:"+SortThreads.getBinaryInsertSortTime());  
  336.         System.out.println("快速排序:"+SortThreads.getQuickSortTime());  
  337.         System.out.println("希爾排序:"+SortThreads.getShellSortTime());  
  338.         System.out.println("歸併排序:"+SortThreads.getMergeSortTime());  
  339.         System.out.println("基數排序:"+SortThreads.getRadixSortTime());  
  340.         System.out.println("堆排序:"+SortThreads.getHeapSortTime());  
  341.           
  342.           
  343.     }  
  344. }  

1四、     Springboot的優點

(1)     遵循"習慣優於配置"原則,使用Spirng Boot只需不多的配置,大部分時候能夠使用默認配置;

(2)項目快速搭建,另外還能夠無配置整合第三方框架;

(3)可徹底不使用xml配置,只使用自動配置和Java Config;

(4)內嵌入Servlet如Tomcat容器,應用可用jar包運行(java -jar);

(5)運行中應用狀態的監控

1五、     Git使用

(1)首先Git是一種版本控制工具,可是與SVN等不一樣的是,它是分佈式的。它並不須要一個集中的服務器。每一個人電腦都是一個完整的獨立倉庫,團隊中的每一個人均可以從其餘成員那裏獲得完整的倉庫。可是爲了知足出差,在家辦公等須要,因此弄了一個集中的服務器。

(2)能夠建立分支。Git默認的分支是master分支,通常作項目能夠在master上放項目的穩定版本,而本身建立一個分支放beta版本。git branch查看當前分支,git branch hk建立新的分支hk,git checkout hk切換到hk分支。在單獨的分支上操做對其它分支沒有影響。

(3)Git有工做區和暫存區之分。好比你在hk分支上修改了代碼後,以爲功能加好了,那麼能夠用git add .和git commit -m "message"來把代碼先提交到暫存區,再提交到工做區。若是你以爲這個版本穩定了,那麼能夠切換到master分支上用git merge hk來合併hk分支。

(4)提交本地的master分支到中心服務器上,用git push origin master命令。

(5)從中心服務器上下載庫,用git pull origin master

1六、     SpringMVC執行流程

        Spring MVC是Spring提供的一個強大而靈活的Web框架,藉助於註解,Spinrg MVC提供了幾乎是POJO的開發模式,使得控制器的開發和測試更加簡單這些控制器通常不直接處理請求,而是將其委託給Spring上下文中的其餘bean,經過Spring的依賴注入功能,這些bean被注入到控制器中。
       Spring MVC主要由DispatcherServlet,處理器映射,處理器(控制器),試圖解析器,試圖組成。兩個核心是:處理器映射(選擇使用那個控制器來處理請求);視圖解析器(選擇結果應該如何渲染)
       原理:

 

核心架構的具體流程步驟以下:

一、首先用戶發送請求——>DispatcherServlet,前端控制器收到請求後本身不進行處理,而是委託給其餘的解析器進行

處理,做爲統一訪問點,進行全局的流程控制;

二、DispatcherServlet——>HandlerMapping, HandlerMapping 將會把請求映射爲HandlerExecutionChain 對象(包含一

個Handler 處理器(頁面控制器)對象、多個HandlerInterceptor 攔截器)對象,經過這種策略模式,很容易添加新

的映射策略;

三、DispatcherServlet——>HandlerAdapter,HandlerAdapter 將會把處理器包裝爲適配器,從而支持多種類型的處理器,

即適配器設計模式的應用,從而很容易支持不少類型的處理器;

四、HandlerAdapter——>處理器功能處理方法的調用,HandlerAdapter 將會根據適配的結果調用真正的處理器的功能處

理方法,完成功能處理;並返回一個ModelAndView 對象(包含模型數據、邏輯視圖名);

五、ModelAndView的邏輯視圖名——> ViewResolver, ViewResolver 將把邏輯視圖名解析爲具體的View,經過這種策

略模式,很容易更換其餘視圖技術;

六、View——>渲染,View會根據傳進來的Model模型數據進行渲染,此處的Model實際是一個Map數據結構,所以

很容易支持其餘視圖技術;

七、返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。

1七、     Mybatis配置

      網址:http://blog.csdn.net/qh_java/article/details/51601139

1八、     快速排序

1. 單軸快速排序的基本原理

快速排序的基本思想就是從一個數組中任意挑選一個元素(一般來講會選擇最左邊的元素)做爲中軸元素,將剩下的元素以中軸元素做爲比較的標準,將小於等於中軸元素的放到中軸元素的左邊,將大於中軸元素的放到中軸元素的右邊,而後以當前中軸元素的位置爲界,將左半部分子數組和右半部分子數組當作兩個新的數組,重複上述操做,直到子數組的元素個數小於等於1(由於一個元素的數組一定是有序的)。

如下的代碼中會經常使用交換數組中兩個元素值的Swap方法,其代碼以下

public static void Swap(int[] A, int i, int j){

    int tmp;

    tmp = A[i];

    A[i] = A[j];

    A[j] = tmp;

}

1九、     線程鎖

1.在多線程環境中,當咱們須要保持線程同步時,一般經過鎖來實現。

互斥鎖的使用過程當中,主要有
第一:線程鎖的初始化,pthread_mutex_init
第二:線程鎖的釋放,pthread_mutex_destory
第三:線程鎖的加鎖操做,pthread_mutex_lock
第四:線程鎖的解鎖操做,pthread_mutex_unlock

網址:http://blog.csdn.net/u011857683/article/details/52336805

20、     Js實現更換圖片

  <script>

 //經過id值得到元素的函數

 function $(id){

  return document.getElementById(id);

 } 

 //初始化函數

 function initial(){

  olLi=document.getElementsByTagName('ol')[0].getElementsByTagName('li');//獲取ol下的li

  ol=$('tab');//獲取ol元素

  theImg=$('theImg');

  //五張圖片的地址

  addressPic=['01.jpg','02.jpg','03.jpg','04.jpg','05.jpg'];

   

  //遍歷ol下的li

  for(var i=0;i<olLi.length;i++){

   //依次給每一個li綁定mouseover事件,該事件執行切換圖片的函數

   olLi[i].addEventListener('mouseover',changePicture,false);

   olLi[i].index=i;//設置ol li的index序列號  

  }

 }

 //切換圖片

 function changePicture(e){

  e.target.className="current";//將選中的ol下的li的class屬性設置爲current,e.target表明選中的li

  //清除ol裏的空白節點

  cleanWhitespace(ol);

  //刪除除當前選中的li外其餘li的class屬性值

  nextNode=e.target.nextSibling;//當前節點的下一個節點

  lastNode=e.target.previousSibling;//當前節點的前一個節點

  while(nextNode){//將當前節點後全部的兄弟節點的class屬性清除

   nextNode.setAttribute('class','');

   nextNode=nextNode.nextSibling;

  }

  while(lastNode){//將當前節點前面全部的兄弟節點的class屬性清除

   lastNode.className='';

   lastNode=lastNode.previousSibling;

  }

  //實現切換圖片的功能

  theImg.src=addressPic[this.index];

 }

 //清除ol下的空白節點

 function cleanWhitespace(oElement)

 {

  for(var i=0;i<oElement.childNodes.length;i++){

   var node=oElement.childNodes[i];

   if(node.nodeType==3 && !/\S/.test(node.nodeValue)){

     node.parentNode.removeChild(node)

   }

 }

}

 

 //給窗體綁定load事件,執行初始化函數initial()

 window.addEventListener('load',initial,false);

 </script>

2一、     什麼叫靜態頁面

     靜態網頁的網址形式一般爲:www.example.com/eg/eg.htm ,也就是以.htm、.html、.shtml、.xml等爲後綴的。在HTML格式的網頁上,也能夠出現各類動態的效果,如.GIF格式的動畫、FLASH、滾動字母等,這些「動態效果」只是視覺上的,與下面將要介紹的動態網頁是不一樣的概念。

靜態網頁的特色簡要概括以下:

  (1)靜態網頁每一個網頁都有一個固定的URL,且網頁URL以.htm、.html、.shtml等常見形式爲後綴,而不含 靜態與動態網頁

有「?」;

  (2)網頁內容一經發布到網站服務器上,不管是否有用戶訪問,每一個靜態網頁的內容都是保存在網站服務器上的,也就是說,靜態網頁是實實在在保存在服務器上的文件,每一個網頁都是一個獨立的文件;

  (3)靜態網頁的內容相對穩定,所以容易被搜索引擎檢索;

  (4)靜態網頁沒有數據庫的支持,在網站製做和維護方面工做量較大,所以當網站信息量很大時徹底依靠靜態網頁製做方式比較困難;

  (5)靜態網頁的交互性較差,在功能方面有較大的限制。 

    靜態網頁,動態網頁主要根據網頁製做的語言來區分:

  靜態網頁使用語言:HTML(超文本標記語言)

  動態網頁使用語言:HTML+ASP 或 HTML+PHP 或 HTML+JSP 等。

靜態網頁與動態的區別

  程序是否在服務器端運行,是重要標誌。在服務器端運行的程序、網頁、組件,屬於動態網頁,它們會隨不一樣客戶、不一樣時間,返回不一樣的網頁,例如ASP、PHP、JSP、ASP.net、CGI等。運行於客戶端的程序、網頁、插件、組件,屬於靜態網頁,例如html頁、Flash、JavaScript、VBScript等等,它們是永遠不變的。

  靜態網頁和動態網頁各有特色,網站採用動態網頁仍是靜態網頁主要取決於網站的功能需求和網站內容的多少,若是網站功能比較簡單,內容更新量不是很大,採用純靜態網頁的方式會更簡單,反之通常要採用動態網頁技術來實現。

  靜態網頁是相對於動態網頁而言,是指沒有後臺數據庫、不含程序和不可交互的網頁。你編的是什麼它顯示的就是什麼、不會有任何改變。靜態網頁相對更新起來比較麻煩,適用於通常更新較少的展現型網站。

  靜態網頁是標準的HTML文件,它的文件擴展名是.htm或.html,能夠包含文本、圖像、聲音、FLASH動畫、客戶端腳本和ActiveX控件及JAVA小程序等。儘管在這種網頁上使用這些對象後能夠使網頁動感十足,可是,這種網頁不包含在服務器端運行的任何腳本,網頁上的每一行代碼都是由網頁設計人員預先編寫好後,放置到Web服務器上的,在發送到客戶端的瀏覽器上後再也不發生任何變化,所以稱其爲靜態網頁。

  靜態網頁是網站建設的基礎,靜態網頁和動態網頁之間也並不矛盾,爲了網站適應搜索引擎檢索的須要,即便採用動態網站技術,也能夠將網頁內容轉化爲靜態網頁發佈。

  動態網站也能夠採用靜動結合的原則,適合採用動態網頁的地方用動態網頁,若是必要使用靜態網頁, 靜態網頁相關圖片

 

2二、     Session共享

1. 基於NFS的Session共享

NFS是Net FileSystem的簡稱,將共享目錄服務器mount到各頻道服務器的本地session目錄便可,缺點是NFS依託於複雜的安全機制和文件系統,所以併發效率不高,

 2. 基於數據庫的Session共享

首選固然是大名鼎鼎的MySQL數據庫,而且建議使用內存表Heap,提升session操做的讀寫效率。它的缺點在於session的併發讀寫能力取決於Mysql數據庫的性能,同時須要本身實現session淘汰邏輯,以便定時從數據表中更新、刪除 session記錄,

 3. 基於Cookie的Session共享

原理是將全站用戶的Session信息加密、序列化後以Cookie的方式,統一種植在根域名下(如:.host.com),利用瀏覽器訪問該根域名下的全部二級域名站點時,會傳遞與之域名對應的全部Cookie內容的特性,從而實現用戶的Cookie化Session 在多服務間的共享訪問。

4. 基於Memcache的Session共享

Memcache因爲是一款基於Libevent多路異步I/O技術的內存共享系統,簡單的Key + Value數據存儲模式使得代碼邏輯小巧高效,所以在併發處理能力上佔據了絕對優點,目前本人所經歷的項目達到2000/秒 平均查詢,而且服務器CPU消耗依然不到10%。

2三、     自旋鎖 迭代鎖

自旋鎖是專爲防止多處理器併發而引入的一種鎖,它在內核中大量應用於中斷處理等部分(對於單處理器來講,防止中斷處理中的併發可簡單採用關閉中斷的方式,即在標誌寄存器中關閉/打開中斷標誌位,不須要自旋鎖)。

 

2四、     單例

單例模式,是一種經常使用的軟件設計模式。在它的核心結構中只包含一個被稱爲單例的特殊類。經過單例模式能夠保證系統中,應用該模式的類一個類只有一個實例。即一個類只有一個對象實例。單例模式是設計模式中最簡單的形式之一。這一模式的目的是使得類的一個對象成爲系統中的惟一實例

2五、     分佈式單例

2六、     系統與系統之間如何保持單例

2七、     Nginx實現原理

Nginx由內核和模塊組成,其中,內核的設計很是微小和簡潔,完成的工做也很是簡單,僅僅經過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每一個指令將會啓動不一樣的模塊去完成相應的工做。

Nginx的模塊從結構上分爲核心模塊、基礎模塊和第三方模塊:

核心模塊:HTTP模塊、EVENT模塊和MAIL模塊

基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊和HTTP Rewrite模塊,

第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊。

用戶根據本身的須要開發的模塊都屬於第三方模塊。正是有了這麼多模塊的支撐,Nginx的功能纔會如此強大。

 

2八、     阻塞與非阻塞的區別

阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.

阻塞調用是指調用結果返回以前,當前線程會被掛起。調用線程只有在獲得結果以後纔會返回。
非阻塞調用指在不能馬上獲得結果以前,該調用不會阻塞當前線程。

 

2九、     線程共享

進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。

 

30、     堆棧空間

     注意:其實堆棧自己就是棧,只是換了個抽象的名字。

堆棧的特性: 最後一個放入堆棧中的物體老是被最早拿出來, 這個特性一般稱爲後進先出(LIFO)隊列。 堆棧中定義了一些操做。 兩個最重要的是PUSH和POP。 PUSH操做在堆棧的頂部加入一 個元素。POP操做相反, 在堆棧頂部移去一個元素, 並將堆棧的大小減一。

 

隊列:什麼是隊列?又該怎麼理解呢?

①隊列是一種特殊的線性表,特殊之處在於它只容許在表的前端(front)進行刪除操做,而在表的後端(rear)進行插入操做,和棧同樣,隊列是一種操做受限制的線性表。進行插入操做的端稱爲隊尾,進行刪除操做的端稱爲隊頭。

②隊列中沒有元素時,稱爲空隊列。

③創建順序隊列結構必須爲其靜態分配或動態申請一片連續的存儲空間,並設置兩個指針進行管理。一個是隊頭指針front,它指向隊頭元素;另外一個是隊尾指針rear,它指向下一個入隊元素的存儲位置。

④隊列採用的FIFO(first in first out),新元素(等待進入隊列的元素)老是被插入到鏈表的尾部,而讀取的時候老是從鏈表的頭部開始讀取。每次讀取一個元素,釋放一個元素。所謂的動態建立,動態釋放。於是也不存在溢出等問題。因爲鏈表由結構體間接而成,遍歷也方便。(先進先出)

堆、棧區別總結:

1.堆棧空間分配

 ①棧(操做系統):由操做系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操做方式相似於數據結構中的棧。

 ②堆(操做系統): 通常由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式卻是相似於鏈表。

2.堆棧緩存方式

①棧使用的是一級緩存, 他們一般都是被調用時處於存儲空間中,調用完畢當即釋放。

②堆則是存放在二級緩存中,生命週期由虛擬機的垃圾回收算法來決定(並非一旦成爲孤兒對象就能被回收)。因此調用這些對象的速度要相對來得低一些。

3.堆棧數據結構區別

①堆(數據結構):堆能夠被當作是一棵樹,如:堆排序。

②棧(數據結構):一種先進後出的數據結構。

3一、     Hashmap,tablemap,treemap,map的對比

共同點

HashMap,LinkedHashMap,TreeMap都屬於Map;Map 主要用於存儲鍵(key)值(value)對,根據鍵獲得值,所以鍵不容許鍵重複,但容許值重複。

不一樣點

一、HashMap鍵無序,它根據鍵的HashCode值存儲數據,根據鍵能夠直接獲取它的值,具備很快的訪問速度,在Map 中插入、刪除和定位元素,HashMap 是最好的選擇;
二、LinkedHashMap 是HashMap的一個子類,鍵保存了插入的順序,使用Iterator遍歷時,獲得的也是插入順序的記錄;
三、TreeMap默認按鍵的升序排序,能夠定製。
四、HashTable 線程安全,鍵不能爲null,與HashMap相似,但效率較低,HashMap若是須要實現同步,能夠使用Collections. synchronizedMap或ConcurrentHashMap 。

3二、     List集合的區別

Vector、ArrayList都是以相似數組的形式存儲在內存中,LinkedList則以鏈表的形式進行存儲。

List中的元素有序、容許有重複的元素,Set中的元素無序、不容許有重複元素。

Vector線程同步,ArrayList、LinkedList線程不一樣步。

LinkedList適合指定位置插入、刪除操做,不適合查找;ArrayList、Vector適合查找,不適合指定位置的插入、刪除操做。

ArrayList在元素填滿容器時會自動擴充容器大小的50%,而Vector則是100%,所以ArrayList更節省空間。

 

 

3三、     treemap和安全集合會產生什麼影響

3四、     spring事物

Spring事務 的本質其實就是數據庫對事務的支持,沒有數據庫的事務支持,spring是沒法提供事務功能的。對於純JDBC操做數據庫,想要用到事務,能夠按照如下步驟進行:
    獲取鏈接 Connection con = DriverManager.getConnection()
    開啓事務con.setAutoCommit(true/false);
    執行CRUD
    提交事務/回滾事務 con.commit() / con.rollback();
    關閉鏈接 conn.close();
使用Spring的事務管理功能後,咱們能夠再也不寫步驟 2 和 4 的代碼,而是由Spirng 自動完成。 那麼Spring是如何在咱們書寫的 CRUD 以前和以後開啓事務和關閉事務的呢?解決這個問題,也就能夠從總體上理解Spring的事務管理實現原理了。下面簡單地介紹下,註解方式爲例子
    配置文件開啓註解驅動,在相關的類和方法上經過註解@Transactional標識。
    spring 在啓動的時候會去解析生成相關的bean,這時候會查看擁有相關注解的類和方法,而且爲這些類和方法生成代理,並根據@Transaction的相關參數進行相關配置注入,這樣就在代理中爲咱們把相關的事務處理掉了(開啓正常提交事務,異常回滾事務)。

3五、     數據庫事物

數據庫事務(Database Transaction) ,是指做爲單個邏輯工做單元執行的一系列操做,要麼徹底地執行,要麼徹底地不執行。 事務處理能夠確保除非事務性單元內的全部操做都成功完成,不然不會永久更新面向數據的資源。經過將一組相關操做組合爲一個要麼所有成功要麼所有失敗的單元,能夠簡化錯誤恢復並使應用程序更加可靠。一個邏輯工做單元要成爲事務,必須知足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。事務是數據庫運行中的邏輯工做單位,由DBMS中的事務管理子系統負責事務的處理。

3六、     怎麼配置spring事物

  一、傳統使用JDBC的事務管理

  以往使用JDBC進行數據操做,使用DataSource,從數據源中獲得Connection,咱們知道數據源是線程安全的,而鏈接不是線程安全的,因此對每一個請求都是從數據源中從新取出一個鏈接。通常的數據源由容器進行管理,包括鏈接池。例如TOMCAT,WEBSPHERE,WEBLOGIC等這些J2EE商業容器都提供了這個功能。

二、Spring提供的編程式的事務處理

  Spring提供了幾個關於事務處理的類:TransactionDefinition //事務屬性定義

  TranscationStatus //表明了當前的事務,能夠提交,回滾。

  PlatformTransactionManager這個是spring提供的用於管理事務的基礎接口,其下有一個實現的抽象類AbstractPlatformTransactionManager,咱們使用的事務管理類例如DataSourceTransactionManager等都是這個類的子類。

Spring聲明式事務處理

  Spring聲明式事務處理也主要使用了IoC,AOP思想,提供了TransactionInterceptor攔截器和經常使用的代理類TransactionProxyFactoryBean,能夠直接對組件進行事務代理。

 

3七、     設計模式

     單例模式有如下特色:
    一、單例類只能有一個實例。
    二、單例類必須本身建立本身的惟一實例。
    三、單例類必須給全部其餘對象提供這一實例。
代理模式:
  代理模式的三種角色:
抽象角色(聲明真實對象和代理對象的共同接口)
  代理角色(代理角色中提供與真實對象相同的接口以便在任什麼時候候可都能代理真實對象,同時附加其餘操做,至關於真實對象進行封裝) 
  真實角色:代理角色所表明的真對象,是咱們最終要引用的對象
  好處:就是對外部提供統一的接口方法而代理類在接口中實現對真實類的附加操做行爲,從而能夠在不影響外部調用的狀況下,進行系統擴展。
工廠模式: 
  主要解決:接口選擇的問題
  如何解決:讓其子類實現工廠接口,返回的也是一個抽象的產品。
  優勢:若是想建立對象,只要知道名字便可;擴展性高,若是想要增長一種產品,只需擴展一個工廠類便可;不關心其內部的具體實現,只關心接口的做用便可 
  缺點:每次增長一個工廠類,須要增長個具體類和對象實現工廠,當時的系統中類的個數成倍增長,在必定層都上增長了系統的複雜度,同時也增長了系統具體類的依賴
觀察者模式:
當對象間存在一對多關係時,則使用觀察者模式(Observer Pattern)。好比,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬於行爲型模式。

意圖:定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。

主要解決:一個對象狀態改變給其餘對象通知的問題,並且要考慮到易用和低耦合,保證高度的協做。

什麼時候使用:一個對象(目標對象)的狀態發生改變,全部的依賴對象(觀察者對象)都將獲得通知,進行廣播通知。

如何解決:使用面向對象技術,能夠將這種依賴關係弱化。

關鍵代碼:在抽象類裏有一個 ArrayList 存放觀察者們。

應用實例: 一、拍賣的時候,拍賣師觀察最高標價,而後通知給其餘競價者競價。 二、西遊記裏面悟空請求菩薩降服紅孩兒,菩薩灑了一地水招來一個老烏龜,這個烏龜就是觀察者,他觀察菩薩灑水這個動做。

優勢: 一、觀察者和被觀察者是抽象耦合的。 二、創建一套觸發機制。

缺點: 一、若是一個被觀察者對象有不少的直接和間接的觀察者的話,將全部的觀察者都通知到會花費不少時間。 二、若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能致使系統崩潰。 三、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。

 

3八、     sleep wait的區別

     1.sleep和wait都是用來進行線程控制,他們最大本質的區別是:

      sleep()不釋放同步鎖,wait()釋放同步鎖.   
     sleep(milliseconds)能夠用時間指定來使他自動醒過來,若是時間不到你只能調用interreput()來強行打斷;
     wait()能夠用notify()直接喚起.

2.sleep是Thread類的靜態方法。

     sleep的做用是讓線程休眠制定的時間,在時間到達時恢復,也就是說sleep將在接到時間到達事件事恢復線程執行,例如:
        try{
            System.out.println("I'm going to bed");
            Thread.sleep(1000);
            System.out.println("I wake up");
        }
        catch(IntrruptedException e) {
        }

 wait是Object的方法,也就是說能夠對任意一個對象調用wait方法,調用wait方法將會將調用者的線程掛起,直到其餘線程調用同一個對象的notify方法纔會從新激活調用者,例如:
         try{
             obj.wait }

          catch(InterrputedException e) {
         }
 
       3. sleep()是讓某個線程暫停運行一段時間,其控制範圍是由當前線程決定,
    wait()是由某個肯定的對象來調用的。
 
      sleep和wait的區別有:
     1,這兩個方法來自不一樣的類分別是Thread和Object
     2,最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其餘線程能夠使用同步控制塊或者方法。
     3,wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep能夠在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }

4,sleep必須捕獲異常,而wait,notify和notifyAll不須要捕獲異常

3九、     js生成excel表

    <!DOCTYPE html><html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <meta charset="utf-8" />
    <style>
        /* 此樣式僅用於瀏覽器頁面效果,Excel不會分離表格邊框,不須要此樣式 */
        table {
            border-collapse: collapse;
        }
    </style></head><body>
    <!-- 設置border="1"以顯示錶格框線 -->
    <table border="1">
        <!-- caption元素能夠生成表標題,其單元格列跨度爲表格的列數 -->
        <caption>學生成績表</caption>
        <tr>
            <!-- 能夠使用rowspan和colspan來合併單元格 -->
            <th rowspan="2">編號</th>
            <th rowspan="2">學號</th>
            <th rowspan="2">姓名</th>
            <th rowspan="2">性別</th>
            <th rowspan="2">年齡</th>
            <th colspan="3">成績</th>
        </tr>
        <tr>
            <th>語文</th>
            <th>數學</th>
            <th>英語</th>
        </tr>
        <tr>
            <td>1</td>
            <td>2016001</td>
            <td>張三</td>
            <td>男</td>
            <td>13</td>
            <td>85</td>
            <td>94</td>
            <td>77</td>
        </tr>
        <tr>
            <td>2</td>
            <td>2016002</td>
            <td>李四</td>
            <td>女</td>
            <td>12</td>
            <td>96</td>
            <td>84</td>
            <td>89</td>
        </tr>
    </table>
 
    <a>導出表格</a>
 
    <script>
        // 使用outerHTML屬性獲取整個table元素的HTML代碼(包括<table>標籤),而後包裝成一個完整的HTML文檔,設置charset爲urf-8以防止中文亂碼
        var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementsByTagName("table")[0].outerHTML + "</body></html>";
        // 實例化一個Blob對象,其構造函數的第一個參數是包含文件內容的數組,第二個參數是包含文件類型屬性的對象
        var blob = new Blob([html], { type: "application/vnd.ms-excel" });
        var a = document.getElementsByTagName("a")[0];
        // 利用URL.createObjectURL()方法爲a元素生成blob URL        a.href = URL.createObjectURL(blob);
        // 設置文件名,目前只有Chrome和FireFox支持此屬性        a.download = "學生成績表.xls";
    </script></body></html>

 

40、     easyUI

41.選擇排序

他的工做原理是每一次從待排序的元素中最小(或最大)的一個元素,存放在序列的起始位置,直到所有待排序的數組元素排完,選擇排序是不穩定的排序方法(好比序列[5,5,3],第一次將第一個5與3交換,致使第一個5挪到第二個5後邊)

public void sort(int[] sort){

for(int i=0;i<sort.length;i++){

for(int j=i+1;j<sort.length;j++){

if(sort[i]>sort[j]){

int temp=sort[j];

sort[j]=sort[i];

sort[i]=temp;

}

}

 

}

42.Map實現原理

通過排序了的二元組的集合,Map中的每一個元素都是由兩個值組成,其中Key(鍵值,一個Map集合中鍵值是必須的),是在排序或搜索時使用,他的值能夠在容器中從新獲取,而另外一個是該元素關聯的數值,好比除了能夠ar[43]=」overripe」這樣找到一個數據,Map還能夠經過ar[「banana」]=「overripe」這樣的方法找到一個數據

43.Tomcat集羣衝突有什麼影響

a)    集羣衝突的話就只能運行一個tomcat而不能運行多個tomcat,因此要改端口號,不讓集羣有衝突!

b)   DNS輪詢 當集羣中某臺服務器中止以後,用戶因爲dns緩存的緣故,便沒法訪問服務,必須等到dns解析更新,或者這臺服務器從新啓動。還有就是必須把集羣中的全部服務端口暴露給外界,沒有用apache作前置代理的方式安全,而且佔用大量公網IP地址,並且tomcat還要負責處理靜態網頁資源,影響效率

c)   R-proxy(反向代理)當其中一臺tomcat中止運行的時候,apache仍然會轉發請求過去,致使502網關錯誤。可是隻要服務器再啓動就不存在這個問題。

d)   mod_jk 當中止掉的tomcat服務器再次啓動的時候,Apache檢測不到,仍然不會轉發請求過去。

44.Spring的實現原理

e)   Spring內部最核心的就是IOC了,動態注入,讓一個對象的建立不用再new,能夠自動的生產,這其實利用了java的反射,反射其實就是在運行時動態的去建立,調用對象,Spring就是在運行時,跟XML Spring的配置文件來動態建立對象和調用對象裏的方法。

f)   Spring還有一個核心就是AOP,這個是面向切面編程,能夠爲某一對象進行監督和控制(也就是在調用這類對象的具體方法的先後去調用你指定的模塊)從而達到對一個模塊擴充的功能,這些都是經過配置類達到的

g)   Spring目的:就是讓對象與對象之間的關係沒有經過代碼來關聯,都是經過配置類說明管理的(Spring根據這些配置,內部經過反射去動態組裝對象)

45.Spring Boot配置與不配置的區別

SpringBoot理念就是零配置編程。

SpringBootServletInitializer初始化servlet代替了web.xml,servlet3.0不須要web.xml。

46.公平和非公平鎖

所謂公平鎖指的是哪一個線程先運行,那就能夠先獲得鎖。非公平鎖是無論線 程是不是先運行,都是隨機得到鎖的。

在公平的鎖上,線程按照他們發出請求的順序獲取鎖,但在非公平鎖上,則容許‘插隊’:當一個線程請求非公平鎖時,若是在發出請求的同時該鎖變成可用狀態,那麼這個線程會跳過隊列中全部的等待線程而得到鎖。

47.orcale調用存儲過程

無參數存儲過程的使用:

·  例:建立一個存儲過程,用於向數據庫中插入一條記錄。  

第一步:建立 

·  CREATE  OR  REPLACE  PROCEDURE  pro_1  

·  IS  

·  Begin  

·    insert into person values (11,'aa','aav');  

·  End;  

 

第二步:在sql*plus中執行該過程 

·  exec pro_1;  

 

第三步:經過JDBC使用存儲過程。

·   private Connection conn = null;  

·   private ResultSet rs = null;  

·   private CallableStatement state = null;  

·   //調用一個無參數的存儲過程  

·   public void testPro()  

·   {  

·    conn = Tools.getConnection();  

·    try {  

·      state = conn.prepareCall("{call pro_1}");  

·      state.execute();  

·    } catch (Exception e) {  

·      // TODO Auto-generated catch block  

·      e.printStackTrace();  

·    }  

·   }

 

48.高併發

域,這個指標和吞吐量區分的沒有這麼明顯。

併發用戶數:同時承載正常使用系什麼是高併發

高併發(High Concurrency)是互聯網分佈式系統架構設計中必須考慮的因素之一,它一般是指,經過設計保證系統可以同時並行處理不少請求。

高併發相關經常使用的一些指標有響應時間(Response Time),吞吐量(Throughput),每秒查詢率QPS(Query Per Second),併發用戶數等。

響應時間:系統對請求作出響應的時間。

吞吐量:單位時間內處理的請求數量。

QPS:每秒響應請求數。在互聯網領統功能的用戶數量。例如一個即時通信系統,同時在線量必定程度上表明瞭系統的併發用戶數

49.點對點和訂閱發佈的區別

JMS中定義

JMS規範目前支持兩種消息模型:點對點(point to point, queue)和發佈/訂閱(publish/subscribe,topic)。
點對點
消息生產者生產消息發送到queue中,而後消息消費者從queue中取出而且消費消息。這裏要注意:
消息被消費之後,queue中再也不有存儲,因此消息消費者不可能消費到已經被消費的消息。 Queue支持存在多個消費者,可是對一個消息而言,只會有一個消費者能夠消費。
發佈/訂閱
消息生產者(發佈)將消息發佈到topic中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不一樣,發佈到topic的消息會被全部訂閱者消費。

50.Websocket

WebSocket 事件

事件

事件處理程序

描述

open

Socket.onopen

鏈接創建時觸發

message

Socket.onmessage

客戶端接收服務端數據時觸發

error

Socket.onerror

通訊發生錯誤時觸發

close

Socket.onclose

鏈接關閉時觸發

 

 

 

 

HTML5 WebSocket

WebSocket是HTML5開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。

在WebSocket API中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。

瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。

當你獲取 Web Socket 鏈接後,你能夠經過 send() 方法來向服務器發送數據,並經過 onmessage 事件來接收服務器返回的數據。

51.dubbo架構圖

1.服務接口層:該層與實際業務邏輯有關,根據服務消費方和服務提供方的業務設計,實現對應的接口。

2.配置層:對外配置接口,以ServiceConfig和ReferenceConfig爲中心,能夠直接new配置類,也能夠根據spring解析配置生成配置類。

3.服務註冊層:封裝服務地址的註冊和發現,以服務URL爲中心,擴展接口爲RegistryFactory、Registry、RegistryService,可能沒有服務註冊中心,此時服務提供方直接暴露   服務。

4.服務代理層:服務接口通明代理,生成服務的客戶端Stub和服務端Skeleton,以ServiceProxy爲中心,擴展接口ProxyFactory。

    5.集羣層:封裝多個提供者的路由和負載均衡,並橋接註冊中  心,以Invoker爲中心,擴展接口爲Cluster、Directory、Router 和LoadBalance,將多個服務提供方組合爲 一個服   務提供方, 實現對服務消費通明。只須要與一個服務提供方進行交互。

6.監控層:RPC調用時間和次數監控,以Statistics爲中心,擴展接口MonitorFactory、Monitor和MonitorService。

7.遠程調用層:封裝RPC調用,以Invocation和Result爲中心,擴展接口爲Protocol、Invoker和Exporter。Protocol是服務域,它是Invoker暴露和引用的主功能入口,它負責  Invoker的生命週期管理。Invoker是實體域,它是Dubbo的核心模型,其餘模型都是向它靠攏,或轉換成它,它表明一個可執行體,可向它發起Invoker調用,它有多是一個本  地實現,也有多是一個遠程實現,也有多是一個集羣實現。

8.信息交換層:封裝請求響應模式,同步轉異步,以Request和Response爲中心,擴展接口爲Exchanger和ExchangeChannel,ExchangeClient和ExchangeServer。

9.網絡傳輸層:抽象和mina和netty爲統一接口,以Message爲中心,擴展接口爲Channel、Transporter、Client、Server和Codec。

10.數據序列化層:可複用的一些工具,擴展接口爲Serialization、ObjectInput,ObejctOutput和ThreadPool。

52.redis持久化方式(兩種)

1)RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操做過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功後,再替換以前的文件,用二進制壓縮存儲。

2)AOF持久化以日誌的形式記錄服務器所處理的每個寫、刪除操做,查詢操做不會記錄,以文本的方式記錄,能夠打開文件看到詳細的操做記錄。

53.項目上線後問題

1.新流程的執行問題。在實施階段設計得很好的流程在實際使用過程當中是否可以獲得很好的執行

2.系統調整的問題。實施項目後,計劃模式及業務流程進行了調整,這個時候系統中設定的某些參數和基礎數據不必定很準確,上線以後,隨着系統的使用,這些參數的問題會暴  露  出來,實施階段,這些參數和基礎數據的設定是顧問協助完成的。系統運維階段,如何對這些參數進行調整使其符合企業的實際是一個很是重要的問題

3.數據的準確性問題。咱們知道,在手工階段,同一個數據能夠經過對不一樣業務部門提交的報表中進行分析比較。實施ERP後,數據的來源基本上就惟一了,數據源頭的錯誤會致使  後續一連串的數據錯誤。

4.隊伍的問題。隨着系統的上線,顧問的撤出,這時候企業須要本身的團隊面對全部可能出現的問題。這個時候,企業本身的團隊是否已經準備好了是系統可否正常運行的關鍵。

5.資金的問題 項目的後續維護成本絕對不是能夠忽略不計的。人員的培訓、系統的維護與優化、硬件的維護等等,這些加起來是一筆不小的費用。

54.不用dubbo使用springcloud的好處

相同之處,它們兩都具有分佈式服務治理相關的功能,都可以提供服務註冊、發現、路由、負載均衡等。說到這,Dubbo的功能好像也就這麼多了,可是Spring Cloud是提供了一  整套企業級分佈式雲應用的完美解決方案,可以結合Spring Boot,Docker實現快速開發的目的,因此說Dubbo只有Spring Cloud的一部分RPC功能,並且也談不上誰好誰壞。不過  Dubbo項目現已中止了更新,淘寶內部由hsf替代dubbo,我想這會有更多人傾向Spring Cloud了。

從開發角度上說,Dubbo常與Spring、zookeeper結合,並且實現只是經過xml來配置服務地址、名稱、端口,代碼的侵入性是很小的,相對Spring Cloud,它的實現須要類註解等多少具備必定侵入性。

55.spring傳播特性

spring經過事務傳播 spring的六種事務傳播特性:

1. PROPAGATION_REQUIRED: 若是存在一個事務,則支持當前事務。若是沒有事務則開啓

2. PROPAGATION_SUPPORTS: 若是存在一個事務,支持當前事務。若是沒有事務,則非事務的執行

3. PROPAGATION_MANDATORY: 若是已經存在一個事務,支持當前事務。若是沒有一個活動的事務,則拋出異常。

4. PROPAGATION_REQUIRES_NEW: 老是開啓一個新的事務。若是一個事務已經存在,則將這個存在的事務掛起。

5. PROPAGATION_NOT_SUPPORTED: 老是非事務地執行,並掛起任何存在的事務。

6. PROPAGATION_NEVER: 老是非事務地執行,若是存在一個活動事務,則拋出異常

56.經緯度計算(百度地圖插件)

  1.          i.      經緯度:經過經度(longitude)和緯度(latitude)描述的地球上的某個位置。
  2.        ii.      平面座標:投影以後的座標(用x和y描述),用於在平面上標識某個位置。
  3.      iii.      像素座標:描述不一樣級別下地圖上某點的位置。
  4.        iv.      圖塊座標:地圖圖塊編號(用x和y描述)。
  5.          v.      可視區域座標:地圖可視區域的座標系(用x和y描述)。
  6.        vi.      覆蓋物座標:覆蓋物相對於容器的座標(用x和y描述)。

 

 

57.訂單狀態監聽(電商項目)

顧客訂單

一. 銷售輸入(小訂單模式): 

  1. 校驗代理商或者店主商品庫存, 校驗輸入的商品總數不能爲負數

  2. 減去代理商或者店主的庫存

  3. 添加一條訂單記錄(小訂單) 

  4. 更新顧客消費總額(每添加一個小訂單,消費總額更新一次)

  5. 更新顧客最近消費記錄(最近消費商品,最近購買時間, 購買次數購買次數(添加一個大單sales加1,銷售取消時不作減操做))

 

 

二. 銷售取消(小訂單)

    1. 校驗顧客購買的產品數量,取消的數量不能大於顧客購買商品剩餘的數量, 校驗輸入的商品總數不能爲負數。

    2. 將所退的商品增長到代理商或者店主庫存

    3. 銷售取消單價重置爲負數,總價格也爲負數

    4. 增長一條銷售取消記錄

    5. 更新用戶消費總額(每取消一個小訂單,消費總額更新一次)

 

代理商訂單(走大訂單流程)

訂單狀態:

  1. 待確認(沒有任何代理商確認過的)

   2. 已確認(有一個代理商確認過但還有代理商沒確認的)

   3.配送準備中(已確認)(全部代理商都確認過了)

   4.確認收款(總部已經收款的)

   5. 配送中(總部已經發貨的,確認收款以後的5天后自動在前端顯示配送中的狀態)

   6. 訂單完成(總部發貨後已經10天自動完成訂單)

   7.訂單取消(至關於將訂單做廢)

    

一. 下單流程:

    1. 查詢商品列表

    2. 勾選商品,添加到購物車,購物車中商品數量加減(購物車中有這個商品,則累計數據,購物車中沒有則新增一條記錄)注意:這個時候不校驗庫存

    3. 提交訂單,勾選地址(沒有的話就建立一個新的地址)。

    4. 訂單確認提交

    5. 商品庫存校驗,商品是否被刪除校驗

    6. 生成大訂單(返回大訂單id,將但訂單id加入到小訂單中)

    7. 遍歷添加小訂單

    8. 商品減庫存,加銷量

    9. 將購物車中的訂單轉化爲訂單狀態

 

二. 訂單定時器

   1. 確認收款以後的5天后自動在前端顯示配送中的狀態

   2. 確認收款後的10天后自動在前端顯示訂單結束  

   3. 訂單結束後增長代理商或者店主商品庫存

   4. 更新代理商或者店主的最近購買記錄。

58.觀察者模式(Observer)

觀察者模式是java中的23種設計模式之一,觀察者模式是對象的行爲模式,又叫發佈,訂閱,模型,視圖,源,監聽器,從屬者/模式,觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知全部觀察者對象,使他們可以自動更新本身。觀察者的出現是爲了是系統可以易於複用,應該選擇低耦合的設計方案。觀察者模式涉及到的角色有「抽象主題角色」「具體主題角色」「抽象觀察者角色」「具體觀察者角色」

59.負載均衡

Load Balancer是整個集羣系統的前端,負責把客戶請求轉發到Real Server上。Load Balancer經過Ldirectord監測各Real Server的健康情況。在Real Server不可用時把它從羣中剔除,恢復時從新加入。

Backup是備份Load Balancer,當Load Balancer不可用時接替它,成爲實際的Load Balancer。

60.拆表原則

1.能不分就不分

2.數據量太大,正常的運維影響正常業務訪問

3.表設計不合理,須要對某些字段垂直拆分

4.某些數據表出現了無窮增加

5.安全性和可用性的考慮

6.業務耦合性考慮

61.Dubbo的做用

Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,若是沒有分佈式的需求,實際上是不須要用的,只有在分佈式的時候,纔有dubbo這樣的分佈式服務框架的需求。

Dubbo是Alibaba開源的分佈式服務框架,它最大的特色是按照分層的方式來架構,使用這種方式能夠使各個層之間解耦合(或者最大限度地鬆耦合)。

62.Jvm

Java程序的跨平臺特性主要是指字節碼文件能夠在任何具備Java虛擬    機的計算機或者電子設備上運行,Java虛擬機中的Java解釋器負責將字節    碼文件解釋成爲特定的機器碼進行運行。所以在運行時,Java源程序須要通    過編譯器編譯成爲.class文件。

JVM是JRE的一部分。它是一個虛構出來的計算機,是經過在實際的計    算機上仿真模擬各類計算機功能來實現的。JVM有本身完善的硬件架構,如    處理器、堆棧、寄存器等,還具備相應的指令系統

 

63.servlet配置

Servlet和jsp功能一致,也就是說,servlet能夠被外部訪問,那麼要訪問它,就須要經過一個地址,所以只有經過web的地址映射來訪問。

web.xmll

<servlet>

<servlet-name>本身定義名字</servlet-name>

<servlet-class>servlet文件的路徑</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>和上邊定義的名字保持一致</servlet-name>

<url-pattern>地址名</url-patturn>

</servlet-mapping>

64.Fastdfs

FastDFS是用c語言編寫的一款開源的分佈式文件系統。FastDFS爲互聯網量身定製,充分考慮了冗餘備份、負載均衡、線性擴容等機制,並注重高可用、高性能等指標,使用FastDFS很容易搭建一套高性能的文件服務器集羣提供文件上傳、下載等服務。

FastDFS架構包括 Tracker server和Storage server。客戶端請求Tracker server進行文件上傳、下載,經過Tracker server調度最終由Storage server完成文件上傳和下載。

65.sharding-jdbc

Sharding-JDBC直接封裝JDBC API,能夠理解爲加強版的JDBC驅動,舊代碼遷移成本幾乎爲零:

Sharding-JDBC定位爲輕量Java框架,使用客戶端直連數據庫,以jar包形式提供服務,無proxy代理層,無需額外部署,無其餘依賴,DBA也無需改變原有的運維方式。

 

66.redis5種基本數據類型

l  字符串類型(string),字符串類型是Redis的最基本類型,它能夠存儲任何形式的字符串。其它的四種類型都是字符串類型的不一樣形式。

l  散列類型(hash),

l  列表類型(list),內部使用雙向鏈表實現,因此獲取越接近兩端的元素速度越快,但經過索引訪問時會比較慢

l  集合類型(set),集合類型值具備惟一性,經常使用操做是向集合添加、刪除、判斷某個值是否存在,集合內部是使用值爲空的散列表實現的。

l  有序集合類型(zset)

67.hibernate和mybatis應用場景

Mybatis應用場景:

         需求多變的互聯網項目,例如電商項目。

Hibernate應用場景:

         需求明確、業務固定的項目,例如OA項目、ERP項目等。

68.stuats2與springmvc的對比

l  Struts2是類級別的攔截, 一個類對應一個request上下文,SpringMVC是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,因此說從架構自己上SpringMVC就容易實現restful url,而struts2的架構實現起來要費勁,由於Struts2中Action的一個方法能夠對應一個url,而其類屬性卻被全部方法共享,這也就沒法用註解或其餘方式標識其所屬方法了。

由上邊緣由,SpringMVC的方法之間基本上獨立的,獨享request response數據,請求數據經過參數獲取,處理結果經過ModelMap交回給框架,方法之間不共享變量,而Struts2搞的就比較亂,雖然方法之間也是獨立的,但其全部Action變量是共享的,這不會影響程序運行,卻給咱們編碼 讀程序時帶來麻煩,每次來了請求就建立一個Action,一個Action對象對應一個request上下文。

l  因爲Struts2須要針對每一個request進行封裝,把request,session等servlet生命週期的變量封裝成一個一個Map,供給每一個Action使用,並保證線程安全,因此在原則上,是比較耗費內存的。

l   攔截器實現機制上,Struts2有以本身的interceptor機制,SpringMVC用的是獨立的AOP方式,這樣致使Struts2的配置文件量仍是比SpringMVC大。

l  SpringMVC的入口是servlet,而Struts2是filter(這裏要指出,filter和servlet是不一樣的。之前認爲filter是servlet的一種特殊),這就致使了兩者的機制不一樣,這裏就牽涉到servlet和filter的區別了。

l  SpringMVC集成了Ajax,使用很是方便,只需一個註解@ResponseBody就能夠實現,而後直接返回響應文本便可,而Struts2攔截器集成了Ajax,在Action中處理時通常必須安裝插件或者本身寫代碼集成進去,使用起來也相對不方便。

l  SpringMVC驗證支持JSR303,處理起來相對更加靈活方便,而Struts2驗證比較繁瑣,感受太煩亂。

l  Spring MVC和Spring是無縫的。從這個項目的管理和安全上也比Struts2高(固然Struts2也能夠經過不一樣的目錄結構和相關配置作到SpringMVC同樣的效果,可是須要xml配置的地方很多)。

l  設計思想上,Struts2更加符合OOP的編程思想, SpringMVC就比較謹慎,在servlet上擴展。

l  SpringMVC開發效率和性能高於Struts2。

l  SpringMVC能夠認爲已經100%零配置。

69.#和$的區別

 #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,若是傳入的值是111,那麼解析成sql時的值爲order by "111", 若是傳入的值是id,則解析成的sql爲order by "id".

l  $將傳入的數據直接顯示生成在sql中。如:order by $user_id$,若是傳入的值是111,那麼解析成sql時的值爲order by user_id,  若是傳入的值是id,則解析成的sql爲order by id.

l   #方式可以很大程度防止sql注入。

l  .$方式沒法防止Sql注入。

l  $方式通常用於傳入數據庫對象,例如傳入表名。

l  .通常能用#的就別用$.

70.人民幣類型

l  M0 M1 M2 M0=流通中現金 M1=M0+非金融性公司的活期存款 M2=M1+非金融性公司的按期存款+儲蓄存款+其餘存款

相關文章
相關標籤/搜索