Skip to main content

1. 阅读提问

我平时就很喜欢阅读,但我很少提出问题。我会习惯性的给作者提出的与我旧有知识体系矛盾的观点添加定语,形象点描述的话,有个很知名的“亚洲最大的单体教学楼”的梗也许能表达我的思维方式,配图的文字是“当数据的维度增加时,数据将会变得特别稀疏”。因此除了明显的钓鱼或者是带有精准目标群体的内容,我都很难提出反驳来——因为在上下文情形下他说的确实是正确的。

所以在阅读《构建之法》时,提出问题对我来说就非常困难,比如代码规范中关于大括号换行(顺便一提,我是函数括号换行,控制语句括号不换行党)的论述、关于面向对象的思想的观点,这样的问题在不同的程序语言/项目中往往是不同的。最后我终于憋出来了一些虽然内心已经有答案的问题:

1.1 敏捷软工过去的团队项目后来怎样了?

“现代软件工程”这门课已经上了好几年了,以前有很多学生做过团队项目(说不定包括本校的学生),请你们找一个以前的团队采访一下,并写一个博客: ·当时的项目有多少用户,给用户带来了多少价值?现在还有人用吗? ·这个项目能否给我们团队继续开发,源代码/文档还有么? ·项目开发有什么经验和教训? ·对学好软件工程有什么建议? ——《构建之法》1.3

在我大一大二时,曾有学长学姐在软工课程上开发了《航胥》等供北航同学使用的App(另一款名字忘了),这些App相比北航教务处提供的时而打不开的小程序,提供了更多直击用户痛点的功能:比如接入课程中心,可以很方便的管理待完成的作业;将课表和空教室查询联系在一起,方便同学上课与寻找教室;本地缓存课程表,即使没有网络也可以放心查看课程……

与这些软件最开始的邂逅往往来自群组里学长学姐的安利,然而可能是服务器资源到期,也可能是课程评分结束,亦或者是教务对于非官方工具的限制,在逐渐习惯这些软件带来的便利后的某天,App便突然再也无法访问了,最后又回到了官方网站的怀抱。

当然,如果同学们的成果最后可以被官方所“招安”,比如集成的Course Center任务提醒功能,那么从结果上看也是好的,但是事实上教务的课程表除了访问超时的次数变少,似乎没有其他新增功能。这门课的助教很多都是去年敏捷软工的参与者,我想也许可以在这里问问《构建之法》中所提问的这几个问题。

1.2 单元测试由最熟悉代码的人(程序的作者)来写是否足够呢?

单元测试必须由最熟悉代码的人(程序的作者)来写。代码的作者最了解代码的目的、特点和实现的局限性。所以,写单元测试没有比作者更适合的人选了。 ——《构建之法》2.1.2

单元测试是一种白盒测试,对于编写这段代码的作者来说,代码的内部结构是完全透明的,所以单元测试当然应该由作者本人负责。然而,个人编写的单元测试是否足够呢?在我看来,单元测试的作用主要有两种:

  1. 作为CI的基础,确保模块在一次次的版本迭代中能够正确执行基本功能
  2. 为了写出单元测试,程序作者需要规范自己的代码,简化对外暴露的逻辑

如果说是一个不会继续迭代的模块(比如你在写前端的某个页面动画,这个时候似乎就没有单元测试的必要?),那么单元测试的重要性就有所削弱(虽然在你某天突然打算新增功能时就会拍大腿);但在业务需要快速迭代的情况下,单元测试与自动化集成部署是减少人力成本的有力方式。然而个人对于代码的理解具有局限性,在写出某段逻辑时,你可能很难意识到自己正引入了一个新的问题。

在现代的软件工程中,很多时候某个功能的设计者与实际的编码人员并不是相同的,单元测试是否更应该由模块的设计者进行?在结对编程中,两个人轮流进行功能开发和单元测试是否是既满足“最熟悉代码”又能够避免囿于个人视野的最佳方式?另外OO第三单元的Junit给我的体验并不好,相关的工具没有良好维护,配置环境就耗费了大量时间,那么又有那些降低程序员进行单元测试的时间成本,从而提高程序员进行单元测试的积极性的框架?我想这些问题在学完本学期的软工后应该能够得到解答。

1.3 2021年,“全栈工程师”们都去哪里了?

