PostgreSQL的学习心得和知识总结(一百四十八)|查看 PostgreSQL 17 中的新内置排序规则提供程序


注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下:

1、参考书籍:《PostgreSQL数据库内核分析》
2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》
3、PostgreSQL数据库仓库链接,点击前往
4、日本著名PostgreSQL数据库专家 铃木启修 网站主页,点击前往
5、参考书籍:《PostgreSQL中文手册》
6、参考书籍:《PostgreSQL指南:内幕探索》,点击前往
7、Looking at the new built-in collation provider in PostgreSQL 17,点击前往


1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)
2、本文目的:开源共享 抛砖引玉 一起学习
3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关
4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)
5、本文内容基于PostgreSQL master源码开发而成


查看 PostgreSQL 17 中的新内置排序规则提供程序

  • 文章快速说明索引
  • 第三个排序规则提供程序
  • 如何使用它
  • 索引和搜索性能
  • 结果排序
  • 二进制排序文本索引的另一个好处
  • 结论
  • 备注



文章快速说明索引

学习目标:

做数据库内核开发久了就会有一种 少年得志,年少轻狂 的错觉,然鹅细细一品觉得自己其实不算特别优秀 远远没有达到自己想要的。也许光鲜的表面掩盖了空洞的内在,每每想到于此,皆有夜半临渊如履薄冰之感。为了睡上几个踏实觉,即日起 暂缓其他基于PostgreSQL数据库的兼容功能开发,近段时间 将着重于学习分享Postgres的基础知识和实践内幕。


学习内容:(详见目录)

1、查看 PostgreSQL 17 中的新内置排序规则提供程序


学习时间:

2024年07月14日 15:19:37


学习产出:

1、PostgreSQL数据库基础知识回顾 1个
2、CSDN 技术博客 1篇
3、PostgreSQL数据库内核深入学习


注:下面我们所有的学习环境是Centos8+PostgreSQL master+Oracle19C+MySQL8.0

postgres=# select version();
                                                  version                                                   
------------------------------------------------------------------------------------------------------------
 PostgreSQL 17devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-21), 64-bit
(1 row)

postgres=#

#-----------------------------------------------------------------------------#

SQL> select * from v$version;          

BANNER        Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
BANNER_FULL	  Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production Version 19.17.0.0.0	
BANNER_LEGACY Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
CON_ID 0


#-----------------------------------------------------------------------------#

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27    |
+-----------+
1 row in set (0.06 sec)

mysql>

在最近发布的测试版,PostgreSQL 17 的众多新功能中,有一个内置的 UTF-8 语言环境和带有二进制字符串比较的排序规则。在这篇文章中,让我们看看它为什么有趣、如何使用它以及它的性能如何。

第三个排序规则提供程序

在版本 17 之前,我们可以在两个提供程序之间进行选择:操作系统附带的 libc 库和可选的 ICU 库。v17 为 Postgres 本身实现的排序规则添加了第三个提供程序。

声明将其描述为:

PostgreSQL 17 包含一个内置排序规则提供程序,它提供与 C 排序规则类似的排序语义,但使用的是 UTF-8 编码而不是 SQL_ASCII。此新排序规则保证是不可变的,从而确保无论 PostgreSQL 安装在什么系统上运行,排序的返回值都不会改变。

有两种内置排序规则,均适用于 UTF-8,如下:

SELECT
  collnamespace::regnamespace,
  collname,
  colllocale,
  pg_encoding_to_char(collencoding) as encoding
FROM pg_collation WHERE collprovider='b';  -- 'b' = 'built-in'

 collnamespace | collname  | colllocale | encoding 
---------------+-----------+------------+----------
 pg_catalog    | ucs_basic | C          | UTF8
 pg_catalog    | pg_c_utf8 | C.UTF-8    | UTF8

ucs_basic 在以前的版本中已经与libc提供程序一起存在,并且与 UTF8 数据库中的C排序规则相同。它在版本 17 中也一样,即:

  • 对于字符串比较,它使用字节顺序,没有任何语言规则。
  • 对于字符分类(即知道某个字符是字母、数字、小写字母还是大写字母……),它根据内部表来回答127 以下的任何代码点(ASCII 字符);对于其余的,则它对这些问题中的任何一个回答No

因此,尽管从技术上讲,在 UTF-8 数据库中使用 ucs_basicC是可行的,但对于非英语内容来说,这并不适用。

