精华内容
下载资源
问答
  • 动态代理的种方式以及缺点

    千次阅读 2019-03-20 14:55:44
    在各种开源的框架中都能看到他们的身影,比如spring中的aop使用动态代理增强,mybatis中使用动态代理生成mapper,动态代理主要JDK和CGLIB种方式,今天来学习下这种方式的实现,以及它们的缺点 动态代理:是...

    前言

    动态代理应用非常的广泛,在各种开源的框架中都能看到他们的身影,比如spring中的aop使用动态代理增强,mybatis中使用动态代理生成mapper,动态代理主要有JDK和CGLIB两种方式,今天来学习下这两种方式的实现,以及它们的优缺点

    动态代理:是使用反射和字节码的技术,在运行期创建指定接口或类的子类,以及其实例对象的技术,通过这个技术可以无侵入的为代码进行增强

    一、JDK实现的动态代理

    1、解析

    jdk实现的动态代理由两个重要的成员组成,分别是Proxy、InvocationHandler

    Proxy:是所有动态代理的父类,它提供了一个静态方法来创建动态代理的class对象和实例

    InvocationHandler:每个动态代理实例都有一个关联的InvocationHandler,在代理实例上调用方法是,方法调用将被转发到InvocationHandler的invoke方法

    2、简单看下jdk的动态代理的原理图

     3、代码实现

    现在模拟一个用户注册的功能,动态代理对用户的注册功能进行增强,会判断用户名和密码的长度,如果用户名<=1和密码<6则会抛出异常

    User.java

    package com.taolong;
    
    public class User {
    
    	private String name;
    	
    	private Integer age;
    	
    	private String password;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    
    	public Integer getAge() {
    		return age;
    	}
    
    	public void setAge(Integer age) {
    		this.age = age;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	@Override
    	public String toString() {
    		return "User [name=" + name + ", age=" + age + ", password=" + password + "]";
    	}
    	
    	
    }

     UserService.java

    package com.taolong.jdk;
    
    import com.taolong.User;
    
    public interface UserService {
    	
    	void addUser(User user);
    }

     UserServiceImpl.java

    package com.taolong.jdk;
    
    import com.taolong.User;
    
    public class UserServiceImpl implements UserService {
    
    	@Override
    	public void addUser(User user) {
    		System.out.println("jdk...正在注册用户,用户信息为:"+user);
    	}
    
    }

     UserServiceInterceptor.java

    package com.taolong.jdk;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    import com.taolong.User;
    
    public class UserServiceInterceptor implements InvocationHandler {
    
    	private Object realObj;
    	
    	public UserServiceInterceptor(Object realObject) {
    		super();
    		this.realObj = realObject;
    	}
    	
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		if (args!=null && args.length > 0 && args[0] instanceof User) {
    			User user = (User)args[0];
    			//进行增强判断
    			if (user.getName().length() <= 1) {
    				throw new RuntimeException("用户名长度必须大于1");
    			}
    			if (user.getPassword().length() <= 6) {
    				throw new RuntimeException("密码长度必须大于6");
    			}
    		}
    		Object result = method.invoke(realObj, args);
    		System.out.println("用户注册成功...");
    		return result;
    	}
    
    	public Object getRealObj() {
    		return realObj;
    	}
    
    	public void setRealObj(Object realObj) {
    		this.realObj = realObj;
    	}
    	
    }

     ClientTest.java

    package com.taolong.jdk;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    import com.taolong.User;
    
    public class ClientTest {
    
    	public static void main(String[] args) {
    		User user = new User();
    		user.setName("hongtaolong");
    		user.setPassword("hong");
    		user.setAge(23);
    		//被代理类
    		UserService delegate = new UserServiceImpl();
    		InvocationHandler userServiceInterceptor = new UserServiceInterceptor(delegate);
    		//动态代理类
    		UserService userServiceProxy = (UserService)Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
    				delegate.getClass().getInterfaces(), userServiceInterceptor);
    		System.out.println("动态代理类:"+userServiceProxy.getClass());
    		userServiceProxy.addUser(user);
    	}
    }

     运行结果:当密码的长度小于6时

    这里就起到了动态增强的作用,mybatis的使用中我们知道不需要创建dao中的mapper接口的子类,也能调用到相应的方法,其实就是生成的实现了mapper接口的动态的代理类,我们可以去看看它的这个方法

     

     接下来我们看下cglib的使用

    二、CGLIB动态代理

    1、解析

    CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承的方式实现代理(最后这部分我们深思一下,它可能有哪些局限,final方法是不能够被重写,所以它不能增强被final修饰的方法,这个等下我们来验证)

    CGLIB的实现也有两个重要的成员组成,Enhancer、MethodInterceptor,其实这两个的使用和jdk实现的动态代理的Proxy、InvocationHandler非常相似

    Enhancer:来指定要代理的目标对象,实际处理代理逻辑的对象,最终通过调用create()方法得到代理对象、对这个对象所有的非final方法的调用都会转发给MethodInterceptor

    MethodInterceptor:动态代理对象的方法调用都会转发到intercept方法进行增强

    2、图解

    3、代码的实现

    还是上面的场景,注册用户进行拦截增强,部分代码如下

    UserServiceCglibInterceptor.java

    package com.taolong.cglib;
    
    import java.lang.reflect.Method;
    
    import com.taolong.User;
    
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class UserServiceCglibInterceptor implements MethodInterceptor {
    
    	private Object realObject;
    	
    	public UserServiceCglibInterceptor(Object realObject) {
    		super();
    		this.realObject = realObject;
    	}
    	
    	@Override
    	public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    		if (args!=null && args.length > 0 && args[0] instanceof User) {
    			User user = (User)args[0];
    			//进行增强判断
    			if (user.getName().length() <= 1) {
    				throw new RuntimeException("用户名长度必须大于1");
    			}
    			if (user.getPassword().length() <= 6) {
    				throw new RuntimeException("密码长度必须大于6");
    			}
    		}
    		Object result = method.invoke(realObject, args);
    		System.out.println("用户注册成功...");
    		return result;
    	}
    
    }

     ClientTest.java

    package com.taolong.cglib;
    
    import com.taolong.User;
    
    import net.sf.cglib.proxy.Enhancer;
    
    public class ClientTest {
    
    	public static void main(String[] args) {
    		User user = new User();
    		user.setName("hongtaolong");
    		user.setPassword("hong");
    		user.setAge(23);
    		//被代理的对象
    		UserServiceImplCglib delegate = new UserServiceImplCglib();
    		UserServiceCglibInterceptor serviceInterceptor = new UserServiceCglibInterceptor(delegate);
    		Enhancer enhancer = new Enhancer();
    		enhancer.setSuperclass(delegate.getClass());
    		enhancer.setCallback(serviceInterceptor);
    		//动态代理类
    		UserServiceImplCglib cglibProxy = (UserServiceImplCglib)enhancer.create();
    		System.out.println("动态代理类父类:"+cglibProxy.getClass().getSuperclass());
    		cglibProxy.addUser(user);
    	}
    }

    运行结果:

     这里顺便打印了动态代理类的父类,接下来我们将它的父类UserServiceImplCglib的addUser方法用final修饰,看看是否会被增强

    UserServiceImplCglib.java

    package com.taolong.cglib;
    
    import com.taolong.User;
    
    public class UserServiceImplCglib {
    
    	final void addUser(User  user) {
    		System.out.println("cglib...正在注册用户,用户信息为:"+user);
    	}
    }

     运行结果:

     

    总结一下

    1、JDK原声动态代理时java原声支持的、不需要任何外部依赖、但是它只能基于接口进行代理(因为它已经继承了proxy了,java不支持多继承)

    2、CGLIB通过继承的方式进行代理、无论目标对象没有没实现接口都可以代理,但是无法处理final的情况(final修饰的方法不能被覆写)

    好了,就暂时先写到这里了,感兴趣的朋友可以具体看一下实现的源码,如有错误欢迎指正,谢谢!

     

     

    展开全文
  • 个for循环的缺点

    千次阅读 2016-02-15 13:27:25
    1.白盒测试方法中的代码检查法需要重点考虑代码的执行效率,阅读以下个循环,回答问题1和问题2。  循环1:  for (i=0;i  {  if(condition)  DoSomething();  else  DoOtherthing();  }  ...

    1.白盒测试方法中的代码检查法需要重点考虑代码的执行效率,阅读以下两个循环,回答问题1和问题2。

          循环1:
          for (i=0;i<n;i++)
          {
          if(condition)
          DoSomething();
          else
          DoOtherthing();
          }

          循环2:
          if(condition)
          {
          for (i=0;i<n;i++)
          DoSomething()
          }
          else
          {
          for (i=0;i<n;i++)
          DoOtherthing();
          }
          问题1:循环1的优点和缺点。
          问题2:循环2的优点和缺点。

    分析:

    前者:
    优点:程序简洁
    条件判断出现在For里面,意味着,即使我在dosomething()或dootherthing()这2个函数中改变了condition的值,For循环也能正确执行我的意图,因为它在每次循环中都会重新检测conditon的值并针对condition的值做不同动作,所谓以不变应万变,这是难能可贵的.   
    缺点:多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
    如果condition一直未曾改变,我们可怜的if必须每次循环都判断一下condition的真假.牺牲了运行时效率.

    后者:
    优点:循环的效率高。只进行一次判断,运行时效率高.适合那种condition的值不会改变的情况.
    缺点:由于只在一开始进行一次判断,所以失去的改变condition的值的机会,也就是说,即使我在dosomething()中改变了condition的值为false,这个程序也不会改变它的判断,它依然执行着dosomething()的循环.我们不能随时更换我们需要进行的动作。这是牺牲了弹性。

    N较大时,建议采用后面这种写法,由于前者老要进行逻辑判断,打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。

    展开全文
  • 实现一 //单例模式一 public class Test{ private static Test test = new Test(); ...第二个线程也执行语句test = new Test(),在这种多线程环境下,可能会创建出来个对象。

    实现一

    //单例模式一
    public class Test{
      private static Test test = new Test();
      public Test(){};
      public static Test getInstance(){
        return test;
      }
    }
    • 优点:当类被加载的时候,已经创建好了一个静态的对象,因此,是线程安全的;
    • 缺点:这个对象还没有被使用就被创建出来了。

    实现二

    //单例模式二
    public class Test{
        private static Test test = null;
        private Test(){};
        public static Test getInstance(){
            if(test == null){
                test = new Test();
            }
            return test;
        }
    }
    • 优点:按需加载对象,只有对象被使用的时候才会被创建
    • 缺点:这种写法不是线程安全的,例如当第一个线程执行判断语句if(test = null)时,
      第二个线程执行判断语句if(test = null),接着第一个线程执行语句test = new Test(),
      第二个线程也执行语句test = new Test(),在这种多线程环境下,可能会创建出来两个对象。
    展开全文
  • MySQL种存储引擎: MyISAM和InnoDB 的区别和缺点

    千次阅读 多人点赞 2019-03-16 16:54:36
    MySQL种存储引擎: MyISAM和InnoDB 简单总结 Mysql 数据库主要以下几种引擎,介绍如下, 本文将主要介绍MyISAM和InnoDB这个引擎。 1.1 MyISAM和InnoDB简介 MyISAM是MySQL的默认数据库引擎(5.5版之前)...

    MySQL两种存储引擎: MyISAM和InnoDB 简单总结

    Mysql 数据库主要有以下几种引擎,介绍如下,

    本文将主要介绍MyISAM和InnoDB这两个引擎。

    1.1 MyISAM和InnoDB简介

          MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的 ISAM (Indexed Sequential Access Method:有索引的顺序访问方法)所改良。虽然性能极佳,而且提供了大量的特性,包括全文索引、压缩、空间函数等,但MyISAM不支持事务和行级锁,而且最大的缺陷就是崩溃后无法安全恢复。

          不过,5.5版本之后,MySQL引入了InnoDB(另一种数据库引擎),以强化参考完整性与并发违规处理机制,后来就逐渐取代MyISAM。与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能,类似于PostgreSQL。目前InnoDB采用双轨制授权,一是GPL授权,另一是专有软件授权。

          现在大多数时候我们使用的都是InnoDB存储引擎,但是在某些情况下使用MyISAM更好,比如:MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。 在数据库做主从分离的情况下,经常选择MyISAM作为主库的存储引擎(最后一句有待验证,因为主库负责对外提供写服务,从库对外提供读服务) 

    1.2 MyISAM特点

    • 不支持行锁(MyISAM只有表锁),读取时对需要读到的所有表加锁,写入时则对表加排他锁;
    • 不支持事务
    • 不支持外键
    • 不支持崩溃后的安全恢复
    • 在表有读取查询的同时,支持往表中插入新纪录
    • 支持BLOB和TEXT的前500个字符索引,支持全文索引
    • 支持延迟更新索引,极大地提升了写入性能
    • 对于不会进行修改的表,支持 压缩表 ,极大地减少了磁盘空间的占用

    补充概念:

    Mysql的行锁和表锁( 锁是计算机协调多个进程或纯线程并发访问某一资源的机制) 
    表级锁: 每次操作锁住整张表。开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低; 
    行级锁: 每次操作锁住一行数据。开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高;


    1.3 InnoDB特点

    • 支持行锁,采用MVCC来支持高并发,有可能死锁
    • 支持事务
    • 支持外键
    • 支持崩溃后的安全恢复
    • 不支持全文索引

    1.4 二者的常见对比

    • count运算上的区别: 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存。
    • 是否支持事务和崩溃后的安全恢复: MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
    • 是否支持外键: MyISAM不支持,而InnoDB支持。

    总之,MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB是不错的选择。如果你的数据量很大(MyISAM支持压缩特性可以减少磁盘的空间占用),而且不需要支持事务MyISAM是最好的选择。
     

    1.5、MyISAM和InnoDB两者之间具体区别如下:

    简单梳理如下:
    1) 事务支持
    MyISAM不支持事务,而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。

    MyISAM是非事务安全型的,而InnoDB是事务安全型的,默认开启自动提交,宜合并事务,一同提交,减小数据库多次提交导致的开销,大大提高性能。

    2) 存储结构
    MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
    InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。

    3) 存储空间
    MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。

    静态表:表中的字段都是非变长字段,这样每个记录都是固定长度的,优点存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多(因为存储时会按照列的宽度定义补足空格)ps:在取数据的时候,默认会把字段后面的空格去掉,如果不注意会把数据本身带的空格也会忽略。

    动态表:记录不是固定长度的,这样存储的优点是占用的空间相对较少;缺点:频繁的更新、删除数据容易产生碎片,需要定期执行OPTIMIZE TABLE或者myisamchk-r命令来改善性能

    压缩表:因为每个记录是被单独压缩的,所以只有非常小的访问开支

    参考:https://blog.csdn.net/qq_34417408/article/details/80957620

    InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

    4) 可移植性、备份及恢复
    MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
    InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。

    5) 事务支持
    MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
    InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。

    6) AUTO_INCREMENT
    MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
    InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。

    7) 表锁差异
    MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
    InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

    MyISAM锁的粒度是表级,而InnoDB支持行级锁定。简单来说就是, InnoDB支持数据行锁定,而MyISAM不支持行锁定,只支持锁定整个表。即MyISAM同一个表上的读锁和写锁是互斥的,MyISAM并发读写时如果等待队列中既有读请求又有写请求,默认写请求的优先级高,即使读请求先到,所以MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。因为MyISAM是锁表,所以某项读操作比较耗时会使其他写进程饿死。

    8) 全文索引
    MyISAM:支持(FULLTEXT类型的)全文索引
    InnoDB:不支持(FULLTEXT类型的)全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。

    全文索引是指对char、varchar和text中的每个词(停用词除外)建立倒排序索引。MyISAM的全文索引其实没啥用,因为它不支持中文分词,必须由使用者分词后加入空格再写到数据表里,而且少于4个汉字的词会和停用词一样被忽略掉。

    另外,MyIsam索引和数据分离,InnoDB在一起,MyIsam天生非聚簇索引,最多有一个unique的性质,InnoDB的数据文件本身就是主键索引文件,这样的索引被称为“聚簇索引”

    9) 表主键
    MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
    InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。InnoDB的主键范围更大,最大是MyISAM的2倍。

    10) 表的具体行数
    MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。
    InnoDB:没有保存表的总行数(只能遍历),如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。

    11) CURD操作
    MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
    InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。

    12) 外键
    MyISAM:不支持
    InnoDB:支持

    13) 查询效率
    没有where的count(*)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,count(*)时它直接从计数器中读,而InnoDB必须扫描全表。

           所以在InnoDB上执行count(*)时一般要伴随where,且where中要包含主键以外的索引列。为什么这里特别强调“主键以外”?因为InnoDB中primary index是和raw data存放在一起的,而secondary index则是单独存放,然后有个指针指向primary key。所以只是count(*)的话使用secondary index扫描更快,而primary key则主要在扫描索引同时要返回raw data时的作用较大。MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。

            通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。

    MyISAM和InnoDB两者的应用场景:
    1) MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
    2) InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

    但是实际场景中,针对具体问题需要具体分析,一般而言可以遵循以下几个问题:
    -  数据库是否有外键? 
    -  是否需要事务支持? 
    -  是否需要全文索引? 
    -  数据库经常使用什么样的查询模式?在写多读少的应用中还是Innodb插入性能更稳定,在并发情况下也能基本,如果是对读取速度要求比较快的应用还是选MyISAM。 
    -  数据库的数据有多大? 大尺寸倾向于innodb,因为事务日志,故障恢复。

    ***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************

    参考:https://www.cnblogs.com/kevingrace/p/5685355.html

               https://blog.csdn.net/qq_34337272/article/details/80586450

    展开全文
  • 大家都知道一般常用种重载运算符的方式分别是: 1.作为成员函数重载运算符. 2.作为友元函数重载运算符. 这里我给个例子. 这里是DoubleA class DoubleA { public: DoubleA(){}; DoubleA(DoubleB m); //DoubleB ...
  • MySQL中种备份方法的缺点

    千次阅读 2016-07-28 16:27:33
    逻辑备份:mysqldump ...若磁盘驱动器故障而要复制原始文件时,此时将得到一个损坏的备份 缺点: 1、 必须数据库服务器完成逻辑工作,需要更多地cpu周期 2、 逻辑备份还原速度慢:需要MySQL加载...
  • C/S和B/S种架构的区别和缺点

    万次阅读 多人点赞 2018-03-31 23:38:35
    C/S和B/S种架构的区别和缺点一、C/S1、 概念:典型的层架构,全称Client/Server,客户端服务器端架构,,其客户端包含一个欧多个用户电脑上运行的程序,二服务器有两种:一种是数据库服务器,可短短通过数据库...
  • C/S和B/S种架构区别与缺点分析

    千次阅读 2018-11-02 14:44:57
    C/S和B/S,是再普通不过的...C/S 架构是一种典型的层架构,其全程是Client/Server,即客户端服务器端架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通...
  • 请简述以下个for 循环的缺点

    千次阅读 2014-05-17 14:41:06
    第一个: for (i=0; i { if (condition) DoSomething(); else DoOtherthing(); } 第二个:
  • 计算机网络拓扑结构:1、网状拓扑结构:网状拓扑结构,这种拓扑结构主要指各节点通过传输线互联连接起来,并且每一个节点至少与其他个节点相连·网状拓扑结构具有较高的可靠性,但其结构复杂,实现起来费用较高...
  • 种方案的缺点比较 学完了种分布式锁的实现方案之后,本节需要讨论的是 Redis 和 ZK 的实现方案中各自的缺点。 对于 Redis 的分布式锁而言,它以下缺点: 它获取锁的方式简单粗暴,获取不到锁直接不断...
  • 图的种存储结构各什么缺点

    千次阅读 2020-04-30 20:23:43
    图的种存储结构各什么缺点 邻接矩阵 优点:容易确定个顶点之前是否存在边,容易确定顶点的度 缺点:占用空间大(当顶点多边少的时候) 空间复杂度:n平方 邻接表: 优点:无向图邻接表容易求得顶点的度 ,节省空间 ...
  • 一、Android引入广播的意义Android广播机制最大的特点是只管发送,不管没有接收,也不管接收方怎么处理数据,这是它与普通方法的区别。事实上,Android广播机制是为了解决跨进程通讯。而这一点是直接调用方法所不...
  • 添加链接描述
  • C/S 架构是一种典型的层架构,其全程是Client/Server,即客户端服务器端架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的...
  • 1)第一种是常驻型(静态注册),也就是说当应用程序关闭后,如果信息广播来,程序也会被系统调用自动运行。 2)第二种不是常驻型广播(动态注册),也就是说广播跟随程序的生命周期。 注册...
  • 常见分类算法缺点

    千次阅读 2018-10-21 21:36:54
    本文主要回顾下几个常用算法的适应场景及其缺点! 机器学习算法太多了,分类、回归、聚类、推荐、图像识别领域等等,要想找到一个合适算法真的不容易,所以在实际应用中,我们一般都是采用启发式学习方式来实验。...
  • ... 下表是 MODBUS ASCII ... 从上表的比较我们可以看到,MODBUS的ASCII...,所以RTU方式下个字节间传输间隔时间要求。MODBUS 的ASCII和RTU种协议的这一区别可能决定某些应用场合只能选用其中一种协议。
  • sso单点登录种方案与缺点

    千次阅读 2018-01-18 09:24:54
    1中间件集群:在资源子网中进行广播的方式,实现session复制,这种方式的缺点是,不能跨通信子网实现sso。并且在局域网中,中间件的数量过多,容易产生网络风暴,占用网络资源。推荐配置条件:服务器(tomcat)数量...
  • 线性表的缺点

    千次阅读 2019-05-29 21:31:06
    线性表顺序存储结构的缺点 优点: 无需为表示表中元素之间的逻辑关系而增加额外的存储空间 可以快速地存取表中任一位置的元素 缺点: 插入删除操作需要移动大量元素 当线性表长度变化较大时,难以确定存储空间的...
  • 1、顺序存储 优点: 在结点等长时可以随机存取 存储密度高节省存储空间 用结点的物理次序反映结点之间的逻辑关系 缺点: ...插入和删除结点时要移动大量的结点 ...检索必须沿链进行,不能随机存取
  • 个for/if循环的缺点

    千次阅读 2014-05-22 20:28:40
    1.白盒测试方法中的代码检查法需要重点考虑代码的执行效率,阅读以下个循环,回答问题1和问题2。  循环1:  for (i=0;i  {  if(condition)  DoSomething();  else  DoOtherthing();
  • AsyncTask缺点(种线程池)

    千次阅读 2016-08-04 10:02:33
    AsyncTask种线程池  http://bbs.51cto.com/thread-1114378-1.html (API 3.0以后): 1.THREAD_POOL_EXECUTOR, 异步线程池 使用 首先创建一个继承自AsyncTask的MyAsyncTask类,然后调用 ...
  • 并发编程的缺点

    万次阅读 多人点赞 2019-10-03 21:50:50
    并发编程的缺点 Java并发编程是整个Java开发体系中最难以理解,但也是最重要的知识点之一,因此学习起来比较费劲,从而导致很多人望而却步,但是无论是职场面试还是高并发高流量的系统的实现都离不开并发编程,...
  • 在for循环中,循环控制变量的初始化和修改都放在语句头部分,形式较简洁,且特别适用于循环次数已知的情况。在while循环中,循环控制变量的初始化一般放在...种形式各优点,但它们在功能上是等价的,可以相互转换。
  • 找出个List集合重复的元素

    万次阅读 热门讨论 2019-02-13 20:26:56
    前几天,个同事问我说怎么找出个List集合中重复的元素,我当时就说一个集合在外面循环,一个集合在内循环,如果个元素相等了,就找出来了,我回来一想还是不对,要是数据非常多,这样循环下去,服务器会卡死的...
  • package com.storge; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.Statement; import org.junit.Test;... *jdbc的批处理有两种机
  • 代码的种命名方法:驼峰命名、匈牙利命名(缺点) 一、骆驼命名法:  小驼峰法(camel方法)变量一般用小驼峰法标识。  第一个单词以小写字母开始;第二个单词的首字母大写或每一个单词的首字母都采用大写...
  • 自己的方向是电力系统多目标优化,其中就要用到pareto最解,多目标求解就会筛选出一个相对较的解的集合,在这个集合里就要用到pareto找出相对的解...1:解A优于解B(解A强帕累托支配解B)假设现在有两个目标函数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 626,301
精华内容 250,520
关键字:

两有两优