基础八股文精简背诵版!

 

 

 

 

 

 

常见八股:

16:00面试,16:08就出来了 ,问的实在是太...

多线程部分:

Java 多线程八股文!

Spring

50 道经典 Spring 面试题

Spring和SpringBoot的区别

掘金

Spring是一个生态体系,包括了许多框架,如springboot、springframework等。其中Spring Framework是整个spring生态的基石。

Spring Framework是一个轻量级的Java web开发框架,以IOC和AOP为核心,然后在此两者的基础上实现了其他延伸产品的高级功能。包括了许多框架,如SpringMVC、SpringJDBC。用到的设计模式有:

  • 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

  • 单例模式:Bean默认为单例模式。

  • 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;

  • 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

  • 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

Spring Boot是基于Spring Framework 4.0派生的,它的诞生是为了简化 Spring 框架初始搭建以及开发的过程,使用它可以不再依赖 Spring 应用程序中的 XML 配置,为更快、更高效的开发 Spring 提供更加有力的支持。并且它还具有以下特点:

  • 内置了web容器,如Tomcat。

  • 通过starter可以简化构建配置

  • xml可以通过注解形式实现自动配置

  • 打成jar包后可直接部署运行

对于应用程序启动引导配置,Spring支持传统的web.xml引导方式以及最新的Servlet3+方法,SpringBoot仅使用 Servlet3功能来引导应用程序。

Spring Cloud是一整套基于Spring Boot的微服务解决方案。它为开发者提供了很多工具,用于快速构建分布式系统的一些通用模式,例如:配置管理、注册中心、服务发现、限流、网关、链路追踪等。

Spring Boot 的启动流程

SpringBoot 有哪些优点?它和 Spring 有什么区别? - 链滴

1.创建并启动计时监控类

此计时器是为了监控并记录 Spring Boot 应用启动的时间的,它会记录当前任务的名称,然后开启计时器。

2.声明应用上下文对象和异常报告集合

此过程声明了应用上下文对象和一个异常报告的 ArrayList 集合。

3.设置系统属性 headless 的值

设置 Java.awt.headless = true,其中 awt(Abstract Window Toolkit)的含义是抽象窗口工具集。设置为 true 表示运行一个 headless 服务器,可以用它来作一些简单的图像处理。

4.创建所有 Spring 运行监听器并发布应用启动事件

此过程用于获取配置的监听器名称并实例化所有的类。

5.初始化默认应用的参数类

也就是说声明并创建一个应用参数对象。

6.准备环境

创建配置并且绑定环境(通过 property sources 和 profiles 等配置文件)。

7.创建 Banner 的打印类

Spring Boot 启动时会打印 Banner 图片。此 banner 信息是在 SpringBootBanner 类中定义的,我们可以通过实现 Banner 接口来自定义 banner 信息,然后通过代码 setBanner() 方法设置 Spring Boot 项目使用自己自定义 Banner 信息,或者是在 resources 下添加一个 banner.txt,把 banner 信息添加到此文件中,就可以实现自定义 banner 的功能了。

8.创建应用上下文

根据不同的应用类型来创建不同的 ApplicationContext 上下文对象。

9.实例化异常报告器

它调用的是 getSpringFactoriesInstances() 方法来获取配置异常类的名称,并实例化所有的异常处理类。

10.准备应用上下文

此方法的主要作用是把上面已经创建好的对象,传递给 prepareContext 来准备上下文,例如将环境变量 environment 对象绑定到上下文中、配置 bean 生成器以及资源加载器、记录启动日志等操作。

11.刷新应用上下文

此方法用于解析配置文件,加载 bean 对象,并且启动内置的 web 容器等操作。

12.应用上下文刷新之后的事件处理

这个方法的源码是空的,可以做一些自定义的后置处理操作。

13.停止计时监控类

停止此过程第一步中的程序计时器,并统计任务的执行信息。

14.输出日志信息

把相关的记录信息,如类名、时间等信息进行控制台输出。

15.发布应用上下文启动完成事件

触发所有 SpringApplicationRunListener 监听器的 started 事件方法。

16.执行所有 Runner 运行器

执行所有的 ApplicationRunner 和 CommandLineRunner 运行器。

17.发布应用上下文就绪事件

