优化出来的bug:慎用static
这几天忙的晕头晕脑的,午休取消了,抽烟时间也掐着算,连上厕所的空儿都在想工作那些事儿,没办法,搞IT这行,事儿多的时候,1天24小时是不够用的,必须一天25小时才行。可日子不按咱的想法走,咱只能顺着日子过!
忙的时候一糊涂就容易犯错,这不犯了个菜鸟级别的错嘛,让同事好一顿奚落 :(。事情是这样的,项目中某个算法需要做优化,在Code review的时候发现在初始化时请求数据库比较多,而部分数据又是配置型数据(这里将不频繁变动的数据且称为配置型数据),且数量也不多,于是就想到了使用静态构造来保存这部分数据,以减少数据库请求量。由此在优化的时候将原来的局部变量变成了全局静态变量,且在静态构造函数内构造一次,这样一来问题就出来了,这也怪我太急功近利,因为事儿比较多,也就没留个心眼,结果吃大亏了。
说到这里,看这文章的老鸟们肯定明白了个中缘由(相信也有不少一看题目就能猜到个八九不离十的鸟人们)。闲话先不说,”翠花,上代码!”
{
static Dictionary<int,Bug> BugDictionary = new Dictionary<int,Bug>();
static StaticBug()
{
InitBugDictionary();
}
private Bug ErrorGetBug(int bugId)
{
//错误的方法.
Bug bug = null;
if (BugDictionary.ContainsKey(bugId))
{
bug = BugDictionary[bugId];
if (bug != null)
{
bug.BugCount++;//并不希望改变BugDictionary中Bug对象的BugCount属性值.
}
}
else
{
InitBugDictionary();
if (BugDictionary.ContainsKey(bugId))
{
bug = BugDictionary[bugId];
if (bug != null)
{
bug.BugCount++;//并不希望改变BugDictionary中Bug对象的BugCount属性值.
}
}
}
return bug;
}
}
public class Bug
{
public int BugId{ get; set; }
public string BugTitle { get; set; }
public string BugContents { get; set; }
public int BugCount { get; set; }
public static Dictionary<int, Bug> GetBugs()
{
//Do some thing to get bugs.
return new Dictionary<int, Bug>();
}
}
从代码中可以看到对bug变量的错误操作。若不希望改变BugDictionary中Bug对象的BugCount属性值,正确的代码应该是:
{
Bug bug = null;
Bug tempBug = new Bug();
if (BugDictionary.ContainsKey(bugId))
{
bug = BugDictionary[bugId];
if (bug != null)
{
tempBug.BugId = bug.BugId;
tempBug.BugTitle = bug.BugTitle;
tempBug.BugContents = bug.BugContents;
tempBug.BugCount = bug.BugCount;
tempBug.BugCount++;
}
}
else
{
InitBugDictionary();
if (BugDictionary.ContainsKey(bugId))
{
bug = BugDictionary[bugId];
if (bug != null)
{
tempBug.BugId = bug.BugId;
tempBug.BugTitle = bug.BugTitle;
tempBug.BugContents = bug.BugContents;
tempBug.BugCount = bug.BugCount;
tempBug.BugCount++;
}
}
}
return tempBug;
}
从上面代码可以看出使用了一个临时Bug对象来接收bug的属性值,然后BugCount++,避免了修改BugDictionary。
相信不少新手在使用static的时候会遇到这个错误,也相信有不少想我这样的老手一不谨慎就造成了这样的错误。造成错误的原因简单,但从3千多行代码中排除bug,谈何容易!因此,各位兄弟姐妹们在使用static变量的时候要谨慎。不只如此,在使用单例模式的时候更要谨慎,相比较起来,单例模式出bug要比我这情况容易排查多了。
写此菜鸟型文章,斗胆放在首页上抛砖引玉,希望比我更老的鸟们提点儿珍贵的意见!