Java面试总结(八)
创始人
2025-05-29 00:05:56
0

MyBatis判断某字段为null使用什么标签

  and category_id=#{categoryId}

MySQL四个事务隔离级别

  1. READ-UNCOMMITTED(读取未提交) : 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  2. READ-COMMITTED(读取已提交) : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  3. REPEATABLE-READ(可重复读) : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  4. SERIALIZABLE(可串行化) : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

ACID

  • 原子性(Atomicity) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

  • 一致性(Consistency): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;

  • 隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;

  • 持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

MySQL唯一索引可以存在多少个

创建唯一索引的目的不是为了提高访问速度,而只是为了避免数据出现重复。唯一索引可以有多个但索引列的值必须唯一,索引列的值允许有空值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE,把它定义为一个唯一索引。

delete语句会加哪些锁

delete属于当前读,所有的当前读最开始都会加临建锁,根据不同的SQL语句过滤条件可能会退化为间隙锁或记录锁,当走全表扫描时会锁住整张表,造成性能损失。

in 和 exists 的区别

  1. in()适合子表比主表数据小的情况

  2. exists()适合子表比主表数据大的情况

  3. 当主表数据与子表数据一样大时,in与exists效率差不多,可任选一个使用

如果想要详细了解这个问题,可以参考这篇文章——IN和EXISTS的区别和使用

如果想要详细了解这个问题,可以参考这篇文章——EXISTS 与 in的区别

Mysql中常用的函数,数据类型转换可能存在的问题

Concat函数。

连接字符串常用:concat函数。如sql查询条件的like查询

select * from ms_sys_user where account like concat("%", 2, "%")

将Int 转为varchar经常用 concat函数,比如concat(8,‘0’) 得到字符串 ‘80’

Cast函数;CONVERT函数。

用法:CAST(expr AS type), CONVERT(expr,type) , CONVERT(expr USING transcoding_name).

SELECT CONVERT(‘abc’ USING utf8);

将varchar 转为Int 用 cast(str as unsigned) str为varchar类型的字符串 。

比如常用的百分比转换:

select cast((1/3)*100 as unsigned) as percent from dual;

result: 33

MySQL类型转换函数参数 : CAST(xxx AS 类型) , CONVERT(xxx,类型)

这个类型 可以是以下值其中的 一个:

BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]整数 : SIGNED 
无符号整数 : UNSIGNED
二进制,同带binary前缀的效果 : BINARY 
字符型,可带参数 : CHAR() 
日期 : DATE 
时间: TIME 
日期时间型 : DATETIME 
浮点数 : DECIMAL 

IF函数

IF(expr1,expr2,expr3)
如果 expr1 != null && expr1 != 0 则返回 expr2 否则返回 expr3

select if(admin, avatar, deleted)  from ms_sys_user where id = 1

如果 admin != null && admin != 0 则返回 avatar 字段内容 否则返回 deleted 字段内容

String、StringBuild、StringBuffer的区别

可变性

String 是不可变的(后面会详细分析原因)。

StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 final 和 private 关键字修饰,最关键的是这个 AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。字符串的拼接底层就是创建了一个StringBuild对象,利用其可变性将两个字符串拼接在一块然后tostring()返回。

abstract class AbstractStringBuilder implements Appendable, CharSequence {char[] value;public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this;}//...
}

线程安全性

String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

性能

每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

对于三者使用的总结:

  1. 操作少量的数据: 适用 String;
  2. 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder;
  3. 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer。

String 为什么是不可变的?

public final class String implements java.io.Serializable, Comparable, CharSequence {private final char value[];//...
}

我们知道被 final 关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是基本数据类型则值不能改变,修饰的变量是引用类型则不能再指向其他对象。因此,final 关键字修饰的数组保存字符串并不是 String 不可变的根本原因,因为这个数组保存的字符串是可变的(final 修饰引用类型变量的情况)。String 真正不可变有下面几点原因:

  1. 保存字符串的数组被 final 修饰且为私有的,并且String 类没有提供/暴露修改这个字符串的方法。

  2. String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变。

字符串拼接用“+” 还是 StringBuilder?

Java 语言本身并不支持运算符重载,“+”和“+=”是专门为 String 类重载过的运算符,也是 Java 中仅有的两个重载过的运算符。

String str1 = "he";
String str2 = "llo";
String str3 = "world";
String str4 = str1 + str2 + str3;

上面的代码对应的字节码如下:

在这里插入图片描述
可以看出,字符串对象通过“+”的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到一个 String 对象 。

不过,在循环内使用“+”进行字符串的拼接的话,存在比较明显的缺陷:编译器不会创建单个 StringBuilder 以复用,会导致创建过多的 StringBuilder 对象。

String[] arr = {"he", "llo", "world"};
String s = "";
for (int i = 0; i < arr.length; i++) {s += arr[i];
}
System.out.println(s);

StringBuilder 对象是在循环内部被创建的,这意味着每循环一次就会创建一个 StringBuilder 对象。

在这里插入图片描述
如果直接使用 StringBuilder 对象进行字符串拼接的话,就不会存在这个问题了。

String[] arr = {"he", "llo", "world"};
StringBuilder s = new StringBuilder();
for (String value : arr) {s.append(value);
}
System.out.println(s);

在这里插入图片描述

相关内容

热门资讯

安卓高系统怎么用美化,打造专属... 亲爱的安卓用户们,你是不是也和我一样,对手机系统美化情有独钟呢?想要让你的安卓手机焕然一新,变得个性...
安卓系统怎么开夜间模式,安卓系... 亲爱的手机控们,你是不是在夜晚使用安卓手机时,眼睛感到有些不适?别担心,今天我要给你揭秘一个超级实用...
王者安卓系统用苹果人脸,一场视... 你知道吗?最近在手机圈里可是掀起了一股不小的波澜呢!那就是王者安卓系统竟然用上了苹果人脸识别技术!是...
安卓444怎么升级系统,轻松迈... 你那安卓444的小家伙是不是已经有点儿落伍了?别急,今天就来给你详细说说怎么给它来个系统升级,让它焕...
安卓系统raw修图软件,探索安... 你有没有发现,手机拍照越来越方便了,但有时候拍出来的照片还是不够完美呢?别急,今天就来给你安利几款安...
安卓系统的王者切换苹果,从安卓... 你知道吗?最近身边的朋友圈里掀起了一股热潮,那就是安卓系统的王者们纷纷切换到苹果阵营。这可真是让人大...
安卓用按钮退出系统,Andro... 你有没有发现,现在用安卓手机的时候,退出系统的方式好像有点变化呢?是不是有时候按了按钮,系统还是纹丝...
安卓系统怎么删除相机,安卓系统... 手机里的照片越来越多,是不是感觉相机里都快装不下你的美好回忆了?别急,今天就来教你怎么轻松地在安卓系...
安卓双系统点歌机系统包,打造智... 你有没有想过,在安卓双系统点歌机里,那些美妙的音乐是如何被唤醒的呢?今天,就让我带你一探究竟,揭开安...
安卓不卡顿的系统,安卓系统不卡... 你有没有想过,为什么有些安卓手机用起来就是那么流畅,而有些却总是卡卡卡个不停?今天,就让我带你一探究...
鸿蒙系统切换安卓死机,系统兼容... 最近手机界可是热闹非凡呢!听说华为的新操作系统鸿蒙系统上线了,不少小伙伴都跃跃欲试,想要体验一下这个...
系统能被卸载吗安卓,卸载与优化... 你有没有想过,你的安卓手机里的系统,是不是也能像卸载一个APP那样简单呢?今天,就让我带你一探究竟,...
安卓永远超不过苹果系统,谁将永... 你有没有想过,为什么安卓手机再怎么努力,好像永远都追不上苹果系统的光芒呢?这背后,可是有着不少门道呢...
安卓系统手机位置共享,探索安卓... 你有没有想过,当你的朋友突然告诉你:“我快到你了,你定位一下我哦!”这时,你的安卓手机位置共享功能就...
安卓系统怎么添加表情包,表情包... 你是不是也和我一样,手机里收藏了超多搞笑的表情包,想要在聊天的时候分享给朋友,但又不知道怎么在安卓系...
安卓变黑鲨系统下载,深度解析系... 你有没有发现,你的安卓手机最近有点儿不一样了?是不是觉得屏幕上的图标变得酷炫了,操作起来也更加流畅了...
windows平板如何装安卓系... 亲爱的电脑迷们,你是否曾梦想过在你的Windows平板上体验安卓系统的流畅与丰富应用?别再羡慕那些安...
鸿蒙系统如何恢复到安卓系统中,... 你是不是也和我一样,对鸿蒙系统到安卓系统的转换感到好奇呢?听说最近很多人都在尝试将手机从鸿蒙系统切换...
苹果手机升级安卓系统,探索安卓... 你有没有想过,如果有一天苹果手机突然宣布要升级成安卓系统,那会是怎样的景象呢?想象那些习惯了iOS操...
iphone能不能安卓系统,探... 最近手机圈可是热闹非凡呢!不少朋友都在问我:“iPhone能不能用安卓系统?”这个问题,真是让人头都...