面試:第一章:java基礎各種區(qū)別
Java基本類型哪些,所占字節(jié)
byte :1個字節(jié)
short :2個字節(jié)
char :2個字節(jié)
int :4個字節(jié)
long :8個字節(jié)
float :4個字節(jié)
double :8個字節(jié)
java集合以及底層原理
Java集合框架的根接口有Collection和Map。Collection根接口包含List和Set二個子接口。
List接口
它的特點是:元素有序、且可重復,主要包含三個實現(xiàn)類:ArrayList,vector,LinkedList
ArrayList的特點:底層是數(shù)組,線程不安全,查找快,增刪慢(數(shù)組的特點)。
ArrayList的底層實現(xiàn)原理:通過ArrrayList空參構造器創(chuàng)建對象。
底層創(chuàng)建一個長度為10的數(shù)組,當我們向數(shù)組中添加11個元素時,底層會進行擴容,擴容為原來的1.5倍
(創(chuàng)建一個新的數(shù)組,長度為原數(shù)組長度的1.5倍,將原數(shù)組復制到新數(shù)組中)。
vector的特點:古老的實現(xiàn)類,底層是數(shù)組,線程安全的,JDK1.0就有了,Vector總是比ArrayList慢,所以盡量避免使用。
LinkedList的特點:底層是使用雙向鏈表。增刪快,查找慢。
Set接口
它的特點:
無序性:通過HashCode方法算出的值來決定在數(shù)組中存放的位置;
不可重復性:進行equals方法比較,結果為true則兩個數(shù)據(jù)相同,若為false則不同。
主要包含三個實現(xiàn)類:HashSet,LinkedHashSet,TreeSet
HashSet特點:線程不安全,集合元素可以為null,不能保證元素的排列順序
HashSet的底層實現(xiàn)原理:
當向HashSet添加數(shù)據(jù)時,首先調(diào)用HashCode方法決定數(shù)據(jù)存放在數(shù)組中的位置,該位置上沒有其他元素,
則將數(shù)據(jù)直接存放,若該位置上有其他元素,調(diào)用equals方法進行比較。若返回true則認為兩個數(shù)據(jù)相同,
若返回false,則以鏈表的形式將該數(shù)據(jù)存在該位置上,(jdk1.8)如果數(shù)量達到8則將鏈表換成紅黑樹。
HashSet的底層就是一個HashMap,向HashSet中添加的數(shù)據(jù)實際上添加到了HashMap中的key里。
所以HashMap的key可以看成是Set的集合。
LinkedHashSet特點:繼承了HashSet,底層實現(xiàn)原理和HashSet一樣,可以安照元素添加的順序進行遍歷
根據(jù)元素的hashCode值來決定元素的存儲位置,它維護了一張鏈表該鏈表記錄了元素添加的順序。
底層就是一個LinkedHashMap。
TreeSet特點:底層為紅黑樹;可以安照指定的元素進行排序;TreeSet中的元素類型必須保持一致,
底層就是TreeMap。TreeSet必須(自然排序)實現(xiàn)Comparable接口,重寫compareTo()方法,
按照某個屬性進行排序,相結合添加元素或(定制排序)創(chuàng)建一個Comparator實現(xiàn)類的對象,
并傳入到TreeSet的構造器中,按照某個屬性進行排序,向集合添加元素。定制排序比自然排序靈活。
如果即有自然排序又有定制排序誰起作用? 定制排序
Map接口
Map的特點:
Map存儲的是鍵值對(key,value),Map中的key是無序的且不可重復的,所有的key可以看成是一個set集合。
Map中的key如果是自定義類的對象必須重寫hashCode和equals方法,Map中的value是無序的可重復的,
所有的value可以看成是Collection集合,Map中的value如果是自定義類的對象必須重寫equals方法,
Map中的鍵值對可以看成是一個一個的Entry.Entry所存放的位置是由key來決定的。
Entry是無序的不可重復的。主要的實現(xiàn)類:HashMap,LinkedHashMap,TreeMap,HashTable.
HashMap特點
1.底層是一個數(shù)組 + 鏈表 + 紅黑樹(jdk1.8)
2.數(shù)組的類型是一個Node類型
3.Node中有key和value的屬性
4.根據(jù)key的hashCode方法來決定Node存放的位置
5.線程不安全的 ,可以存放null
HashMap的底層實現(xiàn)原理:
當我們向HashMap中存放一個元素(k1,v1),先根據(jù)k1的hashCode方法來決定在數(shù)組中存放的位置。
如果該位置沒有其它元素則將(k1,v1)直接放入數(shù)組中,如果該位置已經(jīng)有其它元素(k2,v2),調(diào)用k1的equals方法和k2進行比較。
如果結果為true則用v1替換v2,如果返回值為false則以鏈表的形式將(k1,v1)存放,
當元素達到8時則會將鏈表替換成紅黑樹以提高查找效率。
HashMap的構造器:new HashMap() :創(chuàng)建一個容量為16的數(shù)組,加載因子為0.75。
當我們添加的數(shù)據(jù)超過12時底層會進行擴容,擴容為原來的2倍。
LinkedHashMap:繼承了HashMap底層實現(xiàn)和HashMap一樣.
可以安照元素添加的順序進行遍歷底層維護了一張鏈表用來記錄元素添加的順序。
TreeMap特點:可以對Key中的元素安照指定的順序進行排序 ( 不能對value進行排序)
HashTable特點:線程安全的 ,不可以存放null,map中的key不能重復,如果有重復的,后者的value覆蓋前者的value
四大作用域和九大內(nèi)置對象
四大作用域:
page :當前頁面有效時間最短(頁面執(zhí)行期)
request :HTTP請求開始到結束這段時間
session :HTTP會話開始到結束這段時間
application :服務器啟動到停止這段時間
九大內(nèi)置對象:
request :請求對象 作用域 Request
response :響應對象 作用域 Page
pageContext :頁面上下文對象 作用域 Page
session :會話對象 作用域 Session
application :應用程序對象 作用域 Application
out :輸出對象 作用域 Page
config :配置對象 作用域 Page
page :頁面對象 作用域 Page
exception :例外對象 作用域 page
jsp和servlet的區(qū)別
1.jsp經(jīng)編譯后就變成了Servlet.(JSP的本質(zhì)就是Servlet,JVM只能識別java的類,
不能識別JSP的代碼,Web容器將JSP的代碼編譯成JVM能夠識別的java類)
2.jsp更擅長表現(xiàn)于頁面顯示,servlet更擅長于邏輯控制.
3.Servlet中沒有內(nèi)置對象,Jsp中的內(nèi)置對象都是必須通過HttpServletRequest象,
HttpServletResponse對象以及HttpServlet對象得到.
Jsp是Servlet的一種簡化,使用Jsp只需要完成程序員需要輸出到客戶端的內(nèi)容,Jsp中的Java腳本如何鑲嵌到一個類中,由Jsp容器完成。
而Servlet則是個完整的Java類,這個類的Service方法用于生成對客戶端的響應。
servlet生命周期
1.加載和實例化
2.初始化
3.請求處理
4.服務終止
加載(服務器啟動時,會到web.xml文件中去找到Servlet文件的配置并創(chuàng)建servlet的實例)
→初始化(init()此方法只執(zhí)行一次) →執(zhí)行(service(),doGet(),doPost()) →銷毀(銷毀destory())
service():
方法本身包含了doGet()和doPost().如果服務器發(fā)現(xiàn)了service()方法,則不再執(zhí)行doGet(),doPost().
一般不建議去重寫父類的service方法.因為重寫了此方法doGet方法和doPost方法將得不到利用.
沒有service()方法默認執(zhí)行doGet()方法.
cookie和session區(qū)別以及JWT與Session的差異
1、cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務器上。
2、cookie不是很安全,別人可以分析存放在本地的cookie并進行cookie欺騙,考慮到安全應當使用session。
3、session會在一定時間內(nèi)保存在服務器上。當訪問增多,會比較占用你服務器的性能,考慮到減輕服務器性能方面,應當使用cookie。
4、單個cookie保存的數(shù)據(jù)不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
5、可以考慮將登陸信息等重要信息存放為session,其他信息如果需要保留,可以放在cookie中。
1.Session是在服務器端的,而JWT是在客戶端的。
2.Session方式存儲用戶信息的最大問題在于要占用大量服務器內(nèi)存,增加服務器的開銷。
3.JWT方式將用戶狀態(tài)分散到了客戶端中,可以明顯減輕服務端的內(nèi)存壓力。
4.Session的狀態(tài)是存儲在服務器端,客戶端只有session id;而Token的狀態(tài)是存儲在客戶端。
JWT與OAuth的區(qū)別
OAuth2是一種授權框架 ,JWT是一種認證協(xié)議。
無論使用哪種方式切記用HTTPS來保證數(shù)據(jù)的安全性
OAuth2用在使用第三方賬號登錄的情況(比如使用weibo, qq, github登錄某個app)
JWT是用在前后端分離, 需要簡單的對后臺API進行保護時使用。
Cookie和LocalStorage和sessionStorage的區(qū)別
轉發(fā)和重定向的區(qū)別
轉發(fā):瀏覽器地址欄不變,1次請求,request請求,可以訪問web-inf,可以共享request請求域數(shù)據(jù),只能跳轉工程內(nèi)的資源
重定向:瀏覽器變化,2次請求,response響應,不能訪問web-inf,不可以共享request請求域數(shù)據(jù),可以跳轉任意資源
餓漢于懶漢單例模式
單例模式設計:
第一步:私有化構造器
第二步:提供一個公共靜態(tài)返回該類實例對象的方法
餓漢式:先初始化對象,Single類一進內(nèi)存,就已經(jīng)創(chuàng)建好了對象。
class Single{
private Single(){}
private static Single s=new Single();
public static Single getInstance()
{
return s;
}
}
懶漢式:對象是方法被調(diào)用時,才初始化,也叫做對象的延時加載。
class Single{ //Single類進內(nèi)存,對象還沒存在,只有調(diào)用了getInstance方法時,才建立對象
private Single(){}
private static Single s=null;
public static synchronize Single getInstance()
{
if(s==null){
s=new single();
}
return s;
}
}
操作共享的數(shù)據(jù)有多條,會出現(xiàn)線程安全問題,在方法加一個同步
過濾器和攔截器的區(qū)別
①攔截器是基于java的反射機制的,而過濾器是基于函數(shù)回調(diào)。
②攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
③攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。
④攔截器可以訪問action上下文、值棧里的對象,而過濾器不能訪問。
⑤在action的生命周期中,攔截器可以多次被調(diào)用,而過濾器只能在容器初始化時被調(diào)用一次。
⑥攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器里注入一個service,可以調(diào)用業(yè)務邏輯。
#和$的區(qū)別
#{}和${}的區(qū)別
#{} 在mapper的配置文件的sql語句中,它是占位符, 相當于 ? 號。
${} 在 mapper 的配置文件的 sql 語句中,它是原樣輸出變量的值,然后以字符串拼接的功能進行操作。
${} 中只能寫value,或者是@Param命名參數(shù)后的參數(shù)名稱
在輸出參數(shù)的時候,我們并不推薦使用 ${} 來輸出。因為可能會導至 sql 注入問題的存在。
什么是SQL注入?
如果SQL是根據(jù)用戶輸入拼出來,如果用戶故意輸入可以讓后臺解析失敗的字符串,這就是SQL注入
例如,用戶在輸入密碼的時候,輸入' or 1=1', 這樣,后臺的程序在解析的時候,拼成的SQL語句,可能是這樣的:
select count(1) from tab where user=userinput and pass='' or 1=1;
看這條語句,可以知道,在解析之后,用戶沒有輸入密碼,加了一個恒等的條件 1=1,這樣,這段SQL執(zhí)行的時候,
返回的 count值肯定大于1的,如果程序的邏輯沒加過多的判斷,這樣就能夠使用用戶名 userinput登陸,而不需要密碼。
防止SQL注入,首先要對密碼輸入中的單引號進行過濾,再在后面加其它的邏輯判斷,或者不用這樣的動態(tài)SQL拼。
&&和&與|和||的區(qū)別?
&和&&的區(qū)別?
&和&&左邊的式子為true的時候,右邊的式子都會執(zhí)行。
左邊的式子為false的時候。&右邊的式子仍然會執(zhí)行。&&右邊的式子將不再執(zhí)行。
|和||的區(qū)別?
|和||左邊的式子為false的時候,右邊的式子都會執(zhí)行。
左邊的式子為true的時候。|右邊的式子仍然會執(zhí)行。||右邊的式子將不再執(zhí)行。
final finally finalize區(qū)別?
final修飾符,用來修飾變量,方法和類,分別表示屬性不可變,方法不可被重寫,類不可被繼承,finally是異常語句中處理語句,
表示總是執(zhí)行;finalize表示在垃圾回收機制時使該對象狀態(tài)恢復的方法
int和Integer的區(qū)別?
1、Integer是int的包裝類,int則是java的一種基本數(shù)據(jù)類型
2、Integer變量必須實例化后才能使用,而int變量不需要
3、Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲數(shù)據(jù)值
4、Integer的默認值是null,int的默認值是0
equals與==的區(qū)別?
==:如果==兩邊是基本數(shù)據(jù)類型,那么比較的是具體的值。如果==兩邊是引用數(shù)據(jù)類型,那么比較的是地址值。
(兩個對象是否指向同一塊內(nèi)存)
equals:如果沒有重寫equals方法那么調(diào)用的是Object中的equals方法,比較的是地址值。
如果重寫了euqlas方法(比屬性內(nèi)容)那么就比較的是對象中屬性的內(nèi)容。
StringBuff 和StringBuilder及String區(qū)別?
String類是不可變類,任何對String的改變都會引發(fā)新的String對象的生成;
StringBuffer是可變類,任何對它所指代的字符串的改變都不會產(chǎn)生新的對象,線程安全的。
StringBuilder是可變類,線性不安全的,不支持并發(fā)操作,不適合多線程中使用,但其在單線程中的性能比StringBuffer高。
Override和Overload的含義去區(qū)別?
1. Override 特點
1、覆蓋的方法的標志必須要和被覆蓋的方法的標志完全匹配,才能達到覆蓋的效果;
2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
4、方法被定義為final不能被重寫。
5、對于繼承來說,如果某一方法在父類中是訪問權限是private,那么就不能在子類對其進行重寫覆蓋,如果定義的話,
也只是定義了一個新方法,而不會達到重寫覆蓋的效果。(通常存在于父類和子類之間。)
2.Overload 特點
1、在使用重載時只能通過不同的參數(shù)樣式。例如,不同的參數(shù)類型,不同的參數(shù)個數(shù),不同的參數(shù)順序
當然,同一方法內(nèi)的幾個參數(shù)類型必須不一樣,例如可以是fun(int, float), 但是不能為fun(int, int)
2、不能通過訪問權限、返回類型、拋出的異常進行重載;
3、方法的異常類型和數(shù)目不會對重載造成影響;
4、重載事件通常發(fā)生在同一個類中,不同方法之間的現(xiàn)象。
5、存在于同一類中,但是只有虛方法和抽象方法才能被覆寫。
抽象類和接口及普通類的區(qū)別?
1、抽象類和接口都不能直接實例化,如果要實例化,抽象類變量必須指向實現(xiàn)所有抽象方法的子類對象,
接口變量必須指向實現(xiàn)所有接口方法的類對象。
2、抽象類要被子類繼承,接口要被類實現(xiàn)。
3、接口只能做方法申明,抽象類中可以做方法申明,也可以做方法實現(xiàn)
4、接口里定義的變量只能是公共的靜態(tài)的常量,抽象類中的變量是普通變量。
5、抽象類里的抽象方法必須全部被子類所實現(xiàn),如果子類不能全部實現(xiàn)父類抽象方法,那么該子類只能是抽象類。
同樣,一個實現(xiàn)接口的時候,如不能全部實現(xiàn)接口方法,那么該類也只能為抽象類。
6、抽象方法只能申明,不能實現(xiàn),接口是設計的結果 ,抽象類是重構的結果
7、抽象類里可以沒有抽象方法
8、如果一個類里有抽象方法,那么這個類只能是抽象類
9、抽象方法要被實現(xiàn),所以不能是靜態(tài)的,也不能是私有的。
10、接口可繼承接口,并可多繼承接口,但類只能單根繼承。
堆和棧的區(qū)別?
一.堆??臻g分配區(qū)別:
1.棧(操作系統(tǒng)):由操作系統(tǒng)自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結構中的棧;
2.堆(操作系統(tǒng)): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似于鏈表。
二.堆棧緩存方式區(qū)別:
1.棧使用的是一級緩存, 他們通常都是被調(diào)用時處于存儲空間中,調(diào)用完畢立即釋放;
2.堆是存放在二級緩存中,生命周期由虛擬機的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)。
所以調(diào)用這些對象的速度要相對來得低一些。
三.堆棧數(shù)據(jù)結構區(qū)別:
堆(數(shù)據(jù)結構):堆可以被看成是一棵樹,如:堆排序;
棧(數(shù)據(jù)結構):一種先進后出的數(shù)據(jù)結構。
Spring Bean生命周期
實例化bean對象
設置對象屬性
檢查Aware相關接口并設置相關依賴
BeanPostPreocessor前置處理
檢查是否是InitialliziingBean以決定是否調(diào)用afterPropertesSet方法
檢查是否配置有自定義的init-method
BeanPostProcessor后置處理
注冊必要的Destrunction相關回調(diào)接口
使用中
是否實現(xiàn)DisposableBean接口
是否配置有自定義的Destory方法
JDK、JRE、JVM的區(qū)別?
JDK ( Java開發(fā)工具包)= JRE(Java運行環(huán)境) + 開發(fā)工具集(例如Javac編譯工具等)
JRE (Java運行環(huán)境)= JVM (Java虛擬機)+ Java SE標準類庫
值傳遞和引用傳遞的區(qū)別?
值傳遞:會創(chuàng)建副本,函數(shù)中無法改變原始對象
引用傳遞:不會創(chuàng)建副本,函數(shù)中可以改變原始對象
值傳遞:方法調(diào)用時,實際參數(shù)把它的值傳遞給對應的形式參數(shù),方法執(zhí)行中形式參數(shù)值的改變不影響實際參數(shù)的值。
引用傳遞:也稱為傳地址。方法調(diào)用時,實際參數(shù)的引用(地址,而不是參數(shù)的值)被傳遞給方法中相對應的形式參數(shù),
在方法執(zhí)行中,對形式參數(shù)的操作實際上就是對實際參數(shù)的操作,方法執(zhí)行中形式參數(shù)值的改變將會影響實際參數(shù)的值。
4種訪問控制符區(qū)別?
裝箱和拆箱,類型轉換
裝箱:值類型轉換為引用對象,一般是轉換為System.Object類型或值類型實現(xiàn)的接口引用類型;
拆箱:引用類型轉換為值類型,注意,這里的引用類型只能是被裝箱的引用類型對象;
拆箱與裝箱就是值類型與引用類型的轉換
throw和throws區(qū)別
throw代表動作,表示拋出一個異常的動作;
throws代表一種狀態(tài),代表方法可能有異常拋出;
throw用在方法實現(xiàn)中,而throws用在方法聲明中;
throw只能用于拋出一種異常,而throws可以拋出多個異常。
PreparedStatement比Statement區(qū)別?
第一:statement執(zhí)行的SQL語句必須是一個完整的SQL,而對于PreparedStatement來說,可以使用“?”作為
SQL語句當中的占位符,然后使用PreparedStatement的setXXX方法來給占位符賦值,最后在執(zhí)行;
第二:使用Statement時,如果SQL當中出現(xiàn)了“‘”或者“-”等符號時,需要使用轉義字符來進行轉義,而在
PreparedStatement當中,如果占位符的值當中有這些符號,PreparedStatement會自動的進行轉義;
第三:PreparedStatement會講SQL語句進行預編譯,每次執(zhí)行的時候只需要將參數(shù)設置給相應的占位符就可以
運行。而使用Statement時,SQL語句時每次都要進行編譯,所以PreparedStatement的效率相對較高。
doGet()方法和doPost()方法區(qū)別?
get方式 參數(shù)在地址欄中顯示 通過?name=""&id=""這種形式傳遞的 不安全 只能傳遞2kb的能容
post方式 底層是通過流的形式傳遞 不限制大小 上傳的時候必須用Post方式
doGet:路徑傳參。效率高,安全性差
doPOST:實體傳參。效率第,安全性好
null和undefind的區(qū)別?
undefined是訪問一個未初始化的變量時返回的值,而null是訪問一個尚未存在的對象時所返回的值。
Error和Exception的區(qū)別?
Error(錯誤)是系統(tǒng)中的錯誤,程序員是不能改變的和處理的,是在程序編譯時出現(xiàn)的錯誤,只能通過修改程序才能修正。
一般是指與虛擬機相關的問題,如系統(tǒng)崩潰,虛擬機錯誤,內(nèi)存空間不足,方法調(diào)用棧溢等。
對于這類錯誤的導致的應用程序中斷,僅靠程序本身無法恢復和和預防,遇到這樣的錯誤,建議讓程序終止。
Exception(異常)表示程序可以處理的異常,可以捕獲且可能恢復。遇到這類異常,應該盡可能處理異常,使程序恢復運行,
而不應該隨意終止異常。
阻塞和非阻塞以及同步和異步的區(qū)別?
1. 同步,就是我調(diào)用一個功能,該功能沒有結束前,我死等結果。
2. 異步,就是我調(diào)用一個功能,不需要知道該功能結果,該功能有結果后通知我(回調(diào)通知)
3. 阻塞,就是調(diào)用我(函數(shù)),我(函數(shù))沒有接收完數(shù)據(jù)或者沒有得到結果之前,我不會返回。
4. 非阻塞,就是調(diào)用我(函數(shù)),我(函數(shù))立即返回,通過select通知調(diào)用者
同步IO和異步IO的區(qū)別就在于:數(shù)據(jù)拷貝的時候進程是否阻塞
阻塞IO和非阻塞IO的區(qū)別就在于:應用程序的調(diào)用是否立即返回
事務的ACID和事務的隔離性?
1)原子性(Atomic):事務中各項操作,要么全做要么全不做,任何一項操作的失敗都會導致整個事務的失敗;
2)一致性(Consistent):事務結束后系統(tǒng)狀態(tài)是一致的;
3)隔離性(Isolated):并發(fā)執(zhí)行的事務彼此無法看到對方的中間狀態(tài);
4)持久性(Durable):事務完成后所做的改動都會被持久化,即使發(fā)生災難性的失敗。通過日志和同步備份可以在故障發(fā)生后重建數(shù)據(jù)。
臟讀:事務A讀到了事務B未提交的數(shù)據(jù)。
不可重復讀:事務A第一次查詢得到一行記錄row1,事務B提交修改后,事務A第二次查詢得到row1,但列內(nèi)容發(fā)生了變化,側重于次數(shù),
側重于update
幻讀:事務A第一次查詢得到一行記錄row1,事務B提交修改后,事務A第二次查詢得到兩行記錄row1和row2,側重于內(nèi)容,側重于insert
線程的sleep和wait區(qū)別?
sleep()不釋放同步鎖,wait()釋放同步鎖.
sleep可以用時間指定來使他自動醒過來,如果時間不到你只能調(diào)用interreput()來強行打斷;
wait()可以用notify()直接喚起.
sleep和wait的區(qū)別還有:
1。這兩個方法來自不同的類分別是Thread和Object
2。最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
3。wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用
線程的狀態(tài)(階段)?
創(chuàng)建、就緒、運行、阻塞、終止。
1、新建狀態(tài)(New):新創(chuàng)建了一個線程對象。
2、就緒狀態(tài)(Runnable):線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start()方法。該狀態(tài)的線程位于“可運行線程池”中,
變得可運行,只等待獲取CPU的使用權。即在就緒狀態(tài)的進程除CPU之外,其它的運行所需資源都已全部獲得。
3、運行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼。
4、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態(tài),才有機會轉到運行狀態(tài)。
http和https的區(qū)別?
1、https協(xié)議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構建的可進行加密傳輸、身份認證的網(wǎng)絡協(xié)議,比http協(xié)議安全。
常見的運行時異常?
NullPointerException - 空指針引用異常
ClassCastException - 類型強制轉換異常。
IllegalArgumentException - 傳遞非法參數(shù)異常。
ArithmeticException - 算術運算異常
ArrayStoreException - 向數(shù)組中存放與聲明類型不兼容對象異常
IndexOutOfBoundsException - 下標越界異常
NegativeArraySizeException - 創(chuàng)建一個大小為負數(shù)的數(shù)組錯誤異常
NumberFormatException - 數(shù)字格式異常
SecurityException - 安全異常
UnsupportedOperationException - 不支持的操作異常
BIO和NIO區(qū)別?
互聯(lián)網(wǎng) 強調(diào)的是信息/數(shù)據(jù)在網(wǎng)絡之間的流通,
BIO:堵塞式IO,相當于輪船運輸
NIO:非堵塞式IO:面向緩沖區(qū)(buffer),基于通道(chanel)的io操作,相當于火車運輸,效率高
文件->雙向通道((緩沖區(qū)))->程序
冒泡排序和自然排序及定制排序怎么實現(xiàn)的或者手寫出來
冒泡排序
int[] arr={6,3,8,2,9,1};
System.out.println("排序前數(shù)組為:");
for(int num:arr){
System.out.print(num+" ");
}
for(int i=0;i<arr.length-1;i++){//外層循環(huán)控制排序趟數(shù)
for(int j=0;j<arr.length-1-i;j++){//內(nèi)層循環(huán)控制每一趟排序多少次
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println();
System.out.println("排序后的數(shù)組為:");
for(int num:arr){
System.out.print(num+" ");
}
自然排序
1、定義一個類(文章中為Employee)實現(xiàn)Comparable接口
2、重寫Comparable接口中的compareTo()方法
3、在compareTo()中按指定屬性進行排序
public class Employee implements Comparable{
public int compareTo(Object o) {
if (o instanceof Employee) {
Employee e = (Employee) o;
return this.name.compareTo(e.name);//按name進行排序
}
return 0;
}
}
定制排序
1.創(chuàng)建一個Compartor實現(xiàn)類的對象,并傳入到TreeSet的構造器中
2.重寫compare方法
3.安照某個屬性進行排序
4.向集合中添加元素
TreeSet set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Student && o2 instanceof Student) {
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int s = s1.getAge() - s2.getAge();
if(s == 0) {
return s1.getName().compareTo(s2.getName());
}
return s;
}
return 0;
}
});
set.add(new Student("aaa", 18));
set.add(new Student("bbb", 8));
set.add(new Student("fff", 38));
set.add(new Student("ccc", 28));
System.out.println(set);
在使用定制排序或是自然排序時,在其用到的類中都要重寫hashCode()與equals()方法
三種遍歷方式?
第一種遍歷方法和輸出結果。
for(int i=1,i<list.size(),i++){
System.out.println(list.get(i));
}
第二種用foreach循環(huán)。加強型for循環(huán)。推薦方式。
for(String string:list){
System.out.println(string);
}
第三鐘迭代器
List<String> list=new ArrayList<>();
list.add("abc");
list.add("ghi");
for(Iterator<String> it=list.iterator();it.hasNext();){
System.out.println(it.next());
}