Java面试我这样回答MySQL,面试官让我下周来上班!,java面试题与答案

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

常用(oracle、SQL Server 默认隔离级别)。此隔离级别下,查询采用 快照读 的机制,即不会读取到未提交的数据,从而避免 “脏读”,但是仍可能导致 “不可重复读”、“幻读”。

(3)Repeatable Read(可重复读)
常用(mysql 默认隔离级别)。此隔离级别下,查询采用 快照读 的机制,且事务启动后,当前数据不能被修改,从而可以避免 “不可重复读”,但是仍可能导致 “幻读”(新增或删除某条数据)。

(4)Serializable(串行化)
一般不使用。此隔离级别下,事务会串行化执行(排队执行),执行效率差、开销大。可以避免 “脏读”、“不可重复读”、“幻读“。

【举例:】
select @@transaction_isolation; – 用于查看当前数据库的隔离级别(8.0版本)
set session transaction isolation level read committed; --用于设置隔离级别为 read committed

7.说说自增主键、UUID?

(1)自增主键,数据在物理结构上是顺序存储,性能好,占用空间小。可以是 int 和 bigint 类型。int 4字节,bigint 8 字节,项目中理论不应出现 自增主键达到最大值的情况,因为数据太大,效率会大大降低,当出现一定的数据量后,应进行分库分表操作。

(2)UUID,数据在物理结构上是随机存储,性能较差,占用空间大。唯一ID,绝不冲突。

8.mysql 的约束分类?

(1)约束的作用:是一种限制,用于限制表中的数据,为了保证数据的准确性以及可靠性。
(2)约束分类:
NOT NULL,非空,用于保证某个字段不为空。支持列级约束。
DEFAULT,默认,用于保证某个字段具有默认值。支持列级约束。
PRIMARY KEY,主键,用于保证某个字段具有唯一性且非空。支持列级约束以及表级约束。
UNIQUE,唯一,用于保证某个字段具有唯一性。支持列级约束以及表级约束。
FORGIEN KEY,外键,用于限制两个表间的关系。支持表级约束。
注:
列级约束:指的是定义列的同时指定的约束。
表级约束:指的是列定义之后指定的约束。

外键常用于一对多的关系。即表的某条数据,对应另外一张表的多条数据。
将 “一” 的一方称为 :主表。将 “多” 的一方称为 :从表。
通常将 外键 置于从表上,即 从表上增加一列作为外键,并依赖于主表的某列。

【举例:】
员工与部门间的关系。
一个部门可以有多个员工,而一个员工属于一个部门。此时部门与员工间为 一对多 的关系。
部门表为主表,员工表为从表。外键建立在 员工表(从表)上。

CREATE TABLE dept (
– 此处的 primary key 为 列级约束。
deptId int primary key auto_increment,
deptName varchar(20) not null
);

CREATE TABLE emp (
id int primary key auto_increment,
name varchar(32),
age int,
deptId int,
– 此处的 foreign key 为表级约束。
foreign key(deptId) references dept(deptId)
);

9.drop、delete 与 truncate 的区别:

(1)格式:

drop table 表名; – 用于删除数据表。
truncate table 表名; – 用于删除数据表的数据,但保留表结构。
delete from 表名 [where 条件]; – 用于删除数据标的数据,但保留表结构,可回滚。

(2)delete 与 truncate 相比较:

delete 可以添加删除条件,truncate 不可以。
delete 删除后可以回滚,truncate 不可以。
delete 效率较低,truncate 效率较高。
delete 可以返回受影响的行数,truncate 没有返回值。
delete 删除数据后再次插入数据时,标识列从断点处开始,truncate 标识列从 1 开始。

10.隐式事务、显式事务?

隐式事务:事务没有明显的开启与关闭的标志。比如 insert、delete、update等语句会自动提交。
显式事务:事务具有明显的开启与关闭的标志,前提需禁用自动提交功能。

show variables like “autocommit”; – 用于查看自动提交功能是否打开
set autocommit=1; – 用于打开自动提交功能
set autocommit=0; – 用于关闭自动提交功能

【显式事务步骤:】
Step1:开启事务,关闭自动提交功能。
set autocommit=0;

Step2:编写事务语句。
select、insert、delete、update。
SAVEPOINT A; – 可以设置回滚点

Step3:结束事务。
commit; – 提交事务
rollback; – 回滚事务
rollback to A; – 回滚到回滚点

11.存储过程

(1)存储过程:
指的是 一组预先编译好的 sql 语句的集合,可以理解成批处理语句。类似于 Java 中的方法,使用时调用方法名即可。

(2)好处:
提高了代码的重用性。
简化操作。
减少了编译次数、与数据库交互的次数,提高了效率。
(3)语法:

