JAVA编码笔记

#.e.printStackTrace();和log.error()的区别和用法

catch (Exception e) {
    //e.printStackTrace();// 只能输出在控制台当中,日志文件看不到
    //log.error(e.getMessage());// 只能输出简短的错误信息,不便于排错
    //log.error(e.getStackTrace().toString());// 不能输出错误信息
    //log.error(e.toString());// 只能输出简短的错误信息,不便于排错
    log.error("test fail:",e);// 可以在日志中输出完整的错误信息,""里要写内容
}

        关于e.printStackTrace();可能造成死锁的文章见https://my.oschina.net/sxgkwei/blog/825700。。

        最好不要在生产代码中出现e.printStackTrace(),一是不容易排错,二是容易造成死锁。

        采用不同的log.error()来输出想要的结果。

#.Java 无符号类型是什么意思

        Java语言中没有无符号类型。在其他一些编程语言中,无符号类型是指在数值的二进制表示中没有符号位的类型。这种类型只能表示非负整数。与之相反,有符号类型则包含一个符号位,可以表示正数、零和负数。Java中只有有符号类型,包括byte、short、int、long、float、double等。

#.单精度和双精度的区别

        单精度和双精度都是浮点型数据类型,用于表示小数。它们的主要区别在于精度和存储大小。

1.精度:单精度(float)提供6位十进制精度,双精度(double)提供15位十进制精度。这意味着双精度可以表示更精确的数值。

2.存储大小:单精度占用4个字节(32位)的存储空间,双精度占用8个字节(64位)的存储空间。因此,双精度占用的存储空间是单精度的两倍。

        根据具体的应用需求和对精度的要求,可以选择使用单精度或双精度。如果需要表示的数值范围较大,精度要求不高,可以选择单精度。如果需要表示更精确的数值,或者数值范围较小,可以选择双精度。

#.浮点数和BigDecimal的使用场景

        浮点数(float 和 double)与 BigDecimal 在 Java 中都有各自的适用场景,它们的特点决定了其使用的不同之处:

1.浮点数(float 和 double):

        适合场景:

近似数值计算,例如科学计算、图形渲染、物理模拟等,这些场景中允许一定的误差存在。

对内存和速度敏感的应用程序,如大数据处理、实时系统等,由于 float 和 double 相对于 BigDecimal 更轻量级,处理速度更快。

当精度要求不是特别高,比如显示温度、体积等日常生活中的数值时。

        特点:

浮点数是内建数据类型,执行效率高。

它们是有限精度的,遵循 IEEE 754 标准,意味着在某些情况下可能会出现舍入误差。

float 单精度大约能提供 6-7 位有效数字,而 double 双精度则可提供约 15-16 位有效数字。

2.BigDecimal:

        适合场景:

财务、银行、货币计算、账单系统、税务系统等需要高精度计算的领域,因为这里的数值计算必须是精确无误的,不允许有任何舍入误差。

需要控制舍入模式以及精确指定小数位数的场景,例如商品价格计算、百分比计算等。

        特点:

提供任意精度的浮点数算术,避免了内部二进制表示带来的精度损失问题。

构造时可以指定精度和舍入模式,使得计算结果可控。

执行速度相对较慢,因为它是一种不可变对象,每次操作都会创建新的 BigDecimal 实例。

        总结来说,当你需要进行低精度、快速计算并且可以接受一定误差时,使用 float 或 double 是合适的;而在需要高精度、不允许误差的商业计算中,则应该选择 BigDecimal。

#.Java定义属性使用int还是Integer

        在Java中定义属性时,选择使用int还是Integer主要取决于具体的场景和需求:

1.使用int的情况:

当属性仅需要存储整数值,并且不需要考虑空值(null)的情况下,通常推荐使用int基本数据类型。它更高效,占用的空间少,且没有额外的开销(如装箱和拆箱)。

2.使用Integer的情况:

当属性可能需要表示空值时,应选择Integer包装类,因为基本类型int不能赋值为null。

在需要使用集合(如ArrayList、HashMap等)存储整数值时,由于集合只能存放对象,所以需要使用Integer。

在涉及到自动装箱/拆箱特性,以及需要利用到Integer类提供的方法(如valueOf缓存机制、compareTo等)时,也会选择使用Integer。

        在Java 5及更高版本中,由于引入了自动装箱/拆箱机制,编译器会自动在int和Integer之间转换,所以在一些简单场景下,两者在使用上的差异相对较小。但在关注性能、内存占用以及处理null值时,仍需谨慎选择。

#.字面量和字符串的区别

        字面量(Literal)和字符串(String)在不同的上下文中有着不同的含义和关系,以下是它们的基本概念及其区别:

1.字面量 (Literal) :

字面量是指在源代码中直接以固定形式出现的值,它是编程语言中可以直接识别并具有一确定意义的数据项。字面量可以是各种类型的,如整型、浮点型、字符型、布尔型以及字符串型等。在提到字符串字面量时,它指的是用引号包裹的一串字符序列;

2.字符串 (String)

字符串是在编程中用来表示文本的数据结构,它可以是固定长度的,也可以是可变长度的。在大多数现代编程语言中,字符串是由一系列字符组成的一个有序序列,并提供了许多操作字符串的方法和功能。

字符串既可以是通过字面量方式创建的,也可以通过构造函数、方法调用等方式动态创建。例如在Java中:

   // 示例:字符串字面量
   String str1 = "Hello, World!"; // 这是一个字符串字面量
   // 示例:通过构造函数创建的字符串
   String str2 = new String("Another String"); // 这是一个基于字符串字面量构建的字符串对象

3.区别:

字面量是编程语言中硬编码的值,字符串字面量则是其中一种特定类型的字面量,即表示文本的字面量。

