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提供了许多功能,包括注解、自定义序列化和反序列化、动态解析等,使其非常灵活和强大。
  • 易于使用:JacksonAPI简单易用,使得开发者可以轻松地在他们的应用程序中集成和使用。
  • 社区支持: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 自定义序列化和反序列化

创建自定义序列化器和反序列化器以自定义特定字段或类的序列化和反序列化行为。为此,创建一个实现JsonSerializerJsonDeserializer接口的类,并在需要自定义的字段或类上使用@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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768503.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【工具-GUI Guider】

工具-GUI Guider GUI Guider GUI Guider LVGL-使用GUI Guider 拖拽式设计LVGL

P1719 最大加权矩形(洛谷)

文章目录 最大加权矩形题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示二维前缀和易错 最大加权矩形 题目描述 为了更好的备战 NOIP2013&#xff0c;电脑组的几个女孩子 LYQ,ZSC,ZHQ 认为&#xff0c;我们不光需要机房&#xff0c;我们还需要运动&#xff0c;于…

CSRF一-WEB攻防-CSRF请求伪造Referer同源置空配合XSSToken值校验复用删除

演示案例&#xff1a; CSRF-无检测防护-检测&生成&利用CSRF-Referer同源-规则&上传&XSSCSRF-Token校验-值删除&复用&留空 #CSRF-无检测防护-检测&生成&利用 检测&#xff1a;黑盒手工利用测试&#xff0c;白盒看代码检验&#xff08;有无token…

【ESP32S3 Sense接入百度在线语音识别】

视频地址&#xff1a; ESP32S3 Sense接入百度在线语音识别 1. 前言 使用Seeed XIAO ESP32S3 Sense开发板接入百度智能云实现在线语音识别。自带麦克风模块用做语音输入&#xff0c;通过串口发送字符“1”来控制数据的采集和上传。 步骤概括    (1) 在百度云控制端选择“语音…

2023年全国职业院校技能大赛(网络系统管理赛项)样题三

2023****年全国职业院校技能大赛 GZ073****网络系统管理赛项 赛题第3套 模块A:网络构建 ​ 目 录 任务清单… 1 (一)基础配置… 1 (二)有线网络配置… 1 (三)无线网络配置… 3 (四)出口网络配置… 6 (五)网络运维配置… 6 (六)SDN网络配置… 7 附录1…

YiYi-Web项目介绍

YiYi-Web项目介绍 1. 简介2. 使用2.1 后端开发环境2.2 前端开发环境 3. 测试环境&#xff1a;4. 更新日志5. 打包情况6.项目截图 本项目前端是html、css、js、jQuery基础技术。 后端都是最新的SpringBoot技术&#xff0c;不分离版本&#xff0c; 是最基础的项目开发教程&#x…

挺后悔,我敷衍地回答了“程序员如何提升抽象思维“

分享是最有效的学习方式。 博客&#xff1a;https://blog.ktdaddy.com/ 大家好&#xff0c;我是老猫。 大概在月初的时候&#xff0c;我发了一篇文章【当程序员之后&#xff1f;(真心话)】,在这篇文章中&#xff0c;提及了抽象思维对一名程序员的重要性。可能说得也比较笼统&a…

【Flask】Flask数据模型关系

数据模型关系 一对多 如上所示&#xff0c;一个作者关联多个文章&#xff0c;暂时认定&#xff0c;一篇文章只能有一个作者。 作者以及文章的类定义如下所示&#xff1a; class Author(db.Model):id db.Column(db.Integer, primary_keyTrue)name db.Column(db.String(128)…

Godot.NET C# 工程化开发(1):通用Nuget 导入+ 模板文件导出,包含随机数生成,日志管理,数据库连接等功能

文章目录 前言Github项目地址&#xff0c;包含模板文件后期思考补充项目设置编写失误环境visual studio 配置详细的配置看我这篇文章 Nuget 推荐NewtonSoft 成功Bogus 成功Github文档地址随机生成构造器生成构造器接口(推荐) 文件夹设置Nlog 成功&#xff01;Nlog.configNlogHe…

