0%

概况

作为一个北方汉子对于面食真的是十分热爱的,尤其是发面后的。从小在家兜包子都是只能看不让参与的,长大后在外面都是买现成的,如今也想自己做一做。也许是从小在家耳濡目染,第一次做整体的效果还不错。
宋丹丹老师曾经说过把大象装进冰箱总共要分三步,那么蒸包子总共需要分为如下五步:

  1. 准备原材料
  2. 发面
  3. 调馅
  4. 擀面片
  5. 蒸包子

可是,真的就是只蒸了包子吗?

关于蒸包子的一些思考

分治法

就像我之前聊到过的,复杂的东西是由许多简单的东西组成的。就像蒸包子这件事不一定多么复杂,但也不那么简单,要想做好也是要拆分成上面五个相对简单的步骤执行。作为一个后端工程师,现在做事情总是会带入一些思维模型去看,这个例子是分治法来将蒸包子这件事简单化,只要我们把其中简单的每一步做好就可以最终把包子蒸好。

批处理

当我把包子蒸好以后,发现耗时很长,那么怎么提高效率呢。刨除在网上买菜等菜的时间,大致的时间线如下:

发面准备:15:00 -> 15:30
发面期间:15:30 -> 17:00
做、调馅:16:30 -> 17:30
擀皮 :17:30 -> 18:00
包、蒸 :18:00 -> 19:00

总计人力耗时 3 小时,出锅 18 个包子。如果我要是蒸 36 个包子就要消耗 6 小时的时间吗?答案是要小于 6 小时的,主要原因有以下几点:

  1. 蒸笼仍有一半的空间未用,可以节省掉一次烧水蒸包子的时间。
  2. 每个环节都可以节省准备工具,收拾工具的时间。

但是我要再多蒸一倍的包子是不是平均耗时会更短,这个就不一定了,如果蒸锅的承载上限就是 36 个包子,那平均耗时就不会再减少。
批处理的方案在一定程度上会提高我们的效率,但不会无限提高,而是有一个最优解,这个最优解取决于外在条件。

并发思维

以上情况分析的是单人力情况下,如果再有一个人一起做。可以有以下方面提升:

  1. 我们发现面团在 17:00 发好的,擀皮在 17:30 才开始的,中间阻塞的时间在弄馅。把弄馅的时间交给第二个人做,可以减少 30 分钟阻塞。
  2. 发面准备分两个人做可以大致减少 15 分钟耗时。
  3. 两个人一起包包子可以大致减少15分钟耗时。
  4. 额外损耗,例如工具准备上因为多加了一套工具会产生额外耗时。

最后大致的总人力耗时会大于 3 小时,平均人力耗时在 1.5 到 2小时之间。并发思维又是我们另外一个手段。

流水线模型

上面需要人操作的蒸包子需要四步,其中每一步都会有一些内耗是在每步切换时都需要思考下一步该怎么做,以及准备对应步骤的工具撤掉上一步骤的工具。如果我们厨房能供四人同时使用,并且每人只做一步的事,那么每一步的耗时就会因为熟能生巧而使时间大大缩短。如果这是一家包子店的厨房,那么这四个人就可以源源不断的高效生产包子。通过流水线模型来提高效率,这也是并发的一种。

工具化思维

再假如,北京所有的人早餐都要来这家店吃包子,那么任凭这四个人怎么日夜生产,也不能满足整个北京的需求。如果还是这四个人怎么做?如果恰好其中有一个人学过机械相关的知识并且动手能力又很强,这时候他可以和其他三个人一起交流蒸包子的心得,然后结合整个知识,设计出蒸包子机器,然后找工厂生产出几十台日夜生产,我想北京的包子供应应该就没问题了。他们四个人只需要盯盯机器,坏了修一修就好了。这里面就用到了工具化思维,可以极大的提高我们的生产效率。工业革命的意义之一就是创造了巨大的生产力。

说了这么多,下面附上我的蒸包子攻略~

