道法之间——软工第2次博客作业ShaunYao

软件工程究竟是什么?怀着这样的疑问,我仔细地翻阅了《构建之法》这本书,也算是系统性地对软件工程的各个环节与组成有了一个大致的了解,这才终于得到了一个大致满意的答案:

于是说到底,软件工程这门课程所真正想要讨论的核心是”人在软件开发过程中所应该扮演的角色“,而非”如何去编写一段高质量的代码“;尽管这两者看起来似乎有些因果的味道。

如果将”人的立身之本“看作【道】,将程序的撰写比作【法】,那么软件工程所处的位置,正是这道法之间。

在这部分内容中,为了说明商用软件和爱好者写的程序的区别,作者以航空业类比进行了如下的论述:

说到商用软件和爱好者写的程序的区别,我们还可以看看这个例子:

如果一架民用飞机上有一个功能,用户使用它的概率是百万分之一,你还要做这个功能么?你会选择:

根本不考虑

做了,但是不用告诉用户

做了,而且不厌其烦地告诉用户如何使用

你会如何选择呢?选择之后,这个功能究竟是什么呢?

谜底是:

飞机的安全功能

我认为作者在这里的论述存在着明显的误导性,似乎想要证明无论是什么功能,只要用户有可能要用到,即便可能性很小,一个合格的商用软件开发者也必须要在一开始加以考虑并予以实现。否则万一这个功能就像飞机的安全功能一样在关键时刻可以救人一命的话,到时候再后悔就为时已晚了。

首先需要承认的是,确实存在一些用户平时甚少使用但却极为重要的功能,就如同飞机里的安全功能一样。但对于这些功能,我们之所以在程序中需要加以实现,显然不是因为它被使用到的概率很低,而是因为它的重要性不容忽略。同样是民用飞机上一个使用概率为百万分之一的功能,甚至比这个高一些,可能有万分之一,比如给飞机上的电影库中更新一部最近刚刚上映的小众电影,难道也需要开发者在一开始就要去考虑实现它吗?

至于具体应该如何衡量这一重要性,则是第8章【需求分析】所讨论的内容了。

在讨论”好的单元测试的标准时“,作者给出了以下观点:

单元测试必须由最熟悉代码的人(程序的作者)来写。

代码的作者最了解代码的目的、特点和实现的局限性。所以,写单元测试没有比作者更适合的人选了。

对此我并不是完全认同。一方面,进行测试工作的人必须是熟悉代码的人,这点毋庸置疑:如果一个人之前从未阅读过这份代码,那么他也很难对代码的细节和功能有一个清晰的认识。但另一方面,写单元测试的一定得是最熟悉的人(也就是作者)吗?

在现如今许多成熟的科技公司中,面向编程开发人员往往会设置多种岗位,其中就包括算法岗、运维岗、测试岗——这也就意味着在一个成熟的商业公司中,【开发】与【测试】这两步往往都是分离的,并不是由同一个人甚至是同一个团队来完成,而是会交给专门的测试人员去做。之所以这样,乃是因为一般来说代码的编写者本身往往会陷入到自己的思维定势中,很难跳出自己的视角彻头彻尾地审视这段代码,正所谓”不识庐山真面目,只缘身在此山中“。

当然,要想确保测试人员能够清楚地理解开发者编写的代码,对代码进行良好的封装与抽象以及一份清晰的说明文档是必不可少的,这就对一个商业公司的规范与文化提出了较高的要求。对于普通的业余编程爱好者而言,或许还是自己来写单元测试的好——谁让没有经费呢。

在这部分内容中,作者举了街头卖艺的单人乐队、只研习某一乐器的交响乐团中的乐手和编写交响乐的作曲家的例子,似乎想要引发读者对于【专和精的关系】的思考。(原文较长,故在此不再引用)

这里我对于作者的论述过程感到非常疑惑。在我的认识中,”专“和”精“这两个概念应该是同义词,【专】即专业,【精】即精通——一个人的专业自然就是一个人精通的内容,这有什么思考的必要吗?

