马楠's profileThe colorful dayPhotosBlogListsMore ![]() | Help |
The colorful day |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
February 09 Oracle集群软件名词解释从 Oracle 10g RAC 开始,Oracle 已捆绑其自身的群集软件。初始发行版本称为 Oracle Cluster Ready Service (CRS)。CRS 用作通用术语时表示 《Oracle clusters software》,用作特定术语时表示 《Oracle clusters software》 中的一个组件。在后续发行版本中,Oracle 的通用 CRS 被重命名为 《Oracle Clusterware》。《Oracle Clusterware》 是通用术语,表示 《Oracle Cluster Software》。 Oracle Cluster Software 包括下列组件:Cluster Synchronization Services (CSS)、Cluster Ready Service (CRS) 和 Event Management (EVM)。 CSS 可管理 Oracle 群集成员并将其自身的组成员服务提供给 RAC 实例。当 SGeRAC 群集上安装了 CSS 时,CSS 就可以利用 SGeRAC 提供的组成员服务。 CRS 根据配置管理 Oracle 的群集资源,包括资源的启动、停止、监视和故障切换。 EVM 发布由 CRS 生成的事件,并且当特定事件发生时,可运行脚本。 如果安装在 SGeRAC 群集上,则 Oracle 群集软件和 RAC 均可继续利用共享存储功能、网络监视功能以及通过 Serviceguard 和 SGeRAC 提供的其他功能。 Oracle 10g RAC 将下列两个子网用于群集通信目的:
March 13 利用javascript判断浏览器是否已经安装ActiveX控件和是否禁止运行ActiveX控件利用javascript判断浏览器是否已经安装ActiveX控件和是否禁止运行ActiveX控件 从微软给IE打上SP2以后,当IE在打开一些含有ActiveX控件的网页是,不再像以前那样,弹出提示框,让用户选择是否安装控件;现在默认情况下给隐藏起来,普通用户根本不知道是怎么回事。公司产品同样也遇到这样的问题,唯一的办法就是将控件做成一个exe文件,供用户下载手动安装注册;这样就需要做一个检测,检测要是用户没有安装控件的话就提示用户用户下载安装,要是安装了就直接转到相关页面。想了很多办法,最后找到一种比较合理的解决方式。由于我们现在经常使用的ajax技术,它实际上就是一种com组件,通过接口实现发送请求和获取数据,那么我们要使用ajax,就必定要创建这样一个 com组件,所以我们可以从这里入手来解决检测普通控件是否被拦截的问题。 javascript创建ActiveX控件方式如下: function DetectActiveX() 只要控件已经安装,那么创建肯定会成功(如果IE设置为禁用ActiveX则会失败),如果控件没有安装则会失败。这是一种简单的检测方式。那么控件名称怎么知道呢?大家在写一个com组件的时候,都有一个对应的CLSID。打开自己的注册表(自己系统中已经安装了控件),在HKEY_CLASSESS_ROOT中查找,输入控件对应的CLSID,会在该目录下的一个叫CLSID的目录中找到对应控件的注册信息,打开该节点,其中有一项是ProgID,其对应的值就是创建该控件时所要用的名称,这样你就可以方便创建和检测你自己所设计的控件了。 由于IE不允许javascript访问系统功能,所以我们不能够对IE的相关设置做一个直接的访问,那么根据我们上面的检测试试,我们可以轻松的判定IE是否禁止运行ActiveX控件,这也是非常有用的一点,因为很多提示我们可能要提示用户由于什么什么原因,而导致不能使用某项ActiveX控件的功能。那么我们如何来进行判断呢,还记得我刚开始提到的ajax这个东西吧,这个东西不仅能带来更好的用户交互功能,同时也能够用在我们检测浏览器是否禁止运行ActiveX 控件目的上来。因为ajax是由相关的com组件支持,不管是IE,Firefox,Netscape,Opera等其他浏览器,都有相应的实现,因为了是浏览器的标准。所以我们只要写一个通用的,支持各种浏览器创建ajax 所要用到的xmlhttp对象即可,如果能创建成功,那么证明IE一切OK,如果不成功则给出提示,其检测函数相信大家已经再熟悉不过了,只不过我们现在的目的不一样了,呵呵。 function DisActiveX() 以上是在工作中的一些小经验,感觉挺实用的,和大家分享一下,我也是菜鸟一个,写不出来技术含量高的文章,但和大家分享便是一种快乐... January 25 Perl语言概述
ActiveX控件概述ActiveX是Microsoft提出的一组使用COM(Component Object Model,部件对象模型)使 得软件部件在网络环境中进行交互的技术集。它与具体的编程语言无关。作为针对Internet应 用开发的技术,ActiveX被广泛应用于WEB服务器以及客户端的各个方面。同时,ActiveX技术也被 用于方便地创建普通的桌面应用程序。 1.2. ActiveX的内容 ActiveX既包含服务器端技术,也包含客户端技术。其主要内容是: * ActiveX控制(ActiveX Control);用于向WEB页面、Microsoft Word等支持ActiveX 的容器(Container)中插入COM对象。 * ActiveX文档(ActiveX Document);用于在WEB Browser或者其它支持ActiveX的容器 中浏览复合文档(非HTML文档),例如Microsoft Word文档,Microsoft Excel文档或者用户自 定义的文档等。 * ActiveX脚本描述(ActiveX Scripting);用于从客户端或者服务器端操纵ActiveX控 制和Java程序,传递数据,协调它们之间的操作。 * ActiveX服务器框架(ActiveX Server Framework);提供了一系列针对WEB服务器应 用程序设计各个方面的函数及其封装类,诸如服务器过滤器、HTML数据流控制等。 * 在Internet Explorer中内置Java虚拟机(Java Virtual Machine),从而使Java Applet 能够在Internet Explorer上运行,并可以与ActiveX控制通过脚本描述语言进行通信。 1.3. ActiveX与Java的比较 ActiveX提供了一种扩展包括Java在内的任何编程语言的机制,Java的开发人员可以在Applet 中使用ActiveX技术,直接嵌入ActiveX控制,或者以ActiveX技术为桥梁,将其它开发商提 供的多种语言的程序对象集成到Java中。与Java的字节码技术相比,ActiveX提供了“代码签名” (Code Signing)技术保证其安全性。 1.4. Internet Explorer和Netscape Navigator 不言而喻,Microsoft的Internet Explorer全面支持ActiveX。同时,Microsoft提供了 Netscape Navigator的插件(Plug-In),从而使Navigator也可以浏览包含有ActiveX部件的WEB 站点。 2. ActiveX控制和Internet ActiveX控制是OLE控制的更新版本。控制(Control)是建立可编程部件(Component) 的主要元素。ActiveX控制可以用于所有支持COM规范的容器中,或者作为Internet控制嵌入到WEB 页面中。用户访问该页面时将下载该控制并自动在本地注册。利用脚本描述语言(Script)可 以在控制之间以及客户与服务器之间通过设置属性(Property)、调用方法(Method)和激活事 件(Event)进行通信。 ActiveX控制与以前的OLE控制相比,具有更少的接口,并且可以没有窗口。所有的ActiveX 控制都支持IUnknown接口。 目前,很多第三方开发商编制了各式各样的ActiveX控制。在Internet上,有超过1000个 ActiveX控制供用户下载使用。在WINDOWS的SYSTEM目录下,保存有很多Window提供的ActiveX控 制。Microsoft Visual C++(以下简称VC)提供的MFC(Microsoft Foundation Classes)控制 都是ActiveX控制。 考虑到当前Internet相对较低的传输速率,设计运行于Internet的ActiveX控制时,必须 考虑以下几个问题: * 控制尽可能小; * 持续存储数据(Persist Data)如何保存; * 如何在Internet上下载和安装; * 控制如何在客户端注册; 3. ActiveX文档和Internet ActiveX文档提供了传统的嵌入对象的扩展方法。ActiveX文档对象可以包含多个页,显 示在整个客户区中,并支持原有的菜单功能。与以往的嵌入对象不同的是,ActiveX文档对象不再 以一个阴影方框包围来显示,而是全框架(Full Frame),并总处于激活状态。 Microsoft Office97提供了Microsoft Office Binder,用来生成并浏览由Microsoft Word 、Microsoft Excel或者用户定义的ActiveX文档等构成的复合文档,每一种文档类型都可以 直接进行编辑修改。 ActiveX文档可以作为对象嵌入到WEB网页中,在WEB上发布。 4. ActiveX脚本描述语言 利用VBScript或者Microsoft JScript,可以向Web页面中加入可用于交互的ActiveX控制, 将数据预处理或者检验过程放在客户端进行,然后将结果传往WEB服务器。 5. ActiveX服务器框架 在WEB服务器上创建扩展应用程序,动态生成WEB页面。使用MFC提供的ISAPI类可以方便 地建立WEB服务器端的扩展应用程序。 January 24 AWK语言概述AWK 实用工具带有其自己的自包含语言,它是Unix/Linux 中也是任何环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)的最大功能取决于一个人所拥有的知识。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报 表,还有无数其他的功能。
AWK 是什么? 最简单地说,AWK 是一种用于处理文本的编程语言工具。AWK 实用工具的语言在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。在最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定 内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。
尽管操作可能会很复杂,但命令的语法始终是:
awk '{pattern + action}' 其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号 ({}) 不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。
了解字段
实用工具将每个输入行分为记录和字段。记录是单行的输入,而每条记录包含若干字段。默认的字段分隔符是空格或制表符,而记录的分隔符是换行。虽然在默认情况下将制表符和空格都看作字段分隔符(多个空格仍然作为一个分隔符),但是可以将分隔符从空格改为任何其它字符。
为了进行演示,请查看以下保存为 emp_names 的员工列表文件:
46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AR 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN 当 AWK 读取输入内容时,整条记录被分配给变量 。每个字段以字段分隔符分开,被分配给变量 、、 等等。一行在本质上可以包含无数个字段,通过字段号来访问每个字段。因此,命令 awk '{print ,,,,}' names 将会产生的打印输出是
46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AR 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN 值得注意的一项重要内容是,AWK 解释由空格分隔的五个字段,但当它打印显示内容时,在每个字段间只有一个空格。利用为每个字段指定了唯一号码的功能,您可以选择只打印特定的字段。例如,只打印每条记录的姓名时,只需选择第二个和第三个字段进行打印: $ awk '{print ,}' emp_names DULANEY EVAN DURHAM JEFF STEEN BILL FELDMAN EVAN SWIM STEVE BOGUE ROBERT JUNE MICAH KANE SHERYL WOOD WILLIAM FERGUS SARAH BUCK SARAH TUTTLE BOB $ 您还可以指定按任何顺序打印字段,而无论它们在记录中是如何存在的。因此,只需要显示姓名字段,并且使其顺序颠倒,先显示名字再显示姓氏: $ awk '{print ,}' emp_names EVAN DULANEY JEFF DURHAM BILL STEEN EVAN FELDMAN STEVE SWIM ROBERT BOGUE MICAH JUNE SHERYL KANE WILLIAM WOOD SARAH FERGUS SARAH BUCK BOB TUTTLE $ 使用模式
通过包含一个必须匹配的模式,您可以选择只对特定的记录而不是所有的记录进行操作。模式匹配的最简单形式是搜索,其中要匹配的项目被包含在斜线 (/pattern/) 中。例如,只对那些居住在阿拉巴马州的员工执行前面的操作:
$ awk '/AL/ {print ,}' emp_names EVAN DULANEY JEFF DURHAM BILL STEEN EVAN FELDMAN STEVE SWIM $ 如果您不指定要打印的字段,则会打印整个匹配的条目: $ awk '/AL/' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL $ 对同一数据集的多个命令可以用分号 (;) 分隔开。例如,在一行中打印姓名,而在另一行中打印城市和州名: $ awk '/AL/ {print , ; print ,}' emp_names EVAN DULANEY MOBILE AL JEFF DURHAM MOBILE AL BILL STEEN MOBILE AL EVAN FELDMAN MOBILE AL STEVE SWIM UNKNOWN AL $ 如果没有使用分号 (print ,,,),则会在同一行中显示所有内容。另一方面,如果分别给出两个打印语句,则会产生完全不同的结果: $ awk '/AL/ {print ,} {print ,}' emp_names EVAN DULANEY MOBILE AL JEFF DURHAM MOBILE AL BILL STEEN MOBILE AL EVAN FELDMAN MOBILE AL STEVE SWIM UNKNOWN AL PHOENIX AZ PHOENIX AZ UNKNOWN AR MUNCIE IN MUNCIE IN MUNCIE IN MUNCIE IN $ 只有在列表中找到 AL 时才会给出字段三和字段二。但是,字段四和字段五是无条件的,始终打印它们。只有第一组花括号中的命令对前面紧邻的命令 (/AL/) 起作用。 结果非常不便于阅读,可以使其稍微更清晰一些。首先,在城市与州之间插入一个空格和逗号。然后,在每两行显示之后放置一个空行:
$ awk '/AL/ {print , ; print ", ""n"}' emp_names EVAN DULANEY MOBILE, AL JEFF DURHAM
MOBILE, AL BILL STEEN
MOBILE, AL EVAN FELDMAN
MOBILE, AL STEVE SWIM
UNKNOWN, AL $ 在第四和第五个字段之间,添加一个逗号和一个空格(在引号之间),在第五个字段后面,打印一个换行符 (n)。在 AWK 打印语句中还可以使用那些可在 echo 命令中使用的所有特殊字符,包括: n(换行) t(制表) b(退格) f(进纸) r(回车) 因此,要读取全部五个最初由制表符分隔开的字段,并且也利用制表符打印它们,您可以编程如下 $ awk '{print "t""t""t""t"}' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AR 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN $ 通过连续设置多项标准并用管道 (|) 符号将其分隔开,您可以一次搜索多个模式匹配: $ awk '/AL|IN/' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN $ 这样可找到每个阿拉巴马州和印第安那州居民的匹配记录。但是在试图找出居住在亚利桑那州的人时,出现了一个问题: $ awk '/AR/' emp_names
46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AZ 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN $ 员 工 46026 和 46027 没有住在亚利桑那州;但是他们的名字中包含所搜索的字符序列。切记,当在 AWK 中进行模式匹配时,例如 grep、sed 或者大部分其他 Linux/Unix 命令,将在记录(行)中的任何位置查找匹配,除非指定进行其他操作。为解决这一问题,必须将搜索与特定字段联系起来。通过利用代字号 (?) 以及对特定字段的说明,可以达到这一目的,如下例所示: $ awk ' ? /AR/' emp_names 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AZ $ 代字号(表示匹配)的对应符号是一个前面带有感叹号的代字号 (!?)。这些字符通知程序,如果搜索序列没有出现在指定字段中,则找出与搜索序列相匹配的所有行: $ awk ' !? /AR/' names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN $ 在这种情况下,将显示第五个字段中没有 AR 的所有行 — 包括两个 Sarah 条目,这两个条目确实包含 AR,但却是在第三个字段而不是第五个字段中。 花括号和字段分隔符
括号字符在 AWK 命令中起着很重要的作用。出现在括号之间的操作指出将要发生什么以及何时发生。当只使用一对括号时:
{print ,} 括号间的所有操作同时发生。当使用多于一对的括号时:
{print }{print } 执行第一组命令,在该命令完成后执行第二组命令。注意以下两列清单的区别:
$ awk '{print ,}' names EVAN DULANEY JEFF DURHAM BILL STEEN EVAN FELDMAN STEVE SWIM ROBERT BOGUE MICAH JUNE SHERYL KANE WILLIAM WOOD SARAH FERGUS SARAH BUCK BOB TUTTLE $ $ awk '{print }{print }' names
EVAN DULANEY JEFF DURHAM BILL STEEN EVAN FELDMAN STEVE SWIM ROBERT BOGUE MICAH JUNE SHERYL KANE WILLIAM WOOD SARAH FERGUS SARAH BUCK BOB TUTTLE $ 要 利用多组括号进行重复查找,执行第一组中的命令直到完成为止;然后处理第二组命令。如果有第三组命令,则在第二组命令完成后执行它,以此类推。在所生成的 打印输出中,有两个分隔的打印命令,因此先执行第一个命令,随后执行第二个命令,这样导致每个条目显示在两行而不是一行中。 区分两个字段的字段分隔符不一定始终是空格;它可以是任何可识别的字符。为进行演示,假定 emp_names 文件利用冒号而不是制表符来分隔字段:
$ cat emp_names 46012:DULANEY:EVAN:MOBILE:AL 46013:DURHAM:JEFF:MOBILE:AL 46015:STEEN:BILL:MOBILE:AL 46017:FELDMAN:EVAN:MOBILE:AL 46018:SWIM:STEVE:UNKNOWN:AL 46019:BOGUE:ROBERT:PHOENIX:AZ 46021:JUNE:MICAH:PHOENIX:AZ 46022:KANE:SHERYL:UNKNOWN:AR 46024:WOOD:WILLIAM:MUNCIE:IN 46026:FERGUS:SARAH:MUNCIE:IN 46027:BUCK:SARAH:MUNCIE:IN 46029:TUTTLE:BOB:MUNCIE:IN $ 如果试图通过指定所需要的第二个字段来打印姓氏 $ awk '{print }' emp_names 您 最后会得到十二个空行。因为文件中没有空格,除了第一个字段之外没有可认别的字段。为解决这一问题,必须通知 AWK 是空格之外的另一个字符作为分隔符,有两种方法可通知 AWK 使用新的字段分隔符:使用命令行参数 -F,或在程序中指定变量 FS。两种方法的效果相同,只有一种例外情况,如下例所示:
$ awk '{print }' emp_names DURHAM
STEEN FELDMAN SWIM BOGUE JUNE KANE WOOD FERGUS BUCK TUTTLE $ $ awk -F: '{print }' emp_names
DULANEY DURHAM STEEN FELDMAN SWIM BOGUE JUNE KANE WOOD FERGUS BUCK TUTTLE $ 在第一个命令中,头一条记录返回不正确的空行,而其他结果正确。直到读取第二条记录时,才识别字段分隔符并正确地执行。通过使用 BEGIN 语句可以纠正这一缺点(在后文详述)。-F 的功能非常类似于 BEGIN,能够正确地读取第一条记录并按要求执行。 在本文开始处我曾提到,默认的显示/输出字段分隔符是空格。通过使用输出字段分隔符 (OFS) 变量,可以在程序中更改此特性。例如,要读取文件(由冒号分隔)并以短划线显示,则命令是
$ awk -F":" '{print ,,,,}' emp_names 46012-DULANEY-EVAN-MOBILE-AL 46013-DURHAM-JEFF-MOBILE-AL 46015-STEEN-BILL-MOBILE-AL 46017-FELDMAN-EVAN-MOBILE-AL 46018-SWIM-STEVE-UNKNOWN-AL 46019-BOGUE-ROBERT-PHOENIX-AZ 46021-JUNE-MICAH-PHOENIX-AZ 46022-KANE-SHERYL-UNKNOWN-AR 46024-WOOD-WILLIAM-MUNCIE-IN 46026-FERGUS-SARAH-MUNCIE-IN 46027-BUCK-SARAH-MUNCIE-IN 46029-TUTTLE-BOB-MUNCIE-IN $ FS 和 OFS 是(输入)字段分隔符和输出字段分隔符,它们只是一对可以在 AWK 实用工具中使用的变量。例如,要在打印时为每行编号,可以采用以下方式使用 NR 变量: $ awk -F":" '{print NR,,,}' emp_names 1 46012 DULANEY EVAN 2 46013 DURHAM JEFF 3 46015 STEEN BILL 4 46017 FELDMAN EVAN 5 46018 SWIM STEVE 6 46019 BOGUE ROBERT 7 46021 JUNE MICAH 8 46022 KANE SHERYL 9 46024 WOOD WILLIAM 10 46026 FERGUS SARAH 11 46027 BUCK SARAH 12 46029 TUTTLE BOB $ 找出员工号码处于 46012 和 46015 之间的所有行: $ awk -F":" '/4601[2-5]/' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL $ 添加文本 可以按照添加控制序列或其他字符的相同方式将文本添加到显示中。例如,要将分隔符从空格改为冒号,则命令是
awk '{print ":"":"":"":"}' emp_names > new_emp_names 在这种情况下,字符 (:) 包含在引号 ("/") 中,它被添加到每个字段之间。在引号之间的值可以是任何内容。例如,创建一个关于居住在阿拉巴马州的员工的外观类似数据库的显示:
$ awk ' ~ /AL/ {print "NAME: "", ""nCITY-STATE: "", ""n"}' emp_names NAME: DULANEY, EVAN
CITY-STATE: MOBILE, AL NAME: DURHAM, JEFF
CITY-STATE: MOBILE, AL NAME: STEEN, BILL
CITY-STATE: MOBILE, AL NAME: FELDMAN, EVAN
CITY-STATE: MOBILE, AL NAME: SWIM, STEVE
CITY-STATE: UNKNOWN, AL $ 数学操作 AWK 除了提供文本功能,还提供全部范围的算术操作符,包括以下符号:
+ 将数字相加 - 减 * 乘 / 除 ^ 执行指数运算 % 提供模 ++ 将变量值加一 += 将其他操作的结果分配给变量 — 将变量减一 -= 将减法操作的结果分配给变量 *= 分配乘法操作的结果 /= 分配除法操作的结果 %= 分配求模操作的结果 例如,假定您的机器上存在以下的文件,详细地列出硬件商店中的物品: $ cat inventory hammers 5 7.99 drills 2 29.99 punches 7 3.59 drifts 2 4.09 bits 55 1.19 saws 123 14.99 nails 800 .19 screws 80 .29 brads 100 .24 $ 第一项业务定单是通过将第二个字段(数量)的值乘以第三个字段(价格)的值,计算每种物品的库存价值: $ awk '{print ,"QTY: ","PRICE: ","TOTAL: "*}' inventory hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95 drills QTY: 2 PRICE: 29.99 TOTAL: 59.98 punches QTY: 7 PRICE: 3.59 TOTAL: 25.13 drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18 bits QTY: 55 PRICE: 1.19 TOTAL: 65.45 saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77 nails QTY: 800 PRICE: .19 TOTAL: 152 screws QTY: 80 PRICE: .29 TOTAL: 23.2 brads QTY: 100 PRICE: .24 TOTAL: 24 $ 如果这些行本身并不重要,您只是希望确定商店中有多少件物品,则可以分配一个普通变量,按照每条记录中的物品数量增加: $ awk ' {print x}' inventory 5 7 14 16 71 194 994 1074 1174 $ 根据这一数据,商店中有 1174 件物品。第一次执行时,变量 x 没有值,因此它采用第一行第二个字段的值。第二次执行时,它保留了第一行的值并加上第二行的值,以此类推,直到达到累计的总合。 可以应用相同的过程来确定现有库存的总价值:
$ awk ' {print x}' inventory 39.95 99.93 125.06 133.24 198.69 2042.46 2194.46 2217.66 2241.66 $ 因此,1174 件物品的价值是 ,241.66。虽然这一过程可以获得总计值,但它的外观很差,需要加工成实际的报表。利用一些附加项,很容易使显示变得更整洁: $ awk '{print ,"QTY: ","PRICE: ","TOTAL: "*,"BAL: "x}' inventory hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95 BAL: 39.95 drills QTY: 2 PRICE: 29.99 TOTAL: 59.98 BAL: 99.93 punches QTY: 7 PRICE: 3.59 TOTAL: 25.13 BAL: 125.06 drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18 BAL: 133.24 bits QTY: 55 PRICE: 1.19 TOTAL: 65.45 BAL: 198.69 saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77 BAL: 2042.46 nails QTY: 800 PRICE: .19 TOTAL: 152 BAL: 2194.46 screws QTY: 80 PRICE: .29 TOTAL: 23.2 BAL: 2217.66 brads QTY: 100 PRICE: .24 TOTAL: 24 BAL: 2241.66 $ 该过程提供了每条记录的清单,同时将总价值分配给库存值,并保持商店资产的运作平衡。 BEGIN 和 END
使用 BEGIN 和 END 语句可以分别指定在处理实际开始之前或者完成之后进行操作。BEGIN 语句最常用于建立变量或显示标题。另一方面,END 语句可用于在程序结束后继续进行处理。
在前面的示例中,利用以下例程生成了物品的总价值:
awk ' {print x}' inventory 该例程在运行总计累加时显示了文件中的每一行。没有其他方法可以指定它,而不让在每一行进行打印也导致它始终不打印出来。但是,利用 END 语句可以避免这一问题:
$ awk ' END {print "Total Value of Inventory:"x}' inventory Total Value of Inventory: 2241.66 $ 定义了变量 x,它对每一行进行处理;但是,在所有处理完成之前不会生成显示。尽管可以作为独立例程使用,它也可以置入到先前的代码列表,添加更多信息并生成更完整的报表: $ awk ' {print ,"QTY: ","PRICE: ","TOTAL: "*} END {print "Total Value of Inventory: " x}' inventory hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95
drills QTY: 2 PRICE: 29.99 TOTAL: 59.98 punches QTY: 7 PRICE: 3.59 TOTAL: 25.13 drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18 bits QTY: 55 PRICE: 1.19 TOTAL: 65.45 saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77 nails QTY: 800 PRICE: .19 TOTAL: 152 screws QTY: 80 PRICE: .29 TOTAL: 23.2 brads QTY: 100 PRICE: .24 TOTAL: 24 Total Value of Inventory: 2241.66 $ BEGIN 命令与 END 的工作方式相同,但它建立了那些需要在完成其他工作之前所做的项目。该过程最常见的目的是创建报表的标题。此例程的语法类似于 $ awk 'BEGIN {print "ITEM QUANTITY PRICE TOTAL"}' 输入、输出和源文件
AWK 工具可以从文件中读取其输入,正如在此之前所有示例所做的那样,它也可以从其他命令的输出中获取输入。例如:
$ sort emp_names | awk '{print ,}' awk 命令的输入是排序操作的输出。除了 sort,还可以使用任何其他的 Linux 命令 — 例如 grep。该过程允许您在离开所选定字段前对文件执行其他操作。 类 似于解释程序,AWK 使用输出改向操作符 > 和 >> 将其输出放入文件中而不是标准输出设备。这些符号的作用类似于它们在解释程序中的对应符号,因此 > 在不存在文件时创建文件,而 >> 追加到现有文件的尾部。请看以下的示例:
$ awk '{print NR, ) > "/tmp/filez" }' emp_names $ cat /tmp/filez 1 46012 2 46013 3 46015 4 46017 5 46018 6 46019 7 46021 8 46022 9 46024 10 46026 11 46027 12 46029 $ 检 查该语句的语法,您会看到输出改向是在打印语句完成后进行的。必须将文件名包含在引号中,否则它只是一个未初始化的 AWK 变量,而将指令联接起来会在 AWK 中产生错误。(如果不正确地使用改向符号,则 AWK 无法了解该符号意味着“改向”还是一个关系操作符。) 在 AWK 中输出到管道也类似于解释程序中所实现的相同操作。要将打印命令的输出发送到管道中,可以在打印命令后附加管道符号以及命令的名称,如下所示:
$ awk '{ print | "sort" }' emp_names BOGUE BUCK DULANEY DURHAM FELDMAN FERGUS JUNE KANE STEEN SWIM TUTTLE WOOD $ 这是输出改向的情况,必须将命令包含在引号中,而管道的名称是被执行命令的名称。 AWK 所使用的命令可以来自两个地方。首先,可以在命令行中指定它们,如示例中所示。其次,它们可以由源文件提供。如果是这种情况,通过 -f 选项将这种情况向 AWK 发出警告。演示如下:
$ cat awklist {print ,} {print ,,"n"} $ $ awk -f awklist emp_names
EVAN DULANEY MOBILE AL JEFF DURHAM
MOBILE AL BILL STEEN
MOBILE AL EVAN FELDMAN
MOBILE AL STEVE SWIM
UNKNOWN AL ROBERT BOGUE
PHOENIX AZ MICAH JUNE
PHOENIX AZ SHERYL KANE
UNKNOWN AR WILLIAM WOOD
MUNCIE IN SARAH FERGUS
MUNCIE IN SARAH BUCK
MUNCIE IN BOB TUTTLE
MUNCIE IN $
注意,在源文件中的任何地方或者在命令行中调用它时,不使用单引号。单引号只用于区别命令行中的命令与文件名称。 如果简单的输出不能处理您的程序中所需要的复杂信息,则可以尝试由 printf 命令获得的更加复杂的输出,其语法是
printf( format, value, value ...) 该语法类似于 C 语言中的 printf 命令,而格式的规格是相同的。通过插入一项定义如何打印数值的规格,可以定义该格式。格式规格包含一个跟有字母的 %。类似于打印命令,printf 不必包含在圆括号中,但是可以认为使用圆括号是一种良好的习惯。
下表列出 printf 命令提供的各种规格。
规格 说明 %c 打印单个 ASCII 字符 %d 打印十进制数 %e 打印数字的科学计数表示 %f 打印浮点表示 %g 打印 %e 或 %f;两种方式都更简短 %o 打印无符号的八进制数 s 打印 ASCII 字符串 %x 打印无符号的十六进制数 %% 打印百分号;不执行转换 可以在 % 与字符之间提供某些附加的格式化参数。这些参数进一步改进数值的打印方式: 参数 说明
- 将字段中的表达式向左对齐 ,width 根据需要将字段补齐到指定宽度(前导零使用零将字段补齐) .prec 小数点右面数字的最大字符串宽度或最大数量 printf 命令能够控制并将数值从一种格式转换为另一种格式。当需要打印变量的值时,只需提供一种规格,指示 printf 如何打印信息(通常包含在双引号中)即可。必须为每个传递到 printf 的变量包含一个规格参数;如果包含过少的参数,则 printf 不会打印所有的数值。
处理错误
AWK 工具报告所发生错误的方式很令人恼火。一个错误会阻碍任何操作的进行,所提供的错误信息非常含混不清:
awk: syntax error near line 2 awk: bailing out near line 2 您可能会花几小时的时间查看第 2 行,试图找出它为什么阻碍程序运行;这就是支持使用源文件的一个有力论据。
切记有两条规则可以帮助您避免出现语法错误:
1. 确保命令位于括号中,而括号位于单引号中。没有使用这些字符之一必然导致程序无法运行。 2. 搜索命令需要位于斜线之间。要找出住在印第安那州的员工,您必须使用“/IN/”而不是“IN”。 结论 尽管 AWK 完全代表另外的含意,但它应该是管理员智能工具包的首字母缩写。连同 SED 一起,AWK 实用工具是 Linux 管理员所拥有的功能最强大和灵活的工具之一。通过了解其语言的一些特性,您可以开辟出能够简化任务的领域,否则这些任务将会是非常费时和困难的。 November 29 摘抄的一篇好文章——java代码规范(时刻提醒自己)Java开发者的十大戒律 -- 转载自CSDN有许多标准和实践准则可适用于Java开发者,但此处要说的,是每个Java开发者需坚守的基本原则。一、为代码加注释。虽然每个人都知道这点,但有时却不自觉忘了履行,今天你“忘了”加注释了吗?虽然注释对 程序的功能没什么“贡献”,但过一段时间,比如说两星期之后或者更长,回过头来看看自己的代码,说不定已经记不住它是干什么的了。如果这些代码是你个人的,那还算是走运了,不幸的是,当然了,大多数时候都是别人的不幸,很多时候大家都是在为公司写代码,写代码的人也许早已经离开了公司,但别忘了一句古话,有来有往嘛,为他人,也为我们自己,请为你的代码加上注释。 二、不要让事情复杂化。程序员有时候总是对简单问题想出复杂的解决方案,比如说,在只有五个用户的程序中引入EJB、对程序实现了并不需要的框架(framework),之类的还有属性文件、面向对象解决方案、多线程等等。为什么要这样做呢?也许我们并不知道是否这样会更好,但这样做也许可以学到一些新东西,或者让自己更感兴趣一些。如果是不知道为什么这样做,建议多请教经验丰富的程序员,如果是为了个人的目的,麻烦让自己更专业一点。 三、始终牢记——“少即是好(Less is more)并不总是对的”。代码效率虽然很重要,但在许多解决方案中,编写更少的代码并不能改善这些代码的效率,请看下面这个简单的例子:
能看明白if条件语句是干什么的吗?能想出来是谁写的这段代码吗?如果把它分成两段独立的if语句,是不是更容易理解呢,下面是修改后的代码:
是不是读起来容易多了呢,在此只是多加了一个if和两个花括号,但代码的可读性与可理解性就一下子提高了一大截。 四、请不要硬编码。开发者经常有意“忘记”或忽略掉这点,因为有些时候开发日程逼得实在太紧。其实,多写一行定义静态变量的代码能花多少时间呢?
现在,每次需要将“ABC”与其他变量进行比较时,不必记住实际代码,直接引用A.S_CONSTANT_ABC就行了,而且在今后需要进行修改时,也可在一处修改,不会翻遍整个源代码逐个修改了。 五、不要“创造”自己的框架(framework)。确切来说,有数以千计的各种框架存在,而且大多数是开 源的,这些框架都是优秀的解决方案,可用于日常程序开发中,我们只需使用这些框架的最新版本就行了,至少表面上要跟上形势吧。被大家广为接受的最为明显的一个例子就是Struts了,这个开源web框架非常适合用在基于web的应用程序中。是不是想开发出自己的Struts呢,还是省点力气吧,回头看看第二条——不要让事情复杂化。另外,如果正在开发的程序只有3个窗口,就不要使用Struts了,对这种程序来说,不需要那么多的“控制”。 六、不要使用println及字符串连接。通常为了调试方便,开发者喜欢在可能的所有地方都加上 System.out.println,也许还会提醒自己回过头来再来删除,但有些时候,经常会忘了删除或者不愿意删除它们。既然使用 System.out.println是为了测试,那么测试完之后,为什么还要留着它们呢,因为在删除时,很可能会删除掉真正有用的代码,所以不能低估 System.out.println危害啊,请看下面的代码:
从测试中可以发现,方法calculationWithOutPrint()执行用了0.001204秒,作为对比,方法calculationWithPrint()执行可是用了10.52秒。 要避免浪费CPU时间,最好的方法是引入像如下的包装方法:
另外,字符串连接也是浪费CPU时间的一个大头,请看下面的示例代码:
在测试中可发现,使用StringBuffer的方法只用了0.01秒执行完毕,而使用连接的方法则用了0.08秒,选择显而易见了。 七、多关注GUI(用户界面)。再三强调,GUI对商业客户来说,与程序的功能及效率同等重要,GUI是一 个成功程序的最基本部分,而很多IT经理往往都没注意到GUI的重要性。在现实生活中,许多公司可能为了节省开支,没有雇用那些有着设计“用户友好”界面 丰富经验的网页设计者,此时Java开发者只能依赖他们自身的HTML基本功及在此领域有限的知识,结果,很多开发出来的程序都是“计算机友好”甚于“用 户友好”。很少有开发者同时精通软件开发及GUI设计,如果你在公司“不幸”被分配负责程序界面,就应该遵守下面三条原则: 1、 不要再发明一次轮子,即不做无用功。现有的程序可能会有类似的界面需求。 2、 先创建一个原型。这是非常重要一步,用户一般想看到他们将使用的东西,而且可以先利用这个原型征求用户的意见,再慢慢修改成用户想要的样子。 3、 学会换位思考。换句话来说,就是从用户的角度来审查程序的需求。举例来讲,一个汇总的窗口可以跨页或者不跨页,作为一个软件开发者,可能会倾向于不跨页,因为这样简单一些。但是,从用户的角度来看,可能不希望看到上百行数据都挤在同一页上。 八、文档需求不放松。每个商业需求都必须记录在案,这可能听上去像童话,似乎在现实生活中很难实现。而我们要做的是,不管开发时间多紧迫,不管最终期限多临近,对每个商业需求都必须记录在案。 九、单元测试、单元测试、单元测试。关于什么是单元测试的最好方法,在此不便细说,只是强调,单元测试一定要完成,这也是编程中最基本的原则。当然了,如果有人帮你做单元测试自然是最好,如果没有,就自己来做吧,当创建一个单元测试计划时,请遵守以下三条最基本的原则: 1、 先于编写类代码之前编写单元测试。 2、 记录单元测试中的代码注释。 3、 测试所有执行关键功能的公有方法,这里不是指set和get方法,除非它们是以自己独特方式执行set和get方法。 十、质量,而不是数量。有些时候因为产品问题、期限紧迫、或一些预料之外的事情,导致常常不能按时下班,但一般而言,公司不会因为雇员经常加班而对之表扬和奖励,公司只看重高质量的工作。如果遵守了前九条原则,你会发现自己写出的代码bug少且可维护性高,无形中质量提高了一大步。 November 27 重拾自我(反省、沉淀)好几没有打理我的缤纷世界了,前段时间感觉我的缤纷色彩被冲走了,只留下了灰色。感觉思想干涸了,人也麻木了。可能是由于前段时间工作太忙了。忙?其实并不是原因,只是借口而已。
今天无意看了一个朋友的blog上面有一篇美文,称这种状态为“老”。这篇文章重新诠释了“衰老”,“老”并不是生理的现象,而是心理的变化;是对“懒惰”和“懦弱”的妥协。只要拥有“勇气”、“自信”、“勤劳”和“热情”就算身体已经衰老到80岁,但心理依然很年轻。
我觉该是自我反省的时候,想想自己到底怎么了,已经不像1年前的我了,那时我精力充沛、充满激情和热情、思想活跃如泉涌般。但是看看现在的老气横秋、一天到晚不知所为,工作占据了我的生活,不知目的地在何方,我被枯燥和繁重的工作打败了。我需要反省从新找回自我和绚丽多彩的色彩。
“不应抱怨事与愿违,却不愿意回头看看自己,想想自己到底做了甚么蠢事情。别管那些纷纷扰扰,别停下了脚步,就怕你不说,就怕你不做,别让遗憾继续,一切都来得及”。
想想自己的理想和自己的目标究竟离他还有多远,朝着她努力吧。
Action!!! April 10 在Oracle中使用XQuery查询\构建XMLXQuery介绍 XQuery是W3C组织的标准,它可以从XML文档中提取你想要的数据。 这项技术目前已近应用到商业型数据库技术中,Oracle 10 release 2 和 DB2 9 都支持XQuery。 下面介绍一下XQuery的优点: 1.简单 写的代码量是XSLT处理的1/5 , dom 处理1/20。 2.异构数据源 可以通过不同的数据源提取数据,如:database ,file, web-service等一些XML文档。 3.XML data model 基于XML-schema, 可以表示多样、非规则的数据。 4.构建XML 通过XQuery表达式可以更高效的建立XML。 March 11 修身齐家治国平天下原文是“古之欲明明德于天下者;先治其国;欲治其国者,先齐其家;欲齐其家者,先修其身;欲修其身者,先正其心;……心正而后身修,身修而后家齐,家齐而
后国治,国治而后天下平。”大意是说:古代那些要使美德彰明于天下的人,要先治理好他的国家;要治理好国家的人,要先整顿好自己的家;要整顿好家的人,要
先进行自我修养;要进行自我修养的人,要先端正他的思想……思想端正了,然后自我修养完善;自我修养完善了,然后家庭整顿有序;家庭整顿好了,然后国家安
定繁荣;国家安定繁荣了,然后天下平定。
这是儒家思想传统中知识分子尊崇的信条。以自我完善为基础,通过治理家庭,直到平定天下,是几千年来无数知识者的最高理想。然而实际上,成功的机会少,失 望的时候多,于是又出现了“穷则独善其身,达则兼济天下”的思想。“正心、修身、齐家、治国、平天下”的人生理想与“穷则独善其身,达则兼济天下”的积极 而达观的态度相互结合补充,几千年中影响始终不衰。 其实万事的根本在于端正自己的思想,调整自己的心态,完善自己的能力。当机遇在你面前时你才能抓住它,驾驭它。机遇永远是留给那些有准备的人。其实这与“天将降斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。”的道理是一样的。只有不断地自勉自强才能迸发出生命的火花。 February 26 读《Oracle 9i & 10g编程艺术数据库体系结构》有感-使用procedure对不同数据库进行接口隔离 使用存储过程实现对访问不同数据库的接口隔离,可以充分利用不同数据库的特性。 October 19 XML数据岛技术的总结最近做的一个项目中运用 xml 数据岛技术,所以把数据岛方面的知识总结一下。 XML 数据岛 ( data islands )就是被 html 页面引用或者包含的 xml 数据,是从 IE5 开始引入的一项技术。可以通过 xml 标签很轻松将数据岛插入到 html 文档中。那么怎么访问 xml 数据岛的数据呢,很简单,通过 xml 的 id 。在页面中的数据岛和其他的 xml 数据一样,可以通过标准的dom 方法来进行访问。 数据岛的优点是可以很容易的将 xml 中的数据和 html 元素进行绑定,免去了手工把数据填充到 html 中的麻烦。修改数据岛中的数据,页面上与之绑定的html元素的值也随之改变。 OK ,先来看个数据岛之 Hello World 版, 数据岛其实就是一串 xml ,必须要用 xml 标签围起来,示例如下: <xml id= "island" > <root> <p1> <age> 24 </age> <email> magicdoom@gmail.com </email> </p1> </xml> 数据岛有两种定义方式,一种是直接将上述 xml 嵌入到 html 页面中,另一种是见 xml 数据保存在单独的 xml 文件中,在页面只需嵌入 <xml id= "island" src= "xxx.xml" ></xml> 其中的 src 属性值为保存 xml 数据的那个文件的位置。 如何将上面定义好的 xml 数据岛绑定到 html 控件上呢?答案是通过 datasrc , datafld 属性,下面是一个将 xml 数据岛绑定到 html 控件上的示例: <table width= "100%" datasrc= "#island" >
<thead>
<tr>
<th> Name </th>
<th> Age </th>
<th> Email </th>
</tr>
</thead>
<tbody>
<tr>
<td align= "center" ><span datafld= "name" ></span></td>
<td align= "center" ><span datafld= "age" ></span></td>
<td align= "center" ><span datafld= "email" ></span></td>
</tr>
</tbody>
</table> 例中 table 的 datasrc 属性的 value 为 xml 数据岛中的定义的 id ,注意必须要在前头加上 # 。 表格中的 datafld 属性对应于 xml 中的元素的名称。 将上述数据岛和 html 代码保存到一个 html 文件中,在 IE 中打开,可以看到结果如下:
下面我们来看看在 javascript 中怎样通过DOM访问数据岛中的数据
xmldoc = island; // 取数据岛 var rootElement = xmldoc.documentElement.firstChild; // 取根元素
// 实现打印出数据岛中第一个元素的值 if (rootElement.hasChildNodes())
alert (rootElement.firstChild.text) ;
// 创建一个新的元素,添加到数据岛中 var test = xmldoc.createElement( 'test' );
var testTxt = xmldoc.createTextNode( "This is a test!" );
test.appendChild(testTxt);
rootElement.appendChild(test); alert (rootElement.lastChild.text) ;
// 删除数据岛中的一个元素 rootElement.removeChild(rootElement.lastChild) ;
// 修改数据岛中的一个元素的值 rootElement.firstChild.text= "new value" ; //查找xml元素 使用getElementsByTagName返回一个element的数组
XML 数据岛的应用很容易和其他的技术进行结合。我当前做的一个项目中,就是和 HTC 以及 XmlHttp 技术进行结合。 htc 做了一些功能强大的控件(比如Tree非常好用),底层通过XmlHttp 与后台的服务器进行交互,可以达到无刷新提交页面。前台通过js来操纵页面中的数据岛和发送数据到后台的java类,项目的 框架支持在js调用后台 java 类的方法,有点类似于 DWR 。后台的 java 类返回 XML 数据到前台的 js , js 再将xml数据注入到页面的数据岛中。 最后总结一下 xml 数据岛的最大优点是可以和html元素进行绑定,修改数据岛中的数据,与之绑定的html元素的值也会随之改变。但是也要看到它的缺点: 1.只能在 IE 下运行,firefox等其他的浏览器下无法使用。 2.安全性, xml 数据岛可以通过查看 html 的源代码获取。
另:在 DWR 中,提供有一些便捷的 js 函数,可以将后台 java 方法传回的 json 格式的 js 对象的属性值,赋给 html 页面中的 html 元素, dwr 会根据 html 元素的 id 进行自动赋值。这种方式也蛮简单方便的。 June 25 It's important to test ipersistent domain model 今天在tss上看了一篇关于持久层模型测试的文章,觉得不错值得记录,特此收到我的blog中,文章主要介绍持久层模型测试的重要性和一些测试方法。
测试方法只是手段而已,目的才是根本。
在此我对持久层模型测试的目的做些简单的介绍,其实就是tesing的重要性和所这针对问题,这些问题都是我们在工作中使用orm技术经常遇到的。
文中主要提到两点:第一,是测试orm的细节上的bug,这些bug往往会引起业务逻辑、ORM配置文件和数据库中表结构的矛盾。例如,数据库表中增加一个字段,而忘记在配置文件中增加一个相应配置信息,从而引起许多严重的bug。在数据库约束上的问题也很普遍,他通常限制对象的持久化操作。这说明对持久层模型的测试是非常必要的。
第二个问题出现了,就是我们如何在测试运行中花费更少量的时间来达到高效测试的目的。往往测试一个大的数据模型对象和那些需要频繁访问数据库的对象操需要许多时间,但是这些测试有是必须的。重要的就是找到一个好的测试方法。
下面介绍几种测试策略:
有许多bug都是潜伏在orm的配置和实现上,如:
其中有些bug在ORM Framwork启动时就可以发现,如配置文件的问题。还有一些是只能通过测试应用程序才能发现,如错误的配置了一个collection feild 只有在执行查询操作时,才能被发现。 快速测试的处理就是采用多种测试方法,测试持久层每个独立部分。 The tests that run against the database are:
There are also tests that don't use the database:
June 24 春逝 《春逝》这部电影想必许多人都不会陌生,今天又回顾了一遍,它所表述的那种爱情的感觉真是久久不能让人忘怀,而且感觉像一把刻刀在心灵中留下刻骨铭心的记号。
电影对爱情的描写手法很特别,用散文诗般的手笔将爱情用自然界的声音做了透彻的诠释,它像春天刮的风,秋天下的雨,冬天下的雪,爱情又像春天一样,短暂而又美好,我们总是希望能把春天永远的留住,但是春一旦逝去就无法挽留,只能等到下一个春天的来临。
影片的最后一个镜头,经历爱情风雨洗礼之后的尚优,独自一人戴上耳机,站在迎风摇曳的芦苇丛中,和煦温暖的阳光照在他的脸上,他闭上眼,嘴角带着微微的笑意,仿佛大自然的风抚平了他内心的创伤,他用内心在倾听,在捕捉,在记录那像春天一样稍纵即逝的爱情。爱情已逝,而关于爱情的种种甜蜜与忧伤却如耳中的风声,久久回荡,成为了那个春日最美好回忆。这样的感动是属于生命的,是超越了爱情本身的。 June 19 说和做是两码事 这段时间太忙了,所以好久没有写blog。今天终于有时间把这段的体会总结一下。
这段时间体会最为深刻的就是感觉的说和做确实是两码事,说注重的是思想上的交流,注重的是用最为简单直白的语言将你思想的精隋表达出来,因此它更注重宏观上的逻辑思维,但是这样往往忽视了在实践中的细节之处。正是这些细节上的琐碎的事情阻碍和违背了预想中的逻辑 。
要达到思想与实现的统一,需要缜密的思维和对客观事物真实和全面的了解,建议在开始时做些小的并不复杂实现,这样可以更利于了解客观事物的本质。在物理学和化学中这称之为实验,毕竟实践是检验真理的唯一标准吗。其实在软件工程和计算机科学中也同样需要这样的实验。这可能就是XP编程中所倡导的测试驱动开发的思想吧,主要就是弥补在设计过程中对实现细节不足弥补。其实目的也就是更科学、更准确的事物客观实在的反映到人的意识中,我用面向对象的理论称之为抽象。
这样才能达到微观与宏观的、客观与主观的统一,引用哲学中的一句话世界的本质是物质,物质是不依赖于意识并能为意识所反映的客观实在。毕竟事物的本质是不依赖于意识的,所以只有实践才能更客观的反映本质。所以在设计和构思的过程中,也要适当的考虑实现的细节。在寻找问题解决方案时,也要适当的尝试一下。 May 28 和家人一起踏青 今天和家人一起去陶然亭踏青,感觉真是不错.好久没有感受到阳光的温暖和青草鲜花的味道了,在湖上泛舟一起谈笑风生,再加上明媚的阳光下花红柳绿的景色,心情格外开朗,忘记了所有疲惫和所有烦恼.
想想大家好长时间没有一起出去玩了,最好能安排一下每个月都能聚这么一次.
SDO - javaOne 2006今天又看到一个新的概念SDO.
What's SDO?
SDO is service data object,SDO provides a convenient way to move data from a data source to an SOA-enabled application. SDO is an abstraction over datasource services like SOAP-based Web Services and JDBC access to relational databases. May 26 java one 2006今天实在好困,不过在 serverside 看到了令java程序员兴奋的消息。java se6 (Mustang) 野马将于今年10月发布,真是令人期待呀,据说野马在主要是针对提高GC和Swing component的性能和增强系统资源的监控和管理。希望sun不要在jvm的性能上输给bea和IBM。
还有就是期待着java EE 5
New features include simplified Web Services support, dependency injection to reduce the need for JNDI and properties files, a new persistence API, and added JavaServer Faces. JEE 5 provides full compatibility with J2EE 1.4,and Web 2.0 support, .NET interoperability and simplified SOA development.
我觉得java EE 5 是java在Enterprise Edition中一个新的阶段。真是令人期待和兴奋。
May 23 ORM and the misleading DAO pattern The DAO layer offers a great enhancement in the process of software development. It effectively decouples the business layer from the persistence mechanism. For this reason it gives robustness to our application's architecture and flexibility when it comes to the unavoidable evolutions and branches of our work. In fact, changing the way data is persisted (e.g. JDBC - possibly between different vendors, XML, files) is simply a matter of writing new DAO implementations in a well isolated layer. But with the introduction of an ORM, well, things change quite a lot. Imagine the following scenario: we've got an application developed with a well-isolated DAO layer that interacts with a database via JDBC. Now we want to switch to an ORM solution (e.g. Hibernate) by writing a new DAO implementation which makes calls to our ORM. Sounds good ... but wait! How about the way the business and the view layers are handling the domain objects? There is nothing in these layers to prevent developers from changing a domain object just loaded by the DAO layer. With a JDBC-oriented DAO in mind the developer is free to change anything about a loaded object, maybe for view reasons or for in-memory elaborations. As far as the object is not explicitly updated through calling the DAO again, one thinks the object to be just an in-memory (transient) copy of the original persisted one. This is not the case when using an ORM approach! Switching to an ORM often implies that the object loaded and passed to the business and view layers is persistent; so any change to its properties, any change to relations with other objects will be automatically made persistent, no matter if the DAO is called again. On the other hand switching from an ORM-oriented to a JDBC-oriented DAO (or XML, file) will soon fail because of the missing DAO update calls that an ORM approach does not require. In conclusion the DAO pattern does not isolate well; business and view layers must know if they are handling persistent (automatically updated) or transient (updated upon an explicit request) domain object. Some suggest never to expose directly the persistent object, but a transient copy of them (through another set of classes or by detaching objects). However, I prefer to deal with a poorly isolated DAO layer (thus giving away with the JDBC-ORM switching option) than giving away with the advantages of handling persistent objects directly. I mean, all the overhead working needed to detach/reattach objects or to copy properties back and forth between persistent and transient object almost kills the ORM choice. Better to have a full ORM with a half DAO than a swichable DAO with a half ORM, IMHO. Do we have to split the DAO pattern in two in order to have a clearer distinction? Or am I missing something? I'd appreciate your opinions. References: |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|