day08-AOP-01

AOP

1.官方文档

AOP讲解:下载的spring文件-->spring-framework-5.3.8/docs/reference/html/core.html#aop

AOP APIs:下载的spring文件-->spring-framework-5.3.8/docs/reference/html/core.html#aop-api

2.动态代理

2.1案例说明

需求说明:

  1. 有Vehicle(交通工具接口,有一个run方法),下面有两个实现类Car,Ship

  2. 当运行Car对象的run()方法和Ship对象的run()方法时,输出如下内容,注意观察前后有统一的输出

    image-20230123170808933 image-20230123170808933
  3. 请思考如何完成?

2.2传统方式解决

Vehicle接口:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 * 接口,定义了run方法
 */
public interface Vehicle {
    public void run();
}

Ship类,实现Vehicle接口:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Ship implements Vehicle {

    @Override
    public void run() {
        System.out.println("交通工具开始运行了...");
        System.out.println("大轮船在水上 running...");
        System.out.println("交通工具停止运行了...");
    }
}

Car类,实现Vehicle接口:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Car implements Vehicle {

    @Override
    public void run() {
        System.out.println("交通工具开始运行了...");
        System.out.println("小汽车在公路 running...");
        System.out.println("交通工具停止运行了...");
    }
}

TestVehicle测试类:

package com.li.proxy;

import org.testng.annotations.Test;

/**
 * @author 李
 * @version 1.0
 */
public class TestVehicle {
    @Test
    public void run() {
        Vehicle vehicle = new Car();//Vehicle vehicle = new Ship();
        vehicle.run();//动态绑定,根据实际运行类型调用run方法
    }
}
image-20230123173613218

上面的方式,代码冗余,其实就是单个对象的调用,并没有很好的解决问题。

2.3动态代理方式解决

解决思路:在调用方法的时候,使用反射机制,根据方法去决定调用哪个对象方法

Vehicle接口不变:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 * 接口,定义了run方法
 */
public interface Vehicle {
    public void run();
}

Ship:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Ship implements Vehicle {

    @Override
    public void run() {
        System.out.println("大轮船在水上 running...");
    }
}

Car:

package com.li.proxy;

/**
 * @author 李
 * @version 1.0
 */
public class Car implements Vehicle {

    @Override
    public void run() {
        System.out.println("小汽车在公路 running...");
    }
}

创建VehicleProxyProvider,该类返回一个代理对象:

package com.li.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 李
 * @version 1.0
 * VehicleProxyProvider类可以返回一个代理对象
 */
public class VehicleProxyProvider {
    //定义一个属性
    //target_vehicle 表示真正要执行的对象
    //要求该对象的类实现了Vehicle接口
    private Vehicle target_vehicle;

    //构造器
    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }


    //编写一个方法,可以返回一个代理对象
    public Vehicle getProxy() {
        //(1)得到类加载器
        ClassLoader classLoader =
                target_vehicle.getClass().getClassLoader();

        //(2)得到要代理的对象/被执行的对象 的接口信息,底层通过接口来完成调用
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();

        //(3)创建一个调用处理对象
        /**
         *   public interface InvocationHandler {
         *      public Object invoke(Object proxy, Method method, Object[] args)
         *      throws Throwable;
         *   }
         *   invoke 方法在将来执行我们的 target_vehicle的方法时,会调用到
         */
        //如上,因为InvocationHandler是接口,不能直接实例化
        // 以匿名内部类的方式来获取 InvocationHandler 对象
        //这个对象有一个方法:invoke, 到时可以通过反射,动态调用目标对象的方法
        InvocationHandler invocationHandler = new InvocationHandler() {
            /**
             * invoke()方法,在将来执行我们的target_vehicle的方法时会调用到
             * @param proxy 表示代理对象
             * @param method 就是通过代理对象调用方法时,的哪个方法
             * @param args 表示调用代理对象的方法时,传入方法的参数
             * @return 表示代理对象.方法(xx) 执行后的结果
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("交通工具开始运行了...");
                //这个地方的方法,就是你调用时动态传入的,可能是 run , 可能是 hi 等
                Object result = method.invoke(target_vehicle, args);
                System.out.println("交通工具停止运行了...");
                return result;
            }
        };

        /*(4)
          public static Object newProxyInstance(ClassLoader loader,
                                                    Class<?>[] interfaces,
                                                    InvocationHandler h)
          1.Proxy.newProxyInstance() 可以返回一个代理对象
          2.ClassLoader loader :类加载器
          3.Class<?>[] interfaces:要代理的对象的接口信息
          4.InvocationHandler h:调用处理器/对象,该对象有一个非常重要的方法-invoke
         */
        //将上面的 loader, interfaces, invocationHandler构建一个 Vehicle的代理对象.
        Vehicle proxy =
                (Vehicle) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return proxy;
    }

}

