2018 年将至,iOS 工程师如何自我提高

文章出处,原创于 http://HawkingOuYang.com/

我的GitHub


2018 年将至,iOS 工程师如何自我提高 (张星宇)

转载 小专栏

预计阅读时间6分钟

如果从 13 年移动客户端大火开始算起,至今已经有五个年头了。现在移动端的形势也不需要太多的废话来描述,一句话总结就是:“浪潮退去,谁在裸泳一看就清楚。”我希望借助这篇文章来聊聊在我心目中,移动互联网下一个五年的趋势和机会,以及我们 iOS 工程师能做哪些准备,实现自我提高。本文主观性的看法比较多,文笔也比较激进,仅供参考。

我们都知道价格会受到供需的影响,如果某项技能在市场上紧缺,那么掌握这门技能的工作者工资就会相对高一些,比如 14 年前前后能写好 UITableView 就能找到一个相对不错的工作了。在我看来,未来几年的移动互联网,会出现“一个过剩,两个不足”,我会逐个分析并试着给出一些建议。

UI 工程师过剩

这一点是我老生常谈的了,首先要注意的是避免成为 API 调用工程师,因为这些 UI 方面的知识对个人价值的增长不是线性的,如果你还记得高中数学,请回忆一下 y =
ln(x) 这个函数的曲线。从零到写好 UITableView 给一个工程师带来的收益,远远不是从写好 UITableView 到写好 UIStackView 能比得上的。

就以 UIStackView 为例吧,先不说它从 iOS 9 才开始支持,而要想应用不支持 iOS 9,怕是要等到猴年马月了。就说它提供的功能,虽然简化了已有场景,但这个功能完全可以通过封装已有的组件来实现,相信很多大型项目都有,为什么还要费力气去兼容版本,以及再学习一个新的 API 呢?人的精力是有限的,如果你总是追着苹果的脚步,每年补 WWDC 上那些新坑和老债,那么视野就永远只能停留在 iOS 中了。

我拒绝追随 WWDC 的另一个原因是把自己的职业生涯押注在一个平台或者公司上,是极度不明智,也是极度危险的,即使这是苹果。上半年的时候我们小组招聘,我负责筛选了一批简历,其中有一位已经三十多岁,十年经验的程序员,他的简历让我感触良多。他本科毕业后就在诺基亚负责塞班系统的研发,大概相当于今天的苹果公司负责写 iOS 系统,看起来光环非常明显了,后来先后去过两家生产安卓手机的大厂,现在又申请 iOS 的程序员职位。在他的简历里,我看不到一个十年程序员该有的技术和思维深度,只有一个又一个古老名词的堆砌。因此,我衷心的建议各位读者,在你学习一个新技术以前,不妨先花十秒钟猜测一下,这个技术三年后,五年后,十年后会是什么样?猜不准没问题,如果有了明确的答案,还往坑里踩,就只能怪自己了。

当然,我并不是全盘否定 UI 的技术,毕竟程序员拿工资是因为你能为公司创造效益,所以该做的需求还是要 100% 高质量的完成,也就是说该学的还是要学。但如果是业余时间的自我提高就另说了,我的建议是找一个 UI 组件认真学习下,把官方文档读一遍,自己写个 Demo 理清楚知识脉络。我并不指望这个组件能真的帮上什么忙,但一个合格的程序员,也从来不应该只做自己会做的事。合格的程序员应该要有举一反三,快速学习的能力,所以只要找一个组件熟悉一下整个学习流程就可以了。了解一个 UIStackView 的前因后果以及如何兼容低版本是一个程序员好学的体现,但如果一个程序员只是每年学习新的控件,又不能在项目中取得较大的收益,就只能说是学习方法有问题了。

从技术角度来说,苹果的 UI 布局是我见过最落后的方式,无论是前端的 HTML 还是安卓的 XML 都要比 iOS 先进。这主要是因为把布局信息耦合进二进制代码非常不合理,而且一定程度上损失了动态化和解耦的能力。如果 iOS 的布局方案将来有较大幅度的优化,我可以断言绝对不是 Autolayout 这样的鸡肋工具,或者 Storyboard 这种傻瓜工具。相比之下我更看好一种统一的,能够跨端布局技术,比如 flexbox 规范。

专业技能人才不足

这里的专业技能指的是移动端这个大话题中里比较垂直的知识领域,大概包含以下几个方面:

图像/视频处理

随着网络基础设施的普及,以及流量费用的大幅度降低,4G 基本上已经全面商用了,如果说移动端前五年是文字为主,图片视频为辅的话,在接下来的几年中,用户对高质量图片和视频的要求会日益增长。

由于我对这个领域并不了解,所以能够推荐的并不多,在我印象中,OpenGL 这种跨平台的引擎,计算机图形学的知识,视频编码与协议都是可以花时间研究的,现在有很多优秀的创业公司也急需这类人才。严格来说这些知识都不算移动互联网方面的知识了,所以门槛较高,但门槛这东西是个双刃剑。它会增加你的学习难度,但一旦你掌握了这门知识,门槛又会变成你个人价值的护城河。

我格外想要声明的是,CoreAnimation 这类的东西如果不是工作中强制要用,一般就别碰了,就像没人会傻到用 SpriteKit/SceneKit 去写游戏一样,这种 API 密集型,又不能跨端的库是没有前途的,真正有价值的动画一定是用一套统一的 DSL(领域特定语言)去实现,然后导出到各个平台上,所以开发者一定要多在动画的原理上下功夫,比如了解矩阵变换,线性代数这些,而不是把时间浪费在阅读官方文档上。

把事情搞定

在任何时候,一个靠谱的,能把事情搞定的工程师一定是受到欢迎的。靠谱是一个很虚的概念,我以最近的观察简单的举两个例子。

当项目比较大了以后,随着参与开发的人数越来越多,与技术无关的事情也会占据越来越大的比重。比如协调和沟通,测试,后端的人力什么时候到位,某个 Bug 如何追查复现并定位,新版本的需求哪些可以做,哪些缓一缓,能做的需求什么时候提测,什么时候灰度,什么时候正式发版?这些事情很琐碎,需要很强的责任心,而且在求职的时候比较难体现出来(除非有知名的 app 背书),但相应的好处是绩效一般会比较不错,而且在领导心目中的印象会比较好。技术不敏感的同学也可以考虑这条路线。

虽然我一向对 UI 开发很不屑,但事实是如果一个 iOS 工程师能把各个系统控件玩得很溜,而且有自己对控件的积累和封装,再了解一些性能优化方面的知识,找到一个相当满意的 iOS 职位也不会太难。如果你走的是这种传统的 iOS 开发路线,不妨问问自己,每年的 WWDC 都看完了没,移动开发的各种工具是否都能熟练使用(比如 Reveal,Charles 等),能不能熟练到任何复杂的页面,都能通过自己积累的组件在短时间内实现?然而根据我的观察,绝大多数应聘者的简历里博客都很少,更别提 Github 上面有持续迭代的代码了。这条路线的缺点是职业生涯天花板相对比较低,基本上到高级 iOS 工程师就为止了。

逆向工程

研究逆向工程的作用不仅仅是破解 app,在我看来更多是学习底层的操作系统。在开发 app 的过程中,我们使用系统提供的库,调用 API 就可以实现需求,其中的过程完全是黑盒。而逆向工程的目的就是要开盒子,利用一些工具从二进制层面入手,反过来推测应用开发者的代码和逻辑。这其中会涉及到很多 C 语言,操作系统,编译原理方面的东西,相对来说门槛很高。逆向工程对企业对价值也很大, 因为大家都不希望自己被竞争对手一眼看穿,又对竞争对手对秘密颇感兴趣。

小结

以上是几个我目前能想到的,可以花时间研究的专业知识。这些知识大多是自成体系的,没有较长时间的积累,很难入门。这一点非常重要,因为很多知识看起来非常专业,门槛也很高,比如我下一节就会提到这样的例子,但这些知识我并不鼓励学习。区分的标准是,你学习的知识是一个知识点还是一个体系,如果你学习的只是知识点, 那么它只能是整个知识树上的枝枝丫丫,边边角角;如果你学习的是知识体系,就具备了衍生知识点的能力,也就是我反复强调的举一反三的能力。

上面举的三个例子都是我认为不容易遭到时间的淘汰,比较值得研究的话题。在这些领域上的投入可以理解为线性的,也就是一分耕耘,一分收获。

全栈人才紧缺

这里的全栈没有明确的定义,并非前后端通吃才算是全栈。在我的理解中,只要是跨知识点的融合,都算是全栈,因为跨知识点的融合往往会产生 1 + 1 > 2 的效果。往小了说,全栈可以减少大量浪费在沟通上的时间。往大了说,一个人了解的领域越多,他就越能把这些领域融合在一起,既能站在更高的角度思考问题,也能作为团队的领导者和融合剂。这也就意味着,掌握全栈知识对个人价值的影响是指数形势的,你了解的越多,价值就会越快的提高,职业天花板也会越高。

别研究得太深

我经常关注微信的技术博客,比如客户端通过修改 SQlite 代码达到了更好的性能,以及修复了一个非常诡异的内核崩溃问题,这体现了微信强大的技术能力,能够参与其中的工程师也一定收获颇大。BAT 这种级别的大厂其实有很多非常底层的黑科技,也会在各种大会和文章中对外介绍,然而我给大多数读者的建议是,当个新闻看看就可以了。人家研究得这么深是因为 KPI 指标有压力,你作为一个外人,如果也研究这么深只能说明你傻。

