一、线程安全的类有哪些,用来解决什么问题?
- 并发包提供的线程安全类:这些类提供了比
synchronized
更高级的各种同步结构,如ReentrantLock
、Semaphore
、CountDownLatch
、CyclicBarrier
等。这些类通过使用锁或其他同步机制来确保线程安全。 - 线程安全的容器:Java提供了多种线程安全的容器,如
ConcurrentHashMap
、有序的ConcurrentSkipListMap
,以及利用快照机制实现线程安全的动态数组CopyOnWriteArrayList
。这些容器类通过内部使用锁或其他同步机制来确保在多线程环境下的数据一致性。 - 传统的线程安全集合类:包括
Vector
和Hashtable
。这些类通过内部使用同步代码块或同步方法来确保线程安全,但可能在多线程高并发的情况下性能受到影响。 - 新的线程安全集合类:Java5引入了新的线程安全的集合类,如
ConcurrentHashMap
,它可以在多线程环境下并发的访问和修改数据,且效率比传统的线程安全集合类更高。这些集合类通常使用了读写分离技术来保证线程安全。 - 原子类:JDK中提供了如
AtomicBoolean
、AtomicInteger
等原子类,它们通过CAS(Compare-and-Swap)操作来保证原子性,从而确保线程安全。 - 锁机制:Java还提供了各种锁机制,如
synchronized
关键字和volatile
关键字,以及通过Lock
接口实现的锁,这些机制用于保证代码块在同一时刻只能被一个线程执行,从而确保线程安全。 - ThreadLocal:虽然不是直接用于确保类的线程安全,但
ThreadLocal
可以用于确保变量在每个线程中的独立性,从而避免多线程间的数据共享问题,间接地实现了一种形式的线程安全。
二、mysql 日志文件有哪些,分别介绍下作用
- redolog:主要目的是保证数据不丢失,当mysql发生宕机时可以恢复数据。
为什么要写入redolog,不直接写入磁盘?
因为顺序io的性能远胜于随机io
先写入redolog buffer,然后刷盘写入redolog.file和磁盘
那什么时候写入redolog.file和磁盘呢?
innodb_flush_log_at_trx_commit=1,默认刷盘策略:每次提交事物成功主动刷盘,写入磁盘和redolog.file。如果事物提交过程中mysql挂了,那么也没事。因为事物还没提交成功,没有写入redolog.file也无所谓。保证ACID的D(持久性),性能最差。
innodb_flush_log_at_trx_commit=2,只要事物提交成功,那么写入pagecache,不同步写入磁盘和redolog.file,如果这个时候操作系统挂了,会导致pagecache丢失1秒的数据。
innodb_flush_log_at_trx_commit=0,后台线程每秒提交一次,如果mysql挂了,有一秒的数据丢失风险。效率是最高的。
- bin log: 执行数据库更新操作时记录的日志,比如insert,update,delete,一般用于主从同步
- undo log:用于事物回滚
- 慢查询日志
三、你们项目为什么用 redis,快在哪,怎么保证高性能,高并发的.
1.缓存,减少数据库的压力,2. redission做分布式锁
快在哪?
1.内存操作,2. nio+单线程模式,3.高效的数据结构
怎么保证高性能,高并发的?
a. 主从模式:
优点:读写分离,提高效率;数据热备份,提供多个副本;
缺点:1.主节点故障,导致集群无法正常工作
2.无法自动调整,需要人工干预
3.master节点写压力比较大,因为只有一个写节点,从节点都是读节点。
4.主从同步可能会有性能压力,产生同步风暴
b. 哨兵模式
哨兵模式基于主从模式
优点:1.可以自动实现故障转移和自动重新配置slave,可以在一定成都实现负载均衡 缺点:1.但是它的性能并没有比主从模式提高多少,主从转化过程中可能有一定的业务故障。
c. 集群模式
redis集群至少配置3主3从,这样是6个节点。主节点提供读写操作(主从或者哨兵模式下从节点提供读操作),从节点不提供读写操作,只做故障转移使用。
优点:
为什么集群模式至少要3个master节点?
因为集群模式某个master节点挂了,需要半数以上的master节点重新选举出新的master节点。如果只有2个master节点,那么1个挂了后,剩余的1个master节点没有达到半数以上的条件(刚好是半数),只有3个master节点,1个挂了后,剩余2个节点刚好是半数以上(>1.5)
为什么集群模式推荐奇数个节点而不是偶数个节点?
为了考虑节省资源,比如3个或者4个节点,如果2个节点挂了都不能重新选举。所以3个够了,没必要4个。
redis集群的插槽为什么设计成16384?
16384/8=2048,刚好是2KB的空间