2018年4月28日星期六

用 Raspberry Pi 架设加密 DNS 客户端

dig through DNS-over-HTTPS

最近 Cloudflare 宣布使用 1.1.1.1 作为 DNS,并且强调隐私保护。由于 Cloudflare DNS 支持 DNS-over-TLS 和 DNS-over-HTTPS,这使得加密 DNS 成为了热门话题

因为操作系统往往不支持加密 DNS,所以要使用加密 DNS 必须使用一个加密 DNS 的客户端,然后这个客户端同时作为一个明文 DNS 服务器向操作系统提供正常的 DNS 服务。我可以选择在每一台我使用的设备上安装一个加密 DNS 客户端(对于 iOS 来说则是 NetworkExtension),我也可以选择在家里假设一个加密 DNS 客户端然后把路由器 DNS 指向过去,之后家里所有设备的 DNS 都会跟着变。我选择了后者,因为这样做比较方便,也为我提供了一个折腾 Raspberry Pi 的借口——我需要把加密 DNS 客户端部署到 Raspberry Pi 上让它长期为家里的局域网提供 DNS 服务。

(为什么不用 OpenWRT 呢?因为我家里已经在用 Eero 来做路由器了,它可以通过 mesh Wi-Fi 来提供更好的覆盖。如果我要多买一个 OpenWRT 路由放在 Eero 前面,那我还不如买个 Raspberry Pi 来玩玩呢。)

Raspberry Pi

我买了这个 Raspberry Pi 套装,因为它自带盒子和电源。电源不重要,我家已经有很多 USB 电源,但是我总不能一块电路板随便一放吧,所以必须买个盒子。然后我还买了张 64GB 的 microSD。因为我所有 microSD 都是 64GB 的,所以我只买 64GB 的方便有需要时随意替换。

收到 Raspberry Pi 之后,我就按照官方 NOOBS 的指引下载和准备安装。然而 NOOBS 复制到 SD 卡后无论如何 Raspberry Pi 都无法正常启动,只亮红灯没有视频输出。搜索之后发现绿灯不亮就是没有读取 SD 卡进行启动。我开头怀疑是我下载的 NOOBS 有问题,于是换成 NOOBS Lite 和 Raspbian,但都是不行。我也怀疑过是不是下载的 zip 数据有问题,但 sha256 checksum 正确。

实在找不到问题了,我就开始搜索到底 Raspberry Pi 是如何进行引导的,发现它必须从 FAT 分区进行引导。Raspberry Pi 自己的官方文档教大家使用一个叫做 SD Association’s Formatting Tool 的软件来格式化 SD 卡,但这个软件在面对超过 32GB 的卡时就会傻傻地使用 exFAT 来进行格式化。其实使用 Mac 内置的 Disk Utility 不就好咯,就算是超过 32GB 的 SD 卡也可以选择格式化为 FAT。

把 SD 格为 FAT 后,所有问题都解决了。NOOBS 能够正常启动,接着 Raspbian 也能够顺利装上。Raspberry Pi 安装好之后我尝试启用 VNC 以便我用 Mac 远程控制,结果那上面装的 VNC 和 Mac 自带的 Screen Sharing 客户端不兼容,我只好降级到用 SSH,不过也能完成绝大多数操作了。

启用 SSH 后 Raspbian 会提醒你改默认密码,没有改的话记得改掉,否则太不安全了。因为 Raspbian 连 dig 这么基本的命令都没有,需要通过 apt-get 来安装,所以我们需要先更新一下然后把 dig 装上:

sudo apt-get update
sudo apt-get install dnsutils

DNS-over-HTTPS

我基本上就是按照 Cloudflare 的 DNS-over-HTTPS 指引 来做的。一开始我觉得 Raspbian 既然是 Debian 系的就下载了 Debian 的安装包,结果发现安装不上去。接着尝试用 Linuxbrew 来装 homebrew 的版本,结果装上后发现不能执行。看到「exec format error」并且搜索后才突然明白到,Raspberry Pi 不是基于 x86/x64 架构的,而是基于 ARM 架构的。那到底 Raspberry Pi 是 32 位还是 64 位的呢?理论上 Raspberry Pi 3 B+ 是 64 位的 CPU,但在 Raspbian 上执行 uname -a 的话会显示:

Linux raspberrypi 4.9.80-v7+ #1098 SMP Fri Mar 9 19:11:42 GMT 2018 armv7l GNU/Linux

所以其实不是 64 位的,如果要选正确的版本那必须选 32 位的 ARM。只要选择正确的版本,Cloudflared 和 Dnscrypt-Proxy 都是可以用的。我两个都装了,都能在 localhost:53 上跑起来,最后选择了 Dnscrypt-Proxy 是因为配置方便。(Dnscrypt-Proxy 有配置文件模板,改改就可以用了,不需要对着文档写一个新的。)

Dnscrypt-Proxy 的安装跟着官方指引做就可以了,选择 Linux 版本 来下载。记得下载 Linux ARM 的版本,不要用 Android 或者 ARM64 的版本。(尽管 Dnscrypt-Proxy 是可以安装在 Pi-Hole 上面的,但我不想安装 Pi-Hole 来过滤广告所以选择了非 Pi-Hole 的版本。)尽管官方指引叫你检查一下是否有别的 DNS 服务正在使用 53 端口,但新装的 Raspbian 应该是不会有任何服务占用 53 端口的所以这一步可以略过。

Dnscrypt-Proxy 下载和解压好之后就可以开始配置了。假设我们已经在 Dnscrypt-Proxy 解压好的目录里:

cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml
sudo ./dnscrypt-proxy

这时候 Dnscrypt-Proxy 应该能够跑起来,在 Raspberry Pi 上用 dig 验证一下就知道了:

dig +short @127.0.0.1 cloudflare.com AAAA

这个验证必须在 Raspberry Pi 上做,因为 Dnscrypt-Proxy 的默认配置只监听 localhost:53 端口,从另外一台机器连上来 53 端口是不行的。如果 Dnscrypt-Proxy 正常工作了,我们就可以开始改配置了。打开 dnscrypt-proxy.toml,然后把 server_nameslisten_addresses 改掉。(在 SSH 上面,用 nanovi 都可以编辑 dnscrypt-proxy.toml。)

首先找到 server_names,把前面注释这一行的 # 删掉,然后把后面的内容改为你想要的服务。因为 Cloudflare 和 Google 都支持 DNS-over-HTTPS,而且都是可靠的大公司,所以我在这两家之间选。因为 Google 不强调隐私,有可能记录数据,所以我只用 Cloudflare 的,按照 Cloudflare 的文档把这一行改为这样子:

server_names = ['cloudflare', 'cloudflare-ipv6']

接着找到 listen_addresses,你会发现它只监听 IPv4 和 IPv6 的 localhost,所以其他机器不能用 Raspberry Pi 来做 DNS。这时候你要想办法把 Raspberry Pi 的 IP 绑上去。我的做法是这样子的:因为我家里路由器的 IP 是 192.168.0.1,然后 DHCP 范围是 192.168.0.10–192.168.0.199,所以 192.168.0.2–192.168.0.9 是不会被动态分配出去的。我把 Raspberry Pi 的有线网 IP 写死为 192.168.0.2,然后把它加到监听地址端口列表上:

listen_addresses = ['127.0.0.1:53', '[::1]:53', '192.168.0.2:53']

搞掂之后,可以再启动一下 Dnscrypt-Proxy:

sudo ./dnscrypt-proxy

然后从另外一台机器使用 dig 测试一下:

dig +short @192.168.0.2 cloudflare.com AAAA

如果没有问题的话,就可以把 Dnscrypt-Proxy 当装系统服务启动了:

sudo ./dnscrypt-proxy -service install
sudo ./dnscrypt-proxy -service start
sudo systemctl enable dnscrypt-proxy

