先来简单说下笔者的经历,笔者的研究生专业是电磁场与微波技术,毕业后跨专业选择进入看了一家互联网OTA公司,从事前端开发岗位,19年底加入到字节后又逐渐从前端、全栈转成了全职后端开发,这其中伴随着业务的转变带来的转型需要,也有一部分是自己有强烈的学习意愿,有成长的诉求。虽然我并不推荐你经常这样去做,因为这会让你之前的知识积累、积攒的经验以及所带来的竞争力有所削弱。但于我而言,每一次的转变都非常具有挑战性,我也顺利完成了角色的过渡和转变,这种成长是潜移默化的,我也试着写下我自己的经验之谈,希望能给大家后续发展带来一些借鉴。当然了,这里很多的点虽然只适用于互联网工程师,不过对各行各业的技术类工程师,其中很多基本素养和成长路径究也大抵如此。
成长,泛指事物走向成熟,摆脱稚嫩的过程,是自身不断变得更好、更强、更成熟的一个变化过程。另一方面,成长也是一个复杂、多样且长期的过程,涉及个体在身体、智力、情感、社交等多方面的发展和变化。
首先必须要承认,成长是很个人的事情,我们没办法逼迫每个人都选择成长,各行各业躺平的也大有人在,我们要必须要尊重每个人的选择,成长这个事情也只能由自己亲自经历和感悟才能进行下去。
关于为什么要成长的话题,首先想到的是个人成长带来的工作绩效产出提高,从而带来晋升与年终加薪,这是成长最为直接的回报。其次你的竞争力角度来看,市场竞争力 = 能力/年限,当你工作了N年以后,你是用1年工作经验工作了N年,还是用N年的工作换取了大于N年的工作经验,市场会给出选择,大家应该经常听说过面试不通过的原因之一就是候选人能力与年限不匹配,说明你的成长速度落后了,所以我们必须有危机意识,通过不断成长,以应对业务变动和团队汰换等
最后,成长本身也是个很快乐的过程,成长的过程是个提升认知和祛魅的过程,有句话叫你知道得越多,你不知道的也就越多(如下图),我们成长中不断认识到自身的不足,认识到之前认知的可笑(生命科学、天文物理学的发展过程也是在不断推翻过去的假说),我们学会了用辩证的视角去看待这个世界上的问题。
简而言之,个人成长 = 学习 + 实践 + 坚持学习实践的
作为技术序列,技术是我们的立身之本,技术实力的高低影响着我们设计技术方案的完备程度,影响着我们的研发效率,也决定了我们在职业道路上能走多远,,因此我们要时刻保持着对技术的敬畏之心和技术更新迭代的敏锐度(尤其是终端的发展很快,前端的技术迭代更新也很快)。所以,我们要关注的重心就是如何提升技术硬实力,我列了其中一些点。
这里说的基础包括计算机基础知识,比如,数据结构与算法、操作系统、编译原理、计算机网络、设计模式等等。当然还包括专业方向的基础知识,比如,对于后端开发而言,要掌握数据库(Mysql、Mongodb)、缓存(Redis、Memcached)、消息队列(Kafka、RocketMq)、RPC(thrift、gRpc)、微服务与分布式计算原理等等;对于前端开发而言,我们要掌握前端三剑客(Html、Css、JavaScript),前端框架(Jquery、React、Vue)、代码打包工具(webpack、babel)、NodeJs、网站性能优化(常见的像代码分割、资源懒加载、浏览器缓存策略、cdn加速)、跨端技术(React Native、Flutter)等等。
上面提到掌握的意思是我们不仅要熟练掌握每个技能点的应用,不是说仅仅会调用API就算掌握了,更要了解其实现的底层原理,比如,我们要去理解为什么Mysql innodb引擎要选择B+树作为索引,相比B树有什么优势和弊端,为什么Redis集合类型选择跳表而不用平衡树、红黑树或者 B+树,明白了这些底层原理你才能在实际工作中做出比较好的技术选型。
要多看优秀的代码,比如,一些开源框架、内部的公共库,只有你看得足够多并且多思考总结,才能知道什么是好的代码和架构,什么是差的,我们要树立这个评判标准,这个认知对你很重要。
在通过观察和分析优秀代码的过程中,感受他们在代码设计上的优劣,借鉴他们的经验提升自己的编码水平。
我们在读源码的时候,要注意学习顺序,从整体到细节,要抓大放小,比如,看懂一个函数,主要看懂这个函数对哪些数据做了什么处理,最终对外输出了什么数据,函数的本质就是这个,函数中一些特别生涩难懂的API可以先放一放。还有值得一提的是,我自己在看源码的时候,之前只能通过把源码clone到本地,然后写测试代码debug去看懂其中的逻辑,效率比较低不过也确实没有特别好的办法,去年依赖LLM火了以后,我会通过一些AI工具(如下图)或者bot agent去辅助理解代码,提效很明显。
必须要承认字节是个藏龙卧虎的公司,在你身边有非常多优秀的同事,你可以找到你认为的身边代码写得不错的同事,多去(偷偷)看看他们写的代码,学习他们的设计模式、编码逻辑和代码风格。除此之外,也可以多参与类似下面这样的活动。
无他惟手熟尔,出自宋代文学家欧阳修《卖油翁》,说明了熟能生巧的道路。
如何才能写出更鲁棒的代码,平常可以多去看看团队以及公司内的各种研发规范,比如,分层规范、Mysql规范、代码规范、CR规范等等,这些规范在一定程度上就代表着某个领域的最佳实践。这里不是鼓励大家去背诵规范,而是要去思考这些规范背后的原因,出发点是什么,解决了什么问题?我们站在他人的视角去思考为什么会这么去制定规范,当你多思考这些的时候,你就能更深刻的理解这些开发规范,进而在你自己进行代码编写的时候,潜移默化的影响你的个人习惯。当然了,如果你对其中的规范不理解或者有不同意见的时候,也要多去与规范制定者进行沟通,甚至发起挑战。
在遇到具体问题的时候,我们不光从实现层面看,也能从业务价值、架构稳定性、架构规划层面看,理解业务并知道为什么做,理解系统并知道为什么这么设计,带着架构的视角去看待一个问题的生命周期。
在分析问题方面,建议大家养成结构化思维是指在思考分析解决问题时,以一定的范式、流程顺序进行,首先以假设为先导,对问题进行正确的界定,假设并罗列问题构成的要素,其次对要素进行合理分类,排除非关键分类,对重点分类进行分析,寻找对策,制订行动计划。 这是一种思维方式,同时也是一种管理方法。
在解决问题的时候,我们要尝试对业务逻辑进行抽象和分解,这样可以帮助我们理清逻辑简化问题。利用抽象思维抽象能力,使得模型有更大的应用空间。分解业务逻辑,使系统更可控、更具可扩展性,而且每个小的功能服务更具独立性,提高了系统的稳定性和开发效率。
作为业务研发,我们的核心工作就是支撑业务发展,所以在熟悉工程代码的同时以宏观的视角去了解一个业务领域的知识是非常重要的,这也就是为我们做业务技术规划和搭建微服务提供了帮助,在DDD领域驱动设计中,我们也通常会使用事件风暴建模的将领域专家和项目团队聚集在一起,通过可视化、高互动的方式一步一步将领域模型设计出来。
回到这个问题上,我们需要了解业务在公司中的定位和角色、业务产出和收益、业务流程
我拿我所在团队的业务举个例子。团队负责的创作者业务,对内,面向抖音的各个创作者业务,形成创作者业务阵地;对外,面向创作者,打造经营平台的心智。经营平台的未来应该是一个一站式解决作者经营链路上所有问题的集成平台,通过提供便捷强大的业务集成能力,让业务形成合力,进而提高作者经营体验和效率。它围绕作者的不同时期的诉求,引入期、成长期、成熟期对应所需要的创作、成长、变现诉求提供帮助。
通过了解业务的长期方向、业务的背景和存在的原因,了解业务链条中的角色和分工,深入了解业务流程,可以更好地理解业务的全貌。了解当前业务是如何给公司带来收益的,评估业务的长远发展目标是否清晰,有助于你在技术上做出前瞻性的规划和决策。
提升个人影响力的关键在于建立信任感,让他人相信你的判断力。
首先必须要承认,在大厂上班确实会很忙碌,业务需求感觉永远做不完(也因部门和岗位而异),这是一个现实且普遍存在的情况。在快速变化的商业环境中,需求的不断涌现也是常态。因此,首先我们需要接受并适应这种设定,而不是期待某个时间段有空闲再来思考对系统的优化。
其次,我们也会常常对产品提出的需求有各种吐槽,甚至抱怨。比如,我们会抱怨某个需求太复杂或者太简单,但我们是否思考过是不是架构上有不合理的地方导致工作量膨胀,为了快速验证功能是否可以拉产品讨论砍掉一些不那么重要耗时的功能点。又比如,我们会抱怨老是有很多不那么兼容当前架构的改造(加个兼容字段,流程异化)的需求,但我们是否思考过这些不复杂但占人力且技术价值不高、这改动最频繁的是哪些东西?有没有什么共性可以抽象?是不是可以通过配置化的方案来减少这类需求的研发介入?总之,有这种抱怨是正常,抱怨说明你感受到了问题,但不要只停留在抱怨,在这个基础上,进一步去思考如何把事情变得更好。
我们要记住我们不要只是做需求,而是在每个需求中思考/学习,当你感觉到业务中的痛点,代码的相似和冗余时,请开始你的抽象,最后在实践中不断迭代特性,使之更适应更多场景。我们在善于利用碎片时间,比如,在日常工作中,利用一些零散的时间段进行小范围的优化。例如,在会议间隙、午休时间或等待任务完成的过程中,进行代码优化、文档整理等。
一般而言,我的建议是在掌握一定的技术广度下去追求技术深度,这两者并不矛盾,而是一种相辅相成的关系。
技术本质上是用来解决业务问题的。对于技术深度和广度的提升,建议先专注于技术深度,再逐步拓宽广度。毕竟每个人的时间是有限的,我们不可能精通所有的技术,但我们可以努力地精通工作相关的、有前景的、感兴趣的技术,向T型人才靠拢
一般而言,创业公司或者初创公司,是比较喜欢既有广度的技术人才,因为这个可以面面俱到,而大公司一般都是要求技术深度的人才,因为大公司只要求一个螺丝钉。
为什么我认为要技术深度很重要,举个例子,在我们新接触一门编程语言的时候,我要能掌握编程语言的核心特性并深入底层原理,比如,对于 Go 语言,要充分掌握 Channel、锁、Context 等核心机制。编程语言本身只是工具,编程语言之间的学习也是触类旁通的,当我们精通了一门语言,再学习其它语言我们发现是有非常多共性的,比如你学习了Java 转向 go,会非常容易上手,因为,基础数据类型类似,面向对象编程的思想可以互通,内存管理,垃圾回收机制也都有着非常相似之处。
提升技术深度是解决业务问题的基础。通过掌握编程语言的核心特性,持续学习和实践,可以提升基础能力。在技术选型过程中,保持怀疑和思辨的态度,深入学习选中的技术,并进行模拟设计,有助于提升技术深度。注重实现细节,如变量命名、函数定义、接口设计等,能够不断打磨和提升自己的技术能力。通过这些努力,逐步成为某一领域的专家,然后再拓展技术广度,提升整体技术水平。
机遇和努力哪个更重要呢?当然是机遇更重要。但机遇可遇不可求,我们自己可以把握的只有努力。
关于时间分配其实有很多方法论,我们都知道一个时间管理四象限法则,我会优先解决重要且紧急的工作,制定计划去做重要但不紧急的工作,不重要但紧急的工作交给别人去做,尽量别去做不重要且不紧急的工作。
时间“四象限”法是美国的管理学家科维提出的一个时间管理的理论,把工作按照重要和紧急两个不同的程度进行了划分,基本上可以分为四个“象限”:重要且紧急、非重要但紧急、重要非紧急、非重要非紧急。
有个小tips,我们可以在周末的时候抽1小时左右的时间,review本周自己时间都花在哪了,通过整理能发现哪些是「不重要的-但花了很多时间」、哪些「重要-但没做的」,在下周的日程安排中,就可以把重要的排前面。通过几次次的review就能发现问题,调节好自己的时间分配。
我建议大家还是要选择固定时间学习,碎片时间适合快速获取信息,但不太适合思考学习,所以最好保证你的学习时间跟深度就需要系统性进行学习,最好是自顶向下进行学习,例如要学习kafka,先了解整体框架,再根据时间补足各个方面的知识,MQ可能有20个子topic(架构/容灾/数据结构/稳定性等),先能有个大面了解,再看从各点补齐整个面,这样能清晰感知到自己哪些了解了,哪些还不了解。同时注重可迁移知识的学习,多做沉淀分享,有输入就要有输出,不管是文档还是分享都可以,总之要有沉淀,写不写对于学习而言完全是两个强度的要求。
成长其实还是对人的基本素质有很高的要求,我们会发现成长速度很快的人往往有下面这些特质(包括但不局限),具体特质的详细介绍这里先不展开讲了,后面有时间再展开说说。
就像《浪潮之巅》里讲述公司的一样,寻找那股浪潮,选择最有活力的行业,选择好的公司,业务和团队,随着业务一起成长。永远不要单纯的为了职位和钱去做选择。共勉~
本文作者:sora
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!