教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang 知识点总结

golang 知识点总结

发布时间:2021-12-14   编辑:jiaochengji.com
教程集为您提供golang 知识点总结等资源,欢迎您收藏本站,我们将为您提供最新的golang 知识点总结资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h2 id="1什么情况下设置runtimegomaxprocs会比较好的提高速度呢">1、什么情况下设置runtime.GOMAXPROCS会比较好的提高速度呢?</h2>

GO默认是使用一个CPU核的,通过设置runtime.GOMAXPROCS可以设置使用多核,并不是核越多处理速度越快,要根据不同业务场景设置核数,比如:

<ol><li>适合设置多核场景:CPU密集型、并行度比较高的情景,比如多数组排序,复杂计算等。</li><li>不适合设置多核场景:IO密集型,读写文件、爬虫如果只是抓网页而不分析等场景。</li></ol><h2 id="2syncwaitgroup用法">2、sync.WaitGroup用法</h2>

WaitGroup在go语言中,用于线程同步,单从字面意思理解,wait等待的意思,group组、团队的意思,WaitGroup就是指等待一组,等待一个系列执行完成后才会继续向下执行。贴上google官方的代码:

<pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">package</span> main <span class="hljs-keyword">import</span> ( <span class="hljs-string">"fmt"</span> <span class="hljs-string">"sync"</span> <span class="hljs-string">"net/http"</span> ) <span class="hljs-keyword">func</span> main() { <span class="hljs-keyword">var</span> wg sync.WaitGroup <span class="hljs-keyword">var</span> urls = []<span class="hljs-typename">string</span>{ <span class="hljs-string">"http://www.golang.org/"</span>, <span class="hljs-string">"http://www.google.com/"</span>, <span class="hljs-string">"http://www.baiyuxiong.com/"</span>, } <span class="hljs-keyword">for</span> _, url := <span class="hljs-keyword">range</span> urls { <span class="hljs-comment">// WaitGroup增加一个计数.</span> wg.Add<span class="hljs-number">(1</span>) <span class="hljs-comment">// 执行goroutine抓取网页.</span> <span class="hljs-keyword">go</span> <span class="hljs-keyword">func</span>(url <span class="hljs-typename">string</span>) { <span class="hljs-comment">// 当goroutine完成是,减少WaitGroup的计数.</span> <span class="hljs-keyword">defer</span> wg.Done() <span class="hljs-comment">// Fetch the URL.</span> http.Get(url) fmt.Println(url); }(url) } <span class="hljs-comment">// 等待所有的 HTTP 完成.</span> wg.Wait() fmt.Println(<span class="hljs-string">"over"</span>); } #执行结果: http:<span class="hljs-comment">//www.baiyuxiong.com/</span> http:<span class="hljs-comment">//www.google.com/</span> http:<span class="hljs-comment">//www.golang.org/</span> over</code></pre>

从执行结果可看出:
1、取三个网址信息的时候,结果显示顺序与for循环的顺序没有必然关系。
2、三个goroutine全部执行完成后,wg.Wait()才停止等待,继续执行并打印出over字符

<h2 id="3go语言的组合继承">3、go语言的组合继承</h2> <pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">type</span> People <span class="hljs-keyword">struct</span>{} <span class="hljs-keyword">func</span> (p *People) ShowA() { fmt.Println(<span class="hljs-string">"showA"</span>) p.ShowB() } <span class="hljs-keyword">func</span> (p *People) ShowB() { fmt.Println(<span class="hljs-string">"showB"</span>) } <span class="hljs-keyword">type</span> Teacher <span class="hljs-keyword">struct</span> { People } <span class="hljs-keyword">func</span> (t *Teacher) ShowB() { fmt.Println(<span class="hljs-string">"teacher showB"</span>) } <span class="hljs-keyword">func</span> main() { t := Teacher{} t.ShowA() }</code></pre>

这是Golang的组合模式,可以实现OOP的继承。 被组合的类型People所包含的方法虽然升级成了外部类型Teacher这个组合类型的方法(一定要是匿名字段),但它们的方法(ShowA())调用时接受者并没有发生变化。 此时People类型并不知道自己会被什么类型组合,当然也就无法调用方法时去使用未知的组合者Teacher类型的功能。

