Oracle 启动动态采样 自适应执行计划

news2024/11/16 1:28:10

为了解决因为统计信息缺失或者统计不够准确而引起的问题,从9iR2的版本开始Oracle推出了动态采样(Dynamic Sampling)功能,使SQL文在硬解析过程中动态地收集统计信息。 该功能在以后的版本上得到更进一步的增强,从11.2.0.4版本改称为动态统计(Dynamic Statistics 以后简称DS )。

1.什么是动态统计(Dynamic Statistics)或者动态采样(Dynamic Sampling)?
2.为什么要使用动态统计?
3.动态统计都有哪些级别,各个级别都有什么区别?
4.如何确认采用了动态统计功能?
5.动态统计在各个版本上有什么区别?
6.如何禁用动态统计和12c的自动动态统计?
7.动态统计的利弊,常见问题?

下面章节将针对以上的问题进行解答和说明:

什么是动态统计(Dynamic Statistics)或者动态采样(Dynamic Sampling)?

动态采样是Oracle从9iR2的版本开始推出的一项优化技术,通过执行一些递归SQL(recursive SQL )来随机访问表块,收集一些采样信息,来预估谓词的选择率(selectivities)。

9i以后的版本中不断进行功能加强,在11.2.0.4版本改称为动态统计(Dynamic Statistics)。 在12c版本后进一步推出自动动态统计(Automatic Dynamic Statistics)。

为什么要使用动态统计?

如同前面叙述的,如果由于选择执行计划的Object统计信息缺失、过期或者不足时,CBO优化器选择的执行计划就有可能不是最优的甚至是最差的。  有还不如没有

所以为了保证优化器在SQL硬解析时选择到最优的执行计划,根据数据库动态统计的设置级别,进行动态收集Object的统计信息。

动态统计都有哪些级别,各个级别都有什么区别?

数据库动态统计的级别主要通过参数OPTIMIZERDYNAMICSAMPLING的值(同级别)来决定。

关于OPTIMIZERDYNAMICSAMPLING的值(同级别)和动态统计启用的条件可以参考下表:

※其中样本大小的数据块数可以由隐含参数optimizerdynsmpblks来控制(默认值为32)。

blocks数 ,这个好像有时候不能触发自动采样,如果发现statistics为0 而blocks为XXXX自动采样就好了,但是有个可能就是表被全部delete掉了。

如何确认采用了动态统计功能?

我们可以通过以下的方法来确认一个查询是否使用了动态统计功能:

代码语言:javascript

复制

1.利用DBMS_XPLAN.DISPLAY_CURSOR功能查看是否使用了DS
2.利用Optimizer Trace(10053 Trace)查看是否使用了DS
3.利用SQL Trace(10046 Trace)查看是否使用了DS

我们通过以下的例子,来看一下查看某个查询是否使用动态统计。 (在12.1.0.2版本上进行测试)

代码语言:javascript

复制

---首先我们准备查询用的数据
SQL> conn SH/SH
Connected.

---查看optimizer_dynamic_sampling的级别
SQL> SHOW PARAMETERS optimizer_dynamic_sampling
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling           integer     2

---使统计信息缺失,以便采用动态统计
SQL> EXEC DBMS_STATS.DELETE_SCHEMA_STATS('sh');
PL/SQL procedure successfully completed.

---设定Optimizer Trace(10053 Trace)和SQL Trace(10046 Trace)
SQL> alter session set tracefile_identifier='sampling_10053_10046';

Session altered.
SQL> alter session set statistics_level=all;

Session altered.

SQL> alter session set max_dump_file_size = unlimited;

Session altered.

SQL> alter session set events '10046 trace name context forever, level 12';

Session altered.

SQL> ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';

Session altered.

