谁是虽好的语言 ?- 语言选型闲聊(下)

简介: 近期我们公司做架构升级,调研了一下各种语言, 包括TypeScript,c#,rust, 还有java和go。这个过程中有一些个人看法,可能会有些偏颇或者不正确的地方,我就简单一说,大家一乐,无意引战。

大家好,我是肖恩,源码解析每周见


近期我们公司做架构升级,调研了一下各种语言, 包括TypeScript,c#,rust, 还有java和go。这个过程中有一些个人看法,可能会有些偏颇或者不正确的地方,我就简单一说,大家一乐,无意引战。


在上篇中,我简单介绍了一下游戏行业的一些技术栈特点,以及python,Typescript和c#三种语言的使用感受,没有看过的同学可以去看看链接。本文继续介绍go和java,rust的故事。


go 语言



Go 是一种开源编程语言,可以轻松构建 简单、可靠且高效的软件。Go 语言诞生于 2009 年,由google开源,发展到今天已经有过去了10 多年。伴随着云原生的发展,Go语言也是轰轰烈烈红红火火;许多知名的框架,docker,Kubernetes,etcd等都是使用go实现。国内最近的新闻是字节这样的大厂全面拥抱,很多培训机构也在推各种go课程,一切看着都很不错。


我们先简单感受一下,编写下面的的main.go:


package main
import "fmt"
func main() {
  fmt.Println("Hello, 世界")
}
复制代码


直接运行这个hello程序:


# go run main.go
Hello, 世界
复制代码


分别使用下面3个命令,将hello编译成对应操作系统的可执行程序:


GOOS=darwin GOARCH=amd64 go build -o hello_mac
GOOS=linux GOARCH=amd64 go build
GOOS=windows GOARCH=amd64 go build
复制代码


查看各自的编译结果:


➜  file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=YPrL0x5YX4DVXlh5kkKE/Y2HJXrRQkDsOpEXTVASf/NrLBfe3AB23u7MFL1ITI/GpLRUEatK4FJEmJ8Q5mW, not stripped
➜  file hello.exe
hello.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
➜  file hello_mac
hello_mac: Mach-O 64-bit executable x86_64
复制代码


在mac下可以直接执行hello_mac:


➜  hello ./hello
zsh: exec format error: ./hello
➜  hello ./hello.exe
zsh: exec format error: ./hello.exe
➜  hello ./hello_mac
Hello, 世界
复制代码


这种不需要虚拟机/解释器环境,可以直接执行的能力非常强大。


我自己接触go大概是14年的样子,那时候大概看的是beego的作者Asta谢的书吧。可惜在当时看来感觉go是一个很语法诡异的语言,还不如php/java省事。第二次接触是19年,因为要临时支援一个项目,同时又因为对docker,k8s的学习,了解了go的社区发展,觉得这会是一个很有前景的语言。奈何后来项目变动,又没有继续深入下去。最近算是第三次接触吧,先是写了一些小工具和小服务,计划会写一点网关服务,应该有机会深入下去。无独有偶,发现也有和我感觉类似的同学,我直接摘录在下面:


from draveness


作者目前也使用 Go 语言作为日常开发的主要语言,虽然 Go 语言没有 Lisp 系语言的开发效率和强大表达能力,但是却是一门非常容易使用并且大规模运用的工程语言,这也是作者学习和使用 Go 语言的主要原因。


作者是从 2018 年才开始学习和使用 Go 语言的,刚刚接触 Go 语言时是有些排斥和拒绝的,一度认为 Go 语言 GOPATH 的设计非常诡异,而简单的语法也导致了低下的表达能力并且影响开发效率。但是随着对 Go 语言的深入学习和理解,作者的这一观念也在不断改变。


到了今天,作者认为我们在工业界需要这么一门语法简单的编译型语言,它能够提供简单的抽象和概念,虽然目前 Go 语言也有很多问题,但是语言以及周边工具的不断完善也让作者感受到了社区的活力,也坚定地认为这门语言未来的发展会越来愈好。


