下面是我自己收集整理的Java崗位今天面經遇到的面試題,可以用它來好好準備面試。
一、Java基礎
1. String類爲什麼是final的。
主要是爲了“安全”和"效率"問題!由於string使用頻率高,可能會降低程序的性能,所以也不被允許繼承,同時string也是個對象類型!
2.HashMap的源碼,實現原理,底層結構。
數組的特點是:尋址容易,插入和刪除困難;而鏈表的特點是:尋址困難(從開頭開始),插入和刪除容易。那麼我們能不能綜合兩者的特性,做出一種尋址容易,插入刪除也容易的數據結構?答案是肯定的,這就是我們要提起的哈希表,哈希表有多種不同的實現方法,我接下來解釋的是最常用的一種方法—— 拉鍊法,我們可以理解爲“鏈表的數組”
HashMap的源碼-關鍵屬性:1,5個,存儲元素的實體數組,存放元素的個數,臨界值threshold=加載因子*容量,加載因子,修改的次數。2。構造方法。3,存儲數據。4,調整大小。5,數據讀取
HashMap的源碼-實現原理:對key計算hashcode,hash和table.length計算index也就是table數組的下標
HashMap的源碼-底層結構: HashMap的底層主要是基於數組和鏈表來實現的,它之所以有相當快的查詢速度,主要是因爲它是通過計算散列碼來決定存儲的位置
3.解決hash衝突的辦法,1,開放定址法(線性探測再散列,二次探測再散列,僞隨機探測再散列),2,再哈希法,3,鏈地址法,4,建立一個公共溢出區,Java中hashmap的解決辦法就是採用的鏈地址法。
3. 說說你知道的幾個Java集合類:list、set、queue、map實現類咯。。。
在java5中新增加了java.util.Queue接口,用以支持隊列的常見操作。該接口擴展了java.util.Collection接口。
Queue使用時要儘量避免Collection的add()和remove()方法,而是要使用offer()來加入元素,使用poll()來獲取並移出元素。它們的優點是通過返回值可以判斷成功與否,add()和remove()方法在失敗的時候會拋出異常。 如果要使用前端而不移出該元素,使用element()或者peek()方法。值得注意的是LinkedList類實現了Queue接口,因此我們可以把LinkedList當成Queue來用。
4. 描述一下ArrayList和LinkedList各自實現和區別
ArrayList 採用的是數組形式來保存對象的,這種方式將對象放在連續的位置中,所以最大的缺點就是插入刪除時非常麻煩。
LinkedList 採用的將對象存放在獨立的空間中,而且在每個空間中還保存下一個鏈接的索引 但是缺點就是查找非常麻煩 要從第一個索引開始。
5. Java中的隊列都有哪些,有什麼區別。
在java5中新增加了java.util.Queue接口,用以支持隊列的常見操作。Queue接口與List、Set同一級別,都是繼承了Collection接口。
Queue使用時要儘量避免Collection的add()和remove()方法,而是要使用offer()來加入元素,使用poll()來獲取並移出元素。它們的優
點是通過返回值可以判斷成功與否,add()和remove()方法在失敗的時候會拋出異常。 如果要使用前端而不移出該元素,使用
element()或者peek()方法。
值得注意的是LinkedList類實現了Queue接口,因此我們可以把LinkedList當成Queue來用。
LinkedList實現了Queue接口。Queue接口窄化了對LinkedList的方法的訪問權限(即在方法中的參數類型如果是Queue時,就完全只能訪問Queue接口所定義的方法 了,而不能直接訪問 LinkedList的非Queue的方法),以使得只有恰當的方法纔可以使用。BlockingQueue 繼承了Queue接口
6. 反射中,Class.forName和classloader的區別
1,Class.forName("xx.xx")等同於Class.forName("xx.xx",true,CALLClass.class.getClassLoader()),第二個參數(bool)表示裝載類的時候是否初始化該類,即調用類的靜態塊的語句及初始化靜態成員變量。
ClassLoader loader = Thread.currentThread.getContextClassLoader(); //也可以用(ClassLoader.getSystemClassLoader())
Class cls = loader.loadClass("xx.xx"); //這句話沒有執行初始化,其實與Class.forName("xx.xx",false,loader)是一致的,只是loader.loadClass("xx.xx")執行的是更底層的操作。
,只有執行cls.NewInstance()才能夠初始化類,得到該類的一個實例
Class的裝載分了三個階段,loading,linking和initializing,分別定義在The Java Language Specification的12.2,12.3和12.4。
Class.forName(className) 實際上是調用Class.forName(className, true, this.getClass().getClassLoader())。注意第二個參數,是指Class被loading後是不是必須被初始化。
ClassLoader.loadClass(className)實際上調用的是ClassLoader.loadClass(name, false),第二個參數指出Class是否被link。
區別就出來了。Class.forName(className)裝載的class已經被初始化,而ClassLoader.loadClass(className)裝載的class還沒有被link。
forName支持數組類型,loadClass不支持數組
一般情況下,這兩個方法效果一樣,都能裝載Class。但如果程序依賴於Class是否被初始化,就必須用Class.forName(name)了。
例如,在JDBC編程中,常看到這樣的用法,Class.forName("com.mysql.jdbc.Driver"),如果換成了 getClass().getClassLoader().loadClass("com.mysql.jdbc.Driver"),就不行。
爲什麼呢?打開com.mysql.jdbc.Driver的源代碼看看,
// Register ourselves with the DriverManager
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
原來,Driver在static塊中會註冊自己到java.sql.DriverManager。而static塊就是在Class的初始化中被執行。所以這個地方就只能用Class.forName(className)
7. Java7、Java8的新特性(baidu問的,好BT)
8. Java數組和鏈表兩種結構的操作效率,在哪些情況下(從開頭開始,從結尾開始,從中間開始),哪些操作(插入,查找,刪除)的效率高
9. Java內存泄露的問題調查定位:jmap,jstack的使用等等
命令
1. jmap -dump:format=b,file=filename pid
jmap -dump:format=b,file=jmap0225.bin 18646
jmap -histo<:live> pid : 查看當期那 heap 的對象
sudo -u tomcat jmap -histo 1234 | sudo -u tomcat tee /tmp/histo.log
jmap --heap pid : 查看 heap 結構
--------------------------------
2. jstack pid >> file
jstack 18646 >> jstackfile
出現錯誤
well-known file is not secure
需要將執行命令的用戶改爲啓動tomcat線程用戶, 如下
sudo -u tomcat jmap -dump:file=filename pid
------
使用jstack分析步驟
1. top 查看java進程
2. top -p <java-pid> -H 查看消耗cpu的線程
3. <thread-id> 轉爲 十六進制
3. sudo -u tomcat jstack <java-pid> | grep -A 10 <0x thread-id> 查看運行狀況
10. string、stringbuilder、stringbuffer區別
11. hashtable和hashmap的區別
13 .異常的結構,運行時異常和非運行時異常,各舉個例子
14. String a= “abc” String b = “abc” String c = new String(“abc”) String d = “ab” + “c” .他們之間用 == 比較的結果
15. String 類的常用方法
16. Java 的引用類型有哪幾種
string 類 對象 引用
17. 抽象類和接口的區別
18. java的基礎類型和字節大小。
19. Hashtable,HashMap,ConcurrentHashMap 底層實現原理與線程安全問題(建議熟悉 jdk 源碼,才能從容應答)
20. 如果不讓你用Java Jdk提供的工具,你自己實現一個Map,你怎麼做。說了好久,說了HashMap源代碼,如果我做,就會借鑑HashMap的原理,說了一通HashMap實現
21. Hash衝突怎麼辦?哪些解決散列衝突的方法?
22. HashMap衝突很厲害,最差性能,你會怎麼解決?從O(n)提升到log(n)咯,用二叉排序樹的思路說了一通 http://kb.cnblogs.com/page/189480/
23. rehash
24. hashCode() 與 equals() 生成算法、方法怎麼重寫 http://blog.sina.com.cn/s/blog_5da93c8f0101djjr.html
需要注意記住的事情
- 儘量保證使用對象的同一個屬性來生成hashCode()和equals()兩個方法。在我們的案例中,我們使用員工id。
- eqauls方法必須保證一致(如果對象沒有被修改,equals應該返回相同的值)
- 任何時候只要a.equals(b),那麼a.hashCode()必須和b.hashCode()相等。
- 兩者必須同時重寫。
當使用ORM的時候特別要注意的
- 如果你使用ORM處理一些對象的話,你要確保在hashCode()和equals()對象中使用getter和setter而不是直接引用成員變量。因爲在ORM中有的時候成員變量會被延時加載,這些變量只有當getter方法被調用的時候才真正可用。
- 例如在我們的例子中,如果我們使用e1.id == e2.id則可能會出現這個問題,但是我們使用e1.getId() ==e2.getId()就不會出現這個問題。
擴展:你覺得你還有哪裏比較擅長,在這次面試中沒有聊起來的嗎?
這這這,我心裏想,在你這大牛面前,怎敢提擅長兩個字啊。然後弱弱的說了一句“SSH框架都有用過”——這下好了,把SSH技術原理都說了一通。 Struts2的原理體系架構啊,IoC啊,過濾器啊,攔截器啊。Hibernate的原理體系架構啊,五大核心接口啊,Hibernate對象的三種狀態轉換啊。Spring的IoC、AOP啊,事務管理啊
二、Java IO
1. 講講IO裏面的常見類,字節流、字符流、接口、實現類、方法阻塞。
2. 講講NIO。
3. String 編碼UTF-8 和GBK的區別?
4. 什麼時候使用字節流、什麼時候使用字符流?
5. 遞歸讀取文件夾下的文件,代碼怎麼實現
三、Java Web
1. session和cookie的區別和聯繫,session的生命週期,多個服務部署時session管理。(http://blog.csdn.net/u012635819/article/details/50678602)
url重寫
2. servlet的一些相關問題
3. webservice相關問題
4. jdbc連接,forname方式的步驟,怎麼聲明使用一個事務。舉例並具體代碼
5. 無框架下配置web.xml的主要配置內容
http://blog.csdn.net/guihaijinfen/article/details/8363839
6. jsp和servlet的區別
四、JVM
1. Java的內存模型以及GC算法
2. jvm性能調優都做了什麼
3. 介紹JVM中7個區域,然後把每個區域可能造成內存的溢出的情況說明
4. 介紹GC 和GC Root不正常引用。
5. 自己從classload 加載方式,加載機制說開去,從程序運行時數據區,講到內存分配,講到String常量池,講到JVM垃圾回收機制,算法,hotspot。反正就是各種擴展
6. jvm 如何分配直接內存, new 對象如何不分配在堆而是棧上,常量池解析
7. 數組多大放在 JVM 老年代(不只是設置 PretenureSizeThreshold ,問通常多大,沒做過一問便知)
8. 老年代中數組的訪問方式
9. GC 算法,永久代對象如何 GC , GC 有環怎麼處理
10. 誰會被 GC ,什麼時候 GC
11. 如果想不被 GC 怎麼辦
12. 如果想在 GC 中生存 1 次怎麼辦
五、開源框架
1. hibernate和ibatis的區別
2. 講講mybatis的連接池。
3. spring框架中需要引用哪些jar包,以及這些jar包的用途
4. springMVC的原理
5. springMVC註解的意思
6. spring中beanFactory和ApplicationContext的聯繫和區別
7. spring注入的幾種方式(循環注入)
8. spring如何實現事物管理的
9. springIOC
10. spring AOP的原理
11. hibernate中的1級和2級緩存的使用方式以及區別原理(Lazy-Load的理解)
12. Hibernate的原理體系架構,五大核心接口,Hibernate對象的三種狀態轉換,事務管理。
六、多線程
1. Java創建線程之後,直接調用start()方法和run()的區別
2. 常用的線程池模式以及不同線程池的使用場景
3. newFixedThreadPool此種線程池如果線程數達到最大值後會怎麼辦,底層原理。
4. 多線程之間通信的同步問題,synchronized鎖的是對象,衍伸出和synchronized相關很多的具體問題,例如同一個類不同方法都有synchronized鎖,一個對象是否可以同時訪問。或者一個類的static構造方法加上synchronized之後的鎖的影響。
5. 瞭解可重入鎖的含義,以及ReentrantLock 和synchronized的區別
6. 同步的數據結構,例如concurrentHashMap的源碼理解以及內部實現原理,爲什麼他是同步的且效率高
7. atomicinteger和Volatile等線程安全操作的關鍵字的理解和使用
8. 線程間通信,wait和notify
9. 定時線程的使用
10. 場景:在一個主線程中,要求有大量(很多很多)子線程執行完之後,主線程才執行完成。多種方式,考慮效率。
11. 進程和線程的區別
12. 什麼叫線程安全?舉例說明
13. 線程的幾種狀態
14. 併發、同步的接口或方法
15. HashMap 是否線程安全,爲何不安全。 ConcurrentHashMap,線程安全,爲何安全。底層實現是怎麼樣的。
16. J.U.C下的常見類的使用。 ThreadPool的深入考察; BlockingQueue的使用。(take,poll的區別,put,offer的區別);原子類的實現。
17. 簡單介紹下多線程的情況,從建立一個線程開始。然後怎麼控制同步過程,多線程常用的方法和結構
18. volatile的理解
19. 實現多線程有幾種方式,多線程同步怎麼做,說說幾個線程裏常用的方法
七、網絡通信
1. http是無狀態通信,http的請求方式有哪些,可以自己定義新的請求方式麼。
2. socket通信,以及長連接,分包,連接異常斷開的處理。
3. socket通信模型的使用,AIO和NIO。
4. socket框架netty的使用,以及NIO的實現原理,爲什麼是異步非阻塞。
5. 同步和異步,阻塞和非阻塞。
6. OSI七層模型,包括TCP,IP的一些基本知識
7. http中,get post的區別
8. 說說http,tcp,udp之間關係和區別。
9. 說說瀏覽器訪問www.taobao.com,經歷了怎樣的過程。
10. HTTP協議、 HTTPS協議,SSL協議及完整交互過程;
11. tcp的擁塞,快回傳,ip的報文丟棄
12. https處理的一個過程,對稱加密和非對稱加密
13. head各個特點和區別
14. 說說瀏覽器訪問www.taobao.com,經歷了怎樣的過程。
八、數據庫MySql
1. MySql的存儲引擎的不同
2. 單個索引、聯合索引、主鍵索引
3. Mysql怎麼分表,以及分表後如果想按條件分頁查詢怎麼辦(如果不是按分表字段來查詢的話,幾乎效率低下,無解)
4. 分表之後想讓一個id多個表是自增的,效率實現
5. MySql的主從實時備份同步的配置,以及原理(從庫讀主庫的binlog),讀寫分離
6. 寫SQL語句。。。
7. 索引的數據結構,B+樹
8. 事務的四個特性,以及各自的特點(原子、隔離)等等,項目怎麼解決這些問題
9. 數據庫的鎖:行鎖,表鎖;樂觀鎖,悲觀鎖
10. 數據庫事務的幾種粒度;
11. 關係型和非關係型數據庫區別
關係型數據庫通過外鍵關聯來建立表與表之間的關係,非關係型數據庫通常指數據以對象的形式存儲在數據庫中,而對象之間的關係通過每個對象自身的屬性來決定,非關係型數據庫中,我們查詢一條數據,結果出來一個數組,關係型數據庫中,查詢一條數據結果是一個對象。
九、設計模式
1. 單例模式:飽漢、餓漢。以及餓漢中的延遲加載,雙重檢查
2. 工廠模式、裝飾者模式、觀察者模式,設配器模式。
設配器模式:1. 概述(http://www.cnblogs.com/wangjq/archive/2012/07/09/2582485.html)
將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以在一起工作。
2. 解決的問題
即Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以在一起工作。
3. 模式中的角色
3.1 目標接口(Target):客戶所期待的接口。目標可以是具體的或抽象的類,也可以是接口。
3.2 需要適配的類(Adaptee):需要適配的類或適配者類。
3.3 適配器(Adapter):通過包裝一個需要適配的對象,把原接口轉換成目標接口。
4. 模式解讀
注:在GoF的設計模式中,對適配器模式講了兩種類型,類適配器模式和對象適配器模式。由於類適配器模式通過多重繼承對一個接口與另一個接口進行匹配,而C#、java等語言都不支持多重繼承,因而這裏只是介紹對象適配器。
3. 工廠方法模式的優點(低耦合、高內聚,開放封閉原則)
工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法模式讓實例化推遲到子類。
優點
1、 在工廠方法中,用戶只需要知道所要產品的具體工廠,無須關係具體的創建過程,甚至不需要具體產品類的類名。
2、 在系統增加新的產品時,我們只需要添加一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,很好地符合了“開閉原則”。
缺點
1、 每次增加一個產品時,都需要增加一個具體類和對象實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。這並不是什麼好事
十、算法
1. 使用隨機算法產生一個數,要求把1-1000W之間這些數全部生成。(考察高效率,解決產生衝突的問題)
2. 兩個有序數組的合併排序
3. 一個數組的倒序
4. 計算一個正整數的正平方根
5. 說白了就是常見的那些查找、排序算法以及各自的時間複雜度
6. 二叉樹的遍歷算法
7. DFS,BFS算法
9. 比較重要的數據結構,如鏈表,隊列,棧的基本理解及大致實現。
10. 排序算法與時空複雜度(快排爲什麼不穩定,爲什麼你的項目還在用)
11. 逆波蘭計算器
12. Hoffman 編碼
13. 查找樹與紅黑樹
十一、併發與性能調優
1. 有個每秒鐘5k個請求,查詢手機號所屬地的筆試題(記得不完整,沒列出),如何設計算法?請求再多,比如5w,如何設計整個系統?
2. 高併發情況下,我們系統是如何支撐大量的請求的
3. 集羣如何同步會話狀態
4. 負載均衡的原理
5 .如果有一個特別大的訪問量,到數據庫上,怎麼做優化(DB設計,DBIO,SQL優化,Java優化)
6. 如果出現大面積併發,在不增加服務器的基礎上,如何解決服務器響應不及時問題“。
7. 假如你的項目出現性能瓶頸了,你覺得可能會是哪些方面,怎麼解決問題。
8. 如何查找 造成 性能瓶頸出現的位置,是哪個位置照成性能瓶頸。
9. 你的項目中使用過緩存機制嗎?有沒用用戶非本地緩存
十二、其他
1.常用的linux下的命令