程序员应如何打破平庸,杜绝淘汰,避免内卷!【强烈建议收藏!】
前言
在平时的日常工作、学习、开发、写博客能巩固自身!
正好,这次就借着这个机会分享一波,不出意外又是一篇托家底的分享,大家记得点赞、收藏。好东西记得分享哦。
首先如何解决 35 岁程序员误解?
古人云:“活到老,学到老。”互联网算是最辛苦的行业之一,“加班”对程序员来说已是“家常便饭”,同时互联网技术又日新月异,很多程序员都疲于应付,叫苦不堪。
以至于长期以来流传一个很广的误解:35 岁是程序员工作的终点。
如何在繁忙的工作中做好技术积累,构建个人核心竞争力,相信是很多程序员都在思考的问题。
对于当下的生存,个人的意见仍然是去依附,尤其是依附于单一公司,个人发展要适配市场需求,同时在资本回报率远大于劳动回报率的大背景下,能够早日攒下资本实现资产增值和收入多样化是我们的最终目标。
对于一穷二白的年轻人,无非四条路:
年轻时应该选择当下高回报的技术路径,早日攒下可观的财富,去买楼买铺,为自己获取资产保障,靠资本投资或者被动收入保底。
打通技术栈,不再专纠结于细节,将自己摆在供应商的位置,将公司摆在客户的位置,将自己的技术团队和开发成果打造成为公司业务链中的一环,而不是一颗精密的螺丝钉,然后慢慢从技术思维过渡到客户服务思维,争取将团队的开发成果产品化打造成同类市场产业链中的一环,可以为行业内其他公司提供整套技术咨询和开发服务,填补一定的市场空白,总体而言就是:功能->模块->框架->产品的进化。尽管仍然是行业依附,但至少了对公司的依附,有机会获取超越工资收入的财富,进行更多的资本投资保障未来生活。
进入师医公等类体制内工作, 尽管收入不高,但目前看来至少能保底,还有一定社会地位。
不做有明确成长路径的技术类工作,从事创意类工作,并且要善于利用互联网早日攒下名声和流量,可以靠流量和名声生活,同样美滋滋,优点是替代性小,大流量可以攒下巨大财富,可以尽早进行资本增值,保障后半辈子生活。缺点是太吃天赋和运气,上限下限差距过大,有点赌博性质,而且要能做拉得下脸割粉丝韭菜的心理建设。
技术本身不是最重要的,重要的是持续地学习。
文章进阶路线图,需要的可以自行保存下载
进阶总纲
iOS 开发
架构
iOS基础框架底层原理
视频分析 iOS 架构模式
观看地址:https://www.bilibili.com/video/BV1wA411H7jB
iOS高级框架底层原理
音视频
视频解析手把手教 iOS 音视频开发
观看地址:https://space.bilibili.com/107521719/channel/detail?cid=157340&ctype=0
iOS音视频底层
iOS核心动画
自行领取直达链接:【点击获取】
RxSwift从初探到底层分析
函数响应式编程
一: 函数式
函数式编程简称 FP(FunctionalProgramming),函数式编程就是一种抽象程度很高的编程范式,它将计算机运算看做是数学中函数的计算,而纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是:
允许把函数本身作为参数传入另一个函数,同时还允许返回一个函数!
函数表达式:
y = f(x) ---> x = f(x) ---> y = f(f(x))
常规需求例子,感受函数式的舒服!
对于数组 [1,2,3,4,5,6,7,8,9,10],首先获取 > 2 的数字,
获取到的数字之后 + 1,
再输出所有数字中的偶数
上面的代码嵌套层次之深,我觉得已经非常恶心
代码的可读性也是非常差的
代码复用性较低
维护以及代码构建成本太高,这样就成了函数式出现的必要性
代码层次非常清晰
代码可读性高
代码复用性高
代码简洁,直接面向开发需求
二: 响应式对象对某一数据流变化做出响应的这种编码方式称为响应式。
例如我们在爱奇艺平台观看视频,我们只需要在某一个时刻订阅了这个视频,后面平台自媒体运营者不断更新视频,我们随着时间也能自定接受推送,这就是响应在 iOS 开发中我们经常会响应一些事件 button、tap、textField、textView、notifaction、KVO、NSTimer 等等这些,都需要做响应监听,响应后都需要在对应的响应事件中去做处理,而原生开发中,触发对象与响应方法是分离的,如 button 的初始化和点击响应方法是分离的。功能代码与逻辑代码分析,导致很多比较恶心的感觉!
blingbling, blingbling, blingbling!
RxSwift 闪亮登场
ReactiveX 不仅仅是一个编程接口,它是一种编程思想的突破,它影响了许多其它的程序库和框架以及编程语言。它拓展了观察者模式,使你能够自由组合多个异步事件,而不需要去关心线程,同步,线程安全,并发数据以及 I/O 阻塞。
RxSwift 是 Rx 为 Swift 语言开发的一门函数响应式编程语言, 它可以代替 iOS 系统的 Target Action / 代理 / 闭包 / 通知 / KVO,同时还提供网络、数据绑定、UI 事件处理、UI 的展示和更新、多线程……
鉴于 Swift 日渐增长的影响力,ios 开发者不可避免的要学习和使用 Swift 这门语言进行编程开发。
RxSwift 对使用 Swift 的帮助有如下几点:
Swift 为值类型,在传值与方法回调上有影响,RxSwift 一定程度上弥补 Swift 的灵活性
RxSwift 使得代码复用性较强,减少代码量
RxSwift 因为声明都是不可变更,增加代码可读性
RxSwift 使得更易于理解业务代码,抽象异步编程,统一代码风格
RxSwift 使得代码更易于编写集成单元测试,增加代码稳定性
一: button 点击事件
二: textfiled 文本响应
三: scrollView 效果
从上面三个 UI 效果来说,如果原生实现必将做很多恶心的处理:
addTarget 或者实现响应代理, 但是在 RxSwift 的世界里只需要一句代码:
爽!
四: KVO
原生 KVO 就需要三部曲,非常恶心,其实对于我们开发来说根本没必要! RxSwift 还是温柔的一句代码搞定
五: 通知
通知的实现,也是比较友善的:
编程习惯都有在 RxSwift 风格里面保留 这样能够最大的降低开发者的门槛,也是一个优秀框架的必备条件
六: 手势
很多小伙伴可能会吐槽手势怎么不那么爽!其实你误解,RxSwift 是实现的响应关系,本身手势也是需要添加事件对象的!
当然这里我个人建议:
可以更多拓展一层!
降低代码量 感觉RxSwift会把开发者变傻,哈哈哈......
七: 网络请求
针对 URLSession 也是封装处理。提供了 response,data,json 不同的便于开发者选择的合适函数,说白就是方便但是针对网络这一层,我们一般开发肯定是要处理,不可能这么简单(毕竟不符合开发需求)其实 RxSwift 在网络这一层也是有很多响应式处理:
比如典型的 RxMoya
八: timer 定时器
RxSwift 实现的 timer 免去了我们计时器的一些不必要的麻烦
runloop 影响
销毁问题
线程问题
RxSwift 这个框架非常牛逼,把函数响应式玩到了高潮!无论从代码量,还是从代码的可读性,抑或代码的复用性......都是大大优化!让开发者抛弃更多的胶水代码,直面开发需求。如果你还在为你开发效率而烦恼,那么 RxSwift 是你不二的选择!
性能优化探索
一、入门级
1、 用 ARC 管理内存
2、 在正确的地方使用 reuseIdentifier
3、 尽量把 views 设置为透明
4、 避免过于庞大的 XIB
5、 不要阻塞主线程
6、 在 ImageViews 中调整图片大小。
如果要在 UIImageView 中显示一个来自 bundle 的图片,你应保证图片的大小和 UIImageView 的大小相同。在运行中缩放图片是很耗费资源的,特别是 UIImageView 嵌套在 UIScrollView 中的情况下。如果图片是从远端服务加载的你不能控制图片大小,比如在下载前调整到合适大小的话,你可以在下载完成后,最好是用 backgroundthread,缩放一次,然后在 UIImageView 中使用缩放后的图片。
7、 选择正确的 Collection。
Arrays:
有序的一组值。
使用 index 来 lookup 很快,使用 value lookup 很慢, 插入/删除很慢。
Dictionaries:
存储键值对。
用键来查找比较快。
Sets:
无序的一组值。
用值来查找很快,插入/删除很快。
8、 打开 gzip 压缩。
app 可能大量依赖于服务器资源,问题是我们的目标是移动设备,因此你就不能指望网络状况有多好。减小文档的一个方式就是在服务端和你的 app 中打开 gzip。 这对于文字这种能有更高压缩率的数据来说会有更显著的效用。 iOS 已经在 NSURLConnection 中默认支持了 gzip 压缩,当然 AFNetworking 这些基于它的框架亦然。
二、中级
1、 重用和延迟加载(lazy load) Views
更多的 view 意味着更多的渲染,也就是更多的 CPU 和内存消耗,对于那种嵌套了很多 view 在 UIScrollView 里边的 app 更是如此。
这里我们用到的技巧就是模仿 UITableView 和 UICollectionView 的操作: 不要一次创建所有的 subview,而是当需要时才创建,当它们完成了使命,把他们放进一个可重用的队列中。这样的话你就只需要在滚动发生时创建你的 views,避免了不划算的内存分配。
2、 Cache, Cache, 还是 Cache!
一个极好的原则就是,缓存所需要的,也就是那些不大可能改变但是需要经常读取的东西。
我们能缓存些什么呢?一些选项是,远端服务器的响应,图片,甚至计算结果,比如 UITableView 的行高。
NSCache 和 NSDictionary 类似,不同的是系统回收内存的时候它会自动删掉它的内容。
3、 权衡渲染方法.性能能还是要 bundle 保持合适的大小。
4、 处理内存警告.移除对缓存,图片 object 和其他一些可以重创建的 objects 的 strongreferences.
5、 重用大开销对象
6、 一些 objects 的初始化很慢,比如 NSDateFormatter 和 NSCalendar。然而,你又不可避免地需要使用它们,比如从 JSON 或者 XML 中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们,可以通过添加属性到你的 class 里或者创建静态变量来实现。
7、 避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。
8、 选择正确的数据格式.
解析 JSON 会比 XML 更快一些,JSON 也通常更小更便于传输。 从 iOS5 起有了官方内建的 JSONdeserialization 就更加方便使用了。 但是 XML 也有 XML 的好处,比如使用 SAX 来解析 XML 就像解析本地文件一样,你不需像解析 json 一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。
9、 正确设定背景图片
全屏背景图,在 view 中添加一个 UIImageView 作为一个子 View
只是某个小的 view 的背景图,你就需要用 UIColor 的 colorWithPatternImage 来做了,它会更快地 渲染也不会花费很多内存:
10、 减少使用 Web 特性。
想要更高的性能你就要调整下你的 HTML 了。第一件要做的事就是尽可能移除不必要的 javascript,避免使用过大的框架。能只用原生 js 就更好了。尽可能异步加载例如用户行为统计 script 这种不影响页面表达的 javascript。注意你使用的图片,保证图片的符合你使用的大小。
11、 Shadow Path 。
CoreAnimation 不得不先在后台得出你的图形并加好阴影然后才渲染,这开销是很大的。使用 shadowPath 的话就避免了这个问题。使用 shadow path 的话 iOS 就不必每次都计算如何渲染,它使用一个预先计算好的路径。但问题是自己计算 path 的话可能在某些 View 中比较困难,且每当 view 的 frame 变化的时候你都需要去 update shadow path.
12、 优化 Table View
正确使用 reuseIdentifier 来重用 cells
尽量使所有的 view opaque,包括 cell 自身
避免渐变,图片缩放,后台选人
缓存行高
如果 cell 内现实的内容来自 web,使用异步加载,缓存请求结果
使用 shadowPath 来画阴影
减少 subviews 的数量
尽量不适用 cellForRowAtIndexPath:,如果你需要用到它,只用-一次然后缓存结果
使用正确的数据结构来存储数据
使用 rowHeight, sectionFooterHeight 和 sectionHeaderHeight 来设定固定的高,不要请求 delegate
13、 选择正确的数据存储选项
NSUserDefaults 的问题是什么?
虽然它很 nice 也很便捷,但是它只适用于小数据,比如一些简单的布尔型的设置选项,再大点你就要考虑其它方式了
XML 这种结构化档案呢?
总体来说,你需要读取整个文件到内存里去解析,这样是很不经济的。
使用 SAX 又是一个很麻烦的事情。
NSCoding?
不幸的是,它也需要读写文件,所以也有以上问题。
在这种应用场景下,使用 SQLite 或者 Core Data 比较好。
使用这些技术你用特定的查询语句就能只加载你需要的对象。
在性能层面来讲,SQLite 和 Core Data 是很相似的。他们的不同在于具体使用方法。
Core Data 代表一个对象的 graph model,但 SQLite 就是一个 DBMS。
Apple 在一般情况下建议使用 Core Data,但是如果你有理由不使用它,那么就去使用更加底层的 SQLite 吧。
如果你使用 SQLite,你可以用 FMDB 这个库来简化 SQLite 的操作,这样你就不用花很多经历了解 SQLite 的 CAPI 了。
三、高级
1、 加速启动时间。
快速打开 app 是很重要的,特别是用户第一次打开它时,对 app 来讲,第一印象太 太太重要了。你能做的就是使它尽可能做更多的异步任务,比如加载远端或者数据库数据,解析数据。 避免过于庞大的 XIB,因为他们是在主线程上加载的。所以尽量使用没有这个问题的 Storyboards 吧! 一定要把设备从 Xcode 断开来测试启动速度
2、 使用 Autorelease Pool。
NSAutoreleasePool`负责释放 block 中的 autoreleased objects。 一般情况下它会自动被 UIKit 调用。但是有些状况下你也需要手动去创建它。 假如你创建很多临时对象,你会发现内存一直在减少直到这些对象被 release 的时候。这是因为只有当 UIKit 用光了 autorelease pool 的时候 memory 才会被释放。消息是你可以在你自己的 @autoreleasepool 里创建临时的对象来避免这个行为。
3、 选择是否缓存图片。
常见的从 bundle 中加载图片的方式有两种,一个是用 imageNamed,二是 imageWithContentsOfFile,第一种比较常见一点。
4、 避免日期格式转换。
如果你要用 NSDateFormatter 来处理很多日期格式,应该小心以待。就像先前提到的,任何时候重用 NSDateFormatters 都是一个好的实践。如果你可以控制你所处理的日期格式,尽量选择 Unix 时间戳。你可以方便地从时间戳转换到 NSDate:这样会比用 C 来解析日期字符串还快!需要注意的是,许多 web API 会以微秒的形式返回时间戳,因为这种格式在 javascript 中更方便使用。记住用 dateFromUnixTimestamp 之前除以 1000 就好了。
平时你是如何对代码进行性能优化的?
利用性能分析工具检测,包括静态 Analyze 工具,以及运行时 Profile 工具,通过 Xcode 工具栏中 Product->Profile 可以启动
比如测试程序启动运行时间,当点击 Time Profiler 应用程序开始运行后.就能获取到整个应用程序运行消耗时间分布和百分比.为了保证数据分析在统一使用场景真实需要注意一定要使用真机,因 为此时模拟器是运行在 Mac 上,而 Mac 上的 CPU 往往比 iOS 设备要快。
为了防止一个应用占用过多的系统资源,开发 iOS 的苹果工程师门设计了一个“看门狗”的机制。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。开发者们在 crashlog 里面,会看到诸如 0x8badf00d 这样的错误代码。
优化 Table View
正确使用 reuseIdentifier 来重用 cells
尽量使所有的 view opaque,包括 cell 自身
如果 cell 内现实的内容来自 web,使用异步加载,缓存请求结果减少 subviews 的数量
尽量不适用 cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
使用 rowHeight, sectionFooterHeight 和 sectionHeaderHeight 来设定固定的高,不要请求 delegateUIImage 加载图片性能问题 • imagedNamed 初始化
imageWithContentsOfFile 初始化
imageNamed 默认加载图片成功后会内存中缓存图片,这个方法用一个指定的名字在系统缓存中查找并返回一个图片对象.如果缓存中没有找到相应的图片对象,则从指定地方加载图片然后缓存对象,并返回这个图片对象.
imageWithContentsOfFile 则仅只加载图片,不缓存.
加载一张大图并且使用一次,用 imageWithContentsOfFile 是最好,这样 CPU 不需要做缓存节约时间.
使用场景需要编程时,应该根据实际应用场景加以区分,UIimage 虽小,但使用元素较多问题会 有所凸显.
不要在 viewWillAppear 中做费时的操作:
viewWillAppear:
在 view 显示之前被调用,出于效率考虑,方法中不要处理复杂费时操作;
在该方法设置 view 的显示属性之类的简单事情,比如 背景色,字体等。
否则,会明显感觉到 view 有卡顿或者延迟。
在正确的地方使用 reuseIdentifier:
table view 用 tableView:cellForRowAtIndexPath:
为 rows 分配 cells 的时候,它的数据应该重用自 UITableViewCell。
尽量把 views 设置为透明:
如果你有透明的 Views 你应该设置它们的 opaque 属性为 YES。
系 统用一个最优的方式渲染这些 views。
这个简单的属性在 IB 或者代码里都可以设定。
避免过于庞大的 XIB:
尽量简单的为每个 Controller 配置一个单独的 XIB,尽可能把一个 ViewController 的 view 层次结构分散到单独的 XIB 中去, 当你加载一个引用了图片或者声音资源的 nib 时,nib 加载代码会把图片和声音文件写进内存。
不要阻塞主线程:
永远不要使主线程承担过多。
因为 UIKit 在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成,大部分阻碍主进程的情形是你的 app 在做一些牵涉 到读写外部资源的 I/O 操作,比如存储或者网络。
在 Image Views 中调整图片大小 如果要在 UIImageView 中显示一个来自 bundle 的图片,你应保证图片的大小和 UIImageView 的大 小相同。
在运行中缩放图片是很耗费资源的. 讲讲你用 Instrument 优化动画性能的经历吧(别问我什么是 Instrument)
facebook 启动时间优化
瘦身请求依赖
UDP 启动请求先行缓存
队列串行化处理启动响应
Alamofire框架底层分析
Alamofire 全部实现共有 17 个文件组成,如下:
Alamofire 有五模块组成,即接口、请求、响应、底层和其他。分析各模块的实现,功能和联系就可以理解 Alamofire。
自行领取直达链接:【点击获取】
评论