1、第一章1. 简述什么是 C/S 模式,什么是 B/S 模式,C/S 和 B/S 的优缺点。答:胖客户端应用程序编程架构,其主要工作都在客户端运行,这样可以充分利用本地计算机的性能优势。在分布式的基础上进一步抽象出来的编程模型,缺点是需要在本机安装客户端软件。C/S 将一个网络事务处理分为两部分:客户端(Client,也叫客户机)用于为用户提供操作,同时向网络提供请求服务的接口;服务端(Server)负责接收并处理客户端发出的服务请求,并将服务处理结果返回给客户端。B/S 模式是在分布式系统基础上抽象出来的网络通信模型;B/S 只使用 HTTP 进行通信。优点是单台计算机可以访问任何 Web 服
2、务器,缺点是 B/S 模式有沙盒限制。2. C/S 客户端一般用 WPF,服务端用 WCF 实现。企业内部网用 https 来访问3. TCP/IP 网络模型有四层:应用层,传输层,网际层,网络接口层4. 什么是套接字?套接字有哪几种类型? 答:套接字是支持 TCP/IP 网络通信的基本操作单元,是不同主机间的进程进行通信的端点。在一个套接字实例中,既保存了本机的 IP 地址和端口,也保存了对方的 IP 地址和端口,同时也保存了双方通信采用的网络协议等信息。套接字有 3 种类型:流式套接字( TCP) 、数据报套接字(UDP)和原始套接字(IP) 。5. IP 地址转换与域名解析相关的类都在
3、System.Net 命名空间下。IP:在因特网中,每台联网的主机都要有一个在全世界范围内唯一的标识,该标识称为IP 地址。多播地址在:224.0.0.0239.255.255.255 之间。IP 地址由网络号和主机号构成。端口号:用于区别主机上的那个进程,而引入的新的地址空间,叫端口号。6. 提供网际协议 IP 地址的 IPAddress 类;包含 IP 地址和端口号的 IPEndPoint 类;为 Internet 或 Intranet 主机提供信息容器的 IPHostEntry 类。 IPHostEntry 类将一个域名系统(DNS)的主机名与一组别名和一组匹配的 IP 地址关联。该类一
4、般和 Dns 类一起使用。 IPAddress ips =Dns.GetHostEntry(“”).AddressList;DNS 类的 IPAddress GetHostAddresses(string hostNameOrAddress);方法若是主机名,则返回此主机的所有 IP若 hostNameOrAddress 是 IP 地址,则直接返回此地址;若 hostNameOrAddress 是空字符串,则返回本地主机的所有 IPv4 和 IPv6 地址。DNS 类的 GetHostEntry(String s):当参数为空字符串时,返回本地主机的 IPHostEntry 实例。7. 对网络
5、流量和本机网络地址等信息的访问类都在 System.Net.NetworkInformation 命名空间下。网卡信息由 NetworkInterface 和 IPIterfaceProperties 类得到(实例都只能用静态方法得到实例) ,网络流量用 IPGlobalProprieties(静态方法获得实例).第二章1数字墨迹有哪些用途?一般的 WPF 元素是否具有数字墨迹相关的事件? 答:利用数字墨迹可以在计算机、手机、平板电脑、车载导航仪等各种设备上绘制墨迹形状,还可以利用它实现与触屏和手写应用相关的功能。所有 WPF 元素都支持数字墨迹功能。2. Ribbon 控件主要包括以下子项:
6、QuickAccessToolBar(快速访问工具栏) ,ApplicationMenu(应用程序菜单) ,RibbonTab(选项卡) 。3. 触笔(Stylus)在画板上移动时显示的痕迹叫墨迹笔画(Stroke) ,简称笔画。(System.Windows.Ink) 。其 GUID 一般用 Guid.NewGuid()方法获取4. 静态呈现是指将墨迹添加到控件之后再显示墨迹。添加方式有:通过触笔添加、从剪贴板中粘贴、从文件中加载。静态呈现墨迹的办法是自定义从 Stroke 类继承的类,并且在自定义类中重写引发触笔事件的 DrawCore 方法。动态呈现是指在移动触点的过程中同时呈现墨迹。是
7、将自定义墨迹控件的DynamicRenderer 属性设置为自定义的从 DynamicRenderer 类继承的类。并重写 OnDraw 方法。5. 制作自定义墨迹画板的主要设计步骤如下。1. 创建一个从 InkCanvas 派生的类。2. 将自定义的 DynamicRenderer 分配给 InkCanvas.DynamicRenderer 属性。3. 重写 OnStrokeCollected 方法。在此方法中,移除已添加到 InkCanvas 中的原始笔画,然后创建一个自定义笔画,将其添加到 Strokes 属性中。4. 最后再使用包含该自定义笔画的新 InkCanvasStrokeCol
8、lectedEventArgs 调用基类相应的方法。在 OnStylusMove 事件中,每次自动收集到的墨迹点的集合中只有两个点:一个是上次收集的集合中的最后一个点,一个是当前点。第三章1. 简要回答下列问题。(1)进程和线程有什么区别?为什么要用多线程?多线程适用于哪种场合?(2 )前台线程和后台线程有什么区别和联系?如何判断一个线程属于前台线程还是后台线程?如何将一个线程设置为后台线程? 答:(1)进程是正在执行的程序,线程是某个进程中的一个或多个执行流。进程是线程的容器,至少有一个主线程,线程的提出是为了适应程序内部的并行。多线程可让多个任务同时执行。当执行需要较长时间才能完成的连续操
9、作时,或者等待网络或其他 I/O 设备相应时,都可以使用多线程技术。(2 )一个线程要么是前台线程要么是后台线程。两者的区别是:后台线程不会影响进程的终止,而前台线程则会影响进程的终止。只有当属于某个进程的所有前台线程都终止后,公共语言运行库才会结束该进程,而所有的后台线程也都会立刻停止。用 Thread 对象创建的线程默认都是前台线程,线程池中的以及托管线程都是后台线程。3. System.Diagnostics 命名空间下的 Process 类提供了在操作系统级别对进程进行管理的各种属性和方法。4.启动进程:Process p = new Process(); /首先需要创建Process
10、类的一个实例p.StartInfo.FileName = “Notepad.exe“;/通过StartInfo属性指定要运行的应用程序名称以及传递的参数p.StartInfo.Arguments = argument;/要打开的文本文件p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;/带图形界面的设置p.Start(); /启动进程终止进程有两种方式:Kill 和 CloseMainWindow,Kill方法用于强行终止进程,是终止没有图形化界面进程的唯一方法。Kill 方法是异步执行的,调用 WaitForExit方法等待进程退出,或检
11、查HasExited属性以确定进程是否退出。CloseMainWindow()方法通过向主窗口发送关闭消息来关闭进程。此两种方法都只能对本机进程进行操作。WaitForInputIdle方法仅适用于具有用户界面的进程,它可以使 Process等待关联进程进入空闲状态。EnableRaisingEvents 属性用于获取或设置在进程终止时是否应引发 Exited事件。WaitForExit方法可设置等待关联进程退出的时间,并在该段时间结束前或该进程退出前,阻止当前线程执行。5. 获取进程信息Process.GetProcesses(string IP)获取指定主机的进程,为空时是本地主机的。Pr
12、ocess静态的 GetProcessById(int ID)方法会自动创建 Process对象,并将其与本地计算机上的进程相关联,同时将进程 Id传递给该 Process对象。 Process静态的 GetProcessesByName(string processName)方法返回一个包含所有关联进程的数组,得到该数组后,可以再依次查询这些进程中的每一个标识符,从而得到与该进程相关的更多信息。每次进程变动都需调用 RefreshProcessInfo()方法。6. System.Threading命名空间下的 Thread用于管理线程。7. 主线程和辅助线程:当程序作为进程来运行时,系统都
13、会为该进程创建一个默认的线程,该线程称为主线程。或者说,主线程用于执行 Main方法中的代码,当 Main方法返回时,主线程也自动终止。在一个进程中,除了主线程之外的其他线程都称为辅助线程。8. 通过Thread对象可创建一个单独的线程,Thread thread1 = new Thread();创建一个线程thread1,并自动通过相应的委托执行用” 指定的方法。有两种委托:ThreadStart系统自定义的委托,可执行无返回值的无参函数。ThreadStart a = new ThreadStart(test);/public void test();Thread t = new Thre
14、ad(a);t.Start();/等价于Thread t = new Thread(test);t.Start();还有一个系统自定义委托是 ParameterizedThreadStart的委托,所执行的方法是无返回值的参数为 Object的函数。线程启动即 Start方法,若线程执行的委托是无参的则为 Start().若是有参数的则为Start(Object obj)。终止或取消线程:1. 第 1种方法是先设置一个修饰符为 volatile的布尔型的字段表示是否需要正常结束该线程,称为终止线程。2. 第 2种方法是在其他线程中调用 Thread实例的 Abort方法终止当前线程,该方法的最
15、终效果是强行终止该线程的执行,属于非正常终止的情况,称为取消线程的执行休眠线程:调用 Thread.Sleep(参数)的线程自己阻塞。9. 什么是线程池?使用线程池有什么好处?线程池适用于执行时间短,任务量大的场合。线程池是在后台执行任务的线程集合,好处有:如当某个线程无法进入线程池执行时先将其放入等待队列,自动决定用哪个处理器执行线程池中的某个线程,自动调节这些线程执行时的负载平衡问题等。另外,线程池总是在后台异步处理请求的任务,而不会占用主线程,也不会延迟主线程中后续请求的处理。线程池的基本特征:1. 托管线程池中的线程都是后台线程。2. 添加到线程池中的任务不一定会立即执行。3. 线程池
16、可自动重用已创建过的线程。一旦池中的某个线程完成任务,它将返回到等待线程队列中,等待被再次使用,而不是直接销毁它。4. 开发人员可设置线程池的最大线程数。5. 从.NET 框架 4.0开始,线程池中的线程都是利用多核处理技术来实现的。10. 向线程池中添加工作项:直接利用 Thread.QueueUserWorkItem(new WaitCallback()来添加有参数无返回值的函数。11. 什么是同步?什么是异步?答:执行某语句时,在该语句完成之前不会执行其后面的代码,这种执行方式称为同步执行。另一种是执行某语句时,不管该语句是否完成,都会继续执行其后面的语句,这种执行方式叫异步执行。12.
17、 为什么需要同步?C#提供了什么语句可以简单地实现代码同步?答:当并行执行的多个线程同时访问某些资源时,必须考虑如何让多个线程保持同步。同步的目的是为了防止多个线程同时访问某些资源时出现死锁和争用情况。C#提供的 lock 语句可以简单地实现代码同步。13. 实现资源同步的方式:多线程实现资源同步主要通过加锁或原子操作来实现。1. 用 volatile 修饰符锁定公共或私有字段,利用该修饰符可直接访问内存中的字段,这样做的好处是所有处理器都可以访问该字段最新的值。2. 用 Interlocked 类提供的静态方法锁定局部变量,通过加锁和解锁提供了原子级别的静态操作方法。3. 用 lock 语句
18、锁定代码块(了解:lock 语句的实现原理是进入临界区之前先锁定某个私有对象(声明为 private 的对象),然后再执行临界区中的代码,当代码块中的语句执行完毕后,再自动解除该锁)。不允许锁定声明为 Public为了解决死锁以及异步执行过程中的同步问题,WPF 中的每个元素(包括根元素)都有一个 Dispatcher 属性。textBlock1.Dispatcher.Invoke()=textBlock1.text=”1”;);14. 什么叫应用程序域?应用程序域和进程有什么区别和联系? 和线程呢?答:一个主进程中,可包含一个或多个“子进程”,每个“子进程”所占用的内存范围(或者叫边界)都称
19、为一个应用程序域;一个进程既可以只包含一个应用程序域,也可以同时包含多个相互隔离的应用程序域。多进程是在操作系统级别使用的功能,资源消耗较大,细节控制复杂;应用程序域是在应用程序级别使用的功能,比直接用多进程来实现进程管理速度快、资源消耗少而且更安全,是轻量级的进程管理。应用程序域和线程的关系:1. 应用程序域为安全性、版本控制、可靠性和托管代码的卸载形成隔离边界,执行应用程序时,所有托管代码均加载到一个应用程序域中,由一个或多个托管线程来运行。2. 应用程序域和线程之间不具有一对一的相关性。3. 应用程序域之间是相互隔离的,一个应用程序域无法直接访问另一个应用程序域的资源。15.什么时候使用
20、应用程序域?答:1. 当需要动态扩展程序的功能时,可将其他进程(.dll 文件或者.exe 文件)中的全部或部分功能“嵌入”到当前应用程序进程界面中,使其看起来就像是同一个应用程序一样(多进程则无法做到这一点) ,而且这种实现方式比用多进程实现的运行速度快。2.在同一个进程内,实现不同域之间的通信比用多进程实现简单。3.在安全性方面,用应用程序域来实现比用多进程来实现更有保障第四章 1 (记)C#中的字符和字符串默认采用的都是 Unicode 编码。Encoding 类位于System.Text 命名空间下。 (了解)使用 Encoding 类静态的 GetEncodings 方法可得到一个包
21、含所有编码的 EncodingInfo 类型的数组。也可以利用 Encoding 类静态的GetEndcoing 方法来获取指定的编码,得到 Encoding 对象后,即可利用HeaderName 属性获取编码名称,利用 EncodingName 属性获取编码描述。 2. public static byte Convert(Encoding srcEncoding, /源编码Encoding dstEncoding, /目标编码byte bytes /待转换的字节数组)3. 将字符序列转换为字节序列的过程叫编码,GetBytes()。将字节序列转换为字符序列的过程叫解码,GetString(
22、)。4. 对数据流的操作有 3 种:逐字节顺序写入(将数据从内存缓冲区传输到外部源);逐字节顺序读取(将数据从外部源传输到内存缓冲区);随机读写(从某个位置开始逐字节顺序读或写);5. FileStream(string path,FileMode mode,FileAccess access);FileMode.Append 只能同FileAccess.Write 使用;另外一种构造方法是 File.OpenRead(String path); 创建仅读取的文件流.6. (MemoryStream)内存流:该对象的 CanSeek 属性值默认为 true程序中可通过 Position 属性获
23、取内存流的当前位置。内存流的容量可自动增长。7. NetworkStream 仅支持面向连接的套接字。注意以下几点:a. 通过 DataAvailable 属性,可查看缓冲区中是否有数据等待读出 .b. 网络流没有当前位置的概念,不支持对数据流的查找和随机访问,NetworkStream 对象的 CanSeek 属性始终返回 false.c. 读取 Position 属性和调用 Seek 方法时,都会引发 NotSupportedException 异常.8. 前三种流都在 System.IO 下,加密流(CrytoStream )在System.Security.Cryptography 下
24、;public CryptoStream(Stream stream, /对其执行加密转换的流ICryptoTransform transform, /要对流执行的加密转换CryptoStreamMode mode /CryptoStreamMode 枚举,有 Read 和 Write 两种);9. StreamReader 和 StreamWriterNetworkStream、MemoryStream 和 FileStream 实现思路都是先将待写入的数据转化为字节序列,然后再进行读写,对于文本数据来说操作不方便。所以用StreamReader 和 StreamWriter 来简化。Str
25、emReader sr = new StremReader (前三种流对象)。别忘记 Close 或用 using。10. 为什么要对字符进行编码和解码?答:在网络通信中,很多情况下通信双方传达的都是字符信息。但是,字符信息并不能直接从网络的一端传递到另一端,这些字符信息首先需要被转换成一个字节序列,然后才能在网络中传输。因此,发送方需要进行编码,相应的接收方就要执行解码。3简述对称加密(私钥加密)和不对称加密(公钥加密)的特点及实现原理。对称加密:(1)加密和解密数据使用同一个密钥;( 2)私钥算法以块为单位加密数据,一次加密一个数据块,因此支持数据流。常见的有:DES,RC2,SHA-1,
26、AES; 实现由CiperMode.CBC,密钥和 IV对称加密算法的优点:保密强度高,加、解密速度快,适合加密大量数据。对称加密的缺点:通信双方使用相同的密钥和 IV 加密和解密,发送方需要先将密钥和IV 传递给接收方。如果攻击者截获了密钥和 IV,也就等于知道了如何解密数据。不对称加密:(1)使用一个需要保密的私钥和一个可以对任何人公开的公钥。用公钥加密的数据只能用私钥解密,反之,用私钥加密的数据只能用公钥解密;(2)公钥加密算法使用长度固定的缓冲区,因此无法使用流。RSA,ECC不对称加密的优点:更不容易被攻击。不对称加密的缺点:由于无法使用流,因此不适合加密大量数据。11. 来确保密钥
27、存储的安全性,这就是密钥容器的用途。12. 什么是数字签名?数字签名有什么用途? (这题了解)答:在应用程序中,可以利用数字签名实现数据身份验证和数据完整性验证。数据身份验证是为了验证数据是不是持有私钥的人发送的;数据完整性验证则用于验证数据在传输过程中是否被修改过。数字签名的用途:通过 Internet 下载文件后,验证下载的文件是否和原始文件完全相同。换言之,如果通信双方希望确保信息是来自对方而不是来自第三方,需要使用数字签名进行身份验证。另外,数字签名还可以防止特定一方否认曾发送过的信息。第五章1. 从技术实现的角度看,并行是利用多线程来实现的,异步利用委托,并发数据利用专门的并发集合来
28、实现。2. 任务用 System.Threading.Tasks 命名空间下的 Task(无返回值)和 Task有返回值类来描述。Task.Delay 方法只能用于异步等待,等待过程中不会 界面流畅性。Thread.Sleep 如果不通过异步方式来执行,会影响 UI 操作,休眠期间界面有停顿现象。3. Action 和 Func 委托有什么不同?Action 委托封装了不带返回值的方法(有 016 个输入参数,返回类型为 void) ,Func委托封装了带返回值的方法(有 016 个输入参数,返回类型为 TResult) 。注意:在 Action 和 Func 的参数中不能使用 out 和 r
29、ef4 异步编程的实现方式有:1.传统的异步编程模型(APM)2. 基于事件的异步设计模式(EAP)3. 基于任务的异步模式 TAP4.改进的 TAP5. 有几种创建任务的方式? 有 4 种方式。(1 )利用 Task.Run 方法隐式创建和执行任务;此种方式表示使用默认的任务调度程序在线程池中通过后台 执行指定的任务。(2 )利用 async 和 await 关键字隐式创建异步任务在当前线程中异步执行指定方法;(3 )利用 WPF 控件的调度器隐式创建和执行任务;(4 )通过显式调用 Task 或 Task的构造函数创建任务6. 在 WPF 应用程序中有几种可用的定时器? 有 3 种。(1
30、) System.Timers.Timer 类;(2 ) System.Windows.Threading.DispatcherTimer 类;(3 ) System.Threading.Timer 类。7. 仅包含 async 和 await 关键字的异步方法与用 Task.Run 调用的异步方法有和不同?async 和 await 关键字是 C# 5.0 提供的功能,仅包含 async 和 await 关键字的异步方法不会创建新线程,它只是表示在当前线程中异步执行指定的任务。而 Task.Run 方法是.NET框架 4.5 提供的功能,它会在线程池中用单独的线程执行某个任务。8. 把普通方
31、法和异步方法作为任务来执行时,调用方法有何不同?普通方法要用Task.Run 方法去调用,或者用 Task、Task 类的构造函数显示创建 Task 实例,然后再启动。异步方法不需要用 Task.Run 方法去调用。9. 简述实现任务的取消功能的机制。答:System.Threading.CancellationTokenSource 用于创建取消通知,称为取消源。System.Threading.CancellationToken 结构用于传播应取消操作的通知,称为取消令牌。调用任务的代码在分配任务前,可先用 CancellationTokenSource 类创建一个取消源。在调用任务的代码
32、中,可通过取消源的 Cancel 方法发出取消通知,该方法会将每个取消令牌副本上的 IsCancellationRequested 属性都设置为 true。执行任务的方法接收到取消通知后,可以终止执行。、4简要回答用 WCF 编写 TCP 服务器端和客户端程序的一般步骤。【参考解答】使用 WCF 编写 TCP 服务器端应用程序的一般步骤如下。1)创建一个 WPF 应用程序,在项目中添加 WCF 服务。2)在 WCF 服务接口文件中定义服务端与客户端通信的协定,并实现定义在服务端需要实现的协定方法。3)修改服务端配置文件,并启动 WCF 服务,等待客户端调用并与客户端通信。4)根据实际情况确定是
33、否关闭 WCF 服务。使用 WCF 编写 TCP 客户端端应用程序的一般步骤如下。1)创建一个 WPF 应用程序,添加服务引用。2)实现 WCF 服务定义在客户端需要实现的协定方法。3)调用 WCF 服务,与服务端进行通信。1 UDP 和 TCP 的主要区别有哪些?【参考解答】UDP 是简单的、面向数据报的无连接协议,提供了快速但不一定可靠的传输服务。与TCP 一样,UDP 也是构建于底层 IP 协议之上的传输层协议。与 TCP 相比,UDP 具有以下特点。(1 ) UDP 不但支持一对一通信,而且支持一对多通信。(2 ) UDP 传输速度比 TCP 快。(3 ) UDP 有消息边界,使用 U
34、DP 不需要考虑消息边界问题。(4 ) UDP 不确保数据的发送顺序和接收顺序一致。(5 ) UDP 可靠性不如 TCP。2什么是广播?什么是多路广播?两者有什么区别?【参考解答】广播是指同时向多个设备发送消息,并且所有子网中的设备都可以接收到发送方发来的消息。每个广播消息包含一个特殊的 IP 地址。广播消息地址分为两种类型:本地广播和全球广播。本地广播可以向子网中的所有设备发送广播消息,其他网络不会受到本地广播的影响。多路广播是将消息从一台设备发送到本网或全网内选择的设备子集上,即发送到那些加入指定组播组的设备上。二者区别:广播只能向其所在的子网内发送消息,而且是向子网中的所有设备发送消息,
35、没有目的性,不但造成了网络负载,而且资源消耗较高。而多路广播是将消息发送到加入到特定组播组内的机器上,消息有目的性,资源消耗不高。3简要回答利用 UdpClient 对象加入和退出多播组的步骤。【参考解答】在 UDP 协议中,广播和组播的实现都是借助于特殊的 IP 地址实现的。特别是组播比较特殊。对于 IPv4 来说,多播是指在 224.0.0.0 到 239.255.255.255 的 D 类 IP 地址范围内进行广播。加入多播组时,首选创建 UdpClient 对象,然后使用 JoinMutiCastGroup 方法加入组播组。当退出组播组时,使用 UdpClient 对象的 DropMulticastGroup 方法可以退出多播组,参数中指出要退出多播组的 IPAddress 对象。