Web架构特性及REST架构风格(部分内容摘自网络)
良好的Web架构风格:
1. 客户/服务器模式: 实现了UI与数据的分离。
2. 服务端无状态性: 可见性,可靠性,可伸缩性等方面的改善。
可见性-无状态性使得服务器不必要维护海量的上下文(Context)。
可靠性-无状态性减少了服务器从局部错误中恢复的任务量。
可伸缩性-无状态性使得服务器可以很容易的释放资源。
3. 缓存: 减少服务端不必要的处理。
4. 可伸缩性: 便于分布式和集群部署。
上面的2,3点也是影响4的主要因素。而随着系统用户规模的指数上升,可伸缩性将变的至关重要。
现在大多数应用程序都忽略或者违反了上述2, 3的风格。当然也肯定失去了4带来的好处。
比如Java Servlet中HttpSession的应用,使服务器端保存了客户端的状态。
时下流行的动态页面的做法也使得资源缓存变得困难或者不可能。
这些都直接影响了应用的可伸缩性。
改善现状的思路是,把服务端的处理和状态前移,由客户端来实现。使服务端回归到无状态的特性。
以采用ajax技术的应用系统为例:因为不需要完全刷新就可以与服务器进行交互,使得有状态客户机成为可用选择。基于浏览器的应用程序代码可以在必要时获取新的服务器数据,并把这些数据织入当前页面。
将处理和状态前移到每个客户机上后,实现了无状态的服务端;同时缓存服务器可以缓存ajax引擎(比如dojo, prototype etc.),以及状态无关的数据。
个人理解,多种浏览器的plug-in技术(Sun的applet, MS的ActiveX等等),都应该是这种思路的不同技术实现。
经过以上分析整理,实际上已经涉及到了时下流行的一个概念-REST.
REST(Representational State Transfer)来源于Dr. Roy Thomas Fielding, <Architectural Styles and the Design of Network-based Software Architectures>
当浏览器浏览访问一个url资源时,返回的页面即为该url资源的representation,这个representation给浏览器一个state,当
浏览器访问下一个url资源时,浏览器的state就transfer了。
REST其本身只是为分布式超媒体系统(distributed hypermedia systems)设计的一种架构风格,而不是某个标准,框架。
REST的设计准则
1.网络上的所有事物都被抽象为资源(resource);
2.每个资源对应一个唯一的资源标识符(resource identifier);
3.通过通用的连接器接口(generic connector interface)对资源进行操作;
4.对资源的各种操作不会改变资源标识符;
5.所有的操作都是无状态的(stateless)。
REST中的资源所指的不是数据,而是数据和表现形式的组合。
REST是基于Http协议的,任何对资源的操作行为都是通过Http协议来实现。以往的Web开发大多数用的都是Http协议中的GET和POST方法,对其他方法很少使用,这实际上是因为对Http协议认识片面的理解造成的。Http不仅仅是一个简单的运载数据的协议,而是一个具有丰富内涵的网络软件的协议。他不仅仅能对互联网资源进行唯一定位,而且还能告诉我们如何对该资源进行操作。Http把对一个资源的操作限制在4个方法以内:GET, POST,PUT和DELETE,这正是对资源CRUD操作的实现。由于资源和URI是一一对应的,执行这些操作的时候URI是没有变化的,这和以往的 Web开发有很大的区别。正由于这一点,极大的简化了Web开发,也使得URI可以被设计成更为直观的反映资源的结构,这种URI的设计被称作 RESTful的URI。这位开发人员引入了一种新的思维方式:通过URL来设计系统结构。当然了,这种设计方式对一些特定情况也是不适用的,也就是说不是所有的URI都可以RESTful的。
REST 之所以可以提高系统的可伸缩性,就是因为它要求所有的操作都是无状态的。由于没有了上下文(Context)的约束,做分布式和集群的时候就更为简单,也可以让系统更为有效的利用缓冲池(Pool)。并且由于服务器端不需要记录客户端的一系列访问,也减少了服务器端的性能。
Java语言编程中更新XML文档的四种方法。第一种方法是直接读写XML文件。第二种方法是使用Apache
Crimson的XmlDocument类,这种方法极为简单,使用方便,如果你选用Apache
Crimson作为XML解析器,那么不妨使用这种方法,不过这种方法似乎效率不高(源于效率低下的Apache
Crimson),另外,高版本的JAXP或者是Java XML Pack、JWSDP不直接支持Apache
Crimson,亦即这种方法不通用。第三种方法是使用JAXP的XSLT引擎(Transformer类)来输出XML文档,这种方法也许是标准的方法
了,使用起来十分灵活,特别是可以自如控制输出格式,我们推荐采用这种方法。第四种方法是第三种方法的变种,采用了Xalan XML
Serializer,引入了串行化操作,对于大量文档的修改/输出有优越性,可惜的是要重复设置XSLT引擎的属性和XML
Serializer的输出属性,比较麻烦,而且依赖于Apache Xalan和Apache Xerces技术,通用性略显不足。除此之外,实际上应用别的API(比如dom4j、JDOM、Castor、XML4J、Oracle XML Parser V2)也有很多办法可以更新XML文档。
概念介绍
Xerces/Crimson是XML解析器,Xalan是XSLT处理器,xml-apis.jar实际上是JAXP。
Apache Crimson的前身是Sun Project X Parser, 至今Apache Crimson的很多代码都是从X Parser中直接移植过来的。早期的JAXP是和X Parser捆绑在一起的。后来的 JAXP和Apache Crimson捆绑在一起,比如JAXP 1.1。最新的JAXP 1.2 EA(Early Access)改弦更张,采用性能更好的Apache Xalan和Apache Xerces分别作为XSLT处理器和XML解析器,不能直接支持Apache Crimson了。
dom4j(dom4j.jar)是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML
API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM
developerWorks上面可以找到一篇文章,对主流的Java XML
API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。
.NET垃圾收集器的过去、现在和未来(一)
Patrick Dussud介绍:
Patrick Dussud在微软工作了11年,曾经负责VBA、Jscript、MS Java等语言运行时的垃圾收集器(Garbage Collector)的设计,目前负责.NET CLR垃圾收集器的设计。他是.NET CLR的架构师,WinFX的首席架构师,Windows架构师组的成员。
在微软之前,Patrick是德州仪器(TI)Explorer工作站系统的主要设计人,Lucid公司Energize产品的首席架构师。
关键内容摘要
1. 微管理 / 内存的显式管理 --- 手动内存管理(new/delete)
你必须保证在释放之前内存没有被别人使用,如果你把内存给了别人,往往你就不确定应该何时释放内存了。当你释放了内存,不知道别人正在使用这块内存时,就产生了程序崩溃的问题。所以,当你显式进行“new”和“delete”时,内存管理是一个复杂的问题,并且,此时你的代码不可组合。要么你必须确定对自己的内存有完全的控制,因此,要达到这种完全隔离的目的,你必须在将内存传递给别的模块时进行完全拷贝,这样,别的模块就只对这个完全拷贝的内存负责。要么你就得在某个地方形成对整个内存池的统一的管理,这就是自动化内存管理,这就是垃圾收集器的工作。
2. 对象终止器的调用时机由垃圾收集器决定,这些对象的析构函数被调用的先后顺序是无法预先确定的。提出了“关键终止化对象”的概念。当有一系列对象需要终止化时,关键终止化对象最后被终止化,直到上层对象干完工作前。
3. 工作机理: 垃圾收集器首先遍历所有的栈和静态变量,然后返回最初的树集。然后遍历树集对程序能够到达的每一个对象作标记。此时,我们就能逐个对象地检查内存,发现它被标记了,好的,留下。没有被标记?喔,我们有一个垃圾了。
4. 垃圾收集器的绝大部分速度和效率都来源于对回收策略的调整。通过保持内存紧凑,形成缓存本地化,页面本地化等等优势,很可能其效率甚至高于传统“new”和“delete” 操作,尤其是对于非常难以管理的服务器内存来说更是如此。
如下代码:
class A{
public void foo(){print("aaaaa");}
}
class B extends A{
public void foo(){print("bbbbb");}
}
如果想通过B的实例化变量来调用被override的父类的方法foo():
B b = new B();
在C++中(VC 6)可以两种途径;
1. ((A)b).foo();
2. A a = B();
在java中类似做法则行不通,依然访问的是子类方法。
而且,在java中好像达不到这个目的。
web常用的功能性测试方法
发布时间: 2007-9-20 12:13 作者: 未知 来源: 网络转载
1. 页面链接检查:每一个链接是否都有对应的页面,并且页面之间切换正确。
2. 相关性检查:删除/增加一项会不会对其他项产生影响,如果产生影响,这些影响是否都正确。
3. 检查按钮的功能是否正确:如update、cancel、delete、save等功能是否正确。
4. 字符串长度检查:输入超出需求所说明的字符串长度的内容,看系统是否检查字符串长度,会不会出错。
5. 字符类型检查:在应该输入指定类型的内容的地方输入其他类型的内容(如在应该输入整型的地方输入其他字符类型),看系统是否检查字符类型,会否报错。
6. 标点符号检查:输入内容包括各种标点符号,特别是空格、各种引号、回车键。看系统处理是否正确。
7. 中文字符处理:在可以输入中文的系统输入中文,看会否出现乱码或出错。
8. 检查带出信息的完整性:在查看信息和update信息时,查看所填写的信息是不是全部带出,带出信息和添加的是否一致。
9. 信息重复:在一些需要命名,且名字应该唯一的信息输入重复的名字或ID,看系统有没有处理,会否报错,重名包括是否区分大小写,以及在输入内容的前后输入空格,系统是否作出正确处理。
10. 检查删除功能:在一些可以一次删除多个信息的地方,不选择任何信息,按”delete”,看系统如何处理,会否出错;然后选择一个和多个信息,进行删除,看是否正确处理。
11. 检查添加和修改是否一致:检查添加和修改信息的要求是否一致,例如添加要求必填的项,修改也应该必填;添加规定为整型的项,修改也必须为整型。
12. 检查修改重名:修改时把不能重名的项改为已存在的内容,看会否处理,报错。同时,也要注意,会不会报和自己重名的错。
13. 重复提交表单:一条已经成功提交的纪录,back后再提交,看看系统是否做了处理。
14. 检查多次使用back键的情况:在有back的地方,back,回到原来页面,再back,重复多次,看会否出错。
15. search检查:在有search功能的地方输入系统存在和不存在的内容,看search结果是否正确。如果可以输入多个search条件,可以同时添加合理和不合理的条件,看系统处理是否正确。
16. 输入信息位置:注意在光标停留的地方输入信息时,光标和所输入的信息会否跳到别的地方。
17. 上传下载文件检查:上传下载文件的功能是否实现,上传文件是否能打开。对上传文件的格式有何规定,系统是否有解释信息,并检查系统是否能够做到。
18. 必填项检查:应该填写的项没有填写时系统是否都做了处理,对必填项是否有提示信息,如在必填项前加*
19. 快捷键检查:是否支持常用快捷键,如Ctrl+C Ctrl+V Backspace等,对一些不允许输入信息的字段,如选人,选日期对快捷方式是否也做了限制。
20. 回车键检查:在输入结束后直接按回车键,看系统处理如何,会否报错。
调整完/usr的挂载点后,出现了一个奇怪的现象,原来正确的系统时钟现在出故障了,提前了8个小时。
鼓掌现象具体表现为:每次启动系统,ubuntu会用BIOS的时间+8后作为系统时钟,同时会把新的时间重新同步到BIOS中。所以每启动一次,时间就会快进8小时。很是怪异。
网上一通google才搞定。
原因是因为/usr的挂载时间被滞后了,由于/etc/localtime(时区信息)是连接到/usr/share/zoneinfo/下的某个设定好的时区文件。在系统获取时区信息时/usr尚未挂载,所以系统始终就错了。
修复办法很简单:
1. rm /etc/localtime(取消原来的符号连接)
2. 把/usr/share/zoneinfo/下的某个设定好的时区文件copy到/etc/localtime.
3. 重新启动,故障消除。
相关概念:
UTC(Universal Time Coordinated) = GMT (Greenwich Mean Time)
hwclock : query and set the hardware clock (RTC)
hwclock通过/etc/default/rcS的UTC(=yes/no)来认定BIOS时钟是UTC还是localtime。
参考文章:
http://blog.chinaz.com/u1/5830/archives/2006/36628.shtml
昨天由于ubuntu的/分区空间紧张,决定把/usr挂载到别的分区。
挂载步骤(root权限执行):
1. init 1 -- 切换到单用户模式。
2. cp -ax /usr/* /mnt/tmp (tmp为新的/usr分区)。 -- 拷贝现在/usr下的内容到待切换的分区。
3. ls -l /dev/disk/by-uuid -- 查看分区的UUID。
4. 修改/etc/fstab中/usr的挂载方式,挂接到新的/usr分区。
5. mv /usr /usr.old -- 重命名现有的/usr为/usr.old, 为第6步做准备,重启动后可以删除之。
6. mkdir /usr -- 创建新的/usr挂载点,启动时自动挂载/usr分区到此处。
7. restart
/home 分区是最常移动的分区之一。某些时候,/home
中的全部空间都用完了,而且需要增加一个硬盘驱动器。另一些时候,/home
被设置为根分区的一部分,为了提高性能或便于备份,可能需要将它移动到别的地方。我会针对每种情况说明如何安全有效地移动
/home。
please visit the address:
http://www.ibm.com/developerworks/cn/linux/l-tip-prompt/tip05/index.html
网上常见的推荐是tora. 地址: http://sourceforge.net/projects/tora/
但由于License关系,二进制版本剔除了对oracle的providor. 所以需要下载源码自己编译。
感觉比较麻烦。
最近又找到一个比较好的东东--
Aqua Data Studio。 (http://www.aquafold.com/index.html)
而且也有免费版本。
下载试用了一下,非常方便易用。
推荐给有此需要者。
如何临时增加交换空间。
1.产生一个64M的空文件
#dd if=/dev/zero of=/swapfile bs=1024 count=65536
2.初始化该文件为交换文件:
mkswap /swapfile 65536
sync
3.激活这个交换文件:
swapon /swapfile