2018年4月22日星期日

如何把 Blogger 文章导入到 Facebook Instant Article

Facebook Instant Article in Pages Manager

如果你跟我一样还在用 Blogger 这么远古的工具来写博客,同时又想追赶一下 Facebook Instant Article 的潮流,那你可以跟着我这篇文章做一遍来把 Blogger 的文章导入到 Instant Article。

启用 Instant Article

假设你跟我一样已经有一个在用的 Blogger 博客了,你不需要在 Blogger 上做什么改动,直接开始注册 Instant Article 就可以了。打开 Facebook Instant Article 的入口页面,然后点击注册。Facebook 会问你要为哪个 Page 启用 Instant Article,你选一个就是了。我用 Cat Chen Posts 这个页面来导出我所有的 Blogger 文章,所以我就选择了这个 Page。如果你还没有 Page 的话,可以先创建一个,因为没有 Page 是不能创建 Instant Article 的。但只要在 Page 上把一篇文章转化为 Instant Article 了,之后在个人帐号分享这篇文章的链接也会显示为 Instant Article。

关联域名

接下来你需要跟随 Facebook Instant Article 的配置工具来一步一步完成配置。首先,你要把自己的 BlogSpot 网站关联到你的 Page 下面来。Facebook 会让你把这样一行加到你的 BlogSpot 模板上:

<meta property="fb:pages" content="{page-id}" />

每一个具体 Page 的 {page-id} 都不一样,你复制粘贴 Facebook 配置工具上显示的那一行就可以了。把这一行复制下来后,你可以去 Blogger 里配置 Theme,选择修改 HTML,然后把这一行贴到 <head>...</head> 里面。之后把你 BlogSpot 的域名填到 Facebook 配置工具里去,Facebook 就会抓取你 BlogSpot 的首页并且进行验证。(如果你之前在 Google Webmasters 之类的服务做过类似的域名认证操作,这一步应该很容易。)

导入 RSS

接下来要把 Blogger 的 RSS 导入到 Facebook。如果你的 RSS 没有搞过什么花样,这是非常简单的事情。但如果你像我一样在 RSS 上做过各种优化,那这一步可以很复杂。

FeedBurner

如果你像我一样启用了 FeedBurner,你会发现 FeedBurner 导出的 RSS 可能是 Facebook 不愿意接受的格式,因为 FeedBurner 的优化加了太多东西进去。(但如果不加任何优化的话,Facebook 是可以接受的。)你可以使用 BlogSpot 自带的 feed,但既然你用了 FeedBurner 你很可能跟我一样让 BlogSpot 把自带的 feed 重定向到 FeedBurner,这时候如何才能获取到 BlogSpot 自带的 feed 呢?关键在于 querystring。以我自己的 feed 为例:

http://chinese.catchen.me/feeds/posts/default?alt=rss&redirect=false

加上 ?alt=rss 会强制输出符合 Facebook 期望的 RSS 格式。加上 ?redirect=false 或禁用 FeedBurner 重定向。两者都用上,就能让 Facebook 得到一个它能够解析和接受的 RSS。

合并多个 RSS

我用有多个 Blogger,因此我有多个 RSS 但 Facebook 只接受一个,这怎么办呢?这个问题可以用 RSS Mix 解决。把多个 RSS 的地址输入进去,它会生成一个 RSS,然后把这个合并后的 RSS 给 Facebook 就可以了。

提交审核

搞掂 RSS 后,就可以把 RSS 地址交给 Facebook 了。直接填进去 Production RSS Feed 是没问题的,将来要测试新版本的 RSS 可以用 Development RSS Feed。如果 RSS 里面已经有至少 10 篇文章,那就可以提交审核了,否则还需要写满 10 篇文章才能提交审核。

我把博客提交审核时没有遇到任何问题,但因为审核这个事情因人而异所以很难说你会不会遇到什么问题。如果遇到问题的话可以根据 Facebook 的提示进行修改。审核一旦通过了,你就可以把 Production RSS Feed 里面的内容发布为 Instant Article 了。

发布 Instant Article

尽管 Facebook 从 RSS 中读取了文章,但并不会自动把 Instant Article 发出去。你需要去 Production Articles 里面查看 RSS 导入了的文章,然后把你想要发布的发布出去,不发布的话它们会当作草稿一直存着。

