timzaak / blog

8 stars 1 forks source link

代码项目工程化 #102

Closed timzaak closed 1 year ago

timzaak commented 1 year ago

写代码和工程化其实是两件事。写代码追求的是极致的性能和quick and dirty;工程化则专注于如何管控多人协作,如何在人员更替、人员水平层次不齐的状态下保证产品质量和产出效率。本文记录一些个人关于代码工程化的思考。

质量管控的一些方法

文档

项目相关文档,主要分为:

  1. 预研资料集结,罗列项目相关PDF、链接,并做简要总结。
  2. 项目甘特图,进度排期,方便发现项目卡壳,及时调整。
  3. 项目产品描述,包含产品使用说明文档、测试用例、产品原型、UI原型等,用以和员工、客户解答产品到底是什么的问题。
  4. 技术文章,总结在做项目时,遇到的技术问题和解决方案。这类文档在没有明确的激励下,均来自于自我驱动。
  5. 工程文档,来自于工程协作中,不同工种之间的协作依据,文档生成工具链若是成熟还好,若不成熟,又无法及时共享修改,很容易陷入指责地狱。
  6. 项目总结/会议纪要/周报/...:做事留痕。

文档对于研究型公司来讲,价值巨大,它的价值不仅是对一些实践/实验做总结,方便后来者避坑,更在于后来员工可依据此快速找到解决过相关问题的。 对于业务型公司,若公司没有较好的共享平台,则价值相对较少,更多的是用于汇报和个人成长记录。更有甚者,某些员工写的最有价值的文档是交接文档:)。

公司在实施上,可起步于知识库、项目管理工具,但此类产品不好做激励,更多是用于做事留痕和同步信息。后续引入企业内部论坛,叠加激励机制和硬性规定,才算是步入正轨。

日志

日志是非程序编写人员去了解程序是否异常的有效途径,有时甚至是唯一途径。 当程序上生产后,在和运维人员一起解决Bug时,只有日志是唯一真实可靠的信息源,有时候只能专门为了几行 log 发一个新版本。后续在和 bug 负责人沟通,日志也是防止相互扯皮的有效手段。

日志查看平台的搭建,各大云厂商都有提供,开源的重量级的有 ELK,轻量级的有 Loki,国内的一些大厂会因为日志数据量、并发量过大而基于 Clickhouse 打造。至于日志采集,按照语言、使用场景来看,多种多样,具体采用哪个,还需要具体细看。

监控

监控可归结于日志的一种数值/事件形态。监控的功能除了异常上报、设备负载等关键指标采集,还包含指标异常预警、值班人员触达、异常处理报告。它主要解决的问题是在异常出现的早期,快速介入,防止造成更大影响。开源社区的通用基础方案有 Sentry、 Grafana+Promise 等监控平台,数据上报范式目前较为流行的标准是OpenTelemetry。商业化的手机端国内有 Bugly,Web/小程序端国内有 FunDebug。根据项目类型,有不同的方案可供选择。

公司起步最好先用 SaaS 服务,后面再自搭,最终自研,方便延伸到数据采集、运营。监控对于技术的要求还是蛮高的。

CICD

CICD 主要有三个功能:

  1. 强制约束开发人员,规避低级错误,尽早发现Bug。
  2. 确保打包环境的纯粹性和可重复性。
  3. 隔离密钥等保密资源,确保最少人知道。

企业项目的常用解决方案是 Jenkins,国外的开源项目是Github Actions,至于国内的开源项目大致都是 Jenkins 的魔改版。

企业实施的时候,代码质量检测SonarQube只要一得空闲就要补充在CI中,可有效防止代码格式化、黑魔法的产生。至于CICD方案推荐使用 Jenkins。至于Gitlab Runner 等,要么耦合性太强,要么不成熟。付费版的国内有Zadig 等,未使用过。

编程工具链的选择

对于复杂业务型项目的编程语言选择标准:强类型+GC+生态稳定。 从上述三个层面来讲:Web/H5: Typescript,后台:Java/Go,移动端:Dart/Kotlin/Swift,嵌入式/SoC:C/C++,游戏:C#。

从发展趋势上讲: 后台: Go 最终会变成另一个 Java, 而 Java 会容纳 Go。 移动端:Flutter 带领的跨平台开发体验越来越好,目前就看 Google 是否愿意继续投入大量资源,若无,Dart 也就挂了; Kotlin/Swift 终究会随着移动端下滑而不断削弱。 Web/H5: Typescript 在应用层面,基本上成为很多公司的标配,JsDoc 等通过注释给 Javascript 添加类型的方案,只有 deno 级别的项目才有较大意义。 至于Web开发框架,目前还是 React 独领风骚,Vue、Angular、Svelte 等依旧在追赶,在底层技术不发生大的变更的前提下,整个市场占有率估计不会有大的变化。 嵌入式/SoC:目前嵌入式/SoC的软件复杂度,对于 To C的产品依旧处于较低的水平,厂家更多还是在硬件层面下功夫。C/C++ 完全够用,Rust 会在更具有复杂度的地方,例如驱动、图形、底层框架等地方慢慢侵入进来。 游戏: 引擎层面,业界常规标准是用 C++ 实现。制作层面,国外的 Unity、Godot 可用C#,Unreal 是 C++,后面 Unreal 会提供 C# 支持。国内的 Cocos 用 Typescript。后面随着虚拟化VR的流行,N 年后, Apple、Google、微软以公司战略级别的重视程度下场搏杀的时候,估计会基于他们的已有编程语言,重新构建一套工具链。

