2021 时光鸡:岁月静好 未来可期

1,803 阅读16分钟

「时光不负,创作不停,本文正在参加2021年终总结征文大赛

开头说

引用马老师对职业发展的一句话,警醒自己和众位看官。

如果,一个人在 30 几岁的时候,还没有发现真实的自己,没有发现自己独特的优势,还只是用 20 几岁做事的方式在做当下的事情,自然在和资本博弈中没有优势,这是值得焦虑和恐慌的。因为,30 几岁了大部分成家立业,上有老下有小,精力和时间肯定比不上 10 年前自己。如果能找到自己最强的一个点,打穿它,做到万里挑一,你就有可能去享受它带来的红利,抵消掉其他的不足,甚至整体上产生更多剩余价值。

回顾

即将告别 20 多岁,回顾一下,跟着对的人,去做有意义的事,真的做了很多事情。用劳动时间,换取钱、经验和社会关系。

之前沸点发过一个话题,大体就是讨论客户端开发进阶的 N 个方向:

  • 1️⃣ 横向跨端:动态化+多平台...
  • 2️⃣ 全栈工具:架构工具组...
  • 3️⃣ 领域专精:Socket、音视频...

附加题:一直写业务有没有资格谈技术进阶?

下面也会从这几个方向展开。

横向跨端

一直在探索 Flutter 动态化、平台化小程序、H5、原生应用开发的解决方案

动态化 是各厂在积极探索的方向,暂时来看研发成本过高,风险略高于收益。

  • 腾讯 MXFlutter:使用 TypeScript/JavaScript 来开发 Flutter 应用的框架。

68747470733a2f2f7075622e69647171696d672e636f6d2f70632f6d6973632f66696c65732f32303231303433302f65353238313964666361373734346436386631643638663566663035323130652e6a7067.jpg

screenshot-20211217-171812.png

  • 58 Fair:为 Flutter 设计的,UI & 模板动态化框架。

screenshot-20211217-172004.png

平台化 主要依托容器化架构,各家都在平滑过度,目前来看收益远高于风险。

客户端开发模式进化:集成化开发---组件化开发---模块化开发---平台化开发

微信小程序的成功让微信成为了航母一般的存在,容器化作为模块化的终极形态让很多公司心生向往。

screenshot-20211217-172202.png

小程序、H5、原生应用开发

  • 最近在研究 MPFlutter,感觉是个可行的方向,有完善的脚手架和文档,没错我要开始搞事情了。

    通过 Dart 语言开发 App,一套代码同时运行在以下平台:

    • 微信小程序
    • 百度小程序
    • Web (HTML5)

WechatIMG6059.jpeg

全栈工具

IMG_1684.png

CleanShot_2021-02-20_at_16.46.592x.png

CleanShot_2021-02-20_at_16.21.462x.png

screenshot-20210818-205000.png

  • 组件管理平台(配套 SDK、源码)

CleanShot_2021-02-20_at_15.08.572x.png

  • 订阅库更新通知机器人(源码)

CleanShot_2021-01-03_at_15.16.372x.png

  • Dart Pub 私服(源码)

screenshot.png

💡 专利和软著可以搞一搞,信息系统项目管理师和 PMP 可以考一考,前二者公司可能有实质奖励,后两者会让你的技术路线有更多选择。

领域专精

1.跨平台长连接组件

五层结构(层 * 为 Worker 职责层)

  1. Native 层 *:负责业务请求封装和数据解析,与原生进行交互。
  2. Chat 层 *:负责提供底层通信使用的 c 接口,包含连接、读写和关闭。
  3. WebSocket 层:实现 WebSocket 协议及维护心跳,协议 13 RFC 6455。
  4. TLS 层 :基于 mbedTLS 实现 TLS 协议及数据加解密,双方身份验证,协商加密算法,交换加密密钥。
  5. TCP 层:基于异步 I/O 库 libuv 实现 TCP 连接和数据的读写。

13 RFC 6455 WebSocket 协议:实现为握手,数据发送/读取,关闭连接。

可插拔方案

CleanShot_2020-09-23_at_08.26.472x.png

  1. iOS 和 Android 分别采用 runtime 消息发送和 JNI 进行原生方法调用。
  2. 依托 Flutter FFI to C++ 通信方案实现全平台支持,各端只需对齐 Flutter 通信实现。

