自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

数据小冰的博客

小冰一枚,专注于数据挖掘,玩原汁原昧的工业数据,分享有趣有料的topic

  • 博客(130)
  • 资源 (2)
  • 收藏
  • 关注

原创 Go语言必知必会100问题-24 如何正确的对切片进行拷贝

内置的 copy 函数实现了将源切片中的数据拷贝到目标切片中的功能,尽管这是一个常用的内置函数,但是还是有不少开发者使用有误。总结,将一个切片中的元素拷贝到另一个切片是一种非常频繁的操作,当我们使用copy函数时,需要记得拷贝的元素个数是源切片和目标切片中长度较短的。copy函数将源切片中的数据拷贝到目标切片时,拷贝的元素个数为下面两个长度中较小的一个。在前面的代码中,源切片src的长度为3,但是目标切片dst的长度为0,因此,调用copy函数拷贝的元素个数为0,所以打印输出为空切片。

2024-03-13 22:23:40 365

原创 Go语言必知必会100问题-23 判断空切片最佳方法

在Go语言必知必会100问题-22 空切片与nil切片有区别吗?中分析了空切片和nil切片是有区别的,那如何正确的判断一个切片是否为空切片呢?综上,我们并不是总能够修改调用方逻辑,所以通过判断切片的长度是否为0判别切片中是否存在元素是最佳方法。与此同时,正如Go wiki中陈述的,在我们设计接口的时候,应该避免区分空切片和nil切片,对它们做区分会导致细微的程序错误。在返回切片时,如果返回nil切片或空切片,要确保不会产生语义上和技术上的差异,两者表达的应该是同一个意思。

2024-03-13 22:16:18 329

原创 Go语言必知必会100问题-22 空切片与nil切片有区别吗?

nil切片与nil相等,空切片的长度为0,但是它不等于nil。如果能够确定最后返回的切片为空,则推荐使用 var s []string, 如果在初始化时已知道切片的长度,则采用make([]string,length)最好,[]string(nil)提供了一种语法糖,方便添加元素操作。剩余未讨论的方法2 s:=[]string(nil)和方法3 s:=[]string{}中,方法2使用的最不广泛,只是可以用作语法糖,因为我们可以在一行代码中完成定义一个nil切片并完成元素添加操作,示例程序如下。

2024-03-12 22:09:50 562

原创 Go语言必知必会100问题-21 切片初始化方法及最佳实践

总结,将一种切片类型转换为另一种切片类型是Go中经常遇到的操作。通过前面的分析,如果提前已知道切片的长度是多少,就不要创建一个大小为0的空切片,采用分配给定容量或给定长度对切片进行初始化是最佳选择。具体是采用给定容量还是给定长度,要根据实际情况进行选择,采用给定容量代码的可阅读性更好,采用给定长度程序的性能往往更高。

2024-03-12 22:07:03 875

原创 Go语言必知必会100问题-20 切片操作实战

有很多gopher将切片的length和capacity混淆,没有彻底理清这两者的区别和联系。理清楚切片的长度和容量这两者的关系,有助于我们合理的对切片进行初始化、通过append追加元素以及进行复制等操作。如果没有深入理解它们,缺少高效操作切片的方法,甚至可能导致内存泄露。切片长度是切片中已有元素的数量,而切片容量是切片中可以容纳的元素数量。向切片中添加元素,当长度和容量相等时会导致创建具有新容量的新底层数组,复制所有来自前一个数组的元素,并将切片指针更新为新数组。

2024-03-10 18:17:47 1020

原创 Go语言必知必会100问题-19 浮点数溢出问题

Go语言中float32和float64在计算机中是一种近似值表示,因此,我们必须牢记下面的规则:当比较两个浮点数时,检查它们的差值是否在可接受的范围内,而不是直接 == 进行比较当执行加法或减法时,为了获得更好的精度,可以根据运算级进行分组为了提高准确性,如果一系列运算需要加法、减法、乘法或除法,先执行乘法和除法运算。

2024-03-10 18:09:01 896

原创 Go语言必知必会100问题-18 忽略整数溢出

判断两个整数相乘的结果是否存在溢出有点小复杂,需要检查相乘的整数是否有值为math.MinInt. 如果乘数a或b一个为0,则结果为0.如果a或b有一个为1,则结果为a或b.如果a或b为math.MinInt,则会存在下溢,如果result/b!除了上面的8种类型,还有两种整数类型是:int和uint,这两种类型的大小取决于系统,在32位操作系统上,int/uint类型为32 bits,在64位系统上,int/uint类型为64 bits.但是在运行时,整数上溢和下溢是无感知的,不会导致应用程序崩溃。

