`
dogasshole
  • 浏览: 842540 次
文章分类
社区版块
存档分类
最新评论

细说进程、应用程序域与上下文之间的关系

 
阅读更多

一、进程的概念与作用

进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。

 

 

1.1 Process 的属性与方法

在 System.Diagnostics 命名空间当中存在Process类,专门用于管理进程的开始、结束,访问进程中的模块,获取进程中的线程,设定进程的优先级别等。
表1.0 显示了Process类的常用属性:

属性 说明
BasePriority 获取关联进程的基本优先级。
ExitCode 获取关联进程终止时指定的值。
ExitTime 获取关联进程退出的时间。
Handle 返回关联进程的本机句柄。
HandleCount 获取由进程打开的句柄数。
HasExited 获取指示关联进程是否已终止的值。
Id 获取关联进程的唯一标识符。
MachineName 获取关联进程正在其上运行的计算机的名称。
MainModule 获取关联进程的主模块。
Modules 获取已由关联进程加载的模块。
PriorityClass 获取或设置关联进程的总体优先级类别。
ProcessName 获取该进程的名称。
StartInfo 获取或设置要传递给Process的Start方法的属性。
StartTime 获取关联进程启动的时间。
SynchronizingObject 获取或设置用于封送由于进程退出事件而发出的事件处理程序调用的对象。
Threads 获取在关联进程中运行的一组线程

 表1.0

除了上述属性,Process类也定义了下列经常使用的方法:

方法 说明
GetProcessById 创建新的 Process 组件,并将其与您指定的现有进程资源关联。
GetProcessByName 创建多个新的 Process 组件,并将其与您指定的现有进程资源关联。
GetCurrentProcess 获取新的 Process 组件并将其与当前活动的进程关联。
GetProcesses 获取本地计算机上正在运行的每一个进程列表。
Start 启动一个进程。
Kill 立即停止关联的进程。
Close 释放与此组件关联的所有资源。
WaitForExit 指示 Process 组件无限期地等待关联进程退出。

 表1.1

Process类的详细信息可以参考 http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.aspx
下面将举例介绍一下Process的使用方式

 

 

1.2 建立与销毁进程

利用 Start 与Kill 方法可以简单建立或者销毁进程,下面例子就是利用 Start 方法启动记事本的进程,并打开File.txt文件。2秒钟以后,再使用 Kill 方法销毁进程,并关闭记事本。

1         static void Main(string[] args)
2         {
3             Process process = Process.Start("notepad.exe","File.txt");
4             Thread.Sleep(2000);
5             process.Kill();
6         }
复制代码

 

 

1.3 列举计算机运行中的进程

在表1.0 中可以看到,使用 GetProcesses 方法可以获取本地计算机上正在运行的每一个进程列表。
而进程的 Id 属性是每个进程的唯一标志,通过下面的方法,可以显示当前计算机运行的所有进程信息。
因为篇幅关系,下面例子只获取前10个进程。

 1         static void Main(string[] args)
 2         {
 3             var processList = Process.GetProcesses()
 4                 .OrderBy(x=>x.Id)
 5                 .Take(10);
 6             foreach (var process in processList)
 7                 Console.WriteLine(string.Format("ProcessId is:{0} \t ProcessName is:{1}",
 8                     process.Id, process.ProcessName));
 9             Console.ReadKey();
10         }
复制代码

运行结果

 

如果已知进程的Id,就可以通过 GetProcessById 方法获取对应的进程。

 1         static void Main(string[] args)
 2         {
 3             try
 4             {
 5                 var process = Process.GetProcessById(1772);
 6                 Console.WriteLine("Process name is:" + process.ProcessName);
 7             }
 8             catch (ArgumentException ex)
 9             {
10                 Console.WriteLine("Process is nothing!");
11             }
12             Console.ReadKey();
13         }
复制代码


同样地,你也可能通过GetProcessByName方法获取多个对应名称的进程。

注意:如果不能找到当前ID的进程,系统就会抛出ArgumentException异常。所以使用方法 GetProcessById 获取进程时应该包含在 try{...} catch{..} 之内。

 

 

1.4 获取进程中的多个模块

在表1.0 中包含了Process类的Modules属性,通过此属性可能获取进程中的多个模块。
这些模块可以是以 *.dll 结尾的程序集,也可以是 *.exe 结尾的可执行程序。
下面的例子就是通过 Process 的 GetCurrentProcess 方法获取当前运行的进程信息,然后显示当前进程的多个模块信息。

1         static void Main(string[] args)
2         {
3             var moduleList = Process.GetCurrentProcess().Modules;
4             foreach (System.Diagnostics.ProcessModule module in moduleList)
5                 Console.WriteLine(string.Format("{0}\n  URL:{1}\n  Version:{2}",
6                     module.ModuleName,module.FileName,module.FileVersionInfo.FileVersion));
7             Console.ReadKey();
8         }
复制代码

运行结果:

 

回到目录


二、应用程序域

使用.NET建立的可执行程序 *.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中。应用程序域是.NET引入的一个新概念,它比进程所占用的资源要少,可以被看作是一个轻量级的进程。
在一个进程中可以包含多个应用程序域,一个应用程序域可以装载一个可执行程序(*.exe)或者多个程序集(*.dll)。这样可以使应用程序域之间实现深度隔离,即使进程中的某个应用程序域出现错误,也不会影响其他应用程序域的正常运作。

当一个程序集同时被多个应用程序域调用时,会出现两种情况:
第一种情况:CLR分别为不同的应用程序域加载此程序集。
第二种情况:CLR把此程序集加载到所有的应用程序域之外,并实现程序集共享,此情况比较特殊,被称作为Domain Neutral。

 

 

2.1 AppDomain的属性与方法

在System命名空间当中就存在AppDomain类,用管理应用程序域。下面是AppDomain类的常用属性:

属性 说明
ActivationContext 获取当前应用程序域的激活上下文。
ApplicationIdentity 获得应用程序域中的应用程序标识。
BaseDirectory 获取基目录。
CurrentDomain 获取当前 Thread 的当前应用程序域。
Id 获得一个整数,该整数唯一标识进程中的应用程序域。
RelativeSearchPath 获取相对于基目录的路径,在此程序集冲突解决程序应探测专用程序集。
SetupInformation 获取此实例的应用程序域配置信息。

表2.0

AppDomain类中有多个方法,可以用于创建一个新的应用程序域,或者执行应用程序域中的应用程序。

方法 说明
CreateDomain 创建新的应用程序域。
CreateInstance 创建在指定程序集中定义的指定类型的新实例。
CreateInstanceFrom 创建在指定程序集文件中定义的指定类型的新实例。
DoCallBack 在另一个应用程序域中执行代码,该应用程序域由指定的委托标识。
ExecuteAssembly 执行指定文件中包含的程序集。
ExecuteAssemblyByName 执行程序集。
GetAssemblies 获取已加载到此应用程序域的执行上下文中的程序集。
GetCurrentThreadId 获取当前线程标识符。
GetData 为指定名称获取存储在当前应用程序域中的值。
IsDefaultAppDomain 返回一个值,指示应用程序域是否是进程的默认应用程序域。
SetData 为应用程序域属性分配值。
Load 将 Assembly 加载到此应用程序域中。
Unload 卸载指定的应用程序域。

表2.1

AppDomain类中有多个事件,用于管理应用程序域生命周期中的不同部分。

事件 说明
AssemblyLoad 在加载程序集时发生。
AssemblyResolve 在对程序集的解析失败时发生。
DomainUnload 在即将卸载 AppDomain 时发生。
ProcessExit 当默认应用程序域的父进程存在时发生。
ReflectionOnlyAssemblyResolve 当程序集的解析在只反射上下文中失败时发生。
ResourceResolve 当资源解析因资源不是程序集中的有效链接资源或嵌入资源而失败时发生。
TypeResolve 在对类型的解析失败时发生。
UnhandledException 当某个异常未被捕获时出现。

表2.2

下面将举例详细介绍一下AppDomain的使用方式

 

 

2.2 在AppDomain中加载程序集

由表2.1中可以看到,通过CreateDomain方法可以建立一个新的应用程序域。
下面的例子将使用CreateDomain建立一个应用程序域,并使用Load方法加载程序集Model.dll。最后使用GetAssemblies方法,列举此应用程序域中的所有程序集。

1         static void Main(string[] args)
2         {
3             var appDomain = AppDomain.CreateDomain("NewAppDomain");
4             appDomain.Load("Model");
5             foreach (var assembly in appDomain.GetAssemblies())
6                 Console.WriteLine(string.Format("{0}\n----------------------------",
7                     assembly.FullName));
8             Console.ReadKey();
9         }
复制代码

运行结果

注意:当加载程序集后,就无法把它从AppDomain中卸载,只能把整个AppDomain卸载。

当需要在AppDomain加载可执行程序时,可以使用ExecuteAssembly方法。

AppDomain.ExecuteAssembly("Example.exe");

 

 

2.3 卸载AppDomain

通过Unload可以卸载AppDomain,在AppDomain卸载时将会触发DomainUnload事件。
下面的例子中,将会使用CreateDomain建立一个名为NewAppDomain的应用程序域。然后建立AssemblyLoad的事件处理方法,在程序集加载时显示程序集的信息。最后建立DomainUnload事件处理方法,在AppDomain卸载时显示卸载信息。

 1         static void Main(string[] args)
 2         {
 3             //新建名为NewAppDomain的应用程序域
 4             AppDomain newAppDomain = AppDomain.CreateDomain("NewAppDomain");
 5             //建立AssemblyLoad事件处理方法
 6             newAppDomain.AssemblyLoad +=
 7                 (obj, e) =>
 8                 {
 9                     Console.WriteLine(string.Format("{0} is loading!", e.LoadedAssembly.GetName()));
10                 };
11             //建立DomainUnload事件处理方法
12             newAppDomain.DomainUnload +=
13                 (obj, e) =>
14                 {
15                     Console.WriteLine("NewAppDomain Unload!");
16                 };
17             //加载程序集
18             newAppDomain.Load("Model");
19             //模拟操作
20             for (int n = 0; n < 5; n++)
21                 Console.WriteLine("  Do Work.......!");
22              //卸载AppDomain
23             AppDomain.Unload(newAppDomain);
24             Console.ReadKey();
25         }
复制代码

运行结果

 

 

2.4 在AppDomain中建立程序集中指定类的对象

使用CreateInstance方法,能建立程序集中指定类的对像。但使用此方法将返回一个ObjectHandle对象,若要将此值转化为原类型,可调用Unwrap方法。
下面例子会建立Model.dll程序集中的Model.Person对象。

 1 namespace Test
 2 {
 3      public class Program
 4     {
 5          static void Main(string[] args)
 6          {
 7              var person=(Person)AppDomain.CurrentDomain
 8                           .CreateInstance("Model","Model.Person").Unwrap();
 9              person.ID = 1;
10              person.Name = "Leslie";
11              person.Age = 29;
12              Console.WriteLine(string.Format("{0}'s age is {1}!",person.Name,person.Age));
13              Console.ReadKey();
14          }
15     }
16 }
17 
18 namespace Model
19 {
20     public class Person
21     {
22           public int ID
23           {
24               get;
25               set;
26           }
27           public string Name
28           {
29                get;
30                set;
31           }
32           public int Age
33           {
34                get;
35                set;
36           }
37      }
38 }
复制代码


回到目录

三、深入了解.NET上下文

3.1 .NET上下文的概念

应用程序域是进程中承载程序集的逻辑分区,在应用程序域当中,存在更细粒度的用于承载.NET对象的实体,那就.NET上下文Context。
所有的.NET对象都存在于上下文当中,每个AppDomain当中至少存在一个默认上下文(context 0)。
一般不需要指定特定上下文的对象被称为上下文灵活对象(context-agile),建立此对象不需要特定的操作,只需要由CLR自行管理,一般这些对象都会被建立在默认上下文当中。

图3.0

3.2 透明代理

在上下文的接口当中存在着一个消息接收器负责检测拦截和处理信息,当对象是MarshalByRefObject的子类的时候,CLR将会建立透明代理,实现对象与消息之间的转换。
应用程序域是CLR中资源的边界,一般情况下,应用程序域中的对象不能被外界的对象所访问。而MarshalByRefObject 的功能就是允许在支持远程处理的应用程序中跨应用程序域边界访问对象,在使用.NET Remoting远程对象开发时经常使用到的一个父类。
此文章针对的是进程与应用程序域的作用,关于MarshalByRefObject的使用已经超越了本文的范围,关于.NET Remoting 远程对象开发可参考:“回顾.NET Remoting分布式开发”

 

3.3 上下文绑定

当系统需要对象使用消息接收器机制的时候,即可使用ContextBoundObject类。ContextBoundObject继承了MarshalByRefObject类,保证了它的子类都会通过透明代理被访问。
在第一节介绍过:一般类所建立的对象为上下文灵活对象(context-agile),它们都由CLR自动管理,可存在于任意的上下文当中。而 ContextBoundObject 的子类所建立的对象只能在建立它的对应上下文中正常运行,此状态被称为上下文绑定。其他对象想要访问ContextBoundObject 的子类对象时,都只能通过代透明理来操作。

下面的例子,是上下文绑定对象与上下文灵活对象的一个对比。Example 是一个普通类,它的对象会运行在默认上下文当中。而ContextBound类继承了ContextBoundObject,它的对象是一个上下文绑定对象。ContextBound还有一个Synchronization特性,此特性会保证ContextBound对象被加载到一个线程安全的上下文当中运行。另外,Context类存在ContextProperties属性,通过此属性可以获取该上下文的已有信息。

 1     class Program
 2     {
 3         public class Example
 4         {
 5             public void Test()
 6             {
 7                 ContextMessage("Example Test\n");
 8             }
 9             //访问上下文绑定对象测试
10             public void Sync(ContextBound contextBound)
11             {
12                 contextBound.Test("Example call on contextBound\n");
13             }
14         }
15 
16         [Synchronization]
17         public class ContextBound:ContextBoundObject
18         {
19             public void Test(string message)
20             {
21                 ContextMessage(message);
22             }
23         }
24 
25         static void Main(string[] args)
26         {
27             Example example = new Example();
28             example.Test();
29             ContextBound contextBound = new ContextBound();
30             contextBound.Test("ContentBound Test\n");
31             example.Sync(contextBound);
32             Console.ReadKey();
33         }
34 
35         //显示上下文信息
36         public static void ContextMessage(string data)
37         {
38             Context context = Thread.CurrentContext;
39             Console.WriteLine(string.Format("{0}ContextId is {1}", data, context.ContextID));
40             foreach (var prop in context.ContextProperties)
41                 Console.WriteLine(prop.Name);
42             Console.WriteLine();
43         }
44     }
复制代码

运行结果

由运行结果可以发现,example对象一般只会工作于默认上下文context 0 当中,而contextBound则会工作于线程安全的上下文 context 1当中。当example需要调用contextBound对象时,就会通过透明代理把消息直接传递到context 1中。
 

 

回到目录

四、进程、应用程序域、线程的相互关系

4.1 跨AppDomain运行代码

在应用程序域之间的数据是相对独立的,当需要在其他AppDomain当中执行当前AppDomain中的程序集代码时,可以使用CrossAppDomainDelegate委托。把CrossAppDomainDelegate委托绑定方法以后,通过AppDomain的DoCallBack方法即可执行委托。

 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("CurrentAppDomain start!");
 4             //建立新的应用程序域对象
 5             AppDomain newAppDomain = AppDomain.CreateDomain("newAppDomain");
 6             //绑定CrossAppDomainDelegate的委托方法
 7             CrossAppDomainDelegate crossAppDomainDelegate=new CrossAppDomainDelegate(MyCallBack);
 8             //绑定DomainUnload的事件处理方法
 9             newAppDomain.DomainUnload += (obj, e) =>
10             {
11                 Console.WriteLine("NewAppDomain unload!");
12             };
13             //调用委托
14             newAppDomain.DoCallBack(crossAppDomainDelegate);
15             AppDomain.Unload(newAppDomain) ;
16             Console.ReadKey();
17         }
18 
19         static public void MyCallBack()
20         {
21             string name = AppDomain.CurrentDomain.FriendlyName;
22             for(int n=0;n<4;n++)
23             Console.WriteLine(string.Format( "  Do work in {0}........" , name));
24         }
复制代码

运行结果

 

4.2 跨AppDomain的线程

线程存在于进程当中,它在不同的时刻可以运行于多个不同的AppDomain当中。它是进程中的基本执行单元,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时 系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。
关于线程的介绍,可参考 “C#综合揭秘——细说多线程(上)”、“C#综合揭秘——细说多线程(下)”

下面的例子将介绍一下如何跨AppDomain使用线程,首先建立一个ConsoleApplication项目,在执行时输入当前线程及应用程序域的信息,最后生成Example.exe的可执行程序。

1         static void Main(string[] args)
2         {
3             var message = string.Format("  CurrentThreadID is:{0}\tAppDomainID is:{1}",
4                 Thread.CurrentThread.ManagedThreadId, AppDomain.CurrentDomain.Id);
5             Console.WriteLine(message);
6             Console.Read();
7         }
复制代码

然后再新建一个ConsoleApplication项目,在此项目中新一个AppDomain对象,在新的AppDomain中通过ExecuteAssembly方法执行Example.exe程序。

 1         static void Main(string[] args)
 2         {
 3             //当前应用程序域信息
 4             Console.WriteLine("CurrentAppDomain start!");
 5             ShowMessage();
 6             
 7             //建立新的应用程序域对象
 8             AppDomain newAppDomain = AppDomain.CreateDomain("newAppDomain");
 9             //在新的应用程序域中执行Example.exe
10             newAppDomain.ExecuteAssembly("Example.exe");
11 
12             AppDomain.Unload(newAppDomain);
13             Console.ReadKey();
14         }
15 
16         public static void ShowMessage()
17         {
18             var message = string.Format("  CurrentThreadID is:{0}\tAppDomainID is:{1}",
19                 Thread.CurrentThread.ManagedThreadId, AppDomain.CurrentDomain.Id);
20             Console.WriteLine(message);
21         }
复制代码

运行结果

可见,ID等于9的线程在不同时间内分别运行于AppDomain 1与AppDomain 2当中。

 

4.3 跨上下文的线程

线程既然能够跨越AppDomain的边界,当然也能跨越不同的上下文。
下面这个例子中,线程将同时运行在默认上下文与提供安全线程的上下文中。

 1     class Program
 2     {
 3         [Synchronization]
 4         public class ContextBound : ContextBoundObject
 5         {
 6             public void Test()
 7             {
 8                 ShowMessage();
 9             }
10         }
11 
12         static void Main(string[] args)
13         {
14             //当前应用程序域信息
15             Console.WriteLine("CurrentAppDomain start!");
16             ShowMessage();
17 
18             //在上下文绑定对象中运行线程
19             ContextBound contextBound = new ContextBound();
20             contextBound.Test();
21             Console.ReadKey();
22         }
23 
24         public static void ShowMessage()
25         {
26             var message = string.Format("  CurrentThreadID is:{0}\tContextID is:{1}",
27                  Thread.CurrentThread.ManagedThreadId, Thread.CurrentContext.ContextID);
28             Console.WriteLine(message);
29         }
30     }
复制代码

运行结果

 

本篇总结

进程(Process)、线程(Thread)、应用程序域(AppDomain)、上下文(Context)的关系如图5.0,一个进程内可以包括多个应用程序域,也有包括多个线程,线程也可以穿梭于多个应用程序域当中。但在同一个时刻,线程只会处于一个应用程序域内。线程也能穿梭于多个上下文当中,进行对象的调用。

虽然进程、应用程序域与上下文在平常的开发中并非经常用到,但深入地了解三者的关系,熟悉其操作方式对合理利用系统的资源,提高系统的效率是非常有意义的。
尤其是三者与线程之间的关系尤为重要,特别是在一个多线程系统中,如果不能理清其关系而盲目使用多线程,容易造成资源抢占与死锁之类的错误。

 图5.0

希望本篇文章对相关的开发人员有所帮助。

0
0
分享到:
评论

相关推荐

    毕业设计:基于SSM的mysql-羽毛球交流平台系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_羽毛球交流平台系统(源码 + 数据库 + 说明文档) 2 关键技术介绍 6 2.1 JSP技术概述 6 2.2 MYSQL简介 6 2.3 B/S结构 7 2.4 JAVA语言 8 2.5 MyEclipse简介 9 2.6 性能分析 9 2.7 SSM概述 10 3 需求分析与设计 11 3.1 系统需求分析 11 3.2 运行可行性 11 3.3 系统可行性分析 11 3.3.1 技术可行性 11 3.3.2 经济可行性 12 3.3.3 操作可行性 12 3.4 系统功能分析 12 3.5 系统功能结构图 13 3.6 系统流程分析 14 4 数据库设计 17 4.1数据库逻辑结构设计 17 4.2数据库物理结构设计 20 5 系统的详细设计与实现 25 5.1首页页面 25 5.2站内新闻页面 25 5.3场地列表页面 26 5.4场地详情页面 26 5.5在线留言页面 27 5.6修改密码页面 27 5.7注册用户管理信息页面 28 5.8场地信息管理页面 28 5.9场地预约管理页面 29 5.10评论信息管理页面 29 5.11添加友情链

    node-v10.15.1-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    VLT 变频器工程指南 danfoss

    VLT 变频器工程指南 Guía de funcionamiento Safe Torque off Convertidores de frecuencia VLT

    基于Java的C语言试题生成与考试系统的设计与实现(源代码+论文)

    基于Java的C语言试题生成与考试系统的设计与实现是一个毕业设计题目,旨在通过使用Java编程语言设计和开发一个功能完善的C语言试题生成与考试系统。 该毕业设计题目的背景和意义在于,随着计算机科学的不断发展,C语言作为一门基础编程语言,被广泛应用于软件开发、系统编程等领域。为了更好地评估学生对C语言的掌握程度,传统的纸质试卷已经无法满足需求,因此,开发一个基于Java的C语言试题生成与考试系统具有重要的实际意义。 该毕业设计题目的主要研究内容包括以下几个方面:首先,需要进行系统需求分析,明确系统的功能需求和技术要求。然后,需要进行系统设计,包括数据库设计、模块划分、算法设计等。接下来,需要使用Java编程语言进行系统开发,包括前端界面开发、后台逻辑实现、数据库操作等。最后,需要进行系统测试和优化,确保系统的稳定性和可靠性。 通过完成该毕业设计题目,学生可以深入学习和掌握Java编程语言,提高软件开发能力。同时,学生还可以学习和了解C语言的相关知识,以及试题生成和考试系统的设计与实现方法。这对于学生未来的职业发展具有积极的推动作用。

    毕业设计:基于SSM的mysql-智能图书馆导航系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_智能图书馆导航系统(源码 + 数据库 + 说明文档) 2 系统总体设计 1 2.1 需求调研 1 2.2系统功能性需求 2 2.3可行性分析 3 2.2.1经济可行性 3 2.2.2技术可行性 3 2.2.3操作可行性 4 2.4功能性需求分析 4 2.5本章小结 5 第3章 系统设计 6 3.1设计的思路 6 3.2系统结构设计 6 3系统功能结构 6 3.3数据库设计 7 3.3.1数据库设计概述 7 3.3.2概念设计 8 3.3.3表设计 9 3.4业务功能设计与实现 11 3.4.1查询功能的设计与实现 11 3.4.2借阅功能的设计与实现 12 第四章 系统实现 14 4.1 系统登录页面实现 14 4.2管理员操作界面实现 14 4.3 图书管理实现 15 4.4读者表管理实现 17 4.5 借还管理实现 17 4.6图书借阅实现 18 4.7我的借还信息实现 18 第五章 系统测试 20 5.1系统测试环境 20 5.2系统单元测试 20 5.3集成测试 20 5.4测试用例 21 5.5 性能测试 21 5.6 测试结果分析 22

    毕业设计:基于SSM的mysql-学习交流平台(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学习交流平台(源码 + 数据库 + 说明文档) 第二章 需求分析 5 2.1需求调研 5 2.2可行性分析 6 2.2.1技术的可行性 6 2.2.2经济的可行性 6 2.2.3操作可行性 6 2.2.4法律的可行性 7 2.3系统用户用例图 7 2.3.1管理员用例图 7 2.4功能模块需求分析 7 2.5设计的基本思想 9 2.6性能需求 9 2.6.1系统的安全性 9 2.6.2数据的完整性 9 2.7界面需求 10 2.7非功能性需求分析 11 2.7.1端到端响应时间 11 2.7.2易用性需求 11 2.7.3 可扩展性 11 第三章 系统分析与设计 12 3.1数据库的分析与设计 12 3.1.1数据库的概念结构设计 13 3.1.2数据库的逻辑结构设计 14 第四章 系统功能实现 17 4.1系统登陆页面实现 17 4.2总体功能模块 18 4.2.1注册用户信息管理 19 4.2.2学习资讯管理信息管理 20 4.2.3文章发表管理 21 4.2.4公告信息管理 22 4.2.5留言信息管理 22 4.2.6修改密码 23 4.2.

    基于JAVA的RSA文件加密软件的设计与实现(源代码+论文).rar

    本资料包名为“基于JAVA的RSA文件加密软件的设计与实现”,是一个针对计算机专业学习者提供的实用资源。它包含了完整的Java源代码以及一篇详细的论文,旨在帮助用户深入理解并实践RSA加密算法在文件加密领域的应用。该源码是基于Java语言开发的,利用了Java平台的安全和网络特性,实现了一个简单而强大的RSA文件加密工具。通过这个工具,用户可以对任意文本或数据文件进行加密和解密操作,确保信息传输的安全性。代码结构清晰,注释齐全,便于学习和修改。配套的论文则详细介绍了整个项目的设计理念、开发过程、关键技术点以及可能的改进方向。它从理论到实践,逐步引导读者了解RSA加密原理,并通过实例演示如何在Java环境中实现这一算法。无论是对于正在学习密码学、网络安全或是Java编程的学生,还是对于需要实现文件加密功能的开发者来说,这份资料包都是一份宝贵的学习资源。它不仅提供了现成的解决方案,更开辟了一条探索信息安全和Java编程深层次结合的道路。重新回答||

    毕业设计:基于SSM的mysql-学生网上请假系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学生网上请假系统(源码 + 数据库 + 说明文档) 第2章 主要技术和工具介绍 5 2.1 SSM 框架 5 2.1.1. Spring 框架 5 2.1.2 SpringMVC 6 2.1.3. MyBatis 的选用 6 2.2 mysql数据库 6 2.3eclipse与Tomcat简介 6 第3章 系统分析 4 3.1可行性分析 4 3.1.1经济可行性 4 3.1.2技术可行性 4 3.1.3操作可行性 4 3.2需求分析 4 3.3业务流程分析 5 3.4数据流程分析 5 第4章 系统设计 8 4.1系统结构设计 8 4.2功能模块设计 8 4.3数据库设计 9 4.3.1数据库设计概述 9 4.3.1概念设计 9 4.3.2表设计 11 第5章 系统实现 15 5.1基本论坛 15 5.2主页面的实现 15 5.3登录模块的实现 16 5.4班级信息管理模块的实现 17 5.6基础信息模块的实现 18 5.6用户权限管理模块的实现 19 5.7学生请假管理模块的实现 22 第6章 系统测试 23 6.1测试目的 23 6.2测试概述

    MFC,C++-简单学生成绩管理系统.zip

    学生成绩管理系统c

    node-v8.5.0-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar

    基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar

    M24LC04B EEPROM的Verilog行为模型

    M24LC04B EEPROM的Verilog行为模型

    node-v12.5.0-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2023商业银行数据资产体系白皮书,主要介绍了“三位一体”数据资产体系的构成与工作机制,以及商业银行数据资产体系建设实践

    2023商业银行数据资产体系白皮书 目录 第 1 章 数据资产化与数据要素市场化相辅相成,相互促进 第 2 章 数据资产化是企业数据治理向上演进的必经之路 第 3 章 数据资产体系发展概述 第 4 章 “三位一体”数据资产体系的构思 4.1“三位一体”数据资产体系的构成与工作机制 数据资产管理 数据资产运营 数据资产评价 数据资产体系工作机制 4.2“三位一体”数据资产体系的相互作用关系 4.3“三位一体”数据资产体系的构建 4.4“三位一体”数据资产体系的优势 第 5 章 商业银行数据资产体系建设实践 5.1商业银行开展数据资产体系建设的背景和目标 5.2商业银行数据资产体系建设的工作步骤 5.3上海银行数据资产体系建设实践的主要成果 第 6 章 数据要素流通市场赋能企业数据资产化 6.1全国多层次数据要素市场的建设 6.2上海数据交易所赋能企业数据资产化 6.3数据要素流通交易市场赋能企业数据资产化的展望 第 7 章 未来演进与展望

    基于matlab实现wsn路由,用matlab仿真,具有选簇的功能.rar

    基于matlab实现wsn路由,用matlab仿真,具有选簇的功能.rar

    什么是学生成绩管理系统c++以及学习学生成绩管理系统的意义

    学生成绩管理系统c++

    Dubins曲线算法讲解和在运动规划中的使用.pdf

    Dubins曲线算法讲解和在运动规划中的使用.pdf

    基于TOGAF的4A企业架构规划方法论.pptx

    基于TOGAF的4A企业架构规划方法论.pptx

Global site tag (gtag.js) - Google Analytics