惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
量子位
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
AWS News Blog
AWS News Blog
T
Threat Research - Cisco Blogs
博客园 - Franky
Vercel News
Vercel News
H
Help Net Security
Martin Fowler
Martin Fowler
Security Archives - TechRepublic
Security Archives - TechRepublic
L
LINUX DO - 热门话题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
Lohrmann on Cybersecurity
Cyberwarzone
Cyberwarzone
W
WeLiveSecurity
V2EX - 技术
V2EX - 技术
C
CERT Recently Published Vulnerability Notes
S
Secure Thoughts
C
Cyber Attacks, Cyber Crime and Cyber Security
B
Blog RSS Feed
H
Hacker News: Front Page
P
Proofpoint News Feed
博客园 - 聂微东
N
News and Events Feed by Topic
C
Cybersecurity and Infrastructure Security Agency CISA
D
Docker
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
S
Security @ Cisco Blogs
博客园 - 【当耐特】
F
Fortinet All Blogs
The Register - Security
The Register - Security
A
About on SuperTechFans
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
NISL@THU
NISL@THU
Attack and Defense Labs
Attack and Defense Labs
Help Net Security
Help Net Security
Cisco Talos Blog
Cisco Talos Blog
月光博客
月光博客
IT之家
IT之家
有赞技术团队
有赞技术团队
Know Your Adversary
Know Your Adversary
Hugging Face - Blog
Hugging Face - Blog

博客园 - GDOUJKZZ

.net 8程序如何在信创的arm64架构下运行【nuget包如何判断能不能在arm架构跑呢】 【AI应用】【声纹识别】一、mini io 来构建高可用的文件存储方案 【AI】第五篇 大话说神经网络第一篇 docker 目录下的overlay2层的太多,导致占用大量占用磁盘空间怎么办呢。【docker目录清理】 【AI】第四篇 什么是神经网络 【AI】第三篇 RAG是什么 【AI】前置篇 Ai Agent的全貌概览 【AI】第二篇 为什么会有神经网络 【AI】第一篇 语言模型的前世 n-gram的简单介绍 【一】AI赋能 javascript里面的var let const关键字区别和使用 学习心态 从应用开发转到大数据开发 一分钟RequireJS介绍 .NET 6 在小并发下如何生成唯一单据号 垃圾回收机制简单理解 NPOI导出大量数据的避免OOM解决方案【SXSSFWorkbook】 C# 使用NPOI处理Excel模板-【前面部分固定,中间是动态的几行,尾部是固定的部分】 高并发的场景下,如何保证生产者投递到消息中间件的消息不丢失
递归有环问题解决方案
GDOUJKZZ · 2021-11-05 · via 博客园 - GDOUJKZZ

 场景引入

       今天碰到一个问题:当用户使用某个功能的时候,系统就直接挂了,一开始还以为是啥问题,最后发现是递归有环。

      业务场景:有个功能需要获取地区树,刚刚好地区树里面由于人为修改的原因,造成了环。

       A(广东,44)-->B(韶关,4402)-->C(南雄,44) 这种就是有环,会发生堆栈溢出,如果代码不处理,就会由于堆栈溢出,整个服务器直接挂了。

      直接上代码,模拟情况:

             1、建两个类,后面要使用

 public class DictRegion
    {
        public string RegionCode { get; set; }

        public string RegionName { get; set; }

        public string ParentCode { get; set; }

        public string ParentName { get; set; }
    }


    public class TreeNode
    {
        public string RegionCode { get; set;  }
        public string RegionName { get; set; }
        public List<TreeNode> Childs { get; set; }
    }

        2、递归函数的编写

    static void GetTreeNode(List<DictRegion> regions,string parentCode,List<TreeNode> nodes)
    {
            var regionArr=regions.Where(d=>d.ParentCode == parentCode).ToList();
            foreach(var region in regionArr)
            {

                var node = new TreeNode()
                {
                    RegionCode = region.RegionCode,
                    RegionName = region.RegionName,
                    Childs = new List<TreeNode>()
                };
                GetTreeNode(regions,region.RegionCode,node.Childs);
                nodes.Add(node);
            }
        }

       3、准备数据以及调用

 var regions = new List<DictRegion>() {
                    new DictRegion(){RegionCode="ROOT",RegionName="中国",ParentCode="",ParentName=""},
                    new DictRegion() { RegionCode = "44", RegionName = "广东", ParentCode = "ROOT", ParentName = "中国" },
                    new DictRegion() { RegionCode = "43", RegionName = "湖南", ParentCode = "ROOT", ParentName = "中国" },
                    new DictRegion() { RegionCode = "45", RegionName = "广西", ParentCode = "ROOT", ParentName = "中国" },

                    new DictRegion() { RegionCode = "4401", RegionName = "广州", ParentCode = "44", ParentName = "广东" },
                    new DictRegion() { RegionCode = "4402", RegionName = "韶关", ParentCode = "44", ParentName = "广东" },
                    new DictRegion() { RegionCode = "4403", RegionName = "深圳", ParentCode = "44", ParentName = "广东" },

                    new DictRegion() { RegionCode = "4501", RegionName = "南宁", ParentCode = "45", ParentName = "广西" },
                    new DictRegion() { RegionCode = "4502", RegionName = "柳州", ParentCode = "45", ParentName = "广西" },
                    new DictRegion() { RegionCode = "4503", RegionName = "桂林", ParentCode = "45", ParentName = "广西" },

                    new DictRegion() { RegionCode = "4301", RegionName = "长沙", ParentCode = "43", ParentName = "湖南" },
                    new DictRegion() { RegionCode = "4302", RegionName = "株洲", ParentCode = "43", ParentName = "湖南" },
                    new DictRegion() { RegionCode = "4303", RegionName = "湘潭", ParentCode = "43", ParentName = "湖南" },

                    new DictRegion() { RegionCode = "440111", RegionName = "从化", ParentCode = "4401", ParentName = "广州" },
                    new DictRegion() { RegionCode = "440112", RegionName = "天河", ParentCode = "4401", ParentName = "广州" },
                    new DictRegion() { RegionCode = "440113", RegionName = "增城", ParentCode = "4401", ParentName = "广州" },

                    new DictRegion() { RegionCode = "440211", RegionName = "仁化", ParentCode = "4402", ParentName = "韶关" },
                    new DictRegion() { RegionCode = "440212", RegionName = "乐昌", ParentCode = "4402", ParentName = "韶关" },
                    new DictRegion() { RegionCode = "44", RegionName = "南雄", ParentCode = "4402", ParentName = "韶关" },
            };


            //现在要求是,把中国下的一级节点都打展开。
            var treeNodes = new List<TreeNode>();

            GetTreeNode(regions, "ROOT", treeNodes);

        如红色部分,当我们调用获取地区树的方法时,就会发生堆栈溢出。

  解决方案

        1、限制递归调用的深度,简单,但是不好控制这个深度,如果写得太深,很浪费CPU,如果写得太浅,可能会导致需要的业务数据没有查出来。

             定义一个公共的变量

                //#region 限制递归深度

                //         _depth++;
                //        if (_depth >= 10000)
                //        {
                //            throw new Exception("递归超出深度");
                //         }
                //#endregion

       2、判断一下递归是否有环,在进行递归之前,把数据根据RegionCode进行查重处理,发现了有多个相同RegionCode即,报错。

       3、有同事提出,想在框架层面解决这个问题:

             简单的解决方案:建表的时候,对于regionCode这种字段,要不设置为主键,要不设置为唯一索引,可能更多时候,对于这种字典类的数据可以考虑这种方案。

             复杂的解决方案:暂无。。。,希望大家补充和分享