自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 网络通信IO模型-BIO

因为accpet会阻塞,如果因为没有客户端建立连接,就没有返回值,会一直阻塞,只有客户端建立连接,才能从阻塞变成返回,然后再读取客户端发送过来的数据,读取输入流并打印用户发送的数据,读取的话,也有可能变成阻塞状态,如果客户端一直不发送数据过来,服务器端就会一直阻塞,所以要把客户端读取的过程放到另外一个线程里面去做。刚才accept 3 阻塞在这里了,一个客户端连接进来之后,就会立刻返回一个代表客户端连接的文件描述符5,并且绑定了客户端端口号,

2023-05-28 23:02:43 1183 1

原创 网络通信IO模型上

每震荡一下,就会给cpu产生一个时钟中断,比如cpu正忙着读取某一个进程的指令执行呢,1/1000秒的时候,震荡了一下,这时候cpu会把这个程序的寄存器的值更新下,记录下此时执行的状态,即保护现场,然后从中断向量表中找到这个中断号对应的回调函数,这个回调函数是在内核启动的时候注册的,切换到另外一个进程之后,读取寄存器中的数据,即恢复现场,然后继续执行。cpu有一个时间分片的概念,比如在一个cpu的情况下,执行下内核里面的程序,再切换执行下用户空间中的程序,看起来很多程序在同时运行,其实是有先后顺序的。

2023-05-28 16:51:30 1380

原创 ChatGPT原理简介

贝塔系数(β)是一个权重, SFT表示有监督渲染出来的模型,把x输入之后,有监督模型会帮我们生成一个结果,强化学习ChatGPT也会生成一个结果,强化学习跟有监督之间的一个pk,两者做了一个除法,输出是一个句子,可以把输出一个句子叫输出一个分布或者输出它的概率分布,这时强化学习认为输入这个句子每个词的概率分布合在一起。是不是以后不上网吧就行了呢?我爸教育我,你这么做是不对的,我爸给了明确的标签,有了标准答案,我下次去网吧的时候,就会想一想是我不对,不是我爸不对,那这次我就不去网吧了,这是一个有监督学习。

2023-05-17 23:23:08 31622 13

原创 GPT前2代版本简介

承接上文2018年,Google的Bert和OpenAI的GPT绝代双骄,两者非常像,都是语言模型,都基本上是无监督的方式去训练的,你给我一个文本,我给你一个语言模型出来。GPT前两代没有什么特别的,第三代才有点大发神威。GPT还不是特别火的时候,已经预计每天产生450亿词,每小时生成100W本书,所以以后看到的东西,可能是AI生成出来的。这仅仅是22年5月份的GPT-3的情况。

2023-05-14 23:14:17 1796 2

原创 ChatGPT进化的过程简介

可以看到两者差距非常小,区别是两者使用的GPT版本不同。所以看了InstructGPT论文应该就可以知道ChatGPT大致怎么被训练出来的了。

2023-04-25 22:46:30 3103

原创 异构系统的事务统一处理模型Saga

XA和AT都是数据源代理,业务侵入型少;比如图1中这3个完全没有关系的服务,在总业务逻辑处理的时候,使用Saga的状态机来定义,调用服务1,再调用服务2,再调用服务3。Seata中的Saga事务模式是由外部的Saga提供的状态机来进行完成的,需要定义总流程,状态机里可以定义当前节点的调用服务,而且每个节点上可以配置当前这个调用服务的反向补偿节点。一阶段正向执行,比如T1和T2正常,T2到T3也正常,T3位置出现问题了, 就需要整体的回滚,这个时候就会进行反向补偿,把之前的已成功的状态都补偿回去。

2023-04-23 22:57:57 500

原创 分布式事务Seata-TCC事务模式

下单请求给到事务协调者,首先调用订单服务Try方法执行下单中的逻辑,然后调用库存服务,锁定库存,事务协调者如果没有收到问题反馈,就调用每个具体服务的Confirm,即调用订单服务Confirm执行支付逻辑,调用库存服务Confirm执行扣减库存的逻辑,如果扣减库存出问题了,就调用订单服务的Concel执行未支付或回滚的逻辑。TCC是二阶段提交协议,Try-Confirm-Cancel(资源预留、确认操作、取消操作),Try是对当前业务资源的检查,如果成功,则Confirm提交,否则Cancel回滚。

2023-04-23 19:52:16 495

原创 Seata强一致性事务模式XA的设计理念

如果库存减1了,订单并没有真正创建,这个时候读库存,读到的确实是99,这个99就是所谓的中间状态,这个就是脏读。AT、SAGA、TCC都是补偿型的,都会出现脏读的情况,当然Seata本身是有预防的,但确实会存在这些问题:可能会得到脏数据且最终一致性是允许有中间状态的,这也解释了为什么Seata支持XA,因为XA是强一致性的。如果一个参与全局事务的RM资源失联了,收不到分支事务的结束命令,那它锁定的数据就会被一直锁定,就有可能会产生死锁,这是XA协议要解决的核心问题,也是Seata引入XA模式要解决的问题。

2023-04-22 15:16:06 563

原创 分布式事务Seata-AT模式

一阶段,会拦截业务sql(比如订单先调用库存(库存减1),再生成订单),Seata解析sql语句,同时要找到当前要更新的业务数据,比如库存减1,在数据被更新前,保存undolog日志,再执行业务sql,更新之后的数据再保存到redolog日志。回滚的时候所用到的数据就在undolog,即在数据被正式更新之前所保存下来的原数据作为回滚的依据,通过回滚反向生成sql完成分支事务的回滚,事务结束后会释放所有资源和删除所有日志。TM发起全局事务的执行,不同的分支事务需要执行自己的本地事务。

2023-04-20 23:28:52 497

原创 分布式数据一致性解决方案推理过程

客户端从集群中节点3取数据的时候,因为它已经shutdown了(此时进程还活着,只是跟别的节点连不上 ,必须要找到另外一个小伙伴,2个节点的时候,才能对外提供服务), b和c只能从另外两台(节点1、2)取,这两台曾经又登记过a=3,所以对方一定能够取到正确的数据,这样就可以保证数据最终一致性了。为了解决可用性问题,本来不加b,a可以一直存活,加了b,b挂了,a没挂,给a写,还必须要同步给b,b还不在,只能阻塞等b恢复,即强一致性行为间接会破坏可用性。如果再有一个redis c,则出现问题的几率更高。

2023-04-19 00:00:13 195

原创 怎么设计秒杀系统?

在APP真正秒杀前,将要请求访问的页面资源缓存到客户端或CDN中,这样的话,在未来并发请求的时候,用户请求的是动态数据,而不是请求的静态数据,就不会因为请求数据量大,IO瓶颈等问题导致出现用户连接不上的异常。service服务通过MQ异步调用订单服务,将超出订单服务处理能力的流量放到MQ中,再由订单服务异步消费处理,这也是削峰的过程。用户确认订单信息之后,页面跳转进行购买付款的操作,通过接入层分流进入付款购买服务,付款购买服务查看订单的状态是否可以进行购买。订单系统生成订单,给用户返回请求成功。

2023-04-14 23:47:35 933

原创 Kafka是如何支持百万级TPS的?

程序读取文件,调用内核的read(fd 8)方法,由内核替代程序读取文件描述符fd 8,程序就进入了所谓的io阻塞状态,即由用户态切换到内核态,由内核调用驱动再去读取这个文件,内核驱动将文件数据读取到内核空间,内核再拷贝到用户空间给程序使用。这个空间和磁盘文件做了MMAP映射,从这个空间中读取文件相当于从磁盘中读取文件,即文件的数据是直接放到这个共享区域里面的,程序可以不通过磁盘读取文件,而是直接从这个共享区域里面读取,减少了一次内核到进程之间数据拷贝的过程。程序只需要打开文件,拿到输入流的文件描述符;

2023-04-12 23:11:16 809

原创 网络IO模型BIO->Select->Epoll多路复用的进化史

假设有一个客户端想通过TCP和tomcat 8080建立一个连接,fd3上一定会产生一个客户端建立连接的事件,这个事件一定会被内核的事件机制(中断机制)发现,所以内核会把这个区域的fd3拿出来,因为它有数据到达了,再放入另外一个区域里,另外一个区域放入fd3,只要tomcat这个程序未来调用过了epoll wait,就会把这个区域的fd3给tomcat,tomcat就会判断fd3的事件是有人建立了连接,所以它会调用accept接收并得到一个fd4,服务器资源会被瞬间填满,真正想去连接的人却挤不进去了。

2023-04-06 22:33:03 437

原创 MySQL 幻读问题

因为在RR(可重复读)隔离级别里,事务1的第二次查询没有生成新的readview,而是用的第一次查询时生成的readview,所以第二次查询返回2条数据,而不是3条数据,这就是幻读现象。select 执行的是快照读(某个版本数据的Read View),而update 执行的是当前读(最新的数据,即最新的Read View,因此更新了三条数据)。但是当快照读和当前读一起使用的时候才会产生幻读问题,因为执行了一个update操作,即用了当前读,此时读取的数据是不一致的,就产生了幻读的问题。

2023-04-02 19:30:54 308

原创 MySQL多版本并发控制MVCC实现原理

承接上文。

2023-04-01 19:08:29 410

原创 MySQL事务特性ACID实现原理

Mysql 索引特点MQ消费端如何保证幂等性?MySQL使用B+Tree的数据结构,尽可能少的层级或IO读取量的情况下,能够缓存或存储更多数据量且达到快速查询的效果。在进行索引存储的时候,索引的数据要放到磁盘里面,不可能将磁盘里面的所有文件一口气读到内存里面,因此要使用分块读取的方式,而操作系统本身进行内存和磁盘交互的时候是以页为单位的,按照页的整数倍作为某一个磁盘块来进行数据的读取。在进行数据读取的时候,还要确认一个事情:索引是要有key-value值的,key是指定的索引列,value是具体的行数据。索

2023-03-30 22:27:30 319

原创 MQ消费端如何保证幂等性?

承接上文RabbitMQ、RocketMQ、Kafka性能为何差距如此大?这是乐观锁的一种实现,每一次要对库存的数量+1,这种方式解决消息重复没有问题,但不太好,因为消息在生产的时候,生产者要判断id是不是重复的,如果是重复的,下一次version+1,相当于浏览器点击了2次。这种方式虽然可以解决消息幂等性问题,但要求生产者也要改动,一般情况下不推荐。并发不是很高用mysql实现,并发高用redis实现。在表上要构建一个唯一性的索引,电商平台有一个订单id,适合做唯一性的索引,比如在进行库存扣减的时候,每次

2023-03-30 22:24:11 267

原创 RabbitMQ、RocketMQ、Kafka性能为何差距如此之大?

创建的socket就是一个连接,应用要跟消费者建立一个TCP的连接,这个TCP的连接在底层表示都是socket,不单单只是数据连接,还包含了数据通道,这里new一个socket就相当于跟另外一个消费者8081这样的socket通道建立了链接,通过socket通道里面的dataOutputStream.write方法输出数据,这里又会涉及到一次DMA拷贝,一次CPU拷贝。在计算机里面,启动一个线程,让CPU来跑,CPU在跑的时候,你给我发了一个消息,我的电脑怎么知道我的网卡里面进来一条消息呢?

2023-03-26 18:49:15 667

原创 Spring怎么用三级缓存解决循环依赖问题

刚才是为了给b里面的a属性赋值:先实例化a再初始化a,初始化a的时候找b,先实例化b,再初始化b,初始化b的时候要去容器里面找a,a找回来了,赋值给b中的a属性,当赋值完成之后,相当于把a的半成品取回来,完成了整体的赋值操作,意味着b的实例化和初始化都完成了。先实例化b对象,如果能成功,说明只是在堆中分配了一块内存空间,并没有设置一个具体的属性值,这里也是半成品,接下来要完成b对象的初始化操作即给b对象中的a属性赋值,去spring容器中查找a对象,如果有的话,直接赋值返回;

2023-03-18 17:20:02 799

原创 Spring Bean实例化和初始化的过程

要提前把后面需要用到的beanPostProcessor准备好,如果想在整个bean的spring生命周期里面,在不同的阶段做不同的处理工作,监听器 、监听事件、多播器等这些东西都要提前准备好,只有把这些准备好之后,才能进行后续的调用工作,这是一整个流程,不可能用的时候再准备。配置文件经过读取之后要放到容器里面去,所以第一步先应该有对应的容器工厂或者有bean工厂,当有了BeanFactory之后,才能进行相关的加载工作,所以第一步应该先创建一个容器,当把容器创建好了之后,下一步才读取配置文件。

