基本概念
对象:可以是现实生活中的一个物理对象,还可以是某一类概念实体的实例。
类:描述对象的一个抽象的结构。
接口:是一种规范。描述属性、方法、索引、委托。
属性:通过名称标识,可以是静态成员或实例成员,get、set访问器无参数
索引器:通过签名标识,必须为实例成员,get\set访问器有参数
拆箱:将值类型转换为引用类型。
装箱:将引用类型转换为值类型。
委托:把方法做为参数传递给其他方法用。
事件:当对象状态发生改变时发出的信息或通知。
泛型:通过参数化类型来实现在同一份代码上操作多种数据类型,可以最大限度地重用代码、保护类型的安全以及提高性能。
进程:系统进行资源分配和调度的基本单位,包括运行中和程序与系统资源。
线程:程序的一个执行流,每线程都有自己的寄存器。
序列化:将对象的状态信息转换为可以存储或传输的形式的过程。
反射:使用反射动态地创建类型的实例,将类型绑定到现有对象。
Struck大小为:首地址为最大成员大小整数倍,每成员偏移量为成员大小整数倍,总大小为最大成员大小整数倍
类大小:空类(包括多继承的空类 或 包含stack 成员)大小为1
内存分配:堆栈:保存局部变量,参数,返回值,返回地址。 托管堆(GCH,LOH等): 自由存储。
多线程同步:volatile,Synchronization,Monitor,Mutex,MethodImpl,ReaderWriterLock,AutoResetEvent
.Net架构:
具有两个主要组件:公共语言运行时和 .NET Framework 类库
CLR: 公共语言运行时(CLR) 是 .NET Framework 的运行时环境, 公共语言运行时管理内存、线程执行、代码执行、代码安全验证、编译以及其他系统服务
BCL: 一个公共编程框架,成为基类库,所有语言的开发者都能利用它。是CLI(公共语言基础结构)的规范之一
WPF:使用 WPF 技术在 Windows Vista 上创建应用程序和高保真用户体验
WCF:是Microsoft为构建面向服务的应用提供的分布式通信编程框架,集合了几乎由 .NET Framework 所提供的通信方法以合约(Contract) 来定义双方沟通的协议,支持了 HTTP,TCP,Named Pipe,MSMQ,Peer-To-Peer TCP 等协议。
WF:使用 WF 技术在Windows平台上创建工作流应用程序
WinForm: 使用 Windows Forms 技术创建智能客户端应用程序。
ASP.NET: 用来构建动态 web 应用程序
Data Access:
三种访问数据库方式:
ADO.NET:使用DataSet对象访问数据库
Entity Framework:利用了抽象化数据结构的方式,将每个数据库对象都转换成应用程序对象 (entity),而数据字段都转换为属性 (property),关系则转换为结合属性 (association),让数据库的 E/R 模型完全的转成对象模型,如此让程序设计师能用最熟悉的编程语言来调用访问。分为 Conceptual Schema, Mapping Schema 与 Storage Schema 三层。
Data Services:一个远程主机数据访问的「中介服务」,可由客户端、客户端应用程序,自行决定数据存取的内容和方式。
Microsoft .NET Services 是一套微软代管、具有高度可扩展性、以开发人员为导向的服务,提供主要区块服务给许多以云为基础及具有云感知能力 (cloud-aware) 的应用程序。
Socket
TCP:三次握手:
第一次握手:建立连接时,客户端发送syn(同步序列编号)包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
TCP是一种流模式的协议,UDP是一种数据报模式的协议
TCP:水池就好比接收缓存,倒水就相当于发送数据,接水就相当于读取数据。好比你通过TCP连接给另一端发送数据,你只调用了一次write,发送了100个字节,但是对方可以分10次收完,每次10个字节;你也可以调用10次write,每次10个字节,但是对方可以一次就收完。(假设数据都能到达)但是,你发送的数据量不能大于对方的接收缓存(流量控制),如果你硬是要发送过量数据,则对方的缓存满了就会把多出的数据丢弃。
UDP:发送端调用了几次write,接收端必须用相同次数的read读完。UPD是基于报文的,在接收的时候,每次最多只能读取一个报文,报文和报文是不会合并的,如果缓冲区小于报文长度,则多出的部分会被丢弃。也就说,如果不指定MSG_PEEK标志,每次读取操作将消耗一个报文。
这种不同是由TCP和UDP的特性决定的。TCP是面向连接的,也就是说,在连接持续的过程中,socket中收到的数据都是由同一台主机发出的(劫持什么的不考虑),因此,知道保证数据是有序的到达就行了,至于每次读取多少数据自己看着办。
而UDP是无连接的协议,也就是说,只要知道接收端的IP和端口,且网络是可达的,任何主机都可以向接收端发送数据。这时候,如果一次能读取超过一个报文的数据,则会乱套。比如,主机A向发送了报文P1,主机B发送了报文P2,如果能够读取超过一个报文的数据,那么就会将P1和P2的数据合并在了一起,这样的数据是没有意义的
C#常用的异常就是两大类,
SystemException:预定义的公共语言运行库异常类的基类,例如数组越界,类型转换错误等,都会被此异常捕捉,
ApplicationException:用户定义的应用程序异常类型的基类,这个类是为了区别CLR抛出的异常而设计的,
关键字比较:
Out或ref 关键字会导致参数通过引用来传递,,方法定义和调用方法都必须显式使用 out或ref 关键字。
Ref : 要求变量必须在传递之前进行初始化。
out : 不需要进行初始化
const 静态常量,
readonly动态常量
1)const修饰的常量在声明的时候必须初始化;readonly修饰的常量则可以延迟到构造函数初始化
2)const修饰的常量在编译期间就被解析,即常量值被替换成初始化的值;readonly修饰的常量则延迟到运行的时候
此外const常量既可以声明在类中也可以在函数体内,但是static readonly常量只能声明在类中。
分布式处理: .Net Remoting , Web Service ,WCF
WebService是两个计算机之间通讯(交谈)的技术。并且现在炒的很火的SOA、云计算在技术层面上都是WebService。
除了WebService 通讯外,系统间通讯有很多种技术,如像qq的这种Socket通讯在银行系统中广泛应用,.Net Remoting、DCom等通讯方式也应用很 多,
但是这些方式有如下缺点:
通讯数据格式不统一,同样一个"你好"这样的字符串在不同的协议中有不同的表示方法,异构系统集成很麻烦。一个系统一个模样。
采用Socket、 .Net Remoting、DCom需要打开很多端口,而企业网络安全的一个基本原则就是“尽可能少的打开端口”,很多企业网络甚至严格规定“只能打开80端口”,
因此需要一种“跨防火墙”的技术(跨防火墙就是走80端口进行通讯)
这些通讯方式的协议是不开放的,要想知道服务提供了哪些方法、如何调用,必须能够自描述
Remoting和WebService的区别:Remoting效率高,走的是普通TCP, WebService则是Http协议,需要IIS、ASP.Net、XML解析等,效率低。Remoting适合于内网通讯, WebService适合于外网通讯。
WCF:利用C#的.Net Remoting技术能够方便地解决各场地间数据的通信问题。另外,C#通过ADO.Net访问数据库,使得对数据库的操作及管理变得更加高效、可靠。这两种技术的使用,有效地解决了开发分布式数据库系统的主要问题,大大减轻了系统开发工作量,并且提高了系统的可靠性和安全性。
另外还可以考虑近似计算,也就是我们可以通过结合自然语言属性,只将那些真正实际中出现最多的那些词作为一个字典,使得这个规模可以放入内存。
SQL分类:
DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE)
DML—数据操纵语言(SELECT,DELETE,UPDATE,INSERT)
DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)
ADO.NET 例子:
String strConn, strCmd;
strConn = "DATABASE=MyAgenda;SERVER=localhost;UID=sa;PWD=;";
strCmd = "Select * From Names";
SqlConnection oCN = new SqlConnection(strConn);
SqlCommand oCMD = new SqlCommand(strCmd, oCN);
oCN.Open();
SqlDataReader dr = oCMD.ExecuteReader();
while (dr.Read())
{ int id =dr.GetInt32(); }
SqlDataAdapter adapter = new SqlDataAdapter(strCmd, oCN);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
TCP/IP例子:
TcpListener listener = new TcpListener(new System.Net.IPEndPoint(0,5555));
listener.Start();
this.ServerThread = new Thread(new ThreadStart(() =>
{
while (true)
{
TcpClient tcpClient = listener.AcceptTcpClient();
Thread clientThread = new Thread(new ThreadStart(() =>
{
NetworkStream stream = tcpClient.GetStream();
BinaryWriter writer = new BinaryWriter(stream);
BinaryReader reader = new BinaryReader(stream);
while (true)
{
if (Thread.CurrentThread.ThreadState != ThreadState.Running)
{
break;
}
if (!tcpClient.Connected) throw (new Exception("与客户端连接关闭。"));
//判断Tcp流是否有可读的东西
//Recieve();
}
}));
clientThread.Priority = ThreadPriority.BelowNormal;
clientThread.Start();
}
}));
this.ServerThread.Priority = ThreadPriority.BelowNormal;
this.ServerThread.Start();
this.ServerThread.Abort();
listener.Stop();
Thread.Sleep(1);
文件操作例子:
StreamReader sr = new StreamReader(new FileStream("test.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite));
sr.ReadLine();
FileInfo fi = new FileInfo("test.txt");
FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite);
if (File.Exists("test.txt"))
{ File.Delete("test.txt"); }
else{File.Create("test.txt");}
if(Directory.Exists("path"))
{DirectoryInfo info = Directory.CreateDirectory("path");}
DirectoryInfo di = new DirectoryInfo("path");
foreach (FileInfo fi in d.GetFiles())
{ }
foreach (DirectoryInfo tdi in di.GetDirectories())
{ }
同步例子:
/// <summary>
/// volatile是最简单的一种同步方法,当然简单是要付出代价的。它只能在变量一级做同步,volatile的含义就是告诉处理器,
/// 不要将我放入工作内存, 请直接在主存操作我。因此,当多线程同时访问该变量时,都将直接操作主存,从本质上做到了变量共享。
/// </summary>
public class A
{private volatile int i;
public int I
{get { return i; }set { i = value; }}}
public void LockFun()
{lock (lockThis){ }}
public void MonitorFun()
{if (!Monitor.TryEnter(lockThis)){return;}
try
{System.Threading.Monitor.Enter(lockThis);
Console.WriteLine("Test");
}finally{
System.Threading.Monitor.Exit(lockThis);
}}
public void MutexFun()
{bool created;
System.Threading.Mutex mutex = new System.Threading.Mutex(false, "Test",out created);
if(created){}else{}
}
static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
/// <summary>
/// AutoResetEvent
/// 用lock和Monitor可以很好地起到线程同步的作用,但它们无法实现线程之间传递事件。如果要实现线程同步的同时,线程之间还要有交互,就要用到同步事件。同步事件是有两个状态(终止和非终止)的对象,它可以用来激活和挂起线程。
/// 同步事件有两种:AutoResetEvent和 ManualResetEvent。它们之间唯一不同的地方就是在激活线程之后,状态是否自动由终止变为非终止。
/// AutoResetEvent自动变为非终止,就是说一个AutoResetEvent只能激活一个线程。而ManualResetEvent要等到它的Reset方法被调用,
/// 状态才变为非终止,在这之前,ManualResetEvent可以激活任意多个线程。
/// </summary>
public static void AutoRestEventFun()
{
Thread thread = new Thread(new ThreadStart(ReadThreadProc));
readerThread.Name = "ReaderThread";
readerThread.Start();
for (int i = 1; i <= 10; i++)
{
Console.WriteLine("MainThread writing : {0}", i);
//主(写)线程将数据写入
//主(写)线程发信号,说明值已写过了
//即通知正在等待的线程有事件发生
autoResetEvent.Set();
Thread.Sleep(0);
}
//终止线程
readerThread.Abort();
}
static void ReadThreadProc()
{
while (true)
{
//在数据被写入前,读线程等待(实际上是等待写线程发出数据写完的信号)
autoResetEvent.WaitOne();
Console.WriteLine("");
}
}
c#3.5一些特性例子:
//Func 委托应用
public event Func<object, int> MyEvent;
#region C#3.0特性
private void DoTest()
{
//Lambda表达式 简化了我们编写事件处理函数的工作
MyEvent += (s) => {
//隐式类型化数组
var temps = new[] {
//匿名类型
new { id = 100, name = "gene", sex = true }
,new { id = 200, name = "gene2", sex = true } };
//Linq查询表达式
var rlt = from t in temps where t.id<200 select t;
foreach (var t in rlt.Where((a) => { return a.sex == true; }))
{
Console.WriteLine(t.id);
}
return 0;
};
MyEvent("Lambda表达式");
}
#endregion
SQL例子:
4、说明:创建新表
create table tb_model_course
{
Cno varchar(4) IDENTITY primary key,
Cname varchar(20) unique,
Cpno varchar(4) default ‘’,
foreign key Cpno references Course(Cno)
}
根据已有的表创建新表:
A:create table tab_new like tab_old (使用旧表创建新表)
B:create table tab_new as select col1,col2… from tab_old definition only
当你不再需要该表时, 用 drop table tabname;
当你仍要保留该表,但要删除所有记录时, 用 truncate table name [DROP/REUSE STORAGE];它是DML語言 速度也比delete要快得多.只能操作TABLE
当你要删除部分记录时(always with a WHERE clause), 用 delete.它是DDL語言 产生rollback 是自動提交的,命令完成就不可回滾. 可以操作table,view,synonym
增加一个列 Alter table tabname add column col type
添加主键: Alter table tabname add primary key(col)
创建索引:create [unique] index idxname on tabname(col….) 删除索引:drop index idxname注:索引是不可更改的,想更改必须删除重新建
创建视图:create view viewname as select statement 删除视图:drop view viewname
UNION、UNION ALL 并集 、EXCEPT 排除、INTERSECT交集
使用外连接
A、left outer join: 左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
B:right outer join: 右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
C:full outer join: 全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。
复制表(只复制结构,源表名:a 新表名:b) :select * into b from a where 1<>1法二:select top 0 * into b from a
拷贝表(拷贝数据,源表名:a 目标表名:b): insert into b(a, b, c) select d,e,f from b;
显示文章、提交人和最后回复时间:
select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
删除重复记录:Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)
列出数据库里所有的表名:select name from sysobjects where type='U'
列出表里的所有的:select name from syscolumns where id=object_id('TableName')
选择从10到15的记录:select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
列出的表行数:SELECT rowcnt,indid FROM sysindexes WHERE id=OBJECT_ID('tableName')and indid < 2
存储过程
从存储过程中返回值
create or replace procedure spaddflowdate
(
varAppTypeId in varchar2,
varFlowId in varchar2,
DateLength in number,
ReturnValue out number --返回值
)
is
begin
insert into td values(varAppTypeId,varFlowId,DateLength)
returning 1 into ReturnValue; --返回值
commit;
exception
when others then
rollback;
end;
存储过程的执行
sql>variable testvalue number;
sql>execute spaddflowdate('v','v',2,:testvalue);
sql>print
游标使用:
declare cur_name cursor for select type from table1; --定义游标
declare @type varchar(50);
open cur_name;
fetch next from cur_name into @type;
while @@fetch_status =0
begin
if @type = '存储过程'
begin
exec 存储过程;
end
else if @type = 函数
begin
select dbo.函数();
end
fetch next from cur_name into @type;
end
close cur_name;
deallocate cur_name;
大数据量处理:
数据库:
1.建视图、建索引来优化查询
2.尽量用存储过程来操作数据库,最好是用分页查询的存储过程(需要显示哪些数据就查哪些)
大数据的排序,去重 或取最大N数:
基本原理及要点:外排序的归并方法,置换选择 败者树原理,最优归并树 ,或使用文件,分批次读入,实现一个N个元素的有序链表
大数据量统计其中出现次数最多的前N个数据,分两种情况:
可一次读入内存,不可一次读入。
可用思路:trie树+堆,数据库索引,划分子集分别统计,hash,分布式计算,近似统计,外排序