JAVA基礎學習總結(不按期更新)

1、java語法基礎java

一、finalc++

關於final的問題我曾經被問到兩次,因此首先說一下這個東西。編程

應用於變量,表示該變量一旦被賦值則不能夠改變,可是有一個特殊的:StringBuffer,看下面一個例子設計模式

final StringBuffer sb=new StringBuffer("123");數組

這樣寫 sb=new StringBuffer("");會報錯,可是sb.append("111");不會報錯。安全

final是指引用變量不能變,但變量的內容是不能夠改變的。StringBuffer 只是有這樣一個方法能夠改變它的內容而已。數據結構

應用於方法,表示該方法不能夠被重寫覆蓋。多線程

應用與類,表示該類不能夠被繼承。app

二、關於private,public,protected,friendly異步

能夠用一個表格說明他們的權限和訪問範圍,當修飾元素沒有修飾符時默認是friendly

- 表示不支持 √ 表示支持

修飾符 當前類 同一包 子孫類 其餘包
public
protected -
friendly - -
private - - -

三、基本數據類型

byte、int、short、double、float、long、double、boolean

級別從低到高爲byte,char,short(這三個平級)-->int-->float-->long-->double

由低級到高級系統會自動轉換,由高級到低級須要強制轉換。

四、運算符

a++ 和++a區別

二者都表示a+1可是前者表示先進行運算,而後給a+1,後者表示先a+1,再參加運算,例如:a=2;b=a++;能夠理解爲b=a,a=a+1;b=++a;能夠理解爲a=a+1,b=a;一樣a--和--a相似

& 和 &&(| 和||)區別

首先二者都表示與運算符,兩邊條件均爲true時結果才爲true,其餘狀況均爲false;

&&有短路功能,例如a&&b,當a爲false時,就不會執行b;可是a&b無論a爲true或者false,b都會執行。

& 還能夠看成位運算符,兩邊表達式不是boolean類型時,表示按位與操做。

有一個關於位運算的題:請編程實現計算1234變成二進制之後包含多少1。

通常思路就是先經過Integer.toBinaryString(int i)方法轉換成二進制,而後遍歷裏面1的個數。

這裏說一下不一樣進制之間的轉換方法:

十進制轉成十六進制:
Integer.toHexString(int i)
十進制轉成八進制
Integer.toOctalString(int i)
十進制轉成二進制
Integer.toBinaryString(int i)
十六進制轉成十進制
Integer.valueOf("FFFF",16).toString()
八進制轉成十進制
Integer.valueOf("876",8).toString()
二進制轉十進制
Integer.valueOf("0101",2).toString()

其實經過位運算能夠實現更快的方法。

public static void main(String[] args) {
  int c=0;
  int t=1234;
  while (t>0) {
   t=t&(t-1);
   c++; 
  }
  System.out.print(c);
 }

說明一下,t&(t-1)實際上是 t 的二進制進行移位運算,0&1=0,1&0=0,1&1=1。

說道移位運算還有一個:請用最有效率的方法計算出2乘以8的結果。

2<<3   一個數左移幾位就至關於這個數乘以2的幾回方,2*八、等價於2左移3位

五、Override和Overload的區別(重寫和重載區別)。

重載是指同一個類中能夠存在多個命名相同的方法,可是各個方法的參數個數或類型必須不一樣,而且不能夠經過改變方法的返回值來表示兩個方法的不通。

重寫是指子類能夠與父類的方法名稱參數相同,等於徹底把父類的方法覆蓋了。可是對於異常,子類的方法必須比父類拋出更少的異常或者是父類異常的子異常。

六、java內存

java內存大概分爲5塊:寄存器,本地方法區,方法區,堆,棧。

棧:主要用來存儲局部變量,當運算完成所在趨於結束,內存將被釋放。

堆:存儲數組和對象。

七、成員變量和局部變量區別

成員變量在類裏面定義,只在類裏面有效;局部變量存在方法中定義,只在方法所在的大括號有效。

成員變量存在於堆內存中;局部變量存在與棧內存中

八、this 和 super

this 一般用來表示對象自己,super訪問父類被子類隱藏的變量或覆蓋的方法。

若是一個類繼承自父類,那麼子類的super()方法即對父類的初始化。當類中有兩個同名變量,一個屬於類(類的成員變量),而另外一個屬於某個特定的方法(方法中的局部變量),使用this區分紅員變量和局部變量。

