分类 观点 下的文章

年龄并不是为开源做贡献的障碍。

我叫 Neil Naveen,我是一个 14 岁的初中生,已经有七年的编码经验。我使用 Golang 编码也有两年了。

不过,编码并不是我唯一的爱好。我练习柔术已经有四年了,并参加过多次比赛。我对编码和柔术充满热情,因为它们教给了我重要的人生课程。

Codecombat

我在 Codecombat 上开始编码,它教会了我许多基本的编码技巧。

在我的编码历程中,最激动人心的时刻之一是我在 Codecombat 主办的多人竞技场中,在大约 50,000 名玩家中排名第 16。当时我只有 11 岁,这对我来说是一个不可思议的成就。它给了我继续探索和学习新事物的信心。

Leetcode

在 Codecombat 之后,我转到了 leetcode.com。通过解决这个网站量身定制的问题,来磨练我的算法编码技能,以学习特定的算法。

Coding Game

当我 13 岁时,我转到了 Coding Game 的机器人编程。这里的竞争更加激烈,因此我必须采用更好的算法。例如,在创建终极 井字游戏 tic-tac-toe 人工智能时,我使用了 极小化极大算法 Minimax 蒙特卡洛树搜索 Monte Carlo Tree Search 等算法,使我的代码快速高效。

GitHub CLI

有一天,我看到爸爸在使用一个叫 GitHub CLI 的开源工具,我被它迷住了。GitHub CLI 是一个允许用户直接从命令行与 GitHub 的 API 互动的工具,而不需要到 GitHub 网站上去。

又有一天,我父亲正在审查一个旨在检测依赖关系中的漏洞的机器人的 拉取请求 PR

后来,我思考了 GitHub CLI 和这个机器人,并想知道 GitHub CLI 本身是否被一个安全机器人所监控。事实证明它没有。

所以我创建了一个修复程序,并包含了 GitHub CLI 的安全审计。

令我高兴的是,我的贡献被接受了。它被合并到了项目中,这对我来说是一个激动人心的时刻。能为一个像 GitHub CLI 这样受欢迎的工具的重要项目作出贡献,并帮助保护它,是一个极好的机遇。这是我的 PR 的链接:https://github.com/cli/cli/pull/4473

提交你的代码

我希望我的故事能激励其他年轻人去探索并为开源世界做出贡献。年龄并不是障碍。每个人都应该探索和贡献。如果你想看看我的网站,请到 neilnaveen.dev。你也可以看看我的 Leetcode 个人资料。如果你有兴趣,可以看看我在 CloudNativeSecurityCon 的演讲记录。

我很感激迄今为止我所拥有的机会,我很兴奋地期盼我的未来。谢谢你阅读我的故事!

(LCTT 校注:我也接触过几位初中生,他们在技术和开源方面有这浓厚的兴趣,并取得了令人称道的进展。所以,看到这篇文章的同学们,你也可以的!)

(题图:MJ:Kids programming learning carton)


via: https://opensource.com/article/23/3/my-first-code-contribution-age-14

作者:Neil Naveen 选题:lkxed 译者:hanszhao80 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

开发开源软件背后的工作是相当庞大的。那么我们如何保证开源项目的成功呢?存在捷径吗?本文认为是没有的。

今天,开源已经风靡世界。很多大型企业在快速成功的诱惑下被推向开源。但真实情况是世界上并不存在成功的捷径。你无法做到通过一次努力就能让所有的开源项目正常运行。

事实上,上述公司早期遇到的许多挑战都不是技术上的,而是人员与文化上的。

开发一个能够在市场上获得成功的开源项目需要在开源的许多层面上下功夫。而维持这样的成功是一个持续的过程。所有这一切的关键在于找到以下这个非常基本的问题的正确答案:开源究竟是什么。

开源是代码

对于很多新用户而言,他们可能并不完全了解开源的不同层面,答案相当简单:开源就是软件!这当然没有错,毕竟我们多数人就是这样使用它的。不过,相比仅仅被视作软件而言,开源远不止这些。

任何开源项目的实质仍然是代码本身。代码是使一个开源项目有别于其他项目,并使其对用户有益的根本。当你从事开源工作的时候,代码和软件一样都是产品的一部分。

从零开始开发一个开源项目或者 复刻 fork 一个现有项目,即便是在面对一个庞大而复杂的代码库时,也需要编写成千上万行代码。尤其是在创建一个现有项目的复刻的情况下,在移除任何在先的许可证、宣传材料或者其他任何可能已经失去作用的文件时必须小心翼翼(LCTT 校注:部分开源项目不允许你改变其原有的许可证)。终究是一个项目的功能吸引了它的用户群并维持项目的持续发展。当最终用户在考虑是否使用开源软件的时候,他们会阅读项目的源代码,而他们在其中所看到的应当是那些能够建立他们的信心的内容。

开源是社区

如何参与到社区中也是产品构建的一部分。创建一个社区并维护一个健康的社区关系是开源的核心之一,但对于大部分的领导者而言也往往是最坚难的任务,很少有人能很好地维护它。你可以尝试建立基金会或者提供赞助,但是最终还是由人们自行决定是否想要加入社区。

重要的是与社区保持一定程度的透明度,并不断保持。社区成员可以在它想要的任何阶段参与进来。除了需要进行的工作之外,诸如安全设置、签发证书、注册商标等,尽可能多的将你所做的工作展示给社区是相当重要的,这有助于取得社区信任。归根到底,你需要对社区负责,你的项目成也社区,败也社区。这可能会导致你的项目开发更谨慎、更缓慢并且向社区公开,不过项目最终会进展顺利。

如此地公开你正在进行的工作似乎有些令人生怯,尤其是当你担心更新推迟或者是出现漏洞的影响的时候。不过,让社区成员知悉你的进展,不仅有助帮助你建立与社区之间的信任关系,而且能够让社区成员感到被认可。

另一方面,公开你的工作流也可以获得来自社区成员的监督,他们经常有自己的见解并向你反馈。记录这些反馈是很重要的,这使得你的开源项目如实地反映社区需求。他们是项目的最终用户,而他们的反馈则反映了他们如何看待你的项目的长期发展,以及你的项目最终将有多么成功或者主流。

举例而言,当我们在考虑一个新功能的时候,我们在 征求意见文档 Request for Comments (RFC)中发布一个征集意见的请求,我们会收到大量的反馈,我们必须认真思考应当如何吸收这些反馈。

因为开源是一个大型的合作项目,社区对支持开源项目的主动支持,使项目成为了最好的项目。并非所有的问题都要解决,但只要你有在倾听社区的呼声,社区就会有参与感。

参与到社区中也存在一些隐患。社区内部、项目维护与社区之间均可能存在不同意见,尤其是在涉及治理的问题上。治理对于一个开源项目来说是相当重要的。这也就是为什么拥有一份清晰的文档化的治理条例对于项目以及社区均是如此重要。

社区治理是一个关键的而又难啃的骨头。社区授权本身需要相当大的信任。对于一个拥有成千上万行代码的项目,在社区中寻找能够有效领导社区的人物是不容易的。不过开源项目经常是由更小的子项目组成的,这些子项目最好由社区中的某个人进行管理。这有助于社区更紧密地参与到项目中。

建立社区的过程不是一帆风顺的。让我列举一一些有助于维持社区与我的团队之间平衡的技巧。

声明你的原则: 尤其是在开源项目的早期,在项目代码仍在完善,很多事情还不完美的时候,项目之外的人员很难真正理解你所做的决定。向他们说明你做出决定所依据的原则,有助于你在思考过程上保持坦率,从而让社区不会错误地干扰你的事务。这一经验非常有效,在你做出决定时坚持遵循其中一项原则并展示出来是非常重要的。

确定如何进行协作: 你可以通过 Discord、Slack 或者邮件等途径完成这一工作。但是如果你试图同时使用它们,你将毫不意外的分散项目社区。社区人员将在所有这些途径上互相交流。选择一到两种沟通工具,投身于它们来保证社区的信息同步。

珍惜反馈意见: 倾听来自社区的反馈并付诸行动。即使需要你作出艰难的决定,你也应当向社区展示你是重视社区话语的。

维护一套行为准则: 如果你与社区打交道,你需要定义什么行为是可以接受的。一套落地的行为准则有助于在人们越过红线时警示他们。如果你可以提前制定这些你可以避免很多麻烦。

考虑如何分发你的项目: 存在这样的情况,因为你还没有准备好某一个组件,或者是因为存在一些你不希望所有人都能够访问的项目功能,所以你可能并不希望将你的项目完全向公众公开。关键是制定符合你的要求而不是向用户妥协的分发条款,如此,需要某种功能的用户可以获取所需项目的同时,不需要该功能的用户也不需要在开始使用该项目做出妥协。

尽可能地避免投票: 这是因为部分成员经常会赞成与大部分成员的意见相左的选项,这会使这些人产生一定程度的失望,并让他们觉得被项目所孤立。反之,尽量尝试询问他们想要解决什么问题,并尝试创造一个不需要付出代价的解决方案。

开源是许可

开源是给予你的用户如何使用你的软件的自由,而许可能够做到这一点。开源项目许可的好处在于,它保证了不论你作为维护者做了什么,你的所有最终用户以及利益相关方总是可以维护一系列的项目复刻版本,这些都是重要的项目复刻。

许可提供了人们可选择性,如果他们认为有必要,他们可以将项目带到不同的路径中。他们拥有创建副本的权利,这使得许多优秀的软件能够被开发出来。维护者有责任倾听他们的社区成员的声音,并以一个对项目的社区成员有利的方式运营项目。

我们推荐使用现有的许多可用的许可证,而不是独立制作你自己的许可条款,原因很简单,因为用户以及利益相关方通常都很熟悉常用的许可证,因此你不需要再花费时间在解释许可条款上。这将帮助你将你的精力集中在项目的其他部分上。

最后,开源是一项运动

开源包括了很多维度,也包含了很多人员。最重要的是,它是关于理解人们想要什么,并创建一个鼓励协作与透明的环境。开源也是关于创建社区,帮助建立走自己想走的开源项目的方式。维护者创造越多的机会让社区自由发挥,开源产品就越好,也越发成功。

开源是以上所有这些方面,而你的视野越宽阔,你就能越好的利用它。请考虑你如何能够在开源的每一个维度上出类拔萃,因为时至今日,开源的成功之路并无捷径。


via: https://www.opensourceforu.com/2022/07/open-source-software-is-there-an-easy-path-to-success/

作者:Jules Graybill 选题:lkxed 译者:CanYellow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

开始一份新工作对任何人来说都让人害怕。下面是如何在你的第一份技术工作的早期阶段找到方向。

刚刚入职那几天确实令人害怕。 我现在依然可以清晰举出很多例子,例如在第一天上班前的晚上无法入睡,因为不知道第二天将要发生什么而内心崩溃。对于大多数人来说,开始一份新工作就像踏入未知领域。即使你已是行业的资深人士,不可否认的是,你内心可能还是会对即将发生的事情感到有点害怕。

可以理解的是,刚入职的时候你的事情很多。你要认识新的人,有新的项目和技术要了解,有文档要阅读,有教程要看完,还有没完没了的人事培训和要填的文件。这可能让你感觉压力山大,再加上你还面临着相当大程度的不确定性和未知数,以上种种能引起焦虑。

促使我写这篇文章有两个原因,首先是在我还是学生的时候,大部分讨论都围绕着如何找一份技术工作,却没有人谈论接下来发生的事情。如何在新角色中脱颖而出?现在回过头来看,我想我当时认为最困难的事情是得到一份工作,之后发生什么的一切我都可以自己弄清楚。

