小城,风带香

好好学习,天天向上

项目管理中所涉及到的一些文档整理

春天的熊:

前期策划阶段:
—————–
1  目标分析文档;
弄清楚做什么样的产品,为什么,我们能获得什么,客户能获得什么;

2 竞品分析文档;
这一步不需要多说。

3 需求分析文档;
分析客户,整理需求,挖掘需求;

4 解决方案;
根据需求分析创造解决方案记录。

5 总策划方案;
整理上述内容,撰写初步的策划文案,目标是让领导、技术、美术等相关人员知道你要搞啥,为啥。

底层策划阶段:
—————–
6  系统构架图、数据关系图;
此产品的底层架构是如何的,页面与页面之间的逻辑关系是怎样的。通过什么来在页面之间传递数据。与涉及到的其他系统之间如何关联。

7 技术难点清单;
底层开发难点1.2.3……

8 技术评估报告;
根据文档7、8,开展技术会议,是否可行,是否有更优化方案。

9  页面结构图;
与技术确定后,可以开始具体页面设计,此环节主要为交互细节设计,可参考交互设计一、二、三、四、五几个阶段;

10  功能说明及开发优先级文档;
页面策划完成后,撰写功能说明文档,列出功能涉及到的字段、流程图、其他系统关系等。

美术设计阶段:
—————-
11美术沟通备忘;
设计风格需求怎样,交互风格怎样,列清楚;

12 效果图v1,2,3,4,5……;

13 交互及美术规范;
完稿后,由美术撰写交互及美术规范;

实施阶段:
—————-
14  功能点开发情况、监控对照表;
此文档用于监控所有功能的开发情况,以及相关负责人员。

15 测试功能点、用例及步骤表;

16 Bug汇总、监控表;

17  完工后的开发文档;
一般来讲,在开发过程中,对于具体的技术实现方式、数据交换方式都会有改进,突破,或者是不能达到退而求其次的地方。所以,项目开发完成后,需要根据实际的情况,重写开发文档,以便日后再开发用,此文档技术主导。

全面解读Java NIO工作原理(1)

春天的熊:

本文简介: JDK 1.4 中引入的新输入输出 (NIO) 库在标准 Java 代码中提供了高速的、面向块的 I/O。本实用教程从高级概念到底层的编程细节,非常详细地介绍了 NIO 库。您将学到诸如缓冲区和通道这样的关键 I/O 元素的知识,并考察更新后的库中的标准 I/O 是如何工作的。您还将了解只能通过 NIO 来完成的工作,如异步 I/O 和直接缓冲区。

◆  输入/输出:概念性描述

I/O 简介

I/O ? 或者输入/输出 ? 指的是计算机与外部世界或者一个程序与计算机的其余部分的之间的接口。它对于任何计算机系统都非常关键,因而所有 I/O 的主体实际上是内置在操作系统中的。单独的程序一般是让系统为它们完成大部分的工作。

在 Java 编程中,直到最近一直使用 流 的方式完成 I/O。所有 I/O 都被视为单个的字节的移动,通过一个称为 Stream 的对象一次移动一个字节。流 I/O 用于与外部世界接触。它也在内部使用,用于将对象转换为字节,然后再转换回对象。

NIO 与原来的 I/O 有同样的作用和目的,但是它使用不同的方式? 块 I/O。正如您将在本教程中学到的,块 I/O 的效率可以比流 I/O 高许多。

为什么要使用 NIO?

NIO 的创建目的是为了让 Java 程序员可以实现高速 I/O 而无需编写自定义的本机代码。NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度。

流与块的比较

原来的 I/O 库(在 java.io.*中) 与 NIO 最重要的区别是数据打包和传输的方式。正如前面提到的,原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。

面向流 的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。

一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

集成的 I/O

在 JDK 1.4 中原来的 I/O 包和 NIO 已经很好地集成了。 java.io.* 已经以 NIO 为基础重新实现了,所以现在它可以利用 NIO 的一些特性。例如, java.io.* 包中的一些类包含以块的形式读写数据的方法,这使得即使在更面向流的系统中,处理速度也会更快。

也可以用 NIO 库实现标准 I/O 功能。例如,可以容易地使用块 I/O 一次一个字节地移动数据。但是正如您会看到的,NIO 还提供了原 I/O 包中所没有的许多好处。

◆ 通道和缓冲区

概  述

通道 和 缓冲区 是 NIO 中的核心对象,几乎在每一个 I/O 操作中都要使用它们。

通道是对原 I/O 包中的流的模拟。到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象。一个 Buffer 实质上是一个容器对象。发送给一个通道的所有对象都必须首先放到缓冲区中;同样地,从通道中读取的任何数据都要读到缓冲区中。

在本节中,您会了解到 NIO 中通道和缓冲区是如何工作的。

什么是缓冲区?

Buffer 是一个对象, 它包含一些要写入或者刚读出的数据。 在 NIO 中加入 Buffer 对象,体现了新库与原 I/O 的一个重要区别。在面向流的 I/O 中,您将数据直接写入或者将数据直接读到 Stream 对象中。

在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,您都是将它放到缓冲区中。

缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不 仅仅 是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

缓冲区类型

最常用的缓冲区类型是 ByteBuffer。一个 ByteBuffer 可以在其底层字节数组上进行 get/set 操作(即字节的获取和设置)。

ByteBuffer 不是 NIO 中唯一的缓冲区类型。事实上,对于每一种基本 Java 类型都有一种缓冲区类型:

• ByteBuffer

• CharBuffer

• ShortBuffer

• IntBuffer

• LongBuffer

• FloatBuffer

• DoubleBuffer

每一个 Buffer 类都是 Buffer 接口的一个实例。 除了 ByteBuffer,每一个 Buffer 类都有完全一样的操作,只是它们所处理的数据类型不一样。因为大多数标准 I/O 操作都使用 ByteBuffer,所以它具有所有共享的缓冲区操作以及一些特有的操作。

现在您可以花一点时间运行 UseFloatBuffer.java,它包含了类型化的缓冲区的一个应用例子。

什么是通道?

Channel是一个对象,可以通过它读取和写入数据。拿 NIO 与原来的 I/O 做个比较,通道就像是流。

正如前面提到的,所有数据都通过 Buffer 对象来处理。您永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

通道类型

通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类), 而 通道 可以用于读、写或者同时用于读写。

因为它们是双向的,所以通道可以比流更好地反映底层操作系统的真实情况。特别是在 UNIX 模型中,底层操作系统通道是双向的。

◆ 从理论到实践:NIO 中的读和写

概  述

读和写是 I/O 的基本过程。从一个通道中读取很简单:只需创建一个缓冲区,然后让通道将数据读到这个缓冲区中。写入也相当简单:创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作。

在本节中,我们将学习有关在 Java 程序中读取和写入数据的一些知识。我们将回顾 NIO 的主要组件(缓冲区、通道和一些相关的方法),看看它们是如何交互以进行读写的。在接下来的几节中,我们将更详细地分析这其中的每个组件以及其交互。

从文件中读取

在我们第一个练习中,我们将从一个文件中读取一些数据。如果使用原来的 I/O,那么我们只需创建一个 FileInputStream 并从它那里读取。而在 NIO 中,情况稍有不同:我们首先从 FileInputStream 获取一个 FileInputStream 对象,然后使用这个通道来读取数据。

在 NIO 系统中,任何时候执行一个读操作,您都是从通道中读取,但是您不是 直接 从通道读取。因为所有数据最终都驻留在缓冲区中,所以您是从通道读到缓冲区中。

因此读取文件涉及三个步骤:(1) 从 FileInputStream 获取 Channel,(2) 创建 Buffer,(3) 将数据从 Channel 读到 Buffer 中。

现在,让我们看一下这个过程。

三个容易的步骤

第一步是获取通道。我们从 FileInputStream 获取通道:

  1. FileInputStream fin = new FileInputStream( "readandshow.txt" );  

  2. FileChannel fc = fin.getChannel(); 

下一步是创建缓冲区:

  1. ByteBuffer buffer = ByteBuffer.allocate( 1024 ); 

最后,需要将数据从通道读到缓冲区中,如下所示:

  1. fc.read( buffer ); 

您会注意到,我们不需要告诉通道要读 多少数据 到缓冲区中。每一个缓冲区都有复杂的内部统计机制,它会跟踪已经读了多少数据以及还有多少空间可以容纳更多的数据

写入文件

在 NIO 中写入文件类似于从文件中读取。首先从 FileOutputStream 获取一个通道:

  1. FileOutputStream fout = new FileOutputStream( "writesomebytes.txt" );  

  2. FileChannel fc = fout.getChannel(); 

下一步是创建一个缓冲区并在其中放入一些数据 - 在这里,数据将从一个名为 message 的数组中取出,这个数组包含字符串 "Some bytes" 的 ASCII 字节(本教程后面将会解释 buffer.flip() 和 buffer.put() 调用)。

  1. ByteBuffer buffer = ByteBuffer.allocate( 1024 );  

  2. for (int i=0; i<message.length; ++i) {  

  3.      buffer.put( message[i] );  

  4. }  

  5. buffer.flip(); 

最后一步是写入缓冲区中

  1. fc.write( buffer ); 

注意在这里同样不需要告诉通道要写入多数据。缓冲区的内部统计机制会跟踪它包含多少数据以及还有多少数据要写入。

读写结合

下面我们将看一下在结合读和写时会有什么情况。我们以一个名为 CopyFile.java 的简单程序作为这个练习的基础,它将一个文件的所有内容拷贝到另一个文件中。CopyFile.java 执行三个基本操作:首先创建一个 Buffer,然后从源文件中将数据读到这个缓冲区中,然后将缓冲区写入目标文件。这个程序不断重复 ― 读、写、读、写 ― 直到源文件结束。

CopyFile 程序让您看到我们如何检查操作的状态,以及如何使用 clear() 和 flip() 方法重设缓冲区,并准备缓冲区以便将新读取的数据写到另一个通道中。

运行 CopyFile 例子

因为缓冲区会跟踪它自己的数据,所以 CopyFile 程序的内部循环 (inner loop) 非常简单,如下所示:

  1. fcin.read( buffer );  

  2. fcout.write( buffer ); 

第一行将数据从输入通道 fcin 中读入缓冲区,第二行将这些数据写到输出通道 fcout 。

检查状态

