如何系统的解决问题

背景

只有解决问题才能创造价值。许多问题不是我们不能发现、不能解决,而是思维定势限制了我们,不能系统性的解决

作为一名程序员,我们每天都会遇到大大小小各种各样的问题,也在不断地解决各种各种的问题,同时也在解决问题的过程中不断成长。然而如果我们只是单纯的遇到问题,解决问题,那成长是有天花板的,而且这个天花板可能会很低,这也是我在工作中遇到的比较困扰自己的问题,同时我发现团队中其他人也存在同样的困扰,在经过一段时间的思考和实践后,我把自己的一点经验分享出来,希望能为同样和我一样处在困扰中的人提供一点思路。

方法论

其实我个人并不喜欢"方法论"这个词,提到"xx论"总觉得是一些虚头巴脑的理论,跟实践比较脱节,实际上是一些通用的方法和思维模型

系统性的解决问题,首先要搞清楚两个概念:1.什么是问题 2.什么是系统性

什么是问题

广泛的定义,理想与现实之间的差距就是问题,从这个定义来讲,我们遇到的问题太多了:线上bug是问题,项目延期是问题,效率不高是问题,收益不行更是问题。甚至我们整个业务都是围绕问题解决在运转,就是在解决理想与现实之间的差距。

这样看来,似乎定义问题发现问题并不难,两个关键点:1.定清目标 2.理清现状。 做到这两点之后,问题自然会浮出水面。但是要从这众多问题中找到有价值的问题,并非易事,却很值得,这需要我们结合自己的过往经验和价值观来判断,能够识别关键问题。我们羡慕的大佬、LD,他们的一个重要能力就是能准确识别到关键问题。

什么是系统性

既然要系统性的解决问题,首先要理解,什么是系统性。这个问题就像奥古斯丁在《西方哲学史》中所说的,"至于什么是时间,在没有人问我时,我非常清楚,可一旦要向别人解释,我就有点糊涂了"。我对于系统性概念的理解也是如此,感觉自己懂,但是却不能给别人很好的讲出来。我理解的系统性,应该包含两个层次的含义:

全面性:所谓全面性,不是点对点,而是从点到线再到面的过程,能够从更全面的视角认识并解决问题,需要我们去分析整体与各部分的关系,关注各部分之间的相互作用,理解问题的全貌,最终找到更全面的解决方案

彻底性:所谓彻底性,就是要思考问题的根因,探索问题的本质,从更深的层次分析问题,找到一劳永逸的解决方案。

系统性的典型体现是:一张大图 + 关键要素

系统性描述问题

如何系统性描述问题,也就是明确问题时是什么,这是系统性解决问题的第一步。

美国通用汽车公司管理顾问查尔斯·吉德林曾说过,"能够把问题描述清楚,这个问题已经解决了一半",只有先认清问题,才能很好地解决问题。这个说法并不夸张,他的原理在于当我们把问题清晰地写下来,我们会更容易理清思路,减少混乱和纷杂的思维。当我们开始有条理地思考问题时,我们可以更容易地找到解决问题的方案,而不是在杂乱无章的思维中浪费时间和精力。

清楚的描述问题,按照上面问题的定义,无非就是把现状和理想状态描述清楚,我认为需要做到以下三点:

  • 问题定义

能够给问题一个准确的定义,通过一句话简洁的描述出来。比如我们拿稳定性来举例,什么是稳定性问题呢,系统稳定性是指系统在外界影响下表现出的稳定程度,具备抵抗干扰的能力。

  • 问题量化

当前问题有没有指标可以量化,比如对稳定性来讲,当前系统事故频率怎么样,治理后怎么样,当前系统sla多少,预期应该达到多少

  • 影响评估

这个问题会带来怎么样的后果,同样以稳定性来举例,如果出现了稳定性事故,可能会造成的资金损失是多少,用户反馈投诉有多少等

系统性思考问题

系统性思考:决策者处理复杂问题的核心技能

能够清晰的描述问题之后,接下来我们要做的就是针对发现的问题,进行系统性的思考,这是我们最终能否系统性解决问题的最关键一步。市面上有很多讲解系统思考及思维模型的书籍,这里提炼一些关键信息和方法,系统性思考有三个维度:

暂时无法在飞书文档外展示此内容

  • 深度思考

不能停留在现象的表面思考,而要从现象深入到背后,直击本质。《教父》中说,"花半秒钟就能看透事物本质的人,和花一辈子都看不清事物本质的人,注定是截然不同的命运"。然而怎么样看清事事物的本质,才是真正困扰我们的。在《直击本质》书中,作者提出了三种思考问题本质的方法:

  • 思考事物的根本属性,一个事物之所以成为它的根本原因

思考和解决一个问题的起点,正是对事物根本属性的思考与理解,如果不理解事物的根本属性,就无法回答"是什么"的问题,不明白是什么,也就很难回答"为什么"和"怎么做"。比如商品是用来交换的劳动产品,这就是商品的根本属性。

  • 思考问题的根源:导致问题发生得根本原因

就像我们每次事故之后复盘一样,都要找到事故的根因并加以治理,才能真正的解决问题。

  • 思考现象背后的底层逻辑:隐藏在各种现象背后不变的规律

比如对于直播打赏,我们普通人看来就是内容生产者与消费者各取所需的一种模式,而高手们看到的是情感能量的孵化,能够从人性的维度去解释直播打赏的动机,至于大佬们看到的是啥,我也不知道,但是肯定比我们认识的更深刻

  • 全局思考

不能单点、局部的看待问题,要从更高的视角,更全面的思考问题,在纷繁复杂的关系中看到系统各个模块之间的相互关系,看到问题的全貌,从中找到规律、利用规律、做出最有决策。

我们工作中也经常会被挑战"到底有多少个场景"、"这些事做完系统就稳定了吗"、"这些事做完系统就没有隐私合规问题了吗",这里挑战的本意是全面性,防止有遗漏。如果我们在解决问题的时候就能提前全局思考,那我们自然不怕这些挑战,甚至别人没想到的,我们也想到了。

  • 动态思考

不能停留在某个时刻看问题,要理解每个人、每个业务都是动态变化的,在《如何系统思考》一书中提到,动态思考具备以下两个特质:

  • 不只是看到当下的因果关系,而应该拉长思考的时间维度,看到事物发展的动态变化和可能性
  • 不只是看到单向的、线性结果关联,而是应该认识到所谓的"因"与"果"之间可能是环形互动的。

复杂的业务难题,从来不是一个静止的点或面,而是动态发展系统。比如在今天遇到的内存不够、CPU受限等问题,在未来几年或许根本不是问题。

坦白讲,对于动态思考,我还没有理解的很深入,也没有能够在实践中有很多思考

系统性思考解决实际问题案例

在了解系统性思考之后,遇到问题能够深入、全面、动态的去思考并寻找解决方案,那么自然能达到系统性的解决问题的目的。这里给一个我自己实践中的例子:

问题描述

  • 问题定义:在一次DB迁移过程中,新增查询没有命中索引,出现慢查询,最后导致整个DB挂掉
  • 影响评估:整个库挂掉,导致所有跟这个库相关的多个直接业务以及上游业务都受影响,C端主播中心页面出现服务器打瞌睡,B端工单系统不可用
  • 目标量化:DB打挂的故障永不发生

思考过程

  • 深度思考:夺命连环问,寻找根因

Q: 为什么DB会被打挂?

A: 因为新增查询没有命中索引,出现慢查询

Q: 为什么出现慢查询,就会被打挂,出现慢查询就一定会被打挂吗

A: 出现慢查询不一定会被打挂,只有在高流量下出现慢查询才可能会被打挂

Q: 到底多大流量算高流量,我们的DB能承受多少 QPS ?

A: 没有固定阈值,DB能承受的QPS跟DB的硬件设施(内存、核数)有关,也与单次查询耗时有关,对于固定硬件设施的DB,整体的吞吐大致是跟"QPS * 单次查询耗时"成正比

Q: 为什么新增查询没有命中索引,技术方案中没有考虑到吗

A: 有考虑,但是本次变更新增多个查询,有遗漏,没有确保每个新增查询都能命中索引

Q: 切流过程中没有发现吗,为什么全量切流完之后才发现

A: 小流量阶段因为流量小,慢SQL在小流量下并未影响到DB的查询

Q: 切流前在新库上做过实验吗,有没有发现DB异常?

A: 切流前在新库上做过双写测试,当时没发现问题,因为当时老库中的历史数据还未同步到新库,数据量较小,即使没有索引,查询也不会很慢,所以没有触发异常

