java開發面試問題


Java面試題:java的垮平台原理
為什么要跨平台使用?????
其實說白了就是個操作系統支持的指令集是不一樣的。我們的程序需要再不同的操作系統上運行這些代碼。
但是不要說jvm是跨平台的,而真正跨平台的是 Java 程序,而不是 JVM。JVM 是用 C/C++ 開發的,是編譯后的機器碼,不能跨平台,不同平台下需要安裝不同版本的 JVM

答:
我們編寫的 Java 源碼,編譯后會生成一種 .class 文件,稱為字節碼文件。Java 虛擬機(JVM)就是負責將字節碼文件翻譯成特定平台下的機器碼然后運行,也就是說,只要在不同平台上安裝對應的 JVM,就可以運行字節碼文件,運行我們編寫的 Java 程序。
而這個過程,我們編寫的 Java 程序沒有做任何改變,僅僅是通過 JVM 這一 “中間層” ,就能在不同平台上運行,真正實現了 “一次編譯,到處運行” 的目的。

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

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。

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

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

Java面試題:java面向對象的特征
面向對象的特征:封裝,抽象,繼承,多態
大家一定要注意:回答比較抽象的問題的時候一定要舉例子

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的時候要給一個初始容量。

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

Java面試題:HashMap和HashTable的區別
相同點:都可以用來存儲Key.value型數據
區別:
1、 hashMap是可以把null作為可以key或者value,而hashtable不可以
2、 HashMap是線程不安全的,效率較高,而hashtable是線程安全的,效率較低
我想線程安全我又想效率比較高?????what?????

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

Java面試題:線程的的實現方式?怎么啟動線程?怎么區分線程?
1、 實現方式
a) 常用的通過繼承Thread類來實現一個線程
b) 通過實現Runnable接口來實現一個線程。
c) 通過實現Callable借口來實現一個線程
2.怎么啟動????
我們通過
Thread thread=new Thread(繼承了thread類的對象\或者把實現了runnable接口的對象)
thread.start();
啟動線程的時候用的是start()方法,然后執行線程的時候用的是run()方法;
2、 怎么樣區分線程???
a) 在一個系統當中我們有很多線程,每個系統都會打印日志,我想區分一下到底是哪個系統打印的???
thread.setName(設置一個線程的名稱),這是一個規范,你們將來在開發的時候寫完多線程一定要及記得設置線程名稱。
Java面試題:線程並發庫和線程池的作用
簡單了解過就行
Jdk1.5的時候增加了Doug Lea的並發庫,大大的增加了便利性。Java.util.current
包提供了對線程的優化,包括管理的各項操作。--》線程池的創建,以及線程的生命周期的管理。
Java通過Executors提供四個靜態方法來創建四種線程 池:
1, newCachedThreadPool,可緩存的線程池
2, newFixedThreadPool,創建一個定長線程池
3, newScheduledThreadPool,創建一個定長線程池,支 持定時以及周期性任務
4, newSingleThreadExcutor,創建一個單線程化的線程池
線程池的作用:
1、 限定了線程的個數,不會導致由於線程過多導致系統運行緩慢或崩潰
2、 節約資源,我們不會去關心它的創建於銷毀。
Java面試題:設計模式和常用的設計模式
設計模式就是經過前人總結和實踐出來的,設計過程可以反復的使用,可以解決特定的問題的設計方法
常用的設計模式:
1、單例(餓漢式和飽漢式)
1、構造方法私有化,
2、要自己創建一個對象
3、提供對外獲取對象的方法。
2、工廠設計模式:
Spring IOC就是用的就是工廠模式
3、 代理模式:
a) Spring AOP用的就是動態代理
Java面試題:http get post請求的區別
Get和post都是http的請求方式,用戶可以通過不同的http請求方式完成對資源(url)的操作,get , post,put,delete,對應的是咱們對資源的,查,改,增,刪,四個操作,具體的來說一般情況下,get用於獲取、查詢資源信息。而post一般用於更新資源信息
區別:
1、 get請求提交的數據會在地址欄顯示出來,而post請求不會在地址欄顯示出來
2、 傳輸數據的大小
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的類,然后對外提供服務
不同點:
1、Jsp偏重於視圖,而servlet只要用於控制邏輯
2、servlet如果想要實現html的功能,比喻使用writer輸出對應的html,這個比較麻煩,而jsp是servlet和html組合起來的,做界面展示比較方便,但是想要嵌入邏輯比較復雜。
Java面試題:Session和Cookie的區別和使用場景,你在項目當中哪些地方用到了?????
Session和cookie都是會話跟蹤技術,cookie是通過在客戶端記錄信息來確定用戶身份,session他是通過服務端來記錄用戶的身份。。但是session的實現依賴於cookie,sessionId(session的唯一標識)
區別:
1、 Session放在服務器,而cookie放在瀏覽器
2、 Cookie不是很安全,別人可以通過分析你本地的cookie進行cookie的欺詐,考慮到安全,我們用session
3、 Session會在服務器保存一定的時間,也就是說,當訪問增多的時候,會比較占用服務器的性能,如果將來考慮到服務器壓力的時候,我們要用cookie。
4、 Cookie保存的數據不能超過4k,很多瀏覽器都限制一個站點最多保存50個cookie
5、 個人建議:
要將個人信息保存到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;

		存儲過程有什么優點???????******

1、 存儲過程只在創建是編譯,以后每次執行存儲過程都不需要在重新編譯,而普通的sql語句每執行一次就編譯一次,因此使用存儲過程可以大大提高數據庫的執行速度。
2、 通常情況下,復雜的業務邏輯需要執行多條sql語句,這些語句分別都要從客戶端去鏈接服務器端,這個時候就會產生大量的網絡傳輸,
這個時候,結合業務,我們應該吧這些sql語句放在我們的存儲過程當中,提高我們的效率,降低我們的網絡負載
3、 存儲過程創建一次可以多次調用,可以減少我們開發人員的工作量。
4、 安全性高,存儲過程可以屏蔽對底層數據庫對象的直接訪問。
現在的數據庫支持我們的存儲過程,IBM DB2,oracle。Mysql(5.0) ACCESS。

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

Java面試題:數據庫連接池的作用
1、 限定了數據庫的個數。不會導致由於數據庫鏈接過多導致系統運行緩慢
2、 數據庫連接池,不需要每次都去創建和銷毀,節約資源
3、 響應時間比較快

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

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

Java面試題:簡單介紹一下Spring或者Spring的兩大核心
Spring是將j2EE的應用程序框架,輕量級,可以單獨使用也可以整合我們 struts2 mybatis 。-------EJB
IOC和DI
AOP
Java面試題:AOP是什么?都用它做什么?
AOP:面向切面編程。
用它來干嘛???
1、 事務的控制
2、 權限的判斷
3、 日志
4、 。。。。。。。。。。

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面試::數據庫優化方面的事情
1、 查詢,並定位慢查詢
2、 優化手段
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直接掛掉,水平分表就可以減少壓力。
按行數據進行分表:
如果一張表當中某個字段非常多(長文本,二進制),很少情況下查詢,這個時候我們就要考慮把這些字段單獨放到一個表中,通過外鍵關聯起來。
場景:考試詳情 我們就關心這個人考了多少分,不關心學習過程
水平分表策略:
1、 按時間分表 *****
a) 微博,qq,我們想要查詢月份動態,或者月份的繳費情況,這些有規律性的數據內容,我們可以按時間分表
2、 按區間分表:數據庫當中的自增id
3、 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面試::批量插入幾百萬條數據
1、 修改事務的提交方式
2、 set autocommit=0 開啟
//批量導入數據的時候
set autocommit=1 關閉

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

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

我們會擔心json在轉化成對象的時候會消耗我們的資源的???
第一點:我們使用lib庫轉化成json的形式的時候,是否會存在性能問題
第二點,數據量的級別,百萬級別的大對象,我們就不要用lib轉json的形式,我們就直接用序列化的形式
根據應用場景結合業務---redis其實對string支持的最好如果數據量少,我們還是要用json的形式
Java面試::redis數據淘汰機制
背景:
在redis當中,我們用戶是可以設置最大使用內存的大小,但是內存是固定的,所以需要我們有一定的數據淘汰機制
1、 volatile_lru 從已設置過期時間的數據集中挑選最近很少使用的數據淘汰
2、 volatile_ttl 從已設置過期時間的數據集中選擇將要過期的數據淘汰
3、 volatile_random: 從已設置過期時間的數據集中任意選擇數據淘汰
4、 allkeys_lru:從數據集中挑選最近使用的數據淘汰
5、 allkeys_ random:從數據集當中任意選擇數據淘汰
6、 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中查詢有沒消費記錄即可。
6、如何保證消費的可靠性傳輸?

回答:其實這個可靠性傳輸,每種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信號,生產者會自動重發。
那么如何持久化呢,這里順便說一下吧,其實也很容易,就下面兩步
1、將queue的持久化標識durable設置為true,則代表是一個持久的隊列
2、發送消息的時候將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是干嘛的
    解決方案也很簡單,改成手動提交即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM