java和javaee面試常用大全

需要面試資料可加羣:451834594,互相交流學習。

1、什麼時候用靜態變量 靜態方法?爲什麼要使用靜態變量、靜態方法?

       他們是全局的,那麼走到哪裏都可以使用。而是使用很方便。static全局變量只在聲明此static全局變量的文件中有效;普通全局變量對整個源程序都有效,當此源程序包含多於一個文件的程序時,對其他文件依然有效。

static局部變量的存儲區爲靜態存儲區,普通局部變量的存儲區爲棧;

static局部變量生存週期爲整個源程序,但是只能在聲明其的函數中調用

static全局變量只在聲明此static全局變量的文件中有效;

普通全局變量對整個源程序都有效,當此源程序包含多於一個文件的程序時,對其他文件依然有效。

 

 

 

2、變量,常量,靜態變量存儲的位置

常見的存儲區域1、棧2、堆4、全局/靜態存儲區5、常量存儲區

由編譯器在需要的時候分配,在不需要的時候自動清除的變量的存儲區。裏面的變量通常是局部變量、函數參數等。

由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,程序會一直佔用內存,導致內存泄漏,在程序結束後,操作系統會自動回收。

全局/靜態存儲區

全局變量和靜態變量被分配到同一塊內存中全局變量又分爲初始化的和未初始化的

常量存儲區

這是一塊比較特殊的存儲區,他們裏面存放的是常量,不允許修改

 

3、子類中如何調用父類中被重寫的方法

通過反射進行。可以在運行時調用任意一個對象的方法 

Class cls = Class.forName("com.jdk"); 
Methods methods[]= cls.getDecliedMethod(); 
jdk jdkobj = new jdk(); 
String returnvalue = methods.invoke(jdkobj,null) 



4、java反射機制應用場景

在運行時判斷任意一個對象所屬的類。 
Class cls = Class.forName("com.jdk"); 
返回true 
System.out.print(cls.isInstance(new jdk())); 

在運行時構造任意一個類的對象。 
Class cls = Class.forName("com.jdk"); 
jdk jdkobj = cls.newInstance(); 

在運行時判斷任意一個類所具有的成員變量和方法。

Class cls = Class.forName("com.jdk"); 
Methods methods[]= cls.getDecliedMethod(); 
Fields  fields[] = cls.getDeclieredFields(); 



5、各種編碼方式及區別?

ISO 就直接規定必須用兩個字節,也就是16位來統一表示所有的字符。

即讀取文件時,
若爲unicode(iso)時,前兩個字節可以不用讀取。注:固定是兩個字節一個字。
Javaunicode編碼,也就是用16位來編寫一個字符。
utf8:用三個字節來編碼一箇中文字符。
.Java
源文件(含有中文的話)是用:GBK編碼。

ASSCII:每個字符存儲是需佔用1字節

 

6、什麼是tcp/ip協議,什麼是三次握手?

 TCP爲傳輸控制協議,IP爲網際協議,是網絡層最重要的協議。採用TCP/IP協議通過互聯網傳送信息可減少網絡中的傳輸阻塞,方便大批量的數據在網上傳輸,從而提高網絡的傳輸效率。 

 

第一次握手:建立連接時,客戶端發送syn包(syn=jTCP/IP建立連接時使用的握手信號)到服務器,並進入SYN_SENT狀態,等待服務器確認;第二次握手服務器收到syn包,必須確認客戶的SYNack=j+1),同時自己也發送一個SYN包。第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHEDTCP連接成功)狀態,完成三次握手。

 

7、請求方法有哪些種呢?

GET: 完整請求一個資源 (常用)
HEAD: 僅請求響應首部(向服務器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應消息頭中的元信息)
POST:提交表單(常用)
PUT: 上傳(向指定資源位置上傳其最新內容)
DELETE:刪除(請求服務器刪除Request-URI所標識的資源)

TRACE 回顯服務器收到的請求,主要用於測試或診斷

 

8、如何實現跨域訪問?

後臺代理方式 :也就是將後臺作爲代理,每次對其它域的請求轉交給本域的後臺,本域的後臺通過模擬http請求去訪問其它域,再將返回的結果返回給前臺,這樣做的好處是,無論訪問的是文檔,還是js文件都可以實現跨域。