下一步是检查拷贝何时完成。当没有更多的数据时,拷贝就算完成,并且可以在 read() 方法返回 -1 是判断这一点,如下所示:

  1. int r = fcin.read( buffer );  

  2. if (r==-1) {  

  3.      break;  

重设缓冲区

最后,在从输入通道读入缓冲区之前,我们调用 clear() 方法。同样,在将缓冲区写入输出通道之前,我们调用 flip() 方法,如下所示

  1. buffer.clear();int r = fcin.read( buffer );  

  2. if (r==-1) {  

  3.      break;  

  4. }  

  5. buffer.flip();  

  6. fcout.write( buffer ); 

clear() 方法重设缓冲区,使它可以接受读入的数据。 flip() 方法让缓冲区可以将新读入的数据写入另一个通道。

来自

jsf ajax(a4j)刷新页面或是提交不刷新组件

春天的熊:

页面的技术使用的是jsf,页面组成:左侧一个折叠菜单,右侧一个列表。

要求:点击菜单,右侧列表局部刷新。

 右侧菜单是静态页面标签+js写的。点击的时候,调用一个隐藏的<h:commandButton></h:commandButton>,button里面写上<a4j:support></a4j:support>,如下:

     <h:commandButtonvalue="" id="techlistRefresh" style="display:none;">
                <a4j:support action="#{techShowManageBean.findTechListByCateId}" event="onclick" immediate="false" reRender="tech_list_tb, tech_list_blank, tech_list_html" oncomplete="referscroll();" >
                </a4j:support>
            </h:commandButton>
调用该button的js代码:document.getElementById("form:techlistRefresh").click();

这样调用,页面刷新,但是这样刷新的是整个页面,你在页面onload的时候加个alert()就知道了,这样就不是我要的效果了。原因就是,该button产生的还是一个form的input的提交。

我把button改成了outputtext,如下:

       <h:outputText value="" id="techlistRefresh" style="display:none;">
                <a4j:support action="#{techShowManageBean.findTechListByCateId}" event="onclick" immediate="false" reRender="tech_list_tb, tech_list_blank, tech_list_html" oncomplete="referscroll();" >
                </a4j:support>
            </h:outputText>
该异步调用可以被触发,既我后台的techShowManageBean.findTechListByCateId已经成功调用,并且已经重新set了我要的组件。但是页面没有刷新城最新的数据。

 <a4j:support >已经 reRender="tech_list_tb, tech_list_blank, tech_list_html" 了我要的组件的ID,还是没有效果,修改如下,添加

<a4j:outputPanel id="test" layout="block" ajaxRendered="true">********</<a4j:outputPanel >

用这个标签把要刷新的元素包裹起来,形成一个作用域,有人叫他围堵。这个标签的参数如下:
            

styleClass

和HTML的class属性一样.

title

该组件产生的标记元素的提示文字(当鼠标移动到该组件上面出现的提示文字)

lang

产生该组件标记所使用的语言

layout

HTML layout用于产生 markup. 可能的取值是:   "block" 产生一个 HTML <div> 元素, "inline" 产生一个 HTML   <span> 元素, 和   "none"不产生 HTML 元素. 对于none 当子元素的rendered属性被设置为false时 这里有个小例外 ,这是创建一个具有相同id的空 <span> 元素 作为子元素,用来当作一个用于后序处理的占位符 

keepTransient

指定所有子组件为non-transient的标记.如果为true,所有的子组件将被设置为non-transient,并且在以保存的组件树中(keep in saved   components tree). For output in self-renderer region all content ( By   default, all content in <f:verbatim> tags and non-jsf elements in   facelets, marked as transient - since, self-rendered ajax regions don't plain   output for ajax processing ).

ajaxRendered

Defines, whether the content of this   component must be (or not) included in AJAX response created by parent AJAX Container,   even if it is not forced by reRender list of ajax action. Ignored if   component marked to output by Ajax action. default false

style

HTML: 应用在该组件上的CSS.

rendered

如果为false,该组件将不会被显示.

binding

组件绑定.

dir

文本方向.

id

每个组件都应该有个唯一的id. 如果没有指定的话,将会自动产生.

        


 这样再去尝试一下,嘿嘿,OK.

禁止图片保存 无法另存为

春天的熊:

方式一:

禁止出现图片左上角保存

<META HTTP-EQUIV="imagetoolbar" CONTENT="no">   

插入图片时加入galleryimg属性

<img galleryimg="no" src="">


禁止右键保存

把下面代码放在<head>和</head>之间

<SCRIPT LANGUAGE=java script>

function click() {

alert('对不起,您不能保存此图片,谢谢您的理解和支持!') }

function click1() {

if (event.button==2) {alert('对不起,您不能保存此图片,谢谢您的理解和支持!') }}

function CtrlKeyDown(){

if (event.ctrlKey) {alert('不当的拷贝将损害您的系统!') }}

document.onkeydown=CtrlKeyDown;

document.onselectstart=click;

document.onmousedown=click1;

</SCRIPT> 


方式二:

在页面中加入如下js代码:原理:屏蔽右键

<script>

function   document.onmousedown()

{

      if(event.button==2||event.button==3)

      {

            alert( "右健被禁止 ")

            return   false

        }


}

</script> 


屏蔽右键:<body oncontextmenu="window.event.returnValue=false"> 

JavaScript 仿LightBox内容显示效果

春天的熊:

来自:::JavaScript 仿LightBox内容显示效果


近来要做一个LightBox的效果(也有的叫Windows关机效果),不过不用那么复杂,能显示一个内容框就行了。
这个效果很久以前就做过,无非就是一个覆盖全屏的层,加一个内容显示的层。不过showbo教了我position:fixed这个新特性,决定重写一遍。

先看效果:

  

  

     

   

ps:“定位效果”的意思是屏幕滚动也能固定位置。

程序说明:

要实现一个简单的LightBox效果,主要有两个部分:覆盖层和高亮层。


【跨浏览器的固定定位】
 

首先要先说说这个东西position:fixed,它的作用是跨浏览器的固定定位。

摘自详解定位与定位应用
“如 让一个元素可能随着网页的滚动而不断改变自己在浏览器的位置。而现在我可以通过CSS中的一个定位属性来实现这样的一个效果,这个元素属性就是曾经不被支 持的position:fixed;  他的含义就是:固定定位。这个固定与绝对定位很像,唯一不同的是绝对定位是被固定在网页中的某一个位置,而固定定位则是固定在浏览器的视框位置。”

程序中很多地方利用了这个css,ie7、ff都支持这个css,但ie6不支持,程序中只能是在ie6模拟这个效果。 

【覆盖层】

覆盖层的作用是把焦点限制在高亮层上,原理是通过一个绝对定位的层(通常使用div),设置它的宽度和高度以致能覆盖整个屏幕(包括缩放和滚动浏览 器的情况下),再给它设置一个比较高的zIndex来层叠在原有内容之上(但要比高亮层小),这样用户就只能点到这个层之上的内容了。

如果初始化时没有提供覆盖层对象,程序中会自动创建:

this.Lay = $(this.options.Lay) || document.body.insertBefore(document.createElement("div"), document.body.childNodes[0]);


其中由于document.body.appendChild()导致IE已终止操作bug,所以用了insertBefore。。

【覆盖屏幕】

覆盖层的关键就是如何做到覆盖整个屏幕(锁定整个页面),支持position:fixed的话很简单:

with(this.Lay.style){ display = "none"; zIndex = this.zIndex; left = top = 0; position = "fixed"; width = height = "100%"; }


这样能把浏览器的视框覆盖了,其中使用了fixed样式,这里的意思是定位在浏览器的视框,并100%覆盖。
注意不要理解错为这个层覆盖了整个页面,它只是把浏览器可视的部分覆盖了来达到效果。

ie6不支持怎么办?有几个方法:
1,做一个覆盖视框的层,并在onscroll时相应移动,在onresize时重新设大小;
2,做一个覆盖视框的层,在样式上模拟fixed效果;
3,做一个层覆盖了整个页面的层,并在onresize时重新设大小;
方法1的缺点是滚动时很容易露出马脚,而且不好看;方法2的缺点是需要页面结构的改动和body样式的修改,绝对不是好的架构;而我用的是方法3,有更好的方法欢迎提出。

用这个方法只要把position设为absolute,并使用一个_resize方法来设置width和height即可:


this.Lay.style.position = "absolute";
this._resize = Bind(this, function(){
    this.Lay.style.width = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth) + "px";
    this.Lay.style.height = Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight) + "px";
});


要注意的是scrollHeight和clientHeight的区别(用Height容易测试),顺带还有offsetHeight,手册上的说明:
scrollHeight:Retrieves the scrolling height of the object.
clientHeight:Retrieves the height of the object including padding, but not including margin, border, or scroll bar.
offsetHeight:Retrieves the height of the object relative to the layout or coordinate parent, as specified by the offsetParent property. 

我的理解是:
scrollHeight是对象的内容的高度;
clientHeight是对象的可视部分高度;
offsetHeight是clientHeight加上border和滚动条本身高度。

举个例子吧,先说说clientHeight和offsetHeight的区别(在ie7中测试):

测的是外面的div,offsetHeight和clientHeight相差17(分别是83和100),这个相差的就是那个滚动条本身的高度。

再看看clientHeight和scrollHeight的区别(下面是模拟在ie中的情况):

  
  

可以看到clientHeight不受内容影响,都是83,即内容有没有超过对象高度都不受影响,但scrollHeight会受内容高度影响,而且从测试可以意识到:
当有滚动条时,覆盖层的高度应该取scrollHeight(内容高度);当没有滚动条时,覆盖层的高度应该取clientHeight(视框高度)。
而恰好两个情况都是取两者中比较大的值,所以就有了以下程序: 

Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight) + "px";


设宽度时是不包括滚动条部分的而documentElement一般也没有border,所以不需要offsetWidth。

上面可以看到我用的是documentElement而不是body,手册上是这样说的:
Retrieves a reference to the root node of the document.
意思是整个文档的根节点,其实就是html节点(body的上一级),注意这是在XHTML的标准下。上面可以看到我们取值的对象是整个文档而不只是body,所以这里用documentElement。

要注意的是在window的onresize事件中scrollWidth和clientWidth的值会产生变化,程序中在onresize中使用_resize方法重新设置宽度高度:

if(isIE6){ this._resize(); window.attachEvent("onresize", this._resize); }


【覆盖select】

