写点什么

成长篇 - 程序员修炼之道笔记(完整版)

发布于: 2021 年 01 月 19 日
成长篇-程序员修炼之道笔记(完整版)

一、注重实效的程序员


  • kaizen,日语。持续进步。

  • 跳出自己的所负责圈子,从全局看待问题

  • 对于自己做的事情,要有责任感。

  • 交流与人沟通,深度思考

  • 拥抱变化

  • 学习


1.1、所有的弱点中,最大的弱点就是暴露弱点


对于无知和错误要坦诚接受,对于未期的问题要勇于面对。


1.2、软件的熵


  • 无穷变大(软件腐烂),

  • 破窗户效应(低劣的设计,错误的决策或者糟糕的代码)不要容忍破窗户,如果没有足够的时间,可以利用注释或者虚设的数据代替。


Q:如果你的团队出现破窗户效应,你应该如何应对?你的项目破窗户是什么时候破的?你的反应是什么?如果是决策者或者其他人做的,你应该如何做?


A:如果发生在我这里,需要及时定位到根本原因是什么?会引发的后果是什么?如果弥补我们应该如何处理,涉及的范围是什么?如果是说决策者或者其他人做的,需要考察下当时为啥这么做,如果没有记录了,则需要做个兜底监控,来判断自己是否需要处理这个问题。或者灰度放量观察该问题。接受不完美,但是不能接受一直不处理隐藏的地雷。


  • 石头汤与煮青蛙:利用自己的优势团结起来其他人,启动杂役士兵农名,一起完成一个大的项目联动。做变化的催生剂,让其他人预见未来,看到收益。但是如果你是一个煮青蛙的趋势,是由你这个催生剂来决定的,所以如何决策是好的还是坏的是比较难的一个问题。

  • 止步与系统边界:如何确定自己克制和自己系统边界不断扩张的问题。克制比蔓延难管理。

  • 知识资产的管理:有时效的知识资产(随着时间知识会无用)

  • 批判的思考和认知,看到的听到的不一定是对的


Q:如何应对知识资产的管理?


A:经营你的资产


1.2.1、经验你的资产


  • 定期投资,可大可小,养成习惯,技术或者金融

  • 多元化,万物皆可通,多样的技术和多样的投资方式可以让你有更好的选择权

  • 管理风险,不要将所有鸡蛋放到一个篮子里。

  • 低买高卖,一门新技术出现的时候顺势捕捉。与股票一样。

  • 重新评估和平衡,不断对于自己进行评估缺陷进行补充。


1.3、交流


简略梳理自己的想法,并准备几种讲好讲清楚的策略。


1.3.1、了解你的听众


  • 了解听众需求,兴趣和能力

  • 选择时机



  • 针对不同人选择不同的风格

  • 传递的文档或者书面美观简洁

  • 让听众参与

  • 做倾听者

  • 回复他人(你说什么和你怎么说同样重要)

  • 邮件的提醒

二、注重实效的途径



2.1、估算与规划



不断的估算,如果偏离 50%,说明根本原因是什么?



2.2、DRY,don't repeat yourself



不要重复自己,干着每天重复的东西



  • 强加的重复:信息的多种表示,代码中的文档(糟糕的代码才需要注释,注释留给高级代码),文档与代码的生产(代码变动,文档随之更新),语言自身问题

  • 无意的重复:因为性能原因等违反 DRY,诀窍是影响局部化

  • 无耐性的重复:容易检测和处理的重复形式,

  • 开发者之间的重复(透明的环境,使用简单)



2.3、正交性



设计好的系统是正交的,也就是高内聚,低耦合



  • 提高生产率:消除无关事物之间的影响,改动局部化,提高复用率

  • 降低风险:代码隔离,系统更健壮



设计:



模块化,组件化,分层,如何判断自己的设计是否正交,则提出一个需求,我们要改动的内容有多大。不要依赖无法控制的属性。



编码:



让代码保持解耦,避免使用全局数据,避免编写相似的函数,



测试:



单元测试的必要性



文档:



内容和表现形式的重要性



2.4、可撤销性



如果某个想法是你唯一的想法,再也没有比这个更危险的事情了。



不存在最终决策,决策随时会变化,灵活的架构--架构师



2.5、原型制作



用户能够及早看到能工作的东西



开发者构建一个能工作的结构



集成平台



用于演示的东西



感受到的工作进展



应制作原型的事物:



  • 架构

  • 已有系统的新功能

  • 外部数据的结构或者功能

  • 第三方工具或者组件

  • 性能问题

  • 用户界面设计



如何制作原型(忽略的细节):



  • 数据正确性

  • 完整性

  • 健壮性

  • 风格



举例架构原型(评价和设计的方面):



  • 主要组件的责任和边界的划分

  • 低耦合高内聚

  • 是否会有重复的来源

  • 接口定义和各项约束是否可以接受

  • 每个模块的完整性,准确性



2.7、领域语言



不设限,每种语言都有自己的独特地方。

三、利用好工具,但不丢失基本技能

兵器是一个战将的最得力的武器和助手,但是没有了武器是否基本功需要过关则考察的是每个人的素质能力。

3.1、纯文本工具

很少有人在用了,但是也需要会基本的使用。

优点



  • 不过时

  • 杠杆作用

  • 易于测试



缺点:



  • 复杂逻辑,代价昂贵

3.2、shell 提高自动化内容

脚本的内容还是比较偏好 shell、Python 语言来实现。

3.3、用好你的 IDE



非常熟练知道 ide 的能力,而不是只是会用一部分。


3.4、人生没有撤销回退键



总是需要为自己的所做而负责。

这里的感触很深,就是你对于研发的代码质量和你上线的风险可控以及影响面的把控。一旦写的代码质量出了问题可能真正在线上环境跑起来,则是无疑非常大的损害。另外就是说对于自己的成长,无非很多人寄希望于团队,公司,项目,实际上哪些都是辅助,如果你的人生需要负责任那么我想说只有你自己,你需要有着自己的思考和提升的想法并不断去提高和改进。

3.5、正确面对 bug



bug 是谁的不重要,重要的是你要如何修正它。

不要追究过往,否则只能是陷入死循环。



不要恐慌,定位范围,数据可视化,跟踪 debug

不慌不忙,问题总是能解决的。



不要假设,要证明 bug 问题,调试检查列表

更多时候我们的假设比较苍白,适合用证明来说明问题。

3.6、重复的劳动和代码交给机器来做

很多时候同事们经常说的我们整天在处理业务代码 CRUDboy,或者 SQL Boy 感受不到成长。实际上工作久了以后会发现,每个公司都希望让你天天处理无效的东西,直到有天你被淘汰。如何避免这些事情呢?个人觉得你需要提炼出那些是重复的东西,把重复的东西交给别人或者交给机器。提高实际的时间效率,并保证自己的思考反思能力不断提升。

四、注重实效的偏执



每个人第一次都编写不出完美的代码,针对每个系统每个人也不可能一开始就达到非常完美。但是对于我们系统研发来说,是否能接受不完美呢?

有很多同学或者工作几年的研发人员依然痴迷于完美的架构,开源成熟的框架。热衷于完美的产品,一流的用户体验。实际上工作多了以后会发现 ,符合你当下的业务场景需求,并且有着未来容量的良好预估,以及对于现在资源不浪费,那么这才是真正的达到了实效主义。



4.1、按合约设计

合约其实我们可以理解为你经常用的 API 文档,双方保证接口开发的一个规范。或者你也可以理解为双方签署的 SLA 保证书,对于上游系统或者下游系统保证多长的不可用时长。

4.2、尽早检测问题

