[C#学习笔记]Newtonsoft.Json

news2024/9/21 16:36:10

视频地址:分享一些Newtonsoft.Json的实用功能与技巧_哔哩哔哩_bilibili

强烈推荐学习C#和WPF的朋友关注此UP,知识点巨多,讲解透彻!

一、JsonSerializerSettings

1.1 自动缩进-Formatting

使用Formatting.None进行序列化

var s = new Student
{
    PersonId = 1,
    FullName = "Jack Doe",
};

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.None,
};

var r = JsonConvert.SerializeObject(s, setting);
Console.WriteLine(r);

class Student
{
    public int PersonId { get; set; }

    public string FullName { get; set; }
}

输出结果为

{"PersonId":1,"FullName":"Jack Doe"}

改为Formatting.None后,输出结果为

{
  "PersonId": 1,
  "FullName": "Jack Doe"
}

1.2 命名策略-NamingStrategy

1.2.3 蛇形命名-SnakeCaseNamingStrategy

将设置改成

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver  = new DefaultContractResolver()
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    }
};

输出结果为

{
  "person_id": 1,
  "full_name": "Jack Doe"
}

1.2.4 烤串命名-KebabCaseNamingStrategy

{
  "person-id": 1,
  "full-name": "Jack Doe"
}

1.2.5 驼峰命名-CamelCaseNamingStrategy

{
  "personId": 1,
  "fullName": "Jack Doe"
}

1.2.6 帕斯卡命名-DefaultNamingStrategy

{
  "PersonId": 1,
  "FullName": "Jack Doe"
}

1.3 空值处理- NullValueHandling

1.3.1 忽略-Ignore

实例对象未对可空属性Address赋值,序列化属性使用NullValueHandling.Ignore

var s = new Student
{
    PersonId = 1,
    FullName = "Jack Doe",
};

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver  = new DefaultContractResolver()
    {
        NamingStrategy = new DefaultNamingStrategy()
    },
    NullValueHandling = NullValueHandling.Ignore,
};

var r = JsonConvert.SerializeObject(s, setting);
Console.WriteLine(r);

class Student
{
    public int PersonId { get; set; }

    public string? Address { get; set; }

    public string FullName { get; set; }
}

输出结果,可以看到输出结果中也没有Address属性

{
  "PersonId": 1,
  "FullName": "Jack Doe"
}

1.3.2 包含-Include

改为NullValueHandling.Include后,输出结果

{
  "PersonId": 1,
  "Address": null,
  "FullName": "Jack Doe"
}

1.4 字符串转义-StringEscapeHandling

1.4.1 仅限Ascii-EscapeNonAscii

var s = new Student
{
    PersonId = 1,
    FullName = "Jack Doe",
    Address = "中国"
};

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver  = new DefaultContractResolver()
    {
        NamingStrategy = new DefaultNamingStrategy()
    },
    NullValueHandling = NullValueHandling.Include,
    StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
};

var r = JsonConvert.SerializeObject(s, setting);
Console.WriteLine(r);

class Student
{
    public int PersonId { get; set; }

    public string? Address { get; set; }

    public string FullName { get; set; }
}

输出结果

{
  "PersonId": 1,
  "Address": "\u4e2d\u56fd",
  "FullName": "Jack Doe"
}

1.4.2 默认-Default

{
  "PersonId": 1,
  "Address": "中国",
  "FullName": "Jack Doe"
}

1.5 类型名称-TypeNameHandling

将设置改成

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver = new DefaultContractResolver()
    {
        NamingStrategy = new DefaultNamingStrategy()
    },
    NullValueHandling = NullValueHandling.Include,
    StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
    TypeNameHandling = TypeNameHandling.All,
};

再进行序列化 

{
  "$type": "Student, ConsoleApp2",
  "PersonId": 1,
  "Address": "中国",
  "FullName": "Jack Doe"
}

可以看到多了一个$Type属性,内容为类名和命名空间

以下为其一个应用场景

一个抽象类Person,类Student和Employee继承自Person

abstract class Person
{
    public string Name { get; set; }

    public string Phone { get; set; }
}

