Skip to content

Categories:

兴趣与坚持

       对一年的研究生生活进行了一个整理总结,精炼成一句话就是:在迷茫中前进。这一年收获很多,在北京眼界变得开阔,看到了很多令人兴奋的机会以及激烈的竞争,自己在摸索一些方向以及方法。总体而言是令人满意的,但是还是隐隐感到焦躁。焦躁的地方在哪里呢?还是延续了以前的感受,在学校里面如同雾里看花,迷迷糊糊,看到别人都已经在追寻梦想的道路上飞奔,而自己却还蓄力待发,发号枪一直不响而自己也没有清晰地看到奔跑的道路,你说如何不焦躁?

       不过终究是一个研究生了,还是学会用一些系统分析的方法,以前也一直思考过这个问题,而这一周正好看到了李笑来老师的《把时间当做朋友》,顿时有醍醐灌顶的感觉。里面有几个观点讲得非常好,李老师说兴趣并不是最重要的,因为有时候你所谓的兴趣其实不是你真实的兴趣,而是你对于现在生活的不满以及在现有工作的挫折中的一种心理反馈。很多时候你并不是对一件事情感兴趣,而是没有做好现在的工作,在现在的工作中受到挫折的一种自我逃避的心理反应。所以,下次你再说你对什么感兴趣的时候,请先检讨自己是否没有很好的完成现有的工作。而且我认为一个真正优秀的人应该是能够积极良好地完成现有工作的人,所以不要逃避你在做的事情,用上脑子,很好的完成它,这才是证明你自己的机会!

       同时,坚持是很重要的。我以前一直有这个观点,也被李老师验证了O(∩_∩)O。你做的事情并不在乎对错与否,事实上在我们这个年龄段在我们这个智力范围内,不会做一些傻到吐血的决定,往往失败的原因是你对于决定的纠结以及半途而废。我以前很大的一个毛病就是什么东西都喜欢,什么东西都浅尝辄止。对某个东西很感兴趣,然后研究了一下后发现挺麻烦的,就去涉猎其他事物了。这样做的结果是什么都会一点但是什么都不精通,反倒是大把的时间就这样白白浪费了。所以,要做出改变,做一个专一的人,认真把一件事情弄清楚弄明白,再去触类旁通,效果会好很多。

Posted in Tech.

忍耐力与若干

关于忍耐

算下来,铁齿铜牙已经3个月了。刚开始戴的时候那个难受啊,嘴里包着一堆铁箍,还要上2个橡皮圈,真是生不如死,第一个星期只吃了2包泡面,喝了一大袋牛奶。饿得掉渣了。

可是还是熬过来了,而且已经很习惯了。吃饭什么的已经不会有不适感。

封闭开发三个月过去两个月了。每天早9晚9工作9小时,周六也要加班,动不动开会演示每天坐在实验室coding,习惯了上半年的和谐生活的我,一开始郁闷得要死,现在也能很平和地和同学们说“我封闭开发,暑假不回去”了。

所以说人是韧性极强的生物,一些你认为不敢想象的可怕的事情,真正发生了的时候,虽然开始会很痛苦,但是你总会去适应它,并且接受它(当你确切无法改变它的时候)。所以,你认为难以熬过的事情总是能够熬过的,你认为后果严重的事情总是会有一个结果的。无需恐惧无需害怕,安心接受安心等待。

最近看到很多不和谐的新闻,不真实感越发严重。群里面有同学说,这个世界太复杂,我们只能让自己更加强大。很有道理,无力改变的事情你再怎么愤怒再怎么议论也没有意义,光说不练还不如不说。只有在磨练中让自己强大,不仅能力强大而且内心强大,才能给自己一个独立人格独立空间。

思考太多没有益处,更重要的是用思考去指导实践。光说不练太可怕了。切记。

Posted in Tech.

每周自省–2010-07-23