当我们谈论“全栈工程师”的时候,我们说的究竟是“交响乐作曲家写各个乐器的乐谱”,还是“演奏家满场奔走,操作各种乐器”呢?当工程师设计软件的时候,工程师的设计、修改错误等活动大致等同于交响乐的谱写完善阶段,两个职业都假设一旦程序/乐谱写好,它们就会被正确地执行。当一个运维工程师在维护一套系统的时候,运维团队要了解各个模块的作用、维护知识,以及和硬件、商业模式相关的各种事件的需求。如果这大部分运维工作都是由一个运维工程师来完成,那么这位工程师的确是“全栈”。 ——《构建之法》3.3

在第一次作业阅读提供的往届优秀博客中,我看到很多学长的职业规划都是成为一名全栈工程师,然而这个词语如今似乎早已不再流行,提供的岗位也比职责更加明确的前端、后端少了不少。在网上搜索相关的问题,大部分回答都在劝退:一方面更加明确的分工是大势所趋,企业所需要的是可替换的人才;另一方面过多的领域也让全栈工程师难以深入钻研某一个方向。

《构建之法》中提出了疑问,你是更愿意倾听街头啥乐器都会一点的艺人的演奏,还是专精于某一种乐器的乐手。在各个职能都在进行减少组件之间的耦合,用更加先进的框架封装重复性操作的当下,交响乐已经谱写完毕,大多数人所能做的似乎只有演奏家,也就是维护一套系统,偶尔增加点新功能的工作。我想软件工程属于人的最好的时代已经过去,这种情形下“全栈”也就跌落神坛,成为了又一种重复性的劳作,个人的创新工作又将如何展开呢?

1.4 结对编程在双方差距较大时的意义是什么?

结对编程中,因为有随时的复审和交流,程序各方面的质量取决于一对程序员中各方面水平较高的一个。 ——《构建之法》4.5.2

这周我们马上就要开始结对编程,在网络上查询相关的资料,发现对于结对编程各执一词,在另一个同学的评论区,某位大牛更是直言“公司里没有用过结对编程”。

“在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。”这种工作方式是与技术性工作自身的封闭性有所冲突。对于双方各自的习惯、性格,磨合所耗费的成本是否大于结对得到的产出?

结对编程让代码复审的时间粒度大为减小,但是在双方差距较大时,水平较低的一方能否逃离水平较高的一方的思维误区,进而避免在小问题上有所改善,却因为“当局者迷”而共同出错的可能性?

1.5 如何避免A/B Test带来的运行成本的提升?

A/B测试当然也有弱点: ·运行成本随着时间的推移而变大,增加网站运维的复杂度,对网站数据收集和数据挖掘的能力也是一个考验; ——《构建之法》8.3

在《用户调研》这一章,A/B实验是我相对熟悉的部分——软件项目中的功能改进,很多时候都需要通过A/B实验展开,在得到分析结果之后再选择合适的方案。

不过我在实习期间上手业务代码时,发现有很多过时的A/B实验残留其中,埋点穿插在主要的业务中,再加上没有清晰的文档,很多时候修改都非常困难。而这是否能够通过一开始清晰的规范得以避免?

2. 源代码版本管理软件调研

课程组建议调研的这几款基于源代码版本管理软件Git的项目管理工具都有免费计划,下面我就先从个人免费使用者的角度,简单介绍这几款产品:

2.1 GitHub

截止至2020年末,GitHub上的开发者数量已经超过5600W,而它也是我最早接触的的代码托管平台,并在一次次New Repo中养成了“上传项目→写篇介绍文章→居然真的有人给我点Star”的习惯;GitHub的另一个令人心动的功能莫过于Gist,就像是程序员的印象笔记,可惜国内难以访问(这几天貌似都难以访问了)。

GitHub鼓励开源,用户可以托管不限数量的开源仓库(总项目不超1GB、单文件不超100MB),此前主要以私有仓库订阅付费为盈利手段。在其庞大的用户基数的影响下,也让平台的开源项目遍地开花,我想或许不少同学的GitHub初体验便是用“BUAA+课程名”搜索学长们的作业仓库吧;在被微软收购后,GitHub也逐步放开了对私有仓库的协作人数与仓库数量限制。而在团队协作与项目管理方面,Pull Request和Issue无疑是GitHub的两大利器:

  • 在多人协作的软件工程项目上,通过分支控制和PR可以有序推进bug fix/new feature/release的开发,一个我最近看过的良好的小工程例子就是gin-vue-admin项目,包含develop、feature、release版等分支,在统计面板也有着清晰的数据可视化展示;
  • 每次commit都可以和issue关联,并为issue添加特定的标签(如milestone等),进而将issue作为一个轻量级的项目任务管理工具使用,典型例子如Flutter的5000个issue。

