一个符合软件开发工程师认知的思考框架简单了解下

软件开发需要使用到编程语言,不管是前端、后端或中间件。

下面这段代码来自Spring框架的源码ClassNameGenerator#clean

private String clean(String name) {
    // 创建一个可变的字符串构建器,用于存储清理后的字符串
    StringBuilder clean = new StringBuilder();
    // 用于标记上一个字符是否不是字母
    boolean lastNotLetter = true;
    // 遍历输入字符串的每个字符
    for (char ch : name.toCharArray()) {
        // 如果当前字符不是字母
        if (!Character.isLetter(ch)) {
            // 将标记设为 true,表示上一个字符不是字母
            lastNotLetter = true;
            // 跳过当前非字母字符,继续下一个字符的处理
            continue;
        }
        // 如果上一个字符不是字母,则将当前字母转为大写后添加到构建器中,否则直接添加当前字符
        clean.append(lastNotLetter? Character.toUpperCase(ch) : ch);
        // 将标记设为 false,表示上一个字符是字母
        lastNotLetter = false;
    }
    // 如果清理后的字符串不为空,返回清理后的字符串,否则返回常量 AOT_FEATURE
    return (!clean.isEmpty())? clean.toString() : AOT_FEATURE;
}

通过源码可以清晰到各种条件判断、三元运算、循环、判断标志,这一套表述下来的逻辑是非常清晰的。

这也是软件开发工程师逻辑思维比较强的一个印证,但是对于工作中、生活中的事务是否也有一套逻辑的表达呢?也就是像是if else这样简单的判断和选择处理方式。

软件编程语言的设计参考了计算机科学理论、编程范式、实际应用需求等多方面因素。软件编程语言作为一个实际使用的工具也是各种理论的规范表达,迭代的也是各种理论的设计。

也就是说,能不能像if else这样的处理遇到的问题呢?这个框架是存在的,就是1999年由Dave Snowden提出的Cynefin模型

Cynefin模型将不同问题或场景分为5个域:简单、繁杂、复杂、混乱和失序。利用这五个领域,可以帮助更准确地评估情况,并做出适当的反应。

当遇到一个问题或者一个场景的时候就可以去套这套模板,进而选择不同的解决方式。这个过程和if else这样的思维逻辑很像,但具体的实现还是需要去完成。

graph LR; A[简单] --> B[感知-归类-响应]; E[繁杂] --> F[感知-分析-响应]; I[复杂] --> J[探测-感知-响应]; M[混乱] --> N[行动-感知-响应]; P[失序] --> Q["无法理解"];

Cynefin根据已知的多少可以进行简单的分类,已知的多少就表现在是否可以预测。

graph LR; G["Cynefin"] --> A[不可预测]; G --> B[可预测]; A --> C[混乱的环境]; C --> E[复杂]; C --> I[混乱]; B --> D[有序的环境]; D --> F[繁杂]; D --> H[明晰];

下面以实际软件编写和软件开发场景说明Cynefin的指导意义。

简单

当处在简单场景时,对于要解决的问题,其解决方案通常是明确和已知的。前期不需要过多复杂的准备,因为因果关系清晰,遵循既定的流程和方法就能顺利解决。因此简单场景也被称作“已知的已知”。

简单认知行为模式是归类模式,它表现为:感知(Sense) - 归类(Classify) - 响应(Respond)。首先清晰地感知问题的本质,然后将其准确归类到对应的类别中,最后按照已有的标准流程和规则进行响应,直接执行相应的解决方案。由于问题和解决方案的对应关系明确且固定,所以能够迅速且有效地处理这类场景中的问题。

提示词: Cynefin 简单场景基于Java软件编写举例

假设要编写一个程序来计算两个整数的和。在这种简单场景下:

public class SimpleCalculator {
    public static int addNumbers(int num1, int num2) {
        return num1 + num2;
    }

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
        int sum = addNumbers(num1, num2);
        System.out.println("两数之和为: " + sum);
    }
}

在这个例子中,计算两个整数之和这个问题的定义清晰明确,解决方案就是直接使用加法运算符进行计算,问题与解决方案的对应关系简单直接,符合 Cynefin 模型中简单场景的特征。

提示词: 以一个数据的数据库、前端、后端校验问题说明感知(Sense) - 归类(Classify) - 响应(Respond)的Cynefin简单场景解决

假设有一个用户注册表单,需要对用户输入的用户名、密码、邮箱等数据进行校验。

感知(Sense)

当用户提交注册表单时,系统接收到前端传来的数据,包括用户名、密码、邮箱等。

归类(Classify)

