.net下的初、中、高级问题

以下是转贴:作者:观海看云

 

描述线程与进程的区别?

线程是比进程更小的处理模块。
进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于:

简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

 

线程的引入:例如,有一个Web服务器要进程的方式并发地处理来自不同用户的网页访问请求的话,可以创建父进程和多个子进程的方式来进行处理,但是创建一个进程要花费较大的系统开销和占用较多的资源。除外,这些不同的用户子进程在执行的时候涉及到进程上下文切换,上下文切换是一个复杂的过程。所以,为了减少进程切换和创建的开销,提高执行效率和节省资源,人们在操作系统中引入了"线程(thread"的概念。

 进程的作用和定义:进程是为了提高CPU的执行效率,减少因为程序等待带来的CPU空转以及其他计算机软硬件资源的浪费而提出来的。进程是为了完成用户任务所需要的程序的一次执行过程和为其分配资源的一个基本单位,是一个具有独立功能的程序段对某个数据集的一次执行活动。

 

线程和进程的区别:

      1、线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程。

      2、一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个进程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。

      3、系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。那就是说,出了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。

      4、与进程的控制表PCB相似,线程也有自己的控制表TCB,但是TCB中所保存的线程状态比PCB表中少多了。

      5、进程是系统所有资源分配时候的一个基本单位,拥有一个完整的虚拟空间地址,并不依赖线程而独立存在。

          进程与程序的区别:

      程序是一组指令的集合,它是静态的实体,没有执行的含义。而进程是一个动态的实体,有自己的生命周期。一般说来,一个进程肯定与一个程序相对应,并且只有一个,但是一个程序可以有多个进程,或者一个进程都没有。除此之外,进程还有并发性和交往性。简单地说,进程是程序的一部分,程序运行的时候会产生进程。

 

总结:

      线程是进程的一部分,进程是程序的一部分。

 

 

什么是Windows服务,它的生命周期与标准的EXE程序有什么不同

 

Windows Service 是主要用于服务器环境而长期运行的应用程序, 这类程序不需要有用户界面或者任何模拟输出。 任何的用户消息通常都是记录在Windows 事件日志里。Windows Service可以在操作系统启动的时候开始,一直在后台运行,当有需要时也可以手动启动,我们可以通过管理工具里面的服务进行统一管理。

当系统启动完毕后,Windows服务并不需要通过登陆页面后才能启动,而我们启动一般的exe文件却要先登陆Windows后才能启动它。

 

Windows Service 是一种可随 Windows 操作系统启动而启动的,在后台运行的,通常不和用户产生交互的程序。它无法通过双击来运行,类似于 Unix 守护进程(daemon processes),当用户注销时它也不会停止。

Windows 服务由三部分组成:1.一个服务可执行文件;2.一个服务控制程序(SCP);3.服务控制管理器(SCM),负责在 HKLM/SYSTEM/CurrentControlSet/Services 下创建服务键值。用户可通过 SCP 控制服务的启动、停止、暂停等,SCP 会通过 SCM 调用服务程序。

Window 标准的exe可执行程序通常有一个用户界面,Console或GUI,通常由用户来启动或停止

 

Windows服务是运行在windows后台指定用户下(默认System)的应用程序,它没有标准的UI界面,想比标准的EXE程序,Windows服务是在服务开始的时候创建,而在服务结束的时候销毁,而且可以设置服务是否与操作系统一起启动,一起关闭。它支持三种方式:1)自动方式 2)手动方式 3)禁用 。自动方式的时候,windows服务将在OS启动后自动启动运行,而手动方式则必须手工启动服务,禁用的情况下服务将不能被启动。另外标准的EXE默认使用的当前登录的用户,而windows服务则默认使用System用户,这在对系统资源访问的时候特别需要注意。

 

 

Windows上的单个进程所能访问的最大内存量是多少?它与系统的最大虚拟内存一样吗?这对于系统设计有什么影响?

 

32 Windows上单个进程所能访问的最大内存量是4G,单由于操作系统需要给系统核心分配2G的空间,所以一般用户程序的进程可使用的最大内存为2G

不一定一样,32位的操作系统的进程可访问的最大内存量是4G,这4G包含了虚拟内存,而一个进程可访问的最大内存量也是4G,所以进程内存访问量在物理内存大于等于4G的时候跟虚拟内存无关,而当物理内存小于4G时,进程访问的内存量随着虚拟内存的增加而增加,直到4G

 

