当前位置:   article > 正文

2023-04-16_面试题复盘笔记(72)_两个线程同时update

两个线程同时update

一、 京东Java面经

1.操作系统的作用

操作系统的主要作用是为用户提供一个简单易用的接口来管理计算机硬件和软件资源,同时也是计算机程序和数据之间的中间层。它提供了文件管理、内存管理、进程管理、设备管理等基本功能,使用户可以方便地运行应用程序和处理数据。操作系统还可以被看作是计算机硬件和用户程序之间的接口,帮助用户在计算机系统中完成各种任务。

2.七层网络,TCP与UDP区别,TCP可以看见https加密前的明文吗

七层网络是指ISO(国际标准化组织)制定的网络参考模型,它将计算机网络按照功能划分为七层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。每一层都有自己的功能和协议。
TCP(传输控制协议)和UDP(用户数据报协议)都是传输层的协议。TCP是面向连接的可靠传输协议,而UDP则是面向无连接的不可靠传输协议。区别在于TCP可以保证数据传输的可靠性和顺序性,而UDP则更加轻量级,适合传输不需要保障数据完整性的数据。
TCP不能看见HTTPS加密前的明文,因为HTTPS是TCP协议和SSL(安全套接层)协议的组合,SSL在传输层之上,可以加密传输的数据,保证传输的安全。

3.集合

Java中的集合主要分为List、Set、Map三种类型。其中List是按照元素的插入顺序有序存储的集合,Set是不允许有重复元素存在的集合,而Map则是以键值对的形式存储元素。Java提供了各种集合类的实现,如ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。同时,Java 8还引入了Stream API,使得集合操作具有函数式编程的特点,方便开发人员进行快速、简洁、高效的数据处理。

4.HashMap数据结构

HashMap是一种基于哈希表实现的数据结构,它能够以O(1)的时间复杂度来完成数据的插入、删除和查找操作。HashMap内部包含了一个数组和一个链表或红黑树,其中数组的每个元素又是一个链表或者红黑树。如果发生冲突,即两个不同的键映射到同一个位置上,它们将被存储在同一个位置的链表或红黑树中。HashMap是Java集合框架中最常用的数据结构之一。

5.key可以为空吗

在 HashMap 中,键和值都可以为 null,但是由于哈希表的限制,键不可以重复

6.ConcurrentMap底层数据结构和源码看过吗

ConcurrentMap是一个支持并发访问的键值对容器,它提供了一些新的方法来支持并发访问。其底层数据结构是通过Segment数组实现的,每个Segment是一个独立的Hash表,Segment之间互不影响,因此可以支持同时的读写操作。每个Segment中维护一个HashEntry数组来存储键值对,HashEntry中包含了一个key和一个value,以及一个next指针用来处理Hash冲突。
ConcurrentMap的源码的具体实现细节可能会因版本不同而略有差异。但总体思路是通过对Segment数组的加锁来保证并发访问的线程安全性,通过对HashEntry数组的操作来实现键值对的存储和查找。在并发访问时,读操作采用了乐观锁机制,避免了不必要的加锁和阻塞,提高了并发性能。

7.看过别的jdk源码吗

JDK源码指的是Java开发工具包(Java Development Kit)的源代码,包括了Java语言核心库、开发工具和Java虚拟机等。这些源代码可以帮助Java开发人员更深入地了解Java的内部实现和原理,也可以帮助开发人员定制和扩展Java平台。通常情况下,开发人员可以在Oracle官网上下载JDK源码。

8.Spring、 SpringMVC 、SpringBoot的区别

Spring是一个开源框架,用于构建企业级Java应用程序,并提供以下功能:依赖注入(DI)、面向切面编程(AOP)、模板模式、控制翻转(IOC)、数据访问、Web开发、批处理和消息队列等。
Spring MVC是在Spring Framework基础之上构建的Web开发框架,用于实现基于模型-视图-控制器模式的Web应用程序。它可以帮助开发人员轻松构建Web应用程序,并支持各种Web开发标准,如Declarative Transaction Management、Validation、Data Binding、Conversion、Security等。
Spring Boot是基于Spring Framework构建的快速应用程序开发(RAD)工具,它提供了一个快速、轻量级的方式来启动和运行独立的Spring应用程序。Spring Boot使用一些观念和技术(如自动配置、嵌入式Web服务器、命令行运行和无代码生成器)来加速应用程序开发和部署。
总的来说,Spring是一个核心框架,而Spring MVC和Spring Boot是基于Spring Framework构建的Web开发框架和快速应用程序开发工具。

9.Servlet重要方法

Servlet重要方法包括:
1.init()方法:初始化servlet对象并执行一些必要的操作。在servlet对象被创建时调用一次。
2.doGet()方法:处理HTTP GET请求,通常用于获取信息并将其呈现给用户。
3.doPost()方法:处理HTTP POST请求,通常用于提交表单数据并更新服务器上的数据。
4.service()方法:处理HTTP请求的入口方法,会根据请求的类型调用相应的处理方法(如doGet()、doPost()等)。
5.destroy()方法:当servlet被销毁时调用,可以在此方法中执行清理和释放资源的操作。

10.IOC与AOP

IOC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)都是面向对象编程中的重要概念。
IOC是一种设计模式,通过将对象创建与其依赖的对象创建分离,将对象的控制权反转给外部容器,以达到解耦的目的。
AOP则是在软件设计中,通过横向切割的方式,将一个复杂系统的各个功能模块进行解耦,减少系统的复杂度。
综合来说,IOC和AOP都是为了解决代码耦合带来的问题,使得系统更加灵活、易于维护和扩展。

11.JDK动态代理需要的类

