临时笔记(思考路线)

一,dubbo
1,服务暴露和服务引用的过程熟悉吗,结合源码详细说一下?底层通讯用了netty,说说netty的核心组建,线程模型,内存池设计。注册中心用zk,说说zk的选举过程

2,dubbo原理,rpc流程
只要知道通迅网络需要传输、序列化,集群需要负载容错,服务发现需要注册中心,服务管理用目录,这就行了,背都不用背,自己写一个就会了
通过序列化技术、网络技术、反序列化技术进行网络远程调用的一种框架[坏笑]
通过注册中心获取提供者,然后根据协议发起请求,请求内包含调用的接口信息参数等,提供者接收请求通过反射调用相应服务,封装结果和异常返回响应,客户端再根据响应抛出异常或返回,在此之上再提供failover,路由,filter等,这样吗

3,有http为何要用dubbo
我做web开发的经验不多,想从我个人理解的角度解释一下这个问题。首先实现rpc的功能,不论是基于http还是tcp都是可以的,rpc本质无非是序列化+网络传输+反序列化,网络传输用http还是tcp都是可以的,但是在做网络传输的过程中就涉及到io的阻塞非阻塞,线程模型的同步非同步,数据从内核态到用户态的拷贝,这些东西基本发生在tcp和http之间,如果想要更好的性能,必然需要去优化这一块,既然都要在这一块做优化了,干嘛不直接把http干掉获得更好的性能呢
有啥好比较的,一个是协议,一个是框架。
长链接,适合高并发,http每次需要三次握手四次挥手
其实最主要的目的是为了解决http协议并发度低的问题。一条http连接上的请求响应都是串行,如果想并发多个请求,就必须开启多条tcp连接,tcp连接在三握手上会有一定的延时开销。所以人们就自己搞了很多rpc协议,说白了就是性能比较好应用层协议,比如提供了高效序列化、多路复用等能力。其实如果用http2的话,性能就不至于比其他rpc协议差多少。

http与rpc:

在HTTP和RPC的选择上,可能有些人是迷惑的,主要是因为,有些RPC框架配置复杂,如果走HTTP也能完成同样的功能,那么为什么要选择RPC,而不是更容易上手的HTTP来实现了。
本文主要来阐述HTTP和RPC的异同,让大家更容易根据自己的实际情况选择更适合的方案。

  • 传输协议
    • RPC,可以基于TCP协议,也可以基于HTTP协议
    • HTTP,基于HTTP协议
  • 传输效率

    • RPC,使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以很好的减少报文的体积,提高传输效率
    • HTTP,如果是基于HTTP1.1的协议,请求中会包含很多无用的内容,如果是基于HTTP2.0,那么简单的封装以下是可以作为一个RPC来使用的,这时标准RPC框架更多的是服务治理
  • 性能消耗,主要在于序列化和反序列化的耗时

    • RPC,可以基于thrift实现高效的二进制传输
    • HTTP,大部分是通过json来实现的,字节大小和序列化耗时都比thrift要更消耗性能
  • 负载均衡

    • RPC,基本都自带了负载均衡策略
    • HTTP,需要配置Nginx,HAProxy来实现
  • 服务治理(下游服务新增,重启,下线时如何不影响上游调用者)

    • RPC,能做到自动通知,不影响上游
    • HTTP,需要事先通知,修改Nginx/HAProxy配置

总结:
  RPC主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便。HTTP主要用于对外的异构环境,浏览器接口调用,APP接口调用,第三方接口调用等。

RPC 本身是一种框架,而http 是应用层的协议,两者没有可比性,所以不能说RPC就是基于TCP协议,RPC 也可以是用http协议实现的啊,比如Google 的gRpc 就是基于http2.0实现的

4,dubbo是默认推荐的方式,使用长连接,nio的形式。实现上就是服务消费方与服务提供方及注册中心之间使用长连接。

缺省协议,使用基于netty3.2.2+hessian3.2.1交互。
连接个数:单连接
连接方式:长连接
传输协议:TCP
传输方式:NIO异步传输
序列化:Hessian二进制序列化
适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。
适用场景:常规远程服务方法调用

