随笔- 4  文章- 0  评论- 5 
置顶随笔
摘要: 最近重新复习了一个c#基础知识,在测试StringBuilder与字符串连接的比较时,没想到二者的差距竟然如此之大,用StringBuilder连接字符50000次竟然是0毫秒,而用字符串连接为1750毫秒。当连接500000次的结果差距更不用说了,下面总结一下学习c#的一些知识点:1.StringBuilder与字符串连接比较[代码]  执行结果却大吃一惊,知道用字符串拼接速度慢,但没想到会慢到如此地步,下图是拼接50000个字符:      当拼接500000个字符时,执行结果为:      出现这个结果的原因是:第一是字符串是不可变的,每次字符串变量的内容发生改变时,都必须重新分配内存。阅读全文
posted @ 2010-12-25 09:26 魏志飞 阅读(100) 评论(0) 编辑
摘要: 今天小组一同学做网站时,遇到一个关于"margin-top”兼容问题:有两个div,其中div1嵌套div2,而在div2里面设置margin-top后,在IE8、ff和chrome下显示的效果竟然不是想要出现的结果,而在IE7下面效果正确。而在以前用的时候,从不记得margin也需要不同的浏览器对其进行兼容设置。并且还是在不太支持web标准的IE7下面都可以,其他支持WEB标准的都出现问题。难道是web标准就是这样,曾一度怀疑经常用的“盒子”方法是错误的。后来在网上找了一下才发现以前学习的时候竟然忽略了”折叠margin”。阅读全文
posted @ 2010-12-05 11:39 魏志飞 阅读(992) 评论(5) 编辑
摘要: 1. 外观模式:应该让一个软件中的子系统间的通信和相互依赖关系达到最小,而具体办法就是引入一个外观对象,它为子系统间提供了一个单一而简单的屏障。2. 代理与外观的主要区别在于,代理对象代表一个单一对象而外观对象代表一个子系统:代理的客户对象无法直接访问目标对象,由代理提供对单独的目标对象的访问控制,而外观的客户对象可以直接访问子系统中的各个对象,但通常由外观对象提供对子系统各元件功能的简化的共同层...阅读全文
posted @ 2010-11-14 21:09 魏志飞 阅读(45) 评论(0) 编辑
摘要: 一、cookie机制和session机制的区别 ************************************************************************************* 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于才服务器端保持状态的方案在客户端也需要保存一个标识...阅读全文
posted @ 2008-09-04 20:12 魏志飞 阅读(100) 评论(0) 编辑
posted @ 2008-08-27 15:46 魏志飞 阅读(160) 评论(0) 编辑
2010年12月25日

  最近重新复习了一个c#基础知识,在测试StringBuilder与字符串连接的比较时,没想到二者的差距竟然如此之大,用StringBuilder连接字符50000次竟然是0毫秒,而用字符串连接为1750毫秒。当连接500000次的结果差距更不用说了,下面总结一下学习c#的一些知识点:

1.StringBuilder与字符串连接比较 

 1     Console.WriteLine("String routine");
 2      string a = "a";
 3      string str = string.Empty;
 4      int istart, istop;
 5      istart = Environment.TickCount & Int32.MaxValue;
 6      Console.WriteLine("Start: " + istart);
 7      for (int i = 0; i < 50000; i++)
 8      {
 9          str += a;
10      }
11      istop = Environment.TickCount;
12      Console.WriteLine("Stop: " + Environment.TickCount);
13      Console.WriteLine("Difference: " + (istop - istart));
14      Console.WriteLine("StringBuilder routine");
15      StringBuilder builder = new StringBuilder();
16      istart = Environment.TickCount & Int32.MaxValue;
17      Console.WriteLine("Start: " + istart);
18      for (int i = 0; i < 50000; i++)
19      {
20          builder.Append(a);
21      }
22      istop = Environment.TickCount;
23      str = builder.ToString();
24      Console.WriteLine("Stop: " + Environment.TickCount);
25      Console.WriteLine("Difference: " + (istop - istart));
26      Console.Read(); 

   执行结果却大吃一惊,知道用字符串拼接速度慢,但没想到会慢到如此地步,下图是拼接50000个字符:

 

      

 

  当拼接500000个字符时,执行结果为: 

     

  出现这个结果的原因是:第一是字符串是不可变的,每次字符串变量的内容发生改变时,都必须重新分配内存。例如上面迭代50000次的循环,每次迭代都将一个字符连接到字符串,这样,内存中最终将有50000个字符串,每个字符串与其前面的字符串想比只差1个字符,第二是StringBuilder类是通过分配一个工作区解决这个问题,并在这个工作区中可以对字符串进行追加、插入、删除、移除和替换等操作。也就是说所有的操作都在一个缓存中进行,不需要任何内存分配,所以速度还是明显不一样。。。