在发布之前,你可能会看到某些文章标题旁边有个感叹号,那意味着 Facebook 在解析这篇文章时遇到了问题,不解决这些问题这篇文章就无法被发布出去。这时候你需要做的事情就是编辑文章 HTML,然后把问题都解决掉。具体哪些问题会出现,要看你在 Blogger 中使用的 HTML 有多复杂。尽管 Facebook 使用的 Instant Article 格式也是 HTML,但其实只是一个 HTML 子集,如果你使用的 HTML 超出了这个子集 Facebook 就会尝试进行调整,如果调整后还是有问题你就会看到那个感叹号。

我最常遇到的问题是图片嵌入在段落内。Facebook Instant Article 规定图片必须放在 <figure>...</figure> 里面,如果你在写作时只是用了 <img />,那 Facebook 就会尝试智能地在外面包一层 <figure>...</figure>。但如果你原本的 <img /> 是嵌套在 <p>...</p> 里面的话,那 Facebook 处理后就会变成了 <p><figure><img /></figure></p>。由于 Instant Article 中的 <p>...</p><figure>...</figure> 是互斥的,只能是平级关系,不能互相嵌套,所以 Facebook 就会报错。(错误信息还很奇怪,Facebook 会告诉你元素内没有文本,但其实意思是 <p>...</p> 内不能嵌套 <figure>...</figure>。)解决的办法很简单,把外面那层 <p>...</p> 去掉就可以了。

除了上述问题外,你还可能遇到其他跟 Instant Article HTML 子集不兼容的问题。Facebook 提供的错误信息不一定容易理解,但自行搜索一下总能找到答案。只要把问题都解决了,文章就能够当作 Instant Article 发布了。

测试 Instant Article 效果

最简单的测试方式是用 Facebook Pages Manager (iOS | Android)。在里面打开自己的 Page,如果看到文章下面有个 Instant Article 的闪电符号那意味着文章成功发布为 Instant Article 了。点击进去就能看到文章以 Instant Article 渲染的样子,如果跟自己想要的样子不一样可以回去继续修改 HTML。这篇文章开头的截图就是来自 Facebook Pages Manager,里面显示的是我之前一篇文章的 Instant Article 版本。

2018年4月15日星期日

移动网页的 iPhone X 适配

Instagram web without iPhone X fix (portrait)

一个月前我在 iPhone X 的 Mobile Safari 中打开 Instagram web,发现页面底下的导航栏跟 iPhone 的 home indicator 重叠在一起不方便使用。我想既然 Apple 为 iPhone X 专门更新的 Human Interface Guidelines 并为 native app 引入了 safe area 和 inset 等概念,那 Mobile Safari 应该有对应的 web 概念吧。搜索了一下,发现 Apple 确实对 Mobile Safari 增加了对应的功能。既然 Instagram 是我们公司的产品,那就动手去改吧。

改造的第一步是对页面加上这一句:

<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>

因为大多数移动页面都已经有类似的声明,所以只要加上 viewport-fit=cover 就行了。不加的话,下面所有的 CSS inset 声明都不会生效。

第二部是把竖屏(portrait mode)时的页面底部导航栏往上挪。这时候我们可以把导航栏到屏幕底部的距离设置为 env(safe-area-inset-bottom),然后浏览器自动会使用正确的数值来进行布局。(在 Safari 显示自己的工具栏时,这个值会神器地变为 0,使得页面底部导航栏紧贴 Safari 工具栏。)假设我们使用 padding-bottom 把导航栏往上挪,那么我们可以写 padding-bottom: env(safe-area-inset-bottom)。(当然 Instagram web 的实际情况比这个复杂,如果你想研究的话可以用 Safari remote debugger + iPhone X Simulator 来看。)这样竖屏的问题就修复了。

Instagram web with iPhone X fix (portrait)

如果这是个 native app 的话,问题可能到此就结束了,因为 native app 可以选择不支持横屏(landscape mode)。然后网页必须支持横屏,因为浏览器本身可以横屏。(当然你也可以很霸道地在浏览器横屏时只显示一句提示让用户把屏幕直过来,这样就可以不支持横屏了。)因为 iPhone X 屏幕顶上的那个缺口(notch),Mobile Safari 在横屏时默认会在页面两侧加白边,确保任何没对 iPhone X 做修改的页面能够正常显示。

Instagram web without iPhone X fix (landscape)

