• JAVA 面试笔记


    java中的代理

    • 静态代理
    • JDK动态代理
    • Cglib代理

    设计模式

    • 工厂模式
    • 单例模式
    • 适配器模式
    • 观察者模式
    • 策略模式
    • 代理模式

    spring-cloud组件

    • Netflix Eureka 服务发现
    • Netflix Ribbon 负载均衡
    • Netflix Hystrix 断路器
    • Netflix Zuul 网关
    • Spring Cloud Config 分布式配置

    事务四大特性

    • A:原子性(Atomicity)
    • C:一致性(Consistency)
    • I:隔离性(Isolation)
    • D:持久性(Durability)

    分布式事务

    CAP
    • C (一致性):对某个指定的客户端来说,读操作能返回最新的写操作。对于数据分布在不同节点上的数据上来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
    • A (可用性):非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回50,而不是返回40。
    • P (分区容错性):当出现网络分区后,系统能够继续工作。打个比方,这里个集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。
    BASE

    BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写。是对CAP中AP的一个扩展

    • 基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。
    • 软状态:允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是CAP中的不一致。
    • 最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。

    BASE解决了CAP中理论没有网络延迟,在BASE中用软状态和最终一致,保证了延迟后的一致性。BASE和 ACID 是相反的,它完全不同于ACID的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。

    创建对象的四种方式

    • new
    • clone
    • 反射
    • 序列化

    Redis穿透

    当反复查数据库和缓存中都没有的值的时候会出现穿透

    -> 将查不到的值在缓存中设置为null

    Redis雪崩

    当Redis中key同一时间大量失效,会造成雪崩

    -> 设置随机数,避免同一时间失效

    HashCode 和 equals

    重现equals时候必须重写HashCode

    线程池常用参数

    • corePoolSize:核心线程数量,会一直存在,除非allowCoreThreadTimeOut设置为true
    • maximumPoolSize:线程池允许的最大线程池数量
    • keepAliveTime:线程数量超过corePoolSize,空闲线程的最大超时时间
    • unit:超时时间的单位
    • workQueue:工作队列,保存未执行的Runnable 任务
    • threadFactory:创建线程的工厂类
    • handler:当线程已满,工作队列也满了的时候,会被调用。被用来实现各种拒绝策略。

    ArrayList

    可以用Collections.synchronizedList将ArrayList转化成线程安全的list
    实例化的时候不指定初始化长度将会分配一个长度为0的数组

    /**
     * 空的数组
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
    
    
    /**
     * 构造方法
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
    

    初始化大小为10

    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;
    
    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
    private void ensureCapacityInternal(int minCapacity) {
            ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    
    
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
    
        // overflow-conscious code
        // 当数据长度大于数组长度时扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 扩容到之前的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    

    comparable 和 comparator

    comparable接口需要类进行实现,需要实现compareTo方法才能排序,又称自然排序
    comparator接口单独实现就好,需要实现compare方法,在java1.8中可以使用lambda表达式简化代码

    fail-fast 保护机制

    在使用for in或者forEach对数组进行修改会出发fail-fast保护机制,原因是在修改之后调用了checkForComodification.
    可以使用迭代器就可以避免fail-fast保护机制

    单例模式

    • 懒汉式
    
    /**
     *  懒汉式单例模式在第一次调用的时候进行实例化。
     */
    public class Singleton1 {
    
        /**
         * volatile 关键字避免重排
         */
        private static volatile Singleton1 instance = null;
    
        private Singleton1() {
        }
    
        /**
         * 1、适用于单线程环境(不推荐)
         */
        public static Singleton1 getInstanceA() {
            if (null == instance) {
                instance = new Singleton1();
            }
            return instance;
        }
    
        /**
         * 2、适用于多线程环境,但效率不高(不推荐)
         */
        public static synchronized Singleton1 getInstanceB(){
            if (instance == null) {
                instance = new Singleton1();
            }
            return instance;
        }
    
        /**
         * 3、双重检查加锁(推荐)
         */
        public static Singleton1 getInstanceC() {
            // 先判断实例是否存在,若不存在再对类对象进行加锁处理
            if (instance == null) {
                synchronized (Singleton1.class) {
                    if (instance == null) {
                        instance = new Singleton1();
                    }
                }
            }
            return instance;
        }
    }
    
    • 饿汉式
    /**
     * 饿汉式单例类:在类初始化时,已经自行实例化。
     */
    public class Singleton2 {
    
        private static final Singleton2 instance = new Singleton2();
    
        private Singleton2() {
        }
    
        public static Singleton2 getInstance() {
            return instance;
        }
    }
    
    • 静态内部类
    /**
      *加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造
      *器、静态方法等)被调用时发生。 由于在调用 StaticSingleton.getInstance() 的时候,
      *才会对单例进行初始化,而且通过反射,是不能从外部类获取内部类的属性的;由于静态内部类的特
      *性,只有在其被第一次引用的时候才会被加载,所以可以保证其线程安全性。
      *总结:
      *优势:兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。
      *劣势:需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久带的对象
     *
     */
    public class StaticSingleton {
        /**
         * 私有构造方法,禁止在其他类中创建实例
         */
        private StaticSingleton() {
        }
    
        /**
         * 获取实例
         */
        public static StaticSingleton getInstance() {
            return StaticSingletonHolder.instance;
        }
    
        /**
         * 一个私有的静态内部类,用于初始化一个静态final实例
         */
        private static class StaticSingletonHolder {
            private static final StaticSingleton instance = new StaticSingleton();
        }
    
        /**
         * 方法A
         */
        public void methodA() {
        }
    
        /**
         * 方法B
         */
        public void methodB() {
        }
    
        public static void main(String[] args) {
            StaticSingleton.getInstance().methodA();
            StaticSingleton.getInstance().methodB();
        }
    }
    
    • 枚举
    /**
     *创建枚举默认就是线程安全的,所以不需要担心double checked locking,而且还能防止反序列
     *化导致重新创建新的对象。保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量)。
     */
    public class Singleton {
        public static void main(String[] args) {
            Single single = Single.SINGLE;
            single.print();
        }
    
        enum Single {
            SINGLE;
    
            private Single() {
            }
    
            public void print() {
                System.out.println("hello world");
            }
        }
    }
    

    排序算法

    • 快速排序
    • 冒泡排序
    • 希尔排序
    • 归并排序

    查找算法

    • 顺序查找
    • 二分查找
    • 插值查找
    • 斐波那契查找
    • 二叉树查找
    • 平衡查找树之2-3查找树
    • 平衡查找树之红黑树
    • B树
    • B+树

    数据结构

    • 数组
    • 链表
    • Hash表

    HashMap

    LoadFactor(加载因子)默认为0.75,当加载因子越大,对空间利用就越充分,链表的就会越长,所以查询效率也就越低。反之,查询效率越高,但Hash表的数据就越疏松,空间也更加浪费。

  • 相关阅读:
    DB2基本语句操作
    makefile简析与例子
    io多路复用epoll归纳
    Selenium 3----设置元素等待
    Selenium 3----获取断言信息
    Selenium 3----鼠标、键盘操作常用方法
    Selenium 3----WebDriver常用方法
    算法时间复杂度求解
    Selenium 3----控制浏览器操作
    操作系统基础知识学习
  • 原文地址:https://www.cnblogs.com/97jay/p/12511047.html
Copyright © 2020-2023  润新知