从Vultr新加坡迁移到洛杉矶

Vultr新加坡节点挂了两天了,不能翻墙简直什么都干不了。早上用CloudSpeed看了下,洛杉矶机房的响应速度还不错,就迁移了过去。

ShadowsocksR

这个很简单,用一键安装脚本

网络加速

用BBR,一键安装脚本

Tiny Tiny RSS

先按照之前的笔记安装ttrss。

然后重建一个空的ttrss的数据库:

1
2
docker exec f6d92ad8efba /usr/bin/psql -c "drop database ttrss"
docker exec f6d92ad8efba /usr/bin/psql -c "create database ttrss"

把数据库的备份复制到容器里并导入:

1
2
docker cp ttrss.sql f6d92ad8efba:/tmp/ttrss.sql
docker exec f6d92ad8efba /usr/bin/psql -d ttrss -f /tmp/ttrss.sql postgres

以root身份登录容器并删除备份文件:

1
2
docker exec -it --user root f6d92ad8efba /bin/sh
rm /tmp/ttrss.sql
Unlox:兼顾安全和体验的东西深得我心

买了Unlox。早就知道MacID,阴差阳错一直没买,所以这又是一次后知后觉的行为。

曾经用过一段时间ControlPlane,通过多种条件自动判断场景以启用或关闭锁屏密码。后来在一次系统升级之后就不能用了。因为这个东西本身体验也不是很好,免费的东西折腾起来太耗费精力,所以付费买体验也是个不错的选择。

有三个功能对我来说很有用。

首先是用Face ID解锁Mac。在Mac被唤醒后,iPhone X自动弹出解锁的通知,点击后Unlox被打开并自动调用Face ID,验证通过后Mac即被解锁。不过两次Face ID验证稍显繁琐,如果在iPhone锁屏界面验证通过后就自动解锁,体验会更好。不过我猜应该是iOS在这个地方不会通知到App。

其次是Tap解锁。用手指点击触摸板,点击次数和每次用的手指数目可以自定义。这个方式确实很方便。为了加强安全性,还可以设置当手机断开时禁用Tap解锁。

第三是离开时自动锁屏。可以设置当手机和Mac之间的蓝牙连接信号减弱多少时自动锁屏。虽然对于Macbook用处不大,也不失为忘记合上屏幕时的一种补救手段。

此外还有其它一些功能,例如通过手机锁定或解锁Mac、靠近时自动唤醒Mac等。

今年Apple应该会全系支持Face ID,所以这只是一个过渡方案。

密码管理的最佳实践

通密之所以不应该被过分指责,是因为有其存在的道理,没有哪种方案的管理成本比它更低,它不需要购买昂贵的1password,不需要担心临时用的时候突然想不起来,而且,只要这个密码足够强壮并且使用环境足够安全,大多数情况下也不会有什么问题。通密的问题在于它的风险成本太高,一旦一处泄漏,所有使用这个密码的地方都不安全。

另一个极端是,使用很复杂的密码,每个账号都不同,甚至用密码生成工具生成完全没有规律的随机字符串。这种方案的安全性很高,高到连你自己都记不住。

所以我需要这样一套好的方案,它应该在安全性和易用性之间取得一个比较好的平衡,并且随著方法论和工具链的进化,这个平衡可以无限逼近黄金分割点。

首先,密码应该是复杂但容易记住的。密码的复杂度和记忆负担并不成正比,例如如果你实在记不住“ppnn13%,dkstFeb1st”,那么这样呢——“娉娉袅袅十三余,豆蔻梢头二月初”。密码只是一个字符串,如果不去死记最终的值,而是字符串背后的规律,记忆的压力就会小很多。

但考虑到每个账号都想一个这样的密码是不现实的,而且怎么解决记忆密码和账号的对应关系的问题?所以进一步,可以用这样的密码当前缀,每个密码的前缀都一样,然后针对每个账号创造一个后缀,这个后缀应该是每个账号都不同的,且和账号有某种只有你自己才知道的关联,这样你可以随时根据账号计算出它的后缀。例如,可以用账号拼音首字母(当然,实际的规则应该更复杂一点)。

这样你就有了足够复杂、每个账号都不同并且很容易记住的密码。进一步地,在私有设备上可以利用文本替换功能(例如:Alfred for Mac的Snippets功能)快速输入通用前缀,某些支持按键编程的机械键盘会有更好的体验。

不过好记性不如烂笔头,为防万一,还是需要一个Plan B。主流的密码管理工具主要有这么几种:

  • 浏览器的账号记忆功能
  • 操作系统的keychain
  • 在线密码管理工具
  • 离线密码管理工具