基於iframe實現跨域 :兩個頁面必須屬於一個基礎域(例如都是xxx.com,或是xxx.com.cn),使用同一協議(例如都是 http)和同一端口(例如都是80),這樣在兩個頁面中同時添加document.domain = "xx.com";  

基於script標籤實現跨域 :動態創建script標籤就可以加載其它域的js文件,然後通過本頁面就可以調用加載後js文件的函數,這樣做的缺陷就是不能加載其它域的文檔,只能是js文件

使用window.name來進行跨域數據共享。window對象有個name屬性,該屬性有個特徵:即在一個窗口(window)的生命週期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限。

 

9、主鍵和索引的區別?

主鍵是表中的一個或多個字段,它的值用於惟一地標識表中的某一條記錄.;使用索引可快速訪問數據庫表中的特定信息。索引是對數據庫表中一列或多列的值進行排序的一種結構,只有當經常查詢索引列中的數據時,才需要在表上創建索引。索引佔用磁盤空間,並且降低添加、刪除和更新行的速度。

添加索引:ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) 

 

10、存儲過程使用?

sql存儲過程及應用:存儲過程(StoredProcedure),是一組爲了完成特定功能的SQL 語句。存儲過程在被創建以後,可以在程序中被多次調用,而不必重新編寫該存儲過程的SQL語句,而且數據庫專業人員可隨時對存儲過程進行修改,但對應用程序源代碼毫無影響。因爲應用程序源代碼只包含存儲過程的調用語句,從而極大地提高了程序的可移植性。因爲存儲過程是預編譯的,在首次運行一個存儲過程時,查詢優化器對其進行分析優化,並給出最終被存在系統表中的執行計劃,而批處理的Transaction-SQL 語句在每次運行時都要進行編譯和優化,因此速度相對要慢一些。

 

11、Web 服務器性能與站點訪問性能優化思路

增加帶寬,儘可能多地使用靜態內容(靜態網頁是相對於動態網頁而言,是指沒有後臺數據庫、不含程序和不可交互的網頁),多臺服務器負載均衡同時處理大量的併發訪問,減少網頁中的 HTTP 請求數。

 

12、負載均衡及算法

負載均衡,其意思就是分攤到多個操作單元上進行執行,例如Web服務器FTP服務器企業關鍵應用服務器和其它關鍵任務服務器等,從而共同完成工作任務。

算法:

隨機:負載均衡方法隨機的把負載分配到各個可用的服務器上

輪詢:輪詢算法按順序把每個新的連接請求分配給下一個服務器,最終把所有請求平分給所有的服務器。

加權輪詢:該算法中,每個機器接受的連接數量是按權重比例分配的。

最快算法:最快算法基於所有服務器中的最快響應時間分配連接。

最少連接:系統把新連接分配給當前連接數目最少的服務器

多個服務器間數據共享:session複製。tomcat的session複製使所有節點tomcat的會話相同,tomcat使用組播技術,只要集羣中一個tomcat節點的session發生改變,會廣播通知所有tomcat節點發生改變。

13、高併發量網站解決方案

HTML靜態化、圖片服務器分離、數據庫集羣、庫表散列(在應用程序中安裝業務和應用或者功能模塊將數據庫進行分離,不同的模塊對應不同的數據庫或者表,再按照一定的策略對某個頁面或者功能進行更小的數據庫散列,比如用戶表,按照用戶ID進行表散列,這樣就能夠低成本的提升系統的性能並且有很好的擴展性。),緩存(),負載均衡,CDN(分發網絡。其目的是通過在現有的Internet中增加一層新的網絡架構,將網站的內容發佈到最接近用戶的網絡“邊緣”,使用戶可以就近取得所需的內容,提高用戶訪問網站的響應速度)。


 

14、java的垃圾回收機制(如何確定某個對象是“垃圾”?)。

Java的垃圾回收機制是Java虛擬機提供的能力,用於在空閒時間以不定時的方式動態回收無任何引用的對象佔據的內存空間。
需要注意的是:垃圾回收回收的是無任何引用的對象佔據的內存空間而不是對象本身。

