学编程,来源栈;先学习,再交钱
当前系列: 软件工程 修改讲义
从功能实现,到高质量代码:优秀程序员的成长之路!

性能

究竟什么是性能?

简单的说,就是程序跑得“快不快”?

但严格来说,程序跑得快不快,是由多种因素决定的:

  • 硬件:CPU/内存/……
  • 数据:结构和大小
  • 软件:代码

#理解#:同样的代码,在不同的环境运行,可能产生不同的性能结果。

PS:提升 vs 优化,优化通常意味着“在资源不变的情况下”,对性能进行提升。

实际提升

真正的提升程序的运行效率:以前1分钟才能完成的功能,现在1秒钟就完成了。

一般来说,这需要:

用户感知

性能的英语单词是Performance,有“表现”的意思。

有时候不一定需要“真正”的性能提升,只要让用户感觉到性能有所提升,甚至仅仅是等待不那么乏味,也是OK的。

这是“硬核”开发人员最容易忽略的,但很多时候非常有用的手段。典型的包括:

  • 进度条:所谓的进度都是“假”的,@想一想@:你怎么能预知出下载这个文件需要多长时间呢?^_^
  • 部分加载:图片逐步呈现/Ajax,看到了页面的主要内容,剩下的内容再花个好几秒进行加载,用户不介意的。(闲话工作小窍门:随时向领导汇报)

同学们不要被“技术”所局限,思维可以更“开放”一些。

甚至可以适当的调整业务需求:比如“很紧俏的”报考/查分:

  • 方案A:报名时间早上8点到晚上8点,结果所有同学8点一到就涌进来,于是系统宕机;越是宕机,同学们越慌张,越是拼命刷;越是拼命刷,越是宕机……
  • 方案B:分段报名:学号尾数为1的8点-9点;尾数为2的9点-10点;……最后还留2个小时不区分尾号,给漏报的同学补漏。

12306刚上线的时候,一票难求,结果催生了“抢票软件”,把12306坑得不要不要的!其实只需要做一个“排队/预报/”(现在有候补)功能,就可以大幅缓解这个问题……

方法论

我们会在整个课程中讲解各种各样的性能提升(improvement)的方法。但是,从一开始就认识到以下(被很多开发人员忽略的)关键,是非常必要的:

找到瓶颈

把整个应用作为一个整体来思考。

否则,任何一个地方都可以优化,优化是没有止境的。

把系统想象成一个城市交通系统,数据在这个系统中流动,最关键的问题是不要堵塞——首先找到堵点(瓶颈),对堵点进行优化!

测量

no profile,no improvement。

不要“拍脑门”做决定。

大胆假设,小心求证:不断的测量,确认性能确实有所提升。

善用工具

以上两项,工具都很重要!

性能监控/日志:

  • 操作系统:CPU/内存/IO……
  • 服务器(IIS/Apache):日志分析IP来源/最多请求……
  • 数据库:慢查询/缓存命中/死锁/……

成本

为什么在很多时候大家都选择堆硬件”来解决性能问题?

天下没有免费的晚餐因为性价比高。一块内存条,一个更快的CPU,就能够解决的问题,开发人员用一周的时间进行优化,那就亏了。

代码优化存在的价值在于:总有硬件解决不了的问题……


安全

互联网是开放的,所以也是不安全的。

黑客/病毒/木马/漏洞/后门

随着互联网的蓬勃发展,网络安全逐渐形成一个专门的学科/职业/岗位。作为开发人员,也应对有所了解:

黑客

这就是给自己脸上贴金了,^_^

最初曾指热心于计算机技术、水平高超的电脑高手,尤其是程序设计人员,……hacker客观的解释:

a person who secretly finds a way of looking at and/or changing information on sb else's computer system without permission和计算机技术水平没关系,而且一般都不是程序员!程序员不会干这种事。(别问我密码忘了怎么办?)

黑客世界也是金字塔结构的,遵循80/20原则,一大批的“工具”人,做什么“灰产”……

病毒

在计算机程序中插入的破坏计算机功能或者破坏数据,影响计算机正常使用并且能够自我复制的一组计算机指令或程序代码
  • 外部侵入:区别于漏洞、后门
  • 破坏性:区别于木马
  • 传染性:哦豁~,最大的特点,区别于特定的黑客攻击

木马

名称来源:特洛伊木马。

也可以把它也归入病毒,但是木马通常更隐蔽,没有明显的破坏性,其目的:
  • 窃取数据
  • 远程控制

黑话:“肉鸡”、“种马”。病毒越来越少,木马越来越隐蔽……

漏洞

在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。

可以简单的理解为安全性方面的bug。我们开发人员,应该极力避免我们的代码中有这样的漏洞,燃鹅……

几乎所有攻击(病毒/木马/黑客)都是因为系统本身的漏洞!

发现漏洞之后发布的修复程序,一般被称之为补丁

后门

开发人员故意留下的、能够以非常规手段,隐秘的访问、监听、控制项目或系统的手段。比如:

  • 键入XXXXXX,自动掉落XXXXX装备……一般是为了测试
  • 用某种特定的手段,就可以打开用户手机的摄像头、监听用户的语音

如何让一个系统更安全?

和普通人的直觉相反,开源,而不是闭源,会让系统更安全!

@想一想@:为什么?

设定边界

哪些问题算是安全问题?

可以是数据层面的、也可以是代码层面的,甚至是功能层面的:

  • 泄露:比如用户的密码、个人资料被非法获取
  • 破坏/篡改:得不到的就毁掉
  • 瘫痪:DDOS攻击
  • ……

可以使用的手段五花八门,可以是蛮横而暴力的,也可以是精心设计的诱骗……

其实没有绝对的安全,这就是矛和盾的关系。但让恶意用户破解的成本远大于其收益,就可以认为是安全的。

比如说密码,理论是总是可以通过无数次的尝试暴力破解的。

但我们可以通过:

  • 验证码限制机器人程序
  • 密码的长度
  • 限制错误输入次数
  • ……

增加其暴力破解的时长,让恶意用户无利可图,知难而退即可。

另一个典型的例子就是:用“肉鸡”发起的DDOS攻击,几乎是无解的。最后就是比拼资源/算力!


可维护性

项目最难的不是上线(20%),而是维护(80%)。

