2006年5月30日

一直有留意Firefox对IE的冲击,不过以前用IE也并没觉得有什么大问题,就一直用下来。

直到最近的IE老出问题,公司派的本本装的是win2000,用久了里面的IE经常会弹出一个crash的对话框(似乎在XP里就很少见),然后所有打开的IE窗口都只能关闭,解决无方,于是想到了Firefox,试用一下,第一感觉是非常快,不管是load firefox还是打开新的网页,基本上都是文字刷一下就出来,图片则延迟了点,不过还是比IE做得好:) 很多小的细节都考虑得比较符合用户的操作习惯,比如工具栏有一个下载的管理器,管理最近下载的咚咚,不用第三方软件,而且Firefox比IE小巧多了(4.8M),Simple is beautiful,呵呵,I like it.
posted @ 2006-08-20 23:26 响 阅读(153) | 评论 (1)编辑 收藏
 

Q If Java uses the pass-by reference, why won't a swap function work?

AYour question demonstrates a common error made by Java language newcomers. Indeed, even seasoned veterans find it difficult to keep the terms straight.

Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.

Take the badSwap() method for example:


public void badSwap(int var1, int var2)
{
  int temp = var1;
  var1 = var2;
  var2 = temp;
}

When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well.

Now, here is where it gets tricky:


public void tricky(Point arg1, Point arg2)
{
  arg1.x = 100;
  arg1.y = 100;

  Point temp = arg1;
  arg1 = arg2;
  arg2 = temp;
}

public static void main(String [] args)
{
  Point pnt1 = new Point(0,0);
  Point pnt2 = new Point(0,0);
  System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
  System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
  System.out.println(" ");
  tricky(pnt1,pnt2);
  System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
  System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  
}

If we execute this main() method, we see the following output:


X: 0 Y: 0
X: 0 Y: 0

X: 100 Y: 100
X: 0 Y: 0

The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In the main() method, pnt1 and pnt2 are nothing more than object references. When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.


Figure 1. After being passed to a method, an object will have at least two references

Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail. As Figure 2 illustrates, the method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call, we need to swap the original references, not the copies.


Figure 2. Only the method references are swapped, not the original ones

O'Reilly's Java in a Nutshell by David Flanagan (see Resources) puts it best: "Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'" As a result, you cannot write a standard swap method to swap objects.

Resources

posted @ 2006-08-17 22:00 响 阅读(279) | 评论 (0)编辑 收藏
 
http://www.physics.orst.edu/~rubin/nacphy/brian/socket.html
另外关于Java network的一些基础的教程:
http://java.sun.com/docs/books/tutorial/networking/index.html
posted @ 2006-08-17 10:01 响 阅读(682) | 评论 (0)编辑 收藏
 
http://www-128.ibm.com/developerworks/cn/java/j-jtp05273/
不过翻译得比较烂,还是看英文吧:
http://www-128.ibm.com/developerworks/library/j-jtp05273.html
posted @ 2006-08-10 11:02 响 阅读(216) | 评论 (0)编辑 收藏
 
 很老的文章,不过关于事务的阐述还是比较全面的。全文可见:http://www.javaworld.com/jw-07-2000/jw-0714-transaction.html
一个事务可以定义为由一组操作组成的不可分割的单元,它们要么全部被执行,要么全部不执行以保持事数据完整性。比如,从你的支票帐户到你的储蓄账户进行100美元的转帐包含以下两步操作:从支票账户登记借出100美元,然后在储蓄账户添加100美元。这两步必须同时被执行或者不执行以保护数据的完整性和一致性,以及银行和客户之间的利息核算。因此,这两步的操作组成了一个事务。


事务的属性

所有的事务都具备以下几个属性:原子性、一致性、独立性以及持久性(缩写为ACID)。

原子性:意味着不可分割,一组操作是不可分割的,我们称之为原子的。

一致性:一个事务的转换必须是把持久化的数据从一个一致的状态转换到另一个一致的状态,任何发生在其间的转换失败,都必须保证数据能够返回转换之前的那个状态。

独立性:  事务之间应互不影响,也就是说,一个处于未完成状态的事务(未commit或rollback),必须独立于其他的事务;即使几个事务同时运行,对其中每一个事务来讲,其他的事务也必须在它之前或者之后完成,所有的并发事务都必须按照实际的顺序依次完成。

持久性:一旦一个事务成功地提交完成之后(commit),由该事务所带来的状态的改变必须是稳定和持久的,即使在提交完成之后发生了其他的错误也不受影响。

因此,一个事务运行的最终结果只有两个:commit ——每一步操作的成功执行;rollback——由于执行过程中出现了错误,rollback保证没有一步操作执行。



事务独立性的等级