学go时候需要一定的适应期。比如下面一段代码:


# gin/context.go
func (c *Context) GetString(key string) (s string) {
  if val, ok := c.Get(key); ok && val != nil {
    s, _ = val.(string)
  }
  return
}
复制代码


代码理解起来不难,从一个context中取一个key的值后转换成字符串返回。不同的地方在:


  • if val, ok := c.Get(key); ok && val != nil {...} 这样的三段式结构,这种语法几乎遍布在go的任何函数。这是因为go没有try/catch语法,所有的函数都要做异常判断。
  • (c *Context) 这样的接口实现方式,和面向对象的接口实现有很大的差别。


初期看go的代码,会感觉非常别扭,渡过适应期后,就觉得这种实现方式也没什么问题。然后再陷入go并发不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存的坑中。


go的学习过程,大概就像是windows电脑使用简单还是mac电脑使用简单的争论,是一个打破先入为主印象的问题。


java和rust



java不用介绍了,工业界的霸主,大厂的最爱。优点非常多,缺点嘛,主要就是个人不精通,已经放弃。


Rust是一门赋予每个人构建可靠且高效软件能力的语言。Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务。Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。看着是真棒。


我对rust的了解只是浅尝辄止,因为大家都说它上手难度极高。其中所有权的概念,是其核心功能也是核心阻碍。简单举例一下:


let s1 = String::from("hello");
let s2 = s1;
println!("{}, world!", s1);
复制代码


类似上面代码在其它语言中都可以正常运行,就是把s1赋值给s2,然后打印s1。不管是浅拷贝还是深拷贝,只会涉及性能问题,不会执行错误。但是在rust中却是无法执行成功的,因为rust认为s1赋值s2后,s1不再使用了,应该被销毁,这大概就是所有权的概念。


语言生态



语言的学习,前面介绍的内容,都是语法层面。一般来说还涉及语言的生态或者社区,我自己简单归纳语言生态包括下面几个部分:


image.png


学习语言的语法后,需要了解语言如何执行。比如python,就需要了解cpython的解释器,了解GIL,了解GC;java需要做JVM的调优,要熟练掌握某种编程语言,仅仅会语法显然是不够的。不同的语言,一般还有不同的IDE工具,比如c#大家惯用的是Visual Studio,熟练使用IDE工具,才可以提高研发效率。虽然现在VSCode,也还不错,但是如果不安装插件,不太好用,安装插件,对新手又不够友好。最好的办法,还是使用jetbrains家的工具,pycharm,rider,goland都是神器。我们还需要学习语言的包管理工具,这样才可以利用于同语言的各种库,站在开源的肩膀上。


语言的社区也是非常重要的一环。首先就是文档,是否有足量的文档去介绍各种语法细节,并且是否有中文文档,对语言学习入门有很大的帮助。我个人比较习惯,中英文文档对照着看,中文看的快,对一些感觉中文介绍不太顺的地方,再从英文中对比理解。然后就是是否有足够多的开源项目,可以去使用,有杀手级的应用可以去参考。开源项目够足,编程实现的时候才会便捷,一般工作都是搬砖,不用从沙子开始造起。


学习语言也是为了工作,除了语言自身的情况,还要考虑一下招聘市场和人才市场。招聘市场可以从岗位的数量和薪资情况反映,下面是一个语言及工资情况的统计数据:


image.png


注意: 贴图仅仅示意,并不代表真实的数据


人才市场可以从语言的流行度反映, 比如TIOBE2019-2020年的语言流行度排名:


image.png


从上图看Java和Python都还不赖。我个人把各种语言总结成下表:


语言 语法 环境 包管理 社区 适合领域 个人推荐
python 简单 cpython/pypy pip 丰富 应用广泛:爬虫,数据分析,后端服务,AI等 ⭐️⭐️⭐️⭐️
typescript 简单 node&&v8 npm 丰富 推荐前端应用,或者基于前端的全栈 ⭐️⭐️⭐️
c# 中等 dotnet nuget 丰富 游戏制作 ⭐️⭐️⭐️
go 特别 - go-mod 丰富 云原生服务 ⭐️⭐️⭐️⭐️
java 中等 jvm maven 丰富 anywhere ⭐️⭐️⭐️
rust 特别 - crates 一般 高性能网络服务,WebAssembly,嵌入式 ⭐️⭐️⭐️⭐️


在学习和了解各种语言的语法,对自己的编程能力提升有帮助,可以开阔不少视野。大家关注不同语言应该重点放在这一块, 对于语言的生态,除非打算用来工作,否则不建议深入,因为不用就会忘记,简单了解即可。带着思考去学习不同语法,比如下面一个python函数:


def readme(a, b):
    with open('README.rst', 'w') as f:
        c = 1
        a = a+c;
        b.append("b2")
        f.write(a)
        f.write(b)
    print(a, c)
    return b
复制代码


我们可以思考下面几个问题:


  • 参数a和b的类型
  • 入参和出参
  • 参数的值传递和引用传递
  • b的值和引用
  • f,c,a的作用域
  • 函数是否有返回值,可以返回几个值
  • 如果函数是一个类/接口的实现,语法上又应该如何表示?


上面这几个问题,在不同的语言上,都有不同的实现或者表达方式,多看看就会更加理解函数的本质。


最后的最后,还是推荐大家学习一下c,毕竟这个是鼻祖,是历史,其它语言都是从这个根上派生而来。


参考链接




目录
相关文章
|
前端开发 Java 关系型数据库
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
900 0
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
|
数据采集 UED Python
如何应对动态图片大小变化?Python解决网页图片截图难题
随着互联网技术的发展,电商平台如京东(JD.com)广泛采用动态内容加载技术,给爬虫获取商品图片带来挑战:图片无法直接保存,尺寸动态变化,且存在反爬机制。本文介绍如何利用Python结合代理IP、多线程技术解决这些问题,通过Selenium和Pillow库实现动态网页图片的屏幕截图,有效绕过反爬措施,提升数据抓取效率和稳定性。具体步骤包括设置代理IP、使用Selenium抓取图片、多线程提升效率以及设置cookie和user-agent伪装正常用户。实验结果显示,该方法能显著提升抓取效率,精准截图保存图片,并成功绕过反爬机制。
375 2
|
9月前
|
机器学习/深度学习 人工智能 数据可视化
1.4K star!几分钟搞定AI视频创作,这个开源神器让故事可视化如此简单!
story-flicks 是一个基于AI技术的自动化视频生成工具,能够将文字剧本快速转化为高质量短视频。开发者@alecm20通过深度学习算法,实现了从文本解析到视频合成的全流程自动化处理,支持多平台适配输出,是内容创作者和自媒体运营者的效率神器。
523 0
|
11月前
|
编解码 前端开发 算法
R中单细胞RNA-seq分析教程 (7)
R中单细胞RNA-seq分析教程 (7)
376 20
R中单细胞RNA-seq分析教程 (7)
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
2245 1
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
339 5
|
Linux
langchain 入门指南 - 使用提示词模板
langchain 入门指南 - 使用提示词模板
580 1
|
JavaScript 数据处理
如何使用 Vue.js 将数据对象的值放入另一个数据对象中?
如何使用 Vue.js 将数据对象的值放入另一个数据对象中?
|
设计模式 数据采集 程序员
代码整洁之道--告别码农,做一个有思想的程序员
代码整洁是软件长期稳定和可扩展的基础,本文作者从现实中的代码、重构、设计模式谈论代码整洁之道,总结出如何做一个有思想的程序员。
131703 58
|
Kubernetes 应用服务中间件 调度
kubernetes最小调度单元pod详解(一)
kubernetes最小调度单元pod详解(一)
374 0