Java14道高频面试题

面试题

1、JWT

①、JWT(全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。

②、JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户

③、JWT是由头部、负载和签名这三部分组成的,其中头部和负载都是明文,签名是经过加密处理的。头部是加密方式(HS256)

2、Session和Cookie区别

Session和Cookie都是客户端-服务端的一种存储机制,但是它们之间有一些重要的区别:

1、存储位置:Cookie数据存放在客户端,Session数据存储在服务端

2、数据共享:Cookie是不安全的,可以通过网络被共享,而Session更加安全,因为数据只在客户端和服务器之间共享。

3、数据大小限制:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,而session则存储与服务端,浏览器对其没有限制。

4、数据有效期:Cookie过期时间由开发者设置,而Session数据在用户关闭浏览器后自动过期

5、数据传输:Cookie在每次请求时都需要手动添加到HTTP头中,而Session ID会自动添加到HTTP头中,因此Session更加高效

总之,Cookie更加灵活,但不够安全,适用于不需要太高安全性的场景;Session更加安全,适用于对安全性要求较高的场景。

3、route与router区别

1、router 主要负责页面跳转

2、route 获取当前页面的参数等信息

4、为什么要用token,token的优势

Token是一种用于验证用户身份及权限的机制,它是由服务器颁发给客户端的,用于验证客户端的身份及权限。Token的优势有:

1、增强安全性:Token机制使用了时间戳和签名算法,使得Token更加安全,可以有效防止CSRF攻击

2、简化客户端代码:Token机制允许客户端存储服务器颁发的Token,从而减少了客户端与服务器之间的交互,简化了客户端代码

3、灵活性:Token机制可以根据具体需求进行灵活配置,可以用于不同类型的请求和场景

4、易于实现:Token机制的实现相对简单,可以使用现有的框架和库来实现。

5、token拦截器,前后端如何验证

Token拦截器是一种用于验证用户身份和权限的机制,它通过在HTTP请求头中添加一个Token字段,服务器在处理请求时会检查Token的有效性。

具体实现流程如下:

1、当用户成功登录时,在服务器端生成一个Token,并将其返回给客户端

2、客户端在每次发送请求时,将Token添加到HTTP请求头中。

3、服务拦截器收到请求后,从HTTP请求头中获取Token。

4、服务器对Token进行验证,包括检查Token是否过期、是否被篡改等。

5、如果Token验证通过,则服务器继续处理请求;如果Token验证失败,则返回错误响应。

通过Token拦截器,可以实现前后端的联合验证,增强系统的安全性。前后端分别负责生成、验证和存储Token,以确保Token的安全性和有效性。

6、如何使用自定义注解和AOP实现万能分页

一、先自定义一个注解,然后这个注解上面有三个注解分别为:@Target、@Retention、@Documented

1、@Target({ElementType.METHOD})

在方法上面放注解

2、@Retention(RetentionPolicy.RUNTIME)

表示该注解在程序运行时仍然被保留并可以被读取。

3、@Documented

用于指示注解应该被包含在代码文档中

二、定义切面类 在类里定义切入点

二、AOP,在需要分页的方法上面打上自定义注解,然后使用切入点注解,在有自定义注解的方法运行之前,也就是在环绕通知里面(@around)完成分页配置。

7、reduce函数的概念和使用场景

1、reduce概念:reduce函数是用于对数据进行累加或聚合操作的函数。它接收一个函数作为参数,用于指定聚合的方式,然后将输入的迭代器作为参数传入,通过不断调用指定的聚合函数来将输入的元素进行累加或聚合操作,最后返回一个单独的值

2、使用场景:把扁平化数据转化为树形数据,(统计总数、计算总和、求最大值或最小值)

8、利用线程传递数据

1、ThreadLocal是一个类,它提供了一种将对象保存为线程变量的方法,相当于一个特殊的Map,它通过提供get()和set()方法来实现线程局部变量的功能。

2、ThreadLocalMap的作用:①、为每一个线程创建一个变量,这个变量可以随时获取,并且可以随时设置。

②、可以跨类跨方法传递变量

3、ThreadLocalMap的优点:①、安全性、可以方便的在多线程中传递数据。

②、可以在service层、controller层里面少些代码,减少代码量。

9、MyBatis拦截器

  1. Executor 拦截器:对于 Executor 类中的四个基本操作(update、query、flushStatements、commit/rollback),执行前后都可以进行拦截。

  2. ParameterHandler 拦截器:对查询参数进行处理的拦截器,可以在执行 SQL 语句前对参数进行处理,比如对参数进行加密等。

  3. ResultHandler 拦截器:对查询结果集进行处理的拦截器,可以在获取结果集时对结果进行处理,比如将结果集转换为 Excel 文件等。

  4. StatementHandler 拦截器:对 SQL 语句进行处理的拦截器,可以在执行 SQL 语句前对 SQL 进行处理,比如对 SQL 进行分页等。

10、内存泄漏和内存溢出

1、内存泄漏:指程序运行后,没有释放所占用的内存空间(程序中有引用没有释放,不能被GC回收),一次内存泄漏可能不会有很大的影响,但长时间的内存泄漏,堆积到一定程度就会产生内存溢出。

2、内存溢出:内存溢出(Memory Overflow)是指程序请求的内存超出了 JVM 可以提供的最大内存限制,从而导致内存无法分配而产生的错误。内存溢出通常由于应用使用的内存不断增长,超过了 JVM 配置的堆内存大小而导致。内存溢出会导致应用崩溃或者变得非常缓慢。

11、什么 SPI 和 Spring SPI

1、SPI(Service Provider Interface)是一种设计模式,翻译过来就是“服务提供接口”,再说简单一点就是提供某一个服务的接口, 提供给服务开发者或者服务生产商来进行实现。

2、Java SPI 是JDK内置的一种动态加载扩展点的实现。

3、这个机制在一般的业务代码中很少用到,但是在底层框架中却被大量使用,包括JDBC、Dubbo、Spring框架、日志接口中都有用到,不同的是有的使用Java原生的实现,有的框架则自己实现了一套SPI机制.

4、Spring中的SPI相比于JDK原生的,它的功能更为强大,因为它可以替换的类型不仅仅局限于接口/抽象类,它可以是任何一个类,接口,注解

5、正因为Spring SPI是支持替换注解类型的SPI,这个特性在Spring Boot中的自动装配有体现(EnableAutoConfiguration注解)

6、Spring的SPI文件是有规矩的,它需要放在工程的META-INF下,且文件名必须为spring.factories ,而文件的内容本质就是一个properties

12、SpringBoot如何自动装配

1、SpringBoot启动的时候加载主配置类,@EnableAutoConfiguration注解开启了自动配置功能。

2、@EnableAutoConfiguration注解里面有一个注解叫@Import,它使用反射的方式导入了AutoConfigurationImportSelector类

3、在AutoConfigurationImportSelector类中有一个getCandidateConfigurations(获取候选配置)方法,它里面调用了SpringFactoriesLoader类

4、在SpringFactoriesLoader里面配置了工厂资源位置,这个位置是固定的(META-INF/spring.factories)

spring.factories是KV结构

5、然后通过spring.factories里面的KV值来自动装配

13、如何实现Starter

1、要有被封装的类(MyResponseAdvice)

原因:因为我们这整个starter都是为它服务的。

2、写一个properties包,里面放各种属性配置类,在这些类上面有两个注解,分别是@ConfigurationProperties(配置注解)和@Data,其中@ConfigurationProperties是别人配置starter的前缀

3、写一个autoConfigution包,里面放的是自动配置类,这个类上面也有两个注解,分别为@ConditionalOnProperty(根据属性开启自动配置的开关)和@Import(导入的类),其中@ConditionalOnProperty这个注解根据属性开启自动配置的开关,而@Import是需要被封装的类

4、最后在resources包下创建 META-INF包 和 spring.factories文件,配置自动注入的key和value

14、ThreadLocal的优点

  1. 线程隔离:每个线程都有自己的独立变量副本,不受其他线程的影响,确保了线程安全性。

  2. 简单易用:使用ThreadLocal可以方便地将数据与线程关联起来,无需手动管理线程间的数据传递。

  3. 开箱即用,开销小:在多线程环境下,可以避免因访问共享变量而需要进行的上锁操作,降低了使用复杂性。

  4. 适用于各种场景:如对象跨层传递、事务操作、数据库连接等,能够打破层次间的约束,提高代码的可维护性和扩展性。

你可能感兴趣的:(java,开发语言)