BUAA 软工 Week_1 个人阅读作业-阅读和调研

软工第一周个人作业

项目 内容
这个作业属于哪个课程 北京航空航天大学2022春季软件工程(罗杰 任健)
这个作业的要求在哪里 个人阅读作业
我在这个课程的目标是 见下“想要通过这门课做到”
这个作业在哪个具体方面帮助我实现目标 帮助我捋清了自己当下的问题,以及系统介绍了本课程我即将学习的内容,还有其他软件开发的知识和经验

读完后感触最大的三点:

  • PSP:通过这章我深感自己的编程能力是存在系统性的基础上的漏洞的,自己代码的质量以及代码测试方式都会给未来的项目以及自己的工作带来困扰。
  • 关于猪和鸡的讨论:自己参与活动的心态和我能够投入的能量,以及我参与项目的数量的反思,似乎很多时候不够对等,我确定自己不是鹦鹉,只是一个"操着猪的心却只能够下蛋的鸡"。
  • “技能的反面”:尤其是新手老手的计划书的对比,现阶段我们总是忽略了低级基础技能的缺陷一目了然,一个实际存在的问题就是,有许多同学很喜欢架空的描述某个过程,导致对于询问的人来说总是一头雾水。而我自己在制定某些计划的时候,几乎也和作者在书中特地拿来做对比的同学的凭空的计划相似,但真正懂得的、上手的人总是能给出实打实的规划。

我现在的问题:

  1. 无法系统的对自己的代码进行检测,评估,优化,无从下手。
  2. 很多时候编程仅仅只用到简单的基础用法,并没有探索更深层的技巧或者用意。
  3. debug和设计编写很naive ,缺乏认真思索和考虑,手段也很简单,甚至不爱单行debug,仍然靠手撸数据,输出中间过程检测。
  4. 学习新的工具、语言的时候,根据自己的需要去随意的百度,或者凭感觉去上手,很多时候在不会的情况下,遇到了很多bug,并且经常无效debug,不知道原因,更不知道解决办法。
  5. 团队合作中,常扮演PM或者QA的角色,由于无法学会或钻研新的算法,直接导致我缺乏Dev的经历,对于队友的代码和算法缺乏理解,而且经常在配置环境等无关问题上花费大量时间(绩效低)。

想要通过这门课做到:

​ 改变自己上述中的编程和合作模式缺陷,学会系统的软件开发的模式,学习团队合作技巧和方法,争取让自己有实际的能力和本事做“猪”。

​ 在实际实践中体会书中一些或许本就没有标准答案或者定论的问题:QA如何在开发初期就对一些测试问题进行处理?有的游戏很多bug但是美名其曰为内测版,测试版,这个不好的体验感该由用户来承担吗?NABCD:如何去定义一个说不清道不明的需求?在提出新的点子之前,如果仅仅是一个很模糊的概念,该如何去描述定位?

一、阅读提问

1.该做单元测试的人?

第二章个人开发单元测试中提及,单元测试必须由最熟悉代码的人(程序的作者)来写。代码的作者最了解代码的目的、特点和实现的局限性。所以,写单元测试没有比作者更适合的人选了。

我不是很能够理解这样的观点。确保代码的正确性,测试代码确实是代码作者的责任,但是由于程序员自身对于需求理解得不够或者在程序基础知识上面存在局限性,对于作者而言,作者往往是不了解实现的局限性的人,因为他只知道如何实现了他的圈内的东西,而不知道圈外是怎样的。当测试时,他的单元测试又是在最低的参数上验证程序的正确性--根据书中单元测试好坏的标准,所以会出现遗漏,这样的情况可以由专门的QA进行测试吗?此外,当作者自己进行单元测试的时候,即使他写的代码很复杂,对他而言没有一个比较的对象,即他在写下这段代码的时候已经适应了这样的写法以及复杂度,他可能没有机会意识到这是一个会让别人抓狂的代码。在这种假设下,可不可以用互相hack,互相进行单元测试,这样可以促进对于优秀代码的学习,或者以一个更完善的机制进行单元检验。

2.结对编程中的平等权利如何争取?

关于第三章两人合作中,该如何看待结对编程中所谓的只有水平上的差距没有级别上的差距,在分析、设计或编码上双方都拥有平等的决策权利。

其实团队中,总是有一个贡献度最大的,或者“最有话语权的”,比如经验更加充足,实力更加强大。即使是两人结对编程也会出现这样的情况,如果两个人实力相当,则结对编程更多倾向于复查能够提高准确度,但是如果实力有差距,更多时候无法说明两个人可以处于一个平等的分析设计编码的状态。一个人在与另一个能力较高的人合作时,应该本着学习的态度或不停的被说服去按照对方的想法去做还是应该按照自己所理解的,哪怕方案具有局限性但是保留自己的做法?

3.敏捷开发类比爵士乐?

第五章中提到敏捷开发具有像爵士乐一样“不靠谱”的特点,强调个性化表达,对变化的内容有创意的回应。在后文各类开发方式的对比中更是体现了敏捷开发相对于其他方式的“不靠谱”程度。此外对于爵士乐即兴的特点,应该如何类比到软件开发中呢?

是否可以理解为,敏捷开发是由于目前移动设备或者网络等发展迅速,为了适应不同的人、变化的需求所需要的软件开发方法,但是因为其安全性可靠性不够所以对于一个要求高质量的工程是完全不能用的。如何去衡量一个软件所需的可靠程度呢?而且即使是一个要求很高的工程,也不该是哪里都在严谨复杂的质检验证,应该有所侧重,可能也会有需要快速得到一个效果或者功能的时候,并且敏捷开发也是不断迭代的过程,不断的完善任务,适应新的条件需求或者测试需求。前文提到软件开发的过程中,需要对需求分析,写设计文档,讨论规范等步骤,敏捷中没有设计文档,下文提到其代替其他软件开发中的设计文档的是“可用的软件”,因此它究竟是怎么根据“可用的软件”进行任务规划分配设计的,像爵士一样即兴发挥具体是指?

客观因素\最适用方式 敏捷 (Agile) 计划驱动 (Plan-driven) 形式化的开发方法 (Formal Method)
产品可靠性要求 不高, 容忍经常出错 必须有较高可靠性 有极高的可靠性和质量要求
需求变化 经常变化 不经常变化 固定的需求,需求可以建模
用错方式的后果 用敏捷的方法开发登月火箭控制程序, 前N 批宇航员都挂了。 用敏捷方法, 商业用户未必受得了两周一次更新的频率。 敏捷方法的大部分招数都和这类用户无关, 用户关心的是: 把可靠性提高到 99.99%, 不要让微小的错误把系统搞崩溃!

4.Ad hoc Test & Bug Bash低效率的解决办法?

第五章中的Ad hoc Test作为随机探索式、特定一次性的测试,更适用于用户群体庞大,操作多或者对于系统安全性有极高的要求时,而bug bash则是一种集体hack的方法。我认为这两种方式共同的弱点在于随机性,不够系统。

如果说探索式测试的边界即为目前自动化测试中的盲区,而因为其探索式一次性且临时的特点会导致测试是不够系统的,且容易被丢失遗忘的,有什么办法可以把这种测试和之前的测试统一管理记录?此外,它的必要性如何衡量,因为需要更多的对代码的理解和对数据测试范围等的理解,如果投入测试的时间和测试出来的Bug的收益不高呢?

后文的小强扫荡也面临着相似的问题,如何在大扫荡的时候提高bug检测的效率,即不要有多针对一个问题的不同的测试,很多错误点其实只是一个Bug所导致的,如果在大家并没有打算去找到代码中问题根源所在的时候就进行黑箱测试时,就像OO大家互测的时候,很多人只是随机造了数据进行测试,并没有找到真正的问题所在,这就导致了一个地方的错误,被hack了十几次。是否有必要在大家提交了错误点的同时,由程序员随时进行更正?这样或许可以减少同质bug的出现。

5.平衡点在哪:及时解决客户的问题和及时修改软件的问题

在第四章MSF-Agile以及第八章 从CC 到 ZBB, 到最后的软件发布中提到,只有优秀的软件公司能找到一个平衡点,及时发布能够解决用户问题的软件,并且能及时修改软件中的问题——注意,这两个“及时”并不一定是同一个时间。

用户的需求可能并不能专业、客观或者严格的定义高质量软件,当定义的权力落到了开发者手上时,如何去衡量所谓“高质量”的软件?当提交质量的时候,把所有的问题一起报告给用户,并告诉他,这是无关大局的问题,你们用户在使用的时候不要去踩这个坑,但是用户真的能够理解吗,留在他印象中的有可能只是“你交付的软件有bug”这一个信息,但是当我们不告知这些信息,由有悖于一个合格的软件开发团队的该遵守的一些基本的要求。

能够做到“全面质量管理”无疑是一个优秀的软件,比如航空航天相关软件,汽车的系统开发所应该追求的。只是因为在敏捷开发中,速度的权重大于质量,追求的是“可用”,所谓欲速则不达,因此敏捷开发也不能被用在可靠性要求高的地方。

但其实在敏捷开发中,也是经历了很多版包括Alpha,Beta,ZBB,RC直到RTW,似乎就是在不停的寻找这个平衡点,但事实上就是在追求“高质量”,不过在其开发过程中不停的发布一些带有bug的版本。这个平衡点的建立,或者说开发者对于“高质量”的定义是否有一个可以更加严谨的规范标准呢?

6.放到屁股后面盲拧VS魔方贴纸

在第9章,作者举了魔方创新的例子。当市场饱和后,需要通过“改变规则--屁股后面盲拧”或者“了解用户--在魔方上面贴贴画”作为竞争力。与此同时作者还提出了一个检验是否真正掌握魔方的手段即将魔方复原后又拧回原来的状态,这样类似于盲拧没有与贴画有相同竞争力,技术含量却高很多的手段。

魔方本身的用意是计算最少的还原的步骤,并且通过熟练的手法将其还原。作者在文中批判为了技术创新而“用屁股对着目标用户”这一概念,但是为了吸引市场,而去为其附加本身并不是属于它技术的部分如放在屁股后面盲拧,而是一些花里胡哨的包装和噱头,去迎合目标用户,比如魔方6面贴成了公主的图案。

比如市面上的盲盒,它很吸引人,其是它的实际的价值是玩偶或者盒子里的东西,但商家不是通过提高自身的物品的质量而是通过一系列包装和利用顾客的猎奇心理去抢占市场,这本身是一种好的创新行为吗?

软件开发的时候,如果选择创新,是选择提高自身软件功能的创新,哪怕没有被消费者看到还是应该选择更吸引用户的花哨但是可能没有实际技术突破的点呢?

7.绩效管理的尺?

第十章中提到公司会采取或一维、或二维的方式来进行计算员工的绩效,但是当所有的人完成的工作都是较为独立的,即没有工作之间的可替代性,该如何衡量其贡献呢?

如果一个软件团队的Dev中没有明确出谁是“猪”或者明确出“鸡”,在衡量工作的量上是否只能根据实际且有效的代码量(比如展开不必要的循环或者重复造轮子不算进去)呢?此外,一个团队中负责完全不同方向的人员应该怎么评估工作量呢?PM即使不是完全操刀coding的,但是却也负责了整个项目的全生命周期,又或者QA,他可能不需要去研究很难的算法,但是他所把关的是整个项目中最严峻的一道线,而且正有可能是开发者的盲区,也不能单纯的根据难度去衡量工作量,一夜冥思苦想想到了算法,但是别人可能要花费好几天才能验证成功,又或者跑断腿说服别人投资购买。

二、调研源代码版本管理软件

GitHub:

团队协作流程

团队内

  • 创建团队公共仓库
  • 开发者将仓库克隆到本地
  • 团队不同的人负责不同的部分,并将自己的部分提交到自己的分支
  • 合并各个分支

fork

  • fork原项目
  • 克隆自己主页fork过来的项目
  • 开发并push
  • 在主页create pull request向原开发者申请修改
  • git remote add 添加与原开发者库的关联
  • git fetch upstream可以获取原开发者的修改

特点

拥有大量的开发者,社区活跃度高,该平台CI有Actions,Circle CI,Travis。

私有仓库需要付费,有milestones,labels,可以检查提交历史,对分支进行比较

GitLab:

团队协作流程

协作模式和github类似,通过Merge Request申请合并修改

特点

与GitHub一样都提供了开源项目平台,为开发团队提供了存储、分享、发布和合作开发项目的中心化云存储的场所。

可以建立免费私人仓库,免费设置仓库权限,设置project的获取权限,获取团队整体改进进度(项目开发图表)。

GitLab vs GitHub:代码管理,开发计划,代码核查,安全性,监视器和保护措施上优于GitHub

Bitbucket:

特点

  • pull requests,create a merge checklist with designated approvers.

  • Pipelines: build, test and deploy with integrated CI/CD

  • code and containers security

  • branch permissions

  • Group Milestones、Time Tracking、 Issue Tracker,用户权限和分支保护

三、调研持续集成/部署工具

1.GitHub Actions

1.JAVA_Maven

