原创作品转载请注明出处 + 软件工程(C编码实践篇)的学习心得+ 《软件工程(C编码实践篇)》MOOC课程http://mooc.study.163.com/course/USTC-1000002006
一、实验报告目录链接:
实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
学习笔记:
1、我们为什么要学习软件工程?
不学习软件工程而成为产品经理或者程序员之类的大有人在,可是学习软件工程可以帮助我们少走弯路。
2、熟悉linux环境
2.1 我们为什么选择linux?
因为现在大多数服务器都是linux系统,而且在linux中可以开发彻底掌握设计。不了解linux的程序要不是一个好的程序员。
2.2 linux的基本操作 。 比如:
cd. 当前目录 cd..上级目录 cd/ 根目录
mkdir创建新文件
vim编辑(分为一般、编辑、命令模式)
gcc hello.c -o hello 将hello.c文件生成可执行文件hello
打包 tar -zvcf name.tar.gz path_and_files 解包 tar -zvcf name.tar.gz
rm 删除cp 拷贝
vim中的拷贝和粘贴:v可视化选择,y拷贝,p粘贴
dd剪切该行
3、代码风格规范 (原则:简明、易读、无二义性)
请注意缩进、命名、注释等风格规范。
① 注意在缩进中,使用4个空格,而不要使用Tab键。
② 命名:合适的命名可以增强易读性。 1、类成员变量通常用m_或_做前缀 2、一般变量使用lowerCamel风格 3、类/函数名一般使用Pascal风格,即所有单词首字母大写。
③ 注释:使用英文注释。不要解释程序是如何工作的。每个源文件的开头写上作者、版权等信息。
4、基本的模块化设计
- 代码设计中常用方法:
- KISS(keep it simple & stupid)一个方法或函数只做一件事;不同的抽象层级看到的是不一样的;抽象实际上是选择地忽略一些细节。
- using design to frame the code(matching design with implementation) 设计模式和实现要保持一致。可以将设计转为伪代码,然后再完善成可实施代码。
- including pseuducode
- 不要和陌生人说话原则。“防人之心不可无,害人之心不可有”
- 合理利用Control Structures、Data Structures来简化代码
- 一定要有错误处理。注意错误处理和Assert断言的区别。
- 注意模块化的思想和关注点的分离(separation of concerns),包容变化是模块化的主要作用,把变化的放在一起。在基本模块化写法中,要遵循“开-闭”原则,也就是将扩展功能开放,而将修改功能封闭。
- 将软件分为两个层级:业务逻辑层,数据存储层。注意将系统模块化放在不同源文件 比如实验中的menu.c、linklist.c、linklist.h
- 编码中的功能实现和错误处理符合20/80原则。
- 注意goto不是不能用,而是要用的合适。
5、可重用模块的接口设计
- 通用链表模块的设计接口,也就是说不要重复造轮子。在设计接口中,注意结对原则(生死相依原则),就比如说CreateLinkTable() 和 DeleteLinkTable(tLinkTable *pLinkTable) 成对出现。注意参数化上下文(移除前置条件,简化后置条件)。我们可以设置一个文件柜,这在这个文件柜里面,用户可以自定义数据类型的链表,实验中的文件柜是LinkTableNode。注意用表达式作为判断条件,而不要用布尔型变量做比较。Call-in函数方式遍历链表接口。DVT(开发者验证测试)。
- 接口概念:接口是定义了软件单元对外提供的服务。其中,有三个明显的要素(函数名、参数、返回值),有五个元素(目的、前置条件、协议、后置条件、质量属性)。接口可以按照功能分5类(共享数据或变量名、call-in functions、call-back functions、同步调用接口(阻塞式)、异步调用接口(信号量、消息队列等)。接口的设计遵循高内聚低耦合的原则,同时注意不要太具体也不要太通用。
6、可重用模块的接口设计(Callback)、函数的可重用性与线程安全
我们平常使用的都是call-in函数调用,但是在实验中,是给Linktable增加Callback方式的接口SearchLinkTableNode查询链表。实际上Lamda与Callback函数是最好的匹配,但是C语言里不支持Lamda,所以这里我们就没用使用了。在写代码的过程中注意全局变量cmd作用域问题,这里就涉及到了线程安全。如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行读写操作,一般都需要考虑线程同步,否则就可能影响线程安全。可重用函数和线程安全的关系:可重入的函数不一定是线程安全的;可重入的函数在多个线程中并发使用时是线程安全的,但不同的可重入函数(共享全局变量及静态变量)在多个线程中并发使用时会有线程安全问题;不可重入的函数一定不是线程安全的。
心得:
首先谢谢孟老师在这两个月中的辛苦教学!
在这两月的学习中,我学习到了一次很不一样的软件工程课。通过线上线下的结合,软件工程不仅仅局限于理论上,更是扩展到了实际的编程应用中去。通过学习,懂得了如何分析和处理问题,作为一个好的程序员,学习软件工程绝对是有助于我们少走弯路的。
首先学习的linux让我知道程序员不要仅仅局限于在windows的框架里面开发,应当尽可能地拓宽自己的学习广度。第二,通过代码风格规范,让我知道在软件开发中,遵循规范也是很重要的,之前我是觉得格式并不重要的,为了完成任务,格式常常被忽略,但是现在觉得缺一个空格都非常刺眼,程序员还是要认真对待自己敲出的每一个字符,这样不管是对于自己还是他人都会很方便,要只有这样才能走的长远。再对于模块化设计等,总的来说还是要使得自己写的程序更具有通用性,也更易于维护。也理解了可重用函数和线程安全。
在这门课程中,我依旧是存在很多不足:①学习不及时复习,导致前面学的东西,到了后续就忘记了。②看着老师的视频,过分地照着老师的代码敲,不愿意自己动脑子思考自己去做。③程序员应该是信细心的人,而我却十分地粗心,在线上作业,我曾经忘记写了一次互评…这次的主观题考试,我又忘记将博客的URL地址提交到答卷里面。为什么会出现这样的情况呢?心浮气躁是问题的关键,做事情不好好考虑,一心二用,真是要好好反省自己,为什么别人没出现这样的情况?
能在研一的抢课大战中,争取到高级软件课程,我还是很开心的(哈哈~比手速哦),庆幸自己读上研究生,遇到不一样的老师,不一样的教学方式,增长了见识!谢谢老师!