当前位置: 首页 > news >正文

每日八股文

每日八股-5.29

  • Go
    • 1.Go语言中panic是什么?如何捕获?不捕获会发生什么?
    • 2.子协程panic,父协程会panic吗?
    • 3.Go协程和线程区别(分五个方面)
    • 4.Channel的底层实现
    • 5.Channel的应用场景
    • 6.Channel什么情况下会panic?
    • 7.Golang不关闭channel会怎样?
    • 8.容量为1的channel什么情况下会阻塞?
    • 9.Go的错误处理

Go

1.Go语言中panic是什么?如何捕获?不捕获会发生什么?

Panic是一种运行时错误,类似于其它语言中的异常,如果发生了数组越界或者空指针解引用就会报panic错误。通常使用defer匿名自执行函数加上recover来捕获panic,如果不捕获panic程序将直接终止运行。

package mainimport "fmt"func main() {defer func() {if r := recover(); r!= nil {fmt.Println("Recovered from panic:", r)}}()// 模拟可能发生panic的函数调用panicFunction()fmt.Println("After panicFunction call")
}func panicFunction() {fmt.Println("Before panic")panic("Something went wrong!")fmt.Println("After panic (this line will not be executed)")
}

2.子协程panic,父协程会panic吗?

如果在子协程内没有使用defer/recover来捕获异常,那么父协程就会受到影响,程序会终止运行,如果用了defer/recover来捕获异常,父协程可以继续正常执行下去,不受影响。

3.Go协程和线程区别(分五个方面)

  1. 调度器
    Go程用的是runtime,线程用的是操作系统的调度器,线程和携程是m:n的关系,一个线程可以通过处理器(GMP中的P)绑定多个协程
  2. 创建和销毁的开销
    Go程创建和销毁的开销要显著低于线程
  3. 占用内存的大小
    Go程的栈是动态伸缩的,占用空间较小,但线程是固定地,占用空间较大
  4. 异常处理
    Go程出现了异常可以通过当前的Go程去捕获,但线程若出现异常只能通过线程外的机制去捕获
  5. 同步通信
    Go程可以通过channel实现同步通信,而线程一般使用锁或者sync.cond实现同步通信

4.Channel的底层实现

核心是一个叫做hchan的结构体,包括以下字段(具体字段名称不知道,但知道每个字段都代表什么含义)

  1. 一个表示当前channel元素数量的字段(无缓冲区为0)
  2. 一个表示当前channel缓冲区大小的字段(无缓冲区为0)
  3. 一个指向当前channel环形队列的指针(无缓冲区为nil)
  4. 一个表示当前channel存储元素类型所占的字节数字段
  5. 一个表示当前channel存储元素数据类型的字段
  6. 一个指示当前channel下一个该发送数据的位置字段
  7. 一个指示当前channel下一个该接收数据的位置字段
  8. 待接收数据的goroutine队列
  9. 待发送数据的goroutine队列
  10. Mutex互斥锁
type hchan struct {qcount   uint           // 当前 channel 中元素的数量 (队列中的元素个数)dataqsiz uint           // channel 缓冲区的大小 (即 channel 的容量)buf      unsafe.Pointer // 指向 channel 缓冲区数据(一个环形队列)的指针elemsize uint16         // channel 中元素的字节大小closed   uint32         // channel 是否已关闭的标志,0 表示未关闭,1 表示已关闭elemtype *_type         // channel 中元素的类型(例如 int、string 等)sendx    uint           // 发送操作在缓冲区中的索引 (下一个发送数据的位置)recvx    uint           // 接收操作在缓冲区中的索引 (下一个接收数据的位置)// 等待发送的 goroutine 队列 (sendq)// 等待接收的 goroutine 队列 (recvq)// 这两个是 sudog 链表,sudog 代表一个等待的 goroutinerecvq    waitq          // 等待接收的 goroutine 队列sendq    waitq          // 等待发送的 goroutine 队列lock mutex // 保护 channel 所有字段的互斥锁
}// waitq 是 sudog 链表的头和尾
type waitq struct {first *sudoglast  *sudog
}// sudog 代表一个等待的 goroutine
// 包含指向 goroutine 和其相关数据的指针
type sudog struct {// ... 其他字段 ...g *g // 指向等待中的 goroutine// ... 其他字段 ...
}

5.Channel的应用场景

用来协调并发场景中不同的goroutine之间的通信,通过使用channel,一个goroutine可以向另一个goroutine发送数据,也可以接收数据,channel保证了goroutine之间可以安全的共享数据,并且避免了数据竞争问题。

6.Channel什么情况下会panic?

  1. 关闭nil的channel,(nil的channel不能做任何操作,读写打开关闭)

Ch:=new(chan int)
Close(*Ch)

这里又牵扯到了make和new的区别,可以一起记忆(比如为什么是*Ch)

  1. 关闭已经关闭的channel
  2. 向已经关闭的channel写数据
    但是可以从已经关闭的channel读取数据,因为有缓冲区

7.Golang不关闭channel会怎样?

  1. 如果遍历未关闭的channel,会造成死循环
  2. 通过close()关闭后,不能再往channel里面写数据,但是可以从channel的缓冲区里读数据
  3. 不需要通过手动关闭channel来释放资源,当没有goroutine用到channel时,channel会自动回收

8.容量为1的channel什么情况下会阻塞?

当channel已经有数据时,再往channel里面发送数据就会造成发送方阻塞,直到有新的接收方来接收数据

9.Go的错误处理

Go 语言中把错误当成一种特殊的值来处理,不支持其他语言中使用try/catch捕获异常的方式。

Go 语言中使用一个名为 error接口来表示错误类型。

type error interface {Error() string
}

如果需要自定义 error,最简单的方式是使用errors包提供的New函数创建一个错误。

// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {s string
}
func (e *errorString) Error() string {return e.s
}

我们还可以自己定义结构体类型,实现error接口

// WrapError 自定义结构体类型
type WrapError struct {s string
}
// WrapError 类型实现error接口
func (e *WrapError) Error() string {return fmt.Sprintf("err:%s", e.s)
}

相关文章:

  • 吉林大学操作系统上级实验四(hash存储讲解及顺序存储文件管理实现)
  • 图像数据与显存
  • 宝塔安装WordPress程序
  • Python打卡第39天
  • 嵌入式学习笔记 - freeRTOS任务优先级抢占,时间片抢占的实现机制
  • 330130-045-00-00 Bently Nevada 3300 XL延长电缆
  • 小白成长之路-Linux日志管理
  • 【最小生成树】Prim 算法、Kruskal 算法
  • 数据中台系统是什么意思?如何实现数据中台的搭建?
  • CPU中断频繁导致红外信号失真:问题分析与解决方案
  • npm run build 报错:Some chunks are larger than 500 KB after minification
  • siglip2(2) Naflex模型的动态分辨率原理
  • STM32F103_Bootloader程序开发05 - Keil修改生成文件的路径与文件名,自动生成bin格式文件
  • InnoDB中的锁
  • 第三章:地下三层的技术遗产
  • MySQL ALTER TABLE 组合操作时导致的错误
  • LoadRunner 是什么
  • 打卡day39
  • Shell 脚本基础笔记
  • 车载通信网络 --- CAN FD与CAN XL
  • 无极平台网站/网站建设营销推广
  • 有专门做辩论的网站吗/营销推广的特点是
  • 服装网站建设项目规划/网站服务器速度对seo有什么影响
  • 旅游网站wordpress/设计网站官网
  • 襄阳建设局网站/全自动引流推广软件
  • 网站的mysql数据库放到服务器上服务器需要安装mysql吗?/百度云搜索引擎