获得徽章 0
#青训营 x 字节后端训练营#
Git基础概念:
工作区:本地项目存放文件的位置。
暂存区:顾名思义就是暂时存放文件的地方,通过是通过add命令将工作区的文件添加到缓冲区。
本地仓库:指的就是我们本地电脑中版本控制系统的仓库。
远程仓库:指的是远程的网络仓库,需要通过网络进行交互,如GitHub、Gitte等。
Git基础概念:
工作区:本地项目存放文件的位置。
暂存区:顾名思义就是暂时存放文件的地方,通过是通过add命令将工作区的文件添加到缓冲区。
本地仓库:指的就是我们本地电脑中版本控制系统的仓库。
远程仓库:指的是远程的网络仓库,需要通过网络进行交互,如GitHub、Gitte等。
展开
评论
点赞
#青训营 x 字节后端训练营#
Redis有5个基本数据结构:
1、String:字符串类型,常用命令有set(设置值)、get(获取值)、setnx(不存在才设置值)、append(追加值)等。
2、List:列表类型,常用命令有lpush(在列表左边插入元素)、rpush(在列表右边插入元素)、lrange(返回列表指定区间内的元素)等。
3、Set:无序集合类型,常用命令有sadd(添加一个元素到key中)、smembers(获取一个key下的所有元素)等。
4、ZSet:有序集合类型,常用命令有zadd(添加一个元素至有序集合中)、zscore(返回一个member对应score的值)等。
5、Hash:哈希表类型,常用命令有hset(设置值)、hmset(批量设置值)、hvals(获取所有值)等。
Redis有5个基本数据结构:
1、String:字符串类型,常用命令有set(设置值)、get(获取值)、setnx(不存在才设置值)、append(追加值)等。
2、List:列表类型,常用命令有lpush(在列表左边插入元素)、rpush(在列表右边插入元素)、lrange(返回列表指定区间内的元素)等。
3、Set:无序集合类型,常用命令有sadd(添加一个元素到key中)、smembers(获取一个key下的所有元素)等。
4、ZSet:有序集合类型,常用命令有zadd(添加一个元素至有序集合中)、zscore(返回一个member对应score的值)等。
5、Hash:哈希表类型,常用命令有hset(设置值)、hmset(批量设置值)、hvals(获取所有值)等。
展开
评论
点赞
#青训营 x 字节后端训练营#
1、强引用:只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收。
2、软引用(SoftReference):仅有软引用引用该对象时,在一次垃圾回收后内存仍不足时,会再次触发垃圾回收,回收软引用对象。可以配合引用队列来释放软引用自身。
3、弱引用(WeakReference):仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象。可以配合引用队列来释放弱引用自身。
4、虚引用(PhantomReference):必须配合引用队列使用,主要配合 ByteBuffer 使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存。
1、强引用:只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收。
2、软引用(SoftReference):仅有软引用引用该对象时,在一次垃圾回收后内存仍不足时,会再次触发垃圾回收,回收软引用对象。可以配合引用队列来释放软引用自身。
3、弱引用(WeakReference):仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象。可以配合引用队列来释放弱引用自身。
4、虚引用(PhantomReference):必须配合引用队列使用,主要配合 ByteBuffer 使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存。
展开
评论
点赞
#青训营 x 字节后端训练营#
主动更新策略有三种主流的实现方案:Cache Aside Pattern、Read/Writer Through Pattern、Write Behind Caching Psttern。
Cache-Aside,也叫旁路缓存模式,在三种方案中,旁路缓存模块可以最大程度解决缓存与数据库数据不一致的问题,注意是尽可能的解决,并无法做到绝对解决。
一般都是使用Cache Aside Pattern实现方案,虽然会稍微复杂一点,但是可以我们自己人为控制。
主动更新策略有三种主流的实现方案:Cache Aside Pattern、Read/Writer Through Pattern、Write Behind Caching Psttern。
Cache-Aside,也叫旁路缓存模式,在三种方案中,旁路缓存模块可以最大程度解决缓存与数据库数据不一致的问题,注意是尽可能的解决,并无法做到绝对解决。
一般都是使用Cache Aside Pattern实现方案,虽然会稍微复杂一点,但是可以我们自己人为控制。
展开
评论
点赞
#青训营 x 字节后端训练营#
链表有很多种不同的类型:1、单向链表 2、双向链表 3、循环链表
链表优点:1、插入删除速度快 2、内存利用率高,不会浪费内存 3、大小没有固定,拓展很灵活
链表缺点:1、只能从头结点开始,按照指针进行顺序访问,所以导致查询效率低,也就是随机读写慢
链表有很多种不同的类型:1、单向链表 2、双向链表 3、循环链表
链表优点:1、插入删除速度快 2、内存利用率高,不会浪费内存 3、大小没有固定,拓展很灵活
链表缺点:1、只能从头结点开始,按照指针进行顺序访问,所以导致查询效率低,也就是随机读写慢
展开
评论
点赞
#青训营 x 字节后端训练营#
在 MySQl5.6 版本中,带来了 index condition pushdown,简称ICP,也就是索引下推。
索引下推逐个扫描并 筛选数据花费的时间<索引下推减少的回表次数 从而节省的时间,即 后者时间-前者时间>0 ,那么就会使用索引下推来优化查询性能。MySQL查询语句的优化,就是基于成本的,谁便宜就选谁!
在 MySQl5.6 版本中,带来了 index condition pushdown,简称ICP,也就是索引下推。
索引下推逐个扫描并 筛选数据花费的时间<索引下推减少的回表次数 从而节省的时间,即 后者时间-前者时间>0 ,那么就会使用索引下推来优化查询性能。MySQL查询语句的优化,就是基于成本的,谁便宜就选谁!
展开
评论
点赞
#青训营 x 字节后端训练营#
MySQL中两阶段提交主要指的是redo log的两阶段提交,两阶段提交是为了解决在MySQL主从架构下,由redo log和bin log不同步而导致主从机数据不一致问题。
两阶段提交将redo log的提交拆分为两次提交,此时事务对redo log和bin log的写入顺序为
1、事务执行过程中,写入redo log并标记redo log为prepare阶段
2、事务完成后,写入bin log
3、写完bin log后,标记redo log为commit阶段
在这样的顺序下,即使在第二步执行时,MySQL宕机了,MySQL主机在恢复时,会有三种情况:
1、redo log的状态为commit,代表bin log也成功写入了,则提交事务
2、redo log的状态为prepare,但bin log中存在对应的事务信息,依旧提交事务
3、redo log的状态为prepare,并且bin log中不存在对应的事务信息,则回滚事务。
可以看到,两阶段提交成功保证了MySQL主从机的数据一致性。
MySQL中两阶段提交主要指的是redo log的两阶段提交,两阶段提交是为了解决在MySQL主从架构下,由redo log和bin log不同步而导致主从机数据不一致问题。
两阶段提交将redo log的提交拆分为两次提交,此时事务对redo log和bin log的写入顺序为
1、事务执行过程中,写入redo log并标记redo log为prepare阶段
2、事务完成后,写入bin log
3、写完bin log后,标记redo log为commit阶段
在这样的顺序下,即使在第二步执行时,MySQL宕机了,MySQL主机在恢复时,会有三种情况:
1、redo log的状态为commit,代表bin log也成功写入了,则提交事务
2、redo log的状态为prepare,但bin log中存在对应的事务信息,依旧提交事务
3、redo log的状态为prepare,并且bin log中不存在对应的事务信息,则回滚事务。
可以看到,两阶段提交成功保证了MySQL主从机的数据一致性。
展开
评论
点赞
#青训营 x 字节后端训练营#
MVCC(Multi Version Concurrency Control),也叫多版本并发控制,顾名思义,就是通过记录的多个版本来实现数据库的并发控制。
MySQL之所以可以在可重复读隔离阶段就解决幻读问题,主要依靠于MVCC和锁机制,锁机制是一种悲观锁的实现方式,而MVCC是一种乐观锁的实现方式,使数据库具有更好的并发性能。
MVCC主要依赖于三样东西实现,分别是记录的隐藏字段(聚簇索引才有)、undo log、Read View。
MVCC(Multi Version Concurrency Control),也叫多版本并发控制,顾名思义,就是通过记录的多个版本来实现数据库的并发控制。
MySQL之所以可以在可重复读隔离阶段就解决幻读问题,主要依靠于MVCC和锁机制,锁机制是一种悲观锁的实现方式,而MVCC是一种乐观锁的实现方式,使数据库具有更好的并发性能。
MVCC主要依赖于三样东西实现,分别是记录的隐藏字段(聚簇索引才有)、undo log、Read View。
展开
评论
点赞
#青训营 x 字节后端训练营#
《MySQL是怎样运行的》第六章 快速查找的秘诀——B+树索引 笔记
1、InnoDB中“索引即数据,数据即索引”,也就是默认就会创建一个聚簇索引来作为以主键为索引列的B+树索引
- 当我们不指定主键字段且不存在不允许为NULL的UNIQUE字段,那么InnoDB就会生成row_id作为隐式主键,并作为聚簇索引的索引列。
2、InnoDB中索引可以分为聚簇索引和二级索引
- 聚簇索引:以主键做为索引列,同时叶子节点中的记录就是每条记录的全部数据信息,也就是“索引即数据,数据即索引”的体现
- 二级索引:以自定义的列作为索引列,一般采用自定义索引列(Key):主键列(Value)的形式作为一条记录存储
- 二级索引的目录页中,自定义索引列需要结合主键列作为Key,数据页的页号作为Value,是因为自定义索引列不一定可以保证Key的唯一性
- 当自定义索引列具有唯一性(UNIQUE)时,则不需要结合主键列来保证二级索引的目录页的Key的唯一性了。
- 同时要注意,所有二级索引都需要根据聚簇索引中的主键值(Value)去聚簇索引中进行回表操作,回表的速度也就是等于重新拿一个主键值去聚簇索引中查找,是非常不理想的,所以我们在写SQL时应该尽量避免回表操作,而选择覆盖索引的方式来避免回表操作。
3、InnoDB中B+树索引(包括聚簇索引和二级索引)的根页面是万年不动的。
- 因为InnoDB会在磁盘中指定的位置记录根节点的页号(等于把索引的入口定死,方便找到),并且会把根节点的数据页缓存到内存中,这样子我们访问B+树索引的层数等于减少了一层(不需要每次都去磁盘中找,直接在内存中固定的位置访问即可),加速了索引的查询速度。
4、为什么二级索引一定要做回表的操作,而不是和聚簇索引一样,保存所有数据呢?
- 因为这样会非常浪费存储空间,每一个B+树就代表一个表的所有数据,同时也会增加修改表数据时的维护成本,降低MySQL的运行速度
5、MyISAM中的索引和InnoDB一样,采用B+树结构的索引,但是要注意的是,MyISAM采用“数据和索引分离”的形式存储。
《MySQL是怎样运行的》第六章 快速查找的秘诀——B+树索引 笔记
1、InnoDB中“索引即数据,数据即索引”,也就是默认就会创建一个聚簇索引来作为以主键为索引列的B+树索引
- 当我们不指定主键字段且不存在不允许为NULL的UNIQUE字段,那么InnoDB就会生成row_id作为隐式主键,并作为聚簇索引的索引列。
2、InnoDB中索引可以分为聚簇索引和二级索引
- 聚簇索引:以主键做为索引列,同时叶子节点中的记录就是每条记录的全部数据信息,也就是“索引即数据,数据即索引”的体现
- 二级索引:以自定义的列作为索引列,一般采用自定义索引列(Key):主键列(Value)的形式作为一条记录存储
- 二级索引的目录页中,自定义索引列需要结合主键列作为Key,数据页的页号作为Value,是因为自定义索引列不一定可以保证Key的唯一性
- 当自定义索引列具有唯一性(UNIQUE)时,则不需要结合主键列来保证二级索引的目录页的Key的唯一性了。
- 同时要注意,所有二级索引都需要根据聚簇索引中的主键值(Value)去聚簇索引中进行回表操作,回表的速度也就是等于重新拿一个主键值去聚簇索引中查找,是非常不理想的,所以我们在写SQL时应该尽量避免回表操作,而选择覆盖索引的方式来避免回表操作。
3、InnoDB中B+树索引(包括聚簇索引和二级索引)的根页面是万年不动的。
- 因为InnoDB会在磁盘中指定的位置记录根节点的页号(等于把索引的入口定死,方便找到),并且会把根节点的数据页缓存到内存中,这样子我们访问B+树索引的层数等于减少了一层(不需要每次都去磁盘中找,直接在内存中固定的位置访问即可),加速了索引的查询速度。
4、为什么二级索引一定要做回表的操作,而不是和聚簇索引一样,保存所有数据呢?
- 因为这样会非常浪费存储空间,每一个B+树就代表一个表的所有数据,同时也会增加修改表数据时的维护成本,降低MySQL的运行速度
5、MyISAM中的索引和InnoDB一样,采用B+树结构的索引,但是要注意的是,MyISAM采用“数据和索引分离”的形式存储。
展开
评论
点赞
#青训营 x 字节后端训练营#
《MySQL是怎样运行的》第五章——InnoDB数据页结构
1、InnoDB中的页有非常多的类型,比如:数据页、溢出页、undo 日志页等,我们只需要了解数据页即可。
2、数据页中的记录按照插入的顺序紧密的连续存放,但是他们之间的顺序和存放的顺序并没有关系,记录之间的顺序是通过记录头中的next_record来关联成单向链表的
3、页目录(Page Directory)通过对页内的记录进行分组,并采用槽(数组形式)的方式来对记录进行管理,从而实现在数据页中查找记录可以使用上二分查找,大大提升查找效率。
- 每个槽所对应的普通分组,记录的条数范围为[4,8];其中Infimum记录(最小记录)自己单独一组;Supremum记录(最大记录)所在的分组,记录的条数范围为[1,8];
- 每个槽记录的是对应的分组内 主键值最大的记录的页内偏移量
- 基于以上条件,我们在数据页中按照索引列查找某条记录时,就可以按照页目录中的槽数组进行二分查找,而非是全表扫描。
- 二分查找每次找到的都是 目标值<槽对应的记录的值(槽对应的分组内的最大记录),然后需要从该槽内的最小记录开始遍历,此时就需要返回去找该槽的上一个槽,根据上一个槽的最大记录的next_reorcd找到该槽的最小记录开始遍历该槽中的记录。
4、Page Header(页面头部)主要记录当前数据页中的状态信息(数据页特有)。
5、File Header(文件头部)是所有页都会存在的页结构,主要用于记录页的各种信息。
6、File Trailer(文件尾部)也是所有页都会存在的页结构,主要用于配合File Header来检测一个页是否完整(内存刷新到磁盘中可能会中断)。
《MySQL是怎样运行的》第五章——InnoDB数据页结构
1、InnoDB中的页有非常多的类型,比如:数据页、溢出页、undo 日志页等,我们只需要了解数据页即可。
2、数据页中的记录按照插入的顺序紧密的连续存放,但是他们之间的顺序和存放的顺序并没有关系,记录之间的顺序是通过记录头中的next_record来关联成单向链表的
3、页目录(Page Directory)通过对页内的记录进行分组,并采用槽(数组形式)的方式来对记录进行管理,从而实现在数据页中查找记录可以使用上二分查找,大大提升查找效率。
- 每个槽所对应的普通分组,记录的条数范围为[4,8];其中Infimum记录(最小记录)自己单独一组;Supremum记录(最大记录)所在的分组,记录的条数范围为[1,8];
- 每个槽记录的是对应的分组内 主键值最大的记录的页内偏移量
- 基于以上条件,我们在数据页中按照索引列查找某条记录时,就可以按照页目录中的槽数组进行二分查找,而非是全表扫描。
- 二分查找每次找到的都是 目标值<槽对应的记录的值(槽对应的分组内的最大记录),然后需要从该槽内的最小记录开始遍历,此时就需要返回去找该槽的上一个槽,根据上一个槽的最大记录的next_reorcd找到该槽的最小记录开始遍历该槽中的记录。
4、Page Header(页面头部)主要记录当前数据页中的状态信息(数据页特有)。
5、File Header(文件头部)是所有页都会存在的页结构,主要用于记录页的各种信息。
6、File Trailer(文件尾部)也是所有页都会存在的页结构,主要用于配合File Header来检测一个页是否完整(内存刷新到磁盘中可能会中断)。
展开
评论
点赞
#青训营 x 字节后端训练营#
《MySQL是怎样运行的》第四章——InnoDB记录存储结构 笔记
1、InnoDB的页大小(innodb_page_size),默认16384字节(16KB),在服务器运行时无法修改!!!
2、COMPACT行格式中,变长字段长度列表不止会记录VARCHAR字段的长度,也会记录采用不定长编码集的CHAR字段长度(因为每个字符长度不确定!!!如:gbk中每个字符需要1-2字节,utf8中每个字符需要1-3字节)
3、CHAR(M)最少存储M字节(不足就用无意义字节填充),VARCHAR(M)没有这个限制,主要是为了让更新时不用每次都创建新的记录(节省空间),这是设计者在节省空间和不想因为更新产生记录碎片之间的权衡。
4、记录中存在三种类型的隐藏列,分别是row_id(隐式主键)、trx_id(事务ID)、roll_pointer(undo log的回滚指针),除了row_id不是必需的,其他两个隐藏列都是必须的。
5、row_id是当表中没有显示指定主键,并且不存在不允许为NULL值的UNIQUE约束字段时,InnoDB替我们生成的隐式主键。这主要和InnoDB中数据在聚簇索引中的存储方式有关。聚簇索引要求页中的记录按照主键的顺序排序,且主键需要是唯一值。
6、聚簇索引为什么这么要求呢?我认为是为了配合二级索引的回表操作。聚簇索引中的记录采用唯一且有序的方式排序,可以使二级索引快速回表查询(二级索引是根据记录的主键来进行回表),否则就需要二级索引的回表操作扫描全表了。
《MySQL是怎样运行的》第四章——InnoDB记录存储结构 笔记
1、InnoDB的页大小(innodb_page_size),默认16384字节(16KB),在服务器运行时无法修改!!!
2、COMPACT行格式中,变长字段长度列表不止会记录VARCHAR字段的长度,也会记录采用不定长编码集的CHAR字段长度(因为每个字符长度不确定!!!如:gbk中每个字符需要1-2字节,utf8中每个字符需要1-3字节)
3、CHAR(M)最少存储M字节(不足就用无意义字节填充),VARCHAR(M)没有这个限制,主要是为了让更新时不用每次都创建新的记录(节省空间),这是设计者在节省空间和不想因为更新产生记录碎片之间的权衡。
4、记录中存在三种类型的隐藏列,分别是row_id(隐式主键)、trx_id(事务ID)、roll_pointer(undo log的回滚指针),除了row_id不是必需的,其他两个隐藏列都是必须的。
5、row_id是当表中没有显示指定主键,并且不存在不允许为NULL值的UNIQUE约束字段时,InnoDB替我们生成的隐式主键。这主要和InnoDB中数据在聚簇索引中的存储方式有关。聚簇索引要求页中的记录按照主键的顺序排序,且主键需要是唯一值。
6、聚簇索引为什么这么要求呢?我认为是为了配合二级索引的回表操作。聚簇索引中的记录采用唯一且有序的方式排序,可以使二级索引快速回表查询(二级索引是根据记录的主键来进行回表),否则就需要二级索引的回表操作扫描全表了。
展开
评论
点赞
#青训营 x 字节后端训练营#
继昨天写了一个简易的IOC容器后,很快不少问题接踵而来。
其中就包括“循环依赖”问题,我很早之前就听说过“循环依赖”问题,但是一直没有去研究Spring是如何解决“循环依赖”问题。正好借这个契机,学习一下Spring是如何解决这个问题的。
循环依赖是什么我就不过多展开了,不了解的看文章即可。Spring通过二级缓存解决了循环依赖问题,所以我也在自己的代码中添加了一个二级缓存,让完成实例化,但还没有完成依赖注入的bean提早暴露出来,从而解决了bean之间的循环依赖问题。
PS:图片和链接是只能二选一么?我好像没有办法两者都添加
文章链接:
juejin.cn
继昨天写了一个简易的IOC容器后,很快不少问题接踵而来。
其中就包括“循环依赖”问题,我很早之前就听说过“循环依赖”问题,但是一直没有去研究Spring是如何解决“循环依赖”问题。正好借这个契机,学习一下Spring是如何解决这个问题的。
循环依赖是什么我就不过多展开了,不了解的看文章即可。Spring通过二级缓存解决了循环依赖问题,所以我也在自己的代码中添加了一个二级缓存,让完成实例化,但还没有完成依赖注入的bean提早暴露出来,从而解决了bean之间的循环依赖问题。
PS:图片和链接是只能二选一么?我好像没有办法两者都添加
文章链接:
展开
评论
点赞
#青训营 x 字节后端训练营#
前天读了敖丙的Spring浅析文章后茅塞顿开,开始了理解了Spring IOC的原理。
但是纸上得来终觉浅,决定按照文章的思路进行模仿,搞一个IOC的小Demo。
最终自定义了自己的@MyCommpontScan、@MyComponent、@MyAutowired注解,
通过反射实现了一个简易的IOC容器,非常开心哈哈哈。
以后一定要深入学习Spring,真正的模仿Spring的IOC和AOP。
hxd们,有推荐的Spring资料么
前天读了敖丙的Spring浅析文章后茅塞顿开,开始了理解了Spring IOC的原理。
但是纸上得来终觉浅,决定按照文章的思路进行模仿,搞一个IOC的小Demo。
最终自定义了自己的@MyCommpontScan、@MyComponent、@MyAutowired注解,
通过反射实现了一个简易的IOC容器,非常开心哈哈哈。
以后一定要深入学习Spring,真正的模仿Spring的IOC和AOP。
hxd们,有推荐的Spring资料么
展开
评论
点赞