java面试题_阿里大厂流出的数百道 Java 经典面试题
BAT 常問的 Java基礎39道常見面試題
1.八種基本數據類型的大小,以及他們的封裝類
2.引用數據類型
3.Switch能否用string做參數
4.equals與==的區別
5.自動裝箱,常量池
6.Object有哪些公用方法
7.Java的四種引用,強弱軟虛,用到的場景
8.Hashcode的作用
9.HashMap的hashcode的作用
10.為什么重載hashCode方法?
11.ArrayList、LinkedList、Vector的區別
12.String、StringBuffer與StringBuilder的區別
13.Map、Set、List、Queue、Stack的特點與用法
14.HashMap和HashTable的區別
15.JDK7與JDK8中HashMap的實現
16.HashMap和ConcurrentHashMap的區別,HashMap的底層源碼
17.ConcurrentHashMap能完全替代HashTable嗎
18.為什么HashMap是線程不安全的
19.如何線程安全的使用HashMap
20.多并發情況下HashMap是否還會產生死循環
21.TreeMap、HashMap、LindedHashMap的區別
22.Collection包結構,與Collections的區別
23.try?catch?finally,try里有return,finally還執行么
24.Excption與Error包結構,OOM你遇到過哪些情況,SOF你遇到過哪些情況
25.Java(OOP)面向對象的三個特征與含義
26.Override和Overload的含義去區別
27.Interface與abstract類的區別
28.Static?class?與non?static?class的區別
29.foreach與正常for循環效率對比
30.Java?IO與NIO
31.java反射的作用于原理
32.泛型常用特點
33.解析XML的幾種方式的原理與特點:DOM、SAX
34.Java1.7與1.8,1.9,10 新特性
35.設計模式:單例、工廠、適配器、責任鏈、觀察者等等
36.JNI的使用
37.AOP是什么
38.OOP是什么
39.AOP與OOP的區別
Java 多線程面試題
1、多線程有什么用?
2、創建線程的方式
3、start()方法和run()方法的區別
4、Runnable接口和Callable接口的區別
5、CyclicBarrier和CountDownLatch的區別
6、volatile關鍵字的作用
7、什么是線程安全
8、Java中如何獲取到線程dump文件
9、一個線程如果出現了運行時異常會怎么樣
10、如何在兩個線程之間共享數據
11、sleep方法和wait方法有什么區別
12、生產者消費者模型的作用是什么
13、ThreadLocal有什么用
14、為什么wait()方法和notify()/notifyAll()方法要在同步塊中被調用
15、wait()方法和notify()/notifyAll()方法在放棄對象監視器時有什么區別
16、為什么要使用線程池
17、怎么檢測一個線程是否持有對象監視器
18、synchronized和ReentrantLock的區別
19、ConcurrentHashMap的并發度是什么
20、ReadWriteLock是什么
21、FutureTask是什么
22、Linux環境下如何查找哪個線程使用CPU最長
23、Java編程寫一個會導致死鎖的程序
24、怎么喚醒一個阻塞的線程
25、不可變對象對多線程有什么幫助
26、什么是多線程的上下文切換
27、如果你提交任務時,線程池隊列已滿,這時會發生什么
28、Java中用到的線程調度算法是什么
29、Thread.sleep(0)的作用是什么
30、什么是自旋
31、什么是Java內存模型
32、什么是CAS
33、什么是樂觀鎖和悲觀鎖
34、什么是AQS
35、單例模式的線程安全性
36、Semaphore有什么作用
37、Hashtable的size()方法中明明只有一條語句"return count",為什么還要做同步?
38、線程類的構造方法、靜態塊是被哪個線程調用的
39、同步方法和同步塊,哪個是更好的選擇
40、高并發、任務執行時間短的業務怎樣使用線程池?并發不高、任務執行時間長的業務怎樣使用線程池?并發高、業務執行時間長的業務怎樣使用線程池?
跳槽必備的100道 Java 面試題
多線程、并發及線程的基礎問題
1)Java 中能創建 volatile 數組嗎?
2)volatile 能使得一個非原子操作變成原子操作嗎?
3)volatile 修飾符的有過什么實踐?
4)volatile 類型變量提供什么保證?
5) 10 個線程和 2 個線程的同步代碼,哪個更容易寫?
6)你是如何調用 wait()方法的?使用 if 塊還是循環?為什么?
7)什么是多線程環境下的偽共享(false sharing)?
有經驗程序員的 Java 面試題
8)什么是 Busy spin?我們為什么要使用它?
9)Java 中怎么獲取一份線程 dump 文件?
10)Swing 是線程安全的?
11)什么是線程局部變量?
12)Java 中 sleep 方法和 wait 方法的區別?
13)什么是不可變對象(immutable object)?Java 中怎么創建一個不可變對象?
14)我們能創建一個包含可變對象的不可變對象嗎?
15)Java 中應該使用什么數據類型來代表價格?
16)怎么將 byte 轉換為 String?
17)Java 中怎樣將 bytes 轉換為 long 類型?
18)我們能將 int 強制轉換為 byte 類型的變量嗎?如果該值大于 byte 類型的范圍,將會出現什么現象?
19)哪個類包含 clone 方法?是 Cloneable 還是 Object?
20)Java 中 ++ 操作符是線程安全的嗎?
21)不是線程安全的操作。它涉及到多個指令,如讀取變量值,增加,
22)a = a + b 與 a += b 的區別
23)我能在不進行強制轉換的情況下將一個 double 值賦值給 long 類型的變量嗎?
24)3*0.1 == 0.3 將會返回什么?true 還是 false?
25)int 和 Integer 哪個會占用更多的內存?
26)為什么 Java 中的 String 是不可變的(Immutable)?
27)我們能在 Switch 中使用 String 嗎?
28)Java 中的構造器鏈是什么?
JVM 底層 與 GC(Garbage Collection) 的面試問題
29)64 位 JVM 中,int 的長度是多數?
30)Serial 與 Parallel GC之間的不同之處?
31)32 位和 64 位的 JVM,int 類型變量的長度是多數?
32)Java 中 WeakReference 與 SoftReference的區別?
33)WeakHashMap 是怎么工作的?
34)JVM 選項 -XX:+UseCompressedOops 有什么作用?為什么要使
35)怎樣通過 Java 程序來判斷 JVM 是 32 位 還是 64 位?
36)32 位 JVM 和 64 位 JVM 的最大堆內存分別是多數?
37)JRE、JDK、JVM 及 JIT 之間有什么不同?
3 年工作經驗的 Java 面試題
38)解釋 Java 堆空間及 GC?
39)你能保證 GC 執行嗎?
40)怎么獲取 Java 程序使用的內存?堆使用的百分比?
41)Java 中堆和棧有什么區別?
Java 基本概念面試題
42)“a==b”和”a.equals(b)”有什么區別?
43)a.hashCode() 有什么用?與 a.equals(b) 有什么關系?
44)final、finalize 和 finally 的不同之處?
45)Java 中的編譯期常量是什么?使用它又什么風險?
Java 集合框架的面試題
46) List、Set、Map 和 Queue 之間的區別(答案)
47)poll() 方法和 remove() 方法的區別?
48)Java 中 LinkedHashMap 和 PriorityQueue 的區別是什么?
49)ArrayList 與 LinkedList 的不區別?
50)用哪兩種方式來實現集合的排序?
51)Java 中怎么打印數組?
52)Java 中的 LinkedList 是單向鏈表還是雙向鏈表?
53)Java 中的 TreeMap 是采用什么樹實現的?(答案)
54) Hashtable 與 HashMap 有什么不同之處?
55)Java 中的 HashSet,內部是如何工作的?
56)寫一段代碼在遍歷 ArrayList 時移除一個元素?
57)我們能自己寫一個容器類,然后使用 for-each 循環碼?
58)ArrayList 和 HashMap 的默認大小是多數?
59)有沒有可能兩個不相等的對象有有相同的 hashcode?
60)兩個相同的對象會有不同的的 hash code 嗎?
61)Java 中,Comparator 與 Comparable 有什么不同?
62)為什么在重寫 equals 方法的時候需要重寫 hashCode 方法?
Java IO 和 NIO 的面試題
63)Java 中怎么創建 ByteBuffer?
Java 最佳實踐的面試問題
64)Java 中,編寫多線程程序的時候你會遵循哪些最佳實踐?
65)說出幾點 Java 中使用 Collections 的最佳實踐
66)說出 5 條 IO 的最佳實踐(答案)
67)說出幾條 Java 中方法重載的最佳實踐?
Date、Time 及 Calendar 的面試題
68)在多線程環境下,SimpleDateFormat 是線程安全的嗎?
單元測試 JUnit 面試題
69)如何測試靜態方法?
70)Java 中如何將字符串轉換為整數?
關于 OOP 和設計模式的面試題
71)接口是什么?為什么要使用接口而不是直接使用具體類?
72)Java 中,抽象類與接口之間有什么不同?
73)除了單例模式,你在生產環境中還用過什么設計模式?
74) 什么情況下會違反迪米特法則?為什么會有這個問題?
75)適配器模式是什么?什么時候使用?
76)什么是“依賴注入”和“控制反轉”?為什么有人使用?
77)抽象類是什么?它與接口有什么區別?你為什么要使用過抽象類?
78)構造器注入和 setter 依賴注入,那種方式更好?
79)依賴注入和工程模式之間有什么不同?
80)適配器模式和裝飾器模式有什么區別?
81)適配器模式和代理模式之前有什么不同?
82)什么是模板方法模式?
83)什么時候使用訪問者模式?
84)什么時候使用組合模式?
85)繼承和組合之間有什么不同?
86)描述 Java 中的重載和重寫?
87)Java 中,嵌套公共靜態類與頂級類有什么不同?
88) OOP 中的 組合、聚合和關聯有什么區別?
89)給我一個符合開閉原則的設計模式的例子?
90)抽象工廠模式和原型模式之間的區別?
91)什么時候使用享元模式?
Java 面試中其他各式各樣的問題
92)嵌套靜態類與頂級類有什么區別?
93)你能寫出一個正則表達式來判斷一個字符串是否是一個數字嗎?
94)Java 中,受檢查異常 和 不受檢查異常的區別?
95)Java 中,throw 和 throws 有什么區別
96)Java 中,Serializable 與 Externalizable 的區別?
97)Java 中,DOM 和 SAX 解析器有什么不同?
98)說出 JDK 1.7 中的三個新特性?
99)說出 5 個 JDK 1.8 引入的新特性?
100)Java 中,Maven 和 ANT 有什么區別?
115道Java經典面試題(面中率高、全)
Java是一個支持并發、基于類和面向對象的計算機編程語言。下面列出了面向對象軟件開發的優點:
代碼開發模塊化,更易維護和修改。
代碼復用。
增強代碼的可靠性和靈活性。
增加代碼的可理解性。
面向對象編程有很多重要的特性,比如:封裝,繼承,多態和抽象。下面的章節我們會逐個分析這些特性。
封裝
封裝給對象提供了隱藏內部特性和行為的能力。對象提供一些能被其他對象訪問的方法來改變它內部的數據。在Java當中,有3種修飾符:public,private和protected。每一種修飾符給其他的位于同一個包或者不同包下面對象賦予了不同的訪問權限。
下面列出了使用封裝的一些好處:
通過隱藏對象的屬性來保護對象內部的狀態。
提高了代碼的可用性和可維護性,因為對象的行為可以被單獨的改變或者是擴展。
禁止對象之間的不良交互提高模塊化。
參考這個文檔獲取更多關于封裝的細節和示例。
多態
多態是編程語言給不同的底層數據類型做相同的接口展示的一種能力。一個多態類型上的操作可以應用到其他類型的值上面。
繼承
繼承給對象提供了從基類獲取字段和方法的能力。繼承提供了代碼的重用行,也可以在不修改類的情況下給現存的類添加新特性。
抽象
抽象是把想法從具體的實例中分離出來的步驟,因此,要根據他們的功能而不是實現細節來創建類。Java支持創建只暴漏接口而不包含方法實現的抽象的類。這種抽象技術的主要目的是把類的行為和實現細節分離開。
抽象和封裝的不同點
抽象和封裝是互補的概念。一方面,抽象關注對象的行為。另一方面,封裝關注對象行為的細節。一般是通過隱藏對象內部狀態信息做到封裝,因此,封裝可以看成是用來提供抽象的一種策略。
常見的Java問題
1.什么是Java虛擬機?為什么Java被稱作是“平臺無關的編程語言”?
Java虛擬機是一個可以執行Java字節碼的虛擬機進程。Java源文件被編譯成能被Java虛擬機執行的字節碼文件。
Java被設計成允許應用程序可以運行在任意的平臺,而不需要程序員為每一個平臺單獨重寫或者是重新編譯。Java虛擬機讓這個變為可能,因為它知道底層硬件平臺的指令長度和其他特性。
2.JDK和JRE的區別是什么?
Java運行時環境(JRE)是將要執行Java程序的Java虛擬機。它同時也包含了執行applet需要的瀏覽器插件。Java開發工具包(JDK)是完整的Java軟件開發包,包含了JRE,編譯器和其他的工具(比如:JavaDoc,Java調試器),可以讓開發者開發、編譯、執行Java應用程序。
3.”static”關鍵字是什么意思?Java中是否可以覆蓋(override)一個private或者是static的方法?
“static”關鍵字表明一個成員變量或者是成員方法可以在沒有所屬的類的實例變量的情況下被訪問。
Java中static方法不能被覆蓋,因為方法覆蓋是基于運行時動態綁定的,而static方法是編譯時靜態綁定的。static方法跟類的任何實例都不相關,所以概念上不適用。
4.是否可以在static環境中訪問非static變量?
static變量在Java中是屬于類的,它在所有的實例中的值是一樣的。當類被Java虛擬機載入的時候,會對static變量進行初始化。如果你的代碼嘗試不用實例來訪問非static的變量,編譯器會報錯,因為這些變量還沒有被創建出來,還沒有跟任何實例關聯上。
5.Java支持的數據類型有哪些?什么是自動拆裝箱?
Java語言支持的8中基本數據類型是:
byte
short
int
long
float
double
boolean
char
自動裝箱是Java編譯器在基本數據類型和對應的對象包裝類型之間做的一個轉化。比如:把int轉化成Integer,double轉化成double,等等。反之就是自動拆箱。
6.Java中的方法覆蓋(Overriding)和方法重載(Overloading)是什么意思?
Java中的方法重載發生在同一個類里面兩個或者是多個方法的方法名相同但是參數不同的情況。與此相對,方法覆蓋是說子類重新定義了父類的方法。方法覆蓋必須有相同的方法名,參數列表和返回類型。覆蓋者可能不會限制它所覆蓋的方法的訪問。
7.Java中,什么是構造函數?什么是構造函數重載?什么是復制構造函數?
當新對象被創建的時候,構造函數會被調用。每一個類都有構造函數。在程序員沒有給類提供構造函數的情況下,Java編譯器會為這個類創建一個默認的構造函數。
Java中構造函數重載和方法重載很相似??梢詾橐粋€類創建多個構造函數。每一個構造函數必須有它自己唯一的參數列表。
Java不支持像C++中那樣的復制構造函數,這個不同點是因為如果你不自己寫構造函數的情況下,Java不會創建默認的復制構造函數。
8.Java支持多繼承么?
不支持,Java不支持多繼承。每個類都只能繼承一個類,但是可以實現多個接口。
9.接口和抽象類的區別是什么?
Java提供和支持創建抽象類和接口。它們的實現有共同點,不同點在于:
接口中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。
類可以實現很多個接口,但是只能繼承一個抽象類
類如果要實現一個接口,它必須要實現接口聲明的所有方法。但是,類可以不實現抽象類聲明的所有方法,當然,在這種情況下,類也必須得聲明成是抽象的。
抽象類可以在不提供接口方法實現的情況下實現接口。
Java接口中聲明的變量默認都是final的。抽象類可以包含非final的變量。
Java接口中的成員函數默認是public的。抽象類的成員函數可以是private,protected或者是public。
接口是絕對抽象的,不可以被實例化。抽象類也不可以被實例化,但是,如果它包含main方法的話是可以被調用的。
也可以參考JDK8中抽象類和接口的區別
10.什么是值傳遞和引用傳遞?
對象被值傳遞,意味著傳遞了對象的一個副本。因此,就算是改變了對象副本,也不會影響源對象的值。
對象被引用傳遞,意味著傳遞的并不是實際的對象,而是對象的引用。因此,外部對引用對象所做的改變會反映到所有的對象上。
Java線程
11.進程和線程的區別是什么?
進程是執行著的應用程序,而線程是進程內部的一個執行序列。一個進程可以有多個線程。線程又叫做輕量級進程。
12.創建線程有幾種不同的方式?你喜歡哪一種?為什么?
有三種方式可以用來創建線程:
繼承Thread類
實現Runnable接口
應用程序可以使用Executor框架來創建線程池
實現Runnable接口這種方式更受歡迎,因為這不需要繼承Thread類。在應用設計中已經繼承了別的對象的情況下,這需要多繼承(而Java不支持多繼承),只能實現接口。同時,線程池也是非常高效的,很容易實現和使用。
13.概括的解釋下線程的幾種可用狀態。
線程在執行過程中,可以處于下面幾種狀態:
就緒(Runnable):線程準備運行,不一定立馬就能開始執行。
運行中(Running):進程正在執行線程的代碼。
等待中(Waiting):線程處于阻塞的狀態,等待外部的處理結束。
睡眠中(Sleeping):線程被強制睡眠。
I/O阻塞(Blocked on I/O):等待I/O操作完成。
同步阻塞(Blocked on Synchronization):等待獲取鎖。
死亡(Dead):線程完成了執行。
14.同步方法和同步代碼塊的區別是什么?
在Java語言中,每一個對象有一把鎖。線程可以使用synchronized關鍵字來獲取對象上的鎖。synchronized關鍵字可應用在方法級別(粗粒度鎖)或者是代碼塊級別(細粒度鎖)。
15.在監視器(Monitor)內部,是如何做線程同步的?程序應該做哪種級別的同步?
監視器和鎖在Java虛擬機中是一塊使用的。監視器監視一塊同步代碼塊,確保一次只有一個線程執行同步代碼塊。每一個監視器都和一個對象引用相關聯。線程在獲取鎖之前不允許執行同步代碼。
16.什么是死鎖(deadlock)?
兩個進程都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是兩個進程都陷入了無限的等待中。
17.如何確保N個線程可以訪問N個資源同時又不導致死鎖?
使用多線程的時候,一種非常簡單的避免死鎖的方式就是:指定獲取鎖的順序,并強制線程按照指定的順序獲取鎖。因此,如果所有的線程都是以同樣的順序加鎖和釋放鎖,就不會出現死鎖了。
Java集合類
18.Java集合類框架的基本接口有哪些?
集合類接口指定了一組叫做元素的對象。集合類接口的每一種具體的實現類都可以選擇以它自己的方式對元素進行保存和排序。有的集合類允許重復的鍵,有些不允許。
Java集合類提供了一套設計良好的支持對一組對象進行操作的接口和類。Java集合類里面最基本的接口有:
Collection:代表一組對象,每一個對象都是它的子元素。
Set:不包含重復元素的Collection。
List:有順序的collection,并且可以包含重復元素。
Map:可以把鍵(key)映射到值(value)的對象,鍵不能重復。
19.為什么集合類沒有實現Cloneable和Serializable接口?
克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現相關的。因此,應該由集合類的具體實現來決定如何被克隆或者是序列化。
20.什么是迭代器(Iterator)?
Iterator接口提供了很多對集合元素進行迭代的方法。每一個集合類都包含了可以返回迭代器實例的
迭代方法。迭代器可以在迭代的過程中刪除底層集合的元素。
21.Iterator和ListIterator的區別是什么?
下面列出了他們的區別:
Iterator可用來遍歷Set和List集合,但是ListIterator只能用來遍歷List。
Iterator對集合只能是前向遍歷,ListIterator既可以前向也可以后向。
ListIterator實現了Iterator接口,并包含其他的功能,比如:增加元素,替換元素,獲取前一個和后一個元素的索引,等等。
22.快速失敗(fail-fast)和安全失敗(fail-safe)的區別是什么?
Iterator的安全失敗是基于對底層集合做拷貝,因此,它不受源集合上修改的影響。java.util包下面的所有的集合類都是快速失敗的,而java.util.concurrent包下面的所有的類都是安全失敗的??焖偈〉牡鲿伋?/p>
ConcurrentModificationException異常,而安全失敗的迭代器永遠不會拋出這樣的異常。
23.Java中的HashMap的工作原理是什么?
Java中的HashMap是以鍵值對(key-value)的形式存儲元素的。HashMap需要一個hash函數,它使用hashCode()和equals()方法來向集合/從集合添加和檢索元素。當調用put()方法的時候,HashMap會計算key的hash值,然后把鍵值對存儲在集合中合適的索引上。如果key已經存在了,value會被更新成新值。
HashMap的一些重要的特性是它的容量(capacity),負載因子(load factor)和擴容極限(threshold resizing)。
24.hashCode()和equals()方法的重要性體現在什么地方?
Java中的HashMap使用hashCode()和equals()方法來確定鍵值對的索引,當根據鍵獲取值的時候也會用到這兩個方法。如果沒有正確的實現這兩個方法,兩個不同的鍵可能會有相同的hash值,因此,可能會被集合認為是相等的。而且,這兩個方法也用來發現重復元素。所以這兩個方法的實現對HashMap的精確性和正確性是至關重要的。
25.HashMap和Hashtable有什么區別?
HashMap和Hashtable都實現了Map接口,因此很多特性非常相似。但是,他們有以下不同點:
HashMap允許鍵和值是null,而Hashtable不允許鍵或者值是null。
Hashtable是同步的,而HashMap不是。因此,HashMap更適合于單線程環境,而Hashtable適合于多線程環境。
HashMap提供了可供應用迭代的鍵的集合,因此,HashMap是快速失敗的。另一方面,Hashtable提供了對鍵的列舉(Enumeration)。
一般認為Hashtable是一個遺留的類。
26.數組(Array)和列表(ArrayList)有什么區別?什么時候應該使用Array而不是ArrayList?
下面列出了Array和ArrayList的不同點:
Array可以包含基本類型和對象類型,ArrayList只能包含對象類型。
Array大小是固定的,ArrayList的大小是動態變化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
對于基本類型數據,集合使用自動裝箱來減少編碼工作量。但是,當處理固定大小的基本數據類型的時候,這種方式相對比較慢。
27.ArrayList和LinkedList有什么區別?
ArrayList和LinkedList都實現了List接口,他們有以下的不同點:
ArrayList是基于索引的數據接口,它的底層是數組。它可以以O(1)時間復雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每一個元素都和它的前一個和后一個元素鏈接在一起,在這種情況下,查找某個元素的時間復雜度是O(n)。
相對于ArrayList,LinkedList的插入,添加,刪除操作速度更快,因為當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。
LinkedList比ArrayList更占內存,因為LinkedList為每一個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。
也可以參考ArrayList vs. LinkedList。
28.Comparable和Comparator接口是干什么的?列出它們的區別。
Java提供了只包含一個compareTo()方法的Comparable接口。這個方法可以個給兩個對象排序。具體來說,它返回負數,0,正數來表明輸入對象小于,等于,大于已經存在的對象。
Java提供了包含compare()和equals()兩個方法的Comparator接口。compare()方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小于,等于,大于第二個參數。equals()方法需要一個對象作為參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator并且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。
29.什么是Java優先級隊列(Priority Queue)?
PriorityQueue是一個基于優先級堆的無界隊列,它的元素是按照自然順序(natural order)排序的。在創建的時候,我們可以給它提供一個負責給元素排序的比較器。PriorityQueue不允許null值,因為他們沒有自然順序,或者說他們沒有任何的相關聯的比較器。最后,PriorityQueue不是線程安全的,入隊和出隊的時間復雜度是O(log(n))。
30.你了解大O符號(big-O notation)么?你能給出不同數據結構的例子么?
大O符號描述了當數據結構里面的元素增加的時候,算法的規模或者是性能在最壞的場景下有多么好。
大O符號也可用來描述其他的行為,比如:內存消耗。因為集合類實際上是數據結構,我們一般使用大O符號基于時間,內存和性能來選擇最好的實現。大O符號可以對大量數據的性能給出一個很好的說明。
31.如何權衡是使用無序的數組還是有序的數組?
有序數組最大的好處在于查找的時間復雜度是O(log n),而無序數組是O(n)。有序數組的缺點是插入操作的時間復雜度是O(n),因為值大的元素需要往后移動來給新元素騰位置。相反,無序數組的插入時間復雜度是常量O(1)。
32.Java集合類框架的最佳實踐有哪些?
根據應用的需要正確選擇要使用的集合的類型對性能非常重要,比如:假如元素的大小是固定的,而且能事先知道,我們就應該用Array而不是ArrayList。
有些集合類允許指定初始容量。因此,如果我們能估計出存儲的元素的數目,我們可以設置初始容量來避免重新計算hash值或者是擴容。
為了類型安全,可讀性和健壯性的原因總是要使用泛型。同時,使用泛型還可以避免運行時的ClassCastException。
使用JDK提供的不變類(immutable class)作為Map的鍵可以避免為我們自己的類實現hashCode()和equals()方法。
編程的時候接口優于實現。
底層的集合實際上是空的情況下,返回長度是0的集合或者是數組,不要返回null。
33.Enumeration接口和Iterator接口的區別有哪些?
Enumeration速度是Iterator的2倍,同時占用更少的內存。但是,Iterator遠遠比Enumeration安全,因為其他線程不能夠修改正在被iterator遍歷的集合里面的對象。同時,Iterator允許調用者刪除底層集合里面的元素,這對Enumeration來說是不可能的。
34.HashSet和TreeSet有什么區別?
HashSet是由一個hash表來實現的,因此,它的元素是無序的。add(),remove(),contains()方法的時間復雜度是O(1)。
另一方面,TreeSet是由一個樹形的結構來實現的,它里面的元素是有序的。因此,add(),remove(),contains()方法的時間復雜度是O(logn)。
垃圾收集器(Garbage Collectors)
35.Java中垃圾回收有什么目的?什么時候進行垃圾回收?
垃圾回收的目的是識別并且丟棄應用不再使用的對象來釋放和重用資源。
36.System.gc()和Runtime.gc()會做什么事情?
這兩個方法用來提示JVM要進行垃圾回收。但是,立即開始還是延遲進行垃圾回收是取決于JVM的。
37.finalize()方法什么時候被調用?析構函數(finalization)的目的是什么?
在釋放對象占用的內存之前,垃圾收集器會調用對象的finalize()方法。一般建議在該方法中釋放對象持有的資源。
38.如果對象的引用被置為null,垃圾收集器是否會立即釋放對象占用的內存?
不會,在下一個垃圾回收周期中,這個對象將是可被回收的。
39.Java堆的結構是什么樣子的?什么是堆中的永久代(Perm Gen space)?
JVM的堆是運行時數據區,所有類的實例和數組都是在堆上分配內存。它在JVM啟動的時候被創建。對象所占的堆內存是由自動內存管理系統也就是垃圾收集器回收。
堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直占據堆內存空間。
40.串行(serial)收集器和吞吐量(throughput)收集器的區別是什么?
吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等規模和大規模數據的應用程序。而串行收集器對大多數的小應用(在現代處理器上需要大概100M左右的內存)就足夠了。
41.在Java中,對象什么時候可以被垃圾回收?
當對象對當前使用這個對象的應用程序變得不可觸及的時候,這個對象就可以被回收了。
42.JVM的永久代中會發生垃圾回收么?
垃圾回收不會發生在永久代,如果永久代滿了或者是超過了臨界值,會觸發完全垃圾回收(Full GC)。如果你仔細查看垃圾收集器的輸出信息,就會發現永久代也是被回收的。這就是為什么正確的永久代大小對避免Full GC是非常重要的原因。請參考下Java8:從永久代到元數據區
(譯者注:Java8中已經移除了永久代,新加了一個叫做元數據區的native內存區)
異常處理
43.Java中的兩種異常類型是什么?他們有什么區別?
Java中有兩種異常:受檢查的(checked)異常和不受檢查的(unchecked)異常。不受檢查的異常不需要在方法或者是構造函數上聲明,就算方法或者是構造函數的執行可能會拋出這樣的異常,并且不受檢查的異常可以傳播到方法或者是構造函數的外面。相反,受檢查的異常必須要用throws語句在方法或者是構造函數上聲明。這里有Java異常處理的一些小建議。
44.Java中Exception和Error有什么區別?
Exception和Error都是Throwable的子類。Exception用于用戶程序可以捕獲的異常情況。Error定義了不期望被用戶程序捕獲的異常。
45.throw和throws有什么區別?
throw關鍵字用來在程序中明確的拋出異常,相反,throws語句用來表明方法不能處理的異常。每一個方法都必須要指定哪些異常不能處理,所以方法的調用者才能夠確保處理可能發生的異常,多個異常是用逗號分隔的。
45.異常處理的時候,finally代碼塊的重要性是什么?(譯者注:作者標題的序號弄錯了)
無論是否拋出異常,finally代碼塊總是會被執行。就算是沒有catch語句同時又拋出異常的情況下,finally代碼塊仍然會被執行。最后要說的是,finally代碼塊主要用來釋放資源,比如:I/O緩沖區,數據庫連接。
46.異常處理完成以后,Exception對象會發生什么變化?
Exception對象會在下一個垃圾回收過程中被回收掉。
47.finally代碼塊和finalize()方法有什么區別?
無論是否拋出異常,finally代碼塊都會執行,它主要是用來釋放應用占用的資源。finalize()方法是Object類的一個protected方法,它是在對象被垃圾回收之前由Java虛擬機來調用的。
Java小應用程序(Applet)
48.什么是Applet?
java applet是能夠被包含在HTML頁面中并且能被啟用了java的客戶端瀏覽器執行的程序。Applet主要用來創建動態交互的web應用程序。
49.解釋一下Applet的生命周期
applet可以經歷下面的狀態:
Init:每次被載入的時候都會被初始化。
Start:開始執行applet。
Stop:結束執行applet。
Destroy:卸載applet之前,做最后的清理工作。
50.當applet被載入的時候會發生什么?
首先,創建applet控制類的實例,然后初始化applet,最后開始運行。
51.Applet和普通的Java應用程序有什么區別?
applet是運行在啟用了java的瀏覽器中,Java應用程序是可以在瀏覽器之外運行的獨立的Java程序。但是,它們都需要有Java虛擬機。
進一步來說,Java應用程序需要一個有特定方法簽名的main函數來開始執行。Java applet不需要這樣的函數來開始執行。
最后,Java applet一般會使用很嚴格的安全策略,Java應用一般使用比較寬松的安全策略。
52.Java applet有哪些限制條件?
主要是由于安全的原因,給applet施加了以下的限制:
applet不能夠載入類庫或者定義本地方法。
applet不能在宿主機上讀寫文件。
applet不能讀取特定的系統屬性。
applet不能發起網絡連接,除非是跟宿主機。
applet不能夠開啟宿主機上其他任何的程序。
53.什么是不受信任的applet?
不受信任的applet是不能訪問或是執行本地系統文件的Java applet,默認情況下,所有下載的applet都是不受信任的。
54.從網絡上加載的applet和從本地文件系統加載的applet有什么區別?
當applet是從網絡上加載的時候,applet是由applet類加載器載入的,它受applet安全管理器的限制。
當applet是從客戶端的本地磁盤載入的時候,applet是由文件系統加載器載入的。
從文件系統載入的applet允許在客戶端讀文件,寫文件,加載類庫,并且也允許執行其他程序,但是,卻通不過字節碼校驗。
55.applet類加載器是什么?它會做哪些工作?
當applet是從網絡上加載的時候,它是由applet類加載器載入的。類加載器有自己的java名稱空間等級結構。類加載器會保證來自文件系統的類有唯一的名稱空間,來自網絡資源的類有唯一的名稱空間。
當瀏覽器通過網絡載入applet的時候,applet的類被放置于和applet的源相關聯的私有的名稱空間中。然后,那些被類加載器載入進來的類都是通過了驗證器驗證的。驗證器會檢查類文件格式是否遵守Java語言規范,確保不會出現堆棧溢出(stack overflow)或者下溢(underflow),傳遞給字節碼指令的參數是正確的。
56.applet安全管理器是什么?它會做哪些工作?
applet安全管理器是給applet施加限制條件的一種機制。瀏覽器可以只有一個安全管理器。安全管理器在啟動的時候被創建,之后不能被替換覆蓋或者是擴展。
Swing
57.彈出式選擇菜單(Choice)和列表(List)有什么區別
Choice是以一種緊湊的形式展示的,需要下拉才能看到所有的選項。Choice中一次只能選中一個選項。List同時可以有多個元素可見,支持選中一個或者多個元素。
58.什么是布局管理器?
布局管理器用來在容器中組織組件。
59.滾動條(Scrollbar)和滾動面板(JScrollPane)有什么區別?
Scrollbar是一個組件,不是容器。而ScrollPane是容器。ScrollPane自己處理滾動事件。
60.哪些Swing的方法是線程安全的?
只有3個線程安全的方法:repaint(), revalidate(), and invalidate()。
61.說出三種支持重繪(painting)的組件。
Canvas, Frame, Panel,和Applet支持重繪。
62.什么是裁剪(clipping)?
限制在一個給定的區域或者形狀的繪圖操作就做裁剪。
63.MenuItem和CheckboxMenuItem的區別是什么?
CheckboxMenuItem類繼承自MenuItem類,支持菜單選項可以選中或者不選中。
64.邊緣布局(BorderLayout)里面的元素是如何布局的?
BorderLayout里面的元素是按照容器的東西南北中進行布局的。
65.網格包布局(GridBagLayout)里面的元素是如何布局的?
GridBagLayout里面的元素是按照網格進行布局的。不同大小的元素可能會占據網格的多于1行或一列。因此,行數和列數可以有不同的大小。
66.Window和Frame有什么區別?
Frame類繼承了Window類,它定義了一個可以有菜單欄的主應用窗口。
67.裁剪(clipping)和重繪(repainting)有什么聯系?
當窗口被AWT重繪線程進行重繪的時候,它會把裁剪區域設置成需要重繪的窗口的區域。
68.事件監聽器接口(event-listener interface)和事件適配器(event-adapter)有什么關系?
事件監聽器接口定義了對特定的事件,事件處理器必須要實現的方法。事件適配器給事件監聽器接口提供了默認的實現。
69.GUI組件如何來處理它自己的事件?
GUI組件可以處理它自己的事件,只要它實現相對應的事件監聽器接口,并且把自己作為事件監聽器。
70.Java的布局管理器比傳統的窗口系統有哪些優勢?
Java使用布局管理器以一種一致的方式在所有的窗口平臺上擺放組件。因為布局管理器不會和組件的絕對大小和位置相綁定,所以他們能夠適應跨窗口系統的特定平臺的不同。
71.Java的Swing組件使用了哪種設計模式?
Java中的Swing組件使用了MVC(視圖-模型-控制器)設計模式。
JDBC
72.什么是JDBC?
JDBC是允許用戶在不同數據庫之間做選擇的一個抽象層。JDBC允許開發者用JAVA寫數據庫應用程序,而不需要關心底層特定數據庫的細節。
73.解釋下驅動(Driver)在JDBC中的角色。
JDBC驅動提供了特定廠商對JDBC API接口類的實現,驅動必須要提供java.sql包下面這些類的實現:Connection, Statement, PreparedStatement,CallableStatement, ResultSet和Driver。
74.Class.forName()方法有什么作用?
這個方法用來載入跟數據庫建立連接的驅動。
75.PreparedStatement比Statement有什么優勢?
PreparedStatements是預編譯的,因此,性能會更好。同時,不同的查詢參數值,PreparedStatement可以重用。
76.什么時候使用CallableStatement?用來準備CallableStatement的方法是什么?
CallableStatement用來執行存儲過程。存儲過程是由數據庫存儲和提供的。存儲過程可以接受輸入參數,也可以有返回結果。非常鼓勵使用存儲過程,因為它提供了安全性和模塊化。準備一個CallableStatement的方法是:
1CallableStament.prepareCall();
77.數據庫連接池是什么意思?
像打開關閉數據庫連接這種和數據庫的交互可能是很費時的,尤其是當客戶端數量增加的時候,會消耗大量的資源,成本是非常高的??梢栽趹梅掌鲉拥臅r候建立很多個數據庫連接并維護在一個池中。連接請求由池中的連接提供。在連接使用完畢以后,把連接歸還到池中,以用于滿足將來更多的請求。
遠程方法調用(RMI)
78.什么是RMI?
Java遠程方法調用(Java RMI)是Java API對遠程過程調用(RPC)提供的面向對象的等價形式,支持直接傳輸序列化的Java對象和分布式垃圾回收。遠程方法調用可以看做是激活遠程正在運行的對象上的方法的步驟。RMI對調用者是位置透明的,因為調用者感覺方法是執行在本地運行的對象上的??聪翿MI的一些注意事項。
79.RMI體系結構的基本原則是什么?
RMI體系結構是基于一個非常重要的行為定義和行為實現相分離的原則。RMI允許定義行為的代碼和實現行為的代碼相分離,并且運行在不同的JVM上。
80.RMI體系結構分哪幾層?
RMI體系結構分以下幾層:
存根和骨架層(Stub and Skeleton layer):這一層對程序員是透明的,它主要負責攔截客戶端發出的方法調用請求,然后把請求重定向給遠程的RMI服務。
遠程引用層(Remote Reference Layer):RMI體系結構的第二層用來解析客戶端對服務端遠程對象的引用。這一層解析并管理客戶端對服務端遠程對象的引用。連接是點到點的。
傳輸層(Transport layer):這一層負責連接參與服務的兩個JVM。這一層是建立在網絡上機器間的TCP/IP連接之上的。它提供了基本的連接服務,還有一些防火墻穿透策略。
81.RMI中的遠程接口(Remote Interface)扮演了什么樣的角色?
遠程接口用來標識哪些方法是可以被非本地虛擬機調用的接口。遠程對象必須要直接或者是間接實現遠程接口。實現了遠程接口的類應該聲明被實現的遠程接口,給每一個遠程對象定義構造函數,給所有遠程接口的方法提供實現。
82.java.rmi.Naming類扮演了什么樣的角色?
java.rmi.Naming類用來存儲和獲取在遠程對象注冊表里面的遠程對象的引用。Naming類的每一個方法接收一個URL格式的String對象作為它的參數。
83.RMI的綁定(Binding)是什么意思?
綁定是為了查詢找遠程對象而給遠程對象關聯或者是注冊以后會用到的名稱的過程。遠程對象可以使用Naming類的bind()或者rebind()方法跟名稱相關聯。
84.Naming類的bind()和rebind()方法有什么區別?
bind()方法負責把指定名稱綁定給遠程對象,rebind()方法負責把指定名稱重新綁定到一個新的遠程對象。如果那個名稱已經綁定過了,先前的綁定會被替換掉。
85.讓RMI程序能正確運行有哪些步驟?
為了讓RMI程序能正確運行必須要包含以下幾個步驟:
編譯所有的源文件。
使用rmic生成stub。
啟動rmiregistry。
啟動RMI服務器。
運行客戶端程序。
86.RMI的stub扮演了什么樣的角色?
遠程對象的stub扮演了遠程對象的代表或者代理的角色。調用者在本地stub上調用方法,它負責在遠程對象上執行方法。當stub的方法被調用的時候,會經歷以下幾個步驟:
初始化到包含了遠程對象的JVM的連接。
序列化參數到遠程的JVM。
等待方法調用和執行的結果。
反序列化返回的值或者是方法沒有執行成功情況下的異常。
把值返回給調用者。
87.什么是分布式垃圾回收(DGC)?它是如何工作的?
DGC叫做分布式垃圾回收。RMI使用DGC來做自動垃圾回收。因為RMI包含了跨虛擬機的遠程對象的引用,垃圾回收是很困難的。DGC使用引用計數算法來給遠程對象提供自動內存管理。
88.RMI中使用RMI安全管理器(RMISecurityManager)的目的是什么?
RMISecurityManager使用下載好的代碼提供可被RMI應用程序使用的安全管理器。如果沒有設置安全管理器,RMI的類加載器就不會從遠程下載任何的類。
89.解釋下Marshalling和demarshalling。
當應用程序希望把內存對象跨網絡傳遞到另一臺主機或者是持久化到存儲的時候,就必須要把對象在內存里面的表示轉化成合適的格式。這個過程就叫做Marshalling,反之就是demarshalling。
90.解釋下Serialization和Deserialization。
Java提供了一種叫做對象序列化的機制,他把對象表示成一連串的字節,里面包含了對象的數據,對象的類型信息,對象內部的數據的類型信息等等。因此,序列化可以看成是為了把對象存儲在磁盤上或者是從磁盤上讀出來并重建對象而把對象扁平化的一種方式。反序列化是把對象從扁平狀態轉化成活動對象的相反的步驟。
Servlet
91.什么是Servlet?
Servlet是用來處理客戶端請求并產生動態網頁內容的Java類。Servlet主要是用來處理或者是存儲HTML表單提交的數據,產生動態內容,在無狀態的HTTP協議下管理狀態信息。
92.說一下Servlet的體系結構。
所有的Servlet都必須要實現的核心的接口是javax.servlet.Servlet。每一個Servlet都必須要直接或者是間接實現這個接口,或者是繼承javax.servlet.GenericServlet或者javax.servlet.http.HTTPServlet。最后,Servlet使用多線程可以并行的為多個請求服務。
93.Applet和Servlet有什么區別?
Applet是運行在客戶端主機的瀏覽器上的客戶端Java程序。而Servlet是運行在web服務器上的服務端的組件。applet可以使用用戶界面類,而Servlet沒有用戶界面,相反,Servlet是等待客戶端的HTTP請求,然后為請求產生響應。
94.GenericServlet和HttpServlet有什么區別?
GenericServlet是一個通用的協議無關的Servlet,它實現了Servlet和ServletConfig接口。繼承自GenericServlet的Servlet應該要覆蓋service()方法。最后,為了開發一個能用在網頁上服務于使用HTTP協議請求的Servlet,你的Servlet必須要繼承自HttpServlet。這里有Servlet的例子。
95.解釋下Servlet的生命周期。
對每一個客戶端的請求,Servlet引擎載入Servlet,調用它的init()方法,完成Servlet的初始化。然后,Servlet對象通過為每一個請求單獨調用service()方法來處理所有隨后來自客戶端的請求,最后,調用Servlet(譯者注:這里應該是Servlet而不是server)的destroy()方法把Servlet刪除掉。
96.doGet()方法和doPost()方法有什么區別?
doGet:GET方法會把名值對追加在請求的URL后面。因為URL對字符數目有限制,進而限制了用在客戶端請求的參數值的數目。并且請求中的參數值是可見的,因此,敏感信息不能用這種方式傳遞。
doPOST:POST方法通過把請求參數值放在請求體中來克服GET方法的限制,因此,可以發送的參數的數目是沒有限制的。最后,通過POST請求傳遞的敏感信息對外部客戶端是不可見的。
97.什么是Web應用程序?
Web應用程序是對Web或者是應用服務器的動態擴展。有兩種類型的Web應用:面向表現的和面向服務的。面向表現的Web應用程序會產生包含了很多種標記語言和動態內容的交互的web頁面作為對請求的響應。而面向服務的Web應用實現了Web服務的端點(endpoint)。一般來說,一個Web應用可以看成是一組安裝在服務器URL名稱空間的特定子集下面的Servlet的集合。
98.什么是服務端包含(Server Side Include)?
服務端包含(SSI)是一種簡單的解釋型服務端腳本語言,大多數時候僅用在Web上,用servlet標簽嵌入進來。SSI最常用的場景把一個或多個文件包含到Web服務器的一個Web頁面中。當瀏覽器訪問Web頁面的時候,Web服務器會用對應的servlet產生的文本來替換Web頁面中的servlet標簽。
99.什么是Servlet鏈(Servlet Chaining)?
Servlet鏈是把一個Servlet的輸出發送給另一個Servlet的方法。第二個Servlet的輸出可以發送給第三個Servlet,依次類推。鏈條上最后一個Servlet負責把響應發送給客戶端。
100.如何知道是哪一個客戶端的機器正在請求你的Servlet?
ServletRequest類可以找出客戶端機器的IP地址或者是主機名。getRemoteAddr()方法獲取客戶端主機的IP地址,getRemoteHost()可以獲取主機名。看下這里的例子。
101.HTTP響應的結構是怎么樣的?
HTTP響應由三個部分組成:
狀態碼(Status Code):描述了響應的狀態??梢杂脕頇z查是否成功的完成了請求。請求失敗的情況下,狀態碼可用來找出失敗的原因。如果Servlet沒有返回狀態碼,默認會返回成功的狀態碼HttpServletResponse.SC_OK。
HTTP頭部(HTTP Header):它們包含了更多關于響應的信息。比如:頭部可以指定認為響應過期的過期日期,或者是指定用來給用戶安全的傳輸實體內容的編碼格式。如何在Serlet中檢索HTTP的頭部看這里。
主體(Body):它包含了響應的內容。它可以包含HTML代碼,圖片,等等。主體是由傳輸在HTTP消息中緊跟在頭部后面的數據字節組成的。
102.什么是cookie?session和cookie有什么區別?
cookie是Web服務器發送給瀏覽器的一塊信息。瀏覽器會在本地文件中給每一個Web服務器存儲cookie。以后瀏覽器在給特定的Web服務器發請求的時候,同時會發送所有為該服務器存儲的cookie。下面列出了session和cookie的區別:
無論客戶端瀏覽器做怎么樣的設置,session都應該能正常工作??蛻舳丝梢赃x擇禁用cookie,但是,session仍然是能夠工作的,因為客戶端無法禁用服務端的session。
在存儲的數據量方面session和cookies也是不一樣的。session能夠存儲任意的Java對象,cookie只能存儲String類型的對象。
103.瀏覽器和Servlet通信使用的是什么協議?
瀏覽器和Servlet通信使用的是HTTP協議。
104.什么是HTTP隧道?
HTTP隧道是一種利用HTTP或者是HTTPS把多種網絡協議封裝起來進行通信的技術。因此,HTTP協議扮演了一個打通用于通信的網絡協議的管道的包裝器的角色。把其他協議的請求掩蓋成HTTP的請求就是HTTP隧道。
105.sendRedirect()和forward()方法有什么區別?
sendRedirect()方法會創建一個新的請求,而forward()方法只是把請求轉發到一個新的目標上。重定向(redirect)以后,之前請求作用域范圍以內的對象就失效了,因為會產生一個新的請求,而轉發(forwarding)以后,之前請求作用域范圍以內的對象還是能訪問的。一般認為sendRedirect()比forward()要慢。
106.什么是URL編碼和URL解碼?
URL編碼是負責把URL里面的空格和其他的特殊字符替換成對應的十六進制表示,反之就是解碼。
JSP
107.什么是JSP頁面?
JSP頁面是一種包含了靜態數據和JSP元素兩種類型的文本的文本文檔。靜態數據可以用任何基于文本的格式來表示,比如:HTML或者XML。JSP是一種混合了靜態內容和動態產生的內容的技術。這里看下JSP的例子。
108.JSP請求是如何被處理的?
瀏覽器首先要請求一個以.jsp擴展名結尾的頁面,發起JSP請求,然后,Web服務器讀取這個請求,使用JSP編譯器把JSP頁面轉化成一個Servlet類。需要注意的是,只有當第一次請求頁面或者是JSP文件發生改變的時候JSP文件才會被編譯,然后服務器調用servlet類,處理瀏覽器的請求。一旦請求執行結束,servlet會把響應發送給客戶端。這里看下如何在JSP中獲取請求參數。
109.JSP有什么優點?
下面列出了使用JSP的優點:
JSP頁面是被動態編譯成Servlet的,因此,開發者可以很容易的更新展現代碼。
JSP頁面可以被預編譯。
JSP頁面可以很容易的和靜態模板結合,包括:HTML或者XML,也可以很容易的和產生動態內容的代碼結合起來。
開發者可以提供讓頁面設計者以類XML格式來訪問的自定義的JSP標簽庫。
開發者可以在組件層做邏輯上的改變,而不需要編輯單獨使用了應用層邏輯的頁面。
110.什么是JSP指令(Directive)?JSP中有哪些不同類型的指令?
Directive是當JSP頁面被編譯成Servlet的時候,JSP引擎要處理的指令。Directive用來設置頁面級別的指令,從外部文件插入數據,指定自定義的標簽庫。Directive是定義在 之間的。下面列出了不同類型的Directive:
包含指令(Include directive):用來包含文件和合并文件內容到當前的頁面。
頁面指令(Page directive):用來定義JSP頁面中特定的屬性,比如錯誤頁面和緩沖區。
Taglib指令:用來聲明頁面中使用的自定義的標簽庫。
111.什么是JSP動作(JSP action)?
JSP動作以XML語法的結構來控制Servlet引擎的行為。當JSP頁面被請求的時候,JSP動作會被執行。它們可以被動態的插入到文件中,重用JavaBean組件,轉發用戶到其他的頁面,或者是給Java插件產生HTML代碼。下面列出了可用的動作:
jsp:include-當JSP頁面被請求的時候包含一個文件。
jsp:useBean-找出或者是初始化Javabean。
jsp:setProperty-設置JavaBean的屬性。
jsp:getProperty-獲取JavaBean的屬性。
jsp:forward-把請求轉發到新的頁面。
jsp:plugin-產生特定瀏覽器的代碼。
112.什么是Scriptlets?
JSP技術中,scriptlet是嵌入在JSP頁面中的一段Java代碼。scriptlet是位于標簽內部的所有的東西,在標簽與標簽之間,用戶可以添加任意有效的scriplet。
113.聲明(Decalaration)在哪里?
聲明跟Java中的變量聲明很相似,它用來聲明隨后要被表達式或者scriptlet使用的變量。添加的聲明必須要用開始和結束標簽包起來。
114.什么是表達式(Expression)?
【列表很長,可以分上、中、下發布】
JSP表達式是Web服務器把腳本語言表達式的值轉化成一個String對象,插入到返回給客戶端的數據流中。表達式是在這兩個標簽之間定義的。
115.隱含對象是什么意思?有哪些隱含對象?
JSP隱含對象是頁面中的一些Java對象,JSP容器讓這些Java對象可以為開發者所使用。開發者不用明確的聲明就可以直接使用他們。JSP隱含對象也叫做預定義變量。下面列出了JSP頁面中的隱含對象:
application
page
request
response
session
exception
out
config
pageContext
Java開發崗位面試題歸類匯總
一、Java基礎
1. String類為什么是final的
2. HashMap的源碼,實現原理,底層結構。
3. 說說你知道的幾個Java集合類:list、set、queue、map實現類。
4. 描述一下ArrayList和LinkedList各自實現和區別
5. Java中的隊列都有哪些,有什么區別。
6. 反射中,Class.forName和classloader的區別。
7. Java7、Java8的新特性
8. Java數組和鏈表兩種結構的操作效率,在哪些情況下(從開頭開始,從結尾開始,從中間開始),哪些操作(插入,查找,刪除)的效率高。
9. Java內存泄露的問題調查定位:jmap,jstack的使用等等。
10. string、stringbuilder、stringbuffer區別
11. hashtable和hashmap的區別
13 .異常的結構,運行時異常和非運行時異常,各舉個例子。
14. String 類的常用方法
16. Java 的引用類型有哪幾種
17. 抽象類和接口的區別
18. java的基礎類型和字節大小
19. Hashtable,HashMap,ConcurrentHashMap底層實現原理與線程安全問題。
20. 如果不讓你用Java Jdk提供的工具,你自己實現一個Map,你怎么做。說了好久,說了HashMap源代碼,如果我做,就會借鑒HashMap的原理,說了一通HashMap實現。
21. Hash沖突怎么辦?哪些解決散列沖突的方法?
22. HashMap沖突很厲害,最差性能,你會怎么解決?從O(n)提升到log(n)。
23. rehash
24. hashCode() 與 equals() 生成算法、方法怎么重寫。
二、Java IO
1. 講講IO里面的常見類,字節流、字符流、接口、實現類、方法阻塞。
2. 講講NIO
3. String 編碼UTF-8 和GBK的區別?
4. 什么時候使用字節流、什么時候使用字符流?
5. 遞歸讀取文件夾下的文件,代碼怎么實現?
三、Java Web
1. session和cookie的區別和聯系,session的生命周期,多個服務部署時session管理。
2. servlet的一些相關問題
3. webservice相關問題
4. jdbc連接,forname方式的步驟,怎么聲明使用一個事務。
5. 無框架下配置web.xml的主要配置內容
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老年代
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語句和SQL優化
7. 索引的數據結構,B+樹
8. 事務的四個特性,以及各自的特點(原子、隔離)等等,項目怎么解決這些問題。
9. 數據庫的鎖:行鎖,表鎖;樂觀鎖,悲觀鎖
10. 數據庫事務的幾種粒度
11. 關系型和非關系型數據庫區別
九、設計模式
1. 單例模式:飽漢、餓漢。以及餓漢中的延遲加載,雙重檢查。
2. 工廠模式、裝飾者模式、觀察者模式。
3. 工廠方法模式的優點(低耦合、高內聚,開放封閉原則)
十、算法
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. 你的項目中使用過緩存機制嗎?有沒用用戶非本地緩存
十二、其他
Linux 基本操作命令
文件和目錄管理
創建和刪除
創建:mkdir
刪除:rm
刪除非空目錄:rm -rf file 目錄
刪除日志 rm log (等價: $find ./-name “log” -exec rm {} ; )
移動:mv
復制:cp (復制目錄:cp -r)
創建文件 touch
查看
顯示當前目錄下的文件 ls
按時間排序,以列表的方式顯示目錄項 ls -lrt
ls -l
查看文件內容 cat 可以加 more 、less 控制輸出的內容的大小
cat a.text
cat a.text | more
cat a.text| less
權限
改變文件的擁有者 chown
改變文件讀、寫、執行等屬性 chmod
遞歸子目錄修改:chown -R tuxapp source/
增加腳本可執行權限:chmod a+x myscript
管道和重定向
把前一個命令的執行結果當做后一個命令的輸入 |
串聯:使用分號 ;
前面成功,則執行后面一條,否則,不執行: &&
前面失敗,則后一條執行: ||
ls /proc && echo suss! || echo failed.
文本處理
文件查找 find
find 參數很多,本文只介紹幾個常用的
-name 按名字查找
-type 按類型
-atime 訪問時間
find . -atime 7 -type f -print
find . -type d -print //只列出所有目錄
find / -name "hello.c" 查找hello.c文件
文本查找 grep
grep match_patten file // 默認訪問匹配行
常用參數
-o 只輸出匹配的文本行 VS -v 只輸出沒有匹配的文本行
-c 統計文件中包含文本的次數
grep -c “text” filename
-n 打印匹配的行號
-i 搜索時忽略大小寫
-l 只打印文件名
grep "class" . -R -n # 在多級目錄中對文本遞歸搜索(程序員搜代碼的最愛)
cat LOG.* | tr a-z A-Z | grep "FROM " | grep "WHERE" > b #將日志中的所有帶where條件的sql查找查找出來
文本替換 sed
sed [options] 'command' file(s)
首處替換
sed 's/text/replace_text/' file //替換每一行的第一處匹配的text
全局替換
sed 's/text/replace_text/g' file
默認替換后,輸出替換后的內容,如果需要直接替換原文件,使用 -i:
sed -i 's/text/repalce_text/g' file
移除空白行
sed '/^$/d' file
sed 's/book/books/' file #替換文本中的字符串:
sed 's/book/books/g' file
sed '/^$/d' file #刪除空白行
數據流處理 awk
詳細教程可以查看 http://awk.readthedocs.io/en/latest/chapte...
awk ' BEGIN{ statements } statements2 END{ statements } '
工作流程
1. 執行 begin 中語句塊;
2. 從文件或 stdin 中讀入一行,然后執行 statements2,重復這個過程,直到文件全部被讀取完畢;
3. 執行 end 語句塊;
特殊變量
NR: 表示記錄數量,在執行過程中對應當前行號;
NF: 表示字段數量,在執行過程總對應當前行的字段數;
$0: 這個變量包含執行過程中當前行的文本內容;
$1: 第一個字段的文本內容;
$2: 第二個字段的文本內容;
awk '{print $2, $3}' file
# 日志格式:'$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'
#統計日志中訪問最多的10個IP
awk '{a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
排序 sort
-n 按數字進行排序 VS -d 按字典序進行排序
-r 逆序排序
-k N 指定按第 N 列排序
sort -nrk 1 data.txt
sort -bd data // 忽略像空格之類的前導空白字符
去重 uniq
消除重復行
sort unsort.txt | uniq
統計 wc
wc -l file // 統計行數
wc -w file // 統計單詞數
wc -c file // 統計字符數
Java 知識點
1Java 基礎
1、HashMap的源碼,實現原理,JDK8中對HashMap做了怎樣的優化。
2、HaspMap擴容是怎樣擴容的,為什么都是2的N次冪的大小。
3、HashMap,HashTable,ConcurrentHashMap的區別。
4、極高并發下HashTable和ConcurrentHashMap哪個性能更好,為什么,如何實現的。
5、HashMap在高并發下如果沒有處理線程安全會有怎樣的安全隱患,具體表現是什么。
6、java中四種修飾符的限制范圍。
7、Object類中的方法。
8、接口和抽象類的區別,注意JDK8的接口可以有實現。
9、動態代理的兩種方式,以及區別。
10、Java序列化的方式。
11、傳值和傳引用的區別,Java是怎么樣的,有沒有傳值引用。
12、一個ArrayList在循環過程中刪除,會不會出問題,為什么。
2JVM
1、JVM的內存結構。
2、JVM方法棧的工作過程,方法棧和本地方法棧有什么區別。
3、JVM的棧中引用如何和堆中的對象產生關聯。
4、可以了解一下逃逸分析技術。
5、GC的常見算法,CMS以及G1的垃圾回收過程,CMS的各個階段哪兩個是Stop the world的,CMS會不會產生碎片,G1的優勢。
6、標記清除和標記整理算法的理解以及優缺點。
7、eden survivor區的比例,為什么是這個比例,eden survivor的工作過程。
8、JVM如何判斷一個對象是否該被GC,可以視為root的都有哪幾種類型。
9、強軟弱虛引用的區別以及GC對他們執行怎樣的操作。
10、Java是否可以GC直接內存。
11、Java類加載的過程。
12、雙親委派模型的過程以及優勢。
13、常用的JVM調優參數。
14、dump文件的分析。
15、Java有沒有主動觸發GC的方式(沒有)。
3數據結構與算法
1、B+樹
2、快速排序,堆排序,插入排序(八大排序算法)
3、一致性Hash算法,一致性Hash算法的應用
4多線程
1、Java實現多線程有哪幾種方式。
2、Callable和Future的了解。
3、線程池的參數有哪些,在線程池創建一個線程的過程。
4、volitile關鍵字的作用,原理。
5、synchronized關鍵字的用法,優缺點。
6、Lock接口有哪些實現類,使用場景是什么。
7、可重入鎖的用處及實現原理,寫時復制的過程,讀寫鎖,分段鎖(ConcurrentHashMap中的segment)。
8、悲觀鎖,樂觀鎖,優缺點,CAS有什么缺陷,該如何解決。
9、ABC三個線程如何保證順序執行。
10、線程的狀態都有哪些。
11、sleep和wait的區別。
12、notify和notifyall的區別。
13、ThreadLocal的了解,實現原理。
5分布式
1、分布式事務的控制。分布式鎖如何設計。
2、分布式session如何設計。
3、dubbo的組件有哪些,各有什么作用。
4、zookeeper的負載均衡算法有哪些。
5、dubbo是如何利用接口就可以通信的。
6框架相關
1、SpringMVC的Controller是如何將參數和前端傳來的數據一一對應的。
2、Mybatis如何找到指定的Mapper的,如何完成查詢的。
3、Quartz是如何完成定時任務的。自定義注解的實現。
4、Spring使用了哪些設計模式。Spring的IOC有什么優勢。
5、Spring如何維護它擁有的bean。
6、一些較新的東西JDK8的新特性,流的概念及優勢,為什么有這種優勢。
7、區塊鏈了解如何設計雙11交易總額面板,要做到高并發高可用
Java面試題之:Java中的幾種線程池
Java 通過 Executors 提供四種線程池
CachedThreadPool():可緩存線程池。
FixedThreadPool():定長線程池。
ScheduledThreadPool():定時線程池。
SingleThreadExecutor():單線程化的線程池。
ThreadPoolExecutor 的執行流程
線程數量未達到 corePoolSize,則新建一個線程 (核心線程) 執行任務。
線程數量達到了 corePools,則將任務移入隊列等待。
隊列已滿,新建線程 (非核心線程) 執行任務。
隊列已滿,總線程數又達到了 maximumPoolSize,就會由 (RejectedExecutionHandler) 拋出異常 (拒絕策略)
新建線程 -> 達到核心數 -> 加入隊列 -> 新建線程(非核心) -> 達到最大數 -> 觸發拒絕策略
ThreadPoolExecutor 的幾個參數
corePoolSize:核心池的大小,這個參數跟后面講述的線程池的實現原理有非常大的關系。在創建了線程池后,默認情況下,線程池中并沒有任何線程,而是等待有任務到來才創建線程去執行任務,除非調用了 prestartAllCoreThreads () 或者 prestartCoreThread () 方法,從這 2 個方法的名字就可以看出,是預創建線程的意思,即在沒有任務到來之前就創建 corePoolSize 個線程或者一個線程。默認情況下,在創建了線程池后,線程池中的線程數為 0,當有任務來之后,就會創建一個線程去執行任務,當線程池中的線程數目達到 corePoolSize 后,就會把到達的任務放到緩存隊列當中。
maximumPoolSize:線程池最大線程數,這個參數也是一個非常重要的參數,它表示在線程池中最多能創建多少個線程;如果當前阻塞隊列滿了,且繼續提交任務,則創建新的線程執行任務,前提是當前線程數小于 maximumPoolSize;當阻塞隊列是無界隊列, 則 maximumPoolSize 不起作用,因為無法提交至核心線程池的線程會一直持續地放入 workQueue (工作隊列) 中。
keepAliveTime:表示線程沒有任務執行時最多保持多久時間會終止。默認情況下,只有當線程池中的線程數大于 corePoolSize 時,keepAliveTime 才會起作用,直到線程池中的線程數不大于 corePoolSize,即當線程池中線程數大于 corePoolSize 時, 如果一個線程空閑的時間達到 keepAliveTime,則會終止,直到線程池中的線程數不超過 corePoolSize。但是如果調用了 allowCoreThreadTimeOut (boolean) 方法,在線程池中的線程數不大于 corePoolSize 時,keepAliveTime 參數也會起作用, 直到線程池中的線程數為 0。
allowCoreThreadTimeout:默認情況下超過 keepAliveTime 的時候,核心線程不會退出,可通過將該參數設置為 true,讓核心線程也退出。
unit:可以指定 keepAliveTime 的時間單位。
workQueue
ArrayBlockingQueue 有界隊列,需要指定隊列大小。
LinkedBlockingQueue 若指定大小則和 ArrayBlockingQueue 類似,若不指定大小則默認能存儲 Integer.MAX_VALUE 個任務,相當于無界隊列,此時 maximumPoolSize 值其實是無意義的。
SynchronousQueue 同步阻塞隊列,當有任務添加進來后,必須有線程從隊列中取出,當前線程才會被釋放,newCachedThreadPool 就使用這種隊列。
RejectedExecutionHandler:線程數和隊列都滿的情況下,線程池會執行的拒絕策略,有四個 (也可以使用自定義的策略)。
線程池的四種拒絕策略
AbortPolicy:不執行新任務,直接拋出異常,提示線程池已滿,線程池默認策略。
DiscardPolicy:不執行新任務,也不拋出異常,基本上為靜默模式。
DisCardOldSetPolicy:將消息隊列中的第一個任務替換為當前新進來的任務執行。
CallerRunPolicy:拒絕新任務進入,如果該線程池還沒被關閉,那么這個新的任務在執行線程中被調用。
Executors 和 ThreadPoolExecutor 創建線程的區別
Executors
newFixedThreadPool 和 newSingleThreadExecutor: 主要問題是堆積的請求處理隊列可能會耗費非常大的內存,甚至 OOM。
newCachedThreadPool 和 newScheduledThreadPool: 主要問題是線程數最大數是 Integer.MAX_VALUE (2 的 31 次方 - 1,int 類型最大值),可能會創建數量非常多的線程,甚至 OOM。
ThreadPoolExecutor
創建線程池方式只有一種,就是走它的構造函數,參數自己指定。
為什么使用線程池
減少了創建和銷毀線程的次數,每個工作線程都可以被重復利用,可執行多個任務。
運用線程池能有效的控制線程最大并發數,可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,而把服務器累趴下 (每個線程需要大約 1MB 內存,線程開的越多,消耗的內存也就越大,最后死機)。
對線程進行一些簡單的管理,比如:延時執行、定時循環執行的策略等,運用線程池都能進行很好的實現。
如何向線程池中提交任務
可以通過 execute () 或 submit () 兩個方法向線程池提交任務。
execute () 方法沒有返回值,所以無法判斷任務知否被線程池執行成功。
submit () 方法返回一個 future, 那么我們可以通過這個 future 來判斷任務是否執行成功,通過 future 的 get 方法來獲取返回值。
如何關閉線程池
可以通過 shutdown () 或 shutdownNow () 方法來關閉線程池。
shutdown 的原理是只是將線程池的狀態設置成 SHUTDOWN 狀態,然后中斷所有沒有正在執行任務的線程。
shutdownNow 的原理是遍歷線程池中的工作線程,然后逐個調用線程的 interrupt 方法來中斷線程,所以無法響應中斷的任務可能永遠無法終止。shutdownNow 會首先將線程池的狀態設置成 STOP,然后嘗試停止所有的正在執行或暫停任務的線程,并返回等待執行任務的列表。
萬萬沒想到,JVM內存結構的面試題可以問的這么難?
大家嘗試著回答一下以下問題:
1、JVM管理的內存結構是怎樣的?
2、不同的虛擬機在實現運行時內存的時候有什么區別?
3、運行時數據區中哪些區域是線程共享的?哪些是獨享的?
4、除了JVM運行時內存以外,還有什么區域可以用嗎?
5、堆和棧的區別是什么?
6、Java中的數組是存儲在堆上還是棧上的?
7、Java中的對象創建有多少種方式?
8、Java中對象創建的過程是怎么樣的?
9、Java中的對象一定在堆上分配內存嗎?
10、如何獲取堆和棧的dump文件?
以上10道題,如果您可以全部準確無誤的回答的話,那說明你真的很了解JVM的內存結構以及內存分配相關的知識了,如果有哪些知識點是不了解的,那么本文正好可以幫你答疑解惑。
JVM管理的內存結構是怎樣的?
Java虛擬機在執行Java程序的過程中會把他所管理的內存劃分為若干個不同的數據區域。《Java虛擬機規范》中規定了JVM所管理的內存需要包括一下幾個運行時區域:

主要包含了PC寄存器(程序計數器)、Java虛擬機棧、本地方法棧、Java堆、方法區以及運行時常量池。
各個區域有各自不同的作用,關于各個區域的作用就不在本文中相信介紹了。
但是,需要注意的是,上面的區域劃分只是邏輯區域,對于有些區域的限制是比較松的,所以不同的虛擬機廠商在實現上,甚至是同一款虛擬機的不同版本也是不盡相同的。
不同的虛擬機在實現運行時內存的時候有什么區別?
前面提到過《Java虛擬機規范》定義的JVM運行時所需的內存區域,不同的虛擬機實現上有所不同,而在這么多區域中,規范對于方法區的管理是最寬松的,規范中關于這部分的描述如下:
方法區在虛擬機啟動的時候創建,雖然方法區是堆的邏輯組成部分,但是簡單的虛擬機實現可以選擇在這個區域不實現垃圾收集與壓縮。本版本的規范也不限定實現方法區的內存位置和代碼編譯的管理策略。方法區的容量可以是固定的,也可以隨著程序執行的需求動態擴展,并在不需要過多的空間時自行收縮。方法區在實際內存空間站可以是不連續的。
這一規定,可以說是給了虛擬機廠商很大的自由。
虛擬機規范對方法區實現的位置并沒有明確要求,在最著名的HotSopt虛擬機實現中(在Java 8 之前),方法區僅是邏輯上的獨立區域,在物理上并沒有獨立于堆而存在,而是位于永久代中。所以,這時候方法區也是可以被垃圾回收的。
實踐證明,JVM中存在著大量的聲明短暫的對象,還有一些生命周期比較長的對象。為了對他們采用不同的收集策略,采用了分代收集算法,所以HotSpot虛擬機把的根據對象的年齡不同,把堆分位新生代、老年代和永久代。
在Java 8中 ,HotSpot虛擬機移除了永久代,使用本地內存來存儲類元數據信息并稱之為:元空間(Metaspace)

