百度高效研发实战训练营-Step2


2.1 代码的艺术

2.1.1《代码的艺术》目的解读

这门课程的目的主要有以下四点:
(1) 了解公司与学校写代码的不同
(2) 消除对于程序员这个职业的误解
(3) 建立对软件编程的正确认识
(4) 明确作为软件工程师的修炼方向

1、了解公司与学校写代码的不同

在公司写程序和在学校写程序有很大的不同,在学校写程序时,对代码的质量要求比较低,当进入公司之后,做的是工业级的产品,服务用户量可能会达到亿万级,所以与代码的质量要求比较高,一些伟大产品中的代码,甚至可能被称为是艺术品。

2、消除对于程序员这个职业的误解

很多人都对程序员这个职业有误解,认为程序员就是码农,认为程序员35岁之后会面临失业问题,还有人认为程序员未来的唯一出路是做管理,希望通过接下来的学习,可以对于程序员有一个新的认识,从而消除误解。

3、建立对软件编程的正确认识

在做一件事物时,我们常说要“知”“行”合一,即我们需要对这件事物有一个正确的认识,才会有正确的行动。同理,写出好代码的前提,是对软件编程有正确的认识。

4、明确作为软件工程师的修炼方向

明确作为软件工程师的修炼方向,艺术品是由艺术家创造的,艺术家的修炼是有方式方法的,同样软件工程师的修炼也是有方法的,希望通过接下里的内容,能够对软件工程师这个职业有一个全新的认识。

2.1.2 代码与艺术之间的关系

1、代码是可以被称为艺术的

我们知道,艺术是多种多样的、丰富多彩的。同时,艺术也是有多个层次的。
想象一下我们编写的代码,我们的脑海中也会有类似的感觉,艺术就是人类通过借助特殊的物质材料与工具,运用一定的审美能力和技巧,在精神与物质材料,心灵与审美对象的相互作用下进行的,充满激情与活力的创造性劳动,可以说它是一种精神文化的创造行为,是人的意识形态和生产形态的有机结合体。

百度高效研发实战训练营-Step2_系统设计

同样,写代码也要经历这样的一个过程,在编写代码的过程中,我们借助的物质是计算机系统,借助的工具是设计、编写、编译、调试、测试等,同样编写代码需要激情,而且编写代码是一件非常具有创造性的工作,总之,代码是人类智慧的结晶,代码反映了一个团队或一个人的精神。

百度高效研发实战训练营-Step2_软件工程师_02

代码是可以被称为艺术的!

2、艺术可以从不同的角度进行解读、研究与创造

百度高效研发实战训练营-Step2_软件工程师_03

达芬奇有多幅著名的画作,那著名的《蒙娜丽莎》这幅画来举例,站在观众的角度,可能只是在欣赏画中的人物微笑,但是对于画家来说,可能就会考虑画画的手法、构图、光线明暗、色彩对比等等方面。

百度高效研发实战训练营-Step2_系统设计_04

同样,在《达芬奇自画像》这幅画作中,光有这个人物还不够,我们还要通过这个人物的个性与背景等等因素来揣摩这幅画作。

百度高效研发实战训练营-Step2_软件工程师_05

综上所述,在艺术方面,我们可以站在很多不同的角度进行解读,但是如果要成为一名创作者,我们需要的不仅仅是欣赏的能力,更重要的是从多角度进行解读、研究与创造的能力。

3、写代码如同艺术创作

写代码就如同艺术创作一般,并不是一件容易的事,写代码的内涵是:

  • ①写代码这个过程,是一个从无序到有序的过程。
  • ②写代码需要把现实问题转化为数学问题。在写代码的过程中,我们需要有很好的模型能力。
  • ③写代码实际上是一个认识的过程。很多时候,编码的过程也是我们认识未知问题的过程。
  • ④在写代码的过程中,我们需要综合的全方位的能力。包括把握问题的能力、建立模型的能力、沟通协助的能力、编码执行的能力等等。
  • ⑤在写好代码之前,首先需要建立编码品味。品味是指我们首先要知道什么是好的代码,什么是不好的代码。这样我们才能去不断地调整自己的行为,然后去学习,去提高我们的编码能力,写出具有艺术感的代码。

2.1.3 软件工程师不等于码农