TestVehicle测试类:

@Test
public void proxyRun(){
    //创建Ship对象
    Vehicle vehicle = new Ship();

    //创建VehicleProxyProvider对象,并且传入要代理的对象
    VehicleProxyProvider vehicleProxyProvider = new VehicleProxyProvider(vehicle);

    //获取代理对象,该对象可以代理执行方法
    //1.proxy 编译类型是Vehicle
    //2.proxy 运行类型是 代理类型: class com.sun.proxy.$Proxy3
    Vehicle proxy = vehicleProxyProvider.getProxy();
    System.out.println("proxy 的运行类型是="+proxy.getClass());

    proxy.run();
}
image-20230123184229401

2.4动态代理机制debug

如上所示,当执行proxy.run();时,成功输出了目标信息,那么代码是怎么执行到代理对象的invoke方法上的?

image-20230123185920781

1.在proxy.run();旁打上断点,点击step into,光标跳转至VehicleProxyProvider的invoke方法:

image-20230123190225615

2.点击step over,光标跳转到下一行,此时method,target_vehicle代表了什么?

image-20230123191254182 image-20230123193834072

如上,此时的method就是我们Vehicle接口中的run方法,target_vehicle对象的实际运行类型是Ship,因为我们没有传值进去所以args为null。

3.在这行点击step into,进入invoke方法的源码,点击step over跳到return ma.invoke(obj, args);

image-20230123194558675

在这行点击step into:

image-20230123194851798

可以看到,底层最终执行了invoke0()方法:

image-20230123195041084

这里可以发现method 就是Vehicle的run方法,该方法会通过动态绑定,根据实际运行对象的类型(在这里即Ship),调用Ship中的run方法;var2就是我们调用代理对象的方法时传入的参数,这里为null:

image-20230123195220582

4.在这行再次点击step into,可以看到光标跳转到了Ship对象的run方法中,此时调用了Ship中的run方法:

image-20230123195616219

5.点击step over,因为底层代码执行完毕。光标层层返回到之前的method.invoke(target_vehicle,args)语句:

image-20230123195841465

6.因为Ship的run方法返回void,因此result的值为null:

image-20230123200609276

7.当执行到return result;时,相当于使用代理对象执行run方法执行完毕,因此返回上一层:

image-20230123200844246

至此,总体的流程就执行完毕了。

总结梳理:

1.proxy的编译类型是Vehicle,因此可以调用run方法;proxy的运行类型是class com.sun.proxy.$Proxy3,所以当执行run方法时会执行到代理对象的invoke方法

2.invoke 方法使用反射机制来调用 run()方法(注意这个 run 方法也可以是Vehicle 的其它方法),这时就可以在调用 run()方法前,进行前置处理和后置处理

image-20230123210027227

3.也就是说 proxy 的 target_vehicle 运行类型只要是实现了 Vehicle 接口,就可以去调用不同的方法,是动态的,变化的,底层就是使用反射完成的。

3.动态代理练习

3.1案例说明

需求说明:

有一个SmartAnimal接口,可以完成简单的加减法,要求在执行getSum()和getSub()时,输出执行前、执行过程、执行后的日志输出(参考如下),请思考如何实现

方法执行开始-日志-方法名-getSub-参数 [10.0, 2.0]
方法内部打印 result = 8.0
方法执行正常结束-日志-方法名-getSub-结果 result= 8.0
//可能的异常信息
方法最终结束-日志-方法名-getSub//finally的输出
======================
方法执行开始-日志-方法名-getSum-参数 [10.0, 2.0]
方法内部打印 result = 12.0
方法执行正常结束-日志-方法名-getSum-结果 result= 12.0
//可能的异常信息
方法最终结束-日志-方法名-getSum//finally的输出
  1. 请使用传统方法完成
  2. 请使用动态代理方式完成,并要求考虑代理对象调用方法(底层是反射调用)时,可能出现的异常

3.2传统方式解决

SmartAnimal接口:

package com.li.aop.proxy2;

/**
 * @author 李
 * @version 1.0
 */
