基于个人的简历Java开发岗位的自问

成都Java开发岗位实习3k左右,针对个人的简历内容的自问

Java基础与面向对象

请谈谈你对Java中多线程的理解,并给出一个实际使用多线程的场景?

一个进程可以有多个线程,当我们一个服务需要同时去调用一个类的方法时候单个线程会造成阻塞影响进程一个请求需要去等待一个访问结束。多线程具有并发,线程通信同步(通过锁实现)以及资源共享。

解释一下Java中的反射机制,以及它在哪些情况下可能会被使用?

是Java语言提供的一种强大工具,它允许程序在运行时检查类、接口、字段和方法的信息,并可以动态地创建和调用对象。创建类的实例,在框架开发种Spring的依赖注入动态代理等。

你提到的设计模式中,请详细解释一下工厂模式和单例模式,并给出它们的应用场景?

工厂模式是在不具备指定类的情况下创建对象的方法,在创建对象的时候不会对客户端暴露创建逻辑而是通过一个共同接口来指向新创建的对象。根据抽象程度分为三种,简单工厂,工厂方法,抽象工厂,应用场景一个系统可能需要根据用户的不同输入或配置来创建不同类型的对象,此时就可以使用工厂模式来动态地创建和返回对象降低了代码的耦合度。

在Spring框架中就是一个很好的例子默认bean对象为单例模式,有助于减少内存,为管理bean针对一个类提供一个实例。例如在SpringBoot种实现一个config配置类加上@Configuration注解实现全局跨域

JDK8中引入的Lambda表达式和Stream API对Java编程带来了哪些改变?你如何在实际项目中使用它们?

代码简洁性,提供了函数式接口即只有一个抽象方法,同时支持并行处理,数据集合(如列表、集合等),过滤,排序等自动利用多核处理器运行提高了系统的性能。

利用函数式接口替换匿名内部类,同时提供sorted排序对列表进行处理替代了传统的for 循环

代码编写与框架理解

你在手写Spring框架的过程中,最大的收获是什么?Spring框架的哪些核心组件你进行了深入的了解?

首先我手写Spring框架后对自定义事务注解更加熟悉,对Spring底层的依赖注入原理,作用域,设计模式有了更深刻的认识,Spring中的作用域默认为单例模式,整个Spring只有一个实例,原型则是每一次请求都会获取一个实例。在SpringIOC种作为一个容器提供对Spring的组件管理,当我们通过注解或者xml实现的实现可以交给ioc去管理极大的降低了代码的耦合度,同时是aop提供面向切面编程可以在实现业务的时候通过在方法种实现通知,日志能不影响系统业务逻辑同时内置的支持cglib代理的实现通过异常支持事务回滚极大的提高了安全性。

SpringBoot的自动装配是如何实现的?你能给出一个简单的例子来说明吗?

SpringBoot提供了一套开箱即用的框架,约定大于配置,通过扫描目录的类路径进行自动配置,比起传统的SSM框架省去了更多的配置例如,不需要在web.xml文件中编写各种配置而是通过注解来实现,我们只需要引入SpringBoot的starter依赖即可。同时支持spring.factoryies文件配置需要自动配置的文件包。

谈谈你对SpringMVC执行流程的理解,以及它如何与Spring进行集成?

SpringMVC提供了一套web开发的工具,核心是DispatcherServlet,前端发送http请求到DispatcherServlet然后通过在handlerMappig种查找handler返回执行链给DispatcherServlet再去请求适配器执行(HandlerAdapter)再执行到Handler此时的后端接口controller层然后携带数据返回模型和视图到处理器适配器,再返回模型视图到DispatcherServlet再到视图解析器请求视图解析,随后返回视图给DispatcherServlet,视图渲染模型到请求域(视图,jsp)等最后响应客户端。

在spring种引入spring-webmvc依赖后编写Controller层,配置DispatcherServlet以及web容器如tomcat,在web.xml种配置视图解析器,URL映射地址同时通过注解/Javaconfig/xml方式来开启事务实现Spring对注解的扫描。

