第一次面试java笔试题目

(1).String 和StringBuffer的区别(网上找的答案)

   答:

1.

         String

          为不可变对象,一旦被创建,就不能修改它的值.

          对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
          String 是final类,即不能被继承.

         StringBuffer

          是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象
          它只能通过构造函数来建立,
          StringBuffer sb = new StringBuffer();
          note:不能通过赋值符号对他进行赋值. 
          sb = "welcome to here!";//error
          对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法.
          sb.append("hello");

2.字符串连接操作中StringBuffer的效率要比String高:

         String str = new String("welcome to ");
         str += "here";
         的处理步骤实际上是通过建立一个StringBuffer,然后调用append(),最后
         再将StringBuffer toSting();
         这样的话String的连接操作就比StringBuffer多出了一些附加操作,当然效率上要打折扣.

         并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.
         这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的. 

         

看看以下代码:
将26个英文字母重复加了5000次,

  1.         String tempstr = "abcdefghijklmnopqrstuvwxyz";
  2.         int times = 5000;
  3.         long lstart1 = System.currentTimeMillis();
  4.         String str = "";
  5.         for (int i = 0; i < times; i++) {
  6.             str += tempstr;
  7.         }
  8.         long lend1 = System.currentTimeMillis();
  9.         long time = (lend1 - lstart1);
  10.         System.out.println(time);

可惜我的计算机不是超级计算机,得到的结果每次不一定一样一般为 46687左右。
也就是46秒。
我们再看看以下代码

  1.         String tempstr = "abcdefghijklmnopqrstuvwxyz";
  2.         int times = 5000;
  3.         long lstart2 = System.currentTimeMillis();
  4.         StringBuffer sb = new StringBuffer();
  5.         for (int i = 0; i < times; i++) {
  6.             sb.append(tempstr);
  7.         }
  8.         long lend2 = System.currentTimeMillis();
  9.         long time2 = (lend2 - lstart2);
  10.         System.out.println(time2);

得到的结果为 16 有时还是 0
所以结论很明显,StringBuffer 的速度几乎是String 上万倍。当然这个数据不是很准确。因为循环的次数在100000次的时候,差异更大。不信你试试。

 

根据上面所说:

str += "here";
的处理步骤实际上是通过建立一个StringBuffer,让侯调用append(),最后
再将StringBuffer toSting();

所以str += "here";可以等同于

StringBuffer sb = new StringBuffer(str);

sb.append("here");

str = sb.toString();

所以上面直接利用"+"来连接String的代码可以基本等同于以下代码

  1.         String tempstr = "abcdefghijklmnopqrstuvwxyz";
  2.         int times = 5000;
  3.         long lstart2 = System.currentTimeMillis();
  4.         String str = "";
  5.         for (int i = 0; i < times; i++) {
  6.             StringBuffer sb = new StringBuffer(str);
  7.             sb.append(tempstr);
  8.             str = sb.toString();
  9.         }
  10.         long lend2 = System.currentTimeMillis();
  11.         long time2 = (lend2 - lstart2);
  12.         System.out.println(time2);

平均执行时间为46922左右,也就是46秒。

ps;而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做

3.String实现了equals方法(比较的是两个对象的内容是否相同),newString(“abc”).equals(newString(“abc”)的结果为true,StringBuffer没有实现equals方法(比较的是两个对象是否相同),所以,newStringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false

(2)已知 int x = 3; int y = 4;在不使用中间变量的情况下,交换x,y的值

在程序中实现交换两个数的功能并不复杂,但如果不使用中间变量,就需要动一下脑筋。在本文介绍了两个方法(其实原理都是一个)。其基本原理就是数的中和。 也就是说,通过某种运算(二元运算)将a和b两个数变成一个数,并保存在其中一个变量中。然后再通过同样的运算符将a或b中和掉。这样实际上是利用了a或 b本身作为了中间变量。
    先看第一个算法。

复制代码
static class Num
{
    
int a;
    
int b;
}
public static void swap1(Num num)
{

    num.a 
= num.a + num.b;
    num.b 
= num.a - num.b;
    num.a 
= num.a - num.b;
}
复制代码

上面代码通过“+”运算符将a和b的运算结果赋给了a(这时a是中间变量)。然后再计算b,这时a的值已经是(a+b)了,因此,a再减b就是原来的a。 而这时b已经是原来的a了,因此,再用运算后的a(实际上是a+b)减运算后的b(实际上是原来的a),就是原来的b了,最后将这个b赋值给a。
    实际上,我们还可以使用“*”、“/”等符号来实现同样的效果,代码如下:

public static void swap2(Num num)
{
    num.a = num.a * num.b;
    num.b = num.a / num.b;
    num.a = num.a / num.b;
}
public static void swap3(Num num)
{
    num.a = num.a - num.b;
    num.b = num.a + num.b;
    num.a = num.b - num.a;
}
    上面代码在Java中没有什么问题(但使用“/”时,分母和分子不能为0)。就算溢出也会得到正确的结果,但有某些语言中(如C语言),可能会抛出溢出错误,不了避免这种错误。可以加判断,代码如下:
public  static  void swap4(Num num)
{
     //  不同符号
     if (num.a * num.b <= 0)
    {
        num.a = num.a + num.b;
        num.b = num.a - num.b;
        num.a = num.a - num.b;
    }
     else
    {

        num.a = num.a - num.b;
        num.b = num.a + num.b;
        num.a = num.b - num.a;
    }
}
    当然,我们还有更好的方法,就是使用异或运算符,我们知道,任何数与0异或后仍然为它本身,两个相同的数异或后为0。根本这种特性,可以有如下代码。

public  static  void swap5(Num num)
{
    num.a = num.a ^ num.b;
    num.b = num.a ^ num.b;
    num.a = num.a ^ num.b;
}
(3)页面之间传递参数的几种方式
1.

(1)直接在URL请求后添加

如:< a href="thexuan.jsp?action=transparams&detail=directe">直接传递参数< /a>

特别的在使用response.sendRedirect做页面转向的时候,也可以用如下代码:

response.sendRedirect("thexuan.jsp?action=transparams&detail=directe") ,可用request.getParameter(name)取得参数

(2)jsp:param

它可以实现主页面向包含页面传递参数,如下:

1.  < jsp:include page="Relative URL"> 

2.   

3.  < jsp:param name="param name" value="paramvalue" /> 

4.   

5.  < /jsp:include> 

还可以实现在使用jsp:forward动作做页面跳转时传递参数,如下:

6.  < jsp:forward page="Relative URL"> 

7.   

8.  < jsp:param name="paramname" value="paramvalue" /> 

< /jsp:forward> 通过这种方式和一般的表单参数一样的,也可以通过request.getParameter(name)取得参数

(3)设置session和request

通过显示的把参数放置到session和request中,以达到传递参数的目的

9.  session.setAttribute(name,value);  

10.  

11. request.setAttribute(name,value)  

取参数:

12. value=(value className)session.getAttribute(name);  

13.  

14. value=(value className)request.getAttribute(name);  

15.  

大家肯定已经注意到了,在取参数的时候,做了类型转换,这是因为放置在session和request中的对象的属性被看作 java.lang.Object类型的了,如果不转换,在将直付给value时会报classcastexception异常。

(4)静态include和动态include的区别(课外书上找的,网上答案基本同个版本,不好)

相同点:被包含的jsp页面中不要使用<html>和<body>标签,它们是html语言的结构标签,被包含进其他jsp页面会破坏页面格式。而且源文件和被包含文件中的变量和方法的名称不能冲突,因为它们最终生成一个文件,重名会导致错误发生

不同点

1.相对路径

include指令使用file属性指定被包含的文件,例如:<include file="xx.jsp" />,该属性使用文件的相对路径指定被包含文件(待续)



          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值