2020.01.28,大年初四,疫情已经四处开花了。那天,我坐在出租屋里和孩子玩。我突然想到,2019 年的年度总结我已经写出来了,但是 2020 年都过去两个月了,可是 Flag 呢?好像是丢了。
像我这样到人,除了抽烟一直没能戒掉,做其他事还是计划感挺强的。我觉得 2020 年,应该立个 Flag。

很多人都喜欢打比方来阐述一件事情,比如说 “xxx 就是一个例子”、“有 xxx 一个例子”、“我和你打一个这样的比方 xxx”,比方说完之后,就开始阐述自己的观点。

打比方是一个久经沙场,百试不爽的论证妙计。怎么让对方跟着你的节奏走?当然是打个比方。比方一般都比较有趣,尤其带有故事性,很容易带节奏。而观点但凡和比方有一点相合,那比方就是绝佳的药引子。

但事实是:观点可能是错的,比方可能是不存在的,观点和比方的相合度可能是 1% 的交集,但观点却被采纳了!

很多互联网服务都会开通 IM 功能,如好友通讯,用户反馈,在线推送等。在微信未盛行,QQ 大行其道的年代,IM 还属于高深技术,目前已经进入寻常百姓家了。
其实 IM 本身整个技术流程从终端角度来看不是一个难以理解的问题。但因为诸多人对网络协议不了解,所以认为 IM 难以入门。

首先要说 IM 是一个什么样的形态,它和 HTTP/S 有什么不同。
HTTP 解决了端到端通讯的问题,在互联网大放异彩的原因是浏览器的盛行。冲浪需要网络获取服务端资源,HTTP 可以使得终端发起网络请求服务端返回资源结果实现资源互通。
我们的感知里面,终端发起网络请求,服务端回复网络请求,HTTP 使命就完成了。所以很多人对于 HTTP 的认知是:一次性通讯,每次需要获取信息都要重新发起请求。
其实有这样的认知是完全正确的,因为 HTTP 的确就是这样设计的。这里要着重说到设计这个词,因为 HTTP 就是为了完成一次性通讯这么一个任务。而像 HTTP 这样的应用层协议还有非常多,比如 FTP、RTMP 等等。他们都是为了完成特定任务而实现的协议。所有应用层协议都是被设计过的,为了完成特定的使命。

如果不是 2019-nCoV,我都不会有这个想法。我一直觉得自己还年轻,如果不是车祸等天灾,怎么也轮不到我来思考死亡。但是风水转动的就是如此的快,每个大陆人都有感染的风险,感染后会有死亡的可能。
当然如果自己不作,做好防护工作,那肯定是相对安全的,当然这也是概率问题,概率和幸福指数直接相关,可惜我还不能理解概率。

这次疫情距离很多人都很近,尤其是一二线城市生活的人。我相信自己不会太作到去碰触病毒,但是我也认识到,不管天灾人祸还是自身疾病,不同年龄段的人都有可能突然离开。或许因为车祸,或许因为疾病,人类在未知和概率面前,还是太渺小。
而如果我的人生,突然只剩下 8 小时,我会做些什么?

雪粉已经是大众熟知的美食,不仅国内家家户户必备,国外也是一抢而空。但很少有人知道雪粉的制作过程,而我的家乡,却是雪粉生产大本营。我对雪粉,一来情有独钟,它对家乡的经济发展有巨大的推动力,二来感到惋惜,除了我的家乡,很少有人知道雪粉的制作流程,国外也只能依靠进口才能品尝一二。

雪粉这样的美食原材料,本应该被更多人了解。我网上查阅了很多资料,都没有详细介绍。我想,我可以把雪粉的制作过程写出来,也算给了雪粉一个互联网的名份。

谈数据结构的时候,到底在谈论什么?本质上就是谈论两个东西,分别是 ** 数组 (Array) 链表 (Linked List)**。

数据物理结构和数据逻辑结构

数组和链表,是数据存储计算机的物理结构,所以叫做数据物理结构。而队列、散列表、堆、树、图等,已经超出了物理结构,是方便我们使用的应用层结构,根据数据的 1-1、1-n、n-1、n-n 逻辑关系,引申出了数据逻辑结构。分别为线性结构和非线性结构,相见下图:

参加工作后的这几年,评价哪一年比较平庸或许都不好,毕竟都是自己亲身经历过的时光,每一年都是像孩子一样善待过,不忍心批评。

但就像每人心里都有一个钟意的水杯,我还是很想投 2019 一票,因为这一年,我的确有不少变化。

这一年,我在技能成长、认知提升、工作、家庭生活、业余生活上都有很大变化。优秀肯定无从谈起,人一定要对自己有自知,但我一定是在向前走的,这让我很高兴。

技能成长

先从 2019 年的技能成长说起,因为它给我的温差最大,有时候我激动万分,有时候也在半夜垂头懊恼。

在 Swift 中,struct(值类型)和 class(引用类型)的区别,不仅仅在于对象复制时候表现出来的差异,也不仅仅是构造器和继承的异同,本质上却是数据抽象层级的高低。
如果不能把值传参、地址传参和引用传参与类对象联系起来,也无法理解不同传参下对象的使用和 struct、class 的应用场景。

因为 struct 和 class 表现出来的是语法层面的差异,而项目使用中体现的是语义层级的差异。比如,Objective-C 里面的 NSString,它是引用类型,但是我们却在使用它的值语义。

1
2
3
4
5
6
7
NSMutableString *oldname = @"hello".mutableCopy;
NSMutableString *newname = oldname;
newname = @"word".mutableCopy;
NSLog(@"\n oldName:%@ \n newName:%@", oldname, newname);

> oldName:hello
> newName:word

我们使用了引用类型的 NSMutableString,但是 newname 并没有引用复制 oldname,仅仅是指针地址复制了 oldname。这样导致了 newname 并不是 oldname 的别名 (alias)。
如果 newname 是 oldname 的别名,那么对 newname 的所有 all 操作,都会同步到 oldname。
这里,newname 如果改变了对象数据是可以同步到 oldname,但是却不能改变 oldname 变量的值(oldname 的存储值,即 “hello” 的指针地址)。
所以,这里的 NSMutableString 虽然是引用类型,却具有值语义。

因为编程语言概念上的模糊,下面首先介绍 struct 和值类型的关系。
然后重点说明值类型和引用类型的区别,这是重点,直接解释了 struct 和 class 的根本区别。
最后加一点小彩蛋,介绍 Swift 里面 struct 特性。

我刚刚关闭了自己的花呗。紧接着开始逐渐关闭一些信用卡的绑定。
这种温水煮青蛙的花钱方式,我经历了 6 年了。现在,因为穷,我有些适应不下去了。
我不知道为什么每个月都有这么多的钱要还,我更不知道为什么我要办理 4 张信用卡和花呗一起使用。
我就知道,我已经很久没有带现金外出过了,我家里也很少有现金。
但是,一点点的无知觉消费,使得每个月都有很多钱要还。计算机 / 服务器永远不会自己计算错,说明还的钱都是有依据的。无感知的消费,使得每个月消费金额过多。

相信我,远离信用卡和花呗。过段时间,我会贴出重回现金生活的感受。我想,一定非常棒。

0x01 问题描述和表现

对于 let 和 var,struct 和 class,分成两类来说,很多人比较容易理解。let:不可变,var:可变,struct:栈空间,class:堆空间。
当我想要确认他们的原理的时候,截止发文为止,我没有在中文互联网上搜索到相关信息。所以我把他们的原理写在下面。

下面的示例,你能够理清楚多少?

1
2
3
4
5
6
7
8
struct Person1 {
let name1: String = "name1"
var name2: String = "name2"
}
class Person2 {
let name1: String = "name1"
var name2: String = "name2"
}

上面定义了一个 struct,一个 class,我们下面的代码会有什么结果?

0%