go language few of the most important points are summarized (1)

1. The first thing to say: everyone will have to learn their own ideas and opinions, so my conclusion may just be good for me to understand, please forgive me.

2. probably will summarize the contents of

  • 1.go language interface (interface)
  • 2.goroutine
  • 3.channel
    following two will leave tomorrow or the day after to write one day write too many words no one is willing to see
  • 4. Concurrent and security lock
  • The two simple web entry codes (does not use frames)

3. started

1.go language interface

The word began to learn the interface from java have come into contact with, so let us talk about what is the interface. The official said that the interface (Interface) is a collection of some of the features of the method, and in the go language is an abstract data type interfaces. It may be so difficult to understand, then to write with the examples and talking.

package main

import "fmt"

type dog struct{}

func (d dog) say() {
	fmt.Println("汪汪汪")
}

type cat struct{}

func (c cat) say() {
	fmt.Println("喵喵喵")
}

type person struct {
	name string
}

func (p person) say() {
	fmt.Println("啊啊啊")
}

//接口不注重类型,只注重实现的方法
//只要实现了say()方法的类型就能成为sayer这个接口类型
type sayer interface {
	say()
}

func hit(arg sayer) {
	arg.say()
}

func main() {
	c1 := cat{}
	hit(c1)
	d1 := dog{}
	hit(d1)
	p1 := person{name: "123"}
	hit(p1)
}

The first examples of which we have three structures, dogs, cats, people, and there are ways they called correspondence, such as a dog will bark Wang called. This time we'll define an interface sayer, as long as the data type implements say () method can become sayer this type of interface. This time to write a function hit (), the incoming parameter is the interface type of the variable, in fact, it is all types of implements say () method, and then calls the corresponding parameters passed say () method.
Here Insert Picture Description
After this example, let's look at the interface in the end what's the use: If, as usual, hit () function parameters are passed to a specific structure, it can only achieve a certain kind of structure of the method, for the other two structure should write hit2, hit3 to achieve respectively. But with the interface, we can all achieve the same type of method into a collection, so you can call the same method with different data types in a function.

Then the role of the interface probably know, come to talk about something interfaces for advanced point
here to emphasize two things:
1. a type can implement multiple interfaces
2. Different types of the same interface can also be achieved

earlier example belong to different the same interface type, again following the same type of a different example of nested, and interface

package main

import "fmt"

type mover interface {
	move()
}

type sayer2 interface {
	say()
}

type Person struct {
	name string
	age  int
}

//指针接收者实现接口,赋值的时候只能传入指针!!!而使用值接收者则可以传入值和指针
func (p *Person) move() {
	fmt.Printf("%s在跑\n", p.name)
}

func (p *Person) say() {
	fmt.Printf("%s在叫\n", p.name)
}

//一个类型可以实现多个接口
//不同的类型也可以实现同一个接口
//接口的嵌套
type animal interface {
	mover
	sayer2
}

func main() {
	var m animal
	p1 := &Person{
		name: "hahah",
		age:  18,
	}
	m = p1
	m.move()
	m.say()
	fmt.Println(m)
}

I define a person's body structure, the names and age, but also to achieve a dynamic method and two people called. In addition, I have two and interfaces for dynamic mover and sayer2 called, this time I then use this interface these two interfaces animal nest, that my people because this type of data to achieve the move and called also this interface can be animal type.

Here there is a detail to note, if I put my implementation written

func (p Person) move() {
	fmt.Printf("%s在跑\n", p.name)
}

func (p Person) say() {
	fmt.Printf("%s在叫\n", p.name)
}

Then the main function instantiation or whether incoming pointer values can be assigned to this animal interface, but if, as above, our interface is a pointer to a recipient that is instantiated when the assignment p1 Person can only be a pointer. That is the phrase I code when a recipient pointers to implement an interface assignment can only pass a pointer! ! ! The recipient can use the value of the incoming values and pointers
go in a language pointer fact this has been very friendly, and usually you pass a pointer or value can help you automatically converted just need to make some own special attention.

Then is empty assertion applications and interfaces interface

