Java相關的知識點

JAVA部分:html

  1. JVM內存劃分? www.cnblogs.com/ymerge/p/93… blog.csdn.net/suifeng629/… blog.itpub.net/69917606/vi… blog.csdn.net/u012485165/…
  2. 常見的GC回收算法及其含義? www.jianshu.com/p/3fc4450e1…
  3. java代碼塊,靜態代碼塊,內部類,靜態內部類的加載時機? blog.csdn.net/dreamsever/… 這個加載時機最好本身寫個demo運行一下,能更深入的理解和方便記憶
  4. Java 重載與重寫是什麼?有什麼區別? blog.csdn.net/qunqunstyle…
  5. Java併發編程:synchronized、Lock、ReentrantLock以及ReadWriteLock: www.cnblogs.com/yeya/p/1020…
  6. C++和java的區別和聯繫? www.cnblogs.com/tanrong/p/8…
  7. 什麼是HTTP的長鏈接和短鏈接? www.cnblogs.com/cswuyg/p/36…
  8. http請求方法有哪些:? blog.csdn.net/potato512/a…
  9. HTTP1.0、HTTP1.一、HTTP2和HTTPS的對比? www.jianshu.com/p/883fd0277…
  10. HashMap講解? mp.weixin.qq.com/s/AuGv8xLWy…
  11. Java中的淺複製和深複製? blog.csdn.net/weixin_3881…
  12. 什麼是CAS機制? blog.csdn.net/qq_32998153…
  13. Java類加載過程? www.cnblogs.com/luohanguo/p…
  14. NIO、BIO、AIO的原理及區別與應用場景? blog.csdn.net/qq_36907589…
  15. 紅黑樹原理及插入刪除操做: blog.csdn.net/weixin_3965…
  16. Java 中的 equals,==與 hashCode 的區別與聯繫? www.cnblogs.com/xiaofangcun…

Java相關的知識點

JDK1.8 新特性(stream、lambda 表達式、接口 default 方法)

Stream 是 Java8 中處理集合的關鍵抽象概念,它能夠指定你但願對集合進行的操做,能夠執行很是複雜的查找、過濾和映射數據等操做。使用Stream API 對集合數據進行操做,就相似於使用 SQL 執行的數據庫查詢。也可使用 Stream API 來並行執行操做。簡單來講,Stream API 提供了一種高效且易於使用的處理數據的方式。java

final關鍵字有什麼做用,能夠修飾什麼東西?
  1. ,該類不能被繼承。
  2. 變量,若是是基本類型,則值不可變。若是是引用類型,則變量的引用不能變。
  3. 方法,該方法不能被重寫。
  4. 參數,同修飾變量的做用同樣。 可是做用域在此方法內。
線程和進程的關係?

線程: 每一個進程中至少包含一個線程,而這些線程都在共享進程的資源空間等,當線程發生變化的時候只會引發CPU執行的過程發生變化,不會改變進程所擁有的資源。進程中執行運算的最小單位,亦是執行處理機調度的基本單位程序員

進程: 每一個進程都有本身的地址空間,資源如,內存,I/O,CPU,同一個進程裏的 線程共享本進程裏的地址空間,那能不能使用別人家進程的地址空間呢,顯然這是不能夠的。算法

Java進程間通訊?

1. 管道(PIPE) 管道是一種半雙工的通訊方式,數據只能單向流動,並且只能在具備親緣關係的進程間使用。進程的親緣關係一般是指父子進程關係。 2. 命名管道(FIFO) 名管道也是半雙工的通訊方式,可是它容許無親緣關係進程間的通訊。 3. 信號(Signal) 用於通知接收進程某個事件已經發生,主要做爲進程間以及同一進程不一樣線程之間的同步手段。 4. 信號量(Semaphore) 信號量是一個計數器,能夠用來控制多個進程對共享資源的訪問。它常做爲一種鎖機制,防止某進程正在訪問共享資源時,其餘進程也訪問該資源。 5. 消息隊列(MessageQueue) 消息隊列是消息的鏈表,存放在內核中。一個消息隊列由一個標識符(即隊列ID)來標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。 6. 共享內存(Shared Memory) 共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。 特色: 共享內存是最快的一種 IPC,由於進程是直接對內存進行存取。 由於多個進程能夠同時操做,因此須要進行同步。 信號量+共享內存一般結合在一塊兒使用,信號量用來同步對共享內存的訪問。 7. 套接字(Socket) 套接字也是一種進程間通訊機制,與其餘通訊機制不一樣的是,它可用於不一樣機器間的進程通訊sql

