面試話術

部署activemq

1.上傳 2.解壓 tar vxzf apache-activemq 3.放到一個新的文件夾下 :mv apache-activemq(要放得文件) activemq(文件夾名稱) 4.啓動mq須要在bin下,因此先進到bin下 5.啓動:./activemq java -version 查看jdk版本前端

部署zookeeper

1.上傳 (直接拉過來) 2.解壓 tar vxzf zookeeper... 3.在conf中 複製zoo_sample.cfg 具體代碼:cp zoo_sample.cfg zoo.cfg 4.編輯zoo.cfg 修改路徑 完成以後,wq保存退出 5.在zookeeper下建立一個文件夾date mkdir data 6.給zookeeper-3.4起別名 zookeeper3.4 zookeeper 7.而後在bin下啓動就好了 啓動:./zkServer.sh startjava

AOP:

代理模式:    (將被代理對象注入給代理對象,當調用代理對象時,其實是在調用被注入的被代理對象)
                        代理類     被代理類
                      
                     靜態代理: 代理類只能代理某一種類,不能代理任何一個類

                     動態代理: 代理類能夠代理任何一個類

實現切面的具體代碼:
   註解形式:
           1.創建一個切面類  裏面加上兩個註解    @Component (讓spring容器發現這個類)     @Aspect (告訴它這是個切面)
           2.裏面寫方法       方法上家註解 ,表示這是什麼通知,是前置(@before),後置(@),仍是異常,環繞或最終通知  
                   還得標明要切的方法是什麼,如:@before("execution(*   包名.*.*))  *爲包名裏的全部類(第一*),全部方法(第二*)
複製代碼

1.tomcat的工做流程是什麼? 2.登陸裏面的token是怎麼生成的?token每次是怎麼樣傳回服務端的? 3.session共享有什麼辦法? 4.鎖? 5.redis 緩存? 6.內存模型?mysql

1.什麼是線程池,簡單說一下幾種常見線程池?

java線程池的工做原理和數據庫鏈接池的差很少,由於每次從新建立線程都是很耗資源的操做,因此咱們能夠創建一個線程池,這樣當須要用到線程進行某些操做時,就能夠直接去線程池裏面找到空閒的線程,這樣就能夠直接使用,而不用等到用到的時候再去建立,用完以後能夠把該線程從新放入線程池供其餘請求使用從而提升應用程序的性能。linux

線程池的核心流程:

1.構建一個 ThreadPoolExecutor 並指定默認要建立的線程的數量 2.經過 threadPool.execute() 去添加一個個要執行的線程即實現了Runable接口的java類 3.在實現了Runable接口的java類的run方法中寫入具體的業務代碼nginx

線程池的業務場景:

我在工做的時候,當時一個同事給我提了一個需求,目前有大量的圖片須要處理生產縮略圖並進行加水印,由於按照普通的處理方法一個個的進行處理太慢了,問我有沒有好的解決方案,這個時候我就想到了java中的線程池,我構建了一個線程數爲5個線程池,而後採用分段批量提取的方式每500條爲一組數據進行圖片信息的提取,而後再把這些經過Threadpool的execute方法交給線程池中的線程進行處理,即充分使用了CPU硬件資源又加快了大數據狀況下程序的處理效率。c++

我當時在工做的過程當中,認識一個作電商的朋友,他們當時公司才起步,不少技術都不成熟,因此就經常和我探討一些技術問題,有次他向我請教一個問題,問我如何才能提升網站的性能,我根據本身在項目中的經驗以及本身之前閱讀的關於優化方面的資料給他提出了不少建議,如用lucene進行全文檢索,用memcached進行分佈式緩存,以及經過spring定時器結合freeMarker模板引擎來生成靜態頁面,因爲要生成的頁面的數量比較多,考慮到程序的性能,我建議他結合java的線程池進行工做,這樣就能夠充分使用了CPU硬件資源又加快了大數據狀況下程序的處理效率。程序員

【線程池簡述】web

線程池中,當須要使用線程時,會從線程池中獲取一個空閒線程,線程完成工做時,不會直接關閉線程,而是將這個線程退回到池子,方便其它人使用。ajax

簡而言之,使用線程池後,原來建立線程變成了從線程池得到空閒線程,關閉線程變成了向池子歸還線程。redis

2.說一下數據庫索引,什麼是索引,優勢和缺點和幾個基本的索引類型?

索引的概念

索引就是爲了提升數據的檢索速度。 數據庫的索引相似於書籍的索引。 在書籍中,索引容許用戶沒必要翻閱完整個書就能迅速地找到所須要的信息。 在數據庫中,索引也容許數據庫程序迅速地找到表中的數據,而沒必要掃描整個數據庫。

索引的優勢
 建立惟一性索引,保證數據庫表中每一行數據的惟一性
 大大加快數據的檢索速度,這也是建立索引的最主要的緣由
 減小磁盤IO(向字典同樣能夠直接定位)
複製代碼

索引的缺點

建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長 索引須要佔用額外的物理空間 當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,下降了數據的維護速度

索引的分類

  普通索引和惟一性索引    普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)    惟一性索引:保證在索引列中的所有數據是惟一的    CREATE unique INDEX mycolumn_index ON mytable (myclumn)    單個索引和複合索引    單個索引:對單個字段創建索引    複合索引:又叫組合索引,在索引創建語句中同時包含多個字段名,    最多16個字段    CREATE INDEX name_index ON userInfo(firstname,lastname)    順序索引,散列索引,位圖索引

3.http請求中的中文亂碼問題

經過瀏覽器訪問服務器頁面和資源時,不可避免地要傳送中文字串,若是客戶機與服務器不能用同一碼錶解析字串,確定會出現各     種各樣的亂碼問題。我總結了幾個亂碼場景及解決辦法,以下

  服務器上的中文字串被客戶端訪問時出現的亂碼問題
複製代碼

緣由:瀏覽器在解析中文時,不知道該用什麼碼錶去解析,就會用默認的gb2312去解析,確定會出現亂碼

解決辦法:以什麼碼錶寫入流,在響應的請求頭裏就告訴瀏覽器用什麼碼錶,例子使用utf-8 客戶端提交中文到服務端致使的亂碼

緣由:客戶端以UTF-8編碼,服務端中的request以默認的Iso8859碼錶解析

解決辦法:告訴request用UTF-8碼錶解析

多線程:

進程:當前正在運行的程序,一個應用程序在內存中的執行區域
    線程:進程中的一個執行控制單元,執行路徑
            單線程:安全性高,可是效率低
            多線程:安全性低,效率高
    一個進程能夠有一個線程,也能夠有多個線程
