您好,欢迎访问三七文档
一、接口与抽象类抽象类:1)抽象类是一种不能直接实例化而必须从中继承的类,抽象类实例由它的子类给出,抽象类可以提供实现,也可以不提供实现,2)抽象类可以定义非静态的类变量,抽象类成员可以是私有的,受保护的,公有的3)抽象类是单继承(子类只能继承一个抽象类);4)抽象类主要用于关系密切的对象,若设计大的功能单元,则使用抽象类;抽象类用于共性;5)在抽象类中加入一个方法,那么它的子类就同时有了这种方法;接口:1)接口不提供任何实现,接口的实例是实现接口的类给出的2)接口成员不能包含常数,字段,运算符,实例构造函数,析构函数,静态成员等,只能是方法,属性,事件,或索引器,且其成员都是共有的3)多继承,多态性,类或结构可以继承多个接口;4)适合于为不相关的类提供通用功能;接口用于规范5)在接口中加入方法,那实现它的类就必须重新编写;二、装箱和拆箱装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作。1.装箱在值类型向引用类型转换时发生:objectobj=1;2.拆箱在引用类型向值类型转换时发生装箱操作和拆箱操作是要额外耗费cpu和内存资源的,所以在c#2.0之后引入了泛型来减少装箱操作和拆箱操作消耗。三、return,break,continue1、return语句的作用从当前的方法中退出,返回到该调用的方法的语句处,继续执行。2、break语句的作用用在循环体内和switch语句体内;用在循环体内表示跳出本层循环体,从而提前结束本层循环;用在switch中表示跳出跳出switch语句体。3、continue语句作用其作用是结束本次循环,即跳过本次循环体中余下尚未执行的语句,接着再一次进行循环的条件判定。四、用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系目前.Net平台下的B/S开发框架基本可以分为三大类:基于控件和页面事件驱动思想的WebForms;基于模型、视图、控制器的MVC模式;综合了WebForms和MVC的一些特点而产生的框架;表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)表现层负责与用户交互;业务逻辑层就是指派数据访问层进行表现层请求的逻辑性的业务处理,数据访问层对数据库进行增删查改。优点:分工明确,条理清晰,易于调试,而且具有可扩展性。缺点:增加成本。五、简述数据库连接池连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等连接池为每个唯一的连接字符串创建;连接池一旦创建,直到活动进程终止时才会被毁坏六、C#(Winform)利用委托跨线程界面交互问题窗体上的控件只允许创建它们的线程访问,也就是主线程,若非主线程访问则会发生异常,可借助于控件的InvokeRequired属性判断该控件目前是否被主线程访问,如果是则返回false;在利用Invoke方法找到主线程(在哪个控件上调用了Invoke,就用那个控件所在的线程处理委托方法,Invoke的两个参数分别是:委托、委托的方法需要的参数),让主线程访问控件的方法。(1)创建一个类,类里声明委托及委托对象,在类的方法中调用委托对象classTestClass{//声明一个delegate(委托):testDelegate,该类型可以搭载返回值为空,参数只有一个(long型)的方法。publicdelegatevoidtestDelegate(longi);//声明一个testDelegate类型的对象。它可以搭载N个方法。publictestDelegatemainThread;publicvoidtestFunction(){longi=0;while(true){i++;mainThread(i);//调用委托对象Thread.Sleep(1000);//线程等待1000毫秒}}}(2)在UI控件的事件中创建TestClass类并为委托搭载方法,创建无参线程privatevoidbutton1_Click(objectsender,EventArgse){//创建TestClass类的对象TestClasstestclass=newTestClass();//在testclass对象的mainThread(委托)对象上搭载两个方法,在线程中调用mainThread对象时相当于调用了这两个方法。testclass.mainThread=newTestClass.testDelegate(refreshLabMessage1);testclass.mainThread+=newTestClass.testDelegate(refreshLabMessage2);//创建一个无参数的线程,这个线程执行TestClass类中的testFunction方法。ThreadtestclassThread=newThread(newThreadStart(testclass.testFunction));//启动线程,启动之后线程才开始执行testclassThread.Start();}(3)在搭载的方法中判断该方法是否被主线程调用,若非主线程调用则再创建TestClass并为委托对象搭载方法,///在界面上更新线程执行次数privatevoidrefreshLabMessage1(longi){//判断该方法是否被主线程调用,也就是创建labMessage1控件的线程,当控件的InvokeRequired属性为ture时,说明是被主线程以外的线程调用。如果不加判断,会造成异常if(this.labMessage1.InvokeRequired){//再次创建一个TestClass类的对象TestClasstestclass=newTestClass();//为新对象的mainThread对象搭载方法testclass.mainThread=newTestClass.testDelegate(refreshLabMessage1);//this指窗体,在这调用窗体的Invoke方法,也就是用窗体的创建线程来执行mainThread对象委托的方法,再加上需要的参数(i)this.Invoke(testclass.mainThread,newobject[]{i});}else{labMessage1.Text=i.ToString();}}七、C#动态链接库(DynamicLinkLibrary)使用方法Dll不能直接执行,需要根据进程的需要按需载入,DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程使用,而调用进程的句柄也可以被该Dll使用。非托管代码主要是基于win32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。1、生成动态链接库(以类库为例)新建一个类库(DllTest)-解决方案(右击属性)-配置程序集名称(DllTest),默认命名空间(DllTest),输出类型(类库)-菜单栏“生成”选项-选择生成“DllTest”-在解决方案目录下的\DllTest\DllTest\bin\Debug文件夹下生成DllTest.dll2、C#调用DLL中的非托管函数(这是个全局函数)(1)准备1)在项目解决方案下的“引用”文件夹下“添加引用”,将待引用的动态链接库引用到项目解决方案。2)在需要引用动态库的.cs文件中添加引用(usingSystem.Runtime.InteropServices;)3)待调用的Dll文件必须位于程序当前目录或系统定义的查询路径中(2)调用DLL中的函数或方法1)调用DLL中的非托管函数首先,在C#语言源程序中声明外部方法,其基本形式是:[DLLImport(“DLL文件”)]修饰符extern返回变量类型方法名称(参数列表)示例:[DllImport(kernel32.dll,EntryPoint=GetProcAddress,CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall,ExactSpelling=false))]privateexternstaticIntPtrGetAddress(IntPtrlib,stringfuncName);注:DLLImport第一个参数为DLL文件路径;第二个参数为待调用的DLL函数名;第三个参数为用在入口点中的字符集;第四个参数指示入口点的调用约束;第五个参数指示EntryPoint是否必须与指示的入口点的拼音完全匹配。在方法的声明中若需要使用其他方法名称,需要在DLLImport中设置EntryPoint参数,上例中的GetAddress就是对GetProcAddress方法的更名。3、C#动态装载、调用DLL中的非托管函数用DllImport调用DLL中的非托管函数,但是这个是全局的函数,假若DLL中的非托管函数有一个静态变量S,每次调用这个函数的时候,静态变量S就自动加1。结果,当需要重新计数时,就不能得出想要的结果。因为C#中使用DllImport是不能像动态load/unloadassembly那样,所以只能借助API函数了。在kernel32.dll中,与动态库调用有关的函数包括[3]:①LoadLibrary(或MFC的AfxLoadLibrary),装载动态库。②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。(1)建一个类库usingSystem.Runtime.InteropServices;//用DllImport需用此命名空间usingSystem.Reflection;//使用IAssembly需要此命名空间usingSystem.Reflection.Emit;//使用ILGenerator需要此命名空间classDllInvoke{//声明LoadLibrary,参数path为DLL文件全路径,该函数返回函数库模块的句柄[DllImport(kernel32.dll)]privateexternstaticIntPtrLoadLibrary(stringpath);//声明GetProcAddress,参数lib为包含需调用函数的函数库模块的句柄;funcName为调用函数的名称,该函数返回函数句柄[DllImport(kernel32.dll)]privateexternstaticIntPtrGetProcAddress(IntPtrlib,stringfuncName);//声明FreeLibrary,参数lib为需释放的函数库模块的句柄,该函数返回是否已释放指定的Dll[DllImport(kernel32.dll)]privateexternstaticboolFreeLibrary(IntPtrlib);privateIntPtrhLib;//存储函数库模块的句柄publicDllInvoke(StringDLLPath)//构造函数,获取函数库模块句柄{hLib=LoadLibrary(DLLPath);//若函数库模块的句柄为空,则抛出异常if(hLib==IntPtr.Zero){throw(newException(没有找到:+DLLPath));}}~DllInvoke()//析构函数,释放动态链接库{FreeLibrary(hLib);hLib=IntPtr.Zero;}//取
本文标题:C#面试题精选
链接地址:https://www.777doc.com/doc-4702280 .html