1. 请你讲解一下数据连接池的工作机制?
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的连接并将其标记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量由配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接标记为空闲,其他调用就可以使用这个连接。
2. 你了解继承映射吗,请简单讲讲你的理解
- 每个继承结构一张表(table per class hierarchy),不管多少个子类都用一张表。
- 每个子类一张表(table per subclass),公共信息放一张表,特有信息放单独的表。
- 每个具体类一张表(table per concrete class),有多少个子类就有多少张表。
第一种方式属于单表策略,其优点在于查询子类对象的时候无需表连接,查询速度快,适合多态连接;缺点是可能导致表很大。
后两种方式属于多表策略,其优点在于数据存储紧凑,其缺点是需要进行连接查询,不适合多态查询。
3. 请介绍一些你了解的数据库优化方法
- 选取最适用的字段属性。
- 使用连接(JOIN)来代替子查询(Sub-Queries)。
- 使用联合(UNION)来代替手动创建的临时表
4. 请你说明一下 left join 和 right join 的区别?
- left join(左连接)返回包括左表中的所有记录和右表中联结字段相等的记录
- right join(右连接)返回包括右表中的所有记录和左表中联结字段相等的记录
5. 请你介绍一下,数据库的三个范式?
第一范式的目标是确保每列的原子性:如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF);
第二范式首先满足第一范式,并且表中非主键列不存在对主键的部分依赖。第二范式要求每个表只描述一件事情。
第三范式定义是,满足第二范式,并且表中的列不存在对非主键列的传递依赖。除了主键订单编号外,顾客姓名依赖于非主键顾客编号。
6. 请你介绍一下,数据库乐观锁和悲观锁
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
乐观锁:假定不会发生并发冲突,只是在提交操作时是否违反数据完整性。
7. 请你介绍一下数据库的隔离级别
- 未提交读:允许脏读,也就是可能读取到其他回话中未提交事务修改的事务。
- 已提交读:只能读取到已提交的数据。Oracle等多数数据库默认都是该级别(不重复读)。
- 可重复读:确保可以多次从一个字段中读取到相同的值,在一个事务期间禁止其他事务对这个字段进行更新。
- 串行读:每次读都需要获得表级共享锁,读写相互都会阻塞。
8. 请你说一说,MySQL数据库的两种引擎 区别
InnoDB是聚集索引,支持事务,支持行级锁;
MyISAM是非聚集索引,不支持事务,只支持表级锁;
9. 谈一谈,JDBC中如何进行事务处理?
- Connection提供了事务处理的方法,通过调用setAutoCommit(false)可以设置手动提交事务;
- 当事务提交后手动commit()显式提交事务;
- 如果在事务处理过程中发生异常则通过rollback()进行事务回滚。
- JDBC 3.0中还引入了Savepoint(保存点)的概念,允许通过代码设置保存点并让事务回滚到指定的保存点。
10. 我们使用JDBC操作数据库时,经常遇到性能问题,请你说明一下如何提升读取数据的性能,以及更新数据的性能?
- 要提升读取数据的性能,可以通过指定结果集(ResultSet)对象的setFetchSize()方法指定每次抓取的记录数(典型的空间换时间策略);
- 要提升更新数据的性能可以使用PreparedStatement语句构建批处理,将若干SQL语句置于一个批处理中执行。
11. 请你讲讲 Statement 和 PreparedStatement 的区别?哪个性能更好?
PreparedStatement接口代表预编译的语句,它主要的优势是可以减少SQL的编译错误并增加SQL的安全性,减少SQL注入的可能性。
PreparedStatement中的SQL语句是可以带参数的,避免了使用字符串连接拼接SQL语句的麻烦和不安全。
当批量处理SQL或频繁执行相同的查询时,PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快,不用再次编译和生成执行计划。
所以总体上,PreparedStatement在使用和性能方面都比Statement更有优势。
12. 请你谈谈JDBC的反射,以及它的作用?
通过反射com.mysql.jdbc.Driver类,实例化该类的时候会执行该类内部的静态代码块,该代码块会在Java实现的DriverManager类中注册自己,DriverManager管理所有已经注册的驱动类,当调用DriverManager.getConnection方法时会遍历这些驱动类,并尝试去连接数据库,只要有一个能连接成功,就返回Connection对象,否则则报异常。
13. 数据库连接步骤
- 加载驱动类
- 获取连接对象
- 获取执行对象,传入sql
- 传入sql需要参数
- 执行并接收返回结果/值
- 处理结果/值
- 关闭所有资源