这两侧的白边很不好看,因为会让原本应该贯穿全屏的横线终止在屏幕内。在加上 viewport-fit=cover 后,两侧的白边会消失掉,因为 Mobile Safari 把这看作开发者愿意对 iPhone X 布局负责,之后如何处理横屏一侧缺口就是开发者的责任了。之前对 Instagram web 的竖屏调整一旦放到横屏就会发现新问题。

Instagram web with some iPhone X fix (landscape)

页面顶部标题栏两侧的按钮太靠近屏幕边缘了。因为 iPhone X 屏幕边缘有圆角,所以按钮放在那里并不好按。此外那也在 Apple 定义的 safe area 之外,本来就不应该放可点击元素。为此我们必须使用 env(safe-area-inset-left)env(safe-area-inset-right) 把这两个按钮往页面中间挪。假设我们使用 margin-leftmargin-right 来控制布局的话,我们可以这样写:

.leftButton {
  margin-left: env(safe-area-inset-left);
}
.rightButton {
  margin-right: env(safe-area-inset-right);
}

这样子横屏是修复了,但又会给竖屏引入新的问题。在原本的竖屏设计中,按钮离两侧屏幕边缘 16px。在我们把 16px 替换成 env(safe-area-inset-left)env(safe-area-inset-right) 之后,竖屏时这两个按钮就贴着屏幕边缘了。为此我们要引入 max() 来保证按钮离屏幕边缘至少有 16px

.leftButton {
  margin-left: max(16px, env(safe-area-inset-left));
}
.rightButton {
  margin-right: max(16px, env(safe-area-inset-right));
}

这时候竖屏横屏都没问题了,唯一问题是 Safari 以外的浏览器都被弄晕了,这 maxenv 都是什么呀?我们还没支持呢,而且是否会被标准化也很难说。幸好大多数浏览器都支持 @support,我们可以用它来进行筛选,把专门写给 Safari 看的 CSS 留给 Safari 看。

.leftButton {
  margin-left: 16px;
}
.rightButton {
  margin-right: 16px;
}

@supports (margin: max(16px)) {
  .leftButton {
    margin-left: max(16px, env(safe-area-inset-left));
  }
  .rightButton {
    margin-right: max(16px, env(safe-area-inset-right));
  }
}

到此所有的问题都解决了,Instagram web 也能在横屏中正常显示了。王子和公主从此幸福地生活在一起。

Instagram web with all iPhone X fix (landscape)

故事当然不会到这里就结束了。首先,Instagram web 可不止这一个页面。这些页面的竖屏都不会有问题,但横屏就很难说了,有可能某些元素在使用 viewport-fit=cover 之后被布局到了 safe area 之外,需要把它们挪回来。这些问题我见到一个修一个,但永远也不知道是否有遗留的。当然这个问题在 native app 里面也存在,除非从零开始设计一个新的 app 并在设计原则和布局框架上对 safe area 作出考虑,否则一个 app 无论怎么改都无法证明改全了,而且开发新功能时一不小心没测 iPhone X 就可能出现不兼容的问题。

其次,Mobile Safari 在横屏模式时如果显示地址栏就会导致页面底部导航栏处于半隐藏状态,而非原来的全隐藏状态。

iPhone X Safari Apple bug (landscape)

为什么会发生这样的事情呢?因为在显示地址栏时 Safari 会把整个 viewport 往屏幕下方挪动地址栏的高度。这时候 viewport 高度是不会改变的,因此 viewport 的一部分就跑到屏幕外去了。(但 viewport 的定义不就是屏幕内可见区域么?Apple 你自己发明了这个概念,现在说改就改。)Apple 对此的解释是,显示地址栏的 animation 必须保持 60 FPS,但 viewport 高度变化过程受页面布局速度影响而无法做到 60 FPS,所以这是 feature 不是 bug。(Chrome for iOS 在显示地址栏时会调整 viewport 高度,但因为不是 60 FPS animation 所以会看到页面闪烁。)

我觉得 Apple 要把 viewport 偷偷隐藏掉一部分也不是问题,但在隐藏的时候至少应该把 env(safe-area-inset-bottom) 自动变会 0 吧?这样子底部导航栏至少可以完全隐藏掉。这个问题已经有其他人写过,并且那篇文章的作者已经给 Apple 开 bug。

最后一个问题,为什么 env(safe-area-inset-top) 没有被用到?因为 Mobile Safari 总会在屏幕顶部显示状态栏,所以网页永远都不需要自己想办法避让屏幕顶部的缺口。(那使用 <meta name="apple-mobile-web-app-capable" content="yes"> 强行进入全屏模式呢?iPhone X 会很恶心地在屏幕上方留下一个黑色区域。)估计唯一的例外是你自己写一个 app 并在里面放一个全屏的 WebView,这时候 WebView 内的网页就需要使用 env(safe-area-inset-top) 了。我没有试过做这样的事情,但可以参考别人的文章

总的来说,iPhone X 适配不是一个很难的技术问题,尤其是只做竖屏模式的话。

2018年3月9日星期五

Buy Me a Coffee

最近开了一个 Buy Me a Coffee 的页面,让大家帮我买咖啡。如果你想买一杯咖啡给我,你可以打开 chen.cat/buy-coffee 然后付 $5 给我,这正好够我去 Saint Frank Coffee 买一杯 Nitro Float。(如果你想买多几杯的话也可以哦!)

Nitro Float from Saint Frank Coffee

在刚刚创建这个页面时,我设置了一个目标:如果收到 5 杯咖啡(总共 $25)我就重新开始写博客。然后这个目标一天就超额完成了(总共 $40)。给我买咖啡的主要是我在 Facebook 的同事,其中 Shawn 最多,一下子就给我 5 杯的钱。

之后为了测试一下我知乎的转化率,我又把这个链接发到了我的知乎专栏,同时设定了一个新目标:如果收到 10 杯咖啡(总共 $50)我就在三月每周更新一篇博客。最终我从知乎收到了 12 杯咖啡(总共 $60),按照我知乎 24 万关注者来算这转化率为 0.005%。(因为 BMC 暂时还不提供任何手段区分用户来源,所以我并不能确保那 12 杯咖啡都是来自知乎的,只能说是在知乎专栏宣传后产生的。)

既然目标设定了,我就必须要写。为了监督我写作,大家可以订阅我的博客,或者关注我的 TwitterFacebook

手机无线充电真的更方便吗?

iPhone X with Anker wireless charger

之前一直在纠结要不要买个手机无线充电器来给 iPhone X 充电,因为 $60 买一个第一代产品总觉得有点浪费,而且还不是 Apple 自己的产品。(Apple 自己的 AirPower 至今连个日期和价格都还没有。)后来发现原来普通的 Qi 兼容无线充电器只需要 $20,唯一问题是不兼容 iOS 11.2 升级后新增的 7.5W 快充,只支持 5W 充电。+200% 的价格换 +50% 的充电速度不划算,所以我最终买了 Anker 的 5W 无线充电器。(Anker 还有一个 10W 的版本,但充 iPhone X 还是 5W,无法做到 7.5W。)

在买的时候我就想过了不同使用场景的利弊:

  1. 放在公司电脑桌上:我在座位时可以随时把手机放上去充电,需要去开会时随手可以拿走。好处是比插拔充电线稍微方便一点,但因为我桌面长期有闲置的充电线所以好处也不是非常明显。坏处是手机拿起来用时就不充电了。
  2. 放在家里床头柜上:晚上睡觉时充电。好处坏处跟前面的相似,外加一点坏处是充电灯睡觉时亮着会影响睡眠。
  3. 放在其他地方:除了上述两个地方以外,没有哪里我是会经常把手机放下来的,因此放在其他地方的坏处是使用频率会很低。

最终我选择了放在公司电脑桌上,然后发现这是个正确的选择。其实无线充电最大的便利就是不用插拔线,所以最值得把有线改为无线的地方应该具备两个特性:

  1. 这是一个固定的长期充电点。随身带一个无线充电器没有意义,无线充电器必须固定下来,所以必须固定在一个经常会把手机放下来充电的地方。
  2. 手机需要经常在充电和拿走之间切换。切换得约频发,无线充电消除的充电线插拔次数越多,价值越大。

我以前最头痛的问题是,iPhone 用了一年后电池容量衰减了,经常到下班的时候电量就少于 50%,晚上出去时要用手机很不方便,因此我白天需要注意剩余电量和及时充电。尽管我桌面有闲置的充电线,随时接上去就能充电,但接一下这个操作是有成本的,所以如果电量不是很低我就会懒得去充。换成无线充电最大的好处是把这个成本消除了,我什么时候回到座位都可以把手机放上去充电,无论我在座位停留多短暂都不觉得充电存在成本。

用这个方式去思考的话,很容易会发现在汽车导航时使用无线充电器也是合适的。这个充电点很固定,而且如果经常上下班开短途的话也算是频繁插拔。不过考虑到我还在用 iPhone 7+ 做导航(因为屏幕比 iPhone X 大),所以我暂时就不买整合无线充电的 car mount 了。

