字面量,常量和变量

“字面量,常量和变量” int a; //变量 const int b = 10; //b 为常量(具名常量, named constants), 10 为字面量 string str = "hello world!"; // str 为变量, hello world!为字面量 看完这个例子,我相信大家都会说,啊,可不就是这样吗?这其中可能稍微有点不太理解的就是字面量。像_常量_啊,_变量_啊, 字面量 在计算机科学中,字面量 (literal) 是用于表达源代码中一个固定值的表示法 (notation) 。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如: 整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等复合类型的值也支持字面量表示法。 有个不太好,但是足以说明问题的解释,那就是 对象字面量就是引号引起来的部分,必须是等号右边的部分。虽然这样的解释不太好,但是确实如此,这就是字面量。 const int b = 10; //b为常量,10为字面量 string str = "hello world!"; // str 为变量,hello world!为字面量 变量 有些数据在程序运行中可以变化或者被赋值,这称为变量。 int a; //变量 常量, 具名常量 有些数据可以在程序使用之前预先设定并在整个运行过程中没有变化,这称为常量。 const int b = 10; //b 为常量, 10 为字面量 foo = func_0(b, 11) // func_0有两个参数一个传的是具名常量 b, 一个是常量 11 变量与常量的区别 它们在内存中的存储方式是一样的。只是常量不允许改变,就像只读文件一样。 变量、常量与字面量的区别 字面量是指由字母,数字等构成的字符串或者数值,它只能作为右值出现,(右值是指等号右边的值,如: int a=123这里的a为左值,123为右值。) 常量和变量都属于变量,只不过常量是赋过值后不能再改变的变量,而普通的变量可以再进行赋值操作。 作者: 贺贺v5 链接: https://www.jianshu.com/p/0f2816805da6 来源: 简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1 min · 90 words · -

实体和值对象, entity, value object

