标签 泛型 下的文章

Go,15岁了[译]

本文永久链接 – https://tonybai.com/2024/11/12/go-turns-15

虽然迟到了,但绝不缺席!新任Go技术负责人Austin Clements在Go语言15岁生日后的第二天,在Go官方博客上发表了庆祝文章“Go Turns 15”。在这篇文章中,Austin回顾了过去一年Go项目和社区的变化,以及Go团队的努力工作,并对Go的未来发展进行了展望。我在此对这篇庆生文进行了翻译,供大家参考。


Go,生日快乐!

周日,我们庆祝了Go开源15周年

自从Go诞生10周年以来,无论是Go语言本身还是整个世界都经历了巨大的变化。尽管如此,有些方面依然保持不变:Go始终致力于稳定性、安全性,以及支持软件工程和大规模生产

Go语言发展势头强劲!在过去五年中,Go的用户群增加了三倍多(译注:不知道这个数据从何而来),成为增长最快的编程语言之一。自十五年前诞生以来,Go已成为十大编程语言之一,并成为现代云计算的主要语言


来自TIOBE 2024年11月排行榜(译者配图)


来自Github Octoverse 2024(译者配图)

随着Go 1.22版本在二月份发布和Go 1.23版本在八月份发布,这一年可被称为“for循环之年”。Go 1.22将for循环中引入变量的作用域改为每次迭代,而非整个循环,从而解决了一个长期存在的语言“陷阱”。十多年前,在Go 1发布之前,Go团队对几个语言细节做出了决策,其中就包括for循环是否应该在每次迭代中创建一个新的循环变量。有趣的是,这次讨论非常简短且没有明确的意见。Rob Pike以他一贯的风格结束了讨论,只说了一个字:“stet”(保持原样)。结果也确实如此。尽管当时看似微不足道,但多年的生产经验突显了这一决策的影响。然而,在此期间,我们还构建了强大的工具来理解对Go的变更影响,特别是在整个Google代码库中进行生态系统范围的分析和测试,并建立了与社区合作和获取反馈的流程。在经过广泛的测试、分析和社区讨论后,我们推出了这一变更,并配备了哈希二分工具,以帮助开发者在大规模代码中精确定位受影响的部分。

对for循环的变更仅是是五年演进调整的一部分。这一变更的实现得益于Go 1.21中引入的向前兼容性,而这又建立在四年半前Go 1.14发布的Go模块基础之上。

译注:Go module首次在Go 1.11版本由Russ Cox设计和实现,Go 1.14版本首次宣布Go module具备生产使用的成熟度了。

Go 1.23在此变更的基础上进一步引入了迭代器和用户定义的for-range循环。结合仅仅两年半前在Go 1.18中引入的泛型!——这为自定义集合和许多其他编程模式奠定了强大而人性化的基础。

这些版本还带来了许多生产就绪方面的改进,包括备受期待的标准库HTTP路由器增强执行跟踪的全面重构,以及为所有Go应用程序提供更强的随机性。此外,我们的第一个v2标准库包的引入为未来的标准库演进和现代化建立了模板。

在过去的一年中,我们还谨慎地推出了Go工具的自愿使用的遥测系统。该系统将为Go开发者提供数据,以便他们做出更好的决策,同时保持完全开放和匿名。Go遥测最初出现在gopls(Go语言服务器)中,已经带来了许多改进。这项努力为使Go编程体验变得更加出色奠定了基础。

展望未来,我们正在不断演进Go,以更好地利用当前和未来硬件的能力。在过去的15年中,硬件发生了巨大的变化。为了确保Go能够在接下来的15年中继续支持高性能、大规模的生产工作负载,我们需要适应大型多核处理器、先进的指令集,以及在non-uniform内存层次结构中日益重要的局部性。其中一些改进将是透明的。Go 1.24将推出全新底层实现的map,以提高在现代CPU上的执行效率。同时,我们正在进行新的垃圾回收算法的原型设计,以适应现代硬件的能力和限制。一些改进将以新的API和工具的形式出现,以便Go开发者更好地利用现代硬件。我们正在研究如何支持最新的向量和矩阵硬件指令,以及应用程序如何构建CPU和内存的局部性。指导我们努力的一个核心原则是可组合优化(composable optimization):优化对代码库的影响应该尽可能局部化,以确保对其余代码库开发的便捷性不受影响。