对于问题的梳理,以及已知问题和未知问题都要尽早检测,比如看到异常流量 要去主动评估是否是业务上涨带来的还是异常带来的,是否需要扩容还是需要修复。如果是系统接口错误告警,那么需要尽快查看是否是属于正常的业务异常还是系统级别的异常。

4.3、断言式编程



如果它不可能发生,用断言确保他不会发生。用程序来确保一些事情,总比注释和口头约定更好。

4.4、合理的异常输出

异常输出,主要也是日志控制,对于日志的不合理使用则会排查问题增大,第二个是造成磁盘空间不足。

4.5、配平资源,有始有终



文件的打开和关闭,内存的使用和回收。资源的使用一定要确保使用后的关闭,防止内存泄露,文件丢失等问题。



五、弯曲或者折断



5.1、解耦与得墨忒耳法则



好篱笆促成好邻居

低耦合,高内聚(封装)



得墨忒耳定律(Law of Demeter,缩写 LoD)也叫做“最少知识原则”,是一种开发软件的设计原理,特别是面向对象的程序设计,得墨忒耳定律是松耦合的一种特殊情况。该指导原则是 1987 年末在美国东北大学发明的,该原则可以简单地概括为以下方式之一:

  • 1 每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元;

  • 2 每个单元只能和它的朋友交谈:不能和陌生单元交谈;

  • 3 只和自己直接的朋友交谈。 这个原理的名称来源于希腊神话中的农业女神,孤独的得墨忒耳。

5.2、元程序设计



再多的天才也无法胜过对细节的关注,关注细节不会错。多关注细节不会有任何坏处。

5.2.1、动态配置变动细节数据



元数据来配置参数,这样可以让易变的配置不会耦合太严重,比如可以根据用户喜好,安装目录等变更的内容。

5.2.2、元数据驱动应用



将抽象放进代码,细节放进元数据



可以参考 EJB,SpringBoot 框架的设计和思想

5.2.3、不要编写渡渡鸟的代码(定制化代码)



不适应环境的毛里求斯岛的渡渡鸟就会被灭绝。



人也是,不适应环境就得淘汰。所以我们虽然一开始不会追求过于完美的设计,但是我们的编写代码实现需求的时候 也需要注意防止过度定制化开发。



5.3、时间耦合



工作流分析,架构,设计,部署

比如 UML 的活动图




5.4、工作流和规则引擎的搭配



如果对于一个需求杂乱无章,就像侦探去查询案件一样,则工作流的方式如同黑板来梳理出整个脉络,而工作流的流向则由规则引擎来触发。


六、编程

编程的前提是你对于现有的业务和技术的掌握程度。

6.1、巧合编程

成功编程,或者你的实现是成功的偶然性,你不知道为啥会成功,则依然会迟早进入雷区,知其然,所以然。

6.2、深思熟虑编程



  • 明确知道你在做什么

  • 杜绝盲目编程

  • 按照计划行事

  • 依靠可靠事务

  • 断言式编程,不要假设

  • 工作的优先级

6.3、算法速率



估算:时间,处理器,内存等大数定律,近似计算表示法来估算。


最好的不一定是最好的,适合自己的才是最好的。

6.4、重构



定义:重新,重做和重新架构代码合起来-----称为重构(refatoring)。

6.4.1、应该何时重构?



重构的原因:

  • 重复的代码

  • 非正交的设计

  • 过时的知识和技术

  • 性能

早重构,随时重构,为的就是不给项目留历史债务。



6.4.2、重构的关注点

重构,不是那么简单的!

  • 不要试图在重构

  • 重构前,尽可能详尽的测试用例

  • 短小的更改,步步为营



6.4.3、易于测试的代码

TDD,测试驱动开发,我们在写代码之前那么代码一定的基本要求是需要可测试,为了确保自己在开发之前有着最基本的业务把控。

  • 可复用性和基于组件开发

  • 单元测试

  • 为了测试而设计

  • 测试文化---所有模块必须测试



6.4.4、不要使用你不理解的代码

