日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

面试必会系列 - 4.1 程序员必须掌握的:计算机组成、操作系统知识点汇总

發布時間:2024/2/28 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试必会系列 - 4.1 程序员必须掌握的:计算机组成、操作系统知识点汇总 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文已收錄至 Github(MD-Notes),若博客中圖片模糊或打不開,可以來我的 Github 倉庫,包含了完整圖文:https://github.com/HanquanHq/MD-Notes,涵蓋了互聯網大廠面試必問的知識點,講解透徹,長期更新中,歡迎一起學習探討 ~

更多內容,可以訪問:

面試必會系列專欄:https://blog.csdn.net/sinat_42483341/category_10300357.html
操作系統系列專欄:https://blog.csdn.net/sinat_42483341/category_10519484.html


目錄

  • 計組、操作系統
        • CPU電路原理
        • CPU的基本組成
        • 超線程
        • 計算機的組成
        • 存儲器的層次結構
        • 多核CPU
        • 緩存行對齊偽共享問題
          • 緩存行大小
          • Intel CPU 緩存一致性協議
          • 其他 CPU 緩存一致性協議
        • 非同一訪問內存 NUMA
        • 操作系統啟動過程
      • 匯編語言(機器語言)的執行過程
      • 名詞
      • 常識
          • 吞吐量:單位時間可以讀取的數據
      • 總線的分類
      • 進程、線程
        • 進程
            • 1、僵尸進程
            • 2、孤兒進程
        • 線程
          • 思考:java線程是用戶級線程還是內核級線程?
        • 協程(纖程)
          • 纖程
          • 纖程的優勢
      • 原語
      • 中斷、系統調用
      • 用戶態、內核態
      • mmap
      • 內存管理
          • LRU算法(解決內存不夠用的問題)
        • 虛擬內存
        • 缺頁中斷
      • Linux 內核同步機制
        • 關于同步理論的一些基本概念
        • Linux 內核同步常用方法
      • Linux VFS 虛擬文件系統
        • 硬鏈接、軟鏈接
        • 文件描述符 fd
      • PageCache 頁緩存
          • 為什么 Java 程序員不要使用直接 IO,而要使用 Buffered 形式的IO?
  • Linux
      • Linux 目錄樹
      • Linux 文件類型
      • Linux 常用命令
        • 進程相關
        • 網絡相關


計組、操作系統

匯編和操作系統代碼,又是不同層面的東西。匯編是針對CPU編程。系統內核方法,是針對操作系統編程。

CPU電路原理

CPU的基本組成

PC -> Program Counter 程序計數器 (記錄當前指令地址)
Registers -> 暫時存儲CPU計算需要用到的數據
ALU -> Arithmetic & Logic Unit 運算單元
CU -> Control Unit 控制單元
MMU -> Memory Management Unit 內存管理單元

超線程

一個ALU對應多個Registers

切換線程的時候不需要進行上下文切換,只需要切換到對應的Registers即可

計算機的組成

存儲器的層次結構

添加緩存,是為了解決 CPU 到不同部件的速度差別過大的問題

多核CPU

不同的核心有各自獨立的 L1,L2,但共享 L3 級緩存。為什么是3級?這是工業上的經驗值。

按塊讀取:根據程序局部性原理,提高效率,充分發揮總線CPU針腳一次性讀取更多數據的能力

讀取數據是通過 DMA 硬件進行的,直接內存訪問,用來做數據的搬運。通過協處理器,而不需要走CPU。偏向硬件,驅動開發的人員會接觸。

緩存行對齊偽共享問題

緩存行大小

緩存行越大,局部性空間效率越高,但讀取時間慢;緩存行越小,局部性空間效率越低,但讀取時間快。取一個折中值,目前 Intel CPU 緩存行64字節

Intel CPU 緩存一致性協議

