這篇文章主要介紹了P6級Java面試題有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在錯(cuò)那等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計(jì)、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需搭建網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),網(wǎng)絡(luò)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè)公司,錯(cuò)那網(wǎng)站建設(shè)費(fèi)用合理。一、String stringBuffer和stringBuilder
String:適用于少量字符串操作的情況,為字符串常量,即對象一旦創(chuàng)建之后對象是不可更改的。
StringBuffer:適用多線程下字符緩沖區(qū)進(jìn)行大量操作的情況。屬于線程安全。
StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況。屬于線程不安全。
StringBuffer與StringBuilder均為字符串變量,對象是變量,即可以更改。StringBuilder所有方面都沒有被synchronized修飾,它的效率比StringBuffer要高。
二、HashMap的底層實(shí)現(xiàn)原理
HashMap底層是數(shù)組+鏈表實(shí)現(xiàn)的,它是一個(gè)entry類的數(shù)組,entry中包含key和value的值,允許key、value可以為null,通過key的hashcode計(jì)算在這個(gè)數(shù)組所在位置,遍歷這個(gè)鏈表從而查詢到值,hashMap默認(rèn)的初始化容器大小為16,之后每次擴(kuò)充為原來的2倍。屬于線程不安全的。
在JDK1.7及以前,HashMap中維護(hù)著Entry,Entry中維護(hù)著key,value以及hash和next指針,而整個(gè)HashMap實(shí)際就是一個(gè)Entry數(shù)組。
當(dāng)向 HashMap 中 put 一對鍵值時(shí),它會根據(jù) key的 hashCode 值計(jì)算出一個(gè)位置,該位置就是此對象準(zhǔn)備往數(shù)組中存放的位置。
如果該位置沒有對象存在,就將此對象直接放進(jìn)數(shù)組當(dāng)中;如果該位置已經(jīng)有對象存在了,則順著此存在的對象的鏈開始尋找(為了判斷是否是否值相同,map不允許鍵值對重復(fù)),如果此鏈上有對象的話,再去使用 equals方法進(jìn)行比較,如果對此鏈上的每個(gè)對象的 equals 方法比較為 false,則將該對象放到數(shù)組當(dāng)中,然后將數(shù)組中該位置以前存在的那個(gè)對象鏈接到此對象的后面。
get方法類似,通過key取hash找到數(shù)組的某個(gè)位置,然后遍歷這個(gè)數(shù)組上的每個(gè)Entry,直到key值equals則返回。
如果Hash碰撞嚴(yán)重,那么JDK1.7中的實(shí)現(xiàn)性能就很差,因?yàn)槊看尾迦攵家闅v完整條鏈去查看key值是否重復(fù),每次get也要遍歷整個(gè)鏈,在JDK1.8中,由于鏈表的查找復(fù)雜度為O(n),而紅黑樹的查找復(fù)雜度為O(logn),JDK1.8中采用鏈表/紅黑樹的方式實(shí)現(xiàn)HashMap,達(dá)到某個(gè)閥值時(shí),鏈表轉(zhuǎn)成了紅黑樹。
三、HashMap和Concurrent HashMap區(qū)別, Concurrent HashMap 線程安全嗎, ConcurrentHashMap如何保證線程安全?
HashMap不是線程安全的,ConcurrentHashMap是線程安全的,HashMap內(nèi)部維護(hù)著一個(gè)Entry數(shù)組,而ConcurrentHashMap內(nèi)部有一個(gè)Segment段,它將大的HashMap切分成若干個(gè)段(小的HashMap),然后讓數(shù)據(jù)在每一段上Hash,這樣多個(gè)線程在不同段上的Hash操作一定是線程安全的,所以只需要同步同一個(gè)段上的線程就可以了,這樣實(shí)現(xiàn)了鎖的分離,大大增加了并發(fā)量。ConcurrentHashMap的實(shí)現(xiàn)中還使用了不變模式final和volatile來保障線程安全
四、HashMap的put方法做了哪些操作
他會根據(jù)key的hashcode重新計(jì)算hash值,根據(jù)hash值得到這個(gè)元素在數(shù)據(jù)中的位置,如果數(shù)組在該位置上已經(jīng)存放有其他元素了,那么在這個(gè)位置上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。
五、HashMap的缺點(diǎn)
HashMap不支持并發(fā)操作,所以不適用于多線程環(huán)境,在高并發(fā)狀態(tài)下,如果產(chǎn)生同時(shí)put操作,并且在put時(shí)剛好遇上要擴(kuò)容,可能會形成鏈環(huán),如果get的key的hashcode值剛好在鏈環(huán)的位置,而這個(gè)key對應(yīng)的值為null或不存在就會進(jìn)入死循環(huán),耗盡cpu內(nèi)存。
六、ConcurrentHashMap
底層是數(shù)組+紅黑樹+鏈表實(shí)現(xiàn),可以替代HashTable,因?yàn)槭褂昧硕鄠€(gè)鎖代替hashTable中的單個(gè)鎖,也就是鎖分離技術(shù),hashTable是鎖住了整個(gè)數(shù)組導(dǎo)致效率特別低,屬于線程安全。
七、Springmvc的工作原理
用戶發(fā)送請求至前端控制器DispatcherServlet,DispatcherServlet收到請求調(diào)用handlerMapping處理器映射器,解析請求對應(yīng)的handler,開始由handlerAdapter適配器處理請求,并處理相應(yīng)的業(yè)務(wù)邏輯并返回一個(gè)ModelAndView對象,根據(jù)返回的modelAndView選擇一個(gè)合適視圖解析器返回給DispatcherServlet,視圖解析器根據(jù)view和model渲染頁面。
八、集合的父類及各子類的區(qū)別
Collection
├List 允許重復(fù)值、有序容器,保持了每個(gè)元素的插入順序
│├LinkedList 線程不安全增刪改速度快,基于鏈表數(shù)據(jù)結(jié)構(gòu)
│├ArrayList 線程不安全查詢速度快,基于動(dòng)態(tài)數(shù)組結(jié)構(gòu)
│└Vector 線程安全
│└Stack
├set 不允許重復(fù)值、無序容器,無法保證元素的存儲順序,可以通過TreeSet的comparator或者comparable維護(hù)一個(gè)排序順序
│├HashSet 線程不安全無序(存入與取出時(shí)順序不同)不重復(fù),無索引,底層hash表結(jié)構(gòu)查詢刪除快,增改慢。
│├TreeSet 是sortedSet接口的唯一實(shí)現(xiàn),可以進(jìn)行排序
九、什么是線程安全與不安全
線程安全是多個(gè)線程訪問時(shí),采用了加鎖機(jī)制,當(dāng)一個(gè)線程訪問該類的某個(gè)數(shù)據(jù)時(shí),進(jìn)行保護(hù),其他線程不能進(jìn)行訪問,直到該線程讀取完,其他線程才可使用,不會出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。
線程不安全就是不提供數(shù)據(jù)訪問保護(hù),有可能出現(xiàn)多個(gè)線程后更改數(shù)據(jù)造成所得到數(shù)據(jù)時(shí)臟數(shù)據(jù)。
十、為什么使用reids,用redis都做了些什么
Redis是一個(gè)開源的key-value型數(shù)據(jù)庫,運(yùn)行在內(nèi)存,速度快,同時(shí)支持持久化,支持的數(shù)據(jù)結(jié)構(gòu)豐富(String,list,set,sorted set,hash),支持訂閱發(fā)布功能。
String:(常用命令get,set,incr,decr,mget)常規(guī)的key-value緩存應(yīng)用。統(tǒng)計(jì)訪問次數(shù),關(guān)注人數(shù)。
Hash(常用命令hget,hset,hgetall)省市區(qū)聯(lián)動(dòng),用戶信息
List(常用命令 Ipush,rpush,Ipop)用戶關(guān)注列表
Set 注冊用戶用戶名不能重復(fù),使用set記錄注冊用戶
十一、Jvm如何調(diào)優(yōu)
VisualVM:jdk自帶,功能強(qiáng)大
堆信息查看:觀察內(nèi)存釋放情況、集合類檢查、對象樹-----(查看堆空間的大小分配【年輕代、年老代、持久代分配】、提供即時(shí)的垃圾回收功能、垃圾監(jiān)控),可以解決年老代年輕代大小劃分是否合理、內(nèi)存泄漏、垃圾回收算法設(shè)置是否合理。
線程監(jiān)控:可以查看線程在系統(tǒng)中的數(shù)量,各個(gè)線程都處在什么狀態(tài)下、死鎖檢查
熱點(diǎn)分析:cpu熱點(diǎn)---檢查系統(tǒng)哪些方面占用大量cpu時(shí)間,內(nèi)存熱點(diǎn)-------檢查哪些對象在系統(tǒng)中的數(shù)量大。
內(nèi)存泄漏檢查:在錯(cuò)誤的使用下導(dǎo)致使用完畢的資源無法回收,引起系統(tǒng)錯(cuò)誤。常表現(xiàn)年老代空間被占滿(java heap space)一般根據(jù)垃圾回收前后情況對比,同時(shí)根據(jù)對象引用情況分析,基本可以找到泄漏點(diǎn)。
持久代被沾滿:無法為新的class分配存儲空間而引發(fā)的異常,在java大量的反射的使用會造成,大量動(dòng)態(tài)反射生成的類不斷被加載。解決:-XX:MaxPermSize=16m
堆棧溢出:一般是遞歸沒返回,或者循環(huán)調(diào)用造成
線程池棧滿:java中一個(gè)線程空間大小是有限的,在jdk5以后這個(gè)值是1m。解決:增加線程棧大小,-Xss2m
十二、GC垃圾回收機(jī)制
什么時(shí)候:eden滿了minor gc,升到老年代的對象大于老年代剩余空間full gc,或者小于時(shí)被HandlePromotionFailure參數(shù)強(qiáng)制full gc
對什么東西:從root搜索不到,而且經(jīng)過第一次標(biāo)記,清理后仍然沒有復(fù)活的對象。
做什么事情:刪除不使用的對象,騰出內(nèi)存空間。
算法:
1、標(biāo)記-清除:分為標(biāo)記和清除兩個(gè)階段,首先標(biāo)記出所有需要回收的對象,標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對象。
2、復(fù)制算法:它將可用的內(nèi)存分為兩塊,每次只用其中一塊,當(dāng)這一塊內(nèi)存用完了,就將還存活的對象復(fù)制到另一塊上,然后再把已經(jīng)使用過的內(nèi)存空間一次性清理掉。
3、標(biāo)記-整理算法:是讓所有存活的對象都向一端移動(dòng),然后直接清理掉邊界以外的內(nèi)存。
十三、 JVM如何GC,新生代,老年代,持久代,都存儲哪些東西?
JVM通過可達(dá)性(可觸及性)分析算法標(biāo)記出哪些對象是垃圾對象,然后將垃圾對象進(jìn)行回收,在新生代中采用復(fù)制算法,在老年代中采用標(biāo)記清理或標(biāo)記壓縮算法。
新生代存儲了新new出的對象,老年代存儲了大的對象和多次GC后仍然存在的老年對象,持久代存儲了類信息,常量(JDK7中String常量池被移到堆中),靜態(tài)變量(JDK7中被移到了Java堆),類方法
十四、 強(qiáng)引用、軟引用、弱引用、虛引用的區(qū)別
強(qiáng)引用:是最難被GC回收的,寧可虛擬機(jī)拋出異常,中斷程序,也不會去回收該對象。(Object o=new Object())
軟引用:非必須引用,內(nèi)存溢出之前進(jìn)行回收。軟引用主要用戶實(shí)現(xiàn)類似緩存的功能,在內(nèi)存足夠的情況下直接通過軟引用取值,無需從繁忙的真實(shí)來源查詢數(shù)據(jù),提升速度;當(dāng)內(nèi)存不足時(shí),自動(dòng)刪除這部分緩存數(shù)據(jù),從真正的來源查詢這些數(shù)據(jù)。
弱引用:第二次垃圾回收時(shí)回收。弱引用主要用于監(jiān)控對象是否已經(jīng)被垃圾回收器標(biāo)記為即將回收的垃圾,可以通過弱引用的isEnQueued方法返回對象是否被垃圾回收器標(biāo)記。
虛引用:垃圾回收時(shí)回收,無法通過引用取到對象值。虛引用主要用于檢測對象是否已經(jīng)從內(nèi)存中刪除。
十五、Spring的原理
內(nèi)部核心是ioc,動(dòng)態(tài)注入,讓一個(gè)對象的創(chuàng)建不用new了,可以自動(dòng)生成,這其實(shí)就是利用了java里的反射,反射其實(shí)就是在運(yùn)行時(shí)動(dòng)態(tài)的去創(chuàng)建、調(diào)用對象,spring就是在運(yùn)行時(shí),跟xml spring的配置文件來動(dòng)態(tài)的創(chuàng)建對象,和調(diào)用對象的方法。
Spring還有一個(gè)核心就是AOP面向切面編程,可以為某一類對象進(jìn)行監(jiān)督和控制從而達(dá)到堆一個(gè)模塊擴(kuò)充的功能。這些都是通過配置類達(dá)到的。
十六、Aop如何實(shí)現(xiàn)
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對其編譯。在程序運(yùn)行時(shí),代理類.class文件就已經(jīng)存在了
動(dòng)態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用發(fā)射機(jī)制動(dòng)態(tài)創(chuàng)建而成。
Cglib動(dòng)態(tài)代理:針對類實(shí)現(xiàn)的代理。它的原理是對指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對final修飾的類進(jìn)行代理。
JDK的動(dòng)態(tài)代理依靠接口實(shí)現(xiàn),如果有些類沒有實(shí)現(xiàn)接口,則不能使用jdk代理,就要使用cglib代理了。
十七、MySQL如何優(yōu)化
使用查詢緩存優(yōu)化查詢。(例如NOW(),RAND()或其他SQL函數(shù)都不會開啟查詢緩存,因?yàn)榉祷厥菚欢ǖ囊鬃兊?,所以你需要的就是一個(gè)變量來替代mysql的函數(shù),從而開啟緩存)
使用EXPLANIN關(guān)鍵字檢測查詢(可以使我們知道MYSQL是如何處理SQL語句的,幫助分析查詢語句或是表結(jié)構(gòu)性能瓶頸;索引主鍵是如何被利用的,數(shù)據(jù)表是如何被搜索或排序的,語句格式:EXPLAIN+SELECT語句)
當(dāng)只有一行數(shù)據(jù)時(shí)使用LIMIT 1(可以增加性能,會查到第一條數(shù)據(jù)后停止搜索)
為搜索字段建立索引(普通索引INDEX:適用于name、email等一般屬性,唯一索引UNIQUE:要求索引字段值在表中是唯一的,唯一索引允許有空值。適用于身份證號碼、用戶賬戶等,全文索引:適用于VARCHAR和TEXT類型字段)
在jion表的時(shí)候使用相當(dāng)類型的列,并將其索引(存在很多jion查詢時(shí),保證兩個(gè)表中jion的字段時(shí)被建立索引的,這樣mysql會啟動(dòng)優(yōu)化JION的sql語句機(jī)制)
避免使用 *
永遠(yuǎn)為每一張表設(shè)置一個(gè)ID主鍵
盡可能的不要賦值為NULL(會占用存儲空間,程序判斷更加復(fù)雜,索引不存儲null值,使用not null約束以及默認(rèn)值。)
固定長度的表會更快(容易計(jì)算下一個(gè)數(shù)據(jù)的偏移量,容易被緩存和重建。)
垂直分割:是一種把數(shù)據(jù)庫中的表按列變成幾張表的方法,這樣可以降低表的復(fù)雜度和字段數(shù)目
拆分大的或(這兩個(gè)大操作會鎖表,這樣別的操作就進(jìn)不來了,可以使用LIMIT控制操作記錄的數(shù)量)
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“P6級Java面試題有哪些”這篇文章對大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!