离线下载
PDF版 ePub版

极客学院团队出品 · 更新于 2018-11-28 11:00:43

JDBC 与数据库

1. 下列属于关系型数据库的是()

A. Oracle
B. MySql
C. IMS
D. MongoDB

答案:AB

解答:IMS(Information Management System )数据库是 IBM 公司开发的两种数据库类型之一;

一种是关系数据库,典型代表产品:DB2; 另一种则是层次数据库,代表产品:IMS层次数据库。

非关系型数据库有MongoDB、memcachedb、Redis等。

2. 在进行数据库编程时,连接池有什么作用?

答:由于创建连接和释放连接都有很大的开销(尤其是数据库服务器不在本地时,每次建立连接都需要进行 TCP 的三次握手,再加上网络延迟,造成的开销是不可忽视的),为了提升系统访问数据库的性能,可以事先创建若干连接置于连接池中,需要时直接从连接池获取,使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销,这是典型的用空间换取时间的策略(浪费了空间存储连接,但节省了创建和释放连接的时间)。池化技术在 Java 开发中是很常见的,在使用线程时创建线程池的道理与此相同。基于 Java 的开源数据库连接池主要有: C3P0、Proxool、DBCP、BoneCP、Druid等。

【补充】在计算机系统中时间和空间是不可调和的矛盾,理解这一点对设计满足性能要求的算法是至关重要的。大型网站性能优化的一个关键就是使用缓存,而缓存跟上面讲的连接池道理非常类似,也是使用空间换时间的策略。可以将热点数据置于缓存中,当用户查询这些数据时可以直接从缓存中得到,这无论如何也快过去数据库中查询。当然,缓存的置换策略等也会对系统性能产生重要影响,对于这个问题的讨论已经超出了这里要阐述的范围。

3. 什么是 DAO 模式?

答:DAO(DataAccess Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露数据库实现细节的前提下提供了各种数据操作。为了建立一个健壮的 Java EE 应用,应该将所有对数据源的访问操作进行抽象化后封装在一个公共 API 中。

用程序设计语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口,在逻辑上该类对应一个特定的数据存储。DAO 模式实际上包含了两个模式,一是 Data Accessor(数据访问器),二是 Data Object(数据对象),前者要解决如何访问数据的问题,而后者要解决的是如何用对象封装数据。

4. 什么是ORM?

答:对象关系映射(Object-Relational Mapping,简称 ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,ORM 是通过使用描述对象和数据库之间映射的元数据(可以用 XML 或者是注解),将 Java 程序中的对象自动持久化到关系数据库中或者将关系数据库表中的行转换成 Java 对象,其本质上就是将数据从一种形式转换到另外一种形式。

5. JDBC 中如何进行事务处理?

答:Connection 提供了事务处理的方法,通过调用setAutoCommit(false)可以设置手动提交事务;当事务完成后用 commit()显式提交事务;如果在事务处理过程中发生异常则通过 rollback() 进行事务回滚。除此之外,较新的 JDBC 标准还引入了Savepoint(保存点)的概念,允许事务回滚到指定的保存点。

6. 事务的 ACID 是指什么?

答:

1)原子性(Atomic):事务中各项操作,要么全做要么全不做,任何一项操作的失败都会导致整个事务的失败;

2)一致性(Consistent):事务结束后系统状态是一致的;

3)隔离性(Isolated):并发执行的事务彼此无法看到对方的中间状态;

4)持久性(Durable):事务完成后所做的改动都会被持久化,即使发生灾难性的失败。通过日志和同步备份可以在故障发生后重建数据。

【补充】关于事务,在面试中被问到的概率是很高的,可以问的问题也是很多的。首先需要知道的是,只有存在并发数据访问时才需要事务。

7. 使用 JDBC 操作数据库时,如何提升读取数据的性能?如何提升更新数据的性能?

答:要提升读取数据的性能,可以指定通过结果集(ResultSet)对象指定每次抓取数据的大小(fetch size);要提升更新数据的性能可以使用PreparedStatement语句构建批处理(batch)。

8. 存储过程和函数的区别

答:

从参数的返回情况来看:

如果返回多个参数值最好使用存储过程,如果只有一个返回值的话可以使用函数。

从调用情况来看:

如果在 SQL 语句(DML 或 SELECT)中调用的话一定是存储函数或存储的封装函数不可以是存储过程,但调用存储函数的时候还有好多限制以及函数的纯度等级的问题,如果是在过程化语句中调用的话,就要看你要实现什么样的功能。函数一般情况下是用来计算并返回一个计算结果而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些 DDL 语句等等),所以虽然他们的语法上很相似但用户在使用他们的时候所需要完成的功能大部分情况下是不同的。

9. 你认为在表上建立索引可以提高数据库系统的效率吗,为什么?

答:不一定

建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。对于一个经常需要更新和插入的表格,就没有必要为一个很少使用的 where 子句单独建立索引了,对于比较小的表,排序的开销不会很大,也没有必要建立另外的索引。

10. 什么是数据库的参照完整性?

答:数据库的参照完整性是指表与表之间的一种对应关系,通常情况下可以通过设置两表之间的主键、外键关系,或者编写两表的触发器来实现。 有对应参照完整性的两张表格,在对他们进行数据插入、更新、删除的过程中,系统都会将被修改表格与另一张对应表格进行对照,从而阻止一些不正确的数据的操作。

11. 如何优化数据库,如何提高数据库的性能?

答:

1)硬件调整性能 最有可能影响性能的是磁盘和网络吞吐量,解决办法扩大虚拟内存,并保证有足够可以扩充的空间;把数据库服务器上的不必要服务关闭掉;把数据库服务器和主域服务器分开;把 SQL 数据库服务器的吞吐量调为最大;在具有一个以上处理器的机器上运行 SQL 。

2)调整数据库

若对该表的查询频率比较高,则建立索引;建立索引时,想尽对该表的所有查询搜索操作, 按照 where 选择条件建立索引,尽量为整型键建立为有且只有一个簇集索引,数据在物理上按顺序在数据页上,缩短查找范围,为在查询经常使用的全部列建立非簇集索引,能最大地覆盖查询;但是索引不可太多,执行 UPDATE DELETE INSERT 语句需要用于维护这些索引的开销量急剧增加;避免在索引中有太多的索引键;避免使用大型数据类型的列为索引;保证每个索引键值有少数行。

3)使用存储过程

应用程序的实现过程中,能够采用存储过程实现的对数据库的操作尽量通过存储过程来实现,因为存储过程是存放在数据库服务器上的一次性被设计、编码、测试,并被再次使用,需要执行该任务的应用可以简单地执行存储过程,并且只返回结果集或者数值,这样不仅可以使程序模块化,同时提高响应速度,减少网络流量,并且通过输入参数接受输入,使得在应用中完成逻辑的一致性实现。

4)应用程序结构和算法

建立查询条件索引仅仅是提高速度的前提条件,响应速度的提高还依赖于对索引的使用。因为人们在

使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,特别是对数据量不是特别大的数据库操作时,是否建立索引和使用索引的好坏对程序的响应速度并不大,因此程序员在书写程序时就忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在数据量特别大时或者大型的或是复杂的数据库环境中(如联机事务处理 OLTP 或决策支持系统 DSS )中表现得尤为明显。在工作实践中发现,不良的 SQL 往往来自于不恰当的索引设计、不充份的连接条件和不可优化的 where 子句。在对它们进行适当的优化后,其运行速度有了明显地提高!

上一篇: Java 多线程 下一篇: Servlet 与 JSP