Java線程間通訊?

blog.csdn.net/wlddhj/arti…數據庫

1、傳統線程通訊synchronized + wait + notify編程

Object類的wait()、notify() 、notifyAll()三個方法必須由同步監視器對象來調用,分兩種狀況:設計模式

a)同步方法,該類默認實例(this)就是同步監視器,能夠在同步方法中能夠直接調用數組

b)同步代碼塊,同步監視器是synchronized後括號裏的對象,因此必須使用此對象調用這三個方法緩存

2、使用Condition控制線程通訊lock + condition + await + signal

Lock代替同步方法或同步代碼塊,Condition替代同步監視器的功能。

private final Lock lock = newReentrantLock();

private final Condition con =lock.newCondition();

lock.lock(); con.await(); con.signalAll(); lock.unlock():

3、使用阻塞隊列(BlockingQueue)控制線程通訊

BlockingQueue接口主要做爲線程同步的工具。當生產者試圖向BlockingQueue中放入元素,若是隊列已滿,則線程被阻塞;當消費者試圖向BlockingQueue中取出元素時,若該隊列已空,則線程被阻塞。

數組和鏈表的區別和聯繫,他們是線程安全的嗎?

答:

鏈表與數組的主要區別:

(1)數組的元素個數是固定的,而組成鏈表的結點個數可按須要增減;

(2)數組元素的存儲單元在數組定義時分配,鏈表結點的存儲單元在程序執行時動態向系統申請:

(3)數組中的元素順序關係由元素在數組中的位置(即下標)肯定,鏈表中的結點順序關係由結點所包含的指針來體現。

(4)對於不是固定長度的列表,用可能最大長度的數組來描述,會浪費許多內存空間。

(5)對於元素的插人、刪除操做很是頻繁的列表處理場合,用數組表示列表也是不適宜的。若用鏈表實現,會使程序結構清晰,處理的方法也較爲簡便。

鏈表與數組的聯繫:

ArrayList數組和LinkedList鏈表都是不一樣步的,也就是不保證線程安全。

數組和鏈表的區別

從邏輯結構來看

數組必須事先定義固定的長度(元素個數),不能適應數據動態地增減的狀況。當數據增長時,可能超出原先定義的元素個數;當數據減小時,形成內存浪費;數組能夠根據下標直接存取。

鏈表動態地進行存儲分配,能夠適應數據動態地增減的狀況,且能夠方便地插入、刪除數據項。(數組中插入、刪除數據項時,須要移動其它數據項,很是繁瑣)鏈表必須根據next指針找到下一個元素

從內存存儲來看

(靜態)數組從棧中分配空間, 對於程序員方便快速,可是自由度小

鏈表從堆中分配空間, 自由度大可是申請管理比較麻煩

從上面的比較能夠看出,若是須要快速訪問數據,不多或不插入和刪除元素,就應該用數組;相反, 若是須要常常插入和刪除元素就須要用鏈表數據結構了。

怎麼保證線程安全?

答:

1、線程安全在三個方面體現

1.原子性:提供互斥訪問,同一時刻只能有一個線程對數據進行操做,(atomic,synchronized);

2.可見性:一個線程對主內存的修改能夠及時地被其餘線程看到,(synchronized,volatile);

3.有序性:一個線程觀察其餘線程中的指令執行順序,因爲指令重排序,該觀察結果通常雜亂無序,(happens-before原則)。 解決方法:

對非安全的代碼進行加鎖控制;

使用線程安全的類;

多線程併發狀況下,線程共享的變量改成方法級的局部變量。

線程同步

一、同步方法

synchronized關鍵字修飾方法。因爲java的每一個對象都有一個內置鎖,當用此關鍵字修飾方法時,內置鎖會保護整個方法。在調用該方法前,須要得到內置鎖,不然就處於阻塞狀態。

二、同步代碼塊

synchronized關鍵字修飾的語句塊。被該關鍵字修飾的語句塊會自動加上內置鎖,從而實現同步

三、使用特殊域變量(volatile)實現線程同步

a.volatile關鍵字爲域變量的訪問提供一種免鎖機制

b.使用volatile修飾域至關於告訴虛擬機該域可能被其餘現象更新

c.所以每次使用該域就要從新計算,而不是使用寄存器中的值

