文章已阅读
 

.Net中所有内建类型基类是什么?

System.Object

System.Object 中包含哪些方法,哪些是虚方法?

1
2
3
4
5
6
7
8
9
10
11
12
virtual bool Equals(object obj);//虚方法
virtual int GetHashCode(object obj);//虚方法
Type GetType();
virtual string ToString();//虚方法

//public static method
bool Equals(object objA,object objB);
bool RefernceEquals(object objA,object objB);

//protected
object MemberwiseClone();//浅拷贝
Finalize();//析构方法,用于释放非托管资源

值类型与引用类型?

ASP.NET和ASP的区别?

ASP.NET和ASP的最大区别在于编程思维的转换以及功能的增强。

ASP使用VB/JS这样的弱类型、面向结构的脚本语言混合html来编程,

而非面向对象,这就明显产生以下几个问题:

1、代码逻辑混乱,难于管理。

2、代码的可重用性差:由于是面向结构的编程方式,并且混合html,

所以可能页面原型修改一点,整个程序都需要修改,代码重用性差。

3、弱类型造成潜在的出错可能。

以上是ASP语言本身的弱点,在功能方面ASP同样存在问题:

第一是功能太弱,一些底层操作只能通过组件来完成

第二缺乏完善的纠错/调试功能

ASP.NET理论上可以使用任何编程语言包括C#,VB.NET、JS、、J#、Managed C++等等,

最合适的编程语言还是MS为.NET Frmaework专门推出的C#

优点如下:

(1)是面向对象的编程语言,简单易学。

(2)具有面向对象编程语言的一切特性,比如封装性、继承性、多态性等等,

封装性使得代码逻辑清晰,并且应用到ASP.NET上就可以使业务逻辑和Html页面分离;

继承性和多态性使得代码的可重用性大大提高

(3)C#还提供了完善的调试/纠错体系。

为什么.NET程序第一次运行比较慢?

aspx页面在运行时,第一次访问时要进行编译。

当你再次运行时,由于缓存机制,速度就会正常了。

C#的命名规范

主要有Pascal和Camel两种

Pascal:单词的首字母大写,如ProductType;

Camel:首个单词的首字母小写,其余单词的首字母大写,如productType)

以下是一些常用的C#成员及其推荐命名方法:

类class:Pascal

枚举类型enum:Pascal记住,是以Pascal命名,切勿包含Enum

委托delegate:Pascal以Pascal命名,不以任何特殊字符串区别于类名、函数名

接口interface:Pascal注:总是以”I”前缀开始,后接Pascal命名

方法function: Pascal

命名空间namespace: Pascal比如:usingExcelQuicker.Framework

属性:Pascal

参数:Camel 首字母小写

常量const: Camel 字母全部大写

局部变量:Camel 声明变量是以str开头

数据成员:Camel 以m开头+Pascal命名规则,如mProductType(m意味member)

类的成员修饰符及其访问权限?

private : 私有成员, 在类的内部才可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
public : 公共成员,完全公开,没有访问限制。
internal: 在同一程序集(命名空间)内可以访问。

列举ASP.NET 页面之间传递值的几种方式。

1.使用QueryString, 如…?id=1; response. Redirect()…
2.使用Session变量
3.使用Server.Transfer
4.使用Cookie
5.使用Application

C#中的委托是什么?事件是不是一种委托?

委托可以把一个方法作为参数代入另一个方法。
委托可以理解为指向一个函数的引用。
事件是委托

override与重载的区别

重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要
Override 是在子类对基类中函数的重写。为了适应需要。

如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?

this.Server.Transfer,  Response. Redirect()—QueryString

描述一下C#中索引器的实现过程,是否只能根据数字进行索引?

不是。可以用任意类型。

用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层?

一般为3层:数据访问层,业务层,表示层。
数据访问层对数据库进行增删查改。
业务层一般分为二层,业务表观层实现与表示层的沟通,业务规则层实现用户密码的安全等。
表示层为了与用户交互例如用户添加表单。
优点: 分工明确,条理清晰,易于调试,而且具有可扩展性。
缺点: 增加成本。

什么叫应用程序域?

应用程序域可以理解为一种轻量级进程。起到安全的作用。占用资源小。

CTS、CLS、CLR分别作何解释?

CTS是通用类型系统(Common Type System)
CLR是公共语言运行时(Common language runtime)
CLS是公共语言定义(Common Language Specification)

什么是装箱和拆箱?

从值类型接口转换到引用类型装箱。从引用类型转换到值类型拆箱。

什么是受管制的代码?

unsafe:非托管代码。不经过CLR运行。

什么是强类型系统?

RTTI:类型识别系统

net中读写数据库需要用到那些类?他们的作用?

DataConnection:连接数据库
DataSet:数据存储器。
DataCommand:执行语句命令。
DataAdapter:数据的集合,用于填充数据。

ASP.net的身份验证方式有哪些?分别是什么原理?

Windwos(默认)用IIS…From(窗体)用帐户…Passport(密钥)

什么是Code-Behind技术?

code-Behind技术就是代码隐藏(代码后置),code-Behind是基于部分类技术实现的;
在ASP.NET中通过ASPX页面指向CS文件的方法实现显示逻辑和处理逻辑的分离,这样有助于web应用程序的创建。
比如分工,美工和编程的可以个干各的,不用再像以前asp那样都代码和html代码混在一起,难以维护。

在.net中,配件的意思是?

程序集。(中间语言,源数据,资源,装配清单)

常用的调用WebService的方法有哪些?

1.使用WSDL.exe命令行工具。
2.使用VS.NET中的Add Web Reference菜单选项

…net Remoting 的工作原理是什么?

服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。

在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别。

string str = null 是不给他分配内存空间,而string str = “” 给它分配长度为空字符串的内存空间。

请详述在dotnet中类(class)与结构(struct)的异同?

Class可以被实例化,属于引用类型,是分配在内存的堆上的,Struct属于值类型,是分配在内存的栈上的。

SQLSERVER服务器中,给定表 table1 中有两个字段 ID、LastUpdateDate,ID表示更新的事务号,LastUpdateDate表示更新时的服务器时间,请使用一句SQL语句获得最后更新的事务号。

Select ID FROM table1 Where LastUpdateDate = (Select MAX(LastUpdateDate) FROM table1)

简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。

WS主要是可利用HTTP,穿透防火墙。而Remoting可以利用TCP/IP,二进制传送提高效率。

NET和C#是什么关系?

C#就是为宣传.NET而创立的,它直接集成于Visual Studio .NET中,VB也在.NET 1.0发布后对其进行支持, 所以这两门语言与.NET平台耦合度很高,并且.NET上的技术大多都是以C#编程语言为示例,所以经常就.NET和C#混为一谈(实质上它们是相辅相成的两个概念)。
而作为一个开发者平台,它不仅仅是包含开发环境、技术框架、社区论坛、服务支持等,它还强调了平台的跨语言、跨平台编程的两个特性

列举ASP.NET 页面之间传递值的几种方式。

QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中。如果是传递一个或多个安全性要求不高或是结构简单的数值时,可以使用这个方法。但是对于传递数组或对象的话,就不能用这个方法了。
Application对象的作用范围是整个全局,也就是说对所有用户都有效。其常用的方法用Lock和UnLock。
Session变量 想必这个肯定是大家使用中最常见的用法了,作用于用户个人,所以,过量的存储会导致服务器内存资源的耗尽。
Cookie对象变量这个也是大家常使用的方法,与Session一样,其是什对每一个用户而言的,但是有个本质的区别,即Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用。
Server.Transfer方法这个才可以说是面象对象开发所使用的方法,其使用Server.Transfer方法把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流,所以这个方法是完全面象对象的,简洁有效。

