1 代理模式

  使用代理模式时必须让代理类和被代理类实现相同的接口;

  客户端通过代理类对象来调用被代理对象方法时,代理类对象会将所有方法的调用分派到被代理对象上进行反射执行;

  在分派的过程中还可以添加前置通知和后置处理。

2 为什么需要使用代理

  2.1 需求

    现有一个HelloApi接口和一个HelloApi接口的实现类Hello,现在需要统计HelloApi接口中say方法的耗时

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:20
* @desc
**/
public interface HelloApi { public void say(); }

Hello.java

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:18
* @desc
**/
public class Hello implements HelloApi { @Override
public void say() {
System.out.println("Hello Fury");
}
}

Hello.java

  2.2 思路

    思路01 -> 在实现类中实现

    思路02 -> 利用静态代理实现

    思路03 -> 利用动态代理实现

  2.3 解决

    2.3.1 在实现类中实现

      缺点:

        》需要针对方法进行操作,如果有多个方法需要相同的逻辑时工作量巨大

        》违背了开闭原则:开闭原则是对扩展开放,但是对修改关闭;为了增加功能把每个方法都修改了,不便于维护

        》违背了单一职责原则:每个方法除了完成自己本身的功能,还要计算耗时

开闭原则
开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。对于扩展是开放的,对于修改是关闭的,这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动

开闭原则

单一职责原则
单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。该原则由罗伯特·C·马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中给出的。马丁表示此原则是基于汤姆·狄马克(Tom DeMarco)和Meilir Page-Jones的著作中的内聚性原则发展出的。
所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。

单一职责原则

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:18
* @desc
**/
public class Hello implements HelloApi { @Override
public void say() {
Long start = System.currentTimeMillis();
System.out.println("Hello Fury");
Long end = System.currentTimeMillis();
System.out.println("耗时为:" + (end - start));
} }

HelloApi.java

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:18
* @desc
**/
public class Test { public static void main(String[] args) { Hello hello = new Hello(); // 01 传统调用方式
hello.say(); // 02 静态调用方式
// StaticProxy staticProxy = new StaticProxy(hello);
// staticProxy.say(); // HelloApi proxy = (HelloApi)new DynamicProxy().getProxy(hello);
// proxy.say(); } }

调用测试

    2.3.2 利用静态代理实现

      》修改HelloApi的实现类Hello,将实现类中say方法中的计算耗时逻辑去掉

      》创建一个类,该类实现了HelloApi接口

      》定义一个类型为Hello的成员变量target

      》重写say方法,在say方法中利用target成员变量去调用say方法,并在调用你的前后可以增加逻辑处理

      》》静态代理实现的缺点

        》》》需要针对每一个被代理对象编写一个静态代理类,如果需要进行代理的对象较多,那么工作量将很巨大

        》》》静态代理类实现了被代理对象所属类实现的接口,一旦接口发生改变,静态代理类也必须跟着发生变化

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:18
* @desc
**/
public class Hello implements HelloApi { @Override
public void say() {
// Long start = System.currentTimeMillis();
System.out.println("Hello Fury");
// Long end = System.currentTimeMillis();
// System.out.println("耗时为:" + (end - start));
} }

Hello.java

package demo_test02;

import java.util.concurrent.TimeUnit;

/**
* @author 王杨帅
* @create 2018-08-09 19:21
* @desc 静态代理类
**/
public class StaticProxy implements HelloApi { /**
* 被代理对象
*/
private Hello hello; public StaticProxy(Hello hello) {
this.hello = hello;
} @Override
public void say() {
Long start = System.currentTimeMillis();
hello.say();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
} public Hello getHello() {
return hello;
} public void setHello(Hello hello) {
this.hello = hello;
}
}

StaticProxy.java

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:18
* @desc
**/
public class Test { public static void main(String[] args) { Hello hello = new Hello(); // 01 传统调用方式
// hello.say(); // 02 静态调用方式
StaticProxy staticProxy = new StaticProxy(hello);
staticProxy.say(); // HelloApi proxy = (HelloApi)new DynamicProxy().getProxy(hello);
// proxy.say(); } }

静态代理测试

