天天看點

最全Java知識點

HashCode被設計用來提高性能。equals()方法與hashCode()方法的差別在于:

1,如果兩個對象相等(equal),那麼他們一定有相同的哈希值。

2,如果兩個對象的哈希值相同,但他們未必相等(equal)。

設計模式:

代理模式:

定義:為其他對象提供一種代理,以控制對這個對象的通路

     代理對象起到中介的作用,可去掉功能服務或增加額外的服務

     火車票代售點就是火車站售票處的代理

常見的代理模式:

遠端代理:  為不同地理的對象提供區域網路代表對象,

  例:用戶端&伺服器

虛拟代理: 根據需要将資源消耗很大的對象進行延遲,真正需要的時候進行建立

  例:浏覽文章,正文優先加載,圖檔延遲加載

保護代理: 對權限進行控制

  例:隻有登入才能發帖等等

   智能引用代理:  提供對目标對象額外服務

  例: 火車票代售處提供一些額外服務

以隻能引用代理為例:

靜态代理:代理和被代理對象在代理之前是确定的。他們都實作相同的接口或繼承相同的抽象類

------------------------------------------------------------------------------------------------------------

下列哪種說法是正确的( )

  A 執行個體方法可直接調用超類的執行個體方法

  B 執行個體方法可直接調用超類的類方法

  C 執行個體方法可直接調用其他類的執行個體方法

  D 執行個體方法可直接調用本類的類方法

  選d,類方法就是靜态方法。其它的就是執行個體方法

  執行個體方法可以對目前對象的執行個體變量進行操作,也可以對類變量進行操作,

  但類方法不能通路執行個體變量。執行個體方法必須由執行個體對象來調用,而類方法除了可由執行個體對象調用外,還可以由類名直接調用。

  另外,在類方法中不能使用 this 或 super。 關于類方法的使用,有如下一些限制:

  1 在類方法中不能引用對象變量。

  2 在類方法中不能使用super、this關鍵字。

  3 類方法不能調用類中的對象方法。與類方法相比,執行個體方法幾乎沒有什麼限制:

  1 執行個體方法可以引用對象變量(這是顯然的),也可以引用類變量。

  2 執行個體方法中可以使用super、this關鍵字。

  3 執行個體方法中可以調用類方法。

------------------------------------------------------------------------------------------------------------

關于C++/JAVA類中static 成員和對象成員的說法正确的是?

 A static 成員變量在對象構造時生成

 B static 成員函數在對象成員函數中無法調用

 C 虛成員函數不可能是static成員函數

 D static 成員函數不能通路static成員變量

 static為成員變量或函數,在類初始化是加載完成,可以被成員函數調用或通路

 在java語言中虛函數指代的就是抽象方法,抽象方法中不能用private,static,synchronized,native等修飾詞修飾。

------------------------------------------------------------------------------------------------------------

有如下一段代碼,請選擇其運作結果()

 public class StringDemo{

    private static final String MESSAGE="taobao";

    public static void main(String [] args) {

       String a ="tao"+"bao";

       String b="tao";

       String c="bao";

       System.out.println(a==MESSAGE);

       System.out.println((b+c)==MESSAGE);

    }

  }

 Java對String的相加是通過StringBuffer實作的,先構造一個StringBuffer裡面存放”tao”,

 然後調用append()方法追加”bao”,然後将值為”taobao”的StringBuffer轉化成String對象。

 StringBuffer對象在堆記憶體中,那轉換成的String對象理所應當的也是在堆記憶體中。

 MESSAGE成員變量及其指向的字元串常量肯定都是在棧記憶體裡的

 對于字元串常量的相加,在編譯時直接将字元串合并,而不是等到運作時再合并。也就是說

 String a = "tao" + "bao" 和String a =  "taobao"編譯出的位元組碼是一樣的。

 是以等到運作時,根據上面說的棧記憶體是資料共享原則,a和MESSAGE指向的是同一個字元串。

------------------------------------------------------------------------------------------------------------

接口和抽象類:

相同點:都不能被執行個體化,位于繼承樹的頂端,都包含抽象方法

不同點:1、設計目的:

接口:

     展現的一種規範,類似與整個系統的總綱,

               制訂了系統各子產品應該遵循的标準,是以接口不應該經常改變,一旦改變對整個系統是輻射性的。