怎么保證數據的一致性?Intel MESI 緩存一致性協議,數據四種狀態:

  • M: 被修改(Modified)

    該緩存行只被緩存在該CPU的緩存中,并且是被修改過的(dirty),即與主存中的數據不一致,該緩存行中的內存需要在未來的某個時間點(允許其它CPU讀取請主存中相應內存之前)寫回(write back)主存。當被寫回主存之后,該緩存行的狀態會變成獨享(exclusive)狀態。

  • E: 獨享的(Exclusive)

    該緩存行只被緩存在該CPU的緩存中,它是未被修改過的(clean),與主存中數據一致。該狀態可以在任何時刻當有其它CPU讀取該內存時變成共享狀態(shared)。同樣地,當CPU修改該緩存行中內容時,該狀態可以變成Modified狀態。

  • S: 共享的(Shared)

    該狀態意味著該緩存行可能被多個CPU緩存,并且各個緩存中的數據與主存數據一致(clean),當有一個CPU修改該緩存行中,其它CPU中該緩存行可以被作廢(變成無效狀態(Invalid))。

  • I: 無效的(Invalid)

    該緩存是無效的(可能有其它CPU修改了該緩存行)。

其工作原理是,當CPU1在獲取計算機內存i時,這是CPU2也可以獲取這個變量i。當CPU1對它取回的變量進行操作后。CPU1的i會被標記為被修改的(Modified),他需要將i寫入主內存將i標記為獨享狀態(Exclusive),這時CPU1會立即將i這個變量寫入計算機內存。這時計算機內存中的i會被標記為共享的(Shared)同時CPU2中的i會被標記為無效的(Invalid),然后CPU2就只能重新從計算機內存中獲取新的i變量。然后在進行CPU2中i的操作。

其他 CPU 緩存一致性協議

其他廠商的 CPU 也有緩存一致性協議,例如 MSI,MESI,MOSI,Synapse,Firefly,Dragon 等等。

盡管有緩存一致性協議,有些無法被緩存的數據,或者跨越多個緩存行的數據,依然必須使用總線鎖。

一種情況,假設有兩個線程想要修改的數據,位于同一個緩存行 cache line,你改的時候要通知我,我改的時候要通知你,于是因為緩存行的存在,相比沒有緩存行而言,反而效率會比較低。

于是誕生了一種編程模式:緩存行對齊,對于某些高競爭級別訪問的數據,為了保證不發生偽共享,可以采用緩存行對齊的編程方式,即,使用多個 long 類型的變量,將數據前后緩存行撐起來。例如:單機最快的內存消息隊列 disruptor,核心是一個 ring buffer,它的 cursor 前后分別放了 7個 long 類型數字。

JDK7中,很多采用long padding提高效率

JDK8,加入了@Contended注解(實驗)需要加上:JVM -XX:-RestrictContended

非同一訪問內存 NUMA

UMA:同一內存訪問。多個CPU通過一條總線,訪問同一個內存。
現在很多服務器的架構是使用NUMA的,因為UMA不以拓展:隨著CPU的數量增多,許多時間被浪費在CPU爭搶內存資源上。

NUMA:非同一訪問內存。每個CPU有自己專屬的內存,CPU對于自己插槽上的內存訪問是有優先級的。

ZGC 垃圾回收器可以做到 NUMA aware,如果探測到計算機實現了NUMA的話,分配內存會優先分配該線程所在CPU的最近內存。

操作系統啟動過程

通電 -> bios uefi 工作 -> 自檢 -> 到硬盤固定位置加載 bootloader -> 讀取可配置信息 -> CMOS

bootloader 在硬盤上的位置是固定的,放在硬盤的第一個扇區上

CMOS 用來存儲可以配置的信息,需要通電才能存儲信息,例如開機密碼。主板上有塊電池給它通電。

操作系統的第一條指令在硬盤中也是固定的

匯編語言(機器語言)的執行過程

匯編語言的本質:機器語言的助記符 其實它就是機器語言

計算機通電 -> CPU讀取內存中程序(電信號輸入)->時鐘發生器不斷震蕩通斷電 ->推動CPU內部一步一步執行(執行多少步取決于指令需要的時鐘周期)->計算完成->寫回(電信號)->寫給顯卡輸出(sout,或者圖形)

名詞

異地持久化

常識

秒 > 毫秒 > 微妙 > 納秒

磁盤尋址:毫秒級別(磁頭移動等)

內存尋址:納秒級別(磁盤、內存差距10W倍)