class Student:Person
{
    public string School { get; set; }
    public int Grade { get; set; }
}

class Employee : Person
{
    public string Department { get; set; }
    public double Salary { get; set; }
}

进行实例化

var people = new List<Person>()
{
    new Student
    {
        Name = "John Doe",
        Phone = "123-456-789",
        School = "School of Hard Knocks",
        Grade = 12
    },
    new Employee
    {
         Name = "Jack Doe",
         Phone = "987-654-321",
         Department = "Engineering",
         Salary = 10000
    }
};

使用以下设置进行序列化

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    TypeNameHandling = TypeNameHandling.All,
};

输出结果为

{
  "$type": "System.Collections.Generic.List`1[[Person, ConsoleApp2]], System.Private.CoreLib",
  "$values": [
    {
      "$type": "Student, ConsoleApp2",
      "School": "School of Hard Knocks",
      "Grade": 12,
      "Name": "John Doe",
      "Phone": "123-456-789"
    },
    {
      "$type": "Employee, ConsoleApp2",
      "Department": "Engineering",
      "Salary": 10000.0,
      "Name": "Jack Doe",
      "Phone": "987-654-321"
    }
  ]
}

将TypeNameHandling改为Auto后输出结果为

[
  {
    "$type": "Student, ConsoleApp2",
    "School": "School of Hard Knocks",
    "Grade": 12,
    "Name": "John Doe",
    "Phone": "123-456-789"
  },
  {
    "$type": "Employee, ConsoleApp2",
    "Department": "Engineering",
    "Salary": 10000.0,
    "Name": "Jack Doe",
    "Phone": "987-654-321"
  }
]

可以看到TypeNameHandling.All会输出所有的类型名,而TypeNameHandling.Auto只会在可能产生冲突或者有需要的位置添加类型名

接下来,将TypeNameHandling改成None,输出结果为

[
  {
    "School": "School of Hard Knocks",
    "Grade": 12,
    "Name": "John Doe",
    "Phone": "123-456-789"
  },
  {
    "Department": "Engineering",
    "Salary": 10000.0,
    "Name": "Jack Doe",
    "Phone": "987-654-321"
  }
]

使用以下设置进行反序列化

var source = """
    [
      {
        "School": "School of Hard Knocks",
        "Grade": 12,
        "Name": "John Doe",
        "Phone": "123-456-789"
      },
      {
        "Department": "Engineering",
        "Salary": 10000.0,
        "Name": "Jack Doe",
        "Phone": "987-654-321"
      }
    ]    
    """;

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    TypeNameHandling = TypeNameHandling.None,
};

var result = JsonConvert.DeserializeObject<List<Person>>(source, setting);

运行时报错,提示抽象类和接口不能进行反序列化

将TypeNameHandling改为Auto,进行序列化,输出结果

[
  {
    "$type": "Student, ConsoleApp2",
    "School": "School of Hard Knocks",
    "Grade": 12,
    "Name": "John Doe",
    "Phone": "123-456-789"
  },
  {
    "$type": "Employee, ConsoleApp2",
    "Department": "Engineering",
    "Salary": 10000.0,
    "Name": "Jack Doe",
    "Phone": "987-654-321"
  }
]

使用此内容和设置进行反序列化

var source = """
    [
      {
        "$type": "Student, ConsoleApp2",
        "School": "School of Hard Knocks",
        "Grade": 12,
        "Name": "John Doe",
        "Phone": "123-456-789"
      },
      {
        "$type": "Employee, ConsoleApp2",
        "Department": "Engineering",
        "Salary": 10000.0,
        "Name": "Jack Doe",
        "Phone": "987-654-321"
      }
    ]
    """;

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    TypeNameHandling = TypeNameHandling.Auto,
};

var result = JsonConvert.DeserializeObject<List<Person>>(source, setting);
return;

可以看到没有报错,对result进行监视可以看到其内容,成功进行了反序列化

1.6 对象创建策略-ObjectCreationHandling

定义一个类

class Person
{
    public string Name { get; set; }

    public List<string> Hobbies { get; set; }
}

 对其进行实例化

