基于 Go 语言谈软件开发效率 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
kuanat
V2EX    Go 编程语言

基于 Go 语言谈软件开发效率

  •  
  •   kuanat 281 天前 3132 次点击
    这是一个创建于 281 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基于 Go 语言谈软件开发效率

    这个帖子的目的不是对比不同编程语言开发效率的高低。

    这个帖子实际上讨论的是以下内容:

    • 软件工程中生产力消耗的占比

    • 语言层面如何改善生产力的利用率

    • Go 有何特殊之处

    0x10 定义和量化生产力

    以代码行数来衡量程序员的产出是非常可笑的指标,同理,以代码复杂度、语法糖支持来评价开发效率也很离谱。

    如果一定要找一个量化指标来评价开发效率,那就是相同开发需求下所消耗的总人力。

    实际上,从理解业务需求开始,到构思实现方式和架构占据了写代码这个过程中绝大部分时间。

    如果考虑团队协作的一般场景,沟通成本又占据了团队人力消耗的一半(个人估计)。

    也就是说,纯代码层面的效率提升即便优化到极致,对于整个开发成本的改善贡献可能远低于 10%。

    0x20 编程语言真正的生产力

    0x21 沟通成本

    能看代码不求人才是最节省沟通成本的方式。

    这里的反例就是互联网与工程化兴起之前的各种语言,需要通过外部工具、团队规则才能保证有效协作的各种脚本语言。

    开发者讨厌屎山的深层原因还是代码不好读、不好改。

    0x22 可读性

    影响可读性的因素很多,这里简单列举几个:

    • 在没有 lsp 辅助的情况下,快速定位到方法的实现,即代码结构组织

    • 隐式控制流,在某些地方隐藏着初始化 init 逻辑,或者有非直接可见的构造、析构方法

    人脑的栈空间是非常有限的,间接、隐藏信息越多,理解成本越高。

    0x23 复用性

    往小的方面说,直接复制其他代码引入项目算是复用。往大的方面说,包引入机制也是复用。

    这里的重点是语言的官方仓库和工具链系统来一致化、规范化这个过程。

    缺少官方包管理、没有官方工具链的各种语言都深受其苦。

    0x24 编程范式与思想

    面向对象的思想就是某个阶段编程语言带来的巨大进步。

    在工程化成为现代语言标配的今天,组合替代继承也是巨大进步。

    关于这一点我在其他帖子里有零散的论述,这里就不展开了。

    0x30 Go 与生产力

    我觉得这个部分是误解最多的,大多数的讨论都没有关注到真正的重点。

    0x31 并发原语

    Go 最重要的贡献之一是基于 chan 的思维模型:Share memory by communication

    日常反复被强调的 goroutine 其实不重要,很多语言也可以有样学样。

    通过 chan/goroutine 的结合,初学者即便不理解 race/signal/thread/shared memory 等等概念,一样可以快速、准确地写出并发逻辑。

    0x32 显式控制流

    没有魔法就是编程语言对开发者最大的尊重。

    Debug 浪费的生产力往往会远超写代码的节省。

    0x33 原生 tls

    在网络编程的时代,原生 tls 才是真正的跨平台。

    技术上跨平台的核心是交叉编译,工程上,保证一条命令构建全平台、全指令集,最后的障碍就是原生 tls 。

    这里节省的是构建系统,一旦有了外部依赖,语言自身的工具链就不够用了。

    0x34 快速编译

    Go 从非常早期就是手搓编译器,而不是转换成 IL 交给通用编译器。缺点是各种语言特性、语法糖都会影响编译器的编写,优点是编译很快。

    人类的多线程能力很差,现实任务频繁上下文切换会极大降低工作效率。

    如果你曾经被 webpack 构建或者 rust 编译支配,你会理解快速编译、即时反馈的意义。

    PS

    这个帖子实际价值也就最后一个章节,还没有展开说。权当抛砖引玉,欢迎斧正。特地放到 Go 节点也是不想让话题沦为口水争论。

    15 条回复    2025-01-04 00:02:54 +08:00
    pursuer
        1
    pursuer  
       280 天前
    要说编译速度快,那脚本不是全秒了。
    按照现在的发展情况看,我怀疑如果 TC39 不开摆,除了 C/C++和 Rust ,其他语言生态最终都会被绑定了浏览器的 JS/TS 占据。即使 JS 是一个槽点很多的语言。JS 的拖累还有 NPM 和 Node 的 Native 扩展。
    ninjashixuan
        2
    ninjashixuan  
       280 天前
    我比较喜欢的一个点是 go 对文件、网络 io 的抽象,写起来很舒服。
    kuanat
        3
    kuanat  
    OP
       280 天前 via Android
    @pursuer #1

    编译速度说的是和编译类型的语言比,而且即使和 vm+jit 类型相比也是快的。

    JS 的整个生态都建立浏览器之上,能力的边界取决于浏览器实现了多少对操作系统的封装。

    如果一定要拿出数据作证的话,js 的份额一直就是在浏览器这个笼子里,别的进不来它也出不去。
    kuanat
        4
    kuanat  
    OP
       280 天前 via Android   1
    @ninjashixuan #2

    这里可能涉及到编程语言的设计哲学,即要在多大程度上暴露或者封装操作系统的抽象。

    在 go 看来,内核 fd 是没有抽象过的 Reader Writer Closer 有用的,这种用接口的实现方式是对“万物皆文件”非常好的诠释。

    同理,socket 相关的抽象也是一样。我个人认为这些都是有意的设计,最初就把跨平台作为目标之一,官方库就对如何封装如何抽象,实现哪些功能做了规划。

    所以很多人说 go 的设计定位是 better c ,但我认为这不是重点,语言层面做个 better c 不难,其他语言一样做得很好。像 c 一样把操作系统底层完全暴露出来是没用的,go 优于 c 同时抢占了部分 c 的市场的原因是它解决了 c 工程化的很多问题。
    zealot0630
        5
    zealot0630  
       280 天前 via Android
    不同语言在不同应用场景下能发挥的功能差距非常大,抛开应用场景谈效率毫无意义。

    没有最好的语言,只有最适合的语言。
    tonyjia87
        6
    tonyjia87  
       280 天前
    好奇的地方,资本对 go 的发力领域是否还有持续投入。 毕竟 java 太多沉淀,rust 太多声音,typescript 太多表现欲。
    pursuer
        7
    pursuer  
       280 天前
    @kuanat 如果真的只在浏览器范围的话,但现在个人 PC 已经成 Electron 宇宙了,移动端也是各种浏览器套壳,如果浏览器开放 Raw socket 和文件系统权限,加上 ServiceWorker 后台运行。感觉现在的工具类应用相当数量都会被 Web 化。

    作为特性,只和特定类型语言比没有意义。快速验证相关现在就是 python/js 这种脚本用的最多。
    kuanat
        8
    kuanat  
    OP
       280 天前 via Android
    @tonyjia87 #6

    对于编程语言来说,资本介入是好事。放在 1990 年可能还好,放到 2025 ,没有靠山的编程语言是没有生命力的。
    uSy62nMkdH
        9
    uSy62nMkdH  
       280 天前
    “相同开发需求下所消耗的总人力” 这是一个伪命题没有办法求证
    kuanat
        10
    kuanat  
    OP
       280 天前 via Android
    @pursuer #7

    这个讨论有点偏题了,我想表达的是浏览器相对于整个软件开发领域占比是有限的,这个数据无法支撑你得出“除 c 和 rust 之外被 js 占据”这样的结论。

    我把这个帖子发在 go 而不是程序员节点,目的也是真正讨论工程化和生产力的问题。隔壁帖子的争论 xx 语言的 yy 不好,是建立在真的要把 xx 语言用在所有场景这样一个隐含前提下的。然而现实的人类并不会拿一把锤子就把万物当作钉子。

    所以我不认为某种语言一统天下是个好事,这不符合我的技术哲学认知。
    lesismal
        11
    lesismal  
       280 天前   1
    > Go 最重要的贡献之一是基于 chan 的思维模型:Share memory by communication 。
    > 日常反复被强调的 goroutine 其实不重要,很多语言也可以有样学样。

    chan 挺好, 但本质上相当于个阻塞队列, 即使没有 golang, pipe/cond_t+mutex/sem 之类的传统的进程间通信/线程同步的这些也都能实现类似的阻塞队列组件. 但多进程多线程和这些 syscall 要么阻塞线程要么异步.

    Share memory by communication 更像是从 erlang/actor 拿来的, 但 golang 整个语言本身没有像 erlang 那样纯 actor.
    actor 是个太监模型, actor 之父是为了他们自家电信业务造的 erlang, 电信的那种每个 erlang 进程处理一个连接, 设备进行管理功能也不算复杂不需要连接之间有复杂的交互, 这种场景用 erlang 的进程通信比较简单.
    但纯 actor 并不适合于复杂的业务, 例如连接之间有复杂的交互.
    而且不管哪种 actor, 让一些即使很简单的交互,或者一些用普通的逻辑处理比较简单的交互, 也都强制必须用通信的方式, 都是需要数据拷贝/调度或者切栈上下文之类的, 这些都带来了额外的性能损失. 性能损失这一点, chan 也是类似的, 简单的有性能需要的功能, 用 chan 未必见得划算.

    runtime 基础之上:
    goroutine 让大家绝大多数时候能写同步代码, 这个解决了传统高并发高性能的 c/c++/java netty/nodejs 等语言的 callback 逻辑不直观和 callback hell 的问题.
    传统的进程间通信/线程同步 syscall 封装组件, 即使实现同步组件, 但阻塞的是进程/线程, 所以不能用 goroutine 与这些 syscall 结合来让大家写同步代码, 所以需要 chan 这种基于 runtime 的轻量阻塞队列实现.

    golang 标准库提供了个基于 runtime 的 cond_t 也可以自己封装下实现 chan 或者类似的组件, 但 chan 已经足够方便了, 我暂时想不到有需要自己搞这个的需要.
    从这些角度讲, 我觉得 goroutine 仍然是最重要的; chan 很好, 但是次之, 因为也有很多场景是不需要甚至不适合用 chan 的.
    kuanat
        12
    kuanat  
    OP
       280 天前 via Android
    @lesismal #11

    你说得非常对,我想了一下,还是 goroutine 更重要一些。

    如果拿 js 来做对比的话,很明显 js 努力的方向一直是用同步的方式写异步逻辑,经过了 promise 到 async/await 的迭代,但 go 这边就很符合直觉。

    另外性能在绝大部分场景不那么重要,可读性、效率和性能之间找个平衡点更重要。现在不是单体应用硬怼 c10k 的时代了。
    tonyjia87
        13
    tonyjia87  
       280 天前
    @kuanat 相信未来会很多公司尝试 go ,共建社区。 现在看比较知名的产物 docker ,kubernetes ,甚至核心成员写的 ollama ,知名的 hugo ,https://github.com/topics/go 前十似乎都是在搞隔离,交付。似乎 infrastructure 才是发力点,可能不准确但是占据多。
    lesismal
        14
    lesismal  
       280 天前
    > 如果拿 js 来做对比的话,很明显 js 努力的方向一直是用同步的方式写异步逻辑,经过了 promise 到 async/await 的迭代,但 go 这边就很符合直觉。

    对对, 非常同意. promise 对于很多人都是个坑, 因为看着是顺序的实际上不是本次 eventloop, 所以遇到 for 循环里的 promise 或者 promise 后面的逻辑, 其实都是违反时序直觉的, 很多新手遇到了 bug 都仍然难搞懂这个. async/await 虽然提供了, 但也是难于理解难于使用, 比 goroutine 自动档差远了
    phoulx
        15
    phoulx  
       280 天前
    #2 #4 毕竟 Go 承接自 Plan 9 ,真正「一切皆文件」的系统
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1234 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 17:23 PVG 01:23 LAX 10:23 JFK 13:23
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86