CPU執行線程的隨機性 (CPU高速切換致使的)
複製代碼

多線程實現的方式:

方式1:一種方法是將類聲明爲繼承Thread的子類。該子類應重寫Thread類的run方法。接下來能夠分配並啓動該子類的實例。
複製代碼

方法2:另外一種方法是聲明實現Runable接口的類。該類而後實現run方法。而後能夠分配該類的實例,在建立Thread時做爲一個參數來傳遞並啓動。

主方法是多線程????

答:主方法是單線程的,可是能夠在主方法中建立多個線程,同事執行(變爲多線程) 既然有了繼承Thread爲什麼還要整出來實現Runable???? 答:java中是單一繼承,若是一個類,繼承了一個類,就不能繼承其餘類。若是要是實現了接口,還能夠繼承別的類。

(靜態修飾 的方法,能夠直接經過{類名。方法名}調用)
    static void  sleep (long millis)   ::讓當前進程睡會
    static Thread currentThread()    ::返回當前線程對象
    Thread.currentThread().getName()    直接獲取進程的名稱
    void serName(String name)  改變線程名稱,使之與參數name相同
複製代碼

** 多個線程,一個數據,且併發訪問這個數據,就容易出錯. 怎麼解決??? 答: 這裏面須要用到一個synchronized(同步鎖),能夠修飾代碼塊和方法,被修飾的代碼塊和方法一旦被某一個線程訪問,則直接鎖住,其餘的線程將沒法訪問。 解決1. 同步代碼塊:(對象鎖就是一次只能進一個,別的線程都只能等) synchronized(鎖對象){ 這裏面是放的須要共享的代碼 }

(這個):這個能夠是對象鎖this,也能夠是類鎖.class鎖
複製代碼

注意:鎖對象須要被全部的線程付共享 同步:安全性高,效率低 異步(非同步):正好相反 安全性低,效率高 解決2. 用synchronized修改方法(放在權限修飾符以後 void以前),這個方法就變成了一個同步方法 ,也就是一個方法訪問以後,其餘線程都沒法訪問。

同步方法的: static synchronized 是類鎖 synchronized 是對象鎖

synchronize是一個可重如鎖,就是方法裏面調用方法。

對於對象,不一樣的內存地址,就是不一樣的對象,也是就不一樣的鎖。他們能夠同時執行。可是同一個鎖的時候,就不能夠同時執行。必須一個完成以後,再執行另外一個。 (判斷是不是同一個對象,不是有名稱決定的,而是經過內存地址決定的)

利用實現callable來作多線程: 適用場景:適合於處理大量事務以後,須要返回數據結果的狀況下。(基本數據類型不能當作泛型)


注意: 非靜態 同步方法的鎖對象是this 靜態的同步方法的鎖對象是當前類的字節碼對象 同步方法:使用關鍵字synchronized修飾的方法,一旦被一個線程訪問,則整個方法所有鎖住,其餘線程則沒法訪問

意外收穫:對於sleep()方法,咱們首先知道他是屬於Thread類中的。而wait()方法,則是屬於Object類中的。 sleep()方法致使了程序暫停執行指定的時間,讓出CPU給其餘的線程,可是他的監控轉態依然保持着,當指定的時間到了以後,他會自動恢復成運行狀態。在調用sleep()方法的過程當中,線程不會釋放對象鎖。 而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池準備,獲取對象鎖進入運行轉態。 sleep()必須捕獲異常,而wait,notify和notifyall不須要捕獲異常。


線程的生命週期?(一個對象的生老病死)


linux講解

1.linux操做系統比較穩定(世界級巨頭計算機,各個行業軟件服務器系統都是採用的這種語言,常見的就是系統開發人員,運維人員,程序開發人員) 2.要學習找資料鳥哥linux私房菜這本書可參照。

WebService && CXF的講解

WebService是JDK自帶的,至關於JDBC   (也就是 底層實現)
CXF是基於WebService的框架,至關於Hibernate/mybatis    (也就是 框架)
複製代碼

講解CVS,SVN(集中式)與Git(分佈式版本控制系統)

一:Git簡介

集中式版本控制系統:版本庫是集中存放在中央服務器的,用時拿出來,用完再放進去 。最大的缺點就是必須聯網才能工做,網慢還受影響。 分佈式版本控制系統:1.它相對於集中式的來講,沒有「」中央服務器「」,因此每一個人的 電腦都是一個完整的版本庫,這樣工做的時候就不須要聯網, 2.和集中式相比,分佈式的更安全,由於每一個人電腦裏都有完整的版本庫,一我的的 電腦壞了,直接從別人那直接複製一個就能夠了。而集中式的中央服務器要是壞了,全部人都 不能幹活了。( 對了,別忘了,他仍是開源的,免費的,哈哈)。 3.在實際使用分佈式版本控制系統的時候,其實不多在兩人之間的電腦上推送版本庫 的修改,由於可能大家倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天 你的同事病 了,他的電腦壓根沒有開機。所以,分佈式版本控制系統一般也有一臺充當「中央服務器」的電腦,但這個服務器的做用僅僅是用來方便「交換」你們的 修改,沒有它你們也一 樣幹活,只是交換修改不方便而已。 CVS的弊端:1.因爲CVS自身設計的問題,會形成提交文件不完整,版本庫莫名其妙損壞的狀況。 2.一樣是開源並且免費的SVN修正了CVS的一些穩定性問題,是目 前用 得最多的集中式版本庫控制系統。 3.除了免費的外,還有收費的集中式版本控制系統,好比IBM的ClearCase。

二:安裝

第三方登陸(話術)

第三方登陸採用國際通用的OAtuth協議。首先須要去第三方註冊帳號,獲取到惟一性的id和cecret安全碼,而後在咱們的網站上添加第三方的登陸圖標。例如QQ圖標,微信什麼的。接下來呢,就是一個三次握手,第一次呢就是,當用戶點擊這個圖標時,跳轉到第三方的登陸頁面,用戶登陸後會直接跳轉到咱們的回調地址,而且發送給咱們一個code隨機碼。這樣第一次握手就完成了。而後咱們將這個code隨機碼和id,seret安全碼發送給第三方(利用HttpClient,發送的post請求)。這時候第三方會返回給咱們一個token令牌(其中包含了第三方的一些相關信息)。這樣第二次握手就算完成了。可是此次獲取到的信息通常不全,因此咱們還須要根據用戶綁定的狀態再一次查詢。也就有了第三次握手。第三次在利用token碼在發送請求。(通常是爲了獲取用戶名,頭像,性別,住址)。假如是第一次登錄,咱們會給第三方發送一個綁定帳號的請求,將咱們的網站與第三方網站綁定。以後跳轉到用戶信息完善頁面,讓用戶把信息補全。最後將第三方帳號信息保存到咱們本身的數據庫中。假如以前登錄過,那麼咱們會根據用戶信息到本身的數據庫中查詢出以前添加的信息,並保存在session中,而後跳轉到首頁,這樣第三次握手就算完成了。也就完成了第三方帳號在咱們網站的登陸。