同样的,在我开始在这个行业工作之后,我发现大部分我看到的与职业相关的内容都是讨论如何从一个高级职位升到另一个高级职位。没有人真正谈论在此中间我们要做什么。实习生和初级工程师呢?他们在早期职业生涯中如何找到方向?

在拥有了三年全职软件工程师的经验(以及之前的几次实习)之后,我将这段时间的经历进行了复盘,并整理出一份我自己在适应新技术职位时使用过的技巧和诀窍清单。我想不只局限于前面的几个月,而是优先考虑如何让这段经历帮助你实现长期的成功。

反思现有的流程和文档

大多数新员工一开始要么拥有一大堆文档,要么根本没有。你可以将这视为一个机会,而不是被这两种可能性中的任何一种所淹没。

从现有文档中找到缺口,并想想你可以怎样为下一位入职的工程师做出这方面的改进。这不仅能显示你工作的主动性,还表明你致力于改进团队中的现有流程。

上述两种极端情况我都遇到过。我在没有任何文档的团队中工作过,也在一些更新文档方面很勤快的团队中工作过。对于前者,你的路径非常简单直接,你可以致力于创建那些缺失的文档。对于后者,你总是可以想办法改进已有的东西。有时,过多的书面文件也会让人感到害怕,尤其是对新员工而言。有些事情可能通过其他媒介进行更好地解释,比如视频教程或截屏。

勤问问题

我会建议你在开始一份新工作时研究一下公司是否会为你分配搭档。这在公司中是相当普遍的做法。工作搭档的主要作用是在你入职时为你提供帮助。我发现这非常有用,因为这个人能够针对你所有的问题给出指导,你就不必为了寻找合适的人或部门而四处奔波。

虽然我鼓励提问,但在提问之前也有必要做功课,包括:

  • 做好调查。这包括进行网络搜索、查看论坛和阅读现有文档。使用所有可用的工具。然而,给自己设定时间规划是很重要的。你必须平衡好尽职调查与牢记手头项目截止日期和可交付成果。
  • 说出来。作为母语不是英语的人,我建议你在提问之前大声把想法说出来。根据我的经验,我经常发现自己会用一种语言(通常是我的母语)思考但不得不用另一种语言来解释,而当我在一些困难的问题中挣扎时这一现象尤为突出。有时这颇有挑战性,因为经过翻译后的想法可能没那么容易理解。
  • 组织思绪。当你在为某件事而苦苦挣扎时,可能同时有很多不同的想法在你的脑海中翻来覆去。这些想法可能对你来说都挺有道理的,但对于别人来说却不一定说得通。对此,我建议你坐下来,收集你的想法,写下来,然后大声说出来。这一做法可确保当你在解释自己的思维过程时,你能按照预期进行流畅地表达出来,听众也可以紧跟你的思路。

这种方法称为橡皮鸭调试法,是开发人员在调试时的常见做法。背后的概念是,有时向第三方解释你的问题非常有助于你找到解决方案,同时也证明了你出色的沟通技巧。

尊重别人的时间。即使你在向你的搭档求助时,也要意识到他们也有自己的日常任务要完成。 我尝试过的一些事情包括:

  • 写下我的问题,然后留出一些时间与我的导师交流,以便与他们交谈。
  • 整理问题而不是反复寻求帮助,这样导师可以在他们有空的时候着手解决。
  • 安排 15-20 分钟的快速视频聊天,特别是如果你想共享屏幕,这一方法可以很好地展示你的发现。

我认为这些方法是更好的选择,因为这么做你能得到对方全部的关注,而不是在他们忙着其他事情的时候每隔几分钟打扰他们一下。

深入研究你的项目

即使在拥有出色文档的团队中,开始你的技术项目也可能非常艰巨,因为一个项目涉及多个部分。不过,随着时间的推移,你将了解团队是如何做事的。但是,通过记下一张实用清单,这包括基本项目设置、测试要求、审查和部署流程、任务跟踪和文档,你将迅速搞清楚一切,节省了你的时间和潜在的麻烦。

如果你开始的项目没有文档(我就遇到过这种情况),请看看你能不能找到当前或以前的项目所有者并了解基本的项目结构,这包括设置、部署等。

  • 确定你的团队在 IDE(集成开发环境)中的偏好。你可以自由使用你喜欢的 IDE,但使用和团队相同的 IDE 会比较好,尤其是在调试的时候,因为 IDE 的选择会影响调试。不同的 IDE 提供不同程度的调试支持。
  • 了解如何进行调试。我的意思不仅仅是使用打印语句(不是说这种方法有什么问题)。充分利用团队的经验!
  • 了解测试要求。这可能取决于项目的范围和团队的一般惯例,越早弄清楚要求,你在后期推送自己的修改请求时就会越有信心。
  • 可视化部署过程。这个过程可能因团队、公司等而异。无论这个过程是非正式或正式,请确保你了解自己提交的新代码是如何被部署至新环境中、部署流水线是什么样的、如何安全地部署代码更改、在构建失败后可以怎么做,如何回滚错误的更改,以及如何在生产环境中测试你的更改。
  • 了解工单流程。了解如何记录工单以及要求的详细程度。你会由此发现每个公司各不相同。有的公司希望我们每天提交工单以显示我们的进度。有的公司可能不需要如此详细。

基于我刚才提到的所有内容,我建议你可以在入职头几周内做一个有益的、一体化的练习——跟随模仿另一位工程师并进行结对编码。这么做让你可以端到端地观察整个流程,从派单给工程师到部署到生产中都清清楚楚。

如果刚入职几周时你还没有机会亲身实践,可能你会感到沮丧。为了解决这个问题,你可以让你的经理也给你派一些初级的单子。这些通常是一些小任务,例如代码清理或添加单元测试。不过,它们允许你修补代码库,这有助于提高你的理解并给你带来成就感,这在新工作的初期是非常鼓舞人心的。

当你遇到困难时尤其要大声说出来

我想强调一下当你碰到困难时沟通的重要性。遇到困难总是难免的,尤其是在一份新工作的最初几个月,尽管这可能会令人沮丧,但这正是你的沟通技巧大放异彩的地方。

  • 让工作中的阻碍和进步透明化。即使是像权限问题一样的小事(新员工常常遇到的障碍之一),也要确保你的经理知道。
  • 如果有些工作耽搁了,不要等到最后一天才向团队报告。你的项目延迟会推动许多其他事情的发展。对于一些必要的项目延迟请提前告知,以便你的经理可以与相关人员分享这一信息。
  • 不要因为匆忙而忘记全面测试代码的更改或为你的代码的写文档等事情。

获得技术大局观

获得技术大局观是我个人一直在努力改进的地方,并且我一直在积极改变自己对此的看法。

当年我开始实习时,我会非常专注于自己想学的东西。我会非常专注于我的项目,但对其他一切完全视而不见。多年后,我意识到对其他或相邻的项目视而不见可能不是最明智的。

首先,技术大局观会影响你对自身工作的理解。我曾经天真地以为,只要我专注于自己的项目就可以成为一名优秀的工程师。但事情并非如此。你应该花时间了解其他可能与你的项目有所交互的服务。你无需深入了解细节,但建立基本的理解也会大有帮助。

新员工的一个普遍经历是与公司其他人脱节,会有这种感觉很正常,尤其是在大公司。我是一个很快就会产生排斥感的人,所以当我刚到 Yelp 时 —— 这是一家比我以前的公司大得多的公司,项目规模也大得多,我优先考虑了解大局。我不仅努力建立对我的项目的理解,还认真了解了其他相邻项目。

在 Yelp 的头几周,我与团队中的其他各位工程师坐下来,请他们给我一个关于我将要做什么和项目的总体目标的概况。这种方法非常有用,因为我不仅根据工程师的资历和他们在项目上的工作时间得到了不同程度的解释,而且还加深了我对我将要从事的工作的理解。我参加这些会议的目的,是希望我对项目掌握的认识让我能够向街上的陌生人解释我所做的事。为此,我还请我的技术主管向我解释,当用户打开 Yelp 应用程序并搜索内容时,我的工作成果会在什么时候出现。

在这种情况下架构图也很有用,尤其是它能帮助你了解不同服务是如何交互的。

建立期望

在过去很长一段时间里,我以为自己只需要尽力而为,成为一名优秀的员工就行。只要我有在工作,达成目标,而且没有人投诉,那就足够好了,对吧?错!

你必须对你的职业有战略眼光。你不能只是将它外包给人们的一片好心,并希望自己只要达成了目标就能得到想要的结果。

  • 在你开始新工作的那一刻就建立明确的标准。这因公司而异,因为有些组织有非常明确的措施,而其他组织可能几乎没有。如果是后者,我建议你在头几周内找你的经理坐下来谈谈,制定并统一一个标准。
  • 确保你彻底了解公司将如何评估你以及采用什么方法进行评估。

我记得在我的第一份全职工作中,我对自己的第一次评估谈话一头雾水。整个谈话非常含糊不清,而且我对自己的长处、短处甚至可以如何改进都一无所知。

起初,我很容易地将一切都归咎于我的经理,因为作为新员工的我认为这是他们的工作,而不是我的职责。但随着时间的推移,我意识到,就我的绩效评估而言,我不能只是袖手旁观。你不能只做好工作并期望它就足够了。你必须积极参与到这些对话中。你必须确保你的努力和贡献被注意到。为了确保你的工作得到认可,你可以做很多事情,从定期参与技术设计对话到设置团建活动。

与建立期望相联系的还有积极寻求反馈的重要性。不要等到每三、四个月进行一次正式的绩效评估时才知道自己的表现如何。积极与你的经理建立反馈循环。虽然这听起来很可怕,但尝试定期进行寻求反馈的谈话。

在分布式团队中找到方向

在过去两年中我们的工作场所在不断变化,如今在远程和分布式团队中工作已成为常态,不再罕见。我列出了一些技巧,帮助你在分布式团队中快速找到工作方向:

  • 建立核心时间并将其设置在你的日历上。核心时间是你的团队一致同意的几个小时,在这段时间里,大家都明白自己应该在线并能随时响应。这样做很方便,因为会议只会安排在这个时间段,让你在计划自己一天的工作时更轻松。
  • 注意人们的时区和午餐时间。
  • 在虚拟世界中,你需要付出更大的努力来维持社交互动,而小小的心意却可以大大有助于让工作环境更加友好。其中包括:
  • 开始会议时,互相寒暄并询问人们周末/一天过得如何。这有助于打破僵局,让你能够与团队成员建立更私人的、超越工作的联系。
  • 建议定期举行非正式的虚拟聚会,与团队进行一些随意的闲聊。

维持工作生活间的平衡

在你职业生涯刚开始的时候,你很容易认为只要投入很多时间就能成功,特别是考虑到我们全天候待命的“忙碌文化”,以及认为建立生活工作的平衡是在职业生涯下阶段才需要考虑的想法。但这些想法与事实相去甚远,因为工作与生活的平衡不会神奇地发生在你身上。你需要积极和非常勤奋地去找到个人的平衡点。

没有工作与生活平衡的可怕之处在于它是慢慢蔓延到你身上的。刚开始是你下班后还在查看电子邮件,然后慢慢地,你开始周末也在工作,一直感到疲惫不堪。

我列出了一些提示,可以帮助你避免这种情况:

  • 关闭/暂停通知和电子邮件并将自己设置为离线。
  • 不要在周末工作。刚开始是你需要在这一个周末工作,但不知不觉间,你会发现自己大部分周末都在工作。不管是什么工作,它可以等到星期一。
  • 如果你是待命的工程师,请了解公司的相关政策。一些公司提供金钱补偿,而另一些公司可能会以休假代替。利用这个时间。不使用 PTO(带薪休假)和健康日等福利确实会缩短你的工作寿命。

总结

毫无疑问,开始一份新工作压力很大而且很困难。我希望这些方法和技巧会让你的头几个月变得更轻松,并为你在新职位上取得巨大成功做好准备。记住,勤沟通,确立职业目标,积极主动,有效地使用公司的工具。做到这些,我相信你会做得很好!


via: https://opensource.com/article/23/2/your-first-tech-job

作者:Fatima 选题:lkxed 译者:XiaotingHuang22 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这是非常重要的、上古的计算机上运行的,古老软件的新版本。

LM-3 项目宣布了 MIT CADR Lisp 机器 Lisp Machine 系统软件的第 100 版,这是它的最后一个版本。它既是一个新的版本,也是一个非常 古老的版本。

前两天,IBM 的 Eric Moore 在 LinkedIn 上发布了关于这个版本的 消息,他帮助了这项恢复工作。该项目的一个更详细的 帖子 描述了这个软件是什么,以及它是从哪里恢复的。

为什么这很重要?好吧,这款软件和它所运行的机器,是一场 “重要战斗” 的标志和纪念物。那场战斗是一场战争的一个阶段:一场以 “针锋相对的方式” 制造计算机的战争。“历史是由胜利者书写的”,温斯顿·丘吉尔 不是 第一个这样说的人。

这场战争和大多数战争一样,是两个 “对手阵营” 之间的战争。一方认为,制造计算机的正确方法是用最好的语言编写最好的软件,如果有必要的话,还要设计精工巧做的计算机来运行这些软件。另一方认为制造计算机的正确方法是制造小而快、容易而简单的软件和硬件,完成大多数人当时需要的工作。

同样,像大多数战争一样,这场战争是漫长而险恶的,双方都有一些肮脏的内斗。最终,有一方取得了决定性的胜利,但已经花了太长的时间,胜利者大多是开始战斗的那些人的后代和亲属。如今,他们甚至根本不记得有这么一场战争,而胜利的一方最终吸收了很多失败一方的想法和技术。最终的结果是,软件并不小而快,也不容易而简单。胜利的一方忘记了他们在战斗,也忘记了与之战斗的对手。

当胜利者忘记他们已经胜利了,也忘记了他们在战斗,这意味着失败者可以写一些最好的战争总结。一篇著名的报道是写自 1991 年的文章,名为《Lisp:好消息,坏消息,如何大获全胜》,其中说:

这两种哲学被称为 “ 做正确的事 The Right Thing ” 和 “ 差点则更好 Worse is Better ”。

“做正确的事” 是麻省理工学院/斯坦福的设计风格。另一边呢?

早期的 Unix 和 C 就是使用这种设计流派的例子,我将把这种设计策略的使用称为“新泽西方式”。

这篇文章只有短短几页,但如果你现在没有时间,用一句话可以概况,即 “差点则更好”。

换句话说,一方从麻省理工学院和斯坦福大学开始,他们最终设计了一种叫做 Lisp 机器 Lisp Machine 的计算机。另一方建立了 Unix 和后来专用的工作站,以快速运行 Unix,这需要可以快速运行编译的 C 代码的特殊处理器,它被称为 RISC 芯片。英特尔和 AMD 将 RISC 的一些技术和方法改编为 486 和奔腾芯片,AMD 则改编为皓龙和 x86-64,结果是 x86 电脑最终将 RISC 工作站赶出了市场。不过,今天,由于高端的 苹果芯片 Mac 和低端的 RISC-V,RISC 正在复兴当中。

但是,x86、RISC 和 CISC,以及 基于 Algol 的整个语言家族,包括从 BASIC 到 C++、到 Pascal、到 Go,基本上都是胜利一方的派别。而另一方现在几乎都被遗忘了,但有两个大的例子。一个是已故伟大的 约翰·麦卡锡 John McCarthy 创造的 Lisp,以及 整个基于 Lisp 的操作系统 所运行的 Lisp 机器。另一个是 Smalltalk 和施乐公司的 Alto

Symbolics 3620 (left) and LMI Lambda Lisp machines

麻省理工学院第一次尝试建造运行 Lisp 的计算机是一台 1974 年的原型机,名为 CONS,它以 Lisp 的一个关键词命名。1979 年,它更成功的后代被称为 CADR。CADR 计算机后来成为两家商业 Lisp 机器公司 LMI 和 Symbolics 的首批产品的基础,后者拥有互联网上的第一个 .com 域名。这些公司的成立,以及它们的软件的分拆,开始了 一个叫 理查德·斯托曼 Richard Stallman 的年轻黑客的职业生涯。

这条蓝色的导火索启动了 Emacs、GNU 项目,以及 自由软件运动 Free Software movement 。该项目建立了 GCC 等工具,这些工具被用来创建 Linux,而 Linux 本身也启动了 开源运动 Open Source movement

这次恢复的软件是麻省理工学院 CADR Lisp 机器的系统软件的最终版本。该软件是从麻省理工学院 技术广场磁带 Tapes of Tech Square (ToTS)收藏中的备份磁带上提取的,但它花了十年的时间来提取数据,对其进行清理,并使其在 35 年后首次运行。这是一个庞大的 工程

是的,如今可以运行这个软件,至少在软件模拟器上可以运行,比如最初由 Brad Parker 开发的 usim。它的源代码和一些历史都在 GitHub 上。


via: https://www.theregister.com/2023/03/31/mit_cadr_software_recovered/

作者:Liam Proven 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

程序员可以通过 Flatpak 轻松、稳定地发布他们的软件,让他们专注于他们的激情工作:编程。

 title=

如今,人们比以往任何时候都喜爱 Linux。在这个系列中,我将分享使用 Linux 的 21 个不同理由。今天,我将谈一谈是什么让 Linux 的打包成为程序员的理想选择。

程序员喜欢编程。这可能看起来是一个显而易见的说法,但重要的是要明白,开发软件所涉及的不仅仅是编写代码。它包括编译、文档、源代码管理、安装脚本、配置默认值、支持文件、交付格式等等。从一个空白的屏幕到一个可交付的软件安装程序,需要的不仅仅是编程,但大多数程序员宁愿编程也不愿打包。

