OOhw12——第三单元博客作业

李林泽-24371041 2026-05-29 10:59:46

说实话,第三单元真的是目前最简单的一个单元了,接下来我首先说一下我对JML和规格驱动开发的理解。

1.JML

在完成了这三次作业之后,我对JML最突出的感受就是在某些几个字就可以说请的问题上,JML要花一大堆篇幅,看半天才能看懂,比如说hw11中的recommendNthUp方法,我看了很多遍才看懂是“排第几”的意思。

/*@ public normal_behavior
      @ requires containsUser(userId) && rank > 0 && videos.length > 0 &&
      @          (\num_of int i; 0 <= i && i < users.length; users[i].getId() != userId && !getUser(userId).isFollowing(users[i])) >= rank;
      @ assignable \nothing;
      @ ensures containsUser(\result) && \result != userId && !getUser(userId).isFollowing(getUser(\result));
      @ ensures (\num_of int i; 0 <= i && i < users.length;
      @           users[i].getId() != userId && !getUser(userId).isFollowing(users[i]) &&
      @           (getUser(userId).computeUpScore(users[i], videos.length) > getUser(userId).computeUpScore(getUser(\result), videos.length) ||
      @            (getUser(userId).computeUpScore(users[i], videos.length) == getUser(userId).computeUpScore(getUser(\result), videos.length)) &&
      @             users[i].getId() < \result))) == rank - 1;

相对于我们习惯的自然语言,JML在描述一些要求时非常的复杂,很绕。但是在看懂之后可以发现它非常严谨,且相对于自然语言更贴近代码实现,具体而言,在看懂上面的JML之后我要在函数里写什么几乎呼之欲出了。首先是根据ensures的第3,4行构建比较方法,然后因为\result的限制条件(非参数本人或关注者)与下面的users[i]相同,所以就是要在这个限制条件下找出一个user,条件是按照这个计较方法排序的第n个。

另一方面,JML非常适合用来进行Junit测试,因为已经将所有需要检测的点一行行列出来了,在编写Junit时几乎就是一行行进行检测。

2.Junit

在这三次作业中,我中测全都是代码本体一遍过,但Junit提交了五六次才过,可以说就完成而言比JML实现困难很多。

在这些测试中,我感觉频繁出错的点有两个:一个就是关于assignable的检测,因为随着属性多起来,在检测的时候容易测得不全面;另一个就是极限情况,就是错误函数虽然在大多数情况下符合ensures,但是像空串、0这样的特殊情况很容易实现错误,也就是说对于某些特别的输入要专门检测。

3.迭代中的性能分析

有关已有方法/容器在迭代中的变化,我直接将前后两版JML规格交给AI来实现。

客观而言,很多次我是在看到强测结果时发现了程序的性能问题。所以从hw10开始我对于每个方法力求做到效率最高,对于每个容器都查看一边设计的操作,并选择最快的容器。比如对于维护user,video的容器,因为保证每个对象有唯一确定的标识id,且会频繁通过id查询对象,因此Map最合理。

4.bug总结

除了性能不足导致的超时之外,我的bug主要是边界情况的特判。具体而言,我在hw10的Video.cleanSpamComments方法中使用了KMP算法,但是没有对空串进行特判。

5.JML开发

在Unit3第二次研讨课上进行了一个JML“击鼓传花”游戏,基本上在过程中每一步我都会发现bug(包括我自己写的),下面举出几个印象深刻的例子。
我在第一次写JML时忘记写public exception_behavior了,我写完之后还在那看着别人发呆,传出去之后才意识到,太尴尬了,给我留下了巨大的心理创伤。

我写的第二个自然语言描述就发现我看到的JML绝对不是第一个人(设计者的本意),首先是返回一个容器却只保证了在里面的元素都满足条件,没有写满足条件的元素都在结果里,这样的话全部返回空串完美符合JML,然后就是没有对重复元素行为做出保证,导致出现了未定义行为。

然后最明显的就是我检查的那一份,前面几棒是正确的,但是再把自然语言转化为JML时就出现了问题,就是我在研讨课上进行的发言,JML没有严格“距离”与“最小距离”,只判断了“有距离为一的边”,导致遗漏了大部分结果。

我认为在今后的组队编程中,可以让提出需求的人同时给出NL和JML要求,实现者确保二者表达的是一个意思后在开始设计,如果感觉二者并不是一个意思就找到了二者理解的偏差点,从而在编程前明确需求。至于减少信息差,我认为最好的方法是在二者总结好需求文档可能的问题后直接视频解决,然后开始实现。

...全文
20 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
【更新至2025年】2001-2025年上市公司数字化转型年报词频统计(吴非、赵宸宇、甄红线)(300+年报词频统计) 1、时间:2001-2025年 2、来源:上市公司年报 3、参考文献:企业数字化转型与资本市场表现——来自股票流动性的经验证据(吴非) 数字化转型如何影响企业全要素生产率(赵宸宇) 知识产权行政保护与企业数字化转型(甄红线) 4、方法说明:(1)参考吴非老师的做法,对人工智能技术、大数据技术、云计算技术、区块链技术、数字技术运用五个维度76个数字化相关词频进行统计 (2)参考赵宸宇老师的做法,对数字技术应用、互联网商业模式、智能制造、现代信息系统四个维度99个数字化相关词频进行统计 (3)参考甄红线老师的做法,对技术分类、组织赋能、数字化应用等类别下139个数字化相关词频进行统计 5、指标:年份、股票代码、公司简称、行业名称、行业代码、全文-文本总长度、仅中英文-文本总长度、人工智能技术-吴、大数据技术-吴、云计算技术-吴、区块链技术-吴、数字技术运用-吴、数字技术应用-赵、互联网商业模式-赵、智能制造-赵、现代信息系统-赵、技术分类-人工智能技术-甄、技术分类-区块链技术-甄、技术分类-云计算技术-甄、技术分类-大数据技术-甄、组织赋能-人工智能技术-甄、组织赋能-云计算技术-甄、组织赋能-大数据技术-甄、组织赋能-广义数字技术-甄、数字化应用-技术创新-甄、数字化应用-流程创新-甄、数字化应用-业务创新-甄、人工智能、商业智能、图像理解、投资决策辅助系统、智能数据分析、智能机器人、机器学习、深度学习、语义搜索、生物识别技术、人脸识别、语音识别、身份验证、自动驾驶、自然语言处理、大数据、数据挖掘、文本挖掘、数据可视化、异构数据、征信、增强现实、混合现实、虚拟现实、云计算、流计算、图计算、内存计算、多方安全计算、类脑计算、绿色计算、认知计算等300+词频

307

社区成员

发帖
与我相关
我的任务
社区描述
2026年北航面向对象设计与构造
java 高校
社区管理员
  • 孙琦航
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