java后端面试不知道多少家重庆的公司得来的题目总结

面试题目总结

  • 前言
    • JWT使用
    • token是如何生成
    • 微服务链路检测
    • 泛型的实现
    • cglib的实现
    • 有哪些开发规范
    • 你对雪崩效应的看法
    • 看过哪些源代码
    • 熔断器的使用
    • 高并发场景
    • mybatis一级缓存,二级缓存
    • docker (k8s)
    • docker-compose
    • JVM调优
    • springcloud用过什么组件
    • CAP理论(C——数据一致性,A——服务可用性,P——服务对网络分区故障的容错性),
    • java反射原理
    • zookeeper 调用流程处理方法,调用方式
    • 微服务调用元素
    • Java浅拷贝和深拷贝的理解和实现方式
    • java悲观锁和乐观锁区别
    • 后端实现跨域
    • Spring Boot、Spring MVC、Spring之间的区别?(Spring Boot本质是什么?)
    • Spring Boot Starter 是什么?
    • 如何自定义Spring Boot Starter?(如何扩展Spring Boot)
    • Spring Boot 的自动装配原理是什么?(源码分析哦)
    • Spring Boot 的启动流程是什么?
    • 有没有看过 Spring Boot 源码?你觉得最神奇的地方是什么?
    • 对服务注册中心的理解
    • 对网关的理解
    • jvm 原理
    • 你是怎么设计微服务
    • redis用过锁吗
    • redis内存优化
    • redis淘汰策略
    • Redis最为常用的数据类型主要有以下
    • redis 的应用场景
    • spring bean 不是线程安全的
    • 幂等性问题
    • 微服务的架构设计
    • mybatis原理
    • mybatis $ # 的区别
    • TCP协议详解
    • java sync 锁的是什么
    • hashmap的原理
    • springboot的初始化原理
    • jvm的分区(五大分区)
    • GC垃圾回收机制
    • 怎么执行GC垃圾回收
    • springboot是怎么实现springmvc的东西的
    • mysql怎么运用分库分表
    • 用过哪些设计模式
    • 对Euraka服务注册中心的理解
    • 运用Euraka遇到的问题
    • zuul有哪些过滤器
    • 分页插件的好处是什么
    • 封装类型和基本类型的区别
    • 怎么解决并发的
    • shrio的使用
    • springmvc的源码
    • in id方法有用到索引吗
    • list的子类
    • 并发包
    • 对dubbo的理解
    • 注册中心挂了会产生什么影响?
    • 为什么使用Dubbo?
    • 什么叫事务?简称ACID
    • 线程中变量的可见性
    • 引用数据类型包括:
    • java排序算法
    • 10G的文件导入带数据库中怎么实现(怎么快速把10G的文件解析出来)
    • 微信朋友圈的点赞功能怎么实现,好友可以看到,共同好友可以看到
    • js == === 的区别
    • springboot 的 starter的工作原理 自动装配
    • Servlet的生命周期
    • 如何取得每个部门薪资前三名的人员名称?
    • 查询两张表中没有交集的数据
    • swagger 注解参数
    • synchronized 的方式
    • 接口和抽象的区别
    • 怎么把抽象类变为接口
    • 索引联合
    • mysql的事务隔离级别
    • 索引的数据结构
    • redis是怎么实现单线程的
    • spring bean 为什么没有状态
    • Map map = new HashMap()用到了什么设计模式
    • 工厂模式有几种写法
    • redis什么时候会变卡
    • 单例模式有几种写法(五种)
    • 红黑树是怎么保证自平衡的
    • 数据结构有哪些
    • js的选择器
    • IOC的实现原理
    • DI(依赖注入)
    • AOP原理
    • Autowired 和Resources的区别
    • sprngboot文件上传用什么参数
    • 依赖注入有几种方式
    • 负载均衡用了哪些算法
    • get方法参数为中文会变成什么
    • mysql怎么存储表情符号
    • 进程和线程
    • 线程的生命周期
    • mysql的优化方向
    • 过滤器Filter和拦截器Interceptor的区别
    • String 为什么不能被继承
    • 怎么实现自动登录的
    • Springcloud和dubbo的区别
    • sync和lock的区别
    • B+tree 的的特点
    • redis持久化机制
    • JAVA线程池有哪些配置参数,各自的作用是什么?
    • mysql锁有哪些
    • 锁的级别
    • mysql索引有哪些?
    • mysql性能优化
    • explain 关键字sql执行情况
    • 基本数据类型有哪些
    • Mybatis-Plus 表里面有两个主键(复合组件)应该怎么插入
    • 分布式事务
    • 同一个类下面:两个方法A调用B,B有事务,整个方法有没有事务?
    • logback和log4j的区别
    • int主键和string主键效率哪个高
    • 服务治理是什么
    • Mq如何防止消息丢失解决方案
    • 订单延迟30分钟未支付,自动关闭
    • redis使用在分布式锁的场景
    • mysql 视图和表的区别
    • 表和临时表的区别
    • 一个文件夹里面有多个文件夹中有多个文件,如何读取里面的txt文件的名称
    • SpringBoot 在项目启动之后执行自定义方法的两种方式
    • 对微服务的理解
    • java 异常的原理
    • spring 原理
    • sleep和wait有什么区别
    • Java 实现动态代理主要涉及哪几个类
    • 数据库大数据量分页查询方式
    • nacos和eureka的区别

前言

一名Java后端在重庆面试亲身经历,每一场面试脑海中印象比较深刻的问题记录下来,并且总结,找出答案,分享出来。
现在面试问的问题都相对来说比较深入

话不多说上题目:

JWT使用

客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。
此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。
Authorization: Bearer
当跨域时,也可以将JWT被放置于POST请求的数据主体中。

相对传统token jwt token不需要保存在服务器端
2. JWT实现过程
第一步,用户提交用户名和密码给服务端,如果登录成功使用jwt创建一个token,并给用户返回
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
注意:JWT生成的token是由三段字符串组成的,并且用.连接起来

第一段字符串,HEADER,内部包含算法和token类型,json转化为字符串,然后做base64url的转码
{
“alg”: “HS256”,
“typ”: “JWT”
}
第二段字符串,payload,自定义值.

json转化为字符串,然后做base64url的转码

由于只是做了一层编码,所以这些信息都是透明的。不建议在里面传密码之类的敏感信息。

{
“sub”: “1234567890”,
“name”: “John Doe”,
“iat”: 1516239022
}
第三段字符串

前两部分的密文拼接起来
对前2部分的密文进行HS256加密 + 加盐
对HS256加密后的密文再做base64url加密
以后用户再来访问,需要携带token,后端需要对token进行校验

获取token
第一步:对token进行切割
第二步:对第二段解码,获取payload,检测token是否超时
第三步:把前两段拼接再次执行HS256加密,把加密后的密文和第三段比较。如果相等,认证通过

参考博文:https://www.jianshu.com/p/cb886f995e86

token是如何生成

微服务链路检测

链路追踪
SkyWalking or Zipkin
ZipKin:服务调用的请求和响应中加入ID,标明上下游请求的关系。利用这些信息,可以可视化地分析服务调用链路和服务间的依赖关系
Spring Cloud Sleuth是对Zipkin的一个封装,对于Span、Trace等信息的生成、接入HTTP Request,以及向Zipkin Server发送采集信息等全部自动完成。

参考博文:
https://www.cnblogs.com/duanxz/p/7552857.html
https://www.cnblogs.com/duanxz/p/7552857.html

泛型的实现

