时光飞逝,一转眼已经是一年过去了, 去年的今天我写下了第一篇年度总结:一个普通iOS开发者的2015大总结。在写作那篇文章之前,我觉得一年前的自己完全是一个傻逼;今天重读一遍以后,我感觉一年前的自己也非常傻逼。在写下这一年总结的同时,我也希望明年的自己在回顾这篇文章的时候,可以发出不屑的鄙视。

实际上我认为:

刚开始学习的前五年是发展最快的五年,每一年都应该感觉到自己在过去的一年中发生了天翻地覆的变化。

本文既然是总结, 自然是充满了大量的主观看法。如果读者不认可其中的某些观点,大可呵呵一笑,抛之脑后,切勿较真,做无意义的争论。

Swift

我从元旦后就开始着手准备春招。首先翻译完了 Advanced Swift(盗版可耻),这是自己第一次完整的阅读完一本英语书籍,学到了非常多的知识,有英语方面的,也有 Swift 方面的,随后自己尝试着用 Swift 开发了一个小 app。虽然后续由于工作原因没有能继续接触 Swift,不过它的优雅、简洁还是深深的吸引了我。希望 Swift 4.0 发布后能够解决 ABI 稳定问题。

如果 Xcode 对 Swift 的支持能更友好,业内再提出成熟的动态化方案,我相信 Swift 会有更光明的未来和使用场景。

Swift 与后端开发

随着 Swift 的愈发成熟,业内出现了很多比较成熟的后端开发框架, 比如 perfect、vapor 等。然而我本人并不看好这一领域,主要是从编程语言和程序员两个角度出发。

理论上来说,任何可以调用 socket 接口处理网络请求的语言都可以用来做后端开发,然而对于 Swift 来说,除了处理网络请求以外,一个优秀的 API 也至关重要。不管是 HTTP 协议的解析,还是字符串、栈、时间等常用数据结构的操作,都不方便由做业务的程序员去手动解析。

框架的使用者应该关注业务开发,而不是通用业务的处理。比较遗憾的是,Swift 目前在这一方面做的还不够好,很多重要的操作缺乏语言层面的支持,导致开发者造轮子的成本过高。不过 Swift 已经成立了官方小组,致力于解决这一问题。

考虑到 Swift 还不是个非常成熟的语言,目前还在快速迭代。相比于语言本身,我认为人的问题才是阻碍 Swift 在服务端发力的最大原因。不管是现有哪种用来进行后端开发的语言,都有它本身的卖点。比如 Java 的高效(运行时效率)、稳定、全面,或者 PHP、Ruby 的语法简洁,易上手,还是 GO 的高并发,亦或是 Node.js 的全栈,都能在某个特定场景下派上用场。

目前的 Swift 似乎还没有找到属于自己的舞台,由于绝大多数开发者都是 iOS 开发者,他们并不适合转向服务端开发,这就意味着 Swift 能写 iOS 毫无吸引力(参考一下 JS 能做哪些事)。而对于具有服务的开发经验的开发者来说,Swift 又没有吸引他们切换过去的理由。

准备春招

一不小心就扯远了, 话题回到总结上来。完成了 Swift 学习的收尾工作后,我的精力主要放在春招上。由于大二下学期积累了三个月的实习经验,这一阶段的目的主要是夯实基础。因此重点读了两本书,《图解 TCP/IP》(总结)、《剑指 Offer》。

图解 TCP/IP

这本书主要是讲解了 TCP/IP 四层协议栈(或者分得更细点就是七层),通过一些插图和实际例子来解释枯燥的概念。我认为这是一本不可多得的好书,尤其适合新手入门。不过,如果想精通网络层,还是建议买 《TCP/IP 详解》和 《HTTP 权威指南》或者直接查阅 RFC 协议。

不过在准备面试,或者新手入门时,我觉得非常有必要通过一本简短的书籍来形成大致的知识框架和,这样后续才能有针对性的学习总结,对自己的知识框架进行各种修修补补。

剑指 Offer

这本书相当应试,不过也必须承认它概括了绝大多数常见的算法面试题。如果我们把面试看做是企业对应聘者的能力筛选和鉴定而不是刁难,那么从一定角度来说,也可以证明这本书涵盖了绝大多数常见的场景和算法。

如果不想只是纸上谈兵,还可以去 Leetcode 上找找书中问题对应的题目,参考全世界大牛的精妙解法也会受益匪浅。

iOS

