自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 如何在数据库中存储小数:FLOAT、DECIMAL还是BIGINT?

在小数类型存储上,MySQL提供了多种类型的选择,如FLOATDOUBLEDECIMALBIGINT类型,都可以对小数进行存储。不过往往在某个场景下,只有一个类型才最满足要求。本文详细介绍了各种数据类型,同时在数据精度,存储效率,执行效率,代码复杂性等维度上对其进行了比较,展示了其长处和相对应的缺点。从而能够在数据库设计时,作出更准确,更高效的选择。

2024-03-13 20:36:58 1644

原创 存储日期,该如何抉择呢

本文详细介绍了各种时间类型,同时在时间精度,存储范围,执行效率等维度上对其进行了比较,展示了其长处和相对应的缺点。从而能够在数据库设计时,在时间字段的类型作出更准确,更高效的选择。

2024-03-09 17:10:23 814

原创 设计表时,如何选择正确的数据类型

MySQL 支持的数据类型非常多,在合适的场景下,选择正确的数据类型对于获得高性能至关重要。本文讲述了几个简单的原则,从而作出更好的设计

2024-03-03 16:58:24 817

原创 每日一题-轮转数组

上面描述了轮转数组这道题的三种解法,包括使用额外数组,反转数组,环形替换这三种方法,同时也展示了各个解法过程中数据的流转的顺序,希望对于理解该题能够起到积极的作用。代码已经上传到github上,有兴趣可以看看。

2023-09-17 17:51:50 222

原创 Go语言支持闭包吗?说说你对它的理解

闭包是一个函数值,它引用了在其外部定义的一个或多个变量。这些变量被称为自由变量,它们在闭包内部被绑定到函数值,因此闭包可以访问和操作这些变量,即使在它们的外部函数已经执行完毕。闭包的关键特点是它可以捕获并保持对外部变量的引用,这使得函数值具有状态和行为,可以在多次调用之间保留状态。因此,闭包允许函数不仅仅是独立的代码块,还可以携带数据和状态。count := 0 // count 是一个自由变量,被闭包捕获并绑定// 返回一个闭包函数,它引用并操作 countcount++

2023-09-16 17:04:37 400

原创 一文简单了解函数类型

在Go其中,是函数的参数列表,returnType是函数的返回值类型。我们可以直接使用这种函数类型,声明变量、作为参数传递给其他函数,或作为函数的返回值返回。本文简单介绍了函数在Go语言中是一等公民,基于此,Go语言中的函数拥有了更多的能力,不再需要依附在类上。相对于其他函数非一等公民的语言,在Go语言中,函数可以直接赋值给变量,作为其他函数的返回值,也可以作为参数传递进去等,总体来说更加灵活。同时我们也介绍了常情况下,我们会给函数类型起一个别名,从而增加代码的可读性和可维护性。

2023-09-10 10:09:14 199

原创 接口使用的最佳时机

接口是一种工具,在识别出系统中变化部分时,帮助从系统模块中抽取出变化的部分,从而保证系统的稳定性,可维护性和可扩展性。接口充当了一种契约或规范,规定了类或模块应该提供的方法和行为,而不关心具体的实现细节。接口通常用于面向对象编程语言中,如Java和Go等。在这些语言中,类可以实现一个或多个接口,并提供接口定义的方法的具体实现。通过使用接口,我们可以编写更灵活、可维护和可扩展的代码,同时将系统中的变化隔离开来。接口的实现在不同的编程语言中可能会有所不同。以下简单展示接口在Java和Go语言中的示例。在。

2023-09-09 08:59:39 270

原创 一文了解Validator库

本文介绍了 Go 语言中的库,该库用于对结构体字段进行验证。文章从一个简单的问题出发,引入了Validator库的使用。之后介绍了Validator库的基本使用,包括如何创建验证实例、执行验证以及处理验证错误。通过示例代码,演示了如何使用标签来设置验证规则,以及如何通过Validator库简化数据验证过程,提高代码的可读性和可维护性。总的来说,在比较复杂的场景,通过使用Validator库,我们可以专注于验证逻辑的编写,而不必担心数据结构的解析和重复的验证代码,能够很好得提高代码的可读性和可维护性。

