后台JAVA面试-数据库部分(三)


许多面试过开发岗位的小伙伴都知道,数据库在后台开发面试中是必问的问题,树懒君特意收集了最新的后台开发-数据库部分面试题目。

一、Mysql和PostGreSQL有什么区别?

回答思路:

面试官询问这个问题,原因可能是你在自己的简历中有描述使用到两种不同的数据,主要考察两个方面。

一个是考察你在工作中是否善于思考,一般数据库的选型都是公司的架构师或者组长选择,你可能只是一名组员,只需要负责使用即可,但是,如果你能够主动去思考为什么会选择使用这个数据库而不是使用其他数据库,了解两者的一些差别,这个会很给面试官添加印象分,证明你在平常的工作中是善于去思考的

第二个考察的方面,是看你是否能够结合项目或者公司现在有的业务去讲解使用当前数据库的一些利弊,这同样也是一个加分项,毕竟技术的选型最后还是要考虑业务的支撑,因此,这个问题主要从这两方面回答会有很不错的效果。

第一方面:
    1、Mysql中text类型有不同的限制(既:small text middle text…),但是Pg没有这种限制。
    2、MySQL 里需要 utf8mb4 才能显示 emoji 的坑, Pg 就没这个坑。
    3、MySQL 不支持 OVER 子句, 而 Pg 支持. OVER 子句能简单的解决 “每组取 top 5” 的这类问题。
    4、pg支持更多的数据类型如:jsonb array等,对地理信息处理扩展更好的支持,有更多的数据源。
    5、在高并发读写,负载逼近极限下,PG的性能指标仍可以维持双曲线甚至对数曲线,到顶峰之后不再下降,而 MySQL 明显出现一个波峰后下滑
第二方面:
  可以结合项目的一些业务场景来回答体现使用这种数据库的优势。如使用PostgreSQL,回答如下。
  因为这个项目的技术选型是由我们公司架构师进行选择的,但是,我也通过项目和公司的业务了解到一些选择PG数据库的好处,我们的公司主要项目是公安的相关系统,系统中涉及到很多地理位置信息数据的处理,PG数据库对地理信息的存储和拓展都有很好的支持,这也是我们项目中选择PG数据库的一个原因等等。

二、事务的隔离级别?

1.未提交读

未提交读(read uncommitted)是最低的隔离界别,其含义是允许一个事务读取到另一个事务未提交的数据。未提交读的有点在于并发能力高,适合对数据一致性没有要求而追求高并发的场景,但他最大的坏处就是会出现脏读。

数据库面试题目,JAVA面试, MySQL和PostGreSQL的区别, 事务的隔离级别, 事务并发

在T3时刻,因为采用未提交读,所以事务2可以读取到事务1俄日提交的库存数据为1,当事务2扣减库存后并提交了事务则库存为0,然后事务1在T5时刻回滚事务,因为第一类丢失更新已被客服,所以库存不会回滚到2,最后结果变成了0,这样就出现了错误。

2.读写提交

读写提交(read committed)隔离级别,是指一个事务只能读取到另外一个事务已经提交的数据,不能读取到未提交的数据。

(图片2)

在T3时刻,由于采用了读写提交的隔离级别,因此事务2不能读取到事务1中未提交的库存1,然后事务2提交事务,则库存在T4时刻就变为了1。T5时刻,事务1回滚,因为第一类丢失更新已经克服,所以结果库存为1,这是一个正确的结果。但是读写提交也会产生下面的问题。

数据库面试题目,JAVA面试, MySQL和PostGreSQL的区别, 事务的隔离级别, 事务并发

在T3时刻事务2读取库存的时候,由于事务1没有提交,所以事务2读到的库存为1,此时事务2认为当前可扣减库存;在T4时刻,事务1已经提交事务,所以在T5时刻,它扣减库存的时候发现库存为0,扣减失败。此时库存对于事务2来说是一个可变化的值,这样的现象称为不可重复读,这就是读写提交的一个不足,为了克服这个不足,数据库隔离级别还提出了可重复读的隔离级别,他能够消除不可重读的问题。

3.可重复读

可重复读的目标是克服读写提交中出现的不可重复读的现象,因为在读写提交的时候,可能会出现一些值的变化,影响当前事务的执行,如上述的库存是个变化的值,这个时候数据库提出了可重复读的隔离级别。

数据库面试题目,JAVA面试, MySQL和PostGreSQL的区别, 事务的隔离级别, 事务并发

事务2在T3时刻尝试读取库存,但是此时这个库存已经被事务1事先读取,所以此时数据库就阻塞事务2的读取,直至事务1提交,事务2才能读取库存的值。此时已经是T5时刻,而读取到的值为0,这是就已经无法扣减了,显然在读写提交中出现的不可重复读的场景被消除了。但这样也会引发新的问题,就是幻读。假设现在商品交易正在进行中,而后台也有人也在进行查询分析和打印的业务

数据库面试题目,JAVA面试, MySQL和PostGreSQL的区别, 事务的隔离级别, 事务并发

这便是幻读现象。首先这里的笔数不是数据库存储的值,而是一个统计值,商品库存则是数据库存储的值。幻读不是针对一条数据库记录而言,而是多条记录,例如,这51笔交易笔数就是多条数据库记录统计出来的。而可重复读是针对数据库的单一条记录,例如,商品的库存是以数据库里面的一条记录存储的,它可以产生可重复读,而不能产生幻读。

4.串行化

串行化是数据库最高的隔离级别,他会要求所有的sql按照顺序执行,这样就可以克服上述隔离级别出现的各种问题,所以它能够完全保证数据的一致性。

三、并发事务带来的问题

  • 更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题 --最后的更新覆盖了由其他事务所做的更新。例如,两个编辑人员制作了同一 文档的电子副本。每个编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。 最后保存其更改副本的编辑人员覆盖另一个编辑人员所做的更改。如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同 一文件,则可避免此问题。
  • 脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前, 这条记录的数据就处于不一致状态; 这时, 另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些 “脏” 数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做” 脏读”。
  • 不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做 “不可重复读” 。
  • 幻读 (Phantom Reads): 一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为 “幻读” 。