IM 专题方案

  1. 前微信 Open IM SDK
  2. 关于 IM 通讯模块的架构设计经验
  3. 闲鱼 IM 基于 Flutter 的移动端跨端改造实践
  4. 企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
  5. 完整的 IM 架构设计
  6. 再谈 IM 架构设计(中)
  7. 马蜂窝 IM 移动端架构的从 0 到 1

2.异步渲染 IM 框架

常规优化

  1. 优化 TableView,例如缓存高度等(其实目前用 self-sizing 布局的 UITableViewCell 的越来越多,这种优化方法聊胜于无)。
  2. 防止离屏渲染(圆角问题等)。
  3. 用 collectionView 或者 tableView 的 prefetch 等。
  4. 将繁复操作移步到异步线程处理。

1.优化方案:渲染 Texture 利用 TextKit 将 UI 的绘制变为富文本排版和渲染。

CleanShot_2020-08-28_at_14.06.512x.png

  1. 减少了视图的图层数量(通过 draw 方法讲内容绘制为图片,所以整个视图变为一个 imageView)。
  2. TextKit 可以不在主线程渲染和排版,将内容直接渲染到 Layer 层 可以轻松的到满帧 60 FPS。
  3. Deepdiff 优化,差异计算高效的 reloadData,利用状态机和状态驱动来驱动 UI 的变更。

弊端

  1. 处理不好TextKit 渲染有可能导致闪屏(因为即将 display 的时候还未在异步线程渲染完毕)。
  2. 很难处理点击等事件。
  3. 不太好处理线程之间的切换,处理不好很容易 Crash。

2.优化方案:跨平台 Flutter

  1. 一套代码和更适合多端的 Flex 布局,方便全平台支持和统一多端 UI。
  2. 优于 TextKit 的 120 FPS 高刷新率、自带 Diff 算法优化和学习曲线。
  3. 实时调试,开放效率高。
  4. 支持外接纹理(Native 和 TextKit)扩展性强。

弊端

  1. 需要解决混合栈内存问题。
  2. 对项目组件化程度要求高。

3.组件化分发生命周期 - AOP 方案

将主工程的生命周期分发到各个组件里去:AppDelegate 遵循并实现了 UIApplicationDelegate 代理,其中包括 willFinishLaunchingWithOptions:didFinishLaunchingWithOptions:applicationWillEnterForeground:applicationDidEnterBackground: 等等方法,包含了主工程的各个阶段将执行的方法,我们要做的就是在主工程的这些阶段方法被执行的时候,各个组件里相对应的阶段方法同时会被执行,这样,主工程和各个组件便共享了生命周期。

分发生命周期是组件插件化的基础,不但解决 AppDelegate 臃肿问题,而且可以合理的时机执行相应 load 方法的操作,优化 APP 启动耗时。

  1. sunnyxx 的 Notification Once
  2. 美团的 Kylin 注册函数
  3. 手动注册、遍历分发
  4. Category 覆盖、追加方法
  5. 消息转发
  6. AOP 方案(libffi 实现)

4.CocoaPods 新仲裁算法 Pubgrub(阿里 Triver)

cocoaPods版本仲裁功能基于Molinillo实现,遍历方式是DFS(深度优先算法)。

Molinillo是老一代的版本仲裁算法,PubGrub则是新一代的版本仲裁算法。

Molinillo 的版本仲裁算法有两个明显缺点:

  • 版本冲突遍历效率差;
  • 仲裁失败的错误日志不清晰。

Pubgrub将包之间的版本依赖关系抽象为Term和Incompatibility两个要素:

  • Term 表示一个包的版本约束;
  • Incompatibility 表示一组不兼容的关系。

为了表示一组Term和一个Term的关系,Pubgrub定义了 satisfies(满足)、contradicts(矛盾)、inconclusive(不确定是否满足)三个概念。

类比导航道路拥堵回溯并标记,避免重复走进同一个死胡同,大幅提高版本冲突时搜索的效率。

5.CocoaPods Plugins 汇总

  1. 【微软】动/静态库管理
  2. 远程仓库为 SVN(gem install cocoapods-repo-svn)
  3. cocoapods-ppbuild 提高iOS编译速度
  4. cocoapods-packager 打包工具(废弃)
  5. cocoapods-generate 是 cocoapods-packager 作者的另一个插件,它提供了构建工程的能力,和 cocoapods-packager 相比缺失了构建 framework 功能。但它有个好处,不依赖 git,可以直接根据提供的 podspec 文件在本地生成对应的工程。
  6. Swift CCache:最快的编译是不编译
  7. cocoapods-lebbay 整合工具包
  8. 记录一次 Cocoapods Plugins 插件开发过程

