Oracle 如何给大表添加带有默认值的字段
一、讲故事
你是否遇到过开发人员添加字段,导致数据库锁表问题?
但是令开发疑惑的事,他们添加字段,有的时候很快,有的时候很慢? 为什么呢?
询问得知,**加的慢时候是带上了default默认值,如果表的数据量很大,那么会花费很长时间。在加字段期间,表上还会加6级锁,连select都会被阻塞。**这在生产系统是不可接受的。
所以,任何DDL操作,都应该询问DBA是否有风险。
从11g开始,这种情况有了明显的改善。Oracle 11g引入了元数据唯一默认值的概念。如果增加的列符合default+not null这两个条件的话,它只会去更新数据字典,不会去更新物理行,所以操作可以很短的时间完成,且不会对生产产生影响。读取列数据的时候优化器重写新列的查询,以确保结果与默认定义一致。
注意:这两个条件(列符合default且not null)缺一不可,否则还是会很慢。
从Oracle 12c更进一步,允许元数据默认值not null 可选,因此,在现有表中添加带有默认子句的新列将被作为一个元数据来处理,而不管该列是否被定义not null,两种方式操作都很快。
二、讲实战
1. 模拟大表
SQL> drop table test1; #执行这个sql前,需要确认test1表是不是能删除。表名可以自己换成别的表。Table dropped.SQL> create table test as select * from dba_objects;Table created.SQL> insert into test1 select * from test;79699 rows created
.....
SQL> insert into test1 select * from test;1275200 rows created.SQL> commit;Commit complete.--11g 环境下表初始大小:
SQL> select bytes from user_segments where segment_name='TEST1';BYTES
----------301989888--19c 环境下表初始大小:SQL> select bytes from user_segments where segment_name='TEST1';BYTES
----------739246080
2. 11g 环境下测试
2.1 增加字段
情况1:只有default值
-- 不加not null约束
SQL> alter table test1 add a varchar2(100) default 'aa';Table altered.Elapsed: 00:00:42.62SQL> select count(*) from test1 where a='aa';COUNT(*)
----------2550400
Elapsed: 00:00:00.24SQL> select bytes from user_segments where segment_name='TEST1';BYTES
----------578813952Elapsed: 00:00:00.01
情况2:default+not null
--加上not null 约束
SQL> alter table test1 add b varchar2(100) default 'bb' not null;Table altered.Elapsed: 00:00:00.04SQL> select count(*) from test1 where b='bb';COUNT(*)
----------2550400Elapsed: 00:00:00.23SQL> select bytes from user_segments where segment_name='TEST1';BYTES
----------578813952Elapsed: 00:00:00.01
可以看到:
1.default+not null 的执行时间远小于只有default值的情况。
2.default+not null 表的大小也没有变化,说明表并没有实际去更新物理行,只是更新了数据字典。
这是11g对新增一个not null字段带有默认值进行了优化,默认值以及对应的表信息、列信息一起存储在一个新增数据字典表ecol$中 。
2.2 查询test1表中添加的默认值
SQL> select object_id from dba_objects where object_name = 'TEST1' and owner='SXC';OBJECT_ID
----------97662SQL> set line222
SQL> select colnum,binarydefval from ecol$ where tabobj#= 97662;COLNUM BINARYDEFVAL
---------- ----------------------------------17 6262
SQL> desc ecol$Name Null? Type----------------------------------------- -------- ----------------------------TABOBJ# NUMBERCOLNUM NUMBERBINARYDEFVAL BLOB-- 注意:binarydefval 是blob 类型,所有实际存储的值并不是数值6262,可以通过下面的存储过程查看真实存储的值是bb
SQL> SET SERVEROUT ON
SQL>
SQL> DECLARE2 V_BLOB VARCHAR2(32767) DEFAULT '6262';3 BEGIN4 FOR I IN 1..LENGTH(V_BLOB)/2 LOOP5 DBMS_OUTPUT.PUT(CHR(TO_NUMBER(SUBSTR(V_BLOB, (I-1) * 2 + 1, 2), 'XXX')));6 END LOOP;7 DBMS_OUTPUT.NEW_LINE;8 END;9 /
bbPL/SQL procedure successfully completed.
2.3 对比执行计划
如果我们从表中检索对应的列时候,我们对比一下执行计划:
情况1:只有default值
SQL> select count(*) from test1 where a='aa';COUNT(*)
----------2550368SQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID b91qrsffc9t3d, child number 0
-------------------------------------
select count(*) from test1 where a='aa'Plan hash value: 3896847026----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 9972 (100)| |
| 1 | SORT AGGREGATE | | 1 | 52 | | |PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
|* 2 | TABLE ACCESS FULL| TEST1 | 2886K| 143M| 9972 (1)| 00:02:00 |
----------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter("A"='aa')Note
------ dynamic sampling used for this statement (level=2)PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------23 rows selected.
结论:采用filter(“A”=‘aa’) 过滤的方式,直接读取列数据。
情况2:default+not null
SQL> select count(*) from test1 where b='bb';COUNT(*)
----------2550368SQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 9xurwt6ytwjf0, child number 0
-------------------------------------
select count(*) from test1 where b='bb'Plan hash value: 3896847026----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 9974 (100)| |
| 1 | SORT AGGREGATE | | 1 | 52 | | |PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
|* 2 | TABLE ACCESS FULL| TEST1 | 2886K| 143M| 9974 (1)| 00:02:00 |
----------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter(NVL("B",'bb')='bb')Note
------ dynamic sampling used for this statement (level=2)PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------23 rows selected.
结论:采用filter(NVL(“B”,‘bb’)=‘bb’)方式过滤,读取列数据,但是oracle认为default+not null 的方式添加的列是空列,所以用nvl函数做了一次转换。
※思考?
1、如果我们在列上建索引呢?
SQL> create index idx1 on test1 (b);Index created.SQL> select count(*) from test1 where b='bb';COUNT(*)
----------2550368SQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 9xurwt6ytwjf0, child number 0
-------------------------------------
select count(*) from test1 where b='bb'Plan hash value: 325870156------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1391 (100)| |
| 1 | SORT AGGREGATE | | 1 | 52 | | |PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------
|* 2 | INDEX FAST FULL SCAN| IDX1 | 2886K| 143M| 1391 (1)| 00:00:17 |
------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter(NVL("B",'bb')='bb')Note
------ dynamic sampling used for this statement (level=2)PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------23 rows selected.
结论:虽然从全表扫描变成索引扫描,但是一样是NVL(“B”,‘bb’)='bb’方式过滤数据。
2、后续新增加的数据呢?
-- 增加2行数据,一个用默认值,一个不用默认值。
SQL> select * from test1 where owner='T';no rows selectedSQL> insert into test1 (owner,b) values ('T',default);1 row created.SQL> insert into test1 (owner,b) values ('T','bbb');1 row created.SQL> commit;Commit complete.--访问默认值,查看执行计划
SQL> select owner,b from test1 where owner='T' and b='bb';OWNER B
----------------------------------------
T bbSQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID dyd1zgs10jr16, child number 0
-------------------------------------
select owner,b from test1 where owner='T' and b='bb'Plan hash value: 4122059633---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 9974 (100)| |
|* 1 | TABLE ACCESS FULL| TEST1 | 287 | 19803 | 9974 (1)| 00:02:00 |PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------1 - filter(("OWNER"='T' AND NVL("B",'bb')='bb'))Note
------ dynamic sampling used for this statement (level=2)22 rows selected.--访问非默认值,查看执行计划
SQL> select owner,b from test1 where owner='T' and b='bbb';OWNER B
----------------------------------------
T bbbSQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 5mbna21dqafdw, child number 0
-------------------------------------select owner,b from test1 where owner='T' and b='bbb'Plan hash value: 2734693028-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 9 (100) | |
|* 1 | TABLE ACCESS BY INDEX ROWID| TEST1 | 287 | 19803 | 9 (0)| 00:00:01 |PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------
|* 2 | INDEX RANGE SCAN | IDX1 | 403 | | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------1 - filter("OWNER"='T')2 - access(NVL("B",'bb')='bbb')Note
-----PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------- dynamic sampling used for this statement (level=2)24 rows selected.
结论:新增的数据,执行计划中一样都是采用NVL(“B”,‘bb’)='bb’方式。
2.4 表压缩后限制
1. 添加列报错
表压缩之后,default+not null是可以操作的;但是只有default是不行的。
SQL> alter table test1 compress;Table altered.SQL> alter table test1 add c number default 3 not null;Table altered.SQL> alter table test1 add d number default 4;
alter table test1 add d number default 4*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables
解决办法:但是这种方法,只有之后新插入的行才是有值的,之前已经存在的行是没有的,还是空,所以需要找时间批量提交修改。
SQL> alter table test1 add d number;Table altered.SQL> alter table test1 modify d number default 4;Table altered.SQL> select count(*) from test1 where d=4;COUNT(*)
----------0-- 可以批量更改
SQL> update test1 set d=4 where d is null;2550368 rows updated.SQL> commit;Commit complete.
2. 删除列报错
-- 直接drop column报错
SQL> alter table test1 drop column c;
alter table test1 drop column c*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables-- 尝试先把列设成unused方式,再删除一样报错
SQL> alter table test1 set unused column c;Table altered.SQL> alter table test1 drop unused columns;
alter table test1 drop unused columns
*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables
结论:根据Doc ID 1574318.1 描述,暂时没有好的解决方法,只能针对oltp compress 方式可以删除列。
SQL> alter table t2 compress for oltp; --加上for oltpTable altered.SQL> alter table t2 drop column id;Table altered.SQL> alter table t2 compress;Table altered.SQL> alter table t2 drop column T1_ID;
alter table t2 drop column T1_ID*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables
官方文档:
3. 在Oracle19C 环境下测试
3.1 增加字段
情况1:只有default值
-- 不加not null约束
SQL> alter table test1 add a varchar2(100) default 'aa';Table altered.Elapsed: 00:00:00.02SQL> select count(*) from test1 where a='aa';COUNT(*)
----------4643072Elapsed: 00:00:01.05SQL> select bytes from user_segments where segment_name='TEST1';BYTES
----------739246080Elapsed: 00:00:00.01
情况2:default+not null
--加上not null 约束
SQL> alter table test1 add b varchar2(100) default 'bb' not null;Table altered.Elapsed: 00:00:00.06SQL> select count(*) from test1 where b='bb';COUNT(*)
----------4643072Elapsed: 00:00:00.23SQL> select bytes from user_segments where segment_name='TEST1';BYTES
----------739246080Elapsed: 00:00:00.01
可以看到:
1.和11g不一样,default+not null 和只加default 速度一样快。
2.两种方式表的大小都没有变化,说明表都没有实际去更新物理行,都只是更新了数据字典。
3.2 查询test1表中添加的默认值
SQL> select object_id from dba_objects where object_name = 'TEST1' and owner='SXC';OBJECT_ID
----------73797SQL> set line222
SQL> select colnum,binarydefval from ecol$ where tabobj#= 73797;COLNUM BINARYDEFVAL
---------- -----------------------28 616129 6262-- 比11g 多出一行,不管是否有加上not null 条件,都被存储到了ecol$表中。SQL> SET SERVEROUT ON
SQL> DECLARE2 V_BLOB VARCHAR2(32767) DEFAULT '6161';3 BEGIN4 FOR I IN 1..LENGTH(V_BLOB)/2 LOOP5 DBMS_OUTPUT.PUT(CHR(TO_NUMBER(SUBSTR(V_BLOB, (I-1) * 2 + 1, 2), 'XXX')));6 END LOOP;7 DBMS_OUTPUT.NEW_LINE;8 END;9 /
aaSQL> DECLARE2 V_BLOB VARCHAR2(32767) DEFAULT '6262';3 BEGIN4 FOR I IN 1..LENGTH(V_BLOB)/2 LOOP5 DBMS_OUTPUT.PUT(CHR(TO_NUMBER(SUBSTR(V_BLOB, (I-1) * 2 + 1, 2), 'XXX')));6 END LOOP;7 DBMS_OUTPUT.NEW_LINE;8 END;9 /
bbPL/SQL procedure successfully completed.
3.3 对比执行计划
如果我们从表中检索对应的列时候,我们对比一下执行计划:
情况1:只有default值
SQL> select count(*) from test1 where a='aa';COUNT(*)
----------4643072SQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 12bwjcp0zanhm, child number 0
-------------------------------------select count(*) from test1 where a='aa'Plan hash value: 3896847026----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 394 (100)| |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | TABLE ACCESS FULL| TEST1 | 72548 | 212K| 394 (1)| 00:00:01 |
----------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter(DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00027$",0)),NULL,NVL("A",'aa'),'0',NVL("A",'aa'),'1',"A")='aa')20 rows selected.Elapsed: 00:00:14.13
结论:和11g 不一样,这里即采用了nvl函数转化,也多了一个隐藏列SYS_NC00027$,通过下面的SQL可以查询到。这个隐藏列是在添加default的列的时候增加的,添加default+not null 的列没有。
SQL> select column_name,column_id,hidden_column,virtual_column from dba_tab_cols where table_name='TEST1' and owner='SXC';COLUMN_NAME COLUMN_ID HIDDEN VIRTUA
---------------------------------------- ------ ------------------
OWNER 1 NO NO
...
MODIFIED_VSNID 26 NO NO
SYS_NC00027$ YES NO -- 隐藏列
A 27 NO NO
B 28 NO NO
情况2:default+not null
SQL> select count(*) from test1 where b='bb';COUNT(*)
----------4643072SQL> select * from table(dbms_xplan.display_cursor);PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 9xurwt6ytwjf0, child number 0
-------------------------------------
select count(*) from test1 where b='bb'Plan hash value: 3896847026----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 394 (100)| |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | TABLE ACCESS FULL| TEST1 | 72548 | 212K| 394 (1)| 00:00:01 |
----------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter(NVL("B",'bb')='bb')19 rows selected.Elapsed: 00:00:01.22
结论:和11g 方式一样,都是采用filter(NVL(“B”,‘bb’)=‘bb’)过滤,读取列数据,并且使用了nvl函数。
※思考?
1、如果我们在列上建索引呢?
2、后续新增加的数据呢?
结论:测试下来,大体结果和11g 一样。 都会使用隐藏列SYS_NC00027$和NVL函数转化。
3.4 表压缩后限制
1. 添加列
SQL> alter table test1 compress;Table altered.SQL> alter table test1 add c number default 3 not null;Table altered.SQL> alter table test1 add d number default 4;Table altered.
结论:和11g不一样,19c表compress之后, 两种方式都能添加列 。
但是,在12c环境下,表compress之后, 两种方式都不能添加列 。
SQL> create table T1 ( a number, b varchar2(10) ) compress ;Table created.SQL> alter table T1 add c varchar2(20) default 'test' not null ;
alter table T1 add c varchar2(20) default 'test' not null*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tablesSQL> alter table T1 add c varchar2(20) default 'test' ;
alter table T1 add c varchar2(20) default 'test'*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables
2. 删除列报错
-- 直接drop column报错
SQL> alter table test1 drop column c;
alter table test1 drop column c*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables-- 尝试先把列设成unused方式,再删除一样报错
SQL> alter table test1 set unused column c;Table altered.SQL> alter table test1 drop unused columns;
alter table test1 drop unused columns
*
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables
结论:和11g一样,暂时没有好的解决方法,只能针对oltp compress 方式可以删除列。
相关文章:

Oracle 如何给大表添加带有默认值的字段
一、讲故事 你是否遇到过开发人员添加字段,导致数据库锁表问题? 但是令开发疑惑的事,他们添加字段,有的时候很快,有的时候很慢? 为什么呢? 询问得知,**加的慢时候是带上了default默…...

记录Taro大坑2丢失api无法启动
现象 解决方案 看了很多。很多说要改成一致的版本号。其实没什么用。 正确方案 再新建一个模板跑起来对比config的配置,以及package.json发现关闭预编译即可。预编译导致api丢失...
Java-Maven-解决maven deploy时报 401 Reason Phrase Unauthorized 错误
Java-Maven-解决maven deploy时报 401 Reason Phrase Unauthorized 错误 环境 Java JDK 1.8Maven 3.3.9 引言 项目需要打成jar包上传到私服,供其它项目引用。此时需要执行 mvn clean deploy 命令,执行过程中报 401 错误。 解决401错误 报错信息 执…...

【数据结构】 栈(Stack)的应用场景
文章目录 🌏前言🍀改变元素的序列🚩场景一📌解析: 🚩场景二📌解析: 🎍将递归转化为循环🌳[括号匹配](https://leetcode.cn/problems/valid-parentheses/)&…...

人力资源小程序的设计原则与实现方法
随着移动互联网的快速发展,小程序成为了各行各业推广和服务的新利器。对于人力资源行业来说,开发一款定制化的小程序不仅可以提升服务效率,还可以增强品牌形象和用户粘性。那么,如何定制开发人力资源类的小程序呢?下面…...
检查Javascript对象数组中是否存在对象值,如果没有向数组添加新对象
需求: 如果我有以下对象数组: [ { id: 1, username: fred }, { id: 2, username: bill }, { id: 2, username: ted } ]有没有办法循环遍历数组,以检查特定的用户名值是否已经存在,如果它什么都不做,但是如果它没有用…...

UG\NX二次开发 使用录制功能录制操作记录时,如何设置默认的开发语言?
文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,C\C,Qt-CSDN博客 简介: NX二次开发使用BlockUI设计对话框时,如何设置默认的代码语言? 效果: 方法: 依次打开“文件”->“实用…...

【业务功能篇83】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-应用层实战
五、ElasticSearch应用 1.ES 的Java API两种方式 Elasticsearch 的API 分为 REST Client API(http请求形式)以及 transportClient API两种。相比来说transportClient API效率更高,transportClient 是通过Elasticsearch内部RPC的形式进行请求…...

VBJSON报错:缺少:语句结束
项目中使用JSON库VBJSON时报错: 编译错误:缺少:语句结束 cJSONScript和cStringBuilder报相同的错误,都在第一行: VERSION 1.0 CLASS 研究了半天没啥结果,之前使用这个库的时候没有什么问题,所以判定是当前…...

Docker安装ES+kibana8.9.1
参考:基于Docker安装Elasticsearch【保姆级教程、内含图解】_docker elasticsearch_Acloasia的博客-CSDN博客 创建网络 docker network create es-net 基于Docker安装Elasticsearch 拉取镜像 docker pull elasticsearch:8.9.1 挂载文件 mkdir -p /usr/local/e…...

12. Oracle中case when详解
格式: case expression when condition_01 then result_01 when condition_02 then result_02 ...... when condition_n then result_n else result_default end 表达式expression符合条件condition_01,则返回…...
【电路设计】220V AC转低压DC电路概述
前言 最近因项目需要,电路板上要加上一个交流220V转低压直流,比如12V或者5V这种。一般来说,比较常见也比较简单的做法是使用一个变压器将220V AC进行降压,比如降到22V AC,但是很遗憾的是,支持220V的变压器一般体积很大,而板子留给电源部分的面积又非常有限,所以不得不研…...

网络地址转换NAT-动态NAT的使用范围和配置-思科EI,华为数通
网络地址转换NAT-动态NAT的使用范围和配置 什么是动态NAT? 使用公有地址池,并以先到先得的原则分配这些地址。当具有私有 IP 地址的主机请求访问 Internet 时,动态 NAT 从地址池中选择一个未被其它主机占用的 IP 地址一对一的转化。当数据会话…...

远程连接虚拟机中ubuntu报错:Network error:Connection refused
ping检测一下虚拟机 可以ping通,说明主机是没问题 #检查ssh是否安装: ps -e |grep ssh发现ssh没有安装 #安装openssh-server sudo apt-get install openssh-server#启动ssh service ssh startps -e |grep ssh检查一下防火墙 #防火墙状态查看 sudo ufw…...

快速排序三种思路详解!
一、快速排序的介绍 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,…...

【二叉树入门指南】链式结构的实现
【二叉树入门指南】链式结构的实现 一、前置说明二、二叉树的遍历2.1前序遍历2.2中序遍历2.3 后序遍历 三、以前序遍历为例,递归图解四、层序遍历五、节点个数以及高度等5.1 二叉树节点个数5.2二叉树叶子节点个数5.3 二叉树第k层节点个数5.4 二叉树查找值为x的节点5…...

【位运算】算法实战
文章目录 一、算法原理常见的位运算总结 二、算法实战1. leetcode面试题01.01. 判断字符是否唯一2. leetcode268 丢失的数字3. leetcode371 两整数之和4. leetcode004 只出现一次的数字II5. leetcode面试题17.19. 消失的两个数字 三、总结 一、算法原理 计算机中的数据都以二进…...
C++构建系统
收集C构建系统(2023): 跟我一起写Makefile (PDF重制版)CMake tutorialConan, software package manager for C and C developersvcpkg-repovcpkgGoogle Bazel Build System { Fast, Correct } — Choose twoGN gn_quick_start当前Chromium构建系统 GYP Generate You…...
“深入探索JVM内部机制:理解Java虚拟机的运行原理“
标题:深入探索JVM内部机制:理解Java虚拟机的运行原理 摘要:本篇博客将深入探索Java虚拟机(JVM)的内部机制,帮助读者理解JVM的运行原理。我们将介绍JVM的组成结构,包括类加载器、运行时数据区域…...

java八股文面试[JVM]——双亲委派模型
1.当AppClassLoader去加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委托给父加载器ExtClassLoader去完成。 2.当ExtClassLoader去加载一个class时,它首先也不会去尝试加载这个类,而是把类加载请求委托给父加载…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...