抽象類:

                      作為多個子類的共同父類,展現的是一種模闆式設計,可以當作系統實作過程中的中間産品,已經實作了系統部分功能。

        2、使用不同

    (1)接口隻能包含抽象方法,抽象類可以包含普通方法。

    (2)接口裡不能定義靜态方法,抽象類可以。

    (3)接口隻能定義靜态常量屬性,不能定義普通屬性,抽象類可以。

    (4)接口不包含構造器,抽象類可以(不是用于建立對象而是讓子類完成初始化)。

    (5)接口裡不能包含初始化塊,抽象類完全可以。

    (6)接口多繼承,抽象類單繼承(隻能有一個直接父類)。

總結:

   接口所有方法全是抽象方法隻能public abstract修飾(預設public abstract修飾),屬性預設public static final修飾。

抽象類除了包含抽象方法外與普通類無差別。 

------------------------------------------------------------------------------------------------------------

關于volatile關鍵字,下列描述

A 用volatile修飾的變量,每次更新對其他線程都是立即可見的   //正确

B 對volatile變量的操作是原子性的   //錯誤

C 對volatile變量的操作不會造成阻塞   //正确

D 不依賴其他鎖機制,多線程環境下的計數器可用volatile實作     //錯誤

------------------------------------------------------------------------------------------------------------

兩個最基本的java回收算法:

   複制算法和标記清理算法

                複制算法:兩個區域A和B,初始對象在A,繼續存活的對象被轉移到B。此為新生代最常用的算法

                标記清理:一塊區域,标記要回收的對象,然後回收,一定會出現碎片,那麼引出

                标記-整理算法:多了碎片整理,整理出更大的記憶體放更大的對象

   兩個概念:新生代和年老代

                新生代:初始對象,生命周期短的

                永久代:長時間存在的對象

   整個java的垃圾回收是新生代和年老代的協作,這種叫做分代回收。

   P.S: Serial New收集器是針對新生代的收集器,采用的是複制算法

         Parallel New(并行)收集器,新生代采用複制算法,老年代采用标記整理

         Parallel  Scavenge(并行)收集器,針對新生代,采用複制收集算法

         Serial Old(串行)收集器,新生代采用複制,老年代采用标記清理

         Parallel   Old(并行)收集器,針對老年代,标記整理

         CMS收集器,基于标記清理

         G1收集器:整體上是基于标記清理,局部采用複制

綜上:新生代基本采用複制算法,老年代采用标記整理算法。cms采用标記清理。

------------------------------------------------------------------------------------------------------------

Java虛拟機功能:

 1 通過 ClassLoader 尋找和裝載 class 檔案

 2 解釋位元組碼成為指令并執行,提供 class 檔案的運作環境

 3 進行運作期間垃圾回收

 4 提供與硬體互動的平台

------------------------------------------------------------------------------------------------------------

關于ThreadLocal以下說法正确的是?

A ThreadLocal繼承自Thread         //錯誤,ThreadLocal繼承Object,相當于沒繼承任何特殊的。

B ThreadLocal實作了Runnable接口         //錯誤,ThreadLocal沒有實作任何接口

C ThreadLocal重要作用在于多線程間的資料共享       //錯誤

D ThreadLocal是采用哈希表的方式來為每個線程都提供一個變量的副本              //正确

E ThreadLocal保證各個線程間資料安全,每個線程的資料不會被另外線程通路和破壞   //正确

   線程的角度看,每個線程都保持一個對其線程局部變量副本的隐式引用,隻要線程是活動的并且 ThreadLocal 執行個體是可通路的;

線上程消失之後,其線程局部執行個體的所有副本都會被垃圾回收

------------------------------------------------------------------------------------------------------------

以下JAVA程式的輸出是什麼()

public class HelloSogou{

     public static synchronized void main(String[] a){

         Thread t=new Thread(){

             public void run(){Sogou();}

     };

     t.run();

     System.out.print("Hello");

     }

     static synchronized void Sogou(){

     System.out.print("Sogou");

    }

}

A HelloSogou     B SogouHello        C Hello       D 結果不确定

------------------------------------------------------------------------------------------------------------