最近一直在想的问题是,到底什么样的生活才是我们这一代理想的。
对比高中那会,虽然很辛苦很累,但是有一个很实在的奋斗目标,所以精神很充实饱满。可是现在,同样很辛苦很累,却时常迷失自我,不知道未来的路如何去走。没有选择是痛苦的,但是选择太多同样是痛苦。没有人能够达到无限的自由,就算达到了无限自由,那也是令人揪心的。
最近看到太多光怪陆离的事情,总让人错觉在做梦。这是一个真实国家应该发生的事情么?很无奈,也很无助。但是人的忍耐能力是无穷的,人是具有可怕韧性的生物,所有的所有终将被承担并且包容。坚定自己的脚步,每次迷茫的时候总是得告诉自己,坚持,就这样了。剩下的事情就只能交给上帝去解决了。

Posted in Tech.

每周自省–2010-07-18

柏拉图这么说的,每个人都是活着自己的精神洞穴里,靠着洞穴外阳光的照射看到自己的洞穴,然后就以为这是完整的世界。
每个人都是浅薄而自满的。总是以自己的价值观来轻易地评判世界,给别人下定义,然后被别人定义。如何摆脱这种浅薄和自满,唯有自省以及跳出自己的洞穴,看到外面的世界。
因此就有了这个东西,每周自省。希望把自己每周的收获、感触、犯的错误、有的成就,做一次自省,让自己清晰明白自己在做什么在想什么。想着这样的事情就令人兴奋,嘿嘿。

OK,第一周
这一周最大的感触就是不想去做纯技术的工作了。虽然自己比较适合做技术,可是在中国这种环境下,结合自己的性格,纯技术的工作对我而言,恐怕真是不太适合了。我一直信奉一句话,不管做什么事情,不管不顾做下去,终究会有收获的。许三多都能成功,何况我等?
我还是喜欢跟人打交道,喜欢涉及面更广的领域,喜欢做一些不用循规蹈矩的事情,所以未来的日子,恐怕真得做出一些改变。
不过未来的道路总是由各种机会组成的,说不定有一个很好的技术工作,我也就去了。嘿嘿,不过在这之前,做好准备,做足准备,足矣。
另外的感触是,技术的东西很基础,也很重要。但它毕竟只是个基础。更重要的是你的思想高度以及方法论。方法很重要,优秀的人做什么都很成功,因为他们善于在做的事情中总结经验教训,有自己的一套方法并复用到其他事情上。认真做自己在做的事情,然后持之以恒,就OK啦。

还有,不仅要做事情,还要让别人知道你在做事情,否则,自己累死累活,老板却一无所知还以为你啥都没干,那就太尴尬了。自勉自勉!

Posted in Tech.

被墙2月,泪流满面

与某个天杀的不和谐的人共用了一个IP,因此被墙达2月之久。。
也是一直倦怠,没有更换IP,现在回归此处,撒花~
最近忙的天旋地转,各种事情。。不过学习是要继续的,接下来的几个月安排安排
python源码剖析——读了一小半,虽然生涩,重新捡起C,但是底层的东西看着确实很有用处
论文阅读——继续阅读分布式存储方面的论文,dynamo,google file system,Bigtable
沟通能力与表现能力——太匮乏了。。。太匮乏了。。- -恶补ing

Posted in Tech.

infoQ qclub归来

昨天听了一场很好的演讲,趁着还有记忆给记下来。

    首先是百度的马同学讲大规模数据处理。

这个题目就是我的大爱啊,马同学所在部门使用的是HDFS来做文件系统,使用HBase做数据存储系统。

HDFS的优点在于容错性强、无需人工干预、扩展性好(同时需要操作简单)、数据可用性高、服务可靠性高。HDFS是主从结构的设计,有namenode跟datanode,namenode负责管理文件系统的命名空间,简单而言就是找到datanode,datanode负责具体的数据访问。但是namenode是单节点结构,因此可能存在单点失效的问题,不过据介绍百度的namenode节点任务比较简单访问并不高,因此崩溃的现象还没有发生过,而且namenode使用了32GB的内存(百度真有钱),因此暂时能够应付目前的形势。不过HDFS的分布式namenode是目前一个比较热门而且有难度的问题,百度也在这方面做了一些研究。提到了一些hadoop的研究热点,包括HDFS namemode的分布式改进、HDFSd datanode读写异步化、MapReduce的job tracker分布式改进、MapReduce的作业和任务调度器等等。

