面试专题:Mysql

news2025/2/12 8:17:06

1.说说自己对于 MySQL 常见的两种存储引擎:MyISAM与InnoDB的理解

关于二者的对比与总结:
1.count运算上的区别:因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的。而对于InnoDB来说,则没有这种缓存。
2.是否支持事务和崩溃后的安全恢复: MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
3.是否支持外键: MyISAM不支持,而InnoDB支持。
MyISAM更适合读密集的表,而InnoDB更适合写密集的的表。 在数据库做主从分离的情况下,经常选择MyISAM作为主库的存储引擎。   一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB是不错的选择。如果你的数据量很大(MyISAM支持压       缩特性可以减少磁盘的空间占用),而且不需要支持事务时,MyISAM是最好的选择。

2.数据库索引了解吗?

 

聚集索引与非聚集索引

我们平时建表的时候都会为表加上主键, 在某些关系数据库中, 如果建表时不指定主键
,数据库会拒绝建表的语句执行。如果定义了主键,InnoDB会自动使用主键来创建聚集索
引。如果没有定义主键,InnoDB会选择一个唯一的非空索引代替主键。如果没有唯一的非
空索引,InnoDB会隐式定义一个主键来作为聚集索引。)

MyISAM:

B+Tree叶节点存放的是数据记录的地址,在检索的时候,先找到索引对应的数据记录的
地址,再根据地址读取相应的数据记录,这种查找方式被称为“非聚集索引”。

 InnoDB:

它的主键索引是聚集索引,即主键和行记录放在同一个叶节点,找到了主键也就找到
了行记录;而它的非主键索引,或者说是辅助索引,是非聚集索引,跟MyISAM引擎的
非聚集索引不同的是,MyISAM叶节点保存的是地址,而InnoDB是主键,InnoDB非聚
集索引的索引文件和数据文件分开存储,索引文件的叶节点只保存主键,在查找时,
要先找到叶节点中的主键,再根据主键去主索引文件查找详细行记录;因此,在设计
表的时候,主键字段不宜过长。

为什么要给表加上主键?

事实上, 一个加了主键的表,并不能被称之为「表」。
一个没加主键的表,它的数据无序的放置在磁盘存储器上,一行一行的排列的很整齐
如果给表上了主键,那么表在磁盘上的存储结构就由整齐排列的结构转变成了树状结构, 
也就是上面说的「平衡树」结构
换句话说,就是整个表就变成了一个索引,是所谓的「聚集索引」。
这就是为什么一个表只能有一个主键,一个表只能有一个「聚集索引」,因为主键的作
用就是把「表」的数据格式转换成「索引(平衡树)」的格式放置。

为什么索引能提高查询速度?

其中树的所有结点(底部除外)的数据都是由主键字段中的数据构成,也就是通常我们指定主键的id字段。最下面部分是真正表中的数据。

假如我们执行一个SQL语句: select * from table where id = 1256;
首先根据索引定位到1256这个值所在的叶结点,然后再通过叶结点取到id等于1256的数据行。
这里不讲解平衡树的运行细节, 但是从上图能看出,树一共有三层, 从根节点至叶节点只
需要经过几次查找就能得到结果。如下图

 

 要找到id为8的记录简要步骤:

 

很明显的是:没有用索引我们是需要遍历双向链表来定位对应的页,现在通过 “目录” 就可以很快地定位到对应的页上了!(二分查找,时间复杂度近似为O(logn))

其实底层结构就是B+树,B+树作为树的一种实现,能够让我们很快地查找出对应的记录。   

假如一张表有一亿条数据 ,需要查找其中某一条数据,按照常规逻辑, 一条一条的
去匹配的话,最坏的情况下需要匹配一亿次才能得到结果,用大O标记法就是O(n)最坏
时间复杂度,这是无法接受的,而且这一亿条数据显然不能一次性读入内存供程序使用。
因此, 这一亿次匹配在不经缓存优化的情况下就是一亿次IO开销,以现在磁盘的IO能
力和CPU的运算能力, 有可能需要几个月才能得出结果。
如果把这张表转换成平衡树结构(一棵非常茂盛和节点非常多的树),假设这棵树有10
层,那么只需要10次IO开销就能查找到所需要的数据, 速度以指数级别提升。
n是记录总树,底数是树的分叉数,结果就是树的层次数。换言之,查找次数是以树的
分叉数为底,记录总数的对数,用公式来表示就是

用程序来表示就是Math.Log(100000000,10),100000000是记录数,10是树的分叉数(真实环境下分叉数远不止10),
结果就是查找次数,这里的结果从亿降到了个位数。因此,利用索引会使数据库查询有惊人的性能提升。 

为什么加索引后会使写入、修改、删除变慢?

然而, 事物都是有两面的, 索引能让数据库查询数据的速度上升, 而使写入数据的
速度下降,原因很简单的,
因为平衡树这个结构必须一直维持在一个正确的状态, 增删改数据都会改变平衡树
各节点中的索引数据内容,破坏树结构, 因此,在每次数据改变时,
DBMS必须去重新梳理树(索引)的结构以确保它的正确,这会带来不小的性能开销,
也就是为什么索引会给查询以外的操作带来副作用的原因。

讲完聚集索引 , 接下来聊一下非聚集索引, 也就是我们平时经常提起和使用的常规索引。

非聚集索引和聚集索引一样, 同样是采用平衡树作为索引的数据结构。索引树结构中各
节点的值来自于表中的索引字段。
假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成,在数据改
变时, DBMS需要一直维护索引结构的正确性。如果给表中多个字段加上索引 , 那么就
会出现多个独立的索引结构,每个索引(非聚集索引)互相之间不存在关联。
如下图

每次给字段建一个新索引, 字段中的数据就会被复制一份出来, 用于生成索引。
 因此, 给表添加索引,会增加表的体积, 占用磁盘存储空间。

 

非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 
而通过非聚集索引可以查到记录对应的主键值 ,
再使用主键的值通过聚集索引查找到需要的数据,如下图

不管以任何方式查询表, 最终都会利用主键通过聚集索引来定位到数据, 聚集索引
(主键)是通往真实数据所在的唯一路径。

然而, 有一种例外可以不使用聚集索引就能查询出所需要的数据, 这种非主流的
方法 称之为「覆盖索引」查询。
也就是平时所说的复合索引或者多字段索引查询。 文章上面的内容已经指出, 当为
字段建立索引以后, 字段中的内容会被同步到索引之中。
如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至索引之中。

 

先看下面这个SQL语句

//建立索引

create index index_birthday on user_info(birthday);

//查询生日在1991年11月1日出生用户的用户名

select user_name from user_info where birthday = ‘1991-11-1’
这句SQL语句的执行过程如下

首先,通过非聚集索引index_birthday查找birthday等于1991-11-1的所有记录的主键ID值

然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对就的真实数据(数据行)存储的位置

最后, 从得到的真实数据中取得user_name字段的值返回, 也就是取得最终的结果

什么情况下要同时在两个字段上建索引?

我们把birthday字段上的索引改成双字段的覆盖索引

create index index_birthday_and_user_name on user_info(birthday,
user_name);

这句SQL语句的执行过程就会变为

通过非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的叶
节点的内容,然而,
叶节点中除了有user_name表主键ID的值以外, user_name字段的值也在里面, 因此
不需要通过主键ID值的查找数据行的真实所在,
直接取得叶节点中user_name的值返回即可。 通过这种覆盖索引直接查找的方式, 可
以省略不使用覆盖索引查找的后面两个步骤,
大大的提高了查询性能,如下图

 

最左前缀原则 

MySQL中的索引可以以一定顺序引用多列,这种索引叫作联合索引。
如User表的name和city加联合索引就是(name,city)o而最左前缀
原则指的是,如果查询的时候查询条件精确匹配索引的左边连续一列
或几列,则此列就可以     被用到。如下:
select * from user where name=xx and city=xx ; //可以命中索引
select * from user where name=xx ; // 可以命中索引
select * from user where city=xx; // 无法命中索引
这里需要注意的是,查询的时候如果两个条件都用上了,但是顺序不同,如
 city= xx and name =xx ,那么现在的查询引擎会自动优化为匹配联合
索引的顺序,这样是能够命中索引的.
由于最左前缀原则,在创建联合索引时,索引字段的顺序需要考虑字段值去
重之后的个数,较多的放前面。
ORDERBY子句也遵循此规则。
注意避免冗余索引
冗余索引指的是索引的功能相同,能够命中 就肯定能命中 ,那么 就是冗
余索引如(name,city )和(name )这两个索引就是冗余索引,能够命
中后者的查询肯定是能够命中前者的   在大多数情况下,都应该尽量扩展
已有的索引而不是创建新索引。

MySQLS.7 版本后,可以通过查询 sys 库的schemal_r dundant_indexes
表来查看冗余索引

Mysql如何为表字段添加索引

1.添加PRIMARY KEY(主键索引)

ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )


2.添加UNIQUE(唯一索引)

ALTER TABLE `table_name` ADD UNIQUE ( `column` )


3.添加INDEX(普通索引)

ALTER TABLE `table_name` ADD INDEX index_name ( `column` )


4.添加FULLTEXT(全文索引)

ALTER TABLE `table_name` ADD FULLTEXT ( `column`)


5.添加多列索引

 

ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下:

当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下:
1.限定数据的范围:  务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内。;
2.读/写分离: 经典的数据库拆分方案,主库负责写,从库负责读;
3.垂直分区: 根据数据库里面数据表的相关性进行拆分。 例如,用户表中既有用户的登录信息又有用户的基本信息,可以将用户表拆分成两个单独的表,甚至放到单独的库做分库。简单来说垂直拆分是指数据表列的拆分,   把一张列比较多的表拆分为多张表。 如下图所示,这样来说大家应该就更容易理解了。垂直拆分的优点:    可以使得行数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分区可以简化表的结构,易于维护。垂直拆分的缺点:   主键会出现冗余,需要管理冗余列,并会引起Join操作,可以通过在应用层进行Join来解决。此外,垂直分区会让事务变得更加复杂;
4.水平分区:   保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。

水平拆分可以支撑非常大的数据量。 水平拆分是指数据表行的拆分,表的行数超过200万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。举个例子:我们可以将用户信息表拆分成多  个用户信息表,这样就可以避免单一表数据量过大对性能造成影响。水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的   数据还是在同一台机器上,其实对于提升MySQL并发能力没有什么意义,所以  水平拆分最好分库  。水平拆分能够 支持非常大的数据量存储,应用端改造也少,但 分片事务难以解决 ,跨界点Join性能较差,逻辑复杂。
《Java工程师修炼之道》的作者推荐   尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度  ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O。

下面补充一下数据库分片的两种常见方案:
1.客户端代理: 分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现。 当当网的 Sharding-
JDBC 、阿里的TDDL是两种比较常用的实现。
2.中间件代理: 在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。 我们现在谈的 Mycat
、360的Atlas、网易的DDB等等都是这种架构的实现。

事务隔离级别(图文详解)

什么是事务?
事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就    是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩
溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要   失败。

事物的特性(ACID)

1.原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
2.一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
3.隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
4.持久性:  一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

并发事务带来的问题

在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对统一数据进行操   作)。并发虽然是必须的,但可能会导致以下的问题。
脏读(Dirty  read):  当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个   事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
丢失修改(Lost to modify):  指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢

失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
不可重复读(Unrepeatableread):    指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的    数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
幻读(Phantom  read):   幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就    好像发生了幻觉一样,所以称为幻读。
不可重复度和幻读区别:
不可重复读的重点是修改,幻读的重点在于新增或者删除。
例1(同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 ):事务1中的A先生读取自己的工资为 1000的操作还没完成,事务2中的B先生就修改了A的工资为2000,导 致A再读自己的工资时工资变为 2000;这就是不可重复读。
例2(同样的条件,  第1次和第2次读出来的记录数不一样   ):假某工资单表中工资大于3000的有4人,事务1读取了所有工资大于3000的人,共查到4条记录,这时事务2 又插入了一条工资大于3000的记录,事务1再次读取时查到的记录就变为了5条,这样就导致了幻读。

事务隔离级别

SQL 标准定义了四个隔离级别:
READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
READ-COMMITTED(读取已提交):    允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
REPEATABLE-READ(可重复读):   对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE(可串行化):    最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation; 命令来查看

这里需要注意的是:与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要
求,即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。
因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内      容):,但是你要知道的是InnoDB 存储引擎默认使用 REPEATABLE-READ(可重读)并不会有任何性能损失。
InnoDB 存储引擎在 分布式事务 的情况下一般会用到SERIALIZABLE(可串行化)隔离级别。 

 

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

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

相关文章

[CKA]考试之K8s 版本升级

由于最新的CKA考试改版,不允许存储书签,本博客致力怎么一步步从官网把答案找到,如何修改把题做对,下面开始我们的 CKA之旅 题目为: Task 现有的Kubernetes 集群正在运行版本1.22.0。仅将master节点上的所有 Kuberne…

【Python】集合 set ② ( 集合常用操作 | 集合中添加元素 | 集合中移除元素 | 集合中随机取出元素 )

文章目录 一、集合中添加元素二、集合中移除元素三、集合中随机取出元素 在 Python 中 , 集合 set 是无序的 , 因此 集合 数据容器 不支持 使用 下标索引 访问 集合元素 ; 一、集合中添加元素 调用 集合#add(新元素) 函数 , 可以将新元素添加到 集合 数据容器中 ; 集合添加元素…

Vue- ref属性

ref属性 被用来给元素或者子组件注册引用信息(id的替代者) 通过案例来演示_ref属性 1 编写案例 如图:有一个按钮,点击按钮可以输出dom元素 备注:虽然vue不用我们亲自操作dom,但是有的特殊的情况下就要…

【2023华中杯】B题 小学教学应用题 相似性度量及难度评估 29页论文及MATLAB代码

