java開發面試問題

Java面試題:java的垮平臺原理
爲何要跨平臺使用?????
其實說白了就是個操做系統支持的指令集是不同的。咱們的程序須要再不一樣的操做系統上運行這些代碼。
可是不要說jvm是跨平臺的,而真正跨平臺的是 Java 程序,而不是 JVM。JVM 是用 C/C++ 開發的,是編譯後的機器碼,不能跨平臺,不一樣平臺下須要安裝不一樣版本的 JVMhtml

答:
咱們編寫的 Java 源碼,編譯後會生成一種 .class 文件,稱爲字節碼文件。Java 虛擬機(JVM)就是負責將字節碼文件翻譯成特定平臺下的機器碼而後運行,也就是說,只要在不一樣平臺上安裝對應的 JVM,就能夠運行字節碼文件,運行咱們編寫的 Java 程序。
而這個過程,咱們編寫的 Java 程序沒有作任何改變,僅僅是經過 JVM 這一 「中間層」 ,就能在不一樣平臺上運行,真正實現了 「一次編譯,處處運行」 的目的。前端

Java面試題:JVM由哪些部分組成?
答:JVM 的結構基本上由 4 部分組成:
• 類加載器,在 JVM 啓動時或者類運行時將須要的 class 加載到 JVM 中
• 執行引擎,執行引擎的任務是負責執行 class 文件中包含的字節碼指令,至關於實際機器上的 CPU
• 內存區,將內存劃分紅若干個區以模擬實際機器上的存儲、記錄和調度功能模塊,如實際機器上的各類功能的寄存器或者 PC 指針的記錄器等
• 本地方法調用C 或 C++ 實現的本地,調用方法的代碼返回結果java

Java面試題:類加載器是有了解嗎?
答:顧名思義,類加載器(class loader)用來加載 Java 類到 Java 虛擬機中。通常來講, Java 源程序(.java 文件)在通過 Java 編譯器編譯以後就被轉換成 Java 字節代碼(.class 文件)。
類加載器負責讀取 Java 字節代碼,並轉換成 java.lang.Class類的一個實例。每一個這樣的實例用來表示一個 Java 類。經過此實例的 newInstance()方法就能夠建立出該類的一個對象?
Java面試題:Java 虛擬機是如何斷定兩個 Java 類是相同的?
答:Java 虛擬機不只要看類的全名是否相同,還要看加載此類的類加載器是否同樣。只有二者都相同的狀況,才認爲兩個類是相同的。即使是一樣的字節代碼,被不一樣的類加載器加載以後所獲得的類,也是不一樣的。好比一個 Java 類 com.example.Sample,編譯以後生成了字節代碼文件 Sample.class。兩個不一樣的類加載器 ClassLoaderA和 ClassLoaderB分別讀取了這個 Sample.class文件,並定義出兩個 java.lang.Class類的實例來表示這個類。這兩個實例是不相同的。對於 Java 虛擬機來講,它們是不一樣的類。試圖對這兩個類的對象進行相互賦值,會拋出運行時異常 ClassCastException。mysql

雙親委派模型(Parent Delegation Model)
該模型要求除了頂層的 Bootstrap class loader 啓動類加載器外,其他的類加載器都應當有本身的父類加載器。子類加載器和父類加載器不是以繼承(Inheritance)的關係來實現,而是經過組合(Composition)關係來複用父加載器的代碼。每一個類加載器都有本身的命名空間(由該加載器及全部父類加載器所加載的類組成,在同一個命名空間中,不會出現類的完整名字(包括類的包名)相同的兩個類;在不一樣的命名空間中,有可能會出現類的完整名字(包括類的包名)相同的兩個類)
面試官:雙親委派模型的工做過程?
答:
1.當前 ClassLoader 首先從本身已經加載的類中查詢是否此類已經加載,若是已經加載則直接返回原來已經加載的類。
每一個類加載器都有本身的加載緩存,當一個類被加載了之後就會放入緩存,
等下次加載的時候就能夠直接返回了。
2.當前 ClassLoader 的緩存中沒有找到被加載的類的時候,委託父類加載器去加載,父類加載器採用一樣的策略,首先查看本身的緩存,而後委託父類的父類去加載,一直到 bootstrap ClassLoader.
當全部的父類加載器都沒有加載的時候,再由當前的類加載器加載,並將其放入它本身的緩存中,以便下次有加載請求的時候直接返回。
面試官:爲何這樣設計呢?
解析:這是對於使用這種模型來組織累加器的好處
答:主要是爲了安全性,避免用戶本身編寫的類動態替換 Java 的一些核心類
同時也避免了重複加載,由於 JVM 中區分不一樣類,不只僅是根據類名,相同的 class 文件被不一樣的 ClassLoader 加載就是不一樣的兩個類,若是相互轉型的話會拋java.lang.ClassCaseException.程序員

Jvm垃圾回收算法,原理
    引用計數:標記-清除:複製算法:標記-整理:分代收集算法:

Java面試題:java面向對象的特徵
面向對象的特徵:封裝,抽象,繼承,多態
你們必定要注意:回答比較抽象的問題的時候必定要舉例子web

Java面試題:裝箱和拆箱
?????有了基本的數據類型,咱們爲何還要有包裝類型。
說白了。。。就是體現面向對象的思想
基本類型,int ,flout,double, Bollean等
BooleanBoolean
IntInteger
自動裝箱是jdk1.5之後增長的功能
裝箱:就是把基本數據類型轉化成對應的包裝類型。
總結一下:
Java是一個面向對象的語言,而基本的數據類型,不具有面向對象的特性。
Java面試題:講一下java中的集合
Java集合分爲兩種,一個是value類型的,另外一個就是key.value (Map)兩種
List是有序的,能夠重複的
Set是無序的,不能夠重複的(根據equals和hashcode來判斷。)也就是說若是一個對象要存儲到set當中,就必需要重寫咱們的equals和hashcode的方法。
Map就是key.value的類型數據。
Hashmap存儲原理:
1, API中的經常使用的屬性
2, Hashmap、默認四個構造方法
3, Hash碰撞 ,桶的概念
4, Entry【】--》next屬性面試

Hashmap彈性伸縮的角度不足:
談不足的時候必定要談一下時間複雜度和空間複雜度。
在用hashmap的時候要給一個初始容量。ajax

Java面試題:ArrayList 和LinkedList的區別
是什麼?區別???使用場景
ArrayList底層使用的是數組,LinkedList底層使用的是鏈表
數組查詢的時候具備查詢特定元素比較快。而插入和刪除和修改比較慢(數組在內存當中是一塊聯繫的內存,若是插入或者刪除是須要移動內存的)
鏈表不要求內存是連續的,當查詢的時候,須要從頭部一個一個的找,因此查詢效率低,而插入的時候不須要移動內存,只須要改變引用的指向。
應用場景:ArrayList使用在查詢比較多,答案是插入和刪除比較少的狀況,而LinkedList使用在查詢比較少而插入和刪除比較多的狀況redis

Java面試題:HashMap和HashTable的區別
相同點:均可以用來存儲Key.value型數據
區別:
一、 hashMap是能夠把null做爲能夠key或者value,而hashtable不能夠
二、 HashMap是線程不安全的,效率較高,而hashtable是線程安全的,效率較低
我想線程安全我又想效率比較高?????what?????算法

原理—》就是把整個map分爲N個segment(相似於hashtable),能夠提供相同的線程安全,可是效率提高N。默認提高的16倍。

Java面試題:線程的的實現方式?怎麼啓動線程?怎麼區分線程?
一、 實現方式

a) 經常使用的經過繼承Thread類來實現一個線程

b) 經過實現Runnable接口來實現一個線程。

c) 經過實現Callable藉口來實現一個線程
2.怎麼啓動????
咱們經過
Thread thread=new Thread(繼承了thread類的對象\或者把實現了runnable接口的對象)
thread.start();
啓動線程的時候用的是start()方法,而後執行線程的時候用的是run()方法;
二、 怎麼樣區分線程???

a) 在一個系統當中咱們有不少線程,每一個系統都會打印日誌,我想區分一下究竟是哪一個系統打印的???
thread.setName(設置一個線程的名稱),這是一個規範,大家未來在開發的時候寫完多線程必定要及記得設置線程名稱。
Java面試題:線程併發庫和線程池的做用
簡單瞭解過就行
Jdk1.5的時候增長了Doug Lea的併發庫,大大的增長了便利性。Java.util.current
包提供了對線程的優化,包括管理的各項操做。--》線程池的建立,以及線程的生命週期的管理。
Java經過Executors提供四個靜態方法來建立四種線程 池:
1, newCachedThreadPool,可緩存的線程池
2, newFixedThreadPool,建立一個定長線程池
3, newScheduledThreadPool,建立一個定長線程池,支 持定時以及週期性任務
4, newSingleThreadExcutor,建立一個單線程化的線程池
線程池的做用:
一、 限定了線程的個數,不會致使因爲線程過多致使系統運行緩慢或崩潰
二、 節約資源,咱們不會去關心它的建立於銷燬。
Java面試題:設計模式和經常使用的設計模式
設計模式就是通過前人總結和實踐出來的,設計過程能夠反覆的使用,能夠解決特定的問題的設計方法
經常使用的設計模式:
一、單例(餓漢式和飽漢式)
一、構造方法私有化,
二、要本身建立一個對象
三、提供對外獲取對象的方法。
二、工廠設計模式:
Spring IOC就是用的就是工廠模式
三、 代理模式:

a) Spring AOP用的就是動態代理
Java面試題:http get post請求的區別
Get和post都是http的請求方式,用戶能夠經過不一樣的http請求方式完成對資源(url)的操做,get , post,put,delete,對應的是我們對資源的,查,改,增,刪,四個操做,具體的來講通常狀況下,get用於獲取、查詢資源信息。而post通常用於更新資源信息
區別:
一、 get請求提交的數據會在地址欄顯示出來,而post請求不會在地址欄顯示出來
二、 傳輸數據的大小
http get請求因爲瀏覽器對地址長度有限制,因此就致使對傳輸的數據有限制,而post不會
3,安全性的問題,post的安全性要比get的安全性要高。
Java面試題:Servlet的生命週期