C++笔记之argv[1]与字符串内容的比较

C++笔记之argv[1]与字符串内容的比较 code review! 文章目录 C++笔记之argv[1]与字符串内容的比较1.错误示例:if(argv[1]=="Hello")2.方法一:使用 `strcmp` 函数3.方法二:将 `argv[1]` 转换为 `std::string` 然后使用 `==` 运算符来比较1.错误示例:if(argv[1]=…

蓝桥杯day10刷题日记

P8604 [蓝桥杯 2013 国 C] 危险系数 思路&#xff1a;dfs&#xff0c;用深度优先搜索查找一次所有的线路&#xff0c;过程中记录每个点走过的次数&#xff0c;最后在与总路线数比较&#xff0c;相同即为每次必过的点&#xff0c;即关键点 #include <iostream> using na…

代码学习记录26----贪心算法

随想录日记part26【把这两天没写的补回来】 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.22-24 主要内容&#xff1a;今天开始学习贪心算法&#xff0c;基础知识可以看链接&#xff0c;&#xff1a;接下来是针对题目的讲解&#xff1a;1.分配饼干 &#x…

继承和多态(1)(继承部分)

继承 继承的概念 上文就是继承的概念。 必须记住父类也可以称为基类&#xff0c;超类。 子类也可以称为派生类。 继承的语法 在Java中如果要表示类之间的继承关系&#xff0c;需要借助extends关键字&#xff0c;具体如下&#xff1a; 修饰符 class 子类 extends 父类 {//…

网易web安全工程师进阶版课程

课程介绍 《Web安全工程师&#xff08;进阶&#xff09;》是由“ i春秋学院联合网易安全部”出品&#xff0c;资深讲师团队通过精炼的教学内容、丰富的实际场景及综合项目实战&#xff0c;帮助学员纵向提升技能&#xff0c;横向拓宽视野&#xff0c;牢靠掌握Web安全工程师核心…

pycharm搭建新的解释器及删除处理

目录 1.创建虚拟环境 个人实际操作&#xff1a; 对于“继承全局站点包”&#xff1a; 2.创建一个新项目 3.删除操作 &#xff08;1&#xff09;删除解释器 &#xff08;2&#xff09;删除新建项目 1.创建虚拟环境 Pycharm官方文档说明网址&#xff1a; Configure a virt…

【机器学习】包裹式特征选择之序列前向选择法

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

向开发板上移植ip工具:交叉编译 ip工具

一. 简介 前面几篇文章学习了 CAN设备节点的创建&#xff0c;以及如何使能 CAN驱动。 本文学习向开发板上移植ip工具。 二. 向开发板上移植ip工具&#xff1a;交叉编译 ip工具 注意&#xff1a;在移植 ip 命令的时候必须先对根文件系统做个备份&#xff01;防止操作失误导…

ffmpeg实现媒体流解码

本期主要讲解怎么将MP4媒体流的视频解码为yuv,音频解码为pcm数据;在此之前我们要先了解解复用和复用的概念; 解复用:像mp4是由音频和视频组成的(其他内容流除外);将MP4的流拆分成视频流(h264或h265等)和音频流(AAC或mp3等); 复用:就是将音频和视频打包成MP4或者fl…

我重新理解了《重构》

我重新理解了《重构》 重构的定义 《重构&#xff1a;改善既有代码的设计》 书中给出了重构的定义&#xff1a;对软件内部结构的一种调整&#xff0c;目的是在不改变软件可观察前提下&#xff0c;提高其可理解性&#xff0c;降低其修改成本。每个人对重构有自己的理解&#x…

Cobalt Strike -- 各种beacon

今天来讲一下cs里面的beacon 其实cs真的功能很强大&#xff0c;自带代理创建&#xff0c;自带beacon通信&#xff01;&#xff01;&#xff01; 一张图&#xff0c;就能说明beacon的工作原理 1.Beacon 每当有一台机器上线之后&#xff0c;我们都会选择sleep时间&#xff0c;…