2019最新java面試大全
阿新 • • 發佈:2019-04-19
工具 transacti final 框架 實現接口 字符 整潔 抽象 重復加載
Hibernate的特點:強大、方便、高效、復雜、繞彎子、全自動 1. 對象/關系數據庫映射,完全的向對象思想。開發速度快。 2. Sql移植性好。具有自己的日誌統計。 3. 緩存機制,提供一級緩存和二級緩存。 4. 功能和特性非常多,不適合多表關聯查詢。 5. 事物transaction ,沒有侵入性,即所謂的輕量級框架。 6. 透明持久化,具有業務功能的單線程對象。 7. 簡潔的 HQL編程。 Mybatis的特點:小巧、方便、高效、簡單、直接、半自動 1.Sql更加細致,手寫sql語句,減少查詢字段,有利於sql優化。2.Mybatis簡單,更容易掌握。 hibernate調優方案: 1、制定合理的緩存策略 2、盡量使用延遲加載特性 3、采用合理的session管理機制 4、使用批量抓取設定合理的批處理參數 5、進行合理的O/R映射設計 mybatis中resultMap和resultType的區別: resultType是表示直接返回類型。resultType和resultMap不能同時存在。查詢出來的每一個屬性都相當於一個map。 Mybatis動態sql語句: if 語句、if+where 語句、if+set 語句、choose(when,otherwise) 語句、trim 語句、foreach 語句 如何解決高並發的問題:1. html頁面靜態化 2. 圖片服務器分離 3. 數據庫集群和庫表散列 4. 緩存 5. 負載均衡 6. 鏡像 svn和git的區別? Git是分布式的,把內容按元數據方式存儲,沒有一個全局版本號,Git的內容的完整性要優於SVN:,GIT的內容存儲使用的是SHA-1哈希算法,(分布式版本控制) Svn不是分布的,按文件方式進行存儲,有全局的版本號。(集中式版本控制) 集群軟件的分類: 高性能集群:彌補了單機性的不足,運用在天氣監測上 負載均衡集群:選擇最小的服務器處理 高可用性集群:當一臺機器壞了,另一臺服務器會立刻代替上一臺服務器。一般用在銀行、電信。 處理高並發的的方法?1、HTML靜態化 2、圖片服務器分離 3、數據庫集群和庫表散列 4、緩存 5、鏡像 6、負載均衡 類加載器有哪些? 我們進一步了解類加載器間的關系(並非指繼承關系),主要可以分為以下4點 啟動類加載器,由C++實現,沒有父類。 拓展類加載器(ExtClassLoader),由Java語言實現,父類加載器為null。 系統類加載器(AppClassLoader),由Java語言實現,父類加載器為ExtClassLoader。 自定義類加載器,父類加載器肯定為AppClassLoader。 雙親委派模式? 雙親委派模式要求除了頂層的啟動類加載器外,其余的類加載器都應當有自己的父類加載器,請註意雙親委派模式中的父子關系並非通常所說的類繼承關系,而是采用組合關系來復用父類加載器的相關代碼,類加載器間的關系如下: 雙親委派模式是在Java 1.2後引入的,其工作原理的是,如果一個類加載器收到了類加載請求,它並不會自己先去加載,而是把這個請求委托給父類的加載器去執行,如果父類加載器還存在其父類加載器,則進一步向上委托,依次遞歸,請求最終將到達頂層的啟動類加載器,如果父類加載器可以完成類加載任務,就成功返回,倘若父類加載器無法完成此加載任務,子加載器才會嘗試自己去加載,這就是雙親委派模式。 雙親委派模式優勢: 采用雙親委派模式的是好處是Java類隨著它的類加載器一起具備了一種帶有優先級的層次關系,通過這種層級關可以避免類的重復加載,當父親已經加載了該類時,就沒有必要子ClassLoader再加載一次。其次是考慮到安全因素,java核心api中定義類型不會被隨意替換,假設通過網絡傳遞一個名為java.lang.Integer的類,通過雙親委托模式傳遞到啟動類加載器,而啟動類加載器在核心Java API發現這個名字的類,發現該類已被加載,並不會重新加載網絡傳遞的過來的java.lang.Integer,而直接返回已加載過的Integer.class,這樣便可以防止核心API庫被隨意篡改。可能你會想,如果我們在classpath路徑下自定義一個名為java.lang.SingleInterge類(該類是胡編的)呢?該類並不存在java.lang中,經過雙親委托模式,傳遞到啟動類加載器中,由於父類加載器路徑下並沒有該類,所以不會加載,將反向委托給子類加載器加載,最終會通過系統類加載器加載該類。但是這樣做是不允許,因為java.lang是核心API包,需要訪問權限,強制加載將會報出如下異常 java.lang.SecurityException: Prohibited package name: java.lang 所以無論如何都無法加載成功的。 jvm的優化? a) 設置參數,設置jvm的最大內存數 b) 垃圾回收器的選擇 什麽是Java虛擬機?為什麽Java被稱作是“平臺無關的編程語言”? Java虛擬機是一個可以執行Java字節碼的虛擬機進程。Java源文件被編譯成能被Java虛擬機執行的字節碼文件。 Java被設計成允許應用程序可以運行在任意的平臺,而不需要程序員為每一個平臺單獨重寫或者是重新編譯。Java虛擬機讓這個變為可能,因為它知道底層硬件平臺的指令長度和其他特性。 JDK和JRE的區別是什麽? Java運行時環境(JRE)是將要執行Java程序的Java虛擬機。它同時也包含了執行applet需要的瀏覽器插件。Java開發工具包(JDK)是完整的Java軟件開發包,包含了JRE,編譯器和其他的工具(比如:JavaDoc,Java調試器),可以讓開發者開發、編譯、執行Java應用程序。 JDK(Java Development Kit)即為Java開發工具包,包含編寫Java程序所必須的編譯、運行等開發工具以及JRE。開發工具如:用於編譯java程序的javac命令、用於啟動JVM運行java程序的java命令、用於生成文檔的javadoc命令以及用於打包的jar命令等等。 JRE(Java Runtime Environment)即為Java運行環境,提供了運行Java應用程序所必須的軟件環境,包含有Java虛擬機(JVM)和豐富的系統類庫。系統類庫即為java提前封裝好的功能類,只需拿來直接使用即可,可以大大的提高開發效率。 JVM(Java Virtual Machines)即為Java虛擬機,提供了字節碼文件(.class)的運行環境支持。 簡單說,就是JDK包含JRE包含JVM。 ”static”關鍵字是什麽意思?Java中是否可以覆蓋(override)一個private或者是static的方法? “static”關鍵字表明一個成員變量或者是成員方法可以在沒有所屬的類的實例變量的情況下被訪問。 Java中static方法不能被覆蓋,因為方法覆蓋是基於運行時動態綁定的,而static方法是編譯時靜態綁定的。static方法跟類的任何實例都不相關,所以概念上不適用。 是否可以在static環境中訪問非static變量? static變量在Java中是屬於類的,它在所有的實例中的值是一樣的。當類被Java虛擬機載入的時候,會對static變量進行初始化。如果你的代碼嘗試不用實例來訪問非static的變量,編譯器會報錯,因為這些變量還沒有被創建出來,還沒有跟任何實例關聯上。 [第12題] Java支持的數據類型有哪些?什麽是自動拆裝箱? Java語言支持的8中基本數據類型是: Byte、short、int、long、float、double、boolean、char 自動裝箱是Java編譯器在基本數據類型和對應的對象包裝類型之間做的一個轉化。比如:把int轉化成Integer,double轉化成double,等等。反之就是自動拆箱。 Java中的方法覆蓋(Overriding)和方法重載(Overloading)是什麽意思? Java中的方法重載發生在同一個類裏面兩個或者是多個方法的方法名相同但是參數不同的情況。與此相對,方法覆蓋是說子類重新定義了父類的方法。方法覆蓋必須有相同的方法名,參數列表和返回類型。覆蓋者可能不會限制它所覆蓋的方法的訪問。 Java中,什麽是構造函數?什麽是構造函數重載?什麽是復制構造函數? 當新對象被創建的時候,構造函數會被調用。每一個類都有構造函數。在程序員沒有給類提供構造函數的情況下,Java編譯器會為這個類創建一個默認的構造函數。 Java中構造函數重載和方法重載很相似。可以為一個類創建多個構造函數。每一個構造函數必須有它自己唯一的參數列表。 Java不支持像C++中那樣的復制構造函數,這個不同點是因為如果你不自己寫構造函數的情況下,Java不會創建默認的復制構造函數。 Java支持多繼承麽? Java不支持多繼承。每個類都只能繼承一個類,但是可以實現多個接口。 接口和抽象類的區別是什麽? Java提供和支持創建抽象類和接口。它們的實現有共同點,不同點在於: 接口中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。 類可以實現很多個接口,但是只能繼承一個抽象類 類如果要實現一個接口,它必須要實現接口聲明的所有方法。但是,類可以不實現抽象類聲明的所有方法,當然,在這種情況下,類也必須得聲明成是抽象的。 抽象類可以在不提供接口方法實現的情況下實現接口。 Java接口中聲明的變量默認都是final的。抽象類可以包含非final的變量。 Java接口中的成員函數默認是public的。抽象類的成員函數可以是private,protected或者是public。 接口是絕對抽象的,不可以被實例化。抽象類也不可以被實例化,但是,如果它包含main方法的話是可以被調用的。 也可以參考JDK8中抽象類和接口的區別 什麽是值傳遞和引用傳遞? 對象被值傳遞,意味著傳遞了對象的一個副本。因此,就算是改變了對象副本,也不會影響源對象的值。 對象被引用傳遞,意味著傳遞的並不是實際的對象,而是對象的引用。因此,外部對引用對象所做的改變會反映到所有的對象上。 我們能在 Switch 中使用 String 嗎? 從 Java 7 開始,我們可以在 switch case 中使用字符串,但這僅僅是一個語法糖。內部實現在 switch 中使用字符串的 hash code。 Java 中的構造器鏈是什麽? 當你從一個構造器中調用另一個構造器,就是Java 中的構造器鏈。這種情況只在重載了類的構造器的時候才會出現。 64 位 JVM 中,int 的長度是多數? Java 中,int 類型變量的長度是一個固定值,與平臺無關,都是 32 位。意思就是說,在 32 位 和 64 位 的Java 虛擬機中,int 類型的長度是相同的。 a==b”和”a.equals(b)”有什麽區別? 如果 a 和 b 都是對象,則 a==b 是比較兩個對象的引用,只有當 a 和 b 指向的是堆中的同一個對象才會返回 true a.equals(b) 是進行邏輯比較,所以通常需要重寫該方法來提供邏輯一致性的比較。例如,String 類重寫 equals() 方法,所以可以用於兩個不同對象,但是包含的字母相同的比較。 a.hashCode() 有什麽用?與 a.equals(b) 有什麽關系? hashCode() 方法是相應對象整型的 hash 值。它常用於基於 hash 的集合類,如 Hashtable、HashMap、LinkedHashMap等等。它與 equals() 方法關系特別緊密。根據 Java 規範,兩個使用 equal() 方法來判斷相等的對象,必須具有相同的 hash code。 final、finalize 和 finally 的不同之處? final 是一個修飾符,可以修飾變量、方法和類。如果 final 修飾變量,意味著該變量的值在初始化後不能被改變。 finalize 方法是在對象被回收之前調用的方法,給對象自己最後一個復活的機會,但是什麽時候調用 finalize 沒有保證。 finally 是一個關鍵字,與 try 和 catch 一起用於異常的處理。finally 塊一定會被執行,無論在 try 塊中是否有發生異常。 [第26題] 用最有效率的方法計算2乘以8? 2 << 3(左移3位相當於乘以2的3次方,右移3位相當於除以2的3次方) JVM的內存結構? 答:主要分為三大塊 堆內存、方法區、棧;棧又分為JVM棧、本地方法棧 堆(heap space),堆內存是JVM中最大的一塊,有年輕代和老年代組成,而年輕代又分為三分部分,Eden區,From Survivor,To Survivor,默認情況下按照8:1:1來分配 方法區(Method area),存儲類信息、常量、靜態變量等數據,是線程共享的區域 程序計數器(Program counter Register),是一塊較小的內存空間,是當前線程所執行的字節碼的行號指示器 JVM棧(JVM stacks),也是線程私有的,生命周期與線程相同,每個方法被執行時都會創建一個棧幀,用於存儲局部變量表、操作棧、動態鏈接、方法出口等信息 本地方法棧(Native Mthod Stacks),為虛擬機使用的native方法服務 System.gc()和Runtime.gc()會做什麽事情? 這兩個方法用來提示JVM要進行垃圾回收。但是,立即開始還是延遲進行垃圾回收是取決於JVM的。 怎樣通過 Java 程序來判斷 JVM 是 32 位 還是 64 位? 你可以檢查某些系統屬性如 sun.arch.data.model 或 os.arch 來獲取該信息。 JRE、JDK、JVM 及 JIT 之間有什麽不同? JRE 代表 Java 運行時(Java run-time),是運行 Java 引用所必須的。 JDK 代表 Java 開發工具(Java development kit),是 Java 程序的開發工具,如 Java 編譯器,它也包含 JRE。 JVM 代表 Java 虛擬機(Java virtual machine),它的責任是運行 Java 應用。 JIT 代表即時編譯(Just In Time compilation),當代碼執行的次數超過一定的閾值時,會將 Java 字節碼轉換為本地代碼,如,主要的熱點代碼會被準換為本地代碼,這樣有利大幅度提高 Java 應用的性能。 你能保證 GC 執行嗎? 不能,雖然你可以調用 System.gc() 或者 Runtime.gc(),但是沒有辦法保證 GC 的執行。 動態代理的兩種方式,以及區別? 答:jdk動態代理和cglib動態代理; JDK動態代理只能對實現了接口的類生成代理,而不能針對類;cglib是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法,因為是繼承,所以該類或方法最好不要聲明稱final,final可以阻止繼承和多態; Java中Exception和Error有什麽區別? Exception和Error都是Throwable的子類。Exception用於用戶程序可以捕獲的異常情況。Error定義了不期望被用戶程序捕獲的異常。 hrow和throws有什麽區別? throw關鍵字用來在程序中明確的拋出異常,相反,throws語句用來表明方法不能處理的異常。每一個方法都必須要指定哪些異常不能處理,所以方法的調用者才能夠確保處理可能發生的異常,多個異常是用逗號分隔的。 異常處理完成以後,Exception對象會發生什麽變化? Exception對象會在下一個垃圾回收過程中被回收掉。 什麽是不可變對象(immutable object)?Java 中怎麽創建一個不可變對象? 不可變對象指對象一旦被創建,狀態就不能再改變。任何修改都會創建一個新的對象,如 String、Integer及其它包裝類。 &和&&的區別? &運算符有兩種用法:(1)按位與;(2)邏輯與。&&運算符是短路與運算。邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運算符左右兩端的布爾值都是true整個表達式的值才是true。&&之所以稱為短路運算是因為,如果&&左邊的表達式的值是false,右邊的表達式會被直接短路掉,不會進行運算。很多時候我們可能都需要用&&而不是&,例如在驗證用戶登錄時判定用戶名不是null而且不是空字符串,應當寫為:username != null &&!username.equals(“”),二者的順序不能交換,更不能用&運算符,因為第一個條件如果不成立,根本不能進行字符串的equals比較,否則會產生NullPointerException異常。註意:邏輯或運算符(|)和短路或運算符(||)的差別也是如此。 我們能將 int 強制轉換為 byte 類型的變量嗎?如果該值大於 byte 類型的範圍,將會出現什麽現象? 是的,我們可以做強制轉換,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果強制轉化是,int 類型的高 24 位將會被丟棄,byte 類型的範圍是從 -128 到 128。 String和StringBuilder、StringBuffer的區別? String是只讀字符串,也就意味著String引用的字符串內容是不能被改變的。StringBuffer/StringBuilder類表示的字符串對象可以直接進行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,區別在於它是在單線程環境下使用的,因為它的所有方面都沒有被synchronized修飾,因此它的效率也比StringBuffer要高。 集合類 Collection集合接口,List、set實現Collection接口,arraylist、linkedlist,vector實現list接口,stack繼承vector,Map接口,hashtable、hashmap實現map接口 Java集合類框架的基本接口有哪些? Collection:代表一組對象,每一個對象都是它的子元素。 Set:不包含重復元素的Collection。 List:有順序的collection,並且可以包含重復元素。 Map:可以把鍵(key)映射到值(value)的對象,鍵不能重復。 什麽是叠代器(Iterator)? Iterator接口提供了很多對集合元素進行叠代的方法。每一個集合類都包含了可以返回叠代器實例的叠代方法。叠代器可以在叠代的過程中刪除底層集合的元素,但是不可以直接調用集合的remove(Object Obj)刪除,可以通過叠代器的remove()方法刪除。 Iterator和ListIterator的區別是什麽? Iterator可用來遍歷Set和List集合,但是ListIterator只能用來遍歷List。 Iterator對集合只能是前向遍歷,ListIterator既可以前向也可以後向。 ListIterator實現了Iterator接口,並包含其他的功能,比如:增加元素,替換元素,獲取前一個和後一個元素的索引,等等。 Java中的HashMap的工作原理是什麽? Java中的HashMap是以鍵值對(key-value)的形式存儲元素的。HashMap需要一個hash函數,它使用hashCode()和equals()方法來向集合/從集合添加和檢索元素。當調用put()方法的時候,HashMap會計算key的hash值,然後把鍵值對存儲在集合中合適的索引上。如果key已經存在了,value會被更新成新值。HashMap的一些重要的特性是它的容量(capacity),負載因子(load factor)和擴容極限(threshold resizing)。 如何決定選用HashMap還是TreeMap? 對於在Map中插入、刪除和定位元素這類操作,HashMap是最好的選擇。然而,假如你需要對一個有序的key集合進行遍歷,TreeMap是更好的選擇。基於你的collection的大小,也許向HashMap中添加元素會更快,將map換為TreeMap進行有序key的遍歷。 HashMap,HashTable,ConcurrentHashMap的區別? a、HashMap是非線程安全的,HashTable是線程安全的。 b、HashMap的鍵和值都允許有null值存在,而HashTable則不行。 c、因為線程安全的問題,HashMap效率比HashTable的要高。 HashMap:它根據鍵的hashCode值存儲數據,大多數情況下可以直接定位到它的值,因而具有很快的訪問速度,但遍歷順序卻是不確定的。 HashMap最多只允許一條記錄的鍵為null,允許多條記錄的值為null。HashMap非線程安全,即任一時刻可以有多個線程同時寫HashMap,可能會導致數據的不一致。如果需要滿足線程安全,可以用 Collections的synchronizedMap方法使HashMap具有線程安全的能力,或者使用ConcurrentHashMap。 Hashtable:Hashtable是遺留類,很多映射的常用功能與HashMap類似,不同的是它承自Dictionary類,並且是線程安全的,任一時間只有一個線程能寫Hashtable,並發性不如ConcurrentHashMap,因為ConcurrentHashMap引入了分段鎖。 極高並發下HashTable和ConcurrentHashMap哪個性能更好,為什麽,如何實現的? 答:當然是ConcurrentHashMap,因為ConcurrentHashMap引入了分段鎖,而HashTable則使用的是方法級別的鎖;因此在新版本中一般不建議使用HashTable,不需要線程安全的場合可以使用HashMap,而需要線程安全的場合可以使用ConcurrentHashMap; ArrayList和數組(Array)和有什麽區別?什麽時候應該使用Array而不是ArrayList? Array可以容納基本類型和對象,而ArrayList只能容納對象。 Array是指定大小的,而ArrayList大小是固定的。 Array沒有提供ArrayList那麽多功能,比如addAll、removeAll和iterator等。盡管ArrayList明顯是更好的選擇,但也有些時候Array比較好用。 ArrayList和LinkedList有什麽區別? 相同點:ArrayList和LinkedList都實現了List接口 不同點:ArrayList是基於索引的數據接口,它的底層是數組。它可以以O(1)時間復雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每一個元素都和它的前一個和後一個元素鏈接在一起,在這種情況下,查找某個元素的時間復雜度是O(n)。 LinkedList的插入,添加,刪除操作速度比ArrayList更快,因為當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。 LinkedList比ArrayList更占內存,因為LinkedList為每一個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。 ArrayList和Vector有何異同點? 相同點: (1)兩者都是基於索引的,內部由一個數組支持。 (2)兩者維護插入的順序,我們可以根據插入順序來獲取元素。 (3)ArrayList和Vector的叠代器實現都是fail-fast的。 (4)ArrayList和Vector兩者允許null值,也可以使用索引值對元素進行隨機訪問。 不同點: (1)Vector是同步的,而ArrayList不是。然而,如果你尋求在叠代的時候對列表進行改變,你應該使用CopyOnWriteArrayList。 (2)ArrayList比Vector快,它因為有同步,不會過載。 (3)ArrayList更加通用,因為我們可以使用Collections工具類輕易地獲取同步列表和只讀列表。 Comparable和Comparator接口是幹什麽的?列出它們的區別。 Java提供了只包含一個compareTo()方法的Comparable接口。這個方法可以個給兩個對象排序。具體來說,它返回負數,0,正數來表明輸入對象小於,等於,大於已經存在的對象。 Java提供了包含compare()和equals()兩個方法的Comparator接口。compare()方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小於,等於,大於第二個參數。equals()方法需要一個對象作為參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator並且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。 HashSet和TreeSet有什麽區別? HashSet是由一個hash表來實現的,它的元素是無序的。TreeSet是由一個樹形的結構來實現的,它裏面的元素是有序的。 poll() 方法和 remove() 方法的區別? poll() 和 remove() 都是從隊列中取出一個元素,但是 poll() 在獲取元素失敗的時候會返回空,但是 remove() 失敗的時候會拋出異常。 Java 中的 TreeMap 是采用什麽樹實現的? Java 中的 TreeMap 是使用紅黑樹實現的。 集合框架中的泛型有什麽優點? Java1.5引入了泛型,所有的集合接口和實現都大量地使用它。泛型允許我們為集合提供一個可以容納的對象類型,因此,如果你添加其它類型的任何元素,它會在編譯時報錯。這避免了在運行時出現ClassCastException,因為你將會在編譯時得到報錯信息。泛型也使得代碼整潔,我們不需要使用顯式轉換和instanceOf操作符。它也給運行時帶來好處,因為不會產生類型檢查的字節碼指令。 為何Map接口不繼承Collection接口? 盡管Map接口和它的實現也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map繼承Collection毫無意義,反之亦然。 如果Map繼承Collection接口,那麽元素去哪兒?Map包含key-value對,它提供抽取key或value列表集合的方法,但是它不適合“一組對象”規範。 什麽叫對象序列化,什麽是反序列化,如何實現對象序列化? 對象序列化,將對象以二進制的形式保存在硬盤上 反序列化;將二進制的文件轉化為對象讀取 實現serializable接口 對於 IO 流涉及的裝飾者設計模式例子如下: //把InputStreamReader裝飾成BufferedReader來成為具備緩沖能力的Reader。 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 裝飾者模式就是給一個對象增加一些新的功能,而且是動態的,要求裝飾對象和被裝飾對象實現同一個接口,裝飾對象持有被裝飾對象的實例(各種字符流間裝飾,各種字節流間裝飾)。 對於 IO 流涉及的適配器設計模式例子如下: //把FileInputStream文件字節流適配成InputStreamReader字符流來操作文件字符串。 FileInputStream fileInput = new FileInputStream(file); InputStreamReader inputStreamReader = new InputStreamReader(fileInput); 適配器模式就是將某個類的接口轉換成我們期望的另一個接口表示,目的是消除由於接口不匹配所造成的類的兼容性問題(字符流與字節流間互相適配)。 (1)單例餓漢模式://餓漢式單例類.在類初始化時,已經自行實例化 2 public class Singleton1 { 3 //私有的默認構造子 4 private Singleton1() {} 5 //已經自行實例化 6 private static final Singleton1 single = new Singleton1(); 7 //靜態工廠方法 8 public static Singleton1 getInstance() { 9 return single; 10 } 11 } (2)懶漢模式://懶漢式單例類.在第一次調用的時候實例化 2 public class Singleton2 { 3 //私有的默認構造子 4 private Singleton2() {} 5 //註意,這裏沒有final 6 private static Singleton2 single=null; 7 //靜態工廠方法 8 public synchronized static Singleton2 getInstance() { 9 if (single == null) { 10 single = new Singleton2(); 11 } 12 return single; 13 } 14 } (3)工廠模式: interface IFactory{ public IProduct createProduct();} Class Factory implements IFactory{ public IProduct createProduct(){return new Product();}} Public class client{ Public Static void main (String [] args){IFactory factory=new Factory(); IProduct product=factory.createProduct(); product.ProductMethod();}} 懶漢模式 public class Singleton { private static Singleton instance = null; private Singleton(){} public static synchronized Singleton getInstance(){ //如果還沒有被實例化過,就實例化一個,然後返回 if(instance == null){ instance = new Singleton(); } return instance; } } 餓漢模式: public class Singleton { //類加載的時候instance就已經指向了一個實例 private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } } 雙重檢驗鎖 public class Singleton { private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized (Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; } } AOP與IOC的概念(即spring的核心)? a) IOC:Spring是開源框架,使用框架可以使我們減少工作量,提高工作效率並且它是分層結構,即相對應的層處理對應的業務邏輯,減少代碼的耦合度。而spring的核心是IOC控制反轉和AOP面向切面編程。IOC控制反轉主要強調的是程序之間的關系是由容器控制的,容器控制對象,控制了對外部資源的獲取。而反轉即為,在傳統的編程中都是由我們創建對象獲取依賴對象,而在IOC中是容器幫我們創建對象並註入依賴對象,正是容器幫我們查找和註入對象,對象是被獲取,所以叫反轉。 b) AOP:面向切面編程,主要是管理系統層的業務,比如日誌,權限,事物等。 進程和線程的區別是什麽? 進程是執行著的應用程序,而線程是進程內部的一個執行序列。一個進程可以有多個線程。線程又叫做輕量級進程。 synchronized關鍵字的用法,優缺點: 答:java關鍵字,當它用來修飾一個方法或者代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該代碼段的代碼; synchronized修飾的方法或者對象,只能以同步的方式執行,會引起性能問題;無法中斷一個正在等候獲得鎖的線程,也無法通過投票獲得鎖;一個優先級高的線程等待一個優先級低的線程釋放鎖會導致優先級倒置,引起性能風險; Lock接口有哪些實現類,使用場景是什麽? Lock接口有三個實現類,一個是ReentrantLock,另兩個是ReentrantReadWriteLock類中的兩個靜態內部類ReadLock和WriteLock。 [第18題] 悲觀鎖、樂觀鎖的優缺點,CAS有什麽缺陷,該如何解決 悲觀鎖:總是假設最壞的情況,每次去拿數據的時候都認為別人會修改,所以每次拿數據的時候都會上鎖,這樣別人拿數據的時候就會阻塞知道它拿到鎖; synchronized關鍵字的實現也是悲觀鎖; 樂觀鎖:每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下再次期間別人有沒有更新這個數據。樂觀鎖適用於多讀的應用類型,可以提高吞吐量。 CAS:CAS是樂觀鎖技術,當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其他線程都失敗,失敗的線程不會被掛起,而是被告知這次競爭失敗,並可以再次嘗試; CAS的缺陷:ABA問題、循環時間長開銷大,只能保證一個共享變量的原子操作; 簡述你所知道的Linux: Linux起源於1991年,1995年流行起來的免費操作系統,目前, Linux是主流的服務器操作系統, 廣泛應用於互聯網、雲計算、智能手機(Android)等領域。由於Java主要用於服務器端的開發,因此Java應用的部署環境有很多為Linux。 Windows操作系統的目錄結構,是以盤符為單位,C盤、D盤、E盤等等,數據存儲在各個盤符之下,而Linux操作系統最頂層只有一個根目錄root,所有文件都存儲在這一個根目錄之下。 Linux不像Windows的圖形操作界面,是通過命令的方式進行操作,常用命令有: a . pwd:用於顯示當前工作目錄; b . ls:用於查看當前工作目錄內容; c . cd:用於改變當前工作目錄。 Tomcat服務器優化? a) 內存優化:主要是對Tomcat啟動參數進行優化,我們可以在Tomcat啟動腳本中修改它的最大內存數等等。 b) 線程數優化:Tomcat的並發連接參數,主要在Tomcat配置文件中server.xml中配置,比如修改最小空閑連接線程數,用於提高系統處理性能等等。 c) 優化緩存:打開壓縮功能,修改參數,比如壓縮的輸出內容大小默認為2KB,可以適當的修改。 tomcat的壓縮優化就是將返回的html頁面等內容經過壓縮,壓縮成gzip格式之後,發送給瀏覽器,瀏覽器在本地解壓縮的過程。 Spring使用了哪些設計模式? (1)工廠模式,在各種BeanFactory以及ApplicationContext創建中都用到了; (2)模板模式,也是在各種BeanFactory以及ApplicationContext創建中都用到了; (3)代理模式,在AOP實現中用到了JDK的動態代理; (4)單例模式,比如創建bean的時候; (5)策略模式,第一個地方,加載資源文件的地方,使用了不同的方法,比如:classPathResource,FileSystemResource,ServletContextResource,UrlResource但他們都有共同的接口Resource;第二個地方就是AOP的實現中,采用了不同的方式,JDK動態代理和CGLIB代理; 常見的數據庫優化手段? 庫表優化,表設計合理化,符合三大範式;添加適當的索引(普通索引、主鍵索引、唯一索引、全文索引);分庫分表;讀寫分離等;sql語句優化,定位執行效率低,慢sql的語句,通過explain分析低效率的原因; 索引的優缺點,什麽字段上建立索引? 優點: 第一,通過創建唯一索引可以保證數據的唯一性; 第二,可以大大加快數據的檢索速度,是主要目的; 第三;在使用分組和排序子句進行數據檢索時,可以顯著減少查詢中分組和排序的時間; 第四,可以在查詢中使用優化隱藏器,提高系統的性能; 缺點方面: 第一, 創建索引和維護索引要耗費時間,並且隨著數據量的增加而增加; 第二,每一個索引需要占用額外的物理空間,需要的磁盤開銷更大;第三,當對表中的數據進行增加、刪除、修改操作時,索引也要動態維護,降低了數據的維護速度; 一般來說,在經常需要搜索的列上,強制該列的唯一性和組織表中數據的排列結構的列,在經常用在鏈接的列上,在經常需要排序的列上,在經常使用在where字句的列上可以添加索引,以提升查詢速度;
2019最新java面試大全