d.volatile不會提供任何原子操做,它也不能用來修飾final類型的變量

4:使用重入鎖實現線程同步

在javaSE5.0新增了一個java.concurrent包來支持同步。ReentrantLock類能夠重入、互斥、實現了Lock接口的鎖,它與使用synchronized方法和快具體相同的基本行爲和語義,而且擴展了其能力

5.使用局部變量實現線程同步

若是使用ThreadLocal管理變量,則每個使用變量的線程都得到該變量的副本,副本之間相互獨立,這樣每個線程均可以隨意修改本身的變量副本,而不會對其餘線程產生影響。

在併發狀況中,如何控制建立線程的狀況?

1.自定義線程池

線程狀態的切換
  1. 初始(NEW):新建立了一個線程對象,但尚未調用start()方法。
  2. 運行(RUNNABLE):Java線程中將就緒(ready)和運行中(running)兩種狀態籠統的稱爲「運行」。 線程對象建立後,其餘線程(好比main線程)調用了該對象的start()方法。該狀態的線程位於可運行線程池中,等待被線程調度選中,獲取CPU的使用權,此時處於就緒狀態(ready)。就緒狀態的線程在得到CPU時間片後變爲運行中狀態(running)。
  3. 阻塞(BLOCKED):表示線程阻塞於鎖。
  4. 等待(WAITING):進入該狀態的線程須要等待其餘線程作出一些特定動做(通知或中斷)。
  5. 超時等待(TIMED_WAITING):該狀態不一樣於WAITING,它能夠在指定的時間後自行返回。
  6. 終止(TERMINATED):表示該線程已經執行完畢。
怎麼實現多線程(線程有哪些狀態,哪些鎖,各類鎖的區別)
  1. 繼承Thread類

  2. 實現Runnable接口

  3. 實現Callable接口

  4. 線程池:提供了一個線程隊列,隊列中保存着全部等待狀態的線程。避免了建立與銷燬額外開銷,提升了響應的速度。

建立線程的方式,他們有什麼區別?

1.繼承Thread類實現多線程

2.覆寫Runnable()接口實現多線程,然後一樣覆寫run().推薦此方式

3.覆寫Callable接口實現多線程(JDK1.5)

4.經過線程池啓動多線程

線程池通常用在什麼狀況下?

1.單個任務處理的時間比較短 2.將需處理的任務的數量大

知道線程池嗎?說說對線程池的理解?

線程池作的工做主要是控制運行的線程的數量,處理過程當中將任務放入隊列,而後在線程建立後啓動這些任務,若是線程數量超過了最大數量超出數量的線程排隊等待,等其它線程執行完畢,再從隊列中取出任務來執行。

線程池由任務隊列和工做線程組成,它能夠重用線程來避免線程建立的開銷,在任務過多時經過排隊避免建立過多線程來減小系統資源消耗和競爭,確保任務有序完成

ThreadPoolExecutor 繼承自 AbstractExecutorService 實現了 ExecutorService 接口,ScheduledThreadPoolExecutor 繼承自 ThreadPoolExecutor 實現了 ExecutorService 和 ScheduledExecutorService 接口

Synchronized 關鍵字原理

實現原理: JVM 是經過進入、退出 對象監視器(Monitor) 來實現對方法、同步塊的同步的,而對象監視器的本質依賴於底層操做系統的 互斥鎖(Mutex Lock) 實現。

具體實現是在編譯以後在同步方法調用前加入一個monitor.enter指令,在退出方法和異常處插入monitor.exit的指令。

對於沒有獲取到鎖的線程將會阻塞到方法入口處,直到獲取鎖的線程monitor.exit以後才能嘗試繼續獲取鎖。

blog.csdn.net/weixin_3675…

談談你對鎖的瞭解

1.目的: 爲何要上鎖,主要仍是多線程的緣由。多線程可能對同一塊數據同時操做,數據可能會異常,好比,一個map,A線程把對鍵值對刪除,B線程讀取鍵值對,而後段錯誤就產生了。

併發編程:synchronized 和 volatile 、ReentrantLock 、CAS 的區別

被synchronized修飾的代碼段能夠防止被多個線程同時執行,必須一個線程把synchronized修飾的代碼段都執行完畢了,其餘的線程才能開始執行這段代碼。

volatile關鍵字的做用就是保證了可見性和有序性(不保證原子性),若是一個共享變量被volatile關鍵字修飾,那麼若是一個線程修改了這個共享變量後,其餘線程是立馬可知的。