通过Maven以及JUit创建文件以及生成其测试文件,用yml部署CI,可以保证每次push时能够自动进行编译运行,并且测试,当Action不通过时,可以检查是test的哪一步出了问题,这一步原本应该是在本地跑的。但是一旦能够随时更新单元检测的标准以及整个项目的验证标准,就不在需要像下图右边中合并后在本地进行测试了,而是在Push时像左图一样直接编译测试。这样可以避免了多次迭代中,不停的对整个文件进行合并甚至手动合并再转到本地测试,这里我体会到CI带来最大的好处,极大的简化了繁琐的人工验证,转化成由代码管理库自动帮人验证处理。

#配置maven并借助JUnit框架进行测试:
name: Github Action Test
#在任意分支push时触发
on: [push]

jobs:
  All:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
#环境配置:
      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
#编译运行、测试以及输出命令:
      - shell: bash
        run: |
          echo "Build Project"
          mvn compile
          echo "Run Junit"          
          mvn test
#覆盖率测试:
          mvn cobertura:cobertura
    	  mvn cobertura:dump-datafile

2.python

测试一个答卷平台,仅测试了其能够建立成功,并输出对应的语句

#测试CI
name: test CI
#任意push,pull触发
on:
  push:
  pull_request:
#工作名
jobs:
  build:
    name: build a test for python homework with python${{ matrix.python-version }}
    runs-on:  ${{ matrix.os }}
    strategy:
        matrix:
          os:
            - 'windows-latest'
          python-version:
            - '3.7'
#步骤
    steps:
      - uses: actions/checkout@v2

      - name: Run a one-line script
        run: echo Hello, world!

      - name: Run a multi-line script
        run: |
          echo PYTHON CI TEST

2.GitLab CI

在GitLab CI上面运行时,我提供了java源码,测试代码,pom.xml,并部署了三个流程,但是http://gitlab.oo.buaa.edu.cn,GitLab中文社区(不同的账号)都出现了如下提示,“This job is stuck because the project doesn't have any runners online assigned to it." 我按照提示配置runner,其中由GitLab提供的共享的9个runner全部下线。因此我选择自己下载runner,但是当我运行(包括用管理员身份运行)安装包时,被禁止了。

搜索了其他自行搭建runner的方法,复杂且配置环境多为Ubuntu,于是没有继续,仅写完了针对GitLabCI的yml文件以及相关注释。

#确定镜像
image: local-registry.inner.oo.buaa.edu.cn/image-dev/java:8u201

stages:          
  - build
  - test
  - covertest
  
#在这一阶段输出java,maven的版本号
before_script:
  - java -version
  - javac -version
  - mvn -v
  
#编译,同时输出文件树
mvn_build:
  stage: build
  script:
    - echo "Compiling the code..."
    - mvn compile
    - tree -a
    - echo "Compile complete."

#JUnit测试
mvn_test:
  stage: test
  dependencies:
    - mvn_build
  script:
    - echo "Run JUnit4"
    - mvn test

#覆盖率测试
mvn_covertest:
  stage: covertest
  dependencies:
    - mvn_build
  script:
    - echo "Run JUnit4"
    - mvn cobertura:cobertura
    - mvn cobertura:dump-datafile
  coverage: '/cover="\d+/'

3.我对CI和CD的调研以及看法

敏捷开发模式极大的转变了软件开发的过程,商业软件的更新换代周期很短。

持续集成可以辅助自动将多个分支中的代码集中到一个仓库中,避免了人工合并检查整个系统的错误,它依赖于测试套件和自动化测试执行,有助于降低总体构建成本,并鼓励频繁迭代构建,在周期的早期发现缺陷。比如GitHub Actions,并且它给出了很多开源模板,可以直接使用很方便,可以直接进行代码合并、运行测试、发布到第三方等。实操中GitLab CI自己配置runner很麻烦,尤其是当公共runner都被禁用了。GitLee可以通过图形化界面进行CI的配置开发。

持续交付自动化了从提交代码到仓库,再到测试和发布产品过程的所有步骤,但是发布的具体细节需要人工操作,依赖于部署流水线,在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报,如果通过则将继续进入下一个测试。

持续部署则是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署,不需要人为决定何时及如何投入生产环境,可以配置为快速分发组件、功能模块或修复补丁,并准确说明当前提供的内容,可以更快获取用户反馈并进行迭代。比如Jenkins, CircleCI。

posted @ 2022-03-09 22:16  YSMY  阅读(95)  评论(2编辑  收藏  举报