Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15843 articles
Browse latest View live

五年后通信业将是怎样的?

$
0
0

昨天长微博转了中兴通讯史立荣总裁致中兴全员的一封信《而立之年,让我们从头思考未来——中兴为什么要提出M-ICT战略》 http://weibo.com/p/1001603746131401152057

中兴通讯提出了面向未来的M-ICT战略,我们正在步入一个前所未有的巨变新时代,一个面向移动、万物互联、全面跨界融合的信息时代。信息产业内部IT、CT、Internet成为一体,外部与传统产业深度融合。M-ICT从“CGO”做起,让公司内外的品牌形象认知“更酷”、“更绿色”、“更开放”,让企业增加更大潜力,员工燃烧更高激情。M-ICT时代,我们的解决方案要聚焦“运营商市场、政企市场、消费者市场”的客户核心痛点,并围绕“新兴领域”进行蓝海布局。

~~~~~~~~~~~~~~~~~~~~

 中兴通讯终于下决心转型了,我不知道内部的员工怎么理解M-ICT,怎么理解CGO,又是准备怎么实现的。不过对外界来说,这些英文字母是相当枯燥的(从这点看,中兴通讯的这个新战略名称并不好)。

从信中透漏的信息看, 大致包含以下内容:

1、 对环境的判断:将迎来面向移动、万物互联、全面跨界融合的信息时代

——M-ICT时代。

2、 如何变:未来,我们面向客户必须变得更Cool、技术上更加追求Green,组织和心态上更Open,才能让M-ICT战略获得成功的落地。

(1)要转变为一个COOL公司。 通过极致的产品体验、创新的商业模式把用户吸引到自己的生态圈,需要给用户一个充分的理由感觉到爽,需要聚焦引爆点实现品牌重塑。

(2)要更加注重GREEN。不仅仅意味着节能环保、自然生态友好,还意味着生机勃勃的创新环境……我们必须通过技术创造更加生机勃勃的发展原动力,让新的客户价值在这里萌发。

(3)Open。要坚决全面开放,打造产业新生态,构建全新组织能力。

成立了CGO(Cool、Green、Open)实验室,目的不是像以前一样的追求集成创新、微创新,而是为了面向更长远的未来进行基础创新,也探索符合人性的体验创新。

3、聚焦四大核心领域:聚焦“运营商市场、政企市场、消费者市场”的客户核心痛点,并围绕“新兴领域”进行蓝海布局。

~~~~~~~~~~~~~~~~~~~~~~~~~~~

这些内容中包含了中兴对环境巨变的思考,应对的策略,目标的定位。 居安思危,积极应对未来环境的变化,这个出发点是好的,也是必须的。无论是国内还是国外,无论是电信运营商还是设备商等产业链厂商,必须思考:五年后的通信业将是怎样的?适合自己的位置在哪?

到那个时候,单独的通信服务将不存在。管道流量曾几何级数增加,但单纯的管道业务不足以支撑服务商(那时已不叫电信运营商)的正常盈利,而设备商等产业链厂商,将面临越来越复杂的市场需求,产业链不断拉长,拓宽,同时终端越来越易用,满足各种交互的需要,背后的专业化也越来越强。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

再回到中兴通讯的新战略上,从信中公开的部分信息看,这个转略想既照顾到全公司碰到的面性问题,也照顾局部的点问题。运营商市场、政企市场、消费者市场、新兴领域对手不同,服务流程不同,竞争手法不一样,对管理者要求也不一样,很难在一个战略中全面解决这些问题。我也不清楚中兴通讯期望的“新兴领域”是哪些,但目前能看到的互联网平台(或应用)、云服务、物联网等未来发展潜力较大的领域,又会提出新的要求,拓展并不是技术先进、解决方案完善就能成功的。可以想象,中兴通讯的战略落地将是一个痛苦的过程。


  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密

10种溺爱方式,种种都危险

$
0
0

[ 导读]当今做父母的大都知道溺爱孩子有害,但却分不清什么是溺爱,更不了解自己家里有没有溺爱。

 

10种溺爱方式,种种都危险

 

“溺”,词典上解释为“淹没”的意思。人被水淹没了叫“溺毙”,如果父母的爱流横溢泛滥起来,那也会“淹没”孩子的,这就是溺爱,是一种失去理智,直接摧残儿童身心健康的爱。

1.特殊待遇

孩子在家庭中的地位高人一等,处处特殊照顾,如吃“独食”,好的食品放在他面前供他一人享用;做“独生”,爷爷奶奶可以不过生日,孩子过生日得买大蛋糕,送礼物……这样的孩子自感特殊,习惯于高人一等,必然变得自私,没有同情心,不会关心他人。

2.过分注意

一家人时刻关照他,陪伴他。过年过节,亲戚朋友来了往往嘻笑逗引没完,有时候大人坐一圈把他围在中心,一再欢迎孩子表演节目,掌声不断。这样的孩子自认为自己是中心,确实变成“小太阳”了。家里人都要围着他转,并且一天到晚不得安宁,注意力极其分散,“人来疯”也特别严重,甚至客人来了闹得没法谈话。

 

3.轻易满足

孩子要什么就给什么。有的父母还给幼儿和小学生很多零花钱,孩子的满足就更轻易了。这种孩子必然养成不珍惜物品、讲究物质享受、浪费金钱和不体贴他人的坏性格,并且毫无忍耐和吃苦精神。

4.生活懒散

允许孩子饮食起居、玩耍学习没有规律,要怎样就怎样,睡懒觉,不吃饭,白天游游荡荡,晚上看电视到深夜等。这样的孩子长大后缺乏上进心、好奇心,做人得过且过,做事心猿意马,有始无终。

5.祈求央告

例如边哄边求孩子吃饭睡觉,答应给孩子讲3个故事才把饭吃完。孩子的心理是,你越央求他他越扭捏作态,不但不能明辨是非,培养不出责任心和落落大方的性格,而且教育的威信也丧失殆尽。

6.包办代替

我曾问一些妈妈,要不要求孩子劳动,有的竟说:“我疼都来不及,还忍心让孩子劳动?”也有的说:“叫‘小东西’做事更麻烦,还不如我帮他做了。”所以三四岁的孩子还要喂饭,还不会穿衣,五六岁的孩子还不做任何家务事,不懂得劳动的愉快和帮助父母减轻负担的责任,这样包办下去,必然失去一个勤劳、善良、富有同情心的能干、上进的孩子。这决不是耸人听闻。

7.大惊小怪

本来“初生牛犊不怕虎”,孩子不怕水,不怕黑,不怕摔跤,不怕病痛。摔跤以后往往自己不声不响爬起来继续玩。后来为什么有的孩子胆小爱哭了呢?那往往是父母和祖父母造成的,孩子有病痛时表现惊慌失措,娇惯的最终结果是孩子不让父母离开一步。这些孩子就打下懦弱的烙印了。

8.剥夺独立

为了绝对安全,父母不让孩子走出家门,也不许他和别的小朋友玩。更有甚者,有的孩子成了“小尾巴”,时刻不能离开父母或老人一步,搂抱着睡,偎依着坐,驮在背上走;含在嘴里怕融化,吐出来怕飞走。这样的孩子会变得胆小无能,丧失自信,养成依赖心理,还往往成为“把门虎”,在家里横行霸道,到外面胆小如鼠,造成严重性格缺陷。

 

9.害怕哭闹

由于从小迁就孩子,孩子在不顺心时以哭闹、睡地、不吃饭来要挟父母。溺爱的父母就只好哄骗,投降,依从,迁就。害怕孩子哭闹的父母是无能的父母;打骂爸妈的孩子会变成无情的逆子,在性格中播下了自私、无情、任性和缺乏自制力的种子。

10.当面袒护

有时爸爸管孩子,妈妈护着:“不要太严了,他还小呢。”有的父母教孩子,奶奶会站出来说话:“你们不能要求太急,他大了自然会好;你们小的时候,还远远没有他好呢!”这样的孩子当然是“教不了”啦!因为他全无是非观念,而且时时有“保护伞”和“避难所”,其后果不仅孩子性格扭曲,有时还会造成家庭不睦。

以上10种溺爱的形式是比较典型的实例,不是每个家庭全部都有的,但是一般家庭在各种溺爱中会占有几种,或各种都有轻度表现也是值得警惕的,我们要以科学的爱,来保护孩子的健康成长。


5time语录QQ认证空间: http://user.qzone.qq.com/7116069,求关注!

5time语录官方微信号:i_5time,或者扫描下面图片添加:
5time语录网官方微信

Memcached的服务设计与启动过程——C10K系列

$
0
0
C10k要解决的问题,是10K个连接。
LINUX下,使用EPOLL可实现异步非阻塞(注:阻塞的一定是同步的,阻塞是调用方自己阻塞自己(等待事件))
非阻塞:是指调用方不会阻塞自己,如被调用方有数据就返回,无数据就返回EAGAIN,调用方根据EAGAIN决定自己的策略。因此非阻塞,和异步没有任何关联。
异步:是相对于同步的。异步是指:调用的时机和返回的时机不是同一时刻。异步说的是一个处理流程,而并不一定是具体的某个函数。

举例如下:
你在电子商城买了一本书,你已经下单;但是,这时候商城并没有立即给你发单,而是有合适时候时,主动通知你,我已经发单了。
因此,下单,和发单不是同一时刻。
一般来说,异步需要通过回调函数来实现。即先需要注册一个异步处理流程,如必须先将你的手机号告诉给商城。
当然,也有异步服务。比如用网银买火车票。火车票网站转到网银,网银付账是一个同步的过程。但是火车票网站与网银的处理是异步的。火车票网站,不知道网银交易何时完成;网银交易完成后,再发个消息给火车票网站交易完成。

---------------------------------------------------------------------------------
Memcached,版本1.4.20:基于libevent的多线程实现
采用的是一个主线程(dispatcher_thread),多个工作线程worker(LIBEVENT_THREAD),
(1)主线程dispatcher_thread负责接收外部请求事件,然后派发给工作线程处理。
(2)主线程dispatcher_thread和工作线程的通过管道传递消息。(实际上,是工作线程添加了一个与主线程关联的管道的事件 (libevent 的event))

对于TCP连接来说,主线程(dispatcher_thread)是一个监听线程,即监听外部的服务请求。
主线程(dispatcher_thread)的定义:
typedef struct {
pthread_t thread_id;

/* unique ID of this thread */
struct event_base *base;
/* libevent handle this thread uses */
} LIBEVENT_DISPATCHER_THREAD;

工作线程Worker的定义:
typedef struct {
pthread_t thread_id;

/* unique ID of this thread */
struct event_base *base;
/* libevent handle this thread uses */
struct event notify_event;  /* listen event for notify pipe */
int notify_receive_fd;
/* receiving end of notify pipe */
int notify_send_fd;

/* sending end of notify pipe */
struct conn_queue *new_conn_queue; /* queue of new connections to handle */
} LIBEVENT_THREAD;

Libevent 的main函数比较长,但与网络请求相关的是serversocket的创建和thread_init函数。

第一步:多线程服务初始化thread_init()
服务的初始化是在thread_init()完成的,主要完成主线程(dispatcher_thread),多个工作线程worker(LIBEVENT_THREAD)事件注册,管道通知等:
(1)初始化主线程dispatcher_thread的event base,event;
(2)初始化管道,将主线程dispatcher_thread与工作线程worker,通过管道关联。
for (i = 0; i notify_event, me->notify_receive_fd,
EV_READ | EV_PERSIST, thread_libevent_process, me);
event_base_set(me->base, &me->notify_event);

if (event_add(&me->notify_event, 0) == -1) {
fprintf(stderr, "Can't monitor libevent notify pipe\n");
exit(1);
}
§ thread_libevent_process:这个函数,是接收到数据的具体处理过程,其参数是线程句柄
§ 初始化工作线程自己的请求队列。
LIBEVENT_THREAD中的struct conn_queue *new_conn_queue;这个是请求队列。
(4)启动工作线程
创建Worker线程(LIBEVENT_THREAD),其函数入口是:
static void *worker_libevent(void *arg)
里面是一个event_base_loop()的消息循环。
(5)到这里,工作线程已经完成初始化和启动(即工作线程已经可以工作了)。主线程只要等待工作线程启动完毕。

第二步,serversocket创建:和所有网络服务一样:create the listening socket, bind it, and init
server_sockets(settings.port, tcp_transport,
portnumber_file)

new_socket:
获取socket的设置:fcntl(sfd, F_GETFL, 0))
将其设置为非阻塞:fcntl(sfd, F_SETFL, flags | O_NONBLOCK) 