触发所有的 SpringApplicationRunListener 监听器的 running 事件。

18.返回应用上下文对象

到此为止 Spring Boot 的启动程序就结束了,我们就可以正常来使用 Spring Boot 框架了。

SpringMVC 五大核心组件

  • DispatcherServlet 请求的入口

  • HandlerMapping 请求的派发,负责让请求和控制器建立一一对应的关联

  • Controller 真正的处理器

  • ModelAndView 封装模型信息和视图信息

  • ViewResolver 视图处理器,定位页面

SpringMVC执行流程

img

  • 客户端发送请求到前端控制器DispatcherServlet

  • 前端控制器收到请求后调用处理器映射器hanlderMapping

  • 处理器映射器并找到具体的处理器,生成处理器对象拦截器对象,再一起返回给前端控制器

  • 前端控制器调用处理器适配器HandlerAdapter

  • 处理器适配器经过适配调用具体的处理器Handler/Controller

  • 处理器执行完成返回视图对象modelAndView

  • 处理器适配器视图返回给前端控制器

  • 前端控制器视图传给视图解析器ViewReslover

  • 视图解析器返回具体的视图View

  • 前端控制器根据视图进行渲染

  • 前端控制器响应用户

bean的生命周期

1、实例化Bean对象

2、设置Bean的属性

3、注入Aware的依赖

4、执行前置处理函数,postProcessorBeforeInitialization()

5、执行afterPropertiesSet()方法,

6、执行Bean自定义的初始化方法,可用@PostConstruct注解标注

7、执行后置处理函数,POSTProcessorAfterInitialization()

8、对象创建完毕

9、执行对象销毁方法destory()

10、执行自定义的销毁方法,可用@PreDestory注解标注

11、对象销毁完毕

深究Spring中Bean的生命周期

springboot的核心技术

依赖注入、事件、资源、i18n、验证、数据绑定、类型转换、SpEL、AOP

修改自带的tomcat

在pom.xml去除tomcat相关的配置,再引入其他的servlet容器

SpringMVC常用注解

  • @Controller:使用该注解时不需要实现Controller接口,标注在类上面就是一个控制器

  • @Repository:用于注解dao层,一般用于DAO的实现类上

  • @Service:用于对业务逻辑层进行注解

  • @Component:注解在类上,会被spring容器识别,并转为bean。相当于通用的注解

  • @RequestMapping:处理请求地址映射,可以作用于类和方法上,表示访问请求该方法时的url

  • @Resource:自动注入bean,默认按照ByName自动注入,也可以按byType注入

  • @Autowired:自动注入bean,按照byType注入

  • @ModelAttribute:用于把参数保存到model中,可注解方法或参数

  • @PathVariable:用于将请求URL中的模板变量映射到方法的参数上,即取出url模板中的变量作为参数

  • @requestParam:用于获取传入参数的值

  • @ResponseBody:作用于方法上,可以将整个返回结果以某种格式返回,如json或xml格式

@Component和@Bean的区别

  • @Component 注解作用于,而@Bean注解作用于方法

  • @Component的类可以自动装配到Spring容器中,而@Bean 注解通常是在标有该注解的方法中定义产生这个 bean。(return这个bean)

Spring事务

JavaGuide/Spring事务总结.md at master · Snailclimb/JavaGuide · GitHub

Spring 支持事务管理的方式有两种:

  • 编程式事务管理:通过 TransactionTemplate或者TransactionManager手动管理事务,实际应用中很少使用

  • 声明式事务管理:通过 AOP 实现(基于@Transactional 的全注解方式使用最多)。

@Transactional的作用范围:

  1. 方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。

  2. :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。

  3. 接口 :不推荐在接口上使用。

Spring的自动装配

淘宝一面:“说一下 Spring Boot 自动装配原理呗?” - JavaGuide - 博客园

构造注入和setter注入有时在做配置时比较麻烦。“自动装配”指的是spring容器依据某种规则,自动建立对象之间的依赖关系。而spring框架式默认不支持自动装配的,要想使用自动装配,则需要修改spring配置文件中<bean>标签的autowire属性。

