比赛中的软件工程-读《代码中的软件工程》有感

前言

简介:
博主是一名“科憨”,研一下选修了孟宁老师的《高级软件工程》,原以为这门课是像考研政治一样的“背诵课”,但随着学习的逐渐深入,愈发发觉自己先入为主的无知,这门课之实用性超乎了我的想象,再结合最近一直在打的比赛(4个人团队的AI赛)经历,简直是感慨颇多,其中数个时刻简直犹如雷霆万钧,发人深省。接下来,主要以我个人的比赛经历结合所学进行阐述,实打实的切身体会,如有不足,望多海涵。

贴一下封面图和对自己比较有启发的内容图。
《代码中的软件工程》

内容概览

正文

1. Git大法好

相信大家多多少少也都参加过比赛,应该都有版本快速迭代而带来诸多烦恼的经历,比方说在更新(炼丹)了几次模型参数后,发现甚至不如初始参数的效果好,这个时候就又得费劲巴拉的想初始参数是什么才能回到原点;又比方说,如下图所示,为了尝试更多的可能性,我们对一个文件不断的进行复制,而复制后在文件上做的修改却是微乎其微的(比如调参),这其实很浪费我们的磁盘空间。
为了做一些微乎其微的修改又想保留一些版本而复制的大量雷同的文件

这时,就轮到Git这种版本控制利器大显身手了。实话实说,在上课之前,作为一名卑微计算机学生,也曾在GitHub上down过代码,但那时并不知道Git到底有何作用,直至接触了高软这门课,不仅学会了Git的基础操作(本地或远程),甚至还了解了Git的基本原理,现在的我,只需两三行简单命令,就不必再担心文件覆盖、各种文件找不到的问题了。
下图展示了一下比赛中的团队仓库,由于队员的个人隐私,这里仅展示了我个人的分支,另外比赛还没结束所以对一些信息进行了打码。

团队仓库个人分支展示
像Git这种工具,真的只能说是“难者不会,会者不难”,这里贴一张Git的原理图,相信“懂哥”们一看就会会心一笑,如果不会的话墙裂建议各位去看看孟老师的书(第二章就是),真的是深入浅出,结合实际。
Git原理图概览

1.1 创建版本库

git init
git clone 

1.2 查看当前工作区(workspace)的状态

git status

1.3 把文件添加到暂存区(index)

git add 

1.4 把暂存区里的文件提交到仓库

git commit -m "wrote a commit log infro” 

1.5 查看当前HEAD之前的提交记录,便于回到过去

git log

1.6 回退

git reset —hard HEAD^^/HEAD~100/commit-id/commit-id的头几个字符 

1.7 可以查看当前HEAD之后的提交记录,便于回到未来

git reflog 

1.8 下载一个远程存储库数据对象等信息到本地存储库

git fetch

1.9 将本地存储库的相关数据对象更新到远程存储库

git push

1.10 从其他存储库或分支抓取并合并到当前存储库的当前分支

git pull

1.11 为自己的工作创建一个分支,该分支应该只负责单一功能模块或代码模块的版本控制

git checkout -b mybranch
git branch

1.12 先切换回master分支,将远程origin/master同步最新到本地存储库,再合并mybranch到master分支,推送到远程origin/master之后即完成了一项开发工作

git checkout master
git pull
git merge --no-ff mybranch
git push

2. 通关正则表达式

相信很多小伙伴会被本科期间学习正则表达式时的痛苦支配一生,尤其是要考Linux和python两门课的小伙伴(博主就是这两门课都要考的“大冤种”),应该饱受正则表达式的折磨,如有此类经历,建议好好康康孟老师的 《正则表达式十步通关》(书中第三章),反正博主是被这十步治愈了一生,对孟老师简直是感激涕零。
详细的知识点这里就不多赘述了,这里谈谈这一章对我们比赛的影响,管中窥豹,可见一斑,诸位可以通过接下来学习前后的对比,深刻感受我对孟老师的感激之情。
先简介一下任务,如图所示,官方每天会以CSV文件的形式发布分数及排名,文件中的分数排名仅为当天得分排名,需从这样的文件中提取我们团队的真实分数(官方给了一个参考公式),进而累计计算得到我们当前的真实排名。
在这里插入图片描述
由于这里的Score是以字符串形式存储的,这时正则式表达式就派上了大用场,下面是学习前:
吐槽:他甚至为此专门写了个函数,他真的,我哭死。
在这里插入图片描述
而事实上,这里只需要:
在这里插入图片描述
两者的效果虽然是一样的,但第二种明显更简单,更聚合一点。

