Java面试题 - 03

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 再接着Java面试题 - 02,说说剩下的内容。

三、框架篇:


(三)、mybatis


1. JDBC编程有什么不足?mybatis是如何解决的?


答:主要有以下几个方面:


  • JDBC中数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能
    mybatis解决:在mybatis配置文件中配置数据连接池,使用连接池管理数据库连接。
  • Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
    mybatis解决:将Sql语句配置在mapper.xml文件中,与java代码分离。
  • 向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数一一对应。
    mybatis解决: Mybatis自动将java对象映射至sql语句。
  • 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历。
    mybatis解决:Mybatis自动将sql执行结果映射至java对象。


2. mybatis编程步骤是怎样的?


答:步骤如下:


  • 创建SqlSessionFactory
  • 通过SqlSessionFactory创建 SqlSession
  • 通过sqlsession执行数据库操作
  • 调用session.commit()提交事务
  • 调用session.close()关闭会话


3. Mybatis中#和$的区别?


答: 使用${参数}就是单纯的字符串拼接,拼接完成后才会对SQL进行编译、执行,所以性能较低;#{参数名}在SQL中相当于一个参数占位符“?”,用来补全预编译语句,所有这种方式可以防止SQL注入,它补全预编译语句时,会在此参数值两端加了单引号。但是有些地方必须要用$,比如参数是表名的时候:${表名},因为如果使用#,sql语句就会变成 '表名',会加上单引号,这样就找不到该表。总之,能用#就不要用$。


4. 使用MyBatis的mapper接口调用时有哪些要求?


答:有以下规则:


  • Mapper接口方法名和mapper.xml中对应的sql的id相同 ;
  • Mapper接口方法的输入参数类型和mapper.xml中对应的sql 的parameterType的类型相同 ;
  • Mapper接口方法的输出参数类型和mapper.xml中对应的sql的resultType的类型相同 ;
  • Mapper.xml文件中的namespace即是mapper接口的类路径。


5. 谈谈mybatis中的一级缓存和二级缓存。


答:


  • 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。
  • 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),即对该namespance对应的配置文件中所有的select操作结果都缓存,这样不同线程之间就可以共用二级缓存。并且可自定义存储源,如 Ehcache。启动二级缓存:在mapper配置文件中加上:<cache />。


6. 在进行插入操作时如何回传ID?


答:在insert标签中配置如下属性即可:

<insert id="insert" parameterType="com.test.User" keyProperty="userId" useGeneratedKeys="true" > 
   ......
</insert>


用keyProperty指定Id属性,把useGeneratedKeys设置为true即可。


7. mapper接口工作原理是什么?


答:mapper接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为mapper接口生成代理对象,代理对象会拦截接口方法,转而执行对应的sql,然后将sql执行结果返回。


8. mapper接口里的方法可以重载吗?为什么?


答:不能重载。对应的xml映射文件是根据方法名将方法与sql语句绑定的,如果重载,将无法区分绑定哪个方法。


9. 你了解mybatis的动态SQL吗?


答:动态SQL可以完成逻辑判断和动态拼接sql的功能。在mybatis的xml映射文件中,我们可以标签的形式编写动态sql。常用的动态sql标签有<if>、<where>、<set>等。


10. Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?


答:Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置lazyLoadingEnabled=true来启用延迟加载。它的原理是使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。


(四)、hibernate


1. 简单的说一下hibernate的开发流程。


答:步骤如下:


  • 加载 hibernate 的配置文件,读取其他配置文件(jdbc.properties、表与对象关系映射文件);
  • 创建 SessionFactory 会话工厂;
  • 打开 session 获取连接,构造 session 对象(一次会话维持一个数据连接,也是一级缓存)
  • 开启事务;
  • 使用session进行操作 ;
  • 提交事务;
  • 关闭session;
  • 关闭SessionFactory 。


2. 说说hibernate中对象的三种状态。


答:hibernate中,对象有以下3种状态:


  • 临时态:直接new出来的对象,不处于session的管理,数据库中没有对象的记录;调用save方法后就变成持久态。
  • 持久态:当调用session的save/saveOrUpdate/get/load/list等方法的时候,对象就是持久化状态。处于session的管理,数据库中有对应的记录;调用delete方法后变成临时态,调用session.close()后就变成了游离态。
  • 游离态:Session关闭后,对象的状态就是游离态。不处于session的管理,数据库中有对应的记录;调用update方法后又变成持久态。


3. 你知道hibernate的缓存吗?


答:使用缓存的目的就是减少对数据库的访问次数,以提高hibernate的执行效率。


hibernate有一级缓存和二级缓存之分:


  • 一级缓存:也叫做session的缓存,它可以在session范围内减少数据库的访问次数,只在session范围有效,Session关闭,一级缓存失效,不同的session不会共享缓存数据。当调用session的 save/saveOrUpdate/get/load/list/iterator 方法的时候,都会把对象放入session的缓存中。 Session的缓存由hibernate维护, 用户不能操作缓存内容; 如果想操作缓存内容,必须通过hibernate提供的evit/clear方法操作。
  • 二级缓存:Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据。 这个缓存也叫二级缓存。Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可,不想用,直接移除配置即可。如果用户觉得hibernate提供的缓存框架不好用,可以换其他的缓存框架或自己实现缓存框架都可以。


