重寫和重載的區別
- 重寫(Override)是子類對父類的容許訪問的方法的實現過程進行從新編寫, 返回值和形參都不能改變
- 重載(overloading)是在一個類裏面,方法名字相同,而參數不一樣。
抽象類和接口有什麼區別
- 抽象類是類的抽象,目的在於找出類的共同點,抽象類的不一樣點,接口是行爲的抽象,每一個行爲的具體實現都是不一樣的。
- 實現上,抽象類能夠有構造函數和普通成員變量
- 一個類只能繼承一個抽象類,可是能夠實現多個接口
反射的用途和實現
- 反射用於在jvm運行過程當中動態的獲取對象的類信息,一般用於框架開發如spring
- 判斷任意一個對象所屬的類
- 構造任意一個類的對象
- 判斷任意一個類所具備的成員變量和方法,包括private,好比idea的輸入提示
- 調用任意一個對象的方法
- 實現能夠經過對象的getclass方法獲取類,或者使用class包的class.forname經過類路徑找到類,而後可使用class的newInstance方法建立新的對象,也能夠經過獲取類的constructor對象使用指定的構造函數建立對象。
int 和 Integer 有什麼區別
- Integer是int的包裝類,int則是java的一種基本數據類型
- Integer實際是對象的引用,當new一個Integer時,其實是生成一個指針指向此對象;而int則是直接存儲數據值
- Integer的默認值是null,int的默認值是0
equals 和 == 有什麼區別
- == 比較的是變量(棧)內存中存放的對象的(堆)內存地址,用來判斷兩個對象的地址是否相同,便是否是指相同一個對象。比較的是真正意義上的指針操做
- equals用來比較的是兩個對象的內容是否相等
Integer使用==和int型比較爲何在127如下是相等的而128不等
當Integer和int比較時,java會自動對int裝箱(Integer.valueOf),因爲大多數int比較都在128如下,所以java將-128到127的數放入了緩存,返回的是緩存中的同一個對象而不是新的對象java
類加載,隔離機制
類加載的過程
類加載主要有三個過程,裝載,鏈接,初始化;裝載是指查找和導入class文件到內存中,鏈接則是根據class二進制數據生成對象,這裏會進行類的校驗保證數據符合jvm規範,靜態變量內存分配和符號引用的解析;初始化則是類的初始化操做,這裏會進行靜態變量和靜態代碼塊的初始化,執行類的構造器。面試
雙親委派機制
jvm中有三類加載器,啓動類加載器,擴展類加載器和應用類加載器,雙親委派機制是說當應用類加載器須要加載一個類時不會直接加載而是到父加載器中查找,找不到就找祖加載器,只有都找不到時纔會本身加載。spring
隔離機制
每一個類加載器都有本身的加載範圍以保證內存隔離,對於同一個類的評判標準是:類名一致,類加載器一致,類加載器實例一致。數據庫
若是黑客手寫了一個string.class用自定義加載器加載會生效嗎
不會生效,由於父類加載器已經加載了string.class,當其餘類加載時會直接加載系統的string.class設計模式
多線程環境如何保證只有一個class對象
擴展類加載器在加載類時使用了concurrentHashMap和synchronized,concurrentHashMap保證了只有一個線程能往裏面放對象,而synchronized則保證了加載時只有一個類能被加載數組
如何破壞雙親委派
自定義類加載器一般是繼承擴展類加載器,實現自身findclass方法,若是要破壞雙親委派則要重寫loadclass方法緩存
序列化方式
有兩種方式,一種是使用OutputStream類的wirteobject方法,二種是實現Serializable接口安全
如何判斷一個文件是否存在,如何讀取一個目錄下的全部文件和子目錄
建立file類對象,調用exist方法判斷是否存在,並使用isfile方法判斷是不是文件仍是目錄,目錄的話可使用listfile列出目錄下全部文件和子目錄數據結構
nio aio bio
- bio,同步阻塞io:客戶端發起一個請求,服務端起一個線程處理請求
- nio,同步非阻塞io:客戶端發起一個請求時,服務端生成一個channel創建鏈接,channel註冊到多路複用器上,selector掃描channel,當channel有數據寫到buffer時扔給線程處理
- aio,異步非阻塞io:客戶端發起一個請求時,服務端標記這個io,當系統處理完時回調服務端,服務端處理這個請求
select poll epoll
三種系統的io處理模式,他們都是同步io,使用的多路複用器,當有流須要處理時必須本身處理。多線程
- select 和nio很像,當有流須要io處理時,輪訓多路複用器上全部的文件描述符,每一個文件描述符對應一個socket,找到須要處理的流
- poll 是對select的優化,select因爲在用戶空間操做,每一個端口對應的鏈接數有限制,而poll是將數據移到內核空間處理,只須要檢查文件描述符對應的設備狀態便可,由於處理鏈表存儲fd所以沒有鏈接數的限制
- epoll 則是對poll的優化,當有流進來時會生成io事件通知,而後進程處理對應的io事件,當fd就緒時內核會經過回調激活fd
堆,棧,gc
jvm的做用
java代碼編譯成.class存在操做系統兼容問題,而jdk是根據操做系統安裝的,因此jdk中的jvm加載class文件能夠屏蔽掉操做系統的兼容性問題
jmm是什麼
jmm是java內存模型,和cpu硬件結構類似,每一個線程有本身的工做內存空間,並與主內存交互,當有新的變量時首先寫入主內存而後拷貝到工做內存,好處是能夠提升處理速度,而且線程之間內存隔離。
堆,棧
堆存放動態產生的數據,如new的對象,而棧存放局部變量,包括基礎數據類型的值和對象的引用
一次gc的過程
堆分爲新生代,老年代,永久代(常量池,元數據),java 內存分配和回收的策略是分代分配分代回收,java young gc採用的是中止-複製清理法。新生代分爲eden區和兩個存活區,當一個對象被建立時首先分配到eden區中,當eden區滿時觸發young gc將消亡的對象清理掉並把存活的對象複製到存活區0;以後,young gc在清理eden的同時清理存活區0,把存活的對象複製到存活區1,此時存活區0清空;如此反覆,兩個存活區總有一個是空的,每切換一次存活對象的年齡加1,當屢次切換後(默認年齡是8)仍存活的對象將複製到老年代;當老年代滿時觸發full gc。若是存入eden區的對象很是大,超過eden區的大小則會直接放入老年代。
如何主動觸發gc
jvm判斷是不是垃圾對象用的是可達性分析法,判斷這個對象是否有引用; 使用system.gc主動觸發full gc;
jvm相關命令jstak,jmap,jstat,如何dump內存
- jstat:內存管理工具,能夠查看gc和當前內存使用統計狀況;
- jstack:用來跟蹤堆棧,分析當前程序的運行狀況 ,能夠dump出當前的堆棧信息
- jmap:能夠dump出堆信息,分析當前gc狀況。
排查頻繁gc
- 思路:引發gc的緣由一般有2類,一類是內存泄漏,一類是大對象存儲,所以能夠從這2個方向去排查問題
- 首先jmap dump出內存文件,jstack dump出堆棧信息
- 使用MAT工具分析內存dump文件,找到大量建立的對象和內存佔用最大的對象
- 到堆棧dump信息中找尋問題對象相關的堆棧信息還原現場
- 優化代碼,針對內存泄漏修改代碼邏輯及時釋放對象,針對大對象要分拆
數據結構
ArrayList, LinkedList, SynchronizedList and Vector, CopyAndWriteArrayList
ArrayList, LinkedList 和Vector都實現了List接口,區別在於:
- ArrayList內部其實是一個數組,當更多元素加入時,其大小會動態的增加,每次增加50%,在使用時若是能預估數組的大小進行初始化,能大幅減小調整容量的開銷。
- LinkedList內部是一個雙鏈表,其和ArrayList相比優點在於增刪操做比較快,而get和set操做比較慢
- Vector和ArrayList同樣內部是一個數組,區別在於Vector是線程安全的,當Vector數據增加時默認每次擴容一倍可是長度可控。
- SynchronizedList和Vector同樣是線程安全的,他的區別在於能夠將任意List轉成線程安全的類,可是缺點在於其內部實現機制上遍歷操做不是線程安全的須要手動加鎖。
- CopyAndWriteArrayList是對vector作的優化,vector使用Synchronized鎖住讀寫操做,而CopyAndWriteArrayList不鎖讀操做,寫操做時使用lock上鎖當寫操做完成時替換整個array。
HashMap原理
- hashmap concurrenthashmap
- hashmap
- java7是由數組和鏈表組成的,每個數組元素存的是entry
- get: 根據key的hash值找到數組的位置,而後比較鏈表中每一個元素的key獲得value
- put: 根據key的hash值找到數組的位置,而後比較鏈表中是否存在該key,沒有存在則將該 entry存入鏈表
- resize: hashmap初始化時有數組容量和負載因子,負載因子默認0.75,當數組中存放個數大 於容量*負載因子時進行擴容操做容量翻倍
- java8加入紅黑樹,當鏈表長度大於8時會變成紅黑樹
- concurrenthashmap
- 採用分段設計,每一個段其實就是一個加了同步鎖的hashmap
- ConcurrentHashMap 和 hashtable
- hashtable同步會鎖住整個數據,而ConcurrentHashMap採用分段設計,每次只會鎖住一段數據