Java知識點總結

Java知識點1、==和equals的區別基本類型比較==比較內容 equals比較地址值引用類型比較==比較地址值 equals比較地址值在String類中equals比較內容2、形參和實參的區別形參 是在定義函數名和函數體的時候使用的參數,用來接受調用該函數時傳遞的參數實參 是在調用函數時傳遞的參數特點: 形參只有在被調用時才分配內存單元,再調用結束時立即釋放所分配的內存單元實參可以是常量 變量 函數等 必須有確定的值值傳遞:方法調用時,實參把他對應的值傳遞給對應的形參,方法中執行形參的改變而不影響實參引用傳遞: 傳的是地址值,方法調用時 實參的引用被傳遞給方法中對應的形參 在方法中執行對形參的操作就是對實參的操作3、final的特點Java關鍵字final有“這是無法改變的”或者“終態的”含義,它可以修飾非 抽象類、非抽象類成員方法和變量。final類不能被繼承,沒有子類,final類中的方法默認是final的。final方法不能被子類的方法覆蓋,但可以被繼承。final成員變量表示常量,只能被賦值一次,賦值后值不再改變。final不能用于修飾構造方法。4、final、finally、finallize的區別final 最終的不可改變的 修飾符finally 在try chech 中出現 代表一定執行代碼塊finallize Object的方法 System類的gc方法在清理內存是調用他用于回收垃圾5、android有哪些新集合,有什么特點Api=23 ArraySet 集合 實現Collection和set集合升序 不可重復SparseArrayApi=19ArrayMap 集合 實現Map集合 final不可被繼承鍵必須是引用類型底層是value數組 無序通過鍵的hashcode值找value- ArrayMap它不是一個適應大數據的數據結構,相比傳統的HashMap速度要慢,因為查找方法是二分法,并且當你刪除或者添加數據時,會對空間重新調整,在使用大量數據時,效率并不明顯,低于50%。所以ArrayMap是犧牲了時間換區空間。在寫手機app時,適時的使用ArrayMap,會給內存使用帶來可觀的提升。- ArraySet- SparseArray1,SparseArray的原理是二分檢索法,也因此key的類型都是整型。2,(HashMap和SparseArray比較)當存儲大量數據(起碼上千個)的時候,優先選擇HashMap。如果只有幾百個,用哪個區別不大。如果數量不多,優先選擇SparseArray。3,SparseArray有自己的垃圾回收機制。(當數量不是很多的時候,這個不必關心。)- SparseBooleanArray- SparseIntArraySparseBooleanArray和SparseIntArray,其實看名字也知道,它們跟SparseArray極其類似,只是存儲類型加以限制了。SparseBooleanArray只能存儲boolean值,而SparseIntArray只能存儲integer類型的值。它們也同樣實現了Cloneable接口,可以直接調用clone方法,也同樣是以二分法為依據。- SparseLongArray6、新IO是什么,有什么特點新IO和傳統IO都是用于進行輸入/輸出,相比于傳統IO面向流的處理方式,新IO采用內存映射文件來處理輸入/輸出,新IO將文件或文件的一段區域映射到內存中,這樣就可以像訪問內存一樣來訪問文件了,所以這種訪問方式既方便又快得多。新IO中的兩個核心對象:Channel(通道)和Buffer(緩沖)。Channel用于新IO的數據傳輸,相對于傳統IO中的InputStream和OutputStream,Channel提供了一個map()方法用來將一段數據映射成為一塊內存。也就是在新IO中,改變了傳統IO面向流的處理而轉向面向塊的處理方式。Buffer是一個容器,它的本質是一個數組。發送到Channel的所有對象以及從Channel取出的所有數據先存放到Buffer中。除了上面兩個核心對象外,新IO還提供了Charset類用于將Unicode字符串映射成字節序列以及逆映射操作。以及Selector類用于支持非阻塞式輸入輸出。java.nio.ByteBuffer字節的Bufferjava.nio.CharBuffer字符的Bufferjava.nio.ShortBuffer短整數的Bufferjava.nio.IntBuffer整數的Bufferjava.nio.LongBUffer長整數的Bufferjava.nio.FloatBuffer單精度的Bufferjava.nio.DoubleBuffer雙精度的Bufferallocate(int allocate)設置緩沖區大小put(int[] value)添加元素flip()重設緩沖區7、TreeSet是如何進行排序的?自然排序:要在自定義類中實現Comparerable接口 ,并且重寫compareTo方法比較器排序:在自定義類中實現Comparetor接口,重寫compare方法8、什么是線程線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。9、線程都有哪些狀態?新建->以創建 還未調用start方法就緒->調用start方法 還未搶占到cpu的執行權執行->搶占到cpu的執行權執行代碼阻塞->執行過程中得其他線程 搶占了cpu死亡->線程執行完畢10、什么是線程池? 線程池是指在初始化一個多線程應用程序過程中創建一個線程集合,然后在需要執行新的任務時重用這些線程而不是新建一個線程 。線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然后在創建線程后自動啟動這些任務。線程池線程都是后臺線程。每個線程都使用默認的堆棧大小,以默認的優先級運行,并處于多線程單元中。11、線程和進程的區別線程是指進程內的一個執行單元,也是進程內的可調度實體.與進程的區別:(1)地址空間:進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;(2)資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源(3)線程是處理器調度的基本單位,但進程不是. (4)二者均可并發執行.進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的并發性。進程和線程的區別在于:簡而言之,一個程序至少有一個進程,一個進程至少有一個線程. 線程的劃分尺度小于進程,使得多線程程序的并發性高。 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。 從邏輯角度來看,多線程的意義在于一個應用程序中,有多個執行部分可以同時執行。但操作系統并沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位. 線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源. 一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以并發執行.12、如何在Java中實現線程?1、繼承Thread類實現多線程繼承Thread類的方法盡管被我列為一種多線程實現方式,但Thread本質上也是實現了Runnable接口的一個實例,它代表一個線程的實例,并且,啟動線程的唯一方法就是通過Thread類的start()實例方法。start()方法是一個native方法,它將啟動一個新線程,并執行run()方法。這種方式實現多線程很簡單,通過自己的類直接extend Thread,并復寫run()方法,就可以啟動新線程并執行自己定義的run()方法。2、實現Runnable接口方式實現多線程如果自己的類已經extends另一個類,就無法直接extends Thread,此時,必須實現一個Runnable接口3、使用ExecutorService、Callable、Future實現有返回結果的多線程ExecutorService、Callable、Future這個對象實際上都是屬于Executor框架中的功能類。可返回值的任務必須實現Callable接口,類似的,無返回值的任務必須Runnable接口。執行Callable任務后,可以獲取一個Future的對象,在該對象上調用get就可以獲取到Callable任務返回的Object了,再結合線程池接口ExecutorService就可以實現傳說中有返回結果的多線程了。 13、Thread 類中的 start() 和 run() 方法有什么區別?調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。這兩個方法應該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由jvm的內存機制規定的。并且run()方法必須是public訪問權限,返回值類型為void.。14、線程池的最大線程數是多少?答: 不同的任務類別應采用不同規模的線程池,任務類別可劃分為CPU密集型任務|密集型任務和混合型任務。[N代表CPU個數]對于CPU密集型任務: 線程池中線程個數應盡量少,如配置M+1個線程的線程池;對于IO密集型任務: 由于IO操作速度遠低于CPU速度,那么在運行這類任務時,CPU絕大多數時間處于空閑狀態,那么線程池可以配置盡量多些的線程,以提高CPU利用率,如2*N;對于混合型任務: 可以拆分為CPU密集型任務和IO密集型任務,當這兩類任務執行時間相差無幾時,通過拆分再執行的吞吐率高于串行執行的吞吐率,但若這兩類任務執行時間有數據級的差距,那么沒有拆分的意義。15、HandlerThread是什么?HandlerThread = Handler + Thread + LooperHandlerThread是一個內部有Looper的Thread1)HandlerThread本質上是一個線程類,它繼承了Thread。2)HandlerThread有自己的內部Looper對象,可以進行looper循環。3)通過獲取HandlerThread的Looper對象傳遞給Handler對象,可以在handleMessae方法中執行異步任務。4)優點是不會有堵塞,減少了對性能的消耗。5)缺點是不能同時進行多任務處理,需要進行等待,處理效率較低。6)與線程池側重并發不同,HandlerThread是一個串行隊列,HandlerThread背后只有一個線程。16、HandlerThread 的原理HandlerThread繼承自Thread,因此在run()中的邏輯都是在子線程中運行的。接下來就是兩個關鍵的方法,run()和getLooper(): run()中可以看到是很簡單的創建Looper以及讓Looper工作的邏輯。 run()里面當mLooper創建完成后有個notifyAll(),getLooper()中有個wait(),這有什么用呢?因為的mLooper在一個線程中執行創建,而我們的handler是在UI線程中調用getLooper()初始化的。 也就是說,我們必須等到mLooper創建完成,才能正確的返回。getLooper();wait(),notify()就是為了解決這兩個線程的同步問題。17、用 Runnable 還是 Thread ?實現Runnable接口比繼承Thread類所具有的優勢:1):適合多個相同的程序代碼的線程去處理同一個資源2):可以避免java中的單繼承的限制3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立18、Runnable 和 Callable 有什么不同?在Java5之后,任務分兩類:一類是實現了Runnable接口的類,一類是實現了Callable接口的類。兩者都可以被 ExecutorService執行,但是Runnable任務沒有返回值,而Callable任務有返回值。并且Callable的call()方法只能通過ExecutorService的(task) 方法來執行,并且返回一個,是表示任務等待完成的 Future。public interface Callable返回結果并且可能拋出異常的任務。實現者定義了一個不帶任何參數的叫做 call 的方法。Callable 接口類似于,兩者都是為那些其實例可能被另一個線程執行的類設計的。但是 Runnable 不會返回結果,并且無法拋出經過檢查的異常。類包含一些從其他普通形式轉換成 Callable 類的實用方法。Callable中的call()方法類似Runnable的run()方法,就是前者有返回值,后者沒有。當將一個Callable的對象傳遞給ExecutorService的submit方法,則該call方法自動在一個線程上執行,并且會返回執行結果Future對象。同樣,將Runnable的對象傳遞給ExecutorService的submit方法,則該run方法自動在一個線程上執行,并且會返回執行結果Future對象,但是在該Future對象上調用get方法,將返回null。19、使用多線程的優缺點優點(1)多線程技術使程序的響應速度更快 ,因為用戶界面可以在進行其它工作的同時一直處于活動狀態;(2)當前沒有進行處理的任務時可以將處理器時間讓給其它任務;(3)占用大量處理時間的任務可以定期將處理器時間讓給其它任務;(4)可以隨時停止任務;(5)可以分別設置各個任務的優先級以優化性能。缺點(1)等候使用共享資源時造成程序的運行速度變慢。(2)對線程進行管理要求額外的 CPU開銷。(3)線程的死鎖。(4)對公有變量的同時讀或寫。20、wait()、notify()、notifyAll()的區別Object類里的方法,可以用來控制線程的狀態。這三個方法最終調用的都是jvm級的native方法。隨著jvm運行平臺的不同可能有些許差異。 如果對象調用了wait方法就會使持有該對象的線程把該對象的控制權交出去,然后處于等待狀態。 如果對象調用了notify方法就會通知某個正在等待這個對象的控制權的線程可以繼續運行。 如果對象調用了notifyAll方法就會通知所有等待這個對象控制權的線程繼續運行。21、wait() 與 Thread.sleep(long time) 的區別wait()方法睡眠沒有其他線程喚醒他就不會重新啟動釋放同步鎖不需要捕捉異常Thread.sleep(long time) 方法睡眠 會指定睡眠時間 自動喚醒不釋放同步鎖需要捕捉異常22、volatile關鍵字的作用操作數據對其他線程可見禁止重排序保證有序性23、join方法的作用當前線程調用其他線程的join(加入執行)當前線程會等待加入的線程執行完畢繼續執行24、yield方法的作用Thread.yield()方法作用是:暫停當前正在執行的線程對象,并執行其他線程。yield()應該做的是讓當前運行線程回到可運行狀態,以允許具有相同優先級的其他線程獲得運行機會。因此,使用yield()的目的是讓相同優先級的線程之間能適當的輪轉執行。但是,實際中無法保證yield()達到讓步目的,因為讓步的線程還有可能被線程調度程序再次選中。25、線程池的優點1.減少在創建和銷毀線程上所花的時間以及系統資源的開銷 2.如不使用線程池,有可能造成系統創建大量線程而導致消耗完系統內存以及”過度切換”。26、有幾種線程池,分別是什么?Java通過Executors提供四種線程池,分別為:newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。newFixedThreadPool 創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。27、如何關閉線程池?方法定義:public void shutdown()(1)線程池的狀態變成SHUTDOWN狀態,此時不能再往線程池中添加新的任務,否則會拋出RejectedExecutionException異常。(2)線程池不會立刻退出,直到添加到線程池中的任務都已經處理完成,才會退出。 注意這個函數不會等待提交的任務執行完成,要想等待全部任務完成,可以調用:public boolean awaitTermination(longtimeout, TimeUnit unit)方法定義:public ListshutdownNow()

