• 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);  
        }  
    }  
  • 相关阅读:
    UITabbarItem只显示图标
    [转]translatesAutoresizingMaskIntoConstraints详解
    [转载]podfile语法
    获取数组NSArray元素的className
    HTTP的FormData和Payload的传输格式
    WCDB错误"No matching constructor for initialization of 'WCTColumnBinding'"
    UIStakView的添加与移除
    为什么说Python采用的是基于值的内存管理模式?
    PostgreSQL数据库
    标准库 time
  • 原文地址:https://www.cnblogs.com/chuanqi1995/p/10107369.html
Copyright © 2020-2023  润新知