2023-03-16 23:45:02 934

原创 Spring Bean生命周期

判断类上有没有@PropertySource注解,有的话,进行相应的解析和处理,进而完成一个具体的解析操作,所以这里可以进行扩展,自己需要的时候,就可以进行一些基础的相关扩展工作,但关键点是你要对它整体的执行流程和执行机制比较清楚并且可以修改源码。继承BeanFactoryPostProcessor,也可以修改自定义bean的属性信息,比如xml中定义了100个bean User(name,age),想要修改其中一个user bean的age属性值,就可以通过这种方式。

2023-03-15 19:10:55 360

原创 Spring框架源码分析一

当还需要一些其他的配置文件的时候,只需要创建具体的子类实现这个接口进行解析就可以了,解析完之后,有一个统一的出口都放到BeanDefinition中去,就相当于提前做了一个抽象,这层抽象来完成具体对应的一个功能,此时已经有了bean的定义信息了,下一步就要把当前这个bean进行一些实例化工作,不同的文件需要进行不同的解析工作,中间要进行一个抽象层,抽象存在的意义是定义一些相关的规范或者定义一些相关的方法,由对应的方法来完成具体的解析工作 ,那么再由具体的实现子类去进行相关的一个实现就可以了。

2023-03-11 12:22:01 362

原创 Mysql 索引特点

没有索引下推前,先根据name的值从存储引擎中拿到符合条件的数据,然后在server中对age进行数据过滤,有了索引下推之后,直接根据name和age从存储引擎中筛选对应的数据,返回给server,不需要做索引过滤;id是主键,name是普通索引, 先根据name值去name B+树找到对应的叶子节点,取出id值,再根据id值去id B+树中查找全部的结果,这个过程称为回表,回表的效率比较低,尽可能不要使用,避免回表的产生,因为需要回到原来的表里查询对应的数据记录。第一和第三个sql符合该原则;

2023-03-08 22:55:45 388

原创 Mysql Server原理简介

一个磁盘块16kb,读一次,3层,3个磁盘块,比如读取磁盘块1->磁盘块3->磁盘块7,依然读取了48kb的数据,假设磁盘块1中的p1+28占了10个字节,16*1024/10大约1600个子节点,第二层一个磁盘块也是1600个节点,第三层只能存16条,存满的话1600 x 1600 x 16=40960000,千万级别。所有的data都放到叶子节点里面去了,非叶子节点不存储实际的数据,只有在叶子节点才会存储实际的数据,这样的一个3层B+ Tree,如果存满的话,可以支持多少数据量的存储?

2023-03-06 22:45:47 990

原创 HTTP的前世今生

那么tcp数据包1和3会提前达到缓冲区,tcp就会发现数据包1和3之间缺少了数据包2的字节范围数据,哪怕http2知道tcp数据包1中有stream id为1的数据帧,加上tcp数据包3中stream为1的数据帧,可以组装成一个完整的消息,也要耐心等待tcp至少重返服务器一次,来重传丢包的数据2的数据副本到达才能继续解包其他tcp数据交给应用程序层,就是丢失的tcp数据包2阻塞了tcp数据包3导致了tcp的线头阻塞,所以结论就是http2并没有完全解决线头阻塞的问题。

2023-03-01 22:11:48 309 1

原创 k8s node之间是如何通信的?

flannel虚拟出来了一组ip,然后进行node和node之间通信的时候,它实际上是通过node上实际的网络设备的ip地址进行路由。flannel network是10.1.0.0,10.1是整个集群总的网段,给每个node使用ip地址的第三位即给每个node再划分网段,每个node再用具体划分的网段再给pod分配ip地址。采用了扁平化的网络,这个网络的维护是flannel的demon,有新的node加入进来,通过etcd注册并分配这个node相应的网络空间,并且通知后台的damon用来控制报文的转发。

2023-02-27 15:01:43 662

原创 HTTP请求的详细过程

发生了第三次挥手,客户端收到了服务器的分手请求之后,带上+1的序列号和+1的确认码回复给服务器,于是服务器关闭了连接,客户端进入了定时等待时间,这两个报文的最大生存周期,不同的操作系统不一样,大约是1-4分钟即俗称的冷静期,冷静期后客户端才真正的断开。b站的响应结果是一样的,那起初DNS的域名是谁操作绑定在一起的,当然是b站所属的公司,注册了bilibili的域名,指定好域名的DNS,做好A记录解析来对应好服务器的ip地址,这样就可以通过域名访问b站了。如果你了解背后的原理再进行开发,那是见天地;