今天的项目,尤其是快速迭代的Web项目,都是“边跑边改”,“三年,旧三年缝缝补补又三年”。(复习:从瀑布到敏捷

宏观架构

想象你管理着一个工厂:

  1. 工厂很大,生产的环节很多,所需要的配套更多。
  2. 工厂的产品/厂房/流水线经常调整,一会儿这里拆一会那里建,挪过去挪过来的

你怎么办?#请始终思考这个问题!#

你首先就需要一个架构(Architecture):划分出部门车间,规划好生产流程……

@想一想@:为什么需要架构?

  • 分门别类,井井有条:避免无序导致的混乱
  • 但是,严密的组织架构也会导致:效率低下的官僚主义

#体会#:不要把问题只归咎于“人”的品德能力上面。

好的架构,是在自由和约束之间的微妙平衡。

三种拆分

架构可以是事先设计的,也可以是在代码实践中逐步形成的,或者兼而有之。

软件项目架构,本质上来说,它仍然是对代码的组织管理,但更加的宏观和全面。

架构的一个最主要工作就是对项目进行拆分:

  • 分层:水平划分
  • 模块化:垂直划分
  • 微服务:“胡乱”划分


做架构的人就是大名鼎鼎的架构师!(但和CEO一样,本身并不能说明任何问题)

更高的追求

一个拥抱变化的、有弹性(flexible)的项目,必然是:

高内聚,低耦合

  • 高内聚:一个车间/部门,凭它自己就可以特定的工作
  • 高耦合:工厂内部各个车间/部门,高度依赖,千丝万缕的联系,一个简单的事情,都要n多个部门配合

SOLID原则:

  1. 单一职责(Single Responsibility):各司其职,职责越单一(清晰)越好。负责前台收银的,就不要收盘子;负责收盘子的,就不要去做汉堡。(更容易内聚)
  2. 开闭原则(Open Closed):对扩展开放,对修改关闭。一个部门,就一个对外窗口,其他部门不能绕过这个窗口直接和部门内部人员联系;但窗口本身具有灵活性,不管是VIP还是OIP都可以接待。
  3. 里氏替换(Liskov Substitution):基类变量可以子类对象替换。
  4. 接口隔离(Interface Segregation):类似于单一职责,接口也要越简单越好
  5. 依赖倒置(Dependence Inversion):高层模块不应该依赖底层模块,两者都应该依赖其抽象。先定好规范(接口),然后按规范办事。

微观实现

推荐三本书:

代码整洁之道

代码质量与其整洁度成正比。

从命名、注释、格式、函数封装……讲的东西非常low,一点都不高大上。

但是,保守点说,给同行一点面子,60%的程序员(包括有时候我自己)都没有做到代码整洁

重构(refactor)

好代码是“改”出来的。

这个改动的过程就被称之为“重构”:不改变原有功能(可观察行为)的前提下,提高代码的质量(重新组织代码结构)。

这里的质量,主要是指的是代码的可读(理解)性和可维护性。

这书里引入了一个词 bad smell(臭味),不能说你代码写“错”了,因为它能够正确的运行,但就是让人不舒服难受。

PS:(个人认为)就是“屎山代码”的来源

对于屎山代码的一个忠告:小步重构,而不是推倒重写。

部分内容和代码整洁之道重复,但细品的话:

  • 整洁:看上去就舒服
  • 重构:用起来也不错,这里的“用”,就是“维护”,让别人看到懂看得明白,改起来方便

#体会#:首先是可读,然后是可维护。

代码是写给人看的。

设计模式(Design Pattern)

更经典的是《设计模式:可复用面向对象软件的基础》(由四个作者合著,被称之为GoF(Gang OFour),书中总结出软件设计开发中常用的23中模式

但对于初学者,我推荐:

因为这本书讲明白了:为什么需要使用设计模式。                 

什么是模式?就是“套路”。比如:

  • 工厂(Factory)模式:对象不能直接new,而是通过Factory类/对象生成
  • 代理(Proxy)模式:父类变量装子类代理对象(ORM中lazy load)
  • 构造器(Builder)模式:……

但是,为什么要这么“绕着弯”的写?

  1. 每一种设计模式,其实都有一种适用场景,都是要解决某种特定的问题。(设计模式是药,有病才吃,没病不要乱吃)
  2. 但这种场景/问题,代码实践不够,很难很难体会。(没有十万行代码量,不要谈设计模式)
  3. 所以就算新人学了设计模式,往往也是滥用设计模式,徒增加代码复杂度
  4. Web开发中,尤其是业务逻辑层面,需要设计模式的场景并不多(但在框架/组件/类库中应用广泛)

这就是我们课程为什么不讲的原因(除了单例模式,布置在作业中)。

实际上,设计模式的热度也是逐年下降,原因除了上面讲的“用不到”:


  • 代码整洁的要求n多项目都没有实现。
  • 而且,设计模式增加了代码复杂度,违反了KISS原则(Keep It Stupid Simple)。


平衡

过早的优化是万恶之源?

为什么不能在一开始写代码的时候就注意性能问题?

高质量代码三要素:安全性能可维护,三者不可兼得!

举例理解:

  • 安全必然拖累性能:反复的加密/解密/验证……
  • 可维护性也会拖累性能:分层分类函数调用,对计算机都是没有意义的,都是性能浪费,性能最高的是二进制


很多程序员,尤其是缺乏大型项目实际开发工作经验的程序员,往往会忽略“可维护性”。

为什么开发一个淘宝要那么多工程师?很多答案都在讲性能,淘宝的商品/访问量/交易量……大,海量的数据,需要更多的工程师?——我觉得需要的可能是更聪明的大脑,一个顶一百个,^_^!

但实际上,根据我的经验,需要那么多工程师最大的原因是:维护。

  • 写新功能,熟练的程序员可能一天能写上千行
  • 但改bug,我曾经一个月改一个bug还没改成

如何安全性能可维护不可兼得,如何取舍?中庸/平衡/过犹不及/因地制宜/是一种艺术。

学习笔记
源栈学历
今天学习不努力,明天努力找工作

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 软件工程 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码