字符串对象则是具有数据结构和相关方法的实体,可以保存、操作和传递字面量所代表的文本信息。

字符串字面量在内存中通常是共享存储的(例如Java和C#中字符串字面量常驻在常量池中),而通过构造函数创建的字符串对象通常是独立分配内存的。

        字符串字面量在创建之后不能被修改(在C++和Java等语言中是不可变的),而字符串对象有时可以通过方法进行修改(例如在Java中,尽管String对象本身不可变,但可以创建新的字符串对象来反映修改后的状态)。

#.MyBatis的resultType使用内部类

        在 MyBatis 框架中,当 SQL 查询的结果需要映射到一个复杂的 Java 类型时,可以使用内部类来进行结果映射。这里所说的内部类一般是指位于外部类中的静态嵌套类,这样能够更好地组织和封装数据结构。

假设我们有一个外部类 RechargeListVO,里面有一个静态内部类 Summary,我们要映射查询结果到 Summary 类上。那么在 MyBatis 的映射文件(XML)中的 select 标签内,可以按照以下方式设置 resultType:

<select id="selectRechargeSummary" resultType="com.example.RechargeListVO$Summary">
    SELECT ... <!-- SQL 查询语句 -->
</select>

这里有几个关键点需要注意:

内部类的引用:内部类的名称需要使用 $ 符号连接外部类与内部类的名字,如 RechargeListVO$Summary。

内部类必须是静态的:为了能够在不依赖外部类实例的情况下创建内部类的对象,该内部类必须是静态的(static)。

构造方法:内部类通常需要有一个无参数的构造方法以便 MyBatis 创建实例并填充属性。

属性映射:还需要确保内部类的属性名称与 SQL 查询结果列名相匹配或者通过 映射标签进行显式映射。

这样,当 MyBatis 执行 SQL 查询后,就会根据配置的 resultType 自动将查询结果映射到指定的内部类对象上。

#.String 类的底层是以 Char 数组还是Byte数组

        String 类的底层是以 char 数组来存储字符数据的。

        Java 中的 String 类型是用来表示字符串的,而字符串是由 Unicode 字符组成的,因此 String 类使用 char 数组来存储字符数据,而不是 byte 数组。

        在 Java 中,char 类型是一个 16 位的无符号整数,可以表示一个 Unicode 字符。

        而 byte 类型是一个 8 位的有符号整数,通常用来表示一个 ASCII 字符。

        因此,如果要表示 Unicode 字符串,需要使用 char 数组,而不是 byte 数组。

        然而,在 Java 9 及以后的版本中,如果字符串只包含单字节代码单元(例如 ASCII 字符串),则可以使用 byte 数组来存储字符串数据,以节省内存空间。

        但是,这并不意味着 String 类的底层实现是 byte 数组,而是在特定情况下使用 byte 数组来存储字符串数据的一种优化策略。

#.String类型编译器优化

Java中String不是基本类型,但是有些时候和基本类型差不多,如String b = “tao” ; 可以对变量直接赋值,而不用 new 一个对象(当然也可以用 new)。

Java中的变量和基本类型的值存放于栈内存,而new出来的对象本身存放于堆内存,指向对象的引用还是存放在栈内存。

例如如下的代码:

int i=1;

String s = new String( “Hello World” );

变量i和s以及1存放在栈内存,而s指向的对象”Hello World”存放于堆内存。

栈内存的一个特点是数据共享,这样设计是为了减小内存消耗,前面定义了i=1,i和1都在栈内存内,如果再定义一个j=1,此时将j放入栈内存,然后查找栈内存中是否有1,如果有则j指向1。如果再给j赋值2,则在栈内存中查找是否有2,如果没有就在栈内存中放一个2,然后j指向2。也就是如果常量在栈内存中,就将变量指向该常量,如果没有就在该栈内存增加一个该常量,并将变量指向该常量。

如果j++,这时指向的变量并不会改变,而是在栈内寻找新的常量(比原来的常量大1),如果栈内存有则指向它,如果没有就在栈内存中加入此常量并将j指向它。这种基本类型之间比较大小和我们逻辑上判断大小是一致的。如定义i和j是都赋值1,则i==j结果为true。==用于判断两个变量指向的地址是否一样。i==j就是判断i指向的1和j指向的1是同一个吗?当然是了。

对于直接赋值的字符串常量(如String s=“Hello World”;中的Hello World)也是存放在栈内存中,而new出来的字符串对象(即String对象)是存放在堆内存中。如果定义String s=“Hello World”和String w=“Hello World”,s==w吗?肯定是true,因为他们指向的是同一个Hello World。

堆内存没有数据共享的特点,前面定义的String s = new String( “Hello World” );后,变量s在栈内存内,Hello World 这个String对象在堆内存内。如果定义String w = new String( “Hello World” );,则会在堆内存创建一个新的String对象,变量w存放在栈内存,w指向这个新的String对象。堆内存中不同对象(指同一类型的不同对象)的比较如果用==则结果肯定都是false,比如s==w?当然不等,s和w指向堆内存中不同的String对象。如果判断两个String对象相等呢?用equals方法。

对于字符串常量的相加,在编译时直接将字符串合并,而不是等到运行时再合并。

Java对String的相加是通过StringBuffer实现的。

intern() 方法会先检查 String 池 ( 或者说成栈内存 ) 中是否存在相同的字符串常量,如果有就返回。

在字符串相加中,只要有一个是非final类型的变量,编译器就不会优化,因为这样的变量可能发生改变,所以编译器不可能将这样的变量替换成常量。

#.分布式调度XXL-JOB

1、框架架构图

2、框架设计思想

1、将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。

2、将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值