synchronized 多用於在多個線程中須要對同一段數據進行訪問時候,出現的不安全狀況。由於多個線程執行同一段代碼會形成數據不安全,因此須要用synchronized來同步代碼。

ReenTrantLock可重入鎖和synchronized同步鎖的區別總結

一、可重入性:

從名字上理解, ReenTrantLock的字面意思就是再進入的鎖,其實synchronized關鍵字所使用的鎖也是可重入的,二者關於這個的區別不大。二者都是同一個線程每進入一次,鎖的計數器都自增1,因此要等到鎖的計數器降低爲0時才能釋放鎖。

二、鎖的實現:

Synchronized是依賴於JVM實現的,而ReenTrantLock是JDK實現的,有什麼區別,說白了就相似於操做系統來控制實現和用戶本身敲代碼實現的區別。前者的實現是比較難見到的,後者有直接的源碼可供閱讀。

三、性能的區別:

在Synchronized優化之前,synchronized的性能是比ReenTrantLock差不少的,可是自從Synchronized引入了偏向鎖,輕量級鎖(自旋鎖)後,二者的性能就差很少了,在兩種方法均可用的狀況下,官方甚至建議使用synchronized,其實synchronized的優化我感受就借鑑了ReenTrantLock中的CAS技術。都是試圖在用戶態就把加鎖問題解決,避免進入內核態的線程阻塞。

四、功能區別:

便利性:很明顯Synchronized的使用比較方便簡潔,而且由編譯器去保證鎖的加鎖和釋放,而ReenTrantLock須要手工聲明來加鎖和釋放鎖,爲了不忘記手工釋放鎖形成死鎖,因此最好在finally中聲明釋放鎖。

五、鎖的細粒度和靈活度:

很明顯ReenTrantLock優於Synchronized

synchronized 修飾實例方法和修飾靜態方法有啥不同。

答:

  1. Synchronized修飾非靜態(實例)方法,其實是對調用該方法的對象加鎖,俗稱「對象鎖」。

兩個線程會依次執行,說明產生互斥,由於實例方法加鎖針對的是實例對象,當前對象調用一個synchronized方法時,其餘同步方法須要等待其執行結束並釋放鎖以後才能執行。

  1. Synchronized修飾靜態方法,其實是對該類對象加鎖,俗稱「類鎖」
  • **用類直接在兩個線程中調用兩個不一樣的同步靜態方法:結果:**產生互斥,由於對靜態方法加鎖,其實是對類加鎖,類只有一個。所以當一個同步靜態方法被訪問時,該類已處於被鎖狀態。此時其餘同步靜態方法不能被訪問(未用synchronized修飾的靜態方法仍能夠訪問)
  • **兩個線程分別調用同步類方法和同步實例方法:結果:**不會互斥,鎖對象不一樣,一個是對實例對象加鎖,一個對類加鎖,由於靜態方法不屬於某個實例,而屬於類自己。
解釋一下死鎖

兩個/多個線程佔有鎖的前提又去得到其餘鎖,這樣形成的線程無限的循環等待,產生了死鎖!

sleep 、wait、yield 的區別,wait 的線程如何喚醒它

答:

  • sleep()方法須要指定等待的時間,它可讓當前正在執行的線程在指定的時間內暫停執行,進入阻塞狀態,該方法既可讓其餘同優先級或者高優先級的線程獲得執行的機會,也可讓低優先級的線程獲得執行機會。可是sleep()方法不會釋放「鎖標誌」,也就是說若是有synchronized同步塊,其餘線程仍然不能訪問共享數據。
  • wait()方法與sleep()方法的不一樣之處在於,wait()方法會釋放對象的「鎖標誌」。當調用某一對象的wait()方法後,會使當前線程暫停執行,並將當前線程放入對象等待池中,直到調用了notify()方法後,將從對象等待池中移出任意一個線程並放入鎖標誌等待池中,只有鎖標誌等待池中的線程能夠獲取鎖標誌,它們隨時準備爭奪鎖的擁有權。當調用了某個對象的notifyAll()方法,會將對象等待池中的全部線程都移動到該對象的鎖標誌等待池。
  • yield()方法和sleep()方法相似,也不會釋放「鎖標誌」,區別在於,它沒有參數,即yield()方法只是使當前線程從新回到可執行狀態,因此執行yield()的線程有可能在進入到可執行狀態後立刻又被執行,另外yield()方法只能使同優先級或者高優先級的線程獲得執行機會,這也和sleep()方法不一樣。
  • notify()方法就能喚醒wait的線程