通信跟netty又有什么关系?dubbo底层使用了netty,netty封装了nio的网络编程过程,dubbo里面通过netty client,netty sever进行nio的io过程,即完成请求与返回的过程。

5,dubbo的spi机制。

SPI 全称为 Service Provider Interface,是一种服务发现机制.

说白了是啥呢,比如你有个接口,该接口有3个实现类,那么在系统运行时,这个接口到底选择哪个实现类呢?这就需要SPI了,需要根据指定的配置或者是默认的配置,找到对应的实现类加载进来,然后使用该实现类的实例.

将某功能实现写成插件,作为jar包,某工程引入后,可以配置某接口,实现即为该功能的实现类路径

接口A => 实现A1,实现A2,实现A3
配置一下,接口A = 实现A2
在系统实际运行的时候,会加载你的配置,用实现A2实例化一个对象来提供服务

  • @SPI(“dubbo”)
    通过SPI机制提供实现类,实现类是通过将dubbo作为默认key去配置文件里找到的,配置文件名称为接口全限定名,通过dubbo作为key可以找到默认的实现类com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol

参考:https://javaedge.blog.csdn.net/article/details/95177225?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-7.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-7.edu_weight

6,zk如何保证数据一致性的,与dubbo有什么关系?

https://blog.csdn.net/qq_41936805/article/details/98069515?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-1-98069515.nonecase&utm_term=zookeeper%E4%B8%BA%E5%95%A5%E6%95%B0%E6%8D%AE%E6%98%AF%E5%BC%BA%E4%B8%80%E8%87%B4%E6%80%A7&spm=1000.2123.3001.4430

二,kafka
1,Kafka怎么保证leader和follower一致性
Leader epoch
2,acks,isr,osr,rehash,幂等,交付保证,页缓存,应用场景
3,kafka有重复消费问题吗?如果有,原因有哪些?
消费端接口幂等啊
4,partition 10个,consumer设置多少合适
5,kafka,都有哪些应用场景,举例说说,kafka stream你研究过吗?感觉这个能派上用场么
业务解耦,日志传输,延迟处理,简单的任务调度分配等场景比较多,kafka stream没用过,不过这种还是学学spark或者flink吧。用冷门的技术栈个人踩坑难解决
6,经常碰到的组件 producer,consumer,broker,partition
7,kafka是怎么做失败重试的

8,kafka和rabbitmq什么区别?什么场景适合kafka 什么场景适合rabbitmq?请说出你们认为最有格调的回答
吞吐量大用kafka,消息可靠用rabbitmq
K适用海量消息场景,吞吐量较大,R适用交易场景,可靠性有保障

9,kafka性能为什么好?  和rocketmq的比较
网络:批量合并传输;存储:顺序写,page cache  ,zero copy。

10,为什么consumer要设计成线程不安全[害羞]
因为设计成线程安全的成本高,而且没必要,consumer比较轻量,每个线程用一个consumer就够了
就是希望你顺序消费,假如你多线程消费,offset100比99前消费,100处理完了99没有,这个时候机器挂了,你重启,从哪个offset开始呢?

 

三,mysql
1,mysql的主键为啥推荐使用自增Id,不推荐使用uuid做主键?
自增ID保证索引顺序性,uuid的话没规律,会产生页读取随机io,回复华山弟子:非自增ID会导致插入为了保证有序频繁进行页分裂调整,
你直接回答他B+tree的构建就好了,首先b+tree每个节点都有度,如果是uuid,涉及多个节点,可能频繁的构建分裂b+tree,然后可能会频繁读多个页,有序的话可能只要读一个页。

2,mvcc是如何实现的?undolog何时删除?一个事务结束后当前的undo会被立即删除吗?谈谈快照读和当前读吧?快照读是开启事务立即开始吗?

