2007年01月30日

         Mark Lam has been a virtual machine engineer in the JavaME CDC team at Sun Microsystems for over 6 years. Before joining Sun, he was a real-time embedded systems developer for 6+ years, working on application frameworks, graphics systems, networking protocols, game development, and fault tolerant systems amongst other things, on devices ranging from 64KB 8bit uControllers to 32-bit RISC machines.
原文URL:http://weblogs.java.net/blog/mlam/archive/2006/11/performance_how.html#more

性能:太多的好事?
               这篇文章需要开发者有PhoneMe Advanced VM和J2ME方面比较深奥的知识。
              如果你已经看过了phoneMe Advanced VM的代码,你可能已经注意到许多函数和结构都是以cvm为前缀的。CVM是sun公司CDC VM的名称,而cvm作为前缀是VM代码(特别是全局函数和结构)的标准习惯。这是所有使用sun公司CDC技术工作过的人的普遍常识,但在这里我还是要强调一下。另外,我简单的以CVM来代替phoneMe Advanced VM。
现在让我们开始今天的主题。。。
性能
           通常,没有用户会抱怨,当他们的软件有很好的性能。无论如何,性能伴随着价格。通常,这意味着复杂的代码和更好的硬件。这还意味着需要更多的内存来运行软件。对JavaME VM来说,它的目标是资源受限的嵌入式设备。这是一个明确的关系。因此,一些性能上的工作需要合理的代价。这意味这平台开发者不能做所有他们知道的书本上的优化方法。
          这样说,我希望你知道我没有说这些是因为CVM的性能是窘迫的。直到我们吃的,CVM是这个领域最快的虚拟机,如果不是最快的,给你一个关于CVM性能的想法。几年前,我们把CVM同JavaSE1.3的基于SPEC JVM98子集的client VM进行了比较。我们使用子集是因为SPEC JVM98使用了已经从CDC移出的不受赞成的API。因此,我们做了一些内部“移植”对这个比较。这个比较在PowerPC,PowerMac和Solaris SPARC机器上进行。同JavaSE比,CVM显示了80%~90%的性能,只有10%的静态footprint。你应该知道这是老的数据。JavaSE已经有了很大的提高,CVM也是。注意:我仅仅是共享这些比较而给你一个JavaME能达到的性能等级的概念,我没有说任何关于哪一个VM更好。
         因此,当我们谈论性能的时候,人们首先谈论的VM的一个组成是动态适应编译。而作为JIT,下面我会围绕比较谈关于一些性能的事。我会接触其他非JIT相关但又重要的领域或主题
静态编译 VS 运行时编译
           一个最大的错误是,工程师会在JIT开始执行从其他编译课本来的优化而不做太多考虑。这些优化技术中的一些是意味深长的,而一些不是。有一点,课本经常教的是静态编译。JIT,在其他方面,是动态编译。这是JavaME的资源受限请求的要素。你可以在它们的属性中找到对比。下面是2中技术的比较:
Static compiler                                                                       JavaME JIT compiler
能提供少量内存给编译工作                                                   必须最小化或限制使用的工作内存
能够提供更多的时间和CPU周期给编译工作                      必须最小化或限制CPU的消耗
假设所有的方法在编译时都是可用的                                   只能工作与一个子集
编译所有的方法                                                                       只编译正在使用的方法。
必须编译所有类型的代码                                                   只需用编译通用的类型,让解释器处理那些不常见的实例
             注意,很多静态编译都假定更多内存和CPU资源的可用性。因此,他们的编译技术有很多相似的假定。明显的,这些技术的一部分不适用于JavaME。
                注意,尽管java平台是一个动态环境,可以期望部分代码在运行时下载。后期绑定是Java VM和语言的特点。 这不匹配静态编译的假定:整个应用程序代码必须在编译期可用。
JIT的能力让解释器处理不常用的案例的执行,同样也减少非紧急代码在资源上的消耗(在编译代码和编译footprint)
             批评家会说在我上面基于广泛性的表格里的需求,在今天的编译技术水平下不是真的。为什么,对的,我同意。我假设静态编译也来源静态链接。但记住,你的编译课本可以没有包括这2个中的任一个。我也使用静态编译的严格定义。例如:我认为它是编译静态代码。
真实世界的执行会加入一些能力,包括动态代码(可以下载),但这些不是严格的静态编译。这里的要点是你不必盲目的应用一流的编译技术。这些技术常常对不同的系统(这对类似于java的平台)做目标和最优化,因此他们可能不适合这里。
            人们可能有这样的误解,通过静态编译的代码要运行的比实时编译的要快。这不是全对的,实时编译的代码能够超越静态编译的代码。一个关键的原因是,java平台是动态并且后期绑定的。我会在以后详细的讨论这个。
           因此,有很多的原因导致静态编译不适用,甚至当你关心的资源和性能受限大打折扣。
JavaSE Hotspot VS CVM
        因此我们不能从编译器课本挖掘出诀窍。那从JavaSE VM可以得到诀窍吗?回答是“可能”。首先,这是资源受限的问题。JavaSE已经和有许多资源的大系统匹配了。这完全是合理的和可接受的,他们使用这些资源给你最好的性能在你的话费下。但当这些资源在你的设备上不可用时,这些技术可能就不能用了。
            另一点对普通开发者来说不是那些显而易见,JavaME 执行(像CVM)不仅仅是JavaSE的小版本。JavaSE目标设备的类型和JavaME有很大差别。CVM不是因为比JavaSE Hotspot少了一些功能而变小,CVM体系被设计的它可以工作在不同的嵌入式设备上。在它设计上的每一级,不同的选择会导致速度-空间的权衡。由于这个原因,用在JavaSE里的技术可能不能应用在CVM里,因为它们有不同的权衡。
                 给你一些例子来说明JavaME设备和JavaSE的不同,一段时候前,我的一个JavaSE方面的同事发现了当他应用一个可靠的技术来改善高速缓存位置,基于一个基准他能得到20%性能的提升。这抓住了我的注意。20%是不容忽视的,因此,我应用这个技术到CVM。令我吃惊的是,基于同样的基准,性能下降了70%,发生了什么?不同的是,JavaSE运行在一个有大量高速缓存(上百KB甚至是几兆)的服务器上。而我运行在只有32KB高速缓存的基于ARM处理器的设备上。这个改良的高速缓存位置在这儿制造了一个冲突。
 这个有效提升JavaSE的技术相对CVM来说,这也不是一个精确的例子。在这个例子里,他可以解决。但如果最优化代码,这项JavaSE技术可用于那些有着巨大缓存的设备?把这个技术应用在CVM实际上会造成那些没有大量高速缓存的JavaME设备性能的大幅下降。
              因此,关键是我们不要盲目的应用从JavaSE来的任何重要技术。注意上面的例子也说明了JavaSE VM运行的不比CVM快,当它运行在JavaME设备上时,即便你有大量的RAM(不是系统高速缓存)。这就像你想要你的汽车使用火箭引擎而有更大的马力。这听起来是一个不错的主意,但你的燃料系统不能支持它。结果也不比一般的汽车快。什么也没有改变。
              JavaME不仅仅是JavaSE的缩小版。对比JavaSE和JavaME就像对比苹果和橙子。
 基准
                 最后,确定优化是否工作的最好方法就是实验。 我们经常自己做这些事情。当一个念头失败,我们不混合基本代码。检测优化是否联合的一个重要的标准是,花费了多少成本在小组的资源分配上。另外,它带给了你多少性能的提升。
                 测量性能的提升,你需要运行某个类别的基准。一个常见的错误是人们运行了一个小的基准仅仅在测试一个优化提升的范围。真实世界的应用程序可能不只参加了一个循环和一个代码范围。因此,基于真实世界应用程序的基准是一个可靠的指示。对JavaMe来说,我们喜欢SPEC JVM98,但像前面说的,它不能不修改那些不赞成的方法而运行在CDC上。另外我们还喜欢EEMBC的GrinderBench。
               如果可能,运行你的基准在JavaME类型的设备上。就像上面指出的,JavaME不同于JavaSE,你改变在JavaSE类型的桌面或服务机器的的基准将给你指示,改变的结果是否有增长。但不同的JavaME设备,你得到的结果不完全一样,需要有适当的工程判断。