自定义的层给select遮挡住是一个老问题了,不过可喜的是ie7和ff都已经支持select的zIndex,只要给层设定高的zIndex就能覆盖select了,可惜对于ie6这个问题还是需要解决。

覆盖select据我所知有两个比较好的方法:
1,显示层时,先隐藏select,关闭层时再重新显示;
2,用一个iframe作为层的底,来遮住select。

方法1应该都明白,方法2就是利用iframe可以覆盖select的特性,只要把一个iframe作为层的底部就可以覆盖下面的select了,程序中是这样使用的:

this.Lay.innerHTML = '<iframe style="position:absolute;top:0;left:0;width:100%;height:100%;filter:alpha(opacity=0);"></iframe>'


可以看出这个透明的iframe也以同样覆盖整个页面,如果是有内容显示的页面最好设置z-index:-1;确保iframe在层的底部。

个人觉得使用方法2比较好,但始终是改变了页面结构,有时会比较难控制,至于方法1就比较容易方便。

【高亮层】

高亮层就是用来显示内容的层,没什么看头,所以特意加了些效果在上面,吸引一下眼球。
有兴趣的话可以结合拖放效果渐变效果,做出更好的效果。

【固定定位】

这里“固定定位”的意思是当滚动滚动条时,高亮层依然保持在浏览器对应的位置上,把Fixed设为true就会开启这个效果。

同样对于支持fixed的浏览器很简单,只要把position设为fixed就行了,这个样式本来就是这样使用的,但可怜的ie6只能模拟了。

ie6模拟的原理是在onscroll事件中,不断根据滚动的距离修正top和left。
首先设置position为absolute,要注意的是position要在覆盖层显示之前显示,否则计算覆盖层宽高时会计算偏差(例如把页面撑大)。
再给onscroll事件添加定位函数_fixed来修正滚屏参数:

this.Fixed && window.attachEvent("onscroll", this._fixed);

定位函数_fixed是这样的:

this._fixed = Bind(this, function(){ this.Center ? this.SetCenter() : this.SetFixed(); });


可以看出在_fixed中,当设置了居中显示时会执行SetCenter程序(后面会说明),否则就执行SetFixed程序。
先说说SetFixed程序的原理,就是把当前scrollTop减去_top值(上一个scrollTop值)再加上当前的offsetTop,就得到要设置的top值了:


this.Box.style.top = document.documentElement.scrollTop - this._top + this.Box.offsetTop + "px";
this.Box.style.left = document.documentElement.scrollLeft - this._left + this.Box.offsetLeft + "px";
 
this._top = document.documentElement.scrollTop; this._left = document.documentElement.scrollLeft;


【居中显示】

“居中显示”的意思是高亮层位于视框左右上下居中的位置。
实现这个有两个方法:
1,视框宽度减去高亮层宽度的一半就是居中需要的left值;
2,先设置left值为50%,然后marginLeft设为负的高亮层宽度的一半。

方法1相对方法2需要多一个视框宽度,而且方法2在缩放浏览器时也能保持居中,明显方法2是更好,不过用margin会影响到left和top的计 算,必须注意(例如SetFix修正的地方)。这里我选择了方法2,还要注意offsetWidth和offsetHeight需要在高亮层显示之后才能 获取,所以定位程序需要放到高亮层显示之后:


this.Box.style.top = this.Box.style.left = "50%";
if(this.Fixed){
    this.Box.style.marginTop = - this.Box.offsetHeight / 2 + "px";
    this.Box.style.marginLeft = - this.Box.offsetWidth / 2 + "px";
}else{
    this.SetCenter();
}


其中如果不是固定定位,需要用SetCenter程序来修正滚屏参数,SetCenter程序是这样的:


this.Box.style.marginTop = document.documentElement.scrollTop - this.Box.offsetHeight / 2 + "px";
this.Box.style.marginLeft = document.documentElement.scrollLeft - this.Box.offsetWidth / 2 + "px";


【比较文档位置】

在ie6当不显示覆盖层时需要另外隐藏select,这里使用了“覆盖select”的方法1,值得留意的是这里加了个select是否在高亮层的判断:


this._select.length = 0;
Each(document.getElementsByTagName("select"), Bind(this, function(o){
    if(!Contains(this.Box, o)){ o.style.visibility = "hidden"; this._select.push(o); }
}))


其中Contains程序是这样的:

var Contains = function(a, b){
    return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}


作用是返回a里面是否包含b,里面用到了两个函数,分别是ie的contains和ff(dom)的compareDocumentPosition。
其中contains手册里是这样写的:
Checks whether the given element is contained within the object. 
意思是检测所给对象是否包含在指定对象里面。注意如果所给对象就是指定对象本身也会返回true,虽然这样不太合理。
而ff的compareDocumentPosition功能更强大。

参考Comparing Document Position看下表:
从NodeA.compareDocumentPosition(NodeB)返回的结果:
 

   Bits Number Meaning  000000 0 Elements are identical.  000001 1 The nodes are in different documents (or one is outside of a document).  000010 2 Node B precedes Node A.  000100 4 Node A precedes Node B.  001000 8 Node B contains Node A.  010000 16 Node A contains Node B.  100000 32 For private use by the browser.
从这里可以看出NodeA.compareDocumentPosition(NodeB) & 16的意思是当第5位数是“1”时才返回16,也就是只有NodeA包含NodeB时返回16(&是位与运算)。
ps:为什么不直接a.compareDocumentPosition(b) == 16,我也不清楚。


程序代码: 

Code



使用说明: 

首先要有一个高亮层:


<style>
.lightbox{width:300px;background:#FFFFFF;border:1px solid #ccc;line-height:25px; top:20%; left:20%;}
.lightbox dt{background:#f4f4f4; padding:5px;}
</style>

<dl id="idBox" class="lightbox">
  <dt id="idBoxHead"><b>LightBox</b> </dt>
  <dd>
    内容显示
    <br /><br />
    <input name="" type="button" value=" 关闭 " id="idBoxCancel" />
    <br /><br />
  </dd>
</dl>

至于覆盖层一般不需要另外设了,接着就可以实例化一个LightBox:

var box = new LightBox("idBox");


打开和关闭LightBox分别是Show()和Close()方法,

其中LightBox有下面几个属性:
属性:默认值//说明
Over:true,//是否显示覆盖层
Fixed:false,//是否固定定位
Center:false,//是否居中
onShow:function(){}//显示时执行

还有OverLay属性是覆盖层对象,它也有几个属性:
属性:默认值//说明
Lay:null,//覆盖层对象
Color:"#fff",//背景色
Opacity:50,//透明度(0-100)
zIndex:1000//层叠顺序

js与jquery获得页面大小、滚动条位置、元素位置

春天的熊:

//页面位置及窗口大小

function GetPageSize() {
var scrW, scrH; 
if(window.innerHeight && window.scrollMaxY) 
 {    // Mozilla    
scrW = window.innerWidth + window.scrollMaxX;    
scrH = window.innerHeight + window.scrollMaxY; 
 } 
else if(document.body.scrollHeight > document.body.offsetHeight)
 {    // all but IE Mac    
scrW = document.body.scrollWidth;    
scrH = document.body.scrollHeight; 
 } else if(document.body) 
 { // IE Mac    
scrW = document.body.offsetWidth;    
scrH = document.body.offsetHeight;
 } 
var winW, winH; 
if(window.innerHeight) 
 { // all except IE    
winW = window.innerWidth; 
winH = window.innerHeight; 
 } else if (document.documentElement && document.documentElement.clientHeight)
 {    // IE 6 Strict Mode    
winW = document.documentElement.clientWidth;     
winH = document.documentElement.clientHeight; 
 } else if (document.body) { // other    
winW = document.body.clientWidth;    
winH = document.body.clientHeight; 
 }    // for small pages with total size less then the viewport
var pageW = (scrW<winW) ? winW : scrW; 
var pageH = (scrH<winH) ? winH : scrH;    
return {PageW:pageW, PageH:pageH, WinW:winW, WinH:winH};
 
 };

//滚动条位置
function GetPageScroll() 
 { 
var x, y; if(window.pageYOffset) 
 {    // all except IE    
y = window.pageYOffset;    
x = window.pageXOffset; 
 } else if(document.documentElement && document.documentElement.scrollTop) 
 {    // IE 6 Strict    
y = document.documentElement.scrollTop;    
x = document.documentElement.scrollLeft; 
 } else if(document.body) {    // all other IE    
y = document.body.scrollTop;    
x = document.body.scrollLeft;   
 } 
return {X:x, Y:y};
 
 }

 
 
jquery

 
 获取浏览器显示区域的高度 : $(window).height(); 
 获取浏览器显示区域的宽度 :$(window).width(); 
 获取页面的文档高度 :$(document).height(); 
 获取页面的文档宽度 :$(document).width();
 
 获取滚动条到顶部的垂直高度 :$(document).scrollTop(); 
 获取滚动条到左边的垂直宽度 :$(document).scrollLeft(); 
 
 计算元素位置和偏移量 
offset方法是一个很有用的方法,它返回包装集中第一个元素的偏移信息。默认情况下是相对body的偏移信息。结果包含 top和left两个属性。 
offset(options, results) 
options.relativeTo  指定相对计 算偏移位置的祖先元素。这个元素应该是relative或absolute定位。省略则相对body。 
options.scroll  是否把 滚动条计算在内,默认TRUE
options.padding  是否把padding计算在内,默认false
options.margin   是否把margin计算在内,默认true 
options.border  是否把边框计算在内,默认true

tomcat实现SSL双向认证

春天的熊:

一、基础知识

 

 

Tomcat 简介

Tomcat是Apache Jakarta的子项目之一,作为一个优秀的开源web应用服务器,全面支持jsp1.2以及servlet2.3规范。因其技术先进、性能稳定,而且免费,因而深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的web应用服务器。

 

https(Secure Hypertext Transfer Protocol)安全超文本传输协议 简介

https是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层。

它是由Netscape开发并内置于其浏览器中,旨在达到在开放网络(Internet)上安全保密地传输信息的目的。

用于对数据进行压缩和解压操作,并返回网络上传送回的结果。HTTPS实际上应用了Netscape的完全套接字层(SSL)作为HTTP应用层的子层。(HTTPS使用端口443,而不是象HTTP那样使用端口80来和TCP/IP进行通信。)SSL使用40 位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。HTTPS和SSL支持使用X.509数字认证,如果需要的话用户可以确认发送者是谁。。

 

SSL (Secure Socket Layer)简介

为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。

 

 

(附)SSL工作原理
SSL协议使用不对称加密技术实现会话双方之间信息的安全传递。可以实现信息传递的保密性、完整性,并且会话双方能鉴别对方身份。不同于常用的http协议,我们在与网站建立SSL安全连接时使用https协议,即采用https://ip:port/的方式来访问。
当我们与一个网站建立https连接时,我们的浏览器与Web Server之间要经过一个握手的过程来完成身份鉴定与密钥交换,从而建立安全连接。具体过程如下: 
1. 用户浏览器将其SSL版本号、加密设置参数、与session有关的数据以及其它一些必要信息发送到服务器。 
2. 服务器将其SSL版本号、加密设置参数、与session有关的数据以及其它一些必要信息发送给浏览器,同时发给浏览器的还有服务器的证书。如果配置服务器的SSL需要验证用户身份,还要发出请求要求浏览器提供用户证书。 
3. 客户端检查服务器证书,如果检查失败,提示不能建立SSL连接。如果成功,那么继续。 
4. 客户端浏览器为本次会话生成pre-master secret,并将其用服务器公钥加密后发送给服务器。 
5. 如果服务器要求鉴别客户身份,客户端还要再对另外一些数据签名后并将其与客户端证书一起发送给服务器。 
6. 如果服务器要求鉴别客户身份,则检查签署客户证书的CA是否可信。如果不在信任列表中,结束本次会话。如果检查通过,服务器用自己的私钥解密收到的pre-master secret,并用它通过某些算法生成本次会话的master secret。 
7. 客户端与服务器均使用此master secret生成本次会话的会话密钥(对称密钥)。在双方SSL握手结束后传递任何消息均使用此会话密钥。这样做的主要原因是对称加密比非对称加密的运算量低一个数量级以上,能够显著提高双方会话时的运算速度。 
8. 客户端通知服务器此后发送的消息都使用这个会话密钥进行加密。并通知服务器客户端已经完成本次SSL握手。 
9. 服务器通知客户端此后发送的消息都使用这个会话密钥进行加密。并通知客户端服务器已经完成本次SSL握手。 
10. 本次握手过程结束,会话已经建立。双方使用同一个会话密钥分别对发送以及接受的信息进行加、解密。

 

二、tomcat实现SSL配置

 

 第一步 生成KeyStore

 

keytool -genkey -alias tomcat -keyalg RSA –keysize 1024 –validity 730 -keystore D:\server.keystore

生成.keystore文件在 用户目录下
输入keystore密码: ************
您的名字与姓氏是什么?
[Unknown]: localhost
您的组织单位名称是什么?
[Unknown]: dept
您的组织名称是什么?
[Unknown]: Inc
您所在的城市或区域名称是什么?
[Unknown]: bj
您所在的州或省份名称是什么?
[Unknown]: bj
该单位的两字母国家代码是什么
[Unknown]: CN
CN=localhost, OU= dept, O= Inc, L=bj, ST=bj, C=CN 正确吗?
[否]: Y

输入的主密码
(如果和 keystore 密码相同,按回车):*************

注意: localhost,是网站的域名或者ip,根据实际情况填写,比如 www.baidu.com  192.168.0.85  否则会出现证书上的名称无效,或者与站点名称不匹配。

 

建议:将生成的 server.keystore文件,放到%TOMCAT_HOME%或其子目录中(如:%TOMCAT_HOME%/conf)

(其实放哪里都一样,只是放到%TOMCAT_HOME%里面会方便一些)

 

第二步 修改server.xml

 

 修改%TOMCAT_HOME%/conf/server.xml

去掉下面SSL HTTP那个注释,修改为如下: 

Xml代码 

1          <Connector port="8443" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"    

2             SSLEnabled="true"  

3             maxThreads="150"  

4             scheme="https"  

5             secure="true"  

6             clientAuth="false"  

7             sslProtocol="TLS"    

8             keystoreFile="/conf/server.keystore"  

9             keystorePass="changeit" />  

10       <Connector port="8443" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"  

11          SSLEnabled="true"  

12          maxThreads="150"  

13          scheme="https"  

14          secure="true"  

15          clientAuth="false"  

16          sslProtocol="TLS"  

17          keystoreFile="/conf/server.keystore"  

18          keystorePass="changeit" />  

keystoreFile 是server.keystore放置的位置,keystorePass是密码 (默认密码是changeit)

 

第三步

重启Tomcat,访问地址https://ip:8443/

 

 

 

 

 

 

(附录:)tomcat的配置文件SSL部分详细说明
 

配置文件server.xml,SSL部分:

Xml代码 

19           <!– A "Connector" represents an endpoint by which requests are received   

20                and responses are returned. Documentation at :   

21                Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)   

22                Java AJP  Connector: /docs/config/ajp.html   

23                APR (HTTP/AJP) Connector: /docs/apr.html   

24                Define a non-SSL HTTP/1.1 Connector on port 8080   

25           –>  

26           <Connector  port="8443" maxHttpHeaderSize="8192"  

27               maxThreads="150"  

28               minSpareThreads="25"  

29               maxSpareThreads="75"  

30               enableLookups="false"  

31               disableUploadTimeout="true"  

32               acceptCount="100"  

33               scheme="https"  

34               secure="true"  

35               clientAuth="false"  

36               sslProtocol="TLS"  

37               keystoreFile="D:/Tomcat/conf/tomcatKey.keystore"  

38               keystorePass="changeit"  

39               algorithm="SunX509"  

40           />  

41           <!-- A "Connector" represents an endpoint by which requests are received  

42                and responses are returned. Documentation at :  

43                Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)  

44                Java AJP  Connector: /docs/config/ajp.html  

45                APR (HTTP/AJP) Connector: /docs/apr.html  

46                Define a non-SSL HTTP/1.1 Connector on port 8080  

47           -->  

48           <Connector  port="8443" maxHttpHeaderSize="8192"  

49               maxThreads="150"  

50               minSpareThreads="25"  

51               maxSpareThreads="75"  

52               enableLookups="false"  

53               disableUploadTimeout="true"  

54               acceptCount="100"  

55               scheme="https"  

56               secure="true"  

57               clientAuth="false"  

58               sslProtocol="TLS"  

59               keystoreFile="D:/Tomcat/conf/tomcatKey.keystore"  

60               keystorePass="changeit"  

61               algorithm="SunX509"  

62           />  

 

属性说明:

port:     这个port属性(默认值是8443)是 TCP/IP端口数码,Tomcat在其上监听安全连接。你可以把它更改成任何你愿意要的数值(如默认的https通信,数目是443)。不过,在许多操作系统中,要想在比1024小的端口数码上运行Tomcat,需要特殊的设置(它超出了这个文档资料的范围)。
 
redirectPort: 如果你在这里更改端口数值,你还必须更改在non-SSL连接器上的redirectPort 这个属性特定的值。这允许Tomcat自动地redirect那些试图访问有安全限制页面的用户,指明根据 Servlet 2.4 Specification要求,SSL是必需的
 
clientAuth: 如果你想要Tomcat要求所有的SSL客户在使用这个socket时出示用户认证书,把这个值设定为 true 。如果你想要Tomcat要求出示用户认证书,但是如果没有认证书也可以, 就把这个值设定为want 。
 
keystoreFile: 如果你产生的keystore文件不在Tomcat期望的默认地方(一个叫做.keystore 的文件在Tomcat运行的主目录),就添加这个属性。你可以指定一个绝对路径名称, 或者一个由$CATALINA_BASE环境变量而派生的相对路径名称。
 
keystorePass: 如果你使用一个不同的keystore(以及认证书)密码,而不是Tomcat期望的密码 (就是changeit),添加这个元素。
 
keystoreType: 如果使用一个PKCS12 keystore的话,就添加这个element。 有效的值是JKS 和 PKCS12
 
sslProtocol: 要在这个socket上被使用的加密/解密协定。如果你在使用Sun的JVM,我们不提倡更改 这个值。据报道,TLS协定的IBM's 1.4.1 实现与一些通用的浏览器不兼容。 如果是这样,就使用value SSL
 
ciphers: 这个socket允许使用的由逗号分隔开的加密密码列单。默认的情况下,任何可用的密码都允许被使用。
 
algorithm: 可用的X509算法。默认是Sun的实现( SunX509 )。 对于IBM JVMs,你应该使用值 IbmX509。对于其他卖主,查阅JVM文档资料来 找正确的值。
 
truststoreFile: 用来验证用户认证书的TrustStore文件。
 
truststorePass: 访问TrustStore的密码。默认值就是keystorePass的值。
 
truststoreType: 如果你在使用与KeyStore不同格式的TrustStore,添加这个元素。 合法的值是JKS和PKCS12
 
keyAlias: 如果 keystore 里面有多个 key,你可以为用这个选项为加入的 key 起一个名字。 如果没有指定名字,使用时 keystore 内的第一个 key 将会被使用

 

MyEclipse下Axis2插件的下载和安装

春天的熊:

为了用Myeclipse写Webservice~ 搞的我头都大啦~~ 装插件就烦到死~ 下面是我安装axis2的一点心得,和大家分享下~ 
 


1.       下载Myeclipse Axis2插件

http://archive.apache.org/dist/ws/axis2/tools/1_4_1/

下载axis2-eclipse-codegen-wizard.zip和axis2-eclipse-service-archiver-wizard.zip

http://labs.xiaonei.com/apache-mirror/ws/axis2/1_5/axis2-1.5-war.zip

 下载axis2-1.5-war.zip

2.解压插件($ECLIPSE_HOME表示你安装的myeclipse主目录)

       将上述两个插件都解压到$ECLIPSE_HOME\eclipse\plugins目录中;

Axis2_Codegen_Wizard_1.3.0 和Axis2_Service_Archiver_1.3.0

3.       在$ECLIPSE_HOME\eclipse\links目录下增加文件axis-eclipse-plugin.link

写入path= $ECLIPSE_HOME\eclipse\plugins (千万不要直接复制!!)

4.       重新启动myeclipse,在file->new->other中即可看到Axis2 Wizards,至此,axis2插件安装成功!!(GXGX)

5.       赶快试下用wsdl文件生成java源文件吧!是不是有错误出现?对~ 事情就是这样发展的。

6.       An error occurred while completing process-java.lang.reflect.InvocationTargetException的错误 。嗯不用急~ 有得解(不过我当初很惨弄了一个晚上)

解决方法如下:
step 1、从AXIS2的LIB库中复制"geronimo-stax-api_1.0_spec-1.0.1.jar"和

 "backport-util-concurrent-3.1.jar"文件到Axis2_Codegen_Wizard_1.3.0的lib目录中,同时修改Axis2_Codegen_Wizard_1.3.0下的plugin.xml文件,在<runtime>中添加

<library name="lib/geronimo-stax-api_1.0_spec-1.0.1.jar"> 

         <export name="*"/> 

</library> 

<library name="lib/backport-util-concurrent-3.1.jar"> 

        <export name="*"/>

</library> 

到plugin.xml文件中,保存! 

step 2、将 $workspace位置\.metadata\.plugins下目录 Axis2_Codegen_Wizard 删除

step 3、在命令行下切换至$ECLIPSE_HOME目录,然后执行:

eclipse –clear


你再试试~ 应该可以啦!!可以的话就留个言吧~~

PS:AXIS2可以下载axis2-1.4.1-bin.zip(里面有axis2所有的jar)

http://download.huihoo.com/apache/axis2/axis2-1.4.1-bin.zip

 

程序员的技能杀伤力:高薪背后的秘密

春天的熊:

在软件这个行业里有些规则是很有杀伤力的,比如很有名的摩尔定律。

  总结出这些规则的意义在于可以大致的照明方向,免得努力来努力去却走到了阴沟里。

  现实中种种利益纷争、观点之争看似纷繁,但在大时间尺度下来看却都是规则的实现手段。

  这就好比下围棋,每一手都要为谋得利益而计算,但结局却只有三种:赢、输或和,这就是规则的力量。

  民以食为天,所以第一定律从收入开始。

  程序员第一定律可以表述为:程序员的收入是技能复杂度和技能实现可能程度的函数。

  如果程序员的工资是S,社会平均水平的工资为A,程序员掌握的技能复杂度为C,实现程度为P。

  那么S = A x C x P。

  这里面的实现程度P不太好理解,额外做点说明。

  好比说有人在东北种了很多白菜,并获得了大丰收。与此同时广州也确实需要大白菜,按批发价他的这批白菜可以买10万。

  但关键是这个人找不到车皮,大白菜就只能在当地零售,这个时候这批大白菜就只能买1万块钱。

  这就是实现程度。

  大白菜内蕴了既定的价值,这种价值并不因为卖多少钱而改变,但这种价值能实现到什么程度则依赖于现实的可能性。

  这视乎很简单,但其实不是,很多人的一生就笼罩在这条定律下面,我们来基于这第一定律继续做些推导。

  推论1:越容易上手的技术,其内蕴价值越低。

  技能的复杂度C可以大致等价于掌握一门技术所需要的时间。

  各种集成的开发环境,各种容易学习的类库等使软件开发的门槛降得很低,这对整个产业是有利的,但对个体而言则是不利的。

  你花5个月可以学会的技术,其他人花5个月也可以学会,而5个月可以学会的东西所蕴含的价值一定是低的。

  与之相对5年才可以学会的东西,其内蕴价值一定是高的。

  内蕴价值低,所对应的收入必然偏低。

  为避免争议,我这里就不写技术的名字了,但大家可以从学习所需要的时间上来对各种技术做个分类。

  有时候很多人会有一种错觉,认为越热门的技术收益越好。

  这在大多时候是错的。

  越热的技术,越成熟的技术越是大众的,而越是大众的技术内蕴价值越低,所以收益越不好。

  热度能够帮助找到工作,但对技能复杂度C没有影响。

  推论2:单纯的涉猎广泛,没有专精,对收入的影响是负面的。

  各种技术的复杂度大概是呈指数增长的,越到后面前进一步越困难。

  好比说学会5门语言所需要的时间大多时候远比学精一门语言要短。

  在特定年纪尚,每样技术都会一点,对提高实现程度P略有帮助,但自身可替代性很强,对技能复杂度C的影响为负面。

  长期来看得不偿失。

  推论3:实现程度P越高,风险越大。

  有些技术领域很窄,上手也慢,实现程度却高,比如显卡驱动,打印驱动等。

  但这类工作好比在钢丝上跳舞:只要能实现自己的价值,那么回报大体不错,但最怕技术更迭。

  技术一换代,可能多年积累十去六七。

  总结来看,程序员要想获得不错的收入,第一要掌握稀缺的技术,即技术的内蕴价值要高;第二要找到实现稀缺技术的场景。

  《微软的秘密》一书中提到,微软里面优秀的程序员是可以拥有许多辆保时捷的。

  用上面两条做分解,就会发现原因很简单:

  一是这样的人是NT的核心开发人员,这类人员内蕴价值极高,处于稀缺状态;二是微软提供了实现这种技能内蕴价值的机会。

  这二者缺一不可。

  #根据大家的回复做了点修改把"实现可能性"替换成了"实现程度"。

收录各种猥琐的Java笔试/面试题目

春天的熊:

本文收录各种猥琐的Java笔试/面试题,一些比较容易忘记的,不定期更新。也希望大家在底下留言,贴出自己碰到或看到的各种猥琐笔试、面试题目。

J2EE基础部分

1、运算符优先级问题,下面代码的结果是多少?(笔试)

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.     public static void main(String[] args) {  

  5.         int k = 0;  

  6.         int ret = ++k + k++ + ++k + k;  

  7.         // ret的值为多少  

  8.         System.err.println(ret);  

  9.     }  

  10. }  

2、运算符问题,下面代码分别输出什么?(笔试)

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.     public static void main(String[] args) {  

  5.         int i1 = 10, i2 = 10;  

  6.         System.err.println("i1 + i2 = " + i1 + i2);  

  7.         System.err.println("i1 - i2 = " + i1 - i2);  

  8.         System.err.println("i1 * i2 = " + i1 * i2);  

  9.         System.err.println("i1 / i2 = " + i1 / i2);  

  10.     }  

  11. }  

3、下面代码的结果是什么?还是抛出异常?(笔试)

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.       

  5.     public void myMethod(String str) {  

  6.         System.err.println("string");  

  7.     }  

  8.       

  9.     public void myMethod(Object obj) {  

  10.         System.err.println("object");  

  11.     }  

  12.       

  13.     public static void main(String[] args) {  

  14.         Test t = new Test();  

  15.         t.myMethod(null);  

  16.     }  

  17. }  

4、假设今天是9月8日,下面代码输出什么?(笔试)

[java] view plaincopy

  1. package test;  

  2.   

  3. import java.util.Date;  

  4.   

  5. public class Test {  

  6.   

  7.     public static void main(String[] args) {  

  8.         Date date = new Date();  

  9.         System.err.println(date.getMonth() + " " + date.getDate());  

  10.     }  

  11. }  