2. 深拷贝和浅拷贝

 1      test mytest = new test("Joanna");
 2      mytest.Age = 36;
 3      test clone1 = (test)mytest.Clone(); //浅拷贝
 4      test clone2 = mytest;   //深拷贝
 5      Console.WriteLine(Object.ReferenceEquals(mytest.Name, clone1.Name));     //true
 6      Console.WriteLine(Object.ReferenceEquals(mytest.Name, clone2.Name));     //true
 7      Console.WriteLine(Object.ReferenceEquals(mytest.Age, clone1.Age));       //false
 8      mytest.Name = "Julie";
 9      Console.WriteLine(Object.ReferenceEquals(mytest.Name, clone1.Name));     //false
10      Console.WriteLine(Object.ReferenceEquals(mytest.Name, clone2.Name));     //true 
11      Console.WriteLine(Object.ReferenceEquals(mytest.Age, clone2.Age));       //false
12      Console.Read(); 

 类代码如下: 

 13     public class test : ICloneable
 14     {
 15         public int Age;
 16         public String Name;
 17         public test(string myname)
 18         {
 19             Name = myname;
 20         }
 21         public object Clone()
 22         {
 23             return MemberwiseClone();
 24         }
 25     }

 从上面代码中我们可以看出如下几点:

(1)当字段为引用类型时,不是深拷贝还是浅拷贝,指针都指向同一个地址,如上面代码中的5和6的比较。

        (2)当字段为值类型时,不管是浅拷贝还是深拷贝,指针指向都为不同的地址,如上面代码中的9和11的比较。

(3)当字符串不同时,浅拷贝指向的指针和原来的指针不同,如“9”,深拷贝指向的还是为同一个地址如“11”

出现这种情况的原因如下:

(1) 浅拷贝创建原对象类型的一个新实例,然后将原对象的非静态字段复制到新对象。对于引用类型字段,则只复制指向该值的指针。因些,拷贝的对象和原对象指向相同的引用对象。

(2)深拷贝是复制所有字段,它会创建引用对象的副本,并在副本中提供这些对象的引用。

(3)CLR还在内存中预留了拘留池,是为了避免存储重复的字符串值。在为字符串变量赋值时,先检查字符串值在拘留池中是否存在指向该字符串的指针,如果存在,则把指针指向已有的对象,如果不存在,则另开辟一块内存,用来存储字符串,将指针指向该内存地址,并将拘留池中的指针也指向该内存地址。这也是为什么字符串不同时,浅拷贝与深拷贝的指向的地址也会不同。

3.值类型和引用类型:

(1)内存分配:引用类型分配到堆中,而值类型分配到线程栈或调用栈中。创建引用类型时,会初始化为null,表示它不指向任何数据,值类型则初始化为0.

(2)内存释放:变量超出其作用域时,会释放栈中的内存,而堆内存达到系统内存的下限阈值时,会启动垃圾回收机制,释放堆中内存。

(3)变量赋值:变量设置为引用类型时,它会接收指向原对象的一个指针,而不是对象值本身,变量设置为值类型时,会逐字段地复制原变量,并赋给新变量。 

            

 

 

 

 

 