实体和值对象, entity, value object 实体和值对象 实体和值对象放在一起讲容易区分,概括而言,实体不仅需要知道它是什么?而且还需要知道它是哪个?而值对象只需要知道它是什么?先看定义: 实体 许多对象不是由它们的属性来定义,而是通过一系列的连续性(continuity)和标识(identity)来从根本上定义的。只要一个对象在生命周期中能够保持连续性,并且独立于它的属性(即使这些属性对系统用户非常重要),那它就是一个实体。 值对象:当你只关心某个对象的属性时,该对象便可作为一个值对象。为其添加有意义的属性,并赋予它相应的行为。我们需要将值对象看成不变对象,不要给它任何身份标识,还应该尽量避免像实体对象一样的复杂性。 对于实体Entity,实体核心是用唯一的标识符来定义,而不是通过属性来定义。即即使属性完全相同也可能是两个不同的对象。同时实体本身有状态的,实体又演进的生命周期,实体本身会体现出相关的业务行为,业务行为会实体属性或状态造成影响和改变。 如果从值对象本身无状态,不可变,并且不分配具体的标识层面来看。那么值对象可以仅仅理解为实际的Entity对象的一个属性结合而已。该值对象附属在一个实际的实体对象上面。值对象本身不存在一个独立的生命周期,也一般不会产生独立的行为。 初看还是很难理解,举几个例子: 案例分析 营业厅会卖手机以及很多手机配件,在客户业务规则中,往往每一部手机都要单独管理,通过手机的SN号来识别。而手机配件是一种数量类型的实物,只关心其数量的变化,并不关心到每一个具体的手机配件。这种场景就是典型的实体和对象的案例。 地址是实体还是值对象。在电力公司服务软件中,一个地址对应于公司线路和服务的目的地。如果多个住所都申请了电力服务,那么这个公司需要知道这一点,因此地址是实体。我们也可以用另一种方法,在模型中将“住所”关联到运营服务,其中“住所”是一个包含地址属性的实体。此时,地址就是一个值对象。 体育场座位例子。当我们发放的门票上有座位号的时候,座位需要作为独立的实体,座位号是唯一的标识。而当先到先座模式下,我们只关心剩余座位数,那么座位号并不是唯一标识,这时候座位就可以作为一个值对象。这跟我们的业务需求有关。 消息场景中,发件人、收件人是实体?还是值对象?这个在 三个问题思考实体和值对象一文中有讨论。 值对象的常见例子包括数字,比如100和293.51;或者文本字符串,比如"hello world";或者日期时间;还有更加详细的对象,此如某人的全名,其中包含姓改、名字和头衔;再比如货币、颜色、电话号码和邮寄地址等。当然还有更加复杂的值对象。这种对象无状态,本身不产生行为,不存在生命周期演进。 值对象的目的和使用 实体对象相对容易理解,我们常见的类的都可以看成是实体对象。值对象在DDD中相对而言是难以理解并且容易误用的。 为什么需要使用值对象,书中给了一个解释: 使用不变的值对象使得我们做更少的职责假设 个人理解这个还是基于BC的封闭性而言的,使用值对象在不同的BC中进行数据交换,可以避免不同BC对实体对象的状态变更而引发的数据依赖关系,实现最小化的集成。另外可以从目前流行的Stateless Service角度考虑值对象的价值。 开发者因为习惯趋向于将关注点放在数据而不是领域上。在软件开发中,数据库依然占据着主导地位。我们首先考虑的是数据的属性(对应数据库的列)和关联关系(外键关联),而不是富有行为的领域概念。这样做的结果是将数据模型直接反映在对象模型上,导致产生贫血型的领域模型的实体。虽然在实体模型中加入getter和setter并不是什么大错,但这却不是DDD的做法。 值类型用于度量和描述事物,DDD 中建议应尽量使用值对象来建模而不是实体对象,因为值对象非常容易地对值对象进行创建、测试、使用、优化和维护。 关于值对象,它拥有以下一些特征: 它度量或者描述了领城中的一件东西。 它可以作为不变量。 它将不同的相关的属性组合成一个概念整体(Conceptual Whole) 当度量和描述改变时,可以用另一个值对象予以替换。 它可以和其他值对象进行相等性比较。 它不会对协作对象造成副作用 一个对象的方法可以设计成一个无副作用函数(Side-Effect-Free Function) 。这里的函数表示对某个对象的操作,它只用于产生输出, 而不会修改对象的状态。由于在函数执行的过程中没有状态改变,这样的函数操作也称为无副作用函数。对于不变的值对象而言,所有的方法都必须是无副作用函数,因为它们不能破坏值对象的不变性。 最小化集成 在所有的DDD项目中,通常存在多个限界上下文,这意味着我们需要找到合适的方法对这些上下文进行集成。当模型概念从上游上下文流入下游上下文中时, 尽量使用值对象来表示这些概念。这样的好处是可以达到最小化集成,即可以最小化下游模型中用于管理职责的属性数目。使用不变的值对象使得我们做更少的职责假设。 https://www.cnblogs.com/ttaylor/p/15927009.html DDD 领域驱动设计-三个问题思考实体和值对象 消息场景:用户 A 发送一个消息给用户 B,用户 B 回复一个消息给用户 A。。。 现有设计:消息设计为实体并为聚合根,发件人、收件人设计为值对象。 三个问题: 实体最重要的特性是什么? Message 实体是怎么得来的? 发件人、收件人为什么不是实体? 实体最重要的特性是什么? 《领域驱动设计》5.2 实体: 摘录一段:许多对象不是由它们的属性来定义,而是通过一系列的连续性(continuity)和标识(identity)来从根本上定义的。 归纳: 标识(identity) 连续性(continuity) 标识在实体中的另一种体现就是唯一和不可变,其概念在很多资料中有说明,这也是实体最重要的特性。 我有一个双胞胎哥哥,我们俩出生的时候,长得一模一样,以至于我们的爸妈都分不清,不得已他们在我们脖子上系个项链来标记:谁是老大?谁是老二?其实这个“标记”就可以看作是实体的标识,只不过是用项链来标识的,就像我们在项目中使用 GUID 方式一样,目的就是用来体现标识,但不管用什么方式表示,这个标识必须在这个特定环境下唯一,也就是说,我和我双胞胎哥哥的项链不能完全一样,要不然我爸妈就不能区分我们俩了。 ...

2 min · 238 words · -

宾语从句(Object Clause)

宾语从句(Object Clause) 在句子中起宾语作用的从句叫做宾语从句.宾语从句分为三类:动词的宾语从句,介词的宾语从句和形容词的宾语从句. 时态: 1.主句用一般现在时,从句可用任意时态。 2.主句用过去时,从句用过去某个时态。 3.主句用过去时,从句是真理时,只用一般现在时。 一、宾语从句的连接词 从属连词 连接宾语从句的从属连词主要有that,if,whether. that引导表示陈述句的宾语从句,而if和whether引导表示“是否”的宾语从句. He told me that he would go to the college the next year 他告诉我他下一年上大学. I don’t know if there will be a bus any more. 我不知道是否还会有公交车. Nobody knew whether he could pass the exam. 没人知道他是否会通过考试. 连接代词 连接代词主要有who, whom ,whose ,what ,whoever ,whomever ,whosever, whatever, whichever等. 关系代词what引导 连接代词一般指疑问,但what, whatever除了指疑问外,也可以指陈述. Do you know who has won Red Alert game? 你知道谁赢了这一局红警游戏吗? I don’t know whom you should depend on. ...

