5-6年面试(上海清美1)

1.事务隔离级别

读未提交(Read Uncommitted)

这是最低的事务隔离级别。
一个事务可以读取另一个尚未提交的事务的修改。
可能导致脏读、不可重复读和幻读。
效率高,但并发控制能力最弱。

读已提交(Read Committed)
一个事务只能读取另一个已经提交的事务的修改。
可以防止脏读,但可能出现不可重复读和幻读。
大多数数据库系统的默认隔离级别。

可重复读(Repeatable Read)
在同一事务内,多次读取同一数据返回的结果是一样的。
可以防止脏读和不可重复读,但可能出现幻读。
MySQL的InnoDB存储引擎在默认设置下使用此隔离级别。

串行化(Serializable)
这是最高的隔离级别。
通过对事务进行排序,使得事务完全串行执行,从而解决脏读、不可重复读和幻读问题。
但性能开销最大,因为事务需要等待其他事务完成才能继续执行。

2.怎么写更新sql ?

1、start TRANSACTION;
BEGIN;
update a set …
commit;
2、update table set column = 1 where id = 2 for update

3.可重复读解决什么问题?

可重复读主要解决的是数据库并发控制中的一致性问题。在数据库事务处理中,当多个事务同时访问和修改同一数据时,可能会出现数据不一致的情况。可重复读隔离级别通过确保在一个事务内多次读取同一数据返回的结果相同,从而避免了“不可重复读”和“幻读”的问题。

具体来说,可重复读隔离级别通过一系列的控制机制,如行级锁、多版本并发控制(MVCC.MySQl中只有InnoDB支持MVCC,其他存储引擎不支持)等,实现了以下目标:

在一个事务内,无论其他事务如何修改数据,该事务看到的数据始终是一致的,即多次读取同一数据的结果相同。
防止了“脏读”,即一个事务读取到另一个未提交事务的修改。
降低了“幻读”的可能性,即在一个事务内执行相同的查询操作,结果集不会因其他事务的插入或删除操作而改变。
通过实现这些目标,可重复读隔离级别有效提高了数据库并发控制的性能和可靠性,特别是在高并发场景下,能够确保数据的一致性和完整性。需要注意的是,不同的数据库管理系统(DBMS)可能采用不同的实现方式和技术来支持可重复读隔离级别,因此在具体使用时需要参考相应的DBMS文档和规范。

4.Redis 的数据类型以及底层数据结构?

Redis支持多种数据类型,每种类型都有不同的特点和用途。以下是Redis的数据类型及其底层数据结构:

  1. 字符串(String):
    • 字符串类型是最基本的数据类型,可以存储任何类型的数据,如文本、整数或二进制数据。
    • 底层数据结构是简单动态字符串(SDS),它是一个可变长度的字节数组。
  2. 列表(List):
    • 列表类型是一个按插入顺序排序的字符串元素集合。
    • 底层数据结构使用双向链表实现,使得在两端进行快速插入和删除操作。
  3. 集合(Set):
    • 集合类型是一个无序且唯一的字符串元素集合。
    • 底层数据结构使用哈希表实现,保证高效的元素查找和去重。
  4. 有序集合(Sorted Set):
    • 有序集合类型是一个有序的字符串元素集合,每个元素关联了一个分数,用于排序。
    • 底层数据结构采用跳跃表和哈希表的组合实现,使得元素的添加、删除和范围查询等操作都具有较高的性能。
  5. 哈希表(Hash):
    • 哈希表类型是一个键值对的无序散列集合。
    • 底层数据结构使用哈希表实现,可以快速地通过键进行查找、插入和删除操作。
  6. Bitmap:
    • Bitmap类型是位数组,用于对大量位的设置、清除或查询操作。
    • 底层数据结构使用字节数组实现,每个比特位代表一个状态。
  7. HyperLogLog:
    • HyperLogLog类型用于进行基数估计,即统计集合中不重复元素的个数。
    • 底层数据结构使用原位指令实现,占用固定的空间,但可能会有一定的误差。

4.你用过Zset吗?

ZSet的应用场景非常广泛,例如排行榜、时间轴、朋友圈点赞等。通过将每个用户的分数存储在ZSet中,可以方便地进行排名、排序、取前几名等操作。同时,ZSet还可以用来实现时间轴功能,将每个用户的发布时间作为分数存储在ZSet中,然后按时间排序获取最新的信息。

