map的生命周期 java,【JAVA面试的艺术】JAVA基础知识阶段三
說一下線程的生命周期?
線程是一個動態(tài)執(zhí)行的過程,它也有一個從產(chǎn)生到死亡的過程,有五種狀態(tài)。
新建(new Thread)
當創(chuàng)建Thread類的一個實例(對象)時,此線程進入新建狀態(tài)(未被啟動)。例如:Thread t1=new Thread();
就緒(runnable)
線程已經(jīng)被啟動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候得到CPU資源。例如:t1.start();
運行(running)
線程獲得CPU資源正在執(zhí)行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優(yōu)先級更高的線程進入,線程將一直運行到結束。
死亡(dead)
當線程執(zhí)行完畢或被其它線程殺死,線程就進入死亡狀態(tài),這時線程不可能再進入就緒狀態(tài)等待執(zhí)行。
自然終止:正常運行run()方法后終止
異常終止:調用stop()方法讓一個線程終止運行
阻塞(blocked)
阻塞狀態(tài)是指線程因為某種原因放棄了 cpu 使用權,也即讓出了 cpu timeslice,暫時停止運行。直到線程進入可運行(runnable)狀態(tài),才有機會再次獲得 cpu timeslice 轉到運行(running)狀態(tài)。阻塞的情況分三種:
等待阻塞 ( o.wait-> 等待對列:運行(running)的線程執(zhí)行 o.wait()方法,JVM 會把該線程放入等待隊列(waitting queue)中。
同步阻塞 (lock-> 鎖池 ):運行(running)的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則 JVM 會把該線程放入鎖池(lock pool)中。
其他阻塞 (sleep/join):運行(running)的線程執(zhí)行 Thread.sleep(long ms)或 t.join()方法,或者發(fā)出了 I/O 請求時,JVM 會把該線程置為阻塞狀態(tài)。當 sleep()狀態(tài)超時、join()等待線程終止或者超時、或者 I/O處理完畢時,線程重新轉入可運行(runnable)狀態(tài)。
sleep()和wait()有什么區(qū)別嗎?
sleep()方法是線程類(Thread)的靜態(tài)方法,讓調用線程進入睡眠狀態(tài),讓出執(zhí)行機會給其他線程,等到休眠時間結束后,線程進入就緒狀態(tài)和其他線程一起競爭cpu的執(zhí)行時間
因為sleep() 是static靜態(tài)的方法,他不能改變對象的鎖,當一個synchronized塊中調用了sleep() 方法,線程雖然進入休眠,但是對象的機鎖沒有被釋放,其他線程依然無法訪問這個對象。
wait()是Object類的方法,當一個線程執(zhí)行到wait方法時,它就進入到一個和該對象相關的等待池,同時釋放對象的鎖,使得其他線程能夠訪問,可以通過notify,notifyAll方法來喚醒等待的線程。
簡述基于TCP和UDP的Socket編程主要步驟
Java分別為TCP和UDP 兩種通信協(xié)議提供了相應的Socket編程類,這些類存放在java.net包中。與TCP對應的是服務器的ServerSocket和客戶端的Socket,與UDP對應的是DatagramSocket。
基于TCP創(chuàng)建的套接字可以叫做流套接字,服務器端相當于一個監(jiān)聽器,用來監(jiān)聽端口。 服務器與客服端之間的通訊都是輸入輸出流來實現(xiàn)的。基于UDP的套接字就是數(shù)據(jù)報套接字,? 兩個都要先構造好相應的數(shù)據(jù)包。
基于TCP協(xié)議的Socket編程的主要步驟
服務器端(server)
構建一個ServerSocket實例,指定本地的端口。這個socket就是用來監(jiān)聽指定端口的連接請求的。
重復如下幾個步驟:
調用socket的accept()方法來獲得下面客戶端的連接請求。通過accept()方法返回的socket實例,建立了一個和客戶端的新連接
通過這個返回的socket實例獲取InputStream和OutputStream,可以通過這兩個stream來分別讀和寫數(shù)據(jù)
結束的時候調用socket實例的close()方法關閉socket連接
客戶端(client)
構建Socket實例,通過指定的遠程服務器地址和端口來建立連接
通過Socket實例包含的InputStream和OutputStream來進行數(shù)據(jù)的讀寫
操作結束后調用socket實例的close方法,關閉
基于UDP協(xié)議的Socket編程的主要步驟
服務器端(server)
構造DatagramSocket實例,指定本地端口。
通過DatagramSocket實例的receive方法接收DatagramPacket.DatagramPacket中間就包含了通信的內(nèi)容
通過DatagramSocket的send和receive方法來收和發(fā)DatagramPacket
客戶端(client)
構造DatagramSocket實例
通過DatagramSocket實例的send和receive方法發(fā)送DatagramPacket報文
結束后,調用DatagramSocket的close方法關閉
反射機制的優(yōu)缺點
靜態(tài)編譯:在編譯時確定類型,綁定對象,即通過。
動態(tài)編譯:運行時確定類型,綁定對象。動態(tài)編譯最大限度發(fā)揮了java的靈活性,體現(xiàn)了多態(tài)的應用,有以降低類之間的藕合性。
優(yōu)點:可以實現(xiàn)動態(tài)創(chuàng)建對象和編譯,體現(xiàn)出很大的靈活性,特別是在J2EE的開發(fā)中,它的靈活性就表現(xiàn)的十分明顯。
缺點:對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿足我們的要求。這類操作總是慢于只直接執(zhí)行相同的操作。
HashMap和Hashtable的區(qū)別和聯(lián)系
實現(xiàn)原理相同,功能相同,底層都是哈希表結構,查詢速度快,在很多情況下可以互用
兩者的主要區(qū)別如下
Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口
Hashtable繼承Dictionary類,HashMap實現(xiàn)Map接口
Hashtable線程安全,HashMap線程非安全
Hashtable不允許null值,HashMap允許null值
Hashtable、HashMap都使用了 Iterator。而由于歷史原因,Hashtable還使用了Enumeration的方式 。
初始容量大小和每次擴充容量大小的不同
Hashtable默認的初始大小為11,之后每次擴充,容量變?yōu)樵瓉淼?n+1。HashMap默認的初始化大小為16。之后每次擴充,容量變?yōu)樵瓉淼?倍。
哈希值的使用不同,HashTable直接使用對象的hashCode。而HashMap重新計算hash值。
hashCode是jdk根據(jù)對象的地址或者字符串或者數(shù)字算出來的int類型的數(shù)值。
Hashtable計算hash值,直接用key的hashCode(),而HashMap重新計算了key的hash值,Hashtable在求hash值對應的位置索引時,用取模運算,而HashMap在求位置索引時,則用與運算,且這里一般先用hash&0x7FFFFFFF后,再對length取模,&0x7FFFFFFF的目的是為了將負的hash值轉化為正值,因為hash值有可能為負數(shù),而&0x7FFFFFFF后,只有符號外改變,而后面的位都不變。
字符流字節(jié)流聯(lián)系區(qū)別;什么時候使用字節(jié)流和字符流?
字符流和字節(jié)流是流的一種劃分,按處理照流的數(shù)據(jù)單位進行的劃分。兩類都分為輸入和輸出操作。
在字節(jié)流中輸出數(shù)據(jù)主要是使用OutputStream完成,輸入使的是InputStream,在字符流中輸出主要是使用Writer類完成,輸入流主要使用Reader類完成。這四個都是抽象類。
字符流處理的單元為2個字節(jié)的Unicode字符,分別操作字符、字符數(shù)組或字符串,而字節(jié)流處理單元為1個字節(jié),操作字節(jié)和字節(jié)數(shù)組。字節(jié)流是最基本的,所有的InputStrem和OutputStream的子類都是,主要用在處理二進制數(shù)據(jù),它是按字節(jié)來處理的 但實際中很多的數(shù)據(jù)是文本,又提出了字符流的概念,它是按虛擬機的編碼來處理,也就是要進行字符集的轉化 這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯(lián),實際上是通過byte[]和String來關聯(lián)的。
青蛙跳臺階青蛙可以一次跳1級/2級臺階請問跳上第n級臺階有多少種方法?
遞歸:
if(target == 1){
? return 1;
? }
? if(target == 2){
? return 2;
? }
? //第一次有兩種選擇,然后根據(jù)不同的選擇,然后開始不同的下一步,但是下一步還是一樣有兩種選擇
? return JumpFloor(target - 1) + JumpFloor(target - 2);
復制代碼
非遞歸:
int x=1, y=2, z;
? if(target == 1){
? return 1;
? }
? if(target == 2){
? return 2;
? }
? for(int i = 3; i <= target; i ++){
? z = y;
? y = x + y;
? x = z;
? }
? return y;
復制代碼
總結
以上是生活随笔為你收集整理的map的生命周期 java,【JAVA面试的艺术】JAVA基础知识阶段三的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 德业股份是什么板块 所属家电行业
- 下一篇: c语言词法分析程序,词法分析器(c语言实