socket设置:根据配置文件
SO_REUSEADDR,//地址重用
SO_KEEPALIVE,//是否保持连接,这是TCP层的控制
SO_LINGER,//延时断开连接。ngingx默认也启用
TCP_NODELAY,//不启用Neagle算法(本科书中的滑动窗口拥塞控制协议),一般内网访问,常设置为true
bind:
listen:
listen_conn_add = conn_new(sfd, conn_listening,
EV_READ | EV_PERSIST, 1,
transport, main_base);//main_base要和创建的server socket关联
这里的
conn_new函数:
初始化conn(一个超级复杂的结构体)
设置事件与socket 的fd,与main_base关联,设置事件响应的具体处理函数,event_handler
添加事件
到这里,才把main_base(event_base* 类型)与监听事件关联完成。

第三步:
主消息循环;整个服务启动过程结束。

备注:主线程dispatcher_thread未必是程序启动的main thread,可以是一个独立的thread。


已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



我所遵守的11条数据库设计准则

$
0
0

前言:作者Shivprasad koirala,前微软ASP/ASP.NET的MVC工程师,现于印度任CEO职位。学生初次翻译,如有不妥,不吝赐教。


简介

在你开始阅读这篇文章之前,我要先告诉你我不算是数据库设计方面的什么大师。下面的11条准则,是我从项目、从我自身的经验和我自己的理解和学习中得来的。我个人认为在数据库设计方面运用这些准则能使我受益匪浅。我也欢迎任何批评与指点。

我之所以要写这么一篇详尽的文章,是因为,许多开发者设计数据库的时候十分信奉“三个范式”(译者注:而没有结合实际情况)。他们认为三范式是数据库设计的唯一真谛。随着项目开发的不断推进,持有这些想法的人会经常碰壁和遇上无穷无尽的麻烦。

如果你还不太了解什么是范式,可以点击这里: 3 normal forms: part1- part2- part3(译者注:原文为yotube视频,由于众所周知的原因国内无法观看,我已将原视频分享到csdn下载区,下载免积分),这个教程将会手把手教你这三个范式。

“范式”是非常重要的准则,但是如果完全一味的遵守,不做丝毫改变的话,会让你经常陷入麻烦之中。当我设计数据库时,我将下面这11条重要的准则牢牢记在心中。

准则1:应用的本质是什么(OLTP还是OLAP)?

(译者注:联机事务处理或联机分析处理,即偏向于增删改查还是偏向于数据分析)

当你开始设计数据库的时候,所要做的第一件事是分析你设计的应用的本质,是事务型呢还是分析型呢。你会发现,许许多多的开发者根本没有考虑自己的应用到底是属于哪种类型,而是全部按照“范式”的准则来设计,然后就碰上了各种各样的性能和定制的问题。正如我所说,有两种应用:基于事务型的和基于分析型的,那么接下来让我们了解一下这两种类型具体是什么。

事务型:这种类型的应用,最终用户对增删改查更为关注,比如,增加、读取、更新和删除记录。对于这种类型的数据库,正式来说我们称呼为OLTP(译者注:Online Transaction Processing,联机事务处理)。

分析型:这种类型的应用,最终用户更关注与对数据的分析、产生报告和对数据的预测等。这种类型的数据库很少执行插入或是更新数据的操作。这种设计的主要意图是以最快的速度从数据库获取数据,并进行分析。对于这种类型的数据库,正式来说我们称呼为OLAP(译者注:Online Analytical Processing,联机分析处理)。

换句话说,如果你发现在数据库上进行插入、更新或删除更为重要,那你应该遵循标准的范式来设计,否则应该建立一个扁平非规范的数据库结构。

下图展示了如何在左侧姓名和地址表中运用非规范化设计思想,来创建右侧的不遵守标准范式的扁平的非规范数据结构。

准则2:将你的数据划分成若干逻辑片段,让生活更美好

这条准则实际上就是第一范式。违背了这条准则的一个明显特征是,你的查询语句中用了一大堆字符串解析函数,如substring、charindex等。如果的却是这样,那么你需要应用一下这条准则。

举个例子,下图表中有个字段是“Student Name”,如果你想要查询名字中带有"Koirala"而不带有"Harisingh"的学生,你可以想象到时候你写出来的查询语句是什么样的。

所以一个更好的方案是将这个字段分解成更详细的逻辑片段,这样我们就能写出更干净,也更完美的查询语句了。

准则3:不要过度使用准则2

开发人员们都是聪明人。如果你告诉了他们一个门路,那么他们就总是使用这个方法。准则2用过头会导致一些你根本不想要的结果。但是准则2本身是非常有用的。当你想着"把这玩意儿拆了"的时候,暂停一下,问问你自己,真有必要拆吗?正如我刚才所说,拆分必须是逻辑性的。

举个例子,你可以看到下图中有个电话号码的字段,你几乎不会对号码的ISD(International Subscriber Dialing,国际订户拨号)分别进行管理(除非哪个项目里真有这个需求),所以就这么把号码放着显然更明智。要是你真的把它们拆了,那到时候你就得面对一大堆的"拆分后遗症"了。

准则4:冗余的不统一数据是你最大的敌人

小心冗余数据,并重构它们。我并不担心冗余数据会占用很多磁盘空间,我所担心的是这些冗余数据所造成的困惑与混乱。

比如说,在下图中,你会发现“5th Standard”和“Fifth standard”是一个意思,只不过描述的形式略微不同。你可能会解释说,这些数据是之前有人乱录入的,而且还没有经过验证。当你打算导出一个报告的时候,对于这个字段将产生两份不一样的报告,当用户看到这样的报告,他们恐怕就要在风中凌乱了。


一个解决办法就是,把这些数据移到一个新表中,然后原来的表以引用的方式使用这些数据。下图中你可以看到,我创建了一个新的叫做"Standards"的表,然后用一个外键将这两个表连接起来。

准则5:小心那些用分隔符分开的数据

第一范式的第二条内容规定了一个位置上不能存多个值。下图就是一个存了多个值的例子。仔细观察"Syllabus"字段就会发现,我们塞了太多的数据到这个字段中了。这种字段我们成为"重复组",如果我们要操作这些数据,不仅查询语句会写的很复杂(且不论对错),而且我很怀疑这种查询的效率。


这种某些列里塞了很多数据的字段,要特别小心的对待,一个比较好的解决办法是:将这些字段移到不同的表中,然后将它们用外键相连,以便于从逻辑和操作上更好的进行管理。


我们需要遵守第一范式的第二条规定:一个位置不能存储多个值。从上图中可以看到,我建立了一个独立的"syllabus"表,然后与主表建立了多对多的关联。

用这种方法的话,主表中的"syllabus"字段不再塞入一大堆用分隔符分开的数据了。逻辑上易于理解,操作性也更强。

准则6:小心部分依赖


小心那些部分依赖于主键的字段,例如上图中的主键是Roll Number和Standard。现在来看看“syllabus”,这个字段与standard字段相关联,而不直接与Student(“Roll Number”字段)相关联。

“syllabus”字段与学生正在学习的"standard"字段相关联,而没有直接和学生关联。那么明天我想要更新“syllabus”的时候,我就必须把所有与之相关的"Student"字段也更新掉。老兄,这是个辛苦的体力活,而且还毫无逻辑!所以更有意义的做法是将"syllabus"字段单独拉出来然后与"Standard"通过外键关联。

你可以看到我是如何将"syllabus"字段拉出来然后与“Standards”相联系。

这条准则其实就是第二范式本身:所有的属性必须做到全部依赖,不应该有字段是部分依赖主键的。

准则7:仔细地选择派生列

如果你设计的是OLTP型数据库,即事务型数据库,避免派生列将会是很明智的,除非对这一块内容的性能有高要求。但是对于需要大量求和与计算的OLAP数据库,即分析型数据库,这些派生列就显得很有必要而且能使数据库性能更加优越。

上图中你可以看到,Average依赖Total Marks和Total Subject来计算,这就是数据冗余的表现之一。所以碰到这种派生于其他列的字段,要好好想一想,这个字段真的需要吗?

这条准则正如第三范式所说:字段不能依赖于任何非主键字段。我个人认为不要盲目遵循第三范式,要视情况而定。存在冗余的数据并不总是坏事。如果这些冗余数据是通过计算得来的,看情况来决定要不要遵守第三范式。

准则8:如果性能才是关键,那就不要非常严格地避免冗余数据


不要把"避免一切冗余数据"当成一条死命令。如果对性能的要求很高,就考虑一下非标准化吧。遵守标准的话,你经常需要使用join命令来连接很多个表格,但在非标准化中,通过设置一些冗余信息,就没那么多join命令了,所以性能会好得多。

准则9:多维度的数据是一种完全不同的野兽

使用OLAP(分析型)数据库的项目主要处理的是多维数据。举例来说的话你可以看一下下图,你想要得到每个国家的销量,每个顾客的销量和其他数据。简单来说,你所关注的销量是三个维度数据的交集。


这种情况下,设计成一个维度将会更好。简单来说,你可以建立一个拥有"sales amount"字段的销量表(它为中心表),然后设置一些外键来和其他的一维表相关联。


准则10:集中化键值表的设计

我经常会碰到键值表。键值表的意思是,它存储着键和和与这个键相对应的数据(译者注:就像数据结构中的map的用法一样,是一种结构相当简单的表)。举例来说,下表你可以看到有一个Currency 表和Country表,仔细观察就会发现,实际上这两张表中只有一个键和一个对应值而已。


对于这种类型的数据表,创建一个集中化的表然后设立一个"Type"字段来区分。这会使你的数据库工作的更好。

准则11:对于多级数据要引用自身的主键,或是设立外键

我也会经常会碰到多集数据的情况,考虑一个多级的销售方案,一个销售员旗下可以有很多个销售员。在这种情况下,引用自身的主键或是设立外键都会帮助你达到想要的效果。


这篇文章并不是让你不要遵守标准范式,而是让你不要盲目遵守,你要首先考虑的是项目的属性和你要处理什么类型的数据。


下面是一个用简单的学校表来手把手解释三个标准范式的视频(译者注:与上文中的“3 normal forms”为同一个视频,下载过的读者可不必重复下载)

SQL Server -- Can you explain First,Second and Third normal form in SQL server [part1]

SQL Server -- Can you explain First,Second and Third normal form in SQL server [part2]

SQL Server -- Can you explain First,Second and Third normal form in SQL server [part3]

(全文完)


原文来自:http://www.codeproject.com/Articles/359654/11-important-database-designing-rules-which-I-foll

作者:u014204710 发表于2014-8-23 0:34:07 原文链接
阅读:118 评论:0 查看评论

计算 一个点 附近的地方

$
0
0

问题

随着地理位置的应用普及,越来越多类似计算 一个点 附近的酒店的需求。比如,显示当前位置2000米范围内的 7 天酒店。

一般来说,在系统里都有一张表,存储了每个 7 天酒店的位置信息,表结构可以简化为三个字段 tb_location(ID, lng, lat),其中 lng:表示经度;lat:表示纬度,这两个字段都是数值类型的,且建了索引。

现在要把 2 公里范围内的 7 天酒店找出来,有的人写的 SQL 语句大概是这样的:
select id from tb_location where calc_distance(lng, lat, curLng, curLat) < 2000

这个语句的问题是没法利用索引,需要全表扫描,计算每一条记录与当前位置的距离,效率很低。

优化

用一张图来说明优化策略:
附近地点计算优化

2 公里范围是一个圆,这个圆的边界是由任意多的点确定的。但一个正方形的边界却是由四个点确定的,所以可以通过把要查找的地点限定在包围这个圆的最小正方形来缩小查找范围。

计算代码如下(收集自网络):

package net.coderbee.gps;

public class GPS {

     private final double EARTH_RADIUS = 6378.137; // 地球半径

     private static double rad(double d) {
          return d * Math.PI / 180.0; // 计算弧长
     }