在java中是通過引用來和對象進行關聯的,也就是說如果要操作對象,必須通過引用來進行。那麼很顯然一個簡單的辦法就是通過引用計數來判斷一個對象是否可以被回收。不失一般性,如果一個對象沒有任何引用與之關聯,則說明該對象基本不太可能在其他地方被使用到,那麼這個對象就成爲可被回收的對象了。這種方式成爲引用計數法。

 

由於它們互相引用對方,導致它們的引用計數都不爲0,那麼垃圾收集器就永遠不會回收它們。解決方案:在Java中採取了可達性分析法(該方法的基本思想是通過一系列的“GC Roots”對象作爲起點進行搜索,如果在“GC Roots”和一個對象之間沒有可達路徑,則稱該對象是不可達的,不過要注意的是被判定爲不可達的對象不一定就會成爲可回收對象。被判定爲不可達的對象要成爲可回收對象必須至少經歷兩次標記過程,如果在這兩次標記過程中仍然沒有逃脫成爲可回收對象的可能性,則基本上就真的成爲可回收對象了。)如果兩個對象互相引用,而不再被第3者所引用,那麼這兩個互相引用的對象也會被回收。

 

15、單例設計模式的實現?

 

餓漢式是(靜態初始化對象)線程安全的,因爲虛擬機保證只會裝載一次,在裝載類的時候是不會發生併發的。

懶漢式也是可以實現線程安全的,只要加上synchronized即可,但是這樣一來,會降低整個訪問的速度,而且每次都要判斷。可以使用"雙重檢查加鎖"的方式來實現,就可以既實現線程安全,又能夠使性能不受到很大的影響。並不是每次進入getInstance方法都需要同步,而是先不同步,進入方法過後,先檢查實例是否存在,如果不存在才進入下面的同步塊,這是第一重檢查。進入同步塊過後,再次檢查實例是否存在,如果不存在,就在同步的情況下創建一個實例,這是第二重檢查。這樣一來,就只需要同步一次了,從而減少了多次在同步情況下進行判斷所浪費的時間。

懶漢式:”雙重檢查加鎖”

     public class Singleton { 
         /** 
         * 對保存實例的變量添加volatile的修飾  
          */ 
         private volatile static Singleton instance = null;  
       private Singleton(){ 
        } 
         public static  Singleton getInstance(){ 
             //先檢查實例是否存在,如果不存在才進入下面的同步塊  
         if(instance == null){ 
              //同步塊,線程安全地創建實例  
             synchronized(Singleton.class){ 
                  //再次檢查實例是否存在,如果不存在才真正地創建實例  
                 if(instance == null){ 
                      instance = new Singleton(); 
                 } 
              } 
         } 
          return instance; 
     } 
  }


資源利用率高,不執行getInstance()就不會被實例,可以執行該類的其他靜態方法

 

缺點

第一次加載時不夠快,多線程使用不必要的同步開銷大

22.   

餓漢式:
publicclass Singleton1 {
 
        private Singleton1() {
        }
 
        publicstatic Singleton1 instance = new Singleton1();
 
        public Singleton1 getInstance() {
               return instance;
        }
 
}


優點:1.線程安全 
2.在類加載的同時已經創建好一個靜態對象,調用時反應速度快
缺點:資源效率不高,可能getInstance()永遠不會執行到,但執行該類的其他靜態方法或者加載了該類(class.forName),那麼這個實例仍然初始化
解決方案:

.靜態內部類

class Singleton5 {
        private Singleton5() {
        }
 
        privatestaticclass SingletonHelp {
               static Singleton5 instance = new Singleton5();
        }
 
        publicstatic Singleton5 getInstance() {
               return SingletonHelp.instance;
        }
}


資源利用率高,不執行getInstance()不被實例,可以執行該類其他靜態方法

 

缺點

第一次加載時反應不夠快

 

 

16、對設計模式的理解以及使用場景?

單例模式:確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例,如網站的計數器,數據庫連接池的設計一般也是採用單例模式,因爲數據庫連接是一種數據庫資源。多線程的線程池的設計。

 

裝飾模式:以對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案;
代理模式:給一個對象提供一個代理對象,並有代理對象來控制對原有對象的引用;

裝飾模式應該爲所裝飾的對象增強功能;代理模式對代理的對象施加控制,並不提供對象本身的增強功能,代理對象完成用戶請求,屏蔽用戶對真實對象的訪問。靜態代理是在程序運行之前就已經存在了代理類,動態代理是程序運行中在內存中生成代理類。  
裝飾器模式來說,裝飾者(decorator)和被裝飾者(decoratee)都實現同一個接口。 
對代理模式來說,代理類(proxy class)和真實處理的類(real class)都實現同一個接口。

適配器模式是用新接口來調用原接口,原接口對新系統是不可見或者說不可用的。裝飾者模式原封不動的使用原接口適配器是知道被適配者的詳細情況的(就是那個類或那個接口)。裝飾者只知道其接口是什麼,至於其具體類型(是基類還是其他派生類)只有在運行期間才知道。

適配器模式主要是爲了接口的轉換,而裝飾者模式關注的是通過組合來動態的爲被裝飾者注入新的功能或行爲(即所謂的責任)。

 

17、設計模式的原則

1、開閉原則,對擴展開放,對修改關閉。在程序需要進行拓展的時候,不能去修改原有的代碼2、里氏代換原則,任何基類可以出現的地方,子類一定可以出現3、依賴倒轉原則,真對接口編程,依賴於抽象而不依賴於具體。

18、進程和線程的區別?

進程就是一個應用程序在處理機上的一次執行過程,它是一個動態的概念,而線程是進程中的一部分,進程包含多個線程在運行。

進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源。一個程序至少有一個進程,一個進程至少有一個線程.

 

19、在多線程情況下hashmap的線程不安全問題

Hashtable替換HashMap,如果從結構上對Hashtable 進行修改,除非通過 Iterator 自身的移除或添加方法,否則在任何時間以任何方式對其進行修改,Iterator 都將拋出 ConcurrentModificationException,面對併發的修改,Iterator 很快就會完全失敗,而不冒在將來某個不確定的時間發生任意不確定行爲的風險。   ConcurrentHashMap和Hashtable主要區別就是圍繞着鎖的粒度以及如何鎖,可以簡單理解成把一個大的HashTable分解成多個,形成了鎖分離

 

20、spring是何時創建對象的?

框架讀取配置文件spring.xml後,將配置文件中每個bean元素對應到BeanDefinition. 
根據配置的class元素值首先得到對應的Class對象,然後用Class.newInstance()方法生成對象實例.有了對象實例後根據配置文件的依賴關係進行初始化加工等工作.完了就可以投放使用.

 

21、啓動線程的方法?

Thread類的start()方法來啓動一個線程,
這時此線程是處於就緒狀態,
並沒有運行。
然後通過此Thread類調用方法run()來完成其運行操作的,
這裏方法run()稱爲線程體,
它包含了要執行的這個線程的內容,

 

22、線程的優先級?

* 1.Java中線程優先級:1--10

 * 2.默認優先級:5;設置優先級:setPriority(intp)

我們可以設定,但仍然由操作系統來決定;

 

23、線程的常用操作?

休眠線程:Thread.sleep(1000);

加入線程:* 調用join()的對象,會保證先執行完畢,其它線程纔會開始執行;

禮讓線程:yield()當前執行的線程,會退回到"就緒"狀態,等待操作系統再次分配執行時間.

               操作系統很有可能會再次讓這個線程執行;

守護線程:守護線程:當主進程結束時,線程也會跟着結束(但不會立即結束,有個小緩衝)

setDaemon(true);

中斷線程:Object-->wait()     Thread-->sleep()  Thread-->yield()

       此方式,會在當線程處於上述三種狀態之一時,引發一個異常,

                                                       我們可以在異常中,停止掉線程;

停止線程:stop(),但是常用使用退出標誌,使線程正常退出

