阿Q的博客

如果您发现任何问题,欢迎指正!

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  9 随笔 :: 1 文章 :: 3 评论 :: 0 引用

公告

2009年8月21日 #

  
    这是一个老问题了, 也是做web开发必须要弄明白的, 其实是很简单的东西, 想想上学时被它搞得迷糊就觉得好笑!上班后做了开发, 渐渐明白, 共享一下, 希望对大家有所帮助!
  
    一 先说说http吧, 这个是web的根本大法

HTTP协议本身是无状态的,客户端只需要简单的向服务器请求,如:www.google.com/abc.html.服务器将文件内容返回给客户。无论是客户端还是服务器都没有必要纪录彼此过去的行为。然而人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,如www.google.com/search=美女。这种需求一方面迫使 HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求。 后来用户对WEB有了更高的要求, 如购物, 一个网络商店每天处理N个客户请求,当接到一个请求时,就需要知道这个客户在站点订了几个商品,有没有付款等。为此HTTP协议添加了cookie特性。cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。
   引用网上朋友的用例(忘记URL了,不好意思):
   让我们用几个例子来描述一下cookie和session机制之间的区别与联系。X曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
    由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie来达到保存标识的目的,但实际上它还有其他选择。注意session并不HTTP的内容,它是保存客户端状态的一种机制。
  
    二 理解cookie

    cookie简单来说就是服务器设置一些信息,将它存储在客户端, 就像上面的例子2。(客户端脚本如JavaScript或者VBScript也可以生成cookie,但是目的都是为了存储信息),当客户再次访问服务器时, 浏览器会带上cookies发送请求给服务器。浏览器处理cookies的是有规则的,只发送附和条件的cookies. 意思是,当访问麦当劳时,只需出示麦当劳的会员卡。
  
    三 理解session

    session其实更简单, 就像例子3,在客户端只有一个卡号,他每回来的时候,一出示卡号,服务器会查找当前卡号的信息,就知道他的状态了。它的实现可以用cookies,也可以用其它方法,如:作为查询字符串附加在URL后面。
    在谈论session机制的时候,常常听到这样一种误解“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的 HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。
   
    
posted @ 2009-08-21 12:04 坏份子 阅读(71) 评论(0) 编辑

2009年7月14日 #

源代码分析

首先看 transaction 方法

ActiveRecord::Transactions Public Class methods
     # File vendor
/rails/activerecord/lib/active_record/transactions.rb, line 187
187:     def transaction(&block)
188:       self.class.transaction(&block)
189:     end

 可以看出他是调用类方法,类方法代码如下:

       # File vendor/rails/activerecord/lib/active_record/transactions.rb, line 75
      def transaction(
&block)
        increment_open_transactions

        begin
          #connection 
is kind of MysqlAdapter
          connection.transaction(Thread.current[
'start_db_transaction'], &block)
        ensure
          decrement_open_transactions
        end
      end

#connection.transaction call method 
in
# File vendor
/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 58
      # Wrap a block 
in a transaction.  Returns result of block.
      def transaction(start_db_transaction 
= true)
        transaction_open 
= false
        begin
          
if block_given?
            
if start_db_transaction
              begin_db_transaction
              transaction_open 
= true
            end
            
yield
          end
        rescue Exception 
=> database_transaction_rollback
          
if transaction_open
            transaction_open 
= false
            rollback_db_transaction
          end
          raise unless database_transaction_rollback.is_a
? ActiveRecord::Rollback
        end
      ensure
        
if transaction_open
          begin
            commit_db_transaction
          rescue Exception 
=> database_transaction_rollback
            rollback_db_transaction
            raise
          end
        end
      end

 

 上面的代码即实现了rails中的transaction,可见ActiveRecord是不支持事务嵌套的。 如果模型使用的是相同的数据库, 那么用 ModelA.transaction 或 ModelB.transaction的作用是一样的。


