自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(176)
  • 收藏
  • 关注

原创 第八篇:MySQL之锁详解

1、加锁的原因1、事务并发造成的数据不一致,举例如下:事务A:update test set k = k + 1 where id = 1;事务B:update test set k = k + 1 where id = 1;按照正常执行的话,提交完事务A和B后,k会变成k+2;如果不对对应记录加锁的话,事务B和事务A同时更新的话,会导致k变成k+1,导致数据丢失。2、导致幻读我们都知道MySQL中的读分为两种:1、快照读:读取的不一定是最新的数据,读取的是MVCC为事务提供的快照。

2021-07-31 17:48:41 774 1

原创 第七篇:MySQL之索引

索引的基本思想我们都知道算法设计里面有一个非常经典的思想:用空间复杂度来换取时间复杂度的下降!索引就是用额外的空间来增加数据库的查询效率。

2021-07-26 22:54:59 520 1

原创 第六篇:MySQL之事务

事务的概念事务是数据库的最小的操作单元,要么全部执行,要么都不执行。事务是MySQL中存储引擎方面支持的功能。MySQL支持多引擎,但是不是所有的引擎都支持事务,MyISAM不支持事务,InnoDB支持事务。事务的特征1、原子性事务中的操作要么完全执行,要么都不执行2、持久性事务提交后的数据要能够持久保存,即使系统故障数据也不会丢失。3、隔离性并发事务之间需要有一定的隔离性,防止数据的不一致。4、一致性事务执行前后,数据前后要保持一致。原子性事务的原子性,InnoDB是通过undol

2021-07-24 18:46:00 304 1

原创 第四篇:MySQL之binlog和redolog

引言这篇文章说下MySQl中的恢复日志中的binlog和redolog。binlogbinlog称为二进制日志或者归档日志,主要记录除查询以外的操作(delete、update、insert、DML等),主要用于主从复制和数据恢复。binlog的数据格式有如下三种格式做法优点缺点STATEMENT直接记录相关的SQL语句,在恢复的时候直接执行SQL语句数据量小,节省磁盘IO由于某些函数UUID()、NOW()等函数,并且需要上下文关联,容易造成主从复制不一致RO

2021-07-22 15:43:12 1704 1

原创 第三篇:MySQL中InnoDB的undo日志的物理结构、事务回滚、MVCC

本篇介绍知识InnoDB中的undolog的物理组织结构、以及事务回滚和MVCC的原理。只是说清楚大致原理,不会深入细节。都是个人观点和理解,如存在错误,请批评指正!知识来源阿里数据库内核月报阿里数据库内核月报之undologundo的物理结构undo的组织结构从上到下为回滚表空间、回滚段 (undo log segment)、undo log slot(后文简称slot)、page。page仍然是基本单位,回滚段为逻辑上的结构,slot是一个特殊的page页,分为两部分1、因为一个事务的

2020-11-25 17:56:09 1206 1

原创 第二篇:MySQL之InnoDB物理存储结构

MySQL中InnoDB引擎的物理存储结构1. 个人理解看了很多MySQL的书籍和博客,感觉都是互相抄来抄去,把知识点的罗列,讲不清楚前因后果,让人看起来莫名其妙的。所以,我决定从MySQL的底层物理存储结构了解,掌握了InnoDB的物理存储结构,再理解索引,锁,事务,日志之类的上层优化就很容易了。2. 知识来源本文主要观点来自于阿里数据库内核月报http://mysql.taobao.org/monthly/2016/02/01/和一篇CSDN博客https://blog.csdn.net/

2020-11-19 17:19:57 2223 3

原创 Java中抽象类

抽象类可以代码复用,将一些需要差异化的逻辑抽出一个抽象方法,其他子类可以继承该抽象类,实现对应的逻辑,这样就可以复用其他不需要差异化表达的代码逻辑。

2023-08-29 14:44:15 155

原创 Linux系统初始化

学习Linux内核的原因我个人是软件工程专业的学生,但是对计算机是怎么运行的一直都有疑惑。 为什么一通电计算机就能运行了,处理各种任务。 如果对计算机底层知识的不熟悉和不理解的话,这就造成了在了解各种中间件或者软件的底层原理的时候,会比较吃力,对于程序运行的具体情况也不太清楚。 我个人目前认为只有对程序在计算机中的具体执行过程有着深入的了解,才能写出性能更好、更健壮性的代码,所以开始学习Linux内核。Linux内核学习方法资料《趣谈Linux内核 》 刘超 极客时间专栏Linux源码路线

2022-04-10 21:05:44 4046