電商如何處理高併發的狀況

處理高併發的狀況,通常咱們想到的是經過分流的方式,加快系統的吞吐量,和業務的優化這三方法。在分流方面咱們採用的是用Ngnix作負載均衡和反向代理。在系統吞吐量上咱們採用的是redis作緩存處理。在文件的存儲上咱們能夠採用fastdfs作存儲。頁面呢能夠用freemarker靜態化技術作靜態頁面。與數據庫有關的業務能夠採用分庫分表的形式,來提供數據庫的效率。方法呢有不少,主要呢就是根據系統的壓力和場景來選擇適合本身網站的方式就能夠了。

關於支付的話術

其實全部的第三方支付都差很少,就是根據他們提供額文檔直接寫實現本身的業務邏輯就能夠了,他們的接口須要什麼樣的數據,就給他們什麼樣的數據就能夠了。支付成功後會跳轉到咱們的回調接口。(網站想要與第三方登陸平臺對接,就須要先去該平臺註冊商戶號以及商戶祕鑰)

支付寶支付:

買家點擊確認付款後咱們會根據訂單號去調用訂單服務提供的dubbo獲取該訂單的信息。同時咱們會給支付寶發送一個請求,(當中包含商戶號,祕鑰,回調地址,加密簽名(MD5加密(編號+商戶號+總價格))等支付信息)。並將支付信息保存到咱們的訂單表以及訂單詳情表中。同時頁面也跳轉到支付寶的支付頁面。買家支付完成後,支付寶會把支付結果發送給咱們的回調地址。支付結果中會有一個通知id,咱們須要將通知id做爲參數調用支付寶給咱們的支付結果查詢接口。去查詢支付結果是否正確。主動查詢主要是爲了,防止咱們的回調地址泄露。查詢結果接口會給咱們返回一個以XML形式的查詢信息。告訴咱們該通知id是不是以支付寶發起,而且該支付信息是否有效。咱們還須要根據用戶的實際支付金額和理應支付金額作判斷,若是一直,而且通知id也有效,那麼久認爲該用戶支付成功。而後根據用戶信息跳轉到支付結果頁面,而且更新數據庫中的支付信息。這樣支付就完成了。

微信支付:

訂單管理

首先是訂單表的設計,主要包括訂單表和訂單詳情表,訂單表主要包含訂單的主要信息,好比訂單的編號、總額、數量、狀態、收貨人信息等。其中收貨人信息必需要冗餘到訂單表中,不能簡單用Id進行管理。訂單詳情表和訂單表是多對一關係,訂單詳情表主要計量訂單中的商品的詳細信息,這些信息也要冗餘進來,不能經過id進行簡單的關聯,由於訂單一旦生成,這些信息通常不會再容許改變。

訂單在用戶結算購物車時生成,若是同時購買多個商家的商品,在結算購物車時須要進行分單,同時生成多張訂單。在用戶中心,每一個用戶均可以看到並跟蹤本身的訂單,進行支付、申請退貨、確認收貨、評價等操做。商家後臺能夠看到商家本身的全部訂單,進行確認發貨操做。而在運營管理平臺,能夠監控全部的訂單,可是不能進行操做。

訂單的狀態主要包括:待支付、待發貨、已發貨、已完成、已取消;

生成訂單時,應該對庫存進行一次校驗,防止超賣;

單點登陸

咱們的單點登陸系統,主要包含了登陸驗證、token校驗、註銷、註冊幾大功能,單點登陸系統提供了統一的登陸和註冊頁面,提供了統一的登陸token校驗接口。

單點登陸的主要原理就是在登陸成功之後,生成一個令牌,這個令牌要求每次登陸惟一不可重複,咱們就簡單的用了一個隨機的UUID,由於咱們的系統在部署時,各個模塊都是經過Nginx映射到同一個一級域名下的,cookie只要把他的做用域設置成一級域名,就能夠在全部同一個一級域名下的模塊中共享。因此咱們把隨機生成的token,以字符串 「token」爲key,放在cookie裏邊,而後用生成的token作key,用戶對象信息轉成json字符串後,做爲value,放到redis裏邊,都設置有效期30分鐘;

而後作了一個統一校驗token的接口;各個模塊在本身的攔截器裏邊,調用此token校驗接口,驗證是否登陸,若是返回null,則說明沒有登陸,攔截到統一的登陸頁面,並把進入攔截到的url放入cookie裏邊,方便登陸成功之後,獲取這個url,進行原路徑跳轉,而不是每次登陸都進入首頁,提供用戶的體驗度。若是返回用戶信息,則說明已經登陸,模塊建立本身的session,並放行url。統一校驗token的接口的主要流程是,首先從cookie裏邊獲取到token,而後經過token到redis裏邊獲取用戶信息。這兩個過程,任何一個失敗,都直接返回null,若是成功,就把cookie和token的值重新設置一遍(這個是爲了刷新有效期);?這樣就實現了多個模塊只須要登陸一次就能夠的流程。

還有就是註銷,註銷也是調用統一的註銷接口,註銷時須要首先從cookie中獲取token,根據token刪除redis中的用戶信息,而後在刪除cookie中的token。

MQ消息隊列

MQ簡稱消息隊列,他是一個不一樣項目之間進行通信時,對消息進行管理的組件。有了MQ,能夠使項目之間交互由同步轉換成異步,解耦了消息的處理過程。把消息統一管理起來,按照順序,根據客戶端的處理能力一個一個的進行操做,MQ具備送達保證、排序保證、峯值處理、異步通訊幾大特性。在高併發時,對於減輕數據庫壓力很是有效。MQ通常有點對點和發佈訂閱兩種方式,點對點就是一個消息只容許接收一次,發佈訂閱模式,一個消息能夠被屢次接收。目前主流的產品有RabbitMQ、ActiveMQ和Kafka;ActiveMq是Java語言開發的,RabbitMQ是Erlang語言開發的,理論上,RabbitMQ的性能比ActiveMq更強,是非Java系統的首選,ActiveMq是Java的,整套系統若是原本就是Java的,配合的默契更佳。Kafka至關於一個分佈式的MQ,傳統的MQ,消息被消化掉後會被mq刪除,而kafka中消息被消化後不會被刪除,而是到配置的expire時間後,才刪除,他把寫入壓力均攤到各個節點。能夠經過增長節點下降壓力;

