1 回答

TA貢獻1995條經驗 獲得超2個贊
這是我在一個論壇里看到的,你也參考參考吧。C++的虛函數
======================
C++使用虛函數實現了其對象的多態,C++對象的開始四個字節是指向虛函數表的指針,其初始化順序是先基類后派生類,所以該虛函數表永遠指向最后一個派生類,從而實現了相同函數在不同對象中的不同行為,使得對象既有共性,又有其個性。
內存池分配、回收之伙伴算法
=======================
伙伴算法是空閑鏈表法的一個增強算法,依次建立2^0\2^1\2^2\2^3...2^n大小的 內存塊空閑鏈表,利用相鄰內存塊的伙伴性質,很容易將互為伙伴的內存塊進行合并移到相應的空閑鏈表或將一塊內存拆分成兩塊伙伴內存,一塊分配出去,另一塊掛入相應空閑鏈表,使得內存的分配和回收變得高效。
AVL樹
=======================
AVL樹是一個平衡二叉樹,其中序遍歷是從小到大排序的,該結構插入節點和檢索非常高效,被廣泛應用
快速排序
=======================
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。效率非常高
密碼學之非對稱加密協議(公鑰、私鑰加密協議)
======================
非對稱加密算法需要兩個密鑰,用其中一個加密產生的密文,只能通過另外一個密鑰解密,密鑰持有者A可以將其中一個公開,稱為公用密鑰,另外一個秘密保存稱為私鑰,這樣當某人B想給A傳一封秘信時,只要將密信使用A的公鑰加密后,就可以放心使用各種信道將迷信傳給A了,因為該密信只有A可以解密,第三者截取因為無法解密而毫無意義。
該算法很好地解決了密鑰的安全傳遞的問題,因為公鑰和加密算法都是公開的,私鑰不需要傳輸。
密碼學之數字簽名協議(身份鑒別、防抵賴)
======================
數字簽名也是建立在非對稱加密基礎之上的,如果A君用它的私鑰將文件加密后在發布,A君就無法抵賴該文件是其發布的,因為其他人能通過A君的公鑰將文件解密就說明,如果算法可靠,該文件一定是A君用其私鑰加密的。
由于非對稱加密算法的加密和解密很慢,現在的數字簽名并非是將其要發布的信息用其私鑰加密,而是先用一個單項散列算法如(MD5)產生一個該信息的比較短的指紋(hash值),對其指紋用其私鑰加密后和信息一并發布,同樣達到了防抵賴的作用。
無回溯字符串模式匹配-kmp算法
======================
他是根據子串的特征,當匹配失敗時,不需要回溯,而是直接將字串向后滑動若干個字節,繼續匹配,極大提高了匹配速度。該算法被廣泛使用。詳細請參考數據結構教程。
最小路徑選路-迪杰斯特拉算法、弗洛伊德算法
======================
學習數據結構的時候,印象最深的就要算kmp算法和最小路徑算法了,因為理解他們比較費腦子,我是不可能發明這些算法了,發明他們的都是天才,呵呵。
使用最短路徑的算法曾經幫人寫過一個小東西,還是很有效的,記得是使用的弗洛伊德算法的一個變種,要詳細了解的朋友可以查找相關資料,想將他們使用在你的項目中,代碼直接從教科書上抄就可以了,不需要理解。
tcp協議之-nagle算法
======================
tcp、ip中令人叫絕的想法很多,印象最深的要算nagle算法了。
tcp出于效率和流量控制的考慮,發送端的數據不是產生多少就馬上發送多少,一般是等到數據集聚到發送緩沖區長度的一半或者數據達到最大tcp數據包數據部分長度(好像是65515)才啟動發送,而且還要看接受端可用緩沖區的大小,如果接受端產生一個回應報文通知發送端沒有接受空間了,發送端哪怕緩沖區已經滿了,也不會啟動發送,直到接受端通告發送端其已經有了接受數據的空間了。
這樣就有一個問題,假如發送端就是要發送一個小報文(比如10個字節),然后等待對方的回應。按照上面的方案,tcp會一直等數據收集到一定量才發送,于是矛盾就產生了。應用層不再發數據,tcp等不到足夠的數據不會將10個字的數據發送到網卡,接收端應用層收不到數據就不會回應發送端。
你也可能說,可以讓修改發送端發送條件,不一定要等到足夠的數據再發送,為了效率考慮,可以考慮延時一定的時間,比如說1秒,如果上層還沒有數據到來,就將發送緩沖中的數據發出去。當然這樣也是可行的,盡管應用端白白等了1秒鐘啥也沒干,呵呵。
其實nagle算法很好解決了該問題,它的做發是鏈接建立后的第一次發送不用等待,直接將數據組裝成tcp報文發送出去,以后要么等到數據量足夠多、要么是等到接受方的確認報文,算法及其簡單,而且很好解決了上面的矛盾。
socket之io模型設計
======================
windows下socket有兩種工作方式:
1)同步方式
2)異步方式
同步socket又有兩種工作模式:
1)阻塞模式
2)非阻塞模式
阻塞模式是最簡單的工作模式,以tcp的發送數據為例,如果發送緩沖區沒有空間,send調用就不會返回,一直要等到能夠發出一點數據為止,哪怕是一個字節,但是send返回并不表示我要發送的數據已經全部提交給了tcp,所以send返回時要檢查這次發送的數量,調整發送緩沖指針,繼續發送,直到所有數據都提交給了系統。
由于其阻塞的特性,會阻塞發送線程,所以單線程的程序是不適合使用阻塞模式通信的,一般使用一個連接一個線程的方法,但是這種方式對于要維護多個連接的程序,是個不好的選擇,線程越多,開銷越大。
同步非阻塞模式的socket不會阻塞通信線程,如果發送緩沖區滿,send調用也是立刻返回,接受緩沖區空,recv也不會阻塞,所以通信線程要反復調用send或recv嘗試發送或接收數據,對cpu是很大的浪費。
針對非阻塞的尷尬,接口開發人員發明了三種io模型來解決該問題:
1)選擇模型(select)
2)異步選擇模型(AsyncSelect)
3)事件選擇模型(EventSeselect)
其思想是根據io類型,預先查看1個或n個socket是否能讀、寫等。
其select本身來說,select是阻塞的,可以同時監視多個socket,只要所監視的其中一個socket可以讀、寫,secect調用才返回
異步選擇模型其select是異步的(異步是不會阻塞的),是將監視任務委托給系統,系統在socket可讀、寫時通過消息通知應用程序。有一點需要說明,假如應用程序已經有很多數據需要發送,當收到可寫通知時,一定要盡量多地發送數據,直到發送失敗,lasterror提示“將要阻塞”,將來才可能有新的可寫通知到來,否則永遠也不會有。
事件選擇模型也是將監視socket狀態的工作委托給系統,系統在適當的時候通過事件通知應用程序socket可以的操作。
除了同步工作方式外,還有一種叫異步工作方式
異步工作方式是不會阻塞的,因為是將io操作本身委托給系統,系統在io操作完成后通過回調例程或事件或完成包通知應用程序
異步工作方式有兩種io模型和其對應,其實這兩種模型是window是異步io的實現:
1)重疊模型
2)完成端口
重疊模型通過事件或回調例程通知應用程序io已經完成
完成端口模型比較復雜,完成端口本身其實是一個io完成包隊列。
應用程序一般創建若干個線程用來監視完成端口,這些線程試圖從完成端口移除一個完成包,如果有,移除成功,應用程序處理該完成包,否則應用程序監視完成端口的線程被阻塞。
select模型是從UNIX上的Berkeley Software Distribution(BSD)版本的套接字就實現了的,其它四種io模型windows發明的,在windows中完成端口和異步選擇模型是使用比較廣泛的,一般分別用于服務端和客戶端開發。
這五種io模型設計還是比較巧妙的:三種選擇模型很好解決了“同步非阻塞”模式編程的不足;重疊模型和完成端口是windows異步io的經典實現,不局限于網絡io,對文件io同樣適用。
說點題外話,socket的send完成僅僅是將數據(可能是部分)提交給系統,而不是已經發送到了網卡上,更不是已經發送到了接收端。所以要知道你的數據已經發送到了對方的應用層的唯一方法是,讓對方給你發送一個應對包。
發送數據要注意,對應tcp,要防止發送和接收的亂序,對于發送,一般應該為每一個鏈接建立一個發送隊列,采用類似nagle的算法啟動數據發送。
一次發送可能是你提交數據的一部分,一定要當心,否則出問題沒處找去。
添加回答
舉報