网络ID:杭城小刘,城市:顾名思义,人在杭州。1995年出生,本科毕业,现在是一名 iOS 资深工程师。兴趣爱好广泛:乒乓球、美食、电影、健身、山地车、养了2只布偶猫(Simba & Bella)、养花。技术领域:iOS、Web 前端,写过 Node、PHP 后端服务、写过爬虫、研究过反爬虫技术方案。在成长的路上…
刚毕业开始还是一名普通的 iOS 工程师,做的东西一般是跟着 TL 开会讨论需求,完了自己脑补技术细节,完了编码、UI 还原、测试、发布、维护。在第一家公司做开发的时候,某次和一个后端工程师对接口遇到问题,人家说“别跟我说接口有问题。你跟我说是什么样的问题?我需要参数”。然后初生牛犊(小菜鸟)就把 Xcode 下面的 Debug 信息截图发出去,被人怼,说我需要网络的具体参数,Request、Reponse 信息。当时很尴尬,我在想封装好的网络框架,我一个个下断点 Debug 截图给你吗。后来才知道有 Charles 这么个抓包工具,简单搞了搞 Charles 之后就将截图 Request、Response 信息给他了,这样他没话说了,老老实实改了接口 Bug。当时他问我 Request、Response 的时候真的超尴尬,我说你等我半小时,我找好发给你。( Too young, too simple)。
第一次看到 Charles 有那种看到仙女一样的感觉,因为它不只是可以抓包看 HTTP、HTTPS 的网络请求,还可以模拟数据、篡改网络请求信息、篡改网络返回的信息、模拟弱网环境、接口压力测试(类似于 Load Runner)、还可以隔山打牛(Map Remote:请求域名 A 下的接口 a 却重定向到域名 B 下的接口 b)。功能非常多,让我爱上了它,顺道写了一篇文章。
另一个有趣的事情是慢慢在公司有了起色,自己钻研进步了很多。在做的东西 iOS Native + Hybrid 模式的应用,因为在校实验室期间有 web 前端经验,所以在公司经常设计 JS 与 Native(iOS、Android)的通信机制、Hybrid 的能力等等,Debug 的时候经常踩坑,比如 Android 浏览器访问 localStorage 需要开启权限、某些低版本的 Android 不支持 ES6 写法(Vue、React等工程自动引入 Babel 打包构建的工程是转换过的。之前的老工程直接写 ES6,则低版本浏览器不支持)。还有一些 CSS 在 iOS、Android 两端表现不一致。因为公司和别的上市公司合作项目,成立了微信群,我们公司对外输出 SDK,由于另一名同事解决不了。直接跟我说“刘哥,上吧”。由于经常解决疑难杂症,导致对面那个公司的项目经理,问我要不要跳槽,让我去他们公司工作
说到工程师,肯定要谈如何进阶。那么我作为一个刚毕业不久,从 普通工程师 -> 高级工程师 -> 资深工程师,谈经验不敢当,说说个人的心路历程吧。
首先刚踏入职场,你必须完成从学生到职场的转换,这个转换不是说换个地方做事就行了,而是态度和观念需要改变。学生时代在校不管是课程作业还是毕设、或者学校实验室的那些东西,现在看看都很 low(排除一些高端院校的顶级实验室项目)。
遇到项目,你要认真分析、思考、编码。完了之后想想有没有优化空间、代码规范。代码写多了,可以自定义自己的工作流 和快捷键。
很多人强调没时间去学习,说什么白天在工作,下班后可能要回家路上花费时间、吃晚饭、然后累了一天可能要想着健身、娱乐下。一天除非睡觉、吃饭时间你有多少时间?所以我觉得学习和工作不是互斥的事件,你需要矫正态度,工作中的每个需求都是一次学习进阶和检验的过程,别人给了需求,你需要系统设计、架构设计、思考需要几个类、每个类负责什么行为、属性,对外暴露什么接口,类与类如何通信、如何低耦合、高内聚、可拓展?Unit test 设计等等问题都要考虑清楚。剩下就是编码实现了,这个时候考虑的就是一行行代码如何书写,才符合团队规范、业界规范、代码如何分组、如何做到自解释、代码注释等等都需要做到极致。完成后跑单元测试、最后集成测试。提交给测试工程师的项目个人至少保证 90% 的测试 case 通过,ut 覆盖率至少 90%。关于测试也有一堆经验,等后期我会出文章讲讲。
个人学习和工作的时候注意积累和归纳总结,梳理自己的技术栈和知识体系,等下次学到了新的东西塞到体系里面对应的地方去。最后你的知识系统会越来越完善。
工程师强调几个方面:
大多数人喜欢碎片化时间阅读一些文章或者自己感兴趣的技术博文。比如你在上下班路上、点餐等饭时间看几个公众号技术文章,很多人会大致浏览完。我觉得这样不如不读,或者收效甚微。因为脑子只有印象的话,看完的文章过半年后问,肯定一问三不知了。与其多篇文章大致浏览,不如精读一篇文章,并动手实践每个技术点和细节。必要时做好博文记录最后总结输出。
另外对于每个技术不要停留在会用(我称之为 api 资深工程师)而是知道这个 api 背后的原理,设计模式、设计的优缺点。比如 iOS 领域著名的 WKWebView 很多人知道 NSURLProtocol 可以拦截其他的网络请求却拦截不到它里面 post 的 body 内容。你查看了 webkit 源代码之后就知道 WKWebView 官方宣传快,是说自身做的事情少了,很多任务比如网络是新开了一个独立线程去处理,所以独立线程处理网络完了通过 IPC 的方式将 post 的 body 通过压缩然后 IPC 给 WKWebView 这会非常消耗资源,所以系统索性不给你传递了。
带着这个疑问看看 Chrome for iOS 的开源项目(至于为什么会看它?因为个人研究多端融合能力、Chrome 这样的浏览器如何渲染处理等流程感兴趣所以看的),看到它里面在用 post 传 body。纳闷了,和 webkit2 源代码不一致。这些现象等都是需要深入才可以理解的。当你遇到一个问题发现网上找不到资料或者资料比较少的时候你就算对这个问题的研究比较深入了。
此外,不管做产品还是技术都不要凑合,必须要做到极致或者最好。上面说的反爬虫技术是我在公司担任 iOS 工程师的时候做的。当时进去一个月写完一个 App,追到 Android 进度。然后不满足于进度,在此基础上做到的一些优化、且通过抓包方式进行业务测试的时候找到了 Android 和服务端的一些 Bug,最后还发现安全性较低,在此基础上,做了 HTTPS + 证书验证 +RSA 证书校验、AES 数据加密,做到了 App 被别人抓包马上就断掉链接。假如技术再高明些看到请求信息也是加密过的(不是 HTTPS 自己的加密,是自定义的加密)和防重放策略。
之后鉴于公司的网站太落后,用 Vue 进行重写,再做了安全升级等工作,这样总经理看到个人能力,担任小公司大前端负责人的岗位。这阶段的成长也蛮快的
然后换工作,也是一样,严格要求自己,半年时间做了无痕埋点、组件化、模块化、Hybrid 能力提升、商城业务模块开发等等,从高级工程师升级为资深工程师。个人目标2年后成为技术专家。
很多人会去问有没有较好的学习资料是什么?我觉得如果有人回答除官方文档之外的答案,那么这个人本身就不够专业。在我看来官方文档是设计者(最熟悉技术细节的人)写出的注释和说明。那么肯定是最佳实践。举个例子 Objective-C 里面对 NSDictionary 进行处理成 JSON 字符串,解析的结果是会带空格和换行符的,但是服务端恰好如果对空格和换行敏感的话,那么你们的逻辑就会和预期的不一致。看看下面的代码。
NSJSONWritingSortedKeys(兼容性)、NSJSONWritingPrettyPrinted (换行符)
NSDictionary *dict = @{@"name": @"lbp"};
NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding];
很多人转换后可能会去做字符串处理,正则替换空格和换行符。稍微好一些的可能会看到官方的在 iOS11 推出一个新的枚举值 NSJSONWritingSortedKeys
。那么就是判断当前系统小于 11 则字符串替换,否则就使用新的参数。如果你仔细看官方文档,上面说的非常仔细。看看下面的官方说明。
Generate JSON data from a Foundation object. If the object will not produce valid JSON then an exception will be thrown. Setting the NSJSONWritingPrettyPrinted option will generate JSON with whitespace designed to make the output more readable. If that option is not set, the most compact possible JSON will be generated. If an error occurs, the error parameter will be set and the return value will be nil. The resulting data is a encoded in UTF-8.
另外,越来越觉得架构设计对于架构组同学来说是非常重要的。
为什么?假设你一个需求,预期10天时间;前期架构设计、类的设计、Uint Test 设计估计7天,到时候编码开发2天完成。
这么做的好处很多,比如:
个人是很喜欢程序员这个工种的。做事情纯粹些、且培养了不断学习思考的能力和习惯。不断学习和思考是每个行业都需要的基本素养,所以看到事情本质、不断学习、不断进阶就是人生常态吧