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…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