自动装配的规则:

  1. no:不支持自动装配功能,spring默认。

  2. default:表示默认采用上一级标签的自动装配的取值。如果存在多个配置文件的话,那么每一个配置文件的自动装配方式都是独立的。

  3. byName

    当一个bean节点带有 autowire="byName" 的属性时:

    ①将查找其类中所有属性。

    ②去配置文件中查找是否存在id名称与属性名称相同的bean。

    ③如果有,就取得该bean对象,并调用属性所在类中的setter方法,将找到的bean注入;找不到注入null。

    注意:不可能找到多个符合条件的bean(id唯一)

  4. byType

    当一个bean节点带有 autowire="byType" 的属性时:

    ①将查找其类中所有属性。

    ②去配置文件中查找是否存在bean类型与属性类型相同的bean。

    ③如果有,就取得该bean对象,并调用属性所在类中的setter方法,将找到的bean注入;找不到注入null。

    注意:找到多个符合条件的bean时会报错。

  5. constructor

    使用构造方法完成对象注入,其实也是根据构造方法的参数类型进行对象查找,相当于采用byType的方式。即:根据构造方法的参数的数据类型,进行 byType 模式的自动装配。

Spring注入方式

常用的注入方式主要有三种:

  • 构造方法注入:将对象传参到构造方法中。

  • setter注入

  • 基于注解的注入:@Autowired自动装配,默认是根据类型注入,可以用于构造器、字段、方法注入。

Spring循环依赖

Spring是如何解决循环依赖的? - 知乎

产生循环依赖问题的前提条件:Spring管理的Bean默认都是单例模式。

解决循环依赖的思路:三级缓存+标记缓存

Spring的三级缓存:

  • 一级缓存:保存所有已经创建完成的bean

  • 二级缓存:保存正常创建中的bean(完成实例化,但还未完成属性注入)

  • 三级缓存:保存的是ObjectFactory类型的对象的工厂,通过工厂的方法可以获取到目标对象

  • 标记缓存:保存正在创建中的对象名称。

注意:第三级缓存经过代理包装或替换后,进入到第二级缓存。

无法解决循环依赖的场景:Spring可以正常解决通过属性进行依赖注入的循环依赖场景,但是无法解决通过构造方法进行注入的循环依赖场景。

IOC、DI、AOP

  • IOC: Inversion of Control,控制反转。 创建和管理Bean的控制权从应用程序转移到框架。IOC主要解决了代码的高度耦合问题。主要有3种实现方式:set方法注入、构造方法注入、注解注入。

  • DI:Dependency Injection,依赖注入。是IOC的具体实现,将相互依赖的对象分离,在Spring的配置(注解)中描述它们之间的依赖关系,这些依赖关系也只在使用时才被建立。

  • AOP:Aspect Oriented Programming,面向切面编程。就是将程序功能中的频繁出现或者与主业务逻辑代码相关度不高的代码抽离出来,通过切面编程的方式在想要调用的时候引入调用的思想。这种思想的实现机制在Spring中便是应用了java的动态代理和java的反射

Spring AOP 实现原理

浅析Spring中AOP的实现原理——动态代理 - 特务依昂 - 博客园

通过动态代理实现,分别是JDK的动态代理和CGLib的动态代理。如果我们为Spring的某个bean配置了切面,那么Spring在创建这个bean的时候,实际上创建的是这个bean的一个代理对象,我们后续对bean中方法的调用,实际上调用的是代理类重写的代理方法

Spring默认使用JDK的动态代理实现AOP,类如果实现了接口,Spring就会使用这种方式实现动态代理。JDK的动态代理是基于反射实现。

JDK的动态代理存在限制,那就是被代理的类必须是一个实现了接口的类,代理类需要实现相同的接口,并实现代理接口中声明的方法。若需要代理的类没有实现接口,此时JDK的动态代理将没有办法使用,于是Spring会使用CGLib的动态代理来生成代理对象。CGLib直接操作字节码,生成类的子类,重写类的方法完成代理。

Java

面向对象和面向过程的区别

面向过程的开发方法中最重要的是对事件的处理过程。处理的对象多以变量的形式存在,且与处理过程之间不存在约束关系。开发简单。由于使用面向过程方法设计的程序把处理的主体与处理的方法分开,因此各种成分错综复杂地放在一起,难以理解,易出错,并且难于调试。