2024-03-09 17:29:15 615

原创 Go语言必知必会100问题-17 进制混淆

八进制整数在不同的场景中很有用,例如,假设我们想要使用 os.OpenFile 打开一个文件,该函数需要将权限作为 uint32 类型传递,如果我们想匹配linux文件权限,可以传递一个八进制数字而不是一个十进制数字。为了便于阅读,我们还可以使用下划线字符(_)作为分割符,例如,10亿可以这样表示:1_000_000_000. 此外,还可以将下划线字符与其它表示形式一起使用,像 0b00_00_01 表示的十进制数为1。二进制:使用 0b 或 0B 前缀,例如 0b100等于十进制中的4.

2024-03-09 17:26:09 226

原创 Go语言必知必会100问题-16 不使用 linter

linter和格式化程序是提高代码质量、保持代码风格一致的有力方法,我们应该花点时间了解如何使用它们,并且能够自动执行检查,例如将这些检查集成到CI或git提交钩子中,在提交代码前做风格检查等操作。本文内容不是列举通过linter检查出来的所有问题,而是通过个别例子来理解linter为什么重要,为什么对Go项目开发是必不可少的。由于vet已集成在标准库中,所以只需要安装shadow工具,安装方法如下,然后联合vet工具,对上面的代码进行检查,输出结果如下。正如上面看到的,vet工具提示我们变量i被遮蔽。

2024-03-08 22:25:03 442

原创 Go语言必知必会100问题-15 缺少代码文档

当对变量或常量进行注释说明时,我们可能想传递两方面内容:它的目的和内容. 变量或常量的目的应该作为代码文档存在,以便对外部使用者有所帮助。DefaultPermission 表示默认权限,代码文档注释说明了该变量的目的,而常量旁边的注释描述了它的实际内容(读写权限)。此外,当对一个函数(或方法)注释说明时,应该强调函数打算做什么,而不是它是如何实现的。通常,我们应该将包文档放在与包同名的相关Go文件中,或者放在特定文件中,如doc.go. 关于包文档,最后要说的一点是,与声明不相邻的注释会被省略。

2024-03-03 22:04:08 500

原创 Go语言必知必会100问题-14 忽视包名冲突

虽然上面这种做法非常直接有效,但是,如果出现某种原因我们更喜欢保留名为redis的变量,这时可以在导入包上做点文章,给导入包起一个别名,代码中使用包的别名可以避免冲突,示例程序如下。假设在一个函数中同时使用了变量redis和包名redis,在这种情况下,阅读代码的时候可能混淆不清。上述代码保存在redis库中,现在有一个客户端程序,使用到上面的redis包提供的功能。尽管调用的包名是redis,但在Go语言中创建一个名为redis的变量是完全有效的。当变量名与包名相同时会发生包冲突,会阻止包被重用。

2024-03-03 21:51:12 251

原创 Go语言必知必会100问题-13 创建util包不是一种好的做法

在Go语言中完成该功能的惯用方法是通过 map[K]struct{} 类型来处理,K是map中允许的任何类型作为键,而值是 struct{} 类型, 表示我们对值不关心。上述代码的问题是包名 util 没有任何意义,我们可以称它为 common、shared 或 base, 但它仍是一个毫无意义的名称, 无法提供任何关于包的有意义信息。程序包的命名是应用程序设计的一个关键点,我们应该对此保持谨慎。我们可以对上面的程序做进一步封装,创建一个特定的类型并将Sort作为对外提供的方法,而不是一个对外公开的函数。

2024-03-02 18:47:49 405

原创 Go语言必知必会100问题-12 如何设计项目结构