将接收到的数据按照其类型和校验规则进行归类。例如,用户名归类为字符串类型,长度需在 6 - 20 个字符之间;密码归类为字符串类型,需包含字母、数字和特殊字符,长度在 8 - 16 个字符之间;邮箱归类为符合特定格式的字符串。

响应(Respond)

根据归类的结果进行相应的处理。如果数据符合校验规则,将其存储到数据库中,并向前端返回注册成功的消息。如果数据不符合校验规则,例如用户名长度不足 6 个字符,向前端返回相应的错误提示,要求用户重新输入。

在这个简单场景中,校验规则是明确和固定的,只需要清晰地感知数据,准确归类,然后按照既定的响应方式处理即可。

繁杂

当处在繁杂场景时,对于要解决的问题,虽然存在可能的解决方案,但需要仔细分析和专业知识才能确定最佳选择。前期的准备工作能够提供一定的方向,但不能完全保证解决问题的有效性,因为情况可能存在一些变数。因此繁杂场景也被称作“可知的未知数”。

繁杂认知行为模式是分析模式,它表现为:感知(Sense) - 分析(Analysis) - 响应(Respond)。

首先需要全面感知问题的各个方面和相关信息,然后进行深入的分析,考虑各种因素和潜在的影响,最后采取准确的响应措施,制定具体的解决方案。只有通过严谨的分析,才能在多种可能的方案中选出最适合的那个,以有效解决问题。

提示词: Cynefin繁杂场景基于Java软件编写场景举例

假设要开发一个系统来管理学生的成绩。学生的成绩可能由不同的科目、考试类型(如期中考试、期末考试、作业等)组成,并且需要根据不同的权重计算总评成绩。

import java.util.HashMap;
import java.util.Map;

public class StudentGradeManagement {

    public static double calculateOverallGrade(Map<String, Double> grades, Map<String, Double> weights) {
        double total = 0;
        double totalWeight = 0;
        for (String subject : grades.keySet()) {
            double grade = grades.get(subject);
            double weight = weights.get(subject);
            total += grade * weight;
            totalWeight += weight;
        }
        return total / totalWeight;
    }

    public static void main(String[] args) {
        Map<String, Double> grades = new HashMap<>();
        grades.put("Math", 85.0);
        grades.put("English", 90.0);
        grades.put("Science", 78.0);

        Map<String, Double> weights = new HashMap<>();
        weights.put("Math", 0.3);
        weights.put("English", 0.4);
        weights.put("Science", 0.3);

        double overallGrade = calculateOverallGrade(grades, weights);
        System.out.println("学生的总评成绩为: " + overallGrade);
    }
}

在这个例子中,计算学生的总评成绩问题较为复杂,需要考虑多个科目的成绩和不同的权重。

虽然有明确的计算方法和规则,但需要对多个因素进行分析和处理,符合 Cynefin 模型中繁杂场景的特点,即存在多个正确的答案,需要专业知识和分析才能找到解决方案。

提示词: 以sql查询慢的问题说明感知(sense)- 分析(Analysis)- 响应(Respond)的Cynefin繁杂场景来解决

以下是以解决 SQL 查询慢的问题场景为例,说明感知(sense) - 分析(Analysis) - 响应(Respond)的 Cynefin 繁杂场景的解决过程:

感知(Sense)

首先会感知到 SQL 查询慢这一现象。可能表现为用户反馈系统响应迟缓,或者在监控系统中发现特定查询的执行时间超过了预期阈值。

分析(Analysis)

接下来进行详细的分析。这包括检查以下几个方面:

  1. 查看查询语句的结构和语法,是否存在复杂的连接、子查询或不必要的操作。
  2. 检查数据库表的结构,包括索引的设置是否合理,是否存在缺失或冗余的索引。
  3. 分析数据量的大小,是否有大量数据导致查询性能下降。
  4. 查看数据库服务器的配置,如内存、CPU 使用率等,是否资源不足影响查询性能。
  5. 检查数据库的统计信息是否准确,这会影响查询优化器做出正确的执行计划。

响应(Respond)

根据分析的结果做出相应的响应措施:

  1. 如果是查询语句结构问题,对其进行优化,简化连接和子查询,或者使用合适的聚合函数。
  2. 对于索引不合理的情况,添加必要的索引或者调整现有索引。
  3. 当数据量过大时,考虑数据分区、归档旧数据或者优化表结构。
  4. 若服务器资源不足,可能需要升级硬件配置或调整数据库参数以优化资源利用。
  5. 如果统计信息不准确,重新收集统计信息以帮助查询优化器生成更优的执行计划。

通过这样感知 - 分析 - 响应的过程,针对多个可能的解决方案进行抉择。

复杂

当处在复杂场景时,对于要解决的问题,并不知晓是否能够解决。无论前期做多少准备,都不能确保存在解决方案,而是需要依赖反思改进。因此复杂场景也被称作“未知的未知数”。

复杂认知行为模式是反思模式,它表现为:探测(Probe)- 感知(Sense)- 响应(Respond)。只能通过探测收集必要的信息,再通过反思感知,最后采取必要响应,调整之前的方案。

提示词: Cynefin复杂场景基于Java软件编写场景举例

以下是一个 Cynefin 模型中复杂场景基于 Java 软件编写的举例:

假设要开发一个社交网络平台中的推荐系统。这个系统需要根据用户的行为、兴趣、社交关系等多种因素来为用户推荐相关的内容和好友。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SocialNetworkRecommendationSystem {

    // 模拟用户数据
    static class User {
        int id;
        String name;
        List<String> interests;
        List<User> friends;

        public User(int id, String name) {
            this.id = id;
            this.name = name;
            this.interests = new ArrayList<>();
            this.friends = new ArrayList<>();
        }
    }

    public static List<User> recommendFriends(User user) {
        // 复杂的逻辑来分析用户的行为、兴趣和社交关系
        Map<Integer, User> allUsers = new HashMap<>();
        // 模拟获取所有用户
        allUsers.put(1, new User(1, "Alice"));
        allUsers.put(2, new User(2, "Bob"));
        allUsers.put(3, new User(3, "Charlie"));

        List<User> potentialFriends = new ArrayList<>();

        // 基于用户的兴趣推荐
        for (String interest : user.interests) {
            for (User otherUser : allUsers.values()) {
                if (otherUser.interests.contains(interest) &&!user.friends.contains(otherUser)) {
                    potentialFriends.add(otherUser);
                }
            }
        }

        // 基于社交关系的朋友的朋友推荐
        for (User friend : user.friends) {
            for (User friendOfFriend : friend.friends) {
                if (!user.friends.contains(friendOfFriend) &&!potentialFriends.contains(friendOfFriend)) {
                    potentialFriends.add(friendOfFriend);
                }
            }
        }

        return potentialFriends;
    }

    public static void main(String[] args) {
        User currentUser = new User(1, "John");
        currentUser.interests.add("Music");
        currentUser.interests.add("Travel");
        currentUser.friends.add(new User(2, "Alice"));

        List<User> recommendedFriends = recommendFriends(currentUser);
        for (User friend : recommendedFriends) {
            System.out.println("推荐好友: " + friend.name);
        }
    }
}

在这个例子中,推荐好友的逻辑非常复杂,因果关系不明确,难以通过简单的规则或模型来准确预测。需要不断地尝试和探索不同的算法和策略,根据实际效果进行调整和优化,这符合 Cynefin 模型中复杂场景的特点。

提示词: 以一个由于多个相互关联的微服务之间复杂交互导致的系统性能瓶颈问题说明探测(Probe)- 感知(Sense)- 响应(Respond)的Cynefin复杂场景来解决

以下是以解决由于多个相互关联的微服务之间复杂交互导致的系统性能瓶颈问题为例,说明探测(Probe) - 感知(Sense) - 响应(Respond)的 Cynefin 复杂场景解决过程:

探测(Probe)

首先,对系统进行初步的性能监测和分析,可能会使用一些工具来探测各个微服务的资源使用情况(如 CPU、内存、网络带宽等)、请求处理时间、错误率等指标。同时,尝试引入一些模拟的高并发请求,以观察系统在压力下的表现。

感知(Sense)

收集和分析探测得到的数据,感知系统性能瓶颈的具体表现和可能的位置。例如,发现某个微服务在特定时间段内的响应时间显著增加,或者某些微服务之间的通信出现频繁的超时和错误。还需要感知系统的整体架构和各个微服务之间的依赖关系,以确定可能导致性能问题的关键交互点。

响应(Respond)

根据感知到的情况做出响应。如果发现某个微服务的资源使用过高,可以增加其资源配置(如增加 CPU 核心或内存);如果是通信协议效率低下,可以考虑更换更高效的协议;如果是某个微服务的代码逻辑存在问题,对其进行优化和重构。同时,持续监测系统性能,以确定响应措施是否有效。

