当前位置: 首页 > news >正文

数据库必会面试题(含答案)

面试Java程序员时,数据库相关的问题通常会考察以下几方面的知识。以下是一些常见的数据库面试题:

1. 数据库基础概念

  • **什么是数据库索引?**如何创建索引?什么时候应该使用索引?
  • 主键、外键、唯一键的区别是什么?
  • 什么是视图?它与表的区别是什么?
  • 事务是什么?事务的四大特性(ACID)是什么?
  • SQL 和 NoSQL 数据库的区别是什么?

2. SQL 查询

  • 如何使用 JOIN 查询多张表的数据?你能解释一下 内连接(INNER JOIN)、左连接(LEFT JOIN)、右连接(RIGHT JOIN) 和全连接(FULL JOIN)的区别吗?
  • GROUP BYHAVING 的区别与用法?
  • 如何进行 分页查询
  • 子查询关联子查询 的区别?
  • 如何写一个查询,查找某一列中重复的值?
  • 如何优化一条复杂的 SQL 查询?

3. 数据库性能与优化

  • 你如何排查数据库查询性能问题?
  • 数据库索引 在查询优化中扮演什么角色?哪些情况下会导致索引失效?
  • 什么是连接池?为什么使用连接池?如何在 Java 中使用连接池?
  • 如何避免数据库的死锁
  • 当数据库发生慢查询时,你会怎么处理?
  • Explain 语句是什么?如何分析一条 SQL 的执行计划?

4. 事务与锁机制

  • 什么是事务隔离级别?它们分别解决了什么问题?
  • 解释一下数据库中的锁机制,如悲观锁乐观锁
  • 如何实现分布式事务?你对 XA 事务二阶段提交协议 (2PC) 了解多少?
  • 在高并发场景下,如何保证数据一致性?

5. 数据库设计

  • 你如何设计一个表结构来实现多对多的关系?
  • 设计一个数据库模型来存储用户及其多种角色信息,如何设计表结构?
  • 你在进行数据库设计时,如何考虑范式与反范式?
  • 数据库的分区表分表如何设计?

6. ORM 框架

  • 你对 Java 的持久层框架了解多少?如何使用 MyBatis 或 Hibernate 与数据库交互?
  • 什么是懒加载?它可能会引发什么问题?
  • 如何使用 MyBatis 的 动态 SQL
  • 你是否遇到过 N+1 查询问题?如何解决?
  • 如何处理 MyBatis 中的缓存(一级缓存和二级缓存)?

7. SQL 注入

  • 什么是SQL 注入?如何防止 SQL 注入?
  • 在 Java 中如何通过预编译语句(PreparedStatement) 防止 SQL 注入?

这些问题涵盖了从数据库基础、SQL查询、性能优化、事务与锁机制到ORM框架等多个维度,考察候选人的理论知识与实际开发经验。

以下是针对上述常见数据库面试问题的简要答案:

1. 数据库基础概念

  • 什么是数据库索引?
    索引是一种用于加速数据库查询的特殊数据结构。索引类似于书的目录,通过它可以快速找到数据。常见的索引类型有B树、哈希索引等。
    什么时候应该使用索引?
    在查询频繁的列上,尤其是作为查询条件的列。不要对频繁更新的列、唯一性差的列(如性别)建立索引。

  • 主键、外键、唯一键的区别是什么?

    • 主键:唯一标识一条记录,不能为NULL,每个表只能有一个主键。
    • 外键:引用另一个表的主键,用于保持数据一致性,通常用于表示表之间的关系。
    • 唯一键:确保列中的所有值唯一,但可以为NULL,一个表可以有多个唯一键。
  • 什么是视图?它与表的区别是什么?
    视图是基于一个或多个表的虚拟表,它不存储实际数据,只是保存SQL查询结果。视图可以简化复杂的查询操作,而表实际存储数据。

  • 事务是什么?事务的四大特性(ACID)是什么?
    事务是对数据库的一组操作,必须作为一个单元完成。ACID特性:

    • 原子性:要么全部执行,要么全部不执行。
    • 一致性:事务执行前后,数据库的状态是一致的。
    • 隔离性:一个事务的执行不能被其他事务干扰。
    • 持久性:事务一旦提交,改变将永久保留。
  • SQL 和 NoSQL 数据库的区别是什么?

    • SQL:结构化查询语言,适用于关系型数据库,数据具有固定的表结构,支持ACID特性。
    • NoSQL:非结构化数据存储,如键值对、文档型、列族存储等,适合处理大规模数据,支持更灵活的数据模型。

2. SQL 查询

  • 如何使用 JOIN 查询多张表的数据?内连接、左连接、右连接、全连接的区别?

    • 内连接:只返回两张表中匹配的记录。
    • 左连接:返回左表的所有记录,即使右表没有匹配项。
    • 右连接:返回右表的所有记录,即使左表没有匹配项。
    • 全连接:返回两张表中所有记录,包括没有匹配的。
  • GROUP BY 和 HAVING 的区别与用法?

    • GROUP BY:用于分组查询,根据指定列对结果进行分组。
    • HAVING:用于过滤分组后的结果,常与聚合函数一起使用。
  • 如何进行分页查询?
    使用 SQL 中的 LIMITOFFSET(MySQL)或者 ROWNUM(Oracle)。如:

    SELECT * FROM table LIMIT 10 OFFSET 20;
    
  • 子查询与关联子查询的区别?

    • 子查询:独立查询,结果用于外部查询。
    • 关联子查询:子查询依赖外部查询的列,通常涉及主表和子查询表的列之间的关系。
  • 如何写一个查询,查找某一列中重复的值?

    SELECT column_name, COUNT(*)
    FROM table_name
    GROUP BY column_name
    HAVING COUNT(*) > 1;
    
  • 如何优化一条复杂的 SQL 查询?

    • 使用索引
    • 避免**SELECT ***,只查询必要的字段。
    • 避免在查询条件中对列使用函数操作符,这样会导致索引失效。
    • 使用EXPLAIN分析执行计划。

3. 数据库性能与优化

  • 如何排查数据库查询性能问题?
    使用 EXPLAIN 分析查询执行计划,查看索引使用情况,检查慢查询日志,优化 SQL 语句或调整索引。

  • 索引在查询优化中扮演什么角色?哪些情况下会导致索引失效?
    索引可以大大加快数据的查询速度,但在以下情况下会失效:

    • 使用 LIKE 模式匹配时,通配符在前面。
    • 在查询条件中对索引列使用函数或运算。
    • 对组合索引,未使用索引的最左前缀列。
  • 什么是连接池?为什么使用连接池?如何在 Java 中使用连接池?
    连接池是一种优化数据库连接的方法,它维护一定数量的数据库连接供应用程序复用。使用连接池减少频繁创建、销毁连接的开销,提升性能。在 Java 中,可以使用如 HikariCP、DBCP 或 C3P0 等库。

  • 如何避免数据库的死锁?

    • 确保事务以固定顺序获取锁。
    • 尽可能减少事务锁定的资源和时间。
    • 使用较低的事务隔离级别。
  • 当数据库发生慢查询时,你会怎么处理?

    • 使用 EXPLAIN 检查查询执行计划。
    • 检查是否有索引,或者是否存在索引失效的情况。
    • 优化 SQL 语句,使用适当的索引。
  • Explain 语句是什么?如何分析一条 SQL 的执行计划?
    EXPLAIN 用于分析 SQL 的执行计划,输出各个步骤的执行顺序、使用的索引、扫描的行数等信息。通过分析可以找出瓶颈并优化查询。

4. 事务与锁机制

  • 事务隔离级别及其解决的问题?

    • 读未提交(Read Uncommitted):可能出现脏读。
    • 读已提交(Read Committed):避免脏读,可能出现不可重复读。
    • 可重复读(Repeatable Read):避免脏读、不可重复读,可能出现幻读。
    • 序列化(Serializable):完全隔离,避免所有问题,但性能最低。
  • 悲观锁与乐观锁的区别?

    • 悲观锁:认为并发操作一定会发生冲突,因此在读取数据时就加锁。
    • 乐观锁:认为并发冲突很少发生,通过版本号等机制在更新时检测冲突。
  • 如何实现分布式事务?

    • 使用 XA 事务二阶段提交协议 (2PC)
    • 利用本地事务和消息队列实现最小化分布式事务,如 TCC 模型(Try-Confirm-Cancel)。

5. 数据库设计

  • 如何设计一个表结构来实现多对多的关系?
    需要引入第三张表(中间表),例如 studentcourse 的多对多关系,可以创建 student_course 中间表,包含 student_idcourse_id

  • 范式与反范式?
    范式是为了消除数据冗余。反范式有时为了查询性能,会允许一些冗余,以减少复杂查询的次数。

6. ORM 框架

  • 什么是懒加载?可能会引发什么问题?
    懒加载在需要使用数据时才从数据库中加载对象。可能导致的N+1 查询问题是,主查询执行一次,每个子对象执行一次查询,性能较差。

  • 如何解决 N+1 查询问题?
    使用**预加载(eager loading)**或通过查询语句使用 JOIN

7. SQL 注入

  • 什么是 SQL 注入?如何防止 SQL 注入?
    SQL 注入是通过将恶意 SQL 代码插入输入字段来执行非预期的查询。防止 SQL 注入的方法:

    • 使用预编译语句(PreparedStatement)
    • 进行输入验证
    • 避免拼接 SQL 语句。
    String query = "SELECT * FROM users WHERE username = ? AND password = ?";
    PreparedStatement stmt = connection.prepareStatement(query);
    stmt.setString(1, username);
    stmt.setString(2, password);
    

http://www.mrgr.cn/news/54731.html

相关文章:

  • ruoyi域名跳转缓存冲突问题(解决办法修改:session名修改session的JSESSIONID名称)
  • Vue2、Vue3温习解惑知识点
  • 倪师学习笔记-天纪-斗数星辰介绍
  • 【网安第三章】——XSS
  • 实验报告3-数据库框架实现数据操作1
  • Uiautomator2与weditor配置一直报错咋办
  • 数据结构与算法——Java实现 41.对称二叉树
  • LeetCode Hot100 - 滑动窗口篇
  • JavaScript 数组的魔法
  • JVM面试题
  • Linux笔记之文件查找和搜索命令which,find,locate,whereis总结
  • 基于x86_64汇编语言简单教程6: 变量,常量,与运算
  • Axure中继器时间筛选
  • 将 centos7 的根分区由非逻辑卷转换成使用逻辑卷
  • halcon的intensity算子到底是Mean灰度均值最大表示清晰度最高,还是Deviation灰度偏差最大表示清晰度最高?
  • 深入了解 Flannel(2):vxlan模式下的跨主机pod通信
  • Vue框架基础知识
  • 电能表预付费系统-标准传输规范(STS)(14)
  • 【数据结构】【单调栈】视野总和
  • 动态规划之打家劫舍
  • Python 类
  • 【计网】从零开始理解TCP协议 --- 拥塞控制机制,延迟应答机制,捎带应答,面向字节流
  • 【OD】【E卷】【真题】【100分】最大利润贪心的商人(PythonJavaJavaScriptC++C)
  • Docker无法拉取镜像解决办法
  • 程序员数学:用Python学透线性代数和微积分 中文目录
  • #P3014. 数字游戏