No1.入门第一课,我的go开发之旅

简介: No1.入门第一课,我的go开发之旅

Go必知必会五连问

1.值类型有哪些?

基本数据类型都是值类型,包括:int系列、float系列、bool、字符串、数组、结构体struct。

2.引用类型有哪些?

指针、切片slice、接口interface、管道channel

3.值类型和引用类型的区别?

  • 值类型在内存中存储的是值本身,而引用类型在内存中存储的是值的内存地址。
  • 值类型内存通常在栈中分配,引用类型内存通常在堆中分配。

4.垃圾回收

引用类型的内存在堆中分配,当没有任何变量引用堆中的内存地址时,该内存地址对应的数据存储空间就变成了垃圾,就会被GO语言的GC回收。

5.栈,堆,切片


在Go中,栈的内存是由编译器自动进行分配和释放,栈区往往存储着函数参数、局部变量和调用函数帧,它们随着函数的创建而分配,函数的退出而销毁。

一个goroutine对应一个栈,栈是调用栈(call stack)的简称。一个栈通常又包含了许多栈帧(stack frame),它描述的是函数之间的调用关系,每一帧对应一次尚未返回的函数调用,它本身也是以栈形式存放数据。


与栈不同的是,应用程序在运行时只会存在一个堆。狭隘地说,内存管理只是针对堆内存而言的。程序在运行期间可以主动从堆上申请内存,这些内存通过Go的内存分配器分配,并由垃圾收集器回收。

  • 切片

切片之间是不能比较的,我们不能使用==操作符来判断两个切片是否含有全部相等元素。切片唯一合法的比较操作是和nil比较。

Go必知必会力扣每日一题

《剑指 Offer 09. 用两个栈实现队列》

题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTaildeleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

解题思路首先我们知道,队列是先入先出,栈是后入先出,所以知道了这两个东西的特性,我们很容易就能根据题意使用两个栈来模拟队列。
首先,两个栈分工不同,一个为入队栈,一个为出队栈,各自负责入队和出队。
入队操作,直接压入入队栈即可,出队操作需要优先检查出队栈是否有数据,若无,需要从入队栈倒入后再操作。

Go必知必会思路图解:

640.png

Go语言代码题解:

type CQueue struct {
  stack1, stack2 []int
}
func Constructor() CQueue {
  //返回一个新的CQueue
  return CQueue{}
}
//AppendTail 在stack1存入元素
func (this *CQueue) AppendTail(value int) {
  //在stack1 的末尾追加元素
  this.stack1 = append(this.stack1, value)
}
//DeleteHead 从队列取出并删除
func (this *CQueue) DeleteHead() int {
  //如果stack2里也没有元素,则从stack1中取元素
    if len(this.stack2) == 0 {
      //如果stack1里也没有元素,则返回-1
      if len(this.stack1) == 0 {
        return -1
    }
    //将stack1的所有元素转移到stackB
    for len(this.stack1) >0 {
      //获取stack1最末尾的下标
      tail :=len(this.stack1)-1
      //获取stack1最末尾的元素的值
      value :=this.stack1[tail]
      //向stack2的末尾添加该元素
      this.stack2 =append(this.stack2,value)
      //从stack1中裁剪末尾元素
      this.stack1 =this.stack1[:tail]
    }
  }
  //这个时候Stack2内已有元素
  //获取stack2最末尾的元素下标
  tail :=len(this.stack2)-1
  //获取stack2的最后一个元素
  value :=this.stack2[tail]
  //从stack裁剪出末尾元素
  this.stack2 =this.stack2[:tail]
  //返回末尾元素
  return value
}



go面试题并进行解答(go并发编程)

1、Mutex 有哪几种状态?

mutexLocked — 表示互斥锁的锁定状态;

mutexWoken — 表示从正常模式被从唤醒;

mutexStarving — 当前的互斥锁进入饥饿状态;

waitersCount — 当前互斥锁上等待的 Goroutine 个数;

2、Mutex 正常模式和饥饿模式分别是指什么?正常模式(非公平锁)

    正常模式下,所有等待锁的 goroutine 按照 FIFO(先进先出)顺序等待唤醒的goroutine不会直接拥有锁,而是会和新请求 goroutine 竞争锁。新请求的 goroutine 更容易抢占:因为它正在 CPU 上执行,所以刚刚唤醒的 goroutine有很大可能在锁竞争中失败。在这种情况下,这个被唤醒的 goroutine 会加入到等待队列的前面。
