知易行难

无知者无畏,源于我们对世界的认识太浅

前言:文中提到的很多名词和知识点只能算是领域内的基本知识,懂行的人都明白,就像CLRS、CSAPP、SICP这些“圣经”也都是MIT、CMU的入门教材。

当你天真的以为自己走在正确道路上的时候,却蓦然发现站在世界舞台中心“表演”的那些人,已经接近或者达到你的年龄。为什么?比尔盖茨、马克·扎克伯格在辍学前已经积累了将近十年的编程经验,能够在很短的时间内完成产品原型的开发(注意:Zark说他最初开发Facebook时是考虑千万级别访问量来设计架构的,试问有几个人可以做到这点?)当我们还在奋战高考的时候,他们已然是优秀的Developer。从这个角度来看,纵使高考差距几十分,身处不同的学校,可在计算机科学、电子工程等专业领域,大多数人却依然处于同一起跑线(我是指专业知识)。

在象牙塔里呆久了总会带有理想主义气质,而且总以为成绩至上。可人总是要工作的,能留在学术界的又有多少?想明白工业界才是自己最终的归宿,做事情的不确定性就小很多了。所以早点实习,早点实习。

知识的匮乏也是很大的问题。一开始听到bootstrap(自举),感觉很纳闷,后来看了陈梓翰(vczh)的脚本技术 ,思路开始逐渐清晰:先用底层语言编写最小完备指令集,例如用汇编把分支、循环、函数、递归等基本控制结构写出来,再利用写出来的基本控制结构继续编写更加高级的语言特性。自己开始写的时候,首先要设计词法分析器。接下来引入了自动机编程的概念,这种编程范式在游戏人工智能里应用广泛,每个对象都由一个或多个自动机控制,里面还遵循了很多C++设计模式。软件工程绝对不是课本里空泛的概念,真的是众多工程师在长期实践中总结出来的宝贵经验,可是如果没有足够的编程经验又难以将其融会贯通,而欣赏大师的代码心情是愉悦的。紧接着要考虑字符串匹配的问题,了解到正则表达式后,Aha! 简洁优雅又强大!还好C++11已经增加了对正则表达式的支持,我当时用g++ 4.8.1,还没有完全支持这项功能,老是出错,一怒之下转VS2013,大公司就是不一样啊,编译器完全支持新标准。后来知道Boost库之后又果断转Boost了,这是后话。

问题规模的极速膨胀也会给常规的解决方案带来巨大的挑战,但顺着这个思路就会发现很多技术思路是自然而然的。之前讨论过排序这个问题,小规模排序常规的算法吃得消,当数百万个数的时候,内存开始不够用了,即使你没学过硬盘排序或者Bitmap,也需要往那个方面想,因为没多少更好的路子了。有篇论文《快速排序异步并行算法的多线程实现》倒是只差分布式没用上了,这里设计的时候要注意一下设计模式,比如异步和并行、多线程这几个功能设计成接口(或者是池化技术),分别来实现它,不过Hadoop和Spark都帮你封装好了。

学会解决实际问题。之前被骂的很惨,学了一堆理论,没有实际动手操作,再加上没有解决过实际问题。理论学的不够深,实践能力又没有。所以现在学乖了,会尽力去用所学的知识想办法解决一些存在的问题。渲染视频的时候想痛骂为什么要等待这么长时间?既然学了Hadoop,不如看看利用它能不能实现分布式渲染。搜了一下论文,好家伙,原来早就有人想到并实现了:基于Hadoop的分布式渲染系统...balabala,然后,又要开始编程,但至少有思路了,所以我现在习惯于先搜索一下是否有相关论文(譬如与元胞自动机 相关的内容好有趣啊)。

基本功很重要,很重要。所以我最近回炉重新学高等数学、线性代数和概率论与数理统计了,因为我发现一些书籍、论文里的数学推导我看不懂了,泪奔。我大一下的时候是刷了三本吉米多维奇数学分析习题集的,现在也都已经忘了,还要接着把后面三本做完找找手感。暑假准备搞一搞《偏微分方程》,这本书入学的时候在图书馆看到就很喜欢,一直想刷一遍,但是一直都没时间。

写一些玩具式或者教学式的东西还是不难,但要写成具有工业级强度的产品就非常困难了。这个就不多说了,反正我逐渐开始体会到了,最近在看《代码大全》也对此有所思考。

编程能够带来工作效率和视野上的提升,它是各个行业的好帮手