JDK动态代理需要的类主要有两个,分别是java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler。其中,Proxy类负责动态生成代理类,InvocationHandler接口则是代理类中需要实现的方法。此外,还需要被代理类所实现的接口。

12.InnoDB与MyISAM区别

InnoDB和MyISAM是MySQL数据库存储引擎的两种类型。最大的区别在于它们的锁机制和事务支持。InnoDB支持行级锁和事务处理,可以在高并发的情况下更好地保护数据完整性和一致性。而MyISAM没有行级锁和事务支持,适合于读取频繁、写入少的应用场景。此外,InnoDB还支持外键约束、崩溃恢复等功能。

13.InnoDB与MyISAM底层存储有什么区别

InnoDB和MyISAM是MySQL的两种不同存储引擎,它们的底层存储方式有以下几个区别:
1.InnoDB支持事务处理,而MyISAM不支持。这意味着InnoDB保证了数据的完整性和一致性。
2.InnoDB采用了行级锁,而MyISAM采用了表级锁。这意味着在高并发的情况下,InnoDB可以实现更好的并发处理能力,减少了锁定的竞争。
3.InnoDB支持外键,而MyISAM不支持。这意味着InnoDB可以更好地管理数据完整性和约束。
4.InnoDB的数据和索引采用了聚集(Clustered)方式,而MyISAM则采用了非聚集(Non-clustered)方式。这意味着InnoDB的数据和索引存储在一起,可以提高查询效率。
5.InnoDB支持MVCC(多版本并发控制),而MyISAM不支持。这意味着InnoDB可以实现更好的并发控制能力,可以处理高并发的读写请求,避免锁定的竞争。

14.InnoDB索引存储结构

InnoDB索引存储结构采用了B+树的数据结构,每一个节点都包含了一组键值以及对应的数据指针,这些节点通过指针进行连接,形成了一个多层次的树形结构。在使用B+树时,InnoDB会将数据按照键值大小分成多个页,每页的大小为16KB,默认情况下根据性能的不同,InnoDB采用了不同的页大小。另外,为了保证数据的一致性和可靠性,InnoDB采用了多种技术进行数据管理,如事务机制、锁机制、MVCC等。

15.B+有几层

InnoDB索引存储结构B-tree有三层,分别为根节点、非叶子节点和叶子节点。
1.根节点:B-tree的根节点是一组指针,指向B-tree的非叶子节点或叶子节点。在InnoDB中,根节点的指针数量为1,指向B-tree的第一层非叶子节点。
2.非叶子节点:非叶子节点也是一组指针,指向下一层的非叶子节点或叶子节点。在InnoDB中,每个非叶子节点最多有1024个子节点(即1024个指针)。
3.叶子节点:叶子节点存储了实际的数据行和对应的索引信息。在InnoDB中,每个叶子节点最多存储16KB的数据行。
总体来说,InnoDB的B-tree索引结构层数少、每个节点的指针数量多,这样可以提高索引的查找效率。

16.隔离级别

MySQL的隔离级别包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。

17.MVCC

MVCC是多版本并发控制(Multi-Version Concurrency Control)的缩写,是一种数据库管理系统的技术,可以提供并发控制和事务隔离。它能够处理多个事务并发访问数据时产生的读写冲突问题,同时保证了数据的一致性和完整性。在MVCC中,每个事务都看到数据库中一定时间范围内的快照版本,而不是实时的数据库状态,每个版本都有一个唯一标识符,使得每个事务都可以读取和修改自己的快照版本。

18.Redis业务使用场景

Redis在业务中可以用于以下场景:
1.缓存:可以将热点数据缓存到Redis中,从而减少从数据库中获取数据的压力。
2.计数器:可以将Redis的计数器作为统计日活跃用户、PV、UV等数据的工具,提高统计数据的可靠性和准确性。
3.分布式锁:利用Redis的原子性操作和expire设置来实现分布式锁,保证系统中的数据一致性。
4.任务队列:使用Redis的list数据结构作为任务队列,实现异步任务的执行,提高系统的吞吐量和响应速度。
5.排行榜:可以使用Redis的有序集合实现排行榜,实时展示各种数据的排序情况,如网站的热门商品、热门文章等。

19.Redis支持那些数据结构

Redis支持多种数据结构,包括string、hash、list、set、zset等。其中,string类型是最基本的数据结构,其余的数据结构都是在string类型的基础上进行扩展的。

20.业务题:秒杀该怎么设计

秒杀系统设计应考虑以下几个方面:
1.流量控制:秒杀活动对服务器的访问量会非常高,必须采用合理的流量控制策略,避免系统崩溃。可以采用CDN、负载均衡等技术来分散流量,确保服务可用性。
2.订单处理:秒杀系统需要及时处理消费者的订单,尤其是高并发情况下。可以采用队列等技术缓解压力,确保订单实时处理。
3.数据库优化:秒杀系统会面临大量的访问请求,如果数据库读写能力不足,则很容易崩溃。可以采用Redis等中间件进行缓存,减轻数据库负载。
4.安全性措施:由于秒杀活动的高人气,通常会受到黑客攻击。应加强系统的安全性措施,防止攻击和恶意刷单。
5.反作弊手段:为了避免抢购者和机器人占据系统资源,可以采用验证码、IP限制等策略,阻止非法操作。
以上是秒杀系统设计的几个方面,需要根据具体情况进行调整和优化。

21.设计模式

设计模式是一种在软件设计过程中用来解决常见问题的方法。它们是在不改变现有程序的基础上,提供一种更好的解决方案的方法。设计模式通常是一种常见的解决方案,可以通过重复使用来提高程序的可扩展性、可重用性和可维护性。常见的设计模式包括单例模式、工厂模式、模板方法模式和观察者模式。

二、 阿里巴巴阿里云后端面经

1.数据库怎么分类,描述一下你对这些数据库的理解

数据库可以根据不同的分类方式进行分类,目前比较常用的分类方式包括关系型数据库和非关系型数据库。
关系型数据库是指数据以表格形式存储,并且不同表格之间有关联和连接。常见的关系型数据库有MySQL、Oracle、Microsoft SQL Server等。
非关系型数据库则不是以表格形式存储,常见的非关系型数据库有MongoDB、Cassandra、Redis等。这些数据库通常存储的是大规模非结构化或半结构化数据,例如网络日志、社交媒体数据等。
在这些数据库中,每一种数据库都有其特点和适用场景。关系型数据库的特点是数据结构清晰、事务处理能力强,适合存储结构化数据,例如金融交易数据、网站用户数据等。而非关系型数据库的特点是数据量大、扩展性强、可处理半结构化和非结构化数据,适合存储海量数据以及需要高并发读写和处理数据的应用场景。

2.什么情况使用MySQL,什么情况使用Redis

MySQL和Redis都是常用的数据库管理系统,但它们具有不同的特点和用途。通常情况下,MySQL适用于需要长期保存数据的情况,比如企业的后台管理系统、电商网站的订单管理系统等;而Redis则适用于需要高速读写的场景,比如缓存、队列、分布式锁等。如果应用场景需要频繁地进行数据读写和查询操作,建议使用Redis,如果应用场景需要长期保存数据,并进行复杂的查询操作,建议使用MySQL。

3.Redis有什么持久化策略

Redis有两种持久化策略:RDB和AOF。RDB是将当前进程中的数据快照保存到磁盘中,而AOF则是将每个写操作都追加到一个文件中。RDB比较适合用在数据集较大,但是数据改动不频繁的情况下。而AOF则比较适合用在数据改动频繁的情况下,因为AOF能够提供更高的数据安全性和可读性。可以根据实际业务需求来选择合适的持久化策略。

4.MySQL有哪2种引擎,说一下它们的区别

InnoDB和MyISAM是MySQL的两种不同存储引擎,它们的底层存储方式有以下几个区别:
1.InnoDB支持事务处理,而MyISAM不支持。这意味着InnoDB保证了数据的完整性和一致性。
2.InnoDB采用了行级锁,而MyISAM采用了表级锁。这意味着在高并发的情况下,InnoDB可以实现更好的并发处理能力,减少了锁定的竞争。
3.InnoDB支持外键,而MyISAM不支持。这意味着InnoDB可以更好地管理数据完整性和约束。
4.InnoDB的数据和索引采用了聚集(Clustered)方式,而MyISAM则采用了非聚集(Non-clustered)方式。这意味着InnoDB的数据和索引存储在一起,可以提高查询效率。
5.InnoDB支持MVCC(多版本并发控制),而MyISAM不支持。这意味着InnoDB可以实现更好的并发控制能力,可以处理高并发的读写请求,避免锁定的竞争。

5.MySQL两个线程的update语句同时处理一条数据,会不会有阻塞

会有阻塞的情况发生,因为MySQL的行级锁机制会导致多个线程同时对一条数据进行update时会被阻塞,直到前一个线程释放锁为止。这种情况下,后一个线程需要等待一段时间才能获得锁并继续执行。为了避免这种情况,可以考虑修改数据表的结构,使用其他的锁机制,或者处理数据时避免使用并发。

6.滥用事务,或者一个事务里有特别多sql的弊端

滥用事务或一个事务中有过多的SQL语句会导致数据库的性能下降和负载增加。这是因为事务的提交需要一定的时间和资源,在一个事务中进行大量的数据操作会增加事务提交的时间和资源消耗。此外,如果在一个事务中进行了大量的数据修改操作,可能会导致锁冲突,从而影响并发性能。因此,应该限制事务中的SQL语句数量,并确保事务的时间不要过长,避免出现性能问题。

7.两条update语句处理一张表的不同的主键范围的记录,一个<10,一个>15,会不会遇到阻塞?底层是为什么的?

这取决于具体的数据库管理系统和锁机制的实现。一般来说,如果两个update语句处理的是同一个表的不同的主键范围的记录,会出现锁竞争的情况。如果这些记录使用了行级锁,那么可能会出现死锁问题。如果使用的是表级锁,则可能会出现长时间的阻塞。这是因为每个SQL语句都需要获得一个锁,如果某个语句的锁正在被另一个语句占用,则需要等待这个锁被释放。这可能导致一些语句无法立即执行,从而导致阻塞。出现这种情况的底层原因是由于并发访问数据库时,需要保证数据的一致性和完整性,需要使用锁机制来控制并发操作的顺序和频率。

8.如果2个范围不是主键或索引?还会阻塞吗?

根据事务隔离级别的不同,可能会出现阻塞的情况。如果两条update语句希望更新同一条记录,并且这两条语句没有加锁或者使用了不同类型的锁(例如,一个使用排它锁,一个使用共享锁),那么可能会出现阻塞的情况。此时,一条语句需要等待另一条语句释放锁才能继续执行。
如果这两个范围都不是主键或索引,那么数据库引擎可能需要对整个表进行扫描,为每个记录逐个检查,以决定记录是否处于要更新的范围内。这可能会导致大量的IO操作和CPU开销,进而加剧阻塞问题。
解决这个问题的方法之一是使用合适的索引,以便数据库引擎可以快速地定位到要更新的记录。另外,合理地设置事务隔离级别和使用锁也可以缓解阻塞问题。

9.除了表锁,行锁这些,还有别的形式的锁吗?

除了表锁和行锁,还有页锁和键值锁等其他形式的锁。页锁是对整个页进行加锁,而键值锁则是针对数据表的每个键值进行加锁。不同的锁类型适用于不同的并发访问场景。

10.从设计数据库,编写sql,加锁等方面来对数据库方面的工作做一个总结

数据库方面的工作主要包括设计数据库结构、编写 SQL 语句、加锁等方面。下面我来分别进行总结:
1.设计数据库结构
设计数据库结构是数据库开发中的第一步,它决定了数据库的性能、可扩展性和可维护性。一个好的数据库结构应该能够支持业务需求,同时也应该能够保证数据的完整性和安全性。
在设计数据库时,需要考虑以下几个方面:
1.数据库范式:选择适合业务需求的范式,比如第三范式、反范式等。
2.数据库表结构:合理设计表结构,包括表的字段、主键、外键、索引等。
3.数据库关系:确定数据库表之间的关系,包括一对一、一对多、多对多等关系。
4.数据库安全:采取合适的安全措施,比如限制用户权限、使用加密等方法保护数据安全。

2.编写 SQL 语句
SQL 是数据库管理系统中最重要的语言之一,它用于管理和操作数据库。编写 SQL 语句需要熟悉 SQL 语法和数据库特性,同时也需要了解业务需求和数据结构。
在编写 SQL 语句时,需要注意以下几个方面:
1.SQL 语句的性能:优化 SQL 语句,减少查询时间和资源消耗。
2.SQL 语句的复杂度:尽可能简化 SQL 语句,避免使用复杂的子查询等语句。
3.SQL 语句的安全性:加入适当的安全措施,如防 SQL 注入等。

3.加锁
加锁是数据库管理中的一个重要概念,它用于保证并发访问时数据的完整性和一致性。加锁分为共享锁和排他锁两种,共享锁用于读操作,排他锁用于写操作。
在加锁时,需要注意以下几个方面:
1.加锁的范围:尽可能缩小加锁的范围,避免出现死锁和资源浪费。
2.加锁的时机:在需要修改数据时才加锁,减少锁的竞争和等待时间。
3.加锁的优先级:给写操作优先级,避免读操作长时间等待。
总之,数据库方面的工作需要熟悉数据库结构设计、SQL 语句编写和加锁等知识,同时也需要了解业务需求和数据结构,才能够开发出高性能、可扩展和可维护的数据库系统。

11.谈一下对线程和进程的理解

进程是操作系统资源分配的基本单位,每个进程都有自己独立的内存空间、代码和数据等资源。进程之间的通信需要使用进程间通信(IPC)机制,例如管道、消息队列、信号量等。
而线程是进程内部的一个执行单元,线程共享进程的代码和数据空间,并拥有自己的栈空间和程序计数器等资源。由于线程共享进程的资源,所以线程间通信比进程间通信更加方便。但同时也需要考虑线程间的同步和互斥,以避免资源竞争和死锁等问题。
总的来说,进程和线程可以使操作系统更加高效和灵活地运行不同的任务,但对于不同的应用场景和需求,需要选择合适的方式来实现。

12.多线程比单线程的优势,劣势

多线程的优势是可以提高程序的并发性和执行效率,能够更好地利用多核处理器的计算能力,同时可以提高程序的响应速度和用户体验。不过,多线程也有一些劣势,如线程间的同步和协调比较复杂,容易出现死锁和竞态等问题,需要对程序进行仔细的设计和优化。

13.Java创建线程有几种方式

在 Java 中,有两种主要的方式来创建线程:继承 Thread 类和实现 Runnable 接口。另外,也可以使用 Executor 框架、Callable 和 Future 接口来创建线程。

14.线程池有哪些优势

使用线程池有以下几个优势:
1.提高性能:线程池能够复用线程,避免了线程的频繁创建、销毁的开销,因此能够降低系统负载,并提高程序的性能。
2.提高响应速度:线程池能够提高线程的调度效率,线程池中的线程可以共享资源,不会因为某个线程的阻塞而影响其它线程的执行,从而提高系统的响应速度。
3.控制资源:线程池能够对线程的并发数量进行限制,防止资源耗尽、系统崩溃等情况的发生。
4.提高可管理性:线程池能够很好地管理线程,例如线程的创建、销毁、维护等,使得系统更加易于维护和管理。

15.说一下面对对象3大特性理解

面向对象(OOP)的三个主要特征是封装,继承和多态。
1.封装:指的是将数据和行为组合在一个单元中,将数据和方法组合成一个类,且在类中对外隐藏实现细节,只提供公共的访问方法,保证内部数据的安全性和完整性,也即保护数据。
2.继承:指某个类别的属性(数据成员)和方法可以被另一个类别所使用,同时又保留了自己的特性
3.多态:指同一个方法调用,不同的对象会有不同的实现,即同一接口,不同实现。多态可以分为编译时多态和运行时多态。编译时多态是指在编译时就能确定实际调用哪个具体的方法,也成为静态多态。运行时多态是指在运行时根据实际情况确定调用哪个方法,也成为动态多态。

16.Java有什么常用的集合类?

Java有很多常用的集合类,包括List、Set、Map等。其中,List可以用来存储有序的元素序列,Set用于存储不重复的元素集合,Map用于存储键值对。常用的实现类有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等。

17.有哪些集合类是线程安全的,哪些是不安全的?