如果是t.start(),(靜态同步函數的鎖是該類的位元組碼檔案.class main函數和Sogou方法都是static的,是以持有相同鎖

HelloSogou.class那麼,在main線程(main 是一個線程也是一個程序 )中又開了一個線程,調用Sogou方法,鎖會沖突。 選D

但是,t.run()隻是普通方法,順序執行,選B

-----------------------------------------------------------------------------------------------------------

ServerSocket (int port)

建立一個serversocket 綁定在特定的端口

Socket(InetAddress address, int port)

建立一個socket流,連接配接到特定的端口和ip位址

------------------------------------------------------------------------------------------------------------

一般關系資料模型和對象資料模型之間有以下對應關系:表對應類,記錄對應對象,表的字段對應類的屬性。

------------------------------------------------------------------------------------------------------

線程通過調用對象的synchronized方法可獲得對象的互斥鎖定;

線程排程算法是平台獨立的:

線程排程分為協同式排程和搶占式排程,Java使用的是搶占式排程,也就是每個線程将由作業系統來配置設定執行時間,

線程的切換不由線程本身來決定(協同式排程)。這就是平台獨立的原因。

------------------------------------------------------------------------------------------------------------

優化Hibernate所鼓勵的7大措施:

1.盡量使用many-to-one,避免使用單項one-to-many

2.靈活使用單向one-to-many

3.不用一對一,使用多對一代替一對一

4.配置對象緩存,不使用集合緩存

5.一對多使用Bag 多對一使用Set

6.繼承使用顯示多态 HQL:from object polymorphism="exlicit" 避免查處所有對象

7.消除大表,使用二級緩存

------------------------------------------------------------------------------------------------------------

class Car extends Vehicle

{

    public static void main (String[] args)

    {

        new  Car(). run();

    }

    private final void run()

    {

        System. out. println ("Car");

    }

}

class Vehicle

{

    private final void run()

    {

        System. out. println("Vehicle");

    }

}

首先final聲明的方法是不能被覆寫的,但是這裡并不錯誤,因為方法是private的,

也就是子類沒有繼承父類的run方法,是以子類的run方法跟父類的run方法無關,并不是覆寫。

new Car().run()也是調用子類的run方法。輸出Car。

************************************************************************************************************v

************************************************************************************************************

public class Test2

{

    public void add(Byte b){

        b = b++;

    }

    public void test(){

        Byte a = 127;

        Byte b = 127;

        add(++a);

        System.out.print(a + " ");

        add(b);

        System.out.print(b + "");

    }

}

public void add(Byte b){ b=b++; } 這裡涉及java的自動裝包/自動拆包(AutoBoxing/UnBoxing) 

Byte的首字母為大寫,是類,看似是引用傳遞,但是在add函數内實作++操作,會自動拆包成byte值傳遞類型,

是以add函數還是不能實作自增功能。也就是說add函數隻是個擺設,沒有任何作用。 Byte類型值大小為-128~127之間。

add(++a);這裡++a會越界,a的值變為-128 add(b); 前面說了,add不起任何作用,b還是127

************************************************************************************************************

************************************************************************************************************

class C {

    C() {

        System.out.print("C");

    }

}

class A {

    C c = new C();

    A() {

        this("A");

        System.out.print("A");

    }

    A(String s){

        System.out.print(s);

    }

}

class Test extends A{

    Test(){

        super("B");

        System.out.print("B");

    }

    public static void main(String[] args) {

        new Test();

    }

}

//解答1:

初始化過程是這樣的: 父類B靜态代碼塊->子類A靜态代碼塊->父類B非靜态代碼塊->父類B構造函數->子類A非靜态代碼塊->子類A構造函數

1.首先,初始化父類中的靜态成員變量和靜态代碼塊,按照在程式中出現的順序初始化; 

2.然後,初始化子類中的靜态成員變量和靜态代碼塊,按照在程式中出現的順序初始化; 

3.其次,初始化父類的普通成員變量和代碼塊,在執行父類的構造方法;

4.最後,初始化子類的普通成員變量和代碼塊,在執行子類的構造方法; 

(1)初始化父類的普通成員變量和代碼塊,執行 C c = new C(); 輸出C 

(2)super("B"); 表示調用父類的構造方法,不調用父類的無參構造函數,輸出B 

(3) System.out.print("B"); 

 是以輸出CBB

//解答2:

首先new了一個子類對象,那麼就要調用構造方法來初始化該子類對象,但是該類繼承自A,是以要先調用父類的構造方法,

這裡通過super("B")顯示的調用了父類的帶參構造。

執行父類的帶參構造前要先對父類中的對象進行初始化,對父類中的c成員進行初始化,調用了C類的無參構造,是以調用順序為:

先調用C類的無參構造

再調用A類的帶參構造

最後調用調用子類的構造

------------------------------------------------------------------------------------------------------------

假設有以下代碼String s = "hello":String t = “hello”;char c [ ] = {'h','e','l','l','o'};下列選項中傳回false的語句是?

A s.equals (t);

B t.equals (c);

C s==t;

D t.equals (new String ("hello"));

Sting 類儲存字元串隻是儲存所有單單的字元串;

而 char[] 字元數組 會在最後自動加上'\n';

是以B:t.equals(c)會傳回fasle;

是以 答案B

------------------------------------------------------------------------------------------------------------

根據下面的代碼,

String s = null;

會抛出NullPointerException異常的有:

  A if( (s!=null) & (s.length()>0) )  B if( (s!=null) && (s.length()>0) )

  C if( (s==null) | (s.length()==0))  D if( (s==null) || (s.length()==0) )

String s=null;沒有給s開辟任何空間,當執行length()方法時候,

因為沒有具體指向的記憶體空間,是以報出NullPointerException沒有指向的錯誤。

A &是與,位運算,兩個都得執行,執行到s.length()自然就報錯了。

B s!=null  結果為false 整體就為false ,&& 後面就不會執行。下面的同理。 AC

------------------------------------------------------------------------------------------------------------

************************************************************************************************************

************************************************************************************************************

HashMap和Hashtable兩個類都實作了Map接口,二者儲存K-V對(key-value對)

HashTable不允許null值(key和value都不可以),HashMap允許null值(key和value都可以)。

Hashtable的方法是Synchronize的,而HashMap不是,在多個線程通路Hashtable時,不需要自己為它的方法實作同步,而HashMap就必須為之提供外同步

疊代 HashMap 采用快速失敗機制,而 HashTable 不是,因為 HashTable是線程安全的

HashMap把Hashtable的contains方法去掉了,改成 containsvalue 和 containsKey。因為contains方法容易讓人引起誤解

HashTable使用Enumeration,HashMap使用Iterator

************************************************************************************************************

************************************************************************************************************

------------------------------------------------------------------------------------------------------------

例化線程: 1、如果是擴充java.lang.Thread類的線程,則直接new即可。

           2、如果是實作了java.lang.Runnable接口的類,則用Thread的構造方法:

public class MyRunnable implements Runnable{ 

     public void run()             { 

        (new Thread(new MyRunnable()).start()

     } 

 }

------------------------------------------------------------------------------------------------------------

<<表示左移位

>>表示帶符号右移位

>>>表示無符号右移

但是沒有<<<運算符

------------------------------------------------------------------------------------------------------------

  CopyOnWriteArrayList适用于讀多寫少的并發場景

  ReadWriteLock即為讀寫鎖,要求寫與寫之間互斥,讀與寫之間互斥,讀與讀之間可以并發執行。在讀多寫少的情況下可以提高效率

  ConcurrentHashMap是同步的HashMap,讀寫都加鎖

  volatile隻保證多線程操作的可見性,不保證原子性

------------------------------------------------------------------------------------------------------------

String str = new String("abc"),"abc"在記憶體中是怎麼配置設定的?

A 堆

B 棧

C 字元串常量區

D 寄存器

當你new String("abc")時,其實會先在字元串常量區生成一個abc的對象,然後new String()時會在堆中配置設定空間,

然後此時會把字元串常量區中abc複制一個給堆中的String,故abc應該在堆中和字元串常量

------------------------------------------------------------------------------------------------------------

byte b1=1,b2=2,b3,b6,b8;

final byte b4=4,b5=6,b7;

b3=(b1+b2);  

b6=b4+b5;    

b8=(b1+b4);  

b7=(b2+b5);  

上面代碼片段中,存在編輯錯誤的語句是?

本題答案應為:B、C、D

Java表達式轉型規則由低到高轉換:

1、所有的byte,short,char型的值将被提升為int型;

2、如果有一個操作數是long型,計算結果是long型;

3、如果有一個操作數是float型,計算結果是float型;

4、如果有一個操作數是double型,計算結果是double型;

5、被fianl修飾的變量不會自動改變類型,當2個final修飾相操作時,結果會根據左邊變量的類型而轉化。

語句1錯誤:b3=(b1+b2);  自動轉為int,是以正确寫法為b3=(byte)(b1+b2);或者将b3定義為int;

語句2正确:b6=b4+b5;    b4、b5為final類型,不會自動提升,是以和的類型視左邊變量類型而定,即b6可以是任意數值類型;

語句3錯誤:b8=(b1+b4);  雖然b4不會自動提升,但b1仍會自動提升,是以結果需要強轉,b8=(byte)(b1+b4);

語句4錯誤:b7=(b2+b5);  同上。同時注意b7是final修飾,即隻可指派一次,便不可再改變。

------------------------------------------------------------------------------------------------------------

Java類Demo中存在方法func0、func1、func2、func3和func4,請問該方法中,哪些是不合法的定義?( )

public class Demo{

  float func0() byte,short,char-> int -> long -> float -> double

  { 小轉大不用強轉,大轉小需要強轉

    byte i=1; func1  沒有傳回值;func4  大轉小需要強轉

    return i;

  }

  float func1()

  {

    int i=1;

    return;

  }

  float func2()

  {

    short i=2;

    return i;

  }

  float func3()

  {

    long i=3;

    return i;

  }

  float func4()

  {

    double i=4;

    return i;

  }

}

------------------------------------------------------------------------------------------------------------

java中除了基本資料類型都是引用資料類型

java中的基本資料類型如下:

byte   short  int   long   float   double   char  boolean

除此之外都是引用類型

------------------------------------------------------------------------------------------------------------

可用來實作線程間通知和喚醒:

    Object.wait/notify/notifyAll

    Condition.await/signal/signalAll

------------------------------------------------------------------------------------------------------------

Statement是sql語句的載體

Statement是标準的Statement類,通過字元串對sql語句進行拼接,但是它存在sql注入的危險

PreparedStatement對sql語句進行了預編譯,可以防止SQL注入

CallableStatement用來調用存儲過程的

BatchedStatement用于批量操作資料庫,BatchedStatement不是标準的Statement類

------------------------------------------------------------------------------------------------------------

面向對象的五大基本原則:

   單一職責原則(SRP)

   開放封閉原則(OCP) 

   裡氏替換原則(LSP) 

   依賴倒置原則(DIP) 

   接口隔離原則(ISP)

-----------------------------------------------------------------------------------------------------------

下面有關java執行個體變量,局部變量,類變量和final變量的說法,錯誤的是?

A 執行個體變量指的是類中定義的變量,即成員變量,如果沒有初始化,會有預設值    // 正确

B 局部變量指的是在方法中定義的變量,如果沒有初始化,會有預設值            //********局部變量必須有初始值******

C 類變量指的是用static修飾的屬性       //正确

D final變量指的是用final修飾的變量       //正确

------------------------------------------------------------------------------------------------------------

構造函數不可以用private修飾   //錯誤,單例模式中,構造器私有化

構造函數必須與類名相同        //正确

構造方法不能被子類繼承,是以用final修飾沒有意義。

構造方法用于建立一個新的對象,不能作為類的靜态方法,是以用static修飾沒有意義。

此外,Java語言不支援native或synchronized的構造方法

-----------------------------------------------------------------------------------------------------------

Java預設使用Unioncode編碼,即不論什麼語言都是一個字元占兩個位元組

Java的class檔案編碼為UTF-8,而虛拟機JVM編碼為UTF-16

UTF-8編碼下,一個中文占3個位元組,一個英文占1個位元組

Java中的char預設采用Unicode編碼,是以Java中char占2個位元組

1(byte)位元組=8(bit)位

------------------------------------------------------------------------------------------------------------

floor:   求小于參數的最大整數。傳回double類型-----n. 地闆,地面

         例如:Math.floor(-4.2) = -5.0

ceil:   求大于參數的最小整數。傳回double類型-----vt. 裝天花闆;

         例如:Math.ceil(5.6) = 6.0

round:  對小數進行四舍五入後的結果。傳回int類型

         例如:Math.round(-4.6) = -5

----------------------------------------------------------------------------------------------------------

Integer i = 42;

Long l = 42l;

Double d = 42.0;   下面為true的是?

A i == l         B i == d      C l == d

D i.equals(d)        E d.equals(l)        F i.equals(l)      G l.equals(42L)

ABC3 個選項很明顯,不同類型引用的 == 比較,會出現編譯錯誤,不能比較。

DEF 調用 equals 方法,因為此方法先是比較類型,而 i , d , l 是不同的類型,是以傳回假。

選項 G ,會自動裝箱,将 42L 裝箱成 Long 類型,是以調用 equals 方法時,類型相同,且值也相同,是以傳回真

------------------------------------------------------------------------------------------------------------

Java緻力于檢查程式在編譯和運作時的錯誤

Java虛拟機實作了跨平台接口

類型檢查幫助檢查出許多開發早期出現的錯誤

Java自己操縱記憶體減少了記憶體出錯的可能性

Java還實作了真數組,避免了覆寫資料的可能

注意,是避免資料覆寫的可能,而不是資料覆寫類型 

------------------------------------------------------------------------------------------------------------

java不允許單獨的方法,過程或函數存在,需要隸屬于某一類中

java語言中的方法屬于對象的成員,而不是類的成員。不過,其中靜态方法屬于類的成員

-----------------------------------------------------------------------------------------------------------

形式參數可被視為local variable

對于形式參數隻能用final修飾符

形參的值在調用時根據調用者更改,實參則用自身的值更改形參的值(指針、引用皆在此列),也就是說真正被傳遞的是實參