面试题

作者: 不积小流_无以成江海 | 来源:发表于2023-09-07 16:30 被阅读0次

前端部分:
1.setTimeOut函数里,时间设置为0代表什么意思,会不会立刻执行
会在队列最后添加一个事件,要等待其他任务事件处理完成才会处理。

2.== 和 === 的区别

3.相对定位和决定定位的区别:
    绝对定位:绝对定位是相对于元素最近的已定位的祖先元素(即是设置了绝对定位或者相对定位的祖先元素)。如果元素没有已定位的祖先元素,那么它的位置则是相对于最初的包含块(body)
    相对定位:相对定位是相对于元素在文档中的初始位置,在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间
    
4.鼠标悬停在一个div上时,修改div的背景颜色怎么实现


5.有两个div, 是父子关系, 怎么实现子div在父div里水平,垂直居中
    最优做法是flex布局:display: flex;align-items: center;justify-content: center;
    
6.JavaScript中find()和filter()的区别
    find()主要应用于查找第一个符合条件的数组元素
    filter()返回的是数组,数组内是所有满足条件的元素
    
7.let 与 var 的区别:
    var是函数作用域,而let是块作用域
    var可以允许重复声明相同的变量,后者会覆盖前者,let则不能重复声明相同的变量
    var声明的变量有变量提升特性,let声明则没有这个特性

8.const是什么
    声明常量时,一旦声明,常量的值就不能改变
    声明对象时,指向对象的内存地址不变,对象的内容可以改变
    