2023-09-01 20:08:28 153

原创 一文了解Gin对Cookie的支持z

在本文中,我们深入探讨了Web应用程序在处理用户信息时所面临的挑战,特别是在HTTP协议作为无状态协议的背景下。我们从这一矛盾出发,介绍了解决方案中的Token机制,并引出了基于Cookie的实现方案。我们详细阐述了Cookie的规范,包括服务端如何发送Cookie以及客户端如何在请求中携带Cookie信息。我们进一步深入探讨了具体的实现方式,并介绍了Gin框架提供的API,这些API使得在服务端按照Cookie规范发送和解析Cookie变得更加容易。

2023-08-23 06:56:29 525

原创 有了net/http, 为什么还要有gin

在Go语言中,net/http包提供了一个强大且灵活的标准HTTP库,可以用来构建Web应用程序和处理HTTP请求。这个包是Go语言标准库的一部分,因此所有的Go程序都可以直接使用它。既然已经有net/http这样强大和灵活的标准库,为什么还出现了像Gin这样的,方便我们构建Web应用程序的第三方库?其实在于net/http的定位,其提供了基本的HTTP功能,但它的设计目标是简单和通用性,而不是提供高级特性和便利的开发体验。在处理HTTP请求和构建Web应用时,可能会遇到一系列的问题,这也造就了Gin。

2023-08-07 08:06:35 140

原创 一文了解io.ReadAtLeast函数

函数用于从读取器(io.Reader)读取至少指定数量的字节数据到缓冲区中。其中r是数据源,从它读取数据,而buf是用于接收读取到的数据的字节切片,min是要读取的最小字节数。函数会尝试从读取器中最少读取min个字节的数据,并将其存储在buf中。函数是Go语言标准库提供的一个工具函数,能够从数据源读取至少指定数量的字节数据到缓冲区中。我们先从函数的基本定义出发,之后通过一个简单的示例,展示如何使用函数实现至少读取指定字节数据。接着我们讲述了。

2023-07-14 07:03:33 90

原创 一文了解io包中的discard类型

io.discard是 Go语言提供的一个Writer,这个Writer比较特殊,其不会做任何事情。它会将写入的数据立即丢弃,不会做任何处理。discard结构体类型没有定义任何字段,同时还提供了WriteReadFrom和方法,Write方法和方法分别接收字节切片和字符串,然后返回写入的字节数。同时还实现了接口,这个是为了在使用io.Copy函数时,将数据从源复制到io.discard时,避免不必要的操作。从上面discard。

2023-07-13 06:37:11 261

原创 一文了解 io.LimitedReader类型

是Go语言提供的一个Reader类型,其包装了了一个io.Reader接口,提供了一种有限的读取功能。结构体中包含了两个字段,其中R为底层Reader, 数据都是从Reader当中读取的,而N则代表了剩余最多可以读取的字节数。同时也提供了一个Read方法,通过该方法来实现对数据进行读取,在读取过程中N的值会不断减小。通过使用, 我们可以控制从底层读取器读取的字节数,避免读取到不应该读取的数据,这个在某些场景下非常有用。同时Go语言还提供了一个函数,能够使用该函数,创建出一个我们可以通过该函数创建出一个。

2023-07-12 08:05:38 80

原创 为什么使用ioutil.ReadAll 函数需要注意

本文首先对进行了基本的说明,同时给了一个简单的使用示例。随后,通过基准测试展示了使用加载数据,消耗的内存可能远远大于待加载的数据。之后,通过对源码讲解,说明了导致这个现象导致的原因。最后,给出了一些替代方案,如使用函数和使用io.Copy函数等,以减少内存占用。基于以上内容,便完成了对函数的介绍,希望对你有所帮助。

2023-07-11 07:39:03 196

原创 一文了解 io.Copy 函数

