迷路在现代软件工程中的羔羊——略读邹欣老师《构建之法》及讲义有感(附上源代码管理软件以及CI/CD调研Demo)

迷路在现代软件工程中的羔羊——略读邹欣老师《构建之法》及讲义有感(附上源代码管理软件以及CI/CD调研Demo)

项目内容
这个作业属于哪个课程北京航空航天大学2022春季软件工程(罗杰 任健)
这个作业的要求在哪里个人阅读作业
我在这个课程的目标是学习软工的项目合作管理知识,通过高效的团队合作,建立完整敏捷开发流程,实现一个中大型软件工程项目。
这个作业在哪个具体方面帮助我实现目标通过《构建之法》的阅读来认识软件工程定义,了解软工架构当中从技术到团队管理的全域流程,调研基本Git操作方法,掌握使用常见的CI/CD工具协助开发
本次博客内容
快速阅读《如何提问》以及《提问的艺术》等文章
泛读邹欣老师《构建之法》以及讲义并自主思考,将疑惑与思考在本文中提出
源代码版本管理软件调研
持续集成/部署工具调研

1、初窥软件工程

​ 很开心也很期待即将正式打开软件工程的大门,作为和大家一样的一个秃头的CS大学生,曾经在之前的课堂中写过类似爬虫比价平台、学生社区等项目,也有幸在2021年以实习的身份参与了甘伟冲学长or老板(清华大学2019届软件工程博士)的创业项目writebug社区,担任小小的研发员工,似乎做过一些和SE沾边的小小实践,但是我始终没有正真的理解过“软件工程”这一科学的内涵,也只是在其中的某一个小小的技术方面做一些微不足道的事情。很荣幸能够有机会在北航本科最后的时光中和罗杰老师、任健老师以及助教学长们结缘,感谢老师们正式带领我们这些迷路的羔羊看见“软件工程”这座宏伟的大厦。

​ 何为“软件工程”呢,在wiki百科的解释是:将科学和技术知识、方法和经验系统地应用于软件的设计、实施、测试和文档编制的工程;在邹欣老师的《构建之法-现代软件工程第3版》中的第1.2章也更加细致综合的解释了软件工程是什么,同时在查阅了一些博客以及网络资料之后才发现最初的理解是多么的浅薄,我看到的只不过是冰山一角,它更多的魅力和秘密就从今天开始让我们慢慢解开。

在这里插入图片描述

​ 图1:writebug项目致谢名单

2、思考与提问的本质

​ 我对软件工程的理解将从邹欣老师的《构建之法》以及博客讲义开始,在这之前我们首先需要知道如何在学习和阅读中思考和提问。不论是思考行为还是提问行为我们都需要有一个目的作为驱动,在《如何提问》中有一句话“我认为每个人都应该只字不差地反复阅读这篇文章,直至对其中的基本原则了然于心,乃至于能把这些原则应用在任何领域才对”,这一点我很赞同,思考和提问不仅仅是为了让我们明白某一个问题的原理,对于技术人和科研人来说我们上述行为的本质就是为了转化为另一个行为,这个行为是将原则应用实践,解决我们当下遇到的实际问题。如果不清楚我们思考和提问的目的,那么这种行为显然是没有意义的。

