京东后端开发面试

本文最后更新于 2 分钟前,文中所描述的信息可能已发生改变。
  • 1. Java 里常用的集合有哪些? ✅ 2025-09-15

常用的集合有:List,Map,Set,Queue,PriorityQueue 等/

  • List:ArrayList、LinkedList

  • Set:HashSet、TreeSet、LinkedHashSet

  • Map:HashMap、TreeMap、ConcurrentHashMap

  • 2. 数组的底层原理是啥? ✅ 2025-09-15

通过在内存中分配一块连续的区域,数组中元素内存地址依次递增,能够通过起始位置快速索引元素。

  • 连续的内存空间,支持下标随机访问(O(1))。

  • 插入、删除元素需要移动大量数据(O(n))。

  • 3. ArrayList 是怎么扩容的?

首先根据数组长度重新创建新数组,再将旧数组中元素复制到新数组,后释放旧数组内存。 >具体扩容是将数组长度翻倍。

  • 默认初始容量 10。

  • 扩容时新容量 = 原容量的 1.5 倍。

  • 通过 Arrays.copyOf 复制数据到新数组。

  • 4. ArrayList 在哪些场景下不太好用? ✅ 2025-09-15

频繁插入或删除元素。

  • 元素频繁插入/删除(中间位置)。

  • 大量数据时,扩容成本高。

  • 多线程环境下不安全。

  • 5. HashMap 是怎么解决哈希冲突的?

采用 hashcode()和 equal()方法。

  • JDK 1.8 以前:拉链法(数组 + 链表)。

  • JDK 1.8 以后:链表长度 > 8 时转成红黑树。

  • 6. 讲讲快速排序。 ✅ 2025-09-15

  • 分治思想,选择基准值,分区交换。

  • 平均 O(n log n),最坏 O(n^2)。

  • 非稳定排序。

  • 7. 讲讲堆排序。 ✅ 2025-09-15

  • 基于大顶堆/小顶堆。

  • 建堆 + 调整。

  • 时间复杂度 O(n log n),不稳定排序。

  • 8. Java 里的 sort 方法用的是什么排序算法?

  • 基本类型数组:双轴快排(Dual-Pivot Quicksort)。

  • 对象数组、集合:TimSort(归并 + 插入排序优化,稳定)。

  • 9. final 关键字有什么用?

  • 修饰类:不能被继承。

  • 修饰方法:不能被重写。

  • 修饰变量:常量,不能再赋值。

  • 10. Java 实现多线程有几种方式? ✅ 2025-09-15

  1. new Thread(); 2. extends Callable(); 3. implements Runnable()。
  • 继承 Thread 类。

  • 实现 Runnable 接口。

  • 实现 Callable 接口 + FutureTask。

  • 使用线程池。

  • 11. 线程池的主要参数有哪些?

核心线程数,最大线程数…

  • corePoolSize(核心线程数)

  • maximumPoolSize(最大线程数)

  • keepAliveTime(空闲线程存活时间)

  • workQueue(阻塞队列)

  • threadFactory(线程工厂)

  • handler(拒绝策略)

  • 12. 线程池的拒绝策略有哪些?

  • AbortPolicy(抛异常)

  • CallerRunsPolicy(调用者执行)

  • DiscardPolicy(直接丢弃)

  • DiscardOldestPolicy(丢弃最老任务)

  • 13. 除了线程池,还接触过其他开启多线程的方式吗?

  • ForkJoinPool

  • CompletableFuture

  • 并行流(parallelStream)

  • 14. synchronizedReentrantLock 有什么区别?

  • synchronized:JVM 实现,简单易用,自动释放锁。

  • ReentrantLock:基于 AQS,支持可重入、公平锁、可中断、条件变量。

  • 15. 介绍一下 ReentrantLock 底层的 AQS。

  • AQS 维护一个 state(锁状态)和 FIFO 队列。

  • 通过 CAS 修改 state 实现加锁/释放锁。

  • 队列中节点自旋 + 阻塞等待唤醒。

  • 16. CAS 底层用的是什么技术?

  • CPU 的原子指令(如 x86 的 cmpxchg)。

  • 保证比较并交换的原子性。

  • 17. 听说过无锁吗?

  • 基于 CAS 实现的并发控制。

  • 不需要互斥锁,提高并发性能。

  • 18. ThreadLocal 用过吗? ✅ 2025-09-15

  • 为每个线程提供独立副本,线程之间数据隔离。

  • 19. 用 ThreadLocal 的时候要注意什么问题? ✅ 2025-09-15

及时回收不在使用 ThreadLocal 对象,防止内存泄漏。

  • 内存泄漏问题。

  • 线程池复用线程时要手动清理。

  • 20. 怎么保证 ThreadLocalremove 方法一定会被执行?

  • finally 块中调用 remove()

  • 21. 调用 remove 方法的目的是什么? ✅ 2025-09-15

  • 防止线程复用导致数据错乱。

  • 避免内存泄漏。

  • 22. 数据库的事务隔离级别有哪些? ✅ 2025-09-15

读未提交,读已提交,可重复读,串行化。

  • 23. MySQL 默认的事务隔离级别是哪个? ✅ 2025-09-15

可重复读。

  • 24. MySQL 是怎么解决不可重复读问题的? ✅ 2025-09-15

基于 MVCC 的快照读,实现读进程读取的记录不会被修改。

  • 25. 幻读问题解决了吗? ✅ 2025-09-15

大体上解决了,但是还存在部分 bug。如:快照锁升级导致可重复读失效。

可重复读依赖 MVCC 的快照读,如果事务中显式加锁(for update / lock in share mode),快照会升级为当前读,从而读取到最新数据,导致“可重复读失效”的现象。

  • 26. 算法题:用三个线程按顺序打印 A、B、C(用两个线程按顺序打印奇偶数)。
  • 使用 synchronized + wait/notify
  • Lock + Condition
  • Semaphore 控制顺序。
java
public class Printer {

    private int count = 0;
    private final int maxCount = 200;
    private final Object lock = new Object();
    private boolean isOdd = false;

    public static void main(String[] args) {
        Printer printer = new Printer();

        Thread oddThread = new Thread(() -> {
            printer.print("Thread Odd", true);
        });
        Thread evenThread = new Thread(() -> {
            printer.print("Thread Even", false);
        });

        oddThread.start();
        evenThread.start();
    }

    public void print(String name, boolean isOdd) {
        synchronized (lock) {
            while (count < maxCount) {
                if (this.isOdd != isOdd) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
                System.out.println(name + ": " + count);
                count++;
                this.isOdd = !this.isOdd;
                lock.notifyAll();
            }
        }
    }
}
材料计算常用资源