2023-02-27 14:53:33 256

原创 docker网络基础

vethe35b867@if4657是docker0在宿主机上新建的网络设备,和tomcat01容器里面的eth0@if4658正好是一对。local的简写,本地回环地址,127.0.0.1,它代表本地虚拟设备接口,默认被看作是永远不会宕掉的接口。本文简单介绍下,容器之间的网络访问、容器与宿主机之间的网络访问、宿主机上有哪些网络接口。docker使用的是linux的桥接,docker中所有的网络接口都是虚拟的。配对的网络接口,一端连接容器,一端连接网关,这样就可以实现容器之间的访问。

2023-02-23 14:50:16 354

原创 k8s service的底层实现

如果和当前的进程相关,就会进入filter表的INPUT这个步骤,当本机的进程有报文输出的话,会先走nat这张表的OUTPUT步骤,在这个步骤中可能再去做一个DNAT来决定这个报文的目的地址是原封不动的还是要做一些改动,然后再经过filter的OUTPUT链再走POSTROUTING就出去了,在POSTROUTING的时候还可以做一个SNAT(源网络地址的NAT),决定这个报文出去的ip地址是不是需要变化,源网络地址就是别人可以看到的这个地址,表示报文从哪里来的。

2023-02-23 14:50:16 332

原创 ingress服务

通过yaml文件创建ingress资源的时候其实就是在ingress的pod里面的nginx里面配置了路由关系,动态的加入了 order和user这样的配置,再通过nginx反向代理的方式进行请求的转发。这个是nginx ingress的一个注释,接受到外部的请求比如是api/user/v1,但是转发给user service或order service,按照根目录进行转发,去掉请求中的子目录,在DNS做域名解析的时候,一个域名只能对应一个ip,但这里有2个公网ip,所以这种情况怎么解决呢?

2023-02-23 14:49:12 158

原创 CPU原理简介

当有了算法逻辑单元之后,整个计算的构成还需要其他的电路,比如时钟信号电路,一个是为了计时,再一个会不断的刷新电路,每刷一步电路就往前进一步做一个计算,因为到最后的时候,你会发现所有的计算都需要一个控制电路,控制电路必须一会联通,一会断开,每通一次整个的计算才会往前进一步。通一次电,计算才往前走一步,所以需要一个时钟电路,时钟电路需要电池信号,线圈一通电就会产生磁场,磁场把开关断下来,断下来之后就不通了,不通了之后,电池没电了,开关闭合,电流又通了,这样来回来去的。反之,当自变量取值相同时,函数为0;

2023-02-23 14:46:53 240

原创 K8s调度器Scheduler

调度器给apiserver发出了一个创建pod的api请求,apiserver首先将pod的基本信息保存在etcd,apiserver又会把这些信息给到每个node上的kubelet进程,kubelet一直在监听这些信息,当kubelet发现这个pod的节点信息跟它当前运行的节点一致的时候,就会创建pod进程以及容器当中的docker image进程,创建相应的命名空间,使得进程之间互相隔离,这样pod就在这个节点上运行起来了。实际运用的场景比如前后端的pod运行在同一个node上。

2023-02-23 14:46:49 336

原创 线程的执行

地址线是一个寻址的线,QQ.exe这个程序放到内存之后,它一定会放到内存的某个地址上,比如这个地址是3号地址,在3号地址的起始位置是main方法,在起步的位置一定会放一条指令,操作系统会通知cpu,你去读3号地址,先把指令读过来,读过来指令如果是add,它就会通知地址线,再把后面的2个数字都读过来,读到寄存器,然后计算单元开始做add计算,计算完了之后,存到某个寄存器,然后再写回内存。一个程序的执行,首先把可执行文件放到内存,找到起始位置即main开始的地址,进行读取指令和数据,进行计算并写回内存。

2023-02-23 14:44:09 638

原创 CPU缓存一致性协议原理

