欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

面试题(Java)(一)

程序员文章站 2022-04-11 17:46:54
...

=======================

String s1=new String( ” xyz ” );            //创建了String类型的内容为xyz的s1对象
String s2=new String( ” xyz ” );            //创建了String类型的内容为xyz的s2对象
Boolean b1=s1.equals(s2);                    //比较s1对象和s2对象的内容相等,返回true。
Boolean b2=(s1==s2);                        //比较s1和s2两个对象的存储地址是否相等,明显两者分别存储在不同的地址,所以返回:false。

=======================

一个.java文件中定义多个类:
注意一下几点:

  • (1)public权限类只能有一个(也可以一个都没有,但最多只有一个);
  • (2)这个.java文件名只能是public 权限的类的类名;
  • (3)倘若这个文件中没有public 类,则它的.java文件的名字是随便的一个类名;
  • (4)当用javac命令生成编译这个.java 文件的时候,则会针对每一个类生成一个.class文件;

=======================

  • A:形式参数可被视为local variable。形参和局部变量一样都不能离开方法。都只有在方法内才会发生作用,也只有在方法中使用,不会在方法外可见。
  • B:对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。 不过一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是:方法内部类。 一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。
  • C:形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列),也就是说真正被传递的是实参。
  • D:方法的参数列表指定要传递给方法什么样的信息,采用的都是对象的形式。因此,在参数列表中必须指定每个所传递对象的类型及名字。想JAVA中任何传递对象的场合一样,这里传递的实际上也是引用,并且引用的类型必须正确。–《Thinking in JAVA》

=======================

面试题(Java)(一)

  • 解题思路:
  • 1.注意第二行代码,Byte x;Byte是包装类,不是byte(基本数据类型),因此Byte的默认是null,不是0
  • 2.t是一个引用地址类型,在调用fit(Two tt)函数是,是一个实参到形参的传值,也就是把t的地址赋值给了tt,但是都是指向堆内存中新建的对象,因此当对tt.x和t.x指向是相同的。因此t.x也是42
  • 3.Two t2=fit(t);fit函数返回的还是一个引用地址,这句代码相当于把t(函数里面返回的是tt)的地址赋值给了t2,因此t2.x也是42

=======================

  • 在JAVA中,假设A有构造方法A(int a),则在类A的其他构造方法中调用该构造方法和语句格式应该为()
    • this的作用其中一个就是在一个构造方法中调用另一个构造方法,格式为this(参数);
    • super是调用父类的方法;
    • A(a)这种形式是在new一个类时使用。

=======================

  • getParameter()是获取POST/GET传递的参数值;
  • getInitParameter获取Tomcat的server.xml中设置Context的初始化参数
  • getAttribute()是获取对象容器中的数据值;
  • getRequestDispatcher是请求转发。

=======================

Consider the following code:
Integer s=new Integer(9);
Integer t=new Integer(9);
Long u=new Long(9);
Which test would return true? 

解析:
(s==u) ,因为,s 是 Integer 类型, u 是 Long 类型,两个不同类型的引用不能进行 == 比较。
(s==t) ,s 是指向一个 9 的引用,而 t 也是一个指向 9 的引用,虽然都是指向 9 ,但却是指向不同的 9 ,即是两个不同的引用。因此 == 比较返回的是假。
(s.equals(t)) , Integerequals 方法如下:
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false ;
}
是 Integer 的实例且 value 值也相等的情况下返回真,其他返回假。
在这里, s 和 t 都是 Integer 类型且值都为 9 ,因此结果为真。
(s.equals(9)) , 在进行 equals 比较之前,会对 9 调用 Integer.valueOf 方法,进行自动装箱 , 由于 IntegerCache 中已经存在 9 ,所以,直接返回其引用,引用相同, equals 就自然相同了。所以结果为真。
(s.equals( new Integer(9)) ,直接创建了一个新的 Integer 实例,但且值也为 9 ,所以,满足条件,返回真。 

=======================

  • final修饰类、方法、属性!不能修饰抽象类,因为抽象类一般都是需要被继承的,final修饰后就不能继承了。
  • final修饰的方法不能被重写而不是重载!
  • final修饰属性,此属性就是一个常量,不能被再次赋值!

=======================

  • 什么是互斥锁
    • 在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为” 互斥锁” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象
    • synchronized

=======================

下列程序的输出结果
public class Example {
    String str = new String("good");
    char[] ch = { 'a', 'b', 'c' };

    public static void main(String args[]) {
        Example ex = new Example();
        ex.change(ex.str, ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }

   public static void change(String str, char ch[])      
   {
        str = "test ok";
        ch[0] = 'g';
    }
}
  • 解析:
  • 考察值传递和引用传递。对于值传递,拷贝的值用完之后就会被释放,对原值没有任何影响,但是对于引用传递,拷贝的是对象的引用,和原值指向的同一块地址,即操作的是同一个对象,所以操作之间会相互影响
    所以对于String str是值传递,操作之间互不影响,原值保持不变。而ch是数组,拷贝的是对象的引用,值发生了改变.
  • good and gbc

=======================

  • hashMap和hashtable方面的知识点
  • 关于HashMap的一些说法:
    • a) HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。
    • b) HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子。
    • c) HashMap实现不同步,线程不安全。 HashTable线程安全
    • d) HashMap中的key-value都是存储在Entry中的。
    • e) HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性
    • f) 解决冲突主要有三种方法:定址法拉链法再散列法。HashMap是采用拉链法解决哈希冲突的。
    • 注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;
    • 用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。
    • 拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。拉链法适合未规定元素的大小。
  • . Hashtable和HashMap的区别
    • a) 继承不同。
    • public class Hashtable extends Dictionary implements Map
    • public class HashMap extends AbstractMap implements Map
    • b) Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
    • c) Hashtable 中, key 和 value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。
    • d) 两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
    • e) 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
    • f) Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
    • 注: HashSet子类依靠hashCode()和equal()方法来区分重复元素。 HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。

=======================

  • Web service顾名思义是基于web的服务,它是一种跨平台,跨语言的服务。
  • 我们可以这样理解它,比如说我们可以调用互联网上查询天气信息的web服务,把它嵌入到我们的B/S程序中,当用户从我们的网点看到天气信息时,会认为我们为他提供很多的服务,但其实我们什么也没做,只是简单的调用了一下服务器上的一端代码而已。Web service 可以将你的服务发布到互联网上让别人去调用,也可以调用别人发布的web service,和使用自己的代码一样。
  • 它是采用XML传输格式化的数据,它的通信协议是SOAP(简单对象访问协议).

=======================

下面代码的输出是什么? 
public class Base{
    private String baseName = "base";
    public Base(){
        callName();
    }

    public void callName(){
        System. out. println(baseName);
    }

    static class Sub extends Base{
        private String baseName = "sub";
        public void callName(){
            System. out. println (baseName) ;
        }
    }
    public static void main(String[] args){
        Base b = new Sub();
    }
}
  • 解析:

  • 1.首先,需要明白类的加载顺序。

    • (1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
    • (2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )
    • (3) 父类非静态代码块( 包括非静态初始化块,非静态属性 )
    • (4) 父类构造函数
    • (5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )
    • (6) 子类构造函数
    • 其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)
  • 2.其次,需要理解子类覆盖父类方法的问题,也就是方法重写实现多态问题。
    • Base b = new Sub();它为多态的一种表现形式,声明是Base,实现是Sub类, 理解为 b 编译时表现为Base类特性,运行时表现为Sub类特性。
    • 当子类覆盖了父类的方法后,意思是父类的方法已经被重写,题中 父类初始化调用的方法为子类实现的方法,子类实现的方法中调用的baseName为子类中的私有属性。
    • 由1.可知,此时只执行到步骤4.,子类非静态代码块和初始化步骤还没有到,子类中的baseName还没有被初始化。所以此时 baseName为空。 所以为null。