var p = new Person
{
    Name = "John Doe",
    Hobbies = ["Chess", "Tennis"]
};

定义一个JsonSerializerSettings

var setting = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ObjectCreationHandling = ObjectCreationHandling.Auto,
};

对p进行序列后生成

{
  "Name": "John Doe",
  "Hobbies": [
    "Chess",
    "Tennis"
  ]
}

现在修改p的内容为

var p = new Person
{
    Name = "John Doe",
    Hobbies = ["Swimming", "Reading"]
};

定义一个字符串data

var data = """
    {
      "Name": "John Doe",
      "Hobbies": [
        "Chess",
        "Tennis"
      ]
    }
    """;

调用PopulateObject方法

JsonConvert.PopulateObject(json, p, setting);

得到p的结果为

ObjectCreationHandling.Auto使得字符串中的两个元素追加到对象p的集合Hobbies中 

现在将ObjectCreationHandling修改为Replace,再调用方法,得到

ObjectCreationHandling.Replace使得 字符串中的两个元素覆盖了对象p的集合Hobbies中的元素

二、常用特性

代码:

var p = new Person
{
    Name = "Jack",
};

Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented));

class Person
{
    private readonly DateTime CreateTime = DateTime.Now;
    public string Name { get; set; }

    public string Description => $"{Name} Created at {CreateTime}";
}

序列化后生成

{
  "Name": "Jack",
  "Description": "Jack Created at 2024/9/12 20:18:34"
}

2.1 类特性与JsonSerializerSettings

类可以添加特性(包含JsonSerializerSettings中的所有参数),针对整个类生效

 

 2.2 添加标记-JsonProperty

[JsonProperty()]
private readonly DateTime CreateTime = DateTime.Now;

序列后后生成

{
  "CreateTime": "2024-09-12T20:19:40.781696+08:00",
  "Name": "Jack",
  "Description": "Jack Created at 2024/9/12 20:19:40"
}

还可对序列化后的字段名称进行定制

[JsonProperty("Time")]
private readonly DateTime CreateTime = DateTime.Now;

序列化后生成

{
  "Time": "2024-09-12T20:20:12.251123+08:00",
  "Name": "Jack",
  "Description": "Jack Created at 2024/9/12 20:20:12"
}

2.3 忽略-JsonIgnore

[JsonIgnore]
public string Description => $"{Name} Created at {CreateTime}";

序列化后生成

{
  "Time": "2024-09-12T20:22:03.0953351+08:00",
  "Name": "Jack"
}

2.4 成员序列化方式-MemberSerialization

2.4.1 Fields

[JsonObject(MemberSerialization.Fields)]
class Person
{
    private readonly DateTime CreateTime = DateTime.Now;
    public string Name { get; set; }
    public string Description => $"{Name} Created at {CreateTime}";
}

序列化后生成

{
  "CreateTime": "2024-09-12T20:24:55.9249168+08:00",
  "<Name>k__BackingField": "Jack"
}

可以看到只对字段进行序列化

2.4.2 OptIn

[JsonObject(MemberSerialization.OptIn)]
class Person
{
    [JsonProperty]
    private readonly DateTime CreateTime = DateTime.Now;
    public string Name { get; set; }
    public string Description => $"{Name} Created at {CreateTime}";
}

序列后生成

{
  "CreateTime": "2024-09-12T20:26:20.8093154+08:00"
}

只对有特性JsonProperty的成员进行序列化

2.4.3 OptOut

[JsonObject(MemberSerialization.OptOut)]
class Person
{
    private readonly DateTime CreateTime = DateTime.Now;
    public string Name { get; set; }
    public string Description => $"{Name} Created at {CreateTime}";
}

序列后后生成

{
  "Name": "Jack",
  "Description": "Jack Created at 2024/9/12 20:28:07"
}

只要未标记JsonIgnore的属性都将进行序列化

2.4.4 应用场景

var p = new Person
{
    Name = "Jack",
};

Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented));

abstract class Human
{
    public bool IsAlive { get; set; } = true;
}