作为一名 iOS 开发者,iOS 开发是我的本业,除了准备计算机基础知识外,我也学习了很多 iOS 开发的知识。以上的详细内容都总结在 《让 BAT 的 Offer 不再难拿》,就不赘述了。

入职

春招顺利的拿到了百度贴吧的 offer,入职以后受益匪浅。在善品、权叔等老司机的带领下,我有一种乡下人进城的兴奋感,感觉自己的成长速度非常快。

MVC 与 UITableview

UITableview 是 iOS 开发中最常见的 UI 控件之一,但是想写好一个 UITableview,做到封装、解耦,并与网络请求良好的结合起来并不容易。我花了一定时间学习了贴吧以前的框架,对其做了一些简化和整理,总结在这里: 如何写好一个UITableView。框架没有最优与全能,适合团队业务的就是最好的,所以这套框架主要是为了贴吧业务打造,但也有自己的不足,读者切不可照搬全抄。

高效使用 Mac

我比较看重开发效率,因为我认为开发者应该把宝贵的时间花费在工作本身,而不是与之无关的杂事上。并不耗时的高频操作和比较耗时的中频操作都应该使用快捷键或自动化工具对其进行简化,不过也切忌矫枉过正。对非常低频的操作进行自动化或者仅仅是为了装逼,往往会浪费大量不必要的时间,反而适得其反。

我总结了一篇文章 并做了一次直播,主要涉及全局快捷键、Xcode、Vim、Chrome、Vimium、Git、Zsh、Alfred、Zsh、Emacs 等. 强烈建议对此还不了解的读者收看直播回放。

iOS 深入

在工作之余,我对 iOS 领域的一些常用知识做了深入学习。

GCD 与多线程

虽然去年就复习过类似的话题,但仅仅是停留在总结整理的层面,说白了就是把所有 API 熟悉了一遍。这次学习时,我阅读了 GCD 的源码,从而从更深层次理解了 GCD 的实现原理,总结了一篇文章: 深入理解 GCD。

Runloop

最初接触 runloop 是听了孙源大神的分享,随着学习的深入,发现还是有必要对 Runloop 进行深入的理解。不过 Runloop 虽然重要,但实际使用中接触得并不太多,除了常见的 NSTimer 触发问题外,也就是性能检测时会与之打交道。所以它源码阅读的必要性并不是太高,我觉得只要对 Runloop 的基本概念和工作原理有所涉猎即可。遇到实际问题时可以查阅 ibireme 的 深入理解RunLoop。

我写了一篇: 深入研究 Runloop 与线程保活 作为自己的学习总结。

线程调用栈

上一节谈到了利用 runloop 检测主线程的卡顿。为了找到性能瓶颈,也就是优化点,我们需要在卡顿发生时得到实时的线程调用栈。这就意味着一切依赖于线程层面的操作都会破坏原来线程的调用栈。在尝试使用信号无果后,最终我选择了参考第三方开源框架,直接利用 C 语言解析函数调用栈。具体总结参考: 获取任意线程调用栈的那些事。

iOS 中有很多锁,从最底层的互斥锁、信号量到顶层的 @synchronized,应有尽有。虽然我实际使用经验并不多,但还是研究了一下他们的实现原理和性能优劣: 深入理解 iOS 开发中的锁。随着对多线程在理论和实践上的进一步接触,我相信还会有更具深度的总结面世。

Xcode 项目配置

出于对 Cocoapods 工作原理的兴趣,我前段时间手动模拟了它的工作过程(自动化是通过 ruby 脚本完成的,相对而言重要性低很多)。在这一过程中,更重要的是对编译、链接、Xcode 工程配置的理解。由于时间原因,目前还没有形成总结性文档。

全栈

相比于 iOS 方面的钻研,2016 年最让我感到激动和收益满满的是横向的拓展。关于为什么会选择横向发展路线,在我的 新的开始 一文中已经有了详细的阐述。

哈希表

哈希表是常见的数据结构,但是很多人对他的掌握都非常浅显。曾经问过很多人一个很简单的问题:“为什么很多哈希表的实现中,数组的长度都是 2 的整数次幂?”。根据我的观察,能答出这个问题的人寥寥无几,有很多看上去很正确的废话,其实恰恰说明了大多数人多哈希表的理解还不够深入。

除此以外,不同的语言和框架(OC、Java、Redis、一致性哈希) 对哈希表的实现都各不相同,他们的取舍恰恰说明不同场景下我们关注的指标并不一致,必须舍弃一些无关紧要的功能点,来换取主要功能的性能的大幅度提高。具体对比请参考: 深入理解哈希表。