4. hibernate有几种查询方式?


答:hibernate有3种查询方式:


  • HQL查询:面向对象的查询语言,提供了丰富灵活的查询方式。例子:

String hql = "select userName from User"; // userName是实体类属性名而非表的字段名,User是实体类名
Query query = session.createQuery(hql);
List<Object> nameList = query.list();


  • QBC(Query By Criteria)查询:Criteria对象提供了一种面向对象的方式查询数据库。Criteria对象需要使用Session对象来获得。例子:

Criteria c = session.createCriteria(User.class);
c.add(Restrictions.eq("userName", "James"));
List<User> userList = c.list();


  • 原生SQL查询:就是使用原生的SQL语句进行查询。例子:

String sql = "select id,username,userpwd from t_user";
List list = session.createSQLQuery(sql).list();


5. hibernate的ORM思想你了解多少?


答:ORM 指的是对象关系映射(Object RelationShip Mapping ),指的就是实体类对象和数据库中的表关系进行一一对应,实现通过操作实体类对象来更改数据库里边的数据信息。这就是对象关系映射。hibernate框架也是一个orm框架,主要是通过主配置文件和实体类对应的映射配置文件来实现对象关系映射。


6. 你知道hibernate的懒加载吗?


答:通过设置lazy属性开启懒加载(hibernate3之后默认开启)。当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,节省了服务器的内存开销,从而提高了服务器的性能。比如使用hibernate进行查询,可以使用get方法,也可以使用load方法,get方法不支持懒加载,而load方法支持。get方法会先查一级缓存,再查二级缓存,然后查数据库,如果没有找到会返回null。load方法会先查一级缓存,如果没有找到,就创建代理对象,等需要的时候去查询二级缓存和数据库。也就是说,使用load方法的时候,并不会立刻去数据库查找,等你真的要用到该对象的时候,才会去数据库查找,这就是懒加载。


7. hibernate和mybatis有何异同?


答:异同如下:


(1).相同点:


  • Hibernate与MyBatis都是由XML配置文件生成SessionFactory,然后由SessionFactory 生成 Session,最后由 Session 来开启执行事务和 SQL 语句。其中两者的SessionFactory,Session的生命周期都是差不多的。
  • Hibernate和MyBatis都支持JDBC和JTA事务处理。


(2).不同点:


  • hibernate是全自动,而mybatis是半自动。hibernate完全可以通过对象关系模型实现对数据库的操作,会自动生成sql。而mybatis仅有基本的字段映射,对数据的操作还需要自己编写sql来实现。
  • hibernate数据库移植性远大于mybatis。因为hibernate不需要自己编写sql语句,所有与数据库解耦;而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性,用了很多数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。
  • hibernate拥有完整的日志系统,mybatis则欠缺一些。hibernate日志系统非常健全,涉及广泛,而mybatis则除了基本记录功能外,功能薄弱很多。
  • sql优化上,mybatis要比hibernate方便很多。由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql。


总的来说,mybatis小巧灵活,易于使用,而hibernate学习成本相对较高,数据库移植性好。


8. 谈谈Hibernate中inverse的作用。


答:inverse属性默认是false,就是说双方都维护关联关系。 比如Student和Teacher是多对多关系,用一个中间表TeacherStudent维护。如果Student这边inverse=”true”, 那么关系就由Teacher维护,就是说当插入Student时,不会操作TeacherStudent表。只有Teacher插入或删除时才会触发对中间表的操作。所以两边都inverse=”true”是不对的,会导致任何操作都不触发对中间表的影响;当两边都inverse=”false”或默认时,会导致在中间表中插入两次关系。


9. Hibernate有哪些核心接口?


答:有如下核心接口:


  • Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对象;
  • SessionFactory 接口:初始化Hibernate,充当数据存储源的代理,创建session 对象,sessionFactory 是线程安全的,意味着它的同一个实例多个线程共享;
  • Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的, 避免多个线程共享同一个session;
  • Transaction 接口:管理事务;
  • Query 和Criteria 接口:执行数据库的查询。


(五)、Redis


1. 什么是redis?


答:redis是使用C语言编写的典型的NoSQL数据库,它是一个key-value存储系统,数据存储在内存中,所以存取速度非常快。


2. 为什么redis要把数据放到内存中?


答:Redis为了达到最快的读写速度将数据都读到内存中,并定期将数据写入磁盘。如果不将数据放在磁盘中,会严重影响 redis 的性能。


3. redis支持哪些数据类型?


答:redis有5种基本数据类型,分别是String(字符串)、Hash(字典)、List(列表)、Set(集合)、Zset(有序集合)。


4. 说说redis的优缺点。


答:优缺点如下:


(1). 优点:


  • 由于是基于内存的,所以性能极高。
  • 支持丰富的数据类型。
  • Redis 的所有操作都是原子性的。


(2). 缺点:


  • 由于是内存数据库,所以单台机器存储的数据量,跟机器本身的内存大小。
  • 如果进行完整重同步,由于需要生成 rdb 文件并进行传输,会占用主机的 CPU,消耗带宽。




相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
33 2
|
14天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
19天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
15天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
41 4
|
16天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
57 4
|
1月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
92 1
Java面试题之Java集合面试题 50道(带答案)
|
28天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
54 5
|
27天前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
21 1
|
1月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
28 3
|
2月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
427 37