Go语言中文网 为您找到相关结果 543

Go语言atomic原子操作

atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的。 下面内容摘秒自《GO并发编程实战》—— 原子操作: CAS操作的优势是,可以在不形成临界区和创建互斥量的情况下完成并发安全的值替换操作。 这可以大大的减少同步对程序性能的损耗。 当然,CAS操作也有劣势。在被操作值被频繁变更的情况下,CAS操作并不那么容易成功。 原子操作共有5种,即:增或减、比较并交换、载入、存储和交换 1. 增或减 被用于进行增或减的原子操作(以下简称原子增/减操作)的函数名称都以“Add”为前缀,并后跟针对的具体类型的名称。 不过,由于atomic.AddUint32函数和atomic.AddUint64函数的第二个参数的类型分别是uint32和uint64,所以我们无法通过传递一个负的数值来...阅读全文

博文 2015-06-17 20:12:43 xcltapestry

【GoLang笔记】遍历map时的key随机化问题及解决方法

之前的一篇笔记曾分析过,Go的map在底层是用hashmap实现的。由于高效的hash函数肯定不是对key做顺序散列的,所以,与其它语言实现的hashmap类似,在使用Go语言map过程中,key-value的插入顺序与遍历map时key的访问顺序是不相同的。熟悉hashmap的同学对这个情况应该非常清楚。 所以,本文要提到的肯定不是这个,而是一个比较让人惊奇的情况,下面开始说明。 1. 通过range遍历map时,key的顺序被随机化 在golang 1.4版本中,借助关键字range对Go语言的map做遍历访问时,前后两轮遍历访问到的key的顺序居然是被随机化的! 这个现象在其它语言中是很少见的,比如C语言实现hashmap时,通常会用数组(即一段连续的内存空间)来存key,虽然key的...阅读全文

博文 2015-04-02 19:00:01 slvher

golang 内置函数new() 和struct{} 初始化的区别