(1)線程池的狀態立刻變成STOP狀態,此時不能再往線程池中添加新的任務。

(2)終止等待執行的線程,并返回它們的列表;

(3)試圖停止所有正在執行的線程,試圖終止的方法是調用Thread.interrupt(),但是大家知道,如果線程中沒有sleep 、wait、Condition、定時鎖等應用, interrupt()方法是無法中斷當前的線程的。所以,ShutdownNow()并不代表線程池就一定立即就能退出,它可能必須要等待所有正在執行的任務都執行完成了才能退出。

28、如何關閉線程?

29、1、 使用退出標志,使線程正常退出,也就是當run方法完成后線程終止。

30、2、 使用stop方法強行終止線程(這個方法不推薦使用,因為stop和suspend、resume一樣,也可能發生不可預料的結果)。

31、3、 使用interrupt方法中斷線程。

32、4、 拋出異常

33、什么是 Executor 框架?

Eexecutor作為靈活且強大的異步執行框架,其支持多種不同類型的任務執行策略,提供了一種標準的方法將任務的提交過程和執行過程解耦開發,基于生產者-消費者模式,其提交任務的線程相當于生產者,執行任務的線程相當于消費者,并用Runnable來表示任務,Executor的實現還提供了對生命周期的支持,以及統計信息收集,應用程序管理機制和性能監視等機制。