什么是打包?

当食物被送到商店购买时,它是被包装好的。当直接从农民或从环保的散装或桶装商店购买时,包装是你所带的任何容器。当从杂货店购买时,包装可能是一个纸板箱、塑料袋、一个铁罐等等。

当软件被提供给广大计算机用户时,它也必须被打包起来。像食品一样,软件也有几种打包方式。开源软件可以不进行打包,因为用户在获得原始代码后,可以自己编译和打包它。然而,打包也有好处,所以应用程序通常以某种特定于用户平台的格式交付。而这正是问题的开始,因为软件包的格式并不只有一种。

对于用户来说,软件包使安装软件变得容易,因为所有的工作都由系统的安装程序完成。软件被从软件包中提取出来,并分发到操作系统中的适当位置。几乎没有任何出错的机会。

然而,对于软件开发者来说,打包意味着你必须学会如何创建一个包 —— 而且不仅仅是一个包,而是为你希望你的软件可以安装到的每一个操作系统创建一个独特的包。更加复杂的是,每个操作系统都有多种打包格式和选项,有时甚至是不同的编程语言。

为 Linux 打包

传统上,Linux 的打包方式似乎是非常多的。从 Fedora 衍生出来的 Linux 发行版,如 Red Hat 和 CentOS,默认使用 .rpm 包。Debian 和 Ubuntu(以及类似的)默认使用 .deb 包。其他发行版可能使用其中之一,或者两者都不使用,选择自定义的格式。当被问及时,许多 Linux 用户说,理想情况下,程序员根本不会为 Linux 打包他们的软件,而是依靠每个发行版的软件包维护者来创建软件包。所有安装在 Linux 系统上的软件都应该来自该发行版的官方软件库。然而,目前还不清楚如何让你的软件可靠地被一个发行版打包和包含,更不用说所有的发行版了。

Linux 的 Flatpak

Flatpak 打包系统是为了统一和去中心化 Linux 作为开发者的交付目标而推出的。通过 Flatpak,无论是开发者还是其他人(Linux 社区的成员、不同的开发者、Flatpak 团队成员或其他任何人)都可以自由地打包软件。然后他们可以将软件包提交给 Flathub,或者选择自我托管软件包,并将其提供给几乎任何 Linux 发行版。Flatpak 系统适用于所有 Linux 发行版,所以针对一个发行版就等于针对所有发行版。

Flatpak 技术如何工作

Flatpak 具有普遍吸引力的秘密是一个标准基础。Flatpak 系统允许开发者引用一套通用的软件开发者工具包(SDK)模块。这些模块由 Flatpak 系统的维护者进行打包和管理。当你安装 Flatpak 时,SDK 会根据需要被拉入,以确保与你的系统兼容。任何特定的 SDK 只需要一次,因为它所包含的库可以在任何 Flatpak 中共享。

如果开发者需要一个尚未包含在现有 SDK 中的库,开发者可以在 Flatpak 中添加该库。

结果不言自明。用户可以从一个叫做 Flathub 的中央仓库在任何 Linux 发行版上安装数百个软件包。

开发者如何使用 Flatpak

Flatpak 被设计成可重复的,所以构建过程很容易被集成到 CI/CD 工作流程中。Flatpak 是在一个 YAML 或 JSON 清单文件中定义的。你可以按照我的 介绍性文章 创建你的第一个 Flatpak,你也可以在 docs.flatpak.org 阅读完整的文档。

Linux 让它变得简单

在 Linux 上创建软件很容易,为 Linux 打包也很简单,而且可以自动化。如果你是一个程序员,Linux 使你很容易忘记打包这件事,因为它只需要针对一个系统,并可以整合到你的构建过程中。


via: https://opensource.com/article/21/2/linux-packaging

作者:Seth Kenlon 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

符合 描述性状态迁移 REpresentational State Transfer (LCTT 译注:REST,译自审定公布名词数据库)的应用程序接口(API)无处不在。有趣的是又有多少人真正了解“符合描述性状态迁移”的应有之义呢?

大概我们中的大多数人都会跟 黑客新闻网站上的这篇公开问答 产生共鸣:

我阅读了几篇介绍描述性状态迁移(REST)的文章,甚至包括原始论文的部分章节。然而我仍然对REST 到底是什么只有一个相当模糊的想法。我开始认为没有人真的了解它,它仅仅是一个定义相当不充分的概念。

我曾经计划写一篇有关 REST 的博客,在里面探讨 REST 是如何成为这样一个在网络通信领域占主导地位的范式的。我通过阅读 2000 年发表的 罗伊·菲尔丁 Roy Fielding 的博士论文 开始我的研究,这篇博士论文向世人介绍了 REST 的概念。在读过菲尔丁的博士论文以后,我意识到,相比之下,更引人注意的是菲尔丁的理论缘何受到如此普遍的误解。

(相对公平地说,)很多人知道 REST 源自菲尔丁的博士论文,但并没有读过该论文。因此对于这篇博士论文的原始内容的误解才得以流行。

最大的误解是:这篇博士论文直接解决了构建 API(API)的问题,我此前一直认为 REST 从一开始就打算成为构建在超文本传输协议(HTTP)之上的 网络 API Web API 的架构模型,我相信很多人也这样认为。我猜测此前可能存在一个混乱的试验时期,开发人员采用完全错误的方式在 HTTP 基础上开发 API,然后菲尔丁出现了,并提出了将 REST 做为网络应用程序开发的正确方式。但是这种想法的时间线对不上:我们今天所熟知的网络服务的 API 并非是在菲尔丁出版他的博士论文之后才出现的新生事物。