2018年2月9日星期五

活跃粉丝数

在知乎我大概能感觉到粉丝总数不如月活粉(monthly active follower)、日活粉(daily active follower)重要。在我不怎么用知乎的时候,无论我有多少粉回答后都不能得到多少赞和评论,必须要我频繁回答问题一两个月后赞和评论才能跟上来。我觉得这是因为我的粉丝中的大部分都已经不活跃,所以基数大也没有用。只有不停地吸引新粉丝,才能把月活粉、日活粉质量提上去,然后才能看到赞和评论的明显改善。

因此我觉得各大网站显示一个粉丝数其实挺没有意思的,基数大可能看起来很有面子,但其实无法转化为任何东西因为不活跃的粉丝跟僵死粉本质上毫无区别。不过要计算月活粉、日活粉需要增加网站计算负担,估计大家都不会做。

做直播估计是间接测算月活粉的最好办法,如果观众出现在直播上那一定是活跃的,就算不是直播而是帖子这些粉丝应该也会乐意交互。当然好像我这么懒的,直播能不搞就不搞,所以还要再想个办法测算月活粉。

2017年1月2日星期一

Lucid Dream(清醒梦)

我从中学开始有 lucid dream 的能力。最初获取这种能力的过程很简单,就是噩梦醒来后继续去思考梦境接下来可以怎样延续下去,多练习几次后就发现不再需要有醒来这个中间步骤,一旦意识到这是自己的噩梦就可以抢过来有意识地主导。最初我只会在噩梦中变武器给自己,让我能够把坏人消灭掉。然后我发现改变地形也不错,造个迷宫把坏人围起来。这项技能越来越纯熟后,我发现自己可以进入上帝模式,在地图左边放一群红色的坏人,在地图右边放一群蓝色的坏人,然后让他们自己打吧,我还可以调整地图平衡两边实力。

最近几年这种能力开始出现了一些「变化」。以前在我意识到这是一个梦之后,我就可以任意改变梦境。改变的方式有很多种,在尝试过不同的方式后我只保留下最懒的一种:闭上眼睛然后想象我想要什么,然后睁开眼睛梦境自然会变成我想要的样子。现在的问题是,意识到在做梦这个步骤被无意识地简化掉了,然而我还是保留了上述能力。我无法意识到我在做梦,但我会意识到这个世界跟另外一个世界不一样,我在这个世界里面拥有特殊能力:闭眼再睁眼就能改变世界。这个过程如此流畅自然,使得我不再能够精确控制睁开眼睛后看到的梦境,因为我根本不知道我能够精确控制它。每一次闭上眼睛,我都无法预测到底睁开眼睛会看到什么,我只知道它会不一样。

有某几样东西是我识别梦境的关键:如果我受到了威胁,我就知道这是个噩梦;如果我连续找了 3 个洗手间都还是想要找洗手间的话,我就需要把自己强行唤醒真的去洗手间。(只要我知道是梦境,我就能去尝试感受自己在现实世界的身体,然后就可以强行睁眼把自己弄醒。)最近几年我的梦境开始有针对性地绕开我这些规则,例如说噩梦不再会威胁到我自身。过去我很偶尔才会遇见一次世界末日风格的梦,但在经过 lucid dream 的「优胜劣汰」后这种梦境越来越常见了。这种梦就好像看世界末日题材的电影一样,你可以看着无数的人死去,但同时你又很清楚「上帝视觉」或者是「主角光环」会保证你不受任何伤害。于是我就会看到窗外 UFO 入侵地球,无数人以各种血腥的方式死掉,但我自身所处环境却不受威胁,因此我完全不觉得自己在做梦。(为什么外星人偏偏不攻击我所处的建筑呢?我也不知道呢。)

不知道是不是因为 The Man In the High Castle 看多了,我的梦开始出现穿越题材了。跟我主动选择改变梦境不一样,梦境中的穿越完全不受我控制,而且关键是穿越后的平衡宇宙跟穿越前的是不连续的,那里面的所有人都不知道另外一个平衡宇宙里的事情,只有我一个人知道。这种体验太奇怪了。在过去如果我梦见自己要再一次进入高三,那是非常开心的事情,反正我感觉自己还是保送的,那就玩吧。然而最近有一次类似的梦境发生了穿越,我没办法知道穿越后的平衡宇宙有什么被改变了,所以我也不知道自己是否还是保送的。我尝试通过跟其它人对话来了解这个平衡宇宙,但又要隐藏自己穿越了这一事实,因为在他们眼中我一直存在于那个平衡宇宙中,我应该知道所有我本该知道的事情。最可怕的地方是,我没办法向任何人证明我穿越前曾经是谁,我只能接受这个平衡宇宙中的自己。

我也不知道自己是不是已经失去了 lucid dream 的能力,我觉得拥有这项能力还是挺好玩的。有可能很多的噩梦在 lucid dream 的影响下已经变得如此流畅,导致我醒来之后不会再记得那个梦曾经存在过。这样的结果必然是「优胜劣汰」,只有通过「出奇制胜」抑制了我 lucid dream 能力的梦我才会记得住。

2016年10月25日星期二

《Extreme Ownership》- Part 1

Extreme Ownership: How U.S. Navy SEALs Lead and Win》是一本关于 leadership 的书,两位作者曾经是 Navy SEAL 的军官,离开海军后成立了一家做 leadership training 的咨询公司。推荐这本书的原因是,因为它章节的格式超级好:每一章讲一个道理,为了阐述这个道理先用一个 Navy SEAL 的故事来做解释,再用一个商业环境中的例子来说明这个道理应该被如何应用到实际中来。

Facebook 也是非常强调 ownership 的。尽管不是完全按照这本书的方式来执行,但对 ownership 的解释是十分相似的。作为一个英语非母语的人,我之前一直都觉得 ownership 是个很虚的词,虽然你可以把它翻译为中文但最终还是说不清楚什么叫做 ownership。这本书通过一个个的案例把 onwership 的定义固化下来,这是我觉得整本书最有价值的部分。

Extreme Ownership

这本书的第一章就叫做「Extremem Ownership」。作者作为 SEAL 指挥官在伊拉克 Ramadi 指挥城市作战,在收到增援请求信号后抵达现场。增援请求信号来自 SEAL 狙击手,说受到敌军包围,遭受敌军火力压制,请求重型火力增援。此时 M1A2 主战坦克已经抵达现场,瞄准了对着美军开火的建筑物准备开炮。作者感觉到有什么不对,于是就问现场的海军陆战队军官发生了什么事。对方说建筑物里有敌军,他们已经杀死了我方一名伊拉克政府军士兵,现在还在顽强抵抗当中,如果地面部队无法消灭他们,那就只能呼叫空袭了。

作者还是觉得事情有点不对路。这里已经非常接近 SEAL 狙击手请求增援的地点,战火是在狙击手小分队转移过程中触发的,狙击手小分队的最终位置无人知晓,但必然在这附近。此外,现场的伊拉克政府军和他们的美军顾问本不应该那么早出现。按照原定计划他们应该等 SEAL 解除冲突后才能进入该地区,那应该是几个小时之后的事情。作者叫海军陆战队指挥官先停火,然后带了另外一名 SEAL 前往火力抵抗的建筑物调查。其它人都认为他疯了。

作者绕到建筑物围墙外,发现大门半掩着,确认手上的 M4 准备就绪后用力踢开了大门,发现围墙背后的是 SEAL 小分队队长!队长解释说,他们看到了敌军进入了建筑物,成功射杀了一名敌军后遭受顽强抵抗。这时候一切都明膫了,伊拉克政府军士兵没有留守在限定区域内并闯入了 SEAL 狙击手小分队控制的建筑,清晨时分 SEAL 难以区分手持 AK–47 的男子到底是敌军还是友军于是选择了开火。之后 SEAL 受到火力压制无法确认对方身份,只好请求重型火力支援,为此赶来的主战坦克差点把自己消灭。

友军火力误伤发生后,上级的指挥官立即下令要求作者指挥的部队停止执行任务并展开调查。作者明白做这种调查报告往往意味着有人要承担过失责任,结果很可能是解职,也就是军事生涯的终结。

在调查过程中,作者发现在计划阶段和执行阶段的人为错误:作战计划被修改了但没有发出通知、通信计划存在歧义、伊拉克政府军改变计划但没有通知美军、没有报告友军地理位置……就算是在作者指挥的部队内,也存在人为错误:狙击手具体位置没有传达给其它单位、敌对鉴别没做足导致误杀伊拉克政府军士兵、首次开火后没有传达情况报告。

