GitHub 6.6k Star 的Java工程师成神之路 ,不来了解一下吗?
GitHub 6.6k Star 的Java工程师成神之路 ,真的不来了解一下吗?
GitHub 6.6k Star 的Java工程师成神之路 ,真的确定不来了解一下吗?
这是一个知乎上面很火的问题( www.zhihu.com/question/50… ),下面是我关于这个问题的回答,截止今天,这个答案收获了500+赞和70+评论。
原答案
这个问题只是开个场,热个身而已啊。
StringBuffer,StringBuilder区别是啥?
什么是线程安全?
如何保证线程安全?
什么是锁?死锁?
synchronized的实现原理是什么?
有了synchronized,还要volatile干什么?
synchronized的锁优化是怎么回事?(锁粗化?锁消除?自旋锁?偏向锁?轻量级锁?)
知道JMM吗?(原子性?可见性?有序性?)
Java并发包了解吗?
那什么是fail-fast?什么是fail-safe?
什么是CopyOnWrite?
那AQS呢?那CAS呢?
CAS都知道,那乐观锁一定知道了?
乐观锁悲观锁区别是什么?
数据库如何实现悲观锁和乐观锁?
数据库锁有了解么?行级锁?表级锁?共享锁?排他锁?gap锁?next-key lock?
数据库锁和隔离级别有什么关系?
数据库锁和索引有什么关系?
什么是聚簇索引?非聚簇索引?最左前缀是什么?B+树索引?联合索引?回表?
分布式锁有了解吗?
Redis怎么实现分布式锁?
为什么要用Redis?
Redis和memcache区别是什么?
Zookeeper怎么实现分布式锁?
什么是Zookeeper?
什么是CAP?
什么是BASE?和CAP什么区别?
CAP怎么推导?如何取舍?
分布式系统怎么保证数据一致性?
啥是分布式事务?分布式事务方案?
那么,最后了,来手写一个线程安全的单例吧?
不用synchronized和lock能实现线程安全的单例吗?
这你都能答上?那好吧,你给我解释下什么是Paxos算法吧?
卒~!
部分答案
针对以上的问题,我给一些答案,希望大家都能有所收获。这些答案也都是从我的博客中历史文章总结出来的。
部分问题简单几句可以说的清楚的,我就直接贴答案了,比较复杂的,我贴个传送门。
但是,以下答案可能并不完整,比如一些比较类的,我可能只说重点或者和这个知识体系有关的关键点,所以希望读者可以根据下面的问题,完善每一个问题的答案。
StringBuffer,StringBuilder区别是啥?
StringBuffer是线程安全的,而StringBuilder是非线程安全的。
什么是线程安全?
线程安全是编程中的术语,指某个函数、函数库在并发环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。即在多线程场景下,不发生有序性、原子性以及可见性问题。
如何保证线程安全?
Java中主要通过加锁来实现线程安全。通常使用synchronized和Lock
什么是锁?死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
死锁的发生必须具备以下四个必要条件:互斥条件、请求和保持条件、不剥夺条件、环路等待条件
死锁的解决办法就是破坏以上四种必备条件中的一个或者多个。
synchronized的实现原理是什么?
深入理解多线程(一)——Synchronized的实现原理 深入理解多线程(四)—— Moniter的实现原理 再有人问你synchronized是什么,就把这篇文章发给他
有了synchronized,还要volatile干什么?
volatile通常被比喻成”轻量级的synchronized“,volatile可以保证可见性和有序性,实现原理是通过内存屏障实现的。
volatile有一个重要的作用,是synchronized不具备的,那就是禁止指令重排序。这一特点在双重校验锁实现单例的时候有用到,虽然使用了synchronized关键字,但是如果不用volatile修饰单例对象,就会存在问题。
深入理解Java中的volatile关键字 再有人问你synchronized是什么,就把这篇文章发给他。
synchronized的锁优化是怎么回事?(锁粗化?锁消除?自旋锁?偏向锁?轻量级锁?)
知道JMM吗?(原子性?可见性?有序性?)
Java内存模型(Java Memory Model ,JMM)是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。
Java并发包了解吗?
java.util.concurrent包(J.U.C)中包含的是java并发编程中有用的一些工具类,包括几个部分:
1、locks部分:包含在java.util.concurrent.locks包中,提供显式锁(互斥锁和速写锁)相关功能;
2、atomic部分:包含在java.util.concurrent.atomic包中,提供原子变量类相关的功能,是构建非阻塞算法的基础;
3、executor部分:散落在java.util.concurrent包中,提供线程池相关的功能;
4、collections部分:散落在java.util.concurrent包中,提供并发容器相关功能;
5、tools部分:散落在java.util.concurrent包中,提供同步工具类,如信号量、闭锁、栅栏等功能;
那什么是fail-fast?什么是fail-safe?
我们通常说的Java中的fail-fast机制,默认指的是Java集合的一种错误检测机制。当多个线程对部分集合进行结构上的改变的操作时,有可能会产生fail-fast机制,这个时候就会抛出ConcurrentModificationException。
ConcurrentModificationException,当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常。
为了避免触发fail-fast机制,导致异常,我们可以使用Java中提供的一些采用了fail-safe机制的集合类。
这样的集合容器在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
java.util.concurrent包下的容器都是fail-safe的,可以在多线程下并发使用,并发修改。同时也可以在foreach中进行add/remove 。
什么是CopyOnWrite?
Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。
CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。
那AQS呢?那CAS呢?
AQS(AbstractQueuedSynchronizer),即队列同步器。它是构建锁或者其他同步组件的基础框架(如ReentrantLock、ReentrantReadWriteLock、Semaphore等),JUC并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。它是JUC并发包中的核心基础组件。
CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”这其实和乐观锁的冲突检查+数据更新的原理是一样的。