運行時數據區中哪些區域是線程共享的?哪些是獨享的?
在JVM運行時內存區域中,PC寄存器、虛擬機棧和本地方法棧是線程獨享的。
而Java堆、方法區是線程共享的。但是值得注意的是,Java堆其實還未每一個線程單獨分配了一塊TLAB空間,這部分空間在分配時是線程獨享的,在使用時是線程共享的。
除了JVM運行時內存以外,還有什么區域可以用嗎?
除了我們前面介紹的虛擬機運行時數據區以外,還有一部分內存也被頻繁使用,他不是運行時數據區的一部分,也不是Java虛擬機規范中定義的內存區域,他就是——直接內存。
直接內存的分配不受Java堆大小的限制,但是他還是會收到服務器總內存的影響。
在JDK 1.4中引入的NIO中,引入了一種基于Channel和Buffer的I/O方式,他可以使用Native函數直接分配堆外內存,然后通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內存的應用進行操作。

堆和棧的區別是什么?
堆和棧(虛擬機棧)是完全不同的兩塊內存區域,一個是線程獨享的,一個是線程共享的,二者之間最大的區別就是存儲的內容不同:
堆中主要存放對象實例。
棧(局部變量表)中主要存放各種基本數據類型、對象的引用。
Java中的數組是存儲在堆上還是棧上的?
在Java中,數組同樣是一個對象,所以對象在內存中如何存放同樣適用于數組;
所以,數組的實例是保存在堆中,而數組的引用是保存在棧上的。

