自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 GO简单开发grpc

首先我们需要了解,什么是grpcoogleemoterocedureall)是由Google开发的一个高性能、开源的远程过程调用(RPC)框架。它基于 HTTP/2 协议,并且使用 Protocol Buffers(Protobuf)作为接口定义语言,提供了不同系统之间高效、安全的通信方式。gRPC 支持多种语言(包括 Go、C++、Java、Python 等),并且提供了丰富的功能,比如流式处理、双向通信、负载均衡等。

2025-04-05 19:54:28 577

原创 GO语言 使用protobuf

protobuf是一种类似于json和xml的数据序列化格式我们可能会存在这样的问题:不同语言之间真的没有办法互相传递数据吗?如果可以,那如果一个项目使用了多种语言有应该如何传递数据?这个过程其实很简单,就是拆解与拼装的过程,假如我们有一个数据a,这个数据在另一个语言内没有直接对应的结构。我们就可以把它序列化即转为二进制传输。只需要发送方和接收方使用的是同一种数据序列化格式即可。protobuf就是其中之一。我们为什么要使用protobuf呢?简单来说是因为它快,而且更适用于后端服务之间的交流。

2025-04-02 19:57:25 674 1

原创 Ubuntu下载docker、xshell

配置:VMware虚拟机、Ubuntu24.04.1首先打开vm启动虚拟机。

2025-03-28 18:15:49 805

原创 vm虚拟机 Ubuntu ping失败情况解决方法

这个时候我们再次打开虚拟机 ,我这里用的是Ubuntu,ctrl+alt+t打开终端,输入ip a查看IP地址。这里可以看到我的ip是192.168.135.221,然后我虚拟机的ip是192.168.135.184。宿主机我们通过ipconfig命令查看 ,他可能会跳出多个适配器的配置,我们忽略掉带有VMware的。再次选中虚拟机,右键打开设置, 网络适配器选择桥接模式,并勾选下方的选项。把我们当前使用的网络的防火墙关闭,再次尝试ping。我们选择我们需要的网络, 如果不知道选哪个我们可以。

2025-03-27 11:47:59 448

原创 GO语言 单元测试

