2008年11月1日星期六

经济学原理学习笔记(4)--科学的看待经济学

每个研究领域都有自己的语言和思考方式。数学家讨论公理、积分和向量空间,心理学家谈论自我、本我和认知的不一致性。经济学家也一样,供给、弹性、需求、比较优势、消费者剩余和无畏损失这类术语都是经济学家语言的一部分。

经济学作为一门科学这似乎有些不可思议,但是,科学的本质是科学方法:冷静的建立并校验有关时间如何运行的各种理论,这种研究方法适合于研究生物进化或者是地心引力,同样适用于研究一个国家的经济。

简单的说,科学方法就是:观察、理论和进一步的观察,例如牛顿通过观察苹果落地的现象进行理论然后发现了地心引力。虽然经济学家像其他科学家一样运用理论和观察,但是要记住在经济学中做实验是很困难的。研究万有引力的物理学家可以在实验室中自由下落各种物体从而得到实验数据,但是研究通货膨胀的经济学家绝不会被允许仅仅是为了获得有用的数据而去控制一国的货币供给。与天文学家、考古学家相类似,经济学家通常不得不使用这个世界碰巧向他们提供的数据。

如果去咨询一位物理学家一块石头从10米高空落下来需要多长时间,他会通过假设这块石头在真空落下来回答这个问题。虽然这个假设并不现实,因为空气的阻力会使石头的下落速度变慢,但是物理学家认为空气阻力对大理石下落的速度影响非常小以至于可以忽略不计。同样的,经济学家也可以做出类似的假设,不仅是因为假设可以使复杂的世界简单化,同时可以使解释这个世界变得更加容易。比如,我们可以假设这个世界只有两个国家组成,每个国家都只生产两种产品,虽然现实中并不是这样,但是通过这种假设,我们可以更加集中的思考问题的实质。

科学思考的艺术,无论是在什么学科中,就是决定作出什么样的假设。比如说刚才提到的,如果从10米高空落下的是一片羽毛的话,那么物理学家就会意识到忽略空气阻力的假设是不正确的,毕竟,空气阻力对羽毛的影响要比对石头的影响大的太多。

同样的,经济学家通过不同的假设来回答不同的问题,假设我们想研究政府改变流通中的货币量的时候经济中会出现什么情况。这一分析的重要内容是价格会作出什么样的反应。经济中的许多价格并不是经常变动的,比如说一本杂志的价格可能好几年才会变动一下。在了解了这个事实的基础上,当我们研究政策变动在长短不同时间中的影响时就会做出不同的假设:为了研究政策的短期效应,我们可以假设价格变动并不大,甚至可以做出价格都是固定的假设;然而当研究政策的长期效应的时候,我们可以假设所有的价格都是完全可变的。就像物理学家在羽毛和石头下落时所使用了不同的假设一样。

2008年10月29日星期三

CLR via C#学习笔记(3)--FCL和CTS

FCL也就是Framework Class Library,是.Net Framework的一个重要的组成部分,它是一系列DLL程序集的统称,这些程序集包含了数千个的类型的定义,每个类型都揭示了一些功能。同时MS也发布了很多其他的类库,比如WinFx和DirectX SDK,这些附加的类库提供了更多的类型,也揭示了更多的功能。下面是一些常用的类库:

Web Service: 包含一系列特殊的方法,以方便用户轻松的处理通过Internet发送的基于XML的信息。

Web Form: 提供了一系列基于HTML的应用程序(网站),通常用于查询数据库和调用Web服务,合并和过滤返回的信息,然后通过一个基于HTML的用户界面,在浏览器中来显示那些信息。

Windows Form: 其实就是一系列Windows GUI应用程序,开发人员通过Windows Desktop 提供的更强大的功能来创建应用程序的GUI。Windows Form可以利用控件、菜单以及鼠标/键盘事件,而且可以直接与底层的操作系统交换信息,也可以查询数据库和使用Web服务。

Windows Console Application: 控制台应用程序提供了一种快速、简单的方式来生成一个应用程序,比如编译器、应用程序和工具通常作为控制台应用程序来实现。

Windows Services: .Net Framework提供了生成"服务"应用程序的功能,它们可以使用Windows Service Control Manager来进行控制。

Component Library: .Net Framework可以生成独立的程序集(组件),其中包含的类型可以轻松的集成到前面提到的任意一种类型中。

由于FCL中包含非常多的类型,所以将相关的一系列类型放到一个单独的命名空间中是很有必要的。比如System命名空间包含Object基类型,其他所有类型都是从基类型继承而来的。