//空接口的应用
	//1.可以作为函数的参数,例子:fmt.Println()的参数就是空接口
	//2.作为map的value
	var x = make(map[string]interface{}, 10)
	x["name"] = "xjj"
	x["age"] = 20
	x["hobby"] = []string{"篮球", "唱歌", "敲代码", "玩游戏", "摄影"}
	fmt.Println(x)

	//接口的值由两部分组成:具体的类型+具体类型的值
	//接口的断言
	//开始猜一下接口的类型
	var i interface{}
	i = 123
	ret, ok := i.(string)
	if !ok {
		fmt.Println("不是字符串类型")
	} else {
		fmt.Println("是字符串类型", ret)
	}

	//使用switch进行断言
	switch t := i.(type) {
	case string:
		fmt.Println("是字符串类型", t)
	case bool:
		fmt.Println("是bool类型", t)
	case int:
		fmt.Println("是int类型", t)
	}

Incoming air interface may be any type of data, so it is often used as the parameter value passed to the function or the map
results above all code that runs
Here Insert Picture Description

2.goroutine

Speaking goroutine, the first thought is certainly complicated by, but to talk about concurrency and was from a big process, thread, so here I will simply say these concepts, after all, I did not learn of the operating system when there is no serious particularly clear, ooo, ooo.

When we run an application, and that the operating system will start a process for the application. And each process contains at least one thread, which is the main thread, the thread it is to perform space, it can be used to run the code we write. It is language that go there anything special of it, the general operating system are the calling thread to run on the physical processor, and it is to call goroutine to go running on logical processors.

Then talk about concurrency and parallelism: Use the following example to understand
concurrency and parallelism
Concurrency: the same time, I also chat and two
parallel: the same time, my friend and I were chatting and teachers

in fact, since these developers go language have a good package, then we start also need not be so concerned about the principle, so in the future could look at one o'clock advanced realization of the principle also understand a little more convenient, so first take a few examples.

package main

import (
	"fmt"
	"runtime"
	"sync"
)

func main() {
	runtime.GOMAXPROCS(1)
	var wg sync.WaitGroup
	wg.Add(2)
	fmt.Println("Start Goroutines")

	//声明一个匿名函数创建goroutine
	go func() {
		defer wg.Done()

		//显示小写字母表3次
		for count := 0; count < 3; count++ {
			for char := 'a'; char < 'a'+26; char++ {
				fmt.Printf("%c ", char)
			}
			fmt.Println()
		}
	}()

	//声明一个匿名函数创建goroutine
	go func() {
		defer wg.Done()

		//显示大写字母表3次
		for count := 0; count < 3; count++ {
			for char := 'A'; char < 'A'+26; char++ {
				fmt.Printf("%c ", char)
			}
			fmt.Println()
		}
	}()

	//等待goroutine结束
	fmt.Println("Waiting to finish")
	wg.Wait()
	fmt.Println("Finish!")

}

Here Insert Picture Description
This example is concurrent display case alphabet, in fact, the program is concurrent, but first goroutine done too quickly, so every time I see are the first uppercase and then in lowercase. This simple example there are also some small details that need attention.
1.runtime.GOMAXPROCS (), the number of logical processors is designated scheduler, a default previous version 1.5, after the default, all audit, if it is necessary to call this function can be configured.

2.sync This package is mainly used for record keeping goroutine, a counting semaphore is sync.WaitGroup can record number goroutine run, our code Add (2) to the two goroutine that we use, and requires the use of goroutine is also very simple, just go preceded by the keyword. wg.Done () indicates that the task is completed at this time will count the number of previous WaitGroup -1.

All tasks 3.wg.Wait () will wait until the end to stop waiting, that is, in terms of quantity 0
example above or that code, in order to achieve the above said, "and at the same time two people to talk to the effect," We designated processing an increase in the number, look at the effect of concurrent
Here Insert Picture Description
when we put the processor is set to 5, you can see the situation of the alternate case, due to the randomness try when you can try more than once.
There is also a simple example can illustrate this

package main

import (
	"fmt"
	"runtime"
	"sync"
)

//并发和并行
//并发:同一时间段,我同时和两个人聊天
//并行:同一时刻,我和朋友都在和老师聊天

var wg sync.WaitGroup

//goroutine类似于线程(用户态线程)
func hello(i int) {
	fmt.Println("hello goroutine", i)
	wg.Done() //计数器-1
}

func main() {
	runtime.GOMAXPROCS(3) //占用的cpu核数,1.5+默认使用全部核数
	wg.Add(100)           //计数器
	for i := 0; i < 100; i++ {
		go hello(i)
	}
	fmt.Println("hello main")
	//time.Sleep(time.Second)
	wg.Wait() //等待计数器为0才退出
}

Here Insert Picture Description

3.channel

The main channel for channel synchronization, when a shared resource needs can ensure synchronization with the channel to exchange data between goroutine.
channel in two ways: unbuffered channel and a buffer channel , you will have to start talking about the difference from its creation.

unbuf:=make(chan int)//无缓冲通道
buf:=make(chan int,10)//有缓冲通道

We need to make to create a channel function, it first chan essential parameters, then the type of data needed to be passed, and finally the channel capacity, there is no buffer channel.

btw, to make use of the function in place mainly in the go:
1.slice create
2: map created
3: channel creation

Then time passed we need to use <- operator, when the incoming channel is channel <-, and removed from the channel is: = <- channel, write an example to look at.

package main

import "fmt"

//使用并发是为了协同工作,但是交换数据时会发生数据竞态(竞争状态)
//为了保证数据交换,go使用csp并发模型,通过通信共享内存

//channel的操作
//1.发送:<- 2.接收:<- 3.关闭:close()
func main() {
	var ch1 chan int
	//无缓冲区通道:同步通道
	//带缓冲区的通道:异步通道
	ch1 = make(chan int, 1)
	//ch1:=make(chan int,1)
	ch1 <- 10
	x := <-ch1
	fmt.Println(x)
	close(ch1)
}

This code is very simple, it is to realize the passage 10 and then taken out into a print
Here Insert Picture Description
look at the combination of channel and examples goroutine

package main

import "fmt"

/*
两个goroutine:
1.生成0-100的数字发送到ch1
2.从ch1取出数字并计算平方,把结果发送到ch2
*/

//单向通道:chan<-只能发送,不能取出;<-chan只能取出,不能发送
func f1(ch chan<- int) {
	for i := 0; i < 100; i++ {
		ch <- i
	}
	close(ch)
}

func f2(ch1 <-chan int, ch2 chan<- int) {
	//从通道中循环取值方式1
	for {
		tmp, ok := <-ch1
		if !ok {
			break
		}
		ch2 <- tmp * tmp
	}
	close(ch2)
}

func main() {
	ch1 := make(chan int, 100)
	ch2 := make(chan int, 200)

	go f1(ch1)
	go f2(ch1, ch2)
	//从通道中循环取值方式2
	for ret := range ch2 {
		fmt.Println(ret)
	}
}

Here Insert Picture Description
This example is a digital goroutine generated from 0-100 and transmitted to a channel, a channel from another goroutine removed before calculating the square sent to channel two. Herein except in combination than is also noted that a one-way channel.
Unidirectional channel: chan <- only transmission can not be removed; <- chan only be removed, can not be transmitted
in good time to the function definition unidirectional channel is defined, it is fixed to the direction of the channel. In addition unbuffered channel only to send, receive and prepare Hou operation can be achieved when good, otherwise it will lead to the implementation of the operation blocking wait. The rest will come a few examples to understand it.

package main

import (
	"fmt"
	"time"
)

//work pool

func worker(id int, jobs <-chan int, results chan<- int) {
	for job := range jobs {
		fmt.Printf("worker:%d start job:%d\n", id, job)
		results <- job * 2
		time.Sleep(time.Millisecond * 500)
		fmt.Printf("worker:%d stop job:%d\n", id, job)
	}
}

func main() {
	jobs := make(chan int, 100)
	results := make(chan int, 100)

	//开启三个goroutine
	for j := 0; j < 3; j++ {
		go worker(j, jobs, results)
	}
	//发送五个任务
	for i := 0; i < 5; i++ {
		jobs <- i
	}
	close(jobs)
	for i := 0; i < 5; i++ {
		ret := <-results
		fmt.Println(ret)
	}
}

Here Insert Picture Description

package main

import "fmt"

//select多路复用
/*
select的使用类似于switch,满足多个条件时会随机取一个任务
*/

func main() {
	ch := make(chan int, 1)
	for i := 0; i < 10; i++ {
		select {
		case x := <-ch:
			fmt.Println(x)
		case ch <- i:
		default:
			fmt.Println("什么都不干")
		}
	}
}

Here Insert Picture Description
The last example is channel multiplexed, the plurality of conditions are satisfied when using select randomly select a task, since the channel capacity is above 1, it can store one must be removed, it can only get an even number.

to sum up:

Today say is go language and various other languages, and is the most attractive place, we still need a good digestion. Tomorrow it will finish the remaining two parts, then go after the writing language content will write some words about the web part or crawlers.

Finally feeling about, winter vacation home tiring than at school (mainly heart tired), at least, schools are free, some people at home, the more you want to see him still more to join in on your face, really sick of it .

Published 85 original articles · won praise 55 · views 20000 +

Guess you like

Origin blog.csdn.net/shelgi/article/details/103913894