当前位置: 首页 > news >正文

一个Entity Framework Core的性能优化案例

概要

本文提供一个EF Core的优化案例,主要介绍一些EF Core常用的优化方法,以及在优化过程中,出现性能反复的时候的解决方法,并澄清一些对优化概念的误解,例如AsNoTracking并不包治百病。

本文使用的是Dotnet 6.0和EF Core 7.0。

代码及实现

背景介绍

本文主要使用一个图书和作者的案例,用于介绍优化过程。

  • 一个作者Author有多本自己写的的图书Book
  • 一本图书Book有一个发行商Publisher
  • 一个作者Author是一个系统用户User
  • 一个系统用户User有多个角色Role

本实例中Author表和Book数据量较大,记录数量全部过万条,其它数据表记录大概都是几十或几百条。具体实体类定义请见附录。

查询需求

我们需要查找写书最多的前两名作家,该作家需要年龄在20岁以上,国籍是法国。需要他们的FirstName, LastName, Email,UserName以及在1900年以前他们发行的图书信息,包括书名Name和发行日期Published。

基本优化思路

本人做EF Core的复杂查询优化,并不推荐直接查看生成的SQL代码,我习惯按照如下方式进行:

首先,进行EF的LINQ代码检查(初筛),找到明显的错误。

  1. 查看代码中是否有基本错误,主要针对全表载入的问题。例如EF需要每一步的LINQ扩展方法的返回值都是IQueryable类型,不能有IEnumerable类型;
  2. 查看是否有不需要的栏位;
  3. 根据情况决定是否加AsNoTracking,注意这个东西有时候加了也没用;

其次,找到数据量较大的表,进行代码整理和针对大数据表的优化(精细化调整)

  1. 在操作大数据表时候,先要进行基本的过滤;
  2. 投影操作Select应该放到排序操作后面;
  3. 减少返回值数量,推荐进行分页操作;

本人推荐一旦出现性能反复的时候或者代码整体基本完成的时候,再去查看生成的SQL代码。

初始查询代码

