一、mybatis:
1、当实体类中的属性名和表中的字段名不一样 ,怎么办
1、使用as关键字起别名
-
<sql id="Base_Column_List">
-
<!--数据库种表的字段 as 实体类属性-->
-
uid as id, userName as name, age as age,
-
email as email, create_time as createTime,
-
update_time as updateTime, is_deleted as deleted
-
</sql>
2、使用resultMap标签映射:column的值为数据库中的字段名,property的值为实体类中的属性名
-
<!-- type:指定需要映射的实体类 -->
-
<resultMap id="userMap" type="User">
-
<!-- column:数据库表中的字段名 -->
-
<!-- property:实体类中的属性 -->
-
<id column="uid" property="id" />
-
<result column="userName" property="name" />
-
<result column="age" property="age" />
-
<result column="email" property="email" />
-
<result column="create_time" property="createTime" />
-
<result column="update_time" property="updateTime" />
-
<result column="is_deleted" property="deleted" />
-
</resultMap>
-
<select id="getUserList" resultMap="userMap">
-
select uid,userName,age,email,create_time,update_time,is_deleted from t_user;
-
</select>
2、#{}和${}的区别是什么
#{}是预编译参数占位符,可以防止sql注入。
${}是字符串替换占位符,无法防止sql注入。
sql注入:sql注入是指攻击者向数据库中插入恶意的sql语句,从而来获取或篡改数据库中的数据。
3、Mybatis 分页插件的原理是什么
MyBatis 分页插件的原理是通过拦截 SQL 执行过程,在执行前和执行后对 SQL 进行改写,添加分页相关的语句,实现数据库分页查询功能。
具体原理包括:
1、拦截器:MyBatis 分页插件通过拦截器拦截 Executor 的 query 方法,在执行 SQL 之前和之后进行处理。
2、SQL 改写:在执行前,插
篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
件会将原始 SQL 语句改写成分页查询语句,通常是在原始 SQL 后面添加 LIMIT 或 OFFSET 等关键字,限制返回结果的数量。
3、参数处理:插件还会处理分页相关的参数,如页码和每页数据量,以便构建正确的分页查询语句。
4、结果处理:在执行后,插件会对查询结果进行处理,将结果封装成分页对象,包括总记录数、当前页码、每页数据量等信息。
通过以上步骤,MyBatis 分页插件实现了对 SQL 查询结果的分页处理,使得开发者可以方便地进行数据库分页查询。
4、一对一、一对多的关联查询
1、一对一使用association标签
2、一对多使用collection标签
案例:一个商品对应一个价格,一个价格对应多个商品
实体类:
-
public class Product {
-
private Long id;
-
private String name;
-
private Price price;
-
// Getters and setters
-
}
-
public class Price {
-
private Long id;
-
private Double value;
-
private List<Product> products;
-
// Getters and setters
-
}
xml:
-
<select id="selectProductWithPrice" resultMap="productWithPrice">
-
SELECT p.id AS product_id, p.name, pr.id AS price_id, pr.value
-
FROM product p
-
LEFT JOIN price pr ON p.id = pr.product_id
-
</select>
-
<resultMap id="productWithPrice" type="Product">
-
<id property="id" column="product_id"/>
-
<result property="name" column="name"/>
-
<association property="price" javaType="Price">
-
<id property="id" column="price_id"/>
-
<result property="value" column="value"/>
-
</association>
-
</resultMap>
-
<select id="selectPriceWithProducts" resultMap="priceWithProducts">
-
SELECT pr.id AS price_id, pr.value, p.id AS product_id, p.name
-
FROM price pr
-
LEFT JOIN product p ON pr.product_id = p.id
-
WHERE pr.value > 100;
-
</select>
-
<resultMap id="priceWithProducts" type="Price">
-
<id property="id" column="price_id"/>
-
<result property="value" column="value"/>
-
<collection property="products" ofType="Product">
-
<id property="id" column="product_id"/>
-
<result property="name" column="name"/>
-
</collection>
-
</resultMap>
5、Mybatis 的一级、二级缓存
一级缓存是 MyBatis 默认开启的,作用于同一个 SQLSession 中,生命周期较短。当 SQLSession 关闭时,一级缓存就会被清空。
二级缓存须在 Mapper.xml 中配置,作用于不同的 SQLSession 中,生命周期较长。二级缓存在整个应用程序的生命周期内有效,当应用程序关闭时,二级缓存也会被清空。
总之,一级缓存和二级缓存都旨在提高数据访问的性能并减轻数据库压力,对于相同的查询都是从缓存中获取的。
6、如何获取自动生成的(主)键值
1、在标签中添加一个属性useGeneratedKeys="true"即可。(该属性只能放在insert标签中)
案例:
篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
-
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
-
INSERT INTO users (username, password) VALUES (#{username}, #{password})
-
</insert>
2、使用selectKey标签也行,它可以在执行插入语句数据库之前,通过一个查询来获取主键值。(该标签只能放在insert标签中)
案例:
-
<insert id="insertUser" parameterType="User">
-
<selectKey keyProperty="id" resultType="java.lang.Long" order="AFTER" >
-
SELECT LAST_INSERT_ID() AS id
-
</selectKey>
-
INSERT INTO users (username, password) VALUES (#{username}, #{password})
-
</insert>
二、redis:
1、谈谈你对redis的理解
1、对redis的理解:数据存储在内存中,读取速度快,是一种非关系型数据库。
2、数据结构和用途:Redis支持多种数据结构,如string、hash、list、set、zset,适用于缓存、消息队列和会话存储等场景。
3、分布式特性:Redis支持主从复制和集群模式,实现高可用性和横向扩展。
2、Redis 的数据类型
1、字符串 (String):
简述: 存储字符串、整数或浮点数等基本数据类型。
应用场景: 缓存、计数器、计时器等。
2、哈希 (Hash):
简述: 存储对象的属性和对应值的键值对集合。
应用场景: 存储用户信息、对象属性等。
3、列表 (List):
简述: 按插入顺序排序的字符串元素集合,支持头部和尾部的增删改操作。
应用场景: 消息队列、任务队列等。
4、集合 (Set):
简述: 无序的字符串集合,不允许重复元素。
应用场景: 标签系统、好友关系等。
5、有序集合 (Sorted Set):
简述: 有序集合,元素按分数升序排列,每个元素都有一个分数。
应用场景: 排行榜、范围查询等需要按分数排序的场景。
3、Redis 是单进程单线程的吗
是的。
4、Redis 的淘汰策略
1、LRU(Least Recently Used):淘汰最近最少使用的数据。
2、LFU(Least Frequently Used):淘汰最少频繁使用的数据。
3、TTL(Time To Live):自动淘汰过期的数据。
4、Random(随机淘汰):随机选择一个数据进行淘汰。
5、No Eviction(无淘汰):当内存达到最大限制时,拒绝写入新的数据,而不进行淘汰。
5、redis 过期键的删除策略
Redis 中过期键的删除策略包括定期删除和惰性删除。
定期删除:Redis 默认采用的是定期删除策略。在设置键的过期时间时,同时创建一个定时器,在键的过期时间到达时,定时器会检查该键是否过期,如果过期则删除。定期删除可能会带来性能问题,特别是当大量键在短时间内过期时,可能导致性能下降。
惰性删除:在每次获取键时,Redis 会先检查键是否过期,如果过期则删除。这种策略避免了定期删除可能带来的性能问题,但是可能会造成过期键一直占用内存空间,直到被访问时才删除,增加了内存使用。
定期删除和惰性删除可以结合使用,定期删除主要用于辅助惰性删除,确保内存占用在可控范围内。
6、怎么理解 Redis 事务
Redis 事务是一种将多个命令打包成一个操作单元,然后一次性、顺序执行的机制。在 Redis 中,事务是通过 MULTI、EXEC、DISCARD 和 WATCH 等命令来实现的。
1、MULTI: 开启一个事务,标志着事务的开始。
2、EXEC: 执行事务中的所有命令。
3、DISCARD: 取消事务,放弃执行事务中的所有命令。
4、WATCH: 监视一个或多个键,当这些键被其他客户端修改时,事务将被打断。
在 Redis 事务中,命令序列会被一次性发送到服务器执行,直到 EXEC 命令被调用为止。事务中的命令要么全部执行成功,要么全部执行失败,不存在部分执行的情况。这种原子性保证了事务的一致性。
通过使用 Redis 事务,可以将多个命令打包成一个原子操作单元,保证了数据的一致性,同时减少了网络通信的开销,提高了性能。
7、redis雪崩,击穿,穿透,以及在项目中如何解决的
在 Redis 中,存在三种常见的问题,即雪崩、击穿和穿透,它们分别是:
1、雪崩:指在缓存中大量的数据同时过期失效,导致大量的请求直接访问数据库,造成数据库负载剧增,甚至宕机的情况。这种现象类似于雪崩一样,一旦发生,会导致系统的崩溃。
2、击穿:指查询一个不存在的键,导致请求直接访问数据库,由于缓存中不存在该键,所以会直接请求数据库,如果并发量较大,会导致数据库负载过大。
3、穿透:指查询一个不存在的数据,而且查询的条件恒为真,导致请求直接访问数据库,如果请求量很大,会对数据库造成很大的压力。
篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
针对这些问题,可以采取以下解决方案:
1、对于雪崩问题,可以采取多种手段,如设置不同的过期时间、使用缓存预热、实现缓存数据的永不过期策略等,以减轻缓存数据同时失效的情况。
2、对于击穿问题,可以使用互斥锁或分布式锁等机制,防止大量请求同时查询数据库,同时可以考虑使用哨兵节点等方式提高 Redis 的高可用性。
3、对于穿透问题,可以在缓存中设置空值或默认值,并且可以使用布隆过滤器等技术拦截恶意请求,减少对数据库的直接访问。
综上所述,针对不同的问题,可以采取不同的策略和技术手段来解决,在项目中需要根据具体情况综合考虑采取适当的措施来保障系统的稳定性和性能。
8、redis在你项目中的应用场景
缓存token、缓存树状图、获取系统最大限制长度(例如excel的导入和导出最大长度)。
9、谈谈redis的哨兵机制
作用:Redis的哨兵机制监控主库是否故障,一旦主库宕机,哨兵会自动将一个从库切换成主库,无需人工干预,确保服务的连续性和可用性。这种自动化的故障转移减少了人工干预的需要,提高了系统的稳定性和可靠性。
原理:哨兵通过发送命令,等待redis响应,从而监控多个运行的redis实例。
10、redis持久化机制,RDB和AOF
RDB(Redis DataBase)和 AOF(Append Only File)是Redis提供的两种持久化机制。
RDB持久化是一种快照的方式,定期将内存中的数据集快照写入磁盘。它的优点是生成的快照文件相对较小,恢复速度快,适合用于备份数据或者灾难恢复。缺点是可能会在发生故障时丢失最后一次持久化之后的数据。
AOF持久化是一种追加写入日志文件的方式,记录了服务器执行的所有写操作命令,以此来记录数据变更。AOF文件在Redis重启时会根据文件内容重新执行命令来恢复数据。它的优点是能够保证较高的数据完整性和持久性,可以根据需要选择不同的同步策略。缺点是相比RDB,AOF文件通常较大,恢复速度相对较慢,且可能会有部分数据丢失。
11、谈谈redis集群
1、主从复制模式:
在主从复制模式中,主库负责处理客户端的读写请求,从库提供读操作的服务。当主库宕机后,需要手动将某个从库转换成新的主库,这个过程需要人工干预。
2、主从哨兵模式:
在主从哨兵模式中,除了主库和从库外,还有一个或多个哨兵节点负责监控主库的运行状态。当主库宕机后,哨兵会根据投票的方式自动将某个从库转换成新的主库,无需人工干预。
3、Cluster集群模式:
Redis Cluster是redis提供的一种分布式集群模式,该模式将数据分散存储在多个节点上,提供了高性能,高可用性和可伸缩性的数据存储解决方案。
三、mysql:
1、MySQL事务
1、原子性(Atomicity):指事务中的操作要么全部成功,要么全部失败。不存在部分操作成功而其他操作失败的情况。
2、一致性(Consistency):指事务执行前后,数据库从一个一致性状态转换到另一个一致性状态。即事务开始前和结束后,数据库的完整性约束没有被破坏。
3、隔离性(Isolation):指多个事务并发执行时,每个事务都相互隔离,彼此不会互相干扰。不同的隔离级别(读未提交、读已提交、可重复读、可串行化)决定了事务之间的隔离程度。
4、持久性(Durability):指一旦事务提交,对数据库的修改就会永久保存在数据库中,即使数据库发生故障也不会丢失提交的数据。持久性通过将事务的日志保存在磁盘上来实现。
对于MySQL,可以使用BEGIN、COMMIT和ROLLBACK语句来控制事务的开始、提交和回滚。
2、MySQL索引,索引失效场景
索引:
1、普通索引:最基本的索引类型,用于提高数据的查询速度。
2、主键索引:同一张表中只能有一个,值不能为NULL,创建主键时会自动创建,主要用于保证每一行数据的唯一性。
3、唯一索引:同一张表中可以有多个,用于保证字段的唯一性以及提高数据的查询速度。
4、外键索引:创建外键时会自动创建,使两表之间产生关联。
5、联合索引:同时提高多个字段的查询速度,需满足最左匹配原则,否则会索引失效。
最左匹配原则:
MySQL 的最左匹配原则是指在使用联合索引(也称为多列索引)时,查询条件中的列顺序应该与索引定义的列顺序相匹配,并且优先使用左边的列。
具体来说,如果在一个联合索引中定义了多个列,例如 (列 1, 列 2, 列 3) ,那么在查询时,
MySQL 会首先根据列 1 进行索引搜索。如果列 1 的值存在多个匹配项,那么 MySQL 会继续根据列 2 的值进行筛选,以此类推。
如果查询条件中只使用了联合索引的一部分列,例如只使用了列 2 和列 3,而没有使用列 1,那么索引仍然可以生效,但效果可能会受到一定影响。在这种情况下,MySQL 会利用已使用的列进行索引搜索,但无法利用索引的全部效果。
最左匹配原则的目的是为了提高查询效率和索引的利用效率。通过按照索引定义的顺序使用列,可以更好地利用索引的有序性和筛选能力,减少需要扫描的数据量,从而提高查询性能。
需要注意的是,最左匹配原则并不是绝对的,实际的查询优化还会受到其他因素的影响,例如数据分布、数据量、查询的复杂度等。在实际应用中,需要根据具体情况进行测试和分析,以确定最合适的索引策略和查询方式。
索引失效场景:
1、全表扫描
2、索引列进行了计算
3、使用函数进行索引列的操作
4、like操作符使用通配符开头
5、or条件中的部分条件没有索引
6、联合索引不满足最左匹配原则
3、sql优化
1、使用索引:为经常用于查询条件的列创建索引,加快数据检索速度。
2、避免使用select *:只检索需要的列,减少数据传输和处理时间。
3、适当分页查询:使用limit和offset进行分页,避免一次性加载大量数据。
4、使用连接(JOIN)优化:使用inner/left/right join等连接方式,避免笛卡尔积。
5、避免使用子查询:尽量避免使用子查询,可以使用join或者临时表代替。
6、使用 EXPLAIN 分析查询:通过EXPLAIN关键字分析查询执行计划,找出慢查询和需要优化的地方。
7、定期维护和优化数据库:定期清理无用数据、重建索引、分析表统计信息等,保持数据库性能稳定。
8、合理使用事务:将需要同时执行的操作放在同一个事务中,减少事务的开销。
9、定期优化数据库结构:定期检查和优化数据库表结构,包括索引、字段类型等。
10、适当使用缓存:对一些频繁查询但不经常变化的数据,可以考虑使用缓存,减少数据库压力。
11、避免在 WHERE 子句中对字段进行函数操作:这会导致索引失效,影响查询性能。
12、合理使用字段类型:选择合适的字段类型,避免使用过大或不必要的数据类型,减少存储空间和提高查询效率。
篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
5、MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别
1、读未提交(read uncommitted):
读未提交是指事务A可以读取到事务B未提交的数据。
这种隔离级别存在一种脏读现象,我们称读到了脏数据。
读未提交是最低的隔离级别。
2、读已提交(read committed):
读未提交是指事务A只能读取到事务B提交之后的数据。
这种隔离级别解决了脏读现象,但是存在一种不可重复读现象。
不可重复读是指在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取到的时候,读到的数据就是4条,3不等于4称为不可重复读取。这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实。
oracle数据库默认的隔离级别就是读已提交。
3、可重复读(repeatable read):
可重复读是指事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生变化,这就是可重复读。
这种隔离级别解决了不可重复读现象,但是存在一种幻读现象。
mysql数据库默认的隔离级别就是可重复读。
4、可串行化(serializable):
可串行化每一次读取到的数据都是最真实的,但是效率是最低的。
可串行化解决了所有的问题。
可串行化是最高的隔离级别。
6、CHAR 和 VARCHAR 的区别
1、存储方式:
CHAR 类型固定长度,当存储字符数不足指定长度时会用空格填充,占用空间固定。
VARCHAR 类型可变长度,实际占用的空间根据存储的数据长度而变化。
2、空间利用:
对于包含大量可变长度字符串的列,使用 VARCHAR 可以节省空间,因为它只存储实际使用的数据长度。
对于固定长度的字符串,使用 CHAR 可能更节省空间,因为它不需要存储额外的长度信息。
3、查询效率:
在查询和排序等操作时,CHAR 类型的效率可能更高,因为它的存储方式是固定长度的,无需额外的长度信息,而 VARCHAR 则需要额外的长度信息。
7、mysql的 ACID
1、原子性(Atomicity):指事务中的操作要么全部成功,要么全部失败。不存在部分操作成功而其他操作失败的情况。
2、一致性(Consistency):指事务执行前后,数据库从一个一致性状态转换到另一个一致性状态。即事务开始前和结束后,数据库的完整性约束没有被破坏。
3、隔离性(Isolation):指多个事务并发执行时,每个事务都相互隔离,彼此不会互相干扰。
不同的隔离级别(读未提交、读已提交、可重复读、可串行化)决定了事务之间的隔离程度。
4、持久性(Durability):指一旦事务提交,对数据库的修改就会永久保存在数据库中,即使数据库发生故障也不会丢失提交的数据。持久性通过将事务的日志保存在磁盘上来实现。
对于MySQL,可以使用BEGIN、COMMIT和ROLLBACK语句来控制事务的开始、提交和回滚。
8、查询索引的sql
SHOW INDEX FROM table_name;
9、查询当前数据库版本的sql
SELECT VERSION();
10、mysql 中 in 和 exists 区别
IN 主要用于比较某个字段的值是否在子查询结果集中,适用于简单的值匹配查询。
-
SELECT column_name(s)
-
FROM table_name
-
WHERE column_name IN (SELECT column_name FROM table_name WHERE condition);
EXISTS 主要用于检查子查询是否返回结果,适用于需要判断子查询是否为空的情况。通常用于复杂的条件过滤和连接查询。
-
SELECT column_name(s)
-
FROM table_name
-
WHERE EXISTS (SELECT column_name FROM table_name WHERE condition);
11、mysql统计函数有哪些
COUNT:用于统计查询结果集中的行数。
SUM:用于计算数值列的总和。
AVG:用于计算数值列的平均值。
MAX:用于获取数值列的最大值。
MIN:用于获取数值列的最小值。
12、mysql存储引擎有哪些
InnoDB:MySQL的默认存储引擎,支持事务、行级锁、外键等特性,适合于需要高并发、事务安全的应用场景。
MyISAM:适合于读密集型的应用,不支持事务和行级锁,但是速度快、存储占用小。
MEMORY:将数据存储在内存中,适合于临时表或者存储较小的数据集。
CSV:将数据以CSV格式存储在文件中,适合于导入导出数据。
ARCHIVE:使用压缩算法来存储数据,适合于存储大量历史数据。
NDB Cluster:适合于高可用、高并发的分布式数据库集群环境。
13、score表中有id、name、score三个字段,查询出每个成绩对应的数量,升序排
篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
-
SELECT score, COUNT(*) AS count
-
FROM score
-
GROUP BY score
-
ORDER BY score ASC;
13、student表中有id,name字段,只查出name重复的字段
-
SELECT name
-
FROM student
-
GROUP BY name
-
HAVING COUNT(*) > 1;
篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取