面向对象的开发方式中,以数据为中心,将数据及对数据的操作放在一起,形成对象。使用类来刻画有类似属性的不同对象,使用继承来简化开发过程,使用接口来规范对数据的操作,使用多态达到操作的灵活性。

面向对象易维护、易复用、易扩展。并且由于面向对象有封装、继承、多态性特性,所以可以设计出低耦合的系统,使系统更加灵活、更加易于维护。

抽象类和接口的区别

  1. 抽象类可以有构造方法,接口中不能有构造方法。

  2. 抽象类中可以有普通成员变量,接口中没有普通成员变量

  3. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

  4. 抽象类中的抽象方法的访问类型可以是 public,protected ,但接口中的抽象方法只能是 public 类型的,并且默认即为 public abstract 类型。

  5. 抽象类中可以包含静态方法,接口中不能包含静态方法

  6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只是public static final 类型,并且默认即为 public static final 类型。

  7. 一个类可以实现多个接口,但只能继承一个抽象类。

  8. 抽象类可以实现代码的复用;抽象类不可以创建实例对象;

  9. 有抽象方法的类一定是抽象类;抽象类中的方法可以不是抽象的;

类和抽象类的区别

  • 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

  • 抽象类不能用来创建对象。

  • 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

socket建立连接的过程

图解Java服务端Socket建立原理_一群专业码农的笔记本-CSDN博客_java服务端socket

在这里插入图片描述

在这里插入图片描述

img

STW(Stop The World)

JVM STW(Stop The World)到底怎么回事(三) | 李世佳的博客

FullGC发生过程中,整个应用程序线程都会被暂停(native代码可以执行,但不能与JVM交互),没有任何响应, 有点像卡死的感觉。被STW中断的应用程序线程会在完成GC之后恢复。STW是JVM在后台自动发起和自动完成的。

减少系统的停顿时间(STW)的增量收集算法 和分区算法_一个长不胖的程序YUAN的博客-CSDN博客

减少系统的停顿时间有两种算法:一种是增量收集算法,另一种是分区算法

锁的优化和注意事项

https://www.jb51.net/article/92453.htm

1、减少锁持有的时间和范围

2、减小锁的粒度,将大对象拆为小对象,如ConcurrentHashMap的做法

3、读/写锁分离

4、锁对象不要是字符串或基本类型的包装类,因为会缓存

秒杀场景下如何保证数据一致性

掘金

如何设计分布式锁

常见的分布式锁:MySql、Zk、Redis

掘金

JVM调优

掘金

image-20211008093043055

Java数据类型

基本数据类型

基本数据类型booleanbytecharshortIntlongfloatdouble
位数18161632643264
封装器类BooleanByteCharacterShortIntegerLongFloatDouble

引用数据类型:类、接口、数组、枚举、标注

集合

Java反射

掘金

Java在编译之后会生成一个class文件,反射通过字节码文件找到其类中的方法和属性等。

获取Class对象的方式

  • Class.forName(“类的路径”);

  • 类名.class

  • 对象名.getClass()

  • 基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象

反射机制的优缺点

  • 优点

    • 能够运行时动态获取类的实例,提高灵活性;

    • 可与动态编译结合

  • 缺点

    • 使用反射性能较低,需要解析字节码,将内存中的对象进行解析。

    • 相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性)

反射底层

https://segmentfault.com/a/1190000039302149

Java反射底层原理以及应用_WAXXD的博客-CSDN博客

threadlocal

Java面试必问:ThreadLocal终极篇 淦! - 敖丙 - 博客园

https://segmentfault.com/a/1190000024438006

ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的。在多线程环境下,可以防止自己的变量被其它线程篡改。

Spring采用Threadlocal的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接,同时,采用这种方式可以使业务层使用事务时不需要感知并管理connection对象,通过传播级别,巧妙地管理多个事务配置之间的切换,挂起和恢复。

ThreadLocal

内存泄漏和内存溢出

【221期】面试官:谈谈内存泄漏和内存溢出的联系与区别-Java知音

【面试笔录】内存溢出和内存泄漏 - 简书

内存泄漏

内存泄漏是指程序中已动态分配的堆内存由于某种原因未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统奔溃等严重后果。

几种典型的内存泄漏:

  • 全局集合

  • 缓存

  • 类装载器