浏览器一般是把密码以明文存储在本地的,firefox虽然有个主密码,但只是个幌子,别人仍然可以拿到它记录密码的数据库文件。这种做法的逻辑在于,设备上存储的数据的安全性由操作系统和用户负责,换句话说,用户不应该允许他人用自己的权限登录设备。但实际上很难避免这种情况,而且还要考虑到系统被入侵的可能。所以,只应该让浏览器记住那些最不重要的账号。

相对来说,操作系统的keychain一般有自动锁定的功能,会更安全一些。但是仍无法完全避免上述问题。而且keychain只能记录账号和密码,无法存储更多的附加信息。所以这种工具也只应该存储一些不重要的账号。

最著名的在线密码管理工具应该是Lastpass。关于它的安全性有很多种说法,不过我觉得但凡是敏感数据都不要存储到线上,所以这种方式不予考虑。

我倾向于使用离线的密码管理工具。1password据说很好用,但是太贵了,而且开源免费的keepass已经完全够用了。我在Mac上用KeePassXC,在iOS中用MiniKeePass,私钥文件离线存储,然后数据库文件用Dropbox同步就可以了。

此外,对于重要的账号,如果支持两步验证,一定要开启,然后用OTP Auth管理即可。

最终的方案是:

  • 方法论:统一的复杂但有规律的前缀+根据账号计算出来的后缀
  • 工具链:KeePass + OTP Auth + Dropbox
Laravel单元测试错误:1205 Lock wait timeout exceeded

错误信息:

1205 Lock wait timeout exceeded; try restarting transaction

原因之一是测试用例里重写的tearDown()方法中没有调用父类的该方法。因为DatabaseTransaction这个trait自动开启了事务,对应的回滚方法在测试用例基类的tearDown()中执行。

用Charles拦截iOS APP HTTPS请求

实践环境

  • Charles 4.2
  • iOS 11.2.1

安装证书

按照Charles菜单(Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device or Remote Browser)的指示,设置iOS的系统代理。

为了以后使用方便,可以在代理工具(如ShadowRocket)里设置,注意使用时应配置代理工具对全部流量使用代理,如果使用PAC之类动态代理可能会拦截不到。

在iOS的Safari中访问上面提示中的网址,会弹出提示安装证书。iOS 10.3以后还要设置信任该证书(设置->通用->关于本机->证书信任设置)。

配置Charles拦截HTTPS请求

路径为:Proxy -> SSL Proxying Settings

可以设置对特定的主机名和端口拦截,也可以直接保存,此时对所有请求均会拦截。

拦截

iOS中打开上述代理,APP中发送的请求就会在Charles里列出来。

测试驱动开发的实际收益

我并不试图系统地谈TDD,因为我在这方面的经验还不足以做到这一点。但是TDD的一些方法论和工具确实解决了我在实际开发过程中遇到的一些问题。

第一个问题是健壮性。尤其是对于我这样思维发散、容易迷失又喜欢重构的人,TDD给了我一个明确的目标,在一切刚开始的时候,我要做的只是满足测试用例,让它们由红变绿。到了重构阶段,我就可以把精力放到优化代码上面,且不必对健壮性有过多的担心。在此之前,由于手动测试比较麻烦,很多时候惰性会说服潜意识告诉自己这部分逻辑很简单、不会有什么bug,结果提交测试后却一再地发生问题。

第二个问题是效率。曾经只有不忙的时候才会写测试用例,但是现在一般都会写,因为确实可以提高开发效率,而不只是保证重构的健壮性。可能对于所有对单元测试不熟悉的人来说,这都是匪夷所思的,我也曾认为单元测试只是用来保证健壮性的,必然和开发效率是一对矛盾,因为要花很多时间写测试代码。这种想法首先是因为对单元测试不熟悉,所以才需要花很多时间在上面。其次是没有看到它所带来的好处。

例如你要实现一整套退款单的功能,退款单是依赖订单的,这意味著你需要不只一条符合条件的订单数据。但是订单是有状态的,随著时间的推移、人为的操作或者开发过程中程序的影响,状态会变得不再符合你的要求,这时候你就必须停下来去做更多符合要求的订单。而创建订单也存在很多麻烦,你需要找到有库存的商品,有时候还要去库管系统中补充库存,然后下单并支付。最后花了很多时间做出来的订单,因为正在开发的退款单的程序出现的一个小问题变得不能使用!时间被大量浪费在创建所依赖的上游数据上。