鉴于作者所举的3个音乐方面的例子,我认为可能他真正想要讨论的是【专和”全“的关系】,即对于弹奏一种乐器的乐手而言,精通这一种乐器似乎要比对每种乐器都略知一二要更受人们的欢迎;但对于作曲家、指挥家们而言,则必须要对所有可能用到的乐器都要有一定程度的理解。那么,对于一名工程师而言,究竟应该是更”专“一点好,还是更”全“一点好呢?

而关于如何提高技能,作者给出的答案是:不断地练习。原文如下:

因为,技能。或者说熟练度,其本质上其实是一个人在劳动中逐渐异化的过程。他越熟练于某一特定的工作,就越有可能囿于这项工作所设下的囹圄中。而反过来,解决问题,也就是技能的反面,所体现的才恰恰是一个人真正意义上的真实能力,是人之所以为人的证明。

以编程语言为例,现在市面上的编程语言多如牛毛,比较有名的就有C、python、java、C#、Rust、Go……而每一种语言都有它自己的语言特性,那么对于一个优秀软件工程师的衡量标准,难道是看他所精通的编程语言的多少吗?再比如,随着软件生态的日趋成熟,很多领域都已经有了一套成熟的软件体系和自己定义的各种API与函数接口,像在科学计算领域,就有Matlab,Mathmetica以及Python语言支持的scipy库等等,它们的很多函数虽功能类似,但名称、调用形式却千差万别,难道我们也需要对这里面的每一个API都烂熟于心吗?

如果真是这样的话,那还要机器干什么,都让人来做好了。

所以,我始终认为,衡量一个科班出身的CS人的能力究竟如何,不是看他会调多少包,而是看他能否举一反三、快速把握问题的关键和本质,至于具体的实现细节,还是交给文档的好。

当然,如果一个人连一门编程语言都不会就敢说自己是CS人,那就不在本文的讨论范围之内了。

这里作者在讨论什么是良好的程序设计规范时,认可了对goto语句的使用,原文如下:

函数最好有单一的出口,为了达到这一目的,可以使用goto。只要有助于程序逻辑的清晰体现,什么方法都可以使用,包括goto。

而荷兰计算机科学家Dijkstra在很久以前就提出了著名的"goto有害论",反对在程序中使用goto语句,这显然与本书作者的观点不合。对此,我本人也更倾向于Dijkstra的观点,即一旦允许使用goto,那么很有可能就会破坏程序原有的清晰逻辑结构,造成多出口的结果,这一过程往往是不可控的。因此,有必要在源头上断绝goto被使用的可能。

这部分内容在书中主要以阿超、二柱等人的对话的形式加以展开。当涉及到团队项目在完成后是否应该开源这一问题时,二柱、阿超等人均在不同程度上表达了反对,因此也可以认为作者本人也更倾向于以“闭源”的形式对待商业软件。

现如今,开源已成为CS界的一种潮流,这与传统制造业可以说是大相径庭,但至于这种趋势究竟是否会促进IT公司商业价值的提升还是会在一定程度上影响其(特别是小公司)商业化产品的成功落地,现在也是众说纷纭。对此,我本人也没有一个明确的答案——但我相信,未来一定会出现一种基于开源的全新商业模式,从而可以兼顾对个体劳动贡献的肯定与对社区繁荣的维系。

在本书第16章的开始【创新的迷思】部分,作者提出了两种不同的创新方式(P342),分别是改良式(Incremental)创新与颠覆式(Disruptive)创新;紧接着,在【创新的时机】部分,作者又以黄金点游戏为例,试图说明最终真正能够成功的创新往往每次都是比大众的平均值先走了一小步,实现所谓的“相对优势”;而那些一开始最激进的创新却反而有可能归于失败。

对此我不敢苟同。应该看到,很多对人类文明产生重大影响的发明创造往往对人们的认知都是颠覆性的,远的有牛顿三定律直接打破了人们过去所认可的【力是维持物体运动状态的原因】这一错误观念,近的有乔布斯首创的iPhone系列手机彻底颠覆了人们过去对手机的功能定位。如果任何事都只追求一点一点的迭代式创新的话,那么整个人类文明的发展甚至很有可能会逐渐“收敛”,最终停滞不前。

正如标题中所言,这部分内容中作者的基本观点就是【PM做开发和测试之外的所有事情】。那么问题来了,是不是开发和测试人员要做的事情PM就统统不用管了呢?他们具体都写了哪些代码,这些代码究竟能不能实现客户的需求,难道这些问题PM就不用去考虑了吗?而另一方面,开发和测试人员是不是也无需关心客户的需求了呢?假设客户后面又提出了更复杂的功能要求导致软件全部需要重构,那这个锅应该是PM背还是开发人员背呢?

因此,我认为,单纯地把PM的工作定义为【开发和测试的补集】是非常不合理的。一个合格的PM他在一个团队中所起到的作用更像是【粘合剂+方向标】,他既需要随时把握各个开发测试岗位的当前进度(这如果没有基本的技术功底的显然无法做到),同时也需要及时将客户的需求传达给团队的其他成员们,从而共同协商出下阶段合理的任务计划与分工进度安排。

这里作者将产品的功能从实现和需求两个角度进行了划分,得到了如下图所示的功能象限图。

可以看到,对于【杀手功能+辅助需求】这样的组合,作者给出的建议是采取“维持”的办法进行实现,而对于【杀手+必要】这样的组合,作者则给出了“差异化”的建议。

再比如,现在非常火热的《王者荣耀》等一系列手游,它们的核心功能无疑是游戏的玩法本身,但很遗憾这部分功能通常是免费的,而真正收费的却是各种【皮肤】等看起来并无任何实际用处的外围功能:那这是否意味着游戏公司就只需要提供最基本的皮肤给玩家就够了呢?

因此,我认为在资金有限的前提下,一些必要需求,哪怕是杀手功能,反而只需要“维持”即可;而恰恰是一些看似不那么重要也不难实现的辅助需求,才是真正需要做到“差异化”的关键所在。

本部分将逐一对GitHub、Gitlab与Bitbucket这三个目前主流的用于源代码版本管理的软件进行简要介绍,最后再对它们之间的异同加以分析。

GitLab是一个利用RubyonRails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面访问公开或者私人的项目。

BitBucket是2008年创建的源代码托管网站,采用Mercurial和Git作为分布式版本控制系统,同时提供免费账户和商业计划。2010年被Atlassian收购,与Atlassian的其他服务(GitGUISourceTree、HipChat、Cloud9)顺利集成,主要面向慈善企业和企业用户,其主要市场是大型企业。

由于这三者均为基于Git的分布式版本管理系统,因此在团队协作流程上基本上也是大同小异。以GitHub为例,整体的协作流程大致可分为以下10个基本阶段:

GitLabCI是GitLab内置的进行持续集成的工具,只需要在仓库根目录下创建.gitlab-ci.yml文件,并配置GitLabRunner;每次提交的时候,GitLab将自动识别到.gitlab-ci.yml文件,并且使用GitLabRunner执行该脚本。

本部分采用大二下OO课程的Unit3_task2作业作为样例,引入Maven框架,展示GitLabCI/CD的基本过程。

所选镜像

image:local-registry.inner.buaaoo.top/image-dev/java:8u201宏定义变量

variables:USER_INFO:tcyhostbefore_script

before_script是用于定义一些在所有任务执行前所需执行的命令,包括部署工作,可以接受一个数组或者多行字符串。

before_script:-java-version-javac-version-mvn-v各阶段定义

阶段是对批量的作业的一个逻辑上的划分,每个GitLabCI/CD都必须包含至少一个Stage。多个Stage是按照顺序执行的(但同一个stage的多个jobs则会并发执行),如果其中任何一个Stage失败,则后续的Stage不会被执行,整个CI过程被认为失败。

stages:-build-run-testbuild

build阶段的核心为mvncompile命令,对项目进行编译,并打印编译成功后的目录结构。

mvn_build:stage:buildscript:-echo"[${USER_INFO}]BuildProject"-mvncompile-tree-I.gitartifacts:paths:-target/注意这里利用artifacts字段将mvn编译得到的结果传递给接下来的jobs,从而使后续任务无需重新进行编译。

运行结果如下:

run

run阶段主要任务为执行一个简单的测试样例,从而初步判断项目的正确性。

java_run:stage:rundependencies:-mvn_buildscript:-echo"[${USER_INFO}]Running"-cdtarget/classes-javaMain<../../src/test/in0.txtonly:-se注意这里通过添加only字段,限制该job只能在se分支发生变动时运行,master或其他分支出现变化时,该job不会被执行。

test

test阶段主要任务为对原始项目进行Junit单元测试,并计算测试的覆盖率。

GitHubActions与GitLabCI在功能上类似,都是用于对代码进行持续集成操作;但GitHubActions将这些操作进行了解耦合,从而允许开发者把每个操作写成独立的脚本文件存放到代码仓库中,使得其他开发者也可以引用。因此,如果你需要某个action,就不必再自己写复杂的脚本,而是直接引用他人写好的action即可。整个持续集成过程,也就变成了各种actions的组合。

本部分以一个简单的基于Python实现的M/M/n队列模拟器程序为例,利用pytest和flake8等包,展示GitHubActions的基本过程。

基本配置与环境初始化

name:GitHubActionsdemoon:-push-pull_requestjobs:build:runs-on:ubuntu-lateststrategy:matrix:python-version:-'3.8'steps:-uses:actions/checkout@v2-name:SetupPython${{matrix.python-version}}uses:actions/setup-python@v2with:python-version:${{matrix.python-version}}运行结果如下:

安装依赖包

-name:Installdependenciesrun:|python-mpipinstall--upgradepippipinstallflake8pytestpytest-covif[-frequirements.txt];thenpipinstall-rrequirements.txt;fi运行结果如下:

flake8静态语法测试

-name:Lintwithflake8run:|#stopthebuildiftherearePythonsyntaxerrorsorundefinednamesflake8--count--ignoreF403,F405,W504,E226--max-line-length=127myQueue/--statistics运行结果如下:

pytest单元测试

-name:Testwithpytestrun:|tree-I.gitpipinstall-e.pytest./test--cov-reportterm-missing--cov=./myQueue/-sv运行结果如下:

安装部署包并验证是否安装成功

-name:installmyQueuerun:|pipinstall-e.-name:verifyinstallationrun:|python-c"importmyQueue;print(myQueue.__version__)"运行结果如下:

在充分调研并实践后,我认为无论是GitlabCI还是GitHubActions,其背后的核心宗旨无外乎两点:自动化与标准化。

其次是标准化。既然希望将这部分内容交由机器去完成,那么一方面,为了让机器的执行流程更加高效清晰,另一方面也是为了进一步减轻开发者的编程负担,标准化就显得至关重要了。

这里的标准化有三层含义,首先是执行流程的标准化。无论是GitlabCI还是GithubActions,都利用YAML文件将整个持续集成过程分成了多个阶段,各阶段之间相互独立、顺序执行,从而使得执行流程清晰简明;其次是执行指令的标准化,这一点GitHubActons做的明显要更好些——它将原本一条条原子化的指令进行了进一步封装,构成了一个个action,从而允许开发者彼此之间进行调用,进一步降低了编程负担;最后是执行环境的标准化,比如Gitlab中的Runner,通过在团队之间进行共享,就可以实现统一的运行环境,从而便于最后的集成和部署。

若从需求分析、技术支持与产品实现的角度进行归纳的话,那么CI/CD工具的核心特性可整理如下:

需求分析:许多软件开发团队为了使集成开发的环境、流程做到统一、规范,个人开发者希望实现测试、部署等过程的自动化

技术支持:Docker等虚拟环境技术的成熟,基于web的分布式版本管理技术的推广,yaml工具的出现等

产品实现:GitLabCI/CD、GitHubActions、Travis……

GitLabCI与GitHubActions的系统化优劣对比如下表所示:

当然,应该要认识到很多问题是有两面性的。比如究竟是否应该支持第三方插件这件事,支持的话有助于提升市场开放性和灵活性,但也会出现鱼龙混杂的情况;不支持的话有助于进行统一的管理和优化,但可能缺少足够的个性化服务。

总之,从我个人的角度来看,我会更倾向于使用GitLabCI进行团队项目的集成开发,使用GitHubActions进行个人开源项目的测试部署。