在SpringBoot中直接引入starter依赖即可,通过注解即可例如开启事务在组件用@Transactional,在启动类添加注解EnableTransactional扫描开启事务,实现web开发不需要web.xml文件自动装配已经实现了,我们可以在yml/properties文件中添加匹配器策略以及限制请求头的详细配置

前端技能

你使用过Vue2和Vue3,它们之间有哪些主要的区别?你在实际项目中是如何利用这些区别的?

Vue2与Vue3中同时都有四个生命周期阶段,Vue2是创建前(beforeCreate)创建后(created),挂载前(beforeMount),挂载后(mounted),更新前(beforeUpdate)更新完毕(updated),销毁前(beforeDestory),销毁后(destoryed)而在Vue3中有创建阶段通过setup函数,挂载前(onBeforeMount),挂载完毕(onMounted),更新前(onBeforeUpdated),更新完毕(onUnmounted),卸载前(onBeforeUnmounted),卸载完毕(onUnmounted),Vue2支持选项式api,Vue3支持组合式api能够对组件逻辑拆分成独立的函数提高了代码的灵活性,Vue2不支持碎片,Vue3支持碎片组件可以有多个根节点。在双向数据绑定原理之上,Vue2利用ES5的defineProperty()APi对数据进行劫持并结合发布订阅模式来实现的双向数据绑定,在Vue3中采用了Es6的ProxyAPI进行数据代理提升了监听数据变化效率,Vue3中添加了对ts,jsx的支持。Vue2中,数据通常被放入data对象中,而方法则在methods对象中定义。而在Vue3中,需要使用一个新的setup()方法,该方法在组件初始化时触发,用于定义响应式数据和其他逻辑

axios和ajax的区别是什么?你通常如何选择使用它们?

Axios是基于Promise的http库 ,axios请求支持promiseAPI 可以拦截请求和响应同时支持请求和响应数据转换,取消请求自动转换JSON,客户都安支持防止CSRF攻击,axios是原生的XHR对象,而axios是对原生xhr的封装,在Vue项目中通常直接用 var ajax=new xmlHttpRequest()手动创建对象,而axios需要在项目中下载对应依赖后进行全局配置,挂载,封装api才能使用。

对我而言,在前后端分离项目中全部使用axios做异步处理因为,前后端交互ajax请求过多会影响系统性能,ajax不支持配置拦截请求存在一定的安全隐患,我通常都是在练习demo的时候会用Jquery/layUI去调用ajax请求做登录,注册的验证测试。

前后端交互通信中,你如何确保数据的安全性和完整性?

利用安全的传输协议进行数据传输如JsonWebToken令牌,通信使用https,身份确认机制,每次请求都要进行验证是否合法,采取RestFul 架构。

数据库与缓存

MySQL中索引的作用是什么?你如何优化一个慢查询?

Mysql中的索引可以加快查询速度,更快的定位到表中的特定数据,从而加快查询速度,没有索引需要进行全表扫描效率十分的低,通过创建唯一索引可以确保索引的唯一性,防止插入数据,从而加快检索速度。关于优化慢查询,可以对索引进行优化,避免创建过多的索引,过多的索引会占用额外的磁盘空间,在crud都需要维护索引,要确保查询字段都被索引覆盖这样可以减少回表操作,优化SQL语句避免使用复杂的子查询,join,*,开头的like查询减少查询的复杂度。采取连接池技术(得鲁伊连接池以及Hikari连接池),连接池可以服用数据库链接,减少链接创建和销毁的开销,从而提高查询性能。优化数据库的接口,避免数据亢余和不必要的复杂性,减少存储空间的占用。

请谈谈Redis的缓存机制,以及它是如何与数据库进行协作的?

Redis是将数据存储到内存结构中,使数据的读取速度远远快于传统的磁盘存储。

Redis支持多种数据结构,如字符串,哈希,列表,集合,有序集合能够让Redis更好处理各种类型的数据。