尽管存在大量的人为错误,但作者找不到一个人来追究责任,并且说明如果这一个人不犯错这一切都不会发生。最后作者意识到应该承担责任的是自己。问题在于自己没有跟狙击手小分队在一起,问题在于自己没有控制好伊拉克政府军可能造成的意外情况,无论如何,总之自己指挥的部队出问题了责任就在自己。如果要被解职,那也应该是自己。

最后作者面对上级和下级做了报告,承认是自己的过失,并且对因此而受伤的 SEAL 公开道歉。然后他详细描述了整个事件的过程,指出了其中所有出错的地方,以及如何调整来避免同样的错误再次发生。事件最终的处理结果是没有人被解职,上级变得更加信任他,下级变得更加尊敬他。

这个故事解释了什么叫做 extreme ownership。无论团队大小,总之成败的责任都在 leader 身上,没有任何其它人可以追究责任。出了问题 leader 就必须承认错误接受失败,然后为下一次的成功调整计划。如果下属做不到他们应该做的事情,作为 leader 应该先看看是不是自己的问题:没有解释清楚任务的战略意义、规划好战术、确保获得充足的训练和资源。如果下属表现不佳,作为 leader 有责任培养和训练下属。如果下属持续表现不佳,作为 leader 应该对团队和任务忠诚,把表现不佳的下属换掉。

No Bad Teams, Only Bad Leaders

SEAL 的 Hell Week 训练,按身高每 7 名学员分成一队。队伍之间进行比赛,比赛总是围绕着二战时蛙人使用的皮划艇进行,例如划船出海、把船弄翻在水里正过来、划向下一个浮标、划回岸边、带着船跑向堤岸、绕过路标最后头顶着船跑回堤岸。

每一队里面军衔最高的自动成为 leader,负责从教官那里接收命令和指挥另外 6 名队员。在作者负责的这一周,II 队表现最好而 VI 队表现最差。在场最有经验的教官宣布,把这两队的 leader 交换。在交换 leader 后,VI 队变成了领先而 II 队第二。

一个团队表现好不好完全就是 leader 的责任。一个好的 leader 把团队调教好之后,就算交给别人接手团队还是保持好的表现。一个好的 leader 就算接手了不好的团队,也能把它调教好。

Believe

作者收到上级通知,要求美军所有的作战任务都要带上伊拉克政府军,否则任务不会获得批准。作者一开始也想不明白为什么要让特种部队带上世界上最废柴的常规部队作战,这样大大增加了自己部队的作战风险。而且自己想不明白,就没办法说服自己的手下接受带上伊拉克政府军的任务。

最后作者自己想明白了,接着召开全员会议传达通知。手下都很抗拒,于是作者就解释说,「如果伊拉克政府军没有能力维护自己国家安全,那将由谁来维护他们国家的安全?」然后大家都明白了,因为答案就是美国军队。

作为 leader,必须是战略任务的 true believer,否则无法说服自己的手下。如果接受到一个战略任务是跟当前的战术任务冲突的,leader 必须想明白为什么为什么会制定这样的战略,或者直接去问上级。然后再向自己的下级解释清楚整个战略,而不仅仅是指挥他们执行当前任务。

Check the Ego

SEAL 对着装发型之类的要求比常规部队要宽松,但作者在带领 SEAL 和 506 步兵团(就是二战中 101 空降师 506 步兵团的那个 506 步兵团)合作时就要求自己的手下按照常规部队的要求来执行,以便获得 506 步兵团的尊重。

同一时期,有一个伊拉克政府军中的精锐军团因为听说此地区有重要作战任务于是也迁往此地。因为是伊拉克政府军中最好的军团,所以他们想要什么就有什么。他们拒绝跟 SEAL 和 506 步兵团合作,不愿意提供他们具体的任务计划,只愿意在有需要的时候透露。这使得其它人很难知道他们何时何地在何方,因而难以避免友军误伤,需要提供增援也很难。这个军团只停留了两个星期,就被上校要求调走了。

自我往往会驱使一个人取得成功,但如果自我变得阻碍组织和任务成功时,他的表现就会受到影响,随之而来的就是任务失败。最需要管住的往往是自己的自我。

2016年8月4日星期四

《How to Fail at Almost Everything…》书评

How to Fail at Almost Everything and Still Win Big》的作者是 Scott Adams,也就是 Dilbert 漫画的作者。提起 Dilbert 的名字很多人都想不起来这是谁,但只要你打开网站一看,你会发现你确实看过 Dilbert 漫画。

