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修飾符
形參的值在調用時根據調用者更改,實參則用自身的值更改形參的值(指針、引用皆在此列),也就是說真正被傳遞的是實參