抽出一点时间来

最近三个大作业的deadline们接踵而至让我喘不过气来,上周末好不容易休息了三天,回家参加了我哥的婚礼,一点代码都没写。于是这周又要开始码代码的日子了。

经过了暑假的实习,这个学期在两个实验室的“科研”经历,还有这堆大作业,尤其是软件工程的洗礼,我最初的想法——上个研究生,然后去一家大企业赚够钱,然后回家养老——正在一点点的动摇。

因为我感觉,工业界并没有想象中那样美好。上午刚在人人上看了篇日志(不好意思我依然对人人上瘾),讲了一个gpa2.5的人当上了某著名大学的终身教授的事。文章里有一句话:“ I was more interested in doing things RIGHT than doing them NOW, which is bad news in the software industry.”我感觉这句话也正是我想说的。以前,我感觉所谓搞科研就是不停的申请项目,然后申请到手后就不必管它的质量,只管报销捞钱晋升即可,更看重的是"doing them now";我也感觉所谓工业界的计算机领域才是真正改变世界的地方,更看重的是"doing them right"。现在想来,这种想法完全是错误的。

在(某些)企业里,更看重的大概是"doing them now":上面给你下达一项任务。对于这项任务,你可能有很多很新很好的想法,你希望按照你认为正确的方法去做,但是boss会告诉你,事实证明他的方法才是正确的。deadline就在眼前,你也只好服从命令,做个机器。

而在(某些)研究机构里,说不好它们到底看重哪个,但是与企业显著不同的是,不会有那么多的“经验”压力。对于一件事,你无需按照经验去做,只要按照正确的方法去做即可,最后如果比经验的效果还要好,不会有人批评你。与企业更加不同的是,人少,沟通不会太复杂,因为某个研究方向可能参与的人只有四五个人,代码量也少很多,更多的是脑子里的东西和忽悠出来的东西。

当然,两者都有的特点也有很多,比如说累,不管是体力还是脑力。

于是,我越来越倾向于走科研路线了。但是,走自己喜欢的科研路线,简直比找到自己喜欢的公司,拿到自己满意的薪水,还要难——似乎只有等到你混出来了,当了个小头头,自己才有权利将自己的那些小想法一一实现(当然不必亲自实现)。更可能的是,跟着老板屁股后面,抢项目,写论文,浮躁的进行着所谓“科研”。

所以,在不久的将来,脑子一热去读个phd神马的可能也是一个不错的想法。当然,去一个理想的企业也不错。虽然压力可能大一些,但是薪水多啊,钱才是第一生产力啊。

有关高性能计算

在百度实习的两个多月,在技术上还是有很多收获的,首当其冲的便是对高性能计算方面有了一些见解。

大约在四十多年前,我们的计算机还只是单线程的——它们顺序的读程序,然后交给CPU进行计算,偶尔跳转到别的地方去读写数据。随后,一个叫做操作系统的东西出现了,更高级的操作系统支持多任务,一开始的多任务很粗糙,只是把每个任务分成几个定长的时间片,然后备份CPU寄存器里的数据,轮换各个任务罢了。然后,多任务变得越来越人性化——如加入了优先级,对IO任务和计算任务加以区分等。多任务也成就了日后的线程和进程。

随着计算能力的不断提升,多任务切换所需的额外花销也就不算什么大事了。但是,单个CPU的计算能力在近些年增长缓慢。于是,我们很容易的想到,使用多个CPU去解决问题。但是,一个已有的程序更改成为可以并行计算的程序时很困难的。还有,CPU的数量是未知的,为了适应越来越多的CPU并不浪费其能力,我们建立尽可能多的线程/进程(远远大于CPU数),并行的处理任务,操作系统会帮我们处理它们之间的切换。网络的兴起使得服务器大多采用了这样的方式:每个请求都是一个线程,它们互不干扰的运算、存取、返回结果。

这里便出现了三个问题:一个是怎样把已有的程序改造成为并行程序。这让躲在学术圈的函数式语言得以大放光彩。函数式语言的几乎所有语句都是由函数组成的,而且,每个函数的调用不会修改已有的数据,也就是说,一个对象被创建后,便不会被修改。这样,首先它是线程安全的;另外,它可以在不修改代码的情况下,自适应多CPU的情况,只需将不同的函数调用分配到不同的CPU中去便可以了。但是,真正的函数式语言比较理想化,不是十分浪费内存就是十分浪费计算量,虽然写起来和听起来很好很强大的样子。所以,比较新的函数式语言,如Scala等,也兼容普通的命令式编程和面向对象的思想,虽然浪费了一些并行性,但是最近也越来越火。