瞭解過 Java 的集合嗎?

答:

Java 集合類型分爲 Collection 和 Map,它們是 Java 集合的根接口,這兩個接口又包含了一些子接口或實現類。

Collection

Map

說說 HashMap 的底層實現原理?

答:

**1.**從結構實現來說,HashMap是數組+鏈表+紅黑樹(鏈表長度大於8時轉換成紅黑樹,小於6時變爲單項鍊表)(JDK1.8增長了紅黑樹部分)實現的

2. map.put(k,v)實現原理:

第一步:首先將k,v封裝到Node對象當中(節點)。

第二步:它的底層會調用K的hashCode()方法得出hash值。

**第三步:**經過哈希表函數/哈希算法,將hash值轉換成數組的下標,下標位置上若是沒有任何元素,就把Node添加到這個位置上。若是說下標對應的位置上有鏈表。此時,就會拿着k和鏈表上每一個節點的k進行equal。若是全部的equals方法返回都是false,那麼這個新的節點將被添加到鏈表的末尾。如其中有一個equals返回了true,那麼這個節點的value將會被覆蓋。

3. map.get(k)實現原理:

**第一步:**先調用k的hashCode()方法得出哈希值,並經過哈希算法轉換成數組的下標。

**第二步:**經過上一步哈希算法轉換成數組的下標以後,在經過數組下標快速定位到某個位置上。重點理解若是這個位置上什麼都沒有,則返回null。若是這個位置上有單向鏈表,那麼它就會拿着參數K和單向鏈表上的每個節點的K進行equals,若是全部equals方法都返回false,則get方法返回null。若是其中一個節點的K和參數K進行equals返回true,那麼此時該節點的value就是咱們要找的value了,get方法最終返回這個要找的value。

爲何放在hashMap集合key部分的元素須要重寫equals方法?

由於equals默認比較是兩個對象內存地址

HashMap擴容機制

HashMap默認的「加載因子」是0.75,默認的容量大小是16;增長容量時,每次將容量變爲「原始容量x2」。

介紹下 HashTable

Hashtable 也是一個散列表,它存儲的內容是鍵值對(key-value)映射。Hashtable 的函數都是同步的,這意味着它是線程安全的。它的key、value都不能夠爲null。此外,Hashtable中的映射不是有序的。

HashMap與Hashtable的不一樣點

1 繼承和實現方式不一樣

HashMap 繼承於AbstractMap,實現了Map、Cloneable、java.io.Serializable接口。 Hashtable 繼承於Dictionary,實現了Map、Cloneable、java.io.Serializable接口。

2 線程安全不一樣

Hashtable的幾乎全部函數都是同步的,即它是線程安全的,支持多線程。 而HashMap的函數則是非同步的,它不是線程安全的。

3 對null值的處理不一樣

HashMap的key、value均可覺得null。 Hashtable的key、value都不能夠爲null。

4 遍歷方式不一樣

HashMap只支持Iterator(迭代器)遍歷。此種迭代方式,HashMap是「從前向後」的遍歷數組;Hashtabl是「從後往前」的遍歷數組;而Hashtable支持Iterator(迭代器)和Enumeration(枚舉器)兩種方式遍歷。

5 添加元素時的hash值算法不一樣

HashMap添加元素時,是使用自定義的哈希算法。

Hashtable沒有自定義哈希算法,而直接採用的key的hashCode()。

6 容量的初始值和增長方式不同

HashMap默認的「加載因子」是0.75,默認的容量大小是16;增長容量時,每次將容量變爲「原始容量x2」。 Hashtable默認的「加載因子」是0.75,默認的容量大小是11;增長容量時,每次將容量變爲「原始容量x2 + 1」。

HashMap 和 ConcurrentHashMap 的區別

HashMap不是線程安全的;而ConcurrentHashMap 是線程安全的,可是效率有點慢

hashmap是線程安全的嗎?怎麼解決?怎麼保證多線程安全?

不是線程安全的;

