Java基础面试题附答案 1-20(一)
面试题 1-20(一)
1、面向对象的特征有哪些方面?
2、访问修饰符 public,private,protected,以及不写(默认)时的区别?
3、String 是最基本的数据类型吗?
4、float f=3.4;是否正确?
5、short s = 1; s = s + 1;有错吗?short s = 1; s += 1;有错吗?
6、Java 有没有 goto?
7、int 和 Integer 有什么区别?
8、&和&&的区别?
9、解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。
10、Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
11、switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?
12、用最有效率的方法计算 2 乘以 8?
13、数组有没有 length()方法?String 有没有 length()方法?
14、在 Java 中,如何跳出当前的多重嵌套循环?
15、构造器(constructor)是否可被重写(override)?
16、两个对象值相同(x.equals(y) == true),但却可有不同的 hashcode,这句话对不对?
17、是否可以继承 String 类?
18、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
19、String 和 StringBuilder、StringBuffer 的区别?
20、重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
1、面向对象的特征有哪些方面?
抽象、继承、封装、多态
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
继承:子类继承父类,从而继承了父类的方法和属性。
封装:最常见的是把属性私有化封装在一个类里面,只能通过方法去访问。
多态:多态是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当 A 系统访问 B 系统提供的服务时,B系统有多种提供服务的方式,但一切对 A 系统来说都是透明的(就像电动剃须刀是 A 系统,它的供电系统是 B 系统,B 系统可以使用电池供电或者用交流电,甚至还有可能是太阳能,A 系统只会通过 B 类对象调用供电的方法,但并不知道供电系统的底层实现是什么,究竟通过何种方式获得了动力)。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:
- 1 方法重写(子类继承父类并重写父类中已有的或抽象的方法);
- 2 父类引用指向子类对象(这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。
2、访问修饰符 public,private,protected,以及不写(默认)时的区别?
类的成员不写访问修饰时默认为 default
- private:表示私有,只有自己类能访问
- default:表示没有修饰符修饰,只有同一个包的类能访问
- protected:表示可以被同一个包的类以及其他包中子类访问
- public:表示可以被该项目中的所有包中的所有类访问
3、String 是最基本的数据类型吗?
不是。Java 中的基本数据类型只有 8 个 :byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(referencetype),Java 5 以后引入的枚举类型也算是一种比较特殊的引用类型。
4、float f=3.4;是否正确?
不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4F;。
5、short s = 1; s = s + 1;有错吗?short s = 1; s += 1;有错吗?
对于 short s = 1; s = s + 1;由于 1 是 int 类型,因此 s+1 运算结果也是 int 型,需要强制转换类型才能赋值给 short 型。
而 short s = 1; s += 1;可以正确编译,因为 s += 1;相当于 s = (short(s + 1);其中有隐含的强制类型转换。
6、Java 有没有 goto?
goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。
7、int 和 Integer 有什么区别?
int 为基本数据类型,int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java 为每个原始类型提供了包装类型:
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
class AutoUnboxingTest {
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3; // 将 3 自动装箱成 Integer 类型
int c = 3;
System.out.println(a == b);
// false ,两个引用没有引用同一对象
System.out.println(a == c);
// true ,a 自动拆箱成 int 类型再和 c 比较
}
}
另一个与自动拆箱,自动装箱有关的面试题是:
Integer a=100, b=100, c=200, d=200;
System.out.println(a == b); //true
System.out.println(c == d); //false
需要注意的是,在[-128,127]之间的数,编译器仍然会当做基本数据类型处理。
8、&和&&的区别?
& 有两个作用,分别是位与和逻辑与
&& 就是逻辑与
作为逻辑与
& 表示长路与:两侧,都会被运算
&& 表示短路与:只要第一个是false,第二个就不进行运算了
9、解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。
栈的特点
- 栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
- JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数,局部变量等)
- 栈属于线程私有,不能实现线程间的共享
- 栈的存储特性是“先进后出,后进先出“(形如子弹夹)
- 栈是由系统自动分配,速度快!栈是一个连续的内存空间
- 方法执行完毕,自动释放空间
堆的特点
- 堆用于存储创建好的对象和数组(数组也是对象、存放new出来的对象)
- JVM只有一个堆,被所有线程共享
- 堆是一个不连续的内存空间,分配灵活,速度慢!
- 需要垃圾回收器来回收
方法区的特点
- JVM只有一个方法区,被所有线程共享
- 方法区实际也是堆,只是用于存储类、常量相关的信息!
- 用来存放程序中永远不变或唯一的内容(类的相关信息(class对象)、静态变量、字符串常量等)
10、Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加 0.5 然后进行下取整。
11、switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?
在 Java 5 以前,switch(expression) 中,expression 只能是 byte、short、char、int。
从 Java 5 开始,Java 中引入了枚举类型,expression 也可以是 enum 类型。
从 Java 7 开始,expression 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
12、用最有效率的方法计算 2 乘以 8?
2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。
13、数组有没有 length()方法?String 有没有 length()方法?
数组没有 length()方法 ,有 length 的属性。String 有 length()方法。JavaScript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。
14、在 Java 中,如何跳出当前的多重嵌套循环?
在最外层循环前加一个标记如 A,然后用 break A;可以跳出多重循环。(Java 中支持带标签的 break 和 continue 语句,作用有点类似于 C 和 C++中的 goto 语句,但是就像要避免使用 goto 一样,应该避免使用带标签的 break 和 continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法其实不知道更好)
15、构造器(constructor)是否可被重写(override)?
构造器不能被继承,因此不能被重写,但可以被重载。
16、两个对象值相同(x.equals(y) == true),但却可有不同的 hashcode,这句话对不对?
因为hashCode()方法和equals()方法都可以通过自定义类重写,是可以做到equals相同,但是hashCode不同的。
但是,在Object类的equals()方法中有这么一段话
通常来讲,在重写这个方法的时候,也需要对hashCode方法进行重写,
以此来保证这两个方法的一致性——
当equals返回true的时候,这两个对象一定有相同的hashcode.
所以,“两个对象值相同(x.equals(y) == true),但却可有不同的 hashcode”说法是错误的。
17、是否可以继承 String 类?
String 是 final 修饰的,所以不能够被继承。
18、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。
19、String 和 StringBuilder、StringBuffer 的区别?
String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。而 StringBuffer/StringBuilder 类表示的字符串对象可以直接进行修改。StringBuilder 是 Java 5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized 修饰,因此它的效率也比 StringBuffer 要高。
- 问题1 - 什么情况下用+运算符进行字符串连接比调用 StringBuffer/StringBuilder 对象的 append 方法连接字符串性能更好?
- 问题2 - 请说出下面程序的输出。
class StringEqualTest {
public static void main(String[] args) {
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program" + "ming";
String s6 = s3 + s4;
System.out.println(s1 == s2); //false
System.out.println(s1 == s5); //true
System.out.println(s1 == s6); //false
System.out.println(s1 == s6.intern()); //true
System.out.println(s2 == s2.intern()); //false
}
}
补充:解答上面的问题需要知道两点:
(1) String 对象的 intern 方法会得到字符串对象在常量池中对应的版本的引用(如果常量池中有一个字符串与 String 对象的 equals 结果是 true),如果常量池中没有对应的字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串的引用;
(2) 字符串的+操作其本质是创建了 StringBuilder 对象进行 append 操作,然后将拼接后的 StringBuilder 对象用toString 方法处理成 String 对象,这一点可以用 javap -c StringEqualTest.class命令获得 class 文件对应的 JVM 字节码指令就可以看出来。
20、重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;
重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则:任何父类可以出现的地方,子类一定可以出现)。
重载对返回类型没有特殊的要求。