从《从小工到专家》的“道”到大厂的“法术器”-实效篇

Posted hello_读书就是赚钱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从《从小工到专家》的“道”到大厂的“法术器”-实效篇相关的知识,希望对你有一定的参考价值。

上一篇哲学篇在公司内部论坛发布后被推荐到首页、也用了那篇文章给组内同事分享,得到的大家的认可与大家的讨论,借着这股劲,继续完成《从小工到专家》本书第二章内容的梳理与自己经验的复盘回顾,思考成长的灯塔

一、本文的内容

本文的内容是根据《从小工到专家》这本书的第二章内容梳理编写的,其中印象最深刻的点是“曳光弹”这一节,讲的是我们开发的时候就像是在黑暗中寻找打击目标,需要借助“曳光弹”来照亮黑暗,来寻找到目标的位置.正如这个小故事,书的作者告诉我们在研发中如何提高效率,途径,借着他的观点,我们一起反思.

二、道与法术器

1、重复的危害

只要看过编程思想的书,对“重复”一次应该很熟悉,我们一切的系统架构,代码架构,都是为了减少“重复”而出发.书的作者告诉我们,知识是不稳定的,意味着维护它们要有精力与时间.这里的重复不仅是在代码中,是贯穿整个软件工程的方方面面.
“重复”问题对于腾讯来说最不陌生,它的技术栈一直是被吐槽,就是因为重复的问题,不管是研发中的方方面面,都可以发现N多个轮子,这些轮子业务功能相似,开发的语言、框架却是花样百出各有不同.
轮子太多,都是重复.针对这个问题、在19年,腾讯内部研发一款rpc框架,为的就是解决这个问题.它用接口的方式按照业务方式勾勒出架构图、只在核心处提供具体的实现,把业务的实现交给不同的团队自己实现.这个框架的出现整合了存量的技术、不仅统一了交互协议为框架统一的rpc协议、也用各种语言go、c++、java都将这套框架都实现了一次,对代码语言进行统一.除此之外,监控手机、日志、数据库连接、http、trpc链接等都进行了统一的收归,最后利用内部的123平台做统一的发布迭代,做到了合理调配轮子,去除重复问题.
正如上面我亲眼所见的例子,我们要清楚知识是可以被维护的,但是知识很容易出现重复,针对这个问题,我们要坚守DRY原则,即系统中的每一项知识点都必须具有单一、无歧义、权威的表示.否则,爆雷的时间取决于自己什么时候会忘记.上面我司的例子就是如此,rpc框架就是权威、单一、无歧义.
对于重复,书的作者给我们进行以下几种方式的归类:

强加的重复:环境或者语言等问题导致的,针对这个问题我们可以

  • 利用代码生成器,让知识的生成变为主动的,自动化的.腾讯的rpc框架就是根据pb生成的,可以按你需要生成不同语言的版本
  • 警惕代码中的注释,只保留永不会过期的内容
  • 知识文档的自动化生成.这个也是最近我们组一直在推的东西,框架并没有推动文档的生成,我们又用了一个轮子,我们正在考虑如何跟这个框架结合起来

无意义的重复:比如设计中的重复,不遵循数据库第三范式,变动一个对象就会引起数据不统一问题.
针对这个问题我们可以考虑设计中或者使用中这些无意义的重复的案例,要留意的是缓存问题.
通过我们会用“空间换时间”的方式来加快查询速度,但是不可避免的会让数据有差异.针对该问题的解决途径是,把“重复”控制在一个有效的范围内,通过高内聚,低耦合的解决.

无耐性的重复:直接拷贝代码就是最好的例子,拷贝一时爽,收拢火葬场.欲速则不达,考虑问题一定要想清楚不要自己给自己留坑.最近在收拢一个逻辑,几乎用了两周的时间.

开发者之间的重复:这个问题需要依赖是上面的把控,由上到下,对各个业务模块,要指定出口人,要加强团队之间的沟通交流.

2、正交性

正交性是几何里面的概念.指的是两条直线相交成直角.在软件中, 是某种不相依赖性或解耦性,二者的变动会引起其他模块的变动.
如果我们假设组件是正交的,那么M个和N个组件,就能搭配出M*N个效果.如果其中一个组件有风险,那么我们可以快速的把那个组件隔离掉,正交性也有降低系统风险的好处.
书的作者说,正交性也是发生在系统的整个构建过程中的:

团队间也有正交问题:所以我们对于团队,就是要责任分明,像我们的后台小组,大概有30人左右,我们按照我们各自的业务,区分app、crm、支付等业务、虽然我们用的是同一套技术体系,但是业务上面我们各不同.底层存储我们也是进行隔离、上下游业务依赖直接通过定义好的交互协议进行的.

设计上也有正交问题:所以我们看到的常见的分层结构、就是为了解决正交问题.像tpc协议的为什么要设计7层?就是为了下一层对上一层完全透明、即使是底层进行技术升级迭代,也不影响上层的功能.

数据上也有正交问题:常见的比如说用了变动的数据来做主键.在我遇到过的实践中,经常是有一个字段用来区分不同的意义,导致到最后都分不清个所以然,比如我们用money字段的负数来做异常的状态,需求的变动衍生出了真的有money为负数的情况.我们的头就立刻变大,不得不用其他的方式来兜住这个底.

为了解决正交问题,在代码,书的作者提倡我们可以用重构的方式,提高我们系统的正交性,并且用单元测试来验证我们的正交性是否见效.在其他方面就要我们多多思考了.

3、可撤销性


如果某个想法是你唯一的想法,再也没有比这更危险的事情了,书的作者在这一节里面告诉我们对于研发来说,设计方案的可撤销非常重要.这里的撤销,并不是指的ctrlZ的那种,而是评估了一种技术方案,要考虑可扩展,能撤销掉换成另外一种.即我们做方案设计的时候总要有planB,软件就是要够软.
像DAO层,就是一个可撤销性的最好体现,支持切换不同的数据库.软件工程就是薛定谔的猫,只有等到下一个需求来临的时候,你才知道猫是死还是活,作者用这一节一再的强调所有的需求与决策是写在沙滩上的而不是刻在石头上的,海浪一来,他们将不复存在,不存在最终决策,我的经验里,确实是存在很多设计不够软,导致需求变动引起撕逼改代码的过程.所以,在后面每次技术评审的时候,我都会问产品对需求的扩展问题、我可能会在原有的需求上,保持一个更宽范围的设计,允许需求有小范围的波动,让我的代码可以在小变动的下套进去.
举个更具体的例子.像上面所说我厂的rpc框架与Spring框架就是一个可撤销的例子.在架构上面看,这样的框架只是提供了框框,用接口描述了功能的搭配与交互,其中的实现都是由第三方插件提供,做到随时可拔插,也是说他们的可撤销性很高.我厂rpc框架的诞生也是为了统一我司不同的轮子,但它又不仅仅对内,只要你遵循开发的接口与规范,实时可以实现一套对应的插件.

4、曳光弹


这一节,是我读到的最感兴趣的一节,而且我现在无论是在开发还是排查问题的时候,都会问自己,“我是否已经找到曳光弹”.
书的作者说,每一个需求的开发都是在黑暗中前行,虽然我们可以通过计算、评估、猜测目标的位置,但是也不能保证百发百中,所以我们可以借助曳光弹.研发就是在走夜路,我们时长是摸黑前行.
曳光弹,曳光弹与常规弹药交错着装在弹药带上.发射时,曳光弹中的磷点燃,在枪与它们击中的地方之前留下一条烟花般的踪迹.如果曳光弹集中供暖目标,那么常规子弹也会击中目标.
描述得是不是很精准,开发中的曳光弹,即“在黑暗中发光的代码”.它听起来像不像我们后台写接口的时候做的单元测试,一遍遍的覆盖我们分支,在“黑暗”中摸索到我们逻辑的正确性,等到单元测试通过,那么接口就不会问题.像不像debug的日志存在,我们在每一个代码分支中留下日志的痕迹,直到我们可以准确击中目标.它也可以是postman的rsp,我们项目用的是wns协议,在客户端上面模拟并不容易,所以我们用http协议打通了该条连续,后端直接通过postman调用模拟,数据OK了,代码多路覆盖了,那么便可以直接推测.
我对曳光弹的理解,其实也是解决问题的思路,我们要找到某种东西,让我们能快速、直观和可重复地从需求出发,满足最终系统的某个方面要求.这个可以方方面面,前几天 我们同事分享她在找一个服务的ip时,用了dig命令,这何尝也不是曳光弹的存在.
书的作者还建议曳光弹最好不是用完即弃的代码,最好是让曳光弹能持久的为你扫除黑暗.而且,正确的运用它,还能让我们有了可用于演示的东西,我们能够感觉到工作进展.
我建议所有读者可以培养“曳光弹”意识,这样真的能提高我们解决复杂问题的能力.

5、原型与便笺


我们常在软件工程中读到原型模式.原型的存在是为了分析和揭示风险,并以大大降低代价、为修正提供机会.而便笺则是白板上面的模型.