Java中的對象創建有多少種方式?
Java中有很多方式可以創建一個對象,最簡單的方式就是使用new關鍵字。
User user = new User();復制代碼
除此以外,還可以使用反射機制創建對象:
User user = User.class.newInstance();復制代碼
或者使用Constructor類的newInstance:
Constructor constructor = User.class.getConstructor();User user = constructor.newInstance();復制代碼
除此之外還可以使用clone方法和反序列化的方式,這兩種方式不常用并且代碼比較復雜,就不在這里展示了,感興趣的可以自行了解下。
Java中對象創建的過程是怎么樣的?
對于一個普通的Java對象的創建,大致過程如下:
1、虛擬機遇到new指令,到常量池定位到這個類的符號引用。
2、檢查符號引用代表的類是否被加載、解析、初始化過。
3、虛擬機為對象分配內存。
4、虛擬機將分配到的內存空間都初始化為零值。
5、虛擬機對對象進行必要的設置。
6、執行方法,成員變量進行初始化。
Java中的對象一定在堆上分配內存嗎?
前面我們說過,Java堆中主要保存了對象實例,但是,隨著JIT編譯期的發展與逃逸分析技術逐漸成熟,棧上分配、標量替換優化技術將會導致一些微妙的變化,所有的對象都分配到堆上也漸漸變得不那么“絕對”了。
其實,在編譯期間,JIT會對代碼做很多優化。其中有一部分優化的目的就是減少內存堆分配壓力,其中一種重要的技術叫做逃逸分析。
如果JIT經過逃逸分析,發現有些對象沒有逃逸出方法,那么有可能堆內存分配會被優化成棧內存分配。

