大部分開發者進入公司,一個必備的環節就是面試,只有經過面試,才能知道求職者是否符合公司的要求,也只有經過面試,求職者纔能有倖進入到企業裏工做,那麼怎麼才能提升面試的成功率呢?對於開發者而言,顯然是技術的掌握水平,因爲技術的面很是廣,咱們並不可能所有的都掌握,可是,多多少少咱們都有所瞭解,準備的越充足,意味着成功率也能大大的提升。java
對於Android的面試,咱們能夠發現,要求的是愈來愈多,愈來愈嚴苛,面試如同造航母,已經遠不如14年15年那麼好找了,對於一些點,不只僅要會用,一些原理源碼性的東西,也必須得去研究掌握。面試
接下來的幾篇文章,主要羅列一下Android面試中常見的點,但願能夠幫助到你們,這一篇主要針對java中常見的點。安全
equals的做用是判斷兩個對象是否相等。多線程
經過判斷兩個對象的地址是否相同來判斷。app
==通常用於基本類型數據的比較,判斷兩個值是否相同函數
也能夠用於類的比較,一樣也是比較兩個對象的內存地址。(就是兩個對象都是同一個對象)ui
因此在equals沒覆蓋的狀況下,==和equals是等價的。spa
( 咱們能夠經過覆蓋equals來讓相同內容的對象來返回true。)線程
可以高效率的產生一個離散的int值。指針
經過hashCode()來計算出兩個對象的hash值而後進行比較。
可是會出現不一樣的類也會有相同hash值,因此這不是安全、不可靠的。
####總結
總的來講就是通常狀況equals和==是等價的。
若是兩個對象相等,則他們必定是equals返回true。
若是兩個對象的hashCode相同,也不能 100%保證它們是相同的。
1 Integer是int的包裝類,int則是Java的一種基本數據類型
2 Integer變量必須實例化以後纔可使用,而int變量不須要
3 Integer實際是對象的引用,當new一個Integer時,其實是生成一個指針指向此對象;而int則是直接存儲數據值
4 Integer的默認值是null,int的默認值是0
打個比方 父親person有行爲這個方法,裏面包括幾個動做:吃飯,睡覺,走路 父親有三個兒子,三個兒子都繼承了父親的行爲方法,因此三個兒子都有吃飯,睡覺,走路這些動做,可是三個兒子又分別有本身的動做--大兒子A會彈吉他,二兒子B會唱歌,三兒子C會打鼓 ...
1.Person person = new A(); 不是父類對象指向子類引用而是父類引用指向子類對象
2.這個對象不能調用子類A特有的彈吉他方法--person.guitar(); X
3.若是僅是這麼寫程序,還不是多態,記住實現多態的三要素:繼承 重寫 父類引用指向子類對象
4.以後,若是你調用persion.guitar(),此時在代碼的編譯階段,persion調用的仍然是本身的guitar(),不是兒子的。而當程序運行時,就是java XXX, persion調用的倒是兒子的guitar()。這個動態的過程纔是多態 。
Person person;
//父類的引用指向子類的方法;
person = new Student();
//person類型引用作一個判斷
//(1)if(person.eat().size==2 )
{
if(person instanceof Person)
{
person.eat();
}else if(person instanceof Student) {
Student stu = (Student)person;
stu.eat();
}
person.eat();//從代碼角度看,此時是父類的引用調用的是父類中的eat方法
//(2)子類若覆蓋了父類的方法,eat動態綁定到父類的引用Person上,換個名字叫動態綁定
//父類的引用能夠調用子類的方法,咱們把這一現象成爲多態
//從字面意思來理解person這個父類的引用一會是person一會是student
//person有多種狀態;
//也叫方法的動態綁定
//繼承是通向多態的入口
person.f2();
person.gotobed();
person.eat();
Student stu = new Student();
stu.eat();
stu.gotobed();
//父類的引用可以調用子類的方法
}
Java中,父類的引用既能夠指向父類的對象,也能夠指向子類的對象。但子類的引用不能指向父類的對象。
引用類型也能夠進行類型轉換。
但轉換的類型必定具備繼承關係,即僅容許父子類之間進行轉換。
若是嘗試將毫無關聯的兩個類型進行轉換,將會引起編譯錯誤。可使用instanceof來判斷引用是否爲指定的類型。
咱們先對比下String, StringBuffer, StringBuilder這三個類。他們的主要區別通常體如今線程安全和執行效率上。
String類是用final修飾符修飾的,它的值是不可修改的,所以是線程安全的。 若是一個StringBuffer對象在緩衝區被多個線程使用時,由於StringBuffer的方法都是帶有synchronized關鍵字的,因此能夠保證線程安全,而StringBuilder的方法沒有該關鍵字,不能保證線程安全,所以可能會出現一些操做錯誤。多線程狀況下建議使用StringBuffer,單線程建議使用速度較快的StringBuilder。
先看一段代碼:
String str = "abcdef";
str = str + "123456";
System.out.println(str);
這段代碼輸出的結果是: 「abcdef123456」, 看着好像是str被改變了,但實際上這是一種假象,JVM對上述代碼是這樣處理的。 1.執行第一行代碼:新建一個String對象「abcdef」(該對象保存在字符串常量池中)將「abcdef」對象的實例引用賦值給str(保存在棧中)。 2.執行第二行代碼: 再新建一個String對象str,用來執行str + "123456"操做,也就是說,str這個對象是沒有發生改變的(String不可變)。每當用String操做字符串時,其實是在不斷的建立新的對象,而原來的對象就會變爲垃圾被GC回收掉,可想而知這樣執行效率會有多低。 一個特殊例子:
String str = "This is a" + "special" + "example";
StringBuilder stringBuilder = new StringBuilder("This is a").append("special").append("example");
你會發現生成str對象的速度簡直太快了,而這個時候StringBuilder速度上根本一點都不佔優點。 其實這是JVM的一個把戲,實際上:String str = "This is a" + "special" + "example";其實就是: String str = 「This is a special example」;因此不須要太多的時間了。 要注意的是,若是你的字符串是來自另外的String對象的話,速度就沒那麼快了,譬如:
String str2 = "This is a";
String str3 = "special";
String str4 = "test";
String str = str2 +str3 + str4;
這時候JVM會規規矩矩的按照原來的方式去作。
1.若是要操做少許的數據用 --> String 2.單線程操做字符串緩衝區 下操做大量數據 --> StringBuilder 3.多線程操做字符串緩衝區 下操做大量數據 --> StringBuffer
將一個類定義在另外一個類裏面或者一個方法裏面,這樣的類稱爲內部類。
成員內部類能夠無條件訪問外部類的全部成員屬性和成員方法(包括private成員和靜態成員)。
當成員內部類擁有和外部類同名的成員變量或者方法時,會發生隱藏現象,即默認狀況下訪問的是成員內部類的成員。
局部內部類是定義在一個方法或者一個做用域裏面的類,它和成員內部類的區別在於局部內部類的訪問僅限於方法內或者該做用域內。
匿名內部類就是沒有名字的內部類
指被聲明爲static的內部類,他能夠不依賴內部類而實例,而一般的內部類須要實例化外部類,從而實例化。靜態內部類不能夠有與外部類有相同的類名。不能訪問外部類的普通成員變量,可是能夠訪問靜態成員變量和靜態方法(包括私有類型)
一個 靜態內部類去掉static 就是成員內部類,他能夠自由的引用外部類的屬性和方法,不管是靜態仍是非靜態。可是不能夠有靜態屬性和方法、
1.每一個內部類都能獨立的繼承一個接口的實現,因此不管外部類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。內部類使得多繼承的解決方案變得完整,
2.方便將存在必定邏輯關係的類組織在一塊兒,又能夠對外界隱藏。
3.方便編寫事件驅動程序
4.方便編寫線程代碼
抽象類不能建立實例,它只能做爲父類被繼承。抽象類是從多個具體類中抽象出來的父類,它具備更高層次的抽象。從多個具備相同特徵的類中抽象出一個抽象類,以這個抽象類做爲其子類的模板,從而避免了子類的隨意性。
(1) 抽象方法只做聲明,而不包含實現,能夠當作是沒有實現體的虛方法
(2) 抽象類不能被實例化
(3) 抽象類能夠但不是必須有抽象屬性和抽象方法,可是一旦有了抽象方法,就必定要把這個類聲明爲抽象類
(4) 具體派生類必須覆蓋基類的抽象方法
(5) 抽象派生類能夠覆蓋基類的抽象方法,也能夠不覆蓋。若是不覆蓋,則其具體派生類必須覆蓋它們
(1) 接口不能被實例化
(2) 接口只能包含方法聲明
(3) 接口的成員包括方法、屬性、索引器、事件
(4) 接口中不能包含常量、字段(域)、構造函數、析構函數、靜態成員
(1)抽象類能夠有構造方法,接口中不能有構造方法。
(2)抽象類中能夠有普通成員變量,接口中沒有普通成員變量
(3)抽象類中能夠包含靜態方法,接口中不能包含靜態方法
(4) 一個類能夠實現多個接口,但只能繼承一個抽象類。
(5)接口能夠被多重實現,抽象類只能被單一繼承
(6)若是抽象類實現接口,則能夠把接口中方法映射到抽象類中做爲抽象方法而沒必要實現,而在抽象類的子類中實現接口中方法
(1) 均可以被繼承
(2) 都不能被實例化
(3) 均可以包含方法聲明
(4) 派生類必須實現未實現的方法