什麼是線程死鎖?死鎖如何產生?如何避免線程死鎖?前端
死鎖的介紹:java
線程死鎖是指因爲兩個或者多個線程互相持有對方所須要的資源,致使這些線程處於等待狀態,沒法前往執行。當線程進入對象的synchronized代碼塊時,便佔有了資源,直到它退出該代碼塊或者調用wait方法,才釋放資源,在此期間,其餘線程將不能進入該代碼塊。當線程互相持有對方所須要的資源時,會互相等待對方釋放資源,若是線程都不主動釋放所佔有的資源,將產生死鎖。程序員
死鎖的產生的一些特定條件:redis
一、 互斥條件:進程對於所分配到的資源具備排它性,即一個資源只能被一個進程佔用,直到被該進程釋放 。算法
二、 請求和保持條件:一個進程因請求被佔用資源而發生阻塞時,對已得到的資源保持不放。spring
三、 不剝奪條件:任何一個資源在沒被該進程釋放以前,任何其餘進程都沒法對他剝奪佔用。數據庫
四、 循環等待條件:當發生死鎖時,所等待的進程一定會造成一個環路(相似於死循環),形成永久阻塞。編程
如何避免:設計模式
一、 加鎖順序:瀏覽器
當多個線程須要相同的一些鎖,可是按照不一樣的順序加鎖,死鎖就很容易發生。若是能確保全部的線程都是按照相同的順序得到鎖,那麼死鎖就不會發生。固然這種方式須要你事先知道全部可能會用到的鎖,然而總有些時候是沒法預知的。
二、 加鎖時限:
加上一個超時時間,若一個線程沒有在給定的時限內成功得到全部須要的鎖,則會進行回退並釋放全部已經得到的鎖,而後等待一段隨機的時間再重試。可是若是有很是多的線程同一時間去競爭同一批資源,就算有超時和回退機制,仍是可能會致使這些線程重複地嘗試但卻始終得不到鎖。
三、 死鎖檢測:
死鎖檢測即每當一個線程得到了鎖,會在線程和鎖相關的數據結構中(map、graph等等)將其記下。除此以外,每當有線程請求鎖,也須要記錄在這個數據結構中。死鎖檢測是一個更好的死鎖預防機制,它主要是針對那些不可能實現按序加鎖而且鎖超時也不可行的場景。
notify和notifyAll區別
他們的做用都是通知處於等待該對象的線程。
一、 notifyAll使全部原來在該對象上等待被notify的線程通通退出wait的狀態,變成等待該對象上的鎖,一旦該對象被解鎖,他們就會去競爭。
二、 notify是通知其中一個線程,不會通知全部的線程。
談一談對MySQL InnoDB的認識
介紹:
InnoDB引擎是MySQL數據庫的一個重要的存儲引擎,和其餘存儲引擎相比,InnoDB引擎的優勢是支持兼容ACID的事務(相似於PostgreSQL),以及參數完整性(有外鍵)等。如今Innobase實行雙認證受權.MySQL5.5.5之後默認的存儲引擎都是InnoDB引擎。
特色是:
一、 具備較好的事務支持:支持4個事務隔離級別,支持多版本讀
二、 行級鎖定:經過索引實現,全表掃描仍然會是表鎖,注意間隙鎖的影響
三、 讀寫阻塞與事務隔離級別相關
四、 具備很是高效的緩存特性:能緩存索引,也能緩存數據
五、 整個表和主鍵以Cluster方式存儲,組成一顆平衡樹
六、 全部Secondary Index都會保存主鍵信息
適用場景:
一、 須要事務支持(具備較好的事務特性)
二、 行級鎖定對高併發有很好的適應能力,但須要確保查詢是經過索引完成
三、 數據更新較爲頻繁的場景
四、 數據一致性要求較高
五、 硬件設備內存較大,能夠利用InnoDB較好的緩存能力來提升內存利用率,儘量減小磁盤IO
談一談數據庫事務的隔離級別?
一、 Read uncommitted(讀未提交)就是一個事務能夠讀取另外一個未提交事務的數據。
二、 Read committed(讀提交)就是一個事務要等另外一個事務提交後才能讀取數據。
三、 Repeatable read(重複讀)就是在開始讀取數據(事務開啓)時,再也不容許修改操做。
四、 Serializable(序列化)在該級別下,事務串行化順序執行,能夠避免髒讀、不可重複讀與幻讀。是最高的事務隔離級別,可是這種事務隔離級別效率低下,比較耗數據庫性能,通常不使用。
事務的做用就是保證數據的一致性、完整性。事務隔離級別越高,在併發下會產生的問題就越少,但同時付出的性能消耗也將越大,所以不少時候必須在併發性和性能之間作一個權衡。因此設立了幾種事務隔離級別,以便讓不一樣的項目能夠根據本身項目的併發狀況選擇合適的事務隔離級別,對於在事務隔離級別以外會產生的併發問題,在代碼中作補償。
MySQL主備同步的基本原理
MySQL支持單向、異步複製,複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。
MySQL複製是基於主服務器在二進制日誌中跟蹤全部對數據庫的更改。所以,要進行復制,必須在主服務器上啓用二進制日誌。每一個從服務器從主服務器接收主服務器已經記錄到日誌的數據。
當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,並在本機上執行相同的更新。而後封鎖並等待主服務器通知新的更新。從服務器執行備份不會干擾主服務器,在備份過程當中主服務器能夠繼續處理更新。
Java語言中一個顯著的特色就是引入了垃圾回收機制,這個你們都清楚,垃圾回收的概念這裏也不作介紹,重點是垃圾回收是在何時開始?對什麼東西,作了什麼事情?
GC什麼時候開始:
全部的回收器類型都是基於分代技術來實現的,那就必需要清楚對象按其生命週期是如何劃分的。
年輕代:劃分爲三個區域:原始區(Eden)和兩個小的存活區(Survivor),兩個存活區按功能分爲From和To。絕大多數的對象都在原始區分配,超過一個垃圾回收操做仍然存活的對象放到存活區。垃圾回收絕大部分發生在年輕代。
年老代: 存儲年輕代中通過多個回收週期仍然存活的對象,對於一些大的內存分配,也可能直接分配到永久代。
持久代: 存儲類、方法以及它們的描述信息,這裏基本不產生垃圾回收。
有了以上這些鋪墊以後開始回答GC什麼時候開始:
Eden內存滿了以後,開始Minor GC(從年輕代空間回收內存被稱爲 Minor GC);升到老年代的對象所需空間大於老年代剩餘空間時開始Full GC(但也可能小於剩餘空間時,被HandlePromotionFailure參數強制Full GC)
對什麼東西操做,即垃圾回收的對象是什麼:
從root開始搜索沒有可達對象,並且通過第一次標記、清理後,仍然沒有復活的對象。
作了什麼東西:
主要作了清理對象,整理內存的工做。具體的引伸以下
垃圾回收器的類型:
垃圾回收算法:
加載Loading:
經過一個類的全限定名來獲取一個二進制字節流、將這個字節流所表明的靜態存儲結構轉化爲方法區的運行時數據結構、在內存中生成一個表明這個類的java.lang.Class對象,做爲方法區這個類的各類數據的訪問入口。
驗證Verification:
準備Preparation:
解析Resolution:
初始化Initialization:
使用Using:
卸載Unloading:
說一下spring中Bean的做用域
singleton:
Spring IoC容器中只會存在一個共享的Bean實例,不管有多少個Bean引用它,始終指向同一對象。Singleton做用域是Spring中的缺省做用域。
prototype:
每次經過Spring容器獲取prototype定義的bean時,容器都將建立一個新的Bean實例,每一個Bean實例都有本身的屬性和狀態,而singleton全局只有一個對象。
request:
在一次Http請求中,容器會返回該Bean的同一實例。而對不一樣的Http請求則會產生新的Bean,並且該bean僅在當前Http Request內有效。
session:
在一次Http Session中,容器會返回該Bean的同一實例。而對不一樣的Session請求則會建立新的實例,該bean實例僅在當前Session內有效。
global Session:
在一個全局的Http Session中,容器會返回該Bean的同一個實例,僅在使用portlet context時有效。
說一下spring中Bean的生命週期
實例化一個Bean,也就是咱們一般說的new。
按照Spring上下文對實例化的Bean進行配置,也就是IOC注入。
若是這個Bean實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的是Spring配置文件中Bean的ID。
若是這個Bean實現了BeanFactoryAware接口,會調用它實現的setBeanFactory(),傳遞的是Spring工廠自己(能夠用這個方法獲取到其餘Bean)。
若是這個Bean實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文。
若是這個Bean關聯了BeanPostProcessor接口,將會調用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean內容的更改,而且因爲這個是在Bean初始化結束時調用After方法,也可用於內存或緩存技術。
若是這個Bean在Spring配置文件中配置了init-method屬性會自動調用其配置的初始化方法。
若是這個Bean關聯了BeanPostProcessor接口,將會調用postAfterInitialization(Object obj, String s)方法。
當Bean再也不須要時,會通過清理階段,若是Bean實現了DisposableBean接口,會調用其實現的destroy方法。
最後,若是這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷燬方法。
對Spring中依賴注入兩種方式的認識
兩種注入方式爲:構造方法注入和設值注入
設值注入與傳統的JavaBean的寫法更類似,程序員更容易理解、接受,經過setter方式設定依賴關係顯得更加直觀、明顯;
對於複雜的依賴關係,若是採用構造注入,會致使構造器過於臃腫,難以閱讀。Spring在建立Bean實例時,須要同時實例化其依賴的所有實例,於是會產生浪費。而使用設置注入,則避免這下問題;
在某些屬性可選的狀況下,多參數的構造器更加笨拙,官方更鼓勵使用設值注入。
構造注入能夠在構造器中決定依賴關係的注入順序,優先依賴的優先注入。
對於依賴關係無須變化的Bean,構造注入更有用處,由於沒有setter方法,全部的依賴關係所有在構造器內設定,所以,不用擔憂後續代碼對依賴關係的破壞。
構造注入使依賴關係只能在構造器中設定,則只有組件的建立者才能改變組件的依賴關係。對組件的調用者而言,組件內部的依賴關係徹底透明,更符合高內聚的原則。
設值注入不會重寫構造方法的值。若是咱們對同一個變量同時使用了構造方法注入又使用了設置方法注入的話,那麼構造方法將不能覆蓋由設值方法注入的值。
建議採用以設值注入爲主,構造注入爲輔的注入策略。對於依賴關係無須變化的注入,儘可能採用構造注入;而其餘的依賴關係的注入,則考慮採用set注入。
Spring框架中都用到了哪些設計模式?
代理模式: 在AOP和remoting中被用的比較多。
單例模式: 在spring配置文件中定義的bean默認爲單例模式。
模板方法模式: 用來解決代碼重複的問題。
前端控制器模式: Spring提供了DispatcherServlet來對請求進行分發。
依賴注入模式: 貫穿於BeanFactory / ApplicationContext接口的核心理念。
工廠模式: BeanFactory用來建立對象的實例。
BeanFactory 和ApplicationContext的區別
BeanFactory和ApplicationContext都是接口,而且ApplicationContext是BeanFactory的子接口。
BeanFactory是Spring中最底層的接口,提供了最簡單的容器的功能,只提供了實例化對象和拿對象的功能。而ApplicationContext是Spring的一個更高級的容器,提供了更多的有用的功能。
ApplicationContext提供的額外的功能:國際化的功能、消息發送、響應機制、統一加載資源的功能、強大的事件機制、對Web應用的支持等等。
加載方式的區別:BeanFactory採用的是延遲加載的形式來注入Bean;ApplicationContext則相反的,它是在Ioc啓動時就一次性建立全部的Bean,好處是能夠立刻發現Spring配置文件中的錯誤,壞處是形成浪費。
數據庫的三大範式
1 、第一範式(1NF)
在任何一個關係數據庫中,第一範式(1NF)是對關係模式的基本要求,不知足第一範式(1NF)的數據庫就不是關係數據庫。
所謂第一範式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重複的屬性。若是出現重複的屬性,就可能須要定義一個新的實體,新的實體由重複的屬性構成,新實體與原實體之間爲一對多關係。
在第一範式(1NF)中表的每一行只包含一個實例的信息。簡而言之,第一範式要求數據表中的每一列(每一個字段)必須是不可拆分的最小單元。
二、 第二範式(2NF)
第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必須先知足第一範式(1NF)。第二範式(2NF)要求數據庫表中的每一個實例或行必須能夠被唯一地區分。爲實現區分一般須要爲表加上一個列,以存儲各個實例的唯一標識。
第二範式(2NF)要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴主關鍵字一部分的屬性,若是存在,那麼這個屬性和主關鍵字的這一部分應該分離出來造成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分一般須要爲表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二範式要求表中的全部列,都必須依賴於主鍵,而不能有任何一列與主鍵沒有關係。
3 、第三範式(3NF)
知足第三範式(3NF)必須先知足第二範式(2NF)。第三範式(3NF)要求一個數據庫表中不包含其它表中已包含的非主關鍵字信息。簡而言之,第三範式要求表中的每一列只與主鍵直接相關而不是間接相關,表中的每一列只能依賴於主鍵。
TCP和UDP的區別及其適用場景
首先說一下什麼是TCP和UDP:
TCP是傳輸控制協議,提供的是面向鏈接、可靠的字節流服務。
UDP是用戶數據報協議,是一個簡單的面向數據報的運輸層協議。
TCP和UDP的區別:
TCP面向鏈接的運輸層協議,UDP無鏈接
TCP是可靠交付,UDP是盡最大努力交付
TCP面向字節流,UDP面向報文
TCP是點對點鏈接的,UDP一對一,一對多,多對多均可以
TCP適合用於網頁,郵件等,UDP適合用於視頻,語音廣播等
TCP和UDP的適用場景:
整個數據要準確無誤的傳遞給對方,這每每用於一些要求可靠的應用,好比HTTP、HTTPS、FTP等傳輸文件的協議,POP、SMTP等郵件傳輸的協議。
當對網絡通信質量要求不高的時候,要求網絡通信速度能儘可能的快,好比視頻、廣播等,這時就可使用UDP。
說一下Spring的核心模塊
Spring Core【核心容器】: 核心容器提供了Spring的基本功能。核心容器的核心功能是用IOC容器來管理類的依賴關係。
Spring AOP【面向切面】: Spring的AOP模塊提供了面向切面編程的支持。SpringAOP採用的是純Java實現,採用基於代理的AOP實現方案,AOP代理由IOC容器負責生成、管理,依賴關係也一併由IOC容器管理。
Spring ORM【對象實體映射】: 提供了與多個第三方持久層框架的良好整合。
**Spring DAO【持久層模塊】: ** Spring進一步簡化DAO開發步驟,能以一致的方式使用數據庫訪問技術,用統一的方式調用事務管理,避免具體的實現侵入業務邏輯層的代碼中。
Spring Context【應用上下文】: 它是一個配置文件,爲Spring提供上下文信息,提供了框架式的對象訪問方法。
Spring Web【Web模塊】: 提供了基礎的針對Web開發的集成特性。
Spring MVC【MVC模塊】: 提供了Web應用的MVC實現。Spring的MVC框架並非僅僅提供一種傳統的實現,它提供了一種清晰的分離模型。
(轉發)forward與(重定向)redirect的區別
forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,而後把這些內容再發給瀏覽器。瀏覽器根本不知道服務器發送的內容從哪裏來的,因此它的地址欄仍是原來的地址。
redirect是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,因此地址欄顯示的是新的URL。
forward轉發頁面和轉發到的頁面能夠共享request裏面的數據。
redirect不能共享數據。
redirect不只能夠重定向到當前應用程序的其餘資源,還能夠重定向到同一個站點上的其餘應用程序中的資源,甚至是使用絕對URL重定向到其餘站點的資源。
forward只能在同一個Web應用程序內的資源之間轉發請求。
forward是服務器內部的一種操做。
redirect是服務器通知客戶端,讓客戶端從新發起請求。
forward通常用於用戶登錄的時候根據角色轉發到相應的模塊。
redirect通常用於用戶註銷登錄時返回主頁面和跳轉到其它的網站等。
forward效率高。
redirect效率低。
redis經常使用的五種數據類型
1.String(字符串)
String是簡單的 key-value 鍵值對,value 不只能夠是 String,也能夠是數字。它是Redis最基本的數據類型,一個redis中字符串value最多能夠是512M。
2.Hash(哈希)
Redis hash 是一個鍵值對集合,對應Value內部實際就是一個HashMap,Hash特別適合用於存儲對象。
3.List(列表)
Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素導列表的頭部(左邊)或者尾部(右邊)。
底層實現爲一個雙向鏈表,便可以支持反向查找和遍歷,更方便操做,不過帶來了部分額外的內存開銷,Redis內部的不少實現,包括髮送緩衝隊列等也都是用的這個數據結構。
4.Set(集合)
Redis的Set是String類型的無序集合,它的內部實現是一個 value永遠爲null的HashMap,實際就是經過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的緣由。
5.zset(有序集合)
Redis zset 和 set 同樣也是String類型元素的集合,且不容許重複的成員,不一樣的是每一個元素都會關聯一個double類型的分數,用來排序
以上就是這篇文章的所有內容了,但願本文的內容對你們的學習或者工做具備必定的參考學習價值