如何检测内存泄漏:

  • 对代码进行走查和分析,找出内存泄漏发生的位置

  • 使用专门的内存泄漏测试工具进行测试。

内存溢出

内存溢出指程序在申请内存时,没有足够的内存供申请者使用。

内存溢出原因:

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

  • 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

  • 代码中存在死循环或循环产生过多重复的对象实体;

  • 使用的第三方软件中的BUG;

  • 启动参数内存值设定的过小

AIO和NIO

面试官问我:如何理解BIO、NIO、AIO的区别?我差点拉胯! - 知乎

进程中的IO调用步骤大致可以分为以下四步:

  1. 进程向操作系统请求数据 ;

  2. 操作系统把外部数据加载到内核的缓冲区中;

  3. 操作系统把内核的缓冲区拷贝到进程的缓冲区 ;

  4. 进程获得数据完成自己的功能 ;

当操作系统在把外部数据放到进程缓冲区的这段时间(即上述的第二,三步),如果应用进程是挂起等待的,那么就是同步IO,反之,就是异步IO,也就是AIO 。

nio的实现方式

nio的三种实现方式:select, poll, epoll_Lucky小黄人的博客-CSDN博客

select、poll、epoll

零拷贝

零拷贝的“”是指用户态和内核态间copy数据的次数为零。零拷贝完全依赖于操作系统,不依赖Java本身。

img

传统的数据copy(文件到文件、client到server等)涉及到四次用户态和内核态切换、四次copy。四次copy中,两次在用户态和内核态间copy需要CPU参与、两次在内核态与IO设备间copy为DMA方式不需要CPU参与。零拷贝避免了用户态和内核态间的copy(共2次)、减少了两次用户态内核态间的切换,因此数据传输效率高(4、4变2、2)。

零拷贝可以提高数据传输效率,但对于需要在用户传输过程中对数据进行加工的场景(如加密)就不适合使用零拷贝。

Java NIO中的FileChannel拥有transferTotransferFrom两个方法,可直接把FileChannel中的数据拷贝到另外一个Channel

分布式和微服务的区别

  • 分布式:将一个项目拆分成了多个模块,并将这些模块分开部署。

    • 水平拆分:根据“分层”的思想进行拆分。将一个项目根据“架构”拆分成多个层,再分开部署。

      img

    • 垂直拆分:根据业务进行拆分。拆分后的项目,仍然可以作为独立的项目使用。

      img

  • 微服务:一种非常细粒度的垂直拆分。

    preview

网络

HTTP 1.0/1.1

HTTP1.0、HTTP1.1与HTTPS_bian_qing_quan11的博客-CSDN博客

HTTP是客户端和服务器端之间数据传输的格式规范,格式简称为“超文本传输协议”。是一个应用层协议,基于TCP/IP通信协议。

① HTTP是无连接的:无连接的含义是限制每次连接只能处理一个请求,服务器处理完客户端的请求并收到回复之后立刻断开。(节省传输时间) ​ ② HTTP是媒体独立的:只要客户端和服务端知道如何处理数据内容,任何类型的数据都可以通过HTTP发送; ​ ③ HTTP是无状态协议:无状态协议指协议对事务处理没有记忆能力。

HTTP1.0HTTP1.1
请求方法GET、POST、HEADGET、POST、HEAD、PUT、DELETE、OPTIONS、CONNECT、TRACE
TCP连接短连接长连接
请求流水线不支持支持
Host字段不支持支持
100响应码不支持支持

HTTP2.0:

  • 在应用层和传输层之间增加了一个二进制分帧层,改进了传输性能。

  • 每一个request都使用了连接共享机制,接收方通过request的id划分到不同服务端请求。

  • 通过encoder表,减少了每次传输的header中的信息。

HTTP长连接

一次TCP连接可以传输多次request,而不需要每个request建立一次TCP连接。

HTTP1.0默认关闭,需要在头信息中加入Connection: Keep-Alive来开启。

HTTP1.1默认是开启状态,可以使用Connection: close来关闭。

长连接可以避免连接建立和释放的开销。但长时间的Tcp连接容易导致系统资源无效占用,浪费系统资源。

长连接有一个保活时间,一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接。

