Java面经

127 阅读25分钟

在这里插入图片描述 ls mkdir touch cp mv cat tar -zxvf rm

echo在终端显示一串内容 echo "" > .txt 给文本输入字符串

ps -ef 查看所有进程 ps -ef | grep mysql

在这里插入图片描述

1.git init

2.git clone

3.git pull、git fetch

4.git add

5.git commit

6.git reset

7.git branch

8.git status

10.git push

11.git merge

15.git config

16.git rm

Websocket和osi七层模型的关系:

websocket是基于应用层,建立在tcp协议之上的协议,相比与http协议,它只需要建立一次tcp连接,就可以进行长时间的全双工的低延迟实时通信,适用于基于web的游戏,聊天应用。

内存溢出:

大量jar包,class文件被加载类空间不够导致内存溢出,

大量对象导致堆空间占满,内存溢出

使用jmap ,jstat查看新生代老年代情况,去代码查看对象是否被正确回收

java中的重载与重写的区别:

​ 1、重载发生在本类,重写发生在父类与子类之间;

​ 2、重载的方法名必须相同,重写的方法名相同且返回值类型必须相同;

​ 3、重载的参数列表不同,重写的参数列表必须相同。

mysql的b+树了解吗?主键是什么索引,怎么避免回表?

A2:了解,B+树是一种用于存储数据的多路搜索树,它的特点是在叶子结点中存储数据,而非叶子结点仅用于存储索引,可以更有效的进行检索。主键是一种索引,它能够唯一标识一条记录,通过使用主键可以快速检索到记录,从而避免回表查询。

线程的生命周期?用什么命令可以查看?

A3:线程的生命周期一般分为四个阶段,分别为新建阶段、就绪阶段、运行阶段和死亡阶段。可以使用jps命令查看正在运行的Java进程,使用jstack命令可以查看进程中线程的生命周期状态。

synchronize和reentrantlock有什么区别?

A4:synchronize是java中内置的锁,它能够自动完成加锁和解锁,但是它没有提供其他更多的特性,比如可中断锁、可轮询锁等。而ReentrantLock是java中的可重入锁,它提供了更多的特性,比如可以实现公平锁和非公平锁,以及可以中断锁和可轮询锁等特性。

跟我聊一聊aop,并且跟我说明怎么运用它

A6:面向切面编程(AOP)是面向对象编程的一种补充,它可以把一些公共功能(比如日志记录、权限检查等)抽取出来,作为一个独立的切面来处理,从而避免重复的代码出现在不同的业务逻辑中。使用AOP可以更加灵活的处理业务逻辑,提高代码的可重用性。

跟我聊聊super关键字

A7:super关键字是java中用于访问超类的关键字,它可以用于调用超类的构造函数、调用超类的属性或方法,以及引用超类的实例变量,从而使子类能够获取超类的内容,并且可以对超类的内容进行修改。

我知道mysql中的索引分为三类,B+树索引,Hash索引,全文索引,你可以告诉我这三个索引的区别在哪里,举例出形象的例子,最好有sql语句以便我能够理解。

当谈论MySQL的索引时,通常会涉及以下三种类型的索引:B+树索引、哈希索引和全文索引。它们各自的优势和适用场景不同。

  1. B+树索引

B+树索引是MySQL中最常用的索引类型之一,它采用B+树数据结构来存储索引。B+树索引适用于单列或多列的等值查询、范围查询、排序和分组等操作,而且支持最左前缀匹配原则,也就是说如果查询条件中只涉及到索引的左侧前缀,则可以有效利用索引。

下面是一个创建B+树索引的例子:

scssCopy code
CREATE INDEX idx_name ON users(name);

这将在users表的name列上创建一个名为idx_name的B+树索引。

  1. 哈希索引

哈希索引将索引列的值作为键值,通过哈希算法计算得到一个哈希值,然后将这个哈希值和相应的行指针存储在哈希表中。哈希索引适用于单列等值查询,但不支持范围查询、排序和分组等操作。

下面是一个创建哈希索引的例子:

scssCopy code
CREATE INDEX idx_age ON users(age) USING HASH;

