Java 技术面试常见问题解析

1.说说Mybatis的缓存机制:

MyBatis 是一个优秀的持久层框架,它简化了企业应用开发中数据库操作的代码。MyBatis 提供了一级缓存和二级缓存机制来优化对数据库的访问。

一级缓存 (SqlSession级别的缓存)

一级缓存是 MyBatis 中默认开启且无法关闭的缓存机制。它存在于 SqlSession 的生命周期内,当同一个 SqlSession 实例执行相同的查询语句时,MyBatis 会首先检查一级缓存中是否已经有结果存在。如果有,则直接返回缓存中的数据,不再发起数据库查询;如果没有,则查询数据库并将结果存入缓存中。

一级缓存的生命周期与 SqlSession 绑定,因此在以下情况下,一级缓存会被清空:

  • 提交或回滚事务后;
  • 执行任何更新、插入或删除操作后;
  • 手动调用 clearCache() 方法;
  • 当 SqlSession 关闭时。

二级缓存 (Mapper级别的缓存)

二级缓存可以跨多个 SqlSession 使用,并且可以在不同的 SqlSession 之间共享。它通常应用于多个用户可能会查询相同的数据的情况。要启用二级缓存,需要做如下配置:

  1. 在核心配置文件(如 mybatis-config.xml)中设置 来全局开启二级缓存。

  2. 在具体的 Mapper XML 文件中添加 或者更复杂的 配置来为特定的命名空间开启缓存。

使用二级缓存需要注意的问题包括但不限于:

  • 确保实体类是可序列化的,因为缓存对象可能被序列化到磁盘或者分布式缓存系统中。
  • 不能对频繁更新的数据使用二级缓存,否则会导致脏读问题。
  • 注意并发情况下的缓存一致性问题。

自定义缓存

MyBatis 还允许开发者通过实现自己的缓存接口来自定义缓存策略。你可以通过继承 Cache 接口创建自定义缓存,并将其集成到 MyBatis 的缓存架构中。

总的来说,合理地利用 MyBatis 的缓存机制可以显著提高应用程序的性能,但同时也需要考虑到缓存带来的潜在问题,如数据的一致性和时效性等。

2.JDBC 编程有哪些步骤?

JDBC(Java Database Connectivity)编程是Java应用程序连接和操作数据库的标准方法。以下是使用JDBC进行编程的基本步骤:

  • 加载JDBC驱动:

    • 早期的JDBC版本需要显式地使用 Class.forName() 方法来加载特定数据库的JDBC驱动程序类。
    • 从JDBC 4.0开始,只要JDBC驱动在类路径中,DriverManager 将自动加载它,因此不再需要显式调用 Class.forName()。
  • 获取数据库连接:

    • 使用 DriverManager.getConnection() 方法提供数据库URL、用户名和密码来建立与数据库的连接。
    • 或者使用 DataSource 接口提供的方法来获取连接,这通常用于企业级应用中,因为 DataSource 支持连接池等高级特性。
  • 创建Statement对象:

    • 使用 Connection.createStatement() 创建一个 Statement 对象用于执行SQL语句。
    • 或者使用 Connection.prepareStatement() 来创建一个预编译的 PreparedStatement 对象,以提高性能并防止SQL注入攻击。
    • 如果需要调用存储过程,则可以使用 Connection.prepareCall() 创建 CallableStatement 对象。
  • 执行SQL语句:

    • 对于查询操作,使用 Statement.executeQuery() 执行SQL SELECT语句,并返回一个 ResultSet 对象。
    • 对于更新操作(如INSERT, UPDATE, DELETE),使用 Statement.executeUpdate() 执行这些语句,该方法返回受影响的行数。
  • 处理结果集(仅适用于查询):

    • 使用 ResultSet 的各种 getXXX() 方法来遍历结果集并提取数据。
    • 注意要正确处理 ResultSet 中的数据类型转换。
  • 清理资源:

    • 关闭 ResultSet, Statement 和 Connection 等资源非常重要。未关闭的资源可能会导致内存泄漏或数据库连接耗尽。
    • 最好是在finally块中或者使用try-with-resources语句(Java 7及以上)来确保即使发生异常也能正确关闭资源。

示例代码片段如下:

try (Connection conn = DriverManager.getConnection(dbUrl, user, password);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT id, name FROM users")) {while (rs.next()) {// Process each row of the result set.int id = rs.getInt("id");String name = rs.getString("name");System.out.println("ID: " + id + ", Name: " + name);}
} catch (SQLException e) {e.printStackTrace();
}

这段代码展示了如何使用 try-with-resources 自动管理资源关闭,并且执行了一个简单的查询操作。

3. MyBatis 中见过什么设计模式?

MyBatis 框架中使用了多种设计模式,以提高代码的可维护性、可扩展性和灵活性。以下是 MyBatis 中常见的一些设计模式:

1. 工厂模式 (Factory Pattern)

MyBatis 使用工厂模式来创建 SqlSessionFactory。SqlSessionFactoryBuilder 根据配置信息(XML 或 Java 配置)构建 SqlSessionFactory 实例。SqlSessionFactory 负责创建 SqlSession 对象,而 SqlSession 是执行数据库操作的主要入口。

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {// Use the session to execute SQL statements.
}

2. 代理模式 (Proxy Pattern)

MyBatis 利用 JDK 动态代理或 CGLIB 创建 Mapper 接口的代理实例。这些代理对象拦截方法调用,并将它们转换为对底层 JDBC API 的调用,从而隐藏了数据访问层的实现细节。

UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectAllUsers();

3. 建造者模式 (Builder Pattern)

SqlSessionFactory 的创建过程通过 SqlSessionFactoryBuilder 来完成,它根据不同的配置选项逐步构建出最终的对象。建造者模式使得可以灵活地创建复杂的对象而不必使用大量的构造函数参数。

4. 模板方法模式 (Template Method Pattern)

在 MyBatis 内部,对于 CRUD 操作的流程有一个大致固定的步骤:创建连接 -> 创建语句 -> 执行语句 -> 处理结果 -> 关闭资源。这个流程由框架提供,用户只需要定义具体的 SQL 和映射规则,这正是模板方法模式的应用。

5. 单例模式 (Singleton Pattern)

SqlSessionFactory 通常在整个应用程序生命周期内只被创建一次,并且可以被多个线程安全地共享和重用。因此,它通常被设计成单例模式。

6. 适配器模式 (Adapter Pattern)

MyBatis 的类型处理器(TypeHandler)用于在 JDBC 类型和 Java 类型之间进行转换,起到了适配器的作用,使得不同类型的对象能够兼容工作。

7. 策略模式 (Strategy Pattern)

当涉及到查询缓存时,MyBatis 允许用户选择不同的缓存实现(如一级缓存、二级缓存等),并且可以通过插件机制添加自定义的缓存策略,这体现了策略模式的思想。

这些设计模式共同作用,使得 MyBatis 成为了一个高效、灵活且易于使用的持久层框架。

4.MyBatis 中比如 UserMapper.java 是接口,为什么没有实现类还能调用?

在 MyBatis 中,UserMapper.java 是一个接口,而不需要提供实现类的原因是因为 MyBatis 使用了 动态代理 的机制。具体来说,MyBatis 利用 Java 的反射和动态代理功能(如 JDK 动态代理或 CGLIB)来为这些接口创建代理实例。当你调用 session.getMapper(UserMapper.class) 时,MyBatis 会根据你提供的 Mapper 接口生成一个代理对象。

这个代理对象能够拦截你对 Mapper 接口中定义的方法的调用,并将它们转换成相应的 SQL 操作。例如,如果你有一个方法 List<User> selectAllUsers();,那么 MyBatis 会查找与之对应的 XML 映射文件中的 <select> 标签或者注解配置,并执行该标签内定义的 SQL 语句,然后将结果集映射到返回的对象中。

下面是 MyBatis 如何做到这一点的大致流程:

  • 配置映射信息:你需要通过 XML 文件(如 UserMapper.xml)或者注解的方式为接口中的每个方法指定相应的 SQL 语句。
  • 获取 Mapper 实例:使用 SqlSession 提供的 getMapper(Class type) 方法传入你的 Mapper 接口类型,MyBatis 会为你创建一个代理实例。
  • 代理方法调用:当你调用代理实例上的方法时,实际是触发了 MyBatis 内部逻辑去解析并执行对应的 SQL 语句。
  • 执行 SQL 和处理结果:MyBatis 使用底层的 JDBC 连接执行 SQL 语句,并将结果集映射到 Java 对象,最后返回给调用者。