TCP的Keep-Alive:用于每隔一段时间发送一个侦测包,以判断对方是否在线。与HTTP的Keep-Alive不一样。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

HTTP长连接实现原理

掘金

HTTP协议本质是OSI七层参考模型中的应用层协议,而网络进行通信的时候都是通过上层协议封装头部后作为下层协议的数据部分进行封装的,而实际中我们经常接触的是TCP/IP协议簇,也就是传输层利用TCP协议和网络层利用IP协议。因此HTTP协议的长连接本质上就是TCP的长连接

http、websocket、socket

面试题之---http,websocket和socket详解 - 程序员大本营

http:

http是单向非持久连接的协议。服务端只有在客户端发起请求时才能发送数据。

WebSocket:

WebSocket是基于TCP应用层双向通信持久化协议。协议标识符是wswss。在建立握手时,通过 HTTP/1.1 协议的101协议切换状态码进行握手。但是建立之后,在真正传输时候是不需要HTTP协议的,而是使用TCP协议。可以主动向客户端发送信息。

Websocket使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。

Socket:

Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层传输层之间的一组接口

在程序内部提供了与外界通信的端口,也就是端口通信。它通过建立socket连接,可以为通信双方的数据传输提供一个通道。

Socket有udp的scoket和tcp的socket,一般采用的是tcp的socket。

浏览器输入URL后

1、域名解析:浏览器自身DNS缓存 -> PC自身的DNS缓存 -> host文件 -> 本地域名服务器 -> 根域名服务器。

2、TCP3次握手建立连接。

3、发起HTTP请求。

4、服务端响应HTTP请求,浏览器得到请求的内容。

5、浏览器解析HTML代码,并请求需要的资源。

6、浏览器对页面进行渲染,展现给用户。

TCP、UDP

一文搞定 UDP 和 TCP 高频面试题!

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。UDP是一种无连接的、不可靠的、基于报文的传输层通信协议。

TCP的可靠通信是通过3次握手4次挥手、流量控制、拥塞控制、确认应答标志、错误重传等机制保证的,因此也会造成实时性较差,开销比较大,适用于可靠性要求高的场合,如文件传输。而UDP不保证可靠通信,因此开销小,适用于实时性要求不高的场合,如视频通话、网络游戏。

另外,TCP只能点对点通信,而UDP支持多对多通信。

沾包与拆包

UDP 是基于报文发送的,UDP首部采用了 16bit 来指示 UDP 数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。

而 TCP 是基于字节流的,在 TCP 的首部没有表示数据长度的字段。当发送数据超过TCP最大长度时,就会发生拆包;当发送数据不足 时,会先存在缓冲区内,就会发生沾包。

对于UDP协议来说,整个包的最大长度为65535-IP头20-UDP头8

对于TCP协议来说,整个包的最大长度是由最大传输大小(MSS)决定,MSS就是TCP数据包每次能够传输的最大数据分段。往往MSS为1460(1500-IP头20-TCP头20)。

RPC和HTTP和Feign

RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方法。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。

RPC 和 HTTP 调用是没有经过中间件的,它们是端到端系统的直接数据交互。

主流的RPC框架有:dubbo、dubbox、motan

img

Feign是微服务中最常见的PRC框架,Feign封装了负载均衡Ribbon和服务熔断保护Hystrix,底层用的是RestTemplate,也就是HTTP的形式进行的远程调用,所以也称“伪HTTP客户端”。它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。

HTTPRPC
传输协议HTTPTCP或HTTP2
传输效率1.1版本体积大,2版本较小处理后报文体积小
性能消耗大部分通过json,消耗大基于thrift实现高效二进制传输
负载均衡需搭配Nginx自带
使用场景对外的异构环境公司内部的服务调⽤

MySQL

表连接方式

  • 交叉连接cross join,不能跟where和on

  • 内连接inner join,可以跟where和on

  • 左连接left join

  • 右连接right join

  • 全连接full join

  • 联合查询union/union all,条件是两个表的字段个数都是相同的

索引失效

面试题: MySQL 索引失效的10大原因 - 维宇空灵 - 博客园

  • 数学运算、函数、类型转换等,会导致索引失效而转向全表扫描

  • 在使用不等号(!=或<>)时候,无法使用索引导致全表扫描

  • is null,is not null也无法使用索引

  • 以 % 开头的 like 查询,会导致全表扫描的操作

  • 条件中有 or 时,即使其中有部分条件是索引字段,也不会使用索引

