時(shí)間在一分一秒的過去,面臨求職面試也是越來越近了,在看面試題以及??途W(wǎng)做題時(shí),遇到了很多不理解或者之前沒見過的,就把他總結(jié)下來了,發(fā)個(gè)博客,大家共勉,之后會(huì)持續(xù)更新。
1、String類都有那些常用的方法。
length(); split(); replace();
equals(); subString(); charAt();
concat(); 大小寫轉(zhuǎn)換; indexOf();
trim(); isEmpty(); contains();
startWith()
補(bǔ)充:Object類方法
clone、 equals finalize getClass
hashCode notify notifyAll toString
wait
補(bǔ)充:異常分類
算數(shù)異常 類型轉(zhuǎn)換異常 非法參數(shù)異常
下標(biāo)越界異常 空指針異常 安全性檢查異常
need-to-insert-img
need-to-insert-img
2、StringBuilder和StringBuffer區(qū)別
根本區(qū)別就是StringBuilder是線程不安全的,而StringBuffer是線程安全的。
速度,StringBuilder > StringBuffer > String
String是不可變的,其他兩個(gè)是可變的
按照性能排序 String(大姐,jdk1.0) < StringBuffer(二姐,jdk1.0)
StringBuffer很多方法都被synchronized修飾了,而StringBuilder沒有,所以StringBuilder速度比StringBuffer快。建議用StringBuilder。
JVM運(yùn)行程序主要時(shí)間都是浪費(fèi)在創(chuàng)建對象和回收對象上。
eg:String s = “this is”+“only”“simple test”;等同于 String s = “this is only simple test”。
3、Map和List的遍歷區(qū)別
List:增強(qiáng)的for循環(huán)(最差)、for(int i=0;i
List:對越arrayList、Vector遍歷應(yīng)該采用隨機(jī)訪問get
LinkedList:采用迭代器
關(guān)于Map能不能存儲(chǔ)null情況
?keyvalue?
TreeMap不允許允許線程不安全
HashMap允許允許線程不安全
關(guān)于Map遍歷的entrySet和keySet
推薦使用entrySet,說明,keySet其實(shí)是遍歷了兩次,一次轉(zhuǎn)化為Iterator對象,另一次是從HashMap中取出key所對應(yīng)的value,而entrySet只遍歷了一次就把他key和value全部都存到entry中了,效率更高。
need-to-insert-img
Set代表無序,不重復(fù),Map代表key-value組成的集合,Map的key要求是不能重復(fù),沒有順序,把Map的所有key組合起來就是Set。
4、數(shù)組與List區(qū)別
ArrayList的底層實(shí)現(xiàn)還是數(shù)組,索引速度快。
LinkedList:是基于鏈表。
對于隨機(jī)訪問,get set ArrayList優(yōu)秀。
對于新增和刪除,LinkedList優(yōu)秀
5、Set和List區(qū)別
根本:Set 無序,不重復(fù)。 List:有序,元素可重復(fù)
Java遍歷List
第一種:???
for(Iterator?it?=?list.iterator();?it.hasNext();)?{?????
????......??
}??
這種方式在循環(huán)執(zhí)行過程中會(huì)進(jìn)行數(shù)據(jù)鎖定,??? 性能稍差,??? 同時(shí),如果你想在循環(huán)過程中去掉某個(gè)元素,只能調(diào)用it.remove方法, 不能使用list.remove方法, ?否則一定出并發(fā)訪問的錯(cuò)誤. ??
第二種:
for(A?a?:?list)?{??
????......??
}??
它內(nèi)部還是調(diào)用第一種,??? 換湯不換藥,??? 這種循環(huán)方式還有其他限制,??? 不建議使用它???
第三種:???
for(int?i?=?0;?i?<?list.size();?i++)?{??
????A?a?=?list.get(i);??
????......??
}??
它內(nèi)部不做鎖定,??? 效率最高,??? 但是當(dāng)寫多線程時(shí)要考慮并發(fā)操作的問題!??
注:TreeMap和HashMap,Hash底層采用數(shù)組來保存key和value
6、垃圾回收
System.gc();
Runtime.gc() 也就是 Runtime.getRuntime().gc();
7、反射機(jī)制
在Java運(yùn)行環(huán)境中獲取類的屬性和方法,調(diào)用對象的任意一個(gè)方法,這種動(dòng)態(tài)獲取類的信息,以及動(dòng)態(tài)動(dòng)態(tài)調(diào)用對象的方法的功能,就叫做Java的反射機(jī)制。
8、Java的數(shù)據(jù)類型
need-to-insert-img
補(bǔ)充:關(guān)于float與double精度丟失問題
float:有效位是7位。
double:有效位16位
9、Java類加載機(jī)制
10、棧和鏈表有什么區(qū)別
棧:先進(jìn)后出。
鏈表:隨便什么地方都可以插入刪除
11、Map、HashMap、LinkedHashMap存儲(chǔ)結(jié)構(gòu)以及實(shí)現(xiàn)原理
HashMap底層是用數(shù)組實(shí)現(xiàn)的。
Map中包括一個(gè)內(nèi)部類Entry,封裝了一個(gè)key-value
LinkedHashMap采用雙向鏈表來維護(hù)元素關(guān)系,因?yàn)橐S護(hù)元素順序,所以性能略低于HashMap。
12、short s1 =1, s1 = s1 + 1 有錯(cuò)嗎,shrot s1 = 1 , s1 +=1有錯(cuò)嗎。
對于第一種,由于1是int型,因此s1 + 1 運(yùn)算是int型,需要強(qiáng)制類型轉(zhuǎn)化,
而第二種相當(dāng)于 s1 = (short)(s1 + 1)其中隱含了強(qiáng)制類型轉(zhuǎn)化。
13、Integer 和int區(qū)別。
注意:就是涉及到自動(dòng)裝箱。
Integer a1 = new Integer(3);
Integer a2 = 3;
System.out.println(a1 == a2); //false 如果a2是int型,就是true
Integer a = 15;
Integer b = 15;
Integer c = 129;
Integer d = 128;
System.out.println(a == b); //true
System.out.println(c ==d ); //false
注:如果整形字面的量值在-128 ~128之間,那么不new對象,而是引用常量池中的Integer對象。
訪問控制符
類成員:private、default、protected、public
修飾類:public、final、abstract
修飾方法:public、默認(rèn)、protected、private、|static、find、abstract
修飾變量:public、默認(rèn)、protected、private、|static、find
類型private無protectedpublic
同一類√√√√
同一包中子類?√√√
同一包非子類?√√√
不同包子類??√√
不同包非子類???√
14、HashMap采用拉鏈法解決沖突(鏈地址法)
HashMap有兩個(gè)參數(shù)影響性能,初始容量和加載因子(裝填因子)。
鏈表法就是將相同hash值的對象組織成一個(gè)鏈表放在hash值對應(yīng)的槽位中。
開放地址法是通過一個(gè)探測算法,當(dāng)某個(gè)槽位已經(jīng)被占據(jù)的情況下繼續(xù)尋找下一個(gè)可以使用的槽位,很顯然,HashMap解決沖突的方法是拉鏈法,也叫鏈地址法。
15、關(guān)于Java默認(rèn)導(dǎo)入的包。
Java.lang,包含如下
Object:是所有類的父類。
基礎(chǔ)類型包裝類
數(shù)學(xué)類
String和StringBuilder
系統(tǒng)和運(yùn)行時(shí)類:System.in 和out 是標(biāo)準(zhǔn)的輸入類和輸出類,System所有成員變量和方法都是靜態(tài)的。
16、關(guān)于==和equals
==可用于基本類型和引用類型的比較,采用Integer比較,只要new,就不同。Integer.valueOf()和Integer a = 53,等價(jià)。切記Intger.valueOf()的源碼,大于127都要new。
17、Java語言中數(shù)組復(fù)制的方法.
System.arrayCopy() > clone > Arrays.copyOf -> for循環(huán)賦值。(按性能排序)。
need-to-insert-img
關(guān)于clone方法:Java.lang.Object類的clone()方法,為protected類型,不可直接調(diào)用,需要先對要克隆的對象進(jìn)行下列操作,首先被克隆的類應(yīng)該實(shí)現(xiàn)Cloneable接口,然后在該類中覆蓋clone方法,并且在該類中調(diào)用super.clone()方法。
need-to-insert-img
復(fù)制引用和賦值對象的區(qū)別。
復(fù)制引用:是指將某個(gè)對象的地址復(fù)制,所以復(fù)制后的對象副本的地址和源對象相同,這樣,當(dāng)改變副本的某個(gè)值后,源對象值也被改變;
復(fù)制對象:是將源對象整個(gè)復(fù)制,對象副本和源對象的地址并不相同,當(dāng)改變副本的某個(gè)值后,源對象值不會(huì)改變;
Cat?cat1=new?Cat("xiaohua",3);//源對象??
????????System.out.println("源對象地址"+cat1);??
????????//調(diào)用clone方法,復(fù)制對象??
????????Cat?cat2=(Cat)cat1.clone();??
????????Cat?cat3=(Cat)cat1;//復(fù)制引用??
????????System.out.println("復(fù)制對象地址:"+cat2);??
????????System.out.println("復(fù)制引用地址:"+cat3);
need-to-insert-img
可以看出,復(fù)制引用的對象和源對象地址相同,復(fù)制對象和源對象地址不同
18、關(guān)于靜態(tài)代碼塊,代碼塊,構(gòu)造方法的執(zhí)行順序.
父類靜態(tài)代碼塊-》子類靜態(tài)代碼塊-》父類構(gòu)造代碼塊-》父類構(gòu)造函數(shù)-》子類構(gòu)造代碼塊-》子類構(gòu)造函數(shù)。
注意:構(gòu)造代碼塊和構(gòu)造函數(shù)一起執(zhí)行。
先執(zhí)行靜態(tài)初始化快,普通初始化快和午餐的構(gòu)造函數(shù)一起i執(zhí)行。
19、&& 和&
&&短路,如果&&左邊位false,直接短路掉
&非短路。
20、return、break、和continue
return:直接退出循環(huán)
break:跳出本層循環(huán)
continue:跳過本次循環(huán)
補(bǔ)充:break只能用在循環(huán)語句中,while,do....while或者for 或者switch中
21、Math.round(11.5等于多少)
12.round其實(shí)就是四舍五入
注:關(guān)于四舍五入的方法
//第一種方法,使用DecimalFormat來格式化數(shù)字。
String ss = new DecimalFormat("#.000").format(s);
System.out.println("DecimalFormat四舍五入: "+ ss);
//第二種方式,使用String.format
System.out.println("使用String.format:" + String.format("%.3f", s));
//第三種方式,使用技巧round 這種方式存在問題
System.out.println("使用技巧round:" + Math.round(s*1000)*0.001d);
//錯(cuò)誤System.out.println("使用技巧round:" + Math.round(s*1000*0.001d));
//第四種方式
BigDecimal big = new BigDecimal(s);
double d = big.setScale(3, BigDecimal.ROUND_HALF_EVEN).doubleValue();
System.out.println("第四種方式獲?。? + d);
System.out.println(big.setScale(3, BigDecimal.ROUND_HALF_UP));
22、switch是否作用于byte上,是否作用long,是否String
Java5之前,switch(expr)。expr只能是byte,short,int,char
Java5之后,enum,
Java7,String
long,目前還不支持
23、數(shù)組有沒有l(wèi)ength()方法,String有沒有l(wèi)ength屬性?
數(shù)組有l(wèi)ength屬性,String有l(wèi)ength方法。
24、構(gòu)造器不能被繼承,所以不能被重寫,但課重載,
25、為什么不能通過返回值類型區(qū)分重載
例如 int f(),void f(),在方法調(diào)用時(shí)可以省略類型f(),這時(shí)系統(tǒng)怎么處理?會(huì)找不到,會(huì)迷糊,所以,通過返回值區(qū)分重載行不通。
26、String s = new String("xyz"),創(chuàng)建了幾個(gè)對象。
創(chuàng)建了兩個(gè)對象,一個(gè)是靜態(tài)區(qū)的。
27、Java中的final關(guān)鍵字有那些用法,
修飾類,表示該類不能被繼承。
修飾方法
修飾變量
28、關(guān)于字符編碼轉(zhuǎn)換,就是利用String的構(gòu)造方法和普通方法。
String a = "你好";
String b = new String(a.getBytes("gb2312"),"ISO-8859-1");
System.out.println(b);
String c = new String(a,"gbk").getBytes("utf-8");//第二種
29、TreeMap和TreeSet在排序時(shí),如何比較元素,Collection中的sort()方法如何比較元素,
TreeSet要求所有存放對象必須實(shí)現(xiàn)Comparable接口,該接口提供compareTo()方法,
TreeMap要求存放的鍵值對映射的建必須實(shí)現(xiàn)Compareable接口,從而根據(jù)建進(jìn)行排序。
Collection.sort()有兩種排序方式:
傳入的對象實(shí)現(xiàn)了Comparable
不強(qiáng)制要求傳入元素必須課比較,但如要傳入第二個(gè)參數(shù),參數(shù)時(shí)實(shí)現(xiàn)Comparable接口的子類型,相關(guān)于臨時(shí)定義了一個(gè)排序規(guī)則。
關(guān)于comparable(java.lang)和compartor(java.util)
list列表中所有元素必須實(shí)現(xiàn)Comparable接口,實(shí)現(xiàn)Comparable需要重寫comparTo方法。
使用Comparable有很大局限性,實(shí)現(xiàn)此接口只能按compareTo(T t)定義的方法。
一個(gè)類的兌現(xiàn)更要實(shí)現(xiàn)多種排序方式,可以為該接口定義不同的比較器,實(shí)現(xiàn)comparator接口
附:compartor與comparable區(qū)別:comparator接口與Comparable接口的區(qū)別
補(bǔ)充:線程和進(jìn)程的區(qū)別
進(jìn)行是執(zhí)行著的應(yīng)用程序,而線程是進(jìn)程內(nèi)部的一個(gè)執(zhí)行序列,一個(gè)進(jìn)程可以又多個(gè)線程,
線程同步:
使用lock與使用同步方法有點(diǎn)類似,只是使用lock時(shí)顯示使用lock對象作為同步鎖,而使用同步方式時(shí)系統(tǒng)隱世使用當(dāng)前對象作為同步監(jiān)視器。而使用lock對象時(shí),每個(gè)lock對象對應(yīng)一個(gè)Account對象,一樣可以保證對于同一個(gè)Account對象,同一時(shí)間只能又一個(gè)線程進(jìn)入臨界區(qū)。
30、關(guān)于Thread類的sleep方法和對象(Object)的wait方法。
Thread.sleep() Object.wait()
調(diào)用了sleep時(shí)線程類休眠的靜態(tài)方法,調(diào)用此方法會(huì)讓當(dāng)前線程暫停執(zhí)行指定事件,將執(zhí)行機(jī)會(huì)(CPU)讓給其他線程,但對象的鎖依然保持,因此休眠結(jié)束后自動(dòng)恢復(fù)。
wait是Object的方法,調(diào)用wait方法導(dǎo)致當(dāng)前線程放棄對象所進(jìn)入線程池,只有調(diào)用對象的notify()方法,才能被重新喚醒。
31、創(chuàng)建線程的三種方法。
繼承Thread
實(shí)現(xiàn)Runnable
使用Callable和FUTURE(2、3實(shí)現(xiàn)方式相同,所以歸結(jié)到一類)
推薦采用實(shí)現(xiàn)Runnable接口,Callable接口來創(chuàng)建線程,因?yàn)槿绻抢^承,就浪費(fèi)了一次繼承的機(jī)會(huì),導(dǎo)致無法再繼承其他的類,而接口不一樣。
32、狀態(tài)
線程是進(jìn)行內(nèi)的并發(fā),沒有自己的內(nèi)存空間,共享進(jìn)程的。
線程的四種狀態(tài):就緒,執(zhí)行,掛起。結(jié)束
need-to-insert-img
join:等待另一個(gè)線程完成
Sleep()之后線程進(jìn)入阻塞狀態(tài),然后進(jìn)入就緒狀態(tài),
wait()之后線程進(jìn)入等待隊(duì)列,等待喚醒進(jìn)入就緒狀態(tài)。
yield執(zhí)行后線程進(jìn)入就緒狀態(tài)(直接進(jìn)入就緒狀態(tài),不進(jìn)入阻塞)
join執(zhí)行后線程進(jìn)入阻塞狀態(tài)
need-to-insert-img
need-to-insert-img
sleep與yield
sleep()方法暫停后,會(huì)給其他線程機(jī)會(huì),不會(huì)理會(huì)優(yōu)先級,
sleep()方法會(huì)將線程轉(zhuǎn)入阻塞狀態(tài),然后進(jìn)入就緒狀態(tài),而yield()不會(huì)將線程轉(zhuǎn)入阻塞,只是i強(qiáng)制當(dāng)前進(jìn)程進(jìn)入就緒,因此完全有可能某個(gè)線程調(diào)用yield()方法暫停后,立即再次獲得處理器資源執(zhí)行
sleep()方法拋出一個(gè)InterruptedExecption異常。
sleep(0放比yield()方法具有更好的一致性,通常不建議使用yield()方法來控制并發(fā)線程執(zhí)行。
線程相關(guān):
1、關(guān)鍵字synchronized 、static、abstract、final
synchronized:用于方法或代碼塊前,使此方法或者代碼塊編程同步的。
static:用于聲明靜態(tài)變量,static關(guān)鍵字可以修飾變量,方法,靜態(tài)代碼塊。
? ? ? ? ? ? ? ? ? ? ? ? ??靜態(tài)變量:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 由static修飾的變量稱為靜態(tài)變量
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 靜態(tài)變量屬于類,而不屬于某個(gè)對象
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??靜態(tài)變量它的副本只有一個(gè)(靜態(tài)變量在類中只加載一)
? ? ? ? ? ? ? ? ? ? ? ? ?靜態(tài)方法:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??在靜態(tài)方法中只能調(diào)用靜態(tài)變量和靜態(tài)方法
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 在非靜態(tài)方法中,可以調(diào)用靜態(tài)方法或者變量。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??在靜態(tài)方法中不能使用this和super關(guān)鍵字。
? ? ? ? ? ? ? ? ? ? ? ? 靜態(tài)代碼塊
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??作用:用來給靜態(tài)成員變量初始化
abstract:用于定義抽象類或者方法
final:用于聲明常量,即只能賦一次值
volatile:用來確保將變量的跟新操作通知到其他線程,當(dāng)把變量聲明為volatile類型后,編譯器與運(yùn)行時(shí)都會(huì)注意到這個(gè)變量是共享的,因此不會(huì)將該變量上的操作與其他內(nèi)存操作一起重排序。然而,在訪問volatile變量時(shí)不會(huì)執(zhí)行加鎖操作,因此也就不會(huì)使執(zhí)行線程阻塞,因此volatile變量是一種比?synchronized關(guān)鍵字更輕量級的同步機(jī)制。
serialize:Java 對象序列化為二進(jìn)制文件
33、Java中如何實(shí)現(xiàn)序列化以及實(shí)現(xiàn)序列化的意義。
實(shí)現(xiàn)Serializable接口
意義:可以將硫化后的對象進(jìn)行讀寫操作,也可用于網(wǎng)絡(luò)之間對象傳輸,序列化是為了解決對象流讀寫坐坐時(shí)引發(fā)的問題。
34、xml文檔有幾種形式?本質(zhì)?解析。
兩種:dtd schema
schema本身也是一個(gè)xml文件,可以被xml解析,約束能力大于dtd
解析xml有兩種:
dom:使用dom要預(yù)先加載整個(gè)文件適合隨機(jī)訪問,(空間換時(shí)間)
SAX:是事件驅(qū)動(dòng)型,適合對xml順序訪問。
35、簡述JDBC
加載驅(qū)動(dòng),Class.forName("com.mysql.jdbc.");
創(chuàng)建鏈接,Connention conn = DriverManager.getConnection("")
創(chuàng)建語句:PrepareStatement ps = conn.prepareStatement("");
執(zhí)行語句:ResultSet rs = ps.executeQuery()
處理結(jié)果
關(guān)閉資源
36、事務(wù)的ACID:原子性,一致性,隔離性,持久性
臟讀:A事務(wù)讀取B事務(wù)尚未提交的數(shù)據(jù),并再次基礎(chǔ)上操作,而B事務(wù)執(zhí)行回滾,那么A事務(wù)讀到的數(shù)據(jù)就是臟數(shù)據(jù)。
不可重復(fù)讀:A事務(wù)重新讀取前面讀取過的數(shù)據(jù),發(fā)現(xiàn)該數(shù)據(jù)已經(jīng)被另一個(gè)已提交的事務(wù)B修改了。
幻讀:
37、獲取一個(gè)對象
A.class()
a.getClass()
Class.forName()
38、Arrays.toString(int[]),Arrays工具類的頭String方法。
首先檢查是否為空,如果為空就return "[]",否則,StringBuilder,先append一個(gè)"[",然后循環(huán),append一個(gè)數(shù),if 到結(jié)尾 return appent ”]“,否則append(",")
39、類變量是指用satic修飾的屬性,
40、在子類構(gòu)造方法中使用super(),顯示調(diào)用父類的構(gòu)造方法,super()必須卸載子類構(gòu)造方法第一行,否則不通過。
41、Java是一次編寫多出運(yùn)行,c++是一次編寫多處編譯
42、新生代,老年代,持久代
43、LinkedList實(shí)現(xiàn)了List,而不是繼承,AbstractSet實(shí)現(xiàn)了Set
44、StringBuilder通過調(diào)用toString()方法轉(zhuǎn)換為String型。
45、override重寫,overloadding重載。
重寫是子類重新定義了父類的方法,重寫必有相同的方法名,參數(shù)列表和返回值類型。
重載是發(fā)生在同一個(gè)類里面的兩個(gè)或多個(gè)方法名相同,但參數(shù)不同的情況
46、什么是java虛擬機(jī),為什么java被稱為平臺(tái)無關(guān)語言,
Java虛擬機(jī)是一個(gè)可執(zhí)行Java字節(jié)碼的虛擬機(jī)進(jìn)程,Java源文件被編譯成能被Java虛擬機(jī)執(zhí)行的字節(jié)碼文件。
47、關(guān)于抽象類和接口,區(qū)別和共同點(diǎn)。
接口中的方法都是抽象的,而抽象類則可以同時(shí)包含抽象和非抽象方法。
類可以實(shí)現(xiàn)多個(gè)接口,但只能繼承一個(gè)抽象類。
類可以不實(shí)現(xiàn)抽象類和接口中聲明的方法,當(dāng)然在這種情況下類也必須是抽象的。
抽象類可以在比提供接口實(shí)現(xiàn)的情況下實(shí)現(xiàn)接口。
接口中聲明的變量默認(rèn)都是final的,抽象類可以包含非final的
接口中的成員函數(shù)默認(rèn)都是public的,抽象類的成員函數(shù)可以是private、protected或者public
接口是絕對抽象的,不可以被實(shí)例化,抽象類也是不可以被實(shí)例化的
48、Iterator,ListIterator
Iterator可以遍歷set和list集合,但是ListInterator只能用來遍歷List
Itertator只能向前遍歷,ListIterator既可以向前也可以向后,
ListIterator實(shí)現(xiàn)了Iterator接口。
49、快速失敗和安全失敗的區(qū)別是什么
Java.util都是快速失敗,
Java.util.conncurrent包瞎所有類都是安全失敗的。
快速失敗會(huì)拋出ConncurrentModificationException異常,而安全失敗永遠(yuǎn)不會(huì)拋出這樣的異常。
50、Java中HashMap的工作原理。
Java中HashMap以鍵值對形式存儲(chǔ)元素,HashMap需要一個(gè)hash函數(shù),它使用hashCode()和equals()方法向集合添加元素,當(dāng)調(diào)用put()方法時(shí),HashMap會(huì)計(jì)算key的hash值。
HashMap的一些重要的特性是它的容量、負(fù)載因子和擴(kuò)容極限。