anjularJS

AngularJS 是一個 JavaScript 框架。它是一個以 JavaScript 編寫的庫。它通常用在 數據操做比較多的應用。爲了實現這些,AngularJs引入了一些很是棒的特性,包括模板機制、數據綁定、指令、依賴注入、路由等。數據綁定多是AngularJS最酷最實用的特性。經過數據與模板的綁定,可以讓咱們擺脫繁瑣的DOM操做,而將注意力集中在業務邏輯上。AngularJS內置了不少指令用來控制模板,如ng-repeat,ng-class等,也有不少指令來幫咱們完成業務邏輯。還有AngularJS服務啊路由之類的功能也都是很是實用的。AngularJS不依賴(也不妨礙)任何其餘的框架,咱們甚至能夠基於其它的框架來開發AngularJS應用。在咱們以前的一個項目中也用到了AngularJS,經過AngularJS,咱們實現了先後端分離開發,前端使用路由,頁面的性能會有很大的提高,同時也會減小後端的壓力,頁面跳轉能夠不須要通過後端,後端只負責提供數據作爲展現。

HTTPClient

HttpClient字面理解就是http請求的客戶端,他是Apache開發的一套HTTP協議的客戶端編程工具包。是純Java語音編寫的,支持https協議,實現了http的get、post、delete、put等所有方法,但咱們通常只用get和post方法,用httpclient能夠直接跨域請求http協議的url,並攔截返回的響應結果。

咱們項目裏邊有寫好的工具類,裏邊封裝好了他的get和post方法,傳入url和參數,返回String類型數據(通常是json字符串或xml字符串),而後咱們進行解析就能夠了。

他的調用步驟是:

1.建立HttpClient對象。

2.建立請求方法的實例,並指定請求URL。若是須要發送GET請求,建立HttpGet對象;若是須要發送POST請求,建立HttpPost對象。

3.若是須要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HetpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。

4.調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse。

5.調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可經過該對象獲取服務器的響應內容。

6.釋放鏈接。不管執行方法是否成功,都必須釋放鏈接

Shiro

Apache Shiro是java的一個安全框架,比Spring Security要簡單的多,可是沒有Spring Security他的功能強大。Shiro主要有登陸認證,受權,會話管理這三大功能。另外添加了加密、緩存、web基礎等功能。但它不會去維護用戶和權限。這個還須要咱們本身去完成。它的基本工做流程就是:首先咱們經過SecurityUtils來獲取Subject,用它來進行認證和受權,而後經過安全管理器securityManager來管理全部的Subject. 給Shiro的securityManeger中注入Realm.經過realm獲取相應的用戶進行比較來肯定用戶身份是否合法。同時也須要中獲得用戶相應的角色和權限進行用戶驗證是否能夠進行操做。框架中使用通常是,先導入相關jar包,web.xml中加shiro-filter過濾器,配置shiro.xml,裏邊配置過濾器和安全管理器,還能夠自定義form 認證過濾器、自定義realm(領域)、加密等。他提供了多種受權方式;編程受權、註解受權、jsp標籤受權。

springboot和springcloud

spring boot 我理解就是把 spring,spring-mvc,spring-data-jpa 等等的一些經常使用的經常使用的基礎框架組合起來,提供默認的可插拔的設計配置。spring boot對spring的配置進行簡化,幾乎零配置。同時對spring 須要的jar 也進行了整合,解決jar衝突的問題。能夠理解爲springMvc的升級版。提供了spring-boot-starter-parent的整合工具包。集成了它之後,項目中大部分jar包就再也不引用了。內置了Tomcat插件,能夠直接用main方法運行;

spring_cloud是基於spring_boot的微服務分佈式架構,他主要包括:

服務註冊中心:Eureka Server 服務註冊者客戶端:Eureka Client 服務消費端:負載均衡客戶端:ribbon和feign 斷路器Hystrix 路由網關zuul(Zuul的主要功能是路由轉發和過濾器,zuul默認和Ribbon結合實現了負載均衡的功能。)

事務的隔離級別

髒讀:一個事務看到了另外一個事務沒有提交的更新數據。
     不可重複:在同一事物中,屢次讀取數據可是返回不一樣的結果。
     幻讀:一個事務在執行過程當中讀取到另外一個事務已提交的插入數據。這是併發形成的。
複製代碼

事務的傳播特性

  1. requierd: 若是當前沒有事務,就新建一個事務,若是有事務,就加入這個事務中。
  2. requierd_new: 新建事務,若是當前有事務,就把當前事務掛起。
  3. supports: 支持當前事務,若是當前沒有事務,就以非事務方法執行。
  4. not_supports: 就以非事務方法執行,若是當前存在事務,就把事務掛起。
  5. mandatory: 使用當前事務,若是沒有當前事務就拋異常。
  6. never: 就以非事務方法執行,若是有事務就拋異常。
  7. nested: 若是當前存在事務,就嵌套在事務內執行。若是當前沒有事務,就執行與 required相似的操做(至關於若是沒有就是默認required)。 required(必修的) mandatory(強制性的) nested(嵌套的)

利用docker部署(基本話術)

利用docker作項目部署,首先得知道Dockerfile,dockerfile其實就是一些腳本,就是能把代碼變成鏡像的一種腳本。他和maven插件的功能是同樣的。這須要好幾步才能實現,因此爲了方便,又須要藉助jenkins,jenkins算是一種工具,他把dockerfile的步驟放進了jenkins中,而後只須要一個按鈕,就能實現dockerfile的功能。因此只要配好了jenkins是就方便了好多。二Gogs是jenkins中的一個東西。比較難懂的一個。

Nginx負載均衡是怎麼搭建的?

首先,在linux下裝一個Nginx,必需要有依賴,如:prce正則依賴。還有pcc,c++等。依賴都配置好後才能夠裝nginx。Nginx集羣主要是nginx.conf中配置,conf中的service中location下的proxy_pass配置一個tomcat服務中的引用,另外還要配置一個upstream中ip地址端口號,service中tomcat的引用的是upstream的名字。另外,負載均衡實在upstream中配置,來引用的tomcat的IP地址和端口號後面跟一些參數,來配置權重,參數有weigt,backup等等。

session共享是怎麼作的?