吞吐量:單位時間可以讀取的數據

磁盤IO:百兆級別(SATA3 幾百MB,PCI-E GB級別)

總線的分類

數據總線、地址總線、控制總線

進程、線程

進程是操作系統分配資源的基本單位,線程是操作系統執行調度的基本單位。

進程

  • 進程 是處于執行期的程序以及相關資源的總稱,分配了獨立的內存空間
  • 所有的進程都是 PID 為 1 的 init 進程的后代
  • 內核把進程的列表放在任務隊列 task list 中,鏈表中的每一項都是 進程描述符
    • 進程描述符包含:它打開的文件、進程的地址空間、掛起的信號、進程的狀態等
  • 進程狀態
    • 運行:進程是可執行的
    • 可中斷:正在睡眠,等待某些條件的達成,可以因為收到信號而提前被喚醒
    • 不可中斷:即使收到信號,也不會被喚醒
    • 被其他進程跟蹤:例如通過 ptrace 對調試程序進行跟蹤
    • 停止:進程沒有投入運行,也不能投入運行
  • 進程的創建
    • Linux 中,父進程通過 fork() 創建子進程,fork() 內部調用的是 clone()
    • Linux 的 fork() 使用 寫時拷貝 頁實現
  • 進程的調度
    • Linux 使用 CFS(Completely Fair Scheduler 完全公平調度)
      • 確保給每個進程公平的 處理器使用比,按 優先級 分配 時間片的比例,記錄每個進程的執行時間,如果有一個進程執行時間不到他應該分配的比例(比如給了你50%,你只用了10%),就優先執行這個進程作為補償。例如,一個是用戶鼠標移動優先級高,另一個是 IO 密集型優先級低
      • 紅黑樹 維護 可運行進程隊列,每次運行紅黑樹中 最左邊葉子結點 代表的進程
      • 分為實時進程(始終優先于普通進程)、普通進程(根據 nice 值分配時間片)
1、僵尸進程

在大多數情況下,少量僵尸進程的存在,對操作系統沒有太大影響,它基本不再占用任何資源了,它在內存中唯一占用的資源就是PCB了。僵尸進程的產生原因,有可能父進程是一個daemon進程,C程序開發人員在父進程沒有釋放子進程,這時會出現僵尸進程。可以使用內核中的wait函數,釋放僵尸進程。

2、孤兒進程

孤兒進程產生的原因:子進程還活著,父進程掛了。孤兒進程和孤兒線程沒有太大區別,因為在Linux中,進程和線程沒有太大區別。孤兒進程的影響:影響不大。

線程

  • 線程是在進程中活動的對象
  • 內核調度的對象是 線程,而不是 進程
  • Linux 把所有的線程都當做進程來實現,線程僅僅被視為一個與其他進程共享某些資源的進程,只不過和其他線程共享同一個主進程中的內存空間 ——《Linux內核設計與實現》
  • 線程共享進程的內存空間,沒有自己獨立的內存空間