我们将继续确保Go的标准库在默认情况下是安全的,并在设计上也考虑到安全性。这包括不断努力将内置的、原生支持的FIPS认证加密功能纳入其中,使得需要FIPS加密的应用程序只需简单切换一个命令行标志即可使用。此外,我们还在不断改进Go的标准库包,并借鉴math/rand/v2的例子,考虑在哪里可以引入新的API,以显著提高编写安全和可靠的Go代码的便利性。

我们正在努力使Go在人工智能领域表现更好,同时也让人工智能更好地服务于Go,增强其在AI基础设施、应用程序和开发者辅助工具方面的能力。Go是一种非常适合构建生产系统的语言,我们希望它也能成为构建生产级AI系统的优秀语言。作为云基础设施的可靠语言,Go自然成为大型语言模型(LLM)基础设施的理想选择。针对AI应用,我们将继续在流行的AI SDK中为Go提供一流的支持,包括LangChainGoGenkit。从一开始,Go就旨在改善端到端的软件工程过程,因此我们自然希望引入AI的最新工具和技术,以减少开发者的重复劳动,从而留出更多时间来进行更有趣的编程活动!

感谢您!

所有这一切的实现都离不开Go的杰出贡献者和蓬勃发展的社区。十五年前,我们只能憧憬Go所取得的成功以及围绕Go发展起来的社区。感谢每一位参与其中的人,无论贡献大小。我们祝愿大家在新的一年里一切顺利!


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily
  • Gopher Daily Feed订阅 – https://gopherdaily.tonybai.com/feed

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

认知负荷对编程语言选择和学习的影响

本文永久链接 – https://tonybai.com/2024/10/24/cognitive-load-impact-on-programming-language-choice-and-study

在《Go语言精进之路:从新手到高手的编程思想、方法和技巧》两卷书出版后,我收到了一些读者的反馈。其中一位读者提到:“为什么作者如此偏爱使用心智负担这个词?”当时我对此并未给予太多关注。然而,近期我阅读了一些关于认知心理学和脑科学的著作后,才意识到读者的反馈不仅仅是对该词频繁使用的关注,更可能暗示了用词不当的问题。

“心智负担”(Mental Load)指的是在处理多任务或日常生活安排时所需耗费的心理资源和精力,包括记忆、计划、组织以及应对各种任务所带来的精神压力。然而,在学习、思考和理解的情境中,特别是在编程语言的学习中,使用“认知负荷”(Cognitive Load)这一术语可能更为恰当。

认知负荷理论最初由澳大利亚新南威尔士大学的认知心理学家约翰·斯威勒(John Sweller)于1988年首先提出来的,旨在解释学习过程中的认知资源分配。认知负荷是指在学习、思考或解决问题时,大脑在处理信息和执行任务时所承受的负担。在选择编程语言时,认知负荷是一个至关重要的因素,指的是人们在学习和使用某种编程语言时,为理解语法、掌握工具和解决问题所需付出的心理负担和精力。

那么,在面对众多主流编程语言时,在不考虑市场需求与公司或组织强制学习的情况下,认知负荷究竟如何影响开发人员对编程语言的选择呢?在这篇文章中,我将进行一些不那么严谨,也非专业的粗略探讨,希望能够为大家带来一些启发。

1. 认知负荷在编程语言中的体现

认知负荷理论发展到今天,其总体被分为三种类型:

  • 内在认知负荷(Intrinsic Cognitive Load)

内在认知负荷,也称为固有负荷,是由学习材料本身的复杂性所决定的,它与学习任务的本质和内容密切相关。例如,编程语言的语法规则、数据类型内存管理并发模型等都是内在负荷的一部分。学习这些概念的难易程度主要取决于编程语言本身的设计和复杂度。

  • 外在认知负荷(Extraneous Cognitive Load)

外在负荷是由学习环境和教学方式引起的负担,通常是由于无关信息或低效的学习方法造成的。比如,配置开发环境、学习非必要的工具或被复杂的IDE界面困扰,都可能增加外在负荷。在编程语言学习中,清晰的文档和易于理解的教程可以显著减少外在负荷。

虽然外在负荷不是由编程语言语法本身决定的,但它会影响新手的学习体验。如果学习资源和工具太复杂或不直观,即使是简单的编程语言也会让人感到困难。

  • 相关认知负荷(Germane Cognitive Load)

