《代码的艺术》直播笔记

技术(加强)

编码能力,数据结构,算法

系统结构,操作系统,计算机网络,分布式系统

产品

对业务的理解,交互设计,产品数据统计,产品/业务运营

项目管理

研究和创新

Research && Development

一个系统工程师的培养需要至少8至10年的时间

在Coding的过程中,需要掌握:

把握问题的能力

建立模型的能力

沟通协作的能力

编码执行的能力

 

写代码,要先建立起品味,知道什么是好代码?好的代码时从哪来的呢?

首先,写代码时,严格要求自己的代码质量

然后,从好的开源项目中,看看好的代码是如何写的

一流代码的特性

鲁棒性

高效 fast

简结 simple 逻辑简单易懂

简短 small

可测试 testable

可重用 portable

可移植

可监控

可运维

可扩展

 

总结起来就是:

正确和性能

可读和可维护

可重用

运维和运营

 

写好代码的是个秘诀 林斌

可监控/可观测

可运维

可扩展(Scalable & Extensible) 前者是水平可扩展,后者是功能上可扩展

 

坏代码的味道

函数命名

变量命名

无注释

函数不是单一目的(多目的的代码,未来难以维护)

不好的排版(需合理使用空格和空行)

软件代码无法测试

 

好代码从哪里来呢?

代码不只是写出来的(需要前期的调研、思考、系统设计、模块设计)

编码前(经常被忽视或忽视的环节)

需求分析,系统设计(需完善)

编码中

编写代码,单元测试(需完善)

编码后

集成测试,上线部署,持续运营/迭代改进

 

需求分析和系统设计

前期多投入,收益更大。

修改代码和修改文档,那个成本更高?

需求分析:做什么 what

系统设计:怎么做,为什么这么做?

 

需求分析

怎么用寥寥数语勾勒出一个系统的功能?

???

 

误区1:需求分析是产品经理的事情,和RD有关系?

深入到产品需求评审,激起做产品的激情。

 

误区2:在需求分析时,大量考虑系统实现的细节

忽略需求分析,直奔系统设计,甚至代码实现细节

危害:

阻碍 需求分析 的聚焦

实现决定需求

 

需求分析的重要性

导弹 vs 炸弹

需求分析的地位:导弹中的导航模块

现实情况:有太多的炸药(开发资源)在爆炸在了错误的地方

 

系统设计

系统架构,模块设计,接口定义,数据定义

关键算法,设计思路(why)

设计文档的分类:

1、总体设计文档

2、子系统设计文档

3、接口定义文档

4、关键算法说明文档

5、数据库表设计文档

......等等

每个设计文档都有自己的聚焦和读者,不同需求的读者仅读各自的文档即可。

 

系统架构

静:系统如何组成,功能在这些组成部分之间如何划分?

动:各子系统如何联动,如何完成任务/流程?

细:更详细的刻画出系统的全貌

 

大致可分为两种:

总体设计:大系统的架构

模块设计:子系统的架构

 

系统设计的方法

每个组件(子系统/模块)的功能都必须足够的专注和单一

功能的单一是复用和扩展的基础

子系统/模块之间的关系应该简单而清晰

软件中最复杂的是耦合(为什么全局变量要极力避免?)

系统设计的约束

资源的限制:计算,网络,存储,IO

比如拿时间换空间,计算资源来换取存储,存储不够用压缩来解决。

需求是系统设计决策的来源

在设计中,经常需要做trade-off

需求是决定的重要依据

 

模型/抽象的思维能力

思考的重点:概念,模型,数据结构,算法

脱离开代码的细节:语言 and 函数

 

扩展阅读:

google三大系统经典论文

GFS

BigTable

Map Reduce

重点看一下:

怎么描述问题和出发点

怎么描述模型

怎么描述系统架构

 

关于接口(interface)

系统对外的接口,比系统实现的本身还要更重要。

合理的设计对外api接口,是本学问。

这个问题被多数人忽略!!!

why?

接口定义了功能:如果功能不正确,系统就没有用,更不会有人使用这个功能。

接口决定了外部关系:相对于内部,外部关系确定后非常难以修改,大点的软件会有ABI测试(接口兼容性)(越被人广泛使用的软件,越难以修改接口)

 

哪些是接口

模块对外的函数接口

平台对外的api

系统间通信的协议

系统间存在的依赖的数据

 

设计和修改接口,需要注意什么?

合理好用

修改时尽量向前兼容

 

代码也是一种表达方式

代码主要是写给人看的

编程规范(遵守公司的编程规范,一些语言相关的注意事项)

 

模块(module)

模块:数据,函数,类

c py go 一个文件就是一个模块

模块需要有明确的功能

高内聚,松耦合(经常提起,要铭记)

怎么切分模块,是一个需要谨慎考虑的事情

数据类的模块

过程类的模块

 

模块的重要性

好的模块划分是软件架构稳定的基础

模块划分的好,日后的修改成本很小,和房屋内部装修差不多,否则就要推倒了重新改房子。

减少模块间的耦合-》降低软件复杂性

清晰的模块有利于代码的复用

 

模块切分的误区

误区1:所有的代码放在一个模块中,因为规模太小

切分模块的原则和代码规模没关系

程序的规模在早期无法预估

误区2:将所有附加功能都放到utils中

在utils中,也要根据功能来进行细分

误区3:从过程的角度出发考虑模块的划分

应该首先从“数据”的角度出发考虑

 

类和函数

推荐:和类的成员变量无关的函数,可作为一个独立的函数,便于未来复用。

 

函数

函数描述的3要素

功能描述:函数做什么的

传入参数描述:含义,限制条件

返回值描述:各种可能性

函数的规模

要足够的短小

写好程序的一个秘诀,把函数写的简短一点(除非性能考虑)

bug往往出现在那些非常长的函数中

 

函数的返回值

True,False

逻辑判断型函数,表示“真”或“假”

is_white_cat

OK,ERROR

操作型的函数,表示成功或失败

如data_delete

Data,None

获取数据型的函数,表示“有数据”或“无数据”

如int get_data(void** data)

glang的返回值形式:(data,error)

 

函数:单入口单出口

多线程下数据表的实现:

可使用一个内部函数来实现“单入口单出口”

 

代码块

讨论范围:一个函数内的代码实现

思路:把代码的段落分清楚

形式的背后是逻辑(划分、层次)

注释不是补出来的

我习惯先写注释,然后再写代码

备注:一个在代码表达不好的同学,在其他表达上一般也存在问题,如文档,email,ppt,口头表达

 

怎么修炼成优秀的软件工程师?

学习-》思考-》实践

知识-》方法-》精神

基础是治学之根本

 

有了足够的时间以后,必须把身体和技术好好磨练下。

你可能感兴趣的:(职场生涯,代码的艺术,如何写更好的代码)