跳到主要内容

广告生态系统

· 阅读需 2 分钟

广告生态系统

  • 品牌 / 广告主:希望向客户发布广告信息的个人或组织。

  • 代理机构:帮助品牌与生态系统的其他部分互动,并管理广告信息的整个生命周期,包括规划、创建和分发广告活动。

  • 交易台:简化媒体购买流程。

  • 需求方平台 (DSP):自动化在线广告库存和购买,帮助代理机构通过一个平台管理不同账户和广告活动。

  • 数据管理平台 (DMP)

    1. 基于广告的分析:流失率、定位、画像、会话回放等。
    2. 反欺诈
    3. 基于市场的分析
  • 广告交易所 / 实时竞价 (RTB):将广告供应商与买家匹配。

  • 广告网络:聚合出版商库存并将其出售给广告主。

  • 供应方平台 (SSP):监控整个广告库存并为广告空间建议价格。

  • 出版商:广告空间的拥有者,如网站运营商。

加拿大人吐槽互联网上的支付系统

· 阅读需 2 分钟

自1990年以来,互联网的 402 Payment Required 的状态码早就设计好了,但是过了接近三十年,互联网支付还没有做到无缝体验。

  1. 我在网上看到篇文章只是想交个钱支持一下,你偏要我创建账户,创建密码,填信用卡号,完了还要收没完没了的垃圾邮件
  2. 支付应该像浏览器一样方便,一键交钱,不用填账号,用 crypto token 就成,但是中心化的支付会被大公司垄断
  3. 内容创造者不得不和广告绑定,只有大玩家能赢,他们还变得要钱不要脸
  4. 互联网亟需能够激励创意、保护隐私的基础构架。 虽然 Bitcoin 不是答案,blockchain 会有机会

亚伦·塞德利:变更厌恶:用户为何讨厌你推出的产品(以及该如何应对)

· 阅读需 1 分钟

什么是变更厌恶?

一般来说,任何时候你改变人们在产品中常用的东西,他们都会产生强烈反应。这几乎发生在每一次产品发布中,比如 Gmail、YouTube、iPhone 等等。

如何避免或减轻变更厌恶?

  1. 让用户提前和之后了解。提前警告他们重大变化,并沟通这些地方为何发生变化。之后提供过渡说明。
  2. 让用户切换。不要关上门,让他们孤立无援。
  3. 让用户提供反馈并跟进。

变更厌恶不是借口

产品的变化可能会变得好或坏。

变更厌恶模式

东西方职场文化之异同

· 阅读需 2 分钟

这里是一些不成熟的小看法,我没有在中国工作过,所以按照我在学校的所闻所见填写到中国人这一栏里面。

美国人看重中国人看重
说服力
公开演讲是民主社会的基础
桃李不言下自成蹊
君子欲讷于言而敏于行
情绪化是令人羞愧/不专业的事情
虚伪/专业化
性情中人
撕破脸
开会是为了决定事情开会是为了最后拍板
喜欢钻石喜欢玉
自信
不行也得说行
我比其他人厉害
谦虚
行也得说不行
其他人比我厉害
独立思考
挑战权威
团队精神
服从力和执行力

美国人中国人都看重

  • 商业嗅觉
  • 愿景和战略决策能力
  • 团结就是力量 (我过去所共事的中国人都非常团结,虽然很多人对此有偏见)
  • 人比事情重要,关系决定事情
  • 应对VUCA的灵活性

再窥iOS架构模式

· 阅读需 4 分钟

我们为什么要在架构上费心思?

答案是:为了减少在每做一个功能的时候所耗费的人力资源

移动开发人员会在以下三个层面上评估一个架构的好坏:

  1. 各个功能分区的职责分配是否均衡
  2. 是否具有易测试性
  3. 是否易于使用和维护
职责分配的均衡性易测试性易用性
紧耦合MVC
Cocoa MVC❌ V和C是耦合的✅⭐
MVP✅ 独立的视图生命周期一般:代码较多
MVVM一般:视图(View)存在对UIKit的依赖一般
VIPER✅⭐️✅⭐️

紧耦合MVC

传统 MVC

举一个例子,在一个多页面的网页Web应用程序中,当你点击一个链接导航至其他页面的时候,该页面就会被全部重新加载。该架构的问题在于视图(View)与控制器(Controller)和模型(Model)是紧密耦合的。

Cocoa MVC

Cocoa MVC 是苹果公司建议iOS开发者使用的架构。理论上来说,该架构可以通过控制器(Controller)将模型(Model)与视图(View)剥离开。

Cocoa MVC

然而,在实际操作过程中,Cocoa MVC 鼓励大规模视图控制器的使用,最终使得视图控制器完成所有操作。

实际的 Cocoa MVC

尽管测试这样的耦合大规模视图控制器是十分困难的,然而在开发速度方面,Cocoa MVC是现有的这些选择里面表现最好的。

MVP

在MVP中,Presenter与视图控制器(view controller)的生命周期没有任何关系,视图可以很轻易地被取代。我们可以认为UIViewController实际上就是视图(View)。

MVC 的变体

还有另外一种类型的MVP:带有数据绑定的MVP。如下图所示,视图(View)与模型(Model)和控制器(Controller)是紧密耦合的。

MVP

MVVM

MVVM与MVP相似不过MVVM绑定的是视图(View)与视图模型(View Model)。

MVVM

VIPER

不同于MV(X)的三层结构,VIPER具有五层结构(VIPER View, Interactor, Presenter, Entity, 和 Routing)。这样的结构可以很好地进行职责分配但是其维护性较差。

VIPER

相较于MV(X),VIPER有下列不同点:

  1. Model 的逻辑处理转移到了 Interactor 上,这样一来,Entities 没有逻辑,只是纯粹的保存数据的结构。
  2. ==UI相关的业务逻辑分在Presenter中,数据修改功能分在Interactor中==。
  3. VIPER为实现模块间的跳转功能引入了路由模块 Router 。

如何使用HTTP协议向移动设备传输视频? HTTP Live Streaming (HLS)

· 阅读需 2 分钟

为什么需要这样一个协议?

使用HTTP直播流的移动视频播放服务有以下问题:

  1. ==手机的内存和外存有限==。
  2. 受制于不稳定的网络连接以及不同的带宽,需要==在传输过程中动态调整传输视频的质量==。

解决方法

  1. 服务器层面:在典型的设置中,编码硬件接受音视频输入,将其编码为H.264格式的视频和ACC格式的音频,然后将他们以MPEG-2格式流输出。
    1. 其后通过一个软件分流器将原始输出流分割为一系列短媒体文件(长度可能为10s的.ts文件)。
    2. 分流器同时也会维护一个包含所有媒体文件列表的索引文件(.m3u8格式)。
    3. 将以上步骤生成的媒体文件和索引文件发布在网络服务器上。
  2. 客户端层面:客户端读取索引,然后向服务器顺序请求所需要的媒体文件,并且流畅地将各个短媒体文件的内容播放出来。

架构

HLS Architecture

设计Facebook图片存储系统

· 阅读需 3 分钟

为什么 Facebook 要自己做图片存储?

  • PB级别的Blob数据量
  • 传统的基于NFS的设计(每个图像存储为文件)都存在元数据瓶颈:庞大的元数据严重限制了元数据命中率。
    • 以下是细节解释:

对于图片应用程序,图片的权限等大多数元数据是无用的,从而浪费了存储空间。然而,更大的开销在于,必须将文件的元数据从磁盘读入内存中才能找到文件本身。虽然对于小规模存储来说这微不足道,但当乘以数十亿的照片和数PB的数据时,那么访问元数据将是吞吐量的瓶颈。

解决方案

通过把数以十万计的图像聚集到单个Haystack存储文件中,从而消除了元数据负荷。

结构

Facebook Photo Storage Architecture

数据布局

索引文件(用于快速加载内存)+ 包含很多图片的haystack存储文件。

索引文件布局

index file layout 1

index file layout 2

储存文件

haystack store file

CRUD操作

  • 增: 写入存储文件,然后==异步==写入索引文件,因为建立索引并不是关键的步骤。
  • 删: 通过在标志字段中标记已删除的位来进行软删除。通过紧凑操作执行硬删除。
  • 改: 在更新时,只能追加 (append-only),如果遇到了重复的键,应用程序可以选择具有最大偏移量的键去改和读。
  • 查: 读取操作(偏移量,健,备用键,Cookie 以及数据大小)

用例

上传

Photo Storage Upload

下载

Photo Storage Download

学会被信任——教唆杀人只需要72分钟

· 阅读需 10 分钟

传统智慧告诉我们:失去信任很快,获得信任很慢。但实际上并非如此。英国的著名心理魔术师达伦·布朗在真人秀《达伦·布朗:就范 Derren Brown: The Push》中,利用了种种心理学的技巧,在 72 分钟内,就令一个善良的普通人走向极端,犯下可怕的谋杀案,把老人推下大楼。

故事的主人公是一位性格温和的阳光男孩克里斯。他虽然看上去普普通通,但实际上他是通过实验精心挑选出来的,社会屈从行比较强。克里斯自己其实并不知道实验和节目的目的,而且节目组告诉他落选了,让他放松警惕。节目组找人扮演位高权重的慈善项目的高管,联系到克里斯的公司商量合作计划,并邀请他帮助举办活动。为了尽快树立权威感,这个活动还找来了大量名人的背书,并且让克里斯端酒、拎包、拿衣服训练他的服从感。

然后案件开始了,在只有高管和克里斯的情况下,一位大财主老头突然“暴毙”,高管劝说克里斯顾全大局,让克里斯帮忙藏尸,他照做了。后来,活动主持人"误"以为克里斯是那位大财主,让他上台演讲,他照做了。高管让克里斯转移尸体,他照做了。再后来,财主的妻子说财主有昏睡症,一犯病就像死了一样,于是高管和克里斯松了一口气。不料节目组安排老头“醒来”用自己口袋里的录音器“知道了”他”死“后发生的一切,囔囔着要告发二人,不给慈善机构捐一分钱。最后的最后,害怕失去工作和坐牢的高管让克里斯把老头干掉,把正好坐在高台边缘的老头推下去,他……并没有照做。实际上,节目总共测试了4个人,而克里斯是唯一没有服从“杀人”决定的人。

另外三个“杀人”的受试者会如此之快的就范,说明了信任的建立可以如此之快,让人竟然能够听从他人的命令去“杀人”。

那么,信任是如何建立起来的呢?心理学家早就有了答案:==信任等于能干加亲和==。比如在上面撺掇杀人的真人秀里面,高管就是表现得高端大气上档次,整个慈善活动也是得到了社会名流的加持。

这其中,==“能干”并不是要求人真的能干,而是只要表现得能干就可以了==。比如,说话的时候使用大量的专业名词,就会让人听上去像个专家。还有更肤浅的方法是外表,开豪车戴袖扣,让人记住你。其中的关键在于得体,不要穿着西装领带去修理厂给别人修车,不要穿着拖鞋短裤去慈善晚宴给别人演讲。

还有一个增强“能干程度”的好方法是言行一致,没有人会相信言行不一的伪君子(hypocrite)。要是活在《笑傲江湖》里,我当然也会信任一言九鼎的真小人田伯光,不会信任道貌岸然的伪君子岳不群。

能干程度,或者说是“可置信度”(credibility),在人与人之间、在组织与组织之间,是可以交互促进的。人和组织都可以通过加入一些排他性的协会来增加置信度,而高置信度的人和组织加入这个协会,这个协会的置信度就会更高。我感觉,中国有句古话,叫做“花花轿子人抬人”,讲的可能就是这个道理吧。交互产生可信度的最最直接的产物,就是钱;交互产生可信度的过程越是容易,人们越是互相信任,产生的交易就越多,整个社会的经济水平就越高。

很多国家领导人给人以“能干”的印象,但是很冷酷,所以为了增强民众的信任感,每一任的美国总统都会养狗。比如奥巴马,他在搬进白宫之前从未养过狗,他的女儿玛丽亚甚至对狗过敏,但他还是不得不养狗,毕竟,很少有什么东西能够像毛茸茸的、摇着尾巴的、眼睛水汪汪的狗狗们更能够让人感到亲和的了。

这就是“亲和”的力量。哈佛大学的一位教授做了一个实验发现,雨天的时候在车站躲雨,向陌生人借电话,只要在接电话之前先说了,“我对雨感到抱歉”,借到的概率就会高四倍。研究发现,==甭管这种道歉有多浮夸,这一方法在生活中对于促进合作屡试不爽==。

实际上,==想要表现亲和力,通常而言,说话的方式比说话的内容更重要,肢体语言比口头语言更重要==。坐得更近、身体前倾、握手、拍肩膀、碰到手肘,都能够有力地表达合作的意向。==就信任而言,面对面地交流是非常非常重要的==。我有一位耶鲁的同学,在拿到优步的 Offer 之后直接找老板面谈薪水,一路谈到总监,竟然就多拿到了几千股的股票!

除了这两个维度之外还有什么方法增强信任感呢?答案是暴露无关紧要的弱点。比如“不小心”把笔掉在地上,“不小心”说了一个冷笑话,“不小心”泼了咖啡。

能人能够通过有意识地犯一些小错误或者暴露一些小秘密让自己更合群。哥伦比亚大学MBA项目就曾经有一位高管学生,她有意识地往自己写的邮件里面加错别字,让她显得更平易近人,而她跟同事之间的关系就真的变得更好了。这就解释了为什么日本的职员喜欢下班后一起喝醉酒然后去五音不全地唱卡拉OK。因为你表现得越烂,你与朋友的羁绊就越深。