posted @ 2010-12-25 09:26 魏志飞 阅读(100) 评论(0) 编辑
2010年12月5日
摘要: 今天小组一同学做网站时,遇到一个关于"margin-top”兼容问题:有两个div,其中div1嵌套div2,而在div2里面设置margin-top后,在IE8、ff和chrome下显示的效果竟然不是想要出现的结果,而在IE7下面效果正确。而在以前用的时候,从不记得margin也需要不同的浏览器对其进行兼容设置。并且还是在不太支持web标准的IE7下面都可以,其他支持WEB标准的都出现问题。难道是web标准就是这样,曾一度怀疑经常用的“盒子”方法是错误的。后来在网上找了一下才发现以前学习的时候竟然忽略了”折叠margin”。阅读全文
posted @ 2010-12-05 11:39 魏志飞 阅读(992) 评论(5) 编辑
2010年11月14日
1. 外观模式:应该让一个软件中的子系统间的通信和相互依赖关系达到最小,而具体办法就是引入一个外观对象,它为子系统间提供了一个单一而简单的屏障。
2. 代理与外观的主要区别在于,代理对象代表一个单一对象而外观对象代表一个子系统:代理的客户对象无法直接访问目标对象,由代理提供对单独的目标对象的访问控制,而外观的客户对象可以直接访问子系统中的各个对象,但通常由外观对象提供对子系统各元件功能的简化的共同层次的调用接口。
3. 适配器模式:主要是为了解决两个已有接口之间不匹配的问题,我不需要考虑这些接口是怎样实现的,也不考虑它们各自可能会如何演化。不需要对两个独立设计的类中任一个进行重新设计,就能够使它们协同工作。
4. 观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
5. 状态模式:允许一个对象在其内部状态改变时改变它的行为,让对象看起来似乎修改了它的类。
6. 代码重复是编程中最常见、最糟糕的“坏味道”,如果我们在一个以上的地方看到相同的程序结构,那么可以肯定,设法将它们合二为一,程序会变得更好。完全相同的代码当然存在明显的重复,而微妙的重复会出现在表面不同但是本质相同的结构或处理步骤中。
7. 只要是在做面向对象的开发,创建对象的工作不可避免。创建对象时,负责创建实体通常需要了解要创建的是哪个具体的对象,以及何时创建这个而非那个对象的规则。而我们如果希望遵循开放封闭原则、依赖倒转原则和里氏代换原则,那使用对象时,就不应该知道所用的是哪一个特选的对象。此时就需要“对象管理者”工厂来负责此事。
8. 所有类都有构造方法,如果不编码则系统默认生成空的构造方法,若你有定义的构造方法,那么默认的构造方法就会失效。
9. 用户是如何浏览你的网站的
a) 大部分时候用户并非在阅读屏幕上的内容,而是在扫视。   用户习惯扫视和快速寻找页面上一些能够引导他理解内容的关键点。
b) 不要考验用户的耐心
  当一个页面不能满足用户的期望时,离开就在所难免。希望通过添加相关内容来丰富页面和留住用户往往效果不佳甚至适得其反。一屏页面上承载的信息越多,认知的负担就会越重,就需要花费更多的时间去处理信息,如果这些信息中还有些不是用户期望的,那就还要花额外的精力将这些多于信息从注意力中剥离。Jakbo Nielsen 的研究结论也表明:一个页面上的认识负担越重,导航和浏览就会越困难,用户离开并寻找其他替代品的可能性就越大。
c) 用户并不做最佳选择
  用户并不是在搜寻找到最佳选项的最快途径,他们也并非用线性的方式来阅读屏幕上的内容(有顺序地从一个模块到另一个模块)。当用户找到第一个合理的选项,或者一旦找到了可能的目标内容,立即点击的可能性会非常大。其实,用户是在寻找能让他们觉得够用或者合适的内容,而非寻找最佳的选择,理由也很直观,让用户自己去做最佳选择需要花费不少时间和精力,那已经在考验用户的耐心了(选择即成本)。
