0 编程范式 基本概念
- 1:
库和工具包是为程序员带来自由的,框架是为程序员带来约束的
,框架的意义在于使设计者
在特定领域的整体设计上不必重新发明轮子,库和工具包的意义在于使开发者
脱离底层编码,专注特定问题和业务逻辑
- 2:
设计模式(design pattern)和架构(architecture)不是软件产品而是软件思想
, 设计模式是软件的战术思想,架构是软件的战略决策
- 3:
5
个重要的编程范式: 命令式
函数式
逻辑式
对象式
并发式
命令式: 一切行动听指挥, 世界观: 程序是由若干行动指令组成的有序列表,方法论: 用变量来存储数据,用语句来执行指令
声明范式: 目标决定行动
对象范式: 明主社会的编程法则
并发范式: 合作与竞争
- 11:
SoC(Separation of Concerns):即关注点分离
DRY:(Don't Repeat YourSelf) 即尽量减少代码重复
最主要就是: 抽象和分解
抽象和分解的原则: 单一化和正交话,每个模块职责明确单一,模块之间互相独立,即: 高内聚低耦合(high cohesion&low coupling)
- 12:
AOP以切面为模块,描述的是横切关注点(cross-cutting concerns) 也是:程序的纵向主流执行方向横向正交的关注焦点
单个执行点称为接入点(join point),例如调用某个对象的方法的前后. 符合预先指定条件的接入点集合称为切入点(point cut). 再如所有以set为命名开头的方法. 每段绑定的代码称为一个建议(advice)
望文生义: 接入点是点,切入处是面,面由点组成,advice定义于切入点上,执行与接入点处,换言之,共享一段附加代码的接入点组成了一个切入点.切入点一般用条件表达式来描述,不仅有广泛性还有预见性------以后新增的代码如果满足切入点条件的接入点.advice中的代码便自动附上.这是AOP的威力所在也是麻烦所在
OOP只能沿着继承树的纵向方向重用,而AOP则弥补了OOP的不足,可以在横向方向上重用. 即: AOP不是OOP的分支也不是超越了OOP,而是OOP的一种补充----- 尽管AOP不局限于OOP语言
AOP实现的关键是将Advice的代码嵌入到主体程序之中,术语称为:编织(weaving). ----- 将问题分解后再合成,问题才得以还原. 编织分2种: (1)静态编织: 通过修改源码或者字节码(bytecode)在编译期(compile-time),后编译期(post-complie)或加载期(load-time)嵌入代码,这里涉及到了元编程和生产式编程, (2) 动态编织: 通过代理(proxy)等技术在运行期(run-time)实现嵌入. 具体工具包括: AspectJ,AspectC++和一些框架, AspectWerkz,Spring,Jboss Aop等
- 13:
事件驱动
,(有事我叫你,没事别烦我)
采用警觉式者主动去轮询(polling),行为取决于自身的观察判断,是流程驱动的,符合常规的流程驱动式编程(Flow-Driven Programming) . 采用托付者被动等通知(notification),行为取决于外来的突发事件,是事件驱动,符合时间驱动式编程(Event-Driven Programing,简称:EDP)
- 14:
事件
:是程序中令人关注的信息状态上的变化.在基于事件驱动的系统中,事件包括内建事件与用户自定义事件.其中内建事件又分为底层事件和语义事件.此外:事件还有自然事件和合成事件. Callback:
指能作为参数传递的函数或代码,他允许底层模块调用高层模块,使 调用者与被调用者从代码上解耦.异步callback在传入后并不立即调用,使调用者与被调用者从时间上解耦. 控制反转一般通过callback来实现,其目的是降低模块之间依赖性
,控制反转,依赖反转和依赖注入是近义词,他们的主题是控制与依赖,目的是解耦,方法是翻转,而实现这一切的关键是抽象接口(包括 函数指针,抽象类,接口,C++中的泛型函子和C#中的委托)
事件编程的3个步骤: 实现事件处理器,注册事件处理器,实现事件循环
观察者模式又名发布订阅模式,即时事件驱动式的简化,也是事件驱动式的核心思想,MVC架构是观察者模式在架构设计上的一个应用
- 15:
主体是控制与依赖,目的是解耦,方法是翻转,而实现这一切的关键是抽象接口,(不叫回调函数的原因是它比较古老,多出现于过程式编程,抽象接口更现代,更OO的说法,另外: 回调强调的是行为方式------底层反调高层,而抽象接口强调的是实现方式------正是由于接口具有抽象性,底层才能在调用它时无需考虑及高层的具体细节,从而实现控制反转)
- 16:
同样的思想用在整体系统的结构设计上称为架构模式,用在局部模块细节上称为设计模式,用在引导编程实践上则称为编程范式
- 17:
Duck类型的哲学: 名义不重要,重要的是能力 , 静态类型检查类似于 '疑罪从有'的有罪推定制, 动态类型检查类似'疑罪从无'的无罪推定制
鸭子类型是动态类型的一种风格,允许非继承性多态,即: 一个对象的类型可以由其接口集合来确定,不需要显示继承,有利于代码重用也可能滥用
-
18: 动态类型语言(dynamic typing language),正是类型检查发生在运行期(run-time)的语言,静态类型语言(static typing language)是类型检查发生在编译期(运行期之前,否则容易误解为静态类型语言一定是编译型语言(compiled language))
scala是静态类型语言确实动态语言,VB支持动态类型确实静态语言,极少数语言没有类型检查(untyped or typeless) 如汇编语言或Forth
动态类型语言不需要显示的变量声明(explicit declaration),一些静态类型语言有时也不需要,典型的如:ML Hashkell之类的函数式语言,编译器可以通过上下文进行'类型推断' ,另外C#3.0也开始支持局部变量的类型推断以及c++ 的auto
- 19:
动态类型与弱语言,常常混为一谈但是类型的动静与强弱是完全正交的两个概念.
: 静态类型语言中有强类型的Java
也有弱类型的C
,动态类型语言中,有强类型的Smalltalk
也有弱类型的JavaScript
通常弱类型语言(weakly-typed language)允许一种类型的值隐形转化为另一种类型.有时也叫强制转换(自动转化..例如1+'2' 在c里面是'3' 在js里面是'12'), 而强类型语言(strongly-typed language)着意贯彻类型控制,为保证数据的完整和代码的安全有效,一般不允许隐形类型转换.如果需要转换必须是显性,一般通过我们熟知的cast来完成.
- 20:
类型的动静以类型的绑定(binding)时间来划分,类型的强弱以类型的约束强度来划分
- 21:
脚本语言以语言的实际用途为标志,动态语言以语言的语法特征为标志, 动态语言
- 22: C族静态语言: C,C++,JAVA,C# D ,非C族静态语言: VB Delphi, 动态语言有5中: Perl PHP Python Ruby 和Javascript
- 23:
Java 的目的是让一种语言在多种平台上运行,运行在JVM上, C#(.net)的目的是让多种语言在一种平台上运行,运行在 CLR(common language runtime)
- 24:
5种基本抽象: 过程抽象(赋予程序员自定义运算operation能力),数据抽象(赋予自定义类型(type)能力),迭代抽象(赋予自定义循环能力,STL),类型抽象(赋予自定义类族(type family))和多态抽象(自定义多态类型(polymorphic))
- 25:
以接口为中心
就是设计而言的,强调对象的行为,以及对象之间的交互,不关心底层实现细节,更多的属于OOD的范畴,以数据为中心
是就实现而言的,更多的属于OOP范畴,例如抽象数据类型重在设计
,数据结构重实现
,关键是属性的数据表示(representation) OOP以数据为中心而非算法为中心
- 26:
C++友元类(friend class) 更多的是出于语法形式考虑,常用于运算符重载(operator overloading),一个类与其友元类或友函数是 联合关系而不是主客关系,并且是单向授权关系,(更像是一个类分成几个部分,C#3.0之后也引入了partial关键字)
-27: 接口继承不是为了代码重用,而是为了代码被重用,类是实现,类型是接口,无论是Java c++还是C#,宏观上是对象式,微观上还是过程式
- 28:
UML用子类指向父类的箭头表示继承关系,以此表明子类是通过泛话来得到父类的,反之,我们也用特化(specialization)来表示从父类到子类的关系
- 29:
继承是多态的基础,多态是继承的目的, 鸭子类型是不依赖继承的多态
- 30:
具体类型是创建对象的模板,抽象类型是创建类型的模块,抽象数据类型的核心是数据抽象,而抽象类型的核心是多态抽象
抽象类型: 一个类即使没有一个抽象方法也可以被声明为抽象,一个没有任何成员的空接口或称标记接口同样属于抽象类型
- 31:
动态语言里面的mix-in:
(1)抽象性和依赖性,本身没有独立存在的意义,必须融合主体类型才能发挥作用 (2)实用性和可重用性,不仅提供接口还提供部分实现(3)专一性和细粒度性:提供的接口职责明确而单一 (4) 可选性和边缘性:为主体类型提供非核心的辅助功能
- 32:
抽象类的2个特征: 必须继承和无法实例化,但他们并非本质,关键还是他们的目的--------为类型服务
- 33:
值语义的对象是独立的,引用语义的对象确实可以共享的

- 34:
OOP中对象的三大特性: 状态(state),行为(behavior) 和 标识(identity)
- 35: `关联关系可理解为has-a的'有' 关系,如人与工作单位的双向关联----某人又某个工作单位, 聚合(aggregation)是一种强关联,强调整体与部分的关系,可以理解为'owns-a'的拥有关系,如某部门拥有某些成员, '合成(composition)是一种强聚合,可理解为contains-a的含有关系,比如某工作单位含有某些部门'
- 36:
依赖反转: 高层模块不应依赖底层模块,他们都应依赖抽象, 抽象不应依赖细节,细节应依赖抽象
- 37:
DI强调依赖的来源 ------ 完全由外部提供,该依赖最好是抽象的,但并非首要要求,DIP则强调依赖的抽象性. 其次他们的应用范围不同: DI是更加具体的策略,一般用于类级别的模块,故为一种设计模式, DIP还可以用于类库,组件,架构层等大级别的模块,故为一种设计原则
- 38:
组件(component) ------ 组件也是一个抽象层,也可以看作是一个抽象数据类型(ADT),因为他们都是规范接口为客户提供一系列相关服务, 控制反转并无严格的定义,但可抽象为一种管理组件依赖的机制,以保证组件总能在合适的时候获得合适的依赖,显然,依赖注入是控制反转的一种实现方式, 广泛被spring使用, 此外,依赖查找(Dependency Lookup是另一种实现方式,广泛被EJB2.0容器所使用)
- 39:
抽象与规范 间接与分离 依赖于控制 接口与服务,每一对靠前具有代表性: 称为 抽象原则,间接原则,依赖原则和接口原则,(此处的接口不限于OOP中的interface和abstract class为代表的抽象类型,也可以指任何一个组件为外界提供的API) , 抽象与规范是根本,间接与分离是手段,依赖于控制是关键,接口与服务是核心
- 40:
依赖反转:(DIP) 可以作为间接原则的一个推论,即在高层模块与底层模块之间引入一个抽象层.该抽象层实际率属于高层模块,因此把高层模块依赖于底层的关系'反转'为底层依赖于高层的关系, DIP并不能真正消除依赖,但改善了系统的依赖体系,使之更容易经受需求和环境的变化
DIP倡导依赖抽象层,是因为抽象层更稳定,一次依赖反转原则可重述为 稳定依赖原则:模块应朝着文定的方向依赖
DIP与面向接口编程均提倡: 编程应依赖规范而非实现,依赖抽象而非细节
多态合成是在合成类与被合成类直接利用多态机制插入抽象层(接口),它优于实现继承(即合成重用原则CRP)
DI(依赖注入)强调依赖是来源外部的,DIP则强调依赖是抽象的
- 41:
ISP(接口隔离原则): 不应强迫客户依赖那些他们不用的方法,多个专用的接口比单纯一个总接口更好 , SRP提倡高类聚的类ISP提倡高类聚的接口,同时他们还有助于降低系统的耦合度
- 42:
保边原则(protected variations): 受保护的变化,也是PV原则, 找出预计的变化点或者不稳定点,分配其职责以便用稳定的接口来包装
保变原则提倡的是 变中求稳侧重可维护性, 开闭原则提倡的是稳中求变,侧重可维护性
迪米特法则(Law of Demeter, LOD)又称 最少知识原则也是不要和陌生人交谈, -----> 他要求一个对象的方法只能调用一下对象:该对象本身,即: this或者self,该方法参数,该方法内部创建的对象,该对象的直接组成对象,包括其属性及集合属性中的元素, 例如: role.getEmployee().getCity()明显不满足LoD原则
- 43:
对象池与缓存池: 前者重用的是可互换的(interchangeable)等价对象,后者重用的是不可互换的特定对象,常见对象池: 数据库链接,套接字链接(socket),线程等 ...

静态工厂模式, 
工厂方法模式,

抽象工厂模式: 类似模板方法,不同的工厂去实现不同产品
建造者模式: 不需要知道细节,只要知道最终产品,按步骤进行创建,抽象工厂需要知道产品细节
原型模式(clone), 对象池模式 和 单利模式, 对象的复用
特点:
创建者模式都是为了避免通过构造器来创建对象的底层操作,对创建对象的逻辑进行封装和抽象,以提高软件的灵活应变能力
1高质量分布式应用:
高性能 ,可伸缩,高可用,低延迟的要求.同时保证一致性,容错性,可恢复性和安全性
- 1:
可伸缩性:
垂直伸缩时降低锁竞争,水平伸缩时常用的分布式缓存,分布式文件系统等方法
- 2:
高可用
: 均衡负载, 构建可容错,对资源使用有限制的系统
- 3: 实现SOA时,可参考的概念:
SCA
,ESB
和业界的实现SCA
ESB
,
1: SCA: Service Component Architecture:
2: ESB:核心思想是基于中间件来实现系统的交互.基于消息中间件所构建的此系统交互的中间场所称为总线
,系统间交互数据采用统一的消息格式,由总线完成消息的转化,路由,发送到相应的目标应用,(1)标准的消息通信格式,ESB系统中要定义系统发送以及接收消息时的消息格式,以便各个系统保持同样的方式与总线通信(2) 消息路由,是指当总线接收到消息后,根据消息中的数据来决定需要调用的系统.更为复杂的情况时,还可以基于消息路由实现功能编排,即当某个功能需要有多个系统共同完成时,可以在总线上以流程的方式编排访问系统的顺序.例如某功能需要首先访问A系统,然后根据A系统返回的结果来决定访问B系统还是C系统 (3)支持多种的消息交互类型: 支持 请求/响应和发布/订阅等方式, 请求/响应方式会更加方便实现同步请求, 发布/订阅方式则以更加方便实现异步的消息广播. (4) 支持多种网络协议,总线要和多个系统进行交互,通常要支持多种网络协议,例如:HTTP/IP UDP/IP HTTP (5)支持多种数据格式并能进行互相转换,多个系统需要发送消息到总线,并由总线将消息转发,但各个系统消息格式可能不一致,此时需要总线支持数据转换.
- 4: classloader结构:
- 5:
JVM
采用了invokestatic(静态) ,invokevirtual (实例),invokeinterface(接口方法)和invokespecial(调用private方法和编译后的)四个指令来执行不同的方法调用
- 6: 对于方法的指令解释执行,执行方式为经典的FDX循环方式,即:获取下一条指令,解码并分派,然后执行,在实现FDX循环时有: switch-threading,token-threading,direct-threading,subroutine-threding,inline-threading 等多种方式. Sun JDK采用token-threading.也做了一些其它优化: 栈顶缓存,(将栈顶的值缓存在寄存器) (2)部分栈帧共享, (3)在解释执行特殊情况会直接执行机器指令: Math.sin Unsafe.compareAndSwapInt
- 7:
方法区:
存放了要加载类的信息(名称,修饰符等),类中的静态变量,类中定义为final类型的常量,类中的Field信息,类中的方法信息.当开发人员在程序中通过Class对象的getName isInterface等方法来获取信息时.这些数据都来自方法区域. 也是全局共享
- 8:
对象的分配:
(堆
TLAB(Thread Local Allocator ByteBuf) 在eden区
)
-9 : 线程的状态: