debug和建模,看起来貌似风马牛不相及的两件事物。
对着牙黄色的投影幕布,指着满屏的形形色色的框图,箭头,绚丽多彩的色调,对系统、子系统、模块、领域、微服务侃侃而谈,满嘴蹦出的都是:服务发现、治理、编排、伸缩;数据采集、清洗、数据立方、切片、切块、旋转、折叠、下钻等一系列时尚而又让人似懂非懂的概念,言必称开源,语必说社区。
而广大猿们则是像极了皇帝新装里面的吃瓜群众,明明看着皇帝一丝不挂,却不敢轻易暴露。那股憋屈劲,就像心中有一万只草泥马在飞奔而过。
眼前浮现出一个昏暗画面:一个或几个不修边幅,满脸胡渣,满头头屑和头油的程序猿(一般为男猿),面色憔悴且狰狞,在阴暗的灯光下,坐在一台旧的老实显示器前(注意,一定要是14寸的,非液晶的),眼睛直勾勾的盯着电脑显示屏,双手一会噼噼啪啪的敲击键盘,右手一会转移到鼠标上,啪啪疯狂点击。
嘴里不停这几个词:艹,艹,爽,sb了。。。
往返循环,随机播放。
仿佛是在举行某种神秘的仪式,情绪在极度痛苦和亢奋的兴奋中急速转换,就像大海里狂风暴雨中随波逐流而又摇摆不定的一叶小舟。
怎么看都像赌场中输红了眼却又急于扳本的赌徒。
为啥建模和debug之间会有这么多差距呢?
这要从工作成果的可验证性来看就很好理解了。
架构建模阶段,无论是文字、表、各种图、类、对象、ADT、DSL等作为载体,即便考虑的再完整,系统结构和行为之间的关系总还是静态的,在行为复杂的异步情况下(真实业务场景下,事件的发生次序和异常的出现的时机、关联系统的靠谱程度)对系统的输入的时序都是不能穷举的,这也符合大家直观感觉,就是无论测试的多充分,在实际用户场景下,都会有些异常考虑不全。
编写成代码后,一旦上线,几个棘手的设计时遗漏的场景,总能把人折磨死去活来,这时的系统就不是好不好用的问题,而是能不能用的问题。但这时痛苦已经由程序猿来承担了,设计师已经转身潇洒转身,挥了挥衣袖,不带走一丝云彩的去做下一个系统的设计。
朴素的说,设计师的理想很丰满,程序猿的现实很骨感。
让我们来看看debug是怎么解决问题的。
debug阶段特点是debug的时候系统是实际运行的,系统的状态是动态的,很多设计时没有考虑全的问题都会暴露出来,特别是:
一、对于行为丰富的系统,由于行为(对系统的激励)发生的次序是异步的和随机的,导致设计时无法穷举次序之间的排列组合顺序,从而当某种特定场景(异步为跨进程的异常或周边系统不靠谱)出现时 ,系统无法应对。而且测试时很难充分暴露这种复杂排列组合(比如线程死锁、关联系统不稳定)的场景。
二、对系统运行的约束条件缺失实时校验,且约束没有显示化。系统碰到违反这种约束的场景时,既无法响应,也不易察觉,比如资源管理中,某些资源状态处于未知状态。
三、对于周边系统,其响应性应该考虑always(总是正确响应)、eventually(时好时坏,最终至少有一次是好的)、sometime(时好时坏,不能保证出现一次好的)、down中的所有可能,如果没有全部做应对处理,会导致特定场景下系统无法正确响应。
debug的时候这些情况可能碰到。
debug的本质就是识别系统核心状态序列,并明确在特定行为组合的场景下,状态序列变化的规律。
所以,大家可以看到,debug的过程就是寻找隐藏的状态序列的过程,这种探寻其实很有乐趣。
我们来看下debug的过程都干了哪些事:
1、让处于debug状态的程序运行
2、程序输出日志
3、摘取日志中我们关注的变量和值,当然这些变量和值和它们出现在日志中的位置也应该作为变量之一(位置一般代表了某些行为组合的发生次序,也就是状态序列的切面的快照);debug的step into和step over就是触发这些状态序列由一组值变成另一组值的过程。
4、通过人眼检查某些行为组合发生变化时,状态序列变化和预期是否一致,以及每一步中状态序列的值是否违法了一些规则和约束的定义。
从这里大家可以看到,debug和建模都有以下相似:
1、关注关键数据及其变化
2、关注变化是否满足属性和约束
3、关注希望发生的变化有没有发生
4、不关注所有数据,只关注和问题相关的数据
5、不关注每一步的变化,只关注和问题相关的关键步骤变化
这个过程就是可视化、理解系统在各个抽象层次上行为的过程。
debug会吐槽什么:
1、会吐槽某些数据结构定义层次不清、混杂在一起
2、会吐槽想看到的东西不容易看到
3、会吐槽数据的变化不清晰直接、绕来绕去
4、会吐槽某个关键状态没有显示表达,需要通过其他变量手工计算
弄清楚这些会吐槽的问题,就是梳理业务,建立模型的过程。
假设系统已经实现并正在运行,出现了各种各样的问题,你要去debug这个系统,此时,你希望看到的东西就是建模的关键要素。这个过程就是建模。
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/213233.html