0


《剑指Offer》美团实习第一面(附答案)

2022面经,建议先收藏起来!保证用的到


1.Mysql隔离级别说一下

答:一共有4种隔离级别,分别是未提交读(Read Uncommitted)、提交读(Read Committed)、可重复度(Repeatable Read)和可串行化(Serializable)。

未提交读级别下,所有事务都可以看到其他未提交事务的执行结果,也就是可以读取未提交的数据,会造成脏读。

提交读级别下,一个事务只能读取到已经提交事务修改的数据,解决了脏读问题,但是会有不可重复读的问题。不可重复读说的是,比如A事务中读取2次数据,第一次读取后,B事务修改了数据并提交了事务,A事务第二次读取会和第一次不一样。

可重复度级别是Mysql默认的隔离级别,解决了不可重复读的问题,但是会有幻读的问题。幻读的意思是,比如A事务读取一定范围中的数据,B事务在这个范围内新增了数据,那么A事务再次读取这个范围数据时,会发现有新增行。

可串行化级别是最高的隔离级别,解决了幻读的问题。他是通过加锁,让一个事务执行完后才能进行下一个事务。在这个级别,可能导致大量的超时现象和锁竞争。

2.如何解决幻读的?

答:1.通过可串行化隔离级别。2.在可重复读的隔离级别下,通过多版本并发控制(MVCC)来解决幻读,不过只能解决快照读情况下的幻读,”当前读“还会造成幻读,使用next-key lock(间隙锁加行锁)来解决。

3.Mysql都有什么索引?

答:

聚簇索引:索引非叶子节点只存储索引列,叶子节点存储数据。

非聚簇索引:叶子节点保存的是主键值。

4.索引的底层数据结构?

答:使用的是B+树。

5.为什么走索引速度快?

答:因为查找数据的时候,不再需要进行全表扫描来获取需要的数据,而是从索引的根节点开始进行搜索,就像书的目录一样,快速的找到所需数据。

6.JVM运行时内存模型?

答:1.程序计数器,线程私有,用于代码执行

2.Java虚拟机栈。线程私有,存储方法相关的信息,如局部变量、方法入口等。一个方法从调用到结束,就对应一个栈帧从Java虚拟机栈的入栈和出栈的过程。

3.本地方法栈。线程私有,为使用到的native方法服务。

4.方法区。内存共享,存储已被虚拟机加载的类信息,常量,静态变量,也就是编译后的代码数据。

5.java堆。内存共享,存储对象实例和数组。

7.类加载的过程?

答:

1.加载。在内存中生成改类的Class对象,作为类数据的访问入口

2.验证。Class文件字节流信息符合要求。

3.准备。为类的静态变量分配内存,并初始化为默认值。

4.解析。将常量池中的符号引用替换为直接引用。(符号引用是一种描述符c里面的)

5.初始化。按顺序调用方法初始化数据。

6.使用

7.卸载

8.HashMap底层原理?

答:hashmap使用一个数组,数组的每个元素一个单向链表的节点,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就链接到同一hash值的元素的后面,他们在数组的同一位置,就形成了链表,同一个链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树。

超过原容量的0.75扩容。

链表长度>=8并且数组长度>=64转为红黑树,否则扩容。

红黑树节点数<=6转为链表。

9.头插法尾插法产生的问题

答:

JDK1.7中,HashMap的put方法采用的是头插法,在resize扩容时会形成环形链表,造成死循环。扩容时还可能造成数据丢失。

JDK1.8中,HashMap将put方法改成了尾插法,不会形成环链死循环,但是会造成数据覆盖。

10.手写双重校验锁的单例模式

class Singleton{
    private volatile static Singleton singleton;

    private Singleton(){}

    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

11.垃圾回收算法

答:

标记-清除法:

分为标记、清除两个阶段,首先标记出所有需要回收的对象,然后统一回收。

缺点:1.效率问题,两个阶段效率都不高。2.空间问题,产生大量控件碎片。

复制算法:

将内存按容量划分为大小相同的2块,每次只使用一块,当一块用完了,就将存活的对象复制到另一块。然后把当前清空。

缺点:把内存缩小了一半。

商业虚拟机都采用这种,不过是将内存划分为3块,一般是8:1:1,回收时,将存活的对象从Eden和其中一块存活区复制到另一块存活区。当存活区空间不够,就需要老年代了。

标记整理算法:

当对象存活率高的时候,就需要进行较多的复制,效率会变低。所以老年代不适合。标记出需要清理的对象,然后让存活的对象向一端移动,然后清理掉端边界以外的内存。

分代回收算法:

将内存划分为新生代和老年代,新生代只有少量对象存活,采用复制算法,老年代采用标记整理算法。

12.垃圾收集器

Serial收集器(串行收集器)

新生代收集器,复制算法。一个单线程收集器,在进行垃圾回收时,必须暂停其他工作线程。

ParNew收集器

新生代收集器,复制算法。上一个收集器的多线程版

Parallel Scavenge收集器

新生代收集器,采用复制算法。也是并行的多线程收集器。注重高吞吐量

特点:gc动态调节,可以自动调节新生代内存大小比例。

Serial Old 收集器

是serial 收集器的老年代版本,采用标记整理算法。

Parallel Old 收集器

老年代,标记整理算法。是Parallel Scavenge收集器的老年代版本。注重高吞吐量,平衡每次回收时间和回收间隔。

CMS收集器

一种以获取最短回收停顿时间为目标的收集器。老年代收集器

特点:基于标记-清除算法实现。并发收集、低停顿

工作过程:

1:初始标记 标记GC Roots能直接到的对象。速度很快但是仍存在Stop The World问题

2:并发标记 进行GC Roots Tracing 的过程,找出存活对象且用户线程可并发执行。

3:重新标记 为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。仍然存在Stop The World问题。

4:并发清理 对标记的对象进行清除回收。

缺点:

  • 对CPU资源非常敏感。
  • 无法处理浮动垃圾,可能出现Concurrent Model Failure失败而导致另一次Full GC的产生。(因为使用并发标记,所以得预留一部分空间,如果空间不足用户线程,就会出现。)
  • 因为采用标记-清除算法所以会存在空间碎片的问题,导致大对象无法分配空间,不得不提前触发一次Full GC。

G1收集

新生代和老年代收集器

把这个内存划分成了大小相等的区域,每个区域都会有一个对应的Rememberd set,会记录当前区域中的对象被引用记录。

特点:管理整个堆、空间整合,不会产生碎片、可预测的停顿、并行与并发

工作过程:

1.初始标记,仅标记GC Roots能直接到的对象

2.并发标记:从GC Roots开始对堆中对象进行可达性分析,找出存活对象。

3.最终标记:为了修正在并发标记期间因用户程序执行而导致标记产生变化的那一部分标记记录。

4.筛选回收:对各个区的回收价值和成本进行排序,根据用户所希望的回收时间来指定回收计划。

特点:不会产生碎片。可预测停顿。

13.线程池了解吗,如何创建线程池,线程加入线程池的过程

答:了解,顾名思义,管理线程的池子,降低线程创建和销毁线程造成的开销,有任务时,可以直接从线程池中拿线程。

创建线程池:

无论是创建何种类型线程池(FixedThreadPool、CachedThreadPool...),均会调用ThreadPoolExecutor构造函数,可以通过这个函数的参数来初始化线程池,

corePoolSize:核心线程最大数量,通俗点来讲就是,线程池中常驻线程的最大数量

maximumPoolSize:线程池中运行最大线程数(包括核心线程和非核心线程)

keepAliveTime:线程池中空闲线程(仅适用于非核心线程)所能存活的最长时间

unit:存活时间单位,与keepAliveTime搭配使用

workQueue:存放任务的阻塞队列

handler:线程池拒绝策略

线程加入线程池过程:

addWorker 方法

1.2层for循环,第一层判断线程池状态,如果正在停止,并且没有剩余任务,添加失败。

2.如果判断通过,进入第二层循环。判断线程数量是否超过限制,可以传一个参数,超过核心线程数,还是最大线程数。如果超过,添加失败。

3.没有超过,尝试增加线程容量,如果失败,校验线程池状态是否改变,如果改变,那么回到第一层循环。如果没有改变,回到第二层循环。

4.如果容量增加成功。那么增加线程,并且启动新加入的线程。

13.讲讲AQS

答:AQS(AbstractQueuedSynchronizer)是一个抽象类,不可以被实例化。它内部提供了一个FIFO的等待队列,用于多个线程等待一个事件(锁)。它有一个重要的状态标志——state,该属性是一个int值,表示对象的当前状态(如0表示lock,1表示unlock)。

JDK通过这个类,实现了CountDownLatch、ReentrantLock等锁。

14.TCP三次握手

答:

第一次握手:建立连接时,客户端向服务器发送请求,SYN标志位置为1,seq随机选择一个初始序号,并进入SYN_SEND状态,等待服务器确认。

第二次握手:服务器收到请求,向客户端回复,SYN标志=1,seq随机选择一个初始序号,ack确认号等于客户端的seq+1,此时服务器进入SYN_RECV状态。

第三次握手:客户端收到服务器的消息,校验过后,向服务器发送消息,SYN置为0,ack确认号等于服务端seq+1,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。第三次握手阶段客户端就可以携带要发送的数据了。

完成三次握手,客户端与服务器开始传送数据。

15.TCP与UDP的区别

  1. TCP 是面向连接的,UDP 是面向无连接的
  2. UDP程序结构较简单
  3. TCP 是面向字节流的,UDP 是基于数据报的
  4. TCP 保证数据正确性,UDP 可能丢包
  5. TCP 保证数据顺序,UDP 不保证

16.判断链表是否有环

答:思路是,快慢指针,慢指针走一步,快指针走2步,如果有环,必定相遇。

    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }

17.数组中第K小的数

答:思路是,利用倒序的堆排序,每一次调整最大堆,都会获取到第k个小的数。

class Solution {
    public int findKthmin(int[] nums, int k) {
        int len = nums.length;
        for(int i = len/2-1;i>=0;--i){
            maxHeap(nums, i, len-1);
        }
        for(int i = len-1;i>=len-k;--i){
            int temp = nums[0];
            nums[0] = nums[i];
            nums[i] = temp;
            maxHeap(nums, 0, i-1);
        }
        return nums[len-k];
    }

    private void maxHeap(int[] nums, int post, int len){
        int temp = nums[post];
        int child = 2*post+1;
        while(child <= len){
            if(child <len && nums[child] > nums[child+1]){
                ++child;
            }
            if(temp <= nums[child]){
                break;
            }
            nums[post] = nums[child];
            post = child;
            child = 2*post+1;
        }
        nums[post] = temp;
    }
}

建议收藏,高频面试题,造完用得到

文章中只有答案,↓↓​​​​​​​↓​​​​​​​公众号↓​​​​​​​↓​​​​​​​↓ ​​​​​​​会推送面试题的详细原理以及过程

标签: java 后端 面试

本文转载自: https://blog.csdn.net/LookOutThe/article/details/123591445
版权归原作者 七号公园的忧伤 所有, 如有侵权,请联系我们删除。

“《剑指Offer》美团实习第一面(附答案)”的评论:

还没有评论