写了十几年代码,聊聊什么样的人能做好Java开发

有个现象,做了若干年之后回头看特别明显:起点差不多的人,三五年后差距就拉开了。有些人三年能独当一面,带着团队做核心系统。有些人干了七八年,还在接需求写接口,稍微复杂一点的任务交不到他手上。

差距来自哪?技术天赋有一点影响,但说实话不大。编程不是数学竞赛,不需要你智商超群。学历也不是决定性因素,我见过不少学历一般但成长飞快的人,也见过名校出来但几年下来原地踏步的。

观察了这么多年,我发现真正起作用的是三个层面的东西:你这个人本身的特质,你思考问题的方式,以及你选择走什么样的路。这三个层面有递进关系,前一层是后一层的基础。特质不对,思维方式很难建立起来;思维方式没养成,行动再勤快也容易跑偏。

下面一层一层聊。

先说人本身的特质

技术可以学,方法可以练,但有几个性格和态度上的特质,不具备的话,后面的都很难走远。

对编程要有真正的兴趣

这一条放在最前面,因为它是一切的前提。

编程这个职业可以干很多年,前提是你得真喜欢。不是那种刚入行时的新鲜感,而是写了好几年之后,遇到一个有意思的技术问题,你还是会忍不住想深挖下去。有这种状态的人,不需要别人推着走,他自己就会定期回头想想:这一年我进步了多少,哪些地方做得还不错,哪些地方还差得远。这种反思不是刻意为之,是自然而然的事。你打算在这行长期干下去,自然就会关心自己干得好不好。

反过来,一个对编程没什么热情的人,很容易陷入一种循环:接到需求就做,做完交差,等着下一个来。年复一年,技术没什么长进,工作也没什么成就感。

也有人说不清自己是真喜欢还是只是习惯了。有个自测标准:你周末有没有主动打开编辑器写过跟工作无关的东西?不是为了面试,不是为了完成什么任务,纯粹因为好奇。如果你最近一两年从来没有过这种冲动,那至少说明当前的状态离「真兴趣」有距离。不是说没兴趣就做不了这行,只是成长的动力会弱很多,后面那些需要持续投入的事情,坚持起来会比较难。

谦虚、细心、责任心

这三个放在一起聊,因为它们共同指向一件事:你对工作的认真程度。

谦虚这件事,不从「美德」的角度说,从实际后果说。不谦虚的人,代码审查给他提意见,他的第一反应是辩解。线上出了问题,第一反应是甩锅。觉得自己写的代码不会出错,测试走个过场就提交了。这种状态的后果有三个:跟技术成长绝缘,因为听不进别人的建议就没法改进;破坏团队协作气氛,时间一长没人愿意跟他做代码审查了;容易酿成大故障,因为对自己的代码盲目自信,上线前不做充分验证。

细心在编程领域不是加分项,是底线。一个if条件写反了,一个金额计算用了浮点数没做精度处理,一个SQL的where条件漏了一个字段导致全表更新。这些都不是什么高深的技术问题,就是不够细心。在有并发流量的系统里,一行错误的代码上了生产环境,一分钟可能就是几十万的损失。就算现在很多代码是AI辅助生成的,最终的审核把关还是得人来做。粗心大意的人,写出来的代码让整个团队跟着担风险。

责任心的判断标准只有一个:这个人做事需不需要别人盯。责任心不是绩效考核表上的一个打分项,是体现在你做事需不需要别人盯上的。 责任心强的人拿到一个项目,会先把需求完整梳理一遍,不清楚的地方主动找产品对齐。自己列项目计划和关键节点,不是等别人来排期。写完代码会做详细的自测,覆盖各种分支条件,不是扔给测试就不管了。遇到风险会立刻上报,遇到困难先自己尝试解决,解决不了找人帮忙,而不是一声不吭地卡在那里。上线之后还会观察日志,确认模块运转正常。这些表现不需要多强的技术能力,纯粹是态度问题。

这三个特质说起来都是老生常谈。但观察了十几年,做得好的人几乎无一例外都具备这些。它们不性感,也不像学了某个新技术那样有即时反馈,但长期来看,差距就在这里。

对代码要有敬畏心

敬畏心的意思是,你不会随手就写代码。拿到需求不是先敲键盘,而是先停下来想一想:这个东西该怎么设计,接口该怎么定义,数据结构用什么合适,异常情况怎么处理。用一种慢的心态去思考和决策,而不是赶着把功能堆出来。

见过两类人写代码。一类人接到需求,花半天时间想清楚方案,然后用一两天写出来,代码结构清晰,边界情况考虑到位,后续维护成本很低。另一类人接到需求,半小时就开始写,三个小时就提交了,看着效率很高,但后面改bug、处理各种边界问题的时间,加起来远超前面那个人。

有敬畏心的人,对得起自己写的每一行代码,也对得起要读这些代码的同事。 赶工交差的代码和认真设计过的代码,表面上功能都能跑,但在可维护性、可扩展性上的差距是很大的。你现在偷的懒,全都会变成以后的坑,要么你自己填,要么你的同事填。

敬畏心还会驱动你去追问更深层的东西。你不会满足于「会用就行」,你会想知道它为什么是这样的。这个追问的习惯,就是下一层要聊的东西。

比技术栈更重要的思维方式

有了前面那些基本的特质,至少不会走偏。但光有态度还不够,决定你能走多远的,是你思考问题的方式。

会用和真懂是两码事

很多人用一个技术用了好几年,对它的运行机制几乎不了解。框架配好了能跑,就不再深究为什么这么配。日常开发确实够用,直到出了问题。

一个只停留在「会用」层面的人,遇到框架行为不符合预期时,倾向于换个写法试试,或者搜一个现成方案贴上去。一个理解底层原理的人,会去看日志、查源码、搞清楚到底发生了什么,然后做出准确的判断。两种人平时的产出可能差不多,但在关键场景下的表现完全不同。技术选型要做决策的时候、线上故障要定位根因的时候、架构需要调整的时候,需要的是对技术的理解,不是操作的熟练度。

会用一个东西,说明你能完成任务。理解一个东西,说明你能做出判断。完成任务和做出判断,是两种不同层级的价值。

知道一个框架怎么用,和知道它为什么这样设计、底层走的什么机制,完全是两码事。前者是技能,后者才是知识。技能会过时,Spring Boot今天是2.x,明天就是3.x,API变了你就得重新学。但如果你理解了它背后的自动装配原理、条件注入的设计思想,版本再怎么迭代,你都能很快上手,因为核心的设计理念没有变。

举个例子。线上服务响应变慢,一般人能想到的是加缓存、扩容、优化SQL。这些手段没错,但如果不理解慢的根因,操作可能是无效的。理解了线程模型,知道连接池的工作原理,看得懂GC日志,能分析慢查询的执行计划,才能精准定位到问题出在哪一层。这种能力不是靠搜索引擎和反复试错积攒出来的,是靠平时一点一点积累底层认知得来的。

有人会说「工作中大部分时间就是CRUD,哪有机会深挖原理」。这个反驳有道理,但也有个误区。深挖原理不必非得在工作中做。下班后花一个小时读一段源码,周末研究某个框架的设计文档,这种积累不需要等公司给你机会。等到线上出了问题再去临时学,永远来不及。

细节决定了你眼里的系统长什么样

这里说的细节不是代码里变量命名之类的表面功夫,是每一层技术栈里真正在发生什么。

数据从客户端发出来,经过网络到达服务端,在操作系统内核里经历了什么,被Web容器接收后怎么分发到你的业务代码,业务代码里调用了数据库连接池,连接池内部是怎么管理连接的,SQL到了MySQL之后经过了哪些阶段,结果怎么一路返回到你的应用层。这个链路上每一环,你了解得越多,遇到问题时能排查的范围就越大,定位的速度就越快。

有些人排查线上问题又快又准,不是因为运气好,是因为脑子里有足够多的细节。看到一个现象,马上能关联到可能的原因,因为那些底层的运行机制他都了解过。没有这些积累的人,只能一层层猜、一步步试,效率差距非常明显。

你没有理解细节,就无法真正理解全貌。 同一个分布式系统,在不同人的脑子里,它的清晰度是完全不同的。有人看到的是几个方框之间连着箭头,有人看到的是每个方框内部的线程模型、序列化方式、网络协议、故障恢复机制。后者遇到问题时的思路,会比前者开阔得多。

细节了解够了之后,你会发现一件事:你能把复杂的东西用简单的话讲清楚了。很多人觉得自己表达能力差,给别人讲一个技术方案讲不明白,写技术文档写不清楚。大多数时候这不是表达能力的问题,是对那个东西理解得还不够透。当你真正把一个技术点的每个环节都搞明白了,脑子里有清晰的模型,你自然能用通俗的语言讲出来,因为你知道哪些是关键的,哪些是可以省略的,该从哪个角度切入最容易让人理解。

下次如果你发现自己给别人解释一个东西很费劲,不妨先检查一下:是不是自己还有些地方没想透。

经历和经验是两回事

工作年限长不代表经验丰富。

一个人如果每天做的事情都在舒适区里,需求来了按老套路写,线上问题来了按老办法修,三年和十年的差别只是重复的次数多了。经历在增加,经验没有增长。

真正的经验来自于复盘和思考。做完一个项目,回头想想架构上有没有更合理的方案。看到同事用了一种你没想到的解法,研究一下他的思路和你的区别在哪。读到一篇技术文章,对比一下和自己的认知有没有冲突的地方。这些事不需要额外投入大量时间,但能让同样的经历产出完全不同密度的经验。

带团队的时候见过一个工作不到3年的人,排查问题的思路和代码设计的成熟度比一些做了七八年的人还好。后来了解到,他有个习惯:每次遇到问题解决完之后,会花几分钟想想根因是什么,以后怎么避免类似的情况。这个习惯他坚持了两年多。经验的密度,不取决于时间的长度,取决于你从每次经历中提取了多少东西。

有人可能觉得「复盘」说起来容易做起来难,天天赶需求哪有时间。复盘不需要正式坐下来写文档,很多时候就是做完一件事脑子里过一遍:哪些地方做得好、哪些走了弯路、下次遇到类似场景该怎么做。把这个思考变成下意识的反应,花不了多少额外时间。差距就在这个习惯上。

还有一点。简历上能看到的东西,比如技术栈、工作年限、参与过的项目,是筛选的起点,不是终点。真正决定一个人水平上限的,是那些没法写在简历上的东西:拿到需求后怎么拆解问题,碰到陌生技术怎么上手,线上出了故障排查思路是什么。这些底层能力比表面的技术栈重要得多,因为技术栈会变,但分析问题的方式、学习新东西的能力,是稳定的。

思维方式到这里聊得差不多了。但有个问题:要从经历中提取高密度的经验,你得有足够复杂度的经历才行。如果做的项目一直是简单的增删改查,哪怕复盘意识再强,可提取的东西也有限。

具体该怎么做

前面聊了特质和思维方式,这两层解决的是方向问题。方向对了不等于能走到,很多人想法是对的,但卡在不知道怎么迈出第一步。这一部分聊具体的做法。

走出增删改查的困境

你现在每天干的活,接一个需求,建张表,写几个接口,前端传数据过来你存进去,要数据的时候你查出来返回去。你觉得没意思,觉得天天在重复,看不到成长。

为什么分到你手上的都是这种活?因为复杂的任务,主管不会交给你。一个需要深入理解业务、需要做方案设计、需要考虑各种边界情况的任务,交给一个只写过简单接口的人,他不敢赌。所以你手上永远是那些不太需要动脑子的活,你做完之后经验还是简单活的经验,下次分配还是类似的简单活。这是一个循环,得主动打破它。

一个真正有复杂度的业务系统,增删改查可能只占整体工作量的百分之二三十,甚至更少。剩下的大头在业务流程的梳理上,在状态流转的设计上,在多个模块之间数据一致性的保障上,在并发场景下的安全控制上,在代码结构如何应对频繁变化的需求上。这些东西,不亲自去做一个完整的复杂项目,根本碰不到。

怎么打破这个循环?分三步走:

第一步,主动跟主管谈。 明确表达你想承担一个完整的、有一定复杂度的业务模块。不是打杂式地写几个接口,而是从需求理解、方案设计、编码实现到最终上线,你自己负责到底。很多人从来不跟主管提这种事,觉得主管应该主动安排。但主管手下那么多人,谁主动谁就有机会,谁不吭声主管就默认你挺满意现状。