软件工程师不能只会写代码,更需要具有综合的素质。这个综合的素质包括:
(1)技术
技术能力是基础。包括但不限于编码能力、数据结构和算法能力、系统结构知识、操作系统知识、计算机网络知识、分布式系统知识等等。
(2)产品
要对产品业务有深刻的理解,需要了解产品交互设计、产品数据统计、产品业务运营等。
(3)其他
要了解一些管理知识,需要知识项目是怎么管理的,如何去协调多个人一起去完成一个项目,如何去协调多个人一起去完成一个项目。有一些项目需要具有很强的研究和创新方面的能力。

以上这些能力素质,是一个软件工程师需要具有的综合素质,要成为一个全部掌握这些素质的系统工程师,至少需要8~10年的时间,所以软件工程师绝对不是一个只会简单编写代码就可以的职业。

软件工程师不等于码农。

2.1.4 正确认识代码实践方面的问题

代码实践方面的问题,重点包括以下三个方面:

1、什么是好的代码,好的代码有哪些标准

百度高效研发实战训练营-Step2_数据_06

好代码的标准是:

  • 高效(Fast)
  • 鲁棒(Solid and Robust)
  • 简洁(Maintainable and Simple)
  • 简短(Small)
  • 可共享(Re-usable)
  • 可测试(Testable)
  • 可移植(Portable)
  • 可监控(Monitorable)
  • 可运维(Operational)
  • 可扩展(Scalable & Extensible)

百度高效研发实战训练营-Step2_数据_07

将以上十条标准进行总结精简,可以归纳为

  • 1.代码的正确和性能
  • 2.代码的可读和可维护性
  • 3.代码的可运维和可运营
  • 4.代码的可共享和可重用

了解完好代码的标准,接下来看一下不好的代码主要表现在哪些方面:

百度高效研发实战训练营-Step2_系统设计_08

  • 不好的函数名
    比如在函数名中,加上my等单词,这属于很不专业的用法。
  • 不好的变量名
    比如看不出任何含义的a b c j k temp等变量名
  • 没有注释或注释不清晰
    没有注释的代码是非常难读懂的,注释不倾斜往往是因为文字功底或者描述能力欠缺,从而导致无法通过注释把代码的执行原理讲解清楚。
  • 一个函数执行多个功能
    比如LoadFfomFileAndCalculate()函数,它既执行了文件中去加载数据,还执行了计算功能。一般像这样的函数,我们建议把它切分成两个单独的函数。
  • 不好的代码样式排版
    代码样式排版在某种程度上体现了代码的一种逻辑,好的代码排版能增强代码的可读性和逻辑性,我们在写代码时,要规避不好的代码样式排版。
  • 难以测试的代码
    代码没法测试,就难以编写测试用例。

以上这些都是一些不好的表现。

2、好的代码从哪里来

代码不只是“写”出来的,实际上,在整个项目中,真正的编码时间约占项目整体时间的10%,好的代码是多个环节工作共同作用的结果。

这些环节包括:

  • 1.在编码前,要进行需求分析和系统设计。
  • 2.在编码过程中,要注意单元测试。
  • 3.在编码后,要做集成测试,要上线,要持续运营/迭代改进。

一个好的系统/产品是以上过程持续循环的结果。

下面着重介绍一下重点环节:

  • 1.认识需求分析和系统设计的重要性
    需求分析和系统设计在软件开发中经常被忽略或轻视,但是这两点都是非常重要的环节,人们的直觉就是拿到一个项目就想尽快把它写出来并运行,感觉这样的路径是最快的,但是实际上在前期需求分析和系统设计投入更多的成本,会在后期节省更多的消耗。
    也即前期更多的投入,收益往往最大。
    原因是,如果我们开始的设计做错的话,那么后期开发、测试、上线、调试这些成本都会被浪费掉。
  • 2.清楚需求分析和系统设计的差别

需求分析和系统设计是有泾渭分明的区别的,为了避免这两者相互混杂,我们需要清楚需求分析和系统设计各自的内涵。

百度高效研发实战训练营-Step2_数据_09

需求分析,主要是定义系统或软件的黑盒行为,即外部行为,比如系统从外部来看能够执行什么功能。
系统设计,主要是设计系统或软件的白盒机制,即内部行为,比如系统从内部来看是怎么做出来的,为什么这么做?

  • 3.需求分析的注意要点

