《系统之美》-摘记

一、系统

几乎每一个系统都有一个重要的目标,那就是确保自我永存。

调节回路:使系统逐渐恢复原来的目标,是保持平衡或达到特定目标的结构,也是稳定性和抵制变革的根源。

增强回路:是自我强化的,随着时间的变化,增强回路会导致指数级增长或加速崩溃。

时间延迟:调节回路上的时间延迟很可能导致系统的振荡。

二、系统之美:系统的三大特征

1. 适应力

适应力是一个系统的基础,使系统能正常发挥和维持功能。

有适应力的系统是动态变化的、非静止或恒定。

适应力使系统具有自我修复或复位能力,在遭遇干扰时能恢复原来状态。

2. 自组织

自组织特性会产生异质性和不可预测性:系统可能演变出全新的结构,发展出全新的行为模式。它需要自由和实验,也需要一定的混乱。

是指系统具有塑造自身、生成新结构、学习、多样化和复杂化的能力。

即使是非常复杂的自组织形式,也有可能产生于相对简单的组织规则。

3. 层次性

层次性是系统的伟大发明,能让系统更加稳定和有适应力,而且因为它们减少了信息量,使得系统各部分更容易记录和跟进。

层次性原本的目的是帮助各个子系统更好地做好其工作,不幸的是,系统的层次越高或越低,越容易忘记这一目的。很多系统因为层次的功能失调,而不能实现预定的目标。

层次结构既要有足够的中央控制,以有效第协调整体系统目标的实现,又要让各个子系统有足够的自主权,以维持子系统的活力、功能和自组织。

继续阅读

设计模式之工厂家族

《冒号课堂编程范式与OOP思想》 13.1 创建模式笔记

工厂家族

构造器的弊端:名字必须与类名一致,缺乏表现力;每次调用都会创建新对象;无法多态,new 必须使用具体类型,没法使用抽象的超类型。

抽象工厂模式:
1. 把静态工厂拆分成了一个接口和若干个实现类;
2. 把工厂方法模式中的主题类中的抽象工厂方法提炼为一个接口,用对象合成取代了类继承。

代码说明示例

1. 静态工厂模式:

public class StaticFactory {
    public enum Type {
        AWT, SWING
    };

    public static Container createFrame(Type type, String title) {
        switch (type) {
            case AWT:
                return new Frame(title);
            case SWING:
                return new JFrame(title);
            default:
                return null;
        }
    }

    public static Component createLabel(Type type, String text) {
        switch (type) {
            case AWT:
                return new Label(text);
            case SWING:
                return new JLabel(text);
            default:
                return null;
        }
    }
}

// 使用静态公共方法的类
class LoginForm {
    public Container createLoginWindow() {
        // 使用前要指定具体的类型
        StaticFactory.Type type = StaticFactory.Type.AWT;
        Container frame = StaticFactory.createFrame(type, "标题");
        Component label = StaticFactory.createLabel(type, "文本");
        // 组装组件
        return null;
    }
}

每个创建对象的方法都通过参数来指定要创建的具体对象类型,调用方必须指定具体的类型。

继续阅读

《代码简洁之道–Clean Code》 摘记

第 2 章 有意义的命名

  • 名副其实: 变量、函数或类的名称应该告诉你,它为什么会存在,它做什么事,应该怎么用。如果名称需要注释来补充,那就不算名副其实。
    代码的模糊度:即上下文在代码中未被明确体现的程度。

  • 避免误导: 提防使用不同之处较小的名称。

  • 做有意义的区分: 要区分名称,就要以读者能鉴别不同之处的方式来区分。

  • 使用读得出来的名字。

  • 使用可搜索的名称 : 长名称胜于短名称,搜得到的名称胜于自造编码代写就的名称。单字母名称仅用于端方法中的本地变量。名称长短应与其作用域大小相对应。

  • 避免使用编码 : 不要用类型前缀、特定前缀来标记成员。

  • 避免思维映射 : 聪明程序员和专业程序员之间的区别在于,专业程序员了解,明确是王道

  • 类名 : 类名和对象名应该是名词或名词短语。

  • 方法名 : 方法名应当是动词或动词短语。重载构造器时,使用描述了参数的静态工厂方法名。

  • 每个概念对应一个词 : 给每个抽象概念选一个词,并且一以贯之。

  • 别使用双关语;

  • 使用解决方案领域名称 :

  • 使用源自所涉问题领域的名称;

  • 添加有意义的语境

  • 不要添加没用的语境 : 精确是命名的要点。

取好名字最难的地方在于需要良好的描述技巧和共有文化背景。

继续阅读

摘记–《富爸爸穷爸爸》

国庆的后面几天看完了《富爸爸穷爸爸》,做了些摘记:

一个人的观念对他的一生影响巨大。

贫穷和破产的区别是:破产是暂时的,而贫穷是永久的。

如果你认为是我的问题,你就会想改变我;如果你认为问题在那儿,你就会改变自己,学习一些东西让自己变得更聪明。大多数人认为世界上除了自己外,其他人都应该改变。改变自己比改变他人更容易。

