背景
距离毕业到已经三年多了, 距离实习到现在已经三年半了, 在主管的建议下, 8月17号在公司的研发部门做了 一场关于成长的分享, 从工作方式到技术能力提升对自己三年的成长进行了一个复盘, 幸运的是分享得到的反 馈非常好, 老板看了将录屏在整个研发部进行公布并且推荐大家观看, 这是部门内分享活动以来第一次公示与推荐录 屏的情况, 我自己也感觉非常感慨, 毕业以来, 一直朝着"一年入门, 三年高工、五年资深、七年架构"的目 标前进, 有时候回过头来会发现这一路还是挺有意思的, 借着这样一个平台, 以文字的形式描述出来, 期望 能够给前行路上的各位有一定的帮助
下面的描述中, 为了不暴露个人信息, 对公司名称的描述统一替换为 XX, 涉及到人名的我都会进行打码
一、为什么做这个分享(why)
1.1、原因一
主管说从实习加入XX三年半以来, 看到我成长了很多, 推荐我可以做一下关于个人成长这一块的分享
1.2、原因二
我个人仔细的想了一下, 三年半前加入XX, 当时公司才400多人, 没有一个正式的java团队(公司主c#), 三年半的时间, 公司发展到了750多人, 我经历了java团队从0到1的完整过程(目前已经有3个java团队, 加起来有接近30个java开发), 并且在这三年半的时间, 公司的后端业务项目开始从.net往java迁移, 有大量的重构项目和新的大型项目, 在此期间, 经历了可能有10个以上从0到1的大型项目的落地, 并且这些项目中我个人承担了绝大部分的核心功能开发, 在这些项目的锻炼下, 不管是技术还是工作方式方面, 都有学习到非常多的知识, 借着这样的机会复盘一下, 继续完善自己, 我主观认为这样的经历可能会有一定的参考价值, 期望能够通过这样的一个分享, 能够给一些可能遇到瓶颈或者跟我遇到一样问题的同学一些启发
二、工作方式上的成长及建议
2.1、需求方案的决策
Pre: 遇到问题 / 需求我应该怎么做, 还没有独当一面的能力
Now: 遇到问题 / 需求我思考可以怎么做, 并从自己的角度出发提出方案, 标识每个方案的优缺点, 询问应该怎么做(即使提出的方案都不是最优解, 但是有自己的思考, 并且在遇到更合适的方案时能有一个对比学习)
截图是两个例子, 在我实现功能的时候, 有不同的方案, 在把握不准哪种方案比较合适的情况下, 向主管进行询问, 对可行的方案的优缺点进行分析, 在主管多年的经验下确定最终的实施方案
2.2、需求功能的实现和上线
Pre: 需求处理完, 简单的自测或者压根就不自测, 测试流程走完以后发上线就不管了(在工作过程中其实有遇到许多同事也是这样), 在刚来实习以及刚毕业那段时间, 一个功能编码完以后测试反馈了许多的bug问题, 改了一个旧的出现一个新的, 之前有听过一个段子, 测试听到开发说的最多的是什么(我没改代码 / 网络问题 / 你再试试), 这个段子就在我身上出现了, 当时改一个功能, 连续几次都没改好(因为改完后没有充分验证就提测了), 见下图(2021年的聊天记录)
Now: 需求处理完, 充分的自测, 提测以后多次跟进测试同学的测试情况, 上线后跟进线上是否正常使用, 找产品进行验收流程
Suggest: owner意识、需求从哪里开始就从哪里结束, 回调产生事件的人, 形成闭环
owner意识是主管在小组中提出来的一个工作方式, 是说一个开发, 在多人协作的场景下, 不能只关注自己那一块的功能, 需要对整个流程有充分的了解, 以一个owner的角色参与到项目开发中, 跟进其他端的对接, 把控整个项目的进度, 要做到这个其实是很难的, 需要花费更多的精力, 但是一旦做到了, 对整个项目就有一种非常清晰的感觉, 能够更好的完成多人协作项目的落地, 需求从哪里开始就从哪里结束, 每次一个需求处理完以后, 我会严格按照 自测 -> 提测 -> 联调 -> 督促产品验收 -> 灰度环境发布及验收 -> 正式环境发布及验收 -> 同步所有有关开发自己的功能的发布情况
在这样一个闭环的链路中, 功能的落地和稳定有了非常明显的提高
2.3、句句有回应, 事事有着落
Pre: 忙的时候忘记回消息, 事情多的时候忘记一些临时分配的事情, 遇到的坑重复跳
Now: todoList、QQ置顶, 多检查(防止多次返工), 防止重复的问题重复出现(错别字)
todoList: 我是通过一个txt文件来进行一个记录的(当然有更合适的, 只是用习惯了), 会记录手上的需求有哪些, 每一个的进度是怎么样的, 上线流程是怎么样的, 我给自己定的上线流程中分为以下几步, 并且在上线的过程中严格的按照下面的流程进行操作, 这样极大的提高了上线的稳定性(特别是一些大版本的发布, 有这样的严格流程下, 稳定性有了非常明显的提高)
1、是否有旧数据需要处理
2、是否有sql脚本需要执行
3、是否依赖于其他人的功能
4、是否有单独服务器灰度的需求, 有些业务需要单独一台服务器来进行灰度, 然后通过nginx将部分流量转发过来验收
5、开始灰度, 灰度后产品验收, 全部负载发布完毕后回调需求开始的人, 形成闭环
QQ置顶: 我们公司是采用QQ作为沟通工具的(可能是因为很早之前就是用这个, 即使现在有企业微信, 但是沟通这一块大家都不太倾向于切到企业微信), 当在外面或者遇到其他比较紧急事情时有人找或者发消息, 可能看完就忘记回了, 于是我养成一个习惯, 有人发消息没时间回的, 第一时间置顶, 等有空后再来跟进, 跟进完后取消置顶
防止重复的问题重复出现: 我们需要写周报, 刚开始的时候有出现错别字、格式不正确、周报字数过多的情况(主管规定周报不能超过250个字), 后面为了避免这种情况, 我每次写完都会阅读两遍内容, 防止之前产生的问题重复发生, 每个人都有粗心的时候, 也不能保证不出现错误, 但是我们可以通过一些方式方法来尽量的避免错误的重复发生
2.4、学习别人优秀的地方
人无完人, 比如我有时候说话会比较直接(好吧, 我是直男....), 那时主管就让我在沟通这一块多跟斜对面的同事学习一下, 后面我就观察他的沟通方式, 然后自己从模仿开始, 慢慢的也学会了怎么进行有效的沟通、委婉的拒绝等, 学习别人优秀的地方也是成长中比较重要的一环
2.5、批量接口的重要性
Pre: 对需求的时候遇到一个问题就问一次, 效率低, 刚来实习的时候, 不熟悉业务, 当时接触到一块比较复杂的涉及到购物车优惠计算的业务, 当时跟对方讨论的时候, 遇到一个不懂的就直接去问, 多次打断他的工作, 效率非常低
Now: 对整个需求进行梳理, 整理所有的疑问一次性请教, 效率提高了很多, 也不会容易打断别人的工作(反到现在我经常被别人打断=,=看到了曾经的我....)
2.6、做的事太简单, 没有挑战性
今年带了一个实习生, 刚开始给他分配的工作都是比较简单的, 主要是修bug、小需求, 但是即使是这样简单的功能, 他做的也是磕磕碰碰, 比如代码规范不达标、空指针异常判断不全面、业务涉及到的点想的不全面等等许多瑕疵, 多次需要我来进行一个兜底, 后面他跟HR反馈说太简单没有挑战性, 于是我就分配了一个稍微大的一点需求给他, 结果做的惨不忍睹, 后面他实习结束时这个需求才做到一半, 我转给其他同事帮忙接手....结果那个同事看到代码后对我吐槽了许久....
当时收到反馈后, 我及时的找他进行沟通, 我的观点是他做的每一个简单的需求, 需求的完整稳定上线都是为了给主管建立一个做事靠谱的印象, 如果做事不靠谱, 经常需要他人来进行兜底, 那么谁也不敢把复杂重要的任务交给你做, 公司很多业务都涉及到商家的钱, 一旦这种重要的业务出问题, 那么会给公司造成巨大损失, 其实仔细想想, 自己实习那会也差不多, 想要做很厉害的项目, 用很流行的技术, 但是如果自己给人的感觉是不靠谱的, 那么主管自然就不敢把这些项目交给我了, 明白了这一点后, 当时我毕业一年给主管的目标是一个需求功能下来, 不管大小, 测试反馈的bug不能超过3个, 一个月产生的线上事故不能超过1次, 我努力做到了这一点, 线上事故几乎没发生过, 随之而来的是小组中绝大部分核心的业务、基础组件的开发都由我来处理, 以及一波大的涨薪
2.7、内卷
维基百科: 原是一个社会学概念,指一种文化模式发展到一定水平后,无法突破自身,只能在内部继续发展、复杂化的过程。大约从2018年开始,"内卷"一词在中国大陆变得广为人知,并引申表示付出大量努力却得不到等价的回报,必须在竞争中超过他人的社会文化,包含了恶性竞争、逐底竞争等更为负面的含义。
我们公司965几乎不加班, 所以我们6点会有比较充足的时间, 我一般去楼下吃完饭以后就会回到公司学习, 三年半的时间阅读了大量的源码书籍、学习了许多知识, 个人认为, 深入学习技术, 提高自己其实不属于内卷, 无意义的加班, 内耗等才是内卷, 其他小组也有人说我比较卷, 但是我们小组(包括主管)都是知道我晚上下班后是在公司学习的, 也很少会加班, 借着分享的机会我也跟大家澄清了这样的情况, 并且我们小组的氛围并没有因为我下班后的学习而导致整个小组都晚下班的情况(公司7点左右就基本空了.....)
三、技术能力上的成长及建议
3.1、如何学习
一、我学习一门未接触过的技术时, 会先看视频学习, 建立基本认识, 并且能够从讲师身上学到一些经验, 即先学会简单的使用 二、在了解了基本使用, 并且用起来的情况下, 我会查找跟该技术有关的权威书籍, 对权威书籍的学习是为了建立完整的知识体系
这个学习方式是我从大学以来就保持的, 而我认为这也是对我来说是最合适的学习方式
3.2、打地基-基础知识的重要性
基础知识对一个程序员来说是非常重要的, 个人认为基础越扎实的同学往往在学习技术的时候会吸收的更快, 并且也能够走的更远
一、数据结构, 我学习数据结构的时候, 会手写每个数据结构, 即使是最难的红黑树, 我也手写出来了(当时在大学的时候花了一个下午就为了写一个新增节点和删除节点的方法), 对于数据结构的学习, 我推荐: 恋上数据结构 这套视频, 讲的非常好, 大家如果有兴趣的话可以各显神通的去找找=,=
二、计算机网络, 计算机网络我是通过看视频加书籍的方式来学习的, 视频推荐: 韩立刚, B站就能搜到, 讲的通俗易懂, 我推荐了几个朋友看, 都反馈非常棒, 书籍推荐 计算机网络 第六版(考研408专用)
三、操作系统, 对操作系统的学习, 能够让我们在了解JVM、以及一些底层知识的时候(比如CAS、volatile、synchronize等原理)能够更加的顺利, 他们都是依赖于操作系统相关的知识来的, 视频我推荐: 哈工大的计算机操作系统, B站能搜到, 书籍推荐计算机操作系统(考研408专用)
四、汇编语言, 如果有看过深入理解Java虚拟机这本书, 那么里面就有出现跟汇编相关的话术, 如果对汇编有所了解, 能够亲身的体验到寄存器操作、中断的原理等, 这些在学习操作系统等知识的时候必然会遇到的话术, 视频我推荐推荐: 小甲鱼, B站就能搜到, 书籍我推荐(汇编语言(第3版) 王爽)
五、设计模式, 刚开始写代码的时候, 会一个方法写很多逻辑, 就像流水账一样, 一直写下去, 没有考虑复用等情况, 通过学习设计模式, 我们可以写出更加优雅的代码, 模板方法、单例、工厂等模式的使用能够使得我们的代码阅读性更高、扩展性更强, 学会了设计模式的情况下, 再去看自己之前写的代码就会发现还能写的更好! 并且有了这个知识的基础上, 我们去看一些框架源码的时候会更加顺利, 框架源码用到设计模式的时候命名都是通俗易懂的, 看到名字就知道用了什么模式, 就像程序员之前互相沟通一样, 这个我没有看视频, 我看的是 HeadFirst设计模式 这本书籍, 通过一些生动形象的例子, 把设计模式讲活了...
3.3、创造核心竞争力-不停留在只会用的地步
java开发往往离不开spring的生态系统, 框架开发出来就是给人更加方便开发功能用的, 如果仅仅会用, 那么在遇到一些问题的时候会无从下手, 三年半的时候, 我阅读了spring、springmvc、mybatis、springboot、springcloud等框架的源码, 通过书籍加视频的方式深入的了解了这些框架的原理, 看这些框架源码的时候, 不纠结于一些边线知识, 只管主线流程, 了解主线流程后, 我发现后续遇到问题时, 我能非常自信的跟进源码去排查问题, 在第四章节中我会整理每一个框架我都是通过哪些书籍来深入学习的
3.4、学以致用-尝试输出(github / 博客 / 分享)
学习一个知识, 如果仅仅看了一遍书 / 看了一遍视频, 那么可能过几天就会忘记了, 一般我是通过看视频 -> 记笔记 -> 看书 -> 对书中的知识点进行整理笔记, 笔记采用类似于给他人讲解的方式来记录 -> 将笔记记录在github 或者 以博客的形式分享出来, 在这样的链路下, 我每一步都能更加深刻的学习到知识点, 有时候看书看懂了不代表真懂了, 真正用笔记来描述的时候会发现是磕磕碰碰的, 与此同时, 将这些磕磕碰碰的知识去再次学习, 那么对整个知识点就会有更加全新的认识, 大家也可以看到, 我的掘金的博客是从2020年就开始写了, 都是我个人的口头描述转为文字描述
3.5、有枪不用和无枪可用
在掌握了工作中需要的知识点的情况下, 我们需要去学习流行的技术, 防止自己落伍, 技术的迭代更新是非常快的, 学习这些技术, 往往会给自己带来意想不到的结果
一年前公司我深入的去研究了eureka、zuul等springcloud组件的原理, 后面幸运的是, 公司有一个私有化部署的项目, 主管的计划是用微服务来搭建, 这个项目需要考虑到客户的资源, 有些客户可能预算比较高, 我们就可以提供一套完整的微服务来运行, 有些客户预算比较低, 那么可能最多就跑3-4个java项目, 于是主管的要求是我们的微服务功能, 需要能够满足上述的情况, 能够非常方便的将一个或者多个服务合并成一个服务, 并且自由搭配
正是因为我有对这些组件的深入了解, 我从源码层次提供了一套实现方案, 并且是最简单的实现方案, 主要的原理就是控制bean的加载(打包的时候一起打包, 但是不加载到内存)以及内部 rpc调用时的扩展(利用回环地址来尽可能的忽略http请求的花销), 如果我没有对这一块有所掌握, 那么我可能就失去了这样一个非常好的锻炼机会了