递归实例化导致的栈溢出问题【简直蠢得出奇】

2023-12-02 21:04

本文主要是介绍递归实例化导致的栈溢出问题【简直蠢得出奇】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述

今天在练习数据库增删改查,体验三层架构思想时,随便写了点DAO层代码,但服务器运行时竟然爆出了栈溢出的问题,说实话,空指针问题我还能放着耐心去代码里找找问题,但这个栈溢出,我之前就没有一次解决过,要么改算法,要么直接重写出问题关联的那几段。至于网上说的改JVM的栈内存,这个我还不会。

先说说我遇到的问题吧,请看截图:
在这里插入图片描述

类型 异常报告消息 Servlet执行抛出一个异常描述 服务器遇到一个意外的情况,阻止它完成请求。例外情况javax.servlet.ServletException: Servlet执行抛出一个异常org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
根本原因。java.lang.StackOverflowErrorjava.security.AccessController.doPrivileged(Native Method)org.apache.commons.logging.LogFactory.getContextClassLoaderInternal(LogFactory.java:808)org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:419)org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)org.springframework.jdbc.support.JdbcAccessor.<init>(JdbcAccessor.java:43)org.springframework.jdbc.core.JdbcTemplate.<init>(JdbcTemplate.java:164)com.crud.crud_demo.dao.impl.EmployeeImpl.<init>(EmployeeImpl.java:16)com.crud.crud_demo.dao.impl.EmployeeImpl.<init>(EmployeeImpl.java:17)

我调用DAO层的EmployeeImpl来完成SQL语句来接收数据库数据,并以List集合返回给上层,最后返回到JSP页面层来显示。这里是我的EmployeeImpl代码:

package com.crud.crud_demo.dao.impl;import com.crud.crud_demo.dao.EmployeeDao;
import com.crud.crud_demo.domain.Employee;
import com.crud.crud_demo.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;import java.util.List;/*** 使用SQL语句的地方*/
public class EmployeeImpl implements EmployeeDao {//创建JdbcTemplate 对象并用静态工具类获取数据源private JdbcTemplate jdbcTemplate=new JdbcTemplate(JDBCUtils.getDataSource());private EmployeeDao employeeDao=new EmployeeImpl();@Overridepublic List<Employee> findAll() {String sql="select * from employee";List<Employee> list= jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class));return list;}
}

发生原因

首先我们可以再看看看第一张服务器报错的界面
在这里插入图片描述
后面的报错地方全是一样的,说明这不是代码量较多导致变量过多的问题,而是某处存在创建变量的递归或者循环一直在运行。

相信聪明的小伙伴已经找到问题了,没错就是这一句:

private EmployeeDao employeeDao=new EmployeeImpl();

我也不知道这句我是什么时候写上去的,就很神奇。

EmployeeImpl类的实例化过程中,我通过private EmployeeDao employeeDao=new EmployeeImpl();

这一行代码,又创建了一个新的EmployeeImpl实例

而这个实例中的private EmployeeDao employeeDao=new EmployeeImpl();又会创建一个新的EmployeeImpl实例。

就这样无限递归下去,因为每次方法调用都会在调用栈上分配一定的空间,而无限递归会导致调用栈不断增长,直到耗尽可用的栈空间。

活脱脱的一个俄罗斯套娃
在这里插入图片描述

能写出这种💩代码试问这个世界上除了我还有谁能做到💩💩💩💩💩💩💩💩💩💩💩💩💩💩
在这里插入图片描述
不过借着这个机会了解了一下递归实例化的模式。也算是有点收获。

解决办法

删掉那个套娃语句就行

顺便了解一下什么是递归实例化

递归实例化是一种编程模式,它在某些情况下可能有用,但也存在一些潜在的缺点

优点:

简洁性:通过递归实例化,您可以使用较少的代码实现复杂的功能。相对于使用循环来处理嵌套结构,递归实例化的代码通常更简洁、易于理解和维护。

可读性:递归实例化可以使代码更加可读和自解释。它可以更直观地表示问题的解决方案,特别是对于涉及嵌套结构的问题。通过递归实例化,您可以将问题分解为更小的子问题,每个子问题都可以用相同的方式解决,从而使代码更具可读性。

灵活性:递归实例化可以应对未知深度的数据结构,因为它不需要提前知道要处理的嵌套层级。这使得递归实例化在处理树形结构、图形结构或其他具有递归性质的问题上非常有用。

缺点:

空间复杂度:递归实例化在函数调用过程中需要使用额外的内存来保存中间结果和函数调用栈。如果递归深度很大,这可能导致栈溢出或消耗大量内存。因此,在使用递归实例化时需要注意控制递归深度,以避免空间复杂度过高的问题。

时间复杂度:由于递归实例化需要进行多次函数调用和返回操作,因此可能会导致较高的时间复杂度。特别是在处理大量数据时,递归实例化可能会导致性能下降。因此,在使用递归实例化时需要注意优化算法以降低时间复杂度。

拜了,周末快乐

在这里插入图片描述

这篇关于递归实例化导致的栈溢出问题【简直蠢得出奇】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/446822

相关文章

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

element-ui下拉输入框+resetFields无法回显的问题解决

《element-ui下拉输入框+resetFields无法回显的问题解决》本文主要介绍了在使用ElementUI的下拉输入框时,点击重置按钮后输入框无法回显数据的问题,具有一定的参考价值,感兴趣的... 目录描述原因问题重现解决方案方法一方法二总结描述第一次进入页面,不做任何操作,点击重置按钮,再进行下

解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题

《解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题》本文主要讲述了在使用MyBatis和MyBatis-Plus时遇到的绑定异常... 目录myBATis-plus-boot-starpythonter与mybatis-spring-b

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

mysql主从及遇到的问题解决

《mysql主从及遇到的问题解决》本文详细介绍了如何使用Docker配置MySQL主从复制,首先创建了两个文件夹并分别配置了`my.cnf`文件,通过执行脚本启动容器并配置好主从关系,文中还提到了一些... 目录mysql主从及遇到问题解决遇到的问题说明总结mysql主从及遇到问题解决1.基于mysql

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

如何安装HWE内核? Ubuntu安装hwe内核解决硬件太新的问题

《如何安装HWE内核?Ubuntu安装hwe内核解决硬件太新的问题》今天的主角就是hwe内核(hardwareenablementkernel),一般安装的Ubuntu都是初始内核,不能很好地支... 对于追求系统稳定性,又想充分利用最新硬件特性的 Ubuntu 用户来说,HWEXBQgUbdlna(Har

MAVEN3.9.x中301问题及解决方法

《MAVEN3.9.x中301问题及解决方法》本文主要介绍了使用MAVEN3.9.x中301问题及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录01、背景02、现象03、分析原因04、解决方案及验证05、结语本文主要是针对“构建加速”需求交

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6