MySQL与Redis同步的时候通常会在业务逻辑层清楚Redis的对应的缓存数据来实现,用户请求数据的时候系统会先查询Redis缓存,若缓存不存在数据则要去数据库查询并将查询结果放在Redis缓存,通过Redis缓存系统亢余减少对数据库的访问次数,而当大量用户请求到相同数据时,Redis可以迅速从内存中返回数据,而无需每次都从数据库中查询

在实际项目中,你如何设计并使用Redis来提高系统的性能?

Emm我就用Redis生成了订单号,在后端的接口中用stringRedisTemplate实现通过HashMap接收结构再设置一个key过期时间用expire方法来保证每天的流水从一天开启

网络安全与微服务

你如何理解SQL注入和XSS,CSRF攻击?在实际项目中,你如何防止这些攻击?

SQL注入是一种针对数据库的攻击手段,攻击者再应用程序输入字段插入一些恶意SQL代码使原本正常的SQL查询语句结构被改变从而执行攻击者指定的恶意操纵。例如,攻击者可能通过SQL注入造成数据泄露和篡改,防范SQL注入的主要方法是采取参数化查询和预编译技术避免将用户拼接到SQL语句中同时对用户填写的数据进行过滤和验证。在mybatis中用${}占位符可防止。

Xss攻击是通过再网页中注入恶意脚本当用户浏览网页的时候恶意脚本会在用户浏览器中执行从而获取用户的信息或者执行其他的恶意操作,xss攻击分为反射型,存储型,DOM型。防范XSS可以对用户输入进行严格的过滤和转义防止恶意脚本插入。

CSRF攻击主要方法是利用用户在已登录的web程序上执行非本意的操作攻击方式,攻击者从第三方构造一个恶意请求,诱导用户点击出发请求,让客户的浏览器向目标web应用程序发送一个伪造的请求,执行恶意操作。防范CSRF的话我会在项目中使用令牌后端的jwt密钥,axios每次获取请求都需要验证这个令牌的有效性,只有包含令牌的请求才能被服务器接收并执行。并且对敏感操作进行二次确认。

SpringCloudAlibaba中,你如何理解并应用服务注册与发现机制?

1.当服务启动的时候,它会将自己的信息(服务名,IP地址,端口号等)注册到注册中心,注册中心负责管理存储这些服务中心,以便其他服务可以通过注册中心找到需要的服务。

2.当某个微服务需要调用其他服务的时候,它会向注册中心发送请求,查询所需服务的地址信息。注册中心会根据请求返回相应的服务地址列表,然后调用就可以根据这些地址信息发起远程调用。

3.在微服务中,可以使用 @LoadBalanced 注解的 RestTemplate 或者 FeignClient 来调用其他服务。Spring Cloud Alibaba 会自动根据服务名从注册中心获取服务地址,并实现负载均衡。

请谈谈Ribbon负载均衡的工作原理,以及它在微服务架构中的作用。

1.配置与发现:Ribbon首先通过配置文件或者自定义规则获取到所有可用的服务实例列表。这些服务实例可能分布在不同的服务器或节点上,共同构成了一个微服务集群。

2.请求发起与选择:当客户端发起请求时,Ribbon会根据负载均衡算法从服务实例列表中选择一个目标服务实例。负载均衡算法的选择可以是轮询、随机、加权轮询、加权随机等多种方式,这些算法可以根据实际需求进行配置,以平衡服务实例的负载。

3.请求执行与响应:Ribbon将请求发送给所选的服务实例,并在请求完成后获取响应。如果请求失败或者超时,Ribbon会自动尝试选择另一个可用的服务实例进行重试,以确保服务的可用性和稳定性

消息队列