这本书的核心观点是,你需要保持充足的 energy 来尝试很多的事情,这样就算大部分都失败了你还是成功的。为了让你保持有足够的 energy,你需要有一套 system,而不能依赖于设立 goals。按照 Scott Adams 的说法,「Goals are for losers」。如果你的 goal 是把体重调整到某个值,那么你看着体重往目标正方向走你就很开心,你看着体重往目标反方向走你就很沮丧,而且一旦 goal 完成了你就又要重新寻找 goal 了。所以正确的做法是设定一个 system,对每天怎么吃怎么运动做要求,只要要求做到了你每天都会感到很开心。这样就能保持你的 energy 了。(简单来说 goal 会失败,system 不容易失败,因此不容易造成 energy 流失。)

这本书剩余的部分就是不同的 systems,这些 systems 是 Scott Adams 认为有效的,帮助过他成功的。他的基本观点是,成功是 numbers game,所以他的 systems 都是帮助你增加尝试的次数,优化能够接近成功的尝试。例如说,他认为每掌握一门新的技能,你成功的概率就能翻倍,而这跟你掌握得有多好没有关系。可能你尝试某个创业项目时学会了 web design,尽管这个项目失败了,但掌握一项新技能会让你下一个完全无关的创业项目成功概率翻倍。你可以通过这个方法反复获取新技能,成功的概率就会越来越大。

这本书有意思的地方在于作者穿插了很多他的人生经历,而且写得非常幽默。他在讲述比较优势时就提到这本书的定位。他说这本书可以是一本有点幽默的成功学书,也可以是一本有点建设性的搞笑书,但哪一个立场能够让这本书在同类书籍中脱颖而出呢?作为搞笑书肯定是不行的,所以这本书的定位是有点幽默的成功学书。因此作者说,如果这本书没有你想象中那么搞笑,那是因为我刻意删除了一些搞笑的内容,避免它被错误地归类。

书里面讲到不同人保持 energy 的方式是不一样的,其中提到了 simplifier 和 optimizer 的区别。如果你在做一件事的时候是 simplifier 的角色,你就会尽量避免可能引入有风险的因素,尽量保证这件事最大可能做成功。但如果你是 optimizer 的角色,你就会想办法尽量同时完成更多相关的事情。作者说,他妻子就是 optimizer,而当自己是 simplifier 时就觉得 optimizer 做事情的方式会带来很大的压力,因此耗费 energy 而且容易吵架。

他假想如果和妻子约另外一家人出去 double date 吃晚饭看电影,他妻子肯定会说要开她的车出去,顺路加油这样明天她上班路上不用加油。然后她妻子还要顺路去饭店旁边的一个商场退一个手袋,这个手袋的 recipe 当初估计没有放好应该是找不回来的,到了商场还要跟人 argue 一番才能退掉。路上手机没电要换妻子的手机导航,但她又在打电话谈工作所以边静音导航边打电话,他无法分清她说「right」的时候是让他右转还是只是回答对方。这导致他转入了上高速的 ramp 而高速堵死了。他们到饭店时迟到了很多,幸好预订的桌子还是留给他们了,吃完晚饭已经赶不上原来想看的那场电影了,所以换了一部电影看。一切看起来都还好,但过程中 simplifier 就会一直处于焦虑状态。

整本书最搞笑的人生经历应该是他来到加州做银行和电话公司的一段了。他有一个 finance 的学位,在银行找了一个柜台的工作,理论上他是 overqualified 的。然而当年柜台账目还是人手计算的,他把数字左边抄右边都抄错,所以他其实也是 incompetent 的。做了 4 个月经理就说你还不提高的话就只能让你走了。他想了一下,要离开柜台职位有两种方法,要么是被炒,要么是被提拔,或许能被提拔呢?于是他看了一下公司内部开放的管理职位,然后写了封信给 VP 向公司提了若干改善建议,并且提出要求晋升。VP 是个爽快的人,直接约他面谈,虽然建议不会被采纳,直接提拔他也不行,但推荐他去面试公司内部其它管理层职位,结果他就面过了。之后他发现公司内的职位他都是 incompetent 的,但他非常擅长于面试,所以每次都能通过晋升来逃过一劫。直到有一天公司内部发了个通知,说出于 diversity 的要求不再提拔白人男性,然后他就只好走人了。

虽然这本书讲的道理并不算是什么非常深刻的内容,但考虑到搞笑程度十足,有时间还是值得看一看的。