Windows使用一个系统:虚拟寻址系统。该系统把程序可用的内存地址映射到硬件内存中的实际地址上,这些任务完全有Windows后台管理,其实际结 果是32位处理器上的每个进程都可以使用4GB的内存------无论计算机上有多少硬盘空间(在64位处理器上这个数值会更大)。这个4GB内存实际上 包含了程序的所有部分------包括可执行代码,代码加载的所有dll,以及程序运行时使用的所有变量的内容。这个4GB内存称为虚拟地址空间,或虚拟 内存。

 

EXE和DLL之间的区别是什么?

EXE就是可执行文件,你可要双击它, 它就可以运行,而DLL是一个动态链接库文件,就是说,它不可以自己运行,它是须要一个程序的其它功能运行的时候,它才能运行,打个比方,如果你的QQ要升级,那QQ里面有关升级的DLL文件它就会运行.

 

EXE是带有程序入口(Main)的能被终端用户直接执行的应用程序,随着它的启动系统会产生一个相应的进程。

DLL是动态链接库,不包含程序执行入口,不能被终端用户直接执行,本身需要附加到现有的进程中才可以运行。

但两者都是基于PE格式,运行时由磁盘中的映像载入被调用者的内存或者共享空间中执行,包含程序的数据信息,只是EXE还包括程序的代码信息。

DLL可被多个程序共用,而EXE则不行,只能单独执行。

 

什么是强类型,什么是弱类型?哪种更好些?为什么?

 

弱类型语言允许将一块内存看做多种类型。比如直接将整型变量与字符变量相加。C and C++ 是静态语言,也是弱类型语言;Perl and PHP 是动态语言,但也是弱类型语言。

强类型语言在没有强制类型转化前,不允许两种不同类型的变量相互操作。Java、C# 和 Python 等都是强类型语言。

使用哪种语言还是要按需而定。编写简单小应用,使用弱类型语言可节省很多代码量,有更高的开发效率。而对于构建大型项目,使用强类型语言可能会比使用弱类型更加规范可靠。

 

强类型是指使用内存中的数据时必须做类型转化,否则不能使用,弱类型不需要程序转化,运行时系统自动处理数据直接的类型。

使用强类型的好处:支持智能输入提示、编译时检测出潜在的运行问题、接口中避免数据不一致问题,并且使用强类型可以加快程序的开发速率和程序的运行速度。

 

PID是什么?在做系统的故障排除时如何使用它?

PID是系统进程的全局唯一标志符,在排除系统故障时可以根据PID找到对应的进程进而找到对应的程序。

PID = Process Identifier, 是一个全局唯一的用来标识进程的整数。在多任务系统中,可用来诊断系统中发生错误的进程。

 

单个TCP/IP端口上能够侦听多少个进程?

可能只有一个。如果你需要创建另一个TCP/IP监听,你必须建立另一个不同的端口

 

什么是GAC?它解决了什么问题?

Gloal Assembly Cache,全局应用程序集缓存。它解决了几个程序共享某一个程序集的问题。不必再将那个被共享的程序集拷贝到应用程序目录了,其实这道理很简单,.net应用程序在加载的时候,会首先查看全局应用程序集缓存,如果有就可以直接使用,没有再到应用程序目录进行查找。

 

 

每一个CLR(Common Language Runtime)所在的计算机都有一个全局程序集缓存(Global Assembly Cache,GAC)。部署在GAC上的程序集必须有一个强名称。一种由.net framework sdk提供的名叫 "Global Assembly Cache tool" (Gacutil.exe)的开发工具,可以把程序集部署到GAC上。GAC存储专门指定的程序集以供计算机上多个应用程序共享。它也为我们提供了克服"DLL地狱"的问题。

百度百科上的解释:

GAC全称是Global Assembly Cache
作用是可以存放一些有很多程序都要用 到的公共Assembly,例如System.Data、System.Windows.Forms等等。这样,很多程序就可以从GAC里面取得 Assembly,而不需要再把所有要用到的Assembly都拷贝到应用程序的执行目录下面。举例而言,如果没有GAC,那么势必每个WinForm程 序的目录下就都要从C:/WINDOWS/Microsoft.NET/Framework/v1.0.3705下面拷贝一份 System.Windows.Forms.dll,这样显然不如都从GAC里面取用方便,也有利于Assembly的升级和版本控制。

   除了系统默认放置在GAC中的Assembly如System.Windows.Forms以外,我们也可以添加自己的Assembly:
   1)创建一个strong-name的Assembly,例如ToolbarComponent.dll
   2)运行gacutil -i ToolbarComponent.dll,把这个Assembly添加到GAC
   3)在程序中动态装载:
   System.Reflection.Assembly ass=Assembly.Load("ToolbarComponent, Version=1.0.934.20434, Culture=neutral, PublicKeyToken=65f45658c8d4927f");
   MessageBox.Show("Is the assembly loaded from GAC? "+ass.GlobalAssemblyCache);
   在 上面的程序中,ToolbarComponent就是从GAC装载而不是从程序的运行目录下的dll文件中装载,程序目录下不需要放置 ToolbarComponent.dll程序也能正常运行。另外,Assembly.Load()中的参数可以通过"gacutil -l"查到。

   另外,上面提到了GAC中的Assembly必须是strong-name的。创建strong-name的Assembly的步骤大致如下:
   a) 在命令行运行“sn -k keyPair.snk”创建一个密钥文件。这里的sn.exe也是.NET附带的一个工具。
   b) 在VS.NET里面修改“AssemblyInfo.cs”文件:
   [assembly: AssemblyDelaySign(false)]    
   [assembly: AssemblyKeyFile("..//..//keyPair.snk")]    
   c) 编译项目,就能得到一个strong-name的Assembly。

   MSDN中有一些对GAC的介绍,您可以参考:
   1)《Assembly Cache Viewer (Shfusion.dll)》
   2)《Global Assembly Cache》

   .NET Framework中附带了一些和GAC有关的工具,其中包括:
   1)Gacutil.exe,一个命令行的工具,用于在GAC中浏览、添加、删除Assembly
   2)Ngen.exe,也是一个命令行的工具,用于在GAC中创建Native Image
   3)mscorcfg.msc,一个MMC终端,可以图形化完成Gacutil.exe的主要功能。

 

 

 

  • 阐述面向接口、面向对象、面向方面编程的区别
        面向接口更关注的是概念,它的原则是先定义好行为规范,再根据行为规范创建实现,严格的来说,面向接口应该是面向对象中的一部分吧,因为面向对象也强调的是本末倒

    置原则,也就是实现依赖于抽象,而抽象不依赖于具体实现,更具比较的应该是面向接口与面向抽象对象,我的体会是面向接口更加灵活,但实现时候,稍微有些代码冗余,而面

    向抽象可以结合面向接口,先定义接口,再定义抽象类,在抽象类中处理一些公共逻辑,再实现具体实现类。面向对象是对复杂问题的分解。面向方面的编程是一种新概念,它解

    决了很多面向对象无法解决的问题,比如面向对象技术只能对业务相关的代码模块化,而无法对和业务无关的代码模块化。而面向方面正是解决这一问题的方案,它的关键思想是"

    将应用程序中的商业逻辑与对其提供支持的通用服务进行分离"。

    什么是Interface?它与Class有什么区别?
        接口(Interface)是用来定义行为规范的,不会有具体实现,而抽象类除定义行为规范外,可以有部分实现,但一个类能实现多个接口,但只能继承一个父类 
    接口是是一种契约,定义了继承它的类必须声明接口中的方法。
    接口和类的区别:
    接口只有方法、属性、事件和索引符,并且也只能包含这四种成员;类除了这四种成员之外还可以别的成员(如字段)。
    接口不能实例化,接口只包括成员的签名;而类可以实例化(abstract类除外)。
    接口没有构造函数,类有构造函数。
    接口不能进行运算符的重载,类可以进行运算符重载。
    接口的成员没有任何修饰符,其成员总是公共的,而类的成员则可以有修饰符
    派生于接口的类必须实现接口中所有成员的执行方式,而从类派生的则不然。

    什么是反射?
        程序集包含模块,而模块又包括类型,类型下有成员,反射就是管理程序集,模块,类型的对象,它能够动态的创建类型的实例,设置现有对象的类型或者获取现有对象的类

    型,能调用类型的方法和访问类型的字段属性。它是在运行时创建和使用类型实例

    关于什么事反射,我找了好些资料,有些人说了好多。比如:http://blog.csdn.net/shuilv2000/archive/2009/10/26/4728991.aspx,说了好多,不过个人还是觉得上面的概括更

    好理解。
               

    使用ASMX的XML Web服务与使用SOAP的.NET Remoting的区别?
        Web 服务基础结构通过将 SOAP 消息映射到方法调用,为 Web 服务提供了简单的 API。通过提供一种非常简单的编程模型(基于将 SOAP 消息交换映射到方法调用),它实现

    了此机制。ASP.NET Web 服务的客户端不需要了解用于创建它们的平台、对象模型或编程语言。而服务也不需要了解向它们发送消息的客户端。唯一的要求是:双方都要认可正在

    创建和使用的 SOAP 消息的格式,该格式是由使用 WSDL 和 XML 架构 (XSD) 表示的 Web 服务合约定义来定义的。 
        . NET Remoting 为分布式对象提供了一个基础结构。它使用既灵活又可扩展的管线向远程进程提供 .NET 的完全对象语义。ASP.NET Web 服务基于消息传递提供非常简单的编

    程模型,而 .NET Remoting 提供较为复杂的功能,包括支持通过值或引用传递对象、回调,以及多对象激活和生命周期管理策略等。要使用 .NET Remoting,客户端需要了解所有

    这些详细信息,简而言之,需要使用 .NET 建立客户端。.NET Remoting 管线还支持 SOAP 消息,但必须注意这并没有改变其对客户端的要求。如果 Remoting 端点提供 .NET 专

    用的对象语义,不管是否通过 SOAP,客户端必须理解它们。

    Web服务客户端不需要了解服务创建的平台、对象模型和编程语言,而.NET Remoting需要了解这些信息,而且客户端需要用.NET Framework开发
    Web 服务通过XML传递消息,.NET Remoting可以通过值或引用传递对象、回调,以及多对象激活和生命周期管理策略等
    Web服务使用的消息机制,而Remoting采用的RPC. Web Service能用于不同平台,不同语言,Remoting只适用于.Net。效率上Remoting高于Xml Web Service

    类型系统是由XMLSchema表示的吗?CLS是XMLSchema表示的吗?
        这个不清楚,在网上找了哈,也没看到对这方面的介绍。希望高手指点。

    从概念上阐述前期绑定(early-binding)和后期绑定(late-binding)的区别?
        前期绑定是指在编译时就绑定了变量的类型或者方法的实体,而后期绑定是在运行时根据不同的需要绑定不同的类型或者方法实体。所以前期绑定如果失败,会在编译时报编

    译错误,而后期绑定失败只有在运行时的时候才发生

    调用Assembly.Load算静态引用还是动态引用?
        动态
        关于Assembly.Load这位老兄讲得比较基础:http://hi.baidu.com/zhanghaooy/blog/item/b12aba0e62313cc07bcbe1b2.html

    Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的区别!
         1.Assembly.Load()
             这个方法通过程序集的长名称(包括程序集名,版本信息,语言文化,公钥标记)来加载程序集的,会加载此程序集引用的其他程序集,一般情况下都应该优先使用 这

    个方法,他的执行效率比LoadFrom要高很多,而且不会造成重复加载的问题(原因在第2点上说明)
             使用这个方法的时候, CLR会应用一定的策略来查找程序集,实际上CLR按如下的顺序来定位程序集:
    ⑴如果程序集有强名称,在首先在全局程序集缓(GAC)中查找程序集。         
    ⑵如果程序集的强名称没有正确指定或GAC中找不到,那么通过配置文件中的<codebase>元素指定的URL来查找
    ⑶如果没有指定强名称或是在GAC中找不到,CLR会探测特定的文件夹:
         假设你的应用程序目录是C:/AppDir,<probing>元素中的privatePath指定了一个路径Path1,你要定位的程序集是AssemblyName.dll则CLR将按照如下顺序定位程序集
              C:/AppDir/AssemblyName.dll
              C:/AppDir/AssemblyName/AssemblyName.dll
              C:/AppDir/Path1/AssemblyName.dll
              C:/AppDir/Path1/AssemblyName/AssemblyName.dll
    如果以上方法不能找到程序集,会发生编译错误,如果是动态加载程序集,会在运行时抛出异常!
         2,Assembly.LoadFrom()
              这个方法从指定的路径来加载程序集,实际上这个方法被调用的时候,CLR会打开这个文件,获取其中的程序集版本,语言文化,公钥标记等信息,把他们传递给 Load

    方法,接着,Load方法采用上面的策略来查找程序集。如果找到了程序集,会和LoadFrom方法中指定的路径做比较,如果路径相同,该程序集 会被认为是应用程序的一部分,如果

    路径不同或Load方法没有找到程序集,那该程序集只是被作为一个“数据文件”来加载,不会被认为是应用程序的一部分。 这就是在第1点中提到的Load方法比LoadFrom方法的执

    行效率高的原因。另外,由于可能把程序集作为“数据文件”来加载,所以使用 LoadFrom从不同路径加载相同程序集的时候会导致重复加载。当然这个方法会加载此程序集引用的

    其他程序集。
         3,Assembly.LoadFile()
              这个方法是从指定的文件来加载程序集,和上面方法的不同之处是这个方法不会加载此程序集引用的其他程序集!
         结论:一般大家应该优先选择Load方法来加载程序集,如果遇到需要使用LoadFrom方法的时候,最好改变设计而用Load方法来代替!

    Assembly.LoadFile 与 Assembly.LoadFrom的区别
    1、Assembly.LoadFile只载入相应的dll文件,比如Assembly.LoadFile("abc.dll"),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。
    Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,def.dll也会被载入。
    2、用Assembly.LoadFrom载入一个Assembly时,会先检查前面是否已经载入过相同名字的Assembly,比如abc.dll有两个版本(版本1在目录1下,版本2放在目录2下),程序一开始时

    载入了版本1,当使用Assembly.LoadFrom("2//abc.dll")载入版本2时,不能载入,而是返回版本1。Assembly.LoadFile的话则不会做这样的检查,比如上面的例子换成

    Assembly.LoadFile的话,则能正确载入版本2。
     

    何时使用Assembly.LoadFrom?何时使用Assembly.LoadFile?
        呵呵,这个比较有意思,相比LoadFile,LoadFrom则显得不地道,因为它娶媳妇的时候,是让人家穿上嫁妆,坐上马车,还得带着人家的妹妹来,用它加载的是程序集,这就要

    求同时将此程序集所依赖的程序集加载进来。而LoadFile就地道的多,它是加载程序集文件的内容,只将传入参数的文件加载,不考虑程序集依赖,但如果有相同实现,但位置不

    同的文件用LoadFrom是不能同时加载进来的,而LoadFile却可以。由于LoadFile加载的是文件,所以调用它之后,可能因为缺少必要的依赖造成无法被执行。

    什么叫Assembly Qualified Name?它是一个文件名吗?它有什么不同?
        它不是一个文件名,相比文件名,Assembly Qualified Name(程序集限定名称),更能确定一个程序集,它包含文件名,但同时包含版本,公钥,和区域。因为同样一个名称

    的文件可能有不同的版本和区域,此时单独靠文件名称,可能会造成不能确定程序集的正确性。

    Assembly.Load("foo.dll"); 这句话是否正确?
    正确

    做强签名的assembly与不做强签名的assembly有什么不同?
    强签名的程序集可以做成com,而不做强签名的就不行,同样强签名程序集可以安装到GAC中,而不做强签名的确不能。

    DateTime是否可以为null?
    不能,因为其为Struct类型,而结构属于值类型,值类型不能为null,只有引用类型才能被赋值null

    什么叫JIT?什么是NGEN?它们分别有什么限制和好处?
    Just In Time 及时编译,它是在程序第一次运行的时候才进行编译,而NGEN是所谓的pre-jit,就是说在运行前事先就将生成程序集的本机镜像,并保存到全局缓存中,适用NGEN

    可以提高程序集的加载和执行速度,因为它可以从本机映像中还原数代码和数据结构,而不必像jit那样动态生成它们。感觉和缓存的道理大同小异,也就是传说中的预编译。

    .NET CLR中一代的垃圾收集器是如何管理对象的生命周期的?什么叫非确定性终结?

     
    Finalize()和Dispose()之间的区别?
    Finalize()用于释放非托管资源,Dispose()用于释放托管资源

    using() 语法有用吗?什么是IDisposable?它是如何实现确定性终结的。
    有用,实现了IDisposiable的类在using中创建,using结束后会自定调用该对象的Dispose方法,释放资源。简单的说调用IDisposable的Dispose方法能移除这个对象所使用资源的

    引用,从而达到让垃圾收集器回收资源的目的。
     
    tasklist /m "mscor*" 这句命令是干嘛的?
    列出所有使用了以" mscor"作为开头的dll或者exe的进程和模块信息

    in-proc和out-of-proc的区别
    in-proc是进程内,进程内能共享代码和数据块,out-of-proc是进程外,进程外的互操作需要用进程间通讯来实现。

    .NET里的哪一项技术能够实现out-of-proc通讯?
    .Net Remoting技术或者WCF技术

    当你在ASP.NET中运行一个组件时,它在Windows XP, Windows 2000, Windows 2003上分别跑在哪个进程里面?
    Xp : aspnet_Wp.exe
    Windows 2000 : inetinfo.exe
    Windows 2003 : w3wp.exe  

     观海看云:http://www.cnblogs

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章