3. 接口-外部接口本地化

其实上述一些函数已经实现接口这一概念,但是这里想重点说的是,因为我们的比赛工程是比较小的,大家要共享自己的函数供他人使用时,其实是不需要再定义一个外部接口的,毕竟大多数实现的功能就一二十行的代码,可能两分钟就看完了,所以在我们的比赛过程中,我们更倾向于定义好接口,这其中包括接口的名称,接口的输入,接口的输出;接口的名称需要直白的显示接口的作用,而接口的输入输出则需要关注项目本身的需求。举个例子,在DataFram的操作中有的是需要原地修改表单的,但有时我不希望函数对我的原表单进行修改,只希望你返回的是副本,这就产生了一些代码上的差异,但其实这只需要队员之间提前沟通好即可。
但当我看到外部接口这一概念时,不禁引起了我的种种反思,现在是我们队员各负责一个方案,有些通用函数,我们可以通过定义接口的形式实现公用,但在后期,如果我们需要简洁的调用不同方案中的模型,这种比一个函数功能更复杂的任务来临时,我们又能否仅仅通过一两个函数就完成任务呢?这着实令人担忧。

4. 回调函数

说实话,在学习这个概念之前,“回调函数”对我来说只是一个陌生名词,Seriese.apply()对我来说也只是一个黑箱,但当我学到回调函数,我脑中竟然奇妙的将这两者自动的连接了起来,在后面编写代码时,我也能更大胆的应用apply函数,在知道了黑箱的原理后,我的体会是更加安心,更加“随心所欲不逾矩”。

4.1 回调函数概念

回调函数是一个面向过程的概念,是代码执行过程的一种特殊流程。回调函数就是一个通过函数指针调用的函数。把函数的指针(地址)作为参数传递给另一个函数,当这个指针调用其所指向的函数时,就称这是回调函数。回调函数不是该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

4.2 回调函数用法举例

在这里插入图片描述

5. 唯一不变的就是变化本身

想必大家在比赛时也都有过赛方突然更改赛题的经历,虽然是微小改动,但对我们这种没有接受过系统软件工程培训的小团队(据我所知4个人中只有我有《高级软件工程》这门课)来说,这无疑是灭顶之灾。本次我们遇到的问题就是赛方更改了数据格式,这意味着我们从数据处理到模型预测,乃至生成提交结果的代码都需要进行改动,当然最后我们是熬过来了,但在这个过程中,我无数次的认识到解耦合的重要性,也不断的后悔着,为什么没有在最初时做好结构上的设计,那段暗无天日的重构时光给我上了刻骨铭心的一课,当我听到孟老师说出那句“唯一不变的就是变化本身”时,我霎时间泪眼婆娑,而那时我已不知那是懊恼悔恨或是无比认同的泪水。

6. 团队合作

书中后半部分有数章讲解了团队合作的事项,对我们而已也有借鉴启发作用,比如说,共同参加比赛的队员们自然是有相同的目标,可是由于没有及时的反馈,亦或是没有更加清晰、的任务分配,队员们总是感觉到在孤军奋战,难以形成凝聚力,4个人的团队亦是如此,更何况数百人的公司,这固然是一节软件工程课,但我想这亦是一堂具有人生指导意义的课。

后记

书已至此,比赛的个中心酸不再赘述,诸如“理论指导实践”的说教也不再废言,唯有劝解同行或后来人好好体会软件工程,以免撞了南墙才恍悟,代码如此,生活亦如此,很多事情总是天不遂人愿,太多变数不是你我能够掌控的,我们大多时候只能做好应对变化的准备,之后待到变数降临时,坦然的对朋友们说一句,“是的,唯一不变的总是变化本身”。

参考资料

《代码中的软件工程》 https://gitee.com/mengning997/se

作者 389

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值