好未来Java校招岗一面

大哥大姐们请教一下,好未来Java校招岗一面
最新回答
海不曾怀疑天的蓝

2026-07-13 05:11:24

好未来Java校招岗一面主要涉及自我介绍、消息队列、Redis、多线程、MySQL及算法题,具体内容如下:

一、自我介绍
  • 需清晰阐述个人基本信息、教育背景、项目经历、技术技能等,重点突出与Java开发相关的项目经验、掌握的技术栈(如Spring、MyBatis等框架)及解决问题的关键能力。
二、消息队列相关问题
  • RabbitMQ是否可以重复消费相同的消息

    可以。RabbitMQ通过消息确认机制(ACK/NACK)实现重复消费:若消费者未正确发送ACK,RabbitMQ会重新投递消息;若需主动重复消费,可通过重新声明队列或使用死信队列实现。

  • 项目中为什么选择RabbitMQ

    轻量级:部署简单,资源占用低。

    灵活性:支持多种消息模式(点对点、发布/订阅)。

    可靠性:通过持久化、事务、确认机制保证消息不丢失。

    社区支持:文档完善,问题解决效率高。

  • 其他消息队列的了解

    Kafka:高吞吐、分布式、适合大数据场景,但延迟较高。

    RocketMQ:阿里开源,支持事务消息、顺序消息,适合金融场景。

    ActiveMQ:老牌消息队列,支持JMS规范,但性能较弱。

三、Redis相关问题
  • Redis常用数据结构

    String:存储字符串、数字,支持原子操作(如自增)。

    Hash:存储键值对集合,适合存储对象。

    List:双向链表,支持范围查询、阻塞弹出。

    Set:无序集合,支持交并差运算。

    ZSet(Sorted Set):有序集合,按分数排序,支持范围查询。

  • Redis是多线程还是单线程

    6.0版本前:单线程处理命令(网络请求、命令解析、执行、返回结果),通过IO多路复用(如epoll)实现高并发。

    6.0版本后:引入多线程处理网络请求(命令解析、返回结果),但命令执行仍为单线程。

四、多线程相关问题
  • 创建线程的方式

    继承Thread类:重写run()方法,通过start()启动。

    实现Runnable接口:实现run()方法,通过Thread(Runnable target)构造线程。

    实现Callable接口:实现call()方法(有返回值),通过FutureTask包装后启动。

    线程池:通过Executors或ThreadPoolExecutor创建,复用线程资源。

  • 线程池的几大参数

    corePoolSize:核心线程数,线程池保持的最小线程数。

    maximumPoolSize:最大线程数,线程池允许的最大线程数。

    keepAliveTime:空闲线程存活时间,超过核心线程数的线程在空闲后被回收。

    unit:时间单位(如秒、毫秒)。

    workQueue:任务队列,存储待执行的任务(如LinkedBlockingQueue)。

    threadFactory:线程工厂,用于创建线程。

    handler:拒绝策略,当队列满且线程数达到最大值时处理新任务的策略(如AbortPolicy抛出异常)。

五、MySQL相关问题
  • MySQL引擎

    InnoDB:支持事务、行级锁、外键,默认引擎。

    MyISAM:不支持事务,表级锁,适合读多写少的场景。

    Memory:数据存储在内存中,速度快,但数据易丢失。

  • InnoDB的特点

    事务支持:符合ACID特性。

    行级锁:减少锁冲突,提高并发性能。

    外键约束:保证数据完整性。

    MVCC:多版本并发控制,实现读写不阻塞。

    崩溃恢复:通过redo log和undo log实现数据恢复。

  • MySQL的锁机制

    共享锁(S锁):读锁,多个事务可同时持有。

    排他锁(X锁):写锁,仅一个事务可持有。

    意向锁:表级锁,表示事务打算在表中的行上加锁(意向共享锁、意向排他锁)。

    记录锁(Record Lock):锁定索引记录。

    间隙锁(Gap Lock):锁定索引记录之间的间隙,防止幻读。

    临键锁(Next-Key Lock):记录锁+间隙锁,锁定索引记录及其前后的间隙。

  • MVCC(多版本并发控制)

    原理:通过维护数据的多个版本(隐藏字段DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID)和ReadView(事务快照)实现读写不阻塞。

    实现方式:

    读操作:根据ReadView判断数据版本是否可见(未提交或已回滚的版本不可见)。

    写操作:通过undo log回滚数据,通过redo log保证事务持久性。

六、算法题
  • 题目1:旋转链表

    思路:

    计算链表长度n,若k % n == 0则直接返回原链表。

    找到新链表的尾节点(第n - k % n个节点)和头节点(尾节点的下一个节点)。

    断开链表,将原尾节点指向原头节点,新尾节点指向null。

    代码示例:

    public ListNode rotateRight(ListNode head, int k) { if (head == null || head.next == null || k == 0) return head; int n = 1; ListNode tail = head; while (tail.next != null) { tail = tail.next; n++; } k = k % n; if (k == 0) return head; ListNode newTail = head; for (int i = 0; i < n - k - 1; i++) { newTail = newTail.next; } ListNode newHead = newTail.next; newTail.next = null; tail.next = head; return newHead;}
  • 题目2:链表的奇偶重排

    思路:

    初始化奇数链表头odd和偶数链表头even,以及对应的尾指针oddTail和evenTail。

    遍历原链表,将奇数节点连接到oddTail,偶数节点连接到evenTail。

    将oddTail.next指向even的头节点,evenTail.next指向null。

    代码示例:

    public ListNode oddEvenList(ListNode head) { if (head == null || head.next == null) return head; ListNode odd = head; ListNode even = head.next; ListNode oddTail = odd; ListNode evenTail = even; while (evenTail != null && evenTail.next != null) { oddTail.next = evenTail.next; oddTail = oddTail.next; evenTail.next = oddTail.next; evenTail = evenTail.next; } oddTail.next = even; return odd;}