一列数的规则如下: 1、1、2、3、5、8、13、21、34…… 求第30位数是多少, 用递归算法实现。

public static int Calculate(int x)

    {

        int retInt = 1;

        if (x > 2)

        {

            return Calculate(x - 2) + Calculate(x - 1);

        }

        else

            return retInt;

    }

C#中的委托是什么?事件是不是一种委托?

委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。可以通过委

托调用方法。委托用于将方法作为参数传递给其他方法。

委托具有以下特点:

委托类似于 C++ 函数指针,但它们是类型安全的。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不必与委托签名完全匹配。
事件是一种特殊的委托。

override与重载的区别

Override:要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,重写的基方法必须与 override 方法具有相同的签名。

方法重载:一个类中可以有一个以上的方法拥有相同的名称。但必须有不相同的签名。

如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?

QueryString、 Server.Transfer方法。

请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?

foreach (Control control in this.Controls)

        {

            if (control is TextBox)

            {

                TextBox tb = (TextBox)control;

                tb.Text = String.Empty;

            }

        }

请编程实现一个冒泡排序算法?

//冒泡排序

    public static void MaoPaoSort(ref int[] arrays)

    {

        if (arrays != null && arrays.Length > 0)

        {

            for (int i = 1; i < arrays.Length; i++)

            {

                bool isChange = false;

                for (int j = 0; j < arrays.Length - i; j++)

                {

                    if (arrays[j] > arrays[j + 1])

                    {

                        int tempValue = arrays[j];

                        arrays[j] = arrays[j + 1];

                        arrays[j + 1] = tempValue;

                        isChange = true;

                    }

                }

                if (!isChange)

                    break;

            }

        }

    }

描述一下C#中索引器的实现过程,是否只能根据数字进行索引?

索引器允许类或结构的实例就像数组一样进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。 Public ReturnType this[ paramType index]{get{} set{}},可以用任何类型进行索引。

求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public static int sumMethod1(int m)

{

int sum=0;

for (int i = 1; i <= m; i++)

{

if (i % 2 != 0)

sum += i;

else

sum -= i;

}

return sum;

}

public static int sumMethod2(int m)

{

int sum = 0;

if (m % 2 != 0)

sum = m / 2 + 1;

else

sum = -(m / 2);

return sum;

}

在下面的例子里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class A

{

public A()

{

PrintFields();

}

public virtual void PrintFields() { }

}



class B : A

{

int x = 1;

int y;

public B()

{

y = -1;

}

public override void PrintFields()

{

Console.WriteLine("x={0},y={1}", x, y);

}

}

当使用new B()创建B的实例时,产生什么输出?

X=1,Y=0

什么叫应用程序域?

应用程序域 (application domain) (AppDomain) 一种边界,它由公共语言运行库围绕同一应用程序范围内创建的对象建立(即,从应用程序入口点开始,沿着对象激活的序列的任何位置)。应用程序域有助于将在一个应用程序中创建的对象与在其他应用程序中创建的对象隔离,以使运行时行为可以预知。在一个单独的进程中可以存在多个应用程序域

CTS、CLS、CLR分别作何解释?

CTS:通用类型系统。CLS:通用语言规范。CLR:公共语言运行库。

什么是装箱和拆箱?

装箱:装箱转换是指将一个值类型隐式或显式地转换成一个object类型,拆箱:拆箱转换是指将一个对象类型显式地转换成一个值类型。

什么是受管制的代码?

受托管的代码不能直接写内存,是安全的,它受CLR的内存安全管理,而非托管代码是非安全代码,可以使用指针操作内存

net中读写数据库需要用到那些类?他们的作用?

DataSet:数据存储器

Connection对象,用来创建和打开,关闭数据库连接。

Command对象,用来执行各种sql语句或者调用存储过程。

Adapter对象,数据适配器,用来执行SQL语句,配合数据集执行比较多。

DataReader,只读的对象,有着很高的性能。

在.net中,配件的意思是?

程序集。(中间语言,源数据,资源,装配清单)

常用的调用WebService的方法有哪些?

1.使用WSDL.exe命令行工具。

 2.使用VS.NET中的Add Web Reference菜单选项

.net Remoting 的工作原理是什么?

服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。

公司要求开发一个继承System.Windows.Forms.ListView类的组件,要求达到以下的特殊功能:点击ListView 各列列头时,能按照点击列的每行值进行重排视图中的所有行 (排序的方式如DataGrid相似)。根据您的知识,请简要谈一下您的思路

根据点击的列头,包该列的名称取出,按照该列名排序后,再绑定到ListView中。

能用foreach遍历访问的对象需要实现IEnumerable接口或声明GetEnumerator方法的类型。

GC是什么? 为什么要有GC?

GC是垃圾收集器。程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一: System.GC.Collect();

String s = new String(“xyz”);创建了几个String Object?

两个对象,一个是“xyx”,一个是指向“xyx”的引用对像s。

abstract class和interface有什么区别?

抽象类:

只能用做其它类的基类,它就是被设计来被继承的。
不能创建它的实例。
它使用abstract修饰符来声明。
抽象类可以包含抽象成员,但不是必须的,它的成员可以抽象成员和普通带实现的成员的任意组合。
它自己可以派生自另一个抽象类。任何派生自抽象类的类必须使用override关键字实现该类所有的抽象成员,除非派生类自己也是抽象类。
接口:

接口是表示一组函数成员而不实现成员的引用类型。其它类和结构可以实现接口。
接口声明不包括数据成员。
接口声明只能包含如下类型的静态成员函数的声明:方法、属性、事件、索引。
接口的成员不能包含任何实现代码,而在每一个成员声明的主体后必须使用分号。
接口名称必须从大写的I开始。它和类一样,也可以声明成分部接口。
接口声明可以有任何的访问类型:public、protected、internal、private。
接口成员是隐式Public的,不允许有任何访问修饰符。
1, 什么是线程池

为了帮我们降低创建和销毁线程相关的成本,CLR为每一个进程维护了一个线程池。一开始进程的线程池是空的,如果进程使用的线程被创建,并且完成了线程的执行,它不会被销毁,而是加入到进程的线程池中,这后,如果进程需要一个另外一个线程,CLR就会从池中还原一个线程,这就节省了很多时间。

启动一个线程是用run()还是start()?

启动一个线程是调用start()方法,这并不意味着线程就会立即运行,只是进入了可运行状态。直接调用run()方法不会产生线程,而是把它当作普通的方法调用,马上执行

接口是否可继承接口? 抽像类是否可实现(implements)接口? 抽像类是否可继承实体类(concrete class)?

接口可以继承接口。抽像类可以实现(implements)接口,抽像类是否可继承实体类,但前提是实体类必须有明确的构造函数。

构造器Constructor是否可被override?

构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。

Constructor不能被继承,所以Constructor也就不能被override。每一个类必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须负责在一开始调用父类的构造函数。

是否可以继承String类?

不可以,因为String类是密封类,被Sealed修饰符所修饰。

两个对像值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

不对,有相同的hash code。

Hash Code:可以简单的理解为内存的地址。

“==” : 操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储

的地址是否相同,即栈中的内容是否相同。

“equals” : 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。

swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

可以。

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

不能,一个对象的一个synchronized方法只能由一个线程访问。

List, Set, Map是否继承自Collection接口?

List,Set是Map不是

数组有没有length()这个方法? String有没有length()这个方法?

数组和string都没有Length()方法,只有Length属性。

sleep() 和 wait() 有什么区别?

sleep()方法是将当前线程挂起指定的时间。

wait()释放对象上的锁并阻塞当前线程,直到它重新获取该锁。

short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能隐式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。

