0%

go test 工具

go test 命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以 _test.go 为后缀名的源代码文件都是 go test 测试的一部分,不会被 go build 编译到最终的可执行文件中。

*_test.go 文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数:

阅读全文 »

上下文 context.Context 在 Go 语言中被用来设置截止日期、同步信号,传递请求相关值的结构体。上下文与 goroutine 有比较密切的关系,是 Go 语言中的独特设计。

使用场景

如下代码,每次请求,Handler 会创建一个 goroutine 来为其提供服务,而且连续请求3次,request 的地址也是不同的:

func main()  {
    http.HandleFunc("/", SayHello) // 设置访问的路由

    log.Fatalln(http.ListenAndServe(":8080",nil))
}

func SayHello(writer http.ResponseWriter, request *http.Request)  {
    fmt.Println(&request)
    writer.Write([]byte("Hello world"))
}

========================================================
$ curl http://localhost:8080/
0xc00012a030
0xc000010018
0xc000010028
阅读全文 »

数组类型

数组作为一种基本的数据类型,通常会从两个维度描述数组,也就是数组中存储的元素类型和数组最大能存储的元素个数,在 Go 语言中会使用如下所示的方式来表示数组类型:

[10]int
[200]interface{}

Go 语言数组在初始化之后大小就无法改变,存储元素类型相同、但是大小不同的数组类型在 Go 语言看来也是完全不同的,只有两个条件都相同才是同一类型

阅读全文 »

Go 语言抛弃了 C/C++ 中的开发者管理内存的方式:主动申请与主动释放,增加了逃逸分析GC,这样开发者就能从内存管理中释放出来,有更多的精力去关注软件设计,而不是底层的内存问题。这是 Go 语言成为高生产力语言的原因之一。

阅读全文 »

goroutine 调度器的概念

说到“调度”,首先会想到操作系统对进程、线程的调度。操作系统调度器会将系统中的多个线程按照一定算法调度到物理 CPU 上去运行。传统的编程语言比如 C、C++ 等的并发实现实际上就是基于操作系统调度的,即程序负责创建线程,操作系统负责调度。

尽管线程的调度方式相对于进程来说,线程运行所需要资源比较少,在同一进程中进行线程切换效率会高很多,但实际上多线程开发设计会变得更加复杂,要考虑很多同步竞争等问题,如锁、竞争冲突等。

线程是操作系统调度时的最基本单元,而 Linux 在调度器并不区分进程和线程的调度,只是说线程调度因为资源少,所以切换的效率比较高。

阅读全文 »

Protobuf 概述

Protocol Buffer (简称Protobuf) 是Google出品的性能优异、跨语言、跨平台的序列化库。

2001年初,Protobuf 首先在 Google 内部创建, 我们把它称之为 proto1,一直以来在 Google 的内部使用,其中也不断的演化,根据使用者的需求也添加很多新的功能,一些内部库依赖它。几乎每个 Google 的开发者都会使用到它。

Google 开始开源它的内部项目时,因为依赖的关系,所以他们决定首先把 Protobuf 开源出去。 proto1 在演化的过程中有些混乱,所以Protobuf 的开发者重写了 Protobuf 的实现,保留了 proto1 的大部分设计,以及 proto1 的很多的想法。但是开源的 proto2 不依赖任何的 Google 的库,代码也相当的清晰。2008年7月7日,Protobuf 开始公布出来。

Protobuf 公布出来也得到了大家的广泛的关注, 逐步地也得到了大家的认可,很多项目也采用 Protobuf 进行消息的通讯,还有基于 Protobuf 的微服务框架 GRPC。在使用的过程中,大家也提出了很多的意见和建议,Protobuf 也在演化,于 2016 年推出了 Proto3。 Proto3 简化了 proto2 的开发,提高了开发的效能,但是也带来了版本不兼容的问题。

Protocol Buffer 名称来自于初期一个主要的类的名称 ProtocolBuffer

阅读全文 »

倒排索引也是索引的一种。索引,本质上就是为了快速检索我们存储的数据。

每种数据库都有自己要解决的问题(或者说擅长的领域),对应的就有自己的数据结构,而不同的使用场景和数据结构,需要用不同的索引,才能起到最大化加快查询的目的。

对于 MySQL 来说,使用 B+ tree 索引是为了优化已有数据的存储结构,对于不需要快速更新的时候,采用预先排序等方式换取更小的存储空间,更快的检索速度,但同时,由于每次更新都需要对 B+ 树进行调整,导致更新比较慢。Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好。

Elasticsearch 是建立在全文搜索引擎库 Lucene 基础上的搜索引擎,它隐藏了 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API,不过掩盖不了它底层也是 Lucene 的事实。
Elasticsearch 的倒排索引,其实就是 Lucene 的倒排索引。

阅读全文 »

简介

Elasticsearch 是一个分布式文档储存中间件,它不会将信息储存为列数据行,而是储存已序列化为 JSON 文档的复杂数据结构。当在一个集群中有多个节点时,储存的文档分布在整个集群里面,并且立刻可以从任意节点去访问。

ElasticSearch 是一个高可用开源全文检索和分析组件。提供存储服务,搜索服务,大数据准实时分析等。一般用于提供一些提供复杂搜索的应用。

阅读全文 »

常用代码段

new() 和 make() 选择

  • 切片、映射和通道,使用 make

  • 数组、结构体和所有的值类型,使用 new

new 出来的是一个指针

字符串相关操作

修改字符串的一个字符

str:="hello"
c:=[]byte(str)
c[0]='c'
s2:= string(c) // s2 == "cello"
阅读全文 »

基础

按照约定,包名与导入路径的最后一个元素一致。例如,"math/rand" 包中的源码均以 package rand 语句开始。

导出名

在 Go 中,如果一个名字以大写字母开头,那么它就是已导出的。例如,Pizza 就是个已导出名,Pi 也同样,它导出自 math 包。

pizzapi 并未以大写字母开头,所以它们是未导出的。

在导入一个包时,只能引用其中已导出的名字。任何“未导出”的名字在该包外均无法访问。

阅读全文 »