相关认知负荷是指学习过程中专门用于理解、整合和构建知识结构的认知努力。它与思维加工、模式识别、知识内化等过程有关。在编程中,相关认知负荷指的是学习者在掌握编程思想、设计模式和编程习惯时所付出的努力。例如,理解如何在实际项目中应用编程概念,如何优化代码设计,以及如何解决编程中的复杂问题,这些过程都会增加相关认知负荷。这种负担是积极的,因为它有助于深入理解和长期记忆。

下面这张图来自网络,可以帮助我们进一步理解三类认知负荷(只是出发点来自教学角度):

由此可见,对于新手来说,学习一门编程语言时,外在认知负荷是第一道门槛,它决定了是否能坚持学习,还是选择“Hello and Bye”;内在认知负荷则是基础,是核心;相关认知负荷则是进阶挑战,决定了可以达到的高度

接下来,我们将针对一些主流编程语言,沿着新手入门学习编程语言的认知负荷先后顺序进行粗略对比。希望这能为大家提供在编程语言选择方面的有用信息,同时帮助不同阶段的学习者针对各自的认知负荷水平做好心理准备。

2. 主流编程语言的认知负荷对比

在探讨主流编程语言的认知负荷时,我们需要从外在认知负荷、内在认知负荷以及相关认知负荷这三个维度进行深入分析。这种分析不仅能帮助我们理解不同语言的特点,更能为选择合适的编程语言提供参考依据。

注:笔者是后端程序员出身,对前端语言比如Javascript、Typescript等了解有限,因此这里将使用像Go、Rust、C++等主流后端语言作为分析和对比的参考对象。

2.1 外在认知负荷的影响

在编程语言学习的初始阶段,外在认知负荷往往是最先遇到的挑战

Python在这方面表现出色,它简单的环境搭建流程让初学者能够快速开始编程之旅。只需安装一个解释器,新手就能立即开始编写代码。虽然在使用pip管理依赖时可能遇到一些包冲突的问题,但整体来说,在环境搭建、工具使用等外在认知负荷方面对初学者相当友好。

Go语言同样提供了令人称道的开发体验。它的工具链安装过程直观明了,跨平台支持也十分完善。特别值得一提的是,自从Go 1.11引入go modules以来,依赖管理变得更加自动化和直观。虽然对新手来说,理解版本控制可能需要一些时间。此外,Go团队也给出了Go项目布局的官方建议,为开发者进行代码组织提供了清晰的参考。

相比之下,C++的环境搭建则显得较为复杂。开发者需要安装编译器,配置IDE,这些步骤对新手来说都构成了不小的挑战。加上缺乏统一的包管理工具(尽管vcpkgconan等工具正在改变这一现状),以及灵活但缺乏标准的项目结构,都让C++的外在认知负荷明显高于其他语言。

Rust通过其官方工具链安装工具rustup提供了相对简便的环境搭建方式。它的Cargo包管理器集成度高,使用便捷,而且项目结构的标准化程度高,这些特点都有效降低了外在认知负荷。

Java则介于两个极端之间。它需要安装JDK并配置环境变量(如JAVA_HOME、CLASS_PATH等),这个过程对新手来说可能有些繁琐。虽然Maven和Gradle这样的依赖管理工具功能强大,但学习曲线较陡峭。不过,Java严格的项目布局规范在初期可能显得死板,但从长远来看反而有助于培养良好的工程习惯。

过了环境安装、工具使用和项目布局这些“外在认知负荷”的关卡后,语言自身的复杂性便会成为新手面前的更大的挑战。

2.2 内在认知负荷考量

谈到语言本身的复杂性,Python的设计理念“简单胜于复杂”使其成为认知负荷最低的选择之一。它的语法接近自然语言,几乎不需要特别的学习就能读懂基本的代码结构。这种简洁性使得Python特别适合编程初学者,以至于主流的儿童编程教学大多使用Python(当然一些启蒙教学使用的是scratch)。

Go语言同样以简洁著称,它的语法设计注重一致性和可读性。虽然保留了指针这样的底层特性,可能会让某些初学者感到困惑,但整体而言,Go的学习曲线相当平缓。值得注意的是,Go 1.18引入泛型后,虽然提升了语言的表达能力,但也增加了一定的复杂性。至于Go是否适合作为从零开始编程的新手,也是见仁见智。

C++的内在认知负荷则明显较高。它支持多种编程范式,包括面向过程、面向对象、模板编程等,这些范式和特性固然强大,但对初学者来说往往构成了较大的认知负担。特别是在处理多态、模板元编程等高级特性时,学习曲线会变得异常陡峭。