Servlet有良好的生命週期的定義,他包括加載和實例化、初始化、處理請求以及服務結束。這個生命週期是由javax.servlet.Servlet接口中的int 、service、destroy方法來描述。
        Servlet啓動時,開始加載servlet生命週期的開始,servlet被服務器實例化後,容器運行其init方法,請求到達時運行去service方法,service方法會自動派遣運行對應的doXXX等。而後當服務器決定將實例銷燬的時候,這個時候調用destroy方法

Java面試題:jsp和Servlet的相同點和不一樣點
Jsp本質:
Jsp是servlet的擴展,全部的jsp文件都會被翻譯成爲一個繼承HttpServlet的類,而後對外提供服務
不一樣點:
一、Jsp偏重於視圖,而servlet只要用於控制邏輯
二、servlet若是想要實現html的功能,比喻使用writer輸出對應的html,這個比較麻煩,而jsp是servlet和html組合起來的,作界面展現比較方便,可是想要嵌入邏輯比較複雜。
Java面試題:Session和Cookie的區別和使用場景,你在項目當中哪些地方用到了?????
Session和cookie都是會話跟蹤技術,cookie是經過在客戶端記錄信息來肯定用戶身份,session他是經過服務端來記錄用戶的身份。。可是session的實現依賴於cookie,sessionId(session的惟一標識)
區別:
一、 Session放在服務器,而cookie放在瀏覽器
二、 Cookie不是很安全,別人能夠經過分析你本地的cookie進行cookie的欺詐,考慮到安全,咱們用session
三、 Session會在服務器保存必定的時間,也就是說,當訪問增多的時候,會比較佔用服務器的性能,若是未來考慮到服務器壓力的時候,咱們要用cookie。
四、 Cookie保存的數據不能超過4k,不少瀏覽器都限制一個站點最多保存50個cookie
五、 我的建議:
要將我的信息保存到session當中
其餘的信息,若是須要保留咱們放到cookie:購物車信息。

Java面試題:關係型數據庫的三範式
範式?????說白了就是規範
想要知足第二範式,你就必需要知足第一範式,而後,你想要知足第三範式,你就必需要知足第一第二範式
第一範式(1nf),列數據不可分割,是指數據庫表的每一列都是不可分割的基本數據項,同一列當中不能有多個值,對應到我們的pojo對象當中,你一個對象的屬性不能有多個值。

未來的設計不能這樣設計,應爲地址還能夠再分

可是你們須要注意的是,拆不拆要看業務,好比咱們未來要按照國家和省份來分類彙總,那咱們就要把它拆掉,可是若是這個字段僅僅起到一個字符串的做用,那咱們就不必拆分,你們明白吧????
        第二範式(2nf),針對主鍵:

1.要求數據庫當中的每一行必須能夠被惟一的區分,你想要給惟一的區分????加一列設成主鍵。
2.另外非主鍵的列要依賴主鍵,最好第二範式要讓每一個表只描述一件事情

實際,產品的編號和訂單的編號沒有明確的關係,購買日期和訂單編號有關係。
價格和訂單編號也沒有關係,而與產品編號有關,那麼咱們應該拆分爲

第三範式(2nf),第三範式、要求一個數據庫中非主鍵列不依賴於其餘非主鍵列

學號和姓名存在傳遞,由於(學號,姓名)成績 學號成績 姓名成績,冗餘了,只需保留一個

反三範式:訂單(總價)和訂單項(單價)。咱們能夠經過每個訂單去算總價,這是能夠的,可是每次算的時候都得合併計算,影響效率,因此有時候該反的時候就得反
因此什麼是老大,需求是老大!!!!需求>>結構設計

Java面試題:事務的四大特徵
事務是什麼??what????
事務是併發控制的單位,是用戶定義的一個操做序列,這些操做要麼作,要麼不作,是一個不可分割的單位。
轉帳---》1000 a—》b 500 a500 b1500 a轉帳成功並不表明這件事情已經成功了,也就是說,當a轉帳成功,b收到錢之後這個事情纔算結束 。
事務必須知足四大特性:原子性,一致性,隔離性,持久性(持續性)
原子性:表示事務內操做不可分割,要麼都成功,要麼都失敗。
一致性:要麼都成功,要麼都失敗,可是後面失敗了的要對前面的操做進行回滾,
隔離性:一個事務開始後,後面不能有其餘事務干擾。
持久性:表示事務開始了,就不能終止
Java面試題:觸發器的使用場景?
觸發器,what?????
觸發器須要有觸發條件,當條件知足以後作相應的操做
好比:學校的校園網,開心網,facebook,當你發一個日誌,會自動通知好友,本質就是當你增長一個日誌的時候作了一個後觸發。再向數據庫表當中寫入相應的操做。
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:標識觸發器名稱,用戶自行指定;
trigger_time:標識觸發時機,取值爲 BEFORE 或 AFTER;
trigger_event:標識觸發事件,取值爲 INSERT、UPDATE 或 DELETE;
tbl_name:標識創建觸發器的表名,即在哪張表上創建觸發器;
trigger_stmt:觸發器程序體,能夠是一句SQL語句,或者用 BEGIN 和 END 包含的多條語句。
好處:????效率高。在貼吧發一條帖子,都但願在頁面當中展示咱們的最後發帖時間,帖子總數(保證他們的同步更新。)這個時候就能夠用到觸發器並且效率很是高。
Java面試題:存儲過程的優勢
create proceduce insert_student(xxx xxx xxx)
begin
insert 。。。。。
select 。。。。。
sql語句
end;

存儲過程有什麼優勢???????******

一、 存儲過程只在建立是編譯,之後每次執行存儲過程都不須要在從新編譯,而普通的sql語句每執行一次就編譯一次,所以使用存儲過程能夠大大提升數據庫的執行速度。
二、 一般狀況下,複雜的業務邏輯須要執行多條sql語句,這些語句分別都要從客戶端去連接服務器端,這個時候就會產生大量的網絡傳輸,
這個時候,結合業務,咱們應該吧這些sql語句放在咱們的存儲過程中,提升咱們的效率,下降咱們的網絡負載
三、 存儲過程建立一次能夠屢次調用,能夠減小咱們開發人員的工做量。
四、 安全性高,存儲過程能夠屏蔽對底層數據庫對象的直接訪問。
如今的數據庫支持咱們的存儲過程,IBM DB2,oracle。Mysql(5.0) ACCESS。

Java面試題:jdbc調用存儲過程
過程和jdbc調用數據庫的過程差很少
加載驅動
獲取連接
設置參數
執行sql
釋放資源

Java面試題:數據庫鏈接池的做用
一、 限定了數據庫的個數。不會致使因爲數據庫連接過多致使系統運行緩慢
二、 數據庫鏈接池,不須要每次都去建立和銷燬,節約資源
三、 響應時間比較快

Java面試題:簡單介紹了一下Ajax
首先必需要說一下??what????做用是什麼????使用場景,怎麼使用??
什麼是ajax????異步的js和xml
做用是什麼????咱們能夠經過ajax來與服務器進行交互,進行數據的交換,能夠實現局部刷新,這就意味着,咱們能夠不從新加載整個網頁的狀況下,對網頁進行更新。
怎麼實現????咱們經過XmlHttpRequest這個對象,使用這個對象來異步的向服務器發送請求,獲取響應,完成局部刷新。
使用場景?????登陸失敗不跳轉頁面,註冊時用戶名是否存在。二級聯動,三級聯動

Java面試題:Spring MVC的執行流程
一、 用戶向服務器發送請求,請求被spring前端控制器捕獲,
二、 前端控制器對請求的url進行解析,獲得url根據這個url調用HandlerMapping 得到該handler配置的相關信息(包括handler對象以及handler對象對應的攔截器)返回的是以handlerExcutionChain對象的形式進行返回
三、 前端控制器,根據得到的handler,選擇一個合適的handlerAdapter,獲取到request中的數據模型,填充到handler,並開始執行整個流程,而後向前端控制器返回model and view
四、 前端控制器根據返回的model and view,選擇一個合適的ViewResolver對象。
五、 最後一個就是經過ViewResolver對象結合model and view進行視圖渲染,將渲染結果返回給客戶端

Java面試題:簡單介紹一下Spring或者Spring的兩大核心
Spring是將j2EE的應用程序框架,輕量級,能夠單獨使用也能夠整合咱們 struts2 mybatis 。-------EJB
IOC和DI
AOP
Java面試題:AOP是什麼?都用它作什麼?
AOP:面向切面編程。
用它來幹嗎???
一、 事務的控制
二、 權限的判斷
三、 日誌
四、 。。。。。。。。。。

Java面試題:Spring事務的傳播特性和隔離級別
1) PROPAGATION_REQUIRED ,默認的spring事務傳播級別,使用該級別的特色是,若是上下文中已經存在事務,那麼就加入到事務中執行,若是當前上下文中不存在事務,則新建事務執行。因此這個級別一般能知足處理大多數的業務場景。
2)PROPAGATION_SUPPORTS ,從字面意思就知道,supports,支持,該傳播級別的特色是,若是上下文存在事務,則支持事務加入事務,若是沒有事務,則使用非事務的方式執行。因此說,並不是全部的包在transactionTemplate.execute中的代碼都會有事務支持。這個一般是用來處理那些並不是原子性的非核心業務邏輯操做。應用場景較少。
3)PROPAGATION_MANDATORY , 該級別的事務要求上下文中必需要存在事務,不然就會拋出異常!配置該方式的傳播級別是有效的控制上下文調用代碼遺漏添加事務控制的保證手段。好比一段代碼不能單獨被調用執行,可是一旦被調用,就必須有事務包含的狀況,就可使用這個傳播級別。
4)PROPAGATION_REQUIRES_NEW ,從字面便可知道,new,每次都要一個新事務,該傳播級別的特色是,每次都會新建一個事務,而且同時將上下文中的事務掛起,執行當前新建事務完成之後,上下文事務恢復再執行。
問題 :若是其中一個子事務回滾了,父事務是否回滾?答案是不會,由於子事務是新建事務,父事務已經被掛起,二者不會受到影響。
再問:若是父事務回滾了,子事務是否回滾?答案是不會,一樣的理由。可是能夠手動控制一旦子事務回滾,父事務也回滾。

