Java企业面试题2

1.语言的分代:

第1代:机器语言
机器语言是最底层的计算机编程语言,它是由二进制数构成的一系列指令,直接与计算机硬件交互。每个二进制位模式代表一条特定的指令或数据地址。因为它是直接在硬件上执行的,所以运行效率非常高,但是编写和维护代码非常困难,并且不便于移植到其他类型的计算机上。

第2代:汇编语言
汇编语言是对机器语言的一种符号化表示,它使用助记符(mnemonics)来代替二进制指令码,使得程序更容易阅读和编写。尽管汇编语言比机器语言更易于理解,但它仍然是一种与硬件紧密相关的语言,每一种处理器架构都需要不同的汇编语言。此外,汇编语言仍然是面向机器的,而不是面向问题的。

第3代:高级语言
高级语言是为了解决汇编语言的局限性而发展起来的,它们更接近自然语言,提供了更多的抽象层次。高级语言通常包括控制结构(如条件语句和循环)、数据类型、子程序等特性,使得程序员能够以更自然的方式表达算法和解决问题。

  • 面向过程的语言:C

        C语言是一种中级语言,它结合了高级语言的便利性和汇编语言的灵活性。C语言提供了对内存的直接访问和其他底层操作,这使得它非常适合于系统编程,如操作系统或编译器的开发。C语言也是很多现代编程语言的基础。

  • 面向对象的语言

        面向对象编程(OOP)是一种编程范式,它使用“对象”——数据和可以作用于这些数据上的方法的集合——来设计应用程序和计算机程序。面向对象的语言支持封装、继承和多态性等特性。

  •         C++ 是C语言的一个扩展,引入了面向对象的概念,同时保留了对底层硬件的访问能力。C++被广泛用于游戏开发、嵌入式系统和高性能应用。
  • Java 是一种完全的面向对象语言,强调平台无关性。Java代码可以在任何安装了Java虚拟机(JVM)的平台上运行,这使得Java成为企业级应用开发和安卓应用开发的主要语言之一。
  •         C# 是由微软开发的一种面向对象语言,它为.NET框架提供支持。C#融合了C++和Java的优点,并增加了许多现代化的功能,适用于Web应用程序、桌面应用程序等多种领域。
  •         Python 是一种解释型的、面向对象的动态语言,以其简洁清晰的语法著称。Python广泛应用于快速原型制作、脚本编写、数据分析、人工智能等领域。
  •         Go 是由Google设计的一种静态类型、编译型的并发语言。Go语言简单高效,特别适合网络服务器、数据管道和大规模生产系统。
  •         JavaScript 最初是为了在浏览器中实现客户端脚本而设计的,但现在也广泛用于服务器端编程(例如Node.js)。JavaScript支持事件驱动、函数式编程和基于原型的编程风格。

2.Java 平台有三个主要版本

        分别针对不同类型的计算环境。下面是对 JavaSE、JavaEE 和 JavaME 的简要介绍:

  • JavaSE (Java Platform, Standard Edition)

        JavaSE 提供了标准版的 Java 平台,包含了开发一般桌面和商务应用程序的所有必要组件。它定义了 Java 编程语言的核心 API,包括基本的数据类型、线程管理、文件 I/O、网络编程等功能。JavaSE 是构建桌面应用程序和跨平台服务端应用程序的基础,也是学习 Java 编程的起点。

  • JavaEE (Java Platform, Enterprise Edition),现称为 Jakarta EE

        JavaEE 原先是 Sun Microsystems 开发的企业级 Java 平台,后来 Sun Microsystems 被 Oracle 收购后继续发展。2018 年,随着 JavaEE 规范被移交给 Eclipse Foundation,它被重新命名为 Jakarta EE。Jakarta EE 提供了一套企业级应用开发的标准,包括 Web 服务、组件模型、管理和通信 API 等。Jakarta EE 在 JavaSE 的基础上增加了一系列企业级功能,比如 EJB(Enterprise JavaBeans)、JPA(Java Persistence API)、JMS(Java Message Service)、Servlets、JSP(JavaServer Pages)、JSF(JavaServer Faces)等。这些技术让开发者能够构建复杂的、分布式的、可伸缩的应用程序。

  • JavaME (Java Platform, Micro Edition)

        JavaME 是为嵌入式设备和消费电子产品设计的 Java 平台。它为资源受限的设备(如手机、PDA 和电视顶盒)提供了一个配置和可选的 Profile 层。配置是指一个特定的虚拟机和一组核心类库,而 Profile 则是在配置之上添加的一组特定的 API。JavaME 包括了多种配置,如 CLDC(Connected Limited Device Configuration)和 CDC(Connected Device Configuration),以及相应的 Profile,如 MIDP(Mobile Information Device Profile)用于移动设备。

