– 共享:資源可被多個併發執行的進程使用
– 併發:能夠在同一時間間隔處理多個進程,須要硬件支持
– 虛擬:將物理實體映射成爲多個虛擬設備
– 異步:進程執行走走停停,每次進程執行速度可能不一樣,但OS需保證進程每次執行結果相同前端
程序段、數據段、PCB(Process Control Block)java
併發:同一間隔 並行:同一時刻node
保持處理機上下文 -> 更新PCB -> 把PCB移入相應隊列(就緒、阻塞) -> 選擇另外一個進程並更新其PCB -> 更新內存管理的數據結構 -> 恢復處理機上下文linux
一、低級通訊方式
PV操做(信號量機制)。
– P:wait(S)原語,申請S資源
– V:signal(S)原語,釋放S資源
二、高級通訊方式:以較高效率傳輸大量數據的通訊方式
– 共享存儲(使用同步互斥工具操做共享空間)
– 消息傳遞(進程間以格式化的消息進行數據交換,有中間實體,分爲直接和間接兩種,底層經過發送消息和接收消息兩個原語實現)
– 管道通訊(兩個進程中間存在一個特殊的管道文件,進程的輸入輸出都經過管道,半雙工通訊)c++
由一組數據及對這組數據操做的定義組成的模塊。同一時間只能有一個進程使用管程,即管程是互斥使用的,進程釋放管程後需喚醒申請管程資源的等待隊列上的進程。進程只有經過進入管程並使用管程內部的操做才能訪問其中數據。git
– 互斥條件:資源在某一時刻只能被一個進程佔有
– 不剝奪條件:進程所持有的資源在主動釋放前不能被其餘進程強行奪走
– 請求和佔用條件:死鎖進程必然是既持有資源又在申請資源的
– 循環等待條件:存在等待鏈,互相申請,互不釋放
避免死鎖:不讓循環等待條件發生。使用銀行家算法。程序員
– 都是資源分配問題
– 死鎖是等待永遠不會釋放的資源,而飢餓申請的資源會被釋放,只是永遠不會分配給本身
– 一旦產生死鎖,則死鎖進程必然是多個,而飢餓進程能夠只有一個
– 飢餓的進程可能處於就緒狀態,而死鎖進程必定是阻塞進程github
線程被稱做輕量級進程,在進程中包含線程。進程有獨立的內存空間,不一樣進程間不能直接共享其餘進程資源,而同一個進程內的線程共享進程內存空間;相比進程,線程切換對系統開銷更小一些;進程是資源分配的最小單位,線程是程序執行的最小單位。web
文件指針:上次讀寫位置。
文件打開數:多少個進程打開了此文件。
文件磁盤位置。
文件的訪問權限:建立、只讀、讀寫等。redis
所選擇的被淘汰頁面將是之後永不使用的,或者是在最長時間內再也不被訪問的頁面,這樣能夠保證得到最低的缺頁率。但因爲人們目前沒法預知進程在內存下的若千頁面中哪一個是將來最長時間內再也不被訪問的,於是該算法沒法實現。
優先淘汰最先進入內存的頁面,亦即在內存中駐留時間最久的頁面。該算法實現簡單,只需把調入內存的頁面根據前後次序連接成隊列,設置一個指針總指向最先的頁面。但該算法與進程實際運行時的規律不適應,由於在進程中,有的頁面常常被訪問。
最近最長時間未訪問過的頁面予以淘汰,它認爲過去一段時間內未訪問過的頁面,在最近的未來可能也不會被訪問。該算法爲每一個頁面設置一個訪問字段,來記錄頁面自上次被訪問以來所經歷的時間,淘汰頁面時選擇現有頁面中值最大的予以淘汰。
LRU算法的性能接近於OPT,可是實現起來比較困難,且開銷大;FIFO算法實現簡單,但性能差。因此操做系統的設計者嘗試了不少算法,試圖用比較小的開銷接近LRU的性能,這類算法都是CLOCK算法的變體。
簡單的CLOCK算法是給每一幀關聯一個附加位,稱爲使用位。當某一頁首次裝入主存時,該幀的使用位設置爲1;當該頁隨後再被訪問到時,它的使用位也被置爲1。對於頁替換算法,用於替換的候選幀集合看作一個循環緩衝區,而且有一個指針與之相關聯。當某一頁被替換時,該指針被設置成指向緩衝區中的下一幀。當須要替換一頁時,操做系統掃描緩衝區,以查找使用位被置爲0的一幀。每當遇到一個使用位爲1的幀時,操做系統就將該位從新置爲0;若是在這個過程開始時,緩衝區中全部幀的使用位均爲0,則選擇遇到的第一個幀替換;若是全部幀的使用位均爲1,則指針在緩衝區中完整地循環一週,把全部使用位都置爲0,而且停留在最初的位置上,替換該幀中的頁。因爲該算法循環地檢查各頁面的狀況,故稱爲CLOCK算法,又稱爲最近未用(Not Recently Used, NRU)算法。
改進型的CLOCK算法優於簡單CLOCK算法之處在於替換時首選沒有變化的頁。因爲修改過的頁在被替換以前必須寫回,於是這樣作會節省時間。
就是按照各個做業進入系統的天然次序來調度做業。這種調度算法的優勢是實現簡單,公平。其缺點是沒有考慮到系統中各類資源的綜合使用狀況,每每使短做業的用戶不滿意,由於短做業等待處理的時間可能比實際運行時間長得多。
就是優先調度並處理短做業,所謂短是指做業的運行時間短。而在做業未投入運行時,並不能知道它實際的運行時間的長短,所以須要用戶在提交做業時同時提交做業運行時間的估計值。
FCFS可能形成短做業用戶不滿,SPF可能使得長做業用戶不滿,因而提出HRN,選擇響應比最高的做業運行。響應比=1+做業等待時間/做業處理時間。
每個做業規定一個表示該做業優先級別的整數,當須要將新的做業由輸入井調入內存處理時,優先選擇優先數最高的做業。
進程有三種狀態阻塞就緒,運行。
按照進程進入就緒隊列的前後次序來選擇。即每當進入進程調度,老是把就緒隊列的隊首進程投入運行。
分時系統的一種調度算法。輪轉的基本思想是,將CPU的處理時間劃分紅一個個的時間片,就緒隊列中的進程輪流運行一個時間片。當時間片結束時,就強迫進程讓出CPU,該進程進入就緒隊列,等待下一次調度,同時,進程調度又去選擇就緒隊列中的一個進程,分配給它一個時間片,以投入運行。
進程調度每次將處理機分配給具備最高優先級的就緒進程。最高優先級算法可與不一樣的CPU方式結合造成可搶佔式最高優先級算法和不可搶佔式最高優先級算法。
幾種調度算法的結合形式多級隊列方式。
讓離當前磁道最近的請求訪問者啓動磁盤驅動器,便是讓查找時間最短的那個做業先執行,而不考慮請求訪問者到來的前後次序,這樣就克服了先來先服務調度算法中磁臂移動過大的問題
老是從磁臂當前位置開始,沿磁臂的移動方向去選擇離當前磁臂最近的那個柱面的訪問者。若是沿磁臂的方向無請求訪問時,就改變磁臂的移動方向。在這種調度方法下磁臂的移動相似於電梯的調度,因此它也稱爲電梯調度算法。
循環掃描調度算法是在掃描算法的基礎上改進的。磁臂改成單項移動,由外向裏。當前位置開始沿磁臂的移動方向去選擇離當前磁臂最近的哪一個柱面的訪問者。若是沿磁臂的方向無請求訪問時,再回到最外,訪問柱面號最小的做業請求。
分配給文件的全部盤塊號都放在FAT中,用以記錄了文件的物理位置。
中斷是怎麼操做的?
中斷請求-中斷響應-斷點保護---執行中斷服務程序---斷點恢復---中斷返回
中斷:解決處理器速度和硬件速度不匹配,是多道程序設計的必要條件。每一箇中斷都有本身的數字標識,當中斷髮生時,指令計數器PC和處理機狀態字PSW中的內容自動壓入處理器堆棧,同時新的PC和PSW的中斷向量也裝入各自的寄存器中。這時,PC中包含的是該中斷的中斷處理程序的入口地址,它控制程序轉向相應的處理,當中斷處理程序執行完畢,該程序的最後一條iret(中斷返回),它控制着恢復調用程序的環境。 中斷和系統調用的區別: 中斷是由外設產生, 無心的, 被動的 系統調用是由應用程序請求操做系統提供服務產生, 有意的, 主動的。要從用戶態經過中斷進入內核態。(聯繫) 中斷過程:中斷請求 中斷響應 斷點保護 執行中斷服務程序 斷點恢復 中斷返回 系統調用過程:應用程序在用戶態執行時請求系統調用,中斷,從用戶態進入內核態,在內核態執行相應的內核代碼。
根據程序執行的互斥性和空間與時間局域性兩個特色,容許做業裝入時候只裝入一部分,另外一部分存放在磁盤上,調用時候將經常使用的放入內存,其餘暫時不用的放入外存中。這樣一個小的主存空間也能夠運行一個比它大的做業。經常使用的虛擬存儲技術有分頁分段存儲管理。
window:fat32.linux:ext2,fat32.
是一種將程序指令存儲器和數據存儲器合併在一塊兒的存儲器結構。
五個組成部分是:輸入輸出,計算單元,控制單元,存儲單元。
輸入數據和程序的輸入設備;
記憶程序和數據的存儲器;
完成數據加工處理的運算器;
控制程序執行的控制器;
輸出處理結果的輸出設備。
鏈接CPU和內存。
寄存器是暫時存儲的CPU組成部分,cache用來作高度CPU和低速的主存之間加速帶。
CISC(Complex Instruction Set Computer)複雜指令系統計算器,是一種執行較多類型計算機指令的微處理器。RISC(Reduced Instruction Set Computer)是精簡指令系統計算器,是一種執行較少類型計算機指令的微處理器。
將重複性的過程分爲若干個子過程來完成。
總線是指數據通訊的鏈接線,有地址,數據,控制指令。
I/O輸入/輸出(Input/Output),分爲IO設備和IO接口兩個部分.
I/O的方式有:DIO(Direct I/O),AIO(Asynchronous I/O,異步I/O),Memory-Mapped I/O(內存映射I/O)等,不一樣的I/O方式有不一樣的實現方式和性能,在不一樣的應用中能夠按狀況選擇不一樣的I/O方式。
DMA(Direct Memory Access,直接存儲器訪問) 是全部現代電腦的重要特點,它容許不一樣速度的硬件裝置互相溝通,而不須要依賴於 CPU 的大量中斷負載。不然,CPU 須要歷來源把每一片斷的資料複製到暫存器,而後把它們再次寫回到新的地方。在這個時間中,CPU 對於其餘的工做來講就沒法使用。
一次編譯處處運行,沒有指針,徹底對象化,面向對象(封裝、繼承、多態)。
JavaEE:Java Platform Enterprise Edition,是Sun公司爲企業級應用推出的標準平臺。
J2EE:Java 2 Platform,Enterprise Edition,是JavaEE之前的叫法。
JDBC:Java DataBase Connectivity,Java數據庫鏈接。
JNDI:Java Naming and Directory Interface,提供一個目錄系統,使得開發人員能夠經過名稱來訪問資源。
EJB:Enterprise JavaBean,用來構建一個能夠管理的服務器組件。
Servlet:Java編寫的服務端程序,能夠動態修改web內容。
JSP:Java Server Pages,Sun主導的一種動態網頁技術標準,JSP部署於網絡服務器上,能夠響應客戶端請求,並返回相應內容。
RMI:Remote Method Invocation,使得客戶端能夠像調用本地對象同樣調用遠程服務器上的方法。和RPC(Remote Procedure Call Protocol)不一樣,RMI只適用於Java,返回結果也有區別。RML在文件傳輸時,須要進行序列化serial,轉換爲二進制才能被servlet傳輸
XML:Extensible Markup Language,用於傳輸和存儲數據
JMS:Java Message Service,Java平臺面向消息中間件的一個服務,用於在分佈式系統或應用程序間傳遞服務。
JTA:Java Transaction API,事務管理組件。
Weblogic:Oracle公司推出的商業化JavaEE服務器
java把內存分爲堆棧空間存儲,在堆中new的空間不用本身收回,自動垃圾收回。
不一樣於C++須要編程人員手動釋放內存,Java有虛擬機,所以Java不須要程序員主動去釋放內存,而是經過虛擬機自身的垃圾回收器(Garbage Collector-GC)來進行對象的回收。Java語言因爲有虛擬機的存在,實現了平臺無關性,在任意平臺都是經過將代碼轉換爲字節碼文件,從而在平臺下的虛擬機中運行代碼的。
內存區域分佈
虛擬機棧:存放每一個方法執行時的棧幀,一個方法調用到完成就對應棧幀在虛擬機棧中入棧和出棧的過程。
本地方法棧:和虛擬機棧相似,不過是爲Java中native方法服務的。平時所說的「棧內存」指的就是虛擬機棧和本地方法棧的合稱。
程序計數器:當前線程執行字節碼的行號指示器,字節碼解釋器工做依賴於它。佔用較小的內存空間,不會出現OOM。
堆:即所謂的「堆內存」。JVM所管理最大的一塊內存,被全部線程共享。惟一做用就是給對象實例分配內存空間,在分代回收算法中的新生代老年代就在於堆中。
方法區(也稱爲永久代):不在堆中,被各個線程共享,存儲已被JVM加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。其中包括常量池。
另:直接內存,不屬於JVM內存區域,與NIO聯繫緊密,不受JVM內存大小限制。
## JVM垃圾回收機制
什麼時候進行垃圾回收?
GC本質上是一道守護進程(Daemon Thread),不停的檢測堆中是否有不可達對象並釋放內存,所以GC在什麼時候發生其實咱們是沒法預測的。GC經過調用對象的finalize()方法來摧毀對象。
不可達對象的斷定:根搜索算法。JVM中有一系列設定的GC Roots,當一個對象到任意一個GC Root都沒有引用鏈時,則說明此對象不可達。
一、標記-清除算法
最基礎的算法,GC會判斷堆中對象是否不可達,若是知足清理條件(查看該對象是否有必要執行finalize()方法,有無必要的標準是該對象有沒有被調用過finalize方法或該對象有沒有覆蓋finalize()方法,由於finalize()只能被調用一次),則給這個對象進行標記,將對象放在F-queue隊列。此時除非對象在finalize()方法中從新得到了引用,不然它就會被清除掉。
二、複製算法
將內存分爲大小相等的兩塊,當對象不可達後並非及時清理,而是等待正在使用的內存滿了以後,將該內存內還存活的對象總體複製到另外一塊內存中,複製結束後再清理掉原內存塊中的全部內容。這種方法的優勢是快速,但犧牲了一半的內存。方法的改進版(事實上也是虛擬機的作法)是隻在新生代空間使用複製算法,而且因爲新生代對象生命週期每每很短,所以又將新生代區域分爲Eden和Survivor空間。其中Eden分配的空間又比Survivor大出不少,從而節省內存空間。若是存活對象過多,使得Survivor區也滿,那麼就會轉移Survivor區對象到老年代。
三、標記-整理算法
標記過程與1同樣,將1中的清除過程換成了整理,即將內存中存活的對象歸攏到一邊,使得內存更「緊湊」一些,整理以後將邊界以外的對象清理掉。這種算法是爲了防止2算法中出現存活率100%的極端狀況,那麼複製就沒有止境了。
四、分代算法
新生代採用2算法,老年代採用1或3算法。這是由他們的特色決定的,新生代註定了其中不少對象生命週期轉瞬即逝,所以複製算法移動的存貨對象並非不少。而老年代存活率較高,只能採用一、3來執行,提升效率。
能夠調整堆內新生代老年代比例
能夠調整對象移入老年代的年齡
能夠調整堆內存大小
能夠設置每一個棧大小
能夠設置堆內分區大小
可選擇垃圾回收方式
雙親委派模型。
類加載器(ClassLoader)用來實現類的加載動做。JVM中只存在兩種不一樣的類加載器:啓動類加載器和其餘類加載器。
啓動類加載器:即Bootstrap ClassLoader。由C++編寫,在JVM內部。其餘類加載器都由Java編寫,在JVM外部,所有繼承於抽象類java.lang.ClassLoader。
類加載器之間的層次關係,稱爲雙親委派模型。
頂層爲啓動類加載器,下邊爲擴展類加載器,再下爲應用程序類加載器,其中包含多種自定義類加載器。
若是一個類加載器收到了加載類的請求,它首先不會本身去加載,而是委派給它的父加載器去執行。層層委派以後,到了頂層由啓動類加載器加載,只有當父加載器反饋沒法加載此請求,纔會讓子加載器去加載。這種結構使得Java類型體系中的加載機制清晰準確,不易形成混亂。
有一種雙親委派模型的異常狀況,即相似啓動類加載器這種基礎的類加載器,本應默認爲全部類適用的加載器,但因爲一些環境下調用SPI(Service Provider Interface),繞過雙親委派模型的層次結構使得父加載器委派子加載器去完成類加載動做。
還有一種狀況,即爲了實現模塊的動態性、熱部署,再也不使用雙親委派模型,而是使用更加複雜的網狀結構。OSGi技術便是類加載器網狀結構的一個最佳實踐。
能夠打印當前的內存快照,能夠看到快照中有deadLock對象,所在的方法,請求被鎖的資源,從而進一步分析死鎖緣由。
ThreadLocal,不少地方叫作線程本地變量,也有些地方叫作線程本地存儲,其實意思差很少。可能不少朋友都知道ThreadLocal爲變量在每一個線程中都建立了一個副本,那麼每一個線程能夠訪問本身內部的副本變量。示例:
class ConnectionManager { private static Connection connect = null; public static Connection openConnection() { if(connect == null){ connect = DriverManager.getConnection(); } return connect; } public static void closeConnection() { if(connect!=null) connect.close(); } }
假設有這樣一個數據庫連接管理類,這段代碼在單線程中使用是沒有任何問題的,可是若是在多線程中使用呢?很顯然,在多線程中使用會存在線程安全問題:第一,這裏面的2個方法都沒有進行同步,極可能在openConnection方法中會屢次建立connect;第二,因爲connect是共享變量,那麼必然在調用connect的地方須要使用到同步來保障線程安全,由於極可能一個線程在使用connect進行數據庫操做,而另一個線程調用closeConnection關閉連接。
最多見的ThreadLocal使用場景爲 用來解決數據庫鏈接、Session管理等。
c++是類,c中是基本類型函數。
封裝,繼承,多態。支持面向對象和麪向過程的開發。
拋出異常和捕捉異常進行處理。(實際開發)
c是純過程,c++是對象加過程,java是純面向對象的
被virtual修飾的成員函數,再基類不能實現,而他的實現放到派生類中實現。
內存泄漏(Memory Leak)是指程序中己動態分配的堆內存因爲某種緣由程序未釋放或沒法釋放,形成系統內存的浪費,致使程序運行速度減慢甚至系統崩潰等嚴重後果。
指針是一個存儲地址的變量,該地址爲內存的一個存儲單元;引用是原變量的一個別名;
指針能夠爲空,而引用不能爲空;
指針能夠有多級,而引用只能有一級;
指針能夠從新賦值,而引用只能初始化一次
sizeof引用獲得的是變量大小,而sizeof指針獲得的是指針自己大小
將引用做爲函數返回值的好處是?
在內存中不會產生被返回值的副本,同時不能返回局部變量的引用,由於隨着調用結束局部變量會被銷燬。
值傳遞
傳遞的是實參的一個拷貝,修改形參不會改變實參值。
地址傳遞
傳遞的是實參地址的一個拷貝,修改形參會改變實參值。
引用傳遞
傳遞的是實參的一個別名,修改形參會致使改變實參。
被調用函數的形參只有在被調用時纔會臨時分配存儲單元,一旦調用結束則釋放內存。
被const修飾符修飾的變量不能被修改。const x代表x數據是常量,不能修改;const x代表指針自己是常量,x的指針不能指向其餘內存地址,x自己可被修改;const x代表x自己數據和地址都不能被修改。
被static修飾符修飾的變量在整個文件中都是可見的,而在文件外是不可見的。該變量在全局數據區分配內存。C++中由程序運行new出的動態數據存放在堆區,而函數內部局部變量存放在棧區。
靜態局部變量:在函數內部定義static變量,第一次運行到這裏初始化,存儲到全局數據區,下一次執行到這裏不會再從新初始化。
static變量若是沒有顯式初始化,默認初始值爲0。
靜態函數不能被其餘函數所調用。
一、封裝:將客觀事物封裝成類,隱藏實現細節,模塊化代碼。
二、多態:實現多態的兩種方式——覆蓋(重寫)和重載。
覆蓋是子類從新定義父類的虛函數,與多態真正相關。當子類從新定義了父類的虛函數後,父類指針根據賦給它的不一樣的子類指針,動態的調用屬於子類的該函數,這樣的函數調用在編譯期間是沒法肯定的(調用的子類的虛函數的地址沒法給出)。所以,這樣的函數地址是在運行期綁定的(晚綁定)。
重載是存在多個同名函數,可是函數的參數個數不一樣。這些函數實際上成爲了避免同的函數,對它們的調用在編譯期間就已經肯定,屬於早綁定,與多態無關。
三、繼承:子類繼承父類功能,對父類功能進行擴展。
不是。不一樣類型間指針能夠強制互轉。
const修飾常量受到強制保護,程序更健壯,並且const修飾的常量有數據類型,有類型安全檢查。
爲了防止派生類析構函數未執行,形成資源泄露。
<>是標準頭文件,「」是非系統頭文件
爲了支持運算符的重載。更加方便。
聲明指針記得初始化,暫時不用就指向NULL;使用malloc分配內存,必須通過顯式釋放(free),避免內存泄漏。
有5層結構,分層處理。
一、應用層:應用層是TCP/IP協議的第一層,是直接爲應用進程提供服務的。
(1)對不一樣種類的應用程序它們會根據本身的須要來使用應用層的不一樣協議,郵件傳輸應用使用了SMTP協議、萬維網應用使用了HTTP協議、遠程登陸服務應用使用了有TELNET協議。 [1]
(2)應用層還能加密、解密、格式化數據。 [1]
(3)應用層能夠創建或解除與其餘節點的聯繫,這樣能夠充分節省網絡資源。
二、運輸層:解決的是計算機程序到計算機程序之間的通訊問題,即所謂的「端」到 「端」的通訊。引入傳輸層的緣由: 增長複用和分用的功能、 消除網絡層的不可靠性、 提供從源端主機到目的端主機的可靠的、與實際使用的網絡無關的信息傳輸。運輸層是ISO/OSI的第四層,處於通訊子網和資源子網之間,是整個協議層次中最核心的一層。做爲TCP/IP協議的第二層,運輸層在整個TCP/IP協議中起到了中流砥柱的做用。且在運輸層中,TCP和UDP也一樣起到了中流砥柱的做用。
三、網絡層:網絡層在TCP/IP協議中的位於第三層。在TCP/IP協議中網絡層能夠進行網絡鏈接的創建和終止以及IP地址的尋找等功能。
四、網絡接口層:網絡接口層實際上並非因特網協議組中的一部分,可是它是數據包從一個設備的網絡層傳輸到另一個設備的網絡層的方法。這個過程可以在網卡的軟件驅動程序中控制,也能夠在韌體或者專用芯片中控制。這將完成如添加報頭準備發送、經過物理媒介實際發送這樣一些數據鏈路功能。另外一端,鏈路層將完成數據幀接收、去除報頭而且將接收到的包傳到網絡層,在TCP/IP協議中,網絡接口層位於第四層。因爲網絡接口層兼併了物理層和數據鏈路層因此,網絡接口層既是傳輸數據的物理媒介,也能夠爲網絡層提供一條準確無誤的線路。
五、網際層:提供獨立於硬件的邏輯尋址,從而讓數據可以在具備不一樣物理結構的子網之間傳遞。提供路由功能來下降數據流量,支持Intemet 上的數據傳遞(互聯網絡是指多個局域網互相鏈接而造成的網絡,好比大公司裏的網絡或是Intemet)。
TCP是可靠的面向鏈接的傳輸控制協議,UDP是不可靠的無鏈接傳輸數據報文協議。
IP是網絡層,MAC是數據鏈路層且地址是全球惟一的。
ARRP(得到網關地址) - DNS(得到IP地址) - TCP
hub是集線器屬於物理層,交換機是數據鏈路層,router是路由器網絡層的,負責不一樣網絡結合。
在國際互聯網(Internet)上有成千百萬臺主機(host),爲了區分這些主機,人們給每臺主機都分配了一個專門的「地址」做爲標識,稱爲IP地址。子網掩碼的做用是用來區分網絡上的主機是否在同一網絡段內。子網掩碼不能單獨存在,它必須結合IP地址一塊兒使用。子網掩碼只有一個做用,就是將某個IP地址劃分紅網絡地址和主機地址兩部分。
IPV6更安全,更大的存儲空間。
跨平臺的標記語言,重在儲存數據。HTML重在存儲界面顯示內容
Opening System Interconnection - Reference Model
七層模型: 應用層▪ 表示層▪ 會話層▪ 傳輸層▪ 網絡層▪ 數據鏈路層
在課堂上常常是容易被忽略的。它看起來彷佛很簡單。可是,這一層的某些方面有時須要特別留意。物理層實際上就是佈線、光纖、網卡和其它用來把兩臺網絡通訊設備鏈接在一塊兒的東西。甚至一個信鴿也能夠被認爲是一個1層設備。網絡故障的排除常常涉及到1層問題。咱們不能忘記用五類線在整個一層樓進行鏈接的傳奇故事。因爲辦公室的椅子常常從電纜線上壓過,致使網絡鏈接出現斷斷續續的狀況。遺憾的是,這種故障是很常見的,並且排除這種故障須要耗費很長時間。
運行以太網等協議。請記住,咱們要使這個問題簡單一些。第2層中最重要的是你應該理解網橋是什麼。交換機能夠當作網橋,人們都這樣稱呼它。網橋都在2層工做,僅關注以太網上的MAC地址。若是你在談論有關MAC地址、交換機或者網卡和驅動程序,你就是在第2層的範疇。集線器屬於第1層的領域,由於它們只是電子設備,沒有2層的知識。第2層的相關問題在本網絡講座中有本身的一部分,所以先不詳細討論這個問題的細節。只須要知道第2層把數據幀轉換成二進制位供1層處理就能夠了。
在計算機網絡中進行通訊的兩個計算機之間可能會通過不少個數據鏈路,也可能還要通過不少通訊子網。網絡層的任務就是選擇合適的網間路由和交換結點, 確保數據及時傳送。網絡層將數據鏈路層提供的幀組成數據包,包中封裝有網絡層包頭,其中含有邏輯地址信息- -源站點和目的站點地址的網絡地址。
若是你在談論一個IP地址,那麼你是在處理第3層的問題,這是「數據包」問題,而不是第2層的「幀」。IP是第3層問題的一部分,此外還有一些路由協議和地址解析協議(ARP)。有關路由的一切事情都在第3層處理。地址解析和路由是3層的重要目的。
第4層的數據單元也稱做數據包(packets)。可是,當你談論TCP等具體的協議時又有特殊的叫法,TCP的數據單元稱爲段(segments)而UDP協議的數據單元稱爲「數據報(datagrams)」。這個層負責獲取所有信息,所以,它必須跟蹤數據單元碎片、亂序到達的數據包和其它在傳輸過程當中可能發生的危險。理解第4層的另外一種方法是,第4層提供端對端的通訊管理。像TCP等一些協議很是善於保證通訊的可靠性。有些協議並不在意一些數據包是否丟失,UDP協議就是一個主要例子。
這一層也能夠稱爲會晤層或對話層,在會話層及以上的高層次中,數據傳送的單位再也不另外命名,統稱爲報文。會話層不參與具體的傳輸,它提供包括訪問驗證和會話管理在內的創建和維護應用之間通訊的機制。如服務器驗證用戶登陸即是由會話層完成的。
這一層主要解決用戶信息的語法表示問題。它將欲交換的數據從適合於某一用戶的抽象語法,轉換爲適合於OSI系統內部使用的傳送語法。即提供格式化的表示和轉換數據服務。數據的壓縮和解壓縮, 加密和解密等工做都由表示層負責。
是專門用於應用程序的。應用層肯定進程之間通訊的性質以知足用戶須要以及提供網絡與用戶應用軟件之間的接口服務若是你的程序須要一種具體格式的數據,你能夠發明一些你但願可以把數據發送到目的地的格式,而且建立一個第7層協議。SMTP、DNS和FTP都是第7層協議。
應用層協議,使用UDP。分爲迭代查詢和遞歸查詢。採用分佈式集羣的工做方式,防止單點故障,增長通訊容量。
迭代:主機訪問本地域名服務器,若緩存沒有IP則本地域名服務器進一步向其餘根域名服務器查詢。
遞歸:主機分別向多個服務器發出查詢請求。
發送前無需鏈接,減小了開銷和時延,首部開銷小,無擁塞控制,方便實時應用,不保證可靠交付,無需維持鏈接狀態表。UDP的可靠性要經過應用層來控制。
字符填充法、字符計數法、比特填充法、違規編碼法。
RIP(Routing Information Protocol)路由信息協議。在應用層,最大站點數爲15
OSPF(Open Shortest Path First)網絡層,洪泛法,迪傑斯特拉算法
同一個函數重複用。
單元,集成,黑盒,白盒,灰盒,。
需求,設計,開發,測試。
系統流程建模工具
運用工程化的方法管理軟件開發。
繼承:類繼承另外一個類的功能
實現:類實現接口的功能
依賴:A類的某個方法使用到了B類
關聯:強依賴關係,B類做爲一個屬性出如今了A類
聚合:一種特別的關聯,公司與我的的關係
組合:強聚合關係,總體與部分的聯繫更緊密,如汽車與輪胎
問題定義
可行性研究
需求分析
整體設計
詳細設計
編碼和單元測試
綜合測試
軟件維護
黑盒測試:不考慮軟件內部原理,以用戶角度測試軟件輸入輸出
白盒測試:知道軟件內部工做過程,肯定每一個分支都能按照預約正常工做
灰盒測試:集合白盒黑盒
冒煙測試:測試軟件基本功能,快速
系統測試:驗證系統是否知足需求規格的黑盒類測試
性能測試:負載測試和壓力測試
安全測試:假扮黑客侵入系統
兼容性測試:不一樣平臺不一樣環境下的測試
自頂向下:從程序入口主控模塊開始,按照系統程序結構,沿着控制層次從上而下測試各模塊。方便把握總體結構,早期可發現頂層錯誤。
自底向上:從最底層模塊,即葉子結點開始,按照調用從下而上的測試各模塊。最後一個模塊提交後才能完整系統測試,某些模塊能夠提早測試。
方法、工具、過程。
一、瀑布模型:前一階段工做結束才能夠進行下一階段工做。基於文檔,易於維護,但加大了工做量。
二、快速原型:快速創建能夠運行的程序,完成的功能是最終軟件的一個子集。不帶反饋環,知足用戶真實需求,但會致使系統設計差,難以維護。
三、增量模型:每一個階段不交付完整產品,軟件由一系列增量構件組成。下降開發風險,易於維護,但不容易控制總體過程
四、螺旋模型:結合快速原型和瀑布模型,有利於軟件重用,減小風險,風險人員須要必定經驗。
五、噴泉模型:迭代,無縫,節省開發時間。
六、敏捷
永遠不會被執行到的代碼。
內聚:指一個好的內聚模塊內應當儘可能只作一件事,描述的是模塊內的功能聯繫。
耦合:各模塊之間相互鏈接的一種度量,耦合強弱取決於模塊間接口的複雜程度。
(1)內聚類型高→低:功能內聚、信息內聚、通訊內聚、過程內聚、時間內聚、邏輯內聚、偶然內聚
(2)耦合類型高→低:內容耦合、公共耦合、外部耦合、控制耦合、標記耦合、數據耦合、非直接耦合
順序結構是指內存連續的存儲單元進行存儲,而鏈式結構是指 內存不連續的結構,經過一個節點指向另一個節點的地址。
棧是先進後出的特殊線性表,隊列是先進先出的線性表。
複雜度包括時間複雜度和空間複雜度,用來評價一個算法的好壞。
頭節點是指向初始地址的一個節點,它自己數據段沒有內容,經過它能夠標識這個鏈表。
樹,二叉樹:有左右子樹的區分和度不超過2.
二叉排序樹:左子樹均小於根,根均小於右節點。。
線索二叉樹:設置兩個標識標記左右指針指向的是孩子仍是前軀節點。
平衡二叉樹:左右子樹高度差絕對值小於等於1。
哈夫曼樹:壓縮用的。權值大小排列。
徹底二叉樹:只能從右邊爲空。
二叉樹有左右子樹的定義。
孩子鏈存儲結構和雙親存儲結構。
先序中序後序三種。遞歸實現。
鄰接矩陣和鄰接表,是多對多的關係,分爲有向圖和無向圖。
直接查找和有序表的二分查找。
插入排序有直接插入和折半插入。都是在有序表裏插入進去的。
交換排序:冒泡,快速:以一個數字劃分兩個區域,而後分別對兩個區域繼續劃分,直到區間爲一。注意快排是不穩定。
選擇排序:簡單的選擇排序,堆排序
歸併排序:將兩個有序表歸併到一個有序表。將兩個有序表放到一塊兒進行各個比較,比較完以後放回原來數組內。
一個序列中,關鍵字相同的數排序後相對位置不變即穩定,好比一、三、二、四、五、2序列,第三個位置2和最後一個位置2排序後,他們的位置前後不變化則穩定。
進隊:入A棧。
出隊:若B棧不爲空,則B棧所有出棧;不然將A棧中數據所有入B棧,再依次出B棧。
兩個隊列模仿一個棧?
入棧:入A隊
出棧:將A隊除隊尾元素所有轉移到B隊,出A隊,算法思想就是兩個隊列倒來倒去,只留一個元素時出棧。
設置快慢指針,快指針每次前進兩步,當兩指針重合則有環,快指針爲null則無環。
一、將遍歷過的結點都入set,若是當前結點在set裏有,則此結點即爲入口。
二、快慢指針重合後,重置fast指針,此時fast每次走一步,再次重合結點即爲入口。
DP。由最長公共子序列問題的最優子結構性質可知,要找出X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的最長公共子序列,可按如下方式遞歸地進行:當xm=yn時,找出Xm-1和Yn-1的最長公共子序列,而後在其尾部加上xm(=yn)便可得X和Y的一個最長公共子序列。當xm≠yn時,必須解兩個子問題,即找出Xm-1和Y的一個最長公共子序列及X和Yn-1的一個最長公共子序列。這兩個公共子序列中較長者即爲X和Y的一個最長公共子序列。
能夠。先將鏈表排序,將各個結點的值記入數組,再二分查找。
給定一顆二叉樹的頭結點,和這顆二叉樹中2個節點n1和n2,求這兩個節點的最近公共祖先
後序遍歷方法
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if(left != null && right != null) return root; return left != null ? left : right; }
}
左括號入棧,右括號出棧進行匹配,棧空仍未匹配到則失敗。
被刪除的節點是葉子節點,這時候只要把這個節點刪除,再把指向這個節點的父節點指針置爲空就行。
被刪除的節點有左子樹,或者有右子樹,並且只有其中一個,那麼只要把當前刪除節點的父節點指向被刪除節點的左子樹或者右子樹就行。
被刪除的節點既有左子樹並且又有右子樹,這時候須要把左子樹的最右邊的節點或者右子樹最左邊的節點提到被刪除節點的位置。
O(1)和O(n),n爲表長。
兩次DFS,第一次找出距離root最遠點,第二次以第一次結果爲起點找出第二個點,這兩點的距離即爲直徑。
例:單例模式是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。
這種模式涉及到一個單一的類,該類負責建立本身的對象,同時確保只有單個對象被建立。這個類提供了一種訪問其惟一的對象的方式,能夠直接訪問,不須要實例化該類的對象。
抽象工廠模式是圍繞一個超級工廠建立其餘工廠。該超級工廠又稱爲其餘工廠的工廠。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。
在抽象工廠模式中,接口是負責建立一個相關對象的工廠,不須要顯式指定它們的類。每一個生成的工廠都能按照工廠模式提供對象。
建造者模式建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個複雜的對象。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。一個 Builder 類會一步一步構造最終的對象。該 Builder 類是獨立於其餘對象的。
工廠模式是 Java 中最經常使用的設計模式之一。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。
在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用一個共同的接口來指向新建立的對象。
原型模式
是用於建立重複的對象,同時又能保證性能。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。
這種模式是實現了一個原型接口,該接口用於建立當前對象的克隆。當直接建立對象的代價比較大時,則採用這種模式。例如,一個對象須要在一個高代價的數據庫操做以後被建立。咱們能夠緩存該對象,在下一個請求時返回它的克隆,在須要的時候更新數據庫,以此來減小數據庫調用。
。
例:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
例:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式、訪問者模式。
一、開閉原則(Open Close Principle)
開閉原則的意思是:對擴展開放,對修改關閉。在程序須要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。簡言之,是爲了使程序的擴展性好,易於維護和升級。想要達到這樣的效果,咱們須要使用接口和抽象類,後面的具體設計中咱們會提到這點。
二、里氏代換原則(Liskov Substitution Principle)
里氏代換原則是面向對象設計的基本原則之一。 里氏代換原則中說,任何基類能夠出現的地方,子類必定能夠出現。LSP 是繼承複用的基石,只有當派生類能夠替換掉基類,且軟件單位的功能不受到影響時,基類才能真正被複用,而派生類也可以在基類的基礎上增長新的行爲。里氏代換原則是對開閉原則的補充。實現開閉原則的關鍵步驟就是抽象化,而基類與子類的繼承關係就是抽象化的具體實現,因此里氏代換原則是對實現抽象化的具體步驟的規範。
三、依賴倒轉原則(Dependence Inversion Principle)
這個原則是開閉原則的基礎,具體內容:針對接口編程,依賴於抽象而不依賴於具體。
四、接口隔離原則(Interface Segregation Principle)
這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。它還有另一個意思是:下降類之間的耦合度。因而可知,其實設計模式就是從大型軟件架構出發、便於升級和維護的軟件設計思想,它強調下降依賴,下降耦合。
五、迪米特法則,又稱最少知道原則(Demeter Principle)
最少知道原則是指:一個實體應當儘可能少地與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。
六、合成複用原則(Composite Reuse Principle)
合成複用原則是指:儘可能使用合成/聚合的方式,而不是使用繼承。
改造關係模式,經過分解關係模型來消除其中不合適的數據依賴,以決絕插入異常,刪除異常,數據用餘。
相似查詢一次的命令,要求所有執行完。
原子性,一致性,隔離性,持久性。
數據庫結構化,共享性好,獨立性。有界面接口。
關係模型,層次模型,網狀模型
恰當把握,多的話佔空間,少的話查詢不足,速度達不到。
原子性Atomicity:一個事務被視爲一個最小單元,要麼所有提交,要麼所有回滾
一致性Consistency:事務老是由一種狀態轉換爲另外一種狀態,數據庫事務只會是執行前的狀態或是執行後的狀態,不會出現執行中的狀態。即若是一個事務執行了十秒,那麼第一秒讀到的結果和第九秒獲得的應該是相同的。
隔離性Isolation:一個事務的執行不會被另外一個事務影響,互不干擾。
持久性Durability:事務只要提交了,那麼數據庫中的數據也永久的發生了變化。
1NF(Normal Form):R的全部屬性都不能再分解爲更基本的數據單位。
2NF:R的全部非主屬性都依賴於R的關鍵屬性,全部列都依賴於任意一組候選關鍵字。
3NF:每一列都與任意候選關鍵字直接相關而不是間接相關,沒有傳遞依賴。
BCNF:3NF基礎上,關係R只有一個單屬性,或R的子集都是單屬性,則R知足BCNF。
100數量級小,能夠隨意插入;100萬數量級大,若是表裏有索引,則索引更新代價很高,能夠採起先刪除索引再插入,插入完成後再建索引的策略。
能夠。大小受到主機內存的制約。數據量大時要先刪索引。減小提交次數,即減小IO次數。
表分區,備份,入帶庫。
WHERE 子句用來篩選 FROM 子句中指定的操做所產生的行。
GROUP BY 子句用來分組 WHERE 子句的輸出。
HAVING 子句用來從分組的結果中篩選行。
在查詢過程當中聚合語句(sum,min,max,avg,count)要比having子句優先執行.而where子句在查詢過程當中執行優先級別優先於聚合語句(sum,min,max,avg,count)。
產生死鎖的緣由主要是:
(1) 由於系統資源不足。
(2) 進程運行推動的順序不合適。
(3) 資源分配不當等。
產生死鎖的四個必要條件:
(1)互斥條件:一個資源每次只能被一個進程使用。
(2)請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
(3)不可剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
(4)循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
死鎖的預防是經過破壞產生條件來阻止死鎖的產生,但這種方法破壞了系統的並行性和併發性。
死鎖產生的前三個條件是死鎖產生的必要條件,也就是說要產生死鎖必須具有的條件,而不是存在這3個條件就必定產生死鎖,那麼只要在邏輯上回避了第四個條件就能夠避免死鎖。
避免死鎖採用的是容許前三個條件存在,但經過合理的資源分配算法來確保永遠不會造成環形等待的封閉進程鏈,從而避免死鎖。該方法支持多個進程的並行執行,爲了不死鎖,系統動態的肯定是否分配一個資源給請求的進程。
預防死鎖:具體的作法是破壞產生死鎖的四個必要條件之一。
銀行家算法:該算法須要檢查申請者對各種資源的最大需求量,若是現存的各種資源能夠知足當前它對各種資源的最大需求量時,就知足當前的申請。換言之,僅當申請者能夠在必定時間內無條件歸還它所申請的所有資源時,才能把資源分配給它。這樣申請者就能夠很快完成其計算,而後釋放它佔用的資源,從而保證了系統中的全部進程都能完成,因此能夠避免死鎖的發生。這種算法的主要問題是,要求每一個進程必須先知道資源的最大需求量,並且在系統的運行過程當中,考察每一個進程對各種資源的申請需花費較多的時間。另外,這一算法自己也有些保守,由於它老是考慮最壞可能的狀況。
一、什麼是Redis?簡述它的優缺點?
Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個數據庫通通加載在內存當中進行操做,按期經過異步操做把數據庫數據flush到硬盤上進行保存。
由於是純內存操做,Redis的性能很是出色,每秒能夠處理超過 10萬次讀寫操做,是已知性能最快的Key-Value DB。
Redis的出色之處不只僅是性能,Redis最大的魅力是支持保存多種數據結構,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數據,所以Redis能夠用來實現不少有用的功能。
比方說用他的List來作FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set能夠作高性能的tag系統等等。
另外Redis也能夠對存入的Key-Value設置expire時間,所以也能夠被看成一 個功能增強版的memcached來用。 Redis的主要缺點是數據庫容量受到物理內存的限制,不能用做海量數據的高性能讀寫,所以Redis適合的場景主要侷限在較小數據量的高性能操做和運算上。
二、Redis相比memcached是一套分佈式的高速緩存系統,有哪些優點?
(1) memcached全部的值均是簡單的字符串,redis做爲其替代者,支持更爲豐富的數據類型
(2) redis的速度比memcached快不少
(3) redis能夠持久化其數據
三、Redis支持哪幾種數據類型?
String、List、Set、Sorted Set、hashes
四、Redis主要消耗什麼物理資源?
內存。
五、Redis的全稱是什麼?
Remote Dictionary Server。
六、Redis有哪幾種數據淘汰策略?
6中淘汰策略。
noeviction:返回錯誤當內存限制達到而且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過時集合的鍵,使得新添加的數據有空間存放。
allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過時集合的鍵。
volatile-ttl: 回收在過時集合的鍵,而且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。
七、Redis官方爲何不提供Windows版本?
由於目前Linux版本已經至關穩定,並且用戶量很大,無需開發windows版本,反而會帶來兼容性等問題。
八、一個字符串類型的值能存儲最大容量是多少?
512M
九、爲何Redis須要把全部數據放到內存中?
Redis爲了達到最快的讀寫速度將數據都讀到內存中,並經過異步的方式將數據寫入磁盤。
因此redis具備快速和數據持久化的特徵。若是不將數據放在內存中,磁盤I/O速度爲嚴重影響redis的性能。
在內存愈來愈便宜的今天,redis將會愈來愈受歡迎。 若是設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。
十、Redis集羣方案應該怎麼作?都有哪些方案?
1.codis。
目前用的最多的集羣方案,基本和twemproxy一致的效果,但它支持在 節點數量改變狀況下,舊節點數據可恢復到新hash節點。
2.redis cluster3.0自帶的集羣,特色在於他的分佈式算法不是一致性hash,而是hash槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
4.在業務代碼層實現,起幾個毫無關聯的redis實例,在代碼層,對key 進行hash計算,而後去對應的redis實例操做數據。 這種方式對hash層代碼要求比較高,考慮部分包括,節點失效後的替代算法方案,數據震盪後的自動腳本恢復,實例的監控,等等。
十一、Redis集羣方案什麼狀況下會致使整個集羣不可用?
有A,B,C三個節點的集羣,在沒有複製模型的狀況下,若是節點B失敗了,那麼整個集羣就會覺得缺乏5501-11000這個範圍的槽而不可用。
十二、MySQL裏有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據?
redis內存數據集大小上升到必定大小的時候,就會施行數據淘汰策略。
1三、Redis有哪些適合的場景?
(1)會話緩存(Session Cache)
最經常使用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其餘存儲(如Memcached)的優點在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,若是用戶的購物車信息所有丟失,大部分人都會不高興的,如今,他們還會這樣嗎?
幸運的是,隨着 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩存會話的文檔。甚至廣爲人知的商業平臺Magento也提供Redis的插件。
(2)全頁緩存(FPC)
除基本的會話token以外,Redis還提供很簡便的FPC平臺。回到一致性問題,即便重啓了Redis實例,由於有磁盤的持久化,用戶也不會看到頁面加載速度的降低,這是一個極大改進,相似PHP本地FPC。
再次以Magento爲例,Magento提供一個插件來使用Redis做爲全頁緩存後端。
此外,對WordPress的用戶來講,Pantheon有一個很是好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。
(3)隊列
Reids在內存存儲引擎領域的一大優勢是提供 list 和 set 操做,這使得Redis能做爲一個很好的消息隊列平臺來使用。Redis做爲隊列使用的操做,就相似於本地程序語言(如Python)對 list 的 push/pop 操做。
若是你快速的在Google中搜索「Redis queues」,你立刻就能找到大量的開源項目,這些項目的目的就是利用Redis建立很是好的後端工具,以知足各類隊列需求。例如,Celery有一個後臺就是使用Redis做爲broker,你能夠從這裏去查看。
(4)排行榜/計數器
Redis在內存中對數字進行遞增或遞減的操做實現的很是好。集合(Set)和有序集合(Sorted Set)也使得咱們在執行這些操做的時候變的很是簡單,Redis只是正好提供了這兩種數據結構。
因此,咱們要從排序集合中獲取到排名最靠前的10個用戶–咱們稱之爲「user_scores」,咱們只須要像下面同樣執行便可:
固然,這是假定你是根據你用戶的分數作遞增的排序。若是你想返回用戶及用戶的分數,你須要這樣執行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你能夠在這裏看到。
(5)發佈/訂閱
最後(但確定不是最不重要的)是Redis的發佈/訂閱功能。發佈/訂閱的使用場景確實很是多。我已看見人們在社交網絡鏈接中使用,還可做爲基於發佈/訂閱的腳本觸發器,甚至用Redis的發佈/訂閱功能來創建聊天系統!
1四、Redis支持的Java客戶端都有哪些?官方推薦用哪一個?
Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
1五、Redis和Redisson有什麼關係?
Redisson是一個高級的分佈式協調Redis客服端,能幫助用戶在分佈式環境中輕鬆實現一些Java的對象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。
1六、Jedis與Redisson對比有什麼優缺點?
Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持;
Redisson實現了分佈式和可擴展的Java數據結構,和Jedis相比,功能較爲簡單,不支持字符串操做,不支持排序、事務、管道、分區等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者可以將精力更集中地放在處理業務邏輯上。
1七、Redis如何設置密碼及驗證密碼?
設置密碼:config set requirepass 123456
受權密碼:auth 123456
1八、說說Redis哈希槽的概念?
Redis集羣沒有使用一致性hash,而是引入了哈希槽的概念,Redis集羣有16384個哈希槽,每一個key經過CRC16校驗後對16384取模來決定放置哪一個槽,集羣的每一個節點負責一部分hash槽。
1九、Redis集羣的主從複製模型是怎樣的?
爲了使在部分節點失敗或者大部分節點沒法通訊的狀況下集羣仍然可用,因此集羣使用了主從複製模型,每一個節點都會有N-1個複製品.
20、Redis集羣會有寫操做丟失嗎?爲何?
Redis並不能保證數據的強一致性,這意味這在實際中集羣在特定的條件下可能會丟失寫操做。
2一、Redis集羣之間是如何複製的?
異步複製
2二、Redis集羣最大節點個數是多少?
16384個。
2三、Redis集羣如何選擇數據庫?
Redis集羣目前沒法作數據庫選擇,默認在0數據庫。
2四、怎麼測試Redis的連通性?
ping
2五、Redis中的管道有什麼用?
一次請求/響應服務器能實現處理新的請求即便舊的請求還未被響應。這樣就能夠將多個命令發送到服務器,而不用等待回覆,最後在一個步驟中讀取該答覆。
這就是管道(pipelining),是一種幾十年來普遍使用的技術。例如許多POP3協議已經實現支持這個功能,大大加快了從服務器下載新郵件的過程。
2六、怎麼理解Redis事務?
事務是一個單獨的隔離操做:事務中的全部命令都會序列化、按順序地執行。事務在執行的過程當中,不會被其餘客戶端發送來的命令請求所打斷。
事務是一個原子操做:事務中的命令要麼所有被執行,要麼所有都不執行。
2七、Redis事務相關的命令有哪幾個?
MULTI、EXEC、DISCARD、WATCH
2八、Redis key的過時時間和永久有效分別怎麼設置?
EXPIRE和PERSIST命令。
2九、Redis如何作內存優化?
儘量使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用的內存很是小,因此你應該儘量的將你的數據模型抽象到一個散列表裏面。
好比你的web系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的全部信息存儲到一張散列表裏面。
30、Redis回收進程如何工做的?
一個客戶端運行了新的命令,添加了新的數據。
Redi檢查內存使用狀況,若是大於maxmemory的限制, 則根據設定好的策略進行回收。
一個新的命令被執行,等等。
因此咱們不斷地穿越內存限制的邊界,經過不斷達到邊界而後不斷地回收回到邊界如下。
若是一個命令的結果致使大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
redis分佈式鎖?
setnx(set if not exist)和expire、delete聯合實現(假設各個客戶端時鐘大體相同,偏差處於可接受範圍)釋放鎖的操做用lua腳本實現來保證原子性。在集羣環境下分佈式鎖的key值應當是隨機的不可重複的,不然若是一個客戶端得到了鎖,但發生了阻塞,當鎖過時redis自動釋放了資源,這時第二個客戶端得到了鎖,客戶端1此時從阻塞中恢復釋放了鎖,就會形成混亂。
爲何Redis是單線程的
單線程指的是網絡請求模塊使用了一個線程(因此不需考慮併發安全性),即一個線程處理全部網絡請求,其餘模塊仍用了多個線程(epoll模型)。
由於Redis是基於內存的操做,CPU不是Redis的瓶頸,Redis的瓶頸最有多是機器內存的大小或者網絡帶寬。既然單線程容易實現,並且CPU不會成爲瓶頸,那就瓜熟蒂落地採用單線程的方案了。
Redis爲何這麼快
一、徹底基於內存,絕大部分請求是純粹的內存操做,很是快速。數據存在內存中,相似於HashMap,HashMap的優點就是查找和操做的時間複雜度都是O(1);
二、數據結構簡單,對數據操做也簡單,Redis中的數據結構是專門進行設計的;
三、採用單線程,避免了沒必要要的上下文切換和競爭條件,也不存在多進程或者多線程致使的切換而消耗 CPU,不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗;
四、使用多路I/O複用模型,非阻塞IO;
五、使用底層模型不一樣,它們之間底層實現方式以及與客戶端之間通訊的應用協議不同,Redis直接本身構建了VM 機制 ,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求;
(1)多路 I/O 複用模型
多路I/O複用模型是利用 select、poll、epoll 能夠同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前線程阻塞掉,當有一個或多個流有 I/O 事件時,就從阻塞態中喚醒,因而程序就會輪詢一遍全部的流(epoll 是隻輪詢那些真正發出了事件的流),而且只依次順序的處理就緒的流,這種作法就避免了大量的無用操做。
這裏「多路」指的是多個網絡鏈接,「複用」指的是複用同一個線程。採用多路 I/O 複用技術可讓單個線程高效的處理多個鏈接請求(儘可能減小網絡 IO 的時間消耗),且 Redis 在內存中操做數據的速度很是快,也就是說內存內的操做不會成爲影響Redis性能的瓶頸,主要由以上幾點造就了 Redis 具備很高的吞吐量。
緩存雪崩、緩存穿透、緩存熱點?
1、緩存穿透預防及優化
緩存穿透是指查詢一個根本不存在的數據,緩存層和存儲層都不會命中,可是出於容錯的考慮,若是從存儲層查不到數據則不寫入緩存層,如圖 11-3 所示整個過程分爲以下 3 步:
緩存穿透將致使不存在的數據每次請求都要到存儲層去查詢,失去了緩存保護後端存儲的意義。 緩存穿透問題可能會使後端存儲負載加大,因爲不少後端存儲不具有高併發性,甚至可能形成後端存儲宕掉。一般能夠在程序中分別統計總調用數、緩存層命中數、存儲層命中數,若是發現大量存儲層空命中,可能就是出現了緩存穿透問題。
形成緩存穿透的基本有兩個。第一,業務自身代碼或者數據出現問題,第二,一些惡意攻擊、爬蟲等形成大量空命中,下面咱們來看一下如何解決緩存穿透問題。
2、緩存穿透的解決方法
1)緩存空對象
以下圖所示,當第 2 步存儲層不命中後,仍然將空對象保留到緩存層中,以後再訪問這個數據將會從緩存中獲取,保護了後端數據源。
緩存空對象會有兩個問題:
第一,空值作了緩存,意味着緩存層中存了更多的鍵,須要更多的內存空間 ( 若是是攻擊,問題更嚴重 ),比較有效的方法是針對這類數據設置一個較短的過時時間,讓其自動剔除。
第二,緩存層和存儲層的數據會有一段時間窗口的不一致,可能會對業務有必定影響。例如過時時間設置爲 5 分鐘,若是此時存儲層添加了這個數據,那此段時間就會出現緩存層和存儲層數據的不一致,此時能夠利用消息系統或者其餘方式清除掉緩存層中的空對象。
下面給出了緩存空對象的實現僞代碼:
2)布隆過濾器攔截
以下圖所示,在訪問緩存層和存儲層以前,將存在的 key 用布隆過濾器提早保存起來,作第一層攔截。
例如: 一個個性化推薦系統有 4 億個用戶 ID,每一個小時算法工程師會根據每一個用戶以前歷史行爲作出來的個性化放到存儲層中,可是最新的用戶因爲沒有歷史行爲,就會發生緩存穿透的行爲,爲此能夠將全部有個性化推薦數據的用戶作成布隆過濾器。若是布隆過濾器認爲該用戶 ID 不存在,那麼就不會訪問存儲層,在必定程度保護了存儲層。
開發提示:
有關布隆過濾器的相關知識,能夠參考: Bloom Filter(布隆過濾器)的概念和原理
能夠利用 Redis 的 Bitmaps 實現布隆過濾器,GitHub 上已經開源了相似的方案,讀者能夠進行參考:
https://github.com/erikdubbel...
使用布隆過濾器應對穿透問題
這種方法適用於數據命中不高,數據相對固定實時性低(一般是數據集較大)的應用場景,代碼維護較爲複雜,可是緩存空間佔用少。
兩種方案對比
前面介紹了緩存穿透問題的兩種解決方法 ( 實際上這個問題是一個開放問題,有不少解決方法 ),下面經過下表從適用場景和維護成本兩個方面對兩種方案進行分析。
緩存空對象和布隆過濾器方案對比
3、緩存雪崩問題優化
從下圖能夠很清晰出什麼是緩存雪崩:因爲緩存層承載着大量請求,有效的保護了存儲層,可是若是緩存層因爲某些緣由總體不能提供服務,因而全部的請求都會達到存儲層,存儲層的調用量會暴增,形成存儲層也會掛掉的狀況。緩存雪崩的英文原意是 stampeding herd(奔逃的野牛),指的是緩層宕掉後,流量會像奔逃的野牛同樣,打向後端存儲。
預防和解決緩存雪崩問題,能夠從如下三個方面進行着手。
1)保證緩存層服務高可用性。
和飛機都有多個引擎同樣,若是緩存層設計成高可用的,即便個別節點、個別機器、甚至是機房宕掉,依然能夠提供服務,例如前面介紹過的 Redis Sentinel 和 Redis Cluster 都實現了高可用。
2)依賴隔離組件爲後端限流並降級。
不管是緩存層仍是存儲層都會有出錯的機率,能夠將它們視同爲資源。做爲併發量較大的系統,假若有一個資源不可用,可能會形成線程所有 hang 在這個資源上,形成整個系統不可用。降級在高併發系統中是很是正常的:好比推薦服務中,若是個性化推薦服務不可用,能夠降級補充熱點數據,不至於形成前端頁面是開天窗。
在實際項目中,咱們須要制定以下目標:
雲計算是一種按使用量付費的模式,這種模式提供可用的、便捷的、按需的網絡訪問, 進入可配置的計算資源共享池,這些資源可以被快速提供,只需投入不多的管理工做,或與服務供應商進行不多的交互。基礎設施、安裝配置好開發環境、應用服務爲雲計算三個層面。
1.Volume:數據量巨大
體量大是大數據區分於傳統數據最顯著的特徵。通常關係型數據庫處理的數據量在TB級,大數據所處理的數據量一般在PB級以上。
2.Variety:數據類型多
大數據所處理的計算機數據類型早已不是單一的文本形式或者結構化數據庫中的表,它包括訂單、日誌、BLOG、微博、音頻、視頻等各類複雜結構的數據。
3.Velocity:數據流動快
速度是大數據區分於傳統數據的重要特徵。在海量數據面前,須要實時分析獲取須要的信息,處理數據的效率就是組織的生命。
4.Value:數據潛在價值大
在研究和技術開發領域,上述三個特徵已經足夠表徵大數據的特色。但在商業應用領域,第四個特徵就顯得很是關鍵!投入如此巨大的研究和技術開發的努力,就是由於你們
都洞察到了大數據的潛在巨大價值。如何經過強大的機器學習和高級分析更迅速地完成數據的價值「提純」,挖掘出大數據的潛在價值,這是目前大數據應用背景下苛待解決的難題。
沒有成熟的方法採集和處理大數據。
數據涉及到隱私,法律法規尚未完善。
大量不一樣類別的數據不知道怎麼存儲。
數據的獨佔性:有價值的數據別人不必定會分享。
人工智能
算力和數據是核心,以及神經網絡、遺傳算法、深度學習。
區塊鏈:blockchain
存儲數據的一個個塊,經過鏈char256算法將塊連接起來。
KNN算法的優勢:
一、思想簡單,理論成熟,既能夠用來作分類也能夠用來作迴歸;
二、可用於非線性分類;
三、訓練時間複雜度爲O(n);
四、準確度高,對數據沒有假設,對outlier不敏感;
缺點:
一、計算量大;
二、樣本不平衡問題(即有些類別的樣本數量不少,而其它樣本的數量不多);
三、須要大量的內存;
其僞代碼以下:
Windows 可以流行起來,很大一個緣由是它有友好的用戶圖形界面,操做方便簡單,容易上手。在Windows環境下打開一個程序,只要雙擊軟件的圖標就好了,那麼它是如何啓動起來的?
當咱們啓動電腦進入桌面時,系統會建立 Explorer.exe 進程。Explorer.exe是Windows程序管理器 或者叫 文件資源管理器,用於管理Windows圖形殼,刪除該程序會致使 Windows 圖形界面沒法使用。因此,若是有時候咱們電腦的桌面空白了,或者藍屏,能夠經過 Alt+Ctrl+delete(或者在dos中輸入 taskmgr 命令) 打開任務管理器, 點擊「文件」-> 「新建任務」,輸入 "explorer.exe",就能夠找回咱們的桌面了。
當雙擊某個圖標時,Explorer.exe進程的一個線程會偵測到這個操做,它根據註冊表中的信息取得文件名,而後Explorer.exe 以這個文件名調用 CreateProcess 函數。註冊表中有相關的項保存着雙擊操做的信息,如 exe 文件關聯、啓動 exe 的 Shell 是哪一個。PC中的大多其它的進程都是 Explorer.exe 的子進程,由於它們都是由Explorer.exe 進程建立的。
(1)CreateProcess 其實是經過 NtCreateProcess 函數實現的, 此時,系統會建立一個進程內核對象。進程內核對象能夠看做是操做系統用來管理進程的小的數據結構,它是在內核堆區分配的一個結構體,是系統用來存放關於進程統計信息的地方。進程內核對象維護了一個句柄表的結構,當進程被初始化以後,其句柄表是空的。當進程內的一個線程經過指定的函數建立了一個內核對象時,內核會爲對象分配一塊內存區域並初始化這塊區域,而後內核會在進程的句柄表中查找一個空的入口,找到以後會初始化句柄表的以索引定位的區域。初始化的主要過程就是填充句柄表的一個單元,包括指定內核對象地址,指定訪問碼,指定標記等。
(2)進程內核對象建立後,它的引用計數被置爲1。而後系統爲剛剛建立的進程分配的進程虛擬地址空間。要注意了,之因此稱爲虛擬地址空間,就是由於這塊地址空間並不在內存之中,它只是在硬盤上劃分的被稱爲「頁」的文件。每一個進程都有本身的虛擬地址空間,在進程初始化的時候,其全部的程序和數據會被加載到這個地址空間中。等到真正運行的時候,系統爲每一個進程配置的頁表會把虛擬地址映射爲真正的物理地址(這個過程,我會在後面的博客中詳細介紹如何映射)。
(3)初始化虛擬地址空間。進程地址空間建立後,Windows的裝載器(loader,也稱爲PE裝載器)開始工做,Loader會讀取EXE文件的信息(PE文件)。此時 loader 會檢查PE文件的有效性,若是PE文件有錯誤,進程也就沒法啓動了。若是PE文件沒有錯誤,裝載器就把PE文件的內容(二進制代碼)映射到進程的地址空間中,而後讀取 PE文件的導入地址表(Import Table),這裏存放有exe文件須要導入的模塊文件(DLL),系統會一一加載這些DLL到進程的地址空間中,具體作法是調用 LoadLibrary 函數加載程序代碼到某個地址,而後系統會映射這些代碼到進程的地址空間中,要知道DLL只需加載一次就可映射到全部進程的地址空間(映射過程我會在後面詳細闡述)中,併爲每一個DLL維護一個引用計數,當引用計數爲 0 時,DLL就從內存中卸載,釋放佔用的內存。DLL裏面可能又引用了其它的DLL,所以加載DLL時是遞歸形式的,直到加載完Import Table 裏描述的全部DLL模塊,此時進程初始化部分完成。
(4)建立進程的主線程。當進程的初始化完成後,開始建立進程的主線程,一個進程至少要有一個主線程才能運行,能夠說進程只是充當一個容器的做用,而線程纔是執行代碼的載體。線程是用 CreateThread 這個函數建立的。建立線程時,也和進程類似,系統會建立線程內核對象,初始化線程堆棧。線程堆棧有兩個,一個是核心堆棧,由核心態維護;另外一個是用戶堆棧,運行在用戶態下。一樣的,線程的引用計數也置爲1。
(5)C/C++運行期庫初始化。當進程的主線程初始化完成後,而且線程獲得了CPU時間片,CPU把CS:IP指向程序入口(OEP),這個地址至關重要,由於這是程序運行時第一條指令所在的地址(咱們能夠使用一些PE輔助工具來查看PE文件的地址信息,注意真實地址==偏移地址 + 基址)。其實,CS:IP指向的地址處是一條JMP指令,它跳轉到程序真正的入口函數,入口函數有如下4種形式:
···
mainCRTStartup (用於 ANSI 版本的控制檯應用程序 )
wmainCRTStartup ( 用於 Unicode 版本的控制檯應用程序 )
WinMainCRTStartup ( 用於 ANSI 版本的窗口應用程序 )
wWinMainCRTStartup ( 用於 Unicode 版本的窗口應用程序)
·
信息是個很抽象的概念。人們經常說信息不少,或者信息較少,但卻很難說清楚信息到底有多少。好比一本五十萬字的中文書到底有多少信息量。直到1948年,香農提出了「信息熵」的概念,才解決了對信息的量化度量問題。
公式爲:H(x)=E[I(xi)]=E[ log(2,1/p(xi)) ]=-∑p(xi)log(2,p(xi)) (i=1,2,..n)該值越大表示信息量越大
在一個系統中,該系統越混亂,那麼就越難把它搞清楚,須要的信息量就越大,信息熵就越大,回到數據挖掘中用決策樹進行分類中,在分類的以前,咱們須要創建一個決策樹,在創建決策樹的時候屬性的選擇是一個很是關鍵的問題,咱們選擇的屬性的標準是讓劃分儘可能純(落在給定劃分中的元祖都屬於相同類的越多,那麼就越純),結合上面咱們能夠推理出若是按照某個屬性劃分後,每一個該屬性屬性值所對應的元組越統一(元組所屬的類別越統一),那麼咱們這個屬性的選擇就越符合咱們的需求。和信息熵結合,就是選擇該屬性以後,全部屬性值對應的分類的信息熵之和越小,那麼咱們元組分類所須要的平均信息越少,該屬性就越符合咱們的要求
決策樹模型是一類算法的集合,在數據挖掘十大算法中,具體的決策樹算法佔有兩席位置,即C4.5和CART算法,本文都會介紹到它們。決策樹基礎決策樹是一種用於對實例進行分類的樹形結構。決策樹由節點(node)和有向邊(directed edge)組成。節點的類型有兩種:內部節點和葉子節點。其中,內部節點表示一個特徵或屬性的測試條件(用於分開具備不一樣特性的記錄),葉子節點表示一個分類。一旦咱們構造了一個決策樹模型,以它爲基礎來進行分類將是很是容易的。具體作法是,從根節點開始,地實例的某一特徵進行測試,根據測試結構將實例分配到其子節點(也就是選擇適當的分支);沿着該分支可能達到葉子節點或者到達另外一個內部節點時,那麼就使用新的測試條件遞歸執行下去,直到抵達一個葉子節點。當到達葉子節點時,咱們便獲得了最終的分類結果。