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



相关文章
|
23天前
|
Unix Go
Go从入门到放弃之时间操作
Go从入门到放弃之时间操作
|
23天前
|
机器学习/深度学习 移动开发 Linux
Go从入门到放弃之文件操作
Go从入门到放弃之文件操作
|
23天前
|
Java Go PHP
Go从入门到放弃之错误处理
Go从入门到放弃之错误处理
|
23天前
|
存储 Java Go
Go从入门到放弃之结构体(面向对象)
Go从入门到放弃之结构体(面向对象)
|
23天前
|
存储 机器学习/深度学习 设计模式
Go从入门到放弃之函数
Go从入门到放弃之函数
|
23天前
|
Go C语言 索引
Go从入门到放弃之流程控制
Go从入门到放弃之流程控制
|
23天前
|
Go 计算机视觉
Go从入门到放弃之指针
Go从入门到放弃之指针
|
23天前
|
存储 Go 容器
Go从入门到放弃之map(字典)
Go从入门到放弃之map(字典)
|
23天前
|
人工智能 编译器 Go
Go从入门到放弃之数组、切片
Go从入门到放弃之数组、切片
|
23天前
|
存储 编译器 Go
Go从入门到放弃之数据类型
Go从入门到放弃之数据类型