30、Executors 類是什么?

Executors為Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable類提供了一些工具方法。

Executors可以用于方便的創建線程池。

31、Handler原理|如何進行線程間通信?

當創建Handler時將通過ThreadLocal在當前線程綁定一個Looper對象,而Looper持有MessageQueue對象。執行Handler.sendMessage(Message)方法將一個待處理的Message插入到MessageQueue中,這時候通過Looper.loop()方法獲取到隊列中Message,然后再交由Handler.handleMessage(Message)來處理。

32、String、StringBuffer、StringBuilder的區別

1.可變與不可變

String類中使用字符數組保存字符串,如下就是,因為有“final”修飾符,所以可以知道string對象是不可變的。

StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數組保存字

符串,如下就是,可知這兩種對象都是可變的。

2.是否多線程安全

String中的對象是不可變的,也就可以理解為常量,顯然線程安全。

StringBuffer對方法加了同步鎖或者對調用的方法加了同步鎖,所以是線程安全的

StringBuilder并沒有對方法進行加同步鎖,所以是非線程安全的。

33、冒泡排序、選擇排序、二叉樹排序

冒泡排序:

相鄰的兩個數比較,將小數放在前面,大數放在后面

選擇排序:

每一從待排序的數據元素中選出最小的一個元素,存放在序列的起始位置,依次比較,直到全部待排序的數據元素排完。

二叉樹排序:

左子樹不為空,則左子樹上所有節點的值均小于它的根節點的值。

右子樹不為空,則右子樹上所有節點的值均大于它的根節點的值。

34、異常的繼承體系

35、介紹封裝、繼承、多態

封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏

面向對象編程 (OOP) 語言的一個主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。 繼承現有類 + 擴展

多態性(polymorphisn)是允許你將父對象設置成為和一個或更多的他的子對象相等的技術,賦值之后,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。

36、類與接口的區別

抽象類是用來捕捉子類的通用特性的 。它不能被實例化,只能被用作子類的超類。抽象類是被用來創建繼承層級里子類的模板。

接口是抽象方法的集合。如果一個類實現了某個接口,那么它就繼承了這個接口的抽象方法。這就像契約模式,如果實現了這個接口,那么就必須確保使用這些方法。接口只是一種形式,接口自身不能做任何事情。

37、接口能否寫方法體?

可以,java8的接口新特性中可以寫默認方法

38、集合子類的特點

Collection

|-->List:有序,可重復,有索引

|-->ArrayList:底層是數組數據結構(具有連續性,查詢元素速度快但是增刪元素速度低),是線程不同步的

|-->LinkList:底層是鏈表數據結構(查詢的速度稍慢,但是增刪的速度快),是線程不同步的

|-->Vector:底層是數組數據結構,是線程同步的,但是已經被ArrayList替代。因為增刪和查詢的速度都非常慢,效率很低。

|-->Set:無序,不可以重復元素。Set接口的方法和Collection中的方法一致。Set接口中的方法只有迭代器。

|-->HashSet:底層數據結構式哈希表,哈希表這種結構,其實就是對哈希值的存儲。而且每個對象都有自己的哈希值,因為Object類中有一個方法為hashCode方法。

如何保證元素的唯一性呢?

通過判斷元素的hashCode方法,會判斷一次equals方法的返回值是否為true。

如果hashCode值不相同,就確定元素的哈希表中的位置,就不用在判斷equals了。

在哈希表中有一個桶結構,每一個桶都有一個哈希值,當哈希值相同,但是equals返回為false時,這些元素都存放在一個桶內。

|-->TreeSet:可以對Set集合中的元素進行排序。

看到array就要想到數組,就要想到角標,就要想到查詢很快。

看到link就要想到鏈表,就要想到增刪很快,最好再想到addFirst(offerFirst)

看到hash就要想到hash表,就要想到元素的hashCode方法,和equals方法。

看到tree,就要想到二叉樹,就要想到排序,就要想到兩個接口 Comparable(Object obj)和Comparator(Objcet o1,Object o2)

Map集合中常見的三個子接口:

Map

|--Hashtable :底層數據結構是是哈希表結構,該集合是線程同步的,效率低

此類實現一個哈希表,該哈希表將鍵映射到相應的值。任何非 null 對象都可以 用作鍵或值用作鍵的對象必須實現hashCode 方法和 equals 方法

|--HashMap: 底層也是哈希表數據結構,并允許使用 null 值和 null 鍵,此集合線程是不同步? 效率高

|--TreeMap:? 底層是二叉樹數據結構,線程不同步,可以用于給Map集合中的鍵進行排序

不難發現,Set集合的特點和Map集合的特點非常相似,其實,Set底層就是使用了Map集合,它的很多方法都是調用Map集合的。

39、List集合有幾種排序方式,Set集合有幾種排序方式,Map集合有幾種排序方式?

40、HashMap如何保證key的唯一性?

添加的元素都有一個 hashCode(哈希值),他們先比較哈希值,是否相同? 不相同的元素,添加進入 HashTable. 如果hashCode相同的話, 再去比較 equals()方法,如果也相同的話,JVM就認為數據已經存在了,就不會添加數據!

41、介紹OSI參考模型和TCP/IP參考模型

OSI模型

TCP/ip模型

OSI 7層

應用層->包含大量人們普遍需要的協議

表示層->用于完成某些特定功能

會話層->允許不同機器上的用戶之間建立會話關系

傳輸層->實現網絡中不同主機上的用戶進程之間可靠的數據通信

網絡層->完成網絡中主機間的報文傳輸

數據鏈路層->如何在不可靠的物理線路上進行數據的可靠傳輸

物理層->完成相鄰結點之間原始比特流的傳輸

TCP/IP 4層

應用層->處理高層協議

傳輸層->在源結點和目的結點的兩個進程實體之間提供可靠的,端到端的數據傳輸

互連網層->處理上層發送請求,處理輸入數據報,處理ICMP報文

網絡接口層->涉及分組與網絡接口

42、如何解決并發線程的數據安全?

談到多線程,就涉及到共享數據安全問題,一般來說,解決共享數據安全問題有三種方式

①:在共享數據前加volatile修飾,且保證對共享數據的操作要是原子性的

②:java.util.concurrent.atomic下的AtomicInteger等類來包裝共享數據

③:鎖如靜態鎖synchronize、重入鎖ReentrantLock等

43、序列化機制和原理

對象序列化,將對象以二進制的形式保存在硬盤上

反序列化;將二進制的文件轉化為對象讀取

44、java如何進行序列化和反序列化?

? 序列化實現步驟:

(1)需要序列化的對象所屬類必須實現Serializable接口;

(2)構造FileOutputStream對象;

(3)構造ObjectOutputStream對象;

(4)使用ObjectOutputStream對象的writeObject()方法進行序列化;

(5)關閉ObjectOutputStream對象;

(6)關閉FileOutputStream對象;

(7)對序列化全程捕獲IOException;

? 反序列化實現步驟:

(1)需要序列化的對象所屬類必須實現Serializable接口;

(2)構造FileInputStream對象;

(3)構造ObjectInputStream對象;

(4)使用ObjectInputStream對象的readObject()方法進行序列化;

(5)關閉ObjectInputStream對象;

(6)關閉FileInputStream對象;

(7)對序列化全程捕獲ClassNotFoundException和IOException;

45、Http和Https的區別

1、https協議需要到ca申請證書,一般免費證書比較少,因而需要一定的費用

2、http是超文本傳輸協議,信息是文明傳輸,https則是具有安全性的ssl加密傳輸協議

3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80 后者是

440

4、https的連接很簡單,是無狀態的,https協議是由SSL+HTTP協議構建安的可進行

加密傳輸,身份認證的網絡協議,比http安全

46、TCP和UDP的區別

連接方面:UDP不需要與服務器建立連接,TCP需要與服務器建立連接,通過三次握手完成數據傳遞。

數據限制方面:UDP每個數據限制在64k,TCP沒有限制。

速度與安全方面:UDP速度快,但是不安全,TCP速度稍慢,是可靠協議,安全。

47、如何獲取IP地址信息?

一般獲取客戶端的IP地址的方法是:request.getRemoteAddr();但是在通過了Apache,Squid等反向代理軟件就不能獲取到客戶端的真實IP地址了。 可是,如果通過了多級反向代理的話,X-Forwarded-For的值并不止一個,而是一串IP值 多次反向代理后會有多個ip值,第一個ip才是真實ip

48、Socket如何保持長連接

方法1:應用層自己實現的心跳包

由應用程序自己發送心跳包來檢測連接是否正常,大致的方法是:服務器在一個 Timer事件中定時 向客戶端發送一個短小精悍的數據包,然后啟動一個低級別的線程,在該線程中不斷檢測客戶端的回應, 如果在一定時間內沒有收到客戶端的回應,即認為客戶端已經掉線;同樣,如果客戶端在一定時間內沒 有收到服務器的心跳包,則認為連接不可用。

方法2:TCP的KeepAlive保活機制

因為要考慮到一個服務器通常會連接多個客戶端,因此由用戶在應用層自己實現心跳包,代碼較多 且稍顯復雜,而利用TCP/IP協議層為內置的KeepAlive功能來實現心跳功能則簡單得多。 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規定時間內向對方發送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線。但是

開啟KeepAlive功能需要消耗額外的寬帶和流量,所以TCP協議層默認并不開啟KeepAlive功 能

KeepAlive設置不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接

49、Socket、TCP/IP、HTTP的區別

1、TCP/IP連接

TCP/IP是個協議組,可分為三個層次:網絡層、傳輸層和應用層。

在網絡層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議。

在傳輸層中有TCP協議與UDP協議。

在應用層有FTP、HTTP、TELNET、SMTP、DNS等協議。

因此,HTTP本身就是一個協議,是從Web服務器傳輸超文本到本地瀏覽器的傳送協議。

手機能夠使用聯網功能是因為手機底層實現了TCP/IP協議,可以使手機終端通過無線網絡建立TCP連接。TCP協議可以對上層網絡提供接口,使上層網絡數據的傳輸建立在“無差別”的網絡之上。

建立起一個TCP連接需要經過“三次握手”:

第一次握手:客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認;

第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。

握手過程中傳送的包里不包含數據,三次握手完畢后,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。斷開連接時服務器和客戶端均可以主動發起斷開TCP連接的請求,斷開過程需要經過“四次握手”(過程就不細寫了,就是服務器和客戶端交互,最終確定斷開).

2、HTTP連接

HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種應用。

HTTP連接最顯著的特點是客戶端發送的每次請求都需要服務器回送響應,在請求結束后,會主動釋放連接。從建立連接到關閉連接的過程稱為“一次連接”。

1)在HTTP 1.0中,客戶端的每次請求都要求建立一次單獨的連接,在處理完本次請求后,就自動釋放連接。

2)在HTTP 1.1中則可以在一次連接中處理多個請求,并且多個請求可以重疊進行,不需要等待一個請求結束后再發送下一個請求。

由于HTTP在每次請求結束后都會主動釋放連接,因此HTTP連接是一種“短連接”,要保持客戶端程序的在線狀態,需要不斷地向服務器發起連接請求。通常的做法是即時不需要獲得任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次“保持連接”的請求,服務器在收到該請求后對客戶端進行回復,表明知道客戶端“在線”。若服務器長時間無法收到客戶端的請求,則認為客戶端“下線”,若客戶端長時間無法收到服務器的回復,則認為網絡已經斷開。

3、SOCKET原理

3.1套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP協議的網絡通信的基本操作單元。它是網絡通信過程中端點的抽象表示,包含進行網絡通信必須的五種信息:連接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。

應用層通過傳輸層進行數據通信時,TCP會遇到同時為多個應用程序進程提供并發服務的問題。多個TCP連接或多個應用程序進程可能需要通過同一個 TCP協議端口傳輸數據。為了區別不同的應用程序進程和連接,許多計算機操作系統為應用程序與TCP/IP協議交互提供了套接字(Socket)接口。應用層可以和傳輸層通過Socket接口,區分來自不同應用程序進程或網絡連接的通信,實現數據傳輸的并發服務。

3.2 建立socket連接

建立Socket連接至少需要一對套接字,其中一個運行于客戶端,稱為ClientSocket ,另一個運行于服務器端,稱為ServerSocket 。

套接字之間的連接過程分為三個步驟:服務器監聽,客戶端請求,連接確認。

服務器監聽:服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。

客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求。

連接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務器端套接字繼續處于監聽狀態,繼續接收其他客戶端套接字的連接請求。

4、SOCKET連接與TCP/IP連接

創建Socket連接時,可以指定使用的傳輸層協議,Socket可以支持不同的傳輸層協議(TCP或UDP),當使用TCP協議進行連接時,該Socket連接就是一個TCP連接。

5、Socket連接與HTTP連接

由于通常情況下Socket連接就是TCP連接,因此Socket連接一旦建立,通信雙方即可開始相互發送數據內容,直到雙方連接斷開。但在實際網絡應用中,客戶端到服務器之間的通信往往需要穿越多個中間節點,例如路由器、網關、防火墻等,大部分防火墻默認會關閉長時間處于非活躍狀態的連接而導致 Socket 連接斷連,因此需要通過輪詢告訴網絡,該連接處于活躍狀態。

而HTTP連接使用的是“請求—響應”的方式,不僅在請求時需要先建立連接,而且需要客戶端向服務器發出請求后,服務器端才能回復數據。

很多情況下,需要服務器端主動向客戶端推送數據,保持客戶端與服務器數據的實時與同步。此時若雙方建立的是Socket連接,服務器就可以直接將數據傳送給客戶端;若雙方建立的是HTTP連接,則服務器需要等到客戶端發送一次請求后才能將數據傳回給客戶端,因此,客戶端定時向服務器端發送連接請求,不僅可以保持在線,同時也是在“詢問”服務器是否有新的數據,如果有就將數據傳給客戶端。

http協議是應用層的協義

一個是發動機(Socket),提供了網絡通信的能力

一個是轎車(Http),提供了具體的方式

兩個計算機之間的交流無非是兩個端口之間的數據通信,具體的數據會以什么樣的形式展現`是以不同的應用層協議來定義的`如HTTP`FTP`...

socket是對端口通信開發的工具,它要更底層一些 .

50、Socket如何實現流量控制和擁塞控制的實現機制

1. 利用滑動窗口實現流量控制

如果發送方把數據發送得過快,接收方可能會來不及接收,這就會造成數據的丟失。所謂流量控制就是讓發送方的發送速率不要太快,要讓接收方來得及接收

利用滑動窗口機制可以很方便地在TCP連接上實現對發送方的流量控制。

設A向B發送數據。在連接建立時,B告訴了A:“我的接收窗口是 rwnd = 400 ”(這里的 rwnd 表示 receiver window) 。因此,發送方的發送窗口不能超過接收方給 出的接收窗口的數值。

TCP的擁塞控制

擁塞控制:防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或鏈路不致過載。擁塞控制所要做的都有一個前提:網絡能夠承受現有的網絡負荷。

幾種擁塞控制方法

慢開始( slow-start )、擁塞避免( congestion avoidance )、快重傳( fast retransmit )和快恢復( fast recovery )。

51、多線程如何同步

1.同步方法

即有synchronized關鍵字修飾的方法。

由于java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時,

內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處于阻

塞狀態。

2.同步代碼塊

即有synchronized關鍵字修飾的語句塊。

被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步

3.使用特殊域變量(volatile)實現線程同步

a.volatile關鍵字為域變量的訪問提供了一種免鎖機制,

b.使用volatile修飾域相當于告訴虛擬機該域可能會被其他線程更新,

c.因此每次使用該域就要重新計算,而不是使用寄存器中的值

d.volatile不會提供任何原子操作,它也不能用來修飾final類型的變量

4.使用重入鎖實現線程同步

在JavaSE5.0中新增了一個java.util.concurrent包來支持同步。

ReentrantLock類是可重入、互斥、實現了Lock接口的鎖,

它與使用synchronized方法和快具有相同的基本行為和語義,并且擴展了其

能力

ReenreantLock類的常用方法有:

ReentrantLock() : 創建一個ReentrantLock實例

lock() : 獲得鎖

unlock() : 釋放鎖

5. 使用局部變量實現線程同步

ThreadLocal與同步機制

ThreadLocal與同步機制都是為了解決多線程中相同變量的訪問沖突問題

前者采用以”空間換時間”的方法,后者采用以”時間換空間”的方式

52、tcp連接建立的時候3次握手的具體過程

第一次握手:

建立連接時,客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認;

SYN:同步序列編號(Synchronize Sequence Numbers)

第二次握手:

服務器收到syn包,必須確認客戶的SYN(ack=j+1),

同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

第三次握手:

客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),

此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手.

完成三次握手,客戶端與服務器開始傳送數據

53、tcp斷開連接的具體過程

(客戶機發起斷開請求)

四次斷開是由于tcp的半關閉造成的,即一方已經斷開連接二另一方沒有斷開

1.客戶機發送一個帶有fin的包給服務器,然后進入fin_wait_1狀態.而此時服務器處于close_wait狀態

2.服務器收到后,回應一個ack到客戶機.此時客戶機進入fin_wait_2狀態

3.服務器繼續回應一個Fin的包,服務器進入last_ack狀態,而客戶機進入time_wait狀態

4.客戶機發送ack給服務器,客戶機進入cloesed狀態.

最終雙方連接終止.

54、socket關閉釋放網絡資源的時候,數據還未傳輸完畢,如何解決?

解決方案一:

傳一個文件,建立一個連接,傳完文件后,立即關閉連接。

解決方案二:

在傳一個文件之前,先傳一個文件長度過去,再傳文件的數據,傳完了關閉連接。

接收端,先接收文件長度,然后,按照文件長度來讀取數據,

當,文件長度讀取完畢后,等待下次傳遞

55、什么是請求隊列?

消息隊列跟隊列本質上是一個東西,因為功能不一樣所以名字有區別,首先隊列是一

種數據結構,特點就是先進先出,后今 后出,這跟堆棧剛好相反。最簡單的消息隊

列其實也是用隊列這種數據結構實現的。我們把消息按照先進先出的規則一個一個

的放進隊列里,這個過程叫做進隊,然后在隊頭一個一個取出來叫做出隊。

56、常用的HTTP方法有哪些?

57、HTTP請求報文與響應報文格式

HTTP請求報文與響應報文格式

請求報文包含三部分:

a、請求行:包含請求方法、URI、HTTP版本信息

b、請求首部字段

c、請求內容實體

響應報文包含三部分:

a、狀態行:包含HTTP版本、狀態碼、狀態碼的原因短語

b、響應首部字段

c、響應內容實體

58、常見的HTTP相應狀態碼

200:請求被正常處理

204:請求被受理但沒有資源可以返回

206:客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法,

相應報文中通過Content-Range指定范圍的資源。

301:永久性重定向

302:臨時重定向

303:與302狀態碼有相似功能,只是它希望客戶端在請求一個URI的時候,能通

過GET方法重定向到另一個URI上

304:發送附帶條件的請求時,條件不滿足時返回,與重定向無關

307:臨時重定向,與302類似,只是強制要求使用POST方法

400:請求報文語法有誤,服務器無法識別

401:請求需要認證

403:請求的對應資源禁止被訪問

404:服務器無法找到對應資源

500:服務器內部錯誤

503:服務器正忙

59、HTTP1.1版本新特性

默認持久連接,

節省通信量,只要客戶端和服務端任意一端沒有明確的斷開TCP連接,就可以發送多次HTTP請求

管線化

客戶端可以同時發送多個HTTP請求,而不用一個個等待響應

斷點續傳原理

其原理是:客戶端記錄下當前的下載進度,并在需要續傳時通知服務器本次需要下載的內容片斷

60、常見HTTP首部字段

a、通用首部字段(請求報文與響應報文都會使用的首部字段)

Date:創建報文時間

Connection:連接的管理

Cache-Control:緩存的控制

Transfer-Encoding:報文主體的傳輸編碼方式

b、請求首部字段(請求報文會使用的首部字段)

Host:請求資源所在服務器

Accept:可處理的媒體類型

Accept-Charset:可接收的字符集

Accept-Encoding:可接受的內容編碼

Accept-Language:可接受的自然語言

c、響應首部字段(響應報文會使用的首部字段)

Accept-Ranges:可接受的字節范圍

Location:令客戶端重新定向到的URI

Server:HTTP服務器的安裝信息

d、實體首部字段(請求報文與響應報文的的實體部分使用的首部字段)

Allow:資源可支持的HTTP方法

Content-Type:實體主類的類型

Content-Encoding:實體主體適用的編碼方式

Content-Language:實體主體的自然語言

Content-Length:實體主體的的字節數

Content-Range:實體主體的位置范圍,一般用于發出部分請求時使用

61、Http與Https優缺點?

https:// 要比http://更加安全一些,也就是說HTTPS協議是由SSL+HTTP協議構

建的可進行加密傳輸、身份認證的網絡協議要比http協議安全。

1、https協議需要到ca申請證書,一般免費證書比較少,因而需要一定的費用

2、http是超文本傳輸協議,信息是文明傳輸,https則是具有安全性的ssl加密傳

輸協議

3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80

后者是440

4、https的連接很簡單,是無狀態的,https協議是由SSL+HTTP協議構建安的

可進行加密傳輸,身份認證的網絡協議,比http安全

62、什么是Http協議?

超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標準。

63、說一下Http協議中302狀態