泛型的实现是靠类型擦除技术, 类型擦除是在编译期完成的, 也就是在编译期, 编译器会将泛型的类型参数都擦除成它的限定类型,如果没有则擦除为object类型之后在获取的时候再强制类型转换为对应的类型。 在运行期间并没有泛型的任何信息,因此也没有优化。

cglib的实现

动态代理

有哪些开发规范

 REST full

你对雪崩效应的看法

看过哪些源代码

熔断器的使用

在启动类中,需要添加 @EnableCircuitBreaker 注解
定义 Hystrix 处理类

OrderClientServiceFallbackFactory implements FallbackFactory<OrderClientService>

重写 create方法
里面再重写熔断的默认返回
配合feign在接口上面加上工厂类

@FeignClient(value = "MICROSERVICE-ORDER", fallbackFactory = OrderClientServiceFallbackFactory.class)

开启熔断

feign:
  hystrix:
	enabled: true

参考博文: https://blog.csdn.net/eson_15/article/details/86628622

高并发场景

服务器方面
   nginx 使用负载均衡
   使用服务器集群
   
业务实现方面
   使用队列Kafka、RabitMQ等
   处理秒杀 抢购等高并发场景保证数据安全
   使用缓存Redis、Memcache等
   尽量使用缓存,包括用户缓存,信息缓存等,可以大量减少与数据库的交互,提高性能。
   使用多线程
   部分功能使用多线程后台执行 不阻塞主线程

数据库方面
	 优化数据库查询语句
	 优化数据库结构,多做索引,提高查询效率
	 统计相关功能最好定时统计,避免实时查询

代码方面
	代码构造的时候尽量避免不必要的资源浪费,提高性能
	如:不要频繁使用new对象 使用单例模式等
		   string的连接操作,使用stringbuffer(速度慢,线程安全)或者stringbuilder(速度快,线程不安全)
		   utility类型的类通过静态方法来访问

mybatis一级缓存,二级缓存

  1. 一级缓存:mybatis每次在查询后,会将语句和参数相同的查询SQL的结果集存放进缓存,待下一次有相同的语句和参数时,mybatis直接将缓存内的结果集返回,而不再查询数据库。
  2. 二级缓存:需要手动开启。一级缓存在同一个SqlSession内,以SqlSession为缓存单位;二级缓存在不同的SqlSession间,以mapper为单位,不同的SqlSession间可以共享相同的mapper下接口查询的数据

docker (k8s)

docker-compose

参考博文:https://www.jianshu.com/p/7893af4976d9

JVM调优

    XX:MetaspaceSize=128m (元空间默认大小)
	XX:MaxMetaspaceSize=128m (元空间最大大小)
	Xms1024m (堆最大大小)
	Xmx1024m (堆默认大小)
	Xmn256m (新生代大小)
	Xss256k (棧最大深度大小)
	XX:SurvivorRatio=8 (新生代分区比例 8:2)
	XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)
	XX:+PrintGCDetails (打印详细的GC日志)

参考博文:https://blog.csdn.net/sun1021873926/article/details/78002118

springcloud用过什么组件

  1. spring cloud eureka : 注册中心,可以看到各个服务运行状态,并且各个微服务调用都通过注册中心来找到内网ip进行调用
  2. spring cloud gateway:
    对外的网关,分为zuul版本和F版本,两者最大区别是底层容器不同,zuul版本是servlet,F版本的是webFlux框架,并且F版本可设置统一过滤器,单个微服务过滤器,限流过滤器,相同的是都有负载均衡,熔断机制,重试规则
  3. spring cloud config: 配置中心,可以分为本地扫描配置和从git仓库拉取缓存,在spring cloud
    bus的配合下,可实现实时动态刷新配置文件
  4. spring cloud bus: 消息总线z,实现各个微服务之间的通信,整合java消息的发送和接收
  5. spring cloud Ribbon: 负载均衡
  6. spring cloud Feign: PRC 远程服务调用
  7. spring cloud Hystrix: 熔断机制
  8. spring cloud zipkin: 链路追踪,分为http追踪和rabbitmq追踪,提供前端页面显示各个接口之间的复杂的互相调用
  9. spring boot admin:
    显示各个服务运行的详细状态,线程池,内存环境,系统环境属性,spring各种bean运行状态,可以把阿里数据库连接池druid的监控结合到了监控页面,可以监控到各个sql执行时间等等
  10. spring cloud oauth2: 鉴权服务, 四种模式: 用户名密码模式, 客户端模式, 授权码模式,简化模式过于复杂.
    说明一下,目前微服务一般是使用Spring Cloud Alibaba
    阿里开源组件
  11. Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
  12. Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
  13. RocketMQ:开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
  14. Dubbo:这个就不用多说了,在国内应用非常广泛的一款高性能 Java RPC 框架。
  15. Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
  16. Arthas:开源的Java动态追踪工具,基于字节码增强技术,功能非常强大。

CAP理论(C——数据一致性,A——服务可用性,P——服务对网络分区故障的容错性),

Euraka 和 dubbo ,zookeeper

  1. Euraka: 是分布式系统中的AP
  2. dubbo的注册中心一般选用zookeeper: zookeeper保证的是cp
  3. 在P在网络分区发生故障的时候,zookeeper 要进行选举,euraka: 可以快速切换到另外一个节点

java反射原理

jvm在运行过程中载入class文件,得到class对象后反向获取对象的各种信息

zookeeper 调用流程处理方法,调用方式

微服务调用元素

Java浅拷贝和深拷贝的理解和实现方式

浅拷贝(浅复制、浅克隆):
	被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。
	换言之,浅拷贝仅仅复制所拷贝的对象,而不复制它所引用的对象。

深拷贝(深复制、深克隆):
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。
换言之,深拷贝把要复制的对象所引用的对象都复制了一遍

java悲观锁和乐观锁区别

定义:
	悲观锁(Pessimistic Lock): 
	每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待。

乐观锁(Optimistic Lock): 
每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。

适用场景:
悲观锁:比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。
乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。

总结:两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

后端实现跨域

  1. spring就用filter里面往header里面放跨域参数
	response.setHeader("Access-Control-Allow-Origin", "*");  
	response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
	response.setHeader("Access-Control-Max-Age", "3600");  
	response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
  1. Springboot 很简单 @CrossOrigin
  2. 或者用nginx实现做代理

Spring Boot、Spring MVC、Spring之间的区别?(Spring Boot本质是什么?)

Spring Boot Starter 是什么?

如何自定义Spring Boot Starter?(如何扩展Spring Boot)

Spring Boot 的自动装配原理是什么?(源码分析哦)

在全局配置的属性如:server.port等,  
通过@ConfigurationProperties注解,  
绑定到对应的XxxxProperties配置实体类上封装为一个bean,  
然后再通过@EnableConfigurationProperties注解导入到Spring容器中。
Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到  
META-INF/spring.factories配置文件中的所有自动配置类,  
并对其进行加载,而这些自动配置类	都是以AutoConfiguration结尾来命名的,  
它实际上就是一个JavaConfig形式的Spring容器配置类,  
它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:  
server.port,

参考博文:https://blog.csdn.net/Dongguabai/article/details/80865599

Spring Boot 的启动流程是什么?

有没有看过 Spring Boot 源码?你觉得最神奇的地方是什么?

对服务注册中心的理解

我的理解很简单就是服务注册进来就把他记录下来,客户端需要用的时候就直接来查询

对网关的理解

为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等

注意:Spring Cloud Gateway会和spring-webmvc的依赖冲突,需要排除spring-webmvc

路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。

断言(predicates) Java8中的断言函数,SpringCloud
Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http
request中的任何信息,比如请求头和参数等。

