2019年Android開發者常見面試題(二)

上一篇主要介紹的是Java相關的面試題,其實已經重複的說過,在Android面試中,Java相關的面試大概要佔到20%,甚至是大於20%,因此不得不顯得尤其重要,畢竟目前的開發中,Java語言開發畢竟仍是佔到絕大部分的。java

這篇繼續Java相關的面試題分享:面試

問題 8:抽象類的意義

答案【答案不惟一,可本身衡量】:

抽象類每每用來表徵對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不一樣,可是本質上相同的具體概念的抽象。具體分析以下:編程

1.由於抽象類不能實例化對象,因此必需要有子類來實現它以後才能使用。這樣就能夠把一些具備相同屬性和方法的組件進行抽象,這樣更有利於代碼和程序的維護。設計模式

好比本科和研究生能夠抽象成學生,他們有相同的屬性和方法。這樣當你對其中某個類進行修改時會受到父類的限制,這樣就會提醒開發人員有些東西不能進行隨意修改,這樣能夠對比較重要的東西進行統一的限制,也算是一種保護,對維護會有很大的幫助。 
2.當又有一個具備類似的組件產生時,只須要實現該抽象類就能夠得到該抽象類的那些屬性和方法。 
好比學校又新產生了專科生這類學生,那麼專科生直接繼承學生,而後對本身特有的屬性和方法進行補充便可。這樣對於代碼的重用也是很好的體現。安全

因此,Java中抽象類對於代碼的維護和重用有很好的幫助,也是Java面向對象的一個重要體現。多線程

 

問題 9:抽象類與接口的應用場景

答案【答案不惟一,可本身衡量】:

應用都是基於規則的應用,也就是基於語法的應用,咱們能夠根據語法上的異同點來總結抽象類和接口的應用場景架構

相同點沒有什麼可說的,咱們從不一樣點下手。併發

一、第一個重要的不一樣點

抽象類中不必定都是抽象的方法,也能夠有具體實現的方法,這樣就能夠把你們公用的方法提高到抽象類中,而後具體的方法能夠留給子類本身實現(此處經典的應用,模板方法設計模式)。因此抽象類能夠更好的實現代碼的複用編程語言

二、另外一個重要的不一樣就是類能夠實現多個接口。

接口和抽象類的概念不同。這個能夠理解爲接口是對動做的抽象,抽象類是對根源的抽象(即對本質的抽象與其餘類的本質不一樣)。操作系統

抽象類表示的是,這個對象是什麼。接口表示的是,這個對象能作什麼。好比,男人,女人,這兩個類(若是是類的話……),他們的抽象類是人。說明,他們都是人。人能夠吃東西,狗也能夠吃東西,你能夠把「吃東西」定義成一個接口,而後讓這些類去實現它。

因此,在高級語言上,一個類只能繼承一個類(抽象類)(正如人不可能同時是生物和非生物),可是能夠實現多個接口(吃飯接口、走路接口)。

當你關注一個事物的本質的時候,用抽象類;當你關注一個操做的時候,用接口。

另外一個重要的概念就是多態,多態經過分離作什麼和怎麼作,從另外一個角度將接口和實現分離出來。多態不但可以改善代碼的組織結果和可讀性,還能建立可擴展的程序----即不管在項目最初建立時仍是在須要添加新功能時均可以「生長」的程序。因爲接口更關注於動做的實現,多態主要是分離「作什麼」和「怎麼作」,因此接口的另外一個重要的應用就是多態的實現(固然抽象類也能夠實現多態,可是接口更加合適)。

抽象類的功能要遠超過接口,可是,定義抽象類的代價高。由於高級語言來講(從實際設計上來講也是)每一個類只能繼承一個類。在這個類中,你必須繼承或編寫出其全部子類的全部共性。雖然接口在功能上會弱化許多,可是它只是針對一個動做的描述。並且你能夠在一個類中同時實現多個接口。在設計階段會下降難度的。

 

10:抽象類是否能夠沒有方法和屬性

答案【答案不惟一,可本身衡量】:

答案是確定的,能夠。

抽象類中能夠沒有抽象方法,但有抽象方法的必定是抽象類。因此,java中 抽象類裏面能夠沒有抽象方法。注意即便是沒有抽象方法和屬性的抽象類,也不能被實例化。

 

問題 11:接口的意義

答案【答案不惟一,可本身衡量】:

一、定義接口的重要性:在Java編程,abstract class 和interface是支持抽象類定義的兩種機制。正是因爲這兩種機制的存在,才使得Java成爲面向對象的編程語言。

二、定義接口有利於代碼的規範:對於一個大型項目而言,架構師每每會對一些主要的接口來進行定義,或者清理一些沒有必要的接口。這樣作的目的一方面是爲了給開發人員一個清晰的指示,告訴他們哪些業務須要實現;同時也能防止因爲開發人員隨意命名而致使的命名不清晰和代碼混亂,影響開發效率。

三、有利於對代碼進行維護:好比你要作一個畫板程序,其中裏面有一個面板類,主要負責繪畫功能,而後你就這樣定義了這個類。但是在不久未來,你忽然發現現有的類已經不可以知足須要,而後你又要從新設計這個類,更糟糕是你可能要放棄這個類,那麼其餘地方可能有引用他,這樣修改起來很麻煩。若是你一開始定義一個接口,把繪製功能放在接口裏,而後定義類時實現這個接口,而後你只要用這個接口去引用實現它的類就好了,之後要換的話只不過是引用另外一個類而已,這樣就達到維護、拓展的方便性。