Rust的内在认知负荷同样不低,但事实证明其复杂性是有意义的。它的所有权系统和借用检查器虽然增加了学习难度,但这些机制对于理解系统编程的本质非常有帮助,同时提高了程序在运行时的安全性。新手在最初接触这些概念时可能会感到困惑,但掌握后会对内存安全有深刻的理解。

Java的内在认知负荷介于中等水平。它的面向对象语法虽然比Python或Go略显繁琐,但整体而言还算直观。Java的复杂性主要体现在面向对象设计模式、泛型和异常处理等特性上,这些概念需要时间来消化和掌握。

2.3 相关认知负荷的深入分析

在实际应用知识解决问题时,各种语言呈现出不同的特点。

Python的优势在于它能让学习者快速将知识付诸实践。其丰富的标准库和生态、简洁的语法使得从学习到应用的过程异常顺畅。无论是数据科学还是Web开发,Python都能让新手快速看到成果。它支持多种编程范式,并且社区的PEP 8规范为代码风格提供了清晰的指导。

Go语言在知识应用方面同样表现出色。它的工具链完善,容易将所学付诸实践。特别是在服务器端开发领域,Go的并发模型和简洁的语法让新手能够相对轻松地构建高效的后端服务。虽然Go不像传统的面向对象语言那样依赖继承体系,但其接口机制和组合方式为代码设计提供了优雅的解决方案。

C++的相关认知负荷较高,主要体现在将理论知识转化为实践时面临的挑战。内存管理和性能优化这些概念需要大量实践才能真正掌握。它支持多种编程范式,这种灵活性虽然强大,但对初学者来说往往是一把双刃剑。由于缺乏统一的编码规范,新手可能在选择最佳实践时感到困惑。

Rust在这方面呈现出独特的特点。它的所有权系统要求开发者在实践中深入思考内存管理问题,这个过程虽然充满挑战,但却能培养扎实的系统编程思维。Rust社区提供的编码规范和工具链都很完善,有助于形成良好的编程习惯。

Java则以其企业级开发的特点著称。它要求开发者深入理解面向对象编程的核心概念,这个过程需要较长时间的积累。Java的设计模式体系完备,社区的编码规范成熟,这些特点有助于培养专业的工程思维,但对新手来说可能需要更多的时间和耐心。

2.4 综合评估

通过以上分析,我们可以看出不同语言在认知负荷方面的特点。

Python以其全方位的低认知负荷成为初学者的理想选择。

Go语言通过简洁的设计和完善的工具链在降低认知负荷方面做出了显著成效。

Java虽然相对繁琐,但其成熟的生态系统和规范的开发流程为长期发展提供了良好基础。

Rust和C++的学习曲线较陡,但它们在系统编程和性能优化方面的深度让投入的学习成本变得有价值。

在理解了编程语言的认知负荷特点后,我们不妨再从心理学的角度,特别是借助三脑理论的视角,来探讨初学者是如何在面对不同编程语言时做出选择的。

3. 初学者的编程语言学习决策过程

三脑理论(Triune Brain Theory)由Paul D. MacLean于1970年提出的理论假说,该理论将人脑分为三个层次,如下图所示:


来自维基百科

  • 爬虫脑(Reptilian Brain):也称原始脑,负责基本生存反应,包括对威胁的快速反应和本能行为。
  • 情绪脑(Limbic System):处理情绪和动机,影响记忆形成和社交行为。
  • 理性脑(Neocortex):负责高级认知功能,如逻辑思考、语言处理和复杂决策。

注:三脑理论提出较早,如今有新的理论认为三脑理论毫无依据。不过这里我们假定这个理论是正确和适用的。

三脑理论影响初学者的编程学习决策的过程是怎样的呢?这个过程往往涉及本能反应(爬虫脑主导)、情感体验(情绪脑主导)和理性思考(理性脑主导)三个层面的互动。我们继续往下看。

3.1 初学阶段的决策历程

在首次接触编程语言时,学习者的反应往往是多层次的。本能层面的反应最为直接,面对像C++这样认知负荷较高的语言时,很多人会本能地产生畏惧感。这种反应不是简单的怯懦,而是大脑对复杂性的自然防御机制。相反,Python这类认知负荷较低的语言则较少触发这种应激反应,使得学习者能够保持相对轻松的心态。