从真实情况上讲: 一切最终还是要围绕着来做,外包团队的选型对于普通项目是一个很好的参考标准:他们的技术选型直接关系收入的多少。目前国内我了解到的是大家都在从 PHP 转向 Java,原因貌似是甲方公司相对于招聘 PHP 程序员,更期望招聘 Java 程序员。国外的则是 NodeJS Stack 用的人较多,一些远程招聘的要求大都是会NodeJS能独挡一面的全栈工程师(PS:区块链相关的远程工作机会相对较多)。

小结: 市场上招聘什么多,就用什么。

测试

从最基础的单元测试,到集成测试(API 接口测试、性能测试等),再到黑箱测试、安全测试,这些都是最有力的用代码保证代码的方案。每次代码提交后,都可以解决CI运行一遍测试,这相当于有一个一丝不苟、极度高效的人给你的项目做一次全量测试的价值,这个价值随着项目复杂度和人员流动性的增加越发凸出。 从实施上来讲:单元测试和集成测试要看项目复杂度和重要程度,对于 CURD 这种,主要走集成测试+接口测试即可,对于那种流程周转极长,边界case 极多、更接近基础设施,例如数据库等需要强制编写单元测试,要将单元测试覆盖率作为一个核心指标。 另外,集成测试和单元测试有个前提:代码可测。很多的早期代码编写不规范,导致后期追加测试时,需要重构甚至重写代码,成本倍增。所以,在项目开始的初期,就要补充一些无关痛痒的测试样例,通过 CI 倒逼程序员去产出可测试的代码。 从人员结构上来讲,增加测试人员,对于项目质量提升在早期阶段,是最容易见成效的做法,而单元测试编写需要公司花费大量精力构建相关制度,将其价值传递给程序员、项目进度管理者,见效慢,也容易引发项目不同工种协作矛盾,需要项目负责人做好充足准备。

安全防护

这是个经典的道高一尺魔高一丈的问题,需要砸大量的钱去做可能一次也没“起效”的事情,即使起效了,也无法做成漂亮 PPT,展示给不懂这一行当价值与成本的老板去看。 安全防护的实施要在公司上一定规模后,有一定财力,正好有“合规化”东风的时候去搞。因为安全防护是一件需要多部门“耐心配合”去完成的事情。它的价值往往根植在流程和他人“不方便”的基础之上。 一般公司开展相关工作方向对内是在较为完善的流程基础上做加法、缩权限、“设障碍”;对外是“花钱买平安”。相对于外部安全风险,这时的内部人员的商业安全风险会更大。 代码审计、代码仓库审计、数据库SQL审计、堡垒机、WAF防火墙、文件系统加密、磁盘加密、视频监控、深信服等等一系列工具都需要买起来、用起来。

等公司能养得起安全团队了,才能结合自身企业运转流程做定制化开发与安全运维。这时候才能去追求安全防护对正常员工“无感“。

开会

开会是一个传达并同步上级意志的群体活动。需要有规章、有主持。在开会之前解决问题,开会之中发现问题,开会之后解决矛盾。 代码开发的会议有很多类型,这里简述一下:

  1. 晨会,大家早上站在一起,快速同步下各自进度,时间在15分钟内。往往一段时间后,只有个别人发言,流于表面。这对于不善沟通的团队和迭代频率较高的项目较为有效。
  2. 周会,同步信息的周期变为一周。这对于中高层或各自负责工作关联度不高的团队较为有效。
  3. 项目评审会,各自部门员工针对需求,提出实现难点、工期预估等。但这个会议的实质应该是项目负责人同步项目ToDoList,指望底层员工在这么短的会议时间内提出有建设性的建议或意见不现实。
  4. 项目复盘会,复盘这一阶段内项目中遇到的问题,以及有无更好的解决方案。我目前还没怎么开过复盘会,所以无法置评。

小结

上述只是简单综述了一下软件开发的工程化,不涉及硬件。具体项目实施,还要再考虑多重因素。

timzaak commented 1 year ago

63

timzaak commented 3 months ago

测试

测试注意事项:

  1. 测试乱序、并发执行(文件系统需要mock)
  2. 测试共用相同的进程(需要注意不要使用环境变量)
  3. 调用第三方时存在失败情况(做好异常处理,不要崩溃)
  4. 集成测试入口要提供参数,最好是 配置(文件路径)、日志等DEBUG相关,都需要测试时注入。
timzaak commented 2 months ago

项目经理

项目经理要站在统筹的位置上,疯狂 PUSH 进度,拉着主权人员要资源。