##數(shù)據(jù)庫
#三個(gè)范式
屬性唯一(確
保每列保持原子性)???數(shù)據(jù)庫表中的字段都是單一屬性的,不可再分。這個(gè)單一屬性由基本類型構(gòu)成,包括整型、實(shí)數(shù)、字符型、邏輯型、日期型等。
記錄唯一(確保表中的每列都和主鍵相關(guān))???數(shù)據(jù)庫表中不存在非關(guān)鍵字段對任一候選關(guān)鍵字段的部分函數(shù)依賴(部分函數(shù)依賴指的是存在組合關(guān)鍵字中的某些字段決定非關(guān)鍵字段的情況),也即所有非關(guān)鍵字段都完全依賴于任意一組候選關(guān)鍵字
表唯一(確保每列都和主鍵列直接相關(guān),而不是間接相關(guān))????????在第二范式的基礎(chǔ)上,數(shù)據(jù)表中如果不存在非關(guān)鍵字段對任一候選關(guān)鍵字段的傳遞函數(shù)依賴則符合第三范式。所謂傳遞函數(shù)依賴,指的是如果存在"A → B → C"的決定關(guān)系,則C傳遞函數(shù)依賴于A。因此,滿足第三范式的數(shù)據(jù)庫表應(yīng)該不存在如下依賴關(guān)系: 關(guān)鍵字段 → 非????????關(guān)鍵????字段x → 非關(guān)鍵字段y
#SQL優(yōu)化
總是使用索引的第一個(gè)列
使用where而不是having
多使用commit
使用truncate而不是delete
#Servlet
#運(yùn)行過程
Servlet由web服務(wù)器調(diào)用,收到客戶端的Servlet訪問請求后
1.檢查是否已經(jīng)裝載并創(chuàng)建了該Servlet的實(shí)例對象,是轉(zhuǎn)4,不是轉(zhuǎn)2
2.裝載并創(chuàng)建該Servlet的一個(gè)實(shí)例對象
3.調(diào)用init()方法
4.創(chuàng)建一個(gè)用于封裝HttpSevrletRequest對象和一個(gè)代表Http響應(yīng)消息的HttpServletRespouse對象,調(diào)用Service()方法,將這兩個(gè)對象傳遞出去
5.web應(yīng)用程序停止或者重啟之前,卸載Servlet,并調(diào)用其destroy()方法
#JAVA線程安全
#線程操作某個(gè)對象
多個(gè)線程同時(shí)讀寫某個(gè)內(nèi)存數(shù)據(jù)時(shí),就會(huì)產(chǎn)生多線程并發(fā)問題,涉及到三個(gè)特性:原子性,有序性,可見性
(1) 從主存復(fù)制變量到當(dāng)前工作內(nèi)存 (read and load)
(2) 執(zhí)行代碼,改變共享變量值 (use and assign)
(3) 用工作內(nèi)存數(shù)據(jù)刷新主存相關(guān)內(nèi)容 (store and write)
##synchronized關(guān)鍵字
synchronized(鎖){
臨界區(qū)代碼
}
public synchronized void function() {
臨界區(qū)代碼
}
//每個(gè)對象都可以做為鎖,但一個(gè)對象做為鎖時(shí),應(yīng)該被多個(gè)線程共享,這樣才顯得有意義,在并發(fā)環(huán)境下,一個(gè)沒有共享的對象作為鎖是沒有意義的
//每個(gè)鎖對象都有兩個(gè)隊(duì)列,一個(gè)是就緒隊(duì)列,一個(gè)是阻塞隊(duì)列,就緒隊(duì)列存儲了將要獲得鎖的線程,阻塞隊(duì)列存儲了被阻塞的線程,當(dāng)一個(gè)被線程被喚醒 (notify)后,才會(huì)進(jìn)入到就緒隊(duì)列,等待cpu的調(diào)度
//一個(gè)線程執(zhí)行臨界區(qū)代碼過程
1 獲得同步鎖
2 清空工作內(nèi)存
3 從主存拷貝變量副本到工作內(nèi)存
4 對這些變量計(jì)算
5 將變量從工作內(nèi)存寫回到主存
6 釋放鎖
//synchronized既保證了多線程的并發(fā)有序性,又保證了多線程的內(nèi)存可見性。
##volatile關(guān)鍵字
volatile只能保證多線程的內(nèi)存可見性,不能保證多線程的執(zhí)行有序性
任何被volatile修飾的變量,都不拷貝副本到工作內(nèi)存,任何修改都及時(shí)寫在主存。因此對于Valatile修飾的變量的修改,
所有線程馬上就能看到,但是volatile不能保證對變量的修改是有序的.
//要使 volatile 變量提供理想的線程安全,必須同時(shí)滿足下面兩個(gè)條件:
1)對變量的寫操作不依賴于當(dāng)前值。
2)該變量沒有包含在具有其他變量的不變式中
##JVM內(nèi)存劃分
1.程序計(jì)數(shù)器
每一個(gè)Java線程都有一個(gè)程序計(jì)數(shù)器來用于保存程序執(zhí)行到當(dāng)前方法的哪一個(gè)指令。
2.線程棧
線程的每個(gè)方法被執(zhí)行的時(shí)候,都會(huì)同時(shí)創(chuàng)建一個(gè)幀(Frame)用于存儲本地變量表、操作棧、動(dòng)態(tài)鏈接、方法出入口等信息
3.本地方法棧
4.堆
每個(gè)線程的棧都是該線程私有的,堆則是所有線程共享的,new一個(gè)對象被分配到堆中
jvm的gc都是按代收集,
堆區(qū)大致被分為三大塊:新生代,舊生代,持久代(虛擬的);新生代又分為eden區(qū),s0區(qū),s1區(qū)。
新建一個(gè)對象時(shí),基本小的對象,生命周期短的對象都會(huì)放在新生代的eden區(qū)中,
eden區(qū)滿時(shí),有一個(gè)小范圍的gc(minor gc)
整個(gè)新生代滿時(shí),會(huì)有一個(gè)大范圍的gc(major gc),將新生代里的部分對象轉(zhuǎn)到舊生代里。
5.方法區(qū)
永久代,包括常量池、字段描述、方法描述
6.常量池
##垃圾回收器
引用計(jì)數(shù)法 (Reference Counting)
對于一個(gè)對象 A,只要有任何一個(gè)對象引用了 A,則 A 的引用計(jì)數(shù)器就加 1,當(dāng)引用失效時(shí),引用計(jì)數(shù)器就減 1。只要對象 A 的引用計(jì)數(shù)器的值為 0,則對象 A 就不可能再被使用。
缺點(diǎn):無法處理循環(huán)互相引用
標(biāo)記-清除算法 (Mark-Sweep)
標(biāo)記階段和清除階段
在標(biāo)記階段首先通過根節(jié)點(diǎn),標(biāo)記所有從根節(jié)點(diǎn)開始的較大對象
未被標(biāo)記的對象就是未被引用的垃圾對象
在清除階段,清除所有未被標(biāo)記的對象。
缺點(diǎn):存在大量的空間碎片,回收后的空間是不連續(xù)的
復(fù)制算法 (Copying)
將現(xiàn)有的內(nèi)存空間分為兩快,每次只使用其中一塊
在垃圾回收時(shí)將正在使用的內(nèi)存中的存活對象復(fù)制到未被使用的內(nèi)存塊中,之后,清除正在使用的內(nèi)存塊中的所有對象,交換兩個(gè)內(nèi)存的角色,完成回收。
優(yōu)點(diǎn):真正需要垃圾回收的時(shí)刻,復(fù)制算法的效率是很高的
確保回收后的內(nèi)存空間是沒有碎片的
缺點(diǎn):將系統(tǒng)內(nèi)存折半
(高效的前提是建立在存活對象少,垃圾對象多)——>適用年輕代
Java 的新生代串行垃圾回收器中使用了復(fù)制算法的思想
新生代分為 eden 空間、from 空間、to 空間
from 和 to 空間也稱為 survivor 空間,即幸存者空間,用于存放未被回收的對象。
eden 空間中的存活對象會(huì)被復(fù)制到未使用的 survivor 空間中
正在使用的 survivor 空間 中的年輕對象也會(huì)被復(fù)制到 to 空間中
eden 空間和 from 空間中的剩余對象就是垃圾對象,可以直接清空
優(yōu)點(diǎn):改進(jìn)的復(fù)制算法既保證了空間的連續(xù)性,又避免了大量的內(nèi)存空間浪費(fèi)。
標(biāo)記-壓縮算法 ——>適用老年代
標(biāo)記——清除算法的優(yōu)化
從根節(jié)點(diǎn)開始對所有可達(dá)對象做一次標(biāo)記
是將所有的存活對象壓縮到內(nèi)存的一端,清理邊界外所有的空間
優(yōu)點(diǎn):避免了碎片的產(chǎn)生,又不需要兩塊相同的內(nèi)存空間,性價(jià)比比較高。
增量算法 (Incremental Collecting)
在垃圾回收過程中,應(yīng)用軟件將處于一種 CPU 消耗很高的狀態(tài)
程序所有的線程都會(huì)掛起,暫停一切正常的工作,等待垃圾回收的完成。
如果一次性將所有的垃圾進(jìn)行處理,需要造成系統(tǒng)長時(shí)間的停頓,
思想:讓垃圾收集線程和應(yīng)用程序線程交替執(zhí)行
優(yōu)點(diǎn):減少系統(tǒng)的停頓時(shí)間
缺點(diǎn):線程切換和上下文切換的消耗,使得垃圾回收總體成本上升,造成系統(tǒng)吞吐量下降
分代 (Generational Collecting)
思想:不同階段最優(yōu)的方式是使用合適的算法用于本階段的垃圾回收
將內(nèi)存區(qū)間根據(jù)對象的特點(diǎn)分成幾塊,根據(jù)每塊內(nèi)存區(qū)間的特點(diǎn),使用不同的回收算法,以提高垃圾回收的效率。
將所有的新建對象都放入稱為年輕代的內(nèi)存區(qū)域,年輕代的特點(diǎn)是對象會(huì)很快回收,因此,在年輕代就選擇效率較高的復(fù)制算法。
當(dāng)一個(gè)對象經(jīng)過幾次回收后依然存活,對象就會(huì)被放入稱為老生代的內(nèi)存空間,對老年代的回收使用標(biāo)記-壓縮算法,提高垃圾回收效率。
###從不同角度分析垃圾收集器,可以將其分為不同的類型。
1.按線程數(shù)分,可以分為串行垃圾回收器和并行垃圾回收器。
2.按照工作模式分,可以分為并發(fā)式垃圾回收器和獨(dú)占式垃圾回收器
3.按碎片處理方式可分為壓縮式垃圾回收器和非壓縮式垃圾回收器
4.按工作的內(nèi)存區(qū)間,又可分為新生代垃圾回收器和老年代垃圾回收器
###評價(jià)垃圾處理器的指標(biāo)
吞吐量:指在應(yīng)用程序的生命周期內(nèi),應(yīng)用程序所花費(fèi)的時(shí)間和系統(tǒng)總運(yùn)行時(shí)間的比值。
垃圾回收器負(fù)載:和吞吐量相反,垃圾回收器負(fù)載指來記回收器耗時(shí)與系統(tǒng)運(yùn)行總時(shí)間的比值。
停頓時(shí)間:指垃圾回收器正在運(yùn)行時(shí),應(yīng)用程序的暫停時(shí)間。
垃圾回收頻率:指垃圾回收器多長時(shí)間會(huì)運(yùn)行一次。
(通常增大堆空間可以有效降低垃圾回收發(fā)生的頻率,但是可能會(huì)增加回收產(chǎn)生的停頓時(shí)間。)
反應(yīng)時(shí)間:指當(dāng)一個(gè)對象被稱為垃圾后多長時(shí)間內(nèi),它所占據(jù)的內(nèi)存空間會(huì)被釋放。
堆分配:不同的垃圾回收器對堆內(nèi)存的分配方式可能是不同的。一個(gè)良好的垃圾收集器應(yīng)該有一個(gè)合理的堆內(nèi)存區(qū)間劃分。