这将在users表的age列上创建一个名为idx_age的哈希索引。

  1. 全文索引

全文索引可以用来进行文本搜索,它将文本内容分词后建立索引,支持模糊匹配和多关键字搜索等操作。全文索引适用于对文本内容进行搜索的场景。

下面是一个创建全文索引的例子:

scssCopy code
CREATE FULLTEXT INDEX idx_content ON articles(content);

这将在articles表的content列上创建一个名为idx_content的全文索引。

需要注意的是,不是所有的MySQL存储引擎都支持所有类型的索引,不同的存储引擎支持的索引类型也可能会有所不同。在选择索引类型时,需要根据具体的业务场景和数据特点进行选择。

给我讲讲最左前缀匹配,并举一个形象例子

最左前缀匹配是指在使用B+树索引进行查询时,如果查询条件只涉及到索引的左侧前缀,那么可以有效利用索引进行查询。

举个例子,假设有一个包含姓名、性别、年龄等信息的用户表,现在想查询所有年龄为30岁且性别为男的用户,如果使用B+树索引来优化查询,可以在agegender两个列上创建联合索引。那么如果查询条件为age=30 and gender='男'时,可以利用这个联合索引进行查询。此时,查询条件只涉及到了索引的左侧前缀,即age列。如果查询条件为gender='男'时,由于没有涉及到索引的左侧前缀,无法利用索引进行查询。

因此,在使用B+树索引进行查询时,尽可能使用索引的左侧前缀作为查询条件,可以提高查询效率。

能给我一个涉及最左前缀的sql语句例子吗

当涉及到B+树索引的最左前缀匹配时,一般建议查询条件中的列按照索引定义的顺序依次出现,这样可以保证最左前缀匹配的规则得到充分的利用。

以下是一个使用最左前缀匹配的SQL语句例子,假设有一个表students,其中包含学生姓名、性别、年龄等信息,现在想查询年龄为18岁且性别为女的学生:

sqlCopy code
SELECT * FROM students WHERE age = 18 AND gender = '女';

如果在agegender两列上创建了联合索引,则可以利用该索引进行查询。因为查询条件中的列按照索引定义的顺序依次出现,即先按照age列进行查询,再按照gender列进行查询,这符合了最左前缀匹配的规则。

注意,如果查询条件中只涉及到索引的左侧前缀,则可以利用该索引进行查询。但如果查询条件中出现了索引定义之外的列,或者是涉及到了索引定义之外的操作,如范围查询、排序、分组等,就无法利用该索引进行查询了。

说一下redis和mongdb在项目充当什么样的角色,他们有什么区别

Redis和MongoDB都是常用的NoSQL数据库,但它们在功能和使用场景方面存在一些区别。

Redis通常用作内存数据库和缓存,它可以快速地将数据存储在内存中,并通过提供高效的读写性能来加速应用程序。Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等,这些数据结构可以用于存储各种不同类型的数据。 Redis也提供了一些高级功能,如发布/订阅机制、事务支持和Lua脚本支持等,使其成为实现复杂数据存储和处理的好选择。

MongoDB则是一个文档型数据库,它被广泛用于存储半结构化和非结构化数据,如日志、用户配置文件和Web应用程序中的文档等。MongoDB的文档模型使用了类似于JSON的格式来存储数据,这使得它更加灵活,可以支持不同的数据类型和模式。MongoDB还提供了一些高级功能,如分片和复制集,使其适用于大规模应用程序和高可用性环境。

总的来说,Redis通常用于需要快速存储和检索数据的应用程序,如缓存、排行榜、消息队列等。MongoDB则适用于需要存储复杂文档和查询数据的应用程序,如社交网络、电子商务和博客平台等。

聚簇索引和非聚簇索引 的区别