工具控

我是工具人,喜欢收集工具,工具使我快乐...

  1. 直播 Mac 推流工具 App

  2. 外接显示器亮度控制 App

  3. IB 数据可视化 Dash + Echart

  4. 对外博客系统 Ghost

  5. SwiftLint 代码质量自动检查工具

  6. SwiftGen 重复代码生成工具

  7. pecker 检测无用的代码

    1. sourcekit-lsp,Language Server Protocol (LSP) 实现,提供代码自动补全和定义跳转。
    2. IndexStoreDB,提供可组合且高效的查询API,用于查找源代码符号,符号出现和关系。

生活

个人发展(40%)

  • 跟踪技术前沿论坛:早学早知道
  • 更新技术博客:整理有助消化
  • 技术分享:锻炼表达能力
  • 线下面基大佬:扩大社交圈

要用财富管理的思路去管理你的职业生涯,寻求整个职业生涯的利益最大化,而不是最近一份工作的利益最大化。

经营感情(40%)

今年成功脱单,也已经做好成家的准备,原本以为会经历坎坷,反复磨合,没想到一切都那么自然而然,简单可贵。之前我的全部经历都在工作和学习中,现在会不自觉地去关心照顾她。唯有热爱,可抵岁月漫长,一起承担起家庭的责任,更是种幸福的成长。

投资理财(20%)

  • 向专业的人请教投资风向:专业顾问会让你损失最小
  • 复盘上一周投资状况:调整资金布局,做中长线投资
  • 根据即时事件,调整资金布局:看着玩吃吃瓜~

自信和淡定的投资心态,是投资行为中最重要的。

理财

资产配置结构四大类标的:

  • 固收类:预期收益率固定,或者波动较小,如:国债,保险,银行理财。
  • 股票类:波动大,收益高,如:股票。
  • 实物类投资标:投资金额大,流动性差,如:房产,原油。
  • 新兴类:不确定性强,收益和波动都极大,如:数字货币。

关注以下指标:

  • 年化收益:考察期上按复利计算的年均收益。
  • 最大回撤:净值曲线中最大一次下跌的幅度,它是衡量一个投资标的风险特性的最重要指标。
  • 夏普率:(年化收益 - 无风险收益率【简设为 2.5%】)/年化波动,描述了承担单位波动能够换取的超额收益。专业投资者一般用它来直接衡量一个投资标的的好坏。

夏普比率大于1才是“好组合”

夏普比率(Sharpe ratio)定义上,指每当承受多一分的风险,可以获取多少额外的回报,通常用来代表风险调整后回报。用数学公式描述就是:

夏普比率的计算公式为:

ratio=σp(Rp−Rf)

  • Rp : 回报率平均值
  • Rf : 无风险利率
  • σp : 回报率标准差

如果用文字描述的话,就是用基金的预期收益率减去无风险利率,用这个数值再除以基金的标准差。无风险利率通常会选择1年期定期存款的收益率,或者 1 年期国债收益率;而基金的标准差就代表着基金每日收益率和平均收益率的偏离程度,也就是我们所说的风险衡量的指标。

所以,用预期收益率减去无风险利率,就得到投资组合获得的超额收益,即承担了风险而获取的超过无风险利率的水平,用这个数值再除以风险指标,就表示承担每单位风险而获得的超额收益的水平。

假设一个投资组合预期回报是 20%,标准差是8%,无风险收益水平是3%,那么用20%-3%,得出17%(即超出无风险投资的回报),再用 17% 除以标准差 8% 等于 2.13,这个投资组合的夏普比率就是2.13,代表投资者风险每增长1%,换来的是2.13%的超额收益。

在投资中,我们的投资组合追求的是在同等的风险下,追求更高的回报;或同等的回报下,追求更低的风险。简单说,就是投资组合的收益要高,标准差要相对低。所以,当夏普比率超过 1,才是好的组合。

夏普比率的应用场景

为了更直观地理解夏普比率的意义,我们举个例子。

假设有 2 只基金产品,在 1 年中都赚了 20%,A 基金的净值从年初一路上涨到 20%;B 基金虽然年底也赚到了 20%,但年中的时候曾经一度亏损 10%。从最终的收益看,两者是一致的,但从性价比看,却差异极大。

从投资的角度讲,波动就是风险,如果产品的波动越小,即风险越小,投资效率更高,夏普比率也会越高。A 基金的收益曲线相对平稳;而 B 基金的波动较大,承受的风险更高,以单位风险获得的回报相对就小。那在日常投资中,我们看到的经常是收益率水平不一致的情况,那么夏普比率的作用会更加明显。

例如A基金获得了 15% 的回报,而 B 基金获得 20% 的回报,从收益的角度看,很显然 B 基金表现更出色。但假设无风险利率为 5%,A基金的投资组合标准差为 6%,而 B 基金的投资组合标准差为 12%。那么 A 的夏普比率就是 1.66,而 B 的比率则是 1.25。这样对比,结果恰恰相反,A 基金在风险调整的基础上可以获得一个更高的投资收益。

夏普比率越高越好吗?

看到这里,相信有朋友不禁要问,是不是用夏普比率来筛选基金,越高的越好呢?答案当然是否定的。虽然对投资者而言,夏普比率提示要从风险和回报的角度综合考虑,挑选“性价比”高的投资。但挑选基金产品不能只看夏普比率这一个指标。

举个例子,如果假设资金利息为 0 的前提下,一个预期收益为 0.3% 的基金产品,回撤波动率是 0.1%,那么这个产品的夏普比率为 3。对于投资者来说,预期收益 0.3%,别说货币基金,连银行定期都跑不过。而且从各个资产类别或策略看,其夏普比率的特征是不同的,不能跨类别比较

例如股票多头策略的基金,对应的A股市场本身的波动率就较高,股票多头策略基金产品的夏普比率较低实属正常;债券型基金相对于股票型基金,波动较小,夏普比率也会较高;而像商品期货 CTA 与股票量化对冲型的基金,夏普比率反应的情况相对来更加准确。

同时值得注意的是,夏普比率与年化收益率一样,在不同的统计区间和频次下,反应的结果是完全不同的。比如一年维度统计的波动率与三年统计的波动率相差甚远,一定要换算到同一个周期上,才有可比性;高频策略与较低频策略就不能采用相同的频次,高频策略得用每日收益率,而低频策略可以参考周收益率。

总的来说,在挑选私募基金产品时,夏普比率是一个较好的风险指标。但在做出决定时,还是需要结合长期收益率、最大回撤、投资胜率等指标来进行综合性评估。

展望

30 几岁的时候,稀里糊涂学着自己做,学会和公司、社会互处,找到自己的方向,并把它做到万里挑一。

Flutter 轻容器

立个 Flag “前几年拧螺丝,这几年造惯轮子,明年我要造船”。

App Container.png

我的想象中有一艘小航母,它依托于容器化的组合方式,可以轻松集成进任何项目;支持一套代码编译成小程序、H5和嵌入原生应用;高效每秒刷新 120Hz 的渲染效率;完备的 UIKit 组件物料承载和 UI 自动化走查支持;配合 lowcode 和离线包管理平台下发资源包热更新。

我有一个梦想,一套代码可以跑在任意平台,我有一个梦想,各平台的渲染效果一模一样,我有一个梦想,渲染效果高效无卡顿。

pod_extentions 工具集

向优秀的那群人学习,CocoaPods 工具集是我认为比较有挑战性的课题,接触到字节自研移动研发工具链 MBox 我看不懂,但我大受震撼。

  1. 一键配置各业务方组件库
  2. 全自动二进制化方案
  3. 支持单个 Pod 源码与二进制版本切换
  4. 支持全量二进制版本与源码版本切换
  5. 依赖解析加速
  6. CI 定制化构建加速
  7. Pods 废弃功能通知

小团体大佬荟

Apps.png

同时欢迎各界大佬莅临指导,报名加微信:WhatsXie,请备注:“大佬荟莅临指导 😱”。

💡 建议:提前公告分享主题、展示成果物,分享过程中使用放大镜/透镜/共享画板等工具,点名形式增加互动性。

分享表

“我们都有光明的前途~,每个人都是值得学习的大佬”

尾巴

共勉

  • 今天你拥有的,可能恰恰是阻碍你往前走的包袱。今天你焦虑的,可能恰恰是高度和思维视角问题。
  • 所谓的脏活、苦活、累活,你不想去做,但是也得去做,因为那是成就你的一部分内容,可能你的运气好一点,这种活有人替你扛下来了。
  • 勿松懈,完善流程规范,严格执行,警惕捧杀。
  • 言语多反复,当防欺诈。忘恩思小过,定会反戈。开口说大义,临大难必变节。逢人称兄弟,即深交也平常。