Synchronized是Java中实现线程同步互斥访问的关键机制,其本质是加锁,用于序列化访问临界资源,确保同一时刻只有一个线程能够访问共享的可变状态。Java提供了synchronized关键字和Lock接口两种方式实现同步。 synchronized基于JVM内置锁(Monitor),通过monitorenter和monitorexit指令实现同步,底层依赖操作系统互斥锁。JVM为了提升性能,对synchronized进行了优化,包括锁粗化、锁消除、轻量级锁、偏向锁和自旋锁等。 锁的状态会根据竞争情况进行升级:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁。偏向锁优化了无竞争情况下的加锁,轻量级锁适用于线程交替执行同步块的场景,自旋锁避免了频繁的操作系统线程切换。此外,JIT编译时还可能进行锁消除优化,去除不必要的锁。 对象头中的Mark Word记录了锁状态,对象头的大小和结构会根据虚拟机和开启的指针压缩选项而有所不同。工具如JOL可以用于分析对象头的锁状态。

零拷贝是一种 I/O 优化技术,能够在数据传输过程中避免或极大减少 CPU 参与的内存拷贝和用户态/内核态切换,从而提升吞吐与降低延迟。文章首先解释传统 read/write 流程的四次上下文切换和多次拷贝,然后回顾内核/用户空间、上下文切换、虚拟内存和 DMA 的基本概念。接着介绍三种实现零拷贝的方式:mmap+write、sendfile、以及加入 scatter/gather 的 sendfile,分别说明各自的切换次数和拷贝次数,最后说明 Java NIO 中的 MappedByteBuffer(基于 mmap)和 FileChannel.transferTo/transferFrom(基于 sendfile)如何在代码层面使用零拷贝。全文以 Kafka、RocketMQ 为实际应用场景,展示零拷贝在提升系统性能中的关键作用。

幂等指一次或多次请求产生相同副作用,关键在于全局唯一ID的标记。文中阐释了幂等的必要性,如转账、MQ 重复消费等场景,并比较了超时处理的查询回滚与直接重试两种方案,强调下游接口应支持幂等。随后介绍了生成唯一ID的方式(UUID、Snowflake 等),并详述实现幂等的八种常用方案:①先查后插并捕获唯一索冲突;②直接插入捕冲突;③基于状态机的更新行数判重;④使用防重表;⑤ token 令牌;⑥悲观锁;⑦乐观锁;⑧分布式锁。最后说明 HTTP 方法的幂等性,GET、HEAD、OPTIONS、DELETE、PUT 为幂等,POST 则不具幂等。

本文整理了十道经典的消息队列(MQ)面试题,旨在帮助读者在金三银四的面试季中脱颖而出。文章首先介绍了消息队列的概念、作用以及常见的开源消息中间件(RabbitMQ、RocketMQ、Kafka)。 随后,文章深入探讨了消息队列的应用场景,包括应用解耦、流量削峰、异步处理、消息通讯和远程调用,并以“下单扣库存”为例详细说明了解耦的优势。文章还讨论了消息丢失问题的解决方案,涵盖生产者、存储端和消费者三个阶段的保证方法,以及如何保证消息的顺序性。 此外,文章还探讨了重复消费与幂等处理、消息积压的处理策略、MQ技术选型(Kafka、RocketMQ、RabbitMQ的优缺点对比)、高可用性保障以及数据一致性与事务消息的实现。最后,文章以“设计一个消息队列”为题,从架构设计、持久化、消费关系、可靠性、高可用性和可扩展性等方面提出了设计思路。 总而言之,本文全面覆盖了消息队列相关的核心概念、常见问题和设计思路,对于准备面试或希望深入了解消息队列技术的读者具有重要参考价值。

Redis 用作 DB 的高速缓存能把 QPS 提升至十万,但若设计不当会出现三大问题:缓存击穿(单热点数据在高并发下失效导致瞬时 DB 压垮),缓存穿透(查询不存在的键每次都直达 DB),以及缓存雪崩(大量键同时失效或 Redis 故障使流量全部涌向 DB)。针对击穿可采用不设过期、随机 TTL、预热或分布式锁;针对穿透可缓存空值或使用布隆过滤器;针对雪崩可在 TTL 上加入随机值、限流/熔断以及构建 Redis 哨兵或 Cluster 高可用集群。通过这些手段可保证缓存的稳定性并防止 DB 被压垮。