2024.2.23 Java基础
1.Java语言有哪些特点?
首先,Java语言是纯粹的面向对象编程语言,这意味着它支持面向对象的核心概念,比如封装、继承和多态。这就让你可以更方便地组织和管理你的代码。
Java还具有平台无关性,这是因为它的代码在执行时不是直接在硬件上运行,而是在Java虚拟机(JVM)上运行。这意味着你可以编写一次代码,然后在不同的操作系统和硬件上运行,只要有对应的JVM就行,这极大地提高了代码的可移植性。
另一个Java的特点就是支持多线程编程和网络编程。这意味着你可以同时处理多个任务,或者轻松地编写涉及网络通信的程序,让你的应用更加强大和灵活。
Java非常可靠,因为它具备异常处理和自动内存管理机制。这意味着即使出现错误,你的程序也能够优雅地处理,而且Java会自动帮你管理内存,减少了出现内存泄漏等问题的可能性。
安全性是Java的另一个重要特点。Java提供了多重安全防护机制,比如访问权限修饰符和安全管理器,这可以防止程序访问不应该访问的资源,提高了系统的安全性。
尽管Java是解释性语言,但通过Just In Time编译器等技术的优化,Java的运行效率相当不错,这使得它适用于各种性能要求较高的应用场景。
2.Java和C++的相同点和区别?
虽然,Java 和 C++ 都是面向对象的语言,都支持封装、继承和多态。但是,它们还是有挺多不相同的地方:
- Java 不提供指针来直接访问内存,程序内存更加安全;
- Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承;
- Java 有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存。
- C ++同时支持方法重载和操作符重载,但是 Java 只支持方法重载(操作符重载增加了复杂性,这与 Java 最初的设计思想不符)。
3.什么是字节码?采用字节码具有什么样的好处?
在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class
的文件),它不面向任何特定的处理器,只面向虚拟机。字节码文件是通过javac进行编译得到的。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以, Java 程序运行时相对来说还是高效的(不过,和 C、 C++,Rust,Go 等语言还是有一定差距的),而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。
Java 程序从源代码到运行的过程如下图所示:
4.为什么说Java语言是编译与解释共存的语言?
我们可以将高级编程语言按照程序的执行方式分为两种:
- 编译型:编译型语言会通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般情况下,编译语言的执行速度比较快,开发效率比较低。常见的编译性语言有 C、C++、Go、Rust 等等。
- 解释型:解释型语言会通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。解释型语言开发效率比较快,执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。
而Java 语言既具有编译型语言的特征,也具有解释型语言的特征。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class
文件),这种字节码必须由 Java 解释器来解释执行。
5.JVM vs JDK vs JRE?
JVM(Java Virtual Machine,Java虚拟机) 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。
JDK(Java Development Kit,Java开发者工具)是功能齐全的 Java SDK,是提供给开发者使用,能够创建和编译 Java 程序的开发套件。它包含了 JRE,同时还包含了编译 java 源码的编译器 javac 以及一些其他工具比如 javadoc(文档注释工具)、jdb(调试器)、jconsole(基于 JMX 的可视化监控⼯具)、javap(反编译工具)等等。
JRE(Java Runtime Environment) 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,主要包括 Java 虚拟机(JVM)、Java 基础类库(Class Library)。
JDK包含JRE,JRE包含JVM。
6.Java的基本数据类型?
4种整形(byte、short、int、long)+2种浮点(float、double)+字符(char)+布尔(boolean)
7.基本类型与包装类型的区别?
用途:除了定义一些常量和局部变量之外,我们在其他地方比如方法参数、对象属性中很少会使用基本类型来定义变量。并且,包装类型可用于泛型,而基本类型不可以。
存储方式:基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 static
修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。
占用空间:相比于包装类型(对象类型), 基本数据类型占用的空间往往非常小。
默认值:成员变量包装类型不赋值就是 null
,而基本类型有默认值且不是 null
。
比较方式:对于基本数据类型来说,==
比较的是值。对于包装数据类型来说,==
比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用 equals()
方法。
8.包装类型的缓存机制了解么?
Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。Byte
,Short
,Integer
,Long
这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character
创建了数值在 [0,127] 范围的缓存数据,Boolean
直接返回 True
or False
。记住:所有整型包装类对象之间值的比较,全部使用 equals 方法比较。
9.自动装箱与拆箱了解吗?原理是什么?
装箱是将基本类型用它们对应的引用类型包装起来,而拆箱则是将包装类型转换为基本数据类型。自动装箱和拆箱就指的是自动实现拆箱和装箱的操作,而不需要程序员去手动操作。装箱的基本原理是调用包装类的valueOf()
方法,拆箱其实就是调用了 xxxValue()
方法。
10.为什么浮点数运算的时候会有精度丢失的风险?
这个和计算机保存浮点数的机制有很大关系。计算机采用二进制存储数据,而且计算机在表示一个数字时,宽度是有限的。无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况。这也就是解释了为什么浮点数没有办法用二进制精确表示。
11.如何解决浮点数运算的精度丢失问题?
我们使用BigDecimal
类来解决这个问题。BigDecimal
可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过 BigDecimal
来做的。
12.超过 long 整型的数据应该如何表示?
我们使用BigInteger
类来解决这个问题。BigInteger
内部使用 int[]
数组来存储任意大小的整形数据。相对于常规整数类型的运算来说,BigInteger
运算的效率会相对较低。