JAVA知识点点以及内容-设计JAVA、Redis、Spirng、Spring Cloud、MyBatis、kafka、Docker
考试考点以及内容
- 1、搭建Java环境,Number,Character,StringBuffer类,正则表达式,Scanner类,序列化,Java命令,Java语言特性
- 关于java线程的一些方法,都在这里
- 运算符,面向对象,捕捉处理异常,基础语法,类与对象,基本数据类型,变量与常量,switch-case,方法,继承,抽象类,封装,枚举,类包,ArrayList,Set集合,Map集合,Object类,线程实现方式,代码注释与编码规范,session+token+JWT,限流,函数编程,项目构建,内部类
- 命令,Redis键(Key),Redis字符串(String)
- Redis列表(List),Redis集合(Set),Redis有序集合(sorted Set),Redis连接,Redis 哈希(Hash)
- 面向切面编程,数据源配置,Bean的定义,Bean的生命周期,Bean的装配方式
- 微服务架构,Spring Cloud,与单体系统的区别,服务治理-概述,断路器-概述,声明式服务调用-概述,API网关服务-概述,分布式配置中心-概述,消息总线-概述,分布式访问跟踪-概述,负载均衡-概述,消息队列-概述,任务调度-概述,安全-概述,构建与部署-概述
- 传统的JDBC模型与ORM模型,生命周期,别名,插件,environments环境配置
- 里氏替换原则 LSP,接口隔离原则 ISP,依赖倒置原则 DIP
- mysql 表设计,缓存表与汇总表,表修改,查询基础语法,视图,游标,字符集,集群配置复制,可扩展实现方案,备份和恢复,InnoDB 存储引擎,MyISAM 存储引擎
- kafka配置,生产者,消费者
- Docker软件目标,容器与虚拟化,内核隔离机制,内核命名空间,文件系统,docker架构,运行时,daemon,命令行,源码-容器,源码结构
- Docker基本使用,服务启停,image,容器,生态,安全,监控集装箱应用,docker swarm
1、搭建Java环境,Number,Character,StringBuffer类,正则表达式,Scanner类,序列化,Java命令,Java语言特性
Java Number类, Character类,String类
https://www.cnblogs.com/hehe199316/p/14084299.html
1. Number类
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类Number的子类。
2、Character类
通常,当处理字符时,使用原始数据类型char。但是在开发过程中,经常遇到的是需要使用对象而不是原始数据类型的情况。 为了实现这一点,Java为原始数据类型char提供了包装类Character
。
Character ch = new Character('a');
3. StringBuffer类
当对字符串进行修改的时候,需要使用StringBuffer和StringBuilder类。
StringBuilder类在Java 5中被提出,它和StringBuffer之间的最大不同在于StringBuilder的方法不是线程安全的(不能同步访问)。
java 中的Number类 Character类 String类 StringBuffer类 StringBuilder类
正则表达式
匹配规则:
java正则表达式
Java 基础进阶篇(十八):正则表达式匹配规则和应用
Scanner类
(1)该类主要用来从键盘输入数据,即用户可以使用键盘进行灵活地输入。其中,Scanner类是在java.util包中定义的。
(2)示例:Scanner类的应用
二.对象序列化与反序列化
(1)序列化和反序列化的概念
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
1) 对象持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 网络传输对象:在网络上传送对象的字节序列。可以通过序列化把主机A进程上的对象序列化为二进制序列,传输到主机B上的进程从序列中重构出该对象。
初始Java26(scanner类,序列化和反序列化)
关于java线程的一些方法,都在这里
运算符,面向对象,捕捉处理异常,基础语法,类与对象,基本数据类型,变量与常量,switch-case,方法,继承,抽象类,封装,枚举,类包,ArrayList,Set集合,Map集合,Object类,线程实现方式,代码注释与编码规范,session+token+JWT,限流,函数编程,项目构建,内部类
命令,Redis键(Key),Redis字符串(String)
Redis列表(List),Redis集合(Set),Redis有序集合(sorted Set),Redis连接,Redis 哈希(Hash)
List,为有序列表,列表(List)的底层实现就是链表。
Hash
3.1、使用场景
存储结构化数据:
Hash类似 Map,一般可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)缓存在 Redis 里,然后每次读写缓存的时候,可以就操作 Hash 里的某个字段。
但是因为现在很多对象都是比较复杂的,比如你的商品对象可能里面就包含了很多属性,其中也有对象,不适宜用hash
底层结构(字典)
Set 是无序集合,会自动去重。Set底层使用了intset和hashtable两种数据结构存储的,intset我们可以理解为数组,hashtable就是普通的哈希表。
Sorted set 是排序的 Set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序。底层结构(跳跃表skiplist)
面向切面编程,数据源配置,Bean的定义,Bean的生命周期,Bean的装配方式
AOP通知类型:
@Around:环绕通知。最灵活的通知方式,必须掌握的方式
@Before:前置通知。通知方法在 目标方法执行之前 先执行
@AfterReturning:返回通知。通知方法在 目标方法正常执行之后 再执行
@AfterThrowing:异常通知。通知方法在 目标方法抛出异常之后 再执行
@After:最终通知/后置通知。通知方法在 目标方法执行之后 一定会执行,无论是否有异常
Spring:面向切面编程(AOP)很全面的一个,但是有点冗余,有点多
- Bean的定义
Bean 是由 Spring IoC 容器创建、管理、装配、生命周期控制的对象。每个 Bean 可以是任何 Java 类,只要它被 Spring 容器所管理。通常,通过注解、XML 配置或 Java 配置类来声明 Bean。
定义方式:
基于注解的定义:使用 @Component、@Service、@Repository 或 @Controller 注解来定义一个 Bean。
- Bean的生命周期
Bean 的生命周期可以概括为以下几个主要阶段:
-
实例化:Spring 容器根据配置文件或注解创建 Bean 实例。
-
依赖注入:在 Bean 实例化之后,容器会进行依赖注入(DI),即把需要的依赖(如其他 Bean)注入到当前 Bean 中。
-
初始化:如果 Bean 实现了 InitializingBean 接口,afterPropertiesSet() 方法会被调用。
如果在配置中指定了初始化方法(通过 @PostConstruct 或 init-method),则会调用该方法。
使用阶段:Bean 被容器管理并可以被其他 Bean 使用。 -
销毁:如果 Bean 实现了 `DisposableBean
spring生命周期七个过程_面试官:请你讲解一下Spring Bean的生命周期
对里面的Aware 不是特别清楚
Bean的定义:Spring容器管理的对象。
Bean的生命周期:实例化、依赖注入、初始化、使用、销毁。
Bean的装配方式:包括XML配置、注解方式、Java配置等,主要是通过@Component、@Autowired、@Bean等注解来实现自动装配。
微服务架构,Spring Cloud,与单体系统的区别,服务治理-概述,断路器-概述,声明式服务调用-概述,API网关服务-概述,分布式配置中心-概述,消息总线-概述,分布式访问跟踪-概述,负载均衡-概述,消息队列-概述,任务调度-概述,安全-概述,构建与部署-概述
微服务架构概述:
微服务架构(Microservices Architecture)是一种将单一应用程序拆分成多个小型、独立部署的服务的架构模式。每个微服务负责系统中的某个具体功能或业务领域,并通过轻量级的通信协议(如HTTP REST、消息队列)与其他服务进行交互。微服务具有松耦合、独立部署、可扩展性和容错性等优点。
Spring Cloud概述:
Spring Cloud 是一组用于构建微服务架构的工具和框架,它为开发者提供了一些常用的组件来解决微服务架构中的一些挑战,比如服务注册与发现、配置管理、断路器、负载均衡等。Spring Cloud 基于Spring Boot,能够使开发者更高效地构建、部署和维护微服务系统。
微服务与单体系统的区别:
- 单体系统:所有功能模块在同一个代码库和部署单元中,通常是一个大型的应用程序。它们共享同一个数据库,并且紧密耦合,难以扩展和维护。
- 微服务架构:将系统拆分为多个独立的小服务,每个服务实现特定的业务功能并独立部署。服务之间通过网络进行通信,服务之间松耦合,易于扩展和独立维护。
区别:
- 模块化:单体应用为一个整体,微服务是多个独立服务。
- 扩展性:微服务可以独立扩展,而单体应用只能整体扩展。
- 开发部署:微服务可以独立部署和更新,单体应用通常需要整体部署。
- 容错性:微服务架构提供更好的容错性和高可用性。
服务治理 - 概述:
服务治理是指对分布式系统中的服务进行有效的管理和协调,确保系统中多个微服务之间能够高效、安全、稳定地交互。服务治理包括服务发现、负载均衡、断路器、服务监控等。
断路器 - 概述:
断路器(Circuit Breaker)是微服务架构中的一种模式,旨在防止故障蔓延。当某个服务或服务的某一部分不可用时,断路器会快速失败而不是继续请求该服务,从而保护系统的其他部分不受到影响。常见的断路器框架包括Spring Cloud中的Hystrix。
工作原理:
- 闭合状态:请求正常转发,服务调用正常。
- 打开状态:断路器打开,拒绝对故障服务的所有请求,返回默认值或错误信息。
- 半开状态:尝试发送请求到服务,若服务恢复正常则闭合断路器,否则继续打开。
声明式服务调用 - 概述:
声明式服务调用(Declarative Service Invocation)是通过注解或配置来声明服务调用的方式,无需手动编写调用逻辑。Spring Cloud提供了@FeignClient
注解,它可以帮助开发者在客户端通过声明式的方式访问远程服务,而无需编写复杂的HTTP请求代码。
特性:
- 利用Feign客户端来声明服务接口和目标服务。
- 通过注解简化远程调用代码,避免手动编写HTTP请求。
- 集成了负载均衡、熔断等功能。
API网关服务 - 概述:
API网关是微服务架构中的一个重要组件,用于管理所有客户端与微服务之间的请求。API网关负责请求路由、负载均衡、认证、限流、监控等功能。常见的API网关实现包括Spring Cloud Gateway和Zuul。
特性:
- 提供单一的入口点,客户端通过API网关访问系统。
- 支持请求路由和负载均衡。
- 提供身份验证、授权、安全控制等功能。
分布式配置中心 - 概述:
分布式配置中心(Distributed Configuration Center)是一个用于集中管理微服务配置的组件。在微服务架构中,每个服务可能有不同的配置需求,而分布式配置中心可以集中管理这些配置,避免硬编码配置,并支持动态配置更新。Spring Cloud Config是一个流行的配置中心实现。
特性:
- 集中管理所有微服务的配置。
- 支持配置的动态刷新。
- 提供配置版本控制和安全性管理。
消息总线 - 概述:
消息总线(Message Bus)是一种用于微服务间通信的机制,支持服务之间的异步消息传递。Spring Cloud Bus基于消息中间件(如RabbitMQ、Kafka等),使得微服务能够进行广播、事件发布、通知等功能。
特性:
- 提供异步、松耦合的消息通信机制。
- 支持服务间的事件传递和通知。
- 集成消息中间件实现异步通信。
分布式访问跟踪 - 概述:
分布式访问跟踪(Distributed Tracing)是指追踪请求在微服务之间的流转路径,帮助开发者分析和排查性能瓶颈、故障点等。常见的分布式追踪工具包括Zipkin和Sleuth。
特性:
- 实时追踪请求的流转路径。
- 帮助定位系统中的性能瓶颈和故障。
- 支持对分布式系统的全局监控。
负载均衡 - 概述:
负载均衡是指将请求均匀分配到多个服务实例上,确保服务的高可用性和性能。Spring Cloud支持通过Ribbon和Spring Cloud LoadBalancer来实现客户端负载均衡。
特性:
- 分发请求到多个服务实例,避免单个实例过载。
- 支持多种负载均衡策略,如轮询、加权、随机等。
消息队列 - 概述:
消息队列(Message Queue)是用于异步处理任务、解耦和提升系统可靠性的组件。常见的消息队列有RabbitMQ、Kafka、ActiveMQ等。微服务架构中,消息队列用于解耦微服务、提高系统的吞吐量和可靠性。
特性:
- 提供异步消息处理机制。
- 解耦生产者和消费者。
- 支持消息持久化和高可靠性。
任务调度 - 概述:
任务调度是指定期或按需执行某些后台任务的机制。Spring Cloud中的任务调度可以使用Quartz或Spring Task进行配置。微服务架构中,任务调度用于处理定时任务、延迟任务等。
特性:
- 支持定时任务的调度和管理。
- 集成Quartz或Spring Task进行任务的执行。
安全 - 概述:
安全在微服务架构中非常重要,尤其是服务间的认证、授权和数据保护。Spring Cloud Security提供了多种安全机制,如OAuth2、JWT、SSO等,来确保微服务的安全性。
特性:
- 提供服务间的认证与授权机制。
- 支持基于OAuth2和JWT的安全认证。
- 集成SSO(单点登录)实现集中身份验证。
构建与部署 - 概述:
构建与部署是微服务架构中的核心部分,需要支持快速的持续集成和持续部署(CI/CD)。Spring Cloud与Docker、Kubernetes等工具集成,能够支持容器化部署、自动化构建和发布。
特性:
- 支持Docker容器化部署。
- 与Kubernetes集成,实现自动化部署和扩展。
- 支持CI/CD流水线进行自动化构建和测试。
总结:
- 微服务架构相比传统的单体应用,具备更高的灵活性、可扩展性和容错性。
- Spring Cloud为微服务架构提供了一整套解决方案,涵盖了服务发现、负载均衡、配置管理、服务调用等多个方面。
- 通过以上各个组件的结合,微服务架构可以高效、可靠地运行,并且易于扩展和维护。
传统的JDBC模型与ORM模型,生命周期,别名,插件,environments环境配置
传统的JDBC模型与ORM模型
在Java开发中,JDBC(Java Database Connectivity)和ORM(Object-Relational Mapping)是两种常见的数据持久化方式。它们有着不同的编程模型和管理数据库交互的方式。
1. 传统的JDBC模型:
- 手动管理连接:开发者需要通过
DriverManager
或DataSource
管理数据库连接。 - 手动编写SQL语句:所有的SQL查询、插入、更新、删除等操作都需要手动编写SQL。
- 手动映射结果:查询数据库的结果需要通过
ResultSet
来手动映射到Java对象。 - 事务管理:开发者需要手动处理事务的开启、提交和回滚。
优缺点:
- 优点:灵活、精确控制数据库操作,适用于复杂的查询和操作。
- 缺点:代码量大,容易出错,维护性差,开发效率低。
2. ORM模型:
ORM是一种通过对象映射技术将数据库中的数据表与程序中的对象(实体类)进行映射的方法。ORM框架(如Hibernate、MyBatis等)自动处理SQL生成和执行,简化了开发过程。
ORM模型的特点如下:
- 自动映射:开发者只需要关注Java类和数据库表之间的映射关系,ORM框架自动处理数据库操作。
- 减少SQL代码:ORM框架通过Java对象操作,自动生成SQL语句,开发者无需编写大量SQL。
- 事务管理:ORM框架通常内置事务管理,简化了事务处理。
优缺点:
- 优点:提高开发效率,减少冗余代码,增强代码的可维护性,支持更高层次的抽象。
- 缺点:对于复杂查询性能较差,灵活性较低(ORM框架往往会生成一些笨重的SQL),可能不适合对性能有高要求的场景。
MyBatis生命周期:
MyBatis是一个流行的ORM框架,它是半自动化的ORM框架。MyBatis的生命周期通常涉及以下几个阶段:
-
初始化阶段:
SqlSessionFactory
的创建:通过SqlSessionFactoryBuilder
根据配置文件(如mybatis-config.xml
)构建SqlSessionFactory
。SqlSession
的创建:从SqlSessionFactory
创建SqlSession
实例,SqlSession
负责执行SQL操作。
-
执行阶段:
- 执行Mapper接口中的方法,MyBatis会根据方法名称和SQL映射文件中的SQL语句进行匹配。
- MyBatis将自动执行相应的SQL语句,并将查询结果映射到相应的Java对象。
-
提交/关闭阶段:
- 如果使用了事务,执行完成后需要手动提交事务(
sqlSession.commit()
)。 - 在操作完成后,应关闭
SqlSession
(sqlSession.close()
)来释放资源。
- 如果使用了事务,执行完成后需要手动提交事务(
MyBatis的别名:
在MyBatis中,别名是指将Java类、接口或基本类型与一个简短的名称关联起来,这样可以在映射文件中使用简短的名称而非全限定类名。别名用于提高可读性并简化配置。
别名的配置方式有两种:
-
通过
mybatis-config.xml
文件配置:可以在mybatis-config.xml
文件中配置全局别名。<typeAliases> <typeAlias alias="User" type="com.example.User"/> </typeAliases>
这将允许在映射文件中使用
User
而不是com.example.User
。 -
通过Mapper接口和XML文件自动识别:MyBatis可以自动识别Mapper接口中的类作为别名。
2. 别名的作用和范围
在MyBatis中,别名是为了简化和统一对类型的引用,通常是对类的引用(例如<typeAliases>
)。但在<resultMap>
中,column
和property
的作用其实是字段和属性的映射,它们不是“别名”概念的实现,而是数据库列和Java属性之间的映射关系。
column
和property
的作用:
column
:数据库表的列名。property
:Java对象的属性名。
这种映射关系让MyBatis能够根据查询结果(column
)自动将数据填充到Java对象的相应属性(property
)中。它不涉及对类的别名,而是具体到某个查询的字段映射。
3. typeAliases
与column/property
的区别
-
typeAliases
定义了类的别名,是为了简化类名的引用。通常用于在映射文件中引用类时,使用简短的别名来代替类的全限定名(如com.example.User
)。例如:
<typeAlias alias="User" type="com.example.model.User"/>
-
column
和property
是用来做字段与属性的映射关系,它们并不代表别名,只是指定数据库表字段与Java对象属性之间的对应关系。例如:
<resultMap id="BaseResultMap" type="com.example.model.User"> <id column="user_id" property="id" /> <result column="user_name" property="name" /> </resultMap>
在这个例子中,
column="user_id"
和property="id"
指明了user_id
列映射到User
类中的id
属性,column="user_name"
映射到name
属性。
总结:
column
和property
用于定义数据库字段和Java对象属性之间的映射关系,而不是类的别名。typeAliases
用于定义Java类的别名,简化类名的引用,常用于类的全限定名(如com.example.model.User
)和映射文件中的简写(如User
)之间的映射。
所以,虽然它们都涉及到“映射”这一概念,但<resultMap>
中的column
和property
与typeAliases
的用途和作用是不同的,前者是字段到属性的映射,后者是类名的简化。
MyBatis的插件:
MyBatis支持插件机制,允许开发者在SQL执行的过程中加入自定义逻辑,提供一个可以拦截MyBatis操作的方式。MyBatis插件可以在执行SQL前、执行SQL后,或者执行过程中进行拦截。
插件的使用步骤:
- 实现
Interceptor
接口。 - 配置插件到
mybatis-config.xml
文件。 - 插件拦截器方法会被调用,开发者可以在方法中加入自定义逻辑。
例如:
<plugins>
<plugin interceptor="com.example.MyInterceptor"/>
</plugins>
总结:
- 传统JDBC模型:低级别的数据库操作,灵活但繁琐。
- ORM模型:自动将Java对象与数据库表进行映射,简化数据访问操作,提高开发效率。
- MyBatis生命周期:包括初始化、执行和关闭,具有灵活性,支持自定义SQL。
- 别名:简化映射文件中的类名引用,提高可读性。
- 插件:提供对MyBatis操作的扩展和拦截,增强功能。
environments
配置:支持根据不同的环境配置不同的数据源和事务管理器。
里氏替换原则 LSP,接口隔离原则 ISP,依赖倒置原则 DIP
里氏替换原则 (LSP):
里氏替换原则(Liskov Substitution Principle)是面向对象设计中的一个重要原则,旨在确保继承关系中的子类能够完全替代父类。该原则由Barbara Liskov在1987年提出,强调子类对象可以替换父类对象,并且程序的功能不会受到影响。
定义:
如果程序中的一个对象(类)可以被其子类的对象替换,而不影响程序的正确性,那么子类就是父类的良好替代品,这就遵循了里氏替换原则。
要求:
- 子类必须实现父类的所有行为:子类需要继承父类的行为,并且在不改变父类定义的行为的前提下进行扩展。
- 子类不能改变父类已有方法的语义:子类中重写的父类方法应保持原有方法的行为或至少不破坏程序的正确性。
- 子类必须遵循父类的约束:如果父类的方法在某些条件下会触发错误,子类应该避免违反这些条件,而不是引入新的错误。
举例:
class Bird {
public void fly() {
// 鸟类的飞行行为
}
}
class Sparrow extends Bird {
@Override
public void fly() {
// 麻雀的飞行行为
}
}
class Ostrich extends Bird {
@Override
public void fly() {
// 鸵鸟不能飞行,违背了里氏替换原则
throw new UnsupportedOperationException("Ostriches cannot fly!");
}
}
在上述例子中,Ostrich
继承了 Bird
类并重写了 fly()
方法,但实际上鸵鸟是不能飞的,这会导致程序在使用 Bird
类型时出现异常,违反了里氏替换原则。因此,Ostrich
应该与 Bird
设计成不同的类,避免继承关系导致的问题。
接口隔离原则 (ISP):
接口隔离原则(Interface Segregation Principle)是指一个类不应该依赖于它不需要的接口。也就是说,一个接口不应该强迫实现它的类去实现不需要的方法。ISP强调的是接口的粒度和职责划分,避免接口设计过于庞大,导致实现类需要实现很多不必要的方法。
定义:
客户端不应被迫依赖于它不需要的接口方法。如果某个接口的实现类并不需要其中的一些方法,应该将这些方法分割到不同的接口中,遵循接口隔离原则。
要求:
- 接口应当职责单一:每个接口应该有明确的责任范围,避免将无关的方法集中到一个接口中。
- 避免冗余方法:如果一个类不需要接口中的某些方法,它不应当被强制去实现。
举例:
interface Printer {
void printDocument(String doc);
void faxDocument(String doc);
}
class MultiFunctionPrinter implements Printer {
@Override
public void printDocument(String doc) {
// 打印文档
}
@Override
public void faxDocument(String doc) {
// 传真文档
}
}
class SimplePrinter implements Printer {
@Override
public void printDocument(String doc) {
// 打印文档
}
@Override
public void faxDocument(String doc) {
throw new UnsupportedOperationException("Faxing is not supported.");
}
}
在上面的例子中,SimplePrinter
实现了 Printer
接口,但它并不支持传真功能,因此在实现时抛出了异常。这违反了接口隔离原则。为了遵循ISP,应该将打印和传真功能分开成两个接口:
interface Printer {
void printDocument(String doc);
}
interface Faxer {
void faxDocument(String doc);
}
class MultiFunctionPrinter implements Printer, Faxer {
@Override
public void printDocument(String doc) {
// 打印文档
}
@Override
public void faxDocument(String doc) {
// 传真文档
}
}
class SimplePrinter implements Printer {
@Override
public void printDocument(String doc) {
// 打印文档
}
}
这样,SimplePrinter
类只需要实现它所需的接口,而不必强迫去实现不需要的 faxDocument
方法。
依赖倒置原则 (DIP):
依赖倒置原则(Dependency Inversion Principle)是面向对象设计中的一种原则,它反对高层模块依赖于低层模块的实现,应该依赖于抽象。也就是说,高层模块不应该直接依赖低层模块的具体实现,而应该依赖于接口或抽象类。具体的实现细节由低层模块提供。这个原则的目的是通过引入抽象层来减少模块之间的耦合,提高系统的灵活性和可维护性。
定义:
- 高层模块不应该依赖低层模块,二者都应该依赖于抽象。
- 抽象不应该依赖于细节,细节应该依赖于抽象。
要求:
- 依赖注入:通过依赖注入的方式,将依赖关系传递到类中,而不是在类中直接创建依赖的对象。
- 减少耦合:通过接口或抽象类来隔离模块之间的依赖,避免高层模块对低层模块的直接依赖。
举例:
假设我们有一个应用需要一个报告生成器,但我们直接在高层模块中创建了低层模块的实例:
class ReportGenerator {
private EmailSender emailSender = new EmailSender();
public void generateReport() {
// 生成报告
emailSender.sendEmail("Report generated.");
}
}
class EmailSender {
public void sendEmail(String message) {
// 发送邮件
}
}
在上面的代码中,ReportGenerator
直接依赖于 EmailSender
,这使得系统很难扩展。如果我们想要替换掉 EmailSender
(例如使用短信发送),我们需要修改 ReportGenerator
类,违反了依赖倒置原则。
改进后的代码,遵循DIP:
interface MessageSender {
void sendMessage(String message);
}
class EmailSender implements MessageSender {
@Override
public void sendMessage(String message) {
// 发送邮件
}
}
class SmsSender implements MessageSender {
@Override
public void sendMessage(String message) {
// 发送短信
}
}
class ReportGenerator {
private MessageSender messageSender;
// 通过构造函数注入依赖
public ReportGenerator(MessageSender messageSender) {
this.messageSender = messageSender;
}
public void generateReport() {
// 生成报告
messageSender.sendMessage("Report generated.");
}
}
在这个改进的版本中,ReportGenerator
类不再直接依赖于 EmailSender
,而是依赖于 MessageSender
接口。具体的发送方式(例如邮件或短信)由外部注入进来,这样我们就遵循了依赖倒置原则,增加了系统的灵活性。
总结:
- Liskov Substitution Principle (LSP):子类对象能够替换父类对象,并且不改变程序的正确性。
- Interface Segregation Principle (ISP):一个类不应该依赖它不需要的接口方法,接口应该小而精。
- Dependency Inversion Principle (DIP):高层模块不应该依赖低层模块,二者都应该依赖抽象。
mysql 表设计,缓存表与汇总表,表修改,查询基础语法,视图,游标,字符集,集群配置复制,可扩展实现方案,备份和恢复,InnoDB 存储引擎,MyISAM 存储引擎
集群配置与复制
集群配置
MySQL 集群通常用于提升数据库的可用性、扩展性和容错性。常见的集群配置有:
- 主从复制(Master-Slave Replication):一种主从架构,主服务器负责写操作,从服务器负责读操作,从而分担压力。
- 双主复制(Master-Master Replication):两台主服务器互为主从,可以实现读写分离,但需要额外处理冲突。
- MySQL Group Replication:提供多主复制功能,并能实现自动故障转移。
复制配置
MySQL 复制一般有两个步骤:
- 在主服务器上配置:
- 开启二进制日志:
[mysqld] log-bin=mysql-bin server-id=1
- 开启二进制日志:
- 在从服务器上配置:
-
配置服务器ID和连接到主服务器:
[mysqld] server-id=2
-
启动从服务器复制:
CHANGE MASTER TO MASTER_HOST='master_host', MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='log-bin.000001', MASTER_LOG_POS= 154; START SLAVE;
-
可扩展实现方案
对于 MySQL 的可扩展性,通常使用以下几种方案:
- 读写分离:将数据库的写操作交给主服务器,读操作交给从服务器,从而提高读操作的并发能力。
- 分区与分表:根据数据量和查询方式,进行数据分区或分表处理,将数据分散到多个表或数据库实例中,提高查询效率和扩展性。
- 分布式数据库:如使用 MySQL 的 NDB 存储引擎,或者使用第三方的分布式数据库中间件(如 Vitess、ShardingSphere)来进行数据库水平切分。
备份与恢复
MySQL 提供了多种备份和恢复方案:
-
逻辑备份(使用
mysqldump
):- 备份:
mysqldump -u user -p database_name > backup.sql
- 恢复:
mysql -u user -p database_name < backup.sql
- 备份:
-
物理备份(直接复制数据文件):
- 停止 MySQL 服务,复制数据文件。
- 启动 MySQL 服务。
-
增量备份:通过
binary logs
(二进制日志)来备份变更数据。
InnoDB 存储引擎
InnoDB是 MySQL 的默认存储引擎,具有以下特点:
- 事务支持:支持ACID事务,提供
COMMIT
、ROLLBACK
、SAVEPOINT
等事务控制。 - 行级锁:支持行级锁,可以提高并发性能。
- 外键支持:支持外键约束,保证数据的完整性。
- 崩溃恢复:内置崩溃恢复功能,保证在系统崩溃时数据不丢失。
MyISAM 存储引擎
MyISAM是 MySQL 中的一种旧的存储引擎,主要特点包括:
- 表级锁:使用表级锁,适合读操作远多于写操作的场景,但在高并发写操作时性能较差。
- 不支持事务:MyISAM 不支持事务控制,因此不保证数据的完整性。
- 不支持外键:MyISAM 不支持外键约束。
- 性能:在读密集型的应用中,MyISAM可能比InnoDB更高效。
总结:
- 表设计要遵循规范化原则,并根据实际情况设计索引、分区等。
- 缓存表与汇总表可以优化查询性能,但需要定期维护。
- 查询语法是数据库操作的基础,视图和游标可以用来简化复杂的查询和数据处理。
- 存储引擎选择影响性能,InnoDB适合事务和并发操作,MyISAM适合读密集型场景。
kafka配置,生产者,消费者
Docker软件目标,容器与虚拟化,内核隔离机制,内核命名空间,文件系统,docker架构,运行时,daemon,命令行,源码-容器,源码结构
Docker基本使用,服务启停,image,容器,生态,安全,监控集装箱应用,docker swarm
原文地址:https://blog.csdn.net/missgrass/article/details/143849421
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!