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这些对象 ...
随机推荐
- java微信小程序解密AES/CBC/PKCS7Padding
摘要:微信小程序解密建议使用1.6及以上的环境使用maven下载jar包org.bouncycastlebcprov-jdk15on1.55加密类代码importorg.bouncycastle.jc ...
- 看完了红米5 Plus发布会,我觉得魅蓝Note6降价降多了
没有意外,红米5 Plus在今天下午已经发布.这款以全面屏为卖点的手机机,将红米最低端的一个系列加价到了999元起步——这一切只是因为一个全面屏而已. 知道了红米5 Plus的售价之后,李楠大呼“降多 ...
- Kafka设计解析(八)Exactly Once语义与事务机制原理
转载自 技术世界,原文链接 Kafka设计解析(八)- Exactly Once语义与事务机制原理 本文介绍了Kafka实现事务性的几个阶段——正好一次语义与原子操作.之后详细分析了Kafka事务机制 ...
- 控制层方法中获取url目录
控制层方法中获取url目录 Request.Url.GetLeftPart(UriPartial.Authority).ToString(); //返回 http://localhost:9246(网 ...
- 【html】点击链接让页面在 iframe 中变换
Demo: <html><body> <a href= "1.html " target= "iFrameName "> p ...
- where语句中不能直接使用聚合函数
1.问题描述 select deptno ,avg(sal) from emp where count(*)>3 group by deptno; 在where 句中使用聚合函数count(*) ...
- SpringBoot与mongodb的结合
本文系列文章: 使用Shell 操作 MongoDB的技巧 MongoTemplate的使用技巧及其注意事项 敬请期待. 前言 最近公司想要做一个用户行为数据的收集,最开始想用mysql来存储 ...
- Python学习 :常用模块(二)
常用模块(二) 四.os模块 os模块是与操作系统交互的一个接口,用于对操作系统进行调用 os.getcwd() # 提供当前工作目录 os.chdir() # 改变当前工作目录 os.curdir( ...
- C语言之随机数函数( rand() )的使用方法
文章出自个人博客https://knightyun.github.io/2018/04/25/c-rand-number,转载请申明. 在程序设计中,难免会使用到随机值函数,其原理与语法大多类似,接下 ...
- v$pwfile_user表
SQL> select * from v$pwfile_users;select * from v$pwfile_users; USERNAME SYSDB SYSOP SYSAS------- ...