Java中的集合类大致可以分为两种:线程安全的集合和非线程安全的集合。
线程安全的集合类:
1.ConcurrentHashMap:ConcurrentHashMap是线程安全的HashMap,支持高并发的读和写,采用了分段锁的机制,可以保证多个线程同时访问时的线程安全。
2.CopyOnWriteArrayList:CopyOnWriteArrayList是线程安全的ArrayList,支持高并发的读和写,写操作会先复制一个新的数组,然后将新元素添加到新数组中,最后将原数组引用指向新数组,因此读操作不会受写操作的影响,可以保证线程安全。
3.ConcurrentLinkedQueue:ConcurrentLinkedQueue是线程安全的队列,采用了无锁(CAS)算法,支持高并发的添加、删除和查找元素。
4.BlockingQueue:BlockingQueue是一个阻塞队列,支持多线程并发访问,提供了阻塞机制,当队列为空时,消费者线程会被阻塞,当队列满时,生产者线程会被阻塞,可以保证线程安全。
非线程安全的集合类:
1.ArrayList:ArrayList是一个非线程安全的集合类,不支持多线程并发访问,如果多个线程同时对ArrayList进行修改,就会出现线程安全问题。
2.LinkedList:LinkedList也是一个非线程安全的集合类,不支持多线程并发访问,如果多个线程同时对LinkedList进行修改,就会出现线程安全问题。
3.HashMap:HashMap也是一个非线程安全的集合类,如果多个线程同时对HashMap进行修改,就会出现线程安全问题。
4.HashSet:HashSet也是一个非线程安全的集合类,如果多个线程同时对HashSet进行修改,就会出现线程安全问题。

18.数组和链表有什么区别?

数组和链表是两种不同的数据结构。
数组是一组有序的元素集合,每个元素可以通过下标访问,也即在内存中是一段连续的空间。数组的优点是随机访问元素非常快速,但插入和删除元素的效率较低。
链表是由一组结点组成的集合,每个结点包含数据和指向下一个结点的指针,它们在内存中不是连续的空间,通过指针实现链式链接。链表的优点是插入和删除元素较快,但随机访问元素的效率较低。
因此,在实际使用时,需要根据具体的需求,选择不同的数据结构。

19.堆和栈的区别?

堆和栈都是计算机内存中的存储区域。堆是动态分配的内存区域,而栈是静态分配的内存区域。其区别在于,堆的分配和释放是由程序员控制的,而栈的分配和释放是由编译器自动进行的。堆可以通过调用malloc和free等函数来分配和释放内存,而栈则是通过函数的调用和返回来进行操作。堆的使用需要手动操作,需要注意内存泄漏和访问越界的问题,而栈则相对来说更加安全可靠。

20.Set集合有什么特点?如何实现key无重复的?

Set集合的特点是它是一种无序的数据结构,其中每个元素都是唯一的。在Set集合中,每个元素只能出现一次。Set集合可以用于去重、排序等场景。
实现key无重复的方式可以使用哈希表,也就是将每个key映射到唯一的一个位置上,如果有两个不同的key映射到同一个位置,则需要解决冲突,常用的解决冲突的方法有链地址法和开放寻址法。在哈希表的基础上,可以实现Set集合的特性,即保证元素唯一且无序。

21.有序的Set是什么?记录插入顺序的集合是什么?

有序的Set是指其中的元素是按照某种顺序进行排序的集合,例如按照元素大小升序排序。记录插入顺序的集合是指其中的元素是按照插入顺序进行排序的集合,例如第一个插入的元素排在第一个,第二个插入的元素排在第二个,依次类推。在Java中,可以使用LinkedHashSet来实现有序的Set集合,使用LinkedHashMap来实现记录插入顺序的集合。

22.Linux操作系统中哪个命令可以查看端口被哪个应用占用?

您可以使用 lsof 命令来查看端口被哪个应用占用。具体命令为:lsof -i:端口号。例如,要查看端口号为8080的应用使用情况,可以执行如下命令:lsof -i:8080。

23.网络有什么常用的通信协议?前后端交互用的是什么协议?

常用的网络通信协议包括HTTP、TCP、UDP、FTP等。前后端交互一般使用HTTP协议

24.场景题:想要实现一个100qps的限流策略,怎么从后端进行设计

实现100qps的限流策略需要结合后端工作负载和系统架构进行设计。以下是一些可能的实现策略:
1.在服务器端使用令牌桶算法来限制每个客户端的请求速率,从而达到限流的目的。具体做法是,在服务器端维护一个令牌桶,每当客户端发送请求时从令牌桶中取出一个令牌,当令牌桶中没有令牌时拒绝请求。可以根据服务器处理能力和客户端连接数调整令牌桶的大小,从而达到100qps的限流目标。
2.使用分布式缓存技术来限制请求速率。例如,利用Redis的有序集合数据结构来存储请求时间戳,每次请求时判断时间戳集合中最早的请求时间是否在限定时间窗口内,如果在则拒绝请求,否则添加新的时间戳到集合中。
3.使用反向代理服务器来进行限流。例如,利用Nginx反向代理服务器提供限流功能,设置连接数和速率限制来达到限制请求速率的目的。可以根据实际情况调整Nginx的配置文件来满足100qps的限流需求。
总的来说,实现100qps的限流策略需要考虑多个因素,包括后端负载、系统架构、客户端连接数等,而具体的实现方法也需要根据实际情况进行调整和优化。

25.场景题:对于一个集群系统,如何实现上面的技术

针对一个集群系统实现100qps的限流策略,可以从多个方面进行设计。这里提供一些可能的方案:
1.网关限流:在系统前置一个网关,通过配置参数实现对接口访问频率进行限制,可以使用开源的API网关如Kong或者商用的服务如阿里云网关,实现限流的策略。
2.算法限流:在集群系统中,在代码层面实现对接口访问频率的限制。常用的算法有令牌桶和漏桶算法。也可以使用Redis作为内存缓存,通过Redis的incr和expire命令实现限流。
3.服务端限流:在每个服务端节点独立进行限流,让每个服务实例通过相互协作,从而在整个集群系统范围内实现限流。
以上仅是针对限流设计的一些思路,具体实现需要根据集群系统的具体情况进行综合考虑。