过滤器(Filter) SpringCloud Gateway中的filter分为Gateway FilIer和Global
Filter。Filter可以对请求和响应进行处理。

jvm 原理

  1. JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序。
  2. java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。

你是怎么设计微服务

	1·单一职责(Single Responsibility),一个服务应当承担尽可能单一的职责,服务应基于有界的上下文(bounded 		context,通常是边界清晰的业务领域)构建,服务理想应当只有一个变更的理由(类似Robert C. Martin讲的:A class should have only one reason to change),当一个服务承担过多职责,就会产生各种耦合性问题,需要进一步拆分使其尽可能职责单一化。
	2·关注分离(Separation of Concerns),跨横切面逻辑,例如日志分析、监控、限流、安全等等,尽可能与具体的业务逻辑相互分离,让开发人员能专注于业务逻辑的开发,减轻他们的思考负担,这个也是有界上下文(bounded context)的一个体现。
	3·模块化(Modularity)和分而治之(Divide & Conquer),这个是解决复杂性问题的一般性方法,将大问题(如单块架构)大而化小(模块化和微服务化),然后分而治之。

前期阶段,大致要做好如下事情:

和多方充分沟通,确保能符合客户和组织的需求,并且得到认同
和团队沟通,让队友(开发/测试/运维)理解,并且积极投入
和业务部门沟通,指定版本计划和上线时间
 

设计阶段,参考 Sam Newman 的著作《微服务设计》,单微服务必须要满足以下的条件,才符合微服务的基本要求:

标准的 REST 风格接口(基于 HTTP 和 JSON 格式)
独立部署,避免共享数据库(避免因为数据库而影响整个分布式系统)
业务上的高内聚,减少依赖(从设计上要避免服务过大或者太小)
 

技术阶段,庞大的分布式系统,需要强大基础设施来支撑,微服务涉及哪些基础设施?

CI/CD和自动化(分布式系统几乎不可能通过人工手动发布)
虚拟化技术(要保证微服务运行环境隔离,目前行业主流的是使用 Docker 容器)
日志聚合,全链路监控(高度可观察和分析诊断问题)

参考博文:https://www.cnblogs.com/xiao2shiqi/p/11298663.html

redis用过锁吗

redis缓存穿透
key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。

参考博文: https://www.cnblogs.com/xichji/p/11286443.html

redis雪崩
很多key在同一时间同时过期,解决方案就是把key分组,分别设置过期时间,避免同时过期的情况

redis内存优化

参考:https://blog.csdn.net/qq_42046105/article/details/124507123

redis淘汰策略

(1)volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
(2)volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
(3)volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
(4)volatile-lfu:从已设置过期时间的数据集挑选使用频率最低的数据淘汰。
(5)allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
(6)allkeys-lfu:从数据集中挑选使用频率最低的数据淘汰。
(7)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
(8) no-enviction(驱逐):禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。

这八种大体上可以分为4中,lru、lfu、random、ttl。

Redis最为常用的数据类型主要有以下

String
Hash
List
Set
Z set 有序集合

redis 的应用场景

缓存,秒杀(expire过期时间),计数器(incrby命令可以实现原子性的递增),排行榜(SortedSet 排序),分布式锁(setnx命令进行,有过期时间,可防止死锁),延时操作,分页、模糊搜索(set集合中提供了一个zrangebylex方法),点赞、好友等相互关系的存储(set),队列
消息队列(rabbitMQ)

参考博文: https://www.jianshu.com/p/40dbc78711c8

spring bean 不是线程安全的

Spring对Bean没有做什么加锁之类的操作,所以它不是线程安全

如果创建Bean的时候,作用域设置为prototype,那么每次获取Bean都会新建一个Bean实例

作用域设置为prototype的时候,Bean绝对是安全的
其他时候就不一定了,比如单例的作用域的时候,多个线程同时获取的Bean本就是共享的,本就是不安全的

如果要Bean保证线程安全的问题,就把作用域设置为prototype

@Component
@Scope(value = "prototype")
public class AOPTest{}

这也跟Bean的状态有一点关,如果Bean是⽆状态的,那么Bean则是线程安全的

如果我们不对Bean中的成员变量进行修改,不会对成员变量进行任何的改动
那别说Bean对象,任何对象是这种⽆状态的,线程都是安全的
因为多线程不会改动到任何共享的数据

幂等性问题

微服务的架构设计

mybatis原理

通过 Resource加载 mapper.xml,生成一个 inputstream的输入流,创建 sqlsessionfactorybuilder对象,通过该对象的 builder( inputstream)方法,返回一个 sqlsessionfactory对象,由 sqlsessionfactory对象生成 sqlsession,通过 statement id找到对应的 statement,通过传入的参数进行一系列的复杂判断生成要执行的 sql,通过 jdbc执行 sql,然后把结果封装成 map、 list等返回

mybatis $ # 的区别

 # 可以防止SQL注入 他会做字符串处理 他是预编译的,会用 ? 作为占位符
 $ 变量拼接符,属于静态文本替换,不能防止sql注入

TCP协议详解

1.第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;

2.第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

3.第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

完成了三次握手,客户端和服务器端就可以开始传送数据。以上就是TCP三次握手的总体介绍。

参考博文:
https://blog.csdn.net/weixin_40462235/article/details/79840355?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-1&spm=1001.2101.3001.4242

java sync 锁的是什么

对象

hashmap的原理

(一个是链表的长度达到8个,一个是数组的长度达到64个)
	数组加连表的结构  运用了红黑树原理

Java8中HashMap的红黑树
实质上就是 平衡二叉树 ,通过颜色约束二叉树的平衡:

1)每个节点都只能是红色或者黑色

2)根节点是黑色

3)每个叶节点(NIL 节点,空节点)是黑色的。

4)如果一个节点是红色的,则它两个子节点都是黑色的。也就是说在一条路径上不能出现相邻的两个红色节点。

5)从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

springboot的初始化原理

参考博文:https://blog.csdn.net/u014745069/article/details/83820511

jvm的分区(五大分区)

程序计数器,虚拟机栈,本地方法栈,堆,方法区

参考博文:https://blog.csdn.net/qq_32755757/article/details/85259133

GC垃圾回收机制

把所有对象组成一个集合,或可以理解为树状结构,从树根开始找,只要可以找到的都是活动对象,如果找不到,这个对象就被回收了
	工作原理
		GC的工作流程主要分为如下几个步骤:
		1、标记(Mark)---GC的根节点也即GC Root
		2、计划(Plan)
		3、清理(Sweep)
		4、引用更新(Relocate)
		5、压缩(Compact)

怎么执行GC垃圾回收

代码主动显式调用System.GC.Collect()

springboot是怎么实现springmvc的东西的

mysql怎么运用分库分表

两种解决方案:垂直拆分、水平拆分

  1. 垂直拆分:根据业务进行拆分,比如可以将一张表中的多个字段拆成两张表,一张是不经常更改的,一张是经常改的。
  2. 水平拆分:即根据表来进行分割:比如user表可以拆分为user0,、user1、user2、user3、user4等

参考博文:https://www.cnblogs.com/mengtaoadmin/p/11184047.html

用过哪些设计模式

工厂模式,单例模式(双检锁主要是加锁操作,先判断有没有对象,没有再创建),观察者模式。生产者消费者模式,动态代理模式

参考博文:https://www.cnblogs.com/leeego-123/p/10882079.html

对Euraka服务注册中心的理解