使用Nginx作的反向代理。session共享實現有多種方式,好比能夠本身寫一個filter來攔截請求,而後從請求中取得session的id,而後根據session的id在緩存中查找對應的session。可是我用的是spring對session的管理。實際上spring對session的管理也是基於filter實現的。(若是細問怎麼作的,就這樣回答:1.先導入依賴。2.在web.xml中配置一個filter的過濾器。3.在spring配置文件中,配置spring對session管理的實現。4.把redis集成在項目)

JVM

堆: 分爲兩部分新生代和老年代(老年代:須要長時間保留的;新生代:用完就得銷燬的) 都會先放在新生代中,等到他年齡大的必定的時候,就會放在老年代中(經歷了不少次都沒有被清理的) 新生代的掃描策略和老年代的掃描策略是不同的。 新生代:能夠分爲三部分(伊甸園,S0(From),S1(To)) 根據執行GC()的次數, S0,S1是兩塊大小相等,功能相同的內存空間。同一時間,只能有一個在(使用)運行轉態。(爲了時刻都在 緊挨着) 棧: 一個棧有三部分:(局部變量表,操做數棧和幀數據區)

java虛擬機原理:系統虛擬機和程序虛擬機 虛擬機的結構:類加載子系統,堆,棧,直接內存,方法區,本地方法棧,執行引擎,垃圾回收機制,PC收集器

重要的一些概念:

  1. 在java中對象實例都是在堆中建立的,一些類信息,常量,和靜態變量回放在方法區中,這個堆和方法區都是線程共享的。 2.GC機制是有JVM提供的,用來清理須要清理的對象,回收堆內存的。 3.GC機制是將java程序員從內存管理中解放出來的,因此它更關注於業務邏輯。 4.在java中,GC是有一個叫垃圾回收器的守護線程所執行的。 5.在內存中回收一個對象,首先就須要調用finalize()方法。 6.做爲一個java程序員,不能強制JVM執行GC,這個是由堆內存的大小決定的。 7.System.gc()和Runtime.gc()會向JVM發送執行GC的請求,可是JVM不必定會執行。 8.若是堆沒有新的內存建立新的對象了,那麼會拋出OutOfMemoryError.

哪些對象回唄GC回收呢???

通常GC須要有三件事須要作:1.那些對象須要被回收 2.什麼時候回收這些對象 3.採用什麼樣的方式能夠回收(常見的有引用計數法) 引用計數法:給對象添加一個引用計數器,每當有一個地方引用了,計數器就+1,當引用失效後,計數器就-1;在任什麼時候候計數器都爲0時,就表示這個對象不可能被使用。 當一個對象經過一系列的根對象都不可達時就會被回收。通俗易懂的就是:當一個對象的全部引用都爲null.

GC的算法有哪些?

1.複製算法:就是有兩個相同的區域,每次只使用一個其中一個(堆中的年輕代的處理方法就是複製算法) 2.標記清除算法:就是先標記處全部須要回收的對象,而後統一回收。 3.標記整理算法:就是先標記出全部須要的回收對象,只不過是先整理一遍,就是讓全部存活的對象都向一端移動,而後清理。

SQL的優化

致使查詢慢的緣由:

1.數據量過大
2.表設計不合理
3.sql語句寫的很差
4.沒有合理使用索引
複製代碼

針對sql語句的優化:

1.查詢中不適用*
2.儘可能減小子查詢,使用關聯查詢(left join,right join  等等)替代
3.合理的增長冗餘字段
4.建表的時候能使用數字類型的字段就使用數字類型字段,由於數字類型的字段比字符類型的要查詢起來快的多。
5.哪些能夠過濾掉最大數量記錄的條件必須寫在where字句的最末尾
複製代碼

說索引前,顯瞭解一下這個explain(查看sql的執行計劃):

最終要的就是:
select_type:sql語句的難易程度;
type:表示表的鏈接類型(ALL:說明對錶進行了完成的)
rows:查詢是受影響的行數。
複製代碼

補充: (使用explain查看sql執行計劃後,咱們主要先看下type屬性,表示鏈接的類型,若是是ALL這種那就須要優化了, 再看下possible_key屬性,表示能夠使用的索引,若是沒有則爲null,key屬性表示mysql實際決定使用的索引,若是沒有選擇索引,鍵是null, rows 表示mysql認爲它執行查詢時必須檢查的行數,行數越多效率越低。)

索引的類型:通常分爲:主鍵索引,惟一索引,組合索引,普通索引。 什麼是索引:數據庫索引是數據庫管理系統中的一個排序的數據結構,以協助快速查詢,更新數據 庫表中數據,索引的實現一般使用B樹(B-tree)以及其變種B+tree(一些高效率的算法)

注意事項:

一、使用like關鍵字模糊查詢時,% 放在前面索引不起做用,只有「%」不在第一個位置,索引纔會生效(like '%文'--索引不起做用) 二、使用聯合索引時,只有查詢條件中使用了這些字段中的第一個字段,索引纔會生效 三、使用OR關鍵字的查詢,查詢語句的查詢條件中只有OR關鍵字,且OR先後的兩個條件中的列都是索引時,索引纔會生效,不然索引不生效。 四、儘可能避免在where子句中使用!=或<>操做符,不然引擎將放棄使用索引而進行全表掃描。 五、對查詢進行優化,應儘可能避免全表掃描,首先應考慮在where以及order by涉及的列上創建索引。 六、應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描。如:   select id from t where num/2=100   應改成:   select id from t where num=100*2 七、儘可能避免在where子句中對字段進行函數操做,將致使引擎放棄使用索引而進行全表掃描。 八、不要在 where 子句中的「=」左邊進行函數、算術運算或其餘表達式運算,不然系統將可能沒法正確使用索引。 九、並非全部的索引對查詢都有效,sql是根據表中的數據來進行查詢優化的,當索引列有大量數據重複時,sql查詢不會去利用索引,如一表中有字段   sex,male,female幾乎個一半,那麼即便在sex上創建了索引也對查詢效率起不了做用。 十、索引並非越多越好,索引當然能夠提升相應的 select 的效率,但同時也下降了 insert 及 update 的效率,   由於 insert 或 update 時有可能會重建索引,因此怎樣建索引須要慎重考慮,視具體狀況而定。一個表的索引數最好不要超過6個,   若太多則應考慮一些不常使用到的列上建的索引是否有 必要。 十一、儘可能使用數字型字段,若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。   這是由於引擎在處理查詢和鏈接時會 逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。 十二、mysql查詢只使用一個索引,所以若是where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。    所以數據庫默認排序能夠符合要求的狀況下不要使用排序操做,儘可能不要包含多個列的排序,若是須要最好給這些列建複合索引。 1三、order by 索引 ,不起做用的問題(除了主鍵索引以外):   一、 若是select 只查詢索引字段,order by 索引字段會用到索引,要否則就是全表排列;

   二、若是有where 條件,好比where vtype=1 order by vtype asc . 這樣order by 也會用到索引!