需求分析,主要有两个要点:

  • 要点一:清楚怎么用寥寥数语勾勒出一个系统的功能。
    每个系统都有自己的定位,我们可以从简洁的总体描述,展开到具体的需求描述。需求描述的内容,基本包括系统类型描述、系统规模描述、系统定位和系统差异描述、系统对外接口功能描述。

百度高效研发实战训练营-Step2_系统设计_10

  • 要点二:需求分析需要用精确的数字来描述,需求分析中会涉及到大量的数据分析,这些分析都需要精确的数字来进行支撑。
  • 4.系统设计的注意要点
  • 要点1:清楚什么是系统架构
    系统架构(System Architectrue),在wiki上有一个英文定义,阐述了系统架构是一个概念的模型,它定义了系统的结构、行为、更多的视图,进一步解读系统架构。

百度高效研发实战训练营-Step2_软件工程师_11

它的几个要素是,系统要完成哪些功能,系统如何组成,在这些组成部分之间如何划分。

  • 要点2:注意系统设计的约束
    注意系统设计的约束,重点是资源的限制。比如计算的资源限制、存储的资源限制、IO/网络的资源限制等。

百度高效研发实战训练营-Step2_软件工程师_12

  • 要点3:清楚需求是系统设计决策的来源
    精确定义需求中的各个细节,以及量的定义,对系统设计的决策起着重要的作用。
  • 要点4:系统设计的风格与哲学
    在同样的需求下,可能会出现不同的设计方式,其目的相同,设计不同。
    比如复杂指令集和精简指令集的设计差异。
    一个好的系统,是在合适假设下的精确平衡;一个通用的系统,在某些方面,不如专业系统的。

百度高效研发实战训练营-Step2_软件工程师_13

  • 每个组件(子系统或模块)的功能都应该足够的专一和单一。(每个组件,是指子系统或模块等。)
  • 功能的单一,是指复用和扩展的基础。
    倘若不单一,未来就有很可能很难进行复用和扩展。
  • 子系统或模块之间的关系,应该是简单而清晰的。
  • 软件中最复杂的是耦合。
    如果各系统之间的接口定义非常复杂,那么未来便很难控制系统的健康发展.
    值得注意的是,使用全局变量就是在增加系统的耦合,从而增加系统的复杂性。所以在系统中,需要减少使用全局变量。
  • 要点5:清楚接口的重要性

接口,英文名Interface,系统对外的接口比系统实现本身还要更加重要。
接口的设计开发不容忽视,接口主要包括:
1.模块对外的函数接口

2.平台对外的API
这些API很多是基于RPC或者是基于Web API来实现的

3.系统间通信的协议

4.系统间存在依赖的数据
比如:给另一个系统提供的词表

以上,这些都是接口,都需要去重视和很好的定义。

接口重要的原因在于:


1 接口定义了功能
如果定义的功能不正确,那么系统的可用性与价值便会大打折扣。

2 接口决定了系统与系统外部之间的关系
相对于内部而言,外部关系确定后非常难以修改。因此接口的修改需要非常慎重且要考虑周全。


后期接口修改时,主要注意以下两点:


1 合理好用
新改的接口,应该是非常合理好用的,不能使调度方感觉我们做的接口非常难以使用。

2 修改时需要向前兼容
新改的接口,应该尽量实现前项的兼容,不能出现当新接口上线时,其他程序无法使用的情况。


3、如何写好代码

关于具体怎么写代码,下面主要从两个维度来进行介绍:

(1)代码也是一种表达方式

在一个项目中,软件的维护成本远远高于开发成本,而且超过50%的项目时间都是用于沟通。常规意义的沟通方式,主要有面对面交流、Email邮件、文档或网络电话会议等。

但其实代码也是一种沟通方式,在计算机早期,我们使用机器语言或汇编语言,更多考虑代码如何更高效率地执行,然而,随着技术的进步,代码编译器逐渐完善,我们写代码时,更多的是要考虑如何让其他人看得懂、看得清楚。
于是编程规范就应运而生了,编程规范主要包含:

  • 如何规范的表达代码
  • 语言使用的相关注意事项

基于编程规范,看代码的理想场景是:

  • 看别人的代码,感觉和看自己的代码一样。
  • 看代码时能够专注逻辑,而不是格式方面。
  • 看代码时不用想太多

(2)代码书写过程中的细节问题
关于代码数学过程中的细节问题,我们将从模块、类和函数、面向对象、模块内部组成、函数、代码注释、代码块、命名、系统的运营等。

(1)关于模块

