摘要:
1:JIT(即时编译)。一个方法在第一次调用时JIT会把改方法的IL代码转换成CPU指令,再次调用该方法时就只需执行对应的指令。方法第一次被调用的过程大致是:1获得方法的IL代码;2:分配内存;3:将IL代码转换成CPU指令存在2分配的内存中;4:将方法表中对应该方法的指针指向2分配的内存;5:跳转到2分配的内存执行其中的指令,即该方法的CPU指令。2:as的性能高于is。Is的作用是判断当前类型与目标类型是否兼容,即是否是同一类型或者目标类型是当前类型的父类型。强制类型转换也要判断类型的兼容性,如果不兼容就抛出一个类型转换异常,如果你的代码类型转换用Is+强制类型转换就做了两次兼容性判断,而 阅读全文
摘要:
1:写不易出错的代码 第一次听说“写明显没有什么错误的代码”时,我觉得这个说法很新鲜,让我记忆深刻。其他的很多观点听得我耳朵生茧,基本都是左耳进右耳出。明显没有什么错了的代码肯定是思路清晰、很容易理解的。而要做到这点很难,牛人才能写出牛叉的代码,要做到这一点要有足够的阅历和实战,只能当做目标啦,哪天也和云风一样:今天完成了XX功能,代码明显没有什么错误。现在还不知道明显没有什么错误的代码是怎么样的,但我知道很多代码让我半天不知所云。如从类名和方法名看不出其职能;变量命名让人蛋疼;不对参数做任何验证;参数到处都是都是基本类型;方法参数十几个;一个方法几屏;不能适应半点变化的方法;要么没有注释,要 阅读全文
摘要:
好久没有做算法题了,重温几个简单的算法题。第一题:求子数组的最大和这是一道很常见的算法题,很多人都能很快的写出算法,但很多人都不能写得完全正确,问题主要出在sum初始化上,很多错误的答案将他初始化为0,如果数组的所有元素都为负,那么得到的最大最是0,sum要初始化成数组的第一个元素。第二题:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句 这道题在网上也有很多个版本,有在构造函数中实现加法,利用两个静态变量一个存结果,一个存当前值,然后创建一个一维n个元素的数组,存结果的静态变量即为所求,还有的就是用两个方法,一个方法是递 阅读全文
摘要:
转载: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 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行 阅读全文
摘要:
C#成员的初始化顺序你真的非常清楚吗,我发现有点坑爹,坑到爹突然有点搞不清楚什么状况。下面咱们开始分析,先看3个简单类。 public abstract class Base { public Base() { SetValue(); } public abstract void SetValue(); } public class Sub : Base { public string value; public Sub() { ... 阅读全文
摘要:
垃圾回收还得从根说起,就像生儿育女一样。根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null。根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为定义的变量就存在线程栈上,类型对象指针存在托管堆中,因为实例化一个对象要额外分配两个字段“类型对象指针”和“同步块索引”。类型对象指针的作用。实例化一个对象并没有为其方法分配内存,类型的静态字段分配内存,而实例要向调用属于类型的一些东西,就必须通过类型对象指针。如对象的实例是共用类型的方法,实例只需要通过类型对象指针调用类型的方法,更多关于方法的调用请看我的这篇博客。同步块索引的作用。1:用于loc 阅读全文
摘要:
作者崇尚简约、见解独到、看法新颖、内容有点另类,却总让我产生共鸣,从中受到不少启发,看起来真是过瘾。原来书还可以这样写。有些可能不知不觉加上了我自己的观点,同一句话不同的人有不同的理解,可能会出现断章取义的情况,往你喜欢的方面想就好,这是唯一一本我在几天之内看了两遍的书,我想很多人也会喜欢,于是昨晚我把自己喜欢的内容整理了一下,形成这篇博客。希望对大家有帮助。1.哪来的从错误中学习--别人的失败与你何干,别人挣的没花得多,那么,正好你来挣。你到底能从错误中学到什么?你能学到的只是不再重蹈覆辙,但这有什么意义呢?2.工作狂不是英雄,他们没有力挽狂澜,不过是浪费时间,真正的英雄早已想出办法、搞定一 阅读全文
摘要:
问题:一个瓶子放一个细菌,细菌一分钟裂变一次,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个细菌 阅读全文
摘要:
为什么类型和实例对象都要类型对象指针方法和类型所需的内存是在一起分配的,方法被类型和实例对象共享,在实例化一个对象的时候不会为方法分配内存,而调用方法时只能通过类型对象指针定位到方法表中相应的方法,进行调用==与Equals的区别:值类型他们的效果是一样的,因为值类型分配在线程栈上,存的就是值,直接比较的就是值引用类型:==判断是否指向同一个地址;Equals比较的是变量所指的内存中的数据是否相同Dictionary时间复杂度:Add;ContainsKey;Remove;TryGetValue为O(1),只有ContainsValue为O(n);因为前者根据哈希算法直接定位到数组索引,而后者 阅读全文
摘要:
我们都知道Dictionary<TKey, TValue>查找元素非常快,其实现原理是:将你TKey的值散列到数组的指定位置,将TValue的值存入对应的位置,由于取和存用的是同一个算法,所以就很容易定位到TValue的位置,花费的时间基本上就是实现散列算法的时间,跟其中元素的个数没有关系,故取值的时间复杂度为O(1)。 集合无非都是基于最基础语法的数组[],先欲分配,然后向其中添加元素,容量不够就创建一个2倍容量的数组,将之前的元素赋值过来,将之前的数组回收,但基于散列算法的集合这点上有点不同,他并不是每次创建一个2倍容量的数组,为了让元素均匀的分布到数组上,数组的容量是这么增长 阅读全文