聚簇索引(Clustered Index)和非聚簇索引(Non-Clustered Index)是关系型数据库中常用的两种索引类型。它们的区别在于:

  1. 聚簇索引:数据行的存储顺序与索引顺序相同,也就是说,索引结构与数据行的物理存储顺序是一致的。因此,一个表只能有一个聚簇索引。聚簇索引通常建立在主键列上,或者是唯一的非空列上。因为聚簇索引确定了数据行的物理存储顺序,所以在使用聚簇索引进行查询时,可以通过索引查找到数据行的位置,从而避免了全表扫描,提高了查询效率。
  2. 非聚簇索引:数据行的存储顺序与索引顺序不同,也就是说,索引结构与数据行的物理存储顺序是不一致的。在一个表中,可以有多个非聚簇索引。非聚簇索引通常建立在经常需要进行查询或排序的列上,但是在使用非聚簇索引进行查询时,需要先通过索引查找到数据行的位置,然后再通过物理存储地址访问数据行,因此比使用聚簇索引进行查询的效率稍低一些。

总的来说,聚簇索引的优点是查询速度快,但更新数据的速度较慢,因为需要调整数据行的物理存储位置。而非聚簇索引的优点是更新数据的速度快,但查询速度较慢,因为需要先通过索引查找到数据行的位置,然后再通过物理存储地址访问数据行。

什么时候用stringbuffer和stringbuilder

StringBuffer和StringBuilder都是Java中用于字符串处理的类。它们的主要区别在于StringBuffer是线程安全的,而StringBuilder则是非线程安全的。

如果您的程序需要在多线程环境下进行字符串处理,或者需要进行频繁的字符串操作,建议使用StringBuffer。由于它是线程安全的,多个线程可以同时对其进行操作,避免了并发问题。但是,由于线程安全机制的存在,StringBuffer的性能可能略逊于StringBuilder。

如果您的程序在单线程环境下进行字符串操作,或者需要进行大量字符串操作,建议使用StringBuilder。由于它不需要考虑线程安全问题,因此性能相对较高。

需要注意的是,虽然StringBuffer和StringBuilder都可以进行字符串操作,但它们的使用方式并不完全相同。StringBuffer和StringBuilder都提供了append()方法来追加字符串,insert()方法来插入字符串,delete()方法来删除字符串等操作。但是,由于线程安全机制的存在,StringBuffer的所有公共方法都使用了synchronized关键字,因此在使用StringBuffer时需要考虑同步问题。而StringBuilder则不需要考虑同步问题,因此可以更加自由地使用它的方法。

在项目场景中,什么时候用mybatis-plus,什么时候用mongodb

Mybatis-Plus和MongoDB是两种不同的数据库技术,适用于不同的场景。一般来说,如果您的项目数据量较小,且数据之间存在较强的关系性,建议使用Mybatis-Plus。如果您的项目数据量较大,数据之间的关系较为松散,或者需要进行大量的非结构化数据存储和分析,建议使用MongoDB。

Mybatis-Plus是一种基于Mybatis框架的增强工具,它提供了很多便捷的API和优化功能,可以帮助您更加高效地进行关系型数据库操作。如果您的项目需要进行复杂的SQL查询、事务控制、多表关联等操作,Mybatis-Plus是一个很好的选择。

MongoDB是一种基于文档存储的NoSQL数据库,它不需要固定的表结构,支持动态添加字段,适合存储非结构化数据。如果您的项目需要存储大量的非结构化数据,例如日志、图像、音频等文件,MongoDB是一个很好的选择。此外,MongoDB也提供了很好的数据分析功能,例如聚合操作、地理空间查询等,可以帮助您更好地进行数据挖掘和分析。

需要注意的是,Mybatis-Plus和MongoDB并不是相互排斥的技术,它们可以在不同的场景下共同使用。例如,如果您的项目需要同时存储结构化数据和非结构化数据,可以使用Mybatis-Plus与MongoDB相结合的方式来实现。

为何double,float会出现精度缺失

doublefloat是 Java 中常用的浮点数类型,它们在表示浮点数时会出现精度缺失的原因主要是因为它们的数据类型容量有限,无法表示所有的浮点数精确值。

在 Java 中,double类型使用 8 个字节来存储浮点数,而float类型使用 4 个字节来存储浮点数。因为double类型的容量比float类型大,所以double能够表示更多的浮点数精确值,但同时也带来了精度的损失。

在处理浮点数时,由于精度的限制,可能会出现精度缺失的问题。特别是在处理大量数据时,如果精度不够,可能会导致结果不准确。为了解决这个问题,Java 提供了double.toPrecision()float.toPrecision()方法,用于提高浮点数的精度。

此外,如果在使用浮点数时需要保证精度,可以考虑使用BigDecimal类型,它是一个强大的数字类型,能够精确表示任何浮点数。使用BigDecimal类型可以避免浮点数精度缺失的问题。

为什么要使用静态方法 static(关键字) 静态方法的好处就是不用生成类的实例就可以直接调用。

static方法修饰的成员不再属于某个对象,而是属于它所在的类。只需要通过其类名就可以访问,不需要再消耗资源反复创建对象。

在类第一次加载的时候,static就已经在内存中了,直到程序结束后,该内存才会释放。

如果不是static修饰的成员函数,在使用完之后就会立即被JVM回收。

函数知识点

2.1 CONCAT() 函数

CONCAT 可以将多个字符串拼接在一起。

2.2 LEFT(str, length) 函数

从左开始截取字符串,length 是截取的长度。

2.3 UPPER(str) 与 LOWER(str)

UPPER(str) 将字符串中所有字符转为大写

LOWER(str) 将字符串中所有字符转为小写

2.4 SUBSTRING(str, begin, end)

截取字符串,end 不写默认为空。

SUBSTRING(name, 2) 从第二个截取到末尾,注意并不是下标,就是第二个。

CONCAT 用来拼接字符串 ● LEFT 从左边截取字符 ● RIGHT 从右边截取字符 ● UPPER 变为大写 ● LOWER 变为小写 ● LENGTH 获取字符串长度

select user_id, CONCAT(UPPER(left(name, 1)), LOWER(SUBSTRING(name, 2))) as name

select user_id, CONCAT(UPPER(left(name, 1)), LOWER(RIGHT(name, length(name) - 1))) as name from Users order by user_id

MYSQL GROUP_CONCAT函数

MYSQL GROUP_CONCAT函数 - 简书 (jianshu.com)

请你从存储位置,存储的数据结构,存储的数据大小,存储数据的生命周期来区分cookie和session
  1. 存储位置:

Cookie 通常是在客户端 (浏览器) 上存储的,而 Session 通常是在服务器端存储的。

  1. 存储的数据结构:

Cookie 通常是一个简单的字符串,其中包含一个或多个键值对,这些键值对通常以 ASCII 字符表示。Session 通常是一份二进制数据,其中包含一个或多个 session 标识符 (也称为 session ID)。

  1. 存储的数据大小:

Cookie 可以存储任意大小的数据,但由于浏览器的限制,通常每个 Cookie 的最大值为 4KB。Session 数据大小通常受服务器限制,根据不同的应用程序,Session 数据大小可能会有所不同。

  1. 存储数据的生命周期:

Cookie 的生命周期通常与浏览器窗口相同,即在浏览器关闭之前,Cookie 会被清除。Session 的生命周期通常与应用程序的生命周期相同,即当应用程序结束时,Session 也会被清除。

http协议(超文本传输协议)

HTTP协议是一种无状态协议,即服务器不会保存任何关于客户端的信息。为了实现状态管理,HTTP引入了Cookie和Session机制。同时,HTTP还支持多种请求方法,包括GET、POST、PUT、DELETE等。

TCP UDP

TCP是一种面向连接的协议,它的特点是传输数据之前需要先建立连接,并且在数据传输过程中保证数据的可靠性和完整性。TCP协议适用于需要确保数据可靠传输和顺序到达的应用场景,如文件传输、电子邮件等。

UDP则是一种无连接的协议,它不需要在传输数据之前建立连接,并且在数据传输过程中不保证数据的可靠性和完整性。UDP协议适用于对数据传输效率要求较高,但对数据可靠性和顺序无要求的应用场景,如音视频传输、在线游戏等。

高并发主要要考虑哪些问题?

+ 为什么要设置一人一单? + 如果集群的Redis中一台突然挂了,此时有请求未处理怎么办? + Redis如何设置均衡负载的? + Redis除了缓存商家信息还缓存了什么? + 缓存是如何更新的? + 如何解决超卖问题 + 如何解决一人一单问题? + JVM的垃圾回收机制和JVM性能调优了解? + MySQL用了哪些优化方式? + MySQL是左优先还是右优先?