People who can code in the world of technology companies are a dime a dozen and get no respect. People who can code in biology, medicine, government, sociology, physics, history, and mathematics are respected and can do amazing things to advance those disciplines.  -- Advice From An Old Programmer, Learn Python the Hard Way(3rd Edition)

简单翻译过来就是:在科技界、科技公司里会编程的人多如牛毛,得不到足够的尊重。但在生物、医药、政府、社会学、物理和数学等领域里,如果你有这项技能,你将会做出令人瞩目的成绩。

我这里只是做个简介,就介绍针对9/11的新闻主题可视化的开源项目(Github主页 )和利用Yahoo Finance(YQL)以及Bokeh Tutorial做的两个数据可视化Timeseries Sample ,这里面都有教程和注释,并不难,更多有趣的应用可以参考Christian Peccei   的个人主页(似乎是被屏蔽了,需要翻墙才能上),可以看一下他是如何利用Python预测楼市房价的。只是这里要注意一下,Python2.x和Python3.x是不兼容的,虽然有2to3,但还是有很多问题,很烦的。推荐一个工具链:CLiPS Pattern ,这个只支持Python2.x。

我这个学期选修国际金融课的时候,老师说她很多资料都是手打的。这样不好,费时费力、不全面还容易出错,所以我已经开始在抓取各大财经网站的金融信息了,初有成效,下一步是基于全球地图生成动态可视化JavaScript。

这里有个目的,国际汇率变动在跨境交易和出国旅行是有用的,怎样利用计算机预判经济形势就很值得尝试。抓取“准实时”的汇率是可以,但是要基于某些因子来预判才困难。譬如抓取了全球海量政策信息,首先涉及到分词,或者叫自然语言处理,英文还简单,空格就是一个词,中文可就复杂了,我用IKAnalyzer结合MapReduce对金庸的武侠小说进行过分词,会得到一些诸如“者也”的无意义词汇,另外针对不同行业还要分设业务词典,同时要进行词频统计、文本聚类等工作,总之是件相当麻烦的事情。但是去年11-12月左右的俄罗斯卢布暴跌事件大家还有印象吧?欧美主要经济体对俄罗斯实行经济制裁,一个显著的后果就是人民币对卢布升值了,去俄罗斯买东西便宜好多,所以出现了中国人民组团去俄罗斯购买iPhone、Gucci和Chanel的现象。这种情况不能预判,但是可以及早作出反应,因为制裁俄罗斯的词汇会在短期内频率上升,它是属于消极类的词汇,与之会有相近的词汇簇譬如有经济下行、汇率下跌等...不宜说太多了,我也没完全整明白,大家有兴趣可以继续深入学习。

注意到YQL等各大网站API是有IP请求次数限制的,又要做到“礼貌”爬行,又要追求“准实时”,总是矛盾的。这里有篇关于如何利用Twitter上的心情预测股票信息的论文 ,只是免费的代理不好找,真苦恼。数学,金融和计算机相融合,衍生出了新的职业:宽客(Quant)。高频交易、量化分析,是的,算法交易,华尔街似乎告别了“小米加步枪”的时代。

吾常终日而思矣,不如须臾之所学也。本来我还想自己写一套完整的、相关的系统,当我发现了这个 ,我及时终止了这个想法。

关于“中国大陆”我觉得是一个很特殊的区域,很多公司都对这块土地“区别对待”。例如网易云音乐、酷狗是不支持大陆以外地区随意播放歌曲的,微软DreamSpark For Azure支持中国香港、澳门和台湾用户直接注册,唯独没有中国大陆,无语。

学习编程语言不要嫌多

总是听到“只用把C语言学透彻就足够了”的观点,我绝对不打算说它错。只是这个“透彻”的标准其实很模糊,因人而异,用C语言写一个完整功能的操作系统内核,用C语言把《数据结构与算法分析》或者《算法导论》刷一遍我想都不一定达到“透彻”的标准,不过完成这些任务倒是会很熟悉C。另外,参与过算法竞赛的同学也比较清楚,所用的“C++”准确的说是“C with STL”。

《The Role of the Study of Programming Languages in the Education of a Programmer》阐述了学习多种语言,特别是多种编程范式对程序员的帮助。同时也提倡程序员针对不同的编程范式设计出各自的语言。譬如为什么Java不允许多继承,但允许实现多个接口,同样的设计模式在C++语言特性下要换成纯虚函数来实现。

我用了Python的感受就是,如果以后不当程序员或者工程师,那可能真的会远离C/C++、Java、PHP、JavaScript,MATLAB,R。但是Python真的是全行业覆盖啊,种类繁多、功能强大的第三方包,可以在很大程度上减轻工作负担、提升工作视野,真的是棒极了!