    2.3.3 利用动态代理实现

      》创建一个动态代理类,该类实现了InvocationHandler

      》定义一个Object类型的target成员变量

      》定义一个getProxy方法,该方法接收一个Object类型对象【就是被代理对象】;方法体中初始化target成员变量,并返回一个动态代理对象

        技巧01:调用Proxy的newProxyInstance 去创建动态代理对象,该方法接收三个参数,分别是:

          ClassLoader loader -> 被代理对象的类加载器【PS: 可以通过被加载对象的类类型去获取类加载器】

          Class<?>[] interfaces -> 被代理对象实现的接口组成的数组【PS: 可以通过被加载对象的类类型去获取实现的接口】

          InvocationHandler h -> 动态代理类实例【PS: 通过this传入自定义的动态代理类实例即可】

    /**
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation
* handler.
*
* <p>{@code Proxy.newProxyInstance} throws
* {@code IllegalArgumentException} for the same reasons that
* {@code Proxy.getProxyClass} does.
*
* @param loader the class loader to define the proxy class
* @param interfaces the list of interfaces for the proxy class
* to implement
* @param h the invocation handler to dispatch method invocations to
* @return a proxy instance with the specified invocation handler of a
* proxy class that is defined by the specified class loader
* and that implements the specified interfaces
* @throws IllegalArgumentException if any of the restrictions on the
* parameters that may be passed to {@code getProxyClass}
* are violated
* @throws SecurityException if a security manager, <em>s</em>, is present
* and any of the following conditions is met:
* <ul>
* <li> the given {@code loader} is {@code null} and
* the caller's class loader is not {@code null} and the
* invocation of {@link SecurityManager#checkPermission
* s.checkPermission} with
* {@code RuntimePermission("getClassLoader")} permission
* denies access;</li>
* <li> for each proxy interface, {@code intf},
* the caller's class loader is not the same as or an
* ancestor of the class loader for {@code intf} and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to {@code intf};</li>
* <li> any of the given proxy interfaces is non-public and the
* caller class is not in the same {@linkplain Package runtime package}
* as the non-public interface and the invocation of
* {@link SecurityManager#checkPermission s.checkPermission} with
* {@code ReflectPermission("newProxyInPackage.{package name}")}
* permission denies access.</li>
* </ul>
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}, or
* if the invocation handler, {@code h}, is
* {@code null}
*/
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
} /*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs); /*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
} final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}

      》重写invoke方法,在方法体通过mehtod的invoke方法去调用被代理对象的方法【PS: 利用反射实现的】

      》》坑01:获取到的动态代理类的类型是Ojbect类型,必须进行类型转换成对应的类型

      》》动态代理类实现的好处

        》》》自定义动态代理类,被代理对象所属类所实现的接口变动时代理类也无需变动,因为动态代理是通过反射的方式实现被代理对象所属类所实现的接口的

        》》》符合开闭原则,通过代理实现新功能,没有侵入到原有代码,也不用破坏原来的代码结构,完美的扩展方案

package demo_test02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit; /**
* @author 王杨帅
* @create 2018-08-09 19:26
* @desc 动态代理类
**/
public class DynamicProxy implements InvocationHandler { /**
* 被代理对象
*/
private Object target; /**
* 利用JDK的动态代理创建代理对象
* @param target
* @return
*/
public Object getProxy(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Long start = System.currentTimeMillis();
Object result = method.invoke(target, args);
TimeUnit.SECONDS.sleep(1);
Long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));
return result;
} public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
}
}

DynamicProxy.java

package demo_test02;

/**
* @author 王杨帅
* @create 2018-08-09 19:18
* @desc
**/
public class Test { public static void main(String[] args) { Hello hello = new Hello(); // 01 传统调用方式
// hello.say(); // 02 静态调用方式
// StaticProxy staticProxy = new StaticProxy(hello);
// staticProxy.say(); HelloApi proxy = (HelloApi)new DynamicProxy().getProxy(hello);
proxy.say(); } }

调用测试