真正的学习需要精力、激情和热切的愿望。愤怒是其中一个重要的组成部分,因为激情正是愤怒和热爱的结合体。

你现在才 9 岁,已经有了为钱工作的体验了。你只需要把上个月的生活重复 50 年,就会知道大多数人是如何度过一生的了。(类似“一年的工作经验重复用了 N年”)

老鼠赛跑:起床,上班,付账,再起床,再上班,再付账单—-他们的生活从此被这两种感觉所控制:恐惧和贪婪。给他们更多的钱,他们就会以更高的开支重复这种循环。

正是因为有感情,我们才成为人。感情使我们更加真实,它是我们行动的动力。忠实于你的感情,以你喜欢的方式运用你的头脑和感情,不要让它们(恐惧和贪婪)控制你。

不幸的是,对许多人来说,离开学校是学习的终点而不是起点。

继续阅读

《松本行弘的程序世界》– 面向对象

编程语言不是从安全的角度考虑减少程序员犯错误,而是在程序员自己负责的前提下为他提供最大限度发挥能力的灵活性。

一、结构化编程

结构化编程的基本思想是有序地控制流程,即把程序的执行顺序限制为顺序、分支和循环这 3 种,把共通的处理称为例程。

把基本上相同的处理抽象成例程,其中不同的部分由外部传递进来的参数来对应。

面向对象编程是结构化编程的延伸。

二、面向对象编程

多态性(也称动态绑定)、数据抽象(也称信息隐藏或封装)和继承被称为面向对象编程的三原则。

多态

多态的基本内容:根据对象的不同类型而进行适当处理;自动选择最合适的方法,而程序内部则不发生冲突。

各种数据可以统一处理。多态性让程序员只关注要处理什么(What),而不是怎么去处理(How)。

数据抽象

数据抽象是数据和处理方法的结合。对数据内容的处理和操作,必须通过事先定义好的方法来进行。数据和处理方法结合起来成为了黑盒子。

利用现有的类派生新类的方法称为“差分编程法”(difference programming)。

类以数据为核心,把与之相关的处理也都集中到一起。

黑盒化是模块化的基本原则,面向对象编程语言将每一类数据都当作黑盒处理。

继续阅读

《Effective Ecterprise Java》 笔记

只有第7章的。

关于安全:它是站在屋子中心的大象,每个人都可以看到它,每个人都认识它,但每个人都拼命地试图对它视而不见,绕开它进行工作。

  • 认证(authentication):是一种校验行为,检查系统中的一个实体是否真的与它声明的身份相符。认证有三种基本形式:根据你所知的、你所有的或你是什么来进行认证。
  • 授权(Authorize):授权行为是确认系统中的一个实体能够做什么。很多时候,成功的认证导致某种授权。

安全是一个过程,而不是产品

如果你以为技术可以解决你的安全问题,那你根本没有理解这个问题,并且你也没有理解这项技术。

安全不是那种我们可以简单地在系统实现的生命周期的某个时刻 “打开” 的特性。安全必须贯穿于系统开发的每次迭代过程的分析、设计、实现和测试中,否则,漏洞就会出现。

“编写安全代码” 应该是程序员的一条指导原则,就像 “编写好的代码”、“编写优雅的代码” 那样。

安全不仅仅是预防

任何安全系统的另外两个部分就是 检测与反应。软件不能仅仅依赖于预防,检测和反应也必须有,预防甚至不是我们首先要考虑的。

建立威胁模型

一个攻击者可以通过多种方式接触系统,要覆盖所有的入侵方式似乎是不现实的,需要准确地确定系统的哪些部分最重要且容易受攻击,优先保护它们。

为了安全性,需要某种针对我们的应用的安全性的宏图,需要知道哪个地方最容易受到攻击,以及如果被攻击会造成怎样的破坏。这些信息反过来可以帮助我们区分哪些弱点是需要关注而哪些是可以忽略的。这些资源一般被称为一个威胁模型。

如果没有威胁模型,想知道需要花多少时间和精力来防范一个指定的企业系统可能面对的某个潜在的安全攻击是不可能的。

做不安全假设

建立安全系统的一个特殊要点:你必须假设每一样东西都是不安全的,包括你正在建立的那些部分,直到你确定系统可被入侵和攻击的安全疑点都被清除了。

两条关于企业级安全性的定律:

  • 假设一个构件是不安全的,除非你能证明;
  • 一个构建永远不能被证明是安全的。

总是假设每件东西都是不安全的,假设人们会通过其中一些构件攻破系统。

现实世界中的安全系统都使用深度防御策略。它们假设在每个层次上,防御都会被攻破,因此需要另一种防御来以防万一。

我们不能阻止一个攻击者,预防本身永远不能保证提供一个安全的系统,目标是拖延攻击者,以使入侵检测系统和警报管理员可以检测并采取合适的反应措施。

这一条的结论是采用 最低权限原则。