此外GitHub社区开源的良好风气还能让用户也在issue上提出bug与功能建议、或者自己Fork仓库之后提个PR(据说这样就可以在简历上留下“是XX开源项目的贡献者”的浓墨重彩的一笔)。总的来说GitHub的社区氛围进一步加强了软件开发者与使用者的交流,不愧是“全球最大的同性交友网站”。

2.2 Gitlab

我在OO2019课上第一次接触了Gitlab,感觉大多数功能和Github相差不多。而相比项目代码闭源的GitHub和Bitbucket,Gitlab开源的特性让它备受企业用户的青睐:正所谓“公司代码不出内网”,Gitlab目前划分为EE和CE两个版本,其中Community Edition采用MIT license,可以免费用于商用,因此不少公司都会将Gitlab作为内网的代码托管环境。

我也曾动过在Docker上用它部署私人代码托管工具的念头,虽然最后由于NAS主机孱弱的性能只好作罢。从个人使用角度,功能更简单的Gitea就足以满足托管代码的基本需求了。

2.3 Bitbucket

Bitbucket我还是第一次听说,但将MR与Jira结合的工作流国内不少公司都在采用,或许正体现了Bitbucket的优越性。

而相比GitHub或是Gitlab,Bitbucket在团队协作方面的表现无疑更加优秀。在多人协同开发的情形下,有着更加明确的权限管理和通知方式。

对于个人用户和五人以下的小团队来说,Bitbucket的公有和私有仓库是免费的,我想这就很契合本次软工课程的场景。

2.4 异同总结

最后总结一下这三个软件的异同之处:

相同点:

  • 都支持Markdown语法
  • 都为免费用户提供了足以满足大多数需求的方案
  • 都支持CI/CD工具

不同点:

  • 版本控制工具的泛用性:Gitlab仅支持Git,而GitHub和Bitbucket在此基础上还支持SVN,HG,TFS等管理的项目,更具泛用性。
  • GitHub的领头地位:如同软件领域的第一名定律,GitHub的用户基数最大,在被微软爸爸收购后更是财大气粗,使得它可以很快推出与竟品类似的功能(比如Github Actions就或多或少汲取了Gitlab CI的经验?并做得更好),从而继续保持自己的优势。
  • 差异化的盈利路线:
    • 直观上来说,GitHub就像是一个程序员们都离不开的SNS,QQ微信也有过难以寻找流量变现的时代,但今天却成为了腾讯不断发展新业务的基石——而GitHub或许就有着这样的潜力;
    • Gitlab最开始就作为开源项目而出现,在被Google收购后依然如此(CE)。情怀的事,用钱来衡量或许就庸俗了;
    • Bitbucket在国内个人领域的知名度并不高,但在面向企业所提供的解决方案比前两者更加出色。

3. 调研持续集成/部署工具

3.1 Gitlab CI

  1. 以OO_2020_Pre2_Task2为蓝本,在本地使用maven重构并编写单元测试:

image

  1. 配置yml文件,push后触发pipeline:

image

3.2 GitHub Actions

GitHub Actions是GitHub提供的CI服务,相比Gitlab CI,我觉得GitHub Actions的最大优势就是利用了平台的社交属性:每个开发者可以上传自己的Aciton脚本,在市场中供人下载使用。

上学期的数据库课程上我写了一个基于Vue的商城前端页面,恰好市场上就有Node.js的模板,下面就演示下通过GitHub Actions检验该前端项目能否正常Build的测试:

  1. 在Actions界面选择Node.js模板,并针对项目对具体配置做简单修改: image yml文件语法和Gitlab CI有差别。

  2. 进行push操作,成功触发了Aciton:

image

  1. 运行成功,显示结果。

image

3.3 CI/CD使用小结

在实习的时候第一次接触CI/CD,每次提交的PR会先触发代码静态检查(如是否不符合代码规范、引用了已经准备弃用的库等),出包成功后交由QA等测试,并在审批通过后合并到对应分支。在我看来,这套自动化工作流程能够避免项目出现易于检查的失误,降低合并修改的心智负担与人力资源,也能提升RD们在代码规范上的自觉性。

但要写好CI脚本,对程序员编程素养的要求也随之增加:要怎么写好单元测试,确保每次自动集成的覆盖率?不同的平台(如非Linux的系统)如何运行?我想这些都需要自己在敏捷软工课程上进一步学习。

4. 其他参考资料

  1. github actions 简易入门及自动部署博客实践 https://zhuanlan.zhihu.com/p/93829286
  2. GitHub Actions 入门教程 http://www.ruanyifeng.com/blog/2019/09/getting-started-with-github-actions.html
note

这是一篇搬运自博客园的文章,发表于 2021-03-17 13:45。