百分比分流算法设计

一,需求 在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 攻击方式 被注入的恶意代码被存储在网站服务器。正常用户访问特定页面时,存储的恶意代码被输出执行导致的攻击。此种攻击危害较大,可能危及众多用户。 举例

session

HttpSession 机制及安全防范

一,什么是Http Session 由于http 协议是无状态的,我不能知道当前的request来至于哪一个特定的用户。为来解决这个问题,需要request中携带特定的参数,表明用户身份,而Server端基于这个参数来维护一份该用户特有的上下文会话,称之为session。这个特定参数叫做Session id。 二,基于Session的会话机制 1,client 发起一个request到server端 2,server端基于该request,生成一份session,同时将该session id传递给client端 3,client收到response后,存储session id在本地,一般使用cookie存储。 4,client以后的每份请求都携带该sesion id 5,server端收到request后,

filter

Filter 和 HandlerInterceptor 以及Spring AOP的异同

相同点 都能将某些横切代码提炼出来,然后通过拦截的方式,添加到被拦截的方法或请求,从而降低代码耦合度和复杂度。 其中Filter和Spring的HandlerInterceptor设计思想相同,都是通过链式的方式。即将一组Filter或者HandlerInterceptor定义好,放在配置文件中,然后通过容器加载,然后顺序调度。Filter的容器是Tomcat,HandlerInterceptor的容器是Spring。 同时Filter和HandlerInterceptor都是针对web请求拦截处理 不同点 Filter更原生,基于Servlet框架即可实现 HandlerInterceptor基于Spring,需要Spring MVC Framework的支持 Spring AOP,基于AspectJ,典型的面向切面编程,他不局限于Web应用,功能更强大,使用也更复杂点。

boyhood

我们都是这样长大的

看《少年时代》之前,我不知道导演的名字,不知道电影的内容,只隐约的听说是新近奥斯卡最佳影片。观影近一个小时候之后发现,小主角们的年龄容貌渐进式的改变着,时间跨度之大,让我想起了理查德·林克莱特曾经用27年的跨度拍摄的《爱在黎明破晓前》,《爱在日落黄昏时》,《爱在日落黄昏时》三部曲,他们同样也由伊桑·霍克主演。看完后查了一下,才特么发现,果然就是理查德.林克莱特拍的此片,好浪漫男人。 《少年时代》通过十二年的时间跨度,记录讲述了一个少年的整个成长过程。此间少年有对大人们的迷惑和无助,有不被理解和被欺负,有青春期对爱情和性的向往,有敏感的心对这个世界的不理解。这一路跌跌撞撞,会遇见几个asshole,但也不乏那么几个亦师亦友的人,始终给予少年的支持和提点,

database

如何保证数据的高可用性

一,高可用性定义 我理解的高可用性应该包括两方面 数据稳定性,数据应该总是可以被访问的 数据访问的速度,数据被存取的速度应该在用户可以承受的范围内 二,保证数据的可用性 可以使用数据库的主从备份来保证数据的高可用性。 数据稳定性的保证:由于采用了主从备份,当一台数据库服务宕掉后,其余数据库能保证数据库的可访问和恢复。 数据访问速度的保证:对主数据库进行写操作,对从数据库进行读操作,从而降低读写操作对某单个数据库server的IO压力,这就是所谓的数据读写分离技术 三,主从数据备份的难点 基于对上述可用性结构的理解,我认为该方案有如下两个难点: 主从数据库需要保证数据的一致性 对于多个从数据库,如何将读请求负载均衡至特定的从数据库 一般有成熟的技术框架来解决这两个技术难点,可在网上搜索。

java

Java Thread Pool

一,线程池的好处 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控 二,线程池使用方式 java中使用ThreadPoolExecutor来创建一个线程池。其基本用法如下: //创建一个线程池 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>

String

String 同StringBuffer性能比较

String和StringBuffer都可以用来拼接字符串,但大多数java程序员都知道。String拼接的性能远不及StringBuffer或者StringBuilder,为什么? 一,StringBuffer性能更好的原因 首先,String和StringBuffer对字符串的内部存放都是放在char数组中,但有细微差别。 String的拼接实现 String的数组声明为: private final char value[]; 由于String的char数组是final声明,这意味一旦存放具体内容后,char[]将无法改变,于是String在做拼接时,就有了如下代码: public String concat(String str) { int otherLen = str.length(); if (otherLen == 0)