Eureka 原理与步骤
		比拟场景:餐厅吃饭
			1、先向收银员(注册中心)要个号牌(IP地址)。
			2、饭菜到场就根据你号牌(IP地址)将饭菜端到你面前。
			3、在整个就餐过程中,你随时可以与收银员进行互相沟通(监听客户端心跳)。
			4、最后你吃完跑路了号牌回收(剔除服务器)。
		原理: 与比拟场景序号对应理解。
			1、服务提供方启动后将注册到 注册中心,提供IP, 名字,什么服务等信息,
			2、服务调用方作为客户端注册到注册中心后,拉取注册中心的服务列表,在通过负载均衡调用对应的服务提供方。
			3、注册中心可以建立集群,生成多台eureka,注册中心为了监测各个服务的心跳,将在每30S 向所注册的服务发起请求判断
			4、服务是否挂掉,如果挂掉90S后将会将服务从注册中心剔除。
			一个服务可以监测多台服务实例,从而可实现均衡负载。

参考博文:https://www.cnblogs.com/lanSeGeDiao/p/10801804.html

运用Euraka遇到的问题

zuul有哪些过滤器

	a、pre: 这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择请求的微服务,记录调试信息等。
	b、routing: 这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。
	c、post: 这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的http header、收集统计信息和指标、将响应从微服务发送给客户端等。
	e、error: 在其他阶段发送错误时执行该过滤器。

参考博文: https://www.cnblogs.com/linjiqin/p/10202085.html

分页插件的好处是什么

封装类型和基本类型的区别

包装类型可以为 null,而基本类型不可以
包装类型可用于泛型,而基本类型不可以
基本类型比包装类型更高效
两个包装类型的值可以相同,但却不相等
自动装箱和自动拆箱

怎么解决并发的

消息队列,多线程,负载均衡,代码的话用一些 并发包,比如说map用ConcurrentHashmap

shrio的使用

	Subject: 用户主体(把操作交给SecurityManager)
	SecurityManager:安全管理器(关联Realm)
	Realm:Shiro连接数据的桥梁
	1·创建ShiroFilterFactoryBean 
	设置安全管理器 securityManager
	添加Shiro内置过滤器(访问权限  anon: 无需认证(登录)可以访问  uthc: 必须认证才可以访问 user: 如果使用rememberMe的功能可以直接访问 perms: 该资源必须得到资源权限才可以访问
       role: 该资源必须得到角色权限才可以访问)
	2·创建DefaultWebSecurityManager
	关联realm
	自定义 realm  (public class UserRealm extends AuthorizingRealm 写执行认证逻辑,执行授权逻辑)

springmvc的源码

	用户请求DispatcherServlet。
	DispatcherServlet调用HandlerMapping,
	HandlerMapping根据请求路径找到对应的handler。
	DispatcherServlet调用HandlerAdapter
	HandlerAdapter去调用handler,并且在调用handler前后做一些适配。最终返回ModelAndView对象。
	DispatcherServlet调用ViewResovler,拼接出完整的jsp地址。
	DispatcherServlet传递模型数据给view,并且渲染打印数据给用户。
	
	DispatcherServlet:
	spring mvc的入口,整个框架运行就是在这个servlet中完成。
	HandlerMapping:
	处理器映射器。用于映射每个处理方法对应的请求路径。是一个map结构。
	handler:
	处理器。实际上就是控制器中的每个处理方法。
	HandlerAdapter:
	处理器适配器。专门用来调用handler,因为在spring mvc中每个处理方法参数以及返回类型都不一样,因此需要用适配器来适配。
	ViewResovler:
	视图解析器。用于指定视图技术,以及视图技术相关的配置。
	View:
	视图。springmvc 中支持多种视图,除了jsp外 还有xml,json,pdf等。

in id方法有用到索引吗

会用到索引

list的子类

ArrayList:底层数据结构为数组,查询快,增删慢,线程不安全,效率高;
Vector:底层数据结构为数组,查询快,增删慢,线程安全,效率慢,一般不用;
LinkedList:底层数据结构为链表,查询慢,增删快,线程不安全,效率高

ArrayList
ArrayList集合继承了List的所有成员方法,没有新增,用法和List同
Vector
Vector比继承体系历史更久远,有一些实现同样获取、遍历功能更复杂的方法,老版本用,新版本基本不用。
LinkedList
LinkedList中多了新增,删除,获取First&Last元素的方法

并发包

hashMap 在线程中的并发解决办法
	比如ConcurrentHashmap(锁分段技术)
	jdk1.7
		容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
	JDK 1.8
		不同于 JDK 1.7 版本的 Segment 数组 + HashEntry 链表,
		JDK 1.8 版本中的 ConcurrentHashMap 直接抛弃了 Segment 锁,一个 ConcurrentHashMap 包含一个 Node 数组(和 HashEntry 实现差不多),每个 Node 是一个链表结构,并且在链表长度大于一定值时会转换为红黑树结构(TreeBin)。

	,Hashtable等线程安全等集合类。 
		synchronized来保证线程安全
	为了解决集合的线程安全问题,JDK专门给我们提供了能够保证线程安全的集合。
	比如:CopyOnWriteArrayList、ConcurrentHashMap、CopyOnWriteArraySet、ArrayBlockingQueue等等。

对dubbo的理解

   1、容器 (spring容器)
   2、服务生产者
   3、注册中心 (zookeeper 、redis (发布订阅 -频道))
   4、服务消费者
   5、监控中心(可以查看哪个方法的使用次数)
容器启动,服务生产者会把自己的服务的接口地址报告给注册中心。服务消费者订阅它需要的服务,他去查询注册中心,大哥有地址吗?有就返回服务地址。消费者拿到地址就可以去调用服务。监控中心:监控生产者和消费者的健康状况。
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

注册中心挂了会产生什么影响?

对服务的调用没有任何影响,因为本地缓存了服务端的地址。

为什么使用Dubbo?

1、Dubbo提供了丰富的协议选择:Dubbo协议(服务调用),注册服务:zookeeper协议,tcp协议,http协议等。协议越底层,传输效率越高。     
2、io的选择:异步的nio。

什么叫事务?简称ACID

A 事务的原子性(Atomicity):指一个事务要么全部执行,要么不执行.也就是说一个事务不可能只执行了一半就停止了.比如你从取款机取钱,这个事务可以分成两个步骤:1划卡,2出钱.不可能划了卡,而钱却没出来.这两步必须同时完成.要么就不完成.
C 事务的一致性(Consistency):指事务的运行并不改变数据库中数据的一致性.例如,完整性约束了a+b=10,一个事务改变了a,那么b也应该随之改变.
I 独立性(Isolation):事务的独立性也有称作隔离性,是指两个以上的事务不会出现交错执行的状态.因为这样可能会导致数据不一致.
D 持久性(Durability):事务的持久性是指事务执行成功以后,该事务所对数据库所作的更改便是持久的保存在数据库之中,不会无缘无故的回滚.

线程中变量的可见性

Java中实现多线程共享变量的可见性方法有synchronize 和 volatile :
synchronize:可以用在方法或者代码块上,能保证可见性,也能保证原子性.
volatitle:用在变量上,只保证可见性,不保证原子性,不加锁,比synchronize轻量级,不会造成线程阻塞.volatitle读相当于加锁,volatitle写相当于解锁.

引用数据类型包括:

类、接口类型、数组类型、枚举类型、注解类型,字符串型。	

java排序算法

冒泡,相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。同理,其他的元素就可以排好。
	简单选择排序:,把0索引的元素,和索引1以后的元素都进行比较,第一次完毕,最小值出现在了0索引。同理,其他的元素就可以排好。
	插入排序:它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
	快速排序:快速排序的原理就是每次设置一个基准点,这个基准点可以是要排序的一趴数之间的任何数,然后将比基准点小的数放在基准点左边,比基准点大的数放在基准点右边
	二分排序:针对数组有序的情况(千万不要先排序,在查找)