三、美团到家

1.介绍一下项目吧,再介绍下其中Redis的使用场景?点赞关注这个场景,里面存的什么数据?

Redis的使用场景很多,其中包括缓存、消息队列、计数器、排行榜等。在点赞关注这个场景中,可以使用Redis存储用户点赞和关注的信息。具体来说,可以使用Redis的set类型来存储用户点赞和关注的数据,使用哈希表存储对应的用户和被点赞或者被关注的对象之间的关系。这样,有了Redis的支持,可以实现快速查询、高并发操作等功能。

2.redis的String和其他的语言有什么区别

Redis的String和其他语言的String有几个主要的区别:
1.Redis的String可以存储二进制数据,而其他语言的String通常只能存储文本数据。
2.Redis的String可以设置过期时间,而其他语言的String没有这个功能。
3.Redis的String可以支持一些特殊的操作,比如自增、自减等,而其他语言的String没有这些操作。
4.Redis的String可以在内存中存储,因此读写速度非常快,而其他语言的String通常需要在硬盘上读写,速度较慢。
总体来说,Redis的String比其他语言的String更加灵活、高效,也更适合一些特殊的场景。

3.你刚刚说存储点赞关注信息的时候,都会涉及Redis的什么操作啊?就是说会触发后面什么流程?

当使用 Redis 存储点赞关注信息时,通常会使用 Redis 的以下操作:
1.sadd:将用户 ID 添加到点赞或关注的集合中。
2.srem:将用户 ID 从点赞或关注的集合中移除。
3.scard:获取点赞或关注的集合的大小。
4.smembers:获取点赞或关注的集合的成员列表。
5.expire:设置点赞或关注的集合的过期时间,保证数据不会永久存储在 Redis 中。
当触发上述操作时,通常会触发对应的回调函数,从而对数据库中的数据进行增删改查等操作。这些操作的具体流程取决于具体的业务需求和实现方式。

4.我俩同时点赞的话,可能会让这个数据只加1吗?

当你点赞或关注一个用户的时候,会根据对应的键(key)来执行相关的操作,将点赞或关注的数量加1。如果您俩同时点赞,Redis会根据指定的键(key)对该数据进行原子增加操作,确保数据的一致性,所以不会出现只加1的情况。

5.Set的话,它的这个数据结构是啥样的啊?

Set是一种无序且不重复的数据结构,它包含多个元素,每个元素都是唯一的。在Redis中,Set是通过哈希表实现的,每个元素都被存储在哈希表中的一个键值中。因此,Set支持快速的插入、删除和查询操作,同时也支持集合运算,如求交集、并集和差集等。

6.帖子和评论存在哪里的?两个表吗?表字段怎么设计的?

7.Kafka场景?

Kafka可以用于消息队列、日志收集和流处理等场景。比如,可以将Kafka用作网站活动日志的收集器、分布式提交日志的中心、数据感知型应用程序的缓存层、复杂事件处理系统的持久存储层等。同时,Kafka具有高吞吐量、可扩展性好、持久性高、容错性强等特点。

8.什么场景下发的Kafka消息?消费的业务逻辑是什么?

Kafka作为日志系统时,一般是在分布式系统中的服务间通信场景下使用。Kafka消息通常包含了系统中各个服务产生的日志信息,这些日志信息可以通过Kafka消息传递到消费端,进行后续的处理或者存储。在消费端,业务逻辑一般是将日志信息进行解析,过滤或者聚合,并将其存储到其他的系统中,如MySQL或者HDFS等。同时,Kafka也支持批量消费和实时消费两种模式,可以根据具体业务场景进行选择。

四、京东物流二面凉经

1.微服务调用openfeign底层怎么调用的原理

在微服务架构中,服务之间的调用通常使用HTTP协议进行通信。OpenFeign是一个用于简化微服务之间RESTful通信的客户端工具,它本质上就是对HttpClient进行了封装。
在底层,OpenFeign使用了Java的动态代理技术来生成实现接口的代理类,当调用该代理类的方法时,实际上是通过RestTemplate发送HTTP请求到服务提供方的相应接口上。OpenFeign还提供了一些高级特性,例如负载均衡、断路器等,可以提升微服务之间通信的可靠性和效率。

2.分布式事务,缓存和数据库的一致性保持。

在分布式系统中,当涉及到缓存和数据库的一致性保持时,我们通常会采用两阶段提交协议(2PC):
1.在第一阶段,协调者(通常是事务管理器)会向参与者(包括缓存和数据库)询问他们是否可以提交事务。
2.在第二阶段,如果所有参与者都同意提交事务,协调者会让参与者执行事务,并将事务持久化。
这种方法可以保证在涉及多个参与者的情况下保持数据一致性。但是,2PC 也有它的限制,例如它可能会导致锁定,以及可能会导致高网络延迟。
此外,分布式缓存通常会提供自己的数据一致性保持机制,例如 memcached 中的 CAS(Compare And Swap)协议。这些机制可以帮助我们更加高效地保持数据一致性。

3.MyBatis的缓存

MyBatis的缓存分为一级缓存和二级缓存。一级缓存是指SqlSession级别的缓存,也就是同一个SqlSession对象中执行相同SQL语句得到的结果可以直接从缓存中获取,不需要再向数据库发起请求。二级缓存是指Mapper级别的缓存,它是多个SqlSession对象共享的缓存,可以减少对数据库的访问次数,提高应用性能。但是需要注意的是,二级缓存需要手动开启并配置,而且对于更新操作,需要特别小心,一旦修改数据,就需要清空相应的缓存。

