﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-badboy空间-文章分类-Java基础</title><link>http://www.blogjava.net/badboy/category/8016.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 05:06:07 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 05:06:07 GMT</pubDate><ttl>60</ttl><item><title>JSP学习心得</title><link>http://www.blogjava.net/badboy/articles/33205.html</link><dc:creator>badboy</dc:creator><author>badboy</author><pubDate>Thu, 02 Mar 2006 06:23:00 GMT</pubDate><guid>http://www.blogjava.net/badboy/articles/33205.html</guid><wfw:comment>http://www.blogjava.net/badboy/comments/33205.html</wfw:comment><comments>http://www.blogjava.net/badboy/articles/33205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/badboy/comments/commentRss/33205.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/badboy/services/trackbacks/33205.html</trackback:ping><description><![CDATA[<P>一、JSP工作原理</P>
<P>在一个JSP文件第一次被请求时，JSP引擎把该JSP文件转换成为一个servlet。而这个引擎本身也是一个servlet，在JSWDK或WEBLOGIC中，它就是JspServlet。 JSP引擎先把该JSP文件转换成一个Java源文件，在转换时如果发现jsp文件有任何语法错误，转换过程将中断，并向服务端和客户端输出出错信息；如果转换成功， JSP引擎用javac把该Java源文件编译成相应的class文件。然后创建一个该SERVLET的实例，该SERVLET的jspInit()方法被执行，jspInit()方法在servlet的生命周期中只被执行一次。然后jspService()方法被调用来处理客户端的请求。对每一个请求，JSP引擎创建一个新的线程来处理该请求。如果有多个客户端同时请求该JSP文件，则JSP引擎会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间.但应该注意多线程的编程限制，由于该servlet始终驻于内存，所以响应是非常快的。 如果.jsp文件被修改了，服务器将根据设置决定是否对该文件重新编译，如果需要重新编译，则将编译结果取代内存中的servlet，并继续上述处理过程。 虽然JSP效率很高，但在第一次调用时由于需要转换和编译而有一些轻微的延迟。 此外，如果在任何时候如果由于系统资源不足的原因，JSP引擎将以某种不确定的方式将servlet从内存中移去。当这种情况发生时jspDestroy()方法首先被调用, 然后servlet实例便被标记加入"垃圾收集"处理。 jspInit()及jspDestory()格式如下：可在jspInit()中进行一些初始化工作,如建立与数据库的连接，或建立网络连接，从配置文件中取一些参数等，在jspDestory()中释放相应的资源。 </P>&lt;%!<BR>public void jspInit()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("jspinit"); <BR>}<BR>&nbsp;<BR>%&gt;<BR>&nbsp;<BR>&lt;%!<BR>public void jspDestory()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("jspDestory"); <BR>}<BR>%&gt;<BR><!-----------------------  第二篇文章: 服务端的输出缓冲区  ----------------------->
<P>二、服务端的输出缓冲区</P>
<P>缺省情况下:服务端要输出到客户端的内容,不直接写到客户端,而是先写到一个输出缓冲区中.只有在下面三中情况下，才会把该缓冲区的内容输出到客户端上：<BR>
<OL>
<LI>该JSP网页已完成信息的输出 
<LI>输出缓冲区已满 
<LI>JSP中调用了out.flush()或response.flushbuffer() </LI></OL>输出缓冲区的大小可以用: <%@page buffer="none"|"nkb"%>或response.setBufferSize()设置,如下： 
<OL>
<LI>设置输出缓冲区的大小为1KB。 <%@page buffer="1kb"%>或response.setBufferSize(1); 
<LI>设置输出缓冲区的大小为0，即不缓冲。 <%@page buffer="none" %>或response.setBufferSize(0); </LI></OL>用response.getBufferSize()或out.getBufferSize()可取的输出缓冲区的大小,单位为字节. 用response.isCommitted()可检查看服务端是否已将数据输出到客户端. 如果返回值是TRUE则已将数据输出到客户端,是FALSE则还没有. 
<P></P><!-----------------------  第三篇文章: 服务端输出重定向  ------------------->
<P>三、服务端输出重定向</P>
<P>有以下3种方法可以做到输出重定向: 
<OL>
<LI>RESPONSE.SETREDERECT("URL") 该方法通过修改HTTP协议的HEADER部分,对浏览器下达重定向指令的,使浏览器显示重定向网页的内容. response.sendRedirect("http://localhost:7001/index.html"); 
<LI>下面的方法也能改变HTTP HEADER属性，它的原理和 1 是一样的. <BR>&lt;% <BR>response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); <BR>String newLocn="/index.html"; <BR>response.setHeader("Location",newLocn); <BR>% &gt; 
<LI>采用&lt;JSP:FORWORD&gt; 该方法是利用服务器端先将数据输出到缓冲区的机制,在把缓冲区的内容发送到客户端之前,原来的不发送,改为发送该页面的内容,如果在&lt;JSP:FORWORD&gt;之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么该语句将不起作用,这一点应该特别注意. 如下面的例子中(1)会输出index.html的内容，2 不会输出index.html的内容，而是输出out.println("@@@@@@@@@@@@@@@@@"); 中的内容,并且在服务端会抛出:java.lang.IllegalStateException: Response already committed 异常，但客户端没有任何错误输出。 </LI></OL>(1)<BR>&lt;%@page buffer="1kb"%&gt;<BR>&nbsp;<BR>&lt;%<BR>long i=0;<BR>&nbsp;<BR>for(i=0;i&lt;10;i++)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("@@@@@@@@@@@@@@@@@");<BR>}<BR>%&gt;<BR>&nbsp;<BR>&lt;jsp:forward page="./index.html" /&gt;<BR>&nbsp;<BR>&nbsp;<BR>(2)<BR>&lt;%@page buffer="1kb"%&gt;<BR>&nbsp;<BR>&lt;%<BR>long i=0;<BR>&nbsp;<BR>for(i=0;i&lt;600;i++)<BR>{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("@@@@@@@@@@@@@@@@@");<BR>}<BR>%&gt;<BR>&nbsp;<BR>
<P>说明：<BR>1. 方法(1),(2)可以使用变量表示重定向的地址;方法(3)不能使用变量表示重定向的地址。<BR>String add="./index.html"; <BR>&lt;jsp:forward page= add /&gt; <BR>无法重定向到index.html中去 <BR><BR>String add=http://localhost:7001/index.html <BR>response.sendRedirect(add); <BR>可以重定向到http://localhost:7001/index.html中去。 <BR><BR>2. 采用方法(1),(2)request中的变量(通过request.setAttribute()保存到request中的值)不能在新的页面中采用,采用方法(3)能. 综上,我们应该采用(1),(2)重定向比较好. </P>
<P></P><!-----------------------  第四篇文章: JSP中正确应用类  ------------------->
<P>四、JSP中正确应用类: </P>
<P>应该把类当成JAVA BEAN来用，不要在&lt;% %&gt; 中直接使用. 如下的代码(1)经过JSP引擎转化后会变为代码(2):<BR>从中可看出如果把一个类在JSP当成JAVA BEAN 使用,JSP会根据它的作用范围把它保存到相应的内部对象中.<BR>如作用范围为request,则把它保存到request对象中.并且只在第一次调用(对象的值为null)它时进行实例化. 而如果在&lt;% %&gt;中直接创建该类的一个对象,则每次调用JSP时,都要重新创建该对象,会影响性能. 
<P>代码(1)<BR>&lt;jsp:useBean id="test" scope="request" class="demo.com.testdemo"&gt;<BR>&lt;/jsp:useBean&gt;<BR>&nbsp;<BR>&lt;%<BR>test.print("this is use java bean");<BR>&nbsp;<BR>testdemo td= new testdemo();<BR>td.print("this is use new");<BR>%&gt;<BR>&nbsp;<BR>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">代码</SPAN><SPAN lang=EN-US>(2)<BR>demo.com.testdemo test = (demo.com.testdemo)request.getAttribute("test"); <BR>if (test == null) <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test = (demo.com.testdemo) java.beans.Beans.instantiate(getClass().getClassLoader(),"demo.com.testdemo"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception _beanException) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new weblogic.utils.NestedRuntimeException("cannot instantiate 'demo.com.testdemo'",_beanException); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.setAttribute("test", test); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.print("\r\n");<BR>} <BR>out.print("\r\n\r\n\r\n");<BR>test.print("this is use java bean"); <BR>&nbsp;<BR>testdemo td= new testdemo();<BR>td.print("this is use new");<BR><BR>&nbsp;<BR></SPAN></P>
<P></P><!-----------------------  第五篇文章: JSP的调试  ------------------->
<P><SPAN lang=EN-US>五、JSP的调试 </SPAN></P>
<P><SPAN lang=EN-US>JSP的调试比较麻烦,特别是当bean是在一个session中存在时，更加困难。得从好几个页面开始往里面走才行。通常是用out.println()或System.out.print()来打一大堆的信息来查问题。如果是用jbuilder做开发,它能直接调试JSP.不过更重要的是知道错误产生的原因及解决方法。下面对一些JSP编程常见错误进行分析。 </SPAN>
<P><SPAN lang=EN-US>(1).java.lang.NullPointerException异常<BR>一般是对一个为NULL值的变量进行操作引起的.如下面的操作就会抛出<BR>java.lang.NullPointerException<BR>String a = null; <BR>a.substring(0,1); <BR>&nbsp;<BR>为避免这种异常最好在对变量操作之前检查看它是否为NULL值.如:<BR>&lt;% String ss=Session.getAttribute("NAME") <BR>if isnull(ss) <BR>{ <BR><BR>} <BR>else <BR>{ <BR><BR>} <BR>%&gt; </SPAN></P>
<P><SPAN lang=EN-US>(2).JSP是用JAVA写的，所以它是大小写敏感的，用过其他编程语言的人最容易犯这个错误。另外在浏览器的地址栏中输入的访问JSP的地址也是区分大小写的.如http://localhost:7001/demo/t.jsp与http://localhost:7001/Demo/t.jsp是不一样的</SPAN></P>
<P><SPAN lang=EN-US>(3).在jsp中判断字符串要使用compareTo方法，不要用==，因为在java中String变量不是一个简单的变量而是一个类实例，不同的方法会得到 不同的结果，如下所示： </SPAN></P>
<OL><SPAN lang=EN-US>　　 </SPAN>
<LI><SPAN lang=EN-US><BR>　　String str1="ABCD"; <BR>　　String str2="ABCD"; (或 String str2="AB"+"CD"; ) <BR>　　if (str1==str2) <BR>　　 out.print("yes"); <BR>　　else <BR>　　 out.print("no"); <BR>　　结果是"yes"。 <BR>　 </SPAN>
<LI><SPAN lang=EN-US><BR>　　String str1,str2,str3; <BR>　　str1="ABCD"; <BR>　　str2="AB"; <BR>　　str3=str2+"CD"; <BR>　　if (str1==str3) <BR>　　 out.print("yes"); <BR>　　else <BR>　　 out.print("no"); <BR>　　结果是"no"。 <BR></SPAN>
<LI><SPAN lang=EN-US><BR>String str1=new String("ABCD"); <BR>　　String str2=new String("ABCD"); <BR>　　if (str1==str2) <BR>　　 out.print("yes"); <BR>　　else <BR>　　 out.print("no"); <BR>　　结果是"no"。 <BR></SPAN>
<LI><SPAN lang=EN-US><BR>String str1=new String("ABCD"); <BR>　　String str2=new String("ABCD"); <BR>　　if (str1.compareTo(str2)==0) <BR>　　 out.print("yes"); <BR>　　else <BR>　　 out.print("no"); <BR>　　结果是"yes"。 <BR></SPAN></LI></OL>
<P><SPAN lang=EN-US>(4)防止JSP或SERVLET中的输出被浏览器保存在缓冲区中:<BR>浏览器在默认情况下会把浏览过的网页保存在缓冲区中,在调试时,一般不希望这样.把下面的脚本加入程序中,就可防止JSP或SERVLET中的输出被浏览器保存在缓冲区中 <BR>&lt;% <BR>response.setHeader("Cache-Control","no-store"); //HTTP 1.1 <BR>response.setHeader("Pragma","no-cache"); //HTTP 1.0 <BR>response.setDateHeader ("Expires", 0); //prevents caching at the proxy server <BR>%&gt; <BR>在IE中也可通过设置实现：把/工具/INTERNET选项/常规/设置/的检察所存页面的较新版本,设为每次访问该页时都检查.</SPAN></P>
<P></P><!-----------------------  第六篇文章: COOKIE  ------------------->
<P><SPAN lang=EN-US>六、COOKIE</SPAN></P>
<P><SPAN lang=EN-US>HTTP COOKIE实质是服务端与在客户端之间传送的普通HTTP头,可保存也可不保存在客户的硬盘上.如果保存,每一个文件大小不超过4K的文本文件.多个COOKIE可保存到同一个文件中. 如果从编程角度来看,在JSP中COOKIE就是JAVA提供的一个类.常用的方法如下所表示，因为客户端可能不接受COOKIE，所以建议不用它，改用SESSION等其他方式。 <BR></SPAN></P>public class cookie <BR>{ <BR>public String getDomain() //返回该COOKIE的有效域 <BR>public int getMaxAge() //返回该COOKIE的有效期,单位为秒 <BR>public String getName() //返回该COOKIE的名称 <BR>public String getPath() //返回该COOKIE的有效路径 <BR>public boolean getSecure() //返回该COOKIE的安全设置 <BR>public String getValue() //返回该COOKIE的值 <BR>public void setDomain(java.lang.String pattern) //设置该COOKIE的有效域 <BR>public void setMaxAge(int expiry) //设置该COOKIE的有效期,单位为秒 <BR>public void setPath(java.lang.String uri) //设置该COOKIE的有效路径 <BR>public void setSecure(boolean flag) //设置该COOKIE的安全设置 <BR>public void setValue(java.lang.String newValue) //设置该COOKIE的值 <BR>} <BR>一个COOKIE包含以下五部分: <BR>
<OL>
<LI><SPAN lang=EN-US>NAME/VALUE对,设置该COOKIE的名字及它保存的值 </SPAN>
<LI><SPAN lang=EN-US>COOKIE通常和服务器相关,如果将域设为JAVA.SUN.COM,那么该COOKIE就和这个域相关,只对该网址起作用,当浏览该网址时,浏览器将把该COOKIE的内容发送给服务端,COOKIE是作为HTTP HEADER的一部分被发送的，如果没有设置域,那么COOKIE就只和创建该COOKIE的服务器相关. </SPAN>
<LI><SPAN lang=EN-US>路径用于指定服务器上可以使用该COOKIE的文件所在的路径,它只对该网址下的该路径下的应用起作用."/"表示服务器上所有目录都可以使用该COOKIE. </SPAN>
<LI><SPAN lang=EN-US>COOKIE都有一个有效期,有效期默认值为-1,这表示没有保存该COOKIE,当该浏览器退出时,该COOKIE立即失效. </SPAN>
<LI><SPAN lang=EN-US>安全选项true/false,如果设置为true,那么在服务端与在客户端之间传送该COOKIE的内容时,采用HTTPS协议. </SPAN></LI></OL>
<P><SPAN lang=EN-US>如何检查一个客户端是否支持COOKIE的方法: <BR>用下面的方法写一个COOKIE到客户端,并确认成功 <BR>try <BR>{ <BR>Cookie c = new Cookie("mycookie","COOKIE TEST"); <BR>response.addCookie(c); <BR>} <BR>catch(Exception e) <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(e); <BR>} <BR></SPAN></P>
<P><SPAN lang=EN-US>然后在一个新的JSP文件中:用下面的方法取客户端的COOKIE到cookies中, 如果cookies.length ==0,说明该客户端的浏览器不支持COOKIE <BR>try <BR>{ <BR>Cookie[] cookies = request.getCookies(); <BR>if(cookies.length ==0) <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("not support cookie"); <BR>} <BR>} <BR>catch(Exception e) <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(e); <BR>} <BR></SPAN></P>
<P></P><!-----------------------  第七篇文章: COOKIE  ------------------->
<P><SPAN lang=EN-US>七、JSP和SERVLET的区别:</SPAN></P>
<P><SPAN lang=EN-US>SUN首先发展出SERVLET，其功能比较强劲，体系设计也很先进，只是，它输出HTML语句还是采用了老的CGI方式，是一句一句输出，所以，编写和修改HTML非常不方便。 后来SUN推出了类似于ASP的JSP，把JAVA代码嵌套到HTML语句中，这样，就大大简化和方便了网页的设计和修改。ASP，PHP，JSP都是嵌套型的SCRIPT语言。 一个分布式系统应分为三层：表示层,业务逻辑层,数据存取层,在J2EE体系结构中,SERVLET用来写业务逻辑层是很强大的，但是对于写表示层就很不方便。JSP则主要是为了方便写表示层而设计的。ENTITY BEAN实现数据存取层，SESSION BEAN实现业务逻辑层。如果是简单的应用系统,可采用JSP+BEANS的结构进行设计,JSP中应该仅仅存放与表示层有关的东西，也就是说，只放输出HTML网页的部份。而所有的数据计算，数据分析，数据库联结处理，统统是属于业务逻辑层，应该放在JAVA BEANS中。通过JSP调用JAVA BEANS，实现两层的整合。 实际上，微软的DNA技术，简单说，就是ASP+COM/DCOM技术。与JSP+BEANS完全类似，所有的表示层由ASP完成，所有的业务逻辑由COM/DCOM完成。 为什么要采用这些组件技术呢？因为单纯的ASP/JSP语言是非常低效率执行的，如果出现大量用户点击，纯SCRIPT语言很快就到达了他的功能上限，而组件技术就能大幅度提高功能上限，加快执行速度。另外一方面，纯SCRIPT语言将表示层和业务逻辑层混在一起，造成修改不方便，并且代码不能重复利用，采用组件技术就只改组件就可以了。 对于复杂的应用，应该采用ENTITY BEAN实现数据存取层，SESSION BEAN实现业务逻辑层，用JSP来调用SESSION BEAN，由SESSION BEAN调用ENTITY BEAN。即采用JSP+EJB来构建一个复杂的分布式系统。它比JSP+BEAN具有更高的吞吐量，可靠性，安全性。综上所述，对简单应用，可采用JSP+BAEN，对复杂的应用系统，应采用JSP+EJB，SERVLET变的无足轻重。用JSP完全可替代它。</SPAN></P><img src ="http://www.blogjava.net/badboy/aggbug/33205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/badboy/" target="_blank">badboy</a> 2006-03-02 14:23 <a href="http://www.blogjava.net/badboy/articles/33205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写线程安全的JSP程序</title><link>http://www.blogjava.net/badboy/articles/33204.html</link><dc:creator>badboy</dc:creator><author>badboy</author><pubDate>Thu, 02 Mar 2006 06:22:00 GMT</pubDate><guid>http://www.blogjava.net/badboy/articles/33204.html</guid><wfw:comment>http://www.blogjava.net/badboy/comments/33204.html</wfw:comment><comments>http://www.blogjava.net/badboy/articles/33204.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/badboy/comments/commentRss/33204.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/badboy/services/trackbacks/33204.html</trackback:ping><description><![CDATA[<P>JSP默认是以多线程方式执行的，这是JSP与ASP，PHP，PERL等脚本语言不一样的地方，也是它的优势之一，但如果不注意多线程中的同步问题，会使所写的JSP程序有难以发现的错误。下面以一个例子说明JSP中的多线程问题及解决方法。 <!-----------------------  第一篇文章: JSP的中存在的多线程问题 ----------------------->
<P>一、JSP的中存在的多线程问题：</P>
<P>当客户端第一次请求某一个JSP文件时，服务端把该JSP编译成一个CLASS文件，并创建一个该类的实例，然后创建一个线程处理CLIENT端的请求。如果有多个客户端同时请求该JSP文件，则服务端会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间.对JSP中可能用的的变量说明如下:</P>
<OL>
<LI>实例变量<BR>实例变量是在堆中分配的,并被属于该实例的所有线程共享，所以不是线程安全的. 
<LI>JSP系统提供的8个类变量<BR>JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是线程安全的,APPLICATION在整个系统内被使用,所以不是线程安全的. 
<LI>局部变量<BR>局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以是线程安全的. 
<LI>静态类<BR>静态类不用被实例化,就可直接使用,也不是线程安全的. 
<LI>外部资源:<BR>在程序中可能会有多个线程或进程同时操作同一个资源(如:多个线程或进程同时对一个文件进行写操作).此时也要注意同步问题. </LI></OL><!-----------------------  第二篇文章: 下面的例子存在的多线程问题  ----------------------->
<P>二、下面的例子存在的多线程问题：</P>
<P>
<P>&lt;%@ page import="<BR>javax.naming.*,<BR>java.util.*,<BR>java.sql.*,<BR>weblogic.common.*<BR>" %&gt;<BR>&nbsp;<BR>
<P>&lt;%<BR>String name<BR>String product;<BR>long&nbsp; quantity;</P>
<P><BR>name=request.getParameter("name");<BR>product=request.getParameter("product");<BR>quantity=request.getParameter("quantity"); /*(1)*/<BR>savebuy();<BR>%&gt;</P>
<P><BR>&lt;%!<BR>public void&nbsp; savebuy()<BR>{<BR>&nbsp;&nbsp;&nbsp; /*进行数据库操作，把数据保存到表中*/<BR>&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Properties props = new Properties(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.put("user","scott");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.put("password","tiger");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.put("server","DEMO"); &nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Driver myDriver = (Driver) iver").newInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn = myDriver.connect("jdbc:weblogic:oracle", props);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt = conn.createStatement();<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String inssql = "insert into buy(empid, name, dept) values (?, ?, ?,?)";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt = conn.prepareStatement(inssql); <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;stmt.setString(1, name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt.setString(2, procuct);&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt.setInt(3, quantity);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt.execute();<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; catch (Exception e) <BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("SQLException was thrown: " + e.getMessage());<BR>&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp; finally //close connections and &nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(stmt != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(conn != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (SQLException sqle) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("SQLException was thrown: " + sqle.getMessage());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>%&gt;</P>上面的程序模拟网上购物中的一部分,把用户在浏览器中输入的用户名,购买的物品名称,数量保存到表BUY中。在savebuy()函数中用到了实例变量,所以它不是线程安全的.因为:程序中的每一条语句都不是原子操作,如name=request.getParameter("name");在执行是会对应多个机器指令,在任何时候都可能因系统调度而转入睡眠状态,让其他的线程继续执行.如果线程A在执行到(1)的时候转入睡眠状态,线程B开始执行并改变QUANTITY的值,那么当又到A执行时,它会从调用savebuy()函数开始执行，这样它保存到表中的QUANTITY是被线程B改过的值,那么线程A对应的用户所实际购买的数量与保持到表中的数据不一致.这是个很严重的问题. 
<P></P><!-----------------------  第三篇文章: 解决方法  ------------------->
<P>三、解决方法</P>
<OL>
<LI>采用单线程方式 <BR>在该JSP文件中加上: <%@ page isThreadSafe="false" %>,使它以单线程方式执行,这时，仍然只有一个实例，所有客户端的请求以串行方 式执行。这样会降低系统的性能. <BR>
<LI>对函数savebuy()加synchronized进行线程同步,该JSP仍然以多线程方式执行，但也会降低系统的性能<BR>public synchronized void&nbsp;savebuy() <BR>{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...... <BR>} <BR>
<LI>采用局部变量代替实例变量,函数savebuy()声明如下: <BR>因为在savebuy()中使用的是传给他的形参,是在堆栈中分配的,所以是线程安全的.<BR>public void savebuy(String name,String product, int quantity)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......<BR>}<BR><BR>调用方式改为: <BR>&lt;%<BR>String name<BR>String product;<BR>long quantity; 
<P>name=request.getParameter("name");<BR>product=request.getParameter("product");<BR>quantity=request.getParameter("quantity"); <BR>savebuy(name,product,quantity)<BR>%&gt;<BR></P>
<P>如果savebuy的参数很多,或这些数据要在很多地方用到,也可声明一个类,并用他做参数,如:</P>public class buyinfo<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String name;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String product;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long quantity;<BR>} 
<P>public void savebuy(buyinfo info)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......<BR>}</P>
<P>调用方式改为:<BR>&lt;%<BR>buyinfo userbuy = new buyinfo();</P>
<P>userbuy.name=request.getParameter("name");<BR>userbuy.product=request.getParameter("product");<BR>userbuy.quantity=request.getParameter("quantity"); <BR>savebuy(userbuy);<BR>%&gt;</P>
<P></P></LI></OL>
<P>所以最好是用3,因为1,2会降低系统的性能.<BR>多线程问题一般只有在在大并发量访问时，才有可能出现，并且很难重复出现，所以应在编程时就时刻注意。 <!--文章其他信息--></P><img src ="http://www.blogjava.net/badboy/aggbug/33204.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/badboy/" target="_blank">badboy</a> 2006-03-02 14:22 <a href="http://www.blogjava.net/badboy/articles/33204.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>改善Java Servlet运行性能</title><link>http://www.blogjava.net/badboy/articles/33196.html</link><dc:creator>badboy</dc:creator><author>badboy</author><pubDate>Thu, 02 Mar 2006 06:02:00 GMT</pubDate><guid>http://www.blogjava.net/badboy/articles/33196.html</guid><wfw:comment>http://www.blogjava.net/badboy/comments/33196.html</wfw:comment><comments>http://www.blogjava.net/badboy/articles/33196.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/badboy/comments/commentRss/33196.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/badboy/services/trackbacks/33196.html</trackback:ping><description><![CDATA[1. 避免字符串相加<BR>&nbsp;&nbsp; 这是个老生常谈的问题，但是在写servlet的时候，很多人在输出html时，<BR>这样写<BR>String a = "&lt;html&gt; ";<BR>String b = "&lt;/html&gt;";<BR>String c = a + b;<BR>应该使用StringBuffer，<BR>String a = "&lt;html&gt; ";<BR>String b = "&lt;/html&gt;";<BR>StringBuffer sb = new StringBuffer(a);<BR>sb.append(b);<BR>String c = sb.toString();<BR>最好使用StringBuffer的带参数构造来代替默认的构造函数，因为StringBuffer的append()方法返回<BR>一个StringBuffer实例，最好的写法是这样：<BR>StringBuffer sb = new StringBuffer(256);<BR>StringBuffer sb = new StringBuffer();<BR>sb.append("&lt;html&gt; ").append("&lt;/html&gt;");<BR>2.不要使用StringTokenizer<BR>&nbsp; 例如解析字符串<BR>&nbsp; import java.util.StringTokenizer;<BR>public class TestStringTokenizer<BR>{<BR>public static void main(String[] args)<BR>{<BR>String s = "a,b,c,d";<BR>StringTokenizer st = new StringTokenizer(s, ",");<BR>while (st.hasMoreTokens())<BR>{<BR>String token = st.nextToken();<BR>System.out.println(token);<BR>}<BR>}<BR>}<BR>可以使用String.indexOf()完成相同的功能<BR>public class TestIndexOf<BR>{<BR>public static void main(String[] args)<BR>{<BR>String s = "a,b,c,d";<BR>int begin = 0;<BR>int end = s.indexOf(",");<BR>while (true)<BR>{<BR>String token = null;<BR>if (end == -1)<BR>{<BR>token = s.substring(begin);<BR>}<BR>else<BR>{<BR>token = s.substring(begin, end);<BR>}<BR>System.out.println(token);<BR>// End if there are no more delimiters<BR>if (end == -1) break;<BR>begin = end + 1;<BR>end = s.indexOf(",", begin);<BR>}<BR>}<BR>}<BR>3.一般不要log输出<BR>&nbsp;&nbsp; 一般不要使用System.out.println()作为日志输出，最好使用log4j,更易于打开和关闭输出<BR>&nbsp;&nbsp;&nbsp;&nbsp; if(logger.isDebugEnabled()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("logging method handleRequestInternal()....");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>4.避免不必要同步<BR>&nbsp;&nbsp; servlet容器是个多线程的系统，java的关键字synchronized.避免某些情况的程序死锁，但是性能确实大大的降低了。<BR>除非特别必要，否则不要使用synchronized。<BR>5.尽量使用PreparedStatement<BR>多次使用相同的查询语句，PreparedStatement的效率很高，而且避免了sql注入。<BR>6.尽量使用连接池<BR>使用连接池，可以减少建立连接的时间，而且可以减轻数据库的连接压力。<BR>7.大量的使用cache<BR>对于经常查询相同数据的网站程序，使用cache是优化的不二法门，oscache是个廉价的方案。<BR>8.优化servlet容器<BR>&nbsp; 关闭容器的logging，加大他的File read cache size，加大容器的线程数，禁止servlet的重新加载。<BR>9.优化jvm，加大heap的初始化字节数，降低虚拟机的垃圾回收频率，<BR><img src ="http://www.blogjava.net/badboy/aggbug/33196.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/badboy/" target="_blank">badboy</a> 2006-03-02 14:02 <a href="http://www.blogjava.net/badboy/articles/33196.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面试试题</title><link>http://www.blogjava.net/badboy/articles/33192.html</link><dc:creator>badboy</dc:creator><author>badboy</author><pubDate>Thu, 02 Mar 2006 05:56:00 GMT</pubDate><guid>http://www.blogjava.net/badboy/articles/33192.html</guid><wfw:comment>http://www.blogjava.net/badboy/comments/33192.html</wfw:comment><comments>http://www.blogjava.net/badboy/articles/33192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/badboy/comments/commentRss/33192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/badboy/services/trackbacks/33192.html</trackback:ping><description><![CDATA[
		<p>很快就毕业了，之前去过面试两家公司都考到一些java，linux，SQL，智力等的题目，今天想做个总结把网上找到的面试题目整合一下，方便偶以后面试所用，也当复习一下基础。<br /><strong><font color="#000000">java基础题：</font></strong><br /><br /><font color="#ff0000">1、作用域public,private,protected,以及不写时的区别</font><br />答：区别如下： <br />作用域 当前类 同一package 子孙类 其他package <br />public √ √ √ √ <br />protected √ √ √ × <br />friendly √ √ × × <br />private √ × × × <br />不写时默认为friendly </p>
		<p>
				<font color="#ff0000">2、ArrayList和Vector的区别,HashMap和Hashtable的区别</font>
				<br />答：就ArrayList与Vector主要从二方面来说. <br />一.同步性:Vector是线程安全的，也就是说是同步的，而ArrayList是线程序不安全的，不是同步的 <br />二.数据增长:当需要增长时,Vector默认增长为原来一培，而ArrayList却是原来的一半 <br />就HashMap与HashTable主要从三方面来说。 <br />一.历史原因:Hashtable是基于陈旧的Dictionary类的，HashMap是Java 1.2引进的Map接口的一个实现 <br />二.同步性:Hashtable是线程安全的，也就是说是同步的，而HashMap是线程序不安全的，不是同步的 <br />三.值：只有HashMap可以让你将空值作为一个表的条目的key或value </p>
		<p>
				<font color="#ff0000">3、char型变量中能不能存贮一个中文汉字?为什么?</font>
				<br />答：是能够定义成为一个中文的，因为java中以unicode编码，一个char占16个字节，所以放一个中文是没问题的 </p>
		<p>
				<font color="#ff0000">4、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么? <br /></font>答：多线程有两种实现方法，分别是继承Thread类与实现Runnable接口 <br />同步的实现方面有两种，分别是synchronized,wait与notify </p>
		<p>
				<font color="#ff0000">5、继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么?</font>
				<br />答:父类： <br />package test; <br />public class FatherClass <br />{ <br />public FatherClass() <br />{ <br />System.out.println("FatherClass Create"); <br />} <br />} <br />子类: <br />package test; <br />import test.FatherClass; <br />public class ChildClass extends FatherClass <br />{ <br />public ChildClass() <br />{ <br />System.out.println("ChildClass Create"); <br />} <br />public static void main(String[] args) <br />{ <br />FatherClass fc = new FatherClass(); <br />ChildClass cc = new ChildClass(); <br />} <br />} <br />输出结果： <br />C:\&gt;java test.ChildClass <br />FatherClass Create <br />FatherClass Create <br />ChildClass Create </p>
		<p>
				<font color="#ff0000">6、内部类的实现方式?</font>
				<br />答：示例代码如下： <br />package test; <br />public class OuterClass <br />{ <br />private class InterClass <br />{ <br />public InterClass() <br />{ <br />System.out.println("InterClass Create"); <br />} <br />} <br />public OuterClass() <br />{ <br />InterClass ic = new InterClass(); <br />System.out.println("OuterClass Create"); <br />} <br />public static void main(String[] args) <br />{ <br />OuterClass oc = new OuterClass(); <br />} <br />} <br />输出结果: <br />C:\&gt;java test/OuterClass <br />InterClass Create <br />OuterClass Create <br />再一个例题： <br />public class OuterClass { <br />private double d1 = 1.0; <br />//insert code here <br />} <br />You need to insert an inner class declaration at line 3. Which two inner class declarations are </p>
		<p>valid?(Choose two.) <br />A. class InnerOne{ <br />public static double methoda() {return d1;} <br />} <br />B. public class InnerOne{ <br />static double methoda() {return d1;} <br />} <br />C. private class InnerOne{ <br />double methoda() {return d1;} <br />} <br />D. static class InnerOne{ <br />protected double methoda() {return d1;} <br />} <br />E. abstract class InnerOne{ <br />public abstract double methoda(); <br />} <br />说明如下： <br />一.静态内部类可以有静态成员，而非静态内部类则不能有静态成员。 故 A、B 错 <br />二.静态内部类的非静态成员可以访问外部类的静态变量，而不可访问外部类的非静态变量；return d1 出错。 </p>
		<p>故 D 错 <br />三.非静态内部类的非静态成员可以访问外部类的非静态变量。 故 C 正确 <br />四.答案为C、E </p>
		<p>
				<font color="#ff0000">7、垃圾回收机制,如何优化程序?</font>
				<br />希望大家补上，谢谢 </p>
		<p>
				<font color="#ff0000">8、float型float f=3.4是否正确?</font>
				<br />答:不正确。精度不准确,应该用强制类型转换，如下所示：float f=(float)3.4 </p>
		<p>
				<font color="#ff0000">9、介绍JAVA中的Collection FrameWork(包括如何写自己的数据结构)?</font>
				<br />答：Collection FrameWork如下： <br />Collection <br />├List <br />│├LinkedList <br />│├ArrayList <br />│└Vector <br />│　└Stack <br />└Set <br />Map <br />├Hashtable <br />├HashMap <br />└WeakHashMap <br />Collection是最基本的集合接口，一个Collection代表一组Object，即Collection的元素（Elements） <br />Map提供key到value的映射 </p>
		<p>
				<font color="#ff0000">10、Java中异常处理机制，事件机制？</font>
		</p>
		<p>
				<font color="#ff0000">11、JAVA中的多形与继承？</font>
				<br />希望大家补上，谢谢 </p>
		<p>
				<font color="#ff0000">12、抽象类与接口？</font>
				<br />答：抽象类与接口都用于抽象，但是抽象类(JAVA中)可以有自己的部分实现，而接口则完全是一个标识(同时有多重继承的功能)。 </p>
		<p>
				<font color="#ff0000">13、Java 的通信编程，编程题(或问答)，用JAVA SOCKET编程，读服务器几个字符，再写入本地显示</font>？ <br />答:Server端程序: <br />package test; <br />import java.net.*; <br />import java.io.*; </p>
		<p>public class Server <br />{ <br />private ServerSocket ss; <br />private Socket socket; <br />private BufferedReader in; <br />private PrintWriter out; <br />public Server() <br />{ <br />try <br />{ <br />ss=new ServerSocket(10000); <br />while(true) <br />{ <br />socket = ss.accept(); <br />String RemoteIP = socket.getInetAddress().getHostAddress(); <br />String RemotePort = ":"+socket.getLocalPort(); <br />System.out.println("A client come in!IP:"+RemoteIP+RemotePort); <br />in = new BufferedReader(new </p>
		<p>InputStreamReader(socket.getInputStream())); <br />String line = in.readLine(); <br />System.out.println("Cleint send is :" + line); <br />out = new PrintWriter(socket.getOutputStream(),true); <br />out.println("Your Message Received!"); <br />out.close(); <br />in.close(); <br />socket.close(); <br />} <br />}catch (IOException e) <br />{ <br />out.println("wrong"); <br />} <br />} <br />public static void main(String[] args) <br />{ <br />new Server(); <br />} <br />}; <br />Client端程序: <br />package test; <br />import java.io.*; <br />import java.net.*; </p>
		<p>public class Client <br />{ <br />Socket socket; <br />BufferedReader in; <br />PrintWriter out; <br />public Client() <br />{ <br />try <br />{ <br />System.out.println("Try to Connect to 127.0.0.1:10000"); <br />socket = new Socket("127.0.0.1",10000); <br />System.out.println("The Server Connected!"); <br />System.out.println("Please enter some Character:"); <br />BufferedReader line = new BufferedReader(new </p>
		<p>InputStreamReader(System.in)); <br />out = new PrintWriter(socket.getOutputStream(),true); <br />out.println(line.readLine()); <br />in = new BufferedReader(new InputStreamReader(socket.getInputStream())); <br />System.out.println(in.readLine()); <br />out.close(); <br />in.close(); <br />socket.close(); <br />}catch(IOException e) <br />{ <br />out.println("Wrong"); <br />} <br />} <br />public static void main(String[] args) <br />{ <br />new Client(); <br />} <br />}; </p>
		<p>
				<font color="#ff0000">14、用JAVA实现一种排序，JAVA类实现序列化的方法(二种)？ 如在COLLECTION框架中，实现比较要实现什么样的接口？</font>
				<br />答:用插入法进行排序代码如下 <br />package test; <br />import java.util.*; <br />class InsertSort <br />{ <br />ArrayList al; <br />public InsertSort(int num,int mod) <br />{ <br />al = new ArrayList(num); <br />Random rand = new Random(); <br />System.out.println("The ArrayList Sort Before:"); <br />for (int i=0;i&lt;num ;i++ ) <br />{ <br />al.add(new Integer(Math.abs(rand.nextInt()) % mod + 1)); <br />System.out.println("al["+i+"]="+al.get(i)); <br />} <br />} <br />public void SortIt() <br />{ <br />Integer tempInt; <br />int MaxSize=1; <br />for(int i=1;i&lt;al.size();i++) <br />{ <br />tempInt = (Integer)al.remove(i); <br />if(tempInt.intValue()&gt;=((Integer)al.get(MaxSize-1)).intValue()) <br />{ <br />al.add(MaxSize,tempInt); <br />MaxSize++; <br />System.out.println(al.toString()); <br />} else { <br />for (int j=0;j&lt;MaxSize ;j++ ) <br />{ <br />if </p>
		<p>(((Integer)al.get(j)).intValue()&gt;=tempInt.intValue()) <br />{ <br />al.add(j,tempInt); <br />MaxSize++; <br />System.out.println(al.toString()); <br />break; <br />} <br />} <br />} <br />} <br />System.out.println("The ArrayList Sort After:"); <br />for(int i=0;i&lt;al.size();i++) <br />{ <br />System.out.println("al["+i+"]="+al.get(i)); <br />} <br />} <br />public static void main(String[] args) <br />{ <br />InsertSort is = new InsertSort(10,100); <br />is.SortIt(); <br />} <br />} <br />JAVA类实现序例化的方法是实现java.io.Serializable接口 <br />Collection框架中实现比较要实现Comparable 接口和 Comparator 接口 </p>
		<p>
				<font color="#ff0000">15、编程：编写一个截取字符串的函数，输入为一个字符串和字节数，输出为按字节截取的字符串。 但是要保证汉字不被截半个，如“我ABC”4，应该截为“我AB”，输入“我ABC汉DEF”，6，应该输出为“我ABC”而不是“我ABC+汉的半个”。</font>
				<br />答：代码如下： <br />package test; </p>
		<p>class SplitString <br />{ <br />String SplitStr; <br />int SplitByte; <br />public SplitString(String str,int bytes) <br />{ <br />SplitStr=str; <br />SplitByte=bytes; <br />System.out.println("The String is:′"+SplitStr+"′;SplitBytes="+SplitByte); <br />} <br />public void SplitIt() <br />{ <br />int loopCount; </p>
		<p>loopCount=(SplitStr.length()%SplitByte==0)?(SplitStr.length()/SplitByte):(SplitStr.length()/Split </p>
		<p>Byte+1); <br />System.out.println("Will Split into "+loopCount); <br />for (int i=1;i&lt;=loopCount ;i++ ) <br />{ <br />if (i==loopCount){ </p>
		<p>System.out.println(SplitStr.substring((i-1)*SplitByte,SplitStr.length())); <br />} else { </p>
		<p>System.out.println(SplitStr.substring((i-1)*SplitByte,(i*SplitByte))); <br /></p>
		<p>
				<strong>Jsp方面</strong>
		</p>
		<p>
				<font color="#ff0000">1、jsp有哪些内置对象?作用分别是什么?</font>
				<br />答:JSP共有以下9种基本内置组件（可与ASP的6种内部组件相对应）： <br />　request 用户端请求，此请求会包含来自GET/POST请求的参数 <br />response 网页传回用户端的回应 <br />pageContext 网页的属性是在这里管理 <br />session 与请求有关的会话期 <br />application servlet 正在执行的内容 <br />out 用来传送回应的输出 <br />config servlet的构架部件 <br />page JSP网页本身 <br />exception 针对错误网页，未捕捉的例外 </p>
		<p>
				<font color="#ff0000">2、jsp有哪些动作?作用分别是什么? <br /></font>答:JSP共有以下6种基本动作 <br />jsp:include：在页面被请求的时候引入一个文件。 <br />jsp:useBean：寻找或者实例化一个<font color="#000000">JavaBean</font>。 <br />jsp:setProperty：设置JavaBean的属性。 <br />jsp:getProperty：输出某个JavaBean的属性。 <br />jsp:forward：把请求转到一个新的页面。 <br />jsp:plugin：根据浏览器类型为Java插件生成OBJECT或EMBED标记 </p>
		<p>
				<font color="#ff0000">3、JSP中动态INCLUDE与静态INCLUDE的区别？</font>
				<br />答：动态INCLUDE用jsp:include动作实现 <br />&lt;jsp:include page="included.jsp" flush="true" /&gt;它总是会检查所含文件中的变化，适合用于包含动态页面，并且可以带参数 <br />静态INCLUDE用include伪码实现,定不会检查所含文件的变化，适用于包含静态页面 <br />&lt;%@ include file="included.htm" %&gt; </p>
		<p>
				<font color="#ff0000">4、两种跳转方式分别是什么?有什么区别?</font>
				<br />答：有两种，分别为： <br />&lt;jsp:include page="included.jsp" flush="true"&gt; <br />&lt;jsp:forward page= "nextpage.jsp"/&gt; <br />前者页面不会转向include所指的页面，只是显示该页的结果，主页面还是原来的页面。执行完后还会回来，相当于函数调用。并且可以带参数.后者完全转向新页面，不会再回来。相当于go to 语句。 <br /><br /><font color="#000000"><strong>Servlet方面</strong></font> <br /><br /><font color="#ff0000">1、说一说Servlet的生命周期? <br /></font>答:servlet有良好的生存期的定义，包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。 <br /><br />2、Servlet版本间(忘了问的是哪两个版本了)的不同? <br />希望大家补上，谢谢 <br /><br /><font color="#ff0000">3、JAVA SERVLET API中forward() 与redirect()的区别？</font> <br />答:前者仅是容器中控制权的转向，在客户端浏览器地址栏中不会显示出转向后的地址；后者则是完全的跳转，浏览器将会得到跳转的地址，并重新发送请求链接。这样，从浏览器的地址栏中可以看到跳转后的链接地址。所以，前者更加高效，在前者可以满足需要时，尽量使用forward()方法，并且，这样也有助于隐藏实际的链接。在有些情况下，比如，需要跳转到一个其它服务器上的资源，则必须使用sendRedirect()方法。 <br /><br /><font color="#ff0000">4、Servlet的基本架构</font> <br />public class ServletName extends HttpServlet { <br />public void doPost(HttpServletRequest request, HttpServletResponse response) throws <br />ServletException, IOException { <br />} <br />public void doGet(HttpServletRequest request, HttpServletResponse response) throws <br />ServletException, IOException { <br />} <br />} <br /><br /><strong><font color="#000000">Xml方面</font></strong></p>
		<p>
				<font color="#ff0000">1、xml有哪些解析技术?区别是什么?</font>
				<br />答:有DOM,SAX,STAX等 <br />DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的，这种结构占用的内存较多，而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件，不需要一次全部装载整个文件。当遇到像文件开头，文档结束，或者标签开头与标签结束时，它会触发一个事件，用户通过在其回调事件中写入处理代码来处理XML文件，适合对XML的顺序访问 <br />STAX:Streaming API for XML (StAX) </p>
		<p>
				<font color="#ff0000">2、你在项目中用到了xml技术的哪些方面?如何实现的?</font>
				<br />答:用到了数据存贮，信息配置两方面。在做数据交换平台时，将不能数据源的数据组装成XML文件，然后将XML文件压缩打包加密后通过网络传送给接收者，接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时，利用XML可以很方便的进行，软件的各种配置参数都存贮在XML文件中。 <br /><br /><strong>设计模式方面</strong></p>
		<p>
				<font color="#ff0000">1、开发中都用到了那些设计模式?用在什么场合?</font>
				<br />答：每个模式都描述了一个在我们的环境中不断出现的问题，然后描述了该问题的解决方案的核心。通过这种方式，你可以无数次地使用那些已有的解决方案，无需在重复相同的工作。主要用到了MVC的设计模式。用来开发JSP/Servlet或者J2EE的相关应用。简单工厂模式等。 <br /><br /><font color="#ff0000">2、UML方面 有哪五种图视</font> <br />答：标准建模语言UML。用例图,静态图(包括类图、对象图和包图),行为图,交互图(顺序图,合作图),实现图, <br /><br /><strong>JavaScript方面</strong></p>
		<p>
				<font color="#ff0000">1、如何校验数字型?</font>
				<br />var re=/^\d{1,8}$|\.\d{1,2}$/; <br />var str=document.form1.all(i).value; <br />var r=str.match(re); <br />if (r==null) <br />{ <br />sign=-4; <br />break; <br />} <br />else{ <br />document.form1.all(i).value=parseFloat(str); <br />} <br /><br /><strong>LINUX方面</strong></p>
		<p>
				<font color="#ff0000">1、LINUX下线程，GDI类的解释。</font>
				<br />答：LINUX实现的就是基于核心轻量级进程的"一对一"线程模型，一个线程实体对应一个核心轻量级进程，而线程之间的管理在核外函数库中实现。 <br />GDI类为图像设备编程接口类库。<br /><br /><strong>变态试题集<br /></strong><br />1。变态指数 4<br />int x=4;<br />System.out.println("value is " +((x&gt;4)?99.9:9));<br />答案 9.0 问号表达式的后面两个条件有要求,因为前面的是float,所以后面转为float.<br /><font color="#f70968">估计出题者才通过SCJP的考试。</font><br />2.变态指数 5<br />public class Test { </p>
		<p>public static void main(String[] args) {<br />int x = 4;<br />java.util.Date date = (x &gt; 4) ? new A() : new B();<br />}<br />}</p>
		<p>class A extends java.util.Date {}<br />class B extends java.util.Date {} <br />答案 编译不通过,<br /><font color="#f70968">不知道出题人的意图</font><br />3.变态指数 6<br />String s=new String("abc");<br />创建了几个Ｓtring对象？<br />答案 2个 <br /><font color="#f70968">这样的公司最好不要去</font></p>
		<p>4.变态指数 7<br />const是不是java的关键字？<br />答案 const是java的关键字,但是java没有实现它 <br /><font color="#f70968">一般人绝对用不到它</font><br /><br />5.变态指数 8<br />，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? <br />答案 1错2对，1因为向上转型了,最后导致类型不匹配错误 ,<br />因为s1的+=是一个操作符，能够自动转型,<br />short s1 = 1;<br />s1 = s1+1;这句话在c++里面可以的 <br /><font color="#f70968">不知道出题人的意图</font><br />6.变态指数 9<br />上海贝尔的面试题:你认为效率最高的方法,实现从1加到100.<br />答案 1-100的累加相当于加50次101，这样循环次数从100次降为50次：<br />int sun = 0<br />for(int i = 1,j = 100 ; i &lt;= 50 ; i++,j--){<br />    sun = sun + i + j;<br />}  <br /><font color="#f70938">出题人脑子有问题,直接(1+100)*50不是最快...其实类似这样的优化应该不是程序员考虑的范畴吧</font><br />7.变态指数 10<br /> System.out.println(5.0942*1000);<br />     System.out.println(5.0943*1000);<br />  System.out.println(5.0944*1000);的结果<br />答案 :5094.2 5094.299999999999 5094.400000000001 <br /><font color="#f70938">原理和浮点数的计算机表示方式有关 ,你不用上机,就答对了,你最好去微软,接替安德尔森.</font><br /></p>
<img src ="http://www.blogjava.net/badboy/aggbug/33192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/badboy/" target="_blank">badboy</a> 2006-03-02 13:56 <a href="http://www.blogjava.net/badboy/articles/33192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>string和stringbuffer区别</title><link>http://www.blogjava.net/badboy/articles/33190.html</link><dc:creator>badboy</dc:creator><author>badboy</author><pubDate>Thu, 02 Mar 2006 05:54:00 GMT</pubDate><guid>http://www.blogjava.net/badboy/articles/33190.html</guid><wfw:comment>http://www.blogjava.net/badboy/comments/33190.html</wfw:comment><comments>http://www.blogjava.net/badboy/articles/33190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/badboy/comments/commentRss/33190.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/badboy/services/trackbacks/33190.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<P>&nbsp;这是好友面试的一道题，其实我知道使用的区别，StringBuffer必须new出来，StringBuffer的append的效率比string的+=的效率高，<BR>其实发现还有很大的区别，看了看以前scjp的考题<BR>public class Test {<BR>&nbsp;&nbsp; public static void stringReplace (String text) {<BR>&nbsp;&nbsp; text = text.replace('j' , 'i'); <BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; public static void bufferReplace (StringBuffer text) {<BR>&nbsp;&nbsp; text = text.append("C"); <BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; public static void main (String args[]) { <BR>&nbsp;&nbsp;&nbsp; String textString = new String ("java"); <BR>&nbsp;&nbsp;&nbsp; StringBuffer textBuffer = new StringBuffer ("java"); <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; stringReplace (textString); <BR>&nbsp;&nbsp;&nbsp; bufferReplace (textBuffer); <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; System.out.println (textString + textBuffer); <BR>&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp; }<BR>答案是 javajavaC<BR>这是Java参数传递(by value)造成的,是不可变的(immutable).,例如 基本类型，String传值，复制了值传递过去；可变的（Object）传值，复制了引用传递过去。 <BR></P>
<P>而题目中第七行text = text.append (“C”)，append方法会改变text中的值<BR>而这个text与main中的textBuffer是指向同一个对象，所以对应的输出是javac。<BR><FONT color=#ee3d11>string的值永远不会改变！</FONT></P>
<P><BR>String a = "a";//假设a指向地址0x0001，<BR>a = "b";//重新负值后a指向地址0x0002，但0x0001地址中保存的"a"依旧存在，但已经不再是a所指向的。<BR>从表面上看String类型的对象改变了值，但事实是他不能改变值，只能改变指向的地址</P>
<P><BR>StringBuffer则不同，直接改变指向的地址中保留的值<BR>还有<BR>StringBuffer s1 = new StringBuffer("a");<BR>StringBuffer s2 = new StringBuffer("a");<BR>s1.equals(s2)//为什么是false</P>
<P>String s1 = new String("a");<BR>String s2 = new String("a");<BR>s1.equals(s2)//为什么是true<BR>StringBuffer类中没有重新定义equals这个方法，因此这个方法就来自Object类，<BR>而Object类中的equals方法是用来比较地址的，所以等于false.</P>
<P>String类中重新定义了equals这个方法，而且比较的是值，而不是地址。所以会是<BR>true。<BR>对于这样能不能面试出真正的水平，感到怀疑。</P></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/badboy/aggbug/33190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/badboy/" target="_blank">badboy</a> 2006-03-02 13:54 <a href="http://www.blogjava.net/badboy/articles/33190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>