程序员如何成长

程序员,如何,成长 · 浏览次数 : 387

小编点评

## 打怪兽:从技术学习到实际应用的思考 打怪兽是一个比想象中难解的技术问题,它提醒我们,在技术学习的过程中,如何平衡探索和应用才是关键所在。 * **多样性**是打怪兽的训练突破口。尝试不同的框架和技术,不断挑战自我,才能在不同环境下的表现更上一层。 * **反思**是打怪兽的关键。分析自身的经验,反思自身的工作模式,找到提升效率的方法。 * **平衡**是打怪兽的解题关键。既要追求新技术,也要保留对旧技术的掌握和运用。 * **成本效益**是打怪兽的现实考验。合理地分配资源,选择适合的方案,才能实现预期效果。 * **产品思维**是打怪兽的智慧。通过产品思维,可以更深入地理解问题,找到解决方案。 * **团队协作**是打怪兽的动力。与同事沟通,分享经验,共同进步。

正文

做技术是打怪兽不是养宠物,为什么要打怪兽?因为难;为什么难很重要?因为难的事情才能带来成长;为什么要成长?承认吧,因为「如何成长」是当代人,包括你我他在内焦虑的源泉。

过去几个月内我在写一系列主题为「NodeJS实战」的文章,内容来源是过去两年独自开发和运维 site2share 网站的经验,本篇文章是对这个系列的一个暂时收尾。

今天我不聊代码,聊些更重要的事情

养宠物

从两件事情开始说起

其一是在此之前,我直接或间接听到了一些来自早已离开项目同学的声音,陈旧的项目技术栈和代码是驱使他们离开的原因之一。

其二是在偶尔浏览掘金网站的内容过程中,有一类让我印象深刻的文章标题,大意诸如「教你用xx + xx + xx 打造一个开源系统」,因为我关注前端领域的关系,标题里的 xx 通常是围绕某个前端框架的时髦技术栈,从点赞和评论数来看它们颇受欢迎。

对于前者我当然理解:一方面脱离当下容易让自己丧失竞争力,不管你愿不愿意承认,简历驱动型开发是所有程序员秘而不宣的默契;另一方面陈旧代码给开发工作带来的挫败感不言而喻,我相信每个程序员面对「屎山代码」都有宁愿把它重写也不愿意修改一行的冲动。第二件事的出现也就顺理成章了:我想毫无负担地学习新技术,还能抛开白天工作中的螺丝钉角色,体验一次愉快的项目实战经历。

我把从零开始做新项目比喻为「养宠物」,因为它能给你带来无与伦比的掌控感。假设一个代码库完全是由你一手搭建的话,那么关于它的一切,例如如何启动、如何部署、它适用于什么场景又无法解决什么样的问题你都心中有数。如果你恰巧又在Thoughtworks 工作,那么Thoughtworks 工作体验更增强了这种掌控感的正当性:对于有坏味道的代码我们允许用工作时间进行重构,对于代码内不懂的知识点,只要提出问题就一定可以得到回答。

也许是我运气不够好,我的工作经验告诉我,「养宠物」般的工作机会是可遇而不可求,在大厂晋升靠造轮子而不是填坑是公理人尽皆知,但造轮子的机会屈指可数。维护遗留系统依然是我们大部分人的工作。这也就是我接下来想说的「打怪兽」,此时我们面对的系统哪怕只上线一年,源代码也可能是满目疮痍。

这里是对于下面不中听的一些话的免责声明,我不是在否定精通

React 没有价值,我也不认为简历驱动开发有什么错,只不过要小心它们让我们的眼界变得狭隘

打怪兽

真正的常态是我接下来想说的「打怪兽」。

之所以把它称为「打怪兽」,不仅仅因为你接触的代码会超出你的预期,你甚至想象不到你会遇到什么样(啼笑皆非亦或是让你无从下手)的困难:

- 这个一千行代码的文件应该从哪开始读起?
- 我如何才能让代码进入这个分支?
- 你发现项目用到的一个框架没有任何文档,在 github 上也找不到源码,原来是上一个离职的老大自己写的
- 项目的打包工具用的既不是webpack 也不是 grunt ,而是 shell 脚本
- 现在需要你优化一个超过包含上百个组件的 React 应用的性能

「怪兽」依然是一个友好的比喻,此时此刻你至少还能够把它具象化,将它和某些电影或者游戏里的角色联系在一起,这意味着它造成破坏的手段和范围是可以预知的。但工作中我们实际遇到的问题无法预测。

你一定想象不到在编写 site2share的过程中,困扰我最久的问题背后的罪魁祸首竟然是 ExpressJS 里的 trust proxy 参数,它导致 API 从来无法访问到部署在 Azure App Service 上的后端服务

