有个现象做了若干年之后回头看特别明显起点差不多的人三五年后差距就拉开了。有些人三年能独当一面带着团队做核心系统。有些人干了七八年还在接需求写接口稍微复杂一点的任务交不到他手上。差距来自哪技术天赋有一点影响但说实话不大。编程不是数学竞赛不需要你智商超群。学历也不是决定性因素我见过不少学历一般但成长飞快的人也见过名校出来但几年下来原地踏步的。观察了这么多年我发现真正起作用的是三个层面的东西你这个人本身的特质你思考问题的方式以及你选择走什么样的路。这三个层面有递进关系前一层是后一层的基础。特质不对思维方式很难建立起来思维方式没养成行动再勤快也容易跑偏。下面一层一层聊。先说人本身的特质技术可以学方法可以练但有几个性格和态度上的特质不具备的话后面的都很难走远。对编程要有真正的兴趣这一条放在最前面因为它是一切的前提。编程这个职业可以干很多年前提是你得真喜欢。不是那种刚入行时的新鲜感而是写了好几年之后遇到一个有意思的技术问题你还是会忍不住想深挖下去。有这种状态的人不需要别人推着走他自己就会定期回头想想这一年我进步了多少哪些地方做得还不错哪些地方还差得远。这种反思不是刻意为之是自然而然的事。你打算在这行长期干下去自然就会关心自己干得好不好。反过来一个对编程没什么热情的人很容易陷入一种循环接到需求就做做完交差等着下一个来。年复一年技术没什么长进工作也没什么成就感。也有人说不清自己是真喜欢还是只是习惯了。有个自测标准你周末有没有主动打开编辑器写过跟工作无关的东西不是为了面试不是为了完成什么任务纯粹因为好奇。如果你最近一两年从来没有过这种冲动那至少说明当前的状态离「真兴趣」有距离。不是说没兴趣就做不了这行只是成长的动力会弱很多后面那些需要持续投入的事情坚持起来会比较难。谦虚、细心、责任心这三个放在一起聊因为它们共同指向一件事你对工作的认真程度。谦虚这件事不从「美德」的角度说从实际后果说。不谦虚的人代码审查给他提意见他的第一反应是辩解。线上出了问题第一反应是甩锅。觉得自己写的代码不会出错测试走个过场就提交了。这种状态的后果有三个跟技术成长绝缘因为听不进别人的建议就没法改进破坏团队协作气氛时间一长没人愿意跟他做代码审查了容易酿成大故障因为对自己的代码盲目自信上线前不做充分验证。细心在编程领域不是加分项是底线。一个if条件写反了一个金额计算用了浮点数没做精度处理一个SQL的where条件漏了一个字段导致全表更新。这些都不是什么高深的技术问题就是不够细心。在有并发流量的系统里一行错误的代码上了生产环境一分钟可能就是几十万的损失。就算现在很多代码是AI辅助生成的最终的审核把关还是得人来做。粗心大意的人写出来的代码让整个团队跟着担风险。责任心的判断标准只有一个这个人做事需不需要别人盯。责任心不是绩效考核表上的一个打分项是体现在你做事需不需要别人盯上的。责任心强的人拿到一个项目会先把需求完整梳理一遍不清楚的地方主动找产品对齐。自己列项目计划和关键节点不是等别人来排期。写完代码会做详细的自测覆盖各种分支条件不是扔给测试就不管了。遇到风险会立刻上报遇到困难先自己尝试解决解决不了找人帮忙而不是一声不吭地卡在那里。上线之后还会观察日志确认模块运转正常。这些表现不需要多强的技术能力纯粹是态度问题。这三个特质说起来都是老生常谈。但观察了十几年做得好的人几乎无一例外都具备这些。它们不性感也不像学了某个新技术那样有即时反馈但长期来看差距就在这里。对代码要有敬畏心敬畏心的意思是你不会随手就写代码。拿到需求不是先敲键盘而是先停下来想一想这个东西该怎么设计接口该怎么定义数据结构用什么合适异常情况怎么处理。用一种慢的心态去思考和决策而不是赶着把功能堆出来。见过两类人写代码。一类人接到需求花半天时间想清楚方案然后用一两天写出来代码结构清晰边界情况考虑到位后续维护成本很低。另一类人接到需求半小时就开始写三个小时就提交了看着效率很高但后面改bug、处理各种边界问题的时间加起来远超前面那个人。有敬畏心的人对得起自己写的每一行代码也对得起要读这些代码的同事。赶工交差的代码和认真设计过的代码表面上功能都能跑但在可维护性、可扩展性上的差距是很大的。你现在偷的懒全都会变成以后的坑要么你自己填要么你的同事填。敬畏心还会驱动你去追问更深层的东西。你不会满足于「会用就行」你会想知道它为什么是这样的。这个追问的习惯就是下一层要聊的东西。比技术栈更重要的思维方式有了前面那些基本的特质至少不会走偏。但光有态度还不够决定你能走多远的是你思考问题的方式。会用和真懂是两码事很多人用一个技术用了好几年对它的运行机制几乎不了解。框架配好了能跑就不再深究为什么这么配。日常开发确实够用直到出了问题。一个只停留在「会用」层面的人遇到框架行为不符合预期时倾向于换个写法试试或者搜一个现成方案贴上去。一个理解底层原理的人会去看日志、查源码、搞清楚到底发生了什么然后做出准确的判断。两种人平时的产出可能差不多但在关键场景下的表现完全不同。技术选型要做决策的时候、线上故障要定位根因的时候、架构需要调整的时候需要的是对技术的理解不是操作的熟练度。会用一个东西说明你能完成任务。理解一个东西说明你能做出判断。完成任务和做出判断是两种不同层级的价值。知道一个框架怎么用和知道它为什么这样设计、底层走的什么机制完全是两码事。前者是技能后者才是知识。技能会过时Spring Boot今天是2.x明天就是3.xAPI变了你就得重新学。但如果你理解了它背后的自动装配原理、条件注入的设计思想版本再怎么迭代你都能很快上手因为核心的设计理念没有变。举个例子。线上服务响应变慢一般人能想到的是加缓存、扩容、优化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