菲尔丁的博士论文《架构风格与基于网络的软件架构设计》不是讨论如何在 HTTP 的基础上构建 API,而恰恰是讨论 HTTP 本身。菲尔丁是 HTTP/1.0 版规范的贡献者,同时也是 HTTP/1.1 版的共同作者。有感于从 HTTP 的设计中获得的架构经验,他的博士论文将 REST 视为指导 HTTP/1.1 的标准化过程的架构原则的精华。举例而言,他拒绝了使用新的 MGETMHEAD 方法进行批量请求的提议,因为他认为这违反了 REST 所定义的约束条件,尤其是在一个符合 REST 的系统中传递的消息应该是易于代理和缓存的约束条件。 [1] 因此,HTTP/1.1 转而围绕持久性连接设计,在此基础上可以发送多个 HTTP 请求。(菲尔丁同时认为网页保存在本地的浏览数据,即 cookie 是不符合 REST 的,因为它们在一个状态无关的系统中增加了状态描述,然而它们的应用已经根深蒂固了。 [2] )菲尔丁认为,REST 并非构建基于 HTTP 的系统的操作指南,而是扩展 HTTP 的操作指南。

这并不意味着菲尔丁认为 REST 不能用于构建其他系统。只是他假定其他系统也是 “ 分布式超媒体系统 distributed hypermedia systems ”。人们对 REST 还有另一个误解:认为它是一个可以用在任何网络应用中的通用架构。但是从这篇博士论文中菲尔丁介绍 REST 的部分你基本上能够得出如下的结论,“请注意,我们只设计了 HTTP,但是如果你发现你自己也在设计一个\_分布式超媒体系统\_,你也应该采用我们提出的称为 REST 的优秀架构,以让开发变得更容易”。有鉴于互联网已经存在了,我们尚不清楚为什么菲尔丁认为有人可能试图重新创建这样一个(和 HTTP 一样的)系统。或许在 2000 年的时候世界上仍然存在不只一个分布式超文本系统的空间吧。无论如何,菲尔丁已经说得很清楚了,REST 意在提供一套解决方案,来解决在试图经由网络连接超文本内容时出现的可扩展性与一致性问题,而不是 作为分布式应用的通用架构模型。

我们现在只记得菲尔丁的博士论文提出了 REST 的概念,但事实上,他的博士论文是在讨论一刀切的软件架构有多么糟糕,以及如何更好地选择符合你需求的软件架构。这篇博士论文中仅用了一个章节来讨论 REST 本身,大量的文本内容都都花在了对你能够在网络应用中运用的不同的架构风格 [3] 的分类上。这些架构风格包括:受 Unix 的管道设计启发的 管道-过滤器 Pipe-and-Filter (PF)风格, 客户-服务器 Client-Server (CS)风格的多种改进,如 分层-客户-服务器 Layered-Client-Server (LCS)风格、 客户-缓存-无状态-服务器 Client-Cache-Stateless-Server (C$SS)风格和<ruby> 分层-客户-缓存-无状态-服务器 <rt> Layered-Client-Cache-Stateless-Server </rt></ruby>(LC$SS)。这些缩略词未必实用,但是菲尔丁认为我们可以通过混合匹配现有风格提供的约束条件来派生出新的风格。REST 就是通过这种方式产生的,它本可以称之为 一致性-分层-按需代码-客户-缓存-无状态-服务器 Uniform-Layered-Code-on-Demand-Client-Cache-Stateless-Server (ULCODC$SS)风格,显然我们并没有这样做。菲尔丁建立上述分类是为了强调(每一种风格对应的)约束适用于不同的应用,而上述最后一种风格对应的约束是他所认为的最适用于 HTTP 的。

今天,REST 的无处不在是极具讽刺意味的。REST 在各种各样的网络应用中被盲目使用,但是菲尔丁最初只是将 REST 视作一种指引,通过它指导人们裁剪一种软件架构来适应独立应用的特殊需求。

我很难弄清楚这是如何发生的,毕竟菲尔丁已经明确地指出了不能让形式服从功能的陷阱。他在论文的一开始就作出了警告:由于没有正确地理解软件架构而“使用流行的架构设计是经常发生的” [4] 。他在几页之后又重新强调了这一点:

一些架构风格经常被描述为适用于一切软件形式的“银弹”解决方案。然而,一名好的设计者应该选择能够满足解决特定问题的需要的架构风格 [5]

REST 本身就是一个特别糟糕的 “银弹” 解决方案。正如菲尔丁所指出的,它包含了可能不合适的利弊权衡,除非你试图构建一个分布式超媒体应用:

REST 设计用来高效地进行大粒度的超媒体数据传输,并对网络应用场景中的常用见情形做了优化,但是可能会导致其在与其他形式的软件架构相互作用时不协调。 [6]

菲尔丁提出 REST 是因为网络发展带来了“ 超越政府的可扩展性 anarchic scalability ”这一棘手问题,菲尔丁的意思是需要以一种高性能的方式跨越组织和国家边界连接文件。REST 所施加的约束是经过精心选择的,以用来解决这一“超越政府的扩展性”问题。面向公众 的网络服务 API 同样需要解决类似的问题,因此可以理解为什么 REST 在这些应用中是适用的。然而,时至今日,如果发现一个工程团队使用 REST 构建了一个后端,即使这个后端只与工程团队完全控制的客户端通讯,也不会令人惊讶。我们都成为了 蒙蒂巨蟒 Monty Python 的独幕滑稽剧 中的建筑师,那位建筑师按照屠宰场的风格设计了一座公寓大楼,因为屠宰场是他唯一具有的经验的建筑。(菲尔丁使用了这部滑稽剧中的一句台词作为他的博士论文的题词:打扰一下,你说的是“刀”吗?)(LCTT 校注:顺便说一句,Python 语言的名称来自于 “Monty Python” 这个英国超现实幽默表演团体的名字。)

有鉴于菲尔丁的博士论文一直在极力避免提供一种放之四海而皆准的软件架构,REST 又怎么会成为所有网络服务的事实上的标准呢?

我认为,在 21 世纪头十年的中期人们已经厌倦了简单对象访问协议(SOAP),因此想要创造另一种属于他们自己的四字首字母缩略词。