蒸包子攻略

准备原材料

  • 准备面皮
    • 面粉 1 kg
    • 酵母粉 5g
    • 温水
  • 准备馅(猪肉大葱)
    • 猪肉馅 500g
    • 大葱 500g
    • 姜、料酒、胡椒粉
    • 耗油、鸡精、生抽
    • 香油
    • 老抽

发面

  1. 用温水冲开酵母粉,混合均匀后加入面粉中和面。

  1. 慢慢慢慢~加水,搅拌成絮状。

  1. 最后柔成光滑的圆面团。

  1. 放到温暖的地方发酵,一小时左右吧,面团最后会放大一倍左右。

加水的时候需要慢慢加慢慢抓,慢慢会形成一个光滑的圆团,面团的软硬跟水的多少有关,如果面硬的话可以适当加一些水调整软硬程度。

调馅

  1. 趁着面团发酵期间,可以开始准备调馅了。买的是绞好的猪肉馅,然后就是把两颗大葱切碎,切点姜碎进去。
  2. 加入上述的各种调料调整肉馅的口味。由于放了老抽和生抽,盐可以少放或者不放,根据个人口味来看。
  3. 加好以后搅拌均匀就行了。

其中老抽用来调色,生抽、鸡精、耗油用来调味,胡椒粉、姜碎、料酒用来去腥,加一些香油可以让肉馅变得超级香。

擀面片

  1. 调好馅可以休息一会,待发好面取出来继续揉捏,直到里面没有气泡了。
  2. 然后揉成一个细条状,用刀切成一段一段的。用手掌按成扁圆的。
  3. 用擀面杖一点点擀成扁片,厚度比饺子皮厚一些,标准的面片是边缘较薄中心较厚的圆形。

蒸包子

  1. 准备一个篦子,上面放好屉布,待包子包好放上去。至于兜包子的手法直接网上查吧。
  2. 准备好蒸锅,放上包子开火后蒸20分钟左右即可,关火后放 5分钟。
  3. 最后的出锅,因为包子会变大导致互相黏连,可以准备一些清水滴到屉布和包子连接处湿润,这样包子就可以完好的取下了。

最后来一张出锅照,年轻人的第一锅包子就这样做好了。

最后

工作和生活中我们会遇到很多事和物,事事物物之间有很多共通之处,包括问题的产生和解决办法。不同表象的背后相同的本质的东西是思维方式还是抽象模型?看清它们,能带给我的是做出好吃的包子,不仅仅是这些,还有更多。

什么是复杂性

复杂或复杂性与简单相对立,那么复杂是什么?它是我们大脑中的一个概念,但是我在网上找不到一个给复杂恰当的定义描述,它会有不同的解释。
其中洛克在《人类理解论》中说道:『一些思想是由简单的思想组合而成,我称此为复杂;比如美、感激、人、军队、宇宙等。』
作为研究复杂系统的专家 Melanie Mitchell,也没有给出一个明确的公认的定义。她在《复杂》一书中给出了复杂系统加以定义:『复杂系统是由大量组分组成的网络,不存在中央控制,通过简单运作规则产生出复杂的集体行为和复杂的信息处理,并通过学习和进化产生适应性。』
上述复杂系统中的组分对应软件系统中的组成部分,基于不同粒度可以是对象、函数、类、包、模块、组件和服务等。每一部分都应该是相对单一的职责,细粒度部分之间耦合提供更粗粒度功能,不同组分之间相互协作来提供系统功能,继而组合成我们复杂的软件系统。

阅读全文 »

初步认知

以 Drools 为例子

这个组件是什么,有什么功能?

Drools 是一个基于Charles Forgy’s的RETE算法的,易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师人员或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。
Drools相关概念

  • 事实(Fact):对象之间及对象属性之间的关系
  • 规则(rule):是由条件和结论构成的推理语句,一般表示为if…Then。一个规则的if部分称为LHS,then部分称为RHS。
  • 模式(module):就是指IF语句的条件。这里IF条件可能是有几个更小的条件组成的大条件。模式就是指的不能在继续分割下去的最小的原子条件。

Drools通过 事实、规则和模式相互组合来完成工作,drools在开源规则引擎中使用率最广,但是在国内企业使用偏少,保险、支付行业使用稍多。

阅读全文 »

你有没有遇到过一个函数几百行长度,如果没有可以跳过本文章了,如果没有那么应该看看下面的内容。一个超长函数的复杂性不在于那些胶水代码,而是其中的逻辑分支,大量的逻辑分支导致你的代码难以理解。而重构的过程分为两步:

  1. 编写单元测试,如果覆盖到了函数的每个分支,那么重构的风险性就会降到最低。
  2. 重构代码,对代码进行拆分重写,为了使代码变得易于维护。

重构分为三个层次:

  1. 小重构
    • 消除重复代码
    • 拆分小函数(单一职责)
  2. 设计模式
    • GoF 23种
  3. 抽象建模
    • 四色建模法
    • 风暴建模法

复杂度问题的应对办法,防止偶然复杂性。

TODO

背景介绍

首先介绍一下实体电商通用的售后流程。

  1. 用户申请:在用户申请操作时需要填写退货、换货,以及原因。
  2. 商家审核:商家会根据沟通情况审核售后申请。
  3. 用户回寄:审核通过后需要用户回寄商品。
  4. 确认退换:商家收货确认后会给用户退款或者邮寄新货。

虚拟商品的售后通用流程如下:

  1. 管理员发起退换操作
  2. 处理退换
    • 退:先退货后退款
    • 换:先退货后发货

在以上两个流程的处理流程有个共通的地方,就是一次操作需要涉及多个子流程的处理,这就是接下来需要讲的通用售后流程抽象。多个子流程的处理意味着要和多个子系统分别进行沟通处理退货、换货和退款。

这里就涉及到分布式系统的一致性问题了,售后模块作为资源的协调方,我们是否可以采用 TCC 的强一致性方案?答案是 No,成本有点高。普遍的做法是采用弱一致性方案保证最终一致性,我们可以考虑采用 Pipeline 机制。

阅读全文 »

本文主要介绍知乎订单系统后端语言栈的转型升级过程,包括其间踩过的一些坑和遇到的一些问题。一来是想通过本篇文章为其它应用服务转型提供借鉴经验,二来是总结对于订单系统的理解。鉴于文字功底不足,对于业务理解不充分的地方,欢迎留言交流。文章大纲如下:

  • 迁移背景
  • 前期准备
    • 迁移方案
    • 接口验证
    • 指标梳理
  • 可用性保障
    • MTTR 快速响应
    • MTBF 降低故障率
  • 一致性保障
  • 事后总结
    • 目标回顾
    • 执行计划
    • 执行结果
    • 问题整理
  • 业务沉淀
  • 方法论实践
  • 参考文章
  • 招聘信息

迁移背景

随着知乎整体技术栈的变化,原有的 Python 技术栈逐渐被抛弃,新的 Go 和 Java 技术栈逐渐兴起。知乎交易系统的稳定性相比其它业务系统的稳定性重要很多,因为交易系统核心链路发生故障不仅会造成数据问题,还会造成严重的资损问题。
随着公司业务的不断壮大发展,交易场景变得复杂,重构和优化难以避免,因为语言特性,Python 虽然开始撸代码很爽,但是后期的维护成本慢慢变高,不过 Python 在数据分析和人工智能方向上还是有很大优势的,只是在交易领域目前看起来不太合适。从技术生态上来说,用 Java 做交易系统会更有优势,所以接下来要说的知乎订单系统语言栈转型。
另外一个因素是 Python 的 GIL 锁导致它无法发挥多核的优势,性能上受到很大限制,在实际情况中遇到过多次主线程被 hang 住导致的可用性故障,所以坚定决心来迁移掉旧系统。

阅读全文 »