复合赋值表达式自动地将所执行计算的结果转型为其左侧变量的类型,s1+=1等价于s1=(short)s1+1;

如何处理几十万条并发数据?

用存储过程或事务。取得最大标识的时候同时更新..注意主键不是自增量方式这种方法并发的时候是不会有重复主键的..取得最大标识要有一个存储过程来获取.

Session有什么重大BUG,微软提出了什么方法加以解决?

是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件。

进程和线程的区别?

进程是系统进行资源分配和调度的单位;线程是CPU调度和分派的单位,一个进程可以有多个线程,这些线程共享这个进程的资源。

进程:进程就是一组资源,它们构成了一个正在运行的程序。

线程:在进程中系统创建了一个叫做线程的内核对象,线程体现了一个程序的真实执行情况。

堆和栈的区别?

栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

栈:它是一个内存数组,是一个LIFO的数据结构,数据只能从栈顶插入和删除。

堆:它是一块内存区域,在堆里可以分配大块的内存用于存储某类型的数据,堆里的内存可以以任意顺序存入和取出。

成员变量和成员函数前加static的作用?

它们用来反映类的状态。
静态成员它被类的所有实例所共享,所有实例都访问同一内存位置。
它们独立于所有的类实例,即使没有类实例,也可以调用类的静态成员。

ASP.NET与ASP相比,主要有哪些进步?

asp解释形,aspx编译型,性能提高,可以跟美工的工作分开进行,更有利于团队开发。

产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static int[] BuildIntArray()

{

int[] retsInt = new int[100];

List<int> tempList = new List<int>();

Random random = new Random();

while(tempList.Count < 100)

{

int num = random.Next(1, 101);

if (!tempList.Contains(num))

tempList.Add(num);

}

tempList.Sort();

for (int i = 0; i < tempList.Count; i++)

retsInt[i] = tempList[i];

return retsInt;

}

请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。

QueryString 传递一个或多个安全性要求不高或是结构简单的数值。但是对于传递数组或对象的话,就不能用这个方法了
session(viewstate) 简单,但易丢失 作用于用户个人,过量的存储会导致服务器内存资源的耗尽。
application 对象的作用范围是整个全局,也就是说对所有用户都有效。其常用的方法用Lock和UnLock
cookie 简单,但可能不支持,可能被伪造 Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用
input ttype=”hidden” 简单,可能被伪造
url参数简单,显示于地址栏,长度有限
Server.Transfer 把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流
数据库稳定,安全,但性能相对弱

请指出GAC的含义?

全局程序集缓存。

GAC(Global Assembly Cache),他的作用是可以存放一些有很多程序都要用到的公共Assembly。这样,很多程序就可以从GAC里面取得Assembly,而不需要再把所有要用到的Assembly都拷贝到应用程序的执行目录下面。

向服务器发送请求有几种方式?

get,post。get一般为链接方式,post一般为按钮方式。

区别:

  Get 方式, 服务器端用Request.Qurystring取变量的值,安全性不高,传送数据量小。
  post方式,服务器端用Request.Form获取提交的数据,安全性高。

建议:

1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;

2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式。

DataReader与Dataset有什么区别?

连接数据库时DataSet是非面向连接的,而DataReader是面向连接的。
DataSet表示一个数据集,是数据在内存中的缓存,可以包括多个表,是保存数据的数据结构。而Datareader不承担保存数据的责任,它只负责从数据源读取数据到本地而已,它不是数据结构,而是网络通讯组件的高层封装。
DataSet可以离线处理,前后滚动,而DataReader不能离线处理,且是只读向前的,速度快。
DataSet可以存储数据库各种对象的,比如表触发器等,可以更新回原来的数据库。而DataReader只能存储游标记录,不可以更新回原来的数据库, 它类似一个只能向前的游标记录集。

软件开发过程一般有几个阶段?每个阶段的作用?

软件开发一般分为五个阶段:

问题的定义及规划
此阶段是软件开发与需求方共同讨论,主要确定软件的开发目标及其可行性。

需求分析
在确定软件开发可行性的情况下,对软件需要实现的各个功能进行详细需求分析。需求分析阶段是一个很重要的阶段,这一阶段做的好,将为整个软件项目的开发打下良好的基础。“唯一不变的是变化本身”,同样软件需求也是在软件开发过程中不断变化和深入的,因此,我们必须定制需求变更计划来应付这种变化,以保护整个项目的正常进行。

软件设计
此阶段中要根据需求分析的结果,对整个软件系统进行设计,如系统框架设计、数据库设计等。软件设计一般分为概要设计和详细设计,软件设计将为软件程序编写打下良好的基础。

程序编码
此阶段是将软件设计的结果转化为计算机可运行的程序代码。在程序编码中必定要制定统一、符合标准的编写规范。以保证程序的可读性、易维护性。提高程序的运行效率。

软件测试
在软件设计完成之后要进行严密的测试,一发现软件在整个软件设计过程中存在的问题并加以纠正。整个测试阶段分为单元测试、组装测试、系统测试三个阶段进行。测试方法主要有白盒测试和黑盒测试。

在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?

Uning:
using做为命名空间指令:通过在源文件顶端放置Using命名空间指令以避免不得不使用长名称,它通知编译器你将要使用来自某个指定命名空间的类型。
using做为别名指令:它允许对一个命名空间或命名空间中的一个类型起一个别名。
using语句:某些类型的非托管对象有数量限制或很耗费系统资源,这样在代码使用完它们后,就得尽可能快的释放它们,using语句有助于简化该过程并确保这些资源被适当的处置。

New :
创建类和结构的实例。
隐藏基类的方法。
创建匿名类型(var和new关键字一起使用时可以创建匿名类型,匿名类型只是一个继承了Object的、没有名称的类,该类的定义从初始化器中推断,类似于隐匿类型化的变量)。

需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    string str = "  afdkd   askdfji  ksdafj   ";
string strAfter = Regex.Replace(str.Trim(), @"\s+", " ");
```

### 下面这段代码输出什么?为什么?
```bash
int i = 5;

int j = 5;

if (Object.ReferenceEquals(i, j))

Console.WriteLine("Equal");

else

Console.WriteLine("Not Equal");

Not Equal,因为ReferenceEquals是Object的静态方法,用于比较两个引用类型的对象是否是对于同一个对象的引用,对于值类型它总是返回false。

ReferenceEquals, == , Equals的区别

String对于声明的相同的字符串在堆上只保留一个Copy,所以有相同字符串值的两个字符串变量将会指向相同的Reference。
ReferenceEquals:
它是Object的静态方法,用于比较两个引用类型的对象是否是对于同一个对象的引用,对于值类型它总是返回false。
==:
它是一个可以重载的二元操作符,可以用于比较两个对象是否相等。
对于内置值类型,==判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false,而对于用户定义的值类型,如果没有重载==操作符,==将是不能够使用的。
对于引用类型,== 默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时候才返回true。但是.NET Framework中的类很多对==进行了重载,例如String类的==与Equals的行为相同,判断两个字符串的内容是否相等。所以在应用中,对于 系统定义的引用类型建议不要使用==操作符,以免程序出现与预期不同的运行结果。
Equals():
它对于值类型和引用类型的定义不同,对于值类型,类型相同,并且数值相同(对于struct的每个成员都必须相同),则Equals返回 true,否则返回false。而对于引用类型,默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时 候才返回true。可以根据需要对Equals进行重载,例如String类的Equals用于判断两个字符串的内容是否相等。

什么叫做SQL注入,如何防止?请举例说明。

利用sql语言漏洞获得合法身份登陆系统。如身份验证的程序设计成:

1
2
3
4
5
6
7
8
9
10
11
SqlCommand com=new SqlCommand("Select * from users where username='"+t_name.text+"' and pwd='"+t_pwd.text+"'");

object obj=com.ExcuteScale();

if(obj!=null)

{

//通过验证

}

这段代码容易被sql注入。如用户在t_name中随便输入,在t_pwd中输入1’ or 1=’1 就可以进入系统了。可以采用参数化查询语句进行防止。

什么是反射?

有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程序集中。程序在运行时,可以查看其它程序集及其本身的元数据,一个运行的程序查看本身及其它程序集的元数据的行为叫做反射(reflection)。

用Singleton如何写设计模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
public sealed class Sun

{

private static Sun instance = null;

private Sun(){}

public static Sun Instance

{

get

{

return instance == null ? instance = new Sun() : instance;

}

}

}
```

### 什么是Application Pool?

Web应用,类似Thread Pool,提高并发性能。

### 什么是虚函数?什么是抽像函数?

虚函数:使它们可以在派生类中被重写,它自身可以有函数的实现。
抽像函数:规定其非虚子类必须实现的函数,必须被重写,它自身不可有函数的实现
### 什么是XML?

XML即可扩展标记语言(Extensible Markup Language)。它是一种以简单文本格式存储数据的方式,这意味着它可以被任何计算机读取,它在.Net中执行大量的任务,包括描述应用程序的配置、在Web服务之间传输信息等。

### 什么是ASP.net中的用户控件?

用户控件是能够在其中放置标记和 Web 服务器控件的容器。然后,可以将用户控件作为一个单元对待,为其定义属性和方法。有了用户控件,就不必为每个需要相同内容的页面多次创建用户界面,编写代码,而只需要创建一个用户控件,在几个页面中多次使用。

### 列举一下你所了解的XML技术及其应用

xml用于配置,用于保存静态数据类型.接触XML最多的是web Services..和config,soap协议

### ADO.net中常用的对象有哪些?分别描述一下。

提供者对象:

Connection 提供到数据源的基本连接。
Command 使用它对数据源发出命令。
CommandBuilder 此对象用于构建Sql命令,在基于单一表查询的对象中进行数据修改。
DataReader 这是一个快速而易用的对象,可以从数据源中读取仅能前向和只读的数据流。
DataAdapter 它是一个通用的类,可以执行针对数据源的各种操作,包括更新变动的数据,填充DataSet对象以及其它操作。
用户对象:

DataSet 它表示一组相关表,在应用程序中这些表作为一个单元来引用。

### 什么是code-Behind技术。

Code-Behind技术也称为代码隐藏技术,在ASP.NET中通过ASPX页面指向CS文件的方法实现显示逻辑和处理逻辑的分离,这样有助于web应用程序的创建。比如分工,美工和编程的可以个干各的,不用再像以前asp那样都代码和html代码混在一起,难以维护。

### 什么是SOAP,有哪些应用。

答:SOAP(Simple Object Access Protocol )简单对象访问协议,是在分散或分布式的环境中交换信息并执行远程过程调用的协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一种语言相互通信。这种相互通信采用的是XML格式的消息。

### C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?

Attribute是Microsoft .NET Framework文件的元数据,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。Attribute是派生于System.Attribute类之下,它的主要作用是描述
Property是面向对象编程的基本概念,提供了对私有字段的访问封装,在C#中以get和set访问器方法实现对可读可写属性的操作,提供了安全和灵活的数据访问封装。

### XML 与 HTML 的主要区别

XML是HTML的补充,而不是HTML的替代品,XML和HTML是两种不同用途的语言。
XML是被设计用来描述数据的,重点是:什么是数据,如何存放数据。而HTML是被设计用来显示数据的,重点是:显示数据以及如何显示数据更好上面。
XML是自由的、可以扩展的,XML标记并不是预先规定好的,你必须创造你自XML标记并不是,而在HTML文档中必须使用规则中定义好的标记
XML是区分大小写字母的,HTML不区分。
在HTML中,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略</p>或者</li>之类的结束 标记。在XML中,绝对不能省略掉结束标记。
在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个 / 字符作为结尾。这样分析器就知道不用 查找结束标记了。
在XML中,属性值必须封装在引号中。在HTML中,引号是可用可不用的。
在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。

### c#中的三元运算符是?

?:

### 当整数a赋值给一个object对像时,整数a将会被?

装箱。

### 类成员有5种可访问形式?

public
private
protected
internal
protected internal

### public static const int A=1;这段代码有错误么?是什么?

const表现的很像静态变量,它们对类的每个实例都是可见的,而且即使没有类的实例它们也可以使用,而与静态变量不同的是它没有自己的存储位置,而是在编译时被编译器替换,因此它不能声明为Static。

### float f=-123.567F; int i=(int)f;i的值现在是
-123
将f的值强制转换成int型,也就是将小数点后面的部分直接截取,保留整数部分。

### 委托声明的关键字是
Delegate。

### 在Asp.net中所有的自定义用户控件都必须继承自
Control。

### 在.Net中所有可序列化的类都被标记为
[Serializable]。

### 在.Net托管代码中我们不用担心内存漏洞,这是因为?
有GC垃圾回收机制。

### 下面的代码中有什么错误吗?_______
```bash
using System;

class A

{

public virtual void F(){

Console.WriteLine("A.F");

}

abstract class B:A

{

public abstract override void F();

}

abstract override 是不可以一起修饰.

当类T只声明了私有实例构造函数时,则在T的程序文本外部,不可以从T派生出新的类?

因为子类无法调用父类的构造函数,不可以直接创建T的任何实例。

Switch语句的格式?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
switch (1 + 1)

{

case 1:

Console.WriteLine("Wrong");

break;

case 2:

Console.WriteLine("right");

break;

default:

Console.WriteLine("jiaoyanqing");

break;

}


在.Net中,类System.Web.UI.Page 可以被继承么?

可以。

.net的错误处理机制是什么?

.net错误处理机制采用try->catch->finally结构,发生错误时,层层上抛,直到找到匹配的Catch为止。

异常:它是程序中的运行时错误,它违反了一个系统约束或应用程序约束,或出现了在正常操作时未预料的情形,如果程序没有提供处理该异常的代码,系统会挂起这个程序。

即使在Try块中有Return语句,Finally块也总是会在返回到调用代码之前执行。

利用operator声明且仅声明了==,有什么错误么?

要同时修改Equale和GetHash() ? 重载了”==” 就必须重载 “!=”

62-63=1 等式不成立,请移动一个数字(不可以移动减号和等于号),使得等式成立,如何移动?

62移动成2的6次方

对于这样的一个枚举类型:enum Color : byte { Red, Green, Blue, Orange };

1
2
3
string[] ss = Enum.GetNames(typeof(Color));

Array array = Enum.GetValues(typeof(Color));

C#可否对内存进行直接的操作?

C#可以直接对内存进行操作。但是默认情况下,为了保持类型安全,C#不支持指针运算。不过,通过使用 unsafe 关键字,可以定义可使用指针的不安全上下文。在不安全的上下文中,类型可以是指针类型以及值类型或引用类型。

ADO.NET相对于ADO等主要有什么改进?

ADO.NET不依赖于数据提供程序,而是使用.Net托管提供的程序。
不使用com
不在支持动态游标和服务器端游
可以断开connection而保留当前数据集可用
强类型转换
xml支持

大概描述一下ASP.NET服务器控件的生命周期

初始化 加载视图状态 处理回发数据 加载 发送回发更改通知 处理回发事件 预呈现 保存状态 呈现 处置 卸载

匿名内部类是否可以继承其它类,是否可以实现接口?

不能,可以实现接口

&和&&的区别。

&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and).

HashMap和Hashtable的区别。

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable.

重载方法可以改变返回值的类型?

error和exception有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

<%# %> 和 <% %> 有什么区别?

<%# %>表示绑定的数据源

<% %>是服务器端代码块

重载与覆盖的区别?

方法的覆盖是子类和父类之间的关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系
覆盖是一个方法或一对方法产生关系;方法的重载是多个方法之间的关系。
覆盖要求参数列表相同;重载要求参数列表不同。
覆盖关系中,调用那个方法体,是根据对象的类型(对象对应存储空间类型)来决定;重载关系,是根据调用时的实参表与形参表来选择方法体的。

分析以下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static void test(string ConnectString)

{

System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();

conn.ConnectionString = ConnectString;

try

{

conn.Open();

}

catch(Exception Ex)

{

MessageBox.Show(Ex.ToString());

}

finally

{

if (!conn.State.Equals(ConnectionState.Closed))

conn.Close();

}

}

请问

  1. 以上代码可以正确使用连接池吗?

如果传入的connectionString是一模一样的话,可以正确使用连接池。不过一模一样的意思是,连字符的空格数,顺序完全一致。

什么是WSE?目前最新的版本是多少?

WSE (Web Service Extension) 包来提供最新的WEB服务安全保证,目前最新版本2.0。

下面的例子中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class A

{

public static int X;

static A()

{

X = B.Y + 1;

}

}

class B

{

public static int Y = A.X + 1;

static B() { }

}

static void Main(){

Console.WriteLine("X={0},Y={1}", mytest.A.X, mytest.B.Y);

}

产生的输出结果是什么?

X=2,Y=1;

反射

什么是反射

反射是 .net framework 提供的一个帮助类库,用于读取和使用元数据。
程序集包含模块,而模块包含类型,类型又包含成员。反射则是访问封装程序集,模块和类型的对象的方法。
您可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型
然后可以调用类型其方法或访问其字段和属性(注意:无法访问私有构造)。

简单的说就是反射可以看清一个类或者说对象的本质
可以了解一个类或者说对象其底下有多少个方法,多少个属性,多少个私有属性,
并对其操作调用。

用到的类:

1)System.Reflection(其中System.Reflection.Assembly.LoadFile=>用于动态的加载程序集)
2)System.Type
System.Type 类对于反射起着核心的作用。 当反射请求加载的类型时,公共语言运行时将为它创建一个 Type。
您可以使用 Type 对象的方法、字段、属性和嵌套类来查找有关该类型的所有信息。

反射优缺点

优点:

1、反射提高了程序的灵活性和扩展性。
2、降低耦合性,提高自适应能力。
3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
缺点:

1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

反射的用途

1、它允许在运行时查看特性(attribute)信息。
2、它允许审查集合中的各种类型,以及实例化这些类型。
3、它允许延迟绑定的方法和属性(property)。
4、它允许在运行时创建新类型,然后使用这些类型执行一些任务。
5、MVC的路由就是反射做的。访问的Global的时候,会加载一遍dll

查看元数据

1、获取当前实例的 System.Type 的两种方式
1)使用对象 GetType()方法

1
2
Rectangle nc = new Rectangle();
Type type = nc.GetType();

2)使用c# typeof 运算符

1
Type type = typeof(Rectangle);

2、查看类中的成员:GetMembers()

1
2
3
4
5
MemberInfo[] minfos = type.GetMembers();
foreach (var i in minfos)
{
Console.WriteLine("成员: {0}", i.Name);
}

3、查看类中的构造方法:GetConstructors()

1
2
3
4
5
ConstructorInfo[] ci = type.GetConstructors();
foreach (var i in ci)
{
Console.WriteLine("构造函数: {0}", i.Name);
}

4、查看类中的属性:GetProperties()

1
2
3
4
5
PropertyInfo[] pis = type.GetProperties();
foreach (var i in pis)
{
Console.WriteLine("属性: {0}", i.Name);
}

5、查看类中的字段:GetFields()

1
2
3
4
5
FieldInfo[] fis = type.GetFields();
foreach (var i in fis)
{
Console.WriteLine("字段: {0}", i.Name);
}

6、用反射生成对象,并调用属性、方法和字段进行操作

1
2
3
4
5
6
7
8
9
object obj = Activator.CreateInstance(type);// 创建实例
FieldInfo fi = type.GetField("hight");// 取得hight字段
fi.SetValue(obj, );// 给hight字段赋值
PropertyInfo pi1 = type.GetProperty("length");// 取得length属性
pi1.SetValue(obj, , null);// 给length属性赋值
PropertyInfo pi2 = type.GetProperty("width");// 取得width属性
pi2.SetValue(obj, , null);// 给width属性赋值
MethodInfo mi = type.GetMethod("GetVolume");// 取得GetVolume方法
mi.Invoke(obj, null);// 调用GetVolume方法

7、查看类中的特性:type.GetCustomAttributes()

1
2
3
4
5
6
7
8
9
Object[] attributes = type.GetCustomAttributes(false);
foreach (var i in attributes)
{
DeBugInfo dbi = i as DeBugInfo;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}, Message: {1}", dbi.BugNo, dbi.Message);
}
}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
using System;
using System.Reflection;
namespace ConsoleTest
{
// 一个自定义特性 BugFix 被赋给类及其成员
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]

public class DeBugInfo : System.Attribute
{
private int bugNo;
public string message;

public DeBugInfo(int bg)
{
this.bugNo = bg;
}

public int BugNo
{
get
{
return bugNo;
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
}
/// <summary>
/// 矩形
/// </summary>
[DeBugInfo(, Message = "Return type mismatch")]
[DeBugInfo(, Message = "Unused variable")]
public class Rectangle
{
public int hight = ;
public double length { get; set; }
public double width { get; set; }
public Rectangle()
{
}
public Rectangle(double l, double w)
{
length = l;
width = w;
}
// 计算面积
[DeBugInfo(, Message = "Return type mismatch")]
public void GetArea()
{
Console.WriteLine("面积: {0}", length * width);
}
//计算体积
[DeBugInfo()]
public void GetVolume()
{
Console.WriteLine("体积: {0}", length * width * hight);
}
}

class ExecuteRectangle
{
public static void Main12()
{
//使用对象GetType()方法
//Rectangle nc = new Rectangle();
//Type type = nc.GetType();

//使用 C# typeof 运算符
Type type = typeof(Rectangle);

// 获取 Rectangle 类的所有成员
Console.WriteLine("\n遍历 Rectangle 类的成员开始---------------");
MemberInfo[] minfos = type.GetMembers();
foreach (var i in minfos)
{
Console.WriteLine("成员: {0}", i.Name);
}
Console.WriteLine("-------------------结束-------------------");

// 获取 Rectangle 类的所有构造函数
Console.WriteLine("\n遍历 Rectangle 类的构造函数开始-----------");
ConstructorInfo[] ci = type.GetConstructors();
foreach (var i in ci)
{
Console.WriteLine("构造函数: {0}", i.Name);
}
Console.WriteLine("-------------------结束-------------------");

// 获取 Rectangle 类的所有属性
Console.WriteLine("\n遍历 Rectangle 类的属性开始---------------");
PropertyInfo[] pis = type.GetProperties();
foreach (var i in pis)
{
Console.WriteLine("属性: {0}", i.Name);
}
Console.WriteLine("-------------------结束-------------------");

// 获取 Rectangle 类的所有public字段
Console.WriteLine("\n遍历 Rectangle 类的字段开始---------------");
FieldInfo[] fis = type.GetFields();
foreach (var i in fis)
{
Console.WriteLine("字段: {0}", i.Name);
}
Console.WriteLine("-------------------结束-------------------");

//用反射生成对象,并调用属性、方法和字段进行操作
Console.WriteLine("\n用反射生成对象,并调用属性、方法和字段进行操作");
object obj = Activator.CreateInstance(type);// 创建实例
FieldInfo fi = type.GetField("hight");// 取得hight字段
fi.SetValue(obj, );// 给hight字段赋值
PropertyInfo pi1 = type.GetProperty("length");// 取得length属性
pi1.SetValue(obj, , null);// 给length属性赋值
PropertyInfo pi2 = type.GetProperty("width");// 取得width属性
pi2.SetValue(obj, , null);// 给width属性赋值
MethodInfo mi = type.GetMethod("GetVolume");// 取得GetVolume方法
mi.Invoke(obj, null);// 调用GetVolume方法
Console.WriteLine("-------------------结束-------------------");

// 遍历 Rectangle 类的特性
Console.WriteLine("\n遍历 Rectangle 类的特性开始---------------");
Object[] attributes = type.GetCustomAttributes(false);
foreach (var i in attributes)
{
DeBugInfo dbi = i as DeBugInfo;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}, Message: {1}", dbi.BugNo, dbi.Message);
}
}
Console.WriteLine("-------------------结束-------------------");

// 遍历 Rectangle 类的方法上的特性(此处只遍历)
Console.WriteLine("\n遍历 Rectangle 类的方法上的特性开始-------");
MethodInfo[] m = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (var i in m )
{
foreach (Attribute a in i.GetCustomAttributes(true))
{
DeBugInfo dbi = a as DeBugInfo;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}, for Method: {1}, Message: {2}", dbi.BugNo, i.Name, dbi.Message);
}
}
}
Console.WriteLine("-------------------结束-------------------");

Console.ReadLine();
}
}
}

System.Reflection.Assembly类

Assembly类可以获得程序集的信息,也可以动态的加载程序集,以及在程序集中查找类型信息,并创建该类型的实例。

使用Assembly类可以降低程序集之间的耦合,有利于软件结构的合理化。

1
2
3
4
5
6
7
8
9
10
11
//通过程序集名称返回Assembly对象
Assembly ass = Assembly.Load("ConsoleTest");

//通过DLL、EXE文件名称返回Assembly对象
Assembly ass = Assembly.LoadFrom("ConsoleTest.exe");

//通过Assembly获取程序集中类
Type t = ass.GetType("ConsoleTest.Rectangle"); //参数必须是类的全名

//通过Assembly获取程序集中所有的类
Type[] types = ass.GetTypes();

面向对象的三大特性

面向对象

通过封装对象的属性,实现对象的方法事件一次得到最终的对象。

封装

把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果不想被外界方法,我们大可不必提供方法给外界访问。
简单来说:对内私有,对外公有,用get和set进行封装,保护数据,隐藏功能。
特点:
(1)是面向对象编程的核心思想
(2)对象(类)是由属性、方法、事件封装而成
(3)保证类的内部数据结构的完整
(4)包含属性封装、行为封装、对象封装、命名空间封装、解决方案封装
(5)访问修饰符:设置类的成员的访问权限
1)public(公开):任何代码都可访问
2)private(私有):只能在当前类中访问
3)protected(受保护的):当前类以及所有子类可访问
4)internal:同一程序集(命名空间)可访问
5)protected internal/internal protected:同意程序集或子类可访问

继承

子类继承父类的所有公用属性和方法

1)子类继承父类的属性、构造、行为
2)父类有的子类不一定具有,子类有的父类也不一定具有
3)c#不支持多重继承,但是可以多重接口继承
4)关键字this:当前类自己,base:当前类的亲父类
5)实例化过程(对象创建过程,先调用最终父类的构造,然后依次往下调用到当前类)
6)析构过程(对象销毁的过程,从自己开始销毁直到最终父类)

多态

多态包含重载和重写

重载(关键字OverLoad):函数名相同,参数个数、类型不同的统称为重载。
优点:在不改变原来方法的基础上,新增功能。

重写(关键字Override):子类对基类中的虚成员(虚方法、虚属性等)或抽象成员(抽象方法、抽象属性等)进行覆盖,重新实现。

[特性]

多线程

.net中创建多线程可以有四种方式:

Thread类
委托
ThreadPool类
Task类

Thread类创建多线程

1
2
3
4
5
6
7
8
///
/// Thread类启动
///
public static void Thread_Start()
{
Thread thread = new Thread(new ParameterizedThreadStart(AddA));
thread.Start(“Thread”);
}

委托方式创建多线程

1
2
3
4
5
6
7
8
9
delegate void Delegate_Add(Object stateInfo);
///
/// 委托方式启动
///
public static void Delegate_Start()
{
Delegate_Add dele_add = AddA;
dele_add.BeginInvoke(“Delegate”, null,null);
}

ThreadPool类创建多线程

1
2
3
4
5
6
7
8
///
/// 线程池方式启动
///
public static void ThreadPool_Start()
{
WaitCallback w = new WaitCallback(AddA);
ThreadPool.QueueUserWorkItem(w,“ThreadPool”);
}

Task类创建多线程

1
2
3
4
5
6
7
8
9
///
/// Task方式启动
///
public static void Task_Start()
{
Action add_Action = AddA;
Task task = new Task(add_Action, “Task”);
task.Start();
}

IsBackground

所有的多线程操作,必定有一个主线程;
主线程(ParentThread)与子线程(ChildThread)的生命周期也是相互作用的;
子线程中的IsBackground属性,决定了两类线程生命周期的依赖关系;
如果ChildThread.IsBackGround=true,ParentThread结束时,ChildThread也会终止;
如果ChildThread.IsBackGround=false,ParentThread必须等ChildThread终止后才会终止;

对于这四种多线程方法,默认生成线程的IsBackGround有所不同:

类型 IsBackGround
Thread类 false
委托 true
ThreadPool类 true
Task类 true

辅助方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public static int a;
static void Main(string[] args)
{

MultiThreadDemo demo = new MultiThreadDemo();
Console.WriteLine("Main Thread ID:" + Thread.CurrentThread.ManagedThreadId);
MultiThreadTest();

Thread.Sleep(10000);
Console.WriteLine("a:" + a);
Console.WriteLine("Main thread exits.");
}
///
/// 打印当前线程信息
///
public static void PrinctCurrentThreadInfo()
{
var t = Thread.CurrentThread;
Console.WriteLine(“Current Thread ID:” + t.ManagedThreadId);
Console.WriteLine(“Is Back Ground:{0}”, t.IsBackground);
Console.WriteLine(“Thread Priority:” + t.Priority.ToString());
Console.WriteLine(“Thread State:” + t.ThreadState.ToString());

}

///
/// 测试方法
///
///
public static void AddA(Object stateInfo)
{

Console.WriteLine("{0,-20} Thread ID:{1}", stateInfo.ToString(), Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("IsBackground:{0}\n", Thread.CurrentThread.IsBackground);

while (a < 10)
{
Console.WriteLine("{0,-20} Start :{1}", stateInfo.ToString(), a);
Thread.Sleep(10);
a++;
Console.WriteLine("{0,-20} End :{1}\n", stateInfo.ToString(), a);
}

Console.WriteLine("{0,-20} Thread ID:{1} Result:{2}", stateInfo.ToString(), Thread.CurrentThread.ManagedThreadId, a);
return;
}

///
/// 多线程测试
///
public static void MultiThreadTest()
{
a = 0;
Thread_Start();
Delegate_Start();
ThreadPool_Start();
Task_Start();
}

委托

什么是委托?

A请求B帮A获取或者传递的行为被称为:委托
直接表现为:将一个方法作为另一个方法的参数;

委托的声明方法

//无返回值无参数委托的定义方法
public delegate void NoReturnPara();

//无参数,无返回值方法:
public void DoNothing()
{
// 没有参数,没有返回值
}

给委托赋值的几种方式

//实例化委托,并传入方法
NoReturbNoPara noreturn = new NoReturbNoPara(this.DoNothing);

//LinqToObject
NoReturbNoPara noreturn = () => { };

//直接赋值
NoReturbNoPara noreturn = this.DoNothing;

调用委托的方法

1
noreturn.Invoke()

上面展示的是委托的基本定义与使用方法
现在实际B/S项目中基本摒弃了这种写法,转而使用封装好的泛型委托来使用;

使用方法:

//无返回值,无参数委托,不需要单独声明
Action act = this.DoNothing;
//无返回值,有参数委托,参数类型为泛型
Action act = p => { };
//返回类型为string,参数类型为string的委托
Func<string,string> func = p => p;

//返回类型为bool,参数类型为string的委托
Func<string,bool> func = p => p.Equals(‘’);

下面写几个简单的demo演示一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <summary>
/// 扩展方法
/// </summary>
public static class DelegateExtend
{
/// <summary>
/// 模仿Linq的Where操作
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="scoure">数据源</param>
/// <param name="func">委托(自定义bool条件)</param>
/// <returns></returns>
public static IEnumerable<T> ExtWhere<T>(this IEnumerable<T> scoure, Func<T, bool> func)
{
//遍历数据源的数据
foreach (var item in scoure)
{
//请求委托完成条件的筛选返回bool
bool bResult = func(item);
//把通过筛选提交的数据源,返回出去
if (bResult)
{
yield return item;
}
}
}
}

下面来调用这个方法,看一下委托的具体使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
// 实体模型
public class Student
{
/// <summary>
/// ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//查询出所有数据
IEnumerable<Student> student = sql.QueryList<Student>();
//定义一个匿名方法,并赋值给委托
Func<Student, bool> func = delegate(Student s)
{
//自定义代码逻辑,返回bool类型
return s.Id.Equals("1");
};

//传入委托
IEnumerable<Student> list = student.ExtWhere(func);

//第二种方法,使用linq语法(自定义逻辑)
IEnumerable<Student> list1 = student.ExtWhere(p => p.Id.Equals("1"));

上面就是一个简单但很常见的委托使用场景

从侧面理解一下这段代码,

1
ExtWhere 是我要做的一件事情,但这件事情里面我需要一个bool类型的返回结果,那么我委托func去帮我获取到这个bool类型的结果

委托的好处

解耦:抽出自定义逻辑,保留相同的逻辑,使代码分离。
简化代码:自定义逻辑,避免相同逻辑的代码重复。

控制反转

1:类与类的依赖

依赖是面向对象中用来描述类与类之间一种关系的概念。两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务,这样的两个对象之间主要体现为依赖关系

2:控制反转(IoC,Inverse of Control)

说反转则要先说“正转”,传统中,在程序中使用new关键字配合构造函数去创建一个对象,这就是程序主动的创建其所依赖对象,这就是“正转”。

调用者不自己创建被调用者对象,而交由第三方(容器)进行创建被调用者对象,这个过程称为控制反转(inversion of control,IOC)。

为什么要控制反转?控制反转是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度,便于扩展和后期维护。

IoC的核心思想:在需要对象实例的时候,不要总考虑自己通过 new 来创建对象,放下依赖对象的创建过程,而是把创建对象的工作交给别人来负责,这个别人我们通常称为 容器 (Container) 或者 服务提供者 (ServiceProvider)。

3:依赖注入(DI,Dependedency Injection)

实现控制反转的主要方式是依赖查找(Dependency Lookup,DL)和依赖注入(DI,Dependedency Injection,DI)。依赖注入是一种更可取的方式。

依赖注入具体是指:调用类 不主动创建依赖对象,而是使用容器来帮忙创建及注入依赖对象,这个过程就称为依赖注入(Dependency Injection,DI)

具体的说:Class A(调用类)中用到 Class B 类型的对象(依赖对象),通常情况下,我们在 Class A 中使用new关键字配合构造函数创建一个 Class B 的对象

但是,采用依赖注入技术之后, Class A只需要定义一个Class B类型的属性,不需要直接new来获得这个对象,而是通过IOC容器 将Class B类型的对象在外部new出来并注入到Class A里的引用中,从而实现Class A和Class B解耦。

控制反转容器

1:IoC容器

在说到控制反转时提到“使用IOC容器在 调用类 外部创建 依赖对象 并注入到 调用类”,其中IOC容器是什么?

IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。从而,应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装。

简而言之,IOC容器主要就两个作用:1、绑定服务与实例之间的关系;2、对实例进行创建和销毁。

2:.NET最为流行的IoC容器框架

Unity:微软patterns&practicest团队开发的IOC依赖注入框架,支持AOP横切关注点。

MEF(Managed Extensibility Framework):是一个用来扩展.NET应用程序的框架,可开发插件系统。

Spring.NET:依赖注入、面向方面编程(AOP)、数据访问抽象,、以及ASP.NET集成。

PostSharp:实现静态AOP横切关注点,使用简单,功能强大,对目标拦截的方法无需任何改动。

Autofac:最流行的依赖注入和IOC框架,轻量且高性能,对项目代码几乎无任何侵入性。

.NET 依赖注入的集中方式

1、构造器注入
通过构造器进行依赖注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyClass

{

private IMyInterFace _myinterface;

public MyClass (IMyInterFace myinterface)

{

this._myinterface = myinterface;

}

}

2、Setter注入

通过属性的访问器进行依赖注入

1
2
3
4
5
6
7
8
9
10
11
private IMyInterFace _myinterface;

public IMyInterFace myinterface

{

get { return _myinterface; }

set { _myinterface = value; }

}

3、接口注入

通过接口实现依赖注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface IMyInterFaceCace

{

IMyInterFace myinterfacce { get; set; }

}

class MyClass : IMyInterFaceCace

{

private IMyInterFace _myinterfacce;

public IMyInterFace myinterfacce

{

get { return _myinterfacce; }

set { _myinterfacce = value; }

}

}

此外,通过特性、反射+配置文件、定义注入方法也可进行依赖注入,不多赘述

TCPD、UDP协议

概念

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP(用户数据包协议)是同一层内另一个重要的传输协议。

在因特网协议族中,TCP所在层位于IP层之上、应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

UDP(User Datagram Protocol,用户数据报协议)是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。

TCP和UDP使用IP协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。

TCP和UDP的优缺点

TCP

优点:可靠、稳定。可靠体现在TCP在传输数据之前,会有三次握手来建立连接,而且在数据传输时,有确认、重传、滑动窗口、拥塞控制等机制,在数据传完后,还会断开连接用来节约系统资源。

缺点:慢,效率低,占用系统资源高,易被攻击。TCP在传递数据之前,要先建立连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制等都会消耗大量时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。由于TCP存在确认机制和三次握手机制,这些会导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。


UDP

优点:快,比TCP稍安全。UDP没有TCP的握手、确认、滑动窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如UDP Flood攻击等。

缺点:不可靠,不稳定。因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。

TCP和UDP的应用场景

TCP应用场景:
1.当对网络通讯质量有要求时,比如整个数据要准确无误的传递给对方,
2.用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。
3.在日常生活中,常见使用TCP协议的应用,比如浏览器使用HTTP,Outlook使用POP、SMTP,QQ文件传输等。

UDP应用场景:
1.面向数据报方式
2.网络数据大多为短消息
3.拥有大量Client
4.对数据安全性无特殊要求
5.网络负担非常重,但对响应速度要求高

linq、lambda、entity framework之间的关系

lambda: 一种匿名委托的精简版写法,明显的标志是=>符号

entity framework(简称EF): 微软访问数据库的最快捷最成熟的框架(ORM),在EF出现以前有SqlHelper、NHibernate等访问数据库的框架

Linq: .net 3.5以后的一种语法,使用它可以像用sql语句那样方面地查询内存、xml、数据库等,大大减少了for循环的数量和增加了可靠性

lambda与entity framework什么关系: 可以说没多大关系

lambda与linq什么关系:linq一般有两种等价写法,一是类似sql的from…where…select,一是arr.where().select(),后者就是lamda的写法,看上去更紧凑,但lambda只是linq可选的一种写法

linq与entity framework什么关系: 相辅相成的关系,linq可以查询内存、xml、数据库,用于查数据库的部分在微软的.net的实现就称为entity framework。EF在研发的时候就考虑到尽量使用linq的优势。linq是C#语法的一部分,但EF不是。

“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型。

LINQ是语言集成查询,它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。所以,Lambda 是实现LINQ查询的方式。

Linq是在.NET Framework 3.5 中出现的技术,所以在创建新项目的时候必须要选3.5或者更高版 本,否则无法使用。选择3.5或更高版本的.NET Framework之后,创建类文件中会自动包含System.Linq 的命名空间。

EF(Entity Framework)是什么?

实体框架EF是http://ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架。

主要有三种方式:

Database FirstDatabase First”模式

我们称之为“数据库优先”,前提是你的应用已经有相应的数据库,你可以使用EF设计工具根据数据库生成数据数据类,你可以使用Visual Studio模型设计器修改这些模型之间对应关系。

Model FirstModel First我们称之为“模型优先”,这里的模型指的是“ADO.NET Entity Framework Data Model”,此时你的应用并没有设计相关数据库,在Visual Studio中我们通过设计对于的数据模型来生成数据库和数据类。

Code FirstCode First模式我们称之为“代码优先”模式,是从EF4.1开始新建加入的功能。

使用Code First模式进行EF开发时开发人员只需要编写对应的数据类(其实就是领域模型的实现过程),然后自动生成数据库。这样设计的好处在于我们可以针对概念模型进行所有数据操作而不必关心数据的存储关系,使我们可以更加自然的采用面向对象的方式进行面向数据的应用程序开发。

什么是ORM?

ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的互相转换。

(表实体跟表之间的相互转换)

ORM框架有很多,EF框架是ORM框架的其中一种,是实现了ORM思想的框架。

O=>表实体

M=>映射关系

R=>数据库.表

—>详解

为什么用EF而不用原生的ADO.NET?

1).极大的提高开发效率:EF是微软自己的产品,开发中代码都是强类型的,

xiefl代码效率非常高,自动化程度非常高,命令式的编程.

2).EF提供的模型设计器非常强大,不仅仅带来了设计数据库的革命,也附带来的自动化模型代码的

