一些小Tip
導語
個人感悟,持續更新中。。。
正文
無論NIO還是AIO,都沒有在數據傳輸過程(tcp/udp)作革命性的創新。他們在傳輸過程的效率和傳統BIO是一樣的,還是會產生阻塞(網絡延遲,Socket緩沖區滿了或空了),他們通過在OS層對Socket進行統一管理,進行事件管理。避免了進程級的線程開銷和線程阻塞(線程是JVM資源,這些都會阻塞線程棧,產生內存消耗和CPU時間片和上下文切換時間),JVM進程只需要一個線程來進行事件處理(不會阻塞)。也就是說,BIO,NIO,AIO的本質(Socket)其實是一樣的,只不過把矛盾轉移到了OS層(select,poll,epoll)。
調用一個對象的方法可以理解為在給這個對象發送一個通知。
HTTP是一種文本協議。所謂的文本協議是指,傳輸的數據可以通過文本表達出可讀的內容。HTTP傳輸的數據可以用ASCII字符集解析成可讀的文本,如請求行,請求頭。文件上傳時文件分隔符可以解析成文本,文件的的內容可能是二進制的,但是它不是協議的內容(協議不會定義數據具體內容,它只定義了一個容器,用來傳遞數據,無論是二進制數據還是文本數據)。與此相關的,Google ProtoBuf是一種二進制協議。
線程的阻塞狀態和IO阻塞狀態不是一回事。線程的阻塞是線程棧中的代碼正在等待臨獲取臨界區的鎖。而IO的阻塞狀態是包含在線程的Runnable狀態的。詳細
CPU能認識的就僅僅是中斷線和中斷處理程序這些概念。所謂線程,進程,軟中斷等概念,是軟件發明出來的,CPU是不認識的。所謂線程,本質上是保存CPU運行狀態的一種形式,CPU的運行狀態,就是CPU的所有寄存器的內容的集合(包括用來控制中斷的寄存器),線程的作用就是可以把這些寄存器都保存下來(其實還有軟件本身的堆棧等其他信息,但我們這里不關心軟件,先忽略),然后用另一個保存的狀態刷新CPU的狀態,讓CPU感覺自己在運行到另一個上下文上。OS對CPU不斷進行狀態的切換,保存上一個狀態,加載下一個線程的狀態,就實現線程切換了。至于進程,本質上可以認為是線程切換的同時也會切換地址空間。這里我們混用這兩個概念。詳細
中斷和上下文切換: 通知操作系統發生了外部事件的機制是中斷當前運行線程并將控制轉移到中斷處理程序。在中斷處理程序可以運行之前,必須保存足夠的硬件狀態以保證在中斷處理完成后系統能恢復線程的上下文。新調用的中斷處理程序將經歷在硬件層次結構中上移帶來的所有延遲(除了頁面故障)。如果該中斷處理程序最近沒有運行過(或者中間程序很節約時間),那么它的任何代碼或數據不太可能保留在 TLB 或高速緩存中。當再次調度已中斷的線程時,它的執行上下文(如寄存器內容)邏輯上將得到恢復,以便它可以正確運行。然而,TLB 和高速緩存的內容必須根據程序的后繼請求重新構造。因此,作為中斷的結果,中斷處理程序和被中斷的線程都可能遇到大量的高速緩存未命中和 TLB 未命中延遲。
系統調用,陷入內核。詳細
比較int大小時,如果簡單的使用 a - b > 0來判斷會很不安全。因為如果差值可能是int范圍的兩倍。如最大正數減最小負數。差值會溢出,截取低位。從而產生難以預見的錯誤。
字節流和它的包裝流,只能被讀取一次。讀完一次后在讀會讀不到數據。兩種方式解決:重置流和將流讀出來緩存后重復使用。
java類中硬編碼的字符串長度最大為2個字節表達的長度,即65536。因為類的常量池中字符串類型常量的長度標志位為兩個字節。否則無法通過編譯檢查。但是在運行時在內存中動態生成的字符串不受此限制。
總結
- 上一篇: MySQL和Oracle的区别
- 下一篇: Linux下新建一个站点