例如,在探测阶段发现微服务 A 到微服务 B 的通信频繁超时。在感知阶段,进一步分析发现是由于数据量过大导致的序列化和反序列化开销过大。在响应阶段,可能会采用更高效的序列化方式,或者对数据进行压缩传输。然后再次进行探测和感知,查看响应措施是否解决了性能瓶颈,若未解决,则继续这个循环,不断调整策略,直到系统性能达到预期。

通过这样的探测 - 感知 - 响应的过程,逐步解决由于多个相互关联的微服务之间复杂交互导致的系统性能瓶颈问题。

混乱

当处在混乱场景时,对于要解决的问题,完全处于一种无序和不可预测的状态。不仅不知道能否解决,甚至连问题的本质和范围都难以界定。前期的任何准备几乎都无法发挥作用,因为局势变化极快且毫无规律可循。因此混乱场景也被称作“极端的不确定性”。

混乱认知行为模式是应急模式,它表现为:行动(Act) - 感知(Sense) - 响应(Respond)。必须先迅速采取行动以稳定局势,然后通过感知获取更多信息,最后做出响应来调整后续的策略。在混乱场景中,没有时间进行深入的探测和规划,快速的行动和灵活的应变能力是关键。只能在行动过程中不断感知和调整,以逐步找到解决问题的方向。

提示词: Cynefin混乱场景基于Java软件编写场景举例

以下是一个 Cynefin 模型中混乱场景基于 Java 软件编写的举例:

假设正在开发一个在线购物网站,突然遭遇了大规模的 DDoS(分布式拒绝服务)攻击,导致网站完全瘫痪,用户无法访问和下单。

import java.util.Random;

public class ShoppingSiteUnderDDoSAttack {

    public static void main(String[] args) {
        boolean siteIsDown = true;
        Random random = new Random();

        // 模拟混乱的情况,随机决定是否能够恢复部分服务
        while (siteIsDown) {
            int randomNumber = random.nextInt(100);
            if (randomNumber < 30) {  // 假设 30%的概率能够暂时恢复部分服务
                System.out.println("部分服务暂时恢复,尝试处理积压订单...");
                // 模拟处理积压订单的代码
                try {
                    Thread.sleep(1000);  // 模拟处理时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                siteIsDown = false;
            } else {
                System.out.println("网站仍处于瘫痪状态,努力抵御攻击...");
            }
        }
    }
}

在这个例子中,由于 DDoS 攻击导致的网站瘫痪是一种混乱场景,因果关系不明确,无法预测何时能够恢复正常服务。只能采取快速的行动(如启用备用服务器、调整防火墙规则等),然后感知网站的状态,再根据情况做出响应(如继续加强防御还是开始处理订单)。

提示词: 软件解决过程中哪些需要行动(Act) - 感知(Sense) - 响应(Respond)的Cynefin复杂场景来解决

以下是一些在软件解决过程中可能需要通过行动-感知-响应(Cynefin 混乱场景)来解决的情况:

  1. 应对突然的服务器故障导致关键业务系统完全停止运行:首先需要立即采取行动,如切换到备用服务器或启动紧急修复流程。然后感知系统的恢复情况、数据的完整性等,根据感知结果响应,如决定是否需要进一步的数据恢复或调整业务流程。
  2. 处理由于软件漏洞被黑客利用而引发的大规模数据泄露事件:立即采取行动,如暂停相关服务、通知用户修改密码等。同时感知黑客的进一步行动、数据泄露的范围和影响,然后响应,如加强安全防护、与执法部门合作等。
  3. 面对由于自然灾害(如地震、洪水)导致的数据中心损坏和服务中断:迅速行动,启动灾难恢复计划,调配资源。接着感知数据中心的损坏程度、恢复的进展,然后响应,如调整恢复策略或寻求外部援助。
  4. 解决由于市场竞争对手突然推出颠覆性产品导致用户大量流失的危机:快速行动,制定紧急的市场营销和产品改进策略。感知用户的反馈和市场的动态,然后响应,如进一步优化策略或调整产品方向。
  5. 处理由于法规政策的突然变化对软件合规性产生的重大影响:立即行动,评估软件的不符合项,并采取临时措施。感知法规的具体要求和监管部门的态度,然后响应,如进行全面的软件整改或与相关部门沟通协商。

总结

模式 表现 说明
简单 感知-归类-响应 已知的已知
繁杂 感知-分析-响应 可知的未知数
复杂 探测-感知-响应 未知的未知数
混乱 行动-感知-响应 极端的不确定性
失序 无法理解 -

关于作者

来自一线全栈程序员nine的探索与实践,持续迭代中。

欢迎关注、评论、点赞。

posted @ 2024-08-30 10:44  落叶微风  阅读(15)  评论(0编辑  收藏  举报