其他事项

0 编程范式 基本概念

  • 1: 库和工具包是为程序员带来*的,框架是为程序员带来约束的 ,框架的意义在于使设计者在特定领域的整体设计上不必重新发明*,库和工具包的意义在于使开发者脱离底层编码,专注特定问题和业务逻辑
  • 2: 设计模式(design pattern)和架构(architecture)不是软件产品而是软件思想, 设计模式是软件的战术思想,架构是软件的战略决策
  • 3: 5个重要的编程范式: 命令式 函数式 逻辑式 对象式 并发式

命令式: 一切行动听指挥, 世界观: 程序是由若干行动指令组成的有序列表,方法论: 用变量来存储数据,用语句来执行指令
声明范式: 目标决定行动
对象范式: 明主社会的编程法则
并发范式: 合作与竞争

  • 4 : 3种核心编程范式采用不同的机制:

    • 命令式 : 自动机机制 通过设计指令完成从初试状态到最终状态的转变
    • 函数式: 数学变换机制,通过设计函数完成从自变量因变量的计算
    • 逻辑式: 逻辑证明机制,通过逻辑推理完成从题设到结论的证明
  • 5: OOP: 以数据为中心组织逻辑,将系统视为相互作用的对象集合,并利用继承与多态来增加可维护性,可扩展性和可重用性 ,这种思想也能应用到函数式逻辑式,只不过对象的方法从命令式的过程分别换位函数式中的函数逻辑式中的断言,大致来说,命令式,函数式和逻辑式互相平行,而OOP与他们正交
  • 6: JavaScript是基于对象(Object Base) 而不是OO(Object-Oriented),基于对象有2种形式: 限制版OOP:即具备对象概念但不具备OOP一些其他概念,如继承和多态 基于原型的(prototype-base)或者说基于实例的(instance based) 而不是通常OOP是基于类的(class-based)

    • 7: 以C语言为例: 信息隐藏可以使用static来实现,继承可以用合成(composition)来代替, 多态可以利用 函数指针来实现.只要设计合理,C语言也具有: 可维护性,可扩展性和可重用性
  • 8: 如果把整个流程看作是一课倒长得的树,过程式编程自树根向下,逐渐分支,直到每片树叶,类似数学中的分析法,即知果索因的逆推法 OOP则从每片树叶开始,逐渐合并,直到树根,类似数学证明中的综合法,即执因索果的正推法 倘若树根是主函数,离树根越近,离用户需求也越近.如果使用过程式,采用逆推法,树干的改变容易导致树枝响应改变,相反OOP从树叶开始设计,抽象程度高,收到波及程度小,因此更容易维护 OOP以对象为基本模块单位,而对象是实现中具有事物和抽象概念的模拟,这使得编程设计更自然人性化, 例如: 牛.吃(草) 与 吃.(牛,草)
  • 9: 过程式以函数为基本单位,oop对象为基本单位. 区别: 函数是被动的实体,对象是主动的实体 ,过程式程序的世界是君主制,主函数是国王,其他函数是成名,等级分明.OO程序世界是*制所有对象都是独立而平等的公民,有权保护自己的财产和隐私并向他人寻求服务,同时有义务为他人提供承诺的服务.公民之间通过信息交流来协作完成各种任务 , 封装使得公民拥有个体身份,需要对自己负责,继承使得公民拥有家庭生份,需要对家庭负责,多态使得公民拥有社会身份,需要对社会负责
  • 10: 泛型编程: Generic Programing: 将算法与与其作用的数据分离,并将后者尽可能泛话,最大限度的实现算法重用. 这种泛话是基于模板(template)的参数多态(parametric polymorphism)相比于OOP基于继承(inheritance) 的子类多态(subtyping polymorphism),不仅普适性更强而且效率也更高. GP最著名的代表: STL(算法,容器和迭代),其后Javav C# D等语言所吸纳.此外一些函数式语言如Haskell Satand ML,Ocaml也支持CP, 但是他们实现方式不同: C++ 和D采用 类型模板(template) Java采用类型擦除(type eraser) C#采用类型具话(reification) 附录:算法是一系列可行的步骤,容器是数据的集合,是抽象化的数组,迭代器是算法与容器之间的接口,是抽象化的指针.算法串联数据,数据实例化算法
    其他事项
  • 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),线程等 ...