【创建存储过程:】
DELIMITER $
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的 sql 语句)
END $
DELIMITER ;
注:
参数列表分三个部分,分别为 参数模式、参数名、参数类型
参数模式:IN、OUT、INOUT。
IN:指该参数可以作为输入,即接收值(默认)。
OUT:指该参数可以作为输出,即返回值。
INOUT:指该参数即可作为输入、又可作为输出。

存储过程体中每条语句必须以分号 ; 结尾。
DELIMITER 用于设置结束标记,用于存储过程末尾,执行到标记处则存储过程结束。

【调用存储过程:】
CALL 存储过程名(参数列表);

【删除存储过程:】
DROP PROCEDURE 存储过程名;

【查看存储过程结构:】
SHOW CREATE PROCEDURE 存储过程名;

12.你们数据量级多大?分库分表怎么做的?

首先分库分表分为垂直和水平两个方式,一般来说我们拆分的顺序是先垂直后水平。
垂直分库

基于现在微服务拆分来说,都是已经做到了垂直分库了
[图片上传失败…(image-16e8d3-1600421516221)]

垂直分表
如果表字段比较多,将不常用的、数据较大的等等做拆分
在这里插入图片描述

水平分表
首先根据业务场景来决定使用什么字段作为分表字段(sharding_key),比如我们现在日订单1000万,我们大部分的场景来源于C端,我们可以用user_id作为sharding_key,数据查询支持到最近3个月的订单,超过3个月的做归档处理,那么3个月的数据量就是9亿,可以分1024张表,那么每张表的数据大概就在100万左右。

比如用户id为100,那我们都经过hash(100),然后对1024取模,就可以落到对应的表上了。

13.那分表后的ID怎么保证唯一性的呢?

因为我们主键默认都是自增的,那么分表之后的主键在不同表就肯定会有冲突了。有几个办法考虑:

  1. 设定步长,比如1-1024张表我们分别设定1-1024的基础步长,这样主键落到不同的表就不会冲突了。
  2. 分布式ID,自己实现一套分布式ID生成算法或者使用开源的比如雪花算法这种
  3. 分表后不使用主键作为查询依据,而是每张表单独新增一个字段作为唯一主键使用,比如订单表订单号是唯一的,不管最终落在哪张表都基于订单号作为查询依据,更新也一样。

14.那分表后的ID怎么保证唯一性的呢?

因为我们主键默认都是自增的,那么分表之后的主键在不同表就肯定会有冲突了。有几个办法考虑:

  1. 设定步长,比如1-1024张表我们分别设定1-1024的基础步长,这样主键落到不同的表就不会冲突了。
  2. 分布式ID,自己实现一套分布式ID生成算法或者使用开源的比如雪花算法这种
  3. 分表后不使用主键作为查询依据,而是每张表单独新增一个字段作为唯一主键使用,比如订单表订单号是唯一的,不管最终落在哪张表都基于订单号作为查询依据,更新也一样。

15.分表后非sharding_key的查询怎么处理呢?

  1. 可以做一个mapping表,比如这时候商家要查询订单列表怎么办呢?不带user_id查询的话你总不能扫全表吧?所以我们可以做一个映射关系表,保存商家和用户的关系,查询的时候先通过商家查询到用户列表,再通过user_id去查询。
  2. 打宽表,一般而言,商户端对数据实时性要求并不是很高,比如查询订单列表,可以把订单表同步到离线(实时)数仓,再基于数仓去做成一张宽表,再基于其他如es提供查询服务。
  3. 数据量不是很大的话,比如后台的一些查询之类的,也可以通过多线程扫表,然后再聚合结果的方式来做。或者异步的形式也是可以的。

List<Callable<List>> taskList = Lists.newArrayList();
for (int shardingIndex = 0; shardingIndex < 1024; shardingIndex++) {
taskList.add(() -> (userMapper.getProcessingAccountList(shardingIndex)));
}
List list = null;
try {
list = taskExecutor.executeTask(taskList);
} catch (Exception e) {
//do something
}

public class TaskExecutor {
public List executeTask(Collection<? extends Callable> tasks) throws Exception {
List result = Lists.newArrayList();

总结

虽然我个人也经常自嘲,十年之后要去成为外卖专员,但实际上依靠自身的努力,是能够减少三十五岁之后的焦虑的,毕竟好的架构师并不多。

架构师,是我们大部分技术人的职业目标,一名好的架构师来源于机遇(公司)、个人努力(吃得苦、肯钻研)、天分(真的热爱)的三者协作的结果,实践+机遇+努力才能助你成为优秀的架构师。

如果你也想成为一名好的架构师,那或许这份Java成长笔记你需要阅读阅读,希望能够对你的职业发展有所帮助。

image

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-Nq7ZhOBa-1713555668892)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值