CTS是MS制定的一个有关类型的正式的规范,也就是Common Type System。它已被MS提交给ECMA已完成标准化工作。

CTS规范规定:一个类型可以包含零个或者多个成员,先简单的介绍下这些成员:

Field: 它是对象状态一部分的一个数据变量,不同的字段按照其名称和类型加以区分。

Method: 用Structure Programming的说法来说,其实Method相当于一个Function,它针对对象执行一个操作,通常它会改变对象的状态。Method有一个Name,一个Signature和一个或多个Modifier:Signature制定了参数的数量、类型及其顺序;参数的类型;Method是否有返回值,如果有的话还要制定返回值的类型。

Property: C#他老爸Anders从他的Delphi中搞来的一套重要的思想:Property对于调用者(前台使用人员)来说,它看起来就像是一个Field,然而对于具体的实现者(后台开发)来说,它看起来却像是一个或是两个Method。总而言之,Property提供了一种更人性的实现Accessor/Modifier的途径。

Event: 事件在对象以及其他相关对象之间实现了一个通知机制,比如说,利用按钮提供的click事件,可以方便的在按钮被点击之后通知其它对象。

2008年10月27日星期一

CLR via C#学习笔记(2)--IL和JIT编译

前面提到过,托管程序集同时包含元数据和IL,IL是一种和CPU无关的机器语言,IL要比大多数CPU机器语言高级很多,它可以访问和操作对象类型,提供相应的指令用于初始化对象,在对象上调用虚方法,并可以直接操作数组元素,他甚至提供了用于抛出和捕捉异常的指令。可以把IL想像成是一种面向对象的机器语言。

大部分.Net程序员使用C#,C++/CLI或者是VB编程,这些高级语言会被编译器翻译成对应的IL,当然IL也可以用汇编语言来写,微软为此提供了ILAsm和ILDasm工具用于汇编和反汇编IL。

但需要注意的是,高级语言通常只揭示CLR的一个功能子集,然而IL确允许开发人员访问CLR的所有功能。所以,如果选择的语言隐藏了需要的那部分CLR功能,就可以选择IL或者提供这部分功能的语言来编写这部分代码。

接下来说说JIT编译:

首先考虑下面这个简单的C#方法:

static void Main()
{
Console.WriteLine("Hello");
Console.WriteLine("Byebye");
}

这个方法中,Main方法调用了单件类Console,使得CLR分配了一个单独的内部结构,在这个结构中,Console的每一个方法都有一条记录,每条记录均容纳了一个地址,根据这个地址既可以找到方法的实现。当对这个结构进行初始化时,CLR将每条记录都设置成CLR内部包含的一个未文档化的方法,暂时就把这个方法叫做JITCompiler吧。

Main方法首次调用WriteLine的时候会调用JITCompiler方法,JITCompiler方法负责将一个方法的IL代码编译成本地CPU指令,由于IL是即时(In Time)编译的,所以通常将CLR这个组件称为JITer。

JITCompiler被调用的时候,它需要知道要调用哪个方法以及具体是什么类型定义了该方法,然后JITCompiler会在定义程序集的元数据中搜索被调用方法的IL。JITCompiler接下来要验证IL代码,并将IL代码编译成本地的CPU指令,本地CPU指令保存在一个动态分配的内存块中,然后JITCompiler回到CLR为类型创建的内部数据结构,找到与被调用的方法相对应的那一条记录,然后将最初调用它的那个引用替换成内存块(包含刚才编译好的CPU指令)的地址,最后,JITCompiler会跳转到内存块中的代码,这些代码正是WriteLine方法的具体实现,代码返回时,会返回到Main中的代码并继续执行。

然后Main第二次调用WriteLine,由于之前已对WriteLine的代码进行了验证和编译,所以会直接执行内存块中的代码,完全跳过JITCompiler方法。

所以说,同一个方法只有在首次调用的时候才会造成一定的性能损失,之后对该方法的调用都会以本地代码的形式全速运行,因为不需要再次执行验证和编译本地代码。

需要注意的是,CLR的JIT编译器会对本地代码进行优化,生成这些代码需要更长的时间,但会获得更出色的性能。例如C#的编译器中有两个开关:/optimize和/debug,在VS的Debug配置中,Debug配置是/optimize-和/debug-full,而Release的配置是/optimize+和/debug:pdonly。

N多微软神作的作者Jeffrey Richter认为IL最大的优势并不在于它是脱离了底层CPU的一种抽象,而是它所提供的可靠性和安全性。