     /**
     * 计算两个地理坐标之间的距离,
     * 
     * @param Lat1
     * @param Lng1
     * @param Lat2
     * @param Lng2
     * @return 距离,单位是米
     */
     public double calcDistance(double Lat1, double Lng1, double Lat2,
               double Lng2) {
          double radLat1 = rad(Lat1);
          double radLat2 = rad(Lat2);
          double a = radLat1 - radLat2;
          double b = rad(Lng1) - rad(Lng2);
          double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                    + Math.cos(radLat1) * Math.cos(radLat2)
                    * Math.pow(Math.sin(b / 2), 2)));
          s = s * EARTH_RADIUS;
          s = s * 1000; // 换算成米
          return s;

     }

     /**
     * 计算最小正方形的四个经纬度值
     * 
     * @param lng
     *            经度
     * @param lat
     *            纬度
     * @param distance
     *            距离
     * @return
     */
     public static double[] getRectangle(double lng, double lat, long distance) {
          float delta = 111000;

          double minLng = lng - distance
                    / Math.abs(Math.cos(Math.toRadians(lat)) * delta);
          double maxLng = lng + distance
                    / Math.abs(Math.cos(Math.toRadians(lat)) * delta);
          double minLat = lat - (distance / delta);
          double maxLat = lat + (distance / delta);
          return new double[] { minLng, minLat, maxLng, maxLat };
     }
}

如果需要可以转换为 SQL 的函数。

那么查询的 SQL 语句可以优化为:

select id from (
     select loc.id, calc_distance(loc.lng,  loc.lat,  :curLng,  :curLat) distance
     from tb_location loc 
     where loc.lng >= :minLng and loc.lng < :maxLng 
          and loc.lat >= :minLat and loc.lat < :maxLat
) t 
where t.distance < 2000

hive 配置文件以及join中null值的处理

$
0
0

一、Hive的参数设置

1.  三种设定方式:配置文件

·   用户自定义配置文件:$HIVE_CONF_DIR/hive-site.xml

·   默认配置文件:$HIVE_CONF_DIR/hive-default.xml

用户自定义配置会覆盖默认配置。另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hadoop的配置文件包括

·   $HADOOP_CONF_DIR/hive-site.xml

·   $HADOOP_CONF_DIR/hive-default.xml

Hive的配置会覆盖Hadoop的配置。

配置文件的设定对本机启动的所有Hive进程都有效。

2.  命令行参数 ,

bin/hive -hiveconf hive.root.logger=INFO,console

这一设定对本次启动的Session(对于Server方式启动,则是所有请求的Sessions)有效。

3.  参数声明

set mapred.reduce.tasks=100;

这一设定的作用域也是Session级的

二、使用hive一些注意的地方

1.  Hive使用的字符集默认是UTF-8,hive中没有转换字符编码的这种函数

hive.exec.compress.output 这个参数, 默认是 false,

但是很多时候貌似要单独显式设置一遍,否则会对结果做压缩的,如果你的这个文件后面还要在hadoop下直接操作, 那么就不能压缩了

2.  Join中处理null值的语义区别

这里的特殊逻辑指的是,Hive的Join中,作为Joinkey的字段比较,null=null是有意义的,且返回值为true。检查以下查询:

select u.uid, count(u.uid)

from t_weblog l join t_user u on (l.uid = u.uid) groupby u.uid;

查询中,t_weblog表中uid为空的记录将和t_user表中uid为空的记录做连接,即l.uid = u.uid=null成立。

如果需要与标准一致的语义,我们需要改写查询手动过滤null值的情况:

select u.uid, count(u.uid)

from t_weblog l join t_user u

on (l.uid = u.uid and l.uid is not null and u.uid is notnull)

group by u.uid;

实践中,这一语义区别也是经常导致数据倾斜的原因之一。

作者:manburen01 发表于2014-8-23 21:26:35 原文链接
阅读:80 评论:0 查看评论

谈谈产品开发团队的配置管理规则

$
0
0

作者:张克强    作者微博: 张克强-敏捷307

在《 源代码管理的新15条建议 》中的第7条建议提到:每个团队应当对代码配置项和非配置项有所说明,不要假设每个团队新人都是代码配置管理达人,小心自以为是的新手加入一些自以为是的垃圾。虽然可以删除,但发现再删除,其本身就是成本。

在《 高效组织的配置管理计划》也提到了产品线层面的配置管理,那么产品开发团队的配置管理到底应该是什么样呢?本文试图来探讨下。

首先说明本文探讨的产品开发团队的特征。这里的产品开发是指围绕某产品或者产品线开发,其产品的生命周期是长于一年以上,为了改进产品,不断有新的要求得到实现满足,也会发现产品的缺陷,需要在开发中解决。 这样的产品开发是不同于短期合同外包项目的,其产品开发团队将较长期的承担此产品(线)的运行维护,增强修改,开发建设。应当说,当前大多数团队是属于这样的团队。

什么是配置管理规则?

配置管理规则这个说法也许过于学术化,讲白了其核心就是文件如何存放和版本升级。而规则即是团队共同遵守的约定。比如在某目录下存放会议纪要,为了便于查找会议纪要的文件名以会议日期开头,格式是YYYYMMDD。

为什么需要产品开发团队的配置管理规则?

1,开发团队是多人组成,规则能够让所有人查询,有依据,协同提供效率
2,产品开发是长期过程,文件会越来越多,如果没有一定的规则,将造成文件遗失或者难以查找。

谁来制定团队的配置管理规则?

团队负责人应当为团队长远的信息资产负责,组织团队成员来商量团队自身的配置管理规则。
如果团队存在配置管理员这样的角色的话,那么配置管理规则的起草和维护当然首先是配置管理员的事情。

团队的配置管理规则有哪些内容?

对于软件开发团队,显然首要的,源代码管理是规则重点覆盖的内容。对于源代码管理,要回答如下典型问题:
1,选择什么样的源代码版本控制工具?如果组织已经选定,或者历史上已经选定,那么需要遵循。这是基础工具,一般不会经常变化,而变化必须经过慎重的考虑,当然往往的这是组织级考虑的内容。所以这个问题对于绝大多数团队而言,不是问题,因为已经有选定的工具。
2,对于源代码,选择什么样的主干分支模式? 这是显著影响团队效率的选择,必须团队骨干一起来做决定,不同的主干分支模式适用于不同的场景,需要团队中此方面的达人来提供建议,如果团队内难以做决定,麻烦组织中的高手来设计本团队的主干分支模式也是应当的,甚至有组织邀请业界专家来为重要产品线设计主干分支开发模式,并制定规则。
3,对于选定的主干分支模式,有哪些操作注意点,具体而言比如如下问题:
3.1 什么情况下从主干拉出分支?
3.2 什么情况下合并分支到主干?
3.3 什么情况下从分支拉出分支?
3.4 什么情况下从主干合并到分支?
3.5 什么情况下从分支合并到分支?
3.6 什么情况下删除分支?
3.7 如果选择主干无分支,那么需要注意什么?有什么配套手段?
4,源代码检入时需要遵循什么规则? 如何书写检入说明? 是否需要与某个变更或者需求或者缺陷进行关联? 要先本地进行静态代码扫描? 先进行code review?还是后进行扫描,或者code review
5,哪些区域的代码是信息安全高等级代码? 访问级别比较高,团队外围成员需申请后才能访问?如何申请? 
6,哪些区域的代码是核心代码? 或者是红区代码,但凡此处代码修改,对应的测试范围需要扩大,关联到其它的系统?
7,为了协同工作,在工程师本地电脑上需要如何设置?
其次是文档,文档就存活时间而言,分为两类:第一类是其生命周期与产品相同;第二类是其生命周期与特定改进、事务或者项目相当,明显短于产品生命周期。
第一类文档可称为产品级文档,比如团队配置管理规则就应当是产品级文档,值得长期得到遵循并改进,此类文档典型有:
1,产品白皮书,产品介绍
2,产品功能目录,使用说明,系统功能树
3,产品应用架构,组件(系统,子系统、模块)结构图,组件(系统,子系统、模块)接口说明
4,产品性能架构,并发控制,处理高性能要求的架构模式
5,团队章程,团队改进建议
6,产品待办需求列表,原始需求

第二类文档可称为项目级文档,此类文档是大家最熟悉的文档,如下:
1,项目计划
2,项目需求规格说明书
3,项目会议纪要
4,项目测试计划

对于两类不同的文档,对于团队配置管理规则而言,产品级文档的处理是焦点,因为这是长期的文档。

团队的配置管理规则的好处

往大里说,团队配置管理规则处理的是产品信息资产,当然是值得精心制定并切实执行的。
往小里说,良好统一的协同工作平台能提升团队协作效率,让每个工程师顺畅的工作。







作者:zhangmike 发表于2014-8-23 18:05:10 原文链接
阅读:0 评论:0 查看评论

hadoop2.2.0 源码远程调试

$
0
0

http://blog.sina.com.cn/s/blog_5ccc692d0101pikf.html

 

学习hadoop2.2.0,远程调试hadoop源码

 

note: 只在linux上面调试,windows下面会有脚本执行的问题,可能需要安装cygwin可以解决.

1 把编译好的hadoop源代码导入eclipse
   hadoop2.2.0 <wbr>源码远程调试

 

2 如果要调试hdfs,修改~/hadoop-2.2.0/bin/hdfs
  elif [ "$COMMAND" = "dfs" ] ; then
  CLASS=org.apache.hadoop.fs.FsShell
  HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=6666,server=y,suspend=y"
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
 
  监听设置在这个位置,suspend=y,就是说操作dfs命令时候会挂起在6666端口,进程会暂停,直到有客户端来连接这个端口,比如eclipse远程调试。
   hadoop2.2.0 <wbr>源码远程调试

 

 
3 eclipse打开远程调试
   hadoop2.2.0 <wbr>源码远程调试

 

hadoop2.2.0 <wbr>源码远程调试

4 要调试其他功能,根据脚本来设置监听即可
5 如果调试自己写的mapreduce(伪分布式,mapreduce采用local方式,保证使用单个jvm情况下,否则会有静听端口冲突),修改~/hadoop-2.2.0/bin/hadoop
   #exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
   exec "$JAVA" -Xdebug -Xrunjdwp:transport=dt_socket,address=54321,server=y,suspend=n $HADOOP_OPTS -classpath "$CLASSPATH" $CLASS "$@"
   修改~/hadoop-2.2.0/etc/hadoop/mapred-site.xml为local模式
    hadoop2.2.0 <wbr>源码远程调试

执行hadoop jar ***.jar classname param...

即可进入远程debug模式。


已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




20个linux命令行工具监视性能(下) - Hackerman

$
0
0

昨天晚上第一次翻译了《20 Command Line Tools to Monitor Linux Performance》中的前十个命令,翻译得不是很好,今天晚上继续把后面的十个也翻译给大家吧,第一次写博客,写的不是特别的好,希望大家不要介意,也希望大家觉得有什么不对的地方能够多多指教,毕竟小弟还是初学者。下面我们开始学习下面十个命令吧!

11,Monit –- Linux Process and Services Monitoring

     Monit 是一个免费开源并且基于web的进程监督实用程序,自动监控和管理系统进程,应用程序,文件,目录,权限,校验和和文件系统。

     它监视的服务有 Apache, MySQL, Mail, FTP, ProFTP, Nginx, SSH 等等。系统状态能被浏览通过命令行或者使用 Monit 自己的用户界面。

     Monit Linux Process Monitoring

    想要了解Monit的更多的命令请参考 Linux Process Monitoring with Monit

12,NetHogs –- Monitor Per Process Network Bandwidth

    NetHogs is 是一个类似于 top命令的开源的更好的更小的程序,它能够监视系统上的任何一个活动网络进程。它也能够记录实时网络流量带宽使用的每个程序或应用程序。

   NetHogs Linux Bandwidth Monitoring

  想要了解该命令的更多用法请参考 Monitor Linux Network Bandwidth Using NetHogs

13,iftop -- Network Bandwidth Monitoring

     iftop是另一个基于终端的免费开源的系统监控实用工具。它通过系统连接的网络接口来显示频繁更新的网络(源主机到目的主机)带宽利用率。 iftop 被用作监视网络使用率,而‘ top‘则被用来监视cpu的使用率。 iftop工具被用来监视被选择的网络接口并且显示两个主机之间的网络带宽使用情况。具体用法如下

    http://www.tecmint.com/wp-content/uploads/2013/04/iftop.png

    该命令的更多使用方法请参考 iftop – Monitor Network Bandwidth Utilization

14,Monitorix -- System and Network Monitoring

    Monitorix is  是一个免费的轻量级的实用工具,它主要被设计用来运行和监视系统和网络资源尽可能多的运用在 Linux/Unix服务器上。它有一个内置的web服务器能够定期的收集系统和网络的信息并且通过图像显示它们。 它监视 system load average and usage, memory allocation(内存分配), disk driver health(磁盘驱动的健康状态), system services(系统服务), network ports(网络端口), mail statistics ( Sendmail, Postfix, Dovecot, etc)邮件统计, MySQL statistics(mysql统计)等等. 它旨在监控系统整体性能和有助于检测失败,瓶颈,异常活动等.

   Monitorix Monitoring

   了解该命令的更多使用方法请参考: Monitorix a System and Network Monitoring Tool for Linux

