• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
golang的基础概念

何为runtime?

很多语言都有 Runtime

 go的runtime特点

  1. 没有虚拟机的概念
  2. Runtime 作为程序的一部分打包进二进制产物
  3. Runtime 随用户程序一起运行
  4. Runtime 与用户程序没有明显界限,直接通过函数调用

 

  • 内存管理能力
  • 垃圾回收能力(GC)
  • 超强的并发能力(协程调度)

 

总结:

  • Go 的 Runtime 负责内存管理、垃圾回收、协程调度
  • Go 的 Runtime 被编译为用户程序的一部分,一起运行

go的编译过程

 

 词法分析:

 

句法分析

 语义分析

 

 

中间码生成(SSA)

 

 

 机器码生成

  • 先生成Plan9汇编代码
  • 最后编译为机器码

 

 链接

  • 将各个包进行链接,包括runtime

 

go程序是如何运行的,是main()方法吗?

  • runtime/rt0 XXX.s

读取命令行参数

  • 复制参数数量 argc 和参数值 argv 到栈上

初始化 go 执行栈

  • g0 是为了调度协程而产生的协程
  • g0 是每个 Go 程序的第一个协程

调度器初始化 runtime.schedinit

  • 全局栈空间内存分配
  • 堆内存空间的初始化
  • 初始化当前系统线程
  • 算法初始化(map、hash)
  • 加载命令行参数到 os.Args
  • 加载操作系统环境变量
  • 垃圾回收器的参数初始化
  • 设置 process 数量

创建主协程

  • 创建一个新的协程,执行 runtime.main
  • 放入调度器等待调度

初始化M

  • 初始化一个 M,用来调度主协程

主协程执行主函数

  • 执行 runtime 包中的 init 方法
  • 启动 GC 垃圾收集器
  • 执行用户包依赖的 init 方法
  • 执行用户主函数 main.main()

总结:

  • Go 启动时经历了检查、各种初始化、初始化协程调度的过程
  • main.main()也是在协程中运行的

调度器是什么?
为什么初始化M?
为什么不是直接执行main.main(),而是将其放入调度器?

 

go语言是面向对象吗?


Go允许OO的编程风格

  • Go的Struct可以看作其他语言的Class
  • Go缺乏其他语言的继承结构
  • Go的接口与其他语言有很大差异


go的“类”

  • 其他语言中,往往用class表示一类数据class的每个实例称作“对象
  • Go中用struct表示一类数据
  • struct每个实例并不是“对象”,而是此类型的"值"
  • struct也可以定义方法


go的继承

  • Go并没有继承关系
  • 所谓Go的继承只是组合
  • 组合中的匿名字段,通过语法糖达成了类似继承的效果

go的接口

  • 接口可以定义Go中的一组行为相似的struct
  • struct并不显式实现接口,而是隐式实现


Go没有对象、没有类、没有继承

  • Go通过组合匿名字段来达到类似继承的效果
  • 通过以上手段去掉了面向对象中复杂而几余的部分
  • 保留了基本的面向对象特性

 

企业级go项目包管理

go包管理困境

  • 没有统一的包管理方式
  • 包之间的依赖关系很难维护
  • 如果同时需要一个包的不同版本,非常麻烦
  • 尝试使用 godep、govendor、glide 等解决
  • 未彻底解决 GOPATH 存在的问题
  • 使用起来麻烦

go modules

  • 本质上,一个 Go 包就是一个项目的源码
  • gomod 的作用:将 Go 包和 Git 项目关联起来
  • Go 包的版本就是 git 项目的 Tag

gomod 就是解决“需要哪个 git 项目的什么版本'、

  • 使用goproxy.cn作为代理
  • go env -w GOPROXY=https://goproxy.cn,direct

想用本地文件替代怎么办?

  • go.mod 文件追加:replace github.com/effail/tunny => xxx/xxx
  • go vender 缓存到本地
  • go mod vendor //不是之前的 go vendor

 

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/18593481

posted on 2024-12-08 16:02  孙龙-程序员  阅读(20)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3