JDK和JRE有什麼區別?
簡單來說,JDK是面向開發人員使用的SDK開發環境,包含了軟件開發包,函數庫,編譯程式等等,JDK包含了JRE,JRE是Java執行環境,如果只需要執行Java程式,那麼安裝JRE就可以了。而JRE中包含了JVM,它是Java虛擬機器,當Java編譯器編譯Java程式時,生成的是與平臺無關的位元組碼檔案,這些位元組碼只面向JVM,不同環境的JVM都是不同的,但他們都提供了相同的介面。這就是Java語言的跨平臺原理:一次編譯,多處執行。
==和equals的區別是什麼?
兩個物件的hashCode相同,則equals()也一定爲true,對嗎?
不對!"通話"和"重地"兩個字串的hashCode一樣,但顯然equals比較爲false.
final在java中有什麼作用?
final作爲Java中的關鍵字可以用於三個地方,用於修飾類、類屬性和類方法。
java中的Math.round(-1.5)等於多少?
答案是-1;Math的round方法是四捨五入,如果參數是負數,則取大的整數,Math.round(-1.5)=-1,如果是Math.round(1.5)則結果爲2
String屬於基礎的數據型別嗎?
不屬於,String不是基本數據型別,而是一個類。
Java八大基本數據型別:
java中操作字串都有哪些類?他們之間有什麼區別?
String str=「i」與String str=new String(「i」)一樣嗎?
不一樣。
如何將字串反轉?
String類的常用方法都有哪些?
抽象類必須要有抽象方法嗎?
不必須:
普通類和抽象類有哪些區別?
抽象類能使用final修飾嗎?
抽象類就是要子類繼承後來實現內部方法的,但final修飾的類是不能再被繼承和修改的,所以不能。
介面和抽象類有什麼區別?
知識點:
如果是Java 7,那麼介面中可以包含的內容有:
1. 常數
2. 抽象方法
如果是Java 8,還可以額外包含有:
3. 預設方法
4. 靜態方法
如果是Java 9,還可以額外包含有:
5. 私有方法
注意:介面中不能有變數和構造方法
java中的IO流分爲幾種?
BIO、NIO、AIO有什麼區別?
舉例講解:有一排水壺在燒開水
Files的常用方法有哪些?
java容器都有哪些?
Collection介面下的List、Set、Queue和獨立的Map
Collection和Collections有什麼區別
List、Set、Map之間有什麼區別?
HaspMap和HashTable有什麼區別?
如何決定使用HashMap還是TreeMap?
TreeMap<K,V>
的Key值是要求實現java.lang.Comparable
,所以迭代的時候TreeMap預設是按照Key值升序排序的;TreeMap的實現是基於紅黑樹結構。適用於按自然順序或自定義順序遍歷鍵(key)。HashMap<K,V>
的Key值實現雜湊hashCode()
,分佈是雜湊的、均勻的,不支援排序;數據結構主要是桶(陣列),鏈表或紅黑樹。適用於在Map中插入、刪除和定位元素。說一說HashMap的實現原理
說一說HashSet的實現原理
ArrayList和LinkedList的區別是什麼?
ArraryList(陣列結構):查詢快,增刪慢
LinkedList(鏈表結構):查詢慢,增刪快
執行緒安全:都是不同步的,都不保證執行緒安全
底層數據結構:ArrayList底層使用的是Object陣列,LinkedList底層使用雙向回圈鏈表數據結構
插入和刪除是否受元素位置影響:
是否支援快速隨機存取:LinkedList不支援,ArrayList實現了RandmoAccess介面,所以有隨機存取的功能,快速存取就是通過元素的序號快速獲取元素,對應get(int index)方法
記憶體佔用空間:ArrayList記憶體空間浪費主要體現在list列表的結尾都會預留一定的空間容量,而LinkedList的空間花費體現在每一個元素都需要消耗比ArrayList更多的空間(因爲要存放直接後繼和間接前驅以及數據)
如何實現陣列和List之間的轉換?
ArrayList和Vector的區別是什麼?
Array和ArrayList有何區別?
在Queue中poll()和remove()有什麼區別?
當佇列爲空時,remove會拋異常,poll返回null;
哪些集合類是執行緒安全的?
Vector:就比Arraylist多了個同步化機制 機製(執行緒安全)。
Hashtable:就比Hashmap多了個執行緒安全。
ConcurrentHashMap:是一種高效但是執行緒安全的集合。
Stack:棧,也是執行緒安全的,繼承於Vector。
迭代器iterator是什麼?
Iterator怎麼使用?有什麼特點?
Iterator和ListIterator有什麼區別?
怎麼確保一個集合不能被修改?
我們可以採用Collections包下的unmodifiableMap方法,通過這個方法返回的map,是不可以修改的。他會報 java.lang.UnsupportedOperationException錯。
同理:Collections包也提供了對list和set集合的方法。
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)。。。。。。
並行和併發有什麼區別?序列又是什麼?
執行緒和進程的區別?
守護執行緒是什麼?
守護執行緒擁有自動結束自己生命週期的特性,而非守護執行緒不具備這個特點。JVM 中的垃圾回收執行緒就是典型的守護執行緒。守護執行緒經常被用來執行一些後臺任務,但是呢,你又希望在程式退出時,或者說 JVM 退出時,執行緒能夠自動關閉,此時,守護執行緒是你的首選。
建立執行緒有哪幾種方式?
繼承Thread類建立執行緒類
通過Runnable介面建立執行緒類
實現Callable介面
@Test
public void test() throws ExecutionException, InterruptedException {
CallableDemoTest callableDemoTest = new CallableDemoTest();
FutureTask futureTask = new FutureTask(callableDemoTest);
Thread thread = new Thread(futureTask);
thread.start();
//獲取返回值
futureTask.get();
}
執行緒池
說一下runnable()和callable有什麼區別?
執行緒有哪些狀態?
sleep()和wait有什麼區別?
sleep() 方法是執行緒類(Thread)的靜態方法,使呼叫執行緒進入睡眠狀態,休眠結束後執行緒進入就緒狀態 wait()是Object類的方法,當執行緒執行到wait方法,進入到和該物件相關的等待池,同時釋放物件的機鎖(使得其他執行緒能夠存取),通過notify,notifyAll方法喚醒執行緒。
sleep() 和 wait() 的區別就是 呼叫sleep方法的執行緒不會釋放物件鎖,而呼叫wait() 方法會釋放物件鎖。因爲一個類中的靜態資源在類class被java虛擬機器載入時就已經被初始化了,而非靜態資源要在物件範例化的時候纔會被初始化。sleep()方法是靜態的,只依賴於類,不依賴於物件,而鎖是物件鎖,所以不能改變鎖
notify()和notifyAll()有什麼區別?
1.先說兩個概念:鎖池,等待池
2.然後再來說notify和notifyAll的區別
執行緒的run()和start()有什麼區別?
建立執行緒池有哪幾種方式?
執行緒池都有哪些狀態?
執行緒池的5種狀態:
執行緒池中submit()和execute方法有什麼區別?
兩個方法都可以向執行緒池提交任務
在Java程式中怎麼保證多執行緒的執行安全?
執行緒的安全性問題體現在:
導致原因:
解決方法:
synchronized和volatile的區別是什麼?
作用:
區別:
synchronized和Lock有什麼區別?
兩者區別:
1.首先synchronized是java內建關鍵字,在jvm層面,Lock是個java類;
2.synchronized無法判斷是否獲取鎖的狀態,Lock可以判斷是否獲取到鎖;
3.synchronized會自動釋放鎖(a 執行緒執行完同步程式碼會釋放鎖 ;b 執行緒執行過程中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),否則容易造成執行緒死鎖;
4.用synchronized關鍵字的兩個執行緒1和執行緒2,如果當前執行緒1獲得鎖,執行緒2執行緒等待。如果執行緒1阻塞,執行緒2則會一直等待下去,而Lock鎖就不一定會等待下去,如果嘗試獲取不到鎖,執行緒可以不用一直等待就結束了;
5.synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(兩者皆可)
6.Lock鎖適合大量同步的程式碼的同步問題,synchronized鎖適合程式碼少量的同步問題。
爲什麼要使用spring?
spring 是一個開源的輕量級 JavaBean 容器框架。使用 JavaBean 代替 EJB ,並提供了豐富的企業應用功能,降低應用開發的複雜性。
解釋一下什麼是AOP?
使用AOP技術,可以將一些系統性相關的程式設計工作,獨立提取出來,獨立實現,然後通過切面切入進系統。從而避免了在業務邏輯的程式碼中混入很多的系統相關的邏輯——比如許可權管理,事物管理,日誌記錄等等。這些系統性的程式設計工作都可以獨立編碼實現,然後通過AOP技術切入進系統即可。從而達到了 將不同的關注點分離出來的效果。
解釋一下什麼是IOC?
IoC就是Inversion of Control,控制反轉。在Java開發中,IoC意味着將你設計好的類交給系統去控制,而不是在你的類內部控制。這稱爲控制反轉。就是把原本你自己製造,使用的物件,現在交由別人製造,而通過建構函式,setter方法或方法(這裏指使用這個物件的方法)參數的方式傳給你,由你使用。
Spring有哪些主要模組?
Spring常用的注入方式有哪些?
常用的注入方式主要有三種:構造方法注入,setter注入,基於註解的注入。
Spring中的Bean是執行緒安全的嗎?
Spring容器中的Bean是否執行緒安全,容器本身並沒有提供Bean的執行緒安全策略,因此可以說Spring容器中的Bean本身不具備執行緒安全的特性,但是具體還是要結合具體scope的Bean去研究。
對於原型Bean,每次建立一個新物件,也就是執行緒之間並不存在Bean共用,自然是不會有執行緒安全的問題。
對於單例Bean,所有執行緒都共用一個單例範例Bean,因此是存在資源的競爭。
如果單例Bean,是一個無狀態Bean,也就是執行緒中的操作不會對Bean的成員執行查詢以外的操作,那麼這個單例Bean是執行緒安全的。比如Spring mvc 的 Controller、Service、Dao等,這些Bean大多是無狀態的,只關注於方法本身。
對於有狀態的bean,Spring官方提供的bean,一般提供了通過ThreadLocal去解決執行緒安全的方法,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。
注: Spring容器本身並沒有提供執行緒安全的策略,因此是否執行緒安全完全取決於Bean本身的特性。
Spring支援幾種bean的作用域?
1、singleton:單例,預設作用域。
2、prototype:原型,每次建立一個新物件。
3、request:請求,每次Http請求建立一個新物件,適用於WebApplicationContext環境下。
4、session:對談,同一個對談共用一個範例,不同對談使用不用的範例。
5、global-session:全域性對談,所有對談共用一個範例。
Spring自動裝配bean有哪些方式?
Spring事務實現方式有哪些?
說一下Spring的事務隔離?
說一下SpringMVC執行流程?
SpringMVC有哪些元件?
@RequestMapping的作用是什麼?
是一個用來處理請求地址對映的註解,可用於類或者方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作爲父路徑。
@Autowired的作用是什麼?
@Autowired 是一個註釋,它可以對類成員變數、方法及建構函式進行標註,讓 spring 完成 bean 自動裝配的工作。
@Autowired 預設是按照類去匹配,配合 @Qualifier 指定按照名稱去裝配 bean。
mybatis中#{}和${}的區別是什麼?
mybatis有幾種分頁模式?
陣列分頁:進行數據庫查詢操作時,獲取到數據庫中所有滿足條件的記錄,儲存在應用的臨時陣列中,再通過List的subList方法,獲取到滿足條件的所有記錄。
藉助sql語句進行分頁:通過sql語句實現分頁也是非常簡單的,只是需要改變我們查詢的語句就能實現了,即在sql語句後面新增limit分頁語句。
RowBounds實現分頁:通過RowBounds實現分頁和通過陣列方式分頁原理差不多,都是一次獲取所有符合條件的數據,然後在記憶體中對大數據進行操作,實現分頁效果。只是陣列分頁需要我們自己去實現分頁邏輯,這裏更加簡化而已。
存在問題:一次性從數據庫獲取的數據可能會很多,對記憶體的消耗很大,可能導師效能變差,甚至引發記憶體溢位。
適用場景:在數據量很大的情況下,建議還是適用攔截器實現分頁效果。RowBounds建議在數據量相對較小的情況下使用。
攔截器分頁:自定義攔截器實現了攔截所有以ByPage結尾的查詢語句,並且利用獲取到的分頁相關參數統一在sql語句後面加上limit分頁的相關語句,一勞永逸。不再需要在每個語句中單獨去設定分頁相關的參數了。。
RowBounds是一次性查詢全部結果嗎?爲什麼?
RowBounds 表面是在「所有」數據中檢索數據,其實並非是一次性查詢出所有數據,因爲 MyBatis 是對 jdbc 的封裝,在 jdbc 驅動中有一個 Fetch Size 的設定,它規定了每次最多從數據庫查詢多少條數據,假如你要查詢更多數據,它會在你執行 next()的時候,去查詢更多的數據。就好比你去自動取款機取 10000 元,但取款機每次最多能取 2500 元,所以你要取 4 次才能 纔能把錢取完。只是對於 jdbc 來說,當你呼叫 next()的時候會自動幫你完成查詢工作。這樣做的好處可以有效的防止記憶體溢位。
mybatis邏輯分頁和物理分頁的區別是什麼?
邏輯分頁是一次性查詢很多數據,然後再在結果中檢索分頁的數據。這樣做弊端是需要消耗大量的記憶體、有記憶體溢位的風險、對數據庫壓力較大。
物理分頁是從數據庫查詢指定條數的數據,彌補了一次性全部查出的所有數據的種種缺點,比如需要大量的記憶體,對數據庫查詢壓力較大等問題。
mybatis是否支援延遲載入?延遲載入的原理是什麼?
MyBatis 支援延遲載入,設定 lazyLoadingEnabled=true 即可。
延遲載入的原理的是呼叫的時候觸發載入,而不是在初始化的時候就載入資訊。比如呼叫 a. getB(). getName(),這個時候發現 a. getB() 的值爲 null,此時會單獨觸發事先儲存好的關聯 B 物件的 SQL,先查詢出來 B,然後再呼叫 a. setB(b),而這時候再呼叫 a. getB(). getName() 就有值了,這就是延遲載入的基本原理。
說一下mybatis的一級快取和二級快取?
一級快取:基於 PerpetualCache 的 HashMap 本地快取,它的宣告週期是和 SQLSession 一致的,有多個 SQLSession 或者分佈式的環境中數據庫操作,可能會出現髒數據。當 Session flush 或 close 之後,該 Session 中的所有 Cache 就將清空,預設一級快取是開啓的。
二級快取:也是基於 PerpetualCache 的 HashMap 本地快取,不同在於其儲存作用域爲 Mapper 級別的,如果多個SQLSession之間需要共用快取,則需要使用到二級快取,並且二級快取可自定義儲存源,如 Ehcache。預設不開啓二級快取,要開啓二級快取,使用二級快取屬性類需要實現 Serializable 序列化介面(可用來儲存物件的狀態)。
開啓二級快取數據查詢流程:二級快取 -> 一級快取 -> 數據庫。
快取更新機制 機製:當某一個作用域(一級快取 Session/二級快取 Mapper)進行了C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear。
mybatis和hibernate的區別有哪些?
靈活性:MyBatis 更加靈活,自己可以寫 SQL 語句,使用起來比較方便。
可移植性:MyBatis 有很多自己寫的 SQL,因爲每個數據庫的 SQL 可以不相同,所以可移植性比較差。
學習和使用門檻:MyBatis 入門比較簡單,使用門檻也更低。
二級快取:hibernate 擁有更好的二級快取,它的二級快取可以自行更換爲第三方的二級快取。
mybatis有哪些執行器(Executor)?
MyBatis 有三種基本的Executor執行器:
SimpleExecutor:每執行一次 update 或 select 就開啓一個 Statement 物件,用完立刻關閉 Statement 物件;
ReuseExecutor:執行 update 或 select,以 SQL 作爲 key 查詢 Statement 物件,存在就使用,不存在就建立,用完後不關閉 Statement 物件,而是放置於 Map 內供下一次使用。簡言之,就是重複使用 Statement 物件;
BatchExecutor:執行 update(沒有 select,jdbc 批次處理不支援 select),將所有 SQL 都新增到批次處理中(addBatch()),等待統一執行(executeBatch()),它快取了多個 Statement 物件,每個 Statement 物件都是 addBatch()完畢後,等待逐一執行 executeBatch()批次處理,與 jdbc 批次處理相同。
mybatis分頁外掛的實現原理是什麼?
分頁外掛的基本原理是使用 MyBatis 提供的外掛介面,實現自定義外掛,在外掛的攔截方法內攔截待執行的 SQL,然後重寫 SQL,根據 dialect 方言,新增對應的物理分頁語句和物理分頁參數。
mybatis如何編寫一個自定義外掛?
自定義外掛實現原理
MyBatis 自定義外掛針對 MyBatis 四大物件(Executor、StatementHandler、ParameterHandler、ResultSetHandler)進行攔截:
Executor:攔截內部執行器,它負責呼叫 StatementHandler 操作數據庫,並把結果集通過 ResultSetHandler 進行自動對映,另外它還處理了二級快取的操作;
StatementHandler:攔截 SQL 語法構建的處理,它是 MyBatis 直接和數據庫執行 SQL 指令碼的物件,另外它也實現了 MyBatis 的一級快取;
ParameterHandler:攔截參數的處理;
ResultSetHandler:攔截結果集的處理。
自定義外掛實現關鍵
說一下JVM的主要組成部分及其作用
類載入器(ClassLoader)
執行時數據區(Runtime Data Area)
執行引擎(Execution Engine)
本地庫介面(Native Interface)
元件的作用: 首先通過類載入器(ClassLoader)會把 Java 程式碼轉換成位元組碼,執行時數據區(Runtime Data Area)再把位元組碼載入到記憶體中,而位元組碼檔案只是 JVM 的一套指令集規範,並不能直接交給底層操作系統去執行,因此需要特定的命令解析器執行引擎(Execution Engine),將位元組碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程中需要呼叫其他語言的本地庫介面(Native Interface)來實現整個程式的功能。
說一下JVM執行時數據區
不同虛擬機器的執行時數據區可能略微有所不同,但都會遵從 Java 虛擬機器規範, Java 虛擬機器規範規定的區域分爲以下 5 個部分:
程式計數器(Program Counter Register):當前執行緒所執行的位元組碼的行號指示器,位元組碼解析器的工作是通過改變這個計數器的值,來選取下一條需要執行的位元組碼指令,分支、回圈、跳轉、例外處理、執行緒恢復等基礎功能,都需要依賴這個計數器來完成;
Java 虛擬機器棧(Java Virtual Machine Stacks):用於儲存區域性變數表、運算元棧、動態鏈接、方法出口等資訊;
本地方法棧(Native Method Stack):與虛擬機器棧的作用是一樣的,只不過虛擬機器棧是服務 Java 方法的,而本地方法棧是爲虛擬機器呼叫 Native 方法服務的;
Java 堆(Java Heap):Java 虛擬機器中記憶體最大的一塊,是被所有執行緒共用的,幾乎所有的物件範例都在這裏分配記憶體;
方法區(Methed Area):用於儲存已被虛擬機器載入的類資訊、常數、靜態變數、即時編譯後的程式碼等數據。
說一下堆疊區別
功能方面:堆是用來存放物件的,棧是用來執行程式的。
共用性:堆是執行緒共用的,棧是執行緒私有的。
空間大小:堆大小遠遠大於棧。
佇列和棧是什麼,有什麼區別?
佇列和棧都是被用來預儲存數據的。
佇列允許先進先出檢索元素,但也有例外的情況,Deque 介面允許從兩端檢索元素。
棧和佇列很相似,但它執行對元素進行後進先出進行檢索。
什麼是雙親委派模型?
當需要載入一個類的時候,子類載入器並不會馬上去載入,而是依次去請求父類別載入器載入,一直往上請求到最高類載入器:啓動類載入器。當啓動類載入器載入不了的時候,依次往下讓子類載入器進行載入。當達到最底下的時候,如果還是載入不到該類,就會出現ClassNotFound的情況。
好處:保證了程式的安全性。例子:比如我們重新寫了一個String類,載入的時候並不會去載入到我們自己寫的String類,因爲當請求上到最高層的時候,啓動類載入器發現自己能夠載入String類,因此就不會載入到我們自己寫的String類了。
說一下類載入的執行過程?
類裝載分爲以下 5 個步驟:
載入:根據查詢路徑找到相應的 class 檔案然後匯入;
檢查:檢查載入的 class 檔案的正確性;
準備:給類中的靜態變數分配記憶體空間;
解析:虛擬機器將常數池中的符號參照替換成直接參照的過程。符號參照就理解爲一個標示,而在直接參照直接指向記憶體中的地址;
初始化:對靜態變數和靜態程式碼塊執行初始化工作。
怎麼判斷物件是否可以被回收?
一般有兩種方法來判斷:
參照計數器:爲每個物件建立一個參照計數,有物件參照時計數器 +1,參照被釋放時計數 -1,當計數器爲 0 時就可以被回收。它有一個缺點不能解決回圈參照的問題;
可達性分析:從 GC Roots 開始向下搜尋,搜尋所走過的路徑稱爲參照鏈。當一個物件到 GC Roots 沒有任何參照鏈相連時,則證明此物件是可以被回收的
java中都有哪些參照型別?
說一下JVM有哪些垃圾回收演算法?
常用的垃圾回收演算法有如下四種:標記-清除、複製、標記-整理和分代收集。
標記-清除演算法
從演算法的名稱上可以看出,這個演算法分爲兩部分,標記和清除。首先標記出所有需要被回收的物件,然後在標記完成後統一回收掉所有被標記的物件。
這個演算法簡單,但是有兩個缺點:一是標記和清除的效率不是很高;二是標記和清除後會產生很多的記憶體碎片,導致可用的記憶體空間不連續,當分配大物件的時候,沒有足夠的空間時不得不提前觸發一次垃圾回收。
複製演算法
這個演算法將可用的記憶體空間分爲大小相等的兩塊,每次只是用其中的一塊,當這一塊被用完的時候,就將還存活的物件複製到另一塊中,然後把原已使用過的那一塊記憶體空間一次回收掉。這個演算法常用於新生代的垃圾回收。
複製演算法解決了標記-清除演算法的效率問題,以空間換時間,但是當存活物件非常多的時候,複製操作效率將會變低,而且每次只能使用一半的記憶體空間,利用率不高。
標記-整理演算法
這個演算法分爲三部分:一是標記出所有需要被回收的物件;二是把所有存活的物件都向一端移動;三是把所有存活物件邊界以外的記憶體空間都回收掉。
標記-整理演算法解決了複製演算法多複製效率低、空間利用率低的問題,同時也解決了記憶體碎片的問題。
分代收集演算法
根據物件生存週期的不同將記憶體空間劃分爲不同的塊,然後對不同的塊使用不同的回收演算法。一般把Java堆分爲新生代和老年代,新生代中物件的存活週期短,只有少量存活的物件,所以可以使用複製演算法,而老年代中物件存活時間長,而且物件比較多,所以可以採用標記-清除和標記-整理演算法。
說一下JVM中有哪些垃圾回收器?
**新生代收集器:**Serial、ParNew、Parallel Scavenge
**老年代收集器:**Serial Old、CMS、Parallel Old
**堆記憶體垃圾收集器:**G1
Serial:最早的單執行緒序列垃圾回收器。
Serial Old:Serial 垃圾回收器的老年版本,同樣也是單執行緒的,可以作爲 CMS 垃圾回收器的備選預案。
ParNew:是 Serial 的多執行緒版本。 Parallel 和 ParNew 收集器類似是多執行緒的,但 Parallel 是吞吐量優先的收集器,可以犧牲等待時間換取系統的吞吐量。
Parallel Old 是 Parallel 老生代版本,Parallel 使用的是複製的記憶體回收演算法,Parallel Old 使用的是標記-整理的記憶體回收演算法。
CMS:一種以獲得最短停頓時間爲目標的收集器,非常適用 B/S 系統。
G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 以後的預設 GC 選項。
詳細介紹一下CMS垃圾回收器?
CMS是基於「標記——清除」演算法實現的,整個過程分爲4個步驟:
優點:併發收集、低停頓,oracle公司的一些官方文件中也稱之爲併發低停頓收集器(Concurrent Low Pause Collector)【一定要知道:停頓,停頓的是使用者執行緒】
缺點:
新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?
新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
新生代垃圾回收器一般採用的是複製演算法,複製演算法的優點是效率高,缺點是記憶體利用率低;老年代回收器一般採用的是標記-整理的演算法進行垃圾回收。
簡述一下分代垃圾回收器是怎麼工作的?
分代回收器有兩個分割區:老生代和新生代,新生代預設的空間佔比總空間的 1/3,老生代的預設佔比是 2/3。 新生代使用的是複製演算法,新生代裡有 3 個分割區:Eden、To Survivor、From Survivor,它們的預設佔比是 8:1:1,
它的執行流程如下:
把 Eden + From Survivor 存活的物件放入 To Survivor 區;
清空 Eden 和 From Survivor 分割區; From Survivor 和 To Survivor 分割區交換,From Survivor 變 To Survivor,To Survivor 變 From Survivor。
每次在 From Survivor 到 To Survivor 移動時都存活的物件,年齡就 +1,當年齡到達 15(預設設定是 15)時,升級爲老生代。大物件也會直接進入老生代。
老生代當空間佔用到達某個值之後就會觸發全域性垃圾收回,一般使用標記整理的執行演算法。
以上這些循環往復就構成了整個分代垃圾回收的整體執行流程。
說一下JVM調優的工具?
*Jconsole : jdk自帶,功能簡單,但是可以在系統有一定負荷的情況下使用。對垃圾回收演算法有很詳細的跟蹤。*
*JProfiler:商業軟體,需要付費。功能強大。*
*VisualVM:JDK自帶,功能強大,與JProfiler類似。推薦。*
常用的JVM調優參數都有哪些?
-Xms2g:初始化推大小爲 2g;
-Xmx2g:堆最大記憶體爲 2g;
-XX:NewRatio=4:設定年輕的和老年代的記憶體比例爲 1:4;
-XX:SurvivorRatio=8:設定新生代 Eden 和 Survivor 比例爲 8:2;
–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合;
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合;
-XX:+PrintGC:開啓列印 gc 資訊;
-XX:+PrintGCDetails:列印 gc 詳細資訊。
數據庫的三範式是什麼?
第一範式:強調的是列的原子性,即數據庫表的每一列都是不可分割的原子數據項。
第二範式:要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性。
第三範式:任何非主屬性不依賴於其它非主屬性
一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重新啓動 MySQL 數據庫,又插入了一條數據,此時 id 是幾?
表型別如果是 MyISAM ,那 id 就是 8。
表型別如果是 InnoDB,那 id 就是 6。
InnoDB 表只會把自增主鍵的最大 id 記錄在記憶體中,所以重新啓動之後會導致最大 id 丟失。
如何獲取當前數據庫版本?
使用 select version() 命令獲取當前 MySQL 數據庫版本。
說一下ACID是什麼?
1. Atomicity 原子性:是不可分割的最小操作單位,要麼同時成功,要麼同時失敗。
2. Consistency 一致性:事務操作前後,數據總量不變
3. Isolation 隔離性:多個事務之間。相互獨立。
4. Durability 永續性:當事務提交或回滾後,數據庫會持久化的儲存數據。
char和vachar的區別是什麼?
char(n) :固定長度型別,比如訂閱 char(10),當你輸入"abc"三個字元的時候,它們佔的空間還是 10 個位元組,其他 7 個是空位元組。
chat 優點:效率高;缺點:佔用空間;適用場景:儲存密碼的 md5 值,固定長度的,使用 char 非常合適。
varchar(n) :可變長度,儲存的值是每個值佔用的位元組再加上一個用來記錄其長度的位元組的長度。
所以,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適,二者使用需要權衡。
flioat和double的區別是什麼?
float 最多可以儲存 8 位的十進制數,並在記憶體中佔 4 位元組。
double 最可可以儲存 16 位的十進制數,並在記憶體中佔 8 位元組。
mysql的內連線和左右連線有什麼區別?
內連線關鍵字:inner join;左連線:left join;右連線:right join。
內連線是把匹配的關聯數據顯示出來;左連線是左邊的表全部顯示出來,右邊的表顯示出符合條件的數據;右連線正好相反
mysql索引是怎麼實現的?
索引是滿足某種特定查詢演算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查詢數據。
具體來說 MySQL 中的索引,不同的數據引擎實現有所不同,但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜尋效率,可以到達二分法的效能,找到數據區域之後就找到了完整的數據結構了,所有索引的效能也是更好的。
怎麼驗證mysql索引是否滿足需求?
使用 explain 檢視 SQL 是如何執行查詢語句的,從而分析你的索引是否滿足需求。
explain 語法:explain select * from table where type=1。
說一下數據庫的事務隔離?
* 概念:多個事務之間隔離的,相互獨立的。但是如果多個事務操作同一批數據,則會引發一些問題,設定不同的隔離級別就可以解決這些問題。
* 存在問題:
1. 髒讀:一個事務,讀取到另一個事務中沒有提交的數據
2. 不可重複讀(虛讀):在同一個事務中,兩次讀取到的數據不一樣。
3. 幻讀:一個事務操作(DML)數據表中所有記錄,另一個事務新增了一條數據,則第一個事務查詢不到自己的修改。
* 隔離級別:
1. read uncommitted:讀未提交
* 產生的問題:髒讀、不可重複讀、幻讀
2. read committed:讀已提交 (Oracle)
* 產生的問題:不可重複讀、幻讀
3. repeatable read:可重複讀 (MySQL預設)
* 產生的問題:幻讀
4. serializable:序列化
* 可以解決所有的問題
* 注意:隔離級別從小到大安全性越來越高,但是效率越來越低
* 數據庫查詢隔離級別:
* select @@tx_isolation;
* 數據庫設定隔離級別:
* set global transaction isolation level 級別字串;
說一下mysql常用引擎?
InnoDB 引擎:mysql 5.1 後預設的數據庫引擎,提供了對數據庫 acid 事務的支援,並且還提供了行級鎖和外來鍵的約束,它的設計的目標就是處理大數據容量的數據庫系統。MySQL 執行的時候,InnoDB 會在記憶體中建立緩衝池,用於緩衝數據和索引。但是該引擎是不支援全文搜尋,同時啓動也比較的慢,它是不會儲存表的行數的,所以當進行 select count(*) from table 指令的時候,需要進行掃描全表。由於鎖的粒度小,寫操作是不會鎖定全表的,所以在併發度較高的場景下使用會提升效率的。
MyIASM 引擎:不提供事務的支援,也不支援行級鎖和外來鍵。因此當執行插入和更新語句時,即執行寫操作的時候需要鎖定這個表,所以會導致效率會降低。不過和 InnoDB 不同的是,MyIASM 引擎是儲存了表的行數,於是當進行 select count(*) from table 語句時,可以直接的讀取已經儲存的值而不需要進行掃描全表。所以,如果表的讀操作遠遠多於寫操作時,並且不需要事務的支援的,可以將 MyIASM 作爲數據庫引擎的首選。
說一下mysql的行鎖和表鎖?
MyISAM 只支援表鎖,InnoDB 支援表鎖和行鎖,預設爲行鎖。
表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的概率最高,併發量最低。
行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖衝突的概率小,併發度最高。
說一下樂觀鎖和悲觀鎖?
樂觀鎖:每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
悲觀鎖:每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。
數據庫的樂觀鎖需要自己實現,在表裏面新增一個 version 欄位,每次修改成功值加 1,這樣每次修改的時候先對比一下,自己擁有的 version 和數據庫現在的 version 是否一致,如果不一致就不修改,這樣就實現了樂觀鎖。
mysql問題排查都有哪些手段?
使用 show processlist 命令檢視當前所有連線資訊。
使用 explain 命令查詢 SQL 語句執行計劃。
開啓慢查詢日誌,檢視慢查詢的 SQL。
如何做到mysql的效能調優?
爲搜尋欄位建立索引。
避免使用 select *,列出需要查詢的欄位。
垂直分割分表。
選擇正確的儲存引擎。
redis是什麼?都有哪些使用場景?
Redis 是一個使用 C 語言開發的快取記憶體數據庫。
Redis 使用場景:
redis爲什麼是單執行緒的?
因爲Redis是基於記憶體的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器記憶體的大小或者網路頻寬。既然單執行緒容易實現,而且CPU不會成爲瓶頸,那就順理成章地採用單執行緒的方案了。
什麼是快取穿透?怎麼解決?
快取穿透:指查詢一個一定不存在的數據,由於快取是不命中時需要從數據庫查詢,查不到數據則不寫入快取,這將導致這個不存在的數據每次請求都要到數據庫去查詢,造成快取穿透。
解決方案:最簡單粗暴的方法如果一個查詢返回的數據爲空(不管是數據不存在,還是系統故障),我們就把這個空結果進行快取,但它的過期時間會很短,最長不超過五分鐘。
redis支援的數據型別有哪些?
Redis 支援的數據型別:string(字串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。
redis支援的java用戶端都有哪些?
支援的 Java 用戶端有 Redisson、jedis、lettuce 等。
jedis和Redission有什麼區別?
jedis:提供了比較全面的 Redis 命令的支援。
Redisson:實現了分佈式和可延伸的 Java 數據結構,與 jedis 相比 Redisson 的功能相對簡單,不支援排序、事務、管道、分割區等 Redis 特性。
怎麼保證快取和數據庫數據的一致性?
合理設定快取的過期時間。
新增、更改、刪除數據庫操作時同步更新 Redis,可以使用事物機制 機製來保證數據的一致性。
redis持久化有幾種方式?
Redis 的持久化有兩種方式,或者說有兩種策略:
RDB(Redis Database):指定的時間間隔能對你的數據進行快照儲存。
AOF(Append Only File):每一個收到的寫命令都通過write函數追加到檔案中。
redis怎麼實現分佈式鎖?
Redis 分佈式鎖其實就是在系統裏面佔一個「坑」,其他程式也要佔「坑」的時候,佔用成功了就可以繼續執行,失敗了就只能放棄或稍後重試。
佔坑一般使用 setnx(set if not exists)指令,只允許被一個程式佔有,使用完呼叫 del 釋放鎖。
redis實現分佈式鎖有什麼缺陷?
Redis 分佈式鎖不能解決超時的問題,分佈式鎖有一個超時時間,程式的執行如果超出了鎖的超時時間就會出現問題。
redis如何做記憶體優化?
儘量使用 Redis 的雜湊表,把相關的資訊放到雜湊表裏面儲存,而不是把每個欄位單獨儲存,這樣可以有效的減少記憶體使用。比如將 Web 系統的使用者物件,應該放到雜湊表裏面再整體儲存到 Redis,而不是把使用者的姓名、年齡、密碼、郵箱等欄位分別設定 key 進行儲存。
redis淘汰策略有哪些?
volatile-lru:從已設定過期時間的數據集(server. db[i]. expires)中挑選最近最少使用的數據淘汰。
volatile-ttl:從已設定過期時間的數據集(server. db[i]. expires)中挑選將要過期的數據淘汰。
volatile-random:從已設定過期時間的數據集(server. db[i]. expires)中任意選擇數據淘汰。
allkeys-lru:從數據集(server. db[i]. dict)中挑選最近最少使用的數據淘汰。
allkeys-random:從數據集(server. db[i]. dict)中任意選擇數據淘汰。
no-enviction(驅逐):禁止驅逐數據。
redis常見的效能問題有哪些?該如何解決?
主伺服器寫記憶體快照,會阻塞主執行緒的工作,當快照比較大時對效能影響是非常大的,會間斷性暫停服務,所以主伺服器最好不要寫記憶體快照。
Redis 主從複製的效能問題,爲了主從複製的速度和連線的穩定性,主從庫最好在同一個區域網內。
RabbitMQ的使用場景有哪些?
搶購活動,削峯填谷,防止系統崩塌。
延遲資訊處理,比如 10 分鐘之後給下單未付款的使用者發送郵件提醒。
解耦系統,對於新增的功能可以單獨寫模組擴充套件,比如使用者確認評價之後,新增了給使用者返積分的功能,這個時候不用在業務程式碼裡新增新增積分的功能,只需要把新增積分的介面訂閱確認評價的訊息佇列即可,後面再新增任何功能只需要訂閱對應的訊息佇列即可。
RabbitMQ有哪些重要角色?
RabbitMQ 中重要的角色有:生產者、消費者和代理:
生產者:訊息的建立者,負責建立和推播數據到訊息伺服器;
消費者:訊息的接收方,用於處理數據和確認訊息;
代理:就是 RabbitMQ 本身,用於扮演「快遞」的角色,本身不生產訊息,只是扮演「快遞」的角色。
RabbitMQ有哪些重要的元件?
ConnectionFactory(連線管理器):應用程式與Rabbit之間建立連線的管理器,程式程式碼中使用。
Channel(通道):訊息推播使用的通道。
Exchange(交換器):用於接受、分配訊息。
Queue(佇列):用於儲存生產者的訊息。
RoutingKey(路由鍵):用於把生成者的數據分配到交換器上。
BindingKey(系結鍵):用於把交換器的訊息系結到佇列上。
RabbitMQ中vhost的作用是什麼?
vhost:每個 RabbitMQ 都能建立很多 vhost,我們稱之爲虛擬主機,每個虛擬主機其實都是 mini 版的RabbitMQ,它擁有自己的佇列,交換器和系結,擁有自己的許可權機制 機製。
RabbitMQ中的訊息是怎麼發送的?
首先用戶端必須連線到 RabbitMQ 伺服器才能 纔能發佈和消費訊息,用戶端和 rabbit server 之間會建立一個 tcp 連線,一旦 tcp 開啓並通過了認證(認證就是你發送給 rabbit 伺服器的使用者名稱和密碼),你的用戶端和 RabbitMQ 就建立了一條 amqp 通道(channel),通道是建立在「真實」 tcp 上的虛擬連線,amqp 命令都是通過通道發送出去的,每個通道都會有一個唯一的 id,不論是發佈訊息,訂閱佇列都是通過這個通道完成的。
RabbitMQ怎麼保證訊息的穩定性?
提供了事務的功能。
通過將 channel 設定爲 confirm(確認)模式
RabbitMQ怎麼避免訊息丟失?
把訊息持久化磁碟,保證伺服器重新啓動訊息不丟失。
每個叢集中至少有一個物理磁碟,保證訊息落入磁碟。
要保證訊息持久化成功的條件有哪些?
宣告佇列必須設定持久化 durable 設定爲 true.
訊息推播投遞模式必須設定持久化,deliveryMode 設定爲 2(持久)。
訊息已經到達持久化交換器。
訊息已經到達持久化佇列。
以上四個條件都滿足才能 纔能保證訊息持久化成功。
RabbitMQ持久化有什麼缺點?
持久化的缺點就是降低了伺服器的吞吐量,因爲使用的是磁碟而非記憶體儲存,從而降低了吞吐量。可儘量使用 ssd 硬碟來緩解吞吐量的問題。
RabbitMQ有幾種廣播型別?
direct(預設方式):最基礎最簡單的模式,發送方把訊息發送給訂閱方,如果有多個訂閱者,預設採取輪詢的方式進行訊息發送。
headers:與 direct 類似,只是效能很差,此型別幾乎用不到。
fanout:分發模式,把消費分發給所有訂閱者。
topic:匹配訂閱模式,使用正則匹配到訊息佇列,能匹配到的都能接收到。
RabbitMQ 怎麼實現延遲訊息佇列?
延遲佇列的實現有兩種方式:
通過訊息過期後進入死信交換器,再由交換器轉發到延遲消費佇列,實現延遲功能;
使用 RabbitMQ-delayed-message-exchange 外掛實現延遲功能。
RabbitMQ節點的型別有哪些?
磁碟節點:訊息會儲存到磁碟。
記憶體節點:訊息都儲存在記憶體中,重新啓動伺服器訊息丟失,效能高於磁碟型別。
RabbitMQ叢集搭建需要注意哪些問題?
各節點之間使用「–link」連線,此屬性不能忽略。
各節點使用的 erlang cookie 值必須相同,此值相當於「祕鑰」的功能,用於各節點的認證。
整個叢集中必須包含一個磁碟節點。
RabbitMQ每個節點是其他節點的完整拷貝嗎?爲什麼?
不是,原因有以下兩個:
儲存空間的考慮:如果每個節點都擁有所有佇列的完全拷貝,這樣新增節點不但沒有新增儲存空間,反而增加了更多的冗餘數據;
效能的考慮:如果每條訊息都需要完整拷貝到每一個叢集節點,那新增節點並沒有提升處理訊息的能力,最多是保持和單節點相同的效能甚至是更糟。
RabbitMQ叢集中唯一一個磁碟節點崩潰了會發生什麼情況?
如果唯一磁碟的磁碟節點崩潰了,不能進行以下操作:
不能建立佇列
不能建立交換器
不能建立系結
不能新增使用者
不能更改許可權
不能新增和刪除叢集節點
唯一磁碟節點崩潰了,叢集是可以保持執行的,但你不能更改任何東西。
RabbitMQ對叢集節點停止順序有要求嗎?
RabbitMQ 對叢集的停止的順序是有要求的,應該先關閉記憶體節點,最後再關閉磁碟節點。如果順序恰好相反的話,可能會造成訊息的丟失。
zookeeper 是什麼?
zookeeper 是一個分佈式的,開放原始碼的分佈式應用程式協調服務,是 google chubby 的開源實現,是 hadoop 和 hbase 的重要元件。它是一個爲分佈式應用提供一致性服務的軟體,提供的功能包括:設定維護、域名服務、分佈式同步、組服務等。
zookeeper 都有哪些功能?
叢集管理:監控節點存活狀態、執行請求等。
主節點選舉:主節點掛掉了之後可以從備用的節點開始新一輪選主,主節點選舉說的就是這個選舉的過程,使用 zookeeper 可以協助完成這個過程。
分佈式鎖:zookeeper 提供兩種鎖:獨佔鎖、共用鎖。獨佔鎖即一次只能有一個執行緒使用資源,共用鎖是讀鎖共用,讀寫互斥,即可以有多線執行緒同時讀同一個資源,如果要使用寫鎖也只能有一個執行緒使用。zookeeper可以對分佈式鎖進行控制。
命名服務:在分佈式系統中,通過使用命名服務,用戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等資訊。
zookeeper 有幾種部署模式?
ookeeper 有三種部署模式:
單機部署:一臺叢集上執行;
叢集部署:多臺叢集執行;
僞叢集部署:一臺叢集啓動多個 zookeeper 範例執行。
zookeeper 怎麼保證主從節點的狀態同步?
zookeeper 的核心是原子廣播,這個機制 機製保證了各個 server 之間的同步。實現這個機制 機製的協定叫做 zab 協定。 zab 協定有兩種模式,分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 server 具有相同的系統狀態。
叢集中爲什麼要有主節點?
在分佈式環境中,有些業務邏輯只需要叢集中的某一臺機器進行執行,其他的機器可以共用這個結果,這樣可以大大減少重複計算,提高效能,所以就需要主節點。
叢集中有 3 台伺服器,其中一個節點宕機,這個時候 zookeeper 還可以使用嗎?
可以繼續使用,單數伺服器只要沒超過一半的伺服器宕機就可以繼續使用。
說一下 zookeeper 的通知機制 機製?
用戶端端會對某個 znode 建立一個 watcher 事件,當該 znode 發生變化時,這些用戶端會收到 zookeeper 的通知,然後用戶端可以根據 znode 變化來做出業務上的改變。
kafka 可以脫離 zookeeper 單獨使用嗎?爲什麼?
kafka 不能脫離 zookeeper 單獨使用,因爲 kafka 使用 zookeeper 管理和協調 kafka 的節點伺服器。
kafka 有幾種數據保留的策略?
kafka 有兩種數據儲存策略:按照過期時間保留和按照儲存的訊息大小保留。
kafka 同時設定了 7 天和 10G 清除數據,到第五天的時候訊息達到了 10G,這個時候 kafka 將如何處理?
這個時候 kafka 會執行數據清除工作,時間和大小不論哪個滿足條件,都會清空數據。
什麼情況會導致 kafka 執行變慢?
使用 kafka 叢集需要注意什麼?
叢集的數量不是越多越好,最好不要超過 7 個,因爲節點越多,訊息複製需要的時間就越長,整個羣組的吞吐量就越低。
叢集數量最好是單數,因爲超過一半故障叢集就不能用了,設定爲單數容錯率更高。