高频面试题

==和equals区别?

==: ==比较的是栈中的内容, 基本数据类型比较的是值, 引用类型比较的是内存地址
equals: Object的equals方法是用==实现的, 用法一样, 但是通常会重写该方法, 比如string重写后, 比较的是值内容
 

hashCode和equal关系?

hashCode相当于对象的指纹信息, 但是java做不到这么绝对, 但是还是能提前做一下判断

  • 如果两个对象hashCode不同, 肯定是两个不同对象
  • 如果两个对象hashCode相同, 不一定同一个对象
  • 如果两个对象相等, 他们hashCode一定相同

equals默认是比较引用地址, 通常会重写

在java一些集合的实现, 判断对象是否相等, 会先比较两个对象的hash, 如果hash不同, 直接认定两个对象不同, 如果hash相同, 再调用equals进一步比较, 因为equals相对hash比较重
如果重写了equals, 通常也要重写hash

ArrayList和LinkList区别?

ArrayList底层结构是数组, 是一块连续的内存空间, 对内存要求更高. 随机访问性能更高, 中间增删改性能差, 需要拷贝后面所有元素
LinkList底层结构是链表, 增删改性能差, 查询只能依次遍历下一个节点.LinkList还实现了Deque, 可以当做队列

ConcurrentHashMap扩容机制, jdk7和jdk8区别? 

JDK 1.7:

  • 线程安全: JDK 1.7中ConcurrentHashMap使用了分段锁(Segment)的机制。整个哈希表被分成多个段,每个段都拥有一个独立的锁。在进行读操作时,只需要锁住对应的段,其他段的读操作可以并发执行。但在进行写操作时,需要锁住所有段,保证线程安全。
  • 扩容策略:JDK 1.7 的扩容是通过段来实现的,每次只扩容一个段。在进行扩容时,首先创建一个新的段数组,然后将原有数组中的段逐个迁移到新数组中。

JDK 1.8:

  • 线程安全:JDK 1.8中, 使用CAS和synchronized同步块保证线程安全。相比1.7的分段锁,JDK1.8使用更细粒度的锁,对桶(buckets)进行加锁,而不是整个段。
  • 扩容策略: 当某个线程进行put时,如果发现ConcurrentHashMap正在进行扩容那么该线程一起进行扩容; 如果某个线程put时,发现没有正在进行扩容,则将key-value添加到ConcurrentHashMap中,然后判断是否超过阈值,超过了则进行扩容.ConcurrentHashMap是支持多个线程同时扩容的, 在转移元素时,先将原数组分组,将每组分给不同的线程来进行元素的转移,每个线程负责一组或多组的元素转移工作.

String, StringBuffer, StringBuilder区别?

  • String: 不可变, 如果尝试修改, 会生成新的字符串
  • StringBuffer: 可变, 线程安全
  • StringBuilder: 可变, 线程不安全, 效率更高, 单线程可用

范型extends和super区别

表示包括T在内的所有子类
表示包括T在内的所有T的父类

JDK,JRE,JVM之前区别?

  • JDK: JAVA标准开发包, 提供了编译,运行java程序需要的工具和资源, 包括java编译器, java运行时环境, 常用的java类库
  • JRE: JAVA运行时环境, 用来运行java字节码文件. JRE包括了JVM以及JVM工作需要的类库. 普通用户只需安装JRE来运行java程序, 开发必须按照JDK来编译和调试程序
  • JVM: JAVA虚拟机, JRE的一部分, 负责运行字节码文件

java中的异常体系?

所有异常都来自顶级父类Throwable

Throwable下有两个子类Exception和Error

  • Error: 表示系统层面非常严重的错误, 靠捕获异常解决不了, 比如java.lang.StackOverFlowError和Java.lang.OutOfMemoryError
  • Exception: 分为RuntimeException和非RuntimeException

Exception:

  • RuntimeException: 表示运行时异常, 异步是逻辑错误引起的, 比如NullPointerException、IndexOutOfBoundsException, 应该从代码层面尽量避免这类异常产生
  • 非RuntimeException: 非运行期异常, 也就是检查异常, 必须处理的异常, 如果不处理程序就不能检查通过. 如IOException、SQLException

链路翻转

比如一个链表, 1 > 2 > 3 > 4 > 5, 改成54321


public class FlipList {

    // 迭代
    public static Node iteraor (Node node) {
        Node prev = null, next;
        while (node != null) {
            next = node.next;
            node.next = prev;
            prev = node;
            node = next;
        }
        return prev;
    }


    public static void main(String[] args) {
        Node node5 = new Node(5, null);
        Node node4 = new Node(4, node5);
        Node node3 = new Node(3, node4);
        Node node2 = new Node(2, node3);
        Node node1 = new Node(1, node2);
        Node head = iteraor(node1);
        System.out.println(head);
    }

    static class Node{
        private int val;

        private Node next;


        public Node(int val, Node next) {
            this.val = val;
            this.next = next;
        }
    }
}

你可能感兴趣的:(java)