平安银行后端开发面试

1、springboot中的starter,如果要我自定义写一个,怎么去实现

  • 新建项目:新建一个Maven项目。

  • 添加依赖:在pom.xml中添加必要的Spring Boot依赖,通常你会需要spring-boot-starter作为基础。

  • 编写自定义代码:你可以添加自定义的Beans、配置类、属性文件等。

  • 提供默认配置:在resources目录下的META-INF中创建一个spring.factories文件,然后在这个文件中指定你的自定义auto-configuration类。例如:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yourpackage.YourAutoConfiguration
  • 打包:将项目打包成jar文件。

  • 使用starter:在其他项目中,你可以将此starter作为依赖来使用。

 2、springboot里的容器了解哪些

  • BeanFactory:是最简单的容器,为DI(依赖注入)提供了支持,它使用BeanDefinition对象来管理和创建bean。

  • ApplicationContext:是BeanFactory的超集,在Spring应用程序中,它被用作核心的容器接口。ApplicationContext提供了更多的企业级功能,如事件发布、国际化处理等。

    • AnnotationConfigApplicationContext:从一个或多个Java配置类中加载Spring应用上下文。
    • ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类路径资源。
    • FileSystemXmlApplicationContext:从文件系统的XML配置文件中加载上下文定义。
  • WebApplicationContext:一个特定于Web应用程序的ApplicationContext,为Web应用程序提供了一些额外的特性。

  • Lifecycle and Phases:Spring容器也管理bean的生命周期和各种生命周期回调,从创建到销毁。例如,@PostConstruct@PreDestroy注解等。

  • Environment Abstraction:Spring容器提供了一个Environment接口,它表示当前应用程序运行的环境。这为我们提供了一个方便的方法来访问环境特定的属性。、

3、volatile和sychronized关键字

volatile

  • volatile是Java中的一个类型修饰符,它用于声明一个变量为"易变"的。
  • 它确保对变量的读写都是直接与主内存进行的,而不是先在工作内存中处理然后再同步到主内存。
  • 使用volatile关键字声明的变量,其修改会立即对其他线程可见。
  • 它可以确保变量的可见性,但不能保证复合操作的原子性。

synchronized

  • synchronized是Java中的一个关键字,用于指定一个块是同步的。
  • 它可以确保同一时刻只有一个线程可以执行同步块中的代码,从而避免多线程之间的争用情况。
  • 使用synchronized可以确保方法或块中的代码的原子性
  • volatile相比,synchronized的开销更大,因为它涉及到锁的获取和释放。

4、读屏障和写屏障

在Java中,JMM(Java Memory Model)为了确保不同线程之间的可见性,有时需要添加特定的屏障或指令。

读屏障(Load Barrier)

  • 确保在屏障之前的读操作不会被重排序到屏障之后。

写屏障(Store Barrier)

  • 确保在屏障之前的写操作不会被重排序到屏障之后。

这些屏障确保了内存的一致性和可见性。

5、AQS以及可重入锁

AQS(AbstractQueuedSynchronizer)

  • AQS是Java并发包中的一个框架,用于构建锁、同步器和其他并发控制工具。
  • 它使用一个int成员变量来表示同步状态,并使用一个FIFO队列来管理等待线程。
  • AQS提供了模板方法来使用和修改同步状态,子类可以覆盖这些方法来实现自己的同步机制。

可重入锁(ReentrantLock)

  • 是Java并发包中的一个类,它实现了Lock接口,提供了与synchronized类似的同步能力,但是功能更加强大。
  • 它允许一个线程多次获取同一个锁,这就是所谓的"重入"功能。
  • 可重入锁除了可以实现基本的锁功能外,还提供了其他高级功能,如:可以被中断的锁获取、超时锁获取、公平锁等。
  • ReentrantLock内部使用AQS实现其同步控制。

6、git常用操作

设置和初始化

git config --global user.name "Your Name"  # 设置全局用户名
git config --global user.email "[email protected]"  # 设置全局用户邮箱
git init  # 初始化新的Git仓库

基本操作