class Person : Human
{
    private readonly DateTime CreateTime = DateTime.Now;
    public string Name { get; set; }
    public string Description => $"{Name} Created at {CreateTime}";
}

类Person继承自Human,Human中有一个属性IsAlive,序列化后生成

{
  "Name": "Jack",
  "Description": "Jack Created at 2024/9/12 20:30:16",
  "IsAlive": true
}

现在假设生成的Json中不需要IsAlive字段,Human又不可修改(比如说来自标准库或第三方库),此时就可以用到MemberSerialization特性,修改代码

abstract class Human
{
    public bool IsAlive { get; set; } = true;
}

[JsonObject(MemberSerialization.OptIn)]
class Person : Human
{
    [JsonProperty]
    private readonly DateTime CreateTime = DateTime.Now;
    [JsonProperty]
    public string Name { get; set; }
    [JsonProperty]
    public string Description => $"{Name} Created at {CreateTime}";
}

序列化后生成

{
  "CreateTime": "2024-09-12T20:33:57.3095584+08:00",
  "Name": "Jack",
  "Description": "Jack Created at 2024/9/12 20:33:57"
}

三、 转换器-JsonConverter

3.1 枚举-字符串-StringEnumConverter

var p = new Person
{
    Name = "Jack",
    Gender = Gender.Male
};

var json = JsonConvert.SerializeObject(p, Formatting.Indented);

Console.WriteLine(json);

class Person 
{
    public string Name { get; set; }

    public Gender Gender { get; set; }
}

enum Gender
{
    Male,
    Female,
}

序列后生成

{
  "Name": "Jack",
  "Gender": 0
}

添加特性

[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }

序列后生成

{
  "Name": "Jack",
  "Gender": "Male"
}

3.2 自定义转换器1


var p = new Person
{
    Name = "Jack",
    Birthday = new DateTime(1990, 1, 1),
};

var json = JsonConvert.SerializeObject(p, Formatting.Indented);

Console.WriteLine(json);

class Person 
{
    public string Name { get; set; }

    public DateTime Birthday { get; set; }
}

序列化后生成

{
  "Name": "Jack",
  "Birthday": "1990-01-01T00:00:00"
}

如果生成的Birthday字段只需要年月日,可修改代码为


var p = new Person
{
    Name = "Jack",
    Birthday = new DateTime(1990, 1, 1),
};

var json = JsonConvert.SerializeObject(p, Formatting.Indented);

Console.WriteLine(json);

class Person 
{
    public string Name { get; set; }

    [JsonConverter(typeof(MyDateTimeConverter))]
    public DateTime Birthday { get; set; }
}

class MyDateTimeConverter : IsoDateTimeConverter
{
    public MyDateTimeConverter()
    {
        DateTimeFormat = "yyyy-MM-dd";
    }
}

序列化后生成

{
  "Name": "Jack",
  "Birthday": "1990-01-01"
}

3.3 自定义转换器2

var p = new Person
{
    Name = "Jack",
    Age = new IntWrapper(30)
};

var json = JsonConvert.SerializeObject(p, Formatting.Indented);

Console.WriteLine(json);

class Person 
{
    public string Name { get; set; }

    public IntWrapper Age { get; set; }
}

class IntWrapper 
{
    public IntWrapper(int value)
    {
        Value = value;
    }
    public int Value { get; set; }
}

Age属性进行了封装,序列化后生成

{
  "Name": "Jack",
  "Age": {
    "Value": 30
  }
}

如果想生成"Age":30,可以自定义转换器,如下

var p = new Person
{
    Name = "Jack",
    Age = new IntWrapper(30)
};

var json = JsonConvert.SerializeObject(p, Formatting.Indented);

Console.WriteLine(json);

class Person 
{
    public string Name { get; set; }

    [JsonConverter(typeof(IntWrapperConverter))]
    public IntWrapper Age { get; set; }
}

class IntWrapper 
{
    public IntWrapper(int value)
    {
        Value = value;
    }
    public int Value { get; set; }
}

class IntWrapperConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(IntWrapper).IsAssignableFrom(objectType);
    }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        return new IntWrapper(Convert.ToInt32(reader.Value));
    }

    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, ((IntWrapper)value).Value);
    }
}

