池建强:非 CS(计算机科学) 专业如何进入互联网领域

很多人过长假没什么经验,不给自己留余地,留任务,留 todolist,他们胡吃海塞,他们流浪海外。但是,你们想想,半年多来大部分时间用来吃外卖写代码做需求准备产品上线的人,突然有八天空闲时间让你喝红酒吃海鲜和日本料理游览太平洋的海岛漫步在富士山的小径重拾普通人过的日子,你能适应吗?这并不是一件容易的事。

池建强:非 CS 专业如何进入互联网领域

浪完回来,你不仅要面对这八天懈怠留下来的落后进度和没有修复的 bug,更有对这八天浪费时间的悔恨和自责。你必须更努力的工作才能把长假里的空缺补上,才能有新的功能上线,而这个过程会比长假里制定并完成了六项任务的人(比如卖桃君)来得晚,来得艰难,甚至来不及……于是你们选择了生病。

我司优秀程序员涛哥等由于不适应假期生活悍然生病,这不是他的错,是我的错。如果当初让他十一加班就不会发生这样的悲剧了……

昨天我在朋友圈发了一条信息,问大家想看什么,其实就是想搜集点写作素材,但是读者们都很鸡贼并不露声色。他们微笑着对我说,随便写写,看到你还在写东西,我们就安心了。这特么什么意思,难道不更新就不安心么?

没有主题怎么办?我决定回答一位读者的问题:我不是 CS(Computer Science) 专业的,怎么进入互联网做一名工程师呢?

CS 的意思就是计算机科学,这个专业出来的大都是根正苗红的工程师,他们对基本的数学概念、统计学、算法、计算机结构、操作系统等内家功夫如数家珍,胸中有丘壑,并熟知各类编程语言,毕业的时候基础会比普通非 CS 专业的毕业生扎实很多。我在大学里学的是机械,虽然那会因为兴趣学了不少计算机知识,但基础并不扎实,或者说基础很烂。一工作就开始用 Perl、Java 这样的语言写业务应用,编程过程中遇到问题再去恶补算法、数据结构、操作系统和网络等基础知识,其实是很吃亏的。你需要花费比 CS 专业的毕业生更多的时间和更多的精力去完成别人可能轻松实现的工作,结果还不一定比别人做的好。

所以,在北京这个凄风冷雨的秋夜,我要给这个问题破一瓢冷水,你不一定要转程序员啊。

世界上并不是只有这么一个红火的行业,在分工细化和协作范围日益扩大的今天,传统行业在科技的加持下重新崛起,各行各业都有机会,不一定全部涌到计算机领域来。前一阵子看到一个数据,美国大学生毕业前五年各个专业的平均工资,排在第一的是计算机,排在最后的是哲学、政治学、历史学、心理学、语言等。但是如果把时间拉长,考察各行各业里最拔尖的人才,收入排在第一的是政治学,第二是历史,第四是哲学。

这个数据告诉我们,第一不要看到热门的东西就一拥而上,你要相信,看到热点很多人会比你跑得快,抢得多,下手还早。第二要长远来看,厚积薄发,无论是什么事,从更大的尺度和维度去考虑,看看它未来会变成什么样。也许你现在的行业后续十年有突飞猛进的发展呢?

有了这瓢凉水垫底,如果你依然想转技术,那可能是真·要转,我就给大家几个建议,我当年差不多也是这么过来的。更多计算机科学解读:www.yangfenzi.com/tag/computer

1、确认自己是因为喜欢技术和互联网才加入这个行业,而不是因为起薪高一些。否则你可能坚持不下去,即使坚持下去了,也会比较平庸。

2、用尽可能短的时间去掌握一门编程语言,比如几个月的时间达到熟练使用的程度 —— 这并不是不可能完成的任务 —— 做到这一点,你就可以实际开发应用了,或者说,你能找到一份养活自己的工作。

3、能够编写生产环境的代码了,这时候就要去恶补基础知识。比如编程范式(面向对象编程和函数式编程)、算法和数据结构(徒手翻转二叉树)、操作系统、数据库、网络协议、分布式系统等等。这些知识基本上不可能速成,每一个类别都博大精深,比如操作系统里的进程、线程、多核、物理内存、虚拟内存、文件系统、进程间通信等等。计算机里的 CPU、GPU、磁盘、性能等等,没可能一蹴而就,但长期的学习会让你更好的理解计算机和互联网,很多现代的,时髦的,最新的技术,都可以在这里面找到原型。所谓九阴真经,一通百通,就是这个道理。

4、在工作中寻找自己最擅长的并能够长期坚持的事情,这件事可能是某个领域的技术,也可能是某种产品和业务应用,你有可能转型为产品经理 —— 比如二爷 —— 但技术也不会白学,那时候对比其他产品经理,你的优势你更懂技术,更懂工程师。腾讯的 Pony 不是说过么:

很多产品经理对核心能力的关注不够,不是说完全没有关注,而是没有关注到位。核心能力不仅仅是功能,也包括性能。对于技术出身的产品经理,特别是做后台出来的,如果自己有能力、有信心做到对核心能力的关注,肯定会渴望将速度、后台做到极限。

5、注重阅读和分享。不仅仅阅读代码,也要阅读文章,不仅仅分享文章,也要分享代码。有时候你的个人博客或微信公众号,你的 Github 会比天花乱坠的简历更有说服力。写作和编程可以让我们进入深度思考和自省模式。如果你是个软件工程师,最好两样都干。

6、对于能力强意志力上乘的人来说,自学差不多可以解决工作中的绝大多数问题,但大部分人都是懒惰的,散漫的,喜欢享乐不喜欢挨饿的,我们的注意力只能集中半小时或更少的时间。所以,不要排斥线上或线下的培训课程,通过仪式感的学习方式,可以快速掌握一门技能。这种模式毫无疑问是最有效率的学习方式之一。

7、你可能会问我,你参加过编程技术培训班吗?我没参加过,不是不想参加,而是90年代根本没有人开编程培训班。所以我花了更多的时间,更少的睡眠和更大的功夫……也没成为技术高手(捂脸)。

写到这里你们肯定觉得我要推荐一门课程了。对不起,今儿妹广告。下课。

·氧分子网http://www.yangfenzi.com)延伸阅读:

➤ 王选:科学家、企业家与计算机发展

➤ 为什么斯坦福大学的热门专业是计算机科学

➤ 编程不只是技术,高考应有计算机一席之地

➤ 计算机行业诺贝尔奖花落“密码学”,致敬不能被忘却的图灵

➤ 通用计算的前世今生与未来:将定律装进机器中,创造出一个世界

➤ 女科学家卢宇彤:超级计算机到底有多快?天河二号背后的故事

➤ 未来科学大奖新增 数学与计算机科学奖,丁磊江南春马化腾王强捐赠

➤ 黄铁军:计算机出世—你所不知道的电脑秘史 你应该知道的电脑未来

氧分子网(www.yangfenzi.com)是关注互联网生态圈的科技新媒体

·氧分子网http://www.yangfenzi.com)综合整理

分享给您的好友:

您可能还喜欢…