git clone [URL]  # 从URL克隆一个仓库到本地
git status  # 查看工作目录的状态(修改的文件、未追踪的文件等)
git add [filename]  # 将指定文件添加到暂存区
git add .  # 将所有变更添加到暂存区
git commit -m "Commit message"  # 将暂存区的内容提交到仓库,并附加消息

 分支操作

git branch  # 列出本地的所有分支
git branch [branch-name]  # 创建一个新的分支
git checkout [branch-name]  # 切换到指定分支
git checkout -b [branch-name]  # 创建新分支并立即切换到这个分支
git merge [branch-name]  # 将指定分支合并到当前分支

远程操作

git remote -v  # 查看所有远程仓库
git remote add [alias] [URL]  # 添加新的远程仓库,并给它一个别名
git fetch [remote-name]  # 从远程仓库下载对象和refs
git pull [remote-name] [branch-name]  # 从远程获取数据并尝试合并到当前分支
git push [remote-name] [branch-name]  # 将分支推送到远程仓库

 查看历史

git log  # 查看提交历史
git log --oneline  # 以一行的形式查看简洁的提交历史

撤销操作

git checkout -- [filename]  # 恢复工作目录中指定文件的修改
git reset HEAD [filename]  # 从暂存区中撤销指定文件的变更
git reset [commit-hash]  # 将HEAD和当前分支指向指定的提交

 7、dubbo的架构

  • 提供者(Provider)

    • 服务提供方,它向注册中心注册其提供的服务。
  • 消费者(Consumer)

    • 服务消费方,它从注册中心订阅所需的服务,并从提供者那里调用服务。
  • 注册中心(Registry)

    • 服务注册与发现的中心。提供者在启动时向注册中心注册,并且消费者可以从注册中心查询到所需的服务。
  • 监控中心(Monitor)

    • 对Dubbo服务进行监控的中心,记录服务的调用次数、调用时长等统计信息。
  • 调用关系说明

    • 消费者和提供者在启动时都会与注册中心建立长连接,方便注册服务或者订阅服务。
    • 消费者从注册中心订阅服务时,注册中心会返回提供者的地址。消费者直接和提供者建立连接,并进行服务调用。
    • 监控中心定时从提供者或消费者收集统计信息。

8、数据库的如何分库分表

分库分表是在大数据量情况下,为了提高数据库的性能和扩展性而采取的策略。其主要目的是将大表或大库分成更小、更容易管理的块。

  • 垂直分表

    • 按照业务功能,将一个大表分成几个小表。例如,一个用户信息表可以分为用户基本信息表、用户登录信息表、用户偏好设置表等。
  • 水平分表

    • 将一个表按照某种规则(如范围、哈希、目录)分成多个表。例如,用户表可以按照用户ID的范围分成多个表。
  • 分库

    • 将数据从一个数据库分到多个数据库实例。这可以是垂直分库,也可以是水平分库。
  • 分片策略

    • 常见的分片策略有范围分片、哈希分片和目录分片。
  • 中间件

    • 为了方便管理和查询分库分表后的数据,通常会使用一些中间件,如ShardingSphere、Mycat等。

9、慢查询(有子查询或者各种连接情况)如何优化

针对有子查询或各种连接情况的慢查询,以下是一些建议的优化方法:

  • 避免使用子查询:尽量使用连接(JOIN)替代子查询。

  • 优化JOIN

    • 使用适当的索引。
    • 保证连接条件中的字段在两个表中的数据类型一致。
    • 尽量减少JOIN的表的数量。
  • 使用EXPLAIN:使用EXPLAIN命令查看查询的执行计划,从中找到慢的部分并进行优化。

  • **避免SELECT * **:只选择需要的字段。

  • 使用合适的索引:确保查询条件中的字段有索引,并且是最优的。

  • 优化数据结构:如使用更合适的数据类型,规范化数据结构等。

  • 避免使用函数和复杂的算法:这样可以减少计算的开销。

  • 调整查询缓存:对于经常查询并且不常变化的数据,可以使用查询缓存。

  • 分析并优化硬件和系统配置:如增加内存、优化磁盘I/O、调整数据库配置等。

你可能感兴趣的:(秋招面试,spring)