RabbitMQ在哪些场景下会被使用?你能否给出一个具体的例子?

  1. 异步处理,当系统在执行一些耗时的操作的时候,发送文件,生成报表,可以通过RabbitMQ将这些操作放在队列中异步执行,避免阻塞主线程,提高系统响应速度.
  2. 流量削峰:在抢购,秒杀的场景中,为了防止后端应用被压垮可以在前后端分离系统间使用RabbitMQ消息队列传递请求。前端把请求发送到队列中,后端从队列中取出请求进行处理,从而实现流量控制,避免系统崩溃。
  3. 任务调度通过定时任务批量任务的调度,将任务放入列表中设置对应的延迟或触发条件,RabbitMQ可以确保任务在预定时间或条件下被执行。
  4. 分布式通信,在用户注册,支付成功,物流更新的时侯,RabbitMQ可以作为消息总线,实现1模块之间的解耦和异步通信。
  5. 日志处理,可以用于日志收集,分析,处理,通过将日志消息发送到队列实现异步处理。

你提到的延时队列在RabbitMQ中是如何实现的?它解决了什么问题?

使用TTL设置队列或消息的生存时间,如果消息或队列在一定时间没有被消费,那么它们就会过期。队列的话RabbitMQ会删除它;对于消息有两种处理方式一种是丢弃,一种是成为死信

DLX(Dead-Letter-Exchange):当消息在一个队列中变成死信(例如,消息被拒绝并且requeue=false,或者消息TTL过期)后,RabbitMQ会自动地将这个死信发送到DLX指定的交换机,而不是将消息丢弃。这个DLX交换机可以继续路由这个消息到另一个队列,甚至再次到DLX。

结合TTL和DLX,我们可以实现延时队列。将消息的TTL设置为需要的延迟时间,当消息过期后,它会被发送到DLX指定的交换机和队列,从而实现了消息的延迟处理。

订单支付后,需要在30分钟后检查订单状态,如果未支付则取消订单。

用户发送验证码后,需要在一段时间内(例如5分钟)限制其再次发送验证码。

定时任务,如每天定时发送日报、周报等。

在消息队列的使用中,你如何确保消息的可靠性和一致性?

消息的持久化

队列和消息的持久化:确保RabbitMQ的队列和消息都被设置为持久化,这样在RabbitMQ重启后,队列和消息不会丢失。

交换机持久化:同样,交换机也需要设置为持久化,以确保其配置在RabbitMQ重启后得以保留。

消息的确认机制

生产者确认:生产者发送消息后,需要等待RabbitMQ的确认,以确保消息已经被成功接收并存储。

消费者确认:消费者处理完消息后,需要向RabbitMQ发送确认信号,以确保消息已经被成功处理,从而避免消息重复消费。

消息的重试机制

设置重试次数:当消费者处理消息失败时,可以设置重试次数,让RabbitMQ在一段时间后重新将消息发送给消费者进行重试。

死信队列:对于多次重试仍然失败的消息,可以将其发送到死信队列,由专门的系统或人员进行处理。

分布式事务

两阶段提交(2PC):确保消息的生产和消费都在一个分布式事务的上下文中进行,以确保数据的一致性。但这种方法可能会引入性能瓶颈。

本地消息表:生产者发送消息前,先将消息保存到本地数据库,并标记为待发送状态。然后发送消息到消息队列,当消息队列返回发送成功的确认后,再更新本地数据库的消息状态为已发送。这样即使消息队列出现问题,也可以从本地数据库恢复。

幂等性设计

消费者幂等性:确保即使消息被重复消费,也不会对业务逻辑产生影响。这通常通过设计业务逻辑来实现,比如使用唯一ID或版本号来确保操作只被执行一次。

监控和告警

监控RabbitMQ的状态:包括队列长度、消息堆积情况、消费者数量等,以便及时发现和处理潜在问题。

设置告警阈值:当RabbitMQ的某些指标超过预设的阈值时,触发告警通知,以便及时介入处理。

备份和恢复

定期备份RabbitMQ的数据:以防万一出现硬件故障或其他原因导致数据丢失。

准备恢复策略:在出现故障时,能够快速恢复RabbitMQ的服务,并尽量减少数据的丢失。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值