第二个问题是,怎样让这些并行运行的线程之间进行通信。并行计算中的一个很常见的东西是锁,或者CAS之类的替代品,因为多个线程同时操作同一个数据时会出现难以预料的后果。但是,锁的使用一方面带来的死锁的现象,另一方面则降低了效率,就算现代的CPU硬件支持某些指令,但是在某个线程对某个对象上锁的过程中,另一个也需要访问该对象的线程便只能干等着,这浪费了CPU的很多性能。多个机器的情况下,频繁的数据通信会加重网络的负担。

第三个问题是,IO。CPU那点时间和IO比起来不值一提,对内存的读写、对硬盘的读写、网络的访问,这些都时时刻刻影响着程序的效率。并行计算虽然解放了CPU,但是并没有解放IO。

这三个问题又衍生出很多其他的问题,比如说,在多个线程在同一个CPU中运行时,CPU内部的寄存器、Cache都会被更换,这在线程数比较少的时候不算什么,但是线程数会尽可能的多,则线程之间切换的花销就不能被忽略了而且功耗也是一个问题。线程过多、IO、锁也时时刻刻影响着机器的稳定性;再比如,有些任务是IO密集型任务,有些则是计算密集型任务。我们需要把它们放到适当的机器中运行,不然则会产生浪费。但是,一个线程所在的CPU是随机的,甚至它所在的机器都是随机的。这将会造成一定的浪费。

在这些问题日益增加的情况下,我们勤劳的劳动人民想出了很多的办法。比如说,为了区分IO密集型任务和计算密集型任务,对机器们进行统一个管理和调度,把新的IO密集型任务放在计算密集型任务比较多的机器中,反之亦然;再比如说,关于线程过多计算量过大、机器容易不稳定的问题,通过减少高性能的机器而增加更多的普通机器,来让任务们各得其所。

但是这解决不了根本问题,那就是,本来计算机就是为顺序执行程序而设计的,但是我们为了让计算能力提升而逼迫程序以一种完全不同的方式去运行,这种背离了计算机本身运行方式的计算方法肯定会存在问题的。于是,我们便从另一个方向去思考这个问题:为什么不让一个机器(CPU)以它最大的可能去运行一个它最擅长的任务呢?正如,我们要分别考语文数学英语三科,我们为什么要让一个非常牛的人用两只手加一只脚分别写三科试卷,而不让三个分别擅长语文数学英语的人分别用一只手去写他们擅长的试卷呢。

所以,我们的思绪回到了几十年前,那个没有操作系统的时代,计算机是那样的高效。我们希望回到过去,让每个CPU执行单一的任务,不同任务之间采用无锁的通信方式。但这显然需要很多的工作,比如创建一个崭新的操作系统。但是,现在的许多计算框架已经有这个趋势了:它们只有几个为数不多的线程,线程数根据CPU个数而定,而且各自分工明确;每个线程都拥有一个队列或其他容器,用来进行线程之间的通信;一个机器与另外机器通信后还可以继续执行它后面的任务,也就是异步执行;它们可以很容易的移植到多个机器上,每个机器做特定的事情。

通过这样设计出的系统在性能和稳定性上都优于以往的基于多线程的系统,可以说,这是高性能计算的趋势。但是,它似乎仍然没有解决一个问题,那就是锁和IO,数据通信和对数据的写入成为了瓶颈。但是,锁是用来干啥的呢?一是用来在写数据的时候,不与同时进行的其他写数据的操作冲突,二是在分步操作数据的时候,不被同时进行的其他读数据的操作读到中间结果。但是,我们目前的存储器支持的操作都是单线程的,那我们对其的操作为啥要并行呢?所以,我们可以让一个机器只负责IO,它也有一个容器用来盛放其他机器对它的请求,它依次执行并把执行结果通知拥有请求的机器,它不需要很强大的CPU。如果IO的负担过大,可以把它分为好几个这样的部分。关于数据通信,也就是各个CPU之间的通信。在同一个机器上可以通过共享内存,可那就需要锁,于是,一些无锁队列的实现方式最近火了起来;但是,解决这个问题的终极方法只有一个,那就是制造出适应于并行计算的存储器。不同机器只能通过网络,可是网络不可靠,而且传输速度有上限。于是,很多分布式计算的理论出现了。

我在百度做的东西,Gearman和Kestrel,都采用了这样的思想。