調用super()必須寫在子類構造方法的第一行,不然編譯不經過。每一個子類構造方法的第一條語句,都是隱含地調用super(),若是父類沒有這種形式的構造函數,那麼在編譯的時候就會報錯。

super()和this()相似,區別是super從子類中調用父類的構造方法this()在同一類內調用其它方法。

super的本質是java的一個關鍵字,this的本質是一個指向本對象的指針。

九、單例模式

保證一個類在內存中的對象中惟一性。

步驟:一、私有化構造函數。二、建立一個靜態的私有的本類對象。三、提供一個對外調用的方法

單例模式的建立有兩種:懶漢式,餓漢式

首先來看下懶漢式:

public class Single {
  public static Single single;  
  private Single(){
  }
  public static Single getInstance(){
 if (single==null) {
  single=new Single();
   }     
 return single;   
 }
}

能夠看出當須要Single的時候,隨時用隨時new,這樣之後就不用實例了,再看下餓漢式:

 public class Single {
  public static Single singleInstance=new Single(); 
  private Single(){
  } 
  public static Single getInstance(){    
    return single;   
  }
}

比較推薦餓漢式,由於他不用考慮線程安全問題,懶漢模式下若是有兩個線程同時訪問,第一個線程走到if後尚未執行new,第二個線程也會判斷爲Null,從新建立一個實例,這樣就建立了兩個。固然有一種方法能夠解決這個問題那就是synchronized,看一下代碼:

 public class Single {
  public static Single single;  
  private Single(){
  }
  public  synchronized static Single getInstance(){
  if (single==null) {
  single=new Single();
   }     
return single;   
}
}

固然這樣是能夠的,實現了同步鎖,可是其實還能夠進行優化,這樣每次調用getInstance()都會受同步鎖的影響,效率會下降。其實只要保證new的時候同步就能夠了,這種方法叫雙重鎖定(Double-Check Locking)有興趣的能夠查一下,先看代碼:

 public class Single {
  public static Single single;  
  private Single(){
  }
  public static Single getInstance(){
  if(sing==null){
  synchronized (Single.class){
  if (single==null) {
  single=new Single();
   }    
   } 
   }
return single;   
}
}

10abstract 

抽象類的特色:

1:抽象方法只能定義在抽象類中,抽象類和抽象方法必須由abstract關鍵字修飾(能夠描述類和方法,不能夠描述變量)。

2:抽象方法只定義方法聲明,並不定義方法實現。

3:抽象類不能夠被建立對象(實例化)。

4:只有經過子類繼承抽象類並覆蓋了抽象類中的全部抽象方法後,該子類才能夠實例化。不然,該子類仍是一個抽象類。

十一、String、StringBuffer、StringBuilder區別

因爲String類是final修飾的,因此string對象是不可變的,當前它也就是線程安全的。

StringBuffer和StringBuilder都是繼承AbstractStringBuilder類,他們都是可變的。

因爲StringBuffer對方法或者調用的方法加了同步鎖,StringBuilder沒有加,因此StringBuilder是非線程安全的,StringBuffer是線程安全的。

在不kao慮多線程的狀況下,StringBuilder效率要高於StringBuffer。

十二、==和equals區別

==表示兩個對象在內存中存儲的值相等,而equals是兩個對象的內容相等。

好比:String a=new String("123");String =new String("123");

若是用a==b的話返回false,而a.equals(b)返回true,a和b的內容是相等的,可是a、b是不通的兩個對象,他們的首地址是不同的,因此a==b返回false。

1三、JAVA集合類

有時候會有這樣的題:請說出幾個JAVA經常使用的集合類,他們都有什麼區別?

集合你們並不陌生,經常使用的什麼ArrayList、map等,下面來介紹一下JAVA的集合類。

總的來講總共分爲兩大部分一個是Collection接口,一個是Map接口。

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set

│├AbstractSet

│├HashSet

│└TreeSet

Map
├Hashtable
├HashMap
└WeakHashMap

 先說下Collection,由Collection又派生出兩個接口:List和set,二者最大的區別就是list容許有重複元素,set不容許有重複元素;List是有序的,而set除了TreeSet之外,都是無序的。