總結(優化數據庫的八種方法): 1.選取最適用的字段屬性 2.使用鏈接(join)來代替子查詢。 3.使用聯合(UNION)來代替手動建立的臨時表 4.事務 5.鎖定表 6.使用外鍵 7.使用索引 8.優化的查詢語句

死鎖

什麼是死鎖?

標準定義:
  本身的理解:一座獨木橋上有兩輛車,此刻都在橋上(誰也不能前進,誰也不能後退),就這樣耗着。造成死局面。
複製代碼

產生死鎖的必要條件:

1.互斥條件:如獨木橋就是一種獨佔資源,兩方的人不能同時過橋。
  2.不可搶佔條件:如過獨木橋的人不能強迫對方後退,也不能非法地將對方推下橋,必須是橋上的人本身過橋後空出橋面(即主動釋放佔有資源),對方的人才能過橋。
  3.佔有且申請條件:甲過不去,前進不能,又不後退;乙也處於一樣的情況。
  4.循環等待條件:就像前面的過獨木橋問題,甲等待乙佔有的橋面,而乙又等待甲佔有的橋面,從而彼此循環等待。
複製代碼

死鎖的預防:

方法:只要破壞了前面提到的四個必要條件中的任意一個條件,死鎖就不會發生。(通常地,解決死鎖的方法分爲死鎖的預防,避免,檢測與恢復三種) 具體方法:也就是打破四個必要因素。 死鎖的恢復: 一旦在死鎖檢測時發現了死鎖,就要消除死鎖,使系統從死鎖狀態中恢復過來。

(1)最簡單,最經常使用的方法就是進行系統的從新啓動,不過這種方法代價很大,它意味着在這以前全部的進程已經完成的計算工做都將付之東流,包括參與死鎖的那些進程,以及未參與死鎖的進程。

(2)撤消進程,剝奪資源。終止參與死鎖的進程,收回它們佔有的資源,從而解除死鎖。這時又分兩種狀況:一次性撤消參與死鎖的所有進程,剝奪所有資源;或者逐步撤消參與死鎖的進程,逐步收回死鎖進程佔有的資源。通常來講,選擇逐步撤消的進程時要按照必定的原則進行,目的是撤消那些代價最小的進程,好比按進程的優先級肯定進程的代價;考慮進程運行時的代價和與此進程相關的外部做業的代價等因素。 
複製代碼

此外,還有進程回退策略,即讓參與死鎖的進程回退到沒有發生死鎖前某一點處,並由此點處繼續執行,以求再次執行時再也不發生死鎖。雖然這是個較理想的辦法,可是操做起來系統開銷極大,要有堆棧這樣的機構記錄進程的每一步變化,以便從此的回退,有時這是沒法作到的。

搜索引擎——solr

什麼是solr?

solr是一個開源的搜索平臺,用於構建搜索應程序。它創建在Lucene(全文搜索引擎)之上。solr是企業級的,快速的和高度可擴展的。

Maven

Maven是一個項目管理工具,其核心特色就是經過maven能夠進行包的依賴管理,保證jar包版本的一致性,以及能夠使多個項目共享jar包,從而可以在開發大型應用的時候,減少項目的規模。

爲了節省下jar包的時間?咱們能夠採用了nexus搭建了在局域網內的maven私服,而後經過配置settings.xml中創建mirror鏡像,將全部下載jar包的請求都轉發到maven私服上,以後經過在pom.xml,及中配置項目所依賴的jar包,從而達到在構建項目的時候,先從本地倉庫中查找,若是不存在從內部私服查找,若是不存在最後再從外網central服務器查找的機制,達到了節省下載寬帶,提升開發效率,以及jar包重用的目的。

spring中的IOC和AOP(話術)

IOC: ioc另一種說話叫作DI,既依賴注入。它並非一種技術實現,而是一種設計思想。在任何一個實際開發意義的程序項目中,咱們會使用不少的類來描述他們特有的功能,而且經過類與類之間的相互協做來完成特定的業務邏輯。這個時候,每一個類都須要負責管理與本身有交互的類的引用和依賴。這時候代碼將變得異常難易維護和極度的高耦合。而IOC的出現真實來解決這個問題的。咱們經過IOC將這些相互依賴對象的建立、協調工作交給spring容器來處理,每一個對象只須要關注其自身的業務邏輯就能夠了。在遮掩那個的角度上來看,得到依賴的對象方式,進行了反轉,變成了與spring容器控制對象如歌獲取外部資源。(舉例:就是頭疼病人去醫院買藥的例子。本身選藥很難受,因此就直接找醫生,讓醫生配藥,直接吃就好。IOC起到的就是醫生的做用,他收集你的需求要需,而且對症下藥。直接開藥給你。你就是對象,藥品就是你所須要的外部資源。)

什麼是AOP? 面向切面編程(AOP)完善spring的依賴注入(DI),面向切面編程在spring中主要表現爲兩個方面 1.面向切面編程提供聲明式事務管理 2.spring支持用戶自定義的切面

面向切面編程(aop)是對面向對象編程(oop)的補充, 面向對象編程將程序分解成各個層次的對象,面向切面編程將程序運行過程分解成各個切面。 AOP從程序運行角度考慮程序的結構,提取業務處理過程的切面,oop是靜態的抽象,aop是動態的抽象, 是對應用執行過程當中的步驟進行抽象,,從而得到步驟之間的邏輯劃分。

aop框架具備的兩個特徵: 1.各個步驟之間的良好隔離性 2.源代碼無關性

Spring的事務管理機制實現的原理,就是經過這樣一個動態代理對全部須要事務管理的Bean進行加載,並根據配置在invoke方法中對當前調用的 方法名進行斷定,並在method.invoke方法先後爲其加上合適的事務管理代碼,這樣就實現了Spring式的事務管理。Spring中的AOP實 現更爲複雜和靈活,不過基本原理是一致的。

Lucene原理