所以,高性能计算的未来不是并行运算,而是分布式运算。

以上有感于12306...

沙河这两年

还是决定写篇文章来祭奠一下那逝去的沙河。时光荏苒,岁月如梭,转眼间,我们已然搬入了学院路校区。
在保送的时候我还不知道前两年要去沙河校区,只是那巨大的新主楼在夜晚闪闪发光,才吸引我最终选择了北航。但是计划不如变化,在我第一次踏入沙河校区的那一刻我便后悔了。这不是校区,甚至不是一个村庄。我也曾吐槽过沙河糟糕的环境和交通,但是蓦然回首的时候却也发现它寂静的美;也曾孤单的住在这荒无人烟的地方,却还是想再享受一次那一份平静的心境。直到离去的时候,看着那熟悉的宿舍和空荡荡的楼道,就像即将沉默的泰坦尼克,不忍离去却又不得不离去。
不得不说,学校是十分重视沙河校区的建设的。从宿舍、食堂、教学楼等等地方,都可以看出来学校一直在有条不紊的建设着沙河校区。当然,作为第一届沙航的学生,前两年正好赶期也只能自认倒霉了。现如今回到了学院路校区,虽然学校在安排学院路宿舍方面有欠妥之处,但对大多数人应该都影响不大。比较而言,学院路校区的环境要差了很多,尽管,在沙河没有这么便利的交通,没有这么多的食堂,这么大的校园。
在沙河度过了两年难忘的岁月,唯一的遗憾便是没有认识更多的人。在大一刚开学的时候,我没有加入任何学生会;社团也只是象征性的加入了几个感兴趣的,也没有参加过什么竞选。再加上我的宿舍与六班的在一起,导致和我认识的人不少,和我熟的人不多。很多时候吃饭只能一个人吃,自习只能一个人去。回到了学院路,人更多了。我希望能够认识更多的人,和更多志同道合的人成为更加密切的好友。
在沙河是挑战,也是机遇。这里没有那么多的资源,没有便捷的交通,有的只是环境优良的寝室和教室。有的人会刷夜打dota,有的人会埋头苦读课程,有的人会学习自己喜欢的事情,有的人会迷失于功利的目标,有的人会宅在宿舍,有的人会走出校园奔波于未知的大千世界。作为第一届沙航的学生,我们少了别人的标榜,却也多了那份自由,去选择自己的道路。
回到了学院路,大学时光正式的过半了。未来的路还很长,在这个校区一定会有着完全不同的生活,我期待着。

Metro设计之我见

Metro是微软在Windows Phone 7及其以后的Windows 8、Windows Phone 8中展示出的一种设计风格的名字,它之所以叫这个名字是因为它借鉴了地铁站牌的设计,力求通过简约的、以信息为主体的风格带给用户一种清爽而又高效的体验。

我不是啥专业的设计师,但是却是一名专业的WP7使用者。由于我拥有一部以刷机而闻名的HD2手机,它可以刷各种版本的Android和各个版本号的WP7。我从Nodo开始就开始用WP7了,算是最早使用WP7系统的人之一。WP7的Metro风格确实让我眼前一亮,我很喜欢。Win8的风格,我只能说一般,但是前几天MS展示了WP8的一些特性,让我倍感失望。所以我打算把我心目中的Metro风格表达一下,也算是纪念一下我那刚用不久就无缘WP8的Lumia 800..

关于Metro风格的特点,百度百科的说法是:干净、轻量、开放、快速;要内容,而不是质感;整合软硬件;世界级的动画;生动,有灵魂。于是,WP8就被设计成了那副模样。但是,其实大家不知道,WP7中的Metro UI之所以成功,不只是因为这些特点。

在我看来,Metro UI还有这些十分重要的特点:

阅读更多

片语

前几天在reader上看到个小故事:

很多年前,我还年少的时候,喜欢下象棋,在学校里基本上我能下赢的,我总能下赢,我下不赢的,总也下不赢。不得其解,也慢慢懒得操练了。

后来有次学校搞业余活动,有个老师是省象棋协会的,组织了一节棋课。我去晚了,只听了半节。大致意思是讲,下棋要讲全局观,要有战略,例如中局五种策略,中局成杀、不成杀则优、不占优占先、不占先则多子、不多子则求和。还有什么炮破士、马破相、残局炮归家等等。却没有讲如何下棋,课堂上也没有摆个象棋,或是什么棋谱。

我并没有把这些当回事儿,之后也很少下棋。