7 min · 1344 words · -

服务器三大体系 SMP、NUMA、MPP

“服务器三大体系 SMP、NUMA、MPP” https://blog.csdn.net/ZhipingXi/article/details/78133096 服务器三大体系 SMP、NUMA、MPP zhipingxi 2017-09-29 13:50:15 2236 收藏 5 分类专栏: Operating System 文章标签: 服务器 系统架构 numa smp mpp 系统架构来看,目前的商用服务器大体可以分为三类 对称多处理器结构(SMP: Symmetric Multi-Processor); 非一致存储访问结构(NUMA: Non-Uniform Memory Access); 海量并行处理结构(MPP: Massive Parallel Processing); 共享存储型多处理机有两种模型 均匀存储器存取 (Uniform-Memory-Access,简称UMA) 模型 非均匀存储器存取 (Nonuniform-Memory-Access,简称NUMA) 模型 SMP(Symmetric Multi-Processor) 所谓对称多处理器结构,是指服务器中多个CPU对称工作,无主次或从属关系。各CPU共享相同的物理内存,每个 CPU访问内存中的任何地址所需时间是相同的,因此SMP也被称为一致存储器访问结构(UMA: Uniform Memory Access)。对SMP服务器进行扩展的方式包括增加内存、使用更快的CPU、增加CPU、扩充I/O(槽口数与总线数)以及添加更多的外部设备(通常是磁盘存储)。 SMP服务器的主要特征是共享,系统中所有资源(CPU、内存、I/O等)都是共享的。也正是由于这种特征,导致了SMP服务器的主要问题,那就是它的扩展能力非常有限。对于SMP服务器而言,每一个共享的环节都可能造成SMP服务器扩展时的瓶颈,而最受限制的则是内存。由于每个CPU必须通过相同的内存总线访问相同的内存资源,因此随着CPU数量的增加,内存访问冲突将迅速增加,最终会造成CPU资源的浪费,使 CPU性能的有效性大大降低。实验证明,SMP服务器CPU利用率最好的情况是2至4个CPU。 图1.SMP服务器CPU利用率状态 NUMA(Non-Uniform Memory Access) 由于SMP在扩展能力上的限制,人们开始探究如何进行有效地扩展从而构建大型系统的技术,NUMA就是这种努力下的结果之一。利用NUMA技术,可以把几十个CPU(甚至上百个CPU)组合在一个服务器内。其CPU模块结构如图2所示: 图2.NUMA服务器CPU模块结构 NUMA服务器的基本特征是具有多个CPU模块,每个CPU模块由多个CPU(如4个)组成,并且具有独立的本地内存、I/O槽口等。由于其节点之间可以通过互联模块(如称为Crossbar Switch)进行连接和信息交互,因此每个CPU可以访问整个系统的内存(这是NUMA系统与MPP系统的重要差别)。显然,访问本地内存的速度将远远高于访问远地内存(系统内其它节点的内存)的速度,这也是非一致存储访问NUMA的由来。由于这个特点,为了更好地发挥系统性能,开发应用程序时需要尽量减少不同CPU模块之间的信息交互。利用NUMA技术,可以较好地解决原来SMP系统的扩展问题,在一个物理服务器内可以支持上百个CPU。比较典型的NUMA服务器的例子包括HP的Superdome、SUN15K、IBMp690等。 但NUMA技术同样有一定缺陷,由于访问远地内存的延时远远超过本地内存,因此当CPU数量增加时,系统性能无法线性增加。如HP公司发布Superdome服务器时,曾公布了它与HP其它UNIX服务器的相对性能值,结果发现,64路CPU的Superdome (NUMA结构)的相对性能值是20,而8路N4000(共享的SMP结构)的相对性能值是6.3。从这个结果可以看到,8倍数量的CPU换来的只是3倍性能的提升。 MPP(Massive Parallel Processing) 和NUMA不同,MPP提供了另外一种进行系统扩展的方式,它由多个SMP服务器通过一定的节点互联网络进行连接,协同工作,完成相同的任务,从用户的角度来看是一个服务器系统。其基本特征是由多个SMP服务器(每个SMP服务器称节点)通过节点互联网络连接而成,每个节点只访问自己的本地资源(内存、存储等),是一种完全无共享(Share Nothing)结构,因而扩展能力最好,理论上其扩展无限制,目前的技术可实现512个节点互联,数千个CPU。目前业界对节点互联网络暂无标准,如 NCR的Bynet,IBM的SPSwitch,它们都采用了不同的内部实现机制。但节点互联网仅供MPP服务器内部使用,对用户而言是透明的。 在MPP系统中,每个SMP节点也可以运行自己的操作系统、数据库等。但和NUMA不同的是,它不存在异地内存访问的问题。换言之,每个节点内的CPU不能访问另一个节点的内存。节点之间的信息交互是通过节点互联网络实现的,这个过程一般称为数据重分配(Data Redistribution)。 但是MPP服务器需要一种复杂的机制来调度和平衡各个节点的负载和并行处理过程。目前一些基于MPP技术的服务器往往通过系统级软件(如数据库)来屏蔽这种复杂性。举例来说,NCR的Teradata就是基于MPP技术的一个关系数据库软件,基于此数据库来开发应用时,不管后台服务器由多少个节点组成,开发人员所面对的都是同一个数据库系统,而不需要考虑如何调度其中某几个节点的负载。 NUMA与MPP的区别 ...