情感层面的体验则更为复杂。当成功运行第一个程序时,无论使用什么语言,都会带来成就感。但随着学习的深入,不同语言带来的情感体验会产生分化。举个例子,我在早期学习Java时,仅仅是配置环境变量这样的基础工作就带来了挫折感,这种负面情绪很容易影响学习的积极性。而Rust虽然入门门槛较低,但一旦进入到所有权系统的学习,很多人会因为频繁的编译错误而感到沮丧。

理性思考则是决策过程中最后但也是最重要的环节。这包括对语言应用领域的评估、职业发展前景的考虑,以及个人学习时间和精力投入的权衡。这个阶段的决策通常更加慎重,也更具有长期性。

3.2 深入学习阶段的转变

随着学习的深入,最初的决策依据往往会发生改变。原本令人望而生畏的特性可能转变为吸引力的来源。这种转变在Rust的学习过程中特别明显,当开发者逐渐理解了所有权系统的价值,最初的困惑可能转化为对语言设计的欣赏

在这个阶段,情感体验也往往变得更加丰富。克服困难带来的成就感可能超越了简单的编程快感,这也解释了为什么一些看似“难学”的语言反而能够培养出更加忠实的用户群体。Rust连续多年在最受欢迎编程语言榜单上位居前列,很大程度上就源于这种深层的技术认同感

理性思考在这个阶段会更加全面,不再局限于语言本身的特性,而是扩展到整个技术生态系统的考量。开发者会更多地思考语言的性能特点、社区活跃度、工具链完善程度等因素。

3.3 认知负荷与学习效果

从短期来看,低认知负荷的语言确实能够提供更平缓的学习曲线,让入门过程更加顺畅。Python和Go在这方面的优势明显,它们能让学习者快速进入实践阶段,建立信心。但这种便利性有时也会带来一个意想不到的问题:学习者可能在掌握了基础语法后陷入平台期,难以实现质的突破。这也是为什么经常有读者询问如何才能在Go语言编程中更进一步

相比之下,高认知负荷的语言虽然入门较难,但往往能够培养更深入的编程思维。比如Rust的所有权系统,虽然增加了学习难度,但这种设计迫使开发者深入思考内存管理的问题,从而建立更扎实的系统编程基础。C++的模板元编程虽然复杂,但掌握后能够大大提升代码的抽象能力和复用效率。

不过,我们也要警惕过高的认知负荷带来的风险。如果学习过程中的挫折感持续累积,很容易导致半途而废。每年入门一次Rust的真实案例也屡见不鲜。这就要求我们在选择编程语言时,既要考虑个人的学习能力和时间投入,也要权衡职业发展的需求,找到一个适合自己的平衡点。

4. 小结

在探讨了认知负荷对编程语言学习的影响后,我们可以得出一些粗浅的见解:编程语言的学习绝非简单的语法掌握过程,而是一个涉及多个认知维度的复杂历程。从开发环境的搭建到语言特性的理解,从基础概念的掌握到工程实践的应用,每个阶段都会给学习者带来不同程度的认知压力。理解这些认知负荷的本质,有助于我们做出更明智的编程语言学习的选择。

对于编程新手来说,像Python和Go这样在各个维度都尽量降低认知负荷的语言,无疑是入门的理想选择。但我们也要认识到,较高的认知负荷未必就是缺点。就像Rust和C++这样的语言,它们的学习曲线虽然陡峭,但这种”困难”往往蕴含着宝贵的学习机会。通过克服这些认知挑战,开发者能够建立起更深入的系统编程认知,形成更扎实的技术功底。

选择合适的编程语言,某种程度上就像选择一位长期相处的伙伴。这个选择不仅要考虑语言本身的特点,还要权衡个人的学习能力、职业规划和时间投入。认知负荷理论为我们提供了一个有价值的分析框架,但最终的选择还是要回归到个人的实际需求和发展目标。正如没有完美的编程语言一样,也没有放之四海而皆准的学习路径。找到适合自己的平衡点,或许才是最务实的学习策略。

最后,在人工智能编码辅助技术飞速发展的今天,开放的学习心态和持续学习的能力,可能比选择某个特定的编程语言更为重要。毕竟唯一不变的可能就是变化本身。

5. 参考资料


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily
  • Gopher Daily Feed订阅 – https://gopherdaily.tonybai.com/feed

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats