java面试(基础部分)
一、Java概述
1. 何为编程
2. 什么是Java
3. jdk1.5之后的三大版本
4. Jdk和Jre和JVM的区别
5. 什么是跨平台性?原理是什么
- 所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行。
- 实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。
6. Java语言有哪些特点
- 简单易学(Java语言的语法与C语言和C++语言很接近)
- 面向对象(封装,继承,多态)
- 平台无关性(Java虚拟机实现平台无关性)
- 支持网络编程并且很方便(Java语言诞生本身就是为简化网络编程设计的)
- 支持多线程(多线程机制使应用程序在同一时间并行执行多项任)
- 健壮性(Java语言的强类型机制、异常处理、垃圾的自动收集等)
- 安全性好
7. 什么是字节码?采用字节码的最大好处是什么
8. 什么是Java程序的主类?应用程序和小程序的主类有何不同?
9. Java应用程序与小程序之间有那些差别?
10. Java和C++的区别
11. Oracle JDK 和 OpenJDK 的对比
二、基础语法
数据类型相关
12. Java有哪些数据类型
13. switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上
14. 用最有效率的方法计算 2 乘以 8
- 2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。
15. Math.round(11.5) 等于多少?Math.round(-11.5)等于多少
- Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加 0.5 然后进行下取整。
16. float f=3.4;是否正确
17. short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗
编码相关
18. Java语言采用何种编码方案?有何特点?
- Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。
注释相关
19. 什么Java注释
访问修饰符相关
20. 访问修饰符 public,private,protected,以及不写(默认)时的区别
运算符相关
21. &和&&的区别
&& 操作具有短路性,当第一个条件为false时,就不会执行第二个条件
java关键字
Java 有没有 goto
- goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。
Synchronised和lock
synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。JDK1.5以后引入了自旋锁、锁粗化、轻量级锁,偏向锁来有优化关键字的性能。
两者的区别
1.Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2. synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生; 而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
3. Synchronised 可重入锁,不可以中断,非公平;lock,可重入锁,可以判断锁,非公平(默认,可以自己设置)
4. Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
5. 通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
6. Synchronised 适合少量代码的同步问题;lock适合大量代码的同步问题
介绍一下Syncronized锁,如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?
synchronized修饰静态方法以及同步代码块的synchronized (类.class)用法锁的是类,线程想要执行对应同步代码,需要获得类锁。
synchronized修饰成员方法,线程获取的是当前调用该方法的对象实例的对象锁。
volatile
final 有什么用?
final finally finalize区别
try、catch、finally 考察,请指出下面程序的运行结果。
public class TryDemo { public static void main(String[] args) { System.out.println(test()); } public static int test() { try { return 1; } catch (Exception e) { return 2; } finally { System.out.print("3"); } } }
执行结果:31。
相信很多同学应该都做对了,try、catch。finally 的基础用法,在 return 前会先执行 finally 语句块,所以是先输出 finally 里的 3,再输出 return 的 1。
try、catch、finally 考察2,请指出下面程序的运行结果。
public class TryDemo { public static void main(String[] args) { System.out.println(test1()); } public static int test1() { try { return 2; } finally { return 3; } } }
执行结果:3。
这题有点先将,但也不难,try 返回前先执行 finally,结果 finally 里不按套路出牌,直接 return 了,自然也就走不到 try 里面的 return 了。
finally 里面使用 return 仅存在于面试题中,实际开发中千万不要这么用。
try、catch、finally 考察3,请指出下面程序的运行结果。
public class TryDemo { public static void main(String[] args) { System.out.println(test1()); } public static int test1() { int i = 0; try { i = 2; return i; } finally { i = 3; } } }
执行结果:2。
这边估计有不少同学会以为结果应该是 3,因为我们知道在 return 前会执行 finally,而 i 在 finally 中被修改为 3 了,那最终返回 i 不是应该为 3 吗?确实很容易这么想,我最初也是这么想的,当初的自己还是太年轻了啊。
这边的根本原因是,在执行 finally 之前,JVM 会先将 i 的结果暂存起来,然后 finally 执行完毕后,会返回之前暂存的结果,而不是返回 i,所以即使这边 i 已经被修改为 3,最终返回的还是之前暂存起来的结果 2。
这边其实根据字节码可以很容易看出来,在进入 finally 之前,JVM 会使用 iload、istore 两个指令,将结果暂存,在最终返回时在通过 iload、ireturn 指令返回暂存的结果。
this关键字的用法
super关键字的用法
class Person{ protected String name; public Person(String name) { this.name = name; } } class Student extends Person{ private String name; public Student(String name, String name1) { super(name); this.name = name1; } public void getInfo(){ System.out.println(this.name); //Child System.out.println(super.name); //Father } } public class Test { public static void main(String[] args) { Student s1 = new Student("Father","Child"); s1.getInfo(); } }
this与super的区别
static存在的主要意义
static的独特之处
static应用场景
static注意事项
- 1、静态只能访问静态。
- 2、非静态既可以访问非静态的,也可以访问静态的
流程控制相关
break ,continue ,return 的区别及作用
- break 跳出总上一层循环,不再执行循环(结束当前的循环体)
- continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
- return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
在 Java 中,如何跳出当前的多重嵌套循环
三、面向对象
面向对象和面向过程的区别
38. 面向对象的三大基本特征
面向对象的三个基本特征是:封装、继承和多态。
继承:让某个类型的对象获得另一个类型的对象的属性的方法。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
封装:隐藏部分对象的属性和实现细节,对数据的访问只能通过外公开的接口。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
多态:对于同一个行为,不同的子类对象具有不同的表现形式。多态存在的3个条件:1)继承;2)重写;3)父类引用指向子类对象。
举个简单的例子:英雄联盟里面我们按下 Q 键这个动作:
对于亚索,就是斩钢闪
对于提莫,就是致盲吹箭
对于剑圣,就是阿尔法突袭
同一个事件发生在不同的对象上会产生不同的结果。
36. 什么是多态机制?Java语言是如何实现多态的?
39. 面向对象五大基本原则是什么(可选)
40. 接口
1. 接口的修饰符:接口默认只能是abstract ,可加可不加。还可以加public
public abstract interface test{ }
2. 接口中字段的修饰符:
public abstract interface test{ int age = 10;
//实际上为 public static final int age = 10; }
public: 使接口的实现类可以使用这个常量
static:接口不涉及和任何具体实例相关的细节,因此接口没有构造方法,不能被实例化,没有实例变量,只有静态(static)变量。
static修饰就表示它属于类的,随的类的加载而存在的,当JVM把字节码加载进JVM的时候,static修饰的成员已经在内存中存在了。
如果是非static的话,就表示属于对象的,只有建立对象时才有它,而接口是不能建立对象的,所以接口的常量必须定义为static。
final:
接口中不可以定义变量即定义的变量前都要加上final修饰,使之成为常量(没有final修饰的是变量,加上final修饰就会变成常量)。所以接口的属性默认是public static final 常量,且必须赋初值。( final修饰就是保证接口定义的常量不能被实现类去修改,如果没有final的话,由子类随意去修改的话,接口建立这个常量就没有意义了。)
3. 接口中方法的修饰符:
41. 抽象类
1. 抽象类的概念
普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。
那么什么叫抽象方法呢?在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。
而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。
范例:定义一个抽象类
abstract class A{//定义一个抽象类 public void fun(){//普通方法 System.out.println("存在方法体的方法"); } public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰 }
2. 抽象类的使用原则如下:
(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);
39. 普通类和抽象类有哪些区别?
- 普通类不能包含抽象方法,抽象类可以包含抽象方法。
- 抽象类不能直接实例化,普通类可以直接实例化。
40. 抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 fifinal 该类就不能被继承,这样彼此就会产生矛盾,所以 fifinal 不能修饰抽象类
41. 创建一个对象用什么关键字?对象实例与对象引用有何不同?
变量与方法
42. 成员变量与局部变量的区别有哪些
43. 在Java中定义一个不做事且没有参数的构造方法的作用
44. 在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?
帮助子类做初始化工作。
45. 一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么?
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法
46. 构造方法有哪些特性?
- 名字与类名相同;
- 没有返回值,但不能用void声明构造函数;
- 生成类的对象时自动执行,无需调用。
47. 静态变量和实例变量区别
48. 静态变量与普通变量区别
49. 静态方法和实例方法有何不同?
50. 在一个静态方法内调用一个非静态成员为什么是非法的?
- 由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。
51. 什么是方法的返回值?返回值的作用是什么?
内部类
52. 什么是内部类?
53. 内部类的分类有哪些
54. 内部类的优点
55. 内部类有哪些应用场景
- 一些多算法场合
- 解决一些非面向对象的语句块。
- 适当使用内部类,使得代码更加灵活和富有扩展性。
- 当某个类除了它的外部类,不再被其他的类使用时。
56. 局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?
57. 内部类相关,看程序说出运行结果
构造器(constructor)是否可被重写(override)?
构造器不能被继承,因此不能被重写,但可以被重载。
重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
- 方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
- 重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分
- 重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写。
== 和 equals 的区别是什么
hashcode()介绍
hashCode()的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。
散列表存储的是键值对(key-value),它的特点是:能根据′"键"快速的检索出对应的“值"。这其中就利用到了散列码!(可以快速找到所需要的对象)
为什么要有hashCode?
我们以"Hashset 如何检查重复"为例子来说明为什么要有 hashcode:
当你把对象加入HashSet时,HashSet 会先计算对象的 hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了equals 的次数,相应就大大提高了执行速度。
请解释hashCode()和equals()方法有什么联系?
1. 如果两个对象相等,则hashcode一定也是相同的
2. 两个对象相等,对两个对象分别调用equals方法都返回true
3. 两个对象有相同的hashcode值,它们也不一定是相等的
hashCode 与 equals (重要)
62. 对象的相等与指向他们的引用相等,两者有什么不同?
- 对象的相等 比的是内存中存放的内容是否相等而 引用相等 比较的是他们指向的内存地址是否相等。
值传递
63. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递
64. 为什么 Java 中只有值传递
65. 值传递和引用传递有什么区别
Java包
66. JDK 中常用的包有哪些
- java.lang:这个是系统的基础类;
- java.io:这里面是所有输入输出有关的类,比如文件操作等;
- java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
- java.net:这里面是与网络有关的类;
- java.util:这个是系统辅助类,特别是集合类;
- java.sql:这个是数据库操作的类。
67. import java和javax有什么区别
四、IO流
68. java 中 IO 流分为几种?
69. BIO,NIO,AIO 有什么区别?
70. Files的常用方法都有哪些?
- Files. exists():检测文件路径是否存在。
- Files. createFile():创建文件。
- Files. createDirectory():创建文件夹。
- Files. delete():删除一个文件或目录。
- Files. copy():复制文件。
- Files. move():移动文件。
- Files. size():查看文件个数。
- Files. read():读取文件。
- Files. write():写入文件。
五、反射
71. 什么是反射机制?
72. 反射机制优缺点
73. 反射机制的应用场景有哪些?
74. Java获取反射的三种方法
六、常用API
String相关
1. 字符型常量和字符串常量的区别
1. 形式上:字符常量是单引号引起的一个字符字符串常量是双引号引起的若干个字符
2. 含义上:字符常量相当于-个整形值(ASCI值)可以参加表达式运算字符串常量代表一个地址值(该字符串在内存中存放位置)
3. 占内存大小字符常量只占-一个字节字符串常量占若千个字节(至少-一个字符结束标志)
2. 解释一下什么是字符串常量池?
在理解字符串常量前,我们先熟悉一下如何创建一个字符串,在Java中有两种方法可以创建一个字符串对象:
- 使用new运算符。例如:
String str = new String("Hello");
- 使用字符串常量或者常量表达式。例如:
String str="Hello"; //(字符串常量) 或者 String str="Hel" + "lo"; //(字符串常量表达式).
public class DemoStringCreation { public static void main(String args[]) { String str1 = "Hello"; String str2 = "Hello"; System.out.println("str1 and str2 are created by using string literal."); System.out.println(" str1 == str2 is " + (str1 == str2)); System.out.println(" str1.equals(str2) is " + str1.equals(str2)); String str3 = new String("Hello"); String str4 = new String("Hello"); System.out.println("str3 and str4 are created by using new operator."); System.out.println(" str3 == str4 is " + (str3 == str4)); System.out.println(" str3.equals(str4) is " + str3.equals(str4)); String str5 = "Hel" + "lo"; String str6 = "He" + "llo"; System.out.println("str5 and str6 are created by using string constant expression."); System.out.println(" str5 == str6 is " + (str5 == str6)); System.out.println(" str5.equals(str6) is " + str5.equals(str6)); String s = "lo"; String str7 = "Hel" + s; String str8 = "He" + "llo"; System.out.println("str7 is computed at runtime."); System.out.println("str8 is created by using string constant expression."); System.out.println(" str7 == str8 is " + (str7 == str8)); System.out.println(" str7.equals(str8) is " + str7.equals(str8)); } }
输出结果为:
str1 and str2 are created by using string literal. str1 == str2 is true str1.equals(str2) is true str3 and str4 are created by using new operator. str3 == str4 is false str3.equals(str4) is true str5 and str6 are created by using string constant expression. str5 == str6 is true str5.equals(str6) is true str7 is computed at runtime. str8 is created by using string constant expression. str7 == str8 is false str7.equals(str8) is true
字符串专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空
间存储相同的字符串,在创建字符串时JVM会首先检查字符串常量池,如果该字符串已经存在池
中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。
3. 字符串常量池在哪里?
不清楚
4. String 是最基本的数据类型吗
5. String有哪些特性
6. String为什么是不可变的吗?
7. String真的是不可变的吗?
9. 是否可以继承 String 类
String 类是 fifinal 类,不可以被继承。
10. String str="i"与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。
String str="i"的方式,java 虚拟机会将其分配到常量池中:常量池不会重复创建对象。
而 String str=new String(“i”) 则会被分到堆内存中:堆内存会创建新的对象。
11. String s = new String(“xyz”);创建了几个字符串对象
首先在string池内找,找到?不创建string对象,否则创建, 这样就一个string对象
遇到new运算符号了,在内存上创建string对象,并将其返回给s,又一个对象
所以总共是2个对象
12. 如何将字符串反转?
13. 数组有没有 length()方法?String 有没有 length()方法
数组没有 length()方法 ,有 length 的属性。String 有 length()方法。JavaScript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。
14. String 类的常用方法都有那些?
- indexOf():返回指定字符的索引。
- charAt():返回指定索引处的字符。
- replace():字符串替换。
- trim():去除字符串两端空白。
- split():分割字符串,返回一个分割后的字符串数组。
- getBytes():返回字符串的 byte 类型数组。
- length():返回字符串长度。
- toLowerCase():将字符串转成小写字母。
- toUpperCase():将字符串转成大写字符。
- substring():截取字符串。
- equals():字符串比较。
15. 在使用 HashMap 的时候,用 String 做 key 有什么好处?
HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。
16. String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的
包装类相关
1. 自动装箱与拆箱
- 装箱:将基本类型用它们对应的引用类型包装起来;
- 拆箱:将包装类型转换为基本数据类型;
2. int 和 Integer 有什么区别
3. Integer a= 127 与 Integer b = 127相等吗
最后