装饰模式(Decorator Pattern)是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系。在装饰模式中引入了装饰类,在装饰类中既可以调用被装饰类的方法,还可以定义新的方法,以便扩充类的功能。装饰模式降低了系统的耦合度,可以动态增加或删除对象的职责,并使得需要装饰的具体构件类和具体装饰类可以独立变化,增加新的具体构件类和具体装饰类都非常方便,满足“开闭原则”的要求。也是对象结构型模式
之一。
补充继承与组合的区别
总结一下
变形金刚
作为一辆车,可以在陆地移动,可以变身成机器人说话,可以变身飞机再空中飞
抽象构件接口
public interface Transform {
void move();
}
具体构件
public final class Car implements Transform{
public Car() {
System.out.println("变形金刚是辆车!!!");
}
@Override
public void move() {
System.out.println("在陆地移动!!");
}
}
抽象装饰类
public class Changer implements Transform{
private Transform transform;
public Changer(Transform transform) {
this.transform = transform;
}
@Override
public void move() {
transform.move();
}
}
具体装饰类
public class Ariplane extends Changer{
public Ariplane(Transform transform) {
super(transform);
System.out.println("变成飞机!!!");
}
public void fly(){
System.out.println("在空中飞翔!!");
}
}
public class Robot extends Changer{
public Robot(Transform transform) {
super(transform);
System.out.println("变成机器人!!!");
}
public void say(){
System.out.println("说话!!");
}
}
客户测试类
public class Client {
public static void main(String[] args) {
Transform camaro;
camaro = new Car();
camaro.move();
System.out.println("---------------");
Robot bumblenee = new Robot(camaro);
bumblenee.move();
bumblenee.say();
}
}
……
Component component_o,component_d1,component_d2;
//全部使用抽象构件定义
component_o = new ConcreteComponent();
component_d1 = new ConcreteDecorator1(component_o);
component_d2 = new ConcreteDecorator2(component_d1);
component_d2.operation();
//无法单独调用component_d2的addedBehavior()方法
……
……
Component component_o; //使用抽象构件类型定义
component_o = new ConcreteComponent();
component_o.operation();
ConcreteDecorator component_d; //使用具体装饰类型定义
component_d = new ConcreteDecorator(component_o);
component_d.operation();
component_d.addedBehavior(); //单独调用新增业务方法
……
本文来自博客园,作者:街酒,转载请注明原文链接:http://www.cnblogs.com/sorrymine/p/17420525.html
查询优化: 1.showstatuslike‘slow_queries’;2.分析查询语句: explain/descselect语句mysql>explainselect*fromuser1; ±—±————±——±—–±————–±—–±——–±—–±—–±——+ |id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra| ±—±————±——±—–±————–±—–±——–±—–±—–±——+ |1|SIMPLE|user1|ALL|NULL|NULL|NULL|NULL|3|| ±—±————±——±—–±————–±—–±——–±—–±—–±——+ 1rowinset(0.00sec)idselect语句的id号 select_type:查询语句的类型 simple:简单的查询语句 primary:主查询,最外层查询 union:连接查询 subquery:子查询type:表示查询读取数据的方式; const:表示只有一行数据匹配 system:该表时仅有一行数据的系统表; eq_ref:使用
作者:韩信子@ShowMeAI教程地址:http://www.showmeai.tech/tutorials/37本文地址:http://www.showmeai.tech/article-detail/266声明:版权所有,转载请联系平台与作者并注明出处收藏ShowMeAI查看更多精彩内容TrainingNeuralNetworks;深度学习与计算机视觉;StanfordCS231n本系列为斯坦福CS231n《深度学习与计算机视觉(DeepLearningforComputerVision)》的全套学习笔记,对应的课程视频可以在这里查看。引言ShowMeAI在上一篇深度学习与CV教程(6)|神经网络训练技巧(上)介绍了激活函数选择,sigmoid和tanh都有饱和的问题;权重初始化不能太小也不能太大,最好使用Xavier初始化;数据预处理使用减去均值和归一化,线性分类中这两个操作会使分界线不那么敏感,即使稍微转动也可以,神经网络中也对权重的轻微改变没那么敏感,易于优化;也可以使用批量归一化,将输入数据变成单位高斯分布,或者缩放平移;学习过程跟踪损失、准确率;超参数体调优范围由粗到细,
终于还是成功了,差点没放弃。由于之前在做一个异常处理的时候用到了邮件提醒功能,所以顺便研究了一下在php下如何发送邮件。第一次摸索,折腾了整整一天,最后还是成功了。现做个经历总结,方便大家交流,初次接触,如有不对的地方欢迎指出。那么如何在PHP环境下发送邮件呢,这里介绍一个比较常用的方法,就是使用函数是mail()。关于mail函数的使用方法大家可以查看官方手册:http://php.net/manual/zh/function.mail.php,这里我主要给大家介绍一下相关的服务器配置和sendmail搭建过程。准备:1、开发环境:WAMP(Windows+Apache+MySql+PHP),建议使用phpStudy集成环境。2、sendmail下载:下载地址:https://www.glob.com.au/sendmail/备用地址:http://pan.baidu.com/s/1eRC43aM(密码:6hci)3、准备好一个QQ邮箱为什么要使用QQ邮箱?这是我踩的一个坑,我一开始是用126邮箱和163邮箱来做测试的(126和163是一家的)。我按部就班地把一切都配置好了,但就是一
系统版本cat/etc/redhat-release CentOSLinuxrelease7.6.1810(Core)复制postgresql安装#安装postgresqlrpm yuminstallhttps://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm #安装postgresql客户端 yuminstallpostgresql10 #安装postgresql-server yuminstallpostgresql10-server #初始化数据库 /usr/pgsql-10/bin/postgresql-10-setupinitdb #启动并开机启动 systemctlstartpostgresql-10&&systemctlenablepostgresql-10复制postgresql配置#yum安装postgresql,默认会建一个名为”postgres”的数据库管理员账号和同名的系统用户,用于执行PostgreSQL;
郭一璞发自凹非寺 量子位报道|公众号QbitAI“说人话”越来越热了。先是GoogleI/O大会上一声“嗯哼”震惊了人类世界,然后微软小冰为知乎写歌唱歌又刷了一波屏。这一年来,AI语音的炫技方式,已经从机器“能听会说”,悄然变成了机器“像人类一样说话”,而且一切正在越来越6,越来越自然。但这并不轻而易举。不仅要有专门的训练数据集,还要有算法模型方面的技术实力,以及产品方案的打磨能力。在国内,司空见惯的是若琪、小爱同学、小雅的合成人声,或者也习惯了百度地图、滴滴App里的语音播报,但隐秘不闻的是背后同一家“供应商”——标贝科技。今年3月,国内AI语音领域大牛李秀林,正式以联合创始人及CTO身份,加入了标贝科技。百度2016年最高奖得主李秀林,中科院声学所博士,有10余年语音相关技术研发和相关的学术研究,专利数30多项,涉及文本处理、韵律预测、声学模型、拼接系统、模型自适应、神经网络、情感合成等多个关键领域。2013年,李秀林加盟百度,并成为百度语音合成技术负责人,在其后任职期间,率队成功打造了百度语音合成系统,因此在2016年折桂百度内部一年一度的百万美元最高奖,技术层级T9。但也是拿下
作者介绍:姜刚云和恩墨技术顾问2017年3月加入云和恩墨,熟悉shell、perl脚本等。为了加深对ORACLE数据库结构的了解,我们今天从C语言的角度,讲解如何使用C语言直接访问SGA。基于的事实:1、数据库启动后会分配共享内存(在ORACLE中称为SystemGlobalArea[SGA])2、数据库中X$开头的表都是内存映射表 3、在Linux/Unix下提供了C的Lib库可以访问共享内存(shmat,shmdt,shmget等)以GV$SESSION_WAIT为例查看GV$SEESSION_WAIT的定义通过上述创建视图信息,我们知道v$session_wait是建在X$KSUSECST和X$KSLED两个内存映射表上的,其访问路径是类似下图:共享内存结构 获取SGA起始地址语句如下:select‘0x’||addrfromX$KSMMEMwhererownum<2;X$KSUSECST在内存中的位置获取X$KSUSECST起始地址:Selectmin(addr)asBEGIN_ADDRfromX$KSUSECST获取在内存中的记录数:Selectcount(*)asRE
公共参数是用于标识用户和接口签名的参数,如非必要,在每个接口单独的接口文档中不再对这些参数进行说明,但每次请求均需要携带这些参数,才能正常发起请求。 公共参数的具体内容会因您使用的签名方法版本不同而有所差异。 使用签名方法v3的公共参数签名方法v3(有时也称作TC3-HMAC-SHA256)相比签名方法v1(有些文档可能会简称签名方法),更安全,支持更大的请求包,支持POSTJSON格式,性能有一定提升,推荐使用该签名方法计算签名。完整介绍详见签名方法v3。 注意:接口文档中的示例由于目的是展示接口参数用法,简化起见,使用的是签名方法v1GET请求,如果依旧想使用签名方法v1请参考下文章节。 使用签名方法v3时,公共参数需要统一放到HTTPHeader请求头部中,如下表所示: 参数名称 类型 必选 描述 Action String 是 HTTP请求头:X-TC-Action。操作的接口名称。取值参考接口文档中输入参数公共参数Action的说明。例如云服务器的查询实例列表接口,取值为DescribeInstances。 Region String - HTTP请求头:X-
大家好,我是华仔,又跟大家见面了。 上一篇作为专题系列的第二篇,从演进的角度带你深度剖析了关于Kafka请求处理全流程以及超高并发的网络架构设计的实现细节,今天开启第三篇,我们来聊聊Kafka生产环境大家都比较关心的问题。 那么Kafka到底会不会丢数据呢?如果丢数据,究竟该怎么解决呢? 只有掌握了这些,我们才能处理好Kafka生产级的一些故障,从而更稳定地服务业务。 认真读完这篇文章,我相信你会对Kafka如何解决丢数据问题,有更加深刻的理解。 这篇文章干货很多,希望你可以耐心读完。 01总体概述 越来越多的互联网公司使用消息队列来支撑自己的核心业务。由于是核心业务,一般都会要求消息传递过程中最大限度的做到不丢失,如果中间环节出现数据丢失,就会引来用户的投诉,年底绩效就要背锅了。 那么使用Kafka到底会不会丢数据呢?如果丢数据了该怎么解决呢?为了避免类似情况发生,除了要做好补偿措施,我们更应该在系统设计的时候充分考虑系统中的各种异常情况,从而设计出一个稳定可靠的消息系统。 大家都知道Kafka的整个架构非常简洁,是分布式的架构,主要由Producer、Broker、C
本指导会详尽阐述Ember.js视图层的细节。为想成为熟练Ember开发者准备,且包含了对于入门Ember不必要的细节。 Ember.js有一套复杂的用于创建、管理并渲染连接到浏览器DOM上的层级视图的系统。视图负责响应诸如点击、拖拽以及滚动等的用户事件,也在视图底层数据变更时更新DOM的内容。 视图层级通常由求值一个Handlebars模板创建。当模板求值后,会添加子视图。当那些子视图求值后,会添加它们的子视图,如此递推,直到整个层级被创建。 即使你并没有在Handlebars模板中显式地创建子视图,Ember.js内部仍使用视图系统更新绑定的值。例如,每个Handlebars表达式{{value}}幕后创建一个视图,这个视图知道当值变更时如何更新绑定值。 你也可以在应用运行时用Ember.ContainerView类对视图层级做出修改。一个容器视图暴露一个可以手动修改的子视图实例数组,而非模板驱动。 视图和模板串联工作提供一套用于创建任何你梦寐以求的用户界面的稳健系统。最终用户应从诸如当渲染和事件传播是的计时事件之类的复杂东西中隔离开。应用开发者应可以一次性把他们的UI描述成Han
在茫茫的互联网海洋中,要找到一台计算机非常不容易,有三个要素必须具备,它们分别是 IP地址、MAC地址和端口号。 IP地址 IP地址是 InternetProtocolAddress的缩写,译为“网际协议地址”。目前大部分软件使用IPv4地址,但IPv6也正在被人们接受,尤其是在教育网中,已经大量使用。一台计算机可以拥有一个独立的IP地址,一个局域网也可以拥有一个独立的IP地址(对外就好像只有一台计算机)。对于目前广泛使用IPv4地址,它的资源是非常有限的,一台计算机一个IP地址是不现实的,往往是一个局域网才拥有一个IP地址。在因特网上进行通信时,必须要知道对方的IP地址。实际上数据包中已经附带了IP地址,把数据包发送给路由器以后,路由器会根据IP地址找到对方的地里位置,完成一次数据的传递。路由器有非常高效和智能的算法,很快就会找到目标计算机。 MAC地址 现实的情况是,一个局域网往往才能拥有一个独立的IP;换句话说,IP地址只能定位到一个局域网,无法定位到具体的一台计算机。这可怎么办呀?这样也没法通信啊。其实,真正能唯一标识一台计算机的是MAC地址,每个网卡的M
“different,butnotless.不同,但也不差!” 前记 出现内存错误,查问题是一方面,更多的是需要考虑,以后写代码如何不出现内存错误。总结很关键。 《Linux多线程服务端编程使用muduo网络库》这本书说的是RAII技术(后期研究下,做一些实践)。 自己的总结:new出的内存,不进行类之间的长途传递,若出现这种情况,需要思考下是否真的有必要如此。比如,自己看到的一种比较难受的管理方式:在调用中,new出一个对象A传递指针到另外一个对象B中,并且,最后在对象B析构函数中去释放了A。这种情况,我现在认为的解决办法是传递必要参数到对象B中去new,并且在对象B中的析构中去释放。便于管理。 一、简介 最近在查程序的内存泄漏问题,是在tcmalloc内存分配的基础上,关于tcmalloc是介绍:主要参见两篇博文: (1) 官方文档介绍,主要介绍原理和为什么tcmalloc比glic的快:tcmalloc &nbs
题目:这里 题意:一条数轴上,有n个城市和m个塔,分别给出城市的位置和塔的位置,每个塔有个覆盖范围,问能将所有城市都覆盖的塔的最小范围是多少,一个城市只要被至少一个塔 覆盖就行。 可以利用贪心的思想模拟一下,注意一下细节就行,也可以二分。 1#include<cstdio> 2#include<cstring> 3#include<iostream> 4#include<algorithm> 5#include<map> 6usingnamespacestd; 7 8typedeflonglongll; 9constintM=1e5+10; 10inta[M],b[M]; 11llmax(llx,lly){returnx>y?x:y;} 12 13intmain() 14{ 15intn,m; 16scanf("%d%d",&n,&m); 17for(inti=1;i<=n;i++)scanf("%d",&a[i]); 18for(inti=1;i<=m;
工欲善其事必先利其器,我们既然有VisualStudio2019这样的IDE为什么不用?学.NetCore而不用VisualStudio进行开发可谓是多么另类呀!既然你已经安装了VS2019的话我们就来创建一个MVCWeb吧,如果你还不会安装,可以看我之前发表的安装教程,很简单哦。之前讲了命令创建.netcore3.0web应用,那么VisualStudio2019创建一个MVCWeb应用也如约而来了! 1.点击VisualStudio2019后选择创建新项目 2.选择并直接创建Asp.NetCoreWeb应用程序 3.创建一个名称为Hello的网站项目,解决方案名称自动就有了也是Hello 4.创建一个有模板的项目吧,选择.NetCore->选择3.0框架->Web应用程序(不进行身份验证,Https和启用docker都不勾)->创建 5.之后解决方案右键->添加->新建项目 6.选择类库项目后执行下一步 7.创建一个名称为Common的通用类库
Storm入门教程 1.Storm基础 Storm Storm主要特点 Storm基本概念 Topologies Streams Spouts Bolts Streamgroupings Reliability Tasks Workers Storm调度器 Storm配置 GuaranteeingMessageProcessing(消息处理保障机制) DaemonFaultTolerance(守护线程容错机制) 理解Storm拓扑的并行 Tutorial Local模式 在生产环境中运行Topologies Storm基本概念 Storm中的基本概念包括Topologies、Streams、Spouts、Bolts、Streamgroupings、Reliability、Tasks、Workers。 Topologies Storm中的一个topology代表一个实时应用程序的逻辑处理。Storm的Topology类似与MapReduce的Job。关键的差异是MapReduce的Job最后是要结束的,而Topology是持续运行的,除非你手动停掉。一个Topology就是一个用
使用Composer为ThinkPHP(3.2.3)框架添加和管理组件 环境:Windows1064位 PHP版本:5.5.12 框架:ThinkPHP3.2.3复制 Tips: 组件:打包的代码,可以是一系列相关的类(class)、接口(interface)、特性(trait),用于解决某个具体的问题。组件中的类、接口、特性通常放在同一个命名空间中。 Packagist:https://packagist.org/,该网站收集PHP组件,可以在上面查找项目中需要的组件。ThinkPHP在该站的地址为:https://packagist.org/packages/topthink/thinkphp Composer:Composer是PHP组件的依赖管理器,在命令行中运行,通过运行命令可以下载组件(以及组件的依赖)并且把组件(以及组件的依赖)自动加载到项目中。 安装Composer Composer官网地址:https://getcomposer.org/,中文镜像地址:http://www.phpcomposer.co
对象的新增方法 Object.assign() Object.is() Object.getOwnPropertyDescriptors() Object.fromEntries() 遍历方法: 一、Object.keys()返回键名数组 二、Object.values()返回键值数组 三、Object.entries()返回键值对数组 JavaScript语言的对象继承是通过原型链实现的。ES6提供了更多原型对象的操作方法: 一、__proto__属性 二、Object.setPrototypeOf() 三、Object.getPrototypeOf() Object.assign() 等同于对象扩展运算符(...),将源对象中的所有可枚举属性复制到目标对象中。只拷贝自身可枚举的属性。 属性名为Symbol值的属性,也会被Object.assign()拷贝。 只有一个参数,会直接返回该参数。如果参数不是对象,则会转成对象后再返回。 如果undefined和null作为首参数,会报错,因为无法将其转为对象。若不在首参数,则不报错。 如果源参数是字符串,会将字符串以数组形式拷贝到目标对象
如果我们要导入的模块在不同的包中,该如何导入呢? 可以用 from 包名 import 模块名 或者 from 包名.模块名 import 模块中的代码(如变量、函数、方法等) 方式一:导入整个模块,即 from 包名 import 模块名 如下图结构,有package01包(test.py在其中)和package02包(login.py在其中): login.py模块分别如下: test.py模块如下: 我们可以看到,from包名import模块名的方式,可以导入包中的一个模块,要调用该模块中的代码时,需要用该模块 的模块名称来调用。 运行结果如下:我们可以看到,login.py中的代码被正确调用了 问题:用模块名来调用,是不是会显得有些繁琐?接着看第二种方式方式二:导入模块中的某些部分,可以用 from&n