zoukankan      html  css  js  c++  java
  • Java面试总结(2018

    1.缓存穿透,缓存雪崩,缓存击穿解决方案分析

    1)缓存穿透就是比如拿Redis数据库来说,它是一个键值对,有可能用户查询某个数据的时候没有查到这个key,就跑到数据库中去查了,我们设置缓存的目的就是为了不让请求去数据库中查,但是穿透呢,没查到key会自动去数据库中去查了。这种透过缓存去数据库中查就叫缓存穿透。一般我们把那些空的也存到缓存中,这样就不会穿透缓存了,一般发生的也不是特别多。

    2)缓存雪崩就是在高并发的情况下,因为在缓存中有缓存的时间,同一时间下有好多数据失效了,这样在高并发访问量比较大的时候呢,同时又去数据库查,这样数据库的压力就很大,有可能就挂掉了,这就是缓存雪崩。一般我们给实效时间设置点随机数,不让它一起失效。

    3)缓存击穿就是指某一个数据失效的话,这个数据访问的也比较多,比如说淘宝在0点的时候某个数据实效了,这个时候又有很多用户提前预购了,在0点的时候去抢它,这个时候就会造成击穿的效果。一般这种击穿很难处理,因为你也不知道这个数据会不会用到,所以我也不是太清楚怎么处理。

    2.缓存数据和数据库数据一致性问题

    1)用MQ模式的消息队列,保证串行。

    2)或者用Id先查询数据,保证每次操作数据是同一个,然后再设置队列。如果分布式的话就再加个服务Id,保证同一个服务。

    3.设计模式

    Java中有23种设计模式,常见的设计模式有:

    1)单列模式

    一句话总结:一个类在Java虚拟机中只有一个对象,并提供全局访问点。

    生活中例子:太阳,月亮,国家主席等。

    解决什么问题:对象的唯一性,性能浪费太多。

    项目里面怎么用:数据库连接对象,属性配置文件的读取对象。

    模式结构:分为懒汉模式和饿汉模式(如果考虑性能问题的话,就使用懒汉模式,因为懒汉模式是在方法里面进行初始化的,构造器私有化,对外提供方法加同步关键字)。

    框架里面的使用:Struts1的Action。

    Jdk里面使用:java.lang.Runtime#getRuntimejava.awt.Desktop#getDesktop。

    懒汉模式:就是说比较懒,在用到它的时候它才去创建对象(懒汉模式线程不安全,懒汉加载慢,但是在内存作用域短,节省空间)。

    /*
     * 懒汉模式
     * 懒汉线程不安全
     * 懒汉加载慢,但是在内存作用域短,节省空间
     */
    public class SingletonA {
        
        //SinglettonA的唯一实例
        private static SingletonA instance = null;
        
        //将构造函数私有,防止外界构造SingletonA实例
        private SingletonA() {
            
        }
        
        //获取SingletonA的唯一实例,用synchronized关键字保证某一时刻只有一个线程调用此方法
        public static synchronized SingletonA getInstance(){
            //如果instance为空,便创建一个新的SingletonA实例,否则,返回已有的实例
            if(instance == null){
                instance = new SingletonA();
            }
            return instance;
        }
        
        public void print(){
            System.out.println("我是懒汉模式!");
        }
        
        public static void main(String[] args) {
            SingletonA s1 = SingletonA.getInstance();
            SingletonA s2 = SingletonA.getInstance();
            System.out.println(s1 == s2);
        }
    }

    饿汉模式:就是说比较饿,在用到它的时候它早早的就加载完对象了(饿汉模式线程安全,饿汉加载快,但是在内存中作用域长,不节省空间)。

    /*
     * 饿汉模式
     * 饿汉线程安全
     * 饿汉加载块,但是在内存中作用域长, 不节省空间
     */
    public class SingletonB {
        
        //SingletonB的唯一实例
        private static SingletonB instance = new SingletonB();
        
        //将构造函数私有,防止外界构造SingletonB实例
        private SingletonB() {
            
        }
        //获取SingletonB的实例
        public static SingletonB getInstance() {
            
            return instance;
        }
        public void print() {
            System.out.println("我是饿汉模式");
        }
        public static void main(String[] args) {
            SingletonB s1 = SingletonB.getInstance();
            SingletonB s2 = SingletonB.getInstance();
            System.out.println(s1 == s2);
        }
        
    }

    2)Factory(简单的工厂模式)

    一句话总结:用一个方法来代替new关键字。

    生活中的例子:制衣厂,面包厂等生产厂。

    解决什么问题:对象产生过多,或者经常有子类替换生成。

    项目里面怎么用:对于经常生成的对象,或者父子类替换的对象。

    模式结构:写一个对外声明的方法,方法里面使用new关键字代替。

    框架里面使用:Spring的核心就是工厂模式。

    Jdk里面使用:newInstance。

    工厂模式代码:

    public class UserFactory {
        public static User createUser(int i){
            //如果输入的是1,就创建它的子类,否则就创建父类
            if(i == 1){
                return new Alices();
            }
            return new User();
        }
    }

    3)Proxy(代理模式)

    一句话总结:为其他对象提供一个代理,以控制对当前对象的访问。

    生活中的例子:房屋中介,婚姻介绍所。

    解决什么问题:不能直接访问该对象,或者太大的资源耗费多。

    项目里面怎么用:权限,或者大对象的访问权限。

    模式结构:代理类和被代理类实现同一个接口,用户访问的时候先访问代理对象,然后让代理对象去访问被代理对象。

    框架里面使用:Spring里面的AOP实现。

    Jdk里面使用:java.lang.reflect.Proxy。

    代理模式代码:

    创建一个接口:

    public interface SellHouse {  
        void sell(double money);  
    }  

    创建一个被代理类:

    public class Hoster implements SellHouse {  
        @Override  
        public void sell(double money) {  
            System.out.println("祝你居住愉快");  
        }  
    }  

    创建一个代理类:

    public class Medium implements SellHouse {  
        SellHouse hoster=new Hoster();  
        @Override  
        public void sell(double money) {  
            if(money>=1000){  
                hoster.sell(money);  
            }else{  
                System.out.println("你的价格太低了");  
            }  
        }  
    }  

    创建一个测试类:

    public class Renter {  
        public static void main(String[] args) {  
            SellHouse renter=new Medium();  
            renter.sell(500);  
        }  
    }  
  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/chuanqi1995/p/10107369.html
Copyright © 2011-2022 走看看