又过多年,毕业后同学聚一起,闲来无事,与一个同学下了两盘。刚开始,他问我这两年有没有下棋,我说没有。他调侃我,“那你以前下不赢我,今天你也难赢了”。我也笑着认同,反正只是玩玩,何必认真。

可是一开局,他就傻眼了,一直处在下风,且每局必输。他很吃惊,我也很吃惊。之后我认真思考了这件事,觉得是那节棋课影响了我,人的思考能力、计算能力都差不多,而思维方式不同,结果也会有很大不同。他看到的是“棋”,我看到的是“局”。决定胜败的不是棋艺。

又过了几年,我已经不再年少,但还算年轻吧。有一次找一个朋友玩,正好他的一个朋友也在,吃完饭没事儿做,恰巧有副象棋,就与他的朋友下了几局。他们都比我年龄大,已经三十多岁了。不过我也没有放在眼里,自以为水平相当可以,三局我两胜,颇为自得。

等他走后,我朋友问我:“他水平怎么样呀?”我带着些“谦虚”,洋洋自得:“他水平挺可以的,我差点就输了,还好我三局两胜,略胜那么一点点。”

我朋友听完哈哈大笑:“你知道他是干吗的吗?他是卖保险的。卖保险的吗,任何人都可能是他的潜在客户,他自然不会去赢你,不光让你赢,还要让你赢得有面子,这才是高手。他原来是在象棋协会的,论象棋,那叫牛×死了。”

我听完之后,惭愧至极。我关注的是“棋局”,人家所关注的,则超脱棋局之外。眼界不一样,看到的也不一样,操控点也不一样,输赢已经不重要,重要的是输与赢,哪个更有利于自己,然后才是“如何去输”与“如何去赢”。棋局只是一个棋子。决定成败的不是棋艺。

这则小故事让我思考了很久。作为一名准程序员,似乎视野就应该是编程而已,顶多再自嘲一下不想当美工的策划不是个好程序员之类的东西。但是,这样的人只是个工人而已。即便他学了再多的算法,有多么熟练的编码速度,他也只不过是上面故事中的第一个对手而已。

于是想到了前几天的面向对象小论文,我在文章的结尾写道:

面向对象技术已经面世40余年了,近些年来,Java、C#、C++等主流的面向对象的语言也一直占据着主流编程语言的位置。可以说,过去十年甚至将来的几年将是面向对象编程模式的顶峰。它的特性鲜明,很适合用在大型软件工程领域的开发。它有很强的复用性,通过对代码的复用,编码人员也似乎从高不可测的科学家、工程师,变成了“代码工厂”中的普通工人,从一定程度降低了编码成本。

但是,新的时代带来了新的变化。并行计算、网格计算等崭新的计算技术正在逐渐颠覆现有的计算理论,而面向对象的编程模式则不是十分适应这种新型的计算模式。此时,Haskell、微软的F#等一系列的函数式编程语言也逐渐走进了主流。它们天生就是并行的、模块化的,并且也拥有一些面向对象的特性。

计算机软件设计技术一直在发展着,也许面向对象程序设计是一种十分理想的设计,但是总会有更加先进的设计会在某一天取代它,正如它取代了面向过程的结构化程序设计一样。设计出最符合现有生产需求的编程模式,而不是机械性的套用已有的模式,才是我们大学生应该做的事情。

写到最后一句话时,我自己也为之一振。看了这么长时间的设计模式,在套用着已有的模式的时候,我也在想现代的甚至未来的程序设计到底需要什么样的模式。而什么才是现代的甚至未来的程序设计呢?程序设计如此,其他领域呢?

这就涉及到了创新。昨天晚上看了一期非你莫属,里面有一位求职者自称很有创新能力,要谋求一份策划的工作。但是很不幸,因为企业给的工资太低,他失败了。在这样的环境下创新很难,但是无论如何,创新依旧是第一生产力。社会不需要民工,需要的是更高层次的人。

突然又想到了马原课老师曾经讲的一句话:

有之非有,存在的无。

刚看这句话时很不理解,待到老师解释之后便恍然大悟。

决定一个人的,不只是他的天赋、努力、运气,更是他的思维方式,他的思想层次。

Valder Fields

就以我今天听了一天的歌为题目吧。

做了一整天的wp7应用,基本熟悉了MVVM模式。前几天搞了搞Android的开发,游戏神马的,Android确实不如xna好使。今儿搞wp7的时候更觉得Android应用开发也不如WP7。WP7的界面也更加漂亮,似乎WP7火起来只是时间问题。但是WP7的弱点也很明显,bug略多,API太少,连GDI+都不见了。我很奇怪为啥微软要放弃已经很成熟的.net compact framework而去用silverlight。如果Tango能增加一些API的话,我保证wp8可以火起来。