序列后生成

{
  "Name": "Jack",
  "Age": 30
}

四、回调函数

4.1 序列化中

[OnSerializing]
internal void OnSerializingMethod(StreamingContext context)
{

}

4.2 序列化后 

[OnSerialized]
internal void OnSerializedMethod(StreamingContext context)
{
    
}

4.3 反序列化中

[OnDeserializing]
internal void OnDeserializingMethod(StreamingContext context)
{
    
}

 4.4 反序列后

[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
   
}

4.5 例程 

var p = new Person
{
    Name = "Jack",
    Age = 30,
};

var json = JsonConvert.SerializeObject(p, Formatting.Indented);
Console.WriteLine(json);

var result = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine(result);

class Person 
{
    public string Name { get; set; }
    public int Age { get; set; }


    [OnSerializing]
    internal void OnSerializingMethod(StreamingContext context)
    {
        Console.WriteLine("开始序列化.");
    }

    [OnSerialized]
    internal void OnSerializedMethod(StreamingContext context)
    {
        Console.WriteLine("序列化结束.");
    }

    [OnDeserializing]
    internal void OnDeserializingMethod(StreamingContext context)
    {
        Console.WriteLine("开始反序列化.");
    }

    [OnDeserialized]
    internal void OnDeserializedMethod(StreamingContext context)
    {
        Console.WriteLine("反序列化结束.");
    }
}

class IntWrapper 
{
    public IntWrapper(int value)
    {
        Value = value;
    }
    public int Value { get; set; }
}

输出结果

开始序列化.
序列化结束.
{
  "Name": "Jack",
  "Age": 30
}
开始反序列化.
反序列化结束.
Person

五、未知对象的反序列化

var json = """
    {  
      "user": {  
        "id": 1,  
        "name": "John Doe",  
        "contact": {  
          "email": "john.doe@example.com",  
          "phone": {  
            "home": "123-456-7890",  
            "mobile": "987-654-3210"  
          }  
        },  
        "address": {  
          "street": "123 Main St",  
          "city": "Anytown",  
          "postalCode": {  
            "code": "12345",  
            "extension": "6789"  
          }  
        }  
      }  
    }  
    """;

var obj = JObject.Parse(json);;
Console.WriteLine(obj["user"]["contact"]["email"]);

输出结果

john.doe@example.com

六、未定义类的序列化


var obj = new JObject(
    new JProperty(
        "user1",
        new JObject(
            new JProperty("id", 1),
            new JProperty("name", "John Doe"),
            new JProperty(
                "contact",  
                new JObject(
                    new JProperty("email", "john.doe@example.com"),
                    new JProperty(
                        "phone",
                        new JObject(
                            new JProperty("home", "123-456-7890"),
                            new JProperty("mobile", "987-654-3210"))
                        )
                    )
                )
            )
        )
    );

Console.WriteLine(obj.ToString());

输出结果

{
  "user1": {
    "id": 1,
    "name": "John Doe",
    "contact": {
      "email": "john.doe@example.com",
      "phone": {
        "home": "123-456-7890",
        "mobile": "987-654-3210"
      }
    }
  }
}

七、快速生成json字符串

使用匿名类

var obj = new
{
    Name = "John",
    Age = 30,
    Class = 10,
};

Console.WriteLine(JsonConvert.SerializeObject(obj, Formatting.Indented));

输出结果

{
  "Name": "John",
  "Age": 30,
  "Class": 10
}

八、 Bson

8.1存取效率

1.二进制格式:BSON 是一种二进制格式,解析速度通常比 JSON 的文本格式更快。这是因为解析二进制数据通常比解析文本数据更高效。
2.数据类型支持:BSON 支持更多的数据类型(例如日期、浮点数、整数等),而 JSON 则只有字符串、数字、布尔值和数组等基础类型。对于复杂的数据结构,BSON 可以直接存储和处理,而 JSON 可能需要额外的编码和解码操作。
3.内嵌文档和数组:BSON 允许文档和数组直接嵌套在二进制数据中,无需像 JSON 那样进行字符编码和解码,因而可以加快数据存取速度。