注:go的测试文件需要和被测试的文件处于同一个包内。并且测试文件需要以_test.go结尾,测试文件内测试函数的书写方式为Testxxx(以Test开头。

2025-03-22 15:34:37 1112

原创 使用vite新建vue3项目 以及elementui的使用 vite组件问题

在创建项目之前我们应该在终端中输入node -v 和 npm -v只有它们都能正常查看版本号才说明我们之前是已经安装完成的。接下来我们在合适的目录下输入npm create vite@latest它会要求你输入项目的名称,这个名称和我们之前通过cil创建的命名规则一样。完成之后会要求我们选择合适的框架我们这里选择vue,然后会让我们选择语言,我们选择JavaScript完成之后我们通过 cd 目录 进入然后输入npm install进行依赖安装。之后通过npm run dev运行项目。

2025-03-19 17:20:12 1311

原创 个人blog系统 前后端分离 前端js后端go

系统设计:1.使用语言:前端使用vue,并使用axios向后端发送数据。后端使用的是go的gin框架,并使用grom连接数据库实现数据存储读取。2.设计结构:最终展示:仅展示添加模块,其他模块基本相似。

2025-03-18 20:10:25 776 1

原创 vue3 setup

我们之前所讲的基本都是vue2的一些内容,但是是可以在vue3中使用的。vue3相对于vue2来说就像是pro 和 promax的区别一个升级的版本需要注意的是vue3依旧兼容大部分的vue2写法,只是有一部分不再兼容,这部分大家可以自行搜索。

2025-03-16 13:00:40 960 1

原创 vuejs 组件基础 路由

我们在组件内设置了css的属性,并且把这个组件导入了app,alpha的css样式也是会影响到app的。我们引入组件之后就需要挂载组件,我们需要在js部分的export default{ }里面写一个components:{组件的名称(比如上面说的alpha)}这是引用传递给被引用组件(app -》alpha),要注意的是如果我们需要传递数组和对象,它的默认值(props里面的default要通过函数来返回)我们通过children设置了路由的嵌套,并且通过箭头函数来在调用的时候才会加载导入相应的组件。

2025-03-11 19:01:44 617

原创 vuejs 模板语法、条件渲染、v-for、事件处理、表单输入绑定

创建vue项目之后我们就可以开始写代码了,我们的代码一般都会写在src目录-components目录-HelloWord.vue文件内。我们之前写的HTML文件的结构是HTML代码可以集成或者连接外部的css/js文件。我们通过vue建立的项目,它的结构是在一个vue文件内集成了HTML、css、JavaScript的代码。包含三个部分:<template><script><style scoped>分别对应HTML代码、JavaScript代码、css样式。

2025-03-08 16:14:05 976

原创 vue 安装 环境变量配置 创建新项目 webstrom的设置

然后在node解释器,添加新的路径,选择添加local...。这个路径就是我们node下载的路径,找到node.exe,复制路径到这个里面就可以了。等待安装完成,中间会有一个安装路径的设置,根据自己要求来,我安装到了新建的nodejs文件夹下了。然后在弹出的界面我们选择是否保存这次的配置,我们一般不保存,因为这个配置只是基础的没啥用。这样就创建完成了,我们可以输入cd vue-two进入,然后输入npm run serve运行。然后按回车,然后弹出界面选择版本,我们选择带数字3的。我们可以访问这两个网址。

2025-03-06 16:23:49 900

原创 JavaScript 进阶B(实例、静态成员 防抖 节流 (数组的简单去重)

但是要注意的是,如果是数组嵌套对象的形式,即使连个对象数据都是一样的也会被认为是不同的两个对象。这是因为set使用的是===的严格匹配,虽然对象的属性方法相同,但是依旧是两个独立的对象,我修改其中一个并不会影响另外的一个对象。通过new关键字创建的对象我们成为实例对象,实例对象的方法和属性成为实例成员。这里用到的闭包是为了让a这个变量私有化,只有在按钮的事件监听触发的时候才会调用fd函数,才会访问到a。然后我们又给构造函数添加了属性和方法,但是要注意的是构造函数创建的对象无法调用构造函数的属性和方法。

2025-03-05 19:30:10 371

原创 JavaScript 进阶A(作用域、闭包、变量和函数提升、函数相关只是、数组解构、对象解构、构造函数

这就导致了内部的函数引用了外部的变量。通过这个我们可以很明确的发现,使用var声明的变量可以在声明语句前被访问,但是访问的结果是undefined,变量在未赋值之前访问结果是undefined。剩余参数:我们在传参的时候一般都是一一对应的传参,如果传递的实参数量大于形参,剩余的没有对应的参数就是剩余参数。作用域链就是变量查找的机制,在函数被调用的时候,会优先查找函数作用域内的变量。假设有一个数组arr=[1,2,3,4,5,6,7] 则 ...arr = 1,2,3,4,5,6,7(不是字符串。

2025-03-02 17:57:34 817

原创 JavaScript 年后复习

定义一个函数 sum,接收两个参数 a 和 b,返回它们的和。然后调用该函数并输出结果。函数的定义需要用到function,sum作为函数名,后面的括号跟的是形参列表。函数体的作用是返回两数相加之和然后我们使用console.log输出打印函数的结果到浏览器控制台相同的输出还有1、alert()提示框输出 2、document.write()输出到浏览器。

2025-02-22 17:27:10 529

原创 GO语言 年后复习

ShapeList := []Shape{Rectangle{10, 20}, Circle{10}, Rectangle{11, 12}}在这条语句中我创建了一个Shape类型的切片,这个切片里面有三个结构体,但是我们又发现了,切片的类型是Shape,它是一个接口,那为什么可以存储结构体呢?需要注意的是我们的go模块和包都是以创建目录的形式创建的,区分的时候要观察是否有go.mod文件,如果有的话说明是go模块,没有go.mod却有.go文件就说明是一个包。这样我们就创建好了一个新的go模块。

2025-02-16 12:35:46 787

原创 GO语言 链表(单向链表

如果我们直接创建一个结构体变量,那它的类型就是user,由因为我们是在insert_end函数里面创建的这个变量,所以它的生命周期只有在这个函数里面存在。我们在insert_head函数里面的head并不是main函数里面的head,他只是一个副本,我们需要副本覆盖掉原来的。在这个方法中我们需要确定当前节点的下一个节点是否是我们需要插入到它之前的节点。如果是的话就让当前节点的next指向新节点,新节点的next指向原下一节点。头节点的作用相当于链表的入口,尾节点用来表示节点的结尾,中间节点用于存储信息。

2025-01-26 20:06:45 699

原创 JavaScript 数组的map和join方法、延迟函数、location对象、本地存储、正则表达式、箭头函数

正则表达式feifeifeifeifeifeichang重要,它可以匹配我们的数据是否符合某种规范,我们在注册账户的时候都会有格式的要求,这个就是正则表达式的运用JavaScript的正则表达式都是使用 // 包起来的可以直接匹配某些文字,比如我想在“我高数挂科了”这样一句话中匹配 挂科 这两个字我们就可以直接写一个正则表达式 /挂科/ --》正则不加引号然后使用test()进行匹配,匹配成功返回true否则返回falseconst regex = /挂科/

2025-01-24 13:47:35 1045

原创 JavaScript 日期对象、DOM节点操作

div.childern会返回一个伪数组,可以使用下标访问这些数组元素,假设div有10个子元素,我像插入到最前面,代码如下:div.insertBefore(要插入元素,child[0])设有一个对象alpha,想得到它的父节点。示例:ul1.removeChild(ul1.children[1])ul1是一个父元素,删除父元素中的第二个子元素。删除节点需要用到父元素,代码格式:父元素.removeChild(要删除的元素)Dom元素可以看作一个树,有上层的父节点,下层的子节点,同层的兄弟节点。

2025-01-19 19:59:31 740

原创 JavaScript this、回调函数、事件流、事件委托、默认行为

它的语法格式就是事件监听button.addEventListener(事件,对应函数)因为第三个参数是默认的false,也就是冒泡。它又是默认冒泡的,也就是说我们触发子元素就一定会触发父元素。1.call 格式 函数.call(this指向的对象,函数的参数列表) //函数没有参数就可以省略掉参数列表。回调函数是个概念,大致意思就是假设有a,b两个函数,在b里面调用a,a就被称为回调函数,再具体的就等以后慢慢扩展。3.bind,这个方法区别于前两个,它不会直接执行函数,而是返回一个新的函数。

2025-01-15 21:39:02 779

原创 JavaScript 自定义属性、间歇函数、事件监听。以及综合运用案例

自定义属性:给元素增加一些说明或者标识之类的东西,它并不会影响到元素本身。但是我们可以通过这个自定义属性来操作元素自定义属性都是以:data- 开头,后面可以跟自己起的名字,例如data-id=123,这就是设置了一个自定义属性id,值为123,也可以是"123"既然元素有了自定义属性,那就会有使用元素属性的地方。获取自定义属性,我们首先要获取到一个元素对象。然后通过:对象.dataset.自定义属性来获取。

2025-01-11 20:09:07 872

原创 JavaScript 获取DOM对象

html的标签被js获取到之后就变成了js对象,对象里面包含了标签的属性和方法。同一时间获取多个对象则会翻译一个数组,数组元素是对象。

2025-01-05 12:32:56 860

原创 JavaScript 基础2

同样,我们并不确定函数接收到了参数没有,如果没有传递参数,在运行的时候也是不会报错的。如果表达式1为真执行语句a,如果表达式1为假去判断表达式2,如果表达式2为真执行语句b,如果表达式2为假执行语句c。如果a是100,b是"100",则a==b为true,a===b为false。如果a是100,b是100,则a==b为true,a===b为true。在a||b的运算的时候,如果判断a为真,则整个a||b为真,不会判断b。在a&&b运算的时候如果a判断为假,则整个a&&b都为假,不会判断b。

2025-01-03 21:25:12 885

原创 JavaScript 基础

js中的变量在定义的时候没有类型这一说,而是存储什么数据就是什么类型。

2024-12-28 22:07:44 1069

原创 GO 网络编程

存放数据的容器有了,我们就可以来读取了。类型的指针,里面存储了一些重要的参数,蔽日请求的url,查询参数,表单数据,请求头等参数。然后我们就可以输出我们所读取的数据了,由于是字节类型的数据,所以我们在输出或者处理的时候需要先转换为字符串类型,也就是使用string()强制类型转换,buffer[:n],这个代表我们锁读取到的数据的有效位数。还有就是接收数据从Read()变为ReadFromUDP(),返回值除了写入的字节,错误信息还多了一个addr,这个里面存储的是发送数据的客户端的ip和端口号。

2024-12-22 20:04:29 915

原创 gin框架实现简单的mvc架构

/设置路由,我们的默认端口是8888,所以在设置了上面那个路之后我们就会可以通过localhost:8888/index去访问这个路由,第二个参数是针对这个路由的一些处理,这里是一个匿名函数,也可以是其他的东西。这样我们在访问/index的时候就会跳转到controller包下的Index函数了,这样模块话的设计在我们熟练之后会感觉非常的舒适。有了一个结构体之后我们在连接到数据库成功之后就可以使用db.AutoMigrate(&User{}),db是我们的数据库对象,User是结构体的名字。

2024-12-20 22:00:09 852

原创 GO 互斥锁、等待组

就是主进程都结束了,子进程才开始。这就导致子进程还没开始就随之结束了。但是这又限制了程序运行的速度。可以从输出结果看到每一个进程都有序的运行了,这样就避免了资源的竞争。比如果同一时间a进程和b进程都需要这个资源,这就导致了资源的竞争。互斥锁简单来说就是我访问这一个资源的时候把它锁起来,这个时候这个资源不能被其他进程访问。我们用人话来讲一下就是:先说好有n个进程,每个进程结束的时候让n-1.等n为0的时候所有进程都结束。这时候就要引入一个肥肠耗用的--------等待组。

2024-12-14 18:02:18 211

原创 GO语言 并发,通道

先运行for的通道取出数据操作,但是通道此时是空的,阻塞。ch是通道的名字,chan string是类型,2是缓冲区大小,说明可以存储两个string。但是这里有一个非常致命的错误,我们在运行这段代码的时候会发现,getit函数并没有被完整地运行下来。并发和并行不一样,并发是同一时间内处理多个任务,但不一定是同一时间进行的。我们需要确保的就是主进程的运行时间要大于子进程,或者说子进程在运行的时候主进程要存在。两个或者多个进程之间互相传递数据----------通道的创建-----------make。

2024-12-13 21:02:08 276

原创 GO 连接数据库实现数据的增删改查

这个数据库的表alpha内只有两列数据,一列是id,一列是name。一下所有操作均为针对这个表的操作。在使用的时候根据环境自由调整。实现数据的查询2.查询某一行数据。实现数据的查询1.查询所有数据。

2024-12-13 15:02:11 213

原创 GO 反射

reflect.TypeOf()获取类型。reflect.ValueOf()获取值。通过反射去修改结构体字段值。通过反射调用结构体方法。

2024-12-12 20:15:09 230

原创 GO语言连接到数据库

调用这个函数,第一个是我们的MySQL,第二个就是我们数据库的信息字符串,它会返回两个值:一个是数据库对象,一个是错误信息。安装完成之后就会想上面的图一样,导入的包都是绿色。我们看最后面的root,这个才是我们要使用的用户。密码是我们在下载MySQL的时候设置的,这个的话自己想想自己当初设置的是什么吧。可以看到我们首先是创建了一个字符串,字符串里面的信息我们来逐一讲解!那我们怎么知道用户名,密码,数据库的IP地址和端口号是多少?这样我们就得到了一个字符串,字符串包含了我们的数据库信息。

2024-12-10 19:57:07 1136

原创 GO 文件操作

可能有人注意到了上面的代码有 os.O_RDWR|os.O_CREATE这个,前面的我们知道是读写模式打开文件,那后面的是什么?后面的是创建文件,如果打开文件的时候文件不存在就会创建这个文件。第一种,直接读取文件所有内容,适用于文件内容较少(但是这个方法基本上也已经布增麽用了,我写这个方法的时候ide提示ioutil.ReadFile()已弃用)在文件写入之前我们需要明白的是,我们之前打开文件的时候是只有读取文件内容的权限的。既然了解了文件的写入权限,那我们就可以开始对文件进行写入操作了。

2024-12-08 16:54:56 431

原创 GO 方法

方法重写,依据上面的代码,sta.use()调用的是父类的方法,我们为子类设计一个方法(这个方法的名字和父类相同,只不过接收者改为了子类)。那我如果想在方法里面修改了接收者的值之后,对这个只值进行修改然后映射到原来的上面应该怎么办?这就说明我们接收者类型是指针类型,从结构体的值传递进化到了结构体指针的引用传递!我们会发现,虽然我们能访问这个结构体内的字段,但是没有办法改变它的值!在GO语言中,方法是与某个类型绑定的函数,可以操作这个类型的数据。接收者类型可以是结构体类型,或者非结构体的自定义别名类型。

2024-12-05 12:40:06 242

原创 GO 指针,结构体

所以在执行完student.next = son_student这条语句的时候并不是说student.next = son_student这种,而是student.next复制了son_student的值。如果我们有修改student .next.name之后会映射到son_student身上的需求的时候结构体的嵌套需要选择结构体指针嵌套,我们可以看到,我们用它的类型作为字段的名字了,这样做是可以的,但是需要注意的是重复的类型会报错。结构体的嵌套,就是结构体的字段类型是一个结构体。

2024-12-04 16:58:12 845

原创 GO语言的 defer

还有就是defer在延迟了一个函数调用语句并且这个语句里面有参数,那这个时候虽然函数调用被延迟了,但是but巴特!实参的值已经传递了,后面如果修改了实参的值也不会对被defer的语句造成影响,具体看示例代码↓。2.defer可以用在主函数和子函数中,针对的是它所属的函数。也就是说我在子函数中defer一个语句,它会在子函数结束的时候被执行。1.defer后面的语句需要是函数调用,比如输入输出,调用子函数。defer 语句的作用就是延迟语句生效时间。被defer的语句会被最后执行。下面来看一下示例代码吧!

2024-12-02 12:01:19 172

原创 Go 包的作用与导入包,还有函数

可以看到上面的图片中,我创建了一个文件夹bao1,里面有一个文件gongnengwenjian.go,它默认的包就是所属目录的名字->bao1。我们在创建完一个go项目后,在我们的项目文件夹下会自动生成两个文件,一个是main.go,另一个是go.mod。这段代码就是说明main.go文件是属于main这个包的,包的名字倒是无所谓,自己记得清楚就好。既然说了函数,那我们就会想为什么有的函数在调用的时候还需要在括号里面写东西呢?这个很方便,但是有的时候我们需要的功能,内置的包不一定都有。

2024-12-01 19:27:00 506

原创 Go String

我们有时候会需要对string进行处理,这时候就可以导入包strings。下面我会列出常用的几个操作函数。string,字符串。

2024-12-01 14:16:43 164

原创 go map

go的map有点像python的字典加上集合,都是一个键值对键值对的,而且map没有顺序。map与slice的结合(结婚了(不是。

2024-11-30 22:25:05 205

原创 go切片的拷贝

浅拷贝,顶层地址不同,但是拷贝对象的地址相同(就像两个指针指向同一个地址(上面的代码就是浅拷贝(因为改变一个会影响另一个的值捏~深拷贝,拷贝的值(数据本身)是两个独立的个体,地址不同,但是存储的值相同。copy(接收,被拷贝对象)这是两个切片的拷贝,这种方式是属于浅拷贝。这是通过切片的名字来对它们进行赋值。然后我们来尝试一下copy函数~插入一个知识点:深拷贝和浅拷贝。

2024-11-30 16:35:40 220

原创 go,选择排序

选择排序的原理就是找最小值或者最大值,如果有比他还小或者比他更大的就替换他们的位置。

2024-11-29 18:35:38 103

原创 go 冒泡排序,简单易上手

我们可以分析一下,这个排序的方法需要用到循环的嵌套吧,大的循环(父循环)控制一共循环多少次,小的循环(子循环)来对数值进行操作。从小到大的排序,最大的值肯定一定绝对在最后面,我们就可以从前往后,依次去比较,如果前面的值大于后面的就让他们互换位置。假设我们有一串有序数列:1,5,9,7,3,4,6,8,2,10。我们都知道,在水中大的气泡总是比小的气泡上浮的快。冒泡排序就和这个差不多(不然就不叫冒泡排序了捏)然后我们来探讨从小到大的排序(大到小的在后面)这串数列的长度是10(这个比较重要)

2024-11-29 18:25:38 176

空空如也

空空如也

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

TA关注的人

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