另外的性能
                一般的,java平台的性能不仅仅指执行引擎(解释器,JIT)。VM运行时和类库的品质也是游戏的一大部分。有些时候,它们甚至比VM重要。这包括主要依靠本地代码(相对于java代码)的graphics/GUI应用程序。无论如何,这不是意味着他们不依靠VM来运行。严格来说,VM运行时库是VM实现的一部分,我们也需要优化它。
                VM也能提供帮助机制使类库能执行的更好。他们需要共同工作。
               最后,有一件关于本地代码的事情。一些人认为他们的代码会执行的更快如果他们主要代码都是本地代码。这确实是个谬论,因为一系列的原因,使用本地代码确实会造成性能的下降比起一些功能使用java字节码。
               所有的这些都会在后面讨论。
这对你意味着什么
           性能是个复杂的主题。我们在这里仅仅是触及到了它的表面。正如我上面想要指出的,事情不是总想它们看起来的样子。当试着对JavaME系统执行性能提高的工作,对于嵌入式系统开发者来说,谨慎的思考是必要的。每一种优化技术需要在这个地方个别的进行评估。
            祝有美好的一天!:)

2007年01月25日

         Mark Lam has been a virtual machine engineer in the JavaME CDC team at Sun Microsystems for over 6 years. Before joining Sun, he was a real-time embedded systems developer for 6+ years, working on application frameworks, graphics systems, networking protocols, game development, and fault tolerant systems amongst other things, on devices ranging from 64KB 8bit uControllers to 32-bit RISC machines.

 原文URL:http://weblogs.java.net/blog/mlam/archive/2006/11/introduction_to_1.html

           如果你现在在阅读这篇文章,那么你对Sun通过PhoneMe工程来开放J2ME源代码有所了解,如果不是,点这里了解关于PhoneME。
一些背景信息
       开放我们代码的目的是允许你能够访问它,学习它,并有可能贡献你自己的改进。现在你已经可以访问一个代码链了,但访问和能够理解以及贡献有很大区别,它需要一些特别的知识。就大部分来说,只有Sun的雇员和少数例外(使用我们技术的公司的一些核心虚拟机工程师)能够这样做。我提到的知识包括:代码规范、术语表、设计原理、代码组织和设计权衡等等。但我相信你有足够的智慧来及时的领会这些,但我想这不是你在这个项目里开始的地方。
因此,我会就这些主题写一系列的文章(从这篇开始)来使我们的交流变的更容易,使每个人都能得到很到的资料而不用浪费时间在平常的事情上。我也会写一些像“怎样确定子系统的工作”之类的技术文章当我有灵感的时候。我允许你留下注释来告诉我你想我讨论的主题,或是你想我阐述明白的事情。在我选择文章主题的时候会考虑这些。
       在我开始前,你会问我如果来共享这些知识(为什么你要相信我的确知道我在谈论什么)。因此,关于我:工作在PhoeMe Advanced项目的虚拟机小组,负责建立和维护虚拟机。我从CDC1.0发布前就在这个小组工作。因此我和这些代码已经工作了很长的时间。在我们小组工作的过程中,我们不会正式的把虚拟机按我们工作的分成部分。我们基本会在任何需要的地方做必须的工作。因此,每一个虚拟机工程师的代码知识都是全面的。当然,我们每个人都有比其他人熟悉的领域。我需要指出我是一个虚拟机工程师(相对于类库工程师),我的专业技能集中在虚拟机和一些核心系统代码上。我也有一般的标准类库知识,但和他们比我不是专家。我们每个工程师都有自己的领域。因此我会写关于PhoneMe Advanced虚拟机的文章,因为这是我擅长的领域。
好的,让我们开始我们的第一个主题。
The meat(不知道怎么翻译了)
    前面,我说过深奥的知识我们会很少涉及,甚至在使用我们技术的用户里面。原因是这些用户很少有需要和动机去修改我们称作 共享代码 的部分。但现在这不会维持太久了。有太多的创新和特点需要在我们的代码里实现,这部分历史只限于Sun的雇员。我们的用户,在其他方面,需要关注的是我们称为 HPI (Host Porting Interface)的代码部分。点这里察看CDC移植指南,它会告诉你 HPI 的细节。实际上,在代码里有 HPI 文档如果你知道在哪能看到的话。你也可以从其他网页上找到一些有趣的文档。
设计原理(Design Philosophy)
       虚拟机被设计成高移植性,尽可能的减小代码以用于尽可能多的平台。这是虚拟机的基本规则。
    在共享机制下保证尽可能多的普通代码被减小。只有依靠硬件和OS的代码在共享代码以外。这些和硬件和OS捆定的指那些 目标或平台特殊的代码。点这里察看PhoneME Advanced src 列表。这有几个特殊的例子, arm ,linux ,linux-arm 文件夹。Linux 目录包含那些所有在linux移植下用到的代码。这个通常有一些 HPI 执行被调用,从 share 目录下。
     Linux-arm目录包含附加的用户定制的全部或重载的执行在linux目录。这些用户定制只能对于linux arm 移植。
     arm 目录包含针对arm的特殊代码,通常,他们看起来是一些有效函数(有些情况它们是汇编代码)。它们能被不同的arm平台移植调用。
     你在OS文件夹(如linux)下可以找到代码同等的共享文件夹(包括它们的子目录),紧随其后的是OS-CUP(例如: linux-arm)和CPU(如 arm)。这些事实表明了VM是多么的可以移植。移植成果通常只需要执行活修改目标特定的文件(这只是总代码里面的很小一部分)。
    我们工作的多数和共享代码里的创新对于目标特定代码只支持我们的决心来对所有移植平台最优化性能是相反的。这样,大部分性能工作都在共享代码里,这对每个移植都有好处。这样我们希望应用的特殊移植都被最优化。为了做到这点,我们常常把它们放在适当的OS-CPU或CPU文件夹下。
        我们代码组织的另一方面是代码维护以便于阅读。你会发现共享代码没有用 #ifdefs来定制不同的OS和CPU体系。你可以看到#ifdefs被enabling/disabling VM特性代替。你也可以看到OS,CPU和OS-CPU文件仍然易读,因为他们没有被#ifdefs用来和其他体系分开。
       在src文件夹,你可以看到portlibs文件夹。Portlibs被用来保存那些对多个移植来说通用的,但又不完全能以OS或CPU来区分的代码。一个例子就是工具链(gcc)或库/标准(posix,ansi)。多种的移植(OS和OS-CPU文件)可以选择使用portlibs里适当的代码。
       下面一个需要立即的概念是代码组织:根据OO术语,VM有一个父类。这个父类在共享代码里是明确的。每一个特定OS和CPU目标移植的VM是它的子类,通过继承来实现重用。OS代码是共享代码的直接子类。OS-CPU代码是OS代码的子类。CPU文件夹下的代码是可以被OS-CPU类选择使用的有用库。Portlibs 代码是OS-CPU类可以选用的另外的库
     总的来说,单个VM对一个给的的平台(OS和CPU)是incamated(这个词不知道什么意思)。无论如何,这是一个来自OS-CPU VM类的示例,它扩展了OS VM类,OS类又扩展了共享VM类。OS-CPU VM类也可以重用那些在CPU和portlibs里被授权的类。
      留意,这只是代码组织上的一个概念模型。你会发现在代码里的父和子VM没有参考。这个概念模型表明看来也不完美。你可以发现一些代码关联方面的范围不适合这个提取。是的,这是一个例外,但这个模型是一个普通规则。