之后登录到路由器,把路由器的 DNS 改为 192.168.0.2 就可以了,家里所有设备的 DNS 都会经过 Raspberry Pi 上的 Dnscrypt-Proxy 走 DNS-over-HTTPS 连接 Cloudflare 服务器。尽管 Dnscrypt-Proxy 的官方指引还说要把 Linux 上的 DNS 客户端指向 localhost,但因为我暂时不在 Raspberry Pi 上做别的事情所以不在意 Raspberry Pi 本身发出的 DNS 请求是否加密。只要它作为 DNS 服务器服务好我家里的其他设备就行。

已知问题

上述做法是有一些已知问题的。首先,如果我们请求使用 SNI 的 HTTPS 服务的话,我们还是会明文传输域名的,就算 DNS 加密了还是会存在域名泄漏的情况。如果多个不同证书的 HTTPS 域名要在一个 IP 上共处,那必须使用 SNI 否则 SSL 握手时无法决定用哪个证书的密钥。因此 SNI 常见于跑在云平台上的服务,因为云平台往往在多个服务之间共享 IP,但每一个服务来自不同的客户有不同的证书。对于大型网站来说这不常见,因为无论一个大型网站旗下有多少域名,它都可以选择把所有域名放在同一个证书里面。

其次,我没有做 IPv6 的配置,只让 Dnscrypt-Proxy 绑定了一个 IPv4 地址。这时候如果 IPv6 分配了不一样的 DNS,那使用 IPv6 DNS 查询时还是会走明文的。如果你所处的网络完全不使用 IPv6,那是没问题的。我知道 Comcast 是会分配 IPv6 地址和 IPv6 DNS 的,所以如果不在路由器上设置 IPv6 DNS(或者是不能设置)的话,那 IPv6 DNS 就有可能是 Comcast 分配下来的,也就是明文 DNS。(其他 ISP 也一样。)

最后,如果你喜欢我的文章,欢迎通过邮件订阅我的博客。

2018年4月27日星期五

网上吵架原则

在网上跟别人吵架辩论时,我有两条原则:

  1. 不能在三个回合内结束的架不吵。如果一件事情不能在三个回合内说清楚,那就是自己没搞清楚,不要浪费时间去跟别人吵。
  2. 拥有不能公开的信息时不跟别人吵架。如果一件事情自己觉得能够说清楚,但有部份信息不能够公开,那肯定说服不了别人,说了还不如不说,因为说了之后别人会觉得你缺乏证据强词夺理。

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 的要求不再提拔白人男性,然后他就只好走人了。

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

2016年8月1日星期一

《The Truth》读后感(Part 4 - Open Relationship)

这一部分属于写了没什么意义,不写又缺了点什么。《The Truth》这本书原本不叫做《The Truth》,而叫做《Good Times》。Neil 最初和 Ingrid 分手后,想尝试通过 open relationship 解决自己的问题。最初他的目标是深入体验和研究 open relationship 社区,然后好像他当初写《The Game》一样把自己的经历改写为畅销书。《The Truth》大概有小半的章节花在讲他的 open relationship 实验上。

靠前的章节写得比较详细,说他跟 Ingrid 分手后如何进入 open relationship 社区。一开始他拜访了某知名 open relationship 领袖,然后得知了某 open relationship 峰会。尽管对方对峰会的评价不是那么高,但 Neil 还是决定去参加开开眼界,结果发现去的都是老人家,如同邪教一样一丝不挂地参与宗教仪式。Neil 为了保证自己能够晚上准时出席仪式,连晚饭都没有吃就来了,结果饿到忍不住只好吃爆米花。作为专业记者,当然不能因为肚儿饿而离场,但现场画面令他一点欲望也没有。

之后他认识了一个叫做 Nicole 的女人,然后加入了一个三藩市的 open relationship 的社区。(当然是三藩市,还有哪里更开放?)这个社区当然也有自己的领袖,Neil 从他们身上学到了一些很常识性的道理,例如 open relationship 必须 lady first。如果你不先让女人体会到 open 的好处你就说你想要 open,那绝大多数情况下女人不会同意。但如果你坚持自己 close,让女人先 open,那冲突就能被缓解。Neil 在这个社区里经历了第一次 Eyes Wide Shut moment,同时明白到为什么这个社区里所有人的身材都那么好。正常人只要成功进入 relationship 就不在有动力去保持身材,但因为在 open relationship 时你还要展示身材给其他人看,所以大家的身材都会保持得非常好。

在有了那么多经历之后,Neil 当然会尝试建立自己的小家庭。这个套路到这里为止还是跟《The Game》十分相似的,就是如何从学徒成长为大师。Neil 从他长长的列表里面选择了来之全球不同地方的 3 个女人,然后在三藩市租了个 3 bedrooms,开始他全新一轮的实验。其中一个女人一来就发现自己其实不是真的能接受 open relationship,想要独占 Neil。然后 Neil 的导师开始跟他们讲道理,说你们要勇于说出自己想要什么,不要顾虑着其他人的感受。在灾难性的一晚之后,导师又跟他们说,你们要习惯接受别人的拒绝,别人拒绝的事情你就要尊重别人的选择。Neil 一开始感觉怎么这两条道理互相矛盾,一开始那么激进后来又变得那么保守。事后他才明白到这两条道理要结合在一起用:如果你想要得到 X,你就不要考虑对方听到你这个想法后会有什么要的感觉,要直接跟对方说你想要 X,但同时你又准备好对方会拒绝你获得 X,如果对方真拒绝了你就要接受。这相当于要把 effective communication 提升到一个完全不受情绪影响的高度。

在第一个实验失败之后,《The Truth》就进入了快进阶段,一笔带过讲述 Neil 之后众多失败的家庭组建实验。在最后一个失败的实验里面,一名家庭成员情绪爆发时差点拿消防斧砍到另外一位家庭成员。最终 Neil 意识到 open relationship 的实验也是要冒着生命危险来做的,才开始重新寻找新的方案。

Neil 最后一段 open relationship 是跟 Sage 度过的。他觉得 Sage 简直就是自己的镜像,超级了解自己,随便允许自己 open,还照顾好自己,一切都那么的完美。直到有一天 Sage 说她也要享受 open 去了,Neil 就发现自己受不了了。他其实也有自己害怕失去的一面,只是长期以来都没有受到过别人的刺激而已。之后他和 Sage 的感情恶化,在他想清楚准备丢下 Sage 离去时他发现 Sage 已经丢下他离去了。Neil 感慨镜像确实就是镜像,连伤害对方的方式都如此一致。

原本上述所有内容都属于一本叫做《Good Times》的书,但最终事实证明那不是正确的方向,所以这些内容变成了《The Truth》的一部分。

系列索引:

2016年7月18日星期一

Inside(內含剧透)

INSIDE_07

如果你喜欢 LimboInside 是个无脑的选择,因为两者都来自于 Playdead,玩法和风格都十分相似。从故事上来说,Inside 的深度超越了 Limbo,主题从死亡和恐惧变成了操作和服从。从游戏性来说,我觉得 Inside 就是优化得更好的 Limbo。在 Limbo 里,有些地方对操纵性要求挺高的,你不仅仅要知道谜题怎样解决,还要操作得接近完美才能通过,这偶尔会导致挫败感。Inside 减轻了挫败感但没有削弱刺激程度,你时不时就会有「Wow! So close but I did it!」的感觉,我怀疑 Inside 在设计时刻意引入了操纵容错,在 hit or miss 的瞬间视觉上给你马上要 miss 的效果,但物理引擎还是按照 hit 计算。

如果你没有玩过 Limbo,但喜欢玩解密游戏,例如 Portal,那可以尝试一下 Inside。谜题的难度和 Portal 相似,但很少有操纵不完美导致失败带来的挫败感。就算操纵得不好,同一个谜题死一两次后你就会有 aha-moment,明白到怎样操作才能成功。一旦你明白了,操纵失误的空间其实很大,不会因为细微的错误而失败。跟 Portal 相似的是,有很多场景在你路过时都会让你去想象「What had happend here?」,只是 Inside 的效果更加震撼一些。如果说 Portal 的主要情感是讽刺性幽默,那 Inside 显然就要深沉得多。Inside 会一直通过场景细节来刺激你,让你感觉到「What? What the hell? Did this really happen here? OMG!」。

好,下面这段 trailer 后开始剧透*!

从 trailer 我们能够看到一个小男孩一直往右(inside 的方向)跑,突破层层障碍跑到一个落地大玻璃窗前,看着外面有人跑进一个巨大的建筑物。接着他也进入了这个巨大的建筑物,继续往右跑,来到一个观察室前。众多员工都趴在玻璃上看观察室内发生什么事情,小男孩也靠上去看,只是镜头的角度让你看不到他们看到了什么。好,下面真的要开始剧透了。

主线剧情

其实游戏一开始在郊外你就能看到货柜车装完货出发,如果仔细观察货柜关门前一刻的话,你会发现货柜里站满了人。随着你一直往前走,你会发现货柜车也经过一个一个检查点往里开。之后你穿过玉米地和农场,终于来到一个像似工厂入口的地方。货柜车停在那里,一排毫无意识的人类排队进入工厂。这里到底发生了什么事情?

之后你潜入工厂里面,一直想方设法往里走,同时一直能看到这些无意识的人类排着队有秩序地往里走。由于木板松脱,你一不小心就掉进队伍里了,并且砸死了正下方一个人。系统收到警报,摄像头立即开始监视你,你被迫假装你就是队伍中的一员,毫无意识地有序前进,否则摄像头就发射电极电晕你。一路前进,你能看到工厂的员工在测试这群无意识人类。他们每走一段就要停一下,如果停在第一个黄色区域内,停顿时要跳一下;如果停在第二个黄色区域内,停顿时要转身 360 度。你不跟着做?次品,电晕!到底这里发生了什么事情?为什么一部分人可以操纵另外一部分人?

在农场和工厂里你偶尔能遇到大脑遥控头盔。这些头盔好像吊灯一样从天花板上吊下来,如果你跳起来把头塞进头盔里,你就能控制附近几个无意识人类。尽管你双脚已经离地,但你往哪个方向走,他们就往哪个方向走。他们能够做一些你力量不够做不了的事情,或者是进入你无法进入的区域。只要你脱下头盔,他们就会软软地跪倒在地上。从着装上来看,这些人类看起来像是农夫和工人,难道他们就是用来充当无意识的劳动力的?为什么可以这样?

你在无尽的工厂里面不停的走,感觉这个工厂比 Portal 2 里面的 Aperture Science 还要大。在 Portal 2 里面你是顺着 Aperture Science 最古老的区域往现代走,在 Inside 里面你只看得到墙上巨大的车间编号,并且不知道哪里才是尽头。工厂里有些区域大片被淹没在水里,让人怀疑这到底是天灾还是人祸。到底是因为实验失败了而必须淹没这篇区域,还是因为意外淹没导致实验失败?

INSIDE_03

被淹没的区域一开始只是「有点危险」,因为你的氧气有限,不要潜太久了就行。然后你会遇到头发超长的水中小孩,他只要看到你就想要抓住你,然后你就会被淹死。这时候水面以下区域都是「季度危险」的,任何时候你都想要远离水面,被迫下水时都是能游多快就游多快。最后由于你的失误(剧情需要),你被他抓到了,他把你拖往深渊。在这个过程中,他往你身上插入了一个类似大脑遥控头盔的插头,等你沉在深渊底部时你会醒过来,然后发现自己不再需要氧气了。这时候水域变得「绝对安全」。那到底水中小孩是什么?他到底想要害你还是帮你?难道他是实验失败的结果,被遗弃在被淹没的区域?

继续往里面走,你会看到违反重力的水。这些水不是淹没了房间的地板而是淹没了天花板!然而水里面的重力方向是正确的,比水轻物体还是会往上浮。很多无意识人类倒插在水里——他们泡在淹没了天花板的水里,头朝下接在一根电缆上,电缆往下穿出水面接到放在地板上设备里。这是多么神奇的景象!仔细观察,你会发现这些人类的肢体已经被改造过,有些没有手,有些没有头……但这不影响你对他们进行大脑遥控。这到底是什么可怕的实验?

最终你来到了 trailer 中的观察室,而且找到了一条路跑到观察室的里面去。那里面原来是充满水的,正中央有一个直径两个人那么高的肉团,肉团表面伸出来很多手啊、脚啊、头啊……原来最终改造的结果是把那么多人揉合成一个肉团,真是让人震惊。肉团身上接着四个大脑遥控头盔,你尝试把它们拔掉,每拔掉一个肉团的手脚就尝试来抓了,拔完第三个你被抓住了然后被塞进肉团里。从此你作为玩家就不再控制小男孩,变成控制肉团。这是搞什么鬼?我是被肉团吃了吗?我是成为肉团的主脑了吗?为什么我要成为恶心的肉团?

变成肉团后,你就无敌了。肉团伸出来的手手脚脚等同于几个人的力量,一下子就爆了观察室的玻璃逃脱了。之后这个游戏就不再是往里走了,肉团想要往外走,肉团想要逃脱这群疯狂科学家的实验。在逃脱的过程中,所有的工厂员工都想要远远地观察你,但又不敢靠近。偶尔会有些员工帮你一下,看起来是想帮你逃脱,但其实是诱导你进入一个巨大的礼堂。进去后无数员工在围观,地板正中央打开一个地洞然后你就掉进封闭的水池里了。水池看起来是密封的,但你还是逃出去了,最后找到工厂的外墙,用力把它撞破。墙壁之外其实是悬崖,你撞破后就滚下山去了,一直滚到山脚的沙滩上,静静地躺在海边,一束阳光穿过云层照射到你身上。肉团不再受作为玩家的你控制,游戏……莫非结束了?好像除了肉团呼吸般的起伏就没有动静了啊,游戏真的结束了吗?再等等吧……终于出来字幕了。就这样了?

隐藏结局

游戏结束了但实际上又没有真正结束。跟 Limbo 踩蛋相似,Inside 里面藏有若干个球状机器,你要找到它们并且把核心拔出来让它们停止工作。每搞掂一个你就能够获得一个成就。解决掉 13 个球状机器后,观察室附近的一个隐藏地点的球状密室就会被点亮。要知道自己解决了多少个球状机器也很容易,因为球状密室外面有一块木板上面有 13 个灯泡,每一个球状机器被解决掉后上面对应的灯泡就会亮起来。

当球状密室亮起来时,你就可以进去里面做一个拔出核心的动作。尽管你看不到自己做了什么,但你照拔就是了。之后球状密室会熄灭掉,13 个灯泡会灭掉 12 个,只留下第 2 个灯泡是亮的。你回到第 2 个球状机器的隐藏地点,旁边的密室终于点亮了。输入正确密码进入后,你会看到房间里有一个悬挂在天花板上的大脑遥控头盔。

这个头盔你无法戴上,因为它下面被接上了很多的线缆,这些线缆接到旁边的一堆类似电脑的设备上。房间尽头的挡板拿掉后,你会看到线缆接入到墙上,这时候如果你把线缆拔掉,小男孩的身体就会软下来跪倒在地板上。这个跪倒的肢势有点眼熟啊,那不正是那些可被遥控的无意识人类在遥控断开时的状态吗?所以说小男孩其实也是被遥控的?如果这样说的话,遥控小男孩的又是谁呢?

分析和猜想