15,Arpwatch -- Ethernet Activity Monitor

    Arpwatch is 是一种被设计用来监视以太网的地址解析( MAC and IP address changes)的程序。 它持续保持监视以太网流量和产生一个IP和MAC地址对变化的以及网络上的时间戳的日志。当有一个地址对发生变化时它通过发送一个电子邮件界面告示管理员。它是非常的有用对于检查网络中 ARP 攻击

# arpwatch -i eth0

# tail -f /var/log/messageseth0

Apr 15 12:45:17 tecmint arpwatch: new station 172.16.16.64 d0:67:e5:c:9:67
Apr 15 12:45:19 tecmint arpwatch: new station 172.16.25.86 0:d0:b7:23:72:45
Apr 15 12:45:19 tecmint arpwatch: new station 172.16.25.86 0:d0:b7:23:72:45
Apr 15 12:45:19 tecmint arpwatch: new station 172.16.25.86 0:d0:b7:23:72:45
Apr 15 12:45:19 tecmint arpwatch: new station 172.16.25.86 0:d0:b7:23:72:45

  想要了解更多该命令的使用方法请参考: Arpwatch to Monitor Ethernet Activity

16,Suricata --Network Security Monitoring

     Suricata是一个高性能的开源网络安全和入侵检测和预防监测系统, FreeBSDWindows.它由一个非盈利基金会OISF设计和使用。

# suricata -c /etc/suricata/suricata.yaml -i eth0

23/7/2013 -- 12:22:45 - - This is Suricata version 1.4.4 RELEASE
23/7/2013 -- 12:22:45 - - CPUs/cores online: 2
23/7/2013 -- 12:22:45 - - Found an MTU of 1500 for 'eth0'
23/7/2013 -- 12:22:45 - - allocated 2097152 bytes of memory for the defrag hash... 65536 buckets of size 32
23/7/2013 -- 12:22:45 - - preallocated 65535 defrag trackers of size 104
23/7/2013 -- 12:22:45 - - defrag memory usage: 8912792 bytes, maximum: 33554432
23/7/2013 -- 12:22:45 - - AutoFP mode using default "Active Packets" flow load balancer
23/7/2013 -- 12:22:45 - - preallocated 1024 packets. Total memory 3170304
23/7/2013 -- 12:22:45 - - allocated 131072 bytes of memory for the host hash... 4096 buckets of size 32
23/7/2013 -- 12:22:45 - - preallocated 1000 hosts of size 76
23/7/2013 -- 12:22:45 - - host memory usage: 207072 bytes, maximum: 16777216
23/7/2013 -- 12:22:45 - - allocated 2097152 bytes of memory for the flow hash... 65536 buckets of size 32
23/7/2013 -- 12:22:45 - - preallocated 10000 flows of size 176
23/7/2013 -- 12:22:45 - - flow memory usage: 3857152 bytes, maximum: 33554432
23/7/2013 -- 12:22:45 - - IP reputation disabled
23/7/2013 -- 12:22:45 - - using magic-file /usr/share/file/magic

  了解该命令的更多使用方法请参考: Suricata – A Network Intrusion Detection and Prevention System

17,VnStat PHP – Monitoring Network Bandwidth

     VnStat PHP 一个基于web的前端应用程序最受欢迎的网络工具叫 “ vnstat“. VnStat PHP使用漂亮的图形界面监控网络流量. 它显示了发送和接收的网络流量使用率在每小时,每周,每月的统计报告中。

     Install Vnstat PHP in Linux

   该命令的更多用法参考: VnStat PHP – Monitoring Network Bandwidth

18,Nagios -- Network/Server Monitoring

   Nagios是一个领先的开源强大的监控系统,让网络/系统管理员识别并解决服务器相关问题在影响主要业务流程之前。通过Nagios系统, 管理员能够远程监控系统,交换机,路由器和打印机通过单一的窗口。 它显示关键的警告和指示如果运行错误在你的网络/服务器,它能够间接地帮助你开始补救之前发生的错误。

   具体使用方法请参考:: Install Nagios Monitoring System to Monitor Remote Linux/Windows Hosts   。

19, Nmon --Monitor Linux Performance

      Nmon (stands for Nigel’s performance Monitor) 代表奈杰尔性能监视器工具, 它被用来见识Linux资源例如 CPU, Memory, Disk Usage, Network, Top processes, NFS, Kernel 等等. 这个工具带有两种模式: Online Mode(在线模式) 和 Capture(捕获模式) Mode.

    在线模式,被用来实时监控。抓包模式,被用来存储那个包到格式为csv的文件中。

    Nmon Monitoring

  更多命令请参考: Install Nmon (Performance Monitoring) Tool in Linux

20,Collectl  -- All-in-One Performance Monitoring Tool

   Collectl  is也是另外一个强大并且基于的丰富的命令行界面的实用工具。它能用来搜集linux的系统信息例如CPU usage(cpu使用率), memory(内存), network(网络), inodes(节点), processes(进程), nfs, tcp, sockets 等等.

   Collectl Monitoring

   更多命令参考:I nstall Collectl (All-in-One Performance Monitoring) Tool in Linux

前十个命令行工具请看前一篇文章 《20个linux命令行工具监视性能(上)》

终于翻译完了20个linux命令行工具监视性能。也让我体会到了学习英语的重要性。本人的英语水平有限,有什么错误的地方还望大家多多指教。

 


本文链接: 20个linux命令行工具监视性能(下),转载请注明。

mysql优化方法

$
0
0
通过show status和应用特点了解各种SQL的执行频率

通过SHOW STATUS可以提供服务器状态信息,也可以使用mysqladmin extended-status命令获得。SHOW STATUS可以根据需要显示session级别的统计结果和global级别的统计结果。
以下几个参数对Myisam和Innodb存储引擎都计数:
Com_select  执行select操作的次数,一次查询只累加1;
Com_insert 执行insert操作的次数,对于批量插入的insert操作,只累加一次;
Com_update 执行update操作的次数;
Com_delete 执行delete操作的次数。

以下几个参数是针对Innodb存储引擎计数的,累加的算法也略有不同:
Innodb_rows_read select查询返回的行数;
Innodb_rows_inserted执行Insert操作插入的行数;
Innodb_rows_updated 执行update操作更新的行数;
Innodb_rows_deleted 执行delete操作删除的行数。

通过以上几个参数,可以很容易的了解当前数据库的应用是以插入更新为主还是以查询操作为主,以及各种类型的SQL大致的执行比例是多少。对于更新操作的计数,是对执行次数的计数,不论提交还是回滚都会累加。

对于事务型的应用,通过Com_commit和Com_rollback可以了解事务提交和回滚的情况,对于回滚操作非常频繁的数据库,可能意味着应用编写存在问题。

此外,以下几个参数便于我们了解数据库的基本情况:
Connections 试图连接Mysql服务器的次数
Uptime    服务器工作时间
Slow_queries 慢查询的次数
定位执行效率较低的SQL语句

可以通过以下两种方式定位执行效率较低的SQL语句:
可以通过慢查询日志定位那些执行效率较低的sql语句,用--log-slow-queries[=file_name]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。可以链接到管理维护中的相关章节。
慢查询日志在查询结束以后才纪录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题,可以使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态,是否锁表等等,可以实时的查看SQL执行情况,同时对一些锁表操作进行优化。
通过EXPLAIN分析低效SQL的执行计划

通过以上步骤查询到效率低的SQL后,我们可以通过explain或者desc 获取MySQL如何执行SELECT语句的信息,包括select语句执行过程表如何连接和连接的次序。

explain可以知道什么时候必须为表加入索引以得到一个使用索引来寻找记录的更快的SELECT。

mysql> explain select sum(moneys) from sales a,companys b where a.company_id = b.id and a.year = 2006;
+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+
| select_type   | table | type  | possible_keys| key            | key_len   | rows  | Extra     |
+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+
| SIMPLE    | b     | index | PRIMARY   | PRIMARY   | 4     |    1  | Using index   |
| SIMPLE    | a     | ALL   | NULL      | NULL      | NULL  |   12  | Using where   |
+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+
2 rows in set (0.02 sec)

说明:
select_type:select 类型
table:输出结果集的表
type:表示表的连接类型
①当表中仅有一行是type的值为system是最佳的连接类型;
②当select操作中使用索引进行表连接时type的值为ref;
③当select的表连接没有使用索引时,经常会看到type的值为ALL,表示对该表进行了全表扫描,这时需要考虑通过创建索引来提高表连接的效率。
possible_keys:表示查询时,可以使用的索引列.
key:表示使用的索引
key_len:索引长度
rows:扫描范围
Extra:执行情况的说明和描述
确定问题,并采取相应的优化措施

经过以上步骤,基本可以确认问题出现的原因,可以根据情况采取相应的措施,进行优化提高执行的效率。

例如上面的例子,我们确认是对a表的全表扫描导致效率的不理想,我们对a表的year字段创建了索引,查询需要扫描的行数明显较少。

mysql> explain select sum(moneys) from sales a,companys b where a.company_id = b.id and a.year = 2006;
+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+
| select_type   | table | type  | possible_keys| key            | key_len   | rows  | Extra     |
+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+
| SIMPLE    | b     | index | PRIMARY   | PRIMARY   | 4     |    1  | Using index   |
| SIMPLE    | a     | ref       | year      | year      | 4     |    3  | Using where   |
+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+
2 rows in set (0.02 sec)

已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



如何做一名优秀的团队领导?LinkedIn CEO Jeff Weiner给出的3条建议

$
0
0


上周,LinkedIn的CEO Jeff Weiner在旧金山接受了Pando Daily的专访。投资人、作家Li Jiang在 Medium发文,总结了他从中学到的3堂重要的课程。这其中,既有硅谷常能听到的建议,也有到一些几乎没人提过的观点,在这里与大家分享。

1. Focus

专注。是的,你原来肯定听过这一点,“专注”几乎都快成硅谷人的口头禅了。创办一家公司需要创业者全身心的投入,所以专注对于创业者显得格外重要。但不同于以往的解读,Jeff也提出了自己对于“专注”一些独到的看法。

Jeff在雅虎任职期间,雅虎开拓了大量的业务,包括搜索、新闻、email等。雅虎需要管理的产品越来越多。后来,竞争对手逐渐进入这些领域,并在各个垂直领域建立优势。

雅虎所面临的“问题”是,它在参与的各个领域几乎都是数一数二的。也正因为如此,雅虎很难抉择要舍弃哪些发展势头正好的业务,无法做到专注。

Jeff认为,企业的领导人需要看到未来3年、5年甚至7年的发展趋势,问问自己:“将来我们在这个领域还能保持领先吗?”如果答案是否定的,那么企业的领导人就必须鼓足勇气做出决定,把这些业务剥离出来,即便今天它们现在仍是最好的业务。

垂直领域的竞争者能够专注于一点,把他们的时间和资源全部投入到一个领域,最终超过了雅虎。

2. Thoughtfulness

Thoughtfulness这个词有两层含义,第一层是深思熟虑,并把对任何事情的想法严格执行;第二层是要关照他人。

灵感在科技界并不稀缺,但只有深思熟虑才能走得更远。所谓深思熟虑就是对于每一件事都进行深入彻底的思考,并形成解决问题思维模式,这不是肤浅的想一想,而是建立在多年的经验、对模式认同和不断重复的基础上。 简单地说,就是要在工作和生活的各个方面拥有一套系统性、战略性的解决方法。

Thoughtfulness的第二层含义是关照他人。为他人着想是我们成长过程中所学的一个重要的价值观,但在竞争激烈的公司中,这种体贴却很难见到。Jeff称赞公司的另一位联合创始人Reid Hoffman就总是很会关照他人,尽一切可能去帮助别人。这种形式的thoughtfulness是硅谷文化中非常关键的一点,铸就了硅谷今天的模样。

3. Compassion

同情心。这是在硅谷没怎么听过的说法,在商业领域上也少有人看重这一点。一般人都会仰慕自己的领导,以坚定的态度和超人般的意志服从领导,但是在一些情况下,这种做法使得公司文化一团糟。

Jeff对于同情心和富有同情心的领导方式的给出了自己的概念,让我们对于什么是好领导有了耳目一新的认识。

作为一个领导人,你很容易把自己的世界观强加到别人身上,如果他们没有按照你的想法完成工作你就会很生气。

