farseerfc.wordpress.com 導入

好神奇的想法,先存着,以後慢慢研究

原文: http://blog.youxu.info/2010/03/14/west- chamber/

待月西廂下,迎風戶半開。隔牆花影動,疑是玉人來。

最近推上最流行的一個關鍵詞是”西廂計劃”, 這個計劃名字取得很浪漫,客戶端叫做張生,對,就是西廂記裏面那個翻牆去見崔鶯鶯小姐的張生;顯然,服務器端必然叫做崔鶯鶯。客戶端的張生是最重要的部件,可以不依賴於服務端工作。因爲西廂計劃的作者只是簡要的介紹了一下原理,其他報道又語焉不詳,我當時就覺得很好奇,花了昨天一個晚上詳細讀了一下源代碼,終於知道怎麼回事了,覺得原理非常漂亮,所以寫篇文章介紹總結一下。

先說大方向。大家都知道,連接被重置的本質,是因爲收到了破壞連接的一個 TCP Reset 包。以前劍橋大學有人實驗過,客戶端和服務器都忽略 Reset, 則通信可以不受影響 …

導入自 renren

據說是一道微軟的面試題。如題,寫程序,讓Windows的任務管理器中的性能監視器呈現正弦曲線。

正弦曲線 正弦曲線

潛心鑽研良久,得代碼:(java)

public class sincpu {
    private static final int cycle=1024,tick = 256;
    public static void main (String[] args) throws InterruptedException {
        for(int i = 0;;i++){
            work(calcNextSleep(i % cycle));
            sleep(tick - calcNextSleep(i % cycle));
        }
    }

    private static long calcNextSleep(long i){
        return (int …

導入自 renren

看到陳驫同學很有感想的一篇神創論與命運日誌,覺得近日很久沒有看到這樣的評論了。想說幾句自己的觀點。

首先我認爲,神創論與宿命論沒有多少關聯,甚至進化論者相較於神創論者更容易接受宿命論的觀點。因爲神創論主張意志的存在,人所具有的個體意志與神的意志,因此在神創論者的眼中事件的結果是可以通過意志來改變的,亦即如果我從物理樓11樓跳下,那麼我就可以改變自己死亡時間的宿命。上帝的意志同樣可以左右事件的結果,也就是所謂的宿命不復存在。而進化論者不承認意志獨立於物質世界的存在,你我的思考、行爲,都受到物理學法則諸如量子力學的約束,這就引出了北大物理系教授的那句“宇宙中的一切都是可以計算的”,亦即宿命論。如我我選擇現在從物理樓上跳下,我這一行爲並不是處於個人的獨立意志,乃是想證明這一點,亦即我跳樓這一舉動是有其背後的動機與原因的,就如同計算機的輸入必然導致了輸出,宿命的必然終結於此。

其次,關於事件的複雜度所導致的隨機化,在大量混沌隨機中也存在着如統計學和隨機分形學這樣的規律,並不是否認宿命的充分理由。

關於神創論的合理性問題。我認爲是否相信神的存在只是一個boolean二值問題,它爲true爲false本身並不重要,重要的是確定它的取值之後得到的推論與結果。如果否認神的存在,如現代數學這樣的完美又何以存在,進化論者的解釋是事物最終會向着更好更高級的方向發展,產生現代數學乃至現代科學是發展的必然。而這種論調顯然有悖於物理中以熱力學第二定律爲首的,預言事物會隨時間推演愈發混亂的論斷。更進一步,甚至整個人類、整個生物系統的存在都是有悖於熱力學推論的現象,是某種理論只能以“小概率事件”解釋的現象。

神創論的核心觀點之一,是神的唯一存在性 …

farseerfc.wordpress.com 導入

故障描述: MMC Memory Stick Duo記憶棒未經Adapter適配器,直接插入SD Reader,致使MMC卡入SD Reader中。

棧展開: 某日下午,無課。 忙於數分作業,想查詢用手機拍攝的板書照片。 取出手機中的MMC。 未經裝配Adapter,直接插入SD Reader。 (A runtime exception was thrown.) 嘗試翻轉筆記本機身,倒出MMC,未果。(rethrow) 嘗試用手指甲取出,未果。(rethrow) 考慮到有“推入反彈”機制,嘗試將MMC推入更深,反彈機制由於類型不匹配而失效,未果。(rethrow) (The exception spread across the border of the …

farseerfc.wordpress.com 導入

程序開發原理

——抽象、規格與面向對象設計

Barbara Liskov 、John Guttag 著

楊嘉晨 等譯

關於翻譯風格:

多年來閱讀計算機類的著作及譯作,感覺總體的困難在於一大堆沒有標準譯名的技術術語。由於通行於工業界和學術界的還是英文原名和術語,我決定保留大量的英文術語。這樣的翻譯風格借鑑於臺灣著名的譯者和作者侯捷先生。對於譯與不譯的權衡,主要考慮閱讀的流暢,以及讀者的理解能力,或許難免帶有一些主觀色彩。

前言 Preface

構建產品級質量的程序——可以在很長一段時間內使用的程序——衆所周知是極其困難的。本書的目標就是改善程序員解決這項任務的效率。我希望讀者在閱讀本書之後成爲一名好程序員。我相信本書的成功在於改善編程技巧,因爲我的學生告訴我這已經發生在他們身上。

怎麼纔算是一名好程序員?是產生整個程序產品的效率。關鍵是要在每一階段減少浪費掉的努力。解決的方法包括:在開始編寫代碼之前就仔細考慮你的實現方案,通過未雨綢繆的方法來編寫代碼,使用嚴格的測試在早期發現錯誤,以及仔細注意模塊化編程,這樣當錯誤出現時,只需要改動極少數代碼就可以修正整個程序。本書涉及所有這些領域的技術。

模塊化編程(Modularity)是編寫好程序的關鍵。把程序分解成許多小模塊,每一個模塊通過良好定義的狹窄接口和別的模塊交互作用 …

farseerfc.wordpress.com 導入

3.2 標號、goto,以及switch的實現

goto語句及標號(label)是最古老的C語言特性,也是最早被人們拋棄的語言特性之一。像彙編語言中的jmp指令一樣,goto語句可以跳轉到同一函數體中任何標號位置:

void f()

{int i=0;

Loop: //A label

++i;

if(i<10)goto Loop; //Jump to the label

}

在原始而和諧的早期Fortran和Basic時代,我們沒有if then else,沒有for和while,甚至沒有函數的概念,一切控制結構都靠goto(帶條件的或無條件的)構件。軟件工程師將這樣的代碼稱作“意大利麪條”代碼。實踐證明這樣的代碼極容易造成混亂。

自從證明了結構化的程序可以做意大利麪條做到的任何事情,人們就開始不遺餘力地推廣結構化設計思想,將goto像猛獸一般囚禁在牢籠 …

farseerfc.wordpress.com 導入

3.1 左值右值與常量性(lvalue,rvalue & constant)

首先要搞清楚的是,什麼是左值,什麼是右值。這裏給出左值右值的定義:

1、左值是可以出現在等號(=)左邊的值,右值是隻能出現在等號右邊的值。

2、左值是可讀可寫的值,右值是隻讀的值。

3、左值有地址,右值沒有地址。

根據左值右值的第二定義,值的左右性就是值的常量性——常量是右值,非常量是左值。比如:

1=1;//Error

這個複製操作在C++中是語法錯誤,MSVC給出的錯誤提示爲“error C2106: '=' : left operand must be l-value”,就是說’=’的左操作數必須是一個左值,而字面常數1是一個右值。可見,嚴格的區分左值右值可以從語法分析的角度找出程序的邏輯錯誤。

根據第二定義,一個左值也是一個右值 …

farseerfc.wordpress.com 導入

2.2 I386平臺的內存佈局

衆所周知,I386是32位體系結構。因此對於絕大多數I386平臺的C++編譯器而言,sizeof(int)=sizeof(long)=sizeof(void*)=4。當然C++標準對此沒有任何保證,我們也不應該試圖編寫依賴於此的代碼。

32位指針的可尋址空間爲4GB。爲充分利用這麼大的尋址空間,也是爲了支持其它更先進的技術比如多任務技術或者動態鏈接庫技術,WinNT使用虛擬內存技術,給與每個應用程序全部4GB的內存空間。4GB的地址被一分爲二,前2GB供應用程序自己使用,後2GB由系統內核分配和管理。這2GB的內存地址,通常被劃分成3種內存區使用:

1 代碼及靜態數據區

由代碼加載器從動態鏈接庫鏡像(通常是exe或dll文件)加載,通常定位到鏡像文件中指定的基址開始的內存區。如果基址所在內存已被佔用,動態連接器會將代碼或數據重定向到其它可用地址。

在C++中,靜態數據包括:名字空間(namespace)和全局(global)對象、函數的static對象、類的static數據成員 …

farseerfc.wordpress.com 導入

C++ Tricks

By  FarseerFc

從今天起,我再將在Live SpaceQQZone同時發表一系列文章,暫定名爲“C++Tricks”。

本文旨在記錄和闡述一些本人學習C++時所得的心得、技巧。總體來看,本文涉及的內容是每一個C++程序員都應該知道的,但是很少見諸C++教材。希望對各位同仁學習C++有所幫助。

也可以通過QQ或MSN向我索要此文的DOC版或PDF版,會比網頁上的更新的快一點。

1      詞法問題(Lexical Problems)


2      X86體系結構

     2.1 X86概述

     2.2 …

farseerfc.wordpress.com 導入

2.3 I386平臺C函數內部的棧分配

函數使用棧來保存局部變量,傳遞函數參數。進入函數時,函數在棧上爲函數中的變量統一預留棧空間,將esp減去相應字節數。當函數執行流程途徑變量聲明語句時,如有需要就調用相應構造函數將變量初始化。當執行流程即將離開聲明所在代碼塊時,以初始化的順序的相反順序逐一調用析構函數。當執行流程離開函數體時,將esp加上相應字節數,歸還棧空間。

爲了訪問函數變量,必須有方法定位每一個變量。變量相對於棧頂esp的位置在進入函數體時就已確定,但是由於esp會在函數執行期變動,所以將esp的值保存在ebp中,並事先將ebp的值壓棧。隨後,在函數體中通過ebp減去偏移量來訪問變量。以一個最簡單的函數爲例:

void f()

{

int a=0; //a的地址被分配爲ebp-4

char c=1; //c的地址被分配爲ebp-8

}

產生的彙編代碼爲:

push ebp ;將ebp壓棧

mov ebp,esp ;ebp=esp 用棧底備份棧頂指針

sub …

farseerfc.wordpress.com 導入

2.4 I386平臺C函數調用邊界的棧分配

當調用一個函數時,主調函數將參數以聲明中相反的順序壓棧,然後將當前的代碼執行指針(eip)壓棧,然後跳轉到被調函數的入口點。在被調函數中,通過將ebp加上一個偏移量來訪問函數參數,以聲明中的順序(即壓棧的相反順序)來確定參數偏移量。被調函數返回時,彈出主調函數壓在棧中的代碼執行指針,跳回主調函數。再由主調函數恢復到調用前的棧。

函數的返回值不同於函數參數,通過寄存器傳遞。如果返回值類型可以放入32位變量,比如int、short、char、指針等類型,通過eax寄存器傳遞。如果返回值類型是64位變量,如_int64,同過edx+eax傳遞,edx存儲高32位,eax存儲低32位。如果返回值是浮點類型,如float和double,通過專用的浮點數寄存器棧的棧頂返回。如果返回值類型是用戶自定義結構,或C++類類型,通過修改函數簽名,以引用型參數的形式傳回。

同樣以最簡單的函數爲例:

void f(){

int i …

farseerfc.wordpress.com 導入

2.5 I386平臺的邊界對齊(Align)

首先提問,既然I386上sizeof(int)==4、sizeof(char)==1,那麼如下結構(struct)A的sizeof是多少?

struct A{int i;char c;};

答案是sizeof(A)==8……1+5=8?

呵呵,這就是I386上的邊界對齊問題。我們知道,I386上有整整4GB的地址空間,不過並不是每一個字節上都可以放置任何東西的。由於內存總線帶寬等等的技術原因,很多體系結構都要求內存中的變量被放置於某一個邊界的地址上。如果違反這個要求,重則導致停機出錯,輕則減慢運行速度。對於I386平臺而言,類型爲T的變量必須放置在sizeof(T)的整數倍的地址上,char可以隨便放置,short必須放在2的整數倍的地址上,int必須放在4的整數倍的地址上,double必須放在8的整數倍的地址上。如果違反邊界對齊要求 …