mvcc是每一行数据包含了上次提交的事务ID和回退指针,事务提交时候比较当前版本号和之前版本号是否相同,不相同也根据回退指针回滚
undolog在事务提交后,放入清理链表中,清理线程判断是否有其他事务要访问重做日志表上一个事务版本信息,没有则可以执行删除
快照读是简单select语句,读取是快照,因此可能有幻读,通过mvcc实现,当前读是通过间隙锁实现,读取是最新数据,修改数据行操作会被阻塞,快照生成时机是执行事务第一条select语句的时候

4,复合索引为什么是最左匹配原则
索引组织顺序按字段从左到右字段排序,先按第一个排序,再按第二个

 

四,redis

redis,单线程,epoll,cluster,sentinel,gossip,raft,分布式锁,穿透,击穿,雪崩,数据一致性,sds,ziplist,skiplist,rehash,hyperloglog,热key,大key,过期清理,淘汰策略,主从复制,rdb,aof,aof rewrite,持久化,集群方式

redis为什么存取那么快:并不是因为数据存在内存中,而是数据的存储格式适合内存操作

求问,一个面试题:给你十万个redis操作,如何快速的执行完,且redis不卡顿,性能最好?

首先你十万个请求,redis肯定不会卡的。简单操作1-2s就全执行完了。我觉得主要问题是你的client怎么能快速把10万个请求全部发送过去。分100个pipeline每个pipeline1000个操作,然后100个线程并发,网络延迟不高的话基本上2s肯定处理完了

3,大家一般都是这么操作redis的对吧。那请问redis再高的并发数有啥用?瓶颈在Tomcat啊。redis号称单机10w并发,我们打个折5w。Tomcat算他一个300并发,那要160多个Tomcat才能跑满redis的性能?

你这是两个问号,大多数都在回答第一个,redis高并发就是来解决数据库瓶颈。第二个问题,有了redis之后,瓶颈转移了,假如单次redis请求1ms,tomcat接口100ms,一个接口2次redis调用,10万qps并发就是100,也就是100×100每100ms,单次接口再2次调用,所以再除2,所以5000每100ms,按你说的tomcat300并发,就是300每100ms,tomcat的个数:5000÷300=16.7个,怎么跟楼主的差10倍

qps和同时并发两个概念。300请求池的tomcat同时并发打满算300的话,命中redis的请求算20ms,那么理论上qps单机就到15000了,去掉线程切换性能损耗也能打到10000

4.腾讯pcg面试java八股文,redis缓存雪崩怎么办?我说上线前预热,不同key在固有过期时间后加一个随机过期时间,然后问我还有啥办法,我不知道了,还有啥办法呢?
* 
布隆过滤器啊,多级缓存啊,随机值啊,缓存预热啊,返回一个空值啊,都可以

5,redis集群,codis,redis-cluster
上一篇搭建了一主二从,并加入了哨兵,任何一个节点挂掉都不影响正常使用,实现了高可用。仍然存在一个问题,一主二从每个节点都存储着全部数据,随着业务庞大,数据量会超过节点容量,即便是redis可以配置清理策略,但也有极限,于是需要搭建redis集群,将数据分别存储到不同的redis上,并且可以横向扩展。
本节搭建三主三从,即三组一主一从。组内是主从关系,可以实现高可用;组间是集群关系,实现分工存储。

社区版redis cluster是一个P2P无中心节点的集群架构,依靠gossip协议传播协同自动化修复集群的状态。

redis-cluster原理:

重点参考,较全面:https://www.zhihu.com/question/354518943

https://www.cnblogs.com/mengchunchen/p/10059436.html

https://blog.csdn.net/yejingtao703/article/details/78484151

https://blog.csdn.net/yejingtao703/article/details/78484151

对于Redis集群节点数量为什么要是奇数个?

1、防止由脑裂造成的集群不可用(集群可用原则:可用节点数量 > 总节点数量/2)。对一个偶数折半必然会出现两个数相等(可用节点数量 = 总节点数量/2)。

redis与raft:

redis在3.0.0版本开始支持集群功能,但是实现集群就要求redis能够承受单点故障,保证redis的高可用性,在各种软件和硬件的故障情况下仍然能够提供服务。一般来说有两种解决思路,一种是每一个节点互相之间都会进行数据交互以及监控,出现故障的时候,各个节点都可以做协调任务,比如kv分布式存储cassendra。另一种就是增加一个协调组件来对集群进行实时监控以及故障处理,比如zookeeper,chubby等。现在使用比较广泛的是第二种方案,各个模块之间低耦合,工程师能够专注于自己本身的代码逻辑而不需要考虑太多方面,工程实现也比较简单(相对第一种而言)。

     说到分布式协调组件,就不能不说下分布式一致性协议。从集中式变到分布式,虽然解决了单个主机宕机带来的服务不可用的问题,但是随之带来的就是分布式的各个节点一致性的问题。在分布式系统的一致性协议方面,paxos一直是标准级别的存在,但是由于paxos在工程实现上的困难,很少有人直接使用paxos协议来实现分布式中的协调组件。所以就有人提出了raft协议。和大名鼎鼎的paxos算法不一样,raft比较通俗易懂,在很多关键的地方甚至给出了伪代码。sentinel使用的就是raft协议,raft在redis内并没有用来实现一些分布式锁以及分布式事务,仅仅是用来做master宕机时的选主,可能后续的版本会逐渐支持。在redis内部有一个哨兵(sentinel)监测master和slave的状态,当有一个master节点宕机的时候,sentinel就会在剩下的slave中选择一个合适的节点作为master。这里有一个网址,非常浅显易懂的介绍了raft协议,希望大家看完后都能明白raft协议的精髓。

Redis Sentinel 并不是直接使用Raft选出master node, 而是使用Raft选出master sentinel 然后再由该master sentinel主导操作选出master node并进行故障转移以及对下线的node进行监控等操作。

五,java
Java面试是真的恶心,要问netty,zookeeper,springboot,dubbo各种源码,要问mysql binlog redolog 各种锁 主从复制 索引优化 要问redis击穿穿透雪崩各种数据结构 要问es mq的原理和实现 简历上写了就要问源码问原理 /react-text

1.java io

Java IO 是一套Java用来读写数据(输入和输出)的API。大部分程序都要处理一些输入,并由输入产生一些输出。Java为此提供了java.io包

java中io系统可以分为Bio,Nio,Aio三种io模型

  1. 关于Bio,我们需要知道什么是同步阻塞IO模型,Bio操作的对象:流,以及如何使用Bio进行网络编程,使用Bio进行网络编程的问题
  2. 关于Nio,我们需要知道什么是同步非阻塞IO模型,什么是多路复用Io模型,以及Nio中的Buffer,Channel,Selector的概念,以及如何使用Nio进行网络编程
  3. 关于Aio,我们需要知道什么是异步非阻塞IO模型,Aio可以使用几种方式实现异步操作,以及如何使用Aio进行网络编程

bio:

在Linux中,当应用进程调用recvfrom方法调用数据的时候,如果内核没有把数据准备好不会立刻返回,而是会经历等待数据准备就绪,数据从内核复制到用户空间之后再返回,这期间应用进程一直阻塞直到返回,所以被称为阻塞IO模型。

在这种模式中我们通常用一个线程去接受请求,然后用一个线程池去处理请求,用这种方式并发管理多个Socket客户端连接,像这样:

 

使用BIO模型进行网络编程的问题在于缺乏弹性伸缩能力,客户端并发访问数量和服务器线程数量是1:1的关系,而且平时由于阻塞会有大量的线程处于等待状态,等待输入或者输出数据就绪,造成资源浪费,在面对大量并发的情况下,如果不使用线程池直接new线程的话,就会大致线程膨胀,系统性能下降,有可能导致堆栈的内存溢出,而且频繁的创建销毁线程,更浪费资源。

nio:

JDK中NIO使用多路复用的IO模型,通过把多个IO阻塞复用到一个select的阻塞上,实现系统在单线程中可以同时处理多个客户端请求,节省系统开销,在JDK1.4和1.5 update10版本之前,JDK的Selector基于select/poll模型实现,在JDK 1.5 update10以上的版本,底层使用epoll代替了select/poll

