学习构建之法(2):课程总结

 

 

年底、期末,在繁忙之中,我和我的团队完成了“微学堂”这一产品。伴随着它的交付,《软件工程》结课了。我现在是本科三年级,两年半以来修了五十多门课,应该说这一门是挑战度最高的。最后几周,不时有通知“下周的课不上了,各个小组自己做团队项目”:相对于课堂听讲,课外需要付出的精力之多,由此可见。

即使以代码行数衡量并不是,我感觉这个团队项目是我经历过的规模最大的项目,大到另我有无法驾驭的恐慌。不过这样说也不公平,这种“out of hand”的感受不仅来自这个项目本身,也有来自其他课程、辅修专业、社会工作等等带来的压力。然而话说回来,我直观上的感受就是,作为组长我不清楚每一个组员都具体做了什么、用什么方法做的。不可能有一人 review 每一段代码;不可能有一人了解项目中的全部实现细节;更不可能凭一人之力完成。

与此相比,此前的和本学期其他的“大作业”都只是小打小闹。不点名提及这学期的某些课程的某些 Project:一人花几个小时就做完,好意思说它是 Project?顶多算个 Assignment 好吧。如果把这些都算上,那么我这学期可能做了 20 个大作业,恩,说出来挺唬人(划掉)。

 

Donald Knuth 有一句名言:过早优化是万恶之源。项目中还存在一些过度设计的问题。其实这些词我都不是很懂,通过这个团队项目,只是感觉对此有了一些浅薄的理解。

中途出现的需求变更对我们造成了不利影响——来自教师的一条非功能性需求:我们被要求使用另一小组提供的 API 服务,而非自己编写相关模块。为了保证进度,我没有选择重构,而是把这个 API 服务做了一层包装,以保持接口不变而替换原有模块。这带来了架构上的冗余和“不优雅”。

这里所说的模块是一组爬虫。爬虫总有个运行频率的限度,而用户总是希望得到最新的信息,而且希望在最短时间内得到最新的信息。针对这一矛盾,我们设计了后台定时触发的“自动刷新”和用户手动触发的“强制刷新”这两种不同的刷新,同一个接口设计同步和异步两种调用方法。结果,因为他们 API 服务没能支持,全都白费功夫啦。

值得一提的是,做 API 服务的那组同学似乎并没有考虑运行频率的限度的问题。他们对爬虫的目标,也就是我校网络学堂和综合教务系统,发起高频次、高并发的请求,形成 DoS 攻击,造成网络学堂压力过大、反复宕机。运行着他们 API 服务的那台服务器,其 IP 被学校封禁。不巧的是,该台服务器是由我管理的。简言之,我因为他们被查水表了……这导致我不得不花大量的精力来与上级管理人员沟通,撰写需要同时抄送给三四个单位的整改报告——这影响了我们的进度。

我们在最初设计时,在安全性上花了很多精力。我们使用 OAuth,我们使用 https,避免用户信息的泄露。实现时,微信公众平台 OAuth 那一套牵扯了我们更多的精力:除代码编写外,开发环境搭建、调试、测试等方方面面都有复杂性的增加。结果呢,直到最后,我们的上游,也就是上文提及的 API 服务,也没有实现任何对调用者身份的验证。数据全部明文传输。他们的 mongodb 数据库甚至不设密码,直接暴露在外(这也是上文提及我被查水表的原因之一,原话是“存在高危安全隐患”)。

只要有一环出了问题,整个安全链条就会断掉。API 组糟糕的安全性意味着我们的用户的一切信息都会被公开在国际互联网上,也就意味着我们在安全性上的努力全部白费——除了在文档中写上一笔,期盼因此获得作业成绩的加分。好气啊!

 

花了这么多篇幅吐槽 API 组。我们自己得到的教训是:应该循序渐进。特别是在敏捷的语境下,不能一开始就想着搞出完美的设计“一步到位”,不能指望一开始就把所有细节都考虑周全。一开始最好是设计得简单些,keep it simple and stupid,在反复迭代中进行改进,边写边重构。

通过这个项目,团队管理上的经验也积累了不少。把一个团队带好,这是非常困难的,我一直觉得我在这方面没有缺少天赋,适合埋头干活,而不是做一个管理者。这回做组长,让我在这方面增加了一些经验,也增加了一些自信(笑)。具体的经验可以列一些,比如重要的事情不能只口头说——在微信群里说也算“口头”——要形成文档,形成书面的东西。

 

最后说回这个课程本身吧。除了做项目的锻炼之外,通过课堂讲授,我的理论水平也得到了提高——SC、CC、MCC、CDC 等度量测试覆盖的一堆词儿;系统的 actor、stakeholder,UML 状态图、顺序图、活动图,用户故事、用例建模,需求工程的那一套理论;接触了几种设计模式;关于团队、流程一些成熟经验……作为一门工科专业课,竟也有了一分管理学的味道。

建议就没什么了,各方面都挺好的。只有一条,那就是一组来搞 API、其他组使用的这种玩法,估计明年不会再搞了吧(逃)

 

这是《软件工程》课程系列博客的最后一篇。
相关文章:
学习构建之法(1):写个微信抢票
django 性能调优手记
“结对编程”初体验

3 thoughts on “学习构建之法(2):课程总结”

  1. 》做 API 服务的那组同学似乎并没有考虑运行频率的限度的问题。他们对爬虫的目标,也就是我校网络学堂和综合教务系统,发起高频次、高并发的请求,形成 DoS 攻击

    老师/助教和同学没有对API 服务的设计提出意见么? 在实践中, 这种失误算是项目失败,员工被解雇的等级。

发表评论

电子邮件地址不会被公开。 必填项已用*标注