Q: 怎么样能确保后期新增查询都能命中索引,不会出现类似的问题呢

A: 1.人工保障,提升研发质量意识,新增查询都能主动确认是否有索引 2.系统保障:系统在发现未命中索引之后立马发送提醒给研发,这样如果新增没有命中索引的查询,在ppe阶段就能发现

  • 全局思考,穷尽可能性

Q: 还有没有其他可能也会导致DB被打挂

A: 1.DB数据量大,QPS高,即便是查询都命中索引,也可能会打挂 2.出现漫长的锁等待,单次查询耗时也会升高,可能会导致DB被打挂 3.如果出现大事务,会锁住更多资源部释放,容易导致锁等待及连接池被打满

Q: 对这些可能,我们的预防措施是什么

A: 1.限流,对BD做一层保护 2.如果可以,加缓存,减少到DB的流量 3.读写分离,让更多的读流量都打到读库 4.数据量很大的时候,考虑分库分表 4.对于锁等待,增加锁等待时长告警,出现漫长锁等待可以报警,也可以配置直接kill 5.可以整体对DB配置慢查询kill,防止拖垮整个库

Q: 做了以上策略就能保证DB不会被打挂码

A: 做到以上策略,在我的认知里已经是可以保证DB不会被打挂

Q: 其他服务会不会也存在类似的问题

A: 可能会有,我们对这次DB的故障的防护治理要覆盖到我们所负责的所有的业务

Q: 万一我们还是没有做好防护,DB还是被打挂了呢,该怎么及时处理止损

A: 1.如果是变更导致的,回滚变更 2.如果没有限流或者限流阈值不合理,及时调整限流 3.第一时间找DBA,专业的事情交给专业的人处理

  • 动态思考,拉长时间线看问题

Q: 影响DB故障的多个因素之间互相作用是什么,有没有隐形环路?

A: DB自身性能以及流量和单次查询耗时共同决定了DB的稳定性,不能单独定论说我们的DB可以承受多少多少QPS,这种一定是扯淡的

Q: 一年后两年后甚至多年后,这些保护措施仍然是有效的吗,有没有新的可能出现

A: 随着时间推移,数据量肯定会越来越大,流量大概率也会越来越大,我们遇到的挑战也会越来越多,但是这些防护措施仍然是有效的,做好防微杜渐是关键

通过以上深度思考和全局思考,我们对于DB被打挂这个问题,有了一个深入且全面的认识,也能够针对各种可能做出有效的预防措施。

DB故障 原因分析 事前防护 事中应急
流量大 缓存 - 如果是变更导致的,回滚变更- 没有限流或者限流阈值不合理,及时调整限流- 第一时间找DBA,专业的事情交给专业的人处理
限流
读写分离
分库分表
慢查询 未命中索引 1.提升研发质量意识2.系统索引检测提醒
数据量过大 分库分表
漫长锁等待 1.锁等待时长告警2.慢查询kill
大事务 1.提升研发意识,设计阶段避免大事务出现2.慢查询kill

结束语

以上是一些个人通过阅读提炼、实践总结的系统性解决问题的思考和经验,我仍然相信任何理论都不可能完美的解决所有问题,只能提供一些参考意义,否则一两本书就可能把大家的问题解决完了。

相关推荐
沉默王二19 小时前
你说你用Claude,你用的是 CLI,还是 Agent、Opus?
人工智能·程序员·claude
SimonKing19 小时前
别再把业务逻辑写进回调接口了!支付回调的正确打开方式
java·后端·程序员
BugShare2 天前
厌倦了使用 lsof 命令排查端口,来试试 sonar
运维·程序员
SimonKing2 天前
通义灵码不仅改名,还要收费了!!!
java·后端·程序员
陈随易2 天前
Redis数据结构速通
前端·后端·程序员
陈随易2 天前
Redis 8.8发布,一定要更新
前端·后端·程序员
ssshooter2 天前
Tauri 应用首次上架 App Store 被驳回了 3 次(iOS)和 12 轮(macOS)的经历
前端·ios·程序员
阿祖zu2 天前
2026 企业级 Agent 产品落地思考与全流程指南
前端·程序员·aigc
京东云开发者2 天前
AI助力跨境增长:京点点Oxygen Vision 跨境套图AI生成技术实践与展望
程序员