• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

第二阶段总结

开发技术 开发技术 2周前 (05-02) 8次浏览

第二阶段总结

(1)

题目集四的难度较高,最终也没取得及格的分数。7-1按照类图很快就能明白业务逻辑,需要精通正则表达式的使用,和规范代码的能力。7-2处理日期难度比较传统,给出的类图与常识不符给我造成了一定困扰,但是理解之后我觉得这种代码逻辑简单,写起来也顺风顺水。不过因为我测不出来的阴间bug没能拿到满分7-3没什么难度按题目指引即可。这是最终结果

第二阶段总结

 

题目集5前三题难度很分数都很低,这里不做赘述,7-4考察正则表达式的运用,但是我没有找到方法让正则表达式匹配多行(在线正则表达式的调试网站可以通过)所以遗憾失分,

7-5日期难度也比较传统,这次类设计符合直觉但是逻辑却更复杂。关于逻辑简单重要还是设计合理重要给我带来了新的思考。最终结果如下。

 第二阶段总结

 

 

题目集6前四道题都是一些基础的运用,难度较低,5-6题分别考察了用继承实现多态和用接口实现多态,这引发了我关于抽象的思考。结果如下

 

 第二阶段总结

 

 

(2)设计与分析

 

题目集4 7-2题目集5 7-4的对比

题目集4 7-2的聚合设计是日管理月,月管理年,然后在套个管理类,这样的设计显然不符合直觉(年月日没有逻辑上的联系)。而不符合直觉的代码就是不“优雅”的代码,这种代码更难理解。但是年的变化可以理解为月变化导致的,而月的变化是日导致的,也就是说日的变化可以直接传导到年,月和年直接耦合也让涉及闰年的操作更加简洁,整体代码逻辑更简单,虽然在总体上(年月日的实体)设计不符合直觉,但是在局部(改变的传递)却符合直觉,这种设计意外的简化了代码,由图可见代码的分支是比较少的。

 第二阶段总结第二阶段总结

 

 

 

题目集5 7-4的类图如下

很明显可以看出这种聚合设计更加符合默认的心理预期,也更科学,年月日互不相关并且统一由日期管理,不过缺点就是所有的逻辑代码几乎都集中在dateutil类当中,这实际上让实现代码变得不那么清晰,编写也比较困难,年月日的功能都比较单纯(比如为了减少耦合,最后一天日期加一天不能在day类里面实现,而是在dateutil里实现,daymonthyear里面的逻辑都要集中在dateutil有点蛋疼)

题目集47-3)、题目集67-57-6)的对比

题目集47-3)的设计思路是最简单的,把shape做抽象基类,其他的类都从shape,生,并且通过基类来调用子类。这种方法最直接,也最容易想到,实现也比较容易。按照题目要求很快就能写出来。但是在实际运用的过程中我发现,这样做还有很多缺点,首先继承的耦合性太强,一旦实现之后,如果后来需要在基类上添加功能将变得十分困难,尤其是继承的层数,子类很多的时候,要改变基类简直如履薄冰,而且父类的功能可能并不是子类必须的甚至是不该有的,基类太脆弱了。并且因为java是单继承的语言,利用基类来实现功能会占用宝贵的父类名额,不利于扩展。

题目集47-5)关于继承的特点如上,这里不多赘述。题目集三还只是利用基类调用子类,

而题目集四这彻底的把基类看作是子类的抽象,通过将不同的类对象指向共同点抽象基类,来对不同的类来进行排序,对与基类方法不同的实现来实现多态性,这种多态性是动态的多态性,但是抽象类的设计仍然需要十分谨慎。

题目集47-6

这道题的多态性不再是通过基类来实现,而是通过接口来实现。此题目两个类都实现area接口来求面积,相对于父类接口的写法更加简略。用接口来实现由不少好处,首先一个类只能有一个父类但是可以实现多个接口,利用接口组装类是非常不错的选择,而且接口的功能高度集中而且专一,通过把类转化为接口来处理可以将各种不在继承链上的类当做同一个抽象,相比继承而言实现接口是风险更小,更优雅,也更灵活的处理方式,我认为除非有非常好的理由否则不要用继承。以免程序耦合过于严重。一个功能一个接口能大大提高程序的可读性(相对于将类转化为某个基类,或者以某个类的基类做参数,把接口作为形参或者转化的目标,后者更容易看出写作者的意图,以及将要进行什么操作)

正则表达式技术的分析总结

题目集四7-1

水文是题目集里正则表达式运用最多的地方之一,在这题中先读取一行判断文本是否结束,在利用字符串切割用|”为标志将一行的数据切成5分,在为每一份量身定制专门代表真确表达式的正则表达式,如果格式合格,再利用提取数字的正则表达式挨个提取数字来判断是否在范围内。在这个过程中合理的运用各种通配符来对正确的字符串,或者要提取的目标字符串进行抽象,这个步骤可以专门在测试网站上进行。这里最难把握的就是各种“至少”“至多”还有就是捕获组。

这道题目主要就是锻炼了我门利用正则表达式判断正确格式,和提取有用片段。

题目集五7-1

利用正则表达式匹配单词,注意单词就是由字母开始由字母结束的连续的字母,没什么难度,不再赘述。

 

题目集五7-4

如果水文题目是用格式匹配正确的化,这道题就是用来削除无用的串,这道题目要先削除注释,方法是找到由//”开头换行结尾的串删掉,由“/*”开头“*/”结尾的片段,方括号同理,再匹配出所有关键字,既可以利用正则表达式匹配前面是非字母,后面也是非字母的关键字,也可以用通配符取出单词,在利用以上方法检查出现的次数。这道题更多的运用了各种代表空白格的通配符以及取非通配符,这些不可见的字符在测试和运行中往往会产生很多影藏的bug,对于这样那样的问题,写的时候一定要多多关注。以免走上弯路。

以上是去注释的部分。注意这里有个小bug因为程序是随着循环一行一行读输入,所以无法处理连续多行的内容(比如c风格的注释)。

题目集六7-1

判断QQ号,设计一个由非零的一个数开始,其后414位数,记得标记字符串尾以匹配完整字符串,其他没什么难度,按照题目要求很容易就过了。

题目集六7-4

检查学号

这道题除了要检查格式以外,还要检查数据是否合理,格式部分的检查如上,这里不多做赘述,其他部分切割指定位置的字符串,或者用正则表达式匹配特定位数来提取相应的有意义的字符串,转化为数字来判断合法性。

题目集六7-3

这道题稍微有点弯子,首先字母和数字都是合法的,但是字母和数字至少出现一次。先用方括号实现数字和字母的调配符,再重复四次,然后再单独检查能否匹配到数字和字母。代码整体比较简单,按题目要求很快就能写出来。

 第二阶段总结

 

 

这里没有考虑全是字母或全是数字的情况,比较不严密。

题目集57-4)中Java集合框架应用的分析总结

这道题我主要用了java array集合的排序功能。通过sort能很快对基本类型排序,或者传入接口自定义排序,相对于自己实现的排序,由专业人员维护的广泛使用的集合框架出bug的概率更小,也更方便,编码量也更小,可以让我们把精力主要放在软件的业务逻辑上,非常方便,利用增强for循环实现遍历也可以简化逻辑使代码更加清晰。

 第二阶段总结

 

 

 

(使用集合的代码片段)

(3)采坑心得

一部分采坑心得在上文已经说过这里不再赘述,因为很久以前做的题目有的bug难以复现,请谅解。

首先碰到最多的是写子类用IDE默认添加父类抽象方法的时候老是忘记重写,牵一发而动全身,题目集4 7 -5我三角形的面积我没有重写,在主函数排序的时候第一个就排成零,在输出的时候因为面积是零所以判wf,我当时以为是数据没有读进去,于是在将图形对象添加进list 之前,先把面积输出一遍,结果没问题(因为第一个是0,所以我先入为主的以为是没读进去,所以测试数据的时候没测到三角形),然后我以为是把子类直接add进父类的list数据会丢失,于是我又声明了一个父类的引用,先转化为父类再add结果还是有bug,然后我以为只要转化为父类就会丢失数据,结果再测,还是过得,我就彻底迷茫了。之后单步debug才找到症结所在。这让我感觉到,输出中间结果的debug方法固然好用,但是不要脑袋里有预设,不然很有可能会被误导,以及单步调试yyds

(4)改进建议

题目集中我觉得我最该改的还是两次日期类聚合当中求前n天,后n天的代码。

 第二阶段总结

 

 

(本质上它实现的原理就是求前一天,后一天n次)

这种代码复杂度是n,如果求n次就是n^2,显然对于这样一个明显有着常数复杂度实现的代码,用On)的实现是很不明智的(事实上对于最大最小的测试的它差点就超时了)。

优化的想法是,没四百年天数是相等的,利用这个特性可以把需要计算的年份压缩的四百年一类,而在四百年的跨度里,一百年的天数相等,在一百年的跨度里四年的天数相等,这样就把n限制在了四年里,再进行计算就很快了。

(5)总结

这一部分的学习让我体会到了软件的设计,设计优良的基类和接口可以大大减少编码的复杂度,而解耦清晰的代码可以让维护一气呵成,复用性高的代码可以大大节省编码时间。

利用正则表达式把模糊带给了字符串,利用正则表达式可以轻松实现if else 难以实现的功能,从而大大减少逻辑复杂性,在这段时间的学习中思考如何构建优雅健壮的代码是我主要干的是,前者做好了往往剩下的工作一气呵成。


程序员灯塔
转载请注明原文链接:第二阶段总结
喜欢 (0)