10G的文件导入带数据库中怎么实现(怎么快速把10G的文件解析出来)

一、切割文件
CutText类中的方法splitFile(String filePath, String cutPath, int fileCount);
二、txt文件转换为csv文件
TxtToCSV类中的方法allFileIO(String filePath, String cutPath, int fileCount)
三、txt文件导入mysql
TxtLoadToMySQL类中的方法
toMySQL(String filePath, String cutPath, int fileCount)

参考博文:https://blog.csdn.net/L141210113/article/details/83865611

微信朋友圈的点赞功能怎么实现,好友可以看到,共同好友可以看到

js == === 的区别

== 类型不一样 转换在比较
=== 类型不一样直接false  类型一样才比较

springboot 的 starter的工作原理 自动装配

@Configuration&与@Bean------>>>基于java代码的bean配置
@Conditional-------->>>>>>设置自动配置条件依赖
@EnableConfigurationProperties与@ConfigurationProperties->读取配置文件转换为bean。
@EnableAutoConfiguration、@AutoConfigurationPackage 与@Import->实现bean发现与加载。

Servlet的生命周期

加载阶段、实例化阶段、初始化阶段init、服务阶段service、销毁阶段destroy

如何取得每个部门薪资前三名的人员名称?

select e.ename, e.deptno,e.sal

from emp e
left join dept d on e.dept_id = d.id

where
 (select count(*) from emp em where em.sal>=e.sal and em.deptno=e.deptno) <= 3

order by e.deptno,e.sal desc;
SELECT * FROM t_testscore t  

  WHERE EXISTS(SELECT COUNT(*) FROM t_testscore ts  WHERE ts.c_score>=t.c_score  GROUP BY ts.c_class  HAVING COUNT(*)<=3)  

    ORDER BY c_class,c_score DESC;

查询两张表中没有交集的数据

left join  where id is null 的数据

swagger 注解参数

@ApiParam(name = "id", value = "用户id", required = true)

- @Api()用于类; 
表示标识这个类是swagger的资源 
- @ApiOperation()用于方法; 
表示一个http请求的操作 
- @ApiParam()用于方法,参数,字段说明; 
表示对参数的添加元数据(说明或是否必填等) 
- @ApiModel()用于类 
表示对类进行说明,用于参数用实体类接收 
- @ApiModelProperty()用于方法,字段 
表示对model属性的说明或者数据操作更改 
- @ApiIgnore()用于类,方法,方法参数 
表示这个方法或者类被忽略 
- @ApiImplicitParam() 用于方法 
表示单独的请求参数 
- @ApiImplicitParams() 用于方法,包含多个 @ApiImplicitParam

参考博文:https://blog.csdn.net/wyb880501/article/details/79576784

synchronized 的方式

个人理解:
synchronized(this)
因为this是当前对象本身,所以锁定只对你自己new了并调用那个对象有用,所以另外一个人如果要new并调用,则和这个不是同一个锁,因为this变了。
synchronized(类的名.class)
每个类在jvm里面只有一个唯一的字节码,所以.class是唯一的,无论多少对象,共用此同一把锁。

接口和抽象的区别

