0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

软件的研发属于工程还是设计

Linux阅码场 来源:Linux阅码场 作者:Linux阅码场 2022-09-26 09:13 次阅读

这是Google软件工程系列[1]的最后一篇,这篇主要是分享软件工程中常用的工具,这些工具支撑了软件工程中的流程。但在开始之前,我们先思考一个问题:软件的研发到底是工程还是设计?

软件工程还是软件设计

传统工程的流程比如土木工程是设计师先设计好图纸,然后工程队按照设计图纸去施工建造,所以这里的工程既包含设计又包含建造,但负责设计的人员明显与建造的人员不是同一类人,甚至有着非常大的差异。

那软件的生产流程是什么呢?以敏捷开发流程为例,组建一个软件开发队伍,先进行Inception确定好开发的需求及范围,之后根据需求拆分故事卡,开发人员根据故事卡实现产品需求。在实现故事卡的过程中,开发人员每天会写一部分代码并在本地做自测,之后会对代码做Code Diff[2],在这个过程中又可能重新修改设计与实现。不断重复这个过程,直到最终这部分代码进入集成环境被测试人员验收,最终会上线到生产环境。那么这个过程中既包含了设计又包含了实现(或者说建造),或者说这实际上是个不断设计的过程。

以下两篇文章推荐阅读,可能会让你对这个问题有更好的理解:

•Are We Really Engineers?[3]•What Is Software Design?[4]

Google软件工程中的工具

以下是《Software Engineering at Google》一书第四部分工具篇的思维导图,由于此部分占全书近40%,所以本文不会详细地介绍其中的概念,想详细了解的读者建议阅读原书。本文会结合此书这部分内容分享作者的个人理解及相关经验。

70b0b078-3d2f-11ed-9e49-dac502259ad0.jpg

版本控制(Version control)

在众多软件工程所用的工具中,最重要的我觉得就是版本控制系统了(Version Control System)。版本控制系统从字面意思就可以看出来是控制源代码的版本的,VCS就像时间宝石一样让开发人员在源代码历史中穿梭,为什么这种能力很重要?

其实这和本文开头那个问题相关,如果说软件开发是一个设计的过程,那这个设计可能需要不断修改,能最低成本地在不同版本间切换非常重要,更重要的是这种能力可以让多人协作完成软件的设计与开发。

Development is inherently a branch-and-merge process, both when coordinating between multiple developers or a single developer at different points in time. (Software Engineering at Google)

版本控制也让软件开发过程中产生了Code Diff或Code Review的过程进而促进团队知识共享,而这又是软件工程中文化的一部分。版本控制也影响了软件的部署过程,比如结合Pipeline与Artifact Repository,可以构建出不同环境不同版本的软件制品。

CVCS vs DVCS

早期的版本控制系统是集中式(CVCS)的,比如Subversion,现在更流行的是分布式的(DVCS),比如Git。这两者的区别可以看这篇文章:

•GitSvnComparison[5]

CVCS与DVCS仅仅是适用的场景不同,并不意味着后者是前者更好的替代。比如很多大的公司或组织,如Google、Microsoft与FreeBSD都在用CVCS。一般来说大的公司更偏向于用CVCS,与CVCS密切相关的就是单一代码仓(Monorepo)了。

分布式版本控制系统如Git,其实是没有中央存储库的。我们在GitHub克隆某个仓库到本地,其中的origin其实是刻意约定设置成中央仓库的,但我们可以在本地仓库中添加多个远端中央仓库,也可以rebase多个远端仓库的代码到本地仓库。

单一代码仓(Monorepo)

Monorepo简单理解就是把整个组织的所有项目的代码都放入一个仓库中。初看不可思议,但Monorepo并不仅仅是把代码放一块就行了,它需要一整套的流程与工具链支撑,比如不同团队协作模式、代码库之间的依赖管理、目录的权限配置、构建与发布等。

与以Git为主的Polyrepo(一个项目一个代码存储库)存储库模型相比,Monorepo有如下的好处:

•代码共享:所有人都可以看到其他人的代码,能降低重复代码;•统一依赖:不会出现多个项目依赖相同三方包的不同版本导致的冲突问题;•跨项目修改简单:大规模跨项目的重构更简单了,能一次修改多个项目的代码;•共享构建发布流程:能共享同一套构建发布流程,简化基础设施的复杂性;

Developers within an organization must not have a choice where to commit, or which version of an existing component to depend upon. (Software Engineering at Google)

进一步了解,强烈推荐阅读这篇文档:

•Monorepo Explained[6]

分支管理(Branch management)

版本控制系统不仅可以让开发人员具备时间穿梭的能力,还具备开辟多重宇宙的能力,这就是分支(Branch)的功能。分支不仅仅是代码的不同版本,它还深刻的影响了开发部署的流程。

早期流行复杂的Git Flow[7]分支模型,但这种模型带来了很复杂的维护成本,包括分支的管理、冲突的解决等问题。最终逐渐演变出更简单的主干分支开发(Truck Based Development[8])模型。

