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…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