第二步,如果直接拿大项目不现实,退一步。 不要大的,给个中等规模的完整模块也行。关键是「完整」。你得自己去想表怎么设计、接口怎么划分、异常情况怎么处理、跟其他模块怎么交互。这个思考的过程本身就是成长,哪怕你想的方案不够好,主管帮你改,你也比之前只管埋头写代码的时候进步了一大截。

第三步,如果连中等的任务主管也不放心给你,跟着高手学。 跟主管说你愿意作为帮手,跟着某个资深的同事一起做一个中大型项目。看他怎么拆解一个大需求,看他怎么做技术选型,看他怎么处理那些你从来没想过的问题。一个有经验的人做项目时的思考过程、踩过的坑、做决策时权衡的因素,在任何书上都学不到。跟着走一遍,很多之前想不明白的事自然就理解了。

这三步是递进关系,能走第一步就走第一步,走不了就退到第二步,再不行就第三步。但无论如何,得迈出去。

有人会说「我们公司就是小公司,压根没有复杂项目」。这种情况确实存在。即使是小公司的简单项目,你也可以主动给自己加更高的标准。同样一个功能,考虑一下并发量大了怎么处理、数据量大了怎么办、这个模块未来可能怎么变化。项目简单不代表你的思考要简单。如果环境实在提供不了成长空间,那就需要考虑换一个环境了,这也是后面要聊的。

选一个技术方向往深处扎

广而浅的技术栈在市场上不稀缺。会用Spring Boot、MyBatis、Redis、Kafka的Java开发者有几十万。但能把JVM调优做到源码级别理解的、能把MySQL的索引优化和MVCC讲清底层机制的、能在高并发场景下做出正确架构决策的,数量就少得多了。稀缺性决定了你在市场上的议价能力。

怎么选方向?看你当前的工作内容和兴趣所在。做Java后端的,可以选JVM和性能优化、MySQL深度优化、分布式中间件、高并发架构设计中的任何一个方向深入。选哪个不是最关键的,关键是选了之后真的扎下去。

深到什么程度算深?三个自测标准:

  • 核心组件的源码你读过,并且能讲清它的设计思路和关键实现
  • 你能写出有深度的技术分析文章,写的过程就是逼自己想透的过程
  • 面试时你能主动引导面试官聊你的长板,而不是被动回答

之前团队里有个人来面试的时候说:我只会Spring。我问了不少Spring的知识点,他都是从源码级别的维度跟我解释的,非常精准。深度理解源码让他的思路很开阔,回答难题的时候又快又准。他后来去了小米,现在已经是架构师了。面试官在意的不是你会多少种技术,而是你对技术有没有真正研究过。一个在某个方向有源码级深度的人,学其他东西也不会慢。

有人担心选错方向。这个顾虑合理,但过度纠结比选错更浪费时间。先选一个开始深入,深到一定程度后你的技术判断力会变强,要调整方向时,转型成本比浅尝辄止的人低得多。你在一个方向上训练出来的阅读源码的能力、分析问题的框架,换到另一个技术领域上照样能用。深入的经验本身是可迁移的。

环境对人的影响比你想的大

在小公司写代码,很多时候标准是「功能能跑就行」。嵌套几个for循环,SQL不建索引直接连表查,只要测试通过了就提交,因为线上压根没几个人用。这种环境待久了,你的标准会不知不觉往下掉。

当你的系统每天要承接百万级请求时,情况完全不同。一行低效的代码,一个没处理好的并发锁,上线可能就是P0级故障。在那种环境下,周围的同事都很严谨,代码审查会很严格。你被几次线上报警吓出冷汗后,自然就会对生产环境产生敬畏心。你会开始主动考虑边界条件、高并发下的数据一致性、服务的降级和兜底方案。

环境不决定你的上限,但会决定你的下限。 一个高标准的环境会强行拉高你的最低要求。在一个代码审查严格的团队待两年,你的编码习惯和思维方式会被重新校准。这种改变不是自己看几本书能获得的,它来自日复一日高标准下的实战和即时反馈。

具体怎么走?如果当前在小公司,积累一定经验后去中厂当跳板。中厂的项目规模和技术要求比小公司上一个台阶,同时门槛相对没有那么高。在中厂积累了项目经验和技术深度之后,再挑战大厂。大厂的技术体系、工程规范、高并发场景,是在中小公司很难接触到的。经历过几个有量级的项目,你的技术视野和代码品味就完全不一样了。

如果暂时去不了更好的环境,那就在现有条件下找替代方案:参与开源项目,认真研读大厂公开的技术方案和源码,在技术社区里跟有经验的人交流。不要坐等好环境来找你。

也有人在大厂待了几年反而没什么成长,因为大厂分工太细,做的事情很窄,每天就维护一个小模块。环境是必要条件,不是充分条件。进了好环境之后,还是要回到前面说的那些:主动争取复杂项目,主动深挖技术。在哪里都不能做一颗舒服的螺丝钉。

对照表:你现在在哪个位置

把前面三个层面的内容浓缩成一张自评表,你可以对照着看看自己在每个维度上处于什么阶段。

维度 还需提升 基本做到 做得很好
兴趣 当成工作做,下班不碰代码 偶尔学新技术,但不持续 遇到有意思的技术问题会主动深挖
谦虚 不太接受别人的意见 能听取建议并改进 主动寻求反馈,把代码审查当成学习机会
细心 经常因为粗心导致bug 大部分情况下考虑周全 对边界条件和异常情况有本能的警觉
责任心 需要人催才推进 按时完成分配的任务 主动梳理需求、列计划、拉评审、自测到位
敬畏心 拿到需求就开始写代码 会想一想再动手 每次都做方案设计,考虑边界和异常
知其所以然 会用就行,不深究 偶尔看源码和原理 核心技术栈能讲清底层设计思路
关注细节 只关注业务逻辑层 了解部分底层链路 数据链路每一层都有认知
经验密度 做完项目就做完了 偶尔做复盘 每个项目都有总结和沉淀,形成方法论
项目复杂度 只做过简单的增删改查 做过中等复杂度的完整模块 独立负责过核心复杂系统
技术深度 广而浅,什么都会一点 某个方向有一定积累 至少一个方向达到源码级理解

这张表不是用来打分的,是用来定位的。看看哪些维度你已经做到了,哪些还有提升空间。每个人的成长节奏不一样,不需要焦虑,但需要知道自己在哪里、下一步该往哪个方向用力。

小结

做了这么多年开发,越来越觉得一件事:这篇文章讨论的这些特质和思维方式,去掉「Java」两个字,答案也一样。做Java、做Go、做前端、做数据,底层需要的东西是共通的。谦虚、细心、责任心、对代码的敬畏、对原理的追问、从经历中提取经验的习惯,这些跟具体的编程语言和框架无关。框架换了一波又一波,热点年年不同,但这些东西几十年来没变过。

技术能力的成长不是一条平滑的上升曲线。我的感受是它更像台阶,在一个平台上积累了足够多的东西,某个时刻突然上了一个台阶,看问题的角度和以前完全不一样了。台阶之间的积累期,有时候挺长的,也挺枯燥的。能不能熬过去,靠的就是前面说的那些:对这件事有没有真正的兴趣,和愿不愿意用一种认真的态度去对待你每天写的代码。

决定一个程序员能走多远的,不是他会多少种技术,是他怎么对待每一行代码、怎么思考每一个问题。

希望这篇内容可以帮到你。 最近在知乎出了秒杀专栏,感兴趣的可以订阅一下。至于知识星球的,可以搜:

老码头的技术浮生录

它是一个能实际帮你解决难题的星球。有问题的,找知心的Sam哥。

我的知乎账号:

  • SamDeepThinking
相关推荐
凛_Lin~~2 小时前
安卓实现textview跑马灯效果
android·java
我母鸡啊2 小时前
软考架构师故事系列-数据库系统
后端·架构
开源盛世!!2 小时前
4.20-4.22
java·服务器·开发语言
京师20万禁军教头2 小时前
28面向对象(中级)-封装
java
tERS ERTS2 小时前
头歌答案--爬虫实战
java·前端·爬虫
byterun2 小时前
LangChain4j 完整学习指南:从入门到企业级应用实战,看完这一篇你就是AI应用开发工程师
后端
识君啊2 小时前
中小厂数据库事务高频面试题
java·数据库·mysql·隔离级别·数据库事务·acid
掘金者阿豪2 小时前
为什么 LINUX DO 突然这么火?一个程序员拆解背后的5个互联网逻辑
后端