1 题目 B 题 小学数学应用题相似性度量及难度评估 某 MOOC 在线教育平台希望能够进行个性化教学,实现用户自主学习。在用户学习时,系统从题库中随机抽取若干道与例题同步的随堂测试题,记录、分析学生的学习和答题信息,并且课后会自…

【Pytest实战】解决ModuleNotFoundError: No module named ‘pytest’问题

😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊 座右铭:不想…

JAVA程序的性能优化实践总结

1、 衡量程序性能的指标 可以从常用的性能评估指标入手: 并发:同一时间有多少请求访问TPS:transaction per second(每秒的事物数)QPS:query per second(每秒请求数)耗时:端到端耗时,服务端耗时&#xff…

并行计算——MPI编程

目录 基础知识 进程与线程,并行与并发 奇偶排序 MPI实现 odd-even sort 思路 环境部署 编程实现(C) “若干”的问题 参考链接 一个偶然的机会,我接触到了国立清华大学的MPI编程作业,也就接触到了并行计算。这…

基于Python3接口自动化测试初探

自动化测试是什么? 自动化测试简单来说就是借助工具的方式来辅助手动测试的行为就可以看做是自动化测试。 自动化测试工具有哪些? 现在常用的自动化测试工具包括: QTP:主要用于回归测试和测试同一软件的新版本 Robot Framewor…

大数据ETL工具Kettle

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言最近公司在搞大数据数字化,有MES,CIM,WorkFlow等等N多的系统,不同的数据源DB,需要将这些不同的数据源DB里的数据进行整治统一…

【算法】模拟,高精度

高精度加法 P1601 AB Problem(高精) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路就是模拟,值得注意的就是要用字符串类型输入。存进自己的int数组时要倒着存,因为如果是正着存的话,进位会有点trouble。 时间…

Spread.NET v16.0.20222.0 ASP.NET cRACK

关于 Spread.NET 提供类似 Excel 的电子表格体验。 Spread.NET 可帮助您创建电子表格、网格、仪表板和表单。它包括一个强大的计算引擎,具有450 函数以及导入和导出Excel电子表格的能力。利用广泛的 .NET 电子表格 API 和强大的计算引擎来创建分析、预算、仪表板、…

【C++ 基础篇:24】:【重要模板】C++ 输入输出运算符重载【以 Date 日期类为例】

系列文章说明 本系列 C 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C的三大…

Mysql Access denied for user ‘root‘@ ‘*.*.*.*‘ (using password: YES)异常处理

目录 一、异常错误二、原因三、解决方法 一、异常错误 PS C:\Users\10568> mysql -u root -p Enter password: **** ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES)Access denied表示拒绝访问,using password:NO/…

计算机视觉 | 语义分割与Segmentation

前 言 「MMSegmentation」 是一个基于 PyTorch 的语义分割开源工具箱。它是 OpenMMLab 项目的一部分。 MMSegmentation v1.x 在 0.x 版本的基础上有了显著的提升,提供了更加灵活和功能丰富的体验。 主要特性 统一的基准平台 我们将各种各样的语义分割算法集成到了…

Linux权限维持

SSH后门&VIM后门 ssh后门: 创建一个软链接: ln -sf /usr/sbin/sshd /tmp/su 拓展:软链接相当于一个快捷键,硬链接相当于一个指针指向文件地址,也类似于复制 开启后门: /tmp/su -oport12345 开启后…

chatgpt赋能python:Python另存为:如何保存你的程序代码

Python另存为:如何保存你的程序代码 简介 Python是一种高级编程语言,最初由Guido van Rossum于1991年创建。自创建以来,Python已被广泛应用于Web开发、数据分析、人工智能等领域。作为一名有10年Python编程经验的工程师,我发现在…

万物的算法日记|第一天

笔者自述: 一直有一个声音也一直能听到身边的大佬经常说,要把算法学习搞好,一定要重视平时的算法学习,虽然每天也在学算法,但是感觉自己一直在假装努力表面功夫骗了自己,没有规划好自己的算法学习和总结&am…

内部服务器端口映射实验:打通内外网络,实现公网访问内部服务

内部服务器端口映射实验:打通内外网络,实现公网访问内部服务 【实验目的】 部署服务器地址转换。熟悉服务器地址转换的应用方法。验证配置。 【实验拓扑】 实验拓扑如图所示。 实验拓扑 设备参数如表所示。 设备参数表 设备 接口 IP地址 子网掩…

BOM,什么是BOM?

4.BOM 4.1 什么是BOM? BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window。 ​ BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。 …

react---todoList案例

todoList案例效果图 1.组件拆分 2.操作state数据 state 放在哪个组件: 如果某个组件组件使用: 放在其自身的state中。如果某些组件使用:放在他们共同的父组件state中(官方称此操作为状态提升) 状态(state)在…