上图,是我在读mysql的全文索引机制梳理的一个架构图,是不是有了图片的流程,看起来也是非常的清晰,这是一种便笺,书的作者说它也是一种原型.
我负责的一个业务开发中,其实也用了原型的开发模式.我们内测试的第一个版本,就是只有游戏的互动,基本就是一个背景还有题目的模版,随机的语音,奖励模型等.然后由内部用户体验、在第二个周期,我们往这个游戏上增加了课程的概念,后面有增加了购买体系等,基于这个原型我们在三个月后完成了项目的上线.
书的作者说原型的设计并不是仅仅在于UI,还有是架构、已有系统的结构或内容、第三方工具或组件等.原型存在的意义并不是他的代码,而是基于原型我们学习到的经验教训,所以我们在学习的过程中可以通过制作一个原型来让自己达到学习的目的.
适当地使用原型,可以帮助我们在开发周期的早期确定和改正潜在的问题点——在此时改正错误既便宜又容易,从而为你节省大量时间、金钱、并大大减轻我遭遇的痛苦和折磨.

6、领域语言


这里的领域语言,并不是说领域驱动设计的意思哈.而是说跟业务体系相关的相关术语.书的作者说语言的界限就是一个人的世界的界限,指的是可以根据自己业务的情况建立一套适合业务本身的领域语言,方便团队内部进行业务沟通,再根据领域语言研发自己的代码.
文中举出微软根据邮箱的业务特性,研发了邮箱专属的领域语言(非程序语言).但是这一事例我却不大赞同,除非这种语言对是整个业务团队是唯一的且权威的,否则只会增加迷惑性,我们在考虑领域语言设计的时候,最好还是要参考业界标准,这样能减少同事的认知成本.
书作者提倡,我们考虑领域语言设计的时候,最好还是要考虑这个系统的使用期限,如果系统很快就被淘汰,那么最好还是用比较复杂的,但是是通用的可读性更好的语言.
在我们团队的内部,主要发现的一个大问题是大家对业务的领域语言并没有一个统一的认识,也是《领域驱动设计》里面提到的统一语言,比如我们要描述“学科”这一业务术语,有的人用的是subject、有的人用的是scene,有的是production,对于领域业务术语的没有统一,导致可能针对同一模块的业务代码看起来像是不同模块,增加了阅读和理解成本.针对这个问题,作者的实践是通过wiki建立业务术语表格,大家一起维护这套标准的规范.
对于这个知识,我们其实也是可以参考领域驱动设计里面的想法来做的,它也是可以提供思想方面的指南,我们按我们的业务需要去做不同的落地.

7、估算


有没有遇到这样的一个问题,常常估算的工作时间不准,到dealline的时候就要加班加点.这边书在最后一节告诉我们关于估算的一些方法,他说估算是需要学习的,通过学习估算,并将此技能发展到你对事物的数量级由直觉的程度,你就能展示出一种魔法般的能力,确定它们的可行性.
有趣的事情,作者说关于估算的精准度.同样的时间,会因为单位的不同让人产生不一样的感觉,比如130天,听起来好像很接近,但是4个月到5个月会让人感觉比较远遥.所以,他提倡我们1 ~ 15天用单位、天;3 ~ 8周用单位周;8 ~ 30周,月;用合适的单位,可以更好的反映我们想要传达的精确度的单位.
而对于估算刻度的来源,我们可以通过以下途径来评估:

  • 问做过的人
  • 圈定事情的范围
  • 建立估算的模型.我的理解是细化任务,找出任务主体骨架,并针对每一个小任务评估合理时间,在最后进行合并计算得出最终时间
  • 定时复盘,通过复盘之前的估算结果与实际耗时的差距,并分析gap的原因,在下一次去避免他.比如之前我评估工作量的时候就是按实际的开发+测试时间去评估,但是往往没有给自己留一些“意外”的时间,所以在后面的需求评估,我一般会在实际的时间上加上“意外”时间,保证需求能在规定时间内被完成.

以上就是本章的整体内容了,其实我已经对工具篇的内容也读了,但是因为书出版太久了,现在的工具已经跟那个时代没法比了,但终归我会看完再进行分享,大家可以继续期待

以上是关于从《从小工到专家》的“道”到大厂的“法术器”-实效篇的主要内容,如果未能解决你的问题,请参考以下文章

从《从小工到专家》的“道”到大厂的“法术器”-实效篇

从《从小工到专家》的“道”到大厂的“法术器”-实效篇

从《从小工到专家》的“道”到大厂的“法术器”-哲学篇

从《从小工到专家》的“道”到大厂的“法术器”-哲学篇

从《从小工到专家》的“道”到大厂的“法术器”-哲学篇

从《从小工到专家》的“道”到大厂的“法术器”-哲学篇