10、如何獲取堆和棧的dump文件?
Java Dump,Java虛擬機的運行時快照。將Java虛擬機運行時的狀態和信息保存到文件。
可以使用在服務器上使用jmap命令來獲取堆dump,使用jstack命令來獲取線程的調用棧dump。
來自:【https://juejin.im/post/5d4789afe51d453b386a62ac】
10 道基礎面試題
1.什么是B/S架構?C/S架構?
B/S(Browser/Server),瀏覽器/服務器程序;
C/S(Client/Server),客戶端/服務端,桌面應用程序。
2.網絡協議有哪些?
HTTP:超文本傳輸協議;
SMPT:簡單郵件協議;
TELNET:遠程終端協議;
POP3:郵件讀取協議 ;
FTP:文件傳輸協議;
3. Java的四種引用及應用場景?
強引用: 通常我們使用new操作符創建一個對象時所返回的引用即為強引用;
軟引用: 若一個對象只能通過軟引用到達,那么這個對象在內存不足時會被回收,可用于圖片緩存中,內存不足時系統會自動回收不再使用的Bitmap;
弱引用: 若一個對象只能通過弱引用到達,那么它就會被回收(即使內存充足),同樣可用于圖片緩存中,這時候只要Bitmap不再使用就會被回收;
虛引用: 虛引用是Java中最“弱”的引用,通過它甚至無法獲取被引用的對象,它存在的唯一作用就是當它指向的對象回收時,本身會被加入到引用隊列中,這樣我們可以知道它指向的對象何時被銷毀。
4.Java是否需要開發人員回收內存垃圾嗎?
多情況下是不需要。Java提供了一個系統級的線程來跟蹤內存分配,不再使用的內存區將會自動回收。
5. ArrayList, Vector,LinkedList,的區別是什么?
ArrayList: 內部采用數組存儲元素,支持高效隨機訪問,支持動態調整大小;
Vector: 可以看作線程安全版的ArrayList;
LinkedList: 內部采用鏈表來存儲元素,支持快速插入/刪除元素,但不支持高效地隨機訪問。
6.Java中的包裝類都是那些?
byte:Byte;
short:Short;
int:Integer;
double:Double;
char:Character;
boolean:Boolean;
long:Long;
float:Float。
7. String, StringBuilder, StringBuffer的區別是什么?
String: 不可變的字符序列,若要向其中添加新字符需要創建一個新的String對象;
StringBuilder: 可變字符序列,支持向其中添加新字符;
StringBuffer: 可以看作線程安全版的StringBuilder。
8.一個java類中包含那些內容?
屬性、方法、內部類、構造方法、代碼塊。
9. 靜態內部類與非靜態內部類的區別
靜態內部類不會持有外圍類的引用,而非靜態內部類會隱式持有外圍類的一個引用。
10. Java中多態的實現原理
所謂多態,指的就是父類引用指向子類對象,調用方法時會調用子類的實現而不是父類的實現。多態的實現的關鍵在于“動態綁定”。
Java多線程基礎面試題
1、進程是什么?
進程是程序在處理機中的一次運行。一個進程既包括其所要執行的指令,也包括了執行指令所需的系統資源,不同進程所占用的系統資源相對獨立。所以進程是重量級的任務,它們之間的通信和轉換都需要操作系統付出較大的開銷。
2、線程是什么?
線程是進程中的一個實體,是被系統獨立調度和分派的基本單位。線程自己基本上不擁有系統資源,但它可以與同屬一個進程的其他線程共享進程所擁有的全部資源。所以線程是輕量級的任務,它們之間的通信和轉換只需要較小的系統開銷。
還有哪些常問的面試題呢?
1、并行和并發有什么區別?
答:兩者區別:一個是交替執行,一個是同時執行。
2、創建線程有哪幾種方式?
答:繼承Thread類、實現Runnable接口和實現Callable接口。
3、線程有哪些狀態?
答:線程可以正在運行(Running),只要獲得了CPU時間它就可以運行;
運行的線程可以被掛起(Suspend),并臨時中斷它的執行;
一個掛起的線程可以被恢復(Resume),允許它從停止的地方繼續運行;
一個線程可以在等待資源時被阻塞(Block);
在任何時候,線程可以被終止(Terminate),這將立即中斷運行。一旦終止,線程不能被恢復。
有的說六種的是算上初始的狀態,即:初始(New):新創建了一個線程對象,但還沒有調用start()方法。
4、sleep() 和 wait() 有什么區別?
答:(1)同步鎖的對待不同:
sleep()后,程序并不會不釋放同步鎖。
wait()后,程序會釋放同步鎖。
(2)用法的不同:
sleep()可以用時間指定來使他自動醒過來。如果時間不到你只能調用interreput()來強行打斷。
wait()可以用notify()直接喚起。
(3)屬于不同的類:
sleep()的類是Thread。
wait()的類是Object。
5、線程的 run()和 start()有什么區別?
答:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。
6、什么是死鎖?怎么防止死鎖?
答:當某一進程提出資源的使用要求后,使得系統中一些進程處于無休止的阻塞狀態,在無外力的作用下,這些進程永遠也不能繼續前進。我們稱這種現象為死鎖。
(1) 盡量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),設置超時時間,超時可以退出防止死鎖。
(2)盡量使用 Java. util. concurrent 并發類代替自己手寫鎖。
(3)盡量降低鎖的使用粒度,盡量不要幾個功能用同一把鎖。
(4)盡量減少同步的代碼塊。
7、synchronized 和 ReentrantLock 區別是什么?
答:一個可重入的互斥鎖 Lock,它具有與使用 synchronized 方法和語句所訪問的隱式監視器鎖相同的一些基本行為和語義,但功能更強大。
ReentrantLock更加靈活,提供了超時獲取鎖,可中斷鎖。提供了非公平鎖和非公平鎖,而synchronized僅僅是非公平鎖。
用法上,ReentrantLock必須手動釋放鎖,并且只能修飾代碼塊。而synchronized不用手動釋放鎖,除此之外可以修飾方法。
使用synchronized的線程會被block住,而ReentrantLock的線程則是進入waiting狀態。
阿里高級java面試題和答案
一面面試題目:
1、你比較了解的機器學習的算法有哪些,說一下這些算法的過程和區別
2、網絡的體系結構分為哪五層,每層分別有哪些協議
3、TCP和UDP的區別是什么,如果想發送即時消息應該用哪種協議
4、TCP的連接建立和斷開的過程(三次握手和四次揮手),如何保證TCP發送的信息是正確的,且保證其先后順序不被篡改
5、對HTTP協議了解多少,HTTP和HTTPS有什么區別,HTTPS的安全性是怎么實現的
6、平時用mysql用什么引擎
7、數據庫事務的特性有哪些
8、事務并發可能會導致哪些問題,數據庫的隔離級別有哪些,mysql默認的是哪種級別,這種默認的隔離級別能夠避免哪些問題(復習的太久了,有一些忘記了,這個問題居然答得不全)
9、如何判斷SQL查詢操作是不是慢sql,如何優化
10、進程和線程的區別,進程之間的通信方法
11、死鎖是什么,處理死鎖的方法有哪些
12、進程同步中的臨界區有什么處理方法
13、spring MVC,spring AOP源碼
14、spring循環引用
15、spring事務傳播機制
16、java nio,bio,aio,操作系統底層nio實現原理
17、java線程編程了解嗎?
18、hashmap的數據結構是什么,具體是怎么實現的,是不是線程安全的(不是),那么它的線程安全的替代有哪些?
二面面試題目和參考答案:
你在項目中遇到哪些有挑戰性的點?
參考:參與了秒殺的高并發項目。
1.流量在某一時刻暴漲,然后又猛跌如何應對?
參考答案:
流量削峰填谷
在客戶端與服務器加入消息隊列作為緩存機制
接入層與各模塊都采用cache增加QPS
2.redis 消息隊列如何對過期信息/無效信息進行刪除
參考答案:
添加過期時間上限
不同組團信息采用不同隊列,當該組團滿額之后刪除隊列
3.redis 的持久化機制?
參考答案:RDB和AOF
4. 為什么JAVA類加載要用雙親委派
實例:Object類唯一
5.怎么實現同步
Synchronized關鍵字
Volatile變量
Lock對象
6. JAVA鎖有哪幾種
Sychronized
ReentrantLock
7. 兩種鎖的區別
Synchronized 由JVM實現
ReentrantLock 由JDK實現
6. 了解過AQS嗎?
AQS(Abstract Queue Synchronizer)隊列同步器
由一個Valotaile變量標記狀態State,以及一個CLH(同步、FIFO)隊列構成
具體實現類:
CountdownLatch: 等待多個線程完成;
CyclicBarrier:同步屏障;
Semaphore:控制并發線程數。
7. 場景題:給一個方法加上超時異常
使用AspectJ進行AOP開發
將方法調用進行Around切入
采用Future對象創建一個線程,在調用方法同時進行計時
若Future率先返回值則拋出超時異常
否則則正常調用
英雄帖-Alibaba-企業智能事業部-技術專家/高級開發工程師
前言
如題,本文是招賢納士帖。
崗位和博主一個團隊,歡迎大家一起過來搞事情!
如果你對我有想法,簡歷甩過來吧,我們可以成為同事;
如果你對Alibaba 有想法,簡歷也請甩過來吧,我來給你內推!
如果面試通過,我請你吃大餐 ,大餐,大餐~
職位 :技術專家/高級Java工程師-杭州(P6/P7)
工作地點:?杭州
工作年限:三年以上
所屬部門:阿里集團
招聘人數:若干
團隊介紹:
企業智能部,是阿里巴巴集團協同辦公和運營平臺的建設者,為阿里集團及生態公司提供生態化、國際化、數據化、移動化以及安全穩定的企業信息化服務;負責協同門戶平臺、工作流平臺、數據平臺、iHR、財務、IT、行政、賬戶權限等核心系統,是企業信息化服務能力輸出的強大引擎;我們專注于賦能業務,以嚴謹理念和互聯網的創新精神,致力打造企業運營最佳效能!
崗位描述:
1. 作為核心工程師參與阿里大腦的建設工作,通過云計算和人工智能的手段助力組織升級。
2. 主導業務及技術改造類項目的系統分析和設計工作,承擔核心功能及公共模塊的代碼編寫工作。
3. 維護和升級現有軟件產品,快速定位并修復現有產品的缺陷。
崗位要求:
1. 本科以上學歷,計算機相關專業畢業。
2. 精通Web編程,Java基礎扎實;熟悉Spring、MyBatis等開源框架;熟悉常用消息和存儲中間件;熟悉Oracle、Mysql等關系數據庫,熟悉Linux操作系統。
3. 有4年以上使用Java語言進行web開發的經驗,熟悉常用設計模式。在公司擔任過架構師或核心技術骨干,有主導大型系統架構設計和核心代碼開發的經驗。
4. 對技術有強烈的興趣,喜歡鉆研;同時需要具備良好的溝通協作能力。
5. 熟悉SOA,有平臺化實施經驗,有大數據、高并發系統和大型網站構建經驗者優先。
6. 有企業服務業務系統開發經驗者優先。
注意:這是P7職級的要求,P6職級的要求會相對降低。
咨詢&聯系方式
簡歷可直接發送到郵箱:guangjian.cgj@alibaba-inc.com
微信:?universskyoh
歡迎大家騷擾!
Kotlin 開發者社區
國內第一Kotlin 開發者社區公眾號,主要分享、交流 Kotlin 編程語言、Spring Boot、Android、React.js/Node.js、函數式編程、編程思想等相關主題。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Kotlin 開發者社區
更多文章閱讀:
如何進行思考? 產品經理思維模型參考(學習筆記)
系統架構設計方法論——Zachman框架模型
編程藝術是,而且一直以來都是 —— 語言設計藝術。
什么樣的代碼是好讀的?
《代碼整潔之道》細節之中自有天地,整潔成就卓越代碼 讀書筆記
架構設計模式—6大設計原則
《Kotlin Contract 契約》極簡教程
Kotlin 編碼規約
英雄帖-Alibaba-企業智能事業部-技術專家/高級開發工程師
番外篇:
Kotlin 是一門現代編程語言(1.0 版本是在 2016 年 2 月發布的)。它最初的目標是彌補 Java 的缺點,像 Scala 語言所做的那樣,但解決了一些存在的問題(例如,編譯時間)。
JetBrains 對 Kotlin 作了了不起的優化工作,在最近一個版本中 Kotlin 的編譯時間得到了顯著的提升。作為一個 Kotlin 新手,下面是最初我想到的一些問題的答案:
和 Java 的可互操作性:Kotlin 可以直接和 Java 類進行交互,當然也有其他方式。最基礎的一點:我確實想重用老的代碼倉庫,并引入 Kotlin。
轉換工具:雖然不能盲目的信任 Java 到 Kotlin 的自動轉換,但這個功能確實很棒。當我將 Java 類轉換為 Kotlin 類時,我可以很容易的復用 60%~70% 的結果代碼。我的做法是不要一次性將整個代碼庫從 Java 轉換為 Kotlin,而是遵循小步迭代。這樣審查轉換后的代碼所花的時間也會很少。
回到 Kotlin 本身,在使用 Java 進行多年的開發后,嘗試使用 Kotlin 這種新鮮東西感覺很棒。如果你是一名 Java 開發者,Kotlin 的語法對你而言是非常自然的。如果你是一名 Swift 開發者,也會有同樣的感覺,而且你會很容易理解 Kotlin 的一些關鍵概念例如空類型。Kotlin 其他吸引我注意的特性如下:
空類型:告訴你公司的業務人員你可以避免產品中三分之二的異常,這將是一件令人心動的事情。直到開始使用 Kotlin,你才意識到在 Java 中沒有空類型是多么糟糕的一件事情。
函數式編程:是的,Kotlin 正如 Scala 一樣,支持函數式編程。
默認和命名參數:再次的,如果你之前沒有嘗試過這種特性,你將永遠不會知道它的可貴之處。在 Kotlin 中,你可以為一個函數的參數設置默認值,并為每個參數命名。這成倍的增加代碼的可讀性和易讀性。
智能的強制轉換:厭倦了使用?instanceof?進行類型判斷然后進行類型轉換吧?它似乎總是非常多余的步驟,本應該很容易防止的。Kotlin 自動為你實現這些步驟。
Koltin 還有一堆的特性,可能需要幾篇文章的篇幅來進行列舉和深入介紹??偨Y來說:Koltin 是一門用于補充和完善 Java 不足的語言。對于 Java 開發者而言學習曲線很平緩。這不是一個非此即彼的問題,因為你可以在你的 Java 代碼倉庫中同時使用 Java 和 Kotlin。Kotlin 將會提高您的工作效率,從中長期來看,它將使你成為一名更好的程序員。
總結
以上是生活随笔為你收集整理的java面试题_阿里大厂流出的数百道 Java 经典面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在美容院做身体疏通经络管用吗
- 下一篇: 甜薯的功效与作用、禁忌和食用方法