月度归档:2012年10月

PHP内核中的异常基类

PHP内核中的异常基类

<<思考PHP语言三:异常处理>>中有说到异常的定义:异常处理是指在语言中能够使程序按照一种标准的方法对于某些运行时错误和其他程序所检测到的异常事件做出反应。异常发生的时间是不可以确定的,如果一种语言不包括异常处理机制,这就会给语言带来额外的复杂性。对于异常的处理有三种方案,而PHP5使用的是将一个异常处理独立出来,作为专门的子程序或类存在。

Exception是PHP中所有异常的基类,自从PHP5.1.0开始引入,自此,我们可以以面向对象的方式处理错误。 Exception类的声明如下:

 
 Exception {
        /* 属性 */
        protected string $message ;
        protected int $code ;
        protected string $file ;
        protected int $line ;
 
        /* 方法 */
        public __construct ([ string $message = "" [, int $code = 0 [, Exception $previous = NULL ]]] )
        final public string getMessage ( void )
        final public Exception getPrevious ( void )
        final public int getCode ( void )
        final public string getFile ( void )
        final public int getLine ( void )
        final public array getTrace ( void )
        final public string getTraceAsString ( void )
        public string __toString ( void )
        final private void __clone ( void )
    }

其中message表示异常消息内容,code表示异常代码,file表示抛出异常的文件名,line表示抛出异常在该文件中的行号。下面从 PHP内核的角度说明这些属性及对应的方法。

message表示异常的消息内容,其对应getMessage方法。message是自定义的异常消息,默认为空字符串。对于PHP内核来说,创建Exception对象时,有无message参数会影响 getMessage方法的返回值,以及显示异常时是否有with message %s等字样。message成员变量的作用是为了让用户更好的定义说明异常类。

code表示异常代码,其对应getCode方法。和meesage成员变量一样,code也是用户自定义的内容,默认为0。

file表示抛出异常的文件名,其对应getFile方法,返回值为执行文件的文件名,在PHP内核中存储此文件名的字段为 EG(active_op_array)->filename 此字段的值在生成一个opcode列表时,PHP的内核会将此前正在编译文件的文件名赋值给opcode的filename属性,如生成一个函数的op_array,在初始化op_array时,会执行上面所说的赋值操作,这里的赋值是通过编译的全局变量来传递的。当代码执行时,EG(active_op_array)表示正在执行的opcode列表。

line表示抛出异常在该文件中的行号,其对应getLine方法,返回整数,即EG(opline_ptr)->lineno。对于每条PHP脚本生成的opcode,在编译时都会执行一次初始化操作,在这次初始化操作中,PHP内核会将当前正在编译的行号赋值给opcode的lineno属性。 EG(opline_ptr)是PHP内核执行的当前opcode,抛出异常时对应的行号即为此对象的lineno属性。

除了上面四个属性,异常类还包括一个非常重要的内容:异常的追踪信息。在异常类中,通过getTrace方法可以获取这些信息。此方法的作用相当于PHP的内置函数debug_backtrace。在代码实现层面他们最终都是调用zend_fetch_debug_backtrace函数。在此函数中通过回溯PHP的调用栈,返回代码追踪信息。与getTrace方法对应还有一个返回被串化值的方法getTraceAsString,以字符串替代数组返回异常追踪信息。

在构造函数中,从PHP5.3.0增加$previous参数,表示异常链中的前一个异常。在catch块中可以抛出一个新的异常,并引用原始的异常,为调试提供更多的信息。

你将要怎么样改变世界?

和reeze聊天,reeze问我:linus搞出了linux和git。。你呢?将要怎么样改变世界?

到此,忽然思维停住了。我呢?我是谁?我在哪?我在做什么?我将要怎样改变世界?

很想哭的,那种眼睛涩涩的感觉。

我们在为生活奔波,当年的理想,曾经的誓言,已经不知去了何处。

……
……

只为记录。

《程序员的思维修炼》读书笔记

买《程序员的思维修炼-开发认知潜能的九堂课》这本书有一段时间了,到今天才看完,薄薄的一本书,值得细细品味。很久没有写读书笔记了,本书中建议读完一本书后就应该写一篇总结或至少认真写个评论,阅读更多的书,就会有更多的东西可以写。
这是一本包含了认知科学、神经学、学习和行为理论,以程序员更能理解的形式介绍了人类大脑的工作机制,并研究如何克服这个系统的局限来提高自己学习和思考的技能。
其中一些观点印象深刻。

