帅's profile北邮纯净水的BLOGPhotosBlogLists Tools Help

Blog


    11/7/2009

    (译文)Gentoo的前世今生

    (译文)Gentoo的前世今生 PART 1(完成版)

    Making the distribution, Part 1

    Birth of the Gentoo Linux



    我和Linux

    现今对每一个linux爱好者来说,linux不再只是一个字面上的名称,她所呈现的一切对很多开发人员来说已经超过了他们所接触过的任何东西,linux比它们更强大、更令人着迷和称赞。当我在新墨西哥大学担任系统管理员时便与linux结下了不解之缘。 那时因为我们的NT服务器运行得非常棒,我的手头上也有了很多空余的时间可以加以利用,就这样第一个linux操作系统被我安装到了一台Pentium 166的主机上,接下来的不断学习和深入理解的过程使我对linux越来越着迷了......

    一开始学习了linux下的很多细节的东西:网络访问、执行备份、搞定samba等等。接着我建了一个qmail和apache的服务器并学习了python编程和shell编程。我还搭建了一个小型局域网接着把linux请回了家,在尝试过很多发行版后我最终选择了Stampede Linux这个版本(注:该版本从2001起就没有再更新了)详细的消息可以看一下 http://distrowatch.com/table.php?distribution=stampede
    你知道学习linux的过程是怎么样的吗?:第一、努力搞清楚linux基本的东西;第二、当你已经有了相当好的掌握程度之后,学习定制你的linux,知识的累积会和你深入的程度成正比。由于linux并没有隐藏任何东西,当linux对你来说变得越来越得心应手之后就可以开始探究技术和那些实现这些技术的工具了。

    Linux的潜能

    Linux提供了很多以前我所没有见到过的东西,如果一定要我用一个词来形容这些不可思议的话,我选择“潜能”这个单词:用来维护、改变、提高事物的能力,这种能力甚至能够冲破一些固有规则的约束。  当我把kernel升级到一个更新的版本时,简简单单的就把我眼前的这个linux的性能提升了很多,更为令人兴奋的是这种改变几乎每时每刻都在进行着。而我也正是这种进步的一份子,伴随着linux的前进而不断进步着, 对我而言这种感觉真的很棒。

    如果你和我是同一类人,在你进入开源世界和linux世界之前大概看过位于Redmond和Cupertino的那些大公司们准备的下一代操作系统,它们确实如你所愿般的完美,然而那些东西却始终都只是一个虚幻的影子而已。然后就在我们慢慢等待的过程中linux来到了我们面前。虽然等来的这个精灵并不如我们预料的那么完美,但是她却提供给了我们这些喜欢动手hack的男孩和女孩一个亲手改变她的机会。就这样我们一边期待着一个更强大的操作系统,一边津津有味的hack我们的linux。日子一天一天过去,直到某天我们才突然发现原来期待着的那个强大的操作系统其实就在我们自己的手中,大家不约而同的笑了起来,也决定了继续在linux这条路上走下去。

    Linux的人文艺术

    我学到的另一件事就是Linux对人们的影响,这个话题可能听上去还真有点新鲜,是吧?Linux不仅仅只是一堆源代码的,它其实就是一个“社区”,从一开始的依赖这个社区解决我们提出的问题到付出我们的时间和经验帮助他人,渐渐的我们也成为了这个社区的一部分。

    IRC (Internet relay chat)既是一个交朋友的好地方也是一个很打发时间的场所。irc.openprojects.net上的 #stampede频道已经成为了我在网络上正式的安乐窝^-^。那是我解答自己疑问的地方,也是第一次回答朋友问题的地方。#stampede频道需要很多有安装经验的用户去帮助那些新手解决他们刚刚开始安装后碰到的各种各样的问题。由于那些新手在安装过程遇到的问题在irc中越来越普遍,原来很多有经验的Stampede Linux用户渐渐失去了他们一开始的热情 。但是我依然还是很兴奋,因为很多菜鸟的问题我都知道解决的办法,要我忍着不回答那些问题我可做不到!当然我也并不是唯一的那个对解决新手问题乐此不彼的人,同样的家伙也有不少。我也承认自己也有那么点私心,想从那些更有经验的家伙们(不是指Stampede的开发人员)身上学到更多的东西。

    如何起步

    当有朋友问我如何才能加入一个开源项目时,我告诉他们的是首先是找一个能为他人做些什么的地方,就算那里只是解答一些很基础的问题。一份诚挚的渴望帮助他人的愿望是通往Linux社区的通行证,因为这份诚挚的愿望同样也扎根在每一个开源项目开发人员的心中(不仅仅只是Linux项目),也应该扎根在那里。

    沿着这条路走下去不可避免的你会遇到比你更有经验的同志,你将会从他们身上学到更多的知识,就像以前新手从你身上学习时一样。另一方面,当你积累起更多的经验时在碰到某些问题时你就会用一个新方法去解决它而不是用以前惯用的一套思路。你遇到的一些开发人员有时会提出一些建议,有时又或者会需要一些帮助,他们更可能会邀请你加入他们的开发队伍;如果你的助人为乐成为焦点时,他们可能会笑着从你身边经过;如果你帮助了很多很多人之后,你在社区内肯定会备受瞩目。在Stampede和我身上这些故事都曾经发生过。

    渐渐的我在Stampede的开发越来越深入,不久以后我就成为了一个正是的Stampede开发人员。在受到了Stampede的领导者 Matt Wood的鼓励后,我开始对用于Stampede Linux软件包的原有的.slp机制进行升级。当时,.slp软件包格式包含一个.tar.bz2的软件包和后面的一个包含软件描述及软件包创作者等等在内的一个定长的页脚。这种实现的方式有两个主要问题:页脚部分实际上包含的内容根本达不到定长所约定的字节数;该格式没有预留任何扩充余地(也就是说如果未来没有办法加入一些可能需要的额外信息)。显然这些问题需要动一次大手术了,活活。

    和那些老资格的Stampede开发人员工作一段时间后,我拟了一个解决上面那些问题的草案。过了一阵子我便开始用Python先编写了一些原始的实现方案,新的格式(代号slpv6)有些类似与Amiga世界的IFF格式。下一代的.slp格式包含了了2 32(注1)个字段,字段种类为2 32种,每个字段最大数据段同样为2 32bytes。新的格式不仅具有良好的扩充性而且比纯文本更加紧凑和简洁并易于解析。二进制代码和文本都能存储在这样的格式当中,该架构对其本身在未来的进一步发展带来了无限的可能性。我的想法是把这个新版的动态header加入道打包文件的结尾部分,从而这个新版本的.slp格式未来可以为Stempede用户服务相当一段时间并且同时又能和标准的UNIX档案文件保持不错的兼容性。

    丑陋的一面

    slpv6的开发进展很顺利,所有的资深开发者看到我取得的成果后都很高兴。不幸的是,两名刚加入的Stampede开发者想要自己掌控slpv6项目。由于不欣赏我选择的开发方向,他们花了很大劲诋毁和打击这个新的slpv6系统,虽然我也用了大量时间一边继续我的开发一边加入讨论一边回应他们的攻击, 但是这样做也没从根本上解决问题。最后一切都变的很明了,他们只是很擅长辩论,并且显而易见的是除非走他们自己的路子,不然是不会罢休的。 幸运的是我的项目依然得到了资深开发人员的认可和支持。可是这些讨论渐渐地使我背上了一些包袱,同时对Stampede的开发也产生了一些不好地影响。唉。。。。。。。

    可惜我没办法使这些家伙消失,原来还可以在#stampede频道里和那些高级的开发者互相交谈,但是现在不得不退了出来。每次只要我一进入那个频道,他们就开始变得很不友好,总是在破坏我想要进行得工作。这些家伙会使用各种各样的方法:比如一个开发者会议(其实只是想当着其他资深开发者的面侮辱我)。他们还尝试用投票的方法控制Stempede,当然那种投票只在他们可以得到更多支持的时候才会举行。但是自始至终我在这样的情况下都没有放弃过我得slpv6的开发工作。不用多说,资深开发者都喜欢我的开发项目也都支持我继续做下去(没有他们的支持,我不可能克服那么多困难坚持下去)。  

    对这些异类的了解

    我习惯于把这两个家伙和这种类型的开发者称为“异类”。虽然我的开发工作因此变得很很不愉快,但是我还是学会了怎么样去对付他们。就这点我乐于给各位提供一个对这些“异类”的全方面的描绘:他们的品质、采用的方法以及当你作为一个项目领导者怎么样才能对抗这些”异类“或是尽可能的用最小的代价去改变他们。

    为了消除情绪上可能存在的危险,你需要具备一个先决条件:意志力。如果你不能用一种既礼貌又态度坚决的方式回应你的对手,事情就会变得很糟糕。“异类”的目的就是尽可能多的在你的项目中取得控制权,这么做会使他或她感觉更具有力量。首先,他们会对某个项目或是项目的开发人员进行片面的指责和抱怨,同时他们也会阻止那些对这个项目富有建设性的提议。当然这些家伙在他们获得项目管理人员位置之前也不会对这个项目伸出任何的援手。目的就是使你确信只有依靠他们的那些“独道的、富有素养”的眼光才能最终解决问题,这样你就不得不给他们足够的权限去实现这些。

    如果指责和抱怨没起什么作用,这些“异类”就会要求举行一个开发者会议。这将会给他们一个可以分裂你开发团队的机会。在觉得本方这方面已经得到了大多数人的支持后,他们就会举行一次投票决定(当然他们知道赢的会是他们的情况下)。如果并没有赢得投票或是投票被驳回,那么下周他们还是会提出举行一次会议以便再一次的分裂你的团队,然后再是那种无休止的循环。

    如果会议的方法行不通,“异类”们将会变成革新运动者。他们会用一种更民主(也就是更容易操纵)的办法来取代先前压迫性的和非公平的决策方案。这些办法常常包括令人信服的让你去为你的开发团队中的大部分人做任何事。异类比较偏爱这个办法,因为你没有办法弃大多数投票表决的结果于不顾(活活活)。你许可这些事情发生的时候就已经把那把通往你的”Lexus“的”钥匙“交到了他们的手里,这将使你失去能力。

    ”异类“们用的另一种方法是激怒你的主要开发人员并使他们离开,然后在你的开发团队混乱的时候尝试重新组织该项目的管理团队。如果所有的努力都没有成功的话,他们会聚集尽可能多的叛离者并把他们安插在你的项目中,痛啊!

    对付这些异类

    区分这些家伙还是相当容易的。他们不会写一行代码(也不愿意写),相反他们会花大量的时间讨论那些更重要的问题(对了,就是那些管理方面的问题)。假设你是一个项目管理者,对付他们非常容易。只需要告诉他们,在没有看到高质量的代码之前你是不会考虑他们所谓的建议的。或者在他们提出”建设性“的批评之前强调对于某个项目有建设性得帮助也包括服从项目的管理人员。如果他们开始编制优质的代码并且越来越有易于这个项目,那么就太好了。如果没有,就告诫他们离开。在你忽略这帮家伙一段时间后,他们会选择离开或是一边采取行动一边写一些代码,世界就这样清净了^_^。

    不幸的是Stampede的那些资深开发人员对”异类“并没有采取更多的管理措施。换句话说,他们许可了这两个家伙对我(和其他人)的无休止的纠缠。虽然这些资深开发者总是赞赏我的项目,但是对那两个家伙他们却并没有做的更多。然后终于有一天我决定制作一个自己的发行版,因为我觉得这样做比忍受那两个家伙更容易些。我退出了Stampede的开发团队并开始制定自己发行版的一些计划和草案。

    一段时间之内,我对自己因为两个低等级开发者而离开一个项目还是感到有些不可思议。其实他们没有涉及到的实际情况却真正显示出这个项目存在很严重的管理方面的问题,如果高等级的开发人员不能或者不愿意确认Stampede的开发成果是可喜的和有益的话,我想我不会愿意继续留在那里。


    新的开始

    离开Stampede后我做的第一件事就是长长的舒了口气。喔……,整个世界都清净了。现在我有了足够的时间来思考我自己的Linux发行版的轮廓和将给Linux发行版的布局带来什么新的贡献。对Stampede感兴趣的一件事是它所具有的原生的性能(这得感谢它使用的带有实验性质的、并针对Pentium处理器优化过的pgcc编译器),所以我决定首先我考虑的就是性能。除了更少的CPU占用率以外,我还希望它更精简。很多发行版本(特别是那些流行的热缩塑料封装的家伙)默认启动了太多的daemons以至于打开一个xterm(X环境下的终端)后系统所剩余的可用RAM已经所剩无几了。我希望自己的发行版能更小也更强,为此我把目光放到了最大限度的榨取让这个操作系统运行的硬件平台的性能上。为此我下决心进行一个整体测试并处理掉所有细节中的性能方面的问题。

    但是我真的很 缺乏对应的资源,因为我是这个发行版的唯一的一个开发人员!我该怎样做才能只靠自己就鼓捣出不逊色于Redhat或是Caldera这样的产品呢?解决办法是采用自动控制技术。我必须写一些脚本以便所有的事情都可以自动搞定,这样我就可以事半功倍了。毕竟,电脑们这些方面做得更好,对吧?

    很快我发现光是写一些自动化的脚本还远远不够,需要设计的是一整套能从源代码产生一个完整Linux系统的机制。我实验性的把它称做ebuild系统并且开始了工作。ebuild系统可以自动的建立所有一个发行版所需要的二进制文件,包括从解压源代码并打好相应的patch再到编译、封包的一系列过程的自动化解决方案。在一个基本、原始的ebuild可以工作后,我开始为一个Linux发行版必要的一些关键组成部分(像是gcc、glibc、binutils、util-linux和friends)撰写ebuild脚本。通过重新撰写初始化脚本(基于以前我为Stampede设计的初始化脚本)把原先的Stampede开发系统逐渐的演变成一个我自己的系统,接着用来测试每一个我自己建立好的新的软件包。

    几个月之后我有了一个完整的,自主的Linux版本。我给她起了个名字『Enoch』然后坐着满足得笑了起来。但是什么改变了Enoch、Gentoo的发展又是怎么样的?续篇将会告诉大家Enoch是怎么演变成Gentoo的和我在这条路上将要面对的许多新的挑战。

    敬请期待^_^



    翻译:linky_fan              @            www.linuxfans.org




    原文如下:
    http://www.gentoo.org/doc/en/articles/making-the-distro-p1.xml

    注1:我觉得应该是2的32次方,原始文档2和32之间只是一个空格。


    2006-7-20  第一次增加
    2006-7-24  第二次增加
    2006-7-26  第三次增加&完成


    (译文)Gentoo的前世今生 PART 2(完成版)

    Making the distribution, Part 2

    From Enoch to Gentoo, via minor setbacks and corporate run-ins


    Enoch踏出的第一步

    我在先前的文章中告诉了大家那段和Stampede开发团队在一起的、曾经最兴旺的时光和最后为什么离开的原因(就是想离那些有低级政治目的的、想控制项目的那帮家伙远点)。因为这些爱管闲事的好事者的干涉,我才会觉得装配一个自己的Linux发行版比在那种恶劣条件下改进Stampede要简单的多。幸运的是,我离开Stampede时是带着满满当当的经验离开的,这些经验与在Stampede的工作(应该是实质性的吧?)是分不开的,维护一些软件包也好、设计初始化脚本也好或是领导slpv6(下一代软件包管理系统)都使我相关方面的知识和经验得到了极大的丰富。

    Enoch是我开始工作的这个版本的一个代号,得益于为它开发的高智能的包管理和升级系统,它将会是一个速度飞快的版本。我不得不承认这套智能化的系统在整个版本中占据了很大一部分位置,因为对于我这个光杆司令来说在那种重复性的劳动中消耗时间是没法接受的,所以才会要求开发中的系统必须自动为我完成那些琐事。另一方面完全由源代码来构建整个发行版(比那些“spin off”的版本、例如RedHat要好)也需要把工作划分好并尽可能多的挤出空闲时间来做这些工做。

    使最基本的Enoch系统启动和运行之后,我回到了irc.openprojects.net并开设了自己的#enoch频道。在那里我逐渐聚集起了10个开发人员组成的团队。在早期的那段时间里我们整天都聚集在IRC里,用空下来的时间制作我们的发行版。在我们无私的付出和大家的齐心协力的hack下,在不断的消除bug和新的bug的过程中,Enoch每天都在变化着,不管是专业化的程度还是各方面的功能都变得越来越出色。

    Enoch的第一块绊脚石

    不可避免的一天,Enoch碰到了它的第一块绊脚石。在加入了Xfree86、glib、gtk+之后,我决定把xmms(一个基于X11/gtk+的MP3/CD播放软件)弄进我的发行版,因为也该到了用音乐来调剂调剂的时候了!但是在安装好xmms之后启动它时......X死锁了!最初我觉得是自己使用的编译器的优化参数造成的("-O6 -mpentiumpro",在你看来有点诧异吧?)。第一个想到的解决办法就是用标准的编译器选项来编译,但是问题依然没有解决。然后只好到处寻找解决方法,接下来整整几个星期的开发时间我都用来追踪这个错误。一天,我收到了一个叫Omegardan的Enoch使用者的电子邮件,他也同样碰到了xmms的这个死锁问题。

    交流了一段时间然后历经了n个小时的检测后我们发现死锁的原因在于POSIX的线程描述符(POSIX threads-related issue)。因为一些原因,pthread_mutex_trylock()函数没有返回它应该返回的值。作为一个Linux版本的创始者,这种类型的bug是我真的不愿意碰见的家伙。我指望开发人员能能够释出完美的源代码以便我可以把精力放到提高Linux易用性上,而不是把时间花在修复别人源代码的bug上。当然很快我就发现这种希望仅仅只是一个美好的想法罢了,相同的错误有时还是会出现。

    在找到问题后,我们发现它不是xmms本身的问题,也不时gtk+或glib的问题,也不是Xfree86 3.3.5没有thread-safe和死锁的问题,而是令人惊异的存在于Linux 的POSIX的线程执行本身,具体来说就是版本2.1.2的GNU C库(glibc)的部分代码中存在bug。我很震惊的是在Linux如此核心的部分居然存在这样严重的bug(而且我们为Enoch使用的glibc的版本是它的release版本,并不是什么prerelease版本或是CVS版本!)。

    那么怎么样才能解决这个问题呢?我们不可能马上就能拿出一个修补方案,但是在浏览了一堆glibc开发人员的邮件列表后,我偶然发现了还有一个人也碰到了相同的问题,然后在glibc开发人员在回复他的邮件里我们找到了那个附带的补丁,它为我们解决了那个线程问题。但我令我好奇的是为什么同样使用glibc 2.1.2的RedHat 6没有受这个bug的影响(当时RedHat 6的发布时间先于那个补丁的出现)。为了找到答案,我下载了RedHat里glibc的SRPM包(source RPM)想看一下他们使用的补丁是怎么样的。

    RedHat有他们自己的glibc补丁来解决pthread_mutex_trylock()函数的问题。显而易见的是他们也碰到了同样的问题,然后自己进行了修补。但是由于RedHat没有把这个补丁回馈到glibc的开发社区,其他人们就没有办法分享这个补丁。但是也可能是RedHat把这个修补方案回馈到了glibc的开发社区,然儿glibc的开发人员并没有接受这个修补方案。 或者这个bug只会在特定版本的binutils和特定版本的编译器连用时才会触发,然而RedHat使用的binutils和编译器的版本并不是这两个特定的版本(虽然RedHat还是给出了这个补丁)。我猜测我们永远也不会知道究竟事情的真相是什么样的,但是我学会的一件事情是:RedHat的SRPM包里有很多定制的补丁和增强代码,而这些代码和补丁看来从来没有回馈到原始的开发人员那里。我将会为此来上一段激昂的演说。

    激情的演说

    当你将一大堆各种各样的源代码汇聚成一个Linux发行版时,把所有你做好的bug fix和补丁反馈给原始的某个软件包的开发人员是一件相当重要的事情,就如我了解到的那样,这是发行版的开发人员为Linux做贡献的很多途径中的一个。我们也恰好就是这样的一群人,为的就是把很多不同的程序和软件集合在一起,让它们工作起来就像是一个整体。将来我们也会把我们们对一些软件所做的修改和补丁反馈回原始软件的开发人员以便其他的用户和后来的发行版能从中受益。如果你只是把补丁留在你自己那里,这样做不会对任何人有什么帮助,很多人们将会为一些相同的问题浪费掉大量的时间。这种不顾别人的方式违背了整个开源世界的精神和宗旨,同时对Linux的发展也只是有害无益。或许我应该说这样的做法对我们来说就是一个大大的“BUG”。

    不幸的是一些发行版(啊咳)(RedHat)并不如其他一些版本(Debian)那样对整个开源社区分享他们的成果。

    编译器的艺术

    在我们尝试解决glibc 线程问题的时候,我给Ulrich Drepper发了封email(他是Cygnus的一员并且在glibc的开发中举足轻重)。我在e-mail中提到了我们碰到的POSIX线程问题和我们在Enoch中使用pgcc来获得优化的性能。在他的回信中他这样提到(我解释一下):“我们自己的包含在CodeFusion中的编译器制作的可执行代码比其他的一些编译器、比如pgcc编译出来的代码执行速度更快速。”显然我对测试测试Cygnus那帮家伙开发的神秘的“turbo”编译器非常有兴趣。

    因此我申请拿到了一个Cygnus Codefusion 1.0的demo拷贝以便我可以对它的性能做一个测试。Omegadan和我对测试的结果很吃惊,它同Ulrich提到的那样出色。x86的后端提高了90%的有关cpu-intersive的可执行文件的执行效率(比如bzip2)。几乎每一个程序都能从中获得至少10%的真实世界的性能提升,而我们所作的仅仅是换了一个编译器。Enoch的速度也因此获得了30%-40%的提升。同时性能也提高了不少,提升的幅度超过了我们以前把编译器从gcc切换到pgcc时提高的幅度。显然,在对这个编译器的测试后,我们很希望把这个编译器包含在Enoch中,有点幸运的是CodeFusion CD中的包含的源代码遵循的是GPL,这样在Enoch中使用这个编译器已经可以算是已经得到了完全的认可了..........,至少我们是这么想的。

    异常事件的发生

    为了能在Enoch中使用这个编译器,我给Cygnus的市场部主管发了一封电子邮件,但是期望中的“哦,拿去用好了,感谢使用我们的编译器!”这样的回复并没有收到,取而代之的是一句“虽然在技术上我们许可使用Cygnus的编译器,但是我们强烈建议不要在在Enoch中使用该编译器或是包含它的源代码。接着在我的回复中我问了他们这样一个问题:“既然不愿意让别人使用它的源代码,为什么还在以GPL的许可条例来发布它的源代码?”作为一个猜测,我觉得他们事实上是不想以GPL的方式来发布他们的源代码的,但是由于这个编译器是源自egcs(以GPL方式发布的),他们除了以GPL方式发布之外别无选择。

    这是当某一个公司想使用开源的代码来生产私有产品这样的情况时,GPL如何阻止这样的事情发生的一个很好的例子。我比较有根据的一个猜测是Cygnus担心我们使用这个编译器后将会打击到他们整个产品框架的销售,更加奇怪的是不管是他们的行销方案还是InfoWorld的预览中都没有提及包含在CodeFusion中的那个新的编译器,因为CodeFusion销售的是一套“development IDE”而不是一个编译器。

    为了缓解一下他们那种偏执的态度,我提出了个建议,就是在我们的Enoch主页上放置上CodeFusion的签注文件并加上一个链接来刺激CodeFusion的销售。从我个人的观点来说,我不认为一个“turbo”的Enoch会影响到CodeFusion(虽然它是一个IDE产品)的销售情况。但是我还在想方设法的令到他们愉快,比如告诉他们这个IDE的组件是一个商业化的产品,我们也并没希望或者有什么意图用Enoch来发行它。

    我把这个(大方的)请求用电子邮件的方式发给了Cygnus,但是收到的确实另一个奇怪的回复。他们想得到所有我们关于“市场元素”方面的具有权威的权利(显然,这也包括了我们网站上的内容),真是太令人震惊了。Cyguns的营销团队似乎对Linux社区和GPL的运作一无所知,事到如今我终于决定终止与Cygnus彼此间的联系,因为再这样下去事情会变得怎么样谁都不知道。与此同时,我们为Enoch准备了两个版本,一个是内部的“turbo”版,一个是公开的“non-turbo”版,其实就是把决定留在将来再去做。

    但是几个月之后,他们就把CodeFusion x86的backend换成了gcc 2.95.2,现在不只是那些知道包含在CodeFusion CD中的“隐秘的GPL编译器”的这群人可以获益,几乎每一个人都可以从这个新的优秀的backend中获益了。然后我们还是决定继续前行,尽量使用gcc来替代CodeFusion的编译器。在gcc 2.95.2已经越来越成熟的情况下,我们已经可以放开Cygnus了(同时,RedHat却为购买这个CodeFusion而花费了比较冤的一笔钱了。)(注:新的x86版本gcc 2.95.2的backend为新的Linux发行版提供了一开始我们提到的很重要的速度提升,它也为FreeBSD 4.0相对3.3.6版本速度上提升做出了很大的贡献。你注意到这两个提升的不同点吗?)

    肥皂盒

    感谢这件事情和其他的一些经验,我从中对那些以开源为主要获利手段的企业有了很深的理解。虽然对个人来说,乐于生产私有闭源软件这件事并没有任何错误的地方,但是一个开源企业搅乱或是拒绝与其他的开源世界合作是没有任何意义的;同样,不支持GPL或是其他的等等也没有什么意义。这是一个实践性质的并具有现实意义的观点。

    思想和代码上自由的交换才是开源企业得以获利的根本,这点他们应该充分的认识到。反过来,对立与GPL标准只会破坏这个他们依赖于发展与繁荣的环境。换句话说,开源的环境是你事业的土壤,保护这片土壤的纯净还是很有意义的。

    我也懂得在短时期内保留一些代码上秘密来获得财富的累积是一个颇具诱惑性的东西,先进的代码和特别的技术提供给了人们一个在竞争中获得优势的绝好机会,由此可以获得增长的销售业绩和利益。但是当你的目的是成为一个唯一的产品提供者,而这个产品商业的成分大于开源的成分时,开源世界是不会许可这样排外性质地使用开源或是相关东西的,这就是开源的意义。

    回到Enoch

    现在,我从自己的肥皂盒中出来并继续我的故事。 

    由于Enoch已经变得越来越出色,更名的计划也就这样列入了我们的议事日程当中,接着“Gentoo Linux”诞生了。然后就是朝Gentoo Linux 的1.0版本努力前进中。大约也是这个时候,我决定帮我那台Celeron 300M(超频到450M并且十分稳定)的老电脑升级一下,新平台是一块崭新的Abit BP6主板(从市场上找到的双Celeron接口的)。在卖掉了老主板后我把我两个Celeron 366的系统集中起来,然后把Celeron 366超到了500Mhz,然后开始工作了。但是我注意到我的新机器不是非常稳定。 

    显然我第一个反应就是把频率改回没超之前的366Mhz,但是随之而来却遇到了一个更奇怪的问题:不管CPU全速运转多少时间,系统都不会死锁;但是一旦空闲下来过一夜的话,系统有很大的可能就会完全死锁掉。是的,这是一个idle bug----噢!在作了一些调查之后,我发现在这块主板上也有其他用户碰到了这个相同的问题。原因是BP6主板上的一个芯片(可能是PCI控制器)与标准规格有点不同或是比较古怪,这个东西就是造成Linux在空闲时候死锁的主要原因。

    我渐渐的心烦意乱起来,因为我没法再去采购另外的PC部件了,Gentoo的开发也只好被迫终止下来。我也开始对Linux越来越有些悲观的情绪了并决定转向FreeBSD。是的,的确是FreeBSD!这部分就此为止了,我们Part3再见了:)


    原文出处:
    http://www.gentoo.org/doc/en/articles/making-the-distro-p2.xml

    翻译:linky_fan              @            www.linuxfans.org



    2006-8-2  第一次增加
    2006-8-9  第二次增加
    2006-8-10  第三次增加※

    (译文)Gentoo的前世今生 part3 (完成版※)

    Making the distribution, Part 3
    The author strays from Linux and then returns

    在前一篇文章的结尾部分,我说到因为新升级的双Celeron主板(Abit BP6)存在一个古怪的空闲时死锁的问题导致Gentoo开发停止。虽然解决问题的办法就是更换主板,但是我已经没有重新更换主板的资金了,这件事也打击了我对Linux的信心并使我决定中断Gentoo的开发并转向了FreeBSD。我需要的是一个可以正常运转的系统,而Linux在这个时候的表现并不尽如人意(一天到晚的死锁),那个当口,我觉得是好好接触接触FreeBSD的时候了,便在机器上安装了FreeBSD后开始了又一次的捣腾,在接下去的几个月中,我也几乎没有再碰过Linux一个指头。

    FreeBSD之印象

    首先,我真的很喜欢FreeBSD。我感觉这个操作系统是一个组合的很完美的系统,它的几乎每一个部分都同样精巧,而这种精巧的在Linux世界中几乎不存在。我的满意实质上是来源于那些FreeBSD中非常充足的man page,这可不像Linux里那些只有GNU info文档的很多软件那样让人根本没法用。

    最最重要的是我对FreeBSD中维护与升级系统的ports系统印象非常深刻。与Linux维护与升级的方法不同,ports使用的不是二进制的软件包而是直接去原始的软件站点下载所需要的源代码并编译。不管你是安装Samba或是升级核心系统都是在你的机器上用源代码编译而成。这样的实现方法和我在Gentoo Linux中建立的那套机制有着异曲同工之处。从这点和其他许多方面来说,FreeBSD的这种设计符合我作为一个开发人员和一个系统管理员所期望的那种感觉。就这样,FreeBSD为我营造了整整几个月舒适的工作环境,同样我也很乐意于花些时间在这个出色的操纵系统中探求与获取知识。

    FreeBSD的优点

    很多Linux和FreeBSD之间的不同点都是源自与它们本身开发架构的不同。Linux的开发架构非常松散,我们只是依靠不同的发行版把分散在Internet上呈离散状态的很多部分组合成一个完整的Linux,而FreeBSD和其他BSD系统(OpenBSD和NetBSD)都有一个唯一的核心小组来确保源代码的单一性和协调性,这样至少每一种BSD自身都拥有一套统一的源代码设置。这是一件挺棒的事情,也是FreeBSD感觉上和Linux那种“patch集合”有所不同的主要原因。

    接下来,我们在纯技术方面再作个比较。很多FreeBSD的粉丝都声称FreeBSD比Linux更合适用作服务器上跑的操作系统,他们会告许你在高负载情况下FreeBSD表现得更好,而且它的TCP/IP栈相对出色一些(如果你用Linux 2.2或更早版本的内核和FreeBSD作比较,我同意这个说法)。FreeBSD确实是一个很好的服务器操作系统,这点勿庸置疑,但是这只是FreeBSD相对Linux 2.2或更早的内核版本时的情况。我作为一个新版本内核的粉丝,早就在我的电脑上用上了2.4测试版的内核,它确是也很棒,从出色的TCP/IP栈到整个重新设计的“netfilter”系统都是。我觉得在不久的将来,新的性能标准将会由Linux来定义,而“free UNIX”将会在商业领域面对Linux强有力的挑战。

    FreeBSD的不足

    与服务器领域的应用不同,在桌面应用上,Linux占有绝对份额上的优势(仅相对BSD来说,Linux不管是对Win还是对MAC都完全处于下风)。所有最新的桌面应用软件一定是先在Linux上出现、在3D加速和声卡的支持方面,Linux也比BSD走在了前面。随着2.4版本内核的临近,Linux在这块地盘上还是会继续保持它的优势地位。

    我对FreeBSD采用的UFS文件系统并不喜欢,虽然UFS相对Linux的ext2文件系统来说更健壮,但是付出的代价是那个另人昏昏欲睡的龟速。现在也有一个UFS文件系统的扩展叫“soft update”,它是把小块的IO操作聚合成大的文件块后再写入物理硬盘以提高文件系统的速度,就算“soft update”这套机制大幅提高了UFS文件系统的性能,我也没法就说在所有方面的比较中UFS都比ext2优秀。当然,UFS和“soft update”更加可靠,FreeBSD也可能会在文件系统的战争中击败Linux,但是请不要忘记,输给FreeBSD的仅仅只是现在的2.2版本或者更旧版本的Linux,这不代表将来也会。

    现在,我们把话题转变一下,我们比较的双方是现今的Linux 2.2版本、2.4版本和FreeBSD。Reiserfs(一个新的日志型文件系统)已经给我们带来了一阵惊喜,而Linux还有蓄势待发的ext3、IBM的JFS和XFS文件系统,这些文件系统都在提供高可靠性的同时提供了优秀的性能。Reiserfs给了Linux在文件系统上超越FreeBSD的一个契机,这也是我认为Linux 2.4版本会上演大逆转的原因,FreeBSD的传统强项在未来2.4内核面前可能会荡然无存。

    回到Gentoo的开发

    几个月之后决定重新回到Linux世界的我在一台新的机器上又装了Gentoo。首先,回到Gentoo的开发中来是一个计算后的决定--我已经花费了很多时间使自己成为一个Linux的万事通,而现在怀抱着BSD就等于是把以前学到的知识都浪费掉了,这样做我觉得不是很值得。而且在更新Gentoo Linux后那么一段很短的时间内,我为“为什么再次回到Linux怀抱”找到了几个新的理由,也就是前面提到过的kernel以及文件系统的改进等等。FreeBSD是一个宁静的家园,但是这样的宁静太安静了点,这样的宁静也包含着困惑。相反Linux世界充满着活力,发展也是日新月异。如果你所寻找的是兴奋和创新的地方,那么毫无疑问Linux就是你所向往的世外桃源。

    Linux从2.0进步到2.2给我的感觉就是满失望的,但是2.4时代是绝对值得去守候着的,为此Gentoo Linux重新回到了我们面前,那种兴奋的感觉也重新回到了我的心中。

    Gentoo Linux重生的另一个关键因素是我们开发团队的领导者--Achim Gottinger。我想花一点篇幅对他所给予的帮助(使我我重新开始了Gentoo Linux的开发)致以诚挚的感谢。我在回到Linux世界之前就开始与Achim Gottinger有了电子邮件上的往来,在几乎每一封他的电子邮件中,我都可以看到一些新的.ebuild或者是些迫切需要修复的bug。在我回到Linux世界并重新开始了Gentoo的开发之后,Achim继续贡献着他的时间和精力使这个发行版步入正轨。直到最近,Achim和我都是Gentoo Linux仅有的两个开发者,这也是出于选择的结果。因为我们都使用几乎相同的发行版,也因为Achim的技术,我们可以轻松的完成非常巨大的工作量以至于我觉得加入第三名开发者并不会对我们的进展有什么帮助。现在Achim是Gentoo Linux开发组的负责人,几乎每天Gentoo的都会有基础部分中主要的提高。我们已经走到了这里,也已经准备好了CVS树为后来者提供一个协同开发平台,小心翼翼的逐步扩大Gentoo开发队伍的工作也开始付诸实施。

    新的版本

    我没有觉得花在BSD上的时间是在浪费。实际上,它给了我一个很好的机会来反省一下整个Linux社区存在的问题和Gentoo Linux应该做点什么来改进这些短处。. 

    在新版本的Gentoo Linux中,我下决定不再使用pgcc或者什么非常优化的参数来编译所有的软件包,因为稳定性还是要放在第一位的,我们默认将会使用合理的优化选项("-O2 -mpentium"),但也同时向用户提供了可以简单自定义的优化选项来满足了一些同胞希望得到最“bleed edge”的系统(通过我们的自动化系统完成)这么个愿望。

    FreeBSD给了我一个关于“自动化定制系统如何工作?”这个问句一个很好的提示。我决定在我们的自动化定制系统(现在叫做Portage)中加入一些FreeBSD的特性来制作一个新一代的ports系统。 

    Portage 可以说是Gentoo Linux的心脏,它所具备的东西远远超过一个简单的包管理机制或是一个系统管理机制。Portage通过它包含的对制作工具的设置和制作脚本可以使你从源代码构建一个完整的发行版系统。但对我来说更重要的是,Portage给用户提供了一个可以完全接触Gentoo Linux构建智慧的途径。对我们开发者来说,这意味着当Gentoo Linux不断发展的同时我们也记录下了一个发行版制作的过程。Portage的易用性和可读性也为越来越多的人提供了一个窥探Linux内部的窗口,它也为后来者贡献他们的代码和脚本打开了方便之门。

    Portage是我们为他人展示Linux技术和原理的一条途径,通货学习自动化制作脚本,你可以看到大量各不相同的包是怎么互相适应并结合成一个整体的。如果你需要,你也可以从我们的站点上攫取整个CVS树然后自己hack并制作个人的Linux发行版。我们坚信这是一件好事情--我们希望把知识交给渴望这些知识的人们以便他们可以把Linux带入一个新的领域。

    商业上的关注

    起初,有许多拥有不同背景的人们加入了Gentoo的开发中来。因为这个,我们的开发人员对于如何最终在Gentoo上获得经济利益也有许多各不相同的打算,对此我并没有太多的诧异。基本上有这么两种类型的开发人员:一类群体反对用Gentoo来追名逐利,另一类群体则对使Gentoo Linux成为一个成功的商业产品非常感兴趣。这是一个预料中会存在分歧的地方,第一类群体认为商业化的运作包含着腐化等不良的影响,而第二类群体则认为没有这么多的负面因素。

    在以前还是Enoch的那段时光中,我对商业成份究竟有利还是有弊这点也很难做个了断。我验证过的是像Debian这样的Linux发行版真正忠于“自由”这样的事实,我喜欢这样。对比其他商业化的发行版,他们给用户带来的易用性包括了在各自的网站上提供一份完整的安装说明,这也是一个我想去借鉴的好东西。

    同样,我也真心希望Gentoo Linux能够成为一个成功的商业版本,为了这个目的,我努力想在商业和开源之间找到一个平衡点,可是直到最近我还是没有能够找到这么一个黄金分割点。

    该做些什么

    我们该怎么做才能在商业化和非商业化中取得平衡呢?关键的一点是一定不能忘记我们的基楚和根本---Gentoo Linux 作为一个开源软件的根本和基础。所有我们作出的努力都必须遵循这个基础,这不仅仅是肯定开源软件或只是使用开源软件,还是对开源软件和开源发行版开发的鼓励和支持,也不会发对用这样的一个对待开源姿态来获取商业回报。更重要的是,我们绝不会采用商业化的模型,因为这样做对于其他发行版使用我们的源代码有阻碍作用。我们的开发团队对所有人来说都会是开放的和可接近的,而Gentoo Linux这个自由发行版不仅仅可以被大家接受还会因为很多人的鼓励而继续走下去。我们必会成为开源运动的倡导者,一个把这个理念贯彻到行动中而不是停留在文字层面上的倡导者。

    如果某公司需要为一个商业化的基于Linux技术的需求使用Gentoo Linux,他们可以从我们的CVS树中攫取这些代码并马上开始使用它们,因为所有我们的分散的工作都是基于GPL。我们在确信所有基于Gentoo Linux的衍生产物都遵循GNU Public License的前提下是不会在任何地方限制别人使用我们的代码的。

    我们希望有尽可能多的人们从我们的工作中受益,但是我们也希望尽可能多的能从你对Gentoo Linux的提高中获益。如果你公司的产品有很大一部份是基于Gentoo Linux的话,希望你可以把所有可分类的修改和提高发送给我们以便加入到CVS树中使更多的人获益。继续保管和改进你提交的修改后,你也能从我们所做的修改中受益。我们也鼓励商业实体和非商业实体之间的合作,举个例子来说:不管是在他的ISP中使用Gentoo Linux的系统管理员还是用Gentoo Linux构建商业服务器的公司都能从彼此对Gentoo Linux的改进中获益。是时候来促进在人们之间的自由代码交换了,这也只有开源软件可以做到。

    将来要走的路

    现在离Gentoo Linux 1.0 的发布已经很近了(在你在developerWorks上读这篇文章的时候它可能已经发布了,想想现在的2006.0是不是大家有种沧海桑田的感觉^-^??)。但是Gentoo Linux将来的方向会是怎么样的呢?

    当我们逐步迈向2.0版本时,我希望继续提升Portage作为Gentoo Linux核心的性能,因为任何关于Gentoo Linux主要的进步都会从Portage的进步开始。主要代码从bash转换到python的过程我也会继续下去,因为这么做会使我们加入新的设计(比如为我们的全自动构造系统设计的面向对象的新东东)。

    除了Portage的修改,我还希望小心谨慎的寻找技术出色并且和我们使用相同版本的开发者加入我们的开发团队。在扩大了开发团队之后,我们可以为Gentoo Linux的加入更多的自动化定制脚本。比这更重要的是,适当扩大的开发团队可以使Gentoo Linux站在Linux技术的尖锋之上,这才是乐趣所在嘛:)

    我们也希望商业化的Linux技术公司可以把Gentoo Linux作为他们产品的基础。现在我们已经有了这样一个关系,将来也会更多的,而这样的协作承诺充满着乐趣并对于Gentoo Linux的用户非常有益。

    最后我要说的是,我们主要的目标是为Linux社区提供有意义的贡献。虽然可选择的发行版很多,但是Gentoo Linux还是拥有许多其他版本所没有的东西。我们对未来Gentoo Linux发展充满着信心,我们希望你也有同样的感觉。

    原文如下:
    http://www.gentoo.org/doc/en/articles/making-the-distro-p3.xml

    翻译:linky_fan              @            www.linuxfans.org


    2006-8-13日第一次更新
    2006-8-16日第二次更新
    2006-8-21日第三次更新※


    5/12/2009

    iTunes U

    资料: 什么是iTunes U

    你可以在 iTunes Store 找到 iTunes U。在 iTunes U 之中,你可以找到讲座、语言课程、有书声、与 podcast。不论你是大学生或是终身学习者,iTunes U 的一切都对你免费开放。你可以在家中使用电脑或在行动中使用 iPod 或 iPhone 来学习,不论你处在何时何地,课程都不会间断。

    你可以探索来自一流大学、博物馆、以及世界各地其他文化机构的教育性音频档案与视频档案。你一开始可先看看最常被下载的内容或选择感兴趣的领域。要参观 Stanford 或 MIT 等个别的大学请点击 Universities & Colleges,或者你也可以点击 Beyond Campus 以使用来自 Smithsonian、MoMA、New York Public Library 等着名机构的丰富内容。

    你可一次下载一个 iTunes U 的录音课程或影片课程,或订阅进行中的课程或系列,如此一来只要它们一推出就会自动被下载。要寻找 iTunes U 课程是很简单的:只要找到以大学或机构的名字命名的播放列表即可。将你的 iPod 或 iPhone 连接到电脑可以将课程同步,以便在行动中学习。你也可以坐在舒服的沙发上用 Apple TV 观赏视频讲座。

    苹果公司iTunes副总裁Eddy Cue指出,任何人都可以很容易地通过iTunes U获得由美国国内许多知名院校提供的令人惊喜的教育资料。教育是一个终身学习的过程,我们非常高兴可以让每个人都能免费下载讲义、报告和其他学术资料。美国斯坦福大学教务处长John Etchemendy说,“同苹果公司以及iTunes U的合作是一种富于创造力和革新的方式,使成千上万的人可以参与到我们的教学和科研中来,更好地分享我们的智慧成果和发现,通过共享老师和学生的学术成果来服务大众。”

    同时,Podcasting又是开放性的,每个用户都可以免费获得自己的空间,可以制作音视频节目并将其上传到网站上与他人分享,也可以选择或订阅别人提供的音视频节目并下载到移动终端随时收听。这种开放与共享的机制使得每一个人即是资源共享的受益者又是资源的创造和提供者,这是一种良性循环的系统,必将成为新一代全球化的学习资源环境。
    4/22/2009

    mail server methods


            
    目录:
    1、   基础知识;
    1)   MTAMDAMUA
    2)   Linux Email的一般形式
    3)   DNS域名解析
    4)   Linux Email的一般实现形式
    5)   IMAP的实现
    6)   ESMTP
    2、   Linux Mail解决方案的要求;
    1)   对收发信性能的要求;
    2)   可扩展性和安全性
    3)   提供集成度
    4)   开发量要少
    5)   TLS
    6)   虚拟主机
    3、   Linux Mail解决方案详解;
    1)   qmail方案(qmail+vpopmail+mysql);
    a)          简述;
    b)         功能指标;
    c)          所需软件;
    d)         系统架构;
    e)          安装;
    f)          系统管理及工具;
    g)          LDAP
    h)         IMAP
    i)           TLS
    j)           缺陷和改进余地
    2)   postftx方案;
    a)          概念说明:
                                                                                     i.              Cyrus SASL;
                                                                                    ii.              PAM;
                                                                                  iii.              Berkerley DB;
    b)         简述;
    c)          功能指标;
    d)         需要软件;
    e)          架构;
    f)          安装;
    g)          LDAP实现;
    h)         IMAP实现;
    i)           缺陷和改进余地
     
    3)   courier方案(courier-mta +imap +mysql + mailadm
    a)          功能指标
    b)         需要软件;
    c)          架构;
    d)         安装;
    e)          LDAP
    f)          缺陷;
    4、   其他的可能方案;
    a)          其他部分Linux商业方案
    b)         跨平台JAMES 方案;
    c)          Lotus Mail方案;
    d)         WINDOWS方案;
                                                                                     i.              普通Mail邮件;
                                                                                    ii.              Exchange server

    选用方案:


    配置一台Postfix邮件服务器的过程。实现虚拟域、虚拟用户、POP3、POP3S、SMTP、SMTPS、IMAP、IMAPS、防毒、防SPAM、网页邮件功能。



    涉及的软件
    1.        Redhat Enterprice AS 4 U2
    2.        Mysql
    系统自带
    用于存储虚拟域、虚拟用户等信息
    3.        Apache
    系统自带
    运行网页邮件SquirrelMail和PostfixAdmin时使用。
    4.        PHP
    系统自带
    运行网页邮件SquirrelMail和PostfixAdmin时使用
    5.        Cyrus-sasl
    系统自带
    实现带验证的SMTP时使用。
    6.        Courier authentication library
    http://www.courier-mta.org/ 下载
    实现带验证的SMTP时使用。
    7.        Postfix
    http://postfix.org 下载
    一个MTA,虽然RHEL 4 自带Postfix,但因为其不支持SSL及Mysql,所以我们需要自行编译。
    8.        PostfixAdmin
    http://postfixadmin.com/ 下载
    虚拟域、虚拟用户等信息是放在Mysql内的,安装PostfixAdmin后,就可以用浏览器管理这些信息。
    9.        SquirrelMail
    系统自带
    一个基于IMAP的Webmail客户端。
    10.        Dovecot
    系统自带
    提供POP3,POP3S,IMAP,IMAPS功能。

    11.        F-prot
    http://www.f-prot.com 下载,Linux workstation 版个人使用是免费的
    提供杀毒功能,据闻速度和病毒库比开源的Clamav好。
    12.        SpamAssassin
    系统自带
    提供过滤垃圾邮件功能。
    13.        MailScanner
    http://www.sng.ecs.soton.ac.uk/mailscanner/ 下载
    Postfix 是使用MailScanner 调用f-prot 与SpamAssassin,或者其它调用方法效率更好,但MailScanner配置比较直观,且最近拿了一个大奖 http://www.linuxawards.co.uk/content/view/26/42/
    6/16/2008

    tips

    1、xmlns协议版本
    http://www.w3.org/TR/WD-xsl   草案XSL  
    http://www.w3.org/1999/XSL/Transform   w3c标准XSL  
    两者语法相差很多~
    <xsl:stylesheet   xmlns:xsl="http://www.w3.org/TR/WD-xsl"   language="JavaScript">  
    <xsl:stylesheet   version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
    上面两个是不同xsl里面的代码,但里面有有些语法不兼容,比如说:  
      <xsl:if   expr="depth(this)   >   2">  
      display:   none;  
      </xsl:if>//适用于第一个,不适用第二个  
      test=[count(child::*)=0]//适用于第二个,不适用第一个  

    2、新闻标题过长,如何省略并加……
    <%
    if len(rs("新闻标题")) >=16
        then response.write left(rs("新闻标题"),15)&"......"
          else response.write rs("新闻标题")
    end if
    %>
    3、文本框和密码框长度和高度不一样的解决方法:
    因为密码默认都用·代替了文字,所以肯定是比文本要小,如果用CSS定义就不会出现问题啦。
    代码如下:
    <form name="admin_login" method="post" action="admin_check.asp">
    账号:
    <input name="admin_user" type="text" style="width:120px;height:25px;">
    密码:
    <input name="admin_pswd" type="password" style="width:120px;height:25px;">
    <input type="image" name="sumbit" src="images/login_sumbit.gif" width="60" height="20" border="0">
    </form>
     
    4、mb change logo
    includes文件夹里的footer.php里面
    defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
    global $_VERSION;
    ?>
    <div align="center"><br /><?php echo _D_MAMBORS; ?></div>
    <?php echo _D_MAMBORS; ?>这个换成其他就OK了
    5、启动X
    配置起动K:
    #echo "exec startkde" > ~/.xinitrc
    #startx //可以进入K了
    echo "exec gnome-session" > ~/.xinitrc
    再执行 startx  就进入k 或 g界面了.
    解决办法:
    (1)查看startx文件
    find / -name startx
    找到:/usr/X11R6/bin/startx
    startx中运行了/usr/X11R6/lib/X11/xinit/xinitrc
    (2)修改xinitrc文件
    原内容
    “ twm &
    xclock -geometry 50x50-1+1 &
    xterm -geometry 80x50+494+51 &
    xterm -geometry 80x20+494-0 &
    exec xterm -geometry 80x66+0+0 -name login”
    修改后
    “fcitx &
    exec gnome-session”
     
    【未完待续】

    xmlns

    xmlns:XML命名空间
    2007-10-26 13:40

    Namespaces翻译为名字空间。名字空间有什么作用呢?当我们在一个XML文档中使用他人的或者多个DTD文件,就会出现这样的矛盾:因为XML中标识都是自己创建的,在不同的DTD文件中,标识名可能相同但表示的含义不同,这就可能引起数据混乱。
    比如在一个文档<table>wood table</table>中<table>表示桌子,
    而在另一个文档<table>namelist</table>中<table>表示表格。如果我需要同时处理这两个文档,就会发生名字冲突。
    了解决这个问题,我们引进了namespaces这个概念。namespaces通过给标识名称加一个网址(URL)定位的方法来区别这些名称相同的标识。
    Namespaces同样需要在XML文档的开头部分声明,声明的语法如下:
    <document xmlns:yourname='URL'>
    其中yourname是由你定义的namespaces的名称,URL就是名字空间的网址。
    假设上面的"桌子<table>"文档来自
    http://www.zhuozi.com,我们就可以声明为
    <document xmlns:zhuozi='
    http://www.zhuozi.com'>;
    然后在后面的标识中使用定义好的名字空间:
    <zhuozi:table>wood table</table>
    这样就将这两个<table>区分开来。注意的是:设置URL并不是说这个标识真的要到那个网址去读取,仅仅作为一种区别的标志而已。

    命名冲突
    因为XML文档中使用的元素不是固定的,那么两个不同的XML文档使用同一个名字来描述不同类型的元素的情况就可能发生。而这种情况又往往会导致命名冲突。请看下面两个例子

    这个 XML 文档在table元素中携带了水果的信息:

    <table>
    <tr>
    <td>Apples</td>
    <td>Bananas</td>
    </tr>
    </table>

    这个 XML 文档在table元素中携带了桌子的信息(家具,不能吃的哦):

    <table>
    <name>African Coffee Table</name>
    <width>80</width>
    <length>120</length>
    </table>

    如果上面两个XML文档片断碰巧在一起使用的话,那么将会出现命名冲突的情况。因为这两个片断都包含了<table>元素,而这两个table元素的定义与所包含的内容又各不相同。


    --------------------------------------------------------------------------------

    使用前缀解决命名冲突问题
    下面的XML文档在table元素中携带了信息:

    <h:table>
    <h:tr>
    <h:td>Apples</h:td>
    <h:td>Bananas</h:td>
    </h:tr>
    </h:table>

    下面的XML文档携带了家具table的信息:

    <f:table>
    <f:name>African Coffee Table</f:name>
    <f:width>80</f:width>
    <f:length>120</f:length>
    </f:table>

    现在已经没有元素命名冲突的问题了,因为这两个文档对各自的table元素使用了不同的前缀,table元素在两个文档中分别是(<h:table> 和<f:table>)。

    通过使用前缀,我们创建了两个不同的table元素。


    --------------------------------------------------------------------------------

    使用命名空间
    下面的XML文档在table元素中携带了信息:

    <h:table xmlns:h="" target="_blank">http://www.w3.org/TR/html4/">
    <h:tr>
    <h:td>Apples</h:td>
    <h:td>Bananas</h:td>
    </h:tr>
    </h:table>

    下面的XML文档携带了家具table的信息:

    <f:table xmlns:f="" target="_blank">http://www.w3schools.com/furniture">
    <f:name>African Coffee Table</f:name>
    <f:width>80</f:width>
    <f:length>120</f:length>
    </f:table>

    在上面两个例子中除了使用前缀外,两个table元素都使用了xmlns属性,使元素和不同的命名空间关联到一起。


    --------------------------------------------------------------------------------

    命名空间属性
    命名空间属性一般放置在元素的开始标记处,其使用语法如下所示:

    xmlns:namespace-prefix="namespace"

    在上面的例子中,命名空间定义了一个Internet 地址:

    xmlns:f="http://www.w3schools.com/furniture"

    W3C 命名规范声明命名空间本身就是一个统一资源标示符,Uniform Resource Identifier (URI)。

    当我们在元素的开始标记处使用命名空间时,该元素所有的子元素都将通过一个前缀与同一个命名空间相互关联。

    注意:用来标识命名空间的网络地址并不被XML解析器调用,XML解析器不需要从这个网络地址中查找信息,该网络地址的作用仅仅是给命名空间一个唯一的名字,因此这个网络地址也可以是虚拟的,然而又很多公司经常把这个网络地址值象一个真实的Web页面,这个地址包含了关于当前命名空间更详细的信息。
    可以访问http://www.w3.org/TR/html4/.


    --------------------------------------------------------------------------------

    统一资源标识符
    通用资源标识符(A Uniform Resource Identifier (URI))是一个标识网络资源的字符串。最普通的URI应该是统一资源定位符Uniform Resource Locator (URL)。URL用于标识网络主机的地址。另一方面,另一个不常用的URI是通用资源名字Universal Resource Name (URN)。在我们的例子中,一般使用的是URLs。

    既然前面的例子使用的URL地址来标识命名空间,我们可以确信这个命名空间是唯一的。


    --------------------------------------------------------------------------------

    默认的命名空间
    定义一个默认的XML命名空间使得我们在子元素的开始标记中不需要使用前缀。他的语法如下所示:

    <element xmlns="namespace">

    下面的XML文档在table元素中包含了水果的信息:

    <table xmlns="" target="_blank">http://www.w3.org/TR/html4/">
    <tr>
    <td>Apples</td>
    <td>Bananas</td>
    </tr>
    </table>

    下面的XML文档包含了家具table的信息:

    <table xmlns="" target="_blank">http://www.w3schools.com/furniture">
    <name>African Coffee Table</name>
    <width>80</width>
    <length>120</length>
    </table>


    --------------------------------------------------------------------------------

    使用命名空间
    档开始使用XSL的时候,就会发现命名空间使用的是如此频繁。XSL样式单主要用于将XML文档转换成类似于HTML文件的格式。

    如果看一下下面的XSL文档,就会发现有很多标记都是HTML标记。那些标记并不是HTML标记,是加了前缀的XSL,这个XSL前缀由命名空间"http://www.w3.org/TR/xsl"所标识:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet xmlns:xsl="" target="_blank">http://www.w3.org/TR/xsl">
    <xsl:template match="/">
    <html>
    <body>
    <table border="2" bgcolor="yellow">
    <tr>
    <th>Title</th>
    <th>Artist</th>
    </tr>
    <xsl:for-each select="CATALOG/CD">
    <tr>
    <td><xsl:value-of select="TITLE"/></td>
    <td><xsl:value-of select="ARTIST"/></td>
    </tr>
    </xsl:for-each>
    </table>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>

    【转载】CSS+DIV

    from 徐果萍博客

     

    01.CSS+DIV之第一次接触CD

    星期二, 12月 12th, 2006

      CSS+DIV,一个极其完美的CD组合,一个网站重构的CD元素,一个功能强大的CD家族。以前从未接触过CSS+DIV,网络编辑职位要求我不断学习这些专业知识。为了生存,为了加薪,为了提高职业素质,我开始了CD漫长之路。我对网站设计有着极大的兴趣,但从来没有进行有系统的教育,所以对于CD了解也只是皮毛而已。以前在玩oblog系统的博客程序时,泡在html代码库里N天,便学会最简单的复制粘贴的基本功。而现在要学习CSS+DIV,不知如何落手。花了一个星期,在网上找相关教程。教程要么是一种主食,多得让你吃撑着;要么是一种零食,少得让你饿不死。为了解决温饱问题,我苦思冥想多日,脑门终于大开,蹦出一词:依葫芦画瓢!我边分析边复制边粘贴应该可以把CSS+DIV学会。

      依葫芦画瓢学CSS+DIV系列,适合学习人员,略懂html、css、xhtml、js等知识。对于这些知识,我其实没有深入过研究学习过,只是以前复制粘贴的多了,也就慢慢明白一些常用参数的用法而已。对于批量代码,更加没有仔细剖析过,所以应该来说,学习CSS+DIV必定会遇到一些困难的。网上提供css中文查询的教程也蛮多的,遇到不懂,再去查。同时,要求学习人员有兴趣学习CSS+DIV,并且修得正果之后,能够为我所用。否则的话,根本没有必要浪费时间,和我一起依葫芦画瓢学CSS+DIV。我学习CSS+DIV有三重催化剂:生存+兴趣+实用,所以我没有理由不学好。以前,想学没学,是因为一直迷茫,找不到系统教程;现在,想学要学,是因为懂得清醒,最好的老师就是网络资源。于是,将依葫芦画瓢作为我学习CSS+DIV的方法。

      为了保证《依葫芦画瓢学CSS+DIV》学习效果与教程,我总结几条无师自通的原则:
      其一,为我所用原则。学CSS+DIV,不论是兴趣爱好还是工作需求,最终为我所用。既然开始学了,就应该坚持学到最后,真正从中得到愉悦,从中得到快感。
      其二,稀里糊涂原则。学习有人提倡刨根问底,但我认为学CSS+DIV时,有必要来点稀里糊涂作风,没有必要把每一个参数,每一句代码搞得非常透彻,难得糊涂未尝不可。
      其三,坚持不懈原则。不用多言,学习本来就一项工程,不能只凭着两天的兴趣与激情,要坚持到底。学习CSS+DIV难免会遇到难以消化或理解的时候,但不能就此跳过或放弃。
      其四,思维创新原则。个人对知识理解差异化,所以CSS+DIV学习的悟性会不一样,没有很必要太拘泥于所谓的教程,完全可以顺着自身的思维,拥有量身定做的教程。

      好了,其实每次发现自己撰写整理教程的时候,都比较哆嗦!胡扯那么长长的一段,还没有开始进入CSS+DIV主题内容。因为我今天本来就没有打算有学习CSS+DIV的内容,主要目的是让自己的大脑处于清醒状态。同时,为学习CSS+DIV找到原动力,调整固有的学习方法,纠正原来的意识偏差,同时,也抽时间恶补相关的html和css基本知识,准备《CSS样式表速查手册》查询工具,为《依葫芦画瓢学CSS+DIV》下一课时作准备!

    02.CSS+DIV之模板从偷、切、拼开始

    星期四, 12月 14th, 2006

      身体欠佳,答应“宝贝干女儿”提早休息的,一想到我的“依葫芦画瓢学CSS+DIV”没有更新内容,的确难以入睡,于是不得不拖着病继续坚持把懒人教程的第二课时持撰写完。在开始学习CSS+DIV之前,先来准备一样道具:模板。模板的作用就是为整个页面做一个布局分布样图,使得每一个部分都有CSS+DIV。其实,我个人也非常缺少制作模板的能力与精力,但我学会制作的模板三种“歪术”,那就是偷、切、拼三术。郑重声明:此三术适合不会制作模板或懒于做模板样图人群,并有初步的图片软件处理能力。

      准备图片处理软件:PhotoShop或FireWorks(简称PS或FW),二选一即可。图片处理软件会基本的操作,如复制、粘贴、切割、打字、配色等。接着来熟悉三术。所谓偷术:就是把几张最喜欢的模板偷过来使用的技术,可以全偷,也是可以部分偷。所谓切术:就是把偷到几张模板经过特殊图片处理软件,切去不喜欢的图片。所谓拼术:就是把几个喜欢部分的模板组合拼成一张完整的新图的技术。在我提供的模板中头部、中部、底部是来自于三个不同的模板切图最终组合而成,图在文章最后。  
      
      网上免费模板提供较多,我们可以免费下载用来学习CSS+DIV,有了模板就有了总体布局。所有模板布局大致分为三个部分。
      
      其一,Header 区。顶部,包括网站Logo标志、栏目Menu和广告Banner等。
      其二,PgBody 区。中部,包括内容主体,侧边栏,侧边栏有单与双之分。
      其三,Footer 区。底部,包括网站声明,备案、流量统计、版权等信息。
      
      这是最基本的网站布局,其他的布局都以此为基础细分与删减而成。因身体欠佳,所以偷懒点,内容不多。准备一张模板布局图片,了解布局的三个部分,为进入懒人CSS+DIV学习教程做准备!下篇精彩预告:学习Header 区以外代码编写!
    依葫芦画瓢学CSS+DIV模板样图,放大效果更佳!

    03.CSS+DIV之从DOCTYPE到xmlns

    星期五, 12月 15th, 2006

      时间一晃又一天,天终于放晴天,整理好情绪,开始CD教程新一课时。关键词CSS+DIV也在流量统计中有过访问,而且现在此搜索此关键词,我的博客还是出现在第一页。让我很吃惊,有人已经强烈要求我快点开始把第三课时发表出来。今晚,抽空把所学内容撰写出来,与更多的人CD兴趣者交流分享!

      此课时主要学习内容主要是:DOCTYPE和xmlns。或许对这两个词比较陌生,但必须要学好,而且掌握起来非常简单。在开始解释什么DOCTYPE和xmlns之前,先来熟悉CSS+DIV写入基本结构,新建记事本,将下述代码复制到记事本就OK了,学习内容也算是完成了三分之一。这是最简化的CD代码结构。

    <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” 
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”  xml:lang=”zh-CN”>
    <head>
    </head>
    <body>
    </body>
    </html>

      再来解释代码的具体含义,html成对结构不需要过多说明了。在代码中DOCTYPE,是学习CSS+DIV需要了解并掌握的第一个参数代码。!DOCTYPE这一段代码称为DOCTYPE声明。DOCTYPE是document type(文档类型)的简写,声明网站所采用的XHTML或者HTML是何种版本,而DTD指的是文档类型定义,此参数代码规定此文档的规则,各种不同的浏览器通过识别定义的DTD解析页面。DOCTYPE声明没有的话,所写的CSS+DIV将会失效,位置在XHTML文档开始部分。
        
      知识延伸,自行选学:“XHTML 1.0 提供了三种DTD声明可供选择”
    01.过渡的(Transitional):要求非常宽松的DTD,允许继续使用HTML4.01的标识(要符合xhtml的写法)。
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    02.严格的(Strict):要求严格的DTD,不能使用任何表现层的标识和属性,如

    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
    03.框架的(Frameset):专门针对框架页面设计使用的DTD,页面中包含有框架,需要采用这种DTD。
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd”>
      以上代码,可以忽略学习,因为我们一般采用声明是第一种!

      在html xmlns这一行中,xmlns是xhtml namespace,译为xhtml名字空间。原来的作用是为了说明此编写代码文档谁是拥有者,每个拥有者都可以用网址来指定区分。xhtml是html向xml过渡的标识语言,而xhtml目前版本不能自定义标识,因而此用统一的方法,所有的名字空间指向同一网址http://www.w3.org/1999/xhtml。而紧随其后的xml:lang=”zh-CN”,是指文档使用简体中文。如果不能明白我哆嗦的解释xmlns的话,那就忽略此段文字,原搬复制其代码就OK了!

      此课从DOCTYPE到xmlns理论上十分简单的,没有初学者没有耐心去深入掌握,其内在含义和所起作用的话,直接复制文章开头的代码到所写入CSS+DIV文件就可以了!总算又结束一课时,略有小成就感。下一课时主要学习head区域设置代码。

    04.CSS+DIV之head区必不可少的meta标签

    星期四, 12月 21st, 2006

      这几天手上冻疮在做怪,依葫芦画瓢学CSS+DIV教程也没能及时更新。最为可喜的是,每天会有CSS+DIV通过搜索登录到我的博客上来,只可惜现在的提供内容并不是很多,有点认人失望了,看来以后应该加大强度这方面的更新。这样才能为更多的人提供共享学习资源。费话不哆嗦了,此时课主要学习head区必不可少的meta标签。新建记事本,复制代码,然后我会一一分析其标签代码的具体含义和作用。

    <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” 
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”  xml:lang=”zh-CN”>
    <head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″ />
    <meta http-equiv=”Content-Language” content=”gb2312″ />
    <title>徐果萍博客</title>
    <meta name=”Keywords” content=”博客,互联网,情感,生活,工作” />
    <meta name=”Description” content=”博客,互联网,情感,生活,工作,徐果萍原创博客” />
    <meta name=”author” content=”starpiaosnow@163.com,徐果萍” />
    <meta name=”robots” content=”all|none|index|noindex|follow|nofollow” />
    <meta name=”googlebot” content=”all|none|index|noindex|follow|nofollow” />
    </head>
    <body>
    </body>
    </html>

      红色部分的代码就是此课的学习内容,主要是meta标签常用的标签的相关内容。在没有进入代码学习之前,来掌握一个写入CSS+DIV必备知识点:XHTML语法规则要求所有的标识都必须有开始和结束。如和、和等,不成对的标识,要求在标识最后加一个空格,然后跟一个”/”,加空格的原因是避免代码连在一起浏览器不识别,上述代码有很多实例,不再此列举。

      接着来分析红色代码,什么是meta?meta标签是内嵌在网页中的特殊html标签,包含着关于网页的某些隐藏信息,其作用是向搜索引擎解释所在网页是有关哪方面信息,是网站优化中不可缺少的重要组成部分。在http-equiv表明文档所使用的编码语言,一般情况采用charset=gb2312,也有使用charset=UTF-8的网站,如果使用后者xml:lang也应该修改成为UTF-8。

      再来看看title标签,它应该是网页中最重要的标签,网页中打开最先看到的部分。在这个标签中最好是加上网站的关键字,title标签在搜索引擎比较重要,是在搜索引擎中第一个看到有关我们网站的描述,要做到尽量写入title尽量简洁明了,它最佳位置放在其他meta标签前,这样有利于网站的排名优化。

      而Keywords标签向搜索引擎说明我们网页的关键词,对网站优化起重要角色;Description标签向搜索引擎说明我们站点的主要内容,即站点描述;author标签向搜索引擎显示网站制作的作者,即站长名称;robots标签和googlebot标签主要是向搜索引擎说明文件是否允许检索与查询,具体参数设置解释如下:
        robots标签和googlebot标签属性说明:
      设定为all:文件将被检索,且页面上的链接可以被查询;
      设定为none:文件将不被检索,且页面上的链接不可以被查询;
      设定为index:文件将被检索;
      设定为follow:页面上的链接可以被查询;
      设定为noindex:文件将不被检索,但页面上的链接可以被查询;
      设定为nofollow:文件将不被检索,页面上的链接可以被查询。

      常用设置属性为all即可,meta标签是网站优化的一个重要组成部分,很有必要掌握这些meta标签下的标签名字和标签内容。此课时内容学习差不多了,我们可以把上述代码保存两份,名称分别为css.css和index.htm。打开后一个文件,唯一能够在网页显示的只有title标签,其他的标签只能被搜索引擎所识别。下一课时将继续学习head区其他的一些常用的标签,我也会加快更新进程。

    05.CSS+DIV之icon图标及样式表调用

    星期六, 12月 30th, 2006

      天气突然变冷了,再加上年终工作也比较忙了,我一直没有时间抽出来学习CSS+DIV。现有的学习笔记每天都有人通过搜索引擎来学习。但我所学习的内容并不多,我现在争取尽快更新,以便加速自己的学习能力。此课时继续学习head区icon图标及样式表调用等内容。

      一、icon图标

      icon,就是将某网站加入“收藏夹”之后,原来的IE图标会变成自行设定的图标。其图片大小设置为16*16,将命名为favicon.ico,上传到网站根目录下,然后在我们上课时后head区后继续添加下列代码,即可达到icon图标效果。

    <link rel=”icon” href=”/favicon.ico” mce_href=”/favicon.ico” type=”image/x-icon” />
    <link rel=”shortcut icon” href=”/favicon.ico” mce_href=”/favicon.ico” type=”image/x-icon” />

      
      二、样式表调用

      CSS样式表,Cascading Style Sheet 的缩写,意为层叠样式表单,作用增强控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。调用的方法主要有:

      1.页面内嵌法:直接将样式表写在页面代码的head区。如:

    <style type=”text/css”>
    <!–
    /* 全局CSS定义 */
    body { text-align: center; font-family:”宋体”, arial;margin:0; padding:0; background: #FFF;
    font-size:12px; color:#000;}
    div,form,img,ul,ol,li,dl,dt,dd {margin: 0; padding: 0; border: 0;}
    h1,h2,h3,h4,h5,h6 { margin:0; padding:0;}
    table,td,tr,th{font-size:12px;}
    –>
    </style>

      
      2.外部调用法:将样式表单独写一个.css文件,然后用link调用。

      <link  rel=”stylesheet” rev=”stylesheet” type=”text/css” href=”css.css” mce_href=”css.css”  media=”all”/>
      
      3.双表调用法:适用条件是在netscape4.0以上或其它浏览器中显示时,采用”@import”命令方法。

      <link  rel=”stylesheet” rev=”stylesheet” type=”text/css” href=”css.css” mce_href=”css.css”  media=”all”/>
      <style type=”text/css”>@import url( css.css );</style>

      温馨提醒:一般调用主要是前两种,因第二种只要修改.css文件,就能修改所有调用的页面,所以使用第二种的人会比较多。第一种直接调用法,可以节省读取资源样式表加载的时间。以上代码插入地方还是head区,下一篇学习CSS+DIV各种布局。像我这样的初学者,大部分都是采取复制粘贴修改的形式来学习。

    06.CSS+DIV之五个DIV搞定网页基本布局

    星期日, 01月 21st, 2007

      因工作年底比较忙,把CSS+DIV学习进程延迟下来了。此课学习内容为网页基本布局常用的五个DIV。在学习布局之前,先来介绍写入代码的软件。以前,只用记事本来编辑写入代码,一段时间学习之后,感觉还是使用dreamwaver软件方便,其一、即得即见效果,可及时将代码转变成页面效果;其二、写入代码时有提醒和自动匹配功能;其三、自带常用CSS样式表,可简单调用。打开dreamwaver软件,新建css.css和index.html页面,将这两个文件保存在同一目录下。以下是我新建index.html文件:

    <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” 
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”  xml:lang=”zh-CN”>
    <head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″ />
    <meta http-equiv=”Content-Language” content=”gb2312″ />
    <title>徐果萍博客</title>
    <meta name=”Keywords” content=”博客,互联网,情感,生活,工作” />
    <meta name=”Description” content=”博客,互联网,情感,生活,工作,徐果萍原创博客” />
    <meta name=”author” content=”starpiaosnow@163.com,徐果萍” />
    <meta name=”robots” content=”all” />
    <meta name=”googlebot” content=”all” />
    <link rel=”stylesheet” rev=”stylesheet” type=”text/css” 
    href=”css.css”  media=”all”/>
    </head>
    <body>
    </body>
    </html>

      
    在主体之间写入五个DIV代码:

    <div id=”Container”>页面盒子Container
    <div id=”Header”>页面头部Header</div>
    <div id=”Sidebar”>页面侧边Sidebar</div>
    <div id=”Content”>页面内容Content</div>
    <div id=”Footer”>页面底部Footer</div>
    </div>

      在新建css.css之间写入基本样式CSS代码:

    /*全局定义*/
    body { text-align: center; font-family:”宋体”, arial;margin:0;
     padding:0; background: #FFF; 
    font-size:12px; color:red;}
    /*页面盒子*/
    #Container {width:800px;margin:0 auto;background:#063;}
    /*页面头部*/
    #Header {height:50px;background:#063}
    /*页面侧边*/
    #Sidebar {height:150px;background:#00C}
    /*页面内容*/
    #Content {height:150px;background:#993}
    /*页面底部*/
    #Footer {height:50px;background:#000}

      截图如下:


      以上就是网页基本布局常用的五个DIV,一般网页的布局以此为基准而进行相应的变化。下一课时学习网页布局Layout其他内容。

    07.CSS+DIV之布局Layout参数float\clear\ul\li

    星期一, 01月 22nd, 2007

      在《五个DIV搞定网页基本布局》中,页面分为五个部分,其中页面侧边Sidebar和页面内容Content没有并排,将这两个DIV形成同列并对齐,float和clear参数就可以实现布局Layout,然后再接接着学标题字体大小的控制以及ul、li标签运用。

      一、float
      语法:float: none|left|right
      参数:none: 对象不浮动 left: 对象浮在左边 right: 对象浮在右边
      说明:该属性的值指出了对象是否及如何浮动。

      如,我可以将Sidebar定位在左边,使得页面侧边和页面内容并列。在css.css文件中写入代码:

    #Sidebar{float:left;width:200px;}
      #Content{float:right;width:600px}

      二、clear
      语法:clear: none|left|right|both
      参数:none:允许两边都可以有浮动对象 both:不允许有浮动对象 
      left: 不允许左边有浮动对象 right:不允许右边有浮动对象
      说明:该属性的值指出了不允许有浮动对象的边。
      
      如,我可以将Sidebar和Content通过Footer来对齐两个层,如果两者层高不相同会出现其一占用Footer位置。在css.css文件中写入代码:
      

    #Footer{clear:none;}

      
      三、h1—h6
      我简单地将页面侧边和页面内容进行了定位,现在来设定header标题大小,通过html标题代码h1到h6,一般情况h1网站名/h1,h2网站副标题/h2,h3内容主标题/h3等。在index.html文件中Header写入代码:
      

    <div id=”Header”><h1>徐果萍博客</h1><h2>www.xuguoping.net</h2></div>

      为了避免标题之外会出现空白之处,可以在css.css的文件中为h1,h2写入如下代码:
      

    h1,h2{margin:0;padding:0;}

      
      四、ul、li
      无论是Header区主导航栏还是Footer区底导航栏,我们都可以利用ul和li来写菜单代码。在index.html文件的Footer区新建DIV层。

    <div id=”Footer”><div id=”Fmenu”>
      <ul>
      <li><a href=”#” mce_href=”#”>博客门</a></li>
      <li><a href=”#” mce_href=”#”>追梦阁</a></li>
      <li><a href=”#” mce_href=”#”>工作室</a></li>
      <li><a href=”#” mce_href=”#”>梦幻国</a></li>
      </ul></div>
      </div>
      预览效果,发现利用ul、li制作导航栏菜单,菜单不在同一行,而且菜单前面还有小圆点,利用ul、li制作导航栏菜单,这些问题将留在下一次继续学习修改。

    08.CSS+DIV之ul\li菜单美化

    星期二, 01月 23rd, 2007

      在上一次利用ul、li制作菜单,菜单出现不在同行出现,菜单前面还有小圆点,链接有下划线等,现在来美化ul\li菜单,通过对各种不同参数的设置让我们制作的菜单变得更加漂亮。
      
      一、同行去掉小圆点

      因为小圆点是写入分类出现的,所以只要在css.css文件中Footer处写入代码,就可以轻松除去小圆点。
      #Fmenu ul { list-style:none; margin:0px;}
      #Fmenu ul li {float:left; margin:0 15px}
      #Fmenu { padding:15px 15px 0 0}

      其中list-style:none,取消列表前小圆点。
      margin:0px,删除UL的缩进,使所有列表菜单不缩进。
      float:left,内容同一行显示,不再出现分列显示菜单。
      margin:0 15px,菜单之间产生一个30像素的距离,左和右各15px。
      padding:15px 15px 0 0,利用padding属性固定菜单位置。

      二、去掉链接下划线

      小圆点除去之后,菜单下划线如何除去呢?这下划线产生是链接的属性,所以只要有链接属性,都可以通过以下代码进行美化。分别定义链接link、已使用的链接visited、正在被点击链接hover。其中text-decoration去掉下划线使用none即可,而且可以根据三种状态的不同颜色,css.css文件中Footer处写入代码。
      

    #Fmenu ul li a:link { color:red; text-decoration:none}
      #Fmenu ul li a:visited { color:green; text-decoration:none;}
      #Fmenu ul li a:hover { color:#FFF; text-decoration:underline;}

      三、链接背景色及块级微调

      菜单链接背景色添加非常简单,只要在各种状态下写入background即可。为了使背景色填满整个li的宽度,通过在a的样式定义中增加display:block,使链接以块级元素显示。此外,链接还可以增加text-align:center(菜单的文字属性)、height:20px(增加背景色高度)、margin-left:5px(两菜单相空距离)、line-height:20px(定义行高促使菜单文字纵向居中),css.css文件中Footer处写入代码。
      
    #Fmenu a { display:block; text-align:center; height:20px;}
      #Fmenu li { float:left; width:100px; background:#FFF; margin-left:5px; line-height:20px;}

     
      通过这样三个步骤的话,就可以将菜单美化了。以后可以通过网络资源对这些美化继续深入,初步学习只要会这些,应该会有成就感了。在接着下一课要学习页面布局的其他相关内容!

    [html]<head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″ />
    <meta http-equiv=”Content-Language” content=”gb2312″ />
    <title>徐果萍博客</title>
    <meta name=”Keywords” content=”博客,互联网,情感,生活,工作” />
    <meta name=”Description” content=”博客,互联网,情感,生活,工作,徐果萍原创博客” />
    <meta name=”author” content=”starpiaosnow@163.com,徐果萍” />
    <meta name=”robots” content=”all” />
    <meta name=”googlebot” content=”all” />
    <link rel=”stylesheet” rev=”stylesheet” type=”text/css” media=”all”/>
    <style>
    /*全局定义*/
    body { text-align: center; font-family:”宋体”, arial; margin:0; padding:0; background: #FFF;
    font-size:12px; color:red;}
    h1,h2{ margin:0; padding:0;}
    /*页面盒子*/
    #Container { width:800px; margin:0 auto; background:#063;}
    /*页面头部*/
    #Header { height:50px; background:#063}
    /*页面侧边*/
    #Sidebar { height:150px; background:#00C; float:left; width:200px;}
    /*页面内容*/
    #Content { height:150px; background:#993;}
    /*页面底部*/
    #Footer { height:50px; background:#000; clear:both}
    #Fmenu ul { list-style:none; margin:0px;}
    #Fmenu li { float:left; margin:0 15px;}
    #Fmenu { padding:15px 15px 0 0}
    #Fmenu ul li a:link { text-decoration:underline}
    #Fmenu ul li a:visited { color:green; text-decoration:none;}
    #Fmenu ul li a:hover { color:blue; text-decoration:underline;}
    #Fmenu a { display:block; text-align:center; height:20px;}
    #Fmenu li { float:left; width:100px; background:#FFF; margin-left:5px; line-height:20px;}</style>
    </head>
    <body><div id=”Container”>页面盒子Container
    <div id=”Header”><h1>徐果萍博客</h1><h2>www.xuguoping.net</h2></div>
    <div id=”Sidebar”>页面侧边Sidebar</div>
    <div id=”Content”>页面内容Content</div>
    <div id=”Footer”><div id=”Fmenu”>
    <ul>
    <li><a href=”#” mce_href=”#”>博客门</a></li>
    <li><a href=”#” mce_href=”#”>追梦阁</a></li>
    <li><a href=”#” mce_href=”#”>工作室</a></li>
    <li><a href=”#” mce_href=”#”>梦幻国</a></li>
    </ul></div>
    </div>
    </div>
    </body>
     [/html]

    09.CSS+DIV之强化border属性

    星期二, 05月 15th, 2007

      今天在百度搜索引擎发现了“CSS+DIV”关键词排名从第一页跌到第四页,感觉到蛮可惜的。究其原因应该是好久没有更新依葫芦画瓢学CSS+DIV系列文章造成的,原来计划教程可以与我修改网易版首页共同更新,但首页提前完成了上线了,但还不能完全适应火狐浏览器,在辛苦修改中。求教了一些CSS+DIV高手,他们给我的答案:从最简单的CSS属性学起。将学习笔记整理出来,与更多的CSS+DIV爱好者共同成长。

      在网易首页改版过程中,在div层套入border边框是最常用的,它就像如同表格,可以将样式、文字、图片包装起来。border边框属性主要学习边框风格属性(border-style)、边框宽度属性(border-width)、边框颜色属性(border-color),这三个属性可以对整个边框或者单边框架多样化设置。通过解剖学习的方法,将每一种属性分解出来,更好将基本属性学到位,学会简单的运用。

      1.边框风格属性(border-style),用来设定上下左右边框的风格,具体参数值有:
      
      none (没有边框)、dotted (点线式边框)、dashed (破折线式边框)、solid (直线式边框)、double (双线式边框)、groove (槽线式边框)、ridge(脊线式边框)、inset (内嵌效果的边框)、outset (突起效果的边框),下面以最为常用的直线式边框为例,代码参考写法如下:

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    .apple {border-style:solid;}
    </style>
    </head>
    <body>
    <div class = ”apple”>依葫芦画瓢学CSS+DIV(09):强化border属性</div>
    </body>
    </html>

      2.边框宽度属性(border-width),用来设定上下左右边框的宽度,具体参数值有:

      medium (是缺省值)、thin (比medium细)、thick (比medium粗)、用长度单位定值;可用绝对长度单位(cm, mm, in, pt, pc)或者用相对长度单位 (em, ex, px)。我比较喜欢用px的单位。以直线式1像素边框为例,代码参考写法如下:

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    .apple {border-style:solid; border-width:1px;}
    </style>
    </head>
    <body>
    <div class = ”apple”>依葫芦画瓢学CSS+DIV(09):强化border属性</div>
    </body>
    </html>

      3.边框颜色属性(border-color),用来设定上下左右边框的颜色,颜色值可参照调色板,示例以直线式1像素红色边框为例,代码参考写法如下:

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    .apple {border-style:solid; border-width:1px; border-color:red;}
    </style>
    </head>
    <body>
    <div class = ”apple”>依葫芦画瓢学CSS+DIV(09):强化border属性</div>
    </body>
    </html>

      将这些三个属性分解出来应该很简单的,最后一个属性示例很容易将前面两个属性结合了。其实那样的写法过于详细,可用综合写法对其代码简化。

    .apple {border-style:solid; border-width:1px; border-color:red;} 
    写成<span style=”color:Red”>.apple {border:1px solid red;}</span>

      以上border边框属性是上下左右四个边框统一设定,当然也可分开设定。如右边框,只要将参数值变为:border-right, border-right-width, border-right-style, border-right-color。现举例如下,同样运用综合写法,

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    .apple {border-top:1px solid red; border-right:2px double blue; border-bottom:1px solid red; border-left:2px double blue;}
    </style>
    </head>
    <body>
    <div class = ”apple”>依葫芦画瓢学CSS+DIV(09):强化border属性</div>
    </body>
    </html>

      强化border属性,这是我自学时觉得应该掌握一些基础性的知识,因为这些代码最关键还是要学会运用,光看代码是没有用的,要学会自己去写代码,去发现其中错误的写法,纠正一些常规的写法,这样才能加快手工写入代码的进程。下一课时,准备分享一些font属性个人学习笔记的心得!

     

    10.CSS+DIV之强化font属性

    星期日, 06月 3rd, 2007

      在徐果萍博客上一次的依葫芦画瓢学CSS+DIV中主要学习了在border边框属性的边框风格属性(border-style)、边框宽度属性(border-width)、边框颜色属性(border-color),而此课时主要分享我在学习font属性一些学习心得以及经验。这些是最基本的知识,网络上的教程基本千篇一律。要学会具体去运用这些代码,这才是掌握代码最关键的地方,有很多人属性代码参数都了解,如何去写入规范代码可能就会望而却步了。而font属性是控制字体样式、大小、风格、浓淡等属性,与文本属性有着非常密切关系。我还是把font的相关属性进行分解,一一点学习各种属性代码。

      1.字体名称属性(font-family),设定字体名称,如Arial、Tahoma、Courier、宋体等。

      示例写法为:.apple{font-family:宋体;}

      2.字体大小属性(font-size),设定字体的大小,最常用的字体大小为pt和px(pixel)。我比较喜欢用px来定义字体大小,一般常用大小为12px。

      示例写法为:.apple{font-size:12px;}或.apple{font-size:50%;}或.apple{font-size:larger;}

      3.字体风格属性(font-style),具体参数值有normal, italic, oblique,normal是缺省值,italic, oblique表示斜体。

      示例写法为:.apple{font-sytle:oblique;}

      4.字体浓淡属性(font-weight),具体参数值有normal和bold,normal是缺省值。

      示例写法为:.apple{font-weight:bold;}或.apple{font-weight:lighter;}或.apple{font-weight:数值;}

      5.字体变量属性(font-variant),具体参数值有normal和small-caps,normal是缺省值,small-caps表示小的大写字体。这个参数不太经常用,只适用于将小写字母变成大写。

      示例写法为:.apple {font-variant:small-caps;}

      6.字体综合属性(font),是各种字体属性的综合写法,它综合字体风格属性(font-style),字体变量属性(font-variant),字体浓淡属性(font-weight),字体大小属性(font-size),字体颜色(color)等属性。

      示例写法为:.apple {font: oblique small-caps bold 20px Arial; color:red;}。注意字体综合属性(font)写法顺序为:字体风格(font-style)、字体变量(font-variant)、字体浓淡(font-weight)、字体大小(font-size)、字体名称(font-family)、字体颜色(color)。
      

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    .apple {font: oblique small-caps bold 20px Arial; color:red;}
    </style>
    </head>
    <body>
    <div>依葫芦画瓢学CSS+DIV(10):强化font属性。没有任何font属性设置。</div>
    <div class=”apple”>注意字体综合属性(font)写法顺序为:字体风格(font-style)、字体变量(font-variant)、字体浓淡(font-weight)、字体大小(font-size)、字体名称(font-family)、字体颜色(color)。</div>
    </body>
    </html>
      以上就是最简单的font属性的学习心得,虽然参数不多,但还是需要在运用中加深理解,尤其是在综合写法一定要注意顺序,这些属性可以单独使用也可以混合使用。下一课时徐果萍博客将与CSS+DIV学习者共同学习与交流text文本属性笔记与心得!

    11.CSS+DIV之强化text属性

    星期三, 06月 20th, 2007

      在徐果萍博客上一节的依葫芦画瓢学CSS+DIV中主要强化学习了font相关属性的内容。尤其要注意其注意字体综合属性(font)写法顺序为:字体风格(font-style)、字体变量(font-variant)、字体浓淡(font-weight)、字体大小(font-size)、字体名称(font-family)、字体颜色(color)。而此篇主要学习的内容是在font基础上强化text属性参数的学习。最近又因工作太忙,学习计划一拖再拖,今儿抽个空,把学习笔记整理出来分享,与更多在学习CSS+DIV朋友达成共识,相互交流。

      1.文本对齐属性(text-align),用来设定文本的对齐方式,其相关参数有:left(居左,缺省值)、right(居右)、center(居中)、justify(两端对齐,不常用)。

      示例写法:.apple{text-align:left}或.apple{text-align:right;}

      2.文本修饰属性(text-decoration),用来设定文本划线的属性,其相关参数有:none(无,缺省值)、underline(下划线)、overline(上划线)、line-through (当中划线)。我个人常用none和underline。
      
      示例写法:.apple{text-decoration:underline;}

      3.文本缩进属性(text-indent),用来设定文本首行缩进。其值单位主要有:length长度,绝对单位(cm, mm, in, pt, pc)或者相对单位 (em, ex, px);或者percentage (百分比,相当于父对象宽度的百分比)

      示例写法:.apple{text-indent:20px;}或.apple{text-indent:30%;}

      4.行高属性(line-height),用来设定每行之间的距离。其值单位主要有:normal (缺省值)、length、percentage,类似于文本缩进属性。

      示例写法:.apple{line-height:20px;}

      5.字间距属性(letter-spacing),用来设定字符之间的距离。其值单位主要有:normal (缺省值)、length、percentage,类似于文本缩进属性。

      示例写法:.apple{letter-spacing:100px;}

      text与border、font有不相同之外,后者都有综合的写法,而文本属性经常是单个使用,综合写法,也只需要把所有参数放在同一个{}即可实现效果,也可在文本属性中增加color颜色属性。以下是我自个儿练习的例子,仅供参考!下一课时准备学习背景属性(background),这个属性也是非常重要的,尤其对于总体页面布局很实用,非学不可,共同期待新一课时,学习笔记的分享!

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    .apple {text-align:right;text-decoration:underline;text-indent:20px;line-height:3mm;letter-spacing:2mm;color:red;}
    </style>
    </head>
    <body>
    <div>依葫芦画瓢学CSS+DIV(11):强化text属性</div>
    <div class=”apple”>最近又因工作太忙,学习计划一拖再拖,今儿抽个空,把学习笔记整理出来分享,与更多在学习CSS+DIV朋友达成共识,相互交流。</div>
    </body>
    </html>

    12.CSS+DIV之强化background属性

    星期四, 06月 21st, 2007

      在徐果萍博客上节的依葫芦画瓢学CSS+DIV中主要强化了关于text属性的内容,文本对齐属性(text-align),文本修饰属性(text-decoration),文本缩进属性(text-indent),行高属性(line-height),字间距属性(letter-spacing),相似度很高,而且比较简单,应该比较容易上手。今天主要学习背景属性(background)相关参数以及各自单独写法以及综合写法。学习笔记整理内容摘录如下,方便自己今后复习或查询之用。

      1.背景颜色属性(background-color),设定背景颜色=html中bgcolor属性。我来写一个红色背景的body,(也可以定义某个特定区域)

      示例写法:body {background-color:red;}

      2.背景图片属性(background-image),设定背景图片=html中background属性,为body设置一个背景图片。

      示例写法:body {background-image:url(../images/图片路径)”}

      3.背景重复属性(background-repeat),它和背景图片属性连用,决定背景图片是否重复。在默认不设置状态下,图片向横向、坚向重复。其相关参数主要有:repeat-x 背景图片横向重复,repeat-y背景图片竖向重复,no-repeat背景图片不重复。

      示例写法:body {background-image:url(../images/图片路径);background-repeat:repeat-y;}

      4.背景附着属性(background-attachment),类似于背景重复属性,和背景图片属性连用,决定图片是否跟随内容滚动。其参数值主要有:scroll(滚动),fixed(固定),默认为scroll。

      示例写法:body {background-image:url(../images/图片路径); background-repeat:no-repeat; background-attachment:fixed;}

      5.背景位置属性(background-position),类似于背景重复属性,和背景图片属性连用,
    决定背景图片的最初位置。下面写入一个背景图片的初始位置距离网页最左面5px,距离网页最上面10px。

      示例写法:body {background-image:url(../images/图片路径);background-repeat:no-repeat; background-position:5px 10px;}

      6.背景属性(background),背景相关属性的综合写法,包括上述写的五个属性。这个简洁的写法可以省略background-color, background-image, background-repeat,backgroundattachment, background-position。

      示例写法:body {background:#000 url(../images/图片路径) no-repeat fixed 5px 10px;}

      最后写了一个背景属性的综合写法,点击运行代码,即可预览效果。下一课时我将学习列表属性list-style,还是会以学习笔记的形式整理出来,与更多的CSS+DIV学习者相互交流!

    <html>
    <head>
    <title>徐果萍博客</title>
    <style type=”text/css”>
    body {background:blue url(/attachments/month_0705/8200758214325.gif) repeat-x scroll 5px 5px;}
    </style>
    </head>
    <body>
    <p>今天主要学习背景属性(background)相关参数以及各自单独写法以及综合写法。学习笔记整理内容摘录如下,方便自己今后复习或查询之用。</p>
    </body>
    </html>

     

    apche mod_auth

    认证(Authentication)是指任何识别用户身份的过程。授权(Authorization)是允许特定用户访问特定区域或信息的过程。

    相关模块和指令

    认证和授权涉及到三组模块。通常,你需要从每一组中选择至少一个模块。

    mod_authnz_ldap模块既包含认证功能也包含授权功能。mod_authn_alias模块自身并不实现认证功能,但是允许其它认证支持模块以更灵活的方式进行配置。

    mod_authz_host模块提供基于主机名、IP地址、请求特征的访问控制,但并不属于认证支持系统。

    简介

    如果网站上有些敏感信息或只希望为一个小群体所访问,本文阐述的方法能确保用户只能访问被允许的资源。

    本文涵盖了保护站点资源的"标准"方法,大多数管理员将要用到这些方法。

    决条件

    本文中讨论的指令应该被放进主配置文件(通常在<Directory>段中)或者针对单个目录的配置文件(.htaccess文件)中。

    如果你打算使用.htaccess文件,则必须设置服务器以允许在这些文件中使用认证指令,即用AllowOverride指令指定哪些指令在针对单个目录的配置文件中有效。

    既然本文讨论认证,就应该对AllowOverride这样设置:

    AllowOverride AuthConfig

    如果你希望把这些指令直接写入主配置文件,当然就需要具有对主配置文件的写权限。

    而且,你需要对服务器的目录结构有所了解,以确定某些文件的位置。这个并不难,需要时我们会做适当的说明。

    启用认证

    先介绍用密码来保护服务器上的目录。

    首先需要建立一个密码文件。这个文件应该放在不能被网络访问的位置,以避免被下载。例如,如果/usr/local/apache/htdocs以外的空间不能被网络访问,那么可以考虑把密码文件放在/usr/local/apache/passwd目录中。

    Apache在其安装目录的bin子目录中提供了htpasswd工具,用于建立密码文件,可以这样使用:

    htpasswd -c /usr/local/apache/passwd/passwords rbowen

    htpasswd会要你输入密码,并要求重新输入以进行确认:

    # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    New password: mypassword
    Re-type new password: mypassword
    Adding password for user rbowen

    如果htpasswd不在搜索路径中,则必须使用完整路径,如:/usr/local/apache/bin/htpasswd

    然后修改httpd.conf.htaccess文件,指示服务器允许哪些用户访问并向用户索取密码。若要保护/usr/local/apache/htdocs/secret目录,则可以将下列指令写入/usr/local/apache/htdocs/secret/.htaccess或者httpd.conf的<Directory /usr/local/apache/apache/htdocs/secret>段。

    AuthType Basic
    AuthName "Restricted Files"
    AuthUserFile /usr/local/apache/passwd/passwords
    Require user rbowen

    让我们逐个解释这些指令。AuthType指令选择对用户实施认证的方法,最常用的是由mod_auth_basic提供的Basic 。必须认识到的很重要的一点是,Basic认证方法并不加密来自用户浏览器的密码,因此,不应该用于高度敏感的数据。Apache中还有另一种更安全的认证方法"AuthType Digest",即由mod_auth_digest供的摘要认证。目前,只有最新的浏览器版本才支持摘要认证。

    AuthName指令设置了使用认证的域(Realm),它起两个作用,首先,此域会出现在显示给用户的密码提问对话框中,其次,也帮助客户端程序确定应该发送哪个密码。

    所以,如果一个用户已经在"Restricted Files"域通过了认证,则客户端就可以尝试使用同样的密码来访问同一个服务器上任何名为"Restricted Files"域的其他部分,从而使多个受限区域使用同一个密码,以避免用户重复输入。当然,出于安全考虑,如果服务器变了,客户端始终会要求重新输入密码。

    AuthUserFile指令设置了密码文件的位置,也就是刚才我们用htpasswd建立的文件。如果用户很多则认证速度会很慢,因为对每个请求都必须搜索这个纯文本文件,对此,Apache还支持把用户信息存入快速的数据库文件,mod_authn_dbm模块提供了AuthDBMUserFile指令,并可以用dbmmanage程序建立和操作这些数据库。Apache模块数据库中还提供了许多其他第三方模块提供的认证选项。

    最后,Require指令设置了允许访问受保护区域的用户,下一节将对Require指令作详细说明。

    允许多人访问

    上述指令只允许一个人(一个叫rbowen的用户)访问这个目录,但是多数情况下,都需要允许多人访问,所以就要用到AuthGroupFile指令。

    如果想允许多人访问,那么就必须建立一个组文件以确定组中的用户。其格式很简单,可以用你喜欢的编辑器建立,例如:

    GroupName: rbowen dpitts sungo rshersey

    它只是每组一行的一个用空格分隔的组成员列表。

    向已有的密码文件中增加一个用户,可以输入:

    htpasswd /usr/local/apache/passwd/passwords dpitts

    程序的提示和上面的一样,但是它会追加到已有的文件中,而不是建一个新文件(参数 -c 可以强制建立新的密码文件)。

    现在,需要将.htaccess文件修改成这样:

    AuthType Basic
    AuthName "By Invitation Only"
    AuthUserFile /usr/local/apache/passwd/passwords
    AuthGroupFile /usr/local/apache/passwd/groups
    Require group GroupName

    现在,GroupName组中的成员都在password文件中有一个相应的记录,从而允许他们输入正确的密码进行访问。

    除了建立组文件,还有另一种途径允许多人访问,就是使用如下指令:

    Require valid-user

    使用上述指令,而不是 Require user rbowen ,可以允许密码文件中的所有用户使用正确的密码进行访问。通过为每个组建立一个密码文件,这里甚至允许列举各个组,其优点是Apache只需要检查一个文件(而不是两个),其缺点是,必须维护众多密码文件,而且要确保AuthUserFile指定了一个正确的密码文件。

    可能存在的问题

    由于采用了Basic认证的方法,每次向服务器请求甚至刷新一个受保护的页面或图片时都必须校验用户名和密码,为此,必须打开密码文件并逐行搜索用户名,因此,服务器响应速度会受一些影响,受影响的程度与密码文件的大小成正比。

    所以,对密码文件中的用户总数存在一个实际上的上限,此上限取决于特定的服务器机器的性能,但是一般有几百个用户就会对响应速度有非常明显的影响,在这种情况下,可以考虑用其他认证方法。

    其他认证方法

    基于用户名和密码的认证只是方法之一,时常会有不需要知道来访者是谁,只需要知道来自哪里的情况。

    AllowDeny指令可以允许或拒绝来自特定主机名或主机地址的访问,同时,Order指令告诉Apache处理这两个指令的顺序,以改变过滤器。

    这些指令的用法:

    Allow from address

    address可以是一个IP地址(或者IP地址的一部分),也可以是一个完整的域名(或者域名的一部分),还可以同时指定多个IP地址和域名。

    比如,要拒绝不受欢迎的兜售垃圾的站点:

    Deny from 205.252.46.165

    这样,这个指令所管辖的区域将拒绝所有来自该地址的访问。除了指定IP地址,也可以指定域名,如:

    Deny from host.example.com

    另外,还可以指定地址或域名的一部分来阻止一个群体:

    Deny from 192.101.205
    Deny from cyberthugs.com moreidiots.com
    Deny from ke

    Order可以组合DenyAllow指令,以保证在允许一个群体访问的同时,对其中的一些又加以限制:

    Order deny,allow
    Deny from all
    Allow from dev.example.com

    只列出Allow指令不会得到你想要的结果,因为它在允许指定对象访问的同时并不禁止其他未列出的对象的访问。所以上例使用的方法是:首先拒绝任何人,然后允许来自特定主机的访问。

    更多信息

    mod_auth_basicmod_authz_host文档中有更多的有关资料。mod_authn_alias同样有助于简化认证配置。

    5/18/2008

    基本ok

    1、F+squid+amp
    2、manbo+mediawk+dz

    11/8/2006

    STL

    一、STL简介
    STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称
    。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发
    出来的。现在虽说它主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的
    一段时间。
    STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(
    迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数
    和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个
    头文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<m
    ap>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。以下笔者就简单
    介绍一下STL各个部分的主要特点。
    二、算法
    大家都能取得的一个共识是函数库对数据类型的选择对其可重用性起着至关重要的作用
    。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯
    定比使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择
    ,直到真正想使用模板或者说对模板进行特化的时候,STL就利用了这一点提供了相当多
    的有用算法。它是在一个有效的框架中完成这些算法的——你可以将所有的类型划分为
    少数的几类,然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。

    STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个
    元素调用指定的函数,stable_sort以你所指定的规则对序列进行稳定性排序等等。这样
    一来,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算
    法模板,就可以完成所需要的功能并大大地提升效率。
    算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。<algorithm>是所
    有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认
    为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找
    、遍历操作、复制、修改、移除、反转、排序、合并等等。<numeric>体积很小,只包括
    几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
    <functional>中则定义了一些模板类,用以声明函数对象。
    三、容器
    在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性
    ,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。
    经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写
    的代码,这些代码都十分相似,只是为了适应不同数据的变化而在细节上有所出入。ST
    L容器就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型
    下的数据结构,通过设置一些模版类,STL容器对最常用的数据结构提供了支持,这些模
    板的参数允许我们指定容器中元素的数据类型,可以将我们许多重复而乏味的工作简化

    容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成
    。对于常用的一些容器和容器适配器(可以看作由其它容器实现的容器),可以通过下
    表总结一下它们和相应头文件的对应关系。
    数据结构           描述                                实现头文件
    向量(vector)     连续存储的元素                         <vector>

    列表(list) 由节点组成的双向链表,每个结点包含着一个元素 <list>

    双队列(deque) 连续存储的指向不同元素的指针所组成的数组  <deque>

    集合(set) 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于
    元素对的谓词排列,没有两个不同的元素能够拥有相同的次序   <set>

    多重集合(multiset) 允许存在两个次序相等的元素的集合      <set>

    栈(stack)       后进先出的值的排列                      <stack>

    队列(queue)   先进先出的执的排列                        <queue>

    优先队列(priority_queue) 元素的次序是由作用于所存储的值对上的某种谓词决定的的
    一种队列                                                <queue>

    映射(map) 由{键,值}对组成的集合,以某种作用于键对上的谓词排列  <map>
    多重映射(multimap)    允许键对有相等的次序的映射        <map>
    四、迭代器
    下面要说的迭代器从作用上来说是最基本的部分,可是理解起来比前两者都要费力一些
    (至少笔者是这样)。软件设计有一个基本原则,所有的问题都可以通过引进一个间接
    层来简化,这种简化在STL中就是用迭代器来完成的。概括来说,迭代器在STL中用来将
    算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器
    存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器
    中的元素。
    迭代器部分主要由头文件<utility>,<iterator>和<memory>组成。<utility>是一个很小
    的头文件,它包括了贯穿使用在STL中的几个模板的声明,<iterator>中提供了迭代器使
    用的许多方法,而对于<memory>的描述则十分的困难,它以不同寻常的方式为容器中的
    元素分配存储空间,同时也为某些算法执行期间产生的临时对象提供机制,<memory>中的
    主要部分是模板类allocator,它负责产生所有容器中的默认分配器。
    五、对初学者学习STL的一点建议
    对于之前不太了解STL的读者来说,上面的文字只是十分概括地描述了一下STL的框架,
    对您理解STL的机制乃至使用STL所起到的帮助微乎甚微,这不光是因为深入STL需要对C
    ++的高级应用有比较全面的了解,更因为STL的三个部分算法、容器和迭代器三部分是互
    相牵制或者说是紧密结合的。从概念上讲最基础的部分是迭代器,可是直接学习迭代器
    会遇到许多抽象枯燥和繁琐的细节,然而不真正理解迭代器又是无法直接进入另两部分
    的学习的(至少对剖析源码来说是这样)。可以说,适应STL处理问题的方法是需要花费
    一定的时间的,但是以此为代价,STL取得了一种十分可贵的独立性,它通过迭代器能在
    尽可能少地知道某种数据结构的情况下完成对这一结构的运算,所以下决心钻研STL的朋
    友们千万不要被一时的困难击倒。其实STL运用的模式相对统一,只要适应了它,从一个
    STL工具到另一个工具,都不会有什么大的变化。
    对于STL的使用,也普遍存在着两种观点。第一种认为STL的最大作用在于充当经典的数
    据结构和算法教材,因为它的源代码涉及了许多具体实现方面的问题。第二种则认为ST
    L的初衷乃是为了简化设计,避免重复劳动,提高编程效率,因此应该是“应用至上”的
    ,对于源代码则不必深究。笔者则认为分析源代码和应用并不矛盾,通过分析源代码也
    能提高我们对其应用的理解,当然根据具体的目的也可以有不同的侧重。
    最后要说的是,STL是ANSI/ISO C++标准的一部分,所以对于一个可以有多种C++实现的
    过程,首先考虑的应该是STL提供的模板(高效且可移植性好),其次才是各个厂商各自
    相应的库(高效但可移植性不好)以及自己去编写代码(可移植性好但低效)。
    11/2/2006

    谈谈Unicode编码

    程序员趣味读物:谈谈Unicode编码 出处:CSDN 

     

      这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:

      问题一: 

      使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?

      我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?

      问题二: 

      最近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。

      查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。

    0、big endian和little endian

      big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。

      “endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

      我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。

    1、字符编码、内码,顺带介绍汉字编码

      字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。

      GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。

      GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。

      从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。

      有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。

      这里还有一些细节:

      GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。

      在DBCS中,GB内码的存储格式始终是big endian,即高位在前。

      GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。

    2、Unicode、UCS和UTF

      前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。

      Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。

      根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。

      在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。

      目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是10646-3:2003。

      UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-7、UTF-16。

      IETF的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。

    3、UCS-2、UCS-4、BMP

      UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏:

      UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。

      UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。

      group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。

      将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。

    4、UTF编码

      UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:

    UCS-2编码(16进制)       UTF-8 字节流(二进制) 
    0000 - 007F             0xxxxxxx 
    0080 - 07FF             110xxxxx 10xxxxxx 
    0800 - FFFF             1110xxxx 10xxxxxx 10xxxxxx 


      例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

      读者可以用记事本测试一下我们的编码是否正确。

      UTF-16以16位为单元对UCS进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。

    5、UTF的字节序和BOM

      UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

      Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

      在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

      这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

      UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

      Windows就是使用BOM来标记文本文件的编码方式的。

    6、进一步的参考资料

      本文主要参考的资料是 "Short overview of ISO-IEC 10646 and Unicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。

      我还找了两篇看上去不错的资料,不过因为我开始的疑问都找到了答案,所以就没有看:

    "Understanding Unicode A general introduction to the Unicode Standard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a) 
    "Character set encoding basics Understanding character set encodings and legacy encodings" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03) 

      我写过UTF-8、UCS-2、GBK相互转换的软件包,包括使用Windows API和不使用Windows API的版本。以后有时间的话,我会整理一下放到我的个人主页上(http://fmddlmyy.home4u.china.com)。

      我是想清楚所有问题后才开始写这篇文章的,原以为一会儿就能写好。没想到考虑措辞和查证细节花费了很长时间,竟然从下午1:30写到9:00。希望有读者能从中受益。
    9/28/2006

    ubuntu root 密码的问题

    ubuntu root 密码的问题 2006-01-17 14:27 / 193 原文来自于 八小时外: http://oo8h.com/news_460.html 新接触ubuntu的人(base on debian),大多会因为安装中没有提示root密码而不太清楚为什么会这样。根据ubuntu的中文文档,总结了本文。 关键词: 如何设定/改变/启用 root 使用者的密码? * sudo passwd root 为了启用 root 帐号 (也就是 设置一个口令) 使用: sudo passwd root 当你使用完毕后屏蔽 root 帐号 使用: sudo passwd -l root 这个将锁住 root 帐号. 如何在终端机模式下切换到 root 身份? * sudo -s -H Password: 缺省禁止 root 的好处包括了以下内容. o 起初 Ubuntu 团队希望安装尽可能的简单. 不使用 root , 在安装期间的两个用户交互步骤可以省略. (科林·沃森) o 更进一步, 如果在安装中使用 root, 用户将被要求永远记住他们选择的密码--即使他们很少使用到它. Root 密码经常被对 Unix 安全模型不熟悉的用户忘记. (马特·齐默曼) o 它防止了缺省登录时 "我能做任何事情" --在较大的变化发生之前,你将被提示输入口令,这可以使你考虑你这样做的结果. 如果你作为 root 登录, 你可以删除一些 "没用的文件夹" 并且不会意识到你正处于错误的目录,那时已经太晚了. 它是在 Unix 下长时间使用 "su-command-^D" 练习的情况下,代替一直呆在 root shell--除非你做严重的系统维护 (那时你仍然可以使用 "sudo su"). (吉姆·奇塔姆 和 安德鲁·索巴拉) o Sudo 增加了运行命令的日志记录 (在 /var/log/auth.log). 如果你陷入困境, 你总是可以返回并看见那些运行的命令. (安德鲁·Zbikowski) 安全 与传统的 superuser 模型相比,这种方法有不同的利弊,两者都不总是显示优良的. o 在鼓励使用 root 权限执行一个单独的命令, sudo 好过打开一个 shell: o 减少使用 root 权限的时间总耗用, 降低了不注意使用 root 执行命令的风险 o 提供了有用的审核痕迹 o 有一个单独的 root 密码 (传统模型) 提供了一层额外的保护,当如果一个管理员的密码被侵害时。 o 无论怎样, 如果管理员 (使用 sudo 或 su 变成 root) 被侵害, 攻击者一般可以通过一次间接的攻击来获得 root Sudo 和Root 帐号— Ubuntu中文 缺省禁止root 的好处包括了以下内容. 起初Ubuntu 团队希望安装尽可能的简单. 不使用root , 在安装期间的两个用户交互步骤可以省略. (科林·沃森). 更进一步, 如果在安装中使用root, 用户将被要求永远记住他们选择的密码--即使他们很少使用到它. ... www.ubuntu.org.cn/support/documentation/doc/sudo root ubuntu 服务器安装过程- 笑容网事 ubuntu 服务器安装过程 2005-12-26 18:33 / 140. 原文来自于八小时外: http://oo8h.com/news_452.html. 这是一个安装过程的流水帐。在ubuntu 的中文官方网站[1]上 有相关的一些资料和指南,但是似乎连贯的还不是很少,至少我第一次接触还是很找不到北,所以 ... www.oo8h.com/news_452.html
    8/14/2006

    Google Earth坐标搜集

    启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

      珠穆朗玛峰(Mount Everest):27.9782502279, 86.9221941736 注:珠穆朗玛峰(Jo-mo glang-ma),简称珠峰,又意译作圣母峰,位于中国和尼泊尔交界的喜马拉雅山脉之上,终年积雪。是世界海拔第一高峰。

      英国上空的二战轰炸机: 52 20 10.87N 0 11 43.34W 注:据说不列颠战役纪念飞行表演(Battle of Britain Memorial Flight)中恰巧被卫星拍到的一架轰炸机。

      世界上最大的烂尾楼:39°02′11.11″N, 125°43′48.39″E 注:平壤“柳京饭店”,冷战产物。始建于1982年,最初预算花费7.5亿美元,这是朝鲜总GDP的2%。“柳京饭店”大楼为三角金字塔式建筑,斜面角度为75度,高330米,占地面积360,000平方米,计划有3,000房间、7个旋转餐厅。如果建成,它将是世界上最高的饭店、第七高的大楼、还是世界上位于纽约和芝加哥以外的首个高于100层的建筑。在施工了5年后,由于电力和资金的短缺而停工。

      美国·犹他州·曲颈状国家公园:37° 8′49.74″N 109°54′46.88″W 注:这是原始的曲颈状国家公园的特写,该公园那1000英尺深的裂痕是由堆积于San Juan

      美国·科罗拉多州·谷物迷宫:40°17′52.88″N 104°45′37.05″W

      秘鲁神秘巨型地表图案:14°41′11.61″S,75°10′23.26″W

      麦田怪圈: 53 31′54.33N,1 21′22.63W

      NOKIA Theatre: 32.76685200/96.98219800

      英国的巨石阵: 51°10′44.32″N,1°49′43.38″W

      秘鲁纳斯卡平原巨画:14°41′45.39″S,75°10′35.48″W

      海滩上的家伙,被拍下来了: 12° 9′2.68″S, 40°33′23.24″E

      Miyake-jima(日本的一个火山岛,还在冒烟):34.0833816528, 139.528656006

    ---------------

    世界著名机场

    ---------------

      这里收集了一些关于世界著名机场的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

      新加坡樟宜国际机场:1.36604863171,104.003205457

      首尔仁川国际机场:37.4458383413,126.453957247

      伦敦希思罗机场:51.4654952963,-0.45468726657

      东京羽田国际机场:35.5518209734,139.78996876

      东京成田国际机场:35.7768962952,140.394931041

      关西国际机场:34.4381461683,135.240790576

      纽约肯尼迪国际机场:40.16896207603,-73.7878607292

      纽约拉瓜迪亚机场:40.7709196329,-73.8725781735

      法兰克福国际机场:50.0541882898,8.56882921999

      巴黎戴高乐国际机场:48.9986924434,2.57061168343

      台北桃园中正国际机场:25.0792104197,121.239554291

      香港国际机场:22.308558075,113.932217673

      芝加哥奥黑尔国际机场:41.9819547845,-87.8999733783

      巴尔的摩-华盛顿国际机场:39.1792298757,-76.6744909797

      纽瓦克国际机场:40.69291688399,-74.1845529215

      旧金山国际机场:37.6141019893,-122.395812287

      拉斯维加斯麦卡伦国际机场:36.0882981415,-115.141345243

      洛杉矶国际机场:33.9388100309,-118.402768344

      亚特兰大赫斯菲尔德国际机场:33.6277350167,-84.4261286659

      阿姆斯特丹史基浦机场:52.290576817,4.76246825749

    ---------------

    台湾军事坐标

    ---------------

      这里收集了一些关于台湾军事的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

    Hsinchu AB(新竹空军基地) 第2(第499)战术战斗机联队 24° 49′ 05″ N 120° 56′ 21″ E
    Hualien AB(花莲空军基地) 第5(第401)战术战斗机联队 24° 01′ 23″ N 121° 37′ 04″ E
    Kangshan AB(冈山空军基地) 空军学院 22° 46′ 54″ N 120° 15′ 43″ E
    Kaohsiung Hsiao-kang Intl(高雄小港国际机场) 民用 22° 34′ 31″ N 120° 21′ 02″ E
    Lan Yu / Orchid Island (兰屿) 机场 22° 01′ 59″ N 121° 32′ 60″ E
    Lungtang(龙塘) 小型民用机场 24° 51′ 18″ N 121° 14′ 15″ E
    Makung Airport(马公机场) 军用/民用 23° 34′ 03″ N 119° 37′ 44″ E
    Matsu Peigan Airport(马祖北竿机场) 机场 26° 13′ 31″ N 120° 00′ 00″ E
    Matsu South(马祖南竿机场) 机场 26° 09′ 02″ N 119° 57′ 13″ E
    Pa Kuei / Bakuai(八仙) 不详 24° 55′ 59″ N 121° 17′ 60″ E
    Penghu / Chimei(澎湖/七美屿) 小型民用机场 23° 31′ 05″ N 119° 35′ 04″ E
    Pingtung North (屏东北空军基地) 第439空军联队 22° 41′ 43″ N 120° 28′ 40″ E
    Pingtung South(屏东南空军基地) 第439空军联队 22° 40′ 20″ N 120° 27′ 42″ E
    Pratas Island(东沙岛)  20° 42′ 15″ N 116° 43′ 14″ E
    Shang Yi / Kinmen (上义/金门) 军用/民用 24° 25′ 40″ N 118° 21′ 31″ E
    Sungshan Taipei(台北松山机场) 军用/民用 25° 04′ 10″ N 121° 33′ 09″ E
    Ta Shan Ting(大山亭) 机场 24° 25′ 04″ N 118° 14′ 27″ E
    Taichung (台中空军基地) 军用 24° 11′ 04″ N 120° 39′ 14″ E
    Tainan (台南空军基地) 第1(第443)战术战斗机联队 22° 57′ 01″ N 120° 12′ 20″ E
    Taitung (台东空军基地) 第7(第737)战术战斗 24° 11′ 04″ N 120° 39′ 14″ E
    Taoyuan (桃园空军基地) 桃园司令部 25° 03′ 20″ N 121° 14′ 33″ E
    Tsoying(左营) 军用 22° 42′ 16″ N 120° 16′ 48″ E
    Wang An(望安) 小型民用机场 23° 22′ 04″ N 119° 30′ 07″ E
    Chang Hua(彰化) 不详   24°04′59′’N 120°31′59′’E
    Chia Tung(佳桐) 不详   22°25′00′’N 120°32′60′’E
    Donggung(东港) 不详   22°28′00′’N 120°25′59′’E
    Dongshi(东石) 不详   23°16′00′’N 119°40′00′’E
    Huwei(虎尾) 不详   23°42′37′’N 120°25′41′’E
    Ilan(宜兰) 不详   24°45′00′’N 121°46′00′’E
    ---------------

    青藏铁路篇

    ---------------

      这里收集了一些关于青藏铁路的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

      虽然目前无法到坐火车到西藏去,但是我们可以从Google Earth上游览一下青藏线。不过,由于Google的地图是几年前的,所以看到的青藏铁路还在修建中。

    这是青藏铁路在高原上的一段: 31° 5′55.90″N, 91°39′58.34″E
    这是青藏铁路在高原上的另外一段:30°47′35.19″N, 91°36′38.53″E
    青藏铁路格尔木东站: 36°25′8.48″N, 94°55′23.15″E
    青藏铁路格尔木站: 36°23′0.22″N, 94°54′21.68″E
    青藏铁路一隧道入口: 35°41′7.14″N, 94° 2′56.92″E
    青藏铁路楚玛尔河沿: 35°18′41.27″N, 93°18′46.14″E
    青藏铁路尚未开工的路段: 32°18′52.87″N, 91°43′44.59″E
    青藏铁路一桥梁: 33°43′13.57″N, 92° 5′38.60″E
    青藏铁路上的一列火车: 34°13′46.33″N, 92°26′32.16″E
    青藏铁路及路边待铺的铁轨: 34°15′26.89″N 92°28′23.93″E
    青藏铁路一个小站: 34°54′3.33″N, 92°56′3.09″E
    青藏铁路一个长长的桥: 31°28′27.77″N, 91°59′38.94″E
    青藏铁路那曲附近一小站: 31°33′57.26″N, 91°55′11.96″E
    青藏铁路那曲站: 31°26′45.42″N, 91°59′24.03″E
    青藏铁路穿越雪原: 31°12′54.08″N, 91°41′0.79″E
    青藏铁路尚未建成的拉萨火车站: 29°37′28.44″N, 91° 4′8.92″E

    ---------------

    Google Earth上中国军事标语

    ---------------

      直接在Google中输入坐标值后点Search按钮,即可直接定位。

      卫国戍边: 39°41′44.94″N, 73°55′40.55″E

      祖国在我心中: 39°41′42.55″N, 73°55′34.37″E

      严格要求严格训练: 45° 6′56.73″N, 82°31′32.44″E

      卫国戍边以卡为家: 45°22′3.47″N, 90°34′23.67″E

      苦练精兵: 43°43′45.72″N, 87°40′12.59″E

      仗怎么打 兵怎么练: 43°45′19.85″N, 87°40′6.22″E

      后面这几个是网上最先报料出来的,为原第八航校官兵在戈壁滩上创造的奇迹,这些环绕机场的“语录”地标,可以帮助飞行员保持空域位置,引导教、学员准确进出空域,地标所在区域的中心点,便是柳树泉机场。其中一角还有一条废弃跑道。因为柳树泉机场地处戈壁,附近没有明显的地物特征!飞机都是设备简单的初教机,导航设备简陋,所以就弄了语录地标。 有兴趣的自己去看:

      只争朝夕: 42°39′34.40″N, 94°16′4.27″E

      毛主席万万岁: 42°39′20.78″N, 94°10′0.58″E

      为人民服务: 42°32′29.11″N, 94°19′34.62″E

      排除万难去争取胜利: 42°27′15.00″N, 94° 8′48.36″E

      向斗争中学习: 42°27′36.56″N, 94°14′27.76″E
    ---------------

    体育篇

    ---------------

      这里收集了一些地理和有趣的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

    慕尼黑安联体育场(开幕式): 48.219147789,11.6263784774
    柏林奥林匹克体育场(决赛): 52.5133561136,13.2398110056
    汉诺威AWD竞技场: 52.3599290703,9.73288538378
    汉堡世界杯体育场: 53.5869222364,9.9012440719
    多特蒙德维斯特法伦体育场: 51.4927357971,7.45381528043
    盖尔森基奥夫沙尔克竞技场: 51.5537521117,7.06907863308
    凯泽斯劳滕沃尔特体育场: 49.4337693907,7.77715096552
    纽伦堡法兰克人体育场: 49.4259497861,11.1241851189
    斯图加特戈特利布戴姆勒体育场: 48.7931489667,9.23328332718
    莱比锡中央体育场(改建前): 51.3464198348,12.3509946539
    法兰克福森林体育场(改建前): 50.0696330234,8.64661484093

    ---------------

    文化篇

    ---------------

      这里收集了一些地理和有趣的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

    胡夫金字塔: 29°58′33.22″N, 31°7′49.29″E
    古罗马大竞技场: 41°53′24.32″N,12°29′31.16″E
    英国的巨石阵: 51°10′44.32″N,1°49′43.38″W
    印加遗迹:马丘比丘: 13° 09′48.07″S,72°32′44.69″W
    香格里拉-松赞林寺(经文): 27°52′5.10″N, 99°41′52.20″E
    德国科隆大教堂: 50°56′29.57″N 6°57′30.58″E
    雅典-卫城: 37°58′18.87″N,23°43′32.81″E
    宛如龟甲-小田原城: 35°15′7.56″N,139° 9′12.81″E
    丰臣秀吉-大阪城: 34°41′16.16″N,135°31′29.36″E
    赤道雪-乞力马扎罗: 3° 3′53.24″S,37°20′56.85″E

    ---------------

    军事篇

    ---------------

      这里收集了一些地理和有趣的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

    白宫: 38°53′23.90″N 77°00′32.60″W
    五角大楼: 38°52′15.39″N 77°03′22.02″W
    美国核设施: 37°50′38.81″N116°43′53.01″W
    戴维斯空军基地: 32°9′57.52″N,110°51′17.58″W
    北韩核反应堆: 40° 5′42.20″N,128°20′26.91″E
    怀特曼空军基地: 38°43′40.89″N 93°33′21.58″W
    俄国的核潜艇: 42.8689845164N, 132.517761198E
    俄国SU-27基地: 50°36′8.91″N 137° 4′47.63″E
    北塔山边防站: 45°22′2.53″N, 90°34′24.24″E
    成都飞机公司 新歼: 30°42′17.16″ N 103°57′21.71″ E
    西昌卫星发射基地: 28°14′22.38″ N 102°01′28.95″ E
    清泉岗空军基地1:1模型: 40°23′04.16″N 99° 53′50.63″E
    空三师27: 31°23′37.25″N,118 24′58.22″E
    三亚虎头湾: 18 10′41.10″n 109 34′51.81″e
    空36师 大场: 34 22′19″ n 109 07′10″e
    凤凰山陆航基地及陆军轻武器射击场: 30°43′50.99″N 104°05′26.16E

    ---------------

    风景篇

    ---------------

      这里收集了一些地理和有趣的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

    八达岭: 40°21′15.41″N,116°00′24.21″E
    凯旋门: 48°52′26.79″N,2°17′42.66″E
    凡尔赛宫: 48°48′17.76″N,2° 7′18.24″E
    巴黎圣母院: 48°51′11.39″N,2°20′56.95″E
    卢浮宫: 48°51′39.74″N,2°20′9.26″E
    巴黎埃菲尔铁塔: 48°51′29.54″N,2°17′40.19″E
    自由女神像: 40°41′21.48″N,74° 2′40.38″W
    世贸中心双子星大厦遗址: 40°42′42.19″N 74°00′44.45″W
    帝国大厦: 40°44′54.74″N 73°59′10.88″W
    红场和克里姆林: 55°45′08.86″N 37°37′23.05″E
    三峡 30°50′45″N 111°01′27″E
    泸定铁索桥 29°54′52.39″N 102°13′48.61″E

    ---------------

    奇趣篇

    ---------------

      这里收集了一些地理和有趣的坐标,使用方法很简单,先启动Google Earth,然后选择软件左面的部分“Fly to(飞至)”在下面的框中粘贴坐标,按回车即可“飞”到这个地方。

    比尔盖茨的豪宅: 47°37′37.71″N,122°14′33.26″W
    大标语“仗怎么打,兵怎么练!”: 43°45′19.10″N, 87°40′4.90″E
    老外也搞大标语”Go Wings!”: 42°10′29.19″N, 83°11′41.36″W
    断桥: 25°55′46.42″N,80°7′49.58″W
    马戏团: 45°30′26.40″N 73°32′52.94″W
    大堡礁: Great Barrier Reef 18°21′04.58″S,146°47′58.81″E
    撞机事件: 51°52′17.78″N,0°34′0.13″W
    50米长的KB怪虫: 48°51′28.33N 10°12′18.66E
    一群河马: 28°19′18.43″s 32°24′30.16E
    大三角图案: 37°39′56.22″N116° 1′30.90″W
    乍得超高分辨率骆驼和羚羊: 15°17′54.35″N,19°25′46.65″E
    超高分辨率的非洲东部一处建筑物: 12°11′52.05″S,40°33′47.19″E
    5/30/2006

    Ten Years of Slackware

    Ten Years of Slackware

    [Posted July 16, 2003 by ris]

    [This article was contributed by Ladislav Bodnar]

    From: bf703@cleveland.Freenet.Edu (Patrick J. Volkerding)
    Subject: ANNOUNCE: Slackware Linux 1.00
    Date: 17 Jul 1993 00:16:36 GMT
    The Slackware Linux distribution (v. 1.00) is now available for anonymous FTP. This is a complete installation system designed for systems with a 3.5" boot floppy. It has been tested extensively with a 386/IDE system. The standard kernel included does not support SCSI, but if there's a great demand, I might be persuaded to compile a few custom kernels to put up for FTP.

    Yes, you have been taken exactly 10 years back in history when Slackware Linux 1.0 was rather unceremoniously unveiled to those who had the determination and skill to get it installed on their computers. Since the actual development had started at some point in 1992, it is safe to say that Slackware Linux is the oldest surviving Linux distribution on the market today. It was created by Patrick Volkerding and originally based on one of the first ever Linux distributions called SLS Linux by Soft Landing Systems.

    The Linux veterans among the readers will remember that Slackware 1.0 came on 24 floppy disks, 13 of which were the essential A series, while the remaining 11 floppies contained XFree86 and graphical applications. What exciting features could one find in Slackware 1.0? The Linux kernel was at version 0.99pl11 alpha. It came with math emulation and normal hard drive support, TCP/IP, support for ext2fs, msdos and several other file systems, and it even supported a PS/2 style mouse. It was compiled with libc 4.4.1 and g++ 2.4.5. The graphical part of the distribution was based on XFree86 1.3 and the OpenLook Virtual Window Manager was the default desktop environment.

    New releases followed in rapid succession and six new Slackware versions were announced during the remaining 5 months of that year. A much improved Slackware Linux 2.0 was released in July 1994. It came with a choice between a stable Linux kernel 1.0.9 and a development kernel 1.1.18, and included XFree86 2.1.1. It was about this time that Patrick Volkerding turned the Slackware distribution commercial in cooperation with Morse Telecommunication, who were about to release the product on a bootable CD, together with printed documentation.

    The Linux Journal magazine interviewed Patrick Volkerding in the second issue of the newly launched publication in April 1994. "Why did you call it Slackware?", was one of the questions. "My friend J.R. 'Bob' Dobbs suggested it.", replied Patrick. "Although I've seen people say that it carries negative connotations, I've grown to like the name. It's what I started calling it back when it was really just a hacked version of SLS and I had no intention of putting it up for public retrieval. When I finally did put it up for FTP, I kept the name. I think I named it 'Slackware' because I didn't want people to take it all that seriously at first." Interestingly, a potential merge of Slackware with Debian was under consideration in those days, claimed the 27-year old creator of Slackware Linux.

    Slackware Linux 3.0 (kernel 1.2.13) came out in August 1995 and this was followed by a considerable slowdown in the frequency of new releases. It took the distribution almost four years to reach version 4.0 (kernel 2.2.6) in May 1999 (see this review). This trend was broken 5 months later when another new release was announced, and to the surprise of many, it was called Slackware Linux 7.0 (kernel 2.2.13)! Why the sudden escalation of the version number? The Slackware web site explains: "I think it's clear that some other distributions inflated their version numbers for marketing purposes, and I've had to field (way too many times) the question 'why isn't yours 6.x' or worse 'when will you upgrade to Linux 6.0' which really drives home the effectiveness of this simple trick. Sorry if I haven't been enough of a purist about this. I promise I won't inflate the version number again (unless everyone else does again ;)

    In the following years, the Slackware release cycle settled to about one per year, while the more adventurous users followed the distribution's continuously evolving current branch. But the infamous dotcom bust brought a period of uncertainty to the future of Slackware development. This happened when Slackware's primary distributor Walnut Creek merged with BSDi, which was later acquired by another company called WindRiver. Things started to look bleak when WindRiver announced in April 2001 that it would no longer support the development of Slackware. Patrick Volkerding: "I'm working on setting up a company so we can handle the publishing ourselves. Unfortunately, I'm broke. I can get funding to publish and ship the release to all the subscribers (and anyone else who wants it), but have no money to pay my fellow friends until we make some."

    Luckily for all Slackware fans, things turned out rather nicely as Patrick Volkerding teamed up with Bob Bruce, the founder of Walnut Creek, to form a company handling product sales. And, according to this interview, Slackware is actually a profitable business: Patrick Volkerding: "There were certainly times I looked around at the trade shows at new distributions with larger booths and more employees and wondered if I'd made the right move, but in retrospect I'm glad I kept things small. Most of those companies aren't around anymore. When the investments dried up they couldn't afford to continue operating at a loss. Most of the funding for the Slackware project comes from people who have subscribed to the CD releases, or bought CDs from our Web site. This is what pays the bills and enables us to give away free software to everybody else."

    Things have always been kept simple and quiet at Slackware and this is perhaps the main reason why the distribution's 90% market share, which it enjoyed before 1996, has dwindled substantially, as new distributions with a lot more ambition have come to dominate the server rooms. Despite that, Slackware remains one of the top five Linux distributions in terms of popularity and server deployments. Its mailing lists, which have now been transferred into an online user forum at userlocal.com, have become a large collection of some 170,000 posts over the years, while the sheer number of active Slackware community sites in dozens of languages, perhaps only rivaled by the number of sites devoted to Debian, is a clear indication that Slackware remains a powerful force in the world of Linux distributions.

    Happy birthday, Slackware! Thank you for all the great work during the past decade and we look forward to more "slacking" for many more years to come!

    5/25/2006

    windows 2000/XP/2003下安裝APACHE2.0.53、PHP5.0.3、MYSQL4.1.10a、PHPMYADMIN2

    windows 2000/XP/2003下安裝APACHE2.0.53、PHP5.0.3、MYSQL4.1.10a、PHPMYADMIN2..6.1
    2005年03-31更新记录:
    1.把软件升级至目录最新.
    2.去掉CGI的安装方式.(避免让初学者看着糊涂)
    3.将mysql升级到官方推荐使用的4.1.*系列.5.0系列同样适用!
    4.加入GD2的支持
     
     
    PS:太懒,就根据luck_mlc的版本改制

    --------------------------------------------------------------------------
    先从各官方网站下了APACHE2.0.53、PHP5.03、MYSQL4.1.10a、PHPMYADMIN2.6.1
    apache_2.0.53-win32-x86-no_ssl.msi
    PHP视角本地下载------http://down.phpv.net/soft/392.htm
    官方下载 ------http://www.apache.org

    php-5.0.3-Win32.zip
    PHP视角本地下载------http://down.phpv.net/soft/380.htm
    官方下载---------http://www.php.net

    mysql-noinstall-4.1.10-win32.zip
    PHP视角本地下载------http://down.phpv.net/soft/393.htm 
    官方下载---------http://www.mysql.org

    phpMyAdmin-2.6.1.zip
    PHP视角本地下载------http://down.phpv.net/soft/378.htm
    ---------这个也可到天空下载站去下

    由于时效性,你看贴的时候也许会有更高的版本的,不过如果没有特殊说明,安装方法是一样的

    -------------------------------------------------------------------------------------------------------------


    假设:系统盘为 c:/
    假设:把所有的东西安装在D盘下的php目录下
    假设:安装好后目录状态会是这样子:
    apache-------------------------> d:/php/apache
    mysql---------------------------> d:/php/mysql
    php-----------------------------> d:/php/php
    网页文件------------------------> d:/php/www
    以上这些是我的喜好,你可以改成你喜欢的

    第一步 安装mysql4.1.10a( 本文章的配置适用于mysql4.1 和 mysql5.0版本 )

    将下载的的mysql压缩包,直接解压到指定目录(d:\php\mysql)就可以了
    然后双击 D:\php\mysql\bin\winmysqladmin.exe 这个文件,请输入winmysqladmin的初始用户、密码 (注:这不是mysql里的用户、密码)随便填不必在意.确定之后你的右下角任务的启动栏会出现一个红绿灯的图标(绿灯),红灯亮代表服务停止,绿灯亮代表服务正常

    (如果不是绿灯,就左击这个图标->winnt->install the service 安装此服务
    再左击这个图标->winnt->start the service 启动mysql服务)


    修改mysql数据库的root密码
    开始->运行,输入cmd 然后cd 到d:\mysql\bin 执行以下命令

    D:\mysql\bin>mysql
     
    进入mysql后接着执行:

    (将root密码设置为easy)

     
    下面一步是让PHP可以连接到mysql4.1以上版本的,一定不可以省略。具体可参考
    http://www.phpv.net/article.php/288


    密码请根据你需要换成别的


    如果你下载的是进制安装包,解压到任意目录后就直接双击setup.exe 文件,按照你安装软件的习惯装好它,记得到路径选择那一步时请写d:\php\mysql 装好后打开d:\php\mysql\bin\文件夹,双击winmysqladmin.exe文件,会弹出一个窗口,要求设置你的mysql服务的管理员用户名密码.自己定吧


    两种方法区别一看就明了.

    第二步: 安装apache 并配置支持PHP

    双击安装文件apache_2.0.53-win32-x86-no_ssl.msi
    将apache安装在 D:\php\apache 目录下
    还会有输入框,提示输入域名呀管理员信箱,随便填就是了.
    +-----------------------------------------------------
    | 注: 安装完后会自动安装并启动apache的服务,如在此处出现问题:
    |“(OS 10048)通常每个套接字地址 (协议/网络地址/端口) 只允许使用一次:
    | make_sock: could not bind to address 0.0.0.0:80...” 一般是IIS占用了80端口引起的
    | 解决方法: 打开 控制面板->服务 找到 IIS admin 的服务 关闭并禁用
    | 然后用CMD进入命令行模式 进入你安装apache的目录 /apache2/bin
    | 输入
    | apache -k install
    | apache -k start
    | 如果成功的话,再接着做下面的!
    +--------------------------------------------------------------

    将php-5.0.3-Win32.zip 里内容解压到 D:\php\php 里

    找到 php目录里的 php.ini-dist (似乎这是一个习惯,其实我更喜欢用php.ini-recommended)重命名为 php.ini 并拷到 windows系统目录下(特殊情况:win2k系统目录为winnt)
    如我的php.ini是拷到 c:\windows目录
    再将php目录里的 php5ts.dll,libmysql.dll 拷到 系统目录系统目录如我的是c:\windows 里(也可以是c:\windows\system32)
     
    最后到D:\php\php\ext下将php_gd2.dll php_mysql.dll这两个文件复制到system/system32如我的是c:\windows\system里

    配置apache里的httpd.conf

    打开 D:\php\Apache\conf\httpd.conf 这个文件

    找到 AddDefaultCharset ISO-8859-1 将其改为

    AddDefaultCharset GB2312 (让默认语言编码为简体中文)

    找到 DocumentRoot "D:/php/Apache2/htdocs" 将其改为你的WEB目录,如我的为

    DocumentRoot "D:/php/www"

    找到 DirectoryIndex index.html index.html.var 在后面加入 index.htm index.php (默认index.php为首页文件)

    --------------模块化安装PHP----------------------------------------
    找到 #LoadModule ssl_module modules/mod_ssl.so 这行,在此行后加入一行

    LoadModule php5_module d:/php/php/php5apache2.dll

    其中d:/php/php/php5apache2.dll 为你php目录中php5apache2.dll所在的位置

    再找到 AddType application/x-gzip .gz .tgz 这行,在此行后加入一行

    AddType application/x-httpd-php .php

    (其实:上面两行红色的,你可以直接加在httpd.conf文件的最后面也可以的)
    --------------------------------------------------------------------

    此时PHP环境基本已经配置成功
    在WEB根目录(如我的D:\php\www)里建一个名为test.php (提示:用记事本的朋友,请避免文件为test.php.txt) ,的文件内容如下
    PHP代码:
    <? echo phpinfo(); ?>
    重新启动apache服务
    用浏览器打开 http://localhost/test.php
    如果可以看到php配置输出信息就OK了
    (如果看到的是下载页面或者<? echo phpinfo(); ?>,请查查你所做的与上面是否有错漏)


    三、配置php.ini并测试mysql、GD2(php.ini为 c:\windows下的 php.ini)


    找到
    ;extension=php_mysql.dll
    将';'去掉改为.

    extension=php_mysql.dll
     
    找到
    ;extension=php_gd2.dll 去掉前面的; 以便支持GD库.如
     
    extension=php_gd2.dll

    找到
    ;session.save_path = "/tmp"
    将';'去掉.设置你保存session的目录,如

    session.save_path = "C:\WINDOWS\Temp";

     
    重启apache服务
    在Web根目录下(如 D:\php\www)建立testdb.php文件内容如下:
    PHP代码:
    <?php
    $link
    =mysql_connect('localhost','root','123456');
    //这里的root和123456是MYSQL的用户和密码,请根据你自己的情况改好
    if(!$link) echo "fail"
    ;
    else echo
    "success"
    ;
    mysql_close
    ();
    ?>
    用浏览器打开http://localhost/testdb.php 如果输出success就OK了

    四、phpmyadmin的安装配置

    将phpMyAdmin-2.6.1.zip解压到WEB根目录(d:\php\www\中去),重命名文件夹为phpmyadmin或其它
    打开phpmyadmin 目录中的 config.inc.php
    找到以下这些(以下我已改好):

    $cfg['PmaAbsoluteUri'] = 'http://localhost/phpmyadmin';  //假设是有域名的服务器,可改成http://域名/phpmyadmin


    $cfg['Servers'][$i]['user'] = 'root';

    $cfg['Servers'][$i]['password'] = 'easy; //分别填上你mysql的用户和密码即可

    $cfg['Servers'][$i]['auth_type'] = 'http'; // 这里也可以改为cookie



    改好了保存,在浏览器打开http://localhost/phpmyadmin 输入你的用户名和密码,便可以管理mysql了


    差不多了,如果你想让你的PHP代码执行得更快,就再装个Zend Optimizer.

    方法是:下载后双击,选择路径安装.问PHP.INI路径就填 c:/windows

    装好重启apache服务.再看http://localhost/test.php 时应该看到会多一些东西
    with Zend Extension Manager v1.0.3, Copyright (c) 2003-2004, by Zend Technologies
    with Zend Optimizer v2.5.7, Copyright (c) 1998-2004, by Zend Technologies

    ----------------------------------------------------------------------------------------------------
    2005年3月31日晚23:00更新!
    转载请一定有可链接到本页的URL.

     

    apache 2.2.2 + PHP5.1.4 不能运行的解决办法.


    问题,使用传统的模块化方法安装PHP5.1.* + apache 2.2.2 后不能启动,

    提示:
    "Cannot load C:/php/php5apache2.dll into server: The specified module could not be found."

    原因:

     PHP压缩包里的php5apache2.dll只适用于apache2.0.*

    解决方法:

    下载 这个文件 并解压.共有三个文件.

    vcredist_x86.exe
    php5apache2.dll
    httpd.exe.manifest

    好,开始

    1.将 php5apache2.dll 覆盖掉你原来PHP目录下的 php5apache2.dll 文件.

    2.将 httpd.exe.manifest 文件复制到你的apache安装目录下的bin文件夹下.

    3.双击运行vcredist_x86.exe安装.(如果您的系统里已安装了 .NET framework 2.就可以省掉这一步)

    完成!去重启你的apache2.2试试吧.

    5/13/2006

    与Java相关的四十个名字

    1990-1994:Java缘起
    文/孟岩
    Larry Wall说,优秀程序员应有的三个特点:懒惰、急躁和傲慢。Java就是诞生在一群懒惰、急躁而傲慢的程序天才之中。
    1990年12月,Sun的工程师Patrick Naughton被当时糟糕的Sun C++工具折磨的快疯了。他大声抱怨,并威胁要离开Sun转投当时在Steve Jobs领导之下的NeXT公司。领导层为了留住他,给他一个机会,启动了一个叫做Stealth(秘密行动)的项目。随着James Gosling等人的加入,这个项目更名为Green。其目标是使用C++为嵌入式设备开发一种新的基础平台技术,James Gosling本人负责开发一个SGML编辑器。正如人们事后分析的那样,这位天才的程序员太懒惰,所以没有把C++学好,开发中碰了一头包;太急躁——所以不愿意停下来读读Scott Meyers的新书《Effective C++》;太傲慢——所以轻易地决定开发一中新的编程语言。他把这种语言命名为C++++--,意思是C++“加上一些好东西,减去一些坏东西”。显然这个糟糕的名字不可能长命百岁,很快这种颇受同伴喜爱的小语言被命名为Oak。
    到了1992年9月,Oak语言连同Green OS和一些应用程序一起发布在称做Start 7的小设备上,从而使之有了第一次精彩的亮相。随后,Sun开了一家名为FirstPerson的公司,整个团队被转移到这家公司里研发机顶盒,以投标时代华纳公司的一个项目。这帮天才被技术狂热所鼓舞,开发出了一个高交互性的设备,结果没想到时代华纳公司和有线电视服务商并不愿意用户拥有那么大的控制权,从而在竞标之战中败给了SGI。Oak的锋芒之锐,竟然把客户都给吓懵了。Sun沮丧地关闭了FirstPerson,召回了整个团队。事实证明,传统行业中那些脑满肥肠的保守主义者是腐朽没落的。回去!回到激情澎湃的IT产业,抓住互联网的大潮,这才是出路!1994年,Oak被命名为Java,针对互联网的新一轮开发如火如荼,一切已经就绪,熔岩在地下奔流,火山即将喷发。

    1995: Java香浓世界
    文/马伟
    1995年,Sun正式对外公布了Java,并且发布了JDK 1.0。这种外形酷似C++,却包含一颗Smalltalk般纯洁的面向对象之心的全新程序设计语言及其平台,几乎在一夜之间就成为软件产业的新宠儿。Java当时仅仅被用来为网站制作一些动态应用,诸如动画图片之类,但这仍然引起了很多Web开发者们的注意,他们非常渴望有一种安全的语言,可以在静态的HTML网页上制作动画图片。Sun最终把Java集成到NetScape浏览器。同时因为它具有“只写一次,随处运行”的特性,而引起了很多开发者的注意,他们可以再也不用为了使程序能够在不同型号的硬件上运行而耗费大量的时间来编译代码了。
    当时的Web浏览器的出现也为Java的出现起到了很好的推动作用,通过Java和Web浏览器的结合,人们似乎看到了什么,有人甚至预言PC将在一两年内退出历史的舞台,取而代之的是基于Java的浏览器应用程序,通过网络计算设备来进行应用。Java的出现为当时的软件产业带来了无限的遐想。

    1996:Java大跃进,盟主地位就此定
    文/马伟
    SUN在1996年一开始首先成立了JavaSoft组织,并在1月23日正式发布自己的Java 1.0,作为20世纪业界出现的最重要的技术之一,Java引起了编程世界的革命。直到现在,Java仍然是互联网上最流行的语言。
    在Sun正式发布Java 1.0之后,Java这门新生的语言就拥有了自己的会议——JavaOne,这次会议初试啼音就吸引了600多名参与者。除了拥有这么多的积极参与者来进行Java的开发之外,各大知名公司也纷纷向Sun申请Java的许可。一时间,NetScape、惠普、IBM、Oralce、Sybase甚至当时刚推出Windows 95的微软都是Java的追随者。
    Java的应用就像是世界上的顶级玩家们组成的一个公开联盟,告诉全世界我们大家就是都在用着Java。也正是因为如此,Java也找到了自己的归宿。现在的J2EE已经成为中大型企业级应用的标准,成为承接数据库和Web之间的一个重要桥梁。
    当年Java的机会实在太多了,以至于很难知道到底该做什么。最终Java在应用服务器市场获得了难以取代的地位,也确定了J2EE的发展方向,并且仍将延续下去。

    1997-2001:  微软与Sun的Java官司
    文/孟岩
    Java诞生的1995年,正是微软在软件产业地位达到巅峰的时代,Windows 95发布时的风光场面给人们留下的深刻印象至今难忘。尽管如此,作为最卓越的技术领袖,比尔?盖茨仍然敏锐地注意到Java。当他了解了Java的一些细节之后,给予了这样的评价:“Java是很长时间以来最优秀的程序设计语言。”基于此,微软于1996年3月申请并获得了Java许可证。微软对于Java的这一热情态度在当时大大提高了人们对Java的兴趣和信心,但也有不少人担心微软会依靠自己强大的影响力在标准之外另立标准,从而破坏Java的纯洁性。
    果然,从1997年发布Visual J++的第一个版本开始,微软就开始在Java中掺入自己的私有扩展。这毫无疑问引起Sun的高度重视。1997年10月,Sun向美国加州地方法院起诉微软公司违反两公司就微软使用Java技术所签定的合同,指控微软公司在自己的Java产品中做了“不恰当的修改”,违反了合同中承诺向用户提供Java兼容产品的条款。这一官司旷日持久,直到2001年1月双方达成和解,微软将继续提供采用Sun开发的Java技术的现有产品(包括测试版)。不过,Sun有限制地仅对包括Java 1.1.4的微软产品提供许可。到了2001年7月,微软公布新版的Windows XP将不再支持Sun的JVM,并且推出了.NET平台与Java分庭抗礼。
    现在回过头去看,当时的这一场官司对Java世界产生了深远的影响。如果没有这一场官司,也许很多Java程序员都在使用Visual J++,基于WFC开发Windows客户端程序,同时不得不面对被两个不同的事实标准所分裂的Java世界。

    1998:Java 2平台发布
    文/陶文
    1998年,Java 2平台正式发布。经过了三年时间的发展、热热闹闹的攻关宣传、红红火火的众厂商的热情参与,Sun终于知道Java适合干什么了。对比Java刚发明时的技术定位,与Java的戏剧性触“网”的那段历史,Java 2平台的发布可真算得上是有的放矢了。根据官方的文档,Java 2是Sun意识到“one size doesn’t fit all”之后,把最初的Java技术打包成三个版本的产物,也就是著名的J2ME、J2SE、J2EE。
    之所以说Java自从Java 2平台发布之后,进入了现代。那是因为之前的历史怎么看来都和现在程序员日常开发使用的技术无什么关系,比如Applet,已经很少有人使用了。Java 2之后的历史就不一样了,至少人们在推崇轻量级开发,猛批EJB时还不时会引用J2EE这个词是如何诞生的。而Java 2的三大版本中,除了J2EE得到了长足发展和广泛使用之外,J2ME也在手机市场上取得了遍地开花的结果。相较之下,J2SE难免落寞,只剩SWT这个血统不纯的家伙在Rich Client回归的时代吸引着人们的眼球了。无论今天看来当时的Java 2有多么的不成熟,至少经过市场和时间的检验,Java 2规划出来的三大方向把Java技术指向了光明的方向是勿庸置疑的。

    1998:JCP成立并正式运作,
    Java开源社群开始蓬勃发展
    文/黄海波
    1998年,JCP组织成立,并且开始把握Java的发展方向。JCP组织的开放性,不但使得所有对Java感兴趣的商业公司可以参与Java的发展,更重要的是JCP允许个人、非盈利组织、学校等加入,这就给Java带来了巨大的活力。随之兴起的Java开源运动的最大贡献是实现和鼓励了知识共享,在众多热情的开源程序员们的努力和分享下,很多原先只被商业公司掌握的技术、思想和产品可以被所有需要的开发人员免费或者以较低的价格获得使用权, 并通过开放源代码更容易的获得反馈和改进意见从而进一步演化发展。我们知道,所谓知识不是孤立发展认知,而是人们的经验,认识是思考交流和积累的产物。而开源运动所带来的开放、反馈、交流的风气正是符合人类社会知识形成和发展的规律。
    开源运动起源于西方的发达国家,有其现实背景和文化根源。1990年代可以说是IT产业的一个黄金时代。信息时代的兴起对IT人员,特别是软件人员有着巨大的需求。而软件开发又是一种类似艺术创作的脑力活动,和所有的艺术家、作家们一样,在作品打上自己的印记并流传在世界上是每一个创作人员的梦想。互联网时代下的高收入的舒适生活,早九晚五的编写公司的代码并不能满足很多有激情的软件开发人员的梦想,再加上西方传统的基督教文化中十分推崇的分享和交流,开源的出现和兴起也就水到渠成了。今天,开源运动已经不仅仅是一些个人天才程序员们的游乐园地,而是发展成为一项开源软件产业。

    1998:WebLogic打开J2EE的魔匣
    文/霍泰稳
    Java语言的出现使得互联网络有了良好的交互性能,但这些很“酷”的技术仅被人们认为是一些小花招,它还无法消除企业级用户对它的怀疑。1998年,BEA公司宣布收购WebLogic公司,并接着推出由Sun公司第一个授权使用J2EE许可证的WebLogic Server应用服务器,这个Java版的AppServer一推出就引起业界极大的兴趣。WebLoigc Server以其对标准的支持、强悍的运算能力和安全的架构设计等特性也很快征服了那些怀疑J2EE应用的人们。推出市场后不到一年,WebLogic Server就成为业内第一Java应用服务器。
    这里我们援引一些当时著名咨询公司的调查数据来说明问题,“在IDC的报告中,BEA在应用服务器和交易服务器领域市场份额第一;在Gartner的报告中,BEA WebLogic Server拥有业内最广泛的EJB应用安装基础;在Giga Group的报告中,BEA WebLogic Server市场份额占32%”。
    因为应用服务器市场极大的发展潜力,在WebLogic Server之后,其它的很多公司也推出了自己的AppServer,如IBM的WebSphere、Sun公司的iPlanet等,逐渐地应用服务器取代了传统意义上的各类中间件,成为企业应用的基础平台。应用服务器的出现使得Java有了真正意义上的发展。
     
    2002-2004: Sun与微软的法律碰撞最终以喜剧收场
    文/恶魔
    2003年4月2 日,Sun与微软达成16亿美元的法律和解。如果不是晚了一天,许多人会以为这是一个在4月1日愚人节开的玩笑。尽管当时所有人都像是看到“太阳从西边出来了”那样张大了嘴巴,但这的确是事实。
    根据两家公司达成的版权协议,双方会为采用对方的技术而支付专利费用,微软向Sun提前支付3.5亿美元使用费,Sun则承诺,如果Sun集成微软的某些技术,也会向微软付款。
    毫无疑问,“私下了结”的方式对双方而言都是最好的结果。就在协议签署的当天,在美国旧金山由Sun和微软为“抛弃十年恩怨、携手合作“举行的新闻发布会上,尽管比尔?盖茨没有到场,但这并没有防碍现场看起来异常轻松的气氛。麦克尼利和鲍尔默各自穿了一件密歇根州底特律“Red Wings”曲棍球队的运动服,并谈及了一起在哈佛大学读书的经历,麦克尼利还说:“当时我们两人是非常要好的朋友,当然我们也有吵架的时候。”人与人当然可能成为终生的知己,但是公司与公司之间有的只能是利益上的分分合合。

    2000-2004: JBoss和Eclipse
    ——Java开源软件的王者
    文/莫映
    Java和开源几乎就是天生的一对,这可以从无比兴盛繁荣的Java开源软件社区得到佐证。目前最有影响力的Java开源软件项目,要数JBoss和Eclipse。可以说,几乎所有的Java开发人员都获多或少的听到过或接触和使用过它们。前者是目前最优秀、应用最为广泛的企业级开源J2EE应用服务器,后者是功能完全可以替代商业产品的Java IDE。二者的覆盖功能之全、支持工具之广、子项目之多,几乎可以仅凭借它俩来完成企业应用的开发构建到部署实施的全过程,而软件开发者和客户也都可以最大程度上享受高质量,高可靠Java开源软件所带来的低成本优势。
    JBoss和Eclipse的巨大成功,几乎令各自领域的商用竞争者抓狂,其中BEA的WebLogic和IBM的WebSphere在商业利润上受到JBoss的巨大侵蚀,而Borland的JBuilder、JetBrains的IDEA等诸多优秀的商用开发工具也不得不面对Eclipse独大的现实。JBoss的CEO兼创始人 Marc Fleury曾直言不讳地表示,希望占据市场主导地位。“我们希望打败IBM,成为中间件领域里最大的厂商。”JBoss在4.0以前还只是以一个Group存在,盈利手段主要靠服务和销售文档。但在最近,JBoss已经发展成为一个有限公司,并吸纳多家风险投资,专注于获取利润为目标之一的第二代开源软件模式(JBoss自己称为“Professional Open Source”)的创新和运营。这区别于以理论研究为爱好的学院型开源或大公司为基础的非盈利组织开源,如Linux和Apache。当然JBoss的这种运营方式势必会导致更多的代码控制和专有修改权,但按JBoss的说法是这样更能获得企业客户的信赖。JBoss的这种模式是否能获得成功还要我们拭目以待。
    不管JBoss和Eclipse的未来发展如何,JBoss和Eclipse的成功已经让我们看到了Java开源软件的威力,祝愿它们一路走好。

    2004:Java 5.0
    文/莫映
    2004年9月30日,代号为“Tiger”,研发历时近三年的J2SE 5.0发布正式版本,这是Java平台历来发布版本中改动面波及最大的一次。
    纵观Tiger,“Ease of development”是其核心主题,这一点着重体现于语言特性上的改进,这在很大程度上,简化了开发人员日常的编程任务,以往一些琐碎的手工劳动都代之以轻松自然,而又安全可靠的自动化实现。其中的注解功能,以及随之而来的声明式编程,还对构筑于J2SE 5.0之上的J2EE 5.0产生了巨大影响。尽管Tiger在语言特性上做了很大的动作,但作为Java技术的基础支撑,这些改动都是深思熟虑的结果。
    Tiger发布至今也有大半年了,那么Sun又是如何规划J2SE的未来蓝图的呢?据悉,J2SE的下两个版本分别是代号为“Mustang”的J2SE 6.0和代号为“Dolphin”的J2SE 7.0,预计Mustang将于明年发布。在吸取了Tiger研发周期过长的教训之后,Sun副总裁Graham Hamilton表示,Mustang的发布周期将不会那么长。并且,Sun还将“Becoming more open” 作为Mustang的主题之一。未来JCP对Java技术的影响将会愈加深入,而整个研发过程也将会愈加透明。Mustang在正式发布前的内部版本也会陆续见诸于众,如此,广大Java开发者便可以更加及时的了解到Java发展的最新情况。在语言层面上的扩展依然会比较谨慎,比如像AOP这样的当下热门技术,依然不太可能会见诸其中。据Hamilton所言,一个有可能被引入的语法特性被称作“friends”import机制,它将使由多个包组成的大型项目变得易于管理。
     
     
    十大人物
    James Gosling : Java之父
    文/陶文
    作为Java之父,James Gosling的名字可谓是耳熟能详。当人们评论一种编程语言时,总喜欢捎带着把下蛋的母鸡一起带上。Java做为中国的编程语言学习者餐桌上有限的那么几样餐点中的流行款式,自然是让James Gosling风光不已。虽然James Gosling现在已经不是领导Java发展潮流的领军人物了,做为Sun的开发者产品组的CTO,怎么算来也是身居高位了,俗事缠身吧,但是这并不妨碍其对于Java一如既往的爱护,表达着各式各样鲜明的观点,引发一场又一场的争论。
    James Gosling是很爱Java的——是啊,哪有当父母的不爱自己的孩子的呢。James Gosling也是很爱Sun的——是啊,哪有当领导的不爱自己的公司的呢。于是我们在批评.NET的安全性的队伍前头,在褒扬Java性能的队伍前头,在抨击SWT开倒车的队伍前头,在给NetBeans大唱赞歌的队伍前头,我们都看到了James Gosling的身影。无论对错、偏见或者固执,至少说明了Gosling的鲜明个性丝毫没有受到年龄的影响。也许也只有这种天才而偏执的人物才能创造出Java这般伟大的语言来吧。
     
    Bill Joy : 软件业的爱迪生
    文/徐昊
    Joy生于1954年,1982年与Vinod Khosla, Scott McNealy和Andy Bechtolsheim一起创建了Sun Microsystems,并从那时起担任首席科学家,直到2003年离开。他是一位令人崇敬的软件天才,他在软件和硬件的历史上留下了无数令人仰止的传奇。
    在上个世纪80年代早期,DARPA与BBN达成协议,准备将Vinton Cerf和Bob Kahn设计的TCP/IP协议添加到Berkeley UNIX中。Bill Joy被委派来完成这项任务,然而他却拒绝将BBN的TCP/IP协议栈添加到BSD中,因为在他的眼中BBN的TCP/IP实现还远不够好,于是他就写了一个高性能的TCP/IP协议栈。John Gage回忆道,“BBN和DARPA签署了巨额合同来实现TCP/IP协议,然而他们的员工所编写的代码远没有一个研究生所做的好。于是他们邀请Bill Joy参加他们的一个会议,这位研究生穿着一件T-Shirt就出现了,他们询问他,‘你是如何做到的呢?’Bill回答说,‘这是非常简单的一件事,你读一下协议然后就可以编码了’”。除了TCP/IP协议,基于分页的虚拟内存系统最早也是由Bill Joy添加到Berkeley UNIX内核当中的。同时他还是vi、csh、早期Pascal编译器的作者。
    关于Bill Joy惊人的软件才能流传最广的一个传奇是,据说他在上研究生的时候,想看看自己能不能写一个操作系统出来,于是就在三天里写了一个非常简陋,但是可以使用的Unix系统, 传说就是BSD的前身。虽然如此夸张的才情令人难以置信,但是考虑到主角是Bill Joy,还是有一定的可信度的。Bill Joy硕士毕业之后,决定到工业界发展,于是就到了当时只有一间办公室的Sun, 他作为主要设计者参与了SPARC微处理器的设计,负责设计最为关键的一部分电路。这样兼精软硬件的天才实在是让人不得不佩服啊。1995年,Sun发布了轰动世界的Java语言。当然,Bill Joy对Java也作出了不少的贡献,首先是JINI——一种针对分布式服务的基础连接技术。任何可以内嵌JVM的电子设备都可以通过JINI相互连接;JXTA是基于Java的P2P协议,允许互联网上的软件进行点对点交流和协作。
    这个其貌不扬的瘦高个,有着凌乱的亚麻色头发,被《财富》杂志誉为“网络时代的爱迪生”的技术狂人,在短短的二十年间,创造了无数令人心动的软件。在MIT的BBS上曾有一个帖子,说微软电话面试有一道题,问“Who do you think is the best coder, and why?”虽然回复的帖子中大家都声明列举的best coder排名不分先后,然而大多数人仍把Bill Joy列在第一位,或许可以从一个侧面验证Bill Joy在广大Programmer心目中的地位吧。

    Joshua Bloch :  Java 2 元勋
    文/莫映
    早在1996年,适逢Java刚刚崭露头角,年内好事连连。先是1月份发布JDK 1.0,然后是5月底在旧金山召开首届JavaOne大会,年末又是JDK 1.1紧跟其后。正是在Java技术如火如荼、大展拳脚的背景之下,Joshua Bloch来到了Sun,开始了他带领Java社区步入“迦南美地”的漫长历程。
    很快,他被从安全组调入核心平台组,从事底层API设计。至此以后,每逢JDK的重大版本发布,总能在其中见到Joshua的“妙笔”。JDK 1.1中的java.math、1.4中的assertions,还有大家所熟识的Collections Framework皆是Joshua一手打造。其中的Collections Framework还获得了当年的Jolt大奖。到了J2SE 5.0研发阶段,身为平台组构架师的Joshua接掌了Tiger大旗,其核心地位已然无人可以替代。作为Tiger的代言人和领路人,没有谁比Joshua更清楚Tiger。相信大家一定还记得Joshua当年仿效英国诗人William Blake所做的咏Tiger诗八首,优雅的笔调,透出大师深厚底蕴的同时,也道出了Tiger的几大重要特性,这些特性是自JDK 1.1引入Inner Class以来,Java最大的语法改进。
    Java风雨十年,从JDK 1.1到J2SE 5.0,Joshua实在功不可没。难怪有人戏言,假如将James Gosling比作Java之父,那么Joshua就是一手将Java “哺育”成人的Java之母。Joshua对Java的贡献还不止于JDK,提起他的大作《Effective Java》(Addison Wesley, 2001),相信Java粉丝们一定耳熟能详。该书荣膺2002年度Jolt大奖,且备受James Gosling推崇。书中57条颇具实用价值的经验规则,来自Joshua多年来在JDK开发工作中,尤其是Collections Framework设计中的实践心得,各个有理有据,剖析深入,也足见其深厚功力。该书对Java社群的影响,犹如C++社群中的《Effective C++》。Joshua对JCP的贡献也不小。他是JSR201和JSR175的领导者,前者包含了Tiger四大语言特性,后者则为Java提供了元数据支持。此外,他还是JSR166的发起人之一(该JSR由Doug Lea领导),并且是许多其他JSR的参与者。Joshua目前是JCP为数不多的几个执行委员会成员之一。
    Joshua Bloch给人的印象是谦逊平和,行事低调而不喜抛头露面,一个典型的技术人员和实干家。不过即便如此,也丝毫不会减弱他对Java技术的卓越贡献和对Java社区的绝对影响力。有人说,如果他能更彰显一些,就很有可能成为Java开发者中的领军人物,就有如Don Box之于微软社群。
    2004年7月初,就在Tiger发布在即之时,就在Jusha Bloch刚刚荣获Sun“杰出工程师(Distinguished Engineer)”的称号之时,他突然离开Sun而去了正值发展态势迅猛的Google。当他离开Sun的消息在TSS发布之后,众多拥趸表达了怀念与不舍之情。一年过去了,我们还没有获知Joshua的任何近闻,似乎又是他行事低调的一贯作风所致,不知他在Google状况如何。希望Joshua依然能继续“摩西未尽的事业”,以他的影响力推动Java社群继续前行。据称,《Effective Java》的下一版会加入Java 5.0的部分,让我们翘首以待吧。

    Bruce Eckel : 功勋卓著的机会主义分子
    文/孟岩
    Bruce Eckel原本是一位普通的汇编程序员。不知道是什么因缘际会,他转行去写计算机技术图书,却在此大红大紫。他成功的秘诀不外乎两点:超人的表达能力和捕捉机会的能力。他最早的一本书是1990年代初期的《C++ Inside & Out》,随后,在1995年他写出了改变自己命运的《Thinking in C++》。如果说这本书充分表现了他作为优秀技术作家的一面,那么随后他写作《Thinking in Java》并因此步入顶级技术作家行列,则体现了他作为优秀的机会主义分子善于捕捉机会的另一面。写作中擅长举浅显直接的小例子来说明问题,语言生动,娓娓道来,特别适合于缺乏实践经验的初学者。因此《Thinking in Java》俨然成为天字第一号的Java教科书,对Java的普及与发展发挥着不可忽略的作用。不过公允地说,Bruce Eckel的书欠深刻。比如在“Thinking in…”系列中对设计模式的解说就有失大师水准。这一方面是因为书的定位非常清晰,另一方面也是因为Bruce太过分心赶潮流,未能深入之故。TIJ之后,他预言Python将火,就匆匆跑去写了半本《Thinking in Python》。后来Python并未如期而旺,于是他也就把书稿撂在那里不过问了,机会主义的一面暴露无遗。我们也可以善意的猜测一下,他的下一个投机对象会是什么呢?Ruby?.NET?MDA?总之,是什么我都不奇怪。

    Rickard Oberg :J2EE奇才
    文/熊节
    Oberg的作品很多,流行的代码生成工具XDoclet和MVC框架WebWork都出自他的手笔。这两个框架有一个共同的特点,即它们的功能虽然简单,但设计都非常优雅灵活,能够很方便地扩展新功能甚至移植到新环境下使用。优雅的设计源自Oberg的过人才华,简单的功能则折射出他玩世不恭的人生态度。正是这两种特质的融合,才造就了这个不世出的奇才。
    1999年,JDK 1.3发布,其中带来了一个重要的新特性:动态代理(Dynamic Proxy)。当所有人都还在对这项新技术的用途感到迷惑时,Oberg发现用它便可以轻松攻克EJB容器实现中的一些难关。这一发现的产物就是一本《Mastering RMI》,以及大名鼎鼎的JBoss应用服务器。但Oberg很快又让世人见识了他的玩世不恭。由于和总经理Marc Fleury在经营理念上不合,Oberg抱怨“法国的天空总让我感到压抑”,甩手离开了自己一手打造的JBoss。此后的几年里,他和老友Hani Suleiman不断地对JBoss的“专业开源”模式和Marc Fleury的商人味道冷嘲热讽,让众人为他的孩子气扼腕叹息。
    2002年10月,微软推出Petstore示例应用的.NET版本,并宣称其性能比Java Petstore高出数倍。正是Oberg深入分析这个示例应用的源代码,在第一时间指出它大量运用了SQL Server专有的特性,性能对比根本不具参考价值。后来Oberg又先后关注了AOP和IoC容器,两者都成为了J2EE架构的新宠。
     
    Doug Lea : 世界上对Java影响力最大的个人
    文/KIT
    如果IT的历史,是以人为主体串接起来的话,那么肯定少不了Doug Lea。这个鼻梁挂着眼镜,留着德王威廉二世的胡子,脸上永远挂着谦逊腼腆笑容,服务于纽约州立大学Oswego分校计算器科学系的老大爷。
    说他是这个世界上对Java影响力最大的个人,一点也不为过。因为两次Java历史上的大变革,他都间接或直接的扮演了举足轻重的脚色。一次是由JDK 1.1到JDK 1.2,JDK1.2很重要的一项新创举就是Collections,其Collection的概念可以说承袭自Doug Lea于1995年发布的第一个被广泛应用的collections;一次是2004年所推出的Tiger。Tiger广纳了15项JSRs(Java Specification Requests)的语法及标准,其中一项便是JSR-166。JSR-166是来自于Doug编写的util.concurrent包。
    值得一提的是: Doug Lea也是JCP (Java小区项目)中的一员。
    Doug是一个无私的人,他深知分享知识和分享苹果是不一样的,苹果会越分越少,而自己的知识并不会因为给了别人就减少了,知识的分享更能激荡出不一样的火花。《Effective JAVA》这本Java经典之作的作者Joshua Blosh便在书中特别感谢Doug是此书中许多构想的共鸣板,感谢Doug大方分享丰富而又宝贵的知识。这位并发编程的大师级人物的下一步,将会带给Java怎样的冲击,不禁令人屏息以待。

    Scott McNealy :SUN十年来的掌舵者
    文/KIT
    McNealy,Sun的CEO、总裁兼董事长。他曾经狂傲的说:“摧毁微软是我们每个人的任务。”这位英勇的硅谷英雄,似乎带头起义,试图组织一个反微软阵线联盟,以对抗微软这股庞大的托拉斯恶势力。他时常口出惊人之语,在公开场合大肆的批评微软,并曾经说微软的.NET是.NOT。
    Scott McNealy先后毕业于哈佛大学及史丹佛大学,分别持有经济学学士学位及企管硕士。1982年MBA毕业的他和三个同学共同合伙创建了Sun,并于1984年成为Sun的执行官。“要么吞了别人,不然就被别人吞了”是Scott McNealy的名言录之一。他擅长以信念带动员工,鼓舞士气。极富自信的他,对于认定的事,总是坚持自己的想法,因此有人形容他是一个刚愎自用的决策者。
    身为Sun这艘船的掌舵者,Scott McNealy能够看多远,Sun就能走多远。Scott McNealy认为将来软件界是一个只有服务,没有产品的世代。他希望打造出Sun不是一个纯靠硬件赚钱的公司。从Open Source到Open Solaris,Sun希望可以成为提供整合性解决方案的服务厂商。Solaris 10 + UltraSPARC是否可以像Scott McNealy希望的是下一匹世纪黑马呢?Sun是否能以股价来证明华尔街分析师及普罗大众的诽短流长?Scott McNealy是否能带领着Sun成为继微软之后的下一个巨人,一场场IT界的争霸战值得我们拭目以待。

    Rod Johnson : 用一本书改变了Java世界的人
    文/ 刘铁锋
    Rod在悉尼大学不仅获得了计算机学位,同时还获得了音乐学位。更令人吃惊的是在回到软件开发领域之前,他还获得了音乐学的博士学位。有着相当丰富的C/C++技术背景的Rod早在1996年就开始了对Java服务器端技术的研究。他是一个在保险、电子商务和金融行业有着丰富经验的技术顾问,同时也是JSR-154(Servlet 2.4)和JDO 2.0的规范专家、JCP的积极成员。
    真正引起了人们的注意的,是在2002年Rod Johnson根据多年经验撰写的《Expert One-on-One J2EE Design and Development》。其中对正统J2EE架构的臃肿、低效的质疑,引发了人们对正统J2EE的反思。这本书也体现了Rod Johnson对技术的态度,技术的选择应该基于实证或是自身的经验,而不是任何形式的偶像崇拜或者门户之见。正是这本书真正地改变了Java世界。基于这本书的代码,Rod Johnson创建了轻量级的容器Spring。Spring的出现,使得正统J2EE架构一统天下的局面被打破。基于Struts+Hibernate+Spring的J2EE架构也逐渐得到人们的认可,甚至在大型的项目架构中也逐渐开始应用。
    Rod Johnson的新作《Expert One-on-one J2EE Development without JEB》则更让人吃惊,单单“Without EJB”一词就会让大多数J2EE架构师大跌眼镜了。不过Rod Johnson可能仅仅是想通过“Without EJB”一词表明应该放开门户之见。这也是Rod Johnson一贯的作风,。也许正是这种思想,促使得Rod Johnson创建了Spring,真正改变了Java世界。
     
    Alan Kay :Java的精神先锋
    文/徐昊
    Sun的官方Java教材中有一句话,说Java是“C++的语法与Smalltalk语义的结合”。而Smalltalk的创造者就是Alan Kay。
    Alan Kay于1970年加入Xerox公司的Palo Alto研究中心。早在70年代初期,Alan Kay等人开发了世界上第二个面向对象语言Smalltalk,因此,Alan Kay被誉为Smalltalk之父。2003年,Alan Key因为在面向对象程序设计上的杰出贡献,获得了有计算机界的诺贝尔奖之称的ACM Turing Award。
    Alan Kay成名于Smapltalk和OOP,而Java虽然在语言上类似于C,但是在语义上非常接近Smalltalk,很多Java中的设计思想在Alan Kay的文献中找到根源,也有些人将Alan Kay尊为Java思想的先驱。不过遗憾的是似乎Alan Kay老先生对Java并不买账,反倒攻击说Java是存在致命缺陷的编程语言,Java的成功不是由于Java本身的内在价值,而是其商业化的成功。Alan Kay欣赏的是Lisp,他认为Lisp是软件的麦克斯韦方程,其中的许多想法是软件工程和计算机科学的一部分。看来拥有Alan Kay这样一位重量级的Java先驱仍是我们Java一厢情愿的单恋吧。
     
    Kent Beck : 领导的敏捷潮
    文:刘铁锋
    Beck全家似乎都弥漫着技术的味道。生长在硅谷, 有着一个对无线电痴迷的祖父,以及一个电器工程师父亲。从小就引导Kent Beck成为了业余无线电爱好者。
    在俄勒冈州大学读本科期间,Kent Beck就开始研究起模式。然而在他最终拿到计算机学位之前,他却是在计算机和音乐中交替学习。似乎Java大师都能够有这样的能耐,另一Java大牛Rod Johnson同样也拥有音乐学的博士学位。
    Kent Beck一直倡导软件开发的模式定义。早在1993年,他就和Grady Booch(UML之父)发起了一个团队进行这个方面的研究。虽然著有了《Smalltalk Best Practice Patterns》一书,但这可能并不是Kent Beck最大的贡献。他于1996年在DaimlerChrysler启动的关于软件开发的项目,才真正地影响后来的软件开发。这次的杰作就是XP(极限编程)的方法学。
    和软件开发大师Martin Fowler合著的《Planning Extreme Programming》可谓是关于XP的奠基之作。从此,一系列的作品如《Test Driven Development: By Example》,《Extreme Programming Explained: Embrace Change》让更多的人领略到了极限编程的精髓,也逐步导致了极限编程的流行。
    Kent Beck的贡献远不仅如此。对于众多的Java程序员来说,他和Erich Gamma共同打造的JUnit,意义更加重大。也许正式这个简单而又强大的工具,让众多的程序员更加认可和信赖极限编程,从而引起了Java敏捷开发的狂潮吧。

     十大产品
    Sun JDK :Java的基石
    文/莫映
    众所周知,流传于市的JDK不单Sun一家,比如IBM的JDK、BEA的JRocket、GNU的GCJ,以及如Kaffe这样的开源实现,不一而足。但是,根正苗红的Sun官方JDK一直以来都是备受瞩目的主流,它对Java社区的影响也是举足轻重。
    1996年1月,Sun在成立了JavaSoft部门之后,推出了JDK 1.0,这是Sun JDK(Java Development Kit)的首个正式版本;当年12月,JDK1.1出炉。该版除了对前序版本部分特性做了改进以外,重写了AWT,采用了新的事件模型。1998年12月,JDK 1.2正式发布。此时的类库日臻完善,API已从当初的200个类发展到了1600个类。在1.2版本中引入了用100%纯Java代码写就的Swing,同时,Sun将Java更名为Java 2。
    1999年,Java 技术形成了J2SE、J2EE和J2ME三大格局。Sun向世人公布了Java HotSpot性能引擎技术的研究成果。HotSpot旨在进一步改善JVM性能,提高Java ByteCode的产生品质,加快Java应用程序的执行速度。J2SE 1.3发布于2000年;2002年2月间,J2SE 1.4问世,这是有JCP参与以来首个J2SE的发行版本。2004年9月30日,代号为“Tiger”的J2SE 5.0终于出笼了,这次发布被誉为Java平台历来发布中特性变动最大的一次。包括泛型在内的若干重大语法改进、元数据支持,包括多线程、JDBC在内的多项类库改进,都令广大Java程序员激动不已。自此,Sun的官方JDK(J2SE Development Kit)已经步入了一个新的高度。
     
    Eclipse :以架构赢天下
    文/恶魔
    IBM是在2001年以4000万美元种子基金成立Eclipse联盟,并且捐赠了不少程序代码。如今,该组织有91个会员,包含许多全球最大的软件商。根据Evans Data公司的资料,Eclipse是目前最受欢迎的Java开发工具。
    Java厂商若要共同对抗微软,彼此之间就要有共同的开发工具才行。
    在Eclipse平台上,程序员可使用好几种不同的语言。在前端方面,用户可整合多种工具来撰写Plug-in程序或Unit Test。Eclipse最大的特色就在于其完全开放的体系结构,这代表任何人都可下载并修改程序代码,给Eclipse写插件,让它做任何你能想到的事情,即所谓“Design for everything but nothing in particular”。
    Eclipse基金会的架构比较特别,反映出企业现今对于开放原始码计划也越来越积极主动。Eclipse不像一般开放源码软件容许个人的捐献程序,该基金会是由厂商主导。不论是董事会成员或者是程序赞助者几乎都来自于独立软件开发商(ISVs)的员工。
    Eclipse首席执行官Mike Milinkovich说,这种厂商会员制是特意设计的;他说Eclispe软件开发快速就是因为会员制的关系,同时又加上开放源码开发模式的临门一脚。这与一般透过标准组织的做法全然不同。 这其实正好验证了一句老话:“开放即标准”。

    JUnit/Ant : 让Java自动化的绝代双骄
    文/刘铁锋
    在Java程序员必备的工具中,共 同拥有且交口称赞的恐怕就非JUnit、Ant莫属了。一个是单元测试的神兵利器,一个是编译部署的不二之选,它们让Java的开发更简单。
    JUnit由XP和TDD的创始人、软件大师Kent Back以及Eclipse架构师之一、设计模式之父Erich Gamma共同打造。名家的手笔和理念使得JUnit简单而强大,它将Java程序员代入了测试驱动开发的时代。JUnit连任了2001、2002年“Java World编辑选择奖”以及2003年“Java World最佳测试工具”和2003年“Java Pro最佳Java测试工具”等众多奖项,深受Java程序员好评。
    Ant是开源项目的典范,它让IDE的功能更加强大,从Sun的NetBeans到JBuilder,主流的IDE中处处都有它的身影。“Another Neat Tool”原是它的本名,但这已经渐渐不为人知。它彻底地让部署自动化,而程序员需要做的仅仅是几条简单的配置命令。和JUnit一样,Ant也荣获了众多的殊荣:2003年JavaWorld“最有用的Java社区开发的技术编辑选择奖”, 2003年Java Pro“最有价值的Java部署技术读者选择奖”,2003年“JDJ编辑选择奖”,也让Ant受到的多方的认可。
    Ant对JUnit的全面集成,则使得一切都变得更加完美。只需简单地配置,从自动测试到报告生成,从编译到打包部署均可自动完成。强大的功能,简单的配置,让Java程序员高枕无忧。实可谓让Java自动化的绝代双骄。
    Websphere : 活吞市场的大鲸
    文/jini
    1999年, IBM与Novell签订合作协议,成功地提供电子商务的解决方案给予原先使用NetWare的用户。同年更是推出了WebSphere Application Server 3.0,并且推出WebSphere Studio与VisualAge for Java让工程师可以快速开发相关的程序。2001年,IBM更是宣布将应用服务器、开发工具整合在一起,与DB2、 Tivoli及Lotus结合成为一套共通解决方案,如今、IBM更是并入了Rational Rose ( UML tools )让开发流程更是完整化。
    Sun在Web Services的策略方面远远落后于微软与IBM, 当他们手拉手在研订Web Services规范, 加上IBM买硬件送软件或是买WebSphere送DB2的策略让企业大佬们纷纷转向IBM的阵营, Sun才惊觉大势已去。WebSphere复杂的安装,深奥的设定,难以理解的出错讯息不断地挑战开发者的耐心与毅力。
    IBM如今已经不是将WebSphere定义为单一产品,它已经是一个平台的代名词。它里面的产品目前包含了应用服务器、商业整合、电子商务、 数据讯息管理、网络串流、软件开发流程、系统管理、无线语音等等。非常多样化,也让企业界愿意相信WebSphere可以带给他们一套完整的解决方案。同时, IBM也在推广SOA的概念, 简单来说, 利用Web Service的耦合性与工作流程的整合, 为企业内部打造以服务为导向的架构。
    IBM捐献出Eclipse带给Java开发人员对IDE的重新掌握。未来是否会捐献出WebSphere的哪一个部分成为OpenSources, 或许, 又是改写Java世界的时刻了。
     
    WebLogic : 技术人的最爱
    文/jini
    1995年, BEA成立了, 初期以Tuxedo数据转换的产品为基础, 成长之迅速是历年来最强的企业。 1998年, BEA推出以Java为基础的网络解决方案, 提供了完整的中间层架构, 更同时支持EJB 1.0 及微软的COM组件, 方便的管理接口掳掠了工程师的心。 在IBM和Oracle尚未准备好迎击的时候, BEA已经席卷企业应用平台的市场。 WebLogic无论在市场领先度与技术领导性与策略远观性都优于当年的所有应用服务器厂商。
    如今WebLogic不仅仅是应用平台服务器的名称, 而是BEA对于整个企业解决方案的总称, 无论是WebLogic Portal或是WebLogic Integration配合着Workshop开发环境, 来自微软的UI开发团队让Workshop几乎达到所见即所得。 接着, 在下一个版本之中, BEA的BeeHive开放源代码计划将释出中间层控件的开发模块, 并且与Eclipse合作共同打造新一代的开发环境。 如此强而有力的技术支持, 更是让顾客愿意使用WebLogic平台的最大原因。
    代号为“Diablo”的 WebLogic Server 9.0小恶魔已经出现了, 目前虽然仅仅是BETA版, 以Portlet 方式打造的管理接口与完整且美妙的WebServices支持, 实在很难找到可以挑剔的地方, 虽然去年被IBM的技术性推销超越了市场占有率, 不过接下来SOA的平台竞争现在才开始, BEA的LOGO也加入“Think liquid”并且推出新的AquaLogic平台做为数据服务平台, 可见, Java的应用服务器的战争, 还会继续进行着。
     
    JBuilder : Java开发工具的王者
    文/刘铁锋
    Java的开发工具中,最出名的莫过于Borland公司的JBuilder了。对于一些没有弄清楚开发工具与JDK的区别的Java入门者来说,JBuilder就如同Visual C++之于C++,以为JBuilder就是Java的全部。比起捆绑在服务器上销售的JDeveloper,JBuilder应该是唯一的仅靠自身的实力而占领了大部分市场的Java商用开发工具了。而JBuilder作为Java 开发工具的王者,其夺冠之路并非一帆风顺。直到Java的天才Blake Stone成为JBuilder的Architect之后,JBuilder 2.0以及3.0才逐渐推出。2000年3月14日,JBuilder 3.5的推出别具意义,它成为了业界第一个用纯Java打造的开发工具,也风靡了整个Java开发工具市场。在同年11月份推出的JBuilder 4.0乘胜追击,冲破了50%的市场占有率,成为了真正Java开发工具的王者。
    Borland以每半年左右推出一个新版本的速度,让众多的对手倒在了沙场。而Microsoft因为与Sun的官司,也使得一个强大的对手退出了战争。2001年,加入了对企业协作支持的JBuilder 5以及强化了团队开发工具的JBuilder 6打败了最后一个对手Visual Age For Java。2002年JBuilder 7推出之后,再也没有其他厂商与JBuilder竞争。
    孤独的王者并没有停下脚步,在2003年到2005年间,JBuilder也仍然延续了其半年一个版本的速度,推出了8、9、10、2005四个版本。强大的功能以及持续的改进,也让Java程序员多了一分对能够在开发工具市场上与Microsoft血拼十数年的Borland的敬仰。
     
    Oracle : Java人永远的情结
    文/熊节
    在林林总总的数据库之中,有一种尤其令人又爱又恨、印象深刻,那就是关系型数据库市场的“大佬”——Oracle。
    从公司的角度,Oracle和Sun有着诸多相似之处,例如:两家公司都拥有一位个性鲜明的CEO。早在Java诞生之初的1995年,Oracle就紧随NetScape从而第二个获得了Java许可证。从那以后,Oracle对Java的鼎力支持是Java能够在企业应用领域大获成功的重要原因之一。
    所有J2EE程序员都知道,Oracle的JDBC驱动虽然与Oracle数据库配合良好,但在不少地方使用了专有特性。其中最为著名的就是“CLOB/BLOB问题”,诸如此类的问题给开发者带来了很多麻烦。为了同时兼顾不同的数据库,他们不得不经常把自己的一个DAO(数据访问对象)写成两份版本:针对Oracle的版本和针对其他数据库的版本。有不少人为了开发便利,舍弃了数据库之间的可移植性,将自己的产品绑定在Oracle的专有特性上。
    Oracle提供的Java开发工具也与此大同小异。不管是数据库内置的Java支持还是JDeveloper IDE, Oracle的Java工具都和Oracle数据库有着千丝万缕的联系。看起来,只要Oracle还是数据库市场上的“头牌”,了解、学习Oracle的专有特性,周旋于Oracle特有的问题和解决方案之中,就将仍旧是J2EE程序员在数据库基础和SQL之外的必修功课。对Oracle的爱与恨,也将仍旧是Java人心头一个难解的情结。
     
    Struts、Hibernate : 让官方框架相形失色的产品
    文/刘铁锋
    好的框架能够让项目的开发和维护更加便捷和顺利。相比Sun官方标准的迟钝以及固执,开源框架也更得到Java程序员的共鸣。Struts以及Hibernate就是这样一类产品,它们简单、优雅,更让官方的产品相形失色。
    谈起Struts,不可避免地就要提及MVC(Model-View-Controller)的理念。而准确地讲,MVC的提出却最早源于JSP的标准。在1998年10月7号,Sun发布的JSP的0.92的规范中提出的Model 2就是MVC的原型。在1999年12月Java World的大会中,Gavind Seshadri的文章最早阐述了Model 2就是一种MVC的架构,同时也提及了MVC架构是一种最好的开发方法。2000年3月,由Craig McClanahan发布的Struts成为了最早支持MVC的框架。Struts在设计上虽然存在一些诟病,但是不可否认的是,它使得Java Web应用的开发更加简洁和清晰,也让更多的程序员爱上了Java,并开始遗忘官方的JSP。时至今日,比起如WebWork、Tapestry以及Sun官方的JSF,Struts或多或少存在些不足,但是众多成功项目的实施,仍然使其牢牢占据的Java Web应用框架的首位。
    Hibernate则在某种程度上改变了人们对构建J2EE的思路。相比其EJB的Entity Bean的映射技术,Hibernate则显得更加简洁和强大。五分钟就能把Hibernate跑起来,让更多的Java程序员享受到了开发的乐趣。第15届Jolt大奖中,最优秀数据库、框架以及组件的奖项中,Hibernate当仁不让获得头筹;不仅如此, Hibernate甚至还影响了官方的标准。在众多Java程序员翘首以待的EJB 3.0的规范中,Hibernate得到了支持。
    Java开源的繁荣不仅让众多Java的开发者享受到了更多的便利,甚至影响了官方的标准。恐怕这也是作为Java人独有的乐趣之一吧。
     
    PetStore : J2EE人的必修课
    文/陶文
    很少有一个例子项目如PetStore这 般广为人知,而这很大程度上要归功于Sun很“英明”地把PetStore做成一个只展示架构而在性能调优上留下了大大余地的例子。围绕着性能话题,产生了颇为有趣的厂商之间以及平台之间的Pet Wars。除去这些关于性能的流言蜚语乃至中伤,PetStore在展示J2EE1.3平台的架构、演示什么叫分层方面还是有着很大的功劳的。而且PetStore在架构方面的丰富性使得其成为J2EE的那些轻量级小兄弟们展示自身的一个必选科目。
    不谈那些围绕PetStore的口水,那些数不尽的盗版,PetStore给开发新手带来的最重大的影响,我想应该是架构的观念而不是性能,也不是业务。做为一种技术的Demo,这无可非议。但是如果你是一个新手,跟着PetStore亦步亦趋地学习J2EE开发,难免会陷入过度设计、华而不实之类的困境。围绕着.NET的PetStore的克隆PetShop展开的架构与性能的大讨论,是不是也在促使我们学习新技术时应该以解决问题为导向呢?特别是当你想把一个如PetStore这般的Sample Project的技术照搬到你的现实世界的Real Project来时。
     
    十大组织
    Sun : 因为Java而永被荣光
    文/孟岩
    Sun是1980年代初期由斯坦福大学三位年轻学生创立的公司。与一般人的印象不同,“SUN”的本意并不是企图剽窃天上那颗温暖的恒星的威名,而是“斯坦福大学网络”的意思。Sun在“前Java”时代就因为SPARC芯片、Solaris操作系统和“网络就是计算机”的口号而为人所知。1990年12月,Sun启动了一个看上去没什么意思的嵌入式软件项目。然而,基于C++的开发很快遇到了麻烦。一个创新型技术公司的特色立刻显示出来,一群天才不是去深入C++,而是另辟蹊径,发明了Java。这个传奇故事已经尽人皆知,但是其中所包含的精神却始终令人望空凝思。
    Java的发明,使得Sun真正有机会在软件的历史天空中放射出太阳的光芒。Sun发明了Java,并且在长达十年的时间里始终走在Java大潮的最前端。Sun是Java的老家,是Java慈爱的母亲,这一切任何人都改变不了。虽然Sun似乎没能够从Java中获得应有的金钱回报,但这丝毫没有挫伤Sun对于Java的母爱,还有对于Java大潮的舍我其谁的领导气概。
    所有人都迷恋富有的感觉,但是也迟早会意识到钱不是世上最宝贵的东西。这个世界并不缺少会赚钱的公司,但是能够靠着创新型技术推动整个世界进步的公司却是凤毛麟角。Sun应该感到骄傲,他们将因为Java而在历史的天空里发射出太阳的光芒。
     
    IBM : Java经济的最大受益人
    文/恶魔
    Sun公司是Java的发明人,但IBM却是Java最大的受益者。是IBM抢占了利润丰厚的应用服务器市场的头把交椅,是IBM在Java技术上投入最多的金钱,拥有最大的影响力和最好的开发者社区。可以毫不夸张地说,Java使IBM的软件体系得到复兴,在某种意义上,甚至可以说,是Java创造了这种复兴。Java之后又来了Linux,这种建造在不属于自己的平台上以获得成功的理念更是变得非常有影响力。正是这种理念铸就了今天IBM “按需计算,服务为王”的王者风范。
    2004年三月,IBM以Java的解放者的姿态借机向Sun发难。IBM公司负责新兴技术的副总裁史密斯在一封公开信中表示,IBM愿意与Sun合作成立一个项目,意在通过开放源代码开发模式管理Java的开发工作。
    墙内开花,墙外香。面对IBM的成功,到底是谁妒嫉呢?或许去程序的社区中逛逛聊聊,明眼人是不难发现事实真相的。也许Sun应该好好向IBM学习经营之道。尽管利润额不如硬件及服务部门,但IBM软件部门的利润率是最高的——高达85%的利润率足以令人惊叹。在最近的一个季度里,IBM软件部的利润率上升了8%,其中WebSphere产品组的利润率上升了14%。
    正是IBM在开源和Java上的全身心地投入又秉承开放性的原则,今日的Java才能以日进千里的速度将许多竞争对手远远抛在后面。Java 10年,IBM功不可没。
     
    BEA : 用AppServer影响Java阵营
    文/霍泰稳
    十年前诞生的Java并不是一开始 就那么引人注目的,虽然用Applet也曾为互联网络带来一抹亮色,但毕竟只是Toy。在企业级应用市场上,Java一直没有什么起色,虽然Java的支持者一直在鼓吹它有着大型企业级应用的强悍功能。过高的期望与低能的产品,一时间颇让人怀疑Java的路是否已经走到了尽头?可以说是WebLogic Server的出现逐渐打消了人们的顾虑,BEA公司慧眼独具在2001年收购的这个产品将人们的目光吸引到电信、金融、政府等Java企业级应用方面,WebLogic Server以其优良的性能让人们看到Java应用广阔的未来。虽然随后在Java应用服务器方面出现了像IBM公司的WebSpere、开源软件JBoss等Java应用服务器,但WebLogic Server几乎占领世界前500强所有企业的应用服务器市场地位依然无法撼动。
    Java现在已经不单纯是一个语言,从另一方面它也代表着开放与创新。很多以Java产品为基础的公司或者从事Java开发的程序员骨子里都有着开放与创新的烙印,BEA公司的发展深深地印证了这一点。与合作伙伴的密切合作向Java社区贡献产品基础源代码、加入权威开源组织参与Java标准的制定等证实着BEA的开放,而其产品从WebLogic Server一种拓展到WebLogic Platform、WebLogic Portal、WebLogic Workshop等其它领域又证实着它的创新能力。
     
    Oracle : 早起的鸟儿有虫吃
    文/孟岩
    Oracle的老板拉里?艾利森是有名的混世魔王和花花公子,所以尽管他也是软件产业成功人士的代表,却绝不是程序员们心目中的英雄,程序员们毕竟不是央视《对话》节目里群众演员,没必要为了节目需要而对权贵财阀们做出一副贱骨头状。但是,任何人都不能不钦佩Oracle在技术上的前瞻性和坚决性。Oracle是1996年获得Java许可证的,紧接着就大胆地将Java作为战略性的发展方向而予以全面支持。要知道当时Java的前景并不是十分确定的,而Oracle的坚决投入,使得它在后来的Java世界中抢得一席之地。1998年9月发布的Oracle 8i为数据库用户提供了全方位的Java支持。Oracle 8i成为第一个完全整合了本地Java运行时环境的数据库,开发者用Java就可以编写Oracle的存储过程,这意味着可以仅在Oracle数据库中就完成几乎全部的应用开发。J2EE兴起后,Oracle更是有心进入开发工具市场,因而购买了JBuilder的源码,并在此基础上开发出JDeveloper。如今Oracle除了数据库稳居第一之外,在Java开发工具世界里也自成一派。这一切不能不归功于当初的眼光远大。

    Apache : 开源软件的品牌保证
    文/陶文
    Java程序员的日常工具箱中,我们可以发现Ant、Tomcat、Log4、Lucene这些鼎鼎大名的开源产品。而它们的共同点在于,都是由Apache Software Foundation社群中杰出的开发者开发的开源项目。Apache这个名字在Java的世界中实在太出名了,以至于“Apache”这六个字母成为开源项目品质保证的代名词。Apache是自由开源的一面旗帜,其Apache License更是成为商业友好的License的首选,只SourceForge上就有1000多个以Apache License授权的项目,其流行程度可见一斑。
    但是,如我们所知,Apache最早闻名IT界是靠高性能的Web服务器,其历史甚至和Java一样长。Apache对于Java的偏爱,以及其发展的速度也映射出了Java繁荣的一角。现在去它的主页上看看,满目望去全部都是Java的开源项目,早就不光是其C服务器的老本行了。Apache对Java最大的贡献就是提供了这么一个精品的开放舞台,让杰出的开发者和成熟的开源项目走到一起,共同给Java语言提供一个丰富的工具仓库。对于一种语言、一个平台来说,其库的丰富程度对于开发者来说的重要性再怎么强调也不为过。勿庸置疑,Aapache上会出现越来越多的Java开源项目,而我们开发者也将更多地得益于这令人目不暇接的繁荣。
     
    TheServerSide : 论坛的专业精神
    文/刘天北
    成立于2000年5月,TSS最初以一本书而广为人知。它的创始人Ed Roman同时也是J2EE名著《Mastering EJB》的作者;Roman运营着一个J2EE咨询/培训公司TheMiddlewareCompany(简称TMC),TSS当时是TMC的下属部门;为了扩大企业的影响,Roman在TSS网站上免费发布了那本书的电子版。J2EE程序员要吃下这个香饵,就得在论坛中注册;注册的同时,多半也会看一眼论坛的内容;一看之下,大部分人都被吸引住,成了社区的忠实成员。
    TSS究竟有什么吸引人的秘诀?首先,它有一支能力过人的运营团队,除了Roman本人之外,其中还有好几人都是J2EE领域的顶尖专家;第二,TSS和TMC定期会推出专家研讨会/视频访谈、技术白皮书、评测报告,通读TSS提供的这些内容,基本上就可以把握技术的当前趋势。但这还不是全部。最可贵的还是TSS的社区风格:他们深谙技术,但不盛气凌人;思想敏锐,但不因此缺乏审慎和大局感。其中大多数人都已在自己的开发领域颇有建树,在TSS上的活动既给他们提供了与同行进行深度交流的机会。一个新成员进入社区,就像参加了一个起点很高的专业俱乐部,这不是一个求解“怎样设置JAVA_HOME环境变量”之类问题的地方。事实上,在J2EE技术发展的若干转折点上,TSS都起到了关键的推动作用。
    几经易主之后,J2EE咨询培训公司TMC在2004年关闭;TSS则被IT媒体集团TechTarget收购。我们期待着它更加繁荣的未来。
    JBoss : 职业开源软件组织
    文/刘天北
    J2EE的婴儿期,“应用服务器”原本是“昂贵”的代名词。但从1999年起,Marc Fleury和Rickard Oberg等人就已经着手改变这种状况。他们开发的开源EJB容器当时叫做“EJBoss”,在Sun公司的干预下(注意,“EJB”是注册商标),JBoss获得了今天的名字。虽然从问世起就一直受到关注,但JBoss第一个达到产品化标准的版本可能是它的2.2版。它的易用让人一见难忘:除了标准部署描述符,无需编写专用的xml配置文件。Oberg自豪地说,“我们的架构并不是按照EJB规范指定的路线设计的,因此也没有走大多数应用服务器走过的弯路。”
    Jboss 3.x版本保持了一贯的创新精神,在用户中间获得了更广泛的认可。但是,文档要收费下载、在邮件列表上提问常常会遭到Fleury等人的斥责。无疑,JBoss的创始者也意识到了自己的幼稚:开源软件只能靠服务盈利,卖文档赚钱有限、骂用户当然更损害企业形象。
    虽然以Oberg为首的许多程序员退出了开发队伍(其中很多人成了JBoss的死敌),在开源软件领域也面临JOnAS Geronimo等新老对手的竞争,但JBoss还是以不断推出的新版本站稳了脚跟。在技术上,它是策动J2EE演进的重要力量:拟议中的EJB 3也要追随Jboss 4倡导的开发范式,以至于二者的代码样本之间的差别几乎难以分辨;在商业上,JBoss与Sun公司言和修好,甚至还获得了数量可观的风险投资。JBoss已经像拥护者预期的那样,成为了应用服务器领域的Linux。
     
    Borland : 深度介入Java
    文/左轻候

    除了Sun以外,也许没有一家公司 像Borland这样深层地介入Java。Borland开发了最早的Java编译器之一,Borland的工程师参与了早期JDK的设计,Borland的JBCL(JavaBeans Component Library) 技术也成为后来Java Bean规范的基础。但是Borland对Java世界最大的影响还是JBuilder。
    1997年11月,Borland JBuilder 1.0发布。虽然第一个版本相对于竞争对手并没有表现出明显的优势,但是Borland凭借深厚的技术实力和正确的市场策略,不断地超越了对手。JBuilder 3.5成为业界第一个100%基于Java架构的开发工具,并且市场份额很快超过了50%。在随后的版本中,JBuilder持续改进对团队开发、J2EE架构、Mobile技术等方面的支持,最终成为了Java开发工具市场,特别是大型企业级Java开发市场中的霸主。JBuilder的成功,很大一个原因来自于Borland坚持的平台中立性,即对不同厂商的解决方案提供一视同仁的支持。
    2005年初,随着Eclipse社区的迅速崛起,Borland进入了Eclipse的董事会,成为战略开发者(Strategy Developer) ,并宣布将推动Borland的其它产品与Eclipse的集成。在随后发布的一份文件中,Borland宣称JBuilder的未来版本将放弃原有的PrimeTime架构,而基于Eclipse架构。这个代号为“Peloton”的版本预计于2006年下半年发布。
    Borland对Java的另外两个主要贡献来自Together和BES(Borland Enterprise Server)。Together是著名的建模工具,能够与包括JBuilder在内的许多开发工具进行集成,全球市场份额占有率排名第二。BES AppServer是一种J2EE服务器,在全球市场份额占有率上次于WebLogic和WebSphere,排名第三。
     
    JCP : Java世界的联合国
    文/黄海波

    当联合国正在为安理会改革问题 吵得如火如荼时,Java世界的“联合国安理会”已经成功地运作了七个年头。JCP(Java Community Process)在1998年由Sun发起成立,目标是通过一个开放、合作和鼓励参与的非盈利组织来发展和推进Java和相关的技术。正是由于JCP计划的推出可以让所有对Java感兴趣的软硬件厂商,个人和组织都能参与到技术规范的制定和发展过程中,协调各方的兴趣和利益、集思广益,才可以让Java在短短的几年内异军突起,成为可以和微软开发平台抗衡的一个主流开发语言。JCP计划既然是一个组织,自然也有一定的架构。JCP组织架构主要包括PMO(Program Management Office)、JCP成员、EC、EG。事实上,JCP的架构就好像一个Java世界的联合国。虽然也有不少人批评JCP成为各派利益的角力场,因而效率低下;但是,它毕竟为Java的顺利发展很好地掌握了方向。
     
    微软与Java : 不得不说的故事
    文/孟岩

    微软跟Java不对付,地球人都知 道。跟Sun和解了又怎么样?  .NET跟Java就是竞争对手,没什么说的。但是有点IT掌故的人都知道,微软并非一开始就跟Java过不去。当年比尔?盖茨盛赞Java是“长期以来最好的程序设计语言”,而且很早就购买了Java许可证。但是微软作为村里的老大,看着人家的儿子茁壮呈长,不由得生了私心杂念,搞起了小动作,在Visual J++中加入了一些破坏纯洁性的东西。单独来看,Visual J++是COM时代微软最棒的开发工具,用WFC写Windows应用程序和COM组件实在是一种享受。但是放在Java大家庭里,这个家伙就显得多少有点不怀好意。一场官司下来,微软被逐出Java大家庭,Visual J++无疾而终。以后的事情尽人皆知,.NET出笼,利齿直指Java,几年撕咬下来,没占着便宜也没吃大亏,如今也算是南北朝对峙,二分天下有其一。设想如果当时微软能够摒弃帝国主义心态,正确对待Java,与其他人一起共建美好的Java“共产主义社会”,那么今天我们的软件开发世界应该会美好得多。可惜黄粱一梦,终究是蚂蚁的喜事。2004年,微软与Sun实现了和解,但愿到Java 20周年的时候,我们能更正面地描述微软对Java发挥的作用。
     

    LZW压缩算法简介

    LZW压缩算法简介
    作者:宋成
    描述:一篇关于LZW压缩算法简介的文章,通俗易懂,值得一看!
    备注:该文章整理自软件报1998年合订本上册。


        LZW
    压缩算法是一种新颖的压缩方法,由Lemple-Ziv-Welch 三人共同创造,用他们的名字命名。它采用了一种先进的串表压缩不,将每个第一次出现的串放在一个串表中,用一个数字来表示串,压缩文件只存贮数字,则不存贮串,从而使图象文件的压缩效率得到较大的提高。奇妙的是,不管是在压缩还是在解压缩的过程中都能正确的建立这个串表,压缩或解压缩完成后,这个串表又被丢弃。

    1.
    基本原理
        
    首先建立一个字符串表,把每一个第一次出现的字符串放入串表中,并用一个数字来表示,这个数字与此字符串在串表中的位置有关,并将这个数字存入压缩文件中,如果这个字符串再次出现时,即可用表示它的数字来代替,并将这个数字存入文件中。压缩完成后将串表丢弃。如"print" 字符串,如果在压缩时用266表示,只要再次出现,均用266表示,并将"print"字符串存入串表中,在图象解码时遇到数字266,即可从串表中查出266所代表的字符串"print",在解压缩时,串表可以根据压缩数据重新生成。

    2.
    实现方法
      A.
    初始化串表
        
    在压缩图象信息时,首先要建立一个字符串表,用以记录每个第一次出现的字符串。一个字符串表最少由两个字符数组构成,一个称为当前数组,一个称为前缀数组,因为在GIF文件中每个基本字符串的长度通常为2(但它表示的实际字符串长度可达几百甚至上千),一个基本字符串由当前字符和它前面的字符(也称前缀)构成。前缀数组中存入字符串中的首字符,当前数组存放字符串中的尾字符,其存入位置相同,因此只要确定一个下标,就可确定它所存贮的基本字符串,所以在数据压缩时,用下标代替基本字符串。一般串表大小为4096个字节(即2 12次方),这意味着一个串表中最多能存贮4096个基本字符串,在初始化时根据图象中色彩数目多少,将串表中起始位置的字节均赋以数字,通常当前数组中的内容为该元素的序号(即下标),如第一个元素为0,第二个元素为1,第15个元素为14 ,直到下标为色彩数目加2的元素为止。如果色彩数为256,则要初始化到第258个字节,该字节中的数值为257。其中数字256表示清除码,数字257 为图象结束码。后面的字节存放文件中每一个第一次出现的串。同样也要音乐会 前缀数组初始化,其中各元素的值为任意数,但一般均将其各位置1,即将开始位置的各元素初始化为0XFF,初始化的元素数目与当前数组相同,其后的元素则要存入每一个第一次出现的字符串了。如果加大串表的长度可进一步提高压缩效率,但会降低解码速度。

      B.
    压缩方法
        
    了解压缩方法时,先要了解几个名词,一是字符流,二是代码流,三是当前码,四是当前前缀。字符流是源图象文件中未经压缩的图象数据;代码流是压缩后写入GIF 文件的压缩图象数据;当前码是从字符流中刚刚读入的字符;当前前缀是刚读入字符前面的字符。
    GIF
    文件在压缩时,不论图象色彩位数是多少,均要将颜色值按字节的单位放入代码流中,每个字节均表示一种颜色。虽然在源图象文件中用一个字节表示16色、4色、2色时会出现4位或更多位的浪费(因为用一个字节中的4位就可以表示16色),但用LZW 压缩法时可回收字节中的空闲位。在压缩时,先从字符流中读取第一个字符作为当前前缀,再取第二个字符作为当前码,当前前缀与当前码构成第一个基本字符串(如当前前缀为A,当前码为B则此字符串即为AB),查串表,此时肯定不会找到同样字符串,则将此字符串写入串表,当前前缀写入前缀数组,当前码写入当前数组,并将当前前缀送入代码流,当前码放入当前前缀,接着读取下一个字符,该字符即为当前码了,此时又形成了一个新的基本字符串 (若当前码为C,则此基本字符串为BC),查串表,若有此串,则丢弃当前前缀中的值,用该串在串表中的位置代码(即下标)作为当前前缀,再读取下一个字符作为当前码,形成新的基本字符串,直到整幅图象压缩完成。由此可看出,在压缩时,前缀数组中的值就是代码流中的字符,大于色彩数目的代码肯定表示一个字符串,而小于或等于色彩数目的代码即为色彩本身。

      C.
    清除码
        
    事实上压缩一幅图象时,常常要对串表进行多次初始化,往往一幅图象中出现的第一次出现的基本字符串个数会超过4096个,在压缩过程中只要字符串的长度超过了4096,就要将当前前缀和当前码输入代码流,并向代码流中加入一个清除码,初始化串表,继续按上述方法进行压缩。

      D.
    结束码
        
    当所有压缩完成后,就向代码流中输出一个图象结束码,其值为色彩数加1,在256色文件中,结束码为257

      E.
    字节空间回收
        
    GIF文件输出的代码流中的数据,除了以数据包的形式存放之外,所有的代码均按单位存贮,样就有效的节省了存贮空间。这如同4位彩色(16色)的图象,按字节存放时,只能利用其中的4位,另外的4位就浪费了,可按位存贮时,每个字节就可以存放两个颜色代码了。事实上在GIF 文件中,使用了一种可变数的存贮方法,由压缩过程可看出,串表前缀数组中各元素的值颁是有规律的,以256色的GIF文件中,第258-511元素中值的范围是0-510 ,正好可用9位的二进制数表示,第512-1023元素中值的范围是0-1022,正好可用10位的二进制数表示,第1024-2047 元素中值的范围是0-2046,正好用11位的二进制数表示,第2048-4095元素中值的范围是0-4094,正好用12位的二进制数表示。用可变位数存贮代码时,基础位数为图象色彩位数加1,随着代码数的增加,位数也在加大,直到位数超过为12(此时字符串表中的字符串个数正好为2 12次方,即4096个)。 其基本方法是:每向代码流加入一个字符,就要判别此字符所在串在串表中的位置(即下标)是否超过2的当前位数次方,一旦超过,位数加1。如在4位图象中,对于刚开始的代码按5位存贮,第一个字节的低5位放第一个代码,高三位为第二个代码的低3位,第二个字节的低2位放第二个代码的高两位,依次类推。对于8位(256色)的图象,其基础位数就为9,一个代码最小要放在两个字节。

      F.
    压缩范围
        
    以下为256GIF文件编码实例,如果留心您会发现这是一种奇妙的编码方法,同时为什么在压缩完成后不再需要串表,而且还在解码时根据代码流信息能重新创建串表。
    : 1,2,1,1,1,1,2,3,4,1,2,3,4,5,9,…
    : 2,1,1,1,1,2,3,4,1,2,3,4,5,9,…
    当前前缀: 1,2,1,1,260,1,258,3,4,1,258,262,4,5,…
    当前数组: 2,1,1, 1, 3,4,1, 4,5,9,…
    数组下标: 258,259,260,261,262,263,264,265,266,267,…
    : 1,2,1,260,258,3,4,262,4,5,…

        GIF
    文件作为一种重要的图形图象文件格式,尽管其编码规则极复杂,但其压缩效率是极高的,特别是对某些平滑过渡的图象的图形,压缩效果更好。同时由于其在压缩过程中的对图象信息能够完整的保存,在目前流行的电子图片及电子图书中得到了广泛的应用。

    5/12/2006

    LZW(C)

    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    #include <conio.h>
    #include <windows.h>

    //#define _DISPLAY_DBGINFO_
    #define INLINE __inline

    #ifdef _DISPLAY_DBGINFO_
    #define DBG_PRINT(ARGS) printf##ARGS
    #else
    #define DBG_PRINT(ARGS)
    #endif

    typedef unsigned char u8;
    typedef unsigned short u16;
    typedef unsigned long u32;

    extern "C" void WINAPI write_code(void);
    extern "C" u32 WINAPI read_code(void);

    //#define _USE_ASM_VER__WRITE_DATA_TO_BS
    //#define _USE_ASM_VER__MEMCMP

    //#define _USE_ASM_VER__LZW_COMPRESS
    //#define _USE_ASM_VER__LZW_DECOMPRESS


    #define CODE_LENGTH  (11)
    #define MAX_CB_ONECE (1<<CODE_LENGTH) /*  The maxinum bytes to compress at one time */
    #define MAX_ST_ENTRIES MAX_CB_ONECE
    #define MAXIMUM_CODE (MAX_CB_ONECE-1)
    #define MAX_STR_NUM  (0x10000)

    #pragma pack(1)

    typedef struct
    {
     u16 start_pos;
     u16 str_len;
    } string_t;

    typedef struct _st_entry_t
    {
     string_t the_string;
     struct _st_entry_t *next;
    } st_entry_t;

    typedef struct
    {
     string_t the_string;
    } tt_entry_t;

    typedef struct
    {
     string_t the_string;
     long character;
    } translated_string_t;

    typedef struct
    {
     u32 code_num : 31;
     u32 data_compressed : 1;
    } lzw_info_t;

    #pragma pack()

    enum
    {
     RCOK_DATA_COM = 1, // Data are compressed
     RCOK_DATA_UNC = 2,  /*++
      Data are not compressed,
      just copied  directly from source buffer to destination buffer.
          ++*/
     RCFAILED = -1, // Data compression fails due to some reasons.
    };

    /*+++
    // Data area
    ==*/
    static union
    {
     st_entry_t lzw_string_table_entries[MAX_ST_ENTRIES];
     tt_entry_t lzw_translation_table_entries[MAX_ST_ENTRIES];
    };

    static union
    {
     st_entry_t *lzw_string_table[MAX_STR_NUM];
    };

    #ifdef _USE_ASM_VER__MEMCMP
    extern "C" int WINAPI CompareMemory(void *s, void *d, int size);
    #else
    #define CompareMemory memcmp
    #endif

    void set_bit(u8 *bit_stream, const u32 offset_in_bits)
    {
     u32 offset_in_bytes, offset_within_byte;

     offset_in_bytes = offset_in_bits >> 3;
     offset_within_byte = offset_in_bits & 7;

     *(bit_stream+offset_in_bytes) |= (1<<offset_within_byte);
    }

    void clear_bit(u8 *bit_stream,
     const u32 offset_in_bits)
    {
     u32 offset_in_bytes, offset_within_byte;

     offset_in_bytes = offset_in_bits >> 3 ;
     offset_within_byte = offset_in_bits & 7;

     *(bit_stream+offset_in_bytes) &= (~(1<<offset_within_byte));
    }

    int read_bit(u8 *bit_stream, const u32 offset_in_bits)
    {
     u32 offset_in_bytes;
     u32 offset_within_byte;

     offset_in_bytes = offset_in_bits >> 3 ;
     offset_within_byte = offset_in_bits & 7;

     return ( ( *(u32 *) (bit_stream+offset_in_bytes) )
      >> offset_within_byte ) & 1;
    }


    void write_data_to_bs(u32 *data, int bits_of_data,
     u8 *bit_stream, u32 &bit_offset)
    {

    #ifdef _USE_ASM_VER__WRITE_DATA_TO_BS

     __asm
     {
      push esi
       push ebx

       mov esi, data
       mov eax, [esi]
       mov esi, bit_stream
       mov ebx, bit_offset
       mov ebx, [ebx]

       call write_code

       mov esi, bit_offset
       add dword ptr [esi], CODE_LENGTH

       pop ebx
       pop esi
     }
    #else

     int i;
     int n;

     u32 _bit_offset = bit_offset, _bits_of_data = bits_of_data;

     while( bits_of_data > 0 )
     {
      n = bits_of_data > 32 ? 32 : bits_of_data;

      for(i=0; i<n; i++)
      {
       if( ( ( *data ) >> i) & 1 )
       {
        set_bit(bit_stream, bit_offset);
       }
       else
       {
        clear_bit(bit_stream, bit_offset);
       }

       bit_offset++;
      }

      data ++;
      bits_of_data -= n;

      if( bits_of_data )
      {
       assert(0);
      }
     }

     assert( bit_offset - _bit_offset == _bits_of_data);

    #endif

    }

    void write_char_to_bs(const u8 data, u8 *bit_stream,
     u32 &bit_offset)
    {
     u32 data_buff = data;

     write_data_to_bs(&data_buff, 8, bit_stream, bit_offset);
    }

    void write_short_to_bs(const u16 data, u8 *bit_stream,
     u32 &bit_offset)
    {
     u32 data_buff = data;

     write_data_to_bs(&data_buff, 16, bit_stream, bit_offset);
    }


    void read_data_from_bs(void *data, int bits_of_data,
      u8 *bit_stream, u32 &bit_offset)
    {

    #ifdef _USE_ASM_VER__WRITE_DATA_TO_BS

     __asm
     {
      push esi
       push ebx

       mov esi, bit_stream
       mov ebx, bit_offset
       mov ebx, [ebx]

       call read_code

       mov esi, data
       mov [esi], eax

       mov esi, [bit_offset]
       add dword ptr [esi], CODE_LENGTH

       pop ebx
       pop esi
     }

    #else

     int i;
     int n;

     while( bits_of_data > 0 )
     {
      n = bits_of_data > 8 ? 8 : bits_of_data;
      *(u8 *)data = 0;

      for(i=0; i<n; i++)
      {
       if( read_bit(bit_stream, bit_offset) )
       {
        ( *(u8 *)data ) |= (1<<i);
       }

       bit_offset++;
      }

      data = ( (u8 *)data ) + 1;
      bits_of_data -= n;
     }

    #endif

    }

    u8 read_char_from_bs(u8 *bit_stream, u32 &bit_offset)
    {
     u8 data;
     read_data_from_bs(&data, 8, bit_stream, bit_offset);

     return data;
    }

    u16 read_short_from_bs(u8 *bit_stream, u32 &bit_offset)
    {
     u16 data;
     read_data_from_bs( (u8 *) &data, 16, bit_stream, bit_offset);

     return data;
    }


    int search_string_table(u8 *data_buff, int string_num,
     st_entry_t **string_table, string_t *cur_str, st_entry_t **matched_entry=NULL)
    {

     int length = cur_str->str_len + 1;

     u16 index = *(u16 *) (data_buff + cur_str->start_pos);
     st_entry_t *next_entry = string_table[index];

     *matched_entry = NULL;

     while( next_entry )
     {
      if( length == next_entry->the_string.str_len  &&
       CompareMemory(data_buff + next_entry->the_string.start_pos,
        data_buff + cur_str->start_pos, length) == 0 )
      {
       if( matched_entry )
       {
        *matched_entry = next_entry;
       }
       return (int)index;
      }

      next_entry = next_entry->next;
     }

     return -1;
    }

    void addto_string_table(u8 *data_buff,
     int &string_num, st_entry_t **string_table, st_entry_t *st_entries,
     string_t *cur_str)
    {
     u16 index = *(u16 *) (data_buff + cur_str->start_pos);

     st_entries[string_num].the_string = (*cur_str);
     st_entries[string_num].next = NULL;
     st_entry_t *pre_entry = string_table[index];

     if( pre_entry )
     {
      while( pre_entry->next )
      {
       pre_entry = pre_entry->next;
      }

      pre_entry->next = &st_entries[string_num];
     }
     else
     {
      string_table[index] = &st_entries[string_num];
     }

     string_num++;

    }

    void output_code(u16 code, u8 *out_data_buffer,
      u32 &bit_offset)
    {
     write_data_to_bs(
      (u32 *)&code, CODE_LENGTH, out_data_buffer,  bit_offset);
    }

    #ifdef _USE_ASM_VER__LZW_COMPRESS

    extern "C" int WINAPI lzw_compress(st_entry_t **string_table, st_entry_t *st_entries,
     u8 *in_data_buffer, int in_data_len,
     u8 *out_data_buffer, u32 *out_data_len);

    #else

    int lzw_compress(st_entry_t **string_table, st_entry_t *st_entries,
     u8 *in_data_buffer, int in_data_len,
     u8 *out_data_buffer, u32 *out_data_len)
    {
     int ret_val = RCFAILED;

     int string_num;

     string_t cur_string; // string table entry
     st_entry_t *matched_entry;

     int cur_pos;
     u32 bit_offset;

     st_entry_t **tmp_ptr1=NULL, *tmp_ptr2=NULL;

     if( in_data_len > MAX_CB_ONECE )
     {
      goto err_out;
     }

     if( !string_table )
     {
      tmp_ptr1 = new st_entry_t *[MAX_ST_ENTRIES];
      if( !tmp_ptr1 )
      {
       goto err_out;
      }
      string_table = tmp_ptr1;
     }

     if( !st_entries )
     {
      tmp_ptr2 = new st_entry_t[MAX_ST_ENTRIES];
      if( !tmp_ptr2 )
      {
       goto err_out;
      }
      st_entries = tmp_ptr2;
     }

     memset(string_table, 0, sizeof(st_entry_t *) * MAX_STR_NUM);
     memset(st_entries, 0, sizeof(st_entry_t) * MAX_ST_ENTRIES);

     int cnt1, cnt2;
     u32 total_string_length;


     string_num = 0;
     bit_offset = 0;
     cur_string.start_pos = 0;
     cur_string.str_len = 1;
     cur_pos = 1;
     matched_entry = NULL;

     cnt1=0; cnt2=0; total_string_length=0;
     while( 1/*cur_pos < in_data_len*/ )
     {
      st_entry_t *tmp_matched_entry;

      if( cur_pos==2047 )
      {
       cur_pos = cur_pos;
      }

      if( string_num + 256 >= MAXIMUM_CODE ||
       bit_offset >= (u32)in_data_len * CODE_LENGTH )
      {
       memcpy(out_data_buffer, in_data_buffer, in_data_len);
       *out_data_len = in_data_len;
       ret_val = RCOK_DATA_UNC;
       goto cprs_fail;
      }

      if( cur_pos < in_data_len &&
       search_string_table(in_data_buffer, string_num,
        string_table, &cur_string, &tmp_matched_entry) >= 0 )
      {
       cur_string.str_len ++ ;

       matched_entry = tmp_matched_entry;
      }
      else
      {
       u16 code;

       if( matched_entry )
       {
        code = 256 + (u16) (matched_entry - st_entries);

        //matched_entry = NULL;

        cnt1++;
        total_string_length+=cur_string.str_len;

        matched_entry = NULL;
       }
       else
       {
        code = (u16) in_data_buffer[cur_string.start_pos];
        cnt2++;
       }

       DBG_PRINT(("byte offset=%d, ", cur_string.start_pos));
       DBG_PRINT(("code=%d, string length=%d\n", code, cur_string.str_len));

       output_code(code, out_data_buffer, bit_offset);

       cur_string.str_len++;
       addto_string_table(in_data_buffer, string_num, string_table,
        st_entries, &cur_string);

       cur_string.start_pos = cur_pos;
       cur_string.str_len = 1;

       if( cur_pos >= in_data_len )
       {
        break;
       }
      }

      assert(bit_offset == (u32)(cnt1+cnt2)*CODE_LENGTH);
      cur_pos++;
     }

     *out_data_len = bit_offset / CODE_LENGTH;
     ret_val = RCOK_DATA_COM;

    err_out:
    cprs_fail:

     if( tmp_ptr1 )
     {
      delete []tmp_ptr1;
     }

     if( tmp_ptr2 )
     {
      delete []tmp_ptr2;
     }

     return ret_val;
    }

    #endif

    int search_translation_table(tt_entry_t *tt_entries, u16 code)
    {
     if( code<256 || tt_entries[code-256].the_string.str_len>0 )
     {
      return 1;
     }
     else
     {
      return -1;
     }
    }

    void translate_code(tt_entry_t *tt_entries, u16 code,
     translated_string_t &cur_str)
    {
     if( code<256 )
     {
      cur_str.the_string.start_pos = 0;
      cur_str.the_string.str_len = 0;
      cur_str.character = (int)code;
     }
     else
     {
      cur_str.the_string = tt_entries[code-256].the_string;
      cur_str.character = -1;
     }
    }

    void addto_translation_table(tt_entry_t *tt_entries,
     const tt_entry_t &new_string, u32 &string_num)
    {
     tt_entries[string_num] = new_string;
     string_num ++;
    }

    #ifdef _USE_ASM_VER__LZW_DECOMPRESS

    extern "C" int WINAPI lzw_decompress(tt_entry_t *tt_entries,
     u8 *in_data_buffer, u32 code_num,
     u8 *out_data_buffer, u32 *out_data_len);

    #else

    int lzw_decompress(tt_entry_t *tt_entries, u8 *in_data_buffer, u32 code_num,
     u8 *out_data_buffer, u32 *out_data_len)
    {
     enum
     {
      STA_STRING = 8,
      STA_CHAR = 9,
     };

     int ret_val = -1;
     u32 cur_pos, byte_offset, old_byte_offset, bit_offset;
     u16 old_code, new_code, old_state;
     tt_entry_t tmp_string;
     translated_string_t cur_string;
     u32 string_num;
     u8 character;

     u32 tmp_var;

     tt_entry_t *tmp_ptr2=NULL;
     int flag;

     if( !tt_entries )
     {
      tmp_ptr2 = new tt_entry_t[MAX_ST_ENTRIES];
      if( !tmp_ptr2 )
      {
       goto err_out;
      }
      tt_entries = tmp_ptr2;
     }

     memset(tt_entries, 0, sizeof(tt_entry_t) * MAX_ST_ENTRIES);

     bit_offset = 0;
     read_data_from_bs((u8 *)&old_code, CODE_LENGTH, in_data_buffer, bit_offset);
     assert( old_code < 256 );
     DBG_PRINT(("byte offset=0, code=%d, string length=1\n", old_code));
     out_data_buffer[0] = (u8)old_code;
     character = (u8)old_code;

     string_num = 0;

     byte_offset=1, old_state = STA_CHAR, old_byte_offset = 0;
     for(cur_pos=1; cur_pos<code_num; cur_pos++)
     {

      DBG_PRINT(("byte offset=%d, ", byte_offset));
      if( byte_offset==1947 )
      {
       byte_offset = byte_offset;
      }

      read_data_from_bs(&new_code, CODE_LENGTH, in_data_buffer, bit_offset);
      tmp_var = byte_offset;

      if( search_translation_table(tt_entries, new_code) < 0 )
      { // not in translation table
       flag = 0;
       translate_code(tt_entries, old_code, cur_string);

       tmp_string.the_string.start_pos = (u16)byte_offset;
       tmp_string.the_string.str_len = ( -1 == cur_string.character ?
        cur_string.the_string.str_len + 1 : 2 );
       old_state = STA_STRING;
      }
      else
      { // in translation table
       flag = 1;
       tmp_string.the_string.start_pos = (u16)old_byte_offset;

       if( STA_CHAR==old_state )
       {
        tmp_string.the_string.str_len = 2;
       }
       else if( STA_STRING==old_state )
       {
        tmp_string.the_string.str_len =
         tt_entries[old_code-256].the_string.str_len + 1;
       }
       else
       {
        assert(0);
       }

       translate_code(tt_entries, new_code, cur_string);
       old_state = -1 != cur_string.character ? STA_CHAR : STA_STRING;
      }

      if( -1 == cur_string.character )
      {
       memcpy(out_data_buffer + byte_offset,
        out_data_buffer + cur_string.the_string.start_pos,
        cur_string.the_string.str_len);
       byte_offset += cur_string.the_string.str_len;
      }
      else
      {
       out_data_buffer[byte_offset] = (u8)cur_string.character;
       byte_offset++;
      }


      if( 0==flag )
      {
       out_data_buffer[byte_offset] = character;
       byte_offset++;
      }


      character = ( -1 == cur_string.character ?
       out_data_buffer[cur_string.the_string.start_pos] :
       (u8) cur_string.character );

      DBG_PRINT(("code=%d, string length=%d\n", new_code,
       0==flag ? tmp_string.the_string.str_len :
        -1==cur_string.character ? cur_string.the_string.str_len : 1
       ));

      addto_translation_table(tt_entries, tmp_string, string_num);

      old_code = new_code;
      old_byte_offset = tmp_var;
     }

     assert( bit_offset == code_num*CODE_LENGTH );
     *out_data_len = byte_offset;

     ret_val = 0;

    err_out:

     if( tmp_ptr2 )
     {
      delete []tmp_ptr2;
     }

     return ret_val;
    }


    #endif

    void PrintStringTable(st_entry_t **string_table, st_entry_t *st_entries)
    {
     unsigned int i;
     for(i=0; i<65536; i++)
     {
      if( string_table[i] )
      {
       printf("string chain[%d]\n", i);

       st_entry_t *entry = string_table[i];

       while( entry )
       {
        printf("    start pos=%04d, string length=%04d\n",
         entry->the_string.start_pos, entry->the_string.str_len);
        entry = entry->next;
       }
      }
     }
    }

    void PrintTranslationTable(tt_entry_t **translation_table, tt_entry_t *tt_entries)
    {
     unsigned int i;
     for(i=0; i<MAX_ST_ENTRIES; i++)
     {
      if( translation_table[i] )
      {
       printf("code <%d>: ", 256+i);
       printf("    start pos=%04d, string length=%04d\n",
         translation_table[i]->the_string.start_pos,
         translation_table[i]->the_string.str_len);
      }
     }
    }

    int Lzwc(char *src_file, char *dest_file)
    {
     int ret_val = -1;

     u8 data_buff[MAX_CB_ONECE];
     u8 compressed_data_buff[(MAX_CB_ONECE*CODE_LENGTH)/8];

     int xx=0;

     FILE *fp_src=NULL, *fp_dest=NULL;
     u32 total_bytes_to_compress, bytes_to_compress, number_of_codes;
     int rc;

     fp_src = fopen(src_file, "rb");
     if( !fp_src )
     {
      goto err_out;
     }

     fp_dest = fopen(dest_file, "wb");
     if( !fp_dest )
     {
      goto err_out;
     }

     fseek(fp_src,0, SEEK_END);
     total_bytes_to_compress = ftell(fp_src);
     fseek(fp_src, 0, SEEK_SET);

     do
     {
      lzw_info_t lzwinfo;
      u32 total_bytes_compressed;

      bytes_to_compress = total_bytes_to_compress > MAX_CB_ONECE ?
       MAX_CB_ONECE : total_bytes_to_compress;

      fread(data_buff, 1, bytes_to_compress, fp_src);

      rc = lzw_compress(lzw_string_table, lzw_string_table_entries,
        data_buff, bytes_to_compress, compressed_data_buff, &number_of_codes);

      //printf("%d compression...\n", ++xx);


      if( RCFAILED==rc )
      {
       goto err_out;
      }
      else
      {
       if( RCOK_DATA_UNC==rc )
       {
        lzwinfo.code_num = (u32) number_of_codes;
        total_bytes_compressed = number_of_codes;
        lzwinfo.data_compressed = 0;
       }
       else if( RCOK_DATA_COM==rc  )
       {
        lzwinfo.code_num = (u32) number_of_codes;
        total_bytes_compressed = (CODE_LENGTH * number_of_codes + 7)/8;
        lzwinfo.data_compressed = 1;
       }

       fwrite(&lzwinfo, 1, sizeof(lzw_info_t), fp_dest);
       fwrite(compressed_data_buff, 1, total_bytes_compressed, fp_dest);

       total_bytes_to_compress -= bytes_to_compress;
      }

     } while( total_bytes_to_compress > 0);

     ret_val = 0;

    err_out:

     if( fp_src )
     {
      fclose(fp_src);
     }

     if( fp_dest )
     {
      fclose(fp_dest);
     }

     return ret_val;
    }

    int Lzwd(char *src_file, char *dest_file)
    {
     int ret_val = -1;

     u8 data_buff[MAX_CB_ONECE];
     u8 compressed_data_buff[(MAX_CB_ONECE*CODE_LENGTH)/8];

     FILE *fp_src=NULL, *fp_dest=NULL;
     u32 bytes_decompressed, file_size, file_pos;

     fp_src = fopen(src_file, "rb");
     if( !fp_src )
     {
      goto err_out;
     }

     fp_dest = fopen(dest_file, "wb");
     if( !fp_dest )
     {
      goto err_out;
     }

     fseek(fp_src,0, SEEK_END);
     file_size = ftell(fp_src);
     fseek(fp_src, 0, SEEK_SET);

     file_pos = 0;
     while(1)
     {
      lzw_info_t lzwinfo;
      u32 bytes_to_read;

      if( file_pos >= file_size )
      {
       break;
      }
      fread(&lzwinfo, 1, sizeof(lzwinfo), fp_src);
      file_pos += sizeof(long);

      if( file_pos >= file_size )
      {
       break;
      }

      if( lzwinfo.data_compressed )
      {
       bytes_to_read = ((u32)lzwinfo.code_num * CODE_LENGTH + 7) / 8;
      }
      else
      {
       bytes_to_read = (u32)lzwinfo.code_num ;
      }

      fread(compressed_data_buff, 1, bytes_to_read, fp_src);
      file_pos += bytes_to_read;

      if( lzwinfo.data_compressed )
      {
    #ifdef _USE_ASM_VER__LZW_DECOMPRESS

       lzw_decompress(lzw_translation_table_entries,
        compressed_data_buff, (u32)lzwinfo.code_num,
        data_buff, &bytes_decompressed);
    #else

       lzw_decompress(lzw_translation_table_entries,
        compressed_data_buff, (u32)lzwinfo.code_num,
        data_buff, &bytes_decompressed);
    #endif

       //PrintTranslationTable(lzw_translation_table,
       // lzw_translation_table_entries);

      }
      else
      {
       memcpy(data_buff, compressed_data_buff, bytes_to_read);
       bytes_decompressed = bytes_to_read;
      }


      fwrite(data_buff, 1, bytes_decompressed, fp_dest);
     }

     ret_val = 0;

    err_out:

     if( fp_src )
     {
      fclose(fp_src);
     }

     if( fp_dest )
     {
      fclose(fp_dest);
     }

     return ret_val;
    }

    static N=1;

    int Lzwc_test(char *src_file, char *dest_file)
    {
     int ret_val = -1;

     u8 data_buff[MAX_CB_ONECE];
     u8 compressed_data_buff[(MAX_CB_ONECE*CODE_LENGTH)/8];

     FILE *fp_src=NULL, *fp_dest=NULL;
     u32 code_num;

     fp_src = fopen(src_file, "rb");
     if( !fp_src )
     {
      goto err_out;
     }

     fp_dest = fopen(dest_file, "wb");
     if( !fp_dest )
     {
      goto err_out;
     }

     do
     {
      lzw_info_t lzwinfo;
      int rc;

      fseek(fp_src, N*MAX_CB_ONECE, SEEK_SET);
      fread(data_buff, 1, MAX_CB_ONECE, fp_src);

      FILE *fp_tmp = fopen("test.tmp", "wb");
      fwrite(data_buff, 1, MAX_CB_ONECE, fp_tmp);
      fclose(fp_tmp);

      rc = lzw_compress(lzw_string_table, lzw_string_table_entries,
        data_buff, MAX_CB_ONECE, compressed_data_buff, &code_num);
      PrintStringTable(lzw_string_table, lzw_string_table_entries);

      if( RCFAILED==rc )
      {
       goto err_out;
      }
      else
      {
       u32 bytes_compressed_to;

       if( RCOK_DATA_UNC==rc )
       {
        lzwinfo.code_num = code_num;
        lzwinfo.data_compressed = 0;
        bytes_compressed_to = code_num;
       }
       else if( RCOK_DATA_COM==rc  )
       {
        lzwinfo.code_num = code_num;
        lzwinfo.data_compressed = 1;
        bytes_compressed_to = (code_num * CODE_LENGTH + 7) / 8;
       }

       fwrite(&lzwinfo, 1, sizeof(lzw_info_t), fp_dest);
       fwrite(compressed_data_buff, 1, bytes_compressed_to, fp_dest);
      }

     } while( 0 );

     ret_val = 0;

    err_out:

     if( fp_src )
     {
      fclose(fp_src);
     }

     if( fp_dest )
     {
      fclose(fp_dest);
     }


     return ret_val;

    }


    int main(int argc, char *argv[])
    {
     int ret_val;

     if( 4 != argc )
     {
      printf("Usage: lzw [/c | /d] <source file> <destination file>\n");
      return -1;
     }

     unsigned long t1, t2;
     t1 = GetTickCount();

     if( 'c/' == *(unsigned short *)argv[1] || 'C/' == *(unsigned short *)argv[1] ||
      'c-' == *(unsigned short *)argv[1] || 'C-' == *(unsigned short *)argv[1]
      )
     {
      printf("compressing...");
      ret_val = Lzwc(argv[2], argv[3]);
     }

     if( 'd/' == *(unsigned short *)argv[1] || 'D/' == *(unsigned short *)argv[1] ||
      'd-' == *(unsigned short *)argv[1] || 'D-' == *(unsigned short *)argv[1]
      )
     {
      printf("decompressing...");
      ret_val = Lzwd(argv[2], argv[3]);
     }

     t2 = GetTickCount();

     if( 0==ret_val )
     {
      printf("successfully\n");
      printf("%ld milliseconds elapsed\n", t2-t1);
     }
     else
     {
      printf("failed\n");
     }

     getch();
     return ret_val;
    }


    /*
    void main(int argc, char *argv[])
    {
     Lzwc_test(argv[2], argv[3]);

     getch();
    }
    */

    3/20/2006

    我心目中的计算机科学大牛

     

     MIT BBS上说微软电话面试的一道题就是“Who do you think is the best coder, and why?”。我觉得挺有意思的,也来凑个热闹。排名不分先后。
     Bill Joy, 前任Sun的首席科学家,当年在Berkeley时主持开发了最早版本的BSD。他还是vi和csh的作者。当然,Csh Programming Considered Harmful 是另一个话题乐。据说他想看看自己能不能写个操作系统,就在三天里写了个自己的Unix, 也就是BSD的前身。当然是传说了,但足见他的功力。另一个传说是,1980年初的时候,DARPA让BBN在Berkley Unix里加上BBN开发的TCP/IP代码。但当时还是研究生的B伯伯怒了,拒绝把BBN TCP/IP加入BSD,因为他觉得BBN的TCP/IP写得不好。于是B伯伯出手了,端的是一箭封喉,很快就写出了高性能的伯克利版TCP/IP。当时 BBN和DARPA签了巨额合同开发TCP/IP Stack,谁知他们的代码还不如一个研究生的好。于是他们开会。只见当时B伯伯穿个T-shirt出现在会议室(当时穿T-shirt不象现在,还是相当散漫的哈)。只见BBN问:你怎么写出来的?而B伯伯答:简单,你读协议,然后编程就行了。最令偶晕倒的是,B伯伯硕士毕业后决定到工业界发展,于是就到了当时只有一间办公室的Sun, 然后他就把Sparc设计出来乐。。。象这种软硬通吃的牛人,想不佩服都不行的说。据Bill Joy的同事说,一般开会的时候B伯伯总是拿一堆杂志漫不经心地读。但往往在关键之处,B伯伯发言,直切要害,提出漂亮的构想,让同事们彻底崩溃。对了,他还是Java Spec和JINI的主要作者之一。 [cchere.net 西西河 俺退休了再原创]
     John Carmack,ID Software的founder和Lead Programmer。上个月和一个搞图形的师兄聊天,他竟然不知道John Carmack, 也让偶大大地晕了一把。不过也许搞研究的和搞实战的多少有些隔吧。想必喜欢第一人称射击游戏的都知道J哥哥。90年代初只要能在PC上搞个小动画都能让人惊叹一番的时候,J哥哥就推出了石破天惊的Castle Wolfstein, 然后再接再励,doom, doomII, Quake...每次都把3-D技术推到极限。J哥哥的简历上说自己的专长是"Exhaust 3-D technology",真是牛人之言不我欺的说。做J哥哥这样的人是很幸福的,因为各大图形卡厂家一有了新产品就要向他“进贡” ,不然如果他的游戏不支持哪种卡,哪种卡基本就会夭折乐。当初MS的Direct3D也得听取他的意见,修改了不少API。当然,J哥哥在结婚前十数年如一日地每天编程14小时以上,也是偶们凡人望尘莫及的。对了,J哥哥高中肆业(?),可以说是自学成才。不过呢,谁要用这个例子来为自己学习不好辩护,就大错特错了。那 Leonardo Da Vinci还是自学成才呢(人是私生子,不能上学)。普通人和天才还是有区别的。对了,其实偶们叫“达分奇”是相当不对的,因为Vinci是地名,而Da Vinci就是从Vinci来的人的意思。换句话说,Leonardo Da Vinci就是“从Vinci来的Leonardo”的意思。叫别人“Da Vinci”就不知所谓乐。嗯,扯远了,打住。 [cchere.net 西西河 俺退休了再原创]
     David Cutler,VMS和Windows NT的首席设计师,去微软前号称硅谷最牛的kernel开发员。当初他和他的手下在微软一周内把一个具备基本功能的bootable kernel写出来,然后说:“who can't write an OS in a week?",也是牛气冲天的说。顺便说一句,D爷爷到NT3.5时,管理1500名开发员,自己还兼做设计和编程,不改coder本色啊。
     D爷爷天生脾气火爆,和人争论时喜欢双手猛击桌子以壮声势。 日常交谈F-word不离口。他面试秘书时必问:"what do you think of the word '[censored]'?" ,让无数美女刹羽而归。终于有一天,一个同样火爆的女面对这个问题脱口而出:"That's my favorite word"。于是她被录取乐,为D爷爷工作到NT3.5发布。
     Don Knuth。高爷爷其实用不着偶多说。学编程的不知道他就好像学物理的不知道牛顿,学数学的不知道欧拉,学音乐的不知道莫扎特,学Delphi的不知到 Anders Hejlsberg,或者学Linux不知道Linus Torvalds一样,不可原谅啊。为了让文章完整,就再罗唆几句吧。高爷爷本科时就开始给行行色色的公司写各种稀奇古怪的编译器挣外快了。他卖给别人时收一两千美元,那些公司拿了 code,加工一下卖出去就是上万上十万。不过也没见高爷爷不爽过,学者本色的说。想想那可是60年代初啊,高爷爷写编译器写多了,顺带就搞出了个 Attribute Grammar和LR(k),大大地造福后人啊。至于高爷爷在CalTech的编程比赛(有Alan Kay得众多高高手参加)总是第一,写的Tex到86年就code freeze,还附带2^n美分奖励等等都是耳熟能详的,偶就不饶舌乐。 [cchere.com 西西河 俺退休了再原创]
     顺便说一下,高老大爷是无可争议的写作高手。他给Concrete Mathematics 写的前言可谓字字铿锵,堪为前言的典范。他的技术文章也是一绝,文风细致,解释精当,而且没有学究气,不失轻快跳脱。记得几年前读Concrete Mathemathics,时不时开怀大笑,让老妈极其郁闷,觉得我nerdy到家,不可救药。其实呢,子非鱼,安知鱼之乐,更不知那完全是高爷爷的功劳。说到写作高手,不能不提Stephen A. Cook。他的文章当年就被我们的写作老师极力推荐,号称典雅文风的样本。库爷爷一头银发,身材颀长,总是面带谦和的微笑,颇有仙风道骨,正好和他的仙文相配的说。
     高爷爷其实还是开源运动的先驱。虽然他没有象Richard Stallman那样八方奔走,但他捐献了好多作品,都可以在网上看到,比如著名的Mathematical Writing,MMIXWare,The Tex Book等,更不用说足以让他流芳百世的Tex乐。
     Ken Thompson,C语言前身B语言的作者,Unix的发明人之一(另一个是Dennis M. Riche老大,被尊为DMR),Belle(一个厉害的国际象棋程序)的作者之一, 操作系统Plan 9的主要作者(另一个是大牛人Rob Pike, 前不久被google挖走了)。Ken爷爷也算是计算机历史上开天辟地的人物了。1969年还是计算机史前时代,普通人都认为只有大型机才能运行通用的操作系统,小型机只有高山仰止的份儿。至于用高级语言来写操作系统,更是笑谈。Ken爷爷自然不是池中物,于是他和DMR怒了,在1969年到1970间用汇编在PDP-7上写出了UNIX的第一个版本。他们并不知道,一场轰轰烈烈的UNIX传奇由此拉开了序幕。Ken爷爷在1971年又把Unix用C重写,于是C在随后20年成就了不知多少豪杰的梦想和光荣。 [cchere.net 西西河 俺退休了再原创]
     Ken爷爷还有段佳话: 装了UNIX的PDP-11最早被安装在Bell Lab里供大家日常使用。很快大家就发现Ken爷爷总能进入他们的帐户,获得最高权限。Bell Lab里的科学家都心比天高,当然被搞得郁闷无比。于是有高手怒了,跳出来分析了UNIX代码,找到后门,修改代码,然后重新编译了整个UNIX。就在大家都以为“这个世界清净了”的时候,他们发现Ken爷爷还是轻而易举地拿到他们的帐户权限,百思不解后,只好继续郁闷。谁知道这一郁闷,就郁闷了14年,直到Ken爷爷道出个中缘由。原来,代码里的确有后门,但后门不在Unix代码里,而在编译Unix代码的C编译器里。每次C编译器编译UNIX的代码,就自动生成后门代码。而整个Bell Lab的人,都是用Ken爷爷的C编译器。
     (6)Rob Pike, AT&T Bell Lab前Member of Technical Staff ,现在google研究操作系统 。罗伯伯是Unix的先驱,是贝尔实验室最早和Ken Thompson以及Dennis M. Ritche开发 Unix的猛人,UTF-8的设计人。他还在美国名嘴David Letterman的晚间节目上露了一小脸,一脸憨厚地帮一胖子吹牛搞怪。让偶佩服不已的是,罗伯伯还是1980年奥运会射箭的银牌得主。他还是个颇为厉害的业余天文学家,设计的珈玛射线望远镜差点被NASA用在航天飞机上。他还是两本经典,The Unix Programming Environment 和 The Practice of Programming 的作者之一。如果初学者想在编程方面精益求精,实在该好好读读这两本书。它们都有中文版的说。罗伯伯还写出了Unix下第一个基于位图的窗口系统,并且是著名的blit 终端的作者。当然了,罗伯伯还是号称锐意革新的操作系统,Plan9,的主要作者。可惜的是,Plan9并没有引起多少人的注意。罗伯伯一怒之下,写出了振聋发聩的雄文 Systems Software Research is Irrelevant,痛斥当下系统开发的不思进取,固步自封的弊病。虽然这篇文章是罗伯伯含忿出手,颇有偏激之词,但确实道出了系统开发的无奈:开发周期越来越长,代价越来越大,用户被统一到少数几个系统上,结果越来越多的活动是测量和修补,而真正的革新越来越少。 [cchere.net 西西河 俺退休了再原创]
     就在罗伯伯郁闷之极的时候,google登门求贤来乐。如果说现在还有一家大众公司在不遗余力地把系统开发推向极致的话,也就是google乐。随便看看google的成果就知道了。具有超强容错和负载平衡能力的分布式文件系统GFS (现在能够用100,000台廉价PC搭起一个巨型分布系统,并且高效便宜地进行管理的系统也不多哈),大规模机器学习系统(拼写检查,广告匹配,拼音搜寻。。。哪个都很牛的说),更不用说处理海量并行计算的各式google服务了。Rob在System Software Research is Irrelevant里萧瑟地说现在没有人再关心系统研究的前沿成果了。想不到他错了,应为google关心。google网络了大批功成总是试图吸取系统研究的最新成果。想必Rob Pike在google很幸福。愿他做出更棒的系统。
     Dennis M. Ritchie, 既然Ken Thompson是我的偶像,新闻组上人称DMR的Dennis M. Ritchie自然也是,毕竟两人共同缔造了UNIX,而Dennis几乎独力把C搞大(当然,C的前身是B,而B是Ken Thompson一手做出来的)。J 两人1983年分享图灵奖,是有史以来少数几个因工程项目得奖的工程师(本来是唯一的一对儿,但Alan Kay才因为SmallTalk得奖,所以就成了唯二的乐) 。一个人一生能做出一个卓越的系统已经不易,DMR的C和UNIX长盛不衰近30年,至今生机勃勃,DMR此生可以无憾的说。 [cchere.net 西西河 俺退休了再原创]
     D爷爷也算有家学渊源:他老爸在AT&T贝尔实验室工作了一辈子,并在电路设计方面卓有成就,还出了本颇有影响的书The Design of Switching Circuits,据说在交换理论和逻辑设计方面有独到的论述。当然,D爷爷和他老爸是不同时代的人:他老爸的研究成形于晶体管发明之前,而D爷爷的工作离了晶体管就玩儿不转乐。:-D
     不要看D爷爷搞出了C,其实他最爱的编程语言是Alef,在Plan9上运行,支持并行编程。Alef的语法和C相似,但数据类型和执行方式都和 C大大不同。说到语言,D爷爷对后来人有非常中肯的建议:抱着学习的目的来开发你自己的语言,不要冀望于它被众人接受。这个建议不光对语言开发有用,也适用于其它大型系统的开发。别的不说,DMR后来领导自己的团队在1995年和 1996分别推出了Plan9和Inferno操作系统,又用多少人知道呢?其实,D爷爷当初也没想过C会风行世界。他开发C的初衷和Eric S. Raymond在Cathedral and Bazaar里阐述的一样,就是要消除自己对现有工具的不爽之处。谁知D爷爷无心插柳,C竟然受到众多程序员的狂热拥戴,连D爷爷自己都大惑不解。在一次采访中D爷爷说大概那是因为C的抽象程度碰巧既满足了程序员的要求, 又容易实现。当然C一度是Unix上的通用语言也是原因。但不管怎么说,D爷爷对编程语言出色的审美意识奠定了C广为流传的基础。 [cchere.com 西西河 俺退休了再原创]
     最后八卦一下。D爷爷的业余爱好和NBA大牛Karl Malone一样:开卡车。不过D爷爷更喜欢开NASCAR,而KM独爱巨无霸。J D爷爷自称心中不供偶像,如果一定要说一个,那就是Ken Thompson了。现在Ken爷爷退休当飞机教练去了,而D爷爷当了贝尔实验室系统开发部的头,整日忙于开支票。他俩合作20年,屡屡创造历史。这段令人神往的佳话,也就长留你我心中乐。
     P.S., 很多人都以为Brian W. Kernighan是C的作者。其实BWK只是写了那本经典K&R C。据D爷爷说,他,Ken, 和Kernighan三人中,Kernighan最能写文章,他次之,而Ken写得最少;但说到编程,Ken爷爷才是当之无愧的老大。
     Edsger Wybe Dijkstra, 对,就是E.W. Dijkstra. 一提到EWD,很多人就会想起找最短路径的Dijkstra Algorithm,就好像一提到Sir. Tony Hoare,就想起Quick Sort一样。其实这些个算法不过是两个牛人在他们职业生涯中最琐碎的贡献。比如Dijkstra算法,无非是戴爷爷在1956年为了展示新计算机 ARMAC的计算能力,初试身手的成果,属于他的算法处女作。据戴爷爷自述,他搞出最短路径算法的时候连纸笔都没用。当时他和他老婆在阿姆斯特丹一家咖啡厅的阳台上晒太阳喝咖啡,突然就把这个算法想出来乐。而且当时的算法研究还比较原始,牛人们忙着用计算机搞数值计算,对离散算法不屑一顾。那时连一个象样的专注于离散算法的专业期刊都没有。戴爷爷于是推迟发表这个算法。直到1959年,他才把这个算法发表在Numerische Mathematik的创刊号上,权为捧场。:-) EWD在多个领域牛气冲天,端的是理论和编程两手硬的高手。只不过他的很多工作比较深刻,学校的老先生们觉得本科生接受不了,不给本科生讲而已。 [cchere.net 西西河 俺退休了再原创]
     戴爷爷大概因为最短路径算法一战成名,于是有人请他参加另一台计算机X1的设计工作,并且把设计实时中断系统的任务派给了他。现在看来实时中断也许不算什么,但要知到,X1前根本就没有实时中断的概念。实现它简直就是一场豪赌。戴爷爷起初还不情愿,但经不住项目负责人Bram和Carel的轮番 “吹捧”:我们知道实时中断让您工作变得非常困难,但象您这样的牛人肯定能做出来的说。结果戴爷爷被糖衣炮弹彻底击穿,接下了这个烫手山芋。两三年后,他不仅搞出了实时中断,还围绕这个写出了自己的博士论文,顺利戴上博士帽。
     让戴爷爷真正成名立万的还是在X1上开发的Algo60,最早的高级语言之一。戴爷爷没日没夜地工作了8个月,就搞出了Algo60,也因此获得了 1972年的图灵奖。因为Algo60,戴爷爷发表了一篇石破天惊的文章:Recursive Programming,于是人们才知道,原来高级语言也可以高效地实现递归,原来从此以后,所有程序员都不可避免地和戴爷爷发明的一个词(应该说是概念)打交道:堆栈。而且Algo60还让戴爷爷深入地思考多道程序设计的问题,最终发明了每个系统程序员都绕不开的概念:semaphore。当然,戴爷爷总是把他发明的概念严格形式化,极具科学家本色的说。和这些成就想比,他提出的吃饭的哲学家问题,也就没什么好说的了。 [cchere.net 西西河 俺退休了再原创]
     说来好笑,当时的大学(忘了哪所了)还是觉得戴爷爷没有受过正统的数学训练,也不是专门搞数值分析的,所以最后不太情愿地给了他一个教职。这种小挫折并不能妨碍象戴爷爷这样的牛人创造历史。他一边教数值分析(:-D) ,一边开始开发一个新的操作系统,并培养计算机科学家。几年后,THE Multiprogramming System横空出世。THE是第一个支持松散耦合,显式同步的进程并由此使得严格证明系统没有死锁变得容易的操作系统。可惜戴爷爷任职的系不识货,还强行解散了他的研究小组(1972年戴爷爷给他的系主任说他得了图灵奖,系主任的第一反应是你们搞计算机就喜欢乱发奖)。这让戴爷爷相当郁闷,得了抑郁症。在极度郁闷之中,戴爷爷决定用写作来治疗自己的抑郁症。于是经典就诞生乐:Notes on Structured Programming。戴爷爷从此被尊为结构化编程的奠基人,而且他的抑郁症也被治好乐。
     EWD太牛,结果他的故事也太多。先到这里吧。1973起,他的故事就在美国发生了。 [cchere.net 西西河 俺退休了再原创]
     Anders Hejlsberg,微软.NET的首席架构师,编程语言设计和实现的顶尖高手。他一手做出了 Turbo Pascal, 也是Delphi, J++(尤其是WFC),C#, 和.NET的主要作者。这些作品的名字足以为他立传。作为一个程序员,我在这样的大师面前实在无语。生子当如Anders的说。李维的里已详细讲述了Anders的传奇故事,我就不用费舌了:http: //java.mblogger.cn/iexploiter/posts/1505.aspx 。Artima上有Anders谈C#的系列访谈。MSDN上有一段Anders导游的录像 。有兴趣可以去看看牛人的丰采。
    2/9/2006

    软件编程网络资源

    网络资源汇总贴
     
    本贴将尽可能的收集跟软件产业相关的网站资料
    大家以后发现一些好的学习网站可以发到这里,就不必再另发主题了 
    发帖要求:标题是网站名,内容是链接,简介(最好不多于4行)要精要明了。
    本贴会不断维护更新
     
    1. 综合性站点
     
    csdn官方网站
    http://www.csdn.net 
    中国最大的开发者网络,大量的资料和源码,还与经典文献
     
    msdn官方站点
    http://msdn.microsoft.com/ 
     
    SourceForge
    http://sourceforge.net
    注:挂在sourceforge.net上的好几个网站: 
    http://www.boost.org 
    http://www.wxwindows.org 
    如果无法访问 
    可以用: 
    http://boost.sourceforge.net/ 
    http://wxwindows.sourceforge.net/ 
    代替
     
     
    CodeProject
    http://www.codeproject.com/ 
     
    All File Format
    http://www.wotsit.org/ 
     
    国际标准化组织
    http://www.iso.org/ 
     
    中国知识产权网
    http://www.cnipr.com/ 
     
    全国计算机等级考试网
    http://www.ncre.cn/ncre_new/index.html 
     
    国家计算机病毒应急处理中心
    http://www.antivirus-china.org.cn/ 
     
    http://www.delphibbs.com 
    目前有关delphi,c++,java的最好的论坛,另有大量资料和离线数据库下载
     
    http://www.iturls.com 
    提供软件开发以及其他一些it资源的网络连接,资源对于学习很有用
     
    破釜沉舟 - 网络学院
    http://www.7880.com/Info/index.html
    有不少文章,还有一些电子书
     
    编程爱好者
    http://www.programfan.com/ 
     
    http://tech.sina.com.cn/introduction/prog.shtml 
    一些技术文章
     
    Programmer's Heaven 
    http://www.programmersheaven.com/ 
     
    http://freshmeat.net/ 
    和sourceforge差不多,而且很多project的homepage都是挂在sourceforge上的
     
    中国IT实验室
    http://www.chinaitlab.com/
     
     
    ################################################################
    2. 编程语言类
     
    2.1 C/C++
     
    2.1.1 C/C++ 资源
     
    C++标准程序库 
     
    http://www.ccd.bnl.gov/bcf/cluster/pgi/pgC++_lib/stdlib.htm 
     
    C++标准
    http://std.dkuug.dk/jtc1/sc22/wg21/docs/standards 
     
    C99标准
    http://www.nirvani.net/docs/ansi_c.pdf 
     
    Cprogramming.com
    http://www.cprogramming.com/ 
     
    Dr. Dobb's Journal
    http://www.ddj.com/ 
     
    C/C++ Users Journal
    http://www.cuj.com/ 
     
    The C++ Source
    http://www.artima.com/cppsource/index.jsp
     
    C维视点
    http://www.c-view.org 
     
    C语言之家
    http://www.cstudyhome.com/wenzhang06/ 
     
    维C世界
    http://www.vcok.com/ 
     
    Bjarne Stroustrup的所有访谈录 
    http://www.royaloo.com/bjarne/bjarne.htm
     
    C/C++编码规范
    http://www.fjmcu.com/html/mixed/c++.html 
     
    Boost
    http://www.boost.org/ 
     
    ACE
    http://www.cs.wustl.edu/~schmidt/ACE.html 
     
    Dev-C++
    http://www.c-view.org/soft/devcpp/index.html 
     
    STLport
    http://www.stlport.org/ 
     
    SGI STL
    http://www.sgi.com/tech/stl/ 
     
    Dinkum C++ Library
    http://www.dinkumware.com/ 
     
    Qt
    http://www.trolltech.com/ 
     
    Qt中文网
    http://www.qiliang.net/qt.html  
     
    MS C++(VC)对象模型
    http://msdn.microsoft.com/archive/en-us/dnarvc/html/jangrayhood.asp 
     
    Itanium C++ ABI(GCC等编译器使用的C++对象模型)  
     
    http://www.codesourcery.com/cxx-abi/abi.html 
     
    http://www.vchelp.net 
    学习vc的兄弟去看看,开发计划,学习论坛,合作开发论坛,还有大量文章和源
     

     
    http://www.vchome.net/index.asp 
     
    http://www.vckbase.com 
    vc知识库,有很全的vc知识,文章和源代码,还有好的技术团队支持,是学习vc
     
    的好伴侣
     
     
    2.1.2 个人站点(来源于jjhou.com) 
     
    Bjarne Stroustrup
    http://www.research.att.com/~bs/ 
     
    Stanley B. Lippman
    http://staff.develop.com/slip/ 
     
    David Musser
    http://www.cs.rpi.edu/~musser/ 
     
    Scott Meyers
    http://www.aristeia.com/ 
     
    Nicolai M. Josuttis
    http://www.josuttis.com/ 
     
    Bruce Eckel
    http://www.mindview.net 
     
    Herb Sutter
    http://www.gotw.ca/ 
     
    Andrei Alexandrescu
    http://www.moderncppdesign.com 
     
    候捷个人网站
    http://www.jjhou.com/
     
     
    2.1.3 C++相关库下载  
     
    SGI STL
    http://www.sgi.com/tech/stl/download.html 
     
    STLport
    http://www.stlport.org/download.html 
     
    Boost
    http://sourceforge.net/project/showfiles.php?group_id=7586 
     
    ptypes
    http://sourceforge.net/projects/ptypes/ 
     
    Loki
    http://sourceforge.net/projects/loki-lib/ 
     
    ACE,TAO,CIAO
    http://deuce.doc.wustl.edu/Download.html 
     
    OTL 
    http://otl.sourceforge.net/ 
    OTL 库是C++最强大的数据处理库之一,Oracle等商业公司也推荐大家使用OTL。 
    要想达到最高的运行效率就必须使用C或C++语言,但C语言不能提供特定场合下的
     
    开发效率,而C++能保证这一点,所以目前主流的数据库开发有三种:a.使用C语
     
    言调用数据库api,b.使用其他任意语言调用ODBC/ADO/ADO.net等,c.使用C++语
     
    言的一个库:OTL;下面做个比较 
    ---方法--------     ---开发效率---   ---运行效率---    ---部署容易度--- 
    C语言调用API              低               高                高 
    C#调用ADO.NET             中               低                低 
    C++使用OTL模板            高               高                高
     
     
    2.1.4 编译器相关下载
     
    VCToolKit2003
    http://msdn.microsoft.com/visualc/vctoolkit2003/ 
     
    GNU C++
    http://gcc.gnu.org/ 
     
    Dev-C++
    http://www.c-view.org/soft/devcpp/devcpp.html 
     
    CygWin (GNU + cygnus + Windows)
    http://cygwin.com/ 
     
    C++ Builder
    http://www.borland.com/products/downloads/download_cbuilder.html 
     
    ---------------------------------------------------------------
    2.2 Java
     
    2.2.1 Java 学习
     
    http://www-900.ibm.com/developerWorks/cn/java/index.shtml 
    看了这个其它的你都不想看了
     
    http://www.chinajavaworld.com
     
    http://www.javashelf.com/ 
     
    http://www.javacn.com 
     
    http://www.matrix.org.cn/javadown.asp 
    学习JAVA的首选网站。
     
    Java examples (example source code) Orgainzed in Topic into Categories
    http://www.java2s.com/
     
    2.2.2 Eclipse官方及插件网站
     
    Eclipse 官方站点
    http://www.eclipse.org/ 
     
    http://www.eclipse-workbench.com/jsp/ 
    http://www.objectlearn.com/index.jsp 
    http://www.crionics.com/products/opensource/eclipse/eclipse.jsp 
    http://eclipse-plugins.2y.net/eclipse/index.jsp  ----------good 
    ftp://202.113.29.2/pub/eclipse/plugins/ 
    http://sourceforge.net/projects  -------plugin project
    http://vssplugin.sourceforge.net/ 
    http://www.azzurri.jp/en/software/clay/index.jsp  ---------database modeling plugin
    http://www.improve-technologies.com/alpha/struts-config-editor/  --------plugin 
    http://www.sysdeo.com/eclipse/tomcatPlugin.html  --tomcat的plugin和jboss的plugin 
     
    Lombo
    http://www.objectlearn.com/ 
    TomcatPlugin
    http://www.sysdeo.com/eclipse/tomcatPlugin.html
     
    EasyStruts
    http://easystruts.sourceforge.net
     
    EclipseColorer plugin 
    http://colorer.sf.net 
     
    CVS-SSH2 Plug-in for Eclipse 
    http://www.jcraft.com/eclipse-cvsssh2/ 
    JadClipse
    http://jadclipse.sourceforge.net/
     
    SWT Designer
    http://www.swt-designer.com/
     
    Hibernator
    http://hibernator.sourceforge.net/ 
     
    1.eclipseuml-installer_1.2.1.20030512.jar
    req emf_1.1.0_20030501_0612VL.zip & GEF-runtime-I20030327.zip
    UML工具,比较像rose, 有些bug,而且没有放大缩小,拖来拖去眼都晕了,不过比slim好
    2.lomboz.21_02.zip
    J2ee plugin ,dw上推荐的说
    http://www-900.ibm.com/developerWorks/cn/java/l-jsp-eclipse/index.shtml?n-j-04241
     
    3.jadclipse_b206
    Jad Java decompiler plugin
     
    4.NLS-SDK-2.0.1-Translations.zip
    eclipse多国语言包,连doc都本地化了!
     
    5.v4all_2.1.0.17
    传说中的Swing IDE,可视化编程
     
    6.EclipseColorer-take5.0.4.0
    据说可以语法加亮上百种语言,非常好,至少在XML中如此,棒极了
     
    7.xparrots_proxysettings_0.1.1
    这个最重要了 http proxy plugin
     
    8.checkstyle_eclipse_plugin_v2.1.0
    可以查出编码不好的地方
     
    9.de.mvmsoft.slime_1_1_1_eclipse
    UML建模工具,逆向工程和drag功能做的很好,放大缩小也很好,不过图形看上去不舒服。
     
    10.com.objfac.xmleditor_0.2.8
    受到推崇的XML编辑器
     
    11.jalopy-eclipse-0.2.6
    格式化工具,比eclipse自带的强很多,但是不是太用,一般用把别人的代码整理成自己的风格,他会移动代码位置。
     
    12.OO.还有些在线升级的
    http://www.improve-technologies.com/alpha/updates/site.xml 
    有Axis, C#, XSLT, Resin, Editors等插件
    http://download.eclipse.org/technology/ajdt/update 
    AspectJ
    http://www.x-parrots.com/eclipse/updates/ 
    iPAS, Http Proxy, Telent 
     
    http://eclipse-plugins.2y.net/eclipse/index.jsp 
    http://www.omondo.com/download.jsp 
    http://www.eclipse-workbench.com/jsp/plugins.jsp
     
    http://www.genuitec.com/products_wsad.htm
     
    http://www.myeclipseide.com/ 
     
    JSP插件:
    Eclipse作为一个java应用的IDE,使用非常方便,但是对于Jsp的开发支持还显得不够,在这里向大家推荐一个eclipse的plugins来协助JSP开发。这个名称叫lomboz,不但支持JSP语法高亮显示,还有Code Assist功能,可以与Jbuilder媲美。下面简要介绍一下eclipse2.1结合Tomcat开发Jsp的过程。
    下载: http://www.objectlearn.com/
     
    http://www.eclipseplugincentral.com/
     
    Visual Swing Designer for Eclipse
    http://v4all.sourceforge.net/index_start.html
     
    http://www.docsky.com/doclist.asp?category=J2EE&category1=开发工具&category2=eclipse
     
    ---------------------------------------------------------------
    2.3 C#
     
     
    ---------------------------------------------------------------
    2.4 VB
     
     
    ---------------------------------------------------------------
    2.5 PB
     
    http://221.10.44.214:85/default.asp 
    关于PB编程的一个网站 
     
     
    ---------------------------------------------------------------
    2.6 Python
     
    关于Python的链接,比较全
    http://www.python-eggs.org/links.html 
     
     
    ---------------------------------------------------------------
    2.7 ASM
     
    AoGo的站点 
    http://www.aogosoft.com/ 
    人很多,有一个小型的BBS,可能是他自己写的,牛得YTHT,有问题可以到那个BBS 
    问,16位和32位汇编都有,里面高手如云 
     
    罗云彬的站点 
    http://211.90.225.98:22366/index.asp 
    毕业于浙大,在台州电信工作,后因台州电信黑客案(其实就是很小的事, 
    可能因为才气太旺,被人搞了)打算出书,于是出那本前无古人 
    后无来者的win32平台下的汇编语言程序设计,他的主页上有,当年我在学苑书店 
    (那时候还在西门)看到此书大脑狂热立刻买了下来,唯一后悔的是当时大脑怎么 
    那么发热呢,学苑不打折的,70多rmb啊,要是从china-pub上买会省我近20rmb, 
    NND,又一顿福口居没了。 
    不知道他现在在哪工作,反正感觉他很爽的现在,经常出去旅游。。。。 
     
    老罗的站点,和他聊过,不知道现在在广州还是在珠海,也相当牛 
    http://www.luocong.com/ 
     
    无花果的站点,好像病毒研究得更多一点,QQ经常潜水,从来不见浮上来。。。 
    http://www.cnasm.com/ 
     
    国外的很不错的汇编站点,很多资料,不仅仅是Win平台上的,N多官方资料和工具 
    http://webster.cs.ucr.edu/ 
     
    <<MASM Programming Guide>> 
    http://doc.ddart.net/asm/Microsoft_MASM_Programmers_Guide_v6.1/ 
     
     
    ################################################################
    3. 软件工程
     
    UML
     
    http://www.omg.org/technology/uml/ 
     
    http://www.uml.org.cn/ 
    各各方面分得很细的好站点,还有很多很激励人的好文章
     
    ################################################################
    4. EBook
     
    西安资源网
    http://www.infoxa.com/ 
    上面的电子书超多,重点吐血推荐
     
    http://www.maththinking.com/boat/booksIndex.html
    很多电子eBook,吐血推荐。国外的网站,速度可能有点慢。
     
    传业电脑电子书库
     http://www.netyi.net/
     
    豆豆下载 
    http://soft.ddvip.net/SoftList/Catalog_244_SoftTime_Desc_1.html  
     
    网络合肥E书下载 
    http://www.hf114.com/book/b_type.asp?b_type=电脑教程  
     
    北极星书库 
    http://www.ebook007.com/ 
     
    Win32API参考手册
    http://www.aogosoft.com/downpage.asp?table=soft&id=128 
     
    维维软件园
    http://www.vvsoft.net/index.html
    计算机技术方面资料挺多
     
    ################################################################
    5. 编程竞技
     
    ACM World Finals
    http://acm.sjtu.edu.cn/worldfinals/home.htm
     
    浙大ACM站点
    http://acm.zju.edu.cn/
     
    http://www.topcoder.com 
    一个跟全球高手同台竞技的网站
    每周有一次match,每个季度有一次Tournament 
    C++, Java and C# is acceptable
     
     
    ################################################################
    6. 游戏开发
     
    http://www.gameres.com/ 
    比较全面的关于游戏开发游戏信息的网站,有很多教程和源代码,唯一的缺点是
    速度慢。
     
    中国游戏开发资源网
    http://www.gameres.com/ 
     
    中国游戏开发者
    http://www.chinagamedev.net 
     
     
    ################################################################
    7. 其它
     
    驱动开发论坛 
    http://www.driverdevelop.com/index.php 
     
    数据结构自考网
    http://www.wjzyzx.com/rjxy/sjjg/main.htm 
     
    罗云彬的编程乐园
    http://211.91.36.90:8080/
    (http://asm.yeah.net
     
    加密与解密-看雪学院
    http://www.pediy.com/ 
     
    汉化教学基地
    http://teach.hanzify.org/ 
     
    正则表达式 
    http://www.basetem.com/peter/mydocument/Other/RegularExpressions/ 
     
    http://www.pudn.com/ 
    Windows Linux/Unix Internet编程 黑客与安全 病毒 通讯编程 游戏 编辑器 多
    媒体 图形图象 编译器/解释器 压缩解压加密解密 数值算法 中文编程 磁盘工具 
    语音合成与识别 Java编程 汇编语言 SCSI/ASPI 应用程序 其他 数据库编程 嵌
    入式/单片机编程 Flash源码 
    注册之后需要上传5个该网站没有的程序源代码,才能下载。普通用户每天能下载
    10个不同的程序源代码。一般情况下,如果注册后不上传程序源代码可是试试以
    注册的用户名为登录名,以注册的邮政编码为登录密码,有可能能登陆成功并进
    行下载。
     
    零度在线
    http://www.zwye.com 
    精品软件 破解 注册机 教程下载 网络学院
    2/6/2006

    Kosmix挑战Google

    2月6日消息,据国外媒体报道,两位印度裔电脑天才最近声称,他们将建立一家新的搜索引擎公司,公司名称为Kosmix,由于具备更为强大的搜索功能,Kosmix完全可以对Google发起挑战。

    安迪-拉贾罗曼(Anand Rajaraman )和维基-哈里那亚(Venky Harinarayan)在斯坦福大学上学期间是Google两位创始人拉里-佩奇和塞尔盖-布林的同学。他们表示,Kosmix搜索主要从网页内容本身着眼,而不像Google只是根据一网页与其它网页的关联度作为搜索的依据。

    截至目前,Google可以说是全球最强大的搜索引擎,所覆盖的网页信息库也是最大的。用户键入一个字或者短语,Google可以迅速地在网页数据库中搜索,并发现包括该字或者短语的网页,然后将更多的相关内容提交给用户。Google搜索具备很多优点,但其搜索结果往往并不是用户需要的信息,只是与用户的需求接近。Kosmix搜索技术将弥补上述不足,因为该搜索技术主要以网页内容,而非关联度作为搜索依据。

    Kosmix目前已开发了一种分类搜索技术。首先,它会要求用户限定一个搜索类别。举例来说,如果一个搜索类目与医疗卫生有关,用户就可以在一个与医疗卫生相关的搜索栏目内进行查询。通过这种方式,Kosmix提供的信息就更加具有针对性。哈里那亚表示,如果一个网页与用户搜索内容类似,Kosmix会对其进行链接,这样用户就可以充分了解搜索内容,在该类别内更迅速地获得自己想看到的内容。

    Kosmix公司将于下周正式推出自己的搜索产品Kosmix。该公司目前正在进行有关医疗卫生类别信息的搜索测试,用户可以到该公司网站http://www.kosmix.com上进行体验。明年,该公司就将推出更多类别的分类搜索服务,包括卫生、旅游、政治和财经等。这些类别都会出现在搜索引擎的主页上,分列为不同的栏目。公司计划于年内推出通用搜索服务。