死循環、死鎖、阻塞、頁面打開慢等問題,打線程dump是最好的解決問題的途徑。所謂線程dump也就是線程堆棧,獲取到線程堆棧有兩步:java
(1)獲取到線程的pid,能夠經過使用jps命令,在Linux環境下還可使用ps -ef | grep javalinux
(2)打印線程堆棧,能夠經過使用jstack pid命令,在Linux環境下還可使用kill -3 pid程序員
經過在線程之間共享對象就能夠了,而後經過wait/notify/notifyAll、await/signal/signalAll進行喚起和等待,比方說阻塞隊列BlockingQueue就是爲線程之間共享數據而設計的算法
sleep方法和wait方法均可以用來放棄CPU必定的時間,不一樣點在於若是線程持有某個對象的監視器,sleep方法不會放棄這個對象的監視器,wait方法會放棄這個對象的監視器sql
這是JDK強制的,wait()方法和notify()/notifyAll()方法在調用前都必須先得到對象的鎖shell
區別在於:wait()方法當即釋放對象監視器,notify()/notifyAll()方法則會等待線程剩餘代碼執行完畢纔會放棄對象監視器。數據庫
避免頻繁地建立和銷燬線程,達到線程對象的重用。另外,使用線程池還能夠根據項目靈活地控制併發的數目編程
Thread類提供了一個holdsLock(Object obj)方法,當且僅當對象obj的監視器被某條線程持有的時候纔會返回true,注意這是一個static方法,這意味着"某條線程"指的是當前線程。數組
若是線程是由於調用了wait()、sleep()或者join()方法而致使的阻塞,能夠中斷線程,而且經過拋出InterruptedException來喚醒它;若是線程遇到了IO阻塞,無能爲力,由於IO是操做系統實現的,Java代碼並無辦法直接接觸到操做系統。瀏覽器
多線程的上下文切換是指CPU控制權由一個已經正在運行的線程切換到另一個就緒並等待獲取CPU執行權的線程的過程。
搶佔式。一個線程用完CPU以後,操做系統會根據線程優先級、線程飢餓狀況等數據算出一個總的優先級並分配下一個時間片給某個線程執行。
單例模式的線程安全意味着:某個類的實例在多線程環境下只會被建立一次出來。單例模式有不少種的寫法,我總結一下:
(1)餓漢式單例模式的寫法:線程安全
(2)懶漢式單例模式的寫法:非線程安全
(3)雙檢鎖單例模式的寫法:線程安全
Semaphore就是一個信號量,它的做用是限制某段代碼塊的併發數。Semaphore有一個構造函數,能夠傳入一個int型整數n,表示某段代碼最多隻有n個線程能夠訪問,若是超出了n,那麼請等待,等到某個線程執行完畢這段代碼塊,下一個線程再進入。由此能夠看出若是Semaphore構造函數中傳入的int型整數n=1,至關於變成了一個synchronized了。
線程類的構造方法、靜態塊是被new這個線程類所在的線程所調用的,而run方法裏面的代碼纔是被線程自身所調用的。
例如:假設Thread2中new了Thread1,main函數中new了Thread2,那麼:
(1)Thread2的構造方法、靜態塊是main線程調用的,Thread2的run()方法是Thread2本身調用的
(2)Thread1的構造方法、靜態塊是Thread2調用的,Thread1的run()方法是Thread1本身調用的
(1)高併發、任務執行時間短的業務,線程池線程數能夠設置爲CPU核數+1,減小線程上下文的切換
(2)併發不高、任務執行時間長的業務要區分開看:
a)假如是業務時間長集中在IO操做上,也就是IO密集型的任務,由於IO操做並不佔用CPU,因此不要讓全部的CPU閒下來,能夠加大線程池中的線程數目,讓CPU處理更多的業務
b)假如是業務時間長集中在計算操做上,也就是計算密集型任務,這個就沒辦法了,和(1)同樣吧,線程池中的線程數設置得少一些,減小線程上下文的切換
(3)併發高、業務執行時間長,解決這種類型任務的關鍵不在於線程池而在於總體架構的設計,看看這些業務裏面某些數據是否能作緩存是第一步,增長服務器是第二步,至於線程池的設置,設置參考(2)。最後,業務執行時間長的問題,也可能須要分析一下,看看能不能使用中間件對任務進行拆分和解耦。
線程是操做系統可以進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運做單位。
線程是進程的子集,一個進程能夠有不少線程,每條線程並行執行不一樣的任務。不一樣的進程使用不一樣的內存空間,而全部的線程共享一片相同的內存空間。每一個線程都擁有單獨的棧內存用來存儲本地數據。
兩種方式:java.lang.Thread 類的實例就是一個線程可是它須要調用java.lang.Runnable接口來執行,因爲線程類自己就是調用的Runnable接口因此你能夠繼承java.lang.Thread 類或者直接調用Runnable接口來重寫run()方法實現線程。
當咱們在Java程序中新建一個線程時,它的狀態是New。當咱們調用線程的start()方法時,狀態被改變爲Runnable。線程調度器會爲Runnable線程池中的線程分配CPU時間而且講它們的狀態改變爲Running。其餘的線程狀態還有Waiting,Blocked 和Dead。
死鎖是指兩個以上的線程永遠阻塞的狀況,這種狀況產生至少須要兩個以上的線程和兩個以上的資源。
分析死鎖,咱們須要查看Java應用程序的線程轉儲。咱們須要找出那些狀態爲BLOCKED的線程和他們等待的資源。每一個資源都有一個惟一的id,用這個id咱們能夠找出哪些線程已經擁有了它的對象鎖。 避免嵌套鎖,只在須要的地方使用鎖和避免無限期等待是避免死鎖的一般辦法。
若是你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。若是每次運行結果和單線程運行的結果是同樣的,並且其餘的變量的值也和預期的是同樣的,就是線程安全的。一個線程安全的計數器類的同一個實例對象在被多個線程使用的狀況下也不會出現計算失誤。很顯然你能夠將集合類分紅兩組,線程安全和非線程安全的。Vector 是用同步方法來實現線程安全的, 而和它類似的ArrayList不是線程安全的。
mkdir dir1 建立一個叫作 'dir1' 的目錄'
mkdir dir1 dir2 同時建立兩個目錄
cd .. 返回上一級目錄
cd ../.. 返回上兩級目錄
shutdown -r now 重啓(1)
shutdown -h now 關閉系統(1)
uname -m 顯示機器的處理器架構(2)
find / -user user1 搜索屬於用戶 'user1' 的文件和目錄
在/etc/fstab 文件中指定的文件系統加載參數中, noauto 參數通常用於CD-ROM 等移動設備。
Linux 系統經過write命令給其餘用戶發消息。
NFS 是網絡文件系統。
外部設備文件,通常應將其放在/dev目錄中
網絡管理具有如下幾大功能:配置管理、故障管理、性能管理、安全管理和計費管理等
在vi 編輯器中的命令模式下,鍵入< o>可在光標當前所在行下添加一新行
在vi 編輯器中的命令模式下,刪除當前光標處的字符使用< x>命令
在vi 編輯器中的命令模式下,重複上一次對編輯的文本進行的操做,可以使用< .>命令
1)程序首先執行可能發生異常的try語句塊。
2)若是try語句沒有出現異常則執行完後跳至finally語句塊執行;
3)若是try語句出現異常,則中斷執行並根據發生的異常類型跳至相應的catch語句塊執行處理。
4)catch語句塊能夠有多個,分別捕獲不一樣類型的異常。
5)catch語句塊執行完後程序會繼續執行finally語句塊。
finally語句是可選的,若是有的話,則無論是否發生異常,finally語句都會被執行。須要注意的是即便try和catch塊中存在return語句,finally語句也會執行,是在執行完finally語句後再經過return退出。
NullPointerException空指針異常
ClassCastException類型轉換異常
IndexOutOfBoundsException索引超出邊界的異常
以上這些異常都是程序在運行時發生的異常,因此不須要在編寫程序時聲明
FileNotFoundException:要在編寫程序時聲明
真正影響JAVA程序性能的,就是碎片化。碎片是JAVA堆內存中的空閒空間,多是TLAB剩餘空間,也多是被釋放掉的具備較長生命週期的小對象佔用的空間。
減小new對象。每次new對象以後,都要開闢新的內存空間。這些對象不被引用以後,還要回收掉。所以,若是最大限度地合理重用對象,或者使用基本數據類型替代對象,都有助於節省內存;
多使用局部變量,減小使用靜態變量。局部變量被建立在棧中,存取速度快。靜態變量則是在堆內存;
避免使用finalize,該方法會給GC增添很大的負擔;
若是是單線程,儘可能使用非多線程安全的,由於線程安全來自於同步機制,同步機制會下降性能。例如,單線程程序,能使用HashMap,就不要用HashTable。同理,儘可能減小使用synchronized
用移位符號替代乘除號。eg:a*8應該寫做a<<3
對於常常反覆使用的對象使用緩存;
儘可能使用基本類型而不是包裝類型,儘可能使用一維數組而不是二維數組;
儘可能使用final修飾符,final表示不可修改,訪問效率高
單線程狀況下(或者是針對於局部變量),字符串儘可能使用StringBuilder,比StringBuffer要快;
儘可能早釋放無用對象的引用 大部分時,方法局部引用變量所引用的對象會隨着方法結束而變成垃圾,所以,大部分時候程序無需將局部,引用變量顯式設爲null。
儘可能避免使用二維數組 二維數據佔用的內存空間比一維數組多得多,大概10倍以上。
ArrayList & LinkedList 一個是線性表,一個是鏈表,一句話,隨機查詢儘可能使用ArrayList,ArrayList優於LinkedList,LinkedList還要移動指針,添加刪除的操做LinkedList優於ArrayList,ArrayList還要移動數據,不過這是理論性分析,事實未必如此,重要的是理解好2者得數據結構,對症下藥。
單線程應儘可能使用 HashMap, ArrayList,除非必要,不然不推薦使用HashTable,Vector,它們使用了同步機制,而下降了性能。
數組會在內存中開闢一塊連續的空間,每一個空間至關於以前的一個變量,稱爲數組的元素element
索引從0開始
數組元素有序的,不是大小順序,是索引 的順序
數組中能夠存儲基本數據類型,能夠存儲引用數據類型;可是對於一個數組而言,數組的類型是固定的,只能是一個length:數組的長度,數組的長度是固定的,一經定義,不能再發生變化
HashMap與Hashtable實現原理相同,功能相同,底層都是哈希表結構,查詢速度快,在不少狀況下能夠互用
一、Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口
二、Hashtable繼承Dictionary類,HashMap實現Map接口
三、Hashtable線程安全,HashMap線程非安全
四、Hashtable不容許null值,HashMap容許null值
一、HashSet底層是採用HashMap實現的。HashSet 的實現比較簡單,HashSet 的絕大部分方法都是經過調用 HashMap 的方法來實現的,所以 HashSet 和 HashMap 兩個集合在實現本質上是相同的。
二、HashMap的key就是放進HashSet中對象,value是Object類型的。
三、當調用HashSet的add方法時,其實是向HashMap中增長了一行(key-value對),該行的key就是向HashSet增長的那個對象,該行的value就是一個Object類型的常量
Java取消了強大但又危險的指針,而代之以引用。因爲指針可進行移動運算,指針可隨便指向一個內存區域,而無論這個區域是否可用,這樣作是危險的,由於原來這個內存地址可能存儲着重要數據或者是其餘程序運行所佔用的,而且使用指針也容易數組越界。
垃圾回收機制:不須要程序員直接控制內存回收,由垃圾回收器在後臺自動回收再也不使用的內存。避免程序忘記及時回收,致使內存泄露。避免程序錯誤回收程序核心類庫的內存,致使系統崩潰。
異常處理機制:Java異常機制主要依賴於try、catch、finally、throw、throws五個關鍵字。
強制類型轉換:只有在知足強制轉換規則的狀況下才能強轉成功。
ava中的序列化機制可以將一個實例對象(只序列化對象的屬性值,而不會去序列化什麼所謂的方法。)的狀態信息寫入到一個字節流中使其能夠經過socket進行傳輸、或者持久化到存儲數據庫或文件系統中;而後在須要的時候經過字節流中的信息來重構一個相同的對象。通常而言,要使得一個類能夠序列化,只需簡單實現java.io.Serializable接口便可。
(1)啓動類加載器(Bootstrap ClassLoader)
這個類加載器負責將存放在JAVA_HOME/lib下的,或者被-Xbootclasspath參數所指定的路徑中的,而且是虛擬機識別的類庫加載到虛擬機內存中。啓動類加載器沒法被Java程序直接引用。
(2)擴展類加載器(Extension ClassLoader)
這個加載器負責加載JAVA_HOME/lib/ext目錄中的,或者被java.ext.dirs系統變量所指定的路徑中的全部類庫,開發者能夠直接使用擴展類加載器
(3)應用程序類加載器(Application ClassLoader)
這個加載器是ClassLoader中getSystemClassLoader()方法的返回值,因此通常也稱它爲系統類加載器。它負責加載用戶類路徑(Classpath)上所指定的類庫,可直接使用這個加載器,若是應用程序沒有自定義本身的類加載器,通常狀況下這個就是程序中默認的類加載器
雙親委派模型要求除了頂層的啓動類加載器外,其餘的類加載器都應當有本身的父類加載器。這裏類加載器之間的父子關係通常不會以繼承關係來實現,而是都使用組合關係來複用父加載器的代碼。
若是一個類加載器收到了類加載的請求,它首先不會本身去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每個層次的類加載器都是如此,所以全部的加載請求最終都應該傳遞到頂層的啓動類加載器中,只有當父類加載器反饋本身沒法完成這個請求(它的搜索範圍中沒有找到所需的類)時,子加載器纔會嘗試本身去加載。
Java類隨着它的類加載器一塊兒具有了一種帶有優先級的層次關係。例如類Object,它放在rt.jar中,不管哪個類加載器要加載這個類,最終都是委派給啓動類加載器進行加載,所以Object類在程序的各類類加載器環境中都是同一個類,判斷兩個類是否相同是經過classloader.class這種方式進行的,因此哪怕是同一個class文件若是被兩個classloader加載,那麼他們也是不一樣的類。
A m.length() B. m.length C. m.length()+1 D. m.length+1 答案:B 分析:數組的長度是.length
A java.sql B. java.awt C. java.lang D. java.swing
答案:A
分析: java.awt和javax.swing兩個包是圖形用戶界面編程所須要的包; java.lang包則提供了Java編程中用到的基礎類。
public class Test1 { public static void main(String[] args) { int a = 0; int c = 0; do{ --c; a = a - 1; } while (a > 0); System.out.println(c); } }
A 0 B. 1 C. -1 D. 死循環
答案:C
分析: do-while循環的特色是先執行後判斷,因此代碼先執行--c操做,獲得c爲-1,以後執行a=a-1的操做,獲得a爲-1,而後判斷a是否大於0,判斷條件不成立,退出循環,輸出c爲-1。
A abstract修飾符可修飾字段,方法和類
B. 抽象方法的body部分必須用一對大括號{}包住
C. 聲明抽象方法,大括號無關緊要
D. 聲明抽象方法不可寫出大括號
答案:D
分析: abstract只能修飾方法和類,不能修飾字段; 抽象方法不能有方法體,即沒有{}; 同B。
A 實例方法可直接調用超類的實例方法
B. 實例方法可直接調用超類的類方法
C. 實例方法可直接調用其餘類的實例方法
D. 實例方法可直接調用本類的類方法
答案:D
分析: 實例方法不可直接調用超類的私有實例方法; 實例方法不可直接調用超類的私有的類方法; 要看訪問權限。
Java程序的種類有()(多選)
A 類 (Class)
B. Applet
C. Application
D. Servlet
答案:BCD
分析: 是Java中的類,不是程序; 內嵌於Web文件中,由瀏覽器來觀看的Applet; 可獨立運行的 Application; 服務器端的 Servlet。
下列說法正確的有()(多選)
A 環境變量可在編譯source code時指定
B. 在編譯程序時,所指定的環境變置不包括class path
C. javac —次可同時編譯數個Java 源文件
D. javac.exe能指定編譯結果要置於哪一個目錄(directory)
答案:BCD
分析: 環境變量通常都是先配置好再編譯源文件。
下列說法錯誤的有()(多選)
A 在類方法中可用this來調用本類的類辦法
B. 在類方法中調用本類的類方法時能夠直接調用
C. 在類方法中只能調用本類中的類方法
D. 在類方法中絕對不能調用實例方法
答案:ACD
分析: 類方法是在類加載時被加載到方法區存儲的,此時尚未建立對象,因此不能使用this或者super關鍵字;
C. 在類方法中還能夠調用其餘類的類方法; D. 在類方法能夠經過建立對象來調用實例方法。
在調用方法時,若要使方法改變實參的值,能夠?()
A 用基本數據類型做爲參數
B.用對象做爲參數
C.A和B都對
D.A和B都不對
答案:B
分析:基本數據類型不能改變實參的值
A static
B.package
C.private
D.public
答案:A
(1) 用new語句建立對象,這是最多見的建立對象的方法。
(2) 運用反射手段,調用java.lang.Class或者 java.lang.reflect.Constructor類的newInstance()實例方法。
(3) 調用對象的clone()方法
(4) 運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。
注意:(1)和(2)都會明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,因此不會調用構造函數 (4)是從文件中還原類的對象,也不會調用構造函數。
答案: -11
分析:
小數點後第一位=5
正數:Math.round(11.5)=12
負數:Math.round(-11.5)=-11
小數點後第一位<5
正數:Math.round(11.46)=11
負數:Math.round(-11.46)=-11 小
數點後第一位>5
正數:Math.round(11.68)=12
負數:Math.round(-11.68)=-12
根據上面例子的運行結果,咱們還能夠按照以下方式總結,或許更加容易記憶:
參數的小數點後第一位<5,運算結果爲參數整數部分。
參數的小數點後第一位>5,運算結果爲參數整數部分絕對值+1,符號(即正負)不變。
參數的小數點後第一位=5,正數運算結果爲整數部分+1,負數運算結果爲整數部分。
總結:大於五所有加,等於五正數加,小於五全不加。
(1) 線程建立時,子線程繼承父線程的優先級
(2) 線程建立後,可在程序中經過調用setPriority( )方法改變線程的優先級
(3) 線程的優先級是1~10之間的正整數,數字越大優先級越高,默認的優先級是居中,即爲5。
數組不是面向對象的,存在明顯的缺陷,集合徹底彌補了數組的一些缺點,比數組更靈活更實用,可大大提升軟件的開發效率並且不一樣的集合框架類可適用於不一樣場合。具體以下:
1)數組的效率高於集合類.
2)數組能存放基本數據類型和對象,而集合類中只能放對象。
3)數組容量固定且沒法動態改變,集合類容量動態改變。
4)數組沒法判斷其中實際存有多少元素,length只告訴了array的容量。
5)集合有多種實現方式和不一樣的適用場合,而不像數組僅採用順序表方式。
6)集合以類的形式存在,具備封裝、繼承、多態等類的特性,經過簡單的方法和屬性調用便可實現各類複雜操做,大大提升軟件的開發效率。
Collection:表明一組對象,每個對象都是它的子元素。
Set:不包含重複元素的Collection。
List:有順序的Collection,而且能夠包含重複元素。
Map:能夠把鍵(key)映射到值(value)的對象,鍵不能重複。
ArrayList list=new ArrayList(20);中的list擴充幾回()
A. 0 B. 1 C. 2 D. 3
答案:A 分析:已經指定了長度, 因此不擴容
如下結構中,哪一個具備同步功能()
A. HashMap B. ConcurrentHashMap C. WeakHashMap D. TreeMap
答案:B
分析: A,C,D都線程不安全,B線程安全,具備同步功能