每个版本的 Java 都有其特定的目标和用途。JavaSE是构建大多数普通应用程序的基础;JavaEE针对企业级应用,提供了一整套开发工具和服务;而 JavaME 则专注于嵌入式系统和移动设备。根据你的开发需求,你可以选择合适的 Java 版本来进行开发。

3.一个”.java”源文件中是否可以包括多个类?有什么限制?

在一个.java源文件中可以有多个类,但最多只能有一个公共类,并且这个公共类的名字必须与源文件名一致。其余的类可以是非公共的,并且可以有多个。这样的规定有助于保持代码的组织清晰,并且使得编译器能够正确地识别和处理这些类。

4.Java 的优势

跨平台性(Write Once, Run Anywhere)

  • Java程序可以在任何安装了Java虚拟机(JVM)的平台上运行,无需修改代码。这意味着一次编写的应用程序可以在不同的操作系统(如Windows、Linux、macOS等)上运行。

面向对象

  • Java是一种面向对象的编程语言,它支持封装、继承和多态等面向对象的特性,有助于构建可维护和可扩展的软件。

丰富的API和库

  • Java拥有庞大的标准库,提供了丰富的类和接口,覆盖了从基础数据结构到网络编程、图形用户界面(GUI)等各个方面的功能。

自动垃圾回收

  • Java有自动垃圾回收机制,这减轻了程序员管理内存的负担,降低了内存泄漏和其他内存相关错误的风险。

安全性

  • Java设计时考虑了安全性,例如,它有沙箱执行环境的概念,限制了代码对系统资源的访问,从而减少了恶意代码的潜在风险。

多线程支持

  • Java内置了对多线程编程的支持,使得开发并发应用程序变得相对简单。

健壮性

  • Java语言的设计强调类型检查和异常处理,有助于编写出更稳定、错误更少的代码。

企业级支持

  • Java是企业级应用开发的首选语言之一,许多大型企业系统和金融服务系统都是用Java开发的。Java EE(现在称为Jakarta EE)为企业级应用提供了丰富的规范和框架。

社区和生态系统

  • Java拥有庞大的开发者社区和成熟的生态系统,这意味着有丰富的学习资源、工具、框架和第三方库可供使用。

良好的性能

  • 虽然Java通常不被认为是性能最高的语言,但随着JVM的不断优化和即时编译技术的进步,Java的性能已经非常接近甚至在某些方面超过了传统的编译型语言。

跨行业的应用

  • Java广泛应用于金融服务、电子商务、移动应用(Android)、大数据处理、云计算等领域。

持续的更新和发展

  • Oracle和Java社区持续对Java语言进行更新和改进,确保它能够适应新的技术趋势和市场需求。

5.常用的几个命令行操作都有哪些?

  • javac

        javac 是 Java 编译器,用来将 Java 源代码编译成字节码(.class 文件)。使用示例:

javac HelloWorld.java

        这条命令会将 HelloWorld.java 文件编译成 HelloWorld.class 字节码文件。

  • java

        java 命令用于启动 Java 虚拟机(JVM),并执行指定的类(该类必须包含一个主方法 main 方法)。使用示例:

java HelloWorld

        这条命令会执行 HelloWorld.class 文件中的主方法 public static void main(String[] args)。

  • jar

        jar 命令用于创建、更新和管理 JAR(Java ARchive)文件。JAR 文件是一个 ZIP 格式的归档文件,通常包含多个 .class 文件和其他资源文件。使用示例:

jar cvf myapp.jar MyClass.class OtherClass.class

        这条命令会创建一个名为 myapp.jar 的 JAR 文件,并将 MyClass.class 和 OtherClass.class 文件打包进去。

  • javadoc

        javadoc 命令用于生成 HTML 格式的文档,这些文档是从源代码中的文档注释提取出来的。使用示例:

javadoc -d docs HelloWorld.java

        这条命令会根据 HelloWorld.java 文件中的文档注释生成 HTML 文档,并将它们放置在 docs 目录下。

  • jps

        jps 命令(Java Process Status Tool)用于显示正在运行的 Java 应用程序的进程 ID 和主类名。这对于调试和监控运行中的 Java 应用程序很有帮助。使用示例:

jps

        这条命令会列出所有正在运行的 Java 进程的信息。

  • javap

        javap 是 Java 反汇编器,它可以显示编译后的 Java 字节码。这对于调试和理解字节码层面上的执行逻辑非常有用。使用示例:

javap -c HelloWorld

        这条命令会显示 HelloWorld.class 文件中的字节码。

  • jconsole

        jconsole 是一个监视和管理 Java 应用程序的工具,它可以帮助开发者监控和调整正在运行的 Java 应用程序的性能。使用示例:

jconsole

        启动后可以选择连接到本地或远程的 Java 进程。

  • jstat

        jstat 工具用于收集有关 Java 应用程序的垃圾收集和内存使用情况的统计信息。使用示例:

jstat -gcutil <pid>

        这条命令会显示指定进程 ID 的 Java 应用程序的垃圾收集利用率。

  • jdb

jdb 是一个文本界面的 Java 调试器,允许开发者设置断点、单步执行、检查变量值等。使用示例:

jdb -classpath <path> MyApplication

        这条命令会启动 MyApplication 的调试会话。

6.Java 中是否存在内存溢出、内存泄漏?如何解决?举例说明

内存溢出(OOM)

内存溢出是指Java虚拟机(JVM)在尝试分配内存时,没有足够的空间来存储新的数据,导致无法创建新的对象。

常见原因

  • 内存分配过大:创建了过大的对象或对象数组,超出了JVM堆内存的限制。
  • 内存泄漏:长期存活的对象持续占用内存,未被垃圾收集器回收。
  • 资源密集型操作:如大量加载图片、文件等,未及时释放资源。
  • 递归调用过深:递归算法没有正确的终止条件,导致栈溢出。

解决方法

  • 增加堆内存:通过调整JVM启动参数(如-Xmx-Xms)来增加最大堆内存。
  • 优化代码:检查代码中是否有不必要的大对象创建,优化数据结构和算法。
  • 使用内存分析工具:使用如VisualVM、JProfiler等工具来分析内存使用情况,找出内存泄漏或占用异常的对象。
  • 调整垃圾收集器:根据应用特点选择合适的垃圾收集器,调整其参数来优化垃圾收集行为。

内存泄漏(Memory Leak)

内存泄漏是指程序在分配了内存之后,未能释放已不再使用的内存。

常见原因

  • 静态集合:使用静态集合(如static List)存储对象,导致对象无法被垃圾收集。
  • 长生命周期对象持有短生命周期对象引用:例如,一个大的缓存对象持有许多小对象的引用,即使这些小对象不再需要。
  • 第三方库或框架问题:使用的某些库或框架可能存在内存泄漏问题。
  • 资源未关闭:如数据库连接、文件流等没有正确关闭。

解决方法

  • 代码审查:定期进行代码审查,特别是关注对象的创建和释放。
  • 使用弱引用:对于那些不需要长期持有的对象,可以使用弱引用(WeakReference)。
  • 资源管理:确保所有资源(如文件、数据库连接、网络连接等)在使用完毕后被正确关闭。
  • 内存分析工具:使用内存分析工具来检测内存泄漏,例如Eclipse Memory Analyzer Tool (MAT)。

7.如何看待Java是一门半编译半解释型的语言

Java的编译过程

  • 源代码编译:Java源代码(.java文件)首先被编译器(javac)编译成字节码(.class文件)。这个过程是编译型语言的典型特征,因为源代码被转换成了中间形式的字节码,而不是直接转换成机器码。
  • 字节码:字节码是一种与平台无关的中间代码,它不是直接在硬件上执行的机器码,而是在Java虚拟机(JVM)上运行的指令集。

Java的运行过程

  • 解释执行:当Java程序运行时,JVM通过类加载器加载字节码,然后使用即时编译器(Just-In-Time, JIT)将字节码转换成特定平台的机器码。这个过程可以看作是解释执行,因为字节码在执行时才被转换成机器码。
  • JIT编译优化:JIT编译器在程序运行时动态地将热点代码(频繁执行的代码段)编译成优化后的机器码,以提高执行效率。这意味着,即使是同一段Java代码,在不同的运行阶段或不同的执行路径上,都可能被编译成不同的机器码。