相同点:
	(1)都不能被实例化
	(2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。

不同点:
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
(5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。

怎么把抽象类变为接口

索引联合

mysql的事务隔离级别

	1、未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
	2、提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
	3、可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读,但是innoDB解决了幻读
	4、串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

参考博文: https://www.cnblogs.com/rxbook/p/8975924.html

索引的数据结构

参考博文:
https://www.cnblogs.com/xiaoshahai/p/12028737.html
https://blog.csdn.net/u013314679/article/details/105665026/

redis是怎么实现单线程的

spring bean 为什么没有状态

	有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。 
	无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。 

Map map = new HashMap()用到了什么设计模式

工厂模式有几种写法

抽象工厂,简单(静态)工厂,多方法工厂(常用)
			public class MulWayNoodlesFactory {

			/**
			 * 模仿Executors 类
			 * 生产泡面
			 *
			 * @return
			 */
			public static INoodles createPm() {
				return new PaoNoodles();
			}

			/**
			 * 模仿Executors 类
			 * 生产兰州拉面
			 *
			 * @return
			 */
			public static INoodles createLz() {
				return new LzNoodles();
			}

			/**
			 * 模仿Executors 类
			 * 生产干扣面
			 *
			 * @return
			 */
			public static INoodles createGk() {
				return new GankouNoodles();
			}
		}
	    INoodles lz2 = MulWayNoodlesFactory.createLz();
        lz2.desc();

redis什么时候会变卡

单例模式有几种写法(五种)

懒汉式(少用),饿汉式(常用),双检锁(包含线程安全和线程不安全两种方式),静态内部类(在要明确实现 lazy loading 效果时),枚举(运用到反序列化创建对象的推荐)

参考文档: https://blog.csdn.net/absolute_chen/article/details/93380566

红黑树是怎么保证自平衡的

任意一结点到每个叶子结点的路径都包含数量相同的黑
	自平衡所需要的操作,无非是变色,左旋,右旋。变色不用多说,黑变红红变黑。
	
我们添加一个节点后,如果其父节点还没满三个(左右节点都为红表示满 了),并且空位在新增节点这边,那么变色即可完成修改。
如果新加节点的父节是红色,说明没空位了。那么就得拆分,将红节点变黑。这时会发现又新增了一层,于就通过父节点的左旋或右旋,将父节点上升一层。于是又变回只新增一层,又可以重新按思路走下去。
如果新增节点没有空位让其补进去,会如此一直旋转变色下去,最后到达根节点处。或是左旋或是右旋,根节点会变为原来子节点的子节点,子节点上升为根节点,到此,层数增长。由此也可以知道,层数增长总是发生在根处。

参考博文: https://blog.csdn.net/zjbyough/article/details/105336372

数据结构有哪些

哈希表(Hash)
队列(Queue)
树(Tree)
堆(Heap)
数组(Array)
栈(Stock)
链表(Linked List)
图(Graph)

js的选择器

IOC的实现原理

IOC原理
IOC(Inversion of control控制反转)(之前都是通过new创建对象,是很耗时间的)启动服务器的时候把对象创建好,然后放在容器里面,容器(Spring)就像hashmap那样键值对保存起来。等我们要调用方法的时候去容器拿出来调用它的方法就可以了,这样就减少了对象创建的次数,降低服务器的内存压力,提高了访问速度,我们通常把这创建对象的过程放在服务器启动的时候(利用ServletContextListener来实现,ServletContext初始化时就解析XML或者扫描包路径,来创建各个bean对象)

DI(依赖注入)

就是容器中的对象需要什么属性我就给你什么属性{IOC/DI就是为了降低服务器的压力,提高访问效率,降低对象之间的耦合度}

AOP原理

自己理解:
底层动态代理实现,(封装了创建会话工厂,打开session,创建事务)让我们注重逻辑代码实现(封装了提交事务,关闭session,关闭事务)(降低耦合度,我们在真的逻辑代码前后可以插入我们的日志代码)

Autowired 和Resources的区别

@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。 @Resources按名字,是JDK的,@Autowired按类型,是Spring的。

sprngboot文件上传用什么参数

依赖注入有几种方式

接口,构造, setter

负载均衡用了哪些算法

轮询,加强轮询,随机,加强随机,最小化原则

get方法参数为中文会变成什么

%52%

mysql怎么存储表情符号

使用  utf8mb4_general_ci(推荐)  utf8mb4_unicode_ci(更准确) 字符集

进程和线程

区别:进程是分配资源的最小单位,线程是调度资源的最小单位
	  一个进程中有一个或多个线程
	  一个线程只能属于一个进程
	  进程之间的资源是独立的,线程之间的资源是共享的。

线程的生命周期

线程的五大状态(新建——准备——运行——阻塞——死亡)

mysql的优化方向

MYSQL优化主要分为以下四大方面:
设计:存储引擎,myisam|innodb; 字段类型,尽可能小(占用存储空间少)、尽可能定长(占用存储空间固定)、尽可能使用整数。 范式与逆范式
功能:索引,缓存,分区分表。
架构:主从复制,读写分离,负载均衡。
合理SQL:测试,经验。

参考博文:https://www.cnblogs.com/sharpest/p/10390035.html

过滤器Filter和拦截器Interceptor的区别

   ①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

参考博文:https://www.cnblogs.com/panxuejun/p/7715917.html

String 为什么不能被继承

 因为 是fanal

怎么实现自动登录的

token机制,token过期之后,用refess_token 去刷新,获取新的token,保证登录状态

Springcloud和dubbo的区别

服务的发现、注册、路由、熔断、降级、分布式配置 
dubbo是调用方式 rpc 通讯协议    cloud  rest api  
dubbo由于是二进制的传输,占用带宽会更少  cloud 带宽会比较多,同时使用http协议一般会使用JSON报文,消耗会更大

sync和lock的区别

  1. Synchronized和Lock的区别:Synchronized编码更简单,锁机制由JVM维护,在竞争不激烈的情况下性能更好。Lock功能更强大更灵活,竞争激烈时性能较好。
  2. 性能不一样:资源竞争激励的情况下,lock性能会比synchronize好,竞争不激励的情况下,synchronize比lock性能好,synchronize会根据锁的竞争情况,从偏向锁–>轻量级锁–>重量级锁升级,而且编程更简单。
  3. 锁机制不一样:synchronize是在JVM层面实现的,系统会监控锁的释放与否。lock是JDK代码实现的,需要手动释放,在finally块中释放。可以采用非阻塞的方式获取锁。
  4. Synchronized的编程更简洁,lock的功能更多更灵活,缺点是一定要在finally里面 unlock()资源才行。
  5. 用法不一样:synchronize可以用在代码块上,方法上。lock只能写在代码里,不能直接修改方法。

B+tree 的的特点

和B树的主要区别如下:

  1. 有 k 个子节点的非叶子节点拥有 k 个关键字,B树是k-1个。这使得非叶子节点能保存的关键字大大增加,因此树高也大大降低。
  2. 关键字不保存数据,只是用来索引,这样非叶子节点的所占的内存空间就变小了,读到内存中的索引信息就会更多一些,相当于减少了磁盘IO次数
    数据都是存在叶子节点,这样保证了相近的数据都能存在同一块数据块里。另外也使得B+树的查询次数更稳定,每次查询次数都是相同的,需要查询到叶子节点
  3. 叶子节点的指针指向下一个数据对应的叶子节点,因此B+树具备了天然排序功能,在排序和范围查找的时候更方便,可以通过叶子节点的指针找到下一个叶子节点的位置
  4. B+树可以方便地做全表搜索,只需要从第一个叶子节点顺序往后面扫描即可,而B树则需要做树的遍历。

redis持久化机制

RDB 快照的方式写入到二进制文件中,默认的文件名为dump.rdb。 有两种触发方式 , save bgsave  全量备份
AOF  文件重写原理  增量备份

JAVA线程池有哪些配置参数,各自的作用是什么?

  1. corePoolSize(核心线程数)。核心线程会一直存在,即使没有任务执行;当线程数小于核心线程数的时候,即使有空闲线程,也会一直创建线程直到达到核心线程数;allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭。

  2. queueCapacity(任务队列容量)。也叫阻塞队列,当核心线程都在运行,此时再有任务进来,会进入任务队列,排队等待线程执行。

  3. maxPoolSize(最大线程数),线程池里允许存在的最大线程数量;当任务队列已满,且线程数量大于等于核心线程数时,会创建新的线程执行任务;线程池里允许存在的最大线程数量。当任务队列已满,且线程数量大于等于核心线程数时,会创建新的线程执行任务。

  4. keepAliveTime(线程空闲时间)。当线程空闲时间达到keepAliveTime时,线程会退出(关闭),直到线程数等于核心线程数;如果设置allowCoreThreadTimeout=true,则线程会退出直到线程数等于零。

  5. allowCoreThreadTimeout(允许核心线程超时)

  6. rejectedExecutionHandler(任务拒绝处理器),当线程数量达到最大线程数,且任务队列已满时,会拒绝任务;调用线程池shutdown()方法后,会等待执行完线程池的任务之后,再shutdown()。如果在调用了shutdown()方法和线程池真正shutdown()之间提交任务,会拒绝新任务


2022-06-02继续更新


mysql锁有哪些

MySQL数据库中的锁有:
1、共享锁,表示对数据进行读操作;
2、排他锁,表示对数据进行写操作;
3、行锁,对一行记录加锁,只影响一条记录;
4、意向锁,为了在一个事务中揭示下一行将要被请求锁的类型。

锁的级别

根据锁的级别或密度来划分,MySQL有三种锁的级别:页级、表级、行级。
(1)表级锁
开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
(2)行级锁
开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
(3)页面锁
开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

mysql索引有哪些?

1、主键索引:主键索引是一种特殊的唯一索引,不允许有空值
2、普通索引或者单列索引
3、多列索引(复合索引):复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合
4、唯一索引或者非唯一索引
5、空间索引:空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建

mysql性能优化

1、选择最合适的字段属性
2、尽量把字段设置为NOT NULL
3、使用连接(JOIN)来代替子查询(Sub-Queries)
4、使用联合(UNION)来代替手动创建的临时表
5、事务
6、使用外键
7、锁定表
8、使用索引

索引优化及失效 使用联合索引,where
条件顺序要跟索引一直,否则会失效,如果三个参数联合索引,中间一个参数不一致,则只有第一个条件生效
当第二个参数用了范围条件,则后面的条件也不会用到来联合索引 select * 又不必要的开销。select 字段 where
字段相同能用到覆盖索引

9、优化查询语句

例如:
1 、不使用子查询
2、 避免函数索引 (例如:SELECT * FROM t WHERE YEAR(d) >= 2016;)
3 、用IN来替换OR
4、 LIKE双百分号无法使用到索引(最佳左前缀法制)
5、 读取适当的记录LIMIT M,N (查询是否为空时限制记录 limit 1)
6、 避免数据类型不一致 (查询条件类型不一致)
7 、分组统计可以禁止排序
8、 避免随机取记录
9、 禁止不必要的ORDER BY排序
10 、批量INSERT插入(尽量使用一条SQL批量插入)
查询是不要用select * ,必须指明字段
使用explain关键字来查看当前sql语句的执行情况,来对症下药.因为内容较多,放在最后进行讲解
正确的建立索引
in 包含的值不要过多
只查询一条数据的时候,使用limit 1
对于联合索引来说,要遵守最左前缀法则:
应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描

explain 关键字sql执行情况

参考:https://www.cnblogs.com/tufujie/p/9413852.html

基本数据类型有哪些

1.整型:byte,short,int,long。
2.浮点型:float,double。
3.逻辑型:boolean。
4.字符型:char。

Mybatis-Plus 表里面有两个主键(复合组件)应该怎么插入

使用mybatisplus-plus
注意mybatisplusmybatisplus-plus的版本兼容性
首先引入jar包

<dependency>
     <groupId>com.github.jeffreyninggroupId>
     <artifactId>mybatisplus-plusartifactId>
     <version>1.5.1-RELEASEversion>
dependency>
<dependency>
     <groupId>com.baomidougroupId>
     <artifactId>mybatis-plus-boot-starterartifactId>
     <version>3.1.0version>
 dependency>
 <dependency>
     <groupId>com.baomidougroupId>
     <artifactId>mybatis-plus-generatorartifactId>
     <version>3.1.0version>
 dependency>

DTO这么写

	@MppMultiId // 复合主键
    @TableField("userId")
    @ApiModelProperty(value = "用户id")
    private Integer userId;
    @TableField("lessonItemId")
    @ApiModelProperty(value = "子课程id")
    private Integer lessonItemId;

@MppMultiId 注解即声明为复合主键,并以@TableField 主键 声明表字段

参考:https://www.yzlfxy.com/jiaocheng/java/422670.html

分布式事务

解决方案:
1、基于XA的两阶段提交方案
 2、TCC解决方案

为3个逻辑,Try-Confirm-Cancel。

1.先是服务调用链路依次执行Try逻辑(预留资源出来)
2.如果都正常的话,TCC分布式事务框架推进执行Confirm逻辑,完成整个事务
3.如果某个服务的Try逻辑有问题,TCC分布式事务框架感知到之后就会推进执行各个服务的Cancel逻辑,撤销之前执行的各种操作
这就是所谓的TCC分布式事务。
TCC分布式事务的核心思想,说白了,就是当遇到下面这些情况时,

某个服务的数据库宕机了
某个服务自己挂了
那个服务的redis、elasticsearch、MQ等基础设施故障了
某些资源不足了,比如说库存不够这些
先来Try一下,不要把业务逻辑完成,先试试看,看各个服务能不能基本正常运转,能不能先冻结我需要的资源。

如果Try都ok,也就是说,底层的数据库、redis、elasticsearch、MQ都是可以写入数据的,并且你保留好了需要使用的一些资源(比如冻结了一部分库存)。

接着,再执行各个服务的Confirm逻辑,基本上Confirm就可以很大概率保证一个分布式事务的完成了。

那如果Try阶段某个服务就失败了,比如说底层的数据库挂了,或者redis挂了,等等。

此时就自动执行各个服务的Cancel逻辑,把之前的Try逻辑都回滚,所有服务都不要执行任何设计的业务逻辑。保证大家要么一起成功,要么一起失败。

扩展问题:比如说订单服务突然挂了,然后再次重启,TCC分布式事务框架是如何保证之前没执行完的分布式事务继续执行的呢?

    TCC事务框架都是要记录一些分布式事务的活动日志的,可以在磁盘上的日志文件里记录,也可以在数据库里记录。保存下来分布式事务运行的各个阶段和状态。

扩展问题:万一某个服务的Cancel或者Confirm逻辑执行一直失败怎么办呢?

    TCC事务框架会通过活动日志记录各个服务的状态。

举个例子,比如发现某个服务的Cancel或者Confirm一直没成功,会不停的重试调用他的Cancel或者Confirm逻辑,务必要他成功!

3、本地消息表 (异步确保)
 4、MQ事务消息
 5、分布式事务中间件解决方案
实现框架:
LCN分布式事务框架

参考:https://www.cnblogs.com/jing99/p/11769093.html

同一个类下面:两个方法A调用B,B有事务,整个方法有没有事务?

方法A调用方法B:
1、如果只有A加@Transactional注解;则AB在同一事务中;
2、如果只有B加@Transactional注解;AB方法为同一类,事务失效;AB不同类,只有B有事务;
3, 如果A和B都有事务,那就B开启一个新事务,
例如:

 @Transactional(propagation = Propagation.REQUIRES_NEW)
 @Transactional(propagation = Propagation.NESTED)

logback和log4j的区别

1.更快的实现
Logback的内核重写了,在一些关键执行路径上性能提升10倍以上。而且logback不仅性能提升了,初始化内存加载也更小了。

2.Logback-classic非常自然实现了SLF4j
Logback-classic实现了SLF4j。在使用SLF4j中,你都感觉不到logback-classic。而且因为logback-classic非常自然地实现了SLF4J,所以切换到log4j或者其他,非常容易,只需要提供成另一个jar包就OK,根本不需要去动那些通过SLF4JAPI实现的代码。

3.自动重新加载配置文件
当配置文件修改了,Logback-classic能自动重新加载配置文件。扫描过程快且安全,它并不需要另外创建一个扫描线程。这个技术充分保证了应用程序能跑得很欢在JEE环境里面。

4.SiftingAppender(一个非常多功能的Appender)
它可以用来分割日志文件根据任何一个给定的运行参数。如,SiftingAppender能够区别日志事件跟进用户的Session,然后每个用户会有一个日志文件。

5.自动压缩已经打出来的log
RollingFileAppender在产生新文件的时候,会自动压缩已经打出来的日志文件。压缩是个异步过程,所以甚至对于大的日志文件,在压缩过程中应用不会受任何影响。

6.自动去除旧的日志文件
通过设置TimeBasedRollingPolicy或者SizeAndTimeBasedFNATP的maxHistory属性,你可以控制已经产生日志文件的最大数量。如果设置maxHistory为12,那那些log文件超过12个月的都会被自动移除。

int主键和string主键效率哪个高

主键用整型会极大的提高查询效率,而字符型的比较开销要比整型的比较开销大很多,用字符型数据作主键会使数据插入、更新与查询的效率降低。数据量小的时候这点降低可能不会被注意,可是当数据量大的时候,小的改进也能够提高系统的响应速度。

服务治理是什么

微服务化的架构给系统带来了很多好处,但同时也带来了一些技术上的挑战。这些挑战包括服务注册与发现、负载均衡、监控管理、发布升级、访问控制等。而服务治理就是对这些问题进行管理和预防,保证系统持续平稳地运行。

本文所讲的服务治理方案,也算是传统意义上的方案,有时会有一些代码的侵入,而框架的选择也会对编程语言有限制。

在云原生时代, Service Mesh 的出现又把服务治理的话题带入一个新的阶段。

参考:https://blog.csdn.net/wabiaozia/article/details/84197308

Mq如何防止消息丢失解决方案

1.生产者存放消息的过程中丢失消息
1)事务机制:(同步方式,不推荐)
2)异步机制:
事务模式和confirm模式的区别:
事务机制是同步的,提交事务后悔被阻塞直到提交事务完成后。
confirm 模式异步接收通知,但可能接收不到通知。需要考虑接收不到通知的场景。

