2023年7月27日面试题

1.动态代理的基本原理和实现

  • 动态代理是不事先为每个需要被代理的类编写代理类,而是在运行时生成代理对象,通过代理对象间接访问目标对象,实现对目标对象的增强或者控制,java使用反射创建代理类
  • 实现的两个核心类
    1. Proxy类
    2. invocationHandler接口
  • 实现方式
    • 创建一个代理类实现invocationHandler接口,重写invoke方法,实现相关逻辑
    • 客户端通过Proxy.newProxyInstance方法来创建代理对象

2.Mysql联合索引讲一下,假设我用abc三个字段建联合索引,我用ac查,那么走不走联合索引?为什么?

  • 联合索引是多个字段组成的索引
  • 使用ac查找,不会走abc联合索引,因为不符合最左前缀原则。

3.jdk1.7和1.8中的hashmap的区别

  • 数据结构
    • jdk1.7使用数组+链表
    • jdk1.8使用数组+链表/红黑树;数组长度大于64且链表长度大于8时,由链表转换为红黑树
  • 节点的插入方法
    • jdk1.7 头插法
    • jkd1.8 尾插法;为了解决多线程的链表死循环问题
  • 节点hash值
    • jkd1.7 hash值可变
    • jkd1.8 hash是final修饰的,不可变
比较HashMap1.7HashMap1.8
数据结构数组+链表数组+链表+红黑树
节点EntryNode TreeNode
Hash算法较为复杂异或hash右移16位
对Null的处理单独写一个putForNull()方法处理作为以一个Hash值为0的普通节点处理
初始化赋值给一个空数组,put时初始化没有赋值,懒加载,put时初始化
扩容插入前扩容插入后,初始化,树化时扩容
节点插入头插法尾插法

3.1为何hashmap中的扩容是<<1?

  • <<1是左移一位的位运算,运算效率比 *2 要高
  • 计算数组下标位置时,使用(n-1)&hash,2的幂次方-1后,二进制低位都是1,按位与运算效率比 hash%n 要高

3.2讲一下hashmap的扩容步骤?

  • 当数组大小达到阈值capacity*loadFactor的大小时进行扩容
  • 一般情况下table容量和阈值都扩大2倍
  • 使用(hash高位 & newCap-1)计算新的数组下标,并放入链表

3.3ConcurrentHashMap的put流程?

  • 获取key的hashCode,调用扰乱函数,获取hash值
  • 使用hash值&(数组长度-1)得到数组下标
  • 检测找到的数组位置是否有节点,没有直接放入
  • 如果有节点那么要上锁
    • jdk1.7底层结构是分段数组+链表,使用Segment锁(实现了ReentrantLock)分段上锁
    • jdk1.8底层结构式节点数组+链表/红黑树,使用synchronized配合CAS给链表头节点或红黑树头节点上锁
  • 使用equal方法查找有没有一样的key的节点,如果有直接覆盖,没有就插jkd1.7头插,jkd1.8尾插。

4.方法区和永久代的关系?为什么要将元空间(MetaSpace) 替换为永久代 (PermGen) 呢?

  • 永久代是方法区的在jdk1.7之前的实现。
  • 避免OOM异常
    • 元空间存在于本地内存,意味着只要本地内存足够,它不会出现像永久代中“java.lang.OutOfMemoryError: PermGen space”这种错误。
    • Metaspace 区域位于堆外,所以它的最大内存大小取决于系统内存,而不是堆大小。

5.Java中有哪些锁?简单介绍了一下两种锁的优缺点

  • 有synchronized锁和reentrantlock可重入锁
优缺点synchronized锁reentrantlock可重入锁
都是可重入的
修饰内容普通方法、静态方法和代码块只能用在代码块上
加锁释放锁自动加锁,自动释放手动调用lock()上锁,unlock()释放锁
锁类型只有非公平锁默认非公平锁,可以换成公平锁
响应中断无法响应中断,发生死锁会一直等待可以响应中断并释放锁,解决了死锁问题
实现方式Monitor管程机制 JVM层面AQS的管程机制 JDK的API层面

6.Java对象创建到销毁的流程

  • 检查类加载
    • 加载:读取class文件的二进制字节流,创建java.lang.Class对象,将类信息存入方法区
    • 连接
      • 验证
        • 文件格式验证
        • 元数据验证
        • 字节码验证
        • 符号引用验证
      • 准备:给静态变量赋零值
      • 解析:将符号引用转换为直接引用
    • 初始化:给静态变量赋初始值
  • 分配内存空间
  • 初始化零值
  • 设置对象头
  • 执行init方法
  • 使用:对象至少存在一个强引用
  • 销毁:对象不存在任何引用,处于不可达状态,将会被垃圾回收,释放内存

7.给定10亿条url,内存有限,怎么快速找出其中一条?

  • 使用哈希索引结构(无内存大小限制时)
  • 使用布隆过滤器(能判断出哪个不存在)
  • 使用外部排序算法:将10亿条url分成若干小组,在小组中进行排序,最终使用二分法进行查找

8.索引失效的场景有哪些?

  • 不满足最左前缀原则
    • like以%开头
    • 想命中联合索引时,where语句没有包含索引最左字段。
  • 使用where a = b语句时
    • a部分使用了运算符
    • a部分使用了函数
    • b部分数据类型不匹配
  • 使用or时,or前后的语句有至少一个没命中索引

9.http如何跨域?tcp如何长链接?

  • 两种跨域方式
    • jsonP
    • CORS
  • tcp长连接:节约了建立连接与销毁连接的开销
    1. 三次握手建立连接
    2. 通过心跳机制:互相发送心跳消息检测对方存活的状态
    3. 一定事件内没有收到对方的心跳包,将会断开连接

10.(HR面)你觉得大学生活给你带来了什么?

  • 根据经历边聊边回答
  • 使用具体例子丰满自己的人设
  • 这不是一个填空题,而是一个问答题
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值