2018武大校赛.D. Who killed Cock Robin(树形dfs)

本文介绍了一道算法题目,需要计算从给定的鸟群关系树中选择连通子图的不同方式的数量。输入包括鸟的数量及它们之间的连接关系。

链接:https://www.nowcoder.com/acm/contest/104/C
来源:牛客网

题目描述

由于系统限制,C题无法在此评测,此题为现场赛的D题

Who killed Cock Robin?

I, said the Sparrow, With my bow and arrow,I killed Cock Robin.

Who saw him die?

I, said the Fly.With my little eye,I saw him die.

Who caught his blood?

I, said the Fish,With my little dish,I caught his blood.

Who'll make his shroud?

I, said the Beetle,With my thread and needle,I'll make the shroud.    

.........

All the birds of the air

Fell a-sighing and a-sobbing.

When they heard the bell toll.

For poor Cock Robin.

March 26, 2018


Sparrows are a kind of gregarious animals,sometimes the relationship between them can be represented by a tree.

The Sparrow is for trial, at next bird assizes,we should select a connected subgraph from the whole tree of sparrows as trial objects.

Because the relationship between sparrows is too complex, so we want to leave this problem to you. And your task is to calculate how many different ways can we select a connected subgraph from the whole tree.



输入描述:


 

The first line has a number n to indicate the number of sparrows.

The next n-1 row has two numbers x and y per row, which means there is an undirected edge between x and y.

输出描述:


 

The output is only one integer, the answer module 10000007 (107+7) in a line

