IO模型介绍

一、几种IO模型介绍 1.1 同步/阻塞 同步和阻塞大体上描述的是同一种行为,比如方法A调用方法B。方法A一定要等到方法B执行完毕后,再返回。在方法B执行过程中,方法A依然占用时间片,阻塞等待方法B执行完成。这种IO模型又叫BIO 即Blocking IO 1.2 非阻塞 方法A调用方法B后,立即返回,不阻塞。但方法B可能需要执行很长时间,如果想要拿到方法B执行后的结果,需要循环d定时的去查询方法B的执行情况,这个查询过程也是非阻塞的,调用后立即返回。当查询到方法B已经执行完成,则方法A再调用获取数据的方法,去拉方法B的执行结果。 这种IO模型又叫NIO 即 Non

Java NIO 笔记

一、NIO和IO的区别 1.1 单向和双向 传统IO在读写数据到一个具体位置(可能是文件、网络主机)时,读写操作需要分别对应一个流。而NIO是通过channel的方式连接具体位置,且channel是双向,即可用来读,也可用来写 1.2 直接和间接 传统的流,读取时,直接从流中即可获取内容,写时,直接向流写内容即可。而NIO中,channel读写需要通过Buffer间接进行。 一段典型的IO代码如下: import java.io.*; public class CopyFile { public static

秒杀系统设计

一、前言 这篇文章的设计思想来源于沈剑。很受启发。为了加强记忆,做此笔记。 二、秒杀业务的典型场景 100w个人抢1w台小米 三、秒杀业务的特点 抢之前,需要读库存。如果还有库存,则写数据库进行锁库操作。考虑到人多货少。所以实际有100w人读了库存,但成功锁库的只有1w人。典型的读多,写少的场景。读是主要造成系统压力的操作。且这些读有两个特点: 库存可以不精确,用户关心的是有货没货。并不一定关心到底还有多少货 允许脏读。实际库存只有5台。但是展示给用户有10台都可以。因为用户最终下单锁库时,会去操作真正的库存。这个时候库存不足,可以直接给用户提示下单失败即可。因为即便下单之前读的库存精确,

HBase学习之结构设计

一、HBase在应用层面存取的数据结构 应用层面上,不考虑实现细节。我们对Hbase的操作像其他数据库一样。是以表为单位来存放数据的。但HBase中的表跟传统的关系数据库表,在结构上和存储上有一定差别。 上图中存储了一行cnn的网站数据,这行数据又具体存储了网站的网页内容(contents),和网站的链接(anchor)数据 HBase的表有以下几个重要术语 Row Key :标示一行的主键,按字典顺序排列。查找数据都是通过Row Key来进行。比如上图中展示了Row key为“com.cnn.www”的一行数据(不要看上图表格有多行。那是由于Hbase每列数据有一个版本概念,在逻辑上,只要他们的Row key相同,则属同一行)

RabbitMQ使用入门

一、 四个组件 P: producer,消息生产者 X: exchange,所有消息先送达到这里,然后他再按Queue的定义规则,将消息分类发送给对应的queue queue: 图中红色部分则为queue.他们申明自己所要消息的规则,然后从exchange获取对应的消息。另一端则将该消息推送给对应的comsumer 。queue可以设置durable,这样可以保证RabbitMQ挂后,不丢数据,但是有一定时间窗口,没落盘的数据,可能还是会丢。 C: comsumer,也叫Receiver 从指定的queue中获取消息,并执行一系列动作。Receiver可以开通ACK机制,这样Receiver挂后,依然可以让其它Receiver消费消息 二、两种大的使用方式 2.1

LSM Tree

一、大幅度制约存储介质吞吐量的原因 首先抛出结论。无论任何存储介质(不管是机械硬盘还是SSD,抑或是内存)的顺序访问速度都远远高出随机访问的速度。 二、传统数据库的实现机制 传统数据库,比如Mysql使用的b+树索引,对读友好。但容易造成随机写。比如新插入一个值到数据库,首先我们要读取b+树,判断新插入的值放在树的什么位置,其次在特定的位置写入新值,并做一系列调整,分裂,使之满足b+树的特性。这不可避免的造成了磁盘的随机访问,大数据量的插入速度很慢。当然这也符合历史发展趋势,早起的IT行业,数据量和数据增长速度有限,只要拥有良好的查询性能,即可满足需求。 但随着硬件性能的提升,业务形态的变化,现今的互联网系统,

分布式系统学习笔记

一、分布式的两大场景 数据存储的分布式 服务的分布式 二、数据存储的分布式 比如海量数据,单机存储不下,需要多机,以集群的方式存储,即为数据的分布式存储,数据存储的分布式一般涉及如下几个方面 数据的分片策略 全局主键的实现机制 跨结点数据的聚合 分布式事务 数据容灾机制 2.1数据分片策略 2.1.1 基于数据范围来分 比如库1,存放id 1到1000w的数据,库2存放id 1000w到2000w的数据 优点: 单库数据规模提前预估。超规模后,加机器,不需要迁移数据。

百分比分流算法设计

一,需求 在A/B测试系统中,常常将进入系统中的流量按百分比分组。对不同的分组做不同的业务逻辑,一段时间后观测两组达成的业务效果。比如实验组为20%的流量,对比组为80%的流量,由于最终进入系统总的流量数和具体进入系统有哪些流量都是为止了。需要一个分流算法来保证. 进入流量的分配,在宏观上按实验的百分比配置分配,比如20%的流量进入实验组,80%的流量进入对比组 同一份流量多次进入系统时,保证分组的一致性。即不要出现一会分到实验组,一会分到对比组 二,算法实现 算法思想 通过hash算法,将流量平均分配到100个桶 按百分比顺序取分分配这一个百个桶 具体实现 算法总共分为三个流程 使用MurmurHash将流量id,计算出一个hash值

有意思的增量计算算法

问题场景 假设有一张表(user_info),其数据结构如下 last_login_time记录的是每个用户最后一次登录时间。现在有这样一组标签"1天内","1~3天","3天以上"来描述用户登录日期和当前日期之间的差值,且为了保证查询的效率,需要将每个用户的登录标签提前计算出来并存储,方便前端高效查询,存储的表(user_tag)结构为 请问该如何实现。 普通的方式 每天将每个用户的最后登录日期和今天进行比较,计算出其登录标签,sql伪代码如下: select

我看锤子手机

最新的锤子坚果PRO发布了。也像往常一样看了发布会,但同往常不一样的是,我没能坚持把发布会看完。我开始对锤子手机和老罗有了一些厌倦。要知道,我曾经很是欣赏老罗,甚至跟很多人安利过老罗。可是为什么,在锤子可能发布了有史以来综合实力最好的产品之际,我开始感到厌倦? 五年前,老罗开始踏足手机领域,在这之初,其言行高调,对其它手机品牌的工业设计和人机交互进行了诸多批判,结合他之前已经给自己塑造的形象。似乎传递出,他能制造改变世界,或者起码给这个世界带来一点惊喜的产品。我对这点满怀期待,甚至深信不疑。 最新的坚果PRO,从外观和综合实力上来看,这基本就是锤子五年来最优秀的手机。但老罗偏执的采用方正设计,觉得其它手机在设计上都趋同平庸,美其名曰为“圆滑当道时代的锐利异类”。可能方正的设计是要看一点,可是会很割手,这一点饱受诟病,甚至有网友真的用其削苹果、

读《万历十五年》

万历十五年,也即1587年。这一年在同整个万里朝的其它年份比起来算是稀松平常的一年。但是黄仁宇先生通过对这一年的前后事件串联,试图说明明帝国的衰败已无可避免。 背景 首先我们的国家幅员辽阔,在统治技术简陋无力时,历朝历代为了维持帝国的统治,便求助于基于儒学的传统道德来约束整个社会,而道德本身并不足以弥补技术上的拙劣。而明朝洪武开国定下财政,资源分配政策,更是让明帝国在中后期对整个国家统筹管理上乏力。洪武制定的粮饷不必全部上缴中央,就近送往各地政府单位开销,虽然其目的是出于减少资源集中到再分派过程的运输损耗,节省运力,但这种收支没有两条线(我party就做的很好)分开的做法。在国家一旦遭遇战争或瘟疫时,很难集中力量办大事(好熟悉的味道) 到了万历朝时,文官集团趋于成熟。作为儒家思想的卫道者,这样的成熟集团,对国家是种灾难。他们口口声声呼号着家国天下,但实际上阳奉阴违。儒家思想所倡导的中庸不过是努力掩盖道德所代表的阳和人性所代表的阴之间不可调和的矛盾。同时代的欧洲正在经历着大航海时代,

为什么单元测试很重要

单元测试对程序员不陌生,可是对很多程序员来说,并不太喜欢写单元测试,感觉不是业务代码,又要做数据初始化,又要做数据清理,显得较为麻烦。毋庸置疑单元测试是重要的,尤其是可重复执行的单元测试,甚至早些年还有一些极端的公司践行着测试驱动开发的软件开发模式,但这份重要不见得每个程序员都认识,我就遇到过同事反问我,写单元测试有什么用?基于我自己的程序经验,我觉得有有以下几点进行阐述 白盒测试 大多数测试人员只只能做黑盒测试,但单元测试能更好的做白盒测试,因为代码就是你写的,你理应更清楚其逻辑和风险,从而在单元测试中进行测试。 节省开发时间 是的,你满以为不写单元测试,就是节约时间。但bug是守恒的,你不在单元测试的时候揪出来,那么他会被QA揪出来,甚至揪不出来,直至在某个深夜在线上他爆发出来,这个时候你焦头烂额,你要基于日志还原事发现场,你要一遍一遍读着好几周甚至几个月前的代码,

soa

微服务的注册与发现

一、服务注册中心 Service Register 由于服务的的众多,且服务本身变更可能频繁。所以典型的分布式服务,需要一个服务注册中心来作为服务调用方和服务提供方之间的桥梁。 注册中心像一个数据库,存储了当前的可用服务。注册中心需提供API,供服务端注册、更新服务到注册中心,供客户端查询可用服务。 可用框架: etcd consul Apache Zookeeper 二、服务的注册 服务自己注册到注册中心 服务端自己发起注册,将自己的信息注册到注册中心。 优点 实现简单 缺点 不同语言的服务端,都需要实现服务注册的功能 框架 Netflix OSS Eureka

跨域请求之JSONP

前言 由于安全原因,浏览器会限制脚本发起跨站请求,是为浏览器的同源策略。而有时我们又需要跨站请求,比如一个大型网站多个域名之间的信息协同共享。在不违反同源策略的前提下,大概有CORS,JSONP,Proxy Server等技术达到跨站请求的目的。前面我介绍了CORS,它是W3C推荐跨站请求方式,也更安全。这篇文章主要介绍JSONP。 什么是JSONP JSONP全称(JSON with Padding),是一种基于html中<script>标签实现跨域请求的技术。 为了方便全文举例说明,某页面所在的网站假设为www.foo.com,请求跨站至www.bar.com获取数据。 浏览器同源策略虽然限制了跨站AJAX请求,

hibernate

Hibernate和Mybatis应该如何选择

介绍 Hibernate和Mybatis都是J2EE领域优秀的ORM框架。不同于纯JDBC方式在数据操作时的繁琐,他们很好的隐藏了前者的一些操作细节,提供给调用方更为友好简洁的API。 Hibernate Hibernate更自动化,抽象层次更高,更面向对象。开发者在Hibernate中配置好Java Bean同数据库表的映射关系以及Java Bean之间的关联关系后,就可以专注于业务代码编写,仅通过Hibernate的API进行数据库操作,最终提交给数据库执行的SQL由Hibernate自动生成,在正确使用的情况下,其生成的SQL都是高效妥帖的。值得一提的是,这些配置都是一次性的,不需要反复修改。 MyBatis 比起Hibernate来说,Mybatis的工作方式显得不那么自动,所以也有人称其为半自动化框架。使用Mybatis,开发者不光要关注业务代码怎么写,还要关注其对应的SQL该如何写,并将这些SQL配置在Mybatis中,而业务代码的变更还可能导致这些配置被反复修改。 如何选择 理论上来说,Mybatis这种半自动的方式,能够让开发者能很细粒度的控制持久层的运作方式,

测试

为什么自测很重要

一,故事 做为一个开发人员,对自己交付的成果可靠性负责,这很重要。保证可靠性最重要的手段之一就是充分的自测。 我刚入职场所供职的公司,虽然母公司是一家美国五百强,但我所在的部门比较小,主要负责中国国内中小型企业的供应链管理系统的开发和实施。加之国内中小型企业普遍信息化水平并不高,并发量也不大,所以他们对软件的质量和性能往往没有什么要求,只要能满足其业务需求即可,对于细节不太在意。这些客观原因导致我们团队在交付产品时较为随意,往往没有专业测试团队对产品进行质量把控,大多数时候开发在大概自测后即部署客户测试环境,由客户和现场实施人员测试发现问题,然后再反馈修改,这导致很多项目的交付周期较长,交付软件也并不完美。而这种随意本身,对于一个刚入职场,职业素养还处在塑造期的我来说也是一种伤害。 后来我进入了一家国内领先的电商企业。我所在的团队对开发个人素质要求特别高,开发测试完成后,由专业测试团队进行测试,然后再上线。但如果上线出现任何问题,主要的责备都会落在开发人员身上,而不是测试。

奇点临近

读《奇点临近》

经过长长的时间,我终于读完了《奇点临近》,总得来说,这是一本好书。书中有很多观点同《失控》相同,不同的是《奇点临近》基于人类或则智能的进化阶段叙事,层级清晰。 由于个人原因,本书阅读跨度时间过长,读完后很多细节已记不太清了,独留几个感触较深的点。 1、人类或者整个智能进化和扩散的速度并不是线性的,而是指数的。由于人类掌握的知识总量越来越多,在此基础上所生发的技术进步的速度相比之前更快。这条指数曲线存在一个拐点,在其之前,我们感觉不到技术进步有多快,但当知识积累到一定量之后,过了这个拐点,进步速度将有一个质的飞跃,这个拐点便称之为奇点。 2、生物的进化速度已赶不上智能扩散的速度。所以会出现生物智能同非生物智能结合的过渡阶段,及至非生物智能成为主宰的阶段。 3、

cors

跨域请求之CORS

浏览器同源政策 浏览器为了防止跨站恶意脚本攻击,而对脚本跨站请求所做的一种限制,称为浏览器同源策略(Same-origin policy)。 该策略虽然能够防止跨站脚本的攻击,但同时也限制了跨站信息的沟通。而对于大型网站系统来说,基于脚本跨站通信场景(基于javascript的ajax请求)实实在在存在的。 为了绕过或放松同源策略的限制,出现了一些列技术,如:JSONP、WebSockets、Cross-origin Resource Sharing(Cors),Cross-document-messaging等等。 什么是cors Cors全称跨域资源共享(Cross-origin resource sharing),它是w3c推荐的一种跨站资源资源共享标准。 其主要原理和实现步骤为:(假设www.a.com站请求链接www.b.

java

Java泛型有什么卵用?

一,什么是java泛型 java泛型是指,在类和方法调用时,指定具体的类型参数(type Parameter),从而实现编译时类型检测,保证运行时类型安全的机制。 支持类型参数调用的类和方法定义方式如下: 类 将泛型参数声明放在类名后的尖括号中,多个类型参数以逗号分隔。调用时在类名后传具体的类型 声明 public class TestClass<K,V> { K key; V value; public K getKey() { return key; } public void

java

Java序列化(Serializable)

什么是序列化 在java中,将一个对象变成字节称为序列化。反之称为反序列。 为什么需要序列化 方便网络传输 方便存储 方便跨平台 不可能直接存储并还原一个对象,在计算机世界,存储通信都是以字节流形式进行的。 Java对象序列化生成的字节流并不一定要通过java来进行反序列,它完全可以跨平台使用.net甚或其他程序处理。 序列化后的字节流由于更精简,所以其通信成本更小,优于xml,所以许多RPC框架会使用字节流通信。 如何序列化 java原生方式 hessian Kryo java原生方式:通过java的ObjectInputStream和ObjectOutputStream,可以将实现了Serializable接口的对象进行反序列化和序列化。 由于序列化的过程本身需要耗时,且序列化后的字节过大也不方便传输,这两点上,java自身的序列化机制做的并不优秀。于是有了第三方的序列化框架,hessian和kryo,他们在序列化的效率上要更优秀。 传说Kryo的序列化要由于hessian。

XAResource

JTA

一、什么是JTA JTA全称Java Transaction API ,它是Java中用来规范定义分布式事务处理的标准,其标准编号为JSR 907。 二、如何保证分布式事务 一个业务单元,它所涉及的操作,需要对多个数据库进行修改。这些修改需要一并成功,要么全部回滚,即需要保证跨多个数据库操作的ACID事务性。我们知道单个数据库支持事务,那如何保证分布式数据处理的事务性呢?答案是:X/Open XA**** 三、什么是X/Open XA X/Open XA是一个工业标准,简称XA。他提供了一组本地资源管理器(比如单个数据库)和全局事务管理器(

db

关系型数据库的事务隔离级别

一、什么是事务隔离级别 关系型数据库中,多事务并发时,在数据读写一致性和并发性能之间取不同侧重点的事务特性叫做事务隔离级别。 二、都有哪些隔离级别 一般关系型数据库中,都有四种事务隔离级别,分别是:可序列化、可重复读、提交读、未提交读 可序列化 实现机制 对选定的对象或范围加读锁和写锁,且这些锁只有在事务结束时释放,其他事务对该事务所涉及的对象的读写将被阻塞。这就使得数据的访问是以串行方式进行,从而保证了数据的一致性。这种方式是最高的事务隔离级别,该级别下不会出现脏读、不可重复度、幻读等情况 缺点 由于数据的读写是以串行方式进行的,导致多事务并发时,数据的可用性严重不足 可重复读 实现机制 对选定的对象加读写锁一直到事务结束,但不会加范围锁。

cdn

CDN初探

一,什么是CDN 世界上最遥远的距离不是生与死,而是你在电信,而你所访问的资源服务器却在联通网络;是你在大天朝,而你所访问的资源服务器却远在大洋彼岸的美利坚。为了解决这些由于地址位置,甚至网络环境导致的访问响应漫长的问题,遂有了CDN技术。 CDN全称Content delivery network。是一种内容分发网络技术。其核心点在于通过一个遍及全球的网络来分发内容,使得全球任意一个客户端对内容的请求,都能通过临近客户所在位置的CDN服务器获取内容(当然选定提供内容的服务器可能不仅仅看距离这一个唯度),而无需耗费时间去源服务器获取。同时内容被遍布全球CDN网络分发,能够有效的避免单一服务器提供资源所易遭受的DDOS攻击。 二,CDN获取的两种方式 为了让CDN进行内容分发,需要将原始服务器上的内容缓存至CDN服务器。达到该目的的手段有两种,push和pull push 提前将内容上传至CDN服务器。然后源站引用CDN的url。 比如在www.example.com上引入百度的jQuery(

filter

如何防止xss攻击

前言 上一篇说到了何为xss攻击,以及xss攻击的分为三类,存储型xss***和***反射型xss,以及***dom型xss***。 由于xss的原理是恶意代码在浏览器执行导致。所以对xss防范的核心理念就是让恶意代码不可执行。其手段有二: 1,过滤输入 2,转义输出 过滤输入(Filtering for XSS) 过滤输入就是输入中的可执行代码标记,比如特殊符号及字样(()<>& script)过滤到,将其去除,或替换成无威胁的字符。 对于基于web的java应用,可以使用filter拦截请求,对请求中的输入参数使用正则匹配特殊,然后进行替换处理 转义输出(

xss

什么是XSS攻击

一,什么是xss攻击 XSS全称Cross-Site Scripting。是一种注入攻击方式。攻击者将客户端脚本代码(如JS,AS,HTML,Flash等一切可被客户端执行的代码。互联网时代主要指javascript)注入目标网站,在正常用户访问受害网站时,浏览器执行这些恶意代码,实现一系列恶意行为。 注入的方式一般通过url或者input输入框将恶意代码提交至后台 二,xss攻击有哪些危害 当恶意脚本被执行时,可能获取用户的敏感cookie信息,从而获取用户权限。也可能引导用户至恶意网站页面等等。 三,xss攻击都有哪几类 1,存储型xss 攻击方式 被注入的恶意代码被存储在网站服务器。正常用户访问特定页面时,存储的恶意代码被输出执行导致的攻击。此种攻击危害较大,可能危及众多用户。 举例