5.kafka 分区分组有什么区别?

分区(Partition):

目的:Kafka的分区主要是为了扩展性。当Kafka集群需要处理大量的消息时,通过将一个大的topic分布到多个服务器上,可以有效地分散负载,提高系统的吞吐量和可靠性。
特点:在Kafka中,一个topic可以分成多个partition,每个partition是一个有序的队列。所有的消息在partition内部是有序的,但是Kafka不保证跨partition的消息顺序。每个partition只会被一个消费者组内的消费者消费,这样可以实现消息的负载均衡。
分组(Group):

目的:Kafka的消费者组的主要作用是消息负载均衡和消息广播。通过将多个消费者组织成一个消费者组,Kafka可以实现消息的并行消费,从而提高消息的处理效率。
特点:同一个消费者组中的多个消费者可以并行消费消息,以实现负载均衡。同时,消费者组也支持将消息广播给组内的所有消费者。此外,消费者组还保证了同一个消费者组中的消费者只会消费一次同一条消息,从而避免了消息的重复消费。

总结来说,Kafka的分区主要是为了扩展性和负载均衡,而消费者组则是为了实现消息的并行处理和避免重复消费。这两个机制共同协作,使得Kafka能够高效地处理大量的消息。

6.线程创建方式?

继承Thread类:通过继承Thread类并重写其run()方法,可以创建线程。在创建Thread类的子类时,需要将线程执行的代码放到run()方法中。然后创建Thread子类的实例,并调用该实例的start()方法来启动线程。

实现Runnable接口:通过实现Runnable接口并重写其run()方法,也可以创建线程。与继承Thread类不同,实现Runnable接口的方式可以将线程的任务与代码分离,使得代码更加灵活和可重用。创建Runnable实现类的实例,并将其作为参数传递给Thread类的构造函数,然后调用Thread对象的start()方法来启动线程。

实现Callable接口:Callable接口与Runnable接口类似,但Callable可以返回执行结果,并且可以声明抛出异常。创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。使用FutureTask对象作为Thread对象的target创建并启动新线程。调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。

使用线程池:通过Java提供的Executor框架的工具类Executors来实现。线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的ThreadFactory创建一个新线程。通过调用Executors的静态工厂方法,如newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor等,可以方便地创建线程池。

7.线程池有哪几个核心参数?

corePoolSize:线程池中的核心线程数量。这是在没有任务需要执行时线程池的基本大小。即使在线程处于空闲状态,核心线程也不会被销毁,除非设置了allowCoreThreadTimeOut并且该参数为true。

maximumPoolSize:线程池中允许的最大线程数量。当工作队列已满,且正在执行的线程数量达到corePoolSize时,线程池会创建新的线程来处理任务,但线程的数量不会超过这个值。

keepAliveTime:当线程池中的线程数量大于核心线程数量时,多余的空闲线程在等待新任务到来时能够存活的最长时间。如果当前线程池中的线程数量超过corePoolSize,那么这是多余的空闲线程在终止前等待新任务的最长时间。

unit:keepAliveTime参数的时间单位,例如TimeUnit.SECONDS。

workQueue:用于存放待执行任务的阻塞队列。当提交的任务数超过corePoolSize时,新提交的任务会先被存放在这个队列中。

threadFactory:用于创建新线程的工厂类。通过自定义ThreadFactory,可以设定线程的名称、是否为守护线程、优先级等属性。

handler:当线程池中的线程数量达到最大线程数量并且队列已满时的饱和策略。常见的策略有抛出异常、丢弃任务、丢弃队列中最老的任务、直接在调用者线程中执行等。

7.核心线程数怎么设置?

对于IO密集型的任务,由于IO操作(如读写文件、网络通信等)通常不会占用CPU,线程经常处于等待状态。因此,为了充分利用CPU资源,可以设置较多的线程。一种常见的设置方法是核心线程数等于CPU核心数的两倍,即 corePoolSize = CPU核心数 * 2。

对于CPU密集型的任务,由于任务主要消耗CPU资源,线程数过多可能导致频繁的上下文切换,反而降低性能。因此,核心线程数通常可以设置为CPU核心数加一,即 corePoolSize = CPU核心数 + 1。这个额外的线程可以确保在发生页面错误或其他原因导致一个线程暂停时,仍然有线程可以执行任务。

8. 上述CPU核心数如何知道?

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值