代码复审
1. 概要部分
代码能符合需求和规格说明么?
基本符合。对于小范围的 -c
和 -s
功能符合要求。对于大范围的 -c
会出现问题,参见助教,学号 15061188。
代码设计是否有周全的考虑?
代码有些部分有不同逻辑部分的强耦合,以及对于输入格式有些过于强的假设,具体在设计规范部分中详细说明。
代码可读性如何?
代码可读性还可以,命名有意义,辅助有一定量简明的注释。但生成数独的一部分代码无论是个人项目博客还是代码里都没有明确说明机理,较为难懂。
代码容易维护么?
松耦合做的不太到位,不是很容易维护。
代码的每一行都执行并检查过了吗?
执行并检查过了,但仍然出现了些问题,参见上文链接。
2. 设计规范部分
设计是否遵从已知的设计模式或项目中常用的模式?
松耦合做的并不够。
- 将文件句柄以参数形式传入生成/求解函数中,当更换输出方式时,就会修改若干行本身与输出无关的计算模块代码。
sudoku_processor.cpp
第 26 行,。 - 对输入格式要求过强。
sudoku_processor.cpp
第 90 行,。
有没有硬编码或字符串/数字等存在?
有,大部分结合题目背景可以轻易理解,少部分涉及到未详细说明的生成机理理解不能。
代码有没有依赖于某一平台,是否会影响将来的移植(如 Win32 到 Win64)?
源代码层面没有。
开发者新写的代码能否用已有的 Library/SDK/Framework 中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现?
有,可以通过 atoi
来将一个字符串转换为数字,但由于效率原因(只转换一个字符)重新手写了。
有没有无用的代码可以清除?(很多人想保留尽可能多的代码,因为以后可能会用上,这样导致程序文件中有很多注释掉的代码,这些代码都可以删除,因为源代码控制已经保存了原来的老代码。)
没有。但我个人并不赞同这点。对于长期无用代码这样做是合适的,但是对于正在迅速变化的代码,这样做是不合适的。代码本身和源代码控制的关系个人理解在该问题上相当于 cache 与内存的关系,二者的检索速度是不一样的。个人认为在开发过程中,适量注释一些可能会经常用的代码相比完全一高版本控制在效率上更可取。
3. 代码规范部分
未发现风格不统一的部分。
4. 具体代码部分
有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常?
对输入输出部分(IO 相关部分)没有做相应判断。
参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以 0 开始计数还是以 1 开始计数?
没有错误。从 0 开始计数。
边界条件是如何处理的?Switch语句的Default是如何处理的?循环有没有可能出现死循环?
没有需要特别处理的边界情况。没有 switch
语句。不会出现死循环。
有没有使用断言(Assert)来保证我们认为不变的条件真的满足?
没有。
对资源的利用,是在哪里申请,在哪里释放的?有没有可能导致资源泄露(内存、文件、各种GUI资源、数据库访问的连接,等等)?有没有可能优化?
没有动态申请资源的地方,资源全部限制在函数/类的局部范围之内。不会出现资源泄露的情况。
可以将输出数独的缓存数组开成一个类变量,而非每次输出时重新申请的函数局部变量。这样可以减少申请内存的时间。
数据结构中是否有无用的元素?
没有无用元素。
5. 效能
代码的效能(Performance)如何?最坏的情况是怎样的?
由于采用了最为直接的回溯法,并且实现上有些小问题,导致性能一般,求解一百万个数独需要 580 秒时间。
代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C#中string的操作是否能用StringBuilder 来优化)?
可以通过位来表示数独每个格的状态,然后通过位运算加速寻找可行位的部分。
对于系统和网络调用是否会超时?如何处理?
没有相关调用。
6. 可读性
可读性评价见概要部分。
7. 可测试性
代码是否需要更新或创建新的单元测试?
需要。由于测试不全导致 -c
参数在大范围时未能通过,因此需要补充相应单元测试以确保正确性。
还可以有针对特定领域开发(如数据库、网页、多线程等)的核查表。
该次作业并无此部分需要。
设计一个代码规范
使用的工具为最新版 cpplint
。
工具提供的代码规范和你个人的代码风格有什么不同?
- 加注 Copyright 信息。
- 左大括号不换行。
- 使用空格而非 Tab。
- 强制要求头文件包含顺序。
- 不使用
using namespace
。
工具提供的代码规范里有哪些部分是你之前没有想到的?
- 加注 Copyright 信息。
- 强制要求头文件包含顺序。
- 不使用
using namespace
。
为什么要这样规范?这样的规范有意义吗?
- 加注 Copyright 信息申明版权避免之后的纠纷。
- 左大括号不换行认为是个人风格问题,无论怎样统一即可。
- 为了更好的跨平台阅读体验其实应该使用空格,但基本上 IDE 一手包办所以无所谓了,统一即可。
- 要求头文件包含顺序易于区分头文件类别,使得代码更易读。
- 避免污染全局命名空间,减少了不必要的错误发生概率。
在结对编程中使用的代码规范
- 使用 Visual Studio 2017 Community 自带的默认代码 formater。
- 命名使用驼峰命名法,类名使用第一个字母大写的驼峰命名法。
- 只有一行语句的代码块不用大括号,大于等于两行(即使语义上是一行)使用大括号包裹。
- 左右大括号各占一行。
- 使用 4 个空格缩进。
- 每行宽度不超过 100 字符。