Code

  都是一样的!

  这些对象的方面或类方面, 到最后都是转换成SQL,让数据库来执行, 如果明白这个,一切都变得简单了! 

就从SQL而言 "model.transaction do" 只是执行 Begin, "end" 执行Commit. 对于MYSQL个别是引挚支持的存储点功能不在本文讨论范围之内。补充一下, 目前只是SQLServer支持事务嵌套,所以如果说ROR支持事务嵌套也就有点勉强!

 

posted @ 2009-07-14 09:29 坏份子 阅读(367) 评论(0) 编辑

2008年4月15日 #

引言:各种各样的面像对象语言总是说,世界万物皆为对象,都可以用类来描述,那么‘类‘是不是也属于万物之中呢?他是不是也可以用类来描述呢?
不得而知,我只用过C,C++,C#,ruyb,好像只有ruby是这样的。

1 对象存储数据,类存储方法。就是说,对象保存属于这个对象的数据,这样每个对象间的数据是独立的,各有各的存储空间,方法在内存中只有一份,就是由类保存。

2 什么是metaclass,简单来说就是,首先他是一个类,他是一个特殊的类,他描述的不是人,也不是飞机,是另外的一个类。


当Ruby 处理下面代码后,我们得到Person对象,它是Class类的实例

class Person
    attr_accessor :age,:name
    def initialize(age,name)
        @name = name
        @age = age
    end
end

Class 也是一个对象,那么上面说对象中只存储数据,那么又如何解释呢?

只有查看Ruby的源代码,ruby是用C语言写的,里面的对象简单来说就是一些数据结构。

对于Class的对象,有一个m_tbl成员,从名字可见是一个方法表。可见Class对象要比一般的对象特别。

 struct RObject {
   struct RBasic basic;
   struct st_table *iv_tbl;
 };

 struct RClass {
   struct RBasic basic;
   struct st_table *iv_tbl;
   struct st_table *m_tbl;
   VALUE super;
 };

3 如何取得定义类的metaclass呢?最简单的两个方法,类名即是这个Class的metaclass.也可以能过类实例的.class方法。

irb(main):003:0> Person.object_id
=> -604423968
irb(main):004:0> p = Person.new
=> #<Person:0xb7f1cb08>
irb(main):006:0> p.class.class
=> Class
irb(main):007:0> p.class.class.object_id
=> -604330368
irb(main):008:0> p.class.object_id
=> -604423968
irb(main):009:0> p.class.inspect
=> "Person"
irb(main):010:0> p.object_id
irb(main):011:0> p2 = Person.new
=> #<Person:0xb7ef6944>
irb(main):012:0> p2.class.object_id
=> -604423968

如代码所示 Person.object_id == p.class.object_id == p2.class.object_id 可以他们都是一个东西。
即 p.class == p2.class == Person 都为Person的metaclass


下回分析如何修改metaclass!
posted @ 2008-04-15 14:54 坏份子 阅读(147) 评论(0) 编辑

2008年3月21日 #