<think>我们先分析用户的问题:用户遇到了一个Java SQL异常:`java.sql.SQLException: killed by kill statement : KILL QUERY 681720;`,并希望知道原因和解决方案。 根据引用内容: - 引用[1]提到,有一个`awake`方法,可以向线程传递`THD::KILL_QUERY`或`THD::KILL_CONNECTION`信号,从而杀死查询或关闭连接。 - 引用[2]是关于ORA-01722(无效数字)的错误,与用户的问题无关。 - 引用[3]中提到在Oracle中KILL了一个Session后,连接池可能没有及时清除失效连接,导致后续使用该连接时报错(connection holder is null),同时提到ExceptionSorter没有抛弃报错的连接。 - 引用[4]则直接提到了异常`java.sql.SQLException: ORA-00028: your session has been killed`,这与用户的问题类似,但用户遇到的异常信息是“killed by kill statement”。 用户遇到的异常信息是“killed by kill statement”,并且指定了KILL QUERY和一个数字(681720)。这个数字可能是查询的ID或会话ID。 结合引用[1]和[4],我们可以推断: - 在数据库中,某个查询(ID为681720)被显式地使用KILL QUERY命令终止了。 - 当Java应用程序试图使用这个已经被终止的查询或连接时,就会抛出该异常。 可能的原因: 1. 数据库管理员或某个监控系统主动杀死了该查询(可能是因为查询执行时间过长,或者占用了过多资源)。 2. 应用程序使用连接池,从连接池中获取的连接对应的数据库会话已经被杀死,但连接池没有及时检测到并移除该连接。 解决方案应考虑: - 如何避免查询被杀死?需要检查查询为什么会被杀死(例如,查询是否执行时间太长?是否资源消耗过大?) - 如果查询被杀死是不可避免的,如何让应用程序能够优雅地处理这种情况?例如,连接池应该能够检测到连接失效并移除,然后重试或者获取新的连接。 引用[3]中提到的问题与连接池处理被杀死会话的连接有关,因此我们可以借鉴: - 检查连接池配置,确保能够及时检测并移除失效连接。 具体步骤: 1. **检查数据库中的查询被杀死的原因**: - 查看数据库日志,确定是谁执行了KILL QUERY以及原因。 - 检查被杀死查询的SQL语句,优化该查询以避免长时间运行。 2. **应用程序端处理**: - 使用连接池时,配置合适的验证查询(validationQuery)来检测连接是否有效。 - 配置连接池的测试参数,例如: - `testOnBorrow`:在从连接池获取连接时进行检测,如果连接无效则移除并重新获取。 - `testWhileIdle`:在空闲时检测连接的有效性。 - `timeBetweenEvictionRunsMillis`:设置连接池检测线程的运行间隔,确保及时检测失效连接。 - 配置合理的超时参数,如查询超时(query timeout)和连接超时(connection timeout)。 3. **异常处理**: - 在代码中捕获该异常,然后尝试重试操作(重新获取连接并执行)。 - 记录异常日志,包括被杀死查询的ID,以便后续分析。 4. **检查数据库连接驱动版本**: - 如引用[4]中提到,尝试更换驱动版本(ojdbc6的版本),因为某些驱动版本可能存在处理被杀死会话的问题。 5. **检查数据库端设置**: - 确保数据库的会话超时设置合理,避免不必要的主动杀死查询。 针对用户的问题,解决方案总结如下: **原因**: - 在数据库端,查询(ID为681720)被显式地使用`KILL QUERY`命令终止。这可能是由数据库管理员、监控工具或数据库自身的资源管理策略(如资源组)触发的。 **解决方案**: 1. **优化查询**:检查被终止的查询,优化其性能,避免长时间运行,从而减少被终止的可能性。 2. **连接池配置**: - 确保连接池能够及时检测并移除失效连接。例如,对于Druid连接池,配置如下: ```java // 设置验证查询(Oracle可以使用SELECT 1 FROM DUAL) validationQuery: SELECT 1 FROM DUAL testOnBorrow: true testWhileIdle: true timeBetweenEvictionRunsMillis: 60000 // 根据实际情况调整,不宜过短 ``` - 配置合适的`exceptionSorter`(Druid默认支持Oracle,所以通常不需要额外配置,但可以检查是否生效)。 3. **异常重试机制**:在代码中捕获该异常,并进行重试(注意重试次数和重试间隔,避免雪崩)。 4. **检查驱动版本**:确保使用的Oracle JDBC驱动版本是最新的或者已知稳定的版本,避免驱动问题。 5. **数据库监控**:检查数据库的监控设置,避免过于激进的查询终止策略。 如果问题仍然存在,可能需要进一步分析数据库的KILL操作来源和应用程序的连接池行为。 §§相关问题§§ 1. 如何配置Druid连接池以自动移除被KILL的数据库连接? 2. 在Oracle数据库中,如何查找执行时间过长的查询并优化? 3. 如何在Java应用程序中实现数据库操作的重试机制? 4. Oracle数据库中KILL QUERY和KILL CONNECTION的区别是什么? </think>### Java中出现 `java.sql.SQLException: killed by kill statement : KILL QUERY 681720;` 异常的原因与解决方案 #### **原因分析** 1. **查询被主动终止** 数据库会话(Session ID: 681720)中的查询被显式终止(如通过 `KILL QUERY` 命令)。常见场景: - **人工干预**:DBA 手动终止长时间运行的查询[^1]。 - **监控系统触发**:数据库监控工具自动终止超时或资源占用过高的查询(如 Oracle 的 Resource Manager)。 - **连接池管理**:连接池主动清理空闲会话时误杀活跃查询(需检查连接池配置)[^3]。 2. **连接池未及时清理失效连接** - 连接池(如 Druid)未正确检测到已被终止的会话,导致应用程序继续使用无效连接[^3]。 - 典型表现:连接池的 `ExceptionSorter` 未生效或配置不当。 3. **驱动兼容性问题** 使用的 JDBC 驱动版本可能存在缺陷(尤其是旧版 Oracle JDBC 驱动),无法正确处理 `KILL` 信号[^4]。 --- #### **解决方案** 1. **优化查询性能(根本措施)** - 检查被终止的查询(ID: 681720)是否存在性能问题: - 使用 `EXPLAIN PLAN` 分析 SQL 执行效率。 - 优化慢查询(如添加索引、避免全表扫描)。 - 设置合理的查询超时时间(如 JDBC 的 `setQueryTimeout`)。 2. **配置连接池检测机制** 以 Druid 为例: ```java // 关键配置 dataSource.setValidationQuery("SELECT 1 FROM DUAL"); // Oracle 验证语句 dataSource.setTestWhileIdle(true); dataSource.setTimeBetweenEvictionRunsMillis(30000); // 检测间隔(毫秒) dataSource.setMinEvictableIdleTimeMillis(600000); // 最小空闲时间 ``` - 确保 `validationQuery` 生效,及时移除失效连接[^3]。 3. **升级 JDBC 驱动** 更换新版 Oracle JDBC 驱动(推荐 ≥ 12.2.0.1): ```xml <!-- Maven 示例 --> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>21.5.0.0</version> </dependency> ``` 4. **添加异常重试逻辑** 在代码层捕获异常并重试: ```java try { // 执行数据库操作 } catch (SQLException e) { if (e.getMessage().contains("killed by kill statement")) { // 1. 重置数据库连接 // 2. 重试操作(最多3次) } } ``` 5. **检查数据库端配置** - 确认 `KILL` 操作来源:审查数据库日志,定位触发 `KILL QUERY` 的源头。 - 调整会话超时参数(如 Oracle 的 `IDLE_TIME`)。 --- #### **预防措施** - **监控告警**:部署数据库监控(如 Prometheus + Grafana),对长查询实时告警。 - **压力测试**:模拟高并发场景,验证连接池配置的健壮性。 - **会话管理**:避免长时间持有连接,业务完成后立即释放资源。 > 通过优化查询+连接池配置+驱动升级,可解决 90% 的此类异常。若问题持续,需结合数据库日志深入分析 `KILL` 操作的触发策略[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值