主干开发分支在实践中可能存在的问题是,主干分支与流水线(Pipeline)的集成,一般会有不同环境,如CI、INT、UAT、PROD等。当开发人员要在集成环境测试时,如果有紧急的Hotfix代码要推送到生产环境,这时候主干分支中还包含着集成环境的开发代码,就算有特性开关(feature toggle)的支持,也不敢直接把这些代码推入到生产环境。此时能做到就是回滚(git revert)这部分代码回去。这个问题本质还是因为测试环境有限,无法做到一个代码变更部署到一个临时创建的测试环境中,这时候主干开发分支可能需要做一定的调整,比如用Release分支来发布,主干分支做开发代码的Single Source of Truth。

不同分支模型的介绍,推荐这篇文章:

•Git(Hub) Flow, Trunk Based Development, and Code reviews[9]

代码搜索、构建与静态分析(Code search && Build system && Static analysis)

代码搜索可以用最简单的grep -r命令或者IDE的搜索功能来实现,但要在多个代码仓库间高效地对某些代码进行跨仓库搜索,那这些工具可能很难满足需求。

Google自研了一套代码搜索的工具,这个代码搜索工具甚至可以和其他系统如日志查看系统集成。

Sourcegraph[10]是一个开源免费的代码搜索云服务,可以与GitHub集成,提供良好的代码阅读体验。

Google同样实现了自己的基于制品的构建工具Bazel[11],Bazel也是支持Monorepo很好的构建工具,同样的还有Nx[12]与Gradle[13]。

代码静态分析就像自动化的Code Review一样,能帮助发现代码中的质量与安全问题,减少不必要的Review时间,提升代码质量。流行的代码静态分析工具中,SonarQube[14]是推荐的。

依赖管理(Dependency management)

依赖管理可能是软件工程中最复杂的问题之一(短期编程代码无需考虑此问题)。现代软件是建立在大量的依赖库或框架之上的,这些外部代码很多并不受开发人员的控制,当软件变得越来越庞大时,大量的依赖可能会形成复杂的依赖树(如在Gradle项目中,gradle dependencies命令可以打印出应用的依赖树)。

依赖问题最多的可能是钻石依赖问题,简单说就是同一个包的不同版本共存的问题,这在某些编程语言如Java中影响并不大,因为多个版本可以共存,除非在某些特殊的场景下,不同的包可能会造成一些很诡异的Bug。

在Black Duck[15]中又把依赖的问题分为三大类:

•许可证(License Risk):商业应用对依赖包的License有限制,比如无法使用GPL类的License。•安全(Security Risk):依赖包经常会被爆出重大的安全CVE[16]问题,有时候因兼容性的问题很难去通过版本升级来修复。•运营(Operational Risk):一些小众的编程语言如Clojure的很多包,经常无人维护或者缺乏更新,导致存在潜在的运营风险。

另外一个主要的问题就是兼容性的问题,比如API出现破坏性的更新,或者ABI无法兼容。

编程语言ABI(Application binary interface)兼容性:与API(Application programming interface)类似,是描述二进制文件的兼容性。比如Java有ABI兼容性的保证,意味着基于新版本JDK的代码可以安全地调用老版本JDK的Jar包。

在解决API变化导致的依赖问题上,业界一个流行的方案是语义化版本:SemVer[17]。通过将版本拆分为三部分,如x.y.z,x是破坏性更新版本号,y是特性版本号,z是Bug修复的版本号。我们可以在依赖配置文件如package.json中通过^或~符号来指定依赖的最大版本号范围。

依赖管理的问题也可能和代码设计有关。比如应用对某个外部服务有依赖,如何降低外部API变化对应用代码的影响?这个问题可以从设计模式的角度去解决,比如创建一个适配层(如Gateway[18]模式),通过定义一个抽象的接口层去实现,而非依赖具体的外部API去实现。

持续集成与持续交付(Continuous Integration && Continuous Delivery)

CI是一种团队开发软件的实践,在代码变更集成到主代码分支前尽早的捕捉变更带来的问题,流程主要有自动化的测试[19]与构建,CI工具可以帮助开发人员快速获得代码变更是否正确的反馈。

常用的CI工具有:GitHub Actions[20],GoCD[21]与Jekins[22]。这些工具也称为流水线(Pipeline),不仅支持UI的操作,还支持Pipeline as Code[23]。

实际的CI工具一般受制于服务器资源的限制,很难做到一个代码变更(Code Commit)自动部署一个测试验证环境(这也被称为无限环境CI[24])。目前只有少数的云服务可以支持前端项目的无限环境CI,比如Cloudflare Pages[25],Vercel[26]与Netlify[27]等。

CD发生在代码集成后,包括从代码集成后到发布变更的软件给用户的过程,良好的CD实践既可以快速进行价值交付,又可以快速获得用户反馈。持续交付的原则和敏捷的方法论[28]有一些重合的部分:

•敏捷:小而频繁地发布过程,快速获取反馈。•自动化:通过自动化的手段降低发布的时间成本。•隔离:采用模块化的架构设计使需求变更和故障排除更简单。•可靠:通过技术监控提高系统的可靠性。•数据驱动:使用埋点或A/B测试获取用户反馈的数据,通过数据做决策。•分步发布:产品特性先灰度发布,确保无误后再全量推送给用户。

写在最后

软件工程或者说软件设计是个复杂的活动,其中既涉及文化相关的东西,又有很复杂的流程及一系列的工具集。

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储
    +关注

    关注

    13

    文章

    4213

    浏览量

    85554
  • 软件
    +关注

    关注

    69

    文章

    4684

    浏览量

    87066
  • 代码
    +关注

    关注

    30

    文章

    4717

    浏览量

    68196

原文标题:Google软件工程之工具篇

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    MSP430F5438A的内部看门狗属于硬件狗,还是软件狗?

    请教各位大侠,MSP430F5438A的内部看门狗属于硬件狗,还是软件狗?
    发表于 11-21 17:51

    天津诚聘DSP研发工程

    本帖最后由 mr.pengyongche 于 2013-4-30 03:24 编辑 急求助:诚聘英才:硬件研发工程师(同时会软件者更佳)想在天津长期发展计算机或通信专业大本毕业精通DSP的男士,请联系我
    发表于 03-13 15:46

    硬件工程还是软件工程师的

    我从机械电子转向电子工程师,转硬件工程师有前途还是软件工程师了
    发表于 03-22 16:42

    长城汽车招聘汽车电控研发工程

    工作内容:GDI ECU以及汽车车电子控制单元研发(基础软件编程,应用软件simulink模型编程,硬件电路设计,系统设计,测试,iso26262,CMMi,工具链服务器开发等方向)工作地点:保定
    发表于 04-17 23:04

    招聘研发工程

    研发工程师发布日期2014-12-10工作地点广东-深圳市学历要求大专工作经验1~3年招聘人数2待遇水平面议年龄要求性别要求不限有效期2015-02-17职位描述1.大专以上学历,光电或电子技术
    发表于 12-10 13:36

    招聘Labview 研发工程

    本公司做有源晶振,招聘Labview研发工程师,主要开发自动化生产测试软件,需要一定数据库知识。工作地点:成都高新区软件园待遇:6-8K有意向的可发邮件到:jin@xtaltq.com
    发表于 12-18 13:55

    招聘研发工程

    研发工程师发布日期2014-12-23工作地点广东-深圳市学历要求大专工作经验不限招聘人数2待遇水平面议年龄要求性别要求不限有效期2015-03-02职位描述负责新产品的开发、整改、特配资料等处理
    发表于 12-23 13:28

    诚聘软件研发工程

    本帖最后由 坤驰 于 2015-6-3 11:38 编辑 诚聘嵌入式软件和DSP软件研发经理。参与和协同领导多核多任务处理集群系统的研发,该平台由资深CPU设计专家带队实施。公司
    发表于 03-11 14:54

    资深软件研发工程师 (Connectivity)-合肥

    资深软件研发工程师 (Connectivity)-合肥职位描述:1、Android & Embedded Linux Connectivity系统软件开发、设计;2、参与系统
    发表于 11-20 13:53

    招聘 电子研发工程

    行业知名生产研发厂商招聘 电子研发工程师 要求:熟悉单片机,C语言、汇编语言,有3年以上电子技术研发经验或嵌入式工程师经验。年薪 12W-2
    发表于 07-22 16:48

    苏州倍安电子科技公司招募电子研发工程师-----社招

    ,带薪休假,弹性工作制!一.电子研发工程师:技能要求:1.精通各类嵌入式系统的电路原理和电子元器件选型2.精通电路板布线3.精通常见MCU的嵌入式软件编程4.精通蓝牙和无线等智能模块的使用5.有家电类
    发表于 02-08 10:43

    诚聘硬件研发工程

    猎头职位:硬件研发工程师【北京】职位描述:1、负责产品硬件的需求分析、原理图设计,PCB设计,调试和验证;2、编写产品设计文档、BOM、生产相关技术文档;3、制定硬件的测试方案,对硬件进行测试并编写
    发表于 08-01 11:30

    三相电属于交流还是直流

    请问三相电属于交流还是直流?
    发表于 09-23 16:18

    快来看看你是属于嵌入式软件工程师技术哪一个等级

    嵌入式软件工程师技术分为哪几个等级?快来看看你是属于嵌入式软件工程师技术哪一个等级?
    发表于 12-24 07:29

    fpga属于软件还是硬件

    fpga属于硬件,并不是软件,FPGA产业与人工智能、VR等许多热门应用密切相关,通过配置FPGA可以做不同的事情,可以对不同的算法进行编程,具有灵活、高性能功耗比等优势特征。
    发表于 10-01 09:06 9223次阅读