Copy函数用于将数据从源(io.Reader)复制到目标(io.Writer它会持续复制直到源中的数据全部读取完毕或发生错误,并返回复制的字节数和可能的错误。其中dst为目标写入器,用于接收源数据;src则是源读取器,用于提供数据。io.Copy函数是Go语言标准库提供的一个工具函数,能够将数据从源Reader复制到目标Writer。我们先从io.Copy函数的基本定义出发,之后通过一个简单的示例,展示如何使用io.Copy函数实现数据拷贝。接着我们讲述了io.Copy。

2023-07-10 07:12:11 635

原创 提升性能的利器:深入解析SectionReader

本文将介绍 Go 语言中的,包括的基本使用方法、实现原理、使用注意事项。从而能够在合适的场景下,更好得使用类型,提升程序的性能。r ReaderAtbase int64off int64r:一个实现了ReaderAt接口的对象,它是数据源。base: 数据源的起始位置,通过设置base字段,可以调整数据源的起始位置。off:读取的起始位置,表示从数据源的哪个偏移量开始读取数据,初始化时一般与base保持一致。limit:数据读取的结束位置,表示读取到哪里结束。

2023-07-02 20:30:23 178 1

原创 一文了解Go语言的I/O接口设计

Go语言定义了三个基本的 I/O 接口,其中io.Reader定义了读取数据的标准,io.Writer定义了写入数据的标准,io.Closer定义了关闭资源的标准。通过统一的接口规范,能够将不同的资源(网络链接,文件)都当成统一的实体,能够以一种统一的方式来进行 I/O 操作。其次,I/O接口的设计,也遵循了最小接口原则,每个接口只包含特定的方法,能够更好得支持接口组合,在不同的需求场景下,对 I/O 接口进行组合,在满足需求的同时也不会引入额外不必要的接口。

2023-06-28 08:28:34 257

原创 一文了解函数设计的最佳实践

在这篇文章中,我们总结了几个函数设计的最佳实践,如遵循单一职责原则,控制函数参数数量,函数命名要清晰准确等,通过遵循这些原则,能够让我们设计出来高质量、可读性强的代码,同时也具有更强的可维护性。但是也需要注意的是,函数一开始设计时总是相对比较完美的,只是在不断迭代中,不断堆积代码,最终代码冗长,复杂,各种逻辑穿插其中,使得维护起来越发困难。因此,我们更多的应该是在迭代过程中,多考虑函数设计是否违反了我们这里提出的原则,能在一开始就识别到代码的坏味道,从而避免最终演变成难以维护和迭代的函数。

2023-06-23 07:13:41 196

原创 一文了解Go语言的匿名函数

匿名函数是一种没有函数名的函数。它是在代码中直接定义的函数,没有被分配一个显式的标识符或名称。匿名函数通常用于需要临时定义、简短使用或在其他函数内部使用的情况。Go语言对匿名函数是支持的,其定义方式非常简单,func// 在这个例子中,我们在main函数内部定义了一个匿名函数,并将其赋值给了变量greet")// 调用匿名函数greet()在这个示例中,我们在main函数内部定义了一个匿名函数,并将其赋值给了变量greet。匿名函数体内的代码打印了"Hello, World!通过调用。

2023-06-22 06:32:58 1576

原创 一文了解Go语言的函数

/ 函数体// 可以包含一系列的语句和操作return value // 返回值(如果有)func: 关键字用于定义函数。: 函数名,用于唯一标识该函数。: 参数列表,函数可以接收零个或多个参数。每个参数由参数名和参数类型组成,多个参数之间使用逗号分隔。: 参数的类型,指定参数的数据类型。returnType: 返回类型,指定函数的返回值的数据类型。如果函数没有返回值,则返回类型为空。: 可选项,用于返回函数的结果。如果函数定义了返回类型,则需要使用return语句将结果返回给调用者。

2023-06-22 06:28:25 911

原创 Go语言中的原子操作

Go语言中的原子操作是一种在并发编程中用于对共享数据进行原子性访问和修改的机制。原子操作可以确保对共享数据的操作在不被中断的情况下完成,要么完全执行成功,要么完全不执行,避免了竞态条件和数据竞争问题。Go语言提供了包来支持原子操作。该包中定义了一系列函数和类型,用于操作不同类型的数据。原子性:原子操作是不可分割的,要么全部执行成功,要么全部不执行。这意味着在并发环境中,一个原子操作的执行不会被其他线程或协程的干扰或中断。

2023-06-20 08:41:22 688

原创 深入理解Go语言接口

本文介绍了Go语言中的接口概念、定义和实现方法。我们讨论了接口的特性,包括隐式实现、接口组合和空接口的使用。接着,我们探讨了定义接口的最佳实践,包括定义小接口、使用有意义的命名以及避免不必要的抽象。通过遵循这些最佳实践,我们可以设计出高质量、灵活和易于扩展的接口,提高代码的可读性、可维护性和可重用性。基于对以上内容的接口,我们完成了对接口的介绍,希望对你有所帮助。

2023-06-19 08:27:56 1415

原创 Go语言中的结构体:灵活性与可扩展性的重要角色

在Go语言中,结构体是一种自定义的数据类型,用于将不同类型的字段组合在一起形成一个新的数据结构。结构体定义了一组字段,每个字段可以有不同的类型,这些字段一起构成了结构体的实例。通过结构体,我们可以将相关的数据进行组织和管理,从而更方便地进行操作和传递。结构体的定义使用关键字type和struct。type 结构体名称 struct {字段1 类型1字段2 类型2// 更多字段...在上述语法中,结构体名称是我们为结构体类型起的名称,可以根据实际情况进行命名。

2023-06-14 21:39:03 886

原创 深入探究for...range语句

在Go语言中,语句为遍历数组、切片、映射和通道等数据结构提供了一种便捷的方式。它隐藏了底层的索引或迭代器等细节,是Go语言为遍历各种数据结构提供的一种优雅而简洁的语法糖,使得遍历操作更加方便和直观。下面仔细简介使用完成对切片, map, channel的遍历操作。本文对Go语言中的进行了基本介绍,首先从一个简单遍历问题出发,发现基本的for语句似乎无法简单实现对stringmap等类型的遍历操作,从而引出了语句。接着我们仔细介绍了,如何使用对stringmapchannel等类型的遍历操作。

2023-06-13 08:50:07 279

原创 Go语言中的init函数: 特点、用途和注意事项

本文介绍了Go语言中的init()函数的特点,用途和注意事项。在文章中,我们首先讲述了init()函数的特点,包含init函数的自动执行,以及其执行时机的内容,接着详细讲解了init()函数的几个常见用途,包括初始化全局变量以及执行一些必要的校验操作。接着我们提到了init()函数的一些注意事项,如init函数不能被显式调用等。基于以上内容,完成了对init()函数的介绍,希望能帮助你更好地理解和使用这个重要的Go语言特性。

2023-06-11 17:03:19 1816

原创 切片有哪些注意事项是一定要知道的呢

本文深入探讨了Go语言切片的一些注意事项,旨在帮助读者更好地使用切片。首先,切片是对底层数组的引用。修改切片的元素会直接影响到底层数组以及其他引用该数组的切片。如果需要避免修改一个切片影响其他切片或底层数组,可以使用copy函数创建一个独立的底层数组。其次,切片的自动扩容可能带来性能问题。当切片的长度超过容量时,Go语言会自动扩容切片,需要重新分配底层数组并复制数据。为了避免频繁的扩容操作,可以在创建切片时预估所需的容量,并提前指定切片的容量。

2023-06-10 19:26:57 341

原创 切片比数组好用在哪

数组是一种固定长度、具有相同类型的元素序列。在Go语言中,数组的长度在创建时确定,并且无法动态增长或缩小。数组的声明方式为,其中name是数组的标识符,size是数组的长度,Type// 声明一个整数数组// 初始化数组元素// 访问数组元素fmt.Println("数组中的元素:", numbers[0], numbers[1])在上面的例子中,我们定义了一个长度为2的整数数组,分别对其对其赋值和访问。本文介绍了Go语言中数组和切片的基本概念,并详细探讨了切片相对于数组的优势。

2023-06-09 21:09:42 836

原创 上游服务不可用了,下游服务如何应对?

本文主要介绍了上游服务不可用时,下游服务的应对措施。主要分为短暂不可用和长时间不可用两种情况。短暂不可用通常由网络波动或其他暂时性问题导致。在这种情况下,可以采用重试机制来成功请求上游服务,确保资源的可用性。重试机制是一种简单而有效的方法,通过多次重试请求,以应对短暂的不可用情况,避免下游服务受到影响。长时间不可用可能导致严重的问题,如上游服务崩溃或级联故障。为了应对这种情况,可以引入熔断器保护机制来确保下游服务的稳定性。熔断器能够快速切断对不可用的上游服务的请求,避免系统资源被全部占用。

2023-06-06 08:30:46 777

原创 包含引用类型字段的自定义结构体,能作为map的key吗

综上所述,基于简单性、性能和语义一致性的考虑以及键的不可变性,Go语言选择使用==操作符进行键的比较,而将哈希函数作为运行时库的默认实现,更加符合go语言设计的哲学。在 Go 语言中,map 是一种无序的键值对集合,它提供了高效的数据存储和检索机制。在使用 map 时,通常使用基本数据类型作为键。然而,当我们想要使用自定义结构体作为键时,需要考虑结构体中是否包含引用类型的字段。自定义结构体作为map的键需要满足一些要求。首先,键的类型必须是可比较的,也就是支持通过==运算符进行相等性比较。在Go。

2023-06-04 14:33:36 426

原创 Go语言如何判断两个对象是否相等

=对于自定义Equals方法,可以在自定义结构体上定义一个Equals方法,该方法接受另一个相同类型的对象作为参数,并根据自己的逻辑来比较对象的字段是否相等。这种方法需要手动比较每个字段,并考虑如何处理引用类型的字段。函数是Go语言标准库中提供的一个函数,可以递归比较两个对象是否相等。它会比较对象的类型和值,并在需要时递归比较对象的字段。需要注意的是,函数的使用需要引入reflect包,并且在比较对象时会进行深度遍历,因此在性能上可能会有一定的开销。

2023-06-03 15:11:38 1188

原创 如何使用Go中的Weighted实现资源管理

本文将介绍 Go 语言中的Weighted并发原语,包括Weighted的基本使用方法、实现原理、使用注意事项等内容。能够更好地理解和应用Weighted来实现资源的管理,从而提高程序的稳定性。Weighted是 Go 语言中包中的一种类型,用于限制并发访问某个资源的数量。它提供了一种机制,允许调用者以不同的权重请求访问资源,并在资源可用时进行授予。Weighted的定义如下,提供了AcquireTryAcquireReleasesize int64cur int64Acquire: 以权重n。

2023-05-31 21:08:56 684 2

原创 go语言中如何实现同步操作呢

sync.Cond和通道。通过比较它们的适用场景,读者可以更好地了解何时选择使用不同的同步方式。本文旨在帮助读者理解同步操作的重要性以及选择合适的同步机制来确保多个协程之间的正确协调和数据共享的一致性。同步操作在并发编程中起着关键的作用,用于确保协程之间的正确协调和共享数据的一致性。在选择同步操作的实现方式时,我们有两个常见选项:使用sync.Cond和通道。使用sync.Cond和通道的方式提供了更高级、更灵活的同步机制。sync.Cond允许协程等待特定条件的出现,通过WaitSignal和。

2023-05-27 16:57:12 1803 1

原创 go语言中实现生产者-消费者模式有哪些方法呢

本文将介绍在 Go 语言中实现生产者消费者模式的多种方法,并重点探讨了通道、条件变量的适用场景和优缺点。我们将深入讨论这些方法的特点,以帮助开发者根据应用程序需求选择最适合的方式。通过灵活运用 Go 语言提供的并发原语,我们能够实现高效、可靠的生产者消费者模式,提升系统的并发性能和可维护性。生产者消费者模式是一种常见的并发编程模式,用于解决生产者和消费者之间的数据传递和处理问题。在该模式中,生产者负责生成数据(生产),而消费者负责处理数据(消费)。

2023-05-22 08:17:13 865

原创 协程并发下数据汇总:除了互斥锁,还有其他方式吗?

本文介绍了在并发编程中数据汇总的问题,并探讨了在并发环境下使用互斥锁和通道两种方式来保证数据安全性的方法。首先,通过一个实例,描述了一个并发拉取数据并汇总的案例,并使用互斥锁来确保线程安全。然后,讨论了互斥锁的一些缺点,引出了通道作为一种替代方案,并介绍了通道的基本使用和特性。接下来,通过实例演示了如何使用通道来实现并发下的数据汇总。最后,引用了etcd中使用通道实现协程并发下数据汇总的例子,展示了通道在实际项目中的应用。channel在Go语言中是一种特殊的数据结构,用于协程之间的通信和同步。

2023-05-21 10:08:39 543

原创 defer有什么用呢

本文将从一个资源回收问题引入,引出defer关键字,并对其进行基本介绍。接着,将详细介绍在资源回收、拦截和处理panic等相关场景下defer的使用。进一步,介绍defer的执行顺序,以及在注册defer函数时,其参数的求值时机等相关特性。最后,重点讲解defer的注意点,如在defer中函数中需要尽量避免引起panic,以及尽量避免在defer中使用闭包。通过本文的阅读,读者将对Go语言中的defer有更深入的了解,并且能够更加有效地使用这个关键字。在Go语言中,我们可以在函数体中使用defer。

2023-05-14 18:54:22 404

原创 如何优雅得关闭协程呢

本文将介绍首先为什么需要主动关闭goroutine,并介绍如何在Go语言中关闭goroutine的常见套路,包括传递终止信号和协程内部捕捉终止信号。之后,文章列举了需要主动关闭协程运行的常见场景,如启动一个协程执行一个不断重复的任务。希望通过本文的介绍,读者能够掌握如何在适当的时候关闭goroutine,以及了解关闭goroutine的常见套路。这篇文章主要介绍了为什么需要主动关闭goroutine,以及在Go语言中关闭goroutine的常见套路。文章首先介绍了为什么需要主动关闭goroutine。

2023-05-14 11:14:44 638

原创 为什么需要超时控制

本文将介绍为什么需要超时控制,然后详细介绍Go语言中实现超时控制的方法。其中,我们将讨论time包和context包实现超时控制的具体方式,并说明两者的适用场景,以便在程序中以更合适的方式来实现超时控制,提高程序的稳定性和可靠性。Context和Time都是 Go 语言中实现超时控制的方法,它们各有优缺点,不能说哪一种实现更好,要根据具体的场景来选择使用哪种方法。在一些简单的场景下,使用Time包实现超时控制可能更加方便,因为它的 API 更加简单,只需要使用函数即可实现超时控制。

2023-05-07 15:42:12 504

原创 为什么Sync.Pool不需要加锁却能保证线程安全

我们在Sync.Pool: 提高go语言程序性能的关键一步一文中,已经了解了使用sync.Pool来实现对象的复用以减少对象的频繁创建和销毁,以及使用sync.Pool的一些常见注意事项。在这篇文章中,我们将剖析sync.Pool内部实现中,介绍了sync.Pool比较巧妙的内部设计思路以及其实现方式。在这个过程中,也间接介绍了为何不加锁也能够实现线程安全。

2023-04-22 15:38:56 615

原创 为什么要code review

本文将介绍 Code Review的相关内容,包含为什么要Code Review,以及Code Review主要review哪些部分的内容,之后讲述如何才能形成一套比较好的Code Review规则和流程。后续讲述了Code review中一些可以遵守的比较好的规则,最后讲述了如何才能让Code review流程跑起来。!!该文档是一篇关于Code Review的输出,介绍了Code Review的规则和流程需要包含的内容,以及具体需要Review的内容。

2023-04-15 17:54:21 514

原创 sync.Pool:提高Go语言程序性能的关键一步

本文将介绍 Go 语言中的sync.Pool并发原语,包括sync.Pool的基本使用方法、使用注意事项等的内容。能够更好得使用sync.Pool来减少对象的重复创建,最大限度实现对象的重复使用,减少程序GC的压力,以及提升程序的性能。sync.Pool的定义如下: 提供了GetPutGet方法: 从sync.Pool中取出缓存对象Put方法: 将缓存对象放入到sync.Pool当中New函数: 在创建sync.Pool时,需要传入一个New函数,当Get方法获取不到对象时,此时将会调用New。

2023-04-07 21:28:47 384 1

空空如也

空空如也

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

TA关注的人

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