模块,是程序的基本组成单位。
在一个模块内,会涉及到它的数据,函数或类。
对于Python、Go、C语言这样的程序来说,一个后缀名为.py、.c、.go的文件就是一个模块。每一个模块需要有明确的功能,需要符合紧内聚、松耦合。

百度高效研发实战训练营-Step2_数据_14

关于模块切分的是否合理,对于软件架构的稳定起着至关重要的作用。

百度高效研发实战训练营-Step2_数据_15

切分模块的方法,先区分数据类的模块和过程类的模块。
数据类的模块,主要是要完成对数据的封装,封装往往是通过模块内部变量,或类的内部变量来实现的。
过程类的模块,本身不含数据,可以从文件中去读取一个数据,或执行一些相关的操作。过程类模块,可以调用其他数据类模块或过程类模块。

编写程序时,我们需要注意减少模块间的耦合,从而有利于降低软件复杂性,明确接口关系。

(2)关于类和函数

百度高效研发实战训练营-Step2_软件工程师_16

类和函数,是两种不同的类型,有它们各自适用的范围。
另外,遇见和类的成员变量无关的函数时,可以将该函数抽出来,作为一个独立的函数使用,这样便于未来的复用。

(3)关于面向对象

百度高效研发实战训练营-Step2_系统设计_17

面向对象是一个优秀的编程方法和范式,但是真正理解的人并不多,面向对象的本质是数据封装,这就要求我们,在写程序的过程中应该从数据的角度开始想问题,而不是从执行过程的角度开始想问题。

同时,我们需要注意一个普遍的错误认知,即C语言是面向过程的,C++是面向对象的,实际上,C语言也是基于对象的,C和C++的区别,主要是没有多态和继承。

C++是一个经常被滥用的语言,因为C++有太强的功能,作为软件工程师,我们最重要的任务是去实现我们所需要的功能,语言只是一种解决问题的工具。

我们应该谨慎地使用多态和继承,如果一个系统中,类的继承超过三层,那么这个系统的复杂度便很难把握。

有这样一个悖论,很好的继承模型是基于对需求的准确把握,而我们的初始设计阶段往往对需求理解的透彻。

系统在初始阶段,可能只是一个很简单的原型,然后通过不断地迭代完善,才逐步发展起来变好的。

(4)关于模块内部的组成

一个模块,比如.py、.c、.go这样的模块,其内部组成主要是:

百度高效研发实战训练营-Step2_软件工程师_18

在文件头中,需要对模块的功能进行简要说明,需要把文件的修改历史写清楚,包括修改时间、修改人和修改内容。
在模块内,内容的顺序尽量保持一致,以方便未来对内容的搜索查询,

(5)关于函数

函数的切分同样十分重要。
对于一个函数来说,要有明确的单一功能。
函数描述三要素,包括功能、传入参数和返回值

百度高效研发实战训练营-Step2_数据_19

功能描述,是指描述这个函数是做什么的,实现了哪些功能。
传入参数描述,是指描述这个函数中,传入参数的含义和限制条件。
返回值描述,是指描述这个函数中,返回值都有哪些可能性。

函数的规模要足够的短小,这是写好程序的秘诀之一。
bug往往出现在那些非常长的函数里。

在函数头中,需要对函数的语义做出清晰和准确的说明。
我们需要注意函数的返回值,在写函数时,要判断函数的语义,确定返回值的类型。
基于函数的语义,函数的返回值有三种类型:

  • 1.“逻辑判断型”函数
    “逻辑判断型”函数,返回布尔类型的值,True或False,表示“真”或“假”。
  • 2.“操作型”函数
    “操作型”函数,作为一个动作,返回成功或者失败的结果——SUCCESS或ERROR。
  • 3.“获取数据型”函数
    在“获取数据型”函数中,返回一个“数据”或者返回“无数据/获取数据失败”。

在这里,推荐一种函数的书写方式:

以“单入口、单出口”的方式书写,这种方式能够比较清晰地反映出函数的逻辑。
尤其是在实现多线程的数据表中,推荐使用一个内部函数来实现,“单入口 单出口”的方式。

(6)关于代码注释

要重视注释。
书写注释,要做到清晰明确,在编写程序的过程中,先写注释后写代码。

(7)关于代码块

代码块的讨论范围,是在一个函数类的代码实现。
书写代码块内的思路,是先把代码中的段落分清楚,文章有段落,代码同样有段落,
代码的段落背后表达的是我们对于代码的逻辑理解,包括代码的层次、段落划分、逻辑等。