一个long类型的x是8个字节,这2个x位于同一个缓存行的概率极大(尤其这2个x位于同一个数组,在内存中是挨着的),2个cpu分别修改一个x,2个x在一方cpu都有缓存,修改了其中一个需要通知另外一个,每改一次通知一下,总之在修改的时候需要触发一种机制需要另外的cpu跟我保持一致,如果这样的话,耗时当然会比较长。当要访问一个数据的时候,干脆每一次缓存一小块的数据,这一小块数据里面包含了整个数组的数据,当访问数组中的任意元素数据的时候,就可以直接从缓存中读取到了,这一块的数据被称为缓存行。

2023-02-23 14:43:17 286

原创 证明CPU指令是乱序执行的

单线程的情况下,2个指令乱了顺序执行没有关系,反正最终的结果是一样的,但是在多线程的情况下,非常有可能出现你不想看到的情形,比如x=0、y=0的情况,比如在预知中没有这种情况,但是多线程的情况下,会出现,所以一定会影响整个多线程程序的运行,单线程的程序不会影响。这两种是乱序执行的排列组合,比如第一个场景是线程1先执行x=b、线程2执行y=a,切换到线程1执行a=1,切换到线程2执行b=1,结果是x=0、y=0。第一种组合先执行a=1、x=b,后执行b=1、y=a,得到的结果是x=0、y=1。

2023-02-23 14:43:11 723

原创 DCL单例模式是如何保证数据安全的?

第一个线程判断对象为空,在获取锁之前,切换给了第二个线程执行,第二个线程判断对象为空,获取锁,上完锁后,new对象,把锁释放,然后第二个线程结束,在这个时候第一个线程继续运行,因为第一个线程已经判断完了,直接申请上锁,此时是可以上锁成功的,因为第二个线程已经把锁释放了,线程1又new了一个对象。这样缩小了锁的粒度,不将业务代码的是否等于空的判断加锁,等判断为空之后,再上锁,上完锁,再new对象,这是追求效率的写法,但在多线程访问的情况下能不能保证数据的一致性?

2023-02-23 14:39:40 196

原创 JVM级别内存屏障如何禁止指令重排序的

为什么有一个空指令存在,因lock指令在锁总线的时候,这条指令后面必须跟一条指令,后面指令不能为空,所以后面得跟一条指令,但是后面跟的又不能有任何作用,如果有任何作用,中间改了别的值,也不对,所以设计了这么一个指令,往某个寄存器上加了个0,跟没有操作一样,主要为了迎合lock指令的参数要求即后面必须跟一个指令,其实只要有一个lock指令就足够了。java写的volatile,jvm编译执行,java是解释执行的,所以要想了解volatile怎么实现的,得去读hotspot解释器的代码,看是怎么解释完成的?

2023-02-23 14:37:08 818 2

原创 虚拟机指令集&栈与函数调用

指令集save&loadIMM全称load immidiatily立即加载数据到寄存器LEAload effective address加载地址LC/LI/SC/SIload char/load int:将char和int加载到寄存器save char/save int:将char和int从寄存器加载到内存PUSH将寄存器的数据推到栈顶stack peek举例ax是通用寄存器pc是代码区指针program counter指向当前正在执行的指令这些指令背

2022-03-13 20:03:13 3442

原创 C语言编译器概要设计思路一

700行代码自制C语言编译器一编译器1、编译器定义将高级别语言翻译成更底层的机器可执行的语言2、工业级编译器的编译过程编译过程分前端和后端两个阶段2-1 前端前端即parser:将源代码翻译成中间代码,以便给后端程序进一步处理parser过程分两个步骤词法分析即tokenize词法分析的目标是把人类语言简单处理一下告诉计算机这些词都是什么含义比如把int单词识别出来告诉计算机是整型;add识别出来告诉计算机是一个函数语法分析通过词法分析计算机已经知道每个词是什么意思通过语法分

2022-03-07 00:22:41 1328

原创 自动化运维环境搭建过程

本文介绍下"代码提交自动部署到云原生并实时查看服务的运行状态"运行环境的搭建过程k8s方式安装gitlab下载gitlab yaml文件git clone https://gitee.com/pingfanrenbiji/gitlab安装postgresql、redis、gitlab镜像下载docker pull sameersbn/postgresql:10docker pull sameersbn/redisdocker pull sameersbn/gitlab:11.8.1k8

2022-02-23 17:50:47 859

空空如也

空空如也

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

TA关注的人

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