Something about EditText’s TextWatcher.
《正则表达式必知必会》——Ben Forta,回顾笔记。
正则表达式的两种基本用途:搜索和替换。给定一个正则表达式,它要么匹配一些文本(进行一次搜索),要么匹配并替换一些文本(进行一次替换)。
正则表达式的核心难点:验证某个模式能不能获得预期的匹配结果并不困难,但如何验证它不会匹配到你不想要的东西可就没那么简单了。
rfc5861 定义了两个 Cache-Control 的扩展:
这是两个扩展都是用来定义缓存过期(stale)后的处理策略,旨在提高用户体验,不过两者是独立使用,并无关联的。
我们在 http 里已经使用缓存很多年了,不过有个问题很常见:如果缓存过期了会发生什么?
如果从缓存中可以立即取得响应,但是从服务器获取响应需要几百毫秒或者更久,那用户会很容易注意到这个细节差异。
一个理所当然的解决方案是“在缓存过期之前预拉取最新的内容”,这个听上去很合理,不过这引发了另外一个头疼的问题:“如何决定何时预拉取呢?”。如果没有正确实现预拉取策略,那就有可能加重缓存,网络以及后台服务器等等的负载。
退而求其次,另一个可以采取的方案是,对于那些”稍微“过期的缓存,允许先直接使用,然后在后台静默的更新缓存内容。

本文主要关注所解析的 JSON 对象与已定义的 java 对象结构不匹配的情况,解决方案就是使用 JsonDeserializer 来自定义从 JSON 对象到 Java 对象的映射。
有如下 JSON 对象,表示一本书的基本信息,本书有两个作者。
1 | { |
这个 JSON 对象包含 4 个字段,其中有一个是数组,这些字段表征了一本书的基本信息。
如果我们直接使用 Gson 来解析:
1 | Book book = new Gson().fromJson(jsonString, Book.class); |
会发现 ‘isbn-10’ 这种字段表示在 Java 中是不合法的,因为 Java 的变量名中是不允许含有 ‘-‘ 符号的。
对于这个例子,我们可以使用 Gson 的 @SerializedName 注解来处理,不过注解也仅限于此,遇到后文的场景,注解就无能为力了。
这个时候,就是 JsonDeserializer 派上用场的时候。
使用浏览器调试 http 缓存头的时候,有一些需要注意的地方。一个显著的问题是刷新(F5)或者地址栏输入网址方式(Enter)访问页面,所有请求都会自动设置 Cache-Control:max-age=0。
如果是强制刷新(SHIFT + F5)的方式,所有请求都会自动设置 Cache-Control:no-cache。
另外,控制台(Network)也有一个 “disable cache” 的选项,需要注意。
启用 stale-while-revalidate 扩展,这个需要通过 chrome://flags 设置,将 stale-while-revalidate 设置为 enable。
如果需要在浏览器里面去掉这个强制设定的“Cache-Control:max-age=0”,可以使用 ajax 来发起请求,或者使用页面内链接的方式访问。
比如直接设置 a 标签的 href,这个时候浏览器就不会设定 max-age=0 了。