新的 C.UTF-8 内置语言环境及其 pg_c_utf8 排序规则解决了这个问题,在发布时为 Unicode 库的所有代码点提供了正确的结果(截至 Unicode 15.1,几乎有 150000 个),从而允许对所有字母表进行正确的大小写转换和正则表达式。

现在,libc 和 ICU 提供的 Unicode 排序规则也是如此,但重点是新的语言环境/排序规则在相同语言环境中提供了以下功能的组合:

  • 快速、不可变的二进制排序(没有 ICU 语言环境提供此功能)
  • 操作系统独立性(除"C"外,没有 libc 语言环境提供此功能)
  • 完整的 Unicode 字符分类("C"缺少此功能)

让我们用维恩图来说明这一点:

在这里插入图片描述

请注意,ICU 独立于操作系统并不意味着操作系统升级对 ICU 是透明的。操作系统发行版往往在发行时附带最新版本的 ICU 库,因此升级操作系统通常意味着同时升级 ICU,除非您自己编译它。与 ICU 相关的操作系统独立性意味着,当在不同操作系统上使用相同版本的 ICU 时,排序规则在这些系统上的行为相同。


如何使用它

要在创建实例或数据库时默认使用新排序规则,我们选择语言环境名称为 C.UTF8 且提供程序为builtin(请注意不要将其与 libc 的 C.UTF-8C.utf8 语言环境混淆)。

在实例级别:

initdb --locale-provider=builtin --locale=C.UTF8 -D /usr/local/pgsql/data

在这种情况下,该实例中创建的所有数据库将默认使用该新语言环境。

否则,在使用 libc 或 ICU 提供程序初始化的现有实例上,要使用新的内置语言环境创建特定数据库,我们应该这样做:

CREATE DATABASE test locale_provider='builtin' builtin_locale='C.UTF8' template='template0';

如果您想知道为什么我们需要强制使用 template0(而不是默认的 template1),那是因为服务器假设我们可能已将本地化数据添加到 template1,而这些数据可能与新数据库的区域设置不兼容。template0 包含与区域设置无关的不可修改的基本目录,因此它是一个安全的选择,而 template1template0 加上 DBA 所做的任何添加。

最后,在默认情况下不使用该新区域设置的数据库内部,我们可以在 SQL 级别的列或表达式上添加 COLLATE pg_c_utf8 子句,例如:

CREATE INDEX idx ON tablename using btree(columnname COLLATE pg_c_utf8);

然后,查询规划器将考虑这样的索引,用于如下查询:

SELECT * FROM tablename WHERE columnname = 'some-value' COLLATE pg_c_utf8;

索引和搜索性能

按字节比较比按语言比较占用更少的 CPU。让我们用互联网电影数据库的一些数据来说明这一点:

name_basics 是一个包含约 1300 万行的表。primaryName 列包含参与电影制作的人员的姓名,包含约 1000 万个不同的值。这是一个使用不同排序规则进行排序和搜索的好例子。

\d name_basics
                        Table "public.name_basics"
      Column       |         Type         | Collation | Nullable | Default 
-------------------+----------------------+-----------+----------+---------
 sn_soundex        | character varying(5) |           |          | 
 deathYear         | integer              |           |          | 
 primaryProfession | text                 |           |          | 
 nconst            | integer              |           |          | 
 primaryName       | text                 |           |          | 
 birthYear         | integer              |           |          | 
 s_soundex         | character varying(5) |           |          | 
 ns_soundex        | character varying(5) |           |          | 
 knownForTitles    | text                 |           |          | 
Indexes:
    "idx" btree ("primaryName")

让我们看看在 Linux Debian 12 系统(GNU libc 2.36,ICU 72)上,在使用不同区域设置创建的数据库上建立primaryName的 btree 索引需要多长时间。

在这里插入图片描述

如何解释这些差异:

  • libc 的 en_US.utf8 是最慢的:它进行语言比较时不使用缩写键(note1)
  • ICU 的 en-x-icu 进行语言比较,但使用缩写键优化
  • libc 的 C.utf8 进行更快的二进制比较,但 Postgres 并不 知道,因此它没有使用优化的快速路径,而是调用较慢的通用函数
  • C 和新的 C.UTF-8 语言环境针对最快执行进行了优化,并且性能同样出色

在索引该列后,让我们看看查询在数据库之间的执行时间比较。对于该测试,我们使用 pg_bench 和查询,当时搜索 1000 个值:

SELECT count(*) FROM name_basics WHERE "primaryName" IN
(
...<list of 1000 names previously randomly choosen from the table >...
)

