欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 【每日八股】Golang篇(一):概述

【每日八股】Golang篇(一):概述

2025/3/12 20:26:12 来源:https://blog.csdn.net/Coffeemaker88/article/details/146126550  浏览:    关键词:【每日八股】Golang篇(一):概述

目录

  • 进程、线程、协程的区别?
  • goroutine 相比线程的优势?
  • go 与 Java 的区别?
  • go 如何实现继承?
  • init 函数什么时候执行?

进程、线程、协程的区别?

进程:进程是每一次程序动态执行的过程,是程序运行的基本单位。进程占据独立的内存,有内存地址和自己的堆,挂靠与操作系统。操作系统以进程为单位进行资源分配,进程是资源分配的最小单位。

线程:线程又称轻量级线程,是 CPU 调度的最小单元。线程隶属于进程,是程序的实际执行者,一个进程至少包含一个主线程,可以有多个子线程。线程会共享所属进程的资源,同时线程拥有自己的独占资源。线程切换和线程间通信主要通过内存共享(比如加锁),上下文切换很快(因为同一个进程内的线程共享资源),资源开销较少,但是相比于进程而言不够稳定,容易丢失数据。

协程:协程是一种用户态的轻量级线程,协程的调度完全由用户控制。一个线程可以有多个协程,协程不被操作系统内核管辖,而是由用户控制

区别

  • 资源占用:进程是操作系统分配资源的最小单位,因此线程本身不占有资源,它可以访问其所隶属的进程的资源。进程所维护的是程序所包含的静态资源,比如:地址空间、打开的文件句柄集、文件系统状态、信号处理等;线程维护的是与程序运行相关的资源,即动态资源,包括:运行栈、调度相关的控制信息、待处理的信号集等。【或者说,进程维护的是资源,线程维护的是状态】
  • 并发性:不仅进程可以并发,同一个进程的多个线程也可以并发。
  • 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些
  • 协程和线程:协程避免了无意义的调度,由此可以提高性能,但是用户调度的过程中存在风险。

goroutine 相比线程的优势?

Goroutine 相较于传统线程而言有以下优点:

  1. 轻量级内存占用,goroutine 的初始栈为 KB 级别,可动态拓展,而线程栈通常在 MB 级别,因此使用 goroutine 可以轻松创建百万级的 goroutines;
  2. 快速创建销毁:goroutine 的创建耗时约为 300ns,且由于完全由用户态管理,故无系统调用的开销;
  3. 高效调度机制:单个线程可处理数万 goroutine,上下文切换成本约 200ns;
  4. 智能处理阻塞:goroutine 阻塞时,运行时会自动创建其它新线程处理其它 goroutine,避免线程级阻塞导致的资源浪费;
  5. 通信更安全:goroutine 采用原生 channel 替代共享内存;
  6. 资源利用率优化;

典型对比数据

  • 10万并发连接:Goroutine 消耗≈200MB内存,线程模式需要≈100GB;
  • 上下文切换吞吐量:Go 调度器比 OS 调度器高 5-10倍;

go 与 Java 的区别?

  • 运行:go 是静态编译语言;Java 基于类的面向对象语言,Java 应用程序在 JVM 上运行。
  • 函数重载:go 上不允许函数重载,必须具有方法和函数的唯一名称;java 允许函数重载。
  • 多态:Java 默认允许多态,而 go 没有。
  • 路由配置:go 语言使用 HTTP 协议进行路由配置;java 使用 Akka.routing 进行路由配置。
  • 继承:go 的继承通过匿名组合完成(也就是 struct 当中的嵌入),基类以 Struct 的方式定义,子类只需要把基类作为成员放在子类的定义中,支持多继承;Java 的继承通过 extends 关键字完成,不支持多继承。

go 如何实现继承?

通过 struct 当中的嵌入来实现类似于继承的效果。

init 函数什么时候执行?

特点

  • init函数先于main函数自动执行,不能被其他函数调用。
  • init函数没有输入参数、返回值。
  • 每个包可以有多个init函数,包的每个源文件也可以有多个init函数。
  • go没有明确定义同一个包的init执行顺序,编程时程序不能依赖这个执行顺序。
  • 不同包的init函数按照包导入的依赖关系决定执行顺序。

作用

  • 初始化不能采用初始化表达式初始化的变量。
  • 程序运行前的注册。
  • 实现sync.Once功能。

执行顺序
go程序初始化先于main函数执行,由runtime进行初始化,初始化顺序如下:

  • 初始化导入的包,包的初始化顺序并不是按导入顺序执行的,runtime需要解析包依赖关系,没有依赖的包最先初始化。
  • 初始化包作用域的变量,runtime解析变量依赖关系,没有依赖的变量最先初始化。
  • 执行包的init函数。

最终的初始化顺序:变量初始化 → \rightarrow init() → \rightarrow main()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词