2.消息队列消息丢失
解决办法:
1,创建Queue时,将其设置为持久化
2,发送消息的时候将消息的deliveryMode设置为2(将消息持久化 1:非持久化,2:持久化)
3,开启生产者 confirm`模式,可以重试发送消息。

3.消费者丢失消息
解决办法:
关闭RabbitMQ的自动ack,每次生产者将消息写入消息队列后,就自动回传一个ack给生产者。
消费者处理完消息再主动ack,告诉消息队列我处理完了。

总结:

1.开启生产者消息手动确认机制
2.开启消息持久化,队列持久化,交换机持久化(默认开启)
3.开启消费者消息手动确认机制

订单延迟30分钟未支付,自动关闭

使用消息队列的延迟队列(死信队列)
原理:下单投放消息到A交换机(过期时间30分钟),消息到aa队列(绑定死信交换机),不设置aa队列的消费者(故此消息一直未消费).
30分钟后,过期消息投递到死信交换机,死信队列,由死信消费者消费,判断订单id是否支付,执行业务逻辑,
支付->return
未支付->关闭订单,返还库存

redis使用在分布式锁的场景

实现
可以直接通过 SET lock_key unique_value NX PX milliseconds 命令实现加锁, 通过Lua脚本实现解锁

//获取锁(unique_value可以是UUID等)
SET resource_name unique_value NX PX  30000
 
//释放锁(lua脚本中,一定要比较value,防止误解锁)
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

代码解释
set 命令要用 set key value px milliseconds nx,替代 setnx + expire 需要分两次执行命令的方式,保证了原子性,
value 要具有唯一性,可以使用UUID.randomUUID().toString()方法生成,用来标识这把锁是属于哪个请求加的,在解锁的时候就可以有依据;
释放锁时要验证 value 值,防止误解锁;
通过 Lua 脚本来避免 Check And Set 模型的并发问题,因为在释放锁的时候因为涉及到多个Redis操作 (利用了eval命令执行Lua脚本的原子性);

mysql 视图和表的区别

1、视图是已经编译好的sql语句。而表不是
2、视图没有实际的物理记录。而表有。
3、表是内容,视图是窗口。
4、表只用物理空间而视图不占用物理空间,视图只是逻辑概念的存在,表可以及时修改,但视图只能有创建的语句来修改
5、表是内模式,试图是外模式
6、视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些SQL语句的集合。从安全的角度说,视图可以不给用户接触数据表,从而不知道表结构。
7、表属于全局模式中的表,是实表;视图属于局部模式的表,是虚表。
8、视图的建立和删除只影响视图本身,不影响对应的基本表。

表和临时表的区别

临时表写入速度更快,表需要写入硬盘

一个文件夹里面有多个文件夹中有多个文件,如何读取里面的txt文件的名称

SpringBoot 在项目启动之后执行自定义方法的两种方式

@Component
@Order(1)  // 控制类执行的顺序越小越靠前
public class StartInitializer implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("项目启动,执行 CommandLineRunner 实现类的方法");
    }
}
@Component
@Order(2) // 控制类执行的顺序越小越靠前
public class AppInitializer implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("项目启动,执行 ApplicationRunner 实现类的方法");
    }
}

区别在于实现方法 run() 中的参数类型不一样
实现 ApplicationRunner 接口的 run() 方法参数类型为: ApplicationArguments
实现 CommandLineRunner 接口的 run() 方法参数类型为: String...

对微服务的理解

(1)将复杂的服务拆分成单一功能的服务,利于分工,定位问题也方便。
(2)微服务系统就是分布式系统,业务与业务之间完全解耦。
(3)服务与服务之间完全独立。每个服务可以根据业务场景选取合适的编程语言和数据库。
(4)个服务都是独立部署的,每个服务的修改和部署对其他服务没有影响。

java 异常的原理

异常,又称例外,是指程序运行过程中出现的非正常现象。例如:用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。由于异常情况总是不可避免的,良好的应用程序除了具备用户所需求的基本功能外,还应具有预见并处理可能发生的各种异常的功能。引入了异常处理。

用面向对象的方法处理异常,就必须建立类的层次。在Java中,Throwable是所有可以通过throw抛出或catch捕获错误的基类。Throwable 对象有两个直接子类对象:Error类和Exception类。Error类用来表示编译错误和系统错误,如虚拟机错误、装载错误、动态链接错误,这类异常主要与硬件、运行系统有关,与程序本身无关,因此不需要捕获,特殊情况例外。Exception类用来表示可以被抛出异常的基类和用户自定义异常类。

所有的异常都由Throwable或者其子类的一个对象来表示,这种对象可用于把信息从常发生点传递到捕获点得处理程序中。异常句柄由try语句块中得catch子句建立。在处理异常的过程中,Java VM把当前线程中已开始运行但尚未结束的表达式、语句、方法、构造方法调用、静态初始化或域初始化表达式连续终止掉。这个过程一直继续下去,直到发现了一个异常句柄,该句柄通过指定异常的类或异常类的超类来声明它能处理该异常。如果未发现这样的句柄,就调用当前线程的父线程ThreadGroup的方法uncaught Exception,从而尽可能避免异常逃过处理。

异常处理的原则:Java异常处理结构由try,catch,finally三个块组成。其中try块存放将可能发生异常的Java代码,并管理相关的异常指针;catch块紧跟在try块后面,用来激发被捕获的异常;finally块包含清除程序没有释放的资源,句柄等。不管try块中的代码如何退出,多将执行finally块

spring 原理

IOC原理
IOC(Inversion of control控制反转)(之前都是通过new创建对象,是很耗时间的)启动服务器的时候把对象创建好,然后放在容器里面,容器(Spring)就像hashmap那样键值对保存起来。等我们要调用方法的时候去容器拿出来调用它的方法就可以了,这样就减少了对象创建的次数,降低服务器的内存压力,提高了访问速度,我们通常把这创建对象的过程放在服务器启动的时候(利用ServletContextListener来实现,ServletContext初始化时就解析XML或者扫描包路径,来创建各个bean对象)其中DI(依赖注入)就是容器中的对象需要什么属性我就给你什么属性{IOC/DI就是为了降低服务器的压力,提高访问效率,降低对象之间的耦合度}

AOP原理
自己理解:
底层动态代理实现,(封装了创建会话工厂,打开session,创建事务)让我们注重逻辑代码实现(封装了提交事务,关闭session,关闭事务)(降低耦合度,我们在真的逻辑代码前后可以插入我们的日志代码)

sleep和wait有什么区别

1,这两个方法来自不同的类分别是Thread(自控)和Object(他控)
2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
任何地方使用
synchronized(x){
x.notify()
//或者wait()
}
4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常(终端异常)

Java 实现动态代理主要涉及哪几个类

java.lang.reflect.Proxy: 这是生成代理类的主类,通过 Proxy 类生成的代理类都继承了 Proxy 类,即 DynamicProxyClass extends Proxy。
java.lang.reflect.InvocationHandler: 这里称他为"调用处理器",他是一个接口,我们动态生成的代理类需要完成的具体内容需要自己定义一个类,而这个类必须实现 InvocationHandler 接口。

数据库大数据量分页查询方式

SELECT
	a.* 
FROM
	`sys_user` a,
	( SELECT id FROM `sys_user` LIMIT 4000000, 20 ) b 
WHERE
	b.id = a.id

这个sql是先只查询id出来,然后再拿id关联本表全部数据,进行内连接查询。id查询比较快,然后内连接的时候,只从全部数据中找条件满足的,所以效率很高,看执行时间:

nacos和eureka的区别

1,nacos和eureka的范围不同Nacos的阈值是针对某个具体Service的,而不是针对所有服务的;但Eureka的自我保护阈值是针对所有服务的。nacos支持CP和AP两种eureka只支持APnacos使用netty,是长连接eureka短连接,定时发送。

2,Eureka保护方式:当在短时间内,统计续约失败的比例,如果达到一定阈值,则会触发自我保护的机制,在该机制下,Eureka Server不会剔除任何的微服务,等到正常后,再退出自我保护机制。自我保护开关(eureka.server.enable-self-preservation: false)
Nacos保护方式:当域名健康实例 (Instance) 占总服务实例(Instance) 的比例小于阈值时,无论实例 (Instance) 是否健康,都会将这个实例 (Instance) 返回给客户端。这样做虽然损失了一部分流量,但是保证了集群的剩余健康实例 (Instance) 能正常工作。

你可能感兴趣的:(资料,java,java)