原创 面向对象分析过程

1、将需求拆分成若干个功能点2、将职责相近的功能点合并到一个类中3、根据功能点设计类的属性和方法4、根据组合、继承、实现等关系来组织类之间的关系

2022-03-02 21:18:34 845

原创 组合和继承

继承有很多好处:1、多态2、代码复用继承的坏处1、如果继承的层数过多,会造成代码可读性降低,不好调试,不好维护2、如果一个类中的子类具有不同的行为,比如同属于鸟类,鸵鸟不会飞,而燕子会飞,这样的话,就无法在基类中定义fly()方法了。也就无法多态和代码复用了。对于第2个坏处,我们可以利用组合+接口的方式来达到多态和代码复用的效果。interface flyable{ void fly();}class TuoNiao implements flyable{ void fly(){

2022-03-02 18:55:51 329

原创 面向接口编程

接口是一种抽象的能力,可以用来解耦。当对应的代码不稳定也就是经常变动的时候,最好使用接口编程。在接口中声明对应的函数,然后对应的实现类来重写端口。这样的话,当代码需要变动的时候,我们可以直接新增一个实现类来重写接口,这样的话就避免了对之前实现类的修改。相较于直接修改原来的代码,接口编程有以下好处:原来的代码有可能还会使用,这个时候需要新建一个类来完成新的需求。在调用方我们需要修改的代码就多了。如果接口编程的话,我们利用多态的话,只需要修改对应的实现类就可以了要求:1、接口函数的名字一定要抽象,屏

2022-03-02 18:26:20 344

原创 分布式事务

XA两阶段提交TC:协调者,用来协调全局事务,RM:资源,也就是数据库,用来处理本地子事务TM:事务管理者,也就是发起分布式事务的调用方1、TM发起发起全局事务,向TC注册全局事务,分配对应的全局事务ID2、RM先执行对应的子事务,但是不提交,向TC注册子事务,并且报告对应的状态3、如果所有RM的子事务的状态都正确,进入全局事务提交阶段。TC会向RM发送提交信息。RM收到信息后,提交本地事务4、如果有任何一个向TC发送了错误信息,TC会向所有的RM发送回滚命令缺点:在全局事务提交之前,R

2022-02-19 22:34:21 524 1

原创 数据分片策略

为什么要数据分片?所有的应用都可以归结为两种操作的集合:读 和 写 。随着数据量的增加,单台机器的能力是有限的。一方面,机器的容量会无法容纳数据,另一方面数据的读取速度会变慢。所以我们可以将数据分片,分到多台机器上,这样的话存储压力和读取速度就变快了。上述是数据分片的好处,但也带来的挑战:分布式事务数据被分到不同的数据库,无法保证事务数据查询难度变高没分片之前,只需要在一台机器上就可以查出全部的数据,分片之后,需要从所有机器上查出所有的数据,然后进行整合。并且还需要维护数据和机器之间

2022-02-19 21:52:59 1590

原创 线程切换详解

线程切换的流程:1、保存CPU上下文,也就是各类寄存器的信息2、触发软中断,从用户态转化到内核态,恢复内核栈的寄存器信息,内核栈会执行对应的线程切换函数,从就绪线程中选出一个线程来执行,并恢复线程对应的CPU上下文。这里面存在了2次的CPU上下文切换3、对应的线程开始执行这里面有两个比较耗时间的点:CPU的上下文切换、 进程的调度选择!...

2021-12-21 22:43:53 4980 1

原创 为什么进程切换比线程切换耗费资源?

每个进程都有对应的页表,进程切换的时候需要切换页表,为了加快虚拟地址的地址转换效率,所以引入了TLB来缓存对应的虚拟地址和物理地址的映射。切换页表这个操作本身是不太耗费时间的,切换之后,TLB就失效了,所以在进行地址转化的时候需要重新去查找页表,这就造成了程序运行的效率低下。同一个进程的线程之间是共用一个页表的,所以线程之间的切换是不需要切换页表的。...

2021-12-21 18:48:36 2189

原创 线程到底共享了进程的什么资源了?

本文观点来自于知乎一篇文章添加链接描述线程的原理就是一个函数栈的压入和弹出,用来不断的调用函数。独占资源1、函数栈每个线程都有对应的函数栈,栈帧里面包含了有局部变量、参数、返回的参数、返回的地址、寄存器信息等2、调度信息线程需要被操作系统调度3、程序计数器和寄存器的状态用来标志着当前执行代码的位置4、栈的指针用来表示当前的栈帧5、线程的运行状态共享资源1、代码段一个进程有着对应的代码段,线程之间的是共享的。2、数据区线程之间共享着函数之外的全局变量,这些变量存放在数据区3

2021-12-21 17:59:57 1465

原创 Git详解

Git简介Git是Linus大神写的一款分布式版本控制系统,用于同步多人的项目开发。Git可以维护一个目录下所有文件的修改、新增、删除等操作,达到版本控制的目的。如果要对某个目录进行版本控制,需要在下面执行git init 命令。Git Configgit config --system user.name zmh //全局的变量 git config --global user.name zmh //用户的变量git config user.name zmh//项目的变量在Win

2021-11-24 14:14:02 201

原创 Netty详解

Netty简介Netty是一个基于Java的高性能的网络框架,基于TCP和UDP,是对Java中NIO的一个封装。我们可以根据自己的需求快速的开发一款自己需要的应用层协议。Netty核心组件EventLoopGroupEventLoop的一个数组,默认为CPU个数*2,也可以自定义EventLoop一个单线程的Executor,用来绑定一个selecter,可以同时读取多个Channel的事件,主要有两种任务:1、查询selector中监视的channel的事件2、执行事件对应的chann

2021-11-22 23:05:07 1439

原创 Reactor设计模式

Reactor模式简介Reactor模式是一个基于事件分发的模式。主要用于IO多路复用。当一个事件到来的时候,Reactor根据事件的不同类型,通知对应的handler处理。Reactor详解本文拿 网络IO多路复用来举例,我们都知道IO多路复用可以提高服务器的并发处理能力!IO多路复用就是一个线程可以监控多个socket,减少线程的创建。当服务器连接数过多的时候,IO多路复用能够减少线程数,也可以减少线程上线切换导致的资源浪费。但是socket分为两种情况:1、负责新建连接的socket2

2021-11-21 16:46:09 994

原创 职责链模式

职责链设计模式简介当一个对象需要经过一系列的操作或者检验的时候,这个时候职责链设计模式就很奏效了。比如对一个请求进行一系列的处理的时候,职责链就很好用职责链设计模式详解package chain;public class Chain { private Handler head = null; private Handler tail = null; public void addHandler(Handler handler){ if (head =

2021-11-17 20:17:55 204

原创 策略设计模式

策略设计模式简介策略模式用来解决代码中大量的if-else的情况。对这类情况定义一个接口来规定对应的基本策略,然后对每一种实际情况都实现一种特定的类来具体实现对应的逻辑。策略模式通过查表+接口多态的方式来代替对应的if-else。策略模式详解public interface OrderService{ void call(Order o);}public class OrderServiceImpl1 implements OrderService{ @Override public v

2021-11-17 19:08:26 104

原创 观察者模式

观察者模式简介观察者模式是一种 多个观察者 观察 一个被观察者的 模式。当被观察者的状态改变的时候,会依次通知对应的观察者。观察者模式详解public interface Subject{ void register(Observer observer); void unregister(Observer observer); void notifyObservers(Message message);}public interface Observer{ void update(

2021-11-17 16:09:04 103

原创 原型设计模式

原型模式简介原型模式也是创建对象的一种方式。如果需要创建的对象的初始化比较耗时,并且对应的属性取值都差不多的时候,可以考虑通过原型模式来创建。原型模式是通过直接拷贝其他对象来创建对象,然后更改对应的属性来得到新的对象深拷贝和浅拷贝原型模式涉及到了对象的拷贝,对象的拷贝分为浅拷贝和深拷贝。浅拷贝浅拷贝的时候,对于引用类型的属性,拷贝的时候不会新生成对象,而是拷贝对象的地址。两个对象中的属性的引用是共用一个对象的。深拷贝深拷贝的时候,对于引用类型的属性,会为其创建新的对象。两个对象中的属性

2021-11-16 19:13:18 226

原创 建造者设计模式

建造者模式简介建造者模式也是用来创建对象的,有以下使用场景:1、创建的对象的参数较多,并且允许不同的排列组合当参数过多,并且允许排列组合的话,我们需要写大量的很长的参数列表的构造函数,看起来比较混乱。当然这种情况,可以用set()方法来解决。但是set()无法解决第二个问题2、参数之间有约束关系,比如某个参数的值要大于另一个参数的值当参数之间存在约束关系的时候,set()是无法保证参数之间的约束的,除非要求用户按照一定的次序来使用set()建造者模式详解假设我们现在需要创建一个商品类对象pu

2021-11-15 22:36:19 397 1

原创 工厂设计模式

工厂设计模式简介我们都知道现实世界中,工厂的作用就是批量制造东西的。在设计模式中,工厂设计模式也是用来批量制造物体的,这个物体就是对象。工厂设计模式的身影常常在框架中使用,比如著名的spring,就是使用的工厂模式来生成和管理对象的。常用的工厂模式有两种:简单工厂和工厂方法。简单工厂public class FoodFactory{ public static Food createFood(String className){ if(className.equals("fruit")){

2021-11-15 21:54:32 225

原创 单例设计模式

使用场景单例模式的作用是 保证一个类在JVM中只能存在一个对象,防止多余的对象浪费JVM的内存创建方式1、饿汉式public class Singleton{ private static Singleton singleton = new Singleton(); //必须设置为private,防止通过构造函数来创建对象 private Singleton(){ } public static Singleton getInstance(){ return singleton;

2021-11-14 21:17:34 405

原创 加锁CAS的底层原理

加锁的底层利用的是CPU的一个原子指令,CompareAndSwap,也就是我们说的CAS。如何加锁呢?拿互斥锁为例,在一块内存中维护一个变量和线程信息,当变量为0的时候,代表当前无锁,当变量为1的时候,代表有锁,并将自己的线程信息写入,代表当前线程占用锁了。每个想要拿到锁的线程都通过CPU的CompareAndSwap指令来获取锁,对应的指令为cas(addr,0,1),这条指令的意思是地址为adder的内存中存储的变量取值为0的时候,才将变量改为1,表示加锁成功。1、首先来说,CPU的架构决定了

2021-11-02 14:35:03 1118

原创 CPU和内存的架构 UMA和NUMA

CPU和内存之间的架构分为两种:1、UMAUMA全称为 Uniform Memory Access,叫做一致性内存访问多个CPU通过同一根总线来访问内存。无论多个CPU是访问内存的不同内存单元还是相同的内存单元,同一时刻,只有一个CPU能够访问内存。CPU之间通过总线串行的访问内存,所以会出现访问瓶颈!2、NUMANon-Uniform Memory Access ,非一致性内存访问。每个CPU都分配了一块内存,这样的话,多个CPU可以同时并行访问各自的内存,这样的话,读写内存的效率就上来了。

2021-11-02 12:57:17 7608

原创 vmware虚拟机网络通信

1、桥接模式vmware 会在每个虚拟机生成一个虚拟网卡,这个虚拟网卡和真实的物理网卡处在同一网段,虚拟网卡也通过物理网卡来传输数据2、nat模式vmware会在 主机上生成一个 vmnet8的虚拟网卡,相当于主机有了两个网卡,一个虚拟网卡,一个真实网卡。vmware会在主机内部生成一个 虚拟DHCP服务器、一个虚拟网关,网关支持nat转换。每个虚拟机上也会生成一个虚拟网卡。所有虚拟机的网卡ip地址 和 主机的vmnet8的这个虚拟网卡的ip地址处在同一个网段, vmnet8 和 真实网卡的 I

2021-10-30 21:49:47 1113

原创 主机与IP地址的关系

一个主机可以同时有多个IP地址,一个网卡对应着一个IP地址。当然这里的网卡包括虚拟网卡,虚拟网卡也可以绑定一个IP地址,然后通过物理网卡来发送和接受数据,但是需要和物理网卡的IP地址在同一个网段,这就是桥接模式。...

2021-10-30 18:58:15 2311

原创 Java中HeapByteBuffer和DirectByteBuffer的区别

HeapByteBuffer 和 DirectByteBuffer 都是申请一块内存,只不过HeapByteBuffer是在Java的堆内存中申请,而DirectByteBuffer是在JVM外部申请。有什么区别呢?我们都知道JVM会对 堆区 进行GC,会移动存活对象在内存中的位置,HeapByteBuffer也不例外,也会被移动位置。而DirectByteBuffer由于是在JVM外部,所以不会收到JVM的GC影响。这个差别就体现在了IO上边。如果将HeapByteBuffer中的数据写入的时候

2021-10-28 16:31:53 447

原创 自旋还是挂起?

自旋会一直CAS来获取锁,不会释放CPU,而线程挂起会释放对应的CPU资源。1、如果是多核处理器,如果预计线程等待锁的时间很短,短到比线程两次上下文切换时间要少的情况下,使用自旋锁是划算的。2、如果是多核处理器,如果预计线程等待锁的时间较长,至少比两次线程上下文切换的时间要长,就讲线程挂起,到锁释放的时候再将线程唤醒。3、如果是单核处理器,一般建议不要使用自旋锁。因为,在同一时间只有一个线程是处在运行状态,那如果运行线程发现无法获取锁,只能等待解锁,但因为自身不挂起,所以那个获取到锁的线程没有办法进入

2021-10-24 21:34:13 254 1

原创 线段树模板

线段树是一个区间二叉树,用来处理区间和、区间最大值、区间最小值等区间问题。线段树的节点存储着对应的区间信息、以及维护的最大值或者是最小值信息。线段树是一个完全二叉树,用一个数组来存储,根节点的下标为1,左子节点为2* i,右子节点为2*i+1。对应的区间信息其实不用存储,都是在代码中维护的,因为每次都是将一个区间按照mid来分为[l,mid]和[mid+1,r]两个左右子区间。线段树针对的是区间的动态更新和查找,修改和查找的时间复杂度都是log(n)。因为普通的前缀和的查找时间虽然是O(1),但

2021-10-18 21:29:18 103 1

原创 MySQL之慢查询日志

MySQL中慢查询日志用来记录MySQL中

2021-10-17 16:22:08 497 2

原创 MySQL之乐观锁和悲观锁详解

相信所有后端选手每个人都听说过乐观锁和悲观锁吧,本文就详细说下乐观锁和悲观锁的区别。场景乐观锁和悲观锁主要针对于先读后写的场景。如果是全读的话,没必要加锁。如果是全写的话,没必要用悲观锁。我们拿账户扣钱的例子来说明一下://查询余额select balance from deposit where id = xx;//扣除余额update deposit set balance -= 100 where id = xx;系统首先查询出账户的余额,然后将余额减去100。为什么要提前查一

2021-10-16 09:59:57 510 1

原创 MySQL之子查询

MySQL可以执行子查询,也就是在查询中嵌套查询子查询分为两类:关联子查询和非关联子查询假设系统现在有两个表,分别为 user 和 order。user 为用户表,有id,name两个字段order为订单表,有oid,userid两个字段。我们现在需要求出所有买过东西的用户的name。非关联子查询非关联子查询 指的是 子查询 的查询条件 不依赖于 外部查询的数据select name from user where user.id in (select userid from order);

2021-10-15 22:50:05 288 1

原创 MySQL之groupby详解

MySQL中提供了groupby关键字,用来对数据进行分组,用来统计分组的信息。groupby的原理select id%10 as m, count(*) as c from t group by m;上述的sql是对id进行分组,对10取模相同的id分到一组,然后获取组内的数量。groupby的流程如下:1、创建一个内存临时表temp,表里有两个字段 m 和 c,m为主键2、从表 t 中选取一个最合适的索引,依次的读取出对应的id值,然后将id%10 = mm,对于结果有两种处理方式:a

2021-10-15 16:00:55 10716 1

原创 MySQL中join详解

大家对join应该都不会陌生,join可以将两个表连接起来。join流程详解join 是指 将两个表连接起来,两个表分别为 驱动表 和 被驱动表。我们拿下面的这个sql举例,select t1.id,t2.id from t1 inner join t2 on t1.id = t2.id where t1.id > 10;t1和t2 都对 id 建立了索引,我们假设 t1 是驱动表,t2是被驱动表。join流程如下:1、MySQL每次从t1中读取一行满足过滤条件t1.id>

2021-10-14 23:02:40 1984 1

原创 MySQL之数据发送流程

数据发送流程MySQL是CS架构的,也就是基于客户端-服务器模式,读取数据流程如下:1、客户端通过TCP与服务器建立连接2、客户端通过网络发送一个查询数据包,里面包含了对应的sql语句3、服务器收到查询数据包后,取出并执行里面的sql语句,将结果通过网络返回给客户端。这里面有个问题,如果查询一个大规模数据的话,服务器会将所有的数据都读取到内存中吗?会不会把内存都打爆?其实不是的,MySQL是边读取边发送的。MySQL没必要把所有数据都读取到内存中,因为数据最终要通过网卡发送出去,网卡不可能一下

2021-10-14 18:58:37 1448 1

原创 MySQL中随机选取元素

有点时候,我们会需要随机选取表中的一个记录,以下有几种方法可以随机选择1、select * from t where id >= rand limit 1rand是一个随机值,我们可以首先获取n = min(id)和m = max(id)rand = n + rand()*(m-n);rand是介于 最大 id 和最小id之间的一个id。优点:快速方便,只需要扫描三行记录就可以获取到缺点:如果id分布不均匀的话,会出现伪随机,也就是每个id被选取的概率不相等。比如1,2,4,5。4被

2021-10-13 21:06:41 1228 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除