epoll较select/poll的优点在于:

  1. epoll支持打开的文件描述符数量不在受限制,select/poll可以打开的文件描述符数量有限
  2. select/poll使用轮询方式遍历整个文件描述符的集合,epoll基于每个文件描述符的callback函数回调

select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写

aio:

aio模型 网络编程

异步操作

aio不需要通过多路复用器对注册的通道进行轮询操作就可以实现异步读写,从而简化了NIO的编程模型

aio通过异步通道实现异步操作,异步通道提供了两种方式获取操作结果:

  1. 通过Future类来获取异步操作的结果,不过要注意的是future.get()是阻塞方法,会阻塞线程
  2. 通过回调的方式进行异步,通过传入一个CompletionHandler的实现类进行回调,CompletionHandler定义了两个方法,completed和failed两方法分别对应成功和失败

Aio中的Channel都支持以上两种方式。

2,io多路复用:

IO多路复用:I/O是指网络I/O,多路指多个TCP连接(即socket或者channel),复用指复用一个或几个线程。意思说一个或一组线程处理多个TCP连接。最大优势是减少系统开销小,不必创建过多的进程/线程,也不必维护这些进程/线程。
  IO多路复用使用两个系统调用(select/poll/epoll和recvfrom),blocking IO只调用了recvfrom;select/poll/epoll 核心是可以同时处理多个connection,而不是更快,所以连接数不高的话,性能不一定比多线程+阻塞IO好,多路复用模型中,每一个socket,设置为non-blocking,阻塞是被select这个函数block,而不是被socket阻塞的。

select机制
基本原理:
  客户端操作服务器时就会产生这三种文件描述符(简称fd):writefds(写)、readfds(读)、和exceptfds(异常)。select会阻塞住监视3类文件描述符,等有数据、可读、可写、出异常 或超时、就会返回;返回后通过遍历fdset整个数组来找到就绪的描述符fd,然后进行对应的IO操作。
优点:
  几乎在所有的平台上支持,跨平台支持性好
缺点:
  由于是采用轮询方式全盘扫描,会随着文件描述符FD数量增多而性能下降。
  每次调用 select(),需要把 fd 集合从用户态拷贝到内核态,并进行遍历(消息传递都是从内核到用户空间)
  默认单个进程打开的FD有限制是1024个,可修改宏定义,但是效率仍然慢。

poll机制:
  基本原理与select一致,也是轮询+遍历;唯一的区别就是poll没有最大文件描述符限制(使用链表的方式存储fd)。
epoll机制:
基本原理:
  没有fd个数限制,用户态拷贝到内核态只需要一次,使用时间通知机制来触发。通过epoll_ctl注册fd,一旦fd就绪就会通过callback回调机制来激活对应fd,进行相关的io操作。
epoll之所以高性能是得益于它的三个函数
  1)epoll_create()系统启动时,在Linux内核里面申请一个B+树结构文件系统,返回epoll对象,也是一个fd
  2)epoll_ctl() 每新建一个连接,都通过该函数操作epoll对象,在这个对象里面修改添加删除对应的链接fd, 绑定一个callback函数
  3)epoll_wait() 轮训所有的callback集合,并完成对应的IO操作
优点:
  没fd这个限制,所支持的FD上限是操作系统的最大文件句柄数,1G内存大概支持10万个句柄
  效率提高,使用回调通知而不是轮询的方式,不会随着FD数目的增加效率下降
  内核和用户空间mmap同一块内存实现(mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间)

例子:100万个连接,里面有1万个连接是活跃,我们可以对比 select、poll、epoll 的性能表现
  select:不修改宏定义默认是1024,l则需要100w/1024=977个进程才可以支持 100万连接,会使得CPU性能特别的差。
  poll:    没有最大文件描述符限制,100万个链接则需要100w个fd,遍历都响应不过来了,还有空间的拷贝消耗大量的资源。
  epoll:    请求进来时就创建fd并绑定一个callback,主需要遍历1w个活跃连接的callback即可,即高效又不用内存拷贝。

六,http/tcp

我们平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。 实际上,Socket跟TCP/IP协议没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现 只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口,比如create、 listen、connect、accept、send、read和write等等。

实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口。socket是对端口通信开发的工具,它要更底层一些.

很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

好文讲解tcp:https://www.cnblogs.com/xiaolincoding/p/12732052.html

好文讲http:https://www.cnblogs.com/xiaolincoding/p/12442435.html

 

七,设计模式

1,单例模式;这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。

2,工厂模式;它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

3,观察者模式:

  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。

  这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。

4,策略模式:

属于行为型模型,是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

2.策略模式包含的角色及其职责:

(1)抽象策略角色[Strategy]:策略类,定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,
Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
(2)具体策略类[ConcreteStrategy]:实现了Strategy定义的接口,包装了相关的算法和行为,提供具体的算法实现。
(3)上下文角色[Context]:持有一个策略类的引用,最终给客户端调用。
①需要使用ConcreteStrategy提供的算法。
②内部维护一个Strategy的实例。
③负责动态设置运行时Strategy具体的实现算法。
④负责跟Strategy之间的交互和数据传递。

简单来说就是,一个接口f,如果有三种实现a,b,c,选用哪种实现可直接传递三种实现类的对象,f = new a()、new b(),f.method()的具体执行方法就是传入对象的实现类中定义的具体方法,避免写那么多的if else;多态与向上转型

5,适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以相互合作。

适配器模式主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

类适配器模式,通过继承来实现适配器功能。

比如我有一个Micro USB手机充电器接口, 但是现在我想给我的Type-c插口的手机充电,怎么办?只能准备一个可以把Micro USB接口转换成Type-c接口的转换器。

接口适配器模式,通过抽象类来实现适配,这种适配稍别于上面所述的适配。

当一个接口定义了N多个方法,而现在只想使用其中的一个到几个方法,如果直接实现接口,那么要对所有的方法进行实现,哪怕仅仅是对不需要的方法进行置空也会导致这个类变得臃肿,调用也不方便,这时可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,而在抽象类中所有的方法都进行置空。在创建抽象类的继承类,只需要使用的那几个方法即可。

6,装饰器模式,装饰模式的设计理念主要是以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余)。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展完全是透明的(装饰模式的透明性要求客户端程序不应该将对象声明为具体构件类型或具体装饰类型,而应该全部声明为抽象构件类型),装饰模式的应用在java的I/O流中最为显著。

7,代理模式,proxy;

代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法

举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子

静态代理,动态代理,Cglib代理

参考:https://www.cnblogs.com/leeego-123/p/10995975.html

装饰器模式关注于在一个对象上动态地添加方法,而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例;当使用装饰器模式的时候,我们通常的做法是将原始对象作为一个参数传给装饰器的构造器。

8,责任链模式

责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。

https://www.jianshu.com/p/9f7d9775bdda

9,模板模式

跟策略模式比较像,

模板方法模式:定义 一系列算法, 子类延伸实现。着重点在于:子类去处理不同的方法实现。 看下面例子。

假如一个支付的抽象基类 都包含三个部分: 生成订单 ----》调用API发起支付-----------》处理订单,如微信支付和支付宝分别去继承这个基类,分别实现自己子类的方法,外层调用时使用多态调用具体子类的方法。

首先我们来看模板模式

通常来说模板模式都是由抽象类来定义一个算法,在算法实现的不同步骤上抽象方法由子类继承并提供具体实现,常见的就是不同步骤提供doXXX抽象方法留给子类实现。模板模式一般有两部分组成,即抽象模板和具体模板。

与策略模式的区别

策略模式则是以接口形式提供抽象接口。由具体实现类提供不同算法。策略模式一般由3部分组成

  • 一个Context持有所有策略实现类引用,提供给客户端运行
  • 一个策略接口提供
  • 具体的策略实现类

通过上面可以看到,策略模式和模板模式有一个最重要的区别,即模板模式一般只针对一套算法,注重对同一个算法的不同细节进行抽象提供不同的实现。而策略模式注重多套算法多套实现,在算法中间不应该有交集,因此算法和算法只间一般不会有冗余代码!因为不同算法只间的实现一般不同很相近。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值