总是验证用户输入

如何处理用户输入是建立一个安全系统的关键,任何一个系统接受的用户输入都是攻击者进入系统的通道。

必须假设客户端验证逻辑没有被执行,对于每个用户输入的提交,都要严格地进行一序列的验证校验以保证用户输入中的所有基于输入的攻击都被过滤了。

(数据与代码分离)


欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

《大型网站技术架构》 笔记 - 架构篇

第四章 瞬时响应:网站的高性能架构

4.1 网站性能测试

性能测试是性能优化的前提和基础,也是性能优化结果的检查和度量标准。

性能测试的指标有:响应时间、并发数、吞吐量、性能计数器。

网站性能优化的目的,除了改善用户体验的响应时间,还要尽量提升系统吞吐量,最大限度利用服务器资源。

4.2 Web 前端性能优化

主要手段有优化浏览器访问、使用反向代理、CDN加速等。

继续阅读

《大型网站技术架构》 笔记 - 概述篇

第一章 大型网站架构演化

1.1 大型网站软件系统的特定

  • 高并发、大流量
  • 高可用
  • 海量数据
  • 用户分布广泛,网络情况复杂
  • 安全环境恶劣
  • 需求快速变更,发布频繁
  • 渐进式发展

1.2 大型网站架构演化发展历程

应用服务与数据服务在同一台机器 –> 应用服务与数据服务分离 –> 使用缓存改善网站性能 –> 使用应用服务集群改善网站的并发处理能力 –> 数据库读写分离 –> 使用反向代理和CDN加速网站响应 –> 使用分布式文件系统和分布式数据库系统 –> 使用NoSQL和搜索引擎 –> 业务拆分 –> 分布式服务

网站使用的缓存分为:应用服务器上的本地缓存和专门的分布式缓存服务器上的远程缓存。

为了便于应用程序访问读写分离后的数据库,通常在应用服务器端使用专门的数据访问模块,使数据库读写分离对应用透明。

继续阅读

《把时间当作朋友:运用心智获得解放》笔记

《把时间当作朋友:运用心智获得解放》是 李笑来 的一本书,在微信上看到有人多次推荐,就买了电子版来看。里面讲的一些东西非常现实,现实到让人有些难以接受。摘录一些话,看了有兴趣的可以去买本看看。

不思考的人是没有问题可问的;会思考的人有问题往往并不去问人,因为他们最终能够自己解决问题。

教是最好的学习方法。

往往并不是有兴趣才能做好,而是做好了才有兴趣。

方法固然重要,但是比起“用功”来说,方法几乎可以忽略不计。(这让我想起经常看到的一句话:以大多数人的努力程度,根本轮不到拼天赋。)

所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就是最重要的策略。

与其不停地找更好的方法,还不如马上开始行动,省得虚度更多的时间。

有些哪怕是常识的东西也需要亲身经历过后才能体会。

坚持不懈就是策略加上重复。

平静接受并且正确认识自己的天性是改变天性的第一步。

见识越少的人越喜欢用自己所有的见识作为判断依据,并且完全不顾自己见识的局限,也不知道自己的见识有局限。

一个故事至少有三个版本:你的、我的、真实的。

事实上,买回来一本书里,哪怕有一句话给我们带来惊喜、带来思考、带来改变,就已经值回价值。

决定一个人富有的三个条件:出身、运气、努力,这三者中,努力是最微不足道的。(这是一个经济学家奈特说的)

我们所面临的今天很大程度取决于我们的过去,无论后悔程度多么强烈都无济于事。

我们所使用的语言往往会限制我们的思维。

耐心就是甘于把时间投入到简单、枯燥但是最终意义非凡的重复当中去。


欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

SMART任务

摘自:《程序员的思维修炼:开发认知潜能的九堂课》

这里的SMART代表具体的、可度量的、可实现的、相关的和时间可控的(Specific, Measurable, Achivable, Relevant, Time-boxed)。对于任何目标,都需要制定一个计划,定出一序列帮助你实现目标的任务。每个任务都应该具有SMART特性。

  • 具体的。一个目标任务应该是具体的。“想学习Erlang”是不够具体的,“想用Erlang编写一个可以动态生成内容的Web容器”就是具体的。

  • 可度量的。可度量的与具体的是相辅相成。很难度量笼统抽象的事物,但是很容易度量具体和详细的事物,只要使用确切的数字即可。度量任务目标,要采取增量进步的方法。

  • 可实现的。一个无法达到的目标不是目标,只是一种疯狂、吸食灵魂的自我挫败。先确定目标是否合理。从现在所处的情况着眼,让每一个目标都可实现。

  • 相关的。目标需要相关,需要在掌控之中。

  • 时间可控的。需要设定一个最后期限,没有期限,目标会逐步衰退,永远被每天更紧急的事情所排挤,这样它永远不会实现。

稳抓稳打,采取循序渐进、比较细小的里程碑。当实现它们之后,会更有动力去实现下一个里程碑。


欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。