知识是有价值的,不仅价值各不相同,还受到规模的影响,作为微信来说,修复一个发生率极低的 crash,在过亿用户的基数下,很可能会减少几百万次崩溃,带来巨大的收益。然而这个收益,放在你的公司里,很可能就是 0。因此在选择自我提高方向时,一定要关注技术本身的价值,有些技术自身并不值钱,但经过公司规模的加成,就产生了相当大的价值,但这并不意味着你需要花时间学习它。尤其是某些无法形成体系,仅仅是独立知识点的技术,公司业务有需要,那为了工资得硬着头皮上,但如果自由时间里面还要花时间去学,就太浪费了。

我拒绝花时间了解这类技术的另一个原因在于,很多技术是与业务绑定的,有了核心知识,在业务需求的推动下,很容易就会诞生一个框架。比如应用组件化,很多公司都有自己的组件化库,其实实现原理也就是两大类,但发表到博客里面以后,就会有非常多的业务背景干扰读者的认知,如果读者追着这类文章看,是非常难从框架中剥离业务的干扰,直接挖掘基本原理的。因此大公司搞出来的某些框架,真的没有那么神秘,早期都是一个简陋的基础框架,当面对业务业务需求时,运用一些合理的编程思想,逐步迭代,最后发布了一个完善的版本,大可不必看得晕头转向以后妄自菲薄。

在之前面试的过程中,我也注意到很多应聘者其实对技术很感兴趣,经常刷微博上的文章,了解的也很多。但大多数情况下只知其然,不知其所以然。这是因为这些技术偏离了你的应用场景。以前我总为微博上的好技术无法在项目中落地感到纠结,后来我突然就明白了,这个思路就是错的,我应该挖掘公司项目的痛点,去微博,Google 等平台上的文章中寻找解决方案。所以我反对面向微博学习,应该要学一些更通用的技术,把技术与自己的项目结合起来,争取能在项目中落地,这比看十篇似懂非懂的技术文章还管用。

大公司所谓的基础知识

上一节解释了为什么不要研究单独的几个底层知识点,除了这种知识,以及逆向工程这种自成体系的,求职者只要具备扎实的基础,牢牢掌握一些基础知识就可以了。很多人都会觉得大公司对底层的基础知识考察很严格,基础知识不表示底层,也不一定就很简单,它们通常是那些被框架做了一层封装,以至于如果不用心思考,很可能就会忽略的知识,但不了解这些知识会对你的思考产生较大的影响,也很容易栽进某个坑里。

除非是变态公司以偏题怪题刁难人为乐,或者无能面试官只会问自己懂的东西以外,正常的大公司面试都会考察一些比较基础的问题,如果你还是觉得题目太底层,只能说明自己看问题的角度还不够深刻。

大公司着重考察基础知识,在我看来有两大原因:首先,在比较大型的项目中,业务逻辑非常复杂,所以很少有人有精力去大量的检查并提高你的代码质量,这就要求工程师具备相当扎实的代码功底,无论是代码风格还是语言的掌握都不能有太多问题。这样 Code Review 的时候才能把精力放在业务检查上,代码风格一笔带过,偶尔提醒一下就可以了。

另一方面,基础知识决定一个人思考问题的深度和交流问题的角度。一个不懂计算机背景知识的程序员,看问题的方式经常是错误的,错误的思考方式也就决定了他很难走到正确的道路上,比如我的一个外行朋友曾经接手了一个用 C++ 实现的 GUI,他的第一个问题是“如何在 C++ 中把字符串加粗”,读者大可不必感到荒谬,因为很多人思考问题的方式也不见得高明,在高水平,有经验的程序员看来,也许同样是不可理喻的。大公司复杂的业务逻辑同样也意味着很少有人会耐心的给你讲解每一个名词,比如哈希表,并发,并行,编译,链接等等名词,如果你听不懂或者理解不正确,往往意味着交流上会存在一些障碍。

因此我的建议是:数据结构,操作系统,计算机网络中的基础知识一定要扎实,怎么扎实都不为过,因为它决定了你看问题时候的高度,深度和思路。

让脚本取代 GUI

脚本语言非常重要,绝对是提升工作效率的神器,我强烈建议每个客户端工程师都应该了解一些 Shell 脚本并且掌握 Python,Ruby 和 JS 中至少一门语言。

理论上来说没有什么是脚本语言做得到,Java 做不到的,但脚本语言最大的特点就是快,快到极点的那种快。对于一些极度简单的小需求,比如统计一个文件中某一列数字的平均数,我敢保证在我得出结果之前你肯定还来不及打开 Java 编辑器。

脚本语言的另一个特点是高度的自动化,只要 Unix 和 Linux 系统一天不死,shell 脚本就会永远存活,你学习的知识就永远不会过期,比如 awk 和 sed 这样的神器,年龄比我大得多,至今还非常实用,未来的 20 年也丝毫看不出淘汰的迹象。试问一下,有什么知识能比一个几十年不会过期,而且每天都能用上的知识更值得学习呢?由于 Shell 是距离操作系统最近的脚本,了解了它以后,很多复杂的操作都可以被自动化。比如想找到项目中无用的图片,也就是一行命令的事。

考虑到脚本语言极高的开发效率,很多对性能不敏感的框架都会选择用脚本语言来实现,比如 Node,Flask,Rails,mitmproxy 等等。作为一个大前端工程师,不能总是依赖后端工程师,否则没了后端就只能搞单机模式了。因此了解脚本语言还有助于我们快速上手后端框架,这绝对是应聘时的加分项。

当然,很多人也会抱怨,我们是 iOS 工程师,平时的工作也接触不到脚本语言,该如何学习并投入使用呢。我的建议有三个:

整理自己的痛点, 并尝试着用过脚本去解决,这对学习 Shell 有奇效
整理公司项目开发中的痛点,尝试着用脚本去解决,适合练习 Python,Ruby 和 JS
抛弃 GUI

GUI 诞生的目的是为了更好的显示信息,而不是成为技术残疾者的拐杖。举一个简单的例子,我发现很多人都装了很多编程效率方面的工具,比如 gitx,sourcetree,tower 之类的 git 工具,还有什么快速打开模拟器目录,Derived Data 目录的小工具,我觉得这实在是太愚蠢了。放着大好的学习 Git 和 shell 的机会不要,把时间浪费在了解一个软件的 GUI 上,我觉得是完全不能接受的。尤其是对于 git 来说,我建议多问问自己,学会的是 git 还是 sourcetree 的按钮,将来换一个 GUI 工具,毕生功力还剩几成?至于某些小工具,这种绝佳的练手机会,怎么能拱手相让给别的软件呢,尤其是脚本可以自动化,软件就几乎不可能了。

学点前后端

我并不认为这一波移动互联网的寒潮是对移动端的否定,短期来看还没有设备能够取代手机。在我看来,它其实是 O2O 这种商业模式被证伪后,市场的自然反应。企业都认识到,移动端转型不是商业模式的救命稻草,所以为了节约成本,很多时候都是 Web 先行。这并不意味着移动端的需求没有了,只是现阶段存在着开发成本和收益之间的矛盾。目前移动端对传统行业的渗透还不够多,大一些的传统企业找外包,小一些的干脆就没有能力做了。

一方面,我认为随着框架,工具的日益完善,大前端开发的成本会持续下降,逼近业务复杂度本身。如果对前后端都有一定的了解,即使是做外包,也能以较低的人力和时间成本完成需求,比如熟悉 React Native 的开发者一个人就抵得上 iOS 和 安卓程序员各一人/毕竟大多数人工作还是为了钱,如果有稳定且较高的外包收入,工作也不是不能放弃。

另一方面,在与公司高 T 的聊天中,我了解到即使是大公司,对全栈也是有需求的。不是公司里的每个项目都是淘宝,微信和百度搜索,毕竟多一个人就多一份沟通成本,能够独立把前后端打通,负责整个项目的人,无论在哪里都会被抢着要。

然而这一切的前提都是有扎实的基础知识,比如对于大前端的开发来说,最重要的就是 HTTP 协议了,全栈不是全干,绝非读一篇 xxx 实战指南然后写几行 Demo 就算是入门的。因此一定要对框架背后的原理有深刻的了解,并且积累一定的实战经验才行。程序员应该是框架的主人,因为要节省时间,避免模板代码才选择框架,万万不能成为框架的奴隶,踩着框架的高跟鞋才能在需求的海洋中蹒跚两步,离开了 API 就不会写代码了。如果公司有业务需要,提供转岗的机会,而你又恰好有一定的基础和兴趣,不妨勇敢的尝试一下。否则就只能自己创造需求,比如找一个痛点并加以解决了。

总结

啰啰嗦嗦说了很多,其实总结下来没几点:

学习一个技术之前不妨先思考一下它在整个互联网体系中目前的位置,有什么样的未来,会对个人价值有多大的提高
数据结构,操作系统,编译原理,计算机网络这些基础知识不能丢,它决定了你看问题时候的高度,深度和思路
未来需要特定技术领域里的专才,更需要全栈,归根结底是需要最大化自己的价值。我个人的建议是掌握好脚本语言提高效率,打通前后端,这样无论在外包,独角兽创业公司还是大公司,都能独当一面
学习新技术时要避免好高骛远或者盲目迷信大厂,转发或艾特印象笔记提高不了自己,要结合实际场景,最重要的是要能落地!

© 著作权归作者所有