給定一個字符串(長度不會超過500,必定會有重複的字符),編程返回字符串內第一個重複的字符。例如:「tyuioqiwyss」,返回值:i  。

public static char getFirstRepeat(String str){
  HashSet<Object> hs=new HashSet<>(); //定義一個hashset
  char[] m=str.toCharArray();//將字符串放進一個char數組
  for (int i = 0; i < m.length; i++) {
   boolean b=hs.add(m[i]);//遍歷數組元素放進hashset
   if (!b) {             //因爲hashset不容許有重複元素,因此當有重複元素被添加的時候就會返回false
    return m[i];         
   }
  }
  return 0;
 }

List下面又有ArrayList、LinkedList、Vector和stack,先說下ArrayList、LinkedList的區別:一、ArrayList是基於動態數組的數據結構,對於查找訪問操做效率較高;LinkedList是基於鏈表的數據結構,對於元素的增長刪除效率較高。二者都是非同步的。Vector和stack固然就是同步的了,stack繼承自Vector,實現了一個後進先出的堆棧。

Set接口是不容許插入重複元素的。

Map的元素是用key,value的形式存儲的,能夠存入相同的value可是key要保證惟一。

1四、Math

關於math有幾個經常使用的方法。

Math.ceil():向上取整   Math.ceil(11.5)=12   Math.ceil(-11.5)=-11

Math.floor():向下取整  Math.floor(11.5)=11  Math.floor(-11.5)=-12

Math.round():四捨五入  Math.round(11.5)=12  Math.round(-11.5)=-11  Math.round(-11.6)=-12

1五、關於異或運算

給定兩個Int參數,編程返回兩個參數二進制數有多少位不一樣。

異或運算是這樣的:兩位相同則爲0,不一樣則爲1。0000^0011=0011 1001^1100=0101

因此先把給定的兩個參數作異或運算,獲得的值在判斷他的二進制裏面有多少1即有多少個不一樣的位。

 public static int Sample(int m,int n) {
  int s=m^n; //異或運算
 int count=0;//統計1的個數
  while (s>0) {
   s=s&(s-1);//進行與運算,相似移位運算 0&0=0 0&1=0 1&1=1 1&0=0
   count++;
  }
  return count;
  
 }

 

1六、面向對象的特色,說說對他們的理解。

封裝:可使程序實現「高內聚,低耦合」,對象是封裝的最基本單位。

繼承:提升軟件的可重用性和可擴展性

抽象:把某些具備相同特徵的事物抽象成一個具體的類,只關心咱們須要的地方

多態:增長軟件的靈活性和可擴展性

1七、列舉常見的異常及可能產生緣由,異常解決方法?

NullPointerException 空指針異常 簡單地說就是調用了未經初始化的對象或者是不存在的對象,好比調用了未初始化對象的方法

ArrayIndexOutOfBoundsException 數組越界 調用的數組長度與實際數組長度不一致,好比一個數組有3個元素,獲取第四個元素時就會出現這個異常,因此最好先查看一下數組長度。

NumberFormatException 數字強轉異常 常見於把一個字符串轉爲Int 類型是,Intenger.parseInt("123#")就會拋出異常。

ClassCastException 數據類型轉換異常 如用戶在輸入日期的時候只輸入月、日信息,而沒有年份的信息。此時應用程序在進行數據類型轉換的時候,就會出現異常。

IllegalArgumentException 方法的參數錯誤 好比g.setColor(int red,int green,int blue)這個方法中的三個值,若是有超過255的也會出現這個異常,所以一旦發現這個異常,咱們要作的,就是趕忙去檢查一下方法調用中的參數傳遞是否是出現了錯誤。

異常的處理一般咱們使用try catch來處理可能出現的異常,固然咱們應該是捕獲這個異常來處理。下面是有關異常處理的幾個關鍵字:

throws 捕獲並向外拋出異常

throw 拋出異常

try catch 內部捕獲異常並作自定義處理

finally 不管是否有異常都會被處理的語句

1八、線程相關

1)實現一個線程

兩種方法:繼承thread和實現Runnable接口

2)sleep() wait()區別

sleep()是thread類的一個方法,他須要指定一個時間告訴線程暫停指定時間,時間到了繼續執行,暫停期間依然佔用CPU;wait()是Object類的一個方法,不須要指定時間,想恢復執行的話須要調用notify或者notifyAll方法,暫停期間不會佔用CPU資源。