一、繼承HashMap,重寫或者按要求編寫本身的方法,這些方法要寫成synchronized,在這些synchronized的方法中調用HashMap的方法 二、使用Collections.synchronizedMap() 三、使用ConcurrentHashMap替代,並不推薦新代碼使用Hashtable,HashTable繼承於Dictionary,任意時間只有一個線程能寫Hashtable,併發性能不如ConcurrentHashMap,由於ConcurrentHashMap引入了分段鎖。不須要線程安全的場景使用HashMap,須要線程安全的場合使用ConcurrentHashMap替換。

ArrayList 和 LinkedList 的區別?

大體區別:

1.ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。 (LinkedList是雙向鏈表,有next也有previous)

2.對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針。

3.對於新增和刪除操做add和remove,LinedList比較佔優點,由於ArrayList要移動數據。

Java 集合中哪些是線程安全的?

Vector:就比Arraylist多了個同步化機制(線程安全)。

Hashtable:就比Hashmap多了個線程安全。

ConcurrentHashMap:是一種高效可是線程安全的集合。

Stack:棧,也是線程安全的,繼承於Vector。

Vector(白客特)、HashTable、Properties是線程安全的;

ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等都是線程不安全的。

ArrayList對應的線程安全的類是什麼?

Vector(白客特)

Java的四大引用(強引用、軟引用、弱引用、虛引用的區別以及使用場景。)
  • 強引用:垃圾回收器打死都不會回收掉一個強引用的,那怕是出現OOM也不會回收掉強引用,全部new出來的都是強引用。
  • 軟引用:垃圾回收器會在內存不足的狀況下回收掉軟引用,若是內存充足的話不會理它
  • 弱引用:它跟軟引用相似,可是它更脆弱,只要垃圾回收器一發現它,就會馬上回收掉它。好比一個對象持有一個強引用和弱引用,當強引用被取消時,那麼只要GC發現了它,就會馬上回收掉。只是GC發現它的這個過程是不肯定的,有可能不會立刻發生,因此它可能還會多活一會,中間存在一個優先級。
  • 虛引用:它跟上面3種方式都不一樣。我對虛引用的理解就是若是一個對象持有虛引用,那麼就能夠在被GC回收前進行一些設定好的工做等等。由於虛引用有個機制,由於虛引用必須和引用隊列聯合使用,當垃圾回收器準備回收一個對象時,若是發現它還有虛引用,就回在回收對象的內存前,把這個虛引用加入到與之關聯的引用隊列中。而程序若是判斷到引用隊列中已經加入了虛引用,那麼就能夠了解到被引用的對象立刻就要被垃圾回收了,這個時候就能夠作些被回收以前的事情啦。
JVM 的內存模型?

根據JVM規範,JVM 內存共分爲五類:虛擬機棧,堆,方法區,程序計數器,本地方法棧五個部分。

java中的內存區域?

內存區域是指 Jvm 運行時將數據分區域存儲。

類加載機制

整個生命週期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Useing)、卸載(Unloading)7個階段。其中驗證、準備和解析3個部分統稱爲鏈接(Linking),

  1. 加載:經過ClassLoader加載class文件字節碼,生成Class對象。
  2. 校驗:校驗加載字節碼的安全性和正確性。
  3. 準備:爲類變量分配內存並設置類變量初始的零值。
  4. 解析:將常量池內的符號引用替換爲直接引用。
  5. 初始化:將類進行初始化,執行類構造器(類變量賦值和靜態語句塊)。 5. 初始化:將類進行初始化,執行類構造器(靜態語句塊),可能執行類的構造函數(若是new對象的話先執行類構造器,再執行類的構造函數)。「new對象會執行類構造器」此時仍是類加載過程,「再執行類的構造函數」此時好像已經脫離類加載過程,到了對象的建立過程了。這個地方概念仍是有點模糊,待我把對象的建立過程複習一下,再來總結!!!
  6. 使用:使用這個類進行相關操做。
  7. 卸載:不用了,被JVM垃圾回收了。

加載

「加載」是「類加載」過程的一個階段,由類加載器來完成,主要作如下3件事:

  1. 經過一個類的全限定名來獲取此類的二進制字節流。
  2. 將這個二進制字節流所表明的靜態存儲結構轉化爲方法區的運行時數據接口。
  3. 在內存中生成一個表明這個類的java.lang.Class對象,做爲方法區這個類的各類數據的訪問入口。

驗證

驗證是鏈接階段的第一步,這一階段的目的是爲了確保Class文件的二進制字節流中包含的信息符合當前虛擬機的要求,而且不會危害虛擬機自身的安全。

主要進行以下4個驗證:

  1. 文件格式驗證 驗證字節流是否符合Class文件格式的規範,而且能被當前版本的虛擬機處理。
  2. 元數據驗證 對字節碼描述的信息進行語義分析,以確保其描述的信息符合Java語言規範的要求。
  3. 字節碼驗證 經過數據流和控制流分析肯定成行語義是合法的、符合邏輯的。
  4. 符號引用驗證 對類自身之外的信息(常量池中的各類符號引用)進行匹配性校驗。

準備

準備階段是正式爲類變量分配內存並設置類變量初始值的階段, 這些變量所使用的內存都將在方法區中進行分配。

解析

解析階段是虛擬機將常量池內的符號引用替換爲直接引用的過程

初始化

類初始化階段是類加載過程的最後一步,在這一階段纔開始執行類中定義的Java代碼(字節碼)。初始化階段是執行類構造器 ()方法(類構造器就是「類變量的賦值動做+靜態語句塊」)的過程。

簡單的說下 Java 的垃圾回收?

www.cnblogs.com/aspirant/p/…

JVM 內存共分爲五類:虛擬機棧,堆,方法區,程序計數器,本地方法棧五個部分。其中程序計數器、虛擬機棧、本地方法棧3個區域隨線程而生、隨線程而滅,所以這幾個區域的內存分配和回收都具有肯定性,就不須要過多考慮回收的問題,由於方法結束或者線程結束時,內存天然就跟隨着回收了。而Java堆區和方法區則不同、不同!(怎麼不同說的朗朗上口),這部份內存的分配和回收是動態的,正是垃圾收集器所需關注的部分。

java的垃圾標記算法

Java中標記垃圾的算法主要有兩種, 引用計數法和可達性分析算法。

引用計數法:

引用計數法就是給對象中添加一個引用計數器,每當有一個地方引用它,計數器就加 1;當引用失效,計數器就減 1;任什麼時候候計數器爲 0 的對象就是不可能再被使用的,能夠當作垃圾收集。

可達性分析算法:

這個算法的基本思想就是經過一系列的稱爲 「GC Roots」 的對象做爲起點,從這些節點開始向下搜索,節點所走過的路徑稱爲引用鏈,當一個對象到 GC Roots 沒有任何引用鏈相連的話,則證實此對象是不可用的。

java中垃圾回收算法

Java中存在着四種垃圾回收算法,標記清除算法、複製算法、標記整理算法以及分代回收算法。

1.標記清除算法

該算法分爲「標記」和「清除」兩個階段:標記階段的任務是標記出全部須要被回收的對象,清除階段就是回收被標記的對象所佔用的空間。它是最基礎的收集算法

2.複製算法

爲了解決效率問題,咱們開發出了複製算法。它能夠將內存分爲大小相同的兩塊,每次使用其中的一塊。當第一塊的內存使用完後,就將還存活的對象複製到另外一塊去,而後再把使用的空間一次清理掉。這樣就使每次的內存回收都是對內存區間的一半進行回收。

簡單來講就是該對象分爲對象面以及空閒面,對象在對象面上建立,對象面上存活的對象會被複制到空閒面,接下來就能夠清除對象面的內存。

3.標記整理算法

爲了解決複製算法的缺陷,充分利用內存空間,提出了標記整理算法。該算法標記階段和標記清除同樣,可是在完成標記以後,它不是直接清理可回收對象,而是將存活對象都向一端移動,而後清理掉端邊界之外的內存。

4.分代收集算法

當前虛擬機的垃圾收集都採用分代收集算法,這種算法就是根據具體的狀況選擇具體的垃圾回收算法。通常將 java 堆分爲新生代和老年代,這樣咱們就能夠根據各個年代的特色選擇合適的垃圾收集算法。

StringBuffer 是如何實現線程安全的?

**答:**由於 StringBuffer 的全部公開方法都是 synchronized 修飾的

String ,stringBuilder和stringBuffer區別

**答:區別1:**StringBuffer:線程安全,StringBuilder:線程不安全。由於 StringBuffer 的全部公開方法都是 synchronized 修飾的,而 StringBuilder 並無 synchronized修飾。

**區別2:**緩衝區 StringBuffer 每次獲取 toString 都會直接使用緩存區的 toStringCache 值來構造一個字符串。而 StringBuilder 則每次都須要複製一次字符數組,再構造一個字符串。因此,緩存衝這也是對 StringBuffer 的一個優化吧,不過 StringBuffer 的這個toString 方法仍然是同步的。