索引优化

面试必备的索引优化 - 简书

mysql索引优化面试题 - hephec - 博客园

  • 较频繁作为查询条件的字段才去创建索引

  • 更新频繁字段不适合创建索引

  • 使用短索引

  • 尽量的扩展索引,不要新建索引

  • 对于定义为text、image和bit的数据类型的列不要建立索引

  • 不要在列上进行运算

  • 索引不会包含有NULL值的列

Redis

数据结构

String:字符串类型,可用于缓存、共享session

List:列表类型,可用于消息队列、文章、任务列表

Set:无序集合类型,可用于好友、标签

SortedSet:有序集合类型,可用于排行榜

Hash:哈希表类型,可用于映射管理操作

img

缓存一致性

面试官:怎么保证缓存和数据库一致性?-技术圈

缓存雪崩、缓存穿透、缓存击穿

  • 缓存穿透

    • 现象描述:缓存和数据库中都没有的数据,而用户不断发起请求,每次都从数据库中去取,导致数据库压力过大。

    • 解决方法:从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

  • 缓存击穿

    • 现象描述:并发查同一条数据,缓存中没有但数据库中有(一般是缓存时间到期),引起数据库压力瞬间增大,造成过大压力。

    • 解决方法:设置热点数据永远不过期。加互斥锁。

  • 缓存雪崩

    • 现象描述:缓存中不同数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。

    • 解决方法:设置热点数据永远不过期。缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

数据结构

红黑树

掘金

红黑树是一种自平衡的二叉搜索树

“二叉搜索树”的特点是任何一个结点的值都大于其左子树的所有结点的值,任何一个结点的值都小于其右子树的所有结点的值。

“平衡”就是当结点数量固定时,左右子树的高度越接近,这棵二叉树越平衡(高度越低)。而最理想的平衡就是完全二叉树/满二叉树,高度最小的二叉树。

二叉树在特殊情况下会退化为链表。

B树是一种平衡多路搜索树

其他

如何看待测试工作

面试题记录-- 对于软件测试的理解,测试的核心,测试策略_bingolina的博客-CSDN博客_对测试的理解 面试

测试的主要目的是保证质量,同时现在的软件测试也讲究质量和速度。测试在需求分析阶段就应该介入,把设计上的缺陷,或产品经理、开发、测试间理解不一致的问题都找出来,并达成一致,预防由于理解不一致导致的不必要的缺陷的发生。测试人员必须要深入理解业务。

怎么写测试用例

① 首先是根据产品的需求提炼出测试点,然后根据测试点扩展写成测试用例,像等价类、边界值这种方法在设计测试用例的过程中我就会潜移默化的用到了。 ​ ② 另外写测试用例的时候,会考虑到正例和反例,事实上在写测试点的阶段我就会把正例和反例标记出来了,以及他们的优先级。(理论上来说反例的优先级都是三级,在回归测试的是理论上是可以不做反例的回归测试的→看情况说)我觉得这样其实对后续的工作是一个很大的减负。 ​ ③ 我觉得测试用例设计工作应该有个准出标准,避免陷入测试用例感觉写不完的漩涡。(比如一个注册页面,10几个空,排列组合,都写不完)。所以在整个测试用例设计过程中, 我们要考虑出所有的用户场景(也就是说,当用户的场景都被想全了,就准出了)

测试流程

->需求确定(出一份确定的需求文档) ->开发设计文档(开发人员在开始写代码前就能输出设计文档) ->想好测试策略,写出测试用例 ->发给开发人员和测试经理看看(非正式的评审用例) ->接到测试版本 ->执行测试用例(中间可能会补充用例) ->提交bug(有些bug需要开发人员的确定(严重级别的,或突然发现的在测试用例范围之外的,难以重现的),有些可以直接录制进TD) ->开发人员修改(可以在测试过程中快速的修改) ->回归测试(可能又会发现新问题,再按流程开始跑)。

  • 5
    点赞
  • 31
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:像素格子 设计师:CSDN官方博客 返回首页
评论

打赏作者

小锋学长生活大爆炸

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值