3)同步和異步

若是數據須要在線程間共享,一個線程在讀取數據,另外一個線程在插入數據,這個時候就須要保證同步讀取。若是一個線程須要調用的方法須要執行很長時間,但其餘線程又不須要該線程的數據返回時應該用異步。

4)啓動一個線程是調用start()方法,run()方法是線程進入執行狀態所執行的方法。

1九、輸入輸出流

JAVA的輸入輸出流有兩種 字節流和字符流。字節流繼承InputOutStream、OutputStream,字符流繼承自InputOutStreamReader、OutputStreamReader。字節流主要操做對象是byte,字符流主要操做對象是字符或者字符串。

字節流在操做的時候自己是不會用到緩衝區(內存)的,是與文件自己直接操做的,而字符流在操做的時候是使用到緩衝區的

字節流在操做文件時,即便不關閉資源(close方法),文件也能輸出,可是若是字符流不使用close方法的話,則不會輸出任何內容,說明字符流用的是緩衝區,而且可使用flush方法強制進行刷新緩衝區,這時才能在不close的狀況下輸出內容。

20、內存溢出和內存泄漏(主要針對Android中的狀況進行分析)

內存溢出:應用使用的內存大於機器的最大內存。
內存泄漏:cursor使用完了沒有關閉;Bitmap沒有回收;構造Adapter時,沒有使用 convertView

2一、抽象類和接口的區別

一、抽象類能夠有成員變量,接口裏通常沒有。若是有的話默認必須是static final類型的。

二、一個類能夠實現多個接口但只能繼承一個抽象類

三、抽象類裏面能夠有非抽象的方法,接口裏面的方法都是抽象的,也就是實現他的類裏面必須實現他的方法。

四、抽象類中的抽象方法的訪問類型能夠是public、protected或者包訪問類型。而接口中的抽象方法只能是public abstract類型,接口的方法前面能夠不加修飾符,默認就是public abstract類型。

2二、java中靜態屬性、靜態代碼塊、非靜態屬性、非靜態代碼塊、構造函數在new的時候執行順序是怎樣的?

對於沒有繼承其餘類的執行順序是這樣的:

靜態屬性--靜態代碼塊--非靜態屬性--非靜態代碼塊--構造函數

若是繼承了其餘類:

父類的公共靜態屬性和靜態代碼塊--自身的靜態屬性和靜態代碼塊--父類的非靜態屬性和非靜態代碼塊--父類的構造函數--自身的非靜態屬性和非靜態代碼塊--自身的構造函數

2三、什麼是編譯型語言,什麼是解釋型語言?JAVA屬於哪種?

編譯型語言是指程序在執行前須要有一個單獨的編譯過程,將程序翻譯成機器語言,之後執行這個程序的時候,就不用再進行翻譯了。

解釋型語言是指是每次在運行的時候將程序翻譯成機器語言,因此運行速度相對於編譯型語言要慢。

C/C++ 等都是編譯型語言,而Java,C#,腳本語言等都是解釋型語言。

雖然Java程序在運行以前也有一個編譯過程,可是並非將程序編譯成機器語言,而是將它編譯成字節碼(能夠理解爲一箇中間語言)。
在運行的時候,由JVM將字節碼再翻譯成機器語言。

2四、經常使用的設計模式有哪些?

單例模式、工廠模式、觀察者設計模式、適配器模式等。

2五、synchronized修飾靜態方法和非靜態方法的區別

synchronized在靜態方法上表示調用前要得到類的鎖,而在非靜態方法上表示調用此方法前要得到對象的鎖。

public class StaticSynDemo {

private static String a="test";

//等同於方法print2
public synchronized void print1(String b){ //調用前要取得StaticSynDemo實例化後對象的鎖
   System.out.println(b+a);
}
public void print2(String b){
   synchronized (this) {//取得StaticSynDemo實例化後對象的鎖
    System.out.println(b+a);
   }
}
//等同於方法print4
public synchronized static void print3(String b){//調用前要取得StaticSynDemo.class類的鎖
   System.out.println(b+a);
}
public static void print4(String b){
   synchronized (StaticSynDemo.class) { //取得StaticSynDemo.class類的鎖
    System.out.println(b+a);
   }
}
}

 

相關文章
相關標籤/搜索