Web开发的时候可以选择的地方好多,PHP的Zend Framework,Java EE的SSH,Python的Django和Ruby on Rails、Node.js,居然Haskell也有web框架:Yesod。我也是醉了,这么难学的语言让人怎么维护啊?这样对开发团队和开发者的素质要求很高。据说是因为Haskell优良的高并发特性,那这么说还有Erlang。

编程有三种坏习惯:

1.不遵循编程规范;2.不遵循设计模式;3.不撰写技术文档。

第一种的坏处显而易见,命名规范、代码结构混乱会带来开发上的极大困难,业界中有著名的Google C++/Java Style Guide,就会知道大牛云集的Google是如何要求编程规范的;

第二种是为了降低功能耦合度,增强模块化,提高代码重用性,进而抽象出通用框架。你无法想象各种功能写成一坨是多么的恶心,既不利于功能扩展,也不利于debug。开源圣经《教堂与集市》 里陈述了Unix的一条设计理念:将小工具做的尽善尽美,通过管道的形式把大型任务分解为小工具能够完成的任务。这有点类似于函数式编程,虽然我承认我智商不太够,Haskell学不明白,但我绝对承认它的优雅,至少List Comprehension的概念放到Python中可以使得代码更加简洁。另外确立接口与实现的概念也很重要,这点我是从STL里学到的,它暴露出来的都是接口(public成员),实现的是私有函数成员,譬如简单的二叉树搜索,接口声明是

inline int search(const T data) const;

但里面就一句代码,

return search(data,root);

就是为了递归和满足最小知道原理。

第三种很大程度上是因为不习惯阅读官方文档所导致的,初学者往往喜欢找相关书籍或者技术博客,殊不知官方文档就是最全面的参考手册(或许正是因为它太全面了),一般包括两大组成部分:Tutorial和Reference,前者是用来了解它的大概(at a glance),后者是用到再查阅的。我觉得Oracle的Java官方Tutorial 真的太棒了,所以我会选择先用官方文档入门,再查阅相关书籍深入理解。技术文档不完全是注释,不是说用javadoc把注释全提取出来就完事了,而是涉及到API设计、架构设计等诸多关键因素,是方便日后自己理解当初设计的理念、重构以及为他人提供开发便利。

着重讲一下自主学习。我们这里讲的不是基础学科的教育,比如数学、物理...这里讲的是比较前沿、比较尖端的东西。以移动互联网的角度来说,当我们想学一个最前沿的东西的时候,我们可能想到我要找教材,我找培训班,我到网上找一找教材。其实我觉得最前沿的东西是没有机构可以培训的...入门是我们要看苹果,看苹果最晦涩的东西,我们不要怕。往往我们想要看教材,想要找培训的原因,出自于偷懒,我们其实想走一些捷径,但是捷径不能给你带向最前沿的东西。——季逸超,90后的新型学习方式

就目前的现状来看,绝大多数的官方文档都是英文,除了个别(譬如中文分词器)。所以我认为英语的重要性大于专业课,如果要考虑肉身翻墙,那它大于一切。

关于从具体任务中抽象出通用框架这个命题,我也在尝试着解答。《社会化海量数据采集爬虫框架搭建》 给我提供了一种很好的思路:参数驱动。如果针对海量网站编写特定的爬虫类,工作量是无法想象的,通过合理的设计,可以采用输入参数、可视化采集乃至机器学习的方式进行爬取,将输入与爬虫核心组件剥离,使得高效的代码复用成为可能。如果不是最初的时候就考虑框架设计,仅仅是针对具体任务去开发,就很难做到代码的高效复用。

     敢想不敢做是我的软肋,好想率性而为。顾虑太多,再好的东西都终究会化为泡影。没有执行力,做事畏畏缩缩,没有勇气,心里很想做一件事,却总是怕这怕那,又或是给自己找各种各样的借口为自己的“不作为”辩护,这样心里确实会好受一下,然而下次再碰到事情你又会是这样,长此以往,当断不断,说走不走将成为你生活的常态。我想它已经成为了我生活中的写照了!想要改变的我,立志改变的我,哎呀,这又涉及到行动力。想法是极好的,做起来,对我来说,真的挺难。什么时候才能有机会实现蜕变,成就全新的自我???希望自己把握机会加油加油。

本文由大发快三开奖结果发布于股票,转载请注明出处:知易行难

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。