new() 这是一个用来分配内存的内置函数,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配的 t 类型的零值的指针。 在golang的代码定义如下: func new(t Type) *Type strut{} 直接使用struct{} 来初始化strut时,返回的是一个struct类型的值,而不是指针两者是不一样的 两者对比代码如下: type Student struct{ id int name string } func main(){ var s_1 *Student = new(Student) s_1.id = 100 s_1.name = "cat" var s_2 Student = Student{id:1,name:"tom"} fmt.Println...阅读全文

博文 2015-06-17 20:03:41 happinessaflower

Golang通过syscall调用windows dll方法

本用例在GO 1.4.2 上编译执行通过,直接上CODE: package main import ( "fmt" "syscall" "time" "unsafe" ) const ( MB_OK = 0x00000000 MB_OKCANCEL = 0x00000001 MB_ABORTRETRYIGNORE = 0x00000002 MB_YESNOCANCEL = 0x00000003 MB_YESNO = 0x00000004 MB_RETRYCANCEL = 0x00000005 MB_CANCELTRYCONTINUE = 0x00000006 MB_ICONHAND = 0x00000010 MB_ICONQUESTION = 0x00000020 MB_ICONEXCLAM...阅读全文

博文 2015-03-29 12:00:01 hotkit

go语言常用函数:make

创建数组切片 Go语言提供的内置函数make()可以用于灵活地创建数组切片。创建一个初始元素个数为5的数组切片,元素初始值为0: mySlice1 := make([]int, 5) 创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间: mySlice2 := make([]int, 5, 10) 创建一个map myMap = make(map[string] PersonInfo) 创建了一个键类型为string、值类型为PersonInfo的map.//from:http://www.cnblogs.com/osfipin/ myMap = make(map[string] PersonInfo, 100) 也可以选择是否在创建时指定该map的初始存储能力,...阅读全文

博文 2015-07-28 03:00:00 osfipin

golang对共享内存的操作

不同进程间的内存是互相独立的,没办法直接互相操作对方内的数据,而共享内存则是靠操作系统提供的内存映射机制,让不同进程的一块地址空间映射到同一个虚拟内存区域上,使不同的进程可以操作到一块共用的内存块。共享内存是效率最高的进程间通讯机制,因为数据不需要在内核和程序之间复制。 共享内存用到的是系统提供的mmap函数,它可以将一个文件映射到虚拟内存的一个区域中,程序使用指针引用这个区域,对这个内存区域的操作会被回写到文件上,其函数原型如下: void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); 参数fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,此时须指定f...阅读全文

博文 2014-10-04 19:27:13 壬癸甲乙

golang数据类型-slice(切片)

slice介绍 数组的长度在定义之后无法再次修改;数组是值类型,每次传递都将产生一份副本。显然这种数据结构无法完全满足开发者的真实需求。在初始定义数组时,我们并不知道需要多大的数组,因此我们就需要“动态数组”。在Go里面这种数据结构叫slice,slice并不是真正意义上的动态数组,而是一个引用类型。slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度,它是可变长的,可以随时往slice里面加数据。 初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针。数组切片的数据结构可以抽象为以下3个变量: 1.一个指向原生数组的指针(point):指向数组中slice指定的开始位置; 2.数组切片中的元素个数(len):即sli...阅读全文

博文 2015-06-17 20:17:41 JesseYoung

Go语言slice的那些坑

Go语言Google开发的适用于多核编程的语言。我感觉它像是C语言的现代版本,简单,并发支持友好,部署轻松。GO语言中保留关键字就只有25个,这也足以说明它的学习成本并不高。 然而,Go语言里面slice这个东西并不简单。初学者容易掉入坑中。此文件就试图把slice给讲解清楚。 下面先讲一下slice的一些基本特性。 1. slice内部有三个变量,分别是:ptr, len, cap ptr是用来存储数据的数组 cap是ptr数组的长度 len是实际数组的长度 2. 如何在初始化的时候,指定slice的长度? a := make([]int, 10) 这里make的时候,第2个参数,就是这个slice的长度。 这个时候它的capacity是多少呢? fmt.Println(cap(a)) 这...阅读全文

博文 2016-03-31 19:00:05 zhanchenxing

golang mysql中timestamp,datetime,int类型的区别与优劣

golang time: https://golang.org/pkg/time/ golang中time包用法 http://blog.csdn.net/chenbaoke/article/details/41519193 首先 DATETIM和TIMESTAMP类型所占的存储空间不同,前者8个字节,后者4个字节,这样造成的后果是两者能表示的时间范围不同。前者范围为1000-01-01 00:00:00 ~ 9999-12-31 23:59:59,后者范围为1970-01-01 08:00:01到2038-01-19 11:14:07。所以可以看到TIMESTAMP支持的范围比DATATIME要小,容易出现超出的情况. 其次,TIMESTAMP类型在默认情况下,insert、update ...阅读全文

博文 2016-03-04 08:00:01 scut1135

如何优雅地等待所有的goroutine退出

Table of Contents 1. 通过Channel传递退出信号 2. 使用waitgroup goroutine和channel是Go语言非常棒的特色,它们提供了一种非常轻便易用的并发能力。但是当您的应用进程中有很多goroutine的时候,如何在主流程中等待所有的goroutine 退出呢? 1 通过Channel传递退出信号 Go的一大设计哲学就是:通过Channel共享数据,而不是通过共享内存共享数据。主流程可以通过channel向任何goroutine发送停止信号,就像下面这样: func run(done chan int) { for { select { case <-done: fmt.Println("exiting...") done <- 1 break de...阅读全文

golang make()内置函数

内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型 make()函数在golang的代码如下: func make(t Type,size IntegerType) Type 使用make来创建slice,map,chanel说明如下: slice: var slice_ []int = make([]int,5,10) fmt.Println(slice_) var slice_1 []int = make([]int,5) fmt.Println(slice_1) var s...阅读全文

博文 2015-06-17 20:03:47 happinessaflower

用go语言通过FTP库实现web日库自动上传归档

因为平时管理的web服务器都是VM服务器,为节省硬盘空间,一般给虚拟机分配的硬盘空间都比较小,只有8G,因为,保存不了多少日志,所以每天都需要把每台WEB日志转移到一个硬盘比较大的服务器上,然后再使用NBU集中备份,本程序主要使用go语言实现实现将web日志通过FTP自动上传FTP服务器,使用了filepath.Walk遍历日志目录及第三方纯go库“github.com/jlaffaye/ftp”,而日志VM本地存储路径格式是 /var/log/weblog/www.domainName.com/month/20140616.access.log, ftp库下载地址 http://godoc.org/github.com/jlaffaye/ftp#ServerConn.Stor // upl...阅读全文

博文 2014-10-27 10:00:01 学思

一、Go语言的变量和常量

《Go Web 编程》《Go 语言编程》读书笔记 。 1.变量 变量是几乎所有编程语言中最基本的组成元素。从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间。 1.1 变量声明 对于纯粹的变量声明,Go语言引入关键字var,而类型信息放在变量名之后,形如: var variableName type var vname1, vname2, vname3 type 示例: var v1 int var v2 string var v3 [10]int // 数组 var v4 []int // 数组切片 var v5 struct { f int } var v6 *int // 指针 var v7 map...阅读全文

博文 2015-11-10 10:00:01 chyljy

golang学习之struct

结构体定义的一般方式如下: type identifier struct { field1 type1 field2 type2 ... } type T struct {a, b int} 也是合法的语法,它更适用于简单的结构体。 var t *T t = new(T) 变量 t 是一个指向 T的指针,此时结构体字段的值是它们所属类型的零值,使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针。 无论变量是一个结构体类型还是一个结构体类型指针,都使用同样的 选择器符(selector-notation) 来引用结构体的字段,即: type myStruct struct { i int } var v myStruct // v是结构体类型变量 var p *mySt...阅读全文

博文 2016-06-15 09:00:00 caiya928

为什么我要选择erlang+go进行服务器架构

服务器非业余研究http://blog.csdn.net/erlib 作者Sunface 估计很多同学看到这里都会觉得迷惑,go的大名已经如雷贯耳了,但是erlang?这个东东是神马?难道是编程语言?怎么从来没听说过。 这里请允许我先介绍一下使用Erlang开发的比较有名的应用: 一:whatsapp 只凭32个技术人员,如何应付4.5亿的用户?对于刚刚被Facebook用190亿美元收购的WhatsApp来说,答案是Erlang——一种诞生于上世纪80年代的编程语言,终于在此时走到了聚光灯下。 这个应用把erlang的特性发挥到了极致,利用到了它最好的vm、 集群基础设施、数据库mnesia, 消除了非常多的数据Scale、内存池和锁的问题, 提到的技术和修正点非常值得我们参考。 虽然大部...阅读全文

博文 2015-02-23 23:00:00 robslove

go内存管理和垃圾收集简介

go语言的内存分两部分,一部分用作堆,供内存分配用,另一部分是bitmap,用来管理堆。两部分从同一地址开始,向高地址方向增长的是内存池,向低地址方向增长的是bitmap。 ##内存分配## 对于较大的内存申请,直接从堆上申请,释放时也直接返回给堆。 而当一个go routine申请小于32k字节的内存,则从go routine私有的内存池中分配内存。因为是私有的,所有在多数情况下,分配内存不需要上锁。如果私有内存池没有内存了,则需要向中心内存池申请内存,中心内存池是共享数据,此时需要上锁。如果中心内存池也没有内存了,则从堆里申请内存。 私有内存池和中心内存池里的内存都是按照大小分开管理的,这样,分配和释放内存都非常快,而且也不容易产生碎片。通常,中心内存池从堆上申请...阅读全文

Go语言 传值和传指针性能对比

载自达达的博客 以往的C编程经验告诉我们,指针传参会有更好的性能,在Go语言中,这条经验也是通用的。但是需要留意两个问题: 指针传参会导致参数的操作领域不确定,到底函数内部会不会改变传入的对象呢?Go语言中没有类型C那样的const关键字,所以无法控制。Go语言是有GC的,并且这个GC还不是很完善,受对象数量影响较大,传递指针意味着可能多创建不必要的对象,到底指针传参带来的性能提升能不能抵消创建对象产生的GC压力呢?这是一个不好观察到的数据。(原作者达达这里应该是有错误的,首先传值也是复制,要产生一个新对象,分配内存地址传到新的函数中,其次指针一般来说64个字节,复制的代价远小大中型数据传值,因此在都产生一个新对象的情况下,指针还是远优先于传大中型的值结构) 下面是性能消耗的测试代码: pa...阅读全文

博文 2014-10-09 18:00:00 abv123456789

Go 语言指针

Go 语言指针Go 语言中指针是很容易学习的,Go 语言中使用指针可以更简单的执行一些任务。接下来让我们来一步步学习 Go 语言指针。我们都知道,变量是一种使用方便的占位符,用于引用计算机内存地址。Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。以下实例演示了变量在内存中地址:package main import "fmt" func main() { var a int = 10 fmt.Printf("变量的地址: %x\n", &a ) }执行以上代码输出结果为:变量的地址: 20818a220现在我们已经了解了什么是内存地址和如何去反问它。接下来我们将具体介绍指针。什么是指针一个指针变量可以指向任何一个值的内存地址它指向那个值的内存地址。类似于变量和常量,...阅读全文

博文 2016-01-31 05:00:01 u011225629

Golang百万级高并发实例

前言 感谢Handling 1 Million Requests per Minute with Go 这篇文章给予的巨大启发。 基础 我们使用Go语言,基本上是因为他原生支持的高并发:Goroutine 和 Channel;Go 的并发属于 CSP 并发模型的一种实现;CSP 并发模型的核心概念是:“不要通过共享内存来通信,而应该通过通信来共享内存”。 简单用法 我一开始学习Go语言的时候,遇到大访问量的时候,会先创建一个带缓冲的channel,然后起一个Go协程来逐个读取channel中的数据并处理。说他是并发是因为他没有占用主线程,而是另起了一个协程独自运行。但是这没有实现请求之间的并发。特别注意:Go语言中的map不是并发安全的,要想实现并发安全,需要自己实现(如加锁),或者使用sy...阅读全文

golang里channel的实现原理

channel是消息传递的机制,用于多线程环境下lock free synchronization. 它同时具备2个特性: 1. 消息传递 2. 同步 golang里的channel的性能,可以参考前一篇:http://blog.sina.com.cn/s/blog_630c58cb01016xur.html 此外,自带的runtime package里已经提供了benchmark代码,可以运行下面的命令查看其性能: go test -v -test.bench=".*" runtime 在我的pc上的结果是: BenchmarkChanUncontended 50000000 67.3 ns/op BenchmarkChanContended 50000000 67.7 ns/op Ben...阅读全文

golang协程——通道channel阻塞

新的一年开始了,不管今天以前发生了什么,向前看,就够了。 说到channel,就一定要说一说线程了。任何实际项目,无论大小,并发是必然存在的。并发的存在,就涉及到线程通信。在当下的开发语言中,线程通讯主要有两种,共享内存与消息传递。共享内存一定都很熟悉,通过共同操作同一对象,实现线程间通讯。消息传递即通过类似聊天的方式。golang对并发的处理采用了协程的技术。golang的goroutine就是协程的实现。协程的概念很早就有,简单的理解为轻量级线程,goroutine就是为了解决并发任务间的通信而设计的。golang解决通信的理念是:不要通过共享内存来通信,而应该通过通信来共享内存。golang解决方案是消息传递机制,消息的传递就是通过channel来实现的。 channel的使用很简单,...阅读全文

博文 2016-02-16 03:00:01 xiaofengshuyu

Go并发原理

Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言;也正是Go语言的并发特性,吸引了全球无数的开发者。 并发(concurrency)和并行(parallellism)并发(concurrency):两个或两个以上的任务在一段时间内被执行。我们不必care这些任务在某一个时间点是否是同时执行,可能同时执行,也可能不是,我们只关心在一段时间内,哪怕是很短的时间(一秒或者两秒)是否执行解决了两个或两个以上任务。 并行(parallellism):两个或两个以上的任务在同一时刻被同时执行。 并发说的是逻辑上的概念,而并行,强调的是物理运行状态。并发“包含”并行。 (详情请见:Rob Pike 的PPT) Go的CSP并发模型Go实现了两种并发形式。第一种是大家普遍认知的:多线...阅读全文

Go Runtime hashmap实现

前两天有小伙伴问道是否看过 Go 语言 map 的实现,当时还真没看过,于是就花了一点时间看了一遍 runtime 源码中的 hashmap 实现。map 的底层实现就是一个 hash 表,大体结构上和平时在脑海里的 hash 表差不多,但确实有很多细节(“Devils in the details”)。 hashmap 通过一个 bucket 数组实现,所有元素将被 hash 到数组中的 bucket 中,bucket 填满后,将通过一个 overflow 指针来扩展一个 bucket 出来形成链表,也就是解决冲突问题。这也就是一个基本的 hash 表结构,没什么新奇的东西,下面总结一些细节吧。 注意一个 bucket 并不是只能存储一个 key/value 对,而是可以存储8个 key/...阅读全文

Go的变量到底在堆还是栈中分配

Go的变量到底在堆还是栈中分配 2015-10-22 最近试着优化掉一些小对象分配,发现一个很诡异的问题:这段代码会在堆上分配对象! package main import ( "fmt" ) func main() { var a [1]int c := a[:] fmt.Println(c) } 看汇编代码 go tool compile -S test.golang "".main t=1 size=336 value=0 args=0x0 locals=0x98 0x0000 00000 (test.go:7) TEXT "".main(SB), $152-0 0x0000 00000 (test.go:7) MOVQ (TLS), CX 0x0009 00009 (test.go:...阅读全文

博文 2016-07-20 13:27:37 zenlife

c,golang 条件变量的使用对比

看到golang 标准库 sync package 提供了传统的mutex, once, cond, rwmutex 等基于共享内存的同步原语,就想写个代码实验一下。 type Cond struct { // L is held while observing or changing the condition L Locker // contains filtered or unexported fields } Cond 结构包含一个可导出的Locker 对象 func NewCond(l Locker) *Cond NewCond 函数 接受一个实现Locker 接口的对象, 返回一个指向Cond 的指针; pthread_cond_t 对应于此 func (c *Cond) Bro...阅读全文

博文 2015-01-15 14:00:01 yujian0231

golang之array

数组 √ golang数组包含的每个数据称为数组元素(element),数组包含的元素个数被称为数组长度(length)。 √ golang数组的长度在定义后不可更改,并且在声明时可以是一个常量或常量表达式(在编译期即可计算结果的表达式)。golang数组长度是一个内置常量,可以用len()函数来获取。 √ golang数组是一个值类型,在赋值和作为参数传递时都将产生一次复制动作,因此在函数体中无法修改传入的数组的内容。 • 数组声明和初始化 ▶ 数组声明 ▪ 语法如下 // 数组声明 var array [n]Type // 数组声明和初始化 var array [n]Type = [n]Type{v1, v2, ..., vn} var array = [n]Type{v1, v2, ....阅读全文

博文 2016-02-20 03:00:04 heartchord

Golang笔记之值类型和引用类型

值类型:所有像int、float、bool和string这些类型都属于值类型,使用这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。可以通过 &i 获取变量 i 的内存地址 引用类型:复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存。一个引用类型的变量r1存储的是r1的值所在的内存地址(数字),或内存地址中第一个字所在的位置,这个内存地址被称之为指针,这个指针实际上也被存在另外的某一个字中。 局部变量被声明后必须在相同的代码块中使用它,否则会得到编译错误,全局变量允许声明但不使用 如果要交换两个变量(已声明且赋值)的值,可以简单地使用a,b = b,a,这被称为并...阅读全文

博文 2017-05-17 12:23:47 弧度里的微笑

go中string和slice no-copy转换

在go里面,string和slice的互换是需要进行内存拷贝的,虽然在底层,它们都只是用 pointer + len来表示的一段内存。 通常,我们不会在意string和slice的转换带来的内存拷贝性能问题,但是总有些地方需要关注的,刚好在看vitess代码的时候,发现了一种很hack的做法,string和slice的转换只需要拷贝底层的指针,而不是内存拷贝。当然这样做的风险各位就要好好担当了: func String(b []byte) (s string) { pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) pstring...阅读全文

博文 2015-06-18 09:09:35 siddontang

Golang直接操作共享内存

前言 故事起源于要搭一个高性能的日志中心。当然使用了elk这一套。但是,对于logstash来说,它主要使用的是文件日志的方式了捕捉log。而写文件日志的话会非常慢。对于实时日志要处理滚动的日志更是这样,每次检查是否需要流动日志,然后打开日志,然后写入,然后关闭,当然这中间可以优化。这一切都是那么慢,发起了n个系统调用,硬盘寻道等。这时候想到了用共享内存来通信。 共享内存的基本知识 要使用共享内存要执行以下几步: 发起一个系统调用,让系统帮你生产一块内存,或者取得一块已经存在的内存来使用。 把内存attach到当前进程,让当前进程可以使用。大家都知道,我们在进程中访问的是虚拟内存地址,系统会把它映射到物理内存中。如果没有这一步,第1步创建的内存就不能在当前进程访问。 这时就可以对内存进程读写...阅读全文

博文 2017-07-02 16:10:18 tenfy

简约语言:golang; CSP式的并发模型

用python开发也有几年了,很喜欢它的简洁。最近在看golang,感觉和python很像,语法简洁,标准类型相识,标准库也是一样的丰富。引用一段文字(http://blog.csdn.net/myan/article/details/2028545): 所谓”魔幻语言“,主要代表作品有C++、Perl、Javascript和Ruby。这些语言拥有丰富的特性,聪明的技 巧和意想不到的奇效,永远有发掘不完的奇技淫巧,总能找到让人匪夷所思的”yet another way"。反过来,“简约语言”崇尚清晰直接,够用就行,要求从代码容易理解,宁可笨一点、累一点、多写一点代码,反对出人意料的技巧,反对故弄玄虚。 C、PHP、Python和Lua这一派语言的代表作。 看来golang也是“简约语言”。 ...阅读全文

博文 2014-10-04 19:27:17 seewind

Go-Slice

要点 一个区间:[low:high] 两个概念:length, capability 三个函数:make(), append(), copy() 概念 Array是在声明的时候都确定了长度,之后不可更改。Slice和数组类似,也是表示一个有序元素,但这个序列的长度可变。 在Go中,Slice序列中各元素的数据类型必须一致,因为在声明slice的时候即要指定类型。 可以在Python中找到Slice,和Go的Slice基本上是一致的语义和用法。Slice中文通常被译为切片,大抵是因为可以从一个序列中存取指定的某一部分。下面是Collins词典中对于slice的解释,有助于了解该词的含义: N-COUNT (指食物切下的)片,薄片 A slice of bread, meat, fruit, o...阅读全文

博文 2016-09-02 07:00:05 u013344915

阿里云对象存储OSS Go SDK发布了,欢迎有兴趣的Go爱好者试用~~~

阿里云对象存储OSS提供的海量、安全和高可靠的云存储服务。存储容量和处理能力的弹性扩展,真正使您专注于核心业务,广泛的应用于海量数据存储与备份,数据加工与处理,内容加速分发,业务数据挖掘分析等多种业务场景。详细介绍见[阿里云官网](http://www.aliyun.com/product/oss/?spm=5176.383663.3.14.RM2v6L)。 本次发布的OSS Go SDK包含了丰富的功能,简洁的接口,详细的例子... ## 主要功能包括: - 简洁、丰富、易用的接口,如PutObject/GetObject/ListObjects; - 并发上传/下载; - 断点续传的上传/下载; - 全面支持STS/HTTPS/CNAME访问; - ...阅读全文

Go 语言的数据结构:链表

数据结构和算法是计算机科学的重要组成部分。虽然有时候它们看起来很吓人,但大多数算法都有简单的解释。同样,当问题能用算法来解释清楚的时候,算法的学习和应用也会很有趣。 这篇文章的目标读者是那些对链表感到不舒服的人,或者那些想要看到并学习如何用 Golang 构建一个链表的人。我们将看到如何通过一个(稍微)实际的例子来实现它们,而不是简单的理论和代码示例。 在此之前,让我们来谈谈一些理论。 ## 链表 链表是比较简单的数据结构之一。维基百科关于链接列表的文章指出: > 在计算机科学中,链表是数据元素的线性集合,其中线性顺序不是由它们在内存中的物理位置所给出的。相反,每个元素指向下一个元素。它是由一组节点组成的数据结构,它们共同代表一个序列。在最简单的形式下,每个节点都由数据和一个指向下个节点的引...阅读全文

博文 2018-03-25 23:02:44 SergeyChang

go语言中var

go语言中定义变量使用关键字var,如:var x int=4 也可以写成x:=4; 在函数中,:= 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。 (:= 结构不能使用在函数外,函数外的每个语法块都必须以关键字开始。) package main import ( "fmt" ) func main() { var x int = 4 fmt.Println(x)//输出4 fmt.Println(&x)//输出指针 //fmt.Println(*x) //错误 y := 4 fmt.Println(y)//输出4 fmt.Println(&y)//输出指针 //fmt.Println(*y) //错误 var v *int = new(int)//返回值为指针 fmt.Prin...阅读全文

Golang 1.3 sync.Atomic源码解析

上一篇文章我们说到sync.Mutex的源码实现,核心就是使用到了CPU指令CAS,从并发性能上来说atomic的效率是要高于mutex的,毕竟mutex做了不少的其他步骤,而atomic的核心其实就是和处理器密切关系的,通过一两个指令就能完成的原子操作,我们接下来来看看atomic在golang中的一些细节。 通过目录: 64bit_arm.go asm_amd64p32.s asm_linux_arm.s atomic_test.go race.go asm_386.s asm_arm.s asm_netbsd_arm.s doc.go asm_amd64.s asm_freebsd_arm.s atomic_linux_arm_test.go export_linux_arm_test...阅读全文

博文 2014-10-19 09:03:49 毛, 剑

Go语言数据结构

当向一个新程序员解释Go语言时,我发现如果解释Go的数据是如何在内存中表示的,将有助于建立编写高效程序的良好直觉。 转载地址:http://www.open-open.com/lib/view/open1390373069882.html 基础类型 让我们从一些简单的例子开始: 变量i是int类型,在内存中占用一个32位的存储单位。(上图拿32位系统来举例;对以上的例子,只有指针才会在64位的机器上占用更多的空间——int始终是32位——然而我们仍然可以选择64位的系统。) 变量j是int32类型,因为它经过了显式的类型转化。尽管i和j有着同样的内存布局,但它们的类型是不一样的:像这样的赋值i = j会产生类型异常,必须通过显式的类型转换:i = int(j) 。 变量f是个浮点类型,上例中...阅读全文

博文 2015-04-09 11:00:01 Decadent_2014

[golang note] 协程通信

channel基本语法 • channel介绍 √ golang社区口号:不要通过共享内存来通信,而应该通过通信来共享内存。 √ golang提供一种基于消息机制而非共享内存的通信模型。消息机制认为每个并发单元都是自包含的独立个体,并且拥有自己的变量,但在不同并发单元间这些变量不共享。每个并发单元的输入和输出只有一种,那就是消息。 √ channel是golang在语言级提供的goroutine间的通信方式,可以使用channel在两个或多个goroutine之间传递消息。 √ channel是进程内的通信方式,如果需要跨进程通信,建议使用分布式的方法来解决,比如使用Socket或HTTP等通信协议。 √ channel是类型相关的,即一个channel只能传递一种类型的值,需要在声明cha...阅读全文

博文 2016-03-16 03:00:01 heartchord

Golang slice 切片原理

golang 中的 slice 非常强大,让数组操作非常方便高效。在开发中不定长度表示的数组全部都是 slice 。但是很多同学对 slice 的模糊认识,造成认为golang中的数组是引用类型,结果就是在实际开发中碰到很多坑,以至于出现一些莫名奇妙的问题,数组中的数据丢失了。 下面我们就开始详细理解下 slice ,理解后会对开发出高效的程序非常有帮助。 这个是 slice 的数据结构,它很简单,一个指向真实 array 地址的指针 ptr ,slice 的长度 len 和容量 cap 。 其中 len 和 cap 就是我们在调用 len(slice) 和 cap(slice) 返回的值。 我们来按照 slice 的数据结构定义来解析出 ptr, len, cap // 按照上图定义的数据...阅读全文

关于golang中的引用类型(reference type)

map,指针(pointers),还有slice,按照我的理解,这样的一个变量,存的就是个内存地址,而这样的一个声明 var a map[int]string var p *int var arr []string 在没有初始化之前都是nil,对这样的一个变量进行写(write)操作,都会抛出一个运行异常(a runtime panic),当然,append操作是可以的,或者用在声明的同时用make初始化一下也可以。 现在需要去验证的是,初始化的map或者slice是有一定默认空间的(尤其是map),如果不用append,直接a[x]=n来增加值,会不会越界抛出异常。。...阅读全文

博文 2016-06-13 14:00:02 hificamera

玩转Golang之Struct结构体

先介绍一下go语言的类型系统 Golang中的类型系统 类型系统是指一个语言的类型体系结构。一个典型的类型系统通常包含如下基本内容:  基础类型,如byte、int、bool、float等;  复合类型,如数组、结构体、指针等;  可以指向任意对象的类型(Any类型);  值语义和引用语义;  面向对象,即所有具备面向对象特征(比如成员方法)的类型;  接口。 Go语言中的大多数类型都是值语义,并且都可以包含对应的操作方法。在需要的时候,你可以给任何类型(包括内置类型)“增加”新方法。而在实现某个接口时,无需从 该接口继承(事实上,Go语言根本就不支持面向对象思想中的继承语法),只需要实现该接口 要求的所有方法即可。任何类型都可以被Any类型引用。Any类型就是空接口,即inte...阅读全文

博文 2018-08-11 23:35:04 夏海社长

Go语言把IP转为int存储.节省空间提高索引速度

package main import ( "errors" "fmt" "strconv" "strings" ) type IntIP struct { IP string Intip int } func main() { var x *IntIP = &IntIP{IP: "192.168.1.1"} fmt.Println(x) x.ToIntIp() fmt.Println(*x) } func (self *IntIP) String() string { return self.IP } func (self *IntIP) ToIntIp() (int, error) { Intip, err := ConvertToIntIP(self.IP) if err != nil...阅读全文

博文 2015-12-23 22:00:04 fyxichen

Go和C如何共享内存资源

Go语言作为一个现代化的编程语言以及支持垃圾内存的自动回收特性(GC). 我们现在关注的是C语言返回的内存资源的自动回收技术. CGO初步 Go语言的cgo技术允许在Go代码中方便的使用C语言代码. 基本的用法如下: package rand /* #include */ import "C" func Random() int { return int(C.random()) } func Seed(i int) { C.srandom(C.uint(i)) } 其中"C"是导入一个虚拟的包, 用于引用C语言的符号. Go语言和C语言通讯交互主要是通过传递参数和返回值. 其中参数和返回值除了基本的 数据类型外, 最重要的是如何相互传递/共享二进制的内存块. Go向C语...阅读全文

博文 2015-05-18 12:37:48 chai2010

Golang-TCP异步框架Tao分析

TCP异步框架 Golang 编程风格 Go语言面向对象编程的风格是多用组合,少用继承,以匿名嵌入的方式实现继承。 掌握Go语言,要把握一个中心,两个基本点。 一个中心是Go语言并发模型,即不要通过共享内存来通信,要通过通信来共享内存; 两个基本点是Go语言的并发模型的两大基石:channel和go-routine。 不要通过共享内存来通信,要通过通信来共享内存 这句话的大概解释是: 不要通过共享内存来实现通信,这是因为在复杂的分布式、多线程和多进程之间通过加锁等控制并发方式来保证数据的正确性,是非常困难和低效的。建议线程之间通过通道channel来实现通知,降低数据的竞争,提高系统的可靠性和正确性。 1. 服务启动开始 1.1 启动心跳定时器循环 func (s *Server) time...阅读全文

博文 2017-09-04 09:34:51 wiseAaron

空结构体

空结构体 这篇文章探讨了我喜欢的Go数据类型,空结构体。 空结构体是一个没有field的结构体类型。这里有几个例子,有命名和匿名形式: type Q struct{} var q struct{} 所以,如果空结构体没有成员,我们该怎么使用它? width 在深入研究空结构体本身前,我想简要讨论下width。 术语width来自于gc编译器,尽管它的词源可能追溯到几十年年。 width描述了类型实例占用的字节数目。因为一个进程的地址空间是一维的,我认为witdh比size更合适。 width一个类型的属性。因为Go程序的每个值都有一个类型,值类型定义了它的witdh,一般是8比特的倍数。 我们可以发现任何值的宽度,它的类型的width使用unsafe.Sizeof()函数: var s st...阅读全文

[翻译]飞翔的 gob

这个题目的原文叫做《Gobs on the wire》,作者巧妙的用了“gob”这个词。gob本来是Golang的一个关于网络通信协议的包。而在这里,我感觉标题也可以翻译为《关于线上的那一大陀……》。好吧,我得承认,这么翻译实在不雅。 ————翻译分割线———— 飞翔的 gob 这周,我想跟大家谈谈如何用 Go 编写基于同步请求和异步事件通知的 Client/Server 系统。 为了帮助学习 Go,我克隆了一个Conserver 命令行服务。当然,现在对于世界来说没必要有另外一个命令行服务。然而由于Go语言带给开发者的特性,非常适合用来做命令行服务,所以这将会是一次非常有趣的体验。命令行服务的任务是从一个或者多个串口上汇总输出(或者说各种系统上的一个或者多个实现了使用TCP连接的Rteln...阅读全文

博文 2014-10-09 16:15:25 mikespook

channel in Go's runtime

Go语言有一个非常大的亮点就是支持语言级别的并发。语言级别提供并发编程,究竟有多重要,可能需要你亲自去体会多线程、事件+callback等常见的并发并发编程模型后才能准确的感受到。为了配合语言级别的并发支持,channel组件就是Go语言必不可少的了。官方提倡的一个编程信条——“使用通信去共享内存,而不是共享内存去通信”,这里说的”通信去共享内存”的手段就是channel。 channel的实现位于runtime/chan.c文件中。 channel底层结构模型 每个channel都是由一个Hchan结构定义的,这个结构中有两个非常关键的字段就是recvq和sendq。recvq和sendq是两个等待队列,这个两个队列里分别保存的是等待在channel上进行读操作的goroutine和等待在...阅读全文

go语言学习之路五:Go语言内存分配机制make&new

Go有两种分配内存的机制,规则很简单,下面来简单介绍一下。1、new函数New()函数可以给一个值类型的数据分配内存(不知道什么是值类型请前往切片那一部分),调用成功后返回一个初始化的内存块指针,同时该类型被初始化为0值,原型定义:func new(Type) * Typenew是一个分配内存的内置函数,但是不同于其他语言中new所做的工作,它只是将内存清零,而不是初始化内存。2、make函数Make()函数用于给引用类型分配内存空间,比如:slice,map,channal等,这里需要注意的一点是make()创建的是一个引用类型的对象,而不是一个内存空间的指针。Make()函数原型:func make(Type,size IntegerType)Type参数Type必须是一个引用类型(sl...阅读全文

Go中实现手动内存分配的坑

Go中实现手动内存分配的坑 2016-07-10 你一定想到过,分配一块大的内存,然后从里面切小的对象出来,手动管理对象分配。分配的开销非常小,就是offset加一下。尤其是有些场景,释放时直接把offset重置,就可以重用这块空间了。实现手动内存分配的好处是,减少小对象数目,从而减少垃圾回收时的扫描开销,降低延迟和提升整个性能。 想到不代表做过,做过会踩坑,这篇文章会把你可能要踩的坑都说一遍。不过先说结论:别这么干,不作死就不会死! TL;DR 扩容 开始很容易想用make([]byte)分配空间,如果大小不够时,还可以进行扩容。这是第一个陷阱。 不要append,别让它扩容。一旦发生扩容,会分配一块新的空间,而旧的slice将不再有任何变量引用它,于是会被垃圾回收掉。等等!之前分配的对象...阅读全文

Golang引用类型

引用类型包含 slice、map、channel 内置函数:new 为其分配零值内存 并返回指针 make 为其分配内存初始化结构 并返回对象 package main import ( "fmt" ) func main() { a := make([]int, 3) a[1] = 10 b := new([]int) b[1] = 20 //error : invalid operation: b[1] (type *[]int does not support indexing) ...阅读全文

博文 2016-09-12 12:00:34 lt695981642