如果不考虑隐藏结局的话,现在有一些主流分析是这样子的:

  1. 小男孩其实是受肉团控制的。因为这个游戏从来就没解释过为什么小男孩要不断地往里走,所以只能说小男孩解救肉团是早有预谋的事情。
  2. 水中小孩也是受肉团控制的。他的任务就是赋予你那些特殊技能,但如果他尝试在错误的地方做正确的事情,他就会把你淹死。
  3. 肉团以为自己胜利了,但其实这只是一个工厂的受控实验。在肉团逃离的过程中,你会掉到一个迷你山坡模型上,山脚就在水边,一束灯光打在水边的沙滩上。这个模型跟游戏结局时的场景一模一样,所以可以想象工厂其实提前就设计好这一切。

如果再加上隐藏结局的话,现行的分析就会变成说:

  1. 小男孩其实是受玩家控制的,因为控制小男孩的头盔被接入到电脑当中。然而玩家是受游戏控制的,因为游戏没有给玩家其它选择,所以玩家只能控制着小男孩一直往里冲,这时候主题就立即被提升到「freedom is an illusion」的高度了。
  2. 把控制小男孩的线缆拔掉,终止对小男孩的遥控,体现了「the only winning move is not to play」。只要玩家玩这个游戏,玩家就要受到游戏的控制。如果玩家想要脱离游戏的控制,那就不应该把这个游戏打爆,因为把游戏打爆就意味着完全接受游戏的控制。只有尽早离开游戏才能脱离游戏对玩家的控制。

瞬间这个游戏的深度就暴增了。到底这些分析是不是正确的,Playdead 估计永远都不会出来给出官方的结论。这就如同当年大家对 Limbo 的分析一样,大家都认为主角的小男孩其实已经死了,只是在生死之间的边缘挣扎而已,但 Playdead 就是不愿意向大家确认这是他们的真实想法。

2016年7月6日星期三

《The Truth》读后感(Part 3 - PUA)

读完整本《The Truth》后,我开始反思到底 PUA 做的是什么。

《The Truth》的结局是,Neil 终于清楚了解到自己为什么会形成这样的人格,并且通过治疗让自己变得拥有安全感,不再需要通过不停地满足自己的欲望来获得安全感。在 Neil 的婚礼上,他邀请了两群人:《The Game》里面那群 PUA 导师,和《The Truth》里面那群病友。他说这两个阶段标志着他所需要的两次转变:第一次转变让他获得了自信心,让他意识到女人是随手可得的;第二次转变让他获得了安全感,使得他的一段关系能够维持下去。

如果 Neil 需要通过两次转变才能得到他想要的结果,那意味着 PUA 对大多数人来说都只解决了第一阶段的问题。如果你没有第二阶段的问题,那你只需要一些 PUA 的小技巧来让你变得更加 desirable 就行了,之后只要你有了一段稳定的关系你就可以持续下去。但对另外一些人来说,第二阶段的问题不解决的话 PUA 只是帮你转移了挫败感——从无法得到 desirable 的人,变成就算得到了也无法维持。

如果用 attachment theory 来解释的话,第一阶段的改变本质上就是把 Anxious 转变为 Avoidant,第二阶段的改变才是真正进入 Secure 的状态。如果只完成了第一阶段的话,那实际上只能吸引到 Anxious 的人。

在《The Game》里面我们可以看到,Mystery 的问题通常来源自那些在 Anxious 和 Avoidant 之间摇摆的人。一开始他利用 Avoidant 的人格搞掂了对方 Anxious 的人格,以为对方无论如何都跑不掉了,结果对方转为 Avoidant 后反过来触发他的 Anxious 人格,最终还是自己陷进去了出不来。

在《The Truth》里面 Neil 的状况看起来好一些,因为他真的变成 Avoidant 了,但是他接受不了 Ingrid 的 Anxious 人格,总是想找机会来逃避 Ingrid 的控制欲,但方式就是出轨。虽然 Neil 几乎一直都表现为 Avoidant 人格,但他也是可以被触发为 Anxious 人格的。《The Truth》里面提到,Neil 遇到了一个性格跟自己完全一样的女人,一开始以为这就是完美结局,后来当她表现出 Avoidant 行为时 Neil 才意识到自己有多紧张,于是又变回了 Anxious。

我觉得最终的结论就是,如果要稳定维持一段关系的话就必须要变为 Secure 人格。如果不是的话,PUA 的方法只能帮你攻城不能帮你守城。至于如何能变为一个 Secure 的人,这是一个很好的问题。真正有钱不介意乱花的话当然可以去做不一定有效果的心理治疗。(Neil 在书中提到,这些心理治疗师并不是完美的。有一部分心理治疗师总能找到你下一个需要治疗的点,这样他们才能不停地从你身上赚钱。另外一部分心理治疗师自身就存在安全感问题,只是通过治疗别人来掩盖自己的问题。)但总的来说,这方面的信息不如 PUA 教材一样随手可得。

系列索引:

2016年7月5日星期二

《The Truth》读后感(Part 2 - 心理治疗)

《The Truth》开篇讲的是 Neil Strauss 去接受「性瘾(sex addict)」治疗。原因是他出轨了,出轨的对象还是自己女朋友 Ingrid 的好友。为了挽回这一段关系,他接受了好友 Rick 的建议,承认自己有性瘾然后接受治疗。接下来就是他在康复中心奇幻的历程了,在这里不仅仅有「酒瘾」等其它成瘾症状的患者,还有「爱瘾(love addict)」的患者。虽然这次心理治疗过程只有 6 周,但 Neil 在此认识的「同病相怜」的「病友们」却会一直在剧情中出现。

在 Neil 的心理治疗过程中,免不了被提到的当然是「依恋类型理论」,如果你不知道这是什么可以去看我之前对《Attached》这本书的归纳。Neil 的一位心理治疗师认为性瘾患者和爱瘾患者总是会相互吸引,因为本质上前者是 Avoidant 类型而后者是 Anxious 类型。前者的安全感来自于对方需要依赖自己,但对方靠得太近时就会把对方推开。后者的安全感来自于对方允许自己依赖,所以会无限贴近对方直到被推开,然后又因为得不到满足而再次贴近。总之双方会痛苦挣扎下去,一个追一个跑但又不愿意分开。Neil 和 Ingrid 就是类似这种情况,Neil 接受不了 Ingrid 的控制欲,Ingrid 总是怀疑 Neil 不忠。

Neil 提到一种治疗方法是分析自己家的心理族谱,要解释这是什么就必须回到《The Truth》真正开篇的第一个故事了。英文「skeleton in the closet」是指不可告人的家丑。Neil 说如果你还没有找到你家藏着骷髅的那扇门在哪里,有可能你就在那扇门背后,而你就是那个骷髅。就好像那个笑话说「如果你找不到团队里的猪队友是谁,那你就是猪队友」,Neil 说的是「如果你觉得父母都很爱你,自己家从来没有什么不见得人的秘密,那个不可告人的秘密很可能就是你」。

Neil 的一位心理治疗师问他是不是有很疏远或者是很严格的父母,或者两者都是。Neil 说他父亲疏远母亲严格。随着剧情的发展,Neil 发现这是族谱上遗传下来的。不仅仅他是在父亲疏远母亲严格的环境下长大的,他父亲和他爷爷也是在同样的环境下长大的。他父亲因为在这种环境下长大,从小缺乏安全感,只有在面对残疾人时才感觉到有点自信。这使得他选择了 Neil 的母亲,因为她有点瘸。当 Neil 的母亲得知这一点后,她选择了用 Neil 来弥补心理上情人位置的缺失,于是对 Neil 十分严格,从小就使唤 Neil 帮她做事情,到青春期不允许 Neil 出去玩动不动就禁锢在家里,到 Neil 有女朋友后禁止他带女朋友回家,并且从来没看得上 Neil 的哪一位女朋友。当这一切都被整理出来后,Neil 终于明白到自己就是家里不可告人的秘密。