​ 那么应该如何提问和思考呢,两篇文章中给了我们很多具有条例和逻辑方法,思考时更重要的衡量问题的意义和方案,并在拓展的深度和广度上进行探索,而提问需要在原始问题描述清楚的情况下以合适的语态解释清楚自己的疑问。看完两篇文章后我想起来在2022开年参加“一生一芯”项目之时,官方借用南京大学操作系统中的一个章节告诉我们应该如何思考和提问,文中提出了三种办法来解决我们的问题:STFW(Search The F##king Web)、RTFM(Read The F##king Manual)以及RTFSC(Read The F##king Source Code)这三种带有F的方法听非常冒犯,但却不得不说对于现代人来说这毫无疑问是最高效且广泛的。其中非常有意思的是,RTFSC起源于Linux之父Linus Torvalds在1991年4月1日回复邮件中的第一句话, 目前在网上还能搜到当时的邮件列表

3、一些问题

问题一:关于“足够好”的软件,定义是否缺少维度?

参见《构建之法——现代软件工程》第1章第2节

在这里插入图片描述

在这里插入图片描述

​ 在这里对于“足够好”的定义主要为Bug尽可能的少。邹老师对bug的定义很宽泛,并不是我们狭义上理解的“虫子”,是从用户使用、开发者角度来体现bug的内涵,这点很有趣。但是似乎只在研发阶段的投入成本、使用阶段的用户体验和使用流畅性进行判断。我认为这样来定义“足够好”只具备二重维度,那就是“之前”和“现在”,关于一个好的软件工程应该更需要第三维度——“未来”?这里的“未来”也是基于用户,但不是“现在的”或者“即将的”用户,而是未来长期间隔后的用户。那么“未来”的定义会偏向于:产品基于社会经济发展以及技术趋势而产生的潜在可能,换而言之就是潜在趋势(价值)。

​ 人类往往喜欢站在历史的角度看问题,产品的评价更大程度上取决于未来的人。当然我们没有“穿越机”去看看产品是否符合未来10~20年的发展趋势,但是预测和前瞻性就显得极为重要了。比如最初的QQ,用户的评分低到了极点,没有人认为其比得过当时的飞信,但是站在历史来看似乎并非如此

问题二:为什么软件工程师个人能力的衡量中重复性工作更重要?

参见《构建之法——现代软件工程》第3章第1节

软件项目的确需要创造性,需要一些意外,一些惊喜。但是,更多的是常规的、可重复性的任务,软件工程的奠基人之一瓦茨·汉弗雷总结说,软件领域可以分为两个方面:一方面是记忆创新的大爆发;而另一方面是坚持不懈的工程工作,包括软件的改善、维护和测试等,这一方面占了90%-95%的比例。

​ 对于我们这些小白大学生来说,如何进行“打怪升级”显得格外重要,我们需要不断地对个人能力进行评估来确定未来的进步方向。在看到文中长篇对于工程师个人能力分析中,使用了搬砖的例子来说明,就是要般的多,般的快。我最初认为我们需要实践和学习来掌握理论知识、高质量的进行软件工程中的开发、测试、维护等工作,也就是提升所谓的效率和质量。这样来看也符合文中对能力评估的指标,通过和一些从事软件开发的师兄师姐对话我也发现,确实在他们的工作内容中重复性工作占了大部分时间。这一点似乎构成了软件工程师工作中的大部分,但是为什么因为重复性工作时间占比大,能给团队以及企业带来较高的绩效就成为软件工程师个人能力量化评估的关键呢?

​ 虽然软件工程师对于“灵光乍现”的好点子需求并不高,但是我认为这是弥足珍贵的。软件工程师并不是机器,如果企业和团队把每一位软件工程师当作仅仅可以高效、高质量完成任务的机器人来使用,似乎缺少了一点人性化,谁做的快、谁把PM的新需求完成的好谁就优秀(个人觉得有点压榨,且失去乐趣)。当然高质量和高效率的工作是一个优秀软件工程师的基础,我认为更重要的是基于“基本功”的创造能力,我心中的优秀软件工程师是满足质量和效率之后,具有跳脱框架束缚能力,能够创造更加深远价值的技术人员(这里的价值包括个人价值、团队价值、企业价值、社会价值等),毕竟很少有影响深远的项目不是创建之初就让人耳目一新的。

问题三:组建敏捷团队的难度

参见《构建之法——现代软件工程》第6章第1、2、3、4节

在这里插入图片描述

​ 还记得第一节课上罗老师就为我们阐释了我们本学期的主题,那就是敏捷开发,初次接触软件工程高楼的我充满了好奇什么是敏捷开发?记得去年七月份与我的队友家乐(现在的软工中还是我的队友)开发比价平台的时候就讨论过,我们的两人团队应该怎么组织,当时查阅了解了敏捷开发以及瀑布开发这两种方式,我们也进行了简单的交流,但是却没有理解其中的内涵。

​ 在《构建之法》当中邹欣老师花费大量的文字为我们揭揭示了敏捷开发的奥秘,流程图的讲解和例会制度也非常的有趣,我觉得能在项目周期中起到很好的定期总结以及规划作用,但是我发现邹老师的描述中对团队成员的要求很高很高,不论是团队开发周期中的流程还是个人在团队开发中的要求都很高,要求每一位成员必须对敏捷流程的每一步做到极致,包括复杂关系分析能力、技术交流沟通能力、例会汇报及规划能力、软件测试能力、总结能力等等。团队中每个人的能力要求都极高,从开发到PM都很高,且我个人认为,看起来感觉敏捷开发更适合一个小而精的团队,就是成员都很强而且团队数量不大。我个人会产生一些疑问,如果在大型的项目当中需要组织一个大型的团队,而团队成员能力又参差不齐,我们又该如何选择团队开发组织方式呢?又比如在我们一个小的软工团队当中,大家或许在上述举例的敏捷开发能力需求中只占了一部分又该如何组织呢?

问题四:如何获取需求分析数据

参见《构建之法——现代软件工程》第8章第1、2、3节

在这里插入图片描述

​ 在未来不久即将开启的团队合作中我们要进行的第一步就是调研题目并分析需求,然后再设计功能,我们既充满期待由有一些担忧,如果没有开好头或许进展的内容会更加艰难。

​ 在书中老师为我们提供了许多经过广泛验证使用的需求分析方法:

  1. 焦点小组
  2. 深入面谈
  3. 卡片分类
  4. 用户调查问卷
  5. 用户日志研究
  6. 人类学调查
  7. 眼动跟踪研究
  8. 快速原型调研
  9. A/B测试

这九种方法都是已经且正在被许多团队使用的方法,也使得我们眼前一亮,但是在我们即将进行的软件工程项目中我们该如何选择这些方法呢,是应该依赖于具体的产品内容、时间成本、人力成本等因素选择一种适合团队的调研方法还是应该组合选择呢?还有一个小小的问题就是因为在团队中我们会有分工不论是PM、开发者、还是测试都有自己明确的任务,但是在企业和实践中,这种需求分析调研的任务应当由谁来完成呢?是团队中的某一个角色还是企业中会有专门的团队来进行这项任务?

问题五:PM的管理范围中是否有团队任务分配

参见《构建之法——现代软件工程》第9章第1、2、3、4节

在这里插入图片描述

​ 我经常在Bilibili上看到一些关于PM的搞笑视频,网络中总喜欢把PM喜剧化成一个充满压迫的反派角色,说起来也挺有趣。

​ 《构建之法》中专门用了一个章节来介绍这一角色,而没有介绍常见的研发、测试等人员也充分说明了PM在团队中的重要性,在我的理解中PM应该成为团队执行力的核心。同时也是最累的,因为在我们这种校园团队当中PM往往还需要担任开发的角色,就是说PM不仅需要硬核的专业能力,也需要强大的领导力,还需要有规划和敏锐的市场能力。文中讲了很多如何做好一个PM,但是有一点似乎并没有提及,那就是团队的任务分配由谁来做?是PM吗?如果是的话,PM又怎么能做到在任务量和奖励机制的平衡上做到让大家心服口服,而且能充分发挥每个人的优势呢?

问题六:微软的Program Manager和大部分的Project Manager有什么区别

参见《构建之法——现代软件工程》第9章第1节

​ 文中分别讲解了三专用不同的PM定义,但是似乎我并没有发现他们之间的本质区别,反而觉得工作内容有很大的重叠,似乎只是换了种说法,并没有看出本质的区别。

问题七:对创新的重要性定位

参见《构建之法——现代软件工程》第16章第1节,第17章

很多心理学家通过各种试验和分析告诉我们,纯粹强调外界的驱动因素(金钱的报酬或惩罚)仅仅对体力劳动或有明确规则的活动有效(奖金越多,结果越好),但对于需要创造性思维的活动,即使是简单的认知能力的活动,更多奖金反而起到相反的效果。

在这里插入图片描述

​ 在文章的偏后章节有很多部分都提出了一个问题,就是创新的定位,文中提出创新和创造性思维的激发与金钱成反比,我充满了疑惑,尽管在wiki和百度上的许多心理研究结果都表明这一点是成立的,但是我似乎认为这不应该成为将创新地位放在更下层位置的原因。创新的激励或许不需要天价奖金来支持,但是如果类比问题二中的重复性工作来说创新的基础保障低的可怜,那么还有谁会创新呢?软件工程师岂不真成了完成PM需求清单的机器人?

​ 另外在文中的16.1.2提到了一个电报的例子,来展示颠覆性创新为何不受欢迎,作者似乎更支持的是改进式的创新,是否这种例子以及看法倾向于一个站在管理者和对软件工程师发号施令者的角度呢?我个人认为这种想法仅有助于培养一个符合公司和leader管理的软件工程师,而不是真正有见解有想法的软件工程师。

以上问题仅是我个人在粗略阅读《构建之法》时产生的小小疑问,可能有片面和阅读不充分的错误,希望老师和助教多多包涵。

4、源代码版本管理软件

Git的前生今世:

​ 很多技术人员都在使用Git但是我想很少人知道它的来历,只把它当作得力的工具。实际上Git是由Linux之父Linus创造的,在 2005 年,Linus Torvalds 迫切需要一个新的版本控制系统来维护 Linux 内核的开发。于是他花了一个星期的时间,从头开始编写了一个革命性的新系统,并将其命名为 Git。十五年之后,该平台成为了这个竞争激烈领域里面当之无愧的领导者。

​ 不论大到微软、谷歌,还是小型初创企业都会使用Git来维护它们的项目代码。其中有些公司拥有自己的Git项目,有些公司则使用一些商业托管公司来使用,例如GitHub、GitLab等。Git有时被分类为版本控制系统(VCS),有时是源码管理系统(SCM),还有时是修订控制系统(RCS)。Torvalds 认为“生命太短暂而不必去区分这些定义,因此我们不必纠结于此”。Git最大的吸引力就是开源,不论是版本控制还是分支管理等功能都是造福了广大技术人员,提高了团队开发效率。

代码版本管理软件对比:
名称使用优点缺点使用人数
Git原始命令行,裸板开发工具轻量、可与其他控制软件结合、可离线使用纯命令行使用难度较高、控制功能要求较高许多
GitHub在线代码托管工具,面向全部互联网,企业版需要收费issue的特点明确、平台规模大、个人评估体系完全、成为主流国内访问速度慢,经常连接失败、对文档的优化不够,完全依赖开发人员、企业收费过高4000多万注册者
Gitee中国专用,使用更加简便,面向企业完全免费速度快、免费、API文档自动生成、与中国软件对接、适合敏捷开发管理用户下载发行文件不便、容量限制太小、多余的绑定机制非常“China”500多万注册者
GitLab类似 GitHub,一般用于在企业内搭建git私服,要自己搭环境。集成CI/CD功能强、对私人库完全免费账号验证麻烦、拓展功能收费未知
Bitbucket免费无限制5人私有仓库小团队使用不限容量、具有集成Jira工具、权限控制灵活代码量和使用群体较少、系统稳定性不够500多万注册者

上述软件我只使用过GitHub、Gitlab和Gitee,个人认为在小团队软件开发中Gitee更为友好。

5、持续集成/部署工具

测试一:Java项目的运行(Java with Ant)

在这里插入图片描述
在这里插入图片描述

​ 这里我采用了新建一个简单的java项目主要是输出一些文字,其中构建出新的workflow,在这里我使用的是Java with Ant也就是所谓的Ant来进行持续集成。

# This workflow will build a Java project with Ant
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-ant

name: Java CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'temurin'
    - name: Build with Ant
      run: ant -noinput -buildfile build.xml

​ 这里给出了ant.yml的代码块,这里使用集成了jdk11来编译我们的简单java项目。根据GitHub Docs的官方文档解释,这里的yml文件主要有三个作用:

​ 复制我们的仓库开始重新运行

​ 添加Java 11 的JDK工具

​ 开始运行我们自己构建的build.xml

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>

<project name="AntTestDemo" default="run" basedir=".">

<property name="src" value="src"/>

<property name="dest" value="classes"/>

<property name="helloant_jar" value="helloant.jar"/>

<target name="init">

   <mkdir dir="${dest}"/>

</target>

<target name="compile" depends="init">

   <javac srcdir="${src}" destdir="${dest}"/>

</target>

<target name="build" depends="compile">

   <jar jarfile="${helloant_jar}" basedir="${dest}"/>

</target>

<target name="run" depends="build">

   <java classname="com.zdz.ant.test.HelloAnt" classpath="${helloant_jar}"/>

</target>

<target name="clean">

   <delete dir="${dest}" />

   <delete file="${helloant_jar}" />

</target>

<target name="rerun" depends="clean,run">

   <ant target="clean" />

   <ant target="run" />

</target>

</project>

​ 由于build.xml需要自己构建,这里也给出了我的构建代码

在这里插入图片描述

然后可以看到我们的集成编译流程已经成功

在这里插入图片描述

最后可以看到我们的编译结果,输出了我们在java文件中打印的"Hello SE! This is AaronHuang!"这段话

我最后将仓库重新更名为:Aaronhuang-778/**GitHub-Action-test1**大家可以克隆到自己的仓库中进行测试哦!

测试二:Vue项目的搭建和部署(自定义workflow)

在这里插入图片描述

​ 这里我们测试部署前后端分离的项目,在这里我们使用vue进行测试。

name: GOGO
on:
  push:
    branches:
      - master
jobs:
  main:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v2
      with:
        persist-credentials: false

    - name: Install and Build
      run: |
        npm install
        npm run build
    - name: Deploy
      uses: JamesIves/github-pages-deploy-action@releases/v3
      with:
        ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
        BRANCH: gh-pages
        FOLDER: dist

    - name: Run On Push
      run: |
        echo "Run On Push"

​ 这里我们需要编写自己的yml文件

在这里插入图片描述

上图为构建进行中

在这里插入图片描述

最后构建完成,给出项目链接:Aaronhuang-778/test1

CI/CD工具对比:
工具名称特点推荐
Jenkins在实践方面,Jenkins让团队中的任何成员都能够将他们的代码推送到构建中,并立即获得有关它是否已准备好生成的反馈。在大多数情况下,这需要根据您团队的自定义要求对Jenkins进行一些修补和定制。Jenkins闪耀的地方是其丰富的插件生态系统。Jenkins是免费的CI解决方案,可以定制的环境并需要用户社区的支持
GitLab CI/CD每个构建的可以分为多个作业,并且可以在多台机器上并行运行。该工具可以立即反馈构建的成功或失败,让用户知道出现了什么问题或者过程中是否存在问题。可以与gitlab完美匹配且具有独特的pipline功能和runner配置
GitHub Actions首要优势是设置简便性。GitHub Actions在云端运行,你也可以选择在本地运行,这就是所谓的运行器。可以通过GitHub Marketplace相互分享。可以重用其他开发者编写的Action。实现了异步CI/CD。设置简便,几乎不需要多余的配置,只需要新建自己的workflow或者直接使用推荐配置
Travis CI开发人员可以使用Travis CI在运行时观察测试,并行运行多个测试,并将该工具与Slack,HipChat,Email等集成,以获得问题或不成功构建的通知。Travis CI支持容器构建,并支持Linux Ubuntu和OSX。如果代码是开源的,并且更关注构建的持续集成。
Circle CI每个代码更改都会根据您的初始配置和首选项创建构建并在干净容器或VM中运行测试。有问题的构建和测试的成功或失败状态通过Slack,HipChat,IRC或许多其他集成发送,因此团队可以保持更新。GitHub友好工具,它背后有一个广泛的社区,它也可以在私有云或你自己的数据中心内运行
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值