8.2 空间利用率

1.数据类型标识:BSON 使用数据类型标识符来明确每个字段的数据类型,从而避免了 JSON 中冗余的字符(例如引号和冒号等)。这在一定程度上可以减少存储空间。

2.字符串长度前缀:BSON 存储字符串时会在前面加上长度前缀,使得读取和写入字符串时不需要逐字符解析,可以提高效率并减少空间开销。

3.压缩:虽然 BSON 本身不是压缩格式,但其二进制表示形式在某些情况下可能比 JSON 更紧凑。此外,BSON可以与其他压缩算法结合使用,以进一步减少存储空间。

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

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

相关文章

流媒体之RTMP协议(其四)

欢迎诸位来阅读在下的博文~ 在这里&#xff0c;在下会不定期发表一些浅薄的知识和经验&#xff0c;望诸位能与在下多多交流&#xff0c;共同努力&#xff01; 江山如画&#xff0c;客心如若&#xff0c;欢迎到访&#xff0c;一展风采 文章目录 前期博客参考书籍一、PTMP简介二…

MyBatis的配置文件详解

01-MyBatis的配置文件详解 创建的接口和xml文件的名字最好写一样的要不然会出问题,然后和接口名相同的xml文件在resources下创建个和接口相同文件夹把xml文件放进去,而且resources下的创建的文件夹需要一级一级的创键,比如:cn创建完,创建tulingxue,然后再创建mapper文件夹才行…

python绘制月亮

import matplotlib import matplotlib.pyplot as plt import moviepy.editor as mpymatplotlib.rcParams[font.family] SimHei# 坐标列表 positions [(0, 0), (1 / 4, 1 / 4), (1 / 3, 1 / 4), (1 / 2, 1 / 4), (2 / 3, 1 / 4),(3 / 4, 1 / 4), (1, 1 / 4), (5 / 4, 1 / 4), …

C++中的容器——vector

1. vector的介绍 vector&#xff1a;vector的底层实际上就是一个数组&#xff08;也称为顺序表&#xff09;&#xff0c;数据是连续存储在数组中的&#xff0c;因此vector是可以使用下标来进行访问的&#xff0c;但是它的大小并不是像数组一样是固定的&#xff0c;而是可以动态…

漳州自闭症寄宿学校,孩子的快乐学习乐园

在温暖而包容的南方都市——广州&#xff0c;藏着一所特别的学校&#xff0c;它以爱为名&#xff0c;为自闭症儿童编织了一个充满希望的未来&#xff0c;这就是星贝育园自闭症儿童寄宿制学校。这里&#xff0c;不仅是知识的殿堂&#xff0c;更是孩子们心灵得以自由飞翔、快乐学…

削峰+限流:秒杀场景下的高并发写请求解决方案

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! 哈喽,大家好!我是小米,一个29岁、活泼积极、热衷分享技术的码农。今天和大家聊一聊应对高并发的写请求这个主题,尤其是在大促、秒杀这种场景下,系统…

【Docker Nexus3】maven 私库

