程序员进阶攻略
胡峰
京东成都研究院技术专家
立即订阅
7526 人已学习
课程目录
已完结 65 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 程序行知:走在同样的路上,遇见自己的风景
免费
征途:启程之初 (4讲)
01 | 初心:为什么成为一名程序员?
02 | 初惑:技术方向的选择
03 | 初程:带上一份技能地图
04 | 初感:别了校园,入了江湖
修炼:程序之术 (10讲)
05 | 架构与实现:它们的连接与分界?
06 | 模式与框架:它们的关系与误区?
07 | 多维与视图:系统设计的思考维度与展现视图
08 | 代码与分类:工业级编程的代码分类与特征
09 | 粗放与精益:编程的两种思路与方式
10 | 炫技与克制:代码的两种味道与态度
11 | 三阶段进化:调试,编写与运行代码
12 | Bug的空间属性:环境依赖与过敏反应
13 | Bug的时间属性:周期特点与非规律性
14 | Bug的反复出现:重蹈覆辙与吸取教训
修行:由术入道 (24讲)
15 | 根源:计划的愿景——仰望星空
16 | 方式:计划的方法——脚踏实地
17 | 检视:计划的可行——时间与承诺
18 | 评估:计划的收获——成本与收益
19 | 障碍:从计划到坚持,再到坚持不下去的时候
20 | 执行:从坚持到持续,再到形成自己的节奏
21 | 信息:过载与有效
22 | 领域:知识与体系
23 | 转化:能力与输出
24 | 并行:工作与学习
25 | 时间:塑造基石习惯(上)——感知与测量
26 | 时间:塑造基石习惯(下)——切割与构建
27 | 试试:一种“坏”习惯
28 | 提问:从技术到人生的习惯
29 | 偏好:个人习惯的局限与反思
30 | 写作:写字如编码
31 | 画图:一图胜千言
32 | 演讲:表达的技术
33 | 定义:阶梯与级别
34 | 晋升:评定与博弈
35 | 关系:学徒与导师
36 | 核心:安全与效率——工程技术的两个核心维度
37 | 过程:规模与协作——规模化的过程方法
38 | 思维:科学与系统——两类问题的两种思维解法
徘徊:道中彷徨 (15讲)
39 | 职业倦怠:如何面对?
40 | 局部最优:如何逃离?
41 | 沟通之痛:如何改变?
42 | 技术停滞:如何更新?
43 | 无法实现:困扰与反思
44 | 完成作品:理想与现实
45 | 代码评审:寄望与哀伤
46 | 人到中年:失业与恐惧
47 | 该不该去创业公司?
48 | 该不该接外包?
49 | 技术干货那么多,如何选?
50 | 技术分歧,如何决策?
51 | 技术债务,有意或无意的选择?
52 | 选择从众,还是唯一?
53 | 选择工作,还是生活?
寻路:路在何方 (7讲)
54 | 侠客行:一技压身,天下行走
55 | 江湖路:刀剑相接,战场升级
56 | 御剑流:一击必杀,万剑归心
57 | 三维度:专业、展现与连接
58 | 三人行:前辈、平辈与后辈
59 | 三角色:程序员、技术主管与架构师
60 | 三视角:定位、自省与多维
蜕变:破茧成蝶 (3讲)
61 | 工作之余,专业之外
62 | 跨越断层,突破边界
63 | 成长蓝图,进化跃迁
结束语 (1讲)
尾声 | 始于知,终于行
程序员进阶攻略
登录|注册

14 | Bug的反复出现:重蹈覆辙与吸取教训

胡峰 2018-09-03
Bug 除了时间和空间两种属性,还有一个特点是和程序员直接相关的。在编程的路上,想必你也曾犯过一些形态各异、但本质重复的错误,导致一些 Bug 总是以不同的形态反复出现。在你捶胸顿足懊恼之时,不妨试着反思一下:为什么你总会写出有 Bug 的程序,而且有些同类型的 Bug 还会反复出现?

1. 重蹈覆辙

重蹈覆辙的错误,老实说曾经我经历过不止一次。
也许每次具体的形态可能有些差异,但仔细究其本质却是类似的。想要写出没有 Bug 的程序是不可能的,因为所有的程序员都受到自身能力水平的局限。而我所经历的重蹈覆辙型错误,总结下来大概都可以归为以下三类原因。

1.1 粗心大意