THE END
1.中国梦·践行者放下“金饭碗”她转做竹编匠从“小白”到“熟练工” 建筑系出身的范凌说,自己对待工作喜欢像画画一样“死磕”,尽善尽美是必然的追求,但身体条件让她难以继续保持工作上的“完美”,这让她有点沮丧。竹编的意外出现,让范凌感受到人生转型的可能性。 范凌辞职后,启程“打飞的”去到东阳,找到了何福礼大师所在的东风竹编工艺厂,在那边住了将...https://news.cctv.com/m/a/index.shtml?id=ARTIY8KBoZqwI4kHr8GVJEtR190522
1.车工和熟练车工有什么区别说明:车工和熟练车工哪个工资高?车工低于熟练车工。车工平均工资¥6.0K/月,2024年工资¥6.1K,2024年工资高于2023年,熟练车工平均工资¥7.1K/月,2024年工资¥6.9K,2024年工资低于2023年,统计依赖于各大平台发布的公开数据,系统稳定性会影响客观性,仅供参考。 就业...https://www.jobui.com/gangwei/pk/chegong-shulianchegong/
2.概率的定义及其运算于是3名熟练工分配在同一班组的分法共有3*9!/1!4!4!种,从而所求概率为 P2=(3*9!/1!4!4!>/(12!/1!4!4!>=3/55~0.0545 1.2.5几何概率 定义1.5 设样本空间有一个有限区域W .若样本点落在W内的任何区域G中的事件A的概率与区域G的测度(或长度和面积或体积等>成正比,则区域W内任意地点落在区域...https://m.360docs.net/doc/ed568086.html
3.长期临时工管理办法有哪些内容六、临时工的晋级及待遇 根据所从事工种和技术要求的不同,临时工主要分为分选用工、加工用工和质检用工三部分,分别加以规定。 加工工段用工 加工工段用工分为五个发展阶段:试用工——合格工——熟练工——辅助工——管理工,每个发展阶段对应不同的待遇。 https://www.64365.com/zs/704298.aspx
4.多能工管理制度(精选8篇)为了迅速地适应生产需求变化,开阔员工的工作视野,鼓励员工的掌握多种生产技能。特制订以下制度: 多能工定义 多能工:具有操作多种机器设备的能力或具备进行其它生产组别工作知识满足其他生产组作业资格,并能熟练操作本组内所有工序的作业人员。 多能工的管理: ...https://www.360wenmi.com/f/file6bkxft6a.html
5.标准工时定义一.标准工时定义: 在适宜的操作条件下用最合适的操作方法普通熟练工人以正常速度完成某项工作所需要的时间. 二.标准工时的用途: 1确定作业者的工作量 2确定作业者的操作机台数. 3作业者之间的工作量平衡. 4作业者的效率评定. 6制订周计划https://m.renrendoc.com/paper/178901206.html
6.流水线工人的岗位职责流水线工人的工资多少→MAIGOO知识流水线工作的定义 1、对工作任务进行简化; 2、明确的劳动分工; 3、尽量用设备代替服务员的工作; 4、建立系统的服务制度和工作内容,并使之标准化; 5、使服务员工决策权尽量减少。 流水工作的优点 具有高效率、低成本、有章可循,工作内容标准化,工作方式制度化,易于熟练掌握工作方法,工作质量高,比较容易培训员工。https://www.maigoo.com/goomai/224396.html
7.“春风送温暖就业送真情”2022年春风行动招聘会2022年2月7日...8、二氧化碳气体保护焊工3-5名,要求熟练工,具有液压支架焊接经验的优先录用,月工资6000-9000元。 9、铆工1-2名,要求看懂液压支架结构件图纸,能熟练拼焊,月工资6000-10000元。 8小时白班工作制,加班费另算,铆焊工工资计件,管吃住,有节假日福利。 公司地址: 武陟县南贾工业区 ...https://wzjob.jzggjy.com/news/detail/301772.html
8.2023年8月淮北高新区园区企业招聘简章汇总●三班两转,每月综合上班20天,熟练挡车工正常上岗工资在3000元到5000元之间;两班倒,全月满勤,达到定额挡台和产量标准,工资5500--6500元,超定额挡台,产量达标可达7000元以上。 ●辅助工根据岗位和工作天数不同,工资在2500—5500元之间。 ●每月20号发工资,直接打入银行卡。 https://www.huaibei.gov.cn/xwzx/gsgg/jye/62986845.html
9.沃尔沃(VOLVO)验厂资料:供应商审核清单2.1.10 对于防错和防误防错的措施,需要有书面文件和有效性测试以及定义预防性持续计划 2.1.11 设置规范化的操作指导书(包括控制计划、工艺指导书、作业支持、检查表、作业设置指令和插图),使操作工在工作现场可以看到,并按照指导书所写的操作。指导书必须是可读的、特定的和可控制的。 https://www.yoojia.com/article/10146643379684958469.html
10.英语二课后重点句子翻译(共3篇)5、技术与劳动分工在许多领域结束了对熟练工的需要 workers1、他不情愿从事这项工作 Hewasreluctanttoundertakethework 2、一个人的外貌和他的品质常常不一致 3、这个男孩喜欢集邮 Theboylikestampcollecting 4、雨迫使我们停赛 TheraincompelledustoasuspensionOne'sappearancedoesnotoftencoincidewithhisqualityTechnologyand...https://www.oh100.com/a/201607/468268319434.html
11.这些超火的Vue组件你还没有用过吗?本文这些 Vue 组件,不论对于 Vue 初学者还是使用 Vue 的熟练工,都是具有很高使用价值的组件,对你的 Vue 之路一定很有帮助。 此前Vue 发布了 3.0 的 beta 版本,昨晚的直播中项目核心开发者尤雨溪公开分享了关于该版本的相关信息。 首先,beta 阶段意味着: ...https://www.51cto.com/article/615023.html
12.整车厂柔性化产线精益生产研究可能,对于熟练工的定义会有些争议,但一般来讲,精益生产的工作是循序渐进的,对于新工厂、新产线投产以后的3个月,我们可以进行第一轮的精益革新和效率提升,而通过这3 个月的操作实践,生产线上的工人对于工艺操作一般也相对熟练了。当然,对于熟练工的定义,在项目投产阶段,可以由技能工来担当,通过不断的操作练习,以...https://www.fx361.com/page/2023/0211/17744478.shtml
13.操作工年度个人总结范文(精选11篇)做一个机修工,应对自己的工作认识清晰,熟悉和熟练自己的工作。要有对所有机器设备的了解,也要有对发生故障的应变能力,处理好随时可能发生的设备故障。效率的完成自己的本职工作,也能使我们单位获得最大的效益,这样我的工作和工人的收获的也能达到一个平衡,使我更加有动力,更有自信的工作。 https://www.ruiwen.com/zongjie/6386687.html
14.《代码整洁之道程序员的职业素养》(读书笔记)学校能够传授的是计算机编程的理论。但是学校并不会也无法传授作为一名编程匠者所需掌握的原则,实践和技能。这些东西只有经由师徒个体间多年的细心监督和辅导才能获得。 对新人的培养的辅导非常重要 学徒/实习生–>熟练工(5年左右)–>大师(10年以上)。大师就像星际迷航中的Scotty。https://blog.csdn.net/qmhball/article/details/86478338
15.劳动力短缺的原因范文2.新生代农民工比重加大。当前劳动力市场结构呈现出明显的年轻化倾向,“第二代”打工者约占新求职人群的80%。除工资薪酬外,他们更加注重对职业前景的选择,对就业环境要求高,并且对城市生活方式有更高的期望。 3.普工短缺占大部分。2004年的农民工短缺表现为熟练工、技工短缺,尤其是高级工严重缺乏。2010年开始的农...https://www.haoqikan.com/haowen/52831.html
16.泉州台商投资区2020年“春风行动”暨企业用工线上招聘活动招聘①培训工②熟练工 6 成型工 50 3000-6000 ①培训工②熟练工 7 手工 20 3000-5000 ①培训工②熟练工 泉州路桥翔通建材有限公司 联系人: 徐经理 联系电话: 0595-87591638 地址:泉州台商投资区百崎乡加坑路口 序号 岗位名称 人数 工资待遇 岗位要求 1 清扫驾驶员 1 4000-5500 B2 以上驾 证、驾龄...https://www.hxrc.com/zpgg/168216a/TSCFXD2020/main.htm