写在前面: 整份Java八股文 的整理贯穿我的整个秋招,希望可以给大家带来帮助,如果对你有一定的作用,欢迎大家转发点赞,谢谢!在复习Java八股文的过程中,有两位老哥的博文对我帮助比较大,质量也非常不错,推荐大家去阅读:JavaGuide(Java学习&&面试指南) 、Java程序员进阶之路 如果有想要pdf版本的友友,可以私信我,谢谢大家点赞转发。我将分模块持续更新Java面试的相关知识,希望可以对你有所帮助。
Java基础
一、基础概念
1、Java语言的特点
① 平台无关性 (Java虚拟机实现平台无关性,即一次编写,到处运行); ② 面向对象 (封装、继承、多态); ③ 安全的内存管理和访问机制,避免大部分内存泄漏和指针越界; ④ 完善的应用程序接口,支持第三方类库; ⑤ ⽀持多线程 (C++语言没有内置的多线程机制); ⑥ 支持网络编程 (提供了java.net包,以编程方式访问Web服务的功能); ⑦ 编译和解释共存。
2、JVM vs JRE vs JDK
JVM: Java Virtual Machine,Java虚拟机,Java程序运行在Java虚拟机上。针对不同系统的实现(Windows,Linux,macOS)不同的JVM,因此Java语言可以实现跨平台。字节码和不同系统的JVM是Java语言“一次编写,随处运行”的关键所在。JRE: Java运行时环境。它是运行已编译Java程序所需的所有内容的集合,包括Java虚拟机(JVM),Java类库,Java命令和其他的一些基础构件。但是,它不能用于创建新程序。JDK: Java Development Kit,Java开发工具,它是功能齐全的Java SDK。它拥有JRE所拥有的⼀切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。 简单来说,JDK包含JRE,JRE包含JVM。
Q:什么是Java跨平台?原理是什么?
所谓跨平台性,是指Java语言编写的程序,一次编译后,可以在多个系统平台上运行 。 实现原理: Java程序是通过Java虚拟机在系统平台上运行的,只要该系统可以安装相应的Java虚拟机,该系统就可以运行java程序。
3、什么是字节码?采用字节码的好处是什么?
所谓的字节码,就是Java程序经过编译之后产生的.class文件 ,它不面向任何特定的处理器,只面向虚拟机,从而实现Java程序的跨平台性。 Java程序从源代码到运行主要有3步:
编译:将我们的代码(.java)编译成虚拟机可以识别理解的字节码(.class)。 解释:虚拟机执行Java字节码,将字节码翻译成机器能识别的机器码。 执行:对应的机器执行二进制机器码。 只需要把Java程序编译成Java虚拟机能识别的Java字节码,不同的平台安装对应的Java虚拟机,这样就可以实现Java语言的平台无关性。
4、为什么说Java语言“编译与解释共存”?
高级编程语言按照程序的执行方式分为2种:
编译型: 编译型语言是指编译器 针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码。编译语言执行速度较快,开发效率低,如:C、C++、Go、Rust等。解释型:解释型语言是指解释器 对源程序逐行解释成特定平台的机器码并立即执行。解释型语言开发效率快,执行速度慢,如:Python、JavaScript、PHP等。 **举例:**你想读一本外国的小说,你可以找一个翻译人员帮助你翻译,有两种选择方式,你可以先等翻译人员将全本的小说(也就是源码)都翻译成汉语,再去阅读,也可以让翻译人员翻译一段,你在旁边阅读一段,慢慢把书读完。
Q:为什么说Java是编译和解释共存? 这是因为Java语言既具有编译型语言的特征,也具有解释型语言的特征。因为Java程序要经过先编译,后解释两个步骤,由Java编写的程序需要先经过编译步骤,生成字节码(.class文件),生成的字节码再通过JVM解释器,解释成操作系统能够识别的机器码,最后执行。
5、Java和C++的区别?
首先,Java和C++都是面向对象的语言,都支持封装、继承和多态 。它们的区别在:
Java不提供指针 来直接访问内存,程序内存更加安全。 Java的类是单继承 的,C++支持多重继承 ;虽然Java的类不可以多继承,但是接口可以多继承。 Java有自动内存管理垃圾回收机制(GC) ,不需要程序员手动释放无用内存。 C++同时支持方法重载和操作符重载,但是Java只支持方法重载 (操作符重载会增加复杂性)。
6、为什么Java中只有值传递?
具体参考 JavaGuide(Java学习&&面试指南) 写的相当不错👍👍👍
7、Java的访问修饰符
二、基础语法
1、注释的形式
2、关键字和标识符的区别
1、Java中的关键字有哪些?
2、自增自减运算符
3、continue、break和return的区别?
break:结束当前的循环体,不再执行循环,继续执行循环后面的代码; continue:结束正在执行的循环,继续执行下次循环; return:结束当前的方法,不再执行下面的代码。
3、成员变量和局部变量的区别?
Q:静态变量的作用?
静态变量可以被类的所有实例共享(内存中只有一份) 。无论一个类创建了多少对象,他们都共享一份静态变量。通常情况下,静态变量会被 final 修饰称为常量。
Q:字符型常量和字符串型常量的区别?
形式:字符常量是单引号引起的1个字符;字符串常量是双引号引起的0个或若干个字符。 含义:字符常量相当于一个整型值(ASCll值),可以参加表达式运算;字符串常量代表一个地址值(该字符串在内存中存放位置)。 占内存大小:字符常量只占2个字节;字符串常量占若干个字节。 注意: char 在Java中占两个字节。
4、什么是方法的返回值?方法有哪几种类型?
方法的返回值 是指我们获取到的某个方法体中的代码执行后产生的结果。方法可分为如下4种:无参无返回值、无参有返回值、有参无返回值、有参有返回值。
5、静态方法为什么不能调用非静态成员?
6、静态方法和实例方法有何不同?
7、重载和重写的区别?
重载: 发生在同一个类中(或者父类和子类之间),方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同(不做要求)。 重写: 重写发生在运行期,是子类对父类的允许访问的方法的实现过程进行重新编写。
方法名、参数列表必须相同,子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。 如果父类方法访问修饰符为private/final/static则子类就不能重写该方法,但是被static修饰的方法能够被再次声明。 构造方法无法被重写。 方法的重写要遵循“两同两小—大": -“两同”, 即方法名相同、形参列表相同; “两小” 指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;(如果子类抛出的异常>父类,那么父类无法接收,则无法实现多态)“—大” 指的是子类方法的访问权限应比父类方法的访问权限更大或相等。 注意: 重写的返回值类型:如果方法的返回类型是void和基本数据类型,则返回值重写时不可修改。但是如果方法的返回值是引用类型,重写时是可以返回该引用类型的子类的。
Q:什么是可变长参数?
从Java5开始,Java支持定义可变长参数,所谓可变长参数就是允许在调用方法时传入不定长度的参数。但可变参数只能作为函数的最后一个参数,其前面可以有也可以没有任何其他参数。
Q:遇到方法重载怎么办呢?会优先匹配固定参数还是可变参数的方法呢?
会优先匹配固定参数的方法,因为固定参数的方法匹配度更高。
8、static关键字
static表示静态或者全局,可以用来修饰成员变量和成员方法以及代码块。 使用static修饰的成员变量和成员方法独立于该类的任何一个实例化对象,访问时不依赖于该类的对象,而是直接通过类去访问,可以理解为被该类的所有实例对象所共用,所以说是全局的。 静态变量访问方式: ①类.属性;②对象.属性。 非静态变量访问方式: ①对象.属性。 static还可以修饰代码块,被static修饰的代码块叫做静态代码块。
Q:静态代码块的特点是只执行一次,什么时候执行?
当这个类被加载到内存时执行,不需要开发者手动调用,会自动执行。 被加载到内存中的类叫做运行时类,静态代码块就是在加载类的时候执行的,因为 类只加载一次,所以静态代码块也只执行一次 。
Q:代码块的执行顺序?
代码块执行顺序: 静态代码块 --> 普通代码块 --> 构造函数 继承中代码块执行顺序: 父类静态块 --> 子类静态块 -->父类普通代码块 --> 父类构造函数 --> 子类普通代码块 --> 子类构造函数
9、& 和 && 的区别?
& 运算符有两种用法: &&短路与、&逻辑与。 短路与第一个条件成立才会判断第二个条件。 &&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。 &&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&。 例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。 注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
三、基本数据类型
1、Java基本数据有哪些?
Q:Java自动数据类型转换和强制类型转换
Java 所有的数值型变量可以相互转换,当把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量时,可以进行自动类型转换;反之,需要强制转换。 这就好像,小杯里的水倒进大杯没问题,但大杯的水倒进小杯就不行了,可能会溢出。
float f=3.4,对吗?不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4;或者写成float f =3.4F 。 short s1 = 1; s1 = s1 + 1;对吗?short s1 = 1; s1 += 1;对吗? 对于short s1 = 1; s1 = s1 + 1;编译出错,由于1是int类型,因此s1+1运算结果也是int型,需要强制转换类型才能赋值给short型。 而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short(s1 + 1);其中有隐含的强制类型转换(复合运算符)。
Q:Java中的引用类型有?
引用类型有3个,分别是类、接口、数组。
2、基本类型和包装类的区别
3、自动装箱和自动拆箱
装箱:将基本类型用它们对应的引用类型 包装起来。 拆箱:将包装类型转换为基本数据类型 。 Java可以自动对基本数据类型和它们的包装类进行装箱和拆箱。
4、包装类的缓存机制
**★注意:**需要注意Integer包装类的范围是[-128,127],超过这个范围会在堆中创建对象。
注意: float和double没有实现缓存机制。
5、为什么浮点数运算的时候会有精度丢失的风险?
6、如何解决浮点数运算的精度丢失问题?