3 动态代理

  3.1 动态代理类编程步骤

    》通过实现InvocationHandler接口来自定义自己的InvocationHandler;

    》通过Proxy.getProxyClass获得动态代理类
    》通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
    》通过构造函数获得代理对象并将自定义的InvocationHandler实例对象传为参数传入
    》通过代理对象调用目标方法

  3.2 繁琐方法

package demo_test02;

import java.lang.reflect.*;

/**
* @author 王杨帅
* @create 2018-08-09 19:59
* @desc
**/
public class Test02 { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
StudentImpl student = new StudentImpl(); /**
* 00 实现InvocationHandler来创建自己的动态代理类
* 01 获取动态代理类的类类型
* 02 获取动态代理类的构造器
* 03 创建动态代理类的实例
* 04 利用动态代理对象去调用被代理对象的方法
*/
Class<?> studentProxyClass = Proxy.getProxyClass(Student.class.getClassLoader(), Student.class); Constructor<?> studentProxyClassConstructor = studentProxyClass.getConstructor(InvocationHandler.class); Student studentProxy = (Student)studentProxyClassConstructor.newInstance(new StudentDynamicProxy(student)); studentProxy.study(); } interface Student {
void study();
} static class StudentImpl implements Student { @Override
public void study() {
System.out.println("I am studying dynamic proxy of java.");
}
} /**
* 自定义动态代理类
*/
static class StudentDynamicProxy implements InvocationHandler { /**
* 被代理对象
*/
private Object target; public StudentDynamicProxy(Object target) {
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置处理");
Object result = method.invoke(target, args);
System.out.println("后置处理");
return result;
}
} }

  3.3 简便方法

package demo_test02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author 王杨帅
* @create 2018-08-09 20:13
* @desc
**/
public class Test03 { public static void main(String[] args) {
StudentImpl student = new StudentImpl();
Student studentProxy = (Student)new StudentDynamicProxy().getDynamicProxyObject(student);
studentProxy.hello();
} interface Student {
void hello();
} static class StudentImpl implements Student { @Override
public void hello() {
System.out.println("你好,王杨帅。");
}
} static class StudentDynamicProxy implements InvocationHandler { private Object target; public Object getDynamicProxyObject(Object target) {
this.target = target;
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置处理");
Object result = method.invoke(target, args);
System.out.println("后置处理");
return result;
}
} }

  3.4 参考博文

    01  02  03

 

4 代理模式

  说明:
    target -> 表示被代理者(目标者)
    proxy -> 表示代理者

  4.1 静态代理

    技巧01:静态代理的目标者和代理者都需要实现相同的接口

    》接口:代理者和目标者需要实现的接口

package cn.xinagxu.static_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:27
* @desc
**/
public interface ISservice {
String someMethod01();
void someMethod02();
}

ISservice.java

    》目标者:被代理对象

package cn.xinagxu.static_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:25
* @desc
**/
public class SomeService implements ISservice { public String someMethod01() {
return "someMethod01";
} public void someMethod02() {
System.out.println("someMethod02");
} }

SomeService.java

    》代理者:代理目标者需要用到的代理类

package cn.xinagxu.static_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:26
* @desc
**/
public class StaticProxy implements ISservice { SomeService target; public StaticProxy(SomeService target) {
this.target = target;
} public String someMethod01() {
String result = target.someMethod01();
return result.toUpperCase();
} public void someMethod02() {
target.someMethod02();
}
}

StaticProxy.java

    》测试类

package cn.xinagxu.static_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:32
* @desc
**/
public class StaticProxtTest { public static void main(String[] args) { SomeService target = new SomeService(); StaticProxy proxy = new StaticProxy(target); String result = proxy.someMethod01(); System.out.println(result); proxy.someMethod02(); } }

StaticProxtTest.java

  4.2 JDK动态代理

    技巧01:jdk动态代理不需要自己编写代理类,因为时直接使用Proxy类来创建代理对象的;目标者的类任然需要实现一个接口

    》接口:目标者需要实现的接口

package cn.xinagxu.dynamic_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:27
* @desc
**/
public interface ISservice {
String someMethod01();
void someMethod02();
}

ISservice.java

    》目标者

package cn.xinagxu.dynamic_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:25
* @desc
**/
public class SomeService implements ISservice { public String someMethod01() {
return "someMethod01";
} public void someMethod02() {
System.out.println("someMethod02");
} }

SomeService.java

    》测试类

package cn.xinagxu.dynamic_proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author 王杨帅
* @create 2018-08-19 20:40
* @desc
**/
public class DynamicProxyTest { public static void main(String[] args) { final SomeService target = new SomeService(); ISservice proxy = (ISservice) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("someMethod01".equals(method.getName())) {
String str = (String) method.invoke(target, args);
return str.toUpperCase();
} else {
Object result = method.invoke(target, args);
return result;
} }
}
); System.out.println(proxy.someMethod01()); proxy.someMethod02(); } }

DynamicProxyTest.java

  4.3 Cglib动态代理

    技巧01:Cglib动态代理不需要接口,借助 Enhancer 类来创建代理对象,借助 MethodInterceptor 接口的 intercept 方法来实现增强逻辑

    技巧02:Enhancer 就相当于JDK动态代理中的Proxy,MethodInterceptor 接口的 intercept 方法就相当于JDK动态代理中 InvocationHandler 中的 invoke 方法

    技巧03:使用Cglib动态代理时需要引入外部依赖cglib

        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.7</version>
</dependency>

    》目标者

package cn.xinagxu.cglib_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 20:25
* @desc
**/
public class SomeService { public String someMethod01() {
return "someMethod01";
} public void someMethod02() {
System.out.println("someMethod02");
} }

SomeService.java

    》代理类工厂:用于创建代理对象的【PS: 可以不需要的,直接利用内部类实现】

package cn.xinagxu.cglib_proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import javax.xml.ws.Service;
import java.lang.reflect.Method; /**
* @author 王杨帅
* @create 2018-08-19 21:03
* @desc
**/
public class CglibFactory implements MethodInterceptor { private SomeService target; public CglibFactory(SomeService someService) {
this.target = someService;
} public CglibFactory() {
} // 创建代理对象的方法
public SomeService createProxy() { // 01 创建一个增强器
Enhancer enhancer = new Enhancer(); // 02 设置增强方
enhancer.setSuperclass(target.getClass()); // 03 接口回调方法
enhancer.setCallback(this); // 04 返回代理对象
return (SomeService) enhancer.create(); } // 跟JDK动态代理的invoke方法差不多
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { if ("someMethod01".equals(method.getName())) {
String str = (String) method.invoke(target, objects);
return str.toUpperCase();
} else {
Object result = method.invoke(target, objects);
return result;
} } }

CglibFactory.java

    》测试类

package cn.xinagxu.cglib_proxy;

/**
* @author 王杨帅
* @create 2018-08-19 21:12
* @desc
**/
public class CglibProxyTest { public static void main(String[] args) { SomeService target = new SomeService(); // 创建代理对象
SomeService proxy = new CglibFactory(target).createProxy(); System.out.println(proxy.someMethod01()); proxy.someMethod02(); } }

CglibProxyTest.java

  4.4 三种代理模的总结

    4.4.1 静态代理

      原材料:目标者、代理者、接口

      特点:迅速、目标者和代理者需要实现同一个接口

      比喻:

        目标者 -> 公司

        代理者 -> 法律顾问

    4.4.2 JDK动态代理

      原材料:目标者、接口

      特点:只需要目标者实现接口、目标者必须是final类型、代理者的类型必须是接口类型

        目标者 -> 个人

        代理者 -> 事务所

    4.4.3 Cglib动态代理

      原材料:目标者、cglib依赖

      特点:只需要目标者(目标者类型可以是类也可以是接口)、目标者不能是final类型、需要引入cglib依赖

        目标者 -> 个人

        代理者 -> 儿子

    4.4.4 三种代理方式源代码

      点击前往

 

代理模式 静态代理、JDK动态代理、Cglib动态代理的更多相关文章

  1. 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)

    代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...

  2. 代理模式:利用JDK原生动态实现AOP

    代理模式:利用JDK原生动态实现AOP http://www.cnblogs.com/qiuyong/p/6412870.html 1.概述 含义:控制对对象的访问. 作用:详细控制某个(某类)某对象 ...

  3. java 设计模式之单利模式以及代理模式(静态)

    1:单利模式: public class Singleton { private static Singleton uniqueInstance = null; private Singleton() ...

  4. 分享知识-快乐自己:三种代理(静态、JDK、CGlib 代理)

    1):代理模式(静态代理)点我下载三种模式源码 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由 业务实现类.业务代理类 两部分组成 ...

  5. java 代理模式-静态代理与动态代理

    最近在研究SpringAOP,当然要学习AOP就要知道这么健硕.强大的功能的背后究竟隐藏着怎样不可告人的“秘密”?? 接下来就是查阅了许多资料详细的研究了一下Java的代理模式,感觉还是非常非常重要的 ...

  6. Java代理模式/静态代理/动态代理

    代理模式:即Proxy Pattern,常用的设计模式之一.代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问. 代理概念 :为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委 ...

  7. 【Java】代处理?代理模式 - 静态代理,动态代理

    >不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算, ...

  8. Java中的代理模式--静态代理和动态代理本质理解

    代理模式定义:为其他对象提供了一种代理以控制对这个对象的访问. 代理模式的三种角色: Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求. Real ...

  9. Java代理模式——静态代理模式

    一:代理模式 代理模式的作用是:为其他对象提供一种代理以控制这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 二:代理模式设计 ...

随机推荐

  1. HihoCoder1127 二分图三·二分图最小点覆盖和最大独立集

    二分图三·二分图最小点覆盖和最大独立集 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上次安排完相亲之后又过了挺长时间,大家好像都差不多见过面了.不过相亲这个事不是说 ...

  2. docker -ce(社区免费版)

    Docker -ce https://www.cnblogs.com/zhangxiaoyong/p/9706392.html Docker 是世界领先的软件容器平台.开发人员利用 Docker 可以 ...

  3. Block Towers (思维实现)

    个人心得:这题没怎么看,题意难懂.后面比完再看的时候发现很好做但是怎么卡时间是个问题. 题意:就是有m个可以用2层积木的,n个可以用三层积木的,但是他们不允许重复所以可以无限添加. 比如 3 2 一开 ...

  4. [CSU1911]Card Game

    vjudge 题意 两个数组\(\{a_i\}\)和\(\{b_i\}\),求从中分别选出两个数或运算结果为\(x\)的方案数. sol 裸的FWT. code #include<cstdio& ...

  5. npm 私服工具verdaccio 安装配置试用

      1. 安装 npm install -g verdaccio 2. 启动 verdaccio // 界面显示信息 Verdaccio doesn't need superuser privileg ...

  6. 两种方式创建Maven项目【方式二】

    1.不勾选Create a simple project,直接点击下一步 2.选择maven-archetype-webapp下一步 3.填写相关信息,点击下一步完成 4.此时会报一个jsp的错误.我 ...

  7. ORA-00845 : MEMORY_TARGET not supported on this system(调大数据库内存无法启动)

    问题描述:调大数据库内存后,启动数据库报 ORA-00845 : MEMORY_TARGET not supported on this system . -- 调大数据库内存后,数据库启动报错[ro ...

  8. 在idea下两个项目之间的maven父子级项目依赖

    配置:idea 在一个项目中的父子级依赖网上轮子太多,我就不重复造了,留个链接 http://www.cnblogs.com/tibit/p/6185704.html 说说一些我自己注意的问题,在pr ...

  9. 有限状态机(Finite-state machine, FSM)的C语言实现

    有限状态机,也称为FSM(Finite State Machine),其在任意时刻都处于有限状态集合中的某一状态.当其获得一个输入字符时,将从当前状态转换到另一个状态,或者仍然保持在当前状态.任何一个 ...

  10. UiAutomator viewer 在tools下启动、资源jar包在platforms下(如android22)

    1.UiAutomator viewer 在tools下启动. 2.资源jar包在platforms下(如android22):android.jar/ uiautomator.jar