这对你意味着什么
    当你计划寻找那些完成某些功能的代码,想想这些功能的属于(shared,OS,OS-CPU,or in the CPU or portlibs libraries)。这可以帮助你快速的定位你感兴趣的代码。
    你也可以对你想贡献的代码做同样的思考。这个代码组织是VM完成的一个关键因素,它便于移植(这是对移动和嵌入式领域的VM是非常重要的特点)。代码回顾过程对代码贡献也是必须考虑到的。
    正如我前面提及的,不遵守这些协定你可以得到一些例外。请不要使用那些偏离协定的借口。作为代替,这些已存在的异常会被相应的修正(如果可能)。或者有一个很好的技术理由,这些情况不适合希望的模型。如果理由充分这些异常是被允许的。
嗨,等一下
 所有那些关于可移植的部分听起来都是很好的,但是不是所有的这些层都在性能上有效果?回答是否定的!“不”是对那些我们担心的例子。是不是VM作为高执行蚂蚁它可以内联到任何地方,摆脱压条?可能不会,但我们在可移植和易维护中有一个折中。注意,在实践中,一些执行是可以被忽略的。这就是说,代码不被执行在本地路径。层使用了多样的技术来被执行(那些我在这不会深入)并防止不必要的执行降低与它有关的损失。当然,小组有一些度量来确保这些代码是有竞争力的。
 让我来说下其他问题:如果我们不试着挤出每一点可能的性能(因为我们必须权衡我们的设计原理),那么有多少性能是足够的呢?我会在下篇文章回答这个问题。
 祝有美好的一天!:)

            The article translate from Darryl Mocek’s blog. Darryl Mocek is a staff engineer for sun microsystems,Inc. currently working on J2ME CDC and related techonlogies. the URL is : http://weblogs.java.net/blog/darryl_m/archive/2006/12/phoneme_advance_1.html

           辛辛苦苦打了快一个小时的字,都写完了,结果Maxthon死机了,没上传气死了,不写了!

2007年01月23日

           The article translate from Darryl Mocek’s blog. Darryl Mocek is a staff engineer for sun microsystems,Inc. currently working on J2ME CDC and related techonlogies. the URL is : http://weblogs.java.net/blog/darryl_m/archive/2006/11/phoneme_advance.html

So, let’s begging…

      在这篇文章里,我们将会谈到 PhoneMe 高级工程的目录结构。当你读到这篇文章的时候可以通过这里的链接浏览源代码。你也可以加入这个工程来做这个。

      PhoneME Advanced的源代码从 components/cdc/trunk 目录开始。在 trunk 目录下有下面的目录:

  • build  包含 make 文件
  • src   包含源代码
  • test  包含测试文件

这是显而易见的。

      一旦你在 src 目录,你就在所有平台源代码的根路径上了。你可以注意到有一个 share 目录包含有一系列的硬件和操作系统目录。我们将在后面谈到它。这些目录包含了特定硬件和操作系统的源代码(除了 share 目录)。下面的 share 目录里包含了大多数的 PhoneMe Advanced 的代码

  • appmanager  包含应用程序管理代码
  • basis   包含个人基本描述的代码
  • cdc    包含个人连接设备的演示代码
  • classes    包含个人连接设备的代码
  • foundation   包含基础描述的代码
  • javavm     包含 cvm 的代码
  • lib         包含java 安全文件
  • native    包含共享的本地代码
  • personal   包含个人描述的代码
  • tools        包含工具

        这些所有的目录都可以有一个类别:基层的,个人的。在这里最典型的是 classes 和 native 目录。classes 目录包含了所有的java代码,native目录包含了所有的本地支持代码。native目录豪华 JNI 代码和那些需要用到的库,比如 Qt

        appmanager 目录完全由java代码组成,没有包含本地代码。 cdc 目录只包含了演示代码,lib 目录包含了2个 text 文件来描述和java 安全有关的东西,一个策略文件和一个安全文件。tools 目录包含java代码和本地代码,但现在的目录结构有稍微的不同,现在我集中在 profile 代码。

       classes目录下面,大部分是 java package的根。所以你在下面能找到 java/lang 目录。

        CDC profile 建立在其他部分之上。所以 personal basis profile 包含了基础profile,personal profile 又包含了personal basis profile。 在这些目录中,foundation profile 代码包含在 foundation 目录。personal basis profile 包含在 personal basis目录中。在这些不同的目录中你可以找到一些相同命名的profile文件。比如:你可以在 basis/classes/common/java/awt/toolkit 下找到 toolkit.java 。在 personal/classes/common/java/awt/toolkit 下找到 toolkit.java 。这说明他们是不同系列的 profile 文件。

          在 build 目录下,你可以找到和 src 类似的目录结构。一个 share 目录,它包含了跨越所有平台的 make 文件。特定的目录对应特定的平台,下面的 make 文件都是对对应平台优化了的。

    Now, java is open source! I’m interested how the j2me implemented on the different platform, So i will join this open source project, learning more and more about j2me. j2me open source are named phoneme (this link will redirect you to java.net ,and you can register first). you can find all reference in this site.  let’s go!

     always, play enjoys!

2007年01月22日

摘至IBM, 原文URL:http://www.ibm.com/developerworks/cn/opensource/os-linuxthinkpad/index.html?ca=dwcn-newsletter-opensource

 

级别: 中级

Nathan Harrington (haringtn@us.ibm.com), 编程人员, IBM

2007 年 1 月 15 日

通过修改内核以在受震动导致内核出现紧急情况时自动重置 Linux 膝上型计算机,让您的计算机处于受保护的状态。在内核空间和用户空间中实现震动检测算法,从而执行自动关闭并在特定动力条件得到满足时重新启动。

2003 年,IBM® 开始销售在商业操作系统中集成了加速度传感器及相关软件的 ThinkPad 膝上型计算机,以便在 ThinkPad 坠地时对硬盘进行保护。来自 IBM 和其他地方的富有魄力的计算机程序高手们已经为 Linux 内核开发了利用这些传感器的模块。膝上型计算机的屏幕显示方向、桌面切换、甚至是游戏控制和实时 3D 模型等特性均已实现。

2006 年中期,适用于 Linux 膝上型计算机的基于敲击的命令开始可用于用户空间 Perl 脚本(与内核空间中的基于 C 的代码相对),允许用户运行基于特定敲击序列的随机命令。本文描述了修改 Linux 内核以添加经常需要的功能的过程:对物理输入做出反馈。当 Linux 内核出现紧急情况时,用户可以震动计算机(或对膝上型计算机执行开发人员可配置的任意次数的物理移动),计算机将重置。

本文还介绍了在非紧急情况模式下执行正常关闭的方法。例如,如果用户不注意将计算机放在尚未拉好的计算机包中,则需要计算机检测到正常行走或开车的动作,并关闭计算机。

先决条件

硬件

许多在 2003 年以后(包括 2003 年)制造的 IBM ThinkPad 都配有 HDAPS 硬件。如果不能确定硬件配置,可以到 Lenovo 的 Web 站点中查看详细的技术信息。要运行以下代码,必须有 ThinkPad。某些 MacBook 配有加速度传感器及同样的通过内核访问这些传感器的通用方法。但是,此处的代码并未在 Apple 硬件上做测试,而是基于两个 IBM ThinkPad T42p 型号开发及测试的。有关如何查找在物理上支持膝上型计算机所需的 ThinkPad 硬件的链接,请参阅 参考资料

软件

本文假定您熟悉内核构建过程,并了解内核编译所带来的发行版间的不一致性。有关内核构建过程的简介,以及一些优秀的入门示例,请参阅 参考资料

从 kernel V2.6.15 起,HDAPS 驱动程序已经包含在 Linux 内核中。为了简单起见,请获取最新的内核程序。为了便于开发及管理,本文是基于 Fedora Core V5 开发的。下面用于设置内核构建环境的指导信息是专门针对 Fedora Core 的,但是一般原理适用于所有 Linux 发行版。


回页首

内核开发设置

内核配置、编译和测试

要修改内核,需要按照版本信息中的指导信息进行操作。打开 Web 浏览器并开始按照第 8.6 节:“Preparing for Kernel Development” 中的指导信息进行操作。执行到第 2 部分时,可能会在执行第二条命令 su -c 'yumdownloader --source kernel' 时遇到问题。如果该命令未能把 kernel-2.6.15-1.2054_FC5.src.rpm 软件包下载下来,请使用 wget 命令 wget ftp://ftp.linux.ncsu.edu/pub/fedora/linux/core/5/source/SRPMS/kernel-2.6.15-1.2054_FC5.src.rpm 来获取该软件包。

在执行步骤 5 时,请用 cp configs/kernel-2.6.15-i686.config .config 命令选择基本的 i686 默认配置。确保将 makefile 中的 EXTRAVERSION 部分从 -prep 更改为 -1.2054_FC5。用 make oldconfig 更新构建配置。然后用 su -c "yum install kernel-devel" 命令安装内核开发模块。该模块将用于编译紧急情况触发模块。

我们现在已经完成了 Fedora Core V5 Release Notes 文档中介绍的内核配置的相关部分。其余步骤都是所有内核构建过程通用的标准步骤。建议现在构建并安装新内核、模块和 RAM 磁盘设置以确保一切按预期运行。如果您对自己的新内核配置很有信心,可以跳过以下步骤并直接转到内核修改部分。

make 命令构建新内核。成功构建内核后,请用 su -c "cp ./arch/i386/boot/bzImage /boot/vmlinuz-2.6.15hdaps" 命令将其复制到 /boot 目录。您需要使用 su -c "make modules_install" 命令构建模块。最后一个构建步骤是用 su -c "/sbin/mkinitrd hdapsInitrd.img 2.6.15-1.2054_FC5" 命令为 HDAPS 内核创建 RAM 磁盘。用 su -c "cp hdapsInitrd.img /boot/" 命令将这个新的 RAM 磁盘复制到引导区。引导时,用以下行更新 grub.conf 文件:

清单 1. grub 配置

title Fedora Core (2.6.15hdaps)
    root (hd0,0)
    kernel /vmlinuz-2.6.15hdaps ro root=/dev/VolGroup00/LogVol00 rhgb quiet
    initrd /hdapsInitrd.img

修改 panic.c 和 hdaps.c

现在已经准备好开始一些可快速完成的内核配置。确保位于 ~/rpmbuild/BUILD/kernel-2.6.15/linux-2.6.15.i686 目录。一定要先包含 hdaps 模块作为内核的内置组件,从而准备好在计算机的运行模式中提供对各处的震动检查。

使用 make menuconfig 命令并选择 Device Drivers > Hardware Monitoring Support。键入 Y 以包含 Hardware Monitoring Support 模块,因为 HDAPS 模块依赖于此模块。滚动到清单底部,并在 IBM Hard Drive Active Protection System (hdaps) 条目的旁边再次键入 Y。退出菜单并保存配置。

打开 drivers/hwmon/hdaps.c 文件,然后将以下文本添加到 include 部分中:#include <linux/reboot.h>。并紧挨着 hdaps_read_pair 子程序后面添加下面的新子程序:

清单 2. 来自 hdaps.c 的完整的 panicShake 子程序

/*
 * panicShake - reboot the machine if shaken
 */
extern void panicShake(void)
{
 int ret, x, y; // return value and x,y from hdaps
 int int baseX = -5000; // off scale default values
 int baseY = -5000;
 int totalDev = 0; // running total of deviations from rest (shaking total)
 int devThreshold = 4000; // larger threshold for more shaking
 int dimShiftX = 150; // in case your users shake more in a certain dimension
 int dimShiftY = 150;

 while(1)
 {
  ret = hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y);
  if (!ret)
  {
   if( x != 0 && y != 0 )
   {
    // if its a successful read and not a zero read
    if( baseX == -5000 )
    {
     baseX = x;
     baseY = y;
    }
    if( abs(baseX - x) > dimShiftX || abs(baseY - y) > dimShiftY )
    {
     totalDev += abs(baseX - x);
     totalDev += abs(baseY - y);
    }
    if( totalDev > devThreshold )
    {
     printk(KERN_EMERG "ok, ok! you're shaking my substrate - restarting");
     emergency_restart();
    }
   }//if not a zero value
  }//if successful read of hdaps data

 }//infinite while

}//panicShake

震动检测程序就绪后,需要在系统出现紧急情况时调用该检测程序。打开 kernel/panic.c 文件,并在紧挨着 panicBlink 条件部分之前的位置上放置一个对 panicShake(); 子程序的调用。发出 make 命令。趁着对内核进行重新构建时,让我们复查一下震动检测代码。首先,设置一些变量:

清单 3. panicShake 变量

 int ret, x, y; // return value and x,y from hdaps
 int baseX = -5000; // off scale default values
 int baseY = -5000;
 int totalDev = 0; // running total of deviations from rest (shaking total)
 int devThreshold = 4000; // larger threshold for more shaking
 int dimShiftX = 150; // in case your users shake more in a certain dimension
 int dimShiftY = 150;
 

需要特别注意的是偏差阈值参数和空间移位参数。这些参数可能需要根据尝试检测的动作的独特性质做出调整。例如,如果感觉迫切需要像完成篮球传球动作一样震动计算机,可尝试减少 dimShiftX 参数以更轻松地检测垂直于计算机屏幕的动作。反过来,如果震动脉冲触发剧烈的锯齿状动作,则考虑减少 dimShiftY 参数,以便快速地检测平行于屏幕的震动并在发生进一步的损害之前重置计算机。

空间参数选择 150 及总偏差选择 4000 都旨在检测一般用户的典型震动动作。要立即响应输入,请尝试将空间移位参数减少到 10 或更少,并将总偏差参数减少到 10 或更少。这些值将导致其他类型的输入被立即识别出来,例如猛击键盘或拍打显示器外壳。

接下来,考虑无限循环语句和条件。

清单 4. panicShake hdaps 读取和基本设置

 while(1)
 {
  ret = hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y);
  if (!ret)
  {
   if( x != 0 && y != 0 )
   {
    // if its a successful read and not a zero read
    if( baseX == -5000 )
    {
     baseX = x;
     baseY = y;
    }

代码运行如下:其余时间里,从 Hdaps 传感器中读取当前加速度传感器读数。读数经常是不成功的或者两个值都等于 0,0,这是不能用的数据。需要避免这些虚假的 0,0 读数,来自传感器各个方向上的每 10 个读数中就会有一个读数是 0,0 —— 无效的数据,确实如此。如果是首次成功读取,则将基本参数设为第一个 x 值和 y 值。如果计算机被放在不平的表面(例如人的膝盖上)时发生紧急情况,这将允许我们更有力地检测震动或其他动作。

子程序的其余部分实现简单的震动检测算法。

清单 5. panicShake 震动检测

    if( abs(baseX - x) > dimShiftX || abs(baseY - y) > dimShiftY )
    {
     totalDev += abs(baseX - x);
     totalDev += abs(baseY - y);
     baseX = x;
     baseY = y;
    }
    if( totalDev > devThreshold )
    {
     printk(KERN_EMERG "ok, ok! you're shaking my substrate - restarting");
     emergency_restart();
    }
   }//if not a zero value
  }//if successful read of hdaps data

 }//infinite while

如果在任意方向上的空间移位大于我们先前设定的阈值,就按照两个方向上移动的量增加总偏差。然后将当前的基数设为现有的加速度级别。这样重复地重新初始化基数值要求用户持续超出空间移位值以增加检测到的总偏差。这允许用户在紧急模式下移动并存储 ThinkPad,从而安全地将机器送到系统管理员那里。如果仅需要侧立、倾斜和持拿 ThinkPad 以触发重新启动,请删除重新初始化设定。


回页首

测试 panicShake() 内核

要发动一种紧急情况,需要在内核中调用紧急情况子程序。创建以下 makefile:obj-m := panicCall.o,程序 panicCall.c 在编译时将使用该文件:

清单 6. panicCall.c 内核模块源代码

/*
 * panicCall.c - Instigate a kernel panic
 */
#include <linux/module.h> /* Needed by all modules */
#lincude <linux/kernel.h> /* Needed for KERN_INFO */

static char *pMesgStr = "PANIC SHAKE AND BAKE";

int init_module(void)
{
 printk(KERN_INFO,"panicCall module loaded\n");
 panic(pMesgStr);
 return(0);
}

void cleanup_module(void)
{
 printk(KERN_INFO,"panicCall module unloaded, beyond possible");
}

以超级用户身份用 make -C /lib/modules/$(uname -r)/build SUBDIRS=$PWD modules 命令编译 panicCall 模块。现在就有了一个可调用的模块可以使用 insmod panicCall.ko 命令触发紧急情况。如果还没有该模块则重新引导(以激活 hdaps 紧急情况下触发启用震动的内核),并运行 insmod panicCall.ko。应当会看到类似以下内容:

清单 7. 内核紧急情况堆栈

panicCall: module license 'unspecified' taints kernel.
Kernel panic - not syncing: PANIC SHAKE AND BAKE ACTIVE
 [<c011a32e>] panic+0x3e/0x174   [<f8a97017>] init_module+0xb/0xc [panicCall]
 [<c013050a>] sys_init_module+0x1382/0x1514   [<c0152413>] do_sync_read+0xb8/0xf3
 [<c012a17f>] autoremove_wake_function+0x0/0x2d   [<c01c0672>]
 	 _atomic_dec_and_lock+0x22/0x2c
 [<c0169c32>] mntput_no_expire+0x11/0x6d   [<c0102bc1>] syscall_call+0x7/0xb

现在拿起计算机,然后用力地晃动它,计算机将打印出 “shaking substrate” 消息并执行重新启动。如果您不希望晃动可能活动的磁盘驱动器,请以超级用户身份发出以下命令:

清单 8. RAM 磁盘创建和模块复制

mkdir /tmp/ramdisk0
mke2fs /dev/ram0
mount /dev/ram0 /tmp/ramdisk0/
cp /root/panicCall.ko /tmp/ramdisk0/
cp /sbin/insmod /tmp/ramdisk0/

现在有了将模块插入位于 RAM 磁盘的内核所需的两个文件。用以下部分更新 /etc/init.d/halt 脚本,将其放在刚好位于 fsck check 部分之下 halt execute 部分之上的位置:

清单 9. 修改 /etc/init.d/halt

echo "disks now mounted in readonly mode, spin down in 5 seconds";
/sbin/hdparm -S 1 /dev/hda
echo "spin down hda called, waiting 10 seconds";
sleep 10
echo "calling panic from ramdisk location";
/tmp/ramdisk0/insmod /tmp/ramdisk0/panicCall.ko

以超级用户身份执行命令 init 0 以将计算机转入关闭模式中。在调用关闭程序前,计算机将把紧急情况触发模块装入内核,并调用震动检测程序。如果在系统关闭时仔细听硬盘的声音,可以听到明显比以往更长的喀哒声,然后多普勒磁盘将随着机械臂逐渐下降的 “积载” 位置而降低并且磁盘旋转停止。再过大约五秒钟后,将从 RAM 磁盘执行紧急情况模块,而物理磁盘头仍停止不动。现在,您可以随心所欲地晃动 ThinkPad 而无需考虑磁盘的运行状况。


回页首

用户空间关闭和动作检测

很多 IT 管理员都十分怀念能够随时获知硬件物理历史记录的功能。使用同一个简单的震动检测算法、一个 Perl 脚本和一种监视策略,管理员将能够更好地跟踪硬件的状态。例如,使用下面的 Perl 脚本在计算机遭到用户震动时平稳地关闭计算机。根据用户对 ThinkPad 的操作发送一封电子邮件、闪烁 “ThinkLight” 或播放一个声音文件,这些都可以轻松地完成。

清单 10. 用于检测震动的 Perl 脚本,第 1 部分

#!/usr/bin/perl -w
# shakeShutdown.pl - shutdown (or other command) when the computer is shaken
use strict;
my $file = "/sys/devices/platform/hdaps/position";
my $baseX = -5000;
my $baseY = -5000;
my $totalDev = 0;
if( @ARGV != 1 ){ die "specify a threshold value" }
my $devThreshold = $ARGV[0];
my $dimShiftX = 150;
my $dimShiftY = 150;
while(1)
{
 open(HD,"$file") or die "can't open file";
  my $line$line$line$line$line$line$line$line$line = <HD>;
  chomp($line$line$line$line$line$line$line$line$line);
  $line$line$line$line$line$line$line$line$line =~ s/\(//g;
  $line$line$line$line$line$line$line$line$line =~ s/\)//g;
  $line$line$line$line$line$line$line$line$line =~ s/\,/ /g;
  my( $x, $y ) = split " ", $line$line$line$line$line$line$line$line$line;

正如您所见,初始的程序设置几乎与 hdaps 内核代码完全相同。正则表达式和 split 命令仅将 x 值和 y 值从 (5,4) 更改为 5 和 4。程序的其余部分实质上也是相同的:

清单 11. 用于检测震动的 Perl 脚本,第 2 部分

  if( $x != 0 >> $y != 0 )
  {
   if( $baseX == -5000 )
   {
    $baseX = $x;
    $baseY = $y;
   }
   if( abs($baseX - $x) > $dimShiftX || abs($baseY - $y) > $dimShiftY )
   {
    $totalDev += abs($baseX -$x);
    $totalDev += abs($baseY -$y);
    $baseX = $x;
    $baseY = $y;
   }
   if( $totalDev > $devThreshold )
   {
    print "threshold passed $totalDev\n";
    my $res=`/sbin/shutdown -h 1`;
   }
  }
 close(HD);
}

请注意 shutdown -h 1 命令。这将给用户提供 60 秒的时间更改方法并发出关闭中止。更改此命令以运行您最喜欢的邮件程序,用户滥用设备时可以让系统管理员知道此情况。将消息记录到系统日志中,或让 PC 扬声器发出声响以便对获得的物理输入发出即时用户反馈。用 perl shakeShutdown.lp 1000 命令运行脚本。偏差阈值变得更小,因为加速度传感器的每次读取间隔与内核空间的每次读取间隔比较而言减少了。

修改空间移位参数和偏差阈值可以提供有益的对内核空间外部的物理活动的额外监视。例如,要采集 “行走” 行为的数据,需要将空间移位参数设为大约 20,并将偏差阈值设为大约 5000。这将检测到大约 63 个双坐标轴空间移位,这与膝上型计算机在处于运行状态时被放在典型的单肩背膝上型计算机包中的情况一致。检测到这种长距离行走后(不同于从办公位置到会议室的短距离行走),计算机将进入关闭程序以避免过热,因为空气在背包中不流通。修改空间移位参数使其具有高灵敏度,任何较大的撞击、坠落或震动都会被记录下来。


回页首

结束语

通过使用针对用户空间和内核级代码的这些简单算法,现在能够检测、记录和响应来自用户的各种物理输入。使用这些代码示例,从根据连续的加速度计算出来的高度修改硬盘性能参数,到丈量从办公位置到会议室的距离,并将其用邮件发送给空间规划师,您都可以应对自如。

参考资料

学习

获得产品和技术

  • Fedora Core V5 发行版的内核中包括 hdaps。
  • 使用 IBM 试用软件 改进您的下一个开放源码开发项目,这些软件可以通过下载或从 DVD 中获得。

讨论

关于作者

 

Nathan Harrington 是 IBM 的编程人员,目前从事 Linux、WatchPad 1.5 和资源定位技术的工作。

摘至IBM。原文url :http://www.ibm.com/developerworks/cn/java/j-javares.html?ca=dwcn-newsletter-java

对于 Java™ 语言开发人员来说,信息过量是一个真正的问题。每个新入行的程序员都要面临一个令人畏缩的挑战:要进入的行业是一个具有海量知识的行业。要了解的东西简直太多了。对于有经验的老手来说,情况只有些微好转。知识量总在增大,仅仅跟上进度就是一个挑战。如果有一份专业人士必备的书籍和网站列表该有多好!本文就是这个列表。它包含了每个专业的 Java 语言程序员在书架或浏览器书签中必备的最重要的书籍和网站。

这些都是您书架上必备的书和应该经常使用的 Web 链接。时间是一项重要的资源,本文帮您回避那些分心的事情,把时间专注于最有益于您作为Java 语言程序员职业生涯的信息源。尽管有多少程序员就有多少他们最喜欢的参考资料,但本文收集的这些都是优中选优,来源于我书架上的私家珍藏和许多 Java 专家的推荐。

我考虑了两种组织这份参考资料列表的方法。我本可以通过主题领域来组织,这也许很有帮助,但主题列表很快就会变得不实用。相反,我选择了另一种方法:通过类型来组织,即书籍和 Web 站点。

总的来讲,有经验的老手们用 Web 站点来跟踪行业的走势。书籍、文章和论文有助于跟上潮流,但它们总体上更适合于基础学习。极富创造性的书籍偶尔会撼动一两个基础性的东西。这样的书也在本列表之列。

需要提出的一点警告是,专注于 Java 语言的书籍和 Web 站点数量巨大。您钟爱的未必在这份列表里。那并不意味着它们不好。它们只是不在这份列表里而已。可能是因为我还不知道它们。也可能是因为我不认为它们能够算得上是重要资源。不包含一些参考资料是一个评判问题,但如果不这样的话,您也许就要花几小时来拖动滚动条,还要花上成千上万美元来买书。如果您作为一个专业的 Java 程序员,有一些常用的优秀参考资料,一定要让我知道这些资料。这份列表一直都在更新中,您提出的那些也许就会被收录进去。

书籍

每个程序员都会有一些由于经常被当作专业资料参阅而磨坏的书。下列书籍应该是 Java 语言程序员的书架上必备的。书很贵,所以我有意将这份列表弄得很短,仅限于重要书籍。

Thinking in Java (Bruce Eckel)

Thinking in Java, 3rd edition (Bruce Eckel; Prentice Hall PTR,2002 年)
Java 编程思想:第3版 (陈昊鹏 等译; 机械工业出版社,2005 年)
Eckel 的书对于学习如何在 Java 语言环境中使用好面向对象技术极其实用。书中大量的代码样例解释了他所介绍的概念。文字出自一个并不认为 Java 技术总是正确答案的人,所以相当地实用。Eckel 具有多种语言的大量经验,还有用面向对象方式进行思考的扎实技能。本书将这些技能放到实用的 Java 语言环境中。他还在写一本新书,名为 Thinking in Enterprise Java

Effective Java (Joshua Bloch)

Effective Java: Programming Language Guide (Joshua Bloch; Addison-Wesley,2001 年)
Effective Java 中文版 (潘爱民 译; 机械工业出版社,2003 年)
本书是理解优秀 Java 程序设计原则的最佳书籍。大多数材料从其他的 “学习 Java ” 的书中根本找不到。例如,Bloch 书中关于覆盖 equals() 这一章是我读过的最好的参考资料之一。他也在书中包括了很实用的建议:用接口替代抽象类和灵活使用异常。Bloch 是 Sun 公司 Java 平台库的架构师,所以他透彻地了解这门语言。事实上,他编写了该语言中大量有用的库。本书必读!

The Java Programming Language (Ken Arnold, James Gosling, David Holmes)

The Java Programming Language (Ken Arnold,James Gosling,David Holmes; Addison-Wesley,2000 年)
Java 编程语言(第 3 版) (虞万荣 等译,中国电力出版社,2003 年)
这也许是能弄到的最好的 Java 入门读物。它并不是一个标准规范,而是一本介绍每门语言特性的可读书籍。这本书在严谨性和教育性方面权衡得很好,能够让懂编程的人迅速被 Java 语言(和其丰富的类库)所吸引。

Concurrent Programming in Java: Design Principles and Patterns (Doug Lea)

Concurrent Programming in Java: Design Principles and Patterns, 2nd edition (Doug Lea; Addison-Wesley,1999 年)
Java 并发编程—设计原则与模式(第二版) (赵涌 等译,中国电力出版社,2004 年)
不是每个开发人员都需要如此细致地了解并发性,也不是每个工程师都能达到本书的水准,但却没有比本书更好的关于并发性编程的概述了。如果您对此感兴趣,请从这里开始。Lea 是 SUNY 的一名专业程序员,他的和并发性有关的作品和想法都包含在了 JDK 5.0 规范(引自 JSR166)中,所以您大可放心,他所说的关于有效使用 Java 语言的建议是值得一听的。他是一个很善于沟通的人。

Expert One-On-One J2EE Design and Development (Rod Johnson)

Expert One-On-One J2EE Design and Development (Rod Johnson)
WROX: J2EE 设计开发编程指南 (魏海萍 译,电子工业出版社,2003 年)
对于刚接触 J2EE 的人来说,这是唯一的一本如实反映这项技术的书。本书收录了多年的成功经验和失败经验,不同于其他许多作者,Johnson 乐于将失败的经验公诸于众。J2EE 常常都被过度使用。Johnson 的书能帮您避免这一点。

Refactoring (Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts)

Refactoring: Improving the Design of Existing Code (Martin Fowler,Kent Beck,John Brant,William Opdyke,Don Roberts; Addison-Wesley,1999 年)
重构:改善既有代码的设计(中文版) (侯捷 等译,中国电力出版社 ,2003 年)
Fowler 写了几本现已出版的最流行的编程书,包括 Analysis Patterns。他的关于重构 的书是这一主题的基本书籍。重构代码是被程序员忽略的训练,但却是程序员最直观的想法。重构是在不改变代码结果的前提下改进现有代码的设计。这是保持代码整洁的最佳方式,用这种方法设计的代码总是很容易修改。什么时候进行重构呢?当代码“散发出味道”时。Fowler 的书里满是 Java 语言代码的例子。许多 Java 语言集成开发环境(IDE)(包括了 IBM 的 Eclipse)都将 Fowler 的重构包含了进去,每一个都使用他的重构名命名,所以熟悉如extract method 等重构方法还是很值得的。

Design Patterns (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides)

Design Patterns: Elements of Reusable Object Oriented Software (Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides; Addison-Wesley,1997 年)
设计模式:可复用面向对象软件的基础 (李英军 等译,机械工业出版社 ,2005 年)
这是一本在专业程序员圈子里更为有名的书,基于作者共同的绰号,这本书被认为是 “四人帮(GOF)之书”。模式是思考和解决普通编程问题时可以重用的方式。学习模式是一门学科。使用好模式(或知道什么时候 使用模式)是一项技能。忽略模式则是错误的。书中所有的例子都以 C++ 表示,但 Java 语言是从那里诞生的,让 Java 语言程序员由此联系到如何在 Java 语言中实现这些模式相对简单一些。熟悉模式并了解如何使用好模式使编程更加简单。这使得和其他程序员交流也更简单,因为在针对通用问题的通用解决方案中,模式是描述解决方案中彼此协作的大量相关编程概念的快捷方式。一些更为通用的方式,如工厂方法 则是普便存在的,甚至存在于 Java 语言本身。关于明智使用模式的这个主题,也可以阅读 Joshua Kerievsky 的 Refactoring to Patterns,该书称可以让代码来告诉您何时实现模式。

Patterns of Enterprise Application Architecture (Martin Fowler)

Patterns of Enterprise Application Architecture (Martin Fowler; Addison-Wesley,2002 年)
企业应用架构模式 (王怀民 等译,机械工业出版社 ,2004 年)
比起小型、一次性项目来说,企业开发当然代表了更大的挑战。那并不意味着企业开发带来的所有挑战都是新挑战。事实上有些时候,这项开发已经 是以前完成过的了。Fowler 做了很多个这样的项目。他的书提到了一些通用解决方案,并提供了关于使用、折中和可选方案的指导。Fowler 在书中包含了一些熟悉的模式,如模型视图控制器(MVC),他也提供了一些您也许不了解的模式,如处理 Web 站点上特定页面请求或行为请求的 Page Controller 模式。正如您对待大多数模式一样,一旦您读过许多模式,您就会认为 “我已经知道那个模式了” 。也许是这样,但有一个用来引用模式的通用表达方式还是很有帮助的。在有多个组件(由不同人开发)的大型项目中,该类引用是一项很好的帮助。

UML Distilled (Martin Fowler)

UML Distilled: A Brief Guide to the Standard Object Modeling Language (Martin Fowler; Addison-Wesley 2003 年)
UML精粹:标准对象语言简明指南(第3版) (徐家福 译,清华大学出版社 ,2005 年)
对于专业的程序员来说,UML 是一门很重要的通用可视化沟通语言,但是它被过度使用和草率地滥用了。您无需对使用 UML 沟通了解太多。Martin 对 UML 的提炼为您提供了最核心的东西。事实上,前后的封页提供了常规基础上可能使用到的所有东西。该书中 UML 例子的代码都是 Java 代码。

Test-Driven Development: By Example (Kent Beck)

Test-Driven Development: By Example (Kent Beck; Addison-Wesley 2002 年)
测试驱动开发(中文版) (崔凯 译,中国电力出版社 ,2004 年)
测试优先编程将使编程发生革命性变化,能助您成为更好的程序员。在写代码之前编写测试开始很难,但却是一项威力强大的技能。通过优先编写测试,可使代码更加简单,并确保从一开始它就能工作(Beck 实践着他提倡的测试优先,与人合写了 JUnit,这是 Java 语言最流行的测试框架)。Beck 的书是权威的参考资料,扩展了的 Money 例子也用 Java 语言写成。Beck 详述了如何用测试优先进行 思考(这也许是许多程序员首先遇到的障碍)。

The Pragmatic Programmer: From Journeyman to Master (Andy Hunt and Dave Thomas)

The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt 和 David Thomas; Addison-Wesley 1999 年)
程序员修炼之道——从小工到专家 (马维达 译,电子工业出版社 ,2004 年)
做一个纯粹的面向对象开发人员有其优势所在。在当今复杂的社会中,作为 Java 语言开发人员,为完成任务常要妥协。Hunt 和 Thomas 探讨了如何不将真正重要的东西妥协掉而完成任务。这不是一本关于 Java 语言的书,而是 Java 语言开发人员重要的思想读物。例如,我认为没从“要解决问题,而不是推卸责任”这句忠言中受益的程序员,不能像个自豪的艺术家一样在他的杰作上签上大名。

Peopleware: Productive Projects and Teams (Tom DeMarco and Timothy Lister)

Peopleware: Productive Projects and Teams (Tom DeMarco,Timothy Lister; Dorset House,1999 年)
人件(第2版) (UMLChina 翻译组 译,清华大学出版社 ,2003 年)
这份列表中的其他所有书籍都至少和技术有些相关。这本书却不是。在所有技术行话和首字母缩略词的海洋中,有时软件开发人员和经理们会忘记:是 制造了软件。DeMarco 和 Lister 向我们提醒了这一事实,也向我们提醒了形成这一区别的原因。这不是一本关于一门特定编程语言的书籍,但却是每个 Java 语言程序员都应该读的书。关于 “累死程序员如何让经理们适得其反” 还有许多其他的好书,但这是最好的一本。