反對使用stop(),是因爲它不安全。它會解除由線程獲取的所有鎖定,而且如果對象處於一種不連貫狀態,那麼其他線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來說,如果它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會造成死鎖。所以不應該使用suspend(),而應在自己的Thread類中置入一個標誌,指出線程應該活動還是掛起。若標誌指出線程應該掛起,便用wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()重新啓動線程。

 

 * wait():會釋放鎖;

 *sleep():不釋放鎖;

 *yield():不釋放鎖;

sleep100L)意思爲:佔用CPU,線程休眠100毫秒
wait
100L)意思爲:不佔用CPU,線程等待100毫秒

24、同步的好處和弊端?

併發訪問:* 1.是否是多線程環境

 * 2.是否有共享數據

 * 3.是否有多條語句操作共享數據

同步的好處:

 * 1.它解決了多個線程的併發性訪問的問題;

 * 同步的弊端:

 * 1.由於判斷鎖對象,所以會有額外的執行代碼,所以效率會降低;

56、多線程有幾種實現方法?同步有幾種實現方法?

多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口

同步的實現方面有兩種,分別是synchronized,waitnotify

wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock

sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。

notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。

Allnotity():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。

 

 

25、線程的瞭解?

鎖和死鎖:兩個或者多個線程之間相互等待,導致線程都無法執行。

生產者消費者,當生產者生產產品滿足數量時,進行等待,被消費完時,喚醒,繼續生產。

爲什麼wait(),notify(),notifyAll()等方法都定義在Object類中:

                   1).因爲每個類都有可能被多線程訪問;

                   2).如果被線程訪問時,如果資源沒準備好,每個類都有權利要求訪問的線程等待、及喚醒;

26、什麼是線程池?

對於一個Thread線程,不能多次的調用start();

 *   如果想再次運行,需要再次實例化此線程對象;

 *   如果這個線程對象實例化時,很耗時,那麼我們多次使用,就很不方便;

"線程池",它可以緩存一些"線程對象", 我們可以反覆的調用緩衝的線程對象;

 

 一個線程池包括以下四個基本組成部分:
               1、線程池管理器(ThreadPool):用於創建並管理線程池,包括創建線程池,銷燬線程池,添加新任務;
               2、工作線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,可以循環的執行任務;
               3、任務接口(Task):每個任務必須實現的接口,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;
               4、任務隊列(taskQueue):用於存放沒有處理的任務。

 

27、網絡通信:

TCP(傳輸層)上傳任何東西都是可靠的,只要兩臺機器上建立起了連接,在本機上發送的數據就一定能傳到對方的機器上,UDP就好比發電報,發出去就完事了,對方有沒有接收到它都不管,所以UDP是不可靠的。TCP傳送數據雖然可靠,但傳送得比較慢,UDP傳送數據不可靠,但是傳送得快。

Ip(網絡層):網間數據通信。

 端口號是用來區分一臺機器上不同的應用程序的。

客戶端通過端口6666向服務器端請求連接,服務器端接受客戶端的連接請求以後,就在服務器端上安裝一個Socket,然後讓這個Socket與客戶端的Socket連接,這樣服務器端就可以與客戶端互相通信了,當有另外一個客戶端申請連接時,服務器端接受了以後,又會安裝另外一個Socket與這個客戶端的Socket進行連接。

 

28、error和exception有什麼區別?

error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能處理這樣的情況。 exception 表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。

 

29、Java中的異常處理機制的簡單原理和應用。

異常是指java程序運行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等信息,可以用一個對象來表示,Java使用面向對象的方式來處理異常,它把程序中發生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。

Java對異常進行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類爲java.lang.Throwable,Throwable下面又派生了兩個子類:Error和Exception,Error 表示應用程序本身無法克服和恢復的一種嚴重問題,程序只有死的份了,例如,說內存溢出和線程死鎖等系統問題。Exception表示程序還能夠克服和恢復的問題,其中又分爲系統異常和普通異常,系統異常是軟件本身缺陷所導致的問題,也就是軟件開發人員考慮不周所導致的問題,軟件使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟件系統繼續運行或者讓軟件死掉,例如,數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所導致的問題,是用戶能夠克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常後,程序不應該死掉。

java爲系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,所以普通異常也稱爲checked異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用try..catch處理或用throws聲明,所以系統異常也稱爲unchecked異常。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章