饥饿模式(公平锁)

    为了解决了等待 goroutine 队列的长尾问题,饥饿模式下,直接由 unlock 把锁交给等待队列中排在第一位的 goroutine (队头),同时,饥饿模式下,新进来的 goroutine 不会参与抢锁也不会进入自旋状态会直接进入等待队列的尾部。这样很好的解决了老的 goroutine 一直抢不到锁的场景。
饥饿模式的触发条件:当一个 goroutine 等待锁时间超过 1 毫秒时,或者当前队列只剩下一个 goroutine 的时候,Mutex 切换到饥饿模式。总结对于两种模式,正常模式下的性能是最好的,goroutine 可以连续多次获取锁,饥饿模式解决了取锁公平的问题,但是性能会下降,这其实是性能和公平的一个平衡模式3、Mutex 允许自旋的条件的是什么?锁已被占用,并且锁不处于饥饿模式。积累的自旋次数小于最大自旋次数(active_spin=4)1.CPU 核数大于 12.有空闲的 P3.当前 Goroutine 所挂载的 P 下,本地待运行队列为空。4、RWMutex怎么实现?通过记录 readerCount 读锁的数量来进行控制,当有一个写锁的时候,会将读锁数量设置为负数 1<<30。目的是让新进入的读锁等待之前的写锁释放通知读锁。同样的当有写锁进行抢占时,也会等待之前的读锁都释放完毕,才会开始进行后续的操作。而等写锁释放完之后,会将值重新加上1<<30,并通知刚才新进入的读锁rw.readerSem两者互相限制。

分享工作生活随笔

只是因为自己不够优秀,所以只能风雨兼程,希望每天的成长,从我们彼此的分享开始。疫情当下,让我们先静心沉淀自己,当机会来临时能够一把抓的住。送给大家一句我很喜欢的话:“慢慢走,本来就很快。”,如果喜欢博主的文章请分享点赞加关注,欢迎投稿,加入Go必知必会,一起构建golang最强开放社区。

分享一个好用的包

github.com/ahmetb/go-linq/v3

用于数据的聚合,源于C#,贼像mysql的用法,用起来也很好使,有兴趣的可以B站找视频,或者看go-linq的文章,会很有收获。
文档地址:

https://pkg.go.dev/github.com/ahmetb/go-linq#section-documentation



相关文章
|
19天前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
Go 语言入门指南:切片
|
1月前
|
Go C语言
Go语言入门:分支结构
本文介绍了Go语言中的条件语句,包括`if...else`、`if...else if`和`switch`结构,并通过多个练习详细解释了它们的用法。`if...else`用于简单的条件判断;`if...else if`处理多条件分支;`switch`则适用于基于不同值的选择逻辑。特别地,文章还介绍了`fallthrough`关键字,用于优化重复代码。通过实例如判断年龄、奇偶数、公交乘车及成绩等级等,帮助读者更好地理解和应用这些结构。
39 15
|
3月前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。
|
4月前
|
存储 设计模式 安全
Go语言中的并发编程:从入门到精通###
本文深入探讨了Go语言中并发编程的核心概念与实践技巧,旨在帮助读者从理论到实战全面掌握Go的并发机制。不同于传统的技术文章摘要,本部分将通过一系列生动的案例和代码示例,直观展示Go语言如何优雅地处理并发任务,提升程序性能与响应速度。无论你是Go语言初学者还是有一定经验的开发者,都能在本文中找到实用的知识与灵感。 ###
|
4月前
|
Serverless Go
Go语言中的并发编程:从入门到精通
本文将深入探讨Go语言中并发编程的核心概念和实践,包括goroutine、channel以及sync包等。通过实例演示如何利用这些工具实现高效的并发处理,同时避免常见的陷阱和错误。
|
4月前
|
Go 数据安全/隐私保护 开发者
Go语言开发
【10月更文挑战第26天】Go语言开发
62 3
|
4月前
|
Java 程序员 Go
Go语言的开发
【10月更文挑战第25天】Go语言的开发
50 3
|
5月前
|
安全 Go 开发者
破译Go语言中的并发模式:从入门到精通
在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
|
5月前
|
存储 安全 Go
Go语言切片:从入门到精通的深度探索###
本文深入浅出地剖析了Go语言中切片(Slice)这一核心概念,从其定义、内部结构、基本操作到高级特性与最佳实践,为读者提供了一个全面而深入的理解。通过对比数组,揭示切片的灵活性与高效性,并探讨其在并发编程中的应用优势。本文旨在帮助开发者更好地掌握切片,提升Go语言编程技能。 ###
|
7月前
|
Unix Go
Go从入门到放弃之时间操作
Go从入门到放弃之时间操作