共含208道面试题,涵盖十九个模块:从 Java 基础到框架再到JVM,提供详细解读和代码案例,让你知其然还知其因此然java
这份面试题总内容包含了十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM
mysql
JDK 和 JRE 有什么区别?程序员
JDK: Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境
JRE: Java Runtime Environment 的简称,Java 运行环境,为 Java 运行提供环境web
具体来讲,JDK 包括 JRE,同时还包含了编译 Java 源码的编译器 javac,还包含了Java程序调试和分析的工具面试
== 和 equals 的区别是什么?
equals :基本类型,比较两个值是否相等
== :引用类型,比较的是引用是否相等redis
package cn_lemon; public class Test { public static void main(String[] args) { String s1 = "string"; String s2 = "string"; String s3 = new String("string"); System.out.println(s1 == s2);//true System.out.println(s1 == s3);//false System.out.println(s1.equals(s2));//true System.out.println(s1.equals(s3));//true } }
在上面的的代码中,s1 和 s2 指向的是同一个引用,而 new String()
方法则是重写,在堆里开辟了内存空间。
equals 原意:等于。本质上就是 ==,只不过 String 和 Integer 重写了equals 方法,把它变成了值比较。
实例代码:算法
package cn_lemon; public class Person { String name; public Person(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package cn_lemon; public class Test { public static void main(String[] args) { Person p1 = new Person("Lemon"); Person p2 = new Person("Lemon"); System.out.println(p1.equals(p2)); } }
运行结果是 false;spring
若是只写一个类,以下:sql
package cn_lemon; public class Test { public static void main(String[] args) { String p1 = new String("Lemon"); String p2 = new String("Lemon"); System.out.println(p1.equals(p2)); } }
运行结果是:true数据库
一样的,咱们进入 String 的 equal 方法,看一下,代码以下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
原来是 String 重写了 Object 的 equals 方法,把引用比较改为了值比较。
总结: == 对于基本类型的值来讲是值比较,对于引用类型来讲比较的是引用;而 equals 默认状况下是引用比较,只是不少类从新了 equals 方法,好比 String、Integer 等把它变成了值比较,因此通常状况下 equals 比较的是值是否相等
package cn_lemon; class Test{ public static void main(String[] args) { String str1 = "通话"; String str2 = "重地"; System.out.println(" str1 的哈希值为:" + str1.hashCode()); System.out.println(" str2 的哈希值为:" + str2.hashCode()); System.out.println(str1.equals(str2)); } }
运行显示:
在应用程序的执行期间,只要对象的equals方法的比较操做所用到的信息没有被修改,那么对这同一个对象调用屡次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的屡次执行过程当中,每次执行所返回的整数能够不一致。
若是两个对象根据equal(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须返回一样的整数结果。
若是两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不必定要产生不一样的整数结果。可是程序员应该知道,给不相等的对象产生大相径庭的整数结果,有可能提升散列表的性能。
在散列表中,hashCode() 相等即两个键值对的哈希值相等,然而哈希值相等,并不必定能得出键值对相等
final 在 java 中有什么做用?
final 修饰类,叫最终类,该类不能被继承
final 修饰的方法不能被重写
final 修饰的常量叫变量,常量必须初始化,初始化以后的值不能被修改
java 中的 Math.round(-1.5) 等于多少?
package cn_lemon; public class Demo { public static void main(String[] args) { System.out.println(Math.round(-1.4));//-1 System.out.println(Math.round(-1.5));//-1 System.out.println(Math.round(-1.6));//-2 System.out.println("-----------------"); System.out.println(Math.round(-2.4));//-2 System.out.println(Math.round(-2.5));//-2 System.out.println(Math.round(-2.6));//-3 System.out.println("================="); System.out.println(Math.round(1.4));//1 System.out.println(Math.round(1.5));//2 System.out.println(Math.round(1.6));//2 System.out.println("+++++++++++++++++"); System.out.println(Math.round(2.4));//2 System.out.println(Math.round(2.5));//3 System.out.println(Math.round(2.6));//3 } }
等于 -1,由于在数轴上取值时,中间值(0.5)向右取整,因此正 0.5 是往上取整,负 0.5 是直接舍弃。
String 属于基础的数据类型吗?
String 不属于基础类型,基础类型有8种:byte、short、int、long、float、double、Boolean、char ,而 String 属于对象
java 中操做字符串都有哪些类?它们之间有什么区别?
操做字符串的类有:String、StringBuffer、StringBuilder
String 声明的是不可变的对象,每次操做都会生成新的对象,而后将指针指向新的对象。
StringBuffer 和 StringBuilder 能够在原有对象的基础上进行操做,因此常常改变字符串的内容。StringBuffer 是线程安全的,StringBuilder 是非线程安全的,但 StringBuilder 的性能高于 StringBuffer,因此建议多线程下使用StringBuffer,单线程下使用 StringBuilder
了解更多详情:请点击
String str="i"与 String str=new String(“i”)同样吗?
不同,内存的分配方式不同,前者会被 Java 虚拟机分配到常量池,然后者会被分到堆内存
如何将字符串反转?
使用 StringBuffer 的 reverse 方法,或者使用 StringBuilder 的 reverse 方法
package cn_lemon; class Demo{ public static void main(String[] args){ StringBuffer str1 = new StringBuffer(); str1.append("abcdefg"); System.out.println(str1.reverse());//使用 StringBuffer 的 reverse 方法 StringBuilder str2 = new StringBuilder(); str2.append("abcdefg"); System.out.println(str2.reverse());//使用 StringBuilder 的 reverse 方法 } }
String 类的经常使用方法都有那些?
indexOf() : 返回指定字符的索引
charAt() : 返回指定索引处的数组
replace() : 字符串替换
trim() : 去除字符串两端空白
split() : 分割字符串,返回一个分割后的字符串数组
getBytes() : 返回字符串的 byte 类型的数组
length() : 返回字符串的长度
toLowerCase() : 将字符串转换成小写
toUpperCase() : 将字符串转换成大写
substring() : 截取字符串
equals() : 字符串比较
了解更多详情:请点击
抽象类必需要有抽象方法吗?
不须要,有抽象方法的 Java 类必定是抽象类,抽象类里不必定有抽象方法
了解更多详情:请点击
普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类能够包含抽象方法(在第11题中,能够看出);
抽象类不能直接实例化(不过能够以多态的方式由其具体的子类实例化),普通类能够直接实例化。
了解更多详情:请点击
抽象类能使用 final 修饰吗?
不能,final 修饰类了之后就不能被继承(抽象类就是用来被继承的)
接口和抽象类有什么区别?
接口用 interface 声明、implement 实现;抽象类用 abstract 声明、extends 继承
接口不能由构造函数,而抽象类能够
接口中的方法默认使用 public ,抽象类中的方法可使用任意修饰符
类能够实现不少接口,类只能继承一个类
了解更多详情:请点击
java 中 IO 流分为几种?
按流向划分:输入流与输出流
输入流:只能从中读取数据,不能写入 输出流:只能写入数据,不能读取数据
按操做单元划分:字节流与字符流
字节流:操做单元是8位的字节,主要是 InputStream 和 OutputStream 做为基类 字符流:操做单元是16位的字符,主要是 Reader 和 Writer 做为基类
了解更多详情:请点击
并行和并发有什么区别?
线程和进程的区别?
守护线程是什么?
建立线程有哪几种方式?
说一下 runnable 和 callable 有什么区别?
线程有哪些状态?
sleep() 和 wait() 有什么区别?
notify()和 notifyAll()有什么区别?
线程的 run()和 start()有什么区别?
建立线程池有哪几种方式?
线程池都有哪些状态?
线程池中 submit()和 execute()方法有什么区别?
在 java 程序中怎么保证多线程的运行安全?
多线程锁的升级原理是什么?
什么是死锁?
怎么防止死锁?
ThreadLocal 是什么?有哪些使用场景?
说一下 synchronized 底层实现原理?
synchronized 和 volatile 的区别是什么?
synchronized 和 Lock 有什么区别?
synchronized 和 ReentrantLock 区别是什么?
说一下 atomic 的原理?