此查询的计划是仅索引扫描Index Only Scan,匹配 6572 行。平均执行时间如下:

在这里插入图片描述

差异大致类似于索引创建,只是在索引时 en_US.utf8en-x-icu 之间的差距更大。我的理论是,这是因为 en_US.utf8 禁用了缩写键优化,而 ICU 排序规则启用了缩写键优化。缩写键用于排序,但不用于查找。

depesz 博客上的一篇最新文章(如果使用默认语言环境,您会在表中留下多少速度?)也显示了比较这些排序规则的基准,但使用 COLLATE 子句,而不是像我为上面报告的数字那样在数据库级别定义语言环境。

Depesz 指出,二进制比较的表现更好,正如预期的那样,但内置的 pg_c_utf8 排序规则的表现明显差于"C"排序规则,他想知道为什么。答案来自 Jeff Davis 在 pgsql-hackers 列表中的后续内容:加快排序规则缓存。简而言之,与非默认排序规则的比较目前意味着可以更好地优化缓存查找。希望这种情况能很快得到改善,但仍然要记住,为了更快地获得结果,数据库区域设置应优先于 COLLATE 子句。


结果排序

二进制排序规则的主要缺点是它们不按“人性化方式”进行排序。例如,假设我们想在排序列表中输出所有以AdèleAdele开头的 primaryName。我们将进行如下查询:

SELECT DISTINCT "primaryName" FROM name_basics
 WHERE "primaryName" ~ '^Adèle' OR "primaryName" ~ '^Adele'
 ORDER BY "primaryName" ;

通过二进制排序,我们得到以下输出:

        primaryName          
------------------------------
 Adele
 Adele & The French StarKids
 Adele Aalto
 Adele Abbott
 Adele Abinante
[...]
 Adèle de Fontbrune
 Adèle de Mesnard
 Adèle de la Fuente
 Adèle van Biljon
 Adèle-Elise Prévost
(1342 rows)

Adele”被归类在列表的第一部分,而Adèle 则位于第二部分。这是因为 è 字母的代码点 (U+00E8) 大于 e 字母的代码点 (U+00065)。

使用语言排序规则(如 fr_FR.utf8)时,输出效果更好:

         primaryName          
------------------------------
 Adele
 Adèle
 Adele Aalto
 Adele Abbott
 Adele Abinante
 Adele Abou Ali
 Adele Aburrow
 Adele Adams
 Adele Adderley
 Adele Addison
 Adele Addo
 Adele Adeshayo
 Adele Adkins
 Adèle Ado
[...]
 Adele Zeiner
 Adele Zin
 Adele Zoppis
 Adèle Zouane
 Adele Zupicic
(1342 rows)

在这个列表中,重音字母和非重音字母 e 在一起,姓氏决定了排序。这显然是我们(人类)喜欢看到的。

要在二进制排序数据库中获得这种排序,应将带有语言学家排序规则的 COLLATE 子句添加到 ORDER BY 中。它可以是:

  • ORDER BY "primaryName" COLLATE "en_US.utf8"(或其他 libc 排序规则)。它仅在数据库中存在该排序规则时才有效,这取决于操作系统和安装,因此不可移植。它还会强制使用特定的语言/国家/地区,这可能不是应用程序想要的
  • ORDER BY "primaryName" COLLATE "en-x-icu",使用 ICU 排序规则。优点是每个启用 ICU 的 Postgres 实例都会有此排序规则,因此它几乎是可移植的。但是,这再次强制使用特定的语言
  • ORDER BY "primaryName" COLLATE "unicode",自 Postgres 16 以来就存在。它调用旨在适用于所有语言的root排序规则。对于 Postgres 15 及更早版本,我们可以使用不太容易记住的und-x-icu

实际上,现代客户端应用程序可能配备了排序功能,使它们不依赖于数据库排序。例如,Javascript 现代应用程序可能使用 Navigator.languageIntl.Collat​​or 根据浏览器的语言进行排序。对于大多数开发人员来说,使用 Javascript 对列表进行排序比找到与浏览器语言匹配的数据库排序规则并将其注入 SQL 查询更为自然。如果结果列表可能太大而无法由浏览器处理,那么当然,数据库端排序又回到了游戏中。


二进制排序文本索引的另一个好处

除了速度更快之外,二进制排序索引还直接支持左锚left-anchored搜索。在上一个查询中,如果我们在primaryName上只有一个语言排序索引,那么我们就会得到一个缓慢的顺序扫描:

EXPLAIN ANALYZE  select distinct "primaryName" from name_basics
  where "primaryName" ~ '^Adèle' or "primaryName" ~ '^Adele'
  order by "primaryName";
Unique  (cost=243279.95..243541.75 rows=2174 width=14) (actual time=4354.978..4356.406 rows=1342 loops=1)
   ->  Gather Merge  (cost=243279.95..243536.32 rows=2174 width=14) (actual time=4354.978..4356.212 rows=1398 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Unique  (cost=242279.92..242285.36 rows=1087 width=14) (actual time=4346.459..4346.578 rows=466 loops=3)
               ->  Sort  (cost=242279.92..242282.64 rows=1087 width=14) (actual time=4346.453..4346.482 rows=487 loops=3)
                     Sort Key: "primaryName"
                     Sort Method: quicksort  Memory: 25kB
                     Worker 0:  Sort Method: quicksort  Memory: 25kB
                     Worker 1:  Sort Method: quicksort  Memory: 25kB
                     ->  Parallel Seq Scan on name_basics  (cost=0.00..242225.11 rows=1087 width=14) (actual time=9.747..4345.114 rows=487 loops=3)
                           Filter: (("primaryName" ~ '^Adèle'::text) OR ("primaryName" ~ '^Adele'::text))
                           Rows Removed by Filter: 4345599
 Planning Time: 0.186 ms
 Execution Time: 4356.494 ms

文档中为加速这一过程给出的建议是使用 varchar_pattern_ops 创建第二个索引:

运算符类 text_pattern_ops、varchar_pattern_ops 和 bpchar_pattern_ops 分别支持类型 text、varchar 和 char 上的 B 树索引。与默认运算符类的区别在于,值是严格逐个字符进行比较,而不是根据特定于语言环境的排序规则进行比较。这使得这些运算符类适合在数据库不使用标准“C”语言环境时由涉及模式匹配表达式(LIKE 或 POSIX 正则表达式)的查询使用。例如,您可以像这样索引 varchar 列:CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

好消息是,新的 C.UTF-8 内置语言环境和 pg_c_utf8 排序规则具有与标准"C"语言环境相同的优势:它们可以直接用于左锚搜索,如具有此类索引的执行计划所示:

Unique  (cost=162.45..175.49 rows=2607 width=14) (actual time=30.616..31.048 rows=1342 loops=1)
   ->  Sort  (cost=162.45..168.97 rows=2608 width=14) (actual time=30.612..30.699 rows=1461 loops=1)
         Sort Key: "primaryName"
         Sort Method: quicksort  Memory: 49kB
         ->  Bitmap Heap Scan on name_basics  (cost=10.44..14.46 rows=2608 width=14) (actual time=0.571..26.297 rows=1461 loops=1)
               Recheck Cond: (("primaryName" ~ '^Adèle'::text) OR ("primaryName" ~ '^Adele'::text))
               Filter: (("primaryName" ~ '^Adèle'::text) OR ("primaryName" ~ '^Adele'::text))
               Heap Blocks: exact=1451
               ->  BitmapOr  (cost=10.44..10.44 rows=1 width=0) (actual time=0.356..0.357 rows=0 loops=1)
                     ->  Bitmap Index Scan on idx  (cost=0.00..4.57 rows=1 width=0) (actual time=0.126..0.127 rows=268 loops=1)
                           Index Cond: (("primaryName" >= 'Adèle'::text) AND ("primaryName" < 'Adèlf'::text))
                     ->  Bitmap Index Scan on idx  (cost=0.00..4.57 rows=1 width=0) (actual time=0.227..0.227 rows=1193 loops=1)
                           Index Cond: (("primaryName" >= 'Adele'::text) AND ("primaryName" < 'Adelf'::text))
 Planning Time: 0.473 ms
 Execution Time: 31.132 ms

结论

让我们总结一下此表中的主要排序特征,如下:

"C"
or ucs_basic
libc collations
other than "C"
ICU collationspg_c_utf8
Portability between OSes?✅ Yes❌ No✅ Yes✅ Yes
Bytewise comparisons?✅ Yes❓ Some❌ No✅ Yes
Abbreviated keys?(note1) -❌ No✅ Yes-
Transparent OS updates?(note2) ✅ Yes❌ No❌ No✅ Yes
Unicode classification?❌ No✅ Yes✅ Yes✅ Yes
Linguistic sort?❌ No✅ Yes✅ Yes❌ No
Advanced comparisons?(note3) ❌ No❌ No✅ Yes❌ No

Postgres 17 中的新内置提供程序提供了快速、可移植、更易于升级的 C.UTF-8 语言环境/pg_c_utf8 排序规则。虽然它没有 ICU 提供程序提供的更高级功能,但它很可能是 Unicode 数据库的良好默认语言环境。

有关该主题的更多信息,我建议在 YouTube 上观看这个精彩的演示:Jeremy Schneider 和 Jeff Davis 的从 A 到 Z 的排序规则 (PGConf.dev 2024)。Jeremy 首先列出了一系列与排序规则相关的非直观事实和要点(我注意到其中有一些对这个博客的引用 🤓 ),然后 Jeff(Postgres 17 新功能的作者)详细介绍了可以使用现有排序规则做什么以及新语言环境如何适应该上下文。


备注

  1. 缩写键是字符串的二进制表示,用于加速使用语言排序规则的排序。请参阅 Peter Geoghegan 的帖子缩写键:利用局部性来提高 PostgreSQL 的文本排序性能(自 2015 年起),其中解释了该功能。理论上,libc 排序规则也可以使用它们,但发现实现存在错误,因此不适用于索引。

  2. 严格来说,当操作系统更新意味着 Unicode 升级时,它们并不透明。即使二进制排序解决了主要问题,Unicode 中的代码点的添加在理论上也可以改变涉及正则表达式、大小写转换或规范化规则的检查约束的结果。

  3. 高级比较是指 ICU 非确定性排序规则允许的所有功能,其中包括不区分大小写和不区分重音的比较。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数码暴龙机(电波暴龙机)彩色复刻版!!| 使用Python、PySide6、pixilart自制windows桌面宠物

一、前言 数码暴龙机&#xff08;电波暴龙机&#xff09;是万代公司发售的一系列与《数码兽》系列相关的液晶玩具商品。这些产品融合了养成和对战元素&#xff0c;为玩家提供了一种虚拟养成和战斗的娱乐体验。也是很多人的童年回忆。最近在B站刷到讲解暴龙通关的教程和视频&…

ROS2 + 科大讯飞 初步实现机器人语音控制

环境配置&#xff1a; 电脑端&#xff1a; ubuntu22.04实体机作为上位机 ROS版本&#xff1a;ros2-humble 实体机器人&#xff1a; STM32 思岚A1激光雷达 科大讯飞语音SDK 讯飞开放平台-以语音交互为核心的人工智能开放平台 实现步骤&#xff1a; 1. 下载和处理科大讯飞语音模…

SQL Server的视图

SQL Server的视图 一、基础 SQL 视图&#xff08;Views&#xff09;是一种虚拟表&#xff0c;是基于 SQL 查询结果生成的。这些虚拟表可以包含来自一个或多个表的数据&#xff0c;并且可以像表一样查询&#xff1b;视图是一个表中的数据经过某种筛选后的显示方式&#xff0c;或…

Cornerstone3D导致浏览器崩溃的踩坑记录

WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost ⛳️ 问题描述 在使用vue3vite重构Cornerstone相关项目后&#xff0c;在Mac本地运行良好&#xff0c;但是部署测试环境后&#xff0c;在window系统的Chrome浏览器中切换页面会导致页面崩溃。查看Chrome的任务管理器&am…

对话天润融通首席科学家:大模型的首要任务是为客户创造商业价值

2023年&#xff0c;AI大模型开启了企业数智化转型的新篇章。 不过前沿技术固然重要&#xff0c;但在增长见顶的存量背景下&#xff0c;先进技术带来的实用价值也尤为关键。 正如天润融通首席科学家田凤占所说&#xff1a;“现阶段最重要的是让大模型尽快和企业的业务相结合&a…

【Linux】进程间通信——消息队列和信号量

目录 消息队列&#xff08;message queue&#xff09; 信号量&#xff08;Semaphore&#xff09; system V版本的进程间通信方式有三种&#xff1a;共享内存&#xff0c;消息队列和信号量。之前我们已经说了共享内存&#xff0c;那么我们来看一下消息队列和信号量以及它们之间…

【嵌入式Linux】<总览> 网络编程(更新中)

文章目录 前言 一、网络知识概述 1. 网路结构分层 2. socket 3. IP地址 4. 端口号 5. 字节序 二、网络编程常用API 1. socket函数 2. bind函数 3. listen函数 4. accept函数 5. connect函数 6. read和recv函数 7. write和send函数 三、TCP编程 1. TCP介绍 2.…

新版本WPS不登录无法编辑的解决办法

原因分析&#xff1a;新版本的WPS因加入多种在线功能&#xff0c;建议登录账号获得更加体验 解决办法&#xff1a;首选第一种修改注册表后重启WPS&#xff0c;第二种仅作为临时满足工作需求&#xff0c;过一段时间会自动失效 方法一&#xff1a;键盘同时按下WINR键&#xff0c;…

【Python】基础语法(函数、列表和元组、字典、文件)

。一、函数 1、函数是什么 编程中的函数和数学中的函数有一定的相似之处。 数学上的函数&#xff0c;比如 y sin x&#xff0c;x 取不同的值&#xff0c;y 就会得到不同的结果。 编程中的函数是一段可以被重复使用的代码片段。 &#xff08;1&#xff09;求数列的和&…

MySQL索引特性(上)

目录 索引的重要 案例 认识磁盘 MySQL与存储 先来研究一下磁盘 扇区 定位扇区 结论 磁盘随机访问与连续访问 MySQL与磁盘交互基本单位 建立共识 索引的理解 建立测试表 插入多条记录 局部性原理 所有的MySQL的操作(增删查改)全部都是在MySQL当中的内存中进行的&am…

网友提问:HTML CSS JS很低级吗?

这话听起来就像有人在说披萨只是面团加奶酪&#xff0c;完全忽略了上面的美味配料和烘烤的艺术啊&#xff01;HTML、CSS、JS这三位可是前端开发的铁三角&#xff0c;它们一点都不“低级”&#xff0c;反而相当关键。 HTML就像是房子的骨架&#xff0c;没有它&#xff0c;网页就…

【iOS】——MRC

一、引用计数 内存管理的核心是引用计数器&#xff0c;用一个整数来表示对象被引用的次数&#xff0c;系统需要根据引用计数器来判断对象是否需要被回收。 在每次 RunLoop 迭代结束后&#xff0c;都会检查对象的引用计数器&#xff0c;如果引用计数器等于 0&#xff0c;则说明…

单链表算法 - 链表分割

链表分割_牛客题霸_牛客网现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的。题目来自【牛客题霸】https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70思路: 代码: /* struct ListNode {int val;struct List…

烧掉一个亿就为造好一把椅子,西昊如何策划人体工学椅极致产品力

2011年到2015年这4年期间&#xff0c;功能单一&#xff0c;价值雷同的椅子市场趋于饱和&#xff0c;竞争的白热化和同质化带来了全行业的价格战&#xff0c;彼时西昊的经营陷入巨大的困境&#xff0c;所有的产品和钱都变成成库存&#xff0c;现金流几乎枯竭。因此&#xff0c;西…

文心一言《使用手册》,文心一言怎么用?

一、认识文心一言 &#xff08;一&#xff09;什么是文心一言 文心一言是百度研发的 人工智能大语言模型产品&#xff0c;能够通过上一句话&#xff0c;预测生成下一段话。 任何人都可以通过输入【指令】和文心一言进行对话互动、提出问题或要求&#xff0c;让文心一言高效地…

智能家居产品公司网站源码,自适应布局设计,带完整演示数据

适合各类智能家居电子产品使用的网站源码&#xff0c;深色大气设计&#xff0c;自适应布局设计&#xff0c;pc手机均可完美适配&#xff0c;带完整演示数据。 独家原创资源。源码是asp开发的&#xff0c;数据库是access&#xff0c;主流的虚拟主机空间都支持asp&#xff0c;直…

<Rust><GUI>rust语言GUI库tauri体验:前、后端结合创建一个窗口并修改其样式

前言 本文是rust语言下的GUI库&#xff1a;tauri来创建一个窗口的简单演示&#xff0c;主要说明一下&#xff0c;使用tauri这个库如何创建GUI以及如何添加部件、如何编写逻辑、如何修改风格等&#xff0c;所以&#xff0c;这也是一个专栏&#xff0c;将包括tauri库的多个方面。…

面对人工智能发展的伦理挑战:应对策略与未来方向

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

硬件开发笔记(二十六):AD21导入电感原理图库、封装库和3D模型

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140437290 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

SAP ERP与金蝶云星空的集成案例(新能源光伏行业)

一、项目环境 阳光新能源开发股份有限公司&#xff08;简称“阳光电源”&#xff09;是一家专注于新能源开发利用的国家高新技术企业。作为阳光电源&#xff08;股票代码&#xff1a;300274&#xff09;旗下的新能源开发投资平台&#xff0c;阳光新能源聚焦光伏、风电、风光…