search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

2016秋招筆試面試題一:Java及基礎部分

1.面向對象的特徵

1) 抽象: 抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象並不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是數據抽象。

2) 繼承: 繼承是一種聯結類的層次模型,並且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現有的類中派生,這個過程稱為類繼承。新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那裡繼承方法和實例變數,並且類可以修改或增加新的方法使之更適合特殊的需要。

3) 封裝: 封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。面向對象計算始於這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的介面訪問其他對象。

4) 多態性: 多態性是指允許不同類的對象對同一消息作出響應。多態性包括參數化多態性和包含多態性。多態性語言具有靈活、抽象、行為共享、代碼共享的優勢,很好的解決了應用程序函數同名問題。

2.java和c++最大的區別

  • 內存管理
  • 指針

3.JAVA 中int和Integer的區別

int是一種基本數據類型,而Integer是相應於int的類類型,稱為對象包裝。

Integer類在對象中包裝了一個基本類型int的值。Integer類型的對象包含一個int類型的欄位,Integer是int的封裝類。
此外,該類提供了多個方法,能在int類型和String類型之間互相轉換,還提供了處理int類型時非常有用的其他一些常量和方法。
詳細可見:

4.Java的作用域

private 私有許可權。只有自己能用。
friendly 包許可權。同一個包下的可用。不寫時默認為friendly
protected 繼承許可權。(是包許可權的擴展,子女類也可使用)。
public 誰都可以用。
詳細可見: 5.overload和override的區別

override:(重寫,會覆蓋父類的方法,是父類與子類之間多態性的一種表現)
1) 方法名、參數、返回值必須相同。
2) 子類方法不能縮小父類方法的訪問許可權。
3) 子類方法不能拋出比父類方法更多的異常(但子類方法可以不拋出異常)。
4) 存在於父類和子類之間。,被覆蓋的方法不能為private

5) 方法被定義為final不能被重寫。

class A{ public int getVal{ return(5); } } class B extends A{ public int getVal{ return(10); } } public class override { public static void main(String args) { B b = new B; A a= (A)b;//把 b 強 制轉換成A的類型 int x=a.getVal; System.out.println(x); } }

overload(重載,一個類中定義多個同名的方法,這些方法的參數不相同,是一個類中多態性的一種表現) 1) 參數類型、個數、順序至少有一個不相同。 2) 不能通過訪問許可權、返回類型、拋出的異常進行重載; 3) 存在於父類和子類、同類中。 4) 方法的異常類型和數目不會對重載造成影響;

class OverloadDemo { void test{ System.out.println("NO parameters"); } void test(int a){ System.out.println("a:"+a); }//end of Overload test for one integer parameter. void test(int a, int b){ System.out.println("a and b:"+a+" "+b); } double test(double a){ System.out.println("double a:"+a); return a*a; } } public class Overload{ public static void main(String args) { OverloadDemo ob = new OverloadDemo; double result; ob.test; ob.test(10); ob.test(10, 20); result = ob.test(123.25); System.out.println("Result of ob.test(123.25):"+result); } }

6. volatile關鍵字的作用

當我們使用volatile關鍵字去修飾變數的時候,所以線程都會直接在內存中讀取該變數並且不緩存它。這就確保了線程讀取到的變數是同內存中是一致的。從而保證多線程中變數的安全性。

7.error和exeception的區別

Error類和Exception類都繼承自Throwable類。

Error的繼承關係:Java.lang.Object > java.lang.Throwable > java.lang.Error

Exception的繼承關係:
java.lang.Object > java.lang.Throwable >java.lang.Exception

二者的不同之處:
Exception:
1) 可以是可被控制(checked) 或不可控制的(unchecked)
2) 表示一個由程序員導致的錯誤
3) 應該在應用程序級被處理

Error:
1) 總是不可控制的(unchecked)
2) 經常用來用於表示系統錯誤或低層資源的錯誤
3) 如何可能的話,應該在系統級被捕捉
詳細可見:http://wenku.baidu.com/link?url=Xvk-

8. String、StringBuffer、StringBuilder的區別

String 與StringBuffer對比
String 類型和 StringBuffer 類型的主要性能區別其實在於 String 是不可變的對象, 因此在每次對 String 類型進行改變的時候其實都等同於生成了一個新的 String 對象,然後將指針指向新的 String 對象,所以經常改變內容的字元串最好不要用 String ,因為每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以後, JVM 的 GC 就會開始工作,從而降低了效率。
而使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 對象本身進行操作,而不是生成新的對象,再改變對象引用。別是字元串對象經常改變的情況下推薦使用 StringBuffer 特。

StringBuffer與StringBuilder對比
StringBuffer:線程安全
StringBuilder:線程不安全,單在單線程中,性能比StringBuffer好

區別在於StringBuffer支持併發操作,線性安全的,適 合多線程中使用。StringBuilder不支持併發操作,線性不安全的,不適合多線程中使用。新引入的StringBuilder類不是線程安全的,但其在單線程中的性能比StringBuffer高。

由此可見,如果我們的程序是在單線程下運行,或者是不必考慮到線程同步問題,我們應該優先使用StringBuilder類;如果要保證線程安全,自然是StringBuffer。
詳細可見

9.final,finally, finalize的區別

final 用於聲明屬性,方法和類,分別表示屬性不可交變,方法不可覆蓋,類不可繼承。
finally 是異常處理語句結構的一部分,表示總是執行。
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法, 供垃圾收集時的其他資源回收,例如關閉文件等。

10.數組與鏈表的區別,哪個訪問更快

數組:靜態分配連續的存儲空間,每個元素的佔用的內存大小相同,可以通過下錶快速訪問任以元素,訪問速度快,但是插入刪除要移動大量元素,所以不適合做用於存儲需要頻繁該改變的數據。

鏈表:動態分配內存,不連續,通過指針聯繫,如果要訪問鏈表中一個元素,需要從第一個元素開始,一直找到需要的元素位置。但是增加和刪除一個元素對於鏈表數據結構就非常簡單了,只要修改元素中的指針就可以了。如果應用需要經常插入和刪除元素你就需要用鏈表數據結構了。

總結:
數組靜態分配內存,鏈表動態分配內存,不易造成浪費;
數組在內存中連續,鏈表不連續;
數組元素在棧區,鏈表元素在堆區;
數組利用下標定位,時間複雜度為O(1),鏈表定位元素時間複雜度O(n);
數組插入或刪除元素的時間複雜度O(n),鏈表的時間複雜度O(1)。
詳細可見: 11.java的垃圾處理機制

概念:在C++中,對象所佔的內存在程序結束運行之前一直被佔用,在明確釋放之前不能分配給其它對象;而在Java中,當沒有對象引用指向原先分配給某個對象的內存時,該內存便成為垃圾。JVM的一個系統級線程會自動釋放該內存塊。垃圾收集意味著程序不再需要的對象是」無用信息」,這些信息將被丟棄。當一個對象不再被引用的時候,內存回收它佔領的空間,以便空間被後來的新對象使用。

優點:
1)垃圾回收能自動釋放內存空間,減輕編程的負擔
2)有效的減少內存泄漏

缺點:
垃圾回收的一個潛在的缺點是它的開銷影響程序性能。Java虛擬機必須追蹤運行程序中有用的對象,而且最終釋放沒用的對象。這一個過程需要花費處理器的時間。

在HotSpot虛擬機中,物理的將內存分為兩個—年輕代(young generation)和老年代(old generation)。

年輕代:新創建的對象都存放在這裡。因為大多數對象很快變得不可達,所以大多數對象在年輕代中創建,然後消失。當對象從這塊內存區域消失時,我們說發生了一次「minor GC」。

老年代:沒有變得不可達,存活下來的年輕代對象被複制到這裡。這塊內存區域一般大於年輕代。因為它更大的規模,GC發生的次數比在年輕代的少。對象從老年代消失時,我們說「major GC」(或「full GC」)發生了。

mimor GC(發生在年輕代中)
為了理解GC,我們學習一下年輕代,對象第一次創建發生在這塊內存區域。年輕代分為3塊,Eden區和2個Survivor區。

年輕代總共有3塊空間,其中2塊為Survivor區。各個空間的執行順序如下:

絕大多數新創建的對象分配在Eden區。

在Eden區發生一次GC后,存活的對象移到其中一個Survivor區。

在Eden區發生一次GC后,對象是存放到Survivor區,這個Survivor區已經存在其他存活的對象。

一旦一個Survivor區已滿,存活的對象移動到另外一個Survivor區。然後之前那個空間已滿Survivor區將置為空,沒有任何數據。

經過重複多次這樣的步驟后依舊存活的對象將被移到老年代。

major GC (又叫full GC,發生在啊老年代中)
當老年代數據滿時,基本上會執行一次GC,使數據從老年代消失時

詳細可見:

12.java內存泄漏

在C++中,內存泄漏的範圍更大一些。有些對象被分配了內存空間,然後卻不可達,由於C++中沒有GC,這些內存將永遠收不回來。在Java中,這些不可達的對象都由GC負責回收,因此程序員不需要考慮這部分的內存泄露。

在Java中,內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點,首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連;其次,這些對象是無用的,即程序以後不會再使用這些對象。如果對象滿足這兩個條件,這些對象就可以判定為Java中的內存泄漏,這些對象不會被GC所回收,然而它卻佔用內存。

所以在Java中也有內存泄漏,但範圍比C++要小一些。因為Java從語言上保證,任何對象都是可達的,所有的不可達對象都由GC管理。

詳細可見: 13.進程及線程

一個進程是一個獨立(self contained)的運行環境,它可以被看作一個程序或者一個應用。而線程是在進程中執行的一個任務。Java運行環境是一個包含了不同的類和程序的單一進程。線程可以被稱為輕量級進程。線程需要較少的資源來創建和駐留在進程中,並且可以共享進程中的資源。
阮一峰:進程與線程的一個簡單解釋
JAVA多線程和併發基礎面試問答

14.同步及非同步

同步:指一個進程在執行某個請求的時候,若該請求需要一段時間才能返回信息,那麼這個進程將會一直等待下去,直到收到返回信息才繼續執行下去;

非同步:指進程不需要一直等下去,而是繼續執行下面的操作,不管其他進程的狀態。當有消息返回時系統會通知進程進行處理,這樣可以提高執行的效率。

15.死鎖

兩個線程或兩個以上線程都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是這些線程都陷入了無限的等待中。

死鎖的四個條件是:
禁止搶佔:no preemption
持有和等待:hold and wait
互斥:mutual exclusion
循環等待:circular waiting

死鎖的消除
最簡單的消除死鎖的辦法是重啟系統。更好的辦法是終止一個進程的運行。可以把一個或多個進程回滾到先前的某個狀態。
詳細可見:
https://zh.wikipedia.org/wiki/%E6%AD%BB%E9%94%81

16.生產者消費者架構

(在併發編程中使用生產者和消費者模式能夠解決絕大多數併發問題。該模式通過平衡生產線程和消費線程的工作能力來提高程序的整體處理數據的速度。)

生產者消費者問題(英語:Producer-consumer problem),也稱有限緩衝問題(英語:Bounded-buffer problem),是一個多線程同步問題的經典案例。該問題描述了兩個共享固定大小緩衝區的線程——即所謂的「生產者」和「消費者」——在實際運行時會發生的問題。生產者的主要作用是生成一定量的數據放到緩衝區中,然後重複此過程。與此同時,消費者也在緩衝區消耗這些數據。該問題的關鍵就是要保證生產者不會在緩衝區滿時加入數據,消費者也不會在緩衝區中空時消耗數據。
要解決該問題,就必須讓生產者在緩衝區滿時休眠(要麼乾脆就放棄數據),等到下次消費者消耗緩衝區中的數據的時候,生產者才能被喚醒,開始往緩衝區添加數據。同樣,也可以讓消費者在緩衝區空時進入休眠,等到生產者往緩衝區添加數據之後,再喚醒消費者。通常採用進程間通信的方法解決該問題,常用的方法有信號燈法[1]等。如果解決方法不夠完善,則容易出現死鎖的情況。出現死鎖時,兩個線程都會陷入休眠,等待對方喚醒自己。

生產者消費者模式
產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之後不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列里取,阻塞隊列就相當於一個緩衝區,平衡了生產者和消費者的處理能力。

用處廣泛
Java中的線程池類其實就是一種生產者和消費者模式的實現方式,但是實現方法更高明。生產者把任務丟給線程池,線程池創建線程並處理任務,如果將要運行的任務數大於線程池的基本線程數就把任務扔到阻塞隊列里,這種做法比只使用一個阻塞隊列來實現生產者和消費者模式顯然要高明很多,因為消費者能夠處理直接就處理掉了,這樣速度更快,而生產者先存,消費者再取這種方式顯然慢一些。

(補充:什麼是阻塞隊列?如何使用阻塞隊列來實現生產者-消費者模型?
java.util.concurrent.BlockingQueue的特性是:當隊列是空的時,從隊列中獲取或刪除元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。
阻塞隊列不接受空值,當你嘗試向隊列中添加空值的時候,它會拋出NullPointerException。
阻塞隊列的實現都是線程安全的,所有的查詢方法都是原子的並且使用了內部鎖或者其他形式的併發控制。
BlockingQueue介面是Java collections框架的一部分,它主要用於實現生產者-消費者問題。)
詳細可見:

https://zh.wikipedia.org/wiki/%E7%94%9F%E4%BA%A7%E8%80%85%E6%B6%88%E8%B4%B9%E8%80%85%E9%97%AE%E9%A2%98

17.set用法18.設計模式之設計原則

1) 單一職責原則(SRP)
定義:就一個類而言,應該僅有一個引起它變化的原因。

2) 開放封閉原則(ASD)
定義:類、模塊、函數等等等應該是可以拓展的,但是不可修改。

3) 里氏替換原則(LSP)
定義:所有引用基類(父類)的地方必須能透明地使用其子類的對象替換

4) 依賴倒置原則(DIP)
定義:高層模塊不應該依賴低層模塊,兩個都應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。

5) 迪米特原則(LOD)
定義:一個軟體實體應當儘可能少地與其他實體發生相互作用。

6) 介面隔離原則(ISP)
定義:一個類對另一個類的依賴應該建立在最小的介面上。 也就是說,我們要為各個類建立專用的介面,而不要試圖去建立一個很龐大的介面供所有依賴它的類去調用。

19.抽象類與介面的區別


熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