当前位置: 首页 > 编程日记 > 正文

HttpModule与HttpHandler详解

ASP.NET对请求处理的过程:
当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,ASPNET_ISAPI.dll会通过http管道(Http PipeLine)将请求发送给ASPNET_WP.exe进程,在ASPNET_WP.exe进程中通过HttpRuntime来处理这个请求,处理完毕将结果返回客户端。
    inetinfo.exe进程:是www服务的进程,IIS服务和ASPNET_ISAPI.DLL都寄存在此进程中。
    ASPNET_ISAPI.DLL:是处理.aspx文件的win32组件。其实IIS服务器是只能识别.html文件的,当IIS服务器发现被请求的文件是.aspx文件时,IIS服务器将其交给aspnet_isapi.dll来处理。
    aspnet_wp.exe进程:ASP.NET框架进程,提供.net运行的托管环境,.net的CLR(公共语言运行时)就是寄存在此进程中。

ASP.NET Framework处理一个Http Request的流程:
    HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

ASP.NET 请求处理过程是基于管道模型的,这个管道模型是由多个HttpModule和HttpHandler组成,ASP.NET 把http请求依次传递给管道中各个HttpModule,最终被HttpHandler处理,处理完成后,再次经过管道中的HTTP模块,把结果返回给客户端。我们可以在每个HttpModule中都可以干预请求的处理过程。


注意:在http请求的处理过程中,只能调用一个HttpHandler,但可以调用多个HttpModule。
当请求到达HttpModule的时候,系统还没有对这个请求真正处理,但是我们可以在这个请求传递到处理中心(HttpHandler)之前附加一些其它信息,或者截获的这个请求并作一些额外的工作,也或者终止请求等。在HttpHandler处理完请求之后,我们可以再在相应的HttpModule中把请求处理的结果进行再次加工返回客户端。

HttpModule
    HTTP模块是实现了System.Web.IhttpModule接口的类。
    IHttpModule接口的声明:
        public interface IHttpModule
        {
            void Init (HttpApplication context);
            void Dispose ();
        }
        Init 方法:系统初始化的时候自动调用,这个方法允许HTTP模块向HttpApplication 对象中的事件注册自己的事件处理程序。
        Dispose方法: 这个方法给予HTTP模块在对象被垃圾收集之前执行清理的机会。此方法一般无需编写代码。
   
    HTTP模块可以向System.Web.HttpApplication对象注册下面一系列事件:
        AcquireRequestState 当ASP.NET运行时准备好接收当前HTTP请求的对话状态的时候引发这个事件。
        AuthenticateRequest 当ASP.NET 运行时准备验证用户身份的时候引发这个事件。
        AuthorizeRequest 当ASP.NET运行时准备授权用户访问资源的时候引发这个事件。
        BeginRequest 当ASP.NET运行时接收到新的HTTP请求的时候引发这个事件。
        Disposed 当ASP.NET完成HTTP请求的处理过程时引发这个事件。
        EndRequest 把响应内容发送到客户端之前引发这个事件。
        Error 在处理HTTP请求的过程中出现未处理异常的时候引发这个事件。
        PostRequestHandlerExecute 在HTTP处理程序结束执行的时候引发这个事件。
        PreRequestHandlerExecute 在ASP.NET开始执行HTTP请求的处理程序之前引发这个事件。在这个事件之后,ASP.NET 把该请求转发给适当的HTTP处理程序。
        PreSendRequestContent 在ASP.NET把响应内容发送到客户端之前引发这个事件。这个事件允许我们在内容到达客户端之前改变响应内容。我们可以使用这个事件给页面输出添加用于所有页面的内容。例如通用菜单、头信息或脚信息。
        PreSendRequestHeaders 在ASP.NET把HTTP响应头信息发送给客户端之前引发这个事件。在头信息到达客户端之前,这个事件允许我们改变它的内容。我们可以使用这个事件在头信息中添加cookie和自定义数据。
        ReleaseRequestState 当ASP.NET结束所搜有的请求处理程序执行的时候引发这个事件。
        ResolveRequestCache 我们引发这个事件来决定是否可以使用从输出缓冲返回的内容来结束请求。这依赖于Web应用程序的输出缓冲时怎样设置的。
        UpdateRequestCache 当ASP.NET完成了当前的HTTP请求的处理,并且输出内容已经准备好添加给输出缓冲的时候,引发这个事件。这依赖于Web应用程序的输出缓冲是如何设置的。

上面这么多的事件,我们看起来可能会有些眼晕,但没关系,下面一步一步地看。
    HttpModule生命周期示意图


    下面是事件的触发顺序:


    BeginRequest和PreRequestHandlerExecute之间的事件是在服务器执行HttpHandler处理之前触发。
    PostRequestHandlerExecute和PreSendRequestContent之间的事件是在服务器执行Handler处理之后触发。
   
    下面我们看一下如何使用HttpModule来实现我们日常的应用:
        HttpModule通过在某些事件中注册,把自己插入ASP.NET请求处理管道。当这些事件发生的时候,ASP.NET调用对相应的HTTP模块,这样该模块就能处理请求了。
       1、向每个页面动态添加一些备注或说明性的文字:
            有的网站每一个页面都会弹出一个广告或在每个页面都以注释形式(<!-- -->)加入网站的版权信息。如果在每个页面教编写这样的JS代码的话,对于大一点的网站,这种JS代码的编写与维护可是一个很繁琐枯燥的工作。
            有了HttpModule我们就可以很简单地解决这个问题了。HttpModule是客户端发出请求到客户端接收到服务器响应之间的一段必经之路。我们完全可以在服务器处理完请求之后,并在向客户端发送响应文本之前这段时机,把这段注释文字添加到页面文本之后。这样,每一个页面请求都会被附加上这段注释文字。
            这段代码究竟该在哪个事件里实现呢? PostRequestHandlerExecute和PreSendRequestContent之间的任何一个事件都可以,但我比较喜欢在EndRequest事件里编写代码。
            第一步:创建一个类库ClassLibrary831。
            第二步:编写一个类实现IHttpModule接口
                class TestModule:IHttpModule
                {
                    public void Dispose()
                    {
                    }
                    public void Init(HttpApplication context)
                    {
                    }
                }
            第三步:在Init事件中注册EndRequest事件,并实现事件处理方法
               class TestModule:IHttpModule
                {
                    public void Dispose(){}
                    public void Init(HttpApplication context)
                    {
                        context.EndRequest += new EventHandler(context_EndRequest);
                    }
                    void context_EndRequest(object sender, EventArgs e)
                    {
                        HttpApplication ha = (HttpApplication)sender;
                        ha.Response.Write("<!--这是每个页面都会动态生成的文字。--grayworm-->");
                    }
                }
            第四步:在Web.Conofig中注册一下这个HttpModule模块
          
<httpModules>
           <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
          </httpModules>
          name:模块名称,一般是类名
          type:有两部分组成,前半部分是命名空间和类名组成的全名,后半部分是程序集名称,如果类是直接放在App_Code文件夹中,那程序名称是App_Code。
                这样在Web站点是添加该类库的引用后,运行每个页面,会发现其源文件中都会加入“<!--这是每个页面都会动态生成的文字。 --grayworm-->”这句话。同样的方法你也可以在其中加入JS代码。
       2、身份检查
            大家在作登录时,登录成功后,一般要把用户名放在Session中保存,在其它每一个页面的Page_Load事件中都检查Session中是否存在用户名,如果不存在就说明用户未登录,就不让其访问其中的内容。
            在比较大的程序中,这种做法实在是太笨拙,因为你几乎要在每一个页面中都加入检测Session的代码,导致难以开发和维护。下面我们看看如何使用HttpModule来减少我们的工作量
            由于在这里我们要用到Session中的内容,我们只能在AcquireRequestState和PreRequestHandlerExecute事件中编写代码,因为在HttpModule中只有这两事件中可以访问Session。这里我们选择PreRequestHandlerExecute事件编写代码。
            第一步:创建一个类库ClassLibrary831。
            第二步:编写一个类实现IHttpModule接口
                class TestModule:IHttpModule
                {
                    public void Dispose()
                    {
                    }
                    public void Init(HttpApplication context)
                    {
                    }
                }
            第三步:在Init事件中注册PreRequestHandlerExecute事件,并实现事件处理方法
               class AuthenticModule:IHttpModule
                {
                    public void Dispose(){}
                    public void Init(HttpApplication context)
                    {
                        context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
                    }
                    void context_PreRequestHandlerExecute(object sender, EventArgs e)
                    {
                        HttpApplication ha = (HttpApplication)sender;
                        string path = ha.Context.Request.Url.ToString();
                        int n = path.ToLower().IndexOf("Login.aspx");
                        if (n == -1) //是否是登录页面,不是登录页面的话则进入{}
                        {
                            if (ha.Context.Session["user"] == null) //是否Session中有用户名,若是空的话,转向登录页。
                            {
                                ha.Context.Response.Redirect("Login.aspx?source=" + path);
                            }
                        }
                    }
                }
            第四步:在Login.aspx页面的“登录”按钮中加入下面代码
                protected void Button1_Click(object sender, EventArgs e)
                {
                    if(true)    //判断用户名密码是否正确
                    {
                        if (Request.QueryString["source"] != null)
                        {
                            string s = Request.QueryString["source"].ToLower().ToString();   //取出从哪个页面转来的
                            Session["user"] = txtUID.Text;
                            Response.Redirect(s); //转到用户想去的页面
                        }
                        else
                        {
                            Response.Redirect("main.aspx");    //默认转向main.aspx
                        }
                    }
                }
            第五步:在Web.Conofig中注册一下这个HttpModule模块
          
<httpModules>
           <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
          </httpModules>
       3、多模块的操作
            如果定义了多个HttpModule,在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。

HttpHandler
    HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。
    HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。
    IHttpHandler接口声明
    public interface IHttpHandler
    {
        bool IsReusable { get; }
        public void ProcessRequest(HttpContext context); //请求处理函数
    }
   
    示例:把硬盘上的图片以流的方式写在页面上
        class TestHandler : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);
                byte[] b = new byte[fs.Length];
                fs.Read(b, 0, (int)fs.Length);
                fs.Close();
                context.Response.OutputStream.Write(b, 0, b.Length);
            }
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
        }
        Web.Config配置文件
      <httpHandlers>
       <add verb="*" path="*" type="ClassLibrary831.TestHandler,ClassLibrary831"></add>
      </httpHandlers>
           Verb属性:指定了处理程序支持的HTTP动作。*-支持所有的HTTP动作;“GET”-支持Get操作;“POST”-支持Post操作;“GET, POST”-支持两种操作。
Path属性:指定了需要调用处理程序的路径和文件名(可以包含通配符)。“*”、“*.aspx”、“showImage.aspx”、“test1.aspx,test2.aspx”
Type属性:用名字空间、类名称和程序集名称的组合形式指定处理程序或处理程序工厂的实际类型。ASP.NET运行时首先搜索bin目录中的DLL,接着在GAC中搜索。
        这样程序运行的效果是该网站的任何一个页面都会显示worm.jpg图片。如何只让一个页面(default21.aspx)执行HttpHandler 中的ProcessRequest方法呢?最简单的办法是在Web.Config文件中把path配置信息设为default21.aspx。
        根据这个例子大家可以考虑一下如何编写“验证码”了。

IHttpHandler工厂
    IHttpHandlerFactory的作用是对IHttpHandler进行管理。工厂的作用请见http://hi.baidu.com/grayworm/blog/item/4a832160f8c9de46eaf8f8c1.html"
    IHttpHandlerFactory接口的声明:
        public interface IHttpHandlerFactory
        {
            IHttpHandler GetHandler (HttpContext context,string requestType,string url,string pathTranslated);
            void ReleaseHandler (IHttpHandler handler);
        }
       GetHandler返回实现IHttpHandler接口的类的实例,ReleaseHandler使工厂可以重用现有的处理程序实例。
    示例:两个用IHttpHandlerFactory来实现对不同HttpHandler的调用。
    有两个HttpHandler:将图片显示在页面上的HttpHandler和生成验证码的Handler
        //将图片显示在页面上的Handler
        class TestHandler : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);
                byte[] b = new byte[fs.Length];
                fs.Read(b, 0, (int)fs.Length);
                fs.Close();
                context.Response.OutputStream.Write(b, 0, b.Length);
            }
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
        }
        //生成验证码的Handler
        class CodeHandler:IHttpHandler
        {
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
            public void ProcessRequest(HttpContext context)
            {
                Image b = new Bitmap(50,20);
                Graphics g = Graphics.FromImage(b);
                SolidBrush sb = new SolidBrush(Color.White);
                Font f = new Font("宋体", 12);
                string str = "";
                Random r = new Random();
                for (int i = 0; i < 4; i++)
                {
                    str += r.Next(10);
                }
                g.DrawString(str,f,sb,0,0);
                b.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
        }
         IHttpHandler工厂
         class TestHandlerFactory : IHttpHandlerFactory
         {
            public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
            {
               
                string fname = url.Substring(url.IndexOf('/') + 1);
                while (fname.IndexOf('/') != -1)
                    fname = fname.Substring(fname.IndexOf('/') + 1);
                string cname = fname.Substring(0, fname.IndexOf('.'));
                string className ="";

                className = "ClassLibrary831.CodeHandler";
                object h = null;
                try
                {
                    //h = new TestHandler();
                    h = Activator.CreateInstance(Type.GetType(className));
                }
                catch (Exception e)
                {
                    throw new HttpException("工厂不能为类型" + cname + "创建实例。", e);
                }
                return (IHttpHandler)h;
            }
            public void ReleaseHandler(IHttpHandler handler)
            {
            }
         }(车延禄)
        配置文件
    <httpHandlers>
    <add verb="*" path="default21.aspx,default22.aspx" type="ClassLibrary831.TestHandlerFactory,ClassLibrary831"></add>
   </httpHandlers>

   这样TestHandlerFactory就会根据请求的不同页面执行不同的HttpHandler处理程序了。

HttpHandler使用会话
    如果要在处理程序中使用Session,那必须把该HttpHandler实现IRequiresSessionState接口,,IRequiresSessionState接口是个空接口,它没有抽象方法,只是一个标记。下面是一个文件上传的例子

1、先引用System.Web.SessionState这个命名空间,
2、如果是要在HttpHandler中读取Session的内容,就要在实现IHttpHandler的类中同时实现IReadOnlySessionState这个接口。
3、如果是要在HttpHandler中读写Session的内容,就要在实现IHttpHandler的类中同时实现IRequiresSessionState
  
  这样就可以在自定义的HttpHandler 中正常的使用Session了。

/// <summary>
/// 上传文件事件;
/// </summary>
public class Upload : IHttpHandler, IRequiresSessionState
{   
    public Upload()
    {
    }

    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        string temp = context.Session["temp"].ToString();

        string EncryptString = context.Request.QueryString["User"];
       
        if (temp!="" && context.Request.Files.Count > 0 )
        {
  
            string uploadPath = context.Server.MapPath(context.Request.ApplicationPath + "/Upload/" +temp);
   if (Directory.Exists(uploadPath) == false)//不存在该目录时自动创建一个目录
             {
                  Directory.CreateDirectory(uploadPath);
             }
          
            for(int j = 0; j < context.Request.Files.Count; j++)
            {
              
                HttpPostedFile uploadFile = context.Request.Files[j];
              
                if (uploadFile.ContentLength > 0)
                {
                   
                    uploadFile.SaveAs(Path.Combine(uploadPath, uploadFile.FileName));       
                }               
            }
        }
       
        //HttpContext.Current.Response.Write(" ");
      
    }

    #endregion
}


后台代码:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string jscript = "function UploadComplete(){" + ClientScript.GetPostBackEventReference(LinkButton1, "") + "};";
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "FileCompleteUpload", jscript, true);
        Session["temp"] = "yekin";
        FormsIdentity cIdentity = User.Identity as FormsIdentity;
        string encryptString = Session["temp"].ToString();
        flashUpload.QueryParameters = string.Format("User={0}", encryptString);       
    }

protected void LinkButton1_Click(object sender, EventArgs e)
    {
 
 
  Response.Write("<script>alert('恭喜您,上传成功!');</script>");
 
       
        // MyGrid.DataBind();
    }
}

转载于:https://www.cnblogs.com/yuanyuan/archive/2010/11/15/1877709.html

相关文章:

《梦断代码Dreaming In Code》阅读笔记(三)

最后这几章感觉上更多是从软件完成整体上来讲的。比如说技术、方法等。 在我看来&#xff0c;其实一个团队一直坚持一种好的、先进的方法是不可少的。如果一个优秀的团队刚愎自用&#xff0c;只随着成员们喜好发展&#xff0c;那不能长久。比如说&#xff0c;在开发软件工程课程…

个人建议之PHP面试的准备

你好&#xff0c;是我琉忆——PHP程序员面试笔试系列图书的作者。 随着越来越多的人开始迈入PHP开发工程师的队列&#xff0c;不管是一个PHP新手还是一个有一两年开发经验的PHPer都不得不去面对找工作前面试这件事。 我现在以个人对面试的经历和见解来全面的对PHP面试考点PHP真…

关于2D互动技术的一些要点

没有动画的程序很难称作是互动产品。 2D图形技术主要涵盖 动画原理 动画是定时器改变元素属性&#xff0c;渲染引擎重新渲染的过程。 动画的本质是 关于时间的函数 PS:右图就是一个快进慢出的动画 动画的要素

Xamarin开发Anroid应用介绍

第1章 Xamarin开发Anroid应用介绍 如今智能手机已经盛行了好几年&#xff0c;而针对这些智能手机的软件开发也变得异常火热。但是在Android平台下只能使用Java开发&#xff0c;iOS平台下也只能使用Objective-C或Swift开发本文选自Xamarin Android开发实战上册。 对于那些C#程序…

忘记Rxjava吧,你应该试试Kotlin的协程

0.前言 协程以前一直是Kotlin作为实验性的一个库&#xff0c;前些日子发现1.3版本的kotlin relese了协程&#xff0c;所以就找时间研究了一下&#xff0c;本来早就想写这篇文章了&#xff0c;但是因为离职换工作的原因&#xff0c;迟迟未能动笔&#xff0c;这两天终于算搞完了&…

数据可视化相关网站

D3 gallery Gallery / D3 / Observable Flowing Data / NYTimes / … FlowingData | Data Visualization and Statistics Data Video Explorer Data Video Explorer 配色网站 配色网站 Material Design Color, Flat Colors, Icons, Color Palette | Material UI Colo…

【2012天津区域赛】部分题解 hdu4431—4441

1001&#xff1a; 题意&#xff1a;给你13张麻将牌&#xff0c;问可以胡哪些张 思路&#xff1a; 枚举可能接到的牌&#xff0c;然后dfs判断能否胡 1002&#xff1a; 题意&#xff1a; 已知n&#xff0c;m 求 n的所有约数在m进制下的平方和 做法&#xff1a;队长用java高精度写…

彻底理解OkHttp - OkHttp 源码解析及OkHttp的设计思想

OkHttp 现在统治了Android的网络请求领域&#xff0c;最常用的框架是&#xff1a;Retrofitokhttp。OkHttp的实现原理和设计思想是必须要了解的&#xff0c;读懂和理解流行的框架也是程序员进阶的必经之路&#xff0c;代码和语言只是工具&#xff0c;重要的是思想。 在OKhttp 源…

访问 Microsoft SQL Server 元数据的三种

上海微创软件有限公司 肖桂东适用读者&#xff1a;Microsoft SQL Server 中、高级用户元数据简介元数据 (metadata) 最常见的定义为"有关数据的结构数据"&#xff0c;或者再简单一点就是"关于数据的信息"&#xff0c;日常生活中的图例、图书馆目录卡和名片…

apply()智用:需要几个参数但只有一个参数数组

比奇堡的居民海绵宝宝&#xff0c;派大星&#xff0c;蟹老板正在开party let arr [SpongeBob,Patrick,Mr.Crab]; 如果章鱼哥来了&#xff0c;珊迪也来了 arr.push(Squidward Tentacles,Sandy); 此时一共派对有5人 如果章鱼哥和珊迪一起来了 arr.push.apply(arr,[Squidwar…

HTML转WORD WORD转PDF--来源网络

从网上找的代码&#xff0c;先收藏下。 功能&#xff1a;实现HTML转WORD&#xff0c;WORD转PDF view source print?using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using Syst…

正则表达式小结

基础 数量匹配 *代表{0,} 代表{1,} ?代表{0,1} [0-9][0-9]{1,} 表示匹配0~9中的任意数字&#xff0c;并且至少1位。 [0-9]*[0-9]{0,} 表示匹配0~9中的任意数字&#xff0c;并且可以是0位&#xff08;不存在&#xff09;。 [0-9]?[0-9]{0,1} 表示匹配0~9中的任意数字&…

Log控制台打印设置

android Log.isLoggable方法的使用 android 动态控制logcat日志开关,通过Log.isLoggable&#xff08;TAG,level&#xff09;方法动态控制&#xff0c;1.添加日志的时候加入判断&#xff0c; String TAG"Volley"; boolean isDbugLog.isLoggable(TAG, Lo…

JavaScript 定义类时如何将方法提取出来

现在我们有一个海洋生物类 function marineLife(name,job,friend){this.name name;this.job job;this.friend friend;this.introduceMyself function(){console.log(大家好&#xff01;我叫this.name,我是一名this.job,我最好的朋友是this.friend);} } 让我们用这个类新建…

错误:Error #2032解决方案

问题&#xff1a; Error #2032错误要访问外部数据&#xff0c;必须信任此文件。 现象&#xff1a; 要访问外部数据&#xff0c;必须信任此文件。 对于 PDF 文件&#xff0c;在 Adobe Reader 中&#xff0c;单击“Edit”&#xff08;编辑&#xff09;>“Preferences”&#…

[转]c# 泛类型(泛型) 以及强类型与弱类型的 理解及优化

[泛型的概念]&#xff08;1&#xff09;没有泛型的时候&#xff0c;所有的对象都是以object为基础&#xff0c;如果要使用时必须进行强制类型转换&#xff0c;如果对于值类型&#xff0c;则会导致不断拆箱装箱的过程&#xff0c;对系统消耗很大。&#xff08;2&#xff09;使用…

docker宿主机访问docker容器服务失败

2019独角兽企业重金招聘Python工程师标准>>> 原因&#xff1a; 因为docker的虚拟ip网段是172.17.*。*与局域网的ip网段172.17冲突了&#xff0c;所以有两种方式&#xff1a; 解决方法&#xff1a; 一、 修改docker网卡信息&#xff0c;将网段改为与局域网不同的即可…

从变量地址到指针再到指针变量

标题中的3个概念&#xff1a;变量地址、指针and指针变量是依次出现的&#xff0c;逐个确定就可以明晰到底什么是我们常说的指针(其实是指针变量) 首先&#xff0c;变量在本质上是一段存储空间&#xff0c;既然是存储空间&#xff0c;就必有地址&#xff0c;一般每个字节有一个…

Lua bind 和 conf 实现

Lua &#xff0c;语法简单&#xff08;极像javascript), 移植性好(纯C实现), 启动速度快&#xff0c;空间占用小&#xff0c; 真不愧是潜入式脚本语言之王。 本人想拿它来做 配置文件(conf)&#xff0c;也想加一点IoC, 就是配置脚本可以调用主程序的函数。 实现如下&#xff1…

通过反射执行get、set方法

Class clazz sourceObj.getClass(); 1、获取所有属性 BeanInfo beanInfo Introspector.getBeanInfo(clazz); PropertyDescriptor[] pds beanInfo.getPropertyDescriptors(); 2、获取指定属性 PropertyDescriptor pd new PropertyDescriptor(fieldName, clazz); Method getM…

h5 移动端 关于监测切换程序到后台或息屏事件和visibilitychange的使用

需求&#xff1a;当我们页面上正在播放视频或者播放背景音乐时&#xff0c;我们屏幕自动息屏或者切换程序去看消息时&#xff0c;我们希望暂停视频或背景音乐&#xff0c;回到程序我们希望继续播放视频或播放背景音乐。小程序上提供了 onUnload返回 onHide退出 onShow重新进入等…

一份整理 | PyTorch是什么,为何选择它

PyTorch是什么 PyTorch的特性 PyTorch是什么 PyTorch是一个基于Python的科学计算包&#xff0c;主要提供以下两种用途&#xff1a; 在GPU算力或其他加速器上作为NumPy的替代一个用于实现神经网络的自动求导库 PyTorch的特性 PyTorch的祖先是Chainer,HIPS autograd,twitter…

jquery实现心算练习

看看大家做完要多长时间&#xff0c;不能上传附近&#xff0c;就只得贴代码。代码如下&#xff1a; 代码 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2 <htm…

C/C++利用三元组实现稀疏矩阵运算

三元组&#xff08;&#xff08;x&#xff0c;y&#xff09;&#xff0c;z&#xff09;其中&#xff08;x&#xff0c;y&#xff09;表示非零元位置&#xff0c;z表示该坐标的值 由于实际操作时&#xff0c;我们所用的矩阵0非常多&#xff0c;所以一个一个输入值很浪费时间&…

Database项目中关于Procedure sp_refreshsqlmodule_internal的错误

最近项目中发现一怪问题&#xff0c;使用DB项目发布数据库时&#xff0c;总提示 “(110,1): SQL72014: .Net SqlClient Data Provider: Msg 1222, Level 16, State 56, Procedure sp_refreshsqlmodule_internal, Line 67 Lock request time out period exceeded. An error occu…

脱离公式谈谈对反向传播算法的理解

机器学习的训练过程可看作是最优化问题的求解过程。 根据原理 对于函数f(x),如果f(x)在点xt附近是连续可微的&#xff0c;那么f(x)下降最快的方向是f(x)在xt点的梯度的反方向 得到最简单最常用的优化算法&#xff1a;梯度下降法(Gradient Descent Method)。 可以想见&#xf…

如何在Form中使用键弹性域(Key Flexfield)

在应用弹性域之前必须先定义弹性域&#xff0c;定义之前必须先注册表列。如果你的弹性域已经在Oracle Application Object Library中已经定义和注册了&#xff0c;并且弹性域表和列已经在数据库中存在&#xff0c;则忽略1、2、3步骤&#xff0c;适用于关键性也适用于描述性弹性…

什么是SOLID原则(第3部分)

让我们从最后一个 SOLID 原则开始吧&#xff0c;即依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;简称 DIP&#xff09;&#xff08;不要和依赖注入Dependency Injection &#xff0c;DI 弄混淆了&#xff09;。这个原则所说的是高级模块不应该依赖具象的…

李彦宏,韩寒等入围本年度《时代百人》候选名单

美国《时代》杂志周六&#xff08;4月3日&#xff09;公布了2010年度 “百位全球最具影响力人物”的200名候选人名单,其中中国最大网络搜索公司“百度”总裁李彦宏也以成功企业家入围候选人,同时入围的还有年仅27岁的80后作家韩寒。 其它“全球最具影响力人物”候选人名单中还包…

win10如何查看NVIDIA驱动的版本

入口 输入&#xff1a;控制面板 选择&#xff1a;硬件和声音 选择NVIDIA控制面板 点击小房子图标 看到版本是391.25