Java笔试面试题汇总
更新时间:2024-01-21 23:06:01 阅读量: 教育文库 文档下载
Java笔试面试题: 1.类的定义格式:
[修饰符] class 类名{ 类的主体; }
2.方法声明的基本格式:
[修饰符] 返回值类型 方法名(参数类型 参数名, ...){ 定义变量; 定义方法; }
3.局部变量与成员变量的区别:成员变量有默认值,而局部变量没有;
4.Java的判断条件结果必须是一个布尔值;
5.this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。
this:代表当前类的对象引用
super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)
应用场景:
A:调用成员变量
this.成员变量 调用本类的成员变量 super.成员变量 调用父类的成员变量 B:调用构造方法
this(...) 调用本类的构造方法 super(...) 调用父类的构造方法 C:调用成员方法
this.成员方法 调用本类的成员方法 super.成员方法 调用父类的成员方法
6.权限修饰符:
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类) private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
JAVA的事件委托机制和垃圾回收机制:
java 事件委托机制的概念,一个源产生一个事件并将它送到一个或多个监听器那里。在这种方案中, 监听器简单的等待, 直到它收到一个事件。 一旦事件
被接受, 监听器将处理这个事件,然后返回。
垃圾回收机制 垃圾收集是将分配给对象但不再使用的内存回收或释放的过程。如果一个对象没有指向它的引用或者其赋值为null,则次对象适合进行垃圾回收
7.控制跳转语句: break:中断 continue:继续 return:返回
break:中断的意思 使用场景:
A:switch语句中 B:循环语句中。
(循环语句中加入了if判断的情况) 注意:离开上面的两个场景,无意义。
如何使用呢?
A:跳出单层循环 B:跳出多层循环
要想实现这个效果,就必须知道一个东西。带标签的语句。 格式:
标签名: 语句 wc:for(int x=0; x<3; x++) {
nc:for(int y=0; y<4; y++) { if(y == 2) { break wc; }
System.out.print(\ }
System.out.println(); }
continue:继续
使用场景:
循环中。离开此场景无意义。
测试,找到和break的区别: break:跳出单层循环
continue:跳出一次循环,进入下一次的执行
练习题:
for(int x=1; x<=10; x++) {
if(x%3==0) {
//在此处填写代码 }
System.out.println(“Java基础班”); }
我想在控制台输出2次:“Java基础班“ break;
我想在控制台输出7次:“Java基础班“ continue;
我想在控制台输出13次:“Java基础班“ System.out.println(“Java基础班”);
return:返回
其实它的作用不是结束循环的,而是结束方法的。
8.什么是 java序列化,如何实现 java序列化? (写一个实例) 序列化:
可以将一个对象保存到一个文件, 所以可以通过流的方式在网络上传输, 可以将文件的内容读取,转化为一个对象。
处理对象流的机制, 所谓对象流也就是将对象的内容进行流化。 可以对流化后的对象进行读写操作, 也可将流化后的对象传输于网络之间。 序列化是为了解决在对对象流进行读写操作时所引发的问题。 序列化的实现:
将需要被序列化的类实现 Serializable 接口,该接口没有需要实现的方法, implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流 (如: FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用
ObjectOutputStream对象的writeObject(Objectobj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
9.一个\源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以。如果这个类的修饰符是public,其类名与文件名必须相同
10.方法重写(Override)和方法重载(Overload)的区别?方法重载能改变返回值类型吗?
Override:方法重写也称方法覆盖 Overload:方法重载
方法重写:
在子类中,出现和父类中一模一样的方法声明的现象。
方法重载:
同一个类中,出现的方法名相同,参数列表不同的现象。 方法重载能改变返回值类型,因为它和返回值类型无关。
子类对象调用方法的时候:先找子类本身,再找父类。
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
方法重写的注意事项
A:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承 B:子类重写父类方法时,访问权限不能更低 最好就一致
C:父类静态方法,子类也必须通过静态方法进行重写
其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解
子类重写父类方法的时候,最好声明一模一样。 11.看程序写结果
字符串数据和其他数据做+,结果是字符串类型。 这里的+不是加法运算,而是字符串连接符。
System.out.prinln(8+8+”88”+8+8); //168888
12.final:最终的意思。常见的是它可以修饰类,方法,变量。 final修饰局部变量的问题
基本类型:基本类型的值不能发生改变。
引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。
final修饰变量的初始化时机
A:被final修饰的变量只能赋值一次。 B:在构造方法完毕前。(非静态的常量)
继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么? 父类: 13. package test; public class FatherClass{ public FatherClass(){ System.out.println(\); } } 子类:
package test; import test.FatherClass; public class ChildClass extends FatherClass{ public ChildClass(){
System.out.println(\); }
public static void main(String[] args){ FatherClass fc = new FatherClass();
ChildClass cc = new ChildClass(); } }
输出结果:
FatherClass Create FatherClass Create ChildClass Create
14.内部类的实现方式? 答: 示例代码如下:
public class OuterClass{
private class InterClass{ public InterClass(){
System.out.println(\); } }
public OuterClass(){
InterClass ic = new InterClass();
System.out.println(\); }
public static void main(String[] args){ OuterClass oc = new OuterClass(); } }
输出结果:
InterClass Create OuterClass Create
15.如在 Collection框架中, 实现比较要实现什么样的接口?
Collection框架中实现比较要实现Comparable 接口和 Comparator 接口
16.看程序写结果 class A{ static{
System.out.print(\); }
public A(){
System.out.print(\); } }
class B extends A{ static{
System.out.print(\); }
public B(){
System.out.print(\); } }
public class C{
public static void main(String[] ars){ A a = new B(); //执行到此处,结果: 1a2b a = new B(); //执行到此处,结果: 1a2b2b } }
类的static 代码段,可以看作是类首次加载(被虚拟机加载)执行的代码,而对 于类的加载,首先要执行其基类的构造,再执行其本身的构造
17.抽象类和接口的区别?
(1)接口可以被多重implements,抽象类只能被单一extends (2)接口只有定义,抽象类可以有定义和实现
(3)接口的字段定义默认为:public static final,当功能需要累积时用抽象类,不需要累积时用接口
18.什么是类的反射机制?
通过类(Class对象),可以得出当前类的fields、 method、 construtor、 interface、superClass、 modified等,同时可以通过类实例化一个实例、设置属性、唤醒方法。Spring中一切都是反射、 struts、 hibernate都是通过类的反射进行开发的
19.类的反射机制中的包及核心类 java.lang.Class
java.lang.refrection.Method java.lang.refrection.Field
java.lang.refrection.Constructor
java.lang.refrection.Modifier java.lang.refrection.Interface
20.得到 Class的三个过程是什么? 对象.getClass()
类.class或Integer.type(int) Integer.class(java.lang.Integer) Class.forName();
21.如何唤起类中的一个方法?
产生一个Class数组,说明方法的参数 通过Class对象及方法参数得到Method
通过method.invoke(实例,参数值数组)唤醒方法
22.如何将数值型字符转换为数字( Integer, Double)? Integer.parseInt(“1234”); Double.parseDouble(“123.2”);
23.数据类型转换:
byte a = 3;
int b = 4;
//int c = a + b; //这个肯定没有问题 //byte c = a + b; //这个是有问题的
//用强制类型转换改进 byte c = (byte) (a + b);
思考题1:请问下面这个有没有问题 double d = 12.345; float f = d;
答:是有问题的,需要进行强制类型转换
思考题2:看看下面两个定义有没有区别呢? float f1 = (float)12.345; float f2 = 12.345f;
f1其实是通过一个double类型转换过来的。 而f2本身就是一个float类型。 面试题:
byte b1=3,b2=4,b; b=b1+b2; b=3+4;
哪句是编译失败的呢?为什么呢? b = b1 + b2; //编译失败。
因为变量相加,题中首先会转换为int类型数据,最终把结果赋给byte类型的变量b时由于可能会损失精度,因此会报错!
常量相加,首先做加法,然后看结果是否在赋值的数据类型范围内,如果不是,才报错。 具体分析:
//b = b1 + b2; //这个是类型提升,所以有问题
b = 3 + 4; //常量,先把结果计算出来,然后看是否在byte的范围内,如果在就不报错。
byte b = 130;有没有问题?如果我想让赋值正确,可以怎么做?结果是多少呢?
//因为byte的范围是:-128到127。
//而130不在此范围内,所以报错。 //byte b = 130;
//我们可以使用强制类型转换 byte b = (byte) 130;
//结果是多少呢?
System.out.println(b); //-126 分析过程:
我们要想知道结果是什么,就应该知道是如何进行计算的。 而我们又知道计算机中数据的运算都是补码进行的。 而要得到补码,首先要计算出数据的二进制。
A:获取130这个数据的二进制。
00000000 00000000 00000000 10000010 这是130的原码,也是反码,还是补码。 B:做截取操作,截成byte类型的了。 10000010
这个结果是补码。 C:已知补码求原码。
符号位 数值位 补码: 1 0000010
反码: 1 0000001
原码: 1 1111110
24.运算符 面试题:
short s=1;s = s+1; //错误,运算的时候s先转换为int类型,然后参与运算,此时需要强制类型转换为short类型
short s=1;s+=1; //正确 扩展的赋值运算符其实隐含了一个强制类型转换。 s += 1;
不是等价于 s = s + 1;
而是等价于 s = (s的数据类型)(s + 1); 25.位运算符
class OperatorDemo {
public static void main(String[] args) { //&,|,^,~
int a = 3; int b = 4;
System.out.println(3 & 4); //0 System.out.println(3 | 4); //7 System.out.println(3 ^ 4); //7 System.out.println(~3); //-4 } }
分析:因为是位运算,所以我们必须先把数据换算成二进制。
3的二进制:11
00000000 00000000 00000000 00000011 4的二进制:100
00000000 00000000 00000000 00000100
&位与运算:有0则0。
00000000 00000000 00000000 00000011 &00000000 00000000 00000000 00000100 ----------------------------------- 00000000 00000000 00000000 00000000 结果是:0
|位或运算:有1则1。
00000000 00000000 00000000 00000011 |00000000 00000000 00000000 00000100 ----------------------------------- 00000000 00000000 00000000 00000111 结果是:7
^位异或运算:相同则0,不同则1。
00000000 00000000 00000000 00000011 &00000000 00000000 00000000 00000100
----------------------------------- 00000000 00000000 00000000 00000111 结果是:7
~按位取反运算符:0变1,1变0
00000000 00000000 00000000 00000011
~11111111 11111111 11111111 11111100 (补码)
补码:11111111 11111111 11111111 11111100 反码:11111111 11111111 11111111 11111011 原码:10000000 00000000 00000000 00000100 结果是:-4 面试题:
<<:左移 左边最高位丢弃,右边补齐0
>>:右移 最高位是0,左边补齐0;最高为是1,左边补齐1 >>>:无符号右移 无论最高位是0还是1,左边补齐0
请用最有效率的方式写出计算2乘以8的结果? 2 * 8 2 << 3
class OperatorDemo {
public static void main(String[] args) { //<< 把<<左边的数据乘以2的移动次幂
System.out.println(3 << 2); //3*2^2 = 3*4 = 12;
//>> 把>>左边的数据除以2的移动次幂
System.out.println(24 >> 2); //24 / 2^2 = 24 / 4 = 6 System.out.println(24 >>> 2); //6
System.out.println(-24 >> 2); //-6
System.out.println(-24 >>> 2); //1073741818 } }
详细分析:
计算出3的二进制:11
00000000 00000000 00000000 00000011 (00)000000 00000000 00000000 0000001100 计算出24的二进制11000
00000000 00000000 00000000 00011000 0000000000 00000000 00000000 000110(00)
计算出24的二进制:11000
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111 补码:11111111 11111111 11111111 11101000
11111111 11111111 11111111 11101000
1111111111 11111111 11111111 111010(00) 补码
补码:1111111111 11111111 11111111 111010 反码:1111111111 11111111 11111111 111001 原码:1000000000 00000000 00000000 000110
结果:-6
>>>的移动:
计算出24的二进制:11000
原码:10000000 00000000 00000000 00011000 反码:11111111 11111111 11111111 11100111 补码:11111111 11111111 11111111 11101000
11111111 11111111 11111111 11101000 0011111111 11111111 11111111 111010(00)
结果:1073741818 /*
面试题:
请自己实现两个整数变量的交换 */
class OperatorDemo {
public static void main(String[] args) { int a = 10; int b = 20;
System.out.println(\+a+\+b);
//方式1:使用第三方变量(开发中用的)
int c = a; a = b; b = c;
System.out.println(\+a+\+b); System.out.println(\);
//方式2:用位异或实现(面试用)
//左边:a,b,a //右边:a ^ b
a = a ^ b;
b = a ^ b; //a ^ b ^ b = a a = a ^ b; //a ^ b ^ a = b
System.out.println(\+a+\+b);
//方式3:用变量相加的做法
a = a + b; //a=30 b = a - b; //b=10 a = a - b; //a=20
System.out.println(\+a+\+b);
//方式4:一句话搞定
b = (a+b) - (a=b); //b=30-20=10,a=20 System.out.println(\+a+\+b); } } /*
练习:
获取两个整数中的最大值 获取三个整数中的最大值 比较两个整数是否相同 */
public class OperatorTest {
public static void main(String[] args) { //获取两个整数中的最大值 int x = 100; int y = 200;
int max = (x > y? x: y);
System.out.println(\+max); System.out.println(\);
//获取三个整数中的最大值 int a = 10; int b = 30; int c = 20;
//分两步:
//A:先比较a,b的最大值
//B:拿a,b的最大值再和c进行比较 int temp = ((a > b)? a: b); //System.out.println(temp); max = (temp > c? temp: c);
System.out.println(\+max);
//一步搞定
//int max = (a > b)?((a > c)? a: c):((b > c)? b: c); //这种做法不推荐。
//int max = a > b?a > c? a: c:b > c? b: c; //System.out.println(\ System.out.println(\);
//比较两个整数是否相同 int m = 100; int n = 200;
boolean flag = (m == n); System.out.println(flag); } }
If语句与三目运算符的区别:
由于if语句的第二种格式刚才也完成了三元运算符可以完成的效果。 所以,我们就认为他们可以完成一样的操作。 但是,他们就一点区别没有吗?肯定不是。
区别:
三元运算符实现的,都可以采用if语句实现。反之不成立。
什么时候if语句实现不能用三元改进呢?
当if语句控制的操作是一个输出语句的时候就不能。
为什么呢?因为三元运算符是一个运算符,运算符操作完毕就应该有一个结果,而不是一个输出。
面试题:
字符参与运算
是查找ASCII里面的值 'a' 97 'A' 65 '0' 48
System.out.println('a'); //a System.out.println('a' + 1); //98
字符串参与运算
这里其实是字符串的连接
System.out.println(\+'a'+1); //helloa1 System.out.println('a'+1+\); //98hello System.out.println(\+5+5); //5+5=55 System.out.println(5+5+\); //10=5+5 24.
面试题:
byte可以作为switch的表达式吗? //可以 long可以作为switch的表达式吗? //不可以
String可以作为switch的表达式吗? //JDK7以后可以是字符串 25. 面试题
静态代码块,构造代码块,构造方法的执行顺序? 静态代码块 > 构造代码块 > 构造方法 静态代码块:只执行一次
构造代码块:每次调用构造方法都执行 class Code { //静态代码块 static {
int a = 100;
System.out.println(a); }
//构造代码块 {
int x = 1000;
System.out.println(x); }
//构造方法
public Code(){
System.out.println(\); }
//构造代码块 {
int y = 2000;
System.out.println(y); }
//静态代码块 static {
int b = 200;
System.out.println(b); } }
public class CodeDemo {
public static void main(String[] args) { //局部代码块 {
int x = 10;
System.out.println(x); }
//找不到符号
//System.out.println(x); {
int y = 20;
System.out.println(y); }
System.out.println(\);
Code c1 = new Code();
System.out.println(\); Code c2 = new Code(); } }
输出结果: 10 20
--------------- 100 200 1000 2000 code
--------------- 1000 2000 Code
看程序写结果: class Student { static {
System.out.println(\静态代码块\);
} {
System.out.println(\构造代码块\); }
public Student() {
System.out.println(\构造方法\); } }
public class StudentDemo { static {
System.out.println(\你好,明天!\); }
public static void main(String[] args) { System.out.println(\我是main方法\);
Student s1 = new Student(); Student s2 = new Student(); }
/*输出结果: 你好,明天! 我是main方法
Student 静态代码块 Student 构造代码块 Student 构造方法 Student 构造代码块 Student 构造方法*/ }
问题:不仅要输出局部范围的num,还要输出本类成员范围的num,我还想要输出父类成员范围的num。怎么办呢? class Father {
public int num = 10; }
class Son extends Father { public int num = 20;
public void show() { int num = 30;
System.out.println(num);
System.out.println(this.num); System.out.println(super.num); } }
class ExtendsDemo {
public static void main(String[] args) { Son s = new Son(); s.show(); } }
数据初始化的面试题
A:一个类的初始化过程 B:子父类的构造执行过程 C:分层初始化 class Father {
public Father() {
System.out.println(\的无参构造方法\); }
public Father(String name) {
System.out.println(\的带参构造方法\); } }
class Son extends Father { public Son() { //super();
System.out.println(\的无参构造方法\); }
public Son(String name) { //super();
System.out.println(\的带参构造方法\); } }
class ExtendsDemo {
public static void main(String[] args) { //创建对象 new Son();
System.out.println(\);
new Son(\蒙蒙\);
//运行结果:
//Father的无参构造方法 //Son的无参构造方法 //------------
//Father的无参构造方法 //Son的带参构造方法 } }
看程序写结果: A:成员变量 就近原则 B:this和super的问题 this访问本类的成员 super访问父类的成员
C:子类构造方法执行前默认先执行父类的无参构造方法 D:一个类的初始化过程 成员变量进行初始化 默认初始化 显示初始化 构造方法初始化 class Fu{
public int num = 10; public Fu(){
System.out.println(\); } }
class Zi extends Fu{ public int num = 20; public Zi(){
System.out.println(\); }
public void show(){ int num = 30;
System.out.println(num); //30 System.out.println(this.num); //20 System.out.println(super.num); //10 } }
class ExtendsTest {
public static void main(String[] args) { Zi z = new Zi();
z.show(); } }
结果: fu zi 30 20 10
看程序写结果:
A:一个类的静态代码块,构造代码块,构造方法的执行流程 静态代码块 > 构造代码块 > 构造方法 B:静态的内容是随着类的加载而加载 静态代码块的内容会优先执行
C:子类初始化之前先会进行父类的初始化 class Fu { static {
System.out.println(\静态代码块Fu\); }
{
System.out.println(\构造代码块Fu\); }
public Fu() {
System.out.println(\构造方法Fu\); } }
class Zi extends Fu { static {
System.out.println(\静态代码块Zi\); }
{
System.out.println(\构造代码块Zi\); }
public Zi() {
System.out.println(\构造方法Zi\); } }
public class ExtendsTest {
public static void main(String[] args) { Zi z = new Zi();
/*
结果是:
静态代码块Fu 静态代码块Zi 构造代码块Fu 构造方法Fu 构造代码块Zi 构造方法Zi*/ } }
看程序写结果:
A:成员变量的问题
int x = 10; //成员变量是基本类型 Student s = new Student(); //成员变量是引用类型 B:一个类的初始化过程 成员变量的初始化 默认初始化 显示初始化 构造方法初始化
C:子父类的初始化(分层初始化)
先进行父类初始化,然后进行子类初始化。 问题:
虽然子类中构造方法默认有一个super() 初始化的时候,不是按照那个顺序进行的。 而是按照分层初始化进行的。
它仅仅表示要先初始化父类数据,再初始化子类数据。 class X {
Y b = new Y(); X() {
System.out.print(\); } }
class Y { Y() {
System.out.print(\); } }
public class Z extends X { Y y = new Y(); Z() {
//super();
System.out.print(\); }
public static void main(String[] args) { new Z(); } }
结果: YXYZ
面试题:
package,import,class有没有顺序关系? 有。
package > import > class
Package:只能有一个 import:可以有多个
class:可以有多个,以后建议是一个
面试题:
局部内部类访问局部变量的注意事项?
A:局部内部类访问局部变量必须用final修饰 B:为什么呢?
局部变量是随着方法的调用而调用,随着调用完毕而消失。 而堆内存的内容并不会立即消失。所以,我们加final修饰。 加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
我在内存中存储的是数据20,所以,我还是有数据在使用。
面试题:
要求请填空分别输出30,20,10。 注意:
1:内部类和外部类没有继承关系。 2:通过外部类名限定this对象 Outer.this
成员内部类的面试题(填空) 控制台输出:30,20,10 class Outer {
public int num = 10;
class Inner {
public int num = 20; public void show() { int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num); } } }
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner(); oi.show(); } }
//匿名内部类面试题: //按照要求,补齐代码
//要求在控制台输出”HelloWorld” /*
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) { Outer.method().show(); } } */
//答案:
interface Inter { void show(); //public abstract }
class Outer { //补齐代码
public static Inter method() { //子类对象 -- 子类匿名对象
return new Inter() { public void show() {
System.out.println(\ } }; } }
class OuterDemo {
public static void main(String[] args) { Outer.method().show();
//1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
//2:Outer.method().show()可以看出method()方法的返回值是一个对象。
// 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。 } }
字符串的面试题(看程序写结果)
==和equals()的区别?
A:==
基本类型:比较的是值是否相同 引用类型:比较的是地址值是否相同 B:equals()
只能比较引用类型。默认情况下,比较的是地址值是否相同。 但是,我们可以根据自己的需要重写该方法。
A:==和equals()
String s1 = new String(\ String s2 = new String(\
System.out.println(s1 == s2);// false System.out.println(s1.equals(s2));// true
String s3 = new String(\ String s4 = \
System.out.println(s3 == s4);// false System.out.println(s3.equals(s4));// true
String s5 = \ String s6 = \
System.out.println(s5 == s6);// true
System.out.println(s5.equals(s6));// true B:字符串的拼接 /*
* 字符串如果是变量相加,先开空间,再拼接。
* 字符串如果是常量相加,是先加,然后在常量池找,如果有就直 接返回,否则,就创建。 */
public class StringDemo {
public static void main(String[] args) { String s1 = \ String s2 = \
String s3 = \
System.out.println(s3 == s1 + s2);// false
System.out.println(s3.equals((s1 + s2)));// true
System.out.println(s3 == \这个我们错了,应该是true
System.out.println(s3.equals(\+ \true
// 通过反编译看源码,我们知道这里已经做好了处理。 // System.out.println(s3 == \
// System.out.println(s3.equals(\ }
}
面试题:
StringBuffer:同步的,数据安全,效率低。
StringBuilder:不同步的,数据不安全,效率高。
1:String,StringBuffer,StringBuilder的区别?
A:String是内容不可变的,而StringBuffer,StringBuilder都是内容可变的。 B:StringBuffer是同步的,数据安全,效率低;StringBuilder是不同步的,数据不安全,效率高
2:StringBuffer和数组的区别?
二者都可以看出是一个容器,装其他的数据。
但是呢,StringBuffer的数据最终是一个字符串数据。 而数组可以放置多种数据,但必须是同一种数据类型的。
3:形式参数问题
String作为参数传递
StringBuffer作为参数传递
形式参数:
基本类型:形式参数的改变不影响实际参数 引用类型:形式参数的改变直接影响实际参数
注意:
String作为参数传递,效果和基本类型作为参数传递是一样的。 面试题
-128到127之间的数据缓冲池问题
注意:Integer的数据直接赋值,如果在-128到127之间,会直接从缓冲池里获取数据
通过查看源码,我们就知道了,针对-128到127之间的数据,做了一个数据缓冲池,如果数据是该范围内的,每次并不创建新的空间
注意:
public class BigDecimalDemo {
public static void main(String[] args) { System.out.println(0.09 + 0.01); System.out.println(1.0 - 0.32); System.out.println(1.015 * 100); System.out.println(1.301 / 100);
System.out.println(1.0 - 0.12);
//0.09999999999999999 //0.6799999999999999 //101.49999999999999 //0.013009999999999999 //0.88 } }
面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢?
List:(面试题List的子类特点) ArrayList:
底层数据结构是数组,查询快,增删慢。 线程不安全,效率高。 Vector:
底层数据结构是数组,查询快,增删慢。 线程安全,效率低。 LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
List有三个儿子,我们到底使用谁呢? 看需求(情况)。 要安全吗?
要:Vector(即使要安全,也不用这个了,后面有替代的) 不要:ArrayList或者LinkedList 查询多:ArrayList 增删多:LinkedList
如果你什么都不懂,就用ArrayList。
面试题:
Collection和Collections的区别?
Collection:是单列集合的顶层接口,有子接口List和Set。
Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法
1.Hashtable和HashMap的区别?
Hashtable:线程安全,效率低。不允许null键和null值 HashMap:线程不安全,效率高。允许null键和null值
2.List,Set,Map等接口是否都继承子Map接口?
List,Set不是继承自Map接口,它们继承自Collection接口 Map接口本身就是一个顶层接口
编译时异常和运行时异常的区别
编译期异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译 运行期异常:无需显示处理,也可以和编译时异常一样处理
throws和throw的区别(面试题) throws
用在方法声明后面,跟的是异常类名 可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常 throw
用在方法体内,跟的是异常对象名 只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常
finally关键字及其面试题
1:final,finally和finalize的区别
final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写
finally:是异常处理的一部分,用于释放资源。
一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
finalize:是Object类的一个方法,用于垃圾回收
2:如果catch里面有return语句,请问finally里面的代码还会执行吗? 如果会,请问是在return前,还是return后。 会。前。
准确的说,应该是在中间。
3:try...catch...finally的格式变形 A:try...catch...finally B:try...catch
C:try...catch...catch...
D:try...catch...catch...finally E:try...finally
这种做法的目前是为了释放资源。
面试题:
public class FinallyDemo {
public static void main(String[] args) { System.out.println(getInt()); }
public static int getInt() { int a = 10; try {
System.out.println(a / 0); a = 20;
} catch (ArithmeticException e) { a = 30; return a; /*
* return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
* 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
* 再次回到以前的返回路径,继续走return 30; */
} finally { a = 40;
//return a;//如果这样结果就是40了。 }
return a; } }
面试题:
什么时候序列化? 如何实现序列化? 什么是反序列化?
调用run()方法为什么是单线程的呢?
因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
要想看到多线程的效果,就必须说说另一个方法:start() 面试题:run()和start()的区别?
run():仅仅是封装被线程执行的代码,直接调用是普通方法
start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
多线程常见面试题:
1:多线程有几种实现方案,分别是哪几种? 两种。
继承Thread类 实现Runnable接口
扩展一种:实现Callable接口。这个得和线程池结合。
2:同步有几种方式,分别是什么? 两种。
同步代码块 同步方法
3:启动一个线程是run()还是start()?它们的区别? start();
run():封装了被线程执行的代码,直接调用仅仅是普通方法的调用 start():启动线程,并由JVM自动调用run()方法
4:sleep()和wait()方法的区别
sleep():必须指定时间;不释放锁。
wait():可以不指定时间,也可以指定时间;释放锁。
5:为什么wait(),notify(),notifyAll()等方法都定义在Object类中
因为这些方法的调用是依赖于锁对象的,而同步代码块的锁对象是任意锁。 而Object代表任意的对象,所以,定义在这里面。
6:线程的生命周期图
新建 -- 就绪 -- 运行 -- 死亡
新建 -- 就绪 -- 运行 -- 就绪 -- 运行 -- 死亡
新建 -- 就绪 -- 运行 -- 其他阻塞 -- 就绪 -- 运行 -- 死亡 新建 -- 就绪 -- 运行 -- 同步阻塞 -- 就绪 -- 运行 -- 死亡
新建 -- 就绪 -- 运行 -- 等待阻塞 -- 同步阻塞 -- 就绪 -- 运行 -- 死亡
面试题:单例模式的思想是什么?请写一个代码体现。
面试题:close()和flush()的区别?
A:close()关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。
正在阅读:
Java笔试面试题汇总01-21
安全经验分享记录一03-19
居里夫人的三克镭教学反思5篇02-09
秋天来了一年级作文02-06
国际工程承包第四次网上考试10-13
职业病诊断鉴定09-15
裘布依微分方程06-24
八年级下册人教版历史中考试题汇编06-01
第二届全国口译大赛(英语)复赛细则07-27
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 笔试
- 汇总
- 试题
- Java
- 税法复习资料
- Linux期末考试试题2
- 学生工作亮点及特色工作
- 河南科技大学通讯稿汇总
- 施工栈桥安全措施
- 年产200万盒中药功能红参及其它长白山道地药材饮片生产基地建设项目可行性报告1 - 图文
- 在统战工作座谈会上的讲话
- 音乐学院本科生毕业音乐会实施办法
- 16秋福建师范大学《小学教育管理》在线作业一
- 示波器的使用方法详解 - 图文
- 普通话测试字词表
- 2013年新东方法条串讲班行政法-徐金桂讲义
- 15秋川大《汇编语言程序设计2238》15秋在线作业1
- 材料科学基础课后作业及答案(分章节)
- 无机化学习题及答案 - 图文
- 2014年最新的苏教版本《数学》四年级上册第二单元《两、三位数除以两位数》教案
- 2015年银行业初级资格考试《个人理财》模考押题卷(2)
- 依法使用武器警械专项训练基本知识题库
- C语言二级考复习资料(1)
- 汇发(2009)24号 - 国家外汇管理局关于境内企业境外放款外汇管理有关问题的通知