9.Promise的用法:
    Promise对象是一个构造函数,用来生成Promise实例
    const promise = new Promise(function(resolve, reject) {
      // ... some code

      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
    promise.then(function(value) {
      // success
    }, function(error) {
      // failure
    });

10.箭头函数里的this和普通函数的this的区别
    对于普通函数来说,内部的this指向函数运行时所在的对象,是动态的
    箭头函数它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的

数据库部分:

Mysql中的存储引擎有哪些
    InnoDB
    MyISAM
    Memory
    
InnoDB引擎与MyISAM引擎的区别 ?
    InnoDB引擎, 支持事务, 而MyISAM不支持。

    InnoDB引擎, 支持行锁和表锁, 而MyISAM仅支持表锁, 不支持行锁。

    InnoDB引擎, 支持外键, 而MyISAM是不支持的。
    
    索引方面:MyISam中索引和数据是分开存,InnoDB是都在一个文件
    
Mysql中索引的数据结构,这种结构有什么特点

哪些情况下会出现索引失效

什么是覆盖索引

什么是聚簇索引,什么是非聚簇索引

Mysql的事务隔离级别有哪些,默认级别是什么

Mysql事务原理
    redo.log + undo.log 实现了事务的一致性,原子性,持久性
    锁 + MVCC 实现了事务的隔离性

Mysql锁的分类
    表级锁
        表锁
            加锁:lock tables 表名... read/write
            释放锁:unlock tables / 客户端断开连接
        元数据锁
            加锁过程是系统自动控制
        意向锁
         
    行级锁
        行锁  :锁定单个行记录的锁
        间隙锁 :锁定索引记录间隙(不含该记录)
        临键锁 :同时锁住数据,并锁住数据前面的间隙Gap

微服务部分:

springboot中读取配置文件的顺序是什么 ps:下面的优先级顺序依次升高
    1.classpath/xxx.yml
    2.classpath/config/xxx.yml
    3.项目目录下/xxx.yml
    4.项目目录下/config/xxx.yml

springboot的自动装配原理是什么

Springboot构造函数逻辑:
    1.初始化一些变量
    2.把主类保存为primarySource
    3.推断应用类型
    4.实例化SpringFactoryInstance,并放入缓存
    5.获取初始化器和监听器
    6.推断主类

Springboot中run方法的逻辑:
    1.开始计时
    2.创建启动上下文
    3.设置无显示器也能启动
    4.获取监听器并启动
    5.保存启动参数【启动时传入】
    6.准备环境【Maven变量,类路径,配置文件等】
    7.忽略Bean信息
    8.打印Banner
    
    9.创建应用上下文
        创建BeanFactory
    10.准备上下文
        
    11.刷新上下文
        自动装配
    12.刷新上下文后置处理
        空方法
    13.结束计时
    
    14.调用runner
    

BeanFactory与FactoryBean的区别是什么

SpringBoot中Bean是如何创建的
    通过反射调用构造方法创建的

Springboot中Bean的生命周期是什么
    加载解析Bean定义--》实例化--》属性填充--》初始化--》销毁

SpringBoot如何解决循环依赖,为什么需要第三级缓存

Java基础部分:

1.创建对象有哪几种方式
    new
    反射
    clone
        clone方法执行的是浅拷贝
        在内存中开辟一块新的内存,基础变量是直接拷贝过去,引用对象是拷贝引用

2.八大数据类型
    int, short, char, long, byte, float, double, boolean, 

3.== 和 equals 的区别是什么?
    equals():用来检测两个对象是否相等,即两个对象的内容是否相等。
    ==:用于比较引用和比较基本数据类型时具有不同的功能
        基础数据类型:比较的是他们的值是否相等
        引用数据类型:比较的是引用的地址是否相同
    
    Integer a = 127; Integer b = 127;  a == b ?  128呢?
    
4.创建线程有哪几种方式
    继承Thread类
    实现Runnable
    实现Callable
    
    Runnable和Callable有什么区别
        Callable可以获取线程的返回值,能抛异常
        Runnable没有返回值,也不会抛异常

5.voliate关键字的作用
    内存可见性
    防止指令重排
    不保证原子性

6.Lock与Synchronized的区别,开发中该如何选择呢?
    synchronized是java中的关键字,底层采用的是objectMonitor
    synchronized可以写在需要同步的对象、方法或者是特定代的码块中
    synchronized只提供了非公平锁的实现
    synchronized自动释放锁
    
    lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断
    Lock可以通过trylock来知道有没有获取锁,而synchronized不能
    Lock需要手动释放锁,加锁,解锁都需要显示指定
    synchronized使用了object类的wait和notify进行等待和唤醒, lock使用了condition接口进行等待和唤醒(await和signal);

7.创建线程池的各个参数的含义
    第一个:线程池里核心线程数
    第二个:线程池里的最大线程数
    第三个:线程池里空闲线程的最长存活时间
    第四个:存活时间的单位
    第五个: 线程工作队列
    第六个:创建线程的工厂
    第七个:拒绝策略

8.线程池工作原理,有哪些拒绝策略
    任务提交时,先看线程池里的数量有没有达到核心线程数,如果没达到,就创建新的线程
    如果达到了,就把新提交的任务放到任务队列中
    如果任务队列也满了,这时提交任务时,就判断线程池的线程数有没有达到线程池能容纳的最大线程数,如果没达到,就创建新的线程
    如果达到的最大的线程数,就执行拒绝策略
    如果最大线程数大于核心线程数,超过闲置时间后,线程会被回收,最终保持线程数等于核心线程数
    
    4种拒绝策略
        拒绝接受新任务,然后抛异常 ps: 默认的拒绝策略
            
        丢弃任务,不抛异常
        丢弃队列中最前面的任务,然后接受新提交的任务
        由提交任务的线程执行此任务

9.JVM的内存区域划分

    程序计数器
    虚拟机栈
        栈中的数据都是以栈帧(Stack Frame)的格式存在
        每个栈帧中存储着:
            局部变量表
            动态链接
            操作数栈
            方法的返回地址
    方法区
        元空间是方法区的实现,是jdk1.8中的
        永久代也是方法区的实现,是jdk1.7中的
    堆
        1/3 年轻代
            Eden空间和另外两个survivor空间缺省所占的比例是8:1:1
        2/3 老年代
    本地方法栈
    
    

10.什么是Minor GC ?什么是Major GC ?, 两者之间有什么关系
    Minor GC是新生代区的垃圾回收,当Eden区的空间不够的时候需要进行MinorGC策略回收
    Major GC是老年代的垃圾回收,老年代空间不足时,会先尝试触发Minor GC。Minor GC之后空间还不足,则会触发Major GC。
    基本上进行一次Major GC 就会伴随进行一次 Minor GC
    
11.一个Java对象包含哪些内容:
    对象头
    实例数据
    对齐填充
    
12.对象头包含哪些内容:
    对象的hashcode
    分代年龄
    偏向线程ID
    锁状态标志

13.HashMap put数据的过程
    1.先判断Table是否为空或者长度是否为0,如果成立,进行一次resize()
    2.根据数组长度 - 1,与key的Hash值去模,得出要插入的数组下标,判断该下标是否有元素,如果没有,就直接插入到该位置
    3.如果该下标下有元素:
        3.1:判断该元素的key是否和要插入的key一模一样,先用 == 再用 equals 判断,如果一样,用新值替换就值
        3.2:如果key不一样,就判断该位置的元素是不是TreeNode,如果是,就插入
        3.3:如果该位置的元素是链表结构,就插入到链表的尾部,插入后,如果链表的长度大于等于8,就进行树化
    4.记录modCount
    5.判断是否需要扩容
    
    key的Hash计算方法:(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)
    put方法里,计算hash, 然后调用 putVal()方法,进行添加数据
    
HashMap扩容的长度为什么是原来的2倍
    计算插入数组下标公式:(n-1) & hash,2n - 1 的二进制数都是1,
    保证了每次扩容之后新数组的最大索引值对应的二进制数为全1,每位都能参与位运算,能够最大化的分散到HashMap所有的 bucket 中,减少Hash冲突
    
    当 new HashMap(10) 时,hashMap 初始化的数组长度是10么?

ConcurrentHashMap线程安全的原理
    1.7:采用分段锁
    1.8:synchronized + CAS
        synchronized体现在要添加的索引位置上已经有元素了,再往上面添加时
        CAS体现在要添加的位置没有元素时
    
14.Lock获取锁的过程:
    非公平:
        1.直接调用tryAcquire()尝试获取锁,如果加锁失败,就把当前线程实例化成一个Node,加入队列的尾部
            tryAcquire()逻辑:
                1.先获取到当前线程
                2.获取state字段的值,判断值是否为0
                3.如果为0,判断队列里是否还有其它节点,如果没有,就尝试加锁,加锁成功后,就把exclusiveOwnerThread设置为自己
                4.如果不为0,就判断当前线程是否和拿到锁的线程一样,如果成立,表示可重入,计数加1,如果不一样,就加锁失败
                
                
        2.判断刚实例化的Node的前驱节点是否为头节点,如果是头节点,就再次尝试获取锁,
            2.1:如果取到了,就把自己设置为头节点:
            2.2:如果没有取到,就判断自己是否需要挂起
                判断是否需要挂起条件:当前节点的前驱节点状态为SIGNAL时,当前节点需要挂起
                                      前驱节点状态大于0时,表示取消等待,就获取前驱的前驱,直到状态不大于0,然后设置前驱节点为SIGNAL
        
        ps: 如果只有两个线程AB,A拿到了锁,B尝试拿锁的时候,是拿不到的,那么B就加入到队列中,又因为B的前驱节点是头节点,因此B还会再次尝试一下获取锁,如果还是获取不到,就判断一下B是否需要挂起,判断后B不需要挂起,那么B就会再次执行获取锁的步骤,一直重复到拿到锁为止,因为不知道要循环多少次,因此for循环里没有限制循环次数

中间键部分:
如何避免消息队列中消息的重复消费
建一个本地事务表【Redis或者Mysql都可以】,消费者在消费的时候,先判断库里有没有这个记录,如果没有,就先把消息保存在数据库,状态标记为未消费,然后再正常消费,消费万修改状态为已消费

什么是幂等性,如何实现
    同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用
    利用 redis 执行 setnx 命令,天然具有幂等性。从而实现不重复消费

RabbitMQ如何保证消息不丢失?
    生产端:1.开启发布确认,publisher-confirm-type: correlated,消息到达交换机后,就会调用回调函数
            2.开启回退消息通知,那些没法被成功路由的消息就会触发回调函数,returnCallback
    消费端:开启手动ack

相关文章

  • 面试材料

    面试经验 面试题1 面试题2 面试题3 面试题4 面试题5 面试题6――数据结构 面试题7――网络 面试题8――汇...

  • 高阶面试题

    webpack面试题 面试题:webpack插件 Git面试题 面试题:git常用命令 面试题:解决冲突 面试题:...

  • this的指向的面试题

    面试题1 面试题2 面试题3 面试题4

  • 面试所涉及的问题

    面试题参考1 : 面试题 面试题参考2 : 内存管理 面试题参考3 :面试题 ...

  • Android超实用最全面试大纲(三)

    文章目录: ANR面试题 OOM面试题 Bitmap面试题 UI卡顿面试题 内存泄漏面试题 内存管理面试题 一、A...

  • Android最全面试大纲(三)

    文章目录: ANR面试题 OOM面试题 Bitmap面试题 UI卡顿面试题 内存泄漏面试题 内存管理面试题 一、A...

  • 2022年web前端面试题

    web前端面试题分为:html/css面试题、javascript面试题、vue面试题、性能优化面试题、网络方面面...

  • ios面试题

    初级面试题 中级面试题 高级面试题 swift篇

  • Android超实用最全面试大纲(四)

    文章目录: 冷启动和热启动面试题 其他优化面试题 架构模式面试题 插件化面试题 热更新面试题 进程保活面试题 Li...

  • Android最全面试大纲(四)

    文章目录: 冷启动和热启动面试题 其他优化面试题 架构模式面试题 插件化面试题 热更新面试题 进程保活面试题 Li...

网友评论

      本文标题:面试题

      本文链接:https://www.haomeiwen.com/subject/auqrvdtx.html