Node.js

市面上有很多介绍 Node.js 的优秀文章和书籍,作为一个不懂 Node.js 的小白,其实我只关系以下几个问题:

  1. 为什么要从现有的后端开发框架切换到 Node.js?
  2. Node.js 是银弹么,还是有特别适合自己的使用场景?
  3. Node.js 的事件循环是如何工作的?有什么好处?
  4. Node.js 是异步单线程的, 那么如何最大程度的利用多核 CPU 的所有性能?

作为上述问题的回答,我总结了 为什么要用 Node.js。

前后端分离与前端开发流程

在学习 Node.js 的过程中,我接触到了一个新名词:前后端分离。对于客户端开发者来说,前后端分离是一件天经地义的事情。前端界面是由编译后的代码生成的,相对来说比较固定。前后端的主要交流方式是 JSON/protobuf 等数据交换格式。

然而对于前端开发者来说,事情远远不止这么简单。由于前端的 UI 样式完全由 Server 下发,所以很容易就产生了前后端业务和代码的耦合。所以前后端分离说的就是前端开发和后端开发如何进行解耦和数据交互,详见 移动端开发者眼中的前端开发流程变迁与前后端分离。

利用 JS 等脚本语言实现客户端热更新

不管是 JSPatch 还是 React Native,它们都能做到客户端的热更新,甚至无需通过 AppStore 即可发一个新版本。它们之所以能够做到客户端热更新,主要是依赖了客户端对 JavaScript 的支持以及 iOS 自身基于 runtime 的元编程技术。首先,利用 JSON 传递信息的区别在于它仅有描述信息,却无法携带逻辑信息。

通过官方认可的 JavaScriptCore 框架,我们可以运行一段 JavaScript 代码并获取运行结果。通过对运行结果的解析,我们可以利用 runtime 动态的调用本地预定义好的方法,从而实现了动态化。

React Native 的本质是一个 Hybrid 桥。它与 React 具有相同的 API,为了实现相同的效果,客户端会调用本地的方法(比如 addSubview 等)。详细请参考: React Native 从入门到原理。

脚本语言

一般来说我们认为脚本语言就是没有编译器的、由解释器动态解释的语言。它通常具有弱类型、格式简单、开发效率高等优点,但是作为代价,用脚本语言来开发大型项目会遇到诸多问题。比如性能、调试等等,毕竟它们原本只是用来快速完成某个小的需求。

我最先接触的是 python,我使用 python 编写了 alfred 的一个 workflow,后来在 leader 的带领下实现了一个可以 hook 请求和返回结果的 http 代理服务器。有了实战的机会,也就成功脱离了 hello world 的水平了。

同时我也简单接触了 Ruby。光从脚本语言的角度来看,它和 Python 的作用相仿。不过很多领域特定语言(DSL) 都选择了 Ruby 来实现, 比如我们常用的 cocoapods 中的 Podfile,如果不说,可能只有少数人能意识到这其实是一段标准的 Ruby 代码。

之所以选择用 Ruby 来实现,是因为它的语法可读性更好,看上去就像一段普通的描述性文字。详细的分析可以参考: 白话 Ruby 与 DSL 以及在 iOS 开发中的运用。

严格意义上来说,Shell 脚本才是脚本语言的鼻祖,它提供了非常多常用的工具,比如 awksed 两大文本处理利器。如果需要对文字、文件目录做简单的逻辑操作,应该优先使用 Shell 而不是其他脚本语言。

不同的脚本语言往往是为了解决不同领域的问题而诞生的(虽然它们也可以解决其他问题),遇到问题的时候应该选择最合适、优雅的解决方案,而不是总想着复用当前技术栈。俗话说:“如果你只有锤头,那看什么都是钉子”。

面向接口编程

Swift 诞生后就一直宣传自己面向接口编程的特性,然而在我看来它不过是一种多继承的实现方案。且不谈继承的缺点以及在它和组合之间如何选择,光是多继承,就有很多种实现。比如 C++、Python、Java、Ruby 都有各自的实现。其中有优雅的,也有相对来说比较暴力直接的。

我个人更喜欢 Java 对多继承的实现,与之相比,Swift 的面向接口编程还有一些可以提高的地方。详细可以参考: 从 Swift 的面向协议编程说开去

安卓

从 12 月份开始,由于安卓同事返校上课,我有机会开始接触安卓开发。目前还停留在小白阶段,只能根据前人的代码抄抄改改。安卓的学习主要还是 API 的积累和 Java 语言的学习,希望能在明年总结出更多关于安卓的优秀文章。

我的 2016

对于把好好的年终总结写成了博客摘要我是很不满意的,如果用一个词来总结我的 2016 年,我想那毫无疑问就是:“拓宽”。虽然 iOS 还没有达到炉火纯青的地步,但我还是义无反顾的开始了横向拓宽。我相信一个人才的最大价值,不是做好某一个具体的小需求(这是前提),而是站在更高的角度做更大的事。

16 年技术栈拓展中,最大的三个收获应该是前端、Python 和安卓。然而考虑到与工作相结合,我想前端技术暂时可以放一放,重点学习 Python 和安卓也许会对 KPI 更加有利。

当然,好的书还是要读的。博客可以解释清楚某一个问题,而好书可以解释清楚某一个领域。在 Server 方面,李智慧的 《大型网站技术架构》 可以算作一本非常优秀的入门版书籍,介绍了诸多常见的属于和概念。而《计算机程序的构造和解释》(SICP) 作为 MIT 几十年来的教科书,是一本非常经典的介绍函数式编程的书籍。以上两本书推荐给感兴趣的读者。

过去的这一年成长了很多,从简书、微博几十个粉丝的小菜鸟,到几千粉丝的小 V,一路走来收获满满。不过我逐渐意识到越是大型的平台,普通用户的质量就越接近于行业平均水平。因此粉丝数、喜欢数并不值得参考,而且很多交流其实是浪费时间。因此在新的一年中我会减少社交平台上的互动,把有限的精力投入到线下的生活、工作、学习中去。

2017 年的计划

在去年的年终总结里,我列出了五点计划:

  1. 继续翻译优秀的英文文章。这一点做的不太好,虽然有幸加入了 SwiftGG 并翻译了一些 Swift 文章,但是总的来说数量还不够。不过考虑到还有非常多要做的事,翻译文章的性价比似乎就不太高了,所以暂时搁浅。
  2. 阅读优秀的博文。objc.cn 的文章在带着读,由于掌握了 Google 搜索, 所以再也不会像去年一样看 CSDN 了,从这一点来说,第二个目标算是圆满完成。
  3. 技术与基础。今年学习了 GCD、Runloop、Runtime、锁、Cocoapods、React Native 等技术,算是加深了技术深度,
  4. 读书。读完了 《图解 TCP/IP 》、《剑指 Offer》、《大型网站技术架构》、《计算机程序的构造与解释》,双十一还买(挖)了不少书(坑)。
  5. 实习。在贴吧和凤巢的日子里,小组里的各位同事一直在帮助我成长,我的每一丝进步都要感谢他们的帮助。

总的来说 16 年的计划圆满完成了,在新的一年里我为自己制定了几个小目标:

  1. 业务: 也许业务没有技术重要,但是没有业务的积累,再厉害的技术也只会浪费时间,甚至带来负面作用。踏入工作岗位后,我希望在 2017 年更加深入的理解团队业务,更好的融入团队的交流协作中。
  2. 读书: 双十一买了十几本书,目前看来优先级最高的是《七周七并发模型》和 《改善 Python 程序的 91 个建议》,如果有空的话 《Java 编程思想》和 《Effective Java》、《Android 开发艺术探索》也在计划中。
  3. 技术: 所谓的全栈工程师,或者 T 型人才并不是全干工程师,每一门技术必须掌握到一定深度。因此在跨界时切忌自我麻痹,不能总以“我是新手”为理由来安慰自己。我希望在新的一年里在 Python 和 Android 方面达到一定深度,以工作为标准来要求自己。

我的 2016 年总结相关推荐

  1. 2016计算机二级java_2016计算机二级JAVA练习题及答案

    2016计算机二级JAVA练习题及答案 21.下列选项中,不能输出100个整数的.是( ). A.for(int i=0;i<100;i++) System.out.println(i); B. ...

  2. 电大计算机应用,(2016年电大)电大全国计算机应用考试网考.doc

    (2016年电大)电大全国计算机应用考试网考 计算机基础知识一般认为,世界上第一台电子数字计算机诞生于-------.(1946年)计算机当前已应用于各种行业,各种领域,而计算机最早的设计是针对--- ...

  3. 2016多校赛2 A 数学推公式 E 极角排序,组合数(待补) L dp+bitset优化

    2016 Multi-University Training Contest 2 A - Acperience 题意:给出w[],求S((w[i]-aB[i])^2)的最小值(B[i]为1或-1). ...

  4. 2016.04.09 使用Powerdesigner进行创建数据库的概念模型并转为物理模型

    2016.04.09 使用Powerdesigner进行创建数据库的概念模型并转为物理模型 2016-04-09  21:10:24     本文原创受版权保护,严禁转载. 请大家不要用于商业用途,支 ...

  5. 2016 - 1- 21 - RunLoop使用(2016-1-24修改一次)(2016 - 1 - 24 再次修改)

    一:常驻线程 :当需要一个线程一直处理一些耗时操作时,可以让它拥有一个RunLoop.具体代码如下:    1.通过给RunloopMode里加源来保证RunLoop不直接退出. 这里有个很重要得知识 ...

  6. 个人所得税计算器2016 by Jacksile

    个人所得税计算器2016 个人所得税计算器2016 税前薪资: 元 各项社会保险费: 元 起征点: 35004800元 应缴税款: 元 实发薪资: 元 个人所得税计算公式 应纳税额 = 应纳税所得额 ...

  7. 职称计算机 菏泽,山东菏泽2016年职称计算机首批考试时间

    一.考试范围及科目(模块) 1.参加2016年全国专业技术人员计算机应用能力考试的人员,须按照<2014版全国专业技术人员计算机应用能力考试科目(模块)代码表>(以下简称<2014版 ...

  8. 考研计算机专业课怎么复习,2016考研计算机专业课如何复习?

    2016考研计算机专业课如何复习? ?基础复习阶段 以指定参考书为主,兼顾笔记,进行专业课的第一轮复习.看书要以理解为主,不必纠缠于细节,并在不懂的知识点处做上标记. 第一步,选择一本难度适宜.内容全 ...

  9. c语言字符串机考题,2016全国计算机二级《C语言》机考试题及答案

    2016全国计算机二级<C语言>机考试题及答案 一.程序填空题(共18分) 下列给定程序中,函数fun的功能是:求ss所指字符串数组中长度最短的字符串所在的行下标,作为函数值返回,并把其串 ...

  10. 宁波大学计算机专业复试,2016年宁波大学信息科学与工程学院计算机专业考研复试题库. (1)...

    2016年宁波大学信息科学与工程学院计算机专业考研复试题库(二) ------------------------------------------一.选择题 1.下列有关浮点数加减运算的叒述中,正 ...

最新文章

  1. GStreamer跨平台多媒体框架
  2. MS UI Automation Introduction
  3. 图解八大排序算法——我见过的最详细的讲解(转)
  4. 利用nofllow与内页链接做好SEO
  5. 划时代的项目管理核心引擎——DynamicGantt 动态图甘特图
  6. 【BUG解决】使用body-parser失效的实例解决
  7. 爬虫实战:使用Selenium爬取京东宝贝信息
  8. 什么是Spring inner beans?
  9. JVM编译时和运行时状态
  10. linux 重庆mysql_Linux服务器上MYSQL的安装
  11. 遍历文件夹并移动其中所有的文件
  12. 乔布斯不在了,世界一大步,苹果一小步。
  13. 转, C# 如何在MVC3中取消备用控制器的选择
  14. WinRAR 6.0 永久去除广告
  15. python使用matplotlib库构建动态图表 --基于animation模块
  16. html发展时间轴纵向插件,jquery响应式垂直时间轴插件vertical-timeline
  17. 国产机们的高端梦:OV保守、米耀激进
  18. python编写一个简单的程序验证码_Python实现一个简单的验证码程序
  19. 【字符串】L1-027 出租 (20分)
  20. 卓有成效的管理者总结与思考

热门文章

  1. 编译librtmp for Android
  2. 苹果电脑打开wps云文档方法
  3. Python 文字小游戏
  4. 高考排名liuseroj.picp.io
  5. word段落每行首字怎么对齐_Word段落首行左右缩进及五种对齐方式
  6. HoloLens新版OpenXR
  7. 云计算方向研究热点、 云计算有怎样的发展前景?
  8. IDEA 卡住半天,buid(编译)不动——解决办法(适用于maven和gradle)及定位思路...
  9. anacoda里面安装包显示失败_Premiere2020安装包下载及安装教程(附pr2020配置要求)...
  10. 全国计算机三级网络技术电子版,全国计算机三级网络技术最新版笔试电子教材(完全免费版).doc...