Go语言维护者对构建Go项目结构没有严格的约定,在github上有一个称为标准Go项目结构的模板(https://github.com/golang-standards/project-layout)),注意该模板不是Go官方提供的。我们还要注意一些特殊情况,例如,当我们对一个结构体对象调用 encoding/json 标准库对其进行序列化或反序列化时,该结构体对象的字段需要是可导出的(即首字母要大写),否则会忽略该字段。为了帮助用户理解Go项目,我们应该根据它提供的内容命名包,而不是它包含的内容。

2024-03-02 10:24:47 775

原创 Go语言必知必会100问题-11 使用选项模式

然后,客户端可以通过下面的代码来实现server的初始化(假设上面的实现放在httplib包中)。首先,客户端创建一个ConfigBuilder对象,用它来设置一个可选字段(像本文的端口)。然后,调用它的Build方法并检查错误信息,如果正确无误,则将配置传给NewServer创建一个server对象。

2024-02-29 22:54:30 847

原创 Go语言必知必会100问题-10 小心类型嵌入导致的问题

因此,使用InMem的调用方也可以看到这两个方法. 这种由于内嵌导致的方法提升可能不是我们希望的,在大多数情况下,互斥锁是我们希望封装在结构体内部并且使外部客户端不可见的内容。总结,对于类型嵌入,我们需要知道它不是必须的,这意味着无论什么时候,我们都可以在不使用类型嵌入的情况下解决问题。但是,如果我们没有真正理解类型嵌入的意义,有时可能会导致意想不到的行为。嵌入可以用来提升嵌入类型的字段和方法,像上面的代码,由于Bar包含一个Baz字段,它被提升到Foo中,就好像Foo中定义了一个Baz字段一样。

2024-02-29 22:31:24 1185

原创 Go语言必知必会100问题-09 不知道在什么时候该使用泛型

切片不能作为map的key, 编译下面的代码将会报编译错误:invalid map key type []byte. 因此,有必要限制类型参数,而不是接受任何类型的参数,以便键类型满足特定要求。在结构体Node中使用参数类型T来约束Node中存在的数据的类型,字段Val中存储值的类型为T,next节点也带有约束T。在编译时,接收器中的参数类型T将被实例化。T是any类型,所以它是通用的,但它也必须遵守定义的类型参数。有了泛型,现在可以使用类型参数重构上述代码,类型参数是可以与函数和类型一起使用的泛型类型。

2024-02-28 20:15:38 733

原创 Go语言必知必会100问题-08 不要过度使用any类型

尽管上述代码可以编译成功,但我们应该花点时间审视一下函数签名,可以发现它接收并返回 any 类型对象, 缺乏表现力,不知道它真正存储的是什么类型的值。将任何类型的值赋值给 any 类型时,会丢失原来的类型信息, 这时需要类型断言才能从变量 i 中获取任何有用的信息。总结,如果确实需要接收或返回任何可能的类型,采用any类型可能会有所帮助。采用any类型,失去了Go作为静态类型语言的一些好处,我们应该避免使用 any 类型,尽可能使函数的签名明确。像下面的代码,any 类型的变量可以保存任何类型的值。

2024-02-28 20:13:47 430

原创 Go语言必知必会100问题-07 尽量不要返回接口

当然,也有一些例外情况。最好的例子证明是错误类型,很多函数都会返回一个接口类型的错误(error). 我们还可以使用io包检查标准库中的另外一个异常,像下面的函数返回一个可导出的结构体:io.LimitedReader,但是函数的签名是一个接口:io.Reader, 这不是不符合我们前面的讨论分析吗,为什么要这样实现呢?因为io.Reader是一个提前确定的抽象,它不是由客户端定义的,而是强制存在的,这其实就是前一篇文章中讲的生产者端接口,语言设计者事先知道这种抽象级别在可重用性和可组合性方面有帮助。

2024-02-27 22:05:08 605

原创 Go语言必知必会100问题-06 生产者端接口

采用在客户端中定义接口的关键点是客户端可以根据需要定义最准确的抽象(像customersGetter只有一个方法),契合接口隔离原则(SOLID中的I),该原则指出不应强迫任何客户端依赖它不使用的方法。可能认为有很好的理由这样做,我们可能会说,1.这样可以将客户端代码与实际实现分离,2. 在测试的时候,调用方很方便Mock一个假的接口实现进行测试。所提到的,与具有显示实现接口的语言相比,Go中通过隐式实现接口,这会带来一些变化,像其它语言惯用的生产者端接口在Go语言中并不是最佳实践。

2024-02-26 22:57:56 949

原创 Go语言必知必会100问题-05 接口污染

对于软件开发人员来说,根据当前情况猜测以后可能有什么需求,来构建完美的抽象,过度设计代码是很常见的,应该避免这样做,因为在大多数情况下,会用不必要的抽象污染当前的代码。这句话想表达的意思是如果没有直接的原因,我们不应该首先在代码中创建抽象,不应该使用接口进行设计,而是等待具体的需求。假设我们需要实现将一个文件内容复制到另一个文件中的函数,我们可以创建一个特定的函数,将两个 *os.File作为输入, 或者可以选择使用io.Reader和io.Writer接口创建一个更通用的函数。答案是它使代码流更加复杂。

2024-02-26 22:52:00 735

原创 Go语言必知必会100问题-04 过度使用getter和setter

总结,如果对结构体添加getter和setter方法不会带来任何好处,就不应该添加这些方法,让代码不堪重负。但是,如果发现需要getter和setter,或者在保证向前兼容的同时预见到未来的需求,这种情况下使用getter和setter没有问题。getter和setter是通过在未导出的对象字段上提供导出方法来进行数据封装的方法,在Java语言中使用的比较多,但在Go语言中,没有自动支持它们,所以使用getter和setter访问struct字段不是强制性的,也不是惯用的做法。

2024-02-25 11:15:47 170

原创 Go语言必知必会100问题-03 滥用init函数

例如,如果待测函数不依赖数据库连接,即可以直接进行测试,但是在执行测试函数之前init函数先被执行,只有init函数成功执行,才能运行我们的单元测试,这使得编写单元测试变得很复杂。例如在下面的示例中,main包对foo包没有很强的依赖关系,不会使用到foo包中定义的函数,但是需要初始foo包,执行foo包中的init函数,这时可以使用_操作符。在init函数中,使用sql.Open打开一个数据库,并将它赋值给了全局变量,以便在init函数执行后,可以直接使用这个全局变量。初始化包时会执行init函数。

2024-02-25 11:13:59 1021

原创 Go语言必知必会100问题-02 减少代码的嵌套层数

软件开发中的“心智模型”用于描述开发人员在编码时心理活动,每段代码其实是人在编写这段代码时的心智模型投射,不能把代码看成是客观的存在,而是主观的产物,参合了当时心理活动或各种直觉感知。在编程时,必须不断维护心智模型,例如关于整体代码交互和功能实现的心智模型,代码是否具有可读性,代码风格,变量命名规范等。由于代码嵌套的数量层级过多。编写可读的代码对每个开发人员来说都是一项重要的挑战,努力减少代码块嵌套的层级数量,将快乐路径对齐放在左侧,并尽早返回是提高代码可读性的具体手段,在工作中,我们应该应用这些手段。

2023-03-19 21:30:54 323

原创 Go语言必知必会100问题-01 小心变量遮蔽

在Go语言中,在代码块中声明的变量可以在内部代码块中重新声明,这种使用方法称为变量遮蔽/隐藏,注意在使用时要非常小心,否则很容易出现常见的错误

2023-02-11 13:18:00 145

原创 Go语言中常见100问题-#48 panic

对于Go语言新手来说,在使用error的时候存在一些疑惑。在Go语言中,error通常作为方法或函数的最后一个返回参数。有人可能想采用Java或Python语言中的panic和recover机制来处理异常。Go中也是有异常捕获recover机制的,现在来我们来看在什么场景下使用panic和recover.panic会终止代码执行逻辑panic语句会终止代码执行...

2022-06-06 08:21:31 774

原创 说说channel哪些事-下篇

在channel-上篇中,小编主要从channel是什么,为什么需要channel,channel基本的使用方法以及channel实现原理这个四个方面介绍了channel.本篇,小编将从实际的应用场景出发,介绍如何运用chnanel解决这些问题。channel解决的主要是并发问题,学习下面的场景,总结提炼用法,可以帮助我们更好的编写并发程序。for+select多路复用模式for+select多路复用模式非常常见,在实际的工作中也使用的非常频繁,其基本代码模式如下:for { select {

2021-06-03 07:51:54 403

原创 说说channel哪些事-上篇

channel是什么channel中文翻译为通道,它是Go语言内置的数据类型,使用channel不需要导入任何包,像int/float一样直接使用。它主要用于goroutine之间的消息传递和事件通知。在Go语言中流传着一句话,就是说不要通过共享内存来通信,而是应该通过通信来共享内存。Don’t communicate by sharing memory, share memory by communicating.上面这句话也包含了通信的两种方式:1是通过共享内存 2是通过通信。channe

2021-05-27 07:47:02 551

原创 深入解析Golang之Context

​context是什么context翻译成中文就是上下文,在软件开发环境中,是指接口之间或函数调用之间,除了传递业务参数之外的额外信息,像在微服务环境中,传递追踪信息traceID, 请求接收和返回时间,以及登录操作用户的身份等等。本文说的context是指golang标准库中的context包。Go标准库中的context包,提供了goroutine之间的传递信息的机制,信号同步,除此之外还有超时(timeout)和取消(cancel)机制。概括起来,Context可以控制子goroutine的运行,

2021-05-22 20:32:48 4515 4

原创 反射

什么是反射反射?光的反射吗?在物理学中有反射这个概念,表示光在分界面上改变传播方向又返回原来物质中的现象。本文讲述的是反射是在计算机领域的概念,在计算机科学中,反射编程(reflective programming)定义如下,这是来做维基百科的描述。In computer science, reflective programming or reflection is the ability of a process to examine, introspect, and modify its own

2021-05-21 22:41:42 392

原创 golang单例模式最佳实践

单例模式单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例。使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管理器只有一个就够了。2 方便配置管理,例如,服务器的配置信息存放在一个文件中,配置信息由一个单例实例统一读取,进场中的其他对象通过这个单例实例获取配置信息。单例模式常见写法分析1. 实例1下面这段代码有什么问题,在学校的时候,我们可能写出...

2019-08-04 18:40:44 763

原创 听公司创新思维公开课记录

这里写自定义目录标题为什么要进行创新?创新思维的方法为什么要进行创新?创新说白了就是想把事情做的更好,除了给人带来一些money增加,职位的提升等。创新思维的方法1 知识碰撞,头脑风暴2. 组合思维3. 逆向思维4. 横向多元思维...

2019-06-25 23:22:48 201

原创 【剑指Offer】从尾到头打印链表

题目:输入一个链表,从尾到头打印链表每个节点的值。vector printListFromTailToHead(struct ListNode* head) { stack s; vector v; while(head){ s.push(head->val); head=head->next;

2016-08-16 19:08:32 435

原创 【剑指Offer】替换空格

题目:请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。void replaceSpace(char *str,int length) { char *ch=(char *)malloc(sizeof(char)*length); strcpy(ch,str);

2016-08-16 18:51:53 466

原创 二维数组中的查找

题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。分析:数组左上角的元素最小,右下角的元素最大,

2016-08-15 20:33:47 620

原创 字符串中字母替换-E

[编程题]旧键盘打字(20)旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键,打出的结果文字会是怎样?输入描述:输入在2行中分别给出坏掉的那些键、以及应该输入的文字。其中对应英文字母的坏键以大写给出;每段文字是不超过10^5个字符的串。可用的字符包括字母[a-z, A-Z]、数字0-9、以及下划线“_”(代表空格)、

2016-08-08 14:07:10 2002

原创 根据ID统计分数求最高分-E

现请你根据比赛结果统计出技术最强的那个学校。输入描述:输入在第1行给出不超过105的正整数N,即参赛人数。随后N行,每行给出一位参赛者的信息和成绩,包括其所代表的学校的编号(从1开始连续编号)、及其比赛成绩(百分制),中间以空格分隔。输出描述:在一行中给出总得分最高的学校的编号、及其总分,中间以空格分隔。题目保证答案唯一,没有并列。输入例子:63

2016-08-08 13:18:05 875

原创 进制转换中1的个数--E

NowCoder总是力争上游,凡事都要拿第一,所以他对“1”这个数情有独钟。爱屋及乌,他也很喜欢包含1的数,例如10、11、12……。不仅如此,他同样喜欢任意进制中包含1的数。当然,其中包含1的个数越多他越喜欢。你能帮他统计一下某个数在特定的进制下1的个数吗?#include int main(){ int N,r; int count; while((scan

2016-08-08 12:03:23 480

原创 进制转换

nowcoder费了很大劲,终于和地外文明联系上。我们地球人通常有10根手指,因此我们习惯用10进制的数,而外星人的手指有16跟、8根等不等的数目,因此他们使用与我们不同的进制。为了方便沟通,需要你开发一款工具,把地球人的10进制转换成外星人的R进制形式。#include #include#include#include#includeusing namespace std;

2016-08-08 11:47:09 354

原创 3n+1猜想

对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证(3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……我们今天的题目不是证明

2016-08-08 11:24:51 962

原创 爬台阶

NowCoder小时候走路喜欢蹦蹦跳跳,他最喜欢在楼梯上跳来跳去。但年幼的他一次只能走上一阶或者一下子蹦上两阶。现在一共有N阶台阶,请你计算一下NowCoder从第0阶到第N阶共有几种走法。#include int main(){ long long arr[91]; int i; arr[1]=1; arr[2]=2; for(i=3;

2016-08-08 11:22:49 624

径向基网络

使用径向基网络对蝴蝶花分类学习很好的实例

2015-08-16

Django book2中文版

入门django基础的学习资料,给予1.3版

2015-05-09

空空如也

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

TA关注的人

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