2 min · 219 words · -

炼妖壶

“炼妖壶” https://zhuanlan.zhihu.com/p/50584002

1 min · 2 words · -

相互转换逗号分隔的字符串和List

“相互转换逗号分隔的字符串和List” https://blog.csdn.net/yywusuoweile/article/details/50315377 将逗号分隔的字符串转换为List 方法 1: 利用JDK的Arrays类 String str = “a,b,c”; List result = Arrays.asList(str.split(",")); 方法 2: 利用Guava的Splitter String str = “a, b, c”; List result = Splitter.on(",").trimResults().splitToList(str); 方法 3: 利用Apache Commons的StringUtils (只是用了split) String str = “a,b,c”; List result = Arrays.asList(StringUtils.split(str,",")); 方法 4: 利用Spring Framework的StringUtils String str = “a,b,c”; List str = Arrays.asList(StringUtils.commaDelimitedListToStringArray(str)); 将List转换为逗号分隔符 方法 1: 利用JDK (好像没有很好的方法,需要一步一步实现) ...

1 min · 108 words · -

线程模型

“线程模型” 多线程模型: 一对一模型、多对一模型和多对多模型 迄今为止,我们只是泛泛地讨论了线程。不过,有两种不同方法来提供线程支持: 用户层的用户线程或内核层的内核线程。 用户线程位于内核之上,它的管理无需内核支持;而内核线程由操作系统来直接支持与管理。几乎所有的现代操作系统,包括 Windows、Linux、Mac OS X 和 Solaris,都支持内核线程。 最终,用户线程和内核线程之间必然存在某种关系。本节研究三种常用的建立这种关系的方法: 多对一模型、一对一模型和多对多模型。 多对一模型 多对一模型 多对一模型 (图 1) 映射多个用户级线程到一个内核线程。 线程管理是由用户空间的线程库来完成的,因此效率更高。不过,如果一个线程执行阻塞系统调用,那么整个进程将会阻塞。再者,因为任一时间只有一个线程可以访问内核,所以多个线程不能并行运行在多处理核系统上。 Green threads 线程库为 Solaris 所采用,也为早期版本的 Java 所采纳,它就使用了多对一模型。然而,现在几乎没有系统继续使用这个模型,因为它无法利用多个处理核。 一对一模型 一对一模型 图 2 一对一模型 一对一模型 (图 2) 映射每个用户线程到一个内核线程。 该模型在一个线程执行阻塞系统调用时,能够允许另一个线程继续执行,所以它提供了比多对一模型更好的并发功能;它也允许多个线程并行运行在多处理器系统上。 这种模型的唯一缺点是,创建一个用户线程就要创建一个相应的内核线程。由于创建内核线程的开销会影响应用程序的性能,所以这种模型的大多数实现限制了系统支持的线程数量。Linux,还有 Windows 操作系统的家族,都实现了一对一模型。 多对多模型 多对多模型 图 3 多对多模型 多对多模型 (图 3) 多路复用多个用户级线程到同样数量或更少数量的内核线程。内核线程的数量可能与特定应用程序或特定机器有关 (应用程序在多处理器上比在单处理器上可能分配到更多数量的线程) 。 现在我们考虑一下这些设计对并发性的影响。虽然多对一模型允许开发人员创建任意多的用户线程,但是由于内核只能一次调度一个线程,所以并未增加并发性。虽然一对一模型提供了更大的并发性,但是开发人员应小心,不要在应用程序内创建太多线程 (有时系统可能会限制创建线程的数量) 。 多对多模型没有这两个缺点: 开发人员可以创建任意多的用户线程,并且相应内核线程能在多处理器系统上并发执行。而且,当一个线程执行阻塞系统调用时,内核可以调度另一个线程来执行。 多对多模型的一种变种仍然多路复用多个用户级线程到同样数量或更少数量的内核线程,但也允许绑定某个用户线程到一个内核线程。这个变种,有时称为双层模型 (图 4) 。 双层模型 图 4 双层模型 Solaris 操作系统在第 9 版以前支持这种双层模型;但从第 9 版后,就使用了一对一模型。