对于高并发问题,需要考虑的问题包括但不限于:并发量、并发请求的处理时间、资源的分配和利用、负载均衡、容错机制等。

一人一单的设置可以避免订单的重复提交和混乱,提高订单的处理效率和准确性。

当Redis集群中一台机器挂了,可以通过Redis Sentinel或Redis Cluster等机制来实现高可用性和容错机制。 Redis可以通过一致性哈希算法等方式来实现负载均衡。

除了缓存商家信息,Redis还可以缓存用户信息、商品信息等。

缓存可以通过定时更新、手动更新或者根据业务需求实时更新等方式来进行更新。

超卖问题可以通过加锁、事务等方式来解决。

一人一单问题可以通过设置订单状态、订单锁定等方式来解决。

JVM的垃圾回收机制包括分代回收、标记-清除、标记-整理等方式,JVM性能调优可以通过调整堆大小、GC算法、线程数等方式来实现。

MySQL的优化方式包括但不限于索引优化、SQL语句优化、分区表等方式。

MySQL是左优先的。

Java为什么要用jvm,用的目的是什么,虚拟机是做什么用?

Java使用JVM(Java虚拟机)来实现跨平台性,JVM负责将Java字节码翻译成特定平台的机器码,使得Java程序可以在不同操作系统上运行。JVM还提供了内存管理、垃圾回收等功能,使得Java程序更加可靠和安全。

Java里面的类加载器有几种?

Java中的类加载器有三种:Bootstrap ClassLoader(启动类加载器)

引导类加载器是jvm在运行时,内嵌在jvm中的一段特殊的用来加载java核心类库的C++代码。String.class 对象就是由引导类加载器加载的 Extension ClassLoader(扩展类加载器)

Application ClassLoader(应用程序类加载器)主要负责加载程序开发者自己编写的java类

在项目中什么时候去使用int,什么时候使用Integer

一般情况下,应该尽量使用Integer而不是int,因为Integer是对象,可以为空,而int是基本数据类型,不能为null。但在需要高性能和内存优化的情况下,可以使用int

线程安全和线程不安全怎么理解

线程安全指的是在多线程环境下,对共享资源的访问不会导致数据不一致或不可预期的结果。线程不安全则相反,可能导致数据错乱或异常。通常需要使用同步机制来保证线程安全。

在多线程情况下,当前线程对concurrentHashMap进行put行为,其他线程能进行干扰吗

在ConcurrentHashMap中,其他线程可以同时进行读取操作,但不会受到当前线程的put操作的干扰。采用Node + CAS + Synchronized来保 证并发安全进行实现,synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲 突,就不会产生并发 , 效率得到提升

什么时候应该去使用hashmap,什么时候去使用concurrentHashMap

一般情况下,当并发量较小或者可以通过同步机制来保证线程安全时,可以使用HashMap。而当并发量较大或者需要高并发性能时,应该使用ConcurrentHashMap来保证线程安全并提高性能。

在多线程情况下,jdk1.8后的concurrentHashMap采用Node + CAS + Synchronized来保证并发安全进行实现,CAS体现在什么方面,synchronized在hash冲突时会有什么行为?

CAS(Compare and Swap)是一种乐观锁机制,它通过比较当前值和期望值是否相等来决定是否进行更新。在ConcurrentHashMap中,CAS用于实现并发安全的插入和更新操作。当发生hash冲突时,synchronized会对涉及到的节点进行同步,保证并发安全。

用线程有什么好处

使用线程可以实现并发执行,提高程序的性能和响应速度。同时,线程还可以用于异步编程,提高系统的吞吐量和资源利用率。

用spring的目的是什么,为了解决什么问题

Spring框架的目的是简化企业级应用开发,解决了企业应用开发中的诸多问题,如依赖注入、面向切面编程、事务管理等,从而提高开发效率和代码质量。

AOP可以做日志抽取,那使用AOP和我自己写一个工具类去做日志抽取有什么区别

使用AOP可以将日志抽取的逻辑与业务逻辑分离,提高了代码的模块化和可维护性。而自己写一个工具类可能会导致代码耦合度增加,难以维护和扩展。

javaweb技术栈有哪些

JavaWeb技术栈包括Servlet、JSP、JavaBean、JDBC、Spring MVC、Hibernate等。

nacos本身有没有用到什么算法

Nacos使用了一致性哈希算法来实现服务的负载均衡和故障转移。

nacos使用一致性hash算法都做了什么具体的应用

线程在异步编程的具体使用怎么体现,举个例子

在异步编程中,线程可以通过Future来实现异步任务的执行和结果获取,比如实现异步调用外部服务,同时继续执行其他任务,待外部服务返回结果后再进行处理。

gateway做什么用,网关挂了怎么办

Gateway作为微服务架构中的网关,负责请求路由、安全认证、流量控制等功能。如果网关挂了,可以通过负载均衡和高可用部署来保证服务的可用性。

redis-cli的命令,怎么看一个key的过期时间

使用TTL key命令可以查看一个key的过期时间,返回值为剩余过期时间(单位:秒),-1表示永不过期,-2表示已过期。

rabbitmq的发送消息的模式

RabbitMQ的发送消息模式包括工作队列、发布/订阅模式、route模式,Topic模式

什么场景下使用mq,举个典型的例子

消息队列(MQ)适用于异步通信、削峰填谷、解耦系统等场景。例如,订单系统通过MQ异步处理库存扣减,避免因库存服务故障导致订单服务阻塞。

mysql的索引都有哪些

MySQL的索引包括主键索引、唯一索引、普通索引、全文索引等。

k8s相比于docker(docker-compose)具有什么样的优势,或者说我什么时候应该去使用docker什么时候去使用k8s

Docker用于打包、交付和运行应用,适用于单个应用的容器化部署。Kubernetes(K8s)是一个容器编排平台,适用于多个容器化应用的自动化部署、扩展和管理。当需要管理大规模容器化应用、实现自动化部署和弹性扩展时,应该使用Kubernetes。而当只需要进行单个应用的容器化部署时,可以使用Docker。

k8s相比于Docker Compose具有更强大的集群管理和自动化部署能力。当需要管理大规模容器化应用、实现自动化部署、弹性扩展和故障恢复时,应该使用Kubernetes。而当只需要在单个主机上管理少量容器化应用时,可以使用Docker Compose。

varchar定义10代表10个字符,这边字符代表什么意思,abc的字母吗,如果是中文怎么办

在MySQL中,varchar(10)中的10代表最大可存储的字符数,字符可以是字母、数字、符号或者中文。如果存储中文,需要根据具体的字符编码来确定存储的字节数。

Nacos使用一致性哈希算法来实现服务的负载均衡和故障转移,那ribbon呢,ribbon不也是对服务做负载均衡,两者有什么异同

当需要管理大规模容器化应用、实现自动化部署和弹性扩展时,应该使用Kubernetes。而当只需要进行单个应用的容器化部署时,可以使用Docker。

k8s相比于Docker Compose具有更强大的集群管理和自动化部署能力。当需要管理大规模容器化应用、实现自动化部署、弹性扩展和故障恢复时,应该使用Kubernetes。而当只需要在单个主机上管理少量容器化应用时,可以使用Docker Compose。

varchar定义10代表10个字符,这边字符代表什么意思,abc的字母吗,如果是中文怎么办

在MySQL中,varchar(10)中的10代表最大可存储的字符数,字符可以是字母、数字、符号或者中文。如果存储中文,需要根据具体的字符编码来确定存储的字节数。

Nacos使用一致性哈希算法来实现服务的负载均衡和故障转移,那ribbon呢,ribbon不也是对服务做负载均衡,两者有什么异同

Nacos和Ribbon都是用于服务治理的组件。Nacos主要用于服务注册与发现、动态路由、负载均衡等,而Ribbon是一个客户端负载均衡器,用于在客户端实现负载均衡。Nacos更侧重于服务注册与发现,而Ribbon更侧重于负载均衡。在Spring Cloud中,可以结合使用Nacos和Ribbon来实现完整的服务治理。