作者:JK

时间:2015/09/24

特别说明:版权所有,转载请注明出处;

最近笔者在参与项目时,遇到了一些很奇特的问题,程序运行正常,产生的结果异常,程序功能是对当天的数据进行统计,数据里有可能有重复的,如果数据重复则该数据对应的计数器增1,问题是统计以后,有数据的次数居然类似于一个随机数,看到这个数字我就认定这个结果肯定是错误的,只是一时不能想出问题出在哪里,百思之下仍不得其解,甚至拿着工程的源代码,根据程序的流程重新走读代码,仔细思考每一个处理过程,最后程序看完,仍然对问题没有任何头绪。

搔首顿足,冥思苦想若干分钟,最后决定在每一个关节处增加调试输出语句,这样就能确定数据是在哪个阶段出现了问题。这是一个最笨的办法,也最麻烦。既然没有想到更好的解决办法,那就只能硬着头皮,抱着强大的耐心,在每一个处理过程增加调试输出语句。比如数据从输入到输出,中间可能有10个处理过程(10个函数),我的做法是先在第5个函数产生数据的地方增加调试语句,这样做的好处是,可能在多半的情况下能减少排查问题的时间,这种处理办法类似于“二分查找”算法,从中间位置开始查找,要比从头开始或者从尾开始的做法快,如果在第5个过程处经过调试输出发现,已经出现问题,那数据在第5个过程以前肯定已经出现了问题,最后经过笔者的不断尝试,终于在大概第7个过程的位置发现了一个很隐蔽的问题。

为什么这是一个很隐蔽的问题呢,听我一一道来。C++里关联容器可以使用中括号(‘[]’)来直接引用,关联容器里不存在的KEY值也可以使用中括号来操作,如果该key值对应的值不存在,则往该容器中添加键值对。本项目中所使用的关联容器是一个key为string类型,value为另一个自定义结构体,类似于map<string, STRUCT> >; STRUCT是自定义的数据结构,里面有两个long类型的变量,如下定义:

typedef struct _STATCOUNT
{
long curdatetimes;
long total;
}STATCOUNT;

在项目的代码中,对map的操作时类似于下列代码:

假定map<string, string>contentMap为每一条记录;

map<string, STATCOUNT> statCount;
map<string, string>contentMap::const_iterator iter; for(iter = contentMap.begin(); iter !=contentMap.end(); ++iter)
{
statCount[iter->second].curdatetimes += ;
}

这样的代码表面上看没有任何问题,也能正常运行,可是隐藏的问题是:

(1) statCount中如果key值iter->second所对应的value值不存在,直接使用statCount[iter->second].curdatetimes += 1; 将会根据long类型的属性产生一个随机的结果;

(2) long类型在定义后默认是不进行初始化的,和int类型不同,int类型定义后将被编译器自动初始化为0,而long类型则没有初始值。

因此经过调试输出发现问题在此,因此结果数据中,统计的次数可能出现一个看似奇怪的结果。修正该问题后,重新调试发现,原来的随机数情况就没有再出现了。笔者不禁感慨,设计代码的严谨性多么重要,如果设计之时粗心大意,可能就是给自己埋下的无数的“坑”。

怎么样,可能大家在没有自己亲身经历的情况下,不会有太深刻的体会,没关系,看过这篇文章,脑海里只要有一个印象就够了,下次如果真遇到相似的问题,就能迅速联想起来。那这篇文章就会变得特别有意义了。

C++ 项目经验总结:程序严谨性(一)的更多相关文章

  1. Java项目经验——程序员成长的关键(转载)

    Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的分析与设计技巧3.掌握用例驱动.以 ...

  2. Java项目经验——程序员成长的钥匙

    本文转载至:http://geek.csdn.net/news/detail/109880,像我这样的菜鸟应该多看几遍这样的文章,学起来才更加有动力和方向. Java就是用来做项目的!Java的主要应 ...

  3. java程序员面试交流项目经验

    粘贴自:https://blog.csdn.net/wangyuxuan_java/article/details/8778211 1:请你介绍一下你自己 这是面试官常问的问题.一般人回答这个问题过于 ...

  4. Java项目经验

    Java项目经验 转自CSDN. Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的 ...

  5. java面试项目经验:框架及应用

    Java项目经验 Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的分析与设计技巧3 ...

  6. Javaee项目经验须知

    Java的主要应用领域就是企业级的项目开发!具体要点(09年,那一年我去面试,被拒了几次,想起来还不错!他锻炼了我的心理素质,让我体会到很多,笑一个吧!): 1.掌握项目开发的基本步骤 2.具备极强的 ...

  7. 安利一个基于Spring Cloud 的面试刷题系统。面试、毕设、项目经验一网打尽

    推荐: 接近100K star 的Java学习/面试指南 Github 95k+点赞的Java面试/学习手册.pdf 今天给小伙伴们推荐一个朋友开源的面试刷题系统. 这篇文章我会从系统架构设计层面详解 ...

  8. 最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备

    在上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间.我的标准其实不复杂:第一能干活,第二Java基础要好,第三最好熟悉些分布式框架,我相信其它公司招初级开发时,应该也照着这个标准来面 ...

  9. 项目经验分享[转自min.jiang]

        最近三个月,我非常荣幸的做为TeamLeader带领几个小组成员做了一个国外项目,这里想为大家分享一些小经验,尽管我佣有六年多的项目经验,但我一直的方向是架构师.大家知道架构师一般情况是偏向技 ...

随机推荐

  1. springboot Actuator健康检查

    通过情况下,如我们想在系统中添加一个健康检查的接口,我们怎么做呢? 我们会新建一个类,或在已存在类的基础上添加检测接口. package com.crhms.medicareopinion; impo ...

  2. maven spring MVC 及tomcat

    eclipse+tomcat8+springMVC环境搭建https://blog.csdn.net/code_fighter/article/details/79169058 Eclipse+Tom ...

  3. 删除Rancher节点的正确姿势

    在Rancher上疏散该节点 删除节点 登录该节点宿主机,删除rancher相关容器 docker rm -f -v $(docker ps -aq) 删除该节点的所有volume docker vo ...

  4. java23种设计模式之三: 适配器模式

    一.适配器模式  就是个通过一个中间件转化,可以将不匹配的两件事整合到一起,把不匹配变的匹配. 二.适配器分类 1.类适配器  2.对象适配器 三. 适配器的3种组成 1.类适配器组成 1.2个接口 ...

  5. JavaScript 获取对象属性和方法

    ShineJaie 原创整理,转载请注明出处. 一.获取对象属性和方法 Object.keys() 返回对象的可枚举属性和方法的名称数组. Object.getOwnPropertyNames() 返 ...

  6. Java网络编程学习A轮_01_目标与基础复习

    A. A轮目标 复习网络编程基础知识,重点学习下TCP三次握手四次挥手,以及可能引发的异常情况. 回顾 Socket 编程,好多年没写(chao)过相关代码了. 重学 NIO,以前学的基本忘光了,毕竟 ...

  7. 转载:Object的create方法文档

    源地址:https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/create#.E4.B ...

  8. Ubuntu14.04安装CUDA6.5

    机器配置: 双系统:win10 64bit+ ubuntu14.04 LTS 64bit 显卡: GeForce 405 cuda版本: cuda 6.5 参考: http://m.blog.csdn ...

  9. 威佐夫博弈——hdu1527

    有两堆各若干的物品,两人轮流从其中一堆取至少一件物品,至多不限,或从两堆中同时取相同件物品,规定最后取完者胜利. 直接说结论了,若两堆物品的初始值为(x,y),且x<y,则另z=y-x: 记w= ...

  10. HDU 4352 XHXJ's LIS ★(数位DP)

    题意 求区间[L,R]内满足各位数构成的数列的最长上升子序列长度为K的数的个数. 思路 一开始的思路是枚举数位,最后判断LIS长度.但是这样的话需要全局数组存枚举的各位数字,同时dp数组的区间唯一性也 ...