10. 抽象类不能实例化,抽象方法是必须被子类重写的方法,如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法。抽象类拥有尽可能多的共同代码,拥有尽可能少的数据。
11. 抽象类通常代表一个抽象概念,它提供一个继承的出发点,当设计一个新的抽象类时,一定是用来继承的,所以,在一个以继承关系形成的等级结构里面,树叶节点应当是具体类,而树枝节点均应当是抽象类。
12. 抽象类可以给出一些成员的实现,接口却不包含成员的实现,抽象类的抽象成员可被子类部分实现,接口的成员需要实现类完全实现,一个类只能继承一个抽象类,但可实现多个接口等等。①类是对对象的抽象;抽象类是对类的抽象;接口是对行为的抽象。②如果行为跨越不同类的对象,可使用接口;对于一些相似的类对象,用继承抽象类。③从设计角度讲,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知子类的存大,方法如何实现还不确认,预先定义。
13. .NET Framework提供了用于数据存储和检索的专用类,这些类统称集全。这些类提供对堆栈、队列、列表和哈希表的支持。大多数集合类实现相同的接口。
14. 委托是对函数的封闭,可以当作给方法的特征指定一个名称,而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。
15. 愚弄我一次,是你错;愚弄我两次,是我蠢
16. 墨菲准则 :可能会出错的地方就一定会出错。
17. 从设计角度讲,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知子类的存大,方法如何实现还不确认,预先定义。即抽象类是自底而上抽象出来的,而接口则是自顶向下设计出来的。
18. 设计模式描述了软件设计过程中某一类常见的一般性的解决方案。
19. 原代码就是设计。
posted @ 2010-11-14 21:09 魏志飞 阅读(45) 评论(0) 编辑
2008年9月4日
一、cookie机制和session机制的区别 *************************************************************************************
具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session 机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择 *************************************************************************************
 二、会话cookie和持久cookie的区别 *************************************************************************************
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。  如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。  存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。 *************************************************************************************
三、如何利用实现自动登录 *************************************************************************************   
当用户在某个网站注册后,就会收到一个惟一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务器上的资源。 *************************************************************************************
四、如何根据用户的爱好定制站点 *************************************************************************************   
网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。 *************************************************************************************
五、cookie的发送 *************************************************************************************
1.创建Cookie对象 2.设置最大时效 3.将Cookie放入到HTTP响应报头如果你创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie:存储在浏览器的内存中,用户退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个Set-Cookie HTTP请求报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此我们将这个方法称为是addCookie,而非setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。
*************************************************************************************
六、cookie的读取 *************************************************************************************
1.调用request.getCookie 要获取有浏览器发送来的cookie,需要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。 2.对数组进行循环,调用每个cookie的getName方法,直到找到感兴趣的cookie为止 cookie与你的主机(域)相关,而非你的servlet或JSP页面。因而,尽管你的servlet可能只发送了单个cookie,你也可能会得到许多不相关的cookie。例如:  String cookieName = “userID”; Cookie cookies[] = request.getCookies(); if (cookies!=null){ for(int i=0;i 七、如何使用cookie检测初访者 *************************************************************************************
 A.调用HttpServletRequest.getCookies()获取Cookie数组 B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确 C.如果是则退出循环并设置区别标识 D.根据区别标识判断用户是否为初访者从而进行不同的操作 ************************************************************************************* 八、使用cookie检测初访者的常见错误 *************************************************************************************
不能仅仅因为cookie数组中不存在在特定的数据项就认为用户是个初访者。如果cookie数组为null,客户可能是一个初访者,也可能是由于用户将cookie删除或禁用造成的结果。但是,如果数组非null,也不过是显示客户曾经到过你的网站或域,并不能说明他们曾经访问过你的servlet。其它servlet、JSP页面以及非Java Web应用都可以设置cookie,依据路径的设置,其中的任何cookie都有可能返回给用户的浏览器。正确的做法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。 *************************************************************************************
九、使用cookie属性的注意问题 *************************************************************************************   
属性是从服务器发送到浏览器的报头的一部分;但它们不属于由浏览器返回给服务器的报头。   因此除了名称和值之外,cookie属性只适用于从服务器输出到客户端的cookie;服务器端来自于浏览器的cookie并没有设置这些属性。   因而不要期望通过request.getCookies得到的cookie中可以使用这个属性。这意味着,你不能仅仅通过设置cookie的最大时效,发出它,在随后的输入数组中查找适当的cookie,读取它的值,修改它并将它存回Cookie,从而实现不断改变的cookie值。 *************************************************************************************
十、如何使用cookie记录各个用户的访问计数 *************************************************************************************
1.获取cookie数组中专门用于统计用户访问次数的cookie的值 2.将值转换成int型 3.将值加1并用原来的名称重新创建一个Cookie对象 4.重新设置最大时效 5.将新的cookie输出 *************************************************************************************
十一、session在不同环境下的不同含义 *************************************************************************************
session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义。  session在Web开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。 *************************************************************************************
十二、session的机制 *************************************************************************************   session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session id,如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。如果客户请求不包含session id,则为此客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。 *************************************************************************************
十三、保存session id的几种方式 *************************************************************************************
A.保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。 B.由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。 C.另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。 ************************************************************************************* 十四、session什么时候被创建 *************************************************************************************
一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。 *************************************************************************************
十五、session何时被删除 *************************************************************************************
session在下列情况下被删除: A.程序调用HttpSession.invalidate() B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间 C.服务器进程被停止 再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。 *************************************************************************************
十六、URL重写有什么缺点 *************************************************************************************    
对所有的URL使用URL重写,包括超链接,form的action,和重定向的URL。每个引用你的站点的URL,以及那些返回给用户的URL(即使通过间接手段,比如服务器重定向中的Location字段)都要添加额外的信息。   这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此,每个页面都必须使用servlet或JSP动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签或链接再次回来,会话的信息都会丢失,因为存储下来的链接含有错误的标识信息-该URL后面的SESSION ID已经过期了。   *************************************************************************************
十七、使用隐藏的表单域有什么缺点 *************************************************************************************
仅当每个页面都是有表单提交而动态生成时,才能使用这种方法。单击常规的超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程 *************************************************************************************
十八、会话跟踪的基本步骤 *************************************************************************************
1.访问与当前请求相关的会话对象 2.查找与会话相关的信息 3.存储会话信息 4.废弃会话数据 *************************************************************************************
十九、getSession()/getSession(true)、getSession(false)的区别 *************************************************************************************
getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象 getSession(false):当session存在时返回该session,否则不会新建session,返回null *************************************************************************************
 二十、如何将信息于会话关联起来 *************************************************************************************   setAttribute会替换任何之前设定的值;如果想要在不提供任何代替的情况下移除某个值,则应使用removeAttribute。这个方法会触发所有实现了HttpSessionBindingListener接口的值的valueUnbound 方法。 *************************************************************************************
二十一、会话属性的类型有什么限制吗 *************************************************************************************
通常会话属性的类型只要是Object就可以了。除了null或基本类型,如int,double,boolean。如果要使用基本类型的值作为属性,必须将其转换为相应的封装类对象 *************************************************************************************
 二十二、如何废弃会话数据 *************************************************************************************
A.只移除自己编写的servlet创建的数据: 调用removeAttribute(“key”)将指定键关联的值废弃 B.删除整个会话(在当前Web应用中): 调用invalidate,将整个会话废弃掉。这样做会丢失该用户的所有会话数据,而非仅仅由我们 servlet或JSP页面创建的会话数据 C.将用户从系统中注销并删除所有属于他(或她)的会话 调用logOut,将客户从Web服务器中注销,同时废弃所有与该用户相关联的会话(每个Web应用至多一个)。这个操作有可能影响到服务器上多个不同的Web应用 *************************************************************************************
二十三、使用isNew来判断用户是否为新旧用户的错误做法 *************************************************************************************
public boolean isNew()方法如果会话尚未和客户程序(浏览器)发生任何联系,则这个方法返回true,这一般是因为会话是新建的,不是由输入的客户请求所引起的。但如果isNew返回false,只不过是说明他之前曾经访问该Web应用,并不代表他们曾访问过我们的servlet或JSP页面。因为session是与用户相关的,在用户之前访问的每一个页面都有可能创建了会话。因此isNew为false只能说用户之前访问过该Web应用,session可以是当前页面创建,也可能是由用户之前访问过的页面创建的。正确的做法是判断某个session中是否存在某个特定的key且其value是否正确 *************************************************************************************
二十四、Cookie的过期和Session的超时有什么区别 *************************************************************************************
会话的超时由服务器来维护,它不同于Cookie的失效日期。首先,会话一般基于驻留内存的cookie 不是持续性的cookie,因而也就没有截至日期。即使截取到JSESSIONID cookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。 *************************************************************************************
二十五、session cookie和session对象的生命周期是一样的吗 *************************************************************************************
当用户关闭了浏览器虽然session cookie已经消失,但session对象仍然保存在服务器端 *************************************************************************************
二十六、是否只要关闭浏览器,session就消失了 *************************************************************************************
程序一般都是在用户做log off的时候发个指令去删除session,然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭,因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。之所以会有这种错误的认识,是因为大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接到服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求报头,把原来的session id发送到服务器,则再次打开浏览器仍然能够找到原来的session。恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。  由此我们可以得出如下结论:  关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。 *************************************************************************************
二十七、打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session *************************************************************************************
通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的session id,这样我们信息共享的目的就达不到了。此时我们可以先把session id保存在persistent cookie中(通过设置session的最大有效时间),然后在新窗口中读出来,就可以得到上一个窗口的session id了,这样通过session cookie和persistent cookie的结合我们就可以实现了跨窗口的会话跟踪。 *************************************************************************************
 二十八、如何使用会话显示每个客户的访问次数 *************************************************************************************
由于客户的访问次数是一个整型的变量,但session的属性类型中不能使用int,double,boolean等基本类型的变量,所以我们要用到这些基本类型的封装类型对象作为session对象中属性的值  但像Integer是一种不可修改(Immutable)的数据结构:构建后就不能更改。这意味着每个请求都必须创建新的Integer对象,之后使用setAttribute来代替之前存在的老的属性的值。例如: HttpSession session = request.getSession(); SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”); if (value= =null){ value = new SomeImmutableClass(…); // 新创建一个不可更改对象 }else{ value = new SomeImmutableClass(calculatedFrom(value)); // 对value重新计算后创建新的对象 } session.setAttribute(“someIdentifier”,value); // 使用新创建的对象覆盖原来的老的对象 *************************************************************************************
二十九、如何使用会话累计用户的数据 *************************************************************************************
使用可变的数据结构,比如数组、List、Map或含有可写字段的应用程序专有的数据结构。通过这种方式,除非首次分配对象,否则不需要调用setAttribute。例如 HttpSession session = request.getSession(); SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”); if(value = = null){ value = new SomeMutableClass(…); session.setAttribute(“someIdentifier”,value); }else{ value.updateInternalAttribute(…); // 如果已经存在该对象则更新其属性而不需重新设置属性 } *************************************************************************************
三十、不可更改对象和可更改对象在会话数据更新时的不同处理 *************************************************************************************
不可更改对象因为一旦创建之后就不能更改,所以每次要修改会话中属性的值的时候,都需要调用setAttribute(“someIdentifier”,newValue)来代替原有的属性的值,否则属性的值不会被更新可更改对象因为其自身一般提供了修改自身属性的方法,所以每次要修改会话中属性的值的时候,只要调用该可更改对象的相关修改自身属性的方法就可以了。这意味着我们就不需要调用setAttribute方法了 *************************************************************************************
posted @ 2008-09-04 20:12 魏志飞 阅读(100) 评论(0) 编辑