1 min · 70 words · -

限流、熔断与降级

“限流、熔断与降级” 限流 Rate Limiting 限流是从系统的流量入口考虑,从进入的流量上进行限制,达到保护系统的作用 是指需要限制并发/请求量的场景 (如秒杀等) ,通过限流保护服务免受雪崩之灾。 计数器 多少次每秒/每分/每天,根据作用范围的不同,计算器可以分为单机计数器即Local Counter (每个机器都有自己的计数器) 和全局计数器也就是分布式计数器即Global Counter (所有机器公有一个计数器阈值) 令牌桶 令牌桶算法是网络流量整形 (Traffic Shaping) 和速率限制 (Rate Limiting) 中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。 令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。 漏桶 漏桶算法思路很简单,水 (请求) 先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。 方法 优点 缺点 计数器 简单方便 存在一下子被刷完计数器的情况 令牌桶 可以处理瞬间突发的流量 ~ 漏桶 限制请求的平均速率 不能处理瞬间流量的情况,当流量把漏桶装满后,大部分的请求都会被丢弃掉 熔断 Circuit Breaker 主调熔断 主调熔断是熔断的主要场景,在微服务中是结合服务注册和发现组件来使用的。主调通过服务发现组件来获取被调的实例,如果主调的失败达到了一个阈值,服务发现组件会熔断被调的实例。 被调熔断 被调熔断,被调实例获取当前的实例负载情况,如果cpu/内存/io 等超过了一定的阈值,那么就会触发熔断,将抛弃进来的请求。此时熔断和限流比较像,一个是基于负载情况,一个是根据配置的阈值情况。 降级 降级,是从系统内部的平级服务或者业务的维度考虑,流量大了,可以干掉一些,保护其他功能正常使用。 降级也就是服务降级,当我们的服务器压力剧增为了保证核心功能的可用性 ,而选择性的降低一些功能的可用性,或者直接关闭该功能。这就是典型的丢车保帅了。当服务暂时不可用或者影响到核心流程时,需要待高峰或者问题解决后再打开。通过降级实现部分可用、有损服务。主流的降级策略有基于RT (响应时间) 、异常比率和异常数的降级。 就比如贴吧类型的网站,当服务器吃不消的时候,可以选择把发帖功能关闭,注册功能关闭,改密码,改头像这些都关了,为了确保登录和浏览帖子这种核心的功能。 降级的手段大致有这么三种 强一致变为最后一致,延迟服务 干掉一些次要功能 简化流程 每个服务都需要制定自己的降级策略,根据服务不同的优先级来设定降级方案。另外降级策略最好是由开关系统或者配置系统统一控制。一般而言都会建立一个独立的降级系统,可以灵活且批量的配置服务器的降级功能。当然也有用代码自动降级的,例如接口超时降级、失败重试多次降级等。具体失败几次,超时设置多久,由你们的业务等其他因素决定。开个小会,定个值,扔线上去看看情况。根据情况再调优。 熔断和限流都可以认为是降级的一种方式 https://xie.infoq.cn/article/2593d1a3b9e1e06cac6502c4f?utm_source=rss&utm_medium=article

1 min · 62 words · -

面向对象

面向对象 面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。 继承概念的实现方式主要有2类:实现继承、接口继承。 实现继承是指使用基类的属性和方法而无需额外编码的能力。 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)。 在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。 OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。 https://www.cnblogs.com/bigberg/p/7182741.html

1 min · 22 words · -