回页首

Web 站点

Web 站点的数目浩如烟海,如果您想要消化其中的内容,穷毕生之力也难以全部访问。包含 Java 语言某方面内容的详尽的网站列表会大得离谱。下列站点都是可靠、真实的。

Sun 的 Java 技术站点

Sun 的 Java 语言站点
这是 Sun 的 Java 语言主站。作为 Java 语言开发人员,您会发现自己频繁地访问此站点。下列链接特别重要,特别是对新入行的 Java 语言开发人员:

  • New to Java Center
    New to Java Center
    New to Java Center 存放了许多循序渐进的 Java 技术资源链接。如果您刚接触这门语言,这是一个好的起点。
  • 教程和代码库
    Java Tutorial
    这里有大名鼎鼎的 Java Tutorial,以及关于 Java 语言各个方面(例如 Collection)的其他教程。

 

IBM developerWorks

IBM 的 developerWorks
推销自己也许有些厚脸皮,但 developerWorks 是一项巨大的资源,收录了大量 Java 语言工具和技术的教程和文章。其内容从初学者指南到学习这门语言到高级并发性技术。可以根据主题搜索内容,然后根据类型浏览。

Apache Software Foundation

Apache Software Foundation
Apache 站点是许多可重用库(通用领域)和工具的主页,这些库和工具帮助 Java 开发人员进行开发。这里的内容全都是开放源码,所以尽管下载想要的吧!许多极其流行的 Java 语言库和工具(如 Struts、Ant 和 Tomcat)都始于 Apache 项目。Jakarta 专区汇聚了大多数新兴的 Java 语言材料。

Eclipse.org

Eclipse
有几个好的 Java 语言集成开发环境(IDE)。Eclipse(来自 IBM)是最新的 IDE 之一,它很快成为 Java 语言开发的首要 IDE。它完全是开源的,这意味着它是免费的。该站包含了学习如何有效使用 Eclipse 的各种参考资料。这里还有关于 Standard Widget Toolkit(SWT)的信息,SWT 是相对于 Swing 来说更加轻量级的选择。

Eclipse 插件中心和 Eclipse 插件

Eclipse 插件中心Eclipse 插件
Eclipse 基于插件架构。事实上,插件是 Eclipse 的 Java 语言开发组件。但有差不多上千个插件,从 Web 开发的插件到在 Eclipse 环境中玩游戏的插件。这两个站点分类列出了大多数插件,可以进行搜索。它们是很棒的资源。如果您想在 Eclipse 开发环境中弄点新东西,幸运的话有某个插件可能已经实现,从这两个站点能找到想要的插件。这两个站点都允许评论插件,这样您就可以知道哪些插件好,哪些值得一试。

JUnit.org

JUnit.org
Junit 是 Java 语言中一个基本的单元测试框架。该站点包含了 Junit 最新最棒的版本,外加大量有关测试(Java 语言或者其他语言的)各个层面上(针对桌面应用程序、Web 应用程序、J2EE 应用程序等)的其他资源。如果您想找测试资源,这里就是最佳起点。

TheServerSide.com

TheServerSide.com
如果您要(或将要)从事服务器端 Java 语言的开发,此站点是一处举足轻重的资源。您可以到这里找到有关 JBoss、J2EE、LDAP、Struts 和大量其他主题的文章,并且都是完全可检索的。这些文章不仅仅是简单描述 Java 语言的特征或者支持的库。它们更进一步地描述了库的新奇用法(如使用 Jakarta Velocity 作为规则引擎,而不是模板引擎)。它们也提供了有关 Java 语言现状的连续评论(当前的一篇文章是由 Tim Bray 所写的 Java is boring )。该站点更好的通用功能之一是对 Java 语言工具和产品(应用服务器等)的矩阵式比较。

Bruce Eckel’s MindView, Inc.

Bruce Eckel’s MindView, Inc.
Eckel 写了几本 “用 …… 进行思考” 的书,内容关于 Java 语言、Python 和 C++ ,当我学习 Java 语言时,他的 Thinking in Java 对我尤其有帮助。它很实用并切中要害,在“在 Java 语言环境中如何面向对象思考”方面具有卓识。您可以从此站点免费下载他所有书籍的电子版。他也写了许多好文章,并且他把这些文章的链接都放到了这里(包括关于 Jython、Java 和 .NET 比较等内容的文章)。

ONJava.com

ONJava.com
O’Reilley 历年来出版了一些有关编程语言和工具的优秀书籍。他们的专注于 Java 语言的网站也不错。它有些有关各种 Java 语言工具(如 JDOM 和 Hibernate)、Java 平台(如 J2SE 和 J2EE)不同领域不同部分的文章。全部都可以被检索到。他们有优秀的文章和教程。该站点按主题排列。例如有 Java 和 XML、Java Security、Wireless Java 和 Java SysAdmin。该站点也有到 O’Reilley Learning Lab 的链接,在那里您能获得在线参考资料(Java 语言相关和其他的)。那些不是免费的,但是许多都面向大学认证。因此您可以以一种很方便的方式来学习技能,并得到一些认证。

java.net

java.net 社区
java.net 社区有多个“社区”,有特定于主题的论坛和文章。例如 Java Desktop 社区有各类与 Java 语言桌面开发相关的资料。Java Patterns 社区作为一个门户,也许对提供 Java 语言的模式资源相当感兴趣。还有一个 Java User Groups (JUG) 社区,在那里能找到有关创建、加入和管理一个 JUG 的信息。


回页首

结束语

任何 “好的”、“关键性的” 或者 “重要的” 参考资料列表都注定是不完整的,本文的列表也未能例外。 Java 语言的书籍数目众多,当然,万维网也很庞大。除本文所列的参考资料之外,还有很多用于学习 Java 语言的参考资料。但如果您拥有了这里所提到的所有书籍、网站、文章或者教程,您应当已经拥有了一个使您良好开端并助您登堂入室的实用宝库。

最后,要成为一个能力日增和高效的 Java 语言开发人员,方法就是用它工作,动手来尝试。如果有一个教程详细介绍了所需创建的软件的每一部分,您很可能并没得到多少好处。有时,您可能得走自己的路。在成功地尝试了一些新的东西之后,您可能想要写一篇文章、教程或者一本书来分享您所学到的。

参考资料

关于作者

 

Roy Miller 是一名独立软件开发培训师、程序员兼作家,他在充满挑战、快节奏的咨询公司里从事了十多年软件开发和项目管理工作。他最初在 Andersen Consulting(现在是 Accenture)公司工作,在那里,他管理团队实现了许多系统,从主机记帐系统到星形模式数据集市。最近三年来,他在北卡罗来纳州 Holly Springs 的 RoleModel Software, Inc. 公司工作,在那里他专业地运用着 Java 技术,并担任开发人员兼 Extreme Programming (XP) 培训师。他与人合著了 Addison-Wesley XP 系列的 Extreme Programming Applied: Playing to Win 一书,最近他写了 Managing Software for Growth: Without Fear, Control and the Manufacturing Mindset 一书,来帮助经理和管理层理解:像 XP 这样的敏捷构建方法为什么比传统的方法更有效。2003 年,他创办了自己的公司:The Other Road,该公司帮助其他公司了解如何向 XP 和被他称为 Extreme Business (XB) 的方法转换。