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这些对象 ...
随机推荐
- 取消centOS7虚拟机锁屏
https://blog.csdn.net/ViJayThresh/article/details/81076622
- OSSpinLockLock加锁机制,保证线程安全并且性能高
在aspect_add.aspect_remove方法里面用了aspect_performLocked, 而aspect_performLocked方法用了OSSpinLockLock加锁机制,保证线 ...
- 自定义ClassLoader
自定义classloader MapleClassLoader package com.maple; import java.io.*; public class MapleClassLoader e ...
- UVa 10214 - Trees in a Wood.(欧拉函数)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- Ansible--01
一.ansible是什么: 类似puppet之类的运维自动化工具 二.为什么选择ansible: 1. ansible是python语言开发的,python语言进入门槛低,方便基于pytnon对ans ...
- web常用的正则表达式
1. 平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用: 2. "^\d+$" //非负整数(正整数 + 0) 3. "^[0 ...
- P1481 魔族密码
题目描述 风之子刚走进他的考场,就…… 花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花) 风之子:我呕……(杀死人的眼神)快说题目!否则……-_-### 花花:……咦好冷我们现在 ...
- ZOJ 3983 Crusaders Quest(思维题)
C - Crusaders Quest Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu S ...
- 用ansible2.5在Centos7.2上部署OpenShift3.9(转)
1.环境: 主机名 ip 角色 master 10.2.1.198 master node1 10.2.1.174 no ...
- [图解tensorflow源码] [原创] Tensorflow 图解分析 (Session, Graph, Kernels, Devices)
TF Prepare [图解tensorflow源码] 入门准备工作 [图解tensorflow源码] TF系统概述篇 Session篇 [图解tensorflow源码] Session::Run() ...