程序员
在软件开发过程中离不开
编码
和调试,这两个过程也是相辅相成的,我就个人的体会来谈谈这两个方面。
编码篇:
1
,程序为什么会有
bug
?其中一个比较关键的原因是程序员的主观因素造成的,比如编码习惯不好,粗心,不理解系统,系统太复杂没有想清楚设计,没有考虑到某些意外情况,单元测试不到位等等。
2
,编码前想清楚设计的细节,对设计细节越清楚,编码越顺利,想清楚了后写代码,往往能体会到那种行云流水,一气呵成的感觉,并且代码的
bug
更少。
3
,
我
有种体会就是,当想清楚了自己的设计细节,在头脑最清楚的时候写好代码的框架,一气呵成把一个可以运行的最小功能代码写好,在第一次编译的时候,如果经过
很小的修改就顺利编译通过,再尝试运行,如果遇到运行时的几个问题也比较简单,很快解决,意味着这部分代码质量不错,以后这块代码出问题的可能性也会小很
多。
4
,
编码前最好想清楚自己的设计细节,至少要想好
80%
以上的设计细节,我通常会写一份简单的文档来描述自己的设计,文档不一定正式,但一定要写简洁清楚,发给其
pm
或是其他同事拍砖,如果他们能很快看懂并没有异议,证明这个方案还不错,要是同事提出了一些意见,一定要考虑他们的意见,多讨论权衡后决定如何做。
5
,
编码是软件开发中比较小的一部分,但无疑是很核心的一部分,也是程序员最喜欢的一部分工作,但花在编码上的时间一般不会太长,假设一个
5000
行左右的模块,我一般会用
3-5
天时间把整个模块的框架代码和基础功能代码一口气写完,写代码时真的很充实,完全处于“颠疯”状态。
6
,
看代码的时间远远超过了写代码的时间,写完一段代码要及时回想一下,站在高一层的角度来审视代码,就像在高中考试答题一样,及时检查可以用最小的代价第一时间出代码的问题。
7
,
当第一个已基本功能的模块完成时,第一遍审查自己的代码,加上一些必要的注释,编写单元测试代码,这部分工作很单调但很关键,完备的单元测试可以把
bug
扼杀在摇篮中。单元测试一般以最简单的方式编写,使用一个不错的单元测试框架就事半功倍,比如
gtest
,
cppunit
,必要的时候写一些
mock
。我的单元测试代码不像项目代码那么正规,单元测试代码的重构做得比较少,要是某个模块有大的修改,就直接放弃那部分的测试代码,重新写新的测试代码。我写的单元测试代码一般会比项目代码多,经过自己亲手测试的代码比较放心。
8
,尽量用最简单的方式实现功能,程序员有时候会随做经验的增加,把简单的问题复杂化,但开发中常常需要的是把复杂的问题简单化,用最简洁,最快的方式解决眼下的问题。
9
,
使用自己最熟悉的语言特性实现功能,不要使用费解或是不直观的语言特性。毕竟程序员不是语言专家,最简单的招式用到极致就是绝招。比如在我们的高性能分布式服务器系统中,虽然采用的是
C++
开发,但我们主要使用的
C
的语言特性,不使用
STL
或
boost
,我们只使用我们最熟悉,最可控的语言特性。服务器是需要长时间运行的,一个不可控的因素就可能导致系统崩溃。
10
,
程序有
bug
是难免的,但我们尽量让
bug
无处藏身,相信自己的开发水平,相信编译器,相信自己的单元测试,相信系统测试,相信压力测试,一步一步地,
bug
真的无处藏身。
调试篇:
1
,
这里主要讨论开发的代码调试,没有源代码的的调试要借助比较多的额外工具,包含比较多的技巧性的东西,这个话题留着以后做进一步探讨。
2
,
在学习程序开发的初级阶段,最喜欢用的调试方法就是
"
暴力
"printf
方法,不是说这个方法不好,而是这个调试方法一般不会成为调试方法的首选,当进入正规的开发项目后,系统中都要求实现比较完善的
log
机制,根据
log
的不同级别,一般就能实现
bug
的初步定位。代码中实现完善的
log
机制对多线程程序的调试带来了便捷。
3
,
在
代码的的基本功能实现以后,第一时间审查代码和实现单元测试,确保单元测试通过,然后不断完善代码功能和添加相关的单元测试,每添加一个新功能都确保单元
测试通过,如果单元测试不能通过,第一步想到的就是检查最近修改的代码,由于是迭代开发的,每个阶段都保证了单元测试通过,所以查找一个新引入的
bug
是比较容易的。
4
,
在项目开发后期,系统进入连调阶段,如果你的单元测试做得比较到位,设计清晰简洁,那时候你就会看到其他人都忙着修改
bug
,你却很清闲。那时候你会体会到完备单元测试
+
迭代开发的好处。
5
,
我不太常用
gdb
,一般程序的
bug
在单元测试阶段构造一些简单的测试场景就修复了,并在程序中每个函数都做了充分的参数检查,程序出
core
的情况并不多,但程序发生段错误时,
gdb
是一个比较方便的定位方法。
6
,
一般情况下,程序出错,首先看
log
,如果
log
比较完备,并对自己的代码比较熟悉,基本就能定位
bug
的地方了。如果没有头绪并且
bug
很容易复现,就采用
gdb
调试,使用
gdb
也需要有针对性,首先查看自己怀疑的对象,如果涉及到其他同事写的代码,在调试过程中可以熟悉代码的执行过程。一般简单的
bug
,凭着经验应该能很快定位。能反复重现的
bug
用
gdb
查找是比较快的。
7
,
使用
gdb
调试比较复杂的多线程问题时,我比较喜欢用
gdb attach
<pid>
,
想象一下,一个程序直接跑就出错,但是放到gdb下就能得到正确的结果,好像故意在耍我们一样
,
这种方法的好处是能够使gdb对程序执行的影响最小,而且可以只接管程序中某一条我们所关心的线程,而其他线程不受影响
。如果
还没来得及attach线程就已经执行完或者
crash
了
,我们可以在线程中加入
sleep
()。
8
,
在做压力测试时要是系统崩溃,一般有几种方式来处理这种情况,最常见的一种情况就是
segmentation fault
,我们可以将程序运行在
gdb
中,一旦程序
crash
,
gdb
可以看到最后的出错堆栈信息,但在
gdb
中会影响到程序的性能。第二种办法是查看程序的
core
文件,但程序消耗的内存很庞大时,生成
core
文件也需要很长时间。还有一种办法是使用信号来保存现场。
这样你可以晚上写个脚本让程序无限跑,早上起来你会发现程序停在出错的地方,这是很惬意的事情
,我们只需要在信号的处理函数中添加一段循环
sleep
的代码就可以了。
9
,
内存问题调试采用
valgrind
,一般的内存错误都逃不出它的魔眼,但关键还是需要自己在开发过程中多注意,养成正确使用内存的好习惯,简单设计是防止内存问题的一个比较有效的方法。
10
,
更复杂的系统
bug
就需要用一些工具来辅助解决了,比如性能问题,我们会采用
oprofile
,或是
systemtap
来找到系统的热点。比如全异步,多并发,分布式的服务器程序,我们在试运行时可以采用内存
log
的方式,将系统的的
log
级别定为
DEBUG
,系统将
log
写入一个循环内存缓冲区,当系统出问题时可以看到系统最后那段时间的详细信息,方便调试。对已经在线上运行的系统的
bug
调试,调试手段真的有限,一般采用监测系统状态和系统的一些
stat
接口来间接定为系统是否运行正常,有时候也使用
systemtap
这样的工具对重点怀疑的对象进行监测。
分享到:
相关推荐
该系统的总体的一个结构图有主界面以及主界面上的一些模块构成,主界面为HomeActivity,在主界面上有手机防盗、...数据库的实施主要包括:建立实际数据库结构、装入数据、应用程序编码与调试、数据库试运行和整理文档。
本程序是用C++编写的图像方块编码程序,并且调试已通过。本程序采用了最简单的方块编码对512×512的lena图像进行了编码运行程序后可以看出,方块取得越大,图像编码后失真越大。
调试通信模块发短信时,发送中文需要用Unicode编码,并组包PDU编码,这个工具就是输入手机号和发送内容后,自动组包为pdu编码,以和自己程序做对比,判断程序是否正常。
VC图像编码源程序,调试通过,直接可用,并可在此基础上进一步开发。
卷积编码的matlab程序,可以直接运用,已经调试好了。
多摩川编码器读取程序,支持多摩川ADM485协议,在STM32F4上实验读取TS5668N21成功。
这是QR二维码的编码和解码程序,两个工程放在同一个工作空间中,便于大家学习,调试程序,已经在VC6.0下成功编译,运行正常。
红外发送一开始发送一段13。5ms的引导码,引导码由9ms的高电平和4。5ms的低电平组成,跟着引导码是系统码,系统...25ms的低电平,跟着是一个短脉冲,本程序是免费给大家的,本程序经过试用,能解大部分遥控器的编码。
毕业论文涉及到的,自我编写调试通过,工程打开下载即能使用。代码中包含相对编码器测速程序、8位绝对值编码器位置测量程序。
光电编码的电机驱动调试程序,电机实战必备
本代码实现HUFFMAN编码的基本编写,能够对若干个按概率拍好的字符进行编码,能统计出它的码长、平均码长、编码效率等。。
本程序经过高手大哥调试正确可用 下载就可直接使用 精度准确
编码器调试程序 正交编码器 串口发回计数值 亲测可用
能够使用自己编写的分析程序对简单的程序段进行词法分析。 1.关键字:if、int、for、while、do、return、break、continue;单词种别码为1。 2.标识符;单词种别码为2。 3.常数为无符号整形数;单词种别码为3。 4....
SPIHT编码源程序,包括无损和有损的c++,linux下和matlab的源程序,调试好使。
1、学习使用ccs6000来进行dsp程序的编写和调试工作; 2、掌握dsp在处理程序式的过程和常见错误类型; 3、理解c6000的C运行时的环境和流水线工作流程; 4、掌握用ccs实现32bit*16bit=32bit的无符号整型数据的乘法;
基于STM32控制编码电机,测速等例程代码。 附带例程:1-4 OLED驱动函数模块、3-5 光敏传感器控制蜂鸣器、5-1 对射式红外传感器计次、6-2 定时器外部时钟、6-4 PWM驱动舵机、6-5 PWM驱动直流电机、7-2 AD多通道、6-7 ...
这个c#串口调试助手是自己原创的,有什么问题可以联系我,vs2008编译通过
汉明码的编码程序调试与分析..汉明码的编码思路及程序设计
哈夫曼编码 源程序 附详细注释,均已调试通过