Integer.valueOf()对比Integer.parseInt()
Java 中 Integer.valueOf() 和 Integer.parseInt() 的区别及实践在 Java 中,处理字符串与整数的转换时,Integer.valueOf() 和 Integer.parseInt() 是最常用的两个方法。
这两个方法虽然看似相似,但在实际使用中却有一些关键的区别。本文将详细讲解这两个方法的用法、内部实现及其不同之处,并结合实际示例来帮助大家更好地理解和使用。
方法定义和基本用法1. Integer.valueOf()方法定义:
12public static Integer valueOf(String s) throws NumberFormatException;public static Integer valueOf(int i);
用法:
Integer.valueOf(String s):将字符串 s 转换为 Integer 对象。
Integer.valueOf(int i):将基本数据类型 int 转换为 Integer 对象。
示例:
12Integer num1 = Integer.valueOf("123 ...
ES 文档基本操作
ES 文档基本操作添加文档模版:
12345678910POST /索引库名/_doc/文档id{ "字段1": "值1", "字段2": "值2", "字段3": { "子属性1": "值3", "子属性1": "值4" } // ......}
如果没有文档id,ES会随机生成一个
示例:
123456789POST /demo_index/_doc/1{ "demo_property_1":"test_content1_text", "demo_property_2":"test_content1_keyword", "demo_property_3":{ "demo_child_property ...
JsonNode API文档
JsonNode API 文档概述JsonNode 是 Jackson 数据绑定库中的一个类,用于表示 JSON 数据的节点。它是 com.fasterxml.jackson.databind.JsonNode 包的一部分,提供了处理 JSON 数据的灵活接口。
主要特性
支持多种类型的 JSON 数据(对象、数组、字符串、数字、布尔值和 null)。
支持树状结构的动态访问和遍历。
提供类型安全的方法访问 JSON 数据。
创建 JsonNode从 JSON 字符串创建1JsonNode jsonNode = objectMapper.readTree("{\"key\":\"value\"}");
从 Java 对象创建1JsonNode jsonNode = objectMapper.valueToTree(yourObject);
主要方法节点类型判断
boolean isObject()检查当前节点是否为 JSON 对象。
boolean isArray()检查当前节点是否为 JSON 数 ...
JsonNode详解
JsonNode 详解com.fasterxml.jackson.databind.JsonNode.JsonNode 是 Jackson 库中表示 JSON 数据结构的核心类之一,属于 com.fasterxml.jackson.databind 包。
它用于以树状结构解析和处理 JSON 数据。
JsonNode 的基本特性
树状结构:JsonNode 可以表示 JSON 的各种类型,包括对象、数组、字符串、数字、布尔值和 null。
动态访问:支持动态访问 JSON 节点的属性和元素,可以方便地进行遍历和操作。
类型安全:虽然 JsonNode 是一个通用类型,但它提供了一些方法以确保对 JSON 数据的类型安全访问。
创建 JsonNodeJsonNode 主要通过 ObjectMapper 类创建。以下是一些常用的方法:
12345678910import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.JsonNode;ObjectMapper object ...
数据库表字符编码utf8和utf8mb4
数据库表编码:UTF-8 与 UTF8MB4 的区别及选择编码概述在数据库中,字符编码定义了如何存储和处理字符串数据。UTF-8 和 UTF8MB4 是 MySQL 中常用的字符编码,具有不同的特性和适用场景。
UTF-8
定义:UTF-8 是一种可变长度字符编码,使用 1 到 4 个字节表示一个字符。
范围:支持 Unicode 字符集的绝大多数字符,但不支持某些特殊字符(如某些表情符号)。
字节限制:在 MySQL 中,UTF-8 仅使用 1 到 3 个字节存储字符。
UTF8MB4
定义:UTF8MB4 是 UTF-8 的扩展,完整支持 Unicode,包括所有字符。
范围:除了基本的多语言字符外,还支持所有的 emoji 和其他非基本字符。
字节限制:使用 1 到 4 个字节表示一个字符。
主要区别
特性
UTF-8
UTF8MB4
最大字节数
3 字节
4 字节
支持的字符范围
不支持某些 emoji
支持所有 Unicode 字符
应用场景
多数语言文本
包含特殊符号、表情符号等的文本
实战中的选择在选择字符编码时,考虑以下因素:
数据类型和内容
...
Spring事务管理的原理
Spring事务管理的原理Spring 通过 AOP 实现声明式事务的机制是其事务管理的核心部分。
声明式事务和编程式事务的实现原理不同。
声明式事务的实现原理AOP(面向切面编程)
代理模式:Spring 使用 AOP 代理模式来实现声明式事务。具体而言,当你在服务方法上使用 @Transactional 注解时,Spring 会生成一个代理对象,该对象会拦截方法调用。
切面:切面是 AOP 的核心概念,包含了切点(定义在哪些方法上应用切面)和通知(在切点方法执行前、后或异常时执行的逻辑)。在事务管理中,切面会处理事务的开启、提交和回滚。
事务通知:当目标方法被调用时,代理会执行事务的前置逻辑(例如开启事务),然后调用目标方法。执行完毕后,代理会根据方法执行的结果(正常结束或抛出异常)决定是否提交或回滚事务。
具体流程
方法调用:
当调用标注了 @Transactional 的方法时,Spring 代理会拦截该调用。
事务开始:
代理会使用配置的事务管理器开始一个新事务。
执行目标方法:
代理调用实际的业务逻辑方法。
事务结束:
根据目标方法的执行结果(正 ...
未检查的异常
未检查的异常未检查的异常(Unchecked Exception)是指在编译时不需要强制捕获或声明的异常。
在 Java 中,未检查的异常是 RuntimeException 类及其子类的实例,以及 Error 类及其子类的实例。
未检查的异常通常表示程序中的逻辑错误或不应当发生的情况。
主要特点
不需要显式处理:编译器不会强制要求在代码中捕获或声明这些异常。开发者可以选择处理这些异常,也可以不处理。
程序逻辑错误:未检查的异常通常表示程序内部的逻辑错误,例如访问数组的非法索引、空指针引用等。它们通常表示错误的程序设计。
运行时异常:未检查的异常通常在程序运行时发生,而不是在编译时。例如:
NullPointerException
ArrayIndexOutOfBoundsException
ClassCastException
事务管理中的应用在 Spring 中,默认情况下,只有未检查的异常(如 RuntimeException)会导致事务回滚。这意味着:
如果方法执行中抛出未检查的异常,Spring 会自动回滚当前事务。
如果方法执行中抛出已检查的异常(如 IOEx ...
\@Value注解缺省值的细节
@Value缺省值的细节使用 @Value 注解时,缺省值的一些细节包括:
格式:在 .properties 文件中,缺省值不需要用单引号包裹;在 YAML 文件中,可以使用单引号。
占位符:可以使用 ${} 来引用其他属性。
默认值语法:可以通过 :${defaultValue} 指定缺省值,例如:${some.property:defaultValue}。
类型转换:Spring 会自动根据目标字段类型进行类型转换。
异常处理:如果没有找到值且没有提供缺省值,可能会抛出异常。
gate.io
事务传播的概念概述
事务传播是指在执行数据库操作时,如何处理当前事务与外部事务之间的关系。
在多层架构或分布式系统中,事务传播机制可以确保数据的一致性和完整性。
Spring 框架提供了多种事务传播行为,帮助开发者灵活管理事务。
事务传播的意义
数据一致性:确保在不同的数据库操作中,数据的一致性得以保持,避免因事务未提交或回滚而导致的数据不一致。
灵活性:允许在不同的业务逻辑层次中定义事务的行为,以便在需要的情况下开启或使用现有的事务。
错误处理:在出现异常时,能够决定是回滚当前事务还是让外部事务负责,从而简化错误处理逻辑。
Spring 中的事务传播行为Spring 提供了七种事务传播行为,分别是:
REQUIRED(默认行为):
如果当前存在事务,则加入该事务;如果不存在事务,则新建一个事务。
适用于大多数场景。
REQUIRES_NEW:
总是新建一个事务,即使当前存在事务也会暂停当前事务。
适用于需要独立事务的场景,如日志记录或审计功能。
NESTED:
如果当前存在事务,则在该事务中嵌套一个事务;如果不存在事务,则新建一个事务。
适用于需要部分 ...
\@ConditionalOnProperty 详解
@ConditionalOnProperty 注解详解概述@ConditionalOnProperty 是 Spring Boot 提供的一个条件注解,用于根据特定的属性值来决定是否加载某个 Spring Bean。
它使得 Bean 的创建变得更加灵活,允许开发者根据配置的不同来控制 Bean 的注册。
作用
灵活配置:可以根据不同的环境或配置条件,选择性地启用或禁用某个 Bean。
提高模块化:使得应用程序能够更好地适应不同的需求,避免了在代码中硬编码条件逻辑。
使用方法基本用法使用 @ConditionalOnProperty 注解时,可以指定以下几个属性:
**value/name**:要检查的属性名(必须是一个属性)。
**havingValue**:当属性值匹配时,条件成立,默认为 true。
**matchIfMissing**:如果指定的属性不存在,是否匹配,默认为 false。
示例假设我们有一个服务类 MyService,我们希望根据配置文件中的属性 app.service.enabled 来决定是否注册该 Bean。
1. 配置文件
在 appli ...
\@ConfigurationProperties 详解
@ConfigurationProperties 注解详解概述@ConfigurationProperties 是 Spring Framework 提供的一个注解,用于将外部配置(如 YAML 或 properties 文件)绑定到 Java 对象。
它主要用于集中管理应用程序的配置,简化了配置项的读取和使用。
作用
简化配置管理:将多个相关的配置项聚合到一个类中,便于管理和使用。
类型安全:通过强类型的 Java 对象来获取配置,避免了使用字符串常量,减少了出错的可能性。
便于测试:将配置与业务逻辑分离,使得测试变得更加简单。
使用方法添加依赖确保在 pom.xml 中添加 Spring Boot Starter:
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId></dependency>
创建配置类创建一个类并使用 @Configur ...
为什么Servlet规范规定了只能调用一次getReader方法
为什么一个 Servlet 只能调用一次 getReader() 方法在 Java EE 的 Servlet 规范中,HttpServletRequest 接口的 getReader() 方法用于获取请求体的字符输入流。
然而,一个 Servlet 只能调用一次 getReader() 方法,原因如下:
输入流的单次消费特性
流的性质:输入流(如 BufferedReader)的设计目的是一次性读取数据。读取操作会消耗流中的数据,改变流的状态。调用 getReader() 后,请求体的内容被读取,后续的读取请求会发现流已被关闭或数据已被消费。
设计决策:这种设计确保了输入流的简单性和高效性,避免了复杂的状态管理。它使得开发者在处理请求体时,不必担心流的状态管理和重置。
资源管理
内存和性能:请求体可能很大,尤其在上传文件或大文本数据时。允许多次读取将导致额外的内存开销和性能损失,可能会导致应用程序崩溃或响应缓慢。
避免泄漏:如果允许多个读取,开发者需要显式管理流的生命周期,增加了出错的可能性,如未能正确关闭流,导致内存泄漏。
保持请求的一致性
数据一致性:如果允许多次读取同一请求体 ...
gate.io
OOD五大原则SOLID总览SOLID 是面向对象设计的五大基本原则的首字母缩写,旨在帮助开发者编写更清晰、灵活和易于维护的代码。
它们有助于设计可扩展和可维护的系统,特别是在复杂的项目中应用非常广泛。
详解介绍见链接:
SOLID
LINK
SRP
单一职责原则
OCP
开放封闭原则
LSP
里氏替换原则
ISP
接口隔离原则
DIP
依赖倒置原则
以下是五大 SOLID 原则的简单介绍:
1. 单一职责原则 (Single Responsibility Principle, SRP)定义:每个类应该只有一个职责,即只做一件事。简单来说,一个类应该只有一个引起其变化的原因。
目的:
降低类的复杂度。
提高类的可读性和可维护性。
使代码更容易修改,减少因为一个改动影响到不相关的功能。
示例:12345678910111213141516171819class User { private String name; private String email; // 只处理用户信息 public void updateN ...
接口隔离原则ISP
接口隔离原则 (Interface Segregation Principle, ISP)ISP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义接口隔离原则(Interface Segregation Principle, ISP)规定:客户端不应该被强迫依赖它们不需要的接口。
也就是说,一个接口不应包含过多与客户端无关的方法,而应该根据不同的功能需求,将接口细化为多个具体的接口,以避免冗余和依赖过多不必要的方法。
在设计接口时,ISP 提倡将大而全的接口拆分成多个小而精的接口,每个接口只服务于特定的子功能。
这样,类只会实现自己需要的接口,避免了依赖不必要的接口或方法,从而减少耦合性。
为什么需要接口隔离原则?
减少类与接口的耦合:如果类实现了不相关的方法,会引入不必要的依赖,使代码变得复杂且难以维护。
提高灵活性:细化的接口使类可以根据需要实现相关功能,不受其他不相关功能的影响。
提高系统可维护性:接口更精细、更清晰,使得代码的理解和维护变得更容易。
减少冗余:避免了一个类不得不实现与自己无关的功能,简化了类 ...
开放封闭原则OCP
开放封闭原则 (Open-Closed Principle, OCP)DIP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义开放封闭原则(Open-Closed Principle, OCP)规定:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
也就是说,在不修改现有代码的情况下,通过扩展功能来满足新的需求。
这一原则要求开发者在设计系统时,要确保系统能够适应不断变化的需求,同时尽量避免直接修改已经存在的代码。
通过扩展而非修改来添加新功能,可以减少对现有系统的影响,降低出错的可能性,并提高系统的稳定性和可维护性。
为什么需要开放封闭原则?
减少修改的风险:直接修改已有代码,可能会引发新的错误。开放封闭原则通过扩展功能避免了修改现有代码的风险。
提高代码的灵活性:通过扩展功能,可以轻松地适应需求的变化,而无需触碰核心代码。
支持代码复用:OCP 鼓励通过继承或组合的方式来扩展已有功能,这使得系统中的不同模块能够重复使用现有的代码。
提升代码的可维护性:对修改的封闭意味着代码的稳定性得到了增强,使得维护变 ...
单一职责原则SRP
单一职责原则 (Single Responsibility Principle, SRP)SRP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义单一职责原则(Single Responsibility Principle, SRP)规定:一个类应该只有一个引起其变化的原因。
换句话说,一个类应该只负责一件事情,具有单一职责。
在面向对象设计中,SRP 强调类的职责单一性,以减少类的复杂性和提高其可维护性。
如果一个类承担了多个职责,那么当其中一个职责发生变化时,这个类就需要修改。过多的职责会让类变得臃肿且难以维护,增加代码出错的风险。
原理SRP 背后的逻辑是:任何一个类都应该只负责一项功能,这使得类的结构更加简单且易于理解。
当系统功能发生变化时,只需要修改特定职责的类,而不会影响其他无关功能的代码。
为什么需要单一职责原则?
降低耦合:类的每一项职责都可能与其他系统部分发生交互。职责越多,耦合性越高。
提高可维护性:当某个职责发生变化时,SRP 确保只需要修改相关的类,降低出错的风险。
简化测试:职责单一的类 ...
依赖倒置原则DIP
依赖倒置原则 (Dependency Inversion Principle, DIP)DIP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义依赖倒置原则的核心思想是:高层模块不应该依赖低层模块,二者都应该依赖于抽象。
也就是说,具体的实现类应该依赖于接口或抽象类,而不是高层模块直接依赖实现细节。
依赖倒置原则常常用于创建解耦的系统,减少代码模块之间的直接依赖性。
主要内容
高层模块(如业务逻辑层)不应该依赖低层模块(如数据访问层),二者应该依赖于接口或抽象类。
抽象不应该依赖具体实现,而具体实现应该依赖于抽象。
好处
增强灵活性:代码依赖于接口或抽象类,便于更换不同的实现,而不需要修改高层模块的代码。
解耦模块:高层模块和低层模块通过抽象层进行交互,降低了耦合度,便于维护和扩展。
可扩展性强:添加新的实现类时,不需要改变原有的高层模块,只需实现接口或继承抽象类即可。
示例代码1234567891011121314151617181920212223242526272829303132333435// 抽象层 ...
里氏替换原则LSP
里氏替换原则 (Liskov Substitution Principle, LSP)LSP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义里氏替换原则的核心思想是:子类对象必须能够替换其父类对象,并且不会影响程序的正确性。
这意味着子类在扩展父类的功能时,不能改变父类原有的行为。
简单来说,程序中的子类对象应该能在任何父类对象可以出现的地方正常工作。
主要内容
子类应该完全兼容父类,任何使用父类的地方都可以安全地使用子类。
子类在重写父类方法时,不能违反父类的方法行为规范。
子类在继承父类的同时,不应该对父类的功能做破坏性的修改。
好处
增强系统的灵活性:符合 LSP 的子类能够无缝替换父类,使得代码更易于扩展和维护。
提高代码的健壮性:确保子类在继承父类时,不会破坏程序的行为,使得程序更加稳定和可靠。
减少继承带来的副作用:如果子类修改了父类的核心逻辑,可能会带来意料之外的问题。LSP 的遵守可以减少这种副作用。
示例代码123456789101112131415161718192021222324252 ...
Maps.newHashMapWithExpectedSize
Maps.newHashMapWithExpectedSizeMaps.newHashMapWithExpectedSize 是 Guava 库中的一个静态方法
用于创建一个具有预期大小的 HashMap。它通过合理地预估所需的容量,减少 HashMap 在扩容时的开销,从而提升性能。
方法签名1public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize)
参数
expectedSize:预期 HashMap 的大小,也就是你打算存入的键值对数量。此方法会根据这个值来计算合适的初始容量,以尽量减少扩容操作。
关键点:是预期键值对的大小,不是预期容器大小!,实际容量是 expectedSzie ÷ (3/4) 向 2^n 向上取值
返回值
返回一个初始化好的 HashMap<K, V> 对象,其容量已经根据传入的 expectedSize 进行了优化。
重要说明:
容量与负载因子:HashMap 默认的负载因子是 0.75,也就是说,当 ...
ES object与nested
ES object与nested在 ES 中,object 和 nested 是用来表示复杂 JSON 结构的两种字段类型
object 类型object 类型是最基本的嵌套结构,用来表示 JSON 对象中的字段。这些字段会被扁平化存储在同一个文档中。
使用场景
当你需要存储一个简单的对象或键值对,并且不需要在查询时进行复杂的关联操作。
适合处理非数组的嵌套结构,或者数组中的元素之间不需要保持独立的关联。
定义方式123456789101112131415161718PUT /my_index{ "mappings": { "properties": { "user": { "type": "object", "properties": { "first_name": { "type" ...
索引库基本操作
索引库基本操作ES 通过 Restful 请求操作索引库、文档,本文介绍如何使用 DSL 来操作索引库
创建索引库示例模版
12345678910111213141516171819202122232425PUT /索引库名称{ "mappings":{ "properties":{ "字段1":{ "type":"text", "analyzer":"ik_smart" }, "字段2":{ "type":"keyword", "index":"false" }, "字段3":{ "properties" ...
索引库-mapping
索引库-mapping写在前面的话:
在 Elasticsearch 6.x 及之前,每个索引中可以包含多个“类型”(类似于 SQL 中的表),通过类型区分不同文档结构。
从 Elasticsearch 7.x 开始,移除了类型的概念,所有文档在一个索引中共享相同的映射(mapping)。也就是说,不能再通过 type 区分不同文档,而是直接使用索引级别的映射。
Elasticsearch 8.x 彻底移除了类型字段,即 _type 字段完全不存在。
在 Elasticsearch 7.x 及以上版本中,索引结构的基础已经从原来的“类型(type)”转变为纯粹基于文档和字段(document and field)。
mapping 是对索引库中 document 的约束,本文介绍常见的mapping属性
常见的mapping属性
type(字段类型)
index(是否创建索引,默认true)
analyzer(分词器)
properties(该字段有哪些子字段)
type 类型详解核心数据类型文本类型 text文本类型默认会被分词,可以指定 index:"fal ...
gateio login
IK分词器的扩展与停用词典什么是扩展词典/停用词典可以通过编辑扩展词典和停用词典来改变分词规则
扩展词典:有些词并不是关键词,但是也希望被ES用来作为检索的关键词,可以将这些词加入扩展词典。
停用词典 有些词是关键词,但是出于业务场景不想使用这些关键词被检索到,可以将这些词放入停用词典。
如何添加扩展词典和停用词典?所在目录:
编辑 IKAnalyzer.cfg.xml 文件
1234567891011121314<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"><properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict" ...
docker安装ES kibana ik
docker安装ES kibana ikStep 1. 创建 Docker 网络1docker network create elastic-network
Step 2. 创建Docker Compose 文件在一个目录下创建一个名为 docker-compose.yml 的文件,内容如下:
12345678910111213141516171819202122232425262728293031323334353637383940version: '3'services: elasticsearch: image: elasticsearch:7.17.0 container_name: elasticsearch environment: - discovery.type=single-node - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - cluster.name=docker-cluster - node.name=node-1 - ne ...
什么是ES
什么是ES了解ES
一款强大的开源搜索引擎
elasticsearch结合了kibana、Logstash、Beats,即elastic stack(ELK),ELK技术栈的核心是ES
广泛应用于搜索、日志分析、实时监控领域(数据可视化)
前身是Lucene,提供搜索引擎的API,记住这个人:Shay Banon
认识ES传统的数据库一般使用正向索引,ES使用倒排索引,倒排索引是term到document的索引结构(正向索引是document到term)
ducument可以理解成数据,term是数据的分词,ES面向文档(document)存储,文档以json序列化的格式存储在ES中
相同类型的json的集合(document的集合),作为索引(Index)
建立term到document的映射表,基于term来查询document编号;查询过程如图:
MySQL和ES各自的优势领域:
MySQL: 事务类型操作,数据安全性,一致性
ES:海量数据搜索、分析、计算
二者可以互补,如下图架构:
JVM基础
JVMJVM(Java Virtual Machine,Java 虚拟机)是 Java 程序的运行环境,是 Java 语言的核心和关键部分之一。
JVM负责将.class字节码转化成机器码,能够根据不同的硬件平台和操作系统进行了优化和适配。
基本组成
类加载子系统:
功能:加载类文件(.class),生成类对象
组成:启动类加载器、扩展类加载器、应用程序类加载器
运行时数据区:
功能:用于存放Java程序运行时的数据,包括类的信息、对象实例、方法调用栈、线程状态等
执行引擎:
功能:负责执行Java程序中的字节码指令,将字节码翻译成硬件支持的指令集格式
组成:解释器、即时编译器(JIT编译器)
本地接口:
功能:允许Java程序调用本地方法库中的本地方法,实现更底层的功能和操作
垃圾回收器(GC)和内存管理子系统:
功能:管理Java程序的内存资源,包括内存分配、回收、释放
组成:GC、堆内存管理器
从功能上看,可以分为类加载系统、内存管理系统、执行引擎、本地接口
类加载机制什么是类加载机制JVM将.class文件依次进行 加载 => 连接(验证、整备、解 ...
限流详解
限流(Rate Limiting)详解定义限流(Rate Limiting)是指在单位时间内限制某个操作的最大执行次数,以防止系统过载、资源枯竭或拒绝服务攻击(DDoS)。
通过限流,可以确保系统在高并发访问时仍能保持稳定性和高可用性。
使用场景限流在各种场景中都能发挥重要作用,主要包括但不限于以下几种:
API网关:限制客户端对后端服务的请求频率,防止恶意请求导致服务不可用。
用户操作:防止单个用户频繁操作,如频繁登录尝试、评论、点赞等。
分布式系统:在分布式系统中控制对某些共享资源的访问频率,防止资源竞争导致系统性能下降。
消息队列:控制消息的生产或消费速率,防止消息队列积压或系统过载。
如何使用限流限流的实现可以通过多种方式进行,常见的方法有以下几种:
客户端限流:在客户端对请求频率进行控制,防止过多请求发送到服务器。
服务器端限流:在服务器端对接收到的请求进行控制,常见的做法是在API网关或服务层实现限流逻辑。
中间件限流:使用第三方中间件或库实现限流,如Redis、Nginx等。
以下是一些具体的实现示例:
基于Redis的限流Redis是一个高性能的内存数据库,可以 ...
为什么需要不可变类?
为什么需要不可变类?不可变类一旦创建,其状态就不能被修改,这带来了多个方面的好处
包括:
线程安全性
简化代码
提高性能
…
不可变类不代表类内变量不可变,而是状态(字段值)不可变
线程安全性多线程环境中的安全性:由于不可变对象一旦创建就不能改变状态,它们天生是线程安全的。
多个线程可以安全地共享和访问同一个不可变对象,而不需要同步机制来避免并发修改的问题。
简化代码减少复杂性:不可变对象的状态不会改变,因此在处理它们时,不需要考虑对象状态的变化。这简化了代码,减少了错误的可能性。
安全性:不可变对象可以安全地传递给方法、存储在集合中或返回给调用者,而不需要担心它们会在其他地方被修改。
提高性能缓存:不可变对象可以被缓存和重用。一个典型的例子是字符串池(String Pool),其中相同的字符串字面量被缓存,以减少内存使用和提高性能。
哈希码缓存:由于不可变对象的状态不变,它们的哈希码也不会变化。因此,可以在创建对象时计算并缓存哈希码,以提高集合(如哈希表和哈希集)的性能。
易于维护和调试更容易理解和维护:由于不可变对象的状态一旦创建就不变,理解和维护这些对象的代码变得更加 ...
为什么Java不支持多继承
为什么Java不支持多继承第一,降低类关系复杂度
第二,避免菱形继承问题:A->B , A->C, B&C->D ,现在,D调用A的方法,B,C都有重写,产生冲突
接口与抽象类的区别
接口与抽象类的区别总览
特性
接口
抽象类
方法实现
只能包含抽象方法(Java 8 之后支持默认方法和静态方法)
可以包含抽象方法和具体方法
成员变量
只能包含常量(默认 public static final)
可以包含实例变量、静态变量和常量
多重继承
一个类可以实现多个接口
一个类只能继承一个抽象类
访问修饰符
方法默认是 public
方法可以是 public、protected 或 default
构造器
没有构造器
可以有构造器
适用场景
定义一组不相关类的共同行为
定义一组相关类的共同行为和属性
实现和继承
implements
extends
版本要求
Java 8 之前只能包含抽象方法
任意版本支持
区别
接口使用 interface ,抽象类使用 abstract
一个类可以实现多个接口,但只能继承一个抽象类
接口成员变量一定是public static final,抽象类成员变量没有约束
接口没有构造函数,抽象类可有可无
接口的方法一般是public abstract (Java8 后有default和stati ...