今天晚上要写作业了。下午看了那个被要求的视频,觉得可以写的东西还是挺多的。3000字应该可以编出来。ppt神马的嘛,回学校再说吧。

昨儿晚上正式决定不搞ACM了。或者说是被不搞了。董适说得对,现在的ACM就是应试,跟高考没什么两样。我这个从来就没怎么刷过题的孩子还是不适合这种机械的事情。北航的ACM尤其走刷题路线。没有人讲课,没有人讨论算法的正确性,没有人设计更好的算法,没有人去想某个算法真正该用在哪里。有的只是刷题的人,给题号的人,给源代码的人,出题的人。可能ACM就是这样吧,它不适合我。可能ACM可以给我一个奖项,可能ACM可以为我赢得声誉,但是它给不了我想要的能力。

我虽然很沮丧,但后来感觉到的就是豁然开朗了。少了一项负担,其他目标便明确起来了。比如说这个寒假,剩下的时间就基本用来做云浏览器了。这个东西确实是个体力活,我也不指望高英恺和肖文聪去做了,这种“低级”的事情还是得靠我自己。做不完的话,我就只好把上学期的java大作业当做冯如杯项目了。

一切才刚刚开始。

阅读更多

天生我材必有用

考试考完了,许多科的成绩也都出来了。从成绩上看,估计靠成绩保研这个梦想是够呛了。本来还指着这学期能把平均绩点拉上来一点,结果估计会拉下去很多。为啥这么多尾数是5-9的呢,我数了一下,成绩的尾数有18个5-9的,11个0-4的。点背不能赖社会啊。。

好在绩点还有下学期可以刷,还有最后一学期的希望。下个学期我要立下三个目标。一是每天上课坐前排,二是每天晚上去自习,三是自习回来去跑圈。身体最重要,在这个学期我对这句话有更深的感触。当然在绩点面前,一切都是浮云,这就是北航教给我的。

于是就到寒假了。看到ACM寒假的要求,我不禁出了一身冷汗。这哪是寒假啊,这比刚刚过去的这个学期还苦逼。我对ACM的兴趣正在逐渐的减少,虽然它还在我的底线之上。

还有下学期的冯如杯就要到了。虽然我很希望下个学期拿个很好的奖项回来,但是创意有限,能力更有限。没有了“大一学生”的特权,我甚至都不知道有什么能拿得出手的东西来。

我的电路考试考得这么糟糕,糟糕到我以为它挂了,结果竟然得了90分,虽然我错的题目的总分肯定超过了20分。于是只有一个解释:我差,但是大多数人更差。我不知道从什么时候开始这么注重和别人的比较了,哪怕在初中我的成绩那么好的时候我都没有刻意的和成绩比我更好的人比较。这可能也是北航教给我的吧,这里注重比较的人太多,排名带来的好处太多太多,于是我也就变得对排名这么敏感。

但是排名真的有用么?我已然厌倦了学习自己根本没有兴趣的课程,已然厌倦了课堂点名,已然厌倦了期末的突击,已然厌倦了查看成绩时的狂妄或无地自容。就像我已然厌倦了ACM中的刷题,已然厌倦了将满足感建立在那个Accepted之上。我不厌倦的,是我学到我想要的知识时的喜悦,是我创造出属于我自己的东西时的自豪,是我实现自己的价值时的满足。正如我数电实验期末考试选择了创新实验,当我看到秒表在LCD上显示的时候,这满足感比任何成绩都要强。

但是事实告诉我,我无法这样静下心来。

但是我想起了几年前我经常对自己说过的话,“天生我材必有用”。这半个月的考期让我过于自卑了 ,但是其实仔细想想,自己远没有自己想象的那么差。比如说电路考试,比如说其他。到了大学,人们的目标不一样了。有的人拼命玩游戏,有的人拼命刷绩点。在大学比你牛的人太多了,但是也要相信,比你差的人也太多了,只不过努力的方向不一样罢了。不要有太大的压力,要自信。不要被外界所束缚,不要被浮躁所影响。诺基亚说:“不跟随。”这话说的太对了,我看好诺基亚,等Lumia800降到3000以内的时候我一定要买一台。当然这是后话了。

接下来的寒假,好好享受吧~在知识的海洋里。