高频javasql面试题及答案_第1页
高频javasql面试题及答案_第2页
高频javasql面试题及答案_第3页
高频javasql面试题及答案_第4页
高频javasql面试题及答案_第5页
已阅读5页,还剩10页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高频javasql面试题及答案JDBC连接数据库的标准步骤包括哪些?需要注意哪些细节?JDBC连接数据库的核心步骤可分为六步:首先加载数据库驱动类,通常通过`Class.forName("com.mysql.cj.jdbc.Driver")`实现,新版MySQL驱动已支持自动加载,但显式加载更稳妥;第二步通过`DriverManager.getConnection(url,username,password)`获取数据库连接,其中URL需包含数据库地址、端口、数据库名及连接参数(如`useSSL=false`、`serverTimezone=UTC`);第三步创建执行SQL的对象,可选择`Statement`(普通语句)、`PreparedStatement`(预编译语句)或`CallableStatement`(存储过程);第四步执行SQL,查询使用`executeQuery()`返回`ResultSet`,更新使用`executeUpdate()`返回影响行数;第五步处理结果集,通过`ResultSet`的`next()`遍历数据,使用`getString()`、`getInt()`等方法获取字段值;最后依次关闭`ResultSet`、`Statement`和`Connection`,释放资源。需要注意的细节包括:连接参数需明确字符集(如`characterEncoding=utf8mb4`)以支持emoji;`PreparedStatement`应优先于`Statement`使用,避免SQL注入且提升重复执行性能;资源关闭需在`finally`块或使用`try-with-resources`(JDK7+)确保关闭,防止连接泄漏;处理大字段(如BLOB、CLOB)时,需使用`setBinaryStream()`或`setCharacterStream()`避免内存溢出;事务控制中,默认自动提交需通过`connection.setAutoCommit(false)`开启手动提交,`commit()`或`rollback()`需根据业务逻辑调用。PreparedStatement相比Statement的优势体现在哪些方面?实际开发中如何避免其潜在问题?PreparedStatement的核心优势有三点:其一,预编译机制,SQL语句在数据库端预先编译,后续执行时只需传递参数,减少了语法解析开销,尤其适合重复执行相同结构的SQL(如批量插入);其二,参数化查询,通过`?`占位符传递参数,数据库将用户输入视为数据而非SQL代码,有效防止SQL注入攻击(如用户输入`'OR'1'='1`不会导致条件恒真);其三,支持批量操作,通过`addBatch()`和`executeBatch()`实现批量更新,减少网络IO次数,提升性能。但使用PreparedStatement需注意潜在问题:若SQL语句中占位符过多(如超过数据库支持的最大参数数),可能导致预编译失败,需拆分操作;对于动态SQL(如条件不确定的查询),需谨慎拼接字段或表名(这些部分无法使用占位符),此时仍需校验拼接内容防止注入;长时间不关闭的PreparedStatement可能占用数据库端的预编译缓存,需及时释放或设置合理的缓存大小(如MySQL的`max_prepared_stmt_count`);处理时间类型时,需使用`setDate()`、`setTimestamp()`等对应方法,避免类型不匹配导致的异常。数据库事务的四大特性(ACID)具体指什么?MySQL中InnoDB如何实现这些特性?ACID是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)的缩写。原子性要求事务中的操作要么全部完成,要么全部回滚;一致性确保事务执行前后数据库状态符合业务规则;隔离性指多个事务并发执行时互不干扰;持久性保证事务提交后数据永久保存,即使系统崩溃也不丢失。InnoDB通过以下机制实现ACID:原子性依赖undo日志(回滚日志),事务执行时记录每条操作的反向操作(如插入时记录删除),事务回滚时通过undo日志撤销未提交的修改;一致性由业务逻辑和数据库约束(如唯一索引、外键)共同保证,同时依赖原子性和持久性的支持;隔离性通过锁机制(行锁、间隙锁)和MVCC(多版本并发控制)实现,不同隔离级别(读未提交、读已提交、可重复读、串行化)对应不同的锁策略和可见性规则;持久性依赖redo日志(重做日志),事务提交时先将redo日志写入磁盘(Write-AheadLogging),即使数据页未及时刷盘,崩溃恢复时可通过redo日志重新执行已提交事务的操作。MySQL中常见的索引类型有哪些?哪些场景下不适合创建索引?MySQL支持的索引类型包括:B+树索引(默认,适用于范围查询和排序)、哈希索引(Memory引擎默认,等值查询快但不支持范围查询)、全文索引(MyISAM和InnoDB支持,用于文本内容的模糊搜索)、空间索引(用于地理空间数据)。其中B+树索引又可分为主键索引(聚簇索引,叶子节点存储整行数据)、二级索引(非聚簇索引,叶子节点存储主键值,需回表查询)、唯一索引(限制字段唯一,可含NULL)、复合索引(多字段组合,遵循最左前缀匹配原则)。不适合创建索引的场景包括:字段更新频繁(如计数器),索引维护会增加写操作开销;字段区分度低(如性别字段只有“男/女”),索引无法有效过滤数据;查询中很少使用的字段(如历史归档表的冗余字段),索引徒增存储;表数据量小(如<1000行),全表扫描比索引查找更快;覆盖索引已满足查询需求时,无需额外创建索引(避免重复索引);模糊查询以通配符开头(如`LIKE'%keyword'`),无法利用B+树索引的有序性。如何分析MySQL慢查询?常见的优化手段有哪些?分析慢查询的步骤如下:首先开启慢查询日志(`slow_query_log=ON`,设置`long_query_time`阈值,如1秒),记录执行时间超过阈值的SQL;其次使用`EXPLAIN`命令分析慢查询的执行计划,重点关注`type`(访问类型,理想值为`ref`或`eq_ref`,最差为`ALL`全表扫描)、`key`(实际使用的索引)、`rows`(扫描的行数)、`Extra`(额外信息,如`Usingfilesort`表示需要文件排序,`Usingtemporary`表示使用临时表);最后结合业务场景定位问题(如索引缺失、SQL写法低效、锁竞争等)。常见优化手段包括:为WHERE、JOIN、ORDERBY、GROUPBY中的字段添加复合索引(注意最左前缀);避免SELECT,使用覆盖索引(索引包含所有查询字段)减少回表;将OR条件改为UNION(若字段有索引),或为每个条件字段单独创建索引;优化子查询为JOIN(避免嵌套查询的循环执行);拆分复杂SQL为多个简单查询(减少锁持有时间);调整ORDERBY和GROUPBY的字段顺序,使其与索引顺序一致避免文件排序;对于频繁更新的表,定期执行`OPTIMIZETABLE`重建索引(碎片整理);对大表进行分库分表(水平或垂直拆分),减少单表数据量。JDBC中如何处理事务的隔离级别?Spring的@Transactional注解如何覆盖默认隔离级别?JDBC通过`Connection`接口的`setTransactionIsolation(intlevel)`方法设置隔离级别,参数对应`Connection`类的常量:`TRANSACTION_READ_UNCOMMITTED`(读未提交)、`TRANSACTION_READ_COMMITTED`(读已提交,大多数数据库默认)、`TRANSACTION_REPEATABLE_READ`(可重复读,MySQLInnoDB默认)、`TRANSACTION_SERIALIZABLE`(串行化)、`TRANSACTION_NONE`(不支持事务,仅部分数据库)。设置需在事务开始前(`setAutoCommit(false)`之后),否则可能抛出异常。Spring的@Transactional注解通过`isolation`属性覆盖默认隔离级别,例如`@Transactional(isolation=Isolation.REPEATABLE_READ)`。Spring事务管理器(如`DataSourceTransactionManager`)会在获取连接后,根据该属性调用`setTransactionIsolation()`。需注意:不同数据库支持的隔离级别可能不同(如Oracle不支持可重复读),设置时需考虑兼容性;隔离级别越高,并发性能越低(如串行化会导致锁升级),需根据业务需求权衡(如金融交易需高隔离,日志记录可低隔离)。MyBatis中{}和${}的区别是什么?如何避免${}带来的安全风险?MyBatis中`{}`表示参数占位符,会将参数转换为JDBC的`PreparedStatement`参数,自动添加引号(如字符串)并防止SQL注入;`${}`表示字符串拼接,直接将参数值插入SQL语句,适用于动态表名、列名或排序字段(这些无法使用占位符)。例如,`SELECTFROMuserWHEREname={name}`会编译为`SELECTFROMuserWHEREname=?`,而`ORDERBY${sortField}`会直接替换为`ORDERBYage`(若`sortField`值为`age`)。使用`${}`时需注意SQL注入风险(如`sortField`值为`age;DROPTABLEuser;--`会导致恶意操作)。避免风险的方法包括:严格校验参数值(如仅允许字母数字的字段名);使用白名单限制可替换的参数(如定义允许的排序字段列表);在MyBatis配置中开启`safeParam`(需自定义插件)或通过`TypeHandler`对参数进行转义(如添加反引号包裹字段名);尽量减少`${}`的使用,优先通过动态SQL标签(如`<if>`、`<choose>`)拼接合法内容。Hibernate的一级缓存和二级缓存有何区别?如何配置二级缓存?Hibernate一级缓存是会话级缓存(`Session`级别),默认开启,生命周期与`Session`绑定,存储当前会话中加载或修改的实体对象。一级缓存通过`get()`、`load()`方法查询时,若缓存中存在则直接返回,减少数据库查询;提交事务时,通过脏检查(比较缓存与当前对象状态)自动提供更新语句。二级缓存是进程级或集群级缓存(`SessionFactory`级别),需手动配置,用于缓存跨会话的常用数据(如字典表、高频读低修改的实体)。二级缓存支持多种实现(如Ehcache、Caffeine、Infinispan),存储的是可序列化的对象或数据副本,需考虑缓存一致性(如数据更新时清除或更新缓存)。配置二级缓存的步骤:在`hibernate.cfg.xml`中启用`hibernate.cache.use_second_level_cache=true`和`hibernate.cache.region.factory_class`(指定缓存工厂类,如`org.hibernate.cache.ehcache.EhcacheRegionFactory`);为需要缓存的实体类添加`@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)`注解(或在`hbm.xml`中配置`<cacheusage="read-write"/>`);配置缓存策略(如`READ_ONLY`适用于不变数据,`READ_WRITE`适用于读多写少,`NONSTRICT_READ_WRITE`适用于偶尔修改,`TRANSACTIONAL`适用于事务环境);对于关联对象,可通过`@Cache(include="all")`缓存关联集合。数据库连接池的作用是什么?HikariCP相比其他连接池(如DBCP、C3P0)有哪些优势?连接池的核心作用是管理数据库连接生命周期,避免频繁创建和销毁连接的开销(TCP三次握手、数据库认证等耗时操作)。通过复用空闲连接,降低延迟并提升并发性能;通过配置最大连接数、最小空闲连接数等参数,防止数据库连接数过载;提供连接校验(如测试连接有效性)、超时控制(如连接空闲超时回收)等功能,保障连接可靠性。HikariCP是高性能连接池,相比DBCP、C3P0的优势包括:代码轻量(核心类少,无冗余依赖),性能更优(通过优化字节码、减少锁竞争实现低延迟);默认使用`PreparedStatement`缓存(`prepStmtCacheSize`和`prepStmtCacheSqlLimit`),提升重复SQL执行效率;支持连接测试(默认使用`Connection.isValid()`,比DBCP的`SELECT1`更高效);自动适应JDBC4的`Connection.isValid()`方法,减少不必要的测试开销;配置参数更简洁(如`maximumPoolSize`默认值为`CPU核心数2+1`,更符合现代服务器架构);支持JMX监控,方便性能调优。MySQL中如何解决幻读问题?InnoDB的可重复读隔离级别是否完全避免幻读?幻读指同一事务中,两次相同查询返回不同的行数(如第一次查询有10条记录,第二次插入新记录后查询到11条)。InnoDB在可重复读隔离级别下,通过MVCC(多版本并发控制)和间隙锁(GapLock)解决幻读:MVCC通过记录的版本链(`undolog`)实现一致性读(快照读),事务内查询看到的是事务开始时的快照,避免其他事务插入的新记录;对于当前读(如`SELECT...FORUPDATE`),InnoDB会加间隙锁,锁定记录之间的间隙,防止其他事务插入新记录,从而避免幻读。InnoDB的可重复读隔离级别在大多数情况下可避免幻读,但需注意:若事务中使用`ALTERTABLE`等DDL操作,可能导致快照失效(因DDL会更新数据字典的版本);使用`READCOMMITTED`隔离级别时,MVCC的快照在每次查询时重新提供,无法避免幻读;对于非索引字段的当前读,InnoDB可能升级为表锁,导致间隙锁覆盖整个表,影响并发性能。Java中如何实现数据库的批量插入?JDBC和MyBatis分别有哪些优化方式?JDBC实现批量插入的标准方式是使用`PreparedStatement.addBatch()`和`executeBatch()`。步骤为:关闭自动提交(`connection.setAutoCommit(false)`);创建`PreparedStatement`对象(如`INSERTINTOuser(name)VALUES(?)`);循环调用`addBatch()`添加参数;调用`executeBatch()`执行批量操作;最后提交事务(`mit()`)。此方式减少了网络往返次数(多次`addBatch()`后一次提交),提升插入效率。MyBatis优化批量插入的方式有两种:其一是使用`SqlSession`的`BATCH`执行器,通过`SqlSessionFactory.openSession(ExecutorType.BATCH)`获取会话,循环调用`insert()`方法后统一提交,MyBatis会将多个`insert`语句合并为批量操作;其二是使用动态SQL的`<foreach>`标签,将多条插入语句拼接为一条(如`INSERTINTOuser(name)VALUES('a'),('b'),('c')`),需注意数据库对单条SQL长度的限制(如MySQL的`max_allowed_packet`)。此外,JDBC可通过设置`rewriteBatchedStatements=true`(MySQL连接参数)优化批量插入,将多条`INSERT`语句重写为单条`INSERT...VALUES(...),(...)`形式,进一步提升性能(需MySQL服务器版本≥5.1.17)。MyBatis结合此参数并使用`BATCH`执行器,可达到更高的插入效率。数据库死锁的常见原因是什么?Java应用中如何检测和避免死锁?死锁的常见原因是多个事务争夺相同资源的锁,且持有部分锁的同时等待其他锁。例如,事务A锁定了记录1并请求记录2的锁,事务B锁定了记录2并请求记录1的锁,双方互相等待导致死锁。InnoDB通过锁等待图(LockWaitGraph)检测死锁,当检测到循环等待时,会选择回滚代价较小的事务(如更新行数少的)以释放锁。Java应用中检测死锁的方法包括:监控数据库日志(如MySQL的`innodb_status`输出,通过`SHOWENGINEINNODBSTATUS`查看最近死锁信息);使用JMX或APM工具(如Pinpoint、SkyWalking)跟踪数据库操作的耗时和锁等待;在应用层捕获`SQLTimeoutException`或`SQLIntegrityConstraintViolationException`(部分数据库会抛出特定异常表示死锁)。避免死锁的策略有:按相同顺序访问资源(如所有事务先锁记录1再锁记录2);减少事务持锁时间(避免长事务,尽快提交或回滚);使用锁升级(如将行锁升级为表锁,若业务允许);设置锁超时(InnoDB的`innodb_lock_wait_timeout`,默认50秒,可缩短至5秒加速死锁检测);使用乐观锁(通过版本号或时间戳字段),避免显式加锁(如`UPDATEuserSETcount=count+1,version=version+1WHEREid=1ANDversion=oldVersion`)。MySQL主从复制的原理是什么?如何处理主从延迟问题?主从复制基于二进制日志(binlog),分为三步:主库将数据变更写入binlog(`BinaryLog`),通过`binlogdumpthread`发送给从库;从库的`I/Othread`接收binlog并写入中继日志(`RelayLog`);从库的`SQLthread`读取中继日志并执行其中的SQL,实现主从数据同步。主从延迟指从库数据落后于主库的时间差,常见原因包括主库写压力大(binlog提供快于从库执行)、从库硬件性能差(CPU/磁盘慢)、大事务(从库需执行长时间的SQL)、从库执行额外查询(影响`SQLthread`性能)。处理主

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论