猿辅导一面

  1. 自我介绍

  2. Java中Synchronized是怎么实现?
    Synchronized修饰方法时:修饰普通方法锁的是当前的实例,修饰静态方法锁的是这个类。当方法调用时,调用指令将会检查该方法是否被设置acc_synchronized访问标志:flags:acc_public 和 acc_synchronized。
    当synchronized修饰代码块的时候,锁的的是括号里面的对象。这种情况是用monitor和monitorexit指令来实现同步的,进入monitorenter指令后,线程将持有Monitor对象,退出moinorenter指令后,线程将释放该Monitor对象。

  3. Synchronized修饰普通方法,代码块,静态方法都是锁的那些对象。

  4. Java对象头里面都有什么
    一个对象的内存结构包括:运行时元数据、类型指针、数据类型、对齐填充。
    运行时元数据主要是包括:哈希值,gc分带年龄,锁状态标志等
    类型指针:是对方法区中类元信息的引用。
    实例数据:真实记录一个对象包含的数据,比如说一个person对象,里面可能包含年龄、性别、身高等等,其中数据为字符串的,要引用到字符串常量池。
    对齐填充:填充部分仅起到占位符的作用, 原因是HotSpot要求对象起始地址必须是8字节的整数,假如不是,就采用对齐填充的方式将其补齐8字节整数倍,那么为什么是8呢?原因是64位机器能被8整除的效率是最高的。

  5. Java锁升级的过程?
    锁升级过程主要依赖于对象头的Mark Word中锁的标志位和释放偏向锁标志位。Synchronized锁就是从偏向锁开始的,随着竞争的激烈偏向锁升级到轻量级锁最终升级到重量级锁。

  • 偏向锁主要是为了用来优化同一线程多次申请同一个锁的竞争。当一个线程再次访问这个同步代码或方法时,该线程只需去对象头的 Mark Word 中去判断一下是否有偏向锁指向它的(线程) ID,无需再进入 Monitor 去竞争对象了。一旦出现其它线程竞争锁资源时,偏向锁就会被撤销。
  • 轻量级锁:当有另外一个线程竞争获取这个锁时,发现对象头 Mark Word 中的线程 ID 不是自己的线程 ID,就会进行 CAS 操作获取锁。获取成功,直接替换Mark Word 中的线程 ID 为自己的 ID,该锁会保持偏向锁状态;如果获取锁失败,代表当前锁有一定的竞争,偏向锁将升级为轻量级锁。轻量级锁适用于线程交替执行同步块的场景,绝大部分的锁在整个同步周期内都不存在长时间的竞争。
  • 自旋锁:通过自旋方式不断尝试获取锁,从而避免线程被挂起阻塞。在锁竞争不激烈且锁占用时间非常短的场景下,自旋锁可以提高系统性能。一旦锁竞争激烈或锁占用的时间过长,自旋锁将会导致大量的线程一直处于 CAS 重试状态,占用 CPU 资源,反而会增加系统性能开销。
  • 重量级锁:自旋锁重试之后如果抢锁依然失败,同步锁就会升级至重量级锁。
  1. Java中中断和异常的区别?恢复现场的流程。

  2. 线程池的主要参数
    ThreadPoolExecutor的主要参数
    corePoolSize (线程池基本大小)
    maximumPoolSize(线程池最大大小)
    keepAliveTime(线程存活保持时间)
    workQueue(任务队列):用于传输和保存等待执行任务的阻塞队列
    threadFactory(线程工厂):用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)。
    handler(线程饱和策略):当线程池和队列都满了,再加入线程会执行此策略。

  3. spring aop和IOC的实现原理。
    Spring aop
    概念:那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
    在spring中主要是基于动态代理来做的,有以下两种实现方式:

  • 基于jdk的proxy进行代理
  • 基于cglib的字节码增强的方式
    Spring IOC
    IOC(控制反转,别名也叫依赖注入)就是依赖倒置原则的一种代码设计思路。就是把原先在代码里面需要实现的对象创建、对象之间的依赖,反转给容器来帮忙实现。
    Spring IOC容器通过xml,注解等其它方式配置类及类之间的依赖关系,然后通过反射机制完成了对象的创建和依赖的管理注入。
  1. springMVC的执行流程
    1.Tomcat在启动时加载解析web.xml,找到spring mvc的前端总控制器DispatcherServlet,并且通过DispatcherServlet来加载相关的配置文件信息。

2.DispatcherServlet接收到客户端请求,找到对应HandlerMapping,根据映射规则,找到对应的处理器方法。

3.调用相应处理器中的处理方法,处理该请求后,会返回一个ModelAndView对象。

4.DispatcherServlet根据得到的ModelAndView中的视图对象,找到一个合适的ViewResolver(视图解析器),根据视图解析器的配置,DispatcherServlet将要显示的数据传给对应的视图,最后显示给用户。

  1. MySQL的索引数据结构?B和B+树的区别?

  2. Mysql 聚簇索引和非聚簇索引的区别?

  3. 给一个数组,在里面找到任意一个波峰。返回其索引

public class FindPeak {
    public static void main(String[] args) {
        int[] nums = {1,3,2,4,5,6};
        System.out.println(findcrest(nums));
    }
 
    /**
     * 随机寻找一个波峰
     * @param nums
     * @return
     */
    public static  int findcrest(int[] nums){
        int left=0;
        int right = nums.length-1;
        int n = nums.length;
        while (left <= right){
            int mid = (left + right) /2;
            if(mid ==0){
                left =1;
                continue;
            }
            if(mid == n-1){
                right = n-2;
                continue;
            }
            if(nums[mid] >nums[mid-1] && nums[mid] > nums[mid+1]){
                return mid;
            }else if(nums[mid] < nums[mid-1]){
                right = mid -1;
            }else {
                left = mid+1;
            }
        }
        return -1;
    }
}

你可能感兴趣的:(面试,java,mysql,jvm)