Neil 的另外一位心理治疗师为他提供了「空椅疗法(chair work)」:两张椅子面对面地放在一起,你坐在其中一张,然后进入催眠状态,接着在引导下假想你要对话的人坐在对面的空椅子上,和他进行治疗所需要的对话。Neil 在被催眠后,治疗师先引导他假想青少年时的自己在窗外围观,然后让他假想父亲进来坐下,把他父亲没做对导致他缺乏安全感的事情全部质问一番,接着放走。之后换成母亲又来一遍。最后叫青少年时的自己进来坐下,告诉他父亲和母亲的问题已经解决,从现在开始成年人的自己会充当父母的角色照顾好青少年的自己,保护他不再受到伤害。

这套治疗方法背后的理论是这样子的:伤害其实来自于情感年龄 0 岁到 5 岁的童年,到了情感年龄 6 岁到 18 岁的青少年阶段人为了适应这种伤害会进化出几乎于童年性格完全相反的人格来保护自己,但这两种性格都不是正常成年人应有的人格。如果你无法让自己保持住正常成年人的人格,堕入青少年或童年阶段的性格,那就意味着有东西触动到你的伤疤了。如果你堕入童年人格,你就会展现出受害者的一面;如果你堕入青少年人格,你就会展现出反抗者的一面。无论是那一种,都是过度反应。常见的伤疤和对应的人格如下:

童年人格 青少年人格 成熟的人格
缺乏存在价值 自大 由内而外的自信
极度脆弱 无懈可击 健康的界限
非常多需求 毫无需求 沟通需求
感觉糟糕 感觉完美 坦诚和自知
失去控制 充满控制欲 灵活适度的控制
害怕被抛弃 害怕窒息 相互依存
寻求他人关注 寻求紧张刺激 和谐生活
理想化父母或伴侣 父母或伴侣的幻灭 接受父母或伴侣的现实

我觉得这样分析还是挺准确的,其实人很多时候过度反应都是因为以前有过伤疤,虽然不一定是非常严重的问题但不知道什么时候会被触发。这些过度反应就好像过敏一样,原本是为了保护你而存在的,但在不恰当的场合被触发的话就会杀害到你(和其它人)。如果需要避免过度反应,就需要找出自己的伤疤到底在哪里,然后进行对应的治疗,让自己好像脱敏一样逐步适应对应的刺激,不再过度反应。

《The Truth》当然不是一本专门讲心理治疗的书,但通过心理治疗引入如此多的理论是比较有趣的,所以我放在了 Part 1 写。因为 Neil 在书中责怪了自己的父母,所以书的扉页写着「至父母:别人都说父母的爱是无条件的,希望你们读完这本书后那仍然是个真命题。」这绝对是神级 trolling。

系列索引:

《The Truth》读后感(Part 1 - 背景知识)

Neil Strauss 的《The Truth》去年年底就出了,我上个月才留意到,然后迅速把它看完。《The Truth》可以被看作是《The Game》的续集。之所以称之为续集,是因为它延续了《The Game》里面的主题,讲了作者 Neil Strauss 在《The Game》之后的人生经历(当然主要是男女方面)。《The Truth》跟前作一样是根据真实故事改编的,所以里面所说的事情不可以全部当真,在剧情需要的地方作者会有所改动。

如果你从来没有听说过《The Game》,我可以简单介绍一下。这本书的台湾译版叫做《把妹达人》,讲述的是 PUA(Pick-Up Artist)圈子的事情。作者 Neil Strauss 作出是个宅男,在接触到网上的 PUA 论坛后报名参加了第一个商业活动。PUA 一开始只是一项很小众的爱好,喜欢玩这个的人互相交流,后来代号为 Mystery(谜男)的人开创了一个商业活动,收钱开班培训。Neil Strauss 有幸成为第一期学员,取代号为 Style(型男),随后经历了由学徒到大师的成长过程。《The Game》说的就是这个过程,里面当然有很多很魔幻的情节,大家有兴趣自己看。至于 PUA 具体是研究什么的,自行去读我过去的文章吧。

《The Game》结束之后,Style 已经是一名自行开班培训的 PUA 大师了。他有自己一套理论,出了一本叫做《Rules of The Game》的书来传授知识。他能够随意搭上美女,有时候他也有固定的女朋友,但接下来发生什么事情了呢?这就是《The Truth》的故事了。

系列索引:

2016年7月4日星期一

Grey Goo——C&C 的继承者

Grey Goo 是一个 C&C 风格的 RTS。强调 C&C 风格是因为它和 StarCraft 这种讲究微操的 RTS 很不一样。操作好每一场小战斗显得不那么重要,游戏全局的战略规划决定胜负。

1998 年 Westwood 被 EA 收购,2003 年 C&C: Generals 发布后最后一批 Westwood 员工离职,他们创立了 Petroglyph 然后继续做 C&C 风格的 RTS。早期游戏包括 Star Wars: Empire at War 和 Universe at War: Earth Assault。之后他们就跑去做别的事情去了,然后 2014 年又回归 RTS 做了 Grey Goo。

Grey Goo 剧情从类人种族 Beta 重开虫洞开始,虫洞一打开就发现被攻击了。攻击来自人类,而且人类科技已经远高于 Beta,鄙视 Beta 为「那些武器还需要发射子弹的家伙」。Beta 的步兵都是族人,人类只有总部里有一个人,派出去打仗的全是这个人控制的 drones,明显科技不在同一水平上,这简直就是 Universe at War 的反转。(在 UAW 里面人类科技水平是最低的,地球已经沦陷,地球的入侵者和另一个已毁灭文明的复仇者在地球上开战。)

人类和 Beta 打着打着,就发现 Grey Goo 不幸掉落到星球表面,然后发展成三方混战。作为跟游戏同名的种族,必须跟传统种族有点不一样,否则 Grey Goo 就只是另一个 RTS 而已。小写的 grey goo 其实是一个科幻名词,指的是自我复制的纳米机器人,通过不断消耗外部物质来扩大群体的质量。由于每一个机器人都是纳米级别的,所以整个群体就是一坨灰色的黏液。(最初提出这种机器人理念的是冯·诺依曼,所以这种机器人也叫做冯·诺依曼机器。)

Grey Goo 在游戏中没有总部,只是 Mother Goo。Mother Goo 直接爬到矿上吸矿,吸够了就有丝分裂出另一个 Mother Goo。Mother Goo 也可以有丝分裂出 Small Protein 和 Large Protein,这两者能分别特异化为各式步兵和坦克兵种。所以 Grey Goo 是没有工厂的,也不需要建科技建筑,只要有资源就可以有丝分裂。因为 Grey Goo 没有总部,所以当你打掉一个 Mother Goo 后如果游戏没有结束,你就知道至少还有另外一个 Mother Goo 跑掉了,但你没办法知道它(它们)躲在哪里。

在特异化为具体兵种前,这些黏液一样的东西是可以无视地形障碍的,所以地图上所有的矿都可以是 Grey Goo 的分矿。你找到 Mother Goo 占着的矿可以去打,它就利用无视地形的优势跑掉。此外不要以为没有特异化就没有攻击力,黏液可以直接吞噬敌人,虽然一次只能吞一个而且消化速度有点慢,但至少黏液是有自卫能力的。

总的来说,Grey Goo 作为一个游戏还是不错的。过长动画制作精良,不过剧情有点短,每一个种族只有 6 关,再加上 DLC 也就多 3 关。音乐由 Frank Klepacki 亲自操刀,他从 C&C 开始就负责这个系列的音乐,绝大部分 C&C 和 C&C: Red Alert 的音乐都是他创作的。(想去重听 C&C: Red Alert 3 主题曲 Hell March 3 的可以去他网站。)

习惯玩 StarCraft II 的话,转过来玩 Grey Goo 会不适应,因为 C&C 风格已经不是主流。我对 C&C 风格的理解就是战棋游戏实时化。尽管所有操作都是实时的,但本质上这就是个战棋游戏,对整个棋盘的优化才是关键,局部战斗无法通过微操获得太多优势。这样做的结果就是避免了 StarCraft II 对骚扰的强调,但 RTS 在没有了骚扰后就只剩下谁的一大波能把别人全推掉了,这种设计风格有好处也有坏处。

2016年6月13日星期一

华南师大附中(Part 4)

这部分可以归类到黑历史的范畴……


为什么我会成为华附论坛的管理员?因为我把它黑了。这听起来好像某个讽刺「undocumented immigrant」的笑话,说「hacker 不应该叫做 hacker,而应该叫做 undocumented admin」。我一开始就是那个 undocumented admin,后来变了真正的 admin。

最初把华附论坛黑掉的原因很简单,因为我和我们班某位同学对于什么内容应该发到哪个版的问题有很不一样的想法,然后我们就在论坛上吵了起来。我说这些帖子就应该发到这个版,但他就乱发,而且管理员完全不参与到论坛的日常运作。最后我决定既然管理员什么都不管那就让我把自己的帐号提升为管理员吧,之后我把某同学的帖子都跨版转移到我认为正确的版去。网络中心的老师(也就是真正掌握管理员帐号的人)知道后跟我说,你那么喜欢管论坛那就由你来管吧。


为什么我会开创华附学生网?其实我早就看上了这个机会。

Untitled

华附真正长年稳定运作的 3 个学生社团是什么?负责黑板报的华通社,负责广播的广播站,负责电视的电视台。(华通社全称「华附通讯社」,据说曾经是个正规注册的通讯社,所谓正规注册就是指好像新华社那样有资格在中国报道新闻。我们班某位同学成了末代社长,没能交接下去,不过黑板报没落是必然的啦。)这 3 个学生社团的共同点是什么?都是媒体。所以接下来会发生什么事情显而易见,这件事情我不做也会有人做。

Untitled

然而看到一个机会的存在并不代表这个机会此时此刻已经可以被利用,所以其实我花了好几年的时间去尝试不同的东西。最开始学校并没有网络,所以科技能够对媒体产生的影响仅限于「能够使用 Word 进行排版」。过了一年图书馆出现了多媒体阅览室,大体上就是一个只有局域网的网吧,用于借阅图书馆的多媒体(基本上就是 DVD)内容,但至少我有一个局域网可以管理。然后又过了一年,华附论坛出现了。接着又花了一年,华附学生网才真正成立了,有了自己的独立服务器,然后我们尝试在上面建立各种网站。

虽然最终这只是我们自娱自乐的事情,因为在没有移动互联网之前学生每个星期能够上网的时间很有限,但至少我们为真正感兴趣的人提供了一个动手的平台。华附接入的不是教育网,域名也不是教育网的 .edu.cn 域名,那意味着你放上去的东西全世界都能看得到。hsfz.net.cn 下面的子域名和 @hsfz.net.cn 的邮箱只要我们需要一般都能拿到。


华附对学生会执行一套很符合中国特色的集中民主制度:每个班每年选出 5 位学生代表,由他们参加每年一度的学代会(学生代表大会),然后选出学生会新一届的主席和部长。不知道出于什么原因,我在高三那一年竟然成为了我们班的学生代表。我在参加学代会时遇上了各位现任和前任的电视台台长和广播站站长,其中一位提出了这样一个问题:最近几年学生会的影响力越来越弱,完全不能代表学生和领导学生,只是无脑地完成老师布置的任务。

为了解决这个问题,我们制定了一个策略:选出一位真正有能力的学生会主席,然后各大社团辅助他提升学生会影响力。如何选出一位真正有能力的主席呢?作为掌管各大社团的人,我们发现其实我们能够影响到选举。首先不少学生代表都是各大社团的成员,因为在校园活动上活跃的人来来去去都是同一班人;然后我们还控制了所有的校内媒体。

接下来我们就开始执行我们的计划,尝试在候选人中找出我们认为真正有能力的主席。学代会提供两个环节让我们了解候选人。第一个环节是候选人上台演讲,其中一位部长候选人上去讲了一番「民主」,说完团委老师就狠狠地骂了一顿「你懂什么叫做民主吗?你理解民主如何执行吗?你有资格提供民主吗?」

第二个环节是分组 Q&A,学生代表分成小组,然后候选人去每一个小组回答学生代表提问。我们这群社团负责人自己组成一个小组,然后跟现任学生会主席(当然也是我们其中一员)说「我们要点菜」,意思是让他把两位主席候选人拉过来让我们深入了解一下。现任主席就去把两个主席候选人拉过来,跟他们介绍说「这一圈人虽然不能一人投十票,但你能不能当选很大程度就看他们了」。

我们深入了解的结果是什么呢?就是两个候选人都不理想。这时候我们才意识到真正的问题是什么:广州当时正在进行一项改革,目标是把所有高中都建设为优质高中。实际上怎么执行呢?好学校保留高中并把初中转移给差学校,差学校放弃高中从此高中只有好学校。华附没有了初中,结果就是所有高一学生都是外校考进来的,他们都不了解这所学校的「游戏规则」,跟我们这些从初中就在华附的人不一样。无论选谁出来当主席,他都是新手,就算他能够花一年的时间成为老手,到时候他也必须卸任了,因为他要开始准备高考了。

尽管如此,最终我们还是制定出了一份我们内部选择的主席和部长名单,然后利用我们的影响力去影响代表们的投票。选举完毕当天晚上唱票,负责唱票的三位同学看起来并没有特殊身份,但都是由老师提前点名确定的。(因为他们都姓「冯」,我们就阴谋论说「华附选举其实被冯氏家族控制」。)现任学生会主席在场负责监督,所以他能够事后给我们通风报信:整个唱票过程是没有任何问题的,最后每一名候选人的得票都如实记录在一张白纸上。接着团委老师把这张纸收走,半个小时后拿了另外一张纸回来说「这才是真正的唱票结果,按照上面的名单对外公布新当选的主席和部长吧」,并且要求把所有的选票销毁。新的名单上至少有 3 个部长是换了的,至少有 1 个部长被换到了原先并非他竞选的那个部门。

这件事情给我上了非常深刻的一课——当一个人告诉你「你没有资格提供民主」时,他不是在说气话,他是在说实话。你以为你了解权力的来源在哪里,其实你什么都不知道。

题外话:有些人喜欢讨论当 80 后成为中国领导人时会有什么样的变化,其实我认为这是不需要去猜测的。他们在学校的经历就已经潜移默化地影响了他们对领导力的理解,想要预测他们 60 岁时如何玩政治游戏,最简单的方法就是看他们 20 岁时是如何被这个社会教会玩政治游戏的。

系列索引:

2016年6月3日星期五

Eero 无线路由试用感受

由于家里 Comcast 的同轴电缆出口在我的卧室,所以 modem 必须放在我的卧室。这么老的房子显然是没有布好的网线的,而我又不想自己布线所以只能各种 hack。

首先我在我的房间放了一个 AirPort Express,然后我的房间和客厅就能有 Wi-Fi 覆盖到了,然而另外一个卧室覆盖得不好。幸好我室友也有一个 AirPort Express,而且一个 AirPort 能够轻易地设置为另外一个 AirPort 的中继,于是就用两个 AirPort Express 把整个房子都覆盖了。

后来我在客厅放了一台 PC 用来接电视玩游戏,没有无线网卡的台式机只能接有线。怎么办呢?去买了个 Netgear 的 powerline adapter 回来,也就是所谓的电力猫,一头接在我房间插座上,另外一头接在客厅插座上。不在台式机上装无线网卡的一个原因是据说无线的 ping 值无论如何都比不上有线,所以会影响联网玩游戏。

然而这样的解决方案并不是完美的。AirPort Express 有时候还是会出问题,所以还是要人手重启。最近开始出现各种新一代的智能无线路由,我一直在观望,直到有同事说他有 Eero 的 $50 优惠券,于是我就决定买一组来试试。一组有 3 个,$500 优惠 $50,单个的价格还是比 AirPort Express 贵(但比 AirPort Extreme 便宜),希望是好东西。

IMG_0582

Eero 的盒子跟网站一样简洁,就是强调能够轻易覆盖整栋房子,两层楼多个房间都没问题。

IMG_0583

拆开来之后就能看到 3 个 Eero 在里面,左边第一个写着 Start,这就是要接上 modem 的第一个无线路由器。

IMG_0584

把第一个 Eero 拿下来后,就能看到指引说先装 app 然后跟着 app 设置。把 app 安装好后,还需要先注册个帐号,这其中包括手机号认证。为什么一个无线路由器需要验证用户是真实的个人呢?这有点奇怪……接下来 app 会引导你把 modem 先断电,再把 modem 和 Eero 间的网线连上,最后把两个设备的电源都接上。我不是很明白为什么要把 modem 重启,估计有些 modem 不重启换客户端会有问题,所以宁愿让你重启。

IMG_0585

每一个 Eero 所需要的线缆都在盒子下方。只有第一个 Eero 是带有网线的,因为剩下两个 Eero 只是无线中继,没有考虑过你要接网线。现在新产品的包装都学 Apple,Eero 也不例外。电线和网线的捆绑方式就跟 Lightning cable 一样。

我的第一个 Eero 放在了我房间里,取代了我的 AirPort Express。然后我把第二个 Eero 放在客厅里,用它来扩大 Wi-Fi 覆盖范围。因为放在靠我室友房间的一侧,所以两个 Eero 就足够覆盖了。因为每一个 Eero 上面都有两个网线接口,所以我就在想 Eero 是不是能够同时充当有线网的无线中继。我把台式机的网线接上了第二个 Eero 的网线接口,发现网络确实是连通的,那意味着 Eero 能够把我的 powerline adapter 取代了。

接下来的问题就是无线中继对 ping 值影响有多大了。我简单用 SpeedTest.net 测试了一下,发现其实无线和有线的 ping 值一样,甚至和我 iPhone 上的无线 ping 值一样。那意味着无线网玩游戏 ping 值能够保持稳定吗?我不是很确定,所以暂时先接着 Eero 让我玩一段时间的 Overwatch 再说。如果稳定的话就把 powerline adapter 卖了,不稳定的话就换回去。

IMG_2490

最后值得一提的就是,作为新一代的智能无线路由,通过 app 管理是免不了的了,不过 Eero 的 app 实在看不出有什么非常智能的地方。尽管功能是比 AirPort Express 多一些,但也没有什么非常特别的地方,Eero 有的功能小米路由都有。Eero 号称能够在网络不稳定时自动重启一个或多个路由器,而小米只能设置定时重启,这应该是比小米先进的。但除非能够有记录显示什么时候重启了且解决了问题,否则这就是个完全隐形的功能。

Eero 扩展的网络同时包括 2.4GHz 和 5GHz,不像小米只能扩展 2.4GHz,这是 Eero 更好的地方。当然两者价格完全不能比,一个是 $150,一个是 ¥150。我现在手头上还剩下第三个 Eero,不知道用来干什么好,我又还不至于有钱到能够为了用掉一个路由而买个大房子。毕竟这是价值 $150 的东西,放着也没有用,几年之后估计第二代的 Eero 都要出来了,所以自己用不上的话只能卖掉。

2016年5月30日星期一

华南师大附中(Part 3)

今天来说一些比较搞笑的事情。


话说我们班的某些同学很关注其它班甚至其它年级的美女,于是就发展出「𥄫女」这项活动来。(「𥄫」字的意思跟「glance」和「take a quick look」差不多。)热衷于这项活动的同学每天闲聊的时候都会提及什么时候又看到哪位美女在哪里干什么,所以接下来的问题就是如何唯一标识任何一位美女。

大家都是搞过数学竞赛的人,都了解「点 A」和「直线 AB」这样的命名系统,所以对美女的编号自然从 A 开始。使用编号而非真名的另外一个好处是避免其它人听到我们在说谁。当有人说「今天又看到 B 参加田径队训练」时,外人都不知道 B 指代的是谁。

这套系统真正搞笑的地方在于对 prime 的使用。大家都知道「三角形 A′B′C′ 和三角形 ABC 全等」这样的用法,所以当一个看起来像 A 的美女出现时,她就会自动获得 A′ 这个编号。不要以为外貌相似的人很罕见,double prime 有时候也会被用上。


我们班大概有一半人是会说广东话的,这是因为我们班从初中开始就是全省招生的。(其实不是整个广东都说广东话的。)除去普通话和广东话,还有部分同学会说潮汕话、客家话甚至是雷州话。所以用什么语言视乎跟谁说话。一开始大家说什么语言就是什么语言,但很快就有人不满足,想要把一种语言强行直译为另一种语言。

众所周知学习一门新的语言从粗口开始,所以第一个强行直译的需求是「『屌你老母』用雷州话怎么说」。雷州的同学们一开始说「雷州话骂人不会这样说的」,但有人就是十分坚持要这样翻译,「你就告诉我『屌』、『你』、『妈』这三个字在雷州话对应怎么说吧」,从此这句粗口就有了雷州话版本。无论是对着老师还是对着其它班的同学,当想要骂人又不想被别人听懂时就用雷州话骂,因为懂雷州话的人确实非常少。(雷州话不像潮汕话这样属于一个巨大的语系,不存在相似的语言能互相听懂。如果是潮汕话的话,就会和闽南语、台语相通,互相能够听懂。)

接下来当然是强行把广东话翻译为普通话了,而且范围远超过粗口。基本上无论什么能够用广东话说的,都逐字翻译为普通话说。没错,就是明知道普通话应该对应换成另一个词的但偏偏用原字,只是把读音换成普通话读音。于是同学之间开始互相问候「nǐ jīn rì shí zuǒ wèi a」(你今日食咗未啊)。

随后这必然扩散到英语,把「you got it」翻译为「你得到了它」算是低级的。自从有人发现「操场」能够被翻译为「fuck ground」,大家就想方设法用操场造句,于是就有了「let’s go to the fuck ground and do morning fuck(去操场做早操吧)」。

系列索引:

2016年4月18日星期一

赴美工作常识(Part 6 - 绿卡排队)

上一篇《赴美工作常识(Part 5 - 绿卡优先级)》解释完排队的优先级是怎么确定的,以及 PERM 和 I–140 表的意义,接下来就要解释一下队具体是怎么排的以及排到之后的 I–485 表申请。这里必须要有免责声名。因为我不是移民律师,所以我只是说我的理解,法律问题还是需要咨询律师的。

I–485

I–485 表不像 PERM 需要准备那么多材料,但还是要你填的。I–485 表递交时需要一份体检报告,递交后需要去打指纹,有可能需要进行面谈。这些都不是最有趣的,真正有趣的地方在于 I–485 需要排队。

排队

首先,美国法律规定了每年能够发出去的绿卡总数上限。然后,出于多样性的考虑美国法律还规定了一年之内发给同一个国家的绿卡总数不能超过全球绿卡总数的 7%。当然国家大小和人口有区别,想要移民的比例也要区别,结果就是某些国家等待获取绿卡的人数会超过当年 7% 的上限,因此需要排队。现在世界上只有 4 个国家会因为超过这个 7% 的上限而需要排队的。猜猜是哪 4 个国家?

这 4 个国家分别是:中国(内地)、印度、墨西哥、菲律宾。注意香港、澳门、台湾是不跟中国(内地)合并计算是否超出 7% 的,所以这些地区并不会因为超出 7% 而导致需要排队。你的国家是由出生地来确定的,这是一个你这一辈子都改变不了的属性,先获取另外一个国家的国籍也没用。如果你配偶的出生地跟你不是同一个国家,排队时两个人的国家哪个先排到算哪个。

具体排队怎么排呢?还是用银行拿号排队做类比,只不过绿卡排队系统用的不是号码而是日期——PERM 申请提交的日期。可以想象一下,如果你早上去银行拿到一个号,上面写着当前时间 10:23,然后窗口显示叫到 10:09,大概就是这样的效果。使用时间而非连续号码的主要坏处在于,你不能通过号码来猜前面还有多少个人才轮到你,因为你不知道有多少人在 10:23 到 10:09 之间拿号了。

你 PERM 申请提交的日期叫做 priority date(优先日期),如果 PERM 和 I–140 都审批通过了,这个日期就是有效的。有了这个日期,你就可以每个月去看移民局的 visa bulletin(签证告示板)。这里每个月更新一次,公布下一个月轮到什么 priority date 可以递交 I–485 申请。

例如说 2015 年 10 月 的 visa bulletin 显示中国(内地)EB–3 排到 2013 年 10 月 1 日了,而你的 priority date 是 2013 年 9 月 28 日,因为你的 priority date 比当前叫号叫到的日期要早,所以你就排到了,可以递交 I–485 表了。如果当前叫到的日期写着「current」,那意味着不用排队,随时可以递交 I–485 表。

浏览几份 visa bulletin 后,你就能总结出一些规律来:EB–1 是无论如何都不需要排队的。EB–2 只有中国(内地)和印度需要排队。EB–3 所有国家都要排队,这是因为 EB–3 的优先级比 EB–1 和 EB–2 要低同时全球范围内符合资格申请的人更多。但中国(内地)、印度和菲律宾排的 EB–3 队伍比其它国家要长,这意味着这 3 个国家申请 EB–3 的人确实多。

如果你观察长期的 priority date 走势,你会发现原来这套叫号系统还能倒退!想象这样一个情景:你拿着一个 10:23 的号,窗口显示叫到 10:25 了。你迅速冲到窗口前,把材料递交进去。同时还有几个拿着 10:22 和 10:24 的人也冲上来把材料递交进去。你以为窗口很快就能把手续办好把结果递出来,结果窗口上显示的数字变成 10: 22 了。这意味着什么呢?这意味着你又可以坐下来等了。在窗口上的数字变回 10:23(或更大的数值)之前,就算窗口另一侧把手续都办好了,批准的结果也不能递出来。

中国(内地)的队伍有时候还会有一个特殊的状况,就是 EB–3 的队伍比 EB–2 长。拿着银行金卡的人都知道,金卡有资格拿贵宾号,但普通号也要拿一个,哪边先排到就在哪边办。如果普通号先排到了,当然是把贵宾号扔了。尽管 priority date 排队时不能要两个号,但一个 EB–2 的 priority date 是能申请降级为 EB–3 的。这就好比说贵宾号有权选择变为普通号。

移民局在估算队伍移动速度时是没有考虑降级的情况的,因此既然系统上显示尚未处理的普通号数量少,那就往前叫更多的号进来。结果叫号后一大多贵宾号主动降级为普通号,窗口发现队伍移动速度过快,就只能停下来不往前叫号。如果降级的人足够多,不仅仅不能往前叫号,已经叫了的号也处理不完,那就会出现上述倒退现象。这正是 2016 年 5 月 priority date 不再往前进的原因,因为降级的人太多了。如果降级的人足够多,下一个人公布的 priority date 就有可能倒退。

申请

因为 visa bulletin 总是提前一个月公布下一个月的 priority date 排到哪里了,所以如果你发现自己排到了,那是指下个月排到。排到之后就可以准备 I–485 表所需的体检表了。这个体检需要在移民局认可的诊所做,不过这些诊所实在多所以随便挑一个就可以了。体检包括完成指定疫苗的注射,中国人通常都不保留自己的疫苗注射记录,但其实指定的疫苗大多数中国人都打过。熟悉情况的医生会选择抽血进行抗体检测,只要能证明疫苗仍然有效就不需要再打。

递交 I–485 表后,就会收到收集指纹的预约邮件,预约时间和地点都是移民局选好的,如果不接受就必须回信要求更换预约时间,但不能指定预约时间。理论上非预约时间去是不提供服务的,但我听说如果运气好的话移民局也会愿意帮你在非预约时间收集指纹。

在移民局处理 I–485 表的过程中,你有可能收到面谈预约。这跟签证面谈类似,但因为我没有经验所以我也不知道具体会问什么问题。因为绿卡申请是以家庭为单位的,所以主申请人成功的话意味着配偶和 21 岁以下未婚子女也会获得绿卡。如果结婚不到两年的话,移民局就很有可能需要通过面谈来确认这是真心相爱(而非为了拿绿卡而结婚)。

通常递交 I–485 表的同时还是递交 I–765 表(申请 EAD)和 I–131 表(申请 AP)。EAD 就是工作许可文件,拿到之后你就不再受 H–1B 或 L–1 签证的约束只能为指定雇主工作。AP 的作用是这样的:I–485 递交时你必须身处美国,递交后你必须待在美国直到拿到绿卡才能离开,AP 使得你可以在此期间临时离开美国然后再返回。

拿到 EAD 和 AP 后,你所享受的待遇已经接近绿卡了。你几乎可以随意更换工作,你几乎可以随意出入美国。更换工作的限制在于,你还是要维持符合当初 PERM 描述的工作,你不能申请了一份程序员的 PERM 然后在拿到绿卡前放弃程序员工作去卖奶茶。如果绿卡在 I–485 表递交后的 180 天内获得批准,获得批准时你必须还在原来递交 I–485 表时的公司,但超过 180 天后就随意了。至于出入美国的限制,主要在于拿 AP 入境时需要等待漫长(1 个小时)的审查,比拿签证入境还慢。考虑到中国有些边检不认识 AP,不承认 AP 是有效的外国签证(因为 AP 确实罕见),可能导致出境被拒,所以回中国的话能继续申请签证还是继续申请签证吧。

批准

以前 I–485 表的排队只排一次,排到了就可以递交申请,如果递交申请后不幸倒退的话在再次排到之前都不可能获得批准,即使移民局已经处理完这份申请且计划批准。从 2016 财年开始(即 2015 年 10 月开始),移民局把排一次队拆成了排两次队:第一次排的是申请何时可以递交,第二次排的是申请何时可以批准。这样做的好处是,移民局能够根据第一条队排到的人数来预测第二条队正确的移动速度,从而降低倒退的风险。

还是用银行的例子,你拿着一个 10:23 的号,窗口显示 10:25,结果冲上去递交材料的人太多,完全超出了窗口预测的速度,如果按照一条队的做法拿只能倒退。现在分作了两条队,这个窗口显示 10:25 只是说 10:25 之前的号可以提交材料。旁边还有另外一个窗口,要那个窗口显示 10:25 了才代表 10:25 之前的号可以获得批准。收材料的窗口显示 10:25 没问题,递交材料的人过多也没问题,这个窗口停留在 10:25 或者关闭就行了。发批准的窗口这时候已经得知申请过多,号必须慢慢往前叫。

当你看到第二条队伍也排到你了,这就意味着你终于要拿到绿卡了。移民局很有可能已经在你等待第二条队伍时完成了审批,所以只要一排到就能把批准放出来。然后绿卡制卡和邮寄只需要两周左右,你就等着收这样一封欢迎信吧。

IMG_0468