4.RabbitMQ、Kafak、RocketMQ区别

RabbitMQ、Kafka和RocketMQ都是流行的分布式消息中间件。它们的共同点是都可用于消息传递、异步通信等场景,但也存在一些区别:
1.RabbitMQ基于AMQP协议,Kafka和RocketMQ基于自身设计的协议。
2.RabbitMQ和Kafka都是高吞吐量的消息队列系统,而RocketMQ则更加注重消息的可靠性。
3.RabbitMQ和RocketMQ支持多种编程语言,而Kafka则只支持Java和Scala。
4.RabbitMQ支持消息的确认机制,而Kafka和RocketMQ则支持消息的顺序性。
总之,选择哪个分布式消息中间件要根据实际需求来考虑。

5.慢查询索引失效,b+树分库分表高并发除了加锁还有什么解决方案

针对慢查询索引失效,可以考虑以下几种解决方案:
1.优化查询语句:通过优化查询语句,尽可能利用索引,减少全表扫描;
2.调整数据存储方式:使用更合适的数据存储方式,例如将数据从关系型数据库转移到 NoSQL 数据库中;
3.调整硬件配置:包括增加 CPU、内存等硬件资源,提高数据库性能;
4.优化索引创建方式:可以尝试创建复合索引或覆盖索引来提高查询效率;
5.分库分表:将数据按照一定的规则分散到多个库或表中,减小单个表的数据量,从而提高查询效率;
6.采用缓存技术:通过缓存系统,将常用的数据存储在缓存中,避免频繁查询数据库。
至于 B 树分库分表高并发的解决方案,除了加锁,还可以考虑以下方法:
1.引入分布式锁:分布式锁可以保证分布式系统中的并发控制,避免数据的重复修改和读写冲突;
2.采用分布式数据库:通过分布式数据库部署,可以将数据垂直或水平分布到多个节点中,实现横向扩展,提高并发处理能力;
3.使用缓存技术:将热点数据缓存到内存中,可以大大减少数据库的访问次数,提高并发能力;
4.异步消息队列:通过异步消息队列解耦请求与响应,把高并发请求路由到异步处理队列中,提高系统并发处理能力。

6.kafak持久化内存满了除了迁移还能怎么办?

您可以考虑以下两个解决方案:
1.增加持久化磁盘:您可以将持久化日志写入磁盘而不是内存中。这样可以避免内存溢出问题,但是可能会影响性能。
2.压缩日志:您可以启用Kafka的日志压缩功能来减小日志文件的大小,从而释放内存空间。但是,压缩日志会增加CPU负载和I/O延迟。
请注意,这只是一些可能的解决方案,并不一定适用于所有情况。在具体操作中,请务必谨慎评估和测试解决方案的可行性。

五、上海同余Java一二面

一面:

1.缓存的是什么? 还有哪些类似Integer这样的数据结构?

关于缓存,通常用于临时存储数据或结果,以减少重复计算或访问时间。除了Integer,还有其他像Float、Double、Long等数据结构。

2.String为什么是不可变的 常量池除了字符串还有什么String被final类型修饰,并且数据内部由一个被final修饰的char数组保存,且并未提供修改数组的方法

String是不可变的常量,是因为Java的设计者认为这样可以提高系统的性能和安全性。在Java中,String是一个特殊的类,它是final类型的,意味着无法被继承和修改。
除了字符串外,Java还有其他类型的不可变常量,比如Integer、Boolean、Double等基本数据类型的包装类。这些包装类在创建后就不允许更改其值,从而保证了它们的安全性和稳定性。
String被final类型修饰,是因为一旦它被创建,就不应该再被修改。此外,String内部使用一个final修饰的char数组来保存数据,这个char数组也不能被修改,从而避免了可能会导致不可预测结果或安全问题的问题。

3.JDK 10 11 有什么新特性

JDK 10和JDK 11的新特性如下:
JDK 10:
1.局部变量类型推断:可以使用关键字“var”来推断变量类型,使得代码更加简洁。
2.应用类数据共享(Application Class-Data Sharing):在JDK 9的基础上进一步优化,出现更多的默认加载器的文件映射。
3.新增的垃圾收集器:增加了一种实验性的垃圾收集器,即G1垃圾收集器。
JDK 11:
1.HTTP客户端(HttpClient): 提供了一种新的Http客户端API,使JDK拥有了完整的Http/2实现。
2.Epsilon GC:提供一种实验性的GC,主要用于性能测试和短时间运行的任务。
3.ZGC:提供了一个新的并发垃圾回收器,使得JDK现在可以处理更大内存的堆。
4.Application Class-Data Sharing的增强:现在还可以在传递模块路径相关的操作时享受在类路径模式下的良好体验。
请注意,这些特性可能会因为不同的JDK版本或发行版而有所差异。

4.讲讲Spring,有什么好处 动态代理怎么实现的 动态代理和代理模式有什么区别(字节码) 为什么Java可以实现热加载C++不行

Spring作为一个业界领先的开源框架,具有以下优点:
1.依赖注入和控制反转,减少了代码耦合度,使得代码更加灵活可扩展;
2.AOP 技术,将多个模块之间的复杂逻辑分离出来,简化了项目结构;
3.支持声明式事务管理,使得数据操作更安全可靠;
4.提供了丰富的模板类,大量减少了常用代码的编写量。
动态代理是 Java 语言中常用的一种设计模式,主要作用是在运行时生成代理类。实现方式有两种:JDK 动态代理和 CGLIB 动态代理。JDK 动态代理是通过反射机制实现的,因此必须有接口,不能为类进行代理。CGLIB 动态代理则是通过继承和字节码技术实现的,可以为类和接口进行代理。
动态代理和代理模式有所不同,代理模式主要是通过一个公共的接口对多个类进行代理管理,让客户端通过代理来访问实际对象,而不必直接与实际对象打交道。动态代理则是在运行时生成代理对象,动态地为对象添加功能。
Java 可以实现热加载是因为 JVM 具有独特的类加载机制,通过将类加载器分为不同的层次,可以实现在运行时替换新旧类,从而达到热加载的效果。而 C 语言没有这种机制,因此无法实现热加载。

