Go语言2
Go语言特点:
类型检查:编译时
运行环境:编译成机器代码直接运行
编程范式:面向接口,函数式编程,并发编程
Go并发编程
采用CSP(Communication Sequenication Process) 模型
不需要锁,不需要callback
并发编程 vs 并行计算
简单的一个服务,从浏览器访问可以得到 "Hello World"
结果,可以自己敲一遍
排序:
/*********************************************************/
最后一张是排序好的,也有没排序的时侯,可以自行敲代码,就能看到效果
/************************有一些内容没有,没时间*****************************************/
赋值和切片
对切片里某个索引指向的元素和对数组里某个索引之乡的元素赋值的方法完全一样,使用 [] 操作符就可以改变某个元素的值
切片append
追加
迭代
映射的内部实现和基础功能:
映射是一种数据结构,用于存储一系列无序的键值对
映射基于键来存储值,映射功能强大的地方是,能够基于键快速检索,键就像索引一样,指向与该键关联的值
内部实现:
映射是一个集合,可以使用类似处理数组和切片的方式迭代映射中的元素,但映射是无序的集合,意味着没有办法预测键值对被返回的顺序,即便使用同样的顺序保存键值对,每次迭代映射的时候顺序也可能不一样,无序的原因是映射的实现使用了散列表
映射的散列表包含一组桶。在存储、删除或者查找键值对的时候,所有操作都要先选择一个桶,把操作映射时指定的键传给映射的散列函数,就能选中对应的桶。这个散列函数的目的是生成一个索引,这个索引最终将键值对分布到所有可用的桶里
随着映射存储的增加,索引分布越均匀,访问键值对的速度就越快
测试映射里是否存在某个键值是映射的一个重要操作,这个操作允许用户写一些逻辑来确定是否完成了某个操作,或者是否
在映射里缓存了特定数据,这个操作也可以用来比较两个映射,来确定哪些键值对互相匹配,哪些键值对不匹配
从映射取值有两个选择,第一个选择是,可以同时获得值,以及一个表示这个键是否存在的标志
根据返回
想把一个键值对从映射里删除,就使用内置的 delete 函数
在函数间传递映射
可以看到,在调用了 removeColor 之后 , main 函数里引用的映射中不再有 Color 颜色了,这个特性和切片类似
保证可以用很小的成本来复制映射
小结:
---数组是构造的切片和映射的基石
---Go 语言里切片经常用来处理数据的集合,映射用来处理具有键值对结构的数据
---内置函数 make 可以创建切片和映射,并指定原始的长度和容量,也可以直接使用切片和映射字面量,或者使用字面量作为
变量的初始值
---切片有容量限制,不过可以使用内置的 append 函数扩展容量
---映射的增长没有容量或者任何限制
---内置函数 len 可以用来获取切片长度或者映射长度
---内置函数 cap 只能用于切片
---通过组合,可以创建多维数组和多维切片,也可以使用切片或者其他映射作为映射的值,但是切片不能用作映射的键
---将切片或者映射传递给函数成本很小,并且不会复制底层的数据结构
通道
当一个资源需要在goroutine 之间共享时,通道在 goroutine 之间架起了一个管道,并提供了确保同步交换数据的机制,声明通道时,
需要指定将要被共享的数据的类型,可以通过通道共享内置类型,命名类型,结构类型和引用类型和引用类型的值或指针
创建通道:需要 chan make 关键字,向通道发送数据需要用 <- 操作符
通道是否带有缓冲,其行为会有一些不同,理解这个差异对决定到底该使用还是不使用缓存
无缓冲的通道:是指在接收没有能力保存任何值的通道,这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,
才能完成发送和接收操作,如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待,
这种对通道进行发送和接收的交互行为本身就是同步的,其中任意以份额操作都无法离开另一个操作单独存在
如何利用无缓冲的通道共享一个值
package main import ( "fmt" "math/rand" "sync" "time" ) //wg 等待程序结束 var wg sync.WaitGroup func init() { rand.Seed(time.Now().UnixNano()) } func main() { //创建一个无缓冲的通道 court := make(chan int) //计数 +2 表示要等待 2 个 goroutine wg.Add(2) //启动两个 goroutine go player("jock",court) go player("Roos",court) //发球 court <- 1 //等待游戏结束 wg.Wait() } //模拟一个选手打网球 func player(name string,court chan int) { //在函数退出时调用 Done 来通知 main 函数工作已经完成 defer wg.Done() for { //等待球被击打过来 ball,ok := <-court if !ok { //如果通道被关闭我们就赢了 fmt.Printf("Player %s Won\n",name) return } // 选随机数,然后用这个来判断我们是否丢球 n := rand.Intn(100) if n % 13 == 0 { fmt.Printf("Player %s missed\n", name) //关闭通道 我们输了 close(court) return } // 显示击球数,并将击球数 +1 fmt.Printf("Player %s Hit %d\n",name,ball) ball++ //将球打向对手 court <- ball } }
例子 Runner
package main import ( "fmt" "sync" "time" ) var wg sync.WaitGroup func main() { baton := make(chan int) wg.Add(1) go Runner(baton) baton <- 1 wg.Wait() } func Runner(baton chan int) { var newRunner int runner := <- baton fmt.Printf("Runner %d Running with Baton \n",runner) if runner != 4 { newRunner = runner + 1 fmt.Printf("Runner %d To The Line \n",newRunner) go Runner(baton) } time.Sleep(100 * time.Millisecond) if runner == 4 { fmt.Printf("Runner %d Finished,Race Over\n",runner) wg.Done() return } fmt.Printf("Runner %d Exchange with Runner %d\n",runner,newRunner) baton <- newRunner }
有缓冲的通道:是指一种在被接收前能存储一个或者多个值的通道,这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收
通道会阻塞发送和接收动作的条件也会不同,只有在通道中没有接收的值时,接收动作才会阻塞,只有在通道没有可用缓冲区容纳被发送的
值时,发送动作才会阻塞,这导致有缓冲的通道和无缓冲的通道之间的一个很大的不同,无缓冲的通道之间的一个很大的不同,无缓冲的通道保证
进行发送和接收的 goroutine 会在同一时间进行数据交换,有缓冲的通道没有这种保证
包的导入 :
_,操作, 其实是引入该包,而不是直接使用包里的函数,而是调用了该包的 init 函数
Json文件解析
package main import ( "encoding/json" "fmt" "io/ioutil" "log" ) type Infomation struct { HttpAddr string MaxCoon int ConnName string Nums float64 } var path string = "/home/lbk/go/src/go-websocket/newweb/tsconfig.json" func main () { JsonParse := NewJsonStruct() v := Infomation{} JsonParse.Load(path,&v) //文件路径传进取,可以接收的格式类型传进取 fmt.Println(v.HttpAddr) //传指针/引用进去操作的就是这个实际值 fmt.Println(v.MaxCoon) fmt.Println(v.ConnName) fmt.Println(v.Nums) } //定一个空类型 type JsonStruct struct { } //定义一个函数返回一个 JsonStruct{} 类型的引用/指针 func NewJsonStruct() *JsonStruct { return &JsonStruct{} } // 传文件路径进去,第二个参数相当于一个任意类型的指针 func (jst *JsonStruct) Load(filename string,v interface{}) { data,err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) return } err = json.Unmarshal(data,v) if err != nil { log.Fatal(err) return } }
Json文件定义:
结果:
xml文件读取
CSP (communicating sequential process) 是一个并发模型,在不同的执行体之间传递值,但是变量本身局限于但以的执行体
在有两个或多个goroutine 的并发程序中,两个函数可以同时执行
使用共享变量实现并发
竞态:
考虑一个能在串行程序中正确工作的函数,如果这个函数在并发调用时,仍能正确工作,那么这个函数就是并发安全的,在这里
并发调用是指,在没有额外同步机制的情况下,从两个或多个 goroutine 同时调用这个函数,这个概念也可以推广到其它函数,
比如方法或这作用于特定类型的一些操作,如果一个类型的所有可访问方法和操作都是并发安全的,则它可称为并发安全的类型
让一个程序并发安全并不需要其中的每一个具体类型都是并发安全的,实际上,并发安全的类型其实是特例而不是普遍存在的,所以
仅在文档指出类型安全的情况下,才可以并发的访问一个变量,对于绝大部分变量,如果要回避并发访问,要么限制变量只存在于一个
goroutine 内,要么维护一个更高层的互斥不变量,
与之对应的是,导出的包级别函数通常可以认为是并发安全的,因为包级别的变量无法限制在一个 goroutine 内,所以修改这些变量
的函数就必须采用互斥机制
函数并发工作时不工作的原因有很多,包括死锁,活锁以及资源耗尽,我们没有足够的时间来讨论所有的情形,因此接下来会重点讨论
最重要的一种情形,即竞态
竞态是指在多个 goroutine 按某些交错顺序执行时程序无法给出正确的结果,竞态对于程序是致命的,因为它们可能会潜伏在程序中,
出现频率很低,又可能仅在高负载环境或这在使用特定的编译器,平台和架构时才会出现,这些都让竞态很难再现和分析
如何避免竞态:
1:不要修改变量
Go语言2的更多相关文章
- C语言 · 高精度加法
问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...
- Windows server 2012 添加中文语言包(英文转为中文)(离线)
Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- C语言 · Anagrams问题
问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的.例如,"Unclear"和"Nuclear ...
- C语言 · 字符转对比
问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等.比如 Beijing 和 Hebei 2:两个字符串不仅长度相 ...
- JAVA语言中的修饰符
JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...
- Atitit 项目语言的选择 java c#.net php??
Atitit 项目语言的选择 java c#.net php?? 1.1. 编程语言与技术,应该使用开放式的目前流行的语言趋势1 1.2. 从个人职业生涯考虑,java优先1 1.3. 从项目实际来 ...
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...
- InstallShield 脚本语言学习笔记
InstallShield脚本语言是类似C语言,利用InstallShield的向导或模板都可以生成基本的脚本程序框架,可以在此基础上按自己的意愿进行修改和添加. 一.基本语法规则 ...
- 用C语言封装OC对象(耐心阅读,非常重要)
用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...
随机推荐
- TeamViewer app案例分析
产品 产品名 TeamViewer远程app 选择原因 远程连接软件是不时之需,当有时私人电脑没有在身边而又需要操作电脑时,远程控制TeamViewer这个软件能帮我们大忙. 调研与评测 1.第一次上 ...
- 字典树(前缀树)-Java实现
字典树 字典树是一种树形结构,优点是利用字符串的公共前缀来节约存储空间.在这提供一个自己写的Java实现,非常简洁. 根节点没有字符路径.除根节点外,每一个节点都被一个字符路径找到. 从根节点到某一节 ...
- Eclipse插件安装方法大全
1. M2e maven2插件安装 参考地址:http://www.sonatype.com/books/m2eclipse-book/reference/install-sect-marketpla ...
- IIS : Add the server variable name to the allowed server variable list.
IIS下设置反向代理访问时报错:将服务器变量名添加到允许的服务器变量列表中. 1.打开IIS: 2.打开要添加变量的站点: 3.打开URL Rewrite: 4.在右列上,选择“查看服务器变量(Vie ...
- 1483. [HNOI2009]梦幻布丁【平衡树-splay】
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...
- 【洛谷】【treap/堆】P2073 送花
[题目描述:] 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地向里面添加花.他有以下几种操作: 操作 含义 1 W C 添加一朵美丽值为W,价格为C的花. 3 小 ...
- 【转】使用URL SCHEME启动天猫客户端并跳转到某个商品页面的方法
在项目中遇到了这样一个需求:让用户在手机应用中,点击一个天猫的商品链接(知道商品在PC浏览器里的地址),直接启动天猫的客户端并显示这个商品.以前曾经实现过类似的功能,不过那次是淘宝的商品,天猫和淘宝的 ...
- 随手练——Uva-11584 划分成回文串(区间DP)
思路:dp[i]代表到第i位的最小值,枚举它的前几位,求出最小值. 转移方程:dp[ i ] = min(dp[ i ], dp[ j - 1 ] + 1 ) ; 本来觉得,代码加深部分可以提前bre ...
- 20145203盖泽双 《Java程序设计》第十周学习总结
20145203盖泽双 <Java程序设计>第十周学习总结 教材学习内容总结 一.网络概述 1.网络编程就是两个或多个设备(程序)之间的数据交换. 2.识别网络上的每个设备:①IP地址②域 ...
- Windows下docker的安装,将ASP.NET Core程序部署在Linux和Docker中
参考文章: https://www.cnblogs.com/jRoger/p/aspnet-core-deploy-to-docker.html docker for windows下载连接: htt ...