<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_不断的谦逊，不断的努力</title><subtitle type="text">世界上最酷的词汇不是优雅、品味，而是设计;世界上最好的优点是坚韧</subtitle><id>http://feed.cnblogs.com/blog/u/90276/rss</id><updated>2012-05-29T04:12:11Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/90276/rss"/><entry><id>http://www.cnblogs.com/hlxs/archive/2012/05/29/2523706.html</id><title type="text">常见充值方式介绍及对比</title><summary type="text">1：银联充值1：环境部署安装NetPay4NTSetup.exe，将MerPrk.key和PgPubk.key两个文件放到C:\WINDOWS目录下，环境部署完成了。2：程序中要注意的问题最容易导致问题的就是生成加密串，这个加密功能是由银联提共的，调用Interop.CHINAPAYLib.dll中类CHINAPAYLib.NetPayClientClass的sign方法，由于这是对字符串进行加密，不同的字符串加密后的串是不一样的，所以要注意被加密字符前后是否有多余的空格，支付金额的位数，如果加密串生成有误，到银联那边肯定报参数有误的。充值成功后就是回调解密，解密调用的是CHINAPAYLib</summary><published>2012-05-29T03:29:00Z</published><updated>2012-05-29T03:29:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/05/29/2523706.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/05/29/2523706.html"/><content type="html">&lt;p&gt;&lt;strong&gt;1：银联充值&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1：环境部署&lt;/p&gt;&lt;p&gt;安装NetPay4NTSetup.exe，将MerPrk.key和PgPubk.key两个文件放到C:\WINDOWS目录下，环境部署完成了。&lt;/p&gt;&lt;p&gt;2：程序中要注意的问题&lt;/p&gt;&lt;p&gt;最容易导致问题的就是生成加密串，这个加密功能是由银联提共的，调用Interop.CHINAPAYLib.dll中类CHINAPAYLib.NetPayClientClass的sign方法，由于这是对字符串进行加密，不同的字符串加密后的串是不一样的，所以要注意被加密字符前后是否有多余的空格，支付金额的位数，如果加密串生成有误，到银联那边肯定报参数有误的。充值成功后就是回调解密，解密调用的是CHINAPAYLib.NetPayClientClass的check方法，返回&amp;ldquo;0&amp;rdquo;表示成功，其他值表示失败。充值成功才能进行转点和发奖。&lt;/p&gt;&lt;p&gt;3：还要注意的一个问题是充值金额&lt;/p&gt;&lt;p&gt;充值金额是一个12位的字符串，以分作为单位，如000000001000表示10元，不能提交0元的订单。&lt;/p&gt;&lt;p&gt;4：银联订单的大致流程：用户提交一个订单，将部分参数的值加在一起，按照一定的方式加密，将结果和其他参数POST到银联的指定地址，银联会对参数进行验证，如果验证通过则认为是合法的订单，用户可以开始支付，支付成功之后，银联会对两个地址发送请求，一个地址是前台显示页面（告诉用户支付成功），另一个页面则是逻辑功能页面，把用户买的东西给他，先还是验证订单是否合法，进一步确认用户是否已经支付，支付成功后就把东西给用户。并告诉银联已经把东西给用户了，如果出现问题，银联会隔一段时间再次发送请求，时间间隔会越来越大，一定时间过来不再发送请求，有时候银联那边也会出现问题，用户的钱扣了，但是没有向我们指定的页面发送请求，就只能联系银联让他们退钱，所有的支付流程大致都是这样的，只是不同的支付方式验证不一样。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;验证无非3种：&lt;/p&gt;&lt;p&gt;1：参数验证，参数的格式验证，加密串是否匹配&lt;/p&gt;&lt;p&gt;2：IP验证，只有双方约定的IP才能访问&lt;/p&gt;&lt;p&gt;3：订单的验证，验证订单是否支付&lt;/p&gt;&lt;p&gt;1是必验证的，2||3=true就可，就怕为false，那样真的很不安全&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2：快钱充值&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1：环境部署&lt;/p&gt;&lt;p&gt;环境就是为了解决加密解密问题。登录公司在快钱的账号，按照相关提示可以生成一个加密问题和一个解密问题，解密文件要上传到快钱上，因为我们加密后传过去的字符串他们要解密验证。我们的程序只用调用这个两个文件，生成订单的时候要调用加密文件，回调的时候要调用解密文件，这两个文件建议放在C盘的一个目录中，把他们的路径配在配置文件中共程序调用。IP验证是必须的，只能让指定的IP访问就安全多了，如果哪个牛人能突破IP的限制，或者构造虚假的IP，那就真的可以横冲直撞了。&lt;/p&gt;&lt;p&gt;2：生成加密串注意的问题&lt;/p&gt;&lt;p&gt;所有的参数都是先放到Dictionary中的，然后生成一个字符串，参数加入dictionary中的顺序千万不能改，改了就是不同的字符串了，加密后的字符串当然是不一样的。总之要确保加密和解密的参数的顺序是一样的。&lt;/p&gt;&lt;p&gt;3：还要注意的一个问题是充值金额&lt;/p&gt;&lt;p&gt;充值金额没有位数的限制，以分为单位，如1000表示10元，左边不能补0&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3：支付宝&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;支付宝不需要环境的支持。参数用MD5加密，为了确保安全，在回调页还要向支付宝发送一个请求，验证订单是否支付，参数的顺序是按照参数的名字排序的，所以用的是SortedDictionary集合。&lt;/p&gt;&lt;p&gt;注意：所有的参数都要放到集合当中，哪怕是提交按钮，所以提交按钮最好不要设置name属性。这一点也是支付宝最坑爹的，我猜它是将所有参数按照参数名称排序并串联，然后加密的，你的POST参数多了或者少了参数，哪怕是无关没用的参数都会导致加密串验证失败。当然这样做也好处，不用管参数的串联顺序，不像其他的充值方式，非要A参数必须在B参数的前面。&lt;/p&gt;&lt;p&gt;支付宝支付能确保支付的安全性主要是在回调页面还要去支付宝验证订单是否支付，当然还会验证订单的关联是否正确，不然还是有漏洞。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4：神州行和联通卡&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;没有任何特殊，所以注意的地方比较少，确保被加密的参数顺序不变，即参数的顺序是定的，不能改变。参数MD5加密。解密也是最简单的，加密的时候MD5一次，解密的时候在把参数MD5一下，两次MD5结果一样表示已经支付，相比上面几种支付方式，它是最不安全的。虽然回调页面有一个IP限制。 要是没有这个限制那真的是彻底将接口暴露了，只要会点程序的人，都能很容易写一个东西去攻击了，不用付钱就能得到你想要的东西。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5：V币支付&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;V币支付同样没有任何特殊的地方，MD5验证，跟神州行和联通卡类似。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6：骏卡支付&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;骏卡支付跟其他支付方式不一样的地方时我们提供接口，供骏卡那边调用，由于这个接口是公开的，所以做了IP限制，只有骏卡那边提供的IP才能访问这个接口。验证也是MD5加密验证。&lt;/p&gt;&lt;p&gt;流程：用户在骏卡的网站上提交一个订单，然后骏卡会向我们的接口发送一个请求，我们就给用户转一定的点数，然后输出结果。然后骏卡那边会扣用户的骏点。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;网络支付最常用的支付方式一般是：银联支付、块钱支付、支付宝。当然还有其他的支付方式。我觉得这三种支付方式是相对比较安全的。银联和块钱都有自己的加密解密方式，而且用户也不知道哪些参数是加密串的一部分，参数的顺序也是未知的；支付宝虽然是MD5加密，但会在回调页面验证订单是否支付，保证了安全性。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;写着写着发现还是很能存在漏洞，不敢多说了。真要把网站写得很安全真不是简单的事情，要考虑的方面还真的比较多，特别是涉及到支付、提交数据的地方。比如A页面向B页面发送一个请求，B页面向数据库中插入数据，如果没有在B页面中做有效验证，任何程序员就可以花不到半个小时的时间写一个小东西，向B页面不断的提交数据，很容易就把数据库给弄爆了。所以最好别得罪程序员，特别是牛B的程序员。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2523706.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/05/29/2523706.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/05/18/2507506.html</id><title type="text">C#基础知识</title><summary type="text">1：JIT（即时编译）。一个方法在第一次调用时JIT会把改方法的IL代码转换成CPU指令，再次调用该方法时就只需执行对应的指令。方法第一次被调用的过程大致是：1获得方法的IL代码；2：分配内存；3：将IL代码转换成CPU指令存在2分配的内存中；4：将方法表中对应该方法的指针指向2分配的内存；5：跳转到2分配的内存执行其中的指令，即该方法的CPU指令。2：as的性能高于is。Is的作用是判断当前类型与目标类型是否兼容，即是否是同一类型或者目标类型是当前类型的父类型。强制类型转换也要判断类型的兼容性，如果不兼容就抛出一个类型转换异常，如果你的代码类型转换用Is+强制类型转换就做了两次兼容性判断，而</summary><published>2012-05-18T03:33:00Z</published><updated>2012-05-18T03:33:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/05/18/2507506.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/05/18/2507506.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;1&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;JIT&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;（即时编译）。一个方法在第一次调用时&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;JIT&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会把改方法的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码转换成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;指令，再次调用该方法时就只需执行对应的指令。方法第一次被调用的过程大致是：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;获得方法的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码；&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：分配内存；&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：将&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码转换成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;指令存在&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分配的内存中；&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;4&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：将方法表中对应该方法的指针指向&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分配的内存；&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;5&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：跳转到&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分配的内存执行其中的指令，即该方法的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;指令。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;2&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;as&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的性能高于&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;is&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Is&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的作用是判断当前类型与目标类型是否兼容，即是否是同一类型或者目标类型是当前类型的父类型。强制类型转换也要判断类型的兼容性，如果不兼容就抛出一个类型转换异常，如果你的代码类型转换用&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Is+&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;强制类型转换就做了两次兼容性判断，而&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;as&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只有一次类型转换。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;3&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;int&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对应&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;FCL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Int32&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;.net&amp;nbsp;Framework&amp;nbsp;64&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;int&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对应&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;FCL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;int64&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;int&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;到底对应&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Int32&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;还是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Int64&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;重要吗？不重要，那是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;.net&amp;nbsp;Framework&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的事，或者说这他妈是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的事，同一类型，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;64&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;位&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;所需存储的空间是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;32&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;位&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CPU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;倍。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;4&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;string&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是引用类型，常量字符串都存在字符串池中，如果一个字符串在代码中多次出现，那么这些都是对字符串池的引用，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;string&amp;nbsp;s="a"+"b";&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只分配了一次内存，编译器会直接将其编译成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;string&amp;nbsp;s="ab";s&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是对字符串池中&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;ab&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的引用。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;5&lt;span style="font-family: 宋体;"&gt;：大量字符串的拼接用&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;StringBuilder&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，少量则用字符串相加，能用&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;+=&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;则更好，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;string.format&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的效率是低下的，它的内存其实是&lt;/span&gt;params&amp;nbsp;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Object"&gt;object&lt;/a&gt;[]&amp;nbsp;+StringBuilder&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;params&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也是低效的，字符串相加，或是取其中的一部分都是要重新分配内存，然后将对应的字符串存入。&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;FCL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;大部分代码都是用&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;写的，而操作字符串这一块用的是非托管代码写的，处于对性能的考虑。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;6&lt;span style="font-family: 宋体;"&gt;：别看到&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;new&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;就以为会在托管堆中分配内存，值类型的变量就是分配中线程栈上的，结构体虽然可以用&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;new&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，但是编译器推断出它是值类型，就会按照值类型的处理，当然&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码中是没有&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;newobj&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;指令的。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;7&lt;span style="font-family: 宋体;"&gt;：静态类被编译成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;sealed&amp;nbsp;abstract&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类型，所以他不能被继承，不能被实例化，所以他的属性和方法都是属于类型的，没有属于对象的，它必须直接继承&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Object&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;8&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;const&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;readOnly&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的区别，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码中存的是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;const&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变量的值，而不是引用，所以修改是不可能的，如果一个&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;DLL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只引用了另一个&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;DLL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的一个&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;const&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变量，那么这个&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;DLL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是不会被引用的，因为编译的时候就知道变量的值了，所以在运行的时候也不会分配内存，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;readonly&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;表示你不能修改它的指向，但是可以修改它所指向变量的值。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;9&lt;span style="font-family: 宋体;"&gt;：泛型，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的泛型和&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;C++&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的模版区别在于引用类型，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;C++&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;模版会每一种类型都会生成一个新的类型，而&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;泛型中，引用类型用的是同一个类型，只有值类型用的是不同的类型。因为引用都是一个指针的引用，而值类型存储所需的空间是不同的。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;其他基础知识，请看这篇博客：&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/03/28/2420564.html" target="_blank"&gt;这些天写的技术微博&lt;/a&gt;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2507506.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/05/18/2507506.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/05/16/2503978.html</id><title type="text">软件随想--写牛B的代码</title><summary type="text">1：写不易出错的代码 第一次听说“写明显没有什么错误的代码”时，我觉得这个说法很新鲜，让我记忆深刻。其他的很多观点听得我耳朵生茧，基本都是左耳进右耳出。明显没有什么错了的代码肯定是思路清晰、很容易理解的。而要做到这点很难，牛人才能写出牛叉的代码，要做到这一点要有足够的阅历和实战，只能当做目标啦，哪天也和云风一样：今天完成了XX功能，代码明显没有什么错误。现在还不知道明显没有什么错误的代码是怎么样的，但我知道很多代码让我半天不知所云。如从类名和方法名看不出其职能；变量命名让人蛋疼；不对参数做任何验证；参数到处都是都是基本类型；方法参数十几个；一个方法几屏；不能适应半点变化的方法；要么没有注释，要</summary><published>2012-05-16T06:43:00Z</published><updated>2012-05-16T06:43:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/05/16/2503978.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/05/16/2503978.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;span style="font-family: 宋体;"&gt;&lt;strong&gt;：写不易出错的代码&lt;/strong&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;第一次听说&amp;ldquo;写明显没有什么错误的代码&amp;rdquo;时，我觉得这个说法很新鲜，让我记忆深刻。其他的很多观点听得我耳朵生茧，基本都是左耳进右耳出。明显没有什么错了的代码肯定是思路清晰、很容易理解的。而要做到这点很难，牛人才能写出牛叉的代码，要做到这一点要有足够的阅历和实战，只能当做目标啦，哪天也和云风一样：今天完成了XX&lt;span style="font-family: 宋体;"&gt;功能，代码明显没有什么错误。现在还不知道明显没有什么错误的代码是怎么样的，但我知道很多代码让我半天不知所云。如从类名和方法名看不出其职能；变量命名让人蛋疼；不对参数做任何验证；参数到处都是都是基本类型；方法参数十几个；一个方法几屏；不能适应半点变化的方法；要么没有注释，要么一堆废话；排版稀烂。这些都是不好理解，半天找不到问题的代码，也是容易出错的代码。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;2&lt;span style="font-family: 宋体;"&gt;：写容易查错的代码&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;一直想写很干净的代码，代码除了功能没有多余的代码，但是代码必须有日志，如果代码没有日志，要是出错了，查错肯定很麻烦，有时候真的是无从下手，一个功能涉及到一堆的模块，要想很快的定位错误，就必须记好日志。越清楚越好，程序执行到哪一步，当前的状态最好都要记下来，日志不在多，清楚记录有效的日志非常重要，过多无效的日志不方便查看，而且对于快速定位错误的位置没有任何帮助。如果日志都记录在文本文件中，最好能写一个分析日志的工具。可能是我写的和维护的代码太容易出错了，个人觉得记好日志真他妈重要。一看到日志就能知道出了什么问题那不是一般的爽，当然听说又出问题了让人郁闷。我以前所在的一家公司记录日志的方式是在很多类中都定义一个int&lt;span style="font-family: 宋体;"&gt;类型的成员变量，每隔几行让它自增&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，将这个值记录起来，当出错了就能大致估计是哪几行出错了。这种方法虽然有点蹩脚，代码中到处是这个变量，但的确能帮助我们快速定位错误的位置，日志的作用就是保存案发现场，只有记录犯罪分子作案的过程才能更好的抓住它。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;3&lt;span style="font-family: 宋体;"&gt;：写扩展性好的代码&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;ldquo;今天说要这样，明天说要那样，在上线的前一天说：还是觉得开始的做法是最好的&amp;rdquo;。而我们程序员总是为这种人2B&lt;span style="font-family: 宋体;"&gt;的想法买单。写扩展性好的代码真的就是不仅要满足需求还要超越需求。我们到处可以听到这样的口号，当然很多情况下是这样的人自己都不知道需求是什么。最让人无语的是菜鸟提需求，我来实现。杀了我吧。但现实是杀了我之前我先要满足他的需求。当这种需求像滔滔江水绵延不绝的袭来时，我想到了四个字：生不如死。既然死不了，生活还得继续。代码还是要做到超越需求（你说这世界对程序员要求怎么就这么高呢），&lt;/span&gt;要做到这点难啊，我们是帮别人实现梦想的开拓者。前途是光明的，道路是坎坷的，现实是残酷的，代码必须是扩展性好的。当然这里所说都是人为因素。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;还有就是项目的需求本来就是变化的，或者说你现在完成的是一期，还有二期，三期&lt;span style="font-family: Times New Roman;"&gt;......&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，你在做的时候就必须考虑这些情况，不要把代码写死。我以前总是想：这个可能以后不会变化，可以写死，少一个参数，少一个变量性能会更好写。其实性能的提升相当于一个千万富翁突然多了几毛钱。但是要是以后需求变了，你就得改写代码，还得担心是否会出问题。有时候我就有点怕重构，就怕一个好的功能，被重构坏了，当然也和时间紧，测试不专业有关。写扩展性好的代码别在乎所谓的那点性能，那真的就是九牛一毛不值一提。一个项目维护时间久了，发现那些本来看是不变的很多都变了，而代码也被改了很多次，每一次修改就要做一堆本来没有必要的事情（修改代码，写测试说明，送测，协调上线，而这些沟通时间也不少，真叫一个低效浪费时间），如果能考虑到可能发生的变化，写好代码，效率会高很多，这一点就能体现高手和菜鸟的区别。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;4&lt;span style="font-family: 宋体;"&gt;：写高性能的代码&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;这是我一直渴望的（我当然也会说是我还没有做到的）。我觉得要写出高效的代码首先要非常明白你要实现的功能，将功能分析得很透彻，你找到了解决方案，回想你的实现，如果你的思路非常清晰，你就大致知道每一步是否够好，大致知道你的代码是否高效，或者更进一步说，你确定这就是最优解；如果功能实现了，但是你对自己实现的功能不是很了解，记忆模糊，那肯定不是最优解，你肯定会对自己不是很清楚的代码不放心（我经常是这样），就别谈性能，是否正确都待定。很多高效的代码都很简洁，容易理解，而有些代码总让人看起来很郁闷，如一堆看起来类似的代码实现一个很简单的功能。用数组和一个循环经常能将这样的代码简化，让你轻松实现简洁容易理解的代码，或许它不是最高效的。&lt;span style="font-family: Times New Roman;"&gt;82&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;法则告诉我们，我们应该对影响系统性能的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;20%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的代码进行优化，而不应对其他的&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;80%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的代码耿耿于怀。&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;20%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;影响性能的代码应注重性能进行优化，而其他&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;80%&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;则更多应该考虑理解性，扩展性等。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;高手的代码特点有很多，很多优点是并存的。上面只是我个人认为最重要的四点。&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;顺便说一句：蛋扯多了才能扯得更好。&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/03/03/2378249.html" target="_blank"&gt;软件随想&lt;/a&gt;上一篇：&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/03/03/2378249.html"&gt;http://www.cnblogs.com/hlxs/archive/2012/03/03/2378249.html&lt;/a&gt;&lt;/p&gt;&lt;h5 class="p0"&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;&lt;span style="color: #000000;"&gt;陈太汉&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;&lt;span style="color: #000000;"&gt;http://www.cnblogs.com/hlxs/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2503978.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/05/16/2503978.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/05/08/2490034.html</id><title type="text">三道简单的算法题</title><summary type="text">好久没有做算法题了，重温几个简单的算法题。第一题：求子数组的最大和这是一道很常见的算法题，很多人都能很快的写出算法，但很多人都不能写得完全正确，问题主要出在sum初始化上，很多错误的答案将他初始化为0，如果数组的所有元素都为负，那么得到的最大最是0，sum要初始化成数组的第一个元素。第二题：求1+2+…+n，要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句 这道题在网上也有很多个版本，有在构造函数中实现加法，利用两个静态变量一个存结果，一个存当前值，然后创建一个一维n个元素的数组，存结果的静态变量即为所求，还有的就是用两个方法，一个方法是递</summary><published>2012-05-08T06:20:00Z</published><updated>2012-05-08T06:20:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/05/08/2490034.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/05/08/2490034.html"/><content type="html">&lt;p&gt;好久没有做算法题了，重温几个简单的算法题。&lt;br /&gt;&lt;strong&gt;第一题：求子数组的最大和&lt;/strong&gt;&lt;br /&gt;这是一道很常见的算法题，很多人都能很快的写出算法，但很多人都不能写得完全正确，问题主要出在sum初始化上，&lt;br /&gt;很多错误的答案将他初始化为0，如果数组的所有元素都为负，那么得到的最大最是0，sum要初始化成数组的第一个元素。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第二题：求1+2+&amp;hellip;+n，要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句&lt;/strong&gt; &lt;br /&gt;这道题在网上也有很多个版本，有在构造函数中实现加法，利用两个静态变量一个存结果，一个存当前值，然后创建一个一维n个元素的数组，存结果的静态变量即为所求，&lt;br /&gt;还有的就是用两个方法，一个方法是递归的，另一个值返回常量值0，就是把递归中的判断改成了一个返回值始终是0的方法。&lt;br /&gt;我要说的是第三者方法：利用模板和关键字inline，编译后的结果就是：1+2+...+n，不会生成一堆方法的调用，因为将方法定义成了inline。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;第三题：输入一颗二元树，从上往下按层打印树的每个结点，同一层中按照从左往右的顺序打印。&lt;/strong&gt;&lt;br /&gt;这道题主要用上了队列的思想，先进先出，因为我们很容易实现以层的顺序将二叉树中的元素插入队列，&lt;br /&gt;先将根节点插入队列，每个节点出队列的同时将其子节点加入队列。打印出队列的节点。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;求子数组的最大和&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; maxSum(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;* arr,&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; len)&lt;br/&gt;{ &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; sum,max;&lt;br/&gt;    sum&lt;/span&gt;=max=arr[&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]; &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i=&lt;span style="color: #800080;"&gt;1&lt;/span&gt;;i&amp;lt;len;i++&lt;span style="color: #000000;"&gt;)&lt;br/&gt;    { &lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(sum&amp;lt;=&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;        {&lt;br/&gt;            sum&lt;/span&gt;=&lt;span style="color: #000000;"&gt;arr[i];&lt;br/&gt;        }&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;{&lt;br/&gt;            sum&lt;/span&gt;+=&lt;span style="color: #000000;"&gt;arr[i];&lt;br/&gt;        }&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(sum&amp;gt;&lt;span style="color: #000000;"&gt;max)&lt;br/&gt;        {&lt;br/&gt;            max&lt;/span&gt;=&lt;span style="color: #000000;"&gt;sum;&lt;br/&gt;        } &lt;br/&gt;    }&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; max;&lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;求1+2+&amp;hellip;+n，要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句&lt;/span&gt;&lt;br/&gt;template&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; n&amp;gt; inline &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Sum(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; m)&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Sum&amp;lt;n-&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt;(m-&lt;span style="color: #800080;"&gt;1&lt;/span&gt;)+&lt;span style="color: #000000;"&gt;m;&lt;br/&gt;}&lt;br/&gt; &lt;br/&gt;template&lt;/span&gt;&amp;lt;&amp;gt; inline &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Sum&amp;lt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt;(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; m)&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;template&lt;/span&gt;&amp;lt;&amp;gt; inline &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Sum&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; m)&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="height: 500px;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第三题：输入一颗二元树，从上往下按层打印树的每个结点，同一层中按照从左往右的顺序打印。&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; PrintByFloor&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br/&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt; Node&lt;br/&gt;        {&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; value;&lt;br/&gt;            Node&lt;/span&gt;*&lt;span style="color: #000000;"&gt; left;&lt;br/&gt;            Node&lt;/span&gt;*&lt;span style="color: #000000;"&gt; right;&lt;br/&gt;            Node(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; val):value(val),left(NULL),right(NULL){}&lt;br/&gt;        };&lt;br/&gt;&lt;br/&gt;       PrintByFloor():root(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Node(-&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)){}&lt;br/&gt;             &lt;br/&gt;        &lt;br/&gt;       &lt;/span&gt;~&lt;span style="color: #000000;"&gt;PrintByFloor(){&lt;br/&gt;             MakeEmpty(root);&lt;br/&gt;       }&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Print()&lt;br/&gt;        {&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(root==&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;            {&lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;            }&lt;br/&gt;            queue&lt;/span&gt;&amp;lt;Node*&amp;gt;&lt;span style="color: #000000;"&gt; queue;&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(root-&amp;gt;left!=&lt;span style="color: #000000;"&gt;NULL){&lt;br/&gt;                queue.push(root&lt;/span&gt;-&amp;gt;&lt;span style="color: #000000;"&gt;left);&lt;br/&gt;            }&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br/&gt;            {&lt;br/&gt;                queue.push(root&lt;/span&gt;-&amp;gt;&lt;span style="color: #000000;"&gt;right);&lt;br/&gt;            }&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;(queue.size())&lt;br/&gt;            {&lt;br/&gt;                Node&lt;/span&gt;* cur=&lt;span style="color: #000000;"&gt;queue.front();&lt;br/&gt;                cout&lt;/span&gt;&amp;lt;&amp;lt;cur-&amp;gt;value&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\t&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(cur-&amp;gt;left!=&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;                {&lt;br/&gt;                    queue.push(cur&lt;/span&gt;-&amp;gt;&lt;span style="color: #000000;"&gt;left);&lt;br/&gt;                }&lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(cur-&amp;gt;right!=&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;                {&lt;br/&gt;                    queue.push(cur&lt;/span&gt;-&amp;gt;&lt;span style="color: #000000;"&gt;right);&lt;br/&gt;                }&lt;br/&gt;                queue.pop();&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;  &lt;br/&gt;        Node&lt;/span&gt;* Add(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; value,Node *&lt;span style="color: #000000;"&gt;t)&lt;br/&gt;        {&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(t==&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;            {&lt;br/&gt;                t&lt;/span&gt;=&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Node(value);&lt;br/&gt;            }&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(value&amp;lt;t-&amp;gt;&lt;span style="color: #000000;"&gt;value)&lt;br/&gt;            {&lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(t-&amp;gt;left==&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;                {&lt;br/&gt;                    t&lt;/span&gt;-&amp;gt;left=&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Node(value);&lt;br/&gt;                }&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;{&lt;br/&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Add(value,t-&amp;gt;&lt;span style="color: #000000;"&gt;left);&lt;br/&gt;                }&lt;br/&gt;            }&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(value&amp;gt;t-&amp;gt;&lt;span style="color: #000000;"&gt;value)&lt;br/&gt;            {&lt;br/&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(t-&amp;gt;right==&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;                {&lt;br/&gt;                    t&lt;/span&gt;-&amp;gt;right=&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Node(value);&lt;br/&gt;                }&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;{&lt;br/&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Add(value,t-&amp;gt;&lt;span style="color: #000000;"&gt;right);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; t;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        Node&lt;/span&gt;* Add(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; value)&lt;br/&gt;        {&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; Add(value,root);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; :&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; MakeEmpty(Node *&lt;span style="color: #000000;"&gt;t)&lt;br/&gt;        {&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(t!=&lt;span style="color: #000000;"&gt;NULL)&lt;br/&gt;            {&lt;br/&gt;                MakeEmpty(t&lt;/span&gt;-&amp;gt;&lt;span style="color: #000000;"&gt;left);&lt;br/&gt;                MakeEmpty(t&lt;/span&gt;-&amp;gt;&lt;span style="color: #000000;"&gt;right);&lt;br/&gt;                delete t;&lt;br/&gt;                t&lt;/span&gt;=&lt;span style="color: #000000;"&gt;NULL;&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt; &lt;br/&gt;        Node &lt;/span&gt;*&lt;span style="color: #000000;"&gt;root;&lt;br/&gt;     &lt;br/&gt;};&lt;/span&gt;&lt;/div&gt;&lt;p&gt;测试代码如下：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;测试代码&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; main() { &lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; arr[]={&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,-&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;,-&lt;span style="color: #800080;"&gt;6&lt;/span&gt;,-&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,-&lt;span style="color: #800080;"&gt;7&lt;/span&gt;&lt;span style="color: #000000;"&gt;};&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; maxValue=maxSum(arr,&lt;span style="color: #0000ff;"&gt;sizeof&lt;/span&gt;(arr)/&lt;span style="color: #0000ff;"&gt;sizeof&lt;/span&gt;(arr[&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]));&lt;br/&gt;    cout&lt;/span&gt;&amp;lt;&amp;lt;maxValue&amp;lt;&amp;lt;&lt;span style="color: #000000;"&gt;endl; &lt;br/&gt;&lt;br/&gt;    {&lt;br/&gt;        PrintByFloor floor; &lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;7&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;11&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;9&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;12&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Add(&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;        floor.Print();&lt;br/&gt;    }&lt;br/&gt;    cout&lt;/span&gt;&amp;lt;&amp;lt;&lt;span style="color: #000000;"&gt;endl;&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; sum=Sum&amp;lt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&amp;gt;(&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;    cout&lt;/span&gt;&amp;lt;&amp;lt;sum&amp;lt;&amp;lt;&lt;span style="color: #000000;"&gt;endl;&lt;br/&gt;    getchar();&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;} &lt;/span&gt;&lt;/div&gt;&lt;p&gt;结果截图：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/142192/2012050814170892.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2490034.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/05/08/2490034.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/05/07/2487082.html</id><title type="text">提高SQL查询效率</title><summary type="text">转载：http://panyi5202.iteye.com/blog/6124141.对查询进行优化，应尽量避免全表扫描，首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断，否则将导致引擎放弃使用索引而进行全表扫描，如：select id from t where num is null可以在num上设置默认值0，确保表中num列没有null值，然后这样查询：select id from t where num=03.应尽量避免在 where 子句中使用!=或&lt;&gt;操作符，否则将引擎放弃使用索引而进行</summary><published>2012-05-07T03:09:00Z</published><updated>2012-05-07T03:09:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/05/07/2487082.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/05/07/2487082.html"/><content type="html">&lt;p&gt;&lt;strong&gt;转载：http://panyi5202.iteye.com/blog/612414&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1.对查询进行优化，应尽量避免全表扫描，首先应考虑在 where 及 order by 涉及的列上建立索引。 &lt;br /&gt;&lt;br /&gt;2.应尽量避免在 where 子句中对字段进行 null 值判断，否则将导致引擎放弃使用索引而进行全表扫描，如：&lt;br /&gt;select id from t where num is null&lt;br /&gt;可以在num上设置默认值0，确保表中num列没有null值，然后这样查询：&lt;br /&gt;select id from t where num=0&lt;br /&gt;&lt;br /&gt;3.应尽量避免在 where 子句中使用!=或&amp;lt;&amp;gt;操作符，否则将引擎放弃使用索引而进行全表扫描。&lt;br /&gt;&lt;br /&gt;4.应尽量避免在 where 子句中使用 or 来连接条件，否则将导致引擎放弃使用索引而进行全表扫描，如：&lt;br /&gt;select id from t where num=10 or num=20&lt;br /&gt;可以这样查询：&lt;br /&gt;select id from t where num=10&lt;br /&gt;union all&lt;br /&gt;select id from t where num=20&lt;br /&gt;&lt;br /&gt;5.in 和 not in 也要慎用，否则会导致全表扫描，如：&lt;br /&gt;select id from t where num in(1,2,3)&lt;br /&gt;对于连续的数值，能用 between 就不要用 in 了：&lt;br /&gt;select id from t where num between 1 and 3&lt;br /&gt;&lt;br /&gt;6.下面的查询也将导致全表扫描：&lt;br /&gt;select id from t where name like '%abc%'&lt;br /&gt;若要提高效率，可以考虑全文检索。&lt;br /&gt;&lt;br /&gt;7.如果在 where 子句中使用参数，也会导致全表扫描。因为SQL只有在运行时才会解析局部变量，但优化程序不能将访问计划的选择推迟到运行时；它必须在编译时进行选择。然而，如果在编译时建立访问计划，变量的值还是未知的，因而无法作为索引选择的输入项。如下面语句将进行全表扫描：&lt;br /&gt;select id from t where num=@num&lt;br /&gt;可以改为强制查询使用索引：&lt;br /&gt;select id from t with(index(索引名)) where num=@num&lt;br /&gt;&lt;br /&gt;8.应尽量避免在 where 子句中对字段进行表达式操作，这将导致引擎放弃使用索引而进行全表扫描。如：&lt;br /&gt;select id from t where num/2=100&lt;br /&gt;应改为:&lt;br /&gt;select id from t where num=100*2&lt;br /&gt;&lt;br /&gt;9.应尽量避免在where子句中对字段进行函数操作，这将导致引擎放弃使用索引而进行全表扫描。如：&lt;br /&gt;select id from t where substring(name,1,3)='abc'--name以abc开头的id&lt;br /&gt;select id from t where datediff(day,createdate,'2005-11-30')=0--&amp;lsquo;2005-11-30&amp;rsquo;生成的id&lt;br /&gt;应改为:&lt;br /&gt;select id from t where name like 'abc%'&lt;br /&gt;select id from t where createdate&amp;gt;='2005-11-30' and createdate&amp;lt;'2005-12-1'&lt;br /&gt;&lt;br /&gt;10.不要在 where 子句中的&amp;ldquo;=&amp;rdquo;左边进行函数、算术运算或其他表达式运算，否则系统将可能无法正确使用索引。&lt;br /&gt;&lt;br /&gt;11.在使用索引字段作为条件时，如果该索引是复合索引，那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引，否则该索引将不会被使用，并且应尽可能的让字段顺序与索引顺序相一致。&lt;br /&gt;&lt;br /&gt;12.不要写一些没有意义的查询，如需要生成一个空表结构：&lt;br /&gt;select col1,col2 into #t from t where 1=0&lt;br /&gt;这类代码不会返回任何结果集，但是会消耗系统资源的，应改成这样：&lt;br /&gt;create table #t(...)&lt;br /&gt;&lt;br /&gt;13.很多时候用 exists 代替 in 是一个好的选择：&lt;br /&gt;select num from a where num in(select num from b)&lt;br /&gt;用下面的语句替换：&lt;br /&gt;select num from a where exists(select 1 from b where num=a.num)&lt;br /&gt;&lt;br /&gt;14.并不是所有索引对查询都有效，SQL是根据表中数据来进行查询优化的，当索引列有大量数据重复时，SQL查询可能不会去利用索引，如一表中有字段sex，male、female几乎各一半，那么即使在sex上建了索引也对查询效率起不了作用。&lt;br /&gt;&lt;br /&gt;15.索引并不是越多越好，索引固然可以提高相应的 select 的效率，但同时也降低了 insert 及 update 的效率，因为 insert 或 update 时有可能会重建索引，所以怎样建索引需要慎重考虑，视具体情况而定。一个表的索引数最好不要超过6个，若太多则应考虑一些不常使用到的列上建的索引是否有必要。&lt;br /&gt;&lt;br /&gt;16.应尽可能的避免更新 clustered 索引数据列，因为 clustered 索引数据列的顺序就是表记录的物理存储顺序，一旦该列值改变将导致整个表记录的顺序的调整，会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列，那么需要考虑是否应将该索引建为 clustered 索引。&lt;br /&gt;&lt;br /&gt;17.尽量使用数字型字段，若只含数值信息的字段尽量不要设计为字符型，这会降低查询和连接的性能，并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符，而对于数字型而言只需要比较一次就够了。&lt;br /&gt;&lt;br /&gt;18.尽可能的使用 varchar/nvarchar 代替 char/nchar ，因为首先变长字段存储空间小，可以节省存储空间，其次对于查询来说，在一个相对较小的字段内搜索效率显然要高些。&lt;br /&gt;&lt;br /&gt;19.任何地方都不要使用 select * from t ，用具体的字段列表代替&amp;ldquo;*&amp;rdquo;，不要返回用不到的任何字段。&lt;br /&gt;&lt;br /&gt;20.尽量使用表变量来代替临时表。如果表变量包含大量数据，请注意索引非常有限（只有主键索引）。&lt;br /&gt;&lt;br /&gt;21.避免频繁创建和删除临时表，以减少系统表资源的消耗。&lt;br /&gt;&lt;br /&gt;22.临时表并不是不可使用，适当地使用它们可以使某些例程更有效，例如，当需要重复引用大型表或常用表中的某个数据集时。但是，对于一次性事件，最好使用导出表。&lt;br /&gt;&lt;br /&gt;23.在新建临时表时，如果一次性插入数据量很大，那么可以使用 select into 代替 create table，避免造成大量 log ，以提高速度；如果数据量不大，为了缓和系统表的资源，应先create table，然后insert。&lt;br /&gt;&lt;br /&gt;24.如果使用到了临时表，在存储过程的最后务必将所有的临时表显式删除，先 truncate table ，然后 drop table ，这样可以避免系统表的较长时间锁定。&lt;br /&gt;&lt;br /&gt;25.尽量避免使用游标，因为游标的效率较差，如果游标操作的数据超过1万行，那么就应该考虑改写。&lt;br /&gt;&lt;br /&gt;26.使用基于游标的方法或临时表方法之前，应先寻找基于集的解决方案来解决问题，基于集的方法通常更有效。&lt;br /&gt;&lt;br /&gt;27.与临时表一样，游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法，尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括&amp;ldquo;合计&amp;rdquo;的例程通常要比使用游标执行的速度快。如果开发时间允许，基于游标的方法和基于集的方法都可以尝试一下，看哪一种方法的效果更好。&lt;br /&gt;&lt;br /&gt;28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ，在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。&lt;br /&gt;&lt;br /&gt;29.尽量避免大事务操作，提高系统并发能力。&lt;br /&gt;&lt;br /&gt;30.尽量避免向客户端返回大数据量，若数据量过大，应该考虑相应需求是否合理&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2487082.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/05/07/2487082.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/04/19/2456949.html</id><title type="text">C#成员初始化有点坑爹</title><summary type="text">C#成员的初始化顺序你真的非常清楚吗，我发现有点坑爹，坑到爹突然有点搞不清楚什么状况。下面咱们开始分析，先看3个简单类。 public abstract class Base { public Base() { SetValue(); } public abstract void SetValue(); } public class Sub : Base { public string value; public Sub() { ...</summary><published>2012-04-19T05:25:00Z</published><updated>2012-04-19T05:25:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/04/19/2456949.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/04/19/2456949.html"/><content type="html">&lt;div class="Section0" style="layout-grid: 15.6pt none;"&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 10.5pt; mso-spacerun: 'yes';"&gt;C#&lt;span style="font-family: 宋体;"&gt;成员的初始化顺序你真的非常清楚吗，我发现有点坑爹，坑到爹突然有点搞不清楚什么状况。下面咱们开始分析，先看&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个简单类。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Base&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Base()&lt;br/&gt;        {&lt;br/&gt;            SetValue();&lt;br/&gt;        }&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; SetValue();&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub : Base&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; value;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub()&lt;br/&gt;        {&lt;br/&gt;            value &lt;/span&gt;= &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;chentaihan&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; SetValue()&lt;br/&gt;        {&lt;br/&gt;            value &lt;/span&gt;= &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;陈太汉&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub1 : Base&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; value = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;chentaihan&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; SetValue()&lt;br/&gt;        {&lt;br/&gt;            value &lt;/span&gt;= &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;陈太汉&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;        }&lt;br/&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 10.5pt; mso-spacerun: 'yes';"&gt;如果执行下面这段代码会输出什么值呢，请不要往下看，先给出你自己的答案。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;        {&lt;br/&gt;            Sub sub &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub();&lt;br/&gt;            Console.WriteLine(sub.value);&lt;br/&gt;            Sub1 sub1 &lt;/span&gt;= &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub1();&lt;br/&gt;            Console.WriteLine(sub1.value);&lt;br/&gt;            Console.Read();&lt;br/&gt;        }&lt;br/&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 10.5pt; mso-spacerun: 'yes';"&gt;是的他很简单，但你确信你的答案就是对的吗？这么一个简单的问题我答错了，所以就有了这篇博客。&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&lt;strong&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 13pt; mso-spacerun: 'yes';"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;CLR&amp;nbsp;VIA&amp;nbsp;C#&lt;span style="font-family: 宋体;"&gt;这本书告诉我们：成员在定义的时候初始化相当于在构造函数的最上面初始化，如果一个成员在定义的时候初始化，并在构造函数中赋值，那么在构造函数执行完成之后，该成员的值就是造函数中所赋的值，所以我得出的答案都是：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;chentaihan&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。但答案不是这样的。当运行结果出来时，我那个迷茫啊&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;.....&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="color: #888888;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;先来说说我的简单分析：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="color: #888888;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;1&lt;span style="font-family: 宋体;"&gt;：进入子类构造函数&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="color: #888888;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;2&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Sub&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;成员变量的内存被分配&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="color: #888888;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;3&lt;span style="font-family: 宋体;"&gt;：调用父类构造函数&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="color: #888888;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;4&lt;span style="font-family: 宋体;"&gt;：调用子类的方法&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 13pt; mso-spacerun: 'yes';"&gt;SetValue&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;(&lt;span style="font-family: 宋体;"&gt;子类覆写了这个方法&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被赋值&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="color: #888888;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;5&lt;span style="font-family: 宋体;"&gt;：正式执行子类构造函数，成员变量&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;再次被赋值&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;从上面&lt;span style="font-family: Times New Roman;"&gt;5&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;步我得出他们输出的结果一样，都是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;chentaihan&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。错在哪里呢？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;于是我用&lt;span style="font-family: Times New Roman;"&gt;Reflector&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;查看了一下，得到的结果正如上面所说，他们的源码是一样的，如下所示。正如&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;CLR&amp;nbsp;VIA&amp;nbsp;C#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这本书说的那样，那为什么结果不一样呢，&lt;/span&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="font-family: Times New Roman;"&gt;Reflector&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码是一样的，执行的结果却不一样，怎么回事，怎么回事，那我只能说&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Reflector&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-family: 宋体;"&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;坑爹，它不能反映程序的真正执行逻辑&lt;/span&gt;&lt;/strong&gt;，非要我用&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，我用的还不熟呢。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;   &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub : Base&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; value;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Sub()&lt;br/&gt;        {&lt;br/&gt;            value &lt;/span&gt;= &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;chentaihan&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; SetValue()&lt;br/&gt;        {&lt;br/&gt;            value &lt;/span&gt;= &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;陈太汉&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;        }&lt;br/&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;神马情况，他们的&lt;span style="font-family: Times New Roman;"&gt;IL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码是不一样的，如图所示&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/142192/2012041913220587.jpg" alt="" /&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;看了这个图，我们知道答案是&lt;span style="font-family: Times New Roman;"&gt;chentaihan,&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;陈太汉。谁能告诉我怎么调用父类的构造函数和给&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;赋值的顺序不一样啊。该用的工具都用了，我该怎么证明这个结果，于是开始单步调试，于是发现了一个每天都发现了的秘密：&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; font-weight: bold; mso-spacerun: 'yes';"&gt;成员初始化在构造函数之前执行。&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; font-weight: normal; mso-spacerun: 'yes';"&gt;难怪这本书上说&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;成员在定义的时候初始化相当于在构造函数的最上面初始化，&lt;span style="font-family: Times New Roman;"&gt;Reflector&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也证实了这个答案。但是又绕进另一个坑爹的问题：构造函数还没有调用&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; font-weight: normal; mso-spacerun: 'yes';"&gt;，内存还没有分配，怎么给成员变量赋值啊？这不是问题，从上图可以看出成员变量的赋值只是在父类的构造函数之前调用，肯定也是在子类的成员变量分配空间之后为成员变量赋值。好的，最后我们得出的结论是：&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;1&lt;span style="font-family: 宋体;"&gt;：进入子类构造函数&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;2&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;Sub&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;成员变量的内存被分配&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;3&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; font-weight: bold; mso-spacerun: 'yes';"&gt;为&lt;span style="font-family: Times New Roman;"&gt;Sub&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;成员变量赋值&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;4&lt;span style="font-family: 宋体;"&gt;：调用父类构造函数&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;5&lt;span style="font-family: 宋体;"&gt;：调用子类的方法&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 13pt; mso-spacerun: 'yes';"&gt;SetValue&lt;/span&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;(&lt;span style="font-family: 宋体;"&gt;子类覆写了这个方法&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被赋值&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;6&lt;span style="font-family: 宋体;"&gt;：正式执行子类构造函数，成员变量&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;再次被赋值&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;strong&gt;&lt;span style="font-family: '宋体'; color: #ff0000; font-size: 13pt; mso-spacerun: 'yes';"&gt;&lt;span style="font-family: 宋体;"&gt;同意以上观点的人请放过我，别吐槽，不同意的请留言&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&lt;span style="font-family: '宋体'; font-size: 13pt; mso-spacerun: 'yes';"&gt;这样的解释答案就很合理，但同时也说明成员变量在定义的时候初始化和在构造函数中赋值的意义是不一样的，至少执行顺序不一样，产生的结果可能也不一样。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/142192/2012041913260161.jpg" alt="" /&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;&lt;span style="color: #000000;"&gt;陈太汉&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;&lt;span style="color: #000000;"&gt;http://www.cnblogs.com/hlxs/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="p0" style="margin-top: 0pt; margin-bottom: 0pt;"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2456949.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/04/19/2456949.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/04/12/2443722.html</id><title type="text">C#内存管理与垃圾回收</title><summary type="text">垃圾回收还得从根说起，就像生儿育女一样。根：根是一个位置，存放一个指针，该指针指向托管堆中的一个对象，或是一个空指针不指向任何对象，即为null。根存在线程栈或托管堆中，大部分的跟都在线程栈上，因为定义的变量就存在线程栈上，类型对象指针存在托管堆中，因为实例化一个对象要额外分配两个字段“类型对象指针”和“同步块索引”。类型对象指针的作用。实例化一个对象并没有为其方法分配内存，类型的静态字段分配内存，而实例要向调用属于类型的一些东西，就必须通过类型对象指针。如对象的实例是共用类型的方法，实例只需要通过类型对象指针调用类型的方法，更多关于方法的调用请看我的这篇博客。同步块索引的作用。1：用于loc</summary><published>2012-04-12T04:21:00Z</published><updated>2012-04-12T04:21:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/04/12/2443722.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/04/12/2443722.html"/><content type="html">&lt;p class="p0"&gt;垃圾回收还得从根说起，就像生儿育女一样。&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;根&lt;/strong&gt;：根是一个位置，存放一个指针，该指针指向托管堆中的一个对象，或是一个空指针不指向任何对象，即为null。根存在线程栈或托管堆中，大部分的跟都在线程栈上，因为定义的变量就存在线程栈上，类型对象指针存在托管堆中，因为实例化一个对象要额外分配两个字段&amp;ldquo;类型对象指针&amp;rdquo;和&amp;ldquo;同步块索引&amp;rdquo;。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;类型对象指针的作用&lt;/strong&gt;。实例化一个对象并没有为其方法分配内存，类型的静态字段分配内存，而实例要向调用属于类型的一些东西，就必须通过类型对象指针。如对象的实例是共用类型的方法，实例只需要通过类型对象指针调用类型的方法，更多关于方法的调用请看我的&lt;span style="color: #ff0000;"&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2011/12/10/2283400.html"&gt;&lt;span style="color: #ff0000;"&gt;这篇博客&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;同步块索引的作用&lt;/strong&gt;。1：用于lock，使对象在同一时刻只能一个线程访问；2：用于获取对象的hashCode;3:在垃圾回收时标志某个对象是否是垃圾。关于&lt;span style="font-family: Verdana;"&gt;lock&lt;/span&gt;最经典的一个例子就是单例了，大家的实现都是实例化一个object对象，然后锁住它，然后在判断是否要实例要实现单例的那个对象。我们为什么要实例化一个object，而不是直接lock(typeof(object))，那是因为这样会把object这个类型给锁住，锁住期间，任何使用线程使用lock(typeof(object))就必须等待，object还是可以正常使用。lock能起到单线程访问的原因是：它里面有一个空的for死循环，一直在读同步块索引中的一个位，如果这个位没有被标志跳出循环，如果被标志就一直执行循环，直到方法执行完成，其他线程就一直等待，现在你知道lock能使你的程序只能单线程反问也知道lock的效率低了吧。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;NextObjPtr一个最牛B&lt;span style="font-family: 宋体;"&gt;的指针&lt;/span&gt;&lt;/strong&gt;。CLR中的所有资源都从托管堆中分配，托管堆是一块连续的内存空间，维护一个指针NextObjPtr，它指向上一个对象地址的后面，下一个对象的开始位置，若托管堆中没有对象就指向托管堆的开始位置，每分配一个对象就将NextObjPtr指向这个对象的后面，以准备开始分配下一个对象。NextObjptr指针移动的位置其实就是上一个对象所在空间的长度，从指向对象的开始位置改为对象的末尾吗。从哪里开始分配对象就全靠NextObjPtr啦。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;实例化一个对象需要多少空间？&lt;/strong&gt;对象的所有字段所需的内存+类型对象指针+同步块索引。关于类型对象指针和同步块索引的作用前面已经提过了。有些字段没有明显定义，但它确确实实存在，每个对象除了object的对象都有base字段，通过它可以调用父类的实例字段和方法，通过它你可以访问你爷爷的爷爷定义的字段和方法。CLR用递归的方式调用父类的方法，当然也要看，你爷爷是否愿意让你调用，原因你懂的。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;在垃圾回收开始之前速度比C&lt;span style="font-family: 宋体;"&gt;快&lt;/span&gt;&lt;/strong&gt;。对象就这样开心的在托管堆中分配，托管堆的容量是有限的，总有一天第0代会满，容不下一粒沙子。垃圾回收就出场了，在垃圾回收出场之前，你使用内存很happy，当然速度是非常快，比C语言的速度还快，因为C的内存是随便分配，只要找到合适大小的区域，就在那里分配内存了，这样会导致内存碎片，有时需要一块大的内存，需要遍历多处。垃圾回收的时候日子就不是那么好过了。速度肯定比C慢了，看下面你就知道垃圾回收的时候，程序的速度为什么慢了。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;垃圾回收分两步：1：标记；2：压缩&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;1：标记&lt;/strong&gt;。在垃圾回收开始的时候，垃圾回收器视托管堆中的所有对象都为垃圾，即线程栈上没有指针指向托管堆。这样的估计是因为一个对象被视为垃圾就是它没有被引用，当垃圾回收开始的时候，垃圾回收器会沿着线程栈线性扫描，当线程栈上的一个变量引用了托管堆中的对象时，垃圾回收器就会将这个对象标记，即修改该对象同步块索引中的一个特定的位，同步块索引就是一个bit数组，每一个元素都有它特定的作用，上面就列出了我所知道的三个功能。被标记的对象也可能引用其他的对象，而被引用的对象同样会被标记，垃圾回收器是用递归的方式将这些对象一一标记的，一个对象可能会被多个对象引用，当垃圾回收器发现某个对象被标记时就会退出递归，因为再往下递归完全是多余，而且还可能出现死循环。&lt;/p&gt;&lt;p class="p0"&gt;垃圾回收器就这样线性的扫描线程栈，递归的扫描托管堆，最后将托管堆中所有被引用的对象标记，而没有被标记的对象就是垃圾，等着被回收。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;2：压缩&lt;/strong&gt;。当垃圾被回收之后，就会出现磁盘碎片，那么就要对托管堆进行整理，即压缩。将没有被回收的对象放在一起，靠近托管堆开始的位置，将剩余的内存腾出空间来以便存放新的对象。由于压缩很多对象就会移动位置，而引用他们的指针都会变得无效，所以托管堆要修改所有指针的指向，以保证不会因为垃圾回收而让对象变得不可到达，指针变得无效。&lt;/p&gt;&lt;p class="p0"&gt;压缩完了之后，又腾出了空间，又可以分配新的对象，当第0代满了之后又进行垃圾回收，垃圾回收就这样一直进行着，直到回收了3代还是没有内存可以分配，那就是弹尽粮绝的时候了，CLR会告诉你OutOfMemoryException。CLR的内存被的程序吃光了。更多关于代的信息，可以看我的&lt;span style="color: #ff0000;"&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2011/12/19/2293706.html"&gt;&lt;span style="color: #ff0000;"&gt;这篇博客&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;。在第0代满的时候就会进行垃圾回收，第0代回收完之后还是没有足够的内存存放当前对象就回收第1代，如果还是不够就回收第2代，够就不回收下一代，垃圾回收还可以用代码控制GC.Collect()。&lt;/p&gt;&lt;p class="p0"&gt;更多关于内存管理和垃圾回收的内容，请等待我的下一篇博客。&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2443722.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/04/12/2443722.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/04/12/2443334.html</id><title type="text">《重来》值得你多看几遍</title><summary type="text">作者崇尚简约、见解独到、看法新颖、内容有点另类，却总让我产生共鸣，从中受到不少启发，看起来真是过瘾。原来书还可以这样写。有些可能不知不觉加上了我自己的观点，同一句话不同的人有不同的理解，可能会出现断章取义的情况，往你喜欢的方面想就好，这是唯一一本我在几天之内看了两遍的书，我想很多人也会喜欢，于是昨晚我把自己喜欢的内容整理了一下，形成这篇博客。希望对大家有帮助。1.哪来的从错误中学习－－别人的失败与你何干，别人挣的没花得多，那么，正好你来挣。你到底能从错误中学到什么？你能学到的只是不再重蹈覆辙，但这有什么意义呢？2.工作狂不是英雄，他们没有力挽狂澜，不过是浪费时间，真正的英雄早已想出办法、搞定一</summary><published>2012-04-12T01:04:00Z</published><updated>2012-04-12T01:04:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/04/12/2443334.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/04/12/2443334.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p15"&gt;作者崇尚简约、见解独到、看法新颖、内容有点另类，却总让我产生共鸣，从中受到不少启发，看起来真是过瘾。原来书还可以这样写。有些可能不知不觉加上了我自己的观点，同一句话不同的人有不同的理解，可能会出现断章取义的情况，往你喜欢的方面想就好，这是唯一一本我在几天之内看了两遍的书，我想很多人也会喜欢，于是昨晚我把自己喜欢的内容整理了一下，形成这篇博客。希望对大家有帮助。&lt;/p&gt;&lt;p class="p15"&gt;1.&amp;nbsp;&lt;strong&gt;哪来的从错误中学习&lt;/strong&gt;－－别人的失败与你何干，别人挣的没花得多，那么，正好你来挣。你到底能从错误中学到什么？你能学到的只是不再重蹈覆辙，但这有什么意义呢？&lt;/p&gt;&lt;p class="p15"&gt;2.&amp;nbsp;&lt;strong&gt;工作狂不是英雄&lt;/strong&gt;，他们没有力挽狂澜，不过是浪费时间，真正的英雄早已想出办法、搞定一切，然后回家了。&lt;/p&gt;&lt;p class="p15"&gt;3.&amp;nbsp;&lt;strong&gt;在宇宙中留下你的足迹&lt;/strong&gt;－－你不必去攻克癌症，只要冲着有价值的方向努力，要让你的客户说：&amp;ldquo;这个东西让我的生活变美好了&amp;rdquo;，如果你不做这件事了，人们就会觉得不对劲。&lt;/p&gt;&lt;p class="p15"&gt;4.&amp;nbsp;&lt;strong&gt;怎么样做出好的产品&lt;/strong&gt;－－不需要核心团队、市场调研，也不需要经纪人，就像自己身上痒痒了，就自己挠挠。&lt;/p&gt;&lt;p class="p15"&gt;5.&amp;nbsp;&lt;strong&gt;着手做点什么&lt;/strong&gt;－－你脑袋中有&lt;span style="font-family: Calibri;"&gt;eBay&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的创意和你实际去创建&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;eBay&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;那是一点关系都没有，你的人生中真正有意义的是你做过什么，而不是你想过什么或者计划过什么。&lt;/span&gt;&lt;/p&gt;&lt;p class="p15"&gt;6.&amp;nbsp;&lt;strong&gt;时间不是借口&lt;/strong&gt;－－你的终极职责就是让你自己的梦想成真&lt;/p&gt;&lt;p class="p15"&gt;7.&amp;nbsp;&lt;strong&gt;干自己认为很酷的工作&lt;/strong&gt;－－&lt;span style="font-family: 宋体;"&gt;如果面包不新鲜，就做不出绝味的三明治，如果不能卖让自己倍儿有面子的食物，那赚再多的前又有什么意思呢？&lt;/span&gt;&lt;/p&gt;&lt;p class="p15"&gt;8.&amp;nbsp;&lt;strong&gt;与其做一个半成品，不如做好半个好产品&lt;/strong&gt;－－同时做&lt;span style="font-family: Calibri;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;件事的结果就是：一大绝妙的点子最后被转化成一个蹩脚的产品，很多东西是越简单越好。&lt;/span&gt;&lt;/p&gt;&lt;p class="p15"&gt;9.&amp;nbsp;&lt;strong&gt;关注不变因数&lt;/strong&gt;－－时尚总会凋零，只有当你聚焦于长久的功能时，你才会发现你握住了永不落伍的东西。&lt;/p&gt;&lt;p class="p15"&gt;10.&amp;nbsp;&lt;strong&gt;立马上线&lt;/strong&gt;－－最有效的成功方法就是不断尝试，不要再臆测到底会发生什么事了，到现实中去找答案吧。&lt;/p&gt;&lt;p class="p15"&gt;11.&amp;nbsp;&lt;strong&gt;退出的理由&lt;/strong&gt;－－有时候放弃其实是一步好棋，即是你已经为之投入很多努力，也不要把打好的时间浪费在不值得做的事情上。&lt;/p&gt;&lt;p class="p15"&gt;12.&amp;nbsp;&lt;strong&gt;会议有毒&lt;/strong&gt;－－世界上最可恨的打扰莫过于开会，会议中总难免轮到那么一个低能人士发言，于是大家的时间都被浪费在他们的扯淡上。&lt;/p&gt;&lt;p class="p15"&gt;13.&amp;nbsp;&lt;strong&gt;速战速决&lt;/strong&gt;－－不要等太久，否则你的激情会被扼杀掉&lt;/p&gt;&lt;p class="p15"&gt;14.&amp;nbsp;&lt;strong&gt;不要逞英雄&lt;/strong&gt;－－很多时候知难而退比逞英雄实在，最糟糕的事莫过于继续浪费时间&lt;/p&gt;&lt;p class="p15"&gt;15.&amp;nbsp;&lt;strong&gt;该睡觉时就睡觉&lt;/strong&gt;－－人在困倦的时候，就是一个没有创意的顽固分子，执着于眼前错误的解决方案。&lt;/p&gt;&lt;p class="p15"&gt;16.&amp;nbsp;&lt;strong&gt;养成对客户说不得习惯&lt;/strong&gt;－－如果一味听顾客的，我就只能给他们弄一匹快马&lt;span style="font-family: Calibri;"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;亨利&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;-&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;福特)。不要相信&amp;ldquo;客户永远是对的&amp;rdquo;&amp;nbsp;这种废话。&lt;/span&gt;&lt;/p&gt;&lt;p class="p15"&gt;17.&amp;nbsp;&lt;strong&gt;头脑发热不等于当务之急&lt;/strong&gt;－－当你突然想到一个创意时，认为他非要不可，可能到第二天早上就觉得可有可无。&lt;/p&gt;&lt;p class="p15"&gt;18.&amp;nbsp;&lt;strong&gt;关于广告&lt;/strong&gt;－－广告做得再好也无法弥补一次糟糕的用户体验。&lt;/p&gt;&lt;p class="p15"&gt;19.&amp;nbsp;&lt;strong&gt;普及知识赢得竞争&lt;/strong&gt;－－传道授业能为你建立起凝聚力，这是传统市场策略不可望其项背的。&lt;/p&gt;&lt;p class="p15"&gt;20.&amp;nbsp;&lt;strong&gt;没人喜欢朔料花&lt;/strong&gt;－－不要害怕让人看到你的缺点，不完美才真实，真实才能激起人们的共鸣。&lt;/p&gt;&lt;p class="p15"&gt;21.&amp;nbsp;&lt;strong&gt;关于市场营销&lt;/strong&gt;－－如果你开的是一家餐馆，那么餐后的薄荷糖就是市场营销。&lt;/p&gt;&lt;p class="p15"&gt;22.&amp;nbsp;&lt;strong&gt;一夜成名的传说&lt;/strong&gt;－－在遇到伯乐之前，你得努力很长时间。&lt;/p&gt;&lt;p class="p15"&gt;23.&amp;nbsp;&lt;strong&gt;简历&lt;/strong&gt;－－我们都知道简历就是一个笑话。&lt;/p&gt;&lt;p class="p15"&gt;24.&amp;nbsp;&lt;strong&gt;多年的无关经验&lt;/strong&gt;－一个具有&lt;span style="font-family: Calibri;"&gt;6&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个月工作经验的应聘者和一个具有&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;6&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;年工作经验的应聘者相比，其差别小的令人吃惊。真正的差别来自于个人的努力程度、性格差异以及智力水平。现在已经不是以长短论英雄的时候了，真正重要的是他们做了什么。&lt;/span&gt;&lt;/p&gt;&lt;p class="p15"&gt;25.&amp;nbsp;&lt;strong&gt;常规教育不值一提&lt;/strong&gt;－－我从不把我自己受过的正规学校教育等同于我的受教育程度（马克吐温）&lt;/p&gt;&lt;p class="p15"&gt;26.&amp;nbsp;&lt;strong&gt;人人都得干活&lt;/strong&gt;－－在小团队里不要招监工型的人，他们就是累赘。他们丢下自己的事，想出各种事让别人去做，他们喜欢把别人拖去开会，那是他们表现自己的最佳机会，而被拖去开会的人都不能踏实的工作。&lt;/p&gt;&lt;p class="p15"&gt;27.&amp;nbsp;&lt;strong&gt;企业文化不是由谁创造的&lt;/strong&gt;－－企业文化是自然生产的，你鼓励创新，创新就是你的企业文化，你鼓励复制，复制就是你的企业文化。&lt;/p&gt;&lt;p class="p15"&gt;28.&amp;nbsp;&lt;strong&gt;上报审批&lt;/strong&gt;－－当公司里事事都要审批时，你就创造出了一种无脑文化，你成功的创造出了老板和员工的敌对关系，这种关系咆哮着：我不相信你。&lt;/p&gt;&lt;p class="p15"&gt;29.&amp;nbsp;&lt;strong&gt;准点放人&lt;/strong&gt;－－你需要的不是工作得更久的人，而是工作更高效的人。&lt;/p&gt;&lt;p class="p15"&gt;30.&amp;nbsp;&lt;strong&gt;不要听风就是雨&lt;/strong&gt;－－规章制度是组织体上的伤疤，他是针对不再可能发生的事情做出的过激反应，他是对一个人的错误做出集体的惩罚，他是官僚主义的温床。&lt;/p&gt;&lt;p class="p15"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p15"&gt;在这本书中，看到&amp;ldquo;废话&amp;rdquo;这个词是最多的。因为这个词能让大家产生共鸣，别人的不是总能让自己兴奋，就像微博中的加&lt;span style="font-family: Calibri;"&gt;V&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;人士总说党的不是来吸引大家的眼球。当然这根本不是作者的目的，有个性的人就是不一样，就像乔布斯一样，言辞就是那么激烈&amp;ldquo;这就是一坨屎&amp;rdquo;，就像周星驰的经典台词&amp;ldquo;看到没有，屎诶，看到没有，里面有坨屎&amp;rdquo;，&lt;/span&gt;这是一本很有个性的书籍，适合所有有个性的人。&lt;/p&gt;&lt;p class="p15"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2443334.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/04/12/2443334.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/03/31/2426958.html</id><title type="text">裂变问题分析</title><summary type="text">问题：一个瓶子放一个细菌,细菌一分钟裂变一次，1变2，60分钟后瓶子就满了，问给这个瓶子里放两个细菌裂变后要多久瓶子会满？首先我们用猜的，不是30就是59，不可能是其他的答案，如果让我从30和59中选一个答案，那我肯定选59，不可能30吧，会这么弱智吗，没错答案就是59。现在我们用数学公式来证明。根据题目我们知道瓶子装满时细菌的数量为2^60，假设N分钟后瓶子满，那么我们得到2*2^N=2^60，1+N=60，从而得出N=59。是的就这么简单，还有更简单的呢。1个细菌裂变成2个细菌用时1分钟，1个细菌裂变让瓶子满的时间是60分钟，那么2个细菌让瓶子满的时间=1个细菌裂变让瓶子满的时间-1个细菌</summary><published>2012-03-31T06:23:00Z</published><updated>2012-03-31T06:23:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/03/31/2426958.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/03/31/2426958.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;&lt;strong&gt;问题：一个瓶子放一个细菌,&lt;span style="font-family: 宋体;"&gt;细菌一分钟裂变一次，&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;60&lt;span style="font-family: 宋体;"&gt;分钟后瓶子就满了，问给这个瓶子里放两个细菌裂变后要多久瓶子会满？&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;首先我们用猜的，不是30&lt;span style="font-family: 宋体;"&gt;就是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;59&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，不可能是其他的答案，如果让我从&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;30&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;59&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中选一个答案，那我肯定选&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;59&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，不可能&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;30&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;吧，会这么弱智吗，没错答案就是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;59&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;现在我们用数学公式来证明。根据题目我们知道瓶子装满时细菌的数量为&lt;span style="font-family: Times New Roman;"&gt;2^60&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，假设&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分钟后瓶子满，那么我们得到&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2*2^N=2^60&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1+N=60&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，从而得出&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;N=59&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;是的就这么简单，还有更简单的呢。&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌裂变成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌用时&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分钟，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌裂变让瓶子满的时间是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;60&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分钟，那么&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌让瓶子满的时间&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;=1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌裂变让瓶子满的时间&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;-1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌裂变成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌的时间&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;=60-1=59&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;从上面的那个等式我们可以得出：&lt;strong&gt;N&lt;span style="font-family: 宋体;"&gt;个细菌让瓶子满的时间&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;=1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌裂变让瓶子满的时间&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;-1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌裂变成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌的时间&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;有了这个等式我们就很容易知道往瓶子里面放&lt;span style="font-family: Times New Roman;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌多就会满了，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;4&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌的时间为&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;58,8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌的时间是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;57,16&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌的时间，同样的，&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;5,6,7&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的时间都是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;58&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分钟，因为&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌刚好要&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;57&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分钟，所以我们很容易知道往瓶子里任意放&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1~2^N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌让瓶子满的时间为&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;60-logN&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;从上面那个等式可以看出：用时和细菌是&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，还是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，或是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，没有多大关系，有关系的是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌变成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌所需的时间。所以上面那个等式适用于裂变是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;N&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的情况。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;问题扩展：题目基本不改，只是将细菌&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;改成&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌生出&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个细菌，就变成了鸡生蛋的问题了，其实就是&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;吗&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2426958.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/03/31/2426958.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hlxs/archive/2012/03/28/2420564.html</id><title type="text">这些天写的技术微博</title><summary type="text">为什么类型和实例对象都要类型对象指针方法和类型所需的内存是在一起分配的，方法被类型和实例对象共享，在实例化一个对象的时候不会为方法分配内存，而调用方法时只能通过类型对象指针定位到方法表中相应的方法，进行调用==与Equals的区别：值类型他们的效果是一样的，因为值类型分配在线程栈上，存的就是值，直接比较的就是值引用类型：==判断是否指向同一个地址；Equals比较的是变量所指的内存中的数据是否相同Dictionary时间复杂度：Add；ContainsKey；Remove；TryGetValue为O(1),只有ContainsValue为O(n);因为前者根据哈希算法直接定位到数组索引，而后者</summary><published>2012-03-27T18:22:00Z</published><updated>2012-03-27T18:22:00Z</updated><author><name>啊汉</name><uri>http://www.cnblogs.com/hlxs/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hlxs/archive/2012/03/28/2420564.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hlxs/archive/2012/03/28/2420564.html"/><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="Section0"&gt;&lt;p class="p0"&gt;为什么类型和实例对象都要类型对象指针方法和类型所需的内存是在一起分配的，方法被类型和实例对象共享，在实例化一个对象的时候不会为方法分配内存，而调用方法时只能通过类型对象指针定位到方法表中相应的方法，进行调用&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;==&lt;span style="font-family: 宋体;"&gt;与&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Equals&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的区别：值类型他们的效果是一样的，因为值类型分配在线程栈上，存的就是值，直接比较的就是值引用类型：&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;==&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;判断是否指向同一个地址；&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Equals&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;比较的是变量所指的内存中的数据是否相同&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;span style="font-family: Calibri;"&gt;Dictionary&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时间复杂度：&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Add&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;；&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;ContainsKey&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;；&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Remove&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;；&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;TryGetValue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;O(1),&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只有&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;ContainsValue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;O(n);&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;因为前者根据哈希算法直接定位到数组索引，而后者却要遍历数组做比较；&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Remove&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Add&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;并没有发生数组元素的移动，数组是预先分配好的，&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Add&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只是填充，而&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Remove&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只是将对应的元素都置为初始状态&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;不要把动态的内容存在不能修改的缓存中，如存在静态字段中，如果内容改了，缓存中内容却改不了，如果存在静态字段中，可以隔一段时间更新一下，或者让你的缓存依赖某个文件。总之要让自己可以控制缓存中的内容&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;int&lt;span style="font-family: 宋体;"&gt;映射到&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;FCL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;System.Int32,string&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;映射到&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;FCL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;System.String,&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;他们没有区别，相当于&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;using&amp;nbsp;int=System.Int32&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&lt;span style="font-family: 宋体;"&gt;值类型赋值是逐一对字段赋值，将一个很大的结构体当做实参传递是很低效的，如果这个结构体有&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;1000&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个字段，那就要赋值&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;1000&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;次，而引用类型赋值，只是修改指针指向，说明将&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Class&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;修改成&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;Struct&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;并不一定能提升性能，&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;struct&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的类型实例一定要小&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;拆箱其实是一个获得一个指针的过程，该指针指向对象的数据部分，紧接其后是一个赋值动作，拆箱就是把引用类型赋给值类型，其实是赋给一个中间变量，然后你就可以调用值类型的方法了&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;在&lt;span style="font-family: Calibri;"&gt;foreach&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;循环读取数组中的元素的同时添加或删除元素，都会报&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;InvalidOperationException&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;异常，因为添加和删除都会修改字段&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;version&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值，而&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;MoveNext&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;里面会判断&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;version&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值和数组元素的个数是否发生变化，如果发生变化就报这个异常&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;为什么类型和实例对象都要类型对象指针&amp;nbsp;方法和类型所需的内存是在一起分配的，方法被类型和实例对象共享，在实例化一个对象的时候不会&amp;nbsp;为方法分配内存，而调用方法时只能通过类型对象指针定位到方法表中相应的方法，进行调用&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;效率：静态方法&lt;span style="font-family: Calibri;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实例方法&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;虚方法&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：静态方法不需要判断对象是否为空，而实例方法需要判断调用该方法的对象是否为空&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：虚方法有一些额外代码，用于判断是调用父类的方法还是调用子类的实例方法。实例方法和虚方法都要进行非空检查，若为&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;null&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，就会抛出你常见的&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;NullReferenceException&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而静态方法不需要进行非&lt;/span&gt;&lt;span style="font-family: Calibri;"&gt;null&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;检查，你见过调用静态方法抛这个异常吗？&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;金字塔、锥形结构、树形结构有很好的稳定性，能很好的分散压力负载&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;想了几十分钟没有找到好的解决方法，吃完饭后瞬间就找到了好的方案，感觉思路非常清晰，这就是正确的答案&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;一个简单的防攻击类&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/142192/2012032802173357.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;DataTable&amp;nbsp;转换成 List&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/142192/2012032802181645.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;作者：&lt;a href="http://www.cnblogs.com/hlxs/" target="_blank"&gt;陈太汉&lt;/a&gt;&lt;/p&gt;&lt;p&gt;博客：&lt;a href="http://www.cnblogs.com/hlxs/"&gt;http://www.cnblogs.com/hlxs/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hlxs/aggbug/2420564.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hlxs/archive/2012/03/28/2420564.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