5.Spring boot在spring基础上做了什么,说说Spring boot自动装配

Spring Boot 是建立在 Spring 框架之上的,它的主要作用是简化 Spring 应用程序的创建和开发。Spring Boot 为开发人员提供了丰富的自动化配置和定制选项,同时也提供了各种工具和插件,使得开发人员能够更加高效地完成开发工作。
其中,Spring Boot 的自动装配功能是其最重要的特性之一。Spring Boot 可以通过自动扫描和自动配置的方式,对 Spring 应用程序中需要的各种组件进行自动装配。这样开发人员就不需要手动配置各个组件之间的依赖关系,减少了出错的机会,并且可以大大提高开发效率。
以某个示例为例,Spring Boot 可以自动配置一些常用的组件,例如数据源、缓存管理器、Web 框架、安全框架等等。这些组件可以根据应用程序的需要进行定制,通过修改配置文件即可达到目的。
总而言之,Spring Boot 建立在 Spring 框架之上,提供了自动装配和定制化等丰富的功能,可以帮助开发人员更加高效地完成应用程序的开发工作。

6.Spring data怎么去配置数据库连接(为什么这样能配置), 默认的连接池是什么,为什么要用德鲁伊 ,不用配置文件怎么创建DB链接 怎么能够利用到

Spring Data通过在Spring配置文件或Java代码中设置一些参数,就可以配置数据库连接。例如,可以使用以下代码来配置MySQL数据库连接:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.example.repository"})
public class DatabaseConfig {
 
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        return dataSource;
    }
 
    //Other bean configurations
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在上面的代码中,我们使用了@Configuration注释表示这是Spring配置类。使用@EnableTransactionManagement注释来启用Spring事务的支持。使用@EnableJpaRepositories注释设置包含和管理JPA存储库的位置。
Spring Data默认使用Tomcat连接池。 Tomcat JDBC连接池是一个功能丰富且可配置的连接池实现,是Tomcat应用服务器内置的连接池组件。
如果要使用其他连接池实现,例如德鲁伊连接池,可以在Spring配置文件中进行配置。
创建DB连接可以使用Spring的JdbcTemplate,通过使用JdbcTemplate的execute方法来创建连接。然而,Spring已经为我们提供了更方便的方式,

7.Spring提供了声明式事务,说说编程式事务

编程式事务是通过编写代码实现事务管理的方式。它需要在代码中显式地对事务进行管理,例如开启事务、提交事务、回滚事务等。编程式事务需要程序员编写大量的重复代码来进行事务管理,这样会增加代码量和复杂度。同时,如果一个方法中有多个事务,编程式事务也无法保证事务的一致性。
相比之下,声明式事务更加简单、灵活,它是通过注解或配置文件的方式来实现事务管理。在使用Spring的声明式事务时,开发人员只需要定义好事务管理的基本属性,然后将其配置到Spring的配置文件中即可。这样可以显著简化代码编写的难度,提高代码的可读性和可维护性。同时,声明式事务也可以保证多个事务的一致性。

8.Redis是单线程还是多线程的体现,为什么快?

Redis是单线程的。虽然Redis是单线程的,但它采用了异步的I/O多路复用机制,能够高效地处理并发请求,同时采用了多种内存优化策略和数据结构,如基于快速列表(quicklist)的高性能链表和基于跳跃表(skip list)和哈希表的高效实现,这些优化措施都使得Redis的查询速度与响应速度都非常快。

9. 多路复用是什么

多路复用是一种基于一个信道同时传输多个信号的技术,它可以将多个输入信号经过合理的处理后,通过同一信道同时传输,从而提高信道的传输效率。通过使用多路复用技术,可以在同一信道上传输多路独立的数据流。常见的多路复用技术有时分复用、频分复用和波分复用等。

二面:

10.数据结构数组和链表区别,增删改查时间复杂度

数组和链表都是常见的数据结构,它们的区别如下:
1.数组的元素在内存中是一块连续的空间,而链表的元素在内存中可以是不连续的。
2.对于数组,我们可以通过下标直接访问元素,而对于链表,我们需要从头开始遍历整个链表才能找到对应元素。
3.对于数组,插入或删除一个元素可能需要移动其他元素,导致时间复杂度为O(n),而链表插入或删除一个元素只需要改变指针,时间复杂度为O(1)。
4.对于数组,查询某个元素的时间复杂度为O(1),而对于链表,由于需要遍历,时间复杂度为O(n)。
因此,对于需要频繁进行插入和删除操作的场景,使用链表会更加高效;对于需要频繁进行查询操作的场景,使用数组会更加高效。

11.HashMap的增删改查时间复杂度,查询时的平均复杂度

HashMap中增加、删除、修改、查询的时间复杂度都是O(1),而查询时的平均复杂度取决于哈希函数的质量和哈希表的装载因子。一般情况下,哈希表的装载因子越小,查询时的平均复杂度就越低。

12.共享屏幕写斐波那契,第一次写递归让求一万,用了缓存,然后让用另一种方式写,用了循环

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/算法编织者/article/detail/61809
推荐阅读
相关标签
  

闽ICP备14008679号