项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2021春季软件工程(罗杰 任建) |
这个作业的要求在哪里 | 个人阅读作业#2 |
我在这个课程的目标是 | 锻炼软件开发能力,学习团队协作方法 |
这个作业在哪个具体方面帮助我实现目标 | 深入了解软件工程,学习CI/CD工具 |
快速看完整部教材,列出你仍然不懂的5到10个问题
问题1
教材2.1.2中写到
单元测试必须由最熟悉代码的人(程序的作者)来写。代码的作者最了解代码的目的、特点和实现的局限性。所以,写单元测试没有比作者更适合的人选了。
作者提出单元测试必须由代码作者来编写,因为代码的作者是最了解代码的人。但人的思维都是有局限性的,如果代码的作者真能思考到代码的方方面面,那就不会有那么多bug了,而且很多bug也正是由于代码作者写代码时候的思维局限性所导致的。
所以笔者认为单元测试可以由代码作者来参与编写,因为代码作者确实更了解代码,知道怎样更快的写好单元测试。但与此同时,也应该有非代码作者的参与,非代码作者往往能提供不一样的思路,有角度不同的理解,更容易想到代码作者的思维盲区,这样写出来的单元测试才能更加全面。
问题2
教材3.1中写到
对于这些任务,一个成熟的软件工程师应该能够降低任务交付时间的标准方差。如果你能长时间稳定而按时地交付工作的结果,内部和外部的顾客就会对你的工作有信心,更喜欢与你合作。
作者认为一个任务交付时间稳定的软件工程师,大家会对他更有信心,更喜欢跟他合作。如果所有人都这么认为,会不会因此导致很多软件工程师可以更短时间内完成任务却特意花更长时间呢?因为他们不能保证每次都可以在短时间内完成,另外毕竟市场和公司都喜欢任务交付时间稳定的软件工程师,这样拉长时间还更加轻松,何乐而不为。
当然从整个行业生态来看,在这种交付时间稳定更好的标准下,偶有这种能力资源的“浪费”也是可以接受的。但是否有更好的衡量标准可以避免这种“浪费”呢?
问题3
教材4.3.2中写到
函数最好有单一的出口,为了达到这一目的,可以使用goto。只要有助于程序逻辑的清晰体现,什么方法都可以使用,包括goto。
作者认为只要有助于逻辑清晰表达,使可以使用goto的。犹记得大一时接触c语言时,老师特地说过不要使用goto,goto虽然好用,但会使程序结构混乱。
于是抱着疑惑查阅了相关资料,发现主要有两种观点。一种就是不提倡使用goto,因为容易把逻辑弄乱且难以理解;另一种提倡使用goto,因为在跳出多层循环和异常处理时比较方便且效率高,很多大型项目、开源项目,包括linux都会巨量的出现goto来处理错误。所以比较好的标准就是在错误处理的时候使用goto,其他地方都禁止使用goto吗?
问题4
教材8.5中写到
杀手功能(Core)/外围功能(Context)
除此之外,我们的竞争对手和用户已经决定了一些此类产品必须要满足的需求,不能满足这些需求,产品就入不了用户和评论员的法眼,当然,还有许多功能是辅助性的。这样,我们又得到另一种划分:
必要需求(MissionCritical)/辅助需求(Enabling)
这四种划分结合起来,就得到了功能分析的四个象限。我们以一个英汉词典软件为例子来说明。
在教材后面也提到了,比较核心的功能要尽量做的好,达到行业最佳,而那些辅助性的、外围一点的功能则可以以最低代价来维持,甚至不做。
但现实中很多情况下这样做不太合理,很多软件的核心功能由于行业技术水平的限制,做的再好也就那样,用户甚至感觉不出来有什么差别。但那些外围、辅助性的功能反而是用户最能感受到差别的,比如界面操作的舒适度,比如有多种皮肤,用户可以自由定制。很多原版的软件和游戏不火,反而那些抄袭的软件或游戏被更多人欢迎,这些抄袭软件甚至再在核心功能上对比原版软件还略有不如。但就是因为它能提供舒适的操作界面,个性化的定制,容易上手等非核心特性,反而与其他软件拉开了差距,取得了胜利。
问题5
教材16.1.5中提到
统计数据表明,70%的创新者说,他们最成功的创新,是在他们的拿手领域之外发现的。
第一眼看到这个70%,就觉得难以相信。但经过仔细思考,觉得可能是一种统计偏差。当叫你去思考拿手领域外的创新时,你可能随便就能说出很多,但因为并不了解哪些是可实现的,哪些是有实际意义的,所以可能你说的99%的创新都是无意义的。而如果让你去思考领域内的创新,你可能思考半天也说不来,原因之一是长期处于这个领域,思维会被束缚,另一个原因则是你相比于外行人,更清晰地知道哪种创新是真正可行的且有价值的,所以在思考中就把很多想法给毙了。
所以在拿手领域外创新其实并不比领域内容易,只是思考方式可能与那个领域的工作者不同,加上“不知者无畏”,可以提出很多有意义或无意义的想法。此外,创新者就算在拿手领域外有了一个好的创新想法,最终还是需要那个领域内的工作者来将这个想法改进、细化,使这个想法真正有实现的可能并具有实际的价值,其实这个过程也算是一种“创新”。可以说是创新者提供了一个思考方向,领域内的工作者依着这个思考方向进行创新。
二、调研源代码版本管理软件
相同之处
- GitLab和GitHub都是属于第三方基于Git开发的管理代码的软件
- GitHub 和 GitLab 都是基于 web 的 Git 仓库,使用起来都差不多
- 为开发团队提供存储、分享、发布和合作开发项目的中心化云存储的场所
不同之处
- GitHub如果使用私有仓库,是需要付费的,GitLab可以在上面搭建私人的免费仓库
- GitLab让开发团队对他们的代码仓库拥有更多的控制,相对于GitHub,它有不少的特色:
- 允许免费设置仓库权限
- 允许用户选择分享一个project的部分代码
- 允许用户设置project的获取权限,进一步提升安全性
- 可以设置获取到团队整体的改进进度
- 通过innersourcing让不在权限范围内的人访问不到该资源
- GitHub 作为开源代码库,拥有超过 900 万的开发者用户,目前仍然是最火的开源项目托管平台。从代码的私有性上来看,GitLab 是一个更好的选择。但是对于开源项目而言,GitHub 依然是代码托管的首选。
- BitBucket服务非常类似于GitHub,采用Mercurial和Git作为分布式版本控制系统。BitBucket最适合小型开发团队,随着团队的成长,BitBucket提供了与GitHub和GitLab相比更温和的定价条件。BitBucket还为团队提供了灵活的部署模式。
三、调研持续集成/部署工具
GitLab-CI
仓库点我 采用OO课程的Pre1Task2作业作为样例,构建maven项目,写了简单的Junit单元测试。
yml文件配置如下:
image: local-registry.inner.buaaoo.top/image-dev/java:8u201
stages:
- build
- test
before_script:
- java -version
- javac -version
- mvn -v
mvn_build:
stage: build
script:
- echo "Build Project"
- mvn compile
mvn_test:
stage: test
dependencies:
- mvn_build
script:
- echo "Run JUnit4"
- mvn test
- echo "Code coverage 99%"
coverage: '/Code coverage d+/'
先build maven项目,再进行单元测试。把项目push到仓库,成功触发ci,实现在线编译、在线运行、在线测试,如下图所示。
点进job可详细查看构建过程,下图是test阶段的输出,可见成功通过单元测试。
GitHub-Action
仓库点我 跟GitLab-CI一样,采用OO课程的Pre1Task2作业作为样例,构建maven项目,写了简单的Junit单元测试。
yml文件配置如下:
name: Java CI with Maven
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
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
- name: Build with Maven
run: |
echo "Build Start!@xyl"
mvn compile
echo "Build成功!@xyl"
test:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: |
echo "Test Start!@xyl"
mvn test
echo "Test成功!@xyl"
因为与GitLab-CI采用的项目相同,所以yml含义差不多,都是先构建maven项目,再进行单元测试。另外在构建项目与测试之前,都要进行一些环境的配置,如配置jdk,maven环境等。将代码push到仓库后,成功触发Action,如下图所示。
下图为test job运行结果,可见成功通过单元测试。
CI/CD工具使用小结
GitLab CI/CD 和 GitHub Actions 都可以创建能自动构建、测试、发布、发行和部署代码的工作流程。 二者的工作流程配置有一些相似之处:
- 工作流程配置文件以 YAML 编写并存储在代码仓库中。
- 工作流程包括一项或多项作业。
- 作业包括一个或多个步骤或单个命令。
- 作业可以在托管或自托管计算机上运行。
但二者也有一些区别:
- 在 GitLab CI/CD 中,使用
script
键指定脚本步骤。 在 GitHub Actions 中,所有脚本都使用run
键来指定。 - 在 GitLab CI/CD 中,
tags
用于在不同的平台上运行作业,而在 GitHub Actions 中,它使用runs-on
键运行。 - 在 GitLab CI/CD 中,Docker 映像使用
image
键定义,而在 GitHub Actions 中,它使用container
键定义。
除了语法配置上的区别,还有一些生态上的差别。如GitHub有一个actions market,可以直接引用别人写的action,而且也不用自己配置runner,所以就使用体验上会更加舒适。