然后马同学介绍了下百度目前的数据现状,真是可怕啊= = 百度的存储超过了20PB,每日新增数据10TB,每天处理的数据超过1PB,每天提交10000+次作业,百度使用了2000多台服务器节点,每台服务器是2*4 core,12*1TB disk的配置。。

同时介绍了百度使用的分布式计算方法,百度综合使用MPI以及MapReduce,在数据量不大,计算相关性强,计算复杂的场景中使用MPI,而在相反的场景中使用MapReduce。

最后马同学介绍了他们在做分布式的过程中总结出的一些经验与原则:

  • 大规模数据处理要求容错性好
  • 规模应该能够通过扩展机器数量来达到(也就是说这个问题要能用钱来解决,能用钱来解决的问题对于百度而言就不是问题)
  • 为了满足容错性和扩展性,需要放弃兼容性
  • 成熟系统同时使用传统方案与新方案
  • 不做不能做的做不到的事情
    • 第二个report是Freewheel的人讲互联网应用服务扩展,实际上就是讲他们公司的一些实现。

    Freewheel以前一直只有所耳闻,今天听他们报告,感觉还是挺开放谦逊的。能说的东西不多,关键是他们的商业模式很好,抓住了2点,syndication video economy和TV everywhere.这两句话我也解释不太清楚,总结而言就是做服务已经不行了,因为你想到的服务已经都被人做完了。现在的蓝海在于服务商的服务商,或者说是将2个服务商串联起来的服务商。

    我总结下来,听完这2个report,发现公司做事情跟学术派的差别太大了。学术界都是讨论某个技术好某个技术坏,拥护某一种语言的同时将另一种语言打入冷宫,而公司做事情就很pragmatism了,公司都是需求驱动,先有一个朴素的现有系统,系统出现问题的时候对其进行一些研究分析,做到够用就好,而且不跟风不追潮流(虽然卖产品的时候很是炒作概念,但是自己内部实现的时候很低调很务实),只使用在特定场景下合适的技术。一般不会做太多前瞻性的工作,一则没有精力,二则没有这个需求,做出来的东西可能根本适应不了。Pragmatism ——技术公司的核心。

    Posted in Tech. Tagged with , .

    10年4月工作事宜以及相关

    最近事情挺多的,基本属于瞎忙活,总结了一下稍微有点成果的事情与想法。

    首先学习了flex,flash前端脚本语言。总结使用体验就是,简单易用、性能低劣,维护困难。这可能是大部分脚本语言的通病吧,脚本语言确实在处理复杂场景的情况不如笨重的java以及C,但是在实现小型原型系统中,它的开发效率比后者要强很多。所以语言都是各有千秋的,关键是使用场景以及自己想要进入的领域。

    其次决定以后对于语言的使用应该是以python这样的脚本语言为主,同时跟进C以及java的技术相关。熟练掌握这三门语言,将会受益无穷。对于我而言,更喜欢做一些后台开发的事情,追求simple is beautiful 以及够用就好的设计哲学。因此,我热爱python,一些大型语言我是真不喜欢,但是前面也说了复杂场景需要的问题,因此,使用C以及java是不可避免的,这种大型语言总结而言就是得到越多,付出越多的吧。。

    再次,语言是很低级底层的东西,一个计算机行业的人不应该是一个简单的coder,应该是有严谨以及创造性的逻辑思维,也就是说需要有解决问题的能力。解决问题的能力不仅仅涉及解决一个程序问题,在协作开发中,更应该是与人沟通交流的能力,自我展现的能力(有时候我真觉得展现>实现)。这个是一个素质的问题,不是编写多少程序就能解决,应该是在日常生活中,在处理问题的过程中得以提高。而且,最近看的书籍都是在反复强调,不要让随机事件去左右你的选择,去代替你的选择。而应该是自己主动去作出选择作出调整。因此,应该自己主动去寻找处理问题的机会,主动去寻找挑战以及压力,从而快速提高。

    看了看,都是一些想法,没有什么行动。好吧,五月份,let’s do it!!

    Posted in 杂谈.

    [mongoDB VS Mysql]插入五百万数据集(python)

    前文已经讲述mongodb相关,现在来构造数据提供mongo与mysql的性能对比。
    小的数据集对比没有多大意义,因此构造一个五百万的数据集实现对比。
    数据格式是    ’id‘  ‘num’  ‘name’  ‘rate’
    其中id是一个唯一标记的递增数字,num是一个随机整数,name是一个随机长度为3-8的字符串,rate是一个随机浮点数。

    那如何构造呢?其实这件事情说起来很简单,也没有技术含量,但是在构造的过程中我发现了python很多优秀的语言特性,所以其实这篇其实是在说python,哈哈。
    首先,需要引入相应的库。python下有对mysql操作的MySQLdb库以及对mongo操作的pymongo库(话说,python下的各种开发库相当全,尤其是数学运算,下次要用用)

    import pymongo
    import MySQLdb
    

    现在开始构造数据集,这个太简单了,只有name(随机长度为3-8的字符串)的构造稍微麻烦,,但是在python强大的字符串处理能力面前,一切都是尘埃。。。3句话实现该功能,嘿嘿

    l = list('abcdefghigklmnopqrstuvwxyz')
    tmp = random.randint(3,8)
    name = string.join(random.sample(l, tmp)).replace(" ","")
    

    怎样,强大吧?
    然后把相关处理函数都写了,很简单,就是连接数据库,执行插入操作。mysql使用游标执行sql语句,

    value = [id,num,name,rate]
    cursor.execute("""insert into test_mysql values(%s,%s,%s,%s) """,value)、
    

    而mongo是采用键值对映射插入

    dic = {'id':id,'num':num,'name':name,'rate':rate}
    posts.insert(dic)
    

    很快,一个写入函数就完成了

    def WriteFilefunc():
    connection = Connection('localhost', 27017)
    db = connection['test-MongoDatabase']
    posts = db.posts
    
    conn = MySQLdb.connect(host="localhost", user="***", passwd="***", db="test")
    cursor = conn.cursor()
    
    for id in range(0,5000000):
    num = random.randint(10,1000)
    l = list('abcdefghigklmnopqrstuvwxyz')
    tmp = random.randint(3,8)
    name = string.join(random.sample(l, tmp)).replace(" ","")
    rate = random.random()
    #mongodb insert
    dic = {'id':id,'num':num,'name':name,'rate':rate}
    posts.insert(dic)
    #mysql insert
    value = [id,num,name,rate]
    cursor.execute("""insert into test_mysql values(%s,%s,%s,%s) """,value)
    
    f.close()
    conn.close()
    

    但是这样的程序看上去复杂不易维护,正好在看重构这本书,现学现用将程序拆分成对应函数WriteFile2MongoDB以及WriteFile2MySql,这样主程序就变成这样了

    def WriteFilefunc():
    WriteFile2MySql(5000000)
    WriteFile2MongoDB(5000000)
    

    好,开始执行,很快发现这段代码执行效率很低,因为是顺序执行5000000万条插入,程序很容易就陷入假死状态。怎么办?多线程!
    构造一个写入类,实现多线程。但是我又不想对现有代码进行太大的改动,希望复用现有程序。通常用java的思想方法,应该先写一个接口,然后不同的实现不同方法的子类通过这个接口来调用相关的功能,而且为了复用可能还要用到相关设计模式,处理起来相当冗余繁琐。那python能够如何处理呢?强大到何种地步呢?
    只需要把处理函数加上一个self标志,表明它是类函数,就能直接使用!构造一个简单的线程类

    class WriteFile(threading.Thread):
    def __init__(self,n,wf):
    threading.Thread.__init__(self)
    self.num = n
    self.writefile = wf
    
    def run(self):
    self.writefile(self,self.num)
    

    主程序如下

    def test():
    num = 5000000
    wMongo = WriteFile(num,WriteFile2MongoDB)
    wMysql = WriteFile(num,WriteFile2MySql)
    wMongo.start()
    wMysql.start()
    

    这样就能直接运行了。。ORZ。。真是爽阿。。你想想,用java你得堆垒多少代码,得花多少心思才能达到这样的目的。。。赶快抛弃java,投奔python吧= =
    生产力万岁~~~

    Posted in Tech.

    [mongoDB VS Mysql]mongoDB介绍

    最近在研究nosql相关,重点考察了mongoDB,一个用C++写的分布式文件存储系统。
    mongoDB是一种介于关系型与非关系型数据库之间的产品。具有可伸缩性、高性能、开源以及面向文档的特性。
    mongoDB使用类似于json的文档模型(bson)来存储数据,因此它的存储结构不是如同关系型数据库一样基于表的schema结构,而是如同json一样,基于键值对的KEY-VALUE STORE。因此它的数据查询都是如同哈希表的哈希映射得来的(当然具体实现会比简单的哈希复杂)这一点很诱惑我,因为我一直觉得对于习惯面向对象的程序员而言,想要真正深入了解sql这样的数据库语言,熟练掌握sql后台的配置,真是一件痛苦而别扭的事情。我在国外的邮件列表里问,为什么要使用mongodb而不是mysql,给我印象最深刻的回答是性能并不是他最看重的,他最在意的是数据库操作以及集群操作节点增删的简易性。他说他学mongodb只用了一周时间就能熟练操作,但是对于sql而言,要设计定义良好的schema模型,然后在实现后期对模型进行改动,都是很痛苦的事情。也就是说,sql太笨重,虽然功能健全,但是正是这种健全导致了系统易用性的下降。
    好吧,讲了这么多,对mongoDB有兴趣的同学可以去看看官网http://www.mongodb.org/ mongoDB做得很好的一点是驱动很全,基本上我们熟知的语言都有相关驱动以及文档介绍,我所喜爱的python也不例外。

    下篇,我会分析mongoDB跟mysql数据的构造。很有趣哦~

    Posted in Tech. Tagged with .

    两道google面试题

    最近看了两道google的面试题,很有趣很好玩

    1.

    给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)。

    2.

    给你一个数组A[1..n],请你在O(n)的时间里构造一个新的数组B[1..n],使得B[i]=A[1]*A[2]*…*A[n]/A[i]。你不能使用除法运算。

    暂时把第一题想出来了。在不知道N的情况下要动态的求k/n的概率,这样的问题以前从来没有想过,但是马上想到是用概率论的方法解决。想了几天终于理清思路了。关键是要引入状态量。

    假设P(i)是链表长度为k+i时取出元素的概率,很明显按照题目而言p(i) = k/(k+i),并且p(i+1) = k/(k+i+1),关键是从p(i)中推出p(i+1)。

    如图可知,绿色元素(第k+i+1个元素)被选中的概率为p(i+1) = k/(k+i+1)。而蓝色元素(前面k+i个元素)中选出来的k个元素已经有一个先验概率为p(i),因此蓝色元素被选中的概率p(i+1) = p(i)* X

    X即为我们所求。考虑当绿色元素是否被选中作为区分,当绿色元素被选中时,蓝色元素中只能选择k-1个元素,此时概率为k/(k+i+1) * (k-1)/k;当绿色元素没被选中时,蓝色元素中全部选择,此时概率为((k+i+1) – k)/(k+i+1) = (i+1)/(k+i+1)

    因此按照这种方法选中蓝色元素的概率为p(i+1)= p(i)*( k/(k+i+1) * (k-1)/k +(i+1)/(k+i+1) ) = k/(k+i+1).所以只需在遍历链表时每次前进一位就先按照概率是否选取当前元素,如选取,则随机替换掉前面已选取的元素即可满足题意。

    补上第二题答案
    我没有想出来,林同学帮助解决了,思路很清晰。
    要想在O(n)时间内构造,肯定只能遍历数次,而且遍历的过程中应该是种递进的寻找答案的过程。
    答案是什么呢?对于B[i]而言,答案是两部分的乘积,A[1]*A[2]*…*A[i-1]以及A[i+1]*A[i+2]*A[n].现在的问题是如何在遍历的过程中以递进的形式找到这两部分答案。
    由此问题变得很清晰了。答案的两部分都具有一种特性,假设前半部分答案是C[i],后半部分答案是D[n-i],那么C[i+1] = C[i]*A[i],D[n-i-1] = D[n-i]*A[i],B[i] = C[i]*D[n-i],由此,递进的模型就出现了,因此通过3次遍历就能求出所有答案。
    这个问题的精妙之处在于清楚地认识到要想在O(n)时间内解决问题,只能通过递进的方式来达到。因此考察解的特征,从而得到最终方案。

    Posted in Tech.