如何理解呢?不理解这里其实是指的是你对于不管是接手的老项目代码还是新技术引用的组件,因为不理解,这样的风险便是无人可掌控的,一旦在生产环境下出了问题,那么作为第一责任人的你如果不能迅速定位和解决,那么是需要承担很大的责任。所以你在你的代码中,如果设计了,那么就需要自己保证对这个业务的技术设计能够掌控。

七、项目开始前

7.1、建立需求文档

没有调研清楚或者思考清楚便开始一路 coding 的方式,往往是意味着返工操作。需求是变化的,所以第一个我们需要明确需求文档,如果有原型图是最好的。

随着需求的实现,如何控制需求蔓延是需要每个 Owner 的掌控之中的。

在我们提出需求和方案的时候,最好是拉齐认知和同步信息。避免之后说不清楚。



  • 捕捉需求用例 use case

  • 用例图--UML 活动图

  • 切勿规定过度

  • 将需求往远看,抽象比细节活的更长久

  • 避免需求蔓延,用户需求严格控制,避免发散。

  • 要表达出来你的需求,落实文件上,口头无效



7.2、问题

问题往往在实施过程中会出现不可预知的情况,那么问题的根本原因如果没有找到,很容易解决了一个问题,引入了新的问题。那么问题非常多时间紧是否又是所有问题都要解决,追求完美呢?答案是否定的。



  • 是否有更容易的方法?

  • 是在设法解决问题还是被外围的技术问题转移了注意力

  • 这件事情为啥是一个问题

  • 是什么导致它如此难以解决

  • 是否必须解决?

  • 是否是拖延解决问题还是良好的判断?



7.3、规范的陷阱

不要去非常死板的做一个事情,无论是完成需求还是实现功能。我们的思维要发散,能够在现有的模式下进行良好的可扩展能力提炼。也就是扩展性,伸缩性。



  • 做胜过描述,不要断绝自己的想象力和思考力

  • 类图就是应用,其余的只是机械的编码,这不一定是好事情

八、注重实效的项目



8.1、注重实效的团队

一个好的团队,应该会从如下几个方面来考察:

  • 不留破窗户

  • 煮青蛙

  • 无交流的团队

  • 不要重复你自己

  • 正交性(围绕功能而不是工作职务进行组织)

  • 自动化测试

  • 边界,做与不做



8.2、协作测试

测试是一个繁杂的工作,但是测试是否应该一直由我们来做呢?付出很多的时间,我们可以将其更多的繁琐的工作交给机器。



  • 把不重要的重复的交给机器来做,我们应该做更深度的思考或者更困难的工作。

  • 早测试,常测试,自动化测试

  • 测试的种类:单元测试,集成测试,验证和检验,资源耗尽和错误恢复

  • 测试的方法:回归测试,测试数据,演练 GUI 系统,对测试进行测试(蓄意破坏),彻底测试



8.3、文档

程序员不喜欢写文档,不喜欢写注释,但是往往又会因为这些原因而抱怨前人没有给自己留下很好的资料文档参考,以及注释说明。既然从一开始自己也讨厌,为何不自己去将所有的文档和注释、代码一起交出一份满意的答卷。



  • 文档和代码贴近,实时同步

  • 代码中的注释

  • 不应该出现在源码中的列表:

  • 打印和编排(发布快照记录 snapshot)

  • 标记语言(一些标记方案比如在线帮助手册等)



8.4、期望

针对我们做的项目,可能用户对于一些标准要求比如页面响应 1s,而我们如果能做到响应 500ms 则不仅仅是对我们技术的提升,另外一方面也是对于我们的工作的一种负责,这样用户或者产品在验收项目的时候总会超出期望,从而对你的好感会增强。



  • 超出用户的期望交流用户的期望


发布于: 2021 年 01 月 19 日阅读数: 31
用户头像

小胜靠智,大胜靠德 2019.06.27 加入

历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666

评论

发布
暂无评论
成长篇-程序员修炼之道笔记(完整版)