public  List<AuthorWeb> GetAuthors() {using var dbContext = new AppDbContext();var authors = dbContext.Authors.Include(x => x.User).ThenInclude(x => x.UserRoles).ThenInclude(x => x.Role).Include(x => x.Books).ThenInclude(x => x.Publisher).ToList().Select(x => new AuthorWeb{UserCreated = x.User.Created,UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,UserId = x.User.Id,RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{Id = y.Id,Name = y.Name,Published = y.Published,ISBN = y.ISBN,PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,AuthorNickName = x.NickName,Id = x.Id}).ToList().Where(x => x.AuthorCountry == "France" && x.AuthorAge == 20).ToList();var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in orderedAuthors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}

Benchmark测试后,系统资源使用情况如下:

在这里插入图片描述

代码性能非常差,内存消耗很大,一次执行就要消耗190MB,执行时间超过2s。如果是放到WebAPI里面调用,用户会有明显的卡顿感觉;如果面临高并发的情况,很可得会造成服务器资源紧张,返回各种500错误。

优化代码

初筛

按照我们的优化思路,在查看上面的代码后,发现一个严重的问题。

虽然每次LINQ查询返回都是IQueryable类型,但是源码中有多个ToList(),尤其是第一个,它的意思是将Author, Book,User,Role,Publisher等多个数据表的数据全部载入,前面已经说了,Author, Book两张表的数据量很大,必然影响性能。

我们需要删除前面多余的ToList(),只保留最后的即可。请参考附录中的方法GetAuthors_RemoveToList()。

在GetAuthors_RemoveToList()基础上,对照用户的需求,发现查询结果中包含了Role相关的信息和很多Id信息,但是查询结果并不需要这些,因此必须删掉。请参考附录中的方法GetAuthorsOptimized_RemoveColumn()

在GetAuthorsOptimized_RemoveColumn的基础上,我们再加入AsNoTracking方法。请参考附录中的方法GetAuthorsOptimized_AsNoTracking()

我们在Benchmark中,测试上面提到的三个方法,直接结果如下:

在这里插入图片描述

从Benchmark的测试结果上看,删除多余ToList方法和删除多余的栏位,确实带来了性能的大幅提升。

但是增加AsNoTracking,性能提反而下降了一点。这也说明了AsNoTracking并不是适用所有场景。Select投影操作生成的AuthorWeb对像,并不是EF管理的,与DbContext无关,它只是作为前端API的返回值。相当于EF做了没有用的事,所以性能略有下降。

代码进一步调整

初筛阶段完成后,下面对代码进一步整理

下面Take和Order操作可以并入基本的查询中,Take可以帮助我们减少返回值的数量。请见 GetAuthorsOptimized_ChangeOrder()方法。

var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();

在GetAuthorsOptimized_ChangeOrder基础上,对于dbContext.Authors,Author是一张数据量很大的表,我们需要在其进行联表操作前,先过滤掉不需要的内容,所以我们可以把Where前提,还有就是将排序操作放到投影的Select前面完成。请见 GetAuthorsOptimized_ChangeOrder方法。

上面的两个优化方法的执行结果如下:

在这里插入图片描述
可以看到性略能有提升。

下面我们为了进一步提升性能,可以查看一下生成的SQL代码,看看是否还有优化的空间。

GetAuthorsOptimized_ChangeOrder方法生成的SQL如下:

      SELECT [u].[FirstName], [u].[LastName], [u].[Email], [u].[UserName], [t].[
BooksCount], [t].[Id], [u].[Id], [b].[Name], [b].[Published], [b].[Id], [t].[Age
], [t].[Country]FROM (SELECT TOP(@__p_0) [a].[Id], [a].[Age], [a].[BooksCount], [a].[Country
], [a].[UserId]FROM [Authors] AS [a]WHERE [a].[Country] = N'France' AND [a].[Age] >= 20ORDER BY [a].[BooksCount] DESC) AS [t]INNER JOIN [Users] AS [u] ON [t].[UserId] = [u].[Id]LEFT JOIN [Books] AS [b] ON [t].[Id] = [b].[AuthorId]ORDER BY [t].[BooksCount] DESC, [t].[Id], [u].[Id]

从生成SQL来看,Author表在使用之前过滤掉了相关的内容,但是直接Left Join了[Books]这个大表。我们可以按照前面提到的1900年以前的查询要求,在左联之前先过滤一下,请参考 GetAuthorsOptimized_SelectFilter方法。

该方法执行后,生成的SQL如下:

      SELECT [u].[FirstName], [u].[LastName], [u].[Email], [u].[UserName], [t].[
BooksCount], [t].[Id], [u].[Id], [t0].[Name], [t0].[Published], [t0].[Id], [t].[
Age], [t].[Country]FROM (SELECT TOP(@__p_1) [a].[Id], [a].[Age], [a].[BooksCount], [a].[Country
], [a].[UserId]FROM [Authors] AS [a]WHERE [a].[Country] = N'France' AND [a].[Age] >= 20ORDER BY [a].[BooksCount] DESC) AS [t]INNER JOIN [Users] AS [u] ON [t].[UserId] = [u].[Id]LEFT JOIN (SELECT [b].[Name], [b].[Published], [b].[Id], [b].[AuthorId]FROM [Books] AS [b]WHERE [b].[Published] < @__date_0) AS [t0] ON [t].[Id] = [t0].[AuthorId]ORDER BY [t].[BooksCount] DESC, [t].[Id], [u].[Id]

在左联之前,确实进行了过滤,该方法的性能测试如下:

在这里插入图片描述
在避免Book表直接进行左联后,性能有所提升。

最后一个优化点,是在EF Core 5.0里面提供了带Filter功能的Include方法,也可以用于本案例的优化,但是该特性但是存在一些局限性,具体请参考EF Core中带过滤器参数的Include方法

但是此方法又涉及了将IQueryable转换成IEnumerable的操作,最后要将生成的Author对象全部转换成AuthorWeb对象。代码过于繁琐,而且带来的性能提升也不明显。因此放弃这个点。

dbContext.Authors.AsNoTracking().Include(x => x.Books.Where(b => b.Published < date))......

结论

从这个优化过程来看,其实对性能提升最大的贡献就是删除多余的ToList(),避免全表载入和删除不需要的栏位两项。其它所谓更精细的优化,性能提升有限。

附录

实体类定义

 public class Author{public int Id { get; set; }public int Age { get; set; }public string Country { get; set; }public int BooksCount { get; set; }public string NickName { get; set; }[ForeignKey("UserId")]public User User { get; set; }public int UserId { get; set; }public virtual List<Book> Books { get; set; } = new List<Book>();}public class Book{public int Id { get; set; }public string Name { get; set; }[ForeignKey("AuthorId")]public Author Author { get; set; }public int AuthorId { get; set; }public DateTime Published { get; set; }public string ISBN { get; set; }[ForeignKey("PublisherId")]public Publisher Publisher { get; set; }public int PublisherId { get; set; }}
public class Publisher{public int Id { get; set; }public string Name { get; set; }public DateTime Established { get; set; }}public class User{public int Id { get; set; }public string FirstName { get; set; }public string LastName { get; set; }public string UserName { get; set; }public string Email { get; set; }public virtual List<UserRole> UserRoles { get; set; } = new List<UserRole>();public DateTime Created { get; set; }public bool EmailConfirmed { get; set; }public DateTime LastActivity { get; set; }}public class Role{public int Id { get; set; }public virtual List<UserRole> UserRoles { get; set; } = new List<UserRole>();public string Name { get; set; }}public  class AuthorWeb{public DateTime UserCreated { get; set; }public bool UserEmailConfirmed { get; set; }public string UserFirstName { get; set; }public DateTime UserLastActivity { get; set; }public string UserLastName { get; set; }public string UserEmail { get; set; }public string UserName { get; set; }public int UserId { get; set; }public int AuthorId { get; set; }public int Id { get; set; }public int RoleId { get; set; }public int BooksCount { get; set; }public List<BookWeb> AllBooks { get; set; }public int AuthorAge { get; set; }public string AuthorCountry { get; set; }public string AuthorNickName { get; set; }}public class BookWeb{public int Id { get; set; }public string Name { get; set; }public DateTime Published { get; set; }public int PublishedYear { get; set; }public string PublisherName { get; set; }public string ISBN { get; set; }}

优化方法

[Benchmark]
public  List<AuthorWeb> GetAuthors() {using var dbContext = new AppDbContext();var authors = dbContext.Authors.Include(x => x.User).ThenInclude(x => x.UserRoles).ThenInclude(x => x.Role).Include(x => x.Books).ThenInclude(x => x.Publisher).ToList().Select(x => new AuthorWeb{UserCreated = x.User.Created,UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,UserId = x.User.Id,RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{Id = y.Id,Name = y.Name,Published = y.Published,ISBN = y.ISBN,PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,AuthorNickName = x.NickName,Id = x.Id}).ToList().Where(x => x.AuthorCountry == "France" && x.AuthorAge >= 20).ToList();var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in orderedAuthors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}[Benchmark]public List<AuthorWeb> GetAuthors_RemoveToList(){using var dbContext = new AppDbContext();var authors = dbContext.Authors.Include(x => x.User).ThenInclude(x => x.UserRoles).ThenInclude(x => x.Role).Include(x => x.Books).ThenInclude(x => x.Publisher)//  .ToList().Select(x => new AuthorWeb{UserCreated = x.User.Created,UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,UserId = x.User.Id,RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{Id = y.Id,Name = y.Name,Published = y.Published,ISBN = y.ISBN,PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,AuthorNickName = x.NickName,Id = x.Id})// .ToList().Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20).ToList();var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in orderedAuthors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}[Benchmark]public  List<AuthorWeb> GetAuthorsOptimized_RemoveColumn(){using var dbContext = new AppDbContext();var authors = dbContext.Authors//   .Include(x => x.User)//.ThenInclude(x => x.UserRoles)//   .ThenInclude(x => x.Role)//   .Include(x => x.Books)//     .ThenInclude(x => x.Publisher).Select(x => new AuthorWeb{//   UserCreated = x.User.Created,//  UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,//   UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,//     UserId = x.User.Id,//     RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{//    Id = y.Id,Name = y.Name,Published = y.Published,//       ISBN = y.ISBN,//         PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,AuthorNickName = x.NickName,//   Id = x.Id}).Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20).ToList();var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().Take(2).ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in orderedAuthors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}[Benchmark]public List<AuthorWeb> GetAuthorsOptimized_AsNoTracking(){using var dbContext = new AppDbContext();var authors = dbContext.Authors.AsNoTracking()// .Include(x => x.User)//   .ThenInclude(x => x.UserRoles)//   .ThenInclude(x => x.Role)//    .Include(x => x.Books)//   .ThenInclude(x => x.Publisher).Select(x => new AuthorWeb{//UserCreated = x.User.Created,//    UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,// UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,//  UserId = x.User.Id,//RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{// Id = y.Id,Name = y.Name,Published = y.Published,//ISBN = y.ISBN,//PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,//AuthorNickName = x.NickName,Id = x.Id}).Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20).ToList();var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in authors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}[Benchmark]public List<AuthorWeb> GetAuthorsOptimized_Take_Order(){using var dbContext = new AppDbContext();var authors = dbContext.Authors.AsNoTracking().Select(x => new AuthorWeb{UserFirstName = x.User.FirstName,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{Name = y.Name,Published = y.Published,}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,AuthorNickName = x.NickName,}).Where(x => x.AuthorCountry == "France" && x.AuthorAge >=20).OrderByDescending(x => x.BooksCount).Take(2).ToList();// var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in authors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}[Benchmark]public List<AuthorWeb> GetAuthorsOptimized_ChangeOrder(){using var dbContext = new AppDbContext();var authors = dbContext.Authors.AsNoTracking().Where(x => x.Country == "France" && x.Age >=20).OrderByDescending(x => x.BooksCount)// .Include(x => x.User)//   .ThenInclude(x => x.UserRoles)//   .ThenInclude(x => x.Role)//    .Include(x => x.Books)//   .ThenInclude(x => x.Publisher).Select(x => new AuthorWeb{//UserCreated = x.User.Created,//    UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,// UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,//  UserId = x.User.Id,//RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Select(y => new BookWeb{// Id = y.Id,Name = y.Name,Published = y.Published,//ISBN = y.ISBN,//PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,//AuthorNickName = x.NickName,Id = x.Id})                                     .Take(2).ToList();// var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();List<AuthorWeb> finalAuthors = new List<AuthorWeb>();foreach (var author in authors){List<BookWeb> books = new List<BookWeb>();var allBooks = author.AllBooks;foreach (var book in allBooks){if (book.Published.Year < 1900){book.PublishedYear = book.Published.Year;books.Add(book);}}author.AllBooks = books;finalAuthors.Add(author);}return finalAuthors;}//  [Benchmark]public List<AuthorWeb> GetAuthorsOptimized_IncludeFilter(){using var dbContext = new AppDbContext();var date = new DateTime(1900, 1, 1);var authors = dbContext.Authors.AsNoTracking().Include(x => x.Books.Where(b => b.Published < date)).Include(x => x.User)// .IncludeFilter(x =>x.Books.Where(b =>b.Published.Year < 1900)).Where(x => x.Country == "France" && x.Age >=20).OrderByDescending(x => x.BooksCount)//   .ThenInclude(x => x.UserRoles)//   .ThenInclude(x => x.Role)//    .Include(x => x.Books)//   .ThenInclude(x => x.Publisher).Take(2).ToList();// var orderedAuthors = authors.OrderByDescending(x => x.BooksCount).ToList().ToList();var authorList = authors.AsEnumerable().Select(x => new AuthorWeb{//UserCreated = x.User.Created,//    UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,// UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,//  UserId = x.User.Id,//RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books//    .Where(b => b.Published < date).Select(y => new BookWeb{// Id = y.Id,Name = y.Name,Published = y.Published,//ISBN = y.ISBN,//PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,//AuthorNickName = x.NickName,//    Id = x.Id}).ToList();return authorList;}[Benchmark]public List<AuthorWeb> GetAuthorsOptimized_SelectFilter(){using var dbContext = new AppDbContext();var date = new DateTime(1900, 1, 1);var authors = dbContext.Authors.AsNoTracking().Include(x => x.Books.Where(b => b.Published < date)).Where(x => x.Country == "France" && x.Age >=20).OrderByDescending(x => x.BooksCount).Select(x => new AuthorWeb{//UserCreated = x.User.Created,//    UserEmailConfirmed = x.User.EmailConfirmed,UserFirstName = x.User.FirstName,// UserLastActivity = x.User.LastActivity,UserLastName = x.User.LastName,UserEmail = x.User.Email,UserName = x.User.UserName,//  UserId = x.User.Id,//RoleId = x.User.UserRoles.FirstOrDefault(y => y.UserId == x.UserId).RoleId,BooksCount = x.BooksCount,AllBooks = x.Books.Where(b => b.Published < date).Select(y => new BookWeb{// Id = y.Id,Name = y.Name,Published = y.Published,//ISBN = y.ISBN,//PublisherName = y.Publisher.Name}).ToList(),AuthorAge = x.Age,AuthorCountry = x.Country,//AuthorNickName = x.NickName,//    Id = x.Id}).Take(2).ToList();return authors;}

相关文章:

一个Entity Framework Core的性能优化案例

概要 本文提供一个EF Core的优化案例&#xff0c;主要介绍一些EF Core常用的优化方法&#xff0c;以及在优化过程中&#xff0c;出现性能反复的时候的解决方法&#xff0c;并澄清一些对优化概念的误解&#xff0c;例如AsNoTracking并不包治百病。 本文使用的是Dotnet 6.0和EF…...

【Python 千题 —— 基础篇】列表排序

题目描述 题目描述 给定一个包含无序数字的列表&#xff0c;请将列表中的数字按从小到大的顺序排列&#xff0c;并输出排序后的列表。 输入描述 输入一个包含无序数字的列表。 输出描述 程序将对列表中的数字进行排序&#xff0c;并输出排序后的列表。 示例 示例 ① 1…...

leetcode26:删除有序数组中的重复项

leetcode26&#xff1a;删除有序数组中的重复项 方案一&#xff1a;依次遍历&#xff0c;如果不符合条件则冒泡交换到最后一个位置。o(n^2),结果超时 #include <algorithm> #include <iostream>using namespace std; class Solution { public:int removeDuplicat…...

[FSCTF 2023] web题解

文章目录 源码&#xff01;启动!webshell是啥捏细狗2.0ez_php1Hello,youEZ_eval巴巴托斯&#xff01; 源码&#xff01;启动! 打开题目&#xff0c;发现右键被禁了 直接ctrlu查看源码得到flag webshell是啥捏 源码 <?php highlight_file(__FILE__); $&#x1f600;&qu…...

linux查看内存的方式

1、显示内存状态:free -h  以合适的单位显示内存使用情况&#xff0c;最大为三位数&#xff0c;自动计算对应的单位值。单位有&#xff1a; B bytes K kilos M megas G gigas T teras $free -htotal used free shared buff/cache available Me…...

Python 编写 Flink 应用程序经验记录(Flink1.17.1)

目录 官方API文档 提交作业到集群运行 官方示例 环境 编写一个 Flink Python Table API 程序 执行一个 Flink Python Table API 程序 实例处理Kafka后入库到Mysql 下载依赖 flink-kafka jar 读取kafka数据 写入mysql数据 flink-mysql jar 官方API文档 https://nigh…...

如何 通过使用优先级提示,来控制所有网页资源加载顺序

当你打开浏览器的网络标签时&#xff0c;你会看到大量的活动。资源正在下载&#xff0c;信息正在提交&#xff0c;事件正在记录&#xff0c;等等。 由于有太多的活动&#xff0c;有效地管理这些流量的优先级变得至关重要。带宽争用是真实存在的&#xff0c;当所有请求同时触发时…...

10月25日,每日信息差

今天是2023年10月26日&#xff0c;以下是为您准备的14条信息差 第一、百世集团牵头成立全国智慧物流与供应链行业产教融合共同体在杭州正式成立&#xff0c;该共同体由百世集团、浙江工商大学、浙江经济职业技术学院共同牵头 第二、问界M9预定量突破15000台 第三、前三季度我…...

泛微OA之获取每月固定日期

文章目录 1.需求及效果1.1需求1.2效果 2. 思路3. 实现 1.需求及效果 1.1需求 需要获取每个月的7号作为需发布日期&#xff0c;需要自动填充1.2效果 自动获取每个月的七号2. 思路 1.功能并不复杂&#xff0c;可以用泛微前端自带的插入代码块的功能来实现。 2.将这需要赋值的…...

Dataworks API:调取 MC 项目下所有表单

文章目录 前言Dataworks API 文档解读GetMetaDBTableList 接口文档 API 调试在线调试本地调试运行环境账密问题请求数据进一步处理 小结 前言 最近&#xff0c;我需要对公司的数据资产进行梳理&#xff0c;这其中便包括了Dataworks各个项目下的表单。这些表单&#xff0c;作为…...

Node编写更新用户头像接口

目录 定义路由和处理函数 验证表单数据 ​编辑 实现更新用户头像的功能 定义路由和处理函数 向外共享定义的更新用户头像处理函数 // 更新用户头像的处理函数 exports.updateAvatar (req, res) > {res.send(更新成功) } 定义更新用户头像路由 // 更新用户头像的路由…...

MySQL3:MySQL中一条更新SQL是如何执行的?

MySQL3&#xff1a;MySQL中一条更新SQL是如何执行的&#xff1f; MySQL中一条更新SQL是如何执行的&#xff1f;1.Buffer Pool缓冲池2.Redo logredo log作用Redo log文件位置redo log为什么是2个&#xff1f; 3.Undo log4.更新过程5.InnoDB官网架构InnoDB架构-内存结构①Buffer …...

p5.js map映射

本文简介 带尬猴&#xff0c;我嗨德育处主任 p5.js 为开发者提供了很多有用的方法&#xff0c;这些方法实现起来可能不难&#xff0c;但却非常实用&#xff0c;能大大减少我们的开发时间。 本文将通过举例说明的方式来讲解 映射 map() 方法。 什么是映射 从 p5.js 文档 中可…...

idea提交代码冲突后,代码意外消失解决办法

敲了大半天的代码&#xff0c;解决冲突后&#xff0c;直接消失了当时慌的一批CCCCC 右击项目Local History ----show History 找到最近提交的内容右击选择Revert,代码全回来了...

爬虫批量下载科研论文(SciHub)

系列文章目录 利用 eutils 实现自动下载序列文件 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、获取文献信息二、下载文献PDF文件参考 前言 大家好✨&#xff0c;这里是bio&#x1f996;。…...

explain查询sql执行计划返回的字段的详细说明

当使用EXPLAIN命令查看SQL语句的执行计划时&#xff0c;会返回一张表格&#xff0c;其中包含了该SQL语句的执行计划。下面是每个字段的详细分析&#xff1a; id&#xff1a;执行计划的唯一标识符。如果查询中有子查询&#xff0c;每个子查询都会有一个唯一的ID。在执行计划中&a…...

讯飞输入法13.0发布,推出行业首款生成式AI输入法

&#x1f989; AI新闻 &#x1f680; 讯飞输入法13.0发布&#xff0c;推出行业首款生成式AI输入法 摘要&#xff1a;科大讯飞在2023年全球开发者节上发布了全新讯飞输入法13.0版本&#xff0c;其中最大的亮点是推出了行业首款生成式AI输入法。这次升级将生成式AI能力融入输入…...

35. 搜索插入位置、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天分享一些包括但不限于计算机基础、算法等相关的知识点&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&#x1f4d6;是你想要的&#x1f497; ⛽️今…...

使用 DDPO 在 TRL 中微调 Stable Diffusion 模型

引言 扩散模型 (如 DALL-E 2、Stable Diffusion) 是一类文生图模型&#xff0c;在生成图像 (尤其是有照片级真实感的图像) 方面取得了广泛成功。然而&#xff0c;这些模型生成的图像可能并不总是符合人类偏好或人类意图。因此出现了对齐问题&#xff0c;即如何确保模型的输出与…...

cocosCreator 之 crypto-es数据加密

版本&#xff1a; 3.8.0 语言&#xff1a; TypeScript 环境&#xff1a; Mac 简介 项目开发中&#xff0c;针对于一些明文数据&#xff0c;比如本地存储和Http数据请求等&#xff0c;进行加密保护&#xff0c;是有必要的。 关于加密手段主要有&#xff1a; 对称加密 使用相…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...

【java】【服务器】线程上下文丢失 是指什么

目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失&#xff1f; 直观示例说明 为什么上下文如此重要&#xff1f; 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程&#xff0c;代码应该如何实现 推荐方案&#xff1a;使用 ManagedE…...