<h2 id="4go语言select随机性">4、go语言select随机性</h2> <ol><li>select 中只要有一个case能return,则立刻执行。</li><li>当如果同一时间有多个case均能return则伪随机方式抽取任意一个执行。</li><li>如果没有一个case能return则可以执行”default”块。</li><li>单个chan如果无缓冲时,将会阻塞</li></ol>

5、map线程安全
线程不安全时,可能会出现:可能会出现fatal error: concurrent map read and map write
以下为map不安全的例子:

<pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">type</span> UserAges <span class="hljs-keyword">struct</span> { ages <span class="hljs-keyword">map</span>[<span class="hljs-typename">string</span>]<span class="hljs-typename">int</span> sync.Mutex } <span class="hljs-keyword">func</span> (ua *UserAges) Add(name <span class="hljs-typename">string</span>, age <span class="hljs-typename">int</span>) { ua.Lock() <span class="hljs-keyword">defer</span> ua.Unlock() ua.ages[name] = age } <span class="hljs-keyword">func</span> (ua *UserAges) Get(name <span class="hljs-typename">string</span>) <span class="hljs-typename">int</span> { <span class="hljs-keyword">if</span> age, ok := ua.ages[name]; ok { <span class="hljs-keyword">return</span> age } <span class="hljs-keyword">return</span><span class="hljs-number"> -1</span> }</code></pre>

修改后如下:

<pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">func</span> (ua *UserAges) Get(name <span class="hljs-typename">string</span>) <span class="hljs-typename">int</span> { ua.Lock() <span class="hljs-keyword">defer</span> ua.Unlock() <span class="hljs-keyword">if</span> age, ok := ua.ages[name]; ok { <span class="hljs-keyword">return</span> age } <span class="hljs-keyword">return</span><span class="hljs-number"> -1</span> }</code></pre> <h2 id="5syncrwmutex和syncmutex区别">5、sync.RWMutex和sync.Mutex区别</h2>

golang中sync包实现了两种锁Mutex (互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能.

<pre class="prettyprint"><code class=" hljs go"> <span class="hljs-keyword">type</span> Mutex <span class="hljs-keyword">func</span> (m *Mutex) Lock() <span class="hljs-keyword">func</span> (m *Mutex) Unlock() <span class="hljs-keyword">type</span> RWMutex <span class="hljs-keyword">func</span> (rw *RWMutex) Lock() <span class="hljs-keyword">func</span> (rw *RWMutex) RLock() <span class="hljs-keyword">func</span> (rw *RWMutex) RLocker() Locker <span class="hljs-keyword">func</span> (rw *RWMutex) RUnlock() <span class="hljs-keyword">func</span> (rw *RWMutex) Unlock() </code></pre> <ol><li>其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁.</li><li>RWMutex是一个读写锁,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景. func (rw *RWMutex) Lock()  写锁,如果在添加写锁之前已经有其他的读锁和写锁,则lock就会阻塞直到该锁可用,为确保该锁最终可用,已阻塞的 Lock 调用会从获得的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定.</li></ol><h2 id="6type-用法">6、type 用法</h2>

<code>
switch typevalue.(type) {
case int:
println("int")
case string:
println("string")
case interface{}:
println("interface")
default:
println("unknown")
}
</code>其中typevalue必须时interface类型

<h2 id="7defer用法总结">7、defer用法总结</h2> <ol><li>defer 后面必须跟函数。 </li><li>defer在函数结束前执行,这种结束有可能是:函数正常执行完成后、函数遇到return并执行return后,函数遇到panic。</li><li>执行顺序:函数内容–return–defer–panic</li></ol> 到此这篇关于“golang 知识点总结”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
学习golang开始前的准备工作
数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
Golang核心知识总结
golang map多层嵌套使用及遍历方法汇总
Golang笔记:语法,并发思想,web开发,Go微服务相关
golang key map 所有_Golang面试知识点总结
数据结构-树和二叉树(Golang)
golang float32转float64精度丢失_golang 混合写屏障原理深入剖析,这篇文章给你梳理的明明白白!...
为什么要学 Go
并发同时访问_快速掌握Golang锁机制和并发基础

[关闭]
~ ~