我只是半开玩笑。 简单对象访问协议 Simple Object Access Protocol (SOAP)是一个冗长而复杂的协议,以致于你没法在不事先理解一堆互相关联的可扩展标记语言(XML)规范的基础上使用它。早期的网络服务提供基于 SOAP 的 API。在 21 世纪头十年中期,随着越来越多的 API 开始提供,被 SOAP 的复杂性激怒的软件开发者随之集体迁移。

SOAP 遭到了这群人的蔑视,Rails 之父 戴维·海涅迈尔·汉森 David Heinemeier Hansson (LCTT 译注:译自其所著的《重来》的中文版的作者译名)曾经评论:“我们感觉 SOAP 过于复杂了,它已经被企业人员接管。而当这一切发生的时候,通常没有什么好结果。” [7] 始于这一标志性的评论,Ruby-on-Rails 于 2007 年放弃了对 SOAP 的支持。“企业人员”总是希望所有内容都被正式指定,反对者认为这是浪费时间。

如果反对者不再继续使用 SOAP,他们仍然需要一些标准化的方式来进行工作。由于所有人都在使用 HTTP,而且代理与缓存的所有支持,每个人都至少会继续使用 HTTP 作为传输层,因此最简单的解决方案就是依赖 HTTP 的现有语义。这正是他们所做的工作。他们曾经称之为: 去它的,重载 HTTP Fuck It, Overload HTTP (FIOH)。这会是一个准确的名称,任何曾经试图决定业务逻辑错误需要返回什么 HTTP 状态码的人都能证明这一点。但是在所有的 SOAP 正式规范工作的映衬下,这显得鲁莽而乏味。

幸运的是,出现了这篇由 HTTP/1.1 规范的共同作者创作的博士论文。这篇博士论文与扩展 HTTP 有某种模糊的联系,并给予了 FIOH 一个具有学术体面的外表。因此 REST 非常适合用来掩饰其实仅仅是 FIOH 的东西。

我并不是说事情就是这样发生的,也不是说在不敬业的创业者中确实存在着盗用 REST 的阴谋,但是这个故事有助于我理解,在菲尔丁的博士论文根本就不是讨论网络服务 API 的情况下,REST 是如何成为用于网络服务 API 的架构模型的。采用 REST 的约束存在一些效果,尤其是对于那些面向公众的需要跨越组织边界的 API 来说。这些 API 通常会从 REST 的“统一接口”中受益。这应该是 REST 起初在构建网络 API 时被提及的核心原因。但是,想象一下一种叫做 “FIOH” 的独立方法,它借用 “REST” 的名字只是为了营销,这有助于我解释我们今天所知道的 REST 式 RESTful API 与菲尔丁最初描述的 REST 的架构风格之间的诸多差异。

举例而言,REST 纯粹主义者经常抱怨,那些所谓 RESTful API 实际并不是 REST API,因为它们根本就没有使用 超文本作为应用程序状态引擎 Hypermedia as The Engine of Application State (HATEOAS)。菲尔丁本人也做出过 这样的批评。根据菲尔丁的观点,一个真正的 REST API 应当允许你通过跟随链接实现从一个基础端点访问所有的端点。如果你认为这些人的确在试图构建 RESTful API,那么存在一个明显的疏漏 —— 使用超文本作为应用程序状态引擎(HATEOAS)的确是菲尔丁最初提出的 REST 概念的基础,尤其是考虑到“描述性状态迁移(REST)”中的“状态迁移(ST)”意指使用资源之间的超链接进行状态机的导航(而不是像很多人所相信的那样通过线路传输资源状态) [8] 。但是你试想一下,如果每个人都只是在构建 FIOH 的 API,并明里暗里的将之作为 REST API 宣传,或者更诚实一点说是作为 “RESTful” API 宣传,那么自然使用超文本作为应用程序状态引擎(HATEOAS)也就不重要了。

类似的,你可能会感到惊讶:尽管软件开发者喜欢不断地争论使用 PUT 方法还是使用 PATCH 方法来更新资源更加 RESTful,菲尔丁的博士论文却没有讨论哪个 HTTP 的操作方法应该映射到增删改查(CURD)操作。在 HTTP 操作与 CURD 操作之间建立一个标准的映射表是有用的,但是这一映射表是 FIOH 的一部分而不是 REST 的一部分。

这就是为什么,与其说没有人理解 REST,不如说我们应该认为 “REST” 这一术语是被误用了。REST API 这一现代概念与菲尔丁的 REST 架构之间存在历史联系,但事实上它们是两个不同的概念。历史联系适合作为确定何时构建 RESTful API 的指引而留在心底。你的 API 需要像 HTTP 那样跨越组织和政府边界吗?如果是的话,那么构建具有统一的可预测的接口的 RESTful API 可能是正确的方式。如果不是的话,你最好记住,菲尔丁更倾向于形式服从功能。或许类似 GraphQL 的方案或者仅仅 JSON-RPC 更适合你试图完成的工作。


  1. Roy Fielding. “Architectural Styles and the Design of Network-based Software Architectures,” 128. 2000. University of California, Irvine, PhD Dissertation, accessed June 28, 2020, https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation_2up.pdf. ↩︎
  2. Fielding, 130. ↩︎
  3. Fielding distinguishes between software architectures and software architecture “styles.” REST is an architectural style that has an instantiation in the architecture of HTTP. ↩︎
  4. Fielding, 2. ↩︎
  5. Fielding, 15. ↩︎
  6. Fielding, 82 ↩︎
  7. Paul Krill. “Ruby on Rails 2.0 released for Web Apps,” InfoWorld. Dec 7, 2007, accessed June 28, 2020, https://www.infoworld.com/article/2648925/ruby-on-rails-2-0-released-for-web-apps.html ↩︎
  8. Fielding, 109. ↩︎

via: https://twobithistory.org/2020/06/28/rest.html

作者:Two-Bit History 选题:lujun9972 译者:CanYellow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出