302重定向很容易被搜索引擎誤認為是利用多個域名指向同一網站,那么你的網站就會被封掉,罪名是“利用重復的內容來干擾Google搜索結果的網站排名”。因為302重定向經常被用于做url劫持,黑帽seo技術中,而且百度在處理302重定向技術還不成熟,經常將它納入到黑帽seo的范疇中,而google對這方面識別處理就完善了許多。所以302重定向在現階段的搜索引擎技術中,還是容易導致網站降權的,盡量不用。但從seo、網站優化方面來說是弊大于利

64、Http協議有什么組成?

HTTP協議采用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含請求的方法、URL、協議版本、以及包含請求修飾符、客戶信息和內容的類似于MIME的消息結構。服務器以一個狀態行作為響應,響應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以及可能的實體內容。

65、Http協議中Http1.0與1.1區別?

1,HTTP/1.0協議使用非持久連接,即在非持久連接下,一個tcp連接只傳輸一個Web對象,;

2,HTTP/1.1默認使用持久連接(然而,HTTP/1.1協議的客戶機和服務器可以配置成使用非持久連接)。

在持久連接下,不必為每個Web對象的傳送建立一個新的連接,一個連接中可以傳輸多個對象!

66、Http優化

利用負載均衡優化和加速HTTP應用

利用HTTP Cache來優化網站

67、Http協議有那些特征?

無連接:HTTP本身是無連接的,即交換HTTP報文前不需要建立HTTP連接

無狀態:HTTP協議是無狀態的:數據傳輸過程中,并不保存任何歷史信息和狀態信息。無狀態特性簡化了服務器的設計,使服務器更容易支持大量并發的HTPP請求。

傳輸可靠性高:采用TCP作為運輸層協議(面向連接、可靠傳輸),即交換報文時需要預先建立TCP連接

兼容性好:支持B/S模式及C/S模式;

簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST

靈活:HTTP 允許傳輸任意類型的數據對象

68、什么是比特(Bit),什么是字節(Byte),什么是字符(Char),它們長度是多少,各有什么區別

Bit最小的二進制單位 ,是計算機的操作部分 取值0或者1

Byte是計算機操作數據的最小單位由8位bit組成 取值(-128-127)

Char是用戶的可讀寫的最小單位,在java里面由16位bit組成 取值(0-65535)

Bit 是最小單位 計算機 只能認識 0或者1

8個字節 是給計算機看的

字符 是看到的東西 一個字符=二個字節

69、什么是流,按照傳輸的單位,分成哪兩種流,并且他們的父類叫什么

流是指數據的傳輸

字節流,字符流

字節流:InputStream OutputStream

字符流:Reader Writer

3.流按照傳輸的方向可以分為哪兩種,分別舉例說明

答案

輸入輸出相對于程序

輸入流InputStream

,輸出流OutputStream

70、BufferedReader屬于哪種流,它主要是用來做什么的,它里面有那些經典的方法

屬于處理流中的緩沖流,可以將讀取的內容存在內存里面,有readLine()方法

71、什么是節點流,什么是處理流,它們各有什么用處,處理流的創建有什么特征

節點流 直接與數據源相連,用于輸入或者輸出

處理流:在節點流的基礎上對之進行加工,進行一些功能的擴展

處理流的構造器必須要 傳入節點流的子類

72、如果我要打印出不同類型的數據到數據源,那么最適合的流是那個流,為什么

Printwriter 可以打印各種數據類型

73、怎么樣把我們控制臺的輸出改成輸出到一個文件里面,這個技術叫什么

SetOut(printWriter,printStream)重定向

74、怎么樣把輸出字節流轉換成輸出字符流,說出它的步驟

使用 轉換處理流OutputStreamWriter 可以將字節流轉為字符流

New OutputStreamWriter(new FileOutputStream(File file));

75、把包括基本類型在內的數據和字符串按順序輸出到數據源,或者按照順序從數據源讀入,一般用哪兩個流

DataInputStream DataOutputStream

76、把一個對象寫入數據源或者從一個數據源讀出來,用哪兩個流

ObjectInputStream ObjectOutputStream

77、如果在對象序列化的時候不想給一個字段的數據保存在硬盤上面,采用那個關鍵字?

transient(短暫)關鍵字

78、在實現序列化接口是時候一般要生成一個serialVersionUID字段,它叫做版本標識,一般有什么用

簡單來說,Java的序列化機制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。

79、InputStream里的read()返回的是什么,read(byte[] data)是什么意思,返回的是什么值

返回的是所讀取的字節的int型(范圍0-255)

read(byte [ ] data)將讀取的字節儲存在這個數組

返回的就是傳入數組參數個數

Read 字節讀取字節 字符讀取字符

80、OutputStream里面的write()是什么意思,write(byte b[], int off, int len)這個方法里面的三個參數分別是什么意思

write將指定字節傳入數據源

Byte b[ ]是byte數組

b[off]是傳入的第一個字符

b[off+len-1]是傳入的最后的一個字符

len是實際長度

81、流一般需要不需要關閉,如果關閉的話在用什么方法,一般要在那個代碼塊里面關閉比較好,處理流是怎么關閉的,如果有多個流互相調用傳入是怎么關閉的?

流一旦打開就必須關閉,使用close方法

放入finally語句塊中(finally 語句一定會執行)

調用的是處理流就關閉處理流

多個流互相調用只關閉最外層的流

82、說說你對io流的理解

Io流主要是用來處理輸入輸出問題,常用的io流有InputStream,

OutputStream,Reader,Writer等

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容