一、TCP與UDP區別總結:
1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連接
2、TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保證可靠交付
3、TCP面向字節流,實際上是TCP把數據看成一連串無結構的字節流;UDP是面向報文的
4、每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信
5、TCP首部開銷20字節;UDP的首部開銷小,只有8個字節
6、TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道
7、UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)
二、udp如何實現可靠性傳輸?
傳輸層無法保證數據的可靠傳輸,只能通過應用層來實現了。實現的方式可以參照tcp可靠性傳輸的方式,只是實現不在傳輸層,實現轉移到了應用層。
實現確認機制、重傳機制。
實現流量控制:滑動窗口。
實現擁塞控制:慢開始和擁塞避免,快重傳和快恢復。
目前有如下開源程序利用udp實現了可靠的數據傳輸。分別為RUDP、RTP、UDT。
三、工作內存和主內存。(JMM)
Java 內存模型來屏蔽掉各種硬件和操作系統的內存差異,達到跨平台的內存訪問效果。JLS(Java語言規范)定義了一個統一的內存管理模型JMM(Java Memory Model)
Java內存模型規定了所有的變量都存儲在主內存中,此處的主內存僅僅是虛擬機內存的一部分,而虛擬機內存也僅僅是計算機物理內存的一部分(為虛擬機進程分配的那一部分)。
Java內存模型分為主內存,和工作內存。主內存是所有的線程所共享的,工作內存是每個線程自己有一個,不是共享的。
每條線程還有自己的工作內存,線程的工作內存中保存了被該線程使用到的變量的主內存副本拷貝。線程對變量的所有操作(讀取、賦值),都必須在工作內存中進行,而不能直接讀寫主內存中的變量。不同線程之間也無法直接訪問對方工作內存中的變量,線程間變量值的傳遞均需要通過主內存來完成,線程、主內存、工作內存三者之間的交互關系如下圖:
四、GC
五、volatile,volatile和synchronized的區別。
1.保證可見性
2.防止重排序
區別:
1.volatile不進行加鎖操作,是比synchronized更輕量級的同步機制,也不會造成線程阻塞
2.volatile不如synchronized安全,不能保證原子性。
3.volatile只能作用於變量,使用范圍較小。synchronized可以作用於變量、方法、類、同步代碼塊等。
六、調試器斷點機制的實現
要在被調試進程中的某個目標地址上設定一個斷點,調試器需要做下面兩件事情:
1. 保存目標地址上的數據
2. 將目標地址上的第一個字節替換為int 3指令
然后,當調試器向操作系統請求開始運行進程時(通過前一篇文章中提到的PTRACE_CONT),進程最終一定會碰到int 3指令。此時進程停止,操作系統將發送一個信號。這時就是調試器再次出馬的時候了,接收到一個其子進程(或被跟蹤進程)停止的信號,然后調試器要做下面幾件事:
1. 在目標地址上用原來的指令替換掉int 3
2. 將被跟蹤進程中的指令指針向后遞減1。這么做是必須的,因為現在指令指針指向的是已經執行過的int 3之后的下一條指令。
3. 由於進程此時仍然是停止的,用戶可以同被調試進程進行某種形式的交互。這里調試器可以讓你查看變量的值,檢查調用棧等等。
4. 當用戶希望進程繼續運行時,調試器負責將斷點再次加到目標地址上(由於在第一步中斷點已經被移除了),除非用戶希望取消斷點。
七、地址對齊
八、linux下運行程序的原理
作為UNIX操作系統的一種,Linux的操作系統提供了一系列的接口,這些接口被稱為系統調用(System Call)。在UNIX的理念中,系統調用"提供的是機制,而不是策略"。C語言的庫函數通過調用系統調用來實現,庫函數對上層提供了C語言庫文件的接口。在應用程序層,通過調用C語言庫函數和系統調用來實現功能。一般來說,應用程序大多使用C語言庫函數實現其功能,較少使用系統調用。
九、重寫和重載的區別
1.重寫不能再同一個類中,要在繼承或實現關系的類中;重載都可以
2.重寫方法名,返回類型,參數類型全部相同;重載方法名相同,參數列表不同,和返回類型無關。
3.重寫子類訪問修飾符大於父類;異常類型小於父類
十、HTTP實現斷點續傳
在Http的請求上多定義了斷點續傳相關的HTTP頭 Range和Content-Range字段而已。
可以通過標識文件最后修改時間和對文件進行唯一標識來確定是不是同一個文件。
十一、ArrayList與LinkedList的區別:
1.ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
2.ArrayList查找操作更快,linkedlist的插入刪除操作更快。
十二、List如何刪除。(為什么用iterator的不用List的刪除方法,講了一下ConcurrentModificationException)
list會報異常,因為 iterator的修改計數器和 list的修改計數器不一致就會返回異常。
十三、多態的底層實現。(看的不是很明白,復習完jvm后應該再理解一遍)
1、先從操作棧中找到對象的實際類型 class;
2、找到 class 中與被調用方法簽名相同的方法,如果有訪問權限就返回這個方法的直接引用,如果沒有訪問權限就報錯 java.lang.IllegalAccessError ;
3、如果第 2 步找不到相符的方法,就去搜索 class 的父類,按照繼承關系自下而上依次執行第 2 步的操作;
4、如果第 3 步找不到相符的方法,就報錯 java.lang.AbstractMethodError ;
可以看到,如果子類覆蓋了父類的方法,則在多態調用中,動態綁定過程會首先確定實際類型是子類,從而先搜索到子類中的方法。這個過程便是方法覆蓋的本質。
十四、Object有哪些公有方法。
clone:對象要實現 Cloneable接口
-淺拷貝:被復制對象的所有值屬性都含有與原來對象的相同,而所有的對象引用屬性仍然指向原來的對象。
-深拷貝:在淺拷貝的基礎上,所有引用其他對象的變量也進行了clone,並指向被復制過的新對象。
equals:在Object中與==是一樣的,子類一般需要重寫該方法
==:對於基本數據類型,比較的是值;對於引用數據類型,比較的是地址;
String中equals重寫過了,比較的是值。
hashCode:計算對象的哈希值,重寫過equals后一定要重寫hashCode,因為對象默認的hashCode計算是根據對象的地址進行計算的,哈希值的規定是兩個對象相同,則哈希值肯定相等,這就與equals沖突了,所以要重新寫hashCode。
getClass:class類的提供了你反射操作這個類的一個入口。
wait:調用某個對象的wait()方法,相當於讓當前線程交出此對象的monitor,然后進入等待狀態;
notify:喚醒一個線程
notify:喚醒所有線程.
toString : 默認打印類名+地址。一般需要重寫。
十五、堆溢出、棧溢出
十六、類加載機制,什么時候需要對類進行初始化。
1.new的時候,如果沒有初始化,則初始化
2、執行反射操作的時候
3、初始化一個類時,父類沒有初始化,則先初始化其父類
4、虛擬機啟動時,先初始化主類(包含main方法的類)
十七、如何減少GC
1、對象不用時設置為null
2、少使用 system.gc()
3.少使用靜態變量
4.字符串累加時盡量使用stringbuffer
5.分散對象創建時間
6.增大-Xmx的值
7.少使用裝箱類
十八、http報文格式
1.請求報文:
請求行:url,http版本,getpost方法
請求頭部
空行
請求內容
2.響應報文
狀態碼
頭部
空行
響應內容
十九、http狀態碼:
100,已收到請求的第一部分,繼續發送請求
2**,成功
3**,重定向
4**,請求錯誤
5**,服務器錯誤
600,響應報文沒有頭部只有內容。
二十、get/post的區別
get | post | |
安全性 | 不安全,在url上顯示了 | 安全 |
大小 | 較小,受瀏覽器限制 | 大 |
書簽,緩存 | 可存書簽緩存,因為url顯示 | 不可以 |
作用 | 一般用於獲取數據 | 一般用於更新數據 |
二十一、用戶輸入url后經歷了什么。
二十二、進程線程的區別
-
進程是資源分配的最小單位,線程是程序執行的最小單位。
-
進程有自己的獨立地址空間,每啟動一個進程,系統就會為它分配地址空間,建立數據表來維護代碼段、堆棧段和數據段,這種操作非常昂貴。而線程是共享進程中的數據的,使用相同的地址空間,因此CPU切換一個線程的花費遠比進程要小很多,同時創建一個線程的開銷也比進程要小很多。
-
線程之間的通信更方便,同一進程下的線程共享全局變量、靜態變量等數據,而進程之間的通信需要以通信的方式(IPC)進行。不過如何處理好同步與互斥是編寫多線程程序的難點。
-
但是多進程程序更健壯,多線程程序只要有一個線程死掉,整個進程也死掉了,而一個進程死掉並不會對另外一個進程造成影響,因為進程有自己獨立的地址空間。