面试题(Java)(一)
=======================
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》
=======================
- 解题思路:
- 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)) , Integer 的 equals 方法如下:
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对象)
- 1.request对象
=======================
forward和redirect的区别:
- 从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.从效率来说
forward:高.
redirect:低.
下一篇: python程序设计基础之print