程序员的自我修养
概述
提炼内容来自书籍<<阿里工程师的自我修养>>,时常阅读回顾,勉励自己!
技术人需要具备"结构化思维"
什么是结构化思维
结构化思维: 逻辑+套路
- 表达要有逻辑(逻辑性)
想让表达内容有逻辑,需要学会四种组织思想的逻辑关系,实际上所有逻辑都在这四种顺序之内,只要我们的思想和表达在这四种逻辑顺序之内,就是有逻辑的:
- 做事要有套路(方法论)
套路是指我们解决问题的方法论,比如经典的5W2H分析法,就是可以帮助我们分析问题的一个"套路".
5W2H: 即面对任何一个问题都能从 Why,Who,When,Where,WHat,How,How much七个点状方面去思考,就会思考的全面得多
如何进行结构化思考
-
建立中心
建立中心也就是要定义清楚要解决的问题,明确目标.也就是先搞清楚Why,然后再进行how.
建立中心两种方式:- 自上而下: 适用于问题比较明确的情况,只需要找到问题核心,即为中心
- 自下而上: 适用于问题不够明确情况,需要对多种杂乱的内筒,进行分类,归纳汇总成一个中心
-
结构化分解
建立中心之后,需要构建一个结构,使用结构化思维进行分解,策略就是上文提到的四种顺序.
比如第一.....第二.....第三...... 或者首先....然后....再者.....
在空间分解的时候,注意要满足MECE(相互独立,完全穷尽)原则:
比如前端bug,程序员A的bug,这种分类是混乱的,可以按照前端bug,后端bug这种分,没有重复和遗漏
结构化思维应用
-
落地(适应)新团队
刚刚入职一家公司或者转岗到一个新团队,如何落地开展工作?- 建立中心
企业核心要素:业务,技术,人才,即这三个要素就是中心
graph TB; A[企业] --> C[业务] A --> D[技术] A --> E[人]- 结构化分解
将三个中心结构化分解:
graph TB; A[企业] --> C[业务] A --> D[技术] A --> E[人] C -->F[产品形态] C -->G[业务流程] C -->H[走访客户] D -->I[系统架构] D-->J[领域模型] D-->K[代码结构] E-->L[组织机构] E-->M[人员角色] E-->N[拜山头] - 建立中心
-
打造极客文化
-
做晋升述职
-
罗列事情
-
价值的背后
把价值说清楚的确很重要,但是仅仅阐述价值是不够的,还需要明确价值背后的过程和思考,比如:你让公司产品用户率提高了百分之10,那评为可能会问:
1 之前为什么很低
2 为什么你的方法可以提高用户率,原因是什么?
3 产品中具体解决了什么问题
4 是否可以总结出一套办法,以后别人也可以用这个办法解决这些问题
如果在评委之前提问,就能对这些问题进行深入结构化思考和呈现,那么就是既有过程又有结果!
-
优秀工程师必备的三大思维
工程师思维可以分解为三大思维:
1. 产品思维
- 痛点: 产品思维的起源是用户价值, 用户给价值是通过技术手段以产品或者服务的形态去解决用户的痛点或者带去爽点 ,工程师在工作或只能怪应时刻关注并理清自己的动作与用户价值的联系,并聚焦于用户价值去安排工作的优先级和分配自己的精力
- 体验: 良好的用户体验一定是站在用户的角度.基于用户心智来塑造概念,由于概念存在理解和解释成本,概念应足够轻,少且易于掌握. 好的产品体现在"易用"二字
- 特性: 特性是产品差异化的一种体现,特性也间接地确定了软件实现层面的功能模块边界.作为开发工程师,需要对产品特性有非常透彻的理解.并能将其很好的抽象转化为实现层面的功能模块
- 效果: 什么是闭环 , 通过闭环让整个产品聚焦于用户核心价值,还能帮助团队在探索用户价值的道路上做减法(大多数情况,减法远难于加法)
2. 技术思维
- 需求: 技术思维的源头是需求 ,需求一旦出现偏差,所导致的浪费是非常严重的.所以工程师对于需求质量需要相当重视
- 功能: 需求一旦确立,会基于模块化的思想拆分成多个功能模块去降低实现的局部复杂度,最终将所有功能模块“拼接”在一起去实现整体需求。每个功能模块会安排给一
个人或一个团队负责,由于功能模块是需求分解后的产物,容易导致工程师在实现的过程中只看到“树木”而忘记了“森林” - 性能: 当功能模块被运用于高频、时效性敏感、算力有限的场合时性能将尤其被关注
- 先进: 快速跟上技术的迭代步伐是每个有追求的工程师不断提升自己专业素养的表现之一
3. 工程思维
- 流程: 工程思维的起点是流程,通过过程控制确保最终结果让人满意。由于流程涉及每一个工程师的工作质量与效率,其含义不只在于定义、工具化、检查等内容,而是应基于工程师的日常工作习惯,将流程与工程师的工作环境无缝整合。
- 机制: 机制的含义是通过对所需解决问题的分析,以一种模式去解决同类问题。机制应体现一定的系统性,而非“头痛治头,脚痛治脚”。
- 质量: 为了让产品的质量做到可靠,单元测试、静态分析、动态分析等确保工程质量的手段应成为工程师的基本工作内容
- 风险: 风险往往出现于资源使用的极端场景,当从外部涌入的过多事务远超软件产品的处理能力时,需要有一定的机制让整个产品能相对平滑地应对,或是扩充资源、或是限制涌入事务的流量
- 成本: 当一个软件需要从公司的内部对外输出时,平时忽视对成本的关注就会暴露出成本问题。比如,为了运行某个软件需要数量庞大的计算资源,所导致的资金开销对于客户来讲很可能是无法接受的
- 延伸: 工程师个体需要在工作中逐步建立起产品、技术和工程三大思维,以便用更为全面的视角去看待日常工作中所面临的困境和困惑。当站在单一的思维去看待所面临的问题时可能觉得不合理,但从三大思维层面去审视时所得到结论可能完全相反。从团队协作的角度,只有团队中有更多的个体从多维度去进行思考,才容易发现岗位间衔接的那些无人问津的灰色地带,进而通过补位、助攻去更大程度地发挥团队的效能
优秀工程师必备的一项技能
思考力
"思考力"是程序员需要具备的一种至关重要的素质。掌握了思考力,你就掌握了在互联网领域,这种高度“智力密集型”行业成长的钥匙。
思考力是一门很深的学问,包括认知科学,心理学、教育学、逻辑学,如果要系统化学习,是需要看很多书的
有哪些对程序员最重要的思考力:
1. 原理性思维:找出只是背后的原理
- 掌握原理带来的好处:
- 可以大幅度降低我们对于知识的记忆量,知识量是爆炸的,但是原理绝对是
可控的! - 原理性的东西比直接的知识有更强的复用度!记住最核心的原理,当你面对
新的场景时,你会惊喜地发现,你的理解速度大大加快! - 另外探求原理的过程,本身很有乐趣!
- 可以大幅度降低我们对于知识的记忆量,知识量是爆炸的,但是原理绝对是
- java程序员需要掌握哪些原理知识:
- java,linux,数据结构和算法,数据库,网络通信与分布式计算的原理,这几类是比较重要的基础知识,我们在做方案设计、编码、问题排查中会运用得很多;
- 设计模式,UML 这个是对系统架构设计必要要掌握的知识,当你经历了很多大规模的软件系统设计,回到根本上,你会发现逃不出这一块的理论和工具;
- 领域性的基本原则,比如“财务平衡公式”,“线下收银让消费者最快速度走人”,这种逻辑需要get到这些领域性的设计原理,甚至自己去总结出这种原理;
- 关于管理学,人际沟通,心理学的一些基本原理,大家可以按照自己的实际需求去看一下。
- 如何在学习和工作中运用这些原理,即最佳实践:
- 首先,对你可能用到的领域知识,建立一个基本的概念。
- 在实践中,有个意识是“多问一下为什么”,并一直“刨根问底”,最终肯定能够追查到背后的最终原理;
- 了解了原理以后,在实践中运用一下
- 如果这是一个非常重要的原理,建议大家如有余力去结合经典的书籍系统化学习
2. 结构化思维:构建自己的知识树
很多时候知识其实都是知道的,但是用的时候却,这个其实跟大脑中的知识结构有关,这是知识学习中“索引”没有建立,也就是说,你的知识只有点,没有线!大家想一想,把东西乱七八糟地丢在房间中,到用的时候没有查找的线索和路径,怎么找得到呢?
比如工作中典型的结构化案例:
-
bug问题定位步骤:
- 确认刚才是否有过代码变更和部署,因为有比较高的概率是刚才变更的代码又搞坏了
- 追踪链路日志看链路是否有异常;
- 通过调用接口输入输出是否符合预期;
- 追踪关键方法的入参和出参,看是否有问题;
- 定位到方法细节后,推理逻辑是否有问题;
- 如果无法通过推理,那就最后一招,一步步debug,这样肯定能够找到原因。
-
链路耗时比较长,需要进行性能优化,优化步骤:
- 通过实际流量制造一个耗时较高的 trace;
- 进行 trace 分析,看清楚耗时最多的原因,然后按优先级进行排序;
- 针对对原因找解决方案,可能的方案有:
- 减少数据访问次数或者计算量,常见手段是增加 cache:线程内的invokeCache;分布式缓存 tair;页面缓存……
- 增强处理速度,比如多线程加速;
- 减少循环调用次数,比如请求合并后再分发;
- 减少数据处理范围,比如减少查询内容,异步加载分页;
- 逻辑简化,比如逻辑进行优化,或者非核心逻辑异步化等;
- 改掉以后,回放同样的 case,看性能消耗是否满足预期,不满足预期继续优化;
-
如何熟悉一个新系统:
- 要一个测试账号,把相关功能走一遍,这样能非常快地了解一个系统的功能;
- 看关键的核心表结构,这样可以快速了解系统的领域模型;
- 根据功能步骤找到系统对外的接口列表,了解系统的 L0 业务流程;
- 下载系统工程,熟悉整个工程结构和模块职责;
- 以一个最重要的流程为入手点,阅读代码,看清楚核心的执行逻辑,可以变看边画时序图;
- 制造一个 debug 场景,以 debug 方式走一遍流程,这样可以实际加深一下对系统的理解;
- 做一个小需求,掌握相关的流程和权限;
-
来了一个新的需求,出一个技术方案的步骤:
- 看清楚之前的需求,把这个需求所在的场景和链路大致阅读一遍,搞懂;
- 找到需求的变化点;
- 分析变更的方案,涉及的内容可能会有:
- 数据结构会不会变,如何变;
- 交互协议会不会变,如何变,交互协议分为:端和组件要不要变;和下游接口要不要变;
- 执行逻辑会不会变,如何变,执行逻辑变更的细化考虑点:是否变更域服务;是否变更流程编排;是否变更主干逻辑;是否变更扩展点是否变更扩展点的内部逻辑,变更内部逻辑的时候,又可以进一步拆解:
- 重构原有的方法,覆盖之前的逻辑,那就需要进行回归;
- 通过逻辑路由到新的方法,这里需要增加路由逻辑;
- 稳定性方案;
- 发布方案;
训练自己知识树的实践方案:
- 一定要总结出自己的知识树,而不要盲从书本上的或者别人的
- 习惯性总结,做完任何一个事情,都习惯性地回顾一下,往自己的树上面挂新东西
- 推荐一个很常见的工具:xmind
- 训练自己的思维习惯和做事方式变得结构化
3. 扩展性思维:举一反三
扩展性思维的核心目标是提升我们思维的广度,也就是让我们的知识树变得更加开阔;
- 举一反三:解决同类型的 N 个问题
举一反三的好处是:“我们能否用同样的知识和手段去解决类似的相关联的几个类似问题”,先举一些案例:- 当发现某个系统的 jvm 参数配置存在一个错误配置,不是仅仅修复这个系统的 jvm 配置,而是把负责的几个系统都检查一下是否需要统一修改;
- 系统中存在某个 bug 导致产生了脏数据,不是直接订正已发现的脏数据,而是根据特征拉取出所有的脏数据,进行一次性处理;这种思维方式的特征是举一反三,触类旁通,相当于产生批处理的效果,可以大大提升解决问题的效率,避免重复处理。
- 寻求更多的可能性:拓展解决问题的不同手段
拓展思维常见的手段是:是否能够换更多的理解方式,或者更多的解法,举一些案例:- 产生故障的时候,快速止血除了回滚以外,还有哪些方案?如果故障处理经验丰富的人一定知道,除了回滚,其实还有系统降级,运营活动降级等多种方案;
- 除了写更加健壮的代码,还有哪些手段都可以提升系统的容错性?当解决问题的手段更多了,思维就开阔了。
4. 抓重点思维:提升记忆,方便效率和传递
一定要先建立知识结构化,然后才能从里面筛选出重点,否则知识的体系是不完整的
- 归纳法
采用归纳法,把细节隐藏掉,呈现知识的脉络,这是一种非常好的思路;尤其是大家在准备晋升 ppt时,ppt的每一页都需要归纳一个核心观点,不是全是细节,这个非常重要! - 优先级法
优先级策略往往应用于在多项任务之间找到最最关键或者收益最大的那个任务项,比如完成一个事情可能有若干个步骤,其中哪个步骤是最有效的,大致可以做一个排序
5. 反思性思维:思考哪里可以做的更好
反思性思维是提升知识质量和深度的一个关键能力。因为只有不断反思才能让下一次在上一次基础上升级,而不是重复循环
- 对于技术团队,需要反思的方面:
- 这个项目商业价值 OK 吗?是否取得了预期的效果?
- 项目中我的能力有哪些问题,有哪些做得好的和不好的?
- 系统设计的优势和不足?
- 项目质量保障是否可以做得更好一些?
- 研发过程和项目管理是否有不足?
- 两个比较关键的点:
- 做事情的过程总有优化的空间,每次都要有进步
- 反思是一种习惯和潜意识,可以在不经意之间经常进行,其实不需要很形式化地花很多时间,有时候做完一个事情,习惯性思考一下就可以
6. 总结:
锻炼思考力的有效实践
- 意识觉醒,要意识到思考力这一概念,并不断提升思考力.
- 掌握正确的方法
- 空杯心态,对新的环境,新的理念,新的技术持开放态度
- 利用碎片时间,抓住做事的过程中,抽时间思考总结
- 思考力提升的判断标准:
- 广度,就是你自己的知识树能够长多大的范围,越广知识越渊博
- 深度,就是你自己的知识树的叶子节点有多深,越深对知识了解越透彻
- 速度,就是建立和刷新知识树的速度了。比如原来你想清楚一个建模方案要一天,现在只需要半小时可以想清楚,那就是速度的提升了
- 一定要相互分享,因为思考是智力活动,相互分享完全能够取得 1+1>2 的效果;
如何在工作中快速成长?
时间管理:三八论
- 下班空闲时间,用于消费,比如刷新闻,刷抖音,刷朋友圈,产生及时享受,没产生成长,钱还是那些钱,职位还是原来职位;
- 下班空闲时间,用于交易,接个外快,赚点辛苦钱,产生金钱,没产生成长,钱没多多少,职位却还是原来职位;
- 下班空闲时间,用于投资,以终为始,相信“慢慢来,成长最快”的认知,持续不断投入多维领域的学习,沉淀能力,获得成长,从成长中获得金钱,名誉的升级;
所谓时间管理,就是“找到不被打扰的时间”(即能够一直持续利用的时间)。只有找到了不被打扰的时间用于投资自己的成长才能发生复利效应。如果想从工作中省点时间,想从周末挤点时间用于学习,这叫成长的断崖,我相信不能持续,学习必须是每日的必修课,必须是日拱一卒,持之以恒。
比如睡觉前半个小时,每天早起半个小时,周末上午等
最重要的财富:注意力
“为什么看电影注意力特别好,做正事注意力集中不了”。
首先接受这个现实,医学上把这叫作注意力缺失症,基本所有人都有这种毛病,因为做正事比较枯燥、困难,让人不舒服,集中不了注意力,逃避很正常!
改善方法:
- 边读边记笔记边思考
- 写博客或者PPT分享自己的成果
注意力 + 不被打扰的时间 = 更好的自己
跳出舒适区
心理学家把我们可能面对的学习内容分成了三个区,分别是舒适区、学习区和恐慌区。
- 舒适区太容易,待太久了,总想跳出去看看。
- 恐慌区太难,太难带来恐惧,就像梁宁在产品思维中讲同理心时,恐惧会产生束缚也会产生动力,就看安全边界有没有被侵犯,如果无法战胜挑战,恐惧就产生了束缚,退回到舒适区
跳出舒适区就是进入学习区,平衡挑战和技能从而达到心流体验
职业规划
职业规划不是某个岗位,某个角色,而是工作能力的提升。
针对自己岗位需要的能力,职场需要的能力,然后用专家思维,多维视角重点突破 3-4 项能力,抱着 120% 的努力拿到结果,甚至是超出期望的结果,事情成了,能力也就被认可了,所谓的角色,岗位只是顺其自然的结果
程序员如何自我学习
- 必须持续学习,行业发展得太快,你必须学习,纯靠经验积累行不通,技术淘汰的速度远大于你经验积累的速度
- 工具必须非常熟练,天下武功唯快不破,你后续写 demo、查问题、工具的熟练程度都会决定你学习和尝试新事物的速度
- 读书 & 看文档,学习还需要系统化。并非单靠看一篇文章就能明白原理。
- 视频学习,视频有一些文字表达不了的功能:图书中只会贴一段代码,而视频中这些代码是需要输入的,这时你会发现作者很多的黑科技或者黑技巧,你也能学习到
- 做项目,写 Demo,看源码,多写一些 demo,多磨磨刀。对你本行业的技术,一些源码还是要能看懂的
- 适当的硬件支持,高性能个人电脑,舒适的学习环境
为什么需要技术KPI
在业务技术团队,有一个不好的趋势就是团队越来越业务,越来越没有技术味道。每个人都在谈业务,技术大会上在谈业务,周会上在聊业务,周报里写的是业务项目……唯独少被谈及的是技术本身
这种技术味道的缺失对技术团队来说是非常可惜的,也不利于技术人员的成长和发展。因为很难想象一个没有技术追求的团队能开发出一个健壮的、可维护性好、可扩展性好的系统。