1、对参数进行任何显示的检查,必须由调用者来完成。
通过在sqrt程序的前条件中表示平方根函数的参数域,你把保证正确性的负担转交给了调用者。随后你可以在知道了输入参数会落在有效范围内的前提下,安全地设计sqrt程序。
2.%SystemRoot%
3.每个对象的overhead成员,类型对象指针(type obj pointer)和同步块索引(syn block index)。
4.类型的安全性,是指不同类型的对象之间不能进行转换,在运行时,clr会做检查,以防出现难以预料的结果,比如程序崩溃,安全漏洞(类型伪装是许多安全漏洞的根源,使得程序变得不健壮)。
5.is:检查类型兼容性,返回布尔值,不抛出异常。
if(o is Employee)//检查兼容性
{
Employee e = (Employee)o;//强制类型转换。两次检查,会有一定性能的消耗。
}
as:检查类型兼容性,如果兼容,返回同一对象的非null引用,否则返回null,所以使用引用前要做非空判断。
Employee e = o as Employee;//一般采用这种类型的编程模式,性能较好。
if(e!=null){...}
6.clr会自动将所有的局部变量初始化为null或0,但是,如果试图从一个尚未显示初始化的局部变量读取数据,编译是通不过的:使用了未赋值的局部变量。
7.Employee对象(类型对象指针、同步块索引、实例字段)与Employee对象对象(类型对象指针、同步块索引、静态字段、方法表)。
8.primitive type :基元类型。
9.short-System.int16-16位;char-System.Char-16位
10.所谓安全转换,就是不发生数据丢失的转换,隐式转换。如果会发生数据丢失,就要进行显示转换,。c#总是对数据进行阶段处理,不进行向上取整(比如single转换为int)。
11.c#溢出检查默认是关闭的(自动进行处理),可以通过项目属性-->生成-->高级,打开。如果发生溢出,抛出overflowexception。
System.Decimal比较特殊,clr没有相应的IL指令来决定如何处理一个Decimal值。如果对它的操作是不全的,就会抛出overflowexception。
12.wrap(回滚)——如果发生溢出,就回滚到一个非常小的,负的或者未定义的值,c++中数据溢出时的策略。
13.值类型的实例一般在线程栈上分配。在代表值类型实例的一个变量中,并不包含一个指向实例的指针。相反,变量中包含了实例本身的字段。由于变量已经包含了实例的字段,所以为了操作实例中的字段,不再需要提供一个指针。(申明一个结构变量,不需要new,直接就可以操作结构中的字段)
14.隐式密封,sealed,防止继承,不能作为基类型。
15.
//能通过编译,因为c#认为v1的字段已被初始化为0
SomeVal v1 = new SomeVal();
int a = v1.x;
//不能通过编译,因为c#认为v1的字段还没有被初始化
SomeVal v1;
int a = v1.x;
类似与方法中的局部变量
16.
struct Point
{ public int x,y;}
ArrayList list = new ArrayList();
Point p;
p.x=p.y=1;
list.Add(p);//Add方法需要的参数是object obj,而p是一个值类型,所以会发生装箱操作。
为了将一个值类型转换成一个引用类型,要使用一个名为装箱(boxing)的机制。
装箱操作内部所发生的事
1.内存分配。
2.复制值类型字段的值到堆内存。
3.返回对象的地址。
Point p = (Point)a[0];
1.获取已装箱的Point对象中的各个Point字段的地址,这个过程称为拆箱(unboxing)。
2.将这些字段包含的值复制到基于栈的值类型实例中。
应该使用System.Collections.Generic.List<T>类,而不要使用System.Collections.ArrayList。
1.集合类的性能得到了显著提升。
2.泛型集合类允许开发人员在操作值类型的集合不需要对集合中的项进行装箱/拆箱处理。需要创建的对象少了,执行垃圾回收的次数也少了。
3.编译时安全。
17.大多数方法重载的目的就是为了减少装箱的次数。
18.注意先要new();
Header h = new Header();
List<Header> list = new List<Header>();
for (int i = 0; i < 10; i++)
{
//加上这句后,new 出了10个不同对象。否则只是一个对象,只是改变了这个对象的属性值而已。
//h = new Header();
h.RequestDate = "date"+i.ToString();
h.Filler = "filter" + i.ToString();
//存的是引用地址,此处list里存储的都是同一个地址。
list.Add(h);
}
19.
报ObjectDisposedException(InvalidOperationException)
public class ObjectDisposedExceptionTest
{
public static void Main()
{
MemoryStream ms = new MemoryStream(16);
ms.Close();
try
{
ms.ReadByte();
}
catch (ObjectDisposedException e)
{
Console.WriteLine("Caught: {0}", e.Message);
}
}
}
20.Socket编程,一问一答式。发送命令,接受回复的消息,根据消息再作出下一步的动作。
21.ftp有关的问题。
a.对于内容是文本的文件,读和写时都指定编码,如Encoding.ASCII。传输形式为ASCII类型。如果使用BINARY形式而又不是专有的ftp server,会导致文件格式不正确。
b..net3.5和.net4.0,对ftp的封装已经有所变化。具体在http://blog.csdn.net/yyf_ad/article/details/7447520。所以可以使用socket方式发送ftp command。
c.常用的ftp command.
1.ftp-->open computername;
2.pwd:current dir;
3.ls/dir:show file
22.mq的问题
a.CCSID,如果MQ Client所在操作系统的字符集与队列管理器的ccsid不一致,就会导致通信的失败。在代码中设置环境变量MQCCSID:Environment.SetEnvironment("MQCCSID","437");
b.远程访问MQ:
1、以MQI的方式(client/server)通信,在客户端和服务端都必须有通道定义。在客户端的叫做client-conn channel,可以有多种方式去设定,常用且简单的方式有1.设置环境变量MQSERVER=channel/tcp/hostname(port).2.直接在代码中设置,MQEnvironment.Host=host name;MQEnvironment.Channel = channel name;MQEnvironment.Port = 1414;在服务端需创建一个server-conn类型的通道。这样客户端和服务端就能建立连接。在项目中需引入相应的dll。
(所需的参数,hostname,port(端口区分多个队列管理器),channel(server-conn))
c.conn type 无需指定
d.访问权限问题。设置服务端的通道的MCAUSER为mqm组的成员。
f.看客户端和服务端的日志,信息是不一样的。
23.
性能注意事项
如果要减少应用程序分配的内存总量,请记住留用字符串有两个不希望出现的副作用。首先,为留用的 String 对象分配的内存在公共语言运行库 (CLR) 终止之前不大可能释放。这是因为 CLR 对留用的 String 对象的引用可能保持到应用程序终止之后,甚至可能保持到应用程序域终止之后。其次,要留用字符串,必须先创建字符串。即使 String 对象使用的内存最终将通过垃圾回收,仍然必须分配该内存。
String s1 = "MyTest";
String s2 = new StringBuilder().Append("My").Append("Test").ToString();
String s3 = String.Intern(s2); //从字符串池中寻找与s1值相同的引用,如果有就返回这个引用,没有就向池中添加
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.
24.新增文件,本地编译通过,commmit。
25.使用到App.config,会有一个应用名.exe.config,包含了App.config的信息。发布时将.exe和.exe.config放在一起发布。如果修改了配置文件,保存了但是没有重新编译项目,所做的修改就不会生效,这是使用配置文件的一个缺点。
26.cvs update:move away *file ;it is in the way的问题,将所在文件的目录整个删除掉,在重新更新下来。
27..net版本问题,.net2.0跨线程更新界面,直接使用Action是不行的,要用自己定义的delegate。
28.System.Console.WriteLine(),如果打印的条数很多,不会全部显示出来。
29.http://stackoverflow.com/questions/5018451/mq-series-messages-get-read-more-than-once
http://stackoverflow.com/questions/3084849/how-to-do-a-transactional-get-from-websphere-mq-in-dotnet
30.八进制---以0开头,0123表示八进制的123,二进制为001 101 011,十进制为84.
十六进制---以0x开头,0x123表示十六进制的123,二进制为0001 0010 0011,十进制为291.
31.cil managed:各种支持.net的语言编译后生成与平台无关的中间语言,易于集成。
run managed:方法将在运行时由clr负责处理。
32.
1、泛型技术在.net2.0时代被加入语言特性,从.net2.0开始,委托也开始支持泛型技术,这就是“泛型委托”。
2、.net3.5引入无参数类型的Action委托。
3、.net3.0引入Lambda表达式。
33.
利用委托实现回调。
public delegate List<T> ParseDelegate(string str);//声明一个委托,参数是string,返回值List<T>
//A和B里分别有一个满足该委托的方法
class A
{
public List<MyClass1> Parse(string s){...}
}
class B
{
public List<MyClass2> Parse(string s){...}
}
class Controller
{
private ParseDelegate d;
//注册需要回调的方法
public void RegisterDelegateForCallback(ParseDelegate method)
{
d+=method;
}
//调用需要回调的方法
public void CallBack()
{
if(d!=null){ d.Invoke(); }
}
}
34.定时回调
System.Threading.Timer类
public Timer(TimerCallback callback,Object state,int dueTimer,int period)
callback:public delagate void TimerCall(Object state)
state:传递到回调函数中的参数
dueTime:调用回调方法之前延迟的时间量(毫秒)
period:每隔多少时间调用一次(毫秒)
35.
多线程回调
单独写一个线程类
class MyThread
{
public Func<int[ ]> createArrl;
public Action<int[ ]> shoeArr;
public void DoWork(){...}
}
36.
方法签名一致:
public delegate void TimerCallback(Object state) ---Timer t = new Timer(TimerCallback callback,Object state,int dueTimer,int period)
public delegate void WaitCallback(Object state)---ThreadPool.QueueUserWorkItem(WaitCallback callback,Object state)
public delegate void ParameterizedThreadStart(Object state) ----Thread t = new Thread(new ParameterizedThreadStart(...));
37.日志信息需详细。
38.在回调函数中如果需要更新界面,需要使用委托。
39.到所该目录下去更新。
40.数据压缩和加锁的问题。
41.
public const int MAX = 100;//在编译时获取。如果改变了值,而没有重新编译,获取的还是原来的值。跟配置文件一样
public static readOnly int MAX = 100;//运行时获取。