5)PROPAGATION_NOT_SUPPORTED ,這個也能夠從字面得知,not supported ,不支持,當前級別的特色就是上下文中存在事務,則掛起事務,執行當前邏輯,結束後恢復上下文的事務。
這個級別有什麼好處?能夠幫助你將事務很可能的縮小。咱們知道一個事務越大,它存在的風險也就越多。因此在處理事務的過程當中,要保證儘量的縮小範圍。好比一段代碼,是每次邏輯操做都必須調用的,好比循環1000次的某個非核心業務邏輯操做。這樣的代碼若是包在事務中,勢必形成事務太大,致使出現一些難以考慮周全的異常狀況。因此這個事務這個級別的傳播級別就派上用場了。用當前級別的事務模板抱起來就能夠了。
6)PROPAGATION_NEVER ,該事務更嚴格,上面一個事務傳播級別只是不支持而已,有事務就掛起,而PROPAGATION_NEVER傳播級別要求上下文中不能存在事務,一旦有事務,就拋出runtime異常,強制中止執行!這個級別上輩子跟事務有仇。
7)PROPAGATION_NESTED ,字面也可知道,nested,嵌套級別事務。該傳播級別特徵是,若是上下文中存在事務,則嵌套事務執行,若是不存在事務,則新建事務。Propagation_required_new 老是開啓一個新的事務,若是有一個事務存在,就將已存在的事務掛起
隔離級別:
髒讀 :所謂的髒讀,其實就是讀到了別的事務回滾前的髒數據。好比事務B執行過程當中修改了數據X,在未提交前,事務A讀取了X,而事務B卻回滾了,這樣事務A就造成了髒讀。
不可重複讀 :不可重複讀字面含義已經很明瞭了,好比事務A首先讀取了一條數據,而後執行邏輯的時候,事務B將這條數據改變了,而後事務A再次讀取的時候,發現數據不匹配了,就是所謂的不可重複讀了。
幻讀 :小的時候數手指,第一次數十10個,第二次數是11個,怎麼回事?產生幻覺了?
幻讀也是這樣子,事務A首先根據條件索引獲得10條數據,而後事務B改變了數據庫一條數據,致使也符合事務A當時的搜索條件,這樣事務A再次搜索發現有11條數據了,就產生了幻讀。
Java面試::數據庫優化方面的事情
一、 查詢,並定位慢查詢
二、 優化手段

a) 建立索引:建立合適的索引,咱們就能夠先在索引當中查詢,經過索引找到對應的記錄

b) 分表。也就是說當一張表的數據比較多的時候,或者一張表當中某些字段的值比較多而且不怎麼經常使用的時候咱們要分表。水平拆分和垂直拆分

c) 讀寫分離:當一個服務器不能知足需求的時候,咱們能夠創建數據庫集羣

d) 緩存:也就是咱們要用redis。
Java面試::若是查詢和定位慢查詢
slow_query_log= 1
long_query_time= 1
slow_query_log_file=c:/slow.log
在項目當中,給測試人員執以前,再啓動mysql數據的時候,咱們開啓慢查詢,而且把慢查詢語句打到咱們的日誌當中,運行一段時間,看看哪些語句執行效率最慢

Java面試::選擇合適的數據庫引擎
show engines;
SHOW VARIABLES LIKE 'storage_engine';
在開發當中,咱們常常用的存儲引擎
Myisam innodb memory
Myisam 存儲引擎
MyISAM基於ISAM存儲引擎,並對其進行擴展。它是在Web、數據倉儲和其餘應用環境下最常使用的存儲引擎之一。MyISAM擁有較高的插入、查詢速度,但不支持事物。
Innodb 存儲引擎
InnoDB是事務型數據庫的首選引擎,支持事務安全表(ACID),支持行鎖定和外鍵
Memory
MEMORY存儲引擎將表中的數據存儲到內存中,當咱們的數據頻繁變化的時候,並且不須要入庫,這個時候用memory存儲引擎。
Myisam和innodb的區別:
1, 事務安全 myisam不支持事務,而innodb支持
2, 查詢和添加速度, myisam他由於不支持事務,因此就表明不須要考慮同步鎖,也就是說查找和添加的速度快
3, 支持全文檢索方面 myisam支持 innodb不支持
4, 鎖機制 myisam支持的是表鎖 innodb支持的是行鎖
5, 外鍵方面 myisam不支持外鍵 innodb支持外鍵

Java面試::選擇合適的索引
What???--》索引是幫助dbms(數據庫管理)用來高效獲取數據的數據結構
分類 普通索引\惟一索引\主鍵索引\全文索引
普通索引:容許重複的值出現
惟一索引:除了不能有重複的數據記錄外,和普通索引同樣
主鍵索引:是隨着設定主鍵而建立的,也就是說把某個列設爲主鍵的時候,這個時候數據庫會給該列建立索引,注意!!主鍵索引是惟一的且不能是null值
全文索引:整個表中的文本域都是索引
Java面試::使用索引的一些技巧
索引有什麼弊端!!!!
1,佔用磁盤空間。
2, 對dml(插入、修改、刪除)操做有影響,會變慢。
索引的使用場景:
,1:在where條件常用,若是不作查詢基本上索引沒有什麼意義
2:該字段的內容不是惟一的幾個值
3:字段的內容不能頻繁的變化
具體的技巧:
1:對於建立多列索引的時候(複合索引),記住,若是不是使用的第一部分就不會使用索引

2:對於使用like語句的時候沒若是查詢是‘%aaa’ 不會使用索引,’aaa%’ 會使用索引
3:當你的sql語句有or的時候,只要是有條件沒有使用索引,其餘條件即便帶索引也不會使用。
4:若是列類型是字符串,那必定要在條件中講數據使用引號引發來,不然就不能使用索引

5:Mysql若是感受我遍歷整個表都比使用索引快,那麼它自動就不使用索引了
Java面試::數據庫優化之分表
根據經驗,mysql數據達到百萬級別,查詢效率就很是低了,就會形成鎖表,甚至堆積多鏈接,致使mysql直接掛掉,水平分表就能夠減小壓力。
按行數據進行分表:
若是一張表當中某個字段很是多(長文本,二進制),不多狀況下查詢,這個時候咱們就要考慮把這些字段單獨放到一個表中,經過外鍵關聯起來。
場景:考試詳情 咱們就關心這我的考了多少分,不關心學習過程
水平分表策略:
一、 按時間分表 *****

a) 微博,qq,咱們想要查詢月份動態,或者月份的繳費狀況,這些有規律性的數據內容,咱們能夠按時間分表
二、 按區間分表:數據庫當中的自增id
三、 Hash分表********

a) 經過一個原始目標的id或者名稱經過必定的合適算法,算出來數據庫的表名稱。而後訪問相應的表。
Java面試::數據庫的讀寫分離
背景:一臺數據庫支持最大的併發連接數量是有限的,若是用戶訪問量加大,一臺服務器是知足不了咱們的需求,因此咱們用集羣的方式來實現。
主從同步
讀寫分離
Java面試::數據庫優化之緩存
Java當中咱們持久層和數據庫這個層面 常見的緩存有hb的二級緩存,mb二級緩存,這些緩存都不支持分佈式緩存
咱們能夠用redis來做爲中央緩存

Java面試::sql語句優化小技巧

  1. 對查詢進行優化,要儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。
  2. 應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描
  3. 應儘可能避免在 where 子句中使用 != 或 <> 操做符,不然將引擎放棄使用索引而進行全表掃描。
  4. 應儘可能避免在 where 子句中使用 or 來鏈接條件,若是一個字段有索引,一個字段沒有索引,將致使引擎放棄使用索引而進行全表掃描,如
    select id from t where num=10 or Name = 'admin'
    能夠這樣查詢:
    select id from t where num = 10union allselect id from t where Name = 'admin'
  5. select count(*) from table;這樣不帶任何條件的count會引發全表掃描,而且沒有任何業務意義,是必定要杜絕的。
    調優參數:
  6. back_log:back_log值指出在MySQL暫時中止回答新請求以前的短期內多少個請求能夠被存在堆棧中。也就是說,若是MySql的鏈接數據達到max_connections時,新來的請求將會被存在堆棧中,以等待某一鏈接釋放資源,該堆棧的數量即back_log,若是等待鏈接的數量超過back_log,將不被授予鏈接資源。能夠從默認的50升至500
  7. wait_timeout:數據庫鏈接閒置時間,閒置鏈接會佔用內存資源。能夠從默認的8小時減到半小時
  8. max_user_connection: 最大鏈接數,默認爲0無上限,最好設一個合理上限
  9. thread_concurrency:併發線程數,設爲CPU核數的兩倍
  10. skip_name_resolve:禁止對外部鏈接進行DNS解析,消除DNS解析時間,但須要全部遠程主機用IP訪問
  11. key_buffer_size:索引塊的緩存大小,增長會提高索引處理速度,對MyISAM表性能影響最大。對於內存4G左右,可設爲256M或384M,經過查詢show status like 'key_read%',保證key_reads / key_read_requests在0.1%如下最好
  12. innodb_buffer_pool_size:緩存數據塊和索引塊,對InnoDB表性能影響最大。經過查詢show status like 'Innodb_buffer_pool_read%',保證(Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests越高越好
  13. innodb_additional_mem_pool_size:InnoDB存儲引擎用來存放數據字典信息以及一些內部數據結構的內存空間大小,當數據庫對象很是多的時候,適當調整該參數的大小以確保全部數據都能存放在內存中提升訪問效率,當太小的時候,MySQL會記錄Warning信息到數據庫的錯誤日誌中,這時就須要該調整這個參數大小
  14. innodb_log_buffer_size:InnoDB存儲引擎的事務日誌所使用的緩衝區,通常來講不建議超過32MB
  15. query_cache_size:緩存MySQL中的ResultSet,也就是一條SQL語執行的結果集,因此僅僅只能針對select語句。當某個表的數據有任何任何變化,都會致使全部引用了該表的select語句在Query Cache中的緩存數據失效。因此,當咱們的數據變化很是頻繁的狀況下,使用Query Cache可能會得不償失。根據命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))進行調整,通常不建議太大,256MB可能已經差很少了,大型的配置型靜態數據可適當調大.
    能夠經過命令show status like 'Qcache_%'查看目前系統Query catch使用大小
  16. read_buffer_size:MySql讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql會爲它分配一段內存緩衝區。若是對錶的順序掃描請求很是頻繁,能夠經過增長該變量值以及內存緩衝區大小提升其性能
  17. sort_buffer_size:MySql執行排序使用的緩衝大小。若是想要增長ORDER BY的速度,首先看是否可讓MySQL使用索引而不是額外的排序階段。若是不能,能夠嘗試增長sort_buffer_size變量的大小
  18. read_rnd_buffer_size:MySql的隨機讀緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySql會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySql會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開銷過大。
  19. record_buffer:每一個進行一個順序掃描的線程爲其掃描的每張表分配這個大小的一個緩衝區。若是你作不少順序掃描,可能想要增長該值
  20. thread_cache_size:保存當前沒有與鏈接關聯可是準備爲後面新的鏈接服務的線程,能夠快速響應鏈接的線程請求而無需建立新的
  21. table_cache:相似於thread_cache_size,但用來緩存表文件,對InnoDB效果不大,主要用於MyISAM

Java面試::批量插入幾百萬條數據
一、 修改事務的提交方式
二、 set autocommit=0 開啓
//批量導入數據的時候
set autocommit=1 關閉

二、將多條sql語句合成一條去執行
            能省出的時候很是可觀
            儘可能不要用java代碼去寫,要用存儲過程(最好用)。

Java面試::有沒有使用過redis
介紹一下redis
Redis是一個key_value的非關係型數據庫,它會先把數據放到內存房中,,會根據必定的策略持久化到磁盤當中,及時斷電也不會丟失,支持的數據類型比較多。(數據結構)
Redis主要是用來。緩存數據庫當中的數據,在web集羣當中用做中央緩存存放session
Java面試::redis的使用場景
緩存:
把常常須要查詢的,不多修改的數據,放到讀取速度很快的空間當中(redis),來減小訪問時間,減輕數據壓力
計數器:
Redis當中的計數器是原子性的內存操做
能夠解決數據庫溢出的問題。
Session緩存服務器
web集羣當中用做中央緩存存放session
Java面試::redis存儲對象的方式
一、咱們須要把對象轉化成json字符串,當作字符串處理,直接咱們就可使用set get來設置
優勢就是:獲取和設置的時候比較簡單
缺點是:redis沒有專門的方法去把對象轉化成json形式
三、 字節的形式,必要的時候,咱們能夠把對象序列化,轉化成字節保存

咱們會擔憂json在轉化成對象的時候會消耗咱們的資源的???
第一點:咱們使用lib庫轉化成json的形式的時候,是否會存在性能問題
第二點,數據量的級別,百萬級別的大對象,咱們就不要用lib轉json的形式,咱們就直接用序列化的形式
根據應用場景結合業務---redis其實對string支持的最好若是數據量少,咱們仍是要用json的形式
Java面試::redis數據淘汰機制
背景:
在redis當中,咱們用戶是能夠設置最大使用內存的大小,可是內存是固定的,因此須要咱們有必定的數據淘汰機制
一、 volatile_lru 從已設置過時時間的數據集中挑選最近不多使用的數據淘汰
二、 volatile_ttl 從已設置過時時間的數據集中選擇將要過時的數據淘汰
三、 volatile_random: 從已設置過時時間的數據集中任意選擇數據淘汰
四、 allkeys_lru:從數據集中挑選最近使用的數據淘汰
五、 allkeys_ random:從數據集當中任意選擇數據淘汰
六、 no_enviction:禁止驅逐數據
java面試題:爲何要使用消息隊列?
直接回答6個字,解耦、異步、削峯
使用消息隊列有什麼缺點?
1,系統可用性下降:你想啊,原本其餘系統只要運行好好的,那你的系統就是正常的。如今你非要加個消息隊列進去,那消息隊列掛了,你的系統不是呵呵了。所以,系統可用性下降
2,系統複雜性增長:要多考慮不少方面的問題,好比一致性問題、如何保證消息不被重複消費,如何保證保證消息可靠傳輸。所以,須要考慮的東西更多,系統複雜性增大
怎麼選型???ActiveMQ,RabbitMQ,RocketMQ,Kafka
建議選RabbitMQ.一方面,erlang語言天生具有高併發的特性,並且他的管理界面用起來十分方便。正所謂,成也蕭何,敗也蕭何!他的弊端也在這裏,雖然RabbitMQ是開源的,然而國內有幾個能定製化開發erlang的程序員呢?所幸,RabbitMQ的社區十分活躍,能夠解決開發過程當中遇到的bug,這點對於中小型公司來講十分重要。不考慮rocketmq和kafka的緣由是,一方面中小型軟件公司不如互聯網公司,數據量沒那麼大,選消息中間件,應首選功能比較完備的,因此kafka排除。不考慮rocketmq的緣由是,rocketmq是阿里出品,若是阿里放棄維護rocketmq,中小型公司通常抽不出人來進行rocketmq的定製化開發,所以不推薦。
(2)大型軟件公司,根據具體使用在rocketMq和kafka之間二選一。一方面,大型軟件公司,具有足夠的資金搭建分佈式環境,也具有足夠大的數據量。針對rocketMQ,大型軟件公司也能夠抽出人手對rocketMQ進行定製化開發,畢竟國內有能力改JAVA源碼的人,仍是至關多的。至於kafka,根據業務場景選擇,若是有日誌採集功能,確定是首選kafka了。具體該選哪一個,看使用場景。如何保證消息不被重複消費?
Java面試題:如何保證消息不被重複消費?
分析:這個問題其實換一種問法就是,如何保證消息隊列的冪等性?
回答:先來講一下爲何會形成重複消費?
  其實不管是那種消息隊列,形成重複消費緣由其實都是相似的。正常狀況下,消費者在消費消息時候,消費完畢後,會發送一個確認信息給消息隊列,消息隊列就知道該消息被消費了,就會將該消息從消息隊列中刪除。只是不一樣的消息隊列發送的確認信息形式不一樣,例如RabbitMQ是發送一個ACK確認消息,RocketMQ是返回一個CONSUME_SUCCESS成功標誌,kafka實際上有個offset的概念,簡單說一下(若是還不懂,出門找一個kafka入門到精通教程),就是每個消息都有一個offset,kafka消費過消息後,須要提交offset,讓消息隊列知道本身已經消費過了。那形成重複消費的緣由?,就是由於網絡傳輸等等故障,確認信息沒有傳送到消息隊列,致使消息隊列不知道本身已經消費過該消息了,再次將該消息分發給其餘的消費者。
