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的更多相关文章

  1. C语言 · 高精度加法

    问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...

  2. Windows server 2012 添加中文语言包(英文转为中文)(离线)

    Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...

  3. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  4. C语言 · Anagrams问题

    问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的.例如,"Unclear"和"Nuclear ...

  5. C语言 · 字符转对比

    问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等.比如 Beijing 和 Hebei 2:两个字符串不仅长度相 ...

  6. JAVA语言中的修饰符

    JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...

  7. Atitit 项目语言的选择 java c#.net  php??

    Atitit 项目语言的选择 java c#.net  php?? 1.1. 编程语言与技术,应该使用开放式的目前流行的语言趋势1 1.2. 从个人职业生涯考虑,java优先1 1.3. 从项目实际来 ...

  8. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  9. InstallShield 脚本语言学习笔记

    InstallShield脚本语言是类似C语言,利用InstallShield的向导或模板都可以生成基本的脚本程序框架,可以在此基础上按自己的意愿进行修改和添加.     一.基本语法规则      ...

  10. 用C语言封装OC对象(耐心阅读,非常重要)

    用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...

随机推荐

  1. Java基础面试题(进程和线程的区别)

    进程和线程的区别 1.定义 进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程:进程的一个实体,是CPU调度和分派的基本单位,它是比进程更 ...

  2. Ubuntu 64 + IntelliJ IDEA + Genymotion 搭建Android开发环境

    环境搭建所需可至 http://pan.baidu.com/s/1gd1Kf4Z 下载 注:     此处假定 Ubuntu 用户名为 chenfei     开发相关全部存放在 /home/chen ...

  3. 联通营业厅API 获取个人信息

    string newValue = base.Request["tel"]; string newValue2 = base.Request["pwd"]; s ...

  4. mongodb启动与运用

    在操作前需要启动mongodb数据库服务 1.首先打开dos窗口,然后选择路径到你的安装路径下的bin目录(我的路径是的D:mongo\mongodb\bin) 2.然后输入启动命令(D:mongo\ ...

  5. Python3的__new__进行构造类的实例化

    __new__方法 这个方法是用来生成类的实例 class Singleton(object): def __new__(cls,*args, **kwargs): ① if not hasattr( ...

  6. 【转】Spring Boot干货系列:(六)静态资源和拦截器处理

    前言 本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类WebMvcConfigurerAdapter. 正文 前面章节我们也有简单介绍过SpringBoot中对静态资源的默认支持 ...

  7. PAT乙级1014

    1014 福尔摩斯的约会 (20 分)   大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d& ...

  8. [NOIp2009] $Hankson$の趣味题

    \(23333\)这是最近第二份在时间上吊打\(yjk\)的代码--啊哈哈哈哈哈哈哈 嗯,其实遇到这种单纯的\(gcd \ \ or \ \ lcm\)的题,我们都可以用一种比较简单的方法分析:唯一分 ...

  9. (转)Jmeter http请求之content-type

    原文传送门:http://www.cnblogs.com/dinghanhua/p/5646435.html 第一部分:目前工作中涉及到的content-type 有三种: content-type: ...

  10. [图解tensorflow源码] Graph 图构建 (Graph Constructor)