为什么要打怪兽

实际的出发点正如上面所说,如果我们工作中绝大部分人、绝大部分时间面临的都是怪兽,那么逃避它就是自欺欺人。

说点不实际的,是因为打怪兽比养宠物更难——为什么「难」重要?因为难的事情才能带来成长。为什么要成长?承认吧,因为「如何成长」是当代人,包括你我他在内焦虑的源泉。

除此之外,我还想强调的是它在锻炼解决问题能力本身

随着工作的深入,越来越发现我的角色从「解决技术问题的人」变成「解决问题的人」:从 Javascript、SQL Server 到代码设计、代码规范,再到团队方向、团队培养。整个过程其实不允许你循序渐进地去适应,可能明天醒来新的问题就摆在你面前,你也永远也没有准备好的那一天。也许可以把团队管理当作一门新技术用学习编程语言的方式去学习,也许求助对的人是当务之急,也许有的问题压根可以不解决。但无论如何,思路不会有如神助般凭空出现在你脑海里,举一反三需要的是练习。问题的多样性在练习的过程中起到非常大的作用,解决新问题会带给你明确的反馈:我的经验可以移植到这个领域,亦或者我的工作模式需要调整。

或者忘掉我上面的长篇大论,通俗点说,打完怪兽以后你就是见过「地狱」的人了,还怕什么。我想起来大二时候为了制作这款软件代码被推翻了无数次,从那之后就再也不怕重构了

另一方面,养宠物的风险在于,它让我们不自觉地陷入舒适区中。

我曾经有差不多有一年的时间可以自由选择技术栈来开发各式各样前端应用。最流行的框架和搭配起来最时髦的全家桶便成了我的不二之选。在热门冷门尝试了个遍之后最终我难免会对自己产生怀疑:我似乎永远都在被输入,我永远都在给某个工具打工,如果今天哪个框架告诉我它是业内明日之星那我就要去学它,因为 fear of missing out 是每个技术人的通病。我似乎能做的也只有如此了,但这就真的足够了吗?

工具正在变得自动化,并且「帮助」我们专注于业务开发这件事带有迷惑性。这里的陷阱在于他能替你做很多事,会让你以为你具备同样的能力的错觉。例如虽然 Parcel 可以无须任何一行配置就把脚本打包得漂漂亮亮的,但你可能对背后的缓存策略一无所知。当每个人都在简历上强调「精通 xx 框架」的今天,我们应该问自己除了框架我还有没有更有力的竞争力?

这类陷阱还有另一种变形是,在团队内你只做业务开发。身处大型开发组中会让你以为你有独立驾驭一个相同体量项目的能力,但实际遇到的问题会非常受限,因为功能性需求和底层设计已经交给你们团队的 Tech Lead 甚至是团队前成员去做了。(公允地说这不是完全负面,而是一件需要把握平衡的事情。虽然这会给团队成员的成长带来不利,但另一方面却可以让项目风险变得可控)

「打怪兽」也是在打破你的乌托邦

打怪兽的另一层含义是经历实战

「教你用 xx 打造 xx」这类系列教程的前置条件太美好了:你有无限的业余时间投入其中,你就是你自己的产品经理。但实际工作中我们永远是戴着镣铐跳舞。例如糟糕代码不一定是个人能力的结果,考虑到当时的交付压力,团队状态和历史包袱,换做你不一定能做得更好。所以大部分技术决策其实是在恶劣环境下做出的,然而如何学习在不同环境中作出恰当的反应,我不认为这是脱离实践可以达成的。

另一个问题是它缺少对方案的闭环验证:我不确定有多少此类项目投入到真实的商业运营中,如果没有,很遗憾它的代码就不一定是有效的。例如它设计有异常捕获功能,异常捕获的目的之一是帮助我们在实际运营过程中排查问题,那当异常发生时它可以提供什么样的信息帮助我们定位到错误代码?通常在捕获异常之后紧接着要把信息作为日志输出,有相当一部分公司其实购买的第三方日志系统,那集成难度如何?如果只有零星的用户上报了此类问题,我们可否在实际生产环境下,在每秒上千条日志增速的日志海洋里甄别到他们?

退一步说,即使方案完美无缺,我们还需要关注它的成本如何。再一次强调,实际工作中人力、时间都是有限的,假使我们能做到满分条件也不会允许。当你把方案拍到老板面前,但是他告诉你预算只有三成时,选择留下哪三分之一的功能,或者说如何用三成的预算做出来一个及格的功能比纯粹的编码更棘手。老板更多关心的是风险,说实话「时髦」技术表达的并不一定都是褒义,它意味着技术的关注度仍在持续提升中,意味着它还可能没有被大规模地应用,也意味着我们其实有更成熟的方案可供选择。决策者都厌恶风险,因此在推广新方案时风险可控也是因素之一。除此之外代码的学习曲线如何?代码库毕竟在依赖团队维护,你应当考虑到团队下限对于新技术的接受程度。