如何解決?這個問題針對業務場景來答分如下幾點
  (1)好比,你拿到這個消息作數據庫的insert操做。那就容易了,給這個消息作一個惟一主鍵,那麼就算出現重複消費的狀況,就會致使主鍵衝突,避免數據庫出現髒數據。
  (2)再好比,你拿到這個消息作redis的set的操做,那就容易了,不用解決,由於你不管set幾回結果都是同樣的,set操做原本就算冪等操做。
  (3)若是上面兩種狀況還不行,上大招。準備一個第三方介質,來作消費記錄。以redis爲例,給消息分配一個全局id,只要消費過該消息,將<id,message>以K-V形式寫入redis。那消費者開始消費前,先去redis中查詢有沒消費記錄便可。
六、如何保證消費的可靠性傳輸?

回答:其實這個可靠性傳輸,每種MQ都要從三個角度來分析:生產者弄丟數據、消息隊列弄丟數據、消費者弄丟數據
RabbitMQ
(1)生產者丟數據
從生產者弄丟數據這個角度來看,RabbitMQ提供transaction和confirm模式來確保生產者不丟消息。
transaction機制就是說,發送消息前,開啓事物(channel.txSelect()),而後發送消息,若是發送過程當中出現什麼異常,事物就會回滾(channel.txRollback()),若是發送成功則提交事物(channel.txCommit())。
然而缺點就是吞吐量降低了。所以,生產上用confirm模式的居多。一旦channel進入confirm模式,全部在該信道上面發佈的消息都將會被指派一個惟一的ID(從1開始),一旦消息被投遞到全部匹配的隊列以後,rabbitMQ就會發送一個Ack給生產者(包含消息的惟一ID),這就使得生產者知道消息已經正確到達目的隊列了.若是rabiitMQ沒能處理該消息,則會發送一個Nack消息給你,你能夠進行重試操做。處理Ack和Nack的代碼以下所示(說好不上代碼的,偷偷上了):
(2)消息隊列丟數據
處理消息隊列丟數據的狀況,通常是開啓持久化磁盤的配置。這個持久化配置能夠和confirm機制配合使用,你能夠在消息持久化磁盤後,再給生產者發送一個Ack信號。這樣,若是消息持久化磁盤以前,rabbitMQ陣亡了,那麼生產者收不到Ack信號,生產者會自動重發。
那麼如何持久化呢,這裏順便說一下吧,其實也很容易,就下面兩步
一、將queue的持久化標識durable設置爲true,則表明是一個持久的隊列
二、發送消息的時候將deliveryMode=2
這樣設置之後,rabbitMQ就算掛了,重啓後也能恢復數據

消費者丟數據
消費者丟數據通常是由於採用了自動確認消息模式。這種模式下,消費者會自動確認收到信息。這時rahbitMQ會當即將消息刪除,這種狀況下若是消費者出現異常而沒能處理該消息,就會丟失該消息。
至於解決方案,採用手動確認消息便可。
KAFKA
(1)生產者丟數據
在kafka生產中,基本都有一個leader和多個follwer。follwer會去同步leader的信息。所以,爲了不生產者丟數據,作以下兩點配置

  1. 第一個配置要在producer端設置acks=all。這個配置保證了,follwer同步完成後,才認爲消息發送成功。
  2. 在producer端設置retries=MAX,一旦寫入失敗,這無限重試
    (2)消息隊列丟數據
    針對消息隊列丟數據的狀況,無外乎就是,數據還沒同步,leader就掛了,這時zookpeer會將其餘的follwer切換爲leader,那數據就丟失了。針對這種狀況,應該作兩個配置。
  3. replication.factor參數,這個值必須大於1,即要求每一個partition必須有至少2個副本
  4. min.insync.replicas參數,這個值必須大於1,這個是要求一個leader至少感知到有至少一個follower還跟本身保持聯繫 這兩個配置加上上面生產者的配置聯合起來用,基本可確保kafka不丟數據 (3)消費者丟數據 這種狀況通常是自動提交了offset,而後你處理程序過程當中掛了。kafka覺得你處理好了。再強調一次offset是幹嗎的 解決方案也很簡單,改爲手動提交便可。
相關文章
相關標籤/搜索