Jeff讲了一个故事,有一位直接向他汇报的下属对于团队中一个成员很不满,于是便故意打压这位成员,但是这种打压导致了恶劣的后果,团队中的其他人也没法好好工作了。Jeff要求自己的这位下属更有同情心一些,发现团队成员的长处。他认为这名成员是因为领导的决定而待在团队中,这位领导应该把他放在更能发挥专长的岗位,或者就彻底让他离开团队。 如果某个人表现不好,团队领导有责任理解和倾听团队中的声音,并且平稳地解决问题。

几周之内,这位下属向Jeff汇报,他在把这名成员换到了另一个岗位后,整个团队的表现都显著改善。当时,Jeff意识到,他对于自己的另一位下属可能也犯了同样的错误,把自己的想法强加在他人的身上,并且在下属没有按照自己想法完成任务时感到十分沮丧。从那天开始,他明白做管理需要始终保持着同情心。

我也深受Jeff同情式管理的启发。这样的管理对于提升团队、改善文化具有十分重大的意义。团队领导很容易把自己的意志强加给成员,但是倾听、教导、帮助团队成员实现他们自身的潜力需要更多的耐心、成熟和自知。做一个有同情心的领导从长期来看会收获良好的效果,但这一理念在发展迅速、竞争激烈、进取心十足的科技界却几乎从没有听到过。

结语

Jeff当晚回答的最后一个问题是:“你希望拥有什么样特殊能力?”,Jeff毫不犹豫地回答:

无限的耐心

除非注明,本站文章均为原创或编译,转载请注明: 文章来自 36氪

36氪官方iOS应用正式上线,支持『一键下载36氪报道的移动App』和『离线阅读』立即下载!

我眼中的 性能劣化、优化的曲线

$
0
0

性能劣化

性能劣化的图形

随着代码写得越来越烂,程序运行时 数据库操作更多、IO 阻塞等待跟过、不必要的对象创建、GC 回收更频繁,线程的上下文切换也更多,开销越来越多,所有因素综合起来,程序运行更慢,响应延迟加大。

当到达临界点的时候,压垮骆驼的最后一根稻草出现了,系统直接崩溃。

坏东西、副作用是会累积的。

性能优化

性能优化的图形

代码的实现一直保持良好,不断通过 合并查询等措施减少数据库操作,通过优化SQL语句缩短了单次数据库操作的时间,通过更好的日志记录方式减少 IO 操作,减少 IO 阻塞等待的时间,进而又可以减少线程切换的次数,通过避免不必要的对象创建,可以提升代码的执行速度,还可以减少 GC 的次数,种种优化效果综合起来的结果就是程序运行稳定,响应时间缩短。

从业务实现的角度进行优化的效果是很明显的。

当然,到达临界点之后,也就是没法从业务实现的方式上优化性能的时候,只能通过更底层、更细微的优化手段进行优化,比如 JVM 参数、系统参数 调优等,这些措施带来的效果都是不怎么明显的。

比如,业务实现减少一次数据库操作,至少可以减少 10ms 的延迟,但要在更底层的地方得到 10ms 的优化效果应该是很困难的。

正面的作用也是可以累积的,只不过幅度是很缓慢的,且达到一定程度就很难再继续提升了。

作为开发人员,应该重视每一个细节。

web服务器访问流程

$
0
0

 



 问题1:DNS解析是什么,简述如图步骤1、2做了什么?

人们习惯记忆域名,但机器间互相只认ip,域名和ip可以是多对一的关系,他们之间的转换工作称为域名解析,域名解析需要有专门的域名解析服务器来完成。举例说明:

在浏览器中输入域名www.iteye.com,操作系统会向检查自己本地的hosts

是否有这个网址映射,如果有就直接调用这个ip地址,完成域名解析。如果没有就查找本地DNS解析器缓存,是否有这个网址映射关系,如果有直接返回,完成域名解析。如果咩有相应的网址映射关系,则会查找本地DNS服务器,如果要查询的域名包含在本地配置区域资源中,则返回结果给客户机,完成域名解析。如果未找到,本地DNS就会把请求发至根DNS,根DNS收到请求后会判断这个域名并返回负责该域名服务器的ip,最后会返回到本地DNS服务器,由DNS服务器在返回给客户机。

步骤1是客户端向服务器发出DNS请求。

步骤2是服务器向客户端返回ip响应。

问题2:简述如何与服务器建立TCP连接

在TCP/IP协议体系结构中的TCP协议使用三次握手机制来建立传输连接,具体步骤如下:

(1)首先是服务器初始化的过程,从CLOSED(关闭)状态开始通过顺序调用SOCKET、BIND、LISTEN和ACCEPT原语创建Socket套接字,进入LISTEN(监听)状态,等待客户端的TCP传输连接请求。

(2)客户端最开始也是从CLOSED状态开始调用SOCKET原语创建新的Socket套接字,然后在需要在调用CONNECT原语,向服务器发送一个将SYN字段置1(表示为同步数据段)的数据段,主动打开端口,进入到SYN SENT(已发送连接请求,等待对方确认)状态。

 

(3)服务器在收到来自客户端的SUN数据段后,发回一个SYN字段置1(表示此为同步数据段),ACK字段置1(表示此为确认数据段),ACK(确认号)=i+1的应答数据段(假设初始序号为j),被动打开端口,进入到SYN RCVD(已收到一个连接请求,但未进行确认)状态。这里要注意的是确认号是i+1,而不是i,表示服务器希望接收的下一个数据段序号为i+1.

(4)客户端在收到来自服务器的SYN+ACK数据段后,向服务器发送一个ACK=1(表示此为确认数据段),序号为i+1,ack=J+1的确认数据段,同时进去ESTABLISHED(连接建立)状态,建立单向连接。要注意的是,此时序号为i+1,确认号为j+1,表示客户端希望收到服务器的下一个数据段的序号为j+1.

服务端在收到客户端的ACK数据段后,进入ESTABLISHED状态,完成双向连接的建立。

一旦连接建立,数据就可以双向对等的流动,没有所谓的主从关系。

问题3:简述客户端与服务端传送数据。

在建立连接最后一次“握手”时,客户端发送的数据稍带着http请求报文,服务器在给客户端的http响应报文中稍带着要浏览的数据。

问题4:http协议与tcp协议之间的关系。

TCP协议是传输层协议,主要解决数据如何在网络中传输。而HTTP是应用层协议,主要解决如何包装数据。HTTP建立在TCP的基础上。

问题5:简述Http get请求过程,并举例。

get请求用于从服务器上获取资源,是默认的请求方法。当客户端向服务器发送http请求是可以稍带上要请求的数据,服务器在响应http请求是可以向客户端返回要访问的数据。

例如使用get方法读取路径为/usr/bin/image的图像。请求行给出了方法GET,URL,与HTTP协议版本号。报文头部有2行,给出了浏览器可以接收GIF与JPEG格式的图像。请求报文中没有正文.应答报文包括状态码和4行的报头。报头表示了日期,服务器,MIME版本号和文档长度:

请求:

GET/usr/bin/image1  HTTP/1.1

         Accept:  image/gif

         Accept:  image/jpeg

 应答:

 HTTP/1.1  200  ok

        Date: San,1-Feb-09  8:30:10  GMT

        Server:  xxx

        MIME-version:  1.0

        Content-length: 2048

             (文档内容)

问题6:简述Http post请求过程,并举例

post与get基本一致,post请求是客户端向服务器发送http请求是稍带上要上传到服务器处理的数据。

请求:

POST/cgi-bin/doc.pl  HTTP/1.1

        Accept: */*

        Accept: image/gif

        Accept: image/jpeg

        Content-length:64

应答:

HTTP/1.1  200 OK(状态行)

Last-Modified(应答首部) : Mon,20 Dec 2001 23 :26 :42 GMT

Date:Tue,11 Jan 2002 20:53:12 GMT

Status:200

Content-Type: Text/html

Servlet-Engine:

Content-Length:59

<html>(应答主体)

……

</html>

 

问题7:nginx是什么

Nginx是一个跨平台的Web服务器,可运行在Linux、FreeBSD、Solaris、AIX、Mac OS、Windows等操作系统上。相比Apache等,占有内存少,并发能力强,安装简单,bugs少。

Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块。用户根据自己的需要开发的模块都属于第三方模块。

问题8:简述nginx的工作流程

当它接收到一个HTTP请求是,它仅仅是通过查找配置文件将此次请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看作是nginx的真正劳动工作者。通常一个location中的指令会涉及一个handler模块和多个fiflter模块(多个location可以复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对影响内容进行处理。

问题9:简单的将图中内容填充。

端口(80)

dns服务器

nginx工作原理:

Nginx的模块从功能上分为如下三类。

Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。

Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。

Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

nginx工作原理参考:http://wuzhengfei.iteye.com/blog/2026998



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



网页设计中的彩色滤镜效果

$
0
0

[国外设计第54期]

Lovedays

在当今这个充斥着先进的特效和精妙风格的世界中,谁曾料到,像纯色和渐变这样简单的手法,竟能够催化出创造力,并极大提升网站的美学水准?现代网页设计师们,证明了优雅的插画、精致的图形和壮丽的照片,都能在彩色滤镜效果下很自然地得到强调。气氛焕然一新,网站开始变得光彩夺目。的确,它有助于解决某些问题。

首先,彩色滤镜能给网站耳目一新的外观,却不会增加负担 。其次,它通过搭配传递各种情绪的色彩,很好地丰富了设计。第三,作为一层低透明度的遮罩,它不会掩盖主背景的魅力,对于想要轻微淡化轮播图或视频区域,却仍希望其吸引力不减的人 ,这点尤其有用。最后,它为前面的内容提供了坚实的基础,兼顾了可读性。

参考: 最佳实践:一流的品牌与推广网站

这种方案能非常协调地与各种元素协作:提供强烈反差的白色、极受欢迎的扁平风格元素,还有为项目增添精致微妙感的轮廓式图形。

这里有些杰出的网页设计,示范了如何正确地运用这项技巧。

Zimya

Zimya

着陆页带有一层美妙的半透明渐变,立刻唤起积极温暖的感觉。从紫红色到橙黄色,遮罩层华丽的颜色令人着迷。

Red Collar

Red Collar

平滑的半透明渐变极大地丰富了背景图——这家机构的视觉象征。它增添了几分独特,不仅与整个场景形成互补,也形成了热情洋溢的氛围。

Ingram Cole and Land

Ingram Cole and Land

这个网站基于一些非常棒的赏心悦目的效果,这不仅指它的动画,还有成功贯穿整个网站设计的照片处理手法。从紫色到粉色,温暖而微妙的渐变,使欢迎页面看起来相当美妙奢华。

Adopt Wales

Adopt Wales

设计师在视频背景上覆盖了一层迷人的粉色渐变,营造了亲切友好的氛围。颜色与透明度的选择很好地突出了上面的元素。

Snippet App

The Snippet App

对于更喜欢创造冷静与便捷的整体感观的人而言,蓝与白的结合是非常有用的。设计师实际上用了三种色调,不过这两者占据主要地位。

Joyce Van Herck

Joyce Van Herck

Joyce Van Herck是名高端艺术家,她的在线作品集网站嵌入了优美的几何图形。甜美的半透明渐变使斜线拥有活力,加强了这种愉悦的氛围。

Electric Mainline

Electric Mainline

和前面提到的Snippet App很像,设计师运用了蓝白混合。不论如何,低透明度的遮罩层,使用户欣赏其背后那张扮演主角的背景图。

Solid Giant

Solid Giant

使用粉色是为了解决几个问题。首先,它能有效地突出标语、logo、导航和微妙的白色幽灵按钮;其次,它建立了一种轻松的氛围;最后,它体现了品牌特征。

Invelab

Invelab

同样,设计师试图在背景与前景之间营造完美的对比,同时也将注意力引向工作室的图片。明亮的紫色有效地与白色形成互补。

M2B

M2B

欢快的半透明渐变强化了网站的视觉表现。正由于采用了这种方式,全新的色彩使得背后的图片陡然增色。而白色被用作一种补充色,使内容看起来醒目。

Lovedays

Lovedays

设计师在欢迎页面上运用了扁平风格 。极简设计只包含了几个轮廓式元素、简洁的字体、朴素的按钮,还有城市背景图。后者与半透明的蓝色相配合,增加了可读性。

Numero Neuf

Numero Neuf

首页的特色是大量基于图片的导航,每一项都覆盖了一层黑色半透明滤镜。这种方式很常用:如果你想为文字营造完美的对比,并淡化菜单项,很自然就应该将注意力引向某个选中的项。

Evoluzione Telematica

Evoluzione Telematica

绿色使人联想到正能量,此处就是这么用的。明亮的色调与白色共同建立了一种积极的形象。

The Place

The Place

这位设计师借极简主义的方式重现了优雅。所选的颜色反映了网站的个性,统一了视频样式。

Obbaki Foundation

The Obbaki Foundation

颜色可以提升感观的协调程度。它丰富了网站的主题,同时轻而易举加入了一些戏剧性效果,对整体氛围有一定贡献。

Studio Up

Studio Up

这个机构通过迷人的效果展现了一个视觉差滚动的介绍页面,向普通用户证明了他们熟稔网页流行趋势。每一页都有其独特的颜色,覆盖在动态的背景上,用以突显其内容。

Hype Agency

The Hype Agency

设计师在焦点区域挥洒了一整片的橙色,为网站营造了恰当的积极的氛围。另一种颜色则是白色,非常明亮并融入其中。

Louis Currie

Louis Currie

Louis Currie不满足于单一颜色;他用了一整套不同的蜡笔色调交替展示。这个网站绝对能体现他敏锐的色彩感与协调感。

Grey Group

Grey Group

华丽的青绿色覆盖了首页,像一层没有重量的轻纱,强化了这个网站井然有序的外观。轮廓式图形和幽灵按钮很好地突出并积极配合主色调。

Papertelevision

Papertelevision

薄薄一层明亮多彩的颜色赏心悦目,伴随着每个主要部分。首页的深紫色几乎不容易注意到,但它仍然能使页面活泼有趣。

结论

彩色滤镜——这种从前在平面设计中的基本技巧,在网页设计中重获新生。虽然色彩轻微地稀释了设计,它也带来了一丝精致和特别的魅力,同时兼具功能性。

原文链接

top 查询系统进程运行情况

$
0
0
引用
$ top
top - 01:06:48 up 1:22, 1 user, load average: 0.06, 0.60, 0.48
Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 1.0% sy, 0.0% ni, 98.7% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 191272k total, 173656k used, 17616k free, 22052k buffers
Swap: 192772k total, 0k used, 192772k free, 123988k cached

PID   USER PR  NI  VIRT RES  SHR   S %CPU %MEM TIME+ COMMAND
1379  root 16  0   7976 2456 1980  S 0.7  1.3 0:11.03 sshd
14704 root 16  0   2128 980  796   R 0.7  0.5 0:02.72 top
1     root 16  0   1992 632  544   S 0.0  0.3 0:00.90 init
2     root 34  19  0    0    0     S 0.0  0.0 0:00.00 ksoftirqd/0
3     root RT  0   0    0    0     S 0.0  0.0 0:00.00 watchdog/0


统计信息区
前五行是系统整体的
统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下:

01:06:48 当前时间
up 1:22 系统运行时间,格式为时:分
1 user 当前登录用户数
load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。
三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

第二、三行为进程和CPU的信息。
当有多个CPU时,这些内容可能会超过两行。内容如下:

Tasks: 29 total 进程总数
1 running 正在运行的进程数
28 sleeping 睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数
Cpu(s): 0.3% us 用户空间占用CPU百分比
1.0% sy 内核空间占用CPU百分比
0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.7% id 空闲CPU百分比
0.0% wa 等待输入输出的CPU时间百分比
0.0% hi
0.0% si

最后两行为内存信息。
内容如下:

Mem: 191272k total 物理内存总量
173656k used 使用的物理内存总量
17616k free 空闲内存总量
22052k buffers 用作内核缓存的内存量
Swap: 192772k total 交换区总量
0k used 使用的交换区总量
192772k free 空闲交换区总量
123988k cached 缓冲的交换区总量。
内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被
覆盖,
该数值即为这些内容已存在于内存中的交换区的大小。
相应的内存再次被换出时可不必再对交换区写入。

进程信息区
统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。

序号 列名 含义
a PID 进程id
b PPID 父进程id
c RUSER Real user name
d UID 进程所有者的用户id
e USER 进程所有者的用户名
f GROUP 进程所有者的组名
g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
h PR 优先级
i NI nice值。负值表示高优先级,正值表示低优先级
j P 最后使用的CPU,仅在多CPU环境下有意义
k %CPU 上次更新到现在的CPU时间占用百分比
l TIME 进程使用的CPU时间总计,单位秒
m TIME+ 进程使用的CPU时间总计,单位1/100秒
n %MEM 进程使用的物理内存百分比
o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
r CODE 可执行代码占用的物理内存大小,单位kb
s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
t SHR 共享内存大小,单位kb
u nFLT 页面错误次数
v nDRT 最后一次写入到现在,被修改过的页面数。
w S 进程状态。
D=不可中断的睡眠状态
R=运行
S=睡眠
T=跟踪/停止
Z=僵尸进程
x COMMAND 命令名/命令行
y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
z Flags 任务标志,参考 sched.h

默认情况下仅显示比较重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通过下面的快捷键来更改显示内容。

更改显示内容
通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或隐藏对应的列,最后按回车键确定。

按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z 可以将相应的列向左移动。最后按回车键确定。

按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的 R 键可以将当前的排序倒转。

命令使用

1. 工具(命令)名称
top
2.工具(命令)作用
显示系统当前的进程和其他状况; top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止. 比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定.
3.环境设置
在Linux下使用。
4.使用方法
4.1 使用格式
top [-] [d] [p] [q] [c] [C] [S] [s] [n]

4.2 参数说明
d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。
p 通过指定监控进程ID来仅仅监控某个进程的状态。
q该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。
S 指定累计模式
s 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
i 使top不显示任何闲置或者僵死进程。
c 显示整个命令行而不只是显示命令名

4.3 其他
下面介绍在top命令执行过程中可以使用的一些交互命令。从使用角度来看,熟练的掌握这些命令比掌握选项还重要一些。这些命令都是单字母的,如果在命令行选项中使用了s选项,则可能其中一些命令会被屏蔽掉。
Ctrl+L 擦除并且重写屏幕。
h或者? 显示帮助画面,给出一些简短的命令总结说明。
k 终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。一般的终止进程可以使用15信号;如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。
i 忽略闲置和僵死进程。这是一个开关式命令。
q 退出程序。
r 重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低,反之则可以使该进程拥有更高的优先权。默认值是10。
S 切换到累计模式。
s 改变两次刷新之间的延迟时间。系统将提示用户输入新的时间,单位为s。如果有小数,就换算成m s。输入0值则系统将不断刷新,默认值是5 s。需要注意的是如果设置太小的时间,很可能会引起不断刷新,从而根本来不及看清显示的情况,而且系统负载也会大大增加。
f或者F 从当前显示中添加或者删除项目。
o或者O 改变显示项目的顺序。
l 切换显示平均负载和启动时间信息。
m 切换显示内存信息。
t 切换显示进程和CPU状态信息。
c 切换显示命令名称和完整命令行。
M 根据驻留内存大小进行排序。
P 根据CPU使用百分比大小进行

排序。
T 根据时间/累计时间进行排序。
W 将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




小心倾家荡产 身份证复印一定要加上这些

$
0
0

小心倾家荡产身份证复印一定要加上这些

近日,网上传言称办理信用卡、基金、手机、申请书业务,只要附身份证复印件的,或填写和身份证有类似作用的表格,为保障自己的权益,一定要写签注,否则就会被不法分子挪作他用。

这则传言被迅速转发并引发网友热议,不少网友表示自己长了知识,再使用身份证复印件时会多个心眼。那么,传言是否属实?身份证复印件如果保护不善会有什么后果?   

现象:多数市民并未加签注

网友总结出不加标注衍生的三大风险:到银行办理信用卡透支;被人用来开公司,并从事犯罪活动;成为诈骗分子冒用身份证的工具。

记者上网查询后得知,网友的说法并非空穴来风。据河南一媒体报道,一男子从社会上收集身份证复印件并私刻印章,以批量录入集体办理信用卡为名,办理信用卡 34 张,欠款近 35 万元,现已被刑拘。

网友提醒,复印身份证或填写和身份证有类似作用的表格,一定要写签注。比如申请银行信用卡时,要写上“此身份证复印件,仅为申请××银行××信用卡用,不得挪作其他用途。×××签名。”另外,对各类申请书内尚未填写的空格,如附卡申请、加买保险、加买第二支基金、申请手机号等,这些空格都必须打上,以免被不法业者补填它用。

在西山区便民服务中心,记者发现大部分市民在递交身份证复印件时,均未在上面签注,有些市民直接把身份证交给工作人员复印后就不管不问。当记者询问市民是否知道可以给自己的身份证复印件签注时,多数市民表示不知道何为签注。

另外,记者发现大部分审核办理业务的单位并没有认真核对身份证原件信息,而只是简单地拿着复印件就予以办理。

提醒:最好写上签注

针对身份证复印件使用中存在的可能被犯罪分子利用的问题,市民呼吁有关部门加强管理。对此,警方表示,网友提供的一些保护方式有一定效果,但最根本的还是审核单位要把好关。

云南凌云律师事务所律师孙文杰解释,我国《居民身份证法》和相关法律没有要求公民在办理相关事务时必须留存居民身份证复印件,一些行业和部门要求公民在办理相关事务时留存身份证复印件只是其行业和部门的规定,而且对于从事经营和提供服务过程中留存的居民身份证复印件负有保密义务,由于留存居民身份证复印件而产生的法律问题,相关使用部门应承担相应法律责任。

“不过,为了避免身份证复印件被滥用所引起的法律责任,给复印件加签注还是有必要的。”孙文杰说,身份证作为公民基本信息及身份证明的直接载体,应妥善保管,不能轻易外借或随意复印给第三方使用,任何私自扣押公民身份证原件或擅自使用居民身份证原件、复印件的行为均属违法行为,情况严重的甚至涉嫌犯罪。

针对公民个人信息保护的问题,孙文杰提醒:1、不要轻易通过网络,将真实姓名、身份证号、银行卡号等基本信息透露,防止被违法犯罪分子利用。2、相关部门在日常业务办理过程中所获取的公民个人身份信息,应妥善保管并加强内部监督。如擅自将公民个人信息予以公布或出售,相关部门应予以严厉查处。3、如发现个人信息被擅自使用,应及时报警,如相关个人信息被用来套取信用卡、银行卡等,应及时向相关银行反映。记者李思娴报道

网友提醒

签注要点

①写上 XX 专用,内容尽量详细,不要遮住身份证号和姓名;

②部分笔画与身份证的字要有交叉或接触;

③通常写三行,每一行后面要画上横线,以免被偷加文字;

④用蓝色的圆珠笔或签字笔签注。 

本文链接

scala 开发spark程序

$
0
0

Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情。如果你对Scala语言还不太熟悉,可以阅读网络教程 A Scala Tutorial for Java Programmers或者相关 Scala书籍进行学习。

 

本文将介绍3个Scala Spark编程实例,分别是WordCount、TopK和SparkJoin,分别代表了Spark的三种典型应用。

1. WordCount编程实例

WordCount是一个最简单的分布式应用实例,主要功能是统计输入目录中所有单词出现的总次数,编写步骤如下:

步骤1:创建一个SparkContext对象,该对象有四个参数:Spark master位置、应用程序名称,Spark安装目录和jar存放位置,对于Spark On YARN而言,最重要的是前两个参数,第一个参数指定为“yarn-standalone”,第二个参数是自定义的字符串,举例如下:

1
2
valsc =newSparkContext(args(0), "WordCount",
    System.getenv("SPARK_HOME"), Seq(System.getenv("SPARK_TEST_JAR")))

步骤2:读取输入数据。我们要从HDFS上读取文本数据,可以使用SparkContext中的textFile函数将输入文件转换为一个RDD,该函数采用的是Hadoop中的TextInputFormat解析输入数据,举例如下:

1
valtextFile =sc.textFile(args(1))

当然,Spark允许你采用任何Hadoop InputFormat,比如二进制输入格式SequenceFileInputFormat,此时你可以使用SparkContext中的hadoopRDD函数,举例如下:

1
2
valinputFormatClass =classOf[SequenceFileInputFormat[Text,Text]]
varhadoopRdd =sc.hadoopRDD(conf, inputFormatClass, classOf[Text], classOf[Text])

或者直接创建一个HadoopRDD对象:

1
2
varhadoopRdd =newHadoopRDD(sc, conf,
     classOf[SequenceFileInputFormat[Text,Text, classOf[Text], classOf[Text])

步骤3:通过RDD转换算子操作和转换RDD,对于WordCount而言,首先需要从输入数据中每行字符串中解析出单词,然后将相同单词放到一个桶中,最后统计每个桶中每个单词出现的频率,举例如下:

1
2
3
    valresult =hadoopRdd.flatMap{
        case(key, value)  => value.toString().split("\\s+");
}.map(word => (word, 1)). reduceByKey (_+ _)

其中,flatMap函数可以将一条记录转换成多条记录(一对多关系),map函数将一条记录转换为另一条记录(一对一关系),reduceByKey函数将key相同的数据划分到一个桶中,并以key为单位分组进行计算,这些函数的具体含义可参考:Spark Transformation

步骤4:将产生的RDD数据集保存到HDFS上。可以使用SparkContext中的saveAsTextFile哈数将数据集保存到HDFS目录下,默认采用Hadoop提供的TextOutputFormat,每条记录以“(key,value)”的形式打印输出,你也可以采用saveAsSequenceFile函数将数据保存为SequenceFile格式等,举例如下:

1
result.saveAsSequenceFile(args(2))

当然,一般我们写Spark程序时,需要包含以下两个头文件:

1
2
importorg.apache.spark._
importSparkContext._

WordCount完整程序已在“ Apache Spark学习:利用Eclipse构建Spark集成开发环境”一文中进行了介绍,在次不赘述。

需要注意的是,指定输入输出文件时,需要指定hdfs的URI,比如输入目录是hdfs://hadoop-test/tmp/input,输出目录是hdfs://hadoop-test/tmp/output,其中,“hdfs://hadoop-test”是由Hadoop配置文件core-site.xml中参数fs.default.name指定的,具体替换成你的配置即可。

2. TopK编程实例

TopK程序的任务是对一堆文本进行词频统计,并返回出现频率最高的K个词。如果采用MapReduce实现,则需要编写两个作业:WordCount和TopK,而使用Spark则只需一个作业,其中WordCount部分已由前面实现了,接下来顺着前面的实现,找到Top K个词。注意,本文的实现并不是最优的,有很大改进空间。

步骤1:首先需要对所有词按照词频排序,如下:

1
2
3
valsorted =result.map {
  case(key, value) => (value, key); //exchange key and value
}.sortByKey(true, 1)

步骤2:返回前K个:

1
valtopK =sorted.top(args(3).toInt)

步骤3:将K各词打印出来:

1
topK.foreach(println)

注意,对于应用程序标准输出的内容,YARN将保存到Container的stdout日志中。在YARN中,每个Container存在三个日志文件,分别是stdout、stderr和syslog,前两个保存的是标准输出产生的内容,第三个保存的是log4j打印的日志,通常只有第三个日志中有内容。

本程序完整代码、编译好的jar包和运行脚本可以从 这里下载。下载之后,按照“ Apache Spark学习:利用Eclipse构建Spark集成开发环境”一文操作流程运行即可。

3. SparkJoin编程实例

在推荐领域有一个著名的开放测试集是movielens给的,下载链接是: http://grouplens.org/datasets/movielens/,该测试集包含三个文件,分别是ratings.dat、sers.dat、movies.dat,具体介绍可阅读: README.txt,本节给出的SparkJoin实例则通过连接ratings.dat和movies.dat两个文件得到平均得分超过4.0的电影列表,采用的数据集是: ml-1m。程序代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
importorg.apache.spark._
importSparkContext._
objectSparkJoin {
  defmain(args:Array[String]) {
    if(args.length !=4){
      println("usage is org.test.WordCount <master> <rating> <movie> <output>")
      return
    }
    valsc =newSparkContext(args(0), "WordCount",
    System.getenv("SPARK_HOME"), Seq(System.getenv("SPARK_TEST_JAR")))
 
    // Read rating from HDFS file
    valtextFile =sc.textFile(args(1))
 
    //extract (movieid, rating)
    valrating =textFile.map(line => {
        valfileds =line.split("::")
        (fileds(1).toInt, fileds(2).toDouble)
       })
 
    valmovieScores =rating
       .groupByKey()
       .map(data => {
         valavg =data._2.sum / data._2.size
         (data._1, avg)
       })
 
     // Read movie from HDFS file
     valmovies =sc.textFile(args(2))
     valmovieskey =movies.map(line => {
       valfileds =line.split("::")
        (fileds(0).toInt, fileds(1))
     }).keyBy(tup => tup._1)
 
     // by join, we get <movie, averageRating, movieName>
     valresult =movieScores
       .keyBy(tup => tup._1)
       .join(movieskey)
       .filter(f => f._2._1._2> 4.0)
       .map(f => (f._1, f._2._1._2, f._2._2._2))
 
    result.saveAsTextFile(args(3))
  }
}

你可以从 这里下载代码、编译好的jar包和运行脚本。

这个程序直接使用Spark编写有些麻烦,可以直接在 Shark上编写HQL实现,Shark是基于Spark的类似Hive的交互式查询引擎,具体可参考: Shark

4. 总结

Spark 程序设计对Scala语言的要求不高,正如Hadoop程序设计对Java语言要求不高一样,只要掌握了最基本的语法就能编写程序,且常见的语法和表达方式是很少的。通常,刚开始仿照官方实例编写程序,包括 Scala、Java和Python三种语言实例。



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



推荐系统的那点事

$
0
0

推荐系统的误区

回想起来,我也算是国内接触推荐系统较早的人之一了,最近和人聊天,觉得不少人对推荐系统有所误解,以为需要多么高大上的算法才能搭建起来的,我只想说我经常说的那句话【不是这样的】,所以有了这篇文章。

第一次接触【推荐系统】是在两年前在某高校的互联网信息处理实验室的时候,那时候,【机器学习】和【大数据】都是新概念,但是差不多半年后,【大数据】的概念就开始风靡全球了,到现在已经被爆炒得面目全非。

那年还因此买了一本项亮的书《推荐系统实践》,那本书和现在的很多热门书籍一样,都是跟着概念热起来的。 虽然有一些作者自己的实战经验在里面,但是总体上来说并没有太多值得重复翻开的地方。

几乎所有宣扬【推荐系统】的人,都要拿【啤酒和尿布】,【亚马逊推荐占营收20%】之类的经典例子来说力证推荐系统的牛逼之处。到处宣扬【推荐系统】插上【机器学习】等算法的翅膀,就能让电子商务变得精准无比,能智能的猜出用户想买的东西。

殊不知,其实这两个例子和所谓的【算法】其实关系不大。

1.啤酒和尿布

首先是【啤酒和尿布】,超市的人员发现买啤酒的男人容易顺手买尿布。这其实是一种数据分析,是根据数据统计加上人工分析得出,是一种以经验来改善销售的行为。和【机器学习】【数据挖掘】等算法的关系不大。 刚接触【推荐系统】的时候,【协同过滤算法】大热, 我也曾经迷恋得研究过该算法,以为发现了什么宝贝一样。但是实际上,在工程中【协同过滤】出来的效果往往惨不忍睹,所谓的【算法工程师】每天能做的就是在那调整【协同过滤】算法的相关参数,然后看看第二天的点击率有没有上升。然后调整到最后你会发现,牛逼哄哄的【协同过滤】其实还不如简简单单的【看了又看】效果来的好,虽然协同过滤算法本质上也是一种【看了又看】的思想。

2.亚马逊的推荐系统

亚马逊的推荐系统占了营收比,我记得是20%,不知道现在上升了还是下降了。这个说辞会让很多人误以为只要你搞好了推荐系统,你的营收就能上升20%以上一样。其实不然,对于亚马逊来说,为什么推荐能起到这么高的销量,一个很重要的原因在于,【亚马逊的首页点击率高的部分位置划分给了推荐系统的】,从广告学上讲,广告位置的好坏极大的决定了广告的销量。这个很容易理解,假设你的产品的广告牌能挂上天安门城楼的话,你觉得你还需要担心该产品的销量吗?

当然不可否定的是亚马逊的推荐系统应该是很牛逼的,但是这并不说明他们采用的【推荐算法】非常牛逼。推荐系统我认为其实和搜索系统并无太大差异,我一直认为推荐系统其实只是一个个性化的搜索引擎。之前在【秘密】上很火的有个爆料是:“360搜索的Rank刚开始就是用【机器学习】的算法去做,屎一样的效果,是我把百度的基于规则的算法偷过去之后才变好的。” ,这个爆料出来不少人讽刺【基于规则】,觉得这是在黑百度的算法。 其实不是这样的,记得当时阿里搜索挖了一个谷歌搜索的员工,该人在阿里分享的时候就说过:【谷歌的搜索效果比别人好的原因就是规则库牛逼,关于算法使用的都是成熟的人尽皆知的算法,并没什么新奇酷的算法】。 可能也是这个原因,谷歌研究院的科学家几乎全是【工程师背景】出身的。还记得上次【CCF推荐系统前言讲座】,刚开始叫了几个学院派的讲师在那大讲特讲各种酷炫掉渣天的算法,然后淘宝的大数据负责人车品觉 上台之后直接来了句【我们实验出各种算法效果不太好,还不如最基本的 关联规则效果来的好】直接把前面的学院派专家们打脸打得都肿了。

我心目中的推荐系统

不管是电商,或者是新闻,都有【个性化推荐】和【热门推荐】的取舍。一个商品热门或者点击量高是有其原因的。所以将热门的东西推荐给用户是非常合情合理的,因为既然热门,也侧面说明了很大概率上该用户也会喜欢该商品。而【个性化推荐】本质上是为了解决【长尾】问题,把那些不热门的东西,但是很可能符合某特定用户品味的商品【挖掘】出来,推荐给特定的用户群。

首先,在推荐中,醒目的推荐位应该是【热门推荐】或者【人工推荐】,【人工推荐】是指比如在体育新闻中,巴萨夺冠之类的大新闻是直接让编辑来【人工推荐】即可,就是此新闻一出,马上登上头条,而不是在那磨磨唧唧的计算特征值,计算相似度,计算是否符合用户兴趣。 对于推荐中的【冷启动】,最理想的推荐就是【相关推荐】。说到这里,整个推荐系统的 80% 已经搭建完毕,【热门推荐+人工推荐+相关推荐】,这三者都是【个性化】都没什么关系,也算法关系也不大,但是这三者效果的好坏就决定了整个系统推荐效果好坏的 80% 。好多人连最基本的这三者都没有做好,就开始想一步登天,很可惜,这样的捷径是不存在的。 接下来是 20% 的【个性化】的做法,如上所说,个性化是为了解决【长尾】问题,正是因为长尾占商品的 20% ,所以在此我认为【个性化】其实也只有 20% 。要解决个性化,首先就是要对用户分析,最成熟的办法就是对用户打标签(是否让你想起来社交网络为什么经常让你选用合适的标签描述自己,没错,就是为了分析你)。

其实,给用户打标签,逼格更高的说法叫【用户特征提取】或者【用户行为分析】。说到这两个词,那些所谓的算法工程师可能就会开始扯什么高大上的算法,机器学习,自然语言处理,数据挖掘等各种算法。其实在我看来,算法很大情况根本派不上用场,我认为这方面的关键在于【数据统计 + 人工分析】。将用户的浏览记录等记录下来,统计他最常点击的东西,最常去的频道,然后给他打上这些频道或者商品的标签。或者收集更详细的信息,比如年龄,打上【青少年,男人,女人,老人】等标签,根据这些标签进行推荐。比如当推荐护肤的商品时,就可以偏向于女人,推荐运动产品时,就可以偏向于男人和青少年,推荐保健品时,就可以偏向于老年人。所以,光看年龄这个标签的维度,就可以做很多文章。所以标签库的设计和积累,是非常广泛和重要的,而这方面需要大量依赖于【人工分析】,而不是看论文调算法能做到的。 就好比现在的中文分词,拼到最后大家都在比词库的积累,谁的词库好,谁的效果就好,【搜狗】的【拼音输入法】效果好也是因为词库比别人好。

最后就是根据标签的定向推荐,这个推荐概率是有【权重设置】在里面,就比如刚才对年龄这个维度的权重,是需要给予对应的权重值,如何给定呢?其实就是【拍脑袋】,当然,如果有某些公司已经得出经验值了直接可以拿来用就会更好。但是在拍完脑袋之后需要做的就是观察点击率变化,查Bad Case,然后再对权重进行调整,也就是根据评测和反馈来调整,没有【评测和反馈】,整个系统等于是一个黑盒,谈何优化?在我看来,【推荐系统】本质上首先是一个系统,需要不断的对各种效果进行【评测】,查各种【Bad Case】,而这些都不是看论文可以学到的东西。

总结

  1. 实力派的【算法工程师】往往都是ABC[always be coding],这样的算法工程师才能根据实际问题建立模型或者建立规则库,是真正能解决问题的人。往往是一些有研究背景,经验丰富的研究员,更加重视工程,因为工程架构上一些恰当合理的设计,效果往往就能远远高过于模型算法优化。
  2. 学院派的【算法工程师】往往是为了算法而算法,而不是为了解决推荐系统的问题去找最适合算法。这也是为什么大公司经常招了一些博士毕业的算法工程师后,不是研究算法而是让他们整天在那看数据报表?【因为发现算法没啥好研究,只能让他们在那看看报表找找规律了。】
  3. 【几乎所有所谓的智能推荐算法都是花拳绣腿】
  4. 当一个做推荐系统的部门开始重视【数据清理,数据标柱,效果评测,数据统计,数据分析】这些所谓的脏活累活,这样的推荐系统才会有救。
  5. 儿童节快乐

搭建网页滤重系统的工作总结

$
0
0

趁最近工作业务不多,写篇博客关于 【搭建一个基于 网页相似度滤重的系统服务】 的相关工作。当作整理学习,温故知新吧。

项目旧况

我接手时的线上代码主要有如下特点:

  1. 旧代码的滤重效果和预期的不一致,而旧代码的作者已经离职,所以旧代码等于一个无人可以解释的黑盒。 只知道有问题,但是出了问题没人知道如何解决。

  2. 性能低下得无法容忍,由于线上出现问题没人知道如何修复,解决的办法只有重启。重启有事需要对旧数据进行重跑,因为程序运行效率低下,重跑耗时巨大,但是又无可奈何。

  3. 严重依赖数据库,几乎到处是select和insert,搞得整份代码支离破碎。甚至连数据库的表都没有好好设计,该建索引的地方没有建索引,不该建索引的地方滥建索引,等等十分拙劣的工程设计。

按我的经验判断这样处处是坑的代码,与其重构,不如我直接重写,然后我就哐当哐当开始重写了。

系统框架

项目开发语言选用 C++,功能主要分为五个模块:

  • 算法
  • 存储
  • 索引
  • 服务
  • 测试

1.去重的算法有不少,在本系统中同时支持两种算法, shingle算法和 simhash算法。前者是旧代码中本来就在使用的。 后者是本人调研出来的,google出品的,资料丰富,好评如潮。

对于 simhash和[shingle]算法的评测效果可以发现,总体效果差不多,不过对于内容篇幅较小的文章, simhash的算法效果明显优于 shingle算法。 而且 simhash算法速度远快于 shingle算法(至少3倍以上吧)。在此值得一提的是, simhash是针对中文处理的的 simhash,具体原理请见 SimhashBlog

2.对于滤重系统来说,数据的存储和索引和cache系统非常类似,不停的有新数据进来,所以也要不停的删除过期的数据,才能保证内存使用量稳定在一个可控的量级上面。

所以数据的存储采用 vector包装而成的 容量固定循环队列作为核心数据结构,在此称为 BoundedQueue。 容量固定是因为滤重系统也是个有时效性的系统,我们需要将过时的信息删除掉,所以使用 queue是天经地义的事情。

不过在此需要注意的是,在 c++stl里面的 queue的底层实现是用 deque这种双向数组,已经很大程度上提高了 pushpop的效率。 但是毕竟在 queue里的 pushpop都会直接或者间接的导致内存的申请和释放。

而用 BoundedQueue底层就是一个固定大小的vector,每次push或者pop只是循环的移动head和tail指针,无需内存分配。所以在此,使用 BoundedQueue的好处就显而易见了。

后来得知其实在boost里面有这种循环队列的结构,在 circular_buffer.hpp里面,不过其实这玩意也就那么回事,很简单,自己写也不难。

3.有比较就会有查找,有查找就要有索引。

当我们用算法把一大段一大段的文档计算成一个特征值时,这个特征值在内存中就代表了该文档。而滤重就需要对特征值进行对比,去掉那些 特征值相似的旧数据。所以我们需要对当前 BoundedQueue队列中的所有数据在 push进来的时候,进行索引的建立,然后当数据 pop出去的时候,进行索引的删除。

在本项目中,数据只需要约保留最新的100W条数据。而且特征值占用空间很小,所以直接使用c++里的 unordered_map作为索引的数据结构(不选用 map因为 unoredered_map的查找和插入效率远快于红黑树实现的 map)。

本项目索引的设计是参考了 Mysql数据库里 InnoDB索引的设计,在 InnoDB中,数据必须有个主索引 primary_key,其他普通索引都是指向这个主索引,所以数据位置统一在主索引里面存储即可。

4.在云计算时代,软件基本上都转服务化了,也就是功能以服务接口的形式提供。我个人非常喜欢服务化,服务化可以让功能和模块变得更清晰,而且可以跨语言的调用, protobufthrift都是非常优秀的 rpc解决方案。

在本项目中,使用的是 thrift来搭建服务。但是也因此发现了 thrift的一些恨铁不成钢的地方,详情见博文 ThriftBlog

5.测试主要是 单元测试性能测试。单元测试使用 google的单元测试框架 gtest。 不得不说我非常喜欢gtest来写单元测试。

稍微有点工程经验的人都明白单元测试的重要性。在工作的时候,当业务需求比较紧急的时候,我们开发也会尽量用最快的方法去开发,从而能迅速能上线。 但是上线不是一个项目完成的标志。正如有人说的, 如果一个项目上线的时候是完美的,那说明这个项目上线上得太晚了。 互联网项目讲究 持续集成快速迭代,而这一切的坚实基础就是较为完备的单元测试。

如果没有单元测试,重构时会发生的事情就是,你重构的时间用了一个月,但是重构产生的新bug需要你用半年时间来修复。

性能测试就更是必需品了,值得一提的是,重写之后性能提高至少 十倍

总结一下重写之后主要改进的几个点:

  • 模块职责清晰,代码规范,性能提升至少 10倍
  • 无需依赖数据库。还是那句话。 没有依赖,就没有伤害。
  • 丰富的单元测试才能保证项目可以持续集成,快速迭代。
  • 运行稳定,再也没有那些乱七八糟的未知bug了。

感想

1.有人说 写代码write less不是重点,关键是read easy。。 读书的时候我不能很好的理解这句话,觉得代码优化就是尽提高代码的复用,从来达到 write less的目的。 在公司干活了才能深刻体会到,把一个系统服务写得 read easy是一件更需要功底和经验的事。

记得当初给同事讲解整个项目架构的时候,同事听完说表扬说代码逻辑很清晰。 为了让代码 read easy,确实多花了我不少工作时间,但是看来是值得的。

2.写程序时的 开源心态:我一直尽可能的把每个项目都当成开源项目来写(哪怕由于公司的原因无法开源)。

它的好处就是:当有些功能模块【既可以写的很丑陋难懂但是很快就能写完,又可以写的清晰易懂但是需要废点脑筋】的时候,你会变得尽可能选择后者。 因为开源的最大好处是会让作者对脏乱臭的代码有 羞耻感,比 codereview的效果甚至都好。

3.幸亏当时果断重写旧项目,否则我到现在估计还在修旧代码的bug。。

基于storm的在线关联规则

$
0
0

    基于storm的在线视频推荐算法, 算法依据youtube的推荐算法  算法相对简单,可以认为是关联规则只挖掘频繁二项集。下面给出与storm的结合实现在线实时算法 , 关于storm见这里。首先给出数据流图(不同颜色的线条代表不同的数据流。在storm里面bolt也是可以声明数据流的。)

    

    关联规则挖掘数据项的时候,有事务的概念,这里的事务的定义为:给定时间窗口内用户看过的视频集。所以,我们需要这样一个bolt,根据实时日志收集每个用户看过的视频集----user_videos aggregate bolt。 我们怎样挖掘频繁二项集呢?其实就是视频对共同出现的次数,当视频a和b被共同观看的次数(用户看了视频a又看了视频b)大于某个阈值的时候,{a , b}就是一个频繁二项集。

所以我们定时的输出a:b这样的视频对,然后对其计数即可。这个任务是由video_pair counter bolt完成的。这样频繁项挖掘基本完了,如果对于推荐可能需要再走一步:对于看了a的人推荐b 的可信度有多高?如果为a推荐了b,那么对于b的曝光来说提升度是多少呢(可以这样理解,b本身很热门,你再把b推荐出来对于b本身曝光量没有多大作用,这也叫打压热门)? 所以我们需要一个计数器,里面有每个视频被观看的次数---video_counter_bolt。这样,我们就有了youtube算法公式所需要的所有值。

     storm本身是流式的,我们这里需要用到统计用户看过的视频集,所以得有一个池子,不停的收集用户看过的视频,定时的放水(定时放水的任务就有timed_notifier_spout完成)。所以整体的流程如下描述:

1、rt-log spout按user分组,将数据流推给uva-bolt.

2、tn-spout 会定期向下游推送时间窗口关闭的通知

3、uva-bolt里面维护一个map , 里面是用户到其观看过的视频集的映射。它第接收到一条日志就会更新这个map , 同时向计数器vc-bolt发送一条播放数据.当收到tn-spout的通知时,便会将map里面的数据构建成视频对,分组后推送给相关的vp-bolt.

4、vp-bolt 也会维护一个map , 用以视频对的计数。 当收到tn-spout的通知时向vc-bolt发送这些统计信息,并清空这个map.

3、vc-bolt内容也维护一个map , 里面是视频到其它被观看次数的映射 。它每接收到一条日志都会分析日志的类型, 如果是计数类型的就会更新这个map .如果收到vp-bolt的数据,便会计算两两视频的相似度(youtube的公式)。

               整个topology结构代码:

      

<span style="white-space:pre">		</span>TopologyBuilder builder = new TopologyBuilder();
	        SpoutConfig spoutConfig = new SpoutConfig(new ZkHosts(conf.getString("zk.server")),
                                    conf.getString("topic"),conf.getString("zk.path"),conf.getString("myid"));
	        spoutConfig.scheme = new NginxLogScheme();
                builder.setSpout("nt-spout" , new NotifierSpout(900) , 1);
	        builder.setSpout("log-spout", new KafkaSpout(spoutConfig), 3);
	        builder.setBolt("uv-bolt", new UserVideoAggregationBolt(), conf.getInt("blot.threads"))
                    .fieldsGrouping("log-spout" , new Fields("cookie")).allGrouping("nt-spout" , "nt");
	        builder.setBolt("vp-bolt", new VideoPairBolt(), 3).fieldsGrouping("uv-bolt" , "vp" , new Fields("vidPair"))
                    .allGrouping("nt-spout" , "nt");
	        builder.setBolt("vc-bolt", new VideoCountBolt(), 3).allGrouping("uv-bolt" , "vc")
	        	.fieldsGrouping("vp-bolt" , "vc" , new Fields("vidPair"))
                .allGrouping("nt-spout" , "nt").addConfiguration("mysql.host", conf.getString("mysql.host"))
	        	.addConfiguration("mysql.usr",conf.getString("mysql.usr"))
	            .addConfiguration("mysql.pass",conf.getString("mysql.pass"))
	            .addConfiguration("mysql.port",conf.getInt("mysql.port"))
	            .addConfiguration("mysql.schema",conf.getString("mysql.schema"));
                builder.setBolt("rec-redis-bolt" , new RedisRecBolt() , 1).allGrouping("nt-spout" , "nt")
                    .addConfiguration("mysql.host", conf.getString("mysql.host"))
                    .addConfiguration("mysql.usr",conf.getString("mysql.usr"))
                    .addConfiguration("mysql.pass",conf.getString("mysql.pass"))
                    .addConfiguration("mysql.port",conf.getInt("mysql.port"))
                    .addConfiguration("mysql.schema",conf.getString("mysql.schema"));

注意事项:

1、bolt的outputcollector对于并发可能报错,需要一个定制的线程安全的outputcollector 。

2、这种实现方式属于试验性,不知其是否科学

3、storm会自动重启bolt , 理由是worker heartbeat timeout , 引起这个的问题可能是worker gc的问题。因为我这里有很多的内存缓存,所以会出现频繁full gc

                              以至于超时。这种频繁的full gc很可能是由于定期向下游放水时短时间内生成大量对象造成的。

4、以上代码仅限结构参考,没有整理。我们用到了kafka.

                


    

作者:huilixiang 发表于2014-8-8 17:34:46 原文链接
阅读:57 评论:0 查看评论
Viewing all 15843 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>