Wednesday, July 20, 2011

CS study

既然偶像写了一篇,我也写一篇发表自己的拙见。

首先,师兄写的文章我基本赞同,不过个人觉得稍微" 局限"了一点。
这里的局限,指的是师兄认为需要侧重掌握的能力,可能更偏向适合某类具体的工作。
因为强调要知道系统底层运作,则显得非常computer engineering,更偏向的系统运维类的工作。
但是,有些人可能比较感兴趣于其他方面,如网页前端设计等(当然这个就有点偏离CS了),
则不一定对某些细节需要钻研得那么仔细。
再者,加上由于technology的限制,有些时候成立的观点日后不一定成立。
比如深刻钻研磁盘读写调度算法会对performance有很大的改进,
但这些算法都被限制于现在外存存储的碟片模型,说不定以后SSD之类的全面dominaate市场了,
那些算法就可能成为一些legacy的东西了。

我个人认为,作为一个合格的CS毕业生/IT民工/xyz(这里有很多label可以用的。。)
可以从以下几个方面评价、学习:
- 基本素质
- 生存技能
- 自身修养

1. 基本素质
我认为,作为一个合格的CS毕业生/从业人员,必须拥有的基本素质有:

 - 程序设计。如了解10门以上的语言,精通2-3门语言。 程序设计语言这是作为一个CS科班出身的人所必须拥有的与别人交流的能力。
无论你算法、理论多牛B也好,我也窃以为起码要掌握一种能与人沟通的语言。
其中我认为,C语言是最接近现今主流计算机实现模型 (limited resource TM)而又不至于太low level的描述,所以强烈建议任何人都精通之。
其次,think like a computer scientist,掌握一门高级语言,如Python/Apple script,你会发觉自己不再拘泥于底层细节,而是天高任鸟飞。
不再拘泥于一些底层的、重复性的东西,而是把自己的表达能力提高了一个层次,因此瞬间能力强大了很多。

 - 算法与数据结构。排序、查找、搜索我想是工程里最最常用的case,一定要熟练。
关于它们的重要性,我想CLRS 的序言比我说得好一百倍,不再强调。这对于想做研究的人来说更要。
自我读研以来,越来越发现他们的重要性——除了数学逻辑、可计算性等理论中的战斗机较少用到,之外的几乎任何方向,归根结底总是要设计出一个好的算法解决问题。
如果让我再读一次本科,我会选择少学些花里胡哨的技术,多学些算法。
注意这里说的算法与数据结构,不是指你知道回字有多少种写法,而是你的思维锻炼得究竟如何。

- 根据IEEE/ACM 的Computing Curriculum(CC),你必须熟悉(越深越好)计算机的一些核心课程,如Discrete Math, OS, Networking等。
接下来,具体的侧重点可以参考最新的CC(好像是03,里面具体分了IT/CS/CE/Management/DB等,好像是七种方向)。
在这个基础上,大量了解CS-related的各个方面(extensive study),并且在你的职业道路上做好intensive study。

- 了解各大平台与流行的技术以及*系统*底层,这就与pudding的建议有点接近但又没有具体。
这需要时间的积累。以下随便列举一些能学到的并且可能颇为重要的:
 -- Windows: Win32 API/MFC/WPF/.Net
 -- Linux: shell, kernel, its philosophy, scripting, X
 -- OS X: kernel, Cocoa, Obj C, MVC-style Inter Process Communication (IPC)
 -- Server side: AIX/SunOS/Solaris etc. system mangement & operation

2. 生存技能


3. 自身修养
- 掌握解决问题(Problem Solving)的基本思路(如Divide & Conquer, Recursion, DP等)与常用Heuristic(如'无机为先'的思路,推荐Polya的How to solve it)。不断提高自己解决问题的能力。
掌握一些解决问题的基本工具、技术。如DP,LP,simulated annealing, genetic algorithm,taboo search,data mining,machine learning(后面这两个已经成为无数research topic的有力灌水工具囧)

- 建议了解一门functional PL,如pudding推崇的scheme/LISP(学习递归思维的利器),或者haskel, O'Caml等。
这是接近从递归论/lambda calculus出发的计算模型描述,让你更深刻地理解计算本质。

- 发挥优秀程序员"懒"的本性,培养"计算机为我所用"的观点,深刻挖掘"Automation"的潜力。
如何让计算机为你干活?这就需要有广度深度并重的结合。在这个思想的指导上,你才能发挥程序员lazy的本性,让计算机帮你做更多的东西,一劳永逸。
我认为一个有水平的程序员必须学会脚本/批处理来处理一些繁琐、周期性的任务,如文本处理、资料备份压缩,等。

- 优秀的学习能力。比方说,能快速地上手工具、学习一门新的语言、借助文档快速开发(给你手册,你能快速地开发如Firefox 插件,Twitter Gadget,系统管理script等的东东吗)。

- 保持学习的动力与激情。技术总是不断淘汰与更新的,必须保持良好的心态与兴趣动力,才能在历史的潮流中屹立不倒。

- 数学修养。不知道pudding 大神碰到了虾米问题让他觉得数学不够,可能是因为接触到B公司的核心IR技术,必须从理论上研究东西的层面上了?
不讨论究竟做IT究竟需不需要数学,但是最起码数学是可以作为一门兴趣培养,并且锻炼思维的。
首先离散数学的各个方向肯定是我们必须要掌握的东西,包括: 集合论、数理逻辑、关系与函数、抽象代数、图论、组合数学、数论、运筹学、形式语言与自动机等。
这一堆是最体现CS背景的东西。离开了这一堆,只能称作CE/IT毕业生了。
其余的各种数学理论,我不敢说干IT究竟能不能用到(比如我就很难看到做系统管理员与近世代数有什么关系),但是如果你aim at research,就很容易碰到。
起码我以前觉得用不上的东西,现在全部都能碰到,如:
-- 几乎所有的research都能或多或少用到微积分/转化为图论、combinatorics的问题
-- image processing: 需要一些信号分析、微积分、微分方程等
-- quantum computing: 线性代数、概率统计
-- cryptography: 代数系统、数论
-- system research: 排队论、博弈论、马尔可夫链、控制论、运筹
-- 就连一些泰勒展开式之类的我以前觉得超级恶心的东西,用来解决某些问题也能屡试不爽。
除此之外,还建议看一些拓扑学、逻辑学等的开拓智力的东西,提高自己的修养。

- 理论层面的兴趣培养。Computer Science 之所以能被称为Science,就是因为其基础Theoretical Computer Science,实质上与数学、物理等能归结到一起,上升到哲学的层面。
首先我们可以从历史层面开始研究计算的历史,从第一个算法GCD到Diophantine Equation与费马最后定理,从abacus到calculus machine,从第一个女程序员ada到第一个女图灵奖获得者Frances Allen
从到图灵机与递归论,从图灵的gay友死去到阿西莫夫再到强人工智能主义的兴衰,从第一台晶体管计算机到冯诺伊曼机,
从几合原本到罗素悖论再到哥德尔不完备性定理,数学史上与物理史上的三次危机,等等等等,都是非常生动有趣的故事。
然后,我们可以阅读一些TCS的东西,体验一下理论带给我们的震撼。可计算性、计算复杂性、形式语言、量子计算,都是值得思考玩味的学科。
最后,我们也可以从信息论(Informatics, Information Theory)的角度入手研究计算,体验一下Shannon 截然不同的观点。

----------

最后,我觉得还有一些off topic但很重要的points……
- mm问题
- 培养一门兴趣爱好,琴棋书画(艺术)方面的兴趣
- 身体健康问题

No comments: