select * from table limit 10, 20
SELECT TOP
11 *
FROM
MyTable
WHERE
ID NOT IN ( SELECT TOP 9 ID FROM MyTable ORDER BY ID ASC )
ORDER BY
ID ASC;
select * from (select t.*,rownum num from people t where rownum <= 20) where num >=10;
深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一个新的和原始对象中对应字段相同(内容相同)的字段,也就是说这个引用和原始对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对象中对应字段的内容。
浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值他将反映在原始对象中,也就是说原始对象中对应的字段也会发生变化。
变量提升
console.log(a)
var a= 123;
1. static readonly MyClass myins = new MyClass();
2. static readonly MyClass myins = null;
3. static readonly A = B * 20;
static readonly B = 10;
4. static readonly int [] constIntArray = new int[] {1, 2, 3};
5. void SomeFunction()
{
const int a = 10;
}
1:不可以换成const。new操作符是需要执行构造函数的,所以无法在编译期间确定
2:可以换成const。我们也看到,Reference类型的常量(除了String)只能是Null。
3:可以换成const。我们可以在编译期间很明确的说,A等于200。
4:不可以换成const。道理和1是一样的,虽然看起来1,2,3的数组的确就是一个常量。
5:不可以换成readonly,readonly只能用来修饰类的field,不能修饰局部变量,也不能修饰property等其他类成员。
总结
const是编译时常量,readonly是运行时常量;在应用上以static readonly代替const,以平衡const在灵活性上的不足,同时克服编译器优化cosnt性能,所带来的程序集引用不一致问题;
数组(Array):
1、数组存储在连续的内存上
2、数组的元素类型必须相同
3、数组可以直接通过下标访问
4、查找与修改元素的速度非常快
5、必须在声明时指定长度
动态数组(ArrayList):
1、ArrayList的底层其实就是一个数组
2、不必在声明时指定长度,会根据存储的数据动态增加或减少长度
3、插入和删除一个元素时,会移动它之后所有元素的位置,效率低,频繁进行插入删除元素时推荐使用LinkedList
4、ArrayList会把所有元素都当做Object处理,因此可以存储不同类型的元素
5、ArrayList是非类型安全的,而且在插入和删除元素时会进行拆箱和装箱的操作,消耗性能,效率低
泛型List:
1、List是ArrayList的泛型等效类
2、需要在声明时通过泛型指定类型
3、没有拆箱装箱操作,因此在大多数情况下List要比ArrayList效率高且类型安全
双向链表(LinedList):
1、链表在内存中的空间不是连续的,每块空间称作一个节点,每个节点都存有与它之前和之后相连接的节点的地址,因此向链表中添加和删除元素时只需要更改相关节点存储的地址的指向,效率高
2、查找元素时不能通过下标访问,只能从头开始通过地址按顺序查找,效率低
堆栈(Stack):
先进后出原则,最先插入的元素最后被访问,最后被插入的元素最先被访问
队列(Queue):
先进先出的原则,最先插入的元素最先被访问,最后插入的元素最后被访问
字典(Dictionary):
1、创建字典时需要指定key和value的类型
2、字典中的key的值必须唯一,value的值不唯一
3、可以通过key快速查找对应的value,速度快,但是消耗内存
表名 template
id int 自增
title varchar(200)
lastdate datetime
try
{
return 1; //再返回
}
finally
{
Console.WriteLine("what?"); //先执行
}
///
/// 单例模式的实现
///
public class Singleton
{
// 定义一个静态变量来保存类的实例
// volatile在代码被编译的时候不会微调代码
private static volatile Singleton uniqueInstance;
// 定义一个标识确保线程同步
private static readonly object locker = new object();
// 定义私有构造函数,使外界不能创建该类实例
private Singleton()
{
}
///
/// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
///
///
public static Singleton GetInstance()
{
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
// 双重锁定只需要一句判断就可以了
if (uniqueInstance == null)
{
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
$.ajax({
url:"",
method:"get",
dataType:"jsonp",
success:function(res){
console.log(res);
}
});
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
DataRow dr = dt.NewRow();
dr[0] = "张三";
dr[1] = "15";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "李四";
dr["Age"] = 12;
dt.Rows.Add(dr);
索引分为两大类:聚集索引和非聚集索引,其中,非聚集索引又可细分为普通索引、唯一索引、组合索引。
概念层次
聚集索引:物理存储按照索引排序,就像字典正文,我们按照正文的字母顺序就能找到我们的记录。
非聚集索引:物理存储不按照索引排序,就像偏旁查字法目录,每个偏旁目录下的字的页码不是顺序的。
速度方面
聚集索引:插入数据时,速度较慢(时间主要花费在“物理存储的排序”上,也就是首先要找到位置然后再插入数据)。但查询数据的速度比非聚集索引要快。
实际举例说明
我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。
如果您认识某个字,您可以快速地从拼音表中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。
string 具有不可变性,每进行一次赋值操作就会开辟一个新的空间。
而stringbulider 原理类似于list ,当空间不够时,则会自动增加内存空间
Read uncommitted
读未提交,一个事务可以读取另一个未提交事务的数据。
事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。
分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。
那怎么解决脏读呢?Read committed!读提交,能解决脏读问题。
Read committed
读提交,一个事务要等另一个事务提交后才能读取数据。
事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…
分析:这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。
那怎么解决可能的不可重复读问题?Repeatable read !
Repeatable read
重复读,开始读取数据(事务开启)时,不再允许修改操作
事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。
分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
什么时候会出现幻读?
事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。
那怎么解决幻读问题?Serializable!
Serializable 序列化
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
值得一提的是:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。
微服务架构和单体架构的优劣
单体架构
微服务架构
Consul 服务注册与服务发现
Polly 熔断降级
Ocelot 网关
问题描述
出现原因:
解决方案
对空值仍然缓存,但过期时间设置相对短一点
设置访问白名单 bitmaps,名单id作为偏移量,每次访问验证一次,如果id不存在则拦截。
设置黑名单:排查恶意访问,设置黑名单
问题描述:
出现原因:
解决方案
问题描述:
出现原因:
解决方案:
多级缓存
设置过期标志提前更新缓存
缓存失效时间分散