public interface SmartAnimal {
    //求和
    float getSum(float a, float b);

    //求差
    float getSub(float a, float b);
}

SmartCat类实现接口SmartAnimal:

package com.li.aop.proxy2;

/**
 * @author 李
 * @version 1.0
 */
public class SmartCat implements SmartAnimal {
    @Override
    public float getSum(float a, float b) {
        System.out.println("日志-方法名-getSum-参数 " + a + " " + b);
        float result = a + b;
        System.out.println("方法内部打印 result = " + result);
        System.out.println("日志-方法名-getSum-结果result= " + result);
        return result;
    }

    @Override
    public float getSub(float a, float b) {
        System.out.println("日志-方法名-getSub-参数 " + a + " " + b);
        float result = a - b;
        System.out.println("方法内部打印 result = " + result);
        System.out.println("日志-方法名-getSub-结果result= " + result);
        return result;
    }
}

AopTest测试类:

package com.li.aop.proxy2;

import org.testng.annotations.Test;

/**
 * @author 李
 * @version 1.0
 */
public class AopTest {
    @Test
    public void testSmartAnimal() {
        SmartAnimal smartAnimal = new SmartCat();
        smartAnimal.getSum(10, 2);
        System.out.println("=======================");
        smartAnimal.getSub(10, 2);
    }
}
image-20230123221336974

传统方法的特点:

优点:实现简单直接

缺点:日志代码维护不方便,代码复用性差

解决思路:

  1. 使用动态代理来更好地处理日志记录问题
  2. 其他比如封装函数,或者类的继承在这里都不是特别合适

3.3动态代理方法解决

SmartAnimal接口不变。

SmartDog实现SmartAnimal接口:

package com.li.aop.proxy2;

/**
 * @author 李
 * @version 1.0
 */
public class SmartDog implements SmartAnimal {
    @Override
    public float getSum(float a, float b) {
        float result = a + b;
        System.out.println("方法内部打印 result = " + result);
        return result;
    }

    @Override
    public float getSub(float a, float b) {
        float result = a - b;
        System.out.println("方法内部打印 result = " + result);
        return result;
    }
}

MyProxyProvider类:

package com.li.aop.proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * @author 李
 * @version 1.0
 * 返回一个动态代理对象,可以执行被代理的对象的方法
 */
public class MyProxyProvider {

    //定义要执行的目标对象,该对象需要实现 SmartAnimal接口
    private SmartAnimal target_animal;

    //构造器
    public MyProxyProvider(SmartAnimal target_animal) {
        this.target_animal = target_animal;
    }

    //定义方法返回代理对象,该代理对象可以执行目标对象
    public SmartAnimal getProxy() {
        //(1)先得到类加载器对象
        ClassLoader classLoader = target_animal.getClass().getClassLoader();
        //(2)得到要执行的目标对象的接口信息
        Class<?>[] interfaces = target_animal.getClass().getInterfaces();
        //(3)使用匿名内部类 创建 InvocationHandler对象
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                try {
                    System.out.println("方法执行开始-日志-方法名-" + method.getName() +
                            "-参数 " + Arrays.toString(args));//这里从AOP的角度看,就是一个横切关注点-前置通知
                    //使用反射真正调用方法
                    result = method.invoke(target_animal, args);
                    System.out.println("方法执行正常结束-日志-方法名-" + method.getName()
                            + "-结果 result = " + result);//也是一个横切关注点-返回通知
                } catch (Exception e) {
                    //如果反射出现异常,就会进入到catch块
                    System.out.println("方法执行异常-日志-方法名" + method.getName()
                            + "-异常类型=" + e.getClass().getName());//也是一个横切关注点-异常通知
                    e.printStackTrace();
                } finally {//无论是否出现异常,最终都会执行到 finally{}
                    //也是一个横切关注点-最终通知
                    System.out.println("方法最终结束-日志-方法名-" + method.getName());
                }
                return result;
            }
        };

        //(4)创建代理对象
        SmartAnimal proxy = (SmartAnimal) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
        return proxy;
    }
}

测试方法:

@Test
public void testSmartAnimal() {
    SmartAnimal smartAnimal = new SmartDog();
    
    MyProxyProvider myProxyProvider
            = new MyProxyProvider(smartAnimal);
    
    SmartAnimal proxy = myProxyProvider.getProxy();
    
    proxy.getSum(10, 2);
    System.out.println("=======================");
    proxy.getSub(10, 2);

}
image-20230123224133941