事务的独立性用来衡量并发事务中一个事务查看另外一个事务已经update但尚未commit的数据的能力,如果某些事务允许其他事务读取它已经upadte但尚未commit的数据,这些事务可能会以存在不一致的数据而roll back,或者结束不必要的等待而commit成功。( those transactions could end up with inconsistent data were the transaction to roll back, or end up waiting unnecessarily were the transaction to commit successfully. )

越高等级的独立性意味着越少的并发性,并且越有可能成为系统性能的瓶颈,但它也减少了读取到不一致数据的机会。一个好的应用原则是在可接受的系统性能基础上选择尽可能高的独立性。以下是通常的独立性等级划分,从最低到最高如下:

ReadUncommitted:已经update但尚未commit的数据可以被其他事务读取

ReadCommitted:一个事务只有commit了的数据才可被其他事务读取

RepeatableRead: 一个事务只有commit了的数据才可被其他事务读取,重复的读取则会导致和数据尚未提交状态时一样的结果

Serializable: 这是最高等级的独立性等级,保证了一个事务对数据排他性的读写访问,它包含了ReadCommitted和RepeatableRead级别的所有限制,同时保证所有的事务必须逐个执行,以获取最大程度的数据完整性,这导致了最低的运行性能以及最少的并发性,注意,这里的Serializable和Java里面的java.io.Serializable毫无联系。



J2EE支持的事务

J2EE平台包括了规范、兼容性test suite,application开发蓝图,以及参考实现。基于相同的规范,众多的开发商提供了不同的应用服务器和实现。J2EE组件的设计是基于规范而非基于特定的产品(比如基于某个特定的应用服务器)。J2EE应用程序里的组件利用了J2EE容器和服务器所提供的基础服务,因此只需要将关注点放在处理业务逻辑上,J2EE通过部署描述符,使用声明式的属性,支持可伸缩的部署以及在目标环境中可定制的能力。J2EE的目标是保护IT投资以及降低application开发的成本,J2EE的组件可以自己开发也可从外面的代理商处获得,这样可以使得你的IT部门的成本降低并提高了可伸缩性。

J2EE所提供的基础服务中一个重要部分便是对事务的支持,在J2EE规范中,描述了Java事务的API(JTA,Java Transaction API),JTA主要包括了几个接口:javax.transaction.UserTransaction和javax.transaction.TransactionManager。UserTransaction接口提供给application组件,对application组件而言,底下的J2EE服务器和TransactionManager之间的交互是透明的。TransactionManager的实现提供给应用服务器对事务边界的控制。J2EE的application组件提供了对JTA的UserTransaction和JDBC的事务的支持。

J2EE平台支持了两种类型的事务管理范式:声明式的事务和编程式的事务(declarative transaction demarcation and programmatic transaction demarcation.

...(to be continued)
posted @ 2006-07-17 23:38 响 阅读(267) | 评论 (0)编辑 收藏
 

The history of software development is a history of raising the level of abstraction. Our industry used to build systems by soldering wires together to form hard-wired programs. Machine code let us store programs by manipulating switches to enter each instruction. Data was stored on drums whose rotation time had to be taken into account so that the head would be able to read the next instruction at exactly the right time. Later, assemblers took on the tedious task of generating sequences of ones and zeroes from a set of mnemonics designed for each hardware platform.

软件开发的历史是抽象层次不断提高的历史,我们的工业以前是通过将电路焊接在一起以形成硬件组成的程序,这样来进行系统的搭建。机器码使得我们可以通过操作开关来输入每条指令,数据保持在×××××。。。,后来,汇编程序通过为每种硬件平台定义相应助记符的形式,帮我们把这种繁琐的0/1操作中解放出来。

At some point, programming languages, such as FORTRAN, were born and "formula translation" became a reality. Standards for COBOL and C enabled portability among hardware platforms, and the profession developed techniques for structuring programs so that they were easier to write, understand, and maintain. We now have languages like Smalltalk, C++, Eiffel, and Java, each with the notion of object-orientation, an approach for structuring data and behavior together into classes and objects.
到了后来,编程语言诸如FORTRAN的出现,使得“公式翻译”成为现实,COBOL和C标准使得不同硬件平台之间的移植成为可能,后来发展出了结构化的程序设计方式,使得编程语言更容易编写、理解和维护。我们现在拥有像smalltalk、C++、Eiffel和Java,它们运用了面向对象技术,一种把数据和行为封装到类和对象的方法。

As we moved from one language to another, generally we increased the level of abstraction at which the developer operates, which required the developer to learn a new, higher-level language that could then be mapped into lower-level ones, from C++ to C to assembly code to machine code and the hardware. At first, each higher layer of abstraction was introduced only as a concept. The first assembly languages were no doubt invented without the benefit of an (automated) assembler to turn mnemonics into bits, and developers were grouping functions together with the data they encapsulated long before there was any automatic enforcement of the concept. Similarly, the concepts of structured programming were taught before there were structured programming languages in widespread industrial use (for instance, Pascal).

当我们从一种语言发展到另一种语言的时候,通常我们提高了开发者进行开发所处的抽象层次,这需要开发者学习新的、更高层次的能够映射到低层次的语言,如C++到C到汇编代码到机器码和硬件。最初,每一个更高层次的抽象只是作为一个概念被引入。最初的汇编语言被发明的时候,作为把助记符转换到字节码的汇编器并没有体系出什么明显的又是。。。。,类似的,结构化程序设计的概念也显得很不为人接受直到结构化编程语言在工业界广为使用。

Over time, however, the new layers of abstraction became formalized, and tools such as assemblers, preprocessors, and compilers were constructed to support the concepts. This had the effect of hiding the details of the lower layers so that only a few experts (compiler writers, for example) needed to concern themselves with the details of how those layers work. In turn, this raises concerns about the loss of control induced by, for example, eliminating the GOTO statement or writing in a high-level language at a distance from the "real machine." Indeed, sometimes the next level of abstraction has been too big a reach for the profession as a whole, only of interest to academics and purists, and the concepts did not take a large enough mindshare to survive. (ALGOL-68 springs to mind. So does Eiffel, but it has too many living supporters to be a safe choice of example.)

随着时间的过去,然而,新的抽象层次也开始正式形成,相应的工具如汇编器、预处理器和编译器开始出现以支持这些概念。它们把低抽象层次的细节隐藏,使得只有少数的专家(如编译器的编写者)需要关心这些细节如何工作。。。。。

As the profession has raised the level of abstraction at which developers work, we have developed tools to map from one layer to the next automatically. Developers now write in a high-level language that can be mapped to a lower-level language automatically, instead of writing in the lower-level language that can be mapped to assembly language, just as our predecessors wrote in assembly language and had that translated automatically into machine language.

随着开发者开发的抽象层次的提高,我们开发出从一个层次自动映射到另一个层次的工具。开发者现在只需编写高层次的编程语言,之后的转换将是自动进行的。

Clearly, this forms a pattern: We formalize our knowledge of an application in as high a level a language as we can. Over time, we learn how to use this language and apply a set of conventions for its use. These conventions become formalized and a higher-level language is born that is mapped automatically into the lower-level language. In turn, this next-higher-level language is perceived as low level, and we develop a set of conventions for its use. These newer conventions are then formalized and mapped into the next level down, and so forth.

显然,这形成了一种模式:我们不断地提高抽象的层次的概念,随着时间的过去,我们学会了如何使用这种语言以及应用一系列的使用约束。这些约束变成正式后一种新的语言诞生了,而这种下一代的语言是从低层次被感知的,当我们定义一系列的使用约束之后,这些新的约束又被正式化,来推动下一阶段的发展。不断地循环。

The next level of abstraction is the move, shown in Figure 1-1, to model-based development, in which we build software-platform-independent models.
下一阶段的抽象层次在发展,如图所示。它是基于模型的开发,在这里我们建立的是和软件平台无关的模型。

Figure 1-1. Raising the level of abstraction

graphics/01fig01.gif
Software-platform independence is analogous to hardware-platform independence. A hardware-platform-independent language, such as C or Java, enables the writing of a specification that can execute on a variety of hardware platforms with no change. Similarly, a software-platform-independent language enables the writing of a specification that can execute on a variety of software platforms, or software architecture designs, with no change. So, a software-platform-independent specification could be mapped to a multiprocessor/multitasking CORBA environment, or a client-server relational database environment, with no change to the model.
软件平台无关是和硬件平台无关类似的概念。一个硬件平台无关的语言,如C或者Java,可以使得一个规范的编写能够在不同的硬件平台上运行而不需要更改。类似地,一个软件平台无关的语言可以使得一个规范的编写可以在不同的软件平台上运行,或者在不同的软件架构中运行,而不需要更改。因此,一个软件平台无关的规范可以映射到多处理器/多任务CORBA环境,或者一个C-S关系数据库环境,而不需要更改模型。

In general, the organization of the data and processing implied by a conceptual model may not be the same as the organization of the data and processing in implementation. If we consider two concepts, those of "customer" and "account," modeling them as classes using the UML suggests that the software solution should be expressed in terms of software classes named Customer and Account. However, there are many possible software designs that can meet these requirements, many of which are not even object-oriented. Between concept and implementation, an attribute may become a reference; a class may be divided into sets of object instances according to some sorting criteria; classes may be merged or split; statecharts may be flattened, merged, or separated; and so on. A modeling language that enables such mappings is software-platform independent.
总的而言,由概念模型所驱动的数据的组成和处理也许和实际的数据组成和处理不完全相同。如果我们考虑两个概念,比如“customer”和“Account”,将他们建模程UML的类图以期望能够被用。

posted @ 2006-05-30 10:46 响 阅读(255) | 评论 (0)编辑 收藏