標籤:safe argument 操作 java hand 相等 垃圾收集 外鏈 傳回值
java技術棧
1 java基礎:1.1 演算法
- 1.1 排序演算法:直接插入排序、希爾排序、冒泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序
- 1.2 二叉尋找樹、紅/黑樹狀結構、B樹、B+樹、LSM樹(分別有對應的應用,資料庫、HBase)
- 1.3 BitSet解決資料重複和是否存在等問題
1.2 基本
- 2.1 字串常量池的遷移
- 2.2 字串KMP演算法
- 2.3 equals和hashcode
-
1、equals方法用於比較對象的內容是否相等(覆蓋以後)
2、hashcode方法只有在集合中用到
3、當覆蓋了equals方法時,比較對象是否相等將通過覆蓋後的equals方法進行比較(判斷對象的內容是否相等)。
4、將對象放入到集合中時,首先判斷要放入對象的hashcode值與集合中的任意一個元素的hashcode值是否相等,如果不相等直接將該對象放入集合中。如果hashcode值相等,然後再通過equals方法判斷要放入對象與集合中的任意一個對象是否相等,如果equals判斷不相等,直接將該元素放入到集合中,否則不放入。
5、將元素放入集合的流程圖:
- 2.4 泛型、異常、反射
- 2.5 string的hash演算法
- 設計高效演算法往往需要使用Hash表,O(1)級的尋找速度是任何別的演算法無法比擬的。
所謂Hash,一般是一個整數,通過某種演算法,可以把一個字串"pack"成一個整數,這個數稱為Hash,當然,一個整數是無法對應一個字串的。
所以Hash函數是Hash表最核心的部分,對於一個Hash函數,評價其優劣的標準應為隨機性或離散性,即對任意一組標本,進入Hash表每一個單元(cell)之機率的平均程度,因為這個機率越平均,兩個字串計算出的Hash值相等hash collision的可能越小,資料在表中的分布就越平均,表的空間利用率就越高。
- 2.6 hash衝突的解決辦法:拉鏈法
-
拉鏈法
(1)拉鏈法解決衝突的方法
拉鏈法解決衝突的做法是:將所有關鍵字為同義字的結點連結在同一個單鏈表中。若選定的散列表長度為m,則可將散列表定義為一個由m個頭指標組成的指標數 組T[0..m-1]。凡是散列地址為i的結點,均插入到以T[i]為頭指標的單鏈表中。T中各分量的初值均應為空白指標。在拉鏈法中,裝填因子α可以大於 1,但一般均取α≤1。
【例】設有 m = 5 , H(K) = K mod 5 ,關鍵字值序例 5 , 21 , 17 , 9 , 15 , 36 , 41 , 24 ,按外鏈地址法所建立的雜湊表如所示:
(2)拉鏈法的優點
與開放定址法相比,拉鏈法有如下幾個優點:
①拉鏈法處理衝突簡單,且無堆積現象,即非同義字決不會發生衝突,因此平均尋找長度較短;
②由於拉鏈法中各鏈表上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況;
③開放定址法為減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鏈法中可取α≥1,且結點較大時,拉鏈法中增加的指標域可忽略不計,因此節省空間的;
④在用拉鏈法構造的散列表中,刪除結點的操作易於實現。只要簡單地刪去鏈表上相應的結點即可。而對開放地址法構造的散列表,刪除結點不能簡單地將被刪結 點的空間置為空白,否則將截斷在它之後填人散列表的同義字結點的尋找路徑。這是因為各種開放地址法中,空地址單元(即開放地址)都是尋找失敗的條件。因此在 用開放地址法處理衝突的散列表上執行刪除操作,只能在被刪結點上做刪除標記,而不能真正刪除結點。
(3)拉鏈法的缺點
拉鏈法的缺點是:指標需要額外的空間,故當結點規模較小時,開放定址法較為節省空間的,而若將節省的指標空間用來擴大散列表的規模,可使裝填因子變小,這又減少了開放定址法中的衝突,從而提高平均尋找速度。
- 2.7 foreach迴圈的原理
-
- 對於list編譯器會調用Iterable介面的 iterator方法來迴圈遍曆數組的元素,iterator方法中是調用Iterator介面的的 next()和hasNext()方法來做迴圈遍曆。java中有一個叫做迭代器模式的設計模式,這個其實就是對迭代器模式的一個實現。
- 對於數組,就是轉化為對數組中的每一個元素的循環參考
- 2.8 static、final、transient等關鍵字的作用
-
static 和final
static 靜態修飾關鍵字,可以修飾 變數,程式塊,類的方法;
當你定義一個static的變數的時候jvm會將將其分配在記憶體堆上,所有程式對它的引用都會指向這一個地址而不會重新分配記憶體;
修飾一個程式塊的時候(也就是直接將代碼寫在static{...}中)時候,虛擬機器就會優先載入靜態塊中代碼,這主要用於系統初始化;
當修飾一個類方法時候你就可以直接通過類來調用而不需要建立對象。
final 只能賦值一次;修飾變數、方法及類,
當你定義一個final變數時,jvm會將其分配到常量池中,程式不可改變其值;當你定義一個方法時,改方法在子類中將不能被重寫;當你修飾一個類時,該類不能被繼承。
static和final使用範圍:類、方法、變數。
2.區別和聯絡:
2.1.static 含義:靜態,被 static 修飾的方法和屬性只屬於類不屬於類的任何對象。
2.2.static 用法:
2.2.1.static 可以修飾【內部類】、方法和成員變數。
2.2.2.static【不可以修飾外部類】、【不可以修飾局部變數】(因為 static 本身就是定義為類層級的,所以局部層級的變數是不可以用 static 修飾的)。
2.3 final 含義:【只能賦值一次】的。
2.2.final 用法:
2.2.1.final 修飾屬性,表示屬性【只能賦值一次】,(1)基本類型:值不能被修改;(2)參考型別:引用不可以被修改該。
2.2.2.final 修飾方法,表示方法不可以重寫,但是可以被子類訪問(如果方法不是 private 類型話)。
2.2.2.final 修飾類,表示類不可以被繼承。
3.聯合使用 static final
3.1.適用範圍:
3.1.2.兩者範圍的交集,所以只能修飾:成員變數、方法、內部類。
3.2.含義:也是二者交集:
3.2.1.方法:屬於類的方法且不可以被重寫。
3.2.2.成員變數:屬於類的變數且只能賦值一次。
3.2.3.內部類:屬於外部類,且不能被繼承
transient
類型修飾符,只能用來修飾欄位,如果用transient聲明一個執行個體變數,當Object Storage Service時,它的值不需要維持。換句話來說就是,用transient關鍵字標記的成員變數不參與序列化過程。
- 2.9 volatile關鍵字的底層實現原理
-
volatile
volatile也是變數修飾符,只能用來修飾變數。volatile修飾的成員變數在每次被線程訪問時,都強迫從共用記憶體中重讀該成員變數的值。而且,當成員變數發生變化時,強迫線程將變化值回寫到共用記憶體。這樣在任何時刻,兩個不同的線程總是看到某個成員變數的同一個值。
在此解釋一下Java的記憶體機制:
Java使用一個主記憶體來儲存變數當前值,而每個線程則有其獨立的工作記憶體。線程訪問變數的時候會將變數的值拷貝到自己的工作記憶體中,這樣,當線程對自己工作記憶體中的變數進行操作之後,就造成了工作記憶體中的變數拷貝的值與主記憶體中的變數值不同。
Java語言規範中指出:為了獲得最佳速度,允許線程儲存共用成員變數的私人拷貝,而且只當線程進入或者離開同步代碼塊時才與共用成員變數的原始值對比。
這樣當多個線程同時與某個對象互動時,就必須要注意到要讓線程及時的得到共用成員變數的變化。
而volatile關鍵字就是提示VM:對於這個成員變數不能儲存它的私人拷貝,而應直接與共用成員變數互動。
使用建議:在兩個或者更多的線程訪問的成員變數上使用volatile。當要訪問的變數已在synchronized代碼塊中,或者為常量時,不必使用。
由於使用volatile屏蔽掉了VM中必要的代碼最佳化,所以在效率上比較低,因此一定在必要時才使用此關鍵字。
- 2.10 Collections.sort方法使用的是哪種排序方法
- 2.11 Future介面,常見的線程池中的FutureTask實現等
- 2.12 string的intern方法的內部細節,jdk1.6和jdk1.7的變化以及內部cpp代碼StringTable的實現
1.3 設計模式
- 單例模式
- 原廠模式
- 裝飾者模式
- 觀察者設計模式
- ThreadLocal設計模式
- 。。。
1.4 Regex
- 4.1 擷取的群組和非擷取的群組
- http://www.360doc.com/content/12/0123/05/820209_181153675.shtml
- 4.2 貪婪,勉強,獨佔模式
-
Regex中匹配的三種量詞:貪婪(Greedy)、勉強(Reluctant)、獨佔(Possessive)
貪婪 非貪婪(?) 獨佔(+)
X? X?? X?+
X* X*? X*+
X+ X+? X++
X{n} X{n}? X{n}+
X{n,} X{n,}? X{n,}+
X{n,m} X{n,m}? X{n,m}+
Greedy:貪婪
匹配最長。在貪婪量詞模式下,Regex會儘可能長地去匹配符合規則的字串,且會回溯。
Reluctant :非貪婪
匹配最短。在非貪婪量詞模式下,Regex會匹配儘可能短的字串。
Possessive :獨佔
同貪婪一樣匹配最長。不過在獨佔量詞模式下,Regex儘可能長地去匹配字串,一旦匹配不成功就會結束匹配而不會回溯。
1.5 java記憶體模型以及記憶體回收演算法
-
5.1 類載入機制,也就是雙親委派模型
-
5.2 java記憶體配置模型(預設HotSpot)
線程共用的:堆區、永久區 線程獨享的:虛擬機器棧、本地方法棧、程式計數器
-
5.3 記憶體配置機制:年輕代(Eden區、兩個Survivor區)、年老代、永久代以及他們的分配過程
-
5.4 強引用、軟引用、弱引用、虛引用與GC
-
5.5 happens-before規則
-
5.6 指令重排序、記憶體柵欄
-
5.7 Java 8的記憶體分代改進
-
5.8 記憶體回收演算法:
標記-清除(不足之處:效率不高、記憶體片段)
複製演算法(解決了上述問題,但是記憶體只能使用一半,針對大部分對象存活時間短的情境,引出了一個預設的8:1:1的改進,缺點是仍然需要藉助外界來解決可能承載不下的問題)
標記整理
-
5.8 常用垃圾收集器:
新生代:Serial收集器、ParNew收集器、Parallel Scavenge 收集器
老年代:Serial Old收集器、Parallel Old收集器、CMS(Concurrent Mark Sweep)收集器、 G1 收集器(跨新生代和老年代)
-
5.9 常用gc的參數:-Xmn、-Xms、-Xmx、-XX:MaxPermSize、-XX:SurvivorRatio、-XX:-PrintGCDetails
-
5.10 常用工具: jps、jstat、jmap、jstack、圖形工具jConsole、Visual VM、MAT
1.6 鎖以及並發容器的源碼
- 6.1 synchronized和volatile理解
- 6.2 Unsafe類的原理,使用它來實現CAS。因此誕生了AtomicInteger系列等
- 6.3 CAS可能產生的ABA問題的解決,如加入修改次數、版本號碼
- 6.4 同步器AQS的實現原理
- 6.5 獨佔鎖、共用鎖定;可重新進入的獨佔鎖ReentrantLock、共用鎖定 實現原理
- 6.6 公平鎖和非公平鎖
- 6.7 讀寫鎖 ReentrantReadWriteLock的實現原理
- 6.8 LockSupport工具
- 6.9 Condition介面及其實現原理
- 6.10 HashMap、HashSet、ArrayList、LinkedList、HashTable、ConcurrentHashMap、TreeMap的實現原理
- 6.11 HashMap的並發問題
- 6.12 ConcurrentLinkedQueue的實現原理
- 6.13 Fork/Join架構
- 6.14 CountDownLatch和CyclicBarrier
1.7 線程池源碼
2 web方面:2.1 SpringMVC的架構設計
- 1.1 servlet開發存在的問題:映射問題、參數擷取問題、格式化轉換問題、傳回值處理問題、視圖渲染問題
- 1.2 SpringMVC為解決上述問題開發的幾大組件及介面:HandlerMapping、HandlerAdapter、HandlerMethodArgumentResolver、HttpMessageConverter、Converter、GenericConverter、HandlerMethodReturnValueHandler、ViewResolver、MultipartResolver
- 1.3 DispatcherServlet、容器、組件三者之間的關係
- 1.4 敘述SpringMVC對請求的整體處理流程
- 1.5 SpringBoot
2.2 SpringAOP源碼
-
2.1 AOP的實現分類:編譯期、位元組碼載入前、位元組碼載入後三種時機來實現AOP
-
2.2 深刻理解其中的角色:AOP聯盟、aspectj、jboss AOP、Spring自身實現的AOP、Spring嵌入aspectj。特別是能用代碼區分後兩者
-
2.3 介面設計:
AOP聯盟定義的概念或介面:Pointcut(概念,沒有定義對應的介面)、Joinpoint、Advice、MethodInterceptor、MethodInvocation
SpringAOP針對上述Advice介面定義的介面及其實作類別:BeforeAdvice、AfterAdvice、MethodBeforeAdvice、AfterReturningAdvice;針對aspectj對上述介面的實現AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice、AspectJAfterAdvice。
SpringAOP定義的定義的AdvisorAdapter介面:將上述Advise轉化為MethodInterceptor
SpringAOP定義的Pointcut介面:含有兩個屬性ClassFilter(過濾類)、MethodMatcher(過濾方法)
SpringAOP定義的ExpressionPointcut介面:實現中會引入aspectj的pointcut運算式
SpringAOP定義的PointcutAdvisor介面(將上述Advice介面和Pointcut介面結合起來)
-
2.4 SpringAOP的調用流程
-
2.5 SpringAOP自己的實現方式(代表人物ProxyFactoryBean)和藉助aspectj實現方式區分
2.3 Spring事務體系源碼以及分散式交易Jotm Atomikos源碼實現
- 3.1 jdbc事務存在的問題
- 3.2 Hibernate對事務的改進
- 3.3 針對各種各樣的事務,Spring如何定義事務體系的介面,以及如何融合jdbc事務和Hibernate事務的
- 3.4 三種事務模型包含的角色以及各自的職責
- 3.5 事務代碼也業務代碼分離的實現(AOP+ThreadLocal來實現)
- 3.6 Spring事務攔截器TransactionInterceptor全景
- 3.7 X/Open DTP模型,兩階段交易認可,JTA介面定義
- 3.8 Jotm、Atomikos的實現原理
- 3.9 事務的傳播屬性
- 3.10 PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED的實現原理以及區別
- 3.11 事物的掛起和恢複的原理
2.4 資料庫隔離等級
- 4.1 Read uncommitted:讀未提交
- 4.2 Read committed : 讀已提交
- 4.3 Repeatable read:可重複讀
- 4.4 Serializable :序列化
2.5 資料庫
-
5.1 資料庫效能的最佳化
-
5.2 深入理解mysql的Record Locks、Gap Locks、Next-Key Locks
例如下面的在什麼情況下會出現死結:
start transaction; DELETE FROM t WHERE id =6; INSERT INTO t VALUES(6); commit;
-
5.3 insert into select語句的加鎖情況
-
5.4 事務的ACID特性概念
-
5.5 innodb的MVCC理解
-
5.6 undo redo binlog
- 1 undo redo 都可以實現持久化,他們的流程是什嗎?為什麼選用redo來做持久化?
- 2 undo、redo結合起來實現原子性和持久化,為什麼undo log要先於redo log持久化?
- 3 undo為什麼要依賴redo?
- 4 日誌內容可以是物理日誌,也可以是邏輯日誌?他們各自的優點和缺點是?
- 5 redo log最終採用的是物理日誌加邏輯日誌,物理到page,page內邏輯。還存在什麼問題?怎麼解決?Double Write
- 6 undo log為什麼不採用物理日誌而採用邏輯日誌?
- 7 為什麼要引入Checkpoint?
- 8 引入Checkpoint後為了保證一致性需要阻塞使用者操作一段時間,怎麼解決這個問題?(這個問題還是很有普遍性的,redis、ZooKeeper都有類似的情況以及不同的應對策略)又有了同步Checkpoint和非同步Checkpoint
- 9 開啟binlog的情況下,事務內部2PC的一般過程(含有2次持久化,redo log和binlog的持久化)
- 10 解釋上述過程,為什麼binlog的持久化要在redo log之後,在儲存引擎commit之前?
- 11 為什麼要保持事務之間寫入binlog和執行儲存引擎commit操作的順序性?(即先寫入binlog日誌的事務一定先commit)
- 12 為了保證上述順序性,之前的辦法是加鎖prepare_commit_mutex,但是這極大的降低了事務的效率,怎麼來實現binlog的group commit?
- 13 怎麼將redo log的持久化也實現group commit?至此事務內部2PC的過程,2次持久化的操作都可以group commit了,極大提高了效率
2.6 ORM架構: mybatis、Hibernate
- 6.1 最原始的jdbc->Spring的JdbcTemplate->hibernate->JPA->SpringDataJPA的演化之路
java技術棧