第一次面试-Opay

本文最后更新于:2024年4月18日 晚上

第一次面试-Opay

总之第一次面试答得不好,针对博客之前的内容印象不是很深刻,所以这里整理一下之前的内容,以便下次面试的时候能够更好的回答问题。
待整理

大致的问题合集

  • Java中的集合有哪些
  • 谈到双端队列,是什么,有什么使用场景
  • 谈到阻塞队列,除了生产者消费者模型,还有什么场景
  • InputStream和BufferInputStream的区别,有什么优点
  • 谈到了多线程,可以用什么做线程间同步
  • ThreadLocalMap的实现相关,怎么解决内存泄漏
  • Syncronized关键字,锁升级策略
  • JVM的内存模型
  • JVM堆的结构
  • 堆中创建对象的流程
  • mybatis和mybatis-plus的区别
  • 讲到Nacos的作用,除了nacos,还有什么服务发现中心
  • Nacos和Euareka的优缺点
  • 服务提供方和服务消费方是怎么通过服务发现中心进行通信的
  • CAP理论有了解过吗

Java中的集合有哪些

Java中的集合主要包括List、Set、Map和Queue等。其中,List是有序集合,可以存储重复元素;Set是无序集合,不允许存储重复元素;Map是键值对集合,每个键对应一个值;Queue是队列集合,用于存储元素并实现先进先出的操作。

List

  • ArrayList:基于数组实现,支持随机访问和动态扩容。
  • LinkedList:基于链表实现,支持快速插入和删除操作。

Set

  • HashSet:基于哈希表实现,不保证元素的顺序。
  • TreeSet:基于红黑树实现,保证元素的有序性。

Map

  • HashMap:基于哈希表实现,不保证元素的顺序。
  • TreeMap:基于红黑树实现,保证元素的有序性。
  • LinkedHashMap:基于哈希表和双向链表实现,保证元素的插入顺序。
  • ConcurrentHashMap:基于分段锁实现,支持高并发操作。

Queue

  • ArrayDeque:基于数组实现,支持双端队列操作。
  • PriorityQueue:基于堆实现,支持优先级队列操作。
  • PriorityQueue: 基于堆实现,支持优先级队列操作。

除了生产者消费者模型,阻塞队列还有什么场景
(当时除了生产消费者忘了线程池了,估摸是想通过这个引导出线程池内容)

  • 生产者消费者模型
  • 线程池中的任务队列
  • 事件驱动模型中的事件队列
  • 消息队列中的消息队列

双端队列有什么使用场景

  • 任务调度: 可以将任务按照优先级插入队列的头部或尾部,实现任务的优先级调度。
  • 窗口滑动: 在滑动窗口算法中,双端队列可以用来维护窗口内的最大/最小值。
  • Undo/Redo功能: 在应用程序中实现撤销和重做功能时,可以使用双端队列来管理操作历史。
  • 实现线程安全队列: 在多线程环境下,使用ConcurrentLinkedDeque实现线程安全的双端队列。

InputStream和BufferInputStream的区别

InputStream是Java中所有输入流的抽象基类,它定义了读取字节流的基本方法。BufferedInputStream是InputStream的子类,它提供了缓冲功能,可以提高读取字节流的性能。

BufferInputStream的优缺点

BufferedInputStream的优点是可以减少读取磁盘文件的次数,提高读取性能;缺点是会增加内存消耗,因为需要维护一个缓冲区,增加一定的内存消耗。

ThreadLocal的实现

ThreadLocalMap是ThreadLocal的内部类,用于存储线程本地变量。ThreadLocalMap是一个自定义的哈希表,它的键是ThreadLocal对象,值是线程本地变量的值。每一个线程都有一个ThreadLocalMap对象,用于存储线程本地变量。

ThreadLocal存在内存泄漏的问题,ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。解决这个问题的方法是在使用完 ThreadLocal 后,调用 remove() 方法,手动清除 ThreadLocalMap 中的 key。

Syncronized关键字

(这块没答好,刚开始没反应过来,后面锁升级部分忘了)

synchronized是Java中最基本的同步手段,它保证了线程的安全性,相较于volatile更加重量级。synchronized主要有三种用法:修饰实例方法、修饰静态方法、修饰同步方法块中的对象。

(面试的时候想通过这个引导出锁升级的内容,但是当时没看)
在Java6(1.6)之后,synchronized 引入了大量的优化如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销.

锁升级的过程

  1. 无锁状态:锁对象还没有被任何线程锁定,没有线程相互竞争,此时处于无锁状态。
  2. 偏向锁状态:只有一个线程不停访问代码块,此时会使用偏向锁。(在JDK15后,偏向锁被废弃,因为撤销带来的性能开销大)
  3. 轻量级锁状态:多个线程访问代码块,偏向锁会撤销,此时会使用轻量级锁。
  4. 重量级锁状态:当CAS自旋达到一定次数没有拿到锁(有线程超过10次自旋,或者自旋线程数超过cpu核数的一半),会撤销掉轻量级锁,此时会使用重量级锁。

graph LR;
    A[无锁状态] -->|有一个线程竞争锁| B[偏向锁状态];
    B -->|多个线程竞争| C[偏向锁状态];
    C -->|CAS自旋达到一定次数| D[重量级锁状态];

相较于volatile的区别

  • volatile主要用于修饰变量,而syschronized主要用于修饰方法和代码块;
  • volatile相较于synchronized速度更快;
  • volatile关键字是Java中的一种轻量级同步机制,它保证了线程的可见性,但是不保证原子性;
  • synchronized关键字是Java中的一种重量级同步机制,它保证了线程的可见性和原子性,但是性能开销较大;
  • volatile关键字一般使用乐观锁的思想实现,通常使用轻量级锁,使用CAS机制。
  • synchronized关键字一般使用悲观锁的思想实现,通常有锁升级的过程。

JVM的内存模型

存放在线程中的

  • 程序计数器:记录当前线程执行的字节码的行号,是线程私有的。
  • 虚拟机栈:每个方法执行的时候都会创建一个栈帧,包含局部变量表、操作数栈、动态链接、方法出口等信息,是线程私有的。
  • 本地方法栈:用于存放 Native 方法的信息,是线程私有的。

存放在堆中的

  • 堆:存放对象实例,是垃圾收集器管理的主要区域,包括新生代、老年代和永久代(JDK1.7之前),此外还有字符串常量池。
  • 方法区: 存放类的元数据,包括类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。1.8后被元空间取代,移动到本地内存中。

存放在本地内存

  • 元空间:用于存放 Class 的元数据,JDK1.8 之后取代了永久代。
  • 直接内存:用于存放堆外内存,通过 NIO 类库直接分配堆外内存、Native方法,提高性能。

JVM堆的结构

堆区分为新生代、老年代和永久代(JDK1.7之前)或元空间(JDK1.8之后)。

新生代又分为Eden区、s0区,s1区,默认数据大小为8:1:1

Eden区、s0,s1区关系和对象生成流程

新创建一个对象,首先判断能否放到Eden区,如果Eden区满了,会触发mirror gc。此时Eden区和s0区中存活的对象移至s1区,并标志对象的分代年龄,eden区和s0区清空,如果此时对象还无法放置eden区,则直接放置老年代。反之亦然。

mybatis和mybatis-plus的区别

mybatis-plus是mybatis的增强版,它在mybatis的基础上提供了更多的功能和特性。mybatis-plus提供了代码生成器、分页插件、性能分析插件等功能,简化了开发过程,提高了开发效率。此外,mybatis-plus还提供了更加强大的CRUD操作,支持更多的数据库操作。

讲到Nacos和Euareka的优缺点

首先,从实现方式上看,Nacos和Eureka都支持服务注册与发现,但是它们的实现方式略有不同。Nacos基于客户端/服务器架构,服务提供者在启动时将自己注册到Nacos的服务注册表中,服务消费者从Nacos的服务注册表中获取服务列表。而Eureka则基于云原生架构,使用RESTful API进行通信,服务提供者将自己的信息注册到Eureka Server,服务消费者从Eureka Server获取服务列表。

其次,从功能上看,Nacos和Eureka都提供了动态服务发现、配置管理、服务元数据管理和流量管理等功能。然而,它们之间也存在一些差异。例如,Nacos支持服务端主动检测提供者状态,而Eureka则采用客户端检测机制。此外,Nacos支持服务列表变更的消息推送模式,服务列表更新更及时,而Eureka则采用拉取模式。

最后,从性能上看,Nacos和Eureka都具有较高的性能和可扩展性。然而,由于Nacos是基于长连接的,因此在处理大量并发请求时可能会表现出更高的性能。而Eureka则采用短连接和定时发送的方式,因此在处理少量请求时可能具有更好的性能。

CAP理论

CAP理论是分布式系统设计中的一个重要理论,它指出在分布式系统中,一致性(Consistency)可用性(Availability)分区容错性(Partition Tolerance)这三个特性不可能同时满足。在分布式系统中,由于网络分区、节点故障等原因,分区容错性是必须保证的,因此在一致性和可用性之间需要进行权衡。

具体来说,CAP理论指出在分布式系统中,只能满足其中的两个特性,无法同时满足三个特性。例如,当网络分区发生时,系统需要保证分区容错性,此时需要选择一致性或可用性。如果选择一致性,则可能导致部分节点不可用;如果选择可用性,则可能导致数据不一致。因此,在设计分布式系统时,需要根据具体的业务需求和系统特性进行权衡,选择合适的一致性级别和可用性级别。


第一次面试-Opay
https://www.liahnu.top/2024/03/29/第一次面试-Opay/
作者
liahnu
发布于
2024年3月29日
许可协议