5、下面代码的输出结果是什么?

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         double val = 11.5;  

  7.         System.err.println(Math.round(val));  

  8.         System.err.println(Math.floor(val));  

  9.         System.err.println(Math.ceil(val));  

  10.     }  

  11. }  

6、编程输出一个目录下的所有目录及文件名称,目录之间用tab。(笔试)

[java] view plaincopy

  1. package test;  

  2.   

  3. import java.io.File;  

  4.   

  5. public class Test {  

  6.   

  7.     public static void main(String[] args) {  

  8.         new Test().read("D:/test", "");  

  9.     }  

  10.       

  11.     public void read(String path, String tab) {  

  12.         File file = new File(path);  

  13.         File[] childFiles = file.listFiles();  

  14.         for (int i = 0; childFiles != null && i < childFiles.length; i++) {  

  15.             System.err.println(tab + childFiles[i].getName());  

  16.             if (file.isDirectory()) {  

  17.                 read(childFiles[i].getPath(), tab + "\t");  

  18.             }  

  19.         }  

  20.     }  

  21. }  

不要觉得很简单,最起码你要记得返回当前文件夹下的所有文件的方法是listFiles(),isDirectory别拼错了。

7、从键盘读入10个整数,然后从大到小输出。(笔试)

[java] view plaincopy

  1. package test;  

  2.   

  3. import java.util.Arrays;  

  4. import java.util.Comparator;  

  5. import java.util.Scanner;  

  6.   

  7. public class Test {  

  8.   

  9.     public static void main(String[] args) {  

  10.         Scanner in = new Scanner(System.in);  

  11.         // 注意这里的数组,不是int的  

  12.         Integer[] arr = new Integer[10];  

  13.         for (int i = 0; i < 10; i++) {  

  14.             arr[i] = in.nextInt();  

  15.         }  

  16.         Arrays.sort(arr, new Comparator<Integer>() {  

  17.             @Override  

  18.             public int compare(Integer o1, Integer o2) {  

  19.                 if (o1 > o2) return -1;  

  20.                 if (o1 < o2) return 1;  

  21.                 return 0;  

  22.             }  

  23.               

  24.         });  

  25.         System.err.println(Arrays.toString(arr));  

  26.     }  

  27.       

  28. }  

自己手写排序算法的可以无视此题,如果是Arrays.sort()的,请注意Comparator与Comparable接口的区别,别搞混了。

8、下面代码的结果是什么?

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test extends Base {  

  4.   

  5.     public static void main(String[] args) {  

  6.         Base b = new Test();  

  7.         b.method();  

  8.           

  9.         Test t = new Test();  

  10.         t.method();  

  11.     }  

  12.   

  13.     @Override  

  14.     public void method() {  

  15.         System.err.println("test");  

  16.     }  

  17.       

  18. }  

  19.   

  20. class Base {  

  21.     public void method() throws InterruptedException {  

  22.         System.err.println("base");  

  23.     }  

  24. }  

9、以下代码的结果是什么?

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test extends Base {  

  4.   

  5.     public static void main(String[] args) {  

  6.         new Test().method();  

  7.     }  

  8.   

  9.     public void method() {  

  10.         System.err.println(super.getClass().getName());  

  11.         System.err.println(this.getClass().getSuperclass().getName());  

  12.     }  

  13.       

  14. }  

  15.   

  16. class Base {  

  17. }  

10、true or false?

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         String str1 = new String("abc");  

  7.         String str2 = new String("abc");  

  8.         System.err.println(str1.equals(str2));  

  9.           

  10.         StringBuffer sb1 = new StringBuffer("abc");  

  11.         StringBuffer sb2 = new StringBuffer("abc");  

  12.         System.err.println(sb1.equals(sb2));  

  13.     }  

  14. }  

11、输出的结果是什么?

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         System.err.println(new Test().method1());  

  7.         System.err.println(new Test().method2());  

  8.     }  

  9.       

  10.     public int method1() {  

  11.         int x = 1;  

  12.         try {  

  13.             return x;  

  14.         } finally {  

  15.             ++x;  

  16.         }  

  17.     }  

  18.       

  19.     public int method2() {  

  20.         int x = 1;  

  21.         try {  

  22.             return x;  

  23.         } finally {  

  24.             return ++x;  

  25.         }  

  26.     }  

  27. }  

这样呢?输出什么

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         System.err.println(method());  

  7.     }  

  8.       

  9.     public static boolean method() {   

  10.          try {   

  11.             return true;   

  12.         } finally {   

  13.           return false;  

  14.         }   

  15.     }  

  16. }  

12、方法m1和m2有区别吗?什么区别

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.     }  

  7.   

  8.     public synchronized void m1() {  

  9.     }  

  10.   

  11.     public static synchronized void m2() {  

  12.     }  

  13. }  

13、true or false?理由

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         Integer i1 = 127;  

  7.         Integer i2 = 127;  

  8.         System.err.println(i1 == i2);  

  9.           

  10.         i1 = 128;  

  11.         i2 = 128;  

  12.         System.err.println(i1 == i2);  

  13.     }  

  14. }  

14、true or false?理由

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         String str1 = "a";  

  7.         String str2 = "a";  

  8.         String str3 = new String("a");  

  9.           

  10.         System.err.println(str1 == str2);  

  11.         System.err.println(str1 == str3);  

  12.         str3 = str3.intern();  

  13.         System.err.println(str1 == str3);  

  14.     }  

  15. }  

15、true or false?理由

[java] view plaincopy

  1. package test;  

  2.   

  3. public class Test {  

  4.   

  5.     public static void main(String[] args) {  

  6.         System.err.println(12 - 11.9 == 0.1);  

  7.     }  

  8. }  

16、以下代码输出是什么?

[java] view plaincopy

  1. package test;  

  2.   

  3. import java.math.BigInteger;  

  4.   

  5. public class Test {  

  6.   

  7.     public static void main(String[] args) {  

  8.         BigInteger one = new BigInteger("1");  

  9.         BigInteger two = new BigInteger("2");  

  10.         BigInteger three = new BigInteger("3");  

  11.         BigInteger sum = new BigInteger("0");  

  12.         sum.add(one);  

  13.         sum.add(two);  

  14.         sum.add(three);  

  15.         System.out.println(sum.toString());  

  16.     }  

  17. }  

17、输出的结果是什么?12345?根据单词排序?还是?

[java] view plaincopy

  1. package test;  

  2.   

  3. import java.util.HashSet;  

  4. import java.util.Iterator;  

  5. import java.util.Set;  

  6.   

  7. public class Test {  

  8.   

  9.     public static void main(String[] args) {  

  10.         Set<String> set = new HashSet<String>();  

  11.         set.add("one");  

  12.         set.add("two");  

  13.         set.add("three");  

  14.         set.add("four");  

  15.         set.add("five");  

  16.         for (Iterator<String> it = set.iterator(); it.hasNext();) {  

  17.             System.err.println(it.next());  

  18.         }  

  19.     }  

  20. }  

18、如何迭代Map容器,别所大概是......,手写个试试?