---执行SQL文
SQL> SELECT /* statis sampling1 */
 2         p.prod_name, COUNT(*)
 3    FROM sales s,
 4         products p
 5   WHERE s.time_id >= TO_DATE(' 1997-07-01 00:00:00',
 6      'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
 7     AND s.time_id < TO_DATE(' 1998-04-01 00:00:00',
 8      'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
 9     AND s.prod_id = p.prod_id
10   GROUP BY
11         p.prod_name;

PROD_NAME                                            COUNT(*)
-------------------------------------------------- ----------
...
60 rows selected.

---通过dbms_xplan.display_cursor查看执行计划。
SQL> SET PAGES 2000 LIN 300
SQL> select * from table(dbms_xplan.display_cursor(null,null,'NOTE ALLSTATS LAST'));

SQL_ID  62054vzrc3rcr, child number 0
-------------------------------------
SELECT /* statis sampling1 */        p.prod_name, COUNT(*)   FROM sales
s,        products p  WHERE s.time_id >= TO_DATE(' 1997-07-01
00:00:00',     'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
AND s.time_id < TO_DATE(' 1998-04-01 00:00:00',     'SYYYY-MM-DD
HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')    AND s.prod_id = p.prod_id
GROUP BY        p.prod_name

Plan hash value: 1538978877

----------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                    | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                             |                |      1 |        |     60 |00:00:00.64 |    2339 |       |       |          |
|   1 |  HASH GROUP BY                               |                |      1 |  44240 |     60 |00:00:00.64 |    2339 |   974K|   974K| 3016K (0)|
|*  2 |   HASH JOIN                                  |                |      1 |  44240 |  43687 |00:00:00.57 |    2339 |  1185K|  1185K| 1598K (0)|
|   3 |    TABLE ACCESS FULL                         | PRODUCTS       |      1 |     72 |     72 |00:00:00.01 |       4 |       |       |          |
|   4 |    PARTITION RANGE ITERATOR                  |                |      1 |  44240 |  43687 |00:00:00.33 |    2335 |       |       |          |
|   5 |     TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| SALES          |      2 |  44240 |  43687 |00:00:00.21 |    2335 |       |       |          |
|   6 |      BITMAP CONVERSION TO ROWIDS             |                |      1 |        |  43687 |00:00:00.06 |       4 |       |       |          |
|*  7 |       BITMAP INDEX RANGE SCAN                | SALES_TIME_BIX |      1 |        |     90 |00:00:00.01 |       4 |       |       |          |
---------------------------------------------------------------------------------------------------------------------------------------------------

-Predicate Information (identified by operation id):
---------------------------------------------------  

2 - access("S"."PROD_ID"="P"."PROD_ID")
  
7 - access("S"."TIME_ID">=TO_DATE(' 1997-07-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "S"."TIME_ID"<TO_DATE(' 1998-04-01 00:00:00',
             'syyyy-mm-dd hh24:mi:ss'))Note


-----
  - dynamic statistics used: dynamic sampling (level=2) ★
  - this is an adaptive plan
dbmsxplan.displaycursor

我们可以看到,通过dbmsxplan.displaycursor输出的执行计划有如下的Note内容: 采用了级别为2的动态统计。

代码语言:javascript

复制

Note
-----
  - dynamic statistics used: dynamic sampling (level=2)
10053

然后我们再看一看Optimizer Trace(10053 Trace)中关于动态统计的部分输出,并有包含/* OPTDYNSAMP */ 提示的递归调用SQL文: (详细记录了动态采样的过程)

代码语言:javascript

复制

*** 2016-05-18 20:48:36.534
** Performing dynamic sampling initial checks. **★
 Column (#3): TIME_ID(DATE)  Part#: 3  NO STATISTICS (using defaults)
   AvgLen: 9 NDV: 250 Nulls: 0 Density: 0.003998
 Column (#3): TIME_ID(DATE)  Part#: 4  NO STATISTICS (using defaults)
   AvgLen: 9 NDV: 250 Nulls: 0 Density: 0.003998
 Column (#3): TIME_ID(DATE)  NO STATISTICS (using defaults)
   AvgLen: 9 NDV: 250 Nulls: 0 Density: 0.004000
** Dynamic sampling initial checks returning TRUE (level = 2).★
** Dynamic sampling updated index stats.: SALES_CHANNEL_BIX, blocks=119
** Dynamic sampling updated index stats.: SALES_CUST_BIX, blocks=574
** Dynamic sampling updated index stats.: SALES_PROD_BIX, blocks=105
** Dynamic sampling updated index stats.: SALES_PROMO_BIX, blocks=87
** Dynamic sampling updated index stats.: SALES_TIME_BIX, blocks=127
** Dynamic sampling index access candidate : SALES_TIME_BIX
** Dynamic sampling updated table stats.: blocks=97*** 2016-05-18 20:48:36.534
** Generated dynamic sampling query: ★
   query text :
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
...
*** 2016-05-18 20:48:36.695
** Executed dynamic sampling query:★
   level : 2
   sample pct. : 63.917526
   total partitions : 28
     partitions for sampling : 2
     partitioning pct. : 7.142857
   actual sample size : 28277
   filtered sample card. : 28277
   orig. card. : 8005
   block cnt. table stat. : 97
   block cnt. for sampling: 97
   max. sample block cnt. : 64
   sample block cnt. : 62
   ndv C3 : 57
       scaled : 57.00
   nulls C4 : 0
       scaled : 0.00
   min. sel. est. : 0.00250000
** Dynamic sampling col. stats.:
 Column (#1): PROD_ID(NUMBER)  Part#: 0
   AvgLen: 22 NDV: 57 Nulls: 0 Density: 0.017544
** Using dynamic sampling NULLs estimates.
** Using dynamic sampling NDV estimates.
  Scaled NDVs using cardinality = 619358.
10046

我们可以通过查看SQL Trace(10046 Trace)中的一些以SELECT /* OPTDYNSAMP */... 开头的动态采样递归SQL来判断是否采用了动态统计功能。

代码语言:javascript

复制

例如:
SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
 NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false')
 NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:"SYS_B_00"),
 NVL(SUM(C2),:"SYS_B_01"), COUNT(DISTINCT C3), NVL(SUM(CASE WHEN C3 IS NULL
 THEN :"SYS_B_02" ELSE :"SYS_B_03" END),:"SYS_B_04")
FROM
(SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("S") FULL("S")
 NO_PARALLEL_INDEX("S") */ :"SYS_B_05" AS C1, CASE WHEN "S"."TIME_ID">=
 TO_DATE(:"SYS_B_06", :"SYS_B_07") AND "S"."TIME_ID"<TO_DATE(:"SYS_B_08",
 :"SYS_B_09") THEN :"SYS_B_10" ELSE :"SYS_B_11" END AS C2, "S"."PROD_ID" AS
 C3 FROM "SH"."SALES" SAMPLE BLOCK (:"SYS_B_12" , :"SYS_B_13") SEED
 (:"SYS_B_14") "S" WHERE "S"."TIME_ID">=TO_DATE(:"SYS_B_15", :"SYS_B_16")
 AND "S"."TIME_ID"<TO_DATE(:"SYS_B_17", :"SYS_B_18")) SAMPLESUB

动态统计在各个版本上有什么区别?

下面我们再介绍一下在各个版本上,动态统计有什么特点和那些比较大的演进:

9iR2

在9iR2的版本上推出,称为动态采样(Dynamic Sampling)。

11.2.0.1

在11.2.0.1 的版本上,推出了自动调整(AUTO-ADJUST)功能。 即,11.2.0.1以后的版本,如果动态采样采用的级别是默认级别2,Oracle就有可能根据查询语句的特点自动调整(AUTO-ADJUST)动态采样的级别;调整后的级别范围为4~8. 当然根据需要,你也可以下面的语句关闭这项功能。

代码语言:javascript

复制

SQL> alter session set "_fix_control" = '7452863:off';
11.2.0.4

在11.2.0.4 的版本上,推出了一个新的级别11,并且正式改名为动态统计(Dynamic Statistics) 即,如果把级别设为11,将由Oracle优化器自行决定动态采样范围和采样大小。

12c

在12c的版本上,推出了自动动态统计(Automatic Dynamic Statistics)功能。 即,当满足下面任何的一个条件时,Oracle优化器自行决定动态采样范围和采样大小。

代码语言:javascript

复制

  ・级别为默认级别2时 或者 级别设为11
 ・指定SQL HINT(dynamic_sampling)启用动态统计
 ・并行查询
 ・执行过的查询语句并且其执行履历还是可用的(如在内存中,AWR中等)。

并行并行 

当然还有由于如自适应执行计划,统计反馈,SQL计划指令等自适应查询优化(Adaptive Query Optimization)触发的一些情况。

代码语言:javascript

复制

※可以通过以下设定,使并行查询时的12c自动动态统计无效。   

SQL> alter system set "_fix_control"= '12914055:off'

如何禁用动态统计和12c的自动动态统计?

你可以通过如下几种方法禁用动态统计:

OPTIMIZERDYNAMICSAMPLING

你可以通过设置初始化参数OPTIMIZERDYNAMICSAMPLING为0可以彻底地使动态统计功能无效。

例:

代码语言:javascript

复制

SQL> conn /as sysdba
Connected.
SQL>---系统级别 
   
SQL> show parameter OPTIMIZER_DYNAMIC_SAMPLING

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling           integer     2

SQL> alter system set optimizer_dynamic_sampling=0;

System altered.

SQL> show parameter OPTIMIZER_DYNAMIC_SAMPLING

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling           integer     0--会话级别

SQL> alter session set optimizer_dynamic_sampling=0;

Session altered.

SQL> show parameter OPTIMIZER_DYNAMIC_SAMPLING


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling           integer     0
HINT

可以通过dynamic_sampling HINT,针对某些特定SQL使动态统计无效。

代码语言:javascript

复制

select /*+ dynamic_sampling(0) */ ...

也可以通过dynamic_sampling HINT,针对某些特定语句中的特定表,使动态统计无效。

代码语言:javascript

复制

SELECT /*+ dynamic_sampling(<tab/alias name> 0) */
关于12c版本上的自动动态统计

在12c版本上,自动动态统计(ADS)属于自动查询优化(Adaptive query optimization)的一部分,所以通过参数OPTIMIZERADAPTIVEFEATURES也可以对自动动态统计(ADS)进行控制。 但是需要明确的是,参数OPTIMIZERADAPTIVEFEATURES仅仅能控制12c ADS的使用,并不能控制默认的动态统计功能。即:

代码语言:javascript

复制

  当OPTIMIZER_ADAPTIVE_FEATURES = TRUE 并且OPTIMIZER_DYNAMIC_SAMPLING = 2 时,自动动态统计(ADS)有效。

 当OPTIMIZER_ADAPTIVE_FEATURES = FALSE 并且OPTIMIZER_DYNAMIC_SAMPLING = 2 时,自动动态统计(ADS)无效,但是默认的动态统计(Level 2)依然会有效。 

另外,当OPTIMIZER_DYNAMIC_SAMPLING = 11时,无论OPTIMIZER_ADAPTIVE_FEATURES的值是TRUE 和FALSE ,12c ADS都会有效。

在12c版本上的自动动态统计有效的情况下,动态收集的统计信息还会保存在内存的结果缓存(Result Cache)中,以便供其他相关的查询使用。 我们可以通过 参数optimizerads_useresultcache来控制是否保存统计结果到结果缓存(Result Cache)中。

动态统计的利弊?

我们知道任何新功能都是一把双刃剑,有优点也有缺点,对于动态统计也一样。 动态统计最大的优点是,在优化器选择执行计划时,对统计信息缺失或者统计不够准确的对象,能够动态地收集统计信息,从而获得相对好的执行计划。 并且在12c中优化器还能够自行决定统计收集级别和在内存中保存统计结果,供其他操作共享。 而其也有着缺点,就是使硬解析时候的解析时间可能变得更长,而且如果大量的动态收集操作发生时可能影响到数据库全体性能。 针对动态统计的一些常见问题,我们将在以后的案例中进行介绍。

版权声明:本文为订阅号TeacherWhat原创文章,转载必须注明出处,作者保留一切相关权力!

--------------------------

自适应执行计划

对象统计信息并不总是会为查询优化器提供用于找出最优执行计划所需的全部信息。为了改进这种情况,在解析阶段,查询优化器可以利用动态采样对要处理的数据获取额外的洞察力。

此外,自从12.1版本开始,查询优化器能够将某些决定推迟到执行阶段。其思路是,利用在执行计划的执行部分可以收集的信息来决定应该如何执行其他部分。基于这个目的,查询优化器引入了所谓的子计划。同时引入的还有负责决定应该激活哪个子计划的操作。

注意 自适应执行计划只有在企业版中才可用。

从12.1版本开始,查询优化器能在以下状况中使用自适应执行计划。

Ø  从嵌套循环联接切换到散列联接,反之亦然。  NL - HASH

Ø  为并行执行的SQL语句从散列向广播切换分配方法。

-----------------------散列向广播切换,就和分布式DB一样,控制是不是把整个表分发下去参与join 还是每一个并行分派一部分数据做join-----------------------------------

例如,考虑以下替代情况:

  • 许多并行服务器进程分配的行很少。

    数据库可以选择广播分发方法。在这种情况下,每个并行服务器进程都会接收结果集中的每一行。

  • 很少有并行服务器进程分布许多行。

    如果在数据重新分发期间遇到数据倾斜,则可能会对语句的性能产生不利影响。数据库更有可能选择散列分布,以确保每个并行服务器进程接收相等数量的行。

所述混合散列分配技术是不决定最终的数据分发方法,直到执行时间的自适应并行数据分配。优化器在操作的生产方将统计收集器插入并行服务器进程的前面。如果行数小于阈值(定义为并行度(DOP)的两倍),则数据分发方法从哈希切换为广播。否则,分发方法是哈希。

------------------------------

下面的例子演示切换联接方法是如何实现的。这是一段来自adaptive_plan.sql脚本生成输出的摘录。此查询是一个两张表之间的简单联接。它通过普通的嵌套循环联接执行:

EXPLAIN PLAN FOR SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.n = 666;

select * from table(dbms_xplan.display(format=>'basic +predicate +note'));

Predicate information(identified  by  operation  id):

-------------------------------------------------------

3- filter("T1"."N"=666)

4- access("T1"."ID"="T2"."ID")

Note

 - this is an adaptive plan

注意,上面摘录中末尾的Note部分指出了这个执行计划是自适应的。然而,就执行计划本身而言,却没有任何特别的地方。而事实是,默认情况下,dbms_xplan包的display函数只显示默认的执行计划。

简单来说,这是查询优化器在不考虑自适应执行计划时会选择的执行计划。如果想看见包含子计划的完整执行计划,必须在使用dbms_xplan包时指定adaptive修饰符。在这种情况下,有三个额外的操作会在该执行计划中显示:

select * FROM table(dbms_xplan.display(format=>' basic +predicate +note +adaptive'));

1- access("T1"."ID"="T2"."ID")

5- filter("T1"."N"=666)

6- access("T1"."ID"="T2"."ID")

Note

- this is an adaptive plan(rows marked '-' are inactive)

这样的一个执行计划并不容易读取,因为它其实包含两个不同的执行计划。首先,是基于嵌套循环联接的默认执行计划:

接下来,是基于散列联接的自适应执行计划:

基本上,当t1表的扫描返回少量的数据时,第一个执行计划比第二个好。因此,要决定应该使用哪个执行计划,查询优化器会估算能够被嵌套循环联接有效处理的最大行数(称作转折点)。为了在执行阶段期间决定应该使用哪个执行计划,STATISTICS COLLECTOR操作缓存并记录t1表的扫描返回的记录数。  

终于知道STATISTICS COLLECTOR 干什么的了

然后,只有当记录数低于转折点的数值时,嵌套循环联接才会被执行。否则,散列联接会被执行。此时的执行计划通常被称作最终执行计划。一旦最终执行计划确定下来,就会禁用STATISTICS COLLECTOR操作,因此,不会发生进一步的缓存。此外,与转折点方法有关的操作也会禁用。

注意 要知道执行计划切换只会发生在子游标第一次执行时。所有后续执行都使用最终执行计划

v$sq1动态性能视图提供一个新的列帮助你了解,对于一个特定的子游标其最终执行计划是否已经选定。这个列就是is_resolved_adaptive_plan。它会被设置为以下值。

Ø  NULL意味着与该游标关联的执行计划不是自适应的。

Ø  N意味着最终执行计划还没有被确定下来。这个值只有在最终执行计划被确定下来之前才可以观察到。

Ø  Y意味着最终执行计划已经被确定下来。

两个初始化参数控制自适应执行计划。

Ø  optimizer_adaptive_features 完全启用或禁用该特性。将这个参数设置为FALSE时,会禁用自适应执行计划。默认值是TRUE。

Ø  optimizer_adaptive_reporting_only在报告模式下启用或禁用自适应执行计划。这个模式对于评估执行计划是否会因为自适应执行计划而改变非常有用。当设置为TRUE时,就会生成自适应执行计划,SQL引擎会检查转折点,但是SQL引擎只会使用默认的执行计划。然后,通过下面的例子所示的报告特性,可以检查如果完全启用自适应执行计划,那么会使用哪一个执行计划。默认值是FALSE:

ALTER SESSION SET optimizer_adaptive_reporting_only = TRUE;

select * FROM t1,t2 WHERE ti.id = t2.id AND t1.n=666;

select * FROM table(dbms_xplan.display_cursor(format=>'basic +predicate +note +adaptive +report'));

为了控制在语句级别是否用了自适应计划,自12.1.0.2起可使用hint(no_)adaptive_plan。

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

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

相关文章

创建一个Java项目并在项目中新建文件,最后实现程序简单的输出

目录 前言 一、建立项目及新建Java类 二、输入简单代码实现输出 前言 1.本文所讲的是java程序设计语言&#xff0c;其内容是如何在id中新建一个项目&#xff0c;并新建一个Java文件&#xff0c;在其内输入相关代码并对其输出&#xff1b; 2.Java文件的编写以收入到我的专栏…

Docker torchserve 部署模型流程

1.拉取官方镜像 地址: https://hub.docker.com/r/pytorch/torchserve/tags docker pull pytorch/torchserve:0.7.1-gpu2. docker启动指令 CPU docker run --rm -it -d -p 8380:8080 -p 8381:8081 --name torch-server -v /path/model-server/extra-files:/home/model-serve…

计算机毕业设计选题推荐-4S店试驾平台-小程序/App

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

js 如何代码识别Selenium+Webdriver

Python 的 Selenium 可以模拟用户操作打开浏览器&#xff0c;前端如何去识别是人机还是真人&#xff1a; window.navigator.webdriver Selenium 人机下是这样的&#xff1a; 正常使用&#xff1a;

Makefile语法详解

目录 1 Makefile基本常识1.1 基本格式1.2 makefile规则1.3 伪目标1.4 变量的使用1.5 赋值方式1.6 常用函数 2 Makefile整体编译2.1 编译选项2.2三个.c整体编译2.3 静态库编译2.4 动态库编译 1 Makefile基本常识 1.1 基本格式 如下所示为Makefile的基本格式&#xff0c;特别需…

高等数学 2.5 函数的微分

文章目录 一、微分的定义二、微分的几何意义三、微分运算1、函数和、差、积、商的微分法则2、复合函数的微分法则 四、微分在近似计算中的应用 一、微分的定义 定义 设函数 y f ( x ) y f(x) yf(x) 在某区间内有定义&#xff0c; x 0 x_0 x0​ 及 x 0 Δ x x_0 \Delta x …

大模型时代:普通人如何获利

随着人工智能技术的飞速发展&#xff0c;我们正步入一个以大模型为驱动力的新时代。这些大型语言模型&#xff0c;如GPT-3和BERT&#xff0c;已经在各个领域展现出惊人的能力&#xff0c;包括文本生成、翻译、问答等。这些技术的进步不仅改变了我们的生活&#xff0c;也为普通人…

【数据结构初阶】顺序结构二叉树(堆)接口实现超详解

文章目录 1.树1. 1 树的概念与结构1. 2 树的相关术语1. 3 树的表示1. 4 树形结构实际运用场景 2.二叉树2. 1 概念与结构2. 2 特殊的二叉树2. 2. 1 满二叉树2. 2. 2 完全二叉树 2. 3 二叉树存储结构2. 3. 1 顺序结构2. 3. 2 链式结构 3. 实现顺序结构二叉树&#xff08;小堆&…

【OJ刷题】双指针问题6

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;OJ刷题入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 目录 1…

ThreadX源码:Cortex-A7的tx_thread_irq_nesting_start(嵌套中断开始动作).s汇编代码分析

0 参考资料 Cortex M3权威指南(中文).pdf&#xff08;可以参考ARM指令集用法&#xff09; 1 前言 tx_thread_irq_nesting_start.s是用来实现Cortex-A7 IRQ嵌套中断的开始函数实现的汇编文件。 2 源码分析 源码如下&#xff1a; &#xff11;  IRQ_DISABLE 0x80…

遍历指定的目录a中的所有子目录及所有文件os.walk(root_dir)

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 遍历指定的目录a 中的所有子目录 及所有文件 os.walk(root_dir) [太阳]选择题 已知已经存在的目录和文件情况如下&#xff1a; a目录下有子目录b&#xff0c;有两个文件&#xff1a;a1.txt和…

Flet全平台开发:软件开发界勇士为Python语言补短板的一次极具挑战性的尝试、冲刺和华丽亮相

一、Flet创始人和开发者介绍、开发Flet的背景介绍 Flet 的创始人和开发者 Feodor Fitsner 是俄罗斯人&#xff0c;就职于微软。 Flet 的第一个版本于 2022 年 6 月发布。这是一个相对较新的库&#xff0c;它基于 Flutter 框架&#xff0c;首先支持的是用 Python 语言开发软件…

2024/9/17 pytorch-卷积神经网络

一、torch.nn pytorch有很多接口&#xff0c;其中的torch.nn可以让我们方便的调用以便生成神经网络各层 1.torch.nn.Module 是一个构成神经网络层的一个基本类别&#xff0c;一般生成一个类别来继承nn.module torch.tensor(a)将a初始化为一个tensor类型数据 一般这种已经固…

攻防世界--->hackme

学习笔记。 下载 查壳。 64ida打开。 进入main&#xff1a; 跟进&#xff1a; 这是密文 咋一看这程序感觉很复杂&#xff0c;很复杂&#xff1a; 脚本&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h>int main() {unsigned char …

Qt --- 信号和信号槽

前言 Linux信号Signal&#xff0c;系统内部的通知机制&#xff0c;进程间通信方式。 信号源&#xff1a;谁发的信号。 信号的类型&#xff1a;哪种类别的信号。 信号的处理方式&#xff1a;注册信号处理函数&#xff0c;在信号被触发的时候自动调用执行。 Qt中的信号和Lin…

Bugku---密码学---乐谱密码

题目出处&#xff1a;首页 - Bugku CTF ✨打开后发现是一张乐符图 ✨一般我们所熟悉的「Do Re Mi Fa Sol La Si」&#xff0c;若写成音名&#xff0c;即是「C D E F G A B」。不过德国人习惯使用的音名则是「C D E F G A H」&#xff0c;「B」代表 音名B♭ 。 C也就是后面的4&…

Rust练手项目,写个有趣的小工具定时从一言网获取一段有趣的话并推送通知

Rust练手项目&#xff0c;写个有趣的小工具 代码 继续练习Rust, 写个小工具定时从一言网获取一段有趣的话并提示&#xff0c;如下 练习以下Rust点 并发编程 Mutex, Arc指针使用HTTP请求Windows Gui 代码 Cargo.toml [package] name "funny_word" edition "20…

YOLOv8目标检测模型——遥感小目标检测经验分享

小目标检测——YOLOV8 一、引言 背景介绍 &#xff08;1&#xff09;目标检测的重要性 目标检测在许多领域都具有极其重要的作用。在自动驾驶中&#xff0c;目标检测能够识别道路上的障碍物和行人&#xff0c;确保行车安全。在视频监控中&#xff0c;目标检测能够实时发现异…

【matlab】生成 GIF 的函数(已封装可直接调用)

文章目录 前言一、函数输入与输出二、函数代码三、例程&#xff08;可直接运行&#xff09;参考文献 前言 生成 gif 图片时遇到的问题&#xff0c;为了后续调用方便&#xff0c;封装为函数 一、函数输入与输出 输入&#xff1a; cell_figure: cell 数组&#xff0c;数组元素是…

Chainlit集成LlamaIndex并使用通义千问模型实现AI知识库检索网页对话应用增强版

前言 之前使用Chainlit集成LlamaIndex并使用通义千问大语言模型的API接口&#xff0c;实现一个基于文档文档的网页对话应用。 可以点击我的上一篇文章《Chainlit集成LlamaIndex并使用通义千问模型实现AI知识库检索网页对话应用》 查看。 本次针对上一次的代码功能进一步的完善…