代码中的空行或空格,是帮助我们表达代码逻辑的符号,并非可有可无。
好的代码,可以使人在观看时,一眼明了。

(8)关于命名

命名,包括系统命名、子系统命名、模块命名、函数命名、变量命名、常量命名等。

百度高效研发实战训练营-Step2_软件工程师_20

我们要清楚命名的重要性,命名重要的主要原因为:
1.“望文生义”是人的自然反应。不准确的命名会使人产生误导,
2.概念是建立模型的出发点。(概念、逻辑推理=>模型体系)

好的命名是系统设计的基础。
命名中普遍存在的问题有:
1.名字中不携带任何信息
2.名字中携带的信息是错误的

命名不是一件容易的事情,关系着代码的可读性,需要仔细思考。
命名的基本要求是:准确、易懂。
提高代码命名可读性的方式之一:在名字的格式中加入下划线、驼峰等。

(9)关于系统的运营

在互联网时代,系统非常依赖运营,并不是我们把代码写完调试通了就可以,在系统运营过程中,代码的可监测性非常重要,很多程序都是通过线上的不断运行、不断监测、不断优化而迭代完善的。

所以,我们在编写代码的过程中,要注意尽可能多地暴露出可监控接口。

对于一个系统来说,数据和功能同等重要。
数据收集很重要,数据量够大才能知道这个项目或这个系统的具体收益。

关于系统的运营,我们在设计和编码阶段就需要考虑系统的运营,也就要求:

  • 提供足够的状态记录
  • 提供方便的对外接口

2.1.5 怎样修炼成为优秀的软件工程师

通常,人们在判断一名软件工程师的水平时,都会用工作时间、代码量、学历、曾就职的公司等等,这类外部因素作为评判标准。

但事实上,修炼成为优秀的软件工程师,重要的因素有三点:

(1)学习-思考-实践

1.多学习

  • 软件编写的历史已经超过半个世纪,有太多的经验可以借鉴。
  • 技术更新进步迅速,要不断的学习进步。

2.多思考

  • 学而不思则罔,思而不学则殆。
  • 对于做过的项目要去深入思考,复盘写心得。

3.多实践

  • 知行合一谓之善,要做到知行合一,我们大部分的心得和成长,其实是来自于实践中的经历。
  • 在学习和思考的基础之上,要多做项目,把学到的理论运用到真正的工作中去。

(2)知识-方法-精神

互联网的发展日新月异,对于软件开发来说,知识永远在增加。
所以在变化快速的知识世界中,最好的方式是找到方法。

方法就是用来分析问题和解决问题的,虽然说起来简单,但是适合每个人的方法都需要自己去寻找和总结。

在大多数人的成长过程中,并不单单只是鲜花和掌声,更多的是和困难荆棘做斗争,而真正能做出成就的人,都有着远大理想和宏伟志向。

所以光有知识和方法往往是不够的,还需要有精神作为支撑。

下面列出几个精神理念:
1 自由精神、独立思想
人一定要有自己的思考,不要人云亦云,不要随波逐流。

2 对完美的不懈追求
不要做到一定程度就满意了,而是要去不断的追求一个更好的结果。

(3)基础知识是根本

唐朝著名宰相魏征曾经对唐太宗说过,“求木之长者,必固其根;欲流之远者,必浚其泉源”,充分表达了基础乃治学之根本。

百度高效研发实战训练营-Step2_系统设计_21

对于一个软件工程师来说,需要掌握的基础知识是非常繁杂的,包括以下种种:

  • 数据结构、算法、操作系统、系统结构、计算机网络
  • 软件工程、编程思想
  • 逻辑思维能力、归纳总结能力、表达能力
  • 研究能力、分析问题、解决问题的能力等

这些基础的建立,至少也要5~8年的时间。

欲速则不达,希望可以沉下心来,尤其是在自己职业生涯开始的几年,将基础打好。这样,才能在未来有更长远的发展。

2.1.6《代码的艺术》课程总结

通过这部分的学习,我们了解了公司与学校写代码有很大的不同,消除了对程序员这个职业的误解,建立了对软件编程的正确认识,明确了作为软件工程师的修炼方向。