uby meta-class 分析
ruby core 文档对class , object 和 meta-class 的描述如下:
Classes, modules, and objects are interrelated. In the diagram that follows, the vertical arrows represent inheritance, and the parentheses meta-classes. All metaclasses are instances of the class `Class’.

        

第一次看起来有点糊涂,让我们仔细的来分析一下。先说上面这个图吧
垂直箭头表示继承关系,括号中的(someclass)就是meta-classes,所有的meta-classes都是类Class的实例。
meta-classes是什么?
简单从一个例子说起吧

如果我们建立了一个Person类

irb(main):001:0> class Person
irb(main):002:1> end
=> nil
irb(main):003:0>

当ruby解释器执行上面代码,结束返回nil后,这时候我们就有了一个meta-class,叫Person,它是Class的一个实例
测试一下:
irb(main):003:0> Person.class
=> Class

看来它是Class类的一个实例,从图上看它的祖先是Object那么它也应该有Object类的方法 instance_of?(class)
测试一下:
irb(main):004:0> Person.instance_of?(Class)
=> true
哦,他果然是Class的实例。

再来看看meta-class (Object, Module, Class)
irb(main):005:0> Class.class
=> Class
irb(main):006:0> Module.class
=> Class
irb(main):007:0> Object.class
=> Class
irb(main):008:0>
可见ruby解释器加载时,就自动加载了Object类,Module类,Class类,所以己经生成了他们的meta-class
posted @ 2008-03-21 17:27 坏份子 阅读(245) 评论(0) 编辑

2008年3月14日 #

时间流得很快,没想到再次写点东西时,已是2007年的7月。
结束旧工作,选了新公司,
离开旧房子,搬到新房子,
女朋友走了,换了新男友。
简单来说这就是这半年发生的事,我想可以用不平谈来形容吧。
上班的日子时间总是很紧,忙忙火火的半年就过去了,甚至来不急伤感女友的离去。
看着以往的随笔,感觉惬意想像学生日子的那个下午就在昨天,而上面的一切就在昨晚发生了


posted @ 2008-03-14 16:28 坏份子 阅读(43) 评论(0) 编辑

    2008年3月15日,没想到再次来到这里已是10个月后,上一篇文字是在2007年7月写的。也许是在新工公司的日子过得太好了,人家说:人总是在失意时,才想起过去,才去感概。所以今天就不去呻吟了。新的一年啦,虽然年早过了,但我喜欢按工龄来算年,到今天是在软件行业工作两整年,目前还无所建树,但自我感觉在进步。也算是一点安慰吧。
    这一年来一直在做rubyonrails方面的开发,深感国内这方面的资源太少,希望自己能将使用心德,ruby及rails的源码分析整理成文档和国内的rubist一起共享。这将是本年除工作外业余时间最想做的事。同时也希望能有机会认识这方面的志士,一起学习,成长。
posted @ 2008-03-14 16:28 坏份子 阅读(38) 评论(1) 编辑

2007年3月9日 #

摘要: 第一份IT业工作是在一个日企刚到公司时也是一腔热血,经历了一些事,变得有些消沉。日本总公司的项目不立项了,我们四个月的准备白费了。后面的几个月里自己根据总公司的业务需求,又做了相关方面的软件开发,结果也没有立项。和女朋友相处总是遇到各种问题,大家都很任性。在迷茫和曲折中,走过了我的IT业经历的第一年。想想自己也有问题,以前总觉得自己技术很强,到公司后就是做项目,做好了,就可以了。当没有项目时,自己...阅读全文
posted @ 2007-03-09 16:43 坏份子 阅读(94) 评论(1) 编辑

2006年12月31日 #

摘要: 近来公司有个MS Office 编程的活,借机也研究了一下,略有收获,不敢独享,希望大家扔鸡蛋,但最好不是臭的。这个项目里,主要是想将Word ,Excel做成的文档中的图形导出为XML文件。这里的关键是找出文档中的图形对象,并识别出类型。做法如下: ApplicationClass app = new ApplicationClass(); Document doc = null; object...阅读全文
posted @ 2006-12-31 11:49 坏份子 阅读(265) 评论(1) 编辑

2006年12月21日 #

摘要: 工作一年多了,过于专注技术,似乎总有做不完的工作,干不完的活。因此,忽略了身边很多美好的事物。博客也算是一个吧。 看别人文字激扬,滔滔不绝,心里也怪痒痒了。于是乎有了这篇力作。 想年少时也做过文学大梦,抱着鲁迅或外国名著,似懂非懂的读着,也吸引了不少小女生,怎奈中意的却不屑一顾。情急之下,立志发愤读书,报不屑之仇。天资驽钝,只考了一个中专。人说情场失意,赌场得意,现在想来如果弃文从武,也许会一发不...阅读全文
posted @ 2006-12-21 17:52 坏份子 阅读(33) 评论(0) 编辑

仅列出标题