其他事项

  • 44: 创建者模式(7):

静态工厂模式, 其他事项

工厂方法模式,

其他事项

抽象工厂模式: 类似模板方法,不同的工厂去实现不同产品

建造者模式: 不需要知道细节,只要知道最终产品,按步骤进行创建,抽象工厂需要知道产品细节

原型模式(clone), 对象池模式 和 单利模式, 对象的复用
特点: 创建者模式都是为了避免通过构造器来创建对象的底层操作,对创建对象的逻辑进行封装和抽象,以提高软件的灵活应变能力

  • 45: 结构模式(structure pattern): 他关注的是如何吧类和对象组合成更大的结构,实质上就是一个利用继承层级的类结构和聚合层级的对象结构来构建更高层抽象的过程

    • 1: 桥接模式: 信息的隐藏能将接口与实现从逻辑上分离,却不能从物理上分离,桥接模式克服了这一缺点,使得一个类能同时拥有多种实现,并且可以动态切换
    • 2 : 适配器模式: (和桥接模式有点类似): 可以解决服务提供者与服务享受着之间接口不兼容的问题 - 3: 装饰着模式: 对一个对象增加或者修改某些职责或行为 , 适配器模式也称包装模式(wrapper pattern) 恰巧也是装饰着模式的别名 适配器模式改变对象的接口而保持对象的职责,装饰器模式改变对象的职责而保持对象的接口, 代理模式也一样保持对象的接口,不同的是代理模式通常增加接口服务,从行为上来看,Proxy对象在对客户的请求进行必要的处理后再转发给RealSubject对象,满足代理的实质条件

      • 4: 代理模式: 如果摸个对象的初始化十分耗费时间或资源,却又未必立即投入使用,便可以使用代理来延迟创建(lazy initialization) 还有ORM框架中,加载一个与数据库对应的实体(entity)对象可能会返回一个代理对象,以减少对数据库的访问-----这里代理叫 虚拟代理(virtual proxy) 还有一种多用于分布式系统中的远程代理(remote proxy) :它可以把远程机上的某个对象用本机上的对象(stub)来表示 这两种的区别: (1) 虚拟代理: 对象是否被真正的创建,远程代理:对象是否在本地创建 .(3)由于远程对象与本地对象的地址空间(adress space)不同,Proxy对象不能直接引用RealSubject等(不过可以使用web serverice,RMI等技术实现)
    • 5: 外观模式(facade pattern): 引入一个抽象的中间层,简化了外界对某个子系统的访问,优点(1)客户不再与各种不同的类打交道,之需与一个统一的接口进行通信,符合Lod原则(2)子系统中各服务类发生边界
    • 6: `外观模式与 (代理模式和装饰器模式)的区别: 前者改变了被包装对象的接口,而后两者没有改变接口
      与(适配器模式)的区别: 他是为了提供一种更高层次的抽象和粒度更粗的服务,而适配器模式通常只是单纯的作接口转换`
    • 7: 复合模式: 他和装饰模式一样,都是利用类型层次和聚合层次来构造更大的符合结构
    • 8: 享元模式 的关键抽象出一类对象内在的,不因环境而异(context-insensitive)的状态,封装后作为共享单元----flyweight, 客户端要承担更多的责任-----存储或计算flyweight的上下文(context)信息,否则对象因数据不足而无法提供服务
    • 9: 结构模式关注的是对象静态的结构,行为模式(behaiorial pattern)关注的是对象的动态行为: 分为: 责任链模式, 观察者模式, 中介者模式,状态模式, 备忘录模式,访问者模式,迭代器模式,解释器模式
    • 10: 责任链模式: 消息发送者虽然知道'哪一类'对象是接受者,却不知道'哪一个'对象实际参与了请求的处理,例如: 事件模型(evnet-model),Servlet filter 和异常处理中(exception handling), ,由于责任链可以在运行期改变,他实际上实现了动态层次

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 : 线程的状态: 其他事项
上一篇:昨晚的我是歌手,人工智能也掺了一脚


下一篇:spring boot