结论

        从这个角度来看,Java既不是纯粹的编译型语言,也不是纯粹的解释型语言,而是一种结合了编译和解释两种机制的语言。这种设计让Java具有以下优势:

  • 跨平台性:由于字节码的平台无关性,Java程序可以在任何安装了JVM的平台上运行。
  • 性能优化:JIT编译器可以在运行时对代码进行优化,提高执行效率。
  • 安全性:字节码的执行在JVM的控制下,有助于防止恶意代码直接操作硬件。

        因此,将Java描述为“半编译半解释型”的语言,有助于更全面地理解其工作原理和特点。这种设计使得Java在保持高度的可移植性的同时,也能够提供相对高效的执行性能。

8.关键字、保留字

Java 关键字(共50个):

  • 访问控制publicprotectedprivate

  • 类、方法和变量修饰符abstractclassextendsfinalimplementsinterfacenativenewstaticstrictfpsynchronizedtransientvolatile

  • 程序控制语句breakcasecontinuedefaultdoelseforifinstanceofreturnswitchwhile

  • 错误处理assertcatchfinallythrowthrowstry

  • 包相关importpackage

  • 基本类型booleanbytechardoublefloatintlongshort

  • 变量引用superthisvoid

  • 保留关键字gotoconst

Java 保留字(目前有2个):

  • goto
  • const

需要注意的是,虽然gotoconst是Java的保留字,但它们在Java语言中并没有实际的用途,且在当前版本的Java中不被使用。此外,Java语言中还有三个特殊的直接量:truefalsenull,它们虽然不是关键字,但在编程中具有特定的含义。

9.标识符

  • 标识符:凡是可以自己命名的地方,都是标识符。

        比如:类名、变量名、方法名、接口名、包名、常量名等

  • 记住:标识符命名的规则(必须要遵守的,否则编译不通过)

> 由26个英文字母大小写,0-9 ,_或 $ 组成
> 数字不可以开头。
> 不可以使用关键字和保留字,但能包含关键字和保留字。
> Java中严格区分大小写,长度无限制。
> 标识符不能包含空格。

  • 记住:标识符命名的规范

> 包名:多单词组成时所有字母都小写:xxxyyyzzz。
  例如:java.lang、com.xyafu.edu
> 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
  例如:HelloWorld,String,System等  
> 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
  例如:age,name,bookName,main,binarySearch,getName  
> 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
  例如:MAX_VALUE,PI,DEFAULT_CAPACITY

10.变量的基本使用

  • 变量的理解:内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化

  • 变量的构成包含三个要素:数据类型、变量名、存储的值

  • Java中变量声明的格式:数据类型 变量名 = 变量值

定义变量时,变量名要遵循标识符命名的规则和规范。

说明: ① 变量都有其作用域。变量只在作用域内是有效的,出了作用域就失效了。 ② 在同一个作用域内,不能声明两个同名的变量 ③ 定义好变量以后,就可以通过变量名的方式对变量进行调用和运算。 ④ 变量值在赋值时,必须满足变量的数据类型,并且在数据类型有效的范围内变化。

11.基本数据类型变量的使用

  • 基本数据类型(8种):

整型:byte \ short \ int \ long 
浮点型:float \ double 
字符型:char
布尔型:boolean

  •     引用数据类型:

类(class)
数组(array)
接口(interface)

枚举(enum)
注解(annotation)
记录(record)

12.基本数据类型变量间的运算规则(重点)

  • 自动类型提升

测试基本数据类型变量间的运算规则。

1. 这里提到可以做运算的基本数据类型有7种,不包含boolean类型。
2. 运算规则包括:
        ① 自动类型提升
        ② 强制类型转换

3. 此VariableTest3.java用来测试自动类型提升

规则:当容量小的变量与容量大的变量做运算时,结果自动转换为容量大的数据类型。

    byte 、short 、char ---> int  --->  long  ---> float ---> double

    特别的:byte、short、char类型的变量之间做运算,结果为int类型。

说明:此时的容量小或大,并非指占用的内存空间的大小,而是指表示数据的范围的大小。
     long(8字节) 、 float(4字节)

13.强制类型转换