**區別3:**既然 StringBuffer 是線程安全的,它的全部公開方法都是同步的,StringBuilder 是沒有對方法加鎖同步的,因此毫無疑問,StringBuilder 的性能要遠大於 StringBuffer。

介紹一下你對反射的理解,它的應用場景是什麼:?

所謂的反射機制就是java語言在運行時擁有一項自觀的能力。經過這種能力能夠完全的瞭解自身的狀況爲下一步的動做作準備。

Java的反射機制的實現要藉助於4個類:class,Constructor,Field,Method。

Java反射的做用:在Java運行時環境中,對於任意一個類,能夠知道這個類有哪些屬性和方法。對於任意一個對象,能夠調用它的任意一個方法。這種動態獲取類的信息以及動態調用對象的方法的功能來自於Java 語言的反射(Reflection)機制。

什麼是序列化

序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。

抽象類和接口的區別是什麼?

一、抽象類能夠提供某些方法的部分實現,而接口不能夠;

二、抽象類是單個繼承機制,其子類不必定要實現父類中的全部沒實現的方法,而接口一個類能夠有多個接口,而且方法都要實現。

數據結構中經常使用排序算法?

冒泡排序、快速排序

如何實現對象的排序?
關於 Java 中深拷貝和淺拷貝的區別?

最根本的區別在因而否真正獲取一個對象的複製實體,而不是引用

深拷貝(deepCopy)是增長了一個指針而且申請了一個新的內存,使這個增長的指針指向這個新的內存,

瞭解註解嗎?

能夠對程序做出解釋,方便被其餘程序(編輯器)讀取

你日常是怎麼進行加密的?

MD5

MD5 加密是可逆的嗎?

不可逆的

static 方法能夠被覆蓋嗎?爲何?

不能夠,覆蓋(override)是在繼承+多態的前提下的概念。Java中的靜態方法很少態,因此不涉及覆蓋,不管靜態方法是在基類仍是派生類上。

Java 中關於 equals 和 hashcode 的理解?
面向對象的三大特性,如何理解其中的多態?

封裝的概念

  封裝性是面向對象編程的核心思想

  指的就是將描述某種實體的數據和基於這些數的操做集合到一塊兒,造成一個封裝體

  封裝的思想保證了類內部數據結構的完整性,使用戶沒法輕易直接操做類的內部數據,這樣下降了對內部數據的影響,提升了程序的安全性和可維護性。

繼承的概念

  繼承是Java面向對象編程技術的一塊基石,由於它容許建立分等級層次的類。

  繼承就是子類繼承父類的特徵和行爲,使得子類對象(實例)具備父類的實例域和方法,或類從父 類繼承方法,使得子類具備父類相同的行爲。

多態的概念

多態指的就是在應用程序中出現的「 重名 」 現象。多態性容許以統一的風格編寫程序,以處理種類繁多的已存在的類及其相關類。這樣既下降了維護難度,又節省了時間

你知道哪些設計模式?爲何要這樣用?能解決什麼問題?

建立者模式又叫建造者模式,是將一個複雜的對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。建立者模式隱藏了複雜對象的建立過程,它把複雜對象的建立過程加以抽象,經過子類繼承或者重載的方式,動態的建立具備複合屬性的對象。

  • 在用戶不知道對象的建造過程和細節的狀況下就能夠直接建立複雜的對象。

  • 方便用戶建立複雜的對象(不須要知道實現過程)

  • 代碼複用性 & 封裝性(將對象構建過程和細節進行封裝 & 複用)

Mysql索引

1.普通索引index :加速查找 2.惟一索引 主鍵索引:primary key :加速查找+約束(不爲空且惟一) 惟一索引:unique:加速查找+約束 (惟一) 3.聯合索引 -primary key(id,name):聯合主鍵索引 -unique(id,name):聯合惟一索引 -index(id,name):聯合普通索引 4.全文索引fulltext :用於搜索很長一篇文章的時候,效果最好。 5.空間索引spatial :瞭解就好,幾乎不用

zhuanlan.zhihu.com/p/29118331

在什麼狀況下不適合加索引

(頻繁改動和刪除的數據、數據量小、區分度小的字段(好比性別))

索引失效的狀況

(不知足最左前綴原則、where 後面不能用函數)

相關文章
相關標籤/搜索