有段時間沒有更新新文章了,接下來想把文章的更新速度放慢點,主要是想寫出更高質量的文章,最近收錄了多年面試的經典題目,包括答案,本系列會持續更新。html
1 資源佔用:進程是系統資源分配的基本單位,進程擁有本身獨立的內存空間,所屬同一進程的各個線程共享進程的內存空間。線程的上下文切換更快。 2 調度和運行:線程是進程的實體,是系統調度的基本單位,線程的調度要依賴進程,不能單獨運行。
相同: 都是實現了List接口,內部都是使用的動態數組,元素是有序的,能夠根據索引來訪問元素。 不一樣: 1 Vector是線程安全的,ArrayList和LinkedList是非線程安全的,因此ArrayLsit的執行的效率要高於Vector。 2 Vector當須要增長長度的時候,會增長原來長度的1倍,而讓ArayList會增長原來的一半。 3 Vector設置了增加空間的方法,ArrayList沒有設置此方法。 4 LinkedList是使用的雙向鏈表,繼承了Deque接口。
這2者和LinkedList的優缺點:
很明顯,LinkedList的優勢是能夠實現元素的插入和刪除操做。而Vector和ArrayList能夠實現快速的元素的隨機訪問。java
1 HashTable是線程安全的,HashMap是線程非安全的,HashMap效率會比HashTable高。 2 HashTable不能有null,HashMap能夠用null作key和value。 3 2者均可以使用iterator遍歷,而HashTable還可使用enumeration。 4 HashTable繼承比較老的Dictionary,HashMap繼承AbstractMap。儘可能使用ConcurrentHashMap替換HashTable,由於前者效率更高。 5 HashTable的初始容量是11,擴容的方式是2*old+1。而HashMap初始容量是11,並且必定是2的倍數。
1 String是final修飾的字符串常量,對象內容不可變。後2者都是字符串變量,內容能夠改變。 2 StringBuilder是非線程安全的,StringBuffer是線程安全的。因此StringBuilder的執行效率要高於StringBuffer。 3 StringBuilder和StringBuffer都是繼承自AbstractStringBuilder。
1 sleep是Thread的方法,wait是Object的方法。 2 sleep會暫停線程的執行,可是不會釋放鎖,到了指定時間會自動釋放,,而wait會釋放鎖,讓線程進入等待鎖定池。 3 sleep須要捕獲異常,而wait不用。 4 sleep能夠在任何地方使用,而wait只能在同步塊或者同步方法中使用。
1 TCP傳輸數據以前須要創建鏈接,UDP是傳送數據包,不須要創建鏈接。 2 TCP提供可靠的傳輸,並且利用滑動窗口技術還提供差錯檢測,數據重傳等服務。 3 TCP是傳輸的二進制字節流,UDP傳輸數據包,並且UDP不會提供擁塞控制,當數據傳輸量很大的時候,並不會下降發送端的傳輸速率。 4 TCP提供的是端到端的服務,UDP提供一對多,多對一,多對多的服務 5 TCP數據包的消耗比較大,而UDP數據包消耗會很小。
類的加載順序是:linux
加載->驗證->準備->解析->初始化->使用->卸載 其中前5個階段是類的加載階段。
加載:git
1 獲取classes文件(經過類的全限定名)或者網絡中的二進制字節流。 2 將二進制的靜態存儲結構轉換爲方法區的動態存儲結構。 3 在堆中生成Class對象,做爲對方法區的訪問接口。
驗證:程序員
主要驗證二進制文件的格式是否有錯誤。
準備:github
這個階段爲類的static變量分配內存,並對其賦予默認0值,只是針對static的類變量。若是是final和static同時修飾。此時就爲其分配程序中指定的值。
解析:面試
將符號引用轉換爲直接引用。
初始化:算法
真正意義上執行程序中的代碼。爲變量賦予程序中指定的值。
1 標記-清理:先標記存活的對象。而後將未標記的須要清理的對象清理掉,,效率低下,會產生內存碎片。 2 複製算法:將堆內存劃分爲2部分,將存活的正在使用的對象複製到另一個內存區域,消除了內存碎片。 3 標記-整理:標記存活的對象,而後將存活的對象向堆內存的一邊移動,消除了堆內存的內存碎片。 4 分代回收算法:將堆內存劃分爲,年輕代(Eden,Survivor from,Survivor to),年老代,永久代。而後根據不一樣內存區域中對象的生命週期來使用不一樣的回收算法。通常年輕代(由於存活對象少)使用複製算法(minor gc)。年老代使用標記-整理算法(major/full gc)。
Serial收集器通常是用在Client的虛擬機。有年輕代和年老代。sql
Serial:年輕代的垃圾回收器。使用複製算法。 Serial Old:年老代的收集器,使用標記整理算法。
Parallel收集器
Parallel Scanvage收集器:年輕代的收集器,使用複製算法。目標是獲取最大的吞吐量。 Parallel Old收集器:年老代的收集器,使用標記-整理算法。
CMS收集器(concurrent mark-sweep)
用在服務器端的收集器。目標是得到最短的用戶停頓時間。
g1收集器
最前沿科技的成果,可是內存佈局和傳統的內存佈局不同。
TCP的創建的三次握手:
原始狀態爲Closed狀態,須要創建鏈接的時候,
第一次握手
Client將數據包的SYN爲置爲1,序列號seq爲J,將數據包發送服務server,此時Client的狀態爲SYN_SENT。
第二次握手
server接受數據包後,檢查到SYN=1,知道client須要創建鏈接。server發送數據包,將SYN=1,seq=k,ACK=J+1 。server狀態爲SYN_RCVD。
第三次握手
Client收到數據包後,發送數據包,ACK=k+1。server收到數據後,檢查ACK的值無誤,鏈接創建。進入established。
TCP斷開的四次揮手:
原始狀態爲established
第一次揮手
client發送FIN數據包。客戶端進入FIN_WAIT_1。
第二次揮手
server收到數據包後。發送ACK確認包。server進入CLOSED_WAIT。client收到數據後檢查ACK無誤,client進入FIN_WAIT_2。
第三次揮手
server發送FIN數據包。server進入LAST_ACK。
第四次揮手
client收到數據包後發送ACK包,client進入TIME_WAIT。client等待2MSL後,若是server沒有反應,則進入Closed狀態。
M階B(B-)樹有如下幾點特性:
1 若是這棵樹不是空樹,根節點至少有2個子節點。 2 中間節點至少有ceil(M/2)個子節點。 3 非葉節點最多有M個子節點。 4 有k個關鍵字的節點有k+1個子節點。 5 全部葉子節點都在同一層。
數據庫事物有4個隔離級別(如下級別依次提升)
READ UNCOMMITTED:讀取未提交數據,此級別會形成髒讀,不可重複讀,幻讀。 READ COMMITTED:讀取提交數據,消除了髒讀,但仍是會有不可重複讀,幻讀。大部分數據庫都是這個隔離級別。oracle,sqlserver Repeatable read:重複讀,消除了髒讀和不可重複讀。會有幻讀。Mysql是這個隔離級別。 Serializable:最高隔離級別,消除了幻讀。
數據庫索引有彙集索引和非彙集索引。
彙集索引:彙集索引是表中的記錄的物理順序與索引的key的順序相同,彙集索引是惟一索引,一個表只能有一個索引。相對於非彙集索引,彙集索引提供更快的查詢速度。 非彙集索引:彙集索引是表中的記錄的物理順序與索引的key的順序不相同。不是惟一索引。
堆:解決程序的存儲問題,存儲運行時的對象,是全部線程共享的。 棧:解決運行問題,存儲單個線程的本地變量,運行狀態,和返回結果。線程運行結 束,棧也會隨着消失。
JVM運行時將內存區域分爲
1 程序計數器:是線程隔離的,只是線程下一條將要執行的指令的位置。 2 JVM棧:每一個線程都有本身的虛擬機棧,主要存儲線程的本地變量,天然是線程隔離的。 3 堆:存儲程序中全部的對象,是全部線程能夠共享的內存區域。 4 方法區:存儲類的信息,類變量(static變量),是全部線程共享的。
JVM規定全部的變量都存儲在主存中,而每一個線程運行時都有本身的工做內存。每一個線程不能本身操做主存,必須經過工做內存。一個線程不能直接訪問其它線程的變量。
數據庫範式有8個範式。一般咱們設計數據庫須要知足前面3個範式。
1NF 數據表的字段是原子的,不可再分。 2NF 在1NF的基礎上,非主鍵列對主鍵是徹底依賴,不存在非主屬性對主鍵的部分依賴。 3NF 在2NF的基礎上,非主鍵列對主鍵是直接依賴,不存在非主鍵列對主鍵是傳遞依賴。(如非主屬性C依賴於非主屬性B,非主屬性B依賴於主鍵A)
1 原子性:一個事務對數據的操做要麼成功,要麼失敗。若是有異常,會回滾到事務操做數據以前的狀態。 2 一致性:事務修改數據庫以前和修改數據庫以後的狀態要保持一致。 3 持久性:既事務對數據庫的操做是永久性的。 4 隔離性:多個事務之間的操做應當是隔離的。
1 指針碰撞法:針對連續的內存空間,有內存分配的請求的時候,將指針指向一邊。 2 空閒表法:針對不連續的內存空間,全部的空閒內存都記錄在一個表中,當須要分配內存的時候,查詢這個表,將知足大小的內存分配。
強引用:咱們平時使用到的引用都是強引用,在gc回收內存的時候。會將不可達對象回收掉。 軟引用:SoftReference<V>,在內存不足的時候會將軟引用對象回收掉。 弱引用:WeakRerence<V>,gc回收的時候會將弱引用對象回收掉。 虛引用:PhantomRerence<V>,此引用不能引用到對象,在跟蹤gc回收器的時候使用。
悲觀鎖:數據庫事務獲取數據以前,將數據加鎖,別的線程要讀取數據會blocking。 樂觀鎖:數據庫事務獲取數據不會加鎖,可是更新數據的時候會檢查是否有別的線程在此期間更新數據,若是有別的事務在修改數據,此事物會回滾,可使用版本號等機制。樂觀所適用於寫操做不多的狀況下。
1 髒讀:讀取到沒有提交的數據。好比老張發現本身的銀行帳戶收進了老闆打來5000元,可是老闆此時還爲提交事物,老發發現打錢的數來那個有誤,實際上是2000。老闆又撤銷了事物。這是後老張的銀行帳戶其實只有2000元。 2 不可重複讀:好比老張的老婆在用老張的帳戶進行取款操做,而此時老張正在使用銀行卡進行pos消費。當老張老婆查詢到帳戶還有5000,可是在老張老婆取款前,老張pos消費了3000.而後老張老婆進行取款,會顯示餘額不足。 3 幻讀:老張老婆在銀行部門工做,查詢了老張這個月的消費帳單,而而後老張又pos消費了一筆。而後老張老婆打印帳單會發現多了一條記錄。
Java中是這樣使用二者的:
Statement st=connectiion.createStatement();
st.execuseQuery(sql);
PreparedStatement pst=connection.preparedStatement(sql);
pst.ecxcuseQuery();
程序中應該儘可能用preparedStatement。優點以下:
1:可以使用參數化查詢。參數化查詢的效率比凌亂的字符串追加的方式的效率更高。 2:會有預編譯處理(jdbc引擎支持的前提),會將編譯好的sql語句放進數據庫系統,下次能夠從新使用。對於相同查詢,不一樣參數的查詢,效率會很好。 3:能夠防止大部分的sql注入攻擊。
1 抽象類中能夠有默認的方法實現,而接口不可有有方法的實現。 2 抽象類的方法的修飾符能夠是public, private,protected.可是接口中方法只能是public(默認就是public ) 3 抽象類能夠定義普通變量。接口中的變量只能是public static final(默認) 4 繼承抽象類後不能夠繼承其餘類,實現接口後能夠,繼承其餘類。 5 抽象類可已有構造方法,接口不行。
使用時機:
當須要有一些方法的默認實現的時候,就用抽象類。
當還有其餘的父類須要繼承的時候就必須用接口。
1 實現解耦。 2 用做緩衝。 3 異步通訊,送達保證。
IO用到的設計模式主要有裝飾模式和適配器模式。
詳情請點我
1 IO是面對字節(字符)流的,NIO是面對緩衝區的。IO面對流意味着每次從流中讀取一個或者更多字節,沒有被緩衝到任何其它地方,數據不能先後移動。NIO面對緩衝區更具備靈活性,它將數據讀取到一個緩衝區,能夠在緩衝區中先後移動數據。 2 IO是阻塞模式的。NIO是非阻塞的。阻塞意味着每次讀取數據的時候,必定要讀取到數據,若是沒有數據,此時線程不能作其它任何事情,直到等到有數據可讀(數據徹底寫入)爲止。NIO的非阻塞模式當沒有數據可讀的時候線程不會阻塞,會先去幹其它事情,一般會去處理其它channel的讀寫。因此此時一個線程就可管理多個channel。
詳細請點擊我
//內部類實現
//單例模式 class Single{ //將構造器變爲私有 private Single(){ } //內部類 private static class SingleHolder{ private static final Single Instance=new Single(); } public static Single getInstance(){ return SingleHolder.Instance; } }
堆內存
-Xms:初始內存 -Xmx:最大堆內存
非堆內存
-XX:PermSize 非堆內存初始大小 -XX:MaxPermSize:非堆內存最大大小
1 實現變量的可見性,讓讀取變量的線程及時讀取到變量最新的值,禁止工做線程拷貝。 2 防止編譯器的指令重排序。
1 BeanFactory是最基本的接口,ApplicationContext是前者的擴展。功能更增強大。 2 ApplicationContext擴展MessageSource來支持國際化功能。 3 ApplicationContext有事件監聽空能。由於其支持ApplicationEvent和ApplicationListener。 4 ApplicationContext在容器加載的時候會初始化全部容器中的對象,BeanFactory會延遲加載,直到getBean的時候纔會初始化對象。前者能更好的檢查容器配置中的錯誤。 5 BeanFactory的實現有XmlBeanFactory。ApplicationContext的實現有XmlWebApplicationContext,FileSystemXmlApplicationContext,ClassPathXmlApplicationContext, 6 ApplicationContext擴展ResourceLoader(資源加載器)支持底層資源訪問。
7大原則:
1 里氏替換原則,全部子類必須都可以代替父類。 2 依賴倒置原則,實現應該依賴與抽象,而不是具體 3 開閉原則,全部類應該對擴展開放,對修改關閉 4 單一職責原則,一個類應該專一與作一件事情。 5 迪米特原則,一個軟件實體應該儘量少得訪問其它實體。 6 聚合原則,應該儘量多得使用聚合或者複用,避免使用繼承。 7 接口隔離原則,應該儘量爲客戶提供單獨的小的接口,而不是大的接口。
1 使用new關鍵字,讀取類的靜態成員,設置類的靜態成員值,調用類的靜態方法,若是類沒有被初始化,則要先初始化類。 2 使用java.lang.reflect中的方法進行反射調用的時候,若是類沒有被初始化,則要先初始化類。 3 加載一個子類的時候,若是父類沒有被加載,則要先加載父類。 4 JVM啓動的時候,要先加載主類(帶有main方法的類)、 5 一個java.lang.invoke.MethodHandler的實例的解析結果(結果是REF_getstatic,REF_putstatic,REF_invokestatic)的方法句柄所對應的類沒有被初始化,則要先初始化此類。
1 在html標籤中使用style屬性
`<span style="color:blue">我是藍色</span>`
2 直接在head中寫css文件,style標籤
<head> <style type="text/css"> h1{color:red} </style> </head> <body> <h1>我是1號標題</h1> </body>
3 將css文件單獨寫在一個文件中而後用link標籤導入。
寫好的一個css文件test.css。而後在html文件中。
<head> <link href="test.css" rel="stylesheet" type="text/css"></link> </head>
詳細點擊我
ConcurrentHashMap主要有3個對象,HashMap,Segment,HashEntry。
ConcurrentHashMap默認有16個Segment(段),一個段裏面裝的是HashMap的一部分Entry。操做特色:
put,get,remove操做:都是將對應的Segment加鎖。讀寫某個的Segment中的Entry,並不影響其它Segment的操做,這是其增長Map性能的核心方法。
size方法會鎖定整個表。
視圖就是一些sql語句的集合,是從數據表中提取的子集。
通常能夠禁止用戶訪問數據庫表,而以視圖的方式呈現給用戶,這樣既能夠保證數據表的安全,也可讓用戶或者應用程序不受到數據庫修改帶來的影響。
2者區別:
1 視圖不佔用物理內存。表要佔用物理內存。 2 視圖是展示數據的窗口。表是數據內容。 3 咱們能夠對錶進行修改,可是隻能經過建立視圖的語句來修改視圖。
客戶端第一次經過http協議訪問服務器的時候,服務器會生成一些帶有限制條件的key-value鍵值對,cookies保存在客戶端,當下次同一客戶端訪問的時候,條件知足的時候,會將這些數據完整地帶回服務器,sessions保存在服務器端。cookies保存在客戶端瀏覽器內存中,訪問服務器的時候會返回給服務器一個name叫作JSESSIONID的一個cookie。
public class ThreadPoolExecutor extends AbstractExecutorService{}
其中最重要的構造器有
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
int corePoolSize
:核心池的線程大小。
int maximumPoolSize
:最大允許的線程大小。
long keepAliveTime
:只有正在運行的線程數量大於corePoolSize,這個參數才生效,若是一個線程無事可作,而且線程數量大於或者等於corePoolSize,超過keepAliveTime會關閉此進程,收縮到corePoolSize大小。
TimeUnit unit
:時間單位。
BlockingQueue<Runnable> workQueue
:緩衝隊列。通常能夠用ArrayBlockingQueue或者LinkedBlockingQueue。
RejectedExecutionHandler handler
:飽和策略。
其中幾個最重要的方法
submit()
execute()
shutDown()
shutDownNow()
線程池接受任務的過程以下:
1 提交一個任務,若是當前線程池中的數量小於corePoolSize,則建立線程運行此任務。
2 提交一個任務,若是當前線程數量大於或者等於corePoolSize,任務隊列未滿,則將任務放進緩衝隊列。
3 提交一個任務,若是當前線程數量大於或者等於corePoolSize而且小於maximumPoolSize,任務隊列已滿,則建立線程運行。
4 若是當前線程數量大於或者等於maximumPoolSize,緩衝隊列已滿。則達到飽和狀態,會根據響應的飽和狀態的則略來處理。默認策略是AbortPolicy。
能夠經過ThreadPoolExecutor.setRejectedExecutionHandler(RejectedExecutionHandler)
設置
策略有4種:
AbortPolicy:是默認的策略,在飽和狀態下接受任務會拋出異常,程序員能夠捕獲異常來進行本身想要的處理。
CallerRunsPolicy:會將任務交給提交任務的線程來運行。
DiscardPolicy:直接將任務丟棄。
DiscardOldestPolicy:將workQueue頭部的任務取消掉,常事從新運行。
類加載氣有如下幾種:
1 BootstrapClassLoader(啓動加載器),好比負責jre/lib/* 下面的全部包,是虛擬機自帶的,底層C++實現。 2 ExtensionClassLoader(擴展類加載器),加載jre/lib/ext/*下面的全部包。 3 ApplicationClassLoader(應用程序類加載器),加載classPath(類路徑下面的jar包)。能夠用System.getSystemClassLoader()來獲取這個加載器。 4 固然也能夠定義本身的加載器。
從上至下,上面的加載器是下面加載器的父加載器,這裏並非繼承的關係。雙親委派模型就體如今這裏:
當一個加載器收到一個類加載的請求後,會先交給父加載器去加載,若是不在父類不能加載,本身再去加載這個類。好處是類隨着這種加載機制得到了一中帶有優先級的層次關係。好比Object類,是在rt.jar中,這種機制會保證這個類都被引導類加載器加載,保證了Object的惟一性。
初始標記,併發標記,從新標記,併發清除,併發重設狀態。其中初始標記,從新標記須要Stop the world。
策略模式主要是對方法進行包裝,將不一樣的方法封裝在實現了同一個接口的類中。有環境角色,策略抽象角色,策略具體角色。
查看文件命令:cat head tail more less vim vi gvim
查找命令:grep,find,locate,whereis,which
用戶管理命令:
groupadd user, groupdel user, 查看當前用戶所在組(groups someuser), 將用戶組test修改成testnew(groupmod -n testnew test)
將用戶test添加到test2用戶組並將用戶目錄設置爲~/test usermod -d ~/test -G test2 test gpasswd -a test test2
將用戶test從test2中刪除 gpasswd -d test test2
系統性能維護命令:
top
選擇排序和堆排序:點擊我查看
本文全部代碼均在Github上共享:查看Github
更多資源
請點擊我
還有我
1 非阻塞隊列
咱們通常會接觸到非阻塞隊列 PriorityQueue,LinkedList(LinkedList實現了Deque)。可是當涉及到多線程操做的時候(好比生產者和消費者模式),就會顯得很不方便。因此這裏就會用到阻塞隊列。
2 阻塞隊列的種類:
3 經常使用到的方法
非阻塞隊列經常使用的方法有(非阻塞隊列中的方法都沒有進行線程同步):
add(E e):向隊尾添加元素,添加失敗(隊滿)拋出異常。 remove():從隊首移除元素,若是移除失敗會拋出異常。 off(E e):向隊尾添加元素,添加成功返回true,失敗返回false。 poll():從隊首獲取而且移除元素,若是成功返回隊首元素,若是移除失敗,則返回null; 一般用後2中方法,由於能夠根據返回值判斷操做是否成功。
阻塞隊列經常使用到方法:
阻塞隊列除了有以上非阻塞隊列的方法外(將以上的方法進行了同步)。還添加了如下方法: take():從隊首獲取元素,成功返回隊首的值,失敗(隊列空)則阻塞等待。 put(E e):向隊尾添加元素,添加失敗阻塞等待。 offer(E e,Time t,TimeUnit unit):向隊尾添加元素,若是等待一段時間後添加仍然失敗則返回false。 poll():從隊首獲取元素,若是等待一段時間後獲取元素仍然失敗則返回null。