敏态场景下,自研数据库如何做好技术演进和落地调优?点击预约直播 了解详情
写点什么

十年编程经历杂谈

  • 2022 年 6 月 29 日
  • 本文字数:5419 字

    阅读完需:约 18 分钟

十年编程经历杂谈

本文最初发布于 Thorsten Ball 的个人博客,经原作者授权由 InfoQ 中文站翻译并分享。


截至 2022 年 4 月,我的职业程序员生涯已达 10 周年。


我接触编程的时间比这更早,只是那时没有赚工资。在十几岁时,我创建过网站和 IRC 机器人,并编写了简短的 Python 脚本。然后我停下来,弹了几年吉他。在我二十多岁的时候,在相当巧合的情况下,我再次发现了自己是多么喜欢编程。当时,我按照要求创建了另一个网站,并发现,在我离开的这段时间里,Web 发生了很大的变化(现在是 HTML5 的了)。


于是我就想弄清楚,与继续在大学学习哲学相比,编程是否是更好的职业选择。Robin为我回答了这个问题,他慷慨地给我提供了一个带薪实习的机会。


现在已经过去 10 年了,说实话,不管是对于我作为程序员的成长过程,还是对于我的职业生涯,这都不是一个重要的标志。但意识到已经过去 10 年了,我认为有必要停下来思考一下。


以下是我回顾过去 10 年时想到的一些散乱无序的想法。我学到的东西,我没有学到的东西,我改变了看法的东西,以及我从来没有想过我会相信现在却信了的东西。


在很大程度上,它们源于我参与软件开发的环境:作为 Robin 的实习生,作为德国一家小型创业公司的软件开发人员,作为德国一家大型公司内部的创业公司的高级软件开发人员,以及现在作为一家完全远程、异步的美国创业公司的资深工程师。接下来这句话就当作免责声明吧,我敢打赌,如果我是在游戏工作室、硬件公司和大型科技公司工作,这篇文章的内容会很不一样。

大无畏精神的价值被低估了


我作为学习榜样的大多数程序员都有一个很少被提及的特质:大无畏精神。


他们会毫无畏惧地钻入一个未知的代码库。他们会毫无畏惧地打开他们怀疑存在不正常依赖关系的代码。他们会在不知道如何完成的情况下开始工作。


看到别人无所畏惧非常令人鼓舞,但自己变得无所畏惧是我发现的最好的学习加速器之一。

你无法预测未来;试一下可能给自己惹来麻烦


我们都知道,未来不可预测。但我花了很多年才真正在编程时考虑这一点。


在我职业生涯的前三分之一,我会想:我们会需要这个的,所以让我们现在就构建它。在第二个三分之一,我会想:我们可能需要这个,所以让我们做好准备。现在,我会想:我们不知道我们是否会需要这个,这是一种可能性。当然,看起来我们可能需要,没错。但事情一直在变化,所以让我们构建现在已知需要的东西。

编写的代码要易于测试


编写代码时要秉持这样一个理念:我写代码不只是为了让计算机执行,我写代码也是为了让它易于阅读和理解,或易于删除,或易于修改,或易于审查。

除了给客户带来价值外,没有什么是真正重要的


类型安全、测试覆盖率 100%、在代码中流畅表达业务逻辑的能力、完美的开发工具、不浪费资源的高效系统、在工作中使用最好的编程语言、优雅的 API 设计、快速反馈回路、编写良好的代码——这些都不是目标。


目标应该是:为你的客户提供价值,通过交付软件来解决他们的问题,不断重复这个过程。前面那些事可以帮助你做到这一点——更快、更便宜、更有效、更安全、更快乐——但它们不是目标。目标是为你的客户提供价值。


陷阱:编写软件往往比交付软件更容易。但是,交付才是最重要的。

完美是不可能的


我或许曾经认为那是可能的,但现在我确定那不可能。一切都是权衡的结果。


你永远无法在你关心的每个方面都达到 100%。有些东西必须要让步。当你认为自己做到了完美,你很快就会意识到自己忘记了一些东西。


我的审美观也发生了变化。我现在不再寻求完美之美,而是认为尽管有缺陷但仍能成功的程序就是美。看看那个小程序吧,尽管里面有 17 个 TODO,但它还是维系了互联网的发展。

如果你不能把它与业务联系起来,那就无所谓了


你可以重构一个代码库,对其进行大幅清理,使每个人都更容易理解,也让代码库更容易扩展,但如果该代码库在四个月后因为该项目对业务没有帮助而被删除,那么所有这些就都不重要了。


你可以花几周时间为你写的所有代码添加跟踪和可观察性,但你会意识到,没有人会去看,因为这些代码每天都会运行三次,而且从未引起任何问题。


你可以调整和优化代码,使其高效运行,以至于公司可以将运行代码所需的机器数量减半,尽管所节省的成本与你在优化时得到的工资相比显得微不足道。


你可以把时间花在绝妙的技术工作上,但那仍然是时间的浪费。

弄清楚规则试图防止什么,然后考虑该规则的可选性


如果你在 5 年前问我 TDD、清洁代码、软件工匠精神和其他学派是否是教条主义,我会说:“不!你看不出来吗?干净、良好的代码很重要!”


现在,回过头来看,当我思考“一个方法不应该超过 5 行”这样的规则是否有用的时候,我摇了摇头。


这不是关于规则的问题!而是这些规则所要防止的问题。如果你没有规则试图防止的问题,或者你可以用另一种方式来防止它,那么你就不需要这个规则。

编写测试让你可以相信系统能正常工作


不要太在意一个测试是集成测试还是端到端测试,是单元测试还是功能测试。不要和别人争论是否应该测试私有方法。不要再为是否应该在测试中访问数据库费神。


相反,编写能让你知道系统是否能正常工作的测试。理想情况下,只需 3 次点击,并且在 1 秒钟内就可以完成。


关于这一点,我花了很长时间,做了很多无用的讨论,并以诸多代码缺陷为代价才学到。

最佳实践通常是基于这样的假设:你知道代码应该做什么


如果你确切地知道要构建什么,那么最佳实践和模式可以给你带来帮助,为你提供如何进行构建的建议。


但是,如果你还不知道这个程序应该做什么,或者它在四周后会是什么样子,那么有些最佳实践会使事情变得更加困难。


有些实践在重写时使用非常合适,但在探索时使用却非常糟糕。

使用别人的代码并不像我想象的那么好


我的职业生涯是从编写 Ruby 和 JavaScript 代码开始的,因为有包管理器可以使用,所以我总是会问,“难道没有一个包能做这个吗?”。


常识告诉我们:如果可以,尽量使用库,而不是自己编写。尽可能地重用代码。不要重新发明轮子。不要复制和粘贴。这是我多年来的信念。


但这也有弊端。有时候,自己写一个函数可能比添加一个依赖更好。


依赖是有成本的。你必须保持它们最新。它们会增加编译或加载时间。它们会在堆栈跟踪信息中添加奇怪的东西。而且,很多时候,它们所做的比你需要的多得多,这意味着你付出的比得到的多得多。


当你把别人的代码粘在一起的时候,有一个非常现实的危险,那就是胶水代码的复杂度会不断累积。但这是你最不希望复杂性存在的地方。它会隐藏复杂性。你所要做的是尽可能地让复杂性显露出来,并想办法消除。


有时候,自己写比用别人的代码更好。

有些公司做到了,有些公司没做到,但没有谁是完美的


为软件公司开发软件和为迫不得已雇用软件开发人员的公司开发软件之间有很大的区别。在一个领导层了解软件及其生产方式的公司工作是一件很快乐的事。


话虽如此,我不认为有哪家公司能解决所有问题。每家公司都有某种程度的发挥空间。

在反馈回路上投入绝对不会白费功夫


我从来没有后悔改进反馈回路。更快的测试,更好的测试输出,更快的部署,把一个手动的反馈回路变成一个可以一键反馈信号的东西。


不过要注意:一旦你看到软件开发可以具有真正快速、高效的反馈回路,你就会永远渴望它。

总是在一天结束的时候留点未完成的事


一个失败的测试,一个编译错误,一个未写完的语句,以其中某一项结束你的一天,第二天早上你就可以坐下来继续你的工作,完全跳过了“嗯,我今天应该做什么……”。


没有什么比一个需要通过的测试失败了更能让我快速开始。

完美主义是个陷阱


完美主义基于谎言。你永远无法做到完美。总会有一些东西差强人意。接受不完美的存在,交付并继续构建。


以 80%为目标,将其他 20%视为可选项。给自己留下可以自由呼吸的空间。你最终可能达到 99%,谁知道呢?

工欲善其事必先利其器


我把大量的精力投入到了工具上:Vim、git、shells、Unix 环境、测试框架。我真的很享受在 Vim 配置中度过一个周日的早晨。


但也有可能做得过头,陷入配置阶段无法自拔,做着无休止的修补工作。你必须先使用工具,然后才能知道如何配置和使用最好。

招聘很难


我现在已经做过数百次面试,我获得的最重要的见解是,招聘真的非常非常难。面试评价受很多随机因素影响,让人在“强烈同意”和“强烈反对”之间摇摆不定。


我常常希望有一种方法可以发现人们是否有“搞定”基因。

开发人员最重要的特质:因为必须要完成,所以撸起袖子就干


所有我喜欢的人都有一个共同点:他们做工作任劳任怨。他们知道有些任务并不好玩,也不刺激,更不有趣。但因为必须有人去做,所以他们就做。

在一段比较长的时间内与其他人一起在同一个代码库上工作


与一群人在同一个代码库中工作多年,没有什么能比这个更能帮助我提升软件工程方面的水平了。


你会看到决策是如何进行的。


你会看到最终哪些事情是重要的,哪些不重要。


当你的同事在你写完代码 3 年后试图修改它时,你会看到你代码真正的可扩展性。


你会看到你的预测——我们现在有 2 个,但我肯定将来会有 5 个——是否会变成现实,并在做其他预测时考虑这个结果。


会有些代码让你后悔,也会有其他一些代码让你感到高兴。反思这两者的区别,你就可以学习提升。


你会看到工具出故障,只是因为某个地方的某个东西发生了变化,虽然与你无关,但你仍然要修复。


对于软件的某些部分,你会说“我三年来从未考虑过这个问题”,并把它们视为珍宝。


你会看到代码库中有哪些部分新同事很难理解,哪些部分他们马上就会有收获。


你会看到你编写的代码在 4 年后是什么样子。

了解全栈


对我来说,很少有什么事情能像听到“你并不一定需要知道它是如何工作的 ”这句话那样让我备受激励。


当然,我可能不需要,但如果我没有设法理解 GC 的工作原理,或 Unix 的工作原理,或多线程的工作原理,或数据库如何存储数据,或解释器和编译器如何工作,我就无法做到今天这个程度。


这对我的工作也有好处。我可以做出更好的技术决策,因为我能够更准确地权衡取舍,知道底层发生了什么。

打字可能成为瓶颈


之前说过。不要让打字成为瓶颈。

代码审查并非密不透风


在很长一段时间里,如果我在代码审查时漏掉了 Bug,我就会认为这是我的错。我漏掉了!我怎么会漏掉呢?如此明显的 Bug!


后来我发现,不仅仅是我:其他人在代码审查也会漏掉 Bug。事实上,他们已经接受了这种情况,并且毫无顾忌地说,代码审查并非无懈可击。我松了一口气。


这改变了我对代码审查的看法:它是一种不完美的东西,需要与其他方式相结合来验证代码。

并非每次代码审查都是值得的


并非每条代码都需要进行彻底地审查。有时候,如果风险可接受,那么快速扔下一句 “LGTM!”就可以了。这可以释放同事的潜能,保持势头,潜移默化地建立信任。

消极滋生消极


如果你屈服于消极,那么你就会越来越消极。你得到的总是比你想要的多得多。


它是病毒式的。它始于讽刺,然后变成愤世嫉俗,最终演变为“一切都很糟糕”。不久之后,无论做什么事情都要问“为什么要这么做?”久而久之,人们会对你隐瞒兴奋、喜悦和想法。


做一个消极的人太容易了。我认为,在某种程度上,指着什么说它的坏处,然后耸耸肩说,我早就料到这不是什么好事(每件事都是坏事,对吗?)这很容易做到,也很容易被误认为是一种能够发现缺陷和最坏情况的工程思维(其实不是这样的)。


困难的是看到事物的本来面目,看到它们的美好之处。对别人的想法给予鼓励,即使它们几乎没有什么可谈的东西。创造和培育快乐。这很有挑战性。


所以,最终在某个时候,我决定克服消极,并试图做有挑战的事情。到目前为止,这对我很有帮助。

你无法什么都做百分之百


我不可能一直把所有事情都做得同样好。我不能一边写书,一边在事业上取得进展,一边做一个伟大的父亲,一边在健身房里创造记录,还一边读着两本书。这种状态维持不了一两个星期。这是不可持续的。


现在,我会在重要的事情之间做好切换:当我想在一件特定的事情上取得进展时,我就会在一段时间内专注于这件事情,并接受其他事情必须进入保持模式。

代码是有重量的


代码是有重量的。你不需要的每一行代码都是压舱物,它会增加代码库的重量,这会让你更难掌控和改变方向。你需要的代码越少越好。


代码必须易于阅读,必须经过测试,必须保持兼容,必须保持安全,必须可以工作。即使它现在没有做任何有用的工作,有它在身边也无妨,不是吗?不是的。务必删除它并继续前进。如果有必要,从版本控制中恢复即可。


对测试来说也是如此,我要是早知道就好了。

编程是我生活的一部分


自从开始做实习生以来,我在工作之外花了相当多的时间在编程上:阅读技术书籍,写书,做业余项目,写博客文章,做讲座,去参加会议,学习新语言和工具。


有一些公司并不关心你的大学学位,只要你能证明你真的很擅长编程,这是我多年来的动力。


