- Published on
Hofstadter's Law 的深刻教训
- Authors
- Name
- NorthSecond
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
在26小时极限三门考试交代掉十个学分之后,算是终于有时间总结一下混乱的22年末23年初和混乱的大作业们了。虽然每次回家之后都会被几个大作业催命一段时间,但是像这次一样直接杀到腊月三十的还是第一次。总体上说呢,完全就是侯世达定律(Hofstadter's Law)发威,对自己出现了错误的估计,最后导致悲剧的发生。
在上学期末刚从 hacker-laws 仓库 中了解到这些所谓的定律的时候,其实对于侯世达定律还是多少有点不太理解的,尤其是那一句
It always takes longer than you expect, even when you take into account Hofstadter's Law.
当时一直没明白这是什么意思,直到中级实训和 Rust 大作业,现实给我扎扎实实上了一课属于是。
当然首先还是要感谢各科大作业延期的老师的,要是都像刚刚布置的时候全部堆在学期内的话,我可能要肝到吐血而亡。按完成顺序 (DDL) 排序,一个一个讲吧。
初级实训&数据库:可控摆烂,适当速成
我发现我自己是真的没有写前端尤其是界面的天赋,想得又多是又懒得一点点地蒋公操作。所以当发现数据库大作业和初级实训撞题并且要求还没有初级实训高的时候我自然是开心的——毕竟这种我个人感觉没啥意思的界面程序写一个对我来说就已经是够够的了,刚开始数据库还没说可以用其他编程语言写的时候我甚至已经做好了前后端分离后端就用 Rust 写前端分别按照要求用 Qt/C# 写界面的打算了。不过后面还好说是可以用 Qt 一路梭到底,那也不折腾前后端分离了,直接写个数据库代理当后端得了。
但是大作业的进度始终没有自己想象中的那么好。在学校的时候这个大作业的进度基本上都是在数据库的实验课赶出来的,代码质量只能突出一个粗制滥造。初级实训的 DDL 是 1 月 6 日,回家本想速战速决在2022年把这个大作业一波写完算了,结果在圣诞节不幸阳了……而且症状多少有点严重,虽然躺床上也在写初级实训和中级实训的代码,但是确实产出的代码质量实在太差,最后发现这段时间写的代码其实没留多少下来。
等到跨过阳历年之后,身体稍微好一点,才开始认真写这些大作业。当然这时距离最终的 DDL 已经只有三四天了,我面对的是一个我自己都不知道能不能跑的半成品,于是我决定两头同时写起——在此之前我相当于是自底向上的设计,在确定我需要哪些功能之后先做数据库的代理类和业务逻辑类,这样做的好处就是层次性会强一点,代码质量也好一点。但是最后为了赶时间,我选择了再写完大致的层次和业务逻辑之后先去把界面搞出来,然后再调整后面的业务逻辑。于是找了一天良辰吉日,平板随便放了个纪录片当背景音乐,从下午三点到凌晨五点,十四个小时搞了四千多行代码出来,终于把这个加起来差不多八千行的破玩意肝完了。然后也懒得改/优化界面了,测试了一下这样没啥问题之后直接在 1.6 去初级实训做了展示,还差一点点忘了交数据库。赶工出来的粗制滥造成品自然也不会有特别好的效果,数据库实验成绩还没出来不知道什么情况,反正初级实训一跃成为已出成绩的科目里面的最低绩点 长江后浪推前浪,项目能力比不过学弟学妹们了啊ww。
其实没啥说的,可控摆烂了属于是,毕竟当时刚刚在床上躺尸了一周多,一直提不起劲来,纯粹属于没办法了。
算法:阳着的唯一正经学习
算法大作业是我写的最轻松的一个大作业了,大部分内容其实都是阳的时候写的。当时日常躺尸日夜颠倒,睡一会醒一会,除了大作业不得不干之外也不想干啥事情,于是真·头脑发热连着打了几场 CF,然后算法的题和代码就有了(bushi。
之后就是在中级实训写完之后翻了翻自己打过的那几场 CF ,挑了几道介于自己做出来和没做出来之间的题,做出来的题优化了一下可读性,没做出来的补了一下,然后就交了2333333。不过虽然自己写文档的时候是轻松愉快的,当时打比赛还是花了不少精力做题补题的,最后结果也算是不错,大作业本身的内容和质量也是能够让我自己满意的。
源代码分析:感谢在校的自己
作为小组作业,源代码分析大作业好一点是大家能够相互分个工,读完论文之后我就负责且只负责搞懂论文对应的代码并且成功复现了。
放假之前在学校很多事情的时候我就决定先写源代码分析和中级实训了,于是在校花了几天时间完整配置了一遍环境,写了个 Docker File(PA-Datalog 不向前兼容18.04之后的 Ubuntu 系统是我没想到的,在这里卡了好长时间),然后发现全跑一遍需要的连续运行时间太长本机吃不消,于是又去 AutoDL 搞了个入门款的服务器用了两天,但因为实例本身就是 Docker 所以没法跑 Docker 环境,于是又被逼无奈在 miniconda3 下面配置了一次环境,算是顺利地跑通了。
然后在家就是总结了,总结研究代码的时候研究出的代码结果,上传 DockerFile 再把自己的两次环境配置过程写成 Readme 文档。最后再在提交之前排个版检查一下格式提交一下,这个大作业在学校花了两三天时间但是最后提交之前在家就花了半天多时间,体验不错。
P.S. 最后出了一个坑队友行为,提交之后助教联系我们说我们压缩包里面文件乱码了,当时还不知道为什么觉得很玄学然后就让同学帮忙重新打包提交了,直到前两天整理系统卸载各个程序的时候才想到我电脑开了全局强制 Unicode 编码,单文件和其他电脑互传没啥影响但是会影响压缩包内文件名在彼此电脑上的显示……希望没有坑到……
中级实训:这位更是重量寄
中级实训是我本学期体验最差的大作业,没有之一……
毕竟是一个人写完了后端+数据库,想总结复盘相对来说还是比较容易的。我的中级实训可以形容为:前期勉强凑合,中期完全垮掉,后期缝缝补补。
前面在学校里搞好了框架搭建和接口暴露这些基本工作,信心满满感觉给自己两天时间就能搞定后面的这些接口和业务——“不就是CURD嘛”,然后我就华丽丽地被教做人了。突出一个写不动,总是遇到一些各种各样的细节问题,然后本来打算两天写完的接口,硬生生从十一月底拖到了提前回家。
回家之后就是在躺尸的时候大批量的做接口的实现,当时感觉自己中级实训写的还特有感觉,莫名觉得自己又行了,然鹅等到写的差不多(也好的差不多)开始和前端对接测试的时候才发现自己写的东西好像不太对劲……测一个接口挂一个接口……然后回过去看自己当时写的都是些啥……
之后就开始和回调地狱搏斗,因为 Ts 和 Express 框架毕竟不是很熟,中间也是各种遇到奇奇怪怪的问题,不过好歹算是勉强能跑了。能跑之后又发现了更多的问题……然后就是安吉不停地给我报Bug,我不停地发现各种傻逼低级失误debug……然后原定一天的工作量能拖到两三天(真对不起安吉,过于坑了属于是),真的是在不停的因为各种原因延后预定的时间,这也就是我说被侯世达定律教训的由来……
这个故事告诉我们,感觉不对劲的时候就不要硬写bug了,不然后面debug会花比重新开发更长的时间。另外 Hofstadter's Law 真就客观真理了属于是,学到了学到了。不过万幸最终好歹算是跑起来了,文档和展示做的不错 (除了我录展示视频的时候说入口点的type文件没搞出来所以没法 ts-node
直接run后端而是要先 tsc
编译一下然后 node
跑,录完之后半小时我就写出来了之外) ,属于是被实践经验上了一课。
这是我花的时间最长,精力最多的一个大作业,但是确实是最不满意的……只能说距离自己理想的代码能力还有很长的路要走啊。
Rust:心比天高,命比纸薄
作为一个大作业在腊月三十的大作业,Rust无疑是最特殊的那一个。
五个刚刚被中级实训打击过的心比天高的同学聚在一起,决定使用一门自己压根谈不上熟悉的技术栈和语言整个大活,此时距离 DDL 还有屈指可数的几天时间。
当立起来上面这些 Flag 之后,剩下的问题便是毫无悬念了—— Flag 毫无悬念地倒了。
其实刚开始还好,大家拉个会议分一下工,在决定用现成前端之后甚至一度富裕到我无事可做,于是就去搞基础设施建设,研究题库和前后端交互。但是到腊月二十九感觉就不对劲了,大家进度好像没有想象中那么快,在各个地方都遇到了奇奇怪怪的问题。然后我就成救火队员了,哪里不通我就去那里 handle 一下,前后端联调一下看看哪里和人家现成的 OJ 返回值不符的。
其实在廿九晚上感觉还好,肝一肝对在三十中午彻底搞定还是有一定信心的。三十早上才发现问题的严重性,在调通问题显示之后很多从前没有暴露出来的问题全部暴露出来了,其他同学也是各种有事情响应没有想象中那么快了,到中午之后坚守的人越来越少,最后我把前后端调通了,悦东把judge搞定之后就直接交了,好险没赶上年夜饭……
只能说大家心比天高命比纸薄了属于是,侯世达定律再一次显灵,感谢给力的队友和24h交了36个commit的自己让我吃上年夜饭看上春晚。
至于其他杂七杂八的大小作业就不提了,都是已经过去的事情了。总而言之呢,上学期这波大作业某种程度上也是让我感受到了自己距离先进生产力的差距,自己写代码的水平没有想象中那么好,算法水平和抗压能力还得练~
慢慢来吧,反正不打算本科就就业,没事(希望我的GPA允许我能够没事吧hhhhhh)多敲敲代码总是好的,今天距离高考刚好还有100天,三年前的今天我可能完全想象不到不到现在在这所城市,是现在这样的状态。不过上大学之后总的来说还是在不断向前的,希望在可以遇见的未来还能保持这种乐观和斗志继续前进吧。