1.部署环境 window 11 x64Docker Desktop 4.34.1 (166053) Docker Engine v27.2.0 1.1.Docker 镜像源 1.1.1.Docker Engine 配置 {"builder": {"features": {"buildkit": true},"gc": {"defaultKeepStorage": "32…

微服务_入门2

文章目录 一、Feign二、Gateway服务网关 一、Feign 来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; 代码可读性差&#xff0c;编程体验不统一&#xff08;url需要自己在代码中拼写出来&#xff09;参数复杂URL难以维护&#xff0…

Weapons Armor PBR Pack 1 - Fantasy RPG 武器护甲游戏模型

武器和护甲包#1有30个武器和护甲,每个对象都有默认外观,大多数都有网格变形和Substance Painter源文件,用于自定义纹理。 无限PBR&我的哲学 Infinity PBR是十几位艺术家的作品,他们都在做自己最擅长的事情。我想为独立游戏开发者制作最通用、最优质的资产,按照我希望的…

鸿蒙开发之ArkUI 界面篇 四

文字溢出处理、省略号、文字太长的处理用textOverflow&#xff0c;语法格式是&#xff1a; Text.textOverflow({ overflow: TextOverflow; }) 尤其注意&#xff0c;单独的这个设置没有效果&#xff0c;需要和maxLines一起使用才有效果 Text("男频男频男频男频男频男频男…

好代码网同款wordpress主题,完全开源无加密可二开

这个其实就是好代码网站的早期整站打包代码&#xff0c;当时售价198的&#xff0c;现在里面的部分数据已经过期了&#xff0c;只能展示效果&#xff0c;没法下载。所以就只当做主题分享给大家使用。 资源下载类网站目前还是红利期&#xff0c;搞个特价主机和域名&#xff0c;再…

代码随想录Day 46|动态规划完结,leetcode题目:647. 回文子串、516.最长回文子序列

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 题目题目一&#xff1a;647. 回文子串解题思路&#xff1a;暴力解法动态规划 题目二&#xff1a; 516.最长回文子序列解题思路&#xff1a; 动态规划总结动规五部曲基础概念常见问题类型 动态规划…

算法设计与分析(循环赛日程表

目录 循环赛日程表算法介绍代码实现注意事项 小结&#xff1a; 循环赛日程表 在组织和安排体育赛事时&#xff0c;循环赛日程表的编制是一项重要且复杂的任务。循环赛&#xff0c;即每个参赛队伍都要与其他所有队伍进行一场比赛&#xff0c;确保比赛的公平性和所有队伍之间的平…

Linux下的CAN通讯

CAN总线 CAN总线简介 CAN&#xff08;Controller Area Network&#xff09;总线是一种多主从式 <font color red>异步半双工串行 </font> 通信总线&#xff0c;它最早由Bosch公司开发&#xff0c;用于汽车电子系统。CAN总线具有以下特点&#xff1a; 多主从式&a…

JAVA基础面试题总结(十五)——设计模式

面试专题-设计模式 前言 在平时的开发中&#xff0c;涉及到设计模式的有两块内容&#xff0c;第一个是我们平时使用的框架&#xff08;比如spring、mybatis等&#xff09;&#xff0c;第二个是我们自己开发业务使用的设计模式。 面试官一般比较关心的是你在开发过程中&#…

面向对象程序设计(C++)———多态

1.认识多态 多态(polymorphism)的概念&#xff1a;通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运⾏时多态(动态多态)&#xff0c;这⾥我们重点讲运⾏时多态&#xff0c;编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)主要就是我们…

一分钟掌握 Excel VBA 技巧,轻松批量生成工资条,提高工作效率!

可能大家忽视了一点&#xff0c;Excel是我们日常办公中使用最多的工具&#xff0c;所以&#xff0c;学好Excel并加以运用&#xff0c;一定能提升你的工作效率&#xff0c;比如Excel VBA可以用代码实现自动化办公&#xff0c;下面举一个Excel VBA批量生成工资条的办公小案例。 …

swagger新玩法 - 让你API接口开发原地起飞

作为Java后台接口开发人员&#xff0c;无论对对接方是前端还是第三方&#xff0c;很多时候我们在文档和代码两头都需要费心&#xff0c;而做到自动的同步将会非常省心。本教程将带你领略下如何借助swagger官方提供的新玩法&#xff0c;让你的API接口开发原地起飞&#xff0c;甚…

34.贪心算法1

0.贪心算法 1.柠檬水找零&#xff08;easy&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 题目解析 算法原理 代码 class Solution {public boolean lemonadeChange(int[] bills) {int five 0, ten 0;for (int x : bills) {if (x 5) // 5 元&#xff1a;直接收下…

4. Python之运算符

一. Python运算符 常用的运算符有&#xff1a;算述运算符&#xff0c;赋值运算符&#xff0c;比较运算述&#xff0c;逻辑运算符&#xff0c;位运算符等等。 1. 算述运算符 用于处理四则运算的符号&#xff0c;主要有&#xff1a; 运算符描述加法-减法*乘法/除法//整除%取余…