1 Response

  1. 身处这个行业,许多人都是学习的爱好者。但是如何学习,这是一个值得仔细讨论的问题。我遇到最多的问题是:“我做的基本都是业务功能,计算机理论有什么用?” 这个问题常常又和下面这类质疑联系在一起,就更让人困惑。所以今天我想来个现身说法,讲讲计算机理论对做业务到底有什么用。

    计算机科学理论到底有什么用呢?我一开始也很困惑这些问题,在学校学数据结构、离散数学等等,总觉得和使用的那些炫酷软件相差万里,似乎人家都腾云驾雾了,自己还在地上修理地球。

    某一天在图书馆在做离散数学习题,我感到了“电光火石的瞬间”,原来解决问题可以不靠直觉和猜测,而是有一整套方法。

    过河问题,我们小时候都做过:河这边有人、羊、狼、草。如果没有人看着,羊会吃草,狼会吃羊。大家都要过河,但只有一条船,船上每次最多装两样东西。要怎么过河?

    我只记得小时候做过这种题,但已经完全不记得是怎么解的了。让我用计算机来解的话更是一头雾水,我完全想不通为什么这个题目和离散数学有什么关系?直到翻看答案才恍然大悟。

    人、羊、狼、草,一共四种生物,一开始它们在河这边,最终要去河那边。如果我们换个角度看,每个时刻(不包括渡河中间态),每种生物都可能有两种状态:要么没有渡河,要么已经渡河。如果我们对二进制非常熟悉,就可以迅速穷举出所有的状态(没有渡河标为0,已经渡河标为1)。

    所以,我们要做的其实是从「状态1」出发,抵达「状态16」。我们不妨把每个状态看成一个节点,如果两个状态之间可以通过一次渡河解决,就添加一条边把这两个节点连起来。比如一开始大家都没有渡河(状态1),人和羊可以一次渡河过去(状态13),那么「状态1」和「状态13」两个节点就可以用边连起来。然后人单独乘船回来,那么回到「状态5」,所以「状态13」和「状态5」之间又有一条边相连……

    如果从计算机科学的角度来看,这个问题就变成了图中两个节点的连通可达问题。我相信,到了这个程度,大部分人都可以写出程序来解决了。之前之所以解不出,缺的就是计算机科学理论的那点思维。遗憾的是,我见过的大部分计算机教材都没有“点透”,所以尽管学了课程,还是缺那点视角。

    我猜,有些人看到这里还不会服气,毕竟这个题目本身也很“理论”。那么好,我们再看看其它的例子。

    学过计算理论,或者深入了解过正则表达式的人,一定听说过“自动机”的概念。它由一系列状态和若干转移函数组成。转移函数是这样的一系列规则:从状态q0,输入a,达到状态q1。状态里有两个要特别注意:起始状态,结束状态(下面的图里,q0可以视为起始状态,q3是结束状态)。

    传统的计算机教材讲到自动机,通常也会举个例子:自动售货机。投钱进去,点要买的东西,出货,改变余额…… 最终状态是钱都花光了,或者是退剩下的金额。但是,也就讲到这个例子为止了。看起来,这套理论也那么“理论”,和实际没什么关系。但是,不做自动售货机的业务,真的就可以和自动机划清界限了吗?

    我不知道你是否做过订单系统,或者至少了解、思考过。如果都没有也不要紧,你至少应该在网上下过订单。回头想想,知道订单的处理流程会有许多环节(确认、付款、发货、收货、评价……)。那么,它和自动机有关系吗?

    我见过不少人,或许是不懂,或许是不屑,觉得这个问题自己很容易搞定——订单的处理无非是一系列状态而已,弄个枚举值,每个状态编个号嘛。然后,真的就这么去这么弄了。一开始确实没问题,随着业务的逐渐负责,问题就来了:需要新增或者删除状态,如何保证各个状态的融洽一致?业务规则不断变化,如何避免有些订单走入了预料不到的死胡同?我就见过好几个历史悠久的订单系统,充斥着大量繁杂的 IF-ELSE 判断,基本处于“谁也不想维护,谁也不敢维护”的状态。

    如果换个角度,从自动机的模型出发,就清楚了很多。

    仔细观察,你会发现自动机模型很好地实现了解耦:状态是静态的,我们只要关心它所代表的意义就足够。转移函数负责动态,但它只需要关心“做了什么,结果如何”。而且,所有的状态可以汇总到一张表,所有的转移函数也可以汇总到一张表。再加上一台“不论你是谁,忠实查找转移函数更新状态”的引擎,总共两张表、一台引擎就可以包含所有的信息,干净利落,不留死角。

    我们都知道,计算机要解决的很多问题之所以难,都是因为过于复杂,所以无论是系统设计、程序设计、算法设计,关键问题都在于降低复杂性,而降低复杂性的有效办法之一就是“分而治之”。用自动机的视角来看待订单问题,恰恰做到了动静分离、责任内聚,很方便分而治之。无论订单处理流程如何变化,无非也是增减两张表的数据而已,状态转移引擎完全不必更改。这样做出来的订单系统,再复杂也不怕。

    同样的理论还可以用在更多的领域。比如,我司(沪江)的用户中心在设计在线系统时,也用到了这套理论:所有的在线用户会话总会处于某种状态(可信、不可信、高风险、低风险……),随着用户行为的不断发生,当前会话会在不同的状态之间转移、跃迁。于是,当用户要进行某些关键操作的时候,只要看看当前会话的状态,就可以确定操作是否安全。因为理论模型非常清楚易懂,静态的状态和动态的转移函数责任清晰、职责分明,所以完全拍胸脯说,任何时刻、任何用户会话都处在完全的掌握之中,理解、维护都特别方便。

    如果这些例子不能够说服你,最后我们来看一个更高阶的,来自我的朋友J的例子,它应当足够有说服力了。

    J同学遇到过这么一个问题:他维护的是数据仓库,你可以把数据仓库设想成一张很大很大的表,有很多很多行(数据条目),很多很多列(数据字段)。数据仓库的查询API成一次只能指定少量条目和少量字段。

    查询是众多类似这样的组合:

    {(Row1, Row5): (Field3, Field7)}

    {(Row2): (Field2, Field4)}

    {(Row3): (Field3, Field5)}

    {(Row4): (Field2, Field8)}

    {(Row6): (Field4)}

    简单来看似乎没有什么问题,但随着业务增加,这个API就成了瓶颈:业务方往往给出大量「条目-字段」的组合,需要尽快得到答案。数据仓库的查询速度本身没有问题,但启动一次查询的成本很高。

    通常大家都会想到异步,一次接收多个请求,查询完成再批量返回。异步会有帮助,但还无法解决性能瓶颈:如何能用尽可能少的查询,得到所有需要的数据。许多人会想到缓存,但简单缓存是行不通的,表太大了,哪怕仅仅缓存一行或者一列的完整数据,也超出了内存的限制。

    怎么办呢?幸好我这个朋友的算法学得相当好。他一眼就看出来,这个问题和二部图密切相关。

    所谓二部图,指的是这样的图:(我避免使用过于“数学化”的描述)可以把图中所有顶点分为两部分,保证任何一条边关联的两个顶点都在不同的部分。

    如果我们从图的角度来看,这个问题天然就是二部图:一个顶点集是要查询的所有条目,另一个顶点集是要查询的所有字段,所有的查询都视为边,边都是是「条目-字段」的组合,因此所有的边都满足“一个顶点在这边,一个顶点在那边”的要求。

    剩下的事情还是分而治之:如何把这个图切分为多个互相隔离的部分?或者说,如何用完全二部图去“覆盖”原来的图?上面说的“切分”其实相当于对零散查询的归并,把海量的零散查询归并为少数集中的查询,既能降低查询次数,又避免了缓存浪费。网上搜索Covering Graphs with Few Complete Biparties Subgraphs,现成解法相当多。上面的图,切分之后就很直观了。

    只需要对数据仓库做两次查询,结果集就已经涵盖了所有的查询,而且浪费的空间非常少,时间和空间效率都非常高。

    {(Row1, Row3, Row5): (Field3, Field5, Field7)}

    {(Row2, Row4, Row6): (Field2, Field4, Field8)}

    难吗?似乎不难理解啊。但是如果没有想到问题的原型,任凭你再会编程,也难找到好的解法。要补充的是,我的这个朋友并不是程序员,他的工作是在金融行业设计数据产品……

    上面举了这么多例子,目的是希望给广大不重视算法的程序员朋友们一点启示,一点不一样的思考——其实大家也可以反过来想,你多懂一点点理论,有时候就掌握了哪怕多写几万行代码、多掌握几十种框架也解决不了的问题,何乐而不为?

    对了,最后还有个问题。有许多人问:数据仓库提供这么坑爹的API,到底是谁缺心眼设计的?答案是:不知道是谁设计的,但学校里没有《API设计》这门课,真是害人不浅啊~~

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>