Java序列化之Jackson详解
文章目录
- 1 Jackson
- 1.1 Jackson简介
- 1.2 为什么选择Jackson
- 1.3 Jackson的基本功能
- 1.3.1 将Java对象转换为JSON字符串(序列化)
- 1.3.2 将JSON字符串转换为Java对象(反序列化)
- 1.4 Jackson库主要方法
- 1.5 使用Jackson基本步骤
- 1.5.1 添加依赖(Maven或Gradle)
- 1.5.2 创建Java对象模型
- 1.5.3 使用ObjectMapper进行序列化和反序列化
- 1.6 注解讲解
- 1.6.1 @JsonProperty
- 1.6.2 @JsonIgnore
- 1.6.3 @JsonFormat
- 1.6.4 @JsonInclude
- 1.6.5 @JsonCreator
- 1.6.6 @JsonSetter
- 1.6.7 @JsonGetter
- 1.6.8 @JsonAnySetter
- 1.6.9 @JsonAnyGetter
- 1.6.10 @JsonTypeInfo
- 1.7 高级特性
- 1.7.1 自定义序列化和反序列化
- 1.7.2 使用JsonNode进行动态解析
- 1.7.3 处理日期和时间类型
- 1.7.4 处理泛型
- 1.7.5 使用模块扩展Jackson(如Java 8时间支持)
1 Jackson
1.1 Jackson简介
Jackson是一个用于处理JSON数据的开源Java库。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于计算机解析和生成。在Java领域,Jackson已经成为处理JSON数据的事实标准库。它提供了丰富的功能,包括将Java对象转换为JSON字符串(序列化)以及将JSON字符串转换为Java对象(反序列化)
Jackson主要由三个核心包组成:
jackson-databind:提供了通用的数据绑定功能(将Java对象与JSON数据相互转换)jackson-core:提供了核心的低级JSON处理API(例如JsonParser和JsonGenerator)jackson-annotations:提供了用于配置数据绑定的注解
1.2 为什么选择Jackson
尽管Java生态系统中有其他处理JSON数据的库(如Gson和JSON-java),但Jackson仍然是许多开发者的首选,原因包括:
- 性能:
Jackson性能优越,对内存和CPU的使用都相对较低。许多性能基准测试表明,Jackson在序列化和反序列化方面都比其他库更快。 - 功能丰富:
Jackson提供了许多功能,包括注解、自定义序列化和反序列化、动态解析等,使其非常灵活和强大。 - 易于使用:
Jackson的API简单易用,使得开发者可以轻松地在他们的应用程序中集成和使用。 - 社区支持:
Jackson拥有庞大的开发者社区,这意味着有更多的文档、教程和问题解答可供参考。 - 模块化:
Jackson支持通过模块扩展其功能,例如Java 8时间库、Joda-Time和Kotlin等。 - 兼容性:
Jackson可以很好地与其他流行的Java框架(如Spring)集成。
综上所述,Jackson是一个强大且易于使用的库,值得Java开发者在处理JSON数据时使用
1.3 Jackson的基本功能
Jackson库的核心功能是将Java对象转换为JSON字符串(序列化)以及将JSON字符串转换为Java对象(反序列化)
1.3.1 将Java对象转换为JSON字符串(序列化)
序列化:将Java对象转换为JSON字符串的过程。这在许多场景中非常有用,例如在将数据发送到Web客户端时,或者在将数据存储到文件或数据库时。Jackson通过ObjectMapper类来实现序列化。以下是一个简单的示例:
import com.fasterxml.jackson.databind.ObjectMapper;public class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}public static void main(String[] args) {ObjectMapper objectMapper = new ObjectMapper();Person person = new Person("Alice", 30);try {String jsonString = objectMapper.writeValueAsString(person);System.out.println(jsonString); // 输出:{"name":"Alice","age":30}} catch (Exception e) {e.printStackTrace();}}
}
1.3.2 将JSON字符串转换为Java对象(反序列化)
反序列化:将JSON字符串转换回Java对象的过程。这在从Web客户端接收数据或从文件或数据库读取数据时非常有用。同样,Jackson使用ObjectMapper类来实现反序列化。以下是一个简单的示例:
import com.fasterxml.jackson.databind.ObjectMapper;public class Person {public String name;public int age;public Person() {}public static void main(String[] args) {ObjectMapper objectMapper = new ObjectMapper();String jsonString = "{\"name\":\"Alice\",\"age\":30}";try {Person person = objectMapper.readValue(jsonString, Person.class);System.out.println("Name: " + person.name + ", Age: " + person.age); // 输出:Name: Alice, Age: 30} catch (Exception e) {e.printStackTrace();}}
}
这些示例展示了Jackson库的基本功能。接下来的部分将介绍如何使用Jackson库,包括添加依赖、创建Java对象模型以及使用ObjectMapper进行序列化和反序列化。
1.4 Jackson库主要方法
以下是Jackson库的一些主要API和组件:
ObjectMapper:这是Jackson库的核心类,用于序列化和反序列化操作。主要方法有:
writeValueAsString(Object):将Java对象序列化为JSON字符串
readValue(String, Class):将JSON字符串反序列化为Java对象JsonParser:用于从JSON数据源(如文件、输入流或字符串)解析JSON数据。主要方法有:
nextToken():获取下一个JSON令牌(如START_OBJECT、FIELD_NAME等)。
getValueAsString():将当前令牌作为字符串返回。
getValueAsInt():将当前令牌作为整数返回。JsonGenerator:用于将JSON数据写入数据源(如文件、输出流或字符串缓冲区)。主要方法有:
writeStartObject():写入开始对象标记({)。
writeFieldName(String):写入字段名称。
writeString(String):写入字符串值。
writeEndObject():写入结束对象标记(})。JsonNode:用于表示JSON树模型中的节点,可以是对象、数组、字符串、数字等。主要方法有:
get(String):获取指定字段的子节点。
path(String):获取指定字段的子节点,如果不存在则返回一个“missing”节点。
isObject():检查当前节点是否是一个对象。
isArray():检查当前节点是否是一个数组。注解:Jackson提供了一系列注解来配置序列化和反序列化过程。一些常用注解包括:
@JsonProperty:指定字段在JSON数据中的名称。
@JsonIgnore:指定字段在序列化和反序列化过程中被忽略。
@JsonCreator:指定用于反序列化的构造函数或工厂方法。
@JsonSerialize:指定用于序列化特定字段或类的自定义序列化器。
@JsonDeserialize:指定用于反序列化特定字段或类的自定义反序列化器。
1.5 使用Jackson基本步骤
1.5.1 添加依赖(Maven或Gradle)
以下是添加Jackson库的方法:
Maven:将以下依赖添加到pom.xml文件中:
<dependencies><!-- Jackson core --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.13.0</version></dependency><!-- Jackson databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.0</version></dependency><!-- Jackson annotations --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.13.0</version></dependency>
</dependencies>
Gradle:将以下依赖添加到build.gradle文件中:
dependencies {implementation 'com.fasterxml.jackson.core:jackson-core:2.13.0'implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.0'
}
1.5.2 创建Java对象模型
在使用Jackson之前,需要创建一个Java对象模型,该模型表示要序列化和反序列化的JSON数据。例如,以下是一个表示Person的简单Java类:
public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
1.5.3 使用ObjectMapper进行序列化和反序列化
使用ObjectMapper类,可以轻松地将Java对象序列化为JSON字符串以及将JSON字符串反序列化为Java对象。以下是一个简单的示例:
序列化:
import com.fasterxml.jackson.databind.ObjectMapper;public class Main {public static void main(String[] args) {ObjectMapper objectMapper = new ObjectMapper();Person person = new Person("Alice", 30);try {String jsonString = objectMapper.writeValueAsString(person);System.out.println(jsonString); // 输出:{"name":"Alice","age":30}} catch (Exception e) {e.printStackTrace();}}
}
反序列化:
import com.fasterxml.jackson.databind.ObjectMapper;public class Main {public static void main(String[] args) {ObjectMapper objectMapper = new ObjectMapper();String jsonString = "{\"name\":\"Alice\",\"age\":30}";try {Person person = objectMapper.readValue(jsonString, Person.class);System.out.println("Name: " + person.getName() + ", Age: " + person.getAge()); // 输出:Name: Alice, Age: 30} catch (Exception e) {e.printStackTrace();}}
}
这些示例展示了如何使用Jackson库进行序列化和反序列化操作。在实际项目中,你可能需要根据需求对这些操作进行更多的配置和自定义,例如使用注解、自定义序列化器和反序列化器等。
1.6 注解讲解
Jackson库提供了一系列注解,可以在序列化和反序列化过程中对字段和类进行配置。以下是一些常用注解的示例:
1.6.1 @JsonProperty
该注解用于指定 Java 属性与 JSON 属性之间的映射关系,常用的参数有:
value:用于指定 JSON 属性的名称,当 Java 属性和 JSON 属性名称不一致时使用。access:用于指定该属性的访问方式,常用的取值有JsonAccess.READ_ONLY(只读),JsonAccess.WRITE_ONLY(只写)和JsonAccess.READ_WRITE(可读可写)。
public class Person {@JsonProperty(value = "name")private String fullName;@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)private String password;// getters and setters
}Person person = new Person();
person.setFullName("John Smith");
person.setPassword("123456");ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
// {"name":"John Smith"}Person person2 = mapper.readValue(json, Person.class);
System.out.println(person2.getFullName());
// John Smith
System.out.println(person2.getPassword());
// null
1.6.2 @JsonIgnore
用于禁用 Java 属性的序列化和反序列化。
public class Person {private String fullName;@JsonIgnoreprivate String password;// getters and setters
}Person person = new Person();
person.setFullName("John Smith");
person.setPassword("123456");ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
// {"fullName":"John Smith"}Person person2 = mapper.readValue("{\"fullName\":\"John Smith\",\"password\":\"123456\"}", Person.class);
System.out.println(person2.getFullName());
// John Smith
System.out.println(person2.getPassword());
// null
1.6.3 @JsonFormat
该注解用于指定 Java 属性的日期和时间格式,常用的参数有:
shape:用于指定日期和时间的格式,可选的取值有JsonFormat.Shape.STRING(以字符串形式表示)和JsonFormat.Shape.NUMBER(以时间戳形式表示)。pattern:用于指定日期和时间的格式模板,例如 “yyyy-MM-dd HH:mm:ss”。
public class Person {private String fullName;@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")private Date birthDate;// getters and setters
}Person person = new Person();
person.setFullName("John Smith");
person.setBirthDate(new Date());ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
// {"fullName":"John Smith","birthDate":"2022-05-16 10:38:30"}Person person2 = mapper.readValue(json, Person.class);
System.out.println(person2.getFullName());
// John Smith
System.out.println(person2.getBirthDate());
// Mon May 16 10:38:30 CST 2022
1.6.4 @JsonInclude
该注解用于指定序列化 Java 对象时包含哪些属性,常用的参数有:
value:用于指定包含哪些属性,可选的取值有JsonInclude.Include.ALWAYS(始终包含)、JsonInclude.Include.NON_NULL(值不为 null 时包含)、JsonInclude.Include.NON_DEFAULT(值不为默认值时包含)、JsonInclude.Include.NON_EMPTY(值不为空时包含)和JsonInclude.Include.CUSTOM(自定义条件)。content:用于指定自定义条件的实现类。
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Person {private String fullName;private Integer age;// getters and setters
}Person person = new Person();
person.setFullName("John Smith");
// person.setAge(null);ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
// {"fullName":"John Smith"}Person person2 = mapper.readValue("{\"fullName\":\"John Smith\",\"age\":null}", Person.class);
System.out.println(person2.getFullName());
// John Smith
System.out.println(person2.getAge());
// null
1.6.5 @JsonCreator
该注解用于指定反序列化时使用的构造方法或工厂方法。
public class Person {private String fullName;private Integer age;@JsonCreatorpublic Person(@JsonProperty("fullName") String fullName, @JsonProperty("age") Integer age) {this.fullName = fullName;this.age = age;}// getters and setters
}ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue("{\"fullName\":\"John Smith\",\"age\":30}", Person.class);
System.out.println(person.getFullName());
// John Smith
System.out.println(person.getAge());
// 30
1.6.6 @JsonSetter
该注解用于指定反序列化时使用的方法,常用的参数有:
value:用于指定 JSON 属性的名称,当方法名和 JSON 属性名称不一致时使用
public class Person {private String fullName;private Integer age;@JsonSetter("name")public void setFullName(String fullName) {this.fullName = fullName;}// getters and setters
}ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue("{\"name\":\"John Smith\",\"age\":30}", Person.class);
System.out.println(person.getFullName());
// John Smith
System.out.println(person.getAge());
// 30
1.6.7 @JsonGetter
该注解用于指定序列化时使用的方法,常用的参数有:
value:用于指定JSON属性的名称,当方法名和JSON属性名称不一致时使用。
public class Person {private String fullName;private Integer age;@JsonGetter("name")public String getFullName() {return fullName;}// getters and setters
}
1.6.8 @JsonAnySetter
该注解用于指定反序列化时使用的方法,用于处理 JSON 中未知的属性。
public class Person {private String fullName;private Map<String, Object> otherProperties = new HashMap<>();@JsonAnySetterpublic void setOtherProperties(String key, Object value) {otherProperties.put(key, value);}// getters and setters
}ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue("{\"fullName\":\"John Smith\",\"age\":30}", Person.class);
System.out.println(person.getFullName());
// John Smith
System.out.println(person.getOtherProperties());
// {age=30}
1.6.9 @JsonAnyGetter
该注解用于指定序列化时使用的方法,用于处理 Java 对象中未知的属性
public class Person {private String fullName;private Map<String, Object> otherProperties = new HashMap<>();public void addOtherProperty(String key, Object value) {otherProperties.put(key, value);}@JsonAnyGetterpublic Map<String, Object> getOtherProperties() {return otherProperties;}// getters and setters
}Person person = new Person();
person.setFullName("John Smith");
person.addOtherProperty("age", 30);ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
// {"fullName":"John Smith","age":30}
1.6.10 @JsonTypeInfo
该注解用于指定 Java 对象在序列化和反序列化时的类型信息,常用的参数有:
use:用于指定类型信息的使用方式,可选的取值有JsonTypeInfo.Id.CLASS(使用 Java 类的全限定名)、JsonTypeInfo.Id.NAME(使用名称)和JsonTypeInfo.Id.NONE(不使用类型信息)。include:用于指定类型信息的包含方式,可选的取值有JsonTypeInfo.As.PROPERTY(作为 JSON 属性)和JsonTypeInfo.As.EXTERNAL_PROPERTY(作为外部属性)。property:用于指定包含类型信息的属性名,当 include 的值为JsonTypeInfo.As.PROPERTY时使用。visible:用于指定类型信息是否可见。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"),@JsonSubTypes.Type(value = Circle.class, name = "circle")
})
public abstract class Shape {// ...
}public class Rectangle extends Shape {// ...
}public class Circle extends Shape {// ...
}Shape shape = new Rectangle();ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(shape);
// {"type":"rectangle"}Shape shape2 = mapper.readValue(json, Shape.class);
System.out.println(shape2.getClass().getSimpleName());
// Rectangle
1.7 高级特性
1.7.1 自定义序列化和反序列化
创建自定义序列化器和反序列化器以自定义特定字段或类的序列化和反序列化行为。为此,创建一个实现JsonSerializer或JsonDeserializer接口的类,并在需要自定义的字段或类上使用@JsonSerialize和@JsonDeserialize注解。例如:
public class CustomDateSerializer extends JsonSerializer<Date> {private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");@Overridepublic void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeString(dateFormat.format(value));}
}
public class Person {private String name;@JsonSerialize(using = CustomDateSerializer.class)private Date birthdate;// ...其他代码...
}
1.7.2 使用JsonNode进行动态解析
可以使用JsonNode类来动态地解析和操作JSON数据。例如:
String jsonString = "{\"name\":\"Alice\",\"age\":30,\"address\":{\"street\":\"Main St\",\"city\":\"New York\"}}";ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonString);String name = rootNode.get("name").asText(); // Alice
int age = rootNode.get("age").asInt(); // 30
String street = rootNode.get("address").get("street").asText(); // Main St
1.7.3 处理日期和时间类型
Jackson可以处理Java日期和时间类型,例如java.util.Date和Java 8时间库中的类型。可以通过配置ObjectMapper来指定日期和时间格式,例如:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
1.7.4 处理泛型
Jackson可以处理泛型类型,例如List<T>和Map<String, T>。在反序列化时,需要使用TypeReference来指定泛型类型。例如:
String jsonString = "[{\"name\":\"Alice\",\"age\":30},{\"name\":\"Bob\",\"age\":25}]";ObjectMapper objectMapper = new ObjectMapper();
List<Person> persons = objectMapper.readValue(jsonString, new TypeReference<List<Person>>() {});
1.7.5 使用模块扩展Jackson(如Java 8时间支持)
Jackson可以通过模块来扩展其功能。例如,你可以使用jackson-datatype-jsr310模块为Jackson添加对Java 8时间库的支持。首先,将依赖添加到项目中:
Maven:
<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.13.0</version>
</dependency>
Gradle:
dependencies {implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.0'
}
然后,需要注册模块到ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
现在,Jackson可以正确地处理Java 8时间库中的类型,例如LocalDate、LocalTime和Instant。
参考资料:
https://github.com/FasterXML/jackson-docs
https://github.com/google/gson
https://github.com/alibaba/fastjson
https://github.com/stleary/JSON-java
https://github.com/square/moshi
https://github.com/boonproject/boon
相关文章:
Java序列化之Jackson详解
文章目录 1 Jackson1.1 Jackson简介1.2 为什么选择Jackson1.3 Jackson的基本功能1.3.1 将Java对象转换为JSON字符串(序列化)1.3.2 将JSON字符串转换为Java对象(反序列化) 1.4 Jackson库主要方法1.5 使用Jackson基本步骤1.5.1 添加…...
深入Facebook的世界:探索数字化社交的无限可能性
引言 随着数字化时代的到来,社交媒体平台已经成为了人们日常生活中不可或缺的一部分,而其中最为突出的代表之一便是Facebook。作为全球最大的社交媒体平台之一,Facebook不仅仅是一个社交网络,更是一个数字化社交的生态系统&#…...
HTML 怎么解决上下标问题呢?
当我们阅读内容时,经常会遇到特殊格式的文本,如化学式的下标和数学公式的上标,sub 标签和sup 标签就是用来解决这个问题的。 1. 基础语法 什么是 sub 和sup标签 sub 标签用于定义下标文本,而 sup 标签用于定义上标文本。 这些…...
题目 2880: 计算鞍点
题目描述: 给定一个5*5的矩阵,每行只有一个最大值,每列只有一个最小值,寻找这个矩阵的鞍点。 鞍点指的是矩阵中的一个元素,它是所在行的最大值,并且是所在列的最小值。 例如:在下面的例子中(第…...
前端Web移动端学习day05
移动 Web 第五天 响应式布局方案 媒体查询Bootstrap框架 响应式网页指的是一套代码适配多端,一套代码适配各种大小的屏幕。 共有两种方案可以实现响应式网页,一种是媒体查询,另一种是使用bootstrap框架。 01-媒体查询 基本写法 max-wid…...
蚂蚁庄园今日答案
蚂蚁庄园是一款爱心公益游戏,用户可以通过喂养小鸡,产生鸡蛋,并通过捐赠鸡蛋参与公益项目。用户每日完成答题就可以领取鸡饲料,使用鸡饲料喂鸡之后,会可以获得鸡蛋,可以通过鸡蛋来进行爱心捐赠。其中&#…...
深度学习中的随机种子random_seed
在深度学习中,random_seed是一个用于控制随机过程的种子值。这个种子值用于初始化随机数生成器,从而确保在多次实验中,涉及随机性的步骤能够产生一致的结果。这对于实验的可重复性、调试以及结果对比都是至关重要的。 具体来说,深…...
【项目技术介绍篇】若依管理系统功能介绍
作者介绍:本人笔名姑苏老陈,从事JAVA开发工作十多年了,带过大学刚毕业的实习生,也带过技术团队。最近有个朋友的表弟,马上要大学毕业了,想从事JAVA开发工作,但不知道从何处入手。于是࿰…...
Maximum Sum(贪心策略,模运算,最大子段和)
文章目录 题目描述输入格式输出格式样例输入1样例输出1样例输入2样例输出2提交链接提示 解析参考代码 题目描述 你有一个由 n n n 个整数组成的数组 a a a 。 你要对它进行 k k k 次操作。其中一个操作是选择数组 a a a 的任意连续子数组(可能为空),并在数组的…...
Gartner 公布 2024 年八大网络安全预测
近日,Gartner 安全与风险管理峰会在悉尼举行,旨在探讨网络安全的发展前景。 本次峰会,Gartner 公布了 2024 年及以后的八大网络安全预测。 Gartner 研究总监 Deepti Gopal 表示,随着 GenAI 的不断发展,一些长期困扰网…...
《每天十分钟》-红宝书第4版-对象、类与面向对象编程(六)
盗用构造函数 上节提到原型包含引用值导致的继承问题,为了解决这种问题,一种叫作“盗用构造函数”(constructor stealing)的技术在开发社区流行起来(这种技术有时也称作“对象伪装”或“经典继承”)。基本…...
Ubuntu Desktop Server - user 用户与 root 用户切换
Ubuntu Desktop Server - user 用户与 root 用户切换 1. user 用户与 root 用户切换2. root 用户与 user 用户切换References 1. user 用户与 root 用户切换 strongforeverstrong:~$ strongforeverstrong:~$ sudo su [sudo] password for strong: rootforeverstrong:/home/s…...
SQL Server事务复制操作出现的错误 进程无法在“xxx”上执行sp_replcmds
SQL Server事务复制操作出现的错误 进程无法在“xxx”上执行“sp_replcmds” 无法作为数据库主体执行,因为主体 "dbo" 不存在、无法模拟这种类型的主体,或您没有所需的权限...
学点儿Java_Day12_IO流
1 IO介绍以及分类 IO: Input Output 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据…...
【python】python编程初探1----python中的基本语法,标识符,关键字,注释,多行书写,代码缩进,语句块,模块等
欢迎来CILMY23的博客喔,本篇为【python】python编程初探1----python中的基本语法,标识符,关键字,注释,多行书写,代码缩进,语句块,模块,感谢观看,支持的可以给…...
牛客周赛 Round 38
牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com) A-小红的正整数自增_牛客周赛 Round 38 (nowcoder.com) 取出最后一位判断即可 #include<iostream> #include<algorithm> #include<vector> #include<set> #include…...
漏洞扫描操作系统识别技术原理
漏洞扫描过程中,操作系统识别技术是至关重要的一步,因为它有助于扫描器针对性地选择适用的漏洞检测规则,提高扫描的准确性和效率。以下是漏洞扫描中操作系统识别技术的主要原理: **1. **TCP/IP 协议栈指纹识别** **原理**&#…...
数据结构与算法-分治算法
数据结构与算法 数据结构与算法是计算机科学中的两个核心概念,它们在软件开发和问题解决中起着至关重要的作用。 数据结构 数据结构是计算机中存储、组织和管理数据的方式,它能够帮助我们高效地访问和修改数据。不同的数据结构适用于不同类型的应用场…...
MNN详细介绍、安装和编译
目录 第一章:MNN简介 1.1、MNN概述 1.2、MNN特点 1.3、MNN在移动端的应用优势 第二章:MNN安装与配置 2.1、环境准备 2.2、下载与编译 第三章:MNN使用指南 3.1、模型转换与部署 3.2、推理示例 第四章:MNN高级应用与优化技巧...
uniapp-Form示例(uviewPlus)
示例说明 Vue版本:vue3 组件:uviewPlus(Form 表单 | uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架) 说明:表单组建、表单验证、提交验证等; 截图: 示例代码 <templat…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