最开始是关于技能获取领域的德雷福斯模型(Drefus model)。此模型是一个针对每项技能的的评估体系,它能表示你处于某个特定技能领域中的某个水平阶段。如PHP开发新手、linux专家等。它分为五个等级:新手、高级新手、胜任者、精通者、专家。新手依赖于规则,规则可以让他们开始工作。他们拥有对此领域极少的技能或根本没有技能。新手非常在乎最后的结果,希望自己做的东西能取得明显的效果,当一个功能做出来后,就会有非常大的成功感,会觉得自己是人才。但是由于他们经验的缺失,不知道如何应对出现的错误,此时可能会不知所措。
与新手相比,高级新手已经有一些经验,能够根据一些总体的原则,尝试着解决问题,但是他们没有一个对此领域的全局的理解,并且也不会想去了解,无法站在一个更高的高度去理解现在看到的内容。
胜任者在团队中往往发挥着领导作用,能够独立的解决问题,有时也可以指导新手处理问题。他们往往具有良好的主动性,他们的工作依赖于自己以往的经验,开始学会寻找新的问题的解决方案,如寻求专家的帮助、google等。但是他们缺少对于自身错误的反思和纠错能力。
精通者更多的表现在能时常反思,时常纠错。他们有足够的经验,知道下一步会发生什么,知道如何应对即将发生的事。这个阶段的程序员往往能正确应用设计模式。
专家根据直觉工作,不需要太多理由。他们总在寻找更好的方法和方式,他们有丰富的经验,他们擅长布道。
在现实中,大多数人都是高级新手,他们不知道自己不知道。
我们需要勇于承担责任,保持实践以维持专家技能(如果你是一个leader,也不要脱离开发第一线),多考虑情境,培养更多的直觉。

我们的大脑的配置是双CPU,单主机总线设计。1号CPU负责线性、逻辑思维和语言处理,处理速度较慢,我们称之为L模式;2号CPU不做任何语言处理,当你“思考”时,它会去搜索和匹配,异步返回结果,我们称之为R模式。R型对直觉、问题解决和创造性非常重要。
基于R的不可预测性,我们需要建立外部存储设备,如记事本、PDA等等,当有想法时记录下来,每个人都有好点子,但只有少数人会努力付诸实际先去,只有更少的人将这些好点子成功实现。
如果想成为专家,需要更多的启动你的R型CPU,作家中流传一句话:酒醉写作、酒醒修改,程序员中的结对编程模型都是L和R型充分利用的例子。利用图像、晨写技术、写博客、散步等方式可以让你大脑中的R型自由展示。

程序有BUG,而我们的大脑也会有许多出错的地方,这些错误会影响我们的思维。书的作者介绍了4大类问题:认知偏见、时代影响、人性倾向和硬件故障。
我们常见的认知偏见有思维定势、基本归因错误、自私的偏见、需要定论、认可上的偏见、曝光效应、霍桑效应、虚假记忆、符号约简谬论等。
我们渴望知道结果,从而我们总是努力消除不确定性,但过早的下结论会减少我们的选择。因此我们需要顶住压力,推迟下结论的时间。我们的记忆并不靠谱,甚至会有虚假记忆,用笔或类似的方式记录下你需要记忆的信息,我们需要一些东西来确保你的记忆不会与事实想去甚远。
偏见会随着时间改变,我们都是时代的产物,在不同的时代之间存在着我们常说的代沟。除了时代的影响,我们的个性会影响我们的价值观和看法。性格和技能水平不同,其奖励的方式也应该不同。尊重不同人的不同性格,不要试图改变别人的性格以适应自己。

技术本身并不重要,持续学习才是最重要的。教育字面的意思却是“被引出”。建立SMART任务实现你的目标。我们需要记住:时间是无法创造和销毁的。时间只能分配。教是最好的学。

放松以集中注意力,我们开发外部信息处理系统,以浸泡、分类和发展想法。
优化当前情境,减少情境切换,因为平均需要20分钟才能返回到原来的工作状态,从而不要时不时的检查邮件,避免分心,定制单任务界面。

认识你自己,认识当前时刻,认识你所处的情境。从现在开始改变,虽然开始很难,困难很多,甚至反复,坚持。