3.4问题提出

在MyProxyProvider类中,我们的输出语句功能比较弱,在实际开发中,我们希望是以一个方法的形式,嵌入到真正执行的目标方法前,怎么办?

image-20230123225502663
本文转载于网络 如有侵权请联系删除

相关文章

  • 【经典书】数字图像处理算法介绍, 第三版

    来源:专知本文为书籍推荐,建议阅读5分钟这本书提供了一个现代的,独立的介绍数字图像处理。复制这本书提供了一个现代的,独立的介绍数字图像处理。我们设计了这本书,既供学习者使用,希望建立一个坚实的基础,也供寻找最重要技术的详细分析和透明实现的实践者使用。这是德语原版书的第三个英文版本,它已被广泛使用:这本现代的,独立的教科书提供了一个数字图像的领域介绍。这备受期待的第三版的权威教科书的数字图像处理已完全修订,并扩大了新的内容,改进插图和教材。主题和特点:包含关于几何基元拟合,随机特征检测(RANSAC),和最大稳定极值区域(MSER)的新章节包括大多数章节的练习,并在相关网站上提供额外的补充材料和软件实现所有示例都使用ImageJ,这是一种广泛使用的开源图像环境,可以在所有主要平台上运行以数学形式逐步描述每个解决方案,作为抽象的伪代码算法和完整的Java程序,可以很容易地移植到其他编程语言在前言中提出一个或两个学期课程的建议大纲高级本科生和研究生将发现这全面和例子丰富的教科书将作为理想的介绍数字图像处理。它也将证明宝贵的研究人员和专业人士寻求一个切实集中的自学入门。https://link

  • Parrot Anafi AI无人机介绍.上

    法国无人机厂商Parrot将在下半年发布全新无人机“AnafiAI",快来看看吧! https://mp.weixin.qq.com/s/rP4MWUhVXd0Sfdt3iOdJGg复制Parrot全新的无人机是这个样子的,个人感觉很酷 特别的,融入了仿生学的设计理念全速飞行的样子 换个视角你就会发现它是一个螳螂,重点就是这个摄像头中间这个是全新设计的云台相机 旁边两个相机是避障使用的相机,看型号是使用的黑白相机实现的视频流优化算法(图传算法):ParrotGen4Streaming(第4代)“错误隐藏”该算法减少了损失对网络的视觉影响,并实现了所有解码器的互操作性,同时确保了句法完整的流:丢失的图像部分被重建为跳过的部分,与参考图像的相同。因此,毛刺包含在受损耗影响的区域内,不会扩散到整个图像。下图说明了解码宏块的成功率,网络丢失率为5%-有和没有ANAFIAi的高级流功能。该算法确保对75%的宏块进行正确解码。这些使用户能够继续执行他的任务,而不会出现屏幕冻结或流媒体丢失的情况。希望它公开这个算法,看参数很不错是一种补偿类的算法特别的,飞行器还有可编程性。mate数据是明

  • React + TypeScript + Hook 带你手把手打造类型安全的应用。

    前言TypeScript可以说是今年的一大流行点,虽然Angular早就开始把TypeScript作为内置支持了,但是真正在中文社区火起来据我观察也就是没多久的事情,尤其是在Vue3官方宣布采用TypeScript开发以后达到了一个顶点。社区里有很多TypeScript比较基础的分享,但是关于React实战的还是相对少一些,这篇文章就带大家用React从头开始搭建一个TypeScript的todolist,我们的目标是实现类型安全,杜绝开发时可能出现的任何错误!本文所使用的所有代码全部整理在了ts-react-todo这个仓库里。分别实现了宽松版和严格版的axios和todolist,其中严格版本的实现会在文件夹加上.strict的后缀,请注意区分。本文默认你对于TypeScript的基础应用没有问题,对于泛型的使用也大概理解,如果对于TS的基础还没有熟悉的话,可以看我在上面github仓库的Readme的文末附上的几篇推荐。实战创建应用首先使用的脚手架是create-react-app,根据 www.html.cn/create-reac… 的流程可以很轻松的创建一个开箱即用的typ

  • Centos7搭建git管理系统Gogs

    Gogs简介Gogs是一款类似GitHub的开源文件/代码管理系统(基于Git),Gogs的目标是打造一个最简单、最快速和最轻松的方式搭建自助Git服务。使用Go语言开发使得Gogs能够通过独立的二进制分发,并且支持Go语言支持的所有平台,包括Linux、MacOSX、Windows以及ARM平台。基本功能介绍远程代码仓库管理代码仓库权限分配、管理团队管理代码审查Gogs二进制安装1、安装Git本站安装git详细教程:手动搭建Git服务器2、安装Mysql 本站安装MySql详细教程:手动搭建Git服务器安装完成后新建一个gogs数据库3、为Gogs创建用户与组,分配权限groupadd git useradd -g git git chown -d /usr/local/git  #这里建议安装在git安装目录下,也可以自定义安装目录复制4、下载Gogs二进制安装包,下载地址:https://dl.gogs.io/这里选择下载最新的:cd /usr/local/git wget  tar -zxvf gogs_0.11.86_linux_amd64.tar.gz复制5、使用git用户

  • conda:一个当下最流行的Python虚拟环境工具

    Conda环境Conda简介Conda是目前为止,最流行的Python软件包与管理环境。Conda分为miniconda与anaconda两种。前者从名字上就能猜出是精简版,后者预装了很多常用的功能,但比较臃肿。实际工程中,一般都使用miniconda,按需安装软件包,本文的下面篇幅也以miniconda为例进行说明。Conda安装首先利用wget下载安装脚本文件:wgethttps://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh复制如果速度较慢,可以换用axel或aria2c下载利用chmod命令修改sh文件为可执行文件,然后运行安装脚本:chmod755Miniconda3-latest-Linux-x86_64.sh bash./Miniconda3-latest-Linux-x86_64.sh复制在出现的提示界面中,根据提示选择yes或no。一般来说,我们保持默认即可,但需要留意下最后一步会自动在.bashrc文件添加conda的PATH路径。如果conda的环境存在与你日常使用的程序有冲突的命令,

  • 腾讯社招iOS面试记录

    腾讯社招iOS面试记录毕业好几年了,上周发送了简历给腾讯,参加了腾讯面试。具体部门这边就不说了。这次面试还是收获到了很多。一面电话面试:面试官主要是针对iOS相关的基础问题。先简单自我介绍一下自己对mrc和arc的理解谈谈对自动释放池的理解自动释放池在mrc和arc区别多层自动释放池嵌套的对象在哪一层释放对于block,理解,mrc和arc下有什么区别,使用注意事项对于深拷贝和浅拷贝的理解对于strongweak,atomic等等理解weak原理如果属性完全不加修饰词入weak,atomic,系统会怎么处理简述下block的实现描述下IM系统如何保证消息不丢IM数据库如何设计表C++引用和指针有什么区别Http协议30x的错误是什么谈谈你懂runloop得理解:由浅入深谈谈对多线程理解:由浅入深谈谈category和extension区别,系统如何底层实现category谈谈消息转发机制实现谈谈事件响应链,如何响应view之外的事件界面性能优化整个面试大约1个半小时。整体上,回答的还算OK,自动释放池这块,不够清楚底层实现。另外atomic是在属性没有写的情况下系统默认的。Block的

  • Matplotlib 3.0 可视化工具强势来袭!

    李林编译整理 量子位出品Matplotlib3.0来了!新版Matplotlib已能通过PyPI安装了,不过,这一版本只支持python3,Python2死忠还得继续用2.2.x版本。作为最热门的Python2D绘图工具之一,你看到的论文、教程里,有不少插图出自它手。3.0版总共有16项变化:改进了默认后端选择现在,内置后端在运行时按顺序尝试,直到导入了其中一个为止,不再要求默认后端必须作为构建过程的一部分来设置。无头Linux服务器(由未定义的DISPLAYenv来标识)不会选择GUI后端。新的循环调色板添加了两种新调色板:twilight和twilight_shifted。它们都以相同的颜色开始、结束,每个调色板的两半是对称的,亮度相同颜色不同。因为是循环的,所以它们很适合用在相位角、罗盘方向、一天中的时间等循环数据来上。能按固定的数量级缩放轴想要实现这个功能,需要为scilimits参数Axes.ticklabel_format设置相同的非零上限和下限。比如说,要把y轴缩放100万倍(1e6),代码是这样的:ax.ticklabel_format(style='sci&

  • PHP的yaf框架类加载机制

    代码注册ini设置到global_library变量(yaf.c)STD_PHP_INI_ENTRY("yaf.library","",PHP_INI_ALL,OnUpdateString,global_library,zend_yaf_globals,yaf_globals)复制把global_library和local_library都传递给了loader的初始化方法(yaf_application.c)if(YAF_G(local_library)){ zend_string*global_library=strlen(YAF_G(global_library))? zend_string_init(YAF_G(global_library),strlen(YAF_G(global_library)),0):NULL; loader=yaf_loader_instance(&zloader,YAF_G(local_library),global_library); if(global_library){ ze

  • 浅析MongoDB中的意向锁

    01意向锁,解决的问题成熟的数据库设计中,需要一个模块对资源的并发控制进行管理。意向锁就是实现资源并发控制管理的经典方式。在讨论它的概念与设计前,我们先举几个MongoDB的经典场景。mongoDB默认是行级并发,我们希望多行并发读写互不影响,但是我们又希望对在dropCollection时,不能有任何对表的读写在操作,这个“不希望”也是双向的,即在对表并发读写时,我们也不希望dropCollection在操作。在执行dbStats命令时,希望和dropDB/insert命令互斥,但是又不影响对表的并发读。由于写每个db的每张表,都须要往oplog中写记录,因此oplog是全局的,我们希望在truncateoplog这个全局操作在进行时,任何db对oplog的写操作都被阻塞。 第一个例子中,我们似乎用传统的rwlock就可以解决,在对表进行并发读写前,加rlock,在对表进行dropCollection前,加wlock。暂不论rwlock的r状态和并发写的行为不一致,至少这样是行得通的。可是遇到了第二个例子,我们发现rwlock的rw两个状态无法表达我们的锁需求了,到了第三个例子,只

  • C++中的return和exit区别

    在main函数中,return和exit经常混用,两者的一个区别:return会执行statck unwinding,而exit不会。如果触发了信号,exit也同样不会做stack unwinding,除此之外异常如果没有相应的catch,也同样不会有栈展开(stack unwinding)。 原因是C++编译器只会在遇到“}”或“return”时,才会安插栈展开代码,对于exit等则没这回事。#include #include #include class X { public: X(int m): _m(m) { printf("X::ctor:%d\n", m); } ~X() { printf("X::dtor:%d\n", _m); } private: int _m; }; int main() { X x(1); #if USE_EXIT exit(0); #if USE_RAISE raise(SIGSEGV); #else return 0; #endif }复制 以上述代码为例,通过汇编,可很容易看出这两者的区别: 1) r

  • 区块链上的人工智能

    区块链是一个去中心化的分布式账本,在其上面有像比特币和以太坊这样的加密货币在运行着;区块链也许是下一代的互联网;区块链是一项信息技术;区块链是一个无需信任的网络;区块链是一个为机器经济服务的M2M/物联网支付系统;区块链还是一个规模化的共识机制,这是我们一直在等待的一项技术——可以把我们引入到一个友好型的机器智能时代的技术。  区块链的共识机制恰巧可以在数字经济的“连接的世界”中,在人类和机器之间的信息交流方面有效地发挥作用,使得越来越多的自主的机器行为出现,并导致真正的人工智能,实现技术上的突破(机器智能代替自然人智能的时代也将到来)。主链侧链开发数字货币交易所白皮书区块链浏览器跨境支付场内场外宠物挖矿游戏基金会牌照181-4069-6008微信电话同号以长远的角度来展望,未来的社会有可能会发生翻天覆地的变化,其中有些现象会让现代人感到匪夷所思的:增强型人类,人类和机器不同形式的混合体,数字头脑上传,以及不同形式的人工智能,比如模拟大脑,以及先进的机器学习算法。这些智能可能不能被孤立的操作,应该会被连接到一个可以互相通讯的网络。为了实现他们的目标,数字智能将要求其在网络上进行某些交易

  • 笔记 35 | java线程之线程安全与非线程安全

    地址CSDNhttp://blog.csdn.net/xiangyong_1521/article/details/78541142线程安全与非线程安全ArrayList和VectorHashMap和HashTableStringBuilder和StringBuffer这些有什么区别?这些面试题常被问,答案是,左边的都是非线程安全,右边都是线程安全!然后又问你,什么是线程安全,什么是非线程安全呢?A.线程安全当多个线程类并发操作某类的方法A,来修改这个A方法的某个成员变量的值B,B不会出错,则我们就说,该的这个A方法是线程安全的。  某类的某方法是否线程安全的关键是:  (1)该方法是否修改该类的成员变量;  (2)是否给该方法加锁(是否用synchronized关键字修饰)。B.非线程安全当多个线程类并发操作某类的方法A,来修改这个A方法的某个成员变量的值B,B会出错,则我们就说,该的这个A方法是非线程安全的。synchronized如果要把这个方法变成线程安全的,则用synchronized关键字来修饰该方法即可:classcounnt{ privateintcount=0; /

  • 介绍bigpipe以及bigpipe在django上的实现

    什么是BigPipe 关于BigPipe是在看一篇淘宝ued的官方博客上看到的,原文是说用nodejs做前后端分离的,只是稍微提了一下bigpipe。感兴趣的同学也可以看一下那篇文章,http://ued.taobao.org/blog/2014/04/full-stack-development-with-nodejs/ 于是百度之,发现bigpipe是由facebook最先提出,个人感觉是个非常有意思的想法。关于bigpipe的介绍,网上有很多,这里简单说一下: 我们平常打开网页通常都是串行的,服务器收到请求后,开始各种渲染页面,等页面全部渲染好之后,再返回给浏览器,而在渲染过程中,浏览器则一直处于等待状态。 加入服务器有几个耗时的操作,总共需要花费10秒,则在这10秒钟内,浏览器属于一片空白,用户体验很不好。而bigpipe则是服务器接受到请求之后,立马返回一段骨架html,但是不包括闭合的body和html标签,这时候response并没有结束,每当服务器端准备好一块数据,就立即flush给浏览器,浏览器在收到骨架html之后,就立即开始渲染,之后每得到一段数据都进行渲染。 这

  • 数据可视化名企:搭建大数据与普通用户的桥梁

    虽然可视化在数据分析领域算不上最具技术挑战性的部分,但是它绝对可以说是最重要的一个方面。当然,存储、数据库的查询处理以及算法都是非常的重要——可视化离开它们也无法实现——但是在一个数据驱动的世界里,它们只是处在基本层的位置。这里有6家创业公司,他们试图从根本上改变数据的可视化。其中有一些是高度复杂的可视化处理过程,有些不是。虽然没有一个是完美的,但他们所做的一切,会让我们反思:数据究竟意味着什么? Ayasdi Ayasdi来自印第安语,是“寻找”的意思。斯坦福大学的GurjeetSingh,GunnarCarlsson和HarlanSexton一直在致力于将拓扑学的研究方法应用于数据分析。在2008年,他们联合成立了Ayasdi公司。Ayasdi成立以后,就获得了DARPA(美国国防部高级研究项目组)350万美元的资助。Ayasdi的底层使用的是HBase数据存储,然后再利用拓扑数据分析技术和上百种机器学习的算法来处理复杂的数据集,最终确定数据节点之间的相似度。而对终端用户而言,这看起来更像是一个数据集的拓扑图,只是强调了集群中有关联的数据点。 Ayasdi的技术有一个重要的特点

  • 利用Go语言实现简单Ping过程的方法

    、准备工作安装最新的Go 1、由于Google被墙的原因,如果没有V**的话,就到这里下载:http://www.golangtc.com/download 2、使用任意文本编辑器,或者LiteIDE会比较方便编译和调试 二、编码 要用到的package: ? import( "bytes" "container/list" "encoding/binary" "fmt" "net" "os" "time" )复制 1、使用Golang提供的net包中的相关函数可以快速构造一个IP包并自定义其中一些关键参数,而不需要再自己手动填充IP报文。 2、使用encoding/binary包可以轻松获取结构体struct的内存数据并且可以规定字节序(这里要用网络字节序BigEndian),而不需要自己去转换字节序。之前的一片文中使用boost,还要自己去实现转换过程 3、使用container/list包,方便进行结果统计 4、使用time包实现耗时和超时处

  • NOI 系列真题练习笔记

    前言NOIP前开始做做真题,虽然每年都风格迥异,不过感受一下OI风格的题目还是有一定意义的。P1016旅行家的预算贪心地考虑,在一个油站,如果加油,要么加满,要么加到足够行驶到下一个加油点的油量,在下一个更便宜的加油点再加油。是否存在后效性呢?在下一个油站始终可以加满,所以应该没有。当然,这鬼数据范围乱搜一下就完事了。#include<cstdio> constintmaxn=100; intn; doubletotaldis,C,per; doublecost[maxn],dis[maxn]; doubleres=1e18; voiddfs(intnow,doubletotalcost,doublenowhave) { if(nowhave<0)return; if(now==n)return(void)(res=res>totalcost?totalcost:res); for(inti=now+1;i<=n;++i) { doubled=dis[i]-dis[now]; if(cost[i]<=cost[now]&&am

  • 腾讯云云点播开通某地域的存储api接口

    1.接口描述接口请求域名:vod.tencentcloudapi.com。 该接口用于开通某地域的存储。 用户开通点播业务时,系统默认为用户开通了部分地域的存储,用户如果需要开通其它地域的存储,可以通过该接口进行开通。 通过DescribeStorageRegions接口可以查询到所有存储地域及已经开通的地域。 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:CreateStorageRegion。 Version 是 String 公共参数,本接口取值:2018-07-17。 Region 否 String 公共参数,本接口不需要传递此参数。 StorageRegion 是 String 待开通的存储地域,必须是系统支持的地

  • 【python django docker】docker部署django网站

    目录docker部署django网站1.安装docker2.下载并启动centos镜像3.在容器中准备网站环境4.安装uwsgi5.使用uwgsi运行网站6.设置网站开机自动启动7.保存容器为镜像并上传8.将网站分享给其他人部署后管理常用指令控制台快捷键sh常见指令docker相关conda相关django相关服务相关 docker部署django网站 以下均在centos7下进行。 1.安装docker 在安装前,需要确认是否已经安装docker,直接执行docker指令。如果已经安装,则直接跳到下一步。 没有安装 已经安装 安装并启动docker 安装方法,执行下列语句(参考): curl-sSLhttps://get.daocloud.io/docker|sh 复制 安装后,启动docker服务: systemctlstartdocker 复制 2.下载并启动centos镜像 在部署网站时,使用的python等软件的版本是不一样的,这里就直接使用纯净的centos镜像,然后再上面安装需要的软件。 注册dockerhub账号 dockerhub类

  • 挖掘需求需要知道的人性

    1、逐利心理    经典例子是团购,通过大基数购买达到商家降价从而用户得到优惠,但是这种方式因为长久会有需求,因此会长久。但是大多数P2P的产品的目的只是为了让用户拿钱,然后自己短时间内得益,这种的产品是否长久,用户是否留住似乎不在他们考虑的范围之内,满足一时的逐利心理但是却满足不了长久的心理,产品下场可想而知。 2.两性吸引力   两性社交的需求,两性天生相互吸引。最典型的是陌陌,虽然现在陌陌是除微信外第二大社交软件,但是不可否认,前期推广时运用此心理而导致成功的因素占比很大。 3.懒惰   外卖,喵了个咪,外卖在有补贴的情况下方便了很多用户,但是本人十分怀疑,在没有补贴并且高额的派送费和打包费下外卖能走多久,或者是一些店铺能走多久,从现在周围人使用情况来看,相对来说中高端、服务态度良好的店即使消费较高,但是重复购买率却很高。 4.虚荣心  QQ会员,游戏中付费玩家,减肥软件中各种朋友圈晒照,虚荣心真的是一剂杀招。 5.共情需要   真人秀,满足了一些人对于接触生活中的明星的需求。 6

  • Android AOSP 编译sdk

    首先你要有AOSP工程。 然后执行下面的命令编译sdk。 //运行下面的命令得到编译环境 sourcebuild/envsetup.sh lunchsdk makesdk 复制 最后文件输出在哪个位置会在命令行输出,如下: [100%6804/6804]PackageSDK:out/host/linux-x86/sdk/sdk/android-sdk_eng.caoxiny 泰山崩于前而色不变的曹新雨,抱歉

  • 接口测试HttpClient实践20150925

             用了工具做接口测试,但是对于加密数据和结果的比对,以及批量数据读取,回头还是觉得代码来更方便灵活,从excle中读取数据,构成参数,发请求,并获取返回结果和预期值比较,并将结果输出程报告,可以深入做成框架,用来还算是比较方便的,就研究了下httpclient,刚刚起步,还不是很熟练,以下是实战,不懂不要紧,先跟着练习几次,慢慢就理解了:1、在eclipse中新建java工程,添加jar包2、添加httpclient的jar包3、编写代码,一般我会写两个一个是get请求的,一个是post请求的,我这里写了一个post,里面包含了将数据存取文件中,和加密解密的方法:代码区:/**    *Post请求    *    *@paramurl    *@throwsIOException   &nbs

相关推荐

推荐阅读