自我介绍+项目介绍
目录
1:分布式事务怎么实现的?
通过kafka保证最终一致性,而不是强一致性,强一致性要使用Seata
kafka作为消息中间件,通过确认机制,保证消息不丢失。
2:了解哪些设计模式及其应用?
Aop使用动态代理,
SpringBean单例模式,
策略模式业务场景 一对多 可以使用这种模式,
观察者模式 使用mq时 写入监听器 使用这种模式
3:说一下线程池的使用?
结合业务优化,将串行优化成并行
线程池配置七大参数,以及执行流程(不详细说了)
4:线程池取一个线程与我自己新起一个线程有什么区别?
手动起一个线程消耗资源,线程池有池化思想类似于字符串常量池,可以节省资源。
5:Spring依赖注入的方式?
构造器注入: 通过构造器传递依赖项,确保对象在创建时就完全初始化。Spring容器在创建bean时,会自动调用带有依赖项的构造器。
setter注入: 通过setter方法注入依赖项,允许在对象创建后修改依赖关系。Spring容器会调用带有@Autowired
注解的setter方法来注入依赖。
字段注入: 直接在字段上使用@Autowired
注解,Spring容器会自动注入依赖项。这种方式不推荐使用,因为它破坏了字段的封装性,并且不支持字段的重写。
注解注入: 使用@Autowired
、@Qualifier
、@Resource
等注解来指定注入的依赖项。@Autowired
通常用于构造器、setter方法或字段注入,而@Qualifier
用于解决同名bean的歧义问题。
Java配置类注入: 通过Java配置类(使用@Configuration
注解)和@Bean
注解来定义bean和它们的依赖关系。
XML配置注入: 在Spring的XML配置文件中定义bean和它们的依赖关系。这种方式允许你使用XML来管理bean的生命周期和依赖关系。
使用ApplicationContext
进行手动注入: 通过编程方式获取ApplicationContext
或BeanFactory
,然后手动获取bean的实例并进行依赖注入。
6:说一下项目中Aop的使用,以及增强方式
主要是用来日志管理
前置,环绕,后置,异常,最终
7:你们项目中表的最大体量级是多少?
不到千万吧,是日志表,创建一些索引优化,没有用到分库分表
8:数据库去重函数了解吗?
Distinct,Group by
区别:
- 用途:
DISTINCT
用于去除重复行,而GROUP BY
用于数据分组和聚合计算。 - 行为:
DISTINCT
只返回不同的值,不进行计算;GROUP BY
则用于对分组的数据进行聚合计算。 - 结果集:使用
DISTINCT
的结果集可能包含多列,但这些列的组合必须是唯一的;而GROUP BY
的结果集通常只包含分组列和聚合函数。 - 排序:
DISTINCT
不保证结果集的顺序,而GROUP BY
会按照分组列对结果集进行排序。
9:一个表创建索引的上限有了解过吗?
-
索引数量限制:
- 每个表可以创建的索引数量有一个上限。例如,在 MySQL 中,这个限制通常是 500 个索引。
-
索引大小限制:
- 单个索引的大小也有限制。这通常取决于数据库系统和存储引擎。例如,在 MySQL 的 InnoDB 存储引擎中,单个索引的页大小是 16KB,索引可以包含多达 2^15 个这样的页。
-
表大小限制:
- 表的大小也会影响索引的数量。因为索引会占用额外的存储空间,如果表本身非常大,可能需要更多的索引来提高查询性能。
-
性能考虑:
- 创建过多的索引可能会影响插入、更新和删除操作的性能,因为数据库需要同时更新索引。
-
维护成本:
- 索引需要维护,这会增加数据库的维护成本。因此,通常建议只为最常用的查询创建索引。
-
查询优化器限制:
- 数据库的查询优化器在执行查询时,可能无法使用太多的索引。因此,即使创建了更多的索引,查询性能也不一定会提高。
-
系统资源限制:
- 系统资源(如 CPU、内存、磁盘空间)也会影响索引的数量。如果系统资源有限,可能需要限制索引的数量。
-
特定数据库的限制:
- 不同的数据库系统可能有不同的限制。例如,Oracle 数据库允许每个表最多有 40 个索引,而 SQL Server 允许 999 个索引。
10:写sql获取当前时间的方式?
-
NOW(): 返回当前的日期和时间(包含时分秒)。
SELECT NOW();
-
CURDATE(): 返回当前的日期。
SELECT CURDATE();
-
CURTIME(): 返回当前的时间。
SELECT CURTIME();
-
SYSDATE(): 返回当前的日期和时间,与
NOW()
相同。SELECT SYSDATE();
-
UNIX_TIMESTAMP(): 返回当前的UNIX时间戳(自1970年1月1日以来的秒数)。
SELECT UNIX_TIMESTAMP();
-
FROM_UNIXTIME(unix_timestamp): 将UNIX时间戳转换为日期和时间。
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP());
-
GET_FORMAT(DATE, 'EUR'): 返回当前日期,格式取决于服务器的区域设置。
SELECT GET_FORMAT(DATE, 'EUR');
-
LOCALTIME(): 返回没有时区转换的时间。
SELECT LOCALTIME();
-
LOCALTIMESTAMP(): 返回没有时区转换的日期和时间。
SELECT LOCALTIMESTAMP();
11:sql优化了解吗?
体量比较少,用的比较少,通常用慢查询日志,explain,来查看查询情况,观察是否索引失效。
12:redis用到过哪些数据类型?
String 存取token信息 set zset 哈希 list
13:用到过redis作异步队列吗?
通过设置过期时间,你可以实现一个简单的延迟队列。将消息和过期时间存储在 Redis 中,当消息到期时,再将其移动到另一个队列供消费者处理。
14:redis中的key有上限吗?
有,当内存不足时,Redis 可以使用不同的策略来回收内存
15:说一下RabbitMQ消息模式?
-
点对点(Point-to-Point):
- 消息由一个生产者发送,一个消费者接收。
- 队列(Queue)是实现点对点消息模式的核心组件。
- 消息发送到队列,然后由消费者从队列中取出。
-
发布/订阅(Publish/Subscribe):
- 消息由一个生产者发送,多个消费者订阅并接收。
- 使用交换机(Exchange)和绑定(Binding)将队列连接到交换机。
- 生产者将消息发送到交换机,交换机根据路由键(Routing Key)将消息路由到一个或多个队列。
- 消费者从队列中获取消息。
-
路由(Routing):
- 通过路由键,将消息路由到不同的队列。
- 可以基于路由键的模式匹配来实现更灵活的消息路由。
-
主题(Topic):
- 类似于路由模式,但使用更复杂的匹配规则(如通配符)。
- 生产者发送带有特定模式的路由键,交换机根据这些模式将消息路由到队列。
16.Linux想查看日志文件从上往下查
tail 命令: tail
命令默认显示文件的最后10行内容,但也可以用来显示更多或更少的行数。
grep 命令: 如果你只想查找包含特定文本的行,可以使用 grep
结合 tail
。
tail -n 100 filename.log | grep 'search_text'
17.场景题统计用户连续登录的天数
-
用户登录记录:
- 每次用户登录时,记录登录的时间戳和用户标识。
-
数据库设计:
- 在数据库中设计一个表来存储用户的登录记录,通常包括用户ID、登录时间戳等字段。
-
连续性检查:
- 每次用户登录时,检查其上次登录的时间戳。
- 如果当前登录时间与上次登录时间是连续的(例如,不超过24小时),则连续登录天数加一。
- 如果不连续,则重置连续登录天数。
-
时间差计算:
- 可以通过比较当前登录时间和上次登录时间来计算时间差。
- 如果时间差小于某个阈值(例如,1天),则认为是连续的。
-
重置逻辑:
- 如果用户在一定时间内没有登录,可以设置一个逻辑来重置连续登录天数。
-
数据更新:
- 在用户登录时更新数据库中的登录记录和连续登录天数。
-
用户界面:
- 在用户界面上显示用户的连续登录天数。