在最后,还需要强调一下几个要点:


  • 软件工程师不等于码农,软件工程师是一个很有深度的职业。
  • 代码,我们可以把它携程艺术品。最终成品完全在于我们自身的修养。
  • 不要忘记我们为什么出发。我们的目的是改变世界,而不是学习编程或炫耀技术。
  • 好代码的来源不是写好代码,好代码是系列工作的结果。
  • 代码是写给别人看的,别人看不懂的代码就是失败的。
  • 写好代码是有方法的。系统工程师至少需要学习8~10年的积累。希望能够沉下心来,把基础打好,提升能力。


2.2 Mini-spider实践

本部分将从两个方面来讲解Mini-Spider框架在实际场景下的使用和注意事项等问题:

2.2.1 多线程编程

2.2.1.1 数据互斥访问

多线程中数据互斥访问的情况非常常见,在真实的生产环境中,经常会有开发人员会将对一张表的“添加”和“判断是否存在”分为两个接口,这是一种非常常见的错误。

以下图中的代码为例,左边的代码是正确的写法,将添加和判断写进一个函数中,右边的代码是典型的错误代码,编写了两个函数,分别是添加和判断函数。事实上,这种将添加和判断写进一个函数,并且运行的实现机制,是同8086的底层指令集支持密不可分的。

百度高效研发实战训练营-Step2_软件工程师_22

2.2.1.2 临界区的注意事项

在代码中,用锁来保护的区域被称为临界区。
以下图代码为例,临界区为​​​self.lock.acquire​​​和​​self.lock.release​​两句话之间的区域。在使用临界区的时候要注意,不要把耗费时间的操作放在临界区内执行。

百度高效研发实战训练营-Step2_软件工程师_23

很多开发人员在编写多线程的时候,会将耗费时间很多的逻辑放入临界区内,这样会导致无法发挥多线程对于硬件资源最大化利用的优势。

2.2.1.3 I/O操作的处理

在多线程编程中,还要注意对于IO操作的处理。
首先,在编写代码的时候,要注意不能出现无捕捉的exception,
以下图最左边的代码为例,如果不对异常进行捕捉,那么一旦出现问题,就不会执行​​​self.lock.release()​​语句,进而导致死锁的发生。

百度高效研发实战训练营-Step2_系统设计_24

其次,因为异常处理是非常消耗资源的,所以我们也不能像图中中间的代码一样,将异常放在临界区内,要像最右边的代码一样处理。

2.2.2 具体细节处理

下面来讲解一下Mini-Spider过程中的细节处理问题,

2.2.2.1 种子信息的读取

很多开发人员会将种子信息读取的逻辑,和其他逻辑耦合在一起,这样是错误的。

百度高效研发实战训练营-Step2_系统设计_25

以图中代码为例,虽然通过​​_get_seeds​​函数直接读取文件中的信息,并灭有书写错误,但是如果后续的开发中文件的格式发生了变化,那就需要重新回来修改这部分的代码。

通过上述代码可以发现,模块划分和逻辑的复杂程度是没有关系的。
即使是逻辑简单的代码,如果没有做好模块划分,也会变得难以维护。

2.2.2.2 程序优雅退出

在真实的应用中,很多开发人员在实现程序退出功能的时候,使用了非常复杂的机制,导致后期维护难度较高。
在实际应用中,可以使用Python系统库中,关于队列的​​​task_done()​​​和​​join()​​​的机制,以下图中的代码为例,左边的代码就是使用了​​task_done()​​​,中间的代码是主程序中的一种常规逻辑使用,右边的是对中间主程序的一种优化,增加了​​spider.wait()​​,让整个逻辑可读性更强,更容易被理解。

百度高效研发实战训练营-Step2_系统设计_26

2.2.2.3 爬虫的主逻辑编码

下面来讲一下爬虫主逻辑代码,编写需要注意的地方:
很多开发人员编写的主逻辑,非常的复杂且难懂,事实上图中的代码就是一个爬虫的主逻辑的所有代码,可以看到,里面包含了六个步骤:
第一步:从队列中拿到任务
第二步:读取内容,如果读取内容失败,则重新读取。如果读取成功,则执行第三步。
第三步:存储数据,
第四步:检查数据深度
第五步:如果数据深度不足,就进一步解析,并且放到队列中
第六步:结束任务

百度高效研发实战训练营-Step2_系统设计_27

2.3 代码检查规则背景及总体介绍

2.4 代码检测规则:Python语言案例详解

Talk is cheap. Show me the code