Lucene 是apache軟件基金會一個開放源代碼的全文檢索引擎工具包,是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎。它不是一個完整的搜索應用程序,而是爲你的應用程序提供索引和搜索功能。lucene 可以爲文本類型的數據創建索引,因此你只要能把你要索引的數據格式轉化的文本的,Lucene 就能對你的文檔進行索引和搜索。好比你要對一些 HTML 文檔,PDF 文檔進行索引的話你就首先須要把 HTML 文檔和 PDF 文檔轉化成文本格式的,而後將轉化後的內容交給 Lucene 進行索引,而後把建立好的索引文件保存到磁盤或者內存中,最後根據用戶輸入的查詢條件在索引文件上進行查詢。

索引和搜索: Lucene 採用的是一種稱爲反向索引(inverted index)的機制。反向索引就是說咱們維護了一個詞 / 短語表,對於這個表中的每一個詞 / 短語,都有一個鏈表描述了有哪些文檔包含了這個詞 / 短語。這樣在用戶輸入查詢條件的時候,就能很是快的獲得搜索結果。搜索引擎首先會對搜索的關鍵詞進行解析,而後再在創建好的索引上面進行查找,最終返回和用戶輸入的關鍵詞相關聯的文檔。對於中文用戶來講,最關心的問題是其是否支持中文的全文檢索。因爲Lucene良好架構設計,對中文的支持只需對其語言詞法分析接口進行擴展就能實現對中文檢索的支持。

索引步驟: 1.獲取內容:lucene做爲一款核心搜索庫,不提供任何功能來實現內容獲取。利用大量的開源爬蟲軟件實現這個功能 2.創建文檔:獲取原始內容後,須要對這些內容進行索引,必須將這些內容轉換成部件(文檔)。文檔主要包括幾個帶值的域,好比標題,正文,摘要,做者和連接。若是文檔和域比較重要的話,還能夠添加權值。 3.文檔分析:搜索引擎不能直接對文本進行索引:必須將文本分割成一系列被稱爲語彙單元的獨立的原子元素。每個語彙單元能大體與語言中的「單詞」對應起來,這個步驟決定文檔中的文本域如何分割成語彙單元系列。lucene提供了大量內嵌的分析器能夠輕鬆控制這步操做。 4.文檔索引:將文檔加入到索引列表中。Lucene在這一步驟中提供了強檔的API,只需簡單調用提供的幾個方法就能夠實現出文檔索引的創建。爲了提供好的用戶體驗,索引是必需要處理好的一環:在設計和定製索引程序時必須圍繞如何提升用戶的搜索體驗來進行。

Elasticsearch簡介:

Elasticsearch是一個實時的分佈式搜索和分析引擎。它能夠幫助你用史無前例的速度去處理大規模數據。它能夠用於全文搜索,結構化搜索以及分析,固然你也能夠將這三者進行組合。

ES的優勢:

1.Elasticsearch是分佈式的。不須要其餘組件,分發是實時的。 2.Elasticsearch 徹底支持 Apache Lucene 的接近實時的搜索。 ES的缺點: 1.只有一個開發者。 2.還不夠自動。

Solrs簡介:

Solr是最流行的企業級搜索引擎。Solr是用Java編寫、運行在Servlet容器。的一個獨立的全文搜索服務器。Solr採用了 Lucene Java 搜索庫爲核心的全文索引和搜索,並具備相似REST的HTTP/XML和JSON的API。Solr強大的外部配置功能使得無需進行Java編碼,即可對 其進行調整以適應多種類型的應用程序。Solr有一個插件架構,以支持更多的高級定製。
複製代碼

優勢:

1.Solr有一個更大、更成熟的用戶、開發和貢獻者社區。 2.支持添加多種格式的索引,如:HTML、PDF、微軟 Office 系列軟件格式以及 JSON、XML、CSV 等純文本格式。 3.Solr比較成熟、穩定。 4.不考慮建索引的同時進行搜索,速度更快。 缺點: 1.創建索引時,搜索效率降低,實時索引搜索效率不高。 2.當單純的對已有數據進行搜索時,Solr更快。 3.當實時創建索引時, Solr會產生io阻塞,查詢性能較差, Elasticsearch具備明顯的優點。 4.隨着數據量的增長,Solr的搜索效率會變得更低,而Elasticsearch卻沒有明顯的變化。 5.綜上所述,Solr的架構不適合實時搜索的應用。

Elasticsearch 與 Solr 的比較總結:

1.兩者安裝都很簡單; 2.Solr 利用 Zookeeper 進行分佈式管理,而 Elasticsearch 自身帶有分佈式協調管理功能; 3.Solr 支持更多格式的數據,而 Elasticsearch 僅支持json文件格式; 4.Solr 官方提供的功能更多,而 Elasticsearch 自己更注重於核心功能,高級功能多有第三方插件提供; 5.Solr 在傳統的搜索應用中表現好於 Elasticsearch,但在處理實時搜索應用時效率明顯低於 Elasticsearch。 6.Solr 是傳統搜索應用的有力解決方案,但 Elasticsearch 更適用於新興的實時搜索應用。

*****************************************mongodb簡介 MongoDB是一個基於分佈式文件存儲的數據庫。由C++語言編寫。MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。它支持的數據結構很是鬆散,是相似json的bson格式,所以能夠存儲比較複雜的數據類型。Mongo最大的特色是它支持的查詢語言很是強大,其語法有點相似於面向對象的查詢語言,幾乎能夠實現相似關係數據庫單表查詢的絕大部分功能,並且還支持對數據創建索引。 特色: 1.它的特色是高性能、易部署、易使用,存儲數據很是方便。 2.模式自由。 3.支持動態查詢。 4.支持徹底索引,包含內部對象。 5.支持查詢。 6.支持複製和故障恢復。 7.使用高效的二進制數據存儲,包括大型對象(如視頻等)。 使用原理: 所謂「面向集合」(Collection-Oriented),意思是數據被分組存儲在數據集中,被稱爲一個集合(Collection)。每一個集合在數據庫中都有一個惟一的標識名,而且能夠包含無限數目的文檔。集合的概念相似關係型數據庫(RDBMS)裏的表(table),不一樣的是它不須要定義任何模式(schema)。Nytro MegaRAID技術中的閃存高速緩存算法,可以快速識別數據庫內大數據集中的熱數據,提供一致的性能改進。 MongoDB適用的場景: 1.網站實時數據處理:Mongo 很是適合實時的插入,更新與查詢,並具有網站實時數據存儲所需的複製及高度伸縮性。 2.緩存:因爲性能很高,Mongo 也適合做爲信息基礎設施的緩存層。在系統重啓以後,由Mongo 搭建的持久化緩存層能夠避免下層的數據源過載。 3.高伸縮性的場景:Mongo 很是適合由數十或數百臺服務器組成的數據庫,Mongo 的路線圖中已經包含對MapReduce 引擎的內置支持。 MongoDB不適用的場景: 1.要求高度事務性的系統。 2.傳統的商業智能應用。 3.複雜的跨文檔級聯查詢。

數據模型:一個MongoDB 實例能夠包含一組數據庫,一個DataBase 能夠包含一組Collection(集合),一個集合能夠包含一組Document(文檔)。一個Document包含一組field(字段),每個字段都是一個key/value pair。 key: 必須爲字符串類型。 value:能夠包含以下類型。 ● 基本類型,例如,string,int,float,timestamp,binary 等類型。 ● 一個document。 ● 數組類型。

**********************************************Websocket(HTML5出的東西) 要想了解websocket,咱們首先須要瞭解http協議。websocket是一個新協議,跟http協議基本沒有關係,只是爲了兼容現有瀏覽器的握手規範而已,也就是它是HTTP協議上的一種補充。有交集可是並非所有。

Wrbsocket的優勢:持久性,被動性(就是服務器能夠主動給客戶推送消息了,HTTP不能夠。)

介紹Websocket以前須要先說一下這個,long poll和ajax的原理。 ajax輪詢(須要更快的速度):讓瀏覽器隔幾秒就發送一次請求,詢問服務器是否有新信息。 long poll(須要更多的電話):它的原理跟 ajax輪詢 差很少,都是採用輪詢的方式,不過採起的是阻塞模型(一直 打電話,沒收到就不掛電話),也就是說,客戶端發起鏈接後,若是沒消息,就一直不返回Response給客戶端。 直到有消息才返回,返回完以後,客戶端再次創建鏈接,周而復始。

Websocket的做用:

只要websocket鏈接成功後,以後就能夠源源不斷的傳遞消息了;只須要確認一次身份信息,就不再用了。比http要效率高,這也就是他的持久性。
 被動性就是,就是websocket鏈接成功後,服務端能夠直接給客戶端推送消息,而傳統的http是不能夠的。
複製代碼

傳統的HTTP協議是無轉態的。

Websocket的工做流程:

瀏覽器經過JavaScript向服務端發出創建WebSocket鏈接的請求,在WebSocket鏈接創建成功後,客戶端和服務端就能夠經過 TCP鏈接傳輸數據。由於WebSocket鏈接本質上是TCP鏈接,不須要每次傳輸都帶上重複的頭部數據,因此它的數據傳輸量比輪詢和Comet技術小 了不少。本文不詳
複製代碼

細地介紹WebSocket規範,主要介紹下WebSocket在Java Web中的實現。

Websocket裏面的註解: @ServerEndpoint 註解是一個類層次的註解,它的功能主要是將目前的類定義成一個websocket服務器端, 11 * 註解的值將被用於監聽用戶鏈接的終端訪問URL地址,客戶端能夠經過這個URL來鏈接到WebSocket服務器端

分佈式事務

正常的:就是用的事務管理器(transactionManager)
複製代碼

在分佈式的項目裏,用的是分佈式事務管理。不一樣的框架,使用不一樣的分佈式事務。dubbo框架、springcloud等框架。不一樣的框架,解決方案不同。 Springcloud框架,利用lcn來處理分佈式事務。利用redis作事務的解決。微服務在每次操做的時候,都須要在redis在存放一個標識符。等所有都完成以後,就提交。 dubbo框架:利用transaction這個中間件來實現分佈式事務。還有一種方法就是經過RocketMQ,利用其它的MQ也是能夠的。

Hashtable與ConcurrentHashMap的區別

衆所周知,Hashtable是安全的,可是效率低下。而ConcurrentHashMap在這兩方面都挺好的。這是爲何呢? HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的狀況下HashTable的效率很是低下。由於當一個線程訪問HashTable的同步方法時,其餘線程訪問HashTable的同步方法時,可能會進入阻塞或輪詢狀態。如線程1使用put進行添加元素,線程2不但不能使用put方法添加元素,而且也不能使用get方法來獲取元素,因此競爭越激烈效率越低。 HashTable容器在競爭激烈的併發環境下表現出效率低下的緣由,是由於全部訪問HashTable的線程都必須競爭同一把鎖,那假如容器裏有多把鎖,每一把鎖用於鎖容器其中一部分數據,那麼當多線程訪問容器裏不一樣數據段的數據時,線程間就不會存在鎖競爭,從而能夠有效的提升併發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術,首先將數據分紅一段一段的存儲,而後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其餘段的數據也能被其餘線程訪問。

ConcurrentHashMap的結構分析

ConcurrentHashMap是由Segment數組結構和HashEntry數組結構組成。Segment是一種可重入鎖ReentrantLock,在ConcurrentHashMap裏扮演鎖的角色,HashEntry則用於存儲鍵值對數據。一個ConcurrentHashMap裏包含一個Segment數組,Segment的結構和HashMap相似,是一種數組和鏈表結構, 一個Segment裏包含一個HashEntry數組,每一個HashEntry是一個鏈表結構的元素, 每一個Segment守護者一個HashEntry數組裏的元素,當對HashEntry數組的數據進行修改時,必須首先得到它對應的Segment鎖。
複製代碼

HashMap的講解

1.HashMap是基於數組和單向鏈表的。在這裏在解釋一下什麼是單向鏈表。就是隻有下一個(next),沒有上一個。具體的就是總共有(next,key,value,entity)這四個。 2.在這裏必定要清楚HashMap怎麼存值。他是單向鏈表,通俗易懂的說就是一個鏈裏套了另外一個鏈。新添的數據老是在最外層。最先的數據都在鏈表的最裏層。 3.還有就是一個擴容,HashMap擴容是根據負載因子決定的。通常負載因子默認是0.75。總數據的長度*0.75就是擴容節點。但在這裏必定要記得,並非確定到了這個時候都須要擴容。還得根據有沒有影響HashMap的總體效率。若是影響了,則擴容。若是沒有影響,就不擴容。(拿在這裏就要問,怎麼樣纔算應算效率了呢。那麼首先得知道,HashMap查詢是怎麼查的。他是根據數組的鏈的長度決定的。鏈的長度越短,效率越高。因此假若有一個數組還爲空*****,而其餘的數組上鍊表的長度沒有變化,是不影響整個HashMap的效率的)2

HashMap與Hashtable的區別

1.HashMap是不安全的,而Hashtable是安全的。(主要是由於Hashtable每一個方法上都有synchronized) 2.HashMap有且容許一個key爲null,value能夠爲多個,而Hashtable裏面不能夠爲null。 3.就是數組的長度不同。HashMap默認是16,而Hashtable是11。

相關文章
相關標籤/搜索