11四、java中實現多態的機制是什麼
答:重寫,重載。方法的重寫Overriding和重載Overloading是Java多態性的不一樣表現。
重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。若是在子類中定義某方法與其父類有相同的名稱和參數,咱們說該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被」屏蔽」了。
若是在一個類中定義了多個同名的方法,它們或有不一樣的參數個數或有不一樣的參數類型,則稱爲方法的重載(Overloading)。Overloaded的方法是能夠改變返回值的類型。css
11五、靜態的多態和動態的多態的區別
答:靜態的多態: 即爲重載 ;方法名相同,參數個數或類型不相同。(overloading)。動態的多態: 即爲重寫;子類覆蓋父類的方法,將子類的實例傳與父類的引用調用的是子類的方法 實現接口的實例傳與接口的引用調用的實現類的方法。html
11六、extends和implement的不一樣
答:extends是繼承父類,只要那個類不是聲明爲final或者那個類定義爲abstract的就能繼承,JAVA中不支持多重繼承,可是能夠用接口來實現,這樣就要用到implements,繼承只能繼承一個類,但implements能夠實現多個接口,用逗號分開就好了,好比 class A extends B implements C,D,E。前端
11七、適配器模式與橋樑模式的區別
答:適配器模式把一個類的接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒工做的兩個類可以在一塊兒工做。又稱爲轉換器模式、變壓器模式、包裝模式(把已有的一些類包裝起來,使之能有知足須要的接口)。適配器模式的用意是將接口不一樣而功能相同或者相近的兩個接口加以轉換,包括適配器角色補充一些源角色沒有但目標接口須要的方法。就像生活中電器插頭是三相的,而電源插座是兩相的,這時須要一個三相變兩相的轉換器來知足。
好比,在Java I/O庫中使用了適配器模式,象FileInputStream是一個適配器類,其繼承了InputStrem類型,同時持有一個對FileDiscriptor的引用。這是將一個FileDiscriptor對象適配成InputStrem類型的對象形式的適配器模式。StringReader是一個適配器類,其繼承了Reader類型,持有一個對String對象的引用。它將String的接口適配成Reader類型的接口。等等。
橋樑模式的用意是要把實現和它的接口分開,以便它們能夠獨立地變化。橋樑模式並非用來把一個已有的對象接到不相匹配的接口上的。當一個客戶端只知道一個特定的接口,可是又必須與具備不一樣接口的類打交道時,就應該使用橋樑模式。
好比,JDBC驅動器就是一個橋樑模式的應用,使用驅動程序的應用系統就是抽象化角色,而驅動器自己扮演實現化角色。應用系統和JDBC驅動器是相對獨立的。應用系統動態地選擇一個合適的驅動器,而後經過驅動器向數據庫引擎發出指令就能夠訪問數據庫中的數據。java
11八、抽象類可否被實例化 ?抽象類的做用是什麼?
答:抽象類不能被實例化;抽象類一般不是由程序員定義的,而是由項目經理或模塊設計人設計抽象類的緣由一般是爲了規範方法名 抽象類必需要繼承,否則無法用,做爲模塊設計者,能夠把讓底層程序員直接用得方法直接調用,而一些須要讓程序員覆蓋後本身作得方法則定義稱抽象方法。mysql
120、String,StringBuffer, StringBuilder 的區別是什麼?String爲何是不可變的?
答:
一、String是字符串常量,StringBuffer和StringBuilder都是字符串變量。後二者的字符內容可變,而前者建立後內容不可變。
二、String不可變是由於在JDK中String類被聲明爲一個final類。
三、StringBuffer是線程安全的,而StringBuilder是非線程安全的。
ps:線程安全會帶來額外的系統開銷,因此StringBuilder的效率比StringBuffer高。若是對系統中的線程是否安全很掌握,可用StringBuffer,在線程不安全處加上關鍵字Synchronize。linux
12一、Vector,ArrayList, LinkedList的區別是什麼?
答:
一、Vector、ArrayList都是以相似數組的形式存儲在內存中,LinkedList則以鏈表的形式進行存儲。
二、List中的元素有序、容許有重複的元素,Set中的元素無序、不容許有重複元素。(TreeSet 是二差樹實現的,Treeset中的數據是自動排好序的,不容許放入null值,HashSet 是哈希表實現的,HashSet中的數據是無序的,能夠放入null,但只能放入一個null,二者中的值都不能重複)
三、Vector線程同步,ArrayList、LinkedList線程不一樣步。
四、LinkedList適合指定位置插入、刪除操做,不適合查找;ArrayList、Vector適合查找,不適合指定位置的插入、刪除操做。
五、ArrayList在元素填滿容器時會自動擴充容器大小的0.5n+1,而Vector則是2n,所以ArrayList更節省空間。程序員
12二、HashTable, HashMap,TreeMap區別?
答:
一、HashTable線程同步,HashMap非線程同步。
二、HashTable不容許<鍵,值>有空值,HashMap容許<鍵,值>有空值。
三、HashTable使用Enumeration,HashMap使用Iterator。
四、HashTable中hash數組的默認大小是11,增長方式的old*2+1,HashMap中hash數組的默認大小是16,增加方式必定是2的指數倍。
五、TreeMap可以把它保存的記錄根據鍵排序,默認是按升序排序。web
12三、Tomcat,Apache,JBoss,Weblogic的區別?
答:
Apache:全球應用最普遍的http服務器,免費,出自apache基金組織
Tomcat:應用也算很是普遍的web服務器,支持部分j2ee,免費,出自apache基金組織
JBoss:開源的應用服務器,比較受人喜好,免費(文檔要收費)
Weblogic:應該說算是業界第一的app server,所有支持j2ee1.4,對於開發者,有無償使用一年的許可證。面試
12四、GET,POST區別?
答:基礎知識:Http的請求格式以下。算法
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">request</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">line</span>></span>:主要包含三個信息:一、請求的類型(GET或POST),二、要訪問的資源(如\res\img\a.jif),三、Http版本(http/1.1)
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">header</span>></span>:用來講明服務器要使用的附加信息
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">blank</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">line</span>></span>:這是Http的規定,必須空一行
[<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">request-body</span>></span>]:請求的內容數據</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
區別:
一、Get是從服務器端獲取數據,Post則是向服務器端發送數據。
二、在客戶端,Get方式經過URL提交數據,在URL地址欄能夠看到請求消息,該消息被編碼過;Post數據則是放在Html header內提交。
三、對於Get方式,服務器端用Request.QueryString獲取變量的值;對用Post方式,服務器端用Request.Form獲取提交的數據值。
四、Get方式提交的數據最多1024字節,而Post則沒有限制。
五、Get方式提交的參數及參數值會在地址欄顯示,不安全,而Post不會,比較安全。
12五、Session, Cookie區別
答:
一、Session由應用服務器維護的一個服務器端的存儲空間;Cookie是客戶端的存儲空間,由瀏覽器維護。
二、用戶能夠經過瀏覽器設置決定是否保存Cookie,而不能決定是否保存Session,由於Session是由服務器端維護的。
三、Session中保存的是對象,Cookie中保存的是字符串。
四、Session和Cookie不能跨窗口使用,每打開一個瀏覽器系統會賦予一個SessionID,此時的SessionID不一樣,若要完成跨瀏覽器訪問數據,能夠使用Application。
五、Session、Cookie都有失效時間,過時後會自動刪除,減小系統開銷。
12六、Servlet的生命週期
答:大體分爲4部:Servlet類加載–>實例化–>服務–>銷燬
一、Web Client向Servlet容器(Tomcat)發出Http請求。
二、Servlet容器接收Client端的請求。
三、Servlet容器建立一個HttpRequest對象,將Client的請求信息封裝到這個對象中。
四、Servlet建立一個HttpResponse對象。
五、Servlet調用HttpServlet對象的service方法,把HttpRequest對象和HttpResponse對象做爲參數傳遞給HttpServlet對象中。
六、HttpServlet調用HttpRequest對象的方法,獲取Http請求,並進行相應處理。
七、處理完成HttpServlet調用HttpResponse對象的方法,返回響應數據。
八、Servlet容器把HttpServlet的響應結果傳回客戶端。
其中的3個方法說明了Servlet的生命週期:
一、init():負責初始化Servlet對象。
二、service():負責響應客戶端請求。
三、destroy():當Servlet對象推出時,負責釋放佔用資源。
12七、HTTP 報文包含內容
答:主要包含四部分:
一、request line
二、header line
三、blank line
四、request body
12八、Statement與PreparedStatement的區別,什麼是SQL注入,如何防止SQL注入
答:
一、PreparedStatement支持動態設置參數,Statement不支持。
二、PreparedStatement可避免如相似 單引號 的編碼麻煩,Statement不能夠。
三、PreparedStatement支持預編譯,Statement不支持。
四、在sql語句出錯時PreparedStatement不易檢查,而Statement則更便於查錯。
五、PreparedStatement可防止Sql注入,更加安全,而Statement不行。
什麼是SQL注入:
經過sql語句的拼接達到無參數查詢數據庫數據目的的方法。
如將要執行的sql語句爲 select * from table where name = 「+appName+」,利用appName參數值的輸入,來生成惡意的sql語句,如將[‘or’1’=’1’] 傳入可在數據庫中執行。
所以能夠採用PrepareStatement來避免Sql注入,在服務器端接收參數數據後,進行驗證,此時PrepareStatement會自動檢測,而Statement不 行,須要手工檢測。
12九、sendRedirect, foward區別
答:轉發是服務器行爲,重定向是客戶端行爲。
轉發過程:客戶瀏覽器發送http請求->web服務器接受此請求->調用內部的一個方法在容器內部完成請求處理和轉發動做->將目標資源 發送給客戶;在這裏,轉發的路徑必須是同一個web容器下的url,其不能轉向到其餘的web路徑上去,中間傳遞的是本身的容器內的request。在客戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感受不到服務器作了轉發的。轉發行爲是瀏覽器只作了一次訪問請求。
重定向過程:客戶瀏覽器發送http請求->web服務器接受後發送302狀態碼響應及對應新的location給客戶瀏覽器->客戶瀏覽器發現 是302響應,則自動再發送一個新的http請求,請求url是新的location地址->服務器根據此請求尋找資源併發送給客戶。在這裏location能夠重定向到任意URL,既然是瀏覽器從新發出了請求,則就沒有什麼request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的 路徑,客戶能夠觀察到地址的變化的。重定向行爲是瀏覽器作了至少兩次的訪問請求的。
130、反射講一講,主要是概念,都在哪須要反射機制,反射的性能,如何優化
答:反射機制的定義:是在運行狀態中,對於任意的一個類,都可以知道這個類的全部屬性和方法,對任意一個對象都可以經過反射機制調用一個類的任意方法,這種動態獲取類信息及動態調用類對象方法的功能稱爲java的反射機制。
反射的做用:
一、動態地建立類的實例,將類綁定到現有的對象中,或從現有的對象中獲取類型。
二、應用程序須要在運行時從某個特定的程序集中載入一個特定的類
13一、關於Cache(Ehcache,Memcached)
http://xuezhongfeicn.blog.163.com/blog/static/2246014120106144143737/
13三、畫出最熟悉的三個設計模式的類圖
13四、寫代碼分別使得JVM的堆、棧和持久代發生內存溢出(棧溢出)
一個死循環 遞歸調用就 能夠棧溢出。建好多對象實例放入ArrayList裏能夠堆溢出。持久代溢出能夠新建不少 ClassLoader 來裝載同一個類文件。
由於方法區是保存類的相關信息的,因此當咱們加載過多的類時就會致使方法區溢出。CGLIB一樣會緩存代理類的Class對象,可是咱們能夠經過配置讓它不緩存Class對象,這樣就能夠經過反覆建立代理類達到使方法區溢出的目的。
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">package <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.cdai</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.jvm</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.overflow</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lang</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reflect</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Method</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import net<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.sf</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.cglib</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.proxy</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Enhancer</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import net<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.sf</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.cglib</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.proxy</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MethodInterceptor</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import net<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.sf</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.cglib</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.proxy</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MethodProxy</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
public class MethodAreaOverflow2 {
static class OOMObject {
}
public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
enhancer<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setSuperclass</span>(OOMObject<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.class</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
enhancer<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setUseCache</span>(false)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
enhancer<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCallback</span>(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method,
Object[] args, MethodProxy proxy) throws Throwable {
return method<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.invoke</span>(obj, args)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
})<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
OOMObject proxy = (OOMObject) enhancer<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.create</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(proxy<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getClass</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
堆溢出比較簡單,只需經過建立一個大數組對象來申請一塊比較大的內存,就能夠使堆發生溢出。
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.cdai.jvm.overflow;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">HeapOverflow</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MB = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span> * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>;
SuppressWarnings(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unused"</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] bigMemory = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span> * MB];
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
棧溢出也比較常見,有時咱們編寫的遞歸調用沒有正確的終止條件時,就會使方法不斷遞歸,棧的深度不斷增大,最終發生棧溢出。
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">package com.cdai.jvm.overflow;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> StackOverflow {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> stackDepth = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">stackOverflow</span>() {
stackDepth++;
stackOverflow();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
stackOverflow();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
System.err.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Stack depth: "</span> + stackDepth);
e.printStackTrace();
}
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>
13五、hashmap的內部實現機制,hash是怎樣實現的,何時rehash
13六、java的內存管理
13七、分佈式緩存的內存管理,如何管理和釋放不斷膨脹的session,memcache是否熟悉
13八、oralce的底層管理(怎樣讓查詢快,插入慢)
13九、java底層是怎樣對文件操做的
140、研究了哪些框架的源碼
14一、併發問題,鎖,怎麼處理死鎖,髒數據處理
14一、性能問題
14二、equals和hashcode這些方法怎麼使用的
14三、java的NIO
http://lvwenwen.iteye.com/blog/1706221
14四、先從項目模塊入手,詳細問項目模塊是怎麼實現的,遇到的問題怎麼解決(必定要說本身作過的,真實的狀況)
14五、sql語句優化怎麼作的,建索引的時候要考慮什麼
14六、spring ioc你的理解,ioc容器啓動的過程是什麼樣的,什麼是ioc,aop 你我的的理解是什麼
14七、jms 你我的的理解,就是消息接收完怎麼處理,介質處理(爲何重啓mq就能恢復)
解答:http://setting.iteye.com/blog/1097767
14八、sychronized 機制 加了static 方法的同步異同,A 調用 B,A執行完了,B沒執行完,怎麼解決這個同步問題
14九、servlet 默認是線程安全的嗎,爲何不是線程安全的
解答:不是 :url:http://westlifesz.iteye.com/blog/49511
http://jsjxqjy.iteye.com/blog/1563249
http://developer.51cto.com/art/200907/133827.htm
150、spring裏面的action 默認是單列的,怎麼配置成多列?
socpe =proptype?
15一、socket 是用的什麼協議,tcp協議鏈接(握手)的過程是什麼樣的,socket使用要注意哪些問題
解答:tcp協議,
15二、數據庫鏈接池設置幾個鏈接,是怎麼處理的,說說你的理解
15三、自定義異常要怎麼考慮呢,checked的異常跟 unchecked 的異常的區別
15四、線程池是怎麼配置的,怎麼用的,要注意哪些,說下我的的理解
15五、tomact 裏session共享是怎麼作到的,
解答:http://zhli986-yahoo-cn.iteye.com/blog/1344694
15六、服務器集羣有搭建過嗎
解答:http://www.iteye.com/topic/1119823
15七、阿里B2B北京專場java開發面試題(2011.10.29)
http://yueyemaitian.iteye.com/blog/1387901
jvm的體系結構,畫了以後說各個部分的職責,並扯到運行期優化。
15八、文件拷貝,把一個文件的內容拷貝到另一個文件裏
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.io.File;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.io.FileInputStream;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.io.FileOutputStream;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.io.InputStream;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FileCopy</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args)
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> bytesum = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> byteread = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
File oldfile = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> File( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"c:/test.txt"</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ( oldfile.exists() )
{ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//文件存在時</span>
InputStream inStream = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> FileInputStream( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"c:/test.txt"</span> ); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//讀入原文件</span>
FileOutputStream fs = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> FileOutputStream( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"d:/test.txt"</span> );
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] buffer = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[ <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1444</span> ];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> length;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> ( ( byteread = inStream.read( buffer ) ) != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> )
{
bytesum += byteread; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//字節數 文件大小</span>
System.out.println( bytesum );
fs.write( buffer, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, byteread );
}
inStream.close();
}
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> ( Exception e )
{
System.out.println( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"複製單個文件操做出錯"</span> );
e.printStackTrace();
}
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>
15九、HashMap遍歷的幾種方法
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 第一種:效率高,之後必定要使用此種方式!</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Map</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> HashMap();
Iterator iter <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>entrySet()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>iterator();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (iter<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>hasNext()) {
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Entry entry <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Entry) iter<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>next();
Object key <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> entry<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getKey();
Object val <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> entry<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getValue();
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 第二種:效率低,之後儘可能少使用!</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Map</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> HashMap();
Iterator iter <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>keySet()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>iterator();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (iter<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>hasNext()) {
Object key <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> iter<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>next();
Object val <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>get(key);
} </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
160、寫一個類,鏈接數據庫並執行一條sql
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">import java.sql.*;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> SqlDemo{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
String url = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"jdbc:mysql://localhost/mydb"</span>;
String user = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"root"</span>;
String pwd = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123456"</span>;
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//加載驅動,這一句也可寫爲:Class.forName("com.mysql.jdbc.Driver");</span>
Class.forName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com.mysql.jdbc.Driver"</span>).newInstance();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//創建到MySQL的鏈接</span>
Connection conn = DriverManager.getConnection(url, user, pwd);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//執行SQL語句</span>
Statement stmt = conn.createStatement();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立語句對象,用以執行sql語言</span>
ResultSet rs = stmt.executeQuery(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"select * from student"</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//處理結果集</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (rs.next()) {
String name = rs.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>);
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(name);
}
rs.close();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//關閉數據庫</span>
conn.close();
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception ex) {
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Error : "</span> + ex.toString());
}
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li></ul>
16一、JVM性能調優,都作了什麼?
答:
1).控制GC的行爲。GC是一個後臺處理,可是它也是會消耗系統性能的,所以常常會根據系統運行的程序的特性來更改GC行爲
2).控制JVM堆棧大小。通常來講,JVM在內存分配上不須要你修改,(舉例)可是當你的程序新生代對象在某個時間段產生的比較多的時候,就須要控制新生代的堆大小.同時,還要須要控制總的JVM大小避免內存溢出。
3).控制JVM線程的內存分配。若是是多線程程序,產生線程和線程運行所消耗的內存也是能夠控制的,須要經過必定時間的觀測後,配置最優結果。
16二、TCP頭部都什麼內容
源端口和目的端口:各佔2字節.端口是傳輸層與應用層的服務接口.傳輸層的複用和分用功能都要經過端口才能實現。
序號:佔4字節.TCP 鏈接中傳送的數據流中的每個字節都編上一個序號.序號字段的值則指的是本報文段所發送的數據的第一個字節的序號
確認號:佔 4 字節,是指望收到對方的下一個報文段的數據的第一個字節的序號
數據偏移/首部長度:佔4位,它指出 TCP 報文段的數據起始處距離 TCP 報文段的起始處有多遠.「數據偏移」的單位是32位字(以 4 字節爲計算單位)
保留:佔6位,保留爲從此使用,但目前應置爲0
緊急URG:當 URG=1 時,代表緊急指針字段有效.它告訴系統此報文段中有緊急數據,應儘快傳送(至關於高優先級的數據)
確認ACK:只有當 ACK=1 時確認號字段纔有效.當 ACK=0 時,確認號無效
PSH(PuSH):接收 TCP 收到 PSH = 1 的報文段,就儘快地交付接收應用進程,而再也不等到整個緩存都填滿了後再向上交付。
RST (ReSeT):當 RST=1 時,代表 TCP 鏈接中出現嚴重差錯(如因爲主機崩潰或其餘緣由),必須釋放鏈接,而後再從新創建運輸鏈接。
同步 SYN:同步 SYN = 1 表示這是一個鏈接請求或鏈接接受報文
終止 FIN:用來釋放一個鏈接.FIN=1 代表此報文段的發送端的數據已發送完畢,並要求釋放運輸鏈接
檢驗和:佔 2 字節.檢驗和字段檢驗的範圍包括首部和數據這兩部分.在計算檢驗和時,要在 TCP 報文段的前面加上 12 字節的僞首部
緊急指針:佔 16 位,指出在本報文段中緊急數據共有多少個字節(緊急數據放在本報文段數據的最前面)
選項:長度可變.TCP 最初只規定了一種選項,即最大報文段長度 MSS.MSS 告訴對方 TCP:「個人緩存所能接收的報文段的數據字段的最大長度是 MSS 個字節.」 [MSS(Maximum Segment Size)是 TCP 報文段中的數據字段的最大長度.數據字段加上 TCP 首部纔等於整個的 TCP 報文段]
填充:這是爲了使整個首部長度是4 字節的整數倍
其餘選項:
窗口擴大:佔3字節,其中有一個字節表示移位值 S.新的窗口值等於TCP 首部中的窗口位數增大到(16 + S),至關於把窗口值向左移動 S 位後得到實際的窗口大小
時間戳:佔10 字節,其中最主要的字段時間戳值字段(4字節)和時間戳回送回答字段(4字節)
選擇確認:接收方收到了和前面的字節流不連續的兩2字節.若是這些字節的序號都在接收窗口以內,那麼接收方就先收下這些數據,但要把這些信息準確地告訴發送方,使發送方不要再重複發送這些已收到的數據
16三、DUP報文結構
16四、HTTP報文結構
HTTP請求報文:一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組成。
or
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">request-line</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">headers</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">blank</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">line</span>></span>
[<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">request-body</span>></span>]</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
請求行:請求行由請求方法字段、URL字段和HTTP協議版本字段3個字段組成,它們用空格分隔。
請求頭部:請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號「:」分隔。請求頭部通知服務器有關於客戶端請求的信息,典型的請求頭有:
- User-Agent:產生請求的瀏覽器類型。
- Accept:客戶端可識別的內容類型列表。
- Host:請求的主機名,容許多個域名同處一個IP地址,即虛擬主機。
- 空行:最後一個請求頭以後是一個空行,發送回車符和換行符,通知服務器如下再也不有請求頭。
請求數據:請求數據不在GET方法中使用,而是在POST方法中使用。POST方法適用於須要客戶填寫表單的場合。與請求數據相關的最常使用的請求頭是Content-Type和Content-Length。
HTTP響應報文:HTTP響應由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">status-line</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">headers</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">blank</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">line</span>></span>
[<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">response-body</span>></span>]</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
狀態行格式以下:HTTP-Version Status-Code Reason-Phrase CRLF
HTTP-Version表示服務器HTTP協議的版本;
Status-Code表示服務器發回的響應狀態代碼;
Reason-Phrase表示狀態代碼的文本描述。
CRLF表示換行
狀態代碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
1xx:指示信息–表示請求已接收,繼續處理。
2xx:成功–表示請求已被成功接收、理解、接受。
3xx:重定向–要完成請求必須進行更進一步的操做。
4xx:客戶端錯誤–請求有語法錯誤或請求沒法實現。
5xx:服務器端錯誤–服務器未能實現合法的請求。
常見狀態代碼、狀態描述的說明以下。
200 OK:客戶端請求成功。
400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解。
401 Unauthorized:請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用。
403 Forbidden:服務器收到請求,可是拒絕提供服務。
404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
500 Internal Server Error:服務器發生不可預期的錯誤。
503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常,舉個例子:HTTP/1.1 200 OK(CRLF)。
16五、TCP協議和UDP協議的區別
1,TCP協議面向鏈接,UDP協議面向非鏈接
2,TCP協議傳輸速度慢,UDP協議傳輸速度快
3,TCP協議保證數據順序,UDP協議不保證
4,TCP協議保證數據正確性,UDP協議可能丟包
5,TCP協議對系統資源要求多,UDP協議要求少
16六、java對象在虛擬機中怎樣實例化。
首先判斷對象實例化的類型信息是否已經在JVM,若是不存在就對類型信息進行裝載、鏈接和初始化,以後就能夠使用了,能夠訪問類型的靜態字段和方法,最後再建立類型實例,爲實例對象分配內存空間。對象的建立分爲顯示建立和隱式建立兩種。
顯示建立分爲:
一、經過new建立;
二、經過java.lang.Class的newInstance方法建立;
三、經過clone方法建立;
四、經過java.io.ObjectInputStream的readObject方法建立。
隱式建立分爲:
一、啓動類的main方法的string數組參數;
二、常量池的CONSTANT_String_info表項被解析的時候會建立一個String對象;
三、每一個加載的類都會建立一個java.lang.Class對象;
四、字符串+操做的時候,建立StringBuffer/StringBuilder對象。
對象在內存中的存儲
非嚴格意義來講,對象都存儲在堆上,由垃圾收集器負責回收再也不被引用的對象。可是隨着jvm運行期編譯技術的不斷進步,棧上分配對象和標量替換技術使得非逃逸對象能夠分配在棧上。固然絕大多數對象都是分配在堆上的,此處咱們主要討論對象在堆中的存儲。
對象的內容有:
一、實例數據;
二、指向堆中類型信息的指針;
三、對象鎖相關的數據;
四、多線程協調完成同一件事情的時候wait set相關的隊列;
五、垃圾收集相關的內容,如存活時間、finalize方法是否運行過。
對象在內存中存儲主要有兩種方式:
一、堆劃分爲句柄池和對象池,建立對象後的獲得的引用是指向句柄池的指針,句柄池指針則指向對象池裏的對象;
二、堆只分爲對象池,引用直接指向對象池中的對象。
16七、java鏈接池中鏈接如何收縮?
Java鏈接池中通常都有設置最大、最小鏈接數,當鏈接池中的鏈接達到最大鏈接數時,就不會再建立新的鏈接。通常來講定時檢測鏈接池中空閒鏈接數,當超過必定時間沒有使用的話,先判斷現有鏈接池中的鏈接是否大於最小鏈接數,若是大於的話,就好回收這個空閒鏈接,不然的話,就不會進行回收。
如何確保鏈接池中的最小鏈接數呢?有動態和靜態兩種策略。動態即每隔必定時間就對鏈接池進行檢測,若是發現鏈接數量小於最小鏈接數,則補充相應數量的新鏈接,以保證鏈接池的正常運轉。靜態是發現空閒鏈接不夠時再去檢查。
上面就是鏈接池的配置信息
16八、Java多線程問題
有以下一個類:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MyStack</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> List<String> list = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<String>();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">push</span>(String value) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>) {
list.add(value);
notify();
}
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> String <span class="hljs-title" style="box-sizing: border-box;">pop</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> InterruptedException {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (list.size() <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
wait();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> list.remove(list.size() - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
}
}
} </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>
問題: 這段代碼大多數狀況下運行正常,可是某些狀況下會出問題。何時會出現什麼問題?如何修正?
代碼分析:
從總體上,在併發狀態下,push和pop都使用了synchronized的鎖,來實現同步,同步的數據對象是基於List的數據;大部分狀況下是能夠正常工做的。
問題描述:
情況1:
1. 假設有三個線程: A,B,C. A 負責放入數據到list,就是調用push操做, B,C分別執行Pop操做,移除數據。
2. 首先B先執行,於pop中的wait()方法處,進入waiting狀態,進入等待隊列,釋放鎖。
3. A首先執行放入數據push操做到List,在調用notify()以前; 同時C執行pop(),因爲synchronized,被阻塞,進入Blocked狀態,放入基於鎖的等待隊列。注意,這裏的隊列和2中的waiting等待隊列是兩個不一樣的隊列。
4. A線程調用notify(),喚醒等待中的線程A。
5. 若是此時, C獲取到基於對象的鎖,則優先執行,執行pop方法,獲取數據,從list移除一個元素。
6. 而後,A獲取到競爭鎖,A中調用list.remove(list.size() - 1),則會報數據越界exception。
情況2:
1. 相同於情況1
2. B、C都處於等待waiting狀態,釋放鎖。等待notify()、notifyAll()操做的喚醒。
3. 存在被虛假喚醒的可能。
何爲虛假喚醒?
虛假喚醒就是一些obj.wait()會在除了obj.notify()和obj.notifyAll()的其餘狀況被喚醒,而此時是不該該喚醒的。
解決的辦法是基於while來反覆判斷進入正常操做的臨界條件是否知足:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">synchronized (obj) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<condition does not hold>)
obj.wait();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span> // Perform action appropriate to condition
} </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
如何修復問題?
1. 使用可同步的數據結構來存放數據,好比LinkedBlockingQueue之類。由這些同步的數據結構來完成繁瑣的同步操做。
2. 雙層的synchronized使用沒有意義,保留外層便可。
3. 將if替換爲while,解決虛假喚醒的問題。
16八、super.getClass方法調用
先看一下程序的代碼,看看最後的輸出結果是多少?
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.Date;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Test</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Date</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">test</span>() {
System.out.println(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.getClass().getName());
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Test().test();
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
若是不瞭解,極可能得出錯誤的答案,其實答案是Test,是否是很奇怪,結果居然是Test。
這道題就屬於腦筋急轉彎的題目,很簡單的,也很容易落入陷阱中。我想大部分人之因此落入陷阱中多是由於這個類繼承了。
若是在test方法中,直接調用getClass().getName()方法的化,至關於調用this.getClass().getName(),這樣返回的就是Test類名,getClass()返回對象運行時的字節碼對象,當前對象是Test的實例,因此其字節碼對象就是Test
因爲getClass()在Object類中定義成了final,子類不能覆蓋該方法,因此,Date類也是沒有這個方法的,在test方法中調用getClass().getName()方法,其實就是在調用從父類繼承的getClass()方法,等效於調用super.getClass().getName()方法,因此,super.getClass().getName()方法返回的也應該是Test。
若是想獲得父類的名稱,應該用以下代碼:
getClass().getSuperClass().getName();
16九、B樹,B+樹,B*樹
170、知道哪些鎖機制?(不限JAVA)什麼是可重入性? synchronized的可重入性?顯式鎖跟synchronized對比?semaphore機制怎麼實現?一個線程從wait()狀態醒來是否是必定被notify()了?
17一、什麼情景下應用過TreeMap?TreeMap內部怎麼實現的?
TreeMap 是一個有序的key-value集合,它是經過紅黑樹實現的。
TreeMap 繼承於AbstractMap,因此它是一個Map,即一個key-value集合。
TreeMap 實現了NavigableMap接口,意味着它支持一系列的導航方法。好比返回有序的key集合。
TreeMap 實現了Cloneable接口,意味着它能被克隆。
TreeMap 實現了java.io.Serializable接口,意味着它支持序列化。
TreeMap基於紅黑樹(Red-Black tree)實現。該映射根據其鍵的天然順序進行排序,或者根據建立映射時提供的 Comparator 進行排序,具體取決於使用的構造方法。
TreeMap的基本操做 containsKey、get、put 和 remove 的時間複雜度是 log(n) 。
另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fast的。
17八、Java網絡編程,socket描述什麼的?同一端口能否同時被兩個應用監聽?
Socket一般也稱做」套接字」,用於描述IP地址和端口,是一個通訊鏈的句柄。網絡上的兩個程序經過一個雙向的通信鏈接實現數據的交換,這個雙向鏈路的一端稱爲一個Socket,一個Socket由一個IP地址和一個端口號惟一肯定。應用程序一般經過」套接字」向網絡發出請求或者應答網絡請求。 Socket是TCP/IP協議的一個十分流行的編程界面,可是,Socket所支持的協議種類也不光TCP/IP一種,所以二者之間是沒有必然聯繫的。在Java環境下,Socket編程主要是指基於TCP/IP協議的網絡編程。
Socket通信過程:服務端監聽某個端口是否有鏈接請求,客戶端向服務端發送鏈接請求,服務端收到鏈接請求向客戶端發出接收消息,這樣一個鏈接就創建起來了。客戶端和服務端均可以相互發送消息與對方進行通信。
Socket的基本工做過程包含如下四個步驟:
一、建立Socket;
二、打開鏈接到Socket的輸入輸出流;
三、按照必定的協議對Socket進行讀寫操做;
四、關閉Socket。
在java.net包下有兩個類:Socket和ServerSocket。ServerSocket用於服務器端,Socket是創建網絡鏈接時使用的。在鏈接成功時,應用程序兩端都會產生一個Socket實例,操做這個實例,完成所需的會話。對於一個網絡鏈接來講,套接字是平等的,並無差異,不由於在服務器端或在客戶端而產生不一樣級別。無論是Socket仍是ServerSocket它們的工做都是經過SocketImpl類及其子類完成的。
<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Socket(InetAddress address,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立一個流套接字並將其鏈接到指定 IP 地址的指定端口號</span>
Socket(String host,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立一個流套接字並將其鏈接到指定主機上的指定端口號</span>
Socket(InetAddress address,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port, InetAddress localAddr,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> localPort);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立一個套接字並將其鏈接到指定遠程地址上的指定遠程端口</span>
Socket(String host,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port, InetAddress localAddr,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> localPort);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立一個套接字並將其鏈接到指定遠程主機上的指定遠程端口</span>
Socket(SocketImpl <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">impl</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用用戶指定的 SocketImpl 建立一個未鏈接 Socket</span>
ServerSocket(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立綁定到特定端口的服務器套接字</span>
ServerSocket(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> backlog);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//利用指定的 backlog 建立服務器套接字並將其綁定到指定的本地端口號</span>
ServerSocket(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> port,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> backlog, InetAddress bindAddr);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用指定的端口、偵聽 backlog 和要綁定到的本地 IP地址建立服務器。</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
17九、在多線程裏面如何實現一個變量被多線程獨立的訪問。
1,在線程內部建立變量
2,使用threadlocal對象
180、concurrentHashMap的實現
ConcurrentHashMap容許多個修改操做併發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對hash表的不一樣部分進行的修改。ConcurrentHashMap內部使用段(Segment)來表示這些不一樣的部分,每一個段其實就是一個小的hash table,它們有本身的鎖。只要多個修改操做發生在不一樣的段上,它們就能夠併發進行。
有些方法須要跨段,好比size()和containsValue(),它們可能須要鎖定整個表而而不只僅是某個段,這須要按順序鎖定全部段,操做完畢後,又按順序釋放全部段的鎖。這裏「按順序」是很重要的,不然極有可能出現死鎖,在ConcurrentHashMap內部,段數組是final的,而且其成員變量實際上也是final的,可是,僅僅是將數組聲明爲final的並不保證數組成員也是final的,這須要實現上的保證。這能夠確保不會出現死鎖,由於得到鎖的順序是固定的。
ConcurrentHashMap 類中包含兩個靜態內部類 HashEntry 和 Segment。HashEntry 用來封裝映射表的鍵 / 值對;Segment 用來充當鎖的角色,每一個 Segment 對象守護整個散列映射表的若干個桶。每一個桶是由若干個 HashEntry 對象連接起來的鏈表。一個 ConcurrentHashMap 實例中包含由若干個 Segment 對象組成的數組。
HashEntry 用來封裝散列映射表中的鍵值對。在 HashEntry 類中,key,hash 和 next 域都被聲明爲 final 型,value 域被聲明爲 volatile 型。同時,HashEntry 類的 value 域被聲明爲 Volatile 型,Java 的內存模型能夠保證:某個寫線程對 value 域的寫入立刻能夠被後續的某個讀線程「看」到。在 ConcurrentHashMap 中,不容許用 unll 做爲鍵和值,當讀線程讀到某個 HashEntry 的 value 域的值爲 null 時,便知道產生了衝突——發生了重排序現象,須要加鎖後從新讀入這個 value 值。這些特性互相配合,使得讀線程即便在不加鎖狀態下,也能正確訪問 ConcurrentHashMap。
在 ConcurrentHashMap 中,在散列時若是產生「碰撞」,將採用「分離連接法」來處理「碰撞」:把「碰撞」的 HashEntry 對象連接成一個鏈表。因爲 HashEntry 的 next 域爲 final 型,因此新節點只能在鏈表的表頭處插入。
Segment 類繼承於 ReentrantLock 類,從而使得 Segment 對象能充當鎖的角色。每一個 Segment 對象用來守護其(成員對象 table 中)包含的若干個桶。
避免熱點域:在 ConcurrentHashMap中,每個 Segment 對象都有一個 count 對象來表示本 Segment 中包含的 HashEntry 對象的個數。這樣當須要更新計數器時,不用鎖定整個 ConcurrentHashMap。
ConcurrentHashMap 在默認併發級別會建立包含 16 個 Segment 對象的數組。每一個 Segment 的成員對象 table 包含若干個散列表的桶。每一個桶是由 HashEntry 連接起來的一個鏈表。若是鍵能均勻散列,每一個 Segment 大約守護整個散列表中桶總數的 1/16。
在 ConcurrentHashMap 中,線程對映射表作讀操做時,通常狀況下不須要加鎖就能夠完成,對容器作結構性修改的操做才須要加鎖。
用 Volatile 變量協調讀寫線程間的內存可見性。
ConcurrentHashMap 實現高併發的總結
基於一般情形而優化
在實際的應用中,散列表通常的應用場景是:除了少數插入操做和刪除操做外,絕大多數都是讀取操做,並且讀操做在大多數時候都是成功的。正是基於這個前提,ConcurrentHashMap 針對讀操做作了大量的優化。經過 HashEntry 對象的不變性和用 volatile 型變量協調線程間的內存可見性,使得大多數時候,讀操做不須要加鎖就能夠正確得到值。這個特性使得 ConcurrentHashMap 的併發性能在分離鎖的基礎上又有了近一步的提升。
總結
ConcurrentHashMap 是一個併發散列映射表的實現,它容許徹底併發的讀取,而且支持給定數量的併發更新。相比於 HashTable 和用同步包裝器包裝的 HashMap(Collections.synchronizedMap(new HashMap())),ConcurrentHashMap 擁有更高的併發性。在 HashTable 和由同步包裝器包裝的 HashMap 中,使用一個全局的鎖來同步不一樣線程間的併發訪問。同一時間點,只能有一個線程持有鎖,也就是說在同一時間點,只能有一個線程能訪問容器。這雖然保證多線程間的安全併發訪問,但同時也致使對容器的訪問變成串行化的了。
在使用鎖來協調多線程間併發訪問的模式下,減少對鎖的競爭能夠有效提升併發性。有兩種方式能夠減少對鎖的競爭:
1. 減少請求 同一個鎖的 頻率。
2. 減小持有鎖的 時間。
ConcurrentHashMap 的高併發性主要來自於三個方面:
1. 用分離鎖實現多個線程間的更深層次的共享訪問。
2. 用 HashEntery 對象的不變性來下降執行讀操做的線程在遍歷鏈表期間對加鎖的需求。
3. 經過對同一個 Volatile 變量的寫 / 讀訪問,協調不一樣線程間讀 / 寫操做的內存可見性。
使用分離鎖,減少了請求 同一個鎖的頻率。
經過 HashEntery 對象的不變性及對同一個 Volatile 變量的讀 / 寫來協調內存可見性,使得 讀操做大多數時候不須要加鎖就能成功獲取到須要的值。因爲散列映射表在實際應用中大多數操做都是成功的 讀操做,因此 2 和 3 既能夠減小請求同一個鎖的頻率,也能夠有效減小持有鎖的時間。
經過減少請求同一個鎖的頻率和儘可能減小持有鎖的時間 ,使得 ConcurrentHashMap 的併發性相對於 HashTable 和用同步包裝器包裝的 HashMap有了質的提升。
18一、TCP長鏈接和短鏈接
當網絡通訊時採用TCP協議時,在真正的讀寫操做以前,server與client之間必須創建一個鏈接,當讀寫操做完成後,雙方再也不須要這個鏈接時它們能夠釋放這個鏈接,鏈接的創建是須要三次握手的,而釋放則須要4次握手,因此說每一個鏈接的創建都是須要資源消耗和時間消耗的。
TCP短鏈接
咱們模擬一下TCP短鏈接的狀況,client向server發起鏈接請求,server接到請求,而後雙方創建鏈接。client向server發送消息,server迴應client,而後一次讀寫就完成了,這時候雙方任何一個均可以發起close操做,不過通常都是client先發起close操做。爲何呢,通常的server不會回覆完client後當即關閉鏈接的,固然不排除有特殊的狀況。從上面的描述看,短鏈接通常只會在client/server間傳遞一次讀寫操做
短鏈接的優勢是:管理起來比較簡單,存在的鏈接都是有用的鏈接,不須要額外的控制手段。
TCP長鏈接
接下來咱們再模擬一下長鏈接的狀況,client向server發起鏈接,server接受client鏈接,雙方創建鏈接。Client與server完成一次讀寫以後,它們之間的鏈接並不會主動關閉,後續的讀寫操做會繼續使用這個鏈接。
首先說一下TCP/IP詳解上講到的TCP保活功能,保活功能主要爲服務器應用提供,服務器應用但願知道客戶主機是否崩潰,從而能夠表明客戶使用資源。若是客戶已經消失,使得服務器上保留一個半開放的鏈接,而服務器又在等待來自客戶端的數據,則服務器將永遠等待客戶端的數據,保活功能就是試圖在服務器端檢測到這種半開放的鏈接。
若是一個給定的鏈接在兩小時內沒有任何的動做,則服務器就向客戶發一個探測報文段,客戶主機必須處於
如下4個狀態之一:
客戶主機依然正常運行,並從服務器可達。客戶的TCP響應正常,而服務器也知道對方是正常的,服務器在兩小時後將保活定時器復位。
客戶主機已經崩潰,而且關閉或者正在從新啓動。在任何一種狀況下,客戶的TCP都沒有響應。服務端將不能收到對探測的響應,並在75秒後超時。服務器總共發送10個這樣的探測 ,每一個間隔75秒。若是服務器沒有收到一個響應,它就認爲客戶主機已經關閉並終止鏈接。
客戶主機崩潰並已經從新啓動。服務器將收到一個對其保活探測的響應,這個響應是一個復位,使得服務器終止這個鏈接。
客戶機正常運行,可是服務器不可達,這種狀況與2相似,TCP能發現的就是沒有收到探查的響應。
從上面能夠看出,TCP保活功能主要爲探測長鏈接的存活情況,不過這裏存在一個問題,存活功能的探測週期太長,還有就是它只是探測TCP鏈接的存活,屬於比較斯文的作法,遇到惡意的鏈接時,保活功能就不夠使了。
在長鏈接的應用場景下,client端通常不會主動關閉它們之間的鏈接,Client與server之間的鏈接若是一直不關閉的話,會存在一個問題,隨着客戶端鏈接愈來愈多,server遲早有扛不住的時候,這時候server端須要採起一些策略,如關閉一些長時間沒有讀寫事件發生的鏈接,這樣能夠避免一些惡意鏈接致使server端服務受損;若是條件再容許就能夠以客戶端機器爲顆粒度,限制每一個客戶端的最大長鏈接數,這樣能夠徹底避免某個蛋疼的客戶端連累後端服務。
長鏈接和短鏈接的產生在於client和server採起的關閉策略,具體的應用場景採用具體的策略,沒有十全十美的選擇,只有合適的選擇。
18二、Java實現Socket長鏈接和短鏈接.
概念
Socket:socket其實是對TCP/IP進行的封裝,咱們能夠使用socket套接字經過socket來傳輸。首先咱們須要明白的一個概念就是通道,簡單地說通道就是兩個對端能夠隨時傳輸數據的信道。我麼常說的所謂創建socket鏈接,也就是創建了客戶端與服務器端的通道。
長短鏈接:顯而易見,長鏈接也就是這個socket鏈接一直保持鏈接,也就是通道一直保持通暢,兩個對端能夠隨時發送和接收數據;短鏈接就是咱們發送一次或有限的幾回,socket通道就被關閉了。首先,咱們必須明白的是socket鏈接後,若是沒有任何一方關閉,這個通道是一直保持着的,換句話說,若是任何一方都不關閉鏈接,這個socket鏈接就是長鏈接,所以Java中的socket自己就是支持長鏈接的(如一個簡單的實驗:服務器端不關閉鏈接,服務器端每隔10秒發送一次數據,服務器端每次都能正確接受數據,這個實驗就能夠證實)。
那麼既然socket自己是支持長鏈接的,那麼爲何咱們還要提短鏈接的概念呢?試想一箇中國移動的短信網關(即經過發佈socket通訊接口)每時每分都有N多個鏈接發送短信請求,加入服務器不加任何限制地直接和客戶端使用長鏈接那麼可想而知服務器須要承受多麼大的壓力。因此通常的socket服務器端都是會設定超時時間的,也就是timeout,若是超過timeout服務器沒有接收到任何數據,那麼該服務器就會關閉該鏈接,從而使得服務器資源獲得有效地使用。
如何實現長短鏈接
有了長短鏈接的概念,服務器若是超過timeout時間接收不到客戶端的通訊就會斷開鏈接,那麼假如客戶端在timeout時間前一秒(或者更短的時間)發送一條激活數據來使服務器端從新計時,如此重複就能保證服務器一直不能進入timeout時間,從而一直保持鏈接,這就是長鏈接的實現原理。下面咱們經過一張圖說明:
由上圖可見,是不是長鏈接徹底取決於客戶端是否會在timeout時間發送心跳消息,所以長短鏈接是和客戶端相關的,服務器端沒有任何區別(只不過服務器端須要設定timeout而已)。
18三、適配器模式,裝飾模式,代理模式異同(適配器模式和代理模式的區別答案在其中)。
適配器模式,一個適配容許一般由於接口不兼容而不能在一塊兒工做的類工做在一塊兒,作法是將類本身的接口包裹在一個已存在的類中。
裝飾器模式,原有的不能知足現有的需求,對原有的進行加強。
代理模式,同一個類而去調用另外一個類的方法,不對這個方法進行直接操做。
適配器的特色在於兼容,從代碼上的特色來講,適配類與原有的類具備相同的接口,而且持有新的目標對象。就如同一個三孔轉2孔的適配器同樣,他有三孔的插頭,能夠插到三孔插座裏,又有兩孔的插座能夠被2孔插頭插入。適配器模式是在於對原有3孔的改造。在使用適配器模式的時候,咱們必須同時持有原對象,適配對象,目標對象。
裝飾器模式特色在於加強,他的特色是被裝飾類和全部的裝飾類必須實現同一個接口,並且必須持有被裝飾的對象,能夠無限裝飾。
代理模式的特色在於隔離,隔離調用類和被調用類的關係,經過一個代理類去調用。
總的來講就是以下三句話:
1) 適配器模式是將一個類(a)經過某種方式轉換成另外一個類(b).
2) 裝飾模式是在一個原有類(a)的基礎之上增長了某些新的功能變成另外一個類(b).
3) 代理模式是將一個類(a)轉換成具體的操做類(b).
18四、什麼是可重入鎖
見文章
18五、volatile變量的兩種特性。
可見性:volatile變量則是經過主內存完成交換,可是二者區別在於volatile變量能當即同步到主內存中,當一個線程修改變量的變量的時候,馬上會被其餘線程感知到。
阻止重排序:普通變量僅僅會保證在該方法的執行過程當中所依賴複製結果的地方都能獲取到正確的結果,而不能保證變量複製操做的
順序與程序代碼中的執行順序一致。
18六、volatile變量詳解
Volatile 變量具備 synchronized 的可見性特性,可是不具有原子特性。這就是說線程可以自動發現 volatile 變量的最新值。Volatile 變量可用於提供線程安全,可是隻能應用於很是有限的一組用例:多個變量之間或者某個變量的當前值與修改後值之間沒有約束。所以,單獨使用 volatile 還不足以實現計數器、互斥鎖或任何具備與多個變量相關的不變式(Invariants)的類(例如 「start <=end」)。此外,volatile 變量不會像鎖那樣形成線程阻塞,所以也不多形成可伸縮性問題。在某些狀況下,若是讀操做遠遠大於寫操做,volatile 變量還能夠提供優於鎖的性能優點。
正確使用 volatile 變量的條件:
要使 volatile 變量提供理想的線程安全,必須同時知足下面兩個條件:
對變量的寫操做不依賴於當前值。
該變量沒有包含在具備其餘變量的不變式中。
這些條件代表,能夠被寫入 volatile 變量的這些有效值獨立於任何程序的狀態,包括變量的當前狀態。
第一個條件的限制使 volatile 變量不能用做線程安全計數器。雖然增量操做(x++)看上去相似一個單獨操做,實際上它是一個由讀取-修改-寫入操做序列組成的組合操做,必須以原子方式執行,而 volatile 不能提供必須的原子特性。實現正確的操做須要使 x 的值在操做期間保持不變,而 volatile 變量沒法實現這點。(然而,若是將值調整爲只從單個線程寫入,那麼能夠忽略第一個條件。)
使用 volatile 變量的主要緣由是其簡易性:在某些情形下,使用 volatile 變量要比使用相應的鎖簡單得多。使用 volatile 變量次要緣由是其性能:某些狀況下,volatile 變量同步機制的性能要優於鎖。
很難作出準確、全面的評價,例如 「X 老是比 Y 快」,尤爲是對 JVM 內在的操做而言。(例如,某些狀況下 VM 也許可以徹底刪除鎖機制,這使得咱們難以抽象地比較 volatile 和 synchronized 的開銷。)就是說,在目前大多數的處理器架構上,volatile 讀操做開銷很是低 —— 幾乎和非 volatile 讀操做同樣。而 volatile 寫操做的開銷要比非 volatile 寫操做多不少,由於要保證可見性須要實現內存界定(Memory Fence),即使如此,volatile 的總開銷仍然要比鎖獲取低。
volatile 操做不會像鎖同樣形成阻塞,所以,在可以安全使用 volatile 的狀況下,volatile 能夠提供一些優於鎖的可伸縮特性。若是讀操做的次數要遠遠超過寫操做,與鎖相比,volatile 變量一般可以減小同步的性能開銷。
不少併發性專家事實上每每引導用戶遠離 volatile 變量,由於使用它們要比使用鎖更加容易出錯。然而,若是謹慎地遵循一些良好定義的模式,就可以在不少場合內安全地使用 volatile 變量。要始終牢記使用 volatile 的限制 —— 只有在狀態真正獨立於程序內其餘內容時才能使用 volatile —— 這條規則可以避免將這些模式擴展到不安全的用例。
18七、Sesson怎麼建立和銷燬。
當客戶端發出第一個請求時(無論是被訪問網站的任何頁面)就會在此站點的服務其中開闢一塊內存空間,這塊內存就是session,session的銷燬有兩種方式,一種是session過時時間已到,會自動銷燬(注意這裏不是立刻就會銷燬,具體銷燬時間由Tomcat容器所決定)。在咱們項目中的web.xml中就能夠配置:
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">session-config</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">session-timeout</span>></span>30<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">session-timeout</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">session-config</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
表示設置session過時時間爲30分鐘。值得注意的就是上面說的即便30分鐘到了session不必定會立刻銷燬,能夠經過session監聽器測試獲得每次session銷燬的時間都不同。若是要想安全的話就用下面第二種方法。在Tomcat的conf文件夾中的web.xml中能夠找到Tomcat默認的session過時時間爲30分鐘。若是咱們在咱們的站點中配置了session過時時間Tomcat容器會以站點配置爲主,若是咱們沒有在站點中配置session過時時間,將會以Tomcat下conf文件夾下的web.xml文件中配置的session過時時間爲準。
第二種銷燬方式經過手工方式銷燬,這種銷燬方式會馬上釋放服務器端session的資源,咱們手動銷燬能夠經過session().invalidate();實現。
18八、「static」關鍵字是什麼意思?Java中是否能夠覆蓋(override)一個private或者是static的方法?
「static」關鍵字代表一個成員變量或者是成員方法能夠在沒有所屬的類的實例變量的狀況下被訪問。Java中static方法不能被覆蓋,由於方法覆蓋是基於運行時動態綁定的,而static方法是編譯時靜態綁定的。static方法跟類的任何實例都不相關,因此概念上不適用。
18九、接口和抽象類的區別是什麼?
Java提供和支持建立抽象類和接口。它們的實現有共同點,不一樣點在於:
1. 接口中全部的方法隱含的都是抽象的。而抽象類則能夠同時包含抽象和非抽象的方法。
2. 類能夠實現不少個接口,可是隻能繼承一個抽象類
3. 類若是要實現一個接口,它必需要實現接口聲明的全部方法。可是,類能夠不實現抽象類聲明的全部方法,固然,在這種狀況下,類也必須得聲明成是抽象的。
4. 抽象類能夠在不提供接口方法實現的狀況下實現接口。
5. Java接口中聲明的變量默認都是final的。抽象類能夠包含非final的變量。
6. Java接口中的成員函數默認是public的。抽象類的成員函數能夠是private,protected或者是public。
7. 接口是絕對抽象的,不能夠被實例化。抽象類也不能夠被實例化,可是,若是它包含main方法的話是能夠被調用的。
190、在監視器(Monitor)內部,是如何作線程同步的?程序應該作哪一種級別的同步?
監視器和鎖在Java虛擬機中是一塊使用的。監視器監視一塊同步代碼塊,確保一次只有一個線程執行同步代碼塊。每個監視器都和一個對象引用相關聯。線程在獲取鎖以前不容許執行同步代碼。
19一、如何確保N個線程能夠訪問N個資源同時又不致使死鎖?
使用多線程的時候,一種很是簡單的避免死鎖的方式就是:指定獲取鎖的順序,並強制線程按照指定的順序獲取鎖。所以,若是全部的線程都是以一樣的順序加鎖和釋放鎖,就不會出現死鎖了。
19二、Java集合類框架的基本接口有哪些?
Java集合類提供了一套設計良好的支持對一組對象進行操做的接口和類。Java集合類裏面最基本的接口有:
Collection:表明一組對象,每個對象都是它的子元素。
Set:不包含重複元素的Collection。
List:有順序的collection,而且能夠包含重複元素。
Map:能夠把鍵(key)映射到值(value)的對象,鍵不能重複
19三、爲何集合類沒有實現Cloneable和Serializable接口?
集合類接口指定了一組叫作元素的對象。集合類接口的每一種具體的實現類均可以選擇以它本身的方式對元素進行保存和排序。有的集合類容許重複的鍵,有些不容許。克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現相關的。所以,應該由集合類的具體實現來決定如何被克隆或者是序列化。
19三、Iterator和ListIterator的區別是什麼?
下面列出了他們的區別:
Iterator可用來遍歷Set和List集合,可是ListIterator只能用來遍歷List。
Iterator對集合只能是前向遍歷,ListIterator既能夠前向也能夠後向。
ListIterator實現了Iterator接口,幷包含其餘的功能,好比:增長元素,替換元素,獲取前一個和後一個元素的索引,等等
19四、快速失敗(fail-fast)和安全失敗(fail-safe)的區別是什麼?
Iterator的安全失敗是基於對底層集合作拷貝,所以,它不受源集合上修改的影響。java.util包下面的全部的集合類都是快速失敗的,而java.util.concurrent包下面的全部的類都是安全失敗的。快速失敗的迭代器會拋出ConcurrentModificationException異常,而安全失敗的迭代器永遠不會拋出這樣的異常。
19五、Java中的HashMap的工做原理是什麼?
Java中的HashMap是以鍵值對(key-value)的形式存儲元素的。HashMap須要一個hash函數,它使用hashCode()和equals()方法來向集合/從集合添加和檢索元素。當調用put()方法的時候,HashMap會計算key的hash值,而後把鍵值對存儲在集合中合適的索引上。若是key已經存在了,value會被更新成新值。HashMap的一些重要的特性是它的容量(capacity),負載因子(load factor)和擴容極限(threshold resizing)。
19六、hashCode()和equals()方法的重要性體如今什麼地方?
Java中的HashMap使用hashCode()和equals()方法來肯定鍵值對的索引,當根據鍵獲取值的時候也會用到這兩個方法。若是沒有正確的實現這兩個方法,兩個不一樣的鍵可能會有相同的hash值,所以,可能會被集合認爲是相等的。並且,這兩個方法也用來發現重複元素。因此這兩個方法的實現對HashMap的精確性和正確性是相當重要的。當equals()方法返回true時,兩個對象必須返回相同的hashCode值,不然在HashMap中就會出錯。
19七、HashMap和Hashtable有什麼區別?
HashMap和Hashtable都實現了Map接口,所以不少特性很是類似。可是,他們有如下不一樣點:
HashMap容許鍵和值是null,而Hashtable不容許鍵或者值是null。
Hashtable是同步的,而HashMap不是。所以,HashMap更適合於單線程環境,而Hashtable適合於多線程環境。
HashMap提供了可供應用迭代的鍵的集合,所以,HashMap是快速失敗的。另外一方面,Hashtable提供了對鍵的列舉(Enumeration)。
通常認爲Hashtable是一個遺留的類。
19八、數組(Array)和列表(ArrayList)有什麼區別?何時應該使用Array而不是ArrayList?
下面列出了Array和ArrayList的不一樣點:
Array能夠包含基本類型和對象類型,ArrayList只能包含對象類型。
Array大小是固定的,ArrayList的大小是動態變化的。
ArrayList提供了更多的方法和特性,好比:addAll(),removeAll(),iterator()等等。
對於基本類型數據,集合使用自動裝箱來減小編碼工做量。可是,當處理固定大小的基本數據類型的時候,這種方式相對比較慢。
19九、ArrayList和LinkedList有什麼區別?
ArrayList和LinkedList都實現了List接口,他們有如下的不一樣點:
ArrayList是基於索引的數據接口,它的底層是數組。它能夠以O(1)時間複雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每個元素都和它的前一個和後一個元素連接在一塊兒,在這種狀況下,查找某個元素的時間複雜度是O(n)。
相對於ArrayList,LinkedList的插入,添加,刪除操做速度更快,由於當元素被添加到集合任意位置的時候,不須要像數組那樣從新計算大小或者是更新索引。
LinkedList比ArrayList更佔內存,由於LinkedList爲每個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。
200、Comparable和Comparator接口是幹什麼的?列出它們的區別。
Java提供了只包含一個compareTo()方法的Comparable接口。這個方法能夠個給兩個對象排序。具體來講,它返回負數,0,正數來代表輸入對象小於,等於,大於已經存在的對象。
Java提供了包含compare()和equals()兩個方法的Comparator接口。compare()方法用來給兩個輸入參數排序,返回負數,0,正數代表第一個參數是小於,等於,大於第二個參數。equals()方法須要一個對象做爲參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator而且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。
20一、什麼是Java優先級隊列(Priority Queue)?
PriorityQueue是一個基於優先級堆的無界隊列,它的元素是按照天然順序(natural order)排序的。在建立的時候,咱們能夠給它提供一個負責給元素排序的比較器。PriorityQueue不容許null值,由於他們沒有天然順序,或者說他們沒有任何的相關聯的比較器。最後,PriorityQueue不是線程安全的,入隊和出隊的時間複雜度是O(log(n))。
.
20二、Java集合類框架的最佳實踐有哪些?
根據應用的須要正確選擇要使用的集合的類型對性能很是重要,好比:假如元素的大小是固定的,並且能事先知道,咱們就應該用Array而不是ArrayList。
有些集合類容許指定初始容量。所以,若是咱們能估計出存儲的元素的數目,咱們能夠設置初始容量來避免從新計算hash值或者是擴容。
爲了類型安全,可讀性和健壯性的緣由老是要使用泛型。同時,使用泛型還能夠避免運行時的ClassCastException。
使用JDK提供的不變類(immutable class)做爲Map的鍵能夠避免爲咱們本身的類實現hashCode()和equals()方法。
編程的時候接口優於實現。
底層的集合其實是空的狀況下,返回長度是0的集合或者是數組,不要返回null。
20三、Enumeration接口和Iterator接口的區別有哪些?
Enumeration速度是Iterator的2倍,同時佔用更少的內存。可是,Iterator遠遠比Enumeration安全,由於其餘線程不可以修改正在被iterator遍歷的集合裏面的對象。同時,Iterator容許調用者刪除底層集合裏面的元素,這對Enumeration來講是不可能的。
20四、HashSet和TreeSet有什麼區別?
- HashSet是經過HashMap實現的,TreeSet是經過TreeMap實現的,只不過Set用的只是Map的key
- Map的key和Set都有一個共同的特性就是集合的惟一性.TreeMap更是多了一個排序的功能.
- hashCode和equal()是HashMap用的, 由於無需排序因此只須要關注定位和惟一性便可.
- a. hashCode是用來計算hash值的,hash值是用來肯定hash表索引的.
- b. hash表中的一個索引處存放的是一張鏈表, 因此還要經過equal方法循環比較鏈上的每個對象
才能夠真正定位到鍵值對應的Entry.
- c. put時,若是hash表中沒定位到,就在鏈表前加一個Entry,若是定位到了,則更換Entry中的value,並返回舊value
- 因爲TreeMap須要排序,因此須要一個Comparator爲鍵值進行大小比較.固然也是用Comparator定位的.
- a. Comparator能夠在建立TreeMap時指定
- b. 若是建立時沒有肯定,那麼就會使用key.compareTo()方法,這就要求key必須實現Comparable接口.
- c. TreeMap是使用Tree數據結構實現的,因此使用compare接口就能夠完成定位了.
HashSet是由一個hash表來實現的,所以,它的元素是無序的。add(),remove(),contains()方法的時間複雜度是O(1)。
另外一方面,TreeSet是由一個樹形的結構來實現的,它裏面的元素是有序的。所以,add(),remove(),contains()方法的時間複雜度是O(logn)。
20五、stop() 和 suspend() 方 法爲什麼不推薦使用?
反對使用stop(),是由於它不安全。它會解除由線程獲取的全部鎖定,並且若是對象處於一種不連貫狀態,那麼其餘線程能在那種狀態下檢查和修改它們。結果 很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這以前得到的鎖定。此 時,其餘任何線程都不能訪問鎖定的資源,除非被」掛起」的線程恢復運行。對任何線程來講,若是它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就 會形成死鎖。因此不該該使用suspend(),而應在本身的Thread類中置入一個標誌,指出線程應該活動仍是掛起。若標誌指出線程應該掛起,便用wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()從新啓動線程。
20六、當一個線程進入一個對象的一個 synchronized 方法後,其它線程是否可進入此對象的其它方法 ?
答:狀況一:當一個線程進入一個對象的一個synchronized方法後,其它線程能夠訪問該對象的非同步方法。
狀況二:當一個線程進入一個對象的一個synchronized方法後,其它線程不能訪問該同步方法。
狀況三:當一個線程進入一個對象的一個synchronized方法後,其它線程不能同時訪問該對象的另外一個同步方法。
20七、接口:Collection
全部集合類的根類型,主要的一個接口方法:boolean add(Ojbect c)
雖返回的是boolean,但不是表示添加成功與否,由於Collection規定:一個集合拒絕添加這個元素,不管什麼緣由,都必須拋出異常,這個返回值表示的意義是add()執行後,集合的內容是否改了(就是元素有無數量、位置等變化)。相似的addAll,remove,removeAll,remainAll也是同樣的。
用Iterator模式實現遍歷集合
Collection有一個重要的方法:iterator(),返回一個Iterator(迭代子),用於遍歷集合的全部元素。Iterator模式能夠把訪問邏輯從不一樣類的集合類中抽象出來,從而避免向客戶端暴露集合的內部結構。
for(Iterator it = c.iterator(); it.hasNext();) {…}
不須要維護遍歷集合的「指針」,全部的內部狀態都有Iterator來維護,而這個Iterator由集合類經過工廠方法生成。
每一種集合類返回的Iterator具體類型可能不一樣,但它們都實現了Iterator接口,所以,咱們不須要關心究竟是哪一種Iterator,它只須要得到這個Iterator接口便可,這就是接口的好處,面向對象的威力。
要確保遍歷過程順利完成,必須保證遍歷過程當中不更改集合的內容(Iterator的remove()方法除外),因此,確保遍歷可靠的原則是:只在一個線程中使用這個集合,或者在多線程中對遍歷代碼進行同步。
20八、JDBC:如何控制事務?
A: conn.setAutoCommit(false);
當值爲false時,表示禁止自動提交。 在默認狀況下,JDBC驅動程序會在每個更新操做語句以後自動添加commit語句,若是調用了setAutoCommit(false),則驅動程序再也不添加commit語句了。
B: conn.commit();
提交事務。即驅動程序會向數據庫發送一個commit語句。
C: conn.rollback();
回滾事務。即驅動程序會向數據庫發送一個rollback語句。
20九、ArrayList總結:
-
ArrayList是基於數組實現的,是一個動態數組,其容量能自動增加,相似於C語言中的動態申請內存,動態增加內存。
-
ArrayList不是線程安全的,只能用在單線程環境下,多線程環境下能夠考慮用Collections.synchronizedList(List l)函數返回一個線程安全的ArrayList類,也能夠使用concurrent併發包下的CopyOnWriteArrayList類。
-
ArrayList實現了Serializable接口,所以它支持序列化,可以經過序列化傳輸,實現了RandomAccess接口,支持快速隨機訪問,實際上就是經過下標序號進行快速訪問,實現了Cloneable接口,能被克隆。
-
無參構造方法構造的ArrayList的容量默認爲10,帶有Collection參數的構造方法,將Collection轉化爲數組賦給ArrayList的實現數組elementData。
-
ArrayList在每次增長元素(多是1個,也多是一組)時,都要調用該方法來確保足夠的容量。當容量不足以容納當前的元素個數時,就設置新的容量爲舊的容量的1.5倍加1,若是設置後的新容量還不夠,則直接新容量設置爲傳入的參數(也就是所需的容量),然後用Arrays.copyof()方法將元素拷貝到新的數組。
-
ArrayList基於數組實現,能夠經過下標索引直接查找到指定位置的元素,所以查找效率高,但每次插入或刪除元素,就要大量地移動元素,插入刪除元素的效率低。
-
在查找給定元素索引值等的方法中,源碼都將該元素的值分爲null和不爲null兩種狀況處理,ArrayList中容許元素爲null。
2十、CopyOnWriteArrayList
-
和ArrayList繼承於AbstractList不一樣,CopyOnWriteArrayList沒有繼承於AbstractList,它僅僅只是實現了List接口。
-
ArrayList的iterator()函數返回的Iterator是在AbstractList中實現的;而CopyOnWriteArrayList是本身實現Iterator。
-
ArrayList的Iterator實現類中調用next()時,會「調用checkForComodification()比較‘expectedModCount’和‘modCount’的大小」;可是,CopyOnWriteArrayList的Iterator實現類中,沒有所謂的checkForComodification(),更不會拋出ConcurrentModificationException異常!
-
CopyOnWriteArrayList不會拋ConcurrentModificationException,是由於全部改變其內容的操做(add、remove、clear等),都會copy一份現有數據,在現有數據上修改好,在把原有數據的引用改爲指向修改後的數據。而不是在讀的時候copy。
2十一、LinkedList總結
-
LinkedList是基於雙向循環鏈表實現的,且頭結點中不存放數據。除了能夠當作鏈表來操做外,它還能夠當作棧、隊列和雙端隊列來使用。
-
LinkedList一樣是非線程安全的,只在單線程下適合使用。
-
LinkedList實現了Serializable接口,所以它支持序列化,可以經過序列化傳輸,實現了Cloneable接口,能被克隆。
-
無參構造方法直接創建一個僅包含head節點的空鏈表,包含Collection的構造方法,先調用無參構造方法創建一個空鏈表,然後將Collection中的數據加入到鏈表的尾部後面。
-
在查找和刪除某元素時,源碼中都劃分爲該元素爲null和不爲null兩種狀況來處理,LinkedList中容許元素爲null。
-
LinkedList是基於鏈表實現的,所以不存在容量不足的問題,因此這裏沒有擴容的方法。
-
找指定位置的元素時,先將index與長度size的一半比較,若是index
2十二、Vector總結
-
Vector也是基於數組實現的,是一個動態數組,其容量能自動增加。
-
Vector是JDK1.0引入了,它的不少實現方法都加入了同步語句,所以是線程安全的(其實也只是相對安全,有些時候仍是要加入同步語句來保證線程的安全),能夠用於多線程環境。
-
Vector沒有實現Serializable接口,所以它不支持序列化,實現了Cloneable接口,能被克隆,實現了RandomAccess接口,支持快速隨機訪問。
-
Vector有四個不一樣的構造方法。無參構造方法的容量爲默認值10,僅包含容量的構造方法則將容量增加量明置爲0。
-
Vector在每次增長元素(多是1個,也多是一組)時,都要調用該方法來確保足夠的容量。當容量不足以容納當前的元素個數時,就先看構造方法中傳入的容量增加量參數CapacityIncrement是否爲0,若是不爲0,就設置新的容量爲就容量加上容量增加量,若是爲0,就設置新的容量爲舊的容量的2倍,若是設置後的新容量還不夠,則直接新容量設置爲傳入的參數(也就是所需的容量),然後一樣用Arrays.copyof()方法將元素拷貝到新的數組。
-
不少方法都加入了synchronized同步語句,來保證線程安全。
-
一樣在查找給定元素索引值等的方法中,源碼都將該元素的值分爲null和不爲null兩種狀況處理,Vector中也容許元素爲null。
-
其餘不少地方都與ArrayList實現大同小異,Vector如今已經基本再也不使用。
HashMap總結
-
HashMap是基於哈希表實現的,每個元素是一個key-value對,其內部經過單鏈表解決衝突問題,容量不足(超過了閥值)時,一樣會自動增加。
-
HashMap是非線程安全的,只是用於單線程環境下,多線程環境下能夠採用concurrent併發包下的concurrentHashMap。
-
HashMap 實現了Serializable接口,所以它支持序列化,實現了Cloneable接口,能被克隆。
-
HashMap共有四個構造方法。構造方法中提到了兩個很重要的參數:初始容量和加載因子。這兩個參數是影響HashMap性能的重要參數,其中容量表示哈希表中槽的數量(即哈希數組的長度),初始容量是建立哈希表時的容量(若是不指明,則默認爲16),加載因子是哈希表在其容量自動增長以前能夠達到多滿的一種尺度,當哈希表中的條目數超出了加載因子與當前容量的乘積時,則要對該哈希表進行 resize 操做(即擴容)。若是加載因子越大,對空間的利用更充分,可是查找效率會下降(鏈表長度會愈來愈長);若是加載因子過小,那麼表中的數據將過於稀疏(不少空間還沒用,就開始擴容了),對空間形成嚴重浪費。若是咱們在構造方法中不指定,則系統默認加載因子爲0.75,這是一個比較理想的值,通常狀況下咱們是無需修改的。另外,不管指定的容量爲多少,構造方法都會將實際容量設爲不小於指定容量的2的次方的一個數,且最大值不能超過2的30次方。每次擴容也是擴大兩倍,也就是容量老是2的冪次方。
-
HashMap中key和value都容許爲null。
-
key爲null的鍵值對永遠都放在以table[0]爲頭結點的鏈表中,固然不必定是存放在頭結點table[0]中。若是key不爲null,則先求的key的hash值,根據hash值找到在table中的索引,在該索引對應的單鏈表中查找是否有鍵值對的key與目標key相等,有就返回對應的value,沒有則返回null。
21三、Hashtable總結
-
Hashtable一樣是基於哈希表實現的,一樣每一個元素是一個key-value對,其內部也是經過單鏈表解決衝突問題,容量不足(超過了閥值)時,一樣會自動增加。
-
Hashtable也是JDK1.0引入的類,是線程安全的,能用於多線程環境中。
-
Hashtable一樣實現了Serializable接口,它支持序列化,實現了Cloneable接口,能被克隆。
-
HashTable在不指定容量的狀況下的默認容量爲11,而HashMap爲16,Hashtable不要求底層數組的容量必定要爲2的整數次冪,而HashMap則要求必定爲2的整數次冪。
-
Hashtable中key和value都不容許爲null,而HashMap中key和value都容許爲null(key只能有一個爲null,而value則能夠有多個爲null)。可是若是在Hashtable中有相似put(null,null)的操做,編譯一樣能夠經過,由於key和value都是Object類型,但運行時會拋出NullPointerException異常,這是JDK的規範規定的。
-
Hashtable擴容時,將容量變爲原來的2倍加1,而HashMap擴容時,將容量變爲原來的2倍。
-
Hashtable計算hash值,直接用key的hashCode(),而HashMap從新計算了key的hash值,Hashtable在求hash值對應的位置索引時,用取模運算,而HashMap在求位置索引時,則用與運算,且這裏通常先用hash&0x7FFFFFFF後,再對length取模,&0x7FFFFFFF的目的是爲了將負的hash值轉化爲正值,由於hash值有可能爲負數,而&0x7FFFFFFF後,只有符號外改變,然後面的位都不變。
21四、TreeMap總結
-
TreeMap是基於紅黑樹實現的。
-
TreeMap是根據key進行排序的,它的排序和定位須要依賴比較器或覆寫Comparable接口,也所以不須要key覆寫hashCode方法和equals方法,就能夠排除掉重複的key,而HashMap的key則須要經過覆寫hashCode方法和equals方法來確保沒有重複的key。
-
TreeMap的查詢、插入、刪除效率均沒有HashMap高,通常只有要對key排序時才使用TreeMap。
-
TreeMap的key不能爲null,而HashMap的key能夠爲null。
21五、LinkedHashMap總結
-
LinkedHashMap是HashMap的子類,與HashMap有着一樣的存儲結構,但它加入了一個雙向鏈表的頭結點,將全部put到LinkedHashmap的節點一一串成了一個雙向循環鏈表,所以它保留了節點插入的順序,能夠使節點的輸出順序與輸入順序相同。
-
LinkedHashMap能夠用來實現LRU算法。
-
LinkedHashMap一樣是非線程安全的,只在單線程環境下使用。
-
LinkedHashMap中加入了一個head頭結點,將全部插入到該LinkedHashMap中的Entry按照插入的前後順序依次加入到以head爲頭結點的雙向循環鏈表的尾部。
-
LinkedHashMap因爲繼承自HashMap,所以它具備HashMap的全部特性,一樣容許key和value爲null。
-
源碼中的accessOrder標誌位,當它false時,表示雙向鏈表中的元素按照Entry插入LinkedHashMap到中的前後順序排序,即每次put到LinkedHashMap中的Entry都放在雙向鏈表的尾部,這樣遍歷雙向鏈表時,Entry的輸出順序便和插入的順序一致,這也是默認的雙向鏈表的存儲順序;當它爲true時,表示雙向鏈表中的元素按照訪問的前後順序排列,能夠看到,雖然Entry插入鏈表的順序依然是按照其put到LinkedHashMap中的順序,但put和get方法均有調用recordAccess方法(put方法在key相同,覆蓋原有的Entry的狀況下調用recordAccess方法),該方法判斷accessOrder是否爲true,若是是,則將當前訪問的Entry(put進來的Entry或get出來的Entry)移到雙向鏈表的尾部(key不相同時,put新Entry時,會調用addEntry,它會調用creatEntry,該方法一樣將新插入的元素放入到雙向鏈表的尾部,既符合插入的前後順序,又符合訪問的前後順序,由於這時該Entry也被訪問了),不然,什麼也不作。
-
構造方法,前四個構造方法都將accessOrder設爲false,說明默認是按照插入順序排序的,而第五個構造方法能夠自定義傳入的accessOrder的值,所以能夠指定雙向循環鏈表中元素的排序規則,通常要用LinkedHashMap實現LRU算法,就要用該構造方法,將accessOrder置爲true。
-
LinkedHashMap是如何實現LRU的。首先,當accessOrder爲true時,纔會開啓按訪問順序排序的模式,才能用來實現LRU算法。咱們能夠看到,不管是put方法仍是get方法,都會致使目標Entry成爲最近訪問的Entry,所以便把該Entry加入到了雙向鏈表的末尾(get方法經過調用recordAccess方法來實現,put方法在覆蓋已有key的狀況下,也是經過調用recordAccess方法來實現,在插入新的Entry時,則是經過createEntry中的addBefore方法來實現),這樣便把最近使用了的Entry放入到了雙向鏈表的後面,屢次操做後,雙向鏈表前面的Entry即是最近沒有使用的,這樣當節點個數滿的時候,刪除的最前面的Entry(head後面的那個Entry)即是最近最少使用的Entry。
21六、ThreadLocal原理
首先,ThreadLocal 不是用來解決共享對象的多線程訪問問題的,通常狀況下,經過ThreadLocal.set() 到線程中的對象是該線程本身使用的對象,其餘線程是不須要訪問的,也訪問不到的。各個線程中訪問的是不一樣的對象。
另外,說ThreadLocal使得各線程可以保持各自獨立的一個對象,並非經過ThreadLocal.set()來實現的,而是經過每一個線程中的new 對象 的操做來建立的對象,每一個線程建立一個,不是什麼對象的拷貝或副本。經過ThreadLocal.set()將這個新建立的對象的引用保存到各線程的本身的一個map中,每一個線程都有這樣一個map,執行ThreadLocal.get()時,各線程從本身的map中取出放進去的對象,所以取出來的是各自本身線程中的對象,ThreadLocal實例是做爲map的key來使用的。
若是ThreadLocal.set()進去的東西原本就是多個線程共享的同一個對象,那麼多個線程的ThreadLocal.get()取得的仍是這個共享對象自己,仍是有併發訪問問題。
ThreadLocal不是用來解決對象共享訪問問題的,而主要是提供了保持對象的方法和避免參數傳遞的方便的對象訪問方式。概括了兩點:
若是要把原本線程共享的對象經過ThreadLocal.set()放到線程中也能夠,能夠實現避免參數傳遞的訪問方式,可是要注意get()到的是那同一個共享對象,併發訪問問題要靠其餘手段來解決。但通常來講線程共享的對象經過設置爲某類的靜態變量就能夠實現方便的訪問了,彷佛不必放到線程中。
ThreadLocal的應用場合,我以爲最適合的是按線程多實例(每一個線程對應一個實例)的對象的訪問,而且這個對象不少地方都要用到。
ThreadLocal類中的變量只有這3個int型:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> threadLocalHashCode = nextHashCode();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> nextHashCode = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> HASH_INCREMENT = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x61c88647</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
而做爲ThreadLocal實例的變量只有threadLocalHashCode 這一個,nextHashCode 和HASH_INCREMENT 是ThreadLocal類的靜態變量,實際上HASH_INCREMENT是一個常量,表示了連續分配的兩個ThreadLocal實例的threadLocalHashCode值的增量,而nextHashCode 的表示了即將分配的下一個ThreadLocal實例的threadLocalHashCode 的值。
建立一個ThreadLocal實例即new ThreadLocal()時作了哪些操做,從構造函數ThreadLocal()裏看什麼操做都沒有,惟一的操做是這句:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> threadLocalHashCode = nextHashCode();
nextHashCode()作了什麼呢:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">nextHashCode</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h = nextHashCode;
nextHashCode = h + HASH_INCREMENT;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> h;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
就是將ThreadLocal類的下一個hashCode值即nextHashCode的值賦給實例的threadLocalHashCode,而後nextHashCode的值增長HASH_INCREMENT這個值。
所以ThreadLocal實例的變量只有這個threadLocalHashCode,並且是final的,用來區分不一樣的ThreadLocal實例,ThreadLocal類主要是做爲工具類來使用,那麼ThreadLocal.set()進去的對象是放在哪兒的呢?
看一下上面的set()方法,兩句合併一下成爲
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ThreadLocalMap map = Thread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentThread</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.threadLocals</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
這個ThreadLocalMap 類是ThreadLocal中定義的內部類,可是它的實例卻用在Thread類中:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Thread</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Runnable</span> {</span>
......
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */</span>
ThreadLocal.ThreadLocalMap threadLocals = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
......
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
再看這句。
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (map != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>)
map.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
也就是將該ThreadLocal實例做爲key,要保持的對象做爲值,設置到當前線程的ThreadLocalMap 中,get()方法一樣相似。
21七、Static Nested Class 和 Inner Class的不一樣?
1 建立一個static內部類的對象,不須要一個外部類對象。建立一個非static內部類必需要一個外部類對象
2 不能從一個static內部類的一個對象訪問一個外部類對象,能夠從一個非static內部類訪問其外部類對象。如OutterClassName.this進行訪問。
21八、當你在瀏覽器輸入一個網址,好比http://www.taobao.com,按回車以後發生了什麼?請從技術的角度描述,如瀏覽器、網絡(UDP,TCP,HTTP等),以及服務器等各類參數與對象上由此引起的一系列活動。請儘量的涉及到全部的關鍵技術點。
答案:答題角度有如下幾個DNS域名查找,負載均衡,HTTP協議格式,HTTP下一層的TCP協議,服務器應該返回的各類網絡的應答。
一、經過訪問的域名找出其IP地址。DNS查找過程以下:
瀏覽器緩存:瀏覽器會緩存DNS記錄,並存放一段時間。
系統緩存:若是瀏覽器緩存中沒有找到須要的記錄,瀏覽器會作一個系統調用。
路由器緩存:接着前面的查詢請求發向路由器,它通常會有本身的DNS緩存。
ISP DNS緩存:接下來要check的就是ISP緩存的DNS服務器,在這通常都能找到相應的緩存記錄
遞歸搜索:你的ISP的DNS服務器從根域名服務器開始進行遞歸搜索,從.com頂級域名服務器到葉節點服務器。
二、上述這種域名解析的方式彷佛只能解析出一個ip,咱們知道通常的大型網站都有好幾個ip地址,這種問題如何解決?還好,有幾種方法能夠消除這個瓶頸:
輪叫調度(round-robin DNS):是DNS查找時返回多個IP時的解決方案。舉例來講,Facebook.com實際上就對應了四個IP地址。
負載均衡:是以一個特定IP地址進行偵聽並將網絡請求轉發到集羣服務器上的硬件設備。一些大型的站點通常都會使用這種昂貴的高性能負載均衡
地理DNS:根據用戶所處的地理位置,經過把域名映射到多個不一樣的IP地址提升可擴展性。這樣不一樣的服務器不可以更新同步狀態,但映射靜態內容的話很是好。
Anycast:是一個IP地址映射多個物理主機的路由技術。美中不足,Anycast與TCP協議適應的不是很好,因此不多應用在那些方案中。大多數DNS服務器使用Anycast來得到高效低延遲的DNS查找。
三、瀏覽器給Web服務器發送一個Http請求
這裏能夠回答的更詳細一點:好比說http協議的格式,http請求的頭,好比說發起一個Get類型請求。
四、服務器給瀏覽器響應一個301永久重定向響應
爲何要有這一步,緣由之一是爲了便於搜索引擎優化
五、瀏覽器跟中重定向地址
這個時候瀏覽器已經知道了正確的URL地址,因而從新發送一個Get請求,請求頭中的URL爲重定向以後的。
六、服務器處理請求
Web服務器軟件:web服務器軟件(IIS和Apatch)介紹到Http請求,而後肯定執行什麼請求處理來處理它。請求處理就是一個可以讀懂請求而且能生成HTML來進行相應的程序
請求處理:請求處理閱讀請求及它的參數和cookies。它會讀取也可能更新一些數據,並將數據存儲在服務器上。而後,需求處理會生成一個HTML響應。
七、服務器發回一個HTML響應
八、瀏覽器開始渲染這個HTML
九、瀏覽器發送獲取嵌入在HTML中的資源對象請求
一些嵌入在html中的資源,好比說圖片,js,css等等
十、瀏覽器發送異步(AJAX)請求
在web2.0時代,在頁面渲染成功以後,瀏覽器依然能夠跟服務器進行交互,方法就是經過這個異步請求AJAX
下面這個答案說的儘管跟這道題目關係不大,可是頗有意思。因此仍是給出來:
你打開了www.taobao.com,這時你的瀏覽器首先查詢DNS服務器,將www.taobao.com轉換成ip地址。不過首先你會發現,你在不一樣的地區或者不一樣的網絡(電信,聯通,移動)的狀況下,轉換後的ip地址極可能是不同的,這首先涉及到負載均衡的第一步,經過DNS解析域名時將你的訪問分配到不一樣的入口,同時儘量保證你所訪問的入口是全部入口中可能較快的一個。
你經過這個入口成功的訪問了www.taobao.com的實際的入口ip地址。這時你產生了一個PV,即Page View,頁面訪問。每日每一個網站的總PV量是形容一個網站規模的重要指標。淘寶網全網在平日(非促銷期間)的PV大概是16-25億之間。同時做爲一個獨立的用戶,你此次訪問淘寶網的全部頁面,均算做一個UV(Unique Visitor用戶訪問)。
由於同一時刻訪問www.taobao.com的人數過於巨大,因此即使是生成淘寶首頁頁面的服務器,也不可能僅有一臺。僅用於生成www.taobao.com首頁的服務器就有可能有成百上千臺,那麼你的一次訪問時生成頁面給你看的任務便會被分配給其中一臺服務器完成。這個過程要保證公平公正(也就是說這成百上千臺服務器每臺負擔的用戶數要差很少),這一很複雜的過程是由幾個系統配合完成,其中最關鍵的即是LVS,Linux Virtual Server,世界上最流行的負載均衡系統之一。
通過一系列複雜的邏輯運算和數據處理,用於此次給你看的淘寶網的首頁的HTML內容便生成成功了,對Web前端稍微有點常識的童鞋都應該知道,下一步瀏覽器會去加載頁面中用到的css,js,圖片等樣式,腳本和資源文件。可是可能相對較少的同窗纔會知道,你的瀏覽器在同一個域名下併發加載的資源數量是有限制的,例如ie6-7是兩個,ie8是6個,chrome個版本不大同樣,通常是4-6個。我剛剛看了一下,我訪問的淘寶網首頁須要加載126個資源,那麼如此小的併發鏈接數天然會加載好久。因此前端開發人員每每會將上述的這些資源文件分佈在好多個域名下,變相的繞過瀏覽器的這個限制,同時也爲下文的CDN工做作準備。
據不可靠消息,在雙十一當天高峯,淘寶的訪問流量達到最巔峯達到871GB/S。這個數字意味着須要178萬個4mb帶寬的家庭帶寬才能負擔的起,也徹底有能力拖垮一箇中小城市的所有互聯網帶寬。那麼顯然,這些訪問流量不可能集中在一塊兒。而且你們都知道,不一樣地區不一樣網絡(電信,聯通等)之間互訪會很是緩慢,可是你卻發現不多發現淘寶網訪問緩慢。這即是CDN,Content Delivery Network,即內容分發網絡的做用。淘寶在全國各地創建了上百個CDN節點,利用一些手段保證你的訪問的(這裏主要指js、css、圖片等)地方是離你最近的CDN節點,這樣便保證了大流量分散已經在各地訪問的加速。
這便出現了一個問題,那就是假如一個賣家發佈了一個新寶貝,上傳了幾張新的寶貝圖片,那麼淘寶網如何保證全國各地的CDN節點中都會同步的存在這幾張圖片供用戶使用呢?這裏邊就涉及到大量的內容分發與同步的相關技術。淘寶開發了分佈式文件系統TFS來處理這類問題。
21九、進程間通訊的方法主要有如下幾種:
-
管道(Pipe):管道可用於具備親緣關係進程間的通訊,容許一個進程和另外一個與它有共同祖先的進程之間進行通訊。
-
命名管道(named pipe):命名管道克服了管道沒有名字的限制,所以,除具備管道所具備的功能外,它還容許無親緣關係進程間的通訊。命名管道在文件系統中有對應的文件名。命名管道經過命令mkfifo或系統調用mkfifo來建立。
-
信號(Signal):信號是比較複雜的通訊方式,用於通知接受進程有某種事件發生,除了用於進程間通訊外,進程還能夠發送信號給進程自己;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction(實際上,該函數是基於BSD的,BSD爲了實現可靠信號機制,又可以統一對外接口,用sigaction函數從新實現了signal函數)。
-
消息(Message)隊列:消息隊列是消息的連接表,包括Posix消息隊列system V消息隊列。有足夠權限的進程能夠向隊列中添加消息,被賦予讀權限的進程則能夠讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩衝區大小受限等缺
-
共享內存:使得多個進程能夠訪問同一塊內存空間,是最快的可用IPC形式。是針對其餘通訊機制運行效率較低而設計的。每每與其它通訊機制,如信號量結合使用,來達到進程間的同步及互斥。
-
內存映射(mapped memory):內存映射容許任何多個進程間通訊,每個使用該機制的進程經過把一個共享的文件映射到本身的進程地址空間來實現它。
-
信號量(semaphore):主要做爲進程間以及同一進程不一樣線程之間的同步手段。
-
套接字(Socket):更爲通常的進程間通訊機制,可用於不一樣機器之間的進程間通訊。起初是由Unix系統的BSD分支開發出來的,但如今通常能夠移植到其它
類Unix系統上:Linux和System V的變種都支持套接字。而在java中咱們實現多線程間通訊則主要採用」共享變量」和」管道流」這兩種方法
- 方法一 經過訪問共享變量的方式(注:須要處理同步問題)
- 方法二 經過管道流
其中方法一有兩種實現方法,即
- 經過內部類實現線程的共享變量
- 經過實現Runnable接口實現線程的共享變量
2十、什麼是trie樹(單詞查找樹、字典樹)?
1.Trie樹 (特例結構樹)
Trie樹,又稱單詞查找樹、字典樹,是一種樹形結構,是一種哈希樹的變種,是一種用於快速檢索的多叉樹結構。典型應用是用於統計和排序大量的字符串(但不只限於字符串),因此常常被搜索引擎系統用於文本詞頻統計。它的優勢是:最大限度地減小無謂的字符串比較,查詢效率比哈希表高。
Trie的核心思想是空間換時間。利用字符串的公共前綴來下降查詢時間的開銷以達到提升效率的目的。
Trie樹也有它的缺點,Trie樹的內存消耗很是大.固然,或許用左兒子右兄弟的方法建樹的話,可能會好點.
2. 三個基本特性:
3 .說明:和二叉查找樹不一樣,在trie樹中,每一個結點上並不是存儲一個元素。trie樹把要查找的關鍵詞看做一個字符序列。並根據構成關鍵詞字符的前後順序構造用於檢索的樹結構。在trie樹上進行檢索相似於查閱英語詞典。 一棵m度的trie樹或者爲空,或者由m棵m度的trie樹構成。
查找分析
在trie樹中查找一個關鍵字的時間和樹中包含的結點數無關,而取決於組成關鍵字的字符數。而二叉查找樹的查找時間和樹中的結點數有關O(log2n)。
若是要查找的關鍵字能夠分解成字符序列且不是很長,利用trie樹查找速度優於
二叉查找樹。如:
若關鍵字長度最大是5,則利用trie樹,利用5次比較能夠從26^5=11881376個可能的關鍵字中檢索出指定的關鍵字。而利用二叉查找樹至少要進行 次比較。
trie樹的應用:
- 字符串檢索,詞頻統計,搜索引擎的熱門查詢。
- 字符串最長公共前綴。
- 排序。
- 做爲其餘數據結構和算法的輔助結構。如後綴樹,AC自動機等。
22一、在25匹馬中,挑出速度最快的3匹。每場比賽只能有5馬一塊兒跑。所須要的最少比賽次數是多少
至少7次
先分爲5組,每組5匹。
首先所有5組分別比賽;
其次,每組的第一名進行第六次比賽:這樣可淘汰最後兩名及其所在組的所有馬匹(共10匹),同時可淘汰第三名所在組排名靠後的其他4匹馬,以及第二名所在組的排名最後的3匹,再加上第一名所在小組的最後2名,共計淘汰19名,同時產生25匹中的冠軍(即本輪的第一名)。
最後,剩餘的5匹進行第7次比賽,前兩名爲25匹中的亞軍和季軍。
轉自:http://blog.csdn.net/derrantcm/article/details/46658823