人人都会犯粗心大意的错误,因为这就是 “人” 这个系统的普遍固有缺陷(Bug)之一。所以,作为人的程序员一定会犯一些非常低级的、因为粗心大意而导致的 Bug。
这就好比写文章、写书都会有错别字,即使经历过三审三校后正式出版的书籍,都无法完全避免错别字的存在。
而程序中也有这类 “错别字” 类型的低级错误,比如:条件if 后面没有大括号导致的语义变化,====== 的数量差别,++-- 的位置,甚至 ;的有无在某些编程语言中带来的语义差别。即使通过反复检查也可能有遗漏,而自己检查自己的代码会更难发现这些缺陷,这和自己不容易发现自己的错别字是一个道理。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《程序员进阶攻略》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(17)

  • third
    心得如下:

    1.bug本质上是无法避免的,最好的办法不是不犯错,而是少犯错误,犯错之后尽快改正。最快的成长方法是不退步

    2.bug的反复出现,有三个重要原因,粗心大意,认知偏差,熵增问题

    3.认知偏差是错误的最大来源,思想错误,行动又怎么会正确呢?

    4.熵增问题,是随着复杂增高,而必然有更高概率发生bug

    5.应对这些问题,我们要从各方面吸取教训,其中最重要的是优化方法和塑造环境。

    6.粗心大意,可以通过流程和工具来减少,建议补充代码单元测试

    7.认知偏差,可以通过团队和技术手段来纠偏

    8.熵增问题,通过业界不断迭代更新流行的框架模式来解决。

    9.塑造环境,塑造一个正视错误,改正错误的环境

    作者回复: 👍,总结的比我详细😊

    2018-09-03
    17
  • godtrue
    世界是不完美的,人是这个世界的极小部分,人也是不完美的,如果想使人做的事情趋近于完美,那就需要集体的智慧了。之于编程一套好的流程能扼杀许多的Bug,自测、测试(包括:测试环境联调、预发布环境联通等)、代码review,上线前准备、上线中自验、上线后产品及业务验证等如果都做到位了,至少能保证主流程没问题,对于性能有要求的可以加上性能测试。现在我们基本是这么玩的,另外,就是各种监控和日志的加持啦!

    作者回复: 流程本身就是环境的产物,对于软件开发而言,每个公司估计流程都不会完全一样

    2018-09-03
    8
  • softtwilight
    胡大看问题的角度真是独特,而且深刻

    作者回复: ^_^,这也是可以培养和训练的

    2018-09-03
    4
  • 李正阳Lee
    看到塑造犯错环境这节,想起了桥水基金创始人达利欧对待犯错的态度。

    他允许员工犯错,强调每个人应反思错误,不容许一错再错。并在公司内部建立了一个“错误日志”,用来记录每人犯过的错误和造成的不良后果,这样可以追根溯源,系统化的解决问题。

    我们技术人也可以建立自己或团队的“错误日志”,在错误中成长。

    作者回复: 恩,不错的主意

    2018-09-04
    3
  • Frank.w
    总是粗心大意导致出现bug,甚至一些低级的条件语句发生错误。
    自我总结:
    1. 做好单元测试。
    2.做好代码走查,在写完代码后,在今进行从新构思审查。
    3.对于代码改动影响的所有代码进行测试。
    4.提交测试,同时提交改动范围,改动代码所影响的所有功能。

    作者回复: 可复用的单元测试会拯救未来的你^_^

    2019-07-28
    2
  • 湮汐
    我和胡老师一样,也被线程池池误导过。我也以为先创建线程到max,然后再进入队列,事实上和我们想的正好相反。而我总结了一下,我们之所以被误导,也是有原因的:数据库连接池就是先创建连接到max,如果没有可用连接时,就等待maxWait时间直到有空闲连接或抛出异常。
    在学习的时候虽然有“触类旁通”,但是有时候确实会有一些细节不一样,没有去踩过这个坑,自然就会想当然了。
    出错一直都是正常的,一定要敢于面对自己的错误,并且纠正自己的错误。

    作者回复: 嗯,惯性思维也容易导致犯错

    2018-09-27
    2
  • 艾尔欧唯伊
    我最近面试遇到这个问题,我就说错了。后来继续解释的时候发现说不通了,回来一看,发现之前理解的都是错的

    作者回复: 所以要多交流才能发现自己的认知偏差,面试也算一种特殊的交流

    2018-09-03
    2
  • 艾尔欧唯伊
    线程池那个认知偏差真是一样一样的啊。。。

    作者回复: 听说不少人都掉过这个坑……

    2018-09-03
    2
  • 阿信
    程序之术这部分 笔记 (期待支持markdown)

    # 总览
    主要是讲解程序员技能的锤炼。
    主线:设计、开发、bug处理 (按正常的功能开发流程介绍的)
    * 设计
        * 认知设计。架构与实现,他们的连接与分界;框架和模式的区别
        * 如何来设计。从哪些维度来思考(多维度视图)
    * 编码
        * 工业级编码包含哪些内容 (功能、控制、运维)
        * 编码的两种方式:粗放和精益
        * 编码的态度:炫技和克制
        * 编码的三阶段:调试、编码、运行
    * bug处理
        * bug按特性进行的分类以及各分类介绍。空间特性和时间特性
        * bug出现的原因分析,以及降低bug的方法



    # 05 架构与实现:它们的连接与分界
    架构:做的是顶层设计,技术、框架选型,边界划分。熵尽量小。设计和实现做取舍
    实现:交付代码,尽量简。围绕架构做的程序时间。
    连接:
    架构师:关注系统边界、关键点、战略性细节点

    # 07 多维与视图:系统设计的思考维度与展现视图
    理解或表现系统的视角。
    组成视图:描述组成系统的子系统、服务、组件。便于总体了解系统服务组成,以及其职能。服务切分原则:高内聚,职能单一;正交化,同一个功能只有一个服 务提供
    交互视图:系统组成部分中各部分的依赖、被依赖关系。整体的流转。
    部署视图:系统如何来部署的。关于服务、中间件、使用者之间的网络传输,确认IO瓶颈,从高维度看系统设计的合理性
    流程视图:功能逻辑流
    状态视图:状态的变化流
    我的理解:组成、交互、部署视图,适合描述顶层设计。流程、状态视图,适合描述具体的功能

    # 08 代码与分类:工业级编程代码的分类与特征
    总结:
    对于最终需要交付运行的程序代码,
    从代码的用途(or使用场景)上将作者代码分为三种:功能代码、控制代码、运维代码。
    功能代码,满足于用户需求,为实现特定的业务功能而开发。
    控制代码,对代码执行流的控制,如并行、异步、限流、熔断、超时控制等。RPC、中间件、代理服务器等,应该是对代码执行流的控制。控制代码的需求,是从众多(已有的或预见的)功能开发中提炼而来,基于一些共性的特征抽取。源于功能而高于功能。
    运维代码,用于解决运行过程中出现的问题,或者为解决问题提供必要的信息。

    结合工作,我们做的防重组件,是控制代码。基于pinpoint实现链路跟踪,是对业界已有的运维代码成果的使用

    # 09 精益与粗放,编程的两种思路与方式
    介绍编程的两种思路,完美型和现实型。
    看这篇文章,脑海中想到了两件事情,一是卖油翁的故事;二是态度(吴军老师写的)一书中提到的一些观点:最好是更好的敌人(或者说进步一点比什么都不做好)、做事情时境界要高。
    陶器制作第一组的同学,可以说是熟能生巧;陶器制作第二组的同学以及课程设计的同学,境界是比较高的,但在其事情落地上执行方式有点问题,因为没有找到完美的方案而踌躇不前,最终没有输出满意的成果。
    套用到我们自身的工作,以及绝大多数程序员身上,大量的开发(+用心理解)可以提升我们的水平,我们要求输出的成果有deadline,设计时我们格局可以大一些,考虑后来的扩展,实现时可以分步来执行,多次的改进让我们朝着目标前进,甚至超过原有心中的完美方案。

    # 10 炫技与克制:代码的两种味道与态度
    炫技:能简单处理的采用了复杂的方式
    克制:不随性。第一层意思是采用了简单的方案处理合适的问题;第二层意思是看到不好的代码、设计,克制立刻修改的冲动,了解整个逻辑后,在合适的时机进行重构。

    # 11 三阶段进化:调试,编写与运行代码
    介绍的是两种写代码的方式:一是走一步算一步,边写边调;二是先整理清楚整个思路,然后再动手。


    # 12、13、14 bug分析
    技术性bug,根据特征分为两类:
    空间:环境过敏
    时间:周期规律
    环境过敏,像人到一个新环境过敏一样,程序运行在不同的环境,因为环境的差异而导致程序运行遇到问题。如磁盘故障,网络带宽低等,原本(在次品正常、网络带宽高机器上)运行正常的程序,运行出现了问题。

    bug出现的原因分类:
    粗心大意
    认知偏差,和理解需求出现了偏差
    熵增问题 (系统复杂度变高)

    降低bug出现次数的方法:
    粗心大意,可以通过流程和工具减少;
    认知偏差,可以通过团队和技术手段来纠偏
    熵增问题,重构,如使用业界更好的模式、框架等来降低复杂度
    塑造环境。塑造一个正视错误、改正错误的环境。

    作者回复: 👍,学习心得感悟可以快速记录在这里,总结整理还是汇总到一个自己专用的笔记软件方便些

    2019-03-13
    1
  • 二木🐶
    这篇文章写的真好

    作者回复: ^_^

    2018-10-27
    1
  • 热勇
    非常值得反思的文章!!!为自己加油!谢谢老师

    作者回复: 今天刚碰到一个线上事故,反思中……😢

    2018-09-20
    1
  • 亚林
    嗯 站在更高的角度解决问题
    2018-09-11
    1
  • 石头
    首先要有一套流程避免大问题,然后对于个人来说有一个收获就是建立COF,不断总结优化提高。
    2018-09-05
    1
  • 莫小鹏
    今天的文章不错

    作者回复: ^_^

    2018-09-04
    1
  • 吴秀華
    我承认我是个经常出BUG的人。每次都是粗心大意或未完全了解需求造成的。我正在努力的完善自己的思维和工作态度。在工作中得不到认可和改进意见。在这里,非常感谢峰哥的分享,让我在迷茫中,看到曙光。

    作者回复: ^_^,加油💪

    2018-09-03
    1
  • 香槟
    环境受制于公司和管理者本身的管理方式,目前看扁平化管理应该是做到了。通过采集系统请求错误,及时发现问题,这应该算工程师文化的一些吧,可是主动改善权力距离指数,这有细化的方式列举一二点吗
    2019-02-23
  • 北风一叶
    终于知道为什么我写的程序总是返工了,就是因为bug没有管理好,也没有吸取经验教训
    2018-11-14
收起评论
17
返回
顶部