- 博客(609)
- 收藏
- 关注
原创 消息队列中的topic,partition,offset,broker,消费者组
1个topic的消息会分布到多个partition分区中,每个partition中的每条消息都有一个唯一编号 offset(消费者可以通过记录这个offset来知道自己读到了哪个位置,下次接着从这往下读)一个broker中存着来自不同topic的partition,比如topicA的partition1,topicB的partition2,topicC的partition3......,所以。一个消息只会被组内的一个“同事”处理。的完整数据,互不干扰。一个消息会被每一个“订阅者”(消费组)都处理一次。
2025-11-30 23:55:24
200
原创 Binlog
因为这种格式最节省磁盘空间 遇到“不安全”操作时,自动切换到 ROW 格式:当MySQL判断一条SQL语句如果用 STATEMENT 格式记录,在从库上执行可能会产生与主库不同的结果时(即“不确定性”操作),它就会自动将这一条SQL语句的日志格式切换为 ROW 格式。Go程序会连接到MySQL服务器,告诉它:“你好,我是一个从库,请从某个位置开始把你的Binlog事件发给我”,然后您的程序就可以处理源源不断发来的事件流了。缺点: 如果一个查询更新了大量的数据行,可能会非常冗长,占用更多的磁盘空间。
2025-10-26 22:24:33
841
原创 GMP,不就是工人、流水线和任务吗?
如果一个调度器P的goroutine队列空了,首先它会查看全局goroutine队列)是否有待执行的goroutine,有的话从全局goroutine队列中取,否则查看其他调度器的goroutine队列是否还有等待执行的goroutine,有的话,那么这个调度器P会偷”走其他 P (随机选择)队列中的一半待执行的 G 放到自己的goroutine队列中。3.hand off,M和P解绑:不能因为一个 G 的等待,而让一个 P(代表的 CPU 计算资源)和一整个队列的 G 都跟着等待。
2025-10-12 20:26:40
279
原创 MVCC 多版本并发控制
解决时的冲突问题,主要用于实现事务的两个隔离级别:读已提交 (Read Committed)可重复读 (Repeatable Read) (这是 MySQL InnoDB 默认的隔离级别)【可以理解为,只能读已经被事务提交后产生的版本,在实现读已提交的基础上,将read view生成时机从每一次select之后改成只是第一次select的时候生成read view,后面的select不再生成新的read view,就可以实现可重复读了】实现原理:版本链(每一行数据有一个版本链,)+readview。
2025-10-07 17:14:28
360
原创 go build命令
2.链接(link) 编译得到的二进制机器码还不完整(比如在main.go对应的二进制码中,调用别的函数的地方留下一个占位符,这个占位符的大致意思是说,嘿,链接器,请在这里填上被调用的xxx函数的真正地址),如果直接运行这个编译后的二进制机器码,程序执行到这个调用时,它会发现一个无法跳转的空白地址,然后崩溃。main 包是程序的入口,它应该是“第一章”,但此时它和其他章节是平等的,没有谁先谁后。go run 会 编译并立即运行 你的程序,但它 不会在你的项目目录里留下可执行文件。
2025-10-06 09:29:10
338
原创 服务优雅停止和服务优雅启动
【1】对于正在处理请求的连接 (Active Connections),它会耐心地等待它们完成当前的请求-响应周期,注意此时会进行超时强行关停连接,即请求执行时间太长就会强行关闭连接,比如设置10s后就要强行终止连接了。像突然停电,硬件物理损坏,进程收到sigkill信号(执行kill -9 <PID>)时,服务会被立即终止,不会触发优雅停止。Shutdown() 方法原理就是: 1.关闭http服务器的监听端口(任何新的客户端请求都无法建立连接,它们会立刻被拒绝)2.如果不进行优雅停止,会发生什么?
2025-10-04 09:25:22
355
原创 记录锁,间隙锁,临键锁还在傻傻分不清楚?一招教你直达行级锁本质
是为了解决幻读问题,也就是防止一个事务A在查询的时候,另一个事务B在它查询的区间内插入,删除,修改数据,导致事务A前后查询到的行数不一致(比如之前查到的是5行,现在查到了7行数据)。你要防止24这条记录以前的记录被修改成24,也要防止32这条记录被修改成24,也要其他事务先在(24,32)区间内插入一条数据,再将这条数据的age改成24,由于age是非唯一索引,所以可以出现多行的age都是24,显然你只需要锁住id=1这一行记录即可,因为id这一列是主键索引,这样其它行的id是无法修改成id=1的,
2023-10-27 17:34:50
533
原创 mysql索引覆盖
如果已经在二级索引B+树上查到了我们想要的数据(比如你想要获取的就是这个主键id,或者联合索引index(a,b,c),你查询select b from table where a=1,也是不用回表的,二级索引b+树的索引字段直接就可以返回b的值),不用回表,这就是索引覆盖,二级索引B+树就可以覆盖到我们所需要的值了。正常查找流程是,我们先在二级索引B+树上查找,然后找到数据所在行的主键id,根据这个主键id去主键索引B+树上查找,获得完整数据(去主键索引B+树中查找数据就是回表)
2023-09-04 14:10:13
502
原创 mysql三大日志 undolog,redolog,undolog
②undo log是逻辑日志(针对的是每一行的记录),存储的是数据修改的逆操作(如果执行了一条 UPDATE 语句将某个字段的值从 10 修改为 15,那么 Undo Log 中就会记录一个相应的逆操作,将这个字段的值从 15 修改回 10。(2)bin log是逻辑日志,redo log是物理日志,记录的是哪个数据页的哪个数据被改成什么了,在不同的机器上数据的位置是不一样的,可能在这个机器上是在这个数据页上,在另一台机器,就是在另一个数据页上。(2)undo log和redo log。
2023-09-04 14:09:30
651
原创 Mysql底层数据结构为什么选择B+树
(2)如果采用红黑树,虽然插入新元素的过程中会自我平衡,调整位置,但是红叉树终究还是二叉树,树的高度还是太高了,I/O操作太多,多路树B树和B+树具有更低的层高。2.B树的非叶子节点和叶子节点都既存储索引key,又存储数据data,B+树的非叶子节点只存储索引,不存储数据,叶子节点才是既存储索引,又存储数据。3.B树的叶子节点不会存储相邻节点在磁盘中的位置,B+树的叶子节点会存储相邻节点在磁盘中的位置,所以B+树支持范围查询。4.B树不用查到叶子节点就可能查到数据,B+树必须一路查到叶子节点才能查到数据。
2023-09-04 14:08:45
1390
原创 leetcode12 整数转罗马数字
再和1000比,比1000小,于是去和900比,比900大,于是添加CM,994变成94......1994 先是和1000比,比1000大,于是添加一个M,然后1994变成994。tags:字符串 模拟题。
2023-07-21 15:43:09
181
原创 leetcode13 罗马数字转整数
对于每个字符,都要去查找它右方的字符,如果右方字符比当前字符大,那就要变成负数了(比如100变成-100)一般来说,都是数字大的放左边,数字小的放右边,比如 XXVII 27 依次是10 10 5 1 1。但也有一些特例:: 4的话,不是||||,而是IV。tags:HashMap 字符串。9的话,不是V||||,而是|V。
2023-07-21 12:11:23
282
原创 leetcode 6 N字形变换
先new一个List出来,List中有nums个StringBuilder,然后对于字符串s中的每一个字符判断一下这个字符应该放到哪个StringBuilder里去。tags:字符串 模拟题。
2023-07-21 10:53:52
218
原创 @Async注解
方法在一个单独的线程中异步执行,调用异步方法后,开启单独线程执行这个异步方法里的内容。在主应用程序类上添加@EnableAsync注解,开启异步支持。
2023-06-16 22:19:43
149
原创 头文件header file和源文件 source file
最主要的作用就是将函数的声明和实现分开,如果想将类和函数交给别人使用,但是又不想让别人知道类和函数的源代码,直接将这个类或者函数的头文件给对方。在这个文件中声明了这个类的构造函数,析构函数,以及一个叫做MyMethod的普通函数。头文件 header file,后缀是.h,头文件负责类的定义,函数声明,常量的定义。一般一个类配一个头文件.h进行声明,一个.cpp源文件进行实现。源文件source file,后缀是.cpp, 函数的实现。下图中就有两个类,每个类一个头文件声明,一个源文件实现。
2023-06-12 14:12:03
2927
原创 QT中信号和槽的概念
第二个参数是发送的信号,信号的种类有:(1)clicked点击,按下然后再松开 (2)pressed 摁下 (3)released 释放 (4)toggled 切换(按一下切换一个状态)connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理)老师对象调用hungry方法,学生对象就会调用treat方法请老师吃饭。第四个是处理的槽函数(1)close() 关闭窗口 (2)现在你点击这个按钮就会关闭窗口了。第三个参数是信号的接受者。第一个参数就是按钮指针。
2023-06-12 10:43:27
453
原创 C++函数模板
/也可以swap(a,b);template//声明一个模板。两个函数除了传入参数的类型不一样,其他代码一模一样。swap(a,b);
2023-06-05 17:16:33
107
原创 结构体变量作为函数参数
void function2(struct student *s) //地址传递。void function1(struct student s) //值传递。struct student s={"张三",18,89};s->name="李四";
2023-06-05 00:20:24
548
原创 Const修饰指针
以后*p一定等于=10,不能改变,但是p可以指向a,也可以指向b,也可以指向c,但是这些变量的值都必须是10,如果不是10,不能指向这些变量。这个指针就只能指向变量a了,变量a的值可以改成任何值。指针的指向和指针指向的值都不可以修改。
2023-06-04 21:14:28
121
原创 设计模式之工厂模式
Computer computer=shopAssistant.suggest("打游戏");//new 一个外星人电脑的实例。工厂模式就是简单工厂模式,引入工厂类,客户端只需要new 一个工厂对象即可。
2023-05-31 17:24:51
102
原创 前后端分离
后端程序从数据库中获取到数据后,将数据填入到模板文件里面(jsp文件或者freemarker文件,里面有一些数据占位符,把数据替换掉这些数据占位符即可)这就是渲染,得到html页面返回给前端。RestController返回的是一个json格式的数据(返回的是json数据而不是html页面)后端只返回数据,渲染成html页面交给前端做。1.纯后端渲染页面架构。
2023-05-30 10:52:02
203
原创 CAP原则
AP:保证可用性和分区容错性,创建订单后,不等待库存减少(异步去减库存)就返回处理结果了,保证了用户的可用性,牺牲了数据的一致性(但是会通过其他方法比如人工进行补录,校验程序等保证最终一致性)CP:保证一致性和分区容错性,创建订单后,等到库存减少之后才返回创建订单成功的消息,保证强一致性,但是用户体验很差,需要等待较长时间。有两个系统,订单系统和库存系统,订单系统负责创建订单,库存系统负责去减少库存,两个系统都有自己各自的数据库。三者不可能同时满足,只能CA或者CP,或者AP,不可能CAP。
2023-05-30 10:12:51
186
原创 如何跑通一个java项目
要想看懂代码:主要是看Controller,Service,Repository(或者叫Dao),Model(这里存储的是对象)先读Readme(这里会介绍项目结构和技术选型),这里还会告诉你们怎么跑起来这个项目,比如让你先安装数据库,然后.....注意:从 GitHub 上下载项目时,默认情况下会将项目下载到当前工作目录中,你也可以指定先下载路径。Halo项目:最好的博客项目(基于gradle而不是基于maven进行管理的)查找项目代码的途径:github,码云,掘金网。
2023-05-29 17:19:07
1753
1
原创 一致性哈希算法
假设现在要缓存a.jpg这张图片,hash(a.jpg)%2的32次方,也就是说现在图片和服务器都被映射到了哈希环上了,沿着图片开始,顺时针查找,第一个服务器结点就是这张图片要被缓存的服务器。但是这种算法有个缺点:当服务器数量增加的时候,比如3台服务器变成4台,这个时候可能就不能正常读取到图片了,于是造成缓存失效,大量缓存数据都失效的话,会造成缓存雪崩、有三台服务器:服务器编号分别是S0,S1,S2,现在有3万张图片需要缓存,这些图片最好能够均匀的缓存到三台服务器上。三台服务器的编号分别是A,B,C。
2023-05-27 23:41:03
740
原创 代理模式 静态代理 JDK动态代理 Cglib动态代理
该方法返回一个代理对象,该对象实现了指定接口列表中的所有接口,你要执行被代理类C的function1()方法,只需要执行代理对象的function1()方法即可。下面这张图也写得挺好的:很直观的表明了代理类就是被代理类的增强和扩展。而Cglib动态代理允许代理类和被代理类都不实现接口。动态代理要求被代理类实现接口,代理类可以不实现接口。代理类不需要实现接口,被代理类还是要实现接口。被代理的类C和代理类B都要实现同一个接口。静态代理要求代理类和被代理类都实现接口。代理类B中调用代理类C中相同的方法。
2023-05-24 23:41:17
580
原创 清晰易懂IoC
改进:这样服务端(Service层)的代码不用改动,你客户端传进来Dao1类的对象,那就调用Dao1,那就调用Dao1类的方法。value=”Spring“ 表示给str这个属性赋值Spring(注意这里如果是ref=”XXX“,表示给这个属性赋值一个对象,这个对象已经在Spring容器里面创建好了)这段代码的问题在于,如果想要调用不同的dao层,就需要在服务端的代码Service层中进行改动。现在,服务端被动的接收对象,控制权在用户手上,服务端的代码是写死的,不需要改变。3.依赖注入的三种方式。
2023-05-24 16:23:34
709
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