我喜欢在工作之外花时间进行编程,但不是所有时间。有些感觉像是工作。有些技术书籍读起来很耗费精力。但就是有些事情在做的时候感觉不是很好。


如果我只在白天的工作中编程和学习编程知识,那么我的职业生涯将完全不同。

计算机速度很快


构建 Web 应用程序使我认为 100 毫秒很快,50 毫秒是真的快。编写编译器让我知道,对于现代计算机来说,1 毫秒就是永恒。

我还是那么喜欢编程


我写的一些内容可能会被说成是我多年来变得愤世嫉俗。我的意思是“什么都不重要,完美不可能实现”吗?


不,恰恰相反。我有在意的事情,而且非常在意,只是在意的事情比之前少了,但我还是那么喜欢编程。


欢迎在 Twitter 上关注我(@thorstenball),或者给我发邮件(me@thorstenball.com),或者在interpreterbook.comcompilerbook.com网站上阅读我写的书。


查看英文原文:Professional Programming: The First 10 Years

2022 年 6 月 29 日 19:123772

评论

发布
暂无评论
发现更多内容

基于 Kafka 的实时数仓在搜索的实践应用

vivo互联网技术

kafka 服务器 搜索 数据舱

如何通过 draftjs 设计留言框

全象云低代码

前端 低代码 留言 draftjs 留言框

优化| 手把手教你学会杉数求解器(COPT)的安装、配置与测试

杉数科技

线性规划 求解器 优化求解器 混合整数规划 杉数科技

混合云管平台哪家强?采购时候需要注意什么?

行云管家

混合云 云管平台

Android技术分享| 【你画我猜】Android 快速实现

anyRTC开发者

音视频 移动开发 互动白板 Andriod 你画我猜

Go 语言入门很简单:读写锁

宇宙之一粟

读写锁 Go 语言 2月月更

了解 DevOps,必读这十本书!

禅道项目管理

DevOps

混合编程:如何用pybind11调用C++

华为云开发者联盟

c++ Python API 混合编程 pybind11

“pip不是内部或外部命令,也不是可运行的程序或批处理文件” 到底有多么神秘

华为云开发者联盟

Python pip 批处理 scripts pip install

前所未有的 Milvus 源码架构解析

Zilliz

Milvus 图形化管理工具 Attu 来袭!

Zilliz

数据库

大咖说|对话路特斯科技副总裁李博:如何看待智能驾驶的未来?

大咖说

阿里巴巴 智能 汽车 无人驾驶 路特斯

一个关于 += 的谜题

AlwaysBeta

Python 编程语言

Hudi Bucket Index 在字节跳动的设计与实践

字节跳动数据平台

数据库 字节跳动 数据湖 Hudi

云效发布策略指南|滚动、分批、灰度怎么选?

阿里云云效

云计算 阿里云 云原生 持续交付 发布策略

掌握这些招数,你也能写出HR眼中的高分简历

Tom弹架构

求职面试

百度飞桨大企业开放创新中心联合赋能计划启动!助力浦东产业智能化升级

百度大脑

ModStartCMS模块化建站系统 v3.3.0 组件功能升级,事件触发增强

ModStart开源

乘冬奥之风:北京2022年冬奥会用户信息获取偏好专题分析

易观分析

冬奥会用户分析

产品经理:「点这里,我要跳到任何我想跳的页面」—— 解耦提效神器「统跳路由」

百瓶技术

ios 前端 客户端 路由

Deep dive #2:API 与 Python SDKs 详解

Zilliz

Python 数据库

「前端CI/CD系列」第二篇:如何用建木CI更新七牛云CDN证书

Jianmu

CDN 自动化运维 七牛云 建木CI

杭州AI开发者Meetup报名开启!

百度大脑

边缘计算场景下Service Mesh的延伸和扩展

华为云原生团队

开源 边缘计算 边缘技术 边缘 边缘云

移动开发er,10万奖金等你来战!

Speedoooo

活动 前端开发 移动开发 黑客马拉松 黑客松

oracle数据库审计用什么数据库审计软件好?可以用什么方式部署?

行云管家

数据库 IT运维 数据库审计

极致用云,数智护航

阿里云云效

阿里云 DevOps 运维 云原生 运维安全

为什么我的 ORDER BY create_time ASC 变成了 order by ASC

LigaAI

Java 数据库 sql 程序员

虎符交易所2022年首届交易大赛 最高瓜分5万USDT奖励

区块链前沿News

虎符交易所

web前端培训:vue3源码中细节知多少

@零度

Vue 前端开发

【重磅发布】蚂蚁动态卡片,让 App 首页实现敏捷更新

蚂蚁集团移动开发平台 mPaaS

ios android 前端 mPaaS

十年编程经历杂谈_文化 & 方法_Thorsten Ball_InfoQ精选文章