/*

规则:
1. 如果需要将容量大的变量的类型转换为容量小的变量的类型,需要使用强制类型转换
2. 强制类型转换需要使用强转符:()。在()内指明要转换为的数据类型。
3. 强制类型转换过程中,可能导致精度损失。
*/
class VariableTest4 {
    public static void main(String[] args) {
        
        double d1 = 12;//自动类型提升
        
        //编译失败
        //int i1 = d1;

        int i2 = (int)d1;
        System.out.println(i2);


        long l1 = 123;
        //编译失败
        //short s1 = l1;
        short s2 = (short)l1;
        System.out.println(s2);


        //练习
        int i3 = 12;
        float f1 = i3;//自动类型提升
        System.out.println(f1); //12.0

        float f2 = (float)i3; //编译可以通过。只不过可以省略()而已。
        
        //精度损失的例子1:
        double d2 = 12.9;
        int i4 = (int)d2;
        System.out.println(i4);

        //精度损失的例子2:
        int i5 = 128;
        byte b1 = (byte)i5;
        System.out.println(b1); //-128


        //实际开发举例:
        byte b2 = 12;
        method(b2);

        long l2 = 12L;
        //编译不通过
        //method(l2);
        method((int)l2);
    }

    public static void method(int num){   //int num = b2;自动类型提升
        System.out.println("num = " + num);
    }
}

14.String类的使用、与基本数据类型变量间的运算(重点)

  • String的认识:字符串。使用一对""表示,内部包含0个、1个或多个字符。

  • String与8种基本数据类型变量间的运算:+。运算的结果是String类型。

15.常识:进制的认识

数制表示法

  • 二进制:以0B或0b开头表示二进制数,例如0B10100b1010
  • 十进制:我们日常使用的数字系统,没有特定的前缀。
  • 八进制:以0开头,例如0123
  • 十六进制:以0x或0X开头,例如0x1A0X1A

二进制的理解

正数

对于正数,二进制的原码、反码和补码是相同的。原码就是直接将十进制数转换为二进制表示。

负数

对于负数,情况就有所不同:

  • 原码:直接表示负数的二进制形式,最高位为符号位(0表示正,1表示负),其余位表示数值。
  • 反码:正数的反码与其原码相同,负数的反码是其原码除符号位外所有位取反(0变1,1变0)。
  • 补码:正数的补码与其原码相同,负数的补码是其反码加1。

计算机内部使用补码来表示和存储所有整数,包括负数。补码系统简化了计算机的算术运算,特别是减法运算可以转换为加法运算。

二进制与十进制之间的转换

  • 二进制转十进制:从右到左,将每个位的值(0或1)乘以2的幂次方(从0开始),然后求和。例如,二进制1011转换为十进制是1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 = 111×23+0×22+1×21+1×20=11。
  • 十进制转二进制:通过不断除以2并取余数的方式,然后将余数倒序排列。例如,十进制数11转换为二进制是1011

二进制与八进制、十六进制间的转换

  • 二进制转八进制:将二进制数从右到左每三位一组(不足三位时在左边补0),然后将每组转换为对应的八进制数。例如,二进制101101转八进制是55
  • 八进制转二进制:将每个八进制数字转换为对应的三位二进制数。例如,八进制55转二进制是101101
  • 二进制转十六进制:将二进制数从右到左每四位一组(不足四位时在左边补0),然后将每组转换为对应的十六进制数。例如,二进制101101转十六进制是2D
  • 十六进制转二进制:将每个十六进制数字转换为对应的四位二进制数。例如,十六进制2D转二进制是101101

16.运算符(较常用的是重点)

算术运算符

用于执行基本的数学运算,如加、减、乘、除等。

  • +:加法
  • -:减法
  • *:乘法
  • /:除法
  • %:取模(余数)

赋值运算符

用于将表达式的值赋给变量。

  • =:基本赋值
  • +=:加后赋值(例如 a += b 等同于 a = a + b
  • -=:减后赋值
  • *=:乘后赋值
  • /=:除后赋值
  • %=:取模后赋值

比较运算符(关系运算符)

用于比较两个值,并返回布尔值(true或false)。

  • ==:等于
  • !=:不等于
  • >:大于
  • <:小于
  • >=:大于等于
  • <=:小于等于

逻辑运算符

用于执行布尔逻辑运算。

  • &&:逻辑与(AND)
  • ||:逻辑或(OR)
  • !:逻辑非(NOT)

位运算符

直接对整数类型的位进行操作。

  • &:按位与(AND)
  • |:按位或(OR)
  • ^:按位异或(XOR)
  • ~:按位取反(NOT)
  • <<:左移
  • >>:右移
  • >>>:无符号右移

条件运算符(三元运算符)

  • ?::条件表达式,格式为 条件 ? 表达式1 : 表达式2,如果条件为真,则结果为表达式1,否则为表达式2。

其他运算符

  • instanceof:用于测试对象是否为特定类的实例或其子类的实例。
  • new:用于创建对象实例。

17.高效的方式计算2 * 8的值

  • 使用 <<

18.&和&&的区别?

        在 Java 中,& 是按位与操作符,适用于整数类型的操作;&& 是逻辑与操作符,用于布尔表达式,它具有短路特性,即如果第一个操作数为 false,则不会计算第二个操作数。

19.Java中的基本类型有哪些?String 是最基本的数据类型吗?

  • Java中的基本类型有八种:

        byte、short、int、long、float、double、boolean、char

  • String 不是基本数据类型,它是引用类型,即对象。String 类型是由类定义创建的对象,因此它不是基本类型的一部分。

20.Java开发中计算金额时使用什么数据类型?

  • 在Java中处理货币或金融相关的计算时,通常推荐使用 BigDecimal 类来避免浮点数的精度损失问题。这是因为 float 或 double 类型可能会导致不精确的结果,尤其是在涉及货币时,这种不精确是不可接受的。

21.char型变量中能不能存储一个中文汉字,为什么?

  • 可以的。char c1 = '中';
  • char c2 = 'a'。
  • 因为char使用的是unicode字符集,包含了世界范围的所有的字符。

22.代码分析

第一段代码:

short s1 = 1;
s1 = s1 + 1;

        s1 + 1 的操作会导致类型提升,因为 + 操作符两边的类型会被提升到 int 类型(这是Java的自动类型提升规则之一)。所以 s1 + 1 的结果也是一个 int 类型的值。然后当你试图将这个 int 类型的值赋给 short 类型的变量 s1 时,编译器会报错,因为你需要显式地进行类型转换。

第二段代码:

short s1 = 1;
s1 += 1;

        在这段代码中,使用了 += 运算符,这是一种复合赋值运算符。在这种情况下,Java 会自动处理类型转换,先将表达式的结果转换成 short 类型再进行赋值,所以这段代码可以直接通过编译并正确运行。

23.int i=0; i=i++执行这两句化后变量 i 的值为

        在 Java 中,表达式 i = i++ 是一个典型的例子,展示了自增运算符(++)放在变量后面时的行为。这种情况下,i++ 表示先使用 i 的当前值,然后再将 i 的值加 1。

具体来说,对于以下代码:

int i = 0;
i = i++;

        执行过程如下:

        int i = 0; 初始化 i 为 0。
        i = i++; 这一行中,首先 i 的当前值(即 0)被用来作为赋值操作的右侧的值。然后 i 自增,变为 1。
        因此,在执行完 i = i++; 后,i 的值仍然是 0。这是因为赋值操作 = 的左侧是 i,而右侧是自增之前的 i 的值,即 0。

        总结:执行完这两句代码后,变量 i 的值仍为 0。

24.如何将两个变量的值互换

  • 使用第三个变量:
int a = 1;
int b = 2;
int temp = a;
a = b;
b = temp;
  • 使用算术运算:
int a = 1;
int b = 2;
a = a + b; // a现在等于3
b = a - b; // b现在等于1
a = a - b; // a现在等于2
  • 使用位运算:
int a = 1;
int b = 2;
a = a ^ b; // 使用异或操作
b = a ^ b; // 现在b等于原来的a
a = a ^ b; // 现在a等于原来的b

25.boolean 占几个字节

        在Java中,boolean 类型的大小并不是固定的,JVM 规范并没有明确规定 boolean 的确切大小。实际上,boolean 类型通常被实现为占一个字节(8位),但这取决于具体的JVM实现。需要注意的是,虽然 boolean 在内部可能使用一个字节表示,但是 boolean[] 数组的实现可能会有所不同,可能会使用位压缩等技术来节省空间。

26.为什么Java中0.1 + 0.2结果不是0.3?

        在代码中测试0.1 + 0.2,你会惊讶的发现,结果不是0.3,而是0.3000……4。这是为什么?

        几乎所有现代的编程语言都会遇到上述问题,包括 JavaScript、Ruby、Python、Swift 和 Go 等。引发这个问题的原因是,它们都采用了IEEE 754标准

IEEE是指“电气与电子工程师协会”,其在1985年发布了一个IEEE 754计算标准,根据这个标准,小数的二进制表达能够有最大的精度上限提升。但无论如何,物理边界是突破不了的,它仍然不能实现“每一个十进制小数,都对应一个二进制小数”。正因如此,产生了0.1 + 0.2不等于0.3的问题。

        具体的:

        整数变为二进制,能够做到“每个十进制整数都有对应的二进制数”,比如数字3,二进制就是11;再比如,数字43就是二进制101011,这个毫无争议。

        对于小数,并不能做到“每个小数都有对应的二进制数字”。举例来说,二进制小数0.0001表示十进制数0.0625 (至于它是如何计算的,不用深究);二进制小数0.0010表示十进制数0.125;二进制小数0.0011表示十进制数0.1875。看,对于四位的二进制小数,二进制小数虽然是连贯的,但是十进制小数却不是连贯的。比如,你无法用四位二进制小数的形式表示0.125 ~ 0.1875之间的十进制小数。

        所以在编程中,遇见小数判断相等情况,比如开发银行、交易等系统,可以采用四舍五入或者“同乘同除”等方式进行验证,避免上述问题。

        例如,在二进制中 0.1 可能被表示为一个无限循环的小数,因此在计算机中只能用一个近似的有限数表示。这种近似会导致 0.1 + 0.2 的结果接近但不完全等于 0.3。为了避免这种精度问题,通常建议在涉及到货币或其他需要高精度计算的情况下使用 BigDecimal 类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/54171.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

诚邀见证2024九章云极DataCanvas算力包产品发布会!

算力&#xff0c;是驱动全球智能化升级的关键力量&#xff0c;也是智算经济腾飞的主要燃料。 在智算经济腾起之际&#xff0c;我们洞察未来:算力不仅是生产力还将作为社会性普惠AI资源。我们思考未来:算力产品和模式需要何种创新才能够加速算力普惠的进程?我们定义未来:用单位…

react学习笔记一:react介绍

将view规划成一个个的组件&#xff0c;是一个响应式的声明式的设计。 虚拟dom&#xff0c;减少dom操作。vue的虚拟dom是在react的基础上拓展来的。 单向数据流&#xff1a;是一种数据流动的模式。数据流的方向是有上到下的&#xff0c;在react中主要是从父组件流向子组件。 …

计算机毕业设计 基于SpringBoot框架的网上蛋糕销售系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【微处理器系统原理与应用设计第十三讲】通用同/异步收发器USART轮询模式应用设计

USART提供两设备之间的串行双工通信&#xff0c;并支持中断和DMA工作。采用轮询、中断和DMA三种方式进行数据收发。 一、功能需求 实现远程串行通信数据的回传确认。微处理器系统构成的测控设备通过USART&#xff08;串口&#xff09;与用户设备&#xff08;上位机&#xff0…

【Python篇】Python 函数综合指南——从基础到高阶

文章目录 Python 函数综合指南1. 函数介绍1.1 什么是函数&#xff1f;1.2 定义函数示例&#xff1a;1.3 调用函数1.4 函数参数1.4.1 必需参数1.4.2 默认参数1.4.3 关键字参数1.4.4 可变长度参数 2. Python 内置函数2.1 字符串处理函数示例&#xff1a; 2.2 数学函数示例&#x…

基于Spring Boot的能源管理系统+建筑能耗+建筑能耗监测系统+节能监测系统+能耗监测+建筑能耗监测

介绍 建筑节能监测系统是基于计算机网络、物联网、大数据和数据可视化等多种技术融合形成的一套节能监测系统。 系统实现了对建筑电、水、热&#xff0c;气等能源、资源消耗情况的实时监测和预警、动态分析和评估&#xff0c;为用户建立了科学、系统的节能分析方法&#xff0c…

如何让大模型更好地进行场景落地?

自ChatGPT模型问世后&#xff0c;在全球范围内掀起了AI新浪潮。 有很多企业和高校也随之开源了一些效果优异的大模型&#xff0c;例如&#xff1a;Qwen系列模型、MiniCPM序列模型、Yi系列模型、ChatGLM系列模型、Llama系列模型、Baichuan系列模型、Deepseek系列模型、Moss模型…

简单题28-找出字符传中第一个匹配项的下标(Java and Python)20240918

问题描述&#xff1a; Java代码&#xff1a; class Solution {public int strStr(String haystack, String needle) {int n1 haystack.length();int n2 needle.length();if (n2 0) {return 0; // 如果 needle 为空字符串&#xff0c;直接返回 0}if (n1 < n2) {return -…

LeetCode[中等] 142. 环形链表 II

给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整…

LeetCode[中等] 438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 思路&#xff1a;滑动窗口 s包含p的异位词 ——> 则…

大数据新视界 --大数据大厂之数据科学项目实战:从问题定义到结果呈现的完整流程

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

组合逻辑电路的设计

目录 基本设计步骤 应用实例1&#xff08;三人表决电路&#xff09; 逻辑抽象 列真值表 化简&#xff08;卡诺图&#xff09; 转化为与非表达式 画逻辑图 应用实例2&#xff08;二进制转换为格雷码&#xff09; 逻辑抽象 列真值表 卡诺图化简 画逻辑图 基本设计…

【rust】rust条件编译

在c语言中&#xff0c;条件编译是一个非常好用的功能&#xff0c;那么rust中如何实现条件编译呢? rust的条件编译需要两个部分&#xff0c;一个是fratures&#xff0c;另一个是cfg。Cargo feature是一个非常强大的功能&#xff0c;可以提供条件编译和可选依赖项的高级特性&…

C++ -命名空间-详解

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【C】 欢迎点赞&#x1f44d;收藏⭐关注❤️ C -命名空间-详解 1.C语言缺点之一 -- 命名冲突2.命名空间2.1定义2.2使用访问命名空间中的变量展开命名空间域指定访问命名空间域 2.3其他功能 3.C 标准库中的命名空间指定展开…

云计算实训50——Kubernetes基础命令、常用指令

一、Kubernetes 自动补齐 # 安装自动补齐软件 [rootmaster ~]# yum -y install bash-completion # 临时开启自动补齐功能 [rootmaster ~]# source # 永 久开启自动补齐功能 [rootmaster ~]# echo "source > ~/.bashrc 二、Kubernetes 基础命令 kubectl [command] …

Linux:进程(二)

目录 一、cwd的理解 二、fork的理解 1.代码共享 2.各司其职 3.fork的返回值 三、进程状态 1.进程排队 2.进程状态 运行状态 一、cwd的理解 cwd&#xff08;current working directory&#xff09;。译为当前工作目录。 在C语言中&#xff0c;使用fopen函数打开文件时&…

MindShare PCIE 3.0 笔记-第一二章

MindShare 官网&#xff0c;地址如下: MindShare Chapter 1&#xff1a;PCIE 背景介绍 - PCI 总线模型 1. 以 PCI 总线作为外设总线的 SOC 芯片架构 下图展示了一个以 PCI 总线作为外设总线的 SOC 芯片架构(PCI 总线类似 AXI 下的 AHB&#xff1f;)&#xff1a; 由上图可知…

linux下的日志编写

1、日志初始化创建 2、日志写入 3、日志关闭 log.c #include "log.h"static log_t LOG;//初始化日志文件&#xff0c;在当前目录创建日志文件 int log_init(char *pdirname) {time_t t;struct tm *ptm NULL;char filepath[64] {0};int ret 0;time(&t);ptm …

linux安全软件Hydra使用教程

Hydra 是一个强大的网络登录工具&#xff0c;常用于渗透测试&#xff0c;支持对多种服务和协议&#xff08;如 SSH、FTP、HTTP 等&#xff09;进行暴力crack攻击。它可以通过字典攻击来测试用户名和密码的有效性。以下是关于如何使用 Hydra 的基本步骤和示例&#xff1a; 1. 安…

Mapsui:一个 .NET 开源的地图组件库

前言 今天大姚给大家分享一个.NET开源&#xff08;MIT License&#xff09;、免费、同时支持多平台框架&#xff08;MAUI、WPF、Avalonia、Uno、Blazor、WinUI、Eto、.NET Android 和 .NET iOS&#xff09;地图组件库&#xff1a;Mapsui。 项目源代码 支持的UI框架的NuGet包 创…