思考:java線程是用戶級線程還是內核級線程?
  • java 線程不是純用戶級線程:java中有個 fork join 框架,利用多處理技術進行 maprudce 的工作,證明了內核是可以感知到用戶線程的存在,因此才會將多個線程調度到多個處理器中。

    java應用程序中的某個線程阻塞,是不會引起整個進程的阻塞。

  • java 線程不是純內核級線程:如果使用純粹的內核級線程,那么有關線程的所有管理工作都是內核完成的,用戶程序中沒有管理線程的代碼。顯然,java線程庫提供了大量的線程管理機制,因此java線程絕不是純粹的內核級線程。

    馬士兵:“ JVM 線程和內核中的線程是 1:1 的關系”

  • 綜上,java線程是混合型的線程模型,一般而言,是通過lwp將用戶級線程映射到內核線程中。

  • 補充:《現代操作系統》P79:“Java 支持用戶級線程”

    協程(纖程)

    JVM(HotSpot)和操作系統的線程是一一對應的:JVM空間的一個線程,對應操作系統中的一個線程,這是重量級線程。

    操作系統可以開啟的線程是有限的(1萬個已經很卡了),而纖程用戶空間的,不需要與內核打交道,輕量級,切換速度快,可以啟動幾萬個,甚至幾十萬個都沒有問題。

    纖程

    纖程可以被理解為:線程里的線程,在JVM層級用軟件進行內部的線程協調。
    纖程是被 JVM 管理,運行在用戶態,操作和調度不經過操作系統內核。
    關于纖程的實現:纖程可以分配自己獨立的纖程棧,相當于自己實現了一個小小的操作系統級別的調度程序。

    Java 通過 Quaser 類庫可以支持纖程,但目前還不是很成熟,據說如果大規模應用在生產級別的話,還是有一些小bug存在的。

    纖程的優勢

    1、占有資源很少。操作系統啟動一個線程,占用 1M 的內存空間,而啟動一個纖程只需要 4K 空間
    2、由于輕量級,切換簡單
    3、由于輕量級,可以啟動幾十萬個纖程都沒有問題。

    原語

    • 是一種特殊的程序,運行在 內核態
    • 處于操作系統最底層,是最接近硬件的部分
    • 這種程序的運行具有原子性,只能一氣呵成,不可被中斷
    • 運行時間較短、調用頻繁
    • 原語采用“關中斷指令”和“開中斷指令”實現

    中斷、系統調用

    系統調用表及源碼鏈接 https://filippo.io/linux-syscall-table/

    系統調用 是用戶空間訪問內核的唯一手段,除 異常陷入 外,它是內核的唯一合法入口。

    Linux 的系統調用,作為 C 庫的一部分提供,用戶空間進程系統調用號 來指明執行哪個系統調用。

    進行系統調用的步驟:

  • 用戶空間應用程序把 系統調用號 放入 eax 寄存器中,外部參數 放在另外的 5 或 6 個寄存器中
  • 應用程序通過 int $0x80 觸發 軟中斷(異常),系統切換到內核態,執行 128 號異常處理程序,即 system_call() 系統調用處理程序
  • system_call() 運行,從 eax 寄存器中得到 系統調用號,檢查其有效性,然后 執行相應的系統調用
  • 內核在執行系統調用的時候,處于 進程上下文。在進程上下文中,內核 可以休眠,并且 可以被搶占
  • 系統調用返回 的時候,system_call() 負責 切換回用戶空間,并讓用戶進程繼續執行 int $0x80 的下一條指令
  • # Simple program that exits and returns a status code back to the Linux kernel ./section .data # 以.為開頭的名稱不會被翻譯為機器指令,而是作為一種匯編提示告知匯編器 ,這個形式直接被稱為 “匯編指令” 或 ”偽操作“ ./section .text # .text 段位保存代碼, 是只讀和可執行的。后面的指令都是屬于 .text 段。 .globl _start # 告訴編譯器,_start 這個符號就像c程序中的main函數一樣,是整個程序的入口 _start : # 是一個符號,符號在匯編中表示一個地址,可以再指令中 ,匯編程序經過匯編器的處理后, 所有的符號都被替換成為它所代表的地址值。(通俗說,c語言中的函數變量名都屬于符號) # movl 是一條數據傳送指令,要求CPU內部產生一個long數字1并保存到eax寄存器中。 # 1表示在CPU內部產生 ,稱為立即數,立即數在前面要加個$ ,寄存器就加個% movl $1 ,%eax # eax 寄存器用來指定系統調用號 movl $4 ,%ebx # _ebx 的值是傳給 _exit 的參數,表示退出狀態。_exit 的系統調用號為1。 int $0x80 # int 指令中的立即數 0x80 是一個參數,可以用于執行系統調用

    用戶態、內核態

    Intel CPU 分為三級:ring 0,1,2,3三個級別

    Linux 只使用了 0,3 兩個級別。

    Linux 內核是運行在 ring 0 級別的,能訪問所有指令;應用程序只能訪問 Ring 3 級。

    用戶空間的應用程序運行在 ring 3 級別,某些指令是不能被訪問的,想要讀硬盤、寫硬盤、寫網卡等,對于系統的關鍵訪問,需要通過操作系統內核,因此需要轉換為內核態。正是因為這樣的分層,使得現在的Linux,Windows非常健壯,不會輕易被程序搞崩。

    Linux 內核提供了 200 多個系統調用,例如 sendfile read write pthread fork等對外暴露的函數。

    內核空間:只有內核能訪問的空間。用戶是不可能將這塊內存干掉的。
    用戶空間:用戶可以直接操作的空間。

    mmap

    mmap將 用戶的線性地址空間 直接映射到了 內核的 pagecache 地址,如果是臟的需要寫的話,依然受pagecache 的影響,才能最終刷寫到磁盤中去。

    內存管理

    DOS時代 - 同一時間只能有一個進程在運行(也有一些特殊算法可以支持多進程)

    windows9x - 多個進程裝入內存存在的問題:

    • 內存不夠用
    • 互相打擾

    為了解決這兩個問題,誕生了現在的內存管理系統:使用虛擬地址、分頁裝入、軟硬件結合尋址。

    將內存分頁(因為內存不夠用),內存中分成固定大小的頁框4K,把硬盤上的程序也分成4K大小的塊。另外維護一個頁框page frame,用到哪一塊,就將哪一塊加載進內存中。

    例如,執行QQ.exe時,把它的頁表記錄下來,執行時,用到頁表中的哪一頁,就將這頁加載進內存中。
    在加載的過程中,如果內存已經滿了,會把最不常用的一塊放到swap分區, 把最新的一塊加載進來,這個就是著名的LRU算法。這就是交換分區的由來。

    LRU算法(解決內存不夠用的問題)

    LeetCode 146 題,頭條要求15分鐘內手撕,阿里去年也要求手撕。

    只允許使用 HashMap 實現 LRU 算法,哈希表(保證查找操作O(1)) + 雙向鏈表 (保證排序操作和新增操作 O(1)))

    • LRU (Least recently used) 最近最少使用,如果數據最近時間被訪問過,那么將來被訪問的幾率也更高。
    • LFU (Least frequently used) 最不經常使用,如果一個數據在最近一段時間內使用次數很少,那么在將來一段時間內被使用的可能性也很小。

    虛擬內存

    以DOS Win31 …這類系統為例,A進程、B進程是可以互相操作內存的。為了保證互不影響,讓進程工作在虛擬空間。在程序中用到的空間地址不再是直接的物理地址,而是虛擬的地址,這樣,A進程永遠不可能訪問到B進程的空間。

    **虛擬空間多大呢?**虛擬空間的大小就是尋址空間,要看操作系統是多少位的。例如,64位系統的虛擬空間是2^64,32為系統的虛擬空間是2^32。虛擬空間比物理空間大很多 ,單位是 byte

    **為什么使用虛擬內存?**站在虛擬的角度,進程是獨享整個系統 + CPU

    **地址是怎么映射的?**內存映射:偏移量 + 段的基地址 = 線性地址 (虛擬空間)
    線性地址,是通過 OS + MMU(Memory Management Unit內存管理單元)來映射到真正的物理地址。只有操作系統內核知道虛擬內存中地址對應的真正的物理地址,應用程序是不知道的,這樣保證了系統的安全。

    缺頁中斷

    進程P1,P2,P3,P4都認為自己是獨占整個內核的,實際上是共享操作系統內核。
    MMU給每一個進程分配他們的內存資源。
    如果內存裝滿了,使用LRU算法將最不常使用的頁放入硬盤的交換空間中。

    在執行一條指令時,如果發現需要用到頁在內存中沒有,那么停止該指令的執行,并產生一個缺頁異常(中斷),由內核處理并加載,之后,原先引起的異常的指令就可以繼續執行,而不再產生異常。

    Linux 內核同步機制

    關于同步理論的一些基本概念

    • 臨界區(critical area): 訪問或操作共享數據的代碼段
      簡單理解:synchronized大括號中部分(原子性)
    • 競爭條件(race conditions)兩個線程同時擁有臨界區的執行權
    • 數據不一致:data unconsistency 由競爭條件引起的數據破壞
    • 同步(synchronization)避免race conditions
    • 鎖:鎖是完成同步的手段(門鎖,門后是臨界區,只允許一個線程存在)
      上鎖解鎖必須具備原子性(如果連上鎖的過程都會被打斷的話,就沒有什么意義了)
    • 原子性(象原子一樣不可分割的操作)
    • 有序性(禁止指令重排)
    • 可見性(一個線程內的修改,另一個線程可見)

    互斥鎖 排他鎖 共享鎖 分段鎖

    Linux 內核同步常用方法

    了解一下Linux內核實現的一些同步方法,了解一些關于線程控制的理論知識,可以去印證Java層面的同步知識。
    用的話要用C語言去調用。

  • 原子操作 – Linux內核中提供了類似于 Java 中的 AtomicXXX 的原子操作,位于Linux內核源碼的頭文件``,是從原語層面的支持,不需要實現CAS
  • 自旋鎖 – 內核中通過匯編支持的CAS自旋鎖,位于``。
  • 讀-寫自旋 – 類似于ReadWriteLock,可以同時讀,但只能一個寫
    相當于:的時候是共享鎖,的時候是排他鎖
  • 信號量 – 類似于Java中的Semaphore(PV操作,down up操作,就是占有鎖和釋放鎖)
    是一個重量級鎖,線程會進入wait,適合長時間持有的鎖情況
  • 讀-寫信號量 – downread upread downwrite upwrite
    (多個寫,可以分段寫,比較少用)(分段鎖)
  • 互斥體(mutex) – 特殊的信號量(二值信號量)
  • 完成變量 – 特殊的信號量(A發出信號給B,B等待在完成變量上)
    vfork() 在子進程結束時通過完成變量叫醒父進程 類似于(Latch)
    在網絡編程中有完成端口(Completion Port)
  • BKL:大內核鎖 Big kernel lock(早期,現在已經不用)
  • 順序鎖(內核版本2.6之后新增加的): – 線程可以掛起的讀寫自旋鎖
    序列計數器(從0開始,寫時增加(+1),寫完釋放(+1),讀線程不對計數器做任何操作)
    寫的時候,不妨礙讀線程:
    如果讀線程發現是偶數,說明在讀的時候沒有任何人改變過。
    如果讀線程發現是奇數,說明你讀到的可能是中間狀態,你可以選擇繼續自旋,等待值變為偶數。
    讀前讀后序列一樣,說明沒有寫線程打斷。
  • 禁止搶占 – preempt_disable():我這個線程在執行過程中,不允許任何線程打斷我。
  • 內存屏障 – 見 volatile
  • Linux VFS 虛擬文件系統

    Virtual Filesystem Switch,虛擬文件系統,是一個目錄樹。樹上不同的節點可映射到物理的文件地址,可掛載。

    相當于一個解耦層,在具體的文件系統之上抽象的一層,為能夠給各種文件系統提供一個通用的接口,使上層的應用程序能夠使用通用的接口訪問不同文件系統、不同的驅動。

    硬鏈接、軟鏈接

    • 硬鏈接
      • 兩個變量名指向了同一個物理位置,硬鏈接的文件擁有相同的 inode,操作系統是靠inode來區分文件的。2個inode相同的文件,代表它們是一個文件。
      • 如果刪掉了其中一個文件,另外一方還能找到這個文件。相當于只是刪除了一個引用。除非你把硬鏈接和源文件都刪除, 這個文件才被刪除。
    • 軟鏈接
      • 軟鏈接是兩個獨立的文件,相當于創建了一個“快捷方式”
      • 文件的共享用戶只有該文件的 路徑名,只有文件擁有者才擁有 指向其索引節點的指針
      • 當符號鏈接被刪除時,并不會影響源文件。但是當源文件被刪除時,符號鏈接就找不到源文件了,會標紅報錯。
      • 軟鏈接有著 自己的 inode 號 以及用戶數據塊。
      • 軟鏈接可跨文件系統,硬鏈接不行
    • 共性
      • 無論是硬鏈接還是軟連接,如果修改任意一方,另外一個文件也會看到這個變化。

    文件描述符 fd

    任何程序都有:0 標準輸入,1 標準輸出, 2 報錯輸出

    • lsof 列出系統中打開的文件

      lsof -op $$看見當前進程的文件描述符的細節,包括偏移量、指針等等

    • /proc/$$/fd是當前程序的所有的文件描述符

    PageCache 頁緩存

    PageCache 通常 4K,本來是用來優化IO的性能(優先走內存),但它的缺點是刷寫硬盤不及時,在突然關機或異常斷電時,有丟失數據的可能

    為什么 Java 程序員不要使用直接 IO,而要使用 Buffered 形式的IO?

    一次寫一個緩沖區大小,減少調用 write 的次數,只不過是每一次寫入的數據量比較大。減少了用戶態到內核態的來回切換帶來的性能損耗。

    • ByteBuffer
      • allocate將字節數組分配到了堆上,是 JVM 堆內 的線性地址空間
      • allocateDirect將字節數組分配到 JVM 的堆外 內存中,是 C 語言可以直接訪問的。

    操作系統沒有絕對的數據可靠性。為什么要設計 pagecache,是為了減少硬件的IO的調用,想要優先使用內存,這樣能夠提速。如果追求性能,就要在一致性、可靠性之間做出權衡。

    從大方面來看,在現在的分布式系統當中,如果你追求數據存儲的可靠性(保持緩存和磁盤的強一致,對于每一次對數據的微小改變,都要去刷寫磁盤),仍然避免不了單點故障的問題。單點故障會讓你為了保持強一致而耗費的能損耗一毛錢收益都沒有。

    這就是為什么我們使用主從復制、主備HA
    這就是為什么 Kafka,ES 都有副本的概念,而副本是從 socket 得到的。副本又分為同步的異步的區別,這些都是后話了,我們以后再講…

    Linux

    Linux 目錄樹

    常見目錄說明:

    • /bin: 存放二進制可執行文件(ls、cat、mkdir等),常用命令一般都在這里;
    • /etc: 存放系統管理和配置文件;
    • /home: 存放所有用戶文件的根目錄,是用戶主目錄的基點,比如用戶user的主目錄就是/home/user,可以用~user表示;
    • /usr : 用于存放系統應用程序;
    • /opt: 額外安裝的可選應用程序包所放置的位置。一般情況下,我們可以把tomcat等都安裝到這里;
    • /proc: 虛擬文件系統目錄,是系統內存的映射。可直接訪問這個目錄來獲取系統信息;
    • /root: 超級用戶(系統管理員)的主目錄(特權階級o);
    • /sbin: 存放二進制可執行文件,只有root才能訪問。這里存放的是系統管理員使用的系統級別的管理命令和程序。如ifconfig等;
    • /dev: 用于存放設備文件;
    • /mnt: 系統管理員安裝臨時文件系統的安裝點,系統提供這個目錄是讓用戶臨時掛載其他的文件系統;
    • /boot: 存放用于系統引導時使用的各種文件;
    • /lib : 存放著和系統運行相關的庫文件 ;
    • /tmp: 用于存放各種臨時文件,是公用的臨時文件存儲點;
    • /var: 用于存放運行時需要改變數據的文件,也是某些大文件的溢出區,比方說各種服務的日志文件(系統啟動日志等。)等;
    • /lost+found: 這個目錄平時是空的,系統非正常關機而留下“無家可歸”的文件(windows下叫什么.chk)就在這里。

    Linux 文件類型

    Linux支持很多文件類型,其中非常重要的文件類型有: 普通文件,目錄文件,鏈接文件,設備文件,管道文件,Socket套接字文件等。

    Linux 常用命令

    進程相關

    ps -ef / ps -aux: 查看當前系統正在運行進程,展示格式不同。如果想查看特定的進程,使用:ps aux | grep redis (查看包括redis字符串的進程),也可使用 pgrep redis

    kill -9 進程pid: 殺死進程(-9 表示強制終止)

    網絡相關

    網絡通信命令:

    • 查看當前系統的網卡信息:ifconfig / ip -a
    • 查看當前系統的端口使用:netstat -an

    總結

    以上是生活随笔為你收集整理的面试必会系列 - 4.1 程序员必须掌握的:计算机组成、操作系统知识点汇总的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。