Coding随想录2017

下半年一直没怎么发文,一方面感觉对 “Programming” 有与以往不同的认知,加上不倾向于水一些 tutorial 类的文章,一直没什么启发性的想法也就一拖再拖了;现在正值2017年的尾声,本文将从怎样看待编程技术、怎么看待业务的快速变化与发展、以及对未来的想法三个方面回顾总结一下这一年的变化。

怎样看待编程技术

“编程技术”是个非常大的东西,很容易讲些形而上的内容,每个人都会扯,但这些通常都没什么用。我从每位 Coder 都能摸得着的“编程语言”,“行业方向”两个方面聊聊我的想法。

编程语言

首先我们在学英语或者一门其他自然语言语种的时候大概都听过一个说法:“当你学习一门语言时实际上是在学习这门语言下的思维方式与文化背景”。我想了想,学习一门编程语言也是这样的。比如使用 Java 的时候你自然要思考怎样设计 Class 与 Interface,为了设计更合理的代码,自然要靠向面向对象的思考方式;再比如你写 Nodejs 代码,到处都是各种 Callback 会需要你理解异步的概念;写 C 代码是,面对的 lib 可能都是进程、线程、文件描述符级别的操作,那么就要求你对操作系统原理了如指掌才能写出高效的代码。其他的语言如 Python、php、Go… 等也都有他们各自的特点,并且使用于解决某一类问题。

聪明的程序员都应该会C,至少应该有个基本的了解。为什么是 C 呢,因为程序肯定要跑在某个操作系统下,而目前来看所有的操作系统提供的系统调用都是 C。拿 Windows 举个例子,这十几年大概出了 VB、COM、WinForm、MFC、WPF 等框架,但是 win32 的系统接口从诞生至今完全没怎么变过。掌握 C 就代表着对系统原理的了解,在这个基础上很容易理解新技术。其他的很多脚本语言如 Python、php… 都可以理解为对 C 功能的某种封装,实际上它们也确实是 C 实现的一个“解释器”而已。

通常说优秀的程序员都应该练好内功,理解底层原理。很多人会比较疑惑这些底层原理到底有没有用,看了半天书还是一头雾水。他们可能不知道的是,C 语言就为练习这些“内功”提供了很好的练兵场。如果你要用 C 管理进程、线程那么就要直接 fork,pthread,要去挖掘进程、线程到底是什么,每个参数是什么意思。如果要实现高性能 Server 就要深入 socket,epoll,aio,fd。C 语言在教学与生产环境中可以说是完全不同,甚至可以理解为两种语言,因为某个编程语言是什么样子不仅取决于它的语法,还取决于它提供的 Library

到此语言似乎不是什么大问题了,重要的是打好根基。每种语言都有语法两部分组成。语法可以花两个小时了解下,库这一部分取决于你的业务类型,随用随查。重要的是对系统原理的理解,对思维方式的训练。

行业方向

Android、iOS 还是 Big Data、Machine Learning 还是 Blockchain。很难预测未来社会到底选择谁,但是在更大的时间维度里这些技术肯定都要被淘汰。但是要写出高性能的程序对操作系统原理的理解是必不可少的,至少在现有冯诺依曼体系不被颠覆的情况下是不可能跨过这一步的。

如果想在技术领域立于不败之地至少要做到上文所说的重视培养对原理的理解,思维方式的训练,其次要熟练通用的编程技巧,也就是算法、设计模式。这也是我在面试时通常会主要考察的所谓“内功”。最后研究某一领域的技术栈。比如移动端开发就要熟悉系统 SDK 提供的功能,Machine Learning 就要了解 RNN, LSTM, GRU, Attention 等模型。

至于要不要转型到新领域,我个人不持任何观点。长远来看,3,5年的时间足以淘汰一波技术,到那时候可能又会面临相同的问题。

怎么看待业务的快速变化与发展

业务变化快不一定是件好事,很有可能是大环境的压力推动着不得不改变,业务越来越复杂,代码越来越乱。人员数量到了一定程度后也会带来一些管理、沟通上的问题。这些也会影响到技术选型上,比如是否使用 MVP 在 2 个人或者 10 个人的团队里会有完全不同的思考方式。

业务快速发展同时会要求对代码逻辑更高级的解耦。比如通常 MVP 解耦了数据、UI,但随着更多需求进来,更多 App 需要维护我们可能会考虑从业务上把 IM、数据同步服务、位置信息等业务解耦到不同的进程提供 SDK 调用的方式以实现基础架构的复用与优化集中管理,类似于一个 BaaS 云的模型。同时为了实现这样的架构我需要从人力方面单独组建“基础架构部门”以从深套的业务中解脱出来专心保证基础设施的可靠性,当然这些都是随着业务增长自然而然的事情,一旦抛开业务谈架构都是不切实际纸上谈兵的行为。简单业务小团队没有必要考虑架构,而复杂业务环境下优秀的技术架构与人力架构支撑是必不可少的。

关于优化

关于优化,我认为通用的准则一定是:优化某个方面,并且达到预期效果。

比如,现在内存问题比较大,我们要把内存占用减少50%;或者我们要把 CPU 下降20个点;或者我们要把流量使用降到某种水平。明确优化方向之后在项目里找可能的原因,然后解决问题。

大部分情况我们的代码都是遵循 Best Practice 的,而且这些 Best Practice 通常都是有迹可循的,网上一搜一大堆,非常简单。要针对项目把某个指标优化下来才是优化最应该做的事。就像著名的单机并发 1W+ 的 C10K 问题,一般情况下是有很多套路的,比如 epoll,aync io,但是上了 epoll,aio 然后不解决问题我们就要思考到底是哪出了问题,是内存满了? CPU overload了? 带宽不够了?要针对这个问题结合业务逻辑拿出优化方案。针对某个指标优化,并且要明确的看到优化效果。如果没有明确瓶颈所在或者优化目标不清晰不要轻易着手优化。在此再次寄出名言:

More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason—including blind stupidity.
—- William A. Wulf [Wulf72]

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
—- Donald E. Knuth [Knuth74]

We follow two rules in the matter of optimization:
Rule 1. Don’t do it.
Rule 2 (for experts only). Don’t do it yet—that is, not until you have a perfectly clear and unoptimized solution.
—- M. A. Jackson [Jackson75]

展望

要提高认知。不好意思,这又是个形而上说不清的东西。“认知”这个词是从《人类简史》里习来的,这个词总描述的非常精准。人类认知水平的提高直接导致人类成为地球霸主,而每个人对事物的不同层次的认知决定了他能达到的高度。那么怎么提高认知的,我的理解就是多看、多想优秀的人、事是什么样的,试图去理解它们之所以这样的根本原因并以此矫正自己的思考方式。

作为技术人,最近有很多负面新闻,华为、中兴代表了通信行业的兴衰,这很有可能也是未来几年互联网行业的走势。覆巢之下安有完卵,行业的衰落肯定有人要遭殃,这也是不以某家企业意志有所改变。幸好从事技术行业有很大部分的主动性是掌握在自己手中的,个人认为应该多尝试各种可能性,尝试不同的交流合作,不同的生活方式。但是作为技术行从业者,技术思维也是迈向更独立生活的重大阻力,一定一定要有所察觉并努力克服