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…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
