一些基本概念
-
內(nèi)存溢出 out of memory,是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如申請了一個integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。
內(nèi)存泄露 memory leak,是指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴重,無論多少內(nèi)存,遲早會被占光。
memory leak會最終會導致out of memory!
棧滿時再做進棧必定產(chǎn)生空間溢出,叫上溢,??諘r再做退棧也產(chǎn)生空間溢出,稱為下溢。就是分配的內(nèi)存不足以放下數(shù)據(jù)項序列,稱為內(nèi)存溢出. -
ServerSocket(int port) 是服務(wù)端綁定port端口,調(diào)accept()監(jiān)聽等待客戶端連接,它返回一個連接隊列中的一個socket。
Socket(InetAddress address , int port)是創(chuàng)建客戶端連接主機的socket流,其中InetAddress是用來記錄主機的類,port指定端口。
socket和servletSocket的交互如下圖所示:
Paste_Image.png - A: 垃圾回收在jvm中優(yōu)先級相當相當?shù)汀?br>
B:垃圾收集器(GC)程序開發(fā)者只能推薦JVM進行回收,但何時回收,回收哪些,程序員不能控制。
C:垃圾回收機制只是回收不再使用的JVM內(nèi)存,如果程序有嚴重BUG,照樣內(nèi)存溢出。
D:進入DEAD的線程,它還可以恢復,GC不會回收 -
Java把內(nèi)存分成兩種,一種叫做棧內(nèi)存,一種叫做堆內(nèi)存。
在函數(shù)中定義的一些基本類型的變量和對象的引用變量都是在函數(shù)的棧內(nèi)存中分配。當在一段代碼塊中定義一個變量時,java就在棧中為這個變量分配內(nèi)存空間,當超過變量的作用域后,java會自動釋放掉為該變量分配的內(nèi)存空間,該內(nèi)存空間可以立刻被另作他用。
堆內(nèi)存用于存放由new創(chuàng)建的對象和數(shù)組。在堆中分配的內(nèi)存,由java虛擬機自動垃圾回收器來管理。在堆中產(chǎn)生了一個數(shù)組或者對象后,還可以在棧中定義一個特殊的變量,這個變量的取值等于數(shù)組或者對象在堆內(nèi)存中的首地址,在棧中的這個特殊的變量就變成了數(shù)組或者對象的引用變量,以后就可以在程序中使用棧內(nèi)存中的引用變量來訪問堆中的數(shù)組或者對象,引用變量相當于為數(shù)組或者對象起的一個別名,或者代號。
引用變量是普通變量,定義時在棧中分配內(nèi)存,引用變量在程序運行到作用域外釋放。而數(shù)組&對象本身在堆中分配,即使程序運行到使用new產(chǎn)生數(shù)組和對象的語句所在地代碼塊之外,數(shù)組和對象本身占用的堆內(nèi)存也不會被釋放,數(shù)組和對象在沒有引用變量指向它的時候(比如先前的引用變量x=null時),才變成垃圾,不能再被使用,但是仍然占著內(nèi)存,在隨后的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較占內(nèi)存的主要原因。
以上段落來自于某一本Java程序設(shè)計的書中,實際上,棧中的變量指向堆內(nèi)存中的變量,這就是Java中的指針。
總結(jié)起來就是對象存儲在堆內(nèi)存,引用變量存儲在棧內(nèi)存。棧內(nèi)存指向堆內(nèi)存。 - 數(shù)據(jù)類型的轉(zhuǎn)換,分為自動轉(zhuǎn)換和強制轉(zhuǎn)換。自動轉(zhuǎn)換是程序在執(zhí)行過程中 “ 悄然 ” 進行的轉(zhuǎn)換,不需要用戶提前聲明,一般是從位數(shù)低的類型向位數(shù)高的類型轉(zhuǎn)換;強制類型轉(zhuǎn)換則必須在代碼中聲明,轉(zhuǎn)換順序不受限制。
自動數(shù)據(jù)類型轉(zhuǎn)換
自動轉(zhuǎn)換按從低到高的順序轉(zhuǎn)換。不同類型數(shù)據(jù)間的優(yōu)先關(guān)系如下:
低 ---------------------------------------------> 高
byte,short,char-> int -> long -> float -> double
運算中,不同類型的數(shù)據(jù)先轉(zhuǎn)化為同一類型,然后進行運算,轉(zhuǎn)換規(guī)則如下:
| 操作數(shù) 1 類型 | 操作數(shù) 2 類型 | 轉(zhuǎn)換后的類型 |
|---|---|---|
| byte 、 short 、 char | int | int |
| byte 、 short 、 char 、 int | long | long |
| byte 、 short 、 char 、 int 、 long | float | float |
| byte 、 short 、 char 、 int 、 long 、 float | double | double |
強制數(shù)據(jù)類型轉(zhuǎn)換
強制轉(zhuǎn)換的格式是在需要轉(zhuǎn)型的數(shù)據(jù)前加上 “( )” ,然后在括號內(nèi)加入需要轉(zhuǎn)化的數(shù)據(jù)類型。有的數(shù)據(jù)經(jīng)過轉(zhuǎn)型運算后,精度會丟失,而有的會更加精確
面向?qū)ο笳Z法特點
- 方法的重寫(override)兩同兩小一大原則:
方法名相同,參數(shù)類型相同(參數(shù)順序也相同,總之參數(shù)相同,返回值類型可以不同)
子類返回類型小于等于父類方法返回類型,
子類拋出異常小于等于父類方法拋出異常,
子類訪問權(quán)限大于等于父類方法訪問權(quán)限。 - throws用于在方法上聲明該方法不需要處理的異常類型,用在方法上后面跟異常類名 可以是多個異常類
throw用于拋出具體異常類的對象,用在方法內(nèi) 后面跟異常對象只能是一個異常類型實體.
try塊必須和catch塊或和finally同在,不能單獨存在,二者必須出現(xiàn)一個.
finally塊總會執(zhí)行,不論是否有錯誤出現(xiàn).但是若try語句塊或會執(zhí)行的catch語句塊使用了JVM系統(tǒng)退出語句,finally塊就不會被執(zhí)行了. 一般我們把關(guān)閉資源的代碼放在finally里面 保證資源總是能關(guān)閉。finally在throw和return之前執(zhí)行 - 鏈接:https://www.nowcoder.com/questionTerminal/27a89bce14c242d1a4161fbeca2b6b7e來源:牛客網(wǎng)
1.父類靜態(tài)代碼塊 ( java虛擬機加載類時,就會執(zhí)行該塊代碼,故只執(zhí)行一次)
2 .子類靜態(tài)代碼塊 ( java虛擬機加載類時,就會執(zhí)行該塊代碼,故只執(zhí)行一次)
3. 父類屬性對象初始化
4.父類普通代碼塊(每次new,每次執(zhí)行 )
5. 父類構(gòu)造函數(shù)(每次new,每次執(zhí)行)
6.子 類 屬性對象初始化
7.子類普通代碼塊(每次new,每次執(zhí)行 )
8.子 類構(gòu)造函數(shù)(每次new,每次執(zhí)行) - Java 提供的事件處理模型是一種人機交互模型。它有三個基本要素:
- 事件源(Event Source):即事件發(fā)生的場所,就是指各個組件,如按鈕等,點擊按鈕其實就是組件上發(fā)生的一個事件;
- 事件(Event):事件封裝了組件上發(fā)生的事情,比如按鈕單擊、按鈕松開等等;
- 事件監(jiān)聽器(Event Listener):負責監(jiān)聽事件源上發(fā)生的特定類型的事件,當事件到來時還必須負責處理相應(yīng)的事件;
Java自帶API解讀
- String、StringBuilder、StringBuffer的區(qū)別:
String是不可變對象,不適合用來做大量修改自身操作的地方,因為每次修改都是新建一個String,會造成對內(nèi)存的浪費。StringBuilder是非線程同步的,StringBuffer是線程同步的。單線程情況下推薦使用StringBuilder,因為不用考慮同步,速度自然要快一些。 - 單線程和多線程容器有(左邊是非線程同步的,右邊是線程同步的):
- HashMap和HashTable
- StringBuilder和StringBuffer
- ArrayList和Vector
- HashMap和HashTable的區(qū)別:
- HashMap是非synchronized,而Hashtable是synchronized,這意味著Hashtable是線程安全的,多個線程可以共享一個Hashtable;而如果沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。
- HashMap可以使用null做key或者value,HashTable則不行。
sychronized意味著在一次僅有一個線程能夠更改Hashtable。就是說任何線程要更新Hashtable時要首先獲得同步鎖,其它線程要等到同步鎖被釋放之后才能再次獲得同步鎖更新Hashtable。
我們能否讓HashMap同步?
HashMap可以通過下面的語句進行同步:
Map m = Collections.synchronizeMap(hashMap);
Java多線程
- join()的作用是:“等待該線程終止”,這里需要理解的就是該線程是指的主線程等待子線程的終止。也就是在子線程調(diào)用了join()方法后面的代碼,只有等到子線程結(jié)束了才能執(zhí)行。