最后,我建议技术同学也需要掌握一些产品思维,它也是只有实战可以带给你的,只有你设身处地地把自己当作应用的运营者才会意识到某些问题,这会对技术选型带来帮助。具体请参见我的上一篇文章:《个人开发者如何选购云服务》


你可能会喜欢

与程序员如何成长相似的内容:

程序员如何成长

做技术是打怪兽不是养宠物,为什么要打怪兽?因为难;为什么难很重要?因为难的事情才能带来成长;为什么要成长?承认吧,因为「如何成长」是当代人,包括你我他在内焦虑的源泉。

如何成为一名全职创作者——程序员篇

哈喽大家好,我是咸鱼 今天跟大家分享一篇文章,这篇文章的作者 **Gergely Orosz** 是一名程序员,他从 Uber 辞职以后,就当起了全职创作者 他通过写文章、卖课程、做视频等谋生,今天这篇文章是他对这种商业模式的思考,我把它主要部分翻译了出来(想要看全文的原文链接在文末) **译文如下

strimzi实战之三:prometheus+grafana监控(按官方文档搞不定监控?不妨看看本文,已经踩过坑了)

通过strimzi部署的kafka集群,如何部署prometheus+grafana去监控呢?官方文档信息量太大,即便照着做也可能失败,这里有一份详细的保姆级操作指南,助您成功部署监控服务

一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具 - SQL Translator

前言 对于后端程序员来说,编写SQL代码是日常工作中不可或缺的一部分。然而,随着数据复杂性的增加,如何高效、准确地编写SQL查询成为了新的挑战。幸运的是,SQL Translator的出现为后端程序员提供了一个强大的工具,将自然语言查询转换为精确的SQL代码,极大地提高了工作效率。 SQL Tran

分布式场景下,如何对外提供易变的服务,打造可靠的注册中心?

摘要:本文讲了关于服务发现的很多干货内容,核心内容为服务发现组件的选择、网关的介绍、 客户端侧如何发给已发现的服务。 本文分享自华为云社区《分布式场景下,如何对外提供易变的服务,打造可靠的注册中心?》,作者:breakDawn。 随着云原生的概念越来越火,服务的架构应该如何发展和演进,成为很多程序员

读书笔记丨远程服务调用和RESTful,如何分析和抉择?

摘要:相信未来REST规范将会变得更加流行和普及。 本文分享自华为云社区《云原生时代,远程服务调用和RESTful,如何分析和抉择?》,作者:breakDawn 。 随着云原生的概念越来越火,服务的架构应该如何发展和演进,成为很多程序员关心的话题。大名鼎鼎的《深入理解java虚拟机》一书作者于21年

MySQL性能优化浅析及线上案例

关于数据库的性能优化其实是一个很复杂的大课题,很难通过一篇帖子讲的很全面和深刻,这也就是为什么我的标题是‘浅析’,程序员的成长一定是要付出代价和成本,因为只有真的在一线切身体会到当时的紧张和压力,对于一件事情才能印象深刻,但反之也不能太过于强调代价,如果可以通过一些别人的分享就可以规避一些自己业务的问题和错误的代价也是好的。

浅析云原生时代的服务架构演进

摘要:相比于传统的微服务架构,云原生和 serverless 技术更加灵活、高效,能够更好地满足用户的需求。 本文分享自华为云社区《《凤凰架构》学习和思考——云原生时代的服务架构演进史》,作者:breakDawn。 随着云原生的概念越来越火,服务的架构应该如何发展和演进,成为很多程序员关心的话题。大

读书笔记丨理解和学习事务,让你更好地融入云原生时代

摘要:分布式事务与云原生技术有很强的关联,可以帮助云原生应用程序实现高效的分布式事务处理。 本文分享自华为云社区《理解和学习事务,让你更好地融入云原生时代》,作者: breakDawn。 随着云原生的概念越来越火,服务的架构应该如何发展和演进,成为很多程序员关心的话题。大名鼎鼎的《深入理解java虚

iOS 单元测试

作用一名合格的程序员,得能文能武。写的了代码,也要写的了单元测试。 单元测试步骤 1.File -> New -> Target, 选择单元测试Target,创建成功 如果项目是老项目,那需要手动创建一下UnitTest Target,如果项目里已经有了就忽略。 2.创建一个swift工具的测试类C