功能也极大的提高开发和架构设计的效率.

3).EF跨数据支持的是ORM框架主要功能点之一,带来的是可以通过仅仅改变配置就可以做到跨数据库的能力

如何提高LINQ性能问题?

提升从数据库中拿数据的速度,可以参考以下几种方法:

1).在数据库中的表中定义合适的索引和键

2).只获得你需要的列(使用ViewModel或者改进查询)和行(使用IQueryable)

3).尽可能使用一条查询而不是多条

4).只为了展示数据,而不进行后续修改时,可以使用AsNoTracking。它不会影响生成的SQL,但它可以令系统少维护很多数据,从而提高性能

5).使用Reshaper等工具,它可能会在你写出较差的代码时给出提醒

什么是IEnumerable?

IEnumerable及IEnumerable的泛型版本IEnumerable是一个接口,它只含有一个方法GetEnumerator。Enumerable这个静态类型含有很多扩展方法,其扩展的目标是IEnumerable。

实现了这个接口的类可以使用Foreach关键字进行迭代(迭代的意思是对于一个集合,可以逐一取出元素并遍历之)。实现这个接口必须实现方法GetEnumerator。

IEnumerable的缺点有哪些?

IEnumerable功能有限,不能插入和删除。

访问IEnumerable只能通过迭代,不能使用索引器。迭代显然是非线程安全的,每次IEnumerable都会生成新的IEnumerator,从而形成多个互相不影响的迭代过程。

在迭代时,只能前进不能后退。新的迭代不会记得之前迭代后值的任何变化。

延迟执行 (Lazy Loading)是什么?

大部分LINQ语句是在最终结果的第一个元素被访问的时候(即在foreach中调用MoveNext方法)才真正开始运算的,这个特点称为延迟执行。一般来说,返回另外一个序列(通常为IEnumerable或IQueryable)的操作,使用延迟执行,而返回单一值的运算,使用立即执行。

IEnumerable是延迟执行的,当没有触发执行时,就不会进行任何运算。Select方法不会触发LINQ的执行。一些触发的方式是:foreach循环,ToList,ToArray,ToDictionary方法等

LINQ可视化工具简单介绍一下?

LINQPad工具是一个很好的LINQ查询可视化工具。它由Threading in C#和C# in a Nutshell的作者Albahari编写,完全免费。它的下载地址是http://www.linqpad.net/

进入界面后,LINQPad可以连接到已经存在的数据库(不过就仅限微软的SQL Server系,如果要连接到其他类型的数据库则需要安装插件)。某种程度上可以代替SQL Management Studio,是使用SQL Management Studio作为数据库管理软件的码农的强力工具,可以用于调试和性能优化(通过改善编译后的SQL规模)。

LINQPad支持使用SQL或C#语句(点标记或查询表达式)进行查询。你也可以通过点击橙色圈内的各种不同格式,看到查询表达式的各种不同表达方式:

Lambda:查询表达式的Lambda表达式版本,

SQL:由编译器转化成的SQL,通常这是我们最关心的部分,

IL:IL语言

LINQ to Object和LINQ to SQL有何区别?

LINQ to SQL可以将查询表达式转换为SQL语句,然后在数据库中执行。相比LINQ to Object,则是将查询表达式直接转化为Enumerable的一系列方法,最终在C#内部执行。LINQ to Object的数据源总是实现IEnumerable(所以不如叫做LINQ to IEnumerable),相对的,LINQ to SQL的数据源总是实现IQueryable并使用Queryable的扩展方法。

将查询表达式转换为SQL语句并不保证一定可以成功。

除了EF,列举出你知道的ORM框架?

dapper EntityFramework、 EJB、Hibernate、IBATIS、SqlSugar 、freesql

在哪些类型额项目中你会选择EF? 为什么?

这个要结合EF的特点来说:EF主要是以面向对象的思想来做数据库数据操作,对Sql语句能力没什么要求,开发使用效率高!便于上手,一般来说,使用EF框架,肯定会比直接使用ADO.NET,消耗的时间多一些。所以在一般企业级开发,管理型系统,对数据性能要求不是特别高的情况下,优先选择EF,这样可以大大的推进开发效率!如果像一些互联网项目中,对性能要求精度很高!可以另外做技术选型,选择原生ADO.NET。

请说明EF中映射实体对象的几种状态?

Detached:该实体未由上下文跟踪。刚使用新运算符或某个 System.Data.Entity.DbSet Create 方法创建实体后,实体就处于此状态。

Unchanged:实体将由上下文跟踪并存在于数据库中,其属性值与数据库中的值相同。

Added:实体将由上下文跟踪,但是在数据库中还不存在。

Deleted:实体将由上下文跟踪并存在于数据库中,但是已被标记为在下次调用 SaveChanges 时从数据库中删除。

Modified:实体将由上下文跟踪并存在于数据库中,已修改其中的一些或所有属性值。

2023-02-03

浏览 |

© 2023 南疆 with help from Hexo and Twitter Bootstrap. Theme by Freemind.

container-narrow -->