由于这一切都是在运行时由 MyBatis 自动完成的,所以开发者无需编写具体的实现类。这种方式不仅简化了代码,还提高了灵活性,因为你可以轻松地更改 SQL 语句而不必修改业务逻辑代码。此外,它也遵循了面向接口编程的最佳实践,有助于提高代码的可测试性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Word使用分隔符实现页面部分分栏

文章目录 Word使用分隔符实现页面部分分栏分隔符使用页面设置 Word使用分隔符实现页面部分分栏 分隔符使用 word中的分隔符&#xff1a; 前面不分栏&#xff0c;后面分栏(或前面分栏&#xff0c;后面不分栏)&#xff0c;只需要在分隔位置处插入分隔符&#xff1a;“连续”即…

掌握 Spring Boot 中的 WebClient:何时以及为何使用它而不是 RestTemplate

在开发 Spring Boot 应用程序时&#xff0c;与 RESTful Web 服务进行通信是一项常见需求。从历史上看&#xff0c;开发人员已将RestTemplate用于此目的。然而&#xff0c;随着反应式编程的出现和对更高效资源利用的需求&#xff0c;WebClient已成为首选。本文探讨了RestTemplat…

主曲率为常数时曲面分类

主曲率为常数 ⇔ K , H \Leftrightarrow K,H ⇔K,H 为常数&#xff0c;曲面分类&#xff1a; 1.若 k 1 k 2 0 k_1k_20 k1​k2​0,则 S S S为全脐点曲面——平面的一部分&#xff1b; 2.若 k 1 k 2 ≠ 0 k_1k_2\neq0 k1​k2​0,则 S S S为全脐点曲面——球面的一部分&…

asp.net core发布配置端口号,支持linux

方式一&#xff0c;修改配置文件 appsettings.json 找到文件 appsettings.json&#xff0c; 添加如下节点配置&#xff0c;在linux环境需要设置0.0.0.0才可以正常代表本机&#xff0c;然后被其他机器访问&#xff0c;此处设置端口8000&#xff0c; "Kestrel": {&quo…

【安当产品应用案例100集】033-安当TDE透明加密在移动存储加密中的应用案例

背景介绍 随着移动互联网的普及&#xff0c;企业和个人越来越依赖移动存储设备&#xff0c;如U盘、移动硬盘以及云存储服务进行数据的存储和传输。然而&#xff0c;这种便捷性也带来了数据安全的隐患。如何确保存储在移动设备上的数据不被非法访问和泄露&#xff0c;成为企业和…

【linux 内存】cat /proc/meminfo、free

cat /proc/meminfo 各字段详解 /proc/meminfo是了解Linux系统内存使用状况的主要接口&#xff0c;我们最常用的”free”、”vmstat”等命令就是通过它获取数据的 &#xff0c;/proc/meminfo所包含的信息比”free”等命令要丰富得多&#xff0c;因此需要了解这些字段的含义。 …

Android HandlerThread、Looper、MessageQueue 源码分析

Android HandlerThread、Looper、MessageQueue 源码分析 简介 在 Android 开发中&#xff0c;大家应该对 HandlerThread 有一定了解。顾名思义&#xff0c;HandlerThread 是 Thread 的一个子类。与普通的 Thread 不同&#xff0c;Thread 通常一次只能执行一个后台任务&#x…

配置PostgreSQL用于集成测试的步骤

在进行软件开发时&#xff0c;集成测试是确保各个组件能够协同工作的关键环节。PostgreSQL作为一种强大的开源数据库系统&#xff0c;常被用于集成测试中。下面将详细介绍如何在不同的环境中配置PostgreSQL以支持集成测试。 1. 选择并安装PostgreSQL 首先&#xff0c;你需要根…

WebRTC搭建与应用(一)-ICE服务搭建

WebRTC搭建与应用(一) 近期由于项目需要在研究前端WebGL渲染转为云渲染&#xff0c;借此机会对WebRTC、ICE信令协议等有了初步了解&#xff0c;在此记录一下&#xff0c;以防遗忘。 第一章 ICE服务搭建 文章目录 WebRTC搭建与应用(一)前言一、ICE是什么&#xff1f;二、什么…

【学习笔记】深入浅出详解Pytorch中的View, reshape, unfold,flatten等方法。

文章目录 一、写在前面二、Reshape&#xff08;一&#xff09;用法&#xff08;二&#xff09;代码展示 三、Unfold&#xff08;一&#xff09;torch.unfold 的基本概念&#xff08;二&#xff09;torch.unfold 的工作原理&#xff08;三&#xff09; 示例代码&#xff08;四&a…

深入理解 MySQL 索引

引言 在数据库管理中&#xff0c;索引&#xff08;Index&#xff09;是提高查询性能的关键技术之一。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;广泛应用于各种规模的应用程序中。本文将深入探讨 MySQL 中的索引概念、类型、工作原理以及最佳实践&#xff0c;帮助…

利用notepad++删除特定关键字所在的行

1、按组合键Ctrl H&#xff0c;查找模式选择 ‘正则表达式’&#xff0c;不选 ‘.匹配新行’ 2、查找目标输入 &#xff1a; ^.*关键字.*\r\n (不保留空行) ^.*关键字.*$ (保留空行)3、替换为&#xff1a;&#xff08;空&#xff09; 配置界面参考下图&#xff1a; ​​…

docker安装和换源

安装&#xff1a; https://www.runoob.com/docker/ubuntu-docker-install.html sudo apt-get remove docker docker-engine docker.io containerd runcsudo apt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-commoncurl -fsS…

CSSmodule的作用是什么

CSS Modules的作用主要体现在以下几个方面&#xff1a; 1. 解决全局样式污染问题 在传统的CSS管理方式中&#xff0c;样式定义通常是全局的&#xff0c;这很容易导致全局样式污染。当多个组件或页面共享同一个样式时&#xff0c;可能会出现样式冲突和覆盖的情况&#xff0c;从…

创建第一个QML项目

文章目录 使用 Qt Creator 创建 Qt Quick 项目详解为什么选择 Qt Creator&#xff1f;1. 打开 Qt Creator2. 选择项目模板3. 设置项目名称与路径4. 定义项目细节5. 配置构建套件6. 检查项目配置7. 编译并运行项目后续操作修改界面添加功能 总结 使用 Qt Creator 创建 Qt Quick …

【k8s集群应用】K8S二进制安装大致步骤(简略版)

文章目录 K8S二进制安装部署etcd测试etcd集群&#xff08;可选&#xff09;恢复etcd数据库 部署master组件部署node组件K8S kubeadm安装关键命令更新kubeadm安装的K8S证书有效期方法一方法二查看证书有效期 K8S二进制安装 部署etcd 使用cfssl工具签发证书和私钥下载解压etcd软…

瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现

瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 文章目录 3 项目组件优化3.1 实现Swagger文档输出3.2 实现logback日志打印3.3 实现表单校验功能3.4 实现请求参数和响应参数的打印 3 项目组件优化 3.1 实现Swagger文档输出 1&#xff09;在application.yml中增加knife4…

leetcode刷题-回溯算法04

代码随想录回溯算法part01| 491.递增子序列、46.全排列、47.全排列II 491.递增子序列46.全排列47.全排列II 491.递增子序列 leetcode题目链接 代码随想录文档讲解 思路&#xff1a; 与上一题不同&#xff0c;不能用used列表&#xff0c;因为这个题不能排序&#xff0c; 在每一…

基于字节大模型的论文翻译(含免费源码)

基于字节大模型的论文翻译 源代码&#xff1a; &#x1f44f; star ✨ https://github.com/boots-coder/LLM-application 展示 项目简介 本项目是一个基于大语言模型&#xff08;Large Language Model, LLM&#xff09;的论文阅读与翻译辅助工具。它通过用户界面&#xff08…

mysql的事务控制和数据库的备份和恢复

事务控制语句 行锁和死锁 行锁 两个客户端同时对同一索引行进行操作 客户端1正常运行 客户端2想修改&#xff0c;被锁行 除非将事务提交才能继续运行 死锁 客户端1删除第5行 客户端2设置第1行为排他锁 客户端1删除行1被锁 客户端2更新行5被锁 如何避免死锁 mysql的备份和还…