这时候如果用单元测试并mock出依赖关系,就可以随时随地、无限制地执行相关的业务逻辑。对效率的提高不言而喻。

特别的,mock并不是随时可以抓起的救命稻草,它的原罪在于:不负责任地滥用mock会导致很多问题被掩盖。因此,对mock的使用应该是节制的、目标明确的。

当然,这并不包括单纯地为了提高代码覆盖率而使用mock,只所以这是个在很多强制TDD的团队里的普遍现象,归根结底是因为KPI是万恶之源,任何好的方法论,一旦沦为KPI,就离死不远了。

BaiduPCS:当前最好用的百度网盘下载工具

BaiduPCS是个命令行工具,用于下载百度网盘中的资源。之前用的是浏览器插件,需要先创建分享,再拿到下载链接,最后用下载工具下载。这个工具可以直接执行一条命令下载指定的资源,非常方便。

这里有安装说明,然后按照使用说明操作即可。

iOS垃圾短信过滤器:熊猫吃短信

“熊猫吃短信”是个新上架的App,用于过滤垃圾短信。据说是基于机器学习训练出来的,用了一周,识别得非常准确。

之前用的腾讯手机管家,即使把“精准识别”、“上传到云端”等选项都打开,还会有漏网之鱼,而且会牺牲隐私。这个App声称不会主动上传短信。最重要的是,这一周里所有不关心的短信都被过滤掉了,而且没有失误。

全新Kindle Oasis使用感受

fullsizeoutput_358

早在Paperwhite 1的时候我就不喜欢它的工业设计:边框太宽,屏幕内陷。此外,非人体工学设计和没有实体翻页键导致单手握持体验很差。再有就是做工的问题,机身表面接缝处缝隙明显而不均匀、通体强烈的塑料感。然而还是从一代用到了三代,除了kpw是kindle全系列里性价比最高的产品线之外,还有就是没有其它任何一款产品解决了kpw的主要问题。

例如Voage,虽然屏幕不内陷了、楔形机身优化了握持感、增加了翻页键,但整体的设计只算是在kpw基础上的优化,何况各项硬件配置和kpw3几乎无差。

后来当第一代Oasis发布的时候,看了第一眼就瞬间失掉了兴趣。捆绑的充电保护壳绝对是体验杀手,装上壳比kpw还要厚重,不装的话本体的续航又很差,频繁拆装也很不方便,这样的体验连kpw都不如。所以我很不看好它,果然很快在今年六月就下架了。

十月刚看到新Oasis的消息时,马上觉得这回终于有买的价值了。

首先是7寸的屏幕,瞬间和其它产品线拉开了距离。更大的屏幕意味著能展示更多内容,增加了宽度后也更接近实体书的观感。

工业设计相对于我的kpw3当然是有了质的改变。玻璃材质的纯平表面,金属背壳,没有了kpw的塑料感,显得更精致。得益于窄边框,7寸屏的机身长度比6寸的kpw还短。虽然因为加宽了屏幕和增加了单手握持的边框导致机身宽度超过kpw很多,不过在平时携带中并没有造成很多困扰。

单手握持是ko系列的主要卖点,实际使用体验当然很好。为握持设计的宽边框加上实体翻页键非常方便。虽然因为加大屏幕和增加续航导致194g的重量远远超过1代的131g,但还是比kpw轻了10g,而且主要重量集中在单手握持的一边,杠杆效应很小。配合重力感应,随时换手可以有效缓解疲劳。当然,作为长时间单手握持的阅读设备,重量自然越轻越好,这一点上,ko还有很大优化的空间。

此外,新ko的做工远远好于kpw,没有了廉价感。12颗背光灯使得背光的均匀度比kpw强了很多,几乎不会有kpw上明显的光影。性能上是现在kindle全系列里最高的,翻页时虽然还会看到闪屏,但比以前已经快了很多。自动亮度调节算是个聊胜于无的功能吧。至于防水和有声书,我没有这方面的需求。

如果说缺点的话,还是续航。虽然相对于1代本体,续航已经达到可用的水平,但是对于被其它产品线惯坏的我们来说,新ko电量的消耗还是快了点。我没有精确的对比,但是能明显地感觉到比kpw掉得快不少。

清洁手机的最佳实践

以前的做法是先用湿巾清理,再用纸巾擦干。后来屏幕的触感逐渐不如开始时顺滑,也更容易沾指纹和灰尘,而且不容易清除。估计应该是湿巾的酒精会腐蚀屏幕的涂层,纸巾粗糙的表面也会造成磨损。

现在先用软毛刷扫除灰尘,然后用3M魔布擦拭。效果应该会更好。