=======================

  • URL(Uniform Resource Locator) ,统一资源定位符,能够对因特网的资源进行定位。
    • URL一般有四部分组成: <协议>://<主机>:<端口>/<路径>
    • 现在最常用的<协议>为http协议。
    • <主机>是指主机在因特网上的域名。
    • http协议的默认<端口>为80(可以省略)。
    • <路径>是指要活的的文件的路径。

=======================

  • System.in 和 System.out 是java中的标准输入输出流,一般情况下代表从控制台输入和输出到控制台

=======================

下列代码的输出值是什么:

public class Test {
    public static void main(String[] args) {
        System.out.println("return value of getValue(): " +
        getValue());
    }
     public static int getValue() {
         try {
             return 0;
         } finally {
             return 1;
         }
     }
 }

答案:return value of getValue(): 1
解析:
根据官方的JVM规范:
如果try语句里有return,返回的是try语句块中变量值。
详细执行过程如下:
如果有返回值,就把返回值保存到局部变量中;
执行jsr指令跳到finally语句里执行;
执行完finally语句后,返回之前保存在局部变量表里的值。
如果try,finally语句里均有return,忽略try的return,而使用finally的return.

=======================

java不允许单独的方法,过程或函数存在,需要隶属于某一类中
java语言中的方法属于对象的成员,而不是类的成员。不过,其中静态方法属于类的成员

=======================

class A {}
class B extends A {}
class C extends A {}
class D extends B {}
Which four statements are true ?

A The type List<A>is assignable to List.
B The type List<B>is assignable to List<A>.
C The type List<Object>is assignable to List<?>.
D The type List<D>is assignable to List<?extends B>.
E The type List<?extends A>is assignable to List<A>.
F The type List<Object>is assignable to any List reference.
G The type List<?extends B>is assignable to List<?extends A>.   

答案:A C D G
解析:
- 只看尖括号里边的!!明确点和范围两个概念
- 如果尖括号里的是一个类,那么尖括号里的就是一个点,比如List< A>,List< B>,List< Object>
- 如果尖括号里面带有问号,那么代表一个范围,< ? extends A> 代表小于等于A的范 围,<? super A > 代表大于等于A的范围,<?>代表全部范围
- 尖括号里的所有点之间互相赋值都是错,除非是俩相同的点
- 尖括号小范围赋值给大范围,对,大范围赋值给小范围,错。如果某点包含在某个范围里,那么可以赋值,否则,不能赋值
- List<?>和List 是相等的,都代表最大范围
- List既是点也是范围,当表示范围时,表示最大范围

=======================

  • 创建泛型对象的时候,一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出类不匹配的异常。
  • JVM如何理解泛型概念 —— 类型擦除。事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。 处理方法很简单,我们叫做类型变量T的擦除(erased) 。
  • 总结:泛型代码与JVM
    • ① 虚拟机中没有泛型,只有普通类和方法。
    • ② 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除)
    • ③ 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。 无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。

=======================

下列代码的输出结果是什么:
public static void main (String[] args) { 
    String classFile = "com.jd.". replaceAll(".", "/") + "MyClass.class";
    System.out.println(classFile);
}

答案:///////MyClass.class
解析: 由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/"。如果想替换的只是".",那么久要写成"\\."

=======================

  • JSP内置对象有:
    • 1.request对象
      客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
    • 2.response对象
      response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
    • 3.session对象
      session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.
    • 4.out对象
      out对象是JspWriter类的实例,是向客户端输出内容常用的对象
    • 5.page对象
      page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例
    • 6.application对象
      application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
    • 7.exception对象
      exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象
    • 8.pageContext对象
      pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
    • 9.config对象
      config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)

=======================

forward和redirect的区别:
- 从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

  • 从数据共享来说
    forward:转发页面和转发到的页面可以共享request里面的数据.
    redirect:不能共享数据.

  • 从运用地方来说
    forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
    redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

  • 从效率来说
    forward:高.
    redirect:低.