当然,暴露弱点要小心。==在暴露弱点之前,人们得认可你真的能干==。其次,==弱点必须是无关紧要的==。外科医生手抖,橄榄球四分卫黄油手,这些都不是弱点,是硬伤。

所以,总的来说,==信任=能干+亲和+暴露无关紧要的弱点==。要想被人信任,首先你得值得被信任,你得是能干的人;你不仅要能干,还得得跟对方建立连接,所以你需要表现得亲和。而建立信任之后,如果表现得太过于能干了、太过于面面俱到了,会给人造成距离感和威胁感,所以你还得暴露无关紧要的弱点,拉近和对方的距离。

iOS 架构模式再探

· 阅读需 3 分钟

为什么要关注架构?

答案:为了降低每个功能的人力资源成本

移动开发者从三个维度评估架构。

  1. 功能参与者之间责任的平衡分配。
  2. 可测试性
  3. 易用性和可维护性
责任分配可测试性易用性
紧耦合 MVC
Cocoa MVC❌ VC 耦合✅⭐
MVP✅ 分离的视图生命周期一般:代码较多
MVVM一般:由于视图依赖 UIKit一般
VIPER✅⭐️✅⭐️

紧耦合 MVC

传统 MVC

例如,在一个多页面的 web 应用中,一旦点击链接导航到其他地方,页面会完全重新加载。问题在于视图与控制器和模型紧密耦合。

Cocoa MVC

苹果的 MVC 理论上通过控制器将视图与模型解耦。

Cocoa MVC

实际上,苹果的 MVC 鼓励 ==庞大的视图控制器==。而视图控制器最终负责所有事情。

现实中的 Cocoa MVC

测试耦合的庞大视图控制器是困难的。然而,Cocoa MVC 在开发速度方面是最佳的架构模式。

MVP

在 MVP 中,呈现者与视图控制器的生命周期无关,视图可以轻松模拟。我们可以说 UIViewController 实际上就是视图。

MVC 变体

还有另一种 MVP:带有数据绑定的 MVP。正如你所看到的,视图与其他两个之间存在紧密耦合。

MVP

MVVM

它类似于 MVP,但绑定是在视图和视图模型之间。

MVVM

VIPER

与 MV(X) 相比,VIPER 有五个层次(VIPER 视图、交互器、呈现者、实体和路由)。这很好地分配了责任,但可维护性较差。

VIPER

与 MV(X) 相比,VIPER

  1. 模型逻辑转移到交互器,实体作为简单的数据结构保留。
  2. ==与 UI 相关的业务逻辑放入呈现者,而数据修改能力放入交互器==。
  3. 引入路由器负责导航。

键值缓存

· 阅读需 4 分钟

KV 缓存就像一个巨大的哈希映射,用于减少数据访问的延迟,通常通过

  1. 将来自慢速且便宜介质的数据转移到快速且昂贵的介质上。
  2. 从基于树的数据结构的 O(log n) 索引转为基于哈希的数据结构的 O(1) 进行读写。

有各种缓存策略,如读穿/写穿(或写回)和旁路缓存。总体而言,互联网服务的读写比为 100:1 到 1000:1,因此我们通常会优化读取。

在分布式系统中,我们根据业务需求和上下文选择这些策略,并在 CAP 定理 的指导下进行选择。

常规模式

  • 读取
    • 读穿:客户端通过缓存层从数据库读取数据。当读取命中缓存时,缓存返回;否则,它从数据库获取数据,缓存后再返回值。
  • 写入
    • 写穿:客户端写入缓存,缓存更新数据库。缓存在完成数据库写入后返回。
    • 写后 / 写回:客户端写入缓存,缓存立即返回。在缓存写入的背后,缓存异步写入数据库。
    • 绕过写入:客户端直接写入数据库,绕过缓存。

旁路缓存模式

当缓存不支持原生的读穿和写穿操作,并且资源需求不可预测时,我们使用这种旁路缓存模式。

==在这种模式下仍然存在缓存变脏的可能性。== 当满足以下两个条件时,会发生这种情况:

  1. 读取数据库并更新缓存
  2. 更新数据库并删除缓存

缓存放在哪里?

  • 客户端
  • 独立层
  • 服务器端

如果数据量达到缓存容量怎么办?使用缓存替换策略

  • LRU(最近最少使用):检查时间,驱逐最近使用的条目,保留最近使用的条目。
  • LFU(最不常用):检查频率,驱逐最常用的条目,保留最常用的条目。
  • ARC(自适应替换缓存):其性能优于 LRU。通过同时保留最常用和频繁使用的条目,以及驱逐历史来实现。(保留 MRU + MFU + 驱逐历史。)

谁是缓存使用的王者?

Facebook TAO