四、保證代碼的安全和嚴密:一個好的程序必定符合高內聚低耦合的特徵,那麼實現低耦合,定義接口是一個很好的方法,可以讓系統的功能較好地實現,而不涉及任何具體的實現細節。這樣就比較安全、嚴密一些,這一思想通常在軟件開發中較爲常見。

 

問題 12:泛型中extends和super的區別

答案【答案不惟一,可本身衡量】:

<? extends T>限定參數類型的上界:參數類型必須是T或T的子類型

<? super T> 限定參數類型的下界:參數類型必須是T或T的超類型

總結爲:

<? extends T> 只能用於方法返回,告訴編譯器此返參的類型的最小繼承邊界爲T,T和T的父類都能接收,可是入參類型沒法肯定,只能接受null的傳入

<? super T>只能用於限定方法入參,告訴編譯器入參只能是T或其子類型,而返參只能用Object類接收

? 既不能用於入參也不能用於返參

 

問題 13:父類的靜態方法可否被子類重寫

答案【答案不惟一,可本身衡量】:

首先答案是不能!

這個問題有兩個關鍵字,一個是靜態方法,一個是重寫。

咱們來先說說重寫,可能不少初學的朋友分不清重寫和重載的區別。

重寫:子類繼承父類後,定義了一個和父類中的如出一轍方法,這個如出一轍是值方法名和參數的定義如出一轍。這時候子類要實現這個方法,就稱爲對父類方法的重寫。

重載:子類繼承父類後,定義了一個和父類中相同名字的方法,可是參數不同(必須),實現也不一樣(可選),這就是重載。

靜態方法:java中,static修飾符修飾的方法就是靜態方法。所謂靜態就是指:在編譯以後所分配的內存會一直存在(不會被回收),直到程序退出內存纔會釋放這個空間。

在java中,全部的東西都是對象,對象的抽象就是類,對於一個類而言,若是要使用他的成員(類中的屬性,方法等),通常狀況下,必須先實例化對象後,經過對象的引用才能訪問這些成員。

可是,若是要使用的成員使用了static修飾,就能夠不經過實例化得到該成員。

就好比,如今有個桌子,我想吃蘋果,通常狀況下,我須要先拿個盤子(對象的實例化)去裝蘋果才能吃到蘋果,如今有個蘋果直接放在桌子上(用static修飾過的靜態方法),這樣我就能夠直接從桌子上拿到蘋果。可能你們會有疑問,既然靜態方法(能不經過實例化就使用成員)這麼方便,爲何不都使用靜態方法。

你們回到static這個修飾符的功能定義:所謂靜態就是指:在編譯以後所分配的內存會一直存在(不會被回收),直到程序退出內存纔會釋放這個空間。

java的回收機制會定時的回收已經使用過的對象的內存來釋放內存給應用程序。若是所有都是靜態變量和靜態方法,內存都被佔用了,java程序哪裏還有運行的空間呢?就比如,你回家就看到桌子上擺滿了蘋果,那你買的梨子就沒地方放了。

如今回到題目中來,父類的靜態方法能不能被重寫。答案是不能。

由於靜態方法從程序開始運行後就已經分配了內存,也就是說已經寫死了。全部引用到該方法的對象(父類的對象也好子類的對象也好)所指向的都是同一塊內存中的數據,也就是該靜態方法。子類中若是定義了相同名稱的靜態方法,並不會重寫,而應該是在內存中又分配了一塊給子類的靜態方法,沒有重寫這一說。

 

問題 14:進程和線程的區別

答案【答案不惟一,可本身衡量】:

1. 定義

進程是一個術語,用來描述一組資源和程序運行所需的內存分配。對於每個被加載到內存的exe,在它的生命週期中操做系統會爲之建立一個單獨隔離的進程。一個進程的失敗不會影響其餘的進程。每一個進程是由私有的虛擬地址空間、代碼、數據和其餘各類系統資源組成的。

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。系統建立好進程後,實際就啓動執行了該進程的主線程,主線程終止了,進程也就隨之終止,每個進程至少有一個線程(即主線程,它無需由用戶主動去建立,是由系統在應用程序啓動後建立的),用戶根據須要在應用程序中建立其餘線程,使多個線程併發的運行在同一個進程中。

2.關係

一個線程能夠建立和撤銷另外一個線程;同一個進程中的多個線程之間能夠併發執行.

相對進程而言,線程是一個更加接近於執行體的概念,它能夠與同進程中的其餘線程共享數據,但擁有本身的棧空間,擁有獨立的執行序列。

3.區別

進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空 間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。

1) 簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.

2) 線程的劃分尺度小於進程,使得多線程程序的併發性高。

3) 另外,進程在執行過程當中擁有獨立的內存單元,而多個線程共享內存,從而極大地提升了程序的運行效率。

4) 線程在執行過程當中與進程仍是有區別的。每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

5) 從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分能夠同時執行。但操做系統並無將多個線程看作多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

相關文章
相關標籤/搜索