项目阶段面试题

1、MySQL 的隔离级别有哪些?默认是什么?

  • 读未提交
  • 读已提交
  • 可重复读(默认)
  • 串行化

2、MySQL 的隔离级别可以解决哪些问题?

  • 读未提交:啥也解决不了
  • 读已提交:解决脏读
  • 可重复读:解决不可重复读、脏读
  • -MVCC 机制:解决幻读
  • 串行化:都可以解决

3、HTTP 协议的请求/响应结构是什么样的?

请求/相应:

  • 请求/响应行
  • 请求/响应体
  • 请求/响应体

4、CSRF 是什么? 有什么解决方案?

CSRF:跨站请求伪造攻击

1、利用请求头获取浏览器源地址,从哪里发起的请求来识别是否可信任站点发的请求

2、利用服务端生成的 token,提交表单时对 token 进行校验

5、Spring Security 判断权限/角色的方式有哪些?

  • 利用 HttpStatus 进行规则匹配
  • 利用注解拦截

6、Linux 常用命令有哪些?

top:查看进程和系统负载

find:查找文件

grep:搜索文件内容

ps -ef:查看进程信息。可以配合管道命令 + grep 来搜索进程

cat:查看文件内容

tail:监听文件内容变动并实时输出

df/free:查看磁盘/内存使用情况

7、如何利用命令在 Linux 中查看日志?

tail -f -n200 日志文件地址 | grep xxx

8、利用什么命令确认一个程序是否在运行中?

ps -ef | grep 程序名

9、Spring 的事务传播机制有哪些?

REQUIRED:默认,需要事务,如果有事务就在当前事务运行,如果没有事务就创建一个新的事务

REQUIRED_NEW:如果没有事务,创建一个新的,如果有事务,将该事务挂起并创建一个新的。

SUPPORT:支持事务,如果有事务就在当前事务运行,如果没有事务就以非事务的方式运行

NEVER:不支持事务,如果有事务就抛出异常

10、说说 Spring Bean 的生命周期

1、Spring Bean 的生命周期是从 Spring 容器启动时就开始的

2、所有 Bean 对象的创建都是从 ctx.getBean() 方法开始的

3、最终真正创建 Bwan 对象的方式是 doCreateBean 方法

4、Bean 的生命周期分别为实例化/属性赋值/初始化/注册销毁监听器

5、实例化就是利用反射/FactoryBean.getObject 来创建 Bean 对象,在实例化的前后都有对应拓展点,可以实现拓展点接口来做一些特殊处理

6、属性赋值,在这里进行 DI 操作,将需要注入的属性 @Value/@Autowired 注入。同样也分别在注入前后都有对应拓展点,同时 Spring 解决循环依赖也是基于此处的拓展点解决的

7、初始化阶段就是去执行我们配置或者自定义的初始化方法,例如 init-method/实现了 InitialiaingBean/或者实现了XxxAware的类的初始化方法,在真正初始化前后都会有对应的拓展点

8、最后会将 Bean 对象注册到销毁接口,但容器关闭时进行销毁操作

11、为什么有了 Spring 还需要 Spring Boot?

1、传统 Spring 开发配置过多,使用不方便

2、依赖关联不方便

3、传统 web 项目 Tomcat 部署不方便,SpringBoot 提供了内嵌的 Tomcat

12、Spring Boot 的常用注解有哪些

  • @SpringBootApplication
  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @SpringBootTest
  • @Condition10nXxx

13、Spring Boot 的自动装配是如何实现的?

​ 首先基于 SpringBoot 启动类的注解,其中有一个 、2EnableAutoConfiguration 注解,启用了自动装配,里面导入了自动装配类的导入类,这个类是基于 Spring 的 ImportSelector 的一个用于导入额外 Bean 的类,这个类中间会通过获取 jar 包中 META_INF/spring.factories 的文件,在该文件中获取到所有支持自动装配的全类名,作为候选类加载进来,然后根据类中的 @ConditionalOnXxx 的注解来判断这些类是否满足条件,决定是否装配这些类对象

14、Vue 的船用指令有哪些?

  • v-bind
  • v-model
  • v-on
  • v-if
  • v-show
  • v-for

15、什么是 MVVM?

是一种设计模式,针对于传统 MVC 模式的改进,强调的是 M(模型) V(试图) VM(视图模型),通过 M -> VM -> V 的数据双向绑定

16、Spring Security 的核心原理是什么?它是怎么实现认证的?

核心原理:基于 Servlet 的 Filter 实现,实际是通过一组过滤器链(FilterChain)来实现的各个功能。

认证:通过 UsernamePasswordAuthenticationFilter 来进行用户认证的校验,默认会对 POST 请求类型其请求路径为 login 的请求进行认证,如果当前的认证对象是已认证的,就直接放行,如果认证失败就会抛出失败的异常

17、Activiti 提供的接口有哪些?分别是干什么用的?

RepositoryService:用于操作资源相关的接口,如流程定义文件/图片等相关操作

RuntimeService:用于操作运行时任务相关对象,如流程实例/活动等

TaskService:用于操作运动时的任务相关操作,包括任务批注等功能

HistoryService:用于操作所有对象的历史相关数据,如历史流程实例/历史人物/历史活动等

ManagementService:用于流程相关配置进行管理操作

18、Activit7 新增了哪两个接口?主要有什么作用?

ProcessRuntime:用于替换原先的 RuntimeService 接口,提供了更方便操作流程实例相关的操作的方法

TaskRuntime:用于替换原先的 TaskService 接口,提供了更方便操作运行时任务的相关方法

以上两个方法实际还是在调用原先的 RuntimeService/TaskService

19、Git 分支相关的命令有哪些?

  • git branch
  • git checkout
  • git merge

20、Git 分支管理流程是什么样的?

​ 稳定版代码主要维护在 master 分支,我们开发小组通常都在 dev 分支进行功能的开发,当一个版本的功能开发完成后,将其合并到 test 分支,由该分支发版本去进行测试,如果有后续开发功能,我们会继续在 dev 分支进行开发,当测试分支测试有问题时,我们在测试分支进行修复,修复后确认没有问题了,会重新合并到 dev 分支,并且将测试完成的代码合并到 master 进行线上版本的发布

​ 如果 master 发现了 bug,会直接基于 master 切换出一个新的 bugfix 分支,在该分支解决了 bug,当 bug 解决后,会进行测试,确认测试通过后,将其重新发布,并将修复后的代码合并到 dev 分支

​ 如果代码出现了冲突,首先看冲突的情况,如果能确定哪些代码需要保留,哪些不需要,就直接进行合并,如果有不确定的代码一般是找到对应同事,确认后再合并

21、如何保证接口的幂等性?

幂等性:是指用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。

  • 乐观锁/悲观锁:只在更新操作的时候锁表,性能比悲观锁高/锁住单行数据,前提是有事务,id 是主键或是唯一索引,不然锁住整张表。
  • token(令牌):用户访问页面时,浏览器主动发送获取token令牌请求,后端生成token存储到redis并返回给前端,前端下一次请求携带token,后端判断当前token是否存在,不存在则是第一次请求做后续数据库操作,如果存在就是重复请求,直接返回一个成功的结果,在 redis 中设置token的过期时间。
  • 去重表:f服务端收集到前端请求的数据,将该数据插入到mysql的防重表中,如果执行成功则执行其他逻辑,如果执行失败,因为唯一索引重复插入同样的数据就会冲突捕获唯一索引冲突异常,直接返回成功。

22、怎么解决跨域的问题?

跨域:由于浏览器同源策略的限制,要求当前页面和服务端必须同源,也就是协议、域名和端口号必须一致。

  • 代理服务器:通过在 vue-config 配置文件中配置 proxy 代理服务器.

  • Nginx 反向代理:nginx通过反向代理解决跨域也是利用了服务器请求服务器不受浏览器同源策略的限制实现的

  • Websocket:WebSocket本身不存在跨域问题,所以我们可以利用webSocket来进行非同源之间的通信,客户端和服务器之间存在持久连接,双方可以随时开始发送数据。

23、如何实现线程安全的单例模式?

  • 枚举单例
  • 饿汉式双重检查
public class Singleton {
    
    
   private static Singleton instance = null;

   private Singleton() {
    
     }

   public static Singleton getInstance() {
    
    
      if(instance == null) {
    
    
         synchronzied(Singleton.class) {
    
    
            if(instance == null) {
    
    
               instance = new Singleton();
            }
         }
      }

      return instance;
   }
}

猜你喜欢

转载自blog.csdn.net/weixin_49137820/article/details/128263178