您的位置:首页 > 其它

单例模式(Singleton)的6种实现

2014-03-20 11:34 429 查看

分享到...
复制网址邮件腾讯微博网易微博百度搜藏人人网开心网搜狐微博一键分享豆瓣新浪微博QQ空间微信易信QQ好友查看更多(122)

这是什么工具?


JiaThis





JK_Rush

博客园

首页

博问

闪存

新随笔

联系

订阅

管理

随笔-59 文章-0 评论-637


单例模式(Singleton)的6种实现


1.1.1 摘要

在我们日常的工作中经常需要在应用程序中保持一个唯一的实例,如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要介绍的——单例模式(Singleton)。

使用频率



单件模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。


1.1.2 正文





图1单例模式(Singleton)结构图

单例模式(Singleton)是几个创建模式中最对立的一个,它的主要特点不是根据用户程序调用生成一个新的实例,而是控制某个类型的实例唯一性,通过上图我们知道它包含的角色只有一个,就是Singleton,它拥有一个私有构造函数,这确保用户无法通过new直接实例它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()方法负责检验并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。





图2单例模式(Singleton)逻辑模型

接下来我们将介绍6中不同的单例模式(Singleton)的实现方式。这些实现方式都有以下的共同点:

有一个私有的无参构造函数,这可以防止其他类实例化它,而且单例类也不应该被继承,如果单例类允许继承那么每个子类都可以创建实例,这就违背了Singleton模式“唯一实例”的初衷。
单例类被定义为sealed,就像前面提到的该类不应该被继承,所以为了保险起见可以把该类定义成不允许派生,但没有要求一定要这样定义。
一个静态的变量用来保存单实例的引用。
一个公有的静态方法用来获取单实例的引用,如果实例为null即创建一个。


版本一线程不安全

/// <summary>
/// A simple singleton class implements.
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;

/// <summary>
/// Prevents a default instance of the
/// <see cref="Singleton"/> class from being created.
/// </summary>
private Singleton()
{
}

/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get { return _instance ?? (_instance = new Singleton()); }
}
}




以上的实现方式适用于单线程环境,因为在多线程的环境下有可能得到Singleton类的多个实例。假如同时有两个线程去判断

(null == _singleton),并且得到的结果为真,那么两个线程都会创建类Singleton的实例,这样就违背了Singleton模式“唯一实例”的初衷。


版本二线程安全

/// <summary>
/// A thread-safe singleton class.
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
private static readonly object SynObject = new object();

Singleton()
{
}

/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get
{
// Syn operation.
lock (SynObject)
{
return _instance ?? (_instance = new Singleton());
}
}
}
}



以上方式的实现方式是线程安全的,首先我们创建了一个静态只读的进程辅助对象,由于lock是确保当一个线程位于代码的临界区时,另一个线程不能进入临界区(同步操作)。如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放。从而确保在多线程下不会创建多个对象实例了。只是这种实现方式要进行同步操作,这将是影响系统性能的瓶颈和增加了额外的开销。


Double-Checked Locking

前面讲到的线程安全的实现方式的问题是要进行同步操作,那么我们是否可以降低通过操作的次数呢?其实我们只需在同步操作之前,添加判断该实例是否为null就可以降低通过操作的次数了,这样是经典的Double-Checked Locking方法。

/// <summary>
/// Double-Checked Locking implements a thread-safe singleton class
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
// Creates an syn object.
private static readonly object SynObject = new object();

Singleton()
{
}

public static Singleton Instance
{
get
{
// Double-Checked Locking
if (null == _instance)
{
lock (SynObject)
{
if (null == _instance)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
}




在介绍第四种实现方式之前,首先让我们认识什么是,当字段被标记为beforefieldinit类型时,该字段初始化可以发生在任何时候任何字段被引用之前。这句话听起了有点别扭,接下来让我们通过具体的例子介绍。

/// <summary>
/// Defines a test class.
/// </summary>
class Test
{
public static string x = EchoAndReturn("In type initializer");

public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}




上面我们定义了一个包含静态字段和方法的类Test,但要注意我们并没有定义静态的构造函数。





图3 Test类的IL代码

class Test
{
public static string x = EchoAndReturn("In type initializer");

// Defines a parameterless constructor.
static Test()
{
}

public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}



上面我们给Test类添加一个静态的构造函数。





图4 Test类的IL代码

通过上面Test类的IL代码的区别我们发现,当Test类包含静态字段,而且没有定义静态的构造函数时,该类会被标记为beforefieldinit。

现在也许有人会问:“被标记为beforefieldinit和没有标记的有什么区别呢”?OK现在让我们通过下面的具体例子看一下它们的区别吧!

class Test
{
public static string x = EchoAndReturn("In type initializer");

static Test()
{
}

public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}

class Driver
{
public static void Main()
{
Console.WriteLine("Starting Main");
// Invoke a static method on Test
Test.EchoAndReturn("Echo!");
Console.WriteLine("After echo");
Console.ReadLine();

// The output result:
// Starting Main
// In type initializer
// Echo!
// After echo
}
}




我相信大家都可以得到答案,如果在调用EchoAndReturn()方法之前,需要完成静态成员的初始化,所以最终的输出结果如下:





图5输出结果

接着我们在Main()方法中添加string y = Test.x,如下:

public static void Main()
{
Console.WriteLine("Starting Main");
// Invoke a static method on Test
Test.EchoAndReturn("Echo!");
Console.WriteLine("After echo");

//Reference a static field in Test
string y = Test.x;
//Use the value just to avoid compiler cleverness
if (y != null)
{
Console.WriteLine("After field access");
}
Console.ReadKey();

// The output result:
// In type initializer
// Starting Main
// Echo!
// After echo
// After field access

}







图6 输出结果

通过上面的输出结果,大家可以发现静态字段的初始化跑到了静态方法调用之前,Wo难以想象啊!

最后我们在Test类中添加一个静态构造函数如下:

class Test
{
public static string x = EchoAndReturn("In type initializer");

static Test()
{
}

public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}







图7 输出结果

理论上,type initializer应该发生在”Echo!”之后和”After echo”之前,但这里却出现了不唯一的结果,只有当Test类包含静态构造函数时,才能确保type initializer的初始化发生在”Echo!”之后和”After echo”之前。

所以说要确保type initializer发生在被字段引用时,我们应该给该类添加静态构造函数。接下来让我们介绍单例模式的静态方式。


静态初始化

public sealed class Singleton
{
private static readonly Singleton _instance = new Singleton();

// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}

/// <summary>
/// Prevents a default instance of the
/// <see cref="Singleton"/> class from being created.
/// </summary>
private Singleton()
{
}

/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get
{
return _instance;
}
}
}




以上方式实现比之前介绍的方式都要简单,但它确实是多线程环境下,C#实现的Singleton的一种方式。由于这种静态初始化的方式是在自己的字段被引用时才会实例化。

让我们通过IL代码来分析静态初始化。





图8静态初始化IL代码

首先这里没有beforefieldinit的修饰符,由于我们添加了静态构造函数当静态字段被引用时才进行初始化,因此即便很多线程试图引用_instance,也需要等静态构造函数执行完并把静态成员_instance实例化之后可以使用。


延迟初始化

/// <summary>
/// Delaies initialization.
/// </summary>
public sealed class Singleton
{
private Singleton()
{
}

/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance { get { return Nested._instance; } }

private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}

internal static readonly Singleton _instance = new Singleton();
}
}



这里我们把初始化工作放到Nested类中的一个静态成员来完成,这样就实现了延迟初始化。


Lazy<T> type

/// <summary>
/// .NET 4's Lazy<T> type
/// </summary>
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());

public static Singleton Instance { get { return lazy.Value; } }

private Singleton()
{
}
}



这种方式的简单和性能良好,而且还提供检查是否已经创建实例的属性IsValueCreated。


具体例子

现在让我们使用单例模式(Singleton)实现负载平衡器,首先我们定义一个服务器类,它包含服务器名和IP地址如下:

/// <summary>
/// Represents a server machine
/// </summary>
class Server
{
// Gets or sets server name
public string Name { get; set; }

// Gets or sets server IP address
public string IP { get; set; }
}




由于负载平衡器只提供一个对象实例供服务器使用,所以我们使用单例模式(Singleton)实现该负载平衡器。

/// <summary>
/// The 'Singleton' class
/// </summary>
sealed class LoadBalancer
{
private static readonly LoadBalancer _instance =
new LoadBalancer();

// Type-safe generic list of servers
private List<Server> _servers;
private Random _random = new Random();

static LoadBalancer()
{
}

// Note: constructor is 'private'
private LoadBalancer()
{
// Load list of available servers
_servers = new List<Server>
{
new Server{ Name = "ServerI", IP = "192.168.0.108" },
new Server{ Name = "ServerII", IP = "192.168.0.109" },
new Server{ Name = "ServerIII", IP = "192.168.0.110" },
new Server{ Name = "ServerIV", IP = "192.168.0.111" },
new Server{ Name = "ServerV", IP = "192.168.0.112" },
};
}

/// <summary>
/// Gets the instance through static initialization.
/// </summary>
public static LoadBalancer Instance
{
get { return _instance; }
}

// Simple, but effective load balancer
public Server NextServer
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r];
}
}
}




上面负载平衡器类LoadBalancer我们使用静态初始化方式实现单例模式(Singleton)。

static void Main()
{
LoadBalancer b1 = LoadBalancer.Instance;
b1.GetHashCode();
LoadBalancer b2 = LoadBalancer.Instance;
LoadBalancer b3 = LoadBalancer.Instance;
LoadBalancer b4 = LoadBalancer.Instance;

// Confirm these are the same instance
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Console.WriteLine("Same instance\n");
}

// Next, load balance 15 requests for a server
LoadBalancer balancer = LoadBalancer.Instance;
for (int i = 0; i < 15; i++)
{
string serverName = balancer.NextServer.Name;
Console.WriteLine("Dispatch request to: " + serverName);
}

Console.ReadKey();
}







图9 LoadBalancer输出结果


1.1.3 总结

单例模式的优点:

单例模式(Singleton)会控制其实例对象的数量,从而确保访问对象的唯一性。

实例控制:单例模式防止其它对象对自己的实例化,确保所有的对象都访问一个实例。
伸缩性:因为由类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。

单例模式的缺点:

系统开销。虽然这个系统开销看起来很小,但是每次引用这个类实例的时候都要进行实例是否存在的检查。这个问题可以通过静态实例来解决。
开发混淆。当使用一个单例模式的对象的时候(特别是定义在类库中的),开发人员必须要记住不能使用new关键字来实例化对象。因为开发者看不到在类库中的源代码,所以当他们发现不能实例化一个类的时候会很惊讶。
对象生命周期。单例模式没有提出对象的销毁。在提供内存管理的开发语言(比如,基于.NetFramework的语言)中,只有单例模式对象自己才能将对象实例销毁,因为只有它拥有对实例的引用。在各种开发语言中,比如C++,其它类可以销毁对象实例,但是这么做将导致单例类内部的指针指向不明。

单例适用性

使用Singleton模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式。反之,如果一个类可以有几个实例共存,就不要使用单例模式。

不要使用单例模式存取全局变量。这违背了单例模式的用意,最好放到对应类的静态成员中。

不要将数据库连接做成单例,因为一个系统可能会与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放,带来问题。


参考:

http://csharpindepth.com/Articles/General/Singleton.aspx



关于作者:

[作者]: JK_Rush从事.NET开发和热衷于开源高性能系统设计,通过博文交流和分享经验,欢迎转载,请保留原文地址,谢谢。

[出处]: http://www.cnblogs.com/rush/

[本文基于]: 署名-非商业性使用
3.0 许可协议发布,欢迎转载,演绎,但是必须保留本文的署名 JK_Rush (包含链接),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

分类: [01] .NET, [02]
C#, [05] Design Pattern

绿色通道: 好文要顶 关注我 收藏该文与我联系






JK_Rush

关注 - 5

粉丝 - 843

荣誉:推荐博客

+加关注

35

0

(请您对文章做出评价)

« 上一篇:享元模式(Flyweight)

» 下一篇:观察者模式(Observer)

posted @ 2011-10-30 21:27 JK_Rush 阅读(19472)
评论(27) 编辑 收藏

评论列表

#1楼 2011-10-30
21:34 轩Δ辕

转载到jcyfkimi.tk

支持(0)反对(0)

#2楼[楼主] 2011-10-30
21:40 JK_Rush

欢迎转载

支持(0)反对(0)

#3楼 2011-10-30
21:51 csdbfans

很好,谢谢分享

支持(0)反对(0)

#4楼 2011-10-30
22:21 峰言峰语

受教了,原来只知道用第二种版本实现单例模式,感谢楼主.

支持(0)反对(0)

#5楼 2011-10-30
22:24 Telon

楼主好文

支持(0)反对(0)

#6楼 2011-10-30
22:54 wu.qiliang

茴字有几种写法?

支持(0)反对(0)

#7楼 2011-10-31
08:26 goodfulcom

楼主解释一下,为什么要Double-Checked Locking ?

支持(0)反对(0)

#8楼 2011-10-31
09:01 alexstrasza

clr via C#书中说道:CLR对静态构造器的调用是线程安全的。

那么你的版本一不安全的说法有待确认哦

支持(0)反对(0)

#9楼 2011-10-31
09:20 倾叶枫城

同意楼上的,记得msdn说过对于静态变量是线程安全的。

支持(0)反对(0)

#10楼 2011-10-31
10:16 wdwwtzy

好文章!!!!真的不错!有些地方豁然开朗~~希望博主可以多写点~~~订阅你的RSS了

支持(0)反对(0)

#11楼 2011-10-31
11:22 aspc

太强了,我调试我们以前的程序老是并发问题,现在看看,还是有许多地方要改进

支持(0)反对(0)

#12楼[楼主] 2011-10-31
20:29 JK_Rush

@alexstrasza

对于单例模式的实现方法一:

我认为在多线程环境下,可以同时存在初始化字段_instance的情况,而且该字段也没有定义为ReadOnly所以可以多次赋值,所以这是线程不安全的。

支持(1)反对(0)

#13楼 2011-11-04
12:50 BLoodMaster

@goodfulcom

为了防止线程间不安全。因为在你判断是空的时候,你锁起来,然后进来,但很可能在你锁的时候,另一个线程正好将其初始化成功了,所以这边需要再检查一次

支持(1)反对(0)

#14楼 2011-11-04
12:52 BLoodMaster

@alexstrasza

方法一的不是静态构造器。静态构造器是后面的静态初始化。这里面的方法1和静态构造器没关系

支持(0)反对(0)

#15楼 2011-11-04
12:54 BLoodMaster

楼主,你文章中没有指出静态构造函数的危险所在啊。构造函数的执行是可以失败的。但静态构造函数只在程序加载是运行一次,如果失败的话,那么只能重启程序。这个是实际单例运用中基本看不到静态构造函数的原因所在吧。因为危险且无自我修复能力

支持(0)反对(0)

#16楼[楼主] 2011-11-04
23:23 JK_Rush

@BLoodMaster

当类被加载时,静态构造函数只执行一次,而非静态函数在可以多次执行在创建对象的过程,这很正确。至于静态构造函数执行失败这种情况,我没有了解过是否存在很大的风险,但还是谢谢您的建议。

支持(0)反对(0)

#17楼 2011-11-11
15:33 wdwwtzy

@JK_Rush

你好,博主,我菜鸟,有个问题想问下。

为什么不可以使用静态类静态方法而一定要用单例,例如你最后的这个实例,完全可以有一个静态类LoadBalancerManager,然后里面有个静态方法GetNextServer(),请教一下单例的好处和静态方法有什么不好,多谢。

支持(0)反对(0)

#18楼[楼主] 2011-11-12
12:26 JK_Rush

@wdwwtzy
你好,

你这个问题问得很好,我把你的问题总结一下就是“单例模式和静态方法(静态类)的区别”

单例类可以继承基类或实现接口,这样我们就可以提供这些类或接口提供一种单例的实现方式。这可以作为你考虑使用单例还是静态方法的依据,希望这能帮你解惑。

支持(0)反对(0)

#19楼 2012-07-03
15:57 C#-coder

标记一下

支持(0)反对(0)

#20楼 2012-07-10
14:22 幻灭城主

mark一下,最简单的就是 直接在 静态构造函数中初始化。

支持(0)反对(0)

#21楼 2012-12-28
15:57 kourosh

看不懂,10月份去北科大参加暴风影音的笔试,最后一题就是叫你写一个单例模式,完全不会,现在还是不会,没有进步啊!╭(╯3╰)╮不过还是蛮感谢分享O(∩_∩)O哈!

支持(0)反对(0)

#22楼 2013-05-06
10:57 尐肥羊

学习中,嘻嘻. . .

支持(0)反对(0)

#23楼 2013-07-13
22:18 gn

楼主好文章 ,在一个内实例化的时候静态变量只在内存分配一片区域,为什么我们还要用单例?问一下静态变量和单例的区别和联系是哪些啊

支持(0)反对(0)

#24楼 2013-08-10
16:00 JailBreak02

“理论上,type initializer应该发生在”Echo!”之后和”After echo”之前”这句应该改为“理论上,type initializer应该发生在”Starting Main”之后和”Echo!”之前”

支持(0)反对(0)

#25楼 2013-08-10
16:16 JailBreak02

@BLoodMaster

赞同,静态构造器是线程安全的,不过在 静态初始化 中有必要申明实例对象 _instance 为 ReadOnly吗

支持(0)反对(0)

#26楼 2013-08-22
11:26 流浪键客

mark

支持(0)反对(0)

#27楼 2013-12-25
17:55 goldmeihua

不太懂,有些地方有问题。

支持(0)反对(0)

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。

博客园首页博问新闻闪存程序员招聘知识库

最新IT新闻:

· 京东出版品牌上线推贝克汉姆自传

· 九城朱骏再复出 拉对手“入伙”转型开放平台

· 当当或建价格监督机制 闪购领域实时全网比价

· 惠普CEO称将于6月宣布进军3D打印市场计划

· 腾讯股价虚高?微信纯社交活跃用户已增长停滞

» 更多新闻...

最新知识库文章:

· 项目经理应该把30%的时间用在编程上

· 一名IT从业者的英语口语能力成长路径

· 我们如何进行代码审查

· 指尖上的浏览:如何理解用户的眼?

· Node.js 究竟是什么?

» 更多知识库文章...


公告

About Me<p http:="" stackoverflow.com="" users="" 792801="" jkhuang"="" style="margin-top: 0px; margin-bottom:
20px; padding-top: 0px; padding-bottom: 0px; outline: none 0px;">


黄钧航(JKhuang),职业攻城师。 有幸从事挨踢职业,从此踏上了学海无涯这条不归路。 曾热衷于ACM,故钟情于数据结构与算法,工作后由于面临系统性能瓶颈问题,故学习前端和后端高性能, 对开源分布式系统和高性能实施方案感兴趣,但个人水平一般固依然无所获。 相信天道酬勤,固孜孜不倦,而且希望能够通过和大家交流分享中获得提高。

座右铭:时间就像一阵风,风会吹去浮沙,留下的是真正重要的东西。

自我修养:能力矩阵

Github Email

昵称:JK_Rush

园龄:3年4个月

荣誉:推荐博客

粉丝:843

关注:5
+加关注

<2011年10月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345


搜索


常用链接

我的随笔
我的评论
我的参与
最新评论
我的标签


最新随笔

1. Knockout JS实现任务管理应用程序
2. 博文占位年后发布
3. Ember.js实现单页面应用程序
4. jQuery实现在线文档
5. jQuery自动加载更多程序
6. Weibo用户地图
7. jQuery实现放大镜效果
8. ASP.NET MVC实现仪表程序
9. [译]C++, Java和C#的编译过程解析
10. 引用CDN内容的方法总结


我的标签

Javascript(9)
jQuery(7)
Asp.net(4)
ASP.NET MVC(2)
C#(2)
.NET(2)
Ajax(2)
Ember(2)
SQL(2)
weibo(2)
更多


随笔分类

[00]
.NET Entlib(3)
[01]
.NET(20)
[02]
C#(25)
[03]
ADO.NET(1)
[04]
ASP.NET(8)
[05]
Design Pattern(11)
[06]
VB.NET(1)
[07]
C/C++(1)
[08]
Web(14)
[09]
Linq
[10]
Algorithm(1)
[11]
Security(4)
[12]
Javascript/jQuery(11)
[13]
High Performance
[14]
SQL(5)
Miscellaneous(1)
Trouble
Shooting
水区(1)


随笔档案

2014年2月
(1)
2014年1月
(1)
2013年12月
(1)
2013年11月
(1)
2013年10月
(1)
2013年9月
(1)
2013年8月
(1)
2013年7月
(1)
2013年6月
(1)
2013年5月
(1)
2013年4月
(1)
2013年3月
(1)
2013年2月
(1)
2013年1月
(1)
2012年12月
(1)
2012年11月
(1)
2012年10月
(1)
2012年9月
(1)
2012年8月
(1)
2012年7月
(1)
2012年6月
(1)
2012年5月
(1)
2012年4月
(1)
2012年3月
(2)
2012年2月
(3)
2012年1月
(1)
2011年12月
(3)
2011年11月
(1)
2011年10月
(2)
2011年9月
(2)
2011年8月
(1)
2011年7月
(2)
2011年6月
(4)
2011年5月
(6)
2011年4月
(4)
2011年3月
(1)
2011年2月
(2)
2011年1月
(1)
2010年11月
(1)


积分与排名

积分 - 121392

排名 - 1022


最新评论

1. Re:Debug Source Code in .NET Framework

如果不需要跟踪调试.NET 代码,只是单纯的想查看.NET 基础类库源码,可以访问扣丁格鲁 http://www.projky.com 就够了,例如,输入 http://www.projky.com/dotnet/4.0/ 就能访问sscli中关于.NET 4.0的源码,按命名空间组织,查找挺方便的。

--ProJKY

2. Re:Knockout JS实现任务管理应用程序

文章排版美观,思路清晰,支持一个。

--liefdiy

3. Re:Ember.js实现单页面应用程序

收藏一下

--unbreakable

4. Re:jQuery实现放大镜效果

看到图就忘记博主前面说的啥了

--skybirdzw

5. Re:Ember.js实现单页面应用程序

没有完整源码吗?

--酷库

6. Re:Ember.js实现单页面应用程序

运行没有效果啊

--linhua

7. Re:Ajax与JSON的一些总结

@JK_Rush

恩,上次这个问题解决了,感谢楼主。不好意思,回复的有些迟:)

--Mr.Smart

8. Re:Trie树和Ternary Search树的学习总结

Trie树的代码中,在FindSimilar中,有没有试过查找前缀不在词典中的字符串?

依我的理解,在你的程序,find函数中,如果前缀不在词典中,是会返回null的,这样后面的DFS的执行就没有意义了。

--robinjia

9. Re:微软企业库Unity学习笔记(一)

正在学习Unity,这篇博客理论部分写的很详细

--IT小兵蛋

10. Re:jQuery自动加载更多程序

非常好,很有启发,谢谢

--KeithMoring


阅读排行榜

1. Ajax与JSON的一些总结(54508)
2. SQL
Join的一些总结(47768)
3. [译]Web设计者和开发者必备的28个Chrome插件(26624)
4. 单例模式(Singleton)的6种实现(19471)
5. ASP.NET
Cache的一些总结(16053)
6. 代理模式(Proxy)(14888)
7.
.NET 中的委托(11338)
8. .NET中的加密算法总结(自定义加密Helper类续)(10861)
9. 索引的一些总结(9344)
10. 网络攻击技术开篇——SQL
Injection(9112)
11. Ember.js的一些学习总结(8532)
12. 网络攻击技术(二)——Cross-site
scripting(7333)
13. SQL
Server 高性能写入的一些总结(6663)
14. Ajax注册表单用户名实时验证(6481)
15.
装饰者(Decorator)(6233)
16. 泛型和反射(5965)
17. 自定义jQuery插件Step
by Step(5916)
18. 网络攻击技术(三)——Denial
Of Service(5000)
19. 打造属于你的加密Helper类(4910)
20. Javascript
this 的一些学习总结(4720)


评论排行榜

1. Ajax与JSON的一些总结(70)
2. ASP.NET
Cache的一些总结(44)
3. 索引的一些总结(39)
4. SQL
Server 高性能写入的一些总结(38)
5. 打造属于你的加密Helper类(29)
6. .NET中的加密算法总结(自定义加密Helper类续)(28)
7. SQL
Join的一些总结(28)
8. 单例模式(Singleton)的6种实现(27)
9.
.NET 中的委托(26)
10. 网络攻击技术开篇——SQL
Injection(25)
11. 仿微博字符统计和本地存储功能的实现(24)
12. ASP.NET MVC实现仪表程序(18)
13. SQL
Transcation的一些总结(18)
14. Javascript
this 的一些学习总结(18)
15. 泛型和反射(15)
16. jQuery实现放大镜效果(12)
17. [译]Web设计者和开发者必备的28个Chrome插件(11)
18. C#中
As 和强制转换的总结(10)
19. 桥接模式(Bridge)(9)
20. 代理模式(Proxy)(9)


推荐排行榜

1. Ajax与JSON的一些总结(200)
2. 索引的一些总结(91)
3. ASP.NET
Cache的一些总结(75)
4. SQL
Join的一些总结(63)
5. SQL
Server 高性能写入的一些总结(42)
6. .NET中的加密算法总结(自定义加密Helper类续)(42)
7. 单例模式(Singleton)的6种实现(35)
8. 网络攻击技术开篇——SQL
Injection(33)
9. Javascript
this 的一些学习总结(28)
10. 仿微博字符统计和本地存储功能的实现(28)
11. 自定义jQuery插件Step
by Step(22)
12.
.NET 中的委托(22)
13. SQL
Transcation的一些总结(19)
14. 泛型和反射(17)
15. Ajax注册表单用户名实